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 <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
);