xref: /rk3399_rockchip-uboot/drivers/clk/rockchip/clk_rk3588.c (revision de479f92fac8b00a2b04c4f1fc75f40ac7407e0e)
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 	if (priv->ppll_hz != PPLL_HZ) {
2084 		ret = rockchip_pll_set_rate(&rk3588_pll_clks[PPLL], priv->cru,
2085 					    PPLL, PPLL_HZ);
2086 		priv->ppll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[PPLL],
2087 						      priv->cru, PPLL);
2088 	}
2089 
2090 	rk_clrsetreg(&priv->cru->clksel_con[9],
2091 		     ACLK_TOP_S400_SEL_MASK |
2092 		     ACLK_TOP_S200_SEL_MASK,
2093 		     (ACLK_TOP_S400_SEL_400M << ACLK_TOP_S400_SEL_SHIFT) |
2094 		     (ACLK_TOP_S200_SEL_200M << ACLK_TOP_S200_SEL_SHIFT));
2095 }
2096 
2097 static int rk3588_clk_probe(struct udevice *dev)
2098 {
2099 	struct rk3588_clk_priv *priv = dev_get_priv(dev);
2100 	int ret;
2101 
2102 #if CONFIG_IS_ENABLED(CLK_SCMI)
2103 	struct clk clk;
2104 #endif
2105 
2106 	priv->sync_kernel = false;
2107 
2108 #ifdef CONFIG_SPL_BUILD
2109 	rockchip_pll_set_rate(&rk3588_pll_clks[B0PLL], priv->cru,
2110 			      B0PLL, LPLL_HZ);
2111 	rockchip_pll_set_rate(&rk3588_pll_clks[B1PLL], priv->cru,
2112 			      B1PLL, LPLL_HZ);
2113 	if (!priv->armclk_enter_hz) {
2114 		ret = rockchip_pll_set_rate(&rk3588_pll_clks[LPLL], priv->cru,
2115 					    LPLL, LPLL_HZ);
2116 		priv->armclk_enter_hz =
2117 			rockchip_pll_get_rate(&rk3588_pll_clks[LPLL],
2118 					      priv->cru, LPLL);
2119 		priv->armclk_init_hz = priv->armclk_enter_hz;
2120 	}
2121 #endif
2122 
2123 #if CONFIG_IS_ENABLED(CLK_SCMI)
2124 	ret = rockchip_get_scmi_clk(&clk.dev);
2125 	if (ret) {
2126 		printf("Failed to get scmi clk dev\n");
2127 		return ret;
2128 	}
2129 	clk.id = SCMI_SPLL;
2130 	ret = clk_set_rate(&clk, 702000000);
2131 	if (ret < 0) {
2132 		printf("Failed to set spll\n");
2133 	}
2134 
2135 #ifndef CONFIG_SPL_BUILD
2136 	if (!priv->armclk_enter_hz) {
2137 		clk.id = SCMI_CLK_CPUL;
2138 		ret = clk_set_rate(&clk, CPU_PVTPLL_HZ);
2139 		if (ret < 0) {
2140 			printf("Failed to set cpubl\n");
2141 		} else {
2142 			priv->armclk_enter_hz = CPU_PVTPLL_HZ;
2143 			priv->armclk_init_hz = CPU_PVTPLL_HZ;
2144 		}
2145 	}
2146 	clk.id = SCMI_CLK_CPUB01;
2147 	ret = clk_set_rate(&clk, CPU_PVTPLL_HZ);
2148 	if (ret < 0)
2149 		printf("Failed to set cpub01\n");
2150 	clk.id = SCMI_CLK_CPUB23;
2151 	ret = clk_set_rate(&clk, CPU_PVTPLL_HZ);
2152 	if (ret < 0)
2153 		printf("Failed to set cpub23\n");
2154 #endif
2155 #endif
2156 
2157 	priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
2158 	if (IS_ERR(priv->grf))
2159 		return PTR_ERR(priv->grf);
2160 
2161 	rk3588_clk_init(priv);
2162 
2163 	/* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
2164 	ret = clk_set_defaults(dev);
2165 	if (ret)
2166 		debug("%s clk_set_defaults failed %d\n", __func__, ret);
2167 	else
2168 		priv->sync_kernel = true;
2169 
2170 	return 0;
2171 }
2172 
2173 static int rk3588_clk_ofdata_to_platdata(struct udevice *dev)
2174 {
2175 	struct rk3588_clk_priv *priv = dev_get_priv(dev);
2176 
2177 	priv->cru = dev_read_addr_ptr(dev);
2178 
2179 	return 0;
2180 }
2181 
2182 static int rk3588_clk_bind(struct udevice *dev)
2183 {
2184 	int ret;
2185 	struct udevice *sys_child, *sf_child;
2186 	struct sysreset_reg *priv;
2187 	struct softreset_reg *sf_priv;
2188 
2189 	/* The reset driver does not have a device node, so bind it here */
2190 	ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
2191 				 &sys_child);
2192 	if (ret) {
2193 		debug("Warning: No sysreset driver: ret=%d\n", ret);
2194 	} else {
2195 		priv = malloc(sizeof(struct sysreset_reg));
2196 		priv->glb_srst_fst_value = offsetof(struct rk3588_cru,
2197 						    glb_srst_fst);
2198 		priv->glb_srst_snd_value = offsetof(struct rk3588_cru,
2199 						    glb_srsr_snd);
2200 		sys_child->priv = priv;
2201 	}
2202 
2203 	ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset",
2204 					 dev_ofnode(dev), &sf_child);
2205 	if (ret) {
2206 		debug("Warning: No rockchip reset driver: ret=%d\n", ret);
2207 	} else {
2208 		sf_priv = malloc(sizeof(struct softreset_reg));
2209 		sf_priv->sf_reset_offset = offsetof(struct rk3588_cru,
2210 						    softrst_con[0]);
2211 		sf_priv->sf_reset_num = 49158;
2212 		sf_child->priv = sf_priv;
2213 	}
2214 
2215 	return 0;
2216 }
2217 
2218 static const struct udevice_id rk3588_clk_ids[] = {
2219 	{ .compatible = "rockchip,rk3588-cru" },
2220 	{ }
2221 };
2222 
2223 U_BOOT_DRIVER(rockchip_rk3588_cru) = {
2224 	.name		= "rockchip_rk3588_cru",
2225 	.id		= UCLASS_CLK,
2226 	.of_match	= rk3588_clk_ids,
2227 	.priv_auto_alloc_size = sizeof(struct rk3588_clk_priv),
2228 	.ofdata_to_platdata = rk3588_clk_ofdata_to_platdata,
2229 	.ops		= &rk3588_clk_ops,
2230 	.bind		= rk3588_clk_bind,
2231 	.probe		= rk3588_clk_probe,
2232 };
2233 
2234 #ifdef CONFIG_SPL_BUILD
2235 #define SCRU_BASE			0xfd7d0000
2236 #define BUSSCRU_BASE			0xfd7d8000
2237 #define GPLL_RATE			1188000000
2238 #define SPLL_RATE			702000000
2239 
2240 #ifndef BITS_WITH_WMASK
2241 #define BITS_WITH_WMASK(bits, msk, shift) \
2242 	((bits) << (shift)) | ((msk) << ((shift) + 16))
2243 #endif
2244 
2245 #define CLKDIV_6BITS_SHF(div, shift)	BITS_WITH_WMASK(div, 0x3fU, shift)
2246 #define CLKDIV_5BITS_SHF(div, shift)	BITS_WITH_WMASK(div, 0x1fU, shift)
2247 
2248 static ulong rk3588_clk_scmi_get_rate(struct clk *clk)
2249 {
2250 	u32 src, div;
2251 
2252 	switch (clk->id) {
2253 	case SCMI_SPLL:
2254 		src = readl(BUSSCRU_BASE + RK3588_MODE_CON0) & 0x3;
2255 		if (src == 0)
2256 			return OSC_HZ;
2257 		else if (src == 1)
2258 			return 702 * MHz;
2259 		else
2260 			return 32768;
2261 	case SCMI_CCLK_SD:
2262 		src = readl(SCRU_BASE + RK3588_CLKSEL_CON(3)) & 0x3000;
2263 		src = src >> 12;
2264 		div = readl(SCRU_BASE + RK3588_CLKSEL_CON(3)) & 0x0fc0;
2265 		div = div >> 6;
2266 		if (src == 1)
2267 			return SPLL_RATE / (div + 1);
2268 		else if (src == 2)
2269 			return OSC_HZ / (div + 1);
2270 		else
2271 			return GPLL_RATE / (div + 1);
2272 	case SCMI_DCLK_SD:
2273 		src = readl(SCRU_BASE + RK3588_CLKSEL_CON(3)) & 0x0020;
2274 		div = readl(SCRU_BASE + RK3588_CLKSEL_CON(3)) & 0x001f;
2275 		if (src)
2276 			return SPLL_RATE / (div + 1);
2277 		else
2278 			return GPLL_RATE / (div + 1);
2279 	case SCMI_CRYPTO_RNG:
2280 		src = readl(SCRU_BASE + RK3588_CLKSEL_CON(1)) & 0xc000;
2281 		src = src >> 14;
2282 		if (src == 0)
2283 			return 175 * MHz;
2284 		else if (src == 1)
2285 			return 116 * MHz;
2286 		else if (src == 2)
2287 			return 58 * MHz;
2288 		else
2289 			return OSC_HZ;
2290 	case SCMI_CRYPTO_CORE:
2291 		src = readl(SCRU_BASE + RK3588_CLKSEL_CON(1)) & 0x0c00;
2292 		src = src >> 10;
2293 		if (src == 0)
2294 			return 350 * MHz;
2295 		else if (src == 1)
2296 			return 233 * MHz;
2297 		else if (src == 2)
2298 			return 116 * MHz;
2299 		else
2300 			return OSC_HZ;
2301 	case SCMI_CRYPTO_PKA:
2302 		src = readl(SCRU_BASE + RK3588_CLKSEL_CON(1)) & 0x3000;
2303 		src = src >> 12;
2304 		if (src == 0)
2305 			return 350 * MHz;
2306 		else if (src == 1)
2307 			return 233 * MHz;
2308 		else if (src == 2)
2309 			return 116 * MHz;
2310 		else
2311 			return OSC_HZ;
2312 	case SCMI_KEYLADDER_CORE:
2313 		src = readl(SCRU_BASE + RK3588_CLKSEL_CON(2)) & 0x00c0;
2314 		src = src >> 6;
2315 		if (src == 0)
2316 			return 350 * MHz;
2317 		else if (src == 1)
2318 			return 233 * MHz;
2319 		else if (src == 2)
2320 			return 116 * MHz;
2321 		else
2322 			return OSC_HZ;
2323 	case SCMI_KEYLADDER_RNG:
2324 		src = readl(SCRU_BASE + RK3588_CLKSEL_CON(2)) & 0x0300;
2325 		src = src >> 8;
2326 		if (src == 0)
2327 			return 175 * MHz;
2328 		else if (src == 1)
2329 			return 116 * MHz;
2330 		else if (src == 2)
2331 			return 58 * MHz;
2332 		else
2333 			return OSC_HZ;
2334 	case SCMI_TCLK_WDT:
2335 		return OSC_HZ;
2336 	case SCMI_HCLK_SD:
2337 	case SCMI_HCLK_SECURE_NS:
2338 		src = readl(SCRU_BASE + RK3588_CLKSEL_CON(1)) & 0x000c;
2339 		src = src >> 2;
2340 		if (src == 0)
2341 			return 150 * MHz;
2342 		else if (src == 1)
2343 			return 100 * MHz;
2344 		else if (src == 2)
2345 			return 50 * MHz;
2346 		else
2347 			return OSC_HZ;
2348 	default:
2349 		return -ENOENT;
2350 	}
2351 };
2352 
2353 static ulong rk3588_clk_scmi_set_rate(struct clk *clk, ulong rate)
2354 {
2355 	u32 src, div;
2356 
2357 	if ((readl(BUSSCRU_BASE + RK3588_PLL_CON(137)) & 0x01c0) == 0xc0) {
2358 		writel(BITS_WITH_WMASK(0, 0x3U, 0),
2359 			BUSSCRU_BASE + RK3588_MODE_CON0);
2360 		writel(BITS_WITH_WMASK(2, 0x7U, 6),
2361 			BUSSCRU_BASE + RK3588_PLL_CON(137));
2362 		writel(BITS_WITH_WMASK(1, 0x3U, 0),
2363 		       BUSSCRU_BASE + RK3588_MODE_CON0);
2364 	}
2365 
2366 	switch (clk->id) {
2367 	case SCMI_SPLL:
2368 		if (rate >= 700 * MHz)
2369 			src = 1;
2370 		else
2371 			src = 0;
2372 		writel(BITS_WITH_WMASK(0, 0x3U, 0),
2373 			BUSSCRU_BASE + RK3588_MODE_CON0);
2374 		writel(BITS_WITH_WMASK(2, 0x7U, 6),
2375 			BUSSCRU_BASE + RK3588_PLL_CON(137));
2376 		writel(BITS_WITH_WMASK(src, 0x3U, 0),
2377 		       BUSSCRU_BASE + RK3588_MODE_CON0);
2378 		break;
2379 	case SCMI_CCLK_SD:
2380 		if ((OSC_HZ % rate) == 0) {
2381 			div = DIV_ROUND_UP(OSC_HZ, rate);
2382 			writel(CLKDIV_6BITS_SHF(div - 1, 6) |
2383 			       BITS_WITH_WMASK(2U, 0x3U, 12),
2384 			       SCRU_BASE + RK3588_CLKSEL_CON(3));
2385 		} else if ((SPLL_RATE % rate) == 0) {
2386 			div = DIV_ROUND_UP(SPLL_RATE, rate);
2387 			writel(CLKDIV_6BITS_SHF(div - 1, 6) |
2388 			       BITS_WITH_WMASK(1U, 0x3U, 12),
2389 			       SCRU_BASE + RK3588_CLKSEL_CON(3));
2390 		} else {
2391 			div = DIV_ROUND_UP(GPLL_RATE, rate);
2392 			writel(CLKDIV_6BITS_SHF(div - 1, 6) |
2393 			       BITS_WITH_WMASK(0U, 0x3U, 12),
2394 			       SCRU_BASE + RK3588_CLKSEL_CON(3));
2395 		}
2396 		break;
2397 	case SCMI_DCLK_SD:
2398 		if ((SPLL_RATE % rate) == 0) {
2399 			div = DIV_ROUND_UP(SPLL_RATE, rate);
2400 			writel(CLKDIV_5BITS_SHF(div - 1, 0) |
2401 			       BITS_WITH_WMASK(1U, 0x1U, 5),
2402 			       SCRU_BASE + RK3588_CLKSEL_CON(3));
2403 		} else {
2404 			div = DIV_ROUND_UP(GPLL_RATE, rate);
2405 			writel(CLKDIV_5BITS_SHF(div - 1, 0) |
2406 			       BITS_WITH_WMASK(0U, 0x1U, 5),
2407 			       SCRU_BASE + RK3588_CLKSEL_CON(3));
2408 		}
2409 		break;
2410 	case SCMI_CRYPTO_RNG:
2411 		if (rate >= 175 * MHz)
2412 			src = 0;
2413 		else if (rate >= 116 * MHz)
2414 			src = 1;
2415 		else if (rate >= 58 * MHz)
2416 			src = 2;
2417 		else
2418 			src = 3;
2419 
2420 		writel(BITS_WITH_WMASK(src, 0x3U, 14),
2421 		       SCRU_BASE + RK3588_CLKSEL_CON(1));
2422 		break;
2423 	case SCMI_CRYPTO_CORE:
2424 		if (rate >= 350 * MHz)
2425 			src = 0;
2426 		else if (rate >= 233 * MHz)
2427 			src = 1;
2428 		else if (rate >= 116 * MHz)
2429 			src = 2;
2430 		else
2431 			src = 3;
2432 
2433 		writel(BITS_WITH_WMASK(src, 0x3U, 10),
2434 		       SCRU_BASE + RK3588_CLKSEL_CON(1));
2435 		break;
2436 	case SCMI_CRYPTO_PKA:
2437 		if (rate >= 350 * MHz)
2438 			src = 0;
2439 		else if (rate >= 233 * MHz)
2440 			src = 1;
2441 		else if (rate >= 116 * MHz)
2442 			src = 2;
2443 		else
2444 			src = 3;
2445 
2446 		writel(BITS_WITH_WMASK(src, 0x3U, 12),
2447 		       SCRU_BASE + RK3588_CLKSEL_CON(1));
2448 		break;
2449 	case SCMI_KEYLADDER_CORE:
2450 		if (rate >= 350 * MHz)
2451 			src = 0;
2452 		else if (rate >= 233 * MHz)
2453 			src = 1;
2454 		else if (rate >= 116 * MHz)
2455 			src = 2;
2456 		else
2457 			src = 3;
2458 
2459 		writel(BITS_WITH_WMASK(src, 0x3U, 6),
2460 		       SCRU_BASE + RK3588_CLKSEL_CON(2));
2461 		break;
2462 	case SCMI_KEYLADDER_RNG:
2463 		if (rate >= 175 * MHz)
2464 			src = 0;
2465 		else if (rate >= 116 * MHz)
2466 			src = 1;
2467 		else if (rate >= 58 * MHz)
2468 			src = 2;
2469 		else
2470 			src = 3;
2471 
2472 		writel(BITS_WITH_WMASK(src, 0x3U, 8),
2473 		       SCRU_BASE + RK3588_CLKSEL_CON(2));
2474 		break;
2475 	case SCMI_TCLK_WDT:
2476 		break;
2477 	case SCMI_HCLK_SD:
2478 	case SCMI_HCLK_SECURE_NS:
2479 		if (rate >= 150 * MHz)
2480 			src = 0;
2481 		else if (rate >= 100 * MHz)
2482 			src = 1;
2483 		else if (rate >= 50 * MHz)
2484 			src = 2;
2485 		else
2486 			src = 3;
2487 		writel(BITS_WITH_WMASK(src, 0x3U, 2),
2488 		       SCRU_BASE + RK3588_CLKSEL_CON(1));
2489 		break;
2490 	default:
2491 		return -ENOENT;
2492 	}
2493 	return 0;
2494 };
2495 
2496 /* A fake scmi driver for SPL/TPL where smccc agent is not available. */
2497 static const struct clk_ops scmi_clk_ops = {
2498 	.get_rate = rk3588_clk_scmi_get_rate,
2499 	.set_rate = rk3588_clk_scmi_set_rate,
2500 };
2501 
2502 U_BOOT_DRIVER(scmi_clock) = {
2503 	.name = "scmi_clk",
2504 	.id = UCLASS_CLK,
2505 	.ops = &scmi_clk_ops,
2506 };
2507 #endif
2508 
2509 #ifndef CONFIG_SPL_BUILD
2510 /**
2511  * soc_clk_dump() - Print clock frequencies
2512  * Returns zero on success
2513  *
2514  * Implementation for the clk dump command.
2515  */
2516 int soc_clk_dump(void)
2517 {
2518 	struct udevice *cru_dev;
2519 	struct rk3588_clk_priv *priv;
2520 	const struct rk3588_clk_info *clk_dump;
2521 	struct clk clk;
2522 	unsigned long clk_count = ARRAY_SIZE(clks_dump);
2523 	unsigned long rate;
2524 	int i, ret;
2525 
2526 	ret = uclass_get_device_by_driver(UCLASS_CLK,
2527 					  DM_GET_DRIVER(rockchip_rk3588_cru),
2528 					  &cru_dev);
2529 	if (ret) {
2530 		printf("%s failed to get cru device\n", __func__);
2531 		return ret;
2532 	}
2533 
2534 	priv = dev_get_priv(cru_dev);
2535 	printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n",
2536 	       priv->sync_kernel ? "sync kernel" : "uboot",
2537 	       priv->armclk_enter_hz / 1000,
2538 	       priv->armclk_init_hz / 1000,
2539 	       priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0,
2540 	       priv->set_armclk_rate ? " KHz" : "N/A");
2541 	for (i = 0; i < clk_count; i++) {
2542 		clk_dump = &clks_dump[i];
2543 		if (clk_dump->name) {
2544 			memset(&clk, 0, sizeof(struct clk));
2545 			clk.id = clk_dump->id;
2546 			if (clk_dump->is_cru)
2547 				ret = clk_request(cru_dev, &clk);
2548 			if (ret < 0)
2549 				return ret;
2550 
2551 			rate = clk_get_rate(&clk);
2552 			clk_free(&clk);
2553 			if (rate < 0)
2554 				printf("  %s %s\n", clk_dump->name,
2555 				       "unknown");
2556 			else
2557 				printf("  %s %lu KHz\n", clk_dump->name,
2558 				       rate / 1000);
2559 		}
2560 	}
2561 
2562 	return 0;
2563 }
2564 #endif
2565