Merge branch 'linus' into cpus4096
[pandora-kernel.git] / 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 <asm/arch/clock.h>
26 #include <asm/arch/common.h>
27 #include <asm/div64.h>
28 #include <asm/mach-types.h>
29
30 #include "crm_regs.h"
31
32 static struct clk ckil_clk;
33 static struct clk mpll_clk;
34 static struct clk mpll_main_clk[];
35 static struct clk spll_clk;
36
37 static int _clk_enable(struct clk *clk)
38 {
39         unsigned long reg;
40
41         reg = __raw_readl(clk->enable_reg);
42         reg |= 1 << clk->enable_shift;
43         __raw_writel(reg, clk->enable_reg);
44
45         return 0;
46 }
47
48 static void _clk_disable(struct clk *clk)
49 {
50         unsigned long reg;
51
52         reg = __raw_readl(clk->enable_reg);
53         reg &= ~(1 << clk->enable_shift);
54         __raw_writel(reg, clk->enable_reg);
55 }
56
57 static int _clk_spll_enable(struct clk *clk)
58 {
59         unsigned long reg;
60
61         reg = __raw_readl(CCM_CSCR);
62         reg |= CCM_CSCR_SPEN;
63         __raw_writel(reg, CCM_CSCR);
64
65         while ((__raw_readl(CCM_SPCTL1) & CCM_SPCTL1_LF) == 0)
66                 ;
67
68         return 0;
69 }
70
71 static void _clk_spll_disable(struct clk *clk)
72 {
73         unsigned long reg;
74
75         reg = __raw_readl(CCM_CSCR);
76         reg &= ~CCM_CSCR_SPEN;
77         __raw_writel(reg, CCM_CSCR);
78 }
79
80 static void _clk_pccr01_enable(unsigned long mask0, unsigned long mask1)
81 {
82         unsigned long reg;
83
84         reg = __raw_readl(CCM_PCCR0);
85         reg |= mask0;
86         __raw_writel(reg, CCM_PCCR0);
87
88         reg = __raw_readl(CCM_PCCR1);
89         reg |= mask1;
90         __raw_writel(reg, CCM_PCCR1);
91
92 }
93
94 static void _clk_pccr01_disable(unsigned long mask0, unsigned long mask1)
95 {
96         unsigned long reg;
97
98         reg = __raw_readl(CCM_PCCR0);
99         reg &= ~mask0;
100         __raw_writel(reg, CCM_PCCR0);
101
102         reg = __raw_readl(CCM_PCCR1);
103         reg &= ~mask1;
104         __raw_writel(reg, CCM_PCCR1);
105 }
106
107 static void _clk_pccr10_enable(unsigned long mask1, unsigned long mask0)
108 {
109         unsigned long reg;
110
111         reg = __raw_readl(CCM_PCCR1);
112         reg |= mask1;
113         __raw_writel(reg, CCM_PCCR1);
114
115         reg = __raw_readl(CCM_PCCR0);
116         reg |= mask0;
117         __raw_writel(reg, CCM_PCCR0);
118 }
119
120 static void _clk_pccr10_disable(unsigned long mask1, unsigned long mask0)
121 {
122         unsigned long reg;
123
124         reg = __raw_readl(CCM_PCCR1);
125         reg &= ~mask1;
126         __raw_writel(reg, CCM_PCCR1);
127
128         reg = __raw_readl(CCM_PCCR0);
129         reg &= ~mask0;
130         __raw_writel(reg, CCM_PCCR0);
131 }
132
133 static int _clk_dma_enable(struct clk *clk)
134 {
135         _clk_pccr01_enable(CCM_PCCR0_DMA_MASK, CCM_PCCR1_HCLK_DMA_MASK);
136
137         return 0;
138 }
139
140 static void _clk_dma_disable(struct clk *clk)
141 {
142         _clk_pccr01_disable(CCM_PCCR0_DMA_MASK, CCM_PCCR1_HCLK_DMA_MASK);
143 }
144
145 static int _clk_rtic_enable(struct clk *clk)
146 {
147         _clk_pccr01_enable(CCM_PCCR0_RTIC_MASK, CCM_PCCR1_HCLK_RTIC_MASK);
148
149         return 0;
150 }
151
152 static void _clk_rtic_disable(struct clk *clk)
153 {
154         _clk_pccr01_disable(CCM_PCCR0_RTIC_MASK, CCM_PCCR1_HCLK_RTIC_MASK);
155 }
156
157 static int _clk_emma_enable(struct clk *clk)
158 {
159         _clk_pccr01_enable(CCM_PCCR0_EMMA_MASK, CCM_PCCR1_HCLK_EMMA_MASK);
160
161         return 0;
162 }
163
164 static void _clk_emma_disable(struct clk *clk)
165 {
166         _clk_pccr01_disable(CCM_PCCR0_EMMA_MASK, CCM_PCCR1_HCLK_EMMA_MASK);
167 }
168
169 static int _clk_slcdc_enable(struct clk *clk)
170 {
171         _clk_pccr01_enable(CCM_PCCR0_SLCDC_MASK, CCM_PCCR1_HCLK_SLCDC_MASK);
172
173         return 0;
174 }
175
176 static void _clk_slcdc_disable(struct clk *clk)
177 {
178         _clk_pccr01_disable(CCM_PCCR0_SLCDC_MASK, CCM_PCCR1_HCLK_SLCDC_MASK);
179 }
180
181 static int _clk_fec_enable(struct clk *clk)
182 {
183         _clk_pccr01_enable(CCM_PCCR0_FEC_MASK, CCM_PCCR1_HCLK_FEC_MASK);
184
185         return 0;
186 }
187
188 static void _clk_fec_disable(struct clk *clk)
189 {
190         _clk_pccr01_disable(CCM_PCCR0_FEC_MASK, CCM_PCCR1_HCLK_FEC_MASK);
191 }
192
193 static int _clk_vpu_enable(struct clk *clk)
194 {
195         unsigned long reg;
196
197         reg = __raw_readl(CCM_PCCR1);
198         reg |= CCM_PCCR1_VPU_BAUD_MASK | CCM_PCCR1_HCLK_VPU_MASK;
199         __raw_writel(reg, CCM_PCCR1);
200
201         return 0;
202 }
203
204 static void _clk_vpu_disable(struct clk *clk)
205 {
206         unsigned long reg;
207
208         reg = __raw_readl(CCM_PCCR1);
209         reg &= ~(CCM_PCCR1_VPU_BAUD_MASK | CCM_PCCR1_HCLK_VPU_MASK);
210         __raw_writel(reg, CCM_PCCR1);
211 }
212
213 static int _clk_sahara2_enable(struct clk *clk)
214 {
215         _clk_pccr01_enable(CCM_PCCR0_SAHARA_MASK, CCM_PCCR1_HCLK_SAHARA_MASK);
216
217         return 0;
218 }
219
220 static void _clk_sahara2_disable(struct clk *clk)
221 {
222         _clk_pccr01_disable(CCM_PCCR0_SAHARA_MASK, CCM_PCCR1_HCLK_SAHARA_MASK);
223 }
224
225 static int _clk_mstick1_enable(struct clk *clk)
226 {
227         _clk_pccr10_enable(CCM_PCCR1_MSHC_BAUD_MASK, CCM_PCCR0_MSHC_MASK);
228
229         return 0;
230 }
231
232 static void _clk_mstick1_disable(struct clk *clk)
233 {
234         _clk_pccr10_disable(CCM_PCCR1_MSHC_BAUD_MASK, CCM_PCCR0_MSHC_MASK);
235 }
236
237 #define CSCR() (__raw_readl(CCM_CSCR))
238 #define PCDR0() (__raw_readl(CCM_PCDR0))
239 #define PCDR1() (__raw_readl(CCM_PCDR1))
240
241 static int _clk_cpu_set_parent(struct clk *clk, struct clk *parent)
242 {
243         int cscr = CSCR();
244
245         if (clk->parent == parent)
246                 return 0;
247
248         if (mx27_revision() >= CHIP_REV_2_0) {
249                 if (parent == &mpll_main_clk[0]) {
250                         cscr |= CCM_CSCR_ARM_SRC;
251                 } else {
252                         if (parent == &mpll_main_clk[1])
253                                 cscr &= ~CCM_CSCR_ARM_SRC;
254                         else
255                                 return -EINVAL;
256                 }
257                 __raw_writel(cscr, CCM_CSCR);
258         } else
259                 return -ENODEV;
260
261         clk->parent = parent;
262         return 0;
263 }
264
265 static unsigned long _clk_cpu_round_rate(struct clk *clk, unsigned long rate)
266 {
267         int div;
268         unsigned long parent_rate;
269
270         parent_rate = clk_get_rate(clk->parent);
271
272         div = parent_rate / rate;
273         if (parent_rate % rate)
274                 div++;
275
276         if (div > 4)
277                 div = 4;
278
279         return parent_rate / div;
280 }
281
282 static int _clk_cpu_set_rate(struct clk *clk, unsigned long rate)
283 {
284         unsigned int div;
285         uint32_t reg;
286         unsigned long parent_rate;
287
288         parent_rate = clk_get_rate(clk->parent);
289
290         div = parent_rate / rate;
291
292         if (div > 4 || div < 1 || ((parent_rate / div) != rate))
293                 return -EINVAL;
294
295         div--;
296
297         reg = __raw_readl(CCM_CSCR);
298         if (mx27_revision() >= CHIP_REV_2_0) {
299                 reg &= ~CCM_CSCR_ARM_MASK;
300                 reg |= div << CCM_CSCR_ARM_OFFSET;
301                 reg &= ~0x06;
302                 __raw_writel(reg | 0x80000000, CCM_CSCR);
303         } else {
304                 printk(KERN_ERR "Cant set CPU frequency!\n");
305         }
306
307         return 0;
308 }
309
310 static unsigned long _clk_perclkx_round_rate(struct clk *clk,
311                                              unsigned long rate)
312 {
313         u32 div;
314         unsigned long parent_rate;
315
316         parent_rate = clk_get_rate(clk->parent);
317
318         div = parent_rate / rate;
319         if (parent_rate % rate)
320                 div++;
321
322         if (div > 64)
323                 div = 64;
324
325         return parent_rate / div;
326 }
327
328 static int _clk_perclkx_set_rate(struct clk *clk, unsigned long rate)
329 {
330         u32 reg;
331         u32 div;
332         unsigned long parent_rate;
333
334         parent_rate = clk_get_rate(clk->parent);
335
336         if (clk->id < 0 || clk->id > 3)
337                 return -EINVAL;
338
339         div = parent_rate / rate;
340         if (div > 64 || div < 1 || ((parent_rate / div) != rate))
341                 return -EINVAL;
342         div--;
343
344         reg =
345             __raw_readl(CCM_PCDR1) & ~(CCM_PCDR1_PERDIV1_MASK <<
346                                        (clk->id << 3));
347         reg |= div << (clk->id << 3);
348         __raw_writel(reg, CCM_PCDR1);
349
350         return 0;
351 }
352
353 static unsigned long _clk_usb_recalc(struct clk *clk)
354 {
355         unsigned long usb_pdf;
356         unsigned long parent_rate;
357
358         parent_rate = clk_get_rate(clk->parent);
359
360         usb_pdf = (CSCR() & CCM_CSCR_USB_MASK) >> CCM_CSCR_USB_OFFSET;
361
362         return parent_rate / (usb_pdf + 1U);
363 }
364
365 static unsigned long _clk_ssi1_recalc(struct clk *clk)
366 {
367         unsigned long ssi1_pdf;
368         unsigned long parent_rate;
369
370         parent_rate = clk_get_rate(clk->parent);
371
372         ssi1_pdf = (PCDR0() & CCM_PCDR0_SSI1BAUDDIV_MASK) >>
373                                         CCM_PCDR0_SSI1BAUDDIV_OFFSET;
374
375         if (mx27_revision() >= CHIP_REV_2_0)
376                 ssi1_pdf += 4;
377         else
378                 ssi1_pdf = (ssi1_pdf < 2) ? 124UL : ssi1_pdf;
379
380         return 2UL * parent_rate / ssi1_pdf;
381 }
382
383 static unsigned long _clk_ssi2_recalc(struct clk *clk)
384 {
385         unsigned long ssi2_pdf;
386         unsigned long parent_rate;
387
388         parent_rate = clk_get_rate(clk->parent);
389
390         ssi2_pdf = (PCDR0() & CCM_PCDR0_SSI2BAUDDIV_MASK) >>
391             CCM_PCDR0_SSI2BAUDDIV_OFFSET;
392
393         if (mx27_revision() >= CHIP_REV_2_0)
394                 ssi2_pdf += 4;
395         else
396                 ssi2_pdf = (ssi2_pdf < 2) ? 124UL : ssi2_pdf;
397
398         return 2UL * parent_rate / ssi2_pdf;
399 }
400
401 static unsigned long _clk_nfc_recalc(struct clk *clk)
402 {
403         unsigned long nfc_pdf;
404         unsigned long parent_rate;
405
406         parent_rate = clk_get_rate(clk->parent);
407
408         if (mx27_revision() >= CHIP_REV_2_0) {
409                 nfc_pdf =
410                     (PCDR0() & CCM_PCDR0_NFCDIV2_MASK) >>
411                     CCM_PCDR0_NFCDIV2_OFFSET;
412         } else {
413                 nfc_pdf =
414                     (PCDR0() & CCM_PCDR0_NFCDIV_MASK) >>
415                     CCM_PCDR0_NFCDIV_OFFSET;
416         }
417
418         return parent_rate / (nfc_pdf + 1);
419 }
420
421 static unsigned long _clk_vpu_recalc(struct clk *clk)
422 {
423         unsigned long vpu_pdf;
424         unsigned long parent_rate;
425
426         parent_rate = clk_get_rate(clk->parent);
427
428         if (mx27_revision() >= CHIP_REV_2_0) {
429                 vpu_pdf =
430                     (PCDR0() & CCM_PCDR0_VPUDIV2_MASK) >>
431                     CCM_PCDR0_VPUDIV2_OFFSET;
432                 vpu_pdf += 4;
433         } else {
434                 vpu_pdf =
435                     (PCDR0() & CCM_PCDR0_VPUDIV_MASK) >>
436                     CCM_PCDR0_VPUDIV_OFFSET;
437                 vpu_pdf = (vpu_pdf < 2) ? 124 : vpu_pdf;
438         }
439         return 2UL * parent_rate / vpu_pdf;
440 }
441
442 static unsigned long _clk_parent_round_rate(struct clk *clk, unsigned long rate)
443 {
444         return clk->parent->round_rate(clk->parent, rate);
445 }
446
447 static int _clk_parent_set_rate(struct clk *clk, unsigned long rate)
448 {
449         return clk->parent->set_rate(clk->parent, rate);
450 }
451
452 /* in Hz */
453 static unsigned long external_high_reference = 26000000;
454
455 static unsigned long get_high_reference_clock_rate(struct clk *clk)
456 {
457         return external_high_reference;
458 }
459
460 /*
461  * the high frequency external clock reference
462  * Default case is 26MHz. Could be changed at runtime
463  * with a call to change_external_high_reference()
464  */
465 static struct clk ckih_clk = {
466         .name = "ckih",
467         .get_rate = get_high_reference_clock_rate,
468 };
469
470 /* in Hz */
471 static unsigned long external_low_reference = 32768;
472
473 static unsigned long get_low_reference_clock_rate(struct clk *clk)
474 {
475         return external_low_reference;
476 }
477
478 /*
479  * the low frequency external clock reference
480  * Default case is 32.768kHz Could be changed at runtime
481  * with a call to change_external_low_reference()
482  */
483 static struct clk ckil_clk = {
484         .name = "ckil",
485         .get_rate = get_low_reference_clock_rate,
486 };
487
488 static unsigned long get_mpll_clk(struct clk *clk)
489 {
490         uint32_t reg;
491         unsigned long ref_clk;
492         unsigned long mfi = 0, mfn = 0, mfd = 0, pdf = 0;
493         unsigned long long temp;
494
495         ref_clk = clk_get_rate(clk->parent);
496
497         reg = __raw_readl(CCM_MPCTL0);
498         pdf = (reg & CCM_MPCTL0_PD_MASK) >> CCM_MPCTL0_PD_OFFSET;
499         mfd = (reg & CCM_MPCTL0_MFD_MASK) >> CCM_MPCTL0_MFD_OFFSET;
500         mfi = (reg & CCM_MPCTL0_MFI_MASK) >> CCM_MPCTL0_MFI_OFFSET;
501         mfn = (reg & CCM_MPCTL0_MFN_MASK) >> CCM_MPCTL0_MFN_OFFSET;
502
503         mfi = (mfi <= 5) ? 5 : mfi;
504         temp = 2LL * ref_clk * mfn;
505         do_div(temp, mfd + 1);
506         temp = 2LL * ref_clk * mfi + temp;
507         do_div(temp, pdf + 1);
508
509         return (unsigned long)temp;
510 }
511
512 static struct clk mpll_clk = {
513         .name = "mpll",
514         .parent = &ckih_clk,
515         .get_rate = get_mpll_clk,
516 };
517
518 static unsigned long _clk_mpll_main_get_rate(struct clk *clk)
519 {
520         unsigned long parent_rate;
521
522         parent_rate = clk_get_rate(clk->parent);
523
524         /* i.MX27 TO2:
525          * clk->id == 0: arm clock source path 1 which is from 2*MPLL/DIV_2
526          * clk->id == 1: arm clock source path 2 which is from 2*MPLL/DIV_3
527          */
528
529         if (mx27_revision() >= CHIP_REV_2_0 && clk->id == 1)
530                 return 2UL * parent_rate / 3UL;
531
532         return parent_rate;
533 }
534
535 static struct clk mpll_main_clk[] = {
536         {
537                 /* For i.MX27 TO2, it is the MPLL path 1 of ARM core
538                  * It provide the clock source whose rate is same as MPLL
539                  */
540                 .name = "mpll_main",
541                 .id = 0,
542                 .parent = &mpll_clk,
543                 .get_rate = _clk_mpll_main_get_rate
544         }, {
545                 /* For i.MX27 TO2, it is the MPLL path 2 of ARM core
546                  * It provide the clock source whose rate is same MPLL * 2/3
547                  */
548                 .name = "mpll_main",
549                 .id = 1,
550                 .parent = &mpll_clk,
551                 .get_rate = _clk_mpll_main_get_rate
552         }
553 };
554
555 static unsigned long get_spll_clk(struct clk *clk)
556 {
557         uint32_t reg;
558         unsigned long ref_clk;
559         unsigned long mfi = 0, mfn = 0, mfd = 0, pdf = 0;
560         unsigned long long temp;
561
562         ref_clk = clk_get_rate(clk->parent);
563
564         reg = __raw_readl(CCM_SPCTL0);
565         /*TODO: This is TO2 Bug */
566         if (mx27_revision() >= CHIP_REV_2_0)
567                 __raw_writel(reg, CCM_SPCTL0);
568
569         pdf = (reg & CCM_SPCTL0_PD_MASK) >> CCM_SPCTL0_PD_OFFSET;
570         mfd = (reg & CCM_SPCTL0_MFD_MASK) >> CCM_SPCTL0_MFD_OFFSET;
571         mfi = (reg & CCM_SPCTL0_MFI_MASK) >> CCM_SPCTL0_MFI_OFFSET;
572         mfn = (reg & CCM_SPCTL0_MFN_MASK) >> CCM_SPCTL0_MFN_OFFSET;
573
574         mfi = (mfi <= 5) ? 5 : mfi;
575         temp = 2LL * ref_clk * mfn;
576         do_div(temp, mfd + 1);
577         temp = 2LL * ref_clk * mfi + temp;
578         do_div(temp, pdf + 1);
579
580         return (unsigned long)temp;
581 }
582
583 static struct clk spll_clk = {
584         .name = "spll",
585         .parent = &ckih_clk,
586         .get_rate = get_spll_clk,
587         .enable = _clk_spll_enable,
588         .disable = _clk_spll_disable,
589 };
590
591 static unsigned long get_cpu_clk(struct clk *clk)
592 {
593         u32 div;
594         unsigned long rate;
595
596         if (mx27_revision() >= CHIP_REV_2_0)
597                 div = (CSCR() & CCM_CSCR_ARM_MASK) >> CCM_CSCR_ARM_OFFSET;
598         else
599                 div = (CSCR() & CCM_CSCR_PRESC_MASK) >> CCM_CSCR_PRESC_OFFSET;
600
601         rate = clk_get_rate(clk->parent);
602         return rate / (div + 1);
603 }
604
605 static struct clk cpu_clk = {
606         .name = "cpu_clk",
607         .parent = &mpll_main_clk[1],
608         .set_parent = _clk_cpu_set_parent,
609         .round_rate = _clk_cpu_round_rate,
610         .get_rate = get_cpu_clk,
611         .set_rate = _clk_cpu_set_rate,
612 };
613
614 static unsigned long get_ahb_clk(struct clk *clk)
615 {
616         unsigned long rate;
617         unsigned long bclk_pdf;
618
619         if (mx27_revision() >= CHIP_REV_2_0)
620                 bclk_pdf = (CSCR() & CCM_CSCR_AHB_MASK)
621                                         >> CCM_CSCR_AHB_OFFSET;
622         else
623                 bclk_pdf = (CSCR() & CCM_CSCR_BCLK_MASK)
624                                         >> CCM_CSCR_BCLK_OFFSET;
625
626         rate = clk_get_rate(clk->parent);
627         return rate / (bclk_pdf + 1);
628 }
629
630 static struct clk ahb_clk = {
631         .name = "ahb_clk",
632         .parent = &mpll_main_clk[1],
633         .get_rate = get_ahb_clk,
634 };
635
636 static unsigned long get_ipg_clk(struct clk *clk)
637 {
638         unsigned long rate;
639         unsigned long ipg_pdf;
640
641         if (mx27_revision() >= CHIP_REV_2_0)
642                 return clk_get_rate(clk->parent);
643         else
644                 ipg_pdf = (CSCR() & CCM_CSCR_IPDIV) >> CCM_CSCR_IPDIV_OFFSET;
645
646         rate = clk_get_rate(clk->parent);
647         return rate / (ipg_pdf + 1);
648 }
649
650 static struct clk ipg_clk = {
651         .name = "ipg_clk",
652         .parent = &ahb_clk,
653         .get_rate = get_ipg_clk,
654 };
655
656 static unsigned long _clk_perclkx_recalc(struct clk *clk)
657 {
658         unsigned long perclk_pdf;
659         unsigned long parent_rate;
660
661         parent_rate = clk_get_rate(clk->parent);
662
663         if (clk->id < 0 || clk->id > 3)
664                 return 0;
665
666         perclk_pdf = (PCDR1() >> (clk->id << 3)) & CCM_PCDR1_PERDIV1_MASK;
667
668         return parent_rate / (perclk_pdf + 1);
669 }
670
671 static struct clk per_clk[] = {
672         {
673                 .name = "per_clk",
674                 .id = 0,
675                 .parent = &mpll_main_clk[1],
676                 .get_rate = _clk_perclkx_recalc,
677                 .enable = _clk_enable,
678                 .enable_reg = CCM_PCCR1,
679                 .enable_shift = CCM_PCCR1_PERCLK1_OFFSET,
680                 .disable = _clk_disable,
681         }, {
682                 .name = "per_clk",
683                 .id = 1,
684                 .parent = &mpll_main_clk[1],
685                 .get_rate = _clk_perclkx_recalc,
686                 .enable = _clk_enable,
687                 .enable_reg = CCM_PCCR1,
688                 .enable_shift = CCM_PCCR1_PERCLK2_OFFSET,
689                 .disable = _clk_disable,
690         }, {
691                 .name = "per_clk",
692                 .id = 2,
693                 .parent = &mpll_main_clk[1],
694                 .round_rate = _clk_perclkx_round_rate,
695                 .set_rate = _clk_perclkx_set_rate,
696                 .get_rate = _clk_perclkx_recalc,
697                 .enable = _clk_enable,
698                 .enable_reg = CCM_PCCR1,
699                 .enable_shift = CCM_PCCR1_PERCLK3_OFFSET,
700                 .disable = _clk_disable,
701         }, {
702                 .name = "per_clk",
703                 .id = 3,
704                 .parent = &mpll_main_clk[1],
705                 .round_rate = _clk_perclkx_round_rate,
706                 .set_rate = _clk_perclkx_set_rate,
707                 .get_rate = _clk_perclkx_recalc,
708                 .enable = _clk_enable,
709                 .enable_reg = CCM_PCCR1,
710                 .enable_shift = CCM_PCCR1_PERCLK4_OFFSET,
711                 .disable = _clk_disable,
712         },
713 };
714
715 struct clk uart1_clk[] = {
716         {
717                 .name = "uart_clk",
718                 .id = 0,
719                 .parent = &per_clk[0],
720                 .secondary = &uart1_clk[1],
721         }, {
722                 .name = "uart_ipg_clk",
723                 .id = 0,
724                 .parent = &ipg_clk,
725                 .enable = _clk_enable,
726                 .enable_reg = CCM_PCCR1,
727                 .enable_shift = CCM_PCCR1_UART1_OFFSET,
728                 .disable = _clk_disable,
729         },
730 };
731
732 struct clk uart2_clk[] = {
733         {
734                 .name = "uart_clk",
735                 .id = 1,
736                 .parent = &per_clk[0],
737                 .secondary = &uart2_clk[1],
738         }, {
739                 .name = "uart_ipg_clk",
740                 .id = 1,
741                 .parent = &ipg_clk,
742                 .enable = _clk_enable,
743                 .enable_reg = CCM_PCCR1,
744                 .enable_shift = CCM_PCCR1_UART2_OFFSET,
745                 .disable = _clk_disable,
746         },
747 };
748
749 struct clk uart3_clk[] = {
750         {
751                 .name = "uart_clk",
752                 .id = 2,
753                 .parent = &per_clk[0],
754                 .secondary = &uart3_clk[1],
755         }, {
756                 .name = "uart_ipg_clk",
757                 .id = 2,
758                 .parent = &ipg_clk,
759                 .enable = _clk_enable,
760                 .enable_reg = CCM_PCCR1,
761                 .enable_shift = CCM_PCCR1_UART3_OFFSET,
762                 .disable = _clk_disable,
763         },
764 };
765
766 struct clk uart4_clk[] = {
767         {
768                 .name = "uart_clk",
769                 .id = 3,
770                 .parent = &per_clk[0],
771                 .secondary = &uart4_clk[1],
772         }, {
773                 .name = "uart_ipg_clk",
774                 .id = 3,
775                 .parent = &ipg_clk,
776                 .enable = _clk_enable,
777                 .enable_reg = CCM_PCCR1,
778                 .enable_shift = CCM_PCCR1_UART4_OFFSET,
779                 .disable = _clk_disable,
780         },
781 };
782
783 struct clk uart5_clk[] = {
784         {
785                 .name = "uart_clk",
786                 .id = 4,
787                 .parent = &per_clk[0],
788                 .secondary = &uart5_clk[1],
789         }, {
790                 .name = "uart_ipg_clk",
791                 .id = 4,
792                 .parent = &ipg_clk,
793                 .enable = _clk_enable,
794                 .enable_reg = CCM_PCCR1,
795                 .enable_shift = CCM_PCCR1_UART5_OFFSET,
796                 .disable = _clk_disable,
797         },
798 };
799
800 struct clk uart6_clk[] = {
801         {
802                 .name = "uart_clk",
803                 .id = 5,
804                 .parent = &per_clk[0],
805                 .secondary = &uart6_clk[1],
806         }, {
807                 .name = "uart_ipg_clk",
808                 .id = 5,
809                 .parent = &ipg_clk,
810                 .enable = _clk_enable,
811                 .enable_reg = CCM_PCCR1,
812                 .enable_shift = CCM_PCCR1_UART6_OFFSET,
813                 .disable = _clk_disable,
814         },
815 };
816
817 static struct clk gpt1_clk[] = {
818         {
819                 .name = "gpt_clk",
820                 .id = 0,
821                 .parent = &per_clk[0],
822                 .secondary = &gpt1_clk[1],
823         }, {
824                 .name = "gpt_ipg_clk",
825                 .id = 0,
826                 .parent = &ipg_clk,
827                 .enable = _clk_enable,
828                 .enable_reg = CCM_PCCR0,
829                 .enable_shift = CCM_PCCR0_GPT1_OFFSET,
830                 .disable = _clk_disable,
831         },
832 };
833
834 static struct clk gpt2_clk[] = {
835         {
836                 .name = "gpt_clk",
837                 .id = 1,
838                 .parent = &per_clk[0],
839                 .secondary = &gpt2_clk[1],
840         }, {
841                 .name = "gpt_ipg_clk",
842                 .id = 1,
843                 .parent = &ipg_clk,
844                 .enable = _clk_enable,
845                 .enable_reg = CCM_PCCR0,
846                 .enable_shift = CCM_PCCR0_GPT2_OFFSET,
847                 .disable = _clk_disable,
848         },
849 };
850
851 static struct clk gpt3_clk[] = {
852         {
853                 .name = "gpt_clk",
854                 .id = 2,
855                 .parent = &per_clk[0],
856                 .secondary = &gpt3_clk[1],
857         }, {
858                 .name = "gpt_ipg_clk",
859                 .id = 2,
860                 .parent = &ipg_clk,
861                 .enable = _clk_enable,
862                 .enable_reg = CCM_PCCR0,
863                 .enable_shift = CCM_PCCR0_GPT3_OFFSET,
864                 .disable = _clk_disable,
865         },
866 };
867
868 static struct clk gpt4_clk[] = {
869         {
870                 .name = "gpt_clk",
871                 .id = 3,
872                 .parent = &per_clk[0],
873                 .secondary = &gpt4_clk[1],
874         }, {
875                 .name = "gpt_ipg_clk",
876                 .id = 3,
877                 .parent = &ipg_clk,
878                 .enable = _clk_enable,
879                 .enable_reg = CCM_PCCR0,
880                 .enable_shift = CCM_PCCR0_GPT4_OFFSET,
881                 .disable = _clk_disable,
882         },
883 };
884
885 static struct clk gpt5_clk[] = {
886         {
887                 .name = "gpt_clk",
888                 .id = 4,
889                 .parent = &per_clk[0],
890                 .secondary = &gpt5_clk[1],
891         }, {
892                 .name = "gpt_ipg_clk",
893                 .id = 4,
894                 .parent = &ipg_clk,
895                 .enable = _clk_enable,
896                 .enable_reg = CCM_PCCR0,
897                 .enable_shift = CCM_PCCR0_GPT5_OFFSET,
898                 .disable = _clk_disable,
899         },
900 };
901
902 static struct clk gpt6_clk[] = {
903         {
904                 .name = "gpt_clk",
905                 .id = 5,
906                 .parent = &per_clk[0],
907                 .secondary = &gpt6_clk[1],
908         }, {
909                 .name = "gpt_ipg_clk",
910                 .id = 5,
911                 .parent = &ipg_clk,
912                 .enable = _clk_enable,
913                 .enable_reg = CCM_PCCR0,
914                 .enable_shift = CCM_PCCR0_GPT6_OFFSET,
915                 .disable = _clk_disable,
916         },
917 };
918
919 static struct clk pwm_clk[] = {
920         {
921                 .name = "pwm_clk",
922                 .parent = &per_clk[0],
923                 .secondary = &pwm_clk[1],
924         }, {
925                 .name = "pwm_clk",
926                 .parent = &ipg_clk,
927                 .enable = _clk_enable,
928                 .enable_reg = CCM_PCCR0,
929                 .enable_shift = CCM_PCCR0_PWM_OFFSET,
930                 .disable = _clk_disable,
931         },
932 };
933
934 static struct clk sdhc1_clk[] = {
935         {
936                 .name = "sdhc_clk",
937                 .id = 0,
938                 .parent = &per_clk[1],
939                 .secondary = &sdhc1_clk[1],
940         }, {
941                 .name = "sdhc_ipg_clk",
942                 .id = 0,
943                 .parent = &ipg_clk,
944                 .enable = _clk_enable,
945                 .enable_reg = CCM_PCCR0,
946                 .enable_shift = CCM_PCCR0_SDHC1_OFFSET,
947                 .disable = _clk_disable,
948         },
949 };
950
951 static struct clk sdhc2_clk[] = {
952         {
953                 .name = "sdhc_clk",
954                 .id = 1,
955                 .parent = &per_clk[1],
956                 .secondary = &sdhc2_clk[1],
957         }, {
958                 .name = "sdhc_ipg_clk",
959                 .id = 1,
960                 .parent = &ipg_clk,
961                 .enable = _clk_enable,
962                 .enable_reg = CCM_PCCR0,
963                 .enable_shift = CCM_PCCR0_SDHC2_OFFSET,
964                 .disable = _clk_disable,
965         },
966 };
967
968 static struct clk sdhc3_clk[] = {
969         {
970                 .name = "sdhc_clk",
971                 .id = 2,
972                 .parent = &per_clk[1],
973                 .secondary = &sdhc3_clk[1],
974         }, {
975                 .name = "sdhc_ipg_clk",
976                 .id = 2,
977                 .parent = &ipg_clk,
978                 .enable = _clk_enable,
979                 .enable_reg = CCM_PCCR0,
980                 .enable_shift = CCM_PCCR0_SDHC3_OFFSET,
981                 .disable = _clk_disable,
982         },
983 };
984
985 static struct clk cspi1_clk[] = {
986         {
987                 .name = "cspi_clk",
988                 .id = 0,
989                 .parent = &per_clk[1],
990                 .secondary = &cspi1_clk[1],
991         }, {
992                 .name = "cspi_ipg_clk",
993                 .id = 0,
994                 .parent = &ipg_clk,
995                 .enable = _clk_enable,
996                 .enable_reg = CCM_PCCR0,
997                 .enable_shift = CCM_PCCR0_CSPI1_OFFSET,
998                 .disable = _clk_disable,
999         },
1000 };
1001
1002 static struct clk cspi2_clk[] = {
1003         {
1004                 .name = "cspi_clk",
1005                 .id = 1,
1006                 .parent = &per_clk[1],
1007                 .secondary = &cspi2_clk[1],
1008         }, {
1009                 .name = "cspi_ipg_clk",
1010                 .id = 1,
1011                 .parent = &ipg_clk,
1012                 .enable = _clk_enable,
1013                 .enable_reg = CCM_PCCR0,
1014                 .enable_shift = CCM_PCCR0_CSPI2_OFFSET,
1015                 .disable = _clk_disable,
1016         },
1017 };
1018
1019 static struct clk cspi3_clk[] = {
1020         {
1021                 .name = "cspi_clk",
1022                 .id = 2,
1023                 .parent = &per_clk[1],
1024                 .secondary = &cspi3_clk[1],
1025         }, {
1026                 .name = "cspi_ipg_clk",
1027                 .id = 2,
1028                 .parent = &ipg_clk,
1029                 .enable = _clk_enable,
1030                 .enable_reg = CCM_PCCR0,
1031                 .enable_shift = CCM_PCCR0_CSPI3_OFFSET,
1032                 .disable = _clk_disable,
1033         },
1034 };
1035
1036 static struct clk lcdc_clk[] = {
1037         {
1038                 .name = "lcdc_clk",
1039                 .parent = &per_clk[2],
1040                 .secondary = &lcdc_clk[1],
1041                 .round_rate = _clk_parent_round_rate,
1042                 .set_rate = _clk_parent_set_rate,
1043         }, {
1044                 .name = "lcdc_ipg_clk",
1045                 .parent = &ipg_clk,
1046                 .secondary = &lcdc_clk[2],
1047                 .enable = _clk_enable,
1048                 .enable_reg = CCM_PCCR0,
1049                 .enable_shift = CCM_PCCR0_LCDC_OFFSET,
1050                 .disable = _clk_disable,
1051         }, {
1052                 .name = "lcdc_ahb_clk",
1053                 .parent = &ahb_clk,
1054                 .enable = _clk_enable,
1055                 .enable_reg = CCM_PCCR1,
1056                 .enable_shift = CCM_PCCR1_HCLK_LCDC_OFFSET,
1057                 .disable = _clk_disable,
1058         },
1059 };
1060
1061 static struct clk csi_clk[] = {
1062         {
1063                 .name = "csi_perclk",
1064                 .parent = &per_clk[3],
1065                 .secondary = &csi_clk[1],
1066                 .round_rate = _clk_parent_round_rate,
1067                 .set_rate = _clk_parent_set_rate,
1068         }, {
1069                 .name = "csi_ahb_clk",
1070                 .parent = &ahb_clk,
1071                 .enable = _clk_enable,
1072                 .enable_reg = CCM_PCCR1,
1073                 .enable_shift = CCM_PCCR1_HCLK_CSI_OFFSET,
1074                 .disable = _clk_disable,
1075         },
1076 };
1077
1078 static struct clk usb_clk[] = {
1079         {
1080                 .name = "usb_clk",
1081                 .parent = &spll_clk,
1082                 .get_rate = _clk_usb_recalc,
1083                 .enable = _clk_enable,
1084                 .enable_reg = CCM_PCCR1,
1085                 .enable_shift = CCM_PCCR1_USBOTG_OFFSET,
1086                 .disable = _clk_disable,
1087         }, {
1088                 .name = "usb_ahb_clk",
1089                 .parent = &ahb_clk,
1090                 .enable = _clk_enable,
1091                 .enable_reg = CCM_PCCR1,
1092                 .enable_shift = CCM_PCCR1_HCLK_USBOTG_OFFSET,
1093                 .disable = _clk_disable,
1094         }
1095 };
1096
1097 static struct clk ssi1_clk[] = {
1098         {
1099                 .name = "ssi_clk",
1100                 .id = 0,
1101                 .parent = &mpll_main_clk[1],
1102                 .secondary = &ssi1_clk[1],
1103                 .get_rate = _clk_ssi1_recalc,
1104                 .enable = _clk_enable,
1105                 .enable_reg = CCM_PCCR1,
1106                 .enable_shift = CCM_PCCR1_SSI1_BAUD_OFFSET,
1107                 .disable = _clk_disable,
1108         }, {
1109                 .name = "ssi_ipg_clk",
1110                 .id = 0,
1111                 .parent = &ipg_clk,
1112                 .enable = _clk_enable,
1113                 .enable_reg = CCM_PCCR0,
1114                 .enable_shift = CCM_PCCR0_SSI1_IPG_OFFSET,
1115                 .disable = _clk_disable,
1116         },
1117 };
1118
1119 static struct clk ssi2_clk[] = {
1120         {
1121                 .name = "ssi_clk",
1122                 .id = 1,
1123                 .parent = &mpll_main_clk[1],
1124                 .secondary = &ssi2_clk[1],
1125                 .get_rate = _clk_ssi2_recalc,
1126                 .enable = _clk_enable,
1127                 .enable_reg = CCM_PCCR1,
1128                 .enable_shift = CCM_PCCR1_SSI2_BAUD_OFFSET,
1129                 .disable = _clk_disable,
1130         }, {
1131                 .name = "ssi_ipg_clk",
1132                 .id = 1,
1133                 .parent = &ipg_clk,
1134                 .enable = _clk_enable,
1135                 .enable_reg = CCM_PCCR0,
1136                 .enable_shift = CCM_PCCR0_SSI2_IPG_OFFSET,
1137                 .disable = _clk_disable,
1138         },
1139 };
1140
1141 static struct clk nfc_clk = {
1142         .name = "nfc_clk",
1143         .parent = &cpu_clk,
1144         .get_rate = _clk_nfc_recalc,
1145         .enable = _clk_enable,
1146         .enable_reg = CCM_PCCR1,
1147         .enable_shift = CCM_PCCR1_NFC_BAUD_OFFSET,
1148         .disable = _clk_disable,
1149 };
1150
1151 static struct clk vpu_clk = {
1152         .name = "vpu_clk",
1153         .parent = &mpll_main_clk[1],
1154         .get_rate = _clk_vpu_recalc,
1155         .enable = _clk_vpu_enable,
1156         .disable = _clk_vpu_disable,
1157 };
1158
1159 static struct clk dma_clk = {
1160         .name = "dma_clk",
1161         .parent = &ahb_clk,
1162         .enable = _clk_dma_enable,
1163         .disable = _clk_dma_disable,
1164 };
1165
1166 static struct clk rtic_clk = {
1167         .name = "rtic_clk",
1168         .parent = &ahb_clk,
1169         .enable = _clk_rtic_enable,
1170         .disable = _clk_rtic_disable,
1171 };
1172
1173 static struct clk brom_clk = {
1174         .name = "brom_clk",
1175         .parent = &ahb_clk,
1176         .enable = _clk_enable,
1177         .enable_reg = CCM_PCCR1,
1178         .enable_shift = CCM_PCCR1_HCLK_BROM_OFFSET,
1179         .disable = _clk_disable,
1180 };
1181
1182 static struct clk emma_clk = {
1183         .name = "emma_clk",
1184         .parent = &ahb_clk,
1185         .enable = _clk_emma_enable,
1186         .disable = _clk_emma_disable,
1187 };
1188
1189 static struct clk slcdc_clk = {
1190         .name = "slcdc_clk",
1191         .parent = &ahb_clk,
1192         .enable = _clk_slcdc_enable,
1193         .disable = _clk_slcdc_disable,
1194 };
1195
1196 static struct clk fec_clk = {
1197         .name = "fec_clk",
1198         .parent = &ahb_clk,
1199         .enable = _clk_fec_enable,
1200         .disable = _clk_fec_disable,
1201 };
1202
1203 static struct clk emi_clk = {
1204         .name = "emi_clk",
1205         .parent = &ahb_clk,
1206         .enable = _clk_enable,
1207         .enable_reg = CCM_PCCR1,
1208         .enable_shift = CCM_PCCR1_HCLK_EMI_OFFSET,
1209         .disable = _clk_disable,
1210 };
1211
1212 static struct clk sahara2_clk = {
1213         .name = "sahara_clk",
1214         .parent = &ahb_clk,
1215         .enable = _clk_sahara2_enable,
1216         .disable = _clk_sahara2_disable,
1217 };
1218
1219 static struct clk ata_clk = {
1220         .name = "ata_clk",
1221         .parent = &ahb_clk,
1222         .enable = _clk_enable,
1223         .enable_reg = CCM_PCCR1,
1224         .enable_shift = CCM_PCCR1_HCLK_ATA_OFFSET,
1225         .disable = _clk_disable,
1226 };
1227
1228 static struct clk mstick1_clk = {
1229         .name = "mstick1_clk",
1230         .parent = &ipg_clk,
1231         .enable = _clk_mstick1_enable,
1232         .disable = _clk_mstick1_disable,
1233 };
1234
1235 static struct clk wdog_clk = {
1236         .name = "wdog_clk",
1237         .parent = &ipg_clk,
1238         .enable = _clk_enable,
1239         .enable_reg = CCM_PCCR1,
1240         .enable_shift = CCM_PCCR1_WDT_OFFSET,
1241         .disable = _clk_disable,
1242 };
1243
1244 static struct clk gpio_clk = {
1245         .name = "gpio_clk",
1246         .parent = &ipg_clk,
1247         .enable = _clk_enable,
1248         .enable_reg = CCM_PCCR1,
1249         .enable_shift = CCM_PCCR0_GPIO_OFFSET,
1250         .disable = _clk_disable,
1251 };
1252
1253 static struct clk i2c_clk[] = {
1254         {
1255                 .name = "i2c_clk",
1256                 .id = 0,
1257                 .parent = &ipg_clk,
1258                 .enable = _clk_enable,
1259                 .enable_reg = CCM_PCCR0,
1260                 .enable_shift = CCM_PCCR0_I2C1_OFFSET,
1261                 .disable = _clk_disable,
1262         }, {
1263                 .name = "i2c_clk",
1264                 .id = 1,
1265                 .parent = &ipg_clk,
1266                 .enable = _clk_enable,
1267                 .enable_reg = CCM_PCCR0,
1268                 .enable_shift = CCM_PCCR0_I2C2_OFFSET,
1269                 .disable = _clk_disable,
1270         },
1271 };
1272
1273 static struct clk iim_clk = {
1274         .name = "iim_clk",
1275         .parent = &ipg_clk,
1276         .enable = _clk_enable,
1277         .enable_reg = CCM_PCCR0,
1278         .enable_shift = CCM_PCCR0_IIM_OFFSET,
1279         .disable = _clk_disable,
1280 };
1281
1282 static struct clk kpp_clk = {
1283         .name = "kpp_clk",
1284         .parent = &ipg_clk,
1285         .enable = _clk_enable,
1286         .enable_reg = CCM_PCCR0,
1287         .enable_shift = CCM_PCCR0_KPP_OFFSET,
1288         .disable = _clk_disable,
1289 };
1290
1291 static struct clk owire_clk = {
1292         .name = "owire_clk",
1293         .parent = &ipg_clk,
1294         .enable = _clk_enable,
1295         .enable_reg = CCM_PCCR0,
1296         .enable_shift = CCM_PCCR0_OWIRE_OFFSET,
1297         .disable = _clk_disable,
1298 };
1299
1300 static struct clk rtc_clk = {
1301         .name = "rtc_clk",
1302         .parent = &ipg_clk,
1303         .enable = _clk_enable,
1304         .enable_reg = CCM_PCCR0,
1305         .enable_shift = CCM_PCCR0_RTC_OFFSET,
1306         .disable = _clk_disable,
1307 };
1308
1309 static struct clk scc_clk = {
1310         .name = "scc_clk",
1311         .parent = &ipg_clk,
1312         .enable = _clk_enable,
1313         .enable_reg = CCM_PCCR0,
1314         .enable_shift = CCM_PCCR0_SCC_OFFSET,
1315         .disable = _clk_disable,
1316 };
1317
1318 static unsigned long _clk_clko_round_rate(struct clk *clk, unsigned long rate)
1319 {
1320         u32 div;
1321         unsigned long parent_rate;
1322
1323         parent_rate = clk_get_rate(clk->parent);
1324         div = parent_rate / rate;
1325         if (parent_rate % rate)
1326                 div++;
1327
1328         if (div > 8)
1329                 div = 8;
1330
1331         return parent_rate / div;
1332 }
1333
1334 static int _clk_clko_set_rate(struct clk *clk, unsigned long rate)
1335 {
1336         u32 reg;
1337         u32 div;
1338         unsigned long parent_rate;
1339
1340         parent_rate = clk_get_rate(clk->parent);
1341
1342         div = parent_rate / rate;
1343
1344         if (div > 8 || div < 1 || ((parent_rate / div) != rate))
1345                 return -EINVAL;
1346         div--;
1347
1348         reg = __raw_readl(CCM_PCDR0) & ~CCM_PCDR0_CLKODIV_MASK;
1349         reg |= div << CCM_PCDR0_CLKODIV_OFFSET;
1350         __raw_writel(reg, CCM_PCDR0);
1351
1352         return 0;
1353 }
1354
1355 static unsigned long _clk_clko_recalc(struct clk *clk)
1356 {
1357         u32 div;
1358         unsigned long parent_rate;
1359
1360         parent_rate = clk_get_rate(clk->parent);
1361
1362         div = __raw_readl(CCM_PCDR0) & CCM_PCDR0_CLKODIV_MASK >>
1363                 CCM_PCDR0_CLKODIV_OFFSET;
1364         div++;
1365
1366         return parent_rate / div;
1367 }
1368
1369 static int _clk_clko_set_parent(struct clk *clk, struct clk *parent)
1370 {
1371         u32 reg;
1372
1373         reg = __raw_readl(CCM_CCSR) & ~CCM_CCSR_CLKOSEL_MASK;
1374
1375         if (parent == &ckil_clk)
1376                 reg |= 0 << CCM_CCSR_CLKOSEL_OFFSET;
1377         else if (parent == &ckih_clk)
1378                 reg |= 2 << CCM_CCSR_CLKOSEL_OFFSET;
1379         else if (parent == mpll_clk.parent)
1380                 reg |= 3 << CCM_CCSR_CLKOSEL_OFFSET;
1381         else if (parent == spll_clk.parent)
1382                 reg |= 4 << CCM_CCSR_CLKOSEL_OFFSET;
1383         else if (parent == &mpll_clk)
1384                 reg |= 5 << CCM_CCSR_CLKOSEL_OFFSET;
1385         else if (parent == &spll_clk)
1386                 reg |= 6 << CCM_CCSR_CLKOSEL_OFFSET;
1387         else if (parent == &cpu_clk)
1388                 reg |= 7 << CCM_CCSR_CLKOSEL_OFFSET;
1389         else if (parent == &ahb_clk)
1390                 reg |= 8 << CCM_CCSR_CLKOSEL_OFFSET;
1391         else if (parent == &ipg_clk)
1392                 reg |= 9 << CCM_CCSR_CLKOSEL_OFFSET;
1393         else if (parent == &per_clk[0])
1394                 reg |= 0xA << CCM_CCSR_CLKOSEL_OFFSET;
1395         else if (parent == &per_clk[1])
1396                 reg |= 0xB << CCM_CCSR_CLKOSEL_OFFSET;
1397         else if (parent == &per_clk[2])
1398                 reg |= 0xC << CCM_CCSR_CLKOSEL_OFFSET;
1399         else if (parent == &per_clk[3])
1400                 reg |= 0xD << CCM_CCSR_CLKOSEL_OFFSET;
1401         else if (parent == &ssi1_clk[0])
1402                 reg |= 0xE << CCM_CCSR_CLKOSEL_OFFSET;
1403         else if (parent == &ssi2_clk[0])
1404                 reg |= 0xF << CCM_CCSR_CLKOSEL_OFFSET;
1405         else if (parent == &nfc_clk)
1406                 reg |= 0x10 << CCM_CCSR_CLKOSEL_OFFSET;
1407         else if (parent == &mstick1_clk)
1408                 reg |= 0x11 << CCM_CCSR_CLKOSEL_OFFSET;
1409         else if (parent == &vpu_clk)
1410                 reg |= 0x12 << CCM_CCSR_CLKOSEL_OFFSET;
1411         else if (parent == &usb_clk[0])
1412                 reg |= 0x15 << CCM_CCSR_CLKOSEL_OFFSET;
1413         else
1414                 return -EINVAL;
1415
1416         __raw_writel(reg, CCM_CCSR);
1417
1418         return 0;
1419 }
1420
1421 static int _clk_clko_enable(struct clk *clk)
1422 {
1423         u32 reg;
1424
1425         reg = __raw_readl(CCM_PCDR0) | CCM_PCDR0_CLKO_EN;
1426         __raw_writel(reg, CCM_PCDR0);
1427
1428         return 0;
1429 }
1430
1431 static void _clk_clko_disable(struct clk *clk)
1432 {
1433         u32 reg;
1434
1435         reg = __raw_readl(CCM_PCDR0) & ~CCM_PCDR0_CLKO_EN;
1436         __raw_writel(reg, CCM_PCDR0);
1437 }
1438
1439 static struct clk clko_clk = {
1440         .name = "clko_clk",
1441         .get_rate = _clk_clko_recalc,
1442         .set_rate = _clk_clko_set_rate,
1443         .round_rate = _clk_clko_round_rate,
1444         .set_parent = _clk_clko_set_parent,
1445         .enable = _clk_clko_enable,
1446         .disable = _clk_clko_disable,
1447 };
1448
1449 static struct clk *mxc_clks[] = {
1450         &ckih_clk,
1451         &ckil_clk,
1452         &mpll_clk,
1453         &mpll_main_clk[0],
1454         &mpll_main_clk[1],
1455         &spll_clk,
1456         &cpu_clk,
1457         &ahb_clk,
1458         &ipg_clk,
1459         &per_clk[0],
1460         &per_clk[1],
1461         &per_clk[2],
1462         &per_clk[3],
1463         &clko_clk,
1464         &uart1_clk[0],
1465         &uart1_clk[1],
1466         &uart2_clk[0],
1467         &uart2_clk[1],
1468         &uart3_clk[0],
1469         &uart3_clk[1],
1470         &uart4_clk[0],
1471         &uart4_clk[1],
1472         &uart5_clk[0],
1473         &uart5_clk[1],
1474         &uart6_clk[0],
1475         &uart6_clk[1],
1476         &gpt1_clk[0],
1477         &gpt1_clk[1],
1478         &gpt2_clk[0],
1479         &gpt2_clk[1],
1480         &gpt3_clk[0],
1481         &gpt3_clk[1],
1482         &gpt4_clk[0],
1483         &gpt4_clk[1],
1484         &gpt5_clk[0],
1485         &gpt5_clk[1],
1486         &gpt6_clk[0],
1487         &gpt6_clk[1],
1488         &pwm_clk[0],
1489         &pwm_clk[1],
1490         &sdhc1_clk[0],
1491         &sdhc1_clk[1],
1492         &sdhc2_clk[0],
1493         &sdhc2_clk[1],
1494         &sdhc3_clk[0],
1495         &sdhc3_clk[1],
1496         &cspi1_clk[0],
1497         &cspi1_clk[1],
1498         &cspi2_clk[0],
1499         &cspi2_clk[1],
1500         &cspi3_clk[0],
1501         &cspi3_clk[1],
1502         &lcdc_clk[0],
1503         &lcdc_clk[1],
1504         &lcdc_clk[2],
1505         &csi_clk[0],
1506         &csi_clk[1],
1507         &usb_clk[0],
1508         &usb_clk[1],
1509         &ssi1_clk[0],
1510         &ssi1_clk[1],
1511         &ssi2_clk[0],
1512         &ssi2_clk[1],
1513         &nfc_clk,
1514         &vpu_clk,
1515         &dma_clk,
1516         &rtic_clk,
1517         &brom_clk,
1518         &emma_clk,
1519         &slcdc_clk,
1520         &fec_clk,
1521         &emi_clk,
1522         &sahara2_clk,
1523         &ata_clk,
1524         &mstick1_clk,
1525         &wdog_clk,
1526         &gpio_clk,
1527         &i2c_clk[0],
1528         &i2c_clk[1],
1529         &iim_clk,
1530         &kpp_clk,
1531         &owire_clk,
1532         &rtc_clk,
1533         &scc_clk,
1534 };
1535
1536 void __init change_external_low_reference(unsigned long new_ref)
1537 {
1538         external_low_reference = new_ref;
1539 }
1540
1541 unsigned long __init clk_early_get_timer_rate(void)
1542 {
1543         return clk_get_rate(&per_clk[0]);
1544 }
1545
1546 static void __init probe_mxc_clocks(void)
1547 {
1548         int i;
1549
1550         if (mx27_revision() >= CHIP_REV_2_0) {
1551                 if (CSCR() & 0x8000)
1552                         cpu_clk.parent = &mpll_main_clk[0];
1553
1554                 if (!(CSCR() & 0x00800000))
1555                         ssi2_clk[0].parent = &spll_clk;
1556
1557                 if (!(CSCR() & 0x00400000))
1558                         ssi1_clk[0].parent = &spll_clk;
1559
1560                 if (!(CSCR() & 0x00200000))
1561                         vpu_clk.parent = &spll_clk;
1562         } else {
1563                 cpu_clk.parent = &mpll_clk;
1564                 cpu_clk.set_parent = NULL;
1565                 cpu_clk.round_rate = NULL;
1566                 cpu_clk.set_rate = NULL;
1567                 ahb_clk.parent = &mpll_clk;
1568
1569                 for (i = 0; i < sizeof(per_clk) / sizeof(per_clk[0]); i++)
1570                         per_clk[i].parent = &mpll_clk;
1571
1572                 ssi1_clk[0].parent = &mpll_clk;
1573                 ssi2_clk[0].parent = &mpll_clk;
1574
1575                 vpu_clk.parent = &mpll_clk;
1576         }
1577 }
1578
1579 /*
1580  * must be called very early to get information about the
1581  * available clock rate when the timer framework starts
1582  */
1583 int __init mxc_clocks_init(unsigned long fref)
1584 {
1585         u32 cscr;
1586         struct clk **clkp;
1587
1588         external_high_reference = fref;
1589
1590         /* detect clock reference for both system PLL */
1591         cscr = CSCR();
1592         if (cscr & CCM_CSCR_MCU)
1593                 mpll_clk.parent = &ckih_clk;
1594         else
1595                 mpll_clk.parent = &ckil_clk;
1596
1597         if (cscr & CCM_CSCR_SP)
1598                 spll_clk.parent = &ckih_clk;
1599         else
1600                 spll_clk.parent = &ckil_clk;
1601
1602         probe_mxc_clocks();
1603
1604         per_clk[0].enable(&per_clk[0]);
1605         gpt1_clk[1].enable(&gpt1_clk[1]);
1606
1607         for (clkp = mxc_clks; clkp < mxc_clks + ARRAY_SIZE(mxc_clks); clkp++)
1608                 clk_register(*clkp);
1609
1610         /* Turn off all possible clocks */
1611         __raw_writel(CCM_PCCR0_GPT1_MASK, CCM_PCCR0);
1612         __raw_writel(CCM_PCCR1_PERCLK1_MASK | CCM_PCCR1_HCLK_EMI_MASK,
1613                      CCM_PCCR1);
1614         spll_clk.disable(&spll_clk);
1615
1616         /* This will propagate to all children and init all the clock rates */
1617
1618         clk_enable(&emi_clk);
1619         clk_enable(&gpio_clk);
1620         clk_enable(&iim_clk);
1621         clk_enable(&gpt1_clk[0]);
1622 #ifdef CONFIG_DEBUG_LL_CONSOLE
1623         clk_enable(&uart1_clk[0]);
1624 #endif
1625         return 0;
1626 }