clock_ti816x.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. /*
  2. * clock_ti816x.c
  3. *
  4. * Clocks for TI816X based boards
  5. *
  6. * Copyright (C) 2013, Adeneo Embedded <www.adeneo-embedded.com>
  7. * Antoine Tenart, <atenart@adeneo-embedded.com>
  8. *
  9. * Based on TI-PSP-04.00.02.14 :
  10. *
  11. * Copyright (C) 2009, Texas Instruments, Incorporated
  12. *
  13. * This program is free software; you can redistribute it and/or
  14. * modify it under the terms of the GNU General Public License as
  15. * published by the Free Software Foundation; either version 2 of
  16. * the License, or (at your option) any later version.
  17. *
  18. * This program is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the
  21. * GNU General Public License for more details.
  22. */
  23. #include <common.h>
  24. #include <asm/arch/ddr_defs.h>
  25. #include <asm/arch/cpu.h>
  26. #include <asm/arch/clock.h>
  27. #include <asm/arch/hardware.h>
  28. #include <asm/io.h>
  29. #include <asm/emif.h>
  30. #define CM_PLL_BASE (CTRL_BASE + 0x0400)
  31. /* Main PLL */
  32. #define MAIN_N 64
  33. #define MAIN_P 0x1
  34. #define MAIN_INTFREQ1 0x8
  35. #define MAIN_FRACFREQ1 0x800000
  36. #define MAIN_MDIV1 0x2
  37. #define MAIN_INTFREQ2 0xE
  38. #define MAIN_FRACFREQ2 0x0
  39. #define MAIN_MDIV2 0x1
  40. #define MAIN_INTFREQ3 0x8
  41. #define MAIN_FRACFREQ3 0xAAAAB0
  42. #define MAIN_MDIV3 0x3
  43. #define MAIN_INTFREQ4 0x9
  44. #define MAIN_FRACFREQ4 0x55554F
  45. #define MAIN_MDIV4 0x3
  46. #define MAIN_INTFREQ5 0x9
  47. #define MAIN_FRACFREQ5 0x374BC6
  48. #define MAIN_MDIV5 0xC
  49. #define MAIN_MDIV6 0x48
  50. #define MAIN_MDIV7 0x4
  51. /* DDR PLL */
  52. #define DDR_N 59
  53. #define DDR_P 0x1
  54. #define DDR_MDIV1 0x2
  55. #define DDR_INTFREQ2 0x8
  56. #define DDR_FRACFREQ2 0xD99999
  57. #define DDR_MDIV2 0x1E
  58. #define DDR_INTFREQ3 0x8
  59. #define DDR_FRACFREQ3 0x0
  60. #define DDR_MDIV3 0x4
  61. #define DDR_INTFREQ4 0xE /* Expansion DDR clk */
  62. #define DDR_FRACFREQ4 0x0
  63. #define DDR_MDIV4 0x4
  64. #define DDR_INTFREQ5 0xE /* Expansion DDR clk */
  65. #define DDR_FRACFREQ5 0x0
  66. #define DDR_MDIV5 0x4
  67. #define CONTROL_STATUS (CTRL_BASE + 0x40)
  68. #define DDR_RCD (CTRL_BASE + 0x070C)
  69. #define CM_TIMER1_CLKSEL (PRCM_BASE + 0x390)
  70. #define CM_ALWON_CUST_EFUSE_CLKCTRL (PRCM_BASE + 0x1628)
  71. #define INTCPS_SYSCONFIG 0x48200010
  72. #define CM_SYSCLK10_CLKSEL 0x48180324
  73. struct cm_pll {
  74. unsigned int mainpll_ctrl; /* offset 0x400 */
  75. unsigned int mainpll_pwd;
  76. unsigned int mainpll_freq1;
  77. unsigned int mainpll_div1;
  78. unsigned int mainpll_freq2;
  79. unsigned int mainpll_div2;
  80. unsigned int mainpll_freq3;
  81. unsigned int mainpll_div3;
  82. unsigned int mainpll_freq4;
  83. unsigned int mainpll_div4;
  84. unsigned int mainpll_freq5;
  85. unsigned int mainpll_div5;
  86. unsigned int resv0[1];
  87. unsigned int mainpll_div6;
  88. unsigned int resv1[1];
  89. unsigned int mainpll_div7;
  90. unsigned int ddrpll_ctrl; /* offset 0x440 */
  91. unsigned int ddrpll_pwd;
  92. unsigned int resv2[1];
  93. unsigned int ddrpll_div1;
  94. unsigned int ddrpll_freq2;
  95. unsigned int ddrpll_div2;
  96. unsigned int ddrpll_freq3;
  97. unsigned int ddrpll_div3;
  98. unsigned int ddrpll_freq4;
  99. unsigned int ddrpll_div4;
  100. unsigned int ddrpll_freq5;
  101. unsigned int ddrpll_div5;
  102. unsigned int videopll_ctrl; /* offset 0x470 */
  103. unsigned int videopll_pwd;
  104. unsigned int videopll_freq1;
  105. unsigned int videopll_div1;
  106. unsigned int videopll_freq2;
  107. unsigned int videopll_div2;
  108. unsigned int videopll_freq3;
  109. unsigned int videopll_div3;
  110. unsigned int resv3[4];
  111. unsigned int audiopll_ctrl; /* offset 0x4A0 */
  112. unsigned int audiopll_pwd;
  113. unsigned int resv4[2];
  114. unsigned int audiopll_freq2;
  115. unsigned int audiopll_div2;
  116. unsigned int audiopll_freq3;
  117. unsigned int audiopll_div3;
  118. unsigned int audiopll_freq4;
  119. unsigned int audiopll_div4;
  120. unsigned int audiopll_freq5;
  121. unsigned int audiopll_div5;
  122. };
  123. const struct cm_alwon *cmalwon = (struct cm_alwon *)CM_ALWON_BASE;
  124. const struct cm_def *cmdef = (struct cm_def *)CM_DEFAULT_BASE;
  125. const struct cm_pll *cmpll = (struct cm_pll *)CM_PLL_BASE;
  126. const struct wd_timer *wdtimer = (struct wd_timer *)WDT_BASE;
  127. void enable_dmm_clocks(void)
  128. {
  129. writel(PRCM_MOD_EN, &cmdef->dmmclkctrl);
  130. /* Wait for dmm to be fully functional, including OCP */
  131. while (((readl(&cmdef->dmmclkctrl) >> 17) & 0x3) != 0)
  132. ;
  133. }
  134. void enable_emif_clocks(void)
  135. {
  136. writel(PRCM_MOD_EN, &cmdef->fwclkctrl);
  137. writel(PRCM_MOD_EN, &cmdef->l3fastclkstctrl);
  138. writel(PRCM_MOD_EN, &cmdef->emif0clkctrl);
  139. writel(PRCM_MOD_EN, &cmdef->emif1clkctrl);
  140. /* Wait for clocks to be active */
  141. while ((readl(&cmdef->l3fastclkstctrl) & 0x300) != 0x300)
  142. ;
  143. /* Wait for emif0 to be fully functional, including OCP */
  144. while (((readl(&cmdef->emif0clkctrl) >> 17) & 0x3) != 0)
  145. ;
  146. /* Wait for emif1 to be fully functional, including OCP */
  147. while (((readl(&cmdef->emif1clkctrl) >> 17) & 0x3) != 0)
  148. ;
  149. }
  150. /* assume delay is aprox at least 1us */
  151. static void ddr_delay(int d)
  152. {
  153. int i;
  154. /*
  155. * read a control register.
  156. * this is a bit more delay and cannot be optimized by the compiler
  157. * assuming one read takes 200 cycles and A8 is runing 1 GHz
  158. * somewhat conservative setting
  159. */
  160. for (i = 0; i < 50*d; i++)
  161. readl(CONTROL_STATUS);
  162. }
  163. static void main_pll_init_ti816x(void)
  164. {
  165. u32 main_pll_ctrl = 0;
  166. /* Put the PLL in bypass mode by setting BIT2 in its ctrl reg */
  167. main_pll_ctrl = readl(&cmpll->mainpll_ctrl);
  168. main_pll_ctrl &= 0xFFFFFFFB;
  169. main_pll_ctrl |= BIT(2);
  170. writel(main_pll_ctrl, &cmpll->mainpll_ctrl);
  171. /* Enable PLL by setting BIT3 in its ctrl reg */
  172. main_pll_ctrl = readl(&cmpll->mainpll_ctrl);
  173. main_pll_ctrl &= 0xFFFFFFF7;
  174. main_pll_ctrl |= BIT(3);
  175. writel(main_pll_ctrl, &cmpll->mainpll_ctrl);
  176. /* Write the values of N,P in the CTRL reg */
  177. main_pll_ctrl = readl(&cmpll->mainpll_ctrl);
  178. main_pll_ctrl &= 0xFF;
  179. main_pll_ctrl |= (MAIN_N<<16 | MAIN_P<<8);
  180. writel(main_pll_ctrl, &cmpll->mainpll_ctrl);
  181. /* Power up clock1-7 */
  182. writel(0x0, &cmpll->mainpll_pwd);
  183. /* Program the freq and divider values for clock1-7 */
  184. writel((1<<31 | 1<<28 | (MAIN_INTFREQ1<<24) | MAIN_FRACFREQ1),
  185. &cmpll->mainpll_freq1);
  186. writel(((1<<8) | MAIN_MDIV1), &cmpll->mainpll_div1);
  187. writel((1<<31 | 1<<28 | (MAIN_INTFREQ2<<24) | MAIN_FRACFREQ2),
  188. &cmpll->mainpll_freq2);
  189. writel(((1<<8) | MAIN_MDIV2), &cmpll->mainpll_div2);
  190. writel((1<<31 | 1<<28 | (MAIN_INTFREQ3<<24) | MAIN_FRACFREQ3),
  191. &cmpll->mainpll_freq3);
  192. writel(((1<<8) | MAIN_MDIV3), &cmpll->mainpll_div3);
  193. writel((1<<31 | 1<<28 | (MAIN_INTFREQ4<<24) | MAIN_FRACFREQ4),
  194. &cmpll->mainpll_freq4);
  195. writel(((1<<8) | MAIN_MDIV4), &cmpll->mainpll_div4);
  196. writel((1<<31 | 1<<28 | (MAIN_INTFREQ5<<24) | MAIN_FRACFREQ5),
  197. &cmpll->mainpll_freq5);
  198. writel(((1<<8) | MAIN_MDIV5), &cmpll->mainpll_div5);
  199. writel((1<<8 | MAIN_MDIV6), &cmpll->mainpll_div6);
  200. writel((1<<8 | MAIN_MDIV7), &cmpll->mainpll_div7);
  201. /* Wait for PLL to lock */
  202. while ((readl(&cmpll->mainpll_ctrl) & BIT(7)) != BIT(7))
  203. ;
  204. /* Put the PLL in normal mode, disable bypass */
  205. main_pll_ctrl = readl(&cmpll->mainpll_ctrl);
  206. main_pll_ctrl &= 0xFFFFFFFB;
  207. writel(main_pll_ctrl, &cmpll->mainpll_ctrl);
  208. }
  209. static void ddr_pll_bypass_ti816x(void)
  210. {
  211. u32 ddr_pll_ctrl = 0;
  212. /* Put the PLL in bypass mode by setting BIT2 in its ctrl reg */
  213. ddr_pll_ctrl = readl(&cmpll->ddrpll_ctrl);
  214. ddr_pll_ctrl &= 0xFFFFFFFB;
  215. ddr_pll_ctrl |= BIT(2);
  216. writel(ddr_pll_ctrl, &cmpll->ddrpll_ctrl);
  217. }
  218. static void ddr_pll_init_ti816x(void)
  219. {
  220. u32 ddr_pll_ctrl = 0;
  221. /* Enable PLL by setting BIT3 in its ctrl reg */
  222. ddr_pll_ctrl = readl(&cmpll->ddrpll_ctrl);
  223. ddr_pll_ctrl &= 0xFFFFFFF7;
  224. ddr_pll_ctrl |= BIT(3);
  225. writel(ddr_pll_ctrl, &cmpll->ddrpll_ctrl);
  226. /* Write the values of N,P in the CTRL reg */
  227. ddr_pll_ctrl = readl(&cmpll->ddrpll_ctrl);
  228. ddr_pll_ctrl &= 0xFF;
  229. ddr_pll_ctrl |= (DDR_N<<16 | DDR_P<<8);
  230. writel(ddr_pll_ctrl, &cmpll->ddrpll_ctrl);
  231. ddr_delay(10);
  232. /* Power up clock1-5 */
  233. writel(0x0, &cmpll->ddrpll_pwd);
  234. /* Program the freq and divider values for clock1-3 */
  235. writel(((0<<8) | DDR_MDIV1), &cmpll->ddrpll_div1);
  236. ddr_delay(1);
  237. writel(((1<<8) | DDR_MDIV1), &cmpll->ddrpll_div1);
  238. writel((1<<31 | 1<<28 | (DDR_INTFREQ2<<24) | DDR_FRACFREQ2),
  239. &cmpll->ddrpll_freq2);
  240. writel(((1<<8) | DDR_MDIV2), &cmpll->ddrpll_div2);
  241. writel(((0<<8) | DDR_MDIV3), &cmpll->ddrpll_div3);
  242. ddr_delay(1);
  243. writel(((1<<8) | DDR_MDIV3), &cmpll->ddrpll_div3);
  244. ddr_delay(1);
  245. writel((0<<31 | 1<<28 | (DDR_INTFREQ3<<24) | DDR_FRACFREQ3),
  246. &cmpll->ddrpll_freq3);
  247. ddr_delay(1);
  248. writel((1<<31 | 1<<28 | (DDR_INTFREQ3<<24) | DDR_FRACFREQ3),
  249. &cmpll->ddrpll_freq3);
  250. ddr_delay(5);
  251. /* Wait for PLL to lock */
  252. while ((readl(&cmpll->ddrpll_ctrl) & BIT(7)) != BIT(7))
  253. ;
  254. /* Power up RCD */
  255. writel(BIT(0), DDR_RCD);
  256. }
  257. static void peripheral_enable(void)
  258. {
  259. /* Wake-up the l3_slow clock */
  260. writel(PRCM_MOD_EN, &cmalwon->l3slowclkstctrl);
  261. /*
  262. * Note on Timers:
  263. * There are 8 timers(0-7) out of which timer 0 is a secure timer.
  264. * Timer 0 mux should not be changed
  265. *
  266. * To access the timer registers we need the to be
  267. * enabled which is what we do in the first step
  268. */
  269. /* Enable timer1 */
  270. writel(PRCM_MOD_EN, &cmalwon->timer1clkctrl);
  271. /* Select timer1 clock to be CLKIN (27MHz) */
  272. writel(BIT(1), CM_TIMER1_CLKSEL);
  273. /* Wait for timer1 to be ON-ACTIVE */
  274. while (((readl(&cmalwon->l3slowclkstctrl)
  275. & (0x80000<<1))>>20) != 1)
  276. ;
  277. /* Wait for timer1 to be enabled */
  278. while (((readl(&cmalwon->timer1clkctrl) & 0x30000)>>16) != 0)
  279. ;
  280. /* Active posted mode */
  281. writel(PRCM_MOD_EN, (DM_TIMER1_BASE + 0x54));
  282. while (readl(DM_TIMER1_BASE + 0x10) & BIT(0))
  283. ;
  284. /* Start timer1 */
  285. writel(BIT(0), (DM_TIMER1_BASE + 0x38));
  286. /* eFuse */
  287. writel(PRCM_MOD_EN, CM_ALWON_CUST_EFUSE_CLKCTRL);
  288. while (readl(CM_ALWON_CUST_EFUSE_CLKCTRL) != PRCM_MOD_EN)
  289. ;
  290. /* Enable gpio0 */
  291. writel(PRCM_MOD_EN, &cmalwon->gpio0clkctrl);
  292. while (readl(&cmalwon->gpio0clkctrl) != PRCM_MOD_EN)
  293. ;
  294. writel((BIT(1) | BIT(8)), &cmalwon->gpio0clkctrl);
  295. /* Enable gpio1 */
  296. writel(PRCM_MOD_EN, &cmalwon->gpio1clkctrl);
  297. while (readl(&cmalwon->gpio1clkctrl) != PRCM_MOD_EN)
  298. ;
  299. writel((BIT(1) | BIT(8)), &cmalwon->gpio1clkctrl);
  300. /* Enable spi */
  301. writel(PRCM_MOD_EN, &cmalwon->spiclkctrl);
  302. while (readl(&cmalwon->spiclkctrl) != PRCM_MOD_EN)
  303. ;
  304. /* Enable i2c0 */
  305. writel(PRCM_MOD_EN, &cmalwon->i2c0clkctrl);
  306. while (readl(&cmalwon->i2c0clkctrl) != PRCM_MOD_EN)
  307. ;
  308. /* Enable ethernet0 */
  309. writel(PRCM_MOD_EN, &cmalwon->ethclkstctrl);
  310. writel(PRCM_MOD_EN, &cmalwon->ethernet0clkctrl);
  311. writel(PRCM_MOD_EN, &cmalwon->ethernet1clkctrl);
  312. /* Enable hsmmc */
  313. writel(PRCM_MOD_EN, &cmalwon->sdioclkctrl);
  314. while (readl(&cmalwon->sdioclkctrl) != PRCM_MOD_EN)
  315. ;
  316. }
  317. void setup_clocks_for_console(void)
  318. {
  319. /* Fix ROM code bug - from TI-PSP-04.00.02.14 */
  320. writel(0x0, CM_SYSCLK10_CLKSEL);
  321. ddr_pll_bypass_ti816x();
  322. /* Enable uart0-2 */
  323. writel(PRCM_MOD_EN, &cmalwon->uart0clkctrl);
  324. while (readl(&cmalwon->uart0clkctrl) != PRCM_MOD_EN)
  325. ;
  326. writel(PRCM_MOD_EN, &cmalwon->uart1clkctrl);
  327. while (readl(&cmalwon->uart1clkctrl) != PRCM_MOD_EN)
  328. ;
  329. writel(PRCM_MOD_EN, &cmalwon->uart2clkctrl);
  330. while (readl(&cmalwon->uart2clkctrl) != PRCM_MOD_EN)
  331. ;
  332. while ((readl(&cmalwon->l3slowclkstctrl) & 0x2100) != 0x2100)
  333. ;
  334. }
  335. void setup_early_clocks(void)
  336. {
  337. setup_clocks_for_console();
  338. }
  339. void prcm_init(void)
  340. {
  341. /* Enable the control */
  342. writel(PRCM_MOD_EN, &cmalwon->controlclkctrl);
  343. main_pll_init_ti816x();
  344. ddr_pll_init_ti816x();
  345. /*
  346. * With clk freqs setup to desired values,
  347. * enable the required peripherals
  348. */
  349. peripheral_enable();
  350. }