]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/arm/cpu/armv7/mx5/clock.c
mx51: Fix USB PHY clocks
[karo-tx-uboot.git] / arch / arm / cpu / armv7 / mx5 / clock.c
1 /*
2  * (C) Copyright 2007
3  * Sascha Hauer, Pengutronix
4  *
5  * (C) Copyright 2009 Freescale Semiconductor, Inc.
6  *
7  * See file CREDITS for list of people who contributed to this
8  * project.
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License as
12  * published by the Free Software Foundation; either version 2 of
13  * the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
23  * MA 02111-1307 USA
24  */
25
26 #include <common.h>
27 #include <asm/io.h>
28 #include <asm/errno.h>
29 #include <asm/arch/imx-regs.h>
30 #include <asm/arch/crm_regs.h>
31 #include <asm/arch/clock.h>
32 #include <div64.h>
33 #include <asm/arch/sys_proto.h>
34
35 enum pll_clocks {
36         PLL1_CLOCK = 0,
37         PLL2_CLOCK,
38         PLL3_CLOCK,
39         PLL4_CLOCK,
40         PLL_CLOCKS,
41 };
42
43 struct mxc_pll_reg *mxc_plls[PLL_CLOCKS] = {
44         [PLL1_CLOCK] = (struct mxc_pll_reg *)PLL1_BASE_ADDR,
45         [PLL2_CLOCK] = (struct mxc_pll_reg *)PLL2_BASE_ADDR,
46         [PLL3_CLOCK] = (struct mxc_pll_reg *)PLL3_BASE_ADDR,
47 #ifdef  CONFIG_MX53
48         [PLL4_CLOCK] = (struct mxc_pll_reg *)PLL4_BASE_ADDR,
49 #endif
50 };
51
52 #define AHB_CLK_ROOT    133333333
53 #define SZ_DEC_1M       1000000
54 #define PLL_PD_MAX      16      /* Actual pd+1 */
55 #define PLL_MFI_MAX     15
56 #define PLL_MFI_MIN     5
57 #define ARM_DIV_MAX     8
58 #define IPG_DIV_MAX     4
59 #define AHB_DIV_MAX     8
60 #define EMI_DIV_MAX     8
61 #define NFC_DIV_MAX     8
62
63 #define MX5_CBCMR       0x00015154
64 #define MX5_CBCDR       0x02888945
65
66 struct fixed_pll_mfd {
67         u32 ref_clk_hz;
68         u32 mfd;
69 };
70
71 const struct fixed_pll_mfd fixed_mfd[] = {
72         {MXC_HCLK, 24 * 16},
73 };
74
75 struct pll_param {
76         u32 pd;
77         u32 mfi;
78         u32 mfn;
79         u32 mfd;
80 };
81
82 #define PLL_FREQ_MAX(ref_clk)  (4 * (ref_clk) * PLL_MFI_MAX)
83 #define PLL_FREQ_MIN(ref_clk) \
84                 ((2 * (ref_clk) * (PLL_MFI_MIN - 1)) / PLL_PD_MAX)
85 #define MAX_DDR_CLK     420000000
86 #define NFC_CLK_MAX     34000000
87
88 struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)MXC_CCM_BASE;
89
90 void set_usboh3_clk(void)
91 {
92         clrsetbits_le32(&mxc_ccm->cscmr1,
93                         MXC_CCM_CSCMR1_USBOH3_CLK_SEL_MASK,
94                         MXC_CCM_CSCMR1_USBOH3_CLK_SEL(1));
95         clrsetbits_le32(&mxc_ccm->cscdr1,
96                         MXC_CCM_CSCDR1_USBOH3_CLK_PODF_MASK |
97                         MXC_CCM_CSCDR1_USBOH3_CLK_PRED_MASK,
98                         MXC_CCM_CSCDR1_USBOH3_CLK_PRED(4) |
99                         MXC_CCM_CSCDR1_USBOH3_CLK_PODF(1));
100 }
101
102 void enable_usboh3_clk(unsigned char enable)
103 {
104         unsigned int cg = enable ? MXC_CCM_CCGR_CG_ON : MXC_CCM_CCGR_CG_OFF;
105
106         clrsetbits_le32(&mxc_ccm->CCGR2,
107                         MXC_CCM_CCGR2_USBOH3_60M(MXC_CCM_CCGR_CG_MASK),
108                         MXC_CCM_CCGR2_USBOH3_60M(cg));
109 }
110
111 #ifdef CONFIG_I2C_MXC
112 /* i2c_num can be from 0 - 2 */
113 int enable_i2c_clk(unsigned char enable, unsigned i2c_num)
114 {
115         u32 mask;
116
117         if (i2c_num > 2)
118                 return -EINVAL;
119         mask = MXC_CCM_CCGR_CG_MASK <<
120                         (MXC_CCM_CCGR1_I2C1_OFFSET + (i2c_num << 1));
121         if (enable)
122                 setbits_le32(&mxc_ccm->CCGR1, mask);
123         else
124                 clrbits_le32(&mxc_ccm->CCGR1, mask);
125         return 0;
126 }
127 #endif
128
129 void set_usb_phy_clk(void)
130 {
131         clrbits_le32(&mxc_ccm->cscmr1, MXC_CCM_CSCMR1_USB_PHY_CLK_SEL);
132 }
133
134 #if defined(CONFIG_MX51)
135 void enable_usb_phy1_clk(unsigned char enable)
136 {
137         unsigned int cg = enable ? MXC_CCM_CCGR_CG_ON : MXC_CCM_CCGR_CG_OFF;
138
139         clrsetbits_le32(&mxc_ccm->CCGR2,
140                         MXC_CCM_CCGR2_USB_PHY(MXC_CCM_CCGR_CG_MASK),
141                         MXC_CCM_CCGR2_USB_PHY(cg));
142 }
143
144 void enable_usb_phy2_clk(unsigned char enable)
145 {
146         /* i.MX51 has a single USB PHY clock, so do nothing here. */
147 }
148 #elif defined(CONFIG_MX53)
149 void enable_usb_phy1_clk(unsigned char enable)
150 {
151         unsigned int cg = enable ? MXC_CCM_CCGR_CG_ON : MXC_CCM_CCGR_CG_OFF;
152
153         clrsetbits_le32(&mxc_ccm->CCGR4,
154                         MXC_CCM_CCGR4_USB_PHY1(MXC_CCM_CCGR_CG_MASK),
155                         MXC_CCM_CCGR4_USB_PHY1(cg));
156 }
157
158 void enable_usb_phy2_clk(unsigned char enable)
159 {
160         unsigned int cg = enable ? MXC_CCM_CCGR_CG_ON : MXC_CCM_CCGR_CG_OFF;
161
162         clrsetbits_le32(&mxc_ccm->CCGR4,
163                         MXC_CCM_CCGR4_USB_PHY2(MXC_CCM_CCGR_CG_MASK),
164                         MXC_CCM_CCGR4_USB_PHY2(cg));
165 }
166 #endif
167
168 /*
169  * Calculate the frequency of PLLn.
170  */
171 static uint32_t decode_pll(struct mxc_pll_reg *pll, uint32_t infreq)
172 {
173         uint32_t ctrl, op, mfd, mfn, mfi, pdf, ret;
174         uint64_t refclk, temp;
175         int32_t mfn_abs;
176
177         ctrl = readl(&pll->ctrl);
178
179         if (ctrl & MXC_DPLLC_CTL_HFSM) {
180                 mfn = readl(&pll->hfs_mfn);
181                 mfd = readl(&pll->hfs_mfd);
182                 op = readl(&pll->hfs_op);
183         } else {
184                 mfn = readl(&pll->mfn);
185                 mfd = readl(&pll->mfd);
186                 op = readl(&pll->op);
187         }
188
189         mfd &= MXC_DPLLC_MFD_MFD_MASK;
190         mfn &= MXC_DPLLC_MFN_MFN_MASK;
191         pdf = op & MXC_DPLLC_OP_PDF_MASK;
192         mfi = MXC_DPLLC_OP_MFI_RD(op);
193
194         /* 21.2.3 */
195         if (mfi < 5)
196                 mfi = 5;
197
198         /* Sign extend */
199         if (mfn >= 0x04000000) {
200                 mfn |= 0xfc000000;
201                 mfn_abs = -mfn;
202         } else
203                 mfn_abs = mfn;
204
205         refclk = infreq * 2;
206         if (ctrl & MXC_DPLLC_CTL_DPDCK0_2_EN)
207                 refclk *= 2;
208
209         do_div(refclk, pdf + 1);
210         temp = refclk * mfn_abs;
211         do_div(temp, mfd + 1);
212         ret = refclk * mfi;
213
214         if ((int)mfn < 0)
215                 ret -= temp;
216         else
217                 ret += temp;
218
219         return ret;
220 }
221
222 /*
223  * Get mcu main rate
224  */
225 u32 get_mcu_main_clk(void)
226 {
227         u32 reg, freq;
228
229         reg = MXC_CCM_CACRR_ARM_PODF_RD(readl(&mxc_ccm->cacrr));
230         freq = decode_pll(mxc_plls[PLL1_CLOCK], MXC_HCLK);
231         return freq / (reg + 1);
232 }
233
234 /*
235  * Get the rate of peripheral's root clock.
236  */
237 u32 get_periph_clk(void)
238 {
239         u32 reg;
240
241         reg = readl(&mxc_ccm->cbcdr);
242         if (!(reg & MXC_CCM_CBCDR_PERIPH_CLK_SEL))
243                 return decode_pll(mxc_plls[PLL2_CLOCK], MXC_HCLK);
244         reg = readl(&mxc_ccm->cbcmr);
245         switch (MXC_CCM_CBCMR_PERIPH_CLK_SEL_RD(reg)) {
246         case 0:
247                 return decode_pll(mxc_plls[PLL1_CLOCK], MXC_HCLK);
248         case 1:
249                 return decode_pll(mxc_plls[PLL3_CLOCK], MXC_HCLK);
250         default:
251                 return 0;
252         }
253         /* NOTREACHED */
254 }
255
256 /*
257  * Get the rate of ipg clock.
258  */
259 static u32 get_ipg_clk(void)
260 {
261         uint32_t freq, reg, div;
262
263         freq = get_ahb_clk();
264
265         reg = readl(&mxc_ccm->cbcdr);
266         div = MXC_CCM_CBCDR_IPG_PODF_RD(reg) + 1;
267
268         return freq / div;
269 }
270
271 /*
272  * Get the rate of ipg_per clock.
273  */
274 static u32 get_ipg_per_clk(void)
275 {
276         u32 pred1, pred2, podf;
277
278         if (readl(&mxc_ccm->cbcmr) & MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL)
279                 return get_ipg_clk();
280         /* Fixme: not handle what about lpm*/
281         podf = readl(&mxc_ccm->cbcdr);
282         pred1 = MXC_CCM_CBCDR_PERCLK_PRED1_RD(podf);
283         pred2 = MXC_CCM_CBCDR_PERCLK_PRED2_RD(podf);
284         podf = MXC_CCM_CBCDR_PERCLK_PODF_RD(podf);
285         return get_periph_clk() / ((pred1 + 1) * (pred2 + 1) * (podf + 1));
286 }
287
288 /*
289  * Get the rate of uart clk.
290  */
291 static u32 get_uart_clk(void)
292 {
293         unsigned int freq, reg, pred, podf;
294
295         reg = readl(&mxc_ccm->cscmr1);
296         switch (MXC_CCM_CSCMR1_UART_CLK_SEL_RD(reg)) {
297         case 0x0:
298                 freq = decode_pll(mxc_plls[PLL1_CLOCK], MXC_HCLK);
299                 break;
300         case 0x1:
301                 freq = decode_pll(mxc_plls[PLL2_CLOCK], MXC_HCLK);
302                 break;
303         case 0x2:
304                 freq = decode_pll(mxc_plls[PLL3_CLOCK], MXC_HCLK);
305                 break;
306         default:
307                 return 66500000;
308         }
309
310         reg = readl(&mxc_ccm->cscdr1);
311         pred = MXC_CCM_CSCDR1_UART_CLK_PRED_RD(reg);
312         podf = MXC_CCM_CSCDR1_UART_CLK_PODF_RD(reg);
313         freq /= (pred + 1) * (podf + 1);
314
315         return freq;
316 }
317
318 /*
319  * This function returns the low power audio clock.
320  */
321 static u32 get_lp_apm(void)
322 {
323         u32 ret_val = 0;
324         u32 ccsr = readl(&mxc_ccm->ccsr);
325
326         if (((ccsr >> 9) & 1) == 0)
327                 ret_val = MXC_HCLK;
328         else
329                 ret_val = MXC_CLK32 * 1024;
330
331         return ret_val;
332 }
333
334 /*
335  * get cspi clock rate.
336  */
337 static u32 imx_get_cspiclk(void)
338 {
339         u32 ret_val = 0, pdf, pre_pdf, clk_sel;
340         u32 cscmr1 = readl(&mxc_ccm->cscmr1);
341         u32 cscdr2 = readl(&mxc_ccm->cscdr2);
342
343         pre_pdf = MXC_CCM_CSCDR2_CSPI_CLK_PRED_RD(cscdr2);
344         pdf = MXC_CCM_CSCDR2_CSPI_CLK_PODF_RD(cscdr2);
345         clk_sel = MXC_CCM_CSCMR1_CSPI_CLK_SEL_RD(cscmr1);
346
347         switch (clk_sel) {
348         case 0:
349                 ret_val = decode_pll(mxc_plls[PLL1_CLOCK], MXC_HCLK) /
350                                         ((pre_pdf + 1) * (pdf + 1));
351                 break;
352         case 1:
353                 ret_val = decode_pll(mxc_plls[PLL2_CLOCK], MXC_HCLK) /
354                                         ((pre_pdf + 1) * (pdf + 1));
355                 break;
356         case 2:
357                 ret_val = decode_pll(mxc_plls[PLL3_CLOCK], MXC_HCLK) /
358                                         ((pre_pdf + 1) * (pdf + 1));
359                 break;
360         default:
361                 ret_val = get_lp_apm() / ((pre_pdf + 1) * (pdf + 1));
362                 break;
363         }
364
365         return ret_val;
366 }
367
368 static u32 get_axi_a_clk(void)
369 {
370         u32 cbcdr = readl(&mxc_ccm->cbcdr);
371         u32 pdf = MXC_CCM_CBCDR_AXI_A_PODF_RD(cbcdr);
372
373         return  get_periph_clk() / (pdf + 1);
374 }
375
376 static u32 get_axi_b_clk(void)
377 {
378         u32 cbcdr = readl(&mxc_ccm->cbcdr);
379         u32 pdf = MXC_CCM_CBCDR_AXI_B_PODF_RD(cbcdr);
380
381         return  get_periph_clk() / (pdf + 1);
382 }
383
384 static u32 get_emi_slow_clk(void)
385 {
386         u32 cbcdr = readl(&mxc_ccm->cbcdr);
387         u32 emi_clk_sel = cbcdr & MXC_CCM_CBCDR_EMI_CLK_SEL;
388         u32 pdf = MXC_CCM_CBCDR_EMI_PODF_RD(cbcdr);
389
390         if (emi_clk_sel)
391                 return  get_ahb_clk() / (pdf + 1);
392
393         return  get_periph_clk() / (pdf + 1);
394 }
395
396 static u32 get_ddr_clk(void)
397 {
398         u32 ret_val = 0;
399         u32 cbcmr = readl(&mxc_ccm->cbcmr);
400         u32 ddr_clk_sel = MXC_CCM_CBCMR_DDR_CLK_SEL_RD(cbcmr);
401 #ifdef CONFIG_MX51
402         u32 cbcdr = readl(&mxc_ccm->cbcdr);
403         if (cbcdr & MXC_CCM_CBCDR_DDR_HIFREQ_SEL) {
404                 u32 ddr_clk_podf = MXC_CCM_CBCDR_DDR_PODF_RD(cbcdr);
405
406                 ret_val = decode_pll(mxc_plls[PLL1_CLOCK], MXC_HCLK);
407                 ret_val /= ddr_clk_podf + 1;
408
409                 return ret_val;
410         }
411 #endif
412         switch (ddr_clk_sel) {
413         case 0:
414                 ret_val = get_axi_a_clk();
415                 break;
416         case 1:
417                 ret_val = get_axi_b_clk();
418                 break;
419         case 2:
420                 ret_val = get_emi_slow_clk();
421                 break;
422         case 3:
423                 ret_val = get_ahb_clk();
424                 break;
425         default:
426                 break;
427         }
428
429         return ret_val;
430 }
431
432 /*
433  * The API of get mxc clocks.
434  */
435 unsigned int mxc_get_clock(enum mxc_clock clk)
436 {
437         switch (clk) {
438         case MXC_ARM_CLK:
439                 return get_mcu_main_clk();
440         case MXC_AHB_CLK:
441                 return get_ahb_clk();
442         case MXC_IPG_CLK:
443                 return get_ipg_clk();
444         case MXC_IPG_PERCLK:
445         case MXC_I2C_CLK:
446                 return get_ipg_per_clk();
447         case MXC_UART_CLK:
448                 return get_uart_clk();
449         case MXC_CSPI_CLK:
450                 return imx_get_cspiclk();
451         case MXC_FEC_CLK:
452                 return decode_pll(mxc_plls[PLL1_CLOCK], MXC_HCLK);
453         case MXC_SATA_CLK:
454                 return get_ahb_clk();
455         case MXC_DDR_CLK:
456                 return get_ddr_clk();
457         default:
458                 break;
459         }
460         return -EINVAL;
461 }
462
463 u32 imx_get_uartclk(void)
464 {
465         return get_uart_clk();
466 }
467
468
469 u32 imx_get_fecclk(void)
470 {
471         return mxc_get_clock(MXC_IPG_CLK);
472 }
473
474 static int gcd(int m, int n)
475 {
476         int t;
477         while (m > 0) {
478                 if (n > m) {
479                         t = m;
480                         m = n;
481                         n = t;
482                 } /* swap */
483                 m -= n;
484         }
485         return n;
486 }
487
488 /*
489  * This is to calculate various parameters based on reference clock and
490  * targeted clock based on the equation:
491  *      t_clk = 2*ref_freq*(mfi + mfn/(mfd+1))/(pd+1)
492  * This calculation is based on a fixed MFD value for simplicity.
493  */
494 static int calc_pll_params(u32 ref, u32 target, struct pll_param *pll)
495 {
496         u64 pd, mfi = 1, mfn, mfd, t1;
497         u32 n_target = target;
498         u32 n_ref = ref, i;
499
500         /*
501          * Make sure targeted freq is in the valid range.
502          * Otherwise the following calculation might be wrong!!!
503          */
504         if (n_target < PLL_FREQ_MIN(ref) ||
505                 n_target > PLL_FREQ_MAX(ref)) {
506                 printf("Targeted peripheral clock should be"
507                         "within [%d - %d]\n",
508                         PLL_FREQ_MIN(ref) / SZ_DEC_1M,
509                         PLL_FREQ_MAX(ref) / SZ_DEC_1M);
510                 return -EINVAL;
511         }
512
513         for (i = 0; i < ARRAY_SIZE(fixed_mfd); i++) {
514                 if (fixed_mfd[i].ref_clk_hz == ref) {
515                         mfd = fixed_mfd[i].mfd;
516                         break;
517                 }
518         }
519
520         if (i == ARRAY_SIZE(fixed_mfd))
521                 return -EINVAL;
522
523         /* Use n_target and n_ref to avoid overflow */
524         for (pd = 1; pd <= PLL_PD_MAX; pd++) {
525                 t1 = n_target * pd;
526                 do_div(t1, (4 * n_ref));
527                 mfi = t1;
528                 if (mfi > PLL_MFI_MAX)
529                         return -EINVAL;
530                 else if (mfi < 5)
531                         continue;
532                 break;
533         }
534         /*
535          * Now got pd and mfi already
536          *
537          * mfn = (((n_target * pd) / 4 - n_ref * mfi) * mfd) / n_ref;
538          */
539         t1 = n_target * pd;
540         do_div(t1, 4);
541         t1 -= n_ref * mfi;
542         t1 *= mfd;
543         do_div(t1, n_ref);
544         mfn = t1;
545         debug("ref=%d, target=%d, pd=%d," "mfi=%d,mfn=%d, mfd=%d\n",
546                 ref, n_target, (u32)pd, (u32)mfi, (u32)mfn, (u32)mfd);
547         i = 1;
548         if (mfn != 0)
549                 i = gcd(mfd, mfn);
550         pll->pd = (u32)pd;
551         pll->mfi = (u32)mfi;
552         do_div(mfn, i);
553         pll->mfn = (u32)mfn;
554         do_div(mfd, i);
555         pll->mfd = (u32)mfd;
556
557         return 0;
558 }
559
560 #define calc_div(tgt_clk, src_clk, limit) ({            \
561                 u32 v = 0;                              \
562                 if (((src_clk) % (tgt_clk)) <= 100)     \
563                         v = (src_clk) / (tgt_clk);      \
564                 else                                    \
565                         v = ((src_clk) / (tgt_clk)) + 1;\
566                 if (v > limit)                          \
567                         v = limit;                      \
568                 (v - 1);                                \
569         })
570
571 #define CHANGE_PLL_SETTINGS(pll, pd, fi, fn, fd) \
572         {       \
573                 writel(0x1232, &pll->ctrl);             \
574                 writel(0x2, &pll->config);              \
575                 writel((((pd) - 1) << 0) | ((fi) << 4), \
576                         &pll->op);                      \
577                 writel(fn, &(pll->mfn));                \
578                 writel((fd) - 1, &pll->mfd);            \
579                 writel((((pd) - 1) << 0) | ((fi) << 4), \
580                         &pll->hfs_op);                  \
581                 writel(fn, &pll->hfs_mfn);              \
582                 writel((fd) - 1, &pll->hfs_mfd);        \
583                 writel(0x1232, &pll->ctrl);             \
584                 while (!readl(&pll->ctrl) & 0x1)        \
585                         ;\
586         }
587
588 static int config_pll_clk(enum pll_clocks index, struct pll_param *pll_param)
589 {
590         u32 ccsr = readl(&mxc_ccm->ccsr);
591         struct mxc_pll_reg *pll = mxc_plls[index];
592
593         switch (index) {
594         case PLL1_CLOCK:
595                 /* Switch ARM to PLL2 clock */
596                 writel(ccsr | 0x4, &mxc_ccm->ccsr);
597                 CHANGE_PLL_SETTINGS(pll, pll_param->pd,
598                                         pll_param->mfi, pll_param->mfn,
599                                         pll_param->mfd);
600                 /* Switch back */
601                 writel(ccsr & ~0x4, &mxc_ccm->ccsr);
602                 break;
603         case PLL2_CLOCK:
604                 /* Switch to pll2 bypass clock */
605                 writel(ccsr | 0x2, &mxc_ccm->ccsr);
606                 CHANGE_PLL_SETTINGS(pll, pll_param->pd,
607                                         pll_param->mfi, pll_param->mfn,
608                                         pll_param->mfd);
609                 /* Switch back */
610                 writel(ccsr & ~0x2, &mxc_ccm->ccsr);
611                 break;
612         case PLL3_CLOCK:
613                 /* Switch to pll3 bypass clock */
614                 writel(ccsr | 0x1, &mxc_ccm->ccsr);
615                 CHANGE_PLL_SETTINGS(pll, pll_param->pd,
616                                         pll_param->mfi, pll_param->mfn,
617                                         pll_param->mfd);
618                 /* Switch back */
619                 writel(ccsr & ~0x1, &mxc_ccm->ccsr);
620                 break;
621         case PLL4_CLOCK:
622                 /* Switch to pll4 bypass clock */
623                 writel(ccsr | 0x20, &mxc_ccm->ccsr);
624                 CHANGE_PLL_SETTINGS(pll, pll_param->pd,
625                                         pll_param->mfi, pll_param->mfn,
626                                         pll_param->mfd);
627                 /* Switch back */
628                 writel(ccsr & ~0x20, &mxc_ccm->ccsr);
629                 break;
630         default:
631                 return -EINVAL;
632         }
633
634         return 0;
635 }
636
637 /* Config CPU clock */
638 static int config_core_clk(u32 ref, u32 freq)
639 {
640         int ret = 0;
641         struct pll_param pll_param;
642
643         memset(&pll_param, 0, sizeof(struct pll_param));
644
645         /* The case that periph uses PLL1 is not considered here */
646         ret = calc_pll_params(ref, freq, &pll_param);
647         if (ret != 0) {
648                 printf("Error:Can't find pll parameters: %d\n", ret);
649                 return ret;
650         }
651
652         return config_pll_clk(PLL1_CLOCK, &pll_param);
653 }
654
655 static int config_nfc_clk(u32 nfc_clk)
656 {
657         u32 parent_rate = get_emi_slow_clk();
658         u32 div = parent_rate / nfc_clk;
659
660         if (nfc_clk <= 0)
661                 return -EINVAL;
662         if (div == 0)
663                 div++;
664         if (parent_rate / div > NFC_CLK_MAX)
665                 div++;
666         clrsetbits_le32(&mxc_ccm->cbcdr,
667                         MXC_CCM_CBCDR_NFC_PODF_MASK,
668                         MXC_CCM_CBCDR_NFC_PODF(div - 1));
669         while (readl(&mxc_ccm->cdhipr) != 0)
670                 ;
671         return 0;
672 }
673
674 /* Config main_bus_clock for periphs */
675 static int config_periph_clk(u32 ref, u32 freq)
676 {
677         int ret = 0;
678         struct pll_param pll_param;
679
680         memset(&pll_param, 0, sizeof(struct pll_param));
681
682         if (readl(&mxc_ccm->cbcdr) & MXC_CCM_CBCDR_PERIPH_CLK_SEL) {
683                 ret = calc_pll_params(ref, freq, &pll_param);
684                 if (ret != 0) {
685                         printf("Error:Can't find pll parameters: %d\n",
686                                 ret);
687                         return ret;
688                 }
689                 switch (MXC_CCM_CBCMR_PERIPH_CLK_SEL_RD(
690                                 readl(&mxc_ccm->cbcmr))) {
691                 case 0:
692                         return config_pll_clk(PLL1_CLOCK, &pll_param);
693                         break;
694                 case 1:
695                         return config_pll_clk(PLL3_CLOCK, &pll_param);
696                         break;
697                 default:
698                         return -EINVAL;
699                 }
700         }
701
702         return 0;
703 }
704
705 static int config_ddr_clk(u32 emi_clk)
706 {
707         u32 clk_src;
708         s32 shift = 0, clk_sel, div = 1;
709         u32 cbcmr = readl(&mxc_ccm->cbcmr);
710
711         if (emi_clk > MAX_DDR_CLK) {
712                 printf("Warning:DDR clock should not exceed %d MHz\n",
713                         MAX_DDR_CLK / SZ_DEC_1M);
714                 emi_clk = MAX_DDR_CLK;
715         }
716
717         clk_src = get_periph_clk();
718         /* Find DDR clock input */
719         clk_sel = MXC_CCM_CBCMR_DDR_CLK_SEL_RD(cbcmr);
720         switch (clk_sel) {
721         case 0:
722                 shift = 16;
723                 break;
724         case 1:
725                 shift = 19;
726                 break;
727         case 2:
728                 shift = 22;
729                 break;
730         case 3:
731                 shift = 10;
732                 break;
733         default:
734                 return -EINVAL;
735         }
736
737         if ((clk_src % emi_clk) < 10000000)
738                 div = clk_src / emi_clk;
739         else
740                 div = (clk_src / emi_clk) + 1;
741         if (div > 8)
742                 div = 8;
743
744         clrsetbits_le32(&mxc_ccm->cbcdr, 0x7 << shift, (div - 1) << shift);
745         while (readl(&mxc_ccm->cdhipr) != 0)
746                 ;
747         writel(0x0, &mxc_ccm->ccdr);
748
749         return 0;
750 }
751
752 /*
753  * This function assumes the expected core clock has to be changed by
754  * modifying the PLL. This is NOT true always but for most of the times,
755  * it is. So it assumes the PLL output freq is the same as the expected
756  * core clock (presc=1) unless the core clock is less than PLL_FREQ_MIN.
757  * In the latter case, it will try to increase the presc value until
758  * (presc*core_clk) is greater than PLL_FREQ_MIN. It then makes call to
759  * calc_pll_params() and obtains the values of PD, MFI,MFN, MFD based
760  * on the targeted PLL and reference input clock to the PLL. Lastly,
761  * it sets the register based on these values along with the dividers.
762  * Note 1) There is no value checking for the passed-in divider values
763  *         so the caller has to make sure those values are sensible.
764  *      2) Also adjust the NFC divider such that the NFC clock doesn't
765  *         exceed NFC_CLK_MAX.
766  *      3) IPU HSP clock is independent of AHB clock. Even it can go up to
767  *         177MHz for higher voltage, this function fixes the max to 133MHz.
768  *      4) This function should not have allowed diag_printf() calls since
769  *         the serial driver has been stoped. But leave then here to allow
770  *         easy debugging by NOT calling the cyg_hal_plf_serial_stop().
771  */
772 int mxc_set_clock(u32 ref, u32 freq, enum mxc_clock clk)
773 {
774         freq *= SZ_DEC_1M;
775
776         switch (clk) {
777         case MXC_ARM_CLK:
778                 if (config_core_clk(ref, freq))
779                         return -EINVAL;
780                 break;
781         case MXC_PERIPH_CLK:
782                 if (config_periph_clk(ref, freq))
783                         return -EINVAL;
784                 break;
785         case MXC_DDR_CLK:
786                 if (config_ddr_clk(freq))
787                         return -EINVAL;
788                 break;
789         case MXC_NFC_CLK:
790                 if (config_nfc_clk(freq))
791                         return -EINVAL;
792                 break;
793         default:
794                 printf("Warning:Unsupported or invalid clock type\n");
795         }
796
797         return 0;
798 }
799
800 #ifdef CONFIG_MX53
801 /*
802  * The clock for the external interface can be set to use internal clock
803  * if fuse bank 4, row 3, bit 2 is set.
804  * This is an undocumented feature and it was confirmed by Freescale's support:
805  * Fuses (but not pins) may be used to configure SATA clocks.
806  * Particularly the i.MX53 Fuse_Map contains the next information
807  * about configuring SATA clocks :  SATA_ALT_REF_CLK[1:0] (offset 0x180C)
808  * '00' - 100MHz (External)
809  * '01' - 50MHz (External)
810  * '10' - 120MHz, internal (USB PHY)
811  * '11' - Reserved
812 */
813 void mxc_set_sata_internal_clock(void)
814 {
815         u32 *tmp_base =
816                 (u32 *)(IIM_BASE_ADDR + 0x180c);
817
818         set_usb_phy_clk();
819
820         clrsetbits_le32(tmp_base, 0x6, 0x4);
821 }
822 #endif
823
824 /*
825  * Dump some core clockes.
826  */
827 int do_mx5_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
828 {
829         u32 freq;
830
831         freq = decode_pll(mxc_plls[PLL1_CLOCK], MXC_HCLK);
832         printf("PLL1       %8d MHz\n", freq / 1000000);
833         freq = decode_pll(mxc_plls[PLL2_CLOCK], MXC_HCLK);
834         printf("PLL2       %8d MHz\n", freq / 1000000);
835         freq = decode_pll(mxc_plls[PLL3_CLOCK], MXC_HCLK);
836         printf("PLL3       %8d MHz\n", freq / 1000000);
837 #ifdef  CONFIG_MX53
838         freq = decode_pll(mxc_plls[PLL4_CLOCK], MXC_HCLK);
839         printf("PLL4       %8d MHz\n", freq / 1000000);
840 #endif
841
842         printf("\n");
843         printf("AHB        %8d kHz\n", mxc_get_clock(MXC_AHB_CLK) / 1000);
844         printf("IPG        %8d kHz\n", mxc_get_clock(MXC_IPG_CLK) / 1000);
845         printf("IPG PERCLK %8d kHz\n", mxc_get_clock(MXC_IPG_PERCLK) / 1000);
846         printf("DDR        %8d kHz\n", mxc_get_clock(MXC_DDR_CLK) / 1000);
847
848         return 0;
849 }
850
851 /***************************************************/
852
853 U_BOOT_CMD(
854         clocks, CONFIG_SYS_MAXARGS, 1, do_mx5_showclocks,
855         "display clocks",
856         ""
857 );