1 // 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>
12 #include <syscon.h>
13 #include <asm/arch/clock.h>
14 #include <asm/arch/cru_rk3588.h>
15 #include <asm/arch/hardware.h>
16 #include <asm/io.h>
17 #include <dm/lists.h>
18 #include <dt-bindings/clock/rk3588-cru.h>
19
20 DECLARE_GLOBAL_DATA_PTR;
21
22 #define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1))
23
24 static 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(1150000000, 3, 575, 2, 0),
30 RK3588_PLL_RATE(1100000000, 3, 550, 2, 0),
31 RK3588_PLL_RATE(1008000000, 2, 336, 2, 0),
32 RK3588_PLL_RATE(1000000000, 3, 500, 2, 0),
33 RK3588_PLL_RATE(900000000, 2, 300, 2, 0),
34 RK3588_PLL_RATE(850000000, 3, 425, 2, 0),
35 RK3588_PLL_RATE(816000000, 2, 272, 2, 0),
36 RK3588_PLL_RATE(786432000, 2, 262, 2, 9437),
37 RK3588_PLL_RATE(786000000, 1, 131, 2, 0),
38 RK3588_PLL_RATE(742500000, 4, 495, 2, 0),
39 RK3588_PLL_RATE(722534400, 8, 963, 2, 24850),
40 RK3588_PLL_RATE(600000000, 2, 200, 2, 0),
41 RK3588_PLL_RATE(594000000, 2, 198, 2, 0),
42 RK3588_PLL_RATE(200000000, 3, 400, 4, 0),
43 RK3588_PLL_RATE(100000000, 3, 400, 5, 0),
44 { /* sentinel */ },
45 };
46
47 static struct rockchip_pll_clock rk3588_pll_clks[] = {
48 [B0PLL] = PLL(pll_rk3588, PLL_B0PLL, RK3588_B0_PLL_CON(0),
49 RK3588_B0_PLL_MODE_CON, 0, 15, 0,
50 rk3588_pll_rates),
51 [B1PLL] = PLL(pll_rk3588, PLL_B1PLL, RK3588_B1_PLL_CON(8),
52 RK3588_B1_PLL_MODE_CON, 0, 15, 0,
53 rk3588_pll_rates),
54 [LPLL] = PLL(pll_rk3588, PLL_LPLL, RK3588_LPLL_CON(16),
55 RK3588_LPLL_MODE_CON, 0, 15, 0, rk3588_pll_rates),
56 [V0PLL] = PLL(pll_rk3588, PLL_V0PLL, RK3588_PLL_CON(88),
57 RK3588_MODE_CON0, 4, 15, 0, rk3588_pll_rates),
58 [AUPLL] = PLL(pll_rk3588, PLL_AUPLL, RK3588_PLL_CON(96),
59 RK3588_MODE_CON0, 6, 15, 0, rk3588_pll_rates),
60 [CPLL] = PLL(pll_rk3588, PLL_CPLL, RK3588_PLL_CON(104),
61 RK3588_MODE_CON0, 8, 15, 0, rk3588_pll_rates),
62 [GPLL] = PLL(pll_rk3588, PLL_GPLL, RK3588_PLL_CON(112),
63 RK3588_MODE_CON0, 2, 15, 0, rk3588_pll_rates),
64 [NPLL] = PLL(pll_rk3588, PLL_NPLL, RK3588_PLL_CON(120),
65 RK3588_MODE_CON0, 0, 15, 0, rk3588_pll_rates),
66 [PPLL] = PLL(pll_rk3588, PLL_PPLL, RK3588_PMU_PLL_CON(128),
67 RK3588_MODE_CON0, 10, 15, 0, rk3588_pll_rates),
68 };
69
70 #ifndef CONFIG_SPL_BUILD
71 #define RK3588_CLK_DUMP(_id, _name, _iscru) \
72 { \
73 .id = _id, \
74 .name = _name, \
75 .is_cru = _iscru, \
76 }
77
78 static const struct rk3588_clk_info clks_dump[] = {
79 RK3588_CLK_DUMP(PLL_B0PLL, "b0pll", true),
80 RK3588_CLK_DUMP(PLL_B1PLL, "b1pll", true),
81 RK3588_CLK_DUMP(PLL_LPLL, "lpll", true),
82 RK3588_CLK_DUMP(PLL_V0PLL, "v0pll", true),
83 RK3588_CLK_DUMP(PLL_AUPLL, "aupll", true),
84 RK3588_CLK_DUMP(PLL_CPLL, "cpll", true),
85 RK3588_CLK_DUMP(PLL_GPLL, "gpll", true),
86 RK3588_CLK_DUMP(PLL_NPLL, "npll", true),
87 RK3588_CLK_DUMP(PLL_PPLL, "ppll", true),
88 RK3588_CLK_DUMP(ACLK_CENTER_ROOT, "aclk_center_root", true),
89 RK3588_CLK_DUMP(PCLK_CENTER_ROOT, "pclk_center_root", true),
90 RK3588_CLK_DUMP(HCLK_CENTER_ROOT, "hclk_center_root", true),
91 RK3588_CLK_DUMP(ACLK_CENTER_LOW_ROOT, "aclk_center_low_root", true),
92 RK3588_CLK_DUMP(ACLK_TOP_ROOT, "aclk_top_root", true),
93 RK3588_CLK_DUMP(PCLK_TOP_ROOT, "pclk_top_root", true),
94 RK3588_CLK_DUMP(ACLK_LOW_TOP_ROOT, "aclk_low_top_root", true),
95 };
96 #endif
97
98 #ifndef CONFIG_SPL_BUILD
99 /*
100 *
101 * rational_best_approximation(31415, 10000,
102 * (1 << 8) - 1, (1 << 5) - 1, &n, &d);
103 *
104 * you may look at given_numerator as a fixed point number,
105 * with the fractional part size described in given_denominator.
106 *
107 * for theoretical background, see:
108 * http://en.wikipedia.org/wiki/Continued_fraction
109 */
rational_best_approximation(unsigned long given_numerator,unsigned long given_denominator,unsigned long max_numerator,unsigned long max_denominator,unsigned long * best_numerator,unsigned long * best_denominator)110 static void rational_best_approximation(unsigned long given_numerator,
111 unsigned long given_denominator,
112 unsigned long max_numerator,
113 unsigned long max_denominator,
114 unsigned long *best_numerator,
115 unsigned long *best_denominator)
116 {
117 unsigned long n, d, n0, d0, n1, d1;
118
119 n = given_numerator;
120 d = given_denominator;
121 n0 = 0;
122 d1 = 0;
123 n1 = 1;
124 d0 = 1;
125 for (;;) {
126 unsigned long t, a;
127
128 if (n1 > max_numerator || d1 > max_denominator) {
129 n1 = n0;
130 d1 = d0;
131 break;
132 }
133 if (d == 0)
134 break;
135 t = d;
136 a = n / d;
137 d = n % d;
138 n = t;
139 t = n0 + a * n1;
140 n0 = n1;
141 n1 = t;
142 t = d0 + a * d1;
143 d0 = d1;
144 d1 = t;
145 }
146 *best_numerator = n1;
147 *best_denominator = d1;
148 }
149 #endif
150
rk3588_center_get_clk(struct rk3588_clk_priv * priv,ulong clk_id)151 static ulong rk3588_center_get_clk(struct rk3588_clk_priv *priv, ulong clk_id)
152 {
153 struct rk3588_cru *cru = priv->cru;
154 u32 con, sel, rate;
155
156 switch (clk_id) {
157 case ACLK_CENTER_ROOT:
158 con = readl(&cru->clksel_con[165]);
159 sel = (con & ACLK_CENTER_ROOT_SEL_MASK) >>
160 ACLK_CENTER_ROOT_SEL_SHIFT;
161 if (sel == ACLK_CENTER_ROOT_SEL_700M)
162 rate = 702 * MHz;
163 else if (sel == ACLK_CENTER_ROOT_SEL_400M)
164 rate = 396 * MHz;
165 else if (sel == ACLK_CENTER_ROOT_SEL_200M)
166 rate = 200 * MHz;
167 else
168 rate = OSC_HZ;
169 break;
170 case ACLK_CENTER_LOW_ROOT:
171 con = readl(&cru->clksel_con[165]);
172 sel = (con & ACLK_CENTER_LOW_ROOT_SEL_MASK) >>
173 ACLK_CENTER_LOW_ROOT_SEL_SHIFT;
174 if (sel == ACLK_CENTER_LOW_ROOT_SEL_500M)
175 rate = 500 * MHz;
176 else if (sel == ACLK_CENTER_LOW_ROOT_SEL_250M)
177 rate = 250 * MHz;
178 else if (sel == ACLK_CENTER_LOW_ROOT_SEL_100M)
179 rate = 100 * MHz;
180 else
181 rate = OSC_HZ;
182 break;
183 case HCLK_CENTER_ROOT:
184 con = readl(&cru->clksel_con[165]);
185 sel = (con & HCLK_CENTER_ROOT_SEL_MASK) >>
186 HCLK_CENTER_ROOT_SEL_SHIFT;
187 if (sel == HCLK_CENTER_ROOT_SEL_400M)
188 rate = 396 * MHz;
189 else if (sel == HCLK_CENTER_ROOT_SEL_200M)
190 rate = 200 * MHz;
191 else if (sel == HCLK_CENTER_ROOT_SEL_100M)
192 rate = 100 * MHz;
193 else
194 rate = OSC_HZ;
195 break;
196 case PCLK_CENTER_ROOT:
197 con = readl(&cru->clksel_con[165]);
198 sel = (con & PCLK_CENTER_ROOT_SEL_MASK) >>
199 PCLK_CENTER_ROOT_SEL_SHIFT;
200 if (sel == PCLK_CENTER_ROOT_SEL_200M)
201 rate = 200 * MHz;
202 else if (sel == PCLK_CENTER_ROOT_SEL_100M)
203 rate = 100 * MHz;
204 else if (sel == PCLK_CENTER_ROOT_SEL_50M)
205 rate = 50 * MHz;
206 else
207 rate = OSC_HZ;
208 break;
209 default:
210 return -ENOENT;
211 }
212
213 return rate;
214 }
215
rk3588_center_set_clk(struct rk3588_clk_priv * priv,ulong clk_id,ulong rate)216 static ulong rk3588_center_set_clk(struct rk3588_clk_priv *priv,
217 ulong clk_id, ulong rate)
218 {
219 struct rk3588_cru *cru = priv->cru;
220 int src_clk;
221
222 switch (clk_id) {
223 case ACLK_CENTER_ROOT:
224 if (rate >= 700 * MHz)
225 src_clk = ACLK_CENTER_ROOT_SEL_700M;
226 else if (rate >= 396 * MHz)
227 src_clk = ACLK_CENTER_ROOT_SEL_400M;
228 else if (rate >= 200 * MHz)
229 src_clk = ACLK_CENTER_ROOT_SEL_200M;
230 else
231 src_clk = ACLK_CENTER_ROOT_SEL_24M;
232 rk_clrsetreg(&cru->clksel_con[165],
233 ACLK_CENTER_ROOT_SEL_MASK,
234 src_clk << ACLK_CENTER_ROOT_SEL_SHIFT);
235 break;
236 case ACLK_CENTER_LOW_ROOT:
237 if (rate >= 500 * MHz)
238 src_clk = ACLK_CENTER_LOW_ROOT_SEL_500M;
239 else if (rate >= 250 * MHz)
240 src_clk = ACLK_CENTER_LOW_ROOT_SEL_250M;
241 else if (rate >= 99 * MHz)
242 src_clk = ACLK_CENTER_LOW_ROOT_SEL_100M;
243 else
244 src_clk = ACLK_CENTER_LOW_ROOT_SEL_24M;
245 rk_clrsetreg(&cru->clksel_con[165],
246 ACLK_CENTER_LOW_ROOT_SEL_MASK,
247 src_clk << ACLK_CENTER_LOW_ROOT_SEL_SHIFT);
248 break;
249 case HCLK_CENTER_ROOT:
250 if (rate >= 396 * MHz)
251 src_clk = HCLK_CENTER_ROOT_SEL_400M;
252 else if (rate >= 198 * MHz)
253 src_clk = HCLK_CENTER_ROOT_SEL_200M;
254 else if (rate >= 99 * MHz)
255 src_clk = HCLK_CENTER_ROOT_SEL_100M;
256 else
257 src_clk = HCLK_CENTER_ROOT_SEL_24M;
258 rk_clrsetreg(&cru->clksel_con[165],
259 HCLK_CENTER_ROOT_SEL_MASK,
260 src_clk << HCLK_CENTER_ROOT_SEL_SHIFT);
261 break;
262 case PCLK_CENTER_ROOT:
263 if (rate >= 198 * MHz)
264 src_clk = PCLK_CENTER_ROOT_SEL_200M;
265 else if (rate >= 99 * MHz)
266 src_clk = PCLK_CENTER_ROOT_SEL_100M;
267 else if (rate >= 50 * MHz)
268 src_clk = PCLK_CENTER_ROOT_SEL_50M;
269 else
270 src_clk = PCLK_CENTER_ROOT_SEL_24M;
271 rk_clrsetreg(&cru->clksel_con[165],
272 PCLK_CENTER_ROOT_SEL_MASK,
273 src_clk << PCLK_CENTER_ROOT_SEL_SHIFT);
274 break;
275 default:
276 printf("do not support this center freq\n");
277 return -EINVAL;
278 }
279
280 return rk3588_center_get_clk(priv, clk_id);
281 }
282
rk3588_top_get_clk(struct rk3588_clk_priv * priv,ulong clk_id)283 static ulong rk3588_top_get_clk(struct rk3588_clk_priv *priv, ulong clk_id)
284 {
285 struct rk3588_cru *cru = priv->cru;
286 u32 con, sel, div, rate, prate;
287
288 switch (clk_id) {
289 case ACLK_TOP_ROOT:
290 con = readl(&cru->clksel_con[8]);
291 div = (con & ACLK_TOP_ROOT_DIV_MASK) >>
292 ACLK_TOP_ROOT_DIV_SHIFT;
293 sel = (con & ACLK_TOP_ROOT_SRC_SEL_MASK) >>
294 ACLK_TOP_ROOT_SRC_SEL_SHIFT;
295 if (sel == ACLK_TOP_ROOT_SRC_SEL_CPLL)
296 prate = priv->cpll_hz;
297 else
298 prate = priv->gpll_hz;
299 return DIV_TO_RATE(prate, div);
300 case ACLK_LOW_TOP_ROOT:
301 con = readl(&cru->clksel_con[8]);
302 div = (con & ACLK_LOW_TOP_ROOT_DIV_MASK) >>
303 ACLK_LOW_TOP_ROOT_DIV_SHIFT;
304 sel = (con & ACLK_LOW_TOP_ROOT_SRC_SEL_MASK) >>
305 ACLK_LOW_TOP_ROOT_SRC_SEL_SHIFT;
306 if (sel == ACLK_LOW_TOP_ROOT_SRC_SEL_CPLL)
307 prate = priv->cpll_hz;
308 else
309 prate = priv->gpll_hz;
310 return DIV_TO_RATE(prate, div);
311 case PCLK_TOP_ROOT:
312 con = readl(&cru->clksel_con[8]);
313 sel = (con & PCLK_TOP_ROOT_SEL_MASK) >> PCLK_TOP_ROOT_SEL_SHIFT;
314 if (sel == PCLK_TOP_ROOT_SEL_100M)
315 rate = 100 * MHz;
316 else if (sel == PCLK_TOP_ROOT_SEL_50M)
317 rate = 50 * MHz;
318 else
319 rate = OSC_HZ;
320 break;
321 default:
322 return -ENOENT;
323 }
324
325 return rate;
326 }
327
rk3588_top_set_clk(struct rk3588_clk_priv * priv,ulong clk_id,ulong rate)328 static ulong rk3588_top_set_clk(struct rk3588_clk_priv *priv,
329 ulong clk_id, ulong rate)
330 {
331 struct rk3588_cru *cru = priv->cru;
332 int src_clk, src_clk_div;
333
334 switch (clk_id) {
335 case ACLK_TOP_ROOT:
336 if (!(priv->cpll_hz % rate)) {
337 src_clk = ACLK_TOP_ROOT_SRC_SEL_CPLL;
338 src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate);
339 } else {
340 src_clk = ACLK_TOP_ROOT_SRC_SEL_GPLL;
341 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
342 }
343 assert(src_clk_div - 1 <= 31);
344 rk_clrsetreg(&cru->clksel_con[8],
345 ACLK_TOP_ROOT_DIV_MASK |
346 ACLK_TOP_ROOT_SRC_SEL_MASK,
347 (src_clk <<
348 ACLK_TOP_ROOT_SRC_SEL_SHIFT) |
349 (src_clk_div - 1) << ACLK_TOP_ROOT_DIV_SHIFT);
350 break;
351 case ACLK_LOW_TOP_ROOT:
352 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
353 assert(src_clk_div - 1 <= 31);
354 rk_clrsetreg(&cru->clksel_con[8],
355 ACLK_LOW_TOP_ROOT_DIV_MASK |
356 ACLK_LOW_TOP_ROOT_SRC_SEL_MASK,
357 (ACLK_LOW_TOP_ROOT_SRC_SEL_GPLL <<
358 ACLK_LOW_TOP_ROOT_SRC_SEL_SHIFT) |
359 (src_clk_div - 1) << ACLK_LOW_TOP_ROOT_DIV_SHIFT);
360 break;
361 case PCLK_TOP_ROOT:
362 if (rate == 100 * MHz)
363 src_clk = PCLK_TOP_ROOT_SEL_100M;
364 else if (rate == 50 * MHz)
365 src_clk = PCLK_TOP_ROOT_SEL_50M;
366 else
367 src_clk = PCLK_TOP_ROOT_SEL_24M;
368 rk_clrsetreg(&cru->clksel_con[8],
369 PCLK_TOP_ROOT_SEL_MASK,
370 src_clk << PCLK_TOP_ROOT_SEL_SHIFT);
371 break;
372 default:
373 printf("do not support this top freq\n");
374 return -EINVAL;
375 }
376
377 return rk3588_top_get_clk(priv, clk_id);
378 }
379
rk3588_i2c_get_clk(struct rk3588_clk_priv * priv,ulong clk_id)380 static ulong rk3588_i2c_get_clk(struct rk3588_clk_priv *priv, ulong clk_id)
381 {
382 struct rk3588_cru *cru = priv->cru;
383 u32 sel, con;
384 ulong rate;
385
386 switch (clk_id) {
387 case CLK_I2C0:
388 con = readl(&cru->pmuclksel_con[3]);
389 sel = (con & CLK_I2C0_SEL_MASK) >> CLK_I2C0_SEL_SHIFT;
390 break;
391 case CLK_I2C1:
392 con = readl(&cru->clksel_con[38]);
393 sel = (con & CLK_I2C1_SEL_MASK) >> CLK_I2C1_SEL_SHIFT;
394 break;
395 case CLK_I2C2:
396 con = readl(&cru->clksel_con[38]);
397 sel = (con & CLK_I2C2_SEL_MASK) >> CLK_I2C2_SEL_SHIFT;
398 break;
399 case CLK_I2C3:
400 con = readl(&cru->clksel_con[38]);
401 sel = (con & CLK_I2C3_SEL_MASK) >> CLK_I2C3_SEL_SHIFT;
402 break;
403 case CLK_I2C4:
404 con = readl(&cru->clksel_con[38]);
405 sel = (con & CLK_I2C4_SEL_MASK) >> CLK_I2C4_SEL_SHIFT;
406 break;
407 case CLK_I2C5:
408 con = readl(&cru->clksel_con[38]);
409 sel = (con & CLK_I2C5_SEL_MASK) >> CLK_I2C5_SEL_SHIFT;
410 break;
411 case CLK_I2C6:
412 con = readl(&cru->clksel_con[38]);
413 sel = (con & CLK_I2C6_SEL_MASK) >> CLK_I2C6_SEL_SHIFT;
414 break;
415 case CLK_I2C7:
416 con = readl(&cru->clksel_con[38]);
417 sel = (con & CLK_I2C7_SEL_MASK) >> CLK_I2C7_SEL_SHIFT;
418 break;
419 case CLK_I2C8:
420 con = readl(&cru->clksel_con[38]);
421 sel = (con & CLK_I2C8_SEL_MASK) >> CLK_I2C8_SEL_SHIFT;
422 break;
423 default:
424 return -ENOENT;
425 }
426 if (sel == CLK_I2C_SEL_200M)
427 rate = 200 * MHz;
428 else
429 rate = 100 * MHz;
430
431 return rate;
432 }
433
rk3588_i2c_set_clk(struct rk3588_clk_priv * priv,ulong clk_id,ulong rate)434 static ulong rk3588_i2c_set_clk(struct rk3588_clk_priv *priv, ulong clk_id,
435 ulong rate)
436 {
437 struct rk3588_cru *cru = priv->cru;
438 int src_clk;
439
440 if (rate >= 198 * MHz)
441 src_clk = CLK_I2C_SEL_200M;
442 else
443 src_clk = CLK_I2C_SEL_100M;
444
445 switch (clk_id) {
446 case CLK_I2C0:
447 rk_clrsetreg(&cru->pmuclksel_con[3], CLK_I2C0_SEL_MASK,
448 src_clk << CLK_I2C0_SEL_SHIFT);
449 break;
450 case CLK_I2C1:
451 rk_clrsetreg(&cru->clksel_con[38], CLK_I2C1_SEL_MASK,
452 src_clk << CLK_I2C1_SEL_SHIFT);
453 break;
454 case CLK_I2C2:
455 rk_clrsetreg(&cru->clksel_con[38], CLK_I2C2_SEL_MASK,
456 src_clk << CLK_I2C2_SEL_SHIFT);
457 break;
458 case CLK_I2C3:
459 rk_clrsetreg(&cru->clksel_con[38], CLK_I2C3_SEL_MASK,
460 src_clk << CLK_I2C3_SEL_SHIFT);
461 break;
462 case CLK_I2C4:
463 rk_clrsetreg(&cru->clksel_con[38], CLK_I2C4_SEL_MASK,
464 src_clk << CLK_I2C4_SEL_SHIFT);
465 break;
466 case CLK_I2C5:
467 rk_clrsetreg(&cru->clksel_con[38], CLK_I2C5_SEL_MASK,
468 src_clk << CLK_I2C5_SEL_SHIFT);
469 break;
470 case CLK_I2C6:
471 rk_clrsetreg(&cru->clksel_con[38], CLK_I2C6_SEL_MASK,
472 src_clk << CLK_I2C6_SEL_SHIFT);
473 break;
474 case CLK_I2C7:
475 rk_clrsetreg(&cru->clksel_con[38], CLK_I2C7_SEL_MASK,
476 src_clk << CLK_I2C7_SEL_SHIFT);
477 break;
478 case CLK_I2C8:
479 rk_clrsetreg(&cru->clksel_con[38], CLK_I2C8_SEL_MASK,
480 src_clk << CLK_I2C8_SEL_SHIFT);
481 break;
482 default:
483 return -ENOENT;
484 }
485
486 return rk3588_i2c_get_clk(priv, clk_id);
487 }
488
rk3588_spi_get_clk(struct rk3588_clk_priv * priv,ulong clk_id)489 static ulong rk3588_spi_get_clk(struct rk3588_clk_priv *priv, ulong clk_id)
490 {
491 struct rk3588_cru *cru = priv->cru;
492 u32 sel, con;
493
494 con = readl(&cru->clksel_con[59]);
495
496 switch (clk_id) {
497 case CLK_SPI0:
498 sel = (con & CLK_SPI0_SEL_MASK) >> CLK_SPI0_SEL_SHIFT;
499 break;
500 case CLK_SPI1:
501 sel = (con & CLK_SPI1_SEL_MASK) >> CLK_SPI1_SEL_SHIFT;
502 break;
503 case CLK_SPI2:
504 sel = (con & CLK_SPI2_SEL_MASK) >> CLK_SPI2_SEL_SHIFT;
505 break;
506 case CLK_SPI3:
507 sel = (con & CLK_SPI3_SEL_MASK) >> CLK_SPI3_SEL_SHIFT;
508 break;
509 case CLK_SPI4:
510 sel = (con & CLK_SPI4_SEL_MASK) >> CLK_SPI4_SEL_SHIFT;
511 break;
512 default:
513 return -ENOENT;
514 }
515
516 switch (sel) {
517 case CLK_SPI_SEL_200M:
518 return 200 * MHz;
519 case CLK_SPI_SEL_150M:
520 return 150 * MHz;
521 case CLK_SPI_SEL_24M:
522 return OSC_HZ;
523 default:
524 return -ENOENT;
525 }
526 }
527
rk3588_spi_set_clk(struct rk3588_clk_priv * priv,ulong clk_id,ulong rate)528 static ulong rk3588_spi_set_clk(struct rk3588_clk_priv *priv,
529 ulong clk_id, ulong rate)
530 {
531 struct rk3588_cru *cru = priv->cru;
532 int src_clk;
533
534 if (rate >= 198 * MHz)
535 src_clk = CLK_SPI_SEL_200M;
536 else if (rate >= 140 * MHz)
537 src_clk = CLK_SPI_SEL_150M;
538 else
539 src_clk = CLK_SPI_SEL_24M;
540
541 switch (clk_id) {
542 case CLK_SPI0:
543 rk_clrsetreg(&cru->clksel_con[59],
544 CLK_SPI0_SEL_MASK,
545 src_clk << CLK_SPI0_SEL_SHIFT);
546 break;
547 case CLK_SPI1:
548 rk_clrsetreg(&cru->clksel_con[59],
549 CLK_SPI1_SEL_MASK,
550 src_clk << CLK_SPI1_SEL_SHIFT);
551 break;
552 case CLK_SPI2:
553 rk_clrsetreg(&cru->clksel_con[59],
554 CLK_SPI2_SEL_MASK,
555 src_clk << CLK_SPI2_SEL_SHIFT);
556 break;
557 case CLK_SPI3:
558 rk_clrsetreg(&cru->clksel_con[59],
559 CLK_SPI3_SEL_MASK,
560 src_clk << CLK_SPI3_SEL_SHIFT);
561 break;
562 case CLK_SPI4:
563 rk_clrsetreg(&cru->clksel_con[59],
564 CLK_SPI4_SEL_MASK,
565 src_clk << CLK_SPI4_SEL_SHIFT);
566 break;
567 default:
568 return -ENOENT;
569 }
570
571 return rk3588_spi_get_clk(priv, clk_id);
572 }
573
rk3588_pwm_get_clk(struct rk3588_clk_priv * priv,ulong clk_id)574 static ulong rk3588_pwm_get_clk(struct rk3588_clk_priv *priv, ulong clk_id)
575 {
576 struct rk3588_cru *cru = priv->cru;
577 u32 sel, con;
578
579 switch (clk_id) {
580 case CLK_PWM1:
581 con = readl(&cru->clksel_con[59]);
582 sel = (con & CLK_PWM1_SEL_MASK) >> CLK_PWM1_SEL_SHIFT;
583 break;
584 case CLK_PWM2:
585 con = readl(&cru->clksel_con[59]);
586 sel = (con & CLK_PWM2_SEL_MASK) >> CLK_PWM2_SEL_SHIFT;
587 break;
588 case CLK_PWM3:
589 con = readl(&cru->clksel_con[60]);
590 sel = (con & CLK_PWM3_SEL_MASK) >> CLK_PWM3_SEL_SHIFT;
591 break;
592 case CLK_PMU1PWM:
593 con = readl(&cru->pmuclksel_con[2]);
594 sel = (con & CLK_PMU1PWM_SEL_MASK) >> CLK_PMU1PWM_SEL_SHIFT;
595 break;
596 default:
597 return -ENOENT;
598 }
599
600 switch (sel) {
601 case CLK_PWM_SEL_100M:
602 return 100 * MHz;
603 case CLK_PWM_SEL_50M:
604 return 50 * MHz;
605 case CLK_PWM_SEL_24M:
606 return OSC_HZ;
607 default:
608 return -ENOENT;
609 }
610 }
611
rk3588_pwm_set_clk(struct rk3588_clk_priv * priv,ulong clk_id,ulong rate)612 static ulong rk3588_pwm_set_clk(struct rk3588_clk_priv *priv,
613 ulong clk_id, ulong rate)
614 {
615 struct rk3588_cru *cru = priv->cru;
616 int src_clk;
617
618 if (rate >= 99 * MHz)
619 src_clk = CLK_PWM_SEL_100M;
620 else if (rate >= 50 * MHz)
621 src_clk = CLK_PWM_SEL_50M;
622 else
623 src_clk = CLK_PWM_SEL_24M;
624
625 switch (clk_id) {
626 case CLK_PWM1:
627 rk_clrsetreg(&cru->clksel_con[59],
628 CLK_PWM1_SEL_MASK,
629 src_clk << CLK_PWM1_SEL_SHIFT);
630 break;
631 case CLK_PWM2:
632 rk_clrsetreg(&cru->clksel_con[59],
633 CLK_PWM2_SEL_MASK,
634 src_clk << CLK_PWM2_SEL_SHIFT);
635 break;
636 case CLK_PWM3:
637 rk_clrsetreg(&cru->clksel_con[60],
638 CLK_PWM3_SEL_MASK,
639 src_clk << CLK_PWM3_SEL_SHIFT);
640 break;
641 case CLK_PMU1PWM:
642 rk_clrsetreg(&cru->pmuclksel_con[2],
643 CLK_PMU1PWM_SEL_MASK,
644 src_clk << CLK_PMU1PWM_SEL_SHIFT);
645 break;
646 default:
647 return -ENOENT;
648 }
649
650 return rk3588_pwm_get_clk(priv, clk_id);
651 }
652
rk3588_adc_get_clk(struct rk3588_clk_priv * priv,ulong clk_id)653 static ulong rk3588_adc_get_clk(struct rk3588_clk_priv *priv, ulong clk_id)
654 {
655 struct rk3588_cru *cru = priv->cru;
656 u32 div, sel, con, prate;
657
658 switch (clk_id) {
659 case CLK_SARADC:
660 con = readl(&cru->clksel_con[40]);
661 div = (con & CLK_SARADC_DIV_MASK) >> CLK_SARADC_DIV_SHIFT;
662 sel = (con & CLK_SARADC_SEL_MASK) >>
663 CLK_SARADC_SEL_SHIFT;
664 if (sel == CLK_SARADC_SEL_24M)
665 prate = OSC_HZ;
666 else
667 prate = priv->gpll_hz;
668 return DIV_TO_RATE(prate, div);
669 case CLK_TSADC:
670 con = readl(&cru->clksel_con[41]);
671 div = (con & CLK_TSADC_DIV_MASK) >>
672 CLK_TSADC_DIV_SHIFT;
673 sel = (con & CLK_TSADC_SEL_MASK) >>
674 CLK_TSADC_SEL_SHIFT;
675 if (sel == CLK_TSADC_SEL_24M)
676 prate = OSC_HZ;
677 else
678 prate = 100 * MHz;
679 return DIV_TO_RATE(prate, div);
680 default:
681 return -ENOENT;
682 }
683 }
684
rk3588_adc_set_clk(struct rk3588_clk_priv * priv,ulong clk_id,ulong rate)685 static ulong rk3588_adc_set_clk(struct rk3588_clk_priv *priv,
686 ulong clk_id, ulong rate)
687 {
688 struct rk3588_cru *cru = priv->cru;
689 int src_clk_div;
690
691 switch (clk_id) {
692 case CLK_SARADC:
693 if (!(OSC_HZ % rate)) {
694 src_clk_div = DIV_ROUND_UP(OSC_HZ, rate);
695 assert(src_clk_div - 1 <= 255);
696 rk_clrsetreg(&cru->clksel_con[40],
697 CLK_SARADC_SEL_MASK |
698 CLK_SARADC_DIV_MASK,
699 (CLK_SARADC_SEL_24M <<
700 CLK_SARADC_SEL_SHIFT) |
701 (src_clk_div - 1) <<
702 CLK_SARADC_DIV_SHIFT);
703 } else {
704 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
705 assert(src_clk_div - 1 <= 255);
706 rk_clrsetreg(&cru->clksel_con[40],
707 CLK_SARADC_SEL_MASK |
708 CLK_SARADC_DIV_MASK,
709 (CLK_SARADC_SEL_GPLL <<
710 CLK_SARADC_SEL_SHIFT) |
711 (src_clk_div - 1) <<
712 CLK_SARADC_DIV_SHIFT);
713 }
714 break;
715 case CLK_TSADC:
716 if (!(OSC_HZ % rate)) {
717 src_clk_div = DIV_ROUND_UP(OSC_HZ, rate);
718 assert(src_clk_div - 1 <= 255);
719 rk_clrsetreg(&cru->clksel_con[41],
720 CLK_TSADC_SEL_MASK |
721 CLK_TSADC_DIV_MASK,
722 (CLK_TSADC_SEL_24M <<
723 CLK_TSADC_SEL_SHIFT) |
724 (src_clk_div - 1) <<
725 CLK_TSADC_DIV_SHIFT);
726 } else {
727 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
728 assert(src_clk_div - 1 <= 7);
729 rk_clrsetreg(&cru->clksel_con[41],
730 CLK_TSADC_SEL_MASK |
731 CLK_TSADC_DIV_MASK,
732 (CLK_TSADC_SEL_GPLL <<
733 CLK_TSADC_SEL_SHIFT) |
734 (src_clk_div - 1) <<
735 CLK_TSADC_DIV_SHIFT);
736 }
737 break;
738 default:
739 return -ENOENT;
740 }
741 return rk3588_adc_get_clk(priv, clk_id);
742 }
743
rk3588_mmc_get_clk(struct rk3588_clk_priv * priv,ulong clk_id)744 static ulong rk3588_mmc_get_clk(struct rk3588_clk_priv *priv, ulong clk_id)
745 {
746 struct rk3588_cru *cru = priv->cru;
747 u32 sel, con, div, prate;
748
749 switch (clk_id) {
750 case CCLK_SRC_SDIO:
751 con = readl(&cru->clksel_con[172]);
752 div = (con & CCLK_SDIO_SRC_DIV_MASK) >> CCLK_SDIO_SRC_DIV_SHIFT;
753 sel = (con & CCLK_SDIO_SRC_SEL_MASK) >>
754 CCLK_SDIO_SRC_SEL_SHIFT;
755 if (sel == CCLK_SDIO_SRC_SEL_GPLL)
756 prate = priv->gpll_hz;
757 else if (sel == CCLK_SDIO_SRC_SEL_CPLL)
758 prate = priv->cpll_hz;
759 else
760 prate = OSC_HZ;
761 return DIV_TO_RATE(prate, div);
762 case CCLK_EMMC:
763 con = readl(&cru->clksel_con[77]);
764 div = (con & CCLK_EMMC_DIV_MASK) >> CCLK_EMMC_DIV_SHIFT;
765 sel = (con & CCLK_EMMC_SEL_MASK) >>
766 CCLK_EMMC_SEL_SHIFT;
767 if (sel == CCLK_EMMC_SEL_GPLL)
768 prate = priv->gpll_hz;
769 else if (sel == CCLK_EMMC_SEL_CPLL)
770 prate = priv->cpll_hz;
771 else
772 prate = OSC_HZ;
773 return DIV_TO_RATE(prate, div);
774 case BCLK_EMMC:
775 con = readl(&cru->clksel_con[78]);
776 div = (con & BCLK_EMMC_DIV_MASK) >> BCLK_EMMC_DIV_SHIFT;
777 sel = (con & BCLK_EMMC_SEL_MASK) >>
778 BCLK_EMMC_SEL_SHIFT;
779 if (sel == CCLK_EMMC_SEL_CPLL)
780 prate = priv->cpll_hz;
781 else
782 prate = priv->gpll_hz;
783 return DIV_TO_RATE(prate, div);
784 case SCLK_SFC:
785 con = readl(&cru->clksel_con[78]);
786 div = (con & SCLK_SFC_DIV_MASK) >> SCLK_SFC_DIV_SHIFT;
787 sel = (con & SCLK_SFC_SEL_MASK) >>
788 SCLK_SFC_SEL_SHIFT;
789 if (sel == SCLK_SFC_SEL_GPLL)
790 prate = priv->gpll_hz;
791 else if (sel == SCLK_SFC_SEL_CPLL)
792 prate = priv->cpll_hz;
793 else
794 prate = OSC_HZ;
795 return DIV_TO_RATE(prate, div);
796 case DCLK_DECOM:
797 con = readl(&cru->clksel_con[62]);
798 div = (con & DCLK_DECOM_DIV_MASK) >> DCLK_DECOM_DIV_SHIFT;
799 sel = (con & DCLK_DECOM_SEL_MASK) >>
800 DCLK_DECOM_SEL_SHIFT;
801 if (sel == DCLK_DECOM_SEL_SPLL)
802 prate = 702 * MHz;
803 else
804 prate = priv->gpll_hz;
805 return DIV_TO_RATE(prate, div);
806 default:
807 return -ENOENT;
808 }
809 }
810
rk3588_mmc_set_clk(struct rk3588_clk_priv * priv,ulong clk_id,ulong rate)811 static ulong rk3588_mmc_set_clk(struct rk3588_clk_priv *priv,
812 ulong clk_id, ulong rate)
813 {
814 struct rk3588_cru *cru = priv->cru;
815 int src_clk, div;
816
817 switch (clk_id) {
818 case CCLK_SRC_SDIO:
819 case CCLK_EMMC:
820 case SCLK_SFC:
821 if (!(OSC_HZ % rate)) {
822 src_clk = SCLK_SFC_SEL_24M;
823 div = DIV_ROUND_UP(OSC_HZ, rate);
824 } else if (!(priv->cpll_hz % rate)) {
825 src_clk = SCLK_SFC_SEL_CPLL;
826 div = DIV_ROUND_UP(priv->cpll_hz, rate);
827 } else {
828 src_clk = SCLK_SFC_SEL_GPLL;
829 div = DIV_ROUND_UP(priv->gpll_hz, rate);
830 }
831 break;
832 case BCLK_EMMC:
833 if (!(priv->cpll_hz % rate)) {
834 src_clk = CCLK_EMMC_SEL_CPLL;
835 div = DIV_ROUND_UP(priv->cpll_hz, rate);
836 } else {
837 src_clk = CCLK_EMMC_SEL_GPLL;
838 div = DIV_ROUND_UP(priv->gpll_hz, rate);
839 }
840 break;
841 case DCLK_DECOM:
842 if (!(702 * MHz % rate)) {
843 src_clk = DCLK_DECOM_SEL_SPLL;
844 div = DIV_ROUND_UP(702 * MHz, rate);
845 } else {
846 src_clk = DCLK_DECOM_SEL_GPLL;
847 div = DIV_ROUND_UP(priv->gpll_hz, rate);
848 }
849 break;
850 default:
851 return -ENOENT;
852 }
853
854 switch (clk_id) {
855 case CCLK_SRC_SDIO:
856 rk_clrsetreg(&cru->clksel_con[172],
857 CCLK_SDIO_SRC_SEL_MASK |
858 CCLK_SDIO_SRC_DIV_MASK,
859 (src_clk << CCLK_SDIO_SRC_SEL_SHIFT) |
860 (div - 1) << CCLK_SDIO_SRC_DIV_SHIFT);
861 break;
862 case CCLK_EMMC:
863 rk_clrsetreg(&cru->clksel_con[77],
864 CCLK_EMMC_SEL_MASK |
865 CCLK_EMMC_DIV_MASK,
866 (src_clk << CCLK_EMMC_SEL_SHIFT) |
867 (div - 1) << CCLK_EMMC_DIV_SHIFT);
868 break;
869 case BCLK_EMMC:
870 rk_clrsetreg(&cru->clksel_con[78],
871 BCLK_EMMC_DIV_MASK |
872 BCLK_EMMC_SEL_MASK,
873 (src_clk << BCLK_EMMC_SEL_SHIFT) |
874 (div - 1) << BCLK_EMMC_DIV_SHIFT);
875 break;
876 case SCLK_SFC:
877 rk_clrsetreg(&cru->clksel_con[78],
878 SCLK_SFC_DIV_MASK |
879 SCLK_SFC_SEL_MASK,
880 (src_clk << SCLK_SFC_SEL_SHIFT) |
881 (div - 1) << SCLK_SFC_DIV_SHIFT);
882 break;
883 case DCLK_DECOM:
884 rk_clrsetreg(&cru->clksel_con[62],
885 DCLK_DECOM_DIV_MASK |
886 DCLK_DECOM_SEL_MASK,
887 (src_clk << DCLK_DECOM_SEL_SHIFT) |
888 (div - 1) << DCLK_DECOM_DIV_SHIFT);
889 break;
890 default:
891 return -ENOENT;
892 }
893
894 return rk3588_mmc_get_clk(priv, clk_id);
895 }
896
897 #ifndef CONFIG_SPL_BUILD
rk3588_aux16m_get_clk(struct rk3588_clk_priv * priv,ulong clk_id)898 static ulong rk3588_aux16m_get_clk(struct rk3588_clk_priv *priv, ulong clk_id)
899 {
900 struct rk3588_cru *cru = priv->cru;
901 u32 div, con, parent;
902
903 parent = priv->gpll_hz;
904 con = readl(&cru->clksel_con[117]);
905
906 switch (clk_id) {
907 case CLK_AUX16M_0:
908 div = (con & CLK_AUX16MHZ_0_DIV_MASK) >> CLK_AUX16MHZ_0_DIV_SHIFT;
909 return DIV_TO_RATE(parent, div);
910 case CLK_AUX16M_1:
911 div = (con & CLK_AUX16MHZ_1_DIV_MASK) >> CLK_AUX16MHZ_1_DIV_SHIFT;
912 return DIV_TO_RATE(parent, div);
913 default:
914 return -ENOENT;
915 }
916 }
917
rk3588_aux16m_set_clk(struct rk3588_clk_priv * priv,ulong clk_id,ulong rate)918 static ulong rk3588_aux16m_set_clk(struct rk3588_clk_priv *priv,
919 ulong clk_id, ulong rate)
920 {
921 struct rk3588_cru *cru = priv->cru;
922 u32 div;
923
924 if (!priv->gpll_hz) {
925 printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
926 return -ENOENT;
927 }
928
929 div = DIV_ROUND_UP(priv->gpll_hz, rate);
930
931 switch (clk_id) {
932 case CLK_AUX16M_0:
933 rk_clrsetreg(&cru->clksel_con[117], CLK_AUX16MHZ_0_DIV_MASK,
934 (div - 1) << CLK_AUX16MHZ_0_DIV_SHIFT);
935 break;
936 case CLK_AUX16M_1:
937 rk_clrsetreg(&cru->clksel_con[117], CLK_AUX16MHZ_1_DIV_MASK,
938 (div - 1) << CLK_AUX16MHZ_1_DIV_SHIFT);
939 break;
940 default:
941 return -ENOENT;
942 }
943
944 return rk3588_aux16m_get_clk(priv, clk_id);
945 }
946
rk3588_aclk_vop_get_clk(struct rk3588_clk_priv * priv,ulong clk_id)947 static ulong rk3588_aclk_vop_get_clk(struct rk3588_clk_priv *priv, ulong clk_id)
948 {
949 struct rk3588_cru *cru = priv->cru;
950 u32 div, sel, con, parent;
951
952 switch (clk_id) {
953 case ACLK_VOP_ROOT:
954 case ACLK_VOP:
955 con = readl(&cru->clksel_con[110]);
956 div = (con & ACLK_VOP_ROOT_DIV_MASK) >> ACLK_VOP_ROOT_DIV_SHIFT;
957 sel = (con & ACLK_VOP_ROOT_SEL_MASK) >> ACLK_VOP_ROOT_SEL_SHIFT;
958 if (sel == ACLK_VOP_ROOT_SEL_GPLL)
959 parent = priv->gpll_hz;
960 else if (sel == ACLK_VOP_ROOT_SEL_CPLL)
961 parent = priv->cpll_hz;
962 else if (sel == ACLK_VOP_ROOT_SEL_AUPLL)
963 parent = priv->aupll_hz;
964 else if (sel == ACLK_VOP_ROOT_SEL_NPLL)
965 parent = priv->npll_hz;
966 else
967 parent = 702 * MHz;
968 return DIV_TO_RATE(parent, div);
969 case ACLK_VOP_LOW_ROOT:
970 con = readl(&cru->clksel_con[110]);
971 sel = (con & ACLK_VOP_LOW_ROOT_SEL_MASK) >>
972 ACLK_VOP_LOW_ROOT_SEL_SHIFT;
973 if (sel == ACLK_VOP_LOW_ROOT_SEL_400M)
974 return 396 * MHz;
975 else if (sel == ACLK_VOP_LOW_ROOT_SEL_200M)
976 return 200 * MHz;
977 else if (sel == ACLK_VOP_LOW_ROOT_SEL_100M)
978 return 100 * MHz;
979 else
980 return OSC_HZ;
981 case HCLK_VOP_ROOT:
982 con = readl(&cru->clksel_con[110]);
983 sel = (con & HCLK_VOP_ROOT_SEL_MASK) >> HCLK_VOP_ROOT_SEL_SHIFT;
984 if (sel == HCLK_VOP_ROOT_SEL_200M)
985 return 200 * MHz;
986 else if (sel == HCLK_VOP_ROOT_SEL_100M)
987 return 100 * MHz;
988 else if (sel == HCLK_VOP_ROOT_SEL_50M)
989 return 50 * MHz;
990 else
991 return OSC_HZ;
992 default:
993 return -ENOENT;
994 }
995 }
996
rk3588_aclk_vop_set_clk(struct rk3588_clk_priv * priv,ulong clk_id,ulong rate)997 static ulong rk3588_aclk_vop_set_clk(struct rk3588_clk_priv *priv,
998 ulong clk_id, ulong rate)
999 {
1000 struct rk3588_cru *cru = priv->cru;
1001 int src_clk, div;
1002
1003 switch (clk_id) {
1004 case ACLK_VOP_ROOT:
1005 case ACLK_VOP:
1006 if (rate >= 850 * MHz) {
1007 src_clk = ACLK_VOP_ROOT_SEL_NPLL;
1008 div = 1;
1009 } else if (rate >= 750 * MHz) {
1010 src_clk = ACLK_VOP_ROOT_SEL_CPLL;
1011 div = 2;
1012 } else if (rate >= 700 * MHz) {
1013 src_clk = ACLK_VOP_ROOT_SEL_SPLL;
1014 div = 1;
1015 } else if (!(priv->cpll_hz % rate)) {
1016 src_clk = ACLK_VOP_ROOT_SEL_CPLL;
1017 div = DIV_ROUND_UP(priv->cpll_hz, rate);
1018 } else {
1019 src_clk = ACLK_VOP_ROOT_SEL_GPLL;
1020 div = DIV_ROUND_UP(priv->gpll_hz, rate);
1021 }
1022 rk_clrsetreg(&cru->clksel_con[110],
1023 ACLK_VOP_ROOT_DIV_MASK |
1024 ACLK_VOP_ROOT_SEL_MASK,
1025 (src_clk << ACLK_VOP_ROOT_SEL_SHIFT) |
1026 (div - 1) << ACLK_VOP_ROOT_DIV_SHIFT);
1027 break;
1028 case ACLK_VOP_LOW_ROOT:
1029 if (rate == 400 * MHz || rate == 396 * MHz)
1030 src_clk = ACLK_VOP_LOW_ROOT_SEL_400M;
1031 else if (rate == 200 * MHz)
1032 src_clk = ACLK_VOP_LOW_ROOT_SEL_200M;
1033 else if (rate == 100 * MHz)
1034 src_clk = ACLK_VOP_LOW_ROOT_SEL_100M;
1035 else
1036 src_clk = ACLK_VOP_LOW_ROOT_SEL_24M;
1037 rk_clrsetreg(&cru->clksel_con[110],
1038 ACLK_VOP_LOW_ROOT_SEL_MASK,
1039 src_clk << ACLK_VOP_LOW_ROOT_SEL_SHIFT);
1040 break;
1041 case HCLK_VOP_ROOT:
1042 if (rate == 200 * MHz)
1043 src_clk = HCLK_VOP_ROOT_SEL_200M;
1044 else if (rate == 100 * MHz)
1045 src_clk = HCLK_VOP_ROOT_SEL_100M;
1046 else if (rate == 50 * MHz)
1047 src_clk = HCLK_VOP_ROOT_SEL_50M;
1048 else
1049 src_clk = HCLK_VOP_ROOT_SEL_24M;
1050 rk_clrsetreg(&cru->clksel_con[110],
1051 HCLK_VOP_ROOT_SEL_MASK,
1052 src_clk << HCLK_VOP_ROOT_SEL_SHIFT);
1053 break;
1054 default:
1055 return -ENOENT;
1056 }
1057
1058 return rk3588_aclk_vop_get_clk(priv, clk_id);
1059 }
1060
rk3588_dclk_vop_get_clk(struct rk3588_clk_priv * priv,ulong clk_id)1061 static ulong rk3588_dclk_vop_get_clk(struct rk3588_clk_priv *priv, ulong clk_id)
1062 {
1063 struct rk3588_cru *cru = priv->cru;
1064 u32 div, sel, con, parent;
1065
1066 switch (clk_id) {
1067 case DCLK_VOP0:
1068 case DCLK_VOP0_SRC:
1069 con = readl(&cru->clksel_con[111]);
1070 div = (con & DCLK0_VOP_SRC_DIV_MASK) >> DCLK0_VOP_SRC_DIV_SHIFT;
1071 sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT;
1072 break;
1073 case DCLK_VOP1:
1074 case DCLK_VOP1_SRC:
1075 con = readl(&cru->clksel_con[111]);
1076 div = (con & DCLK1_VOP_SRC_DIV_MASK) >> DCLK1_VOP_SRC_DIV_SHIFT;
1077 sel = (con & DCLK1_VOP_SRC_SEL_MASK) >> DCLK1_VOP_SRC_SEL_SHIFT;
1078 break;
1079 case DCLK_VOP2:
1080 case DCLK_VOP2_SRC:
1081 con = readl(&cru->clksel_con[112]);
1082 div = (con & DCLK2_VOP_SRC_DIV_MASK) >> DCLK2_VOP_SRC_DIV_SHIFT;
1083 sel = (con & DCLK2_VOP_SRC_SEL_MASK) >> DCLK2_VOP_SRC_SEL_SHIFT;
1084 break;
1085 case DCLK_VOP3:
1086 con = readl(&cru->clksel_con[113]);
1087 div = (con & DCLK3_VOP_SRC_DIV_MASK) >> DCLK3_VOP_SRC_DIV_SHIFT;
1088 sel = (con & DCLK3_VOP_SRC_SEL_MASK) >> DCLK3_VOP_SRC_SEL_SHIFT;
1089 break;
1090 default:
1091 return -ENOENT;
1092 }
1093
1094 if (sel == DCLK_VOP_SRC_SEL_AUPLL)
1095 parent = priv->aupll_hz;
1096 else if (sel == DCLK_VOP_SRC_SEL_V0PLL)
1097 parent = rockchip_pll_get_rate(&rk3588_pll_clks[V0PLL],
1098 priv->cru, V0PLL);
1099 else if (sel == DCLK_VOP_SRC_SEL_GPLL)
1100 parent = priv->gpll_hz;
1101 else
1102 parent = priv->cpll_hz;
1103
1104 return DIV_TO_RATE(parent, div);
1105 }
1106
1107 #define RK3588_VOP_PLL_LIMIT_FREQ 594000000
1108
rk3588_dclk_vop_set_clk(struct rk3588_clk_priv * priv,ulong clk_id,ulong rate)1109 static ulong rk3588_dclk_vop_set_clk(struct rk3588_clk_priv *priv,
1110 ulong clk_id, ulong rate)
1111 {
1112 struct rk3588_cru *cru = priv->cru;
1113 ulong pll_rate, now, best_rate = 0;
1114 u32 i, conid, con, sel, div, best_div = 0, best_sel = 0;
1115 u32 mask, div_shift, sel_shift;
1116
1117 switch (clk_id) {
1118 case DCLK_VOP0:
1119 case DCLK_VOP0_SRC:
1120 conid = 111;
1121 con = readl(&cru->clksel_con[111]);
1122 sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT;
1123 mask = DCLK0_VOP_SRC_SEL_MASK | DCLK0_VOP_SRC_DIV_MASK;
1124 div_shift = DCLK0_VOP_SRC_DIV_SHIFT;
1125 sel_shift = DCLK0_VOP_SRC_SEL_SHIFT;
1126 break;
1127 case DCLK_VOP1:
1128 case DCLK_VOP1_SRC:
1129 conid = 111;
1130 con = readl(&cru->clksel_con[111]);
1131 sel = (con & DCLK1_VOP_SRC_SEL_MASK) >> DCLK1_VOP_SRC_SEL_SHIFT;
1132 mask = DCLK1_VOP_SRC_SEL_MASK | DCLK1_VOP_SRC_DIV_MASK;
1133 div_shift = DCLK1_VOP_SRC_DIV_SHIFT;
1134 sel_shift = DCLK1_VOP_SRC_SEL_SHIFT;
1135 break;
1136 case DCLK_VOP2:
1137 case DCLK_VOP2_SRC:
1138 conid = 112;
1139 con = readl(&cru->clksel_con[112]);
1140 sel = (con & DCLK2_VOP_SRC_SEL_MASK) >> DCLK2_VOP_SRC_SEL_SHIFT;
1141 mask = DCLK2_VOP_SRC_SEL_MASK | DCLK2_VOP_SRC_DIV_MASK;
1142 div_shift = DCLK2_VOP_SRC_DIV_SHIFT;
1143 sel_shift = DCLK2_VOP_SRC_SEL_SHIFT;
1144 break;
1145 case DCLK_VOP3:
1146 conid = 113;
1147 con = readl(&cru->clksel_con[113]);
1148 sel = (con & DCLK3_VOP_SRC_SEL_MASK) >> DCLK3_VOP_SRC_SEL_SHIFT;
1149 mask = DCLK3_VOP_SRC_SEL_MASK | DCLK3_VOP_SRC_DIV_MASK;
1150 div_shift = DCLK3_VOP_SRC_DIV_SHIFT;
1151 sel_shift = DCLK3_VOP_SRC_SEL_SHIFT;
1152 break;
1153 default:
1154 return -ENOENT;
1155 }
1156
1157 if (sel == DCLK_VOP_SRC_SEL_V0PLL) {
1158 pll_rate = rockchip_pll_get_rate(&rk3588_pll_clks[V0PLL],
1159 priv->cru, V0PLL);
1160 if (pll_rate >= RK3588_VOP_PLL_LIMIT_FREQ && pll_rate % rate == 0) {
1161 div = DIV_ROUND_UP(pll_rate, rate);
1162 rk_clrsetreg(&cru->clksel_con[conid],
1163 mask,
1164 DCLK_VOP_SRC_SEL_V0PLL << sel_shift |
1165 ((div - 1) << div_shift));
1166 } else {
1167 div = DIV_ROUND_UP(RK3588_VOP_PLL_LIMIT_FREQ, rate);
1168 if (div % 2)
1169 div = div + 1;
1170 rk_clrsetreg(&cru->clksel_con[conid],
1171 mask,
1172 DCLK_VOP_SRC_SEL_V0PLL << sel_shift |
1173 ((div - 1) << div_shift));
1174 rockchip_pll_set_rate(&rk3588_pll_clks[V0PLL],
1175 priv->cru, V0PLL, div * rate);
1176 }
1177 } else {
1178 for (i = 0; i <= DCLK_VOP_SRC_SEL_AUPLL; i++) {
1179 switch (i) {
1180 case DCLK_VOP_SRC_SEL_GPLL:
1181 pll_rate = priv->gpll_hz;
1182 break;
1183 case DCLK_VOP_SRC_SEL_CPLL:
1184 pll_rate = priv->cpll_hz;
1185 break;
1186 case DCLK_VOP_SRC_SEL_AUPLL:
1187 pll_rate = priv->aupll_hz;
1188 break;
1189 case DCLK_VOP_SRC_SEL_V0PLL:
1190 pll_rate = 0;
1191 break;
1192 default:
1193 printf("do not support this vop pll sel\n");
1194 return -EINVAL;
1195 }
1196
1197 div = DIV_ROUND_UP(pll_rate, rate);
1198 if (div > 255)
1199 continue;
1200 now = pll_rate / div;
1201 if (abs(rate - now) < abs(rate - best_rate)) {
1202 best_rate = now;
1203 best_div = div;
1204 best_sel = i;
1205 }
1206 debug("p_rate=%lu, best_rate=%lu, div=%u, sel=%u\n",
1207 pll_rate, best_rate, best_div, best_sel);
1208 }
1209
1210 if (best_rate) {
1211 rk_clrsetreg(&cru->clksel_con[conid],
1212 mask,
1213 best_sel << sel_shift |
1214 (best_div - 1) << div_shift);
1215 } else {
1216 printf("do not support this vop freq %lu\n", rate);
1217 return -EINVAL;
1218 }
1219 }
1220 return rk3588_dclk_vop_get_clk(priv, clk_id);
1221 }
1222
rk3588_clk_csihost_get_clk(struct rk3588_clk_priv * priv,ulong clk_id)1223 static ulong rk3588_clk_csihost_get_clk(struct rk3588_clk_priv *priv, ulong clk_id)
1224 {
1225 struct rk3588_cru *cru = priv->cru;
1226 u32 div, sel, con, parent;
1227
1228 switch (clk_id) {
1229 case CLK_DSIHOST0:
1230 con = readl(&cru->clksel_con[114]);
1231 break;
1232 case CLK_DSIHOST1:
1233 con = readl(&cru->clksel_con[115]);
1234 break;
1235 default:
1236 return -ENOENT;
1237 }
1238
1239 div = (con & CLK_DSIHOST_DIV_MASK) >> CLK_DSIHOST_DIV_SHIFT;
1240 sel = (con & CLK_DSIHOST_SEL_MASK) >> CLK_DSIHOST_SEL_SHIFT;
1241
1242 if (sel == CLK_DSIHOST_SEL_GPLL)
1243 parent = priv->gpll_hz;
1244 else if (sel == CLK_DSIHOST_SEL_CPLL)
1245 parent = priv->cpll_hz;
1246 else if (sel == CLK_DSIHOST_SEL_V0PLL)
1247 parent = priv->v0pll_hz;
1248 else
1249 parent = priv->spll_hz;
1250
1251 return DIV_TO_RATE(parent, div);
1252 }
1253
rk3588_gmac_get_clk(struct rk3588_clk_priv * priv,ulong clk_id)1254 static ulong rk3588_gmac_get_clk(struct rk3588_clk_priv *priv, ulong clk_id)
1255 {
1256 struct rk3588_cru *cru = priv->cru;
1257 u32 con, div;
1258
1259 switch (clk_id) {
1260 case CLK_GMAC0_PTP_REF:
1261 con = readl(&cru->clksel_con[81]);
1262 div = (con & CLK_GMAC0_PTP_DIV_MASK) >> CLK_GMAC0_PTP_DIV_SHIFT;
1263 return DIV_TO_RATE(priv->cpll_hz, div);
1264 case CLK_GMAC1_PTP_REF:
1265 con = readl(&cru->clksel_con[81]);
1266 div = (con & CLK_GMAC1_PTP_DIV_MASK) >> CLK_GMAC1_PTP_DIV_SHIFT;
1267 return DIV_TO_RATE(priv->cpll_hz, div);
1268 case CLK_GMAC_125M:
1269 con = readl(&cru->clksel_con[83]);
1270 div = (con & CLK_GMAC_125M_DIV_MASK) >> CLK_GMAC_125M_DIV_SHIFT;
1271 return DIV_TO_RATE(priv->cpll_hz, div);
1272 case CLK_GMAC_50M:
1273 con = readl(&cru->clksel_con[84]);
1274 div = (con & CLK_GMAC_50M_DIV_MASK) >> CLK_GMAC_50M_DIV_SHIFT;
1275 return DIV_TO_RATE(priv->cpll_hz, div);
1276 default:
1277 return -ENOENT;
1278 }
1279 }
1280
rk3588_gmac_set_clk(struct rk3588_clk_priv * priv,ulong clk_id,ulong rate)1281 static ulong rk3588_gmac_set_clk(struct rk3588_clk_priv *priv,
1282 ulong clk_id, ulong rate)
1283 {
1284 struct rk3588_cru *cru = priv->cru;
1285 int div;
1286
1287 div = DIV_ROUND_UP(priv->cpll_hz, rate);
1288
1289 switch (clk_id) {
1290 case CLK_GMAC0_PTP_REF:
1291 rk_clrsetreg(&cru->clksel_con[81],
1292 CLK_GMAC0_PTP_DIV_MASK | CLK_GMAC0_PTP_SEL_MASK,
1293 CLK_GMAC0_PTP_SEL_CPLL << CLK_GMAC0_PTP_SEL_SHIFT |
1294 (div - 1) << CLK_GMAC0_PTP_DIV_SHIFT);
1295 break;
1296 case CLK_GMAC1_PTP_REF:
1297 rk_clrsetreg(&cru->clksel_con[81],
1298 CLK_GMAC1_PTP_DIV_MASK | CLK_GMAC1_PTP_SEL_MASK,
1299 CLK_GMAC1_PTP_SEL_CPLL << CLK_GMAC1_PTP_SEL_SHIFT |
1300 (div - 1) << CLK_GMAC1_PTP_DIV_SHIFT);
1301 break;
1302
1303 case CLK_GMAC_125M:
1304 rk_clrsetreg(&cru->clksel_con[83],
1305 CLK_GMAC_125M_DIV_MASK | CLK_GMAC_125M_SEL_MASK,
1306 CLK_GMAC_125M_SEL_CPLL << CLK_GMAC_125M_SEL_SHIFT |
1307 (div - 1) << CLK_GMAC_125M_DIV_SHIFT);
1308 break;
1309 case CLK_GMAC_50M:
1310 rk_clrsetreg(&cru->clksel_con[84],
1311 CLK_GMAC_50M_DIV_MASK | CLK_GMAC_50M_SEL_MASK,
1312 CLK_GMAC_50M_SEL_CPLL << CLK_GMAC_50M_SEL_SHIFT |
1313 (div - 1) << CLK_GMAC_50M_DIV_SHIFT);
1314 break;
1315 default:
1316 return -ENOENT;
1317 }
1318
1319 return rk3588_gmac_get_clk(priv, clk_id);
1320 }
1321
rk3588_uart_get_rate(struct rk3588_clk_priv * priv,ulong clk_id)1322 static ulong rk3588_uart_get_rate(struct rk3588_clk_priv *priv, ulong clk_id)
1323 {
1324 struct rk3588_cru *cru = priv->cru;
1325 u32 reg, con, fracdiv, div, src, p_src, p_rate;
1326 unsigned long m, n;
1327
1328 switch (clk_id) {
1329 case SCLK_UART1:
1330 reg = 41;
1331 break;
1332 case SCLK_UART2:
1333 reg = 43;
1334 break;
1335 case SCLK_UART3:
1336 reg = 45;
1337 break;
1338 case SCLK_UART4:
1339 reg = 47;
1340 break;
1341 case SCLK_UART5:
1342 reg = 49;
1343 break;
1344 case SCLK_UART6:
1345 reg = 51;
1346 break;
1347 case SCLK_UART7:
1348 reg = 53;
1349 break;
1350 case SCLK_UART8:
1351 reg = 55;
1352 break;
1353 case SCLK_UART9:
1354 reg = 57;
1355 break;
1356 default:
1357 return -ENOENT;
1358 }
1359 con = readl(&cru->clksel_con[reg + 2]);
1360 src = (con & CLK_UART_SEL_MASK) >> CLK_UART_SEL_SHIFT;
1361 con = readl(&cru->clksel_con[reg]);
1362 div = (con & CLK_UART_SRC_DIV_MASK) >> CLK_UART_SRC_DIV_SHIFT;
1363 p_src = (con & CLK_UART_SRC_SEL_MASK) >> CLK_UART_SRC_SEL_SHIFT;
1364 if (p_src == CLK_UART_SRC_SEL_GPLL)
1365 p_rate = priv->gpll_hz;
1366 else
1367 p_rate = priv->cpll_hz;
1368
1369 if (src == CLK_UART_SEL_SRC) {
1370 return DIV_TO_RATE(p_rate, div);
1371 } else if (src == CLK_UART_SEL_FRAC) {
1372 fracdiv = readl(&cru->clksel_con[reg + 1]);
1373 n = fracdiv & CLK_UART_FRAC_NUMERATOR_MASK;
1374 n >>= CLK_UART_FRAC_NUMERATOR_SHIFT;
1375 m = fracdiv & CLK_UART_FRAC_DENOMINATOR_MASK;
1376 m >>= CLK_UART_FRAC_DENOMINATOR_SHIFT;
1377 return DIV_TO_RATE(p_rate, div) * n / m;
1378 } else {
1379 return OSC_HZ;
1380 }
1381 }
1382
rk3588_uart_set_rate(struct rk3588_clk_priv * priv,ulong clk_id,ulong rate)1383 static ulong rk3588_uart_set_rate(struct rk3588_clk_priv *priv,
1384 ulong clk_id, ulong rate)
1385 {
1386 struct rk3588_cru *cru = priv->cru;
1387 u32 reg, clk_src, uart_src, div;
1388 unsigned long m = 0, n = 0, val;
1389
1390 if (priv->gpll_hz % rate == 0) {
1391 clk_src = CLK_UART_SRC_SEL_GPLL;
1392 uart_src = CLK_UART_SEL_SRC;
1393 div = DIV_ROUND_UP(priv->gpll_hz, rate);
1394 } else if (priv->cpll_hz % rate == 0) {
1395 clk_src = CLK_UART_SRC_SEL_CPLL;
1396 uart_src = CLK_UART_SEL_SRC;
1397 div = DIV_ROUND_UP(priv->gpll_hz, rate);
1398 } else if (rate == OSC_HZ) {
1399 clk_src = CLK_UART_SRC_SEL_GPLL;
1400 uart_src = CLK_UART_SEL_XIN24M;
1401 div = 2;
1402 } else {
1403 clk_src = CLK_UART_SRC_SEL_GPLL;
1404 uart_src = CLK_UART_SEL_FRAC;
1405 div = 2;
1406 rational_best_approximation(rate, priv->gpll_hz / div,
1407 GENMASK(16 - 1, 0),
1408 GENMASK(16 - 1, 0),
1409 &m, &n);
1410 }
1411
1412 switch (clk_id) {
1413 case SCLK_UART1:
1414 reg = 41;
1415 break;
1416 case SCLK_UART2:
1417 reg = 43;
1418 break;
1419 case SCLK_UART3:
1420 reg = 45;
1421 break;
1422 case SCLK_UART4:
1423 reg = 47;
1424 break;
1425 case SCLK_UART5:
1426 reg = 49;
1427 break;
1428 case SCLK_UART6:
1429 reg = 51;
1430 break;
1431 case SCLK_UART7:
1432 reg = 53;
1433 break;
1434 case SCLK_UART8:
1435 reg = 55;
1436 break;
1437 case SCLK_UART9:
1438 reg = 57;
1439 break;
1440 default:
1441 return -ENOENT;
1442 }
1443 rk_clrsetreg(&cru->clksel_con[reg],
1444 CLK_UART_SRC_SEL_MASK |
1445 CLK_UART_SRC_DIV_MASK,
1446 (clk_src << CLK_UART_SRC_SEL_SHIFT) |
1447 ((div - 1) << CLK_UART_SRC_DIV_SHIFT));
1448 rk_clrsetreg(&cru->clksel_con[reg + 2],
1449 CLK_UART_SEL_MASK,
1450 (uart_src << CLK_UART_SEL_SHIFT));
1451 if (m && n) {
1452 val = m << CLK_UART_FRAC_NUMERATOR_SHIFT | n;
1453 writel(val, &cru->clksel_con[reg + 1]);
1454 }
1455
1456 return rk3588_uart_get_rate(priv, clk_id);
1457 }
1458
rk3588_pciephy_get_rate(struct rk3588_clk_priv * priv,ulong clk_id)1459 static ulong rk3588_pciephy_get_rate(struct rk3588_clk_priv *priv, ulong clk_id)
1460 {
1461 struct rk3588_cru *cru = priv->cru;
1462 u32 con, div, src;
1463
1464 switch (clk_id) {
1465 case CLK_REF_PIPE_PHY0:
1466 con = readl(&cru->clksel_con[177]);
1467 src = (con & CLK_PCIE_PHY0_REF_SEL_MASK) >> CLK_PCIE_PHY0_REF_SEL_SHIFT;
1468 con = readl(&cru->clksel_con[176]);
1469 div = (con & CLK_PCIE_PHY0_PLL_DIV_MASK) >> CLK_PCIE_PHY0_PLL_DIV_SHIFT;
1470 break;
1471 case CLK_REF_PIPE_PHY1:
1472 con = readl(&cru->clksel_con[177]);
1473 src = (con & CLK_PCIE_PHY1_REF_SEL_MASK) >> CLK_PCIE_PHY1_REF_SEL_SHIFT;
1474 con = readl(&cru->clksel_con[176]);
1475 div = (con & CLK_PCIE_PHY1_PLL_DIV_MASK) >> CLK_PCIE_PHY1_PLL_DIV_SHIFT;
1476 break;
1477 case CLK_REF_PIPE_PHY2:
1478 con = readl(&cru->clksel_con[177]);
1479 src = (con & CLK_PCIE_PHY2_REF_SEL_MASK) >> CLK_PCIE_PHY2_REF_SEL_SHIFT;
1480 div = (con & CLK_PCIE_PHY2_PLL_DIV_MASK) >> CLK_PCIE_PHY2_PLL_DIV_SHIFT;
1481 break;
1482 default:
1483 return -ENOENT;
1484 }
1485
1486 if (src == CLK_PCIE_PHY_REF_SEL_PPLL) {
1487 return DIV_TO_RATE(priv->ppll_hz, div);
1488 } else {
1489 return OSC_HZ;
1490 }
1491 }
1492
rk3588_pciephy_set_rate(struct rk3588_clk_priv * priv,ulong clk_id,ulong rate)1493 static ulong rk3588_pciephy_set_rate(struct rk3588_clk_priv *priv,
1494 ulong clk_id, ulong rate)
1495 {
1496 struct rk3588_cru *cru = priv->cru;
1497 u32 clk_src, div;
1498
1499 if (rate == OSC_HZ) {
1500 clk_src = CLK_PCIE_PHY_REF_SEL_24M;
1501 div = 1;
1502 } else {
1503 clk_src = CLK_PCIE_PHY_REF_SEL_PPLL;
1504 div = DIV_ROUND_UP(priv->ppll_hz, rate);
1505 }
1506
1507 switch (clk_id) {
1508 case CLK_REF_PIPE_PHY0:
1509 rk_clrsetreg(&cru->clksel_con[177],
1510 CLK_PCIE_PHY0_REF_SEL_MASK,
1511 (clk_src << CLK_PCIE_PHY0_REF_SEL_SHIFT));
1512 rk_clrsetreg(&cru->clksel_con[176],
1513 CLK_PCIE_PHY0_PLL_DIV_MASK,
1514 ((div - 1) << CLK_PCIE_PHY0_PLL_DIV_SHIFT));
1515 break;
1516 case CLK_REF_PIPE_PHY1:
1517 rk_clrsetreg(&cru->clksel_con[177],
1518 CLK_PCIE_PHY1_REF_SEL_MASK,
1519 (clk_src << CLK_PCIE_PHY1_REF_SEL_SHIFT));
1520 rk_clrsetreg(&cru->clksel_con[176],
1521 CLK_PCIE_PHY1_PLL_DIV_MASK,
1522 ((div - 1) << CLK_PCIE_PHY1_PLL_DIV_SHIFT));
1523 break;
1524 case CLK_REF_PIPE_PHY2:
1525 rk_clrsetreg(&cru->clksel_con[177],
1526 CLK_PCIE_PHY2_REF_SEL_MASK |
1527 CLK_PCIE_PHY2_PLL_DIV_MASK,
1528 (clk_src << CLK_PCIE_PHY2_REF_SEL_SHIFT) |
1529 ((div - 1) << CLK_PCIE_PHY2_PLL_DIV_SHIFT));
1530 break;
1531 default:
1532 return -ENOENT;
1533 }
1534
1535 return rk3588_pciephy_get_rate(priv, clk_id);
1536 }
1537 #endif
1538
rk3588_clk_get_rate(struct clk * clk)1539 static ulong rk3588_clk_get_rate(struct clk *clk)
1540 {
1541 struct rk3588_clk_priv *priv = dev_get_priv(clk->dev);
1542 ulong rate = 0;
1543
1544 if (!priv->gpll_hz) {
1545 printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
1546 return -ENOENT;
1547 }
1548
1549 if (!priv->ppll_hz) {
1550 priv->ppll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[PPLL],
1551 priv->cru, PPLL);
1552 }
1553
1554 switch (clk->id) {
1555 case PLL_LPLL:
1556 rate = rockchip_pll_get_rate(&rk3588_pll_clks[LPLL], priv->cru,
1557 LPLL);
1558 break;
1559 case PLL_B0PLL:
1560 rate = rockchip_pll_get_rate(&rk3588_pll_clks[B0PLL], priv->cru,
1561 B0PLL);
1562 break;
1563 case PLL_B1PLL:
1564 rate = rockchip_pll_get_rate(&rk3588_pll_clks[B1PLL], priv->cru,
1565 B1PLL);
1566 break;
1567 case PLL_GPLL:
1568 rate = rockchip_pll_get_rate(&rk3588_pll_clks[GPLL], priv->cru,
1569 GPLL);
1570 break;
1571 case PLL_CPLL:
1572 rate = rockchip_pll_get_rate(&rk3588_pll_clks[CPLL], priv->cru,
1573 CPLL);
1574 break;
1575 case PLL_NPLL:
1576 rate = rockchip_pll_get_rate(&rk3588_pll_clks[NPLL], priv->cru,
1577 NPLL);
1578 break;
1579 case PLL_V0PLL:
1580 rate = rockchip_pll_get_rate(&rk3588_pll_clks[V0PLL], priv->cru,
1581 V0PLL);
1582 break;
1583 case PLL_AUPLL:
1584 rate = rockchip_pll_get_rate(&rk3588_pll_clks[AUPLL], priv->cru,
1585 AUPLL);
1586 break;
1587 case PLL_PPLL:
1588 rate = rockchip_pll_get_rate(&rk3588_pll_clks[PPLL], priv->cru,
1589 PPLL);
1590 break;
1591 case ACLK_CENTER_ROOT:
1592 case PCLK_CENTER_ROOT:
1593 case HCLK_CENTER_ROOT:
1594 case ACLK_CENTER_LOW_ROOT:
1595 rate = rk3588_center_get_clk(priv, clk->id);
1596 break;
1597 case ACLK_TOP_ROOT:
1598 case PCLK_TOP_ROOT:
1599 case ACLK_LOW_TOP_ROOT:
1600 rate = rk3588_top_get_clk(priv, clk->id);
1601 break;
1602 case CLK_I2C0:
1603 case CLK_I2C1:
1604 case CLK_I2C2:
1605 case CLK_I2C3:
1606 case CLK_I2C4:
1607 case CLK_I2C5:
1608 case CLK_I2C6:
1609 case CLK_I2C7:
1610 case CLK_I2C8:
1611 rate = rk3588_i2c_get_clk(priv, clk->id);
1612 break;
1613 case CLK_SPI0:
1614 case CLK_SPI1:
1615 case CLK_SPI2:
1616 case CLK_SPI3:
1617 case CLK_SPI4:
1618 rate = rk3588_spi_get_clk(priv, clk->id);
1619 break;
1620 case CLK_PWM1:
1621 case CLK_PWM2:
1622 case CLK_PWM3:
1623 case CLK_PMU1PWM:
1624 rate = rk3588_pwm_get_clk(priv, clk->id);
1625 break;
1626 case CLK_SARADC:
1627 case CLK_TSADC:
1628 rate = rk3588_adc_get_clk(priv, clk->id);
1629 break;
1630 case CCLK_SRC_SDIO:
1631 case CCLK_EMMC:
1632 case BCLK_EMMC:
1633 case SCLK_SFC:
1634 case DCLK_DECOM:
1635 rate = rk3588_mmc_get_clk(priv, clk->id);
1636 break;
1637 case TCLK_WDT0:
1638 rate = OSC_HZ;
1639 break;
1640 #ifndef CONFIG_SPL_BUILD
1641 case CLK_AUX16M_0:
1642 case CLK_AUX16M_1:
1643 rk3588_aux16m_get_clk(priv, clk->id);
1644 break;
1645 case ACLK_VOP_ROOT:
1646 case ACLK_VOP:
1647 case ACLK_VOP_LOW_ROOT:
1648 case HCLK_VOP_ROOT:
1649 rate = rk3588_aclk_vop_get_clk(priv, clk->id);
1650 break;
1651 case DCLK_VOP0:
1652 case DCLK_VOP0_SRC:
1653 case DCLK_VOP1:
1654 case DCLK_VOP1_SRC:
1655 case DCLK_VOP2:
1656 case DCLK_VOP2_SRC:
1657 case DCLK_VOP3:
1658 rate = rk3588_dclk_vop_get_clk(priv, clk->id);
1659 break;
1660 case CLK_DSIHOST0:
1661 case CLK_DSIHOST1:
1662 rate = rk3588_clk_csihost_get_clk(priv, clk->id);
1663 break;
1664 case CLK_GMAC0_PTP_REF:
1665 case CLK_GMAC1_PTP_REF:
1666 case CLK_GMAC_125M:
1667 case CLK_GMAC_50M:
1668 rate = rk3588_gmac_get_clk(priv, clk->id);
1669 break;
1670 case SCLK_UART1:
1671 case SCLK_UART2:
1672 case SCLK_UART3:
1673 case SCLK_UART4:
1674 case SCLK_UART5:
1675 case SCLK_UART6:
1676 case SCLK_UART7:
1677 case SCLK_UART8:
1678 case SCLK_UART9:
1679 rate = rk3588_uart_get_rate(priv, clk->id);
1680 break;
1681 case CLK_REF_PIPE_PHY0:
1682 case CLK_REF_PIPE_PHY1:
1683 case CLK_REF_PIPE_PHY2:
1684 rate = rk3588_pciephy_get_rate(priv, clk->id);
1685 break;
1686 #endif
1687 default:
1688 return -ENOENT;
1689 }
1690
1691 return rate;
1692 };
1693
rk3588_clk_set_rate(struct clk * clk,ulong rate)1694 static ulong rk3588_clk_set_rate(struct clk *clk, ulong rate)
1695 {
1696 struct rk3588_clk_priv *priv = dev_get_priv(clk->dev);
1697 ulong ret = 0;
1698
1699 if (!priv->gpll_hz) {
1700 printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
1701 return -ENOENT;
1702 }
1703
1704 if (!priv->ppll_hz) {
1705 priv->ppll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[PPLL],
1706 priv->cru, PPLL);
1707 }
1708
1709 switch (clk->id) {
1710 case PLL_CPLL:
1711 ret = rockchip_pll_set_rate(&rk3588_pll_clks[CPLL], priv->cru,
1712 CPLL, rate);
1713 priv->cpll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[CPLL],
1714 priv->cru, CPLL);
1715 break;
1716 case PLL_GPLL:
1717 ret = rockchip_pll_set_rate(&rk3588_pll_clks[GPLL], priv->cru,
1718 GPLL, rate);
1719 priv->gpll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[GPLL],
1720 priv->cru, GPLL);
1721 break;
1722 case PLL_NPLL:
1723 ret = rockchip_pll_set_rate(&rk3588_pll_clks[NPLL], priv->cru,
1724 NPLL, rate);
1725 break;
1726 case PLL_V0PLL:
1727 ret = rockchip_pll_set_rate(&rk3588_pll_clks[V0PLL], priv->cru,
1728 V0PLL, rate);
1729 priv->v0pll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[V0PLL],
1730 priv->cru, V0PLL);
1731 break;
1732 case PLL_AUPLL:
1733 ret = rockchip_pll_set_rate(&rk3588_pll_clks[AUPLL], priv->cru,
1734 AUPLL, rate);
1735 priv->aupll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[AUPLL],
1736 priv->cru, AUPLL);
1737 break;
1738 case PLL_PPLL:
1739 ret = rockchip_pll_set_rate(&rk3588_pll_clks[PPLL], priv->cru,
1740 PPLL, rate);
1741 priv->ppll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[PPLL],
1742 priv->cru, PPLL);
1743 break;
1744 case ACLK_CENTER_ROOT:
1745 case PCLK_CENTER_ROOT:
1746 case HCLK_CENTER_ROOT:
1747 case ACLK_CENTER_LOW_ROOT:
1748 ret = rk3588_center_set_clk(priv, clk->id, rate);
1749 break;
1750 case ACLK_TOP_ROOT:
1751 case PCLK_TOP_ROOT:
1752 case ACLK_LOW_TOP_ROOT:
1753 ret = rk3588_top_set_clk(priv, clk->id, rate);
1754 break;
1755 case CLK_I2C0:
1756 case CLK_I2C1:
1757 case CLK_I2C2:
1758 case CLK_I2C3:
1759 case CLK_I2C4:
1760 case CLK_I2C5:
1761 case CLK_I2C6:
1762 case CLK_I2C7:
1763 case CLK_I2C8:
1764 ret = rk3588_i2c_set_clk(priv, clk->id, rate);
1765 break;
1766 case CLK_SPI0:
1767 case CLK_SPI1:
1768 case CLK_SPI2:
1769 case CLK_SPI3:
1770 case CLK_SPI4:
1771 ret = rk3588_spi_set_clk(priv, clk->id, rate);
1772 break;
1773 case CLK_PWM1:
1774 case CLK_PWM2:
1775 case CLK_PWM3:
1776 case CLK_PMU1PWM:
1777 ret = rk3588_pwm_set_clk(priv, clk->id, rate);
1778 break;
1779 case CLK_SARADC:
1780 case CLK_TSADC:
1781 ret = rk3588_adc_set_clk(priv, clk->id, rate);
1782 break;
1783 case CCLK_SRC_SDIO:
1784 case CCLK_EMMC:
1785 case BCLK_EMMC:
1786 case SCLK_SFC:
1787 case DCLK_DECOM:
1788 ret = rk3588_mmc_set_clk(priv, clk->id, rate);
1789 break;
1790 case TCLK_WDT0:
1791 ret = OSC_HZ;
1792 break;
1793 #ifndef CONFIG_SPL_BUILD
1794 case CLK_AUX16M_0:
1795 case CLK_AUX16M_1:
1796 rk3588_aux16m_set_clk(priv, clk->id, rate);
1797 break;
1798 case ACLK_VOP_ROOT:
1799 case ACLK_VOP:
1800 case ACLK_VOP_LOW_ROOT:
1801 case HCLK_VOP_ROOT:
1802 ret = rk3588_aclk_vop_set_clk(priv, clk->id, rate);
1803 break;
1804 case DCLK_VOP0:
1805 case DCLK_VOP0_SRC:
1806 case DCLK_VOP1:
1807 case DCLK_VOP1_SRC:
1808 case DCLK_VOP2:
1809 case DCLK_VOP2_SRC:
1810 case DCLK_VOP3:
1811 ret = rk3588_dclk_vop_set_clk(priv, clk->id, rate);
1812 break;
1813 case CLK_GMAC0_PTP_REF:
1814 case CLK_GMAC1_PTP_REF:
1815 case CLK_GMAC_125M:
1816 case CLK_GMAC_50M:
1817 ret = rk3588_gmac_set_clk(priv, clk->id, rate);
1818 break;
1819 case SCLK_UART1:
1820 case SCLK_UART2:
1821 case SCLK_UART3:
1822 case SCLK_UART4:
1823 case SCLK_UART5:
1824 case SCLK_UART6:
1825 case SCLK_UART7:
1826 case SCLK_UART8:
1827 case SCLK_UART9:
1828 ret = rk3588_uart_set_rate(priv, clk->id, rate);
1829 break;
1830 case CLK_REF_PIPE_PHY0:
1831 case CLK_REF_PIPE_PHY1:
1832 case CLK_REF_PIPE_PHY2:
1833 ret = rk3588_pciephy_set_rate(priv, clk->id, rate);
1834 break;
1835 #endif
1836 default:
1837 return -ENOENT;
1838 }
1839
1840 return ret;
1841 };
1842
1843 #define ROCKCHIP_MMC_DELAY_SEL BIT(10)
1844 #define ROCKCHIP_MMC_DEGREE_MASK 0x3
1845 #define ROCKCHIP_MMC_DELAYNUM_OFFSET 2
1846 #define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
1847
1848 #define PSECS_PER_SEC 1000000000000LL
1849 /*
1850 * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to
1851 * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg.
1852 */
1853 #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60
1854
rk3588_mmc_get_phase(struct clk * clk)1855 int rk3588_mmc_get_phase(struct clk *clk)
1856 {
1857 struct rk3588_clk_priv *priv = dev_get_priv(clk->dev);
1858 struct rk3588_cru *cru = priv->cru;
1859 u32 raw_value, delay_num;
1860 u16 degrees = 0;
1861 ulong rate;
1862
1863 rate = rk3588_clk_get_rate(clk);
1864 if (rate <= 0)
1865 return rate;
1866
1867 if (clk->id == SCLK_SDMMC_SAMPLE)
1868 raw_value = readl(&cru->sdmmc_con[1]);
1869 else
1870 return 0;
1871
1872 raw_value >>= 1;
1873 degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90;
1874
1875 if (raw_value & ROCKCHIP_MMC_DELAY_SEL) {
1876 /* degrees/delaynum * 10000 */
1877 unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) *
1878 36 * (rate / 1000000);
1879
1880 delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK);
1881 delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET;
1882 degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000);
1883 }
1884
1885 return degrees % 360;
1886 }
1887
rk3588_mmc_set_phase(struct clk * clk,u32 degrees)1888 int rk3588_mmc_set_phase(struct clk *clk, u32 degrees)
1889 {
1890 struct rk3588_clk_priv *priv = dev_get_priv(clk->dev);
1891 struct rk3588_cru *cru = priv->cru;
1892 u8 nineties, remainder, delay_num;
1893 u32 raw_value, delay;
1894 ulong rate;
1895
1896 rate = rk3588_clk_get_rate(clk);
1897 if (rate <= 0)
1898 return rate;
1899
1900 nineties = degrees / 90;
1901 remainder = (degrees % 90);
1902
1903 /*
1904 * Convert to delay; do a little extra work to make sure we
1905 * don't overflow 32-bit / 64-bit numbers.
1906 */
1907 delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */
1908 delay *= remainder;
1909 delay = DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 *
1910 (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10));
1911
1912 delay_num = (u8)min_t(u32, delay, 255);
1913
1914 raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0;
1915 raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET;
1916 raw_value |= nineties;
1917
1918 raw_value <<= 1;
1919 if (clk->id == SCLK_SDMMC_SAMPLE)
1920 writel(raw_value | 0xffff0000, &cru->sdmmc_con[1]);
1921
1922 debug("mmc set_phase(%d) delay_nums=%u reg=%#x actual_degrees=%d\n",
1923 degrees, delay_num, raw_value, rk3588_mmc_get_phase(clk));
1924
1925 return 0;
1926 }
1927
rk3588_clk_get_phase(struct clk * clk)1928 static int rk3588_clk_get_phase(struct clk *clk)
1929 {
1930 int ret;
1931
1932 debug("%s %ld\n", __func__, clk->id);
1933 switch (clk->id) {
1934 case SCLK_SDMMC_SAMPLE:
1935 ret = rk3588_mmc_get_phase(clk);
1936 break;
1937 default:
1938 return -ENOENT;
1939 }
1940
1941 return ret;
1942 }
1943
rk3588_clk_set_phase(struct clk * clk,int degrees)1944 static int rk3588_clk_set_phase(struct clk *clk, int degrees)
1945 {
1946 int ret;
1947
1948 debug("%s %ld\n", __func__, clk->id);
1949 switch (clk->id) {
1950 case SCLK_SDMMC_SAMPLE:
1951 ret = rk3588_mmc_set_phase(clk, degrees);
1952 break;
1953 default:
1954 return -ENOENT;
1955 }
1956
1957 return ret;
1958 }
1959
1960 #if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA))
rk3588_dclk_vop_set_parent(struct clk * clk,struct clk * parent)1961 static int __maybe_unused rk3588_dclk_vop_set_parent(struct clk *clk,
1962 struct clk *parent)
1963 {
1964 struct rk3588_clk_priv *priv = dev_get_priv(clk->dev);
1965 struct rk3588_cru *cru = priv->cru;
1966 u32 sel;
1967 const char *clock_dev_name = parent->dev->name;
1968
1969 if (parent->id == PLL_V0PLL)
1970 sel = 2;
1971 else if (parent->id == PLL_GPLL)
1972 sel = 0;
1973 else if (parent->id == PLL_CPLL)
1974 sel = 1;
1975 else
1976 sel = 3;
1977
1978 switch (clk->id) {
1979 case DCLK_VOP0_SRC:
1980 rk_clrsetreg(&cru->clksel_con[111], DCLK0_VOP_SRC_SEL_MASK,
1981 sel << DCLK0_VOP_SRC_SEL_SHIFT);
1982 break;
1983 case DCLK_VOP1_SRC:
1984 rk_clrsetreg(&cru->clksel_con[111], DCLK1_VOP_SRC_SEL_MASK,
1985 sel << DCLK1_VOP_SRC_SEL_SHIFT);
1986 break;
1987 case DCLK_VOP2_SRC:
1988 rk_clrsetreg(&cru->clksel_con[112], DCLK2_VOP_SRC_SEL_MASK,
1989 sel << DCLK2_VOP_SRC_SEL_SHIFT);
1990 break;
1991 case DCLK_VOP3:
1992 rk_clrsetreg(&cru->clksel_con[113], DCLK3_VOP_SRC_SEL_MASK,
1993 sel << DCLK3_VOP_SRC_SEL_SHIFT);
1994 break;
1995 case DCLK_VOP0:
1996 if (!strcmp(clock_dev_name, "hdmiphypll_clk0"))
1997 sel = 1;
1998 else if (!strcmp(clock_dev_name, "hdmiphypll_clk1"))
1999 sel = 2;
2000 else
2001 sel = 0;
2002 rk_clrsetreg(&cru->clksel_con[112], DCLK0_VOP_SEL_MASK,
2003 sel << DCLK0_VOP_SEL_SHIFT);
2004 break;
2005 case DCLK_VOP1:
2006 if (!strcmp(clock_dev_name, "hdmiphypll_clk0"))
2007 sel = 1;
2008 else if (!strcmp(clock_dev_name, "hdmiphypll_clk1"))
2009 sel = 2;
2010 else
2011 sel = 0;
2012 rk_clrsetreg(&cru->clksel_con[112], DCLK1_VOP_SEL_MASK,
2013 sel << DCLK1_VOP_SEL_SHIFT);
2014 break;
2015 case DCLK_VOP2:
2016 if (!strcmp(clock_dev_name, "hdmiphypll_clk0"))
2017 sel = 1;
2018 else if (!strcmp(clock_dev_name, "hdmiphypll_clk1"))
2019 sel = 2;
2020 else
2021 sel = 0;
2022 rk_clrsetreg(&cru->clksel_con[112], DCLK2_VOP_SEL_MASK,
2023 sel << DCLK2_VOP_SEL_SHIFT);
2024 break;
2025 default:
2026 return -EINVAL;
2027 }
2028 return 0;
2029 }
2030
rk3588_clk_set_parent(struct clk * clk,struct clk * parent)2031 static int rk3588_clk_set_parent(struct clk *clk, struct clk *parent)
2032 {
2033 switch (clk->id) {
2034 case DCLK_VOP0_SRC:
2035 case DCLK_VOP1_SRC:
2036 case DCLK_VOP2_SRC:
2037 case DCLK_VOP0:
2038 case DCLK_VOP1:
2039 case DCLK_VOP2:
2040 case DCLK_VOP3:
2041 return rk3588_dclk_vop_set_parent(clk, parent);
2042 default:
2043 return -ENOENT;
2044 }
2045
2046 return 0;
2047 }
2048 #endif
2049
2050 static struct clk_ops rk3588_clk_ops = {
2051 .get_rate = rk3588_clk_get_rate,
2052 .set_rate = rk3588_clk_set_rate,
2053 .get_phase = rk3588_clk_get_phase,
2054 .set_phase = rk3588_clk_set_phase,
2055 #if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA))
2056 .set_parent = rk3588_clk_set_parent,
2057 #endif
2058 };
2059
rk3588_clk_init(struct rk3588_clk_priv * priv)2060 static void rk3588_clk_init(struct rk3588_clk_priv *priv)
2061 {
2062 int ret, div;
2063
2064 div = DIV_ROUND_UP(GPLL_HZ, 300 * MHz);
2065 rk_clrsetreg(&priv->cru->clksel_con[38],
2066 ACLK_BUS_ROOT_SEL_MASK |
2067 ACLK_BUS_ROOT_DIV_MASK,
2068 div << ACLK_BUS_ROOT_DIV_SHIFT);
2069
2070 priv->spll_hz = 702000000;
2071 if (priv->cpll_hz != CPLL_HZ) {
2072 ret = rockchip_pll_set_rate(&rk3588_pll_clks[CPLL], priv->cru,
2073 CPLL, CPLL_HZ);
2074 if (!ret)
2075 priv->cpll_hz = CPLL_HZ;
2076 }
2077 if (priv->gpll_hz != GPLL_HZ) {
2078 ret = rockchip_pll_set_rate(&rk3588_pll_clks[GPLL], priv->cru,
2079 GPLL, GPLL_HZ);
2080 if (!ret)
2081 priv->gpll_hz = GPLL_HZ;
2082 }
2083
2084 if (priv->ppll_hz != PPLL_HZ) {
2085 ret = rockchip_pll_set_rate(&rk3588_pll_clks[PPLL], priv->cru,
2086 PPLL, PPLL_HZ);
2087 priv->ppll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[PPLL],
2088 priv->cru, PPLL);
2089 }
2090
2091 rk_clrsetreg(&priv->cru->clksel_con[9],
2092 ACLK_TOP_S400_SEL_MASK |
2093 ACLK_TOP_S200_SEL_MASK,
2094 (ACLK_TOP_S400_SEL_400M << ACLK_TOP_S400_SEL_SHIFT) |
2095 (ACLK_TOP_S200_SEL_200M << ACLK_TOP_S200_SEL_SHIFT));
2096 }
2097
rk3588_clk_probe(struct udevice * dev)2098 static int rk3588_clk_probe(struct udevice *dev)
2099 {
2100 struct rk3588_clk_priv *priv = dev_get_priv(dev);
2101 int ret;
2102
2103 #if CONFIG_IS_ENABLED(CLK_SCMI)
2104 struct clk clk;
2105 #endif
2106
2107 priv->sync_kernel = false;
2108
2109 #ifdef CONFIG_SPL_BUILD
2110 rockchip_pll_set_rate(&rk3588_pll_clks[B0PLL], priv->cru,
2111 B0PLL, LPLL_HZ);
2112 rockchip_pll_set_rate(&rk3588_pll_clks[B1PLL], priv->cru,
2113 B1PLL, LPLL_HZ);
2114 if (!priv->armclk_enter_hz) {
2115 ret = rockchip_pll_set_rate(&rk3588_pll_clks[LPLL], priv->cru,
2116 LPLL, LPLL_HZ);
2117 priv->armclk_enter_hz =
2118 rockchip_pll_get_rate(&rk3588_pll_clks[LPLL],
2119 priv->cru, LPLL);
2120 priv->armclk_init_hz = priv->armclk_enter_hz;
2121 }
2122 #endif
2123
2124 #if CONFIG_IS_ENABLED(CLK_SCMI)
2125 ret = rockchip_get_scmi_clk(&clk.dev);
2126 if (ret) {
2127 printf("Failed to get scmi clk dev\n");
2128 return ret;
2129 }
2130 clk.id = SCMI_SPLL;
2131 ret = clk_set_rate(&clk, 702000000);
2132 if (ret < 0) {
2133 printf("Failed to set spll\n");
2134 }
2135
2136 #ifndef CONFIG_SPL_BUILD
2137 if (!priv->armclk_enter_hz) {
2138 clk.id = SCMI_CLK_CPUL;
2139 ret = clk_set_rate(&clk, CPU_PVTPLL_HZ);
2140 if (ret < 0) {
2141 printf("Failed to set cpubl\n");
2142 } else {
2143 priv->armclk_enter_hz = CPU_PVTPLL_HZ;
2144 priv->armclk_init_hz = CPU_PVTPLL_HZ;
2145 }
2146 }
2147 clk.id = SCMI_CLK_CPUB01;
2148 ret = clk_set_rate(&clk, CPU_PVTPLL_HZ);
2149 if (ret < 0)
2150 printf("Failed to set cpub01\n");
2151 clk.id = SCMI_CLK_CPUB23;
2152 ret = clk_set_rate(&clk, CPU_PVTPLL_HZ);
2153 if (ret < 0)
2154 printf("Failed to set cpub23\n");
2155 #endif
2156 #endif
2157
2158 priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
2159 if (IS_ERR(priv->grf))
2160 return PTR_ERR(priv->grf);
2161
2162 rk3588_clk_init(priv);
2163
2164 /* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
2165 ret = clk_set_defaults(dev);
2166 if (ret)
2167 debug("%s clk_set_defaults failed %d\n", __func__, ret);
2168 else
2169 priv->sync_kernel = true;
2170
2171 return 0;
2172 }
2173
rk3588_clk_ofdata_to_platdata(struct udevice * dev)2174 static int rk3588_clk_ofdata_to_platdata(struct udevice *dev)
2175 {
2176 struct rk3588_clk_priv *priv = dev_get_priv(dev);
2177
2178 priv->cru = dev_read_addr_ptr(dev);
2179
2180 return 0;
2181 }
2182
rk3588_clk_bind(struct udevice * dev)2183 static int rk3588_clk_bind(struct udevice *dev)
2184 {
2185 int ret;
2186 struct udevice *sys_child, *sf_child;
2187 struct sysreset_reg *priv;
2188 struct softreset_reg *sf_priv;
2189
2190 /* The reset driver does not have a device node, so bind it here */
2191 ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
2192 &sys_child);
2193 if (ret) {
2194 debug("Warning: No sysreset driver: ret=%d\n", ret);
2195 } else {
2196 priv = malloc(sizeof(struct sysreset_reg));
2197 priv->glb_srst_fst_value = offsetof(struct rk3588_cru,
2198 glb_srst_fst);
2199 priv->glb_srst_snd_value = offsetof(struct rk3588_cru,
2200 glb_srsr_snd);
2201 sys_child->priv = priv;
2202 }
2203
2204 ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset",
2205 dev_ofnode(dev), &sf_child);
2206 if (ret) {
2207 debug("Warning: No rockchip reset driver: ret=%d\n", ret);
2208 } else {
2209 sf_priv = malloc(sizeof(struct softreset_reg));
2210 sf_priv->sf_reset_offset = offsetof(struct rk3588_cru,
2211 softrst_con[0]);
2212 sf_priv->sf_reset_num = 49158;
2213 sf_child->priv = sf_priv;
2214 }
2215
2216 return 0;
2217 }
2218
2219 static const struct udevice_id rk3588_clk_ids[] = {
2220 { .compatible = "rockchip,rk3588-cru" },
2221 { }
2222 };
2223
2224 U_BOOT_DRIVER(rockchip_rk3588_cru) = {
2225 .name = "rockchip_rk3588_cru",
2226 .id = UCLASS_CLK,
2227 .of_match = rk3588_clk_ids,
2228 .priv_auto_alloc_size = sizeof(struct rk3588_clk_priv),
2229 .ofdata_to_platdata = rk3588_clk_ofdata_to_platdata,
2230 .ops = &rk3588_clk_ops,
2231 .bind = rk3588_clk_bind,
2232 .probe = rk3588_clk_probe,
2233 };
2234
2235 #ifdef CONFIG_SPL_BUILD
2236 #define SCRU_BASE 0xfd7d0000
2237 #define BUSSCRU_BASE 0xfd7d8000
2238 #define GPLL_RATE 1188000000
2239 #define SPLL_RATE 702000000
2240
2241 #ifndef BITS_WITH_WMASK
2242 #define BITS_WITH_WMASK(bits, msk, shift) \
2243 ((bits) << (shift)) | ((msk) << ((shift) + 16))
2244 #endif
2245
2246 #define CLKDIV_6BITS_SHF(div, shift) BITS_WITH_WMASK(div, 0x3fU, shift)
2247 #define CLKDIV_5BITS_SHF(div, shift) BITS_WITH_WMASK(div, 0x1fU, shift)
2248
rk3588_clk_scmi_get_rate(struct clk * clk)2249 static ulong rk3588_clk_scmi_get_rate(struct clk *clk)
2250 {
2251 u32 src, div;
2252
2253 switch (clk->id) {
2254 case SCMI_SPLL:
2255 src = readl(BUSSCRU_BASE + RK3588_MODE_CON0) & 0x3;
2256 if (src == 0)
2257 return OSC_HZ;
2258 else if (src == 1)
2259 return 702 * MHz;
2260 else
2261 return 32768;
2262 case SCMI_CCLK_SD:
2263 src = readl(SCRU_BASE + RK3588_CLKSEL_CON(3)) & 0x3000;
2264 src = src >> 12;
2265 div = readl(SCRU_BASE + RK3588_CLKSEL_CON(3)) & 0x0fc0;
2266 div = div >> 6;
2267 if (src == 1)
2268 return SPLL_RATE / (div + 1);
2269 else if (src == 2)
2270 return OSC_HZ / (div + 1);
2271 else
2272 return GPLL_RATE / (div + 1);
2273 case SCMI_DCLK_SD:
2274 src = readl(SCRU_BASE + RK3588_CLKSEL_CON(3)) & 0x0020;
2275 div = readl(SCRU_BASE + RK3588_CLKSEL_CON(3)) & 0x001f;
2276 if (src)
2277 return SPLL_RATE / (div + 1);
2278 else
2279 return GPLL_RATE / (div + 1);
2280 case SCMI_CRYPTO_RNG:
2281 src = readl(SCRU_BASE + RK3588_CLKSEL_CON(1)) & 0xc000;
2282 src = src >> 14;
2283 if (src == 0)
2284 return 175 * MHz;
2285 else if (src == 1)
2286 return 116 * MHz;
2287 else if (src == 2)
2288 return 58 * MHz;
2289 else
2290 return OSC_HZ;
2291 case SCMI_CRYPTO_CORE:
2292 src = readl(SCRU_BASE + RK3588_CLKSEL_CON(1)) & 0x0c00;
2293 src = src >> 10;
2294 if (src == 0)
2295 return 350 * MHz;
2296 else if (src == 1)
2297 return 233 * MHz;
2298 else if (src == 2)
2299 return 116 * MHz;
2300 else
2301 return OSC_HZ;
2302 case SCMI_CRYPTO_PKA:
2303 src = readl(SCRU_BASE + RK3588_CLKSEL_CON(1)) & 0x3000;
2304 src = src >> 12;
2305 if (src == 0)
2306 return 350 * MHz;
2307 else if (src == 1)
2308 return 233 * MHz;
2309 else if (src == 2)
2310 return 116 * MHz;
2311 else
2312 return OSC_HZ;
2313 case SCMI_KEYLADDER_CORE:
2314 src = readl(SCRU_BASE + RK3588_CLKSEL_CON(2)) & 0x00c0;
2315 src = src >> 6;
2316 if (src == 0)
2317 return 350 * MHz;
2318 else if (src == 1)
2319 return 233 * MHz;
2320 else if (src == 2)
2321 return 116 * MHz;
2322 else
2323 return OSC_HZ;
2324 case SCMI_KEYLADDER_RNG:
2325 src = readl(SCRU_BASE + RK3588_CLKSEL_CON(2)) & 0x0300;
2326 src = src >> 8;
2327 if (src == 0)
2328 return 175 * MHz;
2329 else if (src == 1)
2330 return 116 * MHz;
2331 else if (src == 2)
2332 return 58 * MHz;
2333 else
2334 return OSC_HZ;
2335 case SCMI_TCLK_WDT:
2336 return OSC_HZ;
2337 case SCMI_HCLK_SD:
2338 case SCMI_HCLK_SECURE_NS:
2339 src = readl(SCRU_BASE + RK3588_CLKSEL_CON(1)) & 0x000c;
2340 src = src >> 2;
2341 if (src == 0)
2342 return 150 * MHz;
2343 else if (src == 1)
2344 return 100 * MHz;
2345 else if (src == 2)
2346 return 50 * MHz;
2347 else
2348 return OSC_HZ;
2349 default:
2350 return -ENOENT;
2351 }
2352 };
2353
rk3588_clk_scmi_set_rate(struct clk * clk,ulong rate)2354 static ulong rk3588_clk_scmi_set_rate(struct clk *clk, ulong rate)
2355 {
2356 u32 src, div;
2357
2358 if ((readl(BUSSCRU_BASE + RK3588_PLL_CON(137)) & 0x01c0) == 0xc0) {
2359 writel(BITS_WITH_WMASK(0, 0x3U, 0),
2360 BUSSCRU_BASE + RK3588_MODE_CON0);
2361 writel(BITS_WITH_WMASK(2, 0x7U, 6),
2362 BUSSCRU_BASE + RK3588_PLL_CON(137));
2363 writel(BITS_WITH_WMASK(1, 0x3U, 0),
2364 BUSSCRU_BASE + RK3588_MODE_CON0);
2365 }
2366
2367 switch (clk->id) {
2368 case SCMI_SPLL:
2369 if (rate >= 700 * MHz)
2370 src = 1;
2371 else
2372 src = 0;
2373 writel(BITS_WITH_WMASK(0, 0x3U, 0),
2374 BUSSCRU_BASE + RK3588_MODE_CON0);
2375 writel(BITS_WITH_WMASK(2, 0x7U, 6),
2376 BUSSCRU_BASE + RK3588_PLL_CON(137));
2377 writel(BITS_WITH_WMASK(src, 0x3U, 0),
2378 BUSSCRU_BASE + RK3588_MODE_CON0);
2379 break;
2380 case SCMI_CCLK_SD:
2381 if ((OSC_HZ % rate) == 0) {
2382 div = DIV_ROUND_UP(OSC_HZ, rate);
2383 writel(CLKDIV_6BITS_SHF(div - 1, 6) |
2384 BITS_WITH_WMASK(2U, 0x3U, 12),
2385 SCRU_BASE + RK3588_CLKSEL_CON(3));
2386 } else if ((SPLL_RATE % rate) == 0) {
2387 div = DIV_ROUND_UP(SPLL_RATE, rate);
2388 writel(CLKDIV_6BITS_SHF(div - 1, 6) |
2389 BITS_WITH_WMASK(1U, 0x3U, 12),
2390 SCRU_BASE + RK3588_CLKSEL_CON(3));
2391 } else {
2392 div = DIV_ROUND_UP(GPLL_RATE, rate);
2393 writel(CLKDIV_6BITS_SHF(div - 1, 6) |
2394 BITS_WITH_WMASK(0U, 0x3U, 12),
2395 SCRU_BASE + RK3588_CLKSEL_CON(3));
2396 }
2397 break;
2398 case SCMI_DCLK_SD:
2399 if ((SPLL_RATE % rate) == 0) {
2400 div = DIV_ROUND_UP(SPLL_RATE, rate);
2401 writel(CLKDIV_5BITS_SHF(div - 1, 0) |
2402 BITS_WITH_WMASK(1U, 0x1U, 5),
2403 SCRU_BASE + RK3588_CLKSEL_CON(3));
2404 } else {
2405 div = DIV_ROUND_UP(GPLL_RATE, rate);
2406 writel(CLKDIV_5BITS_SHF(div - 1, 0) |
2407 BITS_WITH_WMASK(0U, 0x1U, 5),
2408 SCRU_BASE + RK3588_CLKSEL_CON(3));
2409 }
2410 break;
2411 case SCMI_CRYPTO_RNG:
2412 if (rate >= 175 * MHz)
2413 src = 0;
2414 else if (rate >= 116 * MHz)
2415 src = 1;
2416 else if (rate >= 58 * MHz)
2417 src = 2;
2418 else
2419 src = 3;
2420
2421 writel(BITS_WITH_WMASK(src, 0x3U, 14),
2422 SCRU_BASE + RK3588_CLKSEL_CON(1));
2423 break;
2424 case SCMI_CRYPTO_CORE:
2425 if (rate >= 350 * MHz)
2426 src = 0;
2427 else if (rate >= 233 * MHz)
2428 src = 1;
2429 else if (rate >= 116 * MHz)
2430 src = 2;
2431 else
2432 src = 3;
2433
2434 writel(BITS_WITH_WMASK(src, 0x3U, 10),
2435 SCRU_BASE + RK3588_CLKSEL_CON(1));
2436 break;
2437 case SCMI_CRYPTO_PKA:
2438 if (rate >= 350 * MHz)
2439 src = 0;
2440 else if (rate >= 233 * MHz)
2441 src = 1;
2442 else if (rate >= 116 * MHz)
2443 src = 2;
2444 else
2445 src = 3;
2446
2447 writel(BITS_WITH_WMASK(src, 0x3U, 12),
2448 SCRU_BASE + RK3588_CLKSEL_CON(1));
2449 break;
2450 case SCMI_KEYLADDER_CORE:
2451 if (rate >= 350 * MHz)
2452 src = 0;
2453 else if (rate >= 233 * MHz)
2454 src = 1;
2455 else if (rate >= 116 * MHz)
2456 src = 2;
2457 else
2458 src = 3;
2459
2460 writel(BITS_WITH_WMASK(src, 0x3U, 6),
2461 SCRU_BASE + RK3588_CLKSEL_CON(2));
2462 break;
2463 case SCMI_KEYLADDER_RNG:
2464 if (rate >= 175 * MHz)
2465 src = 0;
2466 else if (rate >= 116 * MHz)
2467 src = 1;
2468 else if (rate >= 58 * MHz)
2469 src = 2;
2470 else
2471 src = 3;
2472
2473 writel(BITS_WITH_WMASK(src, 0x3U, 8),
2474 SCRU_BASE + RK3588_CLKSEL_CON(2));
2475 break;
2476 case SCMI_TCLK_WDT:
2477 break;
2478 case SCMI_HCLK_SD:
2479 case SCMI_HCLK_SECURE_NS:
2480 if (rate >= 150 * MHz)
2481 src = 0;
2482 else if (rate >= 100 * MHz)
2483 src = 1;
2484 else if (rate >= 50 * MHz)
2485 src = 2;
2486 else
2487 src = 3;
2488 writel(BITS_WITH_WMASK(src, 0x3U, 2),
2489 SCRU_BASE + RK3588_CLKSEL_CON(1));
2490 break;
2491 default:
2492 return -ENOENT;
2493 }
2494 return 0;
2495 };
2496
2497 /* A fake scmi driver for SPL/TPL where smccc agent is not available. */
2498 static const struct clk_ops scmi_clk_ops = {
2499 .get_rate = rk3588_clk_scmi_get_rate,
2500 .set_rate = rk3588_clk_scmi_set_rate,
2501 };
2502
2503 U_BOOT_DRIVER(scmi_clock) = {
2504 .name = "scmi_clk",
2505 .id = UCLASS_CLK,
2506 .ops = &scmi_clk_ops,
2507 };
2508 #endif
2509
2510 #ifndef CONFIG_SPL_BUILD
2511 /**
2512 * soc_clk_dump() - Print clock frequencies
2513 * Returns zero on success
2514 *
2515 * Implementation for the clk dump command.
2516 */
soc_clk_dump(void)2517 int soc_clk_dump(void)
2518 {
2519 struct udevice *cru_dev;
2520 struct rk3588_clk_priv *priv;
2521 const struct rk3588_clk_info *clk_dump;
2522 struct clk clk;
2523 unsigned long clk_count = ARRAY_SIZE(clks_dump);
2524 unsigned long rate;
2525 int i, ret;
2526
2527 ret = uclass_get_device_by_driver(UCLASS_CLK,
2528 DM_GET_DRIVER(rockchip_rk3588_cru),
2529 &cru_dev);
2530 if (ret) {
2531 printf("%s failed to get cru device\n", __func__);
2532 return ret;
2533 }
2534
2535 priv = dev_get_priv(cru_dev);
2536 printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n",
2537 priv->sync_kernel ? "sync kernel" : "uboot",
2538 priv->armclk_enter_hz / 1000,
2539 priv->armclk_init_hz / 1000,
2540 priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0,
2541 priv->set_armclk_rate ? " KHz" : "N/A");
2542 for (i = 0; i < clk_count; i++) {
2543 clk_dump = &clks_dump[i];
2544 if (clk_dump->name) {
2545 memset(&clk, 0, sizeof(struct clk));
2546 clk.id = clk_dump->id;
2547 if (clk_dump->is_cru)
2548 ret = clk_request(cru_dev, &clk);
2549 if (ret < 0)
2550 return ret;
2551
2552 rate = clk_get_rate(&clk);
2553 clk_free(&clk);
2554 if (rate < 0)
2555 printf(" %s %s\n", clk_dump->name,
2556 "unknown");
2557 else
2558 printf(" %s %lu KHz\n", clk_dump->name,
2559 rate / 1000);
2560 }
2561 }
2562
2563 return 0;
2564 }
2565 #endif
2566