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