xref: /OK3568_Linux_fs/u-boot/drivers/clk/rockchip/clk_rk3588.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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  */
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)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 
rk3588_center_get_clk(struct rk3588_clk_priv * priv,ulong clk_id)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 
rk3588_center_set_clk(struct rk3588_clk_priv * priv,ulong clk_id,ulong rate)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 
rk3588_top_get_clk(struct rk3588_clk_priv * priv,ulong clk_id)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 
rk3588_top_set_clk(struct rk3588_clk_priv * priv,ulong clk_id,ulong rate)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 
rk3588_i2c_get_clk(struct rk3588_clk_priv * priv,ulong clk_id)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 
rk3588_i2c_set_clk(struct rk3588_clk_priv * priv,ulong clk_id,ulong rate)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 
rk3588_spi_get_clk(struct rk3588_clk_priv * priv,ulong clk_id)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 
rk3588_spi_set_clk(struct rk3588_clk_priv * priv,ulong clk_id,ulong rate)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 
rk3588_pwm_get_clk(struct rk3588_clk_priv * priv,ulong clk_id)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 
rk3588_pwm_set_clk(struct rk3588_clk_priv * priv,ulong clk_id,ulong rate)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 
rk3588_adc_get_clk(struct rk3588_clk_priv * priv,ulong clk_id)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 
rk3588_adc_set_clk(struct rk3588_clk_priv * priv,ulong clk_id,ulong rate)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 
rk3588_mmc_get_clk(struct rk3588_clk_priv * priv,ulong clk_id)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 
rk3588_mmc_set_clk(struct rk3588_clk_priv * priv,ulong clk_id,ulong rate)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
rk3588_aux16m_get_clk(struct rk3588_clk_priv * priv,ulong clk_id)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 
rk3588_aux16m_set_clk(struct rk3588_clk_priv * priv,ulong clk_id,ulong rate)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 
rk3588_aclk_vop_get_clk(struct rk3588_clk_priv * priv,ulong clk_id)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 
rk3588_aclk_vop_set_clk(struct rk3588_clk_priv * priv,ulong clk_id,ulong rate)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 
rk3588_dclk_vop_get_clk(struct rk3588_clk_priv * priv,ulong clk_id)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 600000000
1107 
rk3588_dclk_vop_set_clk(struct rk3588_clk_priv * priv,ulong clk_id,ulong rate)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 			rk_clrsetreg(&cru->clksel_con[conid],
1168 				     mask,
1169 				     DCLK_VOP_SRC_SEL_V0PLL << sel_shift |
1170 				     ((div - 1) << div_shift));
1171 			rockchip_pll_set_rate(&rk3588_pll_clks[V0PLL],
1172 					      priv->cru, V0PLL, div * rate);
1173 		}
1174 	} else {
1175 		for (i = 0; i <= DCLK_VOP_SRC_SEL_AUPLL; i++) {
1176 			switch (i) {
1177 			case DCLK_VOP_SRC_SEL_GPLL:
1178 				pll_rate = priv->gpll_hz;
1179 				break;
1180 			case DCLK_VOP_SRC_SEL_CPLL:
1181 				pll_rate = priv->cpll_hz;
1182 				break;
1183 			case DCLK_VOP_SRC_SEL_AUPLL:
1184 				pll_rate = priv->aupll_hz;
1185 				break;
1186 			case DCLK_VOP_SRC_SEL_V0PLL:
1187 				pll_rate = 0;
1188 				break;
1189 			default:
1190 				printf("do not support this vop pll sel\n");
1191 				return -EINVAL;
1192 			}
1193 
1194 			div = DIV_ROUND_UP(pll_rate, rate);
1195 			if (div > 255)
1196 				continue;
1197 			now = pll_rate / div;
1198 			if (abs(rate - now) < abs(rate - best_rate)) {
1199 				best_rate = now;
1200 				best_div = div;
1201 				best_sel = i;
1202 			}
1203 			debug("p_rate=%lu, best_rate=%lu, div=%u, sel=%u\n",
1204 			      pll_rate, best_rate, best_div, best_sel);
1205 		}
1206 
1207 		if (best_rate) {
1208 			rk_clrsetreg(&cru->clksel_con[conid],
1209 				     mask,
1210 				     best_sel << sel_shift |
1211 				     (best_div - 1) << div_shift);
1212 		} else {
1213 			printf("do not support this vop freq %lu\n", rate);
1214 			return -EINVAL;
1215 		}
1216 	}
1217 	return rk3588_dclk_vop_get_clk(priv, clk_id);
1218 }
1219 
rk3588_gmac_get_clk(struct rk3588_clk_priv * priv,ulong clk_id)1220 static ulong rk3588_gmac_get_clk(struct rk3588_clk_priv *priv, ulong clk_id)
1221 {
1222 	struct rk3588_cru *cru = priv->cru;
1223 	u32 con, div;
1224 
1225 	switch (clk_id) {
1226 	case CLK_GMAC0_PTP_REF:
1227 		con = readl(&cru->clksel_con[81]);
1228 		div = (con & CLK_GMAC0_PTP_DIV_MASK) >> CLK_GMAC0_PTP_DIV_SHIFT;
1229 		return DIV_TO_RATE(priv->cpll_hz, div);
1230 	case CLK_GMAC1_PTP_REF:
1231 		con = readl(&cru->clksel_con[81]);
1232 		div = (con & CLK_GMAC1_PTP_DIV_MASK) >> CLK_GMAC1_PTP_DIV_SHIFT;
1233 		return DIV_TO_RATE(priv->cpll_hz, div);
1234 	case CLK_GMAC_125M:
1235 		con = readl(&cru->clksel_con[83]);
1236 		div = (con & CLK_GMAC_125M_DIV_MASK) >> CLK_GMAC_125M_DIV_SHIFT;
1237 		return DIV_TO_RATE(priv->cpll_hz, div);
1238 	case CLK_GMAC_50M:
1239 		con = readl(&cru->clksel_con[84]);
1240 		div = (con & CLK_GMAC_50M_DIV_MASK) >> CLK_GMAC_50M_DIV_SHIFT;
1241 		return DIV_TO_RATE(priv->cpll_hz, div);
1242 	default:
1243 		return -ENOENT;
1244 	}
1245 }
1246 
rk3588_gmac_set_clk(struct rk3588_clk_priv * priv,ulong clk_id,ulong rate)1247 static ulong rk3588_gmac_set_clk(struct rk3588_clk_priv *priv,
1248 				 ulong clk_id, ulong rate)
1249 {
1250 	struct rk3588_cru *cru = priv->cru;
1251 	int div;
1252 
1253 	div = DIV_ROUND_UP(priv->cpll_hz, rate);
1254 
1255 	switch (clk_id) {
1256 	case CLK_GMAC0_PTP_REF:
1257 		rk_clrsetreg(&cru->clksel_con[81],
1258 			     CLK_GMAC0_PTP_DIV_MASK | CLK_GMAC0_PTP_SEL_MASK,
1259 			     CLK_GMAC0_PTP_SEL_CPLL << CLK_GMAC0_PTP_SEL_SHIFT |
1260 			     (div - 1) << CLK_GMAC0_PTP_DIV_SHIFT);
1261 		break;
1262 	case CLK_GMAC1_PTP_REF:
1263 		rk_clrsetreg(&cru->clksel_con[81],
1264 			     CLK_GMAC1_PTP_DIV_MASK | CLK_GMAC1_PTP_SEL_MASK,
1265 			     CLK_GMAC1_PTP_SEL_CPLL << CLK_GMAC1_PTP_SEL_SHIFT |
1266 			     (div - 1) << CLK_GMAC1_PTP_DIV_SHIFT);
1267 		break;
1268 
1269 	case CLK_GMAC_125M:
1270 		rk_clrsetreg(&cru->clksel_con[83],
1271 			     CLK_GMAC_125M_DIV_MASK | CLK_GMAC_125M_SEL_MASK,
1272 			     CLK_GMAC_125M_SEL_CPLL << CLK_GMAC_125M_SEL_SHIFT |
1273 			     (div - 1) << CLK_GMAC_125M_DIV_SHIFT);
1274 		break;
1275 	case CLK_GMAC_50M:
1276 		rk_clrsetreg(&cru->clksel_con[84],
1277 			     CLK_GMAC_50M_DIV_MASK | CLK_GMAC_50M_SEL_MASK,
1278 			     CLK_GMAC_50M_SEL_CPLL << CLK_GMAC_50M_SEL_SHIFT |
1279 			     (div - 1) << CLK_GMAC_50M_DIV_SHIFT);
1280 		break;
1281 	default:
1282 		return -ENOENT;
1283 	}
1284 
1285 	return rk3588_gmac_get_clk(priv, clk_id);
1286 }
1287 
rk3588_uart_get_rate(struct rk3588_clk_priv * priv,ulong clk_id)1288 static ulong rk3588_uart_get_rate(struct rk3588_clk_priv *priv, ulong clk_id)
1289 {
1290 	struct rk3588_cru *cru = priv->cru;
1291 	u32 reg, con, fracdiv, div, src, p_src, p_rate;
1292 	unsigned long m, n;
1293 
1294 	switch (clk_id) {
1295 	case SCLK_UART1:
1296 		reg = 41;
1297 		break;
1298 	case SCLK_UART2:
1299 		reg = 43;
1300 		break;
1301 	case SCLK_UART3:
1302 		reg = 45;
1303 		break;
1304 	case SCLK_UART4:
1305 		reg = 47;
1306 		break;
1307 	case SCLK_UART5:
1308 		reg = 49;
1309 		break;
1310 	case SCLK_UART6:
1311 		reg = 51;
1312 		break;
1313 	case SCLK_UART7:
1314 		reg = 53;
1315 		break;
1316 	case SCLK_UART8:
1317 		reg = 55;
1318 		break;
1319 	case SCLK_UART9:
1320 		reg = 57;
1321 		break;
1322 	default:
1323 		return -ENOENT;
1324 	}
1325 	con = readl(&cru->clksel_con[reg + 2]);
1326 	src = (con & CLK_UART_SEL_MASK) >> CLK_UART_SEL_SHIFT;
1327 	con = readl(&cru->clksel_con[reg]);
1328 	div = (con & CLK_UART_SRC_DIV_MASK) >> CLK_UART_SRC_DIV_SHIFT;
1329 	p_src = (con & CLK_UART_SRC_SEL_MASK) >> CLK_UART_SRC_SEL_SHIFT;
1330 	if (p_src == CLK_UART_SRC_SEL_GPLL)
1331 		p_rate = priv->gpll_hz;
1332 	else
1333 		p_rate = priv->cpll_hz;
1334 
1335 	if (src == CLK_UART_SEL_SRC) {
1336 		return DIV_TO_RATE(p_rate, div);
1337 	} else if (src == CLK_UART_SEL_FRAC) {
1338 		fracdiv = readl(&cru->clksel_con[reg + 1]);
1339 		n = fracdiv & CLK_UART_FRAC_NUMERATOR_MASK;
1340 		n >>= CLK_UART_FRAC_NUMERATOR_SHIFT;
1341 		m = fracdiv & CLK_UART_FRAC_DENOMINATOR_MASK;
1342 		m >>= CLK_UART_FRAC_DENOMINATOR_SHIFT;
1343 		return DIV_TO_RATE(p_rate, div) * n / m;
1344 	} else {
1345 		return OSC_HZ;
1346 	}
1347 }
1348 
rk3588_uart_set_rate(struct rk3588_clk_priv * priv,ulong clk_id,ulong rate)1349 static ulong rk3588_uart_set_rate(struct rk3588_clk_priv *priv,
1350 				  ulong clk_id, ulong rate)
1351 {
1352 	struct rk3588_cru *cru = priv->cru;
1353 	u32 reg, clk_src, uart_src, div;
1354 	unsigned long m = 0, n = 0, val;
1355 
1356 	if (priv->gpll_hz % rate == 0) {
1357 		clk_src = CLK_UART_SRC_SEL_GPLL;
1358 		uart_src = CLK_UART_SEL_SRC;
1359 		div = DIV_ROUND_UP(priv->gpll_hz, rate);
1360 	} else if (priv->cpll_hz % rate == 0) {
1361 		clk_src = CLK_UART_SRC_SEL_CPLL;
1362 		uart_src = CLK_UART_SEL_SRC;
1363 		div = DIV_ROUND_UP(priv->gpll_hz, rate);
1364 	} else if (rate == OSC_HZ) {
1365 		clk_src = CLK_UART_SRC_SEL_GPLL;
1366 		uart_src = CLK_UART_SEL_XIN24M;
1367 		div = 2;
1368 	} else {
1369 		clk_src = CLK_UART_SRC_SEL_GPLL;
1370 		uart_src = CLK_UART_SEL_FRAC;
1371 		div = 2;
1372 		rational_best_approximation(rate, priv->gpll_hz / div,
1373 					    GENMASK(16 - 1, 0),
1374 					    GENMASK(16 - 1, 0),
1375 					    &m, &n);
1376 	}
1377 
1378 	switch (clk_id) {
1379 	case SCLK_UART1:
1380 		reg = 41;
1381 		break;
1382 	case SCLK_UART2:
1383 		reg = 43;
1384 		break;
1385 	case SCLK_UART3:
1386 		reg = 45;
1387 		break;
1388 	case SCLK_UART4:
1389 		reg = 47;
1390 		break;
1391 	case SCLK_UART5:
1392 		reg = 49;
1393 		break;
1394 	case SCLK_UART6:
1395 		reg = 51;
1396 		break;
1397 	case SCLK_UART7:
1398 		reg = 53;
1399 		break;
1400 	case SCLK_UART8:
1401 		reg = 55;
1402 		break;
1403 	case SCLK_UART9:
1404 		reg = 57;
1405 		break;
1406 	default:
1407 		return -ENOENT;
1408 	}
1409 	rk_clrsetreg(&cru->clksel_con[reg],
1410 		     CLK_UART_SRC_SEL_MASK |
1411 		     CLK_UART_SRC_DIV_MASK,
1412 		     (clk_src << CLK_UART_SRC_SEL_SHIFT) |
1413 		     ((div - 1) << CLK_UART_SRC_DIV_SHIFT));
1414 	rk_clrsetreg(&cru->clksel_con[reg + 2],
1415 		     CLK_UART_SEL_MASK,
1416 		     (uart_src << CLK_UART_SEL_SHIFT));
1417 	if (m && n) {
1418 		val = m << CLK_UART_FRAC_NUMERATOR_SHIFT | n;
1419 		writel(val, &cru->clksel_con[reg + 1]);
1420 	}
1421 
1422 	return rk3588_uart_get_rate(priv, clk_id);
1423 }
1424 
rk3588_pciephy_get_rate(struct rk3588_clk_priv * priv,ulong clk_id)1425 static ulong rk3588_pciephy_get_rate(struct rk3588_clk_priv *priv, ulong clk_id)
1426 {
1427 	struct rk3588_cru *cru = priv->cru;
1428 	u32 con, div, src;
1429 
1430 	switch (clk_id) {
1431 	case CLK_REF_PIPE_PHY0:
1432 		con = readl(&cru->clksel_con[177]);
1433 		src = (con & CLK_PCIE_PHY0_REF_SEL_MASK) >> CLK_PCIE_PHY0_REF_SEL_SHIFT;
1434 		con = readl(&cru->clksel_con[176]);
1435 		div = (con & CLK_PCIE_PHY0_PLL_DIV_MASK) >> CLK_PCIE_PHY0_PLL_DIV_SHIFT;
1436 		break;
1437 	case CLK_REF_PIPE_PHY1:
1438 		con = readl(&cru->clksel_con[177]);
1439 		src = (con & CLK_PCIE_PHY1_REF_SEL_MASK) >> CLK_PCIE_PHY1_REF_SEL_SHIFT;
1440 		con = readl(&cru->clksel_con[176]);
1441 		div = (con & CLK_PCIE_PHY1_PLL_DIV_MASK) >> CLK_PCIE_PHY1_PLL_DIV_SHIFT;
1442 		break;
1443 	case CLK_REF_PIPE_PHY2:
1444 		con = readl(&cru->clksel_con[177]);
1445 		src = (con & CLK_PCIE_PHY2_REF_SEL_MASK) >> CLK_PCIE_PHY2_REF_SEL_SHIFT;
1446 		div = (con & CLK_PCIE_PHY2_PLL_DIV_MASK) >> CLK_PCIE_PHY2_PLL_DIV_SHIFT;
1447 		break;
1448 	default:
1449 		return -ENOENT;
1450 	}
1451 
1452 	if (src == CLK_PCIE_PHY_REF_SEL_PPLL) {
1453 		return DIV_TO_RATE(priv->ppll_hz, div);
1454 	} else {
1455 		return OSC_HZ;
1456 	}
1457 }
1458 
rk3588_pciephy_set_rate(struct rk3588_clk_priv * priv,ulong clk_id,ulong rate)1459 static ulong rk3588_pciephy_set_rate(struct rk3588_clk_priv *priv,
1460 				  ulong clk_id, ulong rate)
1461 {
1462 	struct rk3588_cru *cru = priv->cru;
1463 	u32 clk_src, div;
1464 
1465 	if (rate == OSC_HZ) {
1466 		clk_src = CLK_PCIE_PHY_REF_SEL_24M;
1467 		div = 1;
1468 	} else {
1469 		clk_src = CLK_PCIE_PHY_REF_SEL_PPLL;
1470 		div = DIV_ROUND_UP(priv->ppll_hz, rate);
1471 	}
1472 
1473 	switch (clk_id) {
1474 	case CLK_REF_PIPE_PHY0:
1475 		rk_clrsetreg(&cru->clksel_con[177],
1476 		     CLK_PCIE_PHY0_REF_SEL_MASK,
1477 		     (clk_src << CLK_PCIE_PHY0_REF_SEL_SHIFT));
1478 		rk_clrsetreg(&cru->clksel_con[176],
1479 		     CLK_PCIE_PHY0_PLL_DIV_MASK,
1480 		     ((div - 1) << CLK_PCIE_PHY0_PLL_DIV_SHIFT));
1481 		break;
1482 	case CLK_REF_PIPE_PHY1:
1483 		rk_clrsetreg(&cru->clksel_con[177],
1484 		     CLK_PCIE_PHY1_REF_SEL_MASK,
1485 		     (clk_src << CLK_PCIE_PHY1_REF_SEL_SHIFT));
1486 		rk_clrsetreg(&cru->clksel_con[176],
1487 		     CLK_PCIE_PHY1_PLL_DIV_MASK,
1488 		     ((div - 1) << CLK_PCIE_PHY1_PLL_DIV_SHIFT));
1489 		break;
1490 	case CLK_REF_PIPE_PHY2:
1491 		rk_clrsetreg(&cru->clksel_con[177],
1492 		     CLK_PCIE_PHY2_REF_SEL_MASK |
1493 		     CLK_PCIE_PHY2_PLL_DIV_MASK,
1494 		     (clk_src << CLK_PCIE_PHY2_REF_SEL_SHIFT) |
1495 		     ((div - 1) << CLK_PCIE_PHY2_PLL_DIV_SHIFT));
1496 		break;
1497 	default:
1498 		return -ENOENT;
1499 	}
1500 
1501 	return rk3588_pciephy_get_rate(priv, clk_id);
1502 }
1503 #endif
1504 
rk3588_clk_get_rate(struct clk * clk)1505 static ulong rk3588_clk_get_rate(struct clk *clk)
1506 {
1507 	struct rk3588_clk_priv *priv = dev_get_priv(clk->dev);
1508 	ulong rate = 0;
1509 
1510 	if (!priv->gpll_hz) {
1511 		printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
1512 		return -ENOENT;
1513 	}
1514 
1515 	if (!priv->ppll_hz) {
1516 		priv->ppll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[PPLL],
1517 						      priv->cru, PPLL);
1518 	}
1519 
1520 	switch (clk->id) {
1521 	case PLL_LPLL:
1522 		rate = rockchip_pll_get_rate(&rk3588_pll_clks[LPLL], priv->cru,
1523 					     LPLL);
1524 		break;
1525 	case PLL_B0PLL:
1526 		rate = rockchip_pll_get_rate(&rk3588_pll_clks[B0PLL], priv->cru,
1527 					     B0PLL);
1528 		break;
1529 	case PLL_B1PLL:
1530 		rate = rockchip_pll_get_rate(&rk3588_pll_clks[B1PLL], priv->cru,
1531 					     B1PLL);
1532 		break;
1533 	case PLL_GPLL:
1534 		rate = rockchip_pll_get_rate(&rk3588_pll_clks[GPLL], priv->cru,
1535 					     GPLL);
1536 		break;
1537 	case PLL_CPLL:
1538 		rate = rockchip_pll_get_rate(&rk3588_pll_clks[CPLL], priv->cru,
1539 					     CPLL);
1540 		break;
1541 	case PLL_NPLL:
1542 		rate = rockchip_pll_get_rate(&rk3588_pll_clks[NPLL], priv->cru,
1543 					     NPLL);
1544 		break;
1545 	case PLL_V0PLL:
1546 		rate = rockchip_pll_get_rate(&rk3588_pll_clks[V0PLL], priv->cru,
1547 					     V0PLL);
1548 		break;
1549 	case PLL_AUPLL:
1550 		rate = rockchip_pll_get_rate(&rk3588_pll_clks[AUPLL], priv->cru,
1551 					     AUPLL);
1552 		break;
1553 	case PLL_PPLL:
1554 		rate = rockchip_pll_get_rate(&rk3588_pll_clks[PPLL], priv->cru,
1555 					     PPLL);
1556 		break;
1557 	case ACLK_CENTER_ROOT:
1558 	case PCLK_CENTER_ROOT:
1559 	case HCLK_CENTER_ROOT:
1560 	case ACLK_CENTER_LOW_ROOT:
1561 		rate = rk3588_center_get_clk(priv, clk->id);
1562 		break;
1563 	case ACLK_TOP_ROOT:
1564 	case PCLK_TOP_ROOT:
1565 	case ACLK_LOW_TOP_ROOT:
1566 		rate = rk3588_top_get_clk(priv, clk->id);
1567 		break;
1568 	case CLK_I2C0:
1569 	case CLK_I2C1:
1570 	case CLK_I2C2:
1571 	case CLK_I2C3:
1572 	case CLK_I2C4:
1573 	case CLK_I2C5:
1574 	case CLK_I2C6:
1575 	case CLK_I2C7:
1576 	case CLK_I2C8:
1577 		rate = rk3588_i2c_get_clk(priv, clk->id);
1578 		break;
1579 	case CLK_SPI0:
1580 	case CLK_SPI1:
1581 	case CLK_SPI2:
1582 	case CLK_SPI3:
1583 	case CLK_SPI4:
1584 		rate = rk3588_spi_get_clk(priv, clk->id);
1585 		break;
1586 	case CLK_PWM1:
1587 	case CLK_PWM2:
1588 	case CLK_PWM3:
1589 	case CLK_PMU1PWM:
1590 		rate = rk3588_pwm_get_clk(priv, clk->id);
1591 		break;
1592 	case CLK_SARADC:
1593 	case CLK_TSADC:
1594 		rate = rk3588_adc_get_clk(priv, clk->id);
1595 		break;
1596 	case CCLK_SRC_SDIO:
1597 	case CCLK_EMMC:
1598 	case BCLK_EMMC:
1599 	case SCLK_SFC:
1600 	case DCLK_DECOM:
1601 		rate = rk3588_mmc_get_clk(priv, clk->id);
1602 		break;
1603 	case TCLK_WDT0:
1604 		rate = OSC_HZ;
1605 		break;
1606 #ifndef CONFIG_SPL_BUILD
1607 	case CLK_AUX16M_0:
1608 	case CLK_AUX16M_1:
1609 		rk3588_aux16m_get_clk(priv, clk->id);
1610 		break;
1611 	case ACLK_VOP_ROOT:
1612 	case ACLK_VOP:
1613 	case ACLK_VOP_LOW_ROOT:
1614 	case HCLK_VOP_ROOT:
1615 		rate = rk3588_aclk_vop_get_clk(priv, clk->id);
1616 		break;
1617 	case DCLK_VOP0:
1618 	case DCLK_VOP0_SRC:
1619 	case DCLK_VOP1:
1620 	case DCLK_VOP1_SRC:
1621 	case DCLK_VOP2:
1622 	case DCLK_VOP2_SRC:
1623 	case DCLK_VOP3:
1624 		rate = rk3588_dclk_vop_get_clk(priv, clk->id);
1625 		break;
1626 	case CLK_GMAC0_PTP_REF:
1627 	case CLK_GMAC1_PTP_REF:
1628 	case CLK_GMAC_125M:
1629 	case CLK_GMAC_50M:
1630 		rate = rk3588_gmac_get_clk(priv, clk->id);
1631 		break;
1632 	case SCLK_UART1:
1633 	case SCLK_UART2:
1634 	case SCLK_UART3:
1635 	case SCLK_UART4:
1636 	case SCLK_UART5:
1637 	case SCLK_UART6:
1638 	case SCLK_UART7:
1639 	case SCLK_UART8:
1640 	case SCLK_UART9:
1641 		rate = rk3588_uart_get_rate(priv, clk->id);
1642 		break;
1643 	case CLK_REF_PIPE_PHY0:
1644 	case CLK_REF_PIPE_PHY1:
1645 	case CLK_REF_PIPE_PHY2:
1646 		rate = rk3588_pciephy_get_rate(priv, clk->id);
1647 		break;
1648 #endif
1649 	default:
1650 		return -ENOENT;
1651 	}
1652 
1653 	return rate;
1654 };
1655 
rk3588_clk_set_rate(struct clk * clk,ulong rate)1656 static ulong rk3588_clk_set_rate(struct clk *clk, ulong rate)
1657 {
1658 	struct rk3588_clk_priv *priv = dev_get_priv(clk->dev);
1659 	ulong ret = 0;
1660 
1661 	if (!priv->gpll_hz) {
1662 		printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
1663 		return -ENOENT;
1664 	}
1665 
1666 	if (!priv->ppll_hz) {
1667 		priv->ppll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[PPLL],
1668 						      priv->cru, PPLL);
1669 	}
1670 
1671 	switch (clk->id) {
1672 	case PLL_CPLL:
1673 		ret = rockchip_pll_set_rate(&rk3588_pll_clks[CPLL], priv->cru,
1674 					    CPLL, rate);
1675 		priv->cpll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[CPLL],
1676 						      priv->cru, CPLL);
1677 		break;
1678 	case PLL_GPLL:
1679 		ret = rockchip_pll_set_rate(&rk3588_pll_clks[GPLL], priv->cru,
1680 					    GPLL, rate);
1681 		priv->gpll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[GPLL],
1682 						      priv->cru, GPLL);
1683 		break;
1684 	case PLL_NPLL:
1685 		ret = rockchip_pll_set_rate(&rk3588_pll_clks[NPLL], priv->cru,
1686 					    NPLL, rate);
1687 		break;
1688 	case PLL_V0PLL:
1689 		ret = rockchip_pll_set_rate(&rk3588_pll_clks[V0PLL], priv->cru,
1690 					    V0PLL, rate);
1691 		priv->v0pll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[V0PLL],
1692 						       priv->cru, V0PLL);
1693 		break;
1694 	case PLL_AUPLL:
1695 		ret = rockchip_pll_set_rate(&rk3588_pll_clks[AUPLL], priv->cru,
1696 					    AUPLL, rate);
1697 		priv->aupll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[AUPLL],
1698 						       priv->cru, AUPLL);
1699 		break;
1700 	case PLL_PPLL:
1701 		ret = rockchip_pll_set_rate(&rk3588_pll_clks[PPLL], priv->cru,
1702 					    PPLL, rate);
1703 		priv->ppll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[PPLL],
1704 						      priv->cru, PPLL);
1705 		break;
1706 	case ACLK_CENTER_ROOT:
1707 	case PCLK_CENTER_ROOT:
1708 	case HCLK_CENTER_ROOT:
1709 	case ACLK_CENTER_LOW_ROOT:
1710 		ret = rk3588_center_set_clk(priv, clk->id, rate);
1711 		break;
1712 	case ACLK_TOP_ROOT:
1713 	case PCLK_TOP_ROOT:
1714 	case ACLK_LOW_TOP_ROOT:
1715 		ret = rk3588_top_set_clk(priv, clk->id, rate);
1716 		break;
1717 	case CLK_I2C0:
1718 	case CLK_I2C1:
1719 	case CLK_I2C2:
1720 	case CLK_I2C3:
1721 	case CLK_I2C4:
1722 	case CLK_I2C5:
1723 	case CLK_I2C6:
1724 	case CLK_I2C7:
1725 	case CLK_I2C8:
1726 		ret = rk3588_i2c_set_clk(priv, clk->id, rate);
1727 		break;
1728 	case CLK_SPI0:
1729 	case CLK_SPI1:
1730 	case CLK_SPI2:
1731 	case CLK_SPI3:
1732 	case CLK_SPI4:
1733 		ret = rk3588_spi_set_clk(priv, clk->id, rate);
1734 		break;
1735 	case CLK_PWM1:
1736 	case CLK_PWM2:
1737 	case CLK_PWM3:
1738 	case CLK_PMU1PWM:
1739 		ret = rk3588_pwm_set_clk(priv, clk->id, rate);
1740 		break;
1741 	case CLK_SARADC:
1742 	case CLK_TSADC:
1743 		ret = rk3588_adc_set_clk(priv, clk->id, rate);
1744 		break;
1745 	case CCLK_SRC_SDIO:
1746 	case CCLK_EMMC:
1747 	case BCLK_EMMC:
1748 	case SCLK_SFC:
1749 	case DCLK_DECOM:
1750 		ret = rk3588_mmc_set_clk(priv, clk->id, rate);
1751 		break;
1752 	case TCLK_WDT0:
1753 		ret = OSC_HZ;
1754 		break;
1755 #ifndef CONFIG_SPL_BUILD
1756 	case CLK_AUX16M_0:
1757 	case CLK_AUX16M_1:
1758 		rk3588_aux16m_set_clk(priv, clk->id, rate);
1759 		break;
1760 	case ACLK_VOP_ROOT:
1761 	case ACLK_VOP:
1762 	case ACLK_VOP_LOW_ROOT:
1763 	case HCLK_VOP_ROOT:
1764 		ret = rk3588_aclk_vop_set_clk(priv, clk->id, rate);
1765 		break;
1766 	case DCLK_VOP0:
1767 	case DCLK_VOP0_SRC:
1768 	case DCLK_VOP1:
1769 	case DCLK_VOP1_SRC:
1770 	case DCLK_VOP2:
1771 	case DCLK_VOP2_SRC:
1772 	case DCLK_VOP3:
1773 		ret = rk3588_dclk_vop_set_clk(priv, clk->id, rate);
1774 		break;
1775 	case CLK_GMAC0_PTP_REF:
1776 	case CLK_GMAC1_PTP_REF:
1777 	case CLK_GMAC_125M:
1778 	case CLK_GMAC_50M:
1779 		ret = rk3588_gmac_set_clk(priv, clk->id, rate);
1780 		break;
1781 	case SCLK_UART1:
1782 	case SCLK_UART2:
1783 	case SCLK_UART3:
1784 	case SCLK_UART4:
1785 	case SCLK_UART5:
1786 	case SCLK_UART6:
1787 	case SCLK_UART7:
1788 	case SCLK_UART8:
1789 	case SCLK_UART9:
1790 		ret = rk3588_uart_set_rate(priv, clk->id, rate);
1791 		break;
1792 	case CLK_REF_PIPE_PHY0:
1793 	case CLK_REF_PIPE_PHY1:
1794 	case CLK_REF_PIPE_PHY2:
1795 		ret = rk3588_pciephy_set_rate(priv, clk->id, rate);
1796 		break;
1797 #endif
1798 	default:
1799 		return -ENOENT;
1800 	}
1801 
1802 	return ret;
1803 };
1804 
1805 #define ROCKCHIP_MMC_DELAY_SEL		BIT(10)
1806 #define ROCKCHIP_MMC_DEGREE_MASK	0x3
1807 #define ROCKCHIP_MMC_DELAYNUM_OFFSET	2
1808 #define ROCKCHIP_MMC_DELAYNUM_MASK	(0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
1809 
1810 #define PSECS_PER_SEC 1000000000000LL
1811 /*
1812  * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to
1813  * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg.
1814  */
1815 #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60
1816 
rk3588_mmc_get_phase(struct clk * clk)1817 int rk3588_mmc_get_phase(struct clk *clk)
1818 {
1819 	struct rk3588_clk_priv *priv = dev_get_priv(clk->dev);
1820 	struct rk3588_cru *cru = priv->cru;
1821 	u32 raw_value, delay_num;
1822 	u16 degrees = 0;
1823 	ulong rate;
1824 
1825 	rate = rk3588_clk_get_rate(clk);
1826 	if (rate <= 0)
1827 		return rate;
1828 
1829 	if (clk->id == SCLK_SDMMC_SAMPLE)
1830 		raw_value = readl(&cru->sdmmc_con[1]);
1831 	else
1832 		return 0;
1833 
1834 	raw_value >>= 1;
1835 	degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90;
1836 
1837 	if (raw_value & ROCKCHIP_MMC_DELAY_SEL) {
1838 		/* degrees/delaynum * 10000 */
1839 		unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) *
1840 					36 * (rate / 1000000);
1841 
1842 		delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK);
1843 		delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET;
1844 		degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000);
1845 	}
1846 
1847 	return degrees % 360;
1848 }
1849 
rk3588_mmc_set_phase(struct clk * clk,u32 degrees)1850 int rk3588_mmc_set_phase(struct clk *clk, u32 degrees)
1851 {
1852 	struct rk3588_clk_priv *priv = dev_get_priv(clk->dev);
1853 	struct rk3588_cru *cru = priv->cru;
1854 	u8 nineties, remainder, delay_num;
1855 	u32 raw_value, delay;
1856 	ulong rate;
1857 
1858 	rate = rk3588_clk_get_rate(clk);
1859 	if (rate <= 0)
1860 		return rate;
1861 
1862 	nineties = degrees / 90;
1863 	remainder = (degrees % 90);
1864 
1865 	/*
1866 	 * Convert to delay; do a little extra work to make sure we
1867 	 * don't overflow 32-bit / 64-bit numbers.
1868 	 */
1869 	delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */
1870 	delay *= remainder;
1871 	delay = DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 *
1872 				  (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10));
1873 
1874 	delay_num = (u8)min_t(u32, delay, 255);
1875 
1876 	raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0;
1877 	raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET;
1878 	raw_value |= nineties;
1879 
1880 	raw_value <<= 1;
1881 	if (clk->id == SCLK_SDMMC_SAMPLE)
1882 		writel(raw_value | 0xffff0000, &cru->sdmmc_con[1]);
1883 
1884 	debug("mmc set_phase(%d) delay_nums=%u reg=%#x actual_degrees=%d\n",
1885 	      degrees, delay_num, raw_value, rk3588_mmc_get_phase(clk));
1886 
1887 	return 0;
1888 }
1889 
rk3588_clk_get_phase(struct clk * clk)1890 static int rk3588_clk_get_phase(struct clk *clk)
1891 {
1892 	int ret;
1893 
1894 	debug("%s %ld\n", __func__, clk->id);
1895 	switch (clk->id) {
1896 	case SCLK_SDMMC_SAMPLE:
1897 		ret = rk3588_mmc_get_phase(clk);
1898 		break;
1899 	default:
1900 		return -ENOENT;
1901 	}
1902 
1903 	return ret;
1904 }
1905 
rk3588_clk_set_phase(struct clk * clk,int degrees)1906 static int rk3588_clk_set_phase(struct clk *clk, int degrees)
1907 {
1908 	int ret;
1909 
1910 	debug("%s %ld\n", __func__, clk->id);
1911 	switch (clk->id) {
1912 	case SCLK_SDMMC_SAMPLE:
1913 		ret = rk3588_mmc_set_phase(clk, degrees);
1914 		break;
1915 	default:
1916 		return -ENOENT;
1917 	}
1918 
1919 	return ret;
1920 }
1921 
1922 #if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA))
rk3588_dclk_vop_set_parent(struct clk * clk,struct clk * parent)1923 static int __maybe_unused rk3588_dclk_vop_set_parent(struct clk *clk,
1924 						     struct clk *parent)
1925 {
1926 	struct rk3588_clk_priv *priv = dev_get_priv(clk->dev);
1927 	struct rk3588_cru *cru = priv->cru;
1928 	u32 sel;
1929 	const char *clock_dev_name = parent->dev->name;
1930 
1931 	if (parent->id == PLL_V0PLL)
1932 		sel = 2;
1933 	else if (parent->id == PLL_GPLL)
1934 		sel = 0;
1935 	else if (parent->id == PLL_CPLL)
1936 		sel = 1;
1937 	else
1938 		sel = 3;
1939 
1940 	switch (clk->id) {
1941 	case DCLK_VOP0_SRC:
1942 		rk_clrsetreg(&cru->clksel_con[111], DCLK0_VOP_SRC_SEL_MASK,
1943 			     sel << DCLK0_VOP_SRC_SEL_SHIFT);
1944 		break;
1945 	case DCLK_VOP1_SRC:
1946 		rk_clrsetreg(&cru->clksel_con[111], DCLK1_VOP_SRC_SEL_MASK,
1947 			     sel << DCLK1_VOP_SRC_SEL_SHIFT);
1948 		break;
1949 	case DCLK_VOP2_SRC:
1950 		rk_clrsetreg(&cru->clksel_con[112], DCLK2_VOP_SRC_SEL_MASK,
1951 			     sel << DCLK2_VOP_SRC_SEL_SHIFT);
1952 		break;
1953 	case DCLK_VOP3:
1954 		rk_clrsetreg(&cru->clksel_con[113], DCLK3_VOP_SRC_SEL_MASK,
1955 			     sel << DCLK3_VOP_SRC_SEL_SHIFT);
1956 		break;
1957 	case DCLK_VOP0:
1958 		if (!strcmp(clock_dev_name, "hdmiphypll_clk0"))
1959 			sel = 1;
1960 		else if (!strcmp(clock_dev_name, "hdmiphypll_clk1"))
1961 			sel = 2;
1962 		else
1963 			sel = 0;
1964 		rk_clrsetreg(&cru->clksel_con[112], DCLK0_VOP_SEL_MASK,
1965 			     sel << DCLK0_VOP_SEL_SHIFT);
1966 		break;
1967 	case DCLK_VOP1:
1968 		if (!strcmp(clock_dev_name, "hdmiphypll_clk0"))
1969 			sel = 1;
1970 		else if (!strcmp(clock_dev_name, "hdmiphypll_clk1"))
1971 			sel = 2;
1972 		else
1973 			sel = 0;
1974 		rk_clrsetreg(&cru->clksel_con[112], DCLK1_VOP_SEL_MASK,
1975 			     sel << DCLK1_VOP_SEL_SHIFT);
1976 		break;
1977 	case DCLK_VOP2:
1978 		if (!strcmp(clock_dev_name, "hdmiphypll_clk0"))
1979 			sel = 1;
1980 		else if (!strcmp(clock_dev_name, "hdmiphypll_clk1"))
1981 			sel = 2;
1982 		else
1983 			sel = 0;
1984 		rk_clrsetreg(&cru->clksel_con[112], DCLK2_VOP_SEL_MASK,
1985 			     sel << DCLK2_VOP_SEL_SHIFT);
1986 		break;
1987 	default:
1988 		return -EINVAL;
1989 	}
1990 	return 0;
1991 }
1992 
rk3588_clk_set_parent(struct clk * clk,struct clk * parent)1993 static int rk3588_clk_set_parent(struct clk *clk, struct clk *parent)
1994 {
1995 	switch (clk->id) {
1996 	case DCLK_VOP0_SRC:
1997 	case DCLK_VOP1_SRC:
1998 	case DCLK_VOP2_SRC:
1999 	case DCLK_VOP0:
2000 	case DCLK_VOP1:
2001 	case DCLK_VOP2:
2002 	case DCLK_VOP3:
2003 		return rk3588_dclk_vop_set_parent(clk, parent);
2004 	default:
2005 		return -ENOENT;
2006 	}
2007 
2008 	return 0;
2009 }
2010 #endif
2011 
2012 static struct clk_ops rk3588_clk_ops = {
2013 	.get_rate = rk3588_clk_get_rate,
2014 	.set_rate = rk3588_clk_set_rate,
2015 	.get_phase = rk3588_clk_get_phase,
2016 	.set_phase = rk3588_clk_set_phase,
2017 #if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA))
2018 	.set_parent = rk3588_clk_set_parent,
2019 #endif
2020 };
2021 
rk3588_clk_init(struct rk3588_clk_priv * priv)2022 static void rk3588_clk_init(struct rk3588_clk_priv *priv)
2023 {
2024 	int ret, div;
2025 
2026 	div = DIV_ROUND_UP(GPLL_HZ, 300 * MHz);
2027 	rk_clrsetreg(&priv->cru->clksel_con[38],
2028 		     ACLK_BUS_ROOT_SEL_MASK |
2029 		     ACLK_BUS_ROOT_DIV_MASK,
2030 		     div << ACLK_BUS_ROOT_DIV_SHIFT);
2031 
2032 	if (priv->cpll_hz != CPLL_HZ) {
2033 		ret = rockchip_pll_set_rate(&rk3588_pll_clks[CPLL], priv->cru,
2034 					    CPLL, CPLL_HZ);
2035 		if (!ret)
2036 			priv->cpll_hz = CPLL_HZ;
2037 	}
2038 	if (priv->gpll_hz != GPLL_HZ) {
2039 		ret = rockchip_pll_set_rate(&rk3588_pll_clks[GPLL], priv->cru,
2040 					    GPLL, GPLL_HZ);
2041 		if (!ret)
2042 			priv->gpll_hz = GPLL_HZ;
2043 	}
2044 
2045 #ifdef CONFIG_PCI
2046 	if (priv->ppll_hz != PPLL_HZ) {
2047 		ret = rockchip_pll_set_rate(&rk3588_pll_clks[PPLL], priv->cru,
2048 					    PPLL, PPLL_HZ);
2049 		priv->ppll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[PPLL],
2050 						      priv->cru, PPLL);
2051 	}
2052 #endif
2053 	rk_clrsetreg(&priv->cru->clksel_con[9],
2054 		     ACLK_TOP_S400_SEL_MASK |
2055 		     ACLK_TOP_S200_SEL_MASK,
2056 		     (ACLK_TOP_S400_SEL_400M << ACLK_TOP_S400_SEL_SHIFT) |
2057 		     (ACLK_TOP_S200_SEL_200M << ACLK_TOP_S200_SEL_SHIFT));
2058 }
2059 
rk3588_clk_probe(struct udevice * dev)2060 static int rk3588_clk_probe(struct udevice *dev)
2061 {
2062 	struct rk3588_clk_priv *priv = dev_get_priv(dev);
2063 	int ret;
2064 	struct clk clk;
2065 
2066 	priv->sync_kernel = false;
2067 
2068 #ifdef CONFIG_SPL_BUILD
2069 	rockchip_pll_set_rate(&rk3588_pll_clks[B0PLL], priv->cru,
2070 			      B0PLL, LPLL_HZ);
2071 	rockchip_pll_set_rate(&rk3588_pll_clks[B1PLL], priv->cru,
2072 			      B1PLL, LPLL_HZ);
2073 	if (!priv->armclk_enter_hz) {
2074 		ret = rockchip_pll_set_rate(&rk3588_pll_clks[LPLL], priv->cru,
2075 					    LPLL, LPLL_HZ);
2076 		priv->armclk_enter_hz =
2077 			rockchip_pll_get_rate(&rk3588_pll_clks[LPLL],
2078 					      priv->cru, LPLL);
2079 		priv->armclk_init_hz = priv->armclk_enter_hz;
2080 	}
2081 #endif
2082 
2083 	ret = rockchip_get_scmi_clk(&clk.dev);
2084 	if (ret) {
2085 		printf("Failed to get scmi clk dev\n");
2086 		return ret;
2087 	}
2088 	clk.id = SCMI_SPLL;
2089 	ret = clk_set_rate(&clk, 702000000);
2090 	if (ret < 0) {
2091 		printf("Failed to set spll\n");
2092 	}
2093 
2094 #ifndef CONFIG_SPL_BUILD
2095 	if (!priv->armclk_enter_hz) {
2096 		clk.id = SCMI_CLK_CPUL;
2097 		ret = clk_set_rate(&clk, CPU_PVTPLL_HZ);
2098 		if (ret < 0) {
2099 			printf("Failed to set cpubl\n");
2100 		} else {
2101 			priv->armclk_enter_hz = CPU_PVTPLL_HZ;
2102 			priv->armclk_init_hz = CPU_PVTPLL_HZ;
2103 		}
2104 	}
2105 	clk.id = SCMI_CLK_CPUB01;
2106 	ret = clk_set_rate(&clk, CPU_PVTPLL_HZ);
2107 	if (ret < 0)
2108 		printf("Failed to set cpub01\n");
2109 	clk.id = SCMI_CLK_CPUB23;
2110 	ret = clk_set_rate(&clk, CPU_PVTPLL_HZ);
2111 	if (ret < 0)
2112 		printf("Failed to set cpub23\n");
2113 #endif
2114 
2115 	priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
2116 	if (IS_ERR(priv->grf))
2117 		return PTR_ERR(priv->grf);
2118 
2119 	rk3588_clk_init(priv);
2120 
2121 	/* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
2122 	ret = clk_set_defaults(dev);
2123 	if (ret)
2124 		debug("%s clk_set_defaults failed %d\n", __func__, ret);
2125 	else
2126 		priv->sync_kernel = true;
2127 
2128 	return 0;
2129 }
2130 
rk3588_clk_ofdata_to_platdata(struct udevice * dev)2131 static int rk3588_clk_ofdata_to_platdata(struct udevice *dev)
2132 {
2133 	struct rk3588_clk_priv *priv = dev_get_priv(dev);
2134 
2135 	priv->cru = dev_read_addr_ptr(dev);
2136 
2137 	return 0;
2138 }
2139 
rk3588_clk_bind(struct udevice * dev)2140 static int rk3588_clk_bind(struct udevice *dev)
2141 {
2142 	int ret;
2143 	struct udevice *sys_child, *sf_child;
2144 	struct sysreset_reg *priv;
2145 	struct softreset_reg *sf_priv;
2146 
2147 	/* The reset driver does not have a device node, so bind it here */
2148 	ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
2149 				 &sys_child);
2150 	if (ret) {
2151 		debug("Warning: No sysreset driver: ret=%d\n", ret);
2152 	} else {
2153 		priv = malloc(sizeof(struct sysreset_reg));
2154 		priv->glb_srst_fst_value = offsetof(struct rk3588_cru,
2155 						    glb_srst_fst);
2156 		priv->glb_srst_snd_value = offsetof(struct rk3588_cru,
2157 						    glb_srsr_snd);
2158 		sys_child->priv = priv;
2159 	}
2160 
2161 	ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset",
2162 					 dev_ofnode(dev), &sf_child);
2163 	if (ret) {
2164 		debug("Warning: No rockchip reset driver: ret=%d\n", ret);
2165 	} else {
2166 		sf_priv = malloc(sizeof(struct softreset_reg));
2167 		sf_priv->sf_reset_offset = offsetof(struct rk3588_cru,
2168 						    softrst_con[0]);
2169 		sf_priv->sf_reset_num = 49158;
2170 		sf_child->priv = sf_priv;
2171 	}
2172 
2173 	return 0;
2174 }
2175 
2176 static const struct udevice_id rk3588_clk_ids[] = {
2177 	{ .compatible = "rockchip,rk3588-cru" },
2178 	{ }
2179 };
2180 
2181 U_BOOT_DRIVER(rockchip_rk3588_cru) = {
2182 	.name		= "rockchip_rk3588_cru",
2183 	.id		= UCLASS_CLK,
2184 	.of_match	= rk3588_clk_ids,
2185 	.priv_auto_alloc_size = sizeof(struct rk3588_clk_priv),
2186 	.ofdata_to_platdata = rk3588_clk_ofdata_to_platdata,
2187 	.ops		= &rk3588_clk_ops,
2188 	.bind		= rk3588_clk_bind,
2189 	.probe		= rk3588_clk_probe,
2190 };
2191 
2192 #ifdef CONFIG_SPL_BUILD
2193 #define SCRU_BASE			0xfd7d0000
2194 #define BUSSCRU_BASE			0xfd7d8000
2195 #define GPLL_RATE			1188000000
2196 #define SPLL_RATE			702000000
2197 
2198 #ifndef BITS_WITH_WMASK
2199 #define BITS_WITH_WMASK(bits, msk, shift) \
2200 	((bits) << (shift)) | ((msk) << ((shift) + 16))
2201 #endif
2202 
2203 #define CLKDIV_6BITS_SHF(div, shift)	BITS_WITH_WMASK(div, 0x3fU, shift)
2204 #define CLKDIV_5BITS_SHF(div, shift)	BITS_WITH_WMASK(div, 0x1fU, shift)
2205 
rk3588_clk_scmi_get_rate(struct clk * clk)2206 static ulong rk3588_clk_scmi_get_rate(struct clk *clk)
2207 {
2208 	u32 src, div;
2209 
2210 	switch (clk->id) {
2211 	case SCMI_SPLL:
2212 		src = readl(BUSSCRU_BASE + RK3588_MODE_CON0) & 0x3;
2213 		if (src == 0)
2214 			return OSC_HZ;
2215 		else if (src == 1)
2216 			return 702 * MHz;
2217 		else
2218 			return 32768;
2219 	case SCMI_CCLK_SD:
2220 		src = readl(SCRU_BASE + RK3588_CLKSEL_CON(3)) & 0x3000;
2221 		src = src >> 12;
2222 		div = readl(SCRU_BASE + RK3588_CLKSEL_CON(3)) & 0x0fc0;
2223 		div = div >> 6;
2224 		if (src == 1)
2225 			return SPLL_RATE / (div + 1);
2226 		else if (src == 2)
2227 			return OSC_HZ / (div + 1);
2228 		else
2229 			return GPLL_RATE / (div + 1);
2230 	case SCMI_DCLK_SD:
2231 		src = readl(SCRU_BASE + RK3588_CLKSEL_CON(3)) & 0x0020;
2232 		div = readl(SCRU_BASE + RK3588_CLKSEL_CON(3)) & 0x001f;
2233 		if (src)
2234 			return SPLL_RATE / (div + 1);
2235 		else
2236 			return GPLL_RATE / (div + 1);
2237 	case SCMI_CRYPTO_RNG:
2238 		src = readl(SCRU_BASE + RK3588_CLKSEL_CON(1)) & 0xc000;
2239 		src = src >> 14;
2240 		if (src == 0)
2241 			return 175 * MHz;
2242 		else if (src == 1)
2243 			return 116 * MHz;
2244 		else if (src == 2)
2245 			return 58 * MHz;
2246 		else
2247 			return OSC_HZ;
2248 	case SCMI_CRYPTO_CORE:
2249 		src = readl(SCRU_BASE + RK3588_CLKSEL_CON(1)) & 0x0c00;
2250 		src = src >> 10;
2251 		if (src == 0)
2252 			return 350 * MHz;
2253 		else if (src == 1)
2254 			return 233 * MHz;
2255 		else if (src == 2)
2256 			return 116 * MHz;
2257 		else
2258 			return OSC_HZ;
2259 	case SCMI_CRYPTO_PKA:
2260 		src = readl(SCRU_BASE + RK3588_CLKSEL_CON(1)) & 0x3000;
2261 		src = src >> 12;
2262 		if (src == 0)
2263 			return 350 * MHz;
2264 		else if (src == 1)
2265 			return 233 * MHz;
2266 		else if (src == 2)
2267 			return 116 * MHz;
2268 		else
2269 			return OSC_HZ;
2270 	case SCMI_KEYLADDER_CORE:
2271 		src = readl(SCRU_BASE + RK3588_CLKSEL_CON(2)) & 0x00c0;
2272 		src = src >> 6;
2273 		if (src == 0)
2274 			return 350 * MHz;
2275 		else if (src == 1)
2276 			return 233 * MHz;
2277 		else if (src == 2)
2278 			return 116 * MHz;
2279 		else
2280 			return OSC_HZ;
2281 	case SCMI_KEYLADDER_RNG:
2282 		src = readl(SCRU_BASE + RK3588_CLKSEL_CON(2)) & 0x0300;
2283 		src = src >> 8;
2284 		if (src == 0)
2285 			return 175 * MHz;
2286 		else if (src == 1)
2287 			return 116 * MHz;
2288 		else if (src == 2)
2289 			return 58 * MHz;
2290 		else
2291 			return OSC_HZ;
2292 	case SCMI_TCLK_WDT:
2293 		return OSC_HZ;
2294 	case SCMI_HCLK_SD:
2295 	case SCMI_HCLK_SECURE_NS:
2296 		src = readl(SCRU_BASE + RK3588_CLKSEL_CON(1)) & 0x000c;
2297 		src = src >> 2;
2298 		if (src == 0)
2299 			return 150 * MHz;
2300 		else if (src == 1)
2301 			return 100 * MHz;
2302 		else if (src == 2)
2303 			return 50 * MHz;
2304 		else
2305 			return OSC_HZ;
2306 	default:
2307 		return -ENOENT;
2308 	}
2309 };
2310 
rk3588_clk_scmi_set_rate(struct clk * clk,ulong rate)2311 static ulong rk3588_clk_scmi_set_rate(struct clk *clk, ulong rate)
2312 {
2313 	u32 src, div;
2314 
2315 	if ((readl(BUSSCRU_BASE + RK3588_PLL_CON(137)) & 0x01c0) == 0xc0) {
2316 		writel(BITS_WITH_WMASK(0, 0x3U, 0),
2317 			BUSSCRU_BASE + RK3588_MODE_CON0);
2318 		writel(BITS_WITH_WMASK(2, 0x7U, 6),
2319 			BUSSCRU_BASE + RK3588_PLL_CON(137));
2320 		writel(BITS_WITH_WMASK(1, 0x3U, 0),
2321 		       BUSSCRU_BASE + RK3588_MODE_CON0);
2322 	}
2323 
2324 	switch (clk->id) {
2325 	case SCMI_SPLL:
2326 		if (rate >= 700 * MHz)
2327 			src = 1;
2328 		else
2329 			src = 0;
2330 		writel(BITS_WITH_WMASK(0, 0x3U, 0),
2331 			BUSSCRU_BASE + RK3588_MODE_CON0);
2332 		writel(BITS_WITH_WMASK(2, 0x7U, 6),
2333 			BUSSCRU_BASE + RK3588_PLL_CON(137));
2334 		writel(BITS_WITH_WMASK(src, 0x3U, 0),
2335 		       BUSSCRU_BASE + RK3588_MODE_CON0);
2336 		break;
2337 	case SCMI_CCLK_SD:
2338 		if ((OSC_HZ % rate) == 0) {
2339 			div = DIV_ROUND_UP(OSC_HZ, rate);
2340 			writel(CLKDIV_6BITS_SHF(div - 1, 6) |
2341 			       BITS_WITH_WMASK(2U, 0x3U, 12),
2342 			       SCRU_BASE + RK3588_CLKSEL_CON(3));
2343 		} else if ((SPLL_RATE % rate) == 0) {
2344 			div = DIV_ROUND_UP(SPLL_RATE, rate);
2345 			writel(CLKDIV_6BITS_SHF(div - 1, 6) |
2346 			       BITS_WITH_WMASK(1U, 0x3U, 12),
2347 			       SCRU_BASE + RK3588_CLKSEL_CON(3));
2348 		} else {
2349 			div = DIV_ROUND_UP(GPLL_RATE, rate);
2350 			writel(CLKDIV_6BITS_SHF(div - 1, 6) |
2351 			       BITS_WITH_WMASK(0U, 0x3U, 12),
2352 			       SCRU_BASE + RK3588_CLKSEL_CON(3));
2353 		}
2354 		break;
2355 	case SCMI_DCLK_SD:
2356 		if ((SPLL_RATE % rate) == 0) {
2357 			div = DIV_ROUND_UP(SPLL_RATE, rate);
2358 			writel(CLKDIV_5BITS_SHF(div - 1, 0) |
2359 			       BITS_WITH_WMASK(1U, 0x1U, 5),
2360 			       SCRU_BASE + RK3588_CLKSEL_CON(3));
2361 		} else {
2362 			div = DIV_ROUND_UP(GPLL_RATE, rate);
2363 			writel(CLKDIV_5BITS_SHF(div - 1, 0) |
2364 			       BITS_WITH_WMASK(0U, 0x1U, 5),
2365 			       SCRU_BASE + RK3588_CLKSEL_CON(3));
2366 		}
2367 		break;
2368 	case SCMI_CRYPTO_RNG:
2369 		if (rate >= 175 * MHz)
2370 			src = 0;
2371 		else if (rate >= 116 * MHz)
2372 			src = 1;
2373 		else if (rate >= 58 * MHz)
2374 			src = 2;
2375 		else
2376 			src = 3;
2377 
2378 		writel(BITS_WITH_WMASK(src, 0x3U, 14),
2379 		       SCRU_BASE + RK3588_CLKSEL_CON(1));
2380 		break;
2381 	case SCMI_CRYPTO_CORE:
2382 		if (rate >= 350 * MHz)
2383 			src = 0;
2384 		else if (rate >= 233 * MHz)
2385 			src = 1;
2386 		else if (rate >= 116 * MHz)
2387 			src = 2;
2388 		else
2389 			src = 3;
2390 
2391 		writel(BITS_WITH_WMASK(src, 0x3U, 10),
2392 		       SCRU_BASE + RK3588_CLKSEL_CON(1));
2393 		break;
2394 	case SCMI_CRYPTO_PKA:
2395 		if (rate >= 350 * MHz)
2396 			src = 0;
2397 		else if (rate >= 233 * MHz)
2398 			src = 1;
2399 		else if (rate >= 116 * MHz)
2400 			src = 2;
2401 		else
2402 			src = 3;
2403 
2404 		writel(BITS_WITH_WMASK(src, 0x3U, 12),
2405 		       SCRU_BASE + RK3588_CLKSEL_CON(1));
2406 		break;
2407 	case SCMI_KEYLADDER_CORE:
2408 		if (rate >= 350 * MHz)
2409 			src = 0;
2410 		else if (rate >= 233 * MHz)
2411 			src = 1;
2412 		else if (rate >= 116 * MHz)
2413 			src = 2;
2414 		else
2415 			src = 3;
2416 
2417 		writel(BITS_WITH_WMASK(src, 0x3U, 6),
2418 		       SCRU_BASE + RK3588_CLKSEL_CON(2));
2419 		break;
2420 	case SCMI_KEYLADDER_RNG:
2421 		if (rate >= 175 * MHz)
2422 			src = 0;
2423 		else if (rate >= 116 * MHz)
2424 			src = 1;
2425 		else if (rate >= 58 * MHz)
2426 			src = 2;
2427 		else
2428 			src = 3;
2429 
2430 		writel(BITS_WITH_WMASK(src, 0x3U, 8),
2431 		       SCRU_BASE + RK3588_CLKSEL_CON(2));
2432 		break;
2433 	case SCMI_TCLK_WDT:
2434 		break;
2435 	case SCMI_HCLK_SD:
2436 	case SCMI_HCLK_SECURE_NS:
2437 		if (rate >= 150 * MHz)
2438 			src = 0;
2439 		else if (rate >= 100 * MHz)
2440 			src = 1;
2441 		else if (rate >= 50 * MHz)
2442 			src = 2;
2443 		else
2444 			src = 3;
2445 		writel(BITS_WITH_WMASK(src, 0x3U, 2),
2446 		       SCRU_BASE + RK3588_CLKSEL_CON(1));
2447 		break;
2448 	default:
2449 		return -ENOENT;
2450 	}
2451 	return 0;
2452 };
2453 
2454 /* A fake scmi driver for SPL/TPL where smccc agent is not available. */
2455 static const struct clk_ops scmi_clk_ops = {
2456 	.get_rate = rk3588_clk_scmi_get_rate,
2457 	.set_rate = rk3588_clk_scmi_set_rate,
2458 };
2459 
2460 U_BOOT_DRIVER(scmi_clock) = {
2461 	.name = "scmi_clk",
2462 	.id = UCLASS_CLK,
2463 	.ops = &scmi_clk_ops,
2464 };
2465 #endif
2466 
2467 #ifndef CONFIG_SPL_BUILD
2468 /**
2469  * soc_clk_dump() - Print clock frequencies
2470  * Returns zero on success
2471  *
2472  * Implementation for the clk dump command.
2473  */
soc_clk_dump(void)2474 int soc_clk_dump(void)
2475 {
2476 	struct udevice *cru_dev;
2477 	struct rk3588_clk_priv *priv;
2478 	const struct rk3588_clk_info *clk_dump;
2479 	struct clk clk;
2480 	unsigned long clk_count = ARRAY_SIZE(clks_dump);
2481 	unsigned long rate;
2482 	int i, ret;
2483 
2484 	ret = uclass_get_device_by_driver(UCLASS_CLK,
2485 					  DM_GET_DRIVER(rockchip_rk3588_cru),
2486 					  &cru_dev);
2487 	if (ret) {
2488 		printf("%s failed to get cru device\n", __func__);
2489 		return ret;
2490 	}
2491 
2492 	priv = dev_get_priv(cru_dev);
2493 	printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n",
2494 	       priv->sync_kernel ? "sync kernel" : "uboot",
2495 	       priv->armclk_enter_hz / 1000,
2496 	       priv->armclk_init_hz / 1000,
2497 	       priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0,
2498 	       priv->set_armclk_rate ? " KHz" : "N/A");
2499 	for (i = 0; i < clk_count; i++) {
2500 		clk_dump = &clks_dump[i];
2501 		if (clk_dump->name) {
2502 			memset(&clk, 0, sizeof(struct clk));
2503 			clk.id = clk_dump->id;
2504 			if (clk_dump->is_cru)
2505 				ret = clk_request(cru_dev, &clk);
2506 			if (ret < 0)
2507 				return ret;
2508 
2509 			rate = clk_get_rate(&clk);
2510 			clk_free(&clk);
2511 			if (rate < 0)
2512 				printf("  %s %s\n", clk_dump->name,
2513 				       "unknown");
2514 			else
2515 				printf("  %s %lu KHz\n", clk_dump->name,
2516 				       rate / 1000);
2517 		}
2518 	}
2519 
2520 	return 0;
2521 }
2522 #endif
2523