xref: /rk3399_rockchip-uboot/drivers/clk/rockchip/clk_rk3588.c (revision 514e00a960f8a815e0c86931b498063c6fc4ef76)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2021 Fuzhou Rockchip Electronics Co., Ltd
4  * Author: Elaine Zhang <zhangqing@rock-chips.com>
5  */
6 
7 #include <common.h>
8 #include <bitfield.h>
9 #include <clk-uclass.h>
10 #include <dm.h>
11 #include <errno.h>
12 #include <syscon.h>
13 #include <asm/arch/clock.h>
14 #include <asm/arch/cru_rk3588.h>
15 #include <asm/arch/hardware.h>
16 #include <asm/io.h>
17 #include <dm/lists.h>
18 #include <dt-bindings/clock/rk3588-cru.h>
19 
20 DECLARE_GLOBAL_DATA_PTR;
21 
22 #define DIV_TO_RATE(input_rate, div)	((input_rate) / ((div) + 1))
23 
24 static struct rockchip_pll_rate_table rk3588_pll_rates[] = {
25 	/* _mhz, _p, _m, _s, _k */
26 	RK3588_PLL_RATE(1500000000, 2, 250, 1, 0),
27 	RK3588_PLL_RATE(1200000000, 2, 200, 1, 0),
28 	RK3588_PLL_RATE(1188000000, 2, 198, 1, 0),
29 	RK3588_PLL_RATE(1100000000, 3, 550, 2, 0),
30 	RK3588_PLL_RATE(1008000000, 2, 336, 2, 0),
31 	RK3588_PLL_RATE(1000000000, 3, 500, 2, 0),
32 	RK3588_PLL_RATE(900000000, 2, 300, 2, 0),
33 	RK3588_PLL_RATE(850000000, 3, 425, 2, 0),
34 	RK3588_PLL_RATE(816000000, 2, 272, 2, 0),
35 	RK3588_PLL_RATE(786432000, 2, 262, 2, 9437),
36 	RK3588_PLL_RATE(786000000, 1, 131, 2, 0),
37 	RK3588_PLL_RATE(722534400, 8, 963, 2, 24850),
38 	RK3588_PLL_RATE(600000000, 2, 200, 2, 0),
39 	RK3588_PLL_RATE(594000000, 2, 198, 2, 0),
40 	RK3588_PLL_RATE(200000000, 3, 400, 4, 0),
41 	RK3588_PLL_RATE(100000000, 3, 400, 5, 0),
42 	{ /* sentinel */ },
43 };
44 
45 static struct rockchip_pll_clock rk3588_pll_clks[] = {
46 	[B0PLL] = PLL(pll_rk3588, PLL_B0PLL, RK3588_B0_PLL_CON(0),
47 		      RK3588_B0_PLL_MODE_CON, 0, 15, 0,
48 		      rk3588_pll_rates),
49 	[B1PLL] = PLL(pll_rk3588, PLL_B1PLL, RK3588_B1_PLL_CON(8),
50 		      RK3588_B1_PLL_MODE_CON, 0, 15, 0,
51 		      rk3588_pll_rates),
52 	[LPLL] = PLL(pll_rk3588, PLL_LPLL, RK3588_LPLL_CON(16),
53 		     RK3588_LPLL_MODE_CON, 0, 15, 0, rk3588_pll_rates),
54 	[V0PLL] = PLL(pll_rk3588, PLL_V0PLL, RK3588_PLL_CON(88),
55 		      RK3588_MODE_CON0, 4, 15, 0, rk3588_pll_rates),
56 	[AUPLL] = PLL(pll_rk3588, PLL_AUPLL, RK3588_PLL_CON(96),
57 		      RK3588_MODE_CON0, 6, 15, 0, rk3588_pll_rates),
58 	[CPLL] = PLL(pll_rk3588, PLL_CPLL, RK3588_PLL_CON(104),
59 		     RK3588_MODE_CON0, 8, 15, 0, rk3588_pll_rates),
60 	[GPLL] = PLL(pll_rk3588, PLL_GPLL, RK3588_PLL_CON(112),
61 		     RK3588_MODE_CON0, 2, 15, 0, rk3588_pll_rates),
62 	[NPLL] = PLL(pll_rk3588, PLL_NPLL, RK3588_PLL_CON(120),
63 		     RK3588_MODE_CON0, 0, 15, 0, rk3588_pll_rates),
64 	[PPLL] = PLL(pll_rk3588, PLL_PPLL, RK3588_PMU_PLL_CON(128),
65 		     RK3588_MODE_CON0, 10, 15, 0, rk3588_pll_rates),
66 };
67 
68 #ifndef CONFIG_SPL_BUILD
69 #define RK3588_CLK_DUMP(_id, _name, _iscru)	\
70 {						\
71 	.id = _id,				\
72 	.name = _name,				\
73 	.is_cru = _iscru,			\
74 }
75 
76 static const struct rk3588_clk_info clks_dump[] = {
77 	RK3588_CLK_DUMP(PLL_B0PLL, "b0pll", true),
78 	RK3588_CLK_DUMP(PLL_B1PLL, "b1pll", true),
79 	RK3588_CLK_DUMP(PLL_LPLL, "lpll", true),
80 	RK3588_CLK_DUMP(PLL_V0PLL, "v0pll", true),
81 	RK3588_CLK_DUMP(PLL_AUPLL, "aupll", true),
82 	RK3588_CLK_DUMP(PLL_CPLL, "cpll", true),
83 	RK3588_CLK_DUMP(PLL_GPLL, "gpll", true),
84 	RK3588_CLK_DUMP(PLL_NPLL, "npll", true),
85 	RK3588_CLK_DUMP(PLL_PPLL, "ppll", true),
86 	RK3588_CLK_DUMP(ACLK_CENTER_ROOT, "aclk_center_root", true),
87 	RK3588_CLK_DUMP(PCLK_CENTER_ROOT, "pclk_center_root", true),
88 	RK3588_CLK_DUMP(HCLK_CENTER_ROOT, "hclk_center_root", true),
89 	RK3588_CLK_DUMP(ACLK_CENTER_LOW_ROOT, "aclk_center_low_root", true),
90 	RK3588_CLK_DUMP(ACLK_TOP_ROOT, "aclk_top_root", true),
91 	RK3588_CLK_DUMP(PCLK_TOP_ROOT, "pclk_top_root", true),
92 	RK3588_CLK_DUMP(ACLK_LOW_TOP_ROOT, "aclk_low_top_root", true),
93 };
94 #endif
95 
96 #ifndef CONFIG_SPL_BUILD
97 /*
98  *
99  * rational_best_approximation(31415, 10000,
100  *		(1 << 8) - 1, (1 << 5) - 1, &n, &d);
101  *
102  * you may look at given_numerator as a fixed point number,
103  * with the fractional part size described in given_denominator.
104  *
105  * for theoretical background, see:
106  * http://en.wikipedia.org/wiki/Continued_fraction
107  */
108 static void rational_best_approximation(unsigned long given_numerator,
109 					unsigned long given_denominator,
110 					unsigned long max_numerator,
111 					unsigned long max_denominator,
112 					unsigned long *best_numerator,
113 					unsigned long *best_denominator)
114 {
115 	unsigned long n, d, n0, d0, n1, d1;
116 
117 	n = given_numerator;
118 	d = given_denominator;
119 	n0 = 0;
120 	d1 = 0;
121 	n1 = 1;
122 	d0 = 1;
123 	for (;;) {
124 		unsigned long t, a;
125 
126 		if (n1 > max_numerator || d1 > max_denominator) {
127 			n1 = n0;
128 			d1 = d0;
129 			break;
130 		}
131 		if (d == 0)
132 			break;
133 		t = d;
134 		a = n / d;
135 		d = n % d;
136 		n = t;
137 		t = n0 + a * n1;
138 		n0 = n1;
139 		n1 = t;
140 		t = d0 + a * d1;
141 		d0 = d1;
142 		d1 = t;
143 	}
144 	*best_numerator = n1;
145 	*best_denominator = d1;
146 }
147 #endif
148 
149 static ulong rk3588_center_get_clk(struct rk3588_clk_priv *priv, ulong clk_id)
150 {
151 	struct rk3588_cru *cru = priv->cru;
152 	u32 con, sel, rate;
153 
154 	switch (clk_id) {
155 	case ACLK_CENTER_ROOT:
156 		con = readl(&cru->clksel_con[165]);
157 		sel = (con & ACLK_CENTER_ROOT_SEL_MASK) >>
158 		      ACLK_CENTER_ROOT_SEL_SHIFT;
159 		if (sel == ACLK_CENTER_ROOT_SEL_700M)
160 			rate = 702 * MHz;
161 		else if (sel == ACLK_CENTER_ROOT_SEL_400M)
162 			rate = 396 * MHz;
163 		else if (sel == ACLK_CENTER_ROOT_SEL_200M)
164 			rate = 200 * MHz;
165 		else
166 			rate = OSC_HZ;
167 		break;
168 	case ACLK_CENTER_LOW_ROOT:
169 		con = readl(&cru->clksel_con[165]);
170 		sel = (con & ACLK_CENTER_LOW_ROOT_SEL_MASK) >>
171 		      ACLK_CENTER_LOW_ROOT_SEL_SHIFT;
172 		if (sel == ACLK_CENTER_LOW_ROOT_SEL_500M)
173 			rate = 500 * MHz;
174 		else if (sel == ACLK_CENTER_LOW_ROOT_SEL_250M)
175 			rate = 250 * MHz;
176 		else if (sel == ACLK_CENTER_LOW_ROOT_SEL_100M)
177 			rate = 100 * MHz;
178 		else
179 			rate = OSC_HZ;
180 		break;
181 	case HCLK_CENTER_ROOT:
182 		con = readl(&cru->clksel_con[165]);
183 		sel = (con & HCLK_CENTER_ROOT_SEL_MASK) >>
184 		      HCLK_CENTER_ROOT_SEL_SHIFT;
185 		if (sel == HCLK_CENTER_ROOT_SEL_400M)
186 			rate = 396 * MHz;
187 		else if (sel == HCLK_CENTER_ROOT_SEL_200M)
188 			rate = 200 * MHz;
189 		else if (sel == HCLK_CENTER_ROOT_SEL_100M)
190 			rate = 100 * MHz;
191 		else
192 			rate = OSC_HZ;
193 		break;
194 	case PCLK_CENTER_ROOT:
195 		con = readl(&cru->clksel_con[165]);
196 		sel = (con & PCLK_CENTER_ROOT_SEL_MASK) >>
197 		      PCLK_CENTER_ROOT_SEL_SHIFT;
198 		if (sel == PCLK_CENTER_ROOT_SEL_200M)
199 			rate = 200 * MHz;
200 		else if (sel == PCLK_CENTER_ROOT_SEL_100M)
201 			rate = 100 * MHz;
202 		else if (sel == PCLK_CENTER_ROOT_SEL_50M)
203 			rate = 50 * MHz;
204 		else
205 			rate = OSC_HZ;
206 		break;
207 	default:
208 		return -ENOENT;
209 	}
210 
211 	return rate;
212 }
213 
214 static ulong rk3588_center_set_clk(struct rk3588_clk_priv *priv,
215 				   ulong clk_id, ulong rate)
216 {
217 	struct rk3588_cru *cru = priv->cru;
218 	int src_clk;
219 
220 	switch (clk_id) {
221 	case ACLK_CENTER_ROOT:
222 		if (rate >= 700 * MHz)
223 			src_clk = ACLK_CENTER_ROOT_SEL_700M;
224 		else if (rate >= 396 * MHz)
225 			src_clk = ACLK_CENTER_ROOT_SEL_400M;
226 		else if (rate >= 200 * MHz)
227 			src_clk = ACLK_CENTER_ROOT_SEL_200M;
228 		else
229 			src_clk = ACLK_CENTER_ROOT_SEL_24M;
230 		rk_clrsetreg(&cru->clksel_con[165],
231 			     ACLK_CENTER_ROOT_SEL_MASK,
232 			     src_clk << ACLK_CENTER_ROOT_SEL_SHIFT);
233 		break;
234 	case ACLK_CENTER_LOW_ROOT:
235 		if (rate >= 500 * MHz)
236 			src_clk = ACLK_CENTER_LOW_ROOT_SEL_500M;
237 		else if (rate >= 250 * MHz)
238 			src_clk = ACLK_CENTER_LOW_ROOT_SEL_250M;
239 		else if (rate >= 99 * MHz)
240 			src_clk = ACLK_CENTER_LOW_ROOT_SEL_100M;
241 		else
242 			src_clk = ACLK_CENTER_LOW_ROOT_SEL_24M;
243 		rk_clrsetreg(&cru->clksel_con[165],
244 			     ACLK_CENTER_LOW_ROOT_SEL_MASK,
245 			     src_clk << ACLK_CENTER_LOW_ROOT_SEL_SHIFT);
246 		break;
247 	case HCLK_CENTER_ROOT:
248 		if (rate >= 396 * MHz)
249 			src_clk = HCLK_CENTER_ROOT_SEL_400M;
250 		else if (rate >= 198 * MHz)
251 			src_clk = HCLK_CENTER_ROOT_SEL_200M;
252 		else if (rate >= 99 * MHz)
253 			src_clk = HCLK_CENTER_ROOT_SEL_100M;
254 		else
255 			src_clk = HCLK_CENTER_ROOT_SEL_24M;
256 		rk_clrsetreg(&cru->clksel_con[165],
257 			     HCLK_CENTER_ROOT_SEL_MASK,
258 			     src_clk << HCLK_CENTER_ROOT_SEL_SHIFT);
259 		break;
260 	case PCLK_CENTER_ROOT:
261 		if (rate >= 198 * MHz)
262 			src_clk = PCLK_CENTER_ROOT_SEL_200M;
263 		else if (rate >= 99 * MHz)
264 			src_clk = PCLK_CENTER_ROOT_SEL_100M;
265 		else if (rate >= 50 * MHz)
266 			src_clk = PCLK_CENTER_ROOT_SEL_50M;
267 		else
268 			src_clk = PCLK_CENTER_ROOT_SEL_24M;
269 		rk_clrsetreg(&cru->clksel_con[165],
270 			     PCLK_CENTER_ROOT_SEL_MASK,
271 			     src_clk << PCLK_CENTER_ROOT_SEL_SHIFT);
272 		break;
273 	default:
274 		printf("do not support this center freq\n");
275 		return -EINVAL;
276 	}
277 
278 	return rk3588_center_get_clk(priv, clk_id);
279 }
280 
281 static ulong rk3588_top_get_clk(struct rk3588_clk_priv *priv, ulong clk_id)
282 {
283 	struct rk3588_cru *cru = priv->cru;
284 	u32 con, sel, div, rate, prate;
285 
286 	switch (clk_id) {
287 	case ACLK_TOP_ROOT:
288 		con = readl(&cru->clksel_con[8]);
289 		div = (con & ACLK_TOP_ROOT_DIV_MASK) >>
290 		      ACLK_TOP_ROOT_DIV_SHIFT;
291 		sel = (con & ACLK_TOP_ROOT_SRC_SEL_MASK) >>
292 		      ACLK_TOP_ROOT_SRC_SEL_SHIFT;
293 		if (sel == ACLK_TOP_ROOT_SRC_SEL_CPLL)
294 			prate = priv->cpll_hz;
295 		else
296 			prate = priv->cpll_hz;
297 		return DIV_TO_RATE(prate, div);
298 	case ACLK_LOW_TOP_ROOT:
299 		con = readl(&cru->clksel_con[8]);
300 		div = (con & ACLK_LOW_TOP_ROOT_DIV_MASK) >>
301 		      ACLK_LOW_TOP_ROOT_DIV_SHIFT;
302 		sel = (con & ACLK_LOW_TOP_ROOT_SRC_SEL_MASK) >>
303 		      ACLK_LOW_TOP_ROOT_SRC_SEL_SHIFT;
304 		if (sel == ACLK_LOW_TOP_ROOT_SRC_SEL_CPLL)
305 			prate = priv->cpll_hz;
306 		else
307 			prate = priv->gpll_hz;
308 		return DIV_TO_RATE(prate, div);
309 	case PCLK_TOP_ROOT:
310 		con = readl(&cru->clksel_con[8]);
311 		sel = (con & PCLK_TOP_ROOT_SEL_MASK) >> PCLK_TOP_ROOT_SEL_SHIFT;
312 		if (sel == PCLK_TOP_ROOT_SEL_100M)
313 			rate = 100 * MHz;
314 		else if (sel == PCLK_TOP_ROOT_SEL_50M)
315 			rate = 50 * MHz;
316 		else
317 			rate = OSC_HZ;
318 		break;
319 	default:
320 		return -ENOENT;
321 	}
322 
323 	return rate;
324 }
325 
326 static ulong rk3588_top_set_clk(struct rk3588_clk_priv *priv,
327 				ulong clk_id, ulong rate)
328 {
329 	struct rk3588_cru *cru = priv->cru;
330 	int src_clk, src_clk_div;
331 
332 	switch (clk_id) {
333 	case ACLK_TOP_ROOT:
334 		src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
335 		assert(src_clk_div - 1 <= 31);
336 		rk_clrsetreg(&cru->clksel_con[8],
337 			     ACLK_TOP_ROOT_DIV_MASK |
338 			     ACLK_TOP_ROOT_SRC_SEL_MASK,
339 			     (ACLK_TOP_ROOT_SRC_SEL_GPLL <<
340 			      ACLK_TOP_ROOT_SRC_SEL_SHIFT) |
341 			     (src_clk_div - 1) << ACLK_TOP_ROOT_DIV_SHIFT);
342 		break;
343 	case ACLK_LOW_TOP_ROOT:
344 		src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
345 		assert(src_clk_div - 1 <= 31);
346 		rk_clrsetreg(&cru->clksel_con[8],
347 			     ACLK_LOW_TOP_ROOT_DIV_MASK |
348 			     ACLK_LOW_TOP_ROOT_SRC_SEL_MASK,
349 			     (ACLK_LOW_TOP_ROOT_SRC_SEL_GPLL <<
350 			      ACLK_LOW_TOP_ROOT_SRC_SEL_SHIFT) |
351 			     (src_clk_div - 1) << ACLK_LOW_TOP_ROOT_DIV_SHIFT);
352 		break;
353 	case PCLK_TOP_ROOT:
354 		if (rate == 100 * MHz)
355 			src_clk = PCLK_TOP_ROOT_SEL_100M;
356 		else if (rate == 50 * MHz)
357 			src_clk = PCLK_TOP_ROOT_SEL_50M;
358 		else
359 			src_clk = PCLK_TOP_ROOT_SEL_24M;
360 		rk_clrsetreg(&cru->clksel_con[8],
361 			     PCLK_TOP_ROOT_SEL_MASK,
362 			     src_clk << PCLK_TOP_ROOT_SEL_SHIFT);
363 		break;
364 	default:
365 		printf("do not support this top freq\n");
366 		return -EINVAL;
367 	}
368 
369 	return rk3588_top_get_clk(priv, clk_id);
370 }
371 
372 static ulong rk3588_i2c_get_clk(struct rk3588_clk_priv *priv, ulong clk_id)
373 {
374 	struct rk3588_cru *cru = priv->cru;
375 	u32 sel, con;
376 	ulong rate;
377 
378 	switch (clk_id) {
379 	case CLK_I2C0:
380 		con = readl(&cru->pmuclksel_con[3]);
381 		sel = (con & CLK_I2C0_SEL_MASK) >> CLK_I2C0_SEL_SHIFT;
382 		break;
383 	case CLK_I2C1:
384 		con = readl(&cru->clksel_con[38]);
385 		sel = (con & CLK_I2C1_SEL_MASK) >> CLK_I2C1_SEL_SHIFT;
386 		break;
387 	case CLK_I2C2:
388 		con = readl(&cru->clksel_con[38]);
389 		sel = (con & CLK_I2C2_SEL_MASK) >> CLK_I2C2_SEL_SHIFT;
390 		break;
391 	case CLK_I2C3:
392 		con = readl(&cru->clksel_con[38]);
393 		sel = (con & CLK_I2C3_SEL_MASK) >> CLK_I2C3_SEL_SHIFT;
394 		break;
395 	case CLK_I2C4:
396 		con = readl(&cru->clksel_con[38]);
397 		sel = (con & CLK_I2C4_SEL_MASK) >> CLK_I2C4_SEL_SHIFT;
398 		break;
399 	case CLK_I2C5:
400 		con = readl(&cru->clksel_con[38]);
401 		sel = (con & CLK_I2C5_SEL_MASK) >> CLK_I2C5_SEL_SHIFT;
402 		break;
403 	case CLK_I2C6:
404 		con = readl(&cru->clksel_con[38]);
405 		sel = (con & CLK_I2C6_SEL_MASK) >> CLK_I2C6_SEL_SHIFT;
406 		break;
407 	case CLK_I2C7:
408 		con = readl(&cru->clksel_con[38]);
409 		sel = (con & CLK_I2C7_SEL_MASK) >> CLK_I2C7_SEL_SHIFT;
410 		break;
411 	case CLK_I2C8:
412 		con = readl(&cru->clksel_con[38]);
413 		sel = (con & CLK_I2C8_SEL_MASK) >> CLK_I2C8_SEL_SHIFT;
414 		break;
415 	default:
416 		return -ENOENT;
417 	}
418 	if (sel == CLK_I2C_SEL_200M)
419 		rate = 200 * MHz;
420 	else
421 		rate = 100 * MHz;
422 
423 	return rate;
424 }
425 
426 static ulong rk3588_i2c_set_clk(struct rk3588_clk_priv *priv, ulong clk_id,
427 				ulong rate)
428 {
429 	struct rk3588_cru *cru = priv->cru;
430 	int src_clk;
431 
432 	if (rate >= 198 * MHz)
433 		src_clk = CLK_I2C_SEL_200M;
434 	else
435 		src_clk = CLK_I2C_SEL_100M;
436 
437 	switch (clk_id) {
438 	case CLK_I2C0:
439 		rk_clrsetreg(&cru->pmuclksel_con[3], CLK_I2C0_SEL_MASK,
440 			     src_clk << CLK_I2C0_SEL_SHIFT);
441 		break;
442 	case CLK_I2C1:
443 		rk_clrsetreg(&cru->clksel_con[38], CLK_I2C1_SEL_MASK,
444 			     src_clk << CLK_I2C1_SEL_SHIFT);
445 		break;
446 	case CLK_I2C2:
447 		rk_clrsetreg(&cru->clksel_con[38], CLK_I2C2_SEL_MASK,
448 			     src_clk << CLK_I2C2_SEL_SHIFT);
449 		break;
450 	case CLK_I2C3:
451 		rk_clrsetreg(&cru->clksel_con[38], CLK_I2C3_SEL_MASK,
452 			     src_clk << CLK_I2C3_SEL_SHIFT);
453 		break;
454 	case CLK_I2C4:
455 		rk_clrsetreg(&cru->clksel_con[38], CLK_I2C4_SEL_MASK,
456 			     src_clk << CLK_I2C4_SEL_SHIFT);
457 		break;
458 	case CLK_I2C5:
459 		rk_clrsetreg(&cru->clksel_con[38], CLK_I2C5_SEL_MASK,
460 			     src_clk << CLK_I2C5_SEL_SHIFT);
461 		break;
462 	case CLK_I2C6:
463 		rk_clrsetreg(&cru->clksel_con[38], CLK_I2C6_SEL_MASK,
464 			     src_clk << CLK_I2C6_SEL_SHIFT);
465 		break;
466 	case CLK_I2C7:
467 		rk_clrsetreg(&cru->clksel_con[38], CLK_I2C7_SEL_MASK,
468 			     src_clk << CLK_I2C7_SEL_SHIFT);
469 		break;
470 	case CLK_I2C8:
471 		rk_clrsetreg(&cru->clksel_con[38], CLK_I2C8_SEL_MASK,
472 			     src_clk << CLK_I2C8_SEL_SHIFT);
473 		break;
474 	default:
475 		return -ENOENT;
476 	}
477 
478 	return rk3588_i2c_get_clk(priv, clk_id);
479 }
480 
481 static ulong rk3588_spi_get_clk(struct rk3588_clk_priv *priv, ulong clk_id)
482 {
483 	struct rk3588_cru *cru = priv->cru;
484 	u32 sel, con;
485 
486 	con = readl(&cru->clksel_con[59]);
487 
488 	switch (clk_id) {
489 	case CLK_SPI0:
490 		sel = (con & CLK_SPI0_SEL_MASK) >> CLK_SPI0_SEL_SHIFT;
491 		break;
492 	case CLK_SPI1:
493 		sel = (con & CLK_SPI1_SEL_MASK) >> CLK_SPI1_SEL_SHIFT;
494 		break;
495 	case CLK_SPI2:
496 		sel = (con & CLK_SPI2_SEL_MASK) >> CLK_SPI2_SEL_SHIFT;
497 		break;
498 	case CLK_SPI3:
499 		sel = (con & CLK_SPI3_SEL_MASK) >> CLK_SPI3_SEL_SHIFT;
500 		break;
501 	case CLK_SPI4:
502 		sel = (con & CLK_SPI4_SEL_MASK) >> CLK_SPI4_SEL_SHIFT;
503 		break;
504 	default:
505 		return -ENOENT;
506 	}
507 
508 	switch (sel) {
509 	case CLK_SPI_SEL_200M:
510 		return 200 * MHz;
511 	case CLK_SPI_SEL_150M:
512 		return 150 * MHz;
513 	case CLK_SPI_SEL_24M:
514 		return OSC_HZ;
515 	default:
516 		return -ENOENT;
517 	}
518 }
519 
520 static ulong rk3588_spi_set_clk(struct rk3588_clk_priv *priv,
521 				ulong clk_id, ulong rate)
522 {
523 	struct rk3588_cru *cru = priv->cru;
524 	int src_clk;
525 
526 	if (rate >= 198 * MHz)
527 		src_clk = CLK_SPI_SEL_200M;
528 	else if (rate >= 140 * MHz)
529 		src_clk = CLK_SPI_SEL_150M;
530 	else
531 		src_clk = CLK_SPI_SEL_24M;
532 
533 	switch (clk_id) {
534 	case CLK_SPI0:
535 		rk_clrsetreg(&cru->clksel_con[59],
536 			     CLK_SPI0_SEL_MASK,
537 			     src_clk << CLK_SPI0_SEL_SHIFT);
538 		break;
539 	case CLK_SPI1:
540 		rk_clrsetreg(&cru->clksel_con[59],
541 			     CLK_SPI1_SEL_MASK,
542 			     src_clk << CLK_SPI1_SEL_SHIFT);
543 		break;
544 	case CLK_SPI2:
545 		rk_clrsetreg(&cru->clksel_con[59],
546 			     CLK_SPI2_SEL_MASK,
547 			     src_clk << CLK_SPI2_SEL_SHIFT);
548 		break;
549 	case CLK_SPI3:
550 		rk_clrsetreg(&cru->clksel_con[59],
551 			     CLK_SPI3_SEL_MASK,
552 			     src_clk << CLK_SPI3_SEL_SHIFT);
553 		break;
554 	case CLK_SPI4:
555 		rk_clrsetreg(&cru->clksel_con[59],
556 			     CLK_SPI4_SEL_MASK,
557 			     src_clk << CLK_SPI4_SEL_SHIFT);
558 		break;
559 	default:
560 		return -ENOENT;
561 	}
562 
563 	return rk3588_spi_get_clk(priv, clk_id);
564 }
565 
566 static ulong rk3588_pwm_get_clk(struct rk3588_clk_priv *priv, ulong clk_id)
567 {
568 	struct rk3588_cru *cru = priv->cru;
569 	u32 sel, con;
570 
571 	switch (clk_id) {
572 	case CLK_PWM1:
573 		con = readl(&cru->clksel_con[59]);
574 		sel = (con & CLK_PWM1_SEL_MASK) >> CLK_PWM1_SEL_SHIFT;
575 		break;
576 	case CLK_PWM2:
577 		con = readl(&cru->clksel_con[59]);
578 		sel = (con & CLK_PWM2_SEL_MASK) >> CLK_PWM2_SEL_SHIFT;
579 		break;
580 	case CLK_PWM3:
581 		con = readl(&cru->clksel_con[60]);
582 		sel = (con & CLK_PWM3_SEL_MASK) >> CLK_PWM3_SEL_SHIFT;
583 		break;
584 	case CLK_PMU1PWM:
585 		con = readl(&cru->pmuclksel_con[2]);
586 		sel = (con & CLK_PMU1PWM_SEL_MASK) >> CLK_PMU1PWM_SEL_SHIFT;
587 		break;
588 	default:
589 		return -ENOENT;
590 	}
591 
592 	switch (sel) {
593 	case CLK_PWM_SEL_100M:
594 		return 100 * MHz;
595 	case CLK_PWM_SEL_50M:
596 		return 50 * MHz;
597 	case CLK_PWM_SEL_24M:
598 		return OSC_HZ;
599 	default:
600 		return -ENOENT;
601 	}
602 }
603 
604 static ulong rk3588_pwm_set_clk(struct rk3588_clk_priv *priv,
605 				ulong clk_id, ulong rate)
606 {
607 	struct rk3588_cru *cru = priv->cru;
608 	int src_clk;
609 
610 	if (rate >= 99 * MHz)
611 		src_clk = CLK_PWM_SEL_100M;
612 	else if (rate >= 50 * MHz)
613 		src_clk = CLK_PWM_SEL_50M;
614 	else
615 		src_clk = CLK_PWM_SEL_24M;
616 
617 	switch (clk_id) {
618 	case CLK_PWM1:
619 		rk_clrsetreg(&cru->clksel_con[59],
620 			     CLK_PWM1_SEL_MASK,
621 			     src_clk << CLK_PWM1_SEL_SHIFT);
622 		break;
623 	case CLK_PWM2:
624 		rk_clrsetreg(&cru->clksel_con[59],
625 			     CLK_PWM2_SEL_MASK,
626 			     src_clk << CLK_PWM2_SEL_SHIFT);
627 		break;
628 	case CLK_PWM3:
629 		rk_clrsetreg(&cru->clksel_con[60],
630 			     CLK_PWM3_SEL_MASK,
631 			     src_clk << CLK_PWM3_SEL_SHIFT);
632 		break;
633 	case CLK_PMU1PWM:
634 		rk_clrsetreg(&cru->pmuclksel_con[2],
635 			     CLK_PMU1PWM_SEL_MASK,
636 			     src_clk << CLK_PMU1PWM_SEL_SHIFT);
637 		break;
638 	default:
639 		return -ENOENT;
640 	}
641 
642 	return rk3588_pwm_get_clk(priv, clk_id);
643 }
644 
645 static ulong rk3588_adc_get_clk(struct rk3588_clk_priv *priv, ulong clk_id)
646 {
647 	struct rk3588_cru *cru = priv->cru;
648 	u32 div, sel, con, prate;
649 
650 	switch (clk_id) {
651 	case CLK_SARADC:
652 		con = readl(&cru->clksel_con[40]);
653 		div = (con & CLK_SARADC_DIV_MASK) >> CLK_SARADC_DIV_SHIFT;
654 		sel = (con & CLK_SARADC_SEL_MASK) >>
655 		      CLK_SARADC_SEL_SHIFT;
656 		if (sel == CLK_SARADC_SEL_24M)
657 			prate = OSC_HZ;
658 		else
659 			prate = priv->gpll_hz;
660 		return DIV_TO_RATE(prate, div);
661 	case CLK_TSADC:
662 		con = readl(&cru->clksel_con[41]);
663 		div = (con & CLK_TSADC_DIV_MASK) >>
664 		      CLK_TSADC_DIV_SHIFT;
665 		sel = (con & CLK_TSADC_SEL_MASK) >>
666 		      CLK_TSADC_SEL_SHIFT;
667 		if (sel == CLK_TSADC_SEL_24M)
668 			prate = OSC_HZ;
669 		else
670 			prate = 100 * MHz;
671 		return DIV_TO_RATE(prate, div);
672 	default:
673 		return -ENOENT;
674 	}
675 }
676 
677 static ulong rk3588_adc_set_clk(struct rk3588_clk_priv *priv,
678 				ulong clk_id, ulong rate)
679 {
680 	struct rk3588_cru *cru = priv->cru;
681 	int src_clk_div;
682 
683 	switch (clk_id) {
684 	case CLK_SARADC:
685 		if (!(OSC_HZ % rate)) {
686 			src_clk_div = DIV_ROUND_UP(OSC_HZ, rate);
687 			assert(src_clk_div - 1 <= 255);
688 			rk_clrsetreg(&cru->clksel_con[40],
689 				     CLK_SARADC_SEL_MASK |
690 				     CLK_SARADC_DIV_MASK,
691 				     (CLK_SARADC_SEL_24M <<
692 				      CLK_SARADC_SEL_SHIFT) |
693 				     (src_clk_div - 1) <<
694 				     CLK_SARADC_DIV_SHIFT);
695 		} else {
696 			src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
697 			assert(src_clk_div - 1 <= 255);
698 			rk_clrsetreg(&cru->clksel_con[40],
699 				     CLK_SARADC_SEL_MASK |
700 				     CLK_SARADC_DIV_MASK,
701 				     (CLK_SARADC_SEL_GPLL <<
702 				      CLK_SARADC_SEL_SHIFT) |
703 				     (src_clk_div - 1) <<
704 				     CLK_SARADC_DIV_SHIFT);
705 		}
706 		break;
707 	case CLK_TSADC:
708 		if (!(OSC_HZ % rate)) {
709 			src_clk_div = DIV_ROUND_UP(OSC_HZ, rate);
710 			assert(src_clk_div - 1 <= 255);
711 			rk_clrsetreg(&cru->clksel_con[41],
712 				     CLK_TSADC_SEL_MASK |
713 				     CLK_TSADC_DIV_MASK,
714 				     (CLK_TSADC_SEL_24M <<
715 				      CLK_TSADC_SEL_SHIFT) |
716 				     (src_clk_div - 1) <<
717 				     CLK_TSADC_DIV_SHIFT);
718 		} else {
719 			src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
720 			assert(src_clk_div - 1 <= 7);
721 			rk_clrsetreg(&cru->clksel_con[41],
722 				     CLK_TSADC_SEL_MASK |
723 				     CLK_TSADC_DIV_MASK,
724 				     (CLK_TSADC_SEL_GPLL <<
725 				      CLK_TSADC_SEL_SHIFT) |
726 				     (src_clk_div - 1) <<
727 				     CLK_TSADC_DIV_SHIFT);
728 		}
729 		break;
730 	default:
731 		return -ENOENT;
732 	}
733 	return rk3588_adc_get_clk(priv, clk_id);
734 }
735 
736 static ulong rk3588_mmc_get_clk(struct rk3588_clk_priv *priv, ulong clk_id)
737 {
738 	struct rk3588_cru *cru = priv->cru;
739 	u32 sel, con, div, prate;
740 
741 	switch (clk_id) {
742 	case CCLK_SRC_SDIO:
743 		con = readl(&cru->clksel_con[172]);
744 		div = (con & CCLK_SDIO_SRC_DIV_MASK) >> CCLK_SDIO_SRC_DIV_SHIFT;
745 		sel = (con & CCLK_SDIO_SRC_SEL_MASK) >>
746 		      CCLK_SDIO_SRC_SEL_SHIFT;
747 		if (sel == CCLK_SDIO_SRC_SEL_GPLL)
748 			prate = priv->gpll_hz;
749 		else if (sel == CCLK_SDIO_SRC_SEL_CPLL)
750 			prate = priv->cpll_hz;
751 		else
752 			prate = OSC_HZ;
753 		return DIV_TO_RATE(prate, div);
754 	case CCLK_EMMC:
755 		con = readl(&cru->clksel_con[77]);
756 		div = (con & CCLK_EMMC_DIV_MASK) >> CCLK_EMMC_DIV_SHIFT;
757 		sel = (con & CCLK_EMMC_SEL_MASK) >>
758 		      CCLK_EMMC_SEL_SHIFT;
759 		if (sel == CCLK_EMMC_SEL_GPLL)
760 			prate = priv->gpll_hz;
761 		else if (sel == CCLK_EMMC_SEL_CPLL)
762 			prate = priv->cpll_hz;
763 		else
764 			prate = OSC_HZ;
765 		return DIV_TO_RATE(prate, div);
766 	case BCLK_EMMC:
767 		con = readl(&cru->clksel_con[78]);
768 		div = (con & BCLK_EMMC_DIV_MASK) >> BCLK_EMMC_DIV_SHIFT;
769 		sel = (con & BCLK_EMMC_SEL_MASK) >>
770 		      BCLK_EMMC_SEL_SHIFT;
771 		if (sel == CCLK_EMMC_SEL_CPLL)
772 			prate = priv->cpll_hz;
773 		else
774 			prate = priv->gpll_hz;
775 		return DIV_TO_RATE(prate, div);
776 	case SCLK_SFC:
777 		con = readl(&cru->clksel_con[78]);
778 		div = (con & SCLK_SFC_DIV_MASK) >> SCLK_SFC_DIV_SHIFT;
779 		sel = (con & SCLK_SFC_SEL_MASK) >>
780 		      SCLK_SFC_SEL_SHIFT;
781 		if (sel == SCLK_SFC_SEL_GPLL)
782 			prate = priv->gpll_hz;
783 		else if (sel == SCLK_SFC_SEL_CPLL)
784 			prate = priv->cpll_hz;
785 		else
786 			prate = OSC_HZ;
787 		return DIV_TO_RATE(prate, div);
788 	case DCLK_DECOM:
789 		con = readl(&cru->clksel_con[62]);
790 		div = (con & DCLK_DECOM_DIV_MASK) >> DCLK_DECOM_DIV_SHIFT;
791 		sel = (con & DCLK_DECOM_SEL_MASK) >>
792 		      DCLK_DECOM_SEL_SHIFT;
793 		if (sel == DCLK_DECOM_SEL_SPLL)
794 			prate = 702 * MHz;
795 		else
796 			prate = priv->gpll_hz;
797 		return DIV_TO_RATE(prate, div);
798 	default:
799 		return -ENOENT;
800 	}
801 }
802 
803 static ulong rk3588_mmc_set_clk(struct rk3588_clk_priv *priv,
804 				ulong clk_id, ulong rate)
805 {
806 	struct rk3588_cru *cru = priv->cru;
807 	int src_clk, div;
808 
809 	switch (clk_id) {
810 	case CCLK_SRC_SDIO:
811 	case CCLK_EMMC:
812 	case SCLK_SFC:
813 		if (!(OSC_HZ % rate)) {
814 			src_clk = SCLK_SFC_SEL_24M;
815 			div = DIV_ROUND_UP(OSC_HZ, rate);
816 		} else if (!(priv->cpll_hz % rate)) {
817 			src_clk = SCLK_SFC_SEL_CPLL;
818 			div = DIV_ROUND_UP(priv->cpll_hz, rate);
819 		} else {
820 			src_clk = SCLK_SFC_SEL_GPLL;
821 			div = DIV_ROUND_UP(priv->gpll_hz, rate);
822 		}
823 		break;
824 	case BCLK_EMMC:
825 		if (!(priv->cpll_hz % rate)) {
826 			src_clk = CCLK_EMMC_SEL_CPLL;
827 			div = DIV_ROUND_UP(priv->cpll_hz, rate);
828 		} else {
829 			src_clk = CCLK_EMMC_SEL_GPLL;
830 			div = DIV_ROUND_UP(priv->gpll_hz, rate);
831 		}
832 		break;
833 	case DCLK_DECOM:
834 		if (!(702 * MHz % rate)) {
835 			src_clk = DCLK_DECOM_SEL_SPLL;
836 			div = DIV_ROUND_UP(702 * MHz, rate);
837 		} else {
838 			src_clk = DCLK_DECOM_SEL_GPLL;
839 			div = DIV_ROUND_UP(priv->gpll_hz, rate);
840 		}
841 		break;
842 	default:
843 		return -ENOENT;
844 	}
845 
846 	switch (clk_id) {
847 	case CCLK_SRC_SDIO:
848 		rk_clrsetreg(&cru->clksel_con[172],
849 			     CCLK_SDIO_SRC_SEL_MASK |
850 			     CCLK_SDIO_SRC_DIV_MASK,
851 			     (src_clk << CCLK_SDIO_SRC_SEL_SHIFT) |
852 			     (div - 1) << CCLK_SDIO_SRC_DIV_SHIFT);
853 		break;
854 	case CCLK_EMMC:
855 		rk_clrsetreg(&cru->clksel_con[77],
856 			     CCLK_EMMC_SEL_MASK |
857 			     CCLK_EMMC_DIV_MASK,
858 			     (src_clk << CCLK_EMMC_SEL_SHIFT) |
859 			     (div - 1) << CCLK_EMMC_DIV_SHIFT);
860 		break;
861 	case BCLK_EMMC:
862 		rk_clrsetreg(&cru->clksel_con[78],
863 			     BCLK_EMMC_DIV_MASK |
864 			     BCLK_EMMC_SEL_MASK,
865 			     (src_clk << BCLK_EMMC_SEL_SHIFT) |
866 			     (div - 1) << BCLK_EMMC_DIV_SHIFT);
867 		break;
868 	case SCLK_SFC:
869 		rk_clrsetreg(&cru->clksel_con[78],
870 			     SCLK_SFC_DIV_MASK |
871 			     SCLK_SFC_SEL_MASK,
872 			     (src_clk << SCLK_SFC_SEL_SHIFT) |
873 			     (div - 1) << SCLK_SFC_DIV_SHIFT);
874 		break;
875 	case DCLK_DECOM:
876 		rk_clrsetreg(&cru->clksel_con[62],
877 			     DCLK_DECOM_DIV_MASK |
878 			     DCLK_DECOM_SEL_MASK,
879 			     (src_clk << DCLK_DECOM_SEL_SHIFT) |
880 			     (div - 1) << DCLK_DECOM_DIV_SHIFT);
881 		break;
882 	default:
883 		return -ENOENT;
884 	}
885 
886 	return rk3588_mmc_get_clk(priv, clk_id);
887 }
888 
889 #ifndef CONFIG_SPL_BUILD
890 static ulong rk3588_aux16m_get_clk(struct rk3588_clk_priv *priv, ulong clk_id)
891 {
892 	struct rk3588_cru *cru = priv->cru;
893 	u32 div, con, parent;
894 
895 	parent = priv->gpll_hz;
896 	con = readl(&cru->clksel_con[117]);
897 
898 	switch (clk_id) {
899 	case CLK_AUX16M_0:
900 		div = (con & CLK_AUX16MHZ_0_DIV_MASK) >> CLK_AUX16MHZ_0_DIV_SHIFT;
901 		return DIV_TO_RATE(parent, div);
902 	case CLK_AUX16M_1:
903 		div = (con & CLK_AUX16MHZ_1_DIV_MASK) >> CLK_AUX16MHZ_1_DIV_SHIFT;
904 		return DIV_TO_RATE(parent, div);
905 	default:
906 		return -ENOENT;
907 	}
908 }
909 
910 static ulong rk3588_aux16m_set_clk(struct rk3588_clk_priv *priv,
911 				   ulong clk_id, ulong rate)
912 {
913 	struct rk3588_cru *cru = priv->cru;
914 	u32 div;
915 
916 	if (!priv->gpll_hz) {
917 		printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
918 		return -ENOENT;
919 	}
920 
921 	div = DIV_ROUND_UP(priv->gpll_hz, rate);
922 
923 	switch (clk_id) {
924 	case CLK_AUX16M_0:
925 		rk_clrsetreg(&cru->clksel_con[117], CLK_AUX16MHZ_0_DIV_MASK,
926 			     (div - 1) << CLK_AUX16MHZ_0_DIV_SHIFT);
927 		break;
928 	case CLK_AUX16M_1:
929 		rk_clrsetreg(&cru->clksel_con[117], CLK_AUX16MHZ_1_DIV_MASK,
930 			     (div - 1) << CLK_AUX16MHZ_1_DIV_SHIFT);
931 		break;
932 	default:
933 		return -ENOENT;
934 	}
935 
936 	return rk3588_aux16m_get_clk(priv, clk_id);
937 }
938 
939 static ulong rk3588_aclk_vop_get_clk(struct rk3588_clk_priv *priv, ulong clk_id)
940 {
941 	struct rk3588_cru *cru = priv->cru;
942 	u32 div, sel, con, parent;
943 
944 	switch (clk_id) {
945 	case ACLK_VOP_ROOT:
946 	case ACLK_VOP:
947 		con = readl(&cru->clksel_con[110]);
948 		div = (con & ACLK_VOP_ROOT_DIV_MASK) >> ACLK_VOP_ROOT_DIV_SHIFT;
949 		sel = (con & ACLK_VOP_ROOT_SEL_MASK) >> ACLK_VOP_ROOT_SEL_SHIFT;
950 		if (sel == ACLK_VOP_ROOT_SEL_GPLL)
951 			parent = priv->gpll_hz;
952 		else if (sel == ACLK_VOP_ROOT_SEL_CPLL)
953 			parent = priv->cpll_hz;
954 		else if (sel == ACLK_VOP_ROOT_SEL_AUPLL)
955 			parent = priv->aupll_hz;
956 		else if (sel == ACLK_VOP_ROOT_SEL_NPLL)
957 			parent = priv->npll_hz;
958 		else
959 			parent = 702 * MHz;
960 		return DIV_TO_RATE(parent, div);
961 	case ACLK_VOP_LOW_ROOT:
962 		con = readl(&cru->clksel_con[110]);
963 		sel = (con & ACLK_VOP_LOW_ROOT_SEL_MASK) >>
964 		      ACLK_VOP_LOW_ROOT_SEL_SHIFT;
965 		if (sel == ACLK_VOP_LOW_ROOT_SEL_400M)
966 			return 396 * MHz;
967 		else if (sel == ACLK_VOP_LOW_ROOT_SEL_200M)
968 			return 200 * MHz;
969 		else if (sel == ACLK_VOP_LOW_ROOT_SEL_100M)
970 			return 100 * MHz;
971 		else
972 			return OSC_HZ;
973 	case HCLK_VOP_ROOT:
974 		con = readl(&cru->clksel_con[110]);
975 		sel = (con & HCLK_VOP_ROOT_SEL_MASK) >> HCLK_VOP_ROOT_SEL_SHIFT;
976 		if (sel == HCLK_VOP_ROOT_SEL_200M)
977 			return 200 * MHz;
978 		else if (sel == HCLK_VOP_ROOT_SEL_100M)
979 			return 100 * MHz;
980 		else if (sel == HCLK_VOP_ROOT_SEL_50M)
981 			return 50 * MHz;
982 		else
983 			return OSC_HZ;
984 	default:
985 		return -ENOENT;
986 	}
987 }
988 
989 static ulong rk3588_aclk_vop_set_clk(struct rk3588_clk_priv *priv,
990 				     ulong clk_id, ulong rate)
991 {
992 	struct rk3588_cru *cru = priv->cru;
993 	int src_clk, div;
994 
995 	switch (clk_id) {
996 	case ACLK_VOP_ROOT:
997 	case ACLK_VOP:
998 		if (rate >= 850 * MHz) {
999 			src_clk = ACLK_VOP_ROOT_SEL_NPLL;
1000 			div = 1;
1001 		} else if (rate >= 750 * MHz) {
1002 			src_clk = ACLK_VOP_ROOT_SEL_CPLL;
1003 			div = 2;
1004 		} else if (rate >= 700 * MHz) {
1005 			src_clk = ACLK_VOP_ROOT_SEL_SPLL;
1006 			div = 1;
1007 		} else if (!(priv->cpll_hz % rate)) {
1008 			src_clk = ACLK_VOP_ROOT_SEL_CPLL;
1009 			div = DIV_ROUND_UP(priv->cpll_hz, rate);
1010 		} else {
1011 			src_clk = ACLK_VOP_ROOT_SEL_GPLL;
1012 			div = DIV_ROUND_UP(priv->gpll_hz, rate);
1013 		}
1014 		rk_clrsetreg(&cru->clksel_con[110],
1015 			     ACLK_VOP_ROOT_DIV_MASK |
1016 			     ACLK_VOP_ROOT_SEL_MASK,
1017 			     (src_clk << ACLK_VOP_ROOT_SEL_SHIFT) |
1018 			     (div - 1) << ACLK_VOP_ROOT_DIV_SHIFT);
1019 		break;
1020 	case ACLK_VOP_LOW_ROOT:
1021 		if (rate == 400 * MHz || rate == 396 * MHz)
1022 			src_clk = ACLK_VOP_LOW_ROOT_SEL_400M;
1023 		else if (rate == 200 * MHz)
1024 			src_clk = ACLK_VOP_LOW_ROOT_SEL_200M;
1025 		else if (rate == 100 * MHz)
1026 			src_clk = ACLK_VOP_LOW_ROOT_SEL_100M;
1027 		else
1028 			src_clk = ACLK_VOP_LOW_ROOT_SEL_24M;
1029 		rk_clrsetreg(&cru->clksel_con[110],
1030 			     ACLK_VOP_LOW_ROOT_SEL_MASK,
1031 			     src_clk << ACLK_VOP_LOW_ROOT_SEL_SHIFT);
1032 		break;
1033 	case HCLK_VOP_ROOT:
1034 		if (rate == 200 * MHz)
1035 			src_clk = HCLK_VOP_ROOT_SEL_200M;
1036 		else if (rate == 100 * MHz)
1037 			src_clk = HCLK_VOP_ROOT_SEL_100M;
1038 		else if (rate == 50 * MHz)
1039 			src_clk = HCLK_VOP_ROOT_SEL_50M;
1040 		else
1041 			src_clk = HCLK_VOP_ROOT_SEL_24M;
1042 		rk_clrsetreg(&cru->clksel_con[110],
1043 			     HCLK_VOP_ROOT_SEL_MASK,
1044 			     src_clk << HCLK_VOP_ROOT_SEL_SHIFT);
1045 		break;
1046 	default:
1047 		return -ENOENT;
1048 	}
1049 
1050 	return rk3588_aclk_vop_get_clk(priv, clk_id);
1051 }
1052 
1053 static ulong rk3588_dclk_vop_get_clk(struct rk3588_clk_priv *priv, ulong clk_id)
1054 {
1055 	struct rk3588_cru *cru = priv->cru;
1056 	u32 div, sel, con, parent;
1057 
1058 	switch (clk_id) {
1059 	case DCLK_VOP0:
1060 	case DCLK_VOP0_SRC:
1061 		con = readl(&cru->clksel_con[111]);
1062 		div = (con & DCLK0_VOP_SRC_DIV_MASK) >> DCLK0_VOP_SRC_DIV_SHIFT;
1063 		sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT;
1064 		break;
1065 	case DCLK_VOP1:
1066 	case DCLK_VOP1_SRC:
1067 		con = readl(&cru->clksel_con[111]);
1068 		div = (con & DCLK1_VOP_SRC_DIV_MASK) >> DCLK1_VOP_SRC_DIV_SHIFT;
1069 		sel = (con & DCLK1_VOP_SRC_SEL_MASK) >> DCLK1_VOP_SRC_SEL_SHIFT;
1070 		break;
1071 	case DCLK_VOP2:
1072 	case DCLK_VOP2_SRC:
1073 		con = readl(&cru->clksel_con[112]);
1074 		div = (con & DCLK2_VOP_SRC_DIV_MASK) >> DCLK2_VOP_SRC_DIV_SHIFT;
1075 		sel = (con & DCLK2_VOP_SRC_SEL_MASK) >> DCLK2_VOP_SRC_SEL_SHIFT;
1076 		break;
1077 	case DCLK_VOP3:
1078 		con = readl(&cru->clksel_con[113]);
1079 		div = (con & DCLK3_VOP_SRC_DIV_MASK) >> DCLK3_VOP_SRC_DIV_SHIFT;
1080 		sel = (con & DCLK3_VOP_SRC_SEL_MASK) >> DCLK3_VOP_SRC_SEL_SHIFT;
1081 		break;
1082 	default:
1083 		return -ENOENT;
1084 	}
1085 
1086 	if (sel == DCLK_VOP_SRC_SEL_AUPLL)
1087 		parent = priv->aupll_hz;
1088 	else if (sel == DCLK_VOP_SRC_SEL_V0PLL)
1089 		parent = rockchip_pll_get_rate(&rk3588_pll_clks[V0PLL],
1090 					       priv->cru, V0PLL);
1091 	else if (sel == DCLK_VOP_SRC_SEL_GPLL)
1092 		parent = priv->gpll_hz;
1093 	else if (sel == DCLK_VOP_SRC_SEL_CPLL)
1094 		parent = priv->cpll_hz;
1095 	else
1096 		return -ENOENT;
1097 
1098 	return DIV_TO_RATE(parent, div);
1099 }
1100 
1101 #define RK3588_VOP_PLL_LIMIT_FREQ 600000000
1102 
1103 static ulong rk3588_dclk_vop_set_clk(struct rk3588_clk_priv *priv,
1104 				     ulong clk_id, ulong rate)
1105 {
1106 	struct rk3588_cru *cru = priv->cru;
1107 	ulong pll_rate, now, best_rate = 0;
1108 	u32 i, conid, con, sel, div, best_div = 0, best_sel = 0;
1109 	u32 mask, div_shift, sel_shift;
1110 
1111 	switch (clk_id) {
1112 	case DCLK_VOP0:
1113 	case DCLK_VOP0_SRC:
1114 		conid = 111;
1115 		con = readl(&cru->clksel_con[111]);
1116 		sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT;
1117 		mask = DCLK0_VOP_SRC_SEL_MASK | DCLK0_VOP_SRC_DIV_MASK;
1118 		div_shift = DCLK0_VOP_SRC_DIV_SHIFT;
1119 		sel_shift = DCLK0_VOP_SRC_SEL_SHIFT;
1120 		break;
1121 	case DCLK_VOP1:
1122 	case DCLK_VOP1_SRC:
1123 		conid = 111;
1124 		con = readl(&cru->clksel_con[111]);
1125 		sel = (con & DCLK1_VOP_SRC_SEL_MASK) >> DCLK1_VOP_SRC_SEL_SHIFT;
1126 		mask = DCLK1_VOP_SRC_SEL_MASK | DCLK1_VOP_SRC_DIV_MASK;
1127 		div_shift = DCLK1_VOP_SRC_DIV_SHIFT;
1128 		sel_shift = DCLK1_VOP_SRC_SEL_SHIFT;
1129 		break;
1130 	case DCLK_VOP2:
1131 	case DCLK_VOP2_SRC:
1132 		conid = 112;
1133 		con = readl(&cru->clksel_con[112]);
1134 		sel = (con & DCLK2_VOP_SRC_SEL_MASK) >> DCLK2_VOP_SRC_SEL_SHIFT;
1135 		mask = DCLK2_VOP_SRC_SEL_MASK | DCLK2_VOP_SRC_DIV_MASK;
1136 		div_shift = DCLK2_VOP_SRC_DIV_SHIFT;
1137 		sel_shift = DCLK2_VOP_SRC_SEL_SHIFT;
1138 		break;
1139 	case DCLK_VOP3:
1140 		conid = 113;
1141 		con = readl(&cru->clksel_con[113]);
1142 		sel = (con & DCLK3_VOP_SRC_SEL_MASK) >> DCLK3_VOP_SRC_SEL_SHIFT;
1143 		mask = DCLK3_VOP_SRC_SEL_MASK | DCLK3_VOP_SRC_DIV_MASK;
1144 		div_shift = DCLK3_VOP_SRC_DIV_SHIFT;
1145 		sel_shift = DCLK3_VOP_SRC_SEL_SHIFT;
1146 		break;
1147 	default:
1148 		return -ENOENT;
1149 	}
1150 
1151 	if (sel == DCLK_VOP_SRC_SEL_V0PLL) {
1152 		div = DIV_ROUND_UP(RK3588_VOP_PLL_LIMIT_FREQ, rate);
1153 		rk_clrsetreg(&cru->clksel_con[conid],
1154 			     mask,
1155 			     DCLK_VOP_SRC_SEL_V0PLL << sel_shift |
1156 			     ((div - 1) << div_shift));
1157 		rockchip_pll_set_rate(&rk3588_pll_clks[V0PLL],
1158 				      priv->cru, V0PLL, div * rate);
1159 	} else {
1160 		for (i = 0; i <= DCLK_VOP_SRC_SEL_AUPLL; i++) {
1161 			switch (i) {
1162 			case DCLK_VOP_SRC_SEL_GPLL:
1163 				pll_rate = priv->gpll_hz;
1164 				break;
1165 			case DCLK_VOP_SRC_SEL_CPLL:
1166 				pll_rate = priv->cpll_hz;
1167 				break;
1168 			case DCLK_VOP_SRC_SEL_AUPLL:
1169 				pll_rate = priv->aupll_hz;
1170 				break;
1171 			case DCLK_VOP_SRC_SEL_V0PLL:
1172 				pll_rate = 0;
1173 				break;
1174 			default:
1175 				printf("do not support this vop pll sel\n");
1176 				return -EINVAL;
1177 			}
1178 
1179 			div = DIV_ROUND_UP(pll_rate, rate);
1180 			if (div > 255)
1181 				continue;
1182 			now = pll_rate / div;
1183 			if (abs(rate - now) < abs(rate - best_rate)) {
1184 				best_rate = now;
1185 				best_div = div;
1186 				best_sel = i;
1187 			}
1188 			debug("p_rate=%lu, best_rate=%lu, div=%u, sel=%u\n",
1189 			      pll_rate, best_rate, best_div, best_sel);
1190 		}
1191 
1192 		if (best_rate) {
1193 			rk_clrsetreg(&cru->clksel_con[conid],
1194 				     mask,
1195 				     best_sel << sel_shift |
1196 				     (best_div - 1) << div_shift);
1197 		} else {
1198 			printf("do not support this vop freq %lu\n", rate);
1199 			return -EINVAL;
1200 		}
1201 	}
1202 	return rk3588_dclk_vop_get_clk(priv, clk_id);
1203 }
1204 
1205 static ulong rk3588_gmac_get_clk(struct rk3588_clk_priv *priv, ulong clk_id)
1206 {
1207 	struct rk3588_cru *cru = priv->cru;
1208 	u32 con, div;
1209 
1210 	switch (clk_id) {
1211 	case CLK_GMAC0_PTP_REF:
1212 		con = readl(&cru->clksel_con[81]);
1213 		div = (con & CLK_GMAC0_PTP_DIV_MASK) >> CLK_GMAC0_PTP_DIV_SHIFT;
1214 		return DIV_TO_RATE(priv->cpll_hz, div);
1215 	case CLK_GMAC1_PTP_REF:
1216 		con = readl(&cru->clksel_con[81]);
1217 		div = (con & CLK_GMAC1_PTP_DIV_MASK) >> CLK_GMAC1_PTP_DIV_SHIFT;
1218 		return DIV_TO_RATE(priv->cpll_hz, div);
1219 	case CLK_GMAC_125M:
1220 		con = readl(&cru->clksel_con[83]);
1221 		div = (con & CLK_GMAC_125M_DIV_MASK) >> CLK_GMAC_125M_DIV_SHIFT;
1222 		return DIV_TO_RATE(priv->cpll_hz, div);
1223 	case CLK_GMAC_50M:
1224 		con = readl(&cru->clksel_con[84]);
1225 		div = (con & CLK_GMAC_50M_DIV_MASK) >> CLK_GMAC_50M_DIV_SHIFT;
1226 		return DIV_TO_RATE(priv->cpll_hz, div);
1227 	default:
1228 		return -ENOENT;
1229 	}
1230 }
1231 
1232 static ulong rk3588_gmac_set_clk(struct rk3588_clk_priv *priv,
1233 				 ulong clk_id, ulong rate)
1234 {
1235 	struct rk3588_cru *cru = priv->cru;
1236 	int div;
1237 
1238 	div = DIV_ROUND_UP(priv->cpll_hz, rate);
1239 
1240 	switch (clk_id) {
1241 	case CLK_GMAC0_PTP_REF:
1242 		rk_clrsetreg(&cru->clksel_con[81],
1243 			     CLK_GMAC0_PTP_DIV_MASK | CLK_GMAC0_PTP_SEL_MASK,
1244 			     CLK_GMAC0_PTP_SEL_CPLL << CLK_GMAC0_PTP_SEL_SHIFT |
1245 			     (div - 1) << CLK_GMAC0_PTP_DIV_SHIFT);
1246 		break;
1247 	case CLK_GMAC1_PTP_REF:
1248 		rk_clrsetreg(&cru->clksel_con[81],
1249 			     CLK_GMAC1_PTP_DIV_MASK | CLK_GMAC1_PTP_SEL_MASK,
1250 			     CLK_GMAC1_PTP_SEL_CPLL << CLK_GMAC1_PTP_SEL_SHIFT |
1251 			     (div - 1) << CLK_GMAC1_PTP_DIV_SHIFT);
1252 		break;
1253 
1254 	case CLK_GMAC_125M:
1255 		rk_clrsetreg(&cru->clksel_con[83],
1256 			     CLK_GMAC_125M_DIV_MASK | CLK_GMAC_125M_SEL_MASK,
1257 			     CLK_GMAC_125M_SEL_CPLL << CLK_GMAC_125M_SEL_SHIFT |
1258 			     (div - 1) << CLK_GMAC_125M_DIV_SHIFT);
1259 		break;
1260 	case CLK_GMAC_50M:
1261 		rk_clrsetreg(&cru->clksel_con[84],
1262 			     CLK_GMAC_50M_DIV_MASK | CLK_GMAC_50M_SEL_MASK,
1263 			     CLK_GMAC_50M_SEL_CPLL << CLK_GMAC_50M_SEL_SHIFT |
1264 			     (div - 1) << CLK_GMAC_50M_DIV_SHIFT);
1265 		break;
1266 	default:
1267 		return -ENOENT;
1268 	}
1269 
1270 	return rk3588_gmac_get_clk(priv, clk_id);
1271 }
1272 
1273 static ulong rk3588_uart_get_rate(struct rk3588_clk_priv *priv, ulong clk_id)
1274 {
1275 	struct rk3588_cru *cru = priv->cru;
1276 	u32 reg, con, fracdiv, div, src, p_src, p_rate;
1277 	unsigned long m, n;
1278 
1279 	switch (clk_id) {
1280 	case SCLK_UART1:
1281 		reg = 41;
1282 		break;
1283 	case SCLK_UART2:
1284 		reg = 43;
1285 		break;
1286 	case SCLK_UART3:
1287 		reg = 45;
1288 		break;
1289 	case SCLK_UART4:
1290 		reg = 47;
1291 		break;
1292 	case SCLK_UART5:
1293 		reg = 49;
1294 		break;
1295 	case SCLK_UART6:
1296 		reg = 51;
1297 		break;
1298 	case SCLK_UART7:
1299 		reg = 53;
1300 		break;
1301 	case SCLK_UART8:
1302 		reg = 55;
1303 		break;
1304 	case SCLK_UART9:
1305 		reg = 57;
1306 		break;
1307 	default:
1308 		return -ENOENT;
1309 	}
1310 	con = readl(&cru->clksel_con[reg + 2]);
1311 	src = (con & CLK_UART_SEL_MASK) >> CLK_UART_SEL_SHIFT;
1312 	con = readl(&cru->clksel_con[reg]);
1313 	div = (con & CLK_UART_SRC_DIV_MASK) >> CLK_UART_SRC_DIV_SHIFT;
1314 	p_src = (con & CLK_UART_SRC_SEL_MASK) >> CLK_UART_SRC_SEL_SHIFT;
1315 	if (p_src == CLK_UART_SRC_SEL_GPLL)
1316 		p_rate = priv->gpll_hz;
1317 	else
1318 		p_rate = priv->cpll_hz;
1319 
1320 	if (src == CLK_UART_SEL_SRC) {
1321 		return DIV_TO_RATE(p_rate, div);
1322 	} else if (src == CLK_UART_SEL_FRAC) {
1323 		fracdiv = readl(&cru->clksel_con[reg + 1]);
1324 		n = fracdiv & CLK_UART_FRAC_NUMERATOR_MASK;
1325 		n >>= CLK_UART_FRAC_NUMERATOR_SHIFT;
1326 		m = fracdiv & CLK_UART_FRAC_DENOMINATOR_MASK;
1327 		m >>= CLK_UART_FRAC_DENOMINATOR_SHIFT;
1328 		return DIV_TO_RATE(p_rate, div) * n / m;
1329 	} else {
1330 		return OSC_HZ;
1331 	}
1332 }
1333 
1334 static ulong rk3588_uart_set_rate(struct rk3588_clk_priv *priv,
1335 				  ulong clk_id, ulong rate)
1336 {
1337 	struct rk3588_cru *cru = priv->cru;
1338 	u32 reg, clk_src, uart_src, div;
1339 	unsigned long m = 0, n = 0, val;
1340 
1341 	if (priv->gpll_hz % rate == 0) {
1342 		clk_src = CLK_UART_SRC_SEL_GPLL;
1343 		uart_src = CLK_UART_SEL_SRC;
1344 		div = DIV_ROUND_UP(priv->gpll_hz, rate);
1345 	} else if (priv->cpll_hz % rate == 0) {
1346 		clk_src = CLK_UART_SRC_SEL_CPLL;
1347 		uart_src = CLK_UART_SEL_SRC;
1348 		div = DIV_ROUND_UP(priv->gpll_hz, rate);
1349 	} else if (rate == OSC_HZ) {
1350 		clk_src = CLK_UART_SRC_SEL_GPLL;
1351 		uart_src = CLK_UART_SEL_XIN24M;
1352 		div = 2;
1353 	} else {
1354 		clk_src = CLK_UART_SRC_SEL_GPLL;
1355 		uart_src = CLK_UART_SEL_FRAC;
1356 		div = 2;
1357 		rational_best_approximation(rate, priv->gpll_hz / div,
1358 					    GENMASK(16 - 1, 0),
1359 					    GENMASK(16 - 1, 0),
1360 					    &m, &n);
1361 	}
1362 
1363 	switch (clk_id) {
1364 	case SCLK_UART1:
1365 		reg = 41;
1366 		break;
1367 	case SCLK_UART2:
1368 		reg = 43;
1369 		break;
1370 	case SCLK_UART3:
1371 		reg = 45;
1372 		break;
1373 	case SCLK_UART4:
1374 		reg = 47;
1375 		break;
1376 	case SCLK_UART5:
1377 		reg = 49;
1378 		break;
1379 	case SCLK_UART6:
1380 		reg = 51;
1381 		break;
1382 	case SCLK_UART7:
1383 		reg = 53;
1384 		break;
1385 	case SCLK_UART8:
1386 		reg = 55;
1387 		break;
1388 	case SCLK_UART9:
1389 		reg = 57;
1390 		break;
1391 	default:
1392 		return -ENOENT;
1393 	}
1394 	rk_clrsetreg(&cru->clksel_con[reg],
1395 		     CLK_UART_SRC_SEL_MASK |
1396 		     CLK_UART_SRC_DIV_MASK,
1397 		     (clk_src << CLK_UART_SRC_SEL_SHIFT) |
1398 		     ((div - 1) << CLK_UART_SRC_DIV_SHIFT));
1399 	rk_clrsetreg(&cru->clksel_con[reg + 2],
1400 		     CLK_UART_SEL_MASK,
1401 		     (uart_src << CLK_UART_SEL_SHIFT));
1402 	if (m && n) {
1403 		val = m << CLK_UART_FRAC_NUMERATOR_SHIFT | n;
1404 		writel(val, &cru->clksel_con[reg + 1]);
1405 	}
1406 
1407 	return rk3588_uart_get_rate(priv, clk_id);
1408 }
1409 
1410 static ulong rk3588_pciephy_get_rate(struct rk3588_clk_priv *priv, ulong clk_id)
1411 {
1412 	struct rk3588_cru *cru = priv->cru;
1413 	u32 con, div, src;
1414 
1415 	switch (clk_id) {
1416 	case CLK_REF_PIPE_PHY0:
1417 		con = readl(&cru->clksel_con[177]);
1418 		src = (con & CLK_PCIE_PHY0_REF_SEL_MASK) >> CLK_PCIE_PHY0_REF_SEL_SHIFT;
1419 		con = readl(&cru->clksel_con[176]);
1420 		div = (con & CLK_PCIE_PHY0_PLL_DIV_MASK) >> CLK_PCIE_PHY0_PLL_DIV_SHIFT;
1421 		break;
1422 	case CLK_REF_PIPE_PHY1:
1423 		con = readl(&cru->clksel_con[177]);
1424 		src = (con & CLK_PCIE_PHY1_REF_SEL_MASK) >> CLK_PCIE_PHY1_REF_SEL_SHIFT;
1425 		con = readl(&cru->clksel_con[176]);
1426 		div = (con & CLK_PCIE_PHY1_PLL_DIV_MASK) >> CLK_PCIE_PHY1_PLL_DIV_SHIFT;
1427 		break;
1428 	case CLK_REF_PIPE_PHY2:
1429 		con = readl(&cru->clksel_con[177]);
1430 		src = (con & CLK_PCIE_PHY2_REF_SEL_MASK) >> CLK_PCIE_PHY2_REF_SEL_SHIFT;
1431 		div = (con & CLK_PCIE_PHY2_PLL_DIV_MASK) >> CLK_PCIE_PHY2_PLL_DIV_SHIFT;
1432 		break;
1433 	default:
1434 		return -ENOENT;
1435 	}
1436 
1437 	if (src == CLK_PCIE_PHY_REF_SEL_PPLL) {
1438 		return DIV_TO_RATE(priv->ppll_hz, div);
1439 	} else {
1440 		return OSC_HZ;
1441 	}
1442 }
1443 
1444 static ulong rk3588_pciephy_set_rate(struct rk3588_clk_priv *priv,
1445 				  ulong clk_id, ulong rate)
1446 {
1447 	struct rk3588_cru *cru = priv->cru;
1448 	u32 clk_src, div;
1449 
1450 	if (rate == OSC_HZ) {
1451 		clk_src = CLK_PCIE_PHY_REF_SEL_24M;
1452 		div = 1;
1453 	} else {
1454 		clk_src = CLK_PCIE_PHY_REF_SEL_PPLL;
1455 		div = DIV_ROUND_UP(priv->ppll_hz, rate);
1456 	}
1457 
1458 	switch (clk_id) {
1459 	case CLK_REF_PIPE_PHY0:
1460 		rk_clrsetreg(&cru->clksel_con[177],
1461 		     CLK_PCIE_PHY0_REF_SEL_MASK,
1462 		     (clk_src << CLK_PCIE_PHY0_REF_SEL_SHIFT));
1463 		rk_clrsetreg(&cru->clksel_con[176],
1464 		     CLK_PCIE_PHY0_PLL_DIV_MASK,
1465 		     ((div - 1) << CLK_PCIE_PHY0_PLL_DIV_SHIFT));
1466 		break;
1467 	case CLK_REF_PIPE_PHY1:
1468 		rk_clrsetreg(&cru->clksel_con[177],
1469 		     CLK_PCIE_PHY1_REF_SEL_MASK,
1470 		     (clk_src << CLK_PCIE_PHY1_REF_SEL_SHIFT));
1471 		rk_clrsetreg(&cru->clksel_con[176],
1472 		     CLK_PCIE_PHY1_PLL_DIV_MASK,
1473 		     ((div - 1) << CLK_PCIE_PHY1_PLL_DIV_SHIFT));
1474 		break;
1475 	case CLK_REF_PIPE_PHY2:
1476 		rk_clrsetreg(&cru->clksel_con[177],
1477 		     CLK_PCIE_PHY2_REF_SEL_MASK |
1478 		     CLK_PCIE_PHY2_PLL_DIV_MASK,
1479 		     (clk_src << CLK_PCIE_PHY2_REF_SEL_SHIFT) |
1480 		     ((div - 1) << CLK_PCIE_PHY2_PLL_DIV_SHIFT));
1481 		break;
1482 	default:
1483 		return -ENOENT;
1484 	}
1485 
1486 	return rk3588_pciephy_get_rate(priv, clk_id);
1487 }
1488 #endif
1489 
1490 static ulong rk3588_clk_get_rate(struct clk *clk)
1491 {
1492 	struct rk3588_clk_priv *priv = dev_get_priv(clk->dev);
1493 	ulong rate = 0;
1494 
1495 	if (!priv->gpll_hz) {
1496 		printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
1497 		return -ENOENT;
1498 	}
1499 
1500 	if (!priv->ppll_hz) {
1501 		priv->ppll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[PPLL],
1502 						      priv->cru, PPLL);
1503 	}
1504 
1505 	switch (clk->id) {
1506 	case PLL_LPLL:
1507 		rate = rockchip_pll_get_rate(&rk3588_pll_clks[LPLL], priv->cru,
1508 					     LPLL);
1509 		break;
1510 	case PLL_B0PLL:
1511 		rate = rockchip_pll_get_rate(&rk3588_pll_clks[B0PLL], priv->cru,
1512 					     B0PLL);
1513 		break;
1514 	case PLL_B1PLL:
1515 		rate = rockchip_pll_get_rate(&rk3588_pll_clks[B1PLL], priv->cru,
1516 					     B1PLL);
1517 		break;
1518 	case PLL_GPLL:
1519 		rate = rockchip_pll_get_rate(&rk3588_pll_clks[GPLL], priv->cru,
1520 					     GPLL);
1521 		break;
1522 	case PLL_CPLL:
1523 		rate = rockchip_pll_get_rate(&rk3588_pll_clks[CPLL], priv->cru,
1524 					     CPLL);
1525 		break;
1526 	case PLL_NPLL:
1527 		rate = rockchip_pll_get_rate(&rk3588_pll_clks[NPLL], priv->cru,
1528 					     NPLL);
1529 		break;
1530 	case PLL_V0PLL:
1531 		rate = rockchip_pll_get_rate(&rk3588_pll_clks[V0PLL], priv->cru,
1532 					     V0PLL);
1533 		break;
1534 	case PLL_AUPLL:
1535 		rate = rockchip_pll_get_rate(&rk3588_pll_clks[AUPLL], priv->cru,
1536 					     AUPLL);
1537 		break;
1538 	case PLL_PPLL:
1539 		rate = rockchip_pll_get_rate(&rk3588_pll_clks[PPLL], priv->cru,
1540 					     PPLL);
1541 		break;
1542 	case ACLK_CENTER_ROOT:
1543 	case PCLK_CENTER_ROOT:
1544 	case HCLK_CENTER_ROOT:
1545 	case ACLK_CENTER_LOW_ROOT:
1546 		rate = rk3588_center_get_clk(priv, clk->id);
1547 		break;
1548 	case ACLK_TOP_ROOT:
1549 	case PCLK_TOP_ROOT:
1550 	case ACLK_LOW_TOP_ROOT:
1551 		rate = rk3588_top_get_clk(priv, clk->id);
1552 		break;
1553 	case CLK_I2C0:
1554 	case CLK_I2C1:
1555 	case CLK_I2C2:
1556 	case CLK_I2C3:
1557 	case CLK_I2C4:
1558 	case CLK_I2C5:
1559 	case CLK_I2C6:
1560 	case CLK_I2C7:
1561 	case CLK_I2C8:
1562 		rate = rk3588_i2c_get_clk(priv, clk->id);
1563 		break;
1564 	case CLK_SPI0:
1565 	case CLK_SPI1:
1566 	case CLK_SPI2:
1567 	case CLK_SPI3:
1568 	case CLK_SPI4:
1569 		rate = rk3588_spi_get_clk(priv, clk->id);
1570 		break;
1571 	case CLK_PWM1:
1572 	case CLK_PWM2:
1573 	case CLK_PWM3:
1574 	case CLK_PMU1PWM:
1575 		rate = rk3588_pwm_get_clk(priv, clk->id);
1576 		break;
1577 	case CLK_SARADC:
1578 	case CLK_TSADC:
1579 		rate = rk3588_adc_get_clk(priv, clk->id);
1580 		break;
1581 	case CCLK_SRC_SDIO:
1582 	case CCLK_EMMC:
1583 	case BCLK_EMMC:
1584 	case SCLK_SFC:
1585 	case DCLK_DECOM:
1586 		rate = rk3588_mmc_get_clk(priv, clk->id);
1587 		break;
1588 	case TCLK_WDT0:
1589 		rate = OSC_HZ;
1590 		break;
1591 #ifndef CONFIG_SPL_BUILD
1592 	case CLK_AUX16M_0:
1593 	case CLK_AUX16M_1:
1594 		rk3588_aux16m_get_clk(priv, clk->id);
1595 		break;
1596 	case ACLK_VOP_ROOT:
1597 	case ACLK_VOP:
1598 	case ACLK_VOP_LOW_ROOT:
1599 	case HCLK_VOP_ROOT:
1600 		rate = rk3588_aclk_vop_get_clk(priv, clk->id);
1601 		break;
1602 	case DCLK_VOP0:
1603 	case DCLK_VOP0_SRC:
1604 	case DCLK_VOP1:
1605 	case DCLK_VOP1_SRC:
1606 	case DCLK_VOP2:
1607 	case DCLK_VOP2_SRC:
1608 	case DCLK_VOP3:
1609 		rate = rk3588_dclk_vop_get_clk(priv, clk->id);
1610 		break;
1611 	case CLK_GMAC0_PTP_REF:
1612 	case CLK_GMAC1_PTP_REF:
1613 	case CLK_GMAC_125M:
1614 	case CLK_GMAC_50M:
1615 		rate = rk3588_gmac_get_clk(priv, clk->id);
1616 		break;
1617 	case SCLK_UART1:
1618 	case SCLK_UART2:
1619 	case SCLK_UART3:
1620 	case SCLK_UART4:
1621 	case SCLK_UART5:
1622 	case SCLK_UART6:
1623 	case SCLK_UART7:
1624 	case SCLK_UART8:
1625 	case SCLK_UART9:
1626 		rate = rk3588_uart_get_rate(priv, clk->id);
1627 		break;
1628 	case CLK_REF_PIPE_PHY0:
1629 	case CLK_REF_PIPE_PHY1:
1630 	case CLK_REF_PIPE_PHY2:
1631 		rate = rk3588_pciephy_get_rate(priv, clk->id);
1632 		break;
1633 #endif
1634 	default:
1635 		return -ENOENT;
1636 	}
1637 
1638 	return rate;
1639 };
1640 
1641 static ulong rk3588_clk_set_rate(struct clk *clk, ulong rate)
1642 {
1643 	struct rk3588_clk_priv *priv = dev_get_priv(clk->dev);
1644 	ulong ret = 0;
1645 
1646 	if (!priv->gpll_hz) {
1647 		printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
1648 		return -ENOENT;
1649 	}
1650 
1651 	if (!priv->ppll_hz) {
1652 		priv->ppll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[PPLL],
1653 						      priv->cru, PPLL);
1654 	}
1655 
1656 	switch (clk->id) {
1657 	case PLL_CPLL:
1658 		ret = rockchip_pll_set_rate(&rk3588_pll_clks[CPLL], priv->cru,
1659 					    CPLL, rate);
1660 		priv->cpll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[CPLL],
1661 						      priv->cru, CPLL);
1662 		break;
1663 	case PLL_GPLL:
1664 		ret = rockchip_pll_set_rate(&rk3588_pll_clks[GPLL], priv->cru,
1665 					    GPLL, rate);
1666 		priv->gpll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[GPLL],
1667 						      priv->cru, GPLL);
1668 		break;
1669 	case PLL_NPLL:
1670 		ret = rockchip_pll_set_rate(&rk3588_pll_clks[NPLL], priv->cru,
1671 					    NPLL, rate);
1672 		break;
1673 	case PLL_V0PLL:
1674 		ret = rockchip_pll_set_rate(&rk3588_pll_clks[V0PLL], priv->cru,
1675 					    V0PLL, rate);
1676 		priv->v0pll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[V0PLL],
1677 						       priv->cru, V0PLL);
1678 		break;
1679 	case PLL_AUPLL:
1680 		ret = rockchip_pll_set_rate(&rk3588_pll_clks[AUPLL], priv->cru,
1681 					    AUPLL, rate);
1682 		priv->aupll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[AUPLL],
1683 						       priv->cru, AUPLL);
1684 		break;
1685 	case PLL_PPLL:
1686 		ret = rockchip_pll_set_rate(&rk3588_pll_clks[PPLL], priv->cru,
1687 					    PPLL, rate);
1688 		priv->ppll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[PPLL],
1689 						      priv->cru, PPLL);
1690 		break;
1691 	case ACLK_CENTER_ROOT:
1692 	case PCLK_CENTER_ROOT:
1693 	case HCLK_CENTER_ROOT:
1694 	case ACLK_CENTER_LOW_ROOT:
1695 		ret = rk3588_center_set_clk(priv, clk->id, rate);
1696 		break;
1697 	case ACLK_TOP_ROOT:
1698 	case PCLK_TOP_ROOT:
1699 	case ACLK_LOW_TOP_ROOT:
1700 		ret = rk3588_top_set_clk(priv, clk->id, rate);
1701 		break;
1702 	case CLK_I2C0:
1703 	case CLK_I2C1:
1704 	case CLK_I2C2:
1705 	case CLK_I2C3:
1706 	case CLK_I2C4:
1707 	case CLK_I2C5:
1708 	case CLK_I2C6:
1709 	case CLK_I2C7:
1710 	case CLK_I2C8:
1711 		ret = rk3588_i2c_set_clk(priv, clk->id, rate);
1712 		break;
1713 	case CLK_SPI0:
1714 	case CLK_SPI1:
1715 	case CLK_SPI2:
1716 	case CLK_SPI3:
1717 	case CLK_SPI4:
1718 		ret = rk3588_spi_set_clk(priv, clk->id, rate);
1719 		break;
1720 	case CLK_PWM1:
1721 	case CLK_PWM2:
1722 	case CLK_PWM3:
1723 	case CLK_PMU1PWM:
1724 		ret = rk3588_pwm_set_clk(priv, clk->id, rate);
1725 		break;
1726 	case CLK_SARADC:
1727 	case CLK_TSADC:
1728 		ret = rk3588_adc_set_clk(priv, clk->id, rate);
1729 		break;
1730 	case CCLK_SRC_SDIO:
1731 	case CCLK_EMMC:
1732 	case BCLK_EMMC:
1733 	case SCLK_SFC:
1734 	case DCLK_DECOM:
1735 		ret = rk3588_mmc_set_clk(priv, clk->id, rate);
1736 		break;
1737 	case TCLK_WDT0:
1738 		ret = OSC_HZ;
1739 		break;
1740 #ifndef CONFIG_SPL_BUILD
1741 	case CLK_AUX16M_0:
1742 	case CLK_AUX16M_1:
1743 		rk3588_aux16m_set_clk(priv, clk->id, rate);
1744 		break;
1745 	case ACLK_VOP_ROOT:
1746 	case ACLK_VOP:
1747 	case ACLK_VOP_LOW_ROOT:
1748 	case HCLK_VOP_ROOT:
1749 		ret = rk3588_aclk_vop_set_clk(priv, clk->id, rate);
1750 		break;
1751 	case DCLK_VOP0:
1752 	case DCLK_VOP0_SRC:
1753 	case DCLK_VOP1:
1754 	case DCLK_VOP1_SRC:
1755 	case DCLK_VOP2:
1756 	case DCLK_VOP2_SRC:
1757 	case DCLK_VOP3:
1758 		ret = rk3588_dclk_vop_set_clk(priv, clk->id, rate);
1759 		break;
1760 	case CLK_GMAC0_PTP_REF:
1761 	case CLK_GMAC1_PTP_REF:
1762 	case CLK_GMAC_125M:
1763 	case CLK_GMAC_50M:
1764 		ret = rk3588_gmac_set_clk(priv, clk->id, rate);
1765 		break;
1766 	case SCLK_UART1:
1767 	case SCLK_UART2:
1768 	case SCLK_UART3:
1769 	case SCLK_UART4:
1770 	case SCLK_UART5:
1771 	case SCLK_UART6:
1772 	case SCLK_UART7:
1773 	case SCLK_UART8:
1774 	case SCLK_UART9:
1775 		ret = rk3588_uart_set_rate(priv, clk->id, rate);
1776 		break;
1777 	case CLK_REF_PIPE_PHY0:
1778 	case CLK_REF_PIPE_PHY1:
1779 	case CLK_REF_PIPE_PHY2:
1780 		ret = rk3588_pciephy_set_rate(priv, clk->id, rate);
1781 		break;
1782 #endif
1783 	default:
1784 		return -ENOENT;
1785 	}
1786 
1787 	return ret;
1788 };
1789 
1790 #define ROCKCHIP_MMC_DELAY_SEL		BIT(10)
1791 #define ROCKCHIP_MMC_DEGREE_MASK	0x3
1792 #define ROCKCHIP_MMC_DELAYNUM_OFFSET	2
1793 #define ROCKCHIP_MMC_DELAYNUM_MASK	(0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
1794 
1795 #define PSECS_PER_SEC 1000000000000LL
1796 /*
1797  * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to
1798  * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg.
1799  */
1800 #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60
1801 
1802 int rk3588_mmc_get_phase(struct clk *clk)
1803 {
1804 	struct rk3588_clk_priv *priv = dev_get_priv(clk->dev);
1805 	struct rk3588_cru *cru = priv->cru;
1806 	u32 raw_value, delay_num;
1807 	u16 degrees = 0;
1808 	ulong rate;
1809 
1810 	rate = rk3588_clk_get_rate(clk);
1811 	if (rate < 0)
1812 		return rate;
1813 
1814 	if (clk->id == SCLK_SDMMC_SAMPLE)
1815 		raw_value = readl(&cru->sdmmc_con[1]);
1816 	else
1817 		return 0;
1818 
1819 	raw_value >>= 1;
1820 	degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90;
1821 
1822 	if (raw_value & ROCKCHIP_MMC_DELAY_SEL) {
1823 		/* degrees/delaynum * 10000 */
1824 		unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) *
1825 					36 * (rate / 1000000);
1826 
1827 		delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK);
1828 		delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET;
1829 		degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000);
1830 	}
1831 
1832 	return degrees % 360;
1833 }
1834 
1835 int rk3588_mmc_set_phase(struct clk *clk, u32 degrees)
1836 {
1837 	struct rk3588_clk_priv *priv = dev_get_priv(clk->dev);
1838 	struct rk3588_cru *cru = priv->cru;
1839 	u8 nineties, remainder, delay_num;
1840 	u32 raw_value, delay;
1841 	ulong rate;
1842 
1843 	rate = rk3588_clk_get_rate(clk);
1844 	if (rate < 0)
1845 		return rate;
1846 
1847 	nineties = degrees / 90;
1848 	remainder = (degrees % 90);
1849 
1850 	/*
1851 	 * Convert to delay; do a little extra work to make sure we
1852 	 * don't overflow 32-bit / 64-bit numbers.
1853 	 */
1854 	delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */
1855 	delay *= remainder;
1856 	delay = DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 *
1857 				  (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10));
1858 
1859 	delay_num = (u8)min_t(u32, delay, 255);
1860 
1861 	raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0;
1862 	raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET;
1863 	raw_value |= nineties;
1864 
1865 	raw_value <<= 1;
1866 	if (clk->id == SCLK_SDMMC_SAMPLE)
1867 		writel(raw_value | 0xffff0000, &cru->sdmmc_con[1]);
1868 
1869 	debug("mmc set_phase(%d) delay_nums=%u reg=%#x actual_degrees=%d\n",
1870 	      degrees, delay_num, raw_value, rk3588_mmc_get_phase(clk));
1871 
1872 	return 0;
1873 }
1874 
1875 static int rk3588_clk_get_phase(struct clk *clk)
1876 {
1877 	int ret;
1878 
1879 	debug("%s %ld\n", __func__, clk->id);
1880 	switch (clk->id) {
1881 	case SCLK_SDMMC_SAMPLE:
1882 		ret = rk3588_mmc_get_phase(clk);
1883 		break;
1884 	default:
1885 		return -ENOENT;
1886 	}
1887 
1888 	return ret;
1889 }
1890 
1891 static int rk3588_clk_set_phase(struct clk *clk, int degrees)
1892 {
1893 	int ret;
1894 
1895 	debug("%s %ld\n", __func__, clk->id);
1896 	switch (clk->id) {
1897 	case SCLK_SDMMC_SAMPLE:
1898 		ret = rk3588_mmc_set_phase(clk, degrees);
1899 		break;
1900 	default:
1901 		return -ENOENT;
1902 	}
1903 
1904 	return ret;
1905 }
1906 
1907 #if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA))
1908 static int __maybe_unused rk3588_dclk_vop_set_parent(struct clk *clk,
1909 						     struct clk *parent)
1910 {
1911 	struct rk3588_clk_priv *priv = dev_get_priv(clk->dev);
1912 	struct rk3588_cru *cru = priv->cru;
1913 	u32 sel;
1914 	const char *clock_dev_name = parent->dev->name;
1915 
1916 	if (parent->id == PLL_V0PLL)
1917 		sel = 2;
1918 	else if (parent->id == PLL_GPLL)
1919 		sel = 0;
1920 	else if (parent->id == PLL_CPLL)
1921 		sel = 1;
1922 	else
1923 		sel = 3;
1924 
1925 	switch (clk->id) {
1926 	case DCLK_VOP0_SRC:
1927 		rk_clrsetreg(&cru->clksel_con[111], DCLK0_VOP_SRC_SEL_MASK,
1928 			     sel << DCLK0_VOP_SRC_SEL_SHIFT);
1929 		break;
1930 	case DCLK_VOP1_SRC:
1931 		rk_clrsetreg(&cru->clksel_con[111], DCLK1_VOP_SRC_SEL_MASK,
1932 			     sel << DCLK1_VOP_SRC_SEL_SHIFT);
1933 		break;
1934 	case DCLK_VOP2_SRC:
1935 		rk_clrsetreg(&cru->clksel_con[112], DCLK2_VOP_SRC_SEL_MASK,
1936 			     sel << DCLK2_VOP_SRC_SEL_SHIFT);
1937 		break;
1938 	case DCLK_VOP3:
1939 		rk_clrsetreg(&cru->clksel_con[113], DCLK3_VOP_SRC_SEL_MASK,
1940 			     sel << DCLK3_VOP_SRC_SEL_SHIFT);
1941 		break;
1942 	case DCLK_VOP0:
1943 		if (!strcmp(clock_dev_name, "hdmiphypll_clk0"))
1944 			sel = 1;
1945 		else if (!strcmp(clock_dev_name, "hdmiphypll_clk1"))
1946 			sel = 2;
1947 		else
1948 			sel = 0;
1949 		rk_clrsetreg(&cru->clksel_con[112], DCLK0_VOP_SEL_MASK,
1950 			     sel << DCLK0_VOP_SEL_SHIFT);
1951 		break;
1952 	case DCLK_VOP1:
1953 		if (!strcmp(clock_dev_name, "hdmiphypll_clk0"))
1954 			sel = 1;
1955 		else if (!strcmp(clock_dev_name, "hdmiphypll_clk1"))
1956 			sel = 2;
1957 		else
1958 			sel = 0;
1959 		rk_clrsetreg(&cru->clksel_con[112], DCLK1_VOP_SEL_MASK,
1960 			     sel << DCLK1_VOP_SEL_SHIFT);
1961 		break;
1962 	case DCLK_VOP2:
1963 		if (!strcmp(clock_dev_name, "hdmiphypll_clk0"))
1964 			sel = 1;
1965 		else if (!strcmp(clock_dev_name, "hdmiphypll_clk1"))
1966 			sel = 2;
1967 		else
1968 			sel = 0;
1969 		rk_clrsetreg(&cru->clksel_con[112], DCLK2_VOP_SEL_MASK,
1970 			     sel << DCLK2_VOP_SEL_SHIFT);
1971 		break;
1972 	default:
1973 		return -EINVAL;
1974 	}
1975 	return 0;
1976 }
1977 
1978 static int rk3588_clk_set_parent(struct clk *clk, struct clk *parent)
1979 {
1980 	switch (clk->id) {
1981 	case DCLK_VOP0_SRC:
1982 	case DCLK_VOP1_SRC:
1983 	case DCLK_VOP2_SRC:
1984 	case DCLK_VOP0:
1985 	case DCLK_VOP1:
1986 	case DCLK_VOP2:
1987 	case DCLK_VOP3:
1988 		return rk3588_dclk_vop_set_parent(clk, parent);
1989 	default:
1990 		return -ENOENT;
1991 	}
1992 
1993 	return 0;
1994 }
1995 #endif
1996 
1997 static struct clk_ops rk3588_clk_ops = {
1998 	.get_rate = rk3588_clk_get_rate,
1999 	.set_rate = rk3588_clk_set_rate,
2000 	.get_phase = rk3588_clk_get_phase,
2001 	.set_phase = rk3588_clk_set_phase,
2002 #if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA))
2003 	.set_parent = rk3588_clk_set_parent,
2004 #endif
2005 };
2006 
2007 static void rk3588_clk_init(struct rk3588_clk_priv *priv)
2008 {
2009 	int ret, div;
2010 
2011 	div = DIV_ROUND_UP(GPLL_HZ, 300 * MHz);
2012 	rk_clrsetreg(&priv->cru->clksel_con[38],
2013 		     ACLK_BUS_ROOT_SEL_MASK |
2014 		     ACLK_BUS_ROOT_DIV_MASK,
2015 		     div << ACLK_BUS_ROOT_DIV_SHIFT);
2016 
2017 	if (priv->cpll_hz != CPLL_HZ) {
2018 		ret = rockchip_pll_set_rate(&rk3588_pll_clks[CPLL], priv->cru,
2019 					    CPLL, CPLL_HZ);
2020 		if (!ret)
2021 			priv->cpll_hz = CPLL_HZ;
2022 	}
2023 	if (priv->gpll_hz != GPLL_HZ) {
2024 		ret = rockchip_pll_set_rate(&rk3588_pll_clks[GPLL], priv->cru,
2025 					    GPLL, GPLL_HZ);
2026 		if (!ret)
2027 			priv->gpll_hz = GPLL_HZ;
2028 	}
2029 
2030 #ifdef CONFIG_PCI
2031 	if (priv->ppll_hz != PPLL_HZ) {
2032 		ret = rockchip_pll_set_rate(&rk3588_pll_clks[PPLL], priv->cru,
2033 					    PPLL, PPLL_HZ);
2034 		priv->ppll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[PPLL],
2035 						      priv->cru, PPLL);
2036 	}
2037 #endif
2038 	rk_clrsetreg(&priv->cru->clksel_con[9],
2039 		     ACLK_TOP_S400_SEL_MASK |
2040 		     ACLK_TOP_S200_SEL_MASK,
2041 		     (ACLK_TOP_S400_SEL_400M << ACLK_TOP_S400_SEL_SHIFT) |
2042 		     (ACLK_TOP_S200_SEL_200M << ACLK_TOP_S200_SEL_SHIFT));
2043 }
2044 
2045 static int rk3588_clk_probe(struct udevice *dev)
2046 {
2047 	struct rk3588_clk_priv *priv = dev_get_priv(dev);
2048 	int ret;
2049 	struct clk clk;
2050 
2051 	priv->sync_kernel = false;
2052 
2053 #ifdef CONFIG_SPL_BUILD
2054 	rockchip_pll_set_rate(&rk3588_pll_clks[B0PLL], priv->cru,
2055 			      B0PLL, LPLL_HZ);
2056 	rockchip_pll_set_rate(&rk3588_pll_clks[B1PLL], priv->cru,
2057 			      B1PLL, LPLL_HZ);
2058 	if (!priv->armclk_enter_hz) {
2059 		ret = rockchip_pll_set_rate(&rk3588_pll_clks[LPLL], priv->cru,
2060 					    LPLL, LPLL_HZ);
2061 		priv->armclk_enter_hz =
2062 			rockchip_pll_get_rate(&rk3588_pll_clks[LPLL],
2063 					      priv->cru, LPLL);
2064 		priv->armclk_init_hz = priv->armclk_enter_hz;
2065 	}
2066 #endif
2067 
2068 	ret = rockchip_get_scmi_clk(&clk.dev);
2069 	if (ret) {
2070 		printf("Failed to get scmi clk dev\n");
2071 		return ret;
2072 	}
2073 	clk.id = SCMI_SPLL;
2074 	ret = clk_set_rate(&clk, 702000000);
2075 	if (ret < 0) {
2076 		printf("Failed to set spll\n");
2077 	}
2078 
2079 #ifndef CONFIG_SPL_BUILD
2080 	if (!priv->armclk_enter_hz) {
2081 		clk.id = SCMI_CLK_CPUL;
2082 		ret = clk_set_rate(&clk, CPU_PVTPLL_HZ);
2083 		if (ret < 0) {
2084 			printf("Failed to set cpubl\n");
2085 		} else {
2086 			priv->armclk_enter_hz = CPU_PVTPLL_HZ;
2087 			priv->armclk_init_hz = CPU_PVTPLL_HZ;
2088 		}
2089 	}
2090 	clk.id = SCMI_CLK_CPUB01;
2091 	ret = clk_set_rate(&clk, CPU_PVTPLL_HZ);
2092 	if (ret < 0)
2093 		printf("Failed to set cpub01\n");
2094 	clk.id = SCMI_CLK_CPUB23;
2095 	ret = clk_set_rate(&clk, CPU_PVTPLL_HZ);
2096 	if (ret < 0)
2097 		printf("Failed to set cpub23\n");
2098 #endif
2099 
2100 	priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
2101 	if (IS_ERR(priv->grf))
2102 		return PTR_ERR(priv->grf);
2103 
2104 	rk3588_clk_init(priv);
2105 
2106 	/* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
2107 	ret = clk_set_defaults(dev);
2108 	if (ret)
2109 		debug("%s clk_set_defaults failed %d\n", __func__, ret);
2110 	else
2111 		priv->sync_kernel = true;
2112 
2113 	return 0;
2114 }
2115 
2116 static int rk3588_clk_ofdata_to_platdata(struct udevice *dev)
2117 {
2118 	struct rk3588_clk_priv *priv = dev_get_priv(dev);
2119 
2120 	priv->cru = dev_read_addr_ptr(dev);
2121 
2122 	return 0;
2123 }
2124 
2125 static int rk3588_clk_bind(struct udevice *dev)
2126 {
2127 	int ret;
2128 	struct udevice *sys_child, *sf_child;
2129 	struct sysreset_reg *priv;
2130 	struct softreset_reg *sf_priv;
2131 
2132 	/* The reset driver does not have a device node, so bind it here */
2133 	ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
2134 				 &sys_child);
2135 	if (ret) {
2136 		debug("Warning: No sysreset driver: ret=%d\n", ret);
2137 	} else {
2138 		priv = malloc(sizeof(struct sysreset_reg));
2139 		priv->glb_srst_fst_value = offsetof(struct rk3588_cru,
2140 						    glb_srst_fst);
2141 		priv->glb_srst_snd_value = offsetof(struct rk3588_cru,
2142 						    glb_srsr_snd);
2143 		sys_child->priv = priv;
2144 	}
2145 
2146 	ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset",
2147 					 dev_ofnode(dev), &sf_child);
2148 	if (ret) {
2149 		debug("Warning: No rockchip reset driver: ret=%d\n", ret);
2150 	} else {
2151 		sf_priv = malloc(sizeof(struct softreset_reg));
2152 		sf_priv->sf_reset_offset = offsetof(struct rk3588_cru,
2153 						    softrst_con[0]);
2154 		sf_priv->sf_reset_num = 49158;
2155 		sf_child->priv = sf_priv;
2156 	}
2157 
2158 	return 0;
2159 }
2160 
2161 static const struct udevice_id rk3588_clk_ids[] = {
2162 	{ .compatible = "rockchip,rk3588-cru" },
2163 	{ }
2164 };
2165 
2166 U_BOOT_DRIVER(rockchip_rk3588_cru) = {
2167 	.name		= "rockchip_rk3588_cru",
2168 	.id		= UCLASS_CLK,
2169 	.of_match	= rk3588_clk_ids,
2170 	.priv_auto_alloc_size = sizeof(struct rk3588_clk_priv),
2171 	.ofdata_to_platdata = rk3588_clk_ofdata_to_platdata,
2172 	.ops		= &rk3588_clk_ops,
2173 	.bind		= rk3588_clk_bind,
2174 	.probe		= rk3588_clk_probe,
2175 };
2176 
2177 #ifdef CONFIG_SPL_BUILD
2178 #define SCRU_BASE			0xfd7d0000
2179 #define BUSSCRU_BASE			0xfd7d8000
2180 #define GPLL_RATE			1188000000
2181 #define SPLL_RATE			702000000
2182 
2183 #ifndef BITS_WITH_WMASK
2184 #define BITS_WITH_WMASK(bits, msk, shift) \
2185 	((bits) << (shift)) | ((msk) << ((shift) + 16))
2186 #endif
2187 
2188 #define CLKDIV_6BITS_SHF(div, shift)	BITS_WITH_WMASK(div, 0x3fU, shift)
2189 #define CLKDIV_5BITS_SHF(div, shift)	BITS_WITH_WMASK(div, 0x1fU, shift)
2190 
2191 static ulong rk3588_clk_scmi_get_rate(struct clk *clk)
2192 {
2193 	u32 src, div;
2194 
2195 	switch (clk->id) {
2196 	case SCMI_SPLL:
2197 		src = readl(BUSSCRU_BASE + RK3588_MODE_CON0) & 0x3;
2198 		if (src == 0)
2199 			return OSC_HZ;
2200 		else if (src == 1)
2201 			return 702 * MHz;
2202 		else
2203 			return 32768;
2204 	case SCMI_CCLK_SD:
2205 		src = readl(SCRU_BASE + RK3588_CLKSEL_CON(3)) & 0x3000;
2206 		src = src >> 12;
2207 		div = readl(SCRU_BASE + RK3588_CLKSEL_CON(3)) & 0x0fc0;
2208 		div = div >> 6;
2209 		if (src == 1)
2210 			return SPLL_RATE / (div + 1);
2211 		else if (src == 2)
2212 			return OSC_HZ / (div + 1);
2213 		else
2214 			return GPLL_RATE / (div + 1);
2215 	case SCMI_DCLK_SD:
2216 		src = readl(SCRU_BASE + RK3588_CLKSEL_CON(3)) & 0x0020;
2217 		div = readl(SCRU_BASE + RK3588_CLKSEL_CON(3)) & 0x001f;
2218 		if (src)
2219 			return SPLL_RATE / (div + 1);
2220 		else
2221 			return GPLL_RATE / (div + 1);
2222 	case SCMI_CRYPTO_RNG:
2223 		src = readl(SCRU_BASE + RK3588_CLKSEL_CON(1)) & 0xc000;
2224 		src = src >> 14;
2225 		if (src == 0)
2226 			return 175 * MHz;
2227 		else if (src == 1)
2228 			return 116 * MHz;
2229 		else if (src == 2)
2230 			return 58 * MHz;
2231 		else
2232 			return OSC_HZ;
2233 	case SCMI_CRYPTO_CORE:
2234 		src = readl(SCRU_BASE + RK3588_CLKSEL_CON(1)) & 0x0c00;
2235 		src = src >> 10;
2236 		if (src == 0)
2237 			return 350 * MHz;
2238 		else if (src == 1)
2239 			return 233 * MHz;
2240 		else if (src == 2)
2241 			return 116 * MHz;
2242 		else
2243 			return OSC_HZ;
2244 	case SCMI_CRYPTO_PKA:
2245 		src = readl(SCRU_BASE + RK3588_CLKSEL_CON(1)) & 0x3000;
2246 		src = src >> 12;
2247 		if (src == 0)
2248 			return 350 * MHz;
2249 		else if (src == 1)
2250 			return 233 * MHz;
2251 		else if (src == 2)
2252 			return 116 * MHz;
2253 		else
2254 			return OSC_HZ;
2255 	case SCMI_KEYLADDER_CORE:
2256 		src = readl(SCRU_BASE + RK3588_CLKSEL_CON(2)) & 0x00c0;
2257 		src = src >> 6;
2258 		if (src == 0)
2259 			return 350 * MHz;
2260 		else if (src == 1)
2261 			return 233 * MHz;
2262 		else if (src == 2)
2263 			return 116 * MHz;
2264 		else
2265 			return OSC_HZ;
2266 	case SCMI_KEYLADDER_RNG:
2267 		src = readl(SCRU_BASE + RK3588_CLKSEL_CON(2)) & 0x0300;
2268 		src = src >> 8;
2269 		if (src == 0)
2270 			return 175 * MHz;
2271 		else if (src == 1)
2272 			return 116 * MHz;
2273 		else if (src == 2)
2274 			return 58 * MHz;
2275 		else
2276 			return OSC_HZ;
2277 	case SCMI_TCLK_WDT:
2278 		return OSC_HZ;
2279 	case SCMI_HCLK_SD:
2280 	case SCMI_HCLK_SECURE_NS:
2281 		src = readl(SCRU_BASE + RK3588_CLKSEL_CON(1)) & 0x000c;
2282 		src = src >> 2;
2283 		if (src == 0)
2284 			return 150 * MHz;
2285 		else if (src == 1)
2286 			return 100 * MHz;
2287 		else if (src == 2)
2288 			return 50 * MHz;
2289 		else
2290 			return OSC_HZ;
2291 	default:
2292 		return -ENOENT;
2293 	}
2294 };
2295 
2296 static ulong rk3588_clk_scmi_set_rate(struct clk *clk, ulong rate)
2297 {
2298 	u32 src, div;
2299 
2300 	if ((readl(BUSSCRU_BASE + RK3588_PLL_CON(137)) & 0x01c0) == 0xc0) {
2301 		writel(BITS_WITH_WMASK(0, 0x3U, 0),
2302 			BUSSCRU_BASE + RK3588_MODE_CON0);
2303 		writel(BITS_WITH_WMASK(2, 0x7U, 6),
2304 			BUSSCRU_BASE + RK3588_PLL_CON(137));
2305 		writel(BITS_WITH_WMASK(1, 0x3U, 0),
2306 		       BUSSCRU_BASE + RK3588_MODE_CON0);
2307 	}
2308 
2309 	switch (clk->id) {
2310 	case SCMI_SPLL:
2311 		if (rate >= 700 * MHz)
2312 			src = 1;
2313 		else
2314 			src = 0;
2315 		writel(BITS_WITH_WMASK(0, 0x3U, 0),
2316 			BUSSCRU_BASE + RK3588_MODE_CON0);
2317 		writel(BITS_WITH_WMASK(2, 0x7U, 6),
2318 			BUSSCRU_BASE + RK3588_PLL_CON(137));
2319 		writel(BITS_WITH_WMASK(src, 0x3U, 0),
2320 		       BUSSCRU_BASE + RK3588_MODE_CON0);
2321 		break;
2322 	case SCMI_CCLK_SD:
2323 		if ((OSC_HZ % rate) == 0) {
2324 			div = DIV_ROUND_UP(OSC_HZ, rate);
2325 			writel(CLKDIV_6BITS_SHF(div - 1, 6) |
2326 			       BITS_WITH_WMASK(2U, 0x3U, 12),
2327 			       SCRU_BASE + RK3588_CLKSEL_CON(3));
2328 		} else if ((SPLL_RATE % rate) == 0) {
2329 			div = DIV_ROUND_UP(SPLL_RATE, rate);
2330 			writel(CLKDIV_6BITS_SHF(div - 1, 6) |
2331 			       BITS_WITH_WMASK(1U, 0x3U, 12),
2332 			       SCRU_BASE + RK3588_CLKSEL_CON(3));
2333 		} else {
2334 			div = DIV_ROUND_UP(GPLL_RATE, rate);
2335 			writel(CLKDIV_6BITS_SHF(div - 1, 6) |
2336 			       BITS_WITH_WMASK(0U, 0x3U, 12),
2337 			       SCRU_BASE + RK3588_CLKSEL_CON(3));
2338 		}
2339 		break;
2340 	case SCMI_DCLK_SD:
2341 		if ((SPLL_RATE % rate) == 0) {
2342 			div = DIV_ROUND_UP(SPLL_RATE, rate);
2343 			writel(CLKDIV_5BITS_SHF(div - 1, 0) |
2344 			       BITS_WITH_WMASK(1U, 0x1U, 5),
2345 			       SCRU_BASE + RK3588_CLKSEL_CON(3));
2346 		} else {
2347 			div = DIV_ROUND_UP(GPLL_RATE, rate);
2348 			writel(CLKDIV_5BITS_SHF(div - 1, 0) |
2349 			       BITS_WITH_WMASK(0U, 0x1U, 5),
2350 			       SCRU_BASE + RK3588_CLKSEL_CON(3));
2351 		}
2352 		break;
2353 	case SCMI_CRYPTO_RNG:
2354 		if (rate >= 175 * MHz)
2355 			src = 0;
2356 		else if (rate >= 116 * MHz)
2357 			src = 1;
2358 		else if (rate >= 58 * MHz)
2359 			src = 2;
2360 		else
2361 			src = 3;
2362 
2363 		writel(BITS_WITH_WMASK(src, 0x3U, 14),
2364 		       SCRU_BASE + RK3588_CLKSEL_CON(1));
2365 		break;
2366 	case SCMI_CRYPTO_CORE:
2367 		if (rate >= 350 * MHz)
2368 			src = 0;
2369 		else if (rate >= 233 * MHz)
2370 			src = 1;
2371 		else if (rate >= 116 * MHz)
2372 			src = 2;
2373 		else
2374 			src = 3;
2375 
2376 		writel(BITS_WITH_WMASK(src, 0x3U, 10),
2377 		       SCRU_BASE + RK3588_CLKSEL_CON(1));
2378 		break;
2379 	case SCMI_CRYPTO_PKA:
2380 		if (rate >= 350 * MHz)
2381 			src = 0;
2382 		else if (rate >= 233 * MHz)
2383 			src = 1;
2384 		else if (rate >= 116 * MHz)
2385 			src = 2;
2386 		else
2387 			src = 3;
2388 
2389 		writel(BITS_WITH_WMASK(src, 0x3U, 12),
2390 		       SCRU_BASE + RK3588_CLKSEL_CON(1));
2391 		break;
2392 	case SCMI_KEYLADDER_CORE:
2393 		if (rate >= 350 * MHz)
2394 			src = 0;
2395 		else if (rate >= 233 * MHz)
2396 			src = 1;
2397 		else if (rate >= 116 * MHz)
2398 			src = 2;
2399 		else
2400 			src = 3;
2401 
2402 		writel(BITS_WITH_WMASK(src, 0x3U, 6),
2403 		       SCRU_BASE + RK3588_CLKSEL_CON(2));
2404 		break;
2405 	case SCMI_KEYLADDER_RNG:
2406 		if (rate >= 175 * MHz)
2407 			src = 0;
2408 		else if (rate >= 116 * MHz)
2409 			src = 1;
2410 		else if (rate >= 58 * MHz)
2411 			src = 2;
2412 		else
2413 			src = 3;
2414 
2415 		writel(BITS_WITH_WMASK(src, 0x3U, 8),
2416 		       SCRU_BASE + RK3588_CLKSEL_CON(2));
2417 		break;
2418 	case SCMI_TCLK_WDT:
2419 		break;
2420 	case SCMI_HCLK_SD:
2421 	case SCMI_HCLK_SECURE_NS:
2422 		if (rate >= 150 * MHz)
2423 			src = 0;
2424 		else if (rate >= 100 * MHz)
2425 			src = 1;
2426 		else if (rate >= 50 * MHz)
2427 			src = 2;
2428 		else
2429 			src = 3;
2430 		writel(BITS_WITH_WMASK(src, 0x3U, 2),
2431 		       SCRU_BASE + RK3588_CLKSEL_CON(1));
2432 		break;
2433 	default:
2434 		return -ENOENT;
2435 	}
2436 	return 0;
2437 };
2438 
2439 /* A fake scmi driver for SPL/TPL where smccc agent is not available. */
2440 static const struct clk_ops scmi_clk_ops = {
2441 	.get_rate = rk3588_clk_scmi_get_rate,
2442 	.set_rate = rk3588_clk_scmi_set_rate,
2443 };
2444 
2445 U_BOOT_DRIVER(scmi_clock) = {
2446 	.name = "scmi_clk",
2447 	.id = UCLASS_CLK,
2448 	.ops = &scmi_clk_ops,
2449 };
2450 #endif
2451 
2452 #ifndef CONFIG_SPL_BUILD
2453 /**
2454  * soc_clk_dump() - Print clock frequencies
2455  * Returns zero on success
2456  *
2457  * Implementation for the clk dump command.
2458  */
2459 int soc_clk_dump(void)
2460 {
2461 	struct udevice *cru_dev;
2462 	struct rk3588_clk_priv *priv;
2463 	const struct rk3588_clk_info *clk_dump;
2464 	struct clk clk;
2465 	unsigned long clk_count = ARRAY_SIZE(clks_dump);
2466 	unsigned long rate;
2467 	int i, ret;
2468 
2469 	ret = uclass_get_device_by_driver(UCLASS_CLK,
2470 					  DM_GET_DRIVER(rockchip_rk3588_cru),
2471 					  &cru_dev);
2472 	if (ret) {
2473 		printf("%s failed to get cru device\n", __func__);
2474 		return ret;
2475 	}
2476 
2477 	priv = dev_get_priv(cru_dev);
2478 	printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n",
2479 	       priv->sync_kernel ? "sync kernel" : "uboot",
2480 	       priv->armclk_enter_hz / 1000,
2481 	       priv->armclk_init_hz / 1000,
2482 	       priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0,
2483 	       priv->set_armclk_rate ? " KHz" : "N/A");
2484 	for (i = 0; i < clk_count; i++) {
2485 		clk_dump = &clks_dump[i];
2486 		if (clk_dump->name) {
2487 			clk.id = clk_dump->id;
2488 			if (clk_dump->is_cru)
2489 				ret = clk_request(cru_dev, &clk);
2490 			if (ret < 0)
2491 				return ret;
2492 
2493 			rate = clk_get_rate(&clk);
2494 			clk_free(&clk);
2495 			if (i == 0) {
2496 				if (rate < 0)
2497 					printf("  %s %s\n", clk_dump->name,
2498 					       "unknown");
2499 				else
2500 					printf("  %s %lu KHz\n", clk_dump->name,
2501 					       rate / 1000);
2502 			} else {
2503 				if (rate < 0)
2504 					printf("  %s %s\n", clk_dump->name,
2505 					       "unknown");
2506 				else
2507 					printf("  %s %lu KHz\n", clk_dump->name,
2508 					       rate / 1000);
2509 			}
2510 		}
2511 	}
2512 
2513 	return 0;
2514 }
2515 #endif
2516