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