]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/arm/cpu/armv7/mx6/clock.c
arm: mx6: don't print nonexistant PLL528 PFD3 value
[karo-tx-uboot.git] / arch / arm / cpu / armv7 / mx6 / clock.c
1 /*
2  * Copyright (C) 2010-2011 Freescale Semiconductor, Inc.
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6
7 #include <common.h>
8 #include <asm/io.h>
9 #include <asm/errno.h>
10 #include <asm/arch/imx-regs.h>
11 #include <asm/arch/crm_regs.h>
12 #include <asm/arch/clock.h>
13 #include <asm/arch/sys_proto.h>
14
15 enum pll_clocks {
16         PLL_ARM,        /* PLL1: ARM PLL */
17         PLL_BUS,        /* PLL2: System Bus PLL*/
18         PLL_USBOTG,     /* PLL3: OTG USB PLL */
19         PLL_AUDIO,      /* PLL4: Audio PLL */
20         PLL_VIDEO,      /* PLL5: Video PLL */
21         PLL_ENET,       /* PLL6: ENET PLL */
22         PLL_USB2,       /* PLL7: USB2 PLL */
23         PLL_MLB,        /* PLL8: MLB PLL */
24 };
25
26 struct mxc_ccm_reg *const imx_ccm = (void *)CCM_BASE_ADDR;
27 struct anatop_regs *const anatop = (void *)ANATOP_BASE_ADDR;
28
29 int clk_enable(struct clk *clk)
30 {
31         int ret = 0;
32
33         if (!clk)
34                 return 0;
35         if (clk->usecount == 0) {
36 debug("%s: Enabling %s clock\n", __func__, clk->name);
37                 ret = clk->enable(clk);
38                 if (ret)
39                         return ret;
40                 clk->usecount++;
41         }
42         assert(clk->usecount > 0);
43         return ret;
44 }
45
46 void clk_disable(struct clk *clk)
47 {
48         if (!clk)
49                 return;
50
51         assert(clk->usecount > 0);
52         if (!(--clk->usecount)) {
53                 if (clk->disable) {
54 debug("%s: Disabling %s clock\n", __func__, clk->name);
55                         clk->disable(clk);
56                 }
57         }
58 }
59
60 int clk_get_usecount(struct clk *clk)
61 {
62         if (clk == NULL)
63                 return 0;
64
65         return clk->usecount;
66 }
67
68 u32 clk_get_rate(struct clk *clk)
69 {
70         if (!clk)
71                 return 0;
72
73         return clk->rate;
74 }
75
76 struct clk *clk_get_parent(struct clk *clk)
77 {
78         if (!clk)
79                 return 0;
80
81         return clk->parent;
82 }
83
84 int clk_set_rate(struct clk *clk, unsigned long rate)
85 {
86         if (clk && clk->set_rate)
87                 clk->set_rate(clk, rate);
88         return clk->rate;
89 }
90
91 long clk_round_rate(struct clk *clk, unsigned long rate)
92 {
93         if (clk == NULL || !clk->round_rate)
94                 return 0;
95
96         return clk->round_rate(clk, rate);
97 }
98
99 int clk_set_parent(struct clk *clk, struct clk *parent)
100 {
101         debug("Setting parent of clk %p to %p (%p)\n", clk, parent,
102                 clk ? clk->parent : NULL);
103
104         if (!clk || clk == parent)
105                 return 0;
106
107         if (clk->set_parent) {
108                 int ret;
109
110                 ret = clk->set_parent(clk, parent);
111                 if (ret)
112                         return ret;
113         }
114         clk->parent = parent;
115         return 0;
116 }
117
118 #ifdef CONFIG_MXC_OCOTP
119 void enable_ocotp_clk(unsigned char enable)
120 {
121         u32 reg;
122
123         reg = __raw_readl(&imx_ccm->CCGR2);
124         if (enable)
125                 reg |= MXC_CCM_CCGR2_OCOTP_CTRL_MASK;
126         else
127                 reg &= ~MXC_CCM_CCGR2_OCOTP_CTRL_MASK;
128         __raw_writel(reg, &imx_ccm->CCGR2);
129 }
130 #endif
131
132 void enable_usboh3_clk(unsigned char enable)
133 {
134         u32 reg;
135
136         reg = __raw_readl(&imx_ccm->CCGR6);
137         if (enable)
138                 reg |= MXC_CCM_CCGR6_USBOH3_MASK;
139         else
140                 reg &= ~(MXC_CCM_CCGR6_USBOH3_MASK);
141         __raw_writel(reg, &imx_ccm->CCGR6);
142
143 }
144
145 #ifdef CONFIG_I2C_MXC
146 /* i2c_num can be from 0 - 2 */
147 int enable_i2c_clk(unsigned char enable, unsigned i2c_num)
148 {
149         u32 reg;
150         u32 mask;
151
152         if (i2c_num > 2)
153                 return -EINVAL;
154
155         mask = MXC_CCM_CCGR_CG_MASK
156                 << (MXC_CCM_CCGR2_I2C1_SERIAL_OFFSET + (i2c_num << 1));
157         reg = __raw_readl(&imx_ccm->CCGR2);
158         if (enable)
159                 reg |= mask;
160         else
161                 reg &= ~mask;
162         __raw_writel(reg, &imx_ccm->CCGR2);
163         return 0;
164 }
165 #endif
166
167 static u32 decode_pll(enum pll_clocks pll, u32 infreq)
168 {
169         u32 div;
170
171         switch (pll) {
172         case PLL_ARM:
173                 div = __raw_readl(&anatop->pll_arm);
174                 if (div & BM_ANADIG_PLL_ARM_BYPASS)
175                         /* Assume the bypass clock is always derived from OSC */
176                         return infreq;
177                 div &= BM_ANADIG_PLL_ARM_DIV_SELECT;
178
179                 return infreq * div / 2;
180         case PLL_BUS:
181                 div = __raw_readl(&anatop->pll_528);
182                 if (div & BM_ANADIG_PLL_SYS_BYPASS)
183                         return infreq;
184                 div &= BM_ANADIG_PLL_SYS_DIV_SELECT;
185
186                 return infreq * (20 + div * 2);
187         case PLL_USBOTG:
188                 div = __raw_readl(&anatop->usb1_pll_480_ctrl);
189                 if (div & BM_ANADIG_USB1_PLL_480_CTRL_BYPASS)
190                         return infreq;
191                 div &= BM_ANADIG_USB1_PLL_480_CTRL_DIV_SELECT;
192
193                 return infreq * (20 + div * 2);
194         case PLL_AUDIO:
195                 div = __raw_readl(&anatop->pll_audio);
196                 if (div & BM_ANADIG_PLL_AUDIO_BYPASS)
197                         return infreq;
198                 div &= BM_ANADIG_PLL_AUDIO_DIV_SELECT;
199
200                 return infreq * div;
201         case PLL_VIDEO:
202                 div = __raw_readl(&anatop->pll_video);
203                 if (div & BM_ANADIG_PLL_VIDEO_BYPASS)
204                         return infreq;
205                 div &= BM_ANADIG_PLL_VIDEO_DIV_SELECT;
206
207                 return infreq * div;
208         case PLL_ENET:
209                 div = __raw_readl(&anatop->pll_enet);
210                 if (div & BM_ANADIG_PLL_ENET_BYPASS)
211                         return infreq;
212                 div &= BM_ANADIG_PLL_ENET_DIV_SELECT;
213
214                 return (div == 3 ? 125000000 : 25000000 * div * 2);
215         case PLL_USB2:
216                 div = __raw_readl(&anatop->usb2_pll_480_ctrl);
217                 if (div & BM_ANADIG_USB2_PLL_480_CTRL_BYPASS)
218                         return infreq;
219                 div &= BM_ANADIG_USB2_PLL_480_CTRL_DIV_SELECT;
220
221                 return infreq * (20 + div * 2);
222         case PLL_MLB:
223                 div = __raw_readl(&anatop->pll_mlb);
224                 if (div & BM_ANADIG_PLL_MLB_BYPASS)
225                         return infreq;
226                 /* unknown external clock provided on MLB_CLK pin */
227                 return 0;
228         }
229         return 0;
230 }
231
232 static u32 get_mcu_main_clk(void)
233 {
234         u32 reg, freq;
235
236         reg = __raw_readl(&imx_ccm->cacrr);
237         reg &= MXC_CCM_CACRR_ARM_PODF_MASK;
238         reg >>= MXC_CCM_CACRR_ARM_PODF_OFFSET;
239         freq = decode_pll(PLL_ARM, MXC_HCLK);
240
241         return freq / (reg + 1);
242 }
243
244 u32 get_periph_clk(void)
245 {
246         u32 reg, freq = 0;
247
248         reg = __raw_readl(&imx_ccm->cbcdr);
249         if (reg & MXC_CCM_CBCDR_PERIPH_CLK_SEL) {
250                 reg = __raw_readl(&imx_ccm->cbcmr);
251                 reg &= MXC_CCM_CBCMR_PERIPH_CLK2_SEL_MASK;
252                 reg >>= MXC_CCM_CBCMR_PERIPH_CLK2_SEL_OFFSET;
253
254                 switch (reg) {
255                 case 0:
256                         freq = decode_pll(PLL_USBOTG, MXC_HCLK);
257                         break;
258                 case 1:
259                 case 2:
260                         freq = MXC_HCLK;
261                         break;
262                 }
263         } else {
264                 reg = __raw_readl(&imx_ccm->cbcmr);
265                 reg &= MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK;
266                 reg >>= MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_OFFSET;
267
268                 switch (reg) {
269                 case 0:
270                         freq = decode_pll(PLL_BUS, MXC_HCLK);
271                         break;
272                 case 1:
273                         freq = PLL2_PFD2_FREQ;
274                         break;
275                 case 2:
276                         freq = PLL2_PFD0_FREQ;
277                         break;
278                 case 3:
279                         freq = PLL2_PFD2_DIV_FREQ;
280                         break;
281                 }
282         }
283
284         return freq;
285 }
286
287 static u32 get_ipg_clk(void)
288 {
289         u32 reg, ipg_podf;
290
291         reg = __raw_readl(&imx_ccm->cbcdr);
292         reg &= MXC_CCM_CBCDR_IPG_PODF_MASK;
293         ipg_podf = reg >> MXC_CCM_CBCDR_IPG_PODF_OFFSET;
294
295         return get_ahb_clk() / (ipg_podf + 1);
296 }
297
298 static u32 get_ipg_per_clk(void)
299 {
300         u32 reg, perclk_podf;
301
302         reg = __raw_readl(&imx_ccm->cscmr1);
303         perclk_podf = reg & MXC_CCM_CSCMR1_PERCLK_PODF_MASK;
304
305         return get_ipg_clk() / (perclk_podf + 1);
306 }
307
308 static u32 get_uart_clk(void)
309 {
310         u32 reg, uart_podf;
311         u32 freq = PLL3_80M;
312         reg = __raw_readl(&imx_ccm->cscdr1);
313 #ifdef CONFIG_MX6SL
314         if (reg & MXC_CCM_CSCDR1_UART_CLK_SEL)
315                 freq = MXC_HCLK;
316 #endif
317         reg &= MXC_CCM_CSCDR1_UART_CLK_PODF_MASK;
318         uart_podf = reg >> MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET;
319
320         return freq / (uart_podf + 1);
321 }
322
323 static u32 get_cspi_clk(void)
324 {
325         u32 reg, cspi_podf;
326
327         reg = __raw_readl(&imx_ccm->cscdr2);
328         reg &= MXC_CCM_CSCDR2_ECSPI_CLK_PODF_MASK;
329         cspi_podf = reg >> MXC_CCM_CSCDR2_ECSPI_CLK_PODF_OFFSET;
330
331         return  PLL3_60M / (cspi_podf + 1);
332 }
333
334 static u32 get_axi_clk(void)
335 {
336         u32 root_freq, axi_podf;
337         u32 cbcdr =  __raw_readl(&imx_ccm->cbcdr);
338
339         axi_podf = cbcdr & MXC_CCM_CBCDR_AXI_PODF_MASK;
340         axi_podf >>= MXC_CCM_CBCDR_AXI_PODF_OFFSET;
341
342         if (cbcdr & MXC_CCM_CBCDR_AXI_SEL) {
343                 if (cbcdr & MXC_CCM_CBCDR_AXI_ALT_SEL)
344                         root_freq = PLL2_PFD2_FREQ;
345                 else
346                         root_freq = PLL3_PFD1_FREQ;
347         } else
348                 root_freq = get_periph_clk();
349
350         return  root_freq / (axi_podf + 1);
351 }
352
353 static u32 get_emi_slow_clk(void)
354 {
355         u32 emi_clk_sel, emi_slow_pof, cscmr1, root_freq = 0;
356
357         cscmr1 =  __raw_readl(&imx_ccm->cscmr1);
358         emi_clk_sel = cscmr1 & MXC_CCM_CSCMR1_ACLK_EMI_SLOW_MASK;
359         emi_clk_sel >>= MXC_CCM_CSCMR1_ACLK_EMI_SLOW_OFFSET;
360         emi_slow_pof = cscmr1 & MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_MASK;
361         emi_slow_pof >>= MXC_CCM_CSCMR1_ACLK_EMI_PODF_OFFSET;
362
363         switch (emi_clk_sel) {
364         case 0:
365                 root_freq = get_axi_clk();
366                 break;
367         case 1:
368                 root_freq = decode_pll(PLL_USBOTG, MXC_HCLK);
369                 break;
370         case 2:
371                 root_freq = PLL2_PFD2_FREQ;
372                 break;
373         case 3:
374                 root_freq = PLL2_PFD0_FREQ;
375                 break;
376         }
377
378         return root_freq / (emi_slow_pof + 1);
379 }
380
381 static u32 get_nfc_clk(void)
382 {
383         u32 cs2cdr = __raw_readl(&imx_ccm->cs2cdr);
384         u32 podf = (cs2cdr & MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK) >> MXC_CCM_CS2CDR_ENFC_CLK_PODF_OFFSET;
385         u32 pred = (cs2cdr & MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK) >> MXC_CCM_CS2CDR_ENFC_CLK_PRED_OFFSET;
386         int nfc_clk_sel = (cs2cdr & MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK) >>
387                 MXC_CCM_CS2CDR_ENFC_CLK_SEL_OFFSET;
388         u32 root_freq;
389
390         switch (nfc_clk_sel) {
391         case 0:
392                 root_freq = PLL2_PFD0_FREQ;
393                 break;
394         case 1:
395                 root_freq = decode_pll(PLL_BUS, MXC_HCLK);
396                 break;
397         case 2:
398                 root_freq = decode_pll(PLL_USBOTG, MXC_HCLK);
399                 break;
400         case 3:
401                 root_freq = PLL2_PFD2_FREQ;
402                 break;
403         }
404
405         return root_freq / (pred + 1) / (podf + 1);
406 }
407
408 #define CS2CDR_ENFC_MASK        (MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK |    \
409                                 MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK |     \
410                                 MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK)
411
412 static int set_nfc_clk(u32 ref, u32 freq_khz)
413 {
414         u32 cs2cdr = __raw_readl(&imx_ccm->cs2cdr);
415         u32 podf;
416         u32 pred;
417         int nfc_clk_sel;
418         u32 root_freq;
419         u32 min_err = ~0;
420         u32 nfc_val = ~0;
421         u32 freq = freq_khz * 1000;
422
423         for (nfc_clk_sel = 0; nfc_clk_sel < 4; nfc_clk_sel++) {
424                 u32 act_freq;
425                 u32 err;
426
427                 if (ref < 4 && ref != nfc_clk_sel)
428                         continue;
429
430                 switch (nfc_clk_sel) {
431                 case 0:
432                         root_freq = PLL2_PFD0_FREQ;
433                         break;
434                 case 1:
435                         root_freq = decode_pll(PLL_BUS, MXC_HCLK);
436                         break;
437                 case 2:
438                         root_freq = decode_pll(PLL_USBOTG, MXC_HCLK);
439                         break;
440                 case 3:
441                         root_freq = PLL2_PFD2_FREQ;
442                         break;
443                 }
444                 if (root_freq < freq)
445                         continue;
446
447                 podf = min(DIV_ROUND_UP(root_freq, freq), 1 << 6);
448                 pred = min(DIV_ROUND_UP(root_freq / podf, freq), 8);
449                 act_freq = root_freq / pred / podf;
450                 err = (freq - act_freq) * 100 / freq;
451                 debug("root=%d[%u] freq=%u pred=%u podf=%u act=%u err=%d\n",
452                         nfc_clk_sel, root_freq, freq, pred, podf, act_freq, err);
453                 if (act_freq > freq)
454                         continue;
455                 if (err < min_err) {
456                         nfc_val = (podf - 1) << MXC_CCM_CS2CDR_ENFC_CLK_PODF_OFFSET;
457                         nfc_val |= (pred - 1) << MXC_CCM_CS2CDR_ENFC_CLK_PRED_OFFSET;
458                         nfc_val |= nfc_clk_sel << MXC_CCM_CS2CDR_ENFC_CLK_SEL_OFFSET;
459                         min_err = err;
460                         if (err == 0)
461                                 break;
462                 }
463         }
464
465         if (nfc_val == ~0 || min_err > 10)
466                 return -EINVAL;
467
468         if ((cs2cdr & CS2CDR_ENFC_MASK) != nfc_val) {
469                 debug("changing cs2cdr from %08x to %08x\n", cs2cdr,
470                         (cs2cdr & ~CS2CDR_ENFC_MASK) | nfc_val);
471                 __raw_writel((cs2cdr & ~CS2CDR_ENFC_MASK) | nfc_val,
472                         &imx_ccm->cs2cdr);
473         } else {
474                 debug("Leaving cs2cdr unchanged [%08x]\n", cs2cdr);
475         }
476         return 0;
477 }
478
479 #ifdef CONFIG_MX6SL
480 static u32 get_mmdc_ch0_clk(void)
481 {
482         u32 cbcmr = __raw_readl(&imx_ccm->cbcmr);
483         u32 cbcdr = __raw_readl(&imx_ccm->cbcdr);
484         u32 freq, podf;
485
486         podf = (cbcdr & MXC_CCM_CBCDR_MMDC_CH1_PODF_MASK) \
487                         >> MXC_CCM_CBCDR_MMDC_CH1_PODF_OFFSET;
488
489         switch ((cbcmr & MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_MASK) >>
490                 MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_OFFSET) {
491         case 0:
492                 freq = decode_pll(PLL_BUS, MXC_HCLK);
493                 break;
494         case 1:
495                 freq = PLL2_PFD2_FREQ;
496                 break;
497         case 2:
498                 freq = PLL2_PFD0_FREQ;
499                 break;
500         case 3:
501                 freq = PLL2_PFD2_DIV_FREQ;
502         }
503
504         return freq / (podf + 1);
505
506 }
507 #else
508 static u32 get_mmdc_ch0_clk(void)
509 {
510         u32 cbcdr = __raw_readl(&imx_ccm->cbcdr);
511         u32 mmdc_ch0_podf = (cbcdr & MXC_CCM_CBCDR_MMDC_CH0_PODF_MASK) >>
512                                 MXC_CCM_CBCDR_MMDC_CH0_PODF_OFFSET;
513
514         return get_periph_clk() / (mmdc_ch0_podf + 1);
515 }
516 #endif
517
518 static u32 get_usdhc_clk(u32 port)
519 {
520         u32 root_freq = 0, usdhc_podf = 0, clk_sel = 0;
521         u32 cscmr1 = __raw_readl(&imx_ccm->cscmr1);
522         u32 cscdr1 = __raw_readl(&imx_ccm->cscdr1);
523
524         switch (port) {
525         case 0:
526                 usdhc_podf = (cscdr1 & MXC_CCM_CSCDR1_USDHC1_PODF_MASK) >>
527                                         MXC_CCM_CSCDR1_USDHC1_PODF_OFFSET;
528                 clk_sel = cscmr1 & MXC_CCM_CSCMR1_USDHC1_CLK_SEL;
529
530                 break;
531         case 1:
532                 usdhc_podf = (cscdr1 & MXC_CCM_CSCDR1_USDHC2_PODF_MASK) >>
533                                         MXC_CCM_CSCDR1_USDHC2_PODF_OFFSET;
534                 clk_sel = cscmr1 & MXC_CCM_CSCMR1_USDHC2_CLK_SEL;
535
536                 break;
537         case 2:
538                 usdhc_podf = (cscdr1 & MXC_CCM_CSCDR1_USDHC3_PODF_MASK) >>
539                                         MXC_CCM_CSCDR1_USDHC3_PODF_OFFSET;
540                 clk_sel = cscmr1 & MXC_CCM_CSCMR1_USDHC3_CLK_SEL;
541
542                 break;
543         case 3:
544                 usdhc_podf = (cscdr1 & MXC_CCM_CSCDR1_USDHC4_PODF_MASK) >>
545                                         MXC_CCM_CSCDR1_USDHC4_PODF_OFFSET;
546                 clk_sel = cscmr1 & MXC_CCM_CSCMR1_USDHC4_CLK_SEL;
547
548                 break;
549         default:
550                 break;
551         }
552
553         if (clk_sel)
554                 root_freq = PLL2_PFD0_FREQ;
555         else
556                 root_freq = PLL2_PFD2_FREQ;
557
558         return root_freq / (usdhc_podf + 1);
559 }
560
561 u32 imx_get_uartclk(void)
562 {
563         return get_uart_clk();
564 }
565
566 u32 imx_get_fecclk(void)
567 {
568         return decode_pll(PLL_ENET, MXC_HCLK);
569 }
570
571 int enable_sata_clock(void)
572 {
573         u32 reg;
574         s32 timeout = 100000;
575
576         /* Enable sata clock */
577         reg = readl(&imx_ccm->CCGR5); /* CCGR5 */
578         reg |= MXC_CCM_CCGR5_SATA_MASK;
579         writel(reg, &imx_ccm->CCGR5);
580
581         /* Enable PLLs */
582         reg = readl(&anatop->pll_enet);
583         reg &= ~BM_ANADIG_PLL_ENET_POWERDOWN;
584         writel(reg, &anatop->pll_enet);
585         reg |= BM_ANADIG_PLL_ENET_ENABLE;
586         while (timeout--) {
587                 if (readl(&anatop->pll_enet) & BM_ANADIG_PLL_ENET_LOCK)
588                         break;
589         }
590         if (timeout <= 0)
591                 return -EIO;
592         reg &= ~BM_ANADIG_PLL_ENET_BYPASS;
593         writel(reg, &anatop->pll_enet);
594         reg |= BM_ANADIG_PLL_ENET_ENABLE_SATA;
595         writel(reg, &anatop->pll_enet);
596
597         return 0 ;
598 }
599
600 void ipu_clk_enable(void)
601 {
602         u32 reg = readl(&imx_ccm->CCGR3);
603         reg |= MXC_CCM_CCGR3_IPU1_IPU_MASK;
604         writel(reg, &imx_ccm->CCGR3);
605 }
606
607 void ipu_clk_disable(void)
608 {
609         u32 reg = readl(&imx_ccm->CCGR3);
610         reg &= ~MXC_CCM_CCGR3_IPU1_IPU_MASK;
611         writel(reg, &imx_ccm->CCGR3);
612 }
613
614 void ipu_di_clk_enable(int di)
615 {
616         switch (di) {
617         case 0:
618                 setbits_le32(&imx_ccm->CCGR3,
619                         MXC_CCM_CCGR3_IPU1_IPU_DI0_MASK);
620                 break;
621         case 1:
622                 setbits_le32(&imx_ccm->CCGR3,
623                         MXC_CCM_CCGR3_IPU1_IPU_DI1_MASK);
624                 break;
625         default:
626                 printf("%s: Invalid DI index %d\n", __func__, di);
627         }
628 }
629
630 void ipu_di_clk_disable(int di)
631 {
632         switch (di) {
633         case 0:
634                 clrbits_le32(&imx_ccm->CCGR3,
635                         MXC_CCM_CCGR3_IPU1_IPU_DI0_MASK);
636                 break;
637         case 1:
638                 clrbits_le32(&imx_ccm->CCGR3,
639                         MXC_CCM_CCGR3_IPU1_IPU_DI1_MASK);
640                 break;
641         default:
642                 printf("%s: Invalid DI index %d\n", __func__, di);
643         }
644 }
645
646 void ldb_clk_enable(int ldb)
647 {
648         switch (ldb) {
649         case 0:
650                 setbits_le32(&imx_ccm->CCGR3,
651                         MXC_CCM_CCGR3_LDB_DI0_MASK);
652                 break;
653         case 1:
654                 setbits_le32(&imx_ccm->CCGR3,
655                         MXC_CCM_CCGR3_LDB_DI1_MASK);
656                 break;
657         default:
658                 printf("%s: Invalid LDB index %d\n", __func__, ldb);
659         }
660 }
661
662 void ldb_clk_disable(int ldb)
663 {
664         switch (ldb) {
665         case 0:
666                 clrbits_le32(&imx_ccm->CCGR3,
667                         MXC_CCM_CCGR3_LDB_DI0_MASK);
668                 break;
669         case 1:
670                 clrbits_le32(&imx_ccm->CCGR3,
671                         MXC_CCM_CCGR3_LDB_DI1_MASK);
672                 break;
673         default:
674                 printf("%s: Invalid LDB index %d\n", __func__, ldb);
675         }
676 }
677
678 void ocotp_clk_enable(void)
679 {
680         u32 reg = readl(&imx_ccm->CCGR2);
681         reg |= MXC_CCM_CCGR2_OCOTP_CTRL_MASK;
682         writel(reg, &imx_ccm->CCGR2);
683 }
684
685 void ocotp_clk_disable(void)
686 {
687         u32 reg = readl(&imx_ccm->CCGR2);
688         reg &= ~MXC_CCM_CCGR2_OCOTP_CTRL_MASK;
689         writel(reg, &imx_ccm->CCGR2);
690 }
691
692 unsigned int mxc_get_clock(enum mxc_clock clk)
693 {
694         switch (clk) {
695         case MXC_ARM_CLK:
696                 return get_mcu_main_clk();
697         case MXC_PER_CLK:
698                 return get_periph_clk();
699         case MXC_AHB_CLK:
700                 return get_ahb_clk();
701         case MXC_IPG_CLK:
702                 return get_ipg_clk();
703         case MXC_IPG_PERCLK:
704         case MXC_I2C_CLK:
705                 return get_ipg_per_clk();
706         case MXC_UART_CLK:
707                 return get_uart_clk();
708         case MXC_CSPI_CLK:
709                 return get_cspi_clk();
710         case MXC_AXI_CLK:
711                 return get_axi_clk();
712         case MXC_EMI_SLOW_CLK:
713                 return get_emi_slow_clk();
714         case MXC_DDR_CLK:
715                 return get_mmdc_ch0_clk();
716         case MXC_ESDHC_CLK:
717                 return get_usdhc_clk(0);
718         case MXC_ESDHC2_CLK:
719                 return get_usdhc_clk(1);
720         case MXC_ESDHC3_CLK:
721                 return get_usdhc_clk(2);
722         case MXC_ESDHC4_CLK:
723                 return get_usdhc_clk(3);
724         case MXC_SATA_CLK:
725                 return get_ahb_clk();
726         case MXC_NFC_CLK:
727                 return get_nfc_clk();
728         }
729
730         return -1;
731 }
732
733 static inline int gcd(int m, int n)
734 {
735         int t;
736         while (m > 0) {
737                 if (n > m) {
738                         t = m;
739                         m = n;
740                         n = t;
741                 } /* swap */
742                 m -= n;
743         }
744         return n;
745 }
746
747 /* Config CPU clock */
748 static int set_arm_clk(u32 ref, u32 freq_khz)
749 {
750         int d;
751         int div = 0;
752         int mul = 0;
753         u32 min_err = ~0;
754         u32 reg;
755
756         if (freq_khz > ref / 1000 * 108 / 2 || freq_khz < ref / 1000 * 54 / 8 / 2) {
757                 printf("Frequency %u.%03uMHz is out of range: %u.%03u..%u.%03u\n",
758                         freq_khz / 1000, freq_khz % 1000,
759                         54 * ref / 1000000 / 8 / 2, 54 * ref / 1000 / 8 / 2 % 1000,
760                         108 * ref / 1000000 / 2, 108 * ref / 1000 / 2 % 1000);
761                 return -EINVAL;
762         }
763
764         for (d = DIV_ROUND_UP(648000, freq_khz); d <= 8; d++) {
765                 int m = freq_khz * 2 * d / (ref / 1000);
766                 u32 f;
767                 u32 err;
768
769                 if (m > 108) {
770                         debug("%s@%d: d=%d m=%d\n", __func__, __LINE__,
771                                 d, m);
772                         break;
773                 }
774
775                 f = ref * m / d / 2;
776                 if (f > freq_khz * 1000) {
777                         debug("%s@%d: d=%d m=%d f=%u freq=%u\n", __func__, __LINE__,
778                                 d, m, f, freq_khz);
779                         if (--m < 54)
780                                 return -EINVAL;
781                         f = ref * m / d / 2;
782                 }
783                 err = freq_khz * 1000 - f;
784                 debug("%s@%d: d=%d m=%d f=%u freq=%u err=%d\n", __func__, __LINE__,
785                         d, m, f, freq_khz, err);
786                 if (err < min_err) {
787                         mul = m;
788                         div = d;
789                         min_err = err;
790                         if (err == 0)
791                                 break;
792                 }
793         }
794         if (min_err == ~0)
795                 return -EINVAL;
796         debug("Setting M=%3u D=%2u for %u.%03uMHz (actual: %u.%03uMHz)\n",
797                 mul, div, freq_khz / 1000, freq_khz % 1000,
798                 ref * mul / 2 / div / 1000000, ref * mul / 2 / div / 1000 % 1000);
799
800         reg = readl(&anatop->pll_arm);
801         debug("anadig_pll_arm=%08x -> %08x\n",
802                 reg, (reg & ~0x7f) | mul);
803
804         reg |= 1 << 16;
805         writel(reg, &anatop->pll_arm); /* bypass PLL */
806
807         reg = (reg & ~0x7f) | mul;
808         writel(reg, &anatop->pll_arm);
809
810         writel(div - 1, &imx_ccm->cacrr);
811
812         reg &= ~(1 << 16);
813         writel(reg, &anatop->pll_arm); /* disable PLL bypass */
814
815         return 0;
816 }
817
818 /*
819  * This function assumes the expected core clock has to be changed by
820  * modifying the PLL. This is NOT true always but for most of the times,
821  * it is. So it assumes the PLL output freq is the same as the expected
822  * core clock (presc=1) unless the core clock is less than PLL_FREQ_MIN.
823  * In the latter case, it will try to increase the presc value until
824  * (presc*core_clk) is greater than PLL_FREQ_MIN. It then makes call to
825  * calc_pll_params() and obtains the values of PD, MFI,MFN, MFD based
826  * on the targeted PLL and reference input clock to the PLL. Lastly,
827  * it sets the register based on these values along with the dividers.
828  * Note 1) There is no value checking for the passed-in divider values
829  *         so the caller has to make sure those values are sensible.
830  *      2) Also adjust the NFC divider such that the NFC clock doesn't
831  *         exceed NFC_CLK_MAX.
832  *      3) IPU HSP clock is independent of AHB clock. Even it can go up to
833  *         177MHz for higher voltage, this function fixes the max to 133MHz.
834  *      4) This function should not have allowed diag_printf() calls since
835  *         the serial driver has been stoped. But leave then here to allow
836  *         easy debugging by NOT calling the cyg_hal_plf_serial_stop().
837  */
838 int mxc_set_clock(u32 ref, u32 freq, enum mxc_clock clk)
839 {
840         int ret;
841
842         freq *= 1000;
843
844         switch (clk) {
845         case MXC_ARM_CLK:
846                 ret = set_arm_clk(ref, freq);
847                 break;
848
849         case MXC_NFC_CLK:
850                 ret = set_nfc_clk(ref, freq);
851                 break;
852
853         default:
854                 printf("Warning: Unsupported or invalid clock type: %d\n",
855                         clk);
856                 return -EINVAL;
857         }
858
859         return ret;
860 }
861
862 /*
863  * Dump some core clocks.
864  */
865 #define print_pll(pll)  {                               \
866         u32 __pll = decode_pll(pll, MXC_HCLK);          \
867         printf("%-12s %4d.%03d MHz\n", #pll,            \
868                 __pll / 1000000, __pll / 1000 % 1000);  \
869         }
870
871 #define MXC_IPG_PER_CLK MXC_IPG_PERCLK
872
873 #define print_clk(clk)  {                               \
874         u32 __clk = mxc_get_clock(MXC_##clk##_CLK);     \
875         printf("%-12s %4d.%03d MHz\n", #clk,            \
876                 __clk / 1000000, __clk / 1000 % 1000);  \
877         }
878
879 #define print_pfd(pll, pfd)     {                                       \
880         u32 __pfd = readl(&anatop->pfd_##pll);                          \
881         if (__pfd & (0x80 << 8 * pfd)) {                                \
882                 printf("PFD_%s[%d]      OFF\n", #pll, pfd);             \
883         } else {                                                        \
884                 __pfd = (__pfd >> 8 * pfd) & 0x3f;                      \
885                 printf("PFD_%s[%d]   %4d.%03d MHz\n", #pll, pfd,        \
886                         pll * 18 / __pfd,                               \
887                         pll * 18 * 1000 / __pfd % 1000);                \
888         }                                                               \
889 }
890
891 static void do_mx6_showclocks(void)
892 {
893         print_pll(PLL_ARM);
894         print_pll(PLL_BUS);
895         print_pll(PLL_USBOTG);
896         print_pll(PLL_AUDIO);
897         print_pll(PLL_VIDEO);
898         print_pll(PLL_ENET);
899         print_pll(PLL_USB2);
900         printf("\n");
901
902         print_pfd(480, 0);
903         print_pfd(480, 1);
904         print_pfd(480, 2);
905         print_pfd(480, 3);
906         print_pfd(528, 0);
907         print_pfd(528, 1);
908         print_pfd(528, 2);
909         printf("\n");
910
911         print_clk(IPG);
912         print_clk(UART);
913         print_clk(CSPI);
914         print_clk(AHB);
915         print_clk(AXI);
916         print_clk(DDR);
917         print_clk(ESDHC);
918         print_clk(ESDHC2);
919         print_clk(ESDHC3);
920         print_clk(ESDHC4);
921         print_clk(EMI_SLOW);
922         print_clk(NFC);
923         print_clk(IPG_PER);
924         print_clk(ARM);
925 }
926
927 static struct clk_lookup {
928         const char *name;
929         unsigned int index;
930 } mx6_clk_lookup[] = {
931         { "arm", MXC_ARM_CLK, },
932         { "nfc", MXC_NFC_CLK, },
933 };
934
935 int do_clocks(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
936 {
937         int i;
938         unsigned long freq;
939         unsigned long ref = ~0UL;
940
941         if (argc < 2) {
942                 do_mx6_showclocks();
943                 return CMD_RET_SUCCESS;
944         } else if (argc == 2 || argc > 4) {
945                 return CMD_RET_USAGE;
946         }
947
948         freq = simple_strtoul(argv[2], NULL, 0);
949         if (freq == 0) {
950                 printf("Invalid clock frequency %lu\n", freq);
951                 return CMD_RET_FAILURE;
952         }
953         if (argc > 3) {
954                 ref = simple_strtoul(argv[3], NULL, 0);
955         }
956         for (i = 0; i < ARRAY_SIZE(mx6_clk_lookup); i++) {
957                 if (strcasecmp(argv[1], mx6_clk_lookup[i].name) == 0) {
958                         switch (mx6_clk_lookup[i].index) {
959                         case MXC_ARM_CLK:
960                                 if (argc > 3)
961                                         return CMD_RET_USAGE;
962                                 ref = CONFIG_SYS_MX6_HCLK;
963                                 break;
964
965                         case MXC_NFC_CLK:
966                                 if (argc > 3 && ref > 3) {
967                                         printf("Invalid clock selector value: %lu\n", ref);
968                                         return CMD_RET_FAILURE;
969                                 }
970                                 break;
971                         }
972                         printf("Setting %s clock to %lu MHz\n",
973                                 mx6_clk_lookup[i].name, freq);
974                         if (mxc_set_clock(ref, freq, mx6_clk_lookup[i].index))
975                                 break;
976                         freq = mxc_get_clock(mx6_clk_lookup[i].index);
977                         printf("%s clock set to %lu.%03lu MHz\n",
978                                 mx6_clk_lookup[i].name,
979                                 freq / 1000000, freq / 1000 % 1000);
980                         return CMD_RET_SUCCESS;
981                 }
982         }
983         if (i == ARRAY_SIZE(mx6_clk_lookup)) {
984                 printf("clock %s not found; supported clocks are:\n", argv[1]);
985                 for (i = 0; i < ARRAY_SIZE(mx6_clk_lookup); i++) {
986                         printf("\t%s\n", mx6_clk_lookup[i].name);
987                 }
988         } else {
989                 printf("Failed to set clock %s to %s MHz\n",
990                         argv[1], argv[2]);
991         }
992         return CMD_RET_FAILURE;
993 }
994
995 /***************************************************/
996
997 U_BOOT_CMD(
998         clocks, 4, 0, do_clocks,
999         "display/set clocks",
1000         "                    - display clock settings\n"
1001         "clocks <clkname> <freq>    - set clock <clkname> to <freq> MHz"
1002 );