spear13xx.c 4.7 KB

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