blob: d0cc19b47883b5688d9223783b0cbb48162bfcea [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>
Jonas Karlmanb4505902023-04-17 19:07:20 +000012#include <scmi_protocols.h>
Jagan Teki7d031ee2023-01-30 20:27:36 +053013#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 /* _mhz, _p, _m, _s, _k */
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 { /* sentinel */ },
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 * rational_best_approximation(31415, 10000,
74 * (1 << 8) - 1, (1 << 5) - 1, &n, &d);
75 *
76 * you may look at given_numerator as a fixed point number,
77 * with the fractional part size described in given_denominator.
78 *
79 * for theoretical background, see:
80 * http://en.wikipedia.org/wiki/Continued_fraction
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;
Jonas Karlman291343a2023-04-18 16:46:42 +00001556 case TMCLK_EMMC:
Jagan Teki7d031ee2023-01-30 20:27:36 +05301557 case TCLK_WDT0:
1558 rate = OSC_HZ;
1559 break;
1560#ifndef CONFIG_SPL_BUILD
1561 case CLK_AUX16M_0:
1562 case CLK_AUX16M_1:
Jonas Karlman55152232023-03-14 00:38:27 +00001563 rate = rk3588_aux16m_get_clk(priv, clk->id);
Jagan Teki7d031ee2023-01-30 20:27:36 +05301564 break;
1565 case ACLK_VOP_ROOT:
1566 case ACLK_VOP:
1567 case ACLK_VOP_LOW_ROOT:
1568 case HCLK_VOP_ROOT:
1569 rate = rk3588_aclk_vop_get_clk(priv, clk->id);
1570 break;
1571 case DCLK_VOP0:
1572 case DCLK_VOP0_SRC:
1573 case DCLK_VOP1:
1574 case DCLK_VOP1_SRC:
1575 case DCLK_VOP2:
1576 case DCLK_VOP2_SRC:
1577 case DCLK_VOP3:
1578 rate = rk3588_dclk_vop_get_clk(priv, clk->id);
1579 break;
1580 case CLK_GMAC0_PTP_REF:
1581 case CLK_GMAC1_PTP_REF:
1582 case CLK_GMAC_125M:
1583 case CLK_GMAC_50M:
1584 rate = rk3588_gmac_get_clk(priv, clk->id);
1585 break;
1586 case SCLK_UART1:
1587 case SCLK_UART2:
1588 case SCLK_UART3:
1589 case SCLK_UART4:
1590 case SCLK_UART5:
1591 case SCLK_UART6:
1592 case SCLK_UART7:
1593 case SCLK_UART8:
1594 case SCLK_UART9:
1595 rate = rk3588_uart_get_rate(priv, clk->id);
1596 break;
1597 case CLK_REF_PIPE_PHY0:
1598 case CLK_REF_PIPE_PHY1:
1599 case CLK_REF_PIPE_PHY2:
1600 rate = rk3588_pciephy_get_rate(priv, clk->id);
1601 break;
1602#endif
1603 default:
1604 return -ENOENT;
1605 }
1606
1607 return rate;
1608};
1609
1610static ulong rk3588_clk_set_rate(struct clk *clk, ulong rate)
1611{
1612 struct rk3588_clk_priv *priv = dev_get_priv(clk->dev);
1613 ulong ret = 0;
1614
1615 if (!priv->gpll_hz) {
1616 printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
1617 return -ENOENT;
1618 }
1619
1620 if (!priv->ppll_hz) {
1621 priv->ppll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[PPLL],
1622 priv->cru, PPLL);
1623 }
1624
1625 switch (clk->id) {
1626 case PLL_CPLL:
1627 ret = rockchip_pll_set_rate(&rk3588_pll_clks[CPLL], priv->cru,
1628 CPLL, rate);
1629 priv->cpll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[CPLL],
1630 priv->cru, CPLL);
1631 break;
1632 case PLL_GPLL:
1633 ret = rockchip_pll_set_rate(&rk3588_pll_clks[GPLL], priv->cru,
1634 GPLL, rate);
1635 priv->gpll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[GPLL],
1636 priv->cru, GPLL);
1637 break;
1638 case PLL_NPLL:
1639 ret = rockchip_pll_set_rate(&rk3588_pll_clks[NPLL], priv->cru,
1640 NPLL, rate);
1641 break;
1642 case PLL_V0PLL:
1643 ret = rockchip_pll_set_rate(&rk3588_pll_clks[V0PLL], priv->cru,
1644 V0PLL, rate);
1645 priv->v0pll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[V0PLL],
1646 priv->cru, V0PLL);
1647 break;
1648 case PLL_AUPLL:
1649 ret = rockchip_pll_set_rate(&rk3588_pll_clks[AUPLL], priv->cru,
1650 AUPLL, rate);
1651 priv->aupll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[AUPLL],
1652 priv->cru, AUPLL);
1653 break;
1654 case PLL_PPLL:
1655 ret = rockchip_pll_set_rate(&rk3588_pll_clks[PPLL], priv->cru,
1656 PPLL, rate);
1657 priv->ppll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[PPLL],
1658 priv->cru, PPLL);
1659 break;
1660 case ACLK_CENTER_ROOT:
1661 case PCLK_CENTER_ROOT:
1662 case HCLK_CENTER_ROOT:
1663 case ACLK_CENTER_LOW_ROOT:
1664 ret = rk3588_center_set_clk(priv, clk->id, rate);
1665 break;
1666 case ACLK_TOP_ROOT:
1667 case PCLK_TOP_ROOT:
1668 case ACLK_LOW_TOP_ROOT:
1669 ret = rk3588_top_set_clk(priv, clk->id, rate);
1670 break;
1671 case CLK_I2C0:
1672 case CLK_I2C1:
1673 case CLK_I2C2:
1674 case CLK_I2C3:
1675 case CLK_I2C4:
1676 case CLK_I2C5:
1677 case CLK_I2C6:
1678 case CLK_I2C7:
1679 case CLK_I2C8:
1680 ret = rk3588_i2c_set_clk(priv, clk->id, rate);
1681 break;
1682 case CLK_SPI0:
1683 case CLK_SPI1:
1684 case CLK_SPI2:
1685 case CLK_SPI3:
1686 case CLK_SPI4:
1687 ret = rk3588_spi_set_clk(priv, clk->id, rate);
1688 break;
1689 case CLK_PWM1:
1690 case CLK_PWM2:
1691 case CLK_PWM3:
1692 case CLK_PMU1PWM:
1693 ret = rk3588_pwm_set_clk(priv, clk->id, rate);
1694 break;
1695 case CLK_SARADC:
1696 case CLK_TSADC:
1697 ret = rk3588_adc_set_clk(priv, clk->id, rate);
1698 break;
1699 case CCLK_SRC_SDIO:
1700 case CCLK_EMMC:
1701 case BCLK_EMMC:
1702 case SCLK_SFC:
1703 case DCLK_DECOM:
1704 ret = rk3588_mmc_set_clk(priv, clk->id, rate);
1705 break;
Jonas Karlman291343a2023-04-18 16:46:42 +00001706 case TMCLK_EMMC:
Jagan Teki7d031ee2023-01-30 20:27:36 +05301707 case TCLK_WDT0:
1708 ret = OSC_HZ;
1709 break;
1710#ifndef CONFIG_SPL_BUILD
1711 case CLK_AUX16M_0:
1712 case CLK_AUX16M_1:
Jonas Karlman55152232023-03-14 00:38:27 +00001713 ret = rk3588_aux16m_set_clk(priv, clk->id, rate);
Jagan Teki7d031ee2023-01-30 20:27:36 +05301714 break;
1715 case ACLK_VOP_ROOT:
1716 case ACLK_VOP:
1717 case ACLK_VOP_LOW_ROOT:
1718 case HCLK_VOP_ROOT:
1719 ret = rk3588_aclk_vop_set_clk(priv, clk->id, rate);
1720 break;
1721 case DCLK_VOP0:
1722 case DCLK_VOP0_SRC:
1723 case DCLK_VOP1:
1724 case DCLK_VOP1_SRC:
1725 case DCLK_VOP2:
1726 case DCLK_VOP2_SRC:
1727 case DCLK_VOP3:
1728 ret = rk3588_dclk_vop_set_clk(priv, clk->id, rate);
1729 break;
1730 case CLK_GMAC0_PTP_REF:
1731 case CLK_GMAC1_PTP_REF:
1732 case CLK_GMAC_125M:
1733 case CLK_GMAC_50M:
1734 ret = rk3588_gmac_set_clk(priv, clk->id, rate);
1735 break;
1736 case SCLK_UART1:
1737 case SCLK_UART2:
1738 case SCLK_UART3:
1739 case SCLK_UART4:
1740 case SCLK_UART5:
1741 case SCLK_UART6:
1742 case SCLK_UART7:
1743 case SCLK_UART8:
1744 case SCLK_UART9:
1745 ret = rk3588_uart_set_rate(priv, clk->id, rate);
1746 break;
1747 case CLK_REF_PIPE_PHY0:
1748 case CLK_REF_PIPE_PHY1:
1749 case CLK_REF_PIPE_PHY2:
1750 ret = rk3588_pciephy_set_rate(priv, clk->id, rate);
1751 break;
1752#endif
1753 default:
1754 return -ENOENT;
1755 }
1756
1757 return ret;
1758};
1759
1760#define ROCKCHIP_MMC_DELAY_SEL BIT(10)
1761#define ROCKCHIP_MMC_DEGREE_MASK 0x3
1762#define ROCKCHIP_MMC_DELAYNUM_OFFSET 2
1763#define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
1764
1765#define PSECS_PER_SEC 1000000000000LL
1766/*
1767 * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to
1768 * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg.
1769 */
1770#define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60
1771
1772#if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA))
1773static int __maybe_unused rk3588_dclk_vop_set_parent(struct clk *clk,
1774 struct clk *parent)
1775{
1776 struct rk3588_clk_priv *priv = dev_get_priv(clk->dev);
1777 struct rk3588_cru *cru = priv->cru;
1778 u32 sel;
1779 const char *clock_dev_name = parent->dev->name;
1780
1781 if (parent->id == PLL_V0PLL)
1782 sel = 2;
1783 else if (parent->id == PLL_GPLL)
1784 sel = 0;
1785 else if (parent->id == PLL_CPLL)
1786 sel = 1;
1787 else
1788 sel = 3;
1789
1790 switch (clk->id) {
1791 case DCLK_VOP0_SRC:
1792 rk_clrsetreg(&cru->clksel_con[111], DCLK0_VOP_SRC_SEL_MASK,
1793 sel << DCLK0_VOP_SRC_SEL_SHIFT);
1794 break;
1795 case DCLK_VOP1_SRC:
1796 rk_clrsetreg(&cru->clksel_con[111], DCLK1_VOP_SRC_SEL_MASK,
1797 sel << DCLK1_VOP_SRC_SEL_SHIFT);
1798 break;
1799 case DCLK_VOP2_SRC:
1800 rk_clrsetreg(&cru->clksel_con[112], DCLK2_VOP_SRC_SEL_MASK,
1801 sel << DCLK2_VOP_SRC_SEL_SHIFT);
1802 break;
1803 case DCLK_VOP3:
1804 rk_clrsetreg(&cru->clksel_con[113], DCLK3_VOP_SRC_SEL_MASK,
1805 sel << DCLK3_VOP_SRC_SEL_SHIFT);
1806 break;
1807 case DCLK_VOP0:
1808 if (!strcmp(clock_dev_name, "hdmiphypll_clk0"))
1809 sel = 1;
1810 else if (!strcmp(clock_dev_name, "hdmiphypll_clk1"))
1811 sel = 2;
1812 else
1813 sel = 0;
1814 rk_clrsetreg(&cru->clksel_con[112], DCLK0_VOP_SEL_MASK,
1815 sel << DCLK0_VOP_SEL_SHIFT);
1816 break;
1817 case DCLK_VOP1:
1818 if (!strcmp(clock_dev_name, "hdmiphypll_clk0"))
1819 sel = 1;
1820 else if (!strcmp(clock_dev_name, "hdmiphypll_clk1"))
1821 sel = 2;
1822 else
1823 sel = 0;
1824 rk_clrsetreg(&cru->clksel_con[112], DCLK1_VOP_SEL_MASK,
1825 sel << DCLK1_VOP_SEL_SHIFT);
1826 break;
1827 case DCLK_VOP2:
1828 if (!strcmp(clock_dev_name, "hdmiphypll_clk0"))
1829 sel = 1;
1830 else if (!strcmp(clock_dev_name, "hdmiphypll_clk1"))
1831 sel = 2;
1832 else
1833 sel = 0;
1834 rk_clrsetreg(&cru->clksel_con[112], DCLK2_VOP_SEL_MASK,
1835 sel << DCLK2_VOP_SEL_SHIFT);
1836 break;
1837 default:
1838 return -EINVAL;
1839 }
1840 return 0;
1841}
1842
1843static int rk3588_clk_set_parent(struct clk *clk, struct clk *parent)
1844{
1845 switch (clk->id) {
1846 case DCLK_VOP0_SRC:
1847 case DCLK_VOP1_SRC:
1848 case DCLK_VOP2_SRC:
1849 case DCLK_VOP0:
1850 case DCLK_VOP1:
1851 case DCLK_VOP2:
1852 case DCLK_VOP3:
1853 return rk3588_dclk_vop_set_parent(clk, parent);
1854 default:
1855 return -ENOENT;
1856 }
1857
1858 return 0;
1859}
1860#endif
1861
1862static struct clk_ops rk3588_clk_ops = {
1863 .get_rate = rk3588_clk_get_rate,
1864 .set_rate = rk3588_clk_set_rate,
1865#if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA))
1866 .set_parent = rk3588_clk_set_parent,
1867#endif
1868};
1869
1870static void rk3588_clk_init(struct rk3588_clk_priv *priv)
1871{
1872 int ret, div;
1873
1874 div = DIV_ROUND_UP(GPLL_HZ, 300 * MHz);
1875 rk_clrsetreg(&priv->cru->clksel_con[38],
1876 ACLK_BUS_ROOT_SEL_MASK |
1877 ACLK_BUS_ROOT_DIV_MASK,
1878 div << ACLK_BUS_ROOT_DIV_SHIFT);
1879
1880 if (priv->cpll_hz != CPLL_HZ) {
1881 ret = rockchip_pll_set_rate(&rk3588_pll_clks[CPLL], priv->cru,
1882 CPLL, CPLL_HZ);
1883 if (!ret)
1884 priv->cpll_hz = CPLL_HZ;
1885 }
1886 if (priv->gpll_hz != GPLL_HZ) {
1887 ret = rockchip_pll_set_rate(&rk3588_pll_clks[GPLL], priv->cru,
1888 GPLL, GPLL_HZ);
1889 if (!ret)
1890 priv->gpll_hz = GPLL_HZ;
1891 }
1892
1893#ifdef CONFIG_PCI
1894 if (priv->ppll_hz != PPLL_HZ) {
1895 ret = rockchip_pll_set_rate(&rk3588_pll_clks[PPLL], priv->cru,
1896 PPLL, PPLL_HZ);
1897 priv->ppll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[PPLL],
1898 priv->cru, PPLL);
1899 }
1900#endif
1901 rk_clrsetreg(&priv->cru->clksel_con[9],
1902 ACLK_TOP_S400_SEL_MASK |
1903 ACLK_TOP_S200_SEL_MASK,
1904 (ACLK_TOP_S400_SEL_400M << ACLK_TOP_S400_SEL_SHIFT) |
1905 (ACLK_TOP_S200_SEL_200M << ACLK_TOP_S200_SEL_SHIFT));
1906}
1907
1908static int rk3588_clk_probe(struct udevice *dev)
1909{
1910 struct rk3588_clk_priv *priv = dev_get_priv(dev);
1911 int ret;
1912
1913 priv->sync_kernel = false;
1914
1915#ifdef CONFIG_SPL_BUILD
1916 rockchip_pll_set_rate(&rk3588_pll_clks[B0PLL], priv->cru,
1917 B0PLL, LPLL_HZ);
1918 rockchip_pll_set_rate(&rk3588_pll_clks[B1PLL], priv->cru,
1919 B1PLL, LPLL_HZ);
1920 if (!priv->armclk_enter_hz) {
1921 ret = rockchip_pll_set_rate(&rk3588_pll_clks[LPLL], priv->cru,
1922 LPLL, LPLL_HZ);
1923 priv->armclk_enter_hz =
1924 rockchip_pll_get_rate(&rk3588_pll_clks[LPLL],
1925 priv->cru, LPLL);
1926 priv->armclk_init_hz = priv->armclk_enter_hz;
1927 }
1928#endif
1929
1930 priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
1931 if (IS_ERR(priv->grf))
1932 return PTR_ERR(priv->grf);
1933
1934 rk3588_clk_init(priv);
1935
1936 /* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
1937 ret = clk_set_defaults(dev, 1);
1938 if (ret)
1939 debug("%s clk_set_defaults failed %d\n", __func__, ret);
1940 else
1941 priv->sync_kernel = true;
1942
1943 return 0;
1944}
1945
1946static int rk3588_clk_ofdata_to_platdata(struct udevice *dev)
1947{
1948 struct rk3588_clk_priv *priv = dev_get_priv(dev);
1949
1950 priv->cru = dev_read_addr_ptr(dev);
1951
1952 return 0;
1953}
1954
1955static int rk3588_clk_bind(struct udevice *dev)
1956{
1957 int ret;
1958 struct udevice *sys_child;
1959 struct sysreset_reg *priv;
1960
1961 /* The reset driver does not have a device node, so bind it here */
1962 ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
1963 &sys_child);
1964 if (ret) {
1965 debug("Warning: No sysreset driver: ret=%d\n", ret);
1966 } else {
1967 priv = malloc(sizeof(struct sysreset_reg));
1968 priv->glb_srst_fst_value = offsetof(struct rk3588_cru,
1969 glb_srst_fst);
1970 priv->glb_srst_snd_value = offsetof(struct rk3588_cru,
1971 glb_srsr_snd);
1972 dev_set_priv(sys_child, priv);
1973 }
1974
1975#if CONFIG_IS_ENABLED(RESET_ROCKCHIP)
1976 ret = offsetof(struct rk3588_cru, softrst_con[0]);
1977 ret = rockchip_reset_bind(dev, ret, 49158);
1978 if (ret)
1979 debug("Warning: software reset driver bind faile\n");
1980#endif
1981
1982 return 0;
1983}
1984
1985static const struct udevice_id rk3588_clk_ids[] = {
1986 { .compatible = "rockchip,rk3588-cru" },
1987 { }
1988};
1989
1990U_BOOT_DRIVER(rockchip_rk3588_cru) = {
1991 .name = "rockchip_rk3588_cru",
1992 .id = UCLASS_CLK,
1993 .of_match = rk3588_clk_ids,
1994 .priv_auto = sizeof(struct rk3588_clk_priv),
1995 .of_to_plat = rk3588_clk_ofdata_to_platdata,
1996 .ops = &rk3588_clk_ops,
1997 .bind = rk3588_clk_bind,
1998 .probe = rk3588_clk_probe,
1999};
Jonas Karlmanb4505902023-04-17 19:07:20 +00002000
2001#ifdef CONFIG_SPL_BUILD
2002#define SCRU_BASE 0xfd7d0000
2003
2004static ulong rk3588_scru_clk_get_rate(struct clk *clk)
2005{
2006 u32 con, div, sel, parent;
2007
2008 switch (clk->id) {
2009 case SCMI_CCLK_SD:
2010 con = readl(SCRU_BASE + RK3588_CLKSEL_CON(3));
2011 sel = (con & SCMI_CCLK_SD_SEL_MASK) >> SCMI_CCLK_SD_SEL_SHIFT;
2012 div = (con & SCMI_CCLK_SD_DIV_MASK) >> SCMI_CCLK_SD_DIV_SHIFT;
2013 if (sel == SCMI_CCLK_SD_SEL_GPLL)
2014 parent = GPLL_HZ;
2015 else if (sel == SCMI_CCLK_SD_SEL_SPLL)
2016 parent = SPLL_HZ;
2017 else
2018 parent = OSC_HZ;
2019 return DIV_TO_RATE(parent, div);
2020 case SCMI_HCLK_SD:
2021 con = readl(SCRU_BASE + RK3588_CLKSEL_CON(1));
2022 sel = (con & SCMI_HCLK_SD_SEL_MASK) >> SCMI_HCLK_SD_SEL_SHIFT;
2023 if (sel == SCMI_HCLK_SD_SEL_150M)
2024 return 150 * MHz;
2025 else if (sel == SCMI_HCLK_SD_SEL_100M)
2026 return 100 * MHz;
2027 else if (sel == SCMI_HCLK_SD_SEL_50M)
2028 return 50 * MHz;
2029 else
2030 return OSC_HZ;
2031 default:
2032 return -ENOENT;
2033 }
2034}
2035
2036static ulong rk3588_scru_clk_set_rate(struct clk *clk, ulong rate)
2037{
2038 u32 div, sel;
2039
2040 switch (clk->id) {
2041 case SCMI_CCLK_SD:
2042 if ((OSC_HZ % rate) == 0) {
2043 sel = SCMI_CCLK_SD_SEL_24M;
2044 div = DIV_ROUND_UP(OSC_HZ, rate);
2045 } else if ((SPLL_HZ % rate) == 0) {
2046 sel = SCMI_CCLK_SD_SEL_SPLL;
2047 div = DIV_ROUND_UP(SPLL_HZ, rate);
2048 } else {
2049 sel = SCMI_CCLK_SD_SEL_GPLL;
2050 div = DIV_ROUND_UP(GPLL_HZ, rate);
2051 }
2052 rk_clrsetreg(SCRU_BASE + RK3588_CLKSEL_CON(3),
2053 SCMI_CCLK_SD_SEL_MASK | SCMI_CCLK_SD_DIV_MASK,
2054 sel << SCMI_CCLK_SD_SEL_SHIFT |
2055 (div - 1) << SCMI_CCLK_SD_DIV_SHIFT);
2056 break;
2057 case SCMI_HCLK_SD:
2058 if (rate >= 150 * MHz)
2059 sel = SCMI_HCLK_SD_SEL_150M;
2060 else if (rate >= 100 * MHz)
2061 sel = SCMI_HCLK_SD_SEL_100M;
2062 else if (rate >= 50 * MHz)
2063 sel = SCMI_HCLK_SD_SEL_50M;
2064 else
2065 sel = SCMI_HCLK_SD_SEL_24M;
2066 rk_clrsetreg(SCRU_BASE + RK3588_CLKSEL_CON(1),
2067 SCMI_HCLK_SD_SEL_MASK,
2068 sel << SCMI_HCLK_SD_SEL_SHIFT);
2069 break;
2070 default:
2071 return -ENOENT;
2072 }
2073
2074 return rk3588_scru_clk_get_rate(clk);
2075}
2076
2077static const struct clk_ops rk3588_scru_clk_ops = {
2078 .get_rate = rk3588_scru_clk_get_rate,
2079 .set_rate = rk3588_scru_clk_set_rate,
2080};
2081
2082U_BOOT_DRIVER(rockchip_rk3588_scru) = {
2083 .name = "rockchip_rk3588_scru",
2084 .id = UCLASS_CLK,
2085 .ops = &rk3588_scru_clk_ops,
2086};
2087
2088static int rk3588_scmi_spl_glue_bind(struct udevice *dev)
2089{
2090 ofnode node;
2091 u32 protocol_id;
2092 const char *name;
2093
2094 dev_for_each_subnode(node, dev) {
2095 if (!ofnode_is_enabled(node))
2096 continue;
2097
2098 if (ofnode_read_u32(node, "reg", &protocol_id))
2099 continue;
2100
2101 if (protocol_id != SCMI_PROTOCOL_ID_CLOCK)
2102 continue;
2103
2104 name = ofnode_get_name(node);
2105 return device_bind_driver_to_node(dev, "rockchip_rk3588_scru",
2106 name, node, NULL);
2107 }
2108
2109 return -ENOENT;
2110}
2111
2112static const struct udevice_id rk3588_scmi_spl_glue_ids[] = {
2113 { .compatible = "arm,scmi-smc" },
2114 { }
2115};
2116
2117U_BOOT_DRIVER(rk3588_scmi_spl_glue) = {
2118 .name = "rk3588_scmi_spl_glue",
2119 .id = UCLASS_NOP,
2120 .of_match = rk3588_scmi_spl_glue_ids,
2121 .bind = rk3588_scmi_spl_glue_bind,
2122};
2123#endif