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