spear13xx.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /*
  2. * arch/arm/mach-spear13xx/spear13xx.c
  3. *
  4. * SPEAr13XX machines common source file
  5. *
  6. * Copyright (C) 2012 ST Microelectronics
  7. * Viresh Kumar <viresh.linux@gmail.com>
  8. *
  9. * This file is licensed under the terms of the GNU General Public
  10. * License version 2. This program is licensed "as is" without any
  11. * warranty of any kind, whether express or implied.
  12. */
  13. #define pr_fmt(fmt) "SPEAr13xx: " fmt
  14. #include <linux/amba/pl022.h>
  15. #include <linux/clk.h>
  16. #include <linux/dw_dmac.h>
  17. #include <linux/err.h>
  18. #include <linux/of.h>
  19. #include <asm/hardware/cache-l2x0.h>
  20. #include <asm/mach/map.h>
  21. #include <asm/smp_twd.h>
  22. #include <mach/dma.h>
  23. #include <mach/generic.h>
  24. #include <mach/spear.h>
  25. /* common dw_dma filter routine to be used by peripherals */
  26. bool dw_dma_filter(struct dma_chan *chan, void *slave)
  27. {
  28. struct dw_dma_slave *dws = (struct dw_dma_slave *)slave;
  29. if (chan->device->dev == dws->dma_dev) {
  30. chan->private = slave;
  31. return true;
  32. } else {
  33. return false;
  34. }
  35. }
  36. /* ssp device registration */
  37. static struct dw_dma_slave ssp_dma_param[] = {
  38. {
  39. /* Tx */
  40. .cfg_hi = DWC_CFGH_DST_PER(DMA_REQ_SSP0_TX),
  41. .cfg_lo = 0,
  42. .src_master = DMA_MASTER_MEMORY,
  43. .dst_master = DMA_MASTER_SSP0,
  44. }, {
  45. /* Rx */
  46. .cfg_hi = DWC_CFGH_SRC_PER(DMA_REQ_SSP0_RX),
  47. .cfg_lo = 0,
  48. .src_master = DMA_MASTER_SSP0,
  49. .dst_master = DMA_MASTER_MEMORY,
  50. }
  51. };
  52. struct pl022_ssp_controller pl022_plat_data = {
  53. .enable_dma = 1,
  54. .dma_filter = dw_dma_filter,
  55. .dma_rx_param = &ssp_dma_param[1],
  56. .dma_tx_param = &ssp_dma_param[0],
  57. };
  58. /* CF device registration */
  59. struct dw_dma_slave cf_dma_priv = {
  60. .cfg_hi = 0,
  61. .cfg_lo = 0,
  62. .src_master = 0,
  63. .dst_master = 0,
  64. };
  65. /* dmac device registeration */
  66. struct dw_dma_platform_data dmac_plat_data = {
  67. .nr_channels = 8,
  68. .chan_allocation_order = CHAN_ALLOCATION_DESCENDING,
  69. .chan_priority = CHAN_PRIORITY_DESCENDING,
  70. .block_size = 4095U,
  71. .nr_masters = 2,
  72. .data_width = { 3, 3, 0, 0 },
  73. };
  74. void __init spear13xx_l2x0_init(void)
  75. {
  76. /*
  77. * 512KB (64KB/way), 8-way associativity, parity supported
  78. *
  79. * FIXME: 9th bit, of Auxillary Controller register must be set
  80. * for some spear13xx devices for stable L2 operation.
  81. *
  82. * Enable Early BRESP, L2 prefetch for Instruction and Data,
  83. * write alloc and 'Full line of zero' options
  84. *
  85. */
  86. writel_relaxed(0x06, VA_L2CC_BASE + L2X0_PREFETCH_CTRL);
  87. /*
  88. * Program following latencies in order to make
  89. * SPEAr1340 work at 600 MHz
  90. */
  91. writel_relaxed(0x221, VA_L2CC_BASE + L2X0_TAG_LATENCY_CTRL);
  92. writel_relaxed(0x441, VA_L2CC_BASE + L2X0_DATA_LATENCY_CTRL);
  93. l2x0_init(VA_L2CC_BASE, 0x70A60001, 0xfe00ffff);
  94. }
  95. /*
  96. * Following will create 16MB static virtual/physical mappings
  97. * PHYSICAL VIRTUAL
  98. * 0xB3000000 0xFE000000
  99. * 0xE0000000 0xFD000000
  100. * 0xEC000000 0xFC000000
  101. * 0xED000000 0xFB000000
  102. */
  103. struct map_desc spear13xx_io_desc[] __initdata = {
  104. {
  105. .virtual = (unsigned long)VA_PERIP_GRP2_BASE,
  106. .pfn = __phys_to_pfn(PERIP_GRP2_BASE),
  107. .length = SZ_16M,
  108. .type = MT_DEVICE
  109. }, {
  110. .virtual = (unsigned long)VA_PERIP_GRP1_BASE,
  111. .pfn = __phys_to_pfn(PERIP_GRP1_BASE),
  112. .length = SZ_16M,
  113. .type = MT_DEVICE
  114. }, {
  115. .virtual = (unsigned long)VA_A9SM_AND_MPMC_BASE,
  116. .pfn = __phys_to_pfn(A9SM_AND_MPMC_BASE),
  117. .length = SZ_16M,
  118. .type = MT_DEVICE
  119. }, {
  120. .virtual = (unsigned long)VA_L2CC_BASE,
  121. .pfn = __phys_to_pfn(L2CC_BASE),
  122. .length = SZ_4K,
  123. .type = MT_DEVICE
  124. },
  125. };
  126. /* This will create static memory mapping for selected devices */
  127. void __init spear13xx_map_io(void)
  128. {
  129. iotable_init(spear13xx_io_desc, ARRAY_SIZE(spear13xx_io_desc));
  130. }
  131. static void __init spear13xx_clk_init(void)
  132. {
  133. if (of_machine_is_compatible("st,spear1310"))
  134. spear1310_clk_init();
  135. else if (of_machine_is_compatible("st,spear1340"))
  136. spear1340_clk_init();
  137. else
  138. pr_err("%s: Unknown machine\n", __func__);
  139. }
  140. void __init spear13xx_timer_init(void)
  141. {
  142. char pclk_name[] = "osc_24m_clk";
  143. struct clk *gpt_clk, *pclk;
  144. spear13xx_clk_init();
  145. /* get the system timer clock */
  146. gpt_clk = clk_get_sys("gpt0", NULL);
  147. if (IS_ERR(gpt_clk)) {
  148. pr_err("%s:couldn't get clk for gpt\n", __func__);
  149. BUG();
  150. }
  151. /* get the suitable parent clock for timer*/
  152. pclk = clk_get(NULL, pclk_name);
  153. if (IS_ERR(pclk)) {
  154. pr_err("%s:couldn't get %s as parent for gpt\n", __func__,
  155. pclk_name);
  156. BUG();
  157. }
  158. clk_set_parent(gpt_clk, pclk);
  159. clk_put(gpt_clk);
  160. clk_put(pclk);
  161. spear_setup_of_timer();
  162. twd_local_timer_of_register();
  163. }