2 * Copyright (C) 2010-2011 Freescale Semiconductor, Inc.
4 * See file CREDITS for list of people who contributed to this
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
25 #include <asm/errno.h>
26 #include <asm/arch/imx-regs.h>
27 #include <asm/arch/crm_regs.h>
28 #include <asm/arch/clock.h>
29 #include <asm/arch/sys_proto.h>
32 PLL_ARM, /* PLL1: ARM PLL */
33 PLL_BUS, /* PLL2: System Bus PLL*/
34 PLL_USBOTG, /* PLL3: OTG USB PLL */
35 PLL_AUDIO, /* PLL4: Audio PLL */
36 PLL_VIDEO, /* PLL5: Video PLL */
37 PLL_ENET, /* PLL6: ENET PLL */
38 PLL_USB2, /* PLL7: USB2 PLL */
39 PLL_MLB, /* PLL8: MLB PLL */
42 struct mxc_ccm_reg *const imx_ccm = (void *)CCM_BASE_ADDR;
43 struct anatop_regs *const anatop = (void *)ANATOP_BASE_ADDR;
45 int clk_enable(struct clk *clk)
51 if (clk->usecount == 0) {
52 debug("%s: Enabling %s clock\n", __func__, clk->name);
53 ret = clk->enable(clk);
58 assert(clk->usecount > 0);
62 void clk_disable(struct clk *clk)
67 assert(clk->usecount > 0);
68 if (!(--clk->usecount)) {
70 debug("%s: Disabling %s clock\n", __func__, clk->name);
76 void enable_usboh3_clk(unsigned char enable)
80 reg = __raw_readl(&imx_ccm->CCGR6);
82 reg |= MXC_CCM_CCGR6_USBOH3_MASK;
84 reg &= ~(MXC_CCM_CCGR6_USBOH3_MASK);
85 __raw_writel(reg, &imx_ccm->CCGR6);
90 /* i2c_num can be from 0 - 2 */
91 int enable_i2c_clk(unsigned char enable, unsigned i2c_num)
99 mask = MXC_CCM_CCGR_CG_MASK
100 << (MXC_CCM_CCGR2_I2C1_SERIAL_OFFSET + (i2c_num << 1));
101 reg = __raw_readl(&imx_ccm->CCGR2);
106 __raw_writel(reg, &imx_ccm->CCGR2);
111 static u32 decode_pll(enum pll_clocks pll, u32 infreq)
117 div = __raw_readl(&anatop->pll_arm);
118 if (div & BM_ANADIG_PLL_ARM_BYPASS)
119 /* Assume the bypass clock is always derived from OSC */
121 div &= BM_ANADIG_PLL_ARM_DIV_SELECT;
123 return infreq * div / 2;
125 div = __raw_readl(&anatop->pll_528);
126 if (div & BM_ANADIG_PLL_SYS_BYPASS)
128 div &= BM_ANADIG_PLL_SYS_DIV_SELECT;
130 return infreq * (20 + div * 2);
132 div = __raw_readl(&anatop->usb1_pll_480_ctrl);
133 if (div & BM_ANADIG_USB1_PLL_480_CTRL_BYPASS)
135 div &= BM_ANADIG_USB1_PLL_480_CTRL_DIV_SELECT;
137 return infreq * (20 + div * 2);
139 div = __raw_readl(&anatop->pll_audio);
140 if (div & BM_ANADIG_PLL_AUDIO_BYPASS)
142 div &= BM_ANADIG_PLL_AUDIO_DIV_SELECT;
146 div = __raw_readl(&anatop->pll_video);
147 if (div & BM_ANADIG_PLL_VIDEO_BYPASS)
149 div &= BM_ANADIG_PLL_VIDEO_DIV_SELECT;
153 div = __raw_readl(&anatop->pll_enet);
154 if (div & BM_ANADIG_PLL_ENET_BYPASS)
156 div &= BM_ANADIG_PLL_ENET_DIV_SELECT;
158 return (div == 3 ? 125000000 : 25000000 * div * 2);
160 div = __raw_readl(&anatop->usb2_pll_480_ctrl);
161 if (div & BM_ANADIG_USB2_PLL_480_CTRL_BYPASS)
163 div &= BM_ANADIG_USB2_PLL_480_CTRL_DIV_SELECT;
165 return infreq * (20 + div * 2);
167 div = __raw_readl(&anatop->pll_mlb);
168 if (div & BM_ANADIG_PLL_MLB_BYPASS)
170 /* unknown external clock provided on MLB_CLK pin */
176 static u32 get_mcu_main_clk(void)
180 reg = __raw_readl(&imx_ccm->cacrr);
181 reg &= MXC_CCM_CACRR_ARM_PODF_MASK;
182 reg >>= MXC_CCM_CACRR_ARM_PODF_OFFSET;
183 freq = decode_pll(PLL_ARM, MXC_HCLK);
185 return freq / (reg + 1);
188 u32 get_periph_clk(void)
192 reg = __raw_readl(&imx_ccm->cbcdr);
193 if (reg & MXC_CCM_CBCDR_PERIPH_CLK_SEL) {
194 reg = __raw_readl(&imx_ccm->cbcmr);
195 reg &= MXC_CCM_CBCMR_PERIPH_CLK2_SEL_MASK;
196 reg >>= MXC_CCM_CBCMR_PERIPH_CLK2_SEL_OFFSET;
200 freq = decode_pll(PLL_USBOTG, MXC_HCLK);
208 reg = __raw_readl(&imx_ccm->cbcmr);
209 reg &= MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK;
210 reg >>= MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_OFFSET;
214 freq = decode_pll(PLL_BUS, MXC_HCLK);
217 freq = PLL2_PFD2_FREQ;
220 freq = PLL2_PFD0_FREQ;
223 freq = PLL2_PFD2_DIV_FREQ;
231 static u32 get_ipg_clk(void)
235 reg = __raw_readl(&imx_ccm->cbcdr);
236 reg &= MXC_CCM_CBCDR_IPG_PODF_MASK;
237 ipg_podf = reg >> MXC_CCM_CBCDR_IPG_PODF_OFFSET;
239 return get_ahb_clk() / (ipg_podf + 1);
242 static u32 get_ipg_per_clk(void)
244 u32 reg, perclk_podf;
246 reg = __raw_readl(&imx_ccm->cscmr1);
247 perclk_podf = reg & MXC_CCM_CSCMR1_PERCLK_PODF_MASK;
249 return get_ipg_clk() / (perclk_podf + 1);
252 static u32 get_uart_clk(void)
256 reg = __raw_readl(&imx_ccm->cscdr1);
257 reg &= MXC_CCM_CSCDR1_UART_CLK_PODF_MASK;
258 uart_podf = reg >> MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET;
260 return PLL3_80M / (uart_podf + 1);
263 static u32 get_cspi_clk(void)
267 reg = __raw_readl(&imx_ccm->cscdr2);
268 reg &= MXC_CCM_CSCDR2_ECSPI_CLK_PODF_MASK;
269 cspi_podf = reg >> MXC_CCM_CSCDR2_ECSPI_CLK_PODF_OFFSET;
271 return PLL3_60M / (cspi_podf + 1);
274 static u32 get_axi_clk(void)
276 u32 root_freq, axi_podf;
277 u32 cbcdr = __raw_readl(&imx_ccm->cbcdr);
279 axi_podf = cbcdr & MXC_CCM_CBCDR_AXI_PODF_MASK;
280 axi_podf >>= MXC_CCM_CBCDR_AXI_PODF_OFFSET;
282 if (cbcdr & MXC_CCM_CBCDR_AXI_SEL) {
283 if (cbcdr & MXC_CCM_CBCDR_AXI_ALT_SEL)
284 root_freq = PLL2_PFD2_FREQ;
286 root_freq = PLL3_PFD1_FREQ;
288 root_freq = get_periph_clk();
290 return root_freq / (axi_podf + 1);
293 static u32 get_emi_slow_clk(void)
295 u32 emi_clk_sel, emi_slow_pof, cscmr1, root_freq = 0;
297 cscmr1 = __raw_readl(&imx_ccm->cscmr1);
298 emi_clk_sel = cscmr1 & MXC_CCM_CSCMR1_ACLK_EMI_SLOW_MASK;
299 emi_clk_sel >>= MXC_CCM_CSCMR1_ACLK_EMI_SLOW_OFFSET;
300 emi_slow_pof = cscmr1 & MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_MASK;
301 emi_slow_pof >>= MXC_CCM_CSCMR1_ACLK_EMI_PODF_OFFSET;
303 switch (emi_clk_sel) {
305 root_freq = get_axi_clk();
308 root_freq = decode_pll(PLL_USBOTG, MXC_HCLK);
311 root_freq = PLL2_PFD2_FREQ;
314 root_freq = PLL2_PFD0_FREQ;
318 return root_freq / (emi_slow_pof + 1);
321 static u32 get_nfc_clk(void)
323 u32 cs2cdr = __raw_readl(&imx_ccm->cs2cdr);
324 u32 podf = (cs2cdr & MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK) >> MXC_CCM_CS2CDR_ENFC_CLK_PODF_OFFSET;
325 u32 pred = (cs2cdr & MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK) >> MXC_CCM_CS2CDR_ENFC_CLK_PRED_OFFSET;
326 int nfc_clk_sel = (cs2cdr & MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK) >>
327 MXC_CCM_CS2CDR_ENFC_CLK_SEL_OFFSET;
330 switch (nfc_clk_sel) {
332 root_freq = PLL2_PFD0_FREQ;
335 root_freq = decode_pll(PLL_BUS, MXC_HCLK);
338 root_freq = decode_pll(PLL_USBOTG, MXC_HCLK);
341 root_freq = PLL2_PFD2_FREQ;
344 debug("root=%d[%u] freq=%u pred=%u podf=%u\n", nfc_clk_sel,
345 root_freq, root_freq / (pred + 1) / (podf + 1), pred + 1, podf + 1);
347 return root_freq / (pred + 1) / (podf + 1);
350 #define CS2CDR_ENFC_MASK (MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK | \
351 MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK | \
352 MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK)
354 static int set_nfc_clk(u32 ref, u32 freq_khz)
356 u32 cs2cdr = __raw_readl(&imx_ccm->cs2cdr);
363 u32 freq = freq_khz * 1000;
365 for (nfc_clk_sel = 0; nfc_clk_sel < 4; nfc_clk_sel++) {
369 if (ref < 4 && ref != nfc_clk_sel)
372 switch (nfc_clk_sel) {
374 root_freq = PLL2_PFD0_FREQ;
377 root_freq = decode_pll(PLL_BUS, MXC_HCLK);
380 root_freq = decode_pll(PLL_USBOTG, MXC_HCLK);
383 root_freq = PLL2_PFD2_FREQ;
386 if (root_freq < freq)
389 podf = min(DIV_ROUND_UP(root_freq, freq), 1 << 6);
390 pred = min(DIV_ROUND_UP(root_freq / podf, freq), 8);
391 act_freq = root_freq / pred / podf;
392 err = (freq - act_freq) * 100 / freq;
393 debug("root=%d[%u] freq=%u pred=%u podf=%u act=%u err=%d\n",
394 nfc_clk_sel, root_freq, freq, pred, podf, act_freq, err);
398 nfc_val = (podf - 1) << MXC_CCM_CS2CDR_ENFC_CLK_PODF_OFFSET;
399 nfc_val |= (pred - 1) << MXC_CCM_CS2CDR_ENFC_CLK_PRED_OFFSET;
400 nfc_val |= nfc_clk_sel << MXC_CCM_CS2CDR_ENFC_CLK_SEL_OFFSET;
407 if (nfc_val == ~0 || min_err > 10)
410 if ((cs2cdr & CS2CDR_ENFC_MASK) != nfc_val) {
411 debug("changing cs2cdr from %08x to %08x\n", cs2cdr,
412 (cs2cdr & ~CS2CDR_ENFC_MASK) | nfc_val);
413 __raw_writel((cs2cdr & ~CS2CDR_ENFC_MASK) | nfc_val,
416 debug("Leaving cs2cdr unchanged [%08x]\n", cs2cdr);
421 static u32 get_mmdc_ch0_clk(void)
423 u32 cbcdr = __raw_readl(&imx_ccm->cbcdr);
424 u32 mmdc_ch0_podf = (cbcdr & MXC_CCM_CBCDR_MMDC_CH0_PODF_MASK) >>
425 MXC_CCM_CBCDR_MMDC_CH0_PODF_OFFSET;
427 return get_periph_clk() / (mmdc_ch0_podf + 1);
430 static u32 get_usdhc_clk(u32 port)
432 u32 root_freq = 0, usdhc_podf = 0, clk_sel = 0;
433 u32 cscmr1 = __raw_readl(&imx_ccm->cscmr1);
434 u32 cscdr1 = __raw_readl(&imx_ccm->cscdr1);
438 usdhc_podf = (cscdr1 & MXC_CCM_CSCDR1_USDHC1_PODF_MASK) >>
439 MXC_CCM_CSCDR1_USDHC1_PODF_OFFSET;
440 clk_sel = cscmr1 & MXC_CCM_CSCMR1_USDHC1_CLK_SEL;
444 usdhc_podf = (cscdr1 & MXC_CCM_CSCDR1_USDHC2_PODF_MASK) >>
445 MXC_CCM_CSCDR1_USDHC2_PODF_OFFSET;
446 clk_sel = cscmr1 & MXC_CCM_CSCMR1_USDHC2_CLK_SEL;
450 usdhc_podf = (cscdr1 & MXC_CCM_CSCDR1_USDHC3_PODF_MASK) >>
451 MXC_CCM_CSCDR1_USDHC3_PODF_OFFSET;
452 clk_sel = cscmr1 & MXC_CCM_CSCMR1_USDHC3_CLK_SEL;
456 usdhc_podf = (cscdr1 & MXC_CCM_CSCDR1_USDHC4_PODF_MASK) >>
457 MXC_CCM_CSCDR1_USDHC4_PODF_OFFSET;
458 clk_sel = cscmr1 & MXC_CCM_CSCMR1_USDHC4_CLK_SEL;
466 root_freq = PLL2_PFD0_FREQ;
468 root_freq = PLL2_PFD2_FREQ;
470 return root_freq / (usdhc_podf + 1);
473 u32 imx_get_uartclk(void)
475 return get_uart_clk();
478 u32 imx_get_fecclk(void)
480 return decode_pll(PLL_ENET, MXC_HCLK);
483 int enable_sata_clock(void)
486 s32 timeout = 100000;
488 /* Enable sata clock */
489 reg = readl(&imx_ccm->CCGR5); /* CCGR5 */
490 reg |= MXC_CCM_CCGR5_SATA_MASK;
491 writel(reg, &imx_ccm->CCGR5);
494 reg = readl(&anatop->pll_enet);
495 reg &= ~BM_ANADIG_PLL_ENET_POWERDOWN;
496 writel(reg, &anatop->pll_enet);
497 reg |= BM_ANADIG_PLL_ENET_ENABLE;
499 if (readl(&anatop->pll_enet) & BM_ANADIG_PLL_ENET_LOCK)
504 reg &= ~BM_ANADIG_PLL_ENET_BYPASS;
505 writel(reg, &anatop->pll_enet);
506 reg |= BM_ANADIG_PLL_ENET_ENABLE_SATA;
507 writel(reg, &anatop->pll_enet);
512 void ipu_clk_enable(void)
514 u32 reg = readl(&imx_ccm->CCGR3);
515 reg |= MXC_CCM_CCGR3_CG0_MASK;
516 writel(reg, &imx_ccm->CCGR3);
519 void ipu_clk_disable(void)
521 u32 reg = readl(&imx_ccm->CCGR3);
522 reg &= ~MXC_CCM_CCGR3_CG0_MASK;
523 writel(reg, &imx_ccm->CCGR3);
526 void ocotp_clk_enable(void)
528 u32 reg = readl(&imx_ccm->CCGR2);
529 reg |= MXC_CCM_CCGR2_CG6_MASK;
530 writel(reg, &imx_ccm->CCGR2);
533 void ocotp_clk_disable(void)
535 u32 reg = readl(&imx_ccm->CCGR2);
536 reg &= ~MXC_CCM_CCGR2_CG6_MASK;
537 writel(reg, &imx_ccm->CCGR2);
540 unsigned int mxc_get_clock(enum mxc_clock clk)
544 return get_mcu_main_clk();
546 return get_periph_clk();
548 return get_ahb_clk();
550 return get_ipg_clk();
553 return get_ipg_per_clk();
555 return get_uart_clk();
557 return get_cspi_clk();
559 return get_axi_clk();
560 case MXC_EMI_SLOW_CLK:
561 return get_emi_slow_clk();
563 return get_mmdc_ch0_clk();
565 return get_usdhc_clk(0);
567 return get_usdhc_clk(1);
569 return get_usdhc_clk(2);
571 return get_usdhc_clk(3);
573 return get_ahb_clk();
575 return get_nfc_clk();
581 static inline int gcd(int m, int n)
595 /* Config CPU clock */
596 static int set_arm_clk(u32 ref, u32 freq_khz)
604 if (freq_khz > ref / 1000 * 108 / 2 || freq_khz < ref / 1000 * 54 / 8 / 2) {
605 printf("Frequency %u.%03uMHz is out of range: %u.%03u..%u.%03u\n",
606 freq_khz / 1000, freq_khz % 1000,
607 54 * ref / 1000000 / 8 / 2, 54 * ref / 1000 / 8 / 2 % 1000,
608 108 * ref / 1000000 / 2, 108 * ref / 1000 / 2 % 1000);
612 for (d = DIV_ROUND_UP(648000, freq_khz); d <= 8; d++) {
613 int m = freq_khz * 2 * d / (ref / 1000);
618 debug("%s@%d: d=%d m=%d\n", __func__, __LINE__,
624 if (f > freq_khz * 1000) {
625 debug("%s@%d: d=%d m=%d f=%u freq=%u\n", __func__, __LINE__,
631 err = freq_khz * 1000 - f;
632 debug("%s@%d: d=%d m=%d f=%u freq=%u err=%d\n", __func__, __LINE__,
633 d, m, f, freq_khz, err);
644 debug("Setting M=%3u D=%2u for %u.%03uMHz (actual: %u.%03uMHz)\n",
645 mul, div, freq_khz / 1000, freq_khz % 1000,
646 ref * mul / 2 / div / 1000000, ref * mul / 2 / div / 1000 % 1000);
648 reg = readl(&anatop->pll_arm);
649 debug("anadig_pll_arm=%08x -> %08x\n",
650 reg, (reg & ~0x7f) | mul);
653 writel(reg, &anatop->pll_arm); /* bypass PLL */
655 reg = (reg & ~0x7f) | mul;
656 writel(reg, &anatop->pll_arm);
658 writel(div - 1, &imx_ccm->cacrr);
661 writel(reg, &anatop->pll_arm); /* disable PLL bypass */
666 int mxc_set_clock(u32 ref, u32 freq, enum mxc_clock clk)
674 ret = set_arm_clk(ref, freq);
678 ret = set_nfc_clk(ref, freq);
682 printf("Warning: Unsupported or invalid clock type: %d\n",
691 * Dump some core clocks.
693 #define print_pll(pll) { \
694 u32 __pll = decode_pll(pll, MXC_HCLK); \
695 printf("%-12s %4d.%03d MHz\n", #pll, \
696 __pll / 1000000, __pll / 1000 % 1000); \
699 #define MXC_IPG_PER_CLK MXC_IPG_PERCLK
701 #define print_clk(clk) { \
702 u32 __clk = mxc_get_clock(MXC_##clk##_CLK); \
703 printf("%-12s %4d.%03d MHz\n", #clk, \
704 __clk / 1000000, __clk / 1000 % 1000); \
707 #define print_pfd(pll, pfd) { \
708 u32 __pfd = readl(&anatop->pfd_##pll); \
709 if (__pfd & (0x80 << 8 * pfd)) { \
710 printf("PFD_%s[%d] OFF\n", #pll, pfd); \
712 __pfd = (__pfd >> 8 * pfd) & 0x3f; \
713 printf("PFD_%s[%d] %4d.%03d MHz\n", #pll, pfd, \
715 pll * 18 * 1000 / __pfd % 1000); \
719 static void do_mx6_showclocks(void)
723 print_pll(PLL_USBOTG);
724 print_pll(PLL_AUDIO);
725 print_pll(PLL_VIDEO);
756 static struct clk_lookup {
759 } mx6_clk_lookup[] = {
760 { "arm", MXC_ARM_CLK, },
761 { "nfc", MXC_NFC_CLK, },
764 int do_clocks(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
768 unsigned long ref = ~0UL;
772 return CMD_RET_SUCCESS;
773 } else if (argc == 2 || argc > 4) {
774 return CMD_RET_USAGE;
777 freq = simple_strtoul(argv[2], NULL, 0);
779 printf("Invalid clock frequency %lu\n", freq);
780 return CMD_RET_FAILURE;
783 ref = simple_strtoul(argv[3], NULL, 0);
785 for (i = 0; i < ARRAY_SIZE(mx6_clk_lookup); i++) {
786 if (strcasecmp(argv[1], mx6_clk_lookup[i].name) == 0) {
787 switch (mx6_clk_lookup[i].index) {
790 return CMD_RET_USAGE;
791 ref = CONFIG_SYS_MX6_HCLK;
795 if (argc > 3 && ref > 3) {
796 printf("Invalid clock selector value: %lu\n", ref);
797 return CMD_RET_FAILURE;
801 printf("Setting %s clock to %lu MHz\n",
802 mx6_clk_lookup[i].name, freq);
803 if (mxc_set_clock(ref, freq, mx6_clk_lookup[i].index))
805 freq = mxc_get_clock(mx6_clk_lookup[i].index);
806 printf("%s clock set to %lu.%03lu MHz\n",
807 mx6_clk_lookup[i].name,
808 freq / 1000000, freq / 1000 % 1000);
809 return CMD_RET_SUCCESS;
812 if (i == ARRAY_SIZE(mx6_clk_lookup)) {
813 printf("clock %s not found; supported clocks are:\n", argv[1]);
814 for (i = 0; i < ARRAY_SIZE(mx6_clk_lookup); i++) {
815 printf("\t%s\n", mx6_clk_lookup[i].name);
818 printf("Failed to set clock %s to %s MHz\n",
821 return CMD_RET_FAILURE;
824 /***************************************************/
827 clocks, 4, 0, do_clocks,
828 "display/set clocks",
829 " - display clock settings\n"
830 "clocks <clkname> <freq> - set clock <clkname> to <freq> MHz"