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