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