added 2.6.29.6 aldebaran kernel
[nao-ulib.git] / kernel / 2.6.29.6-aldebaran-rt / arch / arm / mach-mx2 / clock_imx27.c
blobc69896d011a1171cfe5819ef43a6867dd2ba092a
1 /*
2 * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
3 * Copyright 2008 Juergen Beisert, 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,
17 * MA 02110-1301, USA.
20 #include <linux/clk.h>
21 #include <linux/io.h>
22 #include <linux/module.h>
23 #include <linux/spinlock.h>
25 #include <mach/clock.h>
26 #include <mach/common.h>
27 #include <asm/div64.h>
29 #include "crm_regs.h"
31 static struct clk ckil_clk;
32 static struct clk mpll_clk;
33 static struct clk mpll_main_clk[];
34 static struct clk spll_clk;
36 static int _clk_enable(struct clk *clk)
38 unsigned long reg;
40 reg = __raw_readl(clk->enable_reg);
41 reg |= 1 << clk->enable_shift;
42 __raw_writel(reg, clk->enable_reg);
44 return 0;
47 static void _clk_disable(struct clk *clk)
49 unsigned long reg;
51 reg = __raw_readl(clk->enable_reg);
52 reg &= ~(1 << clk->enable_shift);
53 __raw_writel(reg, clk->enable_reg);
56 static int _clk_spll_enable(struct clk *clk)
58 unsigned long reg;
60 reg = __raw_readl(CCM_CSCR);
61 reg |= CCM_CSCR_SPEN;
62 __raw_writel(reg, CCM_CSCR);
64 while ((__raw_readl(CCM_SPCTL1) & CCM_SPCTL1_LF) == 0)
67 return 0;
70 static void _clk_spll_disable(struct clk *clk)
72 unsigned long reg;
74 reg = __raw_readl(CCM_CSCR);
75 reg &= ~CCM_CSCR_SPEN;
76 __raw_writel(reg, CCM_CSCR);
79 static void _clk_pccr01_enable(unsigned long mask0, unsigned long mask1)
81 unsigned long reg;
83 reg = __raw_readl(CCM_PCCR0);
84 reg |= mask0;
85 __raw_writel(reg, CCM_PCCR0);
87 reg = __raw_readl(CCM_PCCR1);
88 reg |= mask1;
89 __raw_writel(reg, CCM_PCCR1);
93 static void _clk_pccr01_disable(unsigned long mask0, unsigned long mask1)
95 unsigned long reg;
97 reg = __raw_readl(CCM_PCCR0);
98 reg &= ~mask0;
99 __raw_writel(reg, CCM_PCCR0);
101 reg = __raw_readl(CCM_PCCR1);
102 reg &= ~mask1;
103 __raw_writel(reg, CCM_PCCR1);
106 static void _clk_pccr10_enable(unsigned long mask1, unsigned long mask0)
108 unsigned long reg;
110 reg = __raw_readl(CCM_PCCR1);
111 reg |= mask1;
112 __raw_writel(reg, CCM_PCCR1);
114 reg = __raw_readl(CCM_PCCR0);
115 reg |= mask0;
116 __raw_writel(reg, CCM_PCCR0);
119 static void _clk_pccr10_disable(unsigned long mask1, unsigned long mask0)
121 unsigned long reg;
123 reg = __raw_readl(CCM_PCCR1);
124 reg &= ~mask1;
125 __raw_writel(reg, CCM_PCCR1);
127 reg = __raw_readl(CCM_PCCR0);
128 reg &= ~mask0;
129 __raw_writel(reg, CCM_PCCR0);
132 static int _clk_dma_enable(struct clk *clk)
134 _clk_pccr01_enable(CCM_PCCR0_DMA_MASK, CCM_PCCR1_HCLK_DMA_MASK);
136 return 0;
139 static void _clk_dma_disable(struct clk *clk)
141 _clk_pccr01_disable(CCM_PCCR0_DMA_MASK, CCM_PCCR1_HCLK_DMA_MASK);
144 static int _clk_rtic_enable(struct clk *clk)
146 _clk_pccr01_enable(CCM_PCCR0_RTIC_MASK, CCM_PCCR1_HCLK_RTIC_MASK);
148 return 0;
151 static void _clk_rtic_disable(struct clk *clk)
153 _clk_pccr01_disable(CCM_PCCR0_RTIC_MASK, CCM_PCCR1_HCLK_RTIC_MASK);
156 static int _clk_emma_enable(struct clk *clk)
158 _clk_pccr01_enable(CCM_PCCR0_EMMA_MASK, CCM_PCCR1_HCLK_EMMA_MASK);
160 return 0;
163 static void _clk_emma_disable(struct clk *clk)
165 _clk_pccr01_disable(CCM_PCCR0_EMMA_MASK, CCM_PCCR1_HCLK_EMMA_MASK);
168 static int _clk_slcdc_enable(struct clk *clk)
170 _clk_pccr01_enable(CCM_PCCR0_SLCDC_MASK, CCM_PCCR1_HCLK_SLCDC_MASK);
172 return 0;
175 static void _clk_slcdc_disable(struct clk *clk)
177 _clk_pccr01_disable(CCM_PCCR0_SLCDC_MASK, CCM_PCCR1_HCLK_SLCDC_MASK);
180 static int _clk_fec_enable(struct clk *clk)
182 _clk_pccr01_enable(CCM_PCCR0_FEC_MASK, CCM_PCCR1_HCLK_FEC_MASK);
184 return 0;
187 static void _clk_fec_disable(struct clk *clk)
189 _clk_pccr01_disable(CCM_PCCR0_FEC_MASK, CCM_PCCR1_HCLK_FEC_MASK);
192 static int _clk_vpu_enable(struct clk *clk)
194 unsigned long reg;
196 reg = __raw_readl(CCM_PCCR1);
197 reg |= CCM_PCCR1_VPU_BAUD_MASK | CCM_PCCR1_HCLK_VPU_MASK;
198 __raw_writel(reg, CCM_PCCR1);
200 return 0;
203 static void _clk_vpu_disable(struct clk *clk)
205 unsigned long reg;
207 reg = __raw_readl(CCM_PCCR1);
208 reg &= ~(CCM_PCCR1_VPU_BAUD_MASK | CCM_PCCR1_HCLK_VPU_MASK);
209 __raw_writel(reg, CCM_PCCR1);
212 static int _clk_sahara2_enable(struct clk *clk)
214 _clk_pccr01_enable(CCM_PCCR0_SAHARA_MASK, CCM_PCCR1_HCLK_SAHARA_MASK);
216 return 0;
219 static void _clk_sahara2_disable(struct clk *clk)
221 _clk_pccr01_disable(CCM_PCCR0_SAHARA_MASK, CCM_PCCR1_HCLK_SAHARA_MASK);
224 static int _clk_mstick1_enable(struct clk *clk)
226 _clk_pccr10_enable(CCM_PCCR1_MSHC_BAUD_MASK, CCM_PCCR0_MSHC_MASK);
228 return 0;
231 static void _clk_mstick1_disable(struct clk *clk)
233 _clk_pccr10_disable(CCM_PCCR1_MSHC_BAUD_MASK, CCM_PCCR0_MSHC_MASK);
236 #define CSCR() (__raw_readl(CCM_CSCR))
237 #define PCDR0() (__raw_readl(CCM_PCDR0))
238 #define PCDR1() (__raw_readl(CCM_PCDR1))
240 static int _clk_cpu_set_parent(struct clk *clk, struct clk *parent)
242 int cscr = CSCR();
244 if (clk->parent == parent)
245 return 0;
247 if (mx27_revision() >= CHIP_REV_2_0) {
248 if (parent == &mpll_main_clk[0]) {
249 cscr |= CCM_CSCR_ARM_SRC;
250 } else {
251 if (parent == &mpll_main_clk[1])
252 cscr &= ~CCM_CSCR_ARM_SRC;
253 else
254 return -EINVAL;
256 __raw_writel(cscr, CCM_CSCR);
257 } else
258 return -ENODEV;
260 clk->parent = parent;
261 return 0;
264 static unsigned long _clk_cpu_round_rate(struct clk *clk, unsigned long rate)
266 int div;
267 unsigned long parent_rate;
269 parent_rate = clk_get_rate(clk->parent);
271 div = parent_rate / rate;
272 if (parent_rate % rate)
273 div++;
275 if (div > 4)
276 div = 4;
278 return parent_rate / div;
281 static int _clk_cpu_set_rate(struct clk *clk, unsigned long rate)
283 unsigned int div;
284 uint32_t reg;
285 unsigned long parent_rate;
287 parent_rate = clk_get_rate(clk->parent);
289 div = parent_rate / rate;
291 if (div > 4 || div < 1 || ((parent_rate / div) != rate))
292 return -EINVAL;
294 div--;
296 reg = __raw_readl(CCM_CSCR);
297 if (mx27_revision() >= CHIP_REV_2_0) {
298 reg &= ~CCM_CSCR_ARM_MASK;
299 reg |= div << CCM_CSCR_ARM_OFFSET;
300 reg &= ~0x06;
301 __raw_writel(reg | 0x80000000, CCM_CSCR);
302 } else {
303 printk(KERN_ERR "Cant set CPU frequency!\n");
306 return 0;
309 static unsigned long _clk_perclkx_round_rate(struct clk *clk,
310 unsigned long rate)
312 u32 div;
313 unsigned long parent_rate;
315 parent_rate = clk_get_rate(clk->parent);
317 div = parent_rate / rate;
318 if (parent_rate % rate)
319 div++;
321 if (div > 64)
322 div = 64;
324 return parent_rate / div;
327 static int _clk_perclkx_set_rate(struct clk *clk, unsigned long rate)
329 u32 reg;
330 u32 div;
331 unsigned long parent_rate;
333 parent_rate = clk_get_rate(clk->parent);
335 if (clk->id < 0 || clk->id > 3)
336 return -EINVAL;
338 div = parent_rate / rate;
339 if (div > 64 || div < 1 || ((parent_rate / div) != rate))
340 return -EINVAL;
341 div--;
343 reg =
344 __raw_readl(CCM_PCDR1) & ~(CCM_PCDR1_PERDIV1_MASK <<
345 (clk->id << 3));
346 reg |= div << (clk->id << 3);
347 __raw_writel(reg, CCM_PCDR1);
349 return 0;
352 static unsigned long _clk_usb_recalc(struct clk *clk)
354 unsigned long usb_pdf;
355 unsigned long parent_rate;
357 parent_rate = clk_get_rate(clk->parent);
359 usb_pdf = (CSCR() & CCM_CSCR_USB_MASK) >> CCM_CSCR_USB_OFFSET;
361 return parent_rate / (usb_pdf + 1U);
364 static unsigned long _clk_ssi1_recalc(struct clk *clk)
366 unsigned long ssi1_pdf;
367 unsigned long parent_rate;
369 parent_rate = clk_get_rate(clk->parent);
371 ssi1_pdf = (PCDR0() & CCM_PCDR0_SSI1BAUDDIV_MASK) >>
372 CCM_PCDR0_SSI1BAUDDIV_OFFSET;
374 if (mx27_revision() >= CHIP_REV_2_0)
375 ssi1_pdf += 4;
376 else
377 ssi1_pdf = (ssi1_pdf < 2) ? 124UL : ssi1_pdf;
379 return 2UL * parent_rate / ssi1_pdf;
382 static unsigned long _clk_ssi2_recalc(struct clk *clk)
384 unsigned long ssi2_pdf;
385 unsigned long parent_rate;
387 parent_rate = clk_get_rate(clk->parent);
389 ssi2_pdf = (PCDR0() & CCM_PCDR0_SSI2BAUDDIV_MASK) >>
390 CCM_PCDR0_SSI2BAUDDIV_OFFSET;
392 if (mx27_revision() >= CHIP_REV_2_0)
393 ssi2_pdf += 4;
394 else
395 ssi2_pdf = (ssi2_pdf < 2) ? 124UL : ssi2_pdf;
397 return 2UL * parent_rate / ssi2_pdf;
400 static unsigned long _clk_nfc_recalc(struct clk *clk)
402 unsigned long nfc_pdf;
403 unsigned long parent_rate;
405 parent_rate = clk_get_rate(clk->parent);
407 if (mx27_revision() >= CHIP_REV_2_0) {
408 nfc_pdf =
409 (PCDR0() & CCM_PCDR0_NFCDIV2_MASK) >>
410 CCM_PCDR0_NFCDIV2_OFFSET;
411 } else {
412 nfc_pdf =
413 (PCDR0() & CCM_PCDR0_NFCDIV_MASK) >>
414 CCM_PCDR0_NFCDIV_OFFSET;
417 return parent_rate / (nfc_pdf + 1);
420 static unsigned long _clk_vpu_recalc(struct clk *clk)
422 unsigned long vpu_pdf;
423 unsigned long parent_rate;
425 parent_rate = clk_get_rate(clk->parent);
427 if (mx27_revision() >= CHIP_REV_2_0) {
428 vpu_pdf =
429 (PCDR0() & CCM_PCDR0_VPUDIV2_MASK) >>
430 CCM_PCDR0_VPUDIV2_OFFSET;
431 vpu_pdf += 4;
432 } else {
433 vpu_pdf =
434 (PCDR0() & CCM_PCDR0_VPUDIV_MASK) >>
435 CCM_PCDR0_VPUDIV_OFFSET;
436 vpu_pdf = (vpu_pdf < 2) ? 124 : vpu_pdf;
438 return 2UL * parent_rate / vpu_pdf;
441 static unsigned long _clk_parent_round_rate(struct clk *clk, unsigned long rate)
443 return clk->parent->round_rate(clk->parent, rate);
446 static int _clk_parent_set_rate(struct clk *clk, unsigned long rate)
448 return clk->parent->set_rate(clk->parent, rate);
451 /* in Hz */
452 static unsigned long external_high_reference = 26000000;
454 static unsigned long get_high_reference_clock_rate(struct clk *clk)
456 return external_high_reference;
460 * the high frequency external clock reference
461 * Default case is 26MHz. Could be changed at runtime
462 * with a call to change_external_high_reference()
464 static struct clk ckih_clk = {
465 .name = "ckih",
466 .get_rate = get_high_reference_clock_rate,
469 /* in Hz */
470 static unsigned long external_low_reference = 32768;
472 static unsigned long get_low_reference_clock_rate(struct clk *clk)
474 return external_low_reference;
478 * the low frequency external clock reference
479 * Default case is 32.768kHz Could be changed at runtime
480 * with a call to change_external_low_reference()
482 static struct clk ckil_clk = {
483 .name = "ckil",
484 .get_rate = get_low_reference_clock_rate,
487 static unsigned long get_mpll_clk(struct clk *clk)
489 uint32_t reg;
490 unsigned long ref_clk;
491 unsigned long mfi = 0, mfn = 0, mfd = 0, pdf = 0;
492 unsigned long long temp;
494 ref_clk = clk_get_rate(clk->parent);
496 reg = __raw_readl(CCM_MPCTL0);
497 pdf = (reg & CCM_MPCTL0_PD_MASK) >> CCM_MPCTL0_PD_OFFSET;
498 mfd = (reg & CCM_MPCTL0_MFD_MASK) >> CCM_MPCTL0_MFD_OFFSET;
499 mfi = (reg & CCM_MPCTL0_MFI_MASK) >> CCM_MPCTL0_MFI_OFFSET;
500 mfn = (reg & CCM_MPCTL0_MFN_MASK) >> CCM_MPCTL0_MFN_OFFSET;
502 mfi = (mfi <= 5) ? 5 : mfi;
503 temp = 2LL * ref_clk * mfn;
504 do_div(temp, mfd + 1);
505 temp = 2LL * ref_clk * mfi + temp;
506 do_div(temp, pdf + 1);
508 return (unsigned long)temp;
511 static struct clk mpll_clk = {
512 .name = "mpll",
513 .parent = &ckih_clk,
514 .get_rate = get_mpll_clk,
517 static unsigned long _clk_mpll_main_get_rate(struct clk *clk)
519 unsigned long parent_rate;
521 parent_rate = clk_get_rate(clk->parent);
523 /* i.MX27 TO2:
524 * clk->id == 0: arm clock source path 1 which is from 2*MPLL/DIV_2
525 * clk->id == 1: arm clock source path 2 which is from 2*MPLL/DIV_3
528 if (mx27_revision() >= CHIP_REV_2_0 && clk->id == 1)
529 return 2UL * parent_rate / 3UL;
531 return parent_rate;
534 static struct clk mpll_main_clk[] = {
536 /* For i.MX27 TO2, it is the MPLL path 1 of ARM core
537 * It provide the clock source whose rate is same as MPLL
539 .name = "mpll_main",
540 .id = 0,
541 .parent = &mpll_clk,
542 .get_rate = _clk_mpll_main_get_rate
543 }, {
544 /* For i.MX27 TO2, it is the MPLL path 2 of ARM core
545 * It provide the clock source whose rate is same MPLL * 2/3
547 .name = "mpll_main",
548 .id = 1,
549 .parent = &mpll_clk,
550 .get_rate = _clk_mpll_main_get_rate
554 static unsigned long get_spll_clk(struct clk *clk)
556 uint32_t reg;
557 unsigned long ref_clk;
558 unsigned long mfi = 0, mfn = 0, mfd = 0, pdf = 0;
559 unsigned long long temp;
561 ref_clk = clk_get_rate(clk->parent);
563 reg = __raw_readl(CCM_SPCTL0);
564 /*TODO: This is TO2 Bug */
565 if (mx27_revision() >= CHIP_REV_2_0)
566 __raw_writel(reg, CCM_SPCTL0);
568 pdf = (reg & CCM_SPCTL0_PD_MASK) >> CCM_SPCTL0_PD_OFFSET;
569 mfd = (reg & CCM_SPCTL0_MFD_MASK) >> CCM_SPCTL0_MFD_OFFSET;
570 mfi = (reg & CCM_SPCTL0_MFI_MASK) >> CCM_SPCTL0_MFI_OFFSET;
571 mfn = (reg & CCM_SPCTL0_MFN_MASK) >> CCM_SPCTL0_MFN_OFFSET;
573 mfi = (mfi <= 5) ? 5 : mfi;
574 temp = 2LL * ref_clk * mfn;
575 do_div(temp, mfd + 1);
576 temp = 2LL * ref_clk * mfi + temp;
577 do_div(temp, pdf + 1);
579 return (unsigned long)temp;
582 static struct clk spll_clk = {
583 .name = "spll",
584 .parent = &ckih_clk,
585 .get_rate = get_spll_clk,
586 .enable = _clk_spll_enable,
587 .disable = _clk_spll_disable,
590 static unsigned long get_cpu_clk(struct clk *clk)
592 u32 div;
593 unsigned long rate;
595 if (mx27_revision() >= CHIP_REV_2_0)
596 div = (CSCR() & CCM_CSCR_ARM_MASK) >> CCM_CSCR_ARM_OFFSET;
597 else
598 div = (CSCR() & CCM_CSCR_PRESC_MASK) >> CCM_CSCR_PRESC_OFFSET;
600 rate = clk_get_rate(clk->parent);
601 return rate / (div + 1);
604 static struct clk cpu_clk = {
605 .name = "cpu_clk",
606 .parent = &mpll_main_clk[1],
607 .set_parent = _clk_cpu_set_parent,
608 .round_rate = _clk_cpu_round_rate,
609 .get_rate = get_cpu_clk,
610 .set_rate = _clk_cpu_set_rate,
613 static unsigned long get_ahb_clk(struct clk *clk)
615 unsigned long rate;
616 unsigned long bclk_pdf;
618 if (mx27_revision() >= CHIP_REV_2_0)
619 bclk_pdf = (CSCR() & CCM_CSCR_AHB_MASK)
620 >> CCM_CSCR_AHB_OFFSET;
621 else
622 bclk_pdf = (CSCR() & CCM_CSCR_BCLK_MASK)
623 >> CCM_CSCR_BCLK_OFFSET;
625 rate = clk_get_rate(clk->parent);
626 return rate / (bclk_pdf + 1);
629 static struct clk ahb_clk = {
630 .name = "ahb_clk",
631 .parent = &mpll_main_clk[1],
632 .get_rate = get_ahb_clk,
635 static unsigned long get_ipg_clk(struct clk *clk)
637 unsigned long rate;
638 unsigned long ipg_pdf;
640 if (mx27_revision() >= CHIP_REV_2_0)
641 return clk_get_rate(clk->parent);
642 else
643 ipg_pdf = (CSCR() & CCM_CSCR_IPDIV) >> CCM_CSCR_IPDIV_OFFSET;
645 rate = clk_get_rate(clk->parent);
646 return rate / (ipg_pdf + 1);
649 static struct clk ipg_clk = {
650 .name = "ipg_clk",
651 .parent = &ahb_clk,
652 .get_rate = get_ipg_clk,
655 static unsigned long _clk_perclkx_recalc(struct clk *clk)
657 unsigned long perclk_pdf;
658 unsigned long parent_rate;
660 parent_rate = clk_get_rate(clk->parent);
662 if (clk->id < 0 || clk->id > 3)
663 return 0;
665 perclk_pdf = (PCDR1() >> (clk->id << 3)) & CCM_PCDR1_PERDIV1_MASK;
667 return parent_rate / (perclk_pdf + 1);
670 static struct clk per_clk[] = {
672 .name = "per_clk",
673 .id = 0,
674 .parent = &mpll_main_clk[1],
675 .get_rate = _clk_perclkx_recalc,
676 .enable = _clk_enable,
677 .enable_reg = CCM_PCCR1,
678 .enable_shift = CCM_PCCR1_PERCLK1_OFFSET,
679 .disable = _clk_disable,
680 }, {
681 .name = "per_clk",
682 .id = 1,
683 .parent = &mpll_main_clk[1],
684 .get_rate = _clk_perclkx_recalc,
685 .enable = _clk_enable,
686 .enable_reg = CCM_PCCR1,
687 .enable_shift = CCM_PCCR1_PERCLK2_OFFSET,
688 .disable = _clk_disable,
689 }, {
690 .name = "per_clk",
691 .id = 2,
692 .parent = &mpll_main_clk[1],
693 .round_rate = _clk_perclkx_round_rate,
694 .set_rate = _clk_perclkx_set_rate,
695 .get_rate = _clk_perclkx_recalc,
696 .enable = _clk_enable,
697 .enable_reg = CCM_PCCR1,
698 .enable_shift = CCM_PCCR1_PERCLK3_OFFSET,
699 .disable = _clk_disable,
700 }, {
701 .name = "per_clk",
702 .id = 3,
703 .parent = &mpll_main_clk[1],
704 .round_rate = _clk_perclkx_round_rate,
705 .set_rate = _clk_perclkx_set_rate,
706 .get_rate = _clk_perclkx_recalc,
707 .enable = _clk_enable,
708 .enable_reg = CCM_PCCR1,
709 .enable_shift = CCM_PCCR1_PERCLK4_OFFSET,
710 .disable = _clk_disable,
714 struct clk uart1_clk[] = {
716 .name = "uart_clk",
717 .id = 0,
718 .parent = &per_clk[0],
719 .secondary = &uart1_clk[1],
720 }, {
721 .name = "uart_ipg_clk",
722 .id = 0,
723 .parent = &ipg_clk,
724 .enable = _clk_enable,
725 .enable_reg = CCM_PCCR1,
726 .enable_shift = CCM_PCCR1_UART1_OFFSET,
727 .disable = _clk_disable,
731 struct clk uart2_clk[] = {
733 .name = "uart_clk",
734 .id = 1,
735 .parent = &per_clk[0],
736 .secondary = &uart2_clk[1],
737 }, {
738 .name = "uart_ipg_clk",
739 .id = 1,
740 .parent = &ipg_clk,
741 .enable = _clk_enable,
742 .enable_reg = CCM_PCCR1,
743 .enable_shift = CCM_PCCR1_UART2_OFFSET,
744 .disable = _clk_disable,
748 struct clk uart3_clk[] = {
750 .name = "uart_clk",
751 .id = 2,
752 .parent = &per_clk[0],
753 .secondary = &uart3_clk[1],
754 }, {
755 .name = "uart_ipg_clk",
756 .id = 2,
757 .parent = &ipg_clk,
758 .enable = _clk_enable,
759 .enable_reg = CCM_PCCR1,
760 .enable_shift = CCM_PCCR1_UART3_OFFSET,
761 .disable = _clk_disable,
765 struct clk uart4_clk[] = {
767 .name = "uart_clk",
768 .id = 3,
769 .parent = &per_clk[0],
770 .secondary = &uart4_clk[1],
771 }, {
772 .name = "uart_ipg_clk",
773 .id = 3,
774 .parent = &ipg_clk,
775 .enable = _clk_enable,
776 .enable_reg = CCM_PCCR1,
777 .enable_shift = CCM_PCCR1_UART4_OFFSET,
778 .disable = _clk_disable,
782 struct clk uart5_clk[] = {
784 .name = "uart_clk",
785 .id = 4,
786 .parent = &per_clk[0],
787 .secondary = &uart5_clk[1],
788 }, {
789 .name = "uart_ipg_clk",
790 .id = 4,
791 .parent = &ipg_clk,
792 .enable = _clk_enable,
793 .enable_reg = CCM_PCCR1,
794 .enable_shift = CCM_PCCR1_UART5_OFFSET,
795 .disable = _clk_disable,
799 struct clk uart6_clk[] = {
801 .name = "uart_clk",
802 .id = 5,
803 .parent = &per_clk[0],
804 .secondary = &uart6_clk[1],
805 }, {
806 .name = "uart_ipg_clk",
807 .id = 5,
808 .parent = &ipg_clk,
809 .enable = _clk_enable,
810 .enable_reg = CCM_PCCR1,
811 .enable_shift = CCM_PCCR1_UART6_OFFSET,
812 .disable = _clk_disable,
816 static struct clk gpt1_clk[] = {
818 .name = "gpt_clk",
819 .id = 0,
820 .parent = &per_clk[0],
821 .secondary = &gpt1_clk[1],
822 }, {
823 .name = "gpt_ipg_clk",
824 .id = 0,
825 .parent = &ipg_clk,
826 .enable = _clk_enable,
827 .enable_reg = CCM_PCCR0,
828 .enable_shift = CCM_PCCR0_GPT1_OFFSET,
829 .disable = _clk_disable,
833 static struct clk gpt2_clk[] = {
835 .name = "gpt_clk",
836 .id = 1,
837 .parent = &per_clk[0],
838 .secondary = &gpt2_clk[1],
839 }, {
840 .name = "gpt_ipg_clk",
841 .id = 1,
842 .parent = &ipg_clk,
843 .enable = _clk_enable,
844 .enable_reg = CCM_PCCR0,
845 .enable_shift = CCM_PCCR0_GPT2_OFFSET,
846 .disable = _clk_disable,
850 static struct clk gpt3_clk[] = {
852 .name = "gpt_clk",
853 .id = 2,
854 .parent = &per_clk[0],
855 .secondary = &gpt3_clk[1],
856 }, {
857 .name = "gpt_ipg_clk",
858 .id = 2,
859 .parent = &ipg_clk,
860 .enable = _clk_enable,
861 .enable_reg = CCM_PCCR0,
862 .enable_shift = CCM_PCCR0_GPT3_OFFSET,
863 .disable = _clk_disable,
867 static struct clk gpt4_clk[] = {
869 .name = "gpt_clk",
870 .id = 3,
871 .parent = &per_clk[0],
872 .secondary = &gpt4_clk[1],
873 }, {
874 .name = "gpt_ipg_clk",
875 .id = 3,
876 .parent = &ipg_clk,
877 .enable = _clk_enable,
878 .enable_reg = CCM_PCCR0,
879 .enable_shift = CCM_PCCR0_GPT4_OFFSET,
880 .disable = _clk_disable,
884 static struct clk gpt5_clk[] = {
886 .name = "gpt_clk",
887 .id = 4,
888 .parent = &per_clk[0],
889 .secondary = &gpt5_clk[1],
890 }, {
891 .name = "gpt_ipg_clk",
892 .id = 4,
893 .parent = &ipg_clk,
894 .enable = _clk_enable,
895 .enable_reg = CCM_PCCR0,
896 .enable_shift = CCM_PCCR0_GPT5_OFFSET,
897 .disable = _clk_disable,
901 static struct clk gpt6_clk[] = {
903 .name = "gpt_clk",
904 .id = 5,
905 .parent = &per_clk[0],
906 .secondary = &gpt6_clk[1],
907 }, {
908 .name = "gpt_ipg_clk",
909 .id = 5,
910 .parent = &ipg_clk,
911 .enable = _clk_enable,
912 .enable_reg = CCM_PCCR0,
913 .enable_shift = CCM_PCCR0_GPT6_OFFSET,
914 .disable = _clk_disable,
918 static struct clk pwm_clk[] = {
920 .name = "pwm_clk",
921 .parent = &per_clk[0],
922 .secondary = &pwm_clk[1],
923 }, {
924 .name = "pwm_clk",
925 .parent = &ipg_clk,
926 .enable = _clk_enable,
927 .enable_reg = CCM_PCCR0,
928 .enable_shift = CCM_PCCR0_PWM_OFFSET,
929 .disable = _clk_disable,
933 static struct clk sdhc1_clk[] = {
935 .name = "sdhc_clk",
936 .id = 0,
937 .parent = &per_clk[1],
938 .secondary = &sdhc1_clk[1],
939 }, {
940 .name = "sdhc_ipg_clk",
941 .id = 0,
942 .parent = &ipg_clk,
943 .enable = _clk_enable,
944 .enable_reg = CCM_PCCR0,
945 .enable_shift = CCM_PCCR0_SDHC1_OFFSET,
946 .disable = _clk_disable,
950 static struct clk sdhc2_clk[] = {
952 .name = "sdhc_clk",
953 .id = 1,
954 .parent = &per_clk[1],
955 .secondary = &sdhc2_clk[1],
956 }, {
957 .name = "sdhc_ipg_clk",
958 .id = 1,
959 .parent = &ipg_clk,
960 .enable = _clk_enable,
961 .enable_reg = CCM_PCCR0,
962 .enable_shift = CCM_PCCR0_SDHC2_OFFSET,
963 .disable = _clk_disable,
967 static struct clk sdhc3_clk[] = {
969 .name = "sdhc_clk",
970 .id = 2,
971 .parent = &per_clk[1],
972 .secondary = &sdhc3_clk[1],
973 }, {
974 .name = "sdhc_ipg_clk",
975 .id = 2,
976 .parent = &ipg_clk,
977 .enable = _clk_enable,
978 .enable_reg = CCM_PCCR0,
979 .enable_shift = CCM_PCCR0_SDHC3_OFFSET,
980 .disable = _clk_disable,
984 static struct clk cspi1_clk[] = {
986 .name = "cspi_clk",
987 .id = 0,
988 .parent = &per_clk[1],
989 .secondary = &cspi1_clk[1],
990 }, {
991 .name = "cspi_ipg_clk",
992 .id = 0,
993 .parent = &ipg_clk,
994 .enable = _clk_enable,
995 .enable_reg = CCM_PCCR0,
996 .enable_shift = CCM_PCCR0_CSPI1_OFFSET,
997 .disable = _clk_disable,
1001 static struct clk cspi2_clk[] = {
1003 .name = "cspi_clk",
1004 .id = 1,
1005 .parent = &per_clk[1],
1006 .secondary = &cspi2_clk[1],
1007 }, {
1008 .name = "cspi_ipg_clk",
1009 .id = 1,
1010 .parent = &ipg_clk,
1011 .enable = _clk_enable,
1012 .enable_reg = CCM_PCCR0,
1013 .enable_shift = CCM_PCCR0_CSPI2_OFFSET,
1014 .disable = _clk_disable,
1018 static struct clk cspi3_clk[] = {
1020 .name = "cspi_clk",
1021 .id = 2,
1022 .parent = &per_clk[1],
1023 .secondary = &cspi3_clk[1],
1024 }, {
1025 .name = "cspi_ipg_clk",
1026 .id = 2,
1027 .parent = &ipg_clk,
1028 .enable = _clk_enable,
1029 .enable_reg = CCM_PCCR0,
1030 .enable_shift = CCM_PCCR0_CSPI3_OFFSET,
1031 .disable = _clk_disable,
1035 static struct clk lcdc_clk[] = {
1037 .name = "lcdc_clk",
1038 .parent = &per_clk[2],
1039 .secondary = &lcdc_clk[1],
1040 .round_rate = _clk_parent_round_rate,
1041 .set_rate = _clk_parent_set_rate,
1042 }, {
1043 .name = "lcdc_ipg_clk",
1044 .parent = &ipg_clk,
1045 .secondary = &lcdc_clk[2],
1046 .enable = _clk_enable,
1047 .enable_reg = CCM_PCCR0,
1048 .enable_shift = CCM_PCCR0_LCDC_OFFSET,
1049 .disable = _clk_disable,
1050 }, {
1051 .name = "lcdc_ahb_clk",
1052 .parent = &ahb_clk,
1053 .enable = _clk_enable,
1054 .enable_reg = CCM_PCCR1,
1055 .enable_shift = CCM_PCCR1_HCLK_LCDC_OFFSET,
1056 .disable = _clk_disable,
1060 static struct clk csi_clk[] = {
1062 .name = "csi_perclk",
1063 .parent = &per_clk[3],
1064 .secondary = &csi_clk[1],
1065 .round_rate = _clk_parent_round_rate,
1066 .set_rate = _clk_parent_set_rate,
1067 }, {
1068 .name = "csi_ahb_clk",
1069 .parent = &ahb_clk,
1070 .enable = _clk_enable,
1071 .enable_reg = CCM_PCCR1,
1072 .enable_shift = CCM_PCCR1_HCLK_CSI_OFFSET,
1073 .disable = _clk_disable,
1077 static struct clk usb_clk[] = {
1079 .name = "usb_clk",
1080 .parent = &spll_clk,
1081 .get_rate = _clk_usb_recalc,
1082 .enable = _clk_enable,
1083 .enable_reg = CCM_PCCR1,
1084 .enable_shift = CCM_PCCR1_USBOTG_OFFSET,
1085 .disable = _clk_disable,
1086 }, {
1087 .name = "usb_ahb_clk",
1088 .parent = &ahb_clk,
1089 .enable = _clk_enable,
1090 .enable_reg = CCM_PCCR1,
1091 .enable_shift = CCM_PCCR1_HCLK_USBOTG_OFFSET,
1092 .disable = _clk_disable,
1096 static struct clk ssi1_clk[] = {
1098 .name = "ssi_clk",
1099 .id = 0,
1100 .parent = &mpll_main_clk[1],
1101 .secondary = &ssi1_clk[1],
1102 .get_rate = _clk_ssi1_recalc,
1103 .enable = _clk_enable,
1104 .enable_reg = CCM_PCCR1,
1105 .enable_shift = CCM_PCCR1_SSI1_BAUD_OFFSET,
1106 .disable = _clk_disable,
1107 }, {
1108 .name = "ssi_ipg_clk",
1109 .id = 0,
1110 .parent = &ipg_clk,
1111 .enable = _clk_enable,
1112 .enable_reg = CCM_PCCR0,
1113 .enable_shift = CCM_PCCR0_SSI1_IPG_OFFSET,
1114 .disable = _clk_disable,
1118 static struct clk ssi2_clk[] = {
1120 .name = "ssi_clk",
1121 .id = 1,
1122 .parent = &mpll_main_clk[1],
1123 .secondary = &ssi2_clk[1],
1124 .get_rate = _clk_ssi2_recalc,
1125 .enable = _clk_enable,
1126 .enable_reg = CCM_PCCR1,
1127 .enable_shift = CCM_PCCR1_SSI2_BAUD_OFFSET,
1128 .disable = _clk_disable,
1129 }, {
1130 .name = "ssi_ipg_clk",
1131 .id = 1,
1132 .parent = &ipg_clk,
1133 .enable = _clk_enable,
1134 .enable_reg = CCM_PCCR0,
1135 .enable_shift = CCM_PCCR0_SSI2_IPG_OFFSET,
1136 .disable = _clk_disable,
1140 static struct clk nfc_clk = {
1141 .name = "nfc_clk",
1142 .parent = &cpu_clk,
1143 .get_rate = _clk_nfc_recalc,
1144 .enable = _clk_enable,
1145 .enable_reg = CCM_PCCR1,
1146 .enable_shift = CCM_PCCR1_NFC_BAUD_OFFSET,
1147 .disable = _clk_disable,
1150 static struct clk vpu_clk = {
1151 .name = "vpu_clk",
1152 .parent = &mpll_main_clk[1],
1153 .get_rate = _clk_vpu_recalc,
1154 .enable = _clk_vpu_enable,
1155 .disable = _clk_vpu_disable,
1158 static struct clk dma_clk = {
1159 .name = "dma_clk",
1160 .parent = &ahb_clk,
1161 .enable = _clk_dma_enable,
1162 .disable = _clk_dma_disable,
1165 static struct clk rtic_clk = {
1166 .name = "rtic_clk",
1167 .parent = &ahb_clk,
1168 .enable = _clk_rtic_enable,
1169 .disable = _clk_rtic_disable,
1172 static struct clk brom_clk = {
1173 .name = "brom_clk",
1174 .parent = &ahb_clk,
1175 .enable = _clk_enable,
1176 .enable_reg = CCM_PCCR1,
1177 .enable_shift = CCM_PCCR1_HCLK_BROM_OFFSET,
1178 .disable = _clk_disable,
1181 static struct clk emma_clk = {
1182 .name = "emma_clk",
1183 .parent = &ahb_clk,
1184 .enable = _clk_emma_enable,
1185 .disable = _clk_emma_disable,
1188 static struct clk slcdc_clk = {
1189 .name = "slcdc_clk",
1190 .parent = &ahb_clk,
1191 .enable = _clk_slcdc_enable,
1192 .disable = _clk_slcdc_disable,
1195 static struct clk fec_clk = {
1196 .name = "fec_clk",
1197 .parent = &ahb_clk,
1198 .enable = _clk_fec_enable,
1199 .disable = _clk_fec_disable,
1202 static struct clk emi_clk = {
1203 .name = "emi_clk",
1204 .parent = &ahb_clk,
1205 .enable = _clk_enable,
1206 .enable_reg = CCM_PCCR1,
1207 .enable_shift = CCM_PCCR1_HCLK_EMI_OFFSET,
1208 .disable = _clk_disable,
1211 static struct clk sahara2_clk = {
1212 .name = "sahara_clk",
1213 .parent = &ahb_clk,
1214 .enable = _clk_sahara2_enable,
1215 .disable = _clk_sahara2_disable,
1218 static struct clk ata_clk = {
1219 .name = "ata_clk",
1220 .parent = &ahb_clk,
1221 .enable = _clk_enable,
1222 .enable_reg = CCM_PCCR1,
1223 .enable_shift = CCM_PCCR1_HCLK_ATA_OFFSET,
1224 .disable = _clk_disable,
1227 static struct clk mstick1_clk = {
1228 .name = "mstick1_clk",
1229 .parent = &ipg_clk,
1230 .enable = _clk_mstick1_enable,
1231 .disable = _clk_mstick1_disable,
1234 static struct clk wdog_clk = {
1235 .name = "wdog_clk",
1236 .parent = &ipg_clk,
1237 .enable = _clk_enable,
1238 .enable_reg = CCM_PCCR1,
1239 .enable_shift = CCM_PCCR1_WDT_OFFSET,
1240 .disable = _clk_disable,
1243 static struct clk gpio_clk = {
1244 .name = "gpio_clk",
1245 .parent = &ipg_clk,
1246 .enable = _clk_enable,
1247 .enable_reg = CCM_PCCR1,
1248 .enable_shift = CCM_PCCR0_GPIO_OFFSET,
1249 .disable = _clk_disable,
1252 static struct clk i2c_clk[] = {
1254 .name = "i2c_clk",
1255 .id = 0,
1256 .parent = &ipg_clk,
1257 .enable = _clk_enable,
1258 .enable_reg = CCM_PCCR0,
1259 .enable_shift = CCM_PCCR0_I2C1_OFFSET,
1260 .disable = _clk_disable,
1261 }, {
1262 .name = "i2c_clk",
1263 .id = 1,
1264 .parent = &ipg_clk,
1265 .enable = _clk_enable,
1266 .enable_reg = CCM_PCCR0,
1267 .enable_shift = CCM_PCCR0_I2C2_OFFSET,
1268 .disable = _clk_disable,
1272 static struct clk iim_clk = {
1273 .name = "iim_clk",
1274 .parent = &ipg_clk,
1275 .enable = _clk_enable,
1276 .enable_reg = CCM_PCCR0,
1277 .enable_shift = CCM_PCCR0_IIM_OFFSET,
1278 .disable = _clk_disable,
1281 static struct clk kpp_clk = {
1282 .name = "kpp_clk",
1283 .parent = &ipg_clk,
1284 .enable = _clk_enable,
1285 .enable_reg = CCM_PCCR0,
1286 .enable_shift = CCM_PCCR0_KPP_OFFSET,
1287 .disable = _clk_disable,
1290 static struct clk owire_clk = {
1291 .name = "owire_clk",
1292 .parent = &ipg_clk,
1293 .enable = _clk_enable,
1294 .enable_reg = CCM_PCCR0,
1295 .enable_shift = CCM_PCCR0_OWIRE_OFFSET,
1296 .disable = _clk_disable,
1299 static struct clk rtc_clk = {
1300 .name = "rtc_clk",
1301 .parent = &ipg_clk,
1302 .enable = _clk_enable,
1303 .enable_reg = CCM_PCCR0,
1304 .enable_shift = CCM_PCCR0_RTC_OFFSET,
1305 .disable = _clk_disable,
1308 static struct clk scc_clk = {
1309 .name = "scc_clk",
1310 .parent = &ipg_clk,
1311 .enable = _clk_enable,
1312 .enable_reg = CCM_PCCR0,
1313 .enable_shift = CCM_PCCR0_SCC_OFFSET,
1314 .disable = _clk_disable,
1317 static unsigned long _clk_clko_round_rate(struct clk *clk, unsigned long rate)
1319 u32 div;
1320 unsigned long parent_rate;
1322 parent_rate = clk_get_rate(clk->parent);
1323 div = parent_rate / rate;
1324 if (parent_rate % rate)
1325 div++;
1327 if (div > 8)
1328 div = 8;
1330 return parent_rate / div;
1333 static int _clk_clko_set_rate(struct clk *clk, unsigned long rate)
1335 u32 reg;
1336 u32 div;
1337 unsigned long parent_rate;
1339 parent_rate = clk_get_rate(clk->parent);
1341 div = parent_rate / rate;
1343 if (div > 8 || div < 1 || ((parent_rate / div) != rate))
1344 return -EINVAL;
1345 div--;
1347 reg = __raw_readl(CCM_PCDR0) & ~CCM_PCDR0_CLKODIV_MASK;
1348 reg |= div << CCM_PCDR0_CLKODIV_OFFSET;
1349 __raw_writel(reg, CCM_PCDR0);
1351 return 0;
1354 static unsigned long _clk_clko_recalc(struct clk *clk)
1356 u32 div;
1357 unsigned long parent_rate;
1359 parent_rate = clk_get_rate(clk->parent);
1361 div = __raw_readl(CCM_PCDR0) & CCM_PCDR0_CLKODIV_MASK >>
1362 CCM_PCDR0_CLKODIV_OFFSET;
1363 div++;
1365 return parent_rate / div;
1368 static int _clk_clko_set_parent(struct clk *clk, struct clk *parent)
1370 u32 reg;
1372 reg = __raw_readl(CCM_CCSR) & ~CCM_CCSR_CLKOSEL_MASK;
1374 if (parent == &ckil_clk)
1375 reg |= 0 << CCM_CCSR_CLKOSEL_OFFSET;
1376 else if (parent == &ckih_clk)
1377 reg |= 2 << CCM_CCSR_CLKOSEL_OFFSET;
1378 else if (parent == mpll_clk.parent)
1379 reg |= 3 << CCM_CCSR_CLKOSEL_OFFSET;
1380 else if (parent == spll_clk.parent)
1381 reg |= 4 << CCM_CCSR_CLKOSEL_OFFSET;
1382 else if (parent == &mpll_clk)
1383 reg |= 5 << CCM_CCSR_CLKOSEL_OFFSET;
1384 else if (parent == &spll_clk)
1385 reg |= 6 << CCM_CCSR_CLKOSEL_OFFSET;
1386 else if (parent == &cpu_clk)
1387 reg |= 7 << CCM_CCSR_CLKOSEL_OFFSET;
1388 else if (parent == &ahb_clk)
1389 reg |= 8 << CCM_CCSR_CLKOSEL_OFFSET;
1390 else if (parent == &ipg_clk)
1391 reg |= 9 << CCM_CCSR_CLKOSEL_OFFSET;
1392 else if (parent == &per_clk[0])
1393 reg |= 0xA << CCM_CCSR_CLKOSEL_OFFSET;
1394 else if (parent == &per_clk[1])
1395 reg |= 0xB << CCM_CCSR_CLKOSEL_OFFSET;
1396 else if (parent == &per_clk[2])
1397 reg |= 0xC << CCM_CCSR_CLKOSEL_OFFSET;
1398 else if (parent == &per_clk[3])
1399 reg |= 0xD << CCM_CCSR_CLKOSEL_OFFSET;
1400 else if (parent == &ssi1_clk[0])
1401 reg |= 0xE << CCM_CCSR_CLKOSEL_OFFSET;
1402 else if (parent == &ssi2_clk[0])
1403 reg |= 0xF << CCM_CCSR_CLKOSEL_OFFSET;
1404 else if (parent == &nfc_clk)
1405 reg |= 0x10 << CCM_CCSR_CLKOSEL_OFFSET;
1406 else if (parent == &mstick1_clk)
1407 reg |= 0x11 << CCM_CCSR_CLKOSEL_OFFSET;
1408 else if (parent == &vpu_clk)
1409 reg |= 0x12 << CCM_CCSR_CLKOSEL_OFFSET;
1410 else if (parent == &usb_clk[0])
1411 reg |= 0x15 << CCM_CCSR_CLKOSEL_OFFSET;
1412 else
1413 return -EINVAL;
1415 __raw_writel(reg, CCM_CCSR);
1417 return 0;
1420 static int _clk_clko_enable(struct clk *clk)
1422 u32 reg;
1424 reg = __raw_readl(CCM_PCDR0) | CCM_PCDR0_CLKO_EN;
1425 __raw_writel(reg, CCM_PCDR0);
1427 return 0;
1430 static void _clk_clko_disable(struct clk *clk)
1432 u32 reg;
1434 reg = __raw_readl(CCM_PCDR0) & ~CCM_PCDR0_CLKO_EN;
1435 __raw_writel(reg, CCM_PCDR0);
1438 static struct clk clko_clk = {
1439 .name = "clko_clk",
1440 .get_rate = _clk_clko_recalc,
1441 .set_rate = _clk_clko_set_rate,
1442 .round_rate = _clk_clko_round_rate,
1443 .set_parent = _clk_clko_set_parent,
1444 .enable = _clk_clko_enable,
1445 .disable = _clk_clko_disable,
1448 static struct clk *mxc_clks[] = {
1449 &ckih_clk,
1450 &ckil_clk,
1451 &mpll_clk,
1452 &mpll_main_clk[0],
1453 &mpll_main_clk[1],
1454 &spll_clk,
1455 &cpu_clk,
1456 &ahb_clk,
1457 &ipg_clk,
1458 &per_clk[0],
1459 &per_clk[1],
1460 &per_clk[2],
1461 &per_clk[3],
1462 &clko_clk,
1463 &uart1_clk[0],
1464 &uart1_clk[1],
1465 &uart2_clk[0],
1466 &uart2_clk[1],
1467 &uart3_clk[0],
1468 &uart3_clk[1],
1469 &uart4_clk[0],
1470 &uart4_clk[1],
1471 &uart5_clk[0],
1472 &uart5_clk[1],
1473 &uart6_clk[0],
1474 &uart6_clk[1],
1475 &gpt1_clk[0],
1476 &gpt1_clk[1],
1477 &gpt2_clk[0],
1478 &gpt2_clk[1],
1479 &gpt3_clk[0],
1480 &gpt3_clk[1],
1481 &gpt4_clk[0],
1482 &gpt4_clk[1],
1483 &gpt5_clk[0],
1484 &gpt5_clk[1],
1485 &gpt6_clk[0],
1486 &gpt6_clk[1],
1487 &pwm_clk[0],
1488 &pwm_clk[1],
1489 &sdhc1_clk[0],
1490 &sdhc1_clk[1],
1491 &sdhc2_clk[0],
1492 &sdhc2_clk[1],
1493 &sdhc3_clk[0],
1494 &sdhc3_clk[1],
1495 &cspi1_clk[0],
1496 &cspi1_clk[1],
1497 &cspi2_clk[0],
1498 &cspi2_clk[1],
1499 &cspi3_clk[0],
1500 &cspi3_clk[1],
1501 &lcdc_clk[0],
1502 &lcdc_clk[1],
1503 &lcdc_clk[2],
1504 &csi_clk[0],
1505 &csi_clk[1],
1506 &usb_clk[0],
1507 &usb_clk[1],
1508 &ssi1_clk[0],
1509 &ssi1_clk[1],
1510 &ssi2_clk[0],
1511 &ssi2_clk[1],
1512 &nfc_clk,
1513 &vpu_clk,
1514 &dma_clk,
1515 &rtic_clk,
1516 &brom_clk,
1517 &emma_clk,
1518 &slcdc_clk,
1519 &fec_clk,
1520 &emi_clk,
1521 &sahara2_clk,
1522 &ata_clk,
1523 &mstick1_clk,
1524 &wdog_clk,
1525 &gpio_clk,
1526 &i2c_clk[0],
1527 &i2c_clk[1],
1528 &iim_clk,
1529 &kpp_clk,
1530 &owire_clk,
1531 &rtc_clk,
1532 &scc_clk,
1535 void __init change_external_low_reference(unsigned long new_ref)
1537 external_low_reference = new_ref;
1540 unsigned long __init clk_early_get_timer_rate(void)
1542 return clk_get_rate(&per_clk[0]);
1545 static void __init probe_mxc_clocks(void)
1547 int i;
1549 if (mx27_revision() >= CHIP_REV_2_0) {
1550 if (CSCR() & 0x8000)
1551 cpu_clk.parent = &mpll_main_clk[0];
1553 if (!(CSCR() & 0x00800000))
1554 ssi2_clk[0].parent = &spll_clk;
1556 if (!(CSCR() & 0x00400000))
1557 ssi1_clk[0].parent = &spll_clk;
1559 if (!(CSCR() & 0x00200000))
1560 vpu_clk.parent = &spll_clk;
1561 } else {
1562 cpu_clk.parent = &mpll_clk;
1563 cpu_clk.set_parent = NULL;
1564 cpu_clk.round_rate = NULL;
1565 cpu_clk.set_rate = NULL;
1566 ahb_clk.parent = &mpll_clk;
1568 for (i = 0; i < sizeof(per_clk) / sizeof(per_clk[0]); i++)
1569 per_clk[i].parent = &mpll_clk;
1571 ssi1_clk[0].parent = &mpll_clk;
1572 ssi2_clk[0].parent = &mpll_clk;
1574 vpu_clk.parent = &mpll_clk;
1579 * must be called very early to get information about the
1580 * available clock rate when the timer framework starts
1582 int __init mxc_clocks_init(unsigned long fref)
1584 u32 cscr;
1585 struct clk **clkp;
1587 external_high_reference = fref;
1589 /* detect clock reference for both system PLL */
1590 cscr = CSCR();
1591 if (cscr & CCM_CSCR_MCU)
1592 mpll_clk.parent = &ckih_clk;
1593 else
1594 mpll_clk.parent = &ckil_clk;
1596 if (cscr & CCM_CSCR_SP)
1597 spll_clk.parent = &ckih_clk;
1598 else
1599 spll_clk.parent = &ckil_clk;
1601 probe_mxc_clocks();
1603 per_clk[0].enable(&per_clk[0]);
1604 gpt1_clk[1].enable(&gpt1_clk[1]);
1606 for (clkp = mxc_clks; clkp < mxc_clks + ARRAY_SIZE(mxc_clks); clkp++)
1607 clk_register(*clkp);
1609 /* Turn off all possible clocks */
1610 __raw_writel(CCM_PCCR0_GPT1_MASK, CCM_PCCR0);
1611 __raw_writel(CCM_PCCR1_PERCLK1_MASK | CCM_PCCR1_HCLK_EMI_MASK,
1612 CCM_PCCR1);
1613 spll_clk.disable(&spll_clk);
1615 /* This will propagate to all children and init all the clock rates */
1617 clk_enable(&emi_clk);
1618 clk_enable(&gpio_clk);
1619 clk_enable(&iim_clk);
1620 clk_enable(&gpt1_clk[0]);
1621 #ifdef CONFIG_DEBUG_LL_CONSOLE
1622 clk_enable(&uart1_clk[0]);
1623 #endif
1624 return 0;