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