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