clock.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806
  1. /*
  2. * Copyright (C) 2010-2011 Freescale Semiconductor, Inc.
  3. *
  4. * SPDX-License-Identifier: GPL-2.0+
  5. */
  6. #include <common.h>
  7. #include <div64.h>
  8. #include <asm/io.h>
  9. #include <asm/errno.h>
  10. #include <asm/arch/imx-regs.h>
  11. #include <asm/arch/crm_regs.h>
  12. #include <asm/arch/clock.h>
  13. #include <asm/arch/sys_proto.h>
  14. enum pll_clocks {
  15. PLL_SYS, /* System PLL */
  16. PLL_BUS, /* System Bus PLL*/
  17. PLL_USBOTG, /* OTG USB PLL */
  18. PLL_ENET, /* ENET PLL */
  19. };
  20. struct mxc_ccm_reg *imx_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
  21. #ifdef CONFIG_MXC_OCOTP
  22. void enable_ocotp_clk(unsigned char enable)
  23. {
  24. u32 reg;
  25. reg = __raw_readl(&imx_ccm->CCGR2);
  26. if (enable)
  27. reg |= MXC_CCM_CCGR2_OCOTP_CTRL_MASK;
  28. else
  29. reg &= ~MXC_CCM_CCGR2_OCOTP_CTRL_MASK;
  30. __raw_writel(reg, &imx_ccm->CCGR2);
  31. }
  32. #endif
  33. #ifdef CONFIG_NAND_MXS
  34. void setup_gpmi_io_clk(u32 cfg)
  35. {
  36. /* Disable clocks per ERR007177 from MX6 errata */
  37. clrbits_le32(&imx_ccm->CCGR4,
  38. MXC_CCM_CCGR4_RAWNAND_U_BCH_INPUT_APB_MASK |
  39. MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_BCH_MASK |
  40. MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK |
  41. MXC_CCM_CCGR4_RAWNAND_U_GPMI_INPUT_APB_MASK |
  42. MXC_CCM_CCGR4_PL301_MX6QPER1_BCH_MASK);
  43. clrbits_le32(&imx_ccm->CCGR2, MXC_CCM_CCGR2_IOMUX_IPT_CLK_IO_MASK);
  44. clrsetbits_le32(&imx_ccm->cs2cdr,
  45. MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK |
  46. MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK |
  47. MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK,
  48. cfg);
  49. setbits_le32(&imx_ccm->CCGR2, MXC_CCM_CCGR2_IOMUX_IPT_CLK_IO_MASK);
  50. setbits_le32(&imx_ccm->CCGR4,
  51. MXC_CCM_CCGR4_RAWNAND_U_BCH_INPUT_APB_MASK |
  52. MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_BCH_MASK |
  53. MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK |
  54. MXC_CCM_CCGR4_RAWNAND_U_GPMI_INPUT_APB_MASK |
  55. MXC_CCM_CCGR4_PL301_MX6QPER1_BCH_MASK);
  56. }
  57. #endif
  58. void enable_usboh3_clk(unsigned char enable)
  59. {
  60. u32 reg;
  61. reg = __raw_readl(&imx_ccm->CCGR6);
  62. if (enable)
  63. reg |= MXC_CCM_CCGR6_USBOH3_MASK;
  64. else
  65. reg &= ~(MXC_CCM_CCGR6_USBOH3_MASK);
  66. __raw_writel(reg, &imx_ccm->CCGR6);
  67. }
  68. #if defined(CONFIG_FEC_MXC) && !defined(CONFIG_MX6SX)
  69. void enable_enet_clk(unsigned char enable)
  70. {
  71. u32 mask = MXC_CCM_CCGR1_ENET_CLK_ENABLE_MASK;
  72. if (enable)
  73. setbits_le32(&imx_ccm->CCGR1, mask);
  74. else
  75. clrbits_le32(&imx_ccm->CCGR1, mask);
  76. }
  77. #endif
  78. #ifdef CONFIG_MXC_UART
  79. void enable_uart_clk(unsigned char enable)
  80. {
  81. u32 mask = MXC_CCM_CCGR5_UART_MASK | MXC_CCM_CCGR5_UART_SERIAL_MASK;
  82. if (enable)
  83. setbits_le32(&imx_ccm->CCGR5, mask);
  84. else
  85. clrbits_le32(&imx_ccm->CCGR5, mask);
  86. }
  87. #endif
  88. #ifdef CONFIG_SPI
  89. /* spi_num can be from 0 - 4 */
  90. int enable_cspi_clock(unsigned char enable, unsigned spi_num)
  91. {
  92. u32 mask;
  93. if (spi_num > 4)
  94. return -EINVAL;
  95. mask = MXC_CCM_CCGR_CG_MASK << (spi_num * 2);
  96. if (enable)
  97. setbits_le32(&imx_ccm->CCGR1, mask);
  98. else
  99. clrbits_le32(&imx_ccm->CCGR1, mask);
  100. return 0;
  101. }
  102. #endif
  103. #ifdef CONFIG_MMC
  104. int enable_usdhc_clk(unsigned char enable, unsigned bus_num)
  105. {
  106. u32 mask;
  107. if (bus_num > 3)
  108. return -EINVAL;
  109. mask = MXC_CCM_CCGR_CG_MASK << (bus_num * 2 + 2);
  110. if (enable)
  111. setbits_le32(&imx_ccm->CCGR6, mask);
  112. else
  113. clrbits_le32(&imx_ccm->CCGR6, mask);
  114. return 0;
  115. }
  116. #endif
  117. #ifdef CONFIG_SYS_I2C_MXC
  118. /* i2c_num can be from 0 - 2 */
  119. int enable_i2c_clk(unsigned char enable, unsigned i2c_num)
  120. {
  121. u32 reg;
  122. u32 mask;
  123. if (i2c_num > 2)
  124. return -EINVAL;
  125. mask = MXC_CCM_CCGR_CG_MASK
  126. << (MXC_CCM_CCGR2_I2C1_SERIAL_OFFSET + (i2c_num << 1));
  127. reg = __raw_readl(&imx_ccm->CCGR2);
  128. if (enable)
  129. reg |= mask;
  130. else
  131. reg &= ~mask;
  132. __raw_writel(reg, &imx_ccm->CCGR2);
  133. return 0;
  134. }
  135. #endif
  136. /* spi_num can be from 0 - SPI_MAX_NUM */
  137. int enable_spi_clk(unsigned char enable, unsigned spi_num)
  138. {
  139. u32 reg;
  140. u32 mask;
  141. if (spi_num > SPI_MAX_NUM)
  142. return -EINVAL;
  143. mask = MXC_CCM_CCGR_CG_MASK << (spi_num << 1);
  144. reg = __raw_readl(&imx_ccm->CCGR1);
  145. if (enable)
  146. reg |= mask;
  147. else
  148. reg &= ~mask;
  149. __raw_writel(reg, &imx_ccm->CCGR1);
  150. return 0;
  151. }
  152. static u32 decode_pll(enum pll_clocks pll, u32 infreq)
  153. {
  154. u32 div;
  155. switch (pll) {
  156. case PLL_SYS:
  157. div = __raw_readl(&imx_ccm->analog_pll_sys);
  158. div &= BM_ANADIG_PLL_SYS_DIV_SELECT;
  159. return (infreq * div) >> 1;
  160. case PLL_BUS:
  161. div = __raw_readl(&imx_ccm->analog_pll_528);
  162. div &= BM_ANADIG_PLL_528_DIV_SELECT;
  163. return infreq * (20 + (div << 1));
  164. case PLL_USBOTG:
  165. div = __raw_readl(&imx_ccm->analog_usb1_pll_480_ctrl);
  166. div &= BM_ANADIG_USB1_PLL_480_CTRL_DIV_SELECT;
  167. return infreq * (20 + (div << 1));
  168. case PLL_ENET:
  169. div = __raw_readl(&imx_ccm->analog_pll_enet);
  170. div &= BM_ANADIG_PLL_ENET_DIV_SELECT;
  171. return 25000000 * (div + (div >> 1) + 1);
  172. default:
  173. return 0;
  174. }
  175. /* NOTREACHED */
  176. }
  177. static u32 mxc_get_pll_pfd(enum pll_clocks pll, int pfd_num)
  178. {
  179. u32 div;
  180. u64 freq;
  181. switch (pll) {
  182. case PLL_BUS:
  183. if (pfd_num == 3) {
  184. /* No PFD3 on PPL2 */
  185. return 0;
  186. }
  187. div = __raw_readl(&imx_ccm->analog_pfd_528);
  188. freq = (u64)decode_pll(PLL_BUS, MXC_HCLK);
  189. break;
  190. case PLL_USBOTG:
  191. div = __raw_readl(&imx_ccm->analog_pfd_480);
  192. freq = (u64)decode_pll(PLL_USBOTG, MXC_HCLK);
  193. break;
  194. default:
  195. /* No PFD on other PLL */
  196. return 0;
  197. }
  198. return lldiv(freq * 18, (div & ANATOP_PFD_FRAC_MASK(pfd_num)) >>
  199. ANATOP_PFD_FRAC_SHIFT(pfd_num));
  200. }
  201. static u32 get_mcu_main_clk(void)
  202. {
  203. u32 reg, freq;
  204. reg = __raw_readl(&imx_ccm->cacrr);
  205. reg &= MXC_CCM_CACRR_ARM_PODF_MASK;
  206. reg >>= MXC_CCM_CACRR_ARM_PODF_OFFSET;
  207. freq = decode_pll(PLL_SYS, MXC_HCLK);
  208. return freq / (reg + 1);
  209. }
  210. u32 get_periph_clk(void)
  211. {
  212. u32 reg, freq = 0;
  213. reg = __raw_readl(&imx_ccm->cbcdr);
  214. if (reg & MXC_CCM_CBCDR_PERIPH_CLK_SEL) {
  215. reg = __raw_readl(&imx_ccm->cbcmr);
  216. reg &= MXC_CCM_CBCMR_PERIPH_CLK2_SEL_MASK;
  217. reg >>= MXC_CCM_CBCMR_PERIPH_CLK2_SEL_OFFSET;
  218. switch (reg) {
  219. case 0:
  220. freq = decode_pll(PLL_USBOTG, MXC_HCLK);
  221. break;
  222. case 1:
  223. case 2:
  224. freq = MXC_HCLK;
  225. break;
  226. default:
  227. break;
  228. }
  229. } else {
  230. reg = __raw_readl(&imx_ccm->cbcmr);
  231. reg &= MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK;
  232. reg >>= MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_OFFSET;
  233. switch (reg) {
  234. case 0:
  235. freq = decode_pll(PLL_BUS, MXC_HCLK);
  236. break;
  237. case 1:
  238. freq = mxc_get_pll_pfd(PLL_BUS, 2);
  239. break;
  240. case 2:
  241. freq = mxc_get_pll_pfd(PLL_BUS, 0);
  242. break;
  243. case 3:
  244. /* static / 2 divider */
  245. freq = mxc_get_pll_pfd(PLL_BUS, 2) / 2;
  246. break;
  247. default:
  248. break;
  249. }
  250. }
  251. return freq;
  252. }
  253. static u32 get_ipg_clk(void)
  254. {
  255. u32 reg, ipg_podf;
  256. reg = __raw_readl(&imx_ccm->cbcdr);
  257. reg &= MXC_CCM_CBCDR_IPG_PODF_MASK;
  258. ipg_podf = reg >> MXC_CCM_CBCDR_IPG_PODF_OFFSET;
  259. return get_ahb_clk() / (ipg_podf + 1);
  260. }
  261. static u32 get_ipg_per_clk(void)
  262. {
  263. u32 reg, perclk_podf;
  264. reg = __raw_readl(&imx_ccm->cscmr1);
  265. #if (defined(CONFIG_MX6SL) || defined(CONFIG_MX6SX))
  266. if (reg & MXC_CCM_CSCMR1_PER_CLK_SEL_MASK)
  267. return MXC_HCLK; /* OSC 24Mhz */
  268. #endif
  269. perclk_podf = reg & MXC_CCM_CSCMR1_PERCLK_PODF_MASK;
  270. return get_ipg_clk() / (perclk_podf + 1);
  271. }
  272. static u32 get_uart_clk(void)
  273. {
  274. u32 reg, uart_podf;
  275. u32 freq = decode_pll(PLL_USBOTG, MXC_HCLK) / 6; /* static divider */
  276. reg = __raw_readl(&imx_ccm->cscdr1);
  277. #if (defined(CONFIG_MX6SL) || defined(CONFIG_MX6SX))
  278. if (reg & MXC_CCM_CSCDR1_UART_CLK_SEL)
  279. freq = MXC_HCLK;
  280. #endif
  281. reg &= MXC_CCM_CSCDR1_UART_CLK_PODF_MASK;
  282. uart_podf = reg >> MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET;
  283. return freq / (uart_podf + 1);
  284. }
  285. static u32 get_cspi_clk(void)
  286. {
  287. u32 reg, cspi_podf;
  288. reg = __raw_readl(&imx_ccm->cscdr2);
  289. reg &= MXC_CCM_CSCDR2_ECSPI_CLK_PODF_MASK;
  290. cspi_podf = reg >> MXC_CCM_CSCDR2_ECSPI_CLK_PODF_OFFSET;
  291. return decode_pll(PLL_USBOTG, MXC_HCLK) / (8 * (cspi_podf + 1));
  292. }
  293. static u32 get_axi_clk(void)
  294. {
  295. u32 root_freq, axi_podf;
  296. u32 cbcdr = __raw_readl(&imx_ccm->cbcdr);
  297. axi_podf = cbcdr & MXC_CCM_CBCDR_AXI_PODF_MASK;
  298. axi_podf >>= MXC_CCM_CBCDR_AXI_PODF_OFFSET;
  299. if (cbcdr & MXC_CCM_CBCDR_AXI_SEL) {
  300. if (cbcdr & MXC_CCM_CBCDR_AXI_ALT_SEL)
  301. root_freq = mxc_get_pll_pfd(PLL_BUS, 2);
  302. else
  303. root_freq = mxc_get_pll_pfd(PLL_USBOTG, 1);
  304. } else
  305. root_freq = get_periph_clk();
  306. return root_freq / (axi_podf + 1);
  307. }
  308. static u32 get_emi_slow_clk(void)
  309. {
  310. u32 emi_clk_sel, emi_slow_podf, cscmr1, root_freq = 0;
  311. cscmr1 = __raw_readl(&imx_ccm->cscmr1);
  312. emi_clk_sel = cscmr1 & MXC_CCM_CSCMR1_ACLK_EMI_SLOW_MASK;
  313. emi_clk_sel >>= MXC_CCM_CSCMR1_ACLK_EMI_SLOW_OFFSET;
  314. emi_slow_podf = cscmr1 & MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_MASK;
  315. emi_slow_podf >>= MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_OFFSET;
  316. switch (emi_clk_sel) {
  317. case 0:
  318. root_freq = get_axi_clk();
  319. break;
  320. case 1:
  321. root_freq = decode_pll(PLL_USBOTG, MXC_HCLK);
  322. break;
  323. case 2:
  324. root_freq = mxc_get_pll_pfd(PLL_BUS, 2);
  325. break;
  326. case 3:
  327. root_freq = mxc_get_pll_pfd(PLL_BUS, 0);
  328. break;
  329. }
  330. return root_freq / (emi_slow_podf + 1);
  331. }
  332. #if (defined(CONFIG_MX6SL) || defined(CONFIG_MX6SX))
  333. static u32 get_mmdc_ch0_clk(void)
  334. {
  335. u32 cbcmr = __raw_readl(&imx_ccm->cbcmr);
  336. u32 cbcdr = __raw_readl(&imx_ccm->cbcdr);
  337. u32 freq, podf;
  338. podf = (cbcdr & MXC_CCM_CBCDR_MMDC_CH1_PODF_MASK) \
  339. >> MXC_CCM_CBCDR_MMDC_CH1_PODF_OFFSET;
  340. switch ((cbcmr & MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_MASK) >>
  341. MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_OFFSET) {
  342. case 0:
  343. freq = decode_pll(PLL_BUS, MXC_HCLK);
  344. break;
  345. case 1:
  346. freq = mxc_get_pll_pfd(PLL_BUS, 2);
  347. break;
  348. case 2:
  349. freq = mxc_get_pll_pfd(PLL_BUS, 0);
  350. break;
  351. case 3:
  352. /* static / 2 divider */
  353. freq = mxc_get_pll_pfd(PLL_BUS, 2) / 2;
  354. }
  355. return freq / (podf + 1);
  356. }
  357. #else
  358. static u32 get_mmdc_ch0_clk(void)
  359. {
  360. u32 cbcdr = __raw_readl(&imx_ccm->cbcdr);
  361. u32 mmdc_ch0_podf = (cbcdr & MXC_CCM_CBCDR_MMDC_CH0_PODF_MASK) >>
  362. MXC_CCM_CBCDR_MMDC_CH0_PODF_OFFSET;
  363. return get_periph_clk() / (mmdc_ch0_podf + 1);
  364. }
  365. #endif
  366. #ifdef CONFIG_FEC_MXC
  367. int enable_fec_anatop_clock(enum enet_freq freq)
  368. {
  369. u32 reg = 0;
  370. s32 timeout = 100000;
  371. struct anatop_regs __iomem *anatop =
  372. (struct anatop_regs __iomem *)ANATOP_BASE_ADDR;
  373. if (freq < ENET_25MHZ || freq > ENET_125MHZ)
  374. return -EINVAL;
  375. reg = readl(&anatop->pll_enet);
  376. reg &= ~BM_ANADIG_PLL_ENET_DIV_SELECT;
  377. reg |= freq;
  378. if ((reg & BM_ANADIG_PLL_ENET_POWERDOWN) ||
  379. (!(reg & BM_ANADIG_PLL_ENET_LOCK))) {
  380. reg &= ~BM_ANADIG_PLL_ENET_POWERDOWN;
  381. writel(reg, &anatop->pll_enet);
  382. while (timeout--) {
  383. if (readl(&anatop->pll_enet) & BM_ANADIG_PLL_ENET_LOCK)
  384. break;
  385. }
  386. if (timeout < 0)
  387. return -ETIMEDOUT;
  388. }
  389. /* Enable FEC clock */
  390. reg |= BM_ANADIG_PLL_ENET_ENABLE;
  391. reg &= ~BM_ANADIG_PLL_ENET_BYPASS;
  392. writel(reg, &anatop->pll_enet);
  393. #ifdef CONFIG_MX6SX
  394. /*
  395. * Set enet ahb clock to 200MHz
  396. * pll2_pfd2_396m-> ENET_PODF-> ENET_AHB
  397. */
  398. reg = readl(&imx_ccm->chsccdr);
  399. reg &= ~(MXC_CCM_CHSCCDR_ENET_PRE_CLK_SEL_MASK
  400. | MXC_CCM_CHSCCDR_ENET_PODF_MASK
  401. | MXC_CCM_CHSCCDR_ENET_CLK_SEL_MASK);
  402. /* PLL2 PFD2 */
  403. reg |= (4 << MXC_CCM_CHSCCDR_ENET_PRE_CLK_SEL_OFFSET);
  404. /* Div = 2*/
  405. reg |= (1 << MXC_CCM_CHSCCDR_ENET_PODF_OFFSET);
  406. reg |= (0 << MXC_CCM_CHSCCDR_ENET_CLK_SEL_OFFSET);
  407. writel(reg, &imx_ccm->chsccdr);
  408. /* Enable enet system clock */
  409. reg = readl(&imx_ccm->CCGR3);
  410. reg |= MXC_CCM_CCGR3_ENET_MASK;
  411. writel(reg, &imx_ccm->CCGR3);
  412. #endif
  413. return 0;
  414. }
  415. #endif
  416. static u32 get_usdhc_clk(u32 port)
  417. {
  418. u32 root_freq = 0, usdhc_podf = 0, clk_sel = 0;
  419. u32 cscmr1 = __raw_readl(&imx_ccm->cscmr1);
  420. u32 cscdr1 = __raw_readl(&imx_ccm->cscdr1);
  421. switch (port) {
  422. case 0:
  423. usdhc_podf = (cscdr1 & MXC_CCM_CSCDR1_USDHC1_PODF_MASK) >>
  424. MXC_CCM_CSCDR1_USDHC1_PODF_OFFSET;
  425. clk_sel = cscmr1 & MXC_CCM_CSCMR1_USDHC1_CLK_SEL;
  426. break;
  427. case 1:
  428. usdhc_podf = (cscdr1 & MXC_CCM_CSCDR1_USDHC2_PODF_MASK) >>
  429. MXC_CCM_CSCDR1_USDHC2_PODF_OFFSET;
  430. clk_sel = cscmr1 & MXC_CCM_CSCMR1_USDHC2_CLK_SEL;
  431. break;
  432. case 2:
  433. usdhc_podf = (cscdr1 & MXC_CCM_CSCDR1_USDHC3_PODF_MASK) >>
  434. MXC_CCM_CSCDR1_USDHC3_PODF_OFFSET;
  435. clk_sel = cscmr1 & MXC_CCM_CSCMR1_USDHC3_CLK_SEL;
  436. break;
  437. case 3:
  438. usdhc_podf = (cscdr1 & MXC_CCM_CSCDR1_USDHC4_PODF_MASK) >>
  439. MXC_CCM_CSCDR1_USDHC4_PODF_OFFSET;
  440. clk_sel = cscmr1 & MXC_CCM_CSCMR1_USDHC4_CLK_SEL;
  441. break;
  442. default:
  443. break;
  444. }
  445. if (clk_sel)
  446. root_freq = mxc_get_pll_pfd(PLL_BUS, 0);
  447. else
  448. root_freq = mxc_get_pll_pfd(PLL_BUS, 2);
  449. return root_freq / (usdhc_podf + 1);
  450. }
  451. u32 imx_get_uartclk(void)
  452. {
  453. return get_uart_clk();
  454. }
  455. u32 imx_get_fecclk(void)
  456. {
  457. return mxc_get_clock(MXC_IPG_CLK);
  458. }
  459. static int enable_enet_pll(uint32_t en)
  460. {
  461. struct mxc_ccm_reg *const imx_ccm
  462. = (struct mxc_ccm_reg *) CCM_BASE_ADDR;
  463. s32 timeout = 100000;
  464. u32 reg = 0;
  465. /* Enable PLLs */
  466. reg = readl(&imx_ccm->analog_pll_enet);
  467. reg &= ~BM_ANADIG_PLL_SYS_POWERDOWN;
  468. writel(reg, &imx_ccm->analog_pll_enet);
  469. reg |= BM_ANADIG_PLL_SYS_ENABLE;
  470. while (timeout--) {
  471. if (readl(&imx_ccm->analog_pll_enet) & BM_ANADIG_PLL_SYS_LOCK)
  472. break;
  473. }
  474. if (timeout <= 0)
  475. return -EIO;
  476. reg &= ~BM_ANADIG_PLL_SYS_BYPASS;
  477. writel(reg, &imx_ccm->analog_pll_enet);
  478. reg |= en;
  479. writel(reg, &imx_ccm->analog_pll_enet);
  480. return 0;
  481. }
  482. #ifndef CONFIG_MX6SX
  483. static void ungate_sata_clock(void)
  484. {
  485. struct mxc_ccm_reg *const imx_ccm =
  486. (struct mxc_ccm_reg *)CCM_BASE_ADDR;
  487. /* Enable SATA clock. */
  488. setbits_le32(&imx_ccm->CCGR5, MXC_CCM_CCGR5_SATA_MASK);
  489. }
  490. #endif
  491. static void ungate_pcie_clock(void)
  492. {
  493. struct mxc_ccm_reg *const imx_ccm =
  494. (struct mxc_ccm_reg *)CCM_BASE_ADDR;
  495. /* Enable PCIe clock. */
  496. setbits_le32(&imx_ccm->CCGR4, MXC_CCM_CCGR4_PCIE_MASK);
  497. }
  498. #ifndef CONFIG_MX6SX
  499. int enable_sata_clock(void)
  500. {
  501. ungate_sata_clock();
  502. return enable_enet_pll(BM_ANADIG_PLL_ENET_ENABLE_SATA);
  503. }
  504. void disable_sata_clock(void)
  505. {
  506. struct mxc_ccm_reg *const imx_ccm =
  507. (struct mxc_ccm_reg *)CCM_BASE_ADDR;
  508. clrbits_le32(&imx_ccm->CCGR5, MXC_CCM_CCGR5_SATA_MASK);
  509. }
  510. #endif
  511. int enable_pcie_clock(void)
  512. {
  513. struct anatop_regs *anatop_regs =
  514. (struct anatop_regs *)ANATOP_BASE_ADDR;
  515. struct mxc_ccm_reg *ccm_regs = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
  516. u32 lvds1_clk_sel;
  517. /*
  518. * Here be dragons!
  519. *
  520. * The register ANATOP_MISC1 is not documented in the Freescale
  521. * MX6RM. The register that is mapped in the ANATOP space and
  522. * marked as ANATOP_MISC1 is actually documented in the PMU section
  523. * of the datasheet as PMU_MISC1.
  524. *
  525. * Switch LVDS clock source to SATA (0xb) on mx6q/dl or PCI (0xa) on
  526. * mx6sx, disable clock INPUT and enable clock OUTPUT. This is important
  527. * for PCI express link that is clocked from the i.MX6.
  528. */
  529. #define ANADIG_ANA_MISC1_LVDSCLK1_IBEN (1 << 12)
  530. #define ANADIG_ANA_MISC1_LVDSCLK1_OBEN (1 << 10)
  531. #define ANADIG_ANA_MISC1_LVDS1_CLK_SEL_MASK 0x0000001F
  532. #define ANADIG_ANA_MISC1_LVDS1_CLK_SEL_PCIE_REF 0xa
  533. #define ANADIG_ANA_MISC1_LVDS1_CLK_SEL_SATA_REF 0xb
  534. if (is_cpu_type(MXC_CPU_MX6SX))
  535. lvds1_clk_sel = ANADIG_ANA_MISC1_LVDS1_CLK_SEL_PCIE_REF;
  536. else
  537. lvds1_clk_sel = ANADIG_ANA_MISC1_LVDS1_CLK_SEL_SATA_REF;
  538. clrsetbits_le32(&anatop_regs->ana_misc1,
  539. ANADIG_ANA_MISC1_LVDSCLK1_IBEN |
  540. ANADIG_ANA_MISC1_LVDS1_CLK_SEL_MASK,
  541. ANADIG_ANA_MISC1_LVDSCLK1_OBEN | lvds1_clk_sel);
  542. /* PCIe reference clock sourced from AXI. */
  543. clrbits_le32(&ccm_regs->cbcmr, MXC_CCM_CBCMR_PCIE_AXI_CLK_SEL);
  544. /* Party time! Ungate the clock to the PCIe. */
  545. #ifndef CONFIG_MX6SX
  546. ungate_sata_clock();
  547. #endif
  548. ungate_pcie_clock();
  549. return enable_enet_pll(BM_ANADIG_PLL_ENET_ENABLE_SATA |
  550. BM_ANADIG_PLL_ENET_ENABLE_PCIE);
  551. }
  552. #ifdef CONFIG_SECURE_BOOT
  553. void hab_caam_clock_enable(unsigned char enable)
  554. {
  555. u32 reg;
  556. /* CG4 ~ CG6, CAAM clocks */
  557. reg = __raw_readl(&imx_ccm->CCGR0);
  558. if (enable)
  559. reg |= (MXC_CCM_CCGR0_CAAM_WRAPPER_IPG_MASK |
  560. MXC_CCM_CCGR0_CAAM_WRAPPER_ACLK_MASK |
  561. MXC_CCM_CCGR0_CAAM_SECURE_MEM_MASK);
  562. else
  563. reg &= ~(MXC_CCM_CCGR0_CAAM_WRAPPER_IPG_MASK |
  564. MXC_CCM_CCGR0_CAAM_WRAPPER_ACLK_MASK |
  565. MXC_CCM_CCGR0_CAAM_SECURE_MEM_MASK);
  566. __raw_writel(reg, &imx_ccm->CCGR0);
  567. /* EMI slow clk */
  568. reg = __raw_readl(&imx_ccm->CCGR6);
  569. if (enable)
  570. reg |= MXC_CCM_CCGR6_EMI_SLOW_MASK;
  571. else
  572. reg &= ~MXC_CCM_CCGR6_EMI_SLOW_MASK;
  573. __raw_writel(reg, &imx_ccm->CCGR6);
  574. }
  575. #endif
  576. static void enable_pll3(void)
  577. {
  578. struct anatop_regs __iomem *anatop =
  579. (struct anatop_regs __iomem *)ANATOP_BASE_ADDR;
  580. /* make sure pll3 is enabled */
  581. if ((readl(&anatop->usb1_pll_480_ctrl) &
  582. BM_ANADIG_USB1_PLL_480_CTRL_LOCK) == 0) {
  583. /* enable pll's power */
  584. writel(BM_ANADIG_USB1_PLL_480_CTRL_POWER,
  585. &anatop->usb1_pll_480_ctrl_set);
  586. writel(0x80, &anatop->ana_misc2_clr);
  587. /* wait for pll lock */
  588. while ((readl(&anatop->usb1_pll_480_ctrl) &
  589. BM_ANADIG_USB1_PLL_480_CTRL_LOCK) == 0)
  590. ;
  591. /* disable bypass */
  592. writel(BM_ANADIG_USB1_PLL_480_CTRL_BYPASS,
  593. &anatop->usb1_pll_480_ctrl_clr);
  594. /* enable pll output */
  595. writel(BM_ANADIG_USB1_PLL_480_CTRL_ENABLE,
  596. &anatop->usb1_pll_480_ctrl_set);
  597. }
  598. }
  599. void enable_thermal_clk(void)
  600. {
  601. enable_pll3();
  602. }
  603. unsigned int mxc_get_clock(enum mxc_clock clk)
  604. {
  605. switch (clk) {
  606. case MXC_ARM_CLK:
  607. return get_mcu_main_clk();
  608. case MXC_PER_CLK:
  609. return get_periph_clk();
  610. case MXC_AHB_CLK:
  611. return get_ahb_clk();
  612. case MXC_IPG_CLK:
  613. return get_ipg_clk();
  614. case MXC_IPG_PERCLK:
  615. case MXC_I2C_CLK:
  616. return get_ipg_per_clk();
  617. case MXC_UART_CLK:
  618. return get_uart_clk();
  619. case MXC_CSPI_CLK:
  620. return get_cspi_clk();
  621. case MXC_AXI_CLK:
  622. return get_axi_clk();
  623. case MXC_EMI_SLOW_CLK:
  624. return get_emi_slow_clk();
  625. case MXC_DDR_CLK:
  626. return get_mmdc_ch0_clk();
  627. case MXC_ESDHC_CLK:
  628. return get_usdhc_clk(0);
  629. case MXC_ESDHC2_CLK:
  630. return get_usdhc_clk(1);
  631. case MXC_ESDHC3_CLK:
  632. return get_usdhc_clk(2);
  633. case MXC_ESDHC4_CLK:
  634. return get_usdhc_clk(3);
  635. case MXC_SATA_CLK:
  636. return get_ahb_clk();
  637. default:
  638. printf("Unsupported MXC CLK: %d\n", clk);
  639. break;
  640. }
  641. return 0;
  642. }
  643. /*
  644. * Dump some core clockes.
  645. */
  646. int do_mx6_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  647. {
  648. u32 freq;
  649. freq = decode_pll(PLL_SYS, MXC_HCLK);
  650. printf("PLL_SYS %8d MHz\n", freq / 1000000);
  651. freq = decode_pll(PLL_BUS, MXC_HCLK);
  652. printf("PLL_BUS %8d MHz\n", freq / 1000000);
  653. freq = decode_pll(PLL_USBOTG, MXC_HCLK);
  654. printf("PLL_OTG %8d MHz\n", freq / 1000000);
  655. freq = decode_pll(PLL_ENET, MXC_HCLK);
  656. printf("PLL_NET %8d MHz\n", freq / 1000000);
  657. printf("\n");
  658. printf("IPG %8d kHz\n", mxc_get_clock(MXC_IPG_CLK) / 1000);
  659. printf("UART %8d kHz\n", mxc_get_clock(MXC_UART_CLK) / 1000);
  660. #ifdef CONFIG_MXC_SPI
  661. printf("CSPI %8d kHz\n", mxc_get_clock(MXC_CSPI_CLK) / 1000);
  662. #endif
  663. printf("AHB %8d kHz\n", mxc_get_clock(MXC_AHB_CLK) / 1000);
  664. printf("AXI %8d kHz\n", mxc_get_clock(MXC_AXI_CLK) / 1000);
  665. printf("DDR %8d kHz\n", mxc_get_clock(MXC_DDR_CLK) / 1000);
  666. printf("USDHC1 %8d kHz\n", mxc_get_clock(MXC_ESDHC_CLK) / 1000);
  667. printf("USDHC2 %8d kHz\n", mxc_get_clock(MXC_ESDHC2_CLK) / 1000);
  668. printf("USDHC3 %8d kHz\n", mxc_get_clock(MXC_ESDHC3_CLK) / 1000);
  669. printf("USDHC4 %8d kHz\n", mxc_get_clock(MXC_ESDHC4_CLK) / 1000);
  670. printf("EMI SLOW %8d kHz\n", mxc_get_clock(MXC_EMI_SLOW_CLK) / 1000);
  671. printf("IPG PERCLK %8d kHz\n", mxc_get_clock(MXC_IPG_PERCLK) / 1000);
  672. return 0;
  673. }
  674. #ifndef CONFIG_MX6SX
  675. void enable_ipu_clock(void)
  676. {
  677. struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
  678. int reg;
  679. reg = readl(&mxc_ccm->CCGR3);
  680. reg |= MXC_CCM_CCGR3_IPU1_IPU_MASK;
  681. writel(reg, &mxc_ccm->CCGR3);
  682. }
  683. #endif
  684. /***************************************************/
  685. U_BOOT_CMD(
  686. clocks, CONFIG_SYS_MAXARGS, 1, do_mx6_showclocks,
  687. "display clocks",
  688. ""
  689. );