blob: 3e88f4633c2d396f5369635f07a5b77eea5129f4 [file] [log] [blame]
Peng Fanb15705a2021-08-07 16:00:35 +08001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright 2020 NXP
4 */
5
6#include <common.h>
Peng Fan690eea12021-08-07 16:00:45 +08007#include <command.h>
Peng Fanb15705a2021-08-07 16:00:35 +08008#include <div64.h>
Peng Fan690eea12021-08-07 16:00:45 +08009#include <asm/arch/imx-regs.h>
Peng Fanb15705a2021-08-07 16:00:35 +080010#include <asm/io.h>
11#include <errno.h>
12#include <asm/arch/clock.h>
Peng Fan690eea12021-08-07 16:00:45 +080013#include <asm/arch/pcc.h>
14#include <asm/arch/cgc.h>
Peng Fanb15705a2021-08-07 16:00:35 +080015#include <asm/arch/sys_proto.h>
Peng Fan690eea12021-08-07 16:00:45 +080016#include <asm/global_data.h>
17#include <linux/delay.h>
Peng Fanb15705a2021-08-07 16:00:35 +080018
19DECLARE_GLOBAL_DATA_PTR;
20
Peng Fan690eea12021-08-07 16:00:45 +080021#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
Ye Lida0469d2021-10-29 09:46:18 +080030static void lpuart_set_clk(u32 index, enum cgc_clk clk)
Peng Fan690eea12021-08-07 16:00:45 +080031{
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{
Ye Li328f2012021-10-29 09:46:26 +0800100 /* disable the ddr pcc */
101 writel(0xc0000000, PCC5_LPDDR4_ADDR);
102
Peng Fan690eea12021-08-07 16:00:45 +0800103 /* enable pll4 and ddrclk*/
Ye Li8c0c8d02022-04-06 14:30:13 +0800104 cgc2_pll4_init(true);
Peng Fan4cdb3a32022-04-06 14:30:12 +0800105 cgc2_ddrclk_config(4, 1);
Peng Fan690eea12021-08-07 16:00:45 +0800106
107 /* enable ddr pcc */
108 writel(0xd0000000, PCC5_LPDDR4_ADDR);
109
Ye Li88408302021-10-29 09:46:30 +0800110 /* Wait until ddrclk reg lock bit is cleared, so that the div update is finished */
111 cgc2_ddrclk_wait_unlock();
112
Peng Fan690eea12021-08-07 16:00:45 +0800113 /* 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
Ye Li88408302021-10-29 09:46:30 +0800150 /* Wait until ddrclk reg lock bit is cleared, so that the div update is finished */
151 cgc2_ddrclk_wait_unlock();
152
Peng Fan690eea12021-08-07 16:00:45 +0800153 return 0;
154}
155
Peng Fan4cdb3a32022-04-06 14:30:12 +0800156void clock_init_early(void)
Peng Fanb15705a2021-08-07 16:00:35 +0800157{
Peng Fan690eea12021-08-07 16:00:45 +0800158 cgc1_soscdiv_init();
Peng Fan690eea12021-08-07 16:00:45 +0800159
160 init_clk_lpuart();
161
Peng Fan4cdb3a32022-04-06 14:30:12 +0800162 /* Enable upower mu1 clk */
163 pcc_clock_enable(3, UPOWER_PCC3_SLOT, true);
164}
Peng Fan690eea12021-08-07 16:00:45 +0800165
Peng Fan4cdb3a32022-04-06 14:30:12 +0800166/* This will be invoked after pmic voltage setting */
167void clock_init_late(void)
168{
Peng Fan690eea12021-08-07 16:00:45 +0800169
Peng Fan4cdb3a32022-04-06 14:30:12 +0800170 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));
Peng Fan690eea12021-08-07 16:00:45 +0800176
Peng Fan4cdb3a32022-04-06 14:30:12 +0800177 /*
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 if (IS_ENABLED(CONFIG_IMX8ULP_LD_MODE) || IS_ENABLED(CONFIG_IMX8ULP_ND_MODE)) {
186 pcc_clock_enable(4, SDHC0_PCC4_SLOT, false);
187 pcc_clock_sel(4, SDHC0_PCC4_SLOT, PLL3_PFD2_DIV2);
188 pcc_clock_enable(4, SDHC0_PCC4_SLOT, true);
189 pcc_reset_peripheral(4, SDHC0_PCC4_SLOT, false);
190
191 pcc_clock_enable(4, SDHC1_PCC4_SLOT, false);
192 pcc_clock_sel(4, SDHC1_PCC4_SLOT, PLL3_PFD2_DIV2);
193 pcc_clock_enable(4, SDHC1_PCC4_SLOT, true);
194 pcc_reset_peripheral(4, SDHC1_PCC4_SLOT, false);
195
196 pcc_clock_enable(4, SDHC2_PCC4_SLOT, false);
197 pcc_clock_sel(4, SDHC2_PCC4_SLOT, PLL3_PFD2_DIV2);
198 pcc_clock_enable(4, SDHC2_PCC4_SLOT, true);
199 pcc_reset_peripheral(4, SDHC2_PCC4_SLOT, false);
200 } else {
201 pcc_clock_enable(4, SDHC0_PCC4_SLOT, false);
202 pcc_clock_sel(4, SDHC0_PCC4_SLOT, PLL3_PFD1_DIV2);
203 pcc_clock_enable(4, SDHC0_PCC4_SLOT, true);
204 pcc_reset_peripheral(4, SDHC0_PCC4_SLOT, false);
205
206 pcc_clock_enable(4, SDHC1_PCC4_SLOT, false);
207 pcc_clock_sel(4, SDHC1_PCC4_SLOT, PLL3_PFD2_DIV1);
208 pcc_clock_enable(4, SDHC1_PCC4_SLOT, true);
209 pcc_reset_peripheral(4, SDHC1_PCC4_SLOT, false);
210
211 pcc_clock_enable(4, SDHC2_PCC4_SLOT, false);
212 pcc_clock_sel(4, SDHC2_PCC4_SLOT, PLL3_PFD2_DIV1);
213 pcc_clock_enable(4, SDHC2_PCC4_SLOT, true);
214 pcc_reset_peripheral(4, SDHC2_PCC4_SLOT, false);
215 }
Peng Fan690eea12021-08-07 16:00:45 +0800216
Peng Fan0736da92022-04-06 14:30:15 +0800217 /* enable MU0_MUB clock before access the register of MU0_MUB */
218 pcc_clock_enable(3, MU0_B_PCC3_SLOT, true);
219
Peng Fan690eea12021-08-07 16:00:45 +0800220 /*
221 * Enable clock division
222 * TODO: may not needed after ROM ready.
223 */
224}
225
226#if IS_ENABLED(CONFIG_SYS_I2C_IMX_LPI2C)
227int enable_i2c_clk(unsigned char enable, u32 i2c_num)
228{
229 /* Set parent to FIRC DIV2 clock */
230 const u32 lpi2c_pcc_clks[] = {
231 LPI2C4_PCC3_SLOT << 8 | 3,
232 LPI2C5_PCC3_SLOT << 8 | 3,
233 LPI2C6_PCC4_SLOT << 8 | 4,
234 LPI2C7_PCC4_SLOT << 8 | 4,
235 };
236
Ye Li27666ca2021-10-29 09:46:21 +0800237 if (i2c_num == 0)
238 return 0;
239
Peng Fan690eea12021-08-07 16:00:45 +0800240 if (i2c_num < 4 || i2c_num > 7)
241 return -EINVAL;
242
243 if (enable) {
244 pcc_clock_enable(lpi2c_pcc_clks[i2c_num - 4] & 0xff,
245 lpi2c_pcc_clks[i2c_num - 4] >> 8, false);
246 pcc_clock_sel(lpi2c_pcc_clks[i2c_num - 4] & 0xff,
247 lpi2c_pcc_clks[i2c_num - 4] >> 8, SOSC_DIV2);
248 pcc_clock_enable(lpi2c_pcc_clks[i2c_num - 4] & 0xff,
249 lpi2c_pcc_clks[i2c_num - 4] >> 8, true);
250 pcc_reset_peripheral(lpi2c_pcc_clks[i2c_num - 4] & 0xff,
251 lpi2c_pcc_clks[i2c_num - 4] >> 8, false);
252 } else {
253 pcc_clock_enable(lpi2c_pcc_clks[i2c_num - 4] & 0xff,
254 lpi2c_pcc_clks[i2c_num - 4] >> 8, false);
255 }
256 return 0;
257}
258
259u32 imx_get_i2cclk(u32 i2c_num)
260{
261 const u32 lpi2c_pcc_clks[] = {
262 LPI2C4_PCC3_SLOT << 8 | 3,
263 LPI2C5_PCC3_SLOT << 8 | 3,
264 LPI2C6_PCC4_SLOT << 8 | 4,
265 LPI2C7_PCC4_SLOT << 8 | 4,
266 };
267
Ye Li27666ca2021-10-29 09:46:21 +0800268 if (i2c_num == 0)
269 return 24000000;
270
Peng Fan690eea12021-08-07 16:00:45 +0800271 if (i2c_num < 4 || i2c_num > 7)
272 return 0;
273
274 return pcc_clock_get_rate(lpi2c_pcc_clks[i2c_num - 4] & 0xff,
275 lpi2c_pcc_clks[i2c_num - 4] >> 8);
276}
277#endif
278
Clark Wang276dfd52022-04-06 14:30:09 +0800279#if IS_ENABLED(CONFIG_SYS_I2C_IMX_I3C)
280int enable_i3c_clk(unsigned char enable, u32 i3c_num)
281{
282 if (enable) {
283 pcc_clock_enable(3, I3C2_PCC3_SLOT, false);
284 pcc_clock_sel(3, I3C2_PCC3_SLOT, SOSC_DIV2);
285 pcc_clock_enable(3, I3C2_PCC3_SLOT, true);
286 pcc_reset_peripheral(3, I3C2_PCC3_SLOT, false);
287 } else {
288 pcc_clock_enable(3, I3C2_PCC3_SLOT, false);
289 }
290 return 0;
291}
292
293u32 imx_get_i3cclk(u32 i3c_num)
294{
295 return pcc_clock_get_rate(3, I3C2_PCC3_SLOT);
296}
297#endif
298
Peng Fan690eea12021-08-07 16:00:45 +0800299void enable_usboh3_clk(unsigned char enable)
300{
301 if (enable) {
302 pcc_clock_enable(4, USB0_PCC4_SLOT, true);
303 pcc_clock_enable(4, USBPHY_PCC4_SLOT, true);
304 pcc_reset_peripheral(4, USB0_PCC4_SLOT, false);
305 pcc_reset_peripheral(4, USBPHY_PCC4_SLOT, false);
306
307#ifdef CONFIG_USB_MAX_CONTROLLER_COUNT
308 if (CONFIG_USB_MAX_CONTROLLER_COUNT > 1) {
309 pcc_clock_enable(4, USB1_PCC4_SLOT, true);
310 pcc_clock_enable(4, USB1PHY_PCC4_SLOT, true);
311 pcc_reset_peripheral(4, USB1_PCC4_SLOT, false);
312 pcc_reset_peripheral(4, USB1PHY_PCC4_SLOT, false);
313 }
314#endif
315
316 pcc_clock_enable(4, USB_XBAR_PCC4_SLOT, true);
317 } else {
318 pcc_clock_enable(4, USB0_PCC4_SLOT, false);
319 pcc_clock_enable(4, USB1_PCC4_SLOT, false);
320 pcc_clock_enable(4, USBPHY_PCC4_SLOT, false);
321 pcc_clock_enable(4, USB1PHY_PCC4_SLOT, false);
322 pcc_clock_enable(4, USB_XBAR_PCC4_SLOT, false);
323 }
Peng Fanb15705a2021-08-07 16:00:35 +0800324}
325
Peng Fan690eea12021-08-07 16:00:45 +0800326int enable_usb_pll(ulong usb_phy_base)
Peng Fanb15705a2021-08-07 16:00:35 +0800327{
Peng Fan690eea12021-08-07 16:00:45 +0800328 u32 sosc_rate;
329 s32 timeout = 1000000;
330
331 struct usbphy_regs *usbphy =
332 (struct usbphy_regs *)usb_phy_base;
333
334 sosc_rate = cgc1_sosc_div(SOSC);
335 if (!sosc_rate)
336 return -EPERM;
337
338 if (!(readl(&usbphy->usb1_pll_480_ctrl) & PLL_USB_LOCK_MASK)) {
339 writel(0x1c00000, &usbphy->usb1_pll_480_ctrl_clr);
340
341 switch (sosc_rate) {
342 case 24000000:
343 writel(0xc00000, &usbphy->usb1_pll_480_ctrl_set);
344 break;
345
346 case 30000000:
347 writel(0x800000, &usbphy->usb1_pll_480_ctrl_set);
348 break;
349
350 case 19200000:
351 writel(0x1400000, &usbphy->usb1_pll_480_ctrl_set);
352 break;
353
354 default:
355 writel(0xc00000, &usbphy->usb1_pll_480_ctrl_set);
356 break;
357 }
358
359 /* Enable the regulator first */
360 writel(PLL_USB_REG_ENABLE_MASK,
361 &usbphy->usb1_pll_480_ctrl_set);
362
363 /* Wait at least 15us */
364 udelay(15);
365
366 /* Enable the power */
367 writel(PLL_USB_PWR_MASK, &usbphy->usb1_pll_480_ctrl_set);
368
369 /* Wait lock */
370 while (timeout--) {
371 if (readl(&usbphy->usb1_pll_480_ctrl) &
372 PLL_USB_LOCK_MASK)
373 break;
374 }
375
376 if (timeout <= 0) {
377 /* If timeout, we power down the pll */
378 writel(PLL_USB_PWR_MASK,
379 &usbphy->usb1_pll_480_ctrl_clr);
380 return -ETIME;
381 }
382 }
383
384 /* Clear the bypass */
385 writel(PLL_USB_BYPASS_MASK, &usbphy->usb1_pll_480_ctrl_clr);
386
387 /* Enable the PLL clock out to USB */
388 writel((PLL_USB_EN_USB_CLKS_MASK | PLL_USB_ENABLE_MASK),
389 &usbphy->usb1_pll_480_ctrl_set);
390
Peng Fanb15705a2021-08-07 16:00:35 +0800391 return 0;
392}
393
Ye Li3d3dfb02021-10-29 09:46:19 +0800394void enable_mipi_dsi_clk(unsigned char enable)
395{
396 if (enable) {
397 pcc_clock_enable(5, DSI_PCC5_SLOT, false);
Ye Licb7e3752021-10-29 09:46:27 +0800398 pcc_reset_peripheral(5, DSI_PCC5_SLOT, true);
Ye Li3d3dfb02021-10-29 09:46:19 +0800399 pcc_clock_sel(5, DSI_PCC5_SLOT, PLL4_PFD3_DIV2);
400 pcc_clock_div_config(5, DSI_PCC5_SLOT, 0, 6);
401 pcc_clock_enable(5, DSI_PCC5_SLOT, true);
402 pcc_reset_peripheral(5, DSI_PCC5_SLOT, false);
403 } else {
404 pcc_clock_enable(5, DSI_PCC5_SLOT, false);
405 pcc_reset_peripheral(5, DSI_PCC5_SLOT, true);
406 }
407}
408
Alice Guo23ee0e12021-10-29 09:46:29 +0800409void enable_adc1_clk(bool enable)
410{
411 if (enable) {
412 pcc_clock_enable(1, ADC1_PCC1_SLOT, false);
413 pcc_clock_sel(1, ADC1_PCC1_SLOT, CM33_BUSCLK);
414 pcc_clock_enable(1, ADC1_PCC1_SLOT, true);
415 pcc_reset_peripheral(1, ADC1_PCC1_SLOT, false);
416 } else {
417 pcc_clock_enable(1, ADC1_PCC1_SLOT, false);
418 }
419}
420
Ye Licb7e3752021-10-29 09:46:27 +0800421void reset_lcdclk(void)
422{
423 /* Disable clock and reset dcnano*/
424 pcc_clock_enable(5, DCNANO_PCC5_SLOT, false);
425 pcc_reset_peripheral(5, DCNANO_PCC5_SLOT, true);
426}
427
Ye Li3d3dfb02021-10-29 09:46:19 +0800428void mxs_set_lcdclk(u32 base_addr, u32 freq_in_khz)
429{
430 u8 pcd, best_pcd = 0;
431 u32 frac, rate, parent_rate, pfd, div;
432 u32 best_pfd = 0, best_frac = 0, best = 0, best_div = 0;
433 u32 pll4_rate;
434
435 pcc_clock_enable(5, DCNANO_PCC5_SLOT, false);
436
437 pll4_rate = cgc_clk_get_rate(PLL4);
438 pll4_rate = pll4_rate / 1000; /* Change to khz*/
439
440 debug("PLL4 rate %ukhz\n", pll4_rate);
441
442 for (pfd = 12; pfd <= 35; pfd++) {
Ye Li3d3dfb02021-10-29 09:46:19 +0800443 for (div = 1; div <= 64; div++) {
Loic Poulainbebd2822022-03-31 12:39:37 +0200444 parent_rate = pll4_rate;
445 parent_rate = parent_rate * 18 / pfd;
Ye Li3d3dfb02021-10-29 09:46:19 +0800446 parent_rate = parent_rate / div;
447
448 for (pcd = 0; pcd < 8; pcd++) {
449 for (frac = 0; frac < 2; frac++) {
450 if (pcd == 0 && frac == 1)
451 continue;
452
453 rate = parent_rate * (frac + 1) / (pcd + 1);
454 if (rate > freq_in_khz)
455 continue;
456
457 if (best == 0 || rate > best) {
458 best = rate;
459 best_pfd = pfd;
460 best_frac = frac;
461 best_pcd = pcd;
462 best_div = div;
463 }
464 }
465 }
466 }
467 }
468
469 if (best == 0) {
470 printf("Can't find parent clock for LCDIF, target freq: %u\n", freq_in_khz);
471 return;
472 }
473
474 debug("LCD target rate %ukhz, best rate %ukhz, frac %u, pcd %u, best_pfd %u, best_div %u\n",
475 freq_in_khz, best, best_frac, best_pcd, best_pfd, best_div);
476
477 cgc2_pll4_pfd_config(PLL4_PFD0, best_pfd);
478 cgc2_pll4_pfddiv_config(PLL4_PFD0_DIV1, best_div - 1);
479
480 pcc_clock_sel(5, DCNANO_PCC5_SLOT, PLL4_PFD0_DIV1);
481 pcc_clock_div_config(5, DCNANO_PCC5_SLOT, best_frac, best_pcd + 1);
482 pcc_clock_enable(5, DCNANO_PCC5_SLOT, true);
483 pcc_reset_peripheral(5, DCNANO_PCC5_SLOT, false);
484}
485
Peng Fan690eea12021-08-07 16:00:45 +0800486u32 mxc_get_clock(enum mxc_clock clk)
487{
488 switch (clk) {
489 case MXC_ESDHC_CLK:
490 return pcc_clock_get_rate(4, SDHC0_PCC4_SLOT);
491 case MXC_ESDHC2_CLK:
492 return pcc_clock_get_rate(4, SDHC1_PCC4_SLOT);
493 case MXC_ESDHC3_CLK:
494 return pcc_clock_get_rate(4, SDHC2_PCC4_SLOT);
495 case MXC_ARM_CLK:
Ye Lida0469d2021-10-29 09:46:18 +0800496 return cgc_clk_get_rate(PLL2);
Peng Fan690eea12021-08-07 16:00:45 +0800497 default:
498 return 0;
499 }
500}
501
Peng Fanb15705a2021-08-07 16:00:35 +0800502u32 get_lpuart_clk(void)
503{
Peng Fan690eea12021-08-07 16:00:45 +0800504 int index = 0;
505
506 const u32 lpuart_array[] = {
507 LPUART4_RBASE,
508 LPUART5_RBASE,
509 LPUART6_RBASE,
510 LPUART7_RBASE,
511 };
512
513 const u32 lpuart_pcc_slots[] = {
514 LPUART4_PCC3_SLOT,
515 LPUART5_PCC3_SLOT,
516 LPUART6_PCC4_SLOT,
517 LPUART7_PCC4_SLOT,
518 };
519
520 const u32 lpuart_pcc[] = {
521 3, 3, 4, 4,
522 };
523
524 for (index = 0; index < 4; index++) {
525 if (lpuart_array[index] == LPUART_BASE)
526 break;
527 }
528
529 if (index > 3)
530 return 0;
531
532 return pcc_clock_get_rate(lpuart_pcc[index], lpuart_pcc_slots[index]);
533}
534
535#ifndef CONFIG_SPL_BUILD
536/*
537 * Dump some core clockes.
538 */
539int do_mx8ulp_showclocks(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[])
540{
541 printf("SDHC0 %8d MHz\n", pcc_clock_get_rate(4, SDHC0_PCC4_SLOT) / 1000000);
542 printf("SDHC1 %8d MHz\n", pcc_clock_get_rate(4, SDHC1_PCC4_SLOT) / 1000000);
543 printf("SDHC2 %8d MHz\n", pcc_clock_get_rate(4, SDHC2_PCC4_SLOT) / 1000000);
544
Ye Lida0469d2021-10-29 09:46:18 +0800545 printf("SOSC %8d MHz\n", cgc_clk_get_rate(SOSC) / 1000000);
546 printf("FRO %8d MHz\n", cgc_clk_get_rate(FRO) / 1000000);
547 printf("PLL2 %8d MHz\n", cgc_clk_get_rate(PLL2) / 1000000);
548 printf("PLL3 %8d MHz\n", cgc_clk_get_rate(PLL3) / 1000000);
549 printf("PLL3_VCODIV %8d MHz\n", cgc_clk_get_rate(PLL3_VCODIV) / 1000000);
550 printf("PLL3_PFD0 %8d MHz\n", cgc_clk_get_rate(PLL3_PFD0) / 1000000);
551 printf("PLL3_PFD1 %8d MHz\n", cgc_clk_get_rate(PLL3_PFD1) / 1000000);
552 printf("PLL3_PFD2 %8d MHz\n", cgc_clk_get_rate(PLL3_PFD2) / 1000000);
553 printf("PLL3_PFD3 %8d MHz\n", cgc_clk_get_rate(PLL3_PFD3) / 1000000);
554
555 printf("PLL4_PFD0 %8d MHz\n", cgc_clk_get_rate(PLL4_PFD0) / 1000000);
556 printf("PLL4_PFD1 %8d MHz\n", cgc_clk_get_rate(PLL4_PFD1) / 1000000);
557 printf("PLL4_PFD2 %8d MHz\n", cgc_clk_get_rate(PLL4_PFD2) / 1000000);
558 printf("PLL4_PFD3 %8d MHz\n", cgc_clk_get_rate(PLL4_PFD3) / 1000000);
559
560 printf("PLL4_PFD0_DIV1 %8d MHz\n", cgc_clk_get_rate(PLL4_PFD0_DIV1) / 1000000);
561 printf("PLL4_PFD0_DIV2 %8d MHz\n", cgc_clk_get_rate(PLL4_PFD0_DIV2) / 1000000);
562 printf("PLL4_PFD1_DIV1 %8d MHz\n", cgc_clk_get_rate(PLL4_PFD1_DIV1) / 1000000);
563 printf("PLL4_PFD1_DIV2 %8d MHz\n", cgc_clk_get_rate(PLL4_PFD1_DIV2) / 1000000);
564
565 printf("PLL4_PFD2_DIV1 %8d MHz\n", cgc_clk_get_rate(PLL4_PFD2_DIV1) / 1000000);
566 printf("PLL4_PFD2_DIV2 %8d MHz\n", cgc_clk_get_rate(PLL4_PFD2_DIV2) / 1000000);
567 printf("PLL4_PFD3_DIV1 %8d MHz\n", cgc_clk_get_rate(PLL4_PFD3_DIV1) / 1000000);
568 printf("PLL4_PFD3_DIV2 %8d MHz\n", cgc_clk_get_rate(PLL4_PFD3_DIV2) / 1000000);
569
570 printf("LPAV_AXICLK %8d MHz\n", cgc_clk_get_rate(LPAV_AXICLK) / 1000000);
571 printf("LPAV_AHBCLK %8d MHz\n", cgc_clk_get_rate(LPAV_AHBCLK) / 1000000);
572 printf("LPAV_BUSCLK %8d MHz\n", cgc_clk_get_rate(LPAV_BUSCLK) / 1000000);
573 printf("NIC_APCLK %8d MHz\n", cgc_clk_get_rate(NIC_APCLK) / 1000000);
Peng Fan690eea12021-08-07 16:00:45 +0800574
Ye Lida0469d2021-10-29 09:46:18 +0800575 printf("NIC_PERCLK %8d MHz\n", cgc_clk_get_rate(NIC_PERCLK) / 1000000);
576 printf("XBAR_APCLK %8d MHz\n", cgc_clk_get_rate(XBAR_APCLK) / 1000000);
577 printf("XBAR_BUSCLK %8d MHz\n", cgc_clk_get_rate(XBAR_BUSCLK) / 1000000);
578 printf("AD_SLOWCLK %8d MHz\n", cgc_clk_get_rate(AD_SLOWCLK) / 1000000);
Peng Fan690eea12021-08-07 16:00:45 +0800579 return 0;
Peng Fanb15705a2021-08-07 16:00:35 +0800580}
Peng Fan690eea12021-08-07 16:00:45 +0800581
582U_BOOT_CMD(
583 clocks, CONFIG_SYS_MAXARGS, 1, do_mx8ulp_showclocks,
584 "display clocks",
585 ""
586);
587#endif