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