1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright 2020 NXP
4 */
5
6#include <common.h>
7#include <command.h>
8#include <div64.h>
9#include <asm/arch/imx-regs.h>
10#include <asm/io.h>
11#include <errno.h>
12#include <asm/arch/clock.h>
13#include <asm/arch/pcc.h>
14#include <asm/arch/cgc.h>
15#include <asm/arch/sys_proto.h>
16#include <asm/global_data.h>
17#include <linux/delay.h>
18
19DECLARE_GLOBAL_DATA_PTR;
20
21#define PLL_USB_EN_USB_CLKS_MASK	(0x01 << 6)
22#define PLL_USB_PWR_MASK		(0x01 << 12)
23#define PLL_USB_ENABLE_MASK		(0x01 << 13)
24#define PLL_USB_BYPASS_MASK		(0x01 << 16)
25#define PLL_USB_REG_ENABLE_MASK		(0x01 << 21)
26#define PLL_USB_DIV_SEL_MASK		(0x07 << 22)
27#define PLL_USB_LOCK_MASK		(0x01 << 31)
28#define PCC5_LPDDR4_ADDR 0x2da70108
29
30static void lpuart_set_clk(u32 index, enum cgc_clk clk)
31{
32	const u32 lpuart_pcc_slots[] = {
33		LPUART4_PCC3_SLOT,
34		LPUART5_PCC3_SLOT,
35		LPUART6_PCC4_SLOT,
36		LPUART7_PCC4_SLOT,
37	};
38
39	const u32 lpuart_pcc[] = {
40		3, 3, 4, 4,
41	};
42
43	if (index > 3)
44		return;
45
46	pcc_clock_enable(lpuart_pcc[index], lpuart_pcc_slots[index], false);
47	pcc_clock_sel(lpuart_pcc[index], lpuart_pcc_slots[index], clk);
48	pcc_clock_enable(lpuart_pcc[index], lpuart_pcc_slots[index], true);
49
50	pcc_reset_peripheral(lpuart_pcc[index], lpuart_pcc_slots[index], false);
51}
52
53static void init_clk_lpuart(void)
54{
55	u32 index = 0, i;
56
57	const u32 lpuart_array[] = {
58		LPUART4_RBASE,
59		LPUART5_RBASE,
60		LPUART6_RBASE,
61		LPUART7_RBASE,
62	};
63
64	for (i = 0; i < 4; i++) {
65		if (lpuart_array[i] == LPUART_BASE) {
66			index = i;
67			break;
68		}
69	}
70
71	lpuart_set_clk(index, SOSC_DIV2);
72}
73
74void init_clk_fspi(int index)
75{
76	pcc_clock_enable(4, FLEXSPI2_PCC4_SLOT, false);
77	pcc_clock_sel(4, FLEXSPI2_PCC4_SLOT, PLL3_PFD2_DIV1);
78	pcc_clock_div_config(4, FLEXSPI2_PCC4_SLOT, false, 8);
79	pcc_clock_enable(4, FLEXSPI2_PCC4_SLOT, true);
80	pcc_reset_peripheral(4, FLEXSPI2_PCC4_SLOT, false);
81}
82
83void setclkout_ddr(void)
84{
85	writel(0x12800000, 0x2DA60020);
86	writel(0xa00, 0x298C0000); /* PTD0 */
87}
88
89void ddrphy_pll_lock(void)
90{
91	writel(0x00011542, 0x2E065964);
92	writel(0x00011542, 0x2E06586C);
93
94	writel(0x00000B01, 0x2E062000);
95	writel(0x00000B01, 0x2E060000);
96}
97
98void init_clk_ddr(void)
99{
100	/* disable the ddr pcc */
101	writel(0xc0000000, PCC5_LPDDR4_ADDR);
102
103	/* enable pll4 and ddrclk*/
104	cgc2_pll4_init(true);
105	cgc2_ddrclk_config(4, 1);
106
107	/* enable ddr pcc */
108	writel(0xd0000000, PCC5_LPDDR4_ADDR);
109
110	/* Wait until ddrclk reg lock bit is cleared, so that the div update is finished */
111	cgc2_ddrclk_wait_unlock();
112
113	/* for debug */
114	/* setclkout_ddr(); */
115}
116
117int set_ddr_clk(u32 phy_freq_mhz)
118{
119	debug("%s %u\n", __func__, phy_freq_mhz);
120
121	if (phy_freq_mhz == 48) {
122		writel(0x90000000, PCC5_LPDDR4_ADDR); /* disable ddr pcc */
123		cgc2_ddrclk_config(2, 0); /* 24Mhz DDR clock */
124		writel(0xd0000000, PCC5_LPDDR4_ADDR); /* enable ddr pcc */
125	} else if (phy_freq_mhz == 384) {
126		writel(0x90000000, PCC5_LPDDR4_ADDR); /* disable ddr pcc */
127		cgc2_ddrclk_config(0, 0); /* 192Mhz DDR clock */
128		writel(0xd0000000, PCC5_LPDDR4_ADDR); /* enable ddr pcc */
129	} else if (phy_freq_mhz == 528) {
130		writel(0x90000000, PCC5_LPDDR4_ADDR); /* disable ddr pcc */
131		cgc2_ddrclk_config(4, 1); /* 264Mhz DDR clock */
132		writel(0xd0000000, PCC5_LPDDR4_ADDR); /* enable ddr pcc */
133	} else if (phy_freq_mhz == 264) {
134		writel(0x90000000, PCC5_LPDDR4_ADDR); /* disable ddr pcc */
135		cgc2_ddrclk_config(4, 3); /* 132Mhz DDR clock */
136		writel(0xd0000000, PCC5_LPDDR4_ADDR); /* enable ddr pcc */
137	} else if (phy_freq_mhz == 192) {
138		writel(0x90000000, PCC5_LPDDR4_ADDR); /* disable ddr pcc */
139		cgc2_ddrclk_config(0, 1); /* 96Mhz DDR clock */
140		writel(0xd0000000, PCC5_LPDDR4_ADDR); /* enable ddr pcc */
141	} else if (phy_freq_mhz == 96) {
142		writel(0x90000000, PCC5_LPDDR4_ADDR); /* disable ddr pcc */
143		cgc2_ddrclk_config(0, 3); /* 48Mhz DDR clock */
144		writel(0xd0000000, PCC5_LPDDR4_ADDR); /* enable ddr pcc */
145	} else {
146		printf("ddr phy clk %uMhz is not supported\n", phy_freq_mhz);
147		return -EINVAL;
148	}
149
150	/* Wait until ddrclk reg lock bit is cleared, so that the div update is finished */
151	cgc2_ddrclk_wait_unlock();
152
153	return 0;
154}
155
156void clock_init_early(void)
157{
158	cgc1_soscdiv_init();
159
160	init_clk_lpuart();
161
162	/* Enable upower mu1 clk */
163	pcc_clock_enable(3, UPOWER_PCC3_SLOT, true);
164}
165
166/* This will be invoked after pmic voltage setting */
167void clock_init_late(void)
168{
169
170	if (IS_ENABLED(CONFIG_IMX8ULP_LD_MODE))
171		cgc1_init_core_clk(MHZ(500));
172	else if (IS_ENABLED(CONFIG_IMX8ULP_ND_MODE))
173		cgc1_init_core_clk(MHZ(750));
174	else
175		cgc1_init_core_clk(MHZ(960));
176
177	/*
178	 * Audio use this frequency in kernel dts,
179	 * however nic use pll3 pfd0, we have to
180	 * make the freqency same as kernel to make nic
181	 * not being disabled
182	 */
183	cgc1_pll3_init(540672000);
184
185	pcc_clock_enable(4, SDHC0_PCC4_SLOT, false);
186	pcc_clock_sel(4, SDHC0_PCC4_SLOT, PLL3_PFD3_DIV1); /* 389M for OD, 194M for LD/ND*/
187	pcc_clock_enable(4, SDHC0_PCC4_SLOT, true);
188	pcc_reset_peripheral(4, SDHC0_PCC4_SLOT, false);
189
190	pcc_clock_enable(4, SDHC1_PCC4_SLOT, false);
191	pcc_clock_sel(4, SDHC1_PCC4_SLOT, PLL3_PFD3_DIV2); /* 194M for OD, 97M for LD/ND */
192	pcc_clock_enable(4, SDHC1_PCC4_SLOT, true);
193	pcc_reset_peripheral(4, SDHC1_PCC4_SLOT, false);
194
195	pcc_clock_enable(4, SDHC2_PCC4_SLOT, false);
196	pcc_clock_sel(4, SDHC2_PCC4_SLOT, PLL3_PFD3_DIV2); /* 194M for OD, 97M for LD/ND*/
197	pcc_clock_enable(4, SDHC2_PCC4_SLOT, true);
198	pcc_reset_peripheral(4, SDHC2_PCC4_SLOT, false);
199
200	/* enable MU0_MUB clock before access the register of MU0_MUB */
201	pcc_clock_enable(3, MU0_B_PCC3_SLOT, true);
202
203	/*
204	 * Enable clock division
205	 * TODO: may not needed after ROM ready.
206	 */
207}
208
209#if IS_ENABLED(CONFIG_SYS_I2C_IMX_LPI2C)
210int enable_i2c_clk(unsigned char enable, u32 i2c_num)
211{
212	/* Set parent to FIRC DIV2 clock */
213	const u32 lpi2c_pcc_clks[] = {
214		LPI2C4_PCC3_SLOT << 8 | 3,
215		LPI2C5_PCC3_SLOT << 8 | 3,
216		LPI2C6_PCC4_SLOT << 8 | 4,
217		LPI2C7_PCC4_SLOT << 8 | 4,
218	};
219
220	if (i2c_num == 0)
221		return 0;
222
223	if (i2c_num < 4 || i2c_num > 7)
224		return -EINVAL;
225
226	if (enable) {
227		pcc_clock_enable(lpi2c_pcc_clks[i2c_num - 4] & 0xff,
228				 lpi2c_pcc_clks[i2c_num - 4] >> 8, false);
229		pcc_clock_sel(lpi2c_pcc_clks[i2c_num - 4] & 0xff,
230			      lpi2c_pcc_clks[i2c_num - 4] >> 8, SOSC_DIV2);
231		pcc_clock_enable(lpi2c_pcc_clks[i2c_num - 4] & 0xff,
232				 lpi2c_pcc_clks[i2c_num - 4] >> 8, true);
233		pcc_reset_peripheral(lpi2c_pcc_clks[i2c_num - 4] & 0xff,
234				     lpi2c_pcc_clks[i2c_num - 4] >> 8, false);
235	} else {
236		pcc_clock_enable(lpi2c_pcc_clks[i2c_num - 4] & 0xff,
237				 lpi2c_pcc_clks[i2c_num - 4] >> 8, false);
238	}
239	return 0;
240}
241
242u32 imx_get_i2cclk(u32 i2c_num)
243{
244	const u32 lpi2c_pcc_clks[] = {
245		LPI2C4_PCC3_SLOT << 8 | 3,
246		LPI2C5_PCC3_SLOT << 8 | 3,
247		LPI2C6_PCC4_SLOT << 8 | 4,
248		LPI2C7_PCC4_SLOT << 8 | 4,
249	};
250
251	if (i2c_num == 0)
252		return 24000000;
253
254	if (i2c_num < 4 || i2c_num > 7)
255		return 0;
256
257	return pcc_clock_get_rate(lpi2c_pcc_clks[i2c_num - 4] & 0xff,
258				  lpi2c_pcc_clks[i2c_num - 4] >> 8);
259}
260#endif
261
262#if IS_ENABLED(CONFIG_SYS_I2C_IMX_I3C)
263int enable_i3c_clk(unsigned char enable, u32 i3c_num)
264{
265	if (enable) {
266		pcc_clock_enable(3, I3C2_PCC3_SLOT, false);
267		pcc_clock_sel(3, I3C2_PCC3_SLOT, SOSC_DIV2);
268		pcc_clock_enable(3, I3C2_PCC3_SLOT, true);
269		pcc_reset_peripheral(3, I3C2_PCC3_SLOT, false);
270	} else {
271		pcc_clock_enable(3, I3C2_PCC3_SLOT, false);
272	}
273	return 0;
274}
275
276u32 imx_get_i3cclk(u32 i3c_num)
277{
278	return pcc_clock_get_rate(3, I3C2_PCC3_SLOT);
279}
280#endif
281
282void enable_usboh3_clk(unsigned char enable)
283{
284	if (enable) {
285		pcc_clock_enable(4, USB0_PCC4_SLOT, true);
286		pcc_clock_enable(4, USBPHY_PCC4_SLOT, true);
287		pcc_reset_peripheral(4, USB0_PCC4_SLOT, false);
288		pcc_reset_peripheral(4, USBPHY_PCC4_SLOT, false);
289
290#ifdef CONFIG_USB_MAX_CONTROLLER_COUNT
291		if (CONFIG_USB_MAX_CONTROLLER_COUNT > 1) {
292			pcc_clock_enable(4, USB1_PCC4_SLOT, true);
293			pcc_clock_enable(4, USB1PHY_PCC4_SLOT, true);
294			pcc_reset_peripheral(4, USB1_PCC4_SLOT, false);
295			pcc_reset_peripheral(4, USB1PHY_PCC4_SLOT, false);
296		}
297#endif
298
299		pcc_clock_enable(4, USB_XBAR_PCC4_SLOT, true);
300	} else {
301		pcc_clock_enable(4, USB0_PCC4_SLOT, false);
302		pcc_clock_enable(4, USB1_PCC4_SLOT, false);
303		pcc_clock_enable(4, USBPHY_PCC4_SLOT, false);
304		pcc_clock_enable(4, USB1PHY_PCC4_SLOT, false);
305		pcc_clock_enable(4, USB_XBAR_PCC4_SLOT, false);
306	}
307}
308
309int enable_usb_pll(ulong usb_phy_base)
310{
311	u32 sosc_rate;
312	s32 timeout = 1000000;
313
314	struct usbphy_regs *usbphy =
315		(struct usbphy_regs *)usb_phy_base;
316
317	sosc_rate = cgc1_sosc_div(SOSC);
318	if (!sosc_rate)
319		return -EPERM;
320
321	if (!(readl(&usbphy->usb1_pll_480_ctrl) & PLL_USB_LOCK_MASK)) {
322		writel(0x1c00000, &usbphy->usb1_pll_480_ctrl_clr);
323
324		switch (sosc_rate) {
325		case 24000000:
326			writel(0xc00000, &usbphy->usb1_pll_480_ctrl_set);
327			break;
328
329		case 30000000:
330			writel(0x800000, &usbphy->usb1_pll_480_ctrl_set);
331			break;
332
333		case 19200000:
334			writel(0x1400000, &usbphy->usb1_pll_480_ctrl_set);
335			break;
336
337		default:
338			writel(0xc00000, &usbphy->usb1_pll_480_ctrl_set);
339			break;
340		}
341
342		/* Enable the regulator first */
343		writel(PLL_USB_REG_ENABLE_MASK,
344		       &usbphy->usb1_pll_480_ctrl_set);
345
346		/* Wait at least 15us */
347		udelay(15);
348
349		/* Enable the power */
350		writel(PLL_USB_PWR_MASK, &usbphy->usb1_pll_480_ctrl_set);
351
352		/* Wait lock */
353		while (timeout--) {
354			if (readl(&usbphy->usb1_pll_480_ctrl) &
355			    PLL_USB_LOCK_MASK)
356				break;
357		}
358
359		if (timeout <= 0) {
360			/* If timeout, we power down the pll */
361			writel(PLL_USB_PWR_MASK,
362			       &usbphy->usb1_pll_480_ctrl_clr);
363			return -ETIME;
364		}
365	}
366
367	/* Clear the bypass */
368	writel(PLL_USB_BYPASS_MASK, &usbphy->usb1_pll_480_ctrl_clr);
369
370	/* Enable the PLL clock out to USB */
371	writel((PLL_USB_EN_USB_CLKS_MASK | PLL_USB_ENABLE_MASK),
372	       &usbphy->usb1_pll_480_ctrl_set);
373
374	return 0;
375}
376
377void enable_mipi_dsi_clk(unsigned char enable)
378{
379	if (enable) {
380		pcc_clock_enable(5, DSI_PCC5_SLOT, false);
381		pcc_reset_peripheral(5, DSI_PCC5_SLOT, true);
382		pcc_clock_sel(5, DSI_PCC5_SLOT, PLL4_PFD3_DIV2);
383		pcc_clock_div_config(5, DSI_PCC5_SLOT, 0, 6);
384		pcc_clock_enable(5, DSI_PCC5_SLOT, true);
385		pcc_reset_peripheral(5, DSI_PCC5_SLOT, false);
386	} else {
387		pcc_clock_enable(5, DSI_PCC5_SLOT, false);
388		pcc_reset_peripheral(5, DSI_PCC5_SLOT, true);
389	}
390}
391
392void enable_adc1_clk(bool enable)
393{
394	if (enable) {
395		pcc_clock_enable(1, ADC1_PCC1_SLOT, false);
396		pcc_clock_sel(1, ADC1_PCC1_SLOT, CM33_BUSCLK);
397		pcc_clock_enable(1, ADC1_PCC1_SLOT, true);
398		pcc_reset_peripheral(1, ADC1_PCC1_SLOT, false);
399	} else {
400		pcc_clock_enable(1, ADC1_PCC1_SLOT, false);
401	}
402}
403
404void reset_lcdclk(void)
405{
406	/* Disable clock and reset dcnano*/
407	pcc_clock_enable(5, DCNANO_PCC5_SLOT, false);
408	pcc_reset_peripheral(5, DCNANO_PCC5_SLOT, true);
409}
410
411/* PLL4 PFD0 max frequency */
412#define PLL4_PFD0_MAX_RATE 600000 /*khz*/
413void mxs_set_lcdclk(u32 base_addr, u32 freq_in_khz)
414{
415	u8 pcd, best_pcd = 0;
416	u32 frac, rate, parent_rate, pfd, div;
417	u32 best_pfd = 0, best_frac = 0, best = 0, best_div = 0;
418	u32 pll4_rate;
419
420	pcc_clock_enable(5, DCNANO_PCC5_SLOT, false);
421
422	pll4_rate = cgc_clk_get_rate(PLL4);
423	pll4_rate = pll4_rate / 1000;  /* Change to khz*/
424
425	debug("PLL4 rate %ukhz\n", pll4_rate);
426
427	for (pfd = 12; pfd <= 35; pfd++) {
428		for (div = 1; div <= 64; div++) {
429			parent_rate = pll4_rate;
430			parent_rate = parent_rate * 18 / pfd;
431			if (parent_rate > PLL4_PFD0_MAX_RATE)
432				continue;
433
434			parent_rate = parent_rate / div;
435
436			for (pcd = 0; pcd < 8; pcd++) {
437				for (frac = 0; frac < 2; frac++) {
438					if (pcd == 0 && frac == 1)
439						continue;
440
441					rate = parent_rate * (frac + 1) / (pcd + 1);
442					if (rate > freq_in_khz)
443						continue;
444
445					if (best == 0 || rate > best) {
446						best = rate;
447						best_pfd = pfd;
448						best_frac = frac;
449						best_pcd = pcd;
450						best_div = div;
451					}
452				}
453			}
454		}
455	}
456
457	if (best == 0) {
458		printf("Can't find parent clock for LCDIF, target freq: %u\n", freq_in_khz);
459		return;
460	}
461
462	debug("LCD target rate %ukhz, best rate %ukhz, frac %u, pcd %u, best_pfd %u, best_div %u\n",
463	      freq_in_khz, best, best_frac, best_pcd, best_pfd, best_div);
464
465	cgc2_pll4_pfd_config(PLL4_PFD0, best_pfd);
466	cgc2_pll4_pfddiv_config(PLL4_PFD0_DIV1, best_div - 1);
467
468	pcc_clock_sel(5, DCNANO_PCC5_SLOT, PLL4_PFD0_DIV1);
469	pcc_clock_div_config(5, DCNANO_PCC5_SLOT, best_frac, best_pcd + 1);
470	pcc_clock_enable(5, DCNANO_PCC5_SLOT, true);
471	pcc_reset_peripheral(5, DCNANO_PCC5_SLOT, false);
472}
473
474u32 mxc_get_clock(enum mxc_clock clk)
475{
476	switch (clk) {
477	case MXC_ESDHC_CLK:
478		return pcc_clock_get_rate(4, SDHC0_PCC4_SLOT);
479	case MXC_ESDHC2_CLK:
480		return pcc_clock_get_rate(4, SDHC1_PCC4_SLOT);
481	case MXC_ESDHC3_CLK:
482		return pcc_clock_get_rate(4, SDHC2_PCC4_SLOT);
483	case MXC_ARM_CLK:
484		return cgc_clk_get_rate(PLL2);
485	default:
486		return 0;
487	}
488}
489
490u32 get_lpuart_clk(void)
491{
492	int index = 0;
493
494	const u32 lpuart_array[] = {
495		LPUART4_RBASE,
496		LPUART5_RBASE,
497		LPUART6_RBASE,
498		LPUART7_RBASE,
499	};
500
501	const u32 lpuart_pcc_slots[] = {
502		LPUART4_PCC3_SLOT,
503		LPUART5_PCC3_SLOT,
504		LPUART6_PCC4_SLOT,
505		LPUART7_PCC4_SLOT,
506	};
507
508	const u32 lpuart_pcc[] = {
509		3, 3, 4, 4,
510	};
511
512	for (index = 0; index < 4; index++) {
513		if (lpuart_array[index] == LPUART_BASE)
514			break;
515	}
516
517	if (index > 3)
518		return 0;
519
520	return pcc_clock_get_rate(lpuart_pcc[index], lpuart_pcc_slots[index]);
521}
522
523#ifndef CONFIG_SPL_BUILD
524/*
525 * Dump some core clockes.
526 */
527int do_mx8ulp_showclocks(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[])
528{
529	printf("SDHC0 %8d MHz\n", pcc_clock_get_rate(4, SDHC0_PCC4_SLOT) / 1000000);
530	printf("SDHC1 %8d MHz\n", pcc_clock_get_rate(4, SDHC1_PCC4_SLOT) / 1000000);
531	printf("SDHC2 %8d MHz\n", pcc_clock_get_rate(4, SDHC2_PCC4_SLOT) / 1000000);
532
533	printf("SOSC %8d MHz\n", cgc_clk_get_rate(SOSC) / 1000000);
534	printf("FRO %8d MHz\n", cgc_clk_get_rate(FRO) / 1000000);
535	printf("PLL2 %8d MHz\n", cgc_clk_get_rate(PLL2) / 1000000);
536	printf("PLL3 %8d MHz\n", cgc_clk_get_rate(PLL3) / 1000000);
537	printf("PLL3_VCODIV %8d MHz\n", cgc_clk_get_rate(PLL3_VCODIV) / 1000000);
538	printf("PLL3_PFD0 %8d MHz\n", cgc_clk_get_rate(PLL3_PFD0) / 1000000);
539	printf("PLL3_PFD1 %8d MHz\n", cgc_clk_get_rate(PLL3_PFD1) / 1000000);
540	printf("PLL3_PFD2 %8d MHz\n", cgc_clk_get_rate(PLL3_PFD2) / 1000000);
541	printf("PLL3_PFD3 %8d MHz\n", cgc_clk_get_rate(PLL3_PFD3) / 1000000);
542
543	printf("PLL4_PFD0 %8d MHz\n", cgc_clk_get_rate(PLL4_PFD0) / 1000000);
544	printf("PLL4_PFD1 %8d MHz\n", cgc_clk_get_rate(PLL4_PFD1) / 1000000);
545	printf("PLL4_PFD2 %8d MHz\n", cgc_clk_get_rate(PLL4_PFD2) / 1000000);
546	printf("PLL4_PFD3 %8d MHz\n", cgc_clk_get_rate(PLL4_PFD3) / 1000000);
547
548	printf("PLL4_PFD0_DIV1 %8d MHz\n", cgc_clk_get_rate(PLL4_PFD0_DIV1) / 1000000);
549	printf("PLL4_PFD0_DIV2 %8d MHz\n", cgc_clk_get_rate(PLL4_PFD0_DIV2) / 1000000);
550	printf("PLL4_PFD1_DIV1 %8d MHz\n", cgc_clk_get_rate(PLL4_PFD1_DIV1) / 1000000);
551	printf("PLL4_PFD1_DIV2 %8d MHz\n", cgc_clk_get_rate(PLL4_PFD1_DIV2) / 1000000);
552
553	printf("PLL4_PFD2_DIV1 %8d MHz\n", cgc_clk_get_rate(PLL4_PFD2_DIV1) / 1000000);
554	printf("PLL4_PFD2_DIV2 %8d MHz\n", cgc_clk_get_rate(PLL4_PFD2_DIV2) / 1000000);
555	printf("PLL4_PFD3_DIV1 %8d MHz\n", cgc_clk_get_rate(PLL4_PFD3_DIV1) / 1000000);
556	printf("PLL4_PFD3_DIV2 %8d MHz\n", cgc_clk_get_rate(PLL4_PFD3_DIV2) / 1000000);
557
558	printf("LPAV_AXICLK %8d MHz\n", cgc_clk_get_rate(LPAV_AXICLK) / 1000000);
559	printf("LPAV_AHBCLK %8d MHz\n", cgc_clk_get_rate(LPAV_AHBCLK) / 1000000);
560	printf("LPAV_BUSCLK %8d MHz\n", cgc_clk_get_rate(LPAV_BUSCLK) / 1000000);
561	printf("NIC_APCLK %8d MHz\n", cgc_clk_get_rate(NIC_APCLK) / 1000000);
562
563	printf("NIC_PERCLK %8d MHz\n", cgc_clk_get_rate(NIC_PERCLK) / 1000000);
564	printf("XBAR_APCLK %8d MHz\n", cgc_clk_get_rate(XBAR_APCLK) / 1000000);
565	printf("XBAR_BUSCLK %8d MHz\n", cgc_clk_get_rate(XBAR_BUSCLK) / 1000000);
566	printf("AD_SLOWCLK %8d MHz\n", cgc_clk_get_rate(AD_SLOWCLK) / 1000000);
567	return 0;
568}
569
570U_BOOT_CMD(
571	clocks,	CONFIG_SYS_MAXARGS, 1, do_mx8ulp_showclocks,
572	"display clocks",
573	""
574);
575#endif
576