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