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