blob: 977699d509d65121ee37e9abe49d365ec7a47db6 [file] [log] [blame]
Elaine Zhang5be90bb2021-06-02 11:39:24 +08001// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2021 Rockchip Electronics Co., Ltd
4 * Author: Elaine Zhang <zhangqing@rock-chips.com>
5 */
6
Elaine Zhang5be90bb2021-06-02 11:39:24 +08007#include <bitfield.h>
8#include <clk-uclass.h>
9#include <dm.h>
10#include <errno.h>
11#include <syscon.h>
12#include <asm/arch-rockchip/cru_rk3568.h>
13#include <asm/arch-rockchip/clock.h>
14#include <asm/arch-rockchip/hardware.h>
Peter Geis393cdce2023-03-14 00:38:26 +000015#include <dm/device-internal.h>
Elaine Zhang5be90bb2021-06-02 11:39:24 +080016#include <dm/lists.h>
17#include <dt-bindings/clock/rk3568-cru.h>
18
19DECLARE_GLOBAL_DATA_PTR;
20
21#if CONFIG_IS_ENABLED(OF_PLATDATA)
22struct rk3568_clk_plat {
23 struct dtd_rockchip_rk3568_cru dtd;
24};
25
26struct rk3568_pmuclk_plat {
27 struct dtd_rockchip_rk3568_pmucru dtd;
28};
29#endif
30
31#define RK3568_CPUCLK_RATE(_rate, _aclk_div, _pclk_div) \
32{ \
33 .rate = _rate##U, \
34 .aclk_div = _aclk_div, \
35 .pclk_div = _pclk_div, \
36}
37
38#define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1))
39
40static struct rockchip_cpu_rate_table rk3568_cpu_rates[] = {
41 RK3568_CPUCLK_RATE(1416000000, 1, 5),
42 RK3568_CPUCLK_RATE(1296000000, 1, 5),
43 RK3568_CPUCLK_RATE(1200000000, 1, 3),
44 RK3568_CPUCLK_RATE(1104000000, 1, 3),
45 RK3568_CPUCLK_RATE(1008000000, 1, 3),
46 RK3568_CPUCLK_RATE(912000000, 1, 3),
47 RK3568_CPUCLK_RATE(816000000, 1, 3),
48 RK3568_CPUCLK_RATE(600000000, 1, 1),
49 RK3568_CPUCLK_RATE(408000000, 1, 1),
50 { /* sentinel */ },
51};
52
53static struct rockchip_pll_rate_table rk3568_pll_rates[] = {
54 /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
55 RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0),
56 RK3036_PLL_RATE(1416000000, 1, 118, 2, 1, 1, 0),
57 RK3036_PLL_RATE(1296000000, 1, 108, 2, 1, 1, 0),
58 RK3036_PLL_RATE(1200000000, 1, 100, 2, 1, 1, 0),
59 RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0),
60 RK3036_PLL_RATE(1104000000, 1, 92, 2, 1, 1, 0),
61 RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0),
62 RK3036_PLL_RATE(1000000000, 3, 250, 2, 1, 1, 0),
63 RK3036_PLL_RATE(912000000, 1, 76, 2, 1, 1, 0),
64 RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0),
65 RK3036_PLL_RATE(600000000, 1, 100, 4, 1, 1, 0),
66 RK3036_PLL_RATE(594000000, 1, 99, 4, 1, 1, 0),
67 RK3036_PLL_RATE(500000000, 1, 125, 6, 1, 1, 0),
68 RK3036_PLL_RATE(408000000, 1, 68, 2, 2, 1, 0),
69 RK3036_PLL_RATE(400000000, 1, 100, 6, 1, 1, 0),
70 RK3036_PLL_RATE(200000000, 1, 100, 6, 2, 1, 0),
71 RK3036_PLL_RATE(100000000, 1, 150, 6, 6, 1, 0),
72 { /* sentinel */ },
73};
74
75static struct rockchip_pll_clock rk3568_pll_clks[] = {
76 [APLL] = PLL(pll_rk3328, PLL_APLL, RK3568_PLL_CON(0),
77 RK3568_MODE_CON, 0, 10, 0, rk3568_pll_rates),
78 [DPLL] = PLL(pll_rk3328, PLL_DPLL, RK3568_PLL_CON(8),
79 RK3568_MODE_CON, 2, 10, 0, NULL),
80 [CPLL] = PLL(pll_rk3328, PLL_CPLL, RK3568_PLL_CON(24),
81 RK3568_MODE_CON, 4, 10, 0, rk3568_pll_rates),
82 [GPLL] = PLL(pll_rk3328, PLL_HPLL, RK3568_PLL_CON(16),
83 RK3568_MODE_CON, 6, 10, 0, rk3568_pll_rates),
84 [NPLL] = PLL(pll_rk3328, PLL_NPLL, RK3568_PLL_CON(32),
85 RK3568_MODE_CON, 10, 10, 0, rk3568_pll_rates),
86 [VPLL] = PLL(pll_rk3328, PLL_VPLL, RK3568_PLL_CON(40),
87 RK3568_MODE_CON, 12, 10, 0, rk3568_pll_rates),
88 [PPLL] = PLL(pll_rk3328, PLL_PPLL, RK3568_PMU_PLL_CON(0),
89 RK3568_PMU_MODE, 0, 10, 0, rk3568_pll_rates),
90 [HPLL] = PLL(pll_rk3328, PLL_HPLL, RK3568_PMU_PLL_CON(16),
91 RK3568_PMU_MODE, 2, 10, 0, rk3568_pll_rates),
92};
93
Simon Glass7ec24132024-09-29 19:49:48 -060094#ifndef CONFIG_XPL_BUILD
Elaine Zhang5be90bb2021-06-02 11:39:24 +080095static ulong
96rk3568_pmu_pll_set_rate(struct rk3568_clk_priv *priv,
97 ulong pll_id, ulong rate)
98{
99 struct udevice *pmucru_dev;
100 struct rk3568_pmuclk_priv *pmu_priv;
101 int ret;
102
103 ret = uclass_get_device_by_driver(UCLASS_CLK,
104 DM_DRIVER_GET(rockchip_rk3568_pmucru),
105 &pmucru_dev);
106 if (ret) {
107 printf("%s: could not find pmucru device\n", __func__);
108 return ret;
109 }
110 pmu_priv = dev_get_priv(pmucru_dev);
111
112 rockchip_pll_set_rate(&rk3568_pll_clks[pll_id],
113 pmu_priv->pmucru, pll_id, rate);
114
115 return 0;
116}
117#endif
118
119static ulong rk3568_pmu_pll_get_rate(struct rk3568_clk_priv *priv,
120 ulong pll_id)
121{
122 struct udevice *pmucru_dev;
123 struct rk3568_pmuclk_priv *pmu_priv;
124 int ret;
125
126 ret = uclass_get_device_by_driver(UCLASS_CLK,
127 DM_DRIVER_GET(rockchip_rk3568_pmucru),
128 &pmucru_dev);
129 if (ret) {
130 printf("%s: could not find pmucru device\n", __func__);
131 return ret;
132 }
133 pmu_priv = dev_get_priv(pmucru_dev);
134
135 return rockchip_pll_get_rate(&rk3568_pll_clks[pll_id],
136 pmu_priv->pmucru, pll_id);
137}
138
139/*
140 *
141 * rational_best_approximation(31415, 10000,
142 * (1 << 8) - 1, (1 << 5) - 1, &n, &d);
143 *
144 * you may look at given_numerator as a fixed point number,
145 * with the fractional part size described in given_denominator.
146 *
147 * for theoretical background, see:
148 * http://en.wikipedia.org/wiki/Continued_fraction
149 */
150static void rational_best_approximation(unsigned long given_numerator,
151 unsigned long given_denominator,
152 unsigned long max_numerator,
153 unsigned long max_denominator,
154 unsigned long *best_numerator,
155 unsigned long *best_denominator)
156{
157 unsigned long n, d, n0, d0, n1, d1;
158
159 n = given_numerator;
160 d = given_denominator;
161 n0 = 0;
162 d1 = 0;
163 n1 = 1;
164 d0 = 1;
165 for (;;) {
166 unsigned long t, a;
167
168 if (n1 > max_numerator || d1 > max_denominator) {
169 n1 = n0;
170 d1 = d0;
171 break;
172 }
173 if (d == 0)
174 break;
175 t = d;
176 a = n / d;
177 d = n % d;
178 n = t;
179 t = n0 + a * n1;
180 n0 = n1;
181 n1 = t;
182 t = d0 + a * d1;
183 d0 = d1;
184 d1 = t;
185 }
186 *best_numerator = n1;
187 *best_denominator = d1;
188}
189
190static ulong rk3568_rtc32k_get_pmuclk(struct rk3568_pmuclk_priv *priv)
191{
192 struct rk3568_pmucru *pmucru = priv->pmucru;
193 unsigned long m, n;
194 u32 fracdiv;
195
196 fracdiv = readl(&pmucru->pmu_clksel_con[1]);
197 m = fracdiv & RTC32K_FRAC_NUMERATOR_MASK;
198 m >>= RTC32K_FRAC_NUMERATOR_SHIFT;
199 n = fracdiv & RTC32K_FRAC_DENOMINATOR_MASK;
200 n >>= RTC32K_FRAC_DENOMINATOR_SHIFT;
201
202 return OSC_HZ * m / n;
203}
204
205static ulong rk3568_rtc32k_set_pmuclk(struct rk3568_pmuclk_priv *priv,
206 ulong rate)
207{
208 struct rk3568_pmucru *pmucru = priv->pmucru;
209 unsigned long m, n, val;
210
211 rk_clrsetreg(&pmucru->pmu_clksel_con[0], RTC32K_SEL_MASK,
212 RTC32K_SEL_OSC0_DIV32K << RTC32K_SEL_SHIFT);
213
214 rational_best_approximation(rate, OSC_HZ,
215 GENMASK(16 - 1, 0),
216 GENMASK(16 - 1, 0),
217 &m, &n);
218 val = m << RTC32K_FRAC_NUMERATOR_SHIFT | n;
219 writel(val, &pmucru->pmu_clksel_con[1]);
220
221 return rk3568_rtc32k_get_pmuclk(priv);
222}
223
224static ulong rk3568_i2c_get_pmuclk(struct rk3568_pmuclk_priv *priv,
225 ulong clk_id)
226{
227 struct rk3568_pmucru *pmucru = priv->pmucru;
228 u32 div, con;
229
230 switch (clk_id) {
231 case CLK_I2C0:
232 con = readl(&pmucru->pmu_clksel_con[3]);
233 div = (con & CLK_I2C0_DIV_MASK) >> CLK_I2C0_DIV_SHIFT;
234 break;
235 default:
236 return -ENOENT;
237 }
238
239 return DIV_TO_RATE(priv->ppll_hz, div);
240}
241
242static ulong rk3568_i2c_set_pmuclk(struct rk3568_pmuclk_priv *priv,
243 ulong clk_id, ulong rate)
244{
245 struct rk3568_pmucru *pmucru = priv->pmucru;
246 int src_clk_div;
247
248 src_clk_div = DIV_ROUND_UP(priv->ppll_hz, rate);
249 assert(src_clk_div - 1 <= 127);
250
251 switch (clk_id) {
252 case CLK_I2C0:
253 rk_clrsetreg(&pmucru->pmu_clksel_con[3], CLK_I2C0_DIV_MASK,
254 (src_clk_div - 1) << CLK_I2C0_DIV_SHIFT);
255 break;
256 default:
257 return -ENOENT;
258 }
259
260 return rk3568_i2c_get_pmuclk(priv, clk_id);
261}
262
263static ulong rk3568_pwm_get_pmuclk(struct rk3568_pmuclk_priv *priv,
264 ulong clk_id)
265{
266 struct rk3568_pmucru *pmucru = priv->pmucru;
267 u32 div, sel, con, parent;
268
269 switch (clk_id) {
270 case CLK_PWM0:
271 con = readl(&pmucru->pmu_clksel_con[6]);
272 sel = (con & CLK_PWM0_SEL_MASK) >> CLK_PWM0_SEL_SHIFT;
273 div = (con & CLK_PWM0_DIV_MASK) >> CLK_PWM0_DIV_SHIFT;
274 if (sel == CLK_PWM0_SEL_XIN24M)
275 parent = OSC_HZ;
276 else
277 parent = priv->ppll_hz;
278 break;
279 default:
280 return -ENOENT;
281 }
282
283 return DIV_TO_RATE(parent, div);
284}
285
286static ulong rk3568_pwm_set_pmuclk(struct rk3568_pmuclk_priv *priv,
287 ulong clk_id, ulong rate)
288{
289 struct rk3568_pmucru *pmucru = priv->pmucru;
290 int src_clk_div;
291
292 switch (clk_id) {
293 case CLK_PWM0:
294 if (rate == OSC_HZ) {
295 rk_clrsetreg(&pmucru->pmu_clksel_con[6],
296 CLK_PWM0_SEL_MASK | CLK_PWM0_DIV_MASK,
297 (CLK_PWM0_SEL_XIN24M <<
298 CLK_PWM0_SEL_SHIFT) |
299 0 << CLK_PWM0_SEL_SHIFT);
300 } else {
301 src_clk_div = DIV_ROUND_UP(priv->ppll_hz, rate);
302 assert(src_clk_div - 1 <= 127);
303 rk_clrsetreg(&pmucru->pmu_clksel_con[6],
304 CLK_PWM0_DIV_MASK | CLK_PWM0_DIV_MASK,
305 (CLK_PWM0_SEL_PPLL << CLK_PWM0_SEL_SHIFT) |
306 (src_clk_div - 1) << CLK_PWM0_DIV_SHIFT);
307 }
308 break;
309 default:
310 return -ENOENT;
311 }
312
313 return rk3568_pwm_get_pmuclk(priv, clk_id);
314}
315
316static ulong rk3568_pmu_get_pmuclk(struct rk3568_pmuclk_priv *priv)
317{
318 struct rk3568_pmucru *pmucru = priv->pmucru;
319 u32 div, con, sel, parent;
320
321 con = readl(&pmucru->pmu_clksel_con[2]);
322 sel = (con & PCLK_PDPMU_SEL_MASK) >> PCLK_PDPMU_SEL_SHIFT;
323 div = (con & PCLK_PDPMU_DIV_MASK) >> PCLK_PDPMU_DIV_SHIFT;
324 if (sel)
325 parent = GPLL_HZ;
326 else
327 parent = priv->ppll_hz;
328
329 return DIV_TO_RATE(parent, div);
330}
331
332static ulong rk3568_pmu_set_pmuclk(struct rk3568_pmuclk_priv *priv,
333 ulong rate)
334{
335 struct rk3568_pmucru *pmucru = priv->pmucru;
336 int src_clk_div;
337
338 src_clk_div = DIV_ROUND_UP(priv->ppll_hz, rate);
339 assert(src_clk_div - 1 <= 31);
340
341 rk_clrsetreg(&pmucru->pmu_clksel_con[2],
342 PCLK_PDPMU_DIV_MASK | PCLK_PDPMU_SEL_MASK,
343 (PCLK_PDPMU_SEL_PPLL << PCLK_PDPMU_SEL_SHIFT) |
344 ((src_clk_div - 1) << PCLK_PDPMU_DIV_SHIFT));
345
346 return rk3568_pmu_get_pmuclk(priv);
347}
348
349static ulong rk3568_pmuclk_get_rate(struct clk *clk)
350{
351 struct rk3568_pmuclk_priv *priv = dev_get_priv(clk->dev);
352 ulong rate = 0;
353
354 if (!priv->ppll_hz) {
355 printf("%s ppll=%lu\n", __func__, priv->ppll_hz);
356 return -ENOENT;
357 }
358
359 debug("%s %ld\n", __func__, clk->id);
360 switch (clk->id) {
361 case PLL_PPLL:
362 rate = rockchip_pll_get_rate(&rk3568_pll_clks[PPLL],
363 priv->pmucru, PPLL);
364 break;
365 case PLL_HPLL:
366 rate = rockchip_pll_get_rate(&rk3568_pll_clks[HPLL],
367 priv->pmucru, HPLL);
368 break;
369 case CLK_RTC_32K:
370 case CLK_RTC32K_FRAC:
371 rate = rk3568_rtc32k_get_pmuclk(priv);
372 break;
373 case CLK_I2C0:
374 rate = rk3568_i2c_get_pmuclk(priv, clk->id);
375 break;
376 case CLK_PWM0:
377 rate = rk3568_pwm_get_pmuclk(priv, clk->id);
378 break;
379 case PCLK_PMU:
380 rate = rk3568_pmu_get_pmuclk(priv);
381 break;
382 default:
383 return -ENOENT;
384 }
385
386 return rate;
387}
388
389static ulong rk3568_pmuclk_set_rate(struct clk *clk, ulong rate)
390{
391 struct rk3568_pmuclk_priv *priv = dev_get_priv(clk->dev);
392 ulong ret = 0;
393
394 if (!priv->ppll_hz) {
395 printf("%s ppll=%lu\n", __func__, priv->ppll_hz);
396 return -ENOENT;
397 }
398
399 debug("%s %ld %ld\n", __func__, clk->id, rate);
400 switch (clk->id) {
401 case PLL_PPLL:
402 ret = rockchip_pll_set_rate(&rk3568_pll_clks[PPLL],
403 priv->pmucru, PPLL, rate);
404 priv->ppll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[PPLL],
405 priv->pmucru, PPLL);
406 break;
407 case PLL_HPLL:
408 ret = rockchip_pll_set_rate(&rk3568_pll_clks[HPLL],
409 priv->pmucru, HPLL, rate);
410 priv->hpll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[HPLL],
411 priv->pmucru, HPLL);
412 break;
413 case CLK_RTC_32K:
414 case CLK_RTC32K_FRAC:
415 ret = rk3568_rtc32k_set_pmuclk(priv, rate);
416 break;
417 case CLK_I2C0:
418 ret = rk3568_i2c_set_pmuclk(priv, clk->id, rate);
419 break;
420 case CLK_PWM0:
421 ret = rk3568_pwm_set_pmuclk(priv, clk->id, rate);
422 break;
423 case PCLK_PMU:
424 ret = rk3568_pmu_set_pmuclk(priv, rate);
425 break;
Vasily Khoruzhick74da8be2023-03-07 21:16:10 -0800426 case CLK_PCIEPHY0_REF:
427 case CLK_PCIEPHY1_REF:
Jonas Karlman96342352023-07-22 13:30:22 +0000428 case CLK_PCIEPHY2_REF:
Vasily Khoruzhick74da8be2023-03-07 21:16:10 -0800429 return 0;
Elaine Zhang5be90bb2021-06-02 11:39:24 +0800430 default:
431 return -ENOENT;
432 }
433
434 return ret;
435}
436
437static int rk3568_rtc32k_set_parent(struct clk *clk, struct clk *parent)
438{
439 struct rk3568_pmuclk_priv *priv = dev_get_priv(clk->dev);
440 struct rk3568_pmucru *pmucru = priv->pmucru;
441
442 if (parent->id == CLK_RTC32K_FRAC)
443 rk_clrsetreg(&pmucru->pmu_clksel_con[0], RTC32K_SEL_MASK,
444 RTC32K_SEL_OSC0_DIV32K << RTC32K_SEL_SHIFT);
445 else
446 rk_clrsetreg(&pmucru->pmu_clksel_con[0], RTC32K_SEL_MASK,
447 RTC32K_SEL_OSC1_32K << RTC32K_SEL_SHIFT);
448
449 return 0;
450}
451
452static int rk3568_pmuclk_set_parent(struct clk *clk, struct clk *parent)
453{
454 switch (clk->id) {
455 case CLK_RTC_32K:
456 return rk3568_rtc32k_set_parent(clk, parent);
457 default:
458 return -ENOENT;
459 }
460}
461
462static struct clk_ops rk3568_pmuclk_ops = {
463 .get_rate = rk3568_pmuclk_get_rate,
464 .set_rate = rk3568_pmuclk_set_rate,
465 .set_parent = rk3568_pmuclk_set_parent,
466};
467
468static int rk3568_pmuclk_probe(struct udevice *dev)
469{
470 struct rk3568_pmuclk_priv *priv = dev_get_priv(dev);
471 int ret = 0;
472
473 if (priv->ppll_hz != PPLL_HZ) {
474 ret = rockchip_pll_set_rate(&rk3568_pll_clks[PPLL],
475 priv->pmucru,
476 PPLL, PPLL_HZ);
477 if (!ret)
478 priv->ppll_hz = PPLL_HZ;
479 }
480
481 /* Ungate PCIe30phy refclk_m and refclk_n */
482 rk_clrsetreg(&priv->pmucru->pmu_clkgate_con[2], 0x3 << 13, 0 << 13);
483 return 0;
484}
485
486static int rk3568_pmuclk_ofdata_to_platdata(struct udevice *dev)
487{
488 struct rk3568_pmuclk_priv *priv = dev_get_priv(dev);
489
490 priv->pmucru = dev_read_addr_ptr(dev);
491
492 return 0;
493}
494
495static int rk3568_pmuclk_bind(struct udevice *dev)
496{
497#if CONFIG_IS_ENABLED(RESET_ROCKCHIP)
498 int ret = 0;
499
500 ret = offsetof(struct rk3568_pmucru, pmu_softrst_con[0]);
501 ret = rockchip_reset_bind(dev, ret, 1);
502 if (ret)
Eugen Hristevf1798262023-04-11 10:17:56 +0300503 debug("Warning: pmucru software reset driver bind failed\n");
Elaine Zhang5be90bb2021-06-02 11:39:24 +0800504#endif
505
506 return 0;
507}
508
509static const struct udevice_id rk3568_pmuclk_ids[] = {
510 { .compatible = "rockchip,rk3568-pmucru" },
511 { }
512};
513
514U_BOOT_DRIVER(rockchip_rk3568_pmucru) = {
515 .name = "rockchip_rk3568_pmucru",
516 .id = UCLASS_CLK,
517 .of_match = rk3568_pmuclk_ids,
518 .priv_auto = sizeof(struct rk3568_pmuclk_priv),
519 .of_to_plat = rk3568_pmuclk_ofdata_to_platdata,
520 .ops = &rk3568_pmuclk_ops,
521 .bind = rk3568_pmuclk_bind,
522 .probe = rk3568_pmuclk_probe,
523#if CONFIG_IS_ENABLED(OF_PLATDATA)
524 .plat_auto = sizeof(struct rk3568_pmuclk_plat),
525#endif
526
527};
528
529static int rk3568_armclk_set_clk(struct rk3568_clk_priv *priv, ulong hz)
530{
531 struct rk3568_cru *cru = priv->cru;
532 const struct rockchip_cpu_rate_table *rate;
533 ulong old_rate;
534
535 rate = rockchip_get_cpu_settings(rk3568_cpu_rates, hz);
536 if (!rate) {
537 printf("%s unsupported rate\n", __func__);
538 return -EINVAL;
539 }
540
541 rk_clrsetreg(&cru->clksel_con[0],
542 CLK_CORE_PRE_SEL_MASK,
543 (CLK_CORE_PRE_SEL_SRC << CLK_CORE_PRE_SEL_SHIFT));
544 rk_clrsetreg(&cru->clksel_con[2],
545 SCLK_CORE_PRE_SEL_MASK |
546 SCLK_CORE_SRC_SEL_MASK |
547 SCLK_CORE_SRC_DIV_MASK,
548 (SCLK_CORE_PRE_SEL_SRC <<
549 SCLK_CORE_PRE_SEL_SHIFT) |
550 (SCLK_CORE_SRC_SEL_APLL <<
551 SCLK_CORE_SRC_SEL_SHIFT) |
552 (1 << SCLK_CORE_SRC_DIV_SHIFT));
553
554 /*
555 * set up dependent divisors for DBG and ACLK clocks.
556 */
557 old_rate = rockchip_pll_get_rate(&rk3568_pll_clks[APLL],
558 priv->cru, APLL);
559 if (old_rate > hz) {
560 if (rockchip_pll_set_rate(&rk3568_pll_clks[APLL],
561 priv->cru, APLL, hz))
562 return -EINVAL;
563 rk_clrsetreg(&cru->clksel_con[3],
564 GICCLK_CORE_DIV_MASK | ATCLK_CORE_DIV_MASK,
565 rate->pclk_div << GICCLK_CORE_DIV_SHIFT |
566 rate->pclk_div << ATCLK_CORE_DIV_SHIFT);
567 rk_clrsetreg(&cru->clksel_con[4],
568 PERIPHCLK_CORE_PRE_DIV_MASK |
569 PCLK_CORE_PRE_DIV_MASK,
570 rate->pclk_div << PCLK_CORE_PRE_DIV_SHIFT |
571 rate->pclk_div << PERIPHCLK_CORE_PRE_DIV_SHIFT);
572 rk_clrsetreg(&cru->clksel_con[5],
573 ACLK_CORE_NDFT_DIV_MASK,
574 rate->aclk_div << ACLK_CORE_NDFT_DIV_SHIFT);
575 } else if (old_rate < hz) {
576 rk_clrsetreg(&cru->clksel_con[3],
577 GICCLK_CORE_DIV_MASK | ATCLK_CORE_DIV_MASK,
578 rate->pclk_div << GICCLK_CORE_DIV_SHIFT |
579 rate->pclk_div << ATCLK_CORE_DIV_SHIFT);
580 rk_clrsetreg(&cru->clksel_con[4],
581 PERIPHCLK_CORE_PRE_DIV_MASK |
582 PCLK_CORE_PRE_DIV_MASK,
583 rate->pclk_div << PCLK_CORE_PRE_DIV_SHIFT |
584 rate->pclk_div << PERIPHCLK_CORE_PRE_DIV_SHIFT);
585 rk_clrsetreg(&cru->clksel_con[5],
586 ACLK_CORE_NDFT_DIV_MASK,
587 rate->aclk_div << ACLK_CORE_NDFT_DIV_SHIFT);
588 if (rockchip_pll_set_rate(&rk3568_pll_clks[APLL],
589 priv->cru, APLL, hz))
590 return -EINVAL;
591 }
592
593 return 0;
594}
595
596static ulong rk3568_cpll_div_get_rate(struct rk3568_clk_priv *priv,
597 ulong clk_id)
598{
599 struct rk3568_cru *cru = priv->cru;
600 int div, mask, shift, con;
601
602 switch (clk_id) {
603 case CPLL_500M:
604 con = 78;
605 mask = CPLL_500M_DIV_MASK;
606 shift = CPLL_500M_DIV_SHIFT;
607 break;
608 case CPLL_333M:
609 con = 79;
610 mask = CPLL_333M_DIV_MASK;
611 shift = CPLL_333M_DIV_SHIFT;
612 break;
613 case CPLL_250M:
614 con = 79;
615 mask = CPLL_250M_DIV_MASK;
616 shift = CPLL_250M_DIV_SHIFT;
617 break;
618 case CPLL_125M:
619 con = 80;
620 mask = CPLL_125M_DIV_MASK;
621 shift = CPLL_125M_DIV_SHIFT;
622 break;
623 case CPLL_100M:
624 con = 82;
625 mask = CPLL_100M_DIV_MASK;
626 shift = CPLL_100M_DIV_SHIFT;
627 break;
628 case CPLL_62P5M:
629 con = 80;
630 mask = CPLL_62P5M_DIV_MASK;
631 shift = CPLL_62P5M_DIV_SHIFT;
632 break;
633 case CPLL_50M:
634 con = 81;
635 mask = CPLL_50M_DIV_MASK;
636 shift = CPLL_50M_DIV_SHIFT;
637 break;
638 case CPLL_25M:
639 con = 81;
640 mask = CPLL_25M_DIV_MASK;
641 shift = CPLL_25M_DIV_SHIFT;
642 break;
643 default:
644 return -ENOENT;
645 }
646
647 div = (readl(&cru->clksel_con[con]) & mask) >> shift;
648 return DIV_TO_RATE(priv->cpll_hz, div);
649}
650
651static ulong rk3568_cpll_div_set_rate(struct rk3568_clk_priv *priv,
652 ulong clk_id, ulong rate)
653{
654 struct rk3568_cru *cru = priv->cru;
655 int div, mask, shift, con;
656
657 switch (clk_id) {
658 case CPLL_500M:
659 con = 78;
660 mask = CPLL_500M_DIV_MASK;
661 shift = CPLL_500M_DIV_SHIFT;
662 break;
663 case CPLL_333M:
664 con = 79;
665 mask = CPLL_333M_DIV_MASK;
666 shift = CPLL_333M_DIV_SHIFT;
667 break;
668 case CPLL_250M:
669 con = 79;
670 mask = CPLL_250M_DIV_MASK;
671 shift = CPLL_250M_DIV_SHIFT;
672 break;
673 case CPLL_125M:
674 con = 80;
675 mask = CPLL_125M_DIV_MASK;
676 shift = CPLL_125M_DIV_SHIFT;
677 break;
678 case CPLL_100M:
679 con = 82;
680 mask = CPLL_100M_DIV_MASK;
681 shift = CPLL_100M_DIV_SHIFT;
682 break;
683 case CPLL_62P5M:
684 con = 80;
685 mask = CPLL_62P5M_DIV_MASK;
686 shift = CPLL_62P5M_DIV_SHIFT;
687 break;
688 case CPLL_50M:
689 con = 81;
690 mask = CPLL_50M_DIV_MASK;
691 shift = CPLL_50M_DIV_SHIFT;
692 break;
693 case CPLL_25M:
694 con = 81;
695 mask = CPLL_25M_DIV_MASK;
696 shift = CPLL_25M_DIV_SHIFT;
697 break;
698 default:
699 return -ENOENT;
700 }
701
702 div = DIV_ROUND_UP(priv->cpll_hz, rate);
Jonas Karlmanf51ca5c2023-08-04 09:33:59 +0000703 if (clk_id == CPLL_25M)
704 assert(div - 1 <= 63);
705 else
706 assert(div - 1 <= 31);
Elaine Zhang5be90bb2021-06-02 11:39:24 +0800707 rk_clrsetreg(&cru->clksel_con[con],
708 mask, (div - 1) << shift);
709 return rk3568_cpll_div_get_rate(priv, clk_id);
710}
711
712static ulong rk3568_bus_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
713{
714 struct rk3568_cru *cru = priv->cru;
715 u32 con, sel, rate;
716
717 switch (clk_id) {
718 case ACLK_BUS:
719 con = readl(&cru->clksel_con[50]);
720 sel = (con & ACLK_BUS_SEL_MASK) >> ACLK_BUS_SEL_SHIFT;
721 if (sel == ACLK_BUS_SEL_200M)
722 rate = 200 * MHz;
723 else if (sel == ACLK_BUS_SEL_150M)
724 rate = 150 * MHz;
725 else if (sel == ACLK_BUS_SEL_100M)
726 rate = 100 * MHz;
727 else
728 rate = OSC_HZ;
729 break;
730 case PCLK_BUS:
731 case PCLK_WDT_NS:
732 con = readl(&cru->clksel_con[50]);
733 sel = (con & PCLK_BUS_SEL_MASK) >> PCLK_BUS_SEL_SHIFT;
734 if (sel == PCLK_BUS_SEL_100M)
735 rate = 100 * MHz;
736 else if (sel == PCLK_BUS_SEL_75M)
737 rate = 75 * MHz;
738 else if (sel == PCLK_BUS_SEL_50M)
739 rate = 50 * MHz;
740 else
741 rate = OSC_HZ;
742 break;
743 default:
744 return -ENOENT;
745 }
746
747 return rate;
748}
749
750static ulong rk3568_bus_set_clk(struct rk3568_clk_priv *priv,
751 ulong clk_id, ulong rate)
752{
753 struct rk3568_cru *cru = priv->cru;
754 int src_clk;
755
756 switch (clk_id) {
757 case ACLK_BUS:
758 if (rate == 200 * MHz)
759 src_clk = ACLK_BUS_SEL_200M;
760 else if (rate == 150 * MHz)
761 src_clk = ACLK_BUS_SEL_150M;
762 else if (rate == 100 * MHz)
763 src_clk = ACLK_BUS_SEL_100M;
764 else
765 src_clk = ACLK_BUS_SEL_24M;
766 rk_clrsetreg(&cru->clksel_con[50],
767 ACLK_BUS_SEL_MASK,
768 src_clk << ACLK_BUS_SEL_SHIFT);
769 break;
770 case PCLK_BUS:
771 case PCLK_WDT_NS:
772 if (rate == 100 * MHz)
773 src_clk = PCLK_BUS_SEL_100M;
774 else if (rate == 75 * MHz)
775 src_clk = PCLK_BUS_SEL_75M;
776 else if (rate == 50 * MHz)
777 src_clk = PCLK_BUS_SEL_50M;
778 else
779 src_clk = PCLK_BUS_SEL_24M;
780 rk_clrsetreg(&cru->clksel_con[50],
781 PCLK_BUS_SEL_MASK,
782 src_clk << PCLK_BUS_SEL_SHIFT);
783 break;
784
785 default:
786 printf("do not support this bus freq\n");
787 return -EINVAL;
788 }
789
790 return rk3568_bus_get_clk(priv, clk_id);
791}
792
793static ulong rk3568_perimid_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
794{
795 struct rk3568_cru *cru = priv->cru;
796 u32 con, sel, rate;
797
798 switch (clk_id) {
799 case ACLK_PERIMID:
800 con = readl(&cru->clksel_con[10]);
801 sel = (con & ACLK_PERIMID_SEL_MASK) >> ACLK_PERIMID_SEL_SHIFT;
802 if (sel == ACLK_PERIMID_SEL_300M)
803 rate = 300 * MHz;
804 else if (sel == ACLK_PERIMID_SEL_200M)
805 rate = 200 * MHz;
806 else if (sel == ACLK_PERIMID_SEL_100M)
807 rate = 100 * MHz;
808 else
809 rate = OSC_HZ;
810 break;
811 case HCLK_PERIMID:
812 con = readl(&cru->clksel_con[10]);
813 sel = (con & HCLK_PERIMID_SEL_MASK) >> HCLK_PERIMID_SEL_SHIFT;
814 if (sel == HCLK_PERIMID_SEL_150M)
815 rate = 150 * MHz;
816 else if (sel == HCLK_PERIMID_SEL_100M)
817 rate = 100 * MHz;
818 else if (sel == HCLK_PERIMID_SEL_75M)
819 rate = 75 * MHz;
820 else
821 rate = OSC_HZ;
822 break;
823 default:
824 return -ENOENT;
825 }
826
827 return rate;
828}
829
830static ulong rk3568_perimid_set_clk(struct rk3568_clk_priv *priv,
831 ulong clk_id, ulong rate)
832{
833 struct rk3568_cru *cru = priv->cru;
834 int src_clk;
835
836 switch (clk_id) {
837 case ACLK_PERIMID:
838 if (rate == 300 * MHz)
839 src_clk = ACLK_PERIMID_SEL_300M;
840 else if (rate == 200 * MHz)
841 src_clk = ACLK_PERIMID_SEL_200M;
842 else if (rate == 100 * MHz)
843 src_clk = ACLK_PERIMID_SEL_100M;
844 else
845 src_clk = ACLK_PERIMID_SEL_24M;
846 rk_clrsetreg(&cru->clksel_con[10],
847 ACLK_PERIMID_SEL_MASK,
848 src_clk << ACLK_PERIMID_SEL_SHIFT);
849 break;
850 case HCLK_PERIMID:
851 if (rate == 150 * MHz)
852 src_clk = HCLK_PERIMID_SEL_150M;
853 else if (rate == 100 * MHz)
854 src_clk = HCLK_PERIMID_SEL_100M;
855 else if (rate == 75 * MHz)
856 src_clk = HCLK_PERIMID_SEL_75M;
857 else
858 src_clk = HCLK_PERIMID_SEL_24M;
859 rk_clrsetreg(&cru->clksel_con[10],
860 HCLK_PERIMID_SEL_MASK,
861 src_clk << HCLK_PERIMID_SEL_SHIFT);
862 break;
863
864 default:
865 printf("do not support this permid freq\n");
866 return -EINVAL;
867 }
868
869 return rk3568_perimid_get_clk(priv, clk_id);
870}
871
872static ulong rk3568_top_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
873{
874 struct rk3568_cru *cru = priv->cru;
875 u32 con, sel, rate;
876
877 switch (clk_id) {
878 case ACLK_TOP_HIGH:
879 con = readl(&cru->clksel_con[73]);
880 sel = (con & ACLK_TOP_HIGH_SEL_MASK) >> ACLK_TOP_HIGH_SEL_SHIFT;
881 if (sel == ACLK_TOP_HIGH_SEL_500M)
882 rate = 500 * MHz;
883 else if (sel == ACLK_TOP_HIGH_SEL_400M)
884 rate = 400 * MHz;
885 else if (sel == ACLK_TOP_HIGH_SEL_300M)
886 rate = 300 * MHz;
887 else
888 rate = OSC_HZ;
889 break;
890 case ACLK_TOP_LOW:
891 con = readl(&cru->clksel_con[73]);
892 sel = (con & ACLK_TOP_LOW_SEL_MASK) >> ACLK_TOP_LOW_SEL_SHIFT;
893 if (sel == ACLK_TOP_LOW_SEL_400M)
894 rate = 400 * MHz;
895 else if (sel == ACLK_TOP_LOW_SEL_300M)
896 rate = 300 * MHz;
897 else if (sel == ACLK_TOP_LOW_SEL_200M)
898 rate = 200 * MHz;
899 else
900 rate = OSC_HZ;
901 break;
902 case HCLK_TOP:
903 con = readl(&cru->clksel_con[73]);
904 sel = (con & HCLK_TOP_SEL_MASK) >> HCLK_TOP_SEL_SHIFT;
905 if (sel == HCLK_TOP_SEL_150M)
906 rate = 150 * MHz;
907 else if (sel == HCLK_TOP_SEL_100M)
908 rate = 100 * MHz;
909 else if (sel == HCLK_TOP_SEL_75M)
910 rate = 75 * MHz;
911 else
912 rate = OSC_HZ;
913 break;
914 case PCLK_TOP:
915 con = readl(&cru->clksel_con[73]);
916 sel = (con & PCLK_TOP_SEL_MASK) >> PCLK_TOP_SEL_SHIFT;
917 if (sel == PCLK_TOP_SEL_100M)
918 rate = 100 * MHz;
919 else if (sel == PCLK_TOP_SEL_75M)
920 rate = 75 * MHz;
921 else if (sel == PCLK_TOP_SEL_50M)
922 rate = 50 * MHz;
923 else
924 rate = OSC_HZ;
925 break;
926 default:
927 return -ENOENT;
928 }
929
930 return rate;
931}
932
933static ulong rk3568_top_set_clk(struct rk3568_clk_priv *priv,
934 ulong clk_id, ulong rate)
935{
936 struct rk3568_cru *cru = priv->cru;
937 int src_clk;
938
939 switch (clk_id) {
940 case ACLK_TOP_HIGH:
941 if (rate == 500 * MHz)
942 src_clk = ACLK_TOP_HIGH_SEL_500M;
943 else if (rate == 400 * MHz)
944 src_clk = ACLK_TOP_HIGH_SEL_400M;
945 else if (rate == 300 * MHz)
946 src_clk = ACLK_TOP_HIGH_SEL_300M;
947 else
948 src_clk = ACLK_TOP_HIGH_SEL_24M;
949 rk_clrsetreg(&cru->clksel_con[73],
950 ACLK_TOP_HIGH_SEL_MASK,
951 src_clk << ACLK_TOP_HIGH_SEL_SHIFT);
952 break;
953 case ACLK_TOP_LOW:
954 if (rate == 400 * MHz)
955 src_clk = ACLK_TOP_LOW_SEL_400M;
956 else if (rate == 300 * MHz)
957 src_clk = ACLK_TOP_LOW_SEL_300M;
958 else if (rate == 200 * MHz)
959 src_clk = ACLK_TOP_LOW_SEL_200M;
960 else
961 src_clk = ACLK_TOP_LOW_SEL_24M;
962 rk_clrsetreg(&cru->clksel_con[73],
963 ACLK_TOP_LOW_SEL_MASK,
964 src_clk << ACLK_TOP_LOW_SEL_SHIFT);
965 break;
966 case HCLK_TOP:
967 if (rate == 150 * MHz)
968 src_clk = HCLK_TOP_SEL_150M;
969 else if (rate == 100 * MHz)
970 src_clk = HCLK_TOP_SEL_100M;
971 else if (rate == 75 * MHz)
972 src_clk = HCLK_TOP_SEL_75M;
973 else
974 src_clk = HCLK_TOP_SEL_24M;
975 rk_clrsetreg(&cru->clksel_con[73],
976 HCLK_TOP_SEL_MASK,
977 src_clk << HCLK_TOP_SEL_SHIFT);
978 break;
979 case PCLK_TOP:
980 if (rate == 100 * MHz)
981 src_clk = PCLK_TOP_SEL_100M;
982 else if (rate == 75 * MHz)
983 src_clk = PCLK_TOP_SEL_75M;
984 else if (rate == 50 * MHz)
985 src_clk = PCLK_TOP_SEL_50M;
986 else
987 src_clk = PCLK_TOP_SEL_24M;
988 rk_clrsetreg(&cru->clksel_con[73],
989 PCLK_TOP_SEL_MASK,
990 src_clk << PCLK_TOP_SEL_SHIFT);
991 break;
992
993 default:
994 printf("do not support this permid freq\n");
995 return -EINVAL;
996 }
997
998 return rk3568_top_get_clk(priv, clk_id);
999}
1000
1001static ulong rk3568_i2c_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
1002{
1003 struct rk3568_cru *cru = priv->cru;
1004 u32 sel, con;
1005 ulong rate;
1006
1007 switch (clk_id) {
1008 case CLK_I2C1:
1009 case CLK_I2C2:
1010 case CLK_I2C3:
1011 case CLK_I2C4:
1012 case CLK_I2C5:
1013 con = readl(&cru->clksel_con[71]);
1014 sel = (con & CLK_I2C_SEL_MASK) >> CLK_I2C_SEL_SHIFT;
1015 if (sel == CLK_I2C_SEL_200M)
1016 rate = 200 * MHz;
1017 else if (sel == CLK_I2C_SEL_100M)
1018 rate = 100 * MHz;
1019 else if (sel == CLK_I2C_SEL_CPLL_100M)
1020 rate = 100 * MHz;
1021 else
1022 rate = OSC_HZ;
1023 break;
1024 default:
1025 return -ENOENT;
1026 }
1027
1028 return rate;
1029}
1030
1031static ulong rk3568_i2c_set_clk(struct rk3568_clk_priv *priv, ulong clk_id,
1032 ulong rate)
1033{
1034 struct rk3568_cru *cru = priv->cru;
1035 int src_clk;
1036
1037 if (rate == 200 * MHz)
1038 src_clk = CLK_I2C_SEL_200M;
1039 else if (rate == 100 * MHz)
1040 src_clk = CLK_I2C_SEL_100M;
1041 else
1042 src_clk = CLK_I2C_SEL_24M;
1043
1044 switch (clk_id) {
1045 case CLK_I2C1:
1046 case CLK_I2C2:
1047 case CLK_I2C3:
1048 case CLK_I2C4:
1049 case CLK_I2C5:
1050 rk_clrsetreg(&cru->clksel_con[71], CLK_I2C_SEL_MASK,
1051 src_clk << CLK_I2C_SEL_SHIFT);
1052 break;
1053 default:
1054 return -ENOENT;
1055 }
1056
1057 return rk3568_i2c_get_clk(priv, clk_id);
1058}
1059
1060static ulong rk3568_spi_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
1061{
1062 struct rk3568_cru *cru = priv->cru;
1063 u32 sel, con;
1064
1065 con = readl(&cru->clksel_con[72]);
1066
1067 switch (clk_id) {
1068 case CLK_SPI0:
1069 sel = (con & CLK_SPI0_SEL_MASK) >> CLK_SPI0_SEL_SHIFT;
1070 break;
1071 case CLK_SPI1:
1072 sel = (con & CLK_SPI1_SEL_MASK) >> CLK_SPI1_SEL_SHIFT;
1073 break;
1074 case CLK_SPI2:
1075 sel = (con & CLK_SPI2_SEL_MASK) >> CLK_SPI2_SEL_SHIFT;
1076 break;
1077 case CLK_SPI3:
1078 sel = (con & CLK_SPI3_SEL_MASK) >> CLK_SPI3_SEL_SHIFT;
1079 break;
1080 default:
1081 return -ENOENT;
1082 }
1083
1084 switch (sel) {
1085 case CLK_SPI_SEL_200M:
1086 return 200 * MHz;
1087 case CLK_SPI_SEL_24M:
1088 return OSC_HZ;
1089 case CLK_SPI_SEL_CPLL_100M:
1090 return 100 * MHz;
1091 default:
1092 return -ENOENT;
1093 }
1094}
1095
1096static ulong rk3568_spi_set_clk(struct rk3568_clk_priv *priv,
1097 ulong clk_id, ulong rate)
1098{
1099 struct rk3568_cru *cru = priv->cru;
1100 int src_clk;
1101
1102 if (rate == 200 * MHz)
1103 src_clk = CLK_SPI_SEL_200M;
1104 else if (rate == 100 * MHz)
1105 src_clk = CLK_SPI_SEL_CPLL_100M;
1106 else
1107 src_clk = CLK_SPI_SEL_24M;
1108
1109 switch (clk_id) {
1110 case CLK_SPI0:
1111 rk_clrsetreg(&cru->clksel_con[72],
1112 CLK_SPI0_SEL_MASK,
1113 src_clk << CLK_SPI0_SEL_SHIFT);
1114 break;
1115 case CLK_SPI1:
1116 rk_clrsetreg(&cru->clksel_con[72],
1117 CLK_SPI1_SEL_MASK,
1118 src_clk << CLK_SPI1_SEL_SHIFT);
1119 break;
1120 case CLK_SPI2:
1121 rk_clrsetreg(&cru->clksel_con[72],
1122 CLK_SPI2_SEL_MASK,
1123 src_clk << CLK_SPI2_SEL_SHIFT);
1124 break;
1125 case CLK_SPI3:
1126 rk_clrsetreg(&cru->clksel_con[72],
1127 CLK_SPI3_SEL_MASK,
1128 src_clk << CLK_SPI3_SEL_SHIFT);
1129 break;
1130 default:
1131 return -ENOENT;
1132 }
1133
1134 return rk3568_spi_get_clk(priv, clk_id);
1135}
1136
1137static ulong rk3568_pwm_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
1138{
1139 struct rk3568_cru *cru = priv->cru;
1140 u32 sel, con;
1141
1142 con = readl(&cru->clksel_con[72]);
1143
1144 switch (clk_id) {
1145 case CLK_PWM1:
Damon Ding46e99932023-08-04 09:33:57 +00001146 sel = (con & CLK_PWM1_SEL_MASK) >> CLK_PWM1_SEL_SHIFT;
Elaine Zhang5be90bb2021-06-02 11:39:24 +08001147 break;
1148 case CLK_PWM2:
1149 sel = (con & CLK_PWM2_SEL_MASK) >> CLK_PWM2_SEL_SHIFT;
1150 break;
1151 case CLK_PWM3:
1152 sel = (con & CLK_PWM3_SEL_MASK) >> CLK_PWM3_SEL_SHIFT;
1153 break;
1154 default:
1155 return -ENOENT;
1156 }
1157
1158 switch (sel) {
1159 case CLK_PWM_SEL_100M:
1160 return 100 * MHz;
1161 case CLK_PWM_SEL_24M:
1162 return OSC_HZ;
1163 case CLK_PWM_SEL_CPLL_100M:
1164 return 100 * MHz;
1165 default:
1166 return -ENOENT;
1167 }
1168}
1169
1170static ulong rk3568_pwm_set_clk(struct rk3568_clk_priv *priv,
1171 ulong clk_id, ulong rate)
1172{
1173 struct rk3568_cru *cru = priv->cru;
1174 int src_clk;
1175
1176 if (rate == 100 * MHz)
1177 src_clk = CLK_PWM_SEL_100M;
1178 else
1179 src_clk = CLK_PWM_SEL_24M;
1180
1181 switch (clk_id) {
1182 case CLK_PWM1:
1183 rk_clrsetreg(&cru->clksel_con[72],
1184 CLK_PWM1_SEL_MASK,
1185 src_clk << CLK_PWM1_SEL_SHIFT);
1186 break;
1187 case CLK_PWM2:
1188 rk_clrsetreg(&cru->clksel_con[72],
1189 CLK_PWM2_SEL_MASK,
1190 src_clk << CLK_PWM2_SEL_SHIFT);
1191 break;
1192 case CLK_PWM3:
1193 rk_clrsetreg(&cru->clksel_con[72],
1194 CLK_PWM3_SEL_MASK,
1195 src_clk << CLK_PWM3_SEL_SHIFT);
1196 break;
1197 default:
1198 return -ENOENT;
1199 }
1200
1201 return rk3568_pwm_get_clk(priv, clk_id);
1202}
1203
1204static ulong rk3568_adc_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
1205{
1206 struct rk3568_cru *cru = priv->cru;
1207 u32 div, sel, con, prate;
1208
1209 switch (clk_id) {
1210 case CLK_SARADC:
1211 return OSC_HZ;
1212 case CLK_TSADC_TSEN:
1213 con = readl(&cru->clksel_con[51]);
1214 div = (con & CLK_TSADC_TSEN_DIV_MASK) >>
1215 CLK_TSADC_TSEN_DIV_SHIFT;
1216 sel = (con & CLK_TSADC_TSEN_SEL_MASK) >>
1217 CLK_TSADC_TSEN_SEL_SHIFT;
1218 if (sel == CLK_TSADC_TSEN_SEL_24M)
1219 prate = OSC_HZ;
1220 else
1221 prate = 100 * MHz;
1222 return DIV_TO_RATE(prate, div);
1223 case CLK_TSADC:
1224 con = readl(&cru->clksel_con[51]);
1225 div = (con & CLK_TSADC_DIV_MASK) >> CLK_TSADC_DIV_SHIFT;
1226 prate = rk3568_adc_get_clk(priv, CLK_TSADC_TSEN);
1227 return DIV_TO_RATE(prate, div);
1228 default:
1229 return -ENOENT;
1230 }
1231}
1232
1233static ulong rk3568_adc_set_clk(struct rk3568_clk_priv *priv,
1234 ulong clk_id, ulong rate)
1235{
1236 struct rk3568_cru *cru = priv->cru;
1237 int src_clk_div;
1238 ulong prate = 0;
1239
1240 switch (clk_id) {
1241 case CLK_SARADC:
1242 return OSC_HZ;
1243 case CLK_TSADC_TSEN:
1244 if (!(OSC_HZ % rate)) {
1245 src_clk_div = DIV_ROUND_UP(OSC_HZ, rate);
1246 assert(src_clk_div - 1 <= 7);
1247 rk_clrsetreg(&cru->clksel_con[51],
1248 CLK_TSADC_TSEN_SEL_MASK |
1249 CLK_TSADC_TSEN_DIV_MASK,
1250 (CLK_TSADC_TSEN_SEL_24M <<
1251 CLK_TSADC_TSEN_SEL_SHIFT) |
1252 (src_clk_div - 1) <<
1253 CLK_TSADC_TSEN_DIV_SHIFT);
1254 } else {
1255 src_clk_div = DIV_ROUND_UP(100 * MHz, rate);
1256 assert(src_clk_div - 1 <= 7);
1257 rk_clrsetreg(&cru->clksel_con[51],
1258 CLK_TSADC_TSEN_SEL_MASK |
1259 CLK_TSADC_TSEN_DIV_MASK,
1260 (CLK_TSADC_TSEN_SEL_100M <<
1261 CLK_TSADC_TSEN_SEL_SHIFT) |
1262 (src_clk_div - 1) <<
1263 CLK_TSADC_TSEN_DIV_SHIFT);
1264 }
1265 break;
1266 case CLK_TSADC:
1267 prate = rk3568_adc_get_clk(priv, CLK_TSADC_TSEN);
1268 src_clk_div = DIV_ROUND_UP(prate, rate);
1269 assert(src_clk_div - 1 <= 128);
1270 rk_clrsetreg(&cru->clksel_con[51],
1271 CLK_TSADC_DIV_MASK,
1272 (src_clk_div - 1) << CLK_TSADC_DIV_SHIFT);
1273 break;
1274 default:
1275 return -ENOENT;
1276 }
1277 return rk3568_adc_get_clk(priv, clk_id);
1278}
1279
1280static ulong rk3568_crypto_get_rate(struct rk3568_clk_priv *priv, ulong clk_id)
1281{
1282 struct rk3568_cru *cru = priv->cru;
1283 u32 sel, con;
1284
1285 switch (clk_id) {
1286 case ACLK_SECURE_FLASH:
1287 case ACLK_CRYPTO_NS:
1288 con = readl(&cru->clksel_con[27]);
1289 sel = (con & ACLK_SECURE_FLASH_SEL_MASK) >>
1290 ACLK_SECURE_FLASH_SEL_SHIFT;
1291 if (sel == ACLK_SECURE_FLASH_SEL_200M)
1292 return 200 * MHz;
1293 else if (sel == ACLK_SECURE_FLASH_SEL_150M)
1294 return 150 * MHz;
1295 else if (sel == ACLK_SECURE_FLASH_SEL_100M)
1296 return 100 * MHz;
1297 else
1298 return 24 * MHz;
1299 case HCLK_SECURE_FLASH:
1300 case HCLK_CRYPTO_NS:
1301 case CLK_CRYPTO_NS_RNG:
1302 con = readl(&cru->clksel_con[27]);
1303 sel = (con & HCLK_SECURE_FLASH_SEL_MASK) >>
1304 HCLK_SECURE_FLASH_SEL_SHIFT;
1305 if (sel == HCLK_SECURE_FLASH_SEL_150M)
1306 return 150 * MHz;
1307 else if (sel == HCLK_SECURE_FLASH_SEL_100M)
1308 return 100 * MHz;
1309 else if (sel == HCLK_SECURE_FLASH_SEL_75M)
1310 return 75 * MHz;
1311 else
1312 return 24 * MHz;
1313 case CLK_CRYPTO_NS_CORE:
1314 con = readl(&cru->clksel_con[27]);
1315 sel = (con & CLK_CRYPTO_CORE_SEL_MASK) >>
1316 CLK_CRYPTO_CORE_SEL_SHIFT;
1317 if (sel == CLK_CRYPTO_CORE_SEL_200M)
1318 return 200 * MHz;
1319 else if (sel == CLK_CRYPTO_CORE_SEL_150M)
1320 return 150 * MHz;
1321 else
1322 return 100 * MHz;
1323 case CLK_CRYPTO_NS_PKA:
1324 con = readl(&cru->clksel_con[27]);
1325 sel = (con & CLK_CRYPTO_PKA_SEL_MASK) >>
1326 CLK_CRYPTO_PKA_SEL_SHIFT;
1327 if (sel == CLK_CRYPTO_PKA_SEL_300M)
1328 return 300 * MHz;
1329 else if (sel == CLK_CRYPTO_PKA_SEL_200M)
1330 return 200 * MHz;
1331 else
1332 return 100 * MHz;
1333 default:
1334 return -ENOENT;
1335 }
1336}
1337
1338static ulong rk3568_crypto_set_rate(struct rk3568_clk_priv *priv,
1339 ulong clk_id, ulong rate)
1340{
1341 struct rk3568_cru *cru = priv->cru;
1342 u32 src_clk, mask, shift;
1343
1344 switch (clk_id) {
1345 case ACLK_SECURE_FLASH:
1346 case ACLK_CRYPTO_NS:
1347 mask = ACLK_SECURE_FLASH_SEL_MASK;
1348 shift = ACLK_SECURE_FLASH_SEL_SHIFT;
1349 if (rate == 200 * MHz)
1350 src_clk = ACLK_SECURE_FLASH_SEL_200M;
1351 else if (rate == 150 * MHz)
1352 src_clk = ACLK_SECURE_FLASH_SEL_150M;
1353 else if (rate == 100 * MHz)
1354 src_clk = ACLK_SECURE_FLASH_SEL_100M;
1355 else
1356 src_clk = ACLK_SECURE_FLASH_SEL_24M;
1357 break;
1358 case HCLK_SECURE_FLASH:
1359 case HCLK_CRYPTO_NS:
1360 case CLK_CRYPTO_NS_RNG:
1361 mask = HCLK_SECURE_FLASH_SEL_MASK;
1362 shift = HCLK_SECURE_FLASH_SEL_SHIFT;
1363 if (rate == 150 * MHz)
1364 src_clk = HCLK_SECURE_FLASH_SEL_150M;
1365 else if (rate == 100 * MHz)
1366 src_clk = HCLK_SECURE_FLASH_SEL_100M;
1367 else if (rate == 75 * MHz)
1368 src_clk = HCLK_SECURE_FLASH_SEL_75M;
1369 else
1370 src_clk = HCLK_SECURE_FLASH_SEL_24M;
1371 break;
1372 case CLK_CRYPTO_NS_CORE:
1373 mask = CLK_CRYPTO_CORE_SEL_MASK;
1374 shift = CLK_CRYPTO_CORE_SEL_SHIFT;
1375 if (rate == 200 * MHz)
1376 src_clk = CLK_CRYPTO_CORE_SEL_200M;
1377 else if (rate == 150 * MHz)
1378 src_clk = CLK_CRYPTO_CORE_SEL_150M;
1379 else
1380 src_clk = CLK_CRYPTO_CORE_SEL_100M;
1381 break;
1382 case CLK_CRYPTO_NS_PKA:
1383 mask = CLK_CRYPTO_PKA_SEL_MASK;
1384 shift = CLK_CRYPTO_PKA_SEL_SHIFT;
1385 if (rate == 300 * MHz)
1386 src_clk = CLK_CRYPTO_PKA_SEL_300M;
1387 else if (rate == 200 * MHz)
1388 src_clk = CLK_CRYPTO_PKA_SEL_200M;
1389 else
1390 src_clk = CLK_CRYPTO_PKA_SEL_100M;
1391 break;
1392 default:
1393 return -ENOENT;
1394 }
1395
1396 rk_clrsetreg(&cru->clksel_con[27], mask, src_clk << shift);
1397
1398 return rk3568_crypto_get_rate(priv, clk_id);
1399}
1400
1401static ulong rk3568_sdmmc_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
1402{
1403 struct rk3568_cru *cru = priv->cru;
1404 u32 sel, con;
1405
1406 switch (clk_id) {
1407 case HCLK_SDMMC0:
1408 case CLK_SDMMC0:
1409 con = readl(&cru->clksel_con[30]);
1410 sel = (con & CLK_SDMMC0_SEL_MASK) >> CLK_SDMMC0_SEL_SHIFT;
1411 break;
1412 case CLK_SDMMC1:
1413 con = readl(&cru->clksel_con[30]);
1414 sel = (con & CLK_SDMMC1_SEL_MASK) >> CLK_SDMMC1_SEL_SHIFT;
1415 break;
1416 case CLK_SDMMC2:
1417 con = readl(&cru->clksel_con[32]);
1418 sel = (con & CLK_SDMMC2_SEL_MASK) >> CLK_SDMMC2_SEL_SHIFT;
1419 break;
1420 default:
1421 return -ENOENT;
1422 }
1423
1424 switch (sel) {
1425 case CLK_SDMMC_SEL_24M:
1426 return OSC_HZ;
1427 case CLK_SDMMC_SEL_400M:
1428 return 400 * MHz;
1429 case CLK_SDMMC_SEL_300M:
1430 return 300 * MHz;
1431 case CLK_SDMMC_SEL_100M:
1432 return 100 * MHz;
1433 case CLK_SDMMC_SEL_50M:
1434 return 50 * MHz;
1435 case CLK_SDMMC_SEL_750K:
1436 return 750 * KHz;
1437 default:
1438 return -ENOENT;
1439 }
1440}
1441
1442static ulong rk3568_sdmmc_set_clk(struct rk3568_clk_priv *priv,
1443 ulong clk_id, ulong rate)
1444{
1445 struct rk3568_cru *cru = priv->cru;
1446 int src_clk;
1447
1448 switch (rate) {
1449 case OSC_HZ:
Elaine Zhang7b9b9262021-10-12 16:43:00 +08001450 case 26 * MHz:
Vasily Khoruzhickd35b4c82023-02-23 13:03:32 -08001451 case 25 * MHz:
Elaine Zhang5be90bb2021-06-02 11:39:24 +08001452 src_clk = CLK_SDMMC_SEL_24M;
1453 break;
1454 case 400 * MHz:
1455 src_clk = CLK_SDMMC_SEL_400M;
1456 break;
1457 case 300 * MHz:
1458 src_clk = CLK_SDMMC_SEL_300M;
1459 break;
1460 case 100 * MHz:
1461 src_clk = CLK_SDMMC_SEL_100M;
1462 break;
1463 case 52 * MHz:
1464 case 50 * MHz:
1465 src_clk = CLK_SDMMC_SEL_50M;
1466 break;
1467 case 750 * KHz:
1468 case 400 * KHz:
1469 src_clk = CLK_SDMMC_SEL_750K;
1470 break;
1471 default:
1472 return -ENOENT;
1473 }
1474
1475 switch (clk_id) {
1476 case HCLK_SDMMC0:
1477 case CLK_SDMMC0:
1478 rk_clrsetreg(&cru->clksel_con[30],
1479 CLK_SDMMC0_SEL_MASK,
1480 src_clk << CLK_SDMMC0_SEL_SHIFT);
1481 break;
1482 case CLK_SDMMC1:
1483 rk_clrsetreg(&cru->clksel_con[30],
1484 CLK_SDMMC1_SEL_MASK,
1485 src_clk << CLK_SDMMC1_SEL_SHIFT);
1486 break;
1487 case CLK_SDMMC2:
1488 rk_clrsetreg(&cru->clksel_con[32],
1489 CLK_SDMMC2_SEL_MASK,
1490 src_clk << CLK_SDMMC2_SEL_SHIFT);
1491 break;
1492 default:
1493 return -ENOENT;
1494 }
1495
1496 return rk3568_sdmmc_get_clk(priv, clk_id);
1497}
1498
1499static ulong rk3568_sfc_get_clk(struct rk3568_clk_priv *priv)
1500{
1501 struct rk3568_cru *cru = priv->cru;
1502 u32 sel, con;
1503
1504 con = readl(&cru->clksel_con[28]);
1505 sel = (con & SCLK_SFC_SEL_MASK) >> SCLK_SFC_SEL_SHIFT;
1506 switch (sel) {
1507 case SCLK_SFC_SEL_24M:
1508 return OSC_HZ;
1509 case SCLK_SFC_SEL_50M:
1510 return 50 * MHz;
1511 case SCLK_SFC_SEL_75M:
1512 return 75 * MHz;
1513 case SCLK_SFC_SEL_100M:
1514 return 100 * MHz;
1515 case SCLK_SFC_SEL_125M:
1516 return 125 * MHz;
1517 case SCLK_SFC_SEL_150M:
Elaine Zhang7b9b9262021-10-12 16:43:00 +08001518 return 150 * MHz;
Elaine Zhang5be90bb2021-06-02 11:39:24 +08001519 default:
1520 return -ENOENT;
1521 }
1522}
1523
1524static ulong rk3568_sfc_set_clk(struct rk3568_clk_priv *priv, ulong rate)
1525{
1526 struct rk3568_cru *cru = priv->cru;
1527 int src_clk;
1528
Jonas Karlmanb8ae8f72024-04-22 06:28:40 +00001529 if (rate >= 150 * MHz)
Elaine Zhang5be90bb2021-06-02 11:39:24 +08001530 src_clk = SCLK_SFC_SEL_150M;
Jonas Karlmanb8ae8f72024-04-22 06:28:40 +00001531 else if (rate >= 125 * MHz)
1532 src_clk = SCLK_SFC_SEL_125M;
1533 else if (rate >= 100 * MHz)
1534 src_clk = SCLK_SFC_SEL_100M;
1535 else if (rate >= 75 * MHz)
1536 src_clk = SCLK_SFC_SEL_75M;
1537 else if (rate >= 50 * MHz)
1538 src_clk = SCLK_SFC_SEL_50M;
1539 else if (rate >= OSC_HZ)
1540 src_clk = SCLK_SFC_SEL_24M;
1541 else
Elaine Zhang5be90bb2021-06-02 11:39:24 +08001542 return -ENOENT;
Elaine Zhang5be90bb2021-06-02 11:39:24 +08001543
1544 rk_clrsetreg(&cru->clksel_con[28],
1545 SCLK_SFC_SEL_MASK,
1546 src_clk << SCLK_SFC_SEL_SHIFT);
1547
1548 return rk3568_sfc_get_clk(priv);
1549}
1550
1551static ulong rk3568_nand_get_clk(struct rk3568_clk_priv *priv)
1552{
1553 struct rk3568_cru *cru = priv->cru;
1554 u32 sel, con;
1555
1556 con = readl(&cru->clksel_con[28]);
1557 sel = (con & NCLK_NANDC_SEL_MASK) >> NCLK_NANDC_SEL_SHIFT;
1558 switch (sel) {
1559 case NCLK_NANDC_SEL_200M:
1560 return 200 * MHz;
1561 case NCLK_NANDC_SEL_150M:
1562 return 150 * MHz;
1563 case NCLK_NANDC_SEL_100M:
1564 return 100 * MHz;
1565 case NCLK_NANDC_SEL_24M:
1566 return OSC_HZ;
1567 default:
1568 return -ENOENT;
1569 }
1570}
1571
1572static ulong rk3568_nand_set_clk(struct rk3568_clk_priv *priv, ulong rate)
1573{
1574 struct rk3568_cru *cru = priv->cru;
1575 int src_clk;
1576
1577 switch (rate) {
1578 case OSC_HZ:
1579 src_clk = NCLK_NANDC_SEL_24M;
1580 break;
1581 case 100 * MHz:
1582 src_clk = NCLK_NANDC_SEL_100M;
1583 break;
1584 case 150 * MHz:
1585 src_clk = NCLK_NANDC_SEL_150M;
1586 break;
1587 case 200 * MHz:
1588 src_clk = NCLK_NANDC_SEL_200M;
1589 break;
1590 default:
1591 return -ENOENT;
1592 }
1593
1594 rk_clrsetreg(&cru->clksel_con[28],
1595 NCLK_NANDC_SEL_MASK,
1596 src_clk << NCLK_NANDC_SEL_SHIFT);
1597
1598 return rk3568_nand_get_clk(priv);
1599}
1600
1601static ulong rk3568_emmc_get_clk(struct rk3568_clk_priv *priv)
1602{
1603 struct rk3568_cru *cru = priv->cru;
1604 u32 sel, con;
1605
1606 con = readl(&cru->clksel_con[28]);
1607 sel = (con & CCLK_EMMC_SEL_MASK) >> CCLK_EMMC_SEL_SHIFT;
1608 switch (sel) {
1609 case CCLK_EMMC_SEL_200M:
1610 return 200 * MHz;
1611 case CCLK_EMMC_SEL_150M:
1612 return 150 * MHz;
1613 case CCLK_EMMC_SEL_100M:
1614 return 100 * MHz;
1615 case CCLK_EMMC_SEL_50M:
1616 return 50 * MHz;
1617 case CCLK_EMMC_SEL_375K:
1618 return 375 * KHz;
1619 case CCLK_EMMC_SEL_24M:
1620 return OSC_HZ;
1621 default:
1622 return -ENOENT;
1623 }
1624}
1625
1626static ulong rk3568_emmc_set_clk(struct rk3568_clk_priv *priv, ulong rate)
1627{
1628 struct rk3568_cru *cru = priv->cru;
1629 int src_clk;
1630
1631 switch (rate) {
1632 case OSC_HZ:
Vasily Khoruzhickd35b4c82023-02-23 13:03:32 -08001633 case 26 * MHz:
1634 case 25 * MHz:
Elaine Zhang5be90bb2021-06-02 11:39:24 +08001635 src_clk = CCLK_EMMC_SEL_24M;
1636 break;
1637 case 52 * MHz:
1638 case 50 * MHz:
1639 src_clk = CCLK_EMMC_SEL_50M;
1640 break;
1641 case 100 * MHz:
1642 src_clk = CCLK_EMMC_SEL_100M;
1643 break;
1644 case 150 * MHz:
1645 src_clk = CCLK_EMMC_SEL_150M;
1646 break;
1647 case 200 * MHz:
1648 src_clk = CCLK_EMMC_SEL_200M;
1649 break;
1650 case 400 * KHz:
1651 case 375 * KHz:
1652 src_clk = CCLK_EMMC_SEL_375K;
1653 break;
1654 default:
1655 return -ENOENT;
1656 }
1657
1658 rk_clrsetreg(&cru->clksel_con[28],
1659 CCLK_EMMC_SEL_MASK,
1660 src_clk << CCLK_EMMC_SEL_SHIFT);
1661
1662 return rk3568_emmc_get_clk(priv);
1663}
1664
1665static ulong rk3568_emmc_get_bclk(struct rk3568_clk_priv *priv)
1666{
1667 struct rk3568_cru *cru = priv->cru;
1668 u32 sel, con;
1669
1670 con = readl(&cru->clksel_con[28]);
1671 sel = (con & BCLK_EMMC_SEL_MASK) >> BCLK_EMMC_SEL_SHIFT;
1672 switch (sel) {
1673 case BCLK_EMMC_SEL_200M:
1674 return 200 * MHz;
1675 case BCLK_EMMC_SEL_150M:
1676 return 150 * MHz;
1677 case BCLK_EMMC_SEL_125M:
1678 return 125 * MHz;
1679 default:
1680 return -ENOENT;
1681 }
1682}
1683
1684static ulong rk3568_emmc_set_bclk(struct rk3568_clk_priv *priv, ulong rate)
1685{
1686 struct rk3568_cru *cru = priv->cru;
1687 int src_clk;
1688
1689 switch (rate) {
1690 case 200 * MHz:
1691 src_clk = BCLK_EMMC_SEL_200M;
1692 break;
1693 case 150 * MHz:
1694 src_clk = BCLK_EMMC_SEL_150M;
1695 break;
1696 case 125 * MHz:
1697 src_clk = BCLK_EMMC_SEL_125M;
1698 break;
1699 default:
1700 return -ENOENT;
1701 }
1702
1703 rk_clrsetreg(&cru->clksel_con[28],
1704 BCLK_EMMC_SEL_MASK,
1705 src_clk << BCLK_EMMC_SEL_SHIFT);
1706
1707 return rk3568_emmc_get_bclk(priv);
1708}
1709
Simon Glass7ec24132024-09-29 19:49:48 -06001710#ifndef CONFIG_XPL_BUILD
Elaine Zhang5be90bb2021-06-02 11:39:24 +08001711static ulong rk3568_aclk_vop_get_clk(struct rk3568_clk_priv *priv)
1712{
1713 struct rk3568_cru *cru = priv->cru;
1714 u32 div, sel, con, parent;
1715
1716 con = readl(&cru->clksel_con[38]);
1717 div = (con & ACLK_VOP_PRE_DIV_MASK) >> ACLK_VOP_PRE_DIV_SHIFT;
1718 sel = (con & ACLK_VOP_PRE_SEL_MASK) >> ACLK_VOP_PRE_SEL_SHIFT;
1719 if (sel == ACLK_VOP_PRE_SEL_GPLL)
1720 parent = priv->gpll_hz;
1721 else if (sel == ACLK_VOP_PRE_SEL_CPLL)
1722 parent = priv->cpll_hz;
1723 else if (sel == ACLK_VOP_PRE_SEL_VPLL)
1724 parent = priv->vpll_hz;
1725 else
1726 parent = priv->hpll_hz;
1727
1728 return DIV_TO_RATE(parent, div);
1729}
1730
1731static ulong rk3568_aclk_vop_set_clk(struct rk3568_clk_priv *priv, ulong rate)
1732{
1733 struct rk3568_cru *cru = priv->cru;
1734 int src_clk_div, src_clk_mux;
1735
1736 if ((priv->cpll_hz % rate) == 0) {
1737 src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate);
1738 src_clk_mux = ACLK_VOP_PRE_SEL_CPLL;
1739 } else {
1740 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
1741 src_clk_mux = ACLK_VOP_PRE_SEL_GPLL;
1742 }
1743 assert(src_clk_div - 1 <= 31);
1744 rk_clrsetreg(&cru->clksel_con[38],
1745 ACLK_VOP_PRE_SEL_MASK | ACLK_VOP_PRE_DIV_MASK,
1746 src_clk_mux << ACLK_VOP_PRE_SEL_SHIFT |
1747 (src_clk_div - 1) << ACLK_VOP_PRE_DIV_SHIFT);
1748
1749 return rk3568_aclk_vop_get_clk(priv);
1750}
1751
1752static ulong rk3568_dclk_vop_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
1753{
1754 struct rk3568_cru *cru = priv->cru;
1755 u32 conid, div, sel, con, parent;
1756
1757 switch (clk_id) {
1758 case DCLK_VOP0:
1759 conid = 39;
1760 break;
1761 case DCLK_VOP1:
1762 conid = 40;
1763 break;
1764 case DCLK_VOP2:
1765 conid = 41;
1766 break;
1767 default:
1768 return -ENOENT;
1769 }
1770
1771 con = readl(&cru->clksel_con[conid]);
1772 div = (con & DCLK0_VOP_DIV_MASK) >> DCLK0_VOP_DIV_SHIFT;
1773 sel = (con & DCLK0_VOP_SEL_MASK) >> DCLK0_VOP_SEL_SHIFT;
1774 if (sel == DCLK_VOP_SEL_HPLL)
1775 parent = rk3568_pmu_pll_get_rate(priv, HPLL);
1776 else if (sel == DCLK_VOP_SEL_VPLL)
1777 parent = rockchip_pll_get_rate(&rk3568_pll_clks[VPLL],
1778 priv->cru, VPLL);
1779 else if (sel == DCLK_VOP_SEL_GPLL)
1780 parent = priv->gpll_hz;
1781 else if (sel == DCLK_VOP_SEL_CPLL)
1782 parent = priv->cpll_hz;
1783 else
1784 return -ENOENT;
1785
1786 return DIV_TO_RATE(parent, div);
1787}
1788
1789#define RK3568_VOP_PLL_LIMIT_FREQ 600000000
1790
1791static ulong rk3568_dclk_vop_set_clk(struct rk3568_clk_priv *priv,
1792 ulong clk_id, ulong rate)
1793{
1794 struct rk3568_cru *cru = priv->cru;
1795 ulong pll_rate, now, best_rate = 0;
1796 u32 i, conid, con, sel, div, best_div = 0, best_sel = 0;
1797
1798 switch (clk_id) {
1799 case DCLK_VOP0:
1800 conid = 39;
1801 break;
1802 case DCLK_VOP1:
1803 conid = 40;
1804 break;
1805 case DCLK_VOP2:
1806 conid = 41;
1807 break;
1808 default:
1809 return -ENOENT;
1810 }
1811
1812 con = readl(&cru->clksel_con[conid]);
1813 sel = (con & DCLK0_VOP_SEL_MASK) >> DCLK0_VOP_SEL_SHIFT;
1814
1815 if (sel == DCLK_VOP_SEL_HPLL) {
1816 div = 1;
1817 rk_clrsetreg(&cru->clksel_con[conid],
1818 DCLK0_VOP_DIV_MASK | DCLK0_VOP_SEL_MASK,
1819 (DCLK_VOP_SEL_HPLL << DCLK0_VOP_SEL_SHIFT) |
1820 ((div - 1) << DCLK0_VOP_DIV_SHIFT));
1821 rk3568_pmu_pll_set_rate(priv, HPLL, div * rate);
1822 } else if (sel == DCLK_VOP_SEL_VPLL) {
1823 div = DIV_ROUND_UP(RK3568_VOP_PLL_LIMIT_FREQ, rate);
1824 rk_clrsetreg(&cru->clksel_con[conid],
1825 DCLK0_VOP_DIV_MASK | DCLK0_VOP_SEL_MASK,
1826 (DCLK_VOP_SEL_VPLL << DCLK0_VOP_SEL_SHIFT) |
1827 ((div - 1) << DCLK0_VOP_DIV_SHIFT));
1828 rockchip_pll_set_rate(&rk3568_pll_clks[VPLL],
1829 priv->cru, VPLL, div * rate);
1830 } else {
Elaine Zhangf12a1602023-10-11 18:29:43 +08001831 for (i = sel; i <= DCLK_VOP_SEL_CPLL; i++) {
Elaine Zhang5be90bb2021-06-02 11:39:24 +08001832 switch (i) {
1833 case DCLK_VOP_SEL_GPLL:
1834 pll_rate = priv->gpll_hz;
1835 break;
1836 case DCLK_VOP_SEL_CPLL:
1837 pll_rate = priv->cpll_hz;
1838 break;
1839 default:
1840 printf("do not support this vop pll sel\n");
1841 return -EINVAL;
1842 }
1843
1844 div = DIV_ROUND_UP(pll_rate, rate);
1845 if (div > 255)
1846 continue;
1847 now = pll_rate / div;
1848 if (abs(rate - now) < abs(rate - best_rate)) {
1849 best_rate = now;
1850 best_div = div;
1851 best_sel = i;
1852 }
1853 debug("p_rate=%lu, best_rate=%lu, div=%u, sel=%u\n",
1854 pll_rate, best_rate, best_div, best_sel);
1855 }
1856
1857 if (best_rate) {
1858 rk_clrsetreg(&cru->clksel_con[conid],
1859 DCLK0_VOP_DIV_MASK | DCLK0_VOP_SEL_MASK,
1860 best_sel << DCLK0_VOP_SEL_SHIFT |
1861 (best_div - 1) << DCLK0_VOP_DIV_SHIFT);
1862 } else {
1863 printf("do not support this vop freq %lu\n", rate);
1864 return -EINVAL;
1865 }
1866 }
1867 return rk3568_dclk_vop_get_clk(priv, clk_id);
1868}
1869
1870static ulong rk3568_gmac_src_get_clk(struct rk3568_clk_priv *priv,
1871 ulong mac_id)
1872{
1873 struct rk3568_cru *cru = priv->cru;
1874 u32 sel, con;
1875
1876 con = readl(&cru->clksel_con[31 + mac_id * 2]);
1877 sel = (con & CLK_MAC0_2TOP_SEL_MASK) >> CLK_MAC0_2TOP_SEL_SHIFT;
1878
1879 switch (sel) {
1880 case CLK_MAC0_2TOP_SEL_125M:
1881 return 125 * MHz;
1882 case CLK_MAC0_2TOP_SEL_50M:
1883 return 50 * MHz;
1884 case CLK_MAC0_2TOP_SEL_25M:
1885 return 25 * MHz;
1886 case CLK_MAC0_2TOP_SEL_PPLL:
1887 return rk3568_pmu_pll_get_rate(priv, HPLL);
1888 default:
1889 return -ENOENT;
1890 }
1891}
1892
1893static ulong rk3568_gmac_src_set_clk(struct rk3568_clk_priv *priv,
1894 ulong mac_id, ulong rate)
1895{
1896 struct rk3568_cru *cru = priv->cru;
1897 int src_clk;
1898
1899 switch (rate) {
1900 case 125 * MHz:
1901 src_clk = CLK_MAC0_2TOP_SEL_125M;
1902 break;
1903 case 50 * MHz:
1904 src_clk = CLK_MAC0_2TOP_SEL_50M;
1905 break;
1906 case 25 * MHz:
1907 src_clk = CLK_MAC0_2TOP_SEL_25M;
1908 break;
1909 default:
1910 return -ENOENT;
1911 }
1912
1913 rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2],
1914 CLK_MAC0_2TOP_SEL_MASK,
1915 src_clk << CLK_MAC0_2TOP_SEL_SHIFT);
1916
1917 return rk3568_gmac_src_get_clk(priv, mac_id);
1918}
1919
1920static ulong rk3568_gmac_out_get_clk(struct rk3568_clk_priv *priv,
1921 ulong mac_id)
1922{
1923 struct rk3568_cru *cru = priv->cru;
1924 u32 sel, con;
1925
1926 con = readl(&cru->clksel_con[31 + mac_id * 2]);
1927 sel = (con & CLK_MAC0_OUT_SEL_MASK) >> CLK_MAC0_OUT_SEL_SHIFT;
1928
1929 switch (sel) {
1930 case CLK_MAC0_OUT_SEL_125M:
1931 return 125 * MHz;
1932 case CLK_MAC0_OUT_SEL_50M:
1933 return 50 * MHz;
1934 case CLK_MAC0_OUT_SEL_25M:
1935 return 25 * MHz;
1936 case CLK_MAC0_OUT_SEL_24M:
1937 return OSC_HZ;
1938 default:
1939 return -ENOENT;
1940 }
1941}
1942
1943static ulong rk3568_gmac_out_set_clk(struct rk3568_clk_priv *priv,
1944 ulong mac_id, ulong rate)
1945{
1946 struct rk3568_cru *cru = priv->cru;
1947 int src_clk;
1948
1949 switch (rate) {
1950 case 125 * MHz:
1951 src_clk = CLK_MAC0_OUT_SEL_125M;
1952 break;
1953 case 50 * MHz:
1954 src_clk = CLK_MAC0_OUT_SEL_50M;
1955 break;
1956 case 25 * MHz:
1957 src_clk = CLK_MAC0_OUT_SEL_25M;
1958 break;
1959 case 24 * MHz:
1960 src_clk = CLK_MAC0_OUT_SEL_24M;
1961 break;
1962 default:
1963 return -ENOENT;
1964 }
1965
1966 rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2],
1967 CLK_MAC0_OUT_SEL_MASK,
1968 src_clk << CLK_MAC0_OUT_SEL_SHIFT);
1969
1970 return rk3568_gmac_out_get_clk(priv, mac_id);
1971}
1972
1973static ulong rk3568_gmac_ptp_ref_get_clk(struct rk3568_clk_priv *priv,
1974 ulong mac_id)
1975{
1976 struct rk3568_cru *cru = priv->cru;
1977 u32 sel, con;
1978
1979 con = readl(&cru->clksel_con[31 + mac_id * 2]);
1980 sel = (con & CLK_GMAC0_PTP_REF_SEL_MASK) >> CLK_GMAC0_PTP_REF_SEL_SHIFT;
1981
1982 switch (sel) {
1983 case CLK_GMAC0_PTP_REF_SEL_62_5M:
1984 return 62500 * KHz;
1985 case CLK_GMAC0_PTP_REF_SEL_100M:
1986 return 100 * MHz;
1987 case CLK_GMAC0_PTP_REF_SEL_50M:
1988 return 50 * MHz;
1989 case CLK_GMAC0_PTP_REF_SEL_24M:
1990 return OSC_HZ;
1991 default:
1992 return -ENOENT;
1993 }
1994}
1995
1996static ulong rk3568_gmac_ptp_ref_set_clk(struct rk3568_clk_priv *priv,
1997 ulong mac_id, ulong rate)
1998{
1999 struct rk3568_cru *cru = priv->cru;
2000 int src_clk;
2001
2002 switch (rate) {
2003 case 62500 * KHz:
2004 src_clk = CLK_GMAC0_PTP_REF_SEL_62_5M;
2005 break;
2006 case 100 * MHz:
2007 src_clk = CLK_GMAC0_PTP_REF_SEL_100M;
2008 break;
2009 case 50 * MHz:
2010 src_clk = CLK_GMAC0_PTP_REF_SEL_50M;
2011 break;
2012 case 24 * MHz:
2013 src_clk = CLK_GMAC0_PTP_REF_SEL_24M;
2014 break;
2015 default:
2016 return -ENOENT;
2017 }
2018
2019 rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2],
2020 CLK_GMAC0_PTP_REF_SEL_MASK,
2021 src_clk << CLK_GMAC0_PTP_REF_SEL_SHIFT);
2022
2023 return rk3568_gmac_ptp_ref_get_clk(priv, mac_id);
2024}
2025
2026static ulong rk3568_gmac_tx_rx_set_clk(struct rk3568_clk_priv *priv,
2027 ulong mac_id, ulong rate)
2028{
2029 struct rk3568_cru *cru = priv->cru;
2030 u32 con, sel, div_sel;
2031
2032 con = readl(&cru->clksel_con[31 + mac_id * 2]);
2033 sel = (con & RMII0_MODE_MASK) >> RMII0_MODE_SHIFT;
2034
2035 if (sel == RMII0_MODE_SEL_RGMII) {
2036 if (rate == 2500000)
2037 div_sel = RGMII0_CLK_SEL_2_5M;
2038 else if (rate == 25000000)
2039 div_sel = RGMII0_CLK_SEL_25M;
2040 else
2041 div_sel = RGMII0_CLK_SEL_125M;
2042 rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2],
2043 RGMII0_CLK_SEL_MASK,
2044 div_sel << RGMII0_CLK_SEL_SHIFT);
2045 } else if (sel == RMII0_MODE_SEL_RMII) {
2046 if (rate == 2500000)
2047 div_sel = RMII0_CLK_SEL_2_5M;
2048 else
2049 div_sel = RMII0_CLK_SEL_25M;
2050 rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2],
2051 RMII0_CLK_SEL_MASK,
2052 div_sel << RMII0_CLK_SEL_SHIFT);
2053 }
2054
2055 return 0;
2056}
2057
2058static ulong rk3568_ebc_get_clk(struct rk3568_clk_priv *priv)
2059{
2060 struct rk3568_cru *cru = priv->cru;
2061 u32 con, div, p_rate;
2062
2063 con = readl(&cru->clksel_con[79]);
2064 div = (con & CPLL_333M_DIV_MASK) >> CPLL_333M_DIV_SHIFT;
2065 p_rate = DIV_TO_RATE(priv->cpll_hz, div);
2066
2067 con = readl(&cru->clksel_con[43]);
2068 div = (con & DCLK_EBC_SEL_MASK) >> DCLK_EBC_SEL_SHIFT;
2069 switch (div) {
2070 case DCLK_EBC_SEL_GPLL_400M:
2071 return 400 * MHz;
2072 case DCLK_EBC_SEL_CPLL_333M:
2073 return p_rate;
2074 case DCLK_EBC_SEL_GPLL_200M:
2075 return 200 * MHz;
2076 default:
2077 return -ENOENT;
2078 }
2079}
2080
2081static ulong rk3568_ebc_set_clk(struct rk3568_clk_priv *priv, ulong rate)
2082{
2083 struct rk3568_cru *cru = priv->cru;
2084 int src_clk_div;
2085
2086 src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate);
2087 assert(src_clk_div - 1 <= 31);
2088 rk_clrsetreg(&cru->clksel_con[79],
2089 CPLL_333M_DIV_MASK,
2090 (src_clk_div - 1) << CPLL_333M_DIV_SHIFT);
2091 rk_clrsetreg(&cru->clksel_con[43],
2092 DCLK_EBC_SEL_MASK,
2093 DCLK_EBC_SEL_CPLL_333M << DCLK_EBC_SEL_SHIFT);
2094
2095 return rk3568_ebc_get_clk(priv);
2096}
2097
2098static ulong rk3568_rkvdec_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
2099{
2100 struct rk3568_cru *cru = priv->cru;
2101 u32 con, div, src, p_rate;
2102
2103 switch (clk_id) {
2104 case ACLK_RKVDEC_PRE:
2105 case ACLK_RKVDEC:
2106 con = readl(&cru->clksel_con[47]);
2107 src = (con & ACLK_RKVDEC_SEL_MASK) >> ACLK_RKVDEC_SEL_SHIFT;
2108 div = (con & ACLK_RKVDEC_DIV_MASK) >> ACLK_RKVDEC_DIV_SHIFT;
2109 if (src == ACLK_RKVDEC_SEL_CPLL)
2110 p_rate = priv->cpll_hz;
2111 else
2112 p_rate = priv->gpll_hz;
2113 return DIV_TO_RATE(p_rate, div);
2114 case CLK_RKVDEC_CORE:
2115 con = readl(&cru->clksel_con[49]);
2116 src = (con & CLK_RKVDEC_CORE_SEL_MASK)
2117 >> CLK_RKVDEC_CORE_SEL_SHIFT;
2118 div = (con & CLK_RKVDEC_CORE_DIV_MASK)
2119 >> CLK_RKVDEC_CORE_DIV_SHIFT;
2120 if (src == CLK_RKVDEC_CORE_SEL_CPLL)
2121 p_rate = priv->cpll_hz;
2122 else if (src == CLK_RKVDEC_CORE_SEL_NPLL)
2123 p_rate = priv->npll_hz;
2124 else if (src == CLK_RKVDEC_CORE_SEL_VPLL)
2125 p_rate = priv->vpll_hz;
2126 else
2127 p_rate = priv->gpll_hz;
2128 return DIV_TO_RATE(p_rate, div);
2129 default:
2130 return -ENOENT;
2131 }
2132}
2133
2134static ulong rk3568_rkvdec_set_clk(struct rk3568_clk_priv *priv,
2135 ulong clk_id, ulong rate)
2136{
2137 struct rk3568_cru *cru = priv->cru;
2138 int src_clk_div, src, p_rate;
2139
2140 switch (clk_id) {
2141 case ACLK_RKVDEC_PRE:
2142 case ACLK_RKVDEC:
2143 src = (readl(&cru->clksel_con[47]) & ACLK_RKVDEC_SEL_MASK)
2144 >> ACLK_RKVDEC_SEL_SHIFT;
2145 if (src == ACLK_RKVDEC_SEL_CPLL)
2146 p_rate = priv->cpll_hz;
2147 else
2148 p_rate = priv->gpll_hz;
2149 src_clk_div = DIV_ROUND_UP(p_rate, rate);
2150 assert(src_clk_div - 1 <= 31);
2151 rk_clrsetreg(&cru->clksel_con[47],
2152 ACLK_RKVDEC_SEL_MASK |
2153 ACLK_RKVDEC_DIV_MASK,
2154 (src << ACLK_RKVDEC_SEL_SHIFT) |
2155 (src_clk_div - 1) << ACLK_RKVDEC_DIV_SHIFT);
2156 break;
2157 case CLK_RKVDEC_CORE:
2158 src = (readl(&cru->clksel_con[49]) & CLK_RKVDEC_CORE_SEL_MASK)
2159 >> CLK_RKVDEC_CORE_SEL_SHIFT;
2160 if (src == CLK_RKVDEC_CORE_SEL_CPLL)
2161 p_rate = priv->cpll_hz;
2162 else if (src == CLK_RKVDEC_CORE_SEL_NPLL)
2163 p_rate = priv->npll_hz;
2164 else if (src == CLK_RKVDEC_CORE_SEL_VPLL)
2165 p_rate = priv->vpll_hz;
2166 else
2167 p_rate = priv->gpll_hz;
2168 src_clk_div = DIV_ROUND_UP(p_rate, rate);
2169 assert(src_clk_div - 1 <= 31);
2170 rk_clrsetreg(&cru->clksel_con[49],
2171 CLK_RKVDEC_CORE_SEL_MASK |
2172 CLK_RKVDEC_CORE_DIV_MASK,
2173 (src << CLK_RKVDEC_CORE_SEL_SHIFT) |
2174 (src_clk_div - 1) << CLK_RKVDEC_CORE_DIV_SHIFT);
2175 break;
2176 default:
2177 return -ENOENT;
2178 }
2179
2180 return rk3568_rkvdec_get_clk(priv, clk_id);
2181}
Jonas Karlman381848a2023-08-04 09:33:59 +00002182#endif
Elaine Zhang5be90bb2021-06-02 11:39:24 +08002183
2184static ulong rk3568_uart_get_rate(struct rk3568_clk_priv *priv, ulong clk_id)
2185{
2186 struct rk3568_cru *cru = priv->cru;
2187 u32 reg, con, fracdiv, div, src, p_src, p_rate;
2188 unsigned long m, n;
2189
2190 switch (clk_id) {
2191 case SCLK_UART1:
2192 reg = 52;
2193 break;
2194 case SCLK_UART2:
2195 reg = 54;
2196 break;
2197 case SCLK_UART3:
2198 reg = 56;
2199 break;
2200 case SCLK_UART4:
2201 reg = 58;
2202 break;
2203 case SCLK_UART5:
2204 reg = 60;
2205 break;
2206 case SCLK_UART6:
2207 reg = 62;
2208 break;
2209 case SCLK_UART7:
2210 reg = 64;
2211 break;
2212 case SCLK_UART8:
2213 reg = 66;
2214 break;
2215 case SCLK_UART9:
2216 reg = 68;
2217 break;
2218 default:
2219 return -ENOENT;
2220 }
2221 con = readl(&cru->clksel_con[reg]);
2222 src = (con & CLK_UART_SEL_MASK) >> CLK_UART_SEL_SHIFT;
2223 div = (con & CLK_UART_SRC_DIV_MASK) >> CLK_UART_SRC_DIV_SHIFT;
2224 p_src = (con & CLK_UART_SRC_SEL_MASK) >> CLK_UART_SRC_SEL_SHIFT;
2225 if (p_src == CLK_UART_SRC_SEL_GPLL)
2226 p_rate = priv->gpll_hz;
2227 else if (p_src == CLK_UART_SRC_SEL_CPLL)
2228 p_rate = priv->cpll_hz;
2229 else
2230 p_rate = 480000000;
2231 if (src == CLK_UART_SEL_SRC) {
2232 return DIV_TO_RATE(p_rate, div);
2233 } else if (src == CLK_UART_SEL_FRAC) {
2234 fracdiv = readl(&cru->clksel_con[reg + 1]);
2235 n = fracdiv & CLK_UART_FRAC_NUMERATOR_MASK;
2236 n >>= CLK_UART_FRAC_NUMERATOR_SHIFT;
2237 m = fracdiv & CLK_UART_FRAC_DENOMINATOR_MASK;
2238 m >>= CLK_UART_FRAC_DENOMINATOR_SHIFT;
2239 return DIV_TO_RATE(p_rate, div) * n / m;
2240 } else {
2241 return OSC_HZ;
2242 }
2243}
2244
2245static ulong rk3568_uart_set_rate(struct rk3568_clk_priv *priv,
2246 ulong clk_id, ulong rate)
2247{
2248 struct rk3568_cru *cru = priv->cru;
2249 u32 reg, clk_src, uart_src, div;
2250 unsigned long m = 0, n = 0, val;
2251
2252 if (priv->gpll_hz % rate == 0) {
2253 clk_src = CLK_UART_SRC_SEL_GPLL;
2254 uart_src = CLK_UART_SEL_SRC;
2255 div = DIV_ROUND_UP(priv->gpll_hz, rate);
2256 } else if (priv->cpll_hz % rate == 0) {
2257 clk_src = CLK_UART_SRC_SEL_CPLL;
2258 uart_src = CLK_UART_SEL_SRC;
2259 div = DIV_ROUND_UP(priv->gpll_hz, rate);
2260 } else if (rate == OSC_HZ) {
2261 clk_src = CLK_UART_SRC_SEL_GPLL;
2262 uart_src = CLK_UART_SEL_XIN24M;
2263 div = 2;
2264 } else {
2265 clk_src = CLK_UART_SRC_SEL_GPLL;
2266 uart_src = CLK_UART_SEL_FRAC;
2267 div = 2;
2268 rational_best_approximation(rate, priv->gpll_hz / div,
2269 GENMASK(16 - 1, 0),
2270 GENMASK(16 - 1, 0),
2271 &m, &n);
2272 }
2273
2274 switch (clk_id) {
2275 case SCLK_UART1:
2276 reg = 52;
2277 break;
2278 case SCLK_UART2:
2279 reg = 54;
2280 break;
2281 case SCLK_UART3:
2282 reg = 56;
2283 break;
2284 case SCLK_UART4:
2285 reg = 58;
2286 break;
2287 case SCLK_UART5:
2288 reg = 60;
2289 break;
2290 case SCLK_UART6:
2291 reg = 62;
2292 break;
2293 case SCLK_UART7:
2294 reg = 64;
2295 break;
2296 case SCLK_UART8:
2297 reg = 66;
2298 break;
2299 case SCLK_UART9:
2300 reg = 68;
2301 break;
2302 default:
2303 return -ENOENT;
2304 }
2305 rk_clrsetreg(&cru->clksel_con[reg],
2306 CLK_UART_SEL_MASK | CLK_UART_SRC_SEL_MASK |
2307 CLK_UART_SRC_DIV_MASK,
2308 (clk_src << CLK_UART_SRC_SEL_SHIFT) |
2309 (uart_src << CLK_UART_SEL_SHIFT) |
2310 ((div - 1) << CLK_UART_SRC_DIV_SHIFT));
2311 if (m && n) {
2312 val = m << CLK_UART_FRAC_NUMERATOR_SHIFT | n;
2313 writel(val, &cru->clksel_con[reg + 1]);
2314 }
2315
2316 return rk3568_uart_get_rate(priv, clk_id);
2317}
Elaine Zhang5be90bb2021-06-02 11:39:24 +08002318
2319static ulong rk3568_clk_get_rate(struct clk *clk)
2320{
2321 struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2322 ulong rate = 0;
2323
2324 if (!priv->gpll_hz) {
2325 printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
2326 return -ENOENT;
2327 }
2328
2329 switch (clk->id) {
2330 case PLL_APLL:
2331 case ARMCLK:
2332 rate = rockchip_pll_get_rate(&rk3568_pll_clks[APLL], priv->cru,
2333 APLL);
2334 break;
2335 case PLL_CPLL:
2336 rate = rockchip_pll_get_rate(&rk3568_pll_clks[CPLL], priv->cru,
2337 CPLL);
2338 break;
2339 case PLL_GPLL:
2340 rate = rockchip_pll_get_rate(&rk3568_pll_clks[GPLL], priv->cru,
2341 GPLL);
2342 break;
2343 case PLL_NPLL:
2344 rate = rockchip_pll_get_rate(&rk3568_pll_clks[NPLL], priv->cru,
2345 NPLL);
2346 break;
2347 case PLL_VPLL:
2348 rate = rockchip_pll_get_rate(&rk3568_pll_clks[VPLL], priv->cru,
2349 VPLL);
2350 break;
2351 case PLL_DPLL:
2352 rate = rockchip_pll_get_rate(&rk3568_pll_clks[DPLL], priv->cru,
2353 DPLL);
2354 break;
2355 case ACLK_BUS:
2356 case PCLK_BUS:
2357 case PCLK_WDT_NS:
2358 rate = rk3568_bus_get_clk(priv, clk->id);
2359 break;
2360 case ACLK_PERIMID:
2361 case HCLK_PERIMID:
2362 rate = rk3568_perimid_get_clk(priv, clk->id);
2363 break;
2364 case ACLK_TOP_HIGH:
2365 case ACLK_TOP_LOW:
2366 case HCLK_TOP:
2367 case PCLK_TOP:
2368 rate = rk3568_top_get_clk(priv, clk->id);
2369 break;
2370 case CLK_I2C1:
2371 case CLK_I2C2:
2372 case CLK_I2C3:
2373 case CLK_I2C4:
2374 case CLK_I2C5:
2375 rate = rk3568_i2c_get_clk(priv, clk->id);
2376 break;
2377 case CLK_SPI0:
2378 case CLK_SPI1:
2379 case CLK_SPI2:
2380 case CLK_SPI3:
2381 rate = rk3568_spi_get_clk(priv, clk->id);
2382 break;
2383 case CLK_PWM1:
2384 case CLK_PWM2:
2385 case CLK_PWM3:
2386 rate = rk3568_pwm_get_clk(priv, clk->id);
2387 break;
2388 case CLK_SARADC:
2389 case CLK_TSADC_TSEN:
2390 case CLK_TSADC:
2391 rate = rk3568_adc_get_clk(priv, clk->id);
2392 break;
2393 case HCLK_SDMMC0:
2394 case CLK_SDMMC0:
2395 case CLK_SDMMC1:
2396 case CLK_SDMMC2:
2397 rate = rk3568_sdmmc_get_clk(priv, clk->id);
2398 break;
2399 case SCLK_SFC:
2400 rate = rk3568_sfc_get_clk(priv);
2401 break;
2402 case NCLK_NANDC:
2403 rate = rk3568_nand_get_clk(priv);
2404 break;
2405 case CCLK_EMMC:
2406 rate = rk3568_emmc_get_clk(priv);
2407 break;
2408 case BCLK_EMMC:
2409 rate = rk3568_emmc_get_bclk(priv);
2410 break;
Jonas Karlman8d54b5c2024-04-22 06:28:38 +00002411 case CLK_USB3OTG0_REF:
2412 case CLK_USB3OTG1_REF:
Elaine Zhang7b9b9262021-10-12 16:43:00 +08002413 case TCLK_EMMC:
2414 rate = OSC_HZ;
2415 break;
Simon Glass7ec24132024-09-29 19:49:48 -06002416#ifndef CONFIG_XPL_BUILD
Elaine Zhang5be90bb2021-06-02 11:39:24 +08002417 case ACLK_VOP:
2418 rate = rk3568_aclk_vop_get_clk(priv);
2419 break;
2420 case DCLK_VOP0:
2421 case DCLK_VOP1:
2422 case DCLK_VOP2:
2423 rate = rk3568_dclk_vop_get_clk(priv, clk->id);
2424 break;
2425 case SCLK_GMAC0:
2426 case CLK_MAC0_2TOP:
2427 case CLK_MAC0_REFOUT:
2428 rate = rk3568_gmac_src_get_clk(priv, 0);
2429 break;
2430 case CLK_MAC0_OUT:
2431 rate = rk3568_gmac_out_get_clk(priv, 0);
2432 break;
2433 case CLK_GMAC0_PTP_REF:
2434 rate = rk3568_gmac_ptp_ref_get_clk(priv, 0);
2435 break;
2436 case SCLK_GMAC1:
2437 case CLK_MAC1_2TOP:
2438 case CLK_MAC1_REFOUT:
2439 rate = rk3568_gmac_src_get_clk(priv, 1);
2440 break;
2441 case CLK_MAC1_OUT:
2442 rate = rk3568_gmac_out_get_clk(priv, 1);
2443 break;
2444 case CLK_GMAC1_PTP_REF:
2445 rate = rk3568_gmac_ptp_ref_get_clk(priv, 1);
2446 break;
2447 case DCLK_EBC:
2448 rate = rk3568_ebc_get_clk(priv);
2449 break;
2450 case ACLK_RKVDEC_PRE:
2451 case ACLK_RKVDEC:
2452 case CLK_RKVDEC_CORE:
2453 rate = rk3568_rkvdec_get_clk(priv, clk->id);
2454 break;
2455 case TCLK_WDT_NS:
2456 rate = OSC_HZ;
2457 break;
Jonas Karlman381848a2023-08-04 09:33:59 +00002458#endif
Elaine Zhang5be90bb2021-06-02 11:39:24 +08002459 case SCLK_UART1:
2460 case SCLK_UART2:
2461 case SCLK_UART3:
2462 case SCLK_UART4:
2463 case SCLK_UART5:
2464 case SCLK_UART6:
2465 case SCLK_UART7:
2466 case SCLK_UART8:
2467 case SCLK_UART9:
2468 rate = rk3568_uart_get_rate(priv, clk->id);
2469 break;
Elaine Zhang5be90bb2021-06-02 11:39:24 +08002470 case ACLK_SECURE_FLASH:
2471 case ACLK_CRYPTO_NS:
2472 case HCLK_SECURE_FLASH:
2473 case HCLK_CRYPTO_NS:
2474 case CLK_CRYPTO_NS_RNG:
2475 case CLK_CRYPTO_NS_CORE:
2476 case CLK_CRYPTO_NS_PKA:
2477 rate = rk3568_crypto_get_rate(priv, clk->id);
2478 break;
2479 case CPLL_500M:
2480 case CPLL_333M:
2481 case CPLL_250M:
2482 case CPLL_125M:
2483 case CPLL_100M:
2484 case CPLL_62P5M:
2485 case CPLL_50M:
2486 case CPLL_25M:
2487 rate = rk3568_cpll_div_get_rate(priv, clk->id);
2488 break;
2489 default:
2490 return -ENOENT;
2491 }
2492
2493 return rate;
2494};
2495
2496static ulong rk3568_clk_set_rate(struct clk *clk, ulong rate)
2497{
2498 struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2499 ulong ret = 0;
2500
2501 if (!priv->gpll_hz) {
2502 printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
2503 return -ENOENT;
2504 }
2505
2506 switch (clk->id) {
2507 case PLL_APLL:
2508 case ARMCLK:
2509 if (priv->armclk_hz)
2510 rk3568_armclk_set_clk(priv, rate);
2511 priv->armclk_hz = rate;
2512 break;
2513 case PLL_CPLL:
2514 ret = rockchip_pll_set_rate(&rk3568_pll_clks[CPLL], priv->cru,
2515 CPLL, rate);
2516 priv->cpll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[CPLL],
2517 priv->cru, CPLL);
2518 break;
2519 case PLL_GPLL:
2520 ret = rockchip_pll_set_rate(&rk3568_pll_clks[GPLL], priv->cru,
2521 GPLL, rate);
2522 priv->gpll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[GPLL],
2523 priv->cru, GPLL);
2524 break;
2525 case PLL_NPLL:
2526 ret = rockchip_pll_set_rate(&rk3568_pll_clks[NPLL], priv->cru,
2527 NPLL, rate);
2528 break;
2529 case PLL_VPLL:
2530 ret = rockchip_pll_set_rate(&rk3568_pll_clks[VPLL], priv->cru,
2531 VPLL, rate);
2532 priv->vpll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[VPLL],
2533 priv->cru,
2534 VPLL);
2535 break;
2536 case ACLK_BUS:
2537 case PCLK_BUS:
2538 case PCLK_WDT_NS:
2539 ret = rk3568_bus_set_clk(priv, clk->id, rate);
2540 break;
2541 case ACLK_PERIMID:
2542 case HCLK_PERIMID:
2543 ret = rk3568_perimid_set_clk(priv, clk->id, rate);
2544 break;
2545 case ACLK_TOP_HIGH:
2546 case ACLK_TOP_LOW:
2547 case HCLK_TOP:
2548 case PCLK_TOP:
2549 ret = rk3568_top_set_clk(priv, clk->id, rate);
2550 break;
2551 case CLK_I2C1:
2552 case CLK_I2C2:
2553 case CLK_I2C3:
2554 case CLK_I2C4:
2555 case CLK_I2C5:
2556 ret = rk3568_i2c_set_clk(priv, clk->id, rate);
2557 break;
2558 case CLK_SPI0:
2559 case CLK_SPI1:
2560 case CLK_SPI2:
2561 case CLK_SPI3:
2562 ret = rk3568_spi_set_clk(priv, clk->id, rate);
2563 break;
2564 case CLK_PWM1:
2565 case CLK_PWM2:
2566 case CLK_PWM3:
2567 ret = rk3568_pwm_set_clk(priv, clk->id, rate);
2568 break;
2569 case CLK_SARADC:
2570 case CLK_TSADC_TSEN:
2571 case CLK_TSADC:
2572 ret = rk3568_adc_set_clk(priv, clk->id, rate);
2573 break;
2574 case HCLK_SDMMC0:
2575 case CLK_SDMMC0:
2576 case CLK_SDMMC1:
2577 case CLK_SDMMC2:
2578 ret = rk3568_sdmmc_set_clk(priv, clk->id, rate);
2579 break;
2580 case SCLK_SFC:
2581 ret = rk3568_sfc_set_clk(priv, rate);
2582 break;
2583 case NCLK_NANDC:
2584 ret = rk3568_nand_set_clk(priv, rate);
2585 break;
2586 case CCLK_EMMC:
2587 ret = rk3568_emmc_set_clk(priv, rate);
2588 break;
2589 case BCLK_EMMC:
2590 ret = rk3568_emmc_set_bclk(priv, rate);
2591 break;
Jonas Karlman8d54b5c2024-04-22 06:28:38 +00002592 case CLK_USB3OTG0_REF:
2593 case CLK_USB3OTG1_REF:
Elaine Zhang7b9b9262021-10-12 16:43:00 +08002594 case TCLK_EMMC:
2595 ret = OSC_HZ;
2596 break;
Simon Glass7ec24132024-09-29 19:49:48 -06002597#ifndef CONFIG_XPL_BUILD
Elaine Zhang5be90bb2021-06-02 11:39:24 +08002598 case ACLK_VOP:
2599 ret = rk3568_aclk_vop_set_clk(priv, rate);
2600 break;
2601 case DCLK_VOP0:
2602 case DCLK_VOP1:
2603 case DCLK_VOP2:
2604 ret = rk3568_dclk_vop_set_clk(priv, clk->id, rate);
2605 break;
2606 case SCLK_GMAC0:
2607 case CLK_MAC0_2TOP:
2608 case CLK_MAC0_REFOUT:
2609 ret = rk3568_gmac_src_set_clk(priv, 0, rate);
2610 break;
2611 case CLK_MAC0_OUT:
2612 ret = rk3568_gmac_out_set_clk(priv, 0, rate);
2613 break;
2614 case SCLK_GMAC0_RX_TX:
2615 ret = rk3568_gmac_tx_rx_set_clk(priv, 0, rate);
2616 break;
2617 case CLK_GMAC0_PTP_REF:
2618 ret = rk3568_gmac_ptp_ref_set_clk(priv, 0, rate);
2619 break;
2620 case SCLK_GMAC1:
2621 case CLK_MAC1_2TOP:
2622 case CLK_MAC1_REFOUT:
2623 ret = rk3568_gmac_src_set_clk(priv, 1, rate);
2624 break;
2625 case CLK_MAC1_OUT:
2626 ret = rk3568_gmac_out_set_clk(priv, 1, rate);
2627 break;
2628 case SCLK_GMAC1_RX_TX:
2629 ret = rk3568_gmac_tx_rx_set_clk(priv, 1, rate);
2630 break;
2631 case CLK_GMAC1_PTP_REF:
2632 ret = rk3568_gmac_ptp_ref_set_clk(priv, 1, rate);
2633 break;
2634 case DCLK_EBC:
2635 ret = rk3568_ebc_set_clk(priv, rate);
2636 break;
2637 case ACLK_RKVDEC_PRE:
2638 case ACLK_RKVDEC:
2639 case CLK_RKVDEC_CORE:
2640 ret = rk3568_rkvdec_set_clk(priv, clk->id, rate);
2641 break;
2642 case TCLK_WDT_NS:
2643 ret = OSC_HZ;
2644 break;
Jonas Karlman381848a2023-08-04 09:33:59 +00002645#endif
Elaine Zhang5be90bb2021-06-02 11:39:24 +08002646 case SCLK_UART1:
2647 case SCLK_UART2:
2648 case SCLK_UART3:
2649 case SCLK_UART4:
2650 case SCLK_UART5:
2651 case SCLK_UART6:
2652 case SCLK_UART7:
2653 case SCLK_UART8:
2654 case SCLK_UART9:
2655 ret = rk3568_uart_set_rate(priv, clk->id, rate);
2656 break;
Elaine Zhang5be90bb2021-06-02 11:39:24 +08002657 case ACLK_SECURE_FLASH:
2658 case ACLK_CRYPTO_NS:
2659 case HCLK_SECURE_FLASH:
2660 case HCLK_CRYPTO_NS:
2661 case CLK_CRYPTO_NS_RNG:
2662 case CLK_CRYPTO_NS_CORE:
2663 case CLK_CRYPTO_NS_PKA:
2664 ret = rk3568_crypto_set_rate(priv, clk->id, rate);
2665 break;
2666 case CPLL_500M:
2667 case CPLL_333M:
2668 case CPLL_250M:
2669 case CPLL_125M:
2670 case CPLL_100M:
2671 case CPLL_62P5M:
2672 case CPLL_50M:
2673 case CPLL_25M:
2674 ret = rk3568_cpll_div_set_rate(priv, clk->id, rate);
2675 break;
2676 default:
2677 return -ENOENT;
2678 }
2679
2680 return ret;
2681};
2682
2683#if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA))
2684static int rk3568_gmac0_src_set_parent(struct clk *clk, struct clk *parent)
2685{
2686 struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2687 struct rk3568_cru *cru = priv->cru;
2688
2689 if (parent->id == CLK_MAC0_2TOP)
2690 rk_clrsetreg(&cru->clksel_con[31],
2691 RMII0_EXTCLK_SEL_MASK,
2692 RMII0_EXTCLK_SEL_MAC0_TOP <<
2693 RMII0_EXTCLK_SEL_SHIFT);
2694 else
2695 rk_clrsetreg(&cru->clksel_con[31],
2696 RMII0_EXTCLK_SEL_MASK,
2697 RMII0_EXTCLK_SEL_IO << RMII0_EXTCLK_SEL_SHIFT);
2698 return 0;
2699}
2700
2701static int rk3568_gmac1_src_set_parent(struct clk *clk, struct clk *parent)
2702{
2703 struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2704 struct rk3568_cru *cru = priv->cru;
2705
2706 if (parent->id == CLK_MAC1_2TOP)
2707 rk_clrsetreg(&cru->clksel_con[33],
2708 RMII0_EXTCLK_SEL_MASK,
2709 RMII0_EXTCLK_SEL_MAC0_TOP <<
2710 RMII0_EXTCLK_SEL_SHIFT);
2711 else
2712 rk_clrsetreg(&cru->clksel_con[33],
2713 RMII0_EXTCLK_SEL_MASK,
2714 RMII0_EXTCLK_SEL_IO << RMII0_EXTCLK_SEL_SHIFT);
2715 return 0;
2716}
2717
2718static int rk3568_gmac0_tx_rx_set_parent(struct clk *clk, struct clk *parent)
2719{
2720 struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2721 struct rk3568_cru *cru = priv->cru;
2722
2723 if (parent->id == SCLK_GMAC0_RGMII_SPEED)
2724 rk_clrsetreg(&cru->clksel_con[31],
2725 RMII0_MODE_MASK,
2726 RMII0_MODE_SEL_RGMII << RMII0_MODE_SHIFT);
2727 else if (parent->id == SCLK_GMAC0_RMII_SPEED)
2728 rk_clrsetreg(&cru->clksel_con[31],
2729 RMII0_MODE_MASK,
2730 RMII0_MODE_SEL_RMII << RMII0_MODE_SHIFT);
2731 else
2732 rk_clrsetreg(&cru->clksel_con[31],
2733 RMII0_MODE_MASK,
2734 RMII0_MODE_SEL_GMII << RMII0_MODE_SHIFT);
2735
2736 return 0;
2737}
2738
2739static int rk3568_gmac1_tx_rx_set_parent(struct clk *clk, struct clk *parent)
2740{
2741 struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2742 struct rk3568_cru *cru = priv->cru;
2743
2744 if (parent->id == SCLK_GMAC1_RGMII_SPEED)
2745 rk_clrsetreg(&cru->clksel_con[33],
2746 RMII0_MODE_MASK,
2747 RMII0_MODE_SEL_RGMII << RMII0_MODE_SHIFT);
2748 else if (parent->id == SCLK_GMAC1_RMII_SPEED)
2749 rk_clrsetreg(&cru->clksel_con[33],
2750 RMII0_MODE_MASK,
2751 RMII0_MODE_SEL_RMII << RMII0_MODE_SHIFT);
2752 else
2753 rk_clrsetreg(&cru->clksel_con[33],
2754 RMII0_MODE_MASK,
2755 RMII0_MODE_SEL_GMII << RMII0_MODE_SHIFT);
2756
2757 return 0;
2758}
2759
2760static int rk3568_dclk_vop_set_parent(struct clk *clk, struct clk *parent)
2761{
2762 struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2763 struct rk3568_cru *cru = priv->cru;
2764 u32 con_id;
2765
2766 switch (clk->id) {
2767 case DCLK_VOP0:
2768 con_id = 39;
2769 break;
2770 case DCLK_VOP1:
2771 con_id = 40;
2772 break;
2773 case DCLK_VOP2:
2774 con_id = 41;
2775 break;
2776 default:
2777 return -EINVAL;
2778 }
2779 if (parent->id == PLL_VPLL) {
2780 rk_clrsetreg(&cru->clksel_con[con_id], DCLK0_VOP_SEL_MASK,
2781 DCLK_VOP_SEL_VPLL << DCLK0_VOP_SEL_SHIFT);
Elaine Zhangf12a1602023-10-11 18:29:43 +08002782 } else if (parent->id == PLL_HPLL) {
Elaine Zhang5be90bb2021-06-02 11:39:24 +08002783 rk_clrsetreg(&cru->clksel_con[con_id], DCLK0_VOP_SEL_MASK,
2784 DCLK_VOP_SEL_HPLL << DCLK0_VOP_SEL_SHIFT);
Elaine Zhangf12a1602023-10-11 18:29:43 +08002785 } else if (parent->id == PLL_CPLL) {
2786 rk_clrsetreg(&cru->clksel_con[con_id], DCLK0_VOP_SEL_MASK,
2787 DCLK_VOP_SEL_CPLL << DCLK0_VOP_SEL_SHIFT);
2788 } else {
2789 rk_clrsetreg(&cru->clksel_con[con_id], DCLK0_VOP_SEL_MASK,
2790 DCLK_VOP_SEL_GPLL << DCLK0_VOP_SEL_SHIFT);
Elaine Zhang5be90bb2021-06-02 11:39:24 +08002791 }
2792
2793 return 0;
2794}
2795
2796static int rk3568_rkvdec_set_parent(struct clk *clk, struct clk *parent)
2797{
2798 struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2799 struct rk3568_cru *cru = priv->cru;
2800 u32 con_id, mask, shift;
2801
2802 switch (clk->id) {
2803 case ACLK_RKVDEC_PRE:
2804 con_id = 47;
2805 mask = ACLK_RKVDEC_SEL_MASK;
2806 shift = ACLK_RKVDEC_SEL_SHIFT;
2807 break;
2808 case CLK_RKVDEC_CORE:
2809 con_id = 49;
2810 mask = CLK_RKVDEC_CORE_SEL_MASK;
2811 shift = CLK_RKVDEC_CORE_SEL_SHIFT;
2812 break;
2813 default:
2814 return -EINVAL;
2815 }
2816 if (parent->id == PLL_CPLL) {
2817 rk_clrsetreg(&cru->clksel_con[con_id], mask,
2818 ACLK_RKVDEC_SEL_CPLL << shift);
2819 } else {
2820 rk_clrsetreg(&cru->clksel_con[con_id], mask,
2821 ACLK_RKVDEC_SEL_GPLL << shift);
2822 }
2823
2824 return 0;
2825}
2826
2827static int rk3568_clk_set_parent(struct clk *clk, struct clk *parent)
2828{
2829 switch (clk->id) {
2830 case SCLK_GMAC0:
2831 return rk3568_gmac0_src_set_parent(clk, parent);
2832 case SCLK_GMAC1:
2833 return rk3568_gmac1_src_set_parent(clk, parent);
2834 case SCLK_GMAC0_RX_TX:
2835 return rk3568_gmac0_tx_rx_set_parent(clk, parent);
2836 case SCLK_GMAC1_RX_TX:
2837 return rk3568_gmac1_tx_rx_set_parent(clk, parent);
2838 case DCLK_VOP0:
2839 case DCLK_VOP1:
2840 case DCLK_VOP2:
2841 return rk3568_dclk_vop_set_parent(clk, parent);
2842 case ACLK_RKVDEC_PRE:
2843 case CLK_RKVDEC_CORE:
2844 return rk3568_rkvdec_set_parent(clk, parent);
Jonas Karlman1f7e8ff2023-04-17 19:07:25 +00002845 case I2S1_MCLKOUT_TX:
Jonas Karlman146150c2023-08-04 09:34:00 +00002846 case SCLK_GMAC0_RGMII_SPEED:
2847 case SCLK_GMAC0_RMII_SPEED:
2848 case SCLK_GMAC1_RGMII_SPEED:
2849 case SCLK_GMAC1_RMII_SPEED:
Jonas Karlman1f7e8ff2023-04-17 19:07:25 +00002850 break;
Elaine Zhang5be90bb2021-06-02 11:39:24 +08002851 default:
2852 return -ENOENT;
2853 }
2854
2855 return 0;
2856}
2857#endif
2858
2859static struct clk_ops rk3568_clk_ops = {
2860 .get_rate = rk3568_clk_get_rate,
2861 .set_rate = rk3568_clk_set_rate,
2862#if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA))
2863 .set_parent = rk3568_clk_set_parent,
2864#endif
2865};
2866
2867static void rk3568_clk_init(struct rk3568_clk_priv *priv)
2868{
2869 int ret;
2870
2871 priv->sync_kernel = false;
2872 if (!priv->armclk_enter_hz) {
2873 priv->armclk_enter_hz =
2874 rockchip_pll_get_rate(&rk3568_pll_clks[APLL],
2875 priv->cru, APLL);
2876 priv->armclk_init_hz = priv->armclk_enter_hz;
2877 }
2878
2879 if (priv->armclk_init_hz != APLL_HZ) {
2880 ret = rk3568_armclk_set_clk(priv, APLL_HZ);
2881 if (!ret)
2882 priv->armclk_init_hz = APLL_HZ;
2883 }
2884 if (priv->cpll_hz != CPLL_HZ) {
2885 ret = rockchip_pll_set_rate(&rk3568_pll_clks[CPLL], priv->cru,
2886 CPLL, CPLL_HZ);
2887 if (!ret)
2888 priv->cpll_hz = CPLL_HZ;
2889 }
2890 if (priv->gpll_hz != GPLL_HZ) {
2891 ret = rockchip_pll_set_rate(&rk3568_pll_clks[GPLL], priv->cru,
2892 GPLL, GPLL_HZ);
2893 if (!ret)
2894 priv->gpll_hz = GPLL_HZ;
2895 }
2896
Simon Glass7ec24132024-09-29 19:49:48 -06002897#ifdef CONFIG_XPL_BUILD
Elaine Zhang5be90bb2021-06-02 11:39:24 +08002898 ret = rk3568_bus_set_clk(priv, ACLK_BUS, 150000000);
2899 if (ret < 0)
2900 printf("Fail to set the ACLK_BUS clock.\n");
2901#endif
2902
2903 priv->ppll_hz = rk3568_pmu_pll_get_rate(priv, PPLL);
2904 priv->hpll_hz = rk3568_pmu_pll_get_rate(priv, HPLL);
2905}
2906
2907static int rk3568_clk_probe(struct udevice *dev)
2908{
2909 struct rk3568_clk_priv *priv = dev_get_priv(dev);
2910 int ret;
2911
2912 priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
2913 if (IS_ERR(priv->grf))
2914 return PTR_ERR(priv->grf);
2915
2916 rk3568_clk_init(priv);
2917
2918 /* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
2919 ret = clk_set_defaults(dev, 1);
2920 if (ret)
2921 debug("%s clk_set_defaults failed %d\n", __func__, ret);
2922 else
2923 priv->sync_kernel = true;
2924
2925 return 0;
2926}
2927
2928static int rk3568_clk_ofdata_to_platdata(struct udevice *dev)
2929{
2930 struct rk3568_clk_priv *priv = dev_get_priv(dev);
2931
2932 priv->cru = dev_read_addr_ptr(dev);
2933
2934 return 0;
2935}
2936
2937static int rk3568_clk_bind(struct udevice *dev)
2938{
2939 int ret;
2940 struct udevice *sys_child;
2941 struct sysreset_reg *priv;
2942
2943 /* The reset driver does not have a device node, so bind it here */
2944 ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
2945 &sys_child);
2946 if (ret) {
2947 debug("Warning: No sysreset driver: ret=%d\n", ret);
2948 } else {
2949 priv = malloc(sizeof(struct sysreset_reg));
2950 priv->glb_srst_fst_value = offsetof(struct rk3568_cru,
2951 glb_srst_fst);
2952 priv->glb_srst_snd_value = offsetof(struct rk3568_cru,
2953 glb_srsr_snd);
Peter Geis393cdce2023-03-14 00:38:26 +00002954 dev_set_priv(sys_child, priv);
Elaine Zhang5be90bb2021-06-02 11:39:24 +08002955 }
2956
2957#if CONFIG_IS_ENABLED(RESET_ROCKCHIP)
2958 ret = offsetof(struct rk3568_cru, softrst_con[0]);
2959 ret = rockchip_reset_bind(dev, ret, 30);
2960 if (ret)
Eugen Hristevf1798262023-04-11 10:17:56 +03002961 debug("Warning: software reset driver bind failed\n");
Elaine Zhang5be90bb2021-06-02 11:39:24 +08002962#endif
2963
2964 return 0;
2965}
2966
2967static const struct udevice_id rk3568_clk_ids[] = {
2968 { .compatible = "rockchip,rk3568-cru" },
2969 { }
2970};
2971
2972U_BOOT_DRIVER(rockchip_rk3568_cru) = {
2973 .name = "rockchip_rk3568_cru",
2974 .id = UCLASS_CLK,
2975 .of_match = rk3568_clk_ids,
2976 .priv_auto = sizeof(struct rk3568_clk_priv),
2977 .of_to_plat = rk3568_clk_ofdata_to_platdata,
2978 .ops = &rk3568_clk_ops,
2979 .bind = rk3568_clk_bind,
2980 .probe = rk3568_clk_probe,
2981#if CONFIG_IS_ENABLED(OF_PLATDATA)
2982 .plat_auto = sizeof(struct rk3568_clk_plat),
2983#endif
2984};