clocks-init.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. /*
  2. * arch/blackfin/mach-common/clocks-init.c - reprogram clocks / memory
  3. *
  4. * Copyright 2004-2008 Analog Devices Inc.
  5. *
  6. * Licensed under the GPL-2 or later.
  7. */
  8. #include <linux/linkage.h>
  9. #include <linux/init.h>
  10. #include <asm/blackfin.h>
  11. #include <asm/dma.h>
  12. #include <asm/clocks.h>
  13. #include <asm/mem_init.h>
  14. #include <asm/dpmc.h>
  15. #ifdef CONFIG_BF60x
  16. #define CSEL_P 0
  17. #define S0SEL_P 5
  18. #define SYSSEL_P 8
  19. #define S1SEL_P 13
  20. #define DSEL_P 16
  21. #define OSEL_P 22
  22. #define ALGN_P 29
  23. #define UPDT_P 30
  24. #define LOCK_P 31
  25. #define CGU_CTL_VAL ((CONFIG_VCO_MULT << 8) | CLKIN_HALF)
  26. #define CGU_DIV_VAL \
  27. ((CONFIG_CCLK_DIV << CSEL_P) | \
  28. (CONFIG_SCLK_DIV << SYSSEL_P) | \
  29. (CONFIG_SCLK0_DIV << S0SEL_P) | \
  30. (CONFIG_SCLK1_DIV << S1SEL_P) | \
  31. (CONFIG_DCLK_DIV << DSEL_P))
  32. #define CONFIG_BFIN_DCLK (((CONFIG_CLKIN_HZ * CONFIG_VCO_MULT) / CONFIG_DCLK_DIV) / 1000000)
  33. #if ((CONFIG_BFIN_DCLK != 125) && \
  34. (CONFIG_BFIN_DCLK != 133) && (CONFIG_BFIN_DCLK != 150) && \
  35. (CONFIG_BFIN_DCLK != 166) && (CONFIG_BFIN_DCLK != 200) && \
  36. (CONFIG_BFIN_DCLK != 225) && (CONFIG_BFIN_DCLK != 250))
  37. #error "DCLK must be in (125, 133, 150, 166, 200, 225, 250)MHz"
  38. #endif
  39. struct ddr_config {
  40. u32 ddr_clk;
  41. u32 dmc_ddrctl;
  42. u32 dmc_ddrcfg;
  43. u32 dmc_ddrtr0;
  44. u32 dmc_ddrtr1;
  45. u32 dmc_ddrtr2;
  46. u32 dmc_ddrmr;
  47. u32 dmc_ddrmr1;
  48. };
  49. struct ddr_config ddr_config_table[] __attribute__((section(".data_l1"))) = {
  50. [0] = {
  51. .ddr_clk = 125,
  52. .dmc_ddrctl = 0x00000904,
  53. .dmc_ddrcfg = 0x00000422,
  54. .dmc_ddrtr0 = 0x20705212,
  55. .dmc_ddrtr1 = 0x201003CF,
  56. .dmc_ddrtr2 = 0x00320107,
  57. .dmc_ddrmr = 0x00000422,
  58. .dmc_ddrmr1 = 0x4,
  59. },
  60. [1] = {
  61. .ddr_clk = 133,
  62. .dmc_ddrctl = 0x00000904,
  63. .dmc_ddrcfg = 0x00000422,
  64. .dmc_ddrtr0 = 0x20806313,
  65. .dmc_ddrtr1 = 0x2013040D,
  66. .dmc_ddrtr2 = 0x00320108,
  67. .dmc_ddrmr = 0x00000632,
  68. .dmc_ddrmr1 = 0x4,
  69. },
  70. [2] = {
  71. .ddr_clk = 150,
  72. .dmc_ddrctl = 0x00000904,
  73. .dmc_ddrcfg = 0x00000422,
  74. .dmc_ddrtr0 = 0x20A07323,
  75. .dmc_ddrtr1 = 0x20160492,
  76. .dmc_ddrtr2 = 0x00320209,
  77. .dmc_ddrmr = 0x00000632,
  78. .dmc_ddrmr1 = 0x4,
  79. },
  80. [3] = {
  81. .ddr_clk = 166,
  82. .dmc_ddrctl = 0x00000904,
  83. .dmc_ddrcfg = 0x00000422,
  84. .dmc_ddrtr0 = 0x20A07323,
  85. .dmc_ddrtr1 = 0x2016050E,
  86. .dmc_ddrtr2 = 0x00320209,
  87. .dmc_ddrmr = 0x00000632,
  88. .dmc_ddrmr1 = 0x4,
  89. },
  90. [4] = {
  91. .ddr_clk = 200,
  92. .dmc_ddrctl = 0x00000904,
  93. .dmc_ddrcfg = 0x00000422,
  94. .dmc_ddrtr0 = 0x20a07323,
  95. .dmc_ddrtr1 = 0x2016050f,
  96. .dmc_ddrtr2 = 0x00320509,
  97. .dmc_ddrmr = 0x00000632,
  98. .dmc_ddrmr1 = 0x4,
  99. },
  100. [5] = {
  101. .ddr_clk = 225,
  102. .dmc_ddrctl = 0x00000904,
  103. .dmc_ddrcfg = 0x00000422,
  104. .dmc_ddrtr0 = 0x20E0A424,
  105. .dmc_ddrtr1 = 0x302006DB,
  106. .dmc_ddrtr2 = 0x0032020D,
  107. .dmc_ddrmr = 0x00000842,
  108. .dmc_ddrmr1 = 0x4,
  109. },
  110. [6] = {
  111. .ddr_clk = 250,
  112. .dmc_ddrctl = 0x00000904,
  113. .dmc_ddrcfg = 0x00000422,
  114. .dmc_ddrtr0 = 0x20E0A424,
  115. .dmc_ddrtr1 = 0x3020079E,
  116. .dmc_ddrtr2 = 0x0032020D,
  117. .dmc_ddrmr = 0x00000842,
  118. .dmc_ddrmr1 = 0x4,
  119. },
  120. };
  121. #else
  122. #define SDGCTL_WIDTH (1 << 31) /* SDRAM external data path width */
  123. #define PLL_CTL_VAL \
  124. (((CONFIG_VCO_MULT & 63) << 9) | CLKIN_HALF | \
  125. (PLL_BYPASS << 8) | (ANOMALY_05000305 ? 0 : 0x8000))
  126. #endif
  127. __attribute__((l1_text))
  128. static void do_sync(void)
  129. {
  130. __builtin_bfin_ssync();
  131. }
  132. __attribute__((l1_text))
  133. void init_clocks(void)
  134. {
  135. /* Kill any active DMAs as they may trigger external memory accesses
  136. * in the middle of reprogramming things, and that'll screw us up.
  137. * For example, any automatic DMAs left by U-Boot for splash screens.
  138. */
  139. #ifdef CONFIG_BF60x
  140. int i, dlldatacycle, dll_ctl;
  141. bfin_write32(CGU0_DIV, CGU_DIV_VAL);
  142. bfin_write32(CGU0_CTL, CGU_CTL_VAL);
  143. while ((bfin_read32(CGU0_STAT) & 0x8) || !(bfin_read32(CGU0_STAT) & 0x4))
  144. continue;
  145. bfin_write32(CGU0_DIV, CGU_DIV_VAL | (1 << UPDT_P));
  146. while (bfin_read32(CGU0_STAT) & (1 << 3))
  147. continue;
  148. for (i = 0; i < 7; i++) {
  149. if (ddr_config_table[i].ddr_clk == CONFIG_BFIN_DCLK) {
  150. bfin_write_DDR0_CFG(ddr_config_table[i].dmc_ddrcfg);
  151. bfin_write_DDR0_TR0(ddr_config_table[i].dmc_ddrtr0);
  152. bfin_write_DDR0_TR1(ddr_config_table[i].dmc_ddrtr1);
  153. bfin_write_DDR0_TR2(ddr_config_table[i].dmc_ddrtr2);
  154. bfin_write_DDR0_MR(ddr_config_table[i].dmc_ddrmr);
  155. bfin_write_DDR0_EMR1(ddr_config_table[i].dmc_ddrmr1);
  156. bfin_write_DDR0_CTL(ddr_config_table[i].dmc_ddrctl);
  157. break;
  158. }
  159. }
  160. do_sync();
  161. while (!(bfin_read_DDR0_STAT() & 0x4))
  162. continue;
  163. dlldatacycle = (bfin_read_DDR0_STAT() & 0x00f00000) >> 20;
  164. dll_ctl = bfin_read_DDR0_DLLCTL();
  165. dll_ctl &= 0x0ff;
  166. bfin_write_DDR0_DLLCTL(dll_ctl | (dlldatacycle << 8));
  167. do_sync();
  168. while (!(bfin_read_DDR0_STAT() & 0x2000))
  169. continue;
  170. #else
  171. size_t i;
  172. for (i = 0; i < MAX_DMA_CHANNELS; ++i) {
  173. struct dma_register *dma = dma_io_base_addr[i];
  174. dma->cfg = 0;
  175. }
  176. do_sync();
  177. #ifdef SIC_IWR0
  178. bfin_write_SIC_IWR0(IWR_ENABLE(0));
  179. # ifdef SIC_IWR1
  180. /* BF52x system reset does not properly reset SIC_IWR1 which
  181. * will screw up the bootrom as it relies on MDMA0/1 waking it
  182. * up from IDLE instructions. See this report for more info:
  183. * http://blackfin.uclinux.org/gf/tracker/4323
  184. */
  185. if (ANOMALY_05000435)
  186. bfin_write_SIC_IWR1(IWR_ENABLE(10) | IWR_ENABLE(11));
  187. else
  188. bfin_write_SIC_IWR1(IWR_DISABLE_ALL);
  189. # endif
  190. # ifdef SIC_IWR2
  191. bfin_write_SIC_IWR2(IWR_DISABLE_ALL);
  192. # endif
  193. #else
  194. bfin_write_SIC_IWR(IWR_ENABLE(0));
  195. #endif
  196. do_sync();
  197. #ifdef EBIU_SDGCTL
  198. bfin_write_EBIU_SDGCTL(bfin_read_EBIU_SDGCTL() | SRFS);
  199. do_sync();
  200. #endif
  201. #ifdef CLKBUFOE
  202. bfin_write16(VR_CTL, bfin_read_VR_CTL() | CLKBUFOE);
  203. do_sync();
  204. __asm__ __volatile__("IDLE;");
  205. #endif
  206. bfin_write_PLL_LOCKCNT(0x300);
  207. do_sync();
  208. /* We always write PLL_CTL thus avoiding Anomaly 05000242 */
  209. bfin_write16(PLL_CTL, PLL_CTL_VAL);
  210. __asm__ __volatile__("IDLE;");
  211. bfin_write_PLL_DIV(CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV);
  212. #ifdef EBIU_SDGCTL
  213. bfin_write_EBIU_SDRRC(mem_SDRRC);
  214. bfin_write_EBIU_SDGCTL((bfin_read_EBIU_SDGCTL() & SDGCTL_WIDTH) | mem_SDGCTL);
  215. #else
  216. bfin_write_EBIU_RSTCTL(bfin_read_EBIU_RSTCTL() & ~(SRREQ));
  217. do_sync();
  218. bfin_write_EBIU_RSTCTL(bfin_read_EBIU_RSTCTL() | 0x1);
  219. bfin_write_EBIU_DDRCTL0(mem_DDRCTL0);
  220. bfin_write_EBIU_DDRCTL1(mem_DDRCTL1);
  221. bfin_write_EBIU_DDRCTL2(mem_DDRCTL2);
  222. #ifdef CONFIG_MEM_EBIU_DDRQUE
  223. bfin_write_EBIU_DDRQUE(CONFIG_MEM_EBIU_DDRQUE);
  224. #endif
  225. #endif
  226. #endif
  227. do_sync();
  228. bfin_read16(0);
  229. }