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