xref: /rk3399_rockchip-uboot/drivers/clk/rockchip/clk_rk3588.c (revision e12b5efd268e1005d4dd24711b7aeefc0edf34bb)
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_PWM1_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_aux16m_get_clk(struct rk3588_clk_priv *priv, ulong clk_id)
890 {
891 	struct rk3588_cru *cru = priv->cru;
892 	u32 div, con, parent;
893 
894 	parent = priv->gpll_hz;
895 	con = readl(&cru->clksel_con[117]);
896 
897 	switch (clk_id) {
898 	case CLK_AUX16M_0:
899 		div = (con & CLK_AUX16MHZ_0_DIV_MASK) >> CLK_AUX16MHZ_0_DIV_SHIFT;
900 		return DIV_TO_RATE(parent, div);
901 	case CLK_AUX16M_1:
902 		div = (con & CLK_AUX16MHZ_1_DIV_MASK) >> CLK_AUX16MHZ_1_DIV_SHIFT;
903 		return DIV_TO_RATE(parent, div);
904 	default:
905 		return -ENOENT;
906 	}
907 }
908 
909 static ulong rk3588_aux16m_set_clk(struct rk3588_clk_priv *priv,
910 				   ulong clk_id, ulong rate)
911 {
912 	struct rk3588_cru *cru = priv->cru;
913 	u32 div;
914 
915 	if (!priv->gpll_hz) {
916 		printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
917 		return -ENOENT;
918 	}
919 
920 	div = DIV_ROUND_UP(priv->gpll_hz, rate);
921 
922 	switch (clk_id) {
923 	case CLK_AUX16M_0:
924 		rk_clrsetreg(&cru->clksel_con[117], CLK_AUX16MHZ_0_DIV_MASK,
925 			     (div - 1) << CLK_AUX16MHZ_0_DIV_SHIFT);
926 		break;
927 	case CLK_AUX16M_1:
928 		rk_clrsetreg(&cru->clksel_con[117], CLK_AUX16MHZ_1_DIV_MASK,
929 			     (div - 1) << CLK_AUX16MHZ_1_DIV_SHIFT);
930 		break;
931 	default:
932 		return -ENOENT;
933 	}
934 
935 	return rk3588_aux16m_get_clk(priv, clk_id);
936 }
937 
938 static ulong rk3588_aclk_vop_get_clk(struct rk3588_clk_priv *priv, ulong clk_id)
939 {
940 	struct rk3588_cru *cru = priv->cru;
941 	u32 div, sel, con, parent;
942 
943 	switch (clk_id) {
944 	case ACLK_VOP_ROOT:
945 	case ACLK_VOP:
946 		con = readl(&cru->clksel_con[110]);
947 		div = (con & ACLK_VOP_ROOT_DIV_MASK) >> ACLK_VOP_ROOT_DIV_SHIFT;
948 		sel = (con & ACLK_VOP_ROOT_SEL_MASK) >> ACLK_VOP_ROOT_SEL_SHIFT;
949 		if (sel == ACLK_VOP_ROOT_SEL_GPLL)
950 			parent = priv->gpll_hz;
951 		else if (sel == ACLK_VOP_ROOT_SEL_CPLL)
952 			parent = priv->cpll_hz;
953 		else if (sel == ACLK_VOP_ROOT_SEL_AUPLL)
954 			parent = priv->aupll_hz;
955 		else if (sel == ACLK_VOP_ROOT_SEL_NPLL)
956 			parent = priv->npll_hz;
957 		else
958 			parent = 702 * MHz;
959 		return DIV_TO_RATE(parent, div);
960 	case ACLK_VOP_LOW_ROOT:
961 		con = readl(&cru->clksel_con[110]);
962 		sel = (con & ACLK_VOP_LOW_ROOT_SEL_MASK) >>
963 		      ACLK_VOP_LOW_ROOT_SEL_SHIFT;
964 		if (sel == ACLK_VOP_LOW_ROOT_SEL_400M)
965 			return 396 * MHz;
966 		else if (sel == ACLK_VOP_LOW_ROOT_SEL_200M)
967 			return 200 * MHz;
968 		else if (sel == ACLK_VOP_LOW_ROOT_SEL_100M)
969 			return 100 * MHz;
970 		else
971 			return OSC_HZ;
972 	case HCLK_VOP_ROOT:
973 		con = readl(&cru->clksel_con[110]);
974 		sel = (con & HCLK_VOP_ROOT_SEL_MASK) >> HCLK_VOP_ROOT_SEL_SHIFT;
975 		if (sel == HCLK_VOP_ROOT_SEL_200M)
976 			return 200 * MHz;
977 		else if (sel == HCLK_VOP_ROOT_SEL_100M)
978 			return 100 * MHz;
979 		else if (sel == HCLK_VOP_ROOT_SEL_50M)
980 			return 50 * MHz;
981 		else
982 			return OSC_HZ;
983 	default:
984 		return -ENOENT;
985 	}
986 }
987 
988 static ulong rk3588_aclk_vop_set_clk(struct rk3588_clk_priv *priv,
989 				     ulong clk_id, ulong rate)
990 {
991 	struct rk3588_cru *cru = priv->cru;
992 	int src_clk, div;
993 
994 	switch (clk_id) {
995 	case ACLK_VOP_ROOT:
996 	case ACLK_VOP:
997 		if (rate >= 850 * MHz) {
998 			src_clk = ACLK_VOP_ROOT_SEL_NPLL;
999 			div = 1;
1000 		} else if (rate >= 750 * MHz) {
1001 			src_clk = ACLK_VOP_ROOT_SEL_CPLL;
1002 			div = 2;
1003 		} else if (rate >= 700 * MHz) {
1004 			src_clk = ACLK_VOP_ROOT_SEL_SPLL;
1005 			div = 1;
1006 		} else if (!(priv->cpll_hz % rate)) {
1007 			src_clk = ACLK_VOP_ROOT_SEL_CPLL;
1008 			div = DIV_ROUND_UP(priv->cpll_hz, rate);
1009 		} else {
1010 			src_clk = ACLK_VOP_ROOT_SEL_GPLL;
1011 			div = DIV_ROUND_UP(priv->gpll_hz, rate);
1012 		}
1013 		rk_clrsetreg(&cru->clksel_con[110],
1014 			     ACLK_VOP_ROOT_DIV_MASK |
1015 			     ACLK_VOP_ROOT_SEL_MASK,
1016 			     (src_clk << ACLK_VOP_ROOT_SEL_SHIFT) |
1017 			     (div - 1) << ACLK_VOP_ROOT_DIV_SHIFT);
1018 		break;
1019 	case ACLK_VOP_LOW_ROOT:
1020 		if (rate == 400 * MHz || rate == 396 * MHz)
1021 			src_clk = ACLK_VOP_LOW_ROOT_SEL_400M;
1022 		else if (rate == 200 * MHz)
1023 			src_clk = ACLK_VOP_LOW_ROOT_SEL_200M;
1024 		else if (rate == 100 * MHz)
1025 			src_clk = ACLK_VOP_LOW_ROOT_SEL_100M;
1026 		else
1027 			src_clk = ACLK_VOP_LOW_ROOT_SEL_24M;
1028 		rk_clrsetreg(&cru->clksel_con[110],
1029 			     ACLK_VOP_LOW_ROOT_SEL_MASK,
1030 			     src_clk << ACLK_VOP_LOW_ROOT_SEL_SHIFT);
1031 		break;
1032 	case HCLK_VOP_ROOT:
1033 		if (rate == 200 * MHz)
1034 			src_clk = HCLK_VOP_ROOT_SEL_200M;
1035 		else if (rate == 100 * MHz)
1036 			src_clk = HCLK_VOP_ROOT_SEL_100M;
1037 		else if (rate == 50 * MHz)
1038 			src_clk = HCLK_VOP_ROOT_SEL_50M;
1039 		else
1040 			src_clk = HCLK_VOP_ROOT_SEL_24M;
1041 		rk_clrsetreg(&cru->clksel_con[110],
1042 			     HCLK_VOP_ROOT_SEL_MASK,
1043 			     src_clk << HCLK_VOP_ROOT_SEL_SHIFT);
1044 		break;
1045 	default:
1046 		return -ENOENT;
1047 	}
1048 
1049 	return rk3588_aclk_vop_get_clk(priv, clk_id);
1050 }
1051 
1052 static ulong rk3588_dclk_vop_get_clk(struct rk3588_clk_priv *priv, ulong clk_id)
1053 {
1054 	struct rk3588_cru *cru = priv->cru;
1055 	u32 div, sel, con, parent;
1056 
1057 	switch (clk_id) {
1058 	case DCLK_VOP0:
1059 	case DCLK_VOP0_SRC:
1060 		con = readl(&cru->clksel_con[111]);
1061 		div = (con & DCLK0_VOP_SRC_DIV_MASK) >> DCLK0_VOP_SRC_DIV_SHIFT;
1062 		sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT;
1063 		break;
1064 	case DCLK_VOP1:
1065 	case DCLK_VOP1_SRC:
1066 		con = readl(&cru->clksel_con[111]);
1067 		div = (con & DCLK1_VOP_SRC_DIV_MASK) >> DCLK1_VOP_SRC_DIV_SHIFT;
1068 		sel = (con & DCLK1_VOP_SRC_SEL_MASK) >> DCLK1_VOP_SRC_SEL_SHIFT;
1069 		break;
1070 	case DCLK_VOP2:
1071 	case DCLK_VOP2_SRC:
1072 		con = readl(&cru->clksel_con[112]);
1073 		div = (con & DCLK2_VOP_SRC_DIV_MASK) >> DCLK2_VOP_SRC_DIV_SHIFT;
1074 		sel = (con & DCLK2_VOP_SRC_SEL_MASK) >> DCLK2_VOP_SRC_SEL_SHIFT;
1075 		break;
1076 	case DCLK_VOP3:
1077 		con = readl(&cru->clksel_con[113]);
1078 		div = (con & DCLK3_VOP_SRC_DIV_MASK) >> DCLK3_VOP_SRC_DIV_SHIFT;
1079 		sel = (con & DCLK3_VOP_SRC_SEL_MASK) >> DCLK3_VOP_SRC_SEL_SHIFT;
1080 		break;
1081 	default:
1082 		return -ENOENT;
1083 	}
1084 
1085 	if (sel == DCLK_VOP_SRC_SEL_AUPLL)
1086 		parent = priv->aupll_hz;
1087 	else if (sel == DCLK_VOP_SRC_SEL_V0PLL)
1088 		parent = rockchip_pll_get_rate(&rk3588_pll_clks[V0PLL],
1089 					       priv->cru, V0PLL);
1090 	else if (sel == DCLK_VOP_SRC_SEL_GPLL)
1091 		parent = priv->gpll_hz;
1092 	else if (sel == DCLK_VOP_SRC_SEL_CPLL)
1093 		parent = priv->cpll_hz;
1094 	else
1095 		return -ENOENT;
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 #ifndef CONFIG_SPL_BUILD
1588 	case CLK_AUX16M_0:
1589 	case CLK_AUX16M_1:
1590 		rk3588_aux16m_get_clk(priv, clk->id);
1591 		break;
1592 	case ACLK_VOP_ROOT:
1593 	case ACLK_VOP:
1594 	case ACLK_VOP_LOW_ROOT:
1595 	case HCLK_VOP_ROOT:
1596 		rate = rk3588_aclk_vop_get_clk(priv, clk->id);
1597 		break;
1598 	case DCLK_VOP0:
1599 	case DCLK_VOP0_SRC:
1600 	case DCLK_VOP1:
1601 	case DCLK_VOP1_SRC:
1602 	case DCLK_VOP2:
1603 	case DCLK_VOP2_SRC:
1604 	case DCLK_VOP3:
1605 		rate = rk3588_dclk_vop_get_clk(priv, clk->id);
1606 		break;
1607 	case CLK_GMAC0_PTP_REF:
1608 	case CLK_GMAC1_PTP_REF:
1609 	case CLK_GMAC_125M:
1610 	case CLK_GMAC_50M:
1611 		rate = rk3588_gmac_get_clk(priv, clk->id);
1612 		break;
1613 	case SCLK_UART1:
1614 	case SCLK_UART2:
1615 	case SCLK_UART3:
1616 	case SCLK_UART4:
1617 	case SCLK_UART5:
1618 	case SCLK_UART6:
1619 	case SCLK_UART7:
1620 	case SCLK_UART8:
1621 	case SCLK_UART9:
1622 		rate = rk3588_uart_get_rate(priv, clk->id);
1623 		break;
1624 	case CLK_REF_PIPE_PHY0:
1625 	case CLK_REF_PIPE_PHY1:
1626 	case CLK_REF_PIPE_PHY2:
1627 		rate = rk3588_pciephy_get_rate(priv, clk->id);
1628 		break;
1629 #endif
1630 	default:
1631 		return -ENOENT;
1632 	}
1633 
1634 	return rate;
1635 };
1636 
1637 static ulong rk3588_clk_set_rate(struct clk *clk, ulong rate)
1638 {
1639 	struct rk3588_clk_priv *priv = dev_get_priv(clk->dev);
1640 	ulong ret = 0;
1641 
1642 	if (!priv->gpll_hz) {
1643 		printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
1644 		return -ENOENT;
1645 	}
1646 
1647 	if (!priv->ppll_hz) {
1648 		priv->ppll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[PPLL],
1649 						      priv->cru, PPLL);
1650 	}
1651 
1652 	switch (clk->id) {
1653 	case PLL_CPLL:
1654 		ret = rockchip_pll_set_rate(&rk3588_pll_clks[CPLL], priv->cru,
1655 					    CPLL, rate);
1656 		priv->cpll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[CPLL],
1657 						      priv->cru, CPLL);
1658 		break;
1659 	case PLL_GPLL:
1660 		ret = rockchip_pll_set_rate(&rk3588_pll_clks[GPLL], priv->cru,
1661 					    GPLL, rate);
1662 		priv->gpll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[GPLL],
1663 						      priv->cru, GPLL);
1664 		break;
1665 	case PLL_NPLL:
1666 		ret = rockchip_pll_set_rate(&rk3588_pll_clks[NPLL], priv->cru,
1667 					    NPLL, rate);
1668 		break;
1669 	case PLL_V0PLL:
1670 		ret = rockchip_pll_set_rate(&rk3588_pll_clks[V0PLL], priv->cru,
1671 					    V0PLL, rate);
1672 		priv->v0pll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[V0PLL],
1673 						       priv->cru, V0PLL);
1674 		break;
1675 	case PLL_AUPLL:
1676 		ret = rockchip_pll_set_rate(&rk3588_pll_clks[AUPLL], priv->cru,
1677 					    AUPLL, rate);
1678 		priv->aupll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[AUPLL],
1679 						       priv->cru, AUPLL);
1680 		break;
1681 	case PLL_PPLL:
1682 		ret = rockchip_pll_set_rate(&rk3588_pll_clks[PPLL], priv->cru,
1683 					    PPLL, rate);
1684 		priv->ppll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[PPLL],
1685 						      priv->cru, PPLL);
1686 		break;
1687 	case ACLK_CENTER_ROOT:
1688 	case PCLK_CENTER_ROOT:
1689 	case HCLK_CENTER_ROOT:
1690 	case ACLK_CENTER_LOW_ROOT:
1691 		ret = rk3588_center_set_clk(priv, clk->id, rate);
1692 		break;
1693 	case ACLK_TOP_ROOT:
1694 	case PCLK_TOP_ROOT:
1695 	case ACLK_LOW_TOP_ROOT:
1696 		ret = rk3588_top_set_clk(priv, clk->id, rate);
1697 		break;
1698 	case CLK_I2C0:
1699 	case CLK_I2C1:
1700 	case CLK_I2C2:
1701 	case CLK_I2C3:
1702 	case CLK_I2C4:
1703 	case CLK_I2C5:
1704 	case CLK_I2C6:
1705 	case CLK_I2C7:
1706 	case CLK_I2C8:
1707 		ret = rk3588_i2c_set_clk(priv, clk->id, rate);
1708 		break;
1709 	case CLK_SPI0:
1710 	case CLK_SPI1:
1711 	case CLK_SPI2:
1712 	case CLK_SPI3:
1713 	case CLK_SPI4:
1714 		ret = rk3588_spi_set_clk(priv, clk->id, rate);
1715 		break;
1716 	case CLK_PWM1:
1717 	case CLK_PWM2:
1718 	case CLK_PWM3:
1719 	case CLK_PMU1PWM:
1720 		ret = rk3588_pwm_set_clk(priv, clk->id, rate);
1721 		break;
1722 	case CLK_SARADC:
1723 	case CLK_TSADC:
1724 		ret = rk3588_adc_set_clk(priv, clk->id, rate);
1725 		break;
1726 	case CCLK_SRC_SDIO:
1727 	case CCLK_EMMC:
1728 	case BCLK_EMMC:
1729 	case SCLK_SFC:
1730 	case DCLK_DECOM:
1731 		ret = rk3588_mmc_set_clk(priv, clk->id, rate);
1732 		break;
1733 #ifndef CONFIG_SPL_BUILD
1734 	case CLK_AUX16M_0:
1735 	case CLK_AUX16M_1:
1736 		rk3588_aux16m_set_clk(priv, clk->id, rate);
1737 		break;
1738 	case ACLK_VOP_ROOT:
1739 	case ACLK_VOP:
1740 	case ACLK_VOP_LOW_ROOT:
1741 	case HCLK_VOP_ROOT:
1742 		ret = rk3588_aclk_vop_set_clk(priv, clk->id, rate);
1743 		break;
1744 	case DCLK_VOP0:
1745 	case DCLK_VOP0_SRC:
1746 	case DCLK_VOP1:
1747 	case DCLK_VOP1_SRC:
1748 	case DCLK_VOP2:
1749 	case DCLK_VOP2_SRC:
1750 	case DCLK_VOP3:
1751 		ret = rk3588_dclk_vop_set_clk(priv, clk->id, rate);
1752 		break;
1753 	case CLK_GMAC0_PTP_REF:
1754 	case CLK_GMAC1_PTP_REF:
1755 	case CLK_GMAC_125M:
1756 	case CLK_GMAC_50M:
1757 		ret = rk3588_gmac_set_clk(priv, clk->id, rate);
1758 		break;
1759 	case SCLK_UART1:
1760 	case SCLK_UART2:
1761 	case SCLK_UART3:
1762 	case SCLK_UART4:
1763 	case SCLK_UART5:
1764 	case SCLK_UART6:
1765 	case SCLK_UART7:
1766 	case SCLK_UART8:
1767 	case SCLK_UART9:
1768 		ret = rk3588_uart_set_rate(priv, clk->id, rate);
1769 		break;
1770 	case CLK_REF_PIPE_PHY0:
1771 	case CLK_REF_PIPE_PHY1:
1772 	case CLK_REF_PIPE_PHY2:
1773 		ret = rk3588_pciephy_set_rate(priv, clk->id, rate);
1774 		break;
1775 #endif
1776 	default:
1777 		return -ENOENT;
1778 	}
1779 
1780 	return ret;
1781 };
1782 
1783 #define ROCKCHIP_MMC_DELAY_SEL		BIT(10)
1784 #define ROCKCHIP_MMC_DEGREE_MASK	0x3
1785 #define ROCKCHIP_MMC_DELAYNUM_OFFSET	2
1786 #define ROCKCHIP_MMC_DELAYNUM_MASK	(0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
1787 
1788 #define PSECS_PER_SEC 1000000000000LL
1789 /*
1790  * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to
1791  * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg.
1792  */
1793 #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60
1794 
1795 int rk3588_mmc_get_phase(struct clk *clk)
1796 {
1797 	struct rk3588_clk_priv *priv = dev_get_priv(clk->dev);
1798 	struct rk3588_cru *cru = priv->cru;
1799 	u32 raw_value, delay_num;
1800 	u16 degrees = 0;
1801 	ulong rate;
1802 
1803 	rate = rk3588_clk_get_rate(clk);
1804 	if (rate < 0)
1805 		return rate;
1806 
1807 	if (clk->id == SCLK_SDMMC_SAMPLE)
1808 		raw_value = readl(&cru->sdmmc_con[1]);
1809 	else
1810 		return 0;
1811 
1812 	raw_value >>= 1;
1813 	degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90;
1814 
1815 	if (raw_value & ROCKCHIP_MMC_DELAY_SEL) {
1816 		/* degrees/delaynum * 10000 */
1817 		unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) *
1818 					36 * (rate / 1000000);
1819 
1820 		delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK);
1821 		delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET;
1822 		degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000);
1823 	}
1824 
1825 	return degrees % 360;
1826 }
1827 
1828 int rk3588_mmc_set_phase(struct clk *clk, u32 degrees)
1829 {
1830 	struct rk3588_clk_priv *priv = dev_get_priv(clk->dev);
1831 	struct rk3588_cru *cru = priv->cru;
1832 	u8 nineties, remainder, delay_num;
1833 	u32 raw_value, delay;
1834 	ulong rate;
1835 
1836 	rate = rk3588_clk_get_rate(clk);
1837 	if (rate < 0)
1838 		return rate;
1839 
1840 	nineties = degrees / 90;
1841 	remainder = (degrees % 90);
1842 
1843 	/*
1844 	 * Convert to delay; do a little extra work to make sure we
1845 	 * don't overflow 32-bit / 64-bit numbers.
1846 	 */
1847 	delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */
1848 	delay *= remainder;
1849 	delay = DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 *
1850 				  (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10));
1851 
1852 	delay_num = (u8)min_t(u32, delay, 255);
1853 
1854 	raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0;
1855 	raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET;
1856 	raw_value |= nineties;
1857 
1858 	raw_value <<= 1;
1859 	if (clk->id == SCLK_SDMMC_SAMPLE)
1860 		writel(raw_value | 0xffff0000, &cru->sdmmc_con[1]);
1861 
1862 	debug("mmc set_phase(%d) delay_nums=%u reg=%#x actual_degrees=%d\n",
1863 	      degrees, delay_num, raw_value, rk3588_mmc_get_phase(clk));
1864 
1865 	return 0;
1866 }
1867 
1868 static int rk3588_clk_get_phase(struct clk *clk)
1869 {
1870 	int ret;
1871 
1872 	debug("%s %ld\n", __func__, clk->id);
1873 	switch (clk->id) {
1874 	case SCLK_SDMMC_SAMPLE:
1875 		ret = rk3588_mmc_get_phase(clk);
1876 		break;
1877 	default:
1878 		return -ENOENT;
1879 	}
1880 
1881 	return ret;
1882 }
1883 
1884 static int rk3588_clk_set_phase(struct clk *clk, int degrees)
1885 {
1886 	int ret;
1887 
1888 	debug("%s %ld\n", __func__, clk->id);
1889 	switch (clk->id) {
1890 	case SCLK_SDMMC_SAMPLE:
1891 		ret = rk3588_mmc_set_phase(clk, degrees);
1892 		break;
1893 	default:
1894 		return -ENOENT;
1895 	}
1896 
1897 	return ret;
1898 }
1899 
1900 #if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA))
1901 static int __maybe_unused rk3588_dclk_vop_set_parent(struct clk *clk,
1902 						     struct clk *parent)
1903 {
1904 	struct rk3588_clk_priv *priv = dev_get_priv(clk->dev);
1905 	struct rk3588_cru *cru = priv->cru;
1906 	u32 sel;
1907 	const char *clock_dev_name = parent->dev->name;
1908 
1909 	if (parent->id == PLL_V0PLL)
1910 		sel = 2;
1911 	else if (parent->id == PLL_GPLL)
1912 		sel = 0;
1913 	else if (parent->id == PLL_CPLL)
1914 		sel = 1;
1915 	else
1916 		sel = 3;
1917 
1918 	switch (clk->id) {
1919 	case DCLK_VOP0_SRC:
1920 		rk_clrsetreg(&cru->clksel_con[111], DCLK0_VOP_SRC_SEL_MASK,
1921 			     sel << DCLK0_VOP_SRC_SEL_SHIFT);
1922 		break;
1923 	case DCLK_VOP1_SRC:
1924 		rk_clrsetreg(&cru->clksel_con[111], DCLK1_VOP_SRC_SEL_MASK,
1925 			     sel << DCLK1_VOP_SRC_SEL_SHIFT);
1926 		break;
1927 	case DCLK_VOP2_SRC:
1928 		rk_clrsetreg(&cru->clksel_con[112], DCLK2_VOP_SRC_SEL_MASK,
1929 			     sel << DCLK2_VOP_SRC_SEL_SHIFT);
1930 		break;
1931 	case DCLK_VOP3:
1932 		rk_clrsetreg(&cru->clksel_con[113], DCLK3_VOP_SRC_SEL_MASK,
1933 			     sel << DCLK3_VOP_SRC_SEL_SHIFT);
1934 		break;
1935 	case DCLK_VOP0:
1936 		if (!strcmp(clock_dev_name, "hdmiphypll_clk0"))
1937 			sel = 1;
1938 		else if (!strcmp(clock_dev_name, "hdmiphypll_clk1"))
1939 			sel = 2;
1940 		else
1941 			sel = 0;
1942 		rk_clrsetreg(&cru->clksel_con[112], DCLK0_VOP_SEL_MASK,
1943 			     sel << DCLK0_VOP_SEL_SHIFT);
1944 		break;
1945 	case DCLK_VOP1:
1946 		if (!strcmp(clock_dev_name, "hdmiphypll_clk0"))
1947 			sel = 1;
1948 		else if (!strcmp(clock_dev_name, "hdmiphypll_clk1"))
1949 			sel = 2;
1950 		else
1951 			sel = 0;
1952 		rk_clrsetreg(&cru->clksel_con[112], DCLK1_VOP_SEL_MASK,
1953 			     sel << DCLK1_VOP_SEL_SHIFT);
1954 		break;
1955 	case DCLK_VOP2:
1956 		if (!strcmp(clock_dev_name, "hdmiphypll_clk0"))
1957 			sel = 1;
1958 		else if (!strcmp(clock_dev_name, "hdmiphypll_clk1"))
1959 			sel = 2;
1960 		else
1961 			sel = 0;
1962 		rk_clrsetreg(&cru->clksel_con[112], DCLK2_VOP_SEL_MASK,
1963 			     sel << DCLK2_VOP_SEL_SHIFT);
1964 		break;
1965 	default:
1966 		return -EINVAL;
1967 	}
1968 	return 0;
1969 }
1970 
1971 static int rk3588_clk_set_parent(struct clk *clk, struct clk *parent)
1972 {
1973 	switch (clk->id) {
1974 	case DCLK_VOP0_SRC:
1975 	case DCLK_VOP1_SRC:
1976 	case DCLK_VOP2_SRC:
1977 	case DCLK_VOP0:
1978 	case DCLK_VOP1:
1979 	case DCLK_VOP2:
1980 	case DCLK_VOP3:
1981 		return rk3588_dclk_vop_set_parent(clk, parent);
1982 	default:
1983 		return -ENOENT;
1984 	}
1985 
1986 	return 0;
1987 }
1988 #endif
1989 
1990 static struct clk_ops rk3588_clk_ops = {
1991 	.get_rate = rk3588_clk_get_rate,
1992 	.set_rate = rk3588_clk_set_rate,
1993 	.get_phase = rk3588_clk_get_phase,
1994 	.set_phase = rk3588_clk_set_phase,
1995 #if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA))
1996 	.set_parent = rk3588_clk_set_parent,
1997 #endif
1998 };
1999 
2000 static void rk3588_clk_init(struct rk3588_clk_priv *priv)
2001 {
2002 	int ret, div;
2003 
2004 	priv->sync_kernel = false;
2005 	if (!priv->armclk_enter_hz) {
2006 		ret = rockchip_pll_set_rate(&rk3588_pll_clks[LPLL], priv->cru,
2007 					    LPLL, LPLL_HZ);
2008 		priv->armclk_enter_hz =
2009 			rockchip_pll_get_rate(&rk3588_pll_clks[LPLL],
2010 					      priv->cru, LPLL);
2011 		priv->armclk_init_hz = priv->armclk_enter_hz;
2012 	}
2013 
2014 	div = DIV_ROUND_UP(GPLL_HZ, 300 * MHz);
2015 	rk_clrsetreg(&priv->cru->clksel_con[38],
2016 		     ACLK_BUS_ROOT_SEL_MASK |
2017 		     ACLK_BUS_ROOT_DIV_MASK,
2018 		     div << ACLK_BUS_ROOT_DIV_SHIFT);
2019 
2020 	if (priv->cpll_hz != CPLL_HZ) {
2021 		ret = rockchip_pll_set_rate(&rk3588_pll_clks[CPLL], priv->cru,
2022 					    CPLL, CPLL_HZ);
2023 		if (!ret)
2024 			priv->cpll_hz = CPLL_HZ;
2025 	}
2026 	if (priv->gpll_hz != GPLL_HZ) {
2027 		ret = rockchip_pll_set_rate(&rk3588_pll_clks[GPLL], priv->cru,
2028 					    GPLL, GPLL_HZ);
2029 		if (!ret)
2030 			priv->gpll_hz = GPLL_HZ;
2031 	}
2032 
2033 	rk_clrsetreg(&priv->cru->clksel_con[9],
2034 		     ACLK_TOP_S400_SEL_MASK |
2035 		     ACLK_TOP_S200_SEL_MASK,
2036 		     (ACLK_TOP_S400_SEL_400M << ACLK_TOP_S400_SEL_SHIFT) |
2037 		     (ACLK_TOP_S200_SEL_200M << ACLK_TOP_S200_SEL_SHIFT));
2038 }
2039 
2040 static int rk3588_clk_probe(struct udevice *dev)
2041 {
2042 	struct rk3588_clk_priv *priv = dev_get_priv(dev);
2043 	int ret;
2044 	struct clk clk;
2045 
2046 #ifdef CONFIG_SPL_BUILD
2047 	rockchip_pll_set_rate(&rk3588_pll_clks[B0PLL], priv->cru,
2048 			      B0PLL, LPLL_HZ);
2049 	rockchip_pll_set_rate(&rk3588_pll_clks[B1PLL], priv->cru,
2050 			      B1PLL, LPLL_HZ);
2051 #endif
2052 
2053 	ret = rockchip_get_scmi_clk(&clk.dev);
2054 	if (ret) {
2055 		printf("Failed to get scmi clk dev\n");
2056 		return ret;
2057 	}
2058 	clk.id = SCMI_SPLL;
2059 	ret = clk_set_rate(&clk, 702000000);
2060 	if (ret < 0) {
2061 		printf("Failed to set spll\n");
2062 	}
2063 
2064 	clk.id = SCMI_CLK_CPUB01;
2065 	ret = clk_set_rate(&clk, LPLL_HZ);
2066 	if (ret < 0)
2067 		printf("Failed to set cpub01\n");
2068 	clk.id = SCMI_CLK_CPUB23;
2069 	ret = clk_set_rate(&clk, LPLL_HZ);
2070 	if (ret < 0)
2071 		printf("Failed to set cpub23\n");
2072 
2073 	priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
2074 	if (IS_ERR(priv->grf))
2075 		return PTR_ERR(priv->grf);
2076 
2077 	rk3588_clk_init(priv);
2078 
2079 	/* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
2080 	ret = clk_set_defaults(dev);
2081 	if (ret)
2082 		debug("%s clk_set_defaults failed %d\n", __func__, ret);
2083 	else
2084 		priv->sync_kernel = true;
2085 
2086 	return 0;
2087 }
2088 
2089 static int rk3588_clk_ofdata_to_platdata(struct udevice *dev)
2090 {
2091 	struct rk3588_clk_priv *priv = dev_get_priv(dev);
2092 
2093 	priv->cru = dev_read_addr_ptr(dev);
2094 
2095 	return 0;
2096 }
2097 
2098 static int rk3588_clk_bind(struct udevice *dev)
2099 {
2100 	int ret;
2101 	struct udevice *sys_child, *sf_child;
2102 	struct sysreset_reg *priv;
2103 	struct softreset_reg *sf_priv;
2104 
2105 	/* The reset driver does not have a device node, so bind it here */
2106 	ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
2107 				 &sys_child);
2108 	if (ret) {
2109 		debug("Warning: No sysreset driver: ret=%d\n", ret);
2110 	} else {
2111 		priv = malloc(sizeof(struct sysreset_reg));
2112 		priv->glb_srst_fst_value = offsetof(struct rk3588_cru,
2113 						    glb_srst_fst);
2114 		priv->glb_srst_snd_value = offsetof(struct rk3588_cru,
2115 						    glb_srsr_snd);
2116 		sys_child->priv = priv;
2117 	}
2118 
2119 	ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset",
2120 					 dev_ofnode(dev), &sf_child);
2121 	if (ret) {
2122 		debug("Warning: No rockchip reset driver: ret=%d\n", ret);
2123 	} else {
2124 		sf_priv = malloc(sizeof(struct softreset_reg));
2125 		sf_priv->sf_reset_offset = offsetof(struct rk3588_cru,
2126 						    softrst_con[0]);
2127 		sf_priv->sf_reset_num = 49158;
2128 		sf_child->priv = sf_priv;
2129 	}
2130 
2131 	return 0;
2132 }
2133 
2134 static const struct udevice_id rk3588_clk_ids[] = {
2135 	{ .compatible = "rockchip,rk3588-cru" },
2136 	{ }
2137 };
2138 
2139 U_BOOT_DRIVER(rockchip_rk3588_cru) = {
2140 	.name		= "rockchip_rk3588_cru",
2141 	.id		= UCLASS_CLK,
2142 	.of_match	= rk3588_clk_ids,
2143 	.priv_auto_alloc_size = sizeof(struct rk3588_clk_priv),
2144 	.ofdata_to_platdata = rk3588_clk_ofdata_to_platdata,
2145 	.ops		= &rk3588_clk_ops,
2146 	.bind		= rk3588_clk_bind,
2147 	.probe		= rk3588_clk_probe,
2148 };
2149 
2150 #ifdef CONFIG_SPL_BUILD
2151 #define SCRU_BASE			0xfd7d0000
2152 #define BUSSCRU_BASE			0xfd7d8000
2153 #define GPLL_RATE			1188000000
2154 #define SPLL_RATE			702000000
2155 
2156 #ifndef BITS_WITH_WMASK
2157 #define BITS_WITH_WMASK(bits, msk, shift) \
2158 	((bits) << (shift)) | ((msk) << ((shift) + 16))
2159 #endif
2160 
2161 #define CLKDIV_6BITS_SHF(div, shift)	BITS_WITH_WMASK(div, 0x3fU, shift)
2162 #define CLKDIV_5BITS_SHF(div, shift)	BITS_WITH_WMASK(div, 0x1fU, shift)
2163 
2164 static ulong rk3588_clk_scmi_get_rate(struct clk *clk)
2165 {
2166 	u32 src, div;
2167 
2168 	switch (clk->id) {
2169 	case SCMI_SPLL:
2170 		src = readl(BUSSCRU_BASE + RK3588_MODE_CON0) & 0x3;
2171 		if (src == 0)
2172 			return OSC_HZ;
2173 		else if (src == 1)
2174 			return 702 * MHz;
2175 		else
2176 			return 32768;
2177 	case SCMI_CCLK_SD:
2178 		src = readl(SCRU_BASE + RK3588_CLKSEL_CON(3)) & 0x3000;
2179 		src = src >> 12;
2180 		div = readl(SCRU_BASE + RK3588_CLKSEL_CON(3)) & 0x0fc0;
2181 		div = div >> 6;
2182 		if (src == 1)
2183 			return SPLL_RATE / (div + 1);
2184 		else if (src == 2)
2185 			return OSC_HZ / (div + 1);
2186 		else
2187 			return GPLL_RATE / (div + 1);
2188 	case SCMI_DCLK_SD:
2189 		src = readl(SCRU_BASE + RK3588_CLKSEL_CON(3)) & 0x0020;
2190 		div = readl(SCRU_BASE + RK3588_CLKSEL_CON(3)) & 0x001f;
2191 		if (src)
2192 			return SPLL_RATE / (div + 1);
2193 		else
2194 			return GPLL_RATE / (div + 1);
2195 	case SCMI_CRYPTO_RNG:
2196 		src = readl(SCRU_BASE + RK3588_CLKSEL_CON(1)) & 0xc000;
2197 		src = src >> 14;
2198 		if (src == 0)
2199 			return 175 * MHz;
2200 		else if (src == 1)
2201 			return 116 * MHz;
2202 		else if (src == 2)
2203 			return 58 * MHz;
2204 		else
2205 			return OSC_HZ;
2206 	case SCMI_CRYPTO_CORE:
2207 		src = readl(SCRU_BASE + RK3588_CLKSEL_CON(1)) & 0x0c00;
2208 		src = src >> 10;
2209 		if (src == 0)
2210 			return 350 * MHz;
2211 		else if (src == 1)
2212 			return 233 * MHz;
2213 		else if (src == 2)
2214 			return 116 * MHz;
2215 		else
2216 			return OSC_HZ;
2217 	case SCMI_CRYPTO_PKA:
2218 		src = readl(SCRU_BASE + RK3588_CLKSEL_CON(1)) & 0x3000;
2219 		src = src >> 12;
2220 		if (src == 0)
2221 			return 350 * MHz;
2222 		else if (src == 1)
2223 			return 233 * MHz;
2224 		else if (src == 2)
2225 			return 116 * MHz;
2226 		else
2227 			return OSC_HZ;
2228 	case SCMI_KEYLADDER_CORE:
2229 		src = readl(SCRU_BASE + RK3588_CLKSEL_CON(2)) & 0x00c0;
2230 		src = src >> 6;
2231 		if (src == 0)
2232 			return 350 * MHz;
2233 		else if (src == 1)
2234 			return 233 * MHz;
2235 		else if (src == 2)
2236 			return 116 * MHz;
2237 		else
2238 			return OSC_HZ;
2239 	case SCMI_KEYLADDER_RNG:
2240 		src = readl(SCRU_BASE + RK3588_CLKSEL_CON(2)) & 0x0300;
2241 		src = src >> 8;
2242 		if (src == 0)
2243 			return 175 * MHz;
2244 		else if (src == 1)
2245 			return 116 * MHz;
2246 		else if (src == 2)
2247 			return 58 * MHz;
2248 		else
2249 			return OSC_HZ;
2250 	case SCMI_TCLK_WDT:
2251 		return OSC_HZ;
2252 	case SCMI_HCLK_SD:
2253 	case SCMI_HCLK_SECURE_NS:
2254 		src = readl(SCRU_BASE + RK3588_CLKSEL_CON(1)) & 0x000c;
2255 		src = src >> 2;
2256 		if (src == 0)
2257 			return 150 * MHz;
2258 		else if (src == 1)
2259 			return 100 * MHz;
2260 		else if (src == 2)
2261 			return 50 * MHz;
2262 		else
2263 			return OSC_HZ;
2264 	default:
2265 		return -ENOENT;
2266 	}
2267 };
2268 
2269 static ulong rk3588_clk_scmi_set_rate(struct clk *clk, ulong rate)
2270 {
2271 	u32 src, div;
2272 
2273 	if ((readl(BUSSCRU_BASE + RK3588_PLL_CON(137)) & 0x01c0) == 0xc0) {
2274 		writel(BITS_WITH_WMASK(0, 0x3U, 0),
2275 			BUSSCRU_BASE + RK3588_MODE_CON0);
2276 		writel(BITS_WITH_WMASK(2, 0x7U, 6),
2277 			BUSSCRU_BASE + RK3588_PLL_CON(137));
2278 		writel(BITS_WITH_WMASK(1, 0x3U, 0),
2279 		       BUSSCRU_BASE + RK3588_MODE_CON0);
2280 	}
2281 
2282 	switch (clk->id) {
2283 	case SCMI_SPLL:
2284 		if (rate >= 700 * MHz)
2285 			src = 1;
2286 		else
2287 			src = 0;
2288 		writel(BITS_WITH_WMASK(0, 0x3U, 0),
2289 			BUSSCRU_BASE + RK3588_MODE_CON0);
2290 		writel(BITS_WITH_WMASK(2, 0x7U, 6),
2291 			BUSSCRU_BASE + RK3588_PLL_CON(137));
2292 		writel(BITS_WITH_WMASK(src, 0x3U, 0),
2293 		       BUSSCRU_BASE + RK3588_MODE_CON0);
2294 		break;
2295 	case SCMI_CCLK_SD:
2296 		if ((OSC_HZ % rate) == 0) {
2297 			div = DIV_ROUND_UP(OSC_HZ, rate);
2298 			writel(CLKDIV_6BITS_SHF(div - 1, 6) |
2299 			       BITS_WITH_WMASK(2U, 0x3U, 12),
2300 			       SCRU_BASE + RK3588_CLKSEL_CON(3));
2301 		} else if ((SPLL_RATE % rate) == 0) {
2302 			div = DIV_ROUND_UP(SPLL_RATE, rate);
2303 			writel(CLKDIV_6BITS_SHF(div - 1, 6) |
2304 			       BITS_WITH_WMASK(1U, 0x3U, 12),
2305 			       SCRU_BASE + RK3588_CLKSEL_CON(3));
2306 		} else {
2307 			div = DIV_ROUND_UP(GPLL_RATE, rate);
2308 			writel(CLKDIV_6BITS_SHF(div - 1, 6) |
2309 			       BITS_WITH_WMASK(0U, 0x3U, 12),
2310 			       SCRU_BASE + RK3588_CLKSEL_CON(3));
2311 		}
2312 		break;
2313 	case SCMI_DCLK_SD:
2314 		if ((SPLL_RATE % rate) == 0) {
2315 			div = DIV_ROUND_UP(SPLL_RATE, rate);
2316 			writel(CLKDIV_5BITS_SHF(div - 1, 0) |
2317 			       BITS_WITH_WMASK(1U, 0x1U, 5),
2318 			       SCRU_BASE + RK3588_CLKSEL_CON(3));
2319 		} else {
2320 			div = DIV_ROUND_UP(GPLL_RATE, rate);
2321 			writel(CLKDIV_5BITS_SHF(div - 1, 0) |
2322 			       BITS_WITH_WMASK(0U, 0x1U, 5),
2323 			       SCRU_BASE + RK3588_CLKSEL_CON(3));
2324 		}
2325 		break;
2326 	case SCMI_CRYPTO_RNG:
2327 		if (rate >= 175 * MHz)
2328 			src = 0;
2329 		else if (rate >= 116 * MHz)
2330 			src = 1;
2331 		else if (rate >= 58 * MHz)
2332 			src = 2;
2333 		else
2334 			src = 3;
2335 
2336 		writel(BITS_WITH_WMASK(src, 0x3U, 14),
2337 		       SCRU_BASE + RK3588_CLKSEL_CON(1));
2338 		break;
2339 	case SCMI_CRYPTO_CORE:
2340 		if (rate >= 350 * MHz)
2341 			src = 0;
2342 		else if (rate >= 233 * MHz)
2343 			src = 1;
2344 		else if (rate >= 116 * MHz)
2345 			src = 2;
2346 		else
2347 			src = 3;
2348 
2349 		writel(BITS_WITH_WMASK(src, 0x3U, 10),
2350 		       SCRU_BASE + RK3588_CLKSEL_CON(1));
2351 		break;
2352 	case SCMI_CRYPTO_PKA:
2353 		if (rate >= 350 * MHz)
2354 			src = 0;
2355 		else if (rate >= 233 * MHz)
2356 			src = 1;
2357 		else if (rate >= 116 * MHz)
2358 			src = 2;
2359 		else
2360 			src = 3;
2361 
2362 		writel(BITS_WITH_WMASK(src, 0x3U, 12),
2363 		       SCRU_BASE + RK3588_CLKSEL_CON(1));
2364 		break;
2365 	case SCMI_KEYLADDER_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, 6),
2376 		       SCRU_BASE + RK3588_CLKSEL_CON(2));
2377 		break;
2378 	case SCMI_KEYLADDER_RNG:
2379 		if (rate >= 175 * MHz)
2380 			src = 0;
2381 		else if (rate >= 116 * MHz)
2382 			src = 1;
2383 		else if (rate >= 58 * MHz)
2384 			src = 2;
2385 		else
2386 			src = 3;
2387 
2388 		writel(BITS_WITH_WMASK(src, 0x3U, 8),
2389 		       SCRU_BASE + RK3588_CLKSEL_CON(2));
2390 		break;
2391 	case SCMI_TCLK_WDT:
2392 		break;
2393 	case SCMI_HCLK_SD:
2394 	case SCMI_HCLK_SECURE_NS:
2395 		if (rate >= 150 * MHz)
2396 			src = 0;
2397 		else if (rate >= 100 * MHz)
2398 			src = 1;
2399 		else if (rate >= 50 * MHz)
2400 			src = 2;
2401 		else
2402 			src = 3;
2403 		writel(BITS_WITH_WMASK(src, 0x3U, 2),
2404 		       SCRU_BASE + RK3588_CLKSEL_CON(1));
2405 		break;
2406 	default:
2407 		return -ENOENT;
2408 	}
2409 	return 0;
2410 };
2411 
2412 /* A fake scmi driver for SPL/TPL where smccc agent is not available. */
2413 static const struct clk_ops scmi_clk_ops = {
2414 	.get_rate = rk3588_clk_scmi_get_rate,
2415 	.set_rate = rk3588_clk_scmi_set_rate,
2416 };
2417 
2418 U_BOOT_DRIVER(scmi_clock) = {
2419 	.name = "scmi_clk",
2420 	.id = UCLASS_CLK,
2421 	.ops = &scmi_clk_ops,
2422 };
2423 #endif
2424 
2425 #ifndef CONFIG_SPL_BUILD
2426 /**
2427  * soc_clk_dump() - Print clock frequencies
2428  * Returns zero on success
2429  *
2430  * Implementation for the clk dump command.
2431  */
2432 int soc_clk_dump(void)
2433 {
2434 	struct udevice *cru_dev;
2435 	struct rk3588_clk_priv *priv;
2436 	const struct rk3588_clk_info *clk_dump;
2437 	struct clk clk;
2438 	unsigned long clk_count = ARRAY_SIZE(clks_dump);
2439 	unsigned long rate;
2440 	int i, ret;
2441 
2442 	ret = uclass_get_device_by_driver(UCLASS_CLK,
2443 					  DM_GET_DRIVER(rockchip_rk3588_cru),
2444 					  &cru_dev);
2445 	if (ret) {
2446 		printf("%s failed to get cru device\n", __func__);
2447 		return ret;
2448 	}
2449 
2450 	priv = dev_get_priv(cru_dev);
2451 	printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n",
2452 	       priv->sync_kernel ? "sync kernel" : "uboot",
2453 	       priv->armclk_enter_hz / 1000,
2454 	       priv->armclk_init_hz / 1000,
2455 	       priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0,
2456 	       priv->set_armclk_rate ? " KHz" : "N/A");
2457 	for (i = 0; i < clk_count; i++) {
2458 		clk_dump = &clks_dump[i];
2459 		if (clk_dump->name) {
2460 			clk.id = clk_dump->id;
2461 			if (clk_dump->is_cru)
2462 				ret = clk_request(cru_dev, &clk);
2463 			if (ret < 0)
2464 				return ret;
2465 
2466 			rate = clk_get_rate(&clk);
2467 			clk_free(&clk);
2468 			if (i == 0) {
2469 				if (rate < 0)
2470 					printf("  %s %s\n", clk_dump->name,
2471 					       "unknown");
2472 				else
2473 					printf("  %s %lu KHz\n", clk_dump->name,
2474 					       rate / 1000);
2475 			} else {
2476 				if (rate < 0)
2477 					printf("  %s %s\n", clk_dump->name,
2478 					       "unknown");
2479 				else
2480 					printf("  %s %lu KHz\n", clk_dump->name,
2481 					       rate / 1000);
2482 			}
2483 		}
2484 	}
2485 
2486 	return 0;
2487 }
2488 #endif
2489