047e71e6ea9aab743a381b137b0ff213870511d0
[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 <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         return mxc_decode_pll(__raw_readl(CCM_MPCTL0),
490                         clk_get_rate(clk->parent));
491 }
492
493 static struct clk mpll_clk = {
494         .name = "mpll",
495         .parent = &ckih_clk,
496         .get_rate = get_mpll_clk,
497 };
498
499 static unsigned long _clk_mpll_main_get_rate(struct clk *clk)
500 {
501         unsigned long parent_rate;
502
503         parent_rate = clk_get_rate(clk->parent);
504
505         /* i.MX27 TO2:
506          * clk->id == 0: arm clock source path 1 which is from 2*MPLL/DIV_2
507          * clk->id == 1: arm clock source path 2 which is from 2*MPLL/DIV_3
508          */
509
510         if (mx27_revision() >= CHIP_REV_2_0 && clk->id == 1)
511                 return 2UL * parent_rate / 3UL;
512
513         return parent_rate;
514 }
515
516 static struct clk mpll_main_clk[] = {
517         {
518                 /* For i.MX27 TO2, it is the MPLL path 1 of ARM core
519                  * It provide the clock source whose rate is same as MPLL
520                  */
521                 .name = "mpll_main",
522                 .id = 0,
523                 .parent = &mpll_clk,
524                 .get_rate = _clk_mpll_main_get_rate
525         }, {
526                 /* For i.MX27 TO2, it is the MPLL path 2 of ARM core
527                  * It provide the clock source whose rate is same MPLL * 2/3
528                  */
529                 .name = "mpll_main",
530                 .id = 1,
531                 .parent = &mpll_clk,
532                 .get_rate = _clk_mpll_main_get_rate
533         }
534 };
535
536 static unsigned long get_spll_clk(struct clk *clk)
537 {
538         uint32_t reg;
539         unsigned long ref_clk;
540
541         ref_clk = clk_get_rate(clk->parent);
542
543         reg = __raw_readl(CCM_SPCTL0);
544
545         /* On TO2 we have to write the value back. Otherwise we
546          * read 0 from this register the next time.
547          */
548         if (mx27_revision() >= CHIP_REV_2_0)
549                 __raw_writel(reg, CCM_SPCTL0);
550
551         return mxc_decode_pll(reg, ref_clk);
552 }
553
554 static struct clk spll_clk = {
555         .name = "spll",
556         .parent = &ckih_clk,
557         .get_rate = get_spll_clk,
558         .enable = _clk_spll_enable,
559         .disable = _clk_spll_disable,
560 };
561
562 static unsigned long get_cpu_clk(struct clk *clk)
563 {
564         u32 div;
565         unsigned long rate;
566
567         if (mx27_revision() >= CHIP_REV_2_0)
568                 div = (CSCR() & CCM_CSCR_ARM_MASK) >> CCM_CSCR_ARM_OFFSET;
569         else
570                 div = (CSCR() & CCM_CSCR_PRESC_MASK) >> CCM_CSCR_PRESC_OFFSET;
571
572         rate = clk_get_rate(clk->parent);
573         return rate / (div + 1);
574 }
575
576 static struct clk cpu_clk = {
577         .name = "cpu_clk",
578         .parent = &mpll_main_clk[1],
579         .set_parent = _clk_cpu_set_parent,
580         .round_rate = _clk_cpu_round_rate,
581         .get_rate = get_cpu_clk,
582         .set_rate = _clk_cpu_set_rate,
583 };
584
585 static unsigned long get_ahb_clk(struct clk *clk)
586 {
587         unsigned long rate;
588         unsigned long bclk_pdf;
589
590         if (mx27_revision() >= CHIP_REV_2_0)
591                 bclk_pdf = (CSCR() & CCM_CSCR_AHB_MASK)
592                                         >> CCM_CSCR_AHB_OFFSET;
593         else
594                 bclk_pdf = (CSCR() & CCM_CSCR_BCLK_MASK)
595                                         >> CCM_CSCR_BCLK_OFFSET;
596
597         rate = clk_get_rate(clk->parent);
598         return rate / (bclk_pdf + 1);
599 }
600
601 static struct clk ahb_clk = {
602         .name = "ahb_clk",
603         .parent = &mpll_main_clk[1],
604         .get_rate = get_ahb_clk,
605 };
606
607 static unsigned long get_ipg_clk(struct clk *clk)
608 {
609         unsigned long rate;
610         unsigned long ipg_pdf;
611
612         if (mx27_revision() >= CHIP_REV_2_0)
613                 return clk_get_rate(clk->parent);
614         else
615                 ipg_pdf = (CSCR() & CCM_CSCR_IPDIV) >> CCM_CSCR_IPDIV_OFFSET;
616
617         rate = clk_get_rate(clk->parent);
618         return rate / (ipg_pdf + 1);
619 }
620
621 static struct clk ipg_clk = {
622         .name = "ipg_clk",
623         .parent = &ahb_clk,
624         .get_rate = get_ipg_clk,
625 };
626
627 static unsigned long _clk_perclkx_recalc(struct clk *clk)
628 {
629         unsigned long perclk_pdf;
630         unsigned long parent_rate;
631
632         parent_rate = clk_get_rate(clk->parent);
633
634         if (clk->id < 0 || clk->id > 3)
635                 return 0;
636
637         perclk_pdf = (PCDR1() >> (clk->id << 3)) & CCM_PCDR1_PERDIV1_MASK;
638
639         return parent_rate / (perclk_pdf + 1);
640 }
641
642 static struct clk per_clk[] = {
643         {
644                 .name = "per_clk",
645                 .id = 0,
646                 .parent = &mpll_main_clk[1],
647                 .get_rate = _clk_perclkx_recalc,
648                 .enable = _clk_enable,
649                 .enable_reg = CCM_PCCR1,
650                 .enable_shift = CCM_PCCR1_PERCLK1_OFFSET,
651                 .disable = _clk_disable,
652         }, {
653                 .name = "per_clk",
654                 .id = 1,
655                 .parent = &mpll_main_clk[1],
656                 .get_rate = _clk_perclkx_recalc,
657                 .enable = _clk_enable,
658                 .enable_reg = CCM_PCCR1,
659                 .enable_shift = CCM_PCCR1_PERCLK2_OFFSET,
660                 .disable = _clk_disable,
661         }, {
662                 .name = "per_clk",
663                 .id = 2,
664                 .parent = &mpll_main_clk[1],
665                 .round_rate = _clk_perclkx_round_rate,
666                 .set_rate = _clk_perclkx_set_rate,
667                 .get_rate = _clk_perclkx_recalc,
668                 .enable = _clk_enable,
669                 .enable_reg = CCM_PCCR1,
670                 .enable_shift = CCM_PCCR1_PERCLK3_OFFSET,
671                 .disable = _clk_disable,
672         }, {
673                 .name = "per_clk",
674                 .id = 3,
675                 .parent = &mpll_main_clk[1],
676                 .round_rate = _clk_perclkx_round_rate,
677                 .set_rate = _clk_perclkx_set_rate,
678                 .get_rate = _clk_perclkx_recalc,
679                 .enable = _clk_enable,
680                 .enable_reg = CCM_PCCR1,
681                 .enable_shift = CCM_PCCR1_PERCLK4_OFFSET,
682                 .disable = _clk_disable,
683         },
684 };
685
686 struct clk uart1_clk[] = {
687         {
688                 .name = "uart_clk",
689                 .id = 0,
690                 .parent = &per_clk[0],
691                 .secondary = &uart1_clk[1],
692         }, {
693                 .name = "uart_ipg_clk",
694                 .id = 0,
695                 .parent = &ipg_clk,
696                 .enable = _clk_enable,
697                 .enable_reg = CCM_PCCR1,
698                 .enable_shift = CCM_PCCR1_UART1_OFFSET,
699                 .disable = _clk_disable,
700         },
701 };
702
703 struct clk uart2_clk[] = {
704         {
705                 .name = "uart_clk",
706                 .id = 1,
707                 .parent = &per_clk[0],
708                 .secondary = &uart2_clk[1],
709         }, {
710                 .name = "uart_ipg_clk",
711                 .id = 1,
712                 .parent = &ipg_clk,
713                 .enable = _clk_enable,
714                 .enable_reg = CCM_PCCR1,
715                 .enable_shift = CCM_PCCR1_UART2_OFFSET,
716                 .disable = _clk_disable,
717         },
718 };
719
720 struct clk uart3_clk[] = {
721         {
722                 .name = "uart_clk",
723                 .id = 2,
724                 .parent = &per_clk[0],
725                 .secondary = &uart3_clk[1],
726         }, {
727                 .name = "uart_ipg_clk",
728                 .id = 2,
729                 .parent = &ipg_clk,
730                 .enable = _clk_enable,
731                 .enable_reg = CCM_PCCR1,
732                 .enable_shift = CCM_PCCR1_UART3_OFFSET,
733                 .disable = _clk_disable,
734         },
735 };
736
737 struct clk uart4_clk[] = {
738         {
739                 .name = "uart_clk",
740                 .id = 3,
741                 .parent = &per_clk[0],
742                 .secondary = &uart4_clk[1],
743         }, {
744                 .name = "uart_ipg_clk",
745                 .id = 3,
746                 .parent = &ipg_clk,
747                 .enable = _clk_enable,
748                 .enable_reg = CCM_PCCR1,
749                 .enable_shift = CCM_PCCR1_UART4_OFFSET,
750                 .disable = _clk_disable,
751         },
752 };
753
754 struct clk uart5_clk[] = {
755         {
756                 .name = "uart_clk",
757                 .id = 4,
758                 .parent = &per_clk[0],
759                 .secondary = &uart5_clk[1],
760         }, {
761                 .name = "uart_ipg_clk",
762                 .id = 4,
763                 .parent = &ipg_clk,
764                 .enable = _clk_enable,
765                 .enable_reg = CCM_PCCR1,
766                 .enable_shift = CCM_PCCR1_UART5_OFFSET,
767                 .disable = _clk_disable,
768         },
769 };
770
771 struct clk uart6_clk[] = {
772         {
773                 .name = "uart_clk",
774                 .id = 5,
775                 .parent = &per_clk[0],
776                 .secondary = &uart6_clk[1],
777         }, {
778                 .name = "uart_ipg_clk",
779                 .id = 5,
780                 .parent = &ipg_clk,
781                 .enable = _clk_enable,
782                 .enable_reg = CCM_PCCR1,
783                 .enable_shift = CCM_PCCR1_UART6_OFFSET,
784                 .disable = _clk_disable,
785         },
786 };
787
788 static struct clk gpt1_clk[] = {
789         {
790                 .name = "gpt_clk",
791                 .id = 0,
792                 .parent = &per_clk[0],
793                 .secondary = &gpt1_clk[1],
794         }, {
795                 .name = "gpt_ipg_clk",
796                 .id = 0,
797                 .parent = &ipg_clk,
798                 .enable = _clk_enable,
799                 .enable_reg = CCM_PCCR0,
800                 .enable_shift = CCM_PCCR0_GPT1_OFFSET,
801                 .disable = _clk_disable,
802         },
803 };
804
805 static struct clk gpt2_clk[] = {
806         {
807                 .name = "gpt_clk",
808                 .id = 1,
809                 .parent = &per_clk[0],
810                 .secondary = &gpt2_clk[1],
811         }, {
812                 .name = "gpt_ipg_clk",
813                 .id = 1,
814                 .parent = &ipg_clk,
815                 .enable = _clk_enable,
816                 .enable_reg = CCM_PCCR0,
817                 .enable_shift = CCM_PCCR0_GPT2_OFFSET,
818                 .disable = _clk_disable,
819         },
820 };
821
822 static struct clk gpt3_clk[] = {
823         {
824                 .name = "gpt_clk",
825                 .id = 2,
826                 .parent = &per_clk[0],
827                 .secondary = &gpt3_clk[1],
828         }, {
829                 .name = "gpt_ipg_clk",
830                 .id = 2,
831                 .parent = &ipg_clk,
832                 .enable = _clk_enable,
833                 .enable_reg = CCM_PCCR0,
834                 .enable_shift = CCM_PCCR0_GPT3_OFFSET,
835                 .disable = _clk_disable,
836         },
837 };
838
839 static struct clk gpt4_clk[] = {
840         {
841                 .name = "gpt_clk",
842                 .id = 3,
843                 .parent = &per_clk[0],
844                 .secondary = &gpt4_clk[1],
845         }, {
846                 .name = "gpt_ipg_clk",
847                 .id = 3,
848                 .parent = &ipg_clk,
849                 .enable = _clk_enable,
850                 .enable_reg = CCM_PCCR0,
851                 .enable_shift = CCM_PCCR0_GPT4_OFFSET,
852                 .disable = _clk_disable,
853         },
854 };
855
856 static struct clk gpt5_clk[] = {
857         {
858                 .name = "gpt_clk",
859                 .id = 4,
860                 .parent = &per_clk[0],
861                 .secondary = &gpt5_clk[1],
862         }, {
863                 .name = "gpt_ipg_clk",
864                 .id = 4,
865                 .parent = &ipg_clk,
866                 .enable = _clk_enable,
867                 .enable_reg = CCM_PCCR0,
868                 .enable_shift = CCM_PCCR0_GPT5_OFFSET,
869                 .disable = _clk_disable,
870         },
871 };
872
873 static struct clk gpt6_clk[] = {
874         {
875                 .name = "gpt_clk",
876                 .id = 5,
877                 .parent = &per_clk[0],
878                 .secondary = &gpt6_clk[1],
879         }, {
880                 .name = "gpt_ipg_clk",
881                 .id = 5,
882                 .parent = &ipg_clk,
883                 .enable = _clk_enable,
884                 .enable_reg = CCM_PCCR0,
885                 .enable_shift = CCM_PCCR0_GPT6_OFFSET,
886                 .disable = _clk_disable,
887         },
888 };
889
890 static struct clk pwm_clk[] = {
891         {
892                 .name = "pwm_clk",
893                 .parent = &per_clk[0],
894                 .secondary = &pwm_clk[1],
895         }, {
896                 .name = "pwm_clk",
897                 .parent = &ipg_clk,
898                 .enable = _clk_enable,
899                 .enable_reg = CCM_PCCR0,
900                 .enable_shift = CCM_PCCR0_PWM_OFFSET,
901                 .disable = _clk_disable,
902         },
903 };
904
905 static struct clk sdhc1_clk[] = {
906         {
907                 .name = "sdhc_clk",
908                 .id = 0,
909                 .parent = &per_clk[1],
910                 .secondary = &sdhc1_clk[1],
911         }, {
912                 .name = "sdhc_ipg_clk",
913                 .id = 0,
914                 .parent = &ipg_clk,
915                 .enable = _clk_enable,
916                 .enable_reg = CCM_PCCR0,
917                 .enable_shift = CCM_PCCR0_SDHC1_OFFSET,
918                 .disable = _clk_disable,
919         },
920 };
921
922 static struct clk sdhc2_clk[] = {
923         {
924                 .name = "sdhc_clk",
925                 .id = 1,
926                 .parent = &per_clk[1],
927                 .secondary = &sdhc2_clk[1],
928         }, {
929                 .name = "sdhc_ipg_clk",
930                 .id = 1,
931                 .parent = &ipg_clk,
932                 .enable = _clk_enable,
933                 .enable_reg = CCM_PCCR0,
934                 .enable_shift = CCM_PCCR0_SDHC2_OFFSET,
935                 .disable = _clk_disable,
936         },
937 };
938
939 static struct clk sdhc3_clk[] = {
940         {
941                 .name = "sdhc_clk",
942                 .id = 2,
943                 .parent = &per_clk[1],
944                 .secondary = &sdhc3_clk[1],
945         }, {
946                 .name = "sdhc_ipg_clk",
947                 .id = 2,
948                 .parent = &ipg_clk,
949                 .enable = _clk_enable,
950                 .enable_reg = CCM_PCCR0,
951                 .enable_shift = CCM_PCCR0_SDHC3_OFFSET,
952                 .disable = _clk_disable,
953         },
954 };
955
956 static struct clk cspi1_clk[] = {
957         {
958                 .name = "cspi_clk",
959                 .id = 0,
960                 .parent = &per_clk[1],
961                 .secondary = &cspi1_clk[1],
962         }, {
963                 .name = "cspi_ipg_clk",
964                 .id = 0,
965                 .parent = &ipg_clk,
966                 .enable = _clk_enable,
967                 .enable_reg = CCM_PCCR0,
968                 .enable_shift = CCM_PCCR0_CSPI1_OFFSET,
969                 .disable = _clk_disable,
970         },
971 };
972
973 static struct clk cspi2_clk[] = {
974         {
975                 .name = "cspi_clk",
976                 .id = 1,
977                 .parent = &per_clk[1],
978                 .secondary = &cspi2_clk[1],
979         }, {
980                 .name = "cspi_ipg_clk",
981                 .id = 1,
982                 .parent = &ipg_clk,
983                 .enable = _clk_enable,
984                 .enable_reg = CCM_PCCR0,
985                 .enable_shift = CCM_PCCR0_CSPI2_OFFSET,
986                 .disable = _clk_disable,
987         },
988 };
989
990 static struct clk cspi3_clk[] = {
991         {
992                 .name = "cspi_clk",
993                 .id = 2,
994                 .parent = &per_clk[1],
995                 .secondary = &cspi3_clk[1],
996         }, {
997                 .name = "cspi_ipg_clk",
998                 .id = 2,
999                 .parent = &ipg_clk,
1000                 .enable = _clk_enable,
1001                 .enable_reg = CCM_PCCR0,
1002                 .enable_shift = CCM_PCCR0_CSPI3_OFFSET,
1003                 .disable = _clk_disable,
1004         },
1005 };
1006
1007 static struct clk lcdc_clk[] = {
1008         {
1009                 .name = "lcdc_clk",
1010                 .parent = &per_clk[2],
1011                 .secondary = &lcdc_clk[1],
1012                 .round_rate = _clk_parent_round_rate,
1013                 .set_rate = _clk_parent_set_rate,
1014         }, {
1015                 .name = "lcdc_ipg_clk",
1016                 .parent = &ipg_clk,
1017                 .secondary = &lcdc_clk[2],
1018                 .enable = _clk_enable,
1019                 .enable_reg = CCM_PCCR0,
1020                 .enable_shift = CCM_PCCR0_LCDC_OFFSET,
1021                 .disable = _clk_disable,
1022         }, {
1023                 .name = "lcdc_ahb_clk",
1024                 .parent = &ahb_clk,
1025                 .enable = _clk_enable,
1026                 .enable_reg = CCM_PCCR1,
1027                 .enable_shift = CCM_PCCR1_HCLK_LCDC_OFFSET,
1028                 .disable = _clk_disable,
1029         },
1030 };
1031
1032 static struct clk csi_clk[] = {
1033         {
1034                 .name = "csi_perclk",
1035                 .parent = &per_clk[3],
1036                 .secondary = &csi_clk[1],
1037                 .round_rate = _clk_parent_round_rate,
1038                 .set_rate = _clk_parent_set_rate,
1039         }, {
1040                 .name = "csi_ahb_clk",
1041                 .parent = &ahb_clk,
1042                 .enable = _clk_enable,
1043                 .enable_reg = CCM_PCCR1,
1044                 .enable_shift = CCM_PCCR1_HCLK_CSI_OFFSET,
1045                 .disable = _clk_disable,
1046         },
1047 };
1048
1049 static struct clk usb_clk[] = {
1050         {
1051                 .name = "usb_clk",
1052                 .parent = &spll_clk,
1053                 .get_rate = _clk_usb_recalc,
1054                 .enable = _clk_enable,
1055                 .enable_reg = CCM_PCCR1,
1056                 .enable_shift = CCM_PCCR1_USBOTG_OFFSET,
1057                 .disable = _clk_disable,
1058         }, {
1059                 .name = "usb_ahb_clk",
1060                 .parent = &ahb_clk,
1061                 .enable = _clk_enable,
1062                 .enable_reg = CCM_PCCR1,
1063                 .enable_shift = CCM_PCCR1_HCLK_USBOTG_OFFSET,
1064                 .disable = _clk_disable,
1065         }
1066 };
1067
1068 static struct clk ssi1_clk[] = {
1069         {
1070                 .name = "ssi_clk",
1071                 .id = 0,
1072                 .parent = &mpll_main_clk[1],
1073                 .secondary = &ssi1_clk[1],
1074                 .get_rate = _clk_ssi1_recalc,
1075                 .enable = _clk_enable,
1076                 .enable_reg = CCM_PCCR1,
1077                 .enable_shift = CCM_PCCR1_SSI1_BAUD_OFFSET,
1078                 .disable = _clk_disable,
1079         }, {
1080                 .name = "ssi_ipg_clk",
1081                 .id = 0,
1082                 .parent = &ipg_clk,
1083                 .enable = _clk_enable,
1084                 .enable_reg = CCM_PCCR0,
1085                 .enable_shift = CCM_PCCR0_SSI1_IPG_OFFSET,
1086                 .disable = _clk_disable,
1087         },
1088 };
1089
1090 static struct clk ssi2_clk[] = {
1091         {
1092                 .name = "ssi_clk",
1093                 .id = 1,
1094                 .parent = &mpll_main_clk[1],
1095                 .secondary = &ssi2_clk[1],
1096                 .get_rate = _clk_ssi2_recalc,
1097                 .enable = _clk_enable,
1098                 .enable_reg = CCM_PCCR1,
1099                 .enable_shift = CCM_PCCR1_SSI2_BAUD_OFFSET,
1100                 .disable = _clk_disable,
1101         }, {
1102                 .name = "ssi_ipg_clk",
1103                 .id = 1,
1104                 .parent = &ipg_clk,
1105                 .enable = _clk_enable,
1106                 .enable_reg = CCM_PCCR0,
1107                 .enable_shift = CCM_PCCR0_SSI2_IPG_OFFSET,
1108                 .disable = _clk_disable,
1109         },
1110 };
1111
1112 static struct clk nfc_clk = {
1113         .name = "nfc_clk",
1114         .parent = &cpu_clk,
1115         .get_rate = _clk_nfc_recalc,
1116         .enable = _clk_enable,
1117         .enable_reg = CCM_PCCR1,
1118         .enable_shift = CCM_PCCR1_NFC_BAUD_OFFSET,
1119         .disable = _clk_disable,
1120 };
1121
1122 static struct clk vpu_clk = {
1123         .name = "vpu_clk",
1124         .parent = &mpll_main_clk[1],
1125         .get_rate = _clk_vpu_recalc,
1126         .enable = _clk_vpu_enable,
1127         .disable = _clk_vpu_disable,
1128 };
1129
1130 static struct clk dma_clk = {
1131         .name = "dma_clk",
1132         .parent = &ahb_clk,
1133         .enable = _clk_dma_enable,
1134         .disable = _clk_dma_disable,
1135 };
1136
1137 static struct clk rtic_clk = {
1138         .name = "rtic_clk",
1139         .parent = &ahb_clk,
1140         .enable = _clk_rtic_enable,
1141         .disable = _clk_rtic_disable,
1142 };
1143
1144 static struct clk brom_clk = {
1145         .name = "brom_clk",
1146         .parent = &ahb_clk,
1147         .enable = _clk_enable,
1148         .enable_reg = CCM_PCCR1,
1149         .enable_shift = CCM_PCCR1_HCLK_BROM_OFFSET,
1150         .disable = _clk_disable,
1151 };
1152
1153 static struct clk emma_clk = {
1154         .name = "emma_clk",
1155         .parent = &ahb_clk,
1156         .enable = _clk_emma_enable,
1157         .disable = _clk_emma_disable,
1158 };
1159
1160 static struct clk slcdc_clk = {
1161         .name = "slcdc_clk",
1162         .parent = &ahb_clk,
1163         .enable = _clk_slcdc_enable,
1164         .disable = _clk_slcdc_disable,
1165 };
1166
1167 static struct clk fec_clk = {
1168         .name = "fec_clk",
1169         .parent = &ahb_clk,
1170         .enable = _clk_fec_enable,
1171         .disable = _clk_fec_disable,
1172 };
1173
1174 static struct clk emi_clk = {
1175         .name = "emi_clk",
1176         .parent = &ahb_clk,
1177         .enable = _clk_enable,
1178         .enable_reg = CCM_PCCR1,
1179         .enable_shift = CCM_PCCR1_HCLK_EMI_OFFSET,
1180         .disable = _clk_disable,
1181 };
1182
1183 static struct clk sahara2_clk = {
1184         .name = "sahara_clk",
1185         .parent = &ahb_clk,
1186         .enable = _clk_sahara2_enable,
1187         .disable = _clk_sahara2_disable,
1188 };
1189
1190 static struct clk ata_clk = {
1191         .name = "ata_clk",
1192         .parent = &ahb_clk,
1193         .enable = _clk_enable,
1194         .enable_reg = CCM_PCCR1,
1195         .enable_shift = CCM_PCCR1_HCLK_ATA_OFFSET,
1196         .disable = _clk_disable,
1197 };
1198
1199 static struct clk mstick1_clk = {
1200         .name = "mstick1_clk",
1201         .parent = &ipg_clk,
1202         .enable = _clk_mstick1_enable,
1203         .disable = _clk_mstick1_disable,
1204 };
1205
1206 static struct clk wdog_clk = {
1207         .name = "wdog_clk",
1208         .parent = &ipg_clk,
1209         .enable = _clk_enable,
1210         .enable_reg = CCM_PCCR1,
1211         .enable_shift = CCM_PCCR1_WDT_OFFSET,
1212         .disable = _clk_disable,
1213 };
1214
1215 static struct clk gpio_clk = {
1216         .name = "gpio_clk",
1217         .parent = &ipg_clk,
1218         .enable = _clk_enable,
1219         .enable_reg = CCM_PCCR1,
1220         .enable_shift = CCM_PCCR0_GPIO_OFFSET,
1221         .disable = _clk_disable,
1222 };
1223
1224 static struct clk i2c_clk[] = {
1225         {
1226                 .name = "i2c_clk",
1227                 .id = 0,
1228                 .parent = &ipg_clk,
1229                 .enable = _clk_enable,
1230                 .enable_reg = CCM_PCCR0,
1231                 .enable_shift = CCM_PCCR0_I2C1_OFFSET,
1232                 .disable = _clk_disable,
1233         }, {
1234                 .name = "i2c_clk",
1235                 .id = 1,
1236                 .parent = &ipg_clk,
1237                 .enable = _clk_enable,
1238                 .enable_reg = CCM_PCCR0,
1239                 .enable_shift = CCM_PCCR0_I2C2_OFFSET,
1240                 .disable = _clk_disable,
1241         },
1242 };
1243
1244 static struct clk iim_clk = {
1245         .name = "iim_clk",
1246         .parent = &ipg_clk,
1247         .enable = _clk_enable,
1248         .enable_reg = CCM_PCCR0,
1249         .enable_shift = CCM_PCCR0_IIM_OFFSET,
1250         .disable = _clk_disable,
1251 };
1252
1253 static struct clk kpp_clk = {
1254         .name = "kpp_clk",
1255         .parent = &ipg_clk,
1256         .enable = _clk_enable,
1257         .enable_reg = CCM_PCCR0,
1258         .enable_shift = CCM_PCCR0_KPP_OFFSET,
1259         .disable = _clk_disable,
1260 };
1261
1262 static struct clk owire_clk = {
1263         .name = "owire_clk",
1264         .parent = &ipg_clk,
1265         .enable = _clk_enable,
1266         .enable_reg = CCM_PCCR0,
1267         .enable_shift = CCM_PCCR0_OWIRE_OFFSET,
1268         .disable = _clk_disable,
1269 };
1270
1271 static struct clk rtc_clk = {
1272         .name = "rtc_clk",
1273         .parent = &ipg_clk,
1274         .enable = _clk_enable,
1275         .enable_reg = CCM_PCCR0,
1276         .enable_shift = CCM_PCCR0_RTC_OFFSET,
1277         .disable = _clk_disable,
1278 };
1279
1280 static struct clk scc_clk = {
1281         .name = "scc_clk",
1282         .parent = &ipg_clk,
1283         .enable = _clk_enable,
1284         .enable_reg = CCM_PCCR0,
1285         .enable_shift = CCM_PCCR0_SCC_OFFSET,
1286         .disable = _clk_disable,
1287 };
1288
1289 static unsigned long _clk_clko_round_rate(struct clk *clk, unsigned long rate)
1290 {
1291         u32 div;
1292         unsigned long parent_rate;
1293
1294         parent_rate = clk_get_rate(clk->parent);
1295         div = parent_rate / rate;
1296         if (parent_rate % rate)
1297                 div++;
1298
1299         if (div > 8)
1300                 div = 8;
1301
1302         return parent_rate / div;
1303 }
1304
1305 static int _clk_clko_set_rate(struct clk *clk, unsigned long rate)
1306 {
1307         u32 reg;
1308         u32 div;
1309         unsigned long parent_rate;
1310
1311         parent_rate = clk_get_rate(clk->parent);
1312
1313         div = parent_rate / rate;
1314
1315         if (div > 8 || div < 1 || ((parent_rate / div) != rate))
1316                 return -EINVAL;
1317         div--;
1318
1319         reg = __raw_readl(CCM_PCDR0) & ~CCM_PCDR0_CLKODIV_MASK;
1320         reg |= div << CCM_PCDR0_CLKODIV_OFFSET;
1321         __raw_writel(reg, CCM_PCDR0);
1322
1323         return 0;
1324 }
1325
1326 static unsigned long _clk_clko_recalc(struct clk *clk)
1327 {
1328         u32 div;
1329         unsigned long parent_rate;
1330
1331         parent_rate = clk_get_rate(clk->parent);
1332
1333         div = __raw_readl(CCM_PCDR0) & CCM_PCDR0_CLKODIV_MASK >>
1334                 CCM_PCDR0_CLKODIV_OFFSET;
1335         div++;
1336
1337         return parent_rate / div;
1338 }
1339
1340 static int _clk_clko_set_parent(struct clk *clk, struct clk *parent)
1341 {
1342         u32 reg;
1343
1344         reg = __raw_readl(CCM_CCSR) & ~CCM_CCSR_CLKOSEL_MASK;
1345
1346         if (parent == &ckil_clk)
1347                 reg |= 0 << CCM_CCSR_CLKOSEL_OFFSET;
1348         else if (parent == &ckih_clk)
1349                 reg |= 2 << CCM_CCSR_CLKOSEL_OFFSET;
1350         else if (parent == mpll_clk.parent)
1351                 reg |= 3 << CCM_CCSR_CLKOSEL_OFFSET;
1352         else if (parent == spll_clk.parent)
1353                 reg |= 4 << CCM_CCSR_CLKOSEL_OFFSET;
1354         else if (parent == &mpll_clk)
1355                 reg |= 5 << CCM_CCSR_CLKOSEL_OFFSET;
1356         else if (parent == &spll_clk)
1357                 reg |= 6 << CCM_CCSR_CLKOSEL_OFFSET;
1358         else if (parent == &cpu_clk)
1359                 reg |= 7 << CCM_CCSR_CLKOSEL_OFFSET;
1360         else if (parent == &ahb_clk)
1361                 reg |= 8 << CCM_CCSR_CLKOSEL_OFFSET;
1362         else if (parent == &ipg_clk)
1363                 reg |= 9 << CCM_CCSR_CLKOSEL_OFFSET;
1364         else if (parent == &per_clk[0])
1365                 reg |= 0xA << CCM_CCSR_CLKOSEL_OFFSET;
1366         else if (parent == &per_clk[1])
1367                 reg |= 0xB << CCM_CCSR_CLKOSEL_OFFSET;
1368         else if (parent == &per_clk[2])
1369                 reg |= 0xC << CCM_CCSR_CLKOSEL_OFFSET;
1370         else if (parent == &per_clk[3])
1371                 reg |= 0xD << CCM_CCSR_CLKOSEL_OFFSET;
1372         else if (parent == &ssi1_clk[0])
1373                 reg |= 0xE << CCM_CCSR_CLKOSEL_OFFSET;
1374         else if (parent == &ssi2_clk[0])
1375                 reg |= 0xF << CCM_CCSR_CLKOSEL_OFFSET;
1376         else if (parent == &nfc_clk)
1377                 reg |= 0x10 << CCM_CCSR_CLKOSEL_OFFSET;
1378         else if (parent == &mstick1_clk)
1379                 reg |= 0x11 << CCM_CCSR_CLKOSEL_OFFSET;
1380         else if (parent == &vpu_clk)
1381                 reg |= 0x12 << CCM_CCSR_CLKOSEL_OFFSET;
1382         else if (parent == &usb_clk[0])
1383                 reg |= 0x15 << CCM_CCSR_CLKOSEL_OFFSET;
1384         else
1385                 return -EINVAL;
1386
1387         __raw_writel(reg, CCM_CCSR);
1388
1389         return 0;
1390 }
1391
1392 static int _clk_clko_enable(struct clk *clk)
1393 {
1394         u32 reg;
1395
1396         reg = __raw_readl(CCM_PCDR0) | CCM_PCDR0_CLKO_EN;
1397         __raw_writel(reg, CCM_PCDR0);
1398
1399         return 0;
1400 }
1401
1402 static void _clk_clko_disable(struct clk *clk)
1403 {
1404         u32 reg;
1405
1406         reg = __raw_readl(CCM_PCDR0) & ~CCM_PCDR0_CLKO_EN;
1407         __raw_writel(reg, CCM_PCDR0);
1408 }
1409
1410 static struct clk clko_clk = {
1411         .name = "clko_clk",
1412         .get_rate = _clk_clko_recalc,
1413         .set_rate = _clk_clko_set_rate,
1414         .round_rate = _clk_clko_round_rate,
1415         .set_parent = _clk_clko_set_parent,
1416         .enable = _clk_clko_enable,
1417         .disable = _clk_clko_disable,
1418 };
1419
1420 static struct clk *mxc_clks[] = {
1421         &ckih_clk,
1422         &ckil_clk,
1423         &mpll_clk,
1424         &mpll_main_clk[0],
1425         &mpll_main_clk[1],
1426         &spll_clk,
1427         &cpu_clk,
1428         &ahb_clk,
1429         &ipg_clk,
1430         &per_clk[0],
1431         &per_clk[1],
1432         &per_clk[2],
1433         &per_clk[3],
1434         &clko_clk,
1435         &uart1_clk[0],
1436         &uart1_clk[1],
1437         &uart2_clk[0],
1438         &uart2_clk[1],
1439         &uart3_clk[0],
1440         &uart3_clk[1],
1441         &uart4_clk[0],
1442         &uart4_clk[1],
1443         &uart5_clk[0],
1444         &uart5_clk[1],
1445         &uart6_clk[0],
1446         &uart6_clk[1],
1447         &gpt1_clk[0],
1448         &gpt1_clk[1],
1449         &gpt2_clk[0],
1450         &gpt2_clk[1],
1451         &gpt3_clk[0],
1452         &gpt3_clk[1],
1453         &gpt4_clk[0],
1454         &gpt4_clk[1],
1455         &gpt5_clk[0],
1456         &gpt5_clk[1],
1457         &gpt6_clk[0],
1458         &gpt6_clk[1],
1459         &pwm_clk[0],
1460         &pwm_clk[1],
1461         &sdhc1_clk[0],
1462         &sdhc1_clk[1],
1463         &sdhc2_clk[0],
1464         &sdhc2_clk[1],
1465         &sdhc3_clk[0],
1466         &sdhc3_clk[1],
1467         &cspi1_clk[0],
1468         &cspi1_clk[1],
1469         &cspi2_clk[0],
1470         &cspi2_clk[1],
1471         &cspi3_clk[0],
1472         &cspi3_clk[1],
1473         &lcdc_clk[0],
1474         &lcdc_clk[1],
1475         &lcdc_clk[2],
1476         &csi_clk[0],
1477         &csi_clk[1],
1478         &usb_clk[0],
1479         &usb_clk[1],
1480         &ssi1_clk[0],
1481         &ssi1_clk[1],
1482         &ssi2_clk[0],
1483         &ssi2_clk[1],
1484         &nfc_clk,
1485         &vpu_clk,
1486         &dma_clk,
1487         &rtic_clk,
1488         &brom_clk,
1489         &emma_clk,
1490         &slcdc_clk,
1491         &fec_clk,
1492         &emi_clk,
1493         &sahara2_clk,
1494         &ata_clk,
1495         &mstick1_clk,
1496         &wdog_clk,
1497         &gpio_clk,
1498         &i2c_clk[0],
1499         &i2c_clk[1],
1500         &iim_clk,
1501         &kpp_clk,
1502         &owire_clk,
1503         &rtc_clk,
1504         &scc_clk,
1505 };
1506
1507 void __init change_external_low_reference(unsigned long new_ref)
1508 {
1509         external_low_reference = new_ref;
1510 }
1511
1512 unsigned long __init clk_early_get_timer_rate(void)
1513 {
1514         return clk_get_rate(&per_clk[0]);
1515 }
1516
1517 static void __init probe_mxc_clocks(void)
1518 {
1519         int i;
1520
1521         if (mx27_revision() >= CHIP_REV_2_0) {
1522                 if (CSCR() & 0x8000)
1523                         cpu_clk.parent = &mpll_main_clk[0];
1524
1525                 if (!(CSCR() & 0x00800000))
1526                         ssi2_clk[0].parent = &spll_clk;
1527
1528                 if (!(CSCR() & 0x00400000))
1529                         ssi1_clk[0].parent = &spll_clk;
1530
1531                 if (!(CSCR() & 0x00200000))
1532                         vpu_clk.parent = &spll_clk;
1533         } else {
1534                 cpu_clk.parent = &mpll_clk;
1535                 cpu_clk.set_parent = NULL;
1536                 cpu_clk.round_rate = NULL;
1537                 cpu_clk.set_rate = NULL;
1538                 ahb_clk.parent = &mpll_clk;
1539
1540                 for (i = 0; i < sizeof(per_clk) / sizeof(per_clk[0]); i++)
1541                         per_clk[i].parent = &mpll_clk;
1542
1543                 ssi1_clk[0].parent = &mpll_clk;
1544                 ssi2_clk[0].parent = &mpll_clk;
1545
1546                 vpu_clk.parent = &mpll_clk;
1547         }
1548 }
1549
1550 /*
1551  * must be called very early to get information about the
1552  * available clock rate when the timer framework starts
1553  */
1554 int __init mxc_clocks_init(unsigned long fref)
1555 {
1556         u32 cscr;
1557         struct clk **clkp;
1558
1559         external_high_reference = fref;
1560
1561         /* detect clock reference for both system PLL */
1562         cscr = CSCR();
1563         if (cscr & CCM_CSCR_MCU)
1564                 mpll_clk.parent = &ckih_clk;
1565         else
1566                 mpll_clk.parent = &ckil_clk;
1567
1568         if (cscr & CCM_CSCR_SP)
1569                 spll_clk.parent = &ckih_clk;
1570         else
1571                 spll_clk.parent = &ckil_clk;
1572
1573         probe_mxc_clocks();
1574
1575         per_clk[0].enable(&per_clk[0]);
1576         gpt1_clk[1].enable(&gpt1_clk[1]);
1577
1578         for (clkp = mxc_clks; clkp < mxc_clks + ARRAY_SIZE(mxc_clks); clkp++)
1579                 clk_register(*clkp);
1580
1581         /* Turn off all possible clocks */
1582         __raw_writel(CCM_PCCR0_GPT1_MASK, CCM_PCCR0);
1583         __raw_writel(CCM_PCCR1_PERCLK1_MASK | CCM_PCCR1_HCLK_EMI_MASK,
1584                      CCM_PCCR1);
1585         spll_clk.disable(&spll_clk);
1586
1587         /* This will propagate to all children and init all the clock rates */
1588
1589         clk_enable(&emi_clk);
1590         clk_enable(&gpio_clk);
1591         clk_enable(&iim_clk);
1592         clk_enable(&gpt1_clk[0]);
1593 #ifdef CONFIG_DEBUG_LL_CONSOLE
1594         clk_enable(&uart1_clk[0]);
1595 #endif
1596         return 0;
1597 }