blob: a995dd5591d3924728ffd0755c25a296a96529da [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) {
Elaine Zhang28920742023-10-12 18:18:12 +08001133 pll_rate = rockchip_pll_get_rate(&rk3588_pll_clks[V0PLL],
1134 priv->cru, V0PLL);
1135 if (pll_rate >= RK3588_VOP_PLL_LIMIT_FREQ && pll_rate % rate == 0) {
1136 div = DIV_ROUND_UP(pll_rate, rate);
1137 rk_clrsetreg(&cru->clksel_con[conid],
1138 mask,
1139 DCLK_VOP_SRC_SEL_V0PLL << sel_shift |
1140 ((div - 1) << div_shift));
1141 } else {
1142 div = DIV_ROUND_UP(RK3588_VOP_PLL_LIMIT_FREQ, rate);
1143 rk_clrsetreg(&cru->clksel_con[conid],
1144 mask,
1145 DCLK_VOP_SRC_SEL_V0PLL << sel_shift |
1146 ((div - 1) << div_shift));
1147 rockchip_pll_set_rate(&rk3588_pll_clks[V0PLL],
1148 priv->cru, V0PLL, div * rate);
1149 }
Jagan Teki7d031ee2023-01-30 20:27:36 +05301150 } else {
1151 for (i = 0; i <= DCLK_VOP_SRC_SEL_AUPLL; i++) {
1152 switch (i) {
1153 case DCLK_VOP_SRC_SEL_GPLL:
1154 pll_rate = priv->gpll_hz;
1155 break;
1156 case DCLK_VOP_SRC_SEL_CPLL:
1157 pll_rate = priv->cpll_hz;
1158 break;
1159 case DCLK_VOP_SRC_SEL_AUPLL:
1160 pll_rate = priv->aupll_hz;
1161 break;
1162 case DCLK_VOP_SRC_SEL_V0PLL:
1163 pll_rate = 0;
1164 break;
1165 default:
1166 printf("do not support this vop pll sel\n");
1167 return -EINVAL;
1168 }
1169
1170 div = DIV_ROUND_UP(pll_rate, rate);
1171 if (div > 255)
1172 continue;
1173 now = pll_rate / div;
1174 if (abs(rate - now) < abs(rate - best_rate)) {
1175 best_rate = now;
1176 best_div = div;
1177 best_sel = i;
1178 }
1179 debug("p_rate=%lu, best_rate=%lu, div=%u, sel=%u\n",
1180 pll_rate, best_rate, best_div, best_sel);
1181 }
1182
1183 if (best_rate) {
1184 rk_clrsetreg(&cru->clksel_con[conid],
1185 mask,
1186 best_sel << sel_shift |
1187 (best_div - 1) << div_shift);
1188 } else {
1189 printf("do not support this vop freq %lu\n", rate);
1190 return -EINVAL;
1191 }
1192 }
1193 return rk3588_dclk_vop_get_clk(priv, clk_id);
1194}
1195
1196static ulong rk3588_gmac_get_clk(struct rk3588_clk_priv *priv, ulong clk_id)
1197{
1198 struct rk3588_cru *cru = priv->cru;
1199 u32 con, div;
1200
1201 switch (clk_id) {
1202 case CLK_GMAC0_PTP_REF:
1203 con = readl(&cru->clksel_con[81]);
1204 div = (con & CLK_GMAC0_PTP_DIV_MASK) >> CLK_GMAC0_PTP_DIV_SHIFT;
1205 return DIV_TO_RATE(priv->cpll_hz, div);
1206 case CLK_GMAC1_PTP_REF:
1207 con = readl(&cru->clksel_con[81]);
1208 div = (con & CLK_GMAC1_PTP_DIV_MASK) >> CLK_GMAC1_PTP_DIV_SHIFT;
1209 return DIV_TO_RATE(priv->cpll_hz, div);
1210 case CLK_GMAC_125M:
1211 con = readl(&cru->clksel_con[83]);
1212 div = (con & CLK_GMAC_125M_DIV_MASK) >> CLK_GMAC_125M_DIV_SHIFT;
1213 return DIV_TO_RATE(priv->cpll_hz, div);
1214 case CLK_GMAC_50M:
1215 con = readl(&cru->clksel_con[84]);
1216 div = (con & CLK_GMAC_50M_DIV_MASK) >> CLK_GMAC_50M_DIV_SHIFT;
1217 return DIV_TO_RATE(priv->cpll_hz, div);
1218 default:
1219 return -ENOENT;
1220 }
1221}
1222
1223static ulong rk3588_gmac_set_clk(struct rk3588_clk_priv *priv,
1224 ulong clk_id, ulong rate)
1225{
1226 struct rk3588_cru *cru = priv->cru;
1227 int div;
1228
1229 div = DIV_ROUND_UP(priv->cpll_hz, rate);
1230
1231 switch (clk_id) {
1232 case CLK_GMAC0_PTP_REF:
1233 rk_clrsetreg(&cru->clksel_con[81],
1234 CLK_GMAC0_PTP_DIV_MASK | CLK_GMAC0_PTP_SEL_MASK,
1235 CLK_GMAC0_PTP_SEL_CPLL << CLK_GMAC0_PTP_SEL_SHIFT |
1236 (div - 1) << CLK_GMAC0_PTP_DIV_SHIFT);
1237 break;
1238 case CLK_GMAC1_PTP_REF:
1239 rk_clrsetreg(&cru->clksel_con[81],
1240 CLK_GMAC1_PTP_DIV_MASK | CLK_GMAC1_PTP_SEL_MASK,
1241 CLK_GMAC1_PTP_SEL_CPLL << CLK_GMAC1_PTP_SEL_SHIFT |
1242 (div - 1) << CLK_GMAC1_PTP_DIV_SHIFT);
1243 break;
1244
1245 case CLK_GMAC_125M:
1246 rk_clrsetreg(&cru->clksel_con[83],
1247 CLK_GMAC_125M_DIV_MASK | CLK_GMAC_125M_SEL_MASK,
1248 CLK_GMAC_125M_SEL_CPLL << CLK_GMAC_125M_SEL_SHIFT |
1249 (div - 1) << CLK_GMAC_125M_DIV_SHIFT);
1250 break;
1251 case CLK_GMAC_50M:
1252 rk_clrsetreg(&cru->clksel_con[84],
1253 CLK_GMAC_50M_DIV_MASK | CLK_GMAC_50M_SEL_MASK,
1254 CLK_GMAC_50M_SEL_CPLL << CLK_GMAC_50M_SEL_SHIFT |
1255 (div - 1) << CLK_GMAC_50M_DIV_SHIFT);
1256 break;
1257 default:
1258 return -ENOENT;
1259 }
1260
1261 return rk3588_gmac_get_clk(priv, clk_id);
1262}
1263
1264static ulong rk3588_uart_get_rate(struct rk3588_clk_priv *priv, ulong clk_id)
1265{
1266 struct rk3588_cru *cru = priv->cru;
1267 u32 reg, con, fracdiv, div, src, p_src, p_rate;
1268 unsigned long m, n;
1269
1270 switch (clk_id) {
1271 case SCLK_UART1:
1272 reg = 41;
1273 break;
1274 case SCLK_UART2:
1275 reg = 43;
1276 break;
1277 case SCLK_UART3:
1278 reg = 45;
1279 break;
1280 case SCLK_UART4:
1281 reg = 47;
1282 break;
1283 case SCLK_UART5:
1284 reg = 49;
1285 break;
1286 case SCLK_UART6:
1287 reg = 51;
1288 break;
1289 case SCLK_UART7:
1290 reg = 53;
1291 break;
1292 case SCLK_UART8:
1293 reg = 55;
1294 break;
1295 case SCLK_UART9:
1296 reg = 57;
1297 break;
1298 default:
1299 return -ENOENT;
1300 }
1301 con = readl(&cru->clksel_con[reg + 2]);
1302 src = (con & CLK_UART_SEL_MASK) >> CLK_UART_SEL_SHIFT;
1303 con = readl(&cru->clksel_con[reg]);
1304 div = (con & CLK_UART_SRC_DIV_MASK) >> CLK_UART_SRC_DIV_SHIFT;
1305 p_src = (con & CLK_UART_SRC_SEL_MASK) >> CLK_UART_SRC_SEL_SHIFT;
1306 if (p_src == CLK_UART_SRC_SEL_GPLL)
1307 p_rate = priv->gpll_hz;
1308 else
1309 p_rate = priv->cpll_hz;
1310
1311 if (src == CLK_UART_SEL_SRC) {
1312 return DIV_TO_RATE(p_rate, div);
1313 } else if (src == CLK_UART_SEL_FRAC) {
1314 fracdiv = readl(&cru->clksel_con[reg + 1]);
1315 n = fracdiv & CLK_UART_FRAC_NUMERATOR_MASK;
1316 n >>= CLK_UART_FRAC_NUMERATOR_SHIFT;
1317 m = fracdiv & CLK_UART_FRAC_DENOMINATOR_MASK;
1318 m >>= CLK_UART_FRAC_DENOMINATOR_SHIFT;
1319 return DIV_TO_RATE(p_rate, div) * n / m;
1320 } else {
1321 return OSC_HZ;
1322 }
1323}
1324
1325static ulong rk3588_uart_set_rate(struct rk3588_clk_priv *priv,
1326 ulong clk_id, ulong rate)
1327{
1328 struct rk3588_cru *cru = priv->cru;
1329 u32 reg, clk_src, uart_src, div;
1330 unsigned long m = 0, n = 0, val;
1331
1332 if (priv->gpll_hz % rate == 0) {
1333 clk_src = CLK_UART_SRC_SEL_GPLL;
1334 uart_src = CLK_UART_SEL_SRC;
1335 div = DIV_ROUND_UP(priv->gpll_hz, rate);
1336 } else if (priv->cpll_hz % rate == 0) {
1337 clk_src = CLK_UART_SRC_SEL_CPLL;
1338 uart_src = CLK_UART_SEL_SRC;
1339 div = DIV_ROUND_UP(priv->gpll_hz, rate);
1340 } else if (rate == OSC_HZ) {
1341 clk_src = CLK_UART_SRC_SEL_GPLL;
1342 uart_src = CLK_UART_SEL_XIN24M;
1343 div = 2;
1344 } else {
1345 clk_src = CLK_UART_SRC_SEL_GPLL;
1346 uart_src = CLK_UART_SEL_FRAC;
1347 div = 2;
1348 rational_best_approximation(rate, priv->gpll_hz / div,
1349 GENMASK(16 - 1, 0),
1350 GENMASK(16 - 1, 0),
1351 &m, &n);
1352 }
1353
1354 switch (clk_id) {
1355 case SCLK_UART1:
1356 reg = 41;
1357 break;
1358 case SCLK_UART2:
1359 reg = 43;
1360 break;
1361 case SCLK_UART3:
1362 reg = 45;
1363 break;
1364 case SCLK_UART4:
1365 reg = 47;
1366 break;
1367 case SCLK_UART5:
1368 reg = 49;
1369 break;
1370 case SCLK_UART6:
1371 reg = 51;
1372 break;
1373 case SCLK_UART7:
1374 reg = 53;
1375 break;
1376 case SCLK_UART8:
1377 reg = 55;
1378 break;
1379 case SCLK_UART9:
1380 reg = 57;
1381 break;
1382 default:
1383 return -ENOENT;
1384 }
1385 rk_clrsetreg(&cru->clksel_con[reg],
1386 CLK_UART_SRC_SEL_MASK |
1387 CLK_UART_SRC_DIV_MASK,
1388 (clk_src << CLK_UART_SRC_SEL_SHIFT) |
1389 ((div - 1) << CLK_UART_SRC_DIV_SHIFT));
1390 rk_clrsetreg(&cru->clksel_con[reg + 2],
1391 CLK_UART_SEL_MASK,
1392 (uart_src << CLK_UART_SEL_SHIFT));
1393 if (m && n) {
1394 val = m << CLK_UART_FRAC_NUMERATOR_SHIFT | n;
1395 writel(val, &cru->clksel_con[reg + 1]);
1396 }
1397
1398 return rk3588_uart_get_rate(priv, clk_id);
1399}
1400
1401static ulong rk3588_pciephy_get_rate(struct rk3588_clk_priv *priv, ulong clk_id)
1402{
1403 struct rk3588_cru *cru = priv->cru;
1404 u32 con, div, src;
1405
1406 switch (clk_id) {
1407 case CLK_REF_PIPE_PHY0:
1408 con = readl(&cru->clksel_con[177]);
1409 src = (con & CLK_PCIE_PHY0_REF_SEL_MASK) >> CLK_PCIE_PHY0_REF_SEL_SHIFT;
1410 con = readl(&cru->clksel_con[176]);
1411 div = (con & CLK_PCIE_PHY0_PLL_DIV_MASK) >> CLK_PCIE_PHY0_PLL_DIV_SHIFT;
1412 break;
1413 case CLK_REF_PIPE_PHY1:
1414 con = readl(&cru->clksel_con[177]);
1415 src = (con & CLK_PCIE_PHY1_REF_SEL_MASK) >> CLK_PCIE_PHY1_REF_SEL_SHIFT;
1416 con = readl(&cru->clksel_con[176]);
1417 div = (con & CLK_PCIE_PHY1_PLL_DIV_MASK) >> CLK_PCIE_PHY1_PLL_DIV_SHIFT;
1418 break;
1419 case CLK_REF_PIPE_PHY2:
1420 con = readl(&cru->clksel_con[177]);
1421 src = (con & CLK_PCIE_PHY2_REF_SEL_MASK) >> CLK_PCIE_PHY2_REF_SEL_SHIFT;
1422 div = (con & CLK_PCIE_PHY2_PLL_DIV_MASK) >> CLK_PCIE_PHY2_PLL_DIV_SHIFT;
1423 break;
1424 default:
1425 return -ENOENT;
1426 }
1427
1428 if (src == CLK_PCIE_PHY_REF_SEL_PPLL)
1429 return DIV_TO_RATE(priv->ppll_hz, div);
1430 else
1431 return OSC_HZ;
1432}
1433
1434static ulong rk3588_pciephy_set_rate(struct rk3588_clk_priv *priv,
1435 ulong clk_id, ulong rate)
1436{
1437 struct rk3588_cru *cru = priv->cru;
1438 u32 clk_src, div;
1439
1440 if (rate == OSC_HZ) {
1441 clk_src = CLK_PCIE_PHY_REF_SEL_24M;
1442 div = 1;
1443 } else {
1444 clk_src = CLK_PCIE_PHY_REF_SEL_PPLL;
1445 div = DIV_ROUND_UP(priv->ppll_hz, rate);
1446 }
1447
1448 switch (clk_id) {
1449 case CLK_REF_PIPE_PHY0:
1450 rk_clrsetreg(&cru->clksel_con[177], CLK_PCIE_PHY0_REF_SEL_MASK,
1451 (clk_src << CLK_PCIE_PHY0_REF_SEL_SHIFT));
1452 rk_clrsetreg(&cru->clksel_con[176], CLK_PCIE_PHY0_PLL_DIV_MASK,
1453 ((div - 1) << CLK_PCIE_PHY0_PLL_DIV_SHIFT));
1454 break;
1455 case CLK_REF_PIPE_PHY1:
1456 rk_clrsetreg(&cru->clksel_con[177], CLK_PCIE_PHY1_REF_SEL_MASK,
1457 (clk_src << CLK_PCIE_PHY1_REF_SEL_SHIFT));
1458 rk_clrsetreg(&cru->clksel_con[176], CLK_PCIE_PHY1_PLL_DIV_MASK,
1459 ((div - 1) << CLK_PCIE_PHY1_PLL_DIV_SHIFT));
1460 break;
1461 case CLK_REF_PIPE_PHY2:
1462 rk_clrsetreg(&cru->clksel_con[177], CLK_PCIE_PHY2_REF_SEL_MASK |
1463 CLK_PCIE_PHY2_PLL_DIV_MASK,
1464 (clk_src << CLK_PCIE_PHY2_REF_SEL_SHIFT) |
1465 ((div - 1) << CLK_PCIE_PHY2_PLL_DIV_SHIFT));
1466 break;
1467 default:
1468 return -ENOENT;
1469 }
1470
1471 return rk3588_pciephy_get_rate(priv, clk_id);
1472}
1473#endif
1474
1475static ulong rk3588_clk_get_rate(struct clk *clk)
1476{
1477 struct rk3588_clk_priv *priv = dev_get_priv(clk->dev);
1478 ulong rate = 0;
1479
1480 if (!priv->gpll_hz) {
1481 printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
1482 return -ENOENT;
1483 }
1484
1485 if (!priv->ppll_hz) {
1486 priv->ppll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[PPLL],
1487 priv->cru, PPLL);
1488 }
1489
1490 switch (clk->id) {
1491 case PLL_LPLL:
1492 rate = rockchip_pll_get_rate(&rk3588_pll_clks[LPLL], priv->cru,
1493 LPLL);
1494 break;
1495 case PLL_B0PLL:
1496 rate = rockchip_pll_get_rate(&rk3588_pll_clks[B0PLL], priv->cru,
1497 B0PLL);
1498 break;
1499 case PLL_B1PLL:
1500 rate = rockchip_pll_get_rate(&rk3588_pll_clks[B1PLL], priv->cru,
1501 B1PLL);
1502 break;
1503 case PLL_GPLL:
1504 rate = rockchip_pll_get_rate(&rk3588_pll_clks[GPLL], priv->cru,
1505 GPLL);
1506 break;
1507 case PLL_CPLL:
1508 rate = rockchip_pll_get_rate(&rk3588_pll_clks[CPLL], priv->cru,
1509 CPLL);
1510 break;
1511 case PLL_NPLL:
1512 rate = rockchip_pll_get_rate(&rk3588_pll_clks[NPLL], priv->cru,
1513 NPLL);
1514 break;
1515 case PLL_V0PLL:
1516 rate = rockchip_pll_get_rate(&rk3588_pll_clks[V0PLL], priv->cru,
1517 V0PLL);
1518 break;
1519 case PLL_AUPLL:
1520 rate = rockchip_pll_get_rate(&rk3588_pll_clks[AUPLL], priv->cru,
1521 AUPLL);
1522 break;
1523 case PLL_PPLL:
1524 rate = rockchip_pll_get_rate(&rk3588_pll_clks[PPLL], priv->cru,
1525 PPLL);
1526 break;
1527 case ACLK_CENTER_ROOT:
1528 case PCLK_CENTER_ROOT:
1529 case HCLK_CENTER_ROOT:
1530 case ACLK_CENTER_LOW_ROOT:
1531 rate = rk3588_center_get_clk(priv, clk->id);
1532 break;
1533 case ACLK_TOP_ROOT:
1534 case PCLK_TOP_ROOT:
1535 case ACLK_LOW_TOP_ROOT:
1536 rate = rk3588_top_get_clk(priv, clk->id);
1537 break;
1538 case CLK_I2C0:
1539 case CLK_I2C1:
1540 case CLK_I2C2:
1541 case CLK_I2C3:
1542 case CLK_I2C4:
1543 case CLK_I2C5:
1544 case CLK_I2C6:
1545 case CLK_I2C7:
1546 case CLK_I2C8:
1547 rate = rk3588_i2c_get_clk(priv, clk->id);
1548 break;
1549 case CLK_SPI0:
1550 case CLK_SPI1:
1551 case CLK_SPI2:
1552 case CLK_SPI3:
1553 case CLK_SPI4:
1554 rate = rk3588_spi_get_clk(priv, clk->id);
1555 break;
1556 case CLK_PWM1:
1557 case CLK_PWM2:
1558 case CLK_PWM3:
1559 case CLK_PMU1PWM:
1560 rate = rk3588_pwm_get_clk(priv, clk->id);
1561 break;
1562 case CLK_SARADC:
1563 case CLK_TSADC:
1564 rate = rk3588_adc_get_clk(priv, clk->id);
1565 break;
1566 case CCLK_SRC_SDIO:
1567 case CCLK_EMMC:
1568 case BCLK_EMMC:
1569 case SCLK_SFC:
1570 case DCLK_DECOM:
1571 rate = rk3588_mmc_get_clk(priv, clk->id);
1572 break;
Jonas Karlman291343a2023-04-18 16:46:42 +00001573 case TMCLK_EMMC:
Jagan Teki7d031ee2023-01-30 20:27:36 +05301574 case TCLK_WDT0:
1575 rate = OSC_HZ;
1576 break;
Eugen Hristev3d3f4072023-04-13 14:36:45 +03001577 case PCLK_PMU0_ROOT:
1578 rate = 100000000;
1579 break;
1580 case HCLK_PMU_CM0_ROOT:
1581 rate = 200000000;
1582 break;
1583 case ACLK_BUS_ROOT:
1584 rate = 375000000;
1585 break;
1586 case CLK_150M_SRC:
1587 rate = 150000000;
1588 break;
1589 case CLK_GPU:
1590 rate = 200000000;
1591 break;
Jagan Teki7d031ee2023-01-30 20:27:36 +05301592#ifndef CONFIG_SPL_BUILD
1593 case CLK_AUX16M_0:
1594 case CLK_AUX16M_1:
Jonas Karlman55152232023-03-14 00:38:27 +00001595 rate = rk3588_aux16m_get_clk(priv, clk->id);
Jagan Teki7d031ee2023-01-30 20:27:36 +05301596 break;
1597 case ACLK_VOP_ROOT:
1598 case ACLK_VOP:
1599 case ACLK_VOP_LOW_ROOT:
1600 case HCLK_VOP_ROOT:
1601 rate = rk3588_aclk_vop_get_clk(priv, clk->id);
1602 break;
1603 case DCLK_VOP0:
1604 case DCLK_VOP0_SRC:
1605 case DCLK_VOP1:
1606 case DCLK_VOP1_SRC:
1607 case DCLK_VOP2:
1608 case DCLK_VOP2_SRC:
1609 case DCLK_VOP3:
1610 rate = rk3588_dclk_vop_get_clk(priv, clk->id);
1611 break;
1612 case CLK_GMAC0_PTP_REF:
1613 case CLK_GMAC1_PTP_REF:
1614 case CLK_GMAC_125M:
1615 case CLK_GMAC_50M:
1616 rate = rk3588_gmac_get_clk(priv, clk->id);
1617 break;
1618 case SCLK_UART1:
1619 case SCLK_UART2:
1620 case SCLK_UART3:
1621 case SCLK_UART4:
1622 case SCLK_UART5:
1623 case SCLK_UART6:
1624 case SCLK_UART7:
1625 case SCLK_UART8:
1626 case SCLK_UART9:
1627 rate = rk3588_uart_get_rate(priv, clk->id);
1628 break;
1629 case CLK_REF_PIPE_PHY0:
1630 case CLK_REF_PIPE_PHY1:
1631 case CLK_REF_PIPE_PHY2:
1632 rate = rk3588_pciephy_get_rate(priv, clk->id);
1633 break;
1634#endif
1635 default:
1636 return -ENOENT;
1637 }
1638
1639 return rate;
1640};
1641
1642static ulong rk3588_clk_set_rate(struct clk *clk, ulong rate)
1643{
1644 struct rk3588_clk_priv *priv = dev_get_priv(clk->dev);
1645 ulong ret = 0;
1646
1647 if (!priv->gpll_hz) {
1648 printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
1649 return -ENOENT;
1650 }
1651
1652 if (!priv->ppll_hz) {
1653 priv->ppll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[PPLL],
1654 priv->cru, PPLL);
1655 }
1656
1657 switch (clk->id) {
1658 case PLL_CPLL:
1659 ret = rockchip_pll_set_rate(&rk3588_pll_clks[CPLL], priv->cru,
1660 CPLL, rate);
1661 priv->cpll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[CPLL],
1662 priv->cru, CPLL);
1663 break;
1664 case PLL_GPLL:
1665 ret = rockchip_pll_set_rate(&rk3588_pll_clks[GPLL], priv->cru,
1666 GPLL, rate);
1667 priv->gpll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[GPLL],
1668 priv->cru, GPLL);
1669 break;
1670 case PLL_NPLL:
1671 ret = rockchip_pll_set_rate(&rk3588_pll_clks[NPLL], priv->cru,
1672 NPLL, rate);
1673 break;
1674 case PLL_V0PLL:
1675 ret = rockchip_pll_set_rate(&rk3588_pll_clks[V0PLL], priv->cru,
1676 V0PLL, rate);
1677 priv->v0pll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[V0PLL],
1678 priv->cru, V0PLL);
1679 break;
1680 case PLL_AUPLL:
1681 ret = rockchip_pll_set_rate(&rk3588_pll_clks[AUPLL], priv->cru,
1682 AUPLL, rate);
1683 priv->aupll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[AUPLL],
1684 priv->cru, AUPLL);
1685 break;
1686 case PLL_PPLL:
1687 ret = rockchip_pll_set_rate(&rk3588_pll_clks[PPLL], priv->cru,
1688 PPLL, rate);
1689 priv->ppll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[PPLL],
1690 priv->cru, PPLL);
1691 break;
1692 case ACLK_CENTER_ROOT:
1693 case PCLK_CENTER_ROOT:
1694 case HCLK_CENTER_ROOT:
1695 case ACLK_CENTER_LOW_ROOT:
1696 ret = rk3588_center_set_clk(priv, clk->id, rate);
1697 break;
1698 case ACLK_TOP_ROOT:
1699 case PCLK_TOP_ROOT:
1700 case ACLK_LOW_TOP_ROOT:
1701 ret = rk3588_top_set_clk(priv, clk->id, rate);
1702 break;
1703 case CLK_I2C0:
1704 case CLK_I2C1:
1705 case CLK_I2C2:
1706 case CLK_I2C3:
1707 case CLK_I2C4:
1708 case CLK_I2C5:
1709 case CLK_I2C6:
1710 case CLK_I2C7:
1711 case CLK_I2C8:
1712 ret = rk3588_i2c_set_clk(priv, clk->id, rate);
1713 break;
1714 case CLK_SPI0:
1715 case CLK_SPI1:
1716 case CLK_SPI2:
1717 case CLK_SPI3:
1718 case CLK_SPI4:
1719 ret = rk3588_spi_set_clk(priv, clk->id, rate);
1720 break;
1721 case CLK_PWM1:
1722 case CLK_PWM2:
1723 case CLK_PWM3:
1724 case CLK_PMU1PWM:
1725 ret = rk3588_pwm_set_clk(priv, clk->id, rate);
1726 break;
1727 case CLK_SARADC:
1728 case CLK_TSADC:
1729 ret = rk3588_adc_set_clk(priv, clk->id, rate);
1730 break;
1731 case CCLK_SRC_SDIO:
1732 case CCLK_EMMC:
1733 case BCLK_EMMC:
1734 case SCLK_SFC:
1735 case DCLK_DECOM:
1736 ret = rk3588_mmc_set_clk(priv, clk->id, rate);
1737 break;
Jonas Karlman291343a2023-04-18 16:46:42 +00001738 case TMCLK_EMMC:
Jagan Teki7d031ee2023-01-30 20:27:36 +05301739 case TCLK_WDT0:
1740 ret = OSC_HZ;
1741 break;
Eugen Hristev3d3f4072023-04-13 14:36:45 +03001742 case PCLK_PMU0_ROOT:
1743 case CLK_GPU:
1744 case HCLK_PMU_CM0_ROOT:
1745 case ACLK_BUS_ROOT:
1746 case CLK_150M_SRC:
1747 ret = 0;
1748 break;
Jagan Teki7d031ee2023-01-30 20:27:36 +05301749#ifndef CONFIG_SPL_BUILD
1750 case CLK_AUX16M_0:
1751 case CLK_AUX16M_1:
Jonas Karlman55152232023-03-14 00:38:27 +00001752 ret = rk3588_aux16m_set_clk(priv, clk->id, rate);
Jagan Teki7d031ee2023-01-30 20:27:36 +05301753 break;
1754 case ACLK_VOP_ROOT:
1755 case ACLK_VOP:
1756 case ACLK_VOP_LOW_ROOT:
1757 case HCLK_VOP_ROOT:
1758 ret = rk3588_aclk_vop_set_clk(priv, clk->id, rate);
1759 break;
1760 case DCLK_VOP0:
1761 case DCLK_VOP0_SRC:
1762 case DCLK_VOP1:
1763 case DCLK_VOP1_SRC:
1764 case DCLK_VOP2:
1765 case DCLK_VOP2_SRC:
1766 case DCLK_VOP3:
1767 ret = rk3588_dclk_vop_set_clk(priv, clk->id, rate);
1768 break;
1769 case CLK_GMAC0_PTP_REF:
1770 case CLK_GMAC1_PTP_REF:
1771 case CLK_GMAC_125M:
1772 case CLK_GMAC_50M:
1773 ret = rk3588_gmac_set_clk(priv, clk->id, rate);
1774 break;
1775 case SCLK_UART1:
1776 case SCLK_UART2:
1777 case SCLK_UART3:
1778 case SCLK_UART4:
1779 case SCLK_UART5:
1780 case SCLK_UART6:
1781 case SCLK_UART7:
1782 case SCLK_UART8:
1783 case SCLK_UART9:
1784 ret = rk3588_uart_set_rate(priv, clk->id, rate);
1785 break;
1786 case CLK_REF_PIPE_PHY0:
1787 case CLK_REF_PIPE_PHY1:
1788 case CLK_REF_PIPE_PHY2:
1789 ret = rk3588_pciephy_set_rate(priv, clk->id, rate);
1790 break;
1791#endif
1792 default:
1793 return -ENOENT;
1794 }
1795
1796 return ret;
1797};
1798
1799#define ROCKCHIP_MMC_DELAY_SEL BIT(10)
1800#define ROCKCHIP_MMC_DEGREE_MASK 0x3
1801#define ROCKCHIP_MMC_DELAYNUM_OFFSET 2
1802#define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
1803
1804#define PSECS_PER_SEC 1000000000000LL
1805/*
1806 * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to
1807 * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg.
1808 */
1809#define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60
1810
1811#if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA))
1812static int __maybe_unused rk3588_dclk_vop_set_parent(struct clk *clk,
1813 struct clk *parent)
1814{
1815 struct rk3588_clk_priv *priv = dev_get_priv(clk->dev);
1816 struct rk3588_cru *cru = priv->cru;
1817 u32 sel;
1818 const char *clock_dev_name = parent->dev->name;
1819
1820 if (parent->id == PLL_V0PLL)
1821 sel = 2;
1822 else if (parent->id == PLL_GPLL)
1823 sel = 0;
1824 else if (parent->id == PLL_CPLL)
1825 sel = 1;
1826 else
1827 sel = 3;
1828
1829 switch (clk->id) {
1830 case DCLK_VOP0_SRC:
1831 rk_clrsetreg(&cru->clksel_con[111], DCLK0_VOP_SRC_SEL_MASK,
1832 sel << DCLK0_VOP_SRC_SEL_SHIFT);
1833 break;
1834 case DCLK_VOP1_SRC:
1835 rk_clrsetreg(&cru->clksel_con[111], DCLK1_VOP_SRC_SEL_MASK,
1836 sel << DCLK1_VOP_SRC_SEL_SHIFT);
1837 break;
1838 case DCLK_VOP2_SRC:
1839 rk_clrsetreg(&cru->clksel_con[112], DCLK2_VOP_SRC_SEL_MASK,
1840 sel << DCLK2_VOP_SRC_SEL_SHIFT);
1841 break;
1842 case DCLK_VOP3:
1843 rk_clrsetreg(&cru->clksel_con[113], DCLK3_VOP_SRC_SEL_MASK,
1844 sel << DCLK3_VOP_SRC_SEL_SHIFT);
1845 break;
1846 case DCLK_VOP0:
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], DCLK0_VOP_SEL_MASK,
1854 sel << DCLK0_VOP_SEL_SHIFT);
1855 break;
1856 case DCLK_VOP1:
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], DCLK1_VOP_SEL_MASK,
1864 sel << DCLK1_VOP_SEL_SHIFT);
1865 break;
1866 case DCLK_VOP2:
1867 if (!strcmp(clock_dev_name, "hdmiphypll_clk0"))
1868 sel = 1;
1869 else if (!strcmp(clock_dev_name, "hdmiphypll_clk1"))
1870 sel = 2;
1871 else
1872 sel = 0;
1873 rk_clrsetreg(&cru->clksel_con[112], DCLK2_VOP_SEL_MASK,
1874 sel << DCLK2_VOP_SEL_SHIFT);
1875 break;
1876 default:
1877 return -EINVAL;
1878 }
1879 return 0;
1880}
1881
1882static int rk3588_clk_set_parent(struct clk *clk, struct clk *parent)
1883{
1884 switch (clk->id) {
1885 case DCLK_VOP0_SRC:
1886 case DCLK_VOP1_SRC:
1887 case DCLK_VOP2_SRC:
1888 case DCLK_VOP0:
1889 case DCLK_VOP1:
1890 case DCLK_VOP2:
1891 case DCLK_VOP3:
1892 return rk3588_dclk_vop_set_parent(clk, parent);
1893 default:
1894 return -ENOENT;
1895 }
1896
1897 return 0;
1898}
1899#endif
1900
1901static struct clk_ops rk3588_clk_ops = {
1902 .get_rate = rk3588_clk_get_rate,
1903 .set_rate = rk3588_clk_set_rate,
1904#if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA))
1905 .set_parent = rk3588_clk_set_parent,
1906#endif
1907};
1908
1909static void rk3588_clk_init(struct rk3588_clk_priv *priv)
1910{
1911 int ret, div;
1912
1913 div = DIV_ROUND_UP(GPLL_HZ, 300 * MHz);
1914 rk_clrsetreg(&priv->cru->clksel_con[38],
1915 ACLK_BUS_ROOT_SEL_MASK |
1916 ACLK_BUS_ROOT_DIV_MASK,
1917 div << ACLK_BUS_ROOT_DIV_SHIFT);
1918
1919 if (priv->cpll_hz != CPLL_HZ) {
1920 ret = rockchip_pll_set_rate(&rk3588_pll_clks[CPLL], priv->cru,
1921 CPLL, CPLL_HZ);
1922 if (!ret)
1923 priv->cpll_hz = CPLL_HZ;
1924 }
1925 if (priv->gpll_hz != GPLL_HZ) {
1926 ret = rockchip_pll_set_rate(&rk3588_pll_clks[GPLL], priv->cru,
1927 GPLL, GPLL_HZ);
1928 if (!ret)
1929 priv->gpll_hz = GPLL_HZ;
1930 }
1931
1932#ifdef CONFIG_PCI
1933 if (priv->ppll_hz != PPLL_HZ) {
1934 ret = rockchip_pll_set_rate(&rk3588_pll_clks[PPLL], priv->cru,
1935 PPLL, PPLL_HZ);
1936 priv->ppll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[PPLL],
1937 priv->cru, PPLL);
1938 }
1939#endif
1940 rk_clrsetreg(&priv->cru->clksel_con[9],
1941 ACLK_TOP_S400_SEL_MASK |
1942 ACLK_TOP_S200_SEL_MASK,
1943 (ACLK_TOP_S400_SEL_400M << ACLK_TOP_S400_SEL_SHIFT) |
1944 (ACLK_TOP_S200_SEL_200M << ACLK_TOP_S200_SEL_SHIFT));
1945}
1946
1947static int rk3588_clk_probe(struct udevice *dev)
1948{
1949 struct rk3588_clk_priv *priv = dev_get_priv(dev);
1950 int ret;
1951
1952 priv->sync_kernel = false;
1953
1954#ifdef CONFIG_SPL_BUILD
1955 rockchip_pll_set_rate(&rk3588_pll_clks[B0PLL], priv->cru,
1956 B0PLL, LPLL_HZ);
1957 rockchip_pll_set_rate(&rk3588_pll_clks[B1PLL], priv->cru,
1958 B1PLL, LPLL_HZ);
1959 if (!priv->armclk_enter_hz) {
1960 ret = rockchip_pll_set_rate(&rk3588_pll_clks[LPLL], priv->cru,
1961 LPLL, LPLL_HZ);
1962 priv->armclk_enter_hz =
1963 rockchip_pll_get_rate(&rk3588_pll_clks[LPLL],
1964 priv->cru, LPLL);
1965 priv->armclk_init_hz = priv->armclk_enter_hz;
1966 }
1967#endif
1968
1969 priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
1970 if (IS_ERR(priv->grf))
1971 return PTR_ERR(priv->grf);
1972
1973 rk3588_clk_init(priv);
1974
1975 /* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
1976 ret = clk_set_defaults(dev, 1);
1977 if (ret)
1978 debug("%s clk_set_defaults failed %d\n", __func__, ret);
1979 else
1980 priv->sync_kernel = true;
1981
1982 return 0;
1983}
1984
1985static int rk3588_clk_ofdata_to_platdata(struct udevice *dev)
1986{
1987 struct rk3588_clk_priv *priv = dev_get_priv(dev);
1988
1989 priv->cru = dev_read_addr_ptr(dev);
1990
1991 return 0;
1992}
1993
1994static int rk3588_clk_bind(struct udevice *dev)
1995{
1996 int ret;
1997 struct udevice *sys_child;
1998 struct sysreset_reg *priv;
1999
2000 /* The reset driver does not have a device node, so bind it here */
2001 ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
2002 &sys_child);
2003 if (ret) {
2004 debug("Warning: No sysreset driver: ret=%d\n", ret);
2005 } else {
2006 priv = malloc(sizeof(struct sysreset_reg));
2007 priv->glb_srst_fst_value = offsetof(struct rk3588_cru,
2008 glb_srst_fst);
2009 priv->glb_srst_snd_value = offsetof(struct rk3588_cru,
2010 glb_srsr_snd);
2011 dev_set_priv(sys_child, priv);
2012 }
2013
2014#if CONFIG_IS_ENABLED(RESET_ROCKCHIP)
2015 ret = offsetof(struct rk3588_cru, softrst_con[0]);
Eugen Hristev2f550822023-05-15 13:55:04 +03002016 ret = rk3588_reset_bind_lut(dev, ret, 49158);
Jagan Teki7d031ee2023-01-30 20:27:36 +05302017 if (ret)
Eugen Hristevf1798262023-04-11 10:17:56 +03002018 debug("Warning: software reset driver bind failed\n");
Jagan Teki7d031ee2023-01-30 20:27:36 +05302019#endif
2020
2021 return 0;
2022}
2023
2024static const struct udevice_id rk3588_clk_ids[] = {
2025 { .compatible = "rockchip,rk3588-cru" },
2026 { }
2027};
2028
2029U_BOOT_DRIVER(rockchip_rk3588_cru) = {
2030 .name = "rockchip_rk3588_cru",
2031 .id = UCLASS_CLK,
2032 .of_match = rk3588_clk_ids,
2033 .priv_auto = sizeof(struct rk3588_clk_priv),
2034 .of_to_plat = rk3588_clk_ofdata_to_platdata,
2035 .ops = &rk3588_clk_ops,
2036 .bind = rk3588_clk_bind,
2037 .probe = rk3588_clk_probe,
2038};
Jonas Karlmanb4505902023-04-17 19:07:20 +00002039
2040#ifdef CONFIG_SPL_BUILD
2041#define SCRU_BASE 0xfd7d0000
2042
2043static ulong rk3588_scru_clk_get_rate(struct clk *clk)
2044{
2045 u32 con, div, sel, parent;
2046
2047 switch (clk->id) {
2048 case SCMI_CCLK_SD:
2049 con = readl(SCRU_BASE + RK3588_CLKSEL_CON(3));
2050 sel = (con & SCMI_CCLK_SD_SEL_MASK) >> SCMI_CCLK_SD_SEL_SHIFT;
2051 div = (con & SCMI_CCLK_SD_DIV_MASK) >> SCMI_CCLK_SD_DIV_SHIFT;
2052 if (sel == SCMI_CCLK_SD_SEL_GPLL)
2053 parent = GPLL_HZ;
2054 else if (sel == SCMI_CCLK_SD_SEL_SPLL)
2055 parent = SPLL_HZ;
2056 else
2057 parent = OSC_HZ;
2058 return DIV_TO_RATE(parent, div);
2059 case SCMI_HCLK_SD:
2060 con = readl(SCRU_BASE + RK3588_CLKSEL_CON(1));
2061 sel = (con & SCMI_HCLK_SD_SEL_MASK) >> SCMI_HCLK_SD_SEL_SHIFT;
2062 if (sel == SCMI_HCLK_SD_SEL_150M)
2063 return 150 * MHz;
2064 else if (sel == SCMI_HCLK_SD_SEL_100M)
2065 return 100 * MHz;
2066 else if (sel == SCMI_HCLK_SD_SEL_50M)
2067 return 50 * MHz;
2068 else
2069 return OSC_HZ;
2070 default:
2071 return -ENOENT;
2072 }
2073}
2074
2075static ulong rk3588_scru_clk_set_rate(struct clk *clk, ulong rate)
2076{
2077 u32 div, sel;
2078
2079 switch (clk->id) {
2080 case SCMI_CCLK_SD:
2081 if ((OSC_HZ % rate) == 0) {
2082 sel = SCMI_CCLK_SD_SEL_24M;
2083 div = DIV_ROUND_UP(OSC_HZ, rate);
2084 } else if ((SPLL_HZ % rate) == 0) {
2085 sel = SCMI_CCLK_SD_SEL_SPLL;
2086 div = DIV_ROUND_UP(SPLL_HZ, rate);
2087 } else {
2088 sel = SCMI_CCLK_SD_SEL_GPLL;
2089 div = DIV_ROUND_UP(GPLL_HZ, rate);
2090 }
2091 rk_clrsetreg(SCRU_BASE + RK3588_CLKSEL_CON(3),
2092 SCMI_CCLK_SD_SEL_MASK | SCMI_CCLK_SD_DIV_MASK,
2093 sel << SCMI_CCLK_SD_SEL_SHIFT |
2094 (div - 1) << SCMI_CCLK_SD_DIV_SHIFT);
2095 break;
2096 case SCMI_HCLK_SD:
2097 if (rate >= 150 * MHz)
2098 sel = SCMI_HCLK_SD_SEL_150M;
2099 else if (rate >= 100 * MHz)
2100 sel = SCMI_HCLK_SD_SEL_100M;
2101 else if (rate >= 50 * MHz)
2102 sel = SCMI_HCLK_SD_SEL_50M;
2103 else
2104 sel = SCMI_HCLK_SD_SEL_24M;
2105 rk_clrsetreg(SCRU_BASE + RK3588_CLKSEL_CON(1),
2106 SCMI_HCLK_SD_SEL_MASK,
2107 sel << SCMI_HCLK_SD_SEL_SHIFT);
2108 break;
2109 default:
2110 return -ENOENT;
2111 }
2112
2113 return rk3588_scru_clk_get_rate(clk);
2114}
2115
2116static const struct clk_ops rk3588_scru_clk_ops = {
2117 .get_rate = rk3588_scru_clk_get_rate,
2118 .set_rate = rk3588_scru_clk_set_rate,
2119};
2120
2121U_BOOT_DRIVER(rockchip_rk3588_scru) = {
2122 .name = "rockchip_rk3588_scru",
2123 .id = UCLASS_CLK,
2124 .ops = &rk3588_scru_clk_ops,
2125};
2126
2127static int rk3588_scmi_spl_glue_bind(struct udevice *dev)
2128{
2129 ofnode node;
2130 u32 protocol_id;
2131 const char *name;
2132
2133 dev_for_each_subnode(node, dev) {
2134 if (!ofnode_is_enabled(node))
2135 continue;
2136
2137 if (ofnode_read_u32(node, "reg", &protocol_id))
2138 continue;
2139
2140 if (protocol_id != SCMI_PROTOCOL_ID_CLOCK)
2141 continue;
2142
2143 name = ofnode_get_name(node);
2144 return device_bind_driver_to_node(dev, "rockchip_rk3588_scru",
2145 name, node, NULL);
2146 }
2147
2148 return -ENOENT;
2149}
2150
2151static const struct udevice_id rk3588_scmi_spl_glue_ids[] = {
2152 { .compatible = "arm,scmi-smc" },
2153 { }
2154};
2155
2156U_BOOT_DRIVER(rk3588_scmi_spl_glue) = {
2157 .name = "rk3588_scmi_spl_glue",
2158 .id = UCLASS_NOP,
2159 .of_match = rk3588_scmi_spl_glue_ids,
2160 .bind = rk3588_scmi_spl_glue_bind,
2161};
2162#endif