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