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 <mach/clock.h>
27 #include <mach/hardware.h>
28 #include <asm/div64.h>
32 #define PRE_DIV_MIN_FREQ 10000000 /* Minimum Frequency after Predivider */
34 static void __calc_pre_post_dividers(u32 div
, u32
*pre
, u32
*post
)
36 u32 min_pre
, temp_pre
, old_err
, err
;
41 } else if (div
>= 64) {
42 min_pre
= (div
- 1) / 64 + 1;
44 for (temp_pre
= 8; temp_pre
>= min_pre
; temp_pre
--) {
56 *post
= (div
+ *pre
- 1) / *pre
;
57 } else if (div
<= 8) {
66 static struct clk mcu_pll_clk
;
67 static struct clk mcu_main_clk
;
68 static struct clk usb_pll_clk
;
69 static struct clk serial_pll_clk
;
70 static struct clk ipg_clk
;
71 static struct clk ckih_clk
;
72 static struct clk ahb_clk
;
74 static int _clk_enable(struct clk
*clk
)
78 reg
= __raw_readl(clk
->enable_reg
);
79 reg
|= 3 << clk
->enable_shift
;
80 __raw_writel(reg
, clk
->enable_reg
);
85 static void _clk_disable(struct clk
*clk
)
89 reg
= __raw_readl(clk
->enable_reg
);
90 reg
&= ~(3 << clk
->enable_shift
);
91 __raw_writel(reg
, clk
->enable_reg
);
94 static void _clk_emi_disable(struct clk
*clk
)
98 reg
= __raw_readl(clk
->enable_reg
);
99 reg
&= ~(3 << clk
->enable_shift
);
100 reg
|= (1 << clk
->enable_shift
);
101 __raw_writel(reg
, clk
->enable_reg
);
104 static int _clk_pll_set_rate(struct clk
*clk
, unsigned long rate
)
107 signed long pd
= 1; /* Pre-divider */
108 signed long mfi
; /* Multiplication Factor (Integer part) */
109 signed long mfn
; /* Multiplication Factor (Integer part) */
110 signed long mfd
; /* Multiplication Factor (Denominator Part) */
112 u32 ref_freq
= clk_get_rate(clk
->parent
);
114 while (((ref_freq
/ pd
) * 10) > rate
)
117 if ((ref_freq
/ pd
) < PRE_DIV_MIN_FREQ
)
120 /* the ref_freq/2 in the following is to round up */
121 mfi
= (((rate
/ 2) * pd
) + (ref_freq
/ 2)) / ref_freq
;
122 if (mfi
< 5 || mfi
> 15)
125 /* pick a mfd value that will work
126 * then solve for mfn */
127 mfd
= ref_freq
/ 50000;
130 * pll_freq * pd * mfd
131 * mfn = -------------------- - (mfi * mfd)
134 /* the tmp/2 is for rounding */
135 tmp
= ref_freq
/ 10000;
137 ((((((rate
/ 2) + (tmp
/ 2)) / tmp
) * pd
) * mfd
) / 10000) -
144 /* Change the Pll value */
145 reg
= (mfi
<< MXC_CCM_PCTL_MFI_OFFSET
) |
146 (mfn
<< MXC_CCM_PCTL_MFN_OFFSET
) |
147 (mfd
<< MXC_CCM_PCTL_MFD_OFFSET
) | (pd
<< MXC_CCM_PCTL_PD_OFFSET
);
149 if (clk
== &mcu_pll_clk
)
150 __raw_writel(reg
, MXC_CCM_MPCTL
);
151 else if (clk
== &usb_pll_clk
)
152 __raw_writel(reg
, MXC_CCM_UPCTL
);
153 else if (clk
== &serial_pll_clk
)
154 __raw_writel(reg
, MXC_CCM_SRPCTL
);
159 static unsigned long _clk_pll_get_rate(struct clk
*clk
)
161 long mfi
, mfn
, mfd
, pdf
, ref_clk
, mfn_abs
;
162 unsigned long reg
, ccmr
;
166 ccmr
= __raw_readl(MXC_CCM_CCMR
);
167 prcs
= (ccmr
& MXC_CCM_CCMR_PRCS_MASK
) >> MXC_CCM_CCMR_PRCS_OFFSET
;
169 ref_clk
= CKIL_CLK_FREQ
* 1024;
171 ref_clk
= clk_get_rate(&ckih_clk
);
173 if (clk
== &mcu_pll_clk
) {
174 if ((ccmr
& MXC_CCM_CCMR_MPE
) == 0)
176 if ((ccmr
& MXC_CCM_CCMR_MDS
) != 0)
178 reg
= __raw_readl(MXC_CCM_MPCTL
);
179 } else if (clk
== &usb_pll_clk
)
180 reg
= __raw_readl(MXC_CCM_UPCTL
);
181 else if (clk
== &serial_pll_clk
)
182 reg
= __raw_readl(MXC_CCM_SRPCTL
);
188 pdf
= (reg
& MXC_CCM_PCTL_PD_MASK
) >> MXC_CCM_PCTL_PD_OFFSET
;
189 mfd
= (reg
& MXC_CCM_PCTL_MFD_MASK
) >> MXC_CCM_PCTL_MFD_OFFSET
;
190 mfi
= (reg
& MXC_CCM_PCTL_MFI_MASK
) >> MXC_CCM_PCTL_MFI_OFFSET
;
191 mfi
= (mfi
<= 5) ? 5 : mfi
;
192 mfn
= mfn_abs
= reg
& MXC_CCM_PCTL_MFN_MASK
;
202 temp
= (u64
) ref_clk
* mfn_abs
;
203 do_div(temp
, mfd
+ 1);
206 temp
= (ref_clk
* mfi
) + temp
;
211 static int _clk_usb_pll_enable(struct clk
*clk
)
215 reg
= __raw_readl(MXC_CCM_CCMR
);
216 reg
|= MXC_CCM_CCMR_UPE
;
217 __raw_writel(reg
, MXC_CCM_CCMR
);
219 /* No lock bit on MX31, so using max time from spec */
225 static void _clk_usb_pll_disable(struct clk
*clk
)
229 reg
= __raw_readl(MXC_CCM_CCMR
);
230 reg
&= ~MXC_CCM_CCMR_UPE
;
231 __raw_writel(reg
, MXC_CCM_CCMR
);
234 static int _clk_serial_pll_enable(struct clk
*clk
)
238 reg
= __raw_readl(MXC_CCM_CCMR
);
239 reg
|= MXC_CCM_CCMR_SPE
;
240 __raw_writel(reg
, MXC_CCM_CCMR
);
242 /* No lock bit on MX31, so using max time from spec */
248 static void _clk_serial_pll_disable(struct clk
*clk
)
252 reg
= __raw_readl(MXC_CCM_CCMR
);
253 reg
&= ~MXC_CCM_CCMR_SPE
;
254 __raw_writel(reg
, MXC_CCM_CCMR
);
257 #define PDR0(mask, off) ((__raw_readl(MXC_CCM_PDR0) & mask) >> off)
258 #define PDR1(mask, off) ((__raw_readl(MXC_CCM_PDR1) & mask) >> off)
259 #define PDR2(mask, off) ((__raw_readl(MXC_CCM_PDR2) & mask) >> off)
261 static unsigned long _clk_mcu_main_get_rate(struct clk
*clk
)
263 u32 pmcr0
= __raw_readl(MXC_CCM_PMCR0
);
265 if ((pmcr0
& MXC_CCM_PMCR0_DFSUP1
) == MXC_CCM_PMCR0_DFSUP1_SPLL
)
266 return clk_get_rate(&serial_pll_clk
);
268 return clk_get_rate(&mcu_pll_clk
);
271 static unsigned long _clk_hclk_get_rate(struct clk
*clk
)
273 unsigned long max_pdf
;
275 max_pdf
= PDR0(MXC_CCM_PDR0_MAX_PODF_MASK
,
276 MXC_CCM_PDR0_MAX_PODF_OFFSET
);
277 return clk_get_rate(clk
->parent
) / (max_pdf
+ 1);
280 static unsigned long _clk_ipg_get_rate(struct clk
*clk
)
282 unsigned long ipg_pdf
;
284 ipg_pdf
= PDR0(MXC_CCM_PDR0_IPG_PODF_MASK
,
285 MXC_CCM_PDR0_IPG_PODF_OFFSET
);
286 return clk_get_rate(clk
->parent
) / (ipg_pdf
+ 1);
289 static unsigned long _clk_nfc_get_rate(struct clk
*clk
)
291 unsigned long nfc_pdf
;
293 nfc_pdf
= PDR0(MXC_CCM_PDR0_NFC_PODF_MASK
,
294 MXC_CCM_PDR0_NFC_PODF_OFFSET
);
295 return clk_get_rate(clk
->parent
) / (nfc_pdf
+ 1);
298 static unsigned long _clk_hsp_get_rate(struct clk
*clk
)
300 unsigned long hsp_pdf
;
302 hsp_pdf
= PDR0(MXC_CCM_PDR0_HSP_PODF_MASK
,
303 MXC_CCM_PDR0_HSP_PODF_OFFSET
);
304 return clk_get_rate(clk
->parent
) / (hsp_pdf
+ 1);
307 static unsigned long _clk_usb_get_rate(struct clk
*clk
)
309 unsigned long usb_pdf
, usb_prepdf
;
311 usb_pdf
= PDR1(MXC_CCM_PDR1_USB_PODF_MASK
,
312 MXC_CCM_PDR1_USB_PODF_OFFSET
);
313 usb_prepdf
= PDR1(MXC_CCM_PDR1_USB_PRDF_MASK
,
314 MXC_CCM_PDR1_USB_PRDF_OFFSET
);
315 return clk_get_rate(clk
->parent
) / (usb_prepdf
+ 1) / (usb_pdf
+ 1);
318 static unsigned long _clk_csi_get_rate(struct clk
*clk
)
322 reg
= __raw_readl(MXC_CCM_PDR0
);
323 pre
= (reg
& MXC_CCM_PDR0_CSI_PRDF_MASK
) >>
324 MXC_CCM_PDR0_CSI_PRDF_OFFSET
;
326 post
= (reg
& MXC_CCM_PDR0_CSI_PODF_MASK
) >>
327 MXC_CCM_PDR0_CSI_PODF_OFFSET
;
329 return clk_get_rate(clk
->parent
) / (pre
* post
);
332 static unsigned long _clk_csi_round_rate(struct clk
*clk
, unsigned long rate
)
334 u32 pre
, post
, parent
= clk_get_rate(clk
->parent
);
335 u32 div
= parent
/ rate
;
340 __calc_pre_post_dividers(div
, &pre
, &post
);
342 return parent
/ (pre
* post
);
345 static int _clk_csi_set_rate(struct clk
*clk
, unsigned long rate
)
347 u32 reg
, div
, pre
, post
, parent
= clk_get_rate(clk
->parent
);
351 if ((parent
/ div
) != rate
)
354 __calc_pre_post_dividers(div
, &pre
, &post
);
356 /* Set CSI clock divider */
357 reg
= __raw_readl(MXC_CCM_PDR0
) &
358 ~(MXC_CCM_PDR0_CSI_PODF_MASK
| MXC_CCM_PDR0_CSI_PRDF_MASK
);
359 reg
|= (post
- 1) << MXC_CCM_PDR0_CSI_PODF_OFFSET
;
360 reg
|= (pre
- 1) << MXC_CCM_PDR0_CSI_PRDF_OFFSET
;
361 __raw_writel(reg
, MXC_CCM_PDR0
);
366 static unsigned long _clk_per_get_rate(struct clk
*clk
)
368 unsigned long per_pdf
;
370 per_pdf
= PDR0(MXC_CCM_PDR0_PER_PODF_MASK
,
371 MXC_CCM_PDR0_PER_PODF_OFFSET
);
372 return clk_get_rate(clk
->parent
) / (per_pdf
+ 1);
375 static unsigned long _clk_ssi1_get_rate(struct clk
*clk
)
377 unsigned long ssi1_pdf
, ssi1_prepdf
;
379 ssi1_pdf
= PDR1(MXC_CCM_PDR1_SSI1_PODF_MASK
,
380 MXC_CCM_PDR1_SSI1_PODF_OFFSET
);
381 ssi1_prepdf
= PDR1(MXC_CCM_PDR1_SSI1_PRE_PODF_MASK
,
382 MXC_CCM_PDR1_SSI1_PRE_PODF_OFFSET
);
383 return clk_get_rate(clk
->parent
) / (ssi1_prepdf
+ 1) / (ssi1_pdf
+ 1);
386 static unsigned long _clk_ssi2_get_rate(struct clk
*clk
)
388 unsigned long ssi2_pdf
, ssi2_prepdf
;
390 ssi2_pdf
= PDR1(MXC_CCM_PDR1_SSI2_PODF_MASK
,
391 MXC_CCM_PDR1_SSI2_PODF_OFFSET
);
392 ssi2_prepdf
= PDR1(MXC_CCM_PDR1_SSI2_PRE_PODF_MASK
,
393 MXC_CCM_PDR1_SSI2_PRE_PODF_OFFSET
);
394 return clk_get_rate(clk
->parent
) / (ssi2_prepdf
+ 1) / (ssi2_pdf
+ 1);
397 static unsigned long _clk_firi_get_rate(struct clk
*clk
)
399 unsigned long firi_pdf
, firi_prepdf
;
401 firi_pdf
= PDR1(MXC_CCM_PDR1_FIRI_PODF_MASK
,
402 MXC_CCM_PDR1_FIRI_PODF_OFFSET
);
403 firi_prepdf
= PDR1(MXC_CCM_PDR1_FIRI_PRE_PODF_MASK
,
404 MXC_CCM_PDR1_FIRI_PRE_PODF_OFFSET
);
405 return clk_get_rate(clk
->parent
) / (firi_prepdf
+ 1) / (firi_pdf
+ 1);
408 static unsigned long _clk_firi_round_rate(struct clk
*clk
, unsigned long rate
)
411 u32 parent
= clk_get_rate(clk
->parent
);
412 u32 div
= parent
/ rate
;
417 __calc_pre_post_dividers(div
, &pre
, &post
);
419 return parent
/ (pre
* post
);
423 static int _clk_firi_set_rate(struct clk
*clk
, unsigned long rate
)
425 u32 reg
, div
, pre
, post
, parent
= clk_get_rate(clk
->parent
);
429 if ((parent
/ div
) != rate
)
432 __calc_pre_post_dividers(div
, &pre
, &post
);
434 /* Set FIRI clock divider */
435 reg
= __raw_readl(MXC_CCM_PDR1
) &
436 ~(MXC_CCM_PDR1_FIRI_PODF_MASK
| MXC_CCM_PDR1_FIRI_PRE_PODF_MASK
);
437 reg
|= (pre
- 1) << MXC_CCM_PDR1_FIRI_PRE_PODF_OFFSET
;
438 reg
|= (post
- 1) << MXC_CCM_PDR1_FIRI_PODF_OFFSET
;
439 __raw_writel(reg
, MXC_CCM_PDR1
);
444 static unsigned long _clk_mbx_get_rate(struct clk
*clk
)
446 return clk_get_rate(clk
->parent
) / 2;
449 static unsigned long _clk_mstick1_get_rate(struct clk
*clk
)
451 unsigned long msti_pdf
;
453 msti_pdf
= PDR2(MXC_CCM_PDR2_MST1_PDF_MASK
,
454 MXC_CCM_PDR2_MST1_PDF_OFFSET
);
455 return clk_get_rate(clk
->parent
) / (msti_pdf
+ 1);
458 static unsigned long _clk_mstick2_get_rate(struct clk
*clk
)
460 unsigned long msti_pdf
;
462 msti_pdf
= PDR2(MXC_CCM_PDR2_MST2_PDF_MASK
,
463 MXC_CCM_PDR2_MST2_PDF_OFFSET
);
464 return clk_get_rate(clk
->parent
) / (msti_pdf
+ 1);
467 static unsigned long ckih_rate
;
469 static unsigned long clk_ckih_get_rate(struct clk
*clk
)
474 static struct clk ckih_clk
= {
476 .get_rate
= clk_ckih_get_rate
,
479 static unsigned long clk_ckil_get_rate(struct clk
*clk
)
481 return CKIL_CLK_FREQ
;
484 static struct clk ckil_clk
= {
486 .get_rate
= clk_ckil_get_rate
,
489 static struct clk mcu_pll_clk
= {
492 .set_rate
= _clk_pll_set_rate
,
493 .get_rate
= _clk_pll_get_rate
,
496 static struct clk mcu_main_clk
= {
497 .name
= "mcu_main_clk",
498 .parent
= &mcu_pll_clk
,
499 .get_rate
= _clk_mcu_main_get_rate
,
502 static struct clk serial_pll_clk
= {
503 .name
= "serial_pll",
505 .set_rate
= _clk_pll_set_rate
,
506 .get_rate
= _clk_pll_get_rate
,
507 .enable
= _clk_serial_pll_enable
,
508 .disable
= _clk_serial_pll_disable
,
511 static struct clk usb_pll_clk
= {
514 .set_rate
= _clk_pll_set_rate
,
515 .get_rate
= _clk_pll_get_rate
,
516 .enable
= _clk_usb_pll_enable
,
517 .disable
= _clk_usb_pll_disable
,
520 static struct clk ahb_clk
= {
522 .parent
= &mcu_main_clk
,
523 .get_rate
= _clk_hclk_get_rate
,
526 static struct clk per_clk
= {
528 .parent
= &usb_pll_clk
,
529 .get_rate
= _clk_per_get_rate
,
532 static struct clk perclk_clk
= {
533 .name
= "perclk_clk",
537 static struct clk cspi_clk
[] = {
542 .enable
= _clk_enable
,
543 .enable_reg
= MXC_CCM_CGR2
,
544 .enable_shift
= MXC_CCM_CGR2_CSPI1_OFFSET
,
545 .disable
= _clk_disable
,},
550 .enable
= _clk_enable
,
551 .enable_reg
= MXC_CCM_CGR2
,
552 .enable_shift
= MXC_CCM_CGR2_CSPI2_OFFSET
,
553 .disable
= _clk_disable
,},
558 .enable
= _clk_enable
,
559 .enable_reg
= MXC_CCM_CGR0
,
560 .enable_shift
= MXC_CCM_CGR0_CSPI3_OFFSET
,
561 .disable
= _clk_disable
,},
564 static struct clk ipg_clk
= {
567 .get_rate
= _clk_ipg_get_rate
,
570 static struct clk emi_clk
= {
573 .enable
= _clk_enable
,
574 .enable_reg
= MXC_CCM_CGR2
,
575 .enable_shift
= MXC_CCM_CGR2_EMI_OFFSET
,
576 .disable
= _clk_emi_disable
,
579 static struct clk gpt_clk
= {
581 .parent
= &perclk_clk
,
582 .enable
= _clk_enable
,
583 .enable_reg
= MXC_CCM_CGR0
,
584 .enable_shift
= MXC_CCM_CGR0_GPT_OFFSET
,
585 .disable
= _clk_disable
,
588 static struct clk pwm_clk
= {
590 .parent
= &perclk_clk
,
591 .enable
= _clk_enable
,
592 .enable_reg
= MXC_CCM_CGR0
,
593 .enable_shift
= MXC_CCM_CGR1_PWM_OFFSET
,
594 .disable
= _clk_disable
,
597 static struct clk epit_clk
[] = {
601 .parent
= &perclk_clk
,
602 .enable
= _clk_enable
,
603 .enable_reg
= MXC_CCM_CGR0
,
604 .enable_shift
= MXC_CCM_CGR0_EPIT1_OFFSET
,
605 .disable
= _clk_disable
,},
609 .parent
= &perclk_clk
,
610 .enable
= _clk_enable
,
611 .enable_reg
= MXC_CCM_CGR0
,
612 .enable_shift
= MXC_CCM_CGR0_EPIT2_OFFSET
,
613 .disable
= _clk_disable
,},
616 static struct clk nfc_clk
= {
619 .get_rate
= _clk_nfc_get_rate
,
622 static struct clk scc_clk
= {
627 static struct clk ipu_clk
= {
629 .parent
= &mcu_main_clk
,
630 .get_rate
= _clk_hsp_get_rate
,
631 .enable
= _clk_enable
,
632 .enable_reg
= MXC_CCM_CGR1
,
633 .enable_shift
= MXC_CCM_CGR1_IPU_OFFSET
,
634 .disable
= _clk_disable
,
637 static struct clk kpp_clk
= {
640 .enable
= _clk_enable
,
641 .enable_reg
= MXC_CCM_CGR1
,
642 .enable_shift
= MXC_CCM_CGR1_KPP_OFFSET
,
643 .disable
= _clk_disable
,
646 static struct clk wdog_clk
= {
649 .enable
= _clk_enable
,
650 .enable_reg
= MXC_CCM_CGR1
,
651 .enable_shift
= MXC_CCM_CGR1_WDOG_OFFSET
,
652 .disable
= _clk_disable
,
654 static struct clk rtc_clk
= {
657 .enable
= _clk_enable
,
658 .enable_reg
= MXC_CCM_CGR1
,
659 .enable_shift
= MXC_CCM_CGR1_RTC_OFFSET
,
660 .disable
= _clk_disable
,
663 static struct clk usb_clk
[] = {
666 .parent
= &usb_pll_clk
,
667 .get_rate
= _clk_usb_get_rate
,},
669 .name
= "usb_ahb_clk",
671 .enable
= _clk_enable
,
672 .enable_reg
= MXC_CCM_CGR1
,
673 .enable_shift
= MXC_CCM_CGR1_USBOTG_OFFSET
,
674 .disable
= _clk_disable
,},
677 static struct clk csi_clk
= {
679 .parent
= &serial_pll_clk
,
680 .get_rate
= _clk_csi_get_rate
,
681 .round_rate
= _clk_csi_round_rate
,
682 .set_rate
= _clk_csi_set_rate
,
683 .enable
= _clk_enable
,
684 .enable_reg
= MXC_CCM_CGR1
,
685 .enable_shift
= MXC_CCM_CGR1_CSI_OFFSET
,
686 .disable
= _clk_disable
,
689 static struct clk uart_clk
[] = {
693 .parent
= &perclk_clk
,
694 .enable
= _clk_enable
,
695 .enable_reg
= MXC_CCM_CGR0
,
696 .enable_shift
= MXC_CCM_CGR0_UART1_OFFSET
,
697 .disable
= _clk_disable
,},
701 .parent
= &perclk_clk
,
702 .enable
= _clk_enable
,
703 .enable_reg
= MXC_CCM_CGR0
,
704 .enable_shift
= MXC_CCM_CGR0_UART2_OFFSET
,
705 .disable
= _clk_disable
,},
709 .parent
= &perclk_clk
,
710 .enable
= _clk_enable
,
711 .enable_reg
= MXC_CCM_CGR1
,
712 .enable_shift
= MXC_CCM_CGR1_UART3_OFFSET
,
713 .disable
= _clk_disable
,},
717 .parent
= &perclk_clk
,
718 .enable
= _clk_enable
,
719 .enable_reg
= MXC_CCM_CGR1
,
720 .enable_shift
= MXC_CCM_CGR1_UART4_OFFSET
,
721 .disable
= _clk_disable
,},
725 .parent
= &perclk_clk
,
726 .enable
= _clk_enable
,
727 .enable_reg
= MXC_CCM_CGR1
,
728 .enable_shift
= MXC_CCM_CGR1_UART5_OFFSET
,
729 .disable
= _clk_disable
,},
732 static struct clk i2c_clk
[] = {
736 .parent
= &perclk_clk
,
737 .enable
= _clk_enable
,
738 .enable_reg
= MXC_CCM_CGR0
,
739 .enable_shift
= MXC_CCM_CGR0_I2C1_OFFSET
,
740 .disable
= _clk_disable
,},
744 .parent
= &perclk_clk
,
745 .enable
= _clk_enable
,
746 .enable_reg
= MXC_CCM_CGR0
,
747 .enable_shift
= MXC_CCM_CGR0_I2C2_OFFSET
,
748 .disable
= _clk_disable
,},
752 .parent
= &perclk_clk
,
753 .enable
= _clk_enable
,
754 .enable_reg
= MXC_CCM_CGR0
,
755 .enable_shift
= MXC_CCM_CGR0_I2C3_OFFSET
,
756 .disable
= _clk_disable
,},
759 static struct clk owire_clk
= {
761 .parent
= &perclk_clk
,
762 .enable_reg
= MXC_CCM_CGR1
,
763 .enable_shift
= MXC_CCM_CGR1_OWIRE_OFFSET
,
764 .enable
= _clk_enable
,
765 .disable
= _clk_disable
,
768 static struct clk sdhc_clk
[] = {
772 .parent
= &perclk_clk
,
773 .enable
= _clk_enable
,
774 .enable_reg
= MXC_CCM_CGR0
,
775 .enable_shift
= MXC_CCM_CGR0_SD_MMC1_OFFSET
,
776 .disable
= _clk_disable
,},
780 .parent
= &perclk_clk
,
781 .enable
= _clk_enable
,
782 .enable_reg
= MXC_CCM_CGR0
,
783 .enable_shift
= MXC_CCM_CGR0_SD_MMC2_OFFSET
,
784 .disable
= _clk_disable
,},
787 static struct clk ssi_clk
[] = {
790 .parent
= &serial_pll_clk
,
791 .get_rate
= _clk_ssi1_get_rate
,
792 .enable
= _clk_enable
,
793 .enable_reg
= MXC_CCM_CGR0
,
794 .enable_shift
= MXC_CCM_CGR0_SSI1_OFFSET
,
795 .disable
= _clk_disable
,},
799 .parent
= &serial_pll_clk
,
800 .get_rate
= _clk_ssi2_get_rate
,
801 .enable
= _clk_enable
,
802 .enable_reg
= MXC_CCM_CGR2
,
803 .enable_shift
= MXC_CCM_CGR2_SSI2_OFFSET
,
804 .disable
= _clk_disable
,},
807 static struct clk firi_clk
= {
809 .parent
= &usb_pll_clk
,
810 .round_rate
= _clk_firi_round_rate
,
811 .set_rate
= _clk_firi_set_rate
,
812 .get_rate
= _clk_firi_get_rate
,
813 .enable
= _clk_enable
,
814 .enable_reg
= MXC_CCM_CGR2
,
815 .enable_shift
= MXC_CCM_CGR2_FIRI_OFFSET
,
816 .disable
= _clk_disable
,
819 static struct clk ata_clk
= {
822 .enable
= _clk_enable
,
823 .enable_reg
= MXC_CCM_CGR0
,
824 .enable_shift
= MXC_CCM_CGR0_ATA_OFFSET
,
825 .disable
= _clk_disable
,
828 static struct clk mbx_clk
= {
831 .enable
= _clk_enable
,
832 .enable_reg
= MXC_CCM_CGR2
,
833 .enable_shift
= MXC_CCM_CGR2_GACC_OFFSET
,
834 .get_rate
= _clk_mbx_get_rate
,
837 static struct clk vpu_clk
= {
840 .enable
= _clk_enable
,
841 .enable_reg
= MXC_CCM_CGR2
,
842 .enable_shift
= MXC_CCM_CGR2_GACC_OFFSET
,
843 .get_rate
= _clk_mbx_get_rate
,
846 static struct clk rtic_clk
= {
849 .enable
= _clk_enable
,
850 .enable_reg
= MXC_CCM_CGR2
,
851 .enable_shift
= MXC_CCM_CGR2_RTIC_OFFSET
,
852 .disable
= _clk_disable
,
855 static struct clk rng_clk
= {
858 .enable
= _clk_enable
,
859 .enable_reg
= MXC_CCM_CGR0
,
860 .enable_shift
= MXC_CCM_CGR0_RNG_OFFSET
,
861 .disable
= _clk_disable
,
864 static struct clk sdma_clk
[] = {
866 .name
= "sdma_ahb_clk",
868 .enable
= _clk_enable
,
869 .enable_reg
= MXC_CCM_CGR0
,
870 .enable_shift
= MXC_CCM_CGR0_SDMA_OFFSET
,
871 .disable
= _clk_disable
,},
873 .name
= "sdma_ipg_clk",
877 static struct clk mpeg4_clk
= {
880 .enable
= _clk_enable
,
881 .enable_reg
= MXC_CCM_CGR1
,
882 .enable_shift
= MXC_CCM_CGR1_HANTRO_OFFSET
,
883 .disable
= _clk_disable
,
886 static struct clk vl2cc_clk
= {
889 .enable
= _clk_enable
,
890 .enable_reg
= MXC_CCM_CGR1
,
891 .enable_shift
= MXC_CCM_CGR1_HANTRO_OFFSET
,
892 .disable
= _clk_disable
,
895 static struct clk mstick_clk
[] = {
897 .name
= "mstick_clk",
899 .parent
= &usb_pll_clk
,
900 .get_rate
= _clk_mstick1_get_rate
,
901 .enable
= _clk_enable
,
902 .enable_reg
= MXC_CCM_CGR1
,
903 .enable_shift
= MXC_CCM_CGR1_MEMSTICK1_OFFSET
,
904 .disable
= _clk_disable
,},
906 .name
= "mstick_clk",
908 .parent
= &usb_pll_clk
,
909 .get_rate
= _clk_mstick2_get_rate
,
910 .enable
= _clk_enable
,
911 .enable_reg
= MXC_CCM_CGR1
,
912 .enable_shift
= MXC_CCM_CGR1_MEMSTICK2_OFFSET
,
913 .disable
= _clk_disable
,},
916 static struct clk iim_clk
= {
919 .enable
= _clk_enable
,
920 .enable_reg
= MXC_CCM_CGR0
,
921 .enable_shift
= MXC_CCM_CGR0_IIM_OFFSET
,
922 .disable
= _clk_disable
,
925 static unsigned long _clk_cko1_round_rate(struct clk
*clk
, unsigned long rate
)
927 u32 div
, parent
= clk_get_rate(clk
->parent
);
943 static int _clk_cko1_set_rate(struct clk
*clk
, unsigned long rate
)
945 u32 reg
, div
, parent
= clk_get_rate(clk
->parent
);
962 reg
= __raw_readl(MXC_CCM_COSR
) & ~MXC_CCM_COSR_CLKOUTDIV_MASK
;
963 reg
|= div
<< MXC_CCM_COSR_CLKOUTDIV_OFFSET
;
964 __raw_writel(reg
, MXC_CCM_COSR
);
969 static unsigned long _clk_cko1_get_rate(struct clk
*clk
)
973 div
= __raw_readl(MXC_CCM_COSR
) & MXC_CCM_COSR_CLKOUTDIV_MASK
>>
974 MXC_CCM_COSR_CLKOUTDIV_OFFSET
;
976 return clk_get_rate(clk
->parent
) / (1 << div
);
979 static int _clk_cko1_set_parent(struct clk
*clk
, struct clk
*parent
)
983 reg
= __raw_readl(MXC_CCM_COSR
) & ~MXC_CCM_COSR_CLKOSEL_MASK
;
985 if (parent
== &mcu_main_clk
)
986 reg
|= 0 << MXC_CCM_COSR_CLKOSEL_OFFSET
;
987 else if (parent
== &ipg_clk
)
988 reg
|= 1 << MXC_CCM_COSR_CLKOSEL_OFFSET
;
989 else if (parent
== &usb_pll_clk
)
990 reg
|= 2 << MXC_CCM_COSR_CLKOSEL_OFFSET
;
991 else if (parent
== mcu_main_clk
.parent
)
992 reg
|= 3 << MXC_CCM_COSR_CLKOSEL_OFFSET
;
993 else if (parent
== &ahb_clk
)
994 reg
|= 5 << MXC_CCM_COSR_CLKOSEL_OFFSET
;
995 else if (parent
== &serial_pll_clk
)
996 reg
|= 7 << MXC_CCM_COSR_CLKOSEL_OFFSET
;
997 else if (parent
== &ckih_clk
)
998 reg
|= 8 << MXC_CCM_COSR_CLKOSEL_OFFSET
;
999 else if (parent
== &emi_clk
)
1000 reg
|= 9 << MXC_CCM_COSR_CLKOSEL_OFFSET
;
1001 else if (parent
== &ipu_clk
)
1002 reg
|= 0xA << MXC_CCM_COSR_CLKOSEL_OFFSET
;
1003 else if (parent
== &nfc_clk
)
1004 reg
|= 0xB << MXC_CCM_COSR_CLKOSEL_OFFSET
;
1005 else if (parent
== &uart_clk
[0])
1006 reg
|= 0xC << MXC_CCM_COSR_CLKOSEL_OFFSET
;
1010 __raw_writel(reg
, MXC_CCM_COSR
);
1015 static int _clk_cko1_enable(struct clk
*clk
)
1019 reg
= __raw_readl(MXC_CCM_COSR
) | MXC_CCM_COSR_CLKOEN
;
1020 __raw_writel(reg
, MXC_CCM_COSR
);
1025 static void _clk_cko1_disable(struct clk
*clk
)
1029 reg
= __raw_readl(MXC_CCM_COSR
) & ~MXC_CCM_COSR_CLKOEN
;
1030 __raw_writel(reg
, MXC_CCM_COSR
);
1033 static struct clk cko1_clk
= {
1035 .get_rate
= _clk_cko1_get_rate
,
1036 .set_rate
= _clk_cko1_set_rate
,
1037 .round_rate
= _clk_cko1_round_rate
,
1038 .set_parent
= _clk_cko1_set_parent
,
1039 .enable
= _clk_cko1_enable
,
1040 .disable
= _clk_cko1_disable
,
1043 static struct clk
*mxc_clks
[] = {
1096 int __init
mxc_clocks_init(unsigned long fref
)
1103 for (clkp
= mxc_clks
; clkp
< mxc_clks
+ ARRAY_SIZE(mxc_clks
); clkp
++)
1104 clk_register(*clkp
);
1106 if (cpu_is_mx31()) {
1107 clk_register(&mpeg4_clk
);
1108 clk_register(&mbx_clk
);
1110 clk_register(&vpu_clk
);
1111 clk_register(&vl2cc_clk
);
1114 /* Turn off all possible clocks */
1115 __raw_writel(MXC_CCM_CGR0_GPT_MASK
, MXC_CCM_CGR0
);
1116 __raw_writel(0, MXC_CCM_CGR1
);
1118 __raw_writel(MXC_CCM_CGR2_EMI_MASK
|
1119 MXC_CCM_CGR2_IPMUX1_MASK
|
1120 MXC_CCM_CGR2_IPMUX2_MASK
|
1121 MXC_CCM_CGR2_MXCCLKENSEL_MASK
| /* for MX32 */
1122 MXC_CCM_CGR2_CHIKCAMPEN_MASK
| /* for MX32 */
1123 MXC_CCM_CGR2_OVRVPUBUSY_MASK
| /* for MX32 */
1124 1 << 27 | 1 << 28, /* Bit 27 and 28 are not defined for
1125 MX32, but still required to be set */
1128 clk_disable(&cko1_clk
);
1129 clk_disable(&usb_pll_clk
);
1131 pr_info("Clock input source is %ld\n", clk_get_rate(&ckih_clk
));
1133 clk_enable(&gpt_clk
);
1134 clk_enable(&emi_clk
);
1135 clk_enable(&iim_clk
);
1137 clk_enable(&serial_pll_clk
);
1139 if (mx31_revision() >= CHIP_REV_2_0
) {
1140 reg
= __raw_readl(MXC_CCM_PMCR1
);
1141 /* No PLL restart on DVFS switch; enable auto EMI handshake */
1142 reg
|= MXC_CCM_PMCR1_PLLRDIS
| MXC_CCM_PMCR1_EMIRQ_EN
;
1143 __raw_writel(reg
, MXC_CCM_PMCR1
);