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