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