[ARM] MXC: Use a single function for decoding a PLL
[linux-2.6.git] / arch / arm / mach-mx3 / clock.c
1 /*
2  * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
3  * Copyright (C) 2008 by Sascha Hauer <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/module.h>
21 #include <linux/spinlock.h>
22 #include <linux/delay.h>
23 #include <linux/clk.h>
24 #include <linux/err.h>
25 #include <linux/io.h>
26 #include <mach/clock.h>
27 #include <mach/hardware.h>
28 #include <asm/div64.h>
29
30 #include "crm_regs.h"
31
32 #define PRE_DIV_MIN_FREQ    10000000 /* Minimum Frequency after Predivider */
33
34 static void __calc_pre_post_dividers(u32 div, u32 *pre, u32 *post)
35 {
36         u32 min_pre, temp_pre, old_err, err;
37
38         if (div >= 512) {
39                 *pre = 8;
40                 *post = 64;
41         } else if (div >= 64) {
42                 min_pre = (div - 1) / 64 + 1;
43                 old_err = 8;
44                 for (temp_pre = 8; temp_pre >= min_pre; temp_pre--) {
45                         err = div % temp_pre;
46                         if (err == 0) {
47                                 *pre = temp_pre;
48                                 break;
49                         }
50                         err = temp_pre - err;
51                         if (err < old_err) {
52                                 old_err = err;
53                                 *pre = temp_pre;
54                         }
55                 }
56                 *post = (div + *pre - 1) / *pre;
57         } else if (div <= 8) {
58                 *pre = div;
59                 *post = 1;
60         } else {
61                 *pre = 1;
62                 *post = div;
63         }
64 }
65
66 static struct clk mcu_pll_clk;
67 static struct clk mcu_main_clk;
68 static struct clk usb_pll_clk;
69 static struct clk serial_pll_clk;
70 static struct clk ipg_clk;
71 static struct clk ckih_clk;
72 static struct clk ahb_clk;
73
74 static int _clk_enable(struct clk *clk)
75 {
76         u32 reg;
77
78         reg = __raw_readl(clk->enable_reg);
79         reg |= 3 << clk->enable_shift;
80         __raw_writel(reg, clk->enable_reg);
81
82         return 0;
83 }
84
85 static void _clk_disable(struct clk *clk)
86 {
87         u32 reg;
88
89         reg = __raw_readl(clk->enable_reg);
90         reg &= ~(3 << clk->enable_shift);
91         __raw_writel(reg, clk->enable_reg);
92 }
93
94 static void _clk_emi_disable(struct clk *clk)
95 {
96         u32 reg;
97
98         reg = __raw_readl(clk->enable_reg);
99         reg &= ~(3 << clk->enable_shift);
100         reg |= (1 << clk->enable_shift);
101         __raw_writel(reg, clk->enable_reg);
102 }
103
104 static int _clk_pll_set_rate(struct clk *clk, unsigned long rate)
105 {
106         u32 reg;
107         signed long pd = 1;     /* Pre-divider */
108         signed long mfi;        /* Multiplication Factor (Integer part) */
109         signed long mfn;        /* Multiplication Factor (Integer part) */
110         signed long mfd;        /* Multiplication Factor (Denominator Part) */
111         signed long tmp;
112         u32 ref_freq = clk_get_rate(clk->parent);
113
114         while (((ref_freq / pd) * 10) > rate)
115                 pd++;
116
117         if ((ref_freq / pd) < PRE_DIV_MIN_FREQ)
118                 return -EINVAL;
119
120         /* the ref_freq/2 in the following is to round up */
121         mfi = (((rate / 2) * pd) + (ref_freq / 2)) / ref_freq;
122         if (mfi < 5 || mfi > 15)
123                 return -EINVAL;
124
125         /* pick a mfd value that will work
126          * then solve for mfn */
127         mfd = ref_freq / 50000;
128
129         /*
130          *          pll_freq * pd * mfd
131          *   mfn = --------------------  -  (mfi * mfd)
132          *           2 * ref_freq
133          */
134         /* the tmp/2 is for rounding */
135         tmp = ref_freq / 10000;
136         mfn =
137             ((((((rate / 2) + (tmp / 2)) / tmp) * pd) * mfd) / 10000) -
138             (mfi * mfd);
139
140         mfn = mfn & 0x3ff;
141         pd--;
142         mfd--;
143
144         /* Change the Pll value */
145         reg = (mfi << MXC_CCM_PCTL_MFI_OFFSET) |
146             (mfn << MXC_CCM_PCTL_MFN_OFFSET) |
147             (mfd << MXC_CCM_PCTL_MFD_OFFSET) | (pd << MXC_CCM_PCTL_PD_OFFSET);
148
149         if (clk == &mcu_pll_clk)
150                 __raw_writel(reg, MXC_CCM_MPCTL);
151         else if (clk == &usb_pll_clk)
152                 __raw_writel(reg, MXC_CCM_UPCTL);
153         else if (clk == &serial_pll_clk)
154                 __raw_writel(reg, MXC_CCM_SRPCTL);
155
156         return 0;
157 }
158
159 static unsigned long _clk_pll_get_rate(struct clk *clk)
160 {
161         unsigned long reg, ccmr;
162         unsigned int prcs, ref_clk;
163
164         ccmr = __raw_readl(MXC_CCM_CCMR);
165         prcs = (ccmr & MXC_CCM_CCMR_PRCS_MASK) >> MXC_CCM_CCMR_PRCS_OFFSET;
166         if (prcs == 0x1)
167                 ref_clk = CKIL_CLK_FREQ * 1024;
168         else
169                 ref_clk = clk_get_rate(&ckih_clk);
170
171         if (clk == &mcu_pll_clk) {
172                 if ((ccmr & MXC_CCM_CCMR_MPE) == 0)
173                         return ref_clk;
174                 if ((ccmr & MXC_CCM_CCMR_MDS) != 0)
175                         return ref_clk;
176                 reg = __raw_readl(MXC_CCM_MPCTL);
177         } else if (clk == &usb_pll_clk)
178                 reg = __raw_readl(MXC_CCM_UPCTL);
179         else if (clk == &serial_pll_clk)
180                 reg = __raw_readl(MXC_CCM_SRPCTL);
181         else {
182                 BUG();
183                 return 0;
184         }
185
186         return mxc_decode_pll(reg, ref_clk);
187 }
188
189 static int _clk_usb_pll_enable(struct clk *clk)
190 {
191         u32 reg;
192
193         reg = __raw_readl(MXC_CCM_CCMR);
194         reg |= MXC_CCM_CCMR_UPE;
195         __raw_writel(reg, MXC_CCM_CCMR);
196
197         /* No lock bit on MX31, so using max time from spec */
198         udelay(80);
199
200         return 0;
201 }
202
203 static void _clk_usb_pll_disable(struct clk *clk)
204 {
205         u32 reg;
206
207         reg = __raw_readl(MXC_CCM_CCMR);
208         reg &= ~MXC_CCM_CCMR_UPE;
209         __raw_writel(reg, MXC_CCM_CCMR);
210 }
211
212 static int _clk_serial_pll_enable(struct clk *clk)
213 {
214         u32 reg;
215
216         reg = __raw_readl(MXC_CCM_CCMR);
217         reg |= MXC_CCM_CCMR_SPE;
218         __raw_writel(reg, MXC_CCM_CCMR);
219
220         /* No lock bit on MX31, so using max time from spec */
221         udelay(80);
222
223         return 0;
224 }
225
226 static void _clk_serial_pll_disable(struct clk *clk)
227 {
228         u32 reg;
229
230         reg = __raw_readl(MXC_CCM_CCMR);
231         reg &= ~MXC_CCM_CCMR_SPE;
232         __raw_writel(reg, MXC_CCM_CCMR);
233 }
234
235 #define PDR0(mask, off) ((__raw_readl(MXC_CCM_PDR0) & mask) >> off)
236 #define PDR1(mask, off) ((__raw_readl(MXC_CCM_PDR1) & mask) >> off)
237 #define PDR2(mask, off) ((__raw_readl(MXC_CCM_PDR2) & mask) >> off)
238
239 static unsigned long _clk_mcu_main_get_rate(struct clk *clk)
240 {
241         u32 pmcr0 = __raw_readl(MXC_CCM_PMCR0);
242
243         if ((pmcr0 & MXC_CCM_PMCR0_DFSUP1) == MXC_CCM_PMCR0_DFSUP1_SPLL)
244                 return clk_get_rate(&serial_pll_clk);
245         else
246                 return clk_get_rate(&mcu_pll_clk);
247 }
248
249 static unsigned long _clk_hclk_get_rate(struct clk *clk)
250 {
251         unsigned long max_pdf;
252
253         max_pdf = PDR0(MXC_CCM_PDR0_MAX_PODF_MASK,
254                        MXC_CCM_PDR0_MAX_PODF_OFFSET);
255         return clk_get_rate(clk->parent) / (max_pdf + 1);
256 }
257
258 static unsigned long _clk_ipg_get_rate(struct clk *clk)
259 {
260         unsigned long ipg_pdf;
261
262         ipg_pdf = PDR0(MXC_CCM_PDR0_IPG_PODF_MASK,
263                        MXC_CCM_PDR0_IPG_PODF_OFFSET);
264         return clk_get_rate(clk->parent) / (ipg_pdf + 1);
265 }
266
267 static unsigned long _clk_nfc_get_rate(struct clk *clk)
268 {
269         unsigned long nfc_pdf;
270
271         nfc_pdf = PDR0(MXC_CCM_PDR0_NFC_PODF_MASK,
272                        MXC_CCM_PDR0_NFC_PODF_OFFSET);
273         return clk_get_rate(clk->parent) / (nfc_pdf + 1);
274 }
275
276 static unsigned long _clk_hsp_get_rate(struct clk *clk)
277 {
278         unsigned long hsp_pdf;
279
280         hsp_pdf = PDR0(MXC_CCM_PDR0_HSP_PODF_MASK,
281                        MXC_CCM_PDR0_HSP_PODF_OFFSET);
282         return clk_get_rate(clk->parent) / (hsp_pdf + 1);
283 }
284
285 static unsigned long _clk_usb_get_rate(struct clk *clk)
286 {
287         unsigned long usb_pdf, usb_prepdf;
288
289         usb_pdf = PDR1(MXC_CCM_PDR1_USB_PODF_MASK,
290                        MXC_CCM_PDR1_USB_PODF_OFFSET);
291         usb_prepdf = PDR1(MXC_CCM_PDR1_USB_PRDF_MASK,
292                           MXC_CCM_PDR1_USB_PRDF_OFFSET);
293         return clk_get_rate(clk->parent) / (usb_prepdf + 1) / (usb_pdf + 1);
294 }
295
296 static unsigned long _clk_csi_get_rate(struct clk *clk)
297 {
298         u32 reg, pre, post;
299
300         reg = __raw_readl(MXC_CCM_PDR0);
301         pre = (reg & MXC_CCM_PDR0_CSI_PRDF_MASK) >>
302             MXC_CCM_PDR0_CSI_PRDF_OFFSET;
303         pre++;
304         post = (reg & MXC_CCM_PDR0_CSI_PODF_MASK) >>
305             MXC_CCM_PDR0_CSI_PODF_OFFSET;
306         post++;
307         return clk_get_rate(clk->parent) / (pre * post);
308 }
309
310 static unsigned long _clk_csi_round_rate(struct clk *clk, unsigned long rate)
311 {
312         u32 pre, post, parent = clk_get_rate(clk->parent);
313         u32 div = parent / rate;
314
315         if (parent % rate)
316                 div++;
317
318         __calc_pre_post_dividers(div, &pre, &post);
319
320         return parent / (pre * post);
321 }
322
323 static int _clk_csi_set_rate(struct clk *clk, unsigned long rate)
324 {
325         u32 reg, div, pre, post, parent = clk_get_rate(clk->parent);
326
327         div = parent / rate;
328
329         if ((parent / div) != rate)
330                 return -EINVAL;
331
332         __calc_pre_post_dividers(div, &pre, &post);
333
334         /* Set CSI clock divider */
335         reg = __raw_readl(MXC_CCM_PDR0) &
336             ~(MXC_CCM_PDR0_CSI_PODF_MASK | MXC_CCM_PDR0_CSI_PRDF_MASK);
337         reg |= (post - 1) << MXC_CCM_PDR0_CSI_PODF_OFFSET;
338         reg |= (pre - 1) << MXC_CCM_PDR0_CSI_PRDF_OFFSET;
339         __raw_writel(reg, MXC_CCM_PDR0);
340
341         return 0;
342 }
343
344 static unsigned long _clk_per_get_rate(struct clk *clk)
345 {
346         unsigned long per_pdf;
347
348         per_pdf = PDR0(MXC_CCM_PDR0_PER_PODF_MASK,
349                        MXC_CCM_PDR0_PER_PODF_OFFSET);
350         return clk_get_rate(clk->parent) / (per_pdf + 1);
351 }
352
353 static unsigned long _clk_ssi1_get_rate(struct clk *clk)
354 {
355         unsigned long ssi1_pdf, ssi1_prepdf;
356
357         ssi1_pdf = PDR1(MXC_CCM_PDR1_SSI1_PODF_MASK,
358                         MXC_CCM_PDR1_SSI1_PODF_OFFSET);
359         ssi1_prepdf = PDR1(MXC_CCM_PDR1_SSI1_PRE_PODF_MASK,
360                            MXC_CCM_PDR1_SSI1_PRE_PODF_OFFSET);
361         return clk_get_rate(clk->parent) / (ssi1_prepdf + 1) / (ssi1_pdf + 1);
362 }
363
364 static unsigned long _clk_ssi2_get_rate(struct clk *clk)
365 {
366         unsigned long ssi2_pdf, ssi2_prepdf;
367
368         ssi2_pdf = PDR1(MXC_CCM_PDR1_SSI2_PODF_MASK,
369                         MXC_CCM_PDR1_SSI2_PODF_OFFSET);
370         ssi2_prepdf = PDR1(MXC_CCM_PDR1_SSI2_PRE_PODF_MASK,
371                            MXC_CCM_PDR1_SSI2_PRE_PODF_OFFSET);
372         return clk_get_rate(clk->parent) / (ssi2_prepdf + 1) / (ssi2_pdf + 1);
373 }
374
375 static unsigned long _clk_firi_get_rate(struct clk *clk)
376 {
377         unsigned long firi_pdf, firi_prepdf;
378
379         firi_pdf = PDR1(MXC_CCM_PDR1_FIRI_PODF_MASK,
380                         MXC_CCM_PDR1_FIRI_PODF_OFFSET);
381         firi_prepdf = PDR1(MXC_CCM_PDR1_FIRI_PRE_PODF_MASK,
382                            MXC_CCM_PDR1_FIRI_PRE_PODF_OFFSET);
383         return clk_get_rate(clk->parent) / (firi_prepdf + 1) / (firi_pdf + 1);
384 }
385
386 static unsigned long _clk_firi_round_rate(struct clk *clk, unsigned long rate)
387 {
388         u32 pre, post;
389         u32 parent = clk_get_rate(clk->parent);
390         u32 div = parent / rate;
391
392         if (parent % rate)
393                 div++;
394
395         __calc_pre_post_dividers(div, &pre, &post);
396
397         return parent / (pre * post);
398
399 }
400
401 static int _clk_firi_set_rate(struct clk *clk, unsigned long rate)
402 {
403         u32 reg, div, pre, post, parent = clk_get_rate(clk->parent);
404
405         div = parent / rate;
406
407         if ((parent / div) != rate)
408                 return -EINVAL;
409
410         __calc_pre_post_dividers(div, &pre, &post);
411
412         /* Set FIRI clock divider */
413         reg = __raw_readl(MXC_CCM_PDR1) &
414             ~(MXC_CCM_PDR1_FIRI_PODF_MASK | MXC_CCM_PDR1_FIRI_PRE_PODF_MASK);
415         reg |= (pre - 1) << MXC_CCM_PDR1_FIRI_PRE_PODF_OFFSET;
416         reg |= (post - 1) << MXC_CCM_PDR1_FIRI_PODF_OFFSET;
417         __raw_writel(reg, MXC_CCM_PDR1);
418
419         return 0;
420 }
421
422 static unsigned long _clk_mbx_get_rate(struct clk *clk)
423 {
424         return clk_get_rate(clk->parent) / 2;
425 }
426
427 static unsigned long _clk_mstick1_get_rate(struct clk *clk)
428 {
429         unsigned long msti_pdf;
430
431         msti_pdf = PDR2(MXC_CCM_PDR2_MST1_PDF_MASK,
432                         MXC_CCM_PDR2_MST1_PDF_OFFSET);
433         return clk_get_rate(clk->parent) / (msti_pdf + 1);
434 }
435
436 static unsigned long _clk_mstick2_get_rate(struct clk *clk)
437 {
438         unsigned long msti_pdf;
439
440         msti_pdf = PDR2(MXC_CCM_PDR2_MST2_PDF_MASK,
441                         MXC_CCM_PDR2_MST2_PDF_OFFSET);
442         return clk_get_rate(clk->parent) / (msti_pdf + 1);
443 }
444
445 static unsigned long ckih_rate;
446
447 static unsigned long clk_ckih_get_rate(struct clk *clk)
448 {
449         return ckih_rate;
450 }
451
452 static struct clk ckih_clk = {
453         .name = "ckih",
454         .get_rate = clk_ckih_get_rate,
455 };
456
457 static unsigned long clk_ckil_get_rate(struct clk *clk)
458 {
459         return CKIL_CLK_FREQ;
460 }
461
462 static struct clk ckil_clk = {
463         .name = "ckil",
464         .get_rate = clk_ckil_get_rate,
465 };
466
467 static struct clk mcu_pll_clk = {
468         .name = "mcu_pll",
469         .parent = &ckih_clk,
470         .set_rate = _clk_pll_set_rate,
471         .get_rate = _clk_pll_get_rate,
472 };
473
474 static struct clk mcu_main_clk = {
475         .name = "mcu_main_clk",
476         .parent = &mcu_pll_clk,
477         .get_rate = _clk_mcu_main_get_rate,
478 };
479
480 static struct clk serial_pll_clk = {
481         .name = "serial_pll",
482         .parent = &ckih_clk,
483         .set_rate = _clk_pll_set_rate,
484         .get_rate = _clk_pll_get_rate,
485         .enable = _clk_serial_pll_enable,
486         .disable = _clk_serial_pll_disable,
487 };
488
489 static struct clk usb_pll_clk = {
490         .name = "usb_pll",
491         .parent = &ckih_clk,
492         .set_rate = _clk_pll_set_rate,
493         .get_rate = _clk_pll_get_rate,
494         .enable = _clk_usb_pll_enable,
495         .disable = _clk_usb_pll_disable,
496 };
497
498 static struct clk ahb_clk = {
499         .name = "ahb_clk",
500         .parent = &mcu_main_clk,
501         .get_rate = _clk_hclk_get_rate,
502 };
503
504 static struct clk per_clk = {
505         .name = "per_clk",
506         .parent = &usb_pll_clk,
507         .get_rate = _clk_per_get_rate,
508 };
509
510 static struct clk perclk_clk = {
511         .name = "perclk_clk",
512         .parent = &ipg_clk,
513 };
514
515 static struct clk cspi_clk[] = {
516         {
517          .name = "cspi_clk",
518          .id = 0,
519          .parent = &ipg_clk,
520          .enable = _clk_enable,
521          .enable_reg = MXC_CCM_CGR2,
522          .enable_shift = MXC_CCM_CGR2_CSPI1_OFFSET,
523          .disable = _clk_disable,},
524         {
525          .name = "cspi_clk",
526          .id = 1,
527          .parent = &ipg_clk,
528          .enable = _clk_enable,
529          .enable_reg = MXC_CCM_CGR2,
530          .enable_shift = MXC_CCM_CGR2_CSPI2_OFFSET,
531          .disable = _clk_disable,},
532         {
533          .name = "cspi_clk",
534          .id = 2,
535          .parent = &ipg_clk,
536          .enable = _clk_enable,
537          .enable_reg = MXC_CCM_CGR0,
538          .enable_shift = MXC_CCM_CGR0_CSPI3_OFFSET,
539          .disable = _clk_disable,},
540 };
541
542 static struct clk ipg_clk = {
543         .name = "ipg_clk",
544         .parent = &ahb_clk,
545         .get_rate = _clk_ipg_get_rate,
546 };
547
548 static struct clk emi_clk = {
549         .name = "emi_clk",
550         .parent = &ahb_clk,
551         .enable = _clk_enable,
552         .enable_reg = MXC_CCM_CGR2,
553         .enable_shift = MXC_CCM_CGR2_EMI_OFFSET,
554         .disable = _clk_emi_disable,
555 };
556
557 static struct clk gpt_clk = {
558         .name = "gpt_clk",
559         .parent = &perclk_clk,
560         .enable = _clk_enable,
561         .enable_reg = MXC_CCM_CGR0,
562         .enable_shift = MXC_CCM_CGR0_GPT_OFFSET,
563         .disable = _clk_disable,
564 };
565
566 static struct clk pwm_clk = {
567         .name = "pwm_clk",
568         .parent = &perclk_clk,
569         .enable = _clk_enable,
570         .enable_reg = MXC_CCM_CGR0,
571         .enable_shift = MXC_CCM_CGR1_PWM_OFFSET,
572         .disable = _clk_disable,
573 };
574
575 static struct clk epit_clk[] = {
576         {
577          .name = "epit_clk",
578          .id = 0,
579          .parent = &perclk_clk,
580          .enable = _clk_enable,
581          .enable_reg = MXC_CCM_CGR0,
582          .enable_shift = MXC_CCM_CGR0_EPIT1_OFFSET,
583          .disable = _clk_disable,},
584         {
585          .name = "epit_clk",
586          .id = 1,
587          .parent = &perclk_clk,
588          .enable = _clk_enable,
589          .enable_reg = MXC_CCM_CGR0,
590          .enable_shift = MXC_CCM_CGR0_EPIT2_OFFSET,
591          .disable = _clk_disable,},
592 };
593
594 static struct clk nfc_clk = {
595         .name = "nfc_clk",
596         .parent = &ahb_clk,
597         .get_rate = _clk_nfc_get_rate,
598 };
599
600 static struct clk scc_clk = {
601         .name = "scc_clk",
602         .parent = &ipg_clk,
603 };
604
605 static struct clk ipu_clk = {
606         .name = "ipu_clk",
607         .parent = &mcu_main_clk,
608         .get_rate = _clk_hsp_get_rate,
609         .enable = _clk_enable,
610         .enable_reg = MXC_CCM_CGR1,
611         .enable_shift = MXC_CCM_CGR1_IPU_OFFSET,
612         .disable = _clk_disable,
613 };
614
615 static struct clk kpp_clk = {
616         .name = "kpp_clk",
617         .parent = &ipg_clk,
618         .enable = _clk_enable,
619         .enable_reg = MXC_CCM_CGR1,
620         .enable_shift = MXC_CCM_CGR1_KPP_OFFSET,
621         .disable = _clk_disable,
622 };
623
624 static struct clk wdog_clk = {
625         .name = "wdog_clk",
626         .parent = &ipg_clk,
627         .enable = _clk_enable,
628         .enable_reg = MXC_CCM_CGR1,
629         .enable_shift = MXC_CCM_CGR1_WDOG_OFFSET,
630         .disable = _clk_disable,
631 };
632 static struct clk rtc_clk = {
633         .name = "rtc_clk",
634         .parent = &ipg_clk,
635         .enable = _clk_enable,
636         .enable_reg = MXC_CCM_CGR1,
637         .enable_shift = MXC_CCM_CGR1_RTC_OFFSET,
638         .disable = _clk_disable,
639 };
640
641 static struct clk usb_clk[] = {
642         {
643          .name = "usb_clk",
644          .parent = &usb_pll_clk,
645          .get_rate = _clk_usb_get_rate,},
646         {
647          .name = "usb_ahb_clk",
648          .parent = &ahb_clk,
649          .enable = _clk_enable,
650          .enable_reg = MXC_CCM_CGR1,
651          .enable_shift = MXC_CCM_CGR1_USBOTG_OFFSET,
652          .disable = _clk_disable,},
653 };
654
655 static struct clk csi_clk = {
656         .name = "csi_clk",
657         .parent = &serial_pll_clk,
658         .get_rate = _clk_csi_get_rate,
659         .round_rate = _clk_csi_round_rate,
660         .set_rate = _clk_csi_set_rate,
661         .enable = _clk_enable,
662         .enable_reg = MXC_CCM_CGR1,
663         .enable_shift = MXC_CCM_CGR1_CSI_OFFSET,
664         .disable = _clk_disable,
665 };
666
667 static struct clk uart_clk[] = {
668         {
669          .name = "uart_clk",
670          .id = 0,
671          .parent = &perclk_clk,
672          .enable = _clk_enable,
673          .enable_reg = MXC_CCM_CGR0,
674          .enable_shift = MXC_CCM_CGR0_UART1_OFFSET,
675          .disable = _clk_disable,},
676         {
677          .name = "uart_clk",
678          .id = 1,
679          .parent = &perclk_clk,
680          .enable = _clk_enable,
681          .enable_reg = MXC_CCM_CGR0,
682          .enable_shift = MXC_CCM_CGR0_UART2_OFFSET,
683          .disable = _clk_disable,},
684         {
685          .name = "uart_clk",
686          .id = 2,
687          .parent = &perclk_clk,
688          .enable = _clk_enable,
689          .enable_reg = MXC_CCM_CGR1,
690          .enable_shift = MXC_CCM_CGR1_UART3_OFFSET,
691          .disable = _clk_disable,},
692         {
693          .name = "uart_clk",
694          .id = 3,
695          .parent = &perclk_clk,
696          .enable = _clk_enable,
697          .enable_reg = MXC_CCM_CGR1,
698          .enable_shift = MXC_CCM_CGR1_UART4_OFFSET,
699          .disable = _clk_disable,},
700         {
701          .name = "uart_clk",
702          .id = 4,
703          .parent = &perclk_clk,
704          .enable = _clk_enable,
705          .enable_reg = MXC_CCM_CGR1,
706          .enable_shift = MXC_CCM_CGR1_UART5_OFFSET,
707          .disable = _clk_disable,},
708 };
709
710 static struct clk i2c_clk[] = {
711         {
712          .name = "i2c_clk",
713          .id = 0,
714          .parent = &perclk_clk,
715          .enable = _clk_enable,
716          .enable_reg = MXC_CCM_CGR0,
717          .enable_shift = MXC_CCM_CGR0_I2C1_OFFSET,
718          .disable = _clk_disable,},
719         {
720          .name = "i2c_clk",
721          .id = 1,
722          .parent = &perclk_clk,
723          .enable = _clk_enable,
724          .enable_reg = MXC_CCM_CGR0,
725          .enable_shift = MXC_CCM_CGR0_I2C2_OFFSET,
726          .disable = _clk_disable,},
727         {
728          .name = "i2c_clk",
729          .id = 2,
730          .parent = &perclk_clk,
731          .enable = _clk_enable,
732          .enable_reg = MXC_CCM_CGR0,
733          .enable_shift = MXC_CCM_CGR0_I2C3_OFFSET,
734          .disable = _clk_disable,},
735 };
736
737 static struct clk owire_clk = {
738         .name = "owire_clk",
739         .parent = &perclk_clk,
740         .enable_reg = MXC_CCM_CGR1,
741         .enable_shift = MXC_CCM_CGR1_OWIRE_OFFSET,
742         .enable = _clk_enable,
743         .disable = _clk_disable,
744 };
745
746 static struct clk sdhc_clk[] = {
747         {
748          .name = "sdhc_clk",
749          .id = 0,
750          .parent = &perclk_clk,
751          .enable = _clk_enable,
752          .enable_reg = MXC_CCM_CGR0,
753          .enable_shift = MXC_CCM_CGR0_SD_MMC1_OFFSET,
754          .disable = _clk_disable,},
755         {
756          .name = "sdhc_clk",
757          .id = 1,
758          .parent = &perclk_clk,
759          .enable = _clk_enable,
760          .enable_reg = MXC_CCM_CGR0,
761          .enable_shift = MXC_CCM_CGR0_SD_MMC2_OFFSET,
762          .disable = _clk_disable,},
763 };
764
765 static struct clk ssi_clk[] = {
766         {
767          .name = "ssi_clk",
768          .parent = &serial_pll_clk,
769          .get_rate = _clk_ssi1_get_rate,
770          .enable = _clk_enable,
771          .enable_reg = MXC_CCM_CGR0,
772          .enable_shift = MXC_CCM_CGR0_SSI1_OFFSET,
773          .disable = _clk_disable,},
774         {
775          .name = "ssi_clk",
776          .id = 1,
777          .parent = &serial_pll_clk,
778          .get_rate = _clk_ssi2_get_rate,
779          .enable = _clk_enable,
780          .enable_reg = MXC_CCM_CGR2,
781          .enable_shift = MXC_CCM_CGR2_SSI2_OFFSET,
782          .disable = _clk_disable,},
783 };
784
785 static struct clk firi_clk = {
786         .name = "firi_clk",
787         .parent = &usb_pll_clk,
788         .round_rate = _clk_firi_round_rate,
789         .set_rate = _clk_firi_set_rate,
790         .get_rate = _clk_firi_get_rate,
791         .enable = _clk_enable,
792         .enable_reg = MXC_CCM_CGR2,
793         .enable_shift = MXC_CCM_CGR2_FIRI_OFFSET,
794         .disable = _clk_disable,
795 };
796
797 static struct clk ata_clk = {
798         .name = "ata_clk",
799         .parent = &ipg_clk,
800         .enable = _clk_enable,
801         .enable_reg = MXC_CCM_CGR0,
802         .enable_shift = MXC_CCM_CGR0_ATA_OFFSET,
803         .disable = _clk_disable,
804 };
805
806 static struct clk mbx_clk = {
807         .name = "mbx_clk",
808         .parent = &ahb_clk,
809         .enable = _clk_enable,
810         .enable_reg = MXC_CCM_CGR2,
811         .enable_shift = MXC_CCM_CGR2_GACC_OFFSET,
812         .get_rate = _clk_mbx_get_rate,
813 };
814
815 static struct clk vpu_clk = {
816         .name = "vpu_clk",
817         .parent = &ahb_clk,
818         .enable = _clk_enable,
819         .enable_reg = MXC_CCM_CGR2,
820         .enable_shift = MXC_CCM_CGR2_GACC_OFFSET,
821         .get_rate = _clk_mbx_get_rate,
822 };
823
824 static struct clk rtic_clk = {
825         .name = "rtic_clk",
826         .parent = &ahb_clk,
827         .enable = _clk_enable,
828         .enable_reg = MXC_CCM_CGR2,
829         .enable_shift = MXC_CCM_CGR2_RTIC_OFFSET,
830         .disable = _clk_disable,
831 };
832
833 static struct clk rng_clk = {
834         .name = "rng_clk",
835         .parent = &ipg_clk,
836         .enable = _clk_enable,
837         .enable_reg = MXC_CCM_CGR0,
838         .enable_shift = MXC_CCM_CGR0_RNG_OFFSET,
839         .disable = _clk_disable,
840 };
841
842 static struct clk sdma_clk[] = {
843         {
844          .name = "sdma_ahb_clk",
845          .parent = &ahb_clk,
846          .enable = _clk_enable,
847          .enable_reg = MXC_CCM_CGR0,
848          .enable_shift = MXC_CCM_CGR0_SDMA_OFFSET,
849          .disable = _clk_disable,},
850         {
851          .name = "sdma_ipg_clk",
852          .parent = &ipg_clk,}
853 };
854
855 static struct clk mpeg4_clk = {
856         .name = "mpeg4_clk",
857         .parent = &ahb_clk,
858         .enable = _clk_enable,
859         .enable_reg = MXC_CCM_CGR1,
860         .enable_shift = MXC_CCM_CGR1_HANTRO_OFFSET,
861         .disable = _clk_disable,
862 };
863
864 static struct clk vl2cc_clk = {
865         .name = "vl2cc_clk",
866         .parent = &ahb_clk,
867         .enable = _clk_enable,
868         .enable_reg = MXC_CCM_CGR1,
869         .enable_shift = MXC_CCM_CGR1_HANTRO_OFFSET,
870         .disable = _clk_disable,
871 };
872
873 static struct clk mstick_clk[] = {
874         {
875          .name = "mstick_clk",
876          .id = 0,
877          .parent = &usb_pll_clk,
878          .get_rate = _clk_mstick1_get_rate,
879          .enable = _clk_enable,
880          .enable_reg = MXC_CCM_CGR1,
881          .enable_shift = MXC_CCM_CGR1_MEMSTICK1_OFFSET,
882          .disable = _clk_disable,},
883         {
884          .name = "mstick_clk",
885          .id = 1,
886          .parent = &usb_pll_clk,
887          .get_rate = _clk_mstick2_get_rate,
888          .enable = _clk_enable,
889          .enable_reg = MXC_CCM_CGR1,
890          .enable_shift = MXC_CCM_CGR1_MEMSTICK2_OFFSET,
891          .disable = _clk_disable,},
892 };
893
894 static struct clk iim_clk = {
895         .name = "iim_clk",
896         .parent = &ipg_clk,
897         .enable = _clk_enable,
898         .enable_reg = MXC_CCM_CGR0,
899         .enable_shift = MXC_CCM_CGR0_IIM_OFFSET,
900         .disable = _clk_disable,
901 };
902
903 static unsigned long _clk_cko1_round_rate(struct clk *clk, unsigned long rate)
904 {
905         u32 div, parent = clk_get_rate(clk->parent);
906
907         div = parent / rate;
908         if (parent % rate)
909                 div++;
910
911         if (div > 8)
912                 div = 16;
913         else if (div > 4)
914                 div = 8;
915         else if (div > 2)
916                 div = 4;
917
918         return parent / div;
919 }
920
921 static int _clk_cko1_set_rate(struct clk *clk, unsigned long rate)
922 {
923         u32 reg, div, parent = clk_get_rate(clk->parent);
924
925         div = parent / rate;
926
927         if (div == 16)
928                 div = 4;
929         else if (div == 8)
930                 div = 3;
931         else if (div == 4)
932                 div = 2;
933         else if (div == 2)
934                 div = 1;
935         else if (div == 1)
936                 div = 0;
937         else
938                 return -EINVAL;
939
940         reg = __raw_readl(MXC_CCM_COSR) & ~MXC_CCM_COSR_CLKOUTDIV_MASK;
941         reg |= div << MXC_CCM_COSR_CLKOUTDIV_OFFSET;
942         __raw_writel(reg, MXC_CCM_COSR);
943
944         return 0;
945 }
946
947 static unsigned long _clk_cko1_get_rate(struct clk *clk)
948 {
949         u32 div;
950
951         div = __raw_readl(MXC_CCM_COSR) & MXC_CCM_COSR_CLKOUTDIV_MASK >>
952             MXC_CCM_COSR_CLKOUTDIV_OFFSET;
953
954         return clk_get_rate(clk->parent) / (1 << div);
955 }
956
957 static int _clk_cko1_set_parent(struct clk *clk, struct clk *parent)
958 {
959         u32 reg;
960
961         reg = __raw_readl(MXC_CCM_COSR) & ~MXC_CCM_COSR_CLKOSEL_MASK;
962
963         if (parent == &mcu_main_clk)
964                 reg |= 0 << MXC_CCM_COSR_CLKOSEL_OFFSET;
965         else if (parent == &ipg_clk)
966                 reg |= 1 << MXC_CCM_COSR_CLKOSEL_OFFSET;
967         else if (parent == &usb_pll_clk)
968                 reg |= 2 << MXC_CCM_COSR_CLKOSEL_OFFSET;
969         else if (parent == mcu_main_clk.parent)
970                 reg |= 3 << MXC_CCM_COSR_CLKOSEL_OFFSET;
971         else if (parent == &ahb_clk)
972                 reg |= 5 << MXC_CCM_COSR_CLKOSEL_OFFSET;
973         else if (parent == &serial_pll_clk)
974                 reg |= 7 << MXC_CCM_COSR_CLKOSEL_OFFSET;
975         else if (parent == &ckih_clk)
976                 reg |= 8 << MXC_CCM_COSR_CLKOSEL_OFFSET;
977         else if (parent == &emi_clk)
978                 reg |= 9 << MXC_CCM_COSR_CLKOSEL_OFFSET;
979         else if (parent == &ipu_clk)
980                 reg |= 0xA << MXC_CCM_COSR_CLKOSEL_OFFSET;
981         else if (parent == &nfc_clk)
982                 reg |= 0xB << MXC_CCM_COSR_CLKOSEL_OFFSET;
983         else if (parent == &uart_clk[0])
984                 reg |= 0xC << MXC_CCM_COSR_CLKOSEL_OFFSET;
985         else
986                 return -EINVAL;
987
988         __raw_writel(reg, MXC_CCM_COSR);
989
990         return 0;
991 }
992
993 static int _clk_cko1_enable(struct clk *clk)
994 {
995         u32 reg;
996
997         reg = __raw_readl(MXC_CCM_COSR) | MXC_CCM_COSR_CLKOEN;
998         __raw_writel(reg, MXC_CCM_COSR);
999
1000         return 0;
1001 }
1002
1003 static void _clk_cko1_disable(struct clk *clk)
1004 {
1005         u32 reg;
1006
1007         reg = __raw_readl(MXC_CCM_COSR) & ~MXC_CCM_COSR_CLKOEN;
1008         __raw_writel(reg, MXC_CCM_COSR);
1009 }
1010
1011 static struct clk cko1_clk = {
1012         .name = "cko1_clk",
1013         .get_rate = _clk_cko1_get_rate,
1014         .set_rate = _clk_cko1_set_rate,
1015         .round_rate = _clk_cko1_round_rate,
1016         .set_parent = _clk_cko1_set_parent,
1017         .enable = _clk_cko1_enable,
1018         .disable = _clk_cko1_disable,
1019 };
1020
1021 static struct clk *mxc_clks[] = {
1022         &ckih_clk,
1023         &ckil_clk,
1024         &mcu_pll_clk,
1025         &usb_pll_clk,
1026         &serial_pll_clk,
1027         &mcu_main_clk,
1028         &ahb_clk,
1029         &per_clk,
1030         &perclk_clk,
1031         &cko1_clk,
1032         &emi_clk,
1033         &cspi_clk[0],
1034         &cspi_clk[1],
1035         &cspi_clk[2],
1036         &ipg_clk,
1037         &gpt_clk,
1038         &pwm_clk,
1039         &wdog_clk,
1040         &rtc_clk,
1041         &epit_clk[0],
1042         &epit_clk[1],
1043         &nfc_clk,
1044         &ipu_clk,
1045         &kpp_clk,
1046         &usb_clk[0],
1047         &usb_clk[1],
1048         &csi_clk,
1049         &uart_clk[0],
1050         &uart_clk[1],
1051         &uart_clk[2],
1052         &uart_clk[3],
1053         &uart_clk[4],
1054         &i2c_clk[0],
1055         &i2c_clk[1],
1056         &i2c_clk[2],
1057         &owire_clk,
1058         &sdhc_clk[0],
1059         &sdhc_clk[1],
1060         &ssi_clk[0],
1061         &ssi_clk[1],
1062         &firi_clk,
1063         &ata_clk,
1064         &rtic_clk,
1065         &rng_clk,
1066         &sdma_clk[0],
1067         &sdma_clk[1],
1068         &mstick_clk[0],
1069         &mstick_clk[1],
1070         &scc_clk,
1071         &iim_clk,
1072 };
1073
1074 int __init mxc_clocks_init(unsigned long fref)
1075 {
1076         u32 reg;
1077         struct clk **clkp;
1078
1079         ckih_rate = fref;
1080
1081         for (clkp = mxc_clks; clkp < mxc_clks + ARRAY_SIZE(mxc_clks); clkp++)
1082                 clk_register(*clkp);
1083
1084         if (cpu_is_mx31()) {
1085                 clk_register(&mpeg4_clk);
1086                 clk_register(&mbx_clk);
1087         } else {
1088                 clk_register(&vpu_clk);
1089                 clk_register(&vl2cc_clk);
1090         }
1091
1092         /* Turn off all possible clocks */
1093         __raw_writel(MXC_CCM_CGR0_GPT_MASK, MXC_CCM_CGR0);
1094         __raw_writel(0, MXC_CCM_CGR1);
1095
1096         __raw_writel(MXC_CCM_CGR2_EMI_MASK |
1097                      MXC_CCM_CGR2_IPMUX1_MASK |
1098                      MXC_CCM_CGR2_IPMUX2_MASK |
1099                      MXC_CCM_CGR2_MXCCLKENSEL_MASK |    /* for MX32 */
1100                      MXC_CCM_CGR2_CHIKCAMPEN_MASK |     /* for MX32 */
1101                      MXC_CCM_CGR2_OVRVPUBUSY_MASK |     /* for MX32 */
1102                      1 << 27 | 1 << 28, /* Bit 27 and 28 are not defined for
1103                                            MX32, but still required to be set */
1104                      MXC_CCM_CGR2);
1105
1106         clk_disable(&cko1_clk);
1107         clk_disable(&usb_pll_clk);
1108
1109         pr_info("Clock input source is %ld\n", clk_get_rate(&ckih_clk));
1110
1111         clk_enable(&gpt_clk);
1112         clk_enable(&emi_clk);
1113         clk_enable(&iim_clk);
1114
1115         clk_enable(&serial_pll_clk);
1116
1117         if (mx31_revision() >= CHIP_REV_2_0) {
1118                 reg = __raw_readl(MXC_CCM_PMCR1);
1119                 /* No PLL restart on DVFS switch; enable auto EMI handshake */
1120                 reg |= MXC_CCM_PMCR1_PLLRDIS | MXC_CCM_PMCR1_EMIRQ_EN;
1121                 __raw_writel(reg, MXC_CCM_PMCR1);
1122         }
1123
1124         return 0;
1125 }
1126