2 * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
3 * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20 #include <linux/module.h>
21 #include <linux/spinlock.h>
22 #include <linux/delay.h>
23 #include <linux/clk.h>
24 #include <linux/err.h>
26 #include <asm/arch/clock.h>
27 #include <asm/div64.h>
31 #define PRE_DIV_MIN_FREQ 10000000 /* Minimum Frequency after Predivider */
33 static void __calc_pre_post_dividers(u32 div, u32 *pre, u32 *post)
35 u32 min_pre, temp_pre, old_err, err;
40 } else if (div >= 64) {
41 min_pre = (div - 1) / 64 + 1;
43 for (temp_pre = 8; temp_pre >= min_pre; temp_pre--) {
55 *post = (div + *pre - 1) / *pre;
56 } else if (div <= 8) {
65 static struct clk mcu_pll_clk;
66 static struct clk mcu_main_clk;
67 static struct clk usb_pll_clk;
68 static struct clk serial_pll_clk;
69 static struct clk ipg_clk;
70 static struct clk ckih_clk;
71 static struct clk ahb_clk;
73 static int _clk_enable(struct clk *clk)
77 reg = __raw_readl(clk->enable_reg);
78 reg |= 3 << clk->enable_shift;
79 __raw_writel(reg, clk->enable_reg);
84 static void _clk_disable(struct clk *clk)
88 reg = __raw_readl(clk->enable_reg);
89 reg &= ~(3 << clk->enable_shift);
90 __raw_writel(reg, clk->enable_reg);
93 static void _clk_emi_disable(struct clk *clk)
97 reg = __raw_readl(clk->enable_reg);
98 reg &= ~(3 << clk->enable_shift);
99 reg |= (1 << clk->enable_shift);
100 __raw_writel(reg, clk->enable_reg);
103 static int _clk_pll_set_rate(struct clk *clk, unsigned long rate)
106 signed long pd = 1; /* Pre-divider */
107 signed long mfi; /* Multiplication Factor (Integer part) */
108 signed long mfn; /* Multiplication Factor (Integer part) */
109 signed long mfd; /* Multiplication Factor (Denominator Part) */
111 u32 ref_freq = clk_get_rate(clk->parent);
113 while (((ref_freq / pd) * 10) > rate)
116 if ((ref_freq / pd) < PRE_DIV_MIN_FREQ)
119 /* the ref_freq/2 in the following is to round up */
120 mfi = (((rate / 2) * pd) + (ref_freq / 2)) / ref_freq;
121 if (mfi < 5 || mfi > 15)
124 /* pick a mfd value that will work
125 * then solve for mfn */
126 mfd = ref_freq / 50000;
129 * pll_freq * pd * mfd
130 * mfn = -------------------- - (mfi * mfd)
133 /* the tmp/2 is for rounding */
134 tmp = ref_freq / 10000;
136 ((((((rate / 2) + (tmp / 2)) / tmp) * pd) * mfd) / 10000) -
143 /* Change the Pll value */
144 reg = (mfi << MXC_CCM_PCTL_MFI_OFFSET) |
145 (mfn << MXC_CCM_PCTL_MFN_OFFSET) |
146 (mfd << MXC_CCM_PCTL_MFD_OFFSET) | (pd << MXC_CCM_PCTL_PD_OFFSET);
148 if (clk == &mcu_pll_clk)
149 __raw_writel(reg, MXC_CCM_MPCTL);
150 else if (clk == &usb_pll_clk)
151 __raw_writel(reg, MXC_CCM_UPCTL);
152 else if (clk == &serial_pll_clk)
153 __raw_writel(reg, MXC_CCM_SRPCTL);
158 static unsigned long _clk_pll_get_rate(struct clk *clk)
160 long mfi, mfn, mfd, pdf, ref_clk, mfn_abs;
161 unsigned long reg, ccmr;
165 ccmr = __raw_readl(MXC_CCM_CCMR);
166 prcs = (ccmr & MXC_CCM_CCMR_PRCS_MASK) >> MXC_CCM_CCMR_PRCS_OFFSET;
168 ref_clk = CKIL_CLK_FREQ * 1024;
170 ref_clk = clk_get_rate(&ckih_clk);
172 if (clk == &mcu_pll_clk) {
173 if ((ccmr & MXC_CCM_CCMR_MPE) == 0)
175 if ((ccmr & MXC_CCM_CCMR_MDS) != 0)
177 reg = __raw_readl(MXC_CCM_MPCTL);
178 } else if (clk == &usb_pll_clk)
179 reg = __raw_readl(MXC_CCM_UPCTL);
180 else if (clk == &serial_pll_clk)
181 reg = __raw_readl(MXC_CCM_SRPCTL);
187 pdf = (reg & MXC_CCM_PCTL_PD_MASK) >> MXC_CCM_PCTL_PD_OFFSET;
188 mfd = (reg & MXC_CCM_PCTL_MFD_MASK) >> MXC_CCM_PCTL_MFD_OFFSET;
189 mfi = (reg & MXC_CCM_PCTL_MFI_MASK) >> MXC_CCM_PCTL_MFI_OFFSET;
190 mfi = (mfi <= 5) ? 5 : mfi;
191 mfn = mfn_abs = reg & MXC_CCM_PCTL_MFN_MASK;
201 temp = (u64) ref_clk * mfn_abs;
202 do_div(temp, mfd + 1);
205 temp = (ref_clk * mfi) + temp;
210 static int _clk_usb_pll_enable(struct clk *clk)
214 reg = __raw_readl(MXC_CCM_CCMR);
215 reg |= MXC_CCM_CCMR_UPE;
216 __raw_writel(reg, MXC_CCM_CCMR);
218 /* No lock bit on MX31, so using max time from spec */
224 static void _clk_usb_pll_disable(struct clk *clk)
228 reg = __raw_readl(MXC_CCM_CCMR);
229 reg &= ~MXC_CCM_CCMR_UPE;
230 __raw_writel(reg, MXC_CCM_CCMR);
233 static int _clk_serial_pll_enable(struct clk *clk)
237 reg = __raw_readl(MXC_CCM_CCMR);
238 reg |= MXC_CCM_CCMR_SPE;
239 __raw_writel(reg, MXC_CCM_CCMR);
241 /* No lock bit on MX31, so using max time from spec */
247 static void _clk_serial_pll_disable(struct clk *clk)
251 reg = __raw_readl(MXC_CCM_CCMR);
252 reg &= ~MXC_CCM_CCMR_SPE;
253 __raw_writel(reg, MXC_CCM_CCMR);
256 #define PDR0(mask, off) ((__raw_readl(MXC_CCM_PDR0) & mask) >> off)
257 #define PDR1(mask, off) ((__raw_readl(MXC_CCM_PDR1) & mask) >> off)
258 #define PDR2(mask, off) ((__raw_readl(MXC_CCM_PDR2) & mask) >> off)
260 static unsigned long _clk_mcu_main_get_rate(struct clk *clk)
262 u32 pmcr0 = __raw_readl(MXC_CCM_PMCR0);
264 if ((pmcr0 & MXC_CCM_PMCR0_DFSUP1) == MXC_CCM_PMCR0_DFSUP1_SPLL)
265 return clk_get_rate(&serial_pll_clk);
267 return clk_get_rate(&mcu_pll_clk);
270 static unsigned long _clk_hclk_get_rate(struct clk *clk)
272 unsigned long max_pdf;
274 max_pdf = PDR0(MXC_CCM_PDR0_MAX_PODF_MASK,
275 MXC_CCM_PDR0_MAX_PODF_OFFSET);
276 return clk_get_rate(clk->parent) / (max_pdf + 1);
279 static unsigned long _clk_ipg_get_rate(struct clk *clk)
281 unsigned long ipg_pdf;
283 ipg_pdf = PDR0(MXC_CCM_PDR0_IPG_PODF_MASK,
284 MXC_CCM_PDR0_IPG_PODF_OFFSET);
285 return clk_get_rate(clk->parent) / (ipg_pdf + 1);
288 static unsigned long _clk_nfc_get_rate(struct clk *clk)
290 unsigned long nfc_pdf;
292 nfc_pdf = PDR0(MXC_CCM_PDR0_NFC_PODF_MASK,
293 MXC_CCM_PDR0_NFC_PODF_OFFSET);
294 return clk_get_rate(clk->parent) / (nfc_pdf + 1);
297 static unsigned long _clk_hsp_get_rate(struct clk *clk)
299 unsigned long hsp_pdf;
301 hsp_pdf = PDR0(MXC_CCM_PDR0_HSP_PODF_MASK,
302 MXC_CCM_PDR0_HSP_PODF_OFFSET);
303 return clk_get_rate(clk->parent) / (hsp_pdf + 1);
306 static unsigned long _clk_usb_get_rate(struct clk *clk)
308 unsigned long usb_pdf, usb_prepdf;
310 usb_pdf = PDR1(MXC_CCM_PDR1_USB_PODF_MASK,
311 MXC_CCM_PDR1_USB_PODF_OFFSET);
312 usb_prepdf = PDR1(MXC_CCM_PDR1_USB_PRDF_MASK,
313 MXC_CCM_PDR1_USB_PRDF_OFFSET);
314 return clk_get_rate(clk->parent) / (usb_prepdf + 1) / (usb_pdf + 1);
317 static unsigned long _clk_csi_get_rate(struct clk *clk)
321 reg = __raw_readl(MXC_CCM_PDR0);
322 pre = (reg & MXC_CCM_PDR0_CSI_PRDF_MASK) >>
323 MXC_CCM_PDR0_CSI_PRDF_OFFSET;
325 post = (reg & MXC_CCM_PDR0_CSI_PODF_MASK) >>
326 MXC_CCM_PDR0_CSI_PODF_OFFSET;
328 return clk_get_rate(clk->parent) / (pre * post);
331 static unsigned long _clk_csi_round_rate(struct clk *clk, unsigned long rate)
333 u32 pre, post, parent = clk_get_rate(clk->parent);
334 u32 div = parent / rate;
339 __calc_pre_post_dividers(div, &pre, &post);
341 return parent / (pre * post);
344 static int _clk_csi_set_rate(struct clk *clk, unsigned long rate)
346 u32 reg, div, pre, post, parent = clk_get_rate(clk->parent);
350 if ((parent / div) != rate)
353 __calc_pre_post_dividers(div, &pre, &post);
355 /* Set CSI clock divider */
356 reg = __raw_readl(MXC_CCM_PDR0) &
357 ~(MXC_CCM_PDR0_CSI_PODF_MASK | MXC_CCM_PDR0_CSI_PRDF_MASK);
358 reg |= (post - 1) << MXC_CCM_PDR0_CSI_PODF_OFFSET;
359 reg |= (pre - 1) << MXC_CCM_PDR0_CSI_PRDF_OFFSET;
360 __raw_writel(reg, MXC_CCM_PDR0);
365 static unsigned long _clk_per_get_rate(struct clk *clk)
367 unsigned long per_pdf;
369 per_pdf = PDR0(MXC_CCM_PDR0_PER_PODF_MASK,
370 MXC_CCM_PDR0_PER_PODF_OFFSET);
371 return clk_get_rate(clk->parent) / (per_pdf + 1);
374 static unsigned long _clk_ssi1_get_rate(struct clk *clk)
376 unsigned long ssi1_pdf, ssi1_prepdf;
378 ssi1_pdf = PDR1(MXC_CCM_PDR1_SSI1_PODF_MASK,
379 MXC_CCM_PDR1_SSI1_PODF_OFFSET);
380 ssi1_prepdf = PDR1(MXC_CCM_PDR1_SSI1_PRE_PODF_MASK,
381 MXC_CCM_PDR1_SSI1_PRE_PODF_OFFSET);
382 return clk_get_rate(clk->parent) / (ssi1_prepdf + 1) / (ssi1_pdf + 1);
385 static unsigned long _clk_ssi2_get_rate(struct clk *clk)
387 unsigned long ssi2_pdf, ssi2_prepdf;
389 ssi2_pdf = PDR1(MXC_CCM_PDR1_SSI2_PODF_MASK,
390 MXC_CCM_PDR1_SSI2_PODF_OFFSET);
391 ssi2_prepdf = PDR1(MXC_CCM_PDR1_SSI2_PRE_PODF_MASK,
392 MXC_CCM_PDR1_SSI2_PRE_PODF_OFFSET);
393 return clk_get_rate(clk->parent) / (ssi2_prepdf + 1) / (ssi2_pdf + 1);
396 static unsigned long _clk_firi_get_rate(struct clk *clk)
398 unsigned long firi_pdf, firi_prepdf;
400 firi_pdf = PDR1(MXC_CCM_PDR1_FIRI_PODF_MASK,
401 MXC_CCM_PDR1_FIRI_PODF_OFFSET);
402 firi_prepdf = PDR1(MXC_CCM_PDR1_FIRI_PRE_PODF_MASK,
403 MXC_CCM_PDR1_FIRI_PRE_PODF_OFFSET);
404 return clk_get_rate(clk->parent) / (firi_prepdf + 1) / (firi_pdf + 1);
407 static unsigned long _clk_firi_round_rate(struct clk *clk, unsigned long rate)
410 u32 parent = clk_get_rate(clk->parent);
411 u32 div = parent / rate;
416 __calc_pre_post_dividers(div, &pre, &post);
418 return parent / (pre * post);
422 static int _clk_firi_set_rate(struct clk *clk, unsigned long rate)
424 u32 reg, div, pre, post, parent = clk_get_rate(clk->parent);
428 if ((parent / div) != rate)
431 __calc_pre_post_dividers(div, &pre, &post);
433 /* Set FIRI clock divider */
434 reg = __raw_readl(MXC_CCM_PDR1) &
435 ~(MXC_CCM_PDR1_FIRI_PODF_MASK | MXC_CCM_PDR1_FIRI_PRE_PODF_MASK);
436 reg |= (pre - 1) << MXC_CCM_PDR1_FIRI_PRE_PODF_OFFSET;
437 reg |= (post - 1) << MXC_CCM_PDR1_FIRI_PODF_OFFSET;
438 __raw_writel(reg, MXC_CCM_PDR1);
443 static unsigned long _clk_mbx_get_rate(struct clk *clk)
445 return clk_get_rate(clk->parent) / 2;
448 static unsigned long _clk_mstick1_get_rate(struct clk *clk)
450 unsigned long msti_pdf;
452 msti_pdf = PDR2(MXC_CCM_PDR2_MST1_PDF_MASK,
453 MXC_CCM_PDR2_MST1_PDF_OFFSET);
454 return clk_get_rate(clk->parent) / (msti_pdf + 1);
457 static unsigned long _clk_mstick2_get_rate(struct clk *clk)
459 unsigned long msti_pdf;
461 msti_pdf = PDR2(MXC_CCM_PDR2_MST2_PDF_MASK,
462 MXC_CCM_PDR2_MST2_PDF_OFFSET);
463 return clk_get_rate(clk->parent) / (msti_pdf + 1);
466 static unsigned long ckih_rate;
468 static unsigned long clk_ckih_get_rate(struct clk *clk)
473 static struct clk ckih_clk = {
475 .get_rate = clk_ckih_get_rate,
478 static unsigned long clk_ckil_get_rate(struct clk *clk)
480 return CKIL_CLK_FREQ;
483 static struct clk ckil_clk = {
485 .get_rate = clk_ckil_get_rate,
488 static struct clk mcu_pll_clk = {
491 .set_rate = _clk_pll_set_rate,
492 .get_rate = _clk_pll_get_rate,
495 static struct clk mcu_main_clk = {
496 .name = "mcu_main_clk",
497 .parent = &mcu_pll_clk,
498 .get_rate = _clk_mcu_main_get_rate,
501 static struct clk serial_pll_clk = {
502 .name = "serial_pll",
504 .set_rate = _clk_pll_set_rate,
505 .get_rate = _clk_pll_get_rate,
506 .enable = _clk_serial_pll_enable,
507 .disable = _clk_serial_pll_disable,
510 static struct clk usb_pll_clk = {
513 .set_rate = _clk_pll_set_rate,
514 .get_rate = _clk_pll_get_rate,
515 .enable = _clk_usb_pll_enable,
516 .disable = _clk_usb_pll_disable,
519 static struct clk ahb_clk = {
521 .parent = &mcu_main_clk,
522 .get_rate = _clk_hclk_get_rate,
525 static struct clk per_clk = {
527 .parent = &usb_pll_clk,
528 .get_rate = _clk_per_get_rate,
531 static struct clk perclk_clk = {
532 .name = "perclk_clk",
536 static struct clk cspi_clk[] = {
541 .enable = _clk_enable,
542 .enable_reg = MXC_CCM_CGR2,
543 .enable_shift = MXC_CCM_CGR2_CSPI1_OFFSET,
544 .disable = _clk_disable,},
549 .enable = _clk_enable,
550 .enable_reg = MXC_CCM_CGR2,
551 .enable_shift = MXC_CCM_CGR2_CSPI2_OFFSET,
552 .disable = _clk_disable,},
557 .enable = _clk_enable,
558 .enable_reg = MXC_CCM_CGR0,
559 .enable_shift = MXC_CCM_CGR0_CSPI3_OFFSET,
560 .disable = _clk_disable,},
563 static struct clk ipg_clk = {
566 .get_rate = _clk_ipg_get_rate,
569 static struct clk emi_clk = {
572 .enable = _clk_enable,
573 .enable_reg = MXC_CCM_CGR2,
574 .enable_shift = MXC_CCM_CGR2_EMI_OFFSET,
575 .disable = _clk_emi_disable,
578 static struct clk gpt_clk = {
580 .parent = &perclk_clk,
581 .enable = _clk_enable,
582 .enable_reg = MXC_CCM_CGR0,
583 .enable_shift = MXC_CCM_CGR0_GPT_OFFSET,
584 .disable = _clk_disable,
587 static struct clk pwm_clk = {
589 .parent = &perclk_clk,
590 .enable = _clk_enable,
591 .enable_reg = MXC_CCM_CGR0,
592 .enable_shift = MXC_CCM_CGR1_PWM_OFFSET,
593 .disable = _clk_disable,
596 static struct clk epit_clk[] = {
600 .parent = &perclk_clk,
601 .enable = _clk_enable,
602 .enable_reg = MXC_CCM_CGR0,
603 .enable_shift = MXC_CCM_CGR0_EPIT1_OFFSET,
604 .disable = _clk_disable,},
608 .parent = &perclk_clk,
609 .enable = _clk_enable,
610 .enable_reg = MXC_CCM_CGR0,
611 .enable_shift = MXC_CCM_CGR0_EPIT2_OFFSET,
612 .disable = _clk_disable,},
615 static struct clk nfc_clk = {
618 .get_rate = _clk_nfc_get_rate,
621 static struct clk scc_clk = {
626 static struct clk ipu_clk = {
628 .parent = &mcu_main_clk,
629 .get_rate = _clk_hsp_get_rate,
630 .enable = _clk_enable,
631 .enable_reg = MXC_CCM_CGR1,
632 .enable_shift = MXC_CCM_CGR1_IPU_OFFSET,
633 .disable = _clk_disable,
636 static struct clk kpp_clk = {
639 .enable = _clk_enable,
640 .enable_reg = MXC_CCM_CGR1,
641 .enable_shift = MXC_CCM_CGR1_KPP_OFFSET,
642 .disable = _clk_disable,
645 static struct clk wdog_clk = {
648 .enable = _clk_enable,
649 .enable_reg = MXC_CCM_CGR1,
650 .enable_shift = MXC_CCM_CGR1_WDOG_OFFSET,
651 .disable = _clk_disable,
653 static struct clk rtc_clk = {
656 .enable = _clk_enable,
657 .enable_reg = MXC_CCM_CGR1,
658 .enable_shift = MXC_CCM_CGR1_RTC_OFFSET,
659 .disable = _clk_disable,
662 static struct clk usb_clk[] = {
665 .parent = &usb_pll_clk,
666 .get_rate = _clk_usb_get_rate,},
668 .name = "usb_ahb_clk",
670 .enable = _clk_enable,
671 .enable_reg = MXC_CCM_CGR1,
672 .enable_shift = MXC_CCM_CGR1_USBOTG_OFFSET,
673 .disable = _clk_disable,},
676 static struct clk csi_clk = {
678 .parent = &serial_pll_clk,
679 .get_rate = _clk_csi_get_rate,
680 .round_rate = _clk_csi_round_rate,
681 .set_rate = _clk_csi_set_rate,
682 .enable = _clk_enable,
683 .enable_reg = MXC_CCM_CGR1,
684 .enable_shift = MXC_CCM_CGR1_CSI_OFFSET,
685 .disable = _clk_disable,
688 static struct clk uart_clk[] = {
692 .parent = &perclk_clk,
693 .enable = _clk_enable,
694 .enable_reg = MXC_CCM_CGR0,
695 .enable_shift = MXC_CCM_CGR0_UART1_OFFSET,
696 .disable = _clk_disable,},
700 .parent = &perclk_clk,
701 .enable = _clk_enable,
702 .enable_reg = MXC_CCM_CGR0,
703 .enable_shift = MXC_CCM_CGR0_UART2_OFFSET,
704 .disable = _clk_disable,},
708 .parent = &perclk_clk,
709 .enable = _clk_enable,
710 .enable_reg = MXC_CCM_CGR1,
711 .enable_shift = MXC_CCM_CGR1_UART3_OFFSET,
712 .disable = _clk_disable,},
716 .parent = &perclk_clk,
717 .enable = _clk_enable,
718 .enable_reg = MXC_CCM_CGR1,
719 .enable_shift = MXC_CCM_CGR1_UART4_OFFSET,
720 .disable = _clk_disable,},
724 .parent = &perclk_clk,
725 .enable = _clk_enable,
726 .enable_reg = MXC_CCM_CGR1,
727 .enable_shift = MXC_CCM_CGR1_UART5_OFFSET,
728 .disable = _clk_disable,},
731 static struct clk i2c_clk[] = {
735 .parent = &perclk_clk,
736 .enable = _clk_enable,
737 .enable_reg = MXC_CCM_CGR0,
738 .enable_shift = MXC_CCM_CGR0_I2C1_OFFSET,
739 .disable = _clk_disable,},
743 .parent = &perclk_clk,
744 .enable = _clk_enable,
745 .enable_reg = MXC_CCM_CGR0,
746 .enable_shift = MXC_CCM_CGR0_I2C2_OFFSET,
747 .disable = _clk_disable,},
751 .parent = &perclk_clk,
752 .enable = _clk_enable,
753 .enable_reg = MXC_CCM_CGR0,
754 .enable_shift = MXC_CCM_CGR0_I2C3_OFFSET,
755 .disable = _clk_disable,},
758 static struct clk owire_clk = {
760 .parent = &perclk_clk,
761 .enable_reg = MXC_CCM_CGR1,
762 .enable_shift = MXC_CCM_CGR1_OWIRE_OFFSET,
763 .enable = _clk_enable,
764 .disable = _clk_disable,
767 static struct clk sdhc_clk[] = {
771 .parent = &perclk_clk,
772 .enable = _clk_enable,
773 .enable_reg = MXC_CCM_CGR0,
774 .enable_shift = MXC_CCM_CGR0_SD_MMC1_OFFSET,
775 .disable = _clk_disable,},
779 .parent = &perclk_clk,
780 .enable = _clk_enable,
781 .enable_reg = MXC_CCM_CGR0,
782 .enable_shift = MXC_CCM_CGR0_SD_MMC2_OFFSET,
783 .disable = _clk_disable,},
786 static struct clk ssi_clk[] = {
789 .parent = &serial_pll_clk,
790 .get_rate = _clk_ssi1_get_rate,
791 .enable = _clk_enable,
792 .enable_reg = MXC_CCM_CGR0,
793 .enable_shift = MXC_CCM_CGR0_SSI1_OFFSET,
794 .disable = _clk_disable,},
798 .parent = &serial_pll_clk,
799 .get_rate = _clk_ssi2_get_rate,
800 .enable = _clk_enable,
801 .enable_reg = MXC_CCM_CGR2,
802 .enable_shift = MXC_CCM_CGR2_SSI2_OFFSET,
803 .disable = _clk_disable,},
806 static struct clk firi_clk = {
808 .parent = &usb_pll_clk,
809 .round_rate = _clk_firi_round_rate,
810 .set_rate = _clk_firi_set_rate,
811 .get_rate = _clk_firi_get_rate,
812 .enable = _clk_enable,
813 .enable_reg = MXC_CCM_CGR2,
814 .enable_shift = MXC_CCM_CGR2_FIRI_OFFSET,
815 .disable = _clk_disable,
818 static struct clk ata_clk = {
821 .enable = _clk_enable,
822 .enable_reg = MXC_CCM_CGR0,
823 .enable_shift = MXC_CCM_CGR0_ATA_OFFSET,
824 .disable = _clk_disable,
827 static struct clk mbx_clk = {
830 .enable = _clk_enable,
831 .enable_reg = MXC_CCM_CGR2,
832 .enable_shift = MXC_CCM_CGR2_GACC_OFFSET,
833 .get_rate = _clk_mbx_get_rate,
836 static struct clk vpu_clk = {
839 .enable = _clk_enable,
840 .enable_reg = MXC_CCM_CGR2,
841 .enable_shift = MXC_CCM_CGR2_GACC_OFFSET,
842 .get_rate = _clk_mbx_get_rate,
845 static struct clk rtic_clk = {
848 .enable = _clk_enable,
849 .enable_reg = MXC_CCM_CGR2,
850 .enable_shift = MXC_CCM_CGR2_RTIC_OFFSET,
851 .disable = _clk_disable,
854 static struct clk rng_clk = {
857 .enable = _clk_enable,
858 .enable_reg = MXC_CCM_CGR0,
859 .enable_shift = MXC_CCM_CGR0_RNG_OFFSET,
860 .disable = _clk_disable,
863 static struct clk sdma_clk[] = {
865 .name = "sdma_ahb_clk",
867 .enable = _clk_enable,
868 .enable_reg = MXC_CCM_CGR0,
869 .enable_shift = MXC_CCM_CGR0_SDMA_OFFSET,
870 .disable = _clk_disable,},
872 .name = "sdma_ipg_clk",
876 static struct clk mpeg4_clk = {
879 .enable = _clk_enable,
880 .enable_reg = MXC_CCM_CGR1,
881 .enable_shift = MXC_CCM_CGR1_HANTRO_OFFSET,
882 .disable = _clk_disable,
885 static struct clk vl2cc_clk = {
888 .enable = _clk_enable,
889 .enable_reg = MXC_CCM_CGR1,
890 .enable_shift = MXC_CCM_CGR1_HANTRO_OFFSET,
891 .disable = _clk_disable,
894 static struct clk mstick_clk[] = {
896 .name = "mstick_clk",
898 .parent = &usb_pll_clk,
899 .get_rate = _clk_mstick1_get_rate,
900 .enable = _clk_enable,
901 .enable_reg = MXC_CCM_CGR1,
902 .enable_shift = MXC_CCM_CGR1_MEMSTICK1_OFFSET,
903 .disable = _clk_disable,},
905 .name = "mstick_clk",
907 .parent = &usb_pll_clk,
908 .get_rate = _clk_mstick2_get_rate,
909 .enable = _clk_enable,
910 .enable_reg = MXC_CCM_CGR1,
911 .enable_shift = MXC_CCM_CGR1_MEMSTICK2_OFFSET,
912 .disable = _clk_disable,},
915 static struct clk iim_clk = {
918 .enable = _clk_enable,
919 .enable_reg = MXC_CCM_CGR0,
920 .enable_shift = MXC_CCM_CGR0_IIM_OFFSET,
921 .disable = _clk_disable,
924 static unsigned long _clk_cko1_round_rate(struct clk *clk, unsigned long rate)
926 u32 div, parent = clk_get_rate(clk->parent);
942 static int _clk_cko1_set_rate(struct clk *clk, unsigned long rate)
944 u32 reg, div, parent = clk_get_rate(clk->parent);
961 reg = __raw_readl(MXC_CCM_COSR) & ~MXC_CCM_COSR_CLKOUTDIV_MASK;
962 reg |= div << MXC_CCM_COSR_CLKOUTDIV_OFFSET;
963 __raw_writel(reg, MXC_CCM_COSR);
968 static unsigned long _clk_cko1_get_rate(struct clk *clk)
972 div = __raw_readl(MXC_CCM_COSR) & MXC_CCM_COSR_CLKOUTDIV_MASK >>
973 MXC_CCM_COSR_CLKOUTDIV_OFFSET;
975 return clk_get_rate(clk->parent) / (1 << div);
978 static int _clk_cko1_set_parent(struct clk *clk, struct clk *parent)
982 reg = __raw_readl(MXC_CCM_COSR) & ~MXC_CCM_COSR_CLKOSEL_MASK;
984 if (parent == &mcu_main_clk)
985 reg |= 0 << MXC_CCM_COSR_CLKOSEL_OFFSET;
986 else if (parent == &ipg_clk)
987 reg |= 1 << MXC_CCM_COSR_CLKOSEL_OFFSET;
988 else if (parent == &usb_pll_clk)
989 reg |= 2 << MXC_CCM_COSR_CLKOSEL_OFFSET;
990 else if (parent == mcu_main_clk.parent)
991 reg |= 3 << MXC_CCM_COSR_CLKOSEL_OFFSET;
992 else if (parent == &ahb_clk)
993 reg |= 5 << MXC_CCM_COSR_CLKOSEL_OFFSET;
994 else if (parent == &serial_pll_clk)
995 reg |= 7 << MXC_CCM_COSR_CLKOSEL_OFFSET;
996 else if (parent == &ckih_clk)
997 reg |= 8 << MXC_CCM_COSR_CLKOSEL_OFFSET;
998 else if (parent == &emi_clk)
999 reg |= 9 << MXC_CCM_COSR_CLKOSEL_OFFSET;
1000 else if (parent == &ipu_clk)
1001 reg |= 0xA << MXC_CCM_COSR_CLKOSEL_OFFSET;
1002 else if (parent == &nfc_clk)
1003 reg |= 0xB << MXC_CCM_COSR_CLKOSEL_OFFSET;
1004 else if (parent == &uart_clk[0])
1005 reg |= 0xC << MXC_CCM_COSR_CLKOSEL_OFFSET;
1009 __raw_writel(reg, MXC_CCM_COSR);
1014 static int _clk_cko1_enable(struct clk *clk)
1018 reg = __raw_readl(MXC_CCM_COSR) | MXC_CCM_COSR_CLKOEN;
1019 __raw_writel(reg, MXC_CCM_COSR);
1024 static void _clk_cko1_disable(struct clk *clk)
1028 reg = __raw_readl(MXC_CCM_COSR) & ~MXC_CCM_COSR_CLKOEN;
1029 __raw_writel(reg, MXC_CCM_COSR);
1032 static struct clk cko1_clk = {
1034 .get_rate = _clk_cko1_get_rate,
1035 .set_rate = _clk_cko1_set_rate,
1036 .round_rate = _clk_cko1_round_rate,
1037 .set_parent = _clk_cko1_set_parent,
1038 .enable = _clk_cko1_enable,
1039 .disable = _clk_cko1_disable,
1042 static struct clk *mxc_clks[] = {
1095 int __init mxc_clocks_init(unsigned long fref)
1102 for (clkp = mxc_clks; clkp < mxc_clks + ARRAY_SIZE(mxc_clks); clkp++)
1103 clk_register(*clkp);
1105 if (cpu_is_mx31()) {
1106 clk_register(&mpeg4_clk);
1107 clk_register(&mbx_clk);
1109 clk_register(&vpu_clk);
1110 clk_register(&vl2cc_clk);
1113 /* Turn off all possible clocks */
1114 __raw_writel(MXC_CCM_CGR0_GPT_MASK, MXC_CCM_CGR0);
1115 __raw_writel(0, MXC_CCM_CGR1);
1117 __raw_writel(MXC_CCM_CGR2_EMI_MASK |
1118 MXC_CCM_CGR2_IPMUX1_MASK |
1119 MXC_CCM_CGR2_IPMUX2_MASK |
1120 MXC_CCM_CGR2_MXCCLKENSEL_MASK | /* for MX32 */
1121 MXC_CCM_CGR2_CHIKCAMPEN_MASK | /* for MX32 */
1122 MXC_CCM_CGR2_OVRVPUBUSY_MASK | /* for MX32 */
1123 1 << 27 | 1 << 28, /* Bit 27 and 28 are not defined for
1124 MX32, but still required to be set */
1127 clk_disable(&cko1_clk);
1128 clk_disable(&usb_pll_clk);
1130 pr_info("Clock input source is %ld\n", clk_get_rate(&ckih_clk));
1132 clk_enable(&gpt_clk);
1133 clk_enable(&emi_clk);
1134 clk_enable(&iim_clk);
1136 clk_enable(&serial_pll_clk);
1138 if (mx31_revision() >= CHIP_REV_2_0) {
1139 reg = __raw_readl(MXC_CCM_PMCR1);
1140 /* No PLL restart on DVFS switch; enable auto EMI handshake */
1141 reg |= MXC_CCM_PMCR1_PLLRDIS | MXC_CCM_PMCR1_EMIRQ_EN;
1142 __raw_writel(reg, MXC_CCM_PMCR1);