1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Copyright 2022 NXP
4 *
5 * Peng Fan <peng.fan@nxp.com>
6 */
7
8 #include <command.h>
9 #include <asm/arch/clock.h>
10 #include <asm/arch/imx-regs.h>
11 #include <asm/arch/ccm_regs.h>
12 #include <asm/arch/sys_proto.h>
13 #include <asm/global_data.h>
14 #include <asm/io.h>
15 #include <div64.h>
16 #include <errno.h>
17 #include <linux/bitops.h>
18 #include <linux/delay.h>
19 #include <log.h>
20 #include <phy.h>
21
22 DECLARE_GLOBAL_DATA_PTR;
23
24 static struct anatop_reg *ana_regs = (struct anatop_reg *)ANATOP_BASE_ADDR;
25
26 static struct imx_intpll_rate_table imx9_intpll_tbl[] = {
27 INT_PLL_RATE(1800000000U, 1, 150, 2), /* 1.8Ghz */
28 INT_PLL_RATE(1700000000U, 1, 141, 2), /* 1.7Ghz */
29 INT_PLL_RATE(1500000000U, 1, 125, 2), /* 1.5Ghz */
30 INT_PLL_RATE(1400000000U, 1, 175, 3), /* 1.4Ghz */
31 INT_PLL_RATE(1000000000U, 1, 166, 4), /* 1000Mhz */
32 INT_PLL_RATE(900000000U, 1, 150, 4), /* 900Mhz */
33 INT_PLL_RATE(800000000U, 1, 200, 6), /* 800Mhz */
34 };
35
36 static struct imx_fracpll_rate_table imx9_fracpll_tbl[] = {
37 FRAC_PLL_RATE(1000000000U, 1, 166, 4, 2, 3), /* 1000Mhz */
38 FRAC_PLL_RATE(933000000U, 1, 155, 4, 1, 2), /* 933Mhz */
39 FRAC_PLL_RATE(800000000U, 1, 200, 6, 0, 1), /* 800Mhz */
40 FRAC_PLL_RATE(700000000U, 1, 145, 5, 5, 6), /* 700Mhz */
41 FRAC_PLL_RATE(600000000U, 1, 200, 8, 0, 1), /* 600Mhz */
42 FRAC_PLL_RATE(484000000U, 1, 121, 6, 0, 1),
43 FRAC_PLL_RATE(445333333U, 1, 167, 9, 0, 1),
44 FRAC_PLL_RATE(466000000U, 1, 155, 8, 1, 3), /* 466Mhz */
45 FRAC_PLL_RATE(400000000U, 1, 200, 12, 0, 1), /* 400Mhz */
46 FRAC_PLL_RATE(300000000U, 1, 150, 12, 0, 1),
47 FRAC_PLL_RATE(233000000U, 1, 174, 18, 3, 4), /* 233Mhz */
48 FRAC_PLL_RATE(200000000U, 1, 200, 24, 0, 1), /* 200Mhz */
49 };
50
51 /* return in khz */
decode_pll_vco(struct ana_pll_reg * reg,bool fracpll)52 static u32 decode_pll_vco(struct ana_pll_reg *reg, bool fracpll)
53 {
54 u32 ctrl;
55 u32 pll_status;
56 u32 div;
57 int rdiv, mfi, mfn, mfd;
58 int clk = 24000;
59
60 ctrl = readl(®->ctrl.reg);
61 pll_status = readl(®->pll_status);
62 div = readl(®->div.reg);
63
64 if (!(ctrl & PLL_CTRL_POWERUP))
65 return 0;
66
67 if (!(pll_status & PLL_STATUS_PLL_LOCK))
68 return 0;
69
70 mfi = (div & GENMASK(24, 16)) >> 16;
71 rdiv = (div & GENMASK(15, 13)) >> 13;
72
73 if (rdiv == 0)
74 rdiv = 1;
75
76 if (fracpll) {
77 mfn = (int)readl(®->num.reg);
78 mfn >>= 2;
79 mfd = (int)(readl(®->denom.reg) & GENMASK(29, 0));
80
81 clk = clk * (mfi * mfd + mfn) / mfd / rdiv;
82 } else {
83 clk = clk * mfi / rdiv;
84 }
85
86 return (u32)clk;
87 }
88
89 /* return in khz */
decode_pll_out(struct ana_pll_reg * reg,bool fracpll)90 static u32 decode_pll_out(struct ana_pll_reg *reg, bool fracpll)
91 {
92 u32 ctrl = readl(®->ctrl.reg);
93 u32 div;
94
95 if (ctrl & PLL_CTRL_CLKMUX_BYPASS)
96 return 24000;
97
98 if (!(ctrl & PLL_CTRL_CLKMUX_EN))
99 return 0;
100
101 div = readl(®->div.reg);
102 div &= 0xff; /* odiv */
103
104 if (div == 0)
105 div = 2;
106 else if (div == 1)
107 div = 3;
108
109 return decode_pll_vco(reg, fracpll) / div;
110 }
111
112 /* return in khz */
decode_pll_pfd(struct ana_pll_reg * reg,struct ana_pll_dfs * dfs_reg,bool div2,bool fracpll)113 static u32 decode_pll_pfd(struct ana_pll_reg *reg, struct ana_pll_dfs *dfs_reg,
114 bool div2, bool fracpll)
115 {
116 u32 pllvco = decode_pll_vco(reg, fracpll);
117 u32 dfs_ctrl = readl(&dfs_reg->dfs_ctrl.reg);
118 u32 dfs_div = readl(&dfs_reg->dfs_div.reg);
119 u32 mfn, mfi;
120 u32 output;
121
122 if (dfs_ctrl & PLL_DFS_CTRL_BYPASS)
123 return pllvco;
124
125 if (!(dfs_ctrl & PLL_DFS_CTRL_ENABLE) ||
126 (div2 && !(dfs_ctrl & PLL_DFS_CTRL_CLKOUT_DIV2)) ||
127 (!div2 && !(dfs_ctrl & PLL_DFS_CTRL_CLKOUT)))
128 return 0;
129
130 mfn = dfs_div & GENMASK(2, 0);
131 mfi = (dfs_div & GENMASK(15, 8)) >> 8;
132
133 if (mfn > 3)
134 return 0; /* valid mfn 0-3 */
135
136 if (mfi == 0 || mfi == 1)
137 return 0; /* valid mfi 2-255 */
138
139 output = (pllvco * 5) / (mfi * 5 + mfn);
140
141 if (div2)
142 return output >> 1;
143
144 return output;
145 }
146
decode_pll(enum ccm_clk_src pll)147 static u32 decode_pll(enum ccm_clk_src pll)
148 {
149 switch (pll) {
150 case ARM_PLL_CLK:
151 return decode_pll_out(&ana_regs->arm_pll, false);
152 case SYS_PLL_PG:
153 return decode_pll_out(&ana_regs->sys_pll, false);
154 case SYS_PLL_PFD0:
155 return decode_pll_pfd(&ana_regs->sys_pll,
156 &ana_regs->sys_pll.dfs[0], false, true);
157 case SYS_PLL_PFD0_DIV2:
158 return decode_pll_pfd(&ana_regs->sys_pll,
159 &ana_regs->sys_pll.dfs[0], true, true);
160 case SYS_PLL_PFD1:
161 return decode_pll_pfd(&ana_regs->sys_pll,
162 &ana_regs->sys_pll.dfs[1], false, true);
163 case SYS_PLL_PFD1_DIV2:
164 return decode_pll_pfd(&ana_regs->sys_pll,
165 &ana_regs->sys_pll.dfs[1], true, true);
166 case SYS_PLL_PFD2:
167 return decode_pll_pfd(&ana_regs->sys_pll,
168 &ana_regs->sys_pll.dfs[2], false, true);
169 case SYS_PLL_PFD2_DIV2:
170 return decode_pll_pfd(&ana_regs->sys_pll,
171 &ana_regs->sys_pll.dfs[2], true, true);
172 case AUDIO_PLL_CLK:
173 return decode_pll_out(&ana_regs->audio_pll, true);
174 case DRAM_PLL_CLK:
175 return decode_pll_out(&ana_regs->dram_pll, true);
176 case VIDEO_PLL_CLK:
177 return decode_pll_out(&ana_regs->video_pll, true);
178 default:
179 printf("Invalid clock source to decode\n");
180 break;
181 }
182
183 return 0;
184 }
185
configure_intpll(enum ccm_clk_src pll,u32 freq)186 int configure_intpll(enum ccm_clk_src pll, u32 freq)
187 {
188 int i;
189 struct imx_intpll_rate_table *rate;
190 struct ana_pll_reg *reg;
191 u32 pll_status;
192
193 for (i = 0; i < ARRAY_SIZE(imx9_intpll_tbl); i++) {
194 if (freq == imx9_intpll_tbl[i].rate)
195 break;
196 }
197
198 if (i == ARRAY_SIZE(imx9_intpll_tbl)) {
199 debug("No matched freq table %u\n", freq);
200 return -EINVAL;
201 }
202
203 rate = &imx9_intpll_tbl[i];
204
205 /* ROM has configured SYS PLL and PFD, no need for it */
206 switch (pll) {
207 case ARM_PLL_CLK:
208 reg = &ana_regs->arm_pll;
209 break;
210 default:
211 return -EPERM;
212 }
213
214 /* Clear PLL HW CTRL SEL */
215 setbits_le32(®->ctrl.reg_clr, PLL_CTRL_HW_CTRL_SEL);
216
217 /* Bypass the PLL to ref */
218 writel(PLL_CTRL_CLKMUX_BYPASS, ®->ctrl.reg_set);
219
220 /* disable pll and output */
221 writel(PLL_CTRL_CLKMUX_EN | PLL_CTRL_POWERUP, ®->ctrl.reg_clr);
222
223 /* Program the ODIV, RDIV, MFI */
224 writel((rate->odiv & GENMASK(7, 0)) | ((rate->rdiv << 13) & GENMASK(15, 13)) |
225 ((rate->mfi << 16) & GENMASK(24, 16)), ®->div.reg);
226
227 /* wait 5us */
228 udelay(5);
229
230 /* power up the PLL and wait lock (max wait time 100 us) */
231 writel(PLL_CTRL_POWERUP, ®->ctrl.reg_set);
232
233 udelay(100);
234
235 pll_status = readl(®->pll_status);
236 if (pll_status & PLL_STATUS_PLL_LOCK) {
237 writel(PLL_CTRL_CLKMUX_EN, ®->ctrl.reg_set);
238
239 /* clear bypass */
240 writel(PLL_CTRL_CLKMUX_BYPASS, ®->ctrl.reg_clr);
241
242 } else {
243 debug("Fail to lock PLL %u\n", pll);
244 return -EIO;
245 }
246
247 return 0;
248 }
249
configure_fracpll(enum ccm_clk_src pll,u32 freq)250 int configure_fracpll(enum ccm_clk_src pll, u32 freq)
251 {
252 struct imx_fracpll_rate_table *rate;
253 struct ana_pll_reg *reg;
254 u32 pll_status;
255 int i;
256
257 for (i = 0; i < ARRAY_SIZE(imx9_fracpll_tbl); i++) {
258 if (freq == imx9_fracpll_tbl[i].rate)
259 break;
260 }
261
262 if (i == ARRAY_SIZE(imx9_fracpll_tbl)) {
263 debug("No matched freq table %u\n", freq);
264 return -EINVAL;
265 }
266
267 rate = &imx9_fracpll_tbl[i];
268
269 switch (pll) {
270 case SYS_PLL_PG:
271 reg = &ana_regs->sys_pll;
272 break;
273 case DRAM_PLL_CLK:
274 reg = &ana_regs->dram_pll;
275 break;
276 case VIDEO_PLL_CLK:
277 reg = &ana_regs->video_pll;
278 break;
279 default:
280 return -EPERM;
281 }
282
283 /* Bypass the PLL to ref */
284 writel(PLL_CTRL_CLKMUX_BYPASS, ®->ctrl.reg_set);
285
286 /* disable pll and output */
287 writel(PLL_CTRL_CLKMUX_EN | PLL_CTRL_POWERUP, ®->ctrl.reg_clr);
288
289 /* Program the ODIV, RDIV, MFI */
290 writel((rate->odiv & GENMASK(7, 0)) | ((rate->rdiv << 13) & GENMASK(15, 13)) |
291 ((rate->mfi << 16) & GENMASK(24, 16)), ®->div.reg);
292
293 /* Set SPREAD_SPECRUM enable to 0 */
294 writel(PLL_SS_EN, ®->ss.reg_clr);
295
296 /* Program NUMERATOR and DENOMINATOR */
297 writel((rate->mfn << 2), ®->num.reg);
298 writel((rate->mfd & GENMASK(29, 0)), ®->denom.reg);
299
300 /* wait 5us */
301 udelay(5);
302
303 /* power up the PLL and wait lock (max wait time 100 us) */
304 writel(PLL_CTRL_POWERUP, ®->ctrl.reg_set);
305
306 udelay(100);
307
308 pll_status = readl(®->pll_status);
309 if (pll_status & PLL_STATUS_PLL_LOCK) {
310 writel(PLL_CTRL_CLKMUX_EN, ®->ctrl.reg_set);
311
312 /* check the MFN is updated */
313 pll_status = readl(®->pll_status);
314 if ((pll_status & ~0x3) != (rate->mfn << 2)) {
315 debug("MFN update not matched, pll_status 0x%x, mfn 0x%x\n",
316 pll_status, rate->mfn);
317 return -EIO;
318 }
319
320 /* clear bypass */
321 writel(PLL_CTRL_CLKMUX_BYPASS, ®->ctrl.reg_clr);
322
323 } else {
324 debug("Fail to lock PLL %u\n", pll);
325 return -EIO;
326 }
327
328 return 0;
329 }
330
configure_pll_pfd(enum ccm_clk_src pll_pfg,u32 mfi,u32 mfn,bool div2_en)331 int configure_pll_pfd(enum ccm_clk_src pll_pfg, u32 mfi, u32 mfn, bool div2_en)
332 {
333 struct ana_pll_dfs *dfs;
334 struct ana_pll_reg *reg;
335 u32 dfs_status;
336 u32 index;
337
338 if (mfn > 3)
339 return -EINVAL; /* valid mfn 0-3 */
340
341 if (mfi < 2 || mfi > 255)
342 return -EINVAL; /* valid mfi 2-255 */
343
344 switch (pll_pfg) {
345 case SYS_PLL_PFD0:
346 reg = &ana_regs->sys_pll;
347 index = 0;
348 break;
349 case SYS_PLL_PFD1:
350 reg = &ana_regs->sys_pll;
351 index = 1;
352 break;
353 case SYS_PLL_PFD2:
354 reg = &ana_regs->sys_pll;
355 index = 2;
356 break;
357 default:
358 return -EPERM;
359 }
360
361 dfs = ®->dfs[index];
362
363 /* Bypass the DFS to PLL VCO */
364 writel(PLL_DFS_CTRL_BYPASS, &dfs->dfs_ctrl.reg_set);
365
366 /* disable DFS and output */
367 writel(PLL_DFS_CTRL_ENABLE | PLL_DFS_CTRL_CLKOUT |
368 PLL_DFS_CTRL_CLKOUT_DIV2, &dfs->dfs_ctrl.reg_clr);
369
370 writel(((mfi << 8) & GENMASK(15, 8)) | (mfn & GENMASK(2, 0)), &dfs->dfs_div.reg);
371
372 writel(PLL_DFS_CTRL_CLKOUT, &dfs->dfs_ctrl.reg_set);
373 if (div2_en)
374 writel(PLL_DFS_CTRL_CLKOUT_DIV2, &dfs->dfs_ctrl.reg_set);
375 writel(PLL_DFS_CTRL_ENABLE, &dfs->dfs_ctrl.reg_set);
376
377 /*
378 * As HW expert said: after enabling the DFS, clock will start
379 * coming after 6 cycles output clock period.
380 * 5us is much bigger than expected, so it will be safe
381 */
382 udelay(5);
383
384 dfs_status = readl(®->dfs_status);
385
386 if (!(dfs_status & (1 << index))) {
387 debug("DFS lock failed\n");
388 return -EIO;
389 }
390
391 /* Bypass the DFS to PLL VCO */
392 writel(PLL_DFS_CTRL_BYPASS, &dfs->dfs_ctrl.reg_clr);
393
394 return 0;
395 }
396
update_fracpll_mfn(enum ccm_clk_src pll,int mfn)397 int update_fracpll_mfn(enum ccm_clk_src pll, int mfn)
398 {
399 struct ana_pll_reg *reg;
400 bool repoll = false;
401 u32 pll_status;
402 int count = 20;
403
404 switch (pll) {
405 case AUDIO_PLL_CLK:
406 reg = &ana_regs->audio_pll;
407 break;
408 case DRAM_PLL_CLK:
409 reg = &ana_regs->dram_pll;
410 break;
411 case VIDEO_PLL_CLK:
412 reg = &ana_regs->video_pll;
413 break;
414 default:
415 printf("Invalid pll %u for update FRAC PLL MFN\n", pll);
416 return -EINVAL;
417 }
418
419 if (readl(®->pll_status) & PLL_STATUS_PLL_LOCK)
420 repoll = true;
421
422 mfn <<= 2;
423 writel(mfn, ®->num);
424
425 if (repoll) {
426 do {
427 pll_status = readl(®->pll_status);
428 udelay(5);
429 count--;
430 } while (((pll_status & ~0x3) != (u32)mfn) && count > 0);
431
432 if (count <= 0) {
433 printf("update MFN timeout, pll_status 0x%x, mfn 0x%x\n", pll_status, mfn);
434 return -EIO;
435 }
436 }
437
438 return 0;
439 }
440
update_pll_pfd_mfn(enum ccm_clk_src pll_pfd,u32 mfn)441 int update_pll_pfd_mfn(enum ccm_clk_src pll_pfd, u32 mfn)
442 {
443 struct ana_pll_dfs *dfs;
444 u32 val;
445 u32 index;
446
447 switch (pll_pfd) {
448 case SYS_PLL_PFD0:
449 case SYS_PLL_PFD0_DIV2:
450 index = 0;
451 break;
452 case SYS_PLL_PFD1:
453 case SYS_PLL_PFD1_DIV2:
454 index = 1;
455 break;
456 case SYS_PLL_PFD2:
457 case SYS_PLL_PFD2_DIV2:
458 index = 2;
459 break;
460 default:
461 printf("Invalid pfd %u for update PLL PFD MFN\n", pll_pfd);
462 return -EINVAL;
463 }
464
465 dfs = &ana_regs->sys_pll.dfs[index];
466
467 val = readl(&dfs->dfs_div.reg);
468 val &= ~0x3;
469 val |= mfn & 0x3;
470 writel(val, &dfs->dfs_div.reg);
471
472 return 0;
473 }
474
475 /* return in khz */
get_clk_src_rate(enum ccm_clk_src source)476 u32 get_clk_src_rate(enum ccm_clk_src source)
477 {
478 u32 ctrl;
479 bool clk_on;
480
481 switch (source) {
482 case ARM_PLL_CLK:
483 ctrl = readl(&ana_regs->arm_pll.ctrl.reg);
484 case AUDIO_PLL_CLK:
485 ctrl = readl(&ana_regs->audio_pll.ctrl.reg);
486 break;
487 case DRAM_PLL_CLK:
488 ctrl = readl(&ana_regs->dram_pll.ctrl.reg);
489 break;
490 case VIDEO_PLL_CLK:
491 ctrl = readl(&ana_regs->video_pll.ctrl.reg);
492 break;
493 case SYS_PLL_PFD0:
494 case SYS_PLL_PFD0_DIV2:
495 ctrl = readl(&ana_regs->sys_pll.dfs[0].dfs_ctrl.reg);
496 break;
497 case SYS_PLL_PFD1:
498 case SYS_PLL_PFD1_DIV2:
499 ctrl = readl(&ana_regs->sys_pll.dfs[1].dfs_ctrl.reg);
500 break;
501 case SYS_PLL_PFD2:
502 case SYS_PLL_PFD2_DIV2:
503 ctrl = readl(&ana_regs->sys_pll.dfs[2].dfs_ctrl.reg);
504 break;
505 case OSC_24M_CLK:
506 return 24000;
507 default:
508 printf("Invalid clock source to get rate\n");
509 return 0;
510 }
511
512 if (ctrl & PLL_CTRL_HW_CTRL_SEL) {
513 /* When using HW ctrl, check OSCPLL */
514 clk_on = ccm_clk_src_is_clk_on(source);
515 if (clk_on)
516 return decode_pll(source);
517 else
518 return 0;
519 } else {
520 /* controlled by pll registers */
521 return decode_pll(source);
522 }
523 }
524
get_arm_core_clk(void)525 u32 get_arm_core_clk(void)
526 {
527 u32 val;
528
529 ccm_shared_gpr_get(SHARED_GPR_A55_CLK, &val);
530
531 if (val & SHARED_GPR_A55_CLK_SEL_PLL)
532 return decode_pll(ARM_PLL_CLK) * 1000;
533
534 return ccm_clk_root_get_rate(ARM_A55_CLK_ROOT);
535 }
536
mxc_get_clock(enum mxc_clock clk)537 unsigned int mxc_get_clock(enum mxc_clock clk)
538 {
539 switch (clk) {
540 case MXC_ARM_CLK:
541 return get_arm_core_clk();
542 case MXC_IPG_CLK:
543 return ccm_clk_root_get_rate(BUS_WAKEUP_CLK_ROOT);
544 case MXC_CSPI_CLK:
545 return ccm_clk_root_get_rate(LPSPI1_CLK_ROOT);
546 case MXC_ESDHC_CLK:
547 return ccm_clk_root_get_rate(USDHC1_CLK_ROOT);
548 case MXC_ESDHC2_CLK:
549 return ccm_clk_root_get_rate(USDHC2_CLK_ROOT);
550 case MXC_ESDHC3_CLK:
551 return ccm_clk_root_get_rate(USDHC3_CLK_ROOT);
552 case MXC_UART_CLK:
553 return ccm_clk_root_get_rate(LPUART1_CLK_ROOT);
554 case MXC_FLEXSPI_CLK:
555 return ccm_clk_root_get_rate(FLEXSPI1_CLK_ROOT);
556 default:
557 return -1;
558 };
559
560 return -1;
561 };
562
enable_i2c_clk(unsigned char enable,u32 i2c_num)563 int enable_i2c_clk(unsigned char enable, u32 i2c_num)
564 {
565 if (i2c_num > 7)
566 return -EINVAL;
567
568 if (enable) {
569 /* 24M */
570 ccm_lpcg_on(CCGR_I2C1 + i2c_num, false);
571 ccm_clk_root_cfg(LPI2C1_CLK_ROOT + i2c_num, OSC_24M_CLK, 1);
572 ccm_lpcg_on(CCGR_I2C1 + i2c_num, true);
573 } else {
574 ccm_lpcg_on(CCGR_I2C1 + i2c_num, false);
575 }
576
577 return 0;
578 }
579
imx_get_i2cclk(u32 i2c_num)580 u32 imx_get_i2cclk(u32 i2c_num)
581 {
582 if (i2c_num > 7)
583 return -EINVAL;
584
585 return ccm_clk_root_get_rate(LPI2C1_CLK_ROOT + i2c_num);
586 }
587
get_lpuart_clk(void)588 u32 get_lpuart_clk(void)
589 {
590 return mxc_get_clock(MXC_UART_CLK);
591 }
592
init_uart_clk(u32 index)593 void init_uart_clk(u32 index)
594 {
595 switch (index) {
596 case LPUART1_CLK_ROOT:
597 /* 24M */
598 ccm_lpcg_on(CCGR_URT1, false);
599 ccm_clk_root_cfg(LPUART1_CLK_ROOT, OSC_24M_CLK, 1);
600 ccm_lpcg_on(CCGR_URT1, true);
601 break;
602 default:
603 break;
604 }
605 }
606
init_clk_usdhc(u32 index)607 void init_clk_usdhc(u32 index)
608 {
609 u32 div;
610
611 if (is_voltage_mode(VOLT_LOW_DRIVE))
612 div = 3; /* 266.67 Mhz */
613 else
614 div = 2; /* 400 Mhz */
615
616 switch (index) {
617 case 0:
618 ccm_lpcg_on(CCGR_USDHC1, 0);
619 ccm_clk_root_cfg(USDHC1_CLK_ROOT, SYS_PLL_PFD1, div);
620 ccm_lpcg_on(CCGR_USDHC1, 1);
621 break;
622 case 1:
623 ccm_lpcg_on(CCGR_USDHC2, 0);
624 ccm_clk_root_cfg(USDHC2_CLK_ROOT, SYS_PLL_PFD1, div);
625 ccm_lpcg_on(CCGR_USDHC2, 1);
626 break;
627 case 2:
628 ccm_lpcg_on(CCGR_USDHC3, 0);
629 ccm_clk_root_cfg(USDHC3_CLK_ROOT, SYS_PLL_PFD1, div);
630 ccm_lpcg_on(CCGR_USDHC3, 1);
631 break;
632 default:
633 return;
634 };
635 }
636
enable_usboh3_clk(unsigned char enable)637 void enable_usboh3_clk(unsigned char enable)
638 {
639 if (enable) {
640 ccm_clk_root_cfg(HSIO_CLK_ROOT, SYS_PLL_PFD1_DIV2, 3);
641 ccm_lpcg_on(CCGR_USBC, 1);
642 } else {
643 ccm_lpcg_on(CCGR_USBC, 0);
644 }
645 }
646
647 #ifdef CONFIG_XPL_BUILD
dram_pll_init(ulong pll_val)648 void dram_pll_init(ulong pll_val)
649 {
650 configure_fracpll(DRAM_PLL_CLK, pll_val);
651 }
652
dram_enable_bypass(ulong clk_val)653 void dram_enable_bypass(ulong clk_val)
654 {
655 switch (clk_val) {
656 case MHZ(625):
657 ccm_clk_root_cfg(DRAM_ALT_CLK_ROOT, SYS_PLL_PFD2, 1);
658 break;
659 case MHZ(400):
660 ccm_clk_root_cfg(DRAM_ALT_CLK_ROOT, SYS_PLL_PFD1, 2);
661 break;
662 case MHZ(333):
663 ccm_clk_root_cfg(DRAM_ALT_CLK_ROOT, SYS_PLL_PFD0, 3);
664 break;
665 case MHZ(200):
666 ccm_clk_root_cfg(DRAM_ALT_CLK_ROOT, SYS_PLL_PFD1, 4);
667 break;
668 case MHZ(100):
669 ccm_clk_root_cfg(DRAM_ALT_CLK_ROOT, SYS_PLL_PFD1, 8);
670 break;
671 default:
672 printf("No matched freq table %lu\n", clk_val);
673 return;
674 }
675
676 /* Set DRAM APB to 133Mhz */
677 ccm_clk_root_cfg(DRAM_APB_CLK_ROOT, SYS_PLL_PFD1_DIV2, 3);
678 /* Switch from DRAM clock root from PLL to CCM */
679 ccm_shared_gpr_set(SHARED_GPR_DRAM_CLK, SHARED_GPR_DRAM_CLK_SEL_CCM);
680 }
681
dram_disable_bypass(void)682 void dram_disable_bypass(void)
683 {
684 /* Set DRAM APB to 133Mhz */
685 ccm_clk_root_cfg(DRAM_APB_CLK_ROOT, SYS_PLL_PFD1_DIV2, 3);
686 /* Switch from DRAM clock root from CCM to PLL */
687 ccm_shared_gpr_set(SHARED_GPR_DRAM_CLK, SHARED_GPR_DRAM_CLK_SEL_PLL);
688 }
689
set_arm_clk(ulong freq)690 void set_arm_clk(ulong freq)
691 {
692 /* Increase ARM clock to 1.7Ghz */
693 ccm_shared_gpr_set(SHARED_GPR_A55_CLK, SHARED_GPR_A55_CLK_SEL_CCM);
694 configure_intpll(ARM_PLL_CLK, freq);
695 ccm_shared_gpr_set(SHARED_GPR_A55_CLK, SHARED_GPR_A55_CLK_SEL_PLL);
696 }
697
set_arm_core_max_clk(void)698 void set_arm_core_max_clk(void)
699 {
700 /* Increase ARM clock to max rate according to speed grade */
701 u32 speed = get_cpu_speed_grade_hz();
702
703 set_arm_clk(speed);
704 }
705
706 #endif
707
708 struct imx_clk_setting imx_clk_ld_settings[] = {
709 /* Set A55 clk to 500M */
710 {ARM_A55_CLK_ROOT, SYS_PLL_PFD0, 2},
711 /* Set A55 periphal to 200M */
712 {ARM_A55_PERIPH_CLK_ROOT, SYS_PLL_PFD1, 4},
713 /* Set A55 mtr bus to 133M */
714 {ARM_A55_MTR_BUS_CLK_ROOT, SYS_PLL_PFD1_DIV2, 3},
715
716 /* ELE to 133M */
717 {ELE_CLK_ROOT, SYS_PLL_PFD1_DIV2, 3},
718 /* Bus_wakeup to 133M */
719 {BUS_WAKEUP_CLK_ROOT, SYS_PLL_PFD1_DIV2, 3},
720 /* Bus_AON to 133M */
721 {BUS_AON_CLK_ROOT, SYS_PLL_PFD1_DIV2, 3},
722 /* M33 to 133M */
723 {M33_CLK_ROOT, SYS_PLL_PFD1_DIV2, 3},
724 /* WAKEUP_AXI to 200M */
725 {WAKEUP_AXI_CLK_ROOT, SYS_PLL_PFD1, 4},
726 /* SWO TRACE to 133M */
727 {SWO_TRACE_CLK_ROOT, SYS_PLL_PFD1_DIV2, 3},
728 /* M33 systetick to 24M */
729 {M33_SYSTICK_CLK_ROOT, OSC_24M_CLK, 1, CLK_SOC_IMX93},
730 /* NIC to 250M */
731 {NIC_CLK_ROOT, SYS_PLL_PFD0, 4},
732 /* NIC_APB to 133M */
733 {NIC_APB_CLK_ROOT, SYS_PLL_PFD1_DIV2, 3}
734 };
735
736 struct imx_clk_setting imx_clk_settings[] = {
737 /*
738 * Set A55 clk to 500M. This clock root is normally used as intermediate
739 * clock source for A55 core/DSU when doing ARM PLL reconfig. set it to
740 * 500MHz(LD mode frequency) should be ok.
741 */
742 {ARM_A55_CLK_ROOT, SYS_PLL_PFD0, 2},
743 /* Set A55 periphal to 333M */
744 {ARM_A55_PERIPH_CLK_ROOT, SYS_PLL_PFD0, 3},
745 /* Set A55 mtr bus to 133M */
746 {ARM_A55_MTR_BUS_CLK_ROOT, SYS_PLL_PFD1_DIV2, 3},
747 /* ELE to 200M */
748 {ELE_CLK_ROOT, SYS_PLL_PFD1_DIV2, 2},
749 /* Bus_wakeup to 133M */
750 {BUS_WAKEUP_CLK_ROOT, SYS_PLL_PFD1_DIV2, 3},
751 /* Bus_AON to 133M */
752 {BUS_AON_CLK_ROOT, SYS_PLL_PFD1_DIV2, 3},
753 /* M33 to 200M */
754 {M33_CLK_ROOT, SYS_PLL_PFD1_DIV2, 2},
755 /*
756 * WAKEUP_AXI to 312.5M, because of FEC only can support to 320M for
757 * generating MII clock at 2.5M
758 */
759 {WAKEUP_AXI_CLK_ROOT, SYS_PLL_PFD2, 2, CLK_SOC_IMX93},
760 /* Wakeup AXI 250M*/
761 {WAKEUP_AXI_CLK_ROOT, SYS_PLL_PFD0, 4, CLK_SOC_IMX91},
762 /* SWO TRACE to 133M */
763 {SWO_TRACE_CLK_ROOT, SYS_PLL_PFD1_DIV2, 3},
764 /* M33 systetick to 24M */
765 {M33_SYSTICK_CLK_ROOT, OSC_24M_CLK, 1, CLK_SOC_IMX93},
766 /* NIC to 400M */
767 {NIC_CLK_ROOT, SYS_PLL_PFD1, 2, CLK_SOC_IMX93},
768 /* NIC to 333M */
769 {NIC_CLK_ROOT, SYS_PLL_PFD0, 3, CLK_SOC_IMX91},
770 /* NIC_APB to 133M */
771 {NIC_APB_CLK_ROOT, SYS_PLL_PFD1_DIV2, 3}
772 };
773
bus_clock_init_low_drive(void)774 void bus_clock_init_low_drive(void)
775 {
776 int i;
777
778 for (i = 0; i < ARRAY_SIZE(imx_clk_ld_settings); i++) {
779 if (imx_clk_ld_settings[i].soc == CLK_SOC_ALL ||
780 (is_imx91() && imx_clk_ld_settings[i].soc == CLK_SOC_IMX91) ||
781 (is_imx93() && imx_clk_ld_settings[i].soc == CLK_SOC_IMX93)) {
782 ccm_clk_root_cfg(imx_clk_ld_settings[i].clk_root,
783 imx_clk_ld_settings[i].src, imx_clk_ld_settings[i].div);
784 }
785 }
786 }
787
bus_clock_init(void)788 void bus_clock_init(void)
789 {
790 int i;
791
792 for (i = 0; i < ARRAY_SIZE(imx_clk_settings); i++) {
793 if (imx_clk_settings[i].soc == CLK_SOC_ALL ||
794 (is_imx91() && imx_clk_settings[i].soc == CLK_SOC_IMX91) ||
795 (is_imx93() && imx_clk_settings[i].soc == CLK_SOC_IMX93)) {
796 ccm_clk_root_cfg(imx_clk_settings[i].clk_root,
797 imx_clk_settings[i].src, imx_clk_settings[i].div);
798 }
799 }
800 }
801
clock_init_early(void)802 int clock_init_early(void)
803 {
804 int i;
805
806 /* allow for non-secure access */
807 for (i = 0; i < OSCPLL_END; i++)
808 ccm_clk_src_tz_access(i, true, false, false);
809
810 for (i = 0; i < CLK_ROOT_NUM; i++)
811 ccm_clk_root_tz_access(i, true, false, false);
812
813 for (i = 0; i < CCGR_NUM; i++)
814 ccm_lpcg_tz_access(i, true, false, false);
815
816 for (i = 0; i < SHARED_GPR_NUM; i++)
817 ccm_shared_gpr_tz_access(i, true, false, false);
818
819 return 0;
820 }
821
822 /* Set bus and A55 core clock per voltage mode */
clock_init_late(void)823 int clock_init_late(void)
824 {
825 if (is_voltage_mode(VOLT_LOW_DRIVE)) {
826 bus_clock_init_low_drive();
827 set_arm_core_max_clk();
828 } else {
829 bus_clock_init();
830 }
831
832 return 0;
833 }
834
set_clk_eqos(enum enet_freq type)835 int set_clk_eqos(enum enet_freq type)
836 {
837 u32 eqos_post_div;
838
839 switch (type) {
840 case ENET_125MHZ:
841 eqos_post_div = 2; /* 250M clock */
842 break;
843 case ENET_50MHZ:
844 eqos_post_div = 5; /* 100M clock */
845 break;
846 case ENET_25MHZ:
847 eqos_post_div = 10; /* 50M clock*/
848 break;
849 default:
850 return -EINVAL;
851 }
852
853 /* disable the clock first */
854 ccm_lpcg_on(CCGR_ENETQOS, false);
855
856 ccm_clk_root_cfg(ENET_CLK_ROOT, SYS_PLL_PFD0_DIV2, eqos_post_div);
857 ccm_clk_root_cfg(ENET_TIMER2_CLK_ROOT, SYS_PLL_PFD0_DIV2, 5);
858
859 /* enable clock */
860 ccm_lpcg_on(CCGR_ENETQOS, true);
861
862 return 0;
863 }
864
imx_get_eqos_csr_clk(void)865 u32 imx_get_eqos_csr_clk(void)
866 {
867 return ccm_clk_root_get_rate(WAKEUP_AXI_CLK_ROOT);
868 }
869
imx_get_fecclk(void)870 u32 imx_get_fecclk(void)
871 {
872 return ccm_clk_root_get_rate(WAKEUP_AXI_CLK_ROOT);
873 }
874
875 #if (CONFIG_IS_ENABLED(IMX93) || CONFIG_IS_ENABLED(IMX91)) && CONFIG_IS_ENABLED(DWC_ETH_QOS)
imx93_eqos_interface_init(struct udevice * dev,phy_interface_t interface_type)876 static int imx93_eqos_interface_init(struct udevice *dev, phy_interface_t interface_type)
877 {
878 struct blk_ctrl_wakeupmix_regs *bctrl =
879 (struct blk_ctrl_wakeupmix_regs *)BLK_CTRL_WAKEUPMIX_BASE_ADDR;
880
881 clrbits_le32(&bctrl->eqos_gpr,
882 BCTRL_GPR_ENET_QOS_INTF_MODE_MASK |
883 BCTRL_GPR_ENET_QOS_CLK_GEN_EN);
884
885 switch (interface_type) {
886 case PHY_INTERFACE_MODE_MII:
887 setbits_le32(&bctrl->eqos_gpr,
888 BCTRL_GPR_ENET_QOS_INTF_SEL_MII |
889 BCTRL_GPR_ENET_QOS_CLK_GEN_EN);
890 break;
891 case PHY_INTERFACE_MODE_RMII:
892 setbits_le32(&bctrl->eqos_gpr,
893 BCTRL_GPR_ENET_QOS_INTF_SEL_RMII |
894 BCTRL_GPR_ENET_QOS_CLK_GEN_EN);
895 break;
896 case PHY_INTERFACE_MODE_RGMII:
897 case PHY_INTERFACE_MODE_RGMII_ID:
898 case PHY_INTERFACE_MODE_RGMII_RXID:
899 case PHY_INTERFACE_MODE_RGMII_TXID:
900 setbits_le32(&bctrl->eqos_gpr,
901 BCTRL_GPR_ENET_QOS_INTF_SEL_RGMII |
902 BCTRL_GPR_ENET_QOS_CLK_GEN_EN);
903 break;
904 default:
905 return -EINVAL;
906 }
907
908 return 0;
909 }
910 #else
imx93_eqos_interface_init(struct udevice * dev,phy_interface_t interface_type)911 static int imx93_eqos_interface_init(struct udevice *dev, phy_interface_t interface_type)
912 {
913 return 0;
914 }
915 #endif
916
board_interface_eth_init(struct udevice * dev,phy_interface_t interface_type)917 int board_interface_eth_init(struct udevice *dev, phy_interface_t interface_type)
918 {
919 if ((IS_ENABLED(CONFIG_IMX93) || IS_ENABLED(CONFIG_IMX91)) &&
920 IS_ENABLED(CONFIG_DWC_ETH_QOS) &&
921 device_is_compatible(dev, "nxp,imx93-dwmac-eqos"))
922 return imx93_eqos_interface_init(dev, interface_type);
923
924 if ((IS_ENABLED(CONFIG_IMX93) || IS_ENABLED(CONFIG_IMX91)) &&
925 IS_ENABLED(CONFIG_FEC_MXC) &&
926 device_is_compatible(dev, "fsl,imx93-fec"))
927 return 0;
928
929 return -EINVAL;
930 }
931
set_clk_enet(enum enet_freq type)932 int set_clk_enet(enum enet_freq type)
933 {
934 u32 div;
935
936 /* disable the clock first */
937 ccm_lpcg_on(CCGR_ENET1, false);
938
939 switch (type) {
940 case ENET_125MHZ:
941 div = 2; /* 250Mhz */
942 break;
943 case ENET_50MHZ:
944 div = 5; /* 100Mhz */
945 break;
946 case ENET_25MHZ:
947 div = 10; /* 50Mhz */
948 break;
949 default:
950 return -EINVAL;
951 }
952
953 ccm_clk_root_cfg(ENET_REF_CLK_ROOT, SYS_PLL_PFD0_DIV2, div);
954 ccm_clk_root_cfg(ENET_TIMER1_CLK_ROOT, SYS_PLL_PFD0_DIV2, 5);
955
956 #ifdef CONFIG_FEC_MXC_25M_REF_CLK
957 ccm_clk_root_cfg(ENET_REF_PHY_CLK_ROOT, SYS_PLL_PFD0_DIV2, 20);
958 #endif
959
960 /* enable clock */
961 ccm_lpcg_on(CCGR_ENET1, true);
962
963 return 0;
964 }
965
966 /*
967 * Dump some clockes.
968 */
969 #ifndef CONFIG_XPL_BUILD
do_showclocks(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])970 int do_showclocks(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[])
971 {
972 u32 freq;
973
974 freq = decode_pll(ARM_PLL_CLK);
975 printf("ARM_PLL %8d MHz\n", freq / 1000);
976 freq = decode_pll(DRAM_PLL_CLK);
977 printf("DRAM_PLL %8d MHz\n", freq / 1000);
978 freq = decode_pll(SYS_PLL_PFD0);
979 printf("SYS_PLL_PFD0 %8d MHz\n", freq / 1000);
980 freq = decode_pll(SYS_PLL_PFD0_DIV2);
981 printf("SYS_PLL_PFD0_DIV2 %8d MHz\n", freq / 1000);
982 freq = decode_pll(SYS_PLL_PFD1);
983 printf("SYS_PLL_PFD1 %8d MHz\n", freq / 1000);
984 freq = decode_pll(SYS_PLL_PFD1_DIV2);
985 printf("SYS_PLL_PFD1_DIV2 %8d MHz\n", freq / 1000);
986 freq = decode_pll(SYS_PLL_PFD2);
987 printf("SYS_PLL_PFD2 %8d MHz\n", freq / 1000);
988 freq = decode_pll(SYS_PLL_PFD2_DIV2);
989 printf("SYS_PLL_PFD2_DIV2 %8d MHz\n", freq / 1000);
990 freq = mxc_get_clock(MXC_ARM_CLK);
991 printf("ARM CORE %8d MHz\n", freq / 1000000);
992 freq = mxc_get_clock(MXC_IPG_CLK);
993 printf("IPG %8d MHz\n", freq / 1000000);
994 freq = mxc_get_clock(MXC_UART_CLK);
995 printf("UART3 %8d MHz\n", freq / 1000000);
996 freq = mxc_get_clock(MXC_ESDHC_CLK);
997 printf("USDHC1 %8d MHz\n", freq / 1000000);
998 freq = mxc_get_clock(MXC_FLEXSPI_CLK);
999 printf("FLEXSPI %8d MHz\n", freq / 1000000);
1000
1001 return 0;
1002 }
1003
1004 U_BOOT_CMD(
1005 clocks, CONFIG_SYS_MAXARGS, 1, do_showclocks,
1006 "display clocks",
1007 ""
1008 );
1009 #endif
1010