]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/arm/cpu/armv7/mx6/clock.c
TX6 Release 2013-04-22
[karo-tx-uboot.git] / arch / arm / cpu / armv7 / mx6 / clock.c
1 /*
2  * Copyright (C) 2010-2011 Freescale Semiconductor, Inc.
3  *
4  * See file CREDITS for list of people who contributed to this
5  * project.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as
9  * published by the Free Software Foundation; either version 2 of
10  * the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20  * MA 02111-1307 USA
21  */
22 //#define DEBUG
23
24 #include <common.h>
25 #include <asm/io.h>
26 #include <asm/errno.h>
27 #include <asm/arch/imx-regs.h>
28 #include <asm/arch/crm_regs.h>
29 #include <asm/arch/clock.h>
30 #include <asm/arch/sys_proto.h>
31
32 enum pll_clocks {
33         PLL_ARM,        /* PLL1: ARM PLL */
34         PLL_BUS,        /* PLL2: System Bus PLL*/
35         PLL_USBOTG,     /* PLL3: OTG USB PLL */
36         PLL_AUDIO,      /* PLL4: Audio PLL */
37         PLL_VIDEO,      /* PLL5: Video PLL */
38         PLL_ENET,       /* PLL6: ENET PLL */
39         PLL_USB2,       /* PLL7: USB2 PLL */
40         PLL_MLB,        /* PLL8: MLB PLL */
41 };
42
43 struct mxc_ccm_reg *const imx_ccm = (void *)CCM_BASE_ADDR;
44 struct anatop_regs *const anatop = (void *)ANATOP_BASE_ADDR;
45
46 int clk_enable(struct clk *clk)
47 {
48         int ret = 0;
49
50         if (!clk)
51                 return 0;
52         if (clk->usecount == 0) {
53 debug("%s: Enabling %s clock\n", __func__, clk->name);
54                 ret = clk->enable(clk);
55                 if (ret)
56                         return ret;
57                 clk->usecount++;
58         }
59         assert(clk->usecount > 0);
60         return ret;
61 }
62
63 void clk_disable(struct clk *clk)
64 {
65         if (!clk)
66                 return;
67
68         assert(clk->usecount > 0);
69         if (!(--clk->usecount)) {
70                 if (clk->disable) {
71 debug("%s: Disabling %s clock\n", __func__, clk->name);
72                         clk->disable(clk);
73                 }
74         }
75 }
76
77 void enable_usboh3_clk(unsigned char enable)
78 {
79         u32 reg;
80
81         reg = __raw_readl(&imx_ccm->CCGR6);
82         if (enable)
83                 reg |= MXC_CCM_CCGR6_USBOH3_MASK;
84         else
85                 reg &= ~(MXC_CCM_CCGR6_USBOH3_MASK);
86         __raw_writel(reg, &imx_ccm->CCGR6);
87
88 }
89
90 #ifdef CONFIG_I2C_MXC
91 /* i2c_num can be from 0 - 2 */
92 int enable_i2c_clk(unsigned char enable, unsigned i2c_num)
93 {
94         u32 reg;
95         u32 mask;
96
97         if (i2c_num > 2)
98                 return -EINVAL;
99
100         mask = MXC_CCM_CCGR_CG_MASK
101                 << (MXC_CCM_CCGR2_I2C1_SERIAL_OFFSET + (i2c_num << 1));
102         reg = __raw_readl(&imx_ccm->CCGR2);
103         if (enable)
104                 reg |= mask;
105         else
106                 reg &= ~mask;
107         __raw_writel(reg, &imx_ccm->CCGR2);
108         return 0;
109 }
110 #endif
111
112 static u32 decode_pll(enum pll_clocks pll, u32 infreq)
113 {
114         u32 div;
115
116         switch (pll) {
117         case PLL_ARM:
118                 div = __raw_readl(&anatop->pll_arm);
119                 if (div & BM_ANADIG_PLL_ARM_BYPASS)
120                         /* Assume the bypass clock is always derived from OSC */
121                         return infreq;
122                 div &= BM_ANADIG_PLL_ARM_DIV_SELECT;
123
124                 return infreq * div / 2;
125         case PLL_BUS:
126                 div = __raw_readl(&anatop->pll_528);
127                 if (div & BM_ANADIG_PLL_SYS_BYPASS)
128                         return infreq;
129                 div &= BM_ANADIG_PLL_SYS_DIV_SELECT;
130
131                 return infreq * (20 + div * 2);
132         case PLL_USBOTG:
133                 div = __raw_readl(&anatop->usb1_pll_480_ctrl);
134                 if (div & BM_ANADIG_USB1_PLL_480_CTRL_BYPASS)
135                         return infreq;
136                 div &= BM_ANADIG_USB1_PLL_480_CTRL_DIV_SELECT;
137
138                 return infreq * (20 + div * 2);
139         case PLL_AUDIO:
140                 div = __raw_readl(&anatop->pll_audio);
141                 if (div & BM_ANADIG_PLL_AUDIO_BYPASS)
142                         return infreq;
143                 div &= BM_ANADIG_PLL_AUDIO_DIV_SELECT;
144
145                 return infreq * div;
146         case PLL_VIDEO:
147                 div = __raw_readl(&anatop->pll_video);
148                 if (div & BM_ANADIG_PLL_VIDEO_BYPASS)
149                         return infreq;
150                 div &= BM_ANADIG_PLL_VIDEO_DIV_SELECT;
151
152                 return infreq * div;
153         case PLL_ENET:
154                 div = __raw_readl(&anatop->pll_enet);
155                 if (div & BM_ANADIG_PLL_ENET_BYPASS)
156                         return infreq;
157                 div &= BM_ANADIG_PLL_ENET_DIV_SELECT;
158
159                 return (div == 3 ? 125000000 : 25000000 * div * 2);
160         case PLL_USB2:
161                 div = __raw_readl(&anatop->usb2_pll_480_ctrl);
162                 if (div & BM_ANADIG_USB2_PLL_480_CTRL_BYPASS)
163                         return infreq;
164                 div &= BM_ANADIG_USB2_PLL_480_CTRL_DIV_SELECT;
165
166                 return infreq * (20 + div * 2);
167         case PLL_MLB:
168                 div = __raw_readl(&anatop->pll_mlb);
169                 if (div & BM_ANADIG_PLL_MLB_BYPASS)
170                         return infreq;
171                 /* unknown external clock provided on MLB_CLK pin */
172                 return 0;
173         }
174         return 0;
175 }
176
177 static u32 get_mcu_main_clk(void)
178 {
179         u32 reg, freq;
180
181         reg = __raw_readl(&imx_ccm->cacrr);
182         reg &= MXC_CCM_CACRR_ARM_PODF_MASK;
183         reg >>= MXC_CCM_CACRR_ARM_PODF_OFFSET;
184         freq = decode_pll(PLL_ARM, MXC_HCLK);
185
186         return freq / (reg + 1);
187 }
188
189 u32 get_periph_clk(void)
190 {
191         u32 reg, freq = 0;
192
193         reg = __raw_readl(&imx_ccm->cbcdr);
194         if (reg & MXC_CCM_CBCDR_PERIPH_CLK_SEL) {
195                 reg = __raw_readl(&imx_ccm->cbcmr);
196                 reg &= MXC_CCM_CBCMR_PERIPH_CLK2_SEL_MASK;
197                 reg >>= MXC_CCM_CBCMR_PERIPH_CLK2_SEL_OFFSET;
198
199                 switch (reg) {
200                 case 0:
201                         freq = decode_pll(PLL_USBOTG, MXC_HCLK);
202                         break;
203                 case 1:
204                 case 2:
205                         freq = MXC_HCLK;
206                         break;
207                 }
208         } else {
209                 reg = __raw_readl(&imx_ccm->cbcmr);
210                 reg &= MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK;
211                 reg >>= MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_OFFSET;
212
213                 switch (reg) {
214                 case 0:
215                         freq = decode_pll(PLL_BUS, MXC_HCLK);
216                         break;
217                 case 1:
218                         freq = PLL2_PFD2_FREQ;
219                         break;
220                 case 2:
221                         freq = PLL2_PFD0_FREQ;
222                         break;
223                 case 3:
224                         freq = PLL2_PFD2_DIV_FREQ;
225                         break;
226                 }
227         }
228
229         return freq;
230 }
231
232 static u32 get_ipg_clk(void)
233 {
234         u32 reg, ipg_podf;
235
236         reg = __raw_readl(&imx_ccm->cbcdr);
237         reg &= MXC_CCM_CBCDR_IPG_PODF_MASK;
238         ipg_podf = reg >> MXC_CCM_CBCDR_IPG_PODF_OFFSET;
239
240         return get_ahb_clk() / (ipg_podf + 1);
241 }
242
243 static u32 get_ipg_per_clk(void)
244 {
245         u32 reg, perclk_podf;
246
247         reg = __raw_readl(&imx_ccm->cscmr1);
248         perclk_podf = reg & MXC_CCM_CSCMR1_PERCLK_PODF_MASK;
249
250         return get_ipg_clk() / (perclk_podf + 1);
251 }
252
253 static u32 get_uart_clk(void)
254 {
255         u32 reg, uart_podf;
256
257         reg = __raw_readl(&imx_ccm->cscdr1);
258         reg &= MXC_CCM_CSCDR1_UART_CLK_PODF_MASK;
259         uart_podf = reg >> MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET;
260
261         return PLL3_80M / (uart_podf + 1);
262 }
263
264 static u32 get_cspi_clk(void)
265 {
266         u32 reg, cspi_podf;
267
268         reg = __raw_readl(&imx_ccm->cscdr2);
269         reg &= MXC_CCM_CSCDR2_ECSPI_CLK_PODF_MASK;
270         cspi_podf = reg >> MXC_CCM_CSCDR2_ECSPI_CLK_PODF_OFFSET;
271
272         return  PLL3_60M / (cspi_podf + 1);
273 }
274
275 static u32 get_axi_clk(void)
276 {
277         u32 root_freq, axi_podf;
278         u32 cbcdr =  __raw_readl(&imx_ccm->cbcdr);
279
280         axi_podf = cbcdr & MXC_CCM_CBCDR_AXI_PODF_MASK;
281         axi_podf >>= MXC_CCM_CBCDR_AXI_PODF_OFFSET;
282
283         if (cbcdr & MXC_CCM_CBCDR_AXI_SEL) {
284                 if (cbcdr & MXC_CCM_CBCDR_AXI_ALT_SEL)
285                         root_freq = PLL2_PFD2_FREQ;
286                 else
287                         root_freq = PLL3_PFD1_FREQ;
288         } else
289                 root_freq = get_periph_clk();
290
291         return  root_freq / (axi_podf + 1);
292 }
293
294 static u32 get_emi_slow_clk(void)
295 {
296         u32 emi_clk_sel, emi_slow_pof, cscmr1, root_freq = 0;
297
298         cscmr1 =  __raw_readl(&imx_ccm->cscmr1);
299         emi_clk_sel = cscmr1 & MXC_CCM_CSCMR1_ACLK_EMI_SLOW_MASK;
300         emi_clk_sel >>= MXC_CCM_CSCMR1_ACLK_EMI_SLOW_OFFSET;
301         emi_slow_pof = cscmr1 & MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_MASK;
302         emi_slow_pof >>= MXC_CCM_CSCMR1_ACLK_EMI_PODF_OFFSET;
303
304         switch (emi_clk_sel) {
305         case 0:
306                 root_freq = get_axi_clk();
307                 break;
308         case 1:
309                 root_freq = decode_pll(PLL_USBOTG, MXC_HCLK);
310                 break;
311         case 2:
312                 root_freq = PLL2_PFD2_FREQ;
313                 break;
314         case 3:
315                 root_freq = PLL2_PFD0_FREQ;
316                 break;
317         }
318
319         return root_freq / (emi_slow_pof + 1);
320 }
321
322 static u32 get_nfc_clk(void)
323 {
324         u32 cs2cdr = __raw_readl(&imx_ccm->cs2cdr);
325         u32 podf = (cs2cdr & MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK) >> MXC_CCM_CS2CDR_ENFC_CLK_PODF_OFFSET;
326         u32 pred = (cs2cdr & MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK) >> MXC_CCM_CS2CDR_ENFC_CLK_PRED_OFFSET;
327         int nfc_clk_sel = (cs2cdr & MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK) >>
328                 MXC_CCM_CS2CDR_ENFC_CLK_SEL_OFFSET;
329         u32 root_freq;
330
331         switch (nfc_clk_sel) {
332         case 0:
333                 root_freq = PLL2_PFD0_FREQ;
334                 break;
335         case 1:
336                 root_freq = decode_pll(PLL_BUS, MXC_HCLK);
337                 break;
338         case 2:
339                 root_freq = decode_pll(PLL_USBOTG, MXC_HCLK);
340                 break;
341         case 3:
342                 root_freq = PLL2_PFD2_FREQ;
343                 break;
344         }
345
346         return root_freq / (pred + 1) / (podf + 1);
347 }
348
349 static u32 get_mmdc_ch0_clk(void)
350 {
351         u32 cbcdr = __raw_readl(&imx_ccm->cbcdr);
352         u32 mmdc_ch0_podf = (cbcdr & MXC_CCM_CBCDR_MMDC_CH0_PODF_MASK) >>
353                                 MXC_CCM_CBCDR_MMDC_CH0_PODF_OFFSET;
354
355         return get_periph_clk() / (mmdc_ch0_podf + 1);
356 }
357
358 static u32 get_usdhc_clk(u32 port)
359 {
360         u32 root_freq = 0, usdhc_podf = 0, clk_sel = 0;
361         u32 cscmr1 = __raw_readl(&imx_ccm->cscmr1);
362         u32 cscdr1 = __raw_readl(&imx_ccm->cscdr1);
363
364         switch (port) {
365         case 0:
366                 usdhc_podf = (cscdr1 & MXC_CCM_CSCDR1_USDHC1_PODF_MASK) >>
367                                         MXC_CCM_CSCDR1_USDHC1_PODF_OFFSET;
368                 clk_sel = cscmr1 & MXC_CCM_CSCMR1_USDHC1_CLK_SEL;
369
370                 break;
371         case 1:
372                 usdhc_podf = (cscdr1 & MXC_CCM_CSCDR1_USDHC2_PODF_MASK) >>
373                                         MXC_CCM_CSCDR1_USDHC2_PODF_OFFSET;
374                 clk_sel = cscmr1 & MXC_CCM_CSCMR1_USDHC2_CLK_SEL;
375
376                 break;
377         case 2:
378                 usdhc_podf = (cscdr1 & MXC_CCM_CSCDR1_USDHC3_PODF_MASK) >>
379                                         MXC_CCM_CSCDR1_USDHC3_PODF_OFFSET;
380                 clk_sel = cscmr1 & MXC_CCM_CSCMR1_USDHC3_CLK_SEL;
381
382                 break;
383         case 3:
384                 usdhc_podf = (cscdr1 & MXC_CCM_CSCDR1_USDHC4_PODF_MASK) >>
385                                         MXC_CCM_CSCDR1_USDHC4_PODF_OFFSET;
386                 clk_sel = cscmr1 & MXC_CCM_CSCMR1_USDHC4_CLK_SEL;
387
388                 break;
389         default:
390                 break;
391         }
392
393         if (clk_sel)
394                 root_freq = PLL2_PFD0_FREQ;
395         else
396                 root_freq = PLL2_PFD2_FREQ;
397
398         return root_freq / (usdhc_podf + 1);
399 }
400
401 u32 imx_get_uartclk(void)
402 {
403         return get_uart_clk();
404 }
405
406 u32 imx_get_fecclk(void)
407 {
408         return decode_pll(PLL_ENET, MXC_HCLK);
409 }
410
411 int enable_sata_clock(void)
412 {
413         u32 reg;
414         s32 timeout = 100000;
415
416         /* Enable sata clock */
417         reg = readl(&imx_ccm->CCGR5); /* CCGR5 */
418         reg |= MXC_CCM_CCGR5_SATA_MASK;
419         writel(reg, &imx_ccm->CCGR5);
420
421         /* Enable PLLs */
422         reg = readl(&anatop->pll_enet);
423         reg &= ~BM_ANADIG_PLL_ENET_POWERDOWN;
424         writel(reg, &anatop->pll_enet);
425         reg |= BM_ANADIG_PLL_ENET_ENABLE;
426         while (timeout--) {
427                 if (readl(&anatop->pll_enet) & BM_ANADIG_PLL_ENET_LOCK)
428                         break;
429         }
430         if (timeout <= 0)
431                 return -EIO;
432         reg &= ~BM_ANADIG_PLL_ENET_BYPASS;
433         writel(reg, &anatop->pll_enet);
434         reg |= BM_ANADIG_PLL_ENET_ENABLE_SATA;
435         writel(reg, &anatop->pll_enet);
436
437         return 0 ;
438 }
439
440 void ipu_clk_enable(void)
441 {
442         u32 reg = readl(&imx_ccm->CCGR3);
443         reg |= MXC_CCM_CCGR3_CG0_MASK;
444         writel(reg, &imx_ccm->CCGR3);
445 }
446
447 void ipu_clk_disable(void)
448 {
449         u32 reg = readl(&imx_ccm->CCGR3);
450         reg &= ~MXC_CCM_CCGR3_CG0_MASK;
451         writel(reg, &imx_ccm->CCGR3);
452 }
453
454 void ocotp_clk_enable(void)
455 {
456         u32 reg = readl(&imx_ccm->CCGR2);
457         reg |= MXC_CCM_CCGR2_CG6_MASK;
458         writel(reg, &imx_ccm->CCGR2);
459 }
460
461 void ocotp_clk_disable(void)
462 {
463         u32 reg = readl(&imx_ccm->CCGR2);
464         reg &= ~MXC_CCM_CCGR2_CG6_MASK;
465         writel(reg, &imx_ccm->CCGR2);
466 }
467
468 unsigned int mxc_get_clock(enum mxc_clock clk)
469 {
470         switch (clk) {
471         case MXC_ARM_CLK:
472                 return get_mcu_main_clk();
473         case MXC_PER_CLK:
474                 return get_periph_clk();
475         case MXC_AHB_CLK:
476                 return get_ahb_clk();
477         case MXC_IPG_CLK:
478                 return get_ipg_clk();
479         case MXC_IPG_PERCLK:
480         case MXC_I2C_CLK:
481                 return get_ipg_per_clk();
482         case MXC_UART_CLK:
483                 return get_uart_clk();
484         case MXC_CSPI_CLK:
485                 return get_cspi_clk();
486         case MXC_AXI_CLK:
487                 return get_axi_clk();
488         case MXC_EMI_SLOW_CLK:
489                 return get_emi_slow_clk();
490         case MXC_DDR_CLK:
491                 return get_mmdc_ch0_clk();
492         case MXC_ESDHC_CLK:
493                 return get_usdhc_clk(0);
494         case MXC_ESDHC2_CLK:
495                 return get_usdhc_clk(1);
496         case MXC_ESDHC3_CLK:
497                 return get_usdhc_clk(2);
498         case MXC_ESDHC4_CLK:
499                 return get_usdhc_clk(3);
500         case MXC_SATA_CLK:
501                 return get_ahb_clk();
502         case MXC_NFC_CLK:
503                 return get_nfc_clk();
504         }
505
506         return -1;
507 }
508
509 static inline int gcd(int m, int n)
510 {
511         int t;
512         while (m > 0) {
513                 if (n > m) {
514                         t = m;
515                         m = n;
516                         n = t;
517                 } /* swap */
518                 m -= n;
519         }
520         return n;
521 }
522
523 /* Config CPU clock */
524 static int config_core_clk(u32 ref, u32 freq)
525 {
526         int d;
527         int div = 0;
528         int mul = 0;
529         int min_err = ~0 >> 1;
530         u32 reg;
531
532         if (freq / ref > 108 || freq / ref * 8 < 54) {
533                 return -EINVAL;
534         }
535
536         for (d = 1; d < 8; d++) {
537                 int m = (freq + (ref - 1)) / ref;
538                 unsigned long f;
539                 int err;
540
541                 if (m > 108 || m < 54)
542                         return -EINVAL;
543
544                 f = ref * m / d;
545                 while (f > freq) {
546                         if (--m < 54)
547                                 return -EINVAL;
548                         f = ref * m / d;
549                 }
550                 err = freq - f;
551                 if (err == 0)
552                         break;
553                 if (err < 0)
554                         return -EINVAL;
555                 if (err < min_err) {
556                         mul = m;
557                         div = d;
558                 }
559         }
560         printf("Setting M=%3u D=%2u for %u.%03uMHz (actual: %u.%03uMHz)\n",
561                 mul, div, freq / 1000000, freq / 1000 % 1000,
562                 ref * mul / div / 1000000, ref * mul / div / 1000 % 1000);
563
564         reg = readl(&anatop->pll_arm);
565         printf("anadig_pll_arm=%08x -> %08x\n",
566                 reg, (reg & ~0x7f) | mul);
567 #if 0
568         writel(div - 1, &imx_ccm->caccr);
569         reg &= 0x7f;
570         writel(reg | mul, &anatop->pll_arm);
571 #endif
572         return 0;
573 }
574
575 /*
576  * This function assumes the expected core clock has to be changed by
577  * modifying the PLL. This is NOT true always but for most of the times,
578  * it is. So it assumes the PLL output freq is the same as the expected
579  * core clock (presc=1) unless the core clock is less than PLL_FREQ_MIN.
580  * In the latter case, it will try to increase the presc value until
581  * (presc*core_clk) is greater than PLL_FREQ_MIN. It then makes call to
582  * calc_pll_params() and obtains the values of PD, MFI,MFN, MFD based
583  * on the targeted PLL and reference input clock to the PLL. Lastly,
584  * it sets the register based on these values along with the dividers.
585  * Note 1) There is no value checking for the passed-in divider values
586  *         so the caller has to make sure those values are sensible.
587  *      2) Also adjust the NFC divider such that the NFC clock doesn't
588  *         exceed NFC_CLK_MAX.
589  *      3) IPU HSP clock is independent of AHB clock. Even it can go up to
590  *         177MHz for higher voltage, this function fixes the max to 133MHz.
591  *      4) This function should not have allowed diag_printf() calls since
592  *         the serial driver has been stoped. But leave then here to allow
593  *         easy debugging by NOT calling the cyg_hal_plf_serial_stop().
594  */
595 int mxc_set_clock(u32 ref, u32 freq, enum mxc_clock clk)
596 {
597         freq *= 1000000;
598
599         switch (clk) {
600         case MXC_ARM_CLK:
601                 if (config_core_clk(ref, freq))
602                         return -EINVAL;
603                 break;
604 #if 0
605         case MXC_PER_CLK:
606                 if (config_periph_clk(ref, freq))
607                         return -EINVAL;
608                 break;
609         case MXC_DDR_CLK:
610                 if (config_ddr_clk(freq))
611                         return -EINVAL;
612                 break;
613         case MXC_NFC_CLK:
614                 if (config_nfc_clk(freq))
615                         return -EINVAL;
616                 break;
617 #endif
618         default:
619                 printf("Warning: Unsupported or invalid clock type: %d\n",
620                         clk);
621                 return -EINVAL;
622         }
623
624         return 0;
625 }
626
627 /*
628  * Dump some core clocks.
629  */
630 #define print_pll(pll)  printf("%-12s %4d.%03d MHz\n", #pll,            \
631                                 decode_pll(pll, MXC_HCLK) / 1000000,    \
632                                 decode_pll(pll, MXC_HCLK) / 1000 % 1000)
633
634 #define MXC_IPG_PER_CLK MXC_IPG_PERCLK
635 #define print_clk(clk)  printf("%-12s %4d.%03d MHz\n", #clk,            \
636                                 mxc_get_clock(MXC_##clk##_CLK) / 1000000, \
637                                 mxc_get_clock(MXC_##clk##_CLK) / 1000 % 1000)
638
639 int do_mx6_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
640 {
641         print_pll(PLL_ARM);
642         print_pll(PLL_BUS);
643         print_pll(PLL_USBOTG);
644         print_pll(PLL_AUDIO);
645         print_pll(PLL_VIDEO);
646         print_pll(PLL_ENET);
647         print_pll(PLL_USB2);
648
649         printf("\n");
650         print_clk(IPG);
651         print_clk(UART);
652         print_clk(CSPI);
653         print_clk(AHB);
654         print_clk(AXI);
655         print_clk(DDR);
656         print_clk(ESDHC);
657         print_clk(ESDHC2);
658         print_clk(ESDHC3);
659         print_clk(ESDHC4);
660         print_clk(EMI_SLOW);
661         print_clk(NFC);
662         print_clk(IPG_PER);
663         print_clk(ARM);
664
665         return 0;
666 }
667
668 /***************************************************/
669
670 U_BOOT_CMD(
671         clocks, CONFIG_SYS_MAXARGS, 1, do_mx6_showclocks,
672         "display clocks",
673         ""
674 );