Merge commit 'v2.6.27-rc7' into x86/microcode
[linux-2.6] / arch / arm / mach-mx2 / clock_imx27.c
1 /*
2  * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
3  * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
4  *
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.
13  *
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.
18  */
19
20 #include <linux/clk.h>
21 #include <linux/io.h>
22 #include <linux/module.h>
23 #include <linux/spinlock.h>
24
25 #include <mach/clock.h>
26 #include <mach/common.h>
27 #include <asm/div64.h>
28
29 #include "crm_regs.h"
30
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;
35
36 static int _clk_enable(struct clk *clk)
37 {
38         unsigned long reg;
39
40         reg = __raw_readl(clk->enable_reg);
41         reg |= 1 << clk->enable_shift;
42         __raw_writel(reg, clk->enable_reg);
43
44         return 0;
45 }
46
47 static void _clk_disable(struct clk *clk)
48 {
49         unsigned long reg;
50
51         reg = __raw_readl(clk->enable_reg);
52         reg &= ~(1 << clk->enable_shift);
53         __raw_writel(reg, clk->enable_reg);
54 }
55
56 static int _clk_spll_enable(struct clk *clk)
57 {
58         unsigned long reg;
59
60         reg = __raw_readl(CCM_CSCR);
61         reg |= CCM_CSCR_SPEN;
62         __raw_writel(reg, CCM_CSCR);
63
64         while ((__raw_readl(CCM_SPCTL1) & CCM_SPCTL1_LF) == 0)
65                 ;
66
67         return 0;
68 }
69
70 static void _clk_spll_disable(struct clk *clk)
71 {
72         unsigned long reg;
73
74         reg = __raw_readl(CCM_CSCR);
75         reg &= ~CCM_CSCR_SPEN;
76         __raw_writel(reg, CCM_CSCR);
77 }
78
79 static void _clk_pccr01_enable(unsigned long mask0, unsigned long mask1)
80 {
81         unsigned long reg;
82
83         reg = __raw_readl(CCM_PCCR0);
84         reg |= mask0;
85         __raw_writel(reg, CCM_PCCR0);
86
87         reg = __raw_readl(CCM_PCCR1);
88         reg |= mask1;
89         __raw_writel(reg, CCM_PCCR1);
90
91 }
92
93 static void _clk_pccr01_disable(unsigned long mask0, unsigned long mask1)
94 {
95         unsigned long reg;
96
97         reg = __raw_readl(CCM_PCCR0);
98         reg &= ~mask0;
99         __raw_writel(reg, CCM_PCCR0);
100
101         reg = __raw_readl(CCM_PCCR1);
102         reg &= ~mask1;
103         __raw_writel(reg, CCM_PCCR1);
104 }
105
106 static void _clk_pccr10_enable(unsigned long mask1, unsigned long mask0)
107 {
108         unsigned long reg;
109
110         reg = __raw_readl(CCM_PCCR1);
111         reg |= mask1;
112         __raw_writel(reg, CCM_PCCR1);
113
114         reg = __raw_readl(CCM_PCCR0);
115         reg |= mask0;
116         __raw_writel(reg, CCM_PCCR0);
117 }
118
119 static void _clk_pccr10_disable(unsigned long mask1, unsigned long mask0)
120 {
121         unsigned long reg;
122
123         reg = __raw_readl(CCM_PCCR1);
124         reg &= ~mask1;
125         __raw_writel(reg, CCM_PCCR1);
126
127         reg = __raw_readl(CCM_PCCR0);
128         reg &= ~mask0;
129         __raw_writel(reg, CCM_PCCR0);
130 }
131
132 static int _clk_dma_enable(struct clk *clk)
133 {
134         _clk_pccr01_enable(CCM_PCCR0_DMA_MASK, CCM_PCCR1_HCLK_DMA_MASK);
135
136         return 0;
137 }
138
139 static void _clk_dma_disable(struct clk *clk)
140 {
141         _clk_pccr01_disable(CCM_PCCR0_DMA_MASK, CCM_PCCR1_HCLK_DMA_MASK);
142 }
143
144 static int _clk_rtic_enable(struct clk *clk)
145 {
146         _clk_pccr01_enable(CCM_PCCR0_RTIC_MASK, CCM_PCCR1_HCLK_RTIC_MASK);
147
148         return 0;
149 }
150
151 static void _clk_rtic_disable(struct clk *clk)
152 {
153         _clk_pccr01_disable(CCM_PCCR0_RTIC_MASK, CCM_PCCR1_HCLK_RTIC_MASK);
154 }
155
156 static int _clk_emma_enable(struct clk *clk)
157 {
158         _clk_pccr01_enable(CCM_PCCR0_EMMA_MASK, CCM_PCCR1_HCLK_EMMA_MASK);
159
160         return 0;
161 }
162
163 static void _clk_emma_disable(struct clk *clk)
164 {
165         _clk_pccr01_disable(CCM_PCCR0_EMMA_MASK, CCM_PCCR1_HCLK_EMMA_MASK);
166 }
167
168 static int _clk_slcdc_enable(struct clk *clk)
169 {
170         _clk_pccr01_enable(CCM_PCCR0_SLCDC_MASK, CCM_PCCR1_HCLK_SLCDC_MASK);
171
172         return 0;
173 }
174
175 static void _clk_slcdc_disable(struct clk *clk)
176 {
177         _clk_pccr01_disable(CCM_PCCR0_SLCDC_MASK, CCM_PCCR1_HCLK_SLCDC_MASK);
178 }
179
180 static int _clk_fec_enable(struct clk *clk)
181 {
182         _clk_pccr01_enable(CCM_PCCR0_FEC_MASK, CCM_PCCR1_HCLK_FEC_MASK);
183
184         return 0;
185 }
186
187 static void _clk_fec_disable(struct clk *clk)
188 {
189         _clk_pccr01_disable(CCM_PCCR0_FEC_MASK, CCM_PCCR1_HCLK_FEC_MASK);
190 }
191
192 static int _clk_vpu_enable(struct clk *clk)
193 {
194         unsigned long reg;
195
196         reg = __raw_readl(CCM_PCCR1);
197         reg |= CCM_PCCR1_VPU_BAUD_MASK | CCM_PCCR1_HCLK_VPU_MASK;
198         __raw_writel(reg, CCM_PCCR1);
199
200         return 0;
201 }
202
203 static void _clk_vpu_disable(struct clk *clk)
204 {
205         unsigned long reg;
206
207         reg = __raw_readl(CCM_PCCR1);
208         reg &= ~(CCM_PCCR1_VPU_BAUD_MASK | CCM_PCCR1_HCLK_VPU_MASK);
209         __raw_writel(reg, CCM_PCCR1);
210 }
211
212 static int _clk_sahara2_enable(struct clk *clk)
213 {
214         _clk_pccr01_enable(CCM_PCCR0_SAHARA_MASK, CCM_PCCR1_HCLK_SAHARA_MASK);
215
216         return 0;
217 }
218
219 static void _clk_sahara2_disable(struct clk *clk)
220 {
221         _clk_pccr01_disable(CCM_PCCR0_SAHARA_MASK, CCM_PCCR1_HCLK_SAHARA_MASK);
222 }
223
224 static int _clk_mstick1_enable(struct clk *clk)
225 {
226         _clk_pccr10_enable(CCM_PCCR1_MSHC_BAUD_MASK, CCM_PCCR0_MSHC_MASK);
227
228         return 0;
229 }
230
231 static void _clk_mstick1_disable(struct clk *clk)
232 {
233         _clk_pccr10_disable(CCM_PCCR1_MSHC_BAUD_MASK, CCM_PCCR0_MSHC_MASK);
234 }
235
236 #define CSCR() (__raw_readl(CCM_CSCR))
237 #define PCDR0() (__raw_readl(CCM_PCDR0))
238 #define PCDR1() (__raw_readl(CCM_PCDR1))
239
240 static int _clk_cpu_set_parent(struct clk *clk, struct clk *parent)
241 {
242         int cscr = CSCR();
243
244         if (clk->parent == parent)
245                 return 0;
246
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;
255                 }
256                 __raw_writel(cscr, CCM_CSCR);
257         } else
258                 return -ENODEV;
259
260         clk->parent = parent;
261         return 0;
262 }
263
264 static unsigned long _clk_cpu_round_rate(struct clk *clk, unsigned long rate)
265 {
266         int div;
267         unsigned long parent_rate;
268
269         parent_rate = clk_get_rate(clk->parent);
270
271         div = parent_rate / rate;
272         if (parent_rate % rate)
273                 div++;
274
275         if (div > 4)
276                 div = 4;
277
278         return parent_rate / div;
279 }
280
281 static int _clk_cpu_set_rate(struct clk *clk, unsigned long rate)
282 {
283         unsigned int div;
284         uint32_t reg;
285         unsigned long parent_rate;
286
287         parent_rate = clk_get_rate(clk->parent);
288
289         div = parent_rate / rate;
290
291         if (div > 4 || div < 1 || ((parent_rate / div) != rate))
292                 return -EINVAL;
293
294         div--;
295
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");
304         }
305
306         return 0;
307 }
308
309 static unsigned long _clk_perclkx_round_rate(struct clk *clk,
310                                              unsigned long rate)
311 {
312         u32 div;
313         unsigned long parent_rate;
314
315         parent_rate = clk_get_rate(clk->parent);
316
317         div = parent_rate / rate;
318         if (parent_rate % rate)
319                 div++;
320
321         if (div > 64)
322                 div = 64;
323
324         return parent_rate / div;
325 }
326
327 static int _clk_perclkx_set_rate(struct clk *clk, unsigned long rate)
328 {
329         u32 reg;
330         u32 div;
331         unsigned long parent_rate;
332
333         parent_rate = clk_get_rate(clk->parent);
334
335         if (clk->id < 0 || clk->id > 3)
336                 return -EINVAL;
337
338         div = parent_rate / rate;
339         if (div > 64 || div < 1 || ((parent_rate / div) != rate))
340                 return -EINVAL;
341         div--;
342
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);
348
349         return 0;
350 }
351
352 static unsigned long _clk_usb_recalc(struct clk *clk)
353 {
354         unsigned long usb_pdf;
355         unsigned long parent_rate;
356
357         parent_rate = clk_get_rate(clk->parent);
358
359         usb_pdf = (CSCR() & CCM_CSCR_USB_MASK) >> CCM_CSCR_USB_OFFSET;
360
361         return parent_rate / (usb_pdf + 1U);
362 }
363
364 static unsigned long _clk_ssi1_recalc(struct clk *clk)
365 {
366         unsigned long ssi1_pdf;
367         unsigned long parent_rate;
368
369         parent_rate = clk_get_rate(clk->parent);
370
371         ssi1_pdf = (PCDR0() & CCM_PCDR0_SSI1BAUDDIV_MASK) >>
372                                         CCM_PCDR0_SSI1BAUDDIV_OFFSET;
373
374         if (mx27_revision() >= CHIP_REV_2_0)
375                 ssi1_pdf += 4;
376         else
377                 ssi1_pdf = (ssi1_pdf < 2) ? 124UL : ssi1_pdf;
378
379         return 2UL * parent_rate / ssi1_pdf;
380 }
381
382 static unsigned long _clk_ssi2_recalc(struct clk *clk)
383 {
384         unsigned long ssi2_pdf;
385         unsigned long parent_rate;
386
387         parent_rate = clk_get_rate(clk->parent);
388
389         ssi2_pdf = (PCDR0() & CCM_PCDR0_SSI2BAUDDIV_MASK) >>
390             CCM_PCDR0_SSI2BAUDDIV_OFFSET;
391
392         if (mx27_revision() >= CHIP_REV_2_0)
393                 ssi2_pdf += 4;
394         else
395                 ssi2_pdf = (ssi2_pdf < 2) ? 124UL : ssi2_pdf;
396
397         return 2UL * parent_rate / ssi2_pdf;
398 }
399
400 static unsigned long _clk_nfc_recalc(struct clk *clk)
401 {
402         unsigned long nfc_pdf;
403         unsigned long parent_rate;
404
405         parent_rate = clk_get_rate(clk->parent);
406
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;
415         }
416
417         return parent_rate / (nfc_pdf + 1);
418 }
419
420 static unsigned long _clk_vpu_recalc(struct clk *clk)
421 {
422         unsigned long vpu_pdf;
423         unsigned long parent_rate;
424
425         parent_rate = clk_get_rate(clk->parent);
426
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;
437         }
438         return 2UL * parent_rate / vpu_pdf;
439 }
440
441 static unsigned long _clk_parent_round_rate(struct clk *clk, unsigned long rate)
442 {
443         return clk->parent->round_rate(clk->parent, rate);
444 }
445
446 static int _clk_parent_set_rate(struct clk *clk, unsigned long rate)
447 {
448         return clk->parent->set_rate(clk->parent, rate);
449 }
450
451 /* in Hz */
452 static unsigned long external_high_reference = 26000000;
453
454 static unsigned long get_high_reference_clock_rate(struct clk *clk)
455 {
456         return external_high_reference;
457 }
458
459 /*
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()
463  */
464 static struct clk ckih_clk = {
465         .name = "ckih",
466         .get_rate = get_high_reference_clock_rate,
467 };
468
469 /* in Hz */
470 static unsigned long external_low_reference = 32768;
471
472 static unsigned long get_low_reference_clock_rate(struct clk *clk)
473 {
474         return external_low_reference;
475 }
476
477 /*
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()
481  */
482 static struct clk ckil_clk = {
483         .name = "ckil",
484         .get_rate = get_low_reference_clock_rate,
485 };
486
487 static unsigned long get_mpll_clk(struct clk *clk)
488 {
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;
493
494         ref_clk = clk_get_rate(clk->parent);
495
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;
501
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);
507
508         return (unsigned long)temp;
509 }
510
511 static struct clk mpll_clk = {
512         .name = "mpll",
513         .parent = &ckih_clk,
514         .get_rate = get_mpll_clk,
515 };
516
517 static unsigned long _clk_mpll_main_get_rate(struct clk *clk)
518 {
519         unsigned long parent_rate;
520
521         parent_rate = clk_get_rate(clk->parent);
522
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
526          */
527
528         if (mx27_revision() >= CHIP_REV_2_0 && clk->id == 1)
529                 return 2UL * parent_rate / 3UL;
530
531         return parent_rate;
532 }
533
534 static struct clk mpll_main_clk[] = {
535         {
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
538                  */
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
546                  */
547                 .name = "mpll_main",
548                 .id = 1,
549                 .parent = &mpll_clk,
550                 .get_rate = _clk_mpll_main_get_rate
551         }
552 };
553
554 static unsigned long get_spll_clk(struct clk *clk)
555 {
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;
560
561         ref_clk = clk_get_rate(clk->parent);
562
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);
567
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;
572
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);
578
579         return (unsigned long)temp;
580 }
581
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,
588 };
589
590 static unsigned long get_cpu_clk(struct clk *clk)
591 {
592         u32 div;
593         unsigned long rate;
594
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;
599
600         rate = clk_get_rate(clk->parent);
601         return rate / (div + 1);
602 }
603
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,
611 };
612
613 static unsigned long get_ahb_clk(struct clk *clk)
614 {
615         unsigned long rate;
616         unsigned long bclk_pdf;
617
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;
624
625         rate = clk_get_rate(clk->parent);
626         return rate / (bclk_pdf + 1);
627 }
628
629 static struct clk ahb_clk = {
630         .name = "ahb_clk",
631         .parent = &mpll_main_clk[1],
632         .get_rate = get_ahb_clk,
633 };
634
635 static unsigned long get_ipg_clk(struct clk *clk)
636 {
637         unsigned long rate;
638         unsigned long ipg_pdf;
639
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;
644
645         rate = clk_get_rate(clk->parent);
646         return rate / (ipg_pdf + 1);
647 }
648
649 static struct clk ipg_clk = {
650         .name = "ipg_clk",
651         .parent = &ahb_clk,
652         .get_rate = get_ipg_clk,
653 };
654
655 static unsigned long _clk_perclkx_recalc(struct clk *clk)
656 {
657         unsigned long perclk_pdf;
658         unsigned long parent_rate;
659
660         parent_rate = clk_get_rate(clk->parent);
661
662         if (clk->id < 0 || clk->id > 3)
663                 return 0;
664
665         perclk_pdf = (PCDR1() >> (clk->id << 3)) & CCM_PCDR1_PERDIV1_MASK;
666
667         return parent_rate / (perclk_pdf + 1);
668 }
669
670 static struct clk per_clk[] = {
671         {
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,
711         },
712 };
713
714 struct clk uart1_clk[] = {
715         {
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,
728         },
729 };
730
731 struct clk uart2_clk[] = {
732         {
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,
745         },
746 };
747
748 struct clk uart3_clk[] = {
749         {
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,
762         },
763 };
764
765 struct clk uart4_clk[] = {
766         {
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,
779         },
780 };
781
782 struct clk uart5_clk[] = {
783         {
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,
796         },
797 };
798
799 struct clk uart6_clk[] = {
800         {
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,
813         },
814 };
815
816 static struct clk gpt1_clk[] = {
817         {
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,
830         },
831 };
832
833 static struct clk gpt2_clk[] = {
834         {
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,
847         },
848 };
849
850 static struct clk gpt3_clk[] = {
851         {
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,
864         },
865 };
866
867 static struct clk gpt4_clk[] = {
868         {
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,
881         },
882 };
883
884 static struct clk gpt5_clk[] = {
885         {
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,
898         },
899 };
900
901 static struct clk gpt6_clk[] = {
902         {
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,
915         },
916 };
917
918 static struct clk pwm_clk[] = {
919         {
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,
930         },
931 };
932
933 static struct clk sdhc1_clk[] = {
934         {
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,
947         },
948 };
949
950 static struct clk sdhc2_clk[] = {
951         {
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,
964         },
965 };
966
967 static struct clk sdhc3_clk[] = {
968         {
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,
981         },
982 };
983
984 static struct clk cspi1_clk[] = {
985         {
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,
998         },
999 };
1000
1001 static struct clk cspi2_clk[] = {
1002         {
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,
1015         },
1016 };
1017
1018 static struct clk cspi3_clk[] = {
1019         {
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,
1032         },
1033 };
1034
1035 static struct clk lcdc_clk[] = {
1036         {
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,
1057         },
1058 };
1059
1060 static struct clk csi_clk[] = {
1061         {
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,
1074         },
1075 };
1076
1077 static struct clk usb_clk[] = {
1078         {
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,
1093         }
1094 };
1095
1096 static struct clk ssi1_clk[] = {
1097         {
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,
1115         },
1116 };
1117
1118 static struct clk ssi2_clk[] = {
1119         {
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,
1137         },
1138 };
1139
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,
1148 };
1149
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,
1156 };
1157
1158 static struct clk dma_clk = {
1159         .name = "dma_clk",
1160         .parent = &ahb_clk,
1161         .enable = _clk_dma_enable,
1162         .disable = _clk_dma_disable,
1163 };
1164
1165 static struct clk rtic_clk = {
1166         .name = "rtic_clk",
1167         .parent = &ahb_clk,
1168         .enable = _clk_rtic_enable,
1169         .disable = _clk_rtic_disable,
1170 };
1171
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,
1179 };
1180
1181 static struct clk emma_clk = {
1182         .name = "emma_clk",
1183         .parent = &ahb_clk,
1184         .enable = _clk_emma_enable,
1185         .disable = _clk_emma_disable,
1186 };
1187
1188 static struct clk slcdc_clk = {
1189         .name = "slcdc_clk",
1190         .parent = &ahb_clk,
1191         .enable = _clk_slcdc_enable,
1192         .disable = _clk_slcdc_disable,
1193 };
1194
1195 static struct clk fec_clk = {
1196         .name = "fec_clk",
1197         .parent = &ahb_clk,
1198         .enable = _clk_fec_enable,
1199         .disable = _clk_fec_disable,
1200 };
1201
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,
1209 };
1210
1211 static struct clk sahara2_clk = {
1212         .name = "sahara_clk",
1213         .parent = &ahb_clk,
1214         .enable = _clk_sahara2_enable,
1215         .disable = _clk_sahara2_disable,
1216 };
1217
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,
1225 };
1226
1227 static struct clk mstick1_clk = {
1228         .name = "mstick1_clk",
1229         .parent = &ipg_clk,
1230         .enable = _clk_mstick1_enable,
1231         .disable = _clk_mstick1_disable,
1232 };
1233
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,
1241 };
1242
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,
1250 };
1251
1252 static struct clk i2c_clk[] = {
1253         {
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,
1269         },
1270 };
1271
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,
1279 };
1280
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,
1288 };
1289
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,
1297 };
1298
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,
1306 };
1307
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,
1315 };
1316
1317 static unsigned long _clk_clko_round_rate(struct clk *clk, unsigned long rate)
1318 {
1319         u32 div;
1320         unsigned long parent_rate;
1321
1322         parent_rate = clk_get_rate(clk->parent);
1323         div = parent_rate / rate;
1324         if (parent_rate % rate)
1325                 div++;
1326
1327         if (div > 8)
1328                 div = 8;
1329
1330         return parent_rate / div;
1331 }
1332
1333 static int _clk_clko_set_rate(struct clk *clk, unsigned long rate)
1334 {
1335         u32 reg;
1336         u32 div;
1337         unsigned long parent_rate;
1338
1339         parent_rate = clk_get_rate(clk->parent);
1340
1341         div = parent_rate / rate;
1342
1343         if (div > 8 || div < 1 || ((parent_rate / div) != rate))
1344                 return -EINVAL;
1345         div--;
1346
1347         reg = __raw_readl(CCM_PCDR0) & ~CCM_PCDR0_CLKODIV_MASK;
1348         reg |= div << CCM_PCDR0_CLKODIV_OFFSET;
1349         __raw_writel(reg, CCM_PCDR0);
1350
1351         return 0;
1352 }
1353
1354 static unsigned long _clk_clko_recalc(struct clk *clk)
1355 {
1356         u32 div;
1357         unsigned long parent_rate;
1358
1359         parent_rate = clk_get_rate(clk->parent);
1360
1361         div = __raw_readl(CCM_PCDR0) & CCM_PCDR0_CLKODIV_MASK >>
1362                 CCM_PCDR0_CLKODIV_OFFSET;
1363         div++;
1364
1365         return parent_rate / div;
1366 }
1367
1368 static int _clk_clko_set_parent(struct clk *clk, struct clk *parent)
1369 {
1370         u32 reg;
1371
1372         reg = __raw_readl(CCM_CCSR) & ~CCM_CCSR_CLKOSEL_MASK;
1373
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;
1414
1415         __raw_writel(reg, CCM_CCSR);
1416
1417         return 0;
1418 }
1419
1420 static int _clk_clko_enable(struct clk *clk)
1421 {
1422         u32 reg;
1423
1424         reg = __raw_readl(CCM_PCDR0) | CCM_PCDR0_CLKO_EN;
1425         __raw_writel(reg, CCM_PCDR0);
1426
1427         return 0;
1428 }
1429
1430 static void _clk_clko_disable(struct clk *clk)
1431 {
1432         u32 reg;
1433
1434         reg = __raw_readl(CCM_PCDR0) & ~CCM_PCDR0_CLKO_EN;
1435         __raw_writel(reg, CCM_PCDR0);
1436 }
1437
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,
1446 };
1447
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,
1533 };
1534
1535 void __init change_external_low_reference(unsigned long new_ref)
1536 {
1537         external_low_reference = new_ref;
1538 }
1539
1540 unsigned long __init clk_early_get_timer_rate(void)
1541 {
1542         return clk_get_rate(&per_clk[0]);
1543 }
1544
1545 static void __init probe_mxc_clocks(void)
1546 {
1547         int i;
1548
1549         if (mx27_revision() >= CHIP_REV_2_0) {
1550                 if (CSCR() & 0x8000)
1551                         cpu_clk.parent = &mpll_main_clk[0];
1552
1553                 if (!(CSCR() & 0x00800000))
1554                         ssi2_clk[0].parent = &spll_clk;
1555
1556                 if (!(CSCR() & 0x00400000))
1557                         ssi1_clk[0].parent = &spll_clk;
1558
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;
1567
1568                 for (i = 0; i < sizeof(per_clk) / sizeof(per_clk[0]); i++)
1569                         per_clk[i].parent = &mpll_clk;
1570
1571                 ssi1_clk[0].parent = &mpll_clk;
1572                 ssi2_clk[0].parent = &mpll_clk;
1573
1574                 vpu_clk.parent = &mpll_clk;
1575         }
1576 }
1577
1578 /*
1579  * must be called very early to get information about the
1580  * available clock rate when the timer framework starts
1581  */
1582 int __init mxc_clocks_init(unsigned long fref)
1583 {
1584         u32 cscr;
1585         struct clk **clkp;
1586
1587         external_high_reference = fref;
1588
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;
1595
1596         if (cscr & CCM_CSCR_SP)
1597                 spll_clk.parent = &ckih_clk;
1598         else
1599                 spll_clk.parent = &ckil_clk;
1600
1601         probe_mxc_clocks();
1602
1603         per_clk[0].enable(&per_clk[0]);
1604         gpt1_clk[1].enable(&gpt1_clk[1]);
1605
1606         for (clkp = mxc_clks; clkp < mxc_clks + ARRAY_SIZE(mxc_clks); clkp++)
1607                 clk_register(*clkp);
1608
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);
1614
1615         /* This will propagate to all children and init all the clock rates */
1616
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;
1625 }