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