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