blob: 57ef27dda893d3380ed2267f06e85bbf0b9f9237 [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
1530 switch (rate) {
1531 case OSC_HZ:
1532 src_clk = SCLK_SFC_SEL_24M;
1533 break;
1534 case 50 * MHz:
1535 src_clk = SCLK_SFC_SEL_50M;
1536 break;
1537 case 75 * MHz:
1538 src_clk = SCLK_SFC_SEL_75M;
1539 break;
1540 case 100 * MHz:
1541 src_clk = SCLK_SFC_SEL_100M;
1542 break;
1543 case 125 * MHz:
1544 src_clk = SCLK_SFC_SEL_125M;
1545 break;
Elaine Zhang7b9b9262021-10-12 16:43:00 +08001546 case 150 * MHz:
Elaine Zhang5be90bb2021-06-02 11:39:24 +08001547 src_clk = SCLK_SFC_SEL_150M;
1548 break;
1549 default:
1550 return -ENOENT;
1551 }
1552
1553 rk_clrsetreg(&cru->clksel_con[28],
1554 SCLK_SFC_SEL_MASK,
1555 src_clk << SCLK_SFC_SEL_SHIFT);
1556
1557 return rk3568_sfc_get_clk(priv);
1558}
1559
1560static ulong rk3568_nand_get_clk(struct rk3568_clk_priv *priv)
1561{
1562 struct rk3568_cru *cru = priv->cru;
1563 u32 sel, con;
1564
1565 con = readl(&cru->clksel_con[28]);
1566 sel = (con & NCLK_NANDC_SEL_MASK) >> NCLK_NANDC_SEL_SHIFT;
1567 switch (sel) {
1568 case NCLK_NANDC_SEL_200M:
1569 return 200 * MHz;
1570 case NCLK_NANDC_SEL_150M:
1571 return 150 * MHz;
1572 case NCLK_NANDC_SEL_100M:
1573 return 100 * MHz;
1574 case NCLK_NANDC_SEL_24M:
1575 return OSC_HZ;
1576 default:
1577 return -ENOENT;
1578 }
1579}
1580
1581static ulong rk3568_nand_set_clk(struct rk3568_clk_priv *priv, ulong rate)
1582{
1583 struct rk3568_cru *cru = priv->cru;
1584 int src_clk;
1585
1586 switch (rate) {
1587 case OSC_HZ:
1588 src_clk = NCLK_NANDC_SEL_24M;
1589 break;
1590 case 100 * MHz:
1591 src_clk = NCLK_NANDC_SEL_100M;
1592 break;
1593 case 150 * MHz:
1594 src_clk = NCLK_NANDC_SEL_150M;
1595 break;
1596 case 200 * MHz:
1597 src_clk = NCLK_NANDC_SEL_200M;
1598 break;
1599 default:
1600 return -ENOENT;
1601 }
1602
1603 rk_clrsetreg(&cru->clksel_con[28],
1604 NCLK_NANDC_SEL_MASK,
1605 src_clk << NCLK_NANDC_SEL_SHIFT);
1606
1607 return rk3568_nand_get_clk(priv);
1608}
1609
1610static ulong rk3568_emmc_get_clk(struct rk3568_clk_priv *priv)
1611{
1612 struct rk3568_cru *cru = priv->cru;
1613 u32 sel, con;
1614
1615 con = readl(&cru->clksel_con[28]);
1616 sel = (con & CCLK_EMMC_SEL_MASK) >> CCLK_EMMC_SEL_SHIFT;
1617 switch (sel) {
1618 case CCLK_EMMC_SEL_200M:
1619 return 200 * MHz;
1620 case CCLK_EMMC_SEL_150M:
1621 return 150 * MHz;
1622 case CCLK_EMMC_SEL_100M:
1623 return 100 * MHz;
1624 case CCLK_EMMC_SEL_50M:
1625 return 50 * MHz;
1626 case CCLK_EMMC_SEL_375K:
1627 return 375 * KHz;
1628 case CCLK_EMMC_SEL_24M:
1629 return OSC_HZ;
1630 default:
1631 return -ENOENT;
1632 }
1633}
1634
1635static ulong rk3568_emmc_set_clk(struct rk3568_clk_priv *priv, ulong rate)
1636{
1637 struct rk3568_cru *cru = priv->cru;
1638 int src_clk;
1639
1640 switch (rate) {
1641 case OSC_HZ:
Vasily Khoruzhickd35b4c82023-02-23 13:03:32 -08001642 case 26 * MHz:
1643 case 25 * MHz:
Elaine Zhang5be90bb2021-06-02 11:39:24 +08001644 src_clk = CCLK_EMMC_SEL_24M;
1645 break;
1646 case 52 * MHz:
1647 case 50 * MHz:
1648 src_clk = CCLK_EMMC_SEL_50M;
1649 break;
1650 case 100 * MHz:
1651 src_clk = CCLK_EMMC_SEL_100M;
1652 break;
1653 case 150 * MHz:
1654 src_clk = CCLK_EMMC_SEL_150M;
1655 break;
1656 case 200 * MHz:
1657 src_clk = CCLK_EMMC_SEL_200M;
1658 break;
1659 case 400 * KHz:
1660 case 375 * KHz:
1661 src_clk = CCLK_EMMC_SEL_375K;
1662 break;
1663 default:
1664 return -ENOENT;
1665 }
1666
1667 rk_clrsetreg(&cru->clksel_con[28],
1668 CCLK_EMMC_SEL_MASK,
1669 src_clk << CCLK_EMMC_SEL_SHIFT);
1670
1671 return rk3568_emmc_get_clk(priv);
1672}
1673
1674static ulong rk3568_emmc_get_bclk(struct rk3568_clk_priv *priv)
1675{
1676 struct rk3568_cru *cru = priv->cru;
1677 u32 sel, con;
1678
1679 con = readl(&cru->clksel_con[28]);
1680 sel = (con & BCLK_EMMC_SEL_MASK) >> BCLK_EMMC_SEL_SHIFT;
1681 switch (sel) {
1682 case BCLK_EMMC_SEL_200M:
1683 return 200 * MHz;
1684 case BCLK_EMMC_SEL_150M:
1685 return 150 * MHz;
1686 case BCLK_EMMC_SEL_125M:
1687 return 125 * MHz;
1688 default:
1689 return -ENOENT;
1690 }
1691}
1692
1693static ulong rk3568_emmc_set_bclk(struct rk3568_clk_priv *priv, ulong rate)
1694{
1695 struct rk3568_cru *cru = priv->cru;
1696 int src_clk;
1697
1698 switch (rate) {
1699 case 200 * MHz:
1700 src_clk = BCLK_EMMC_SEL_200M;
1701 break;
1702 case 150 * MHz:
1703 src_clk = BCLK_EMMC_SEL_150M;
1704 break;
1705 case 125 * MHz:
1706 src_clk = BCLK_EMMC_SEL_125M;
1707 break;
1708 default:
1709 return -ENOENT;
1710 }
1711
1712 rk_clrsetreg(&cru->clksel_con[28],
1713 BCLK_EMMC_SEL_MASK,
1714 src_clk << BCLK_EMMC_SEL_SHIFT);
1715
1716 return rk3568_emmc_get_bclk(priv);
1717}
1718
1719#ifndef CONFIG_SPL_BUILD
1720static ulong rk3568_aclk_vop_get_clk(struct rk3568_clk_priv *priv)
1721{
1722 struct rk3568_cru *cru = priv->cru;
1723 u32 div, sel, con, parent;
1724
1725 con = readl(&cru->clksel_con[38]);
1726 div = (con & ACLK_VOP_PRE_DIV_MASK) >> ACLK_VOP_PRE_DIV_SHIFT;
1727 sel = (con & ACLK_VOP_PRE_SEL_MASK) >> ACLK_VOP_PRE_SEL_SHIFT;
1728 if (sel == ACLK_VOP_PRE_SEL_GPLL)
1729 parent = priv->gpll_hz;
1730 else if (sel == ACLK_VOP_PRE_SEL_CPLL)
1731 parent = priv->cpll_hz;
1732 else if (sel == ACLK_VOP_PRE_SEL_VPLL)
1733 parent = priv->vpll_hz;
1734 else
1735 parent = priv->hpll_hz;
1736
1737 return DIV_TO_RATE(parent, div);
1738}
1739
1740static ulong rk3568_aclk_vop_set_clk(struct rk3568_clk_priv *priv, ulong rate)
1741{
1742 struct rk3568_cru *cru = priv->cru;
1743 int src_clk_div, src_clk_mux;
1744
1745 if ((priv->cpll_hz % rate) == 0) {
1746 src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate);
1747 src_clk_mux = ACLK_VOP_PRE_SEL_CPLL;
1748 } else {
1749 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
1750 src_clk_mux = ACLK_VOP_PRE_SEL_GPLL;
1751 }
1752 assert(src_clk_div - 1 <= 31);
1753 rk_clrsetreg(&cru->clksel_con[38],
1754 ACLK_VOP_PRE_SEL_MASK | ACLK_VOP_PRE_DIV_MASK,
1755 src_clk_mux << ACLK_VOP_PRE_SEL_SHIFT |
1756 (src_clk_div - 1) << ACLK_VOP_PRE_DIV_SHIFT);
1757
1758 return rk3568_aclk_vop_get_clk(priv);
1759}
1760
1761static ulong rk3568_dclk_vop_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
1762{
1763 struct rk3568_cru *cru = priv->cru;
1764 u32 conid, div, sel, con, parent;
1765
1766 switch (clk_id) {
1767 case DCLK_VOP0:
1768 conid = 39;
1769 break;
1770 case DCLK_VOP1:
1771 conid = 40;
1772 break;
1773 case DCLK_VOP2:
1774 conid = 41;
1775 break;
1776 default:
1777 return -ENOENT;
1778 }
1779
1780 con = readl(&cru->clksel_con[conid]);
1781 div = (con & DCLK0_VOP_DIV_MASK) >> DCLK0_VOP_DIV_SHIFT;
1782 sel = (con & DCLK0_VOP_SEL_MASK) >> DCLK0_VOP_SEL_SHIFT;
1783 if (sel == DCLK_VOP_SEL_HPLL)
1784 parent = rk3568_pmu_pll_get_rate(priv, HPLL);
1785 else if (sel == DCLK_VOP_SEL_VPLL)
1786 parent = rockchip_pll_get_rate(&rk3568_pll_clks[VPLL],
1787 priv->cru, VPLL);
1788 else if (sel == DCLK_VOP_SEL_GPLL)
1789 parent = priv->gpll_hz;
1790 else if (sel == DCLK_VOP_SEL_CPLL)
1791 parent = priv->cpll_hz;
1792 else
1793 return -ENOENT;
1794
1795 return DIV_TO_RATE(parent, div);
1796}
1797
1798#define RK3568_VOP_PLL_LIMIT_FREQ 600000000
1799
1800static ulong rk3568_dclk_vop_set_clk(struct rk3568_clk_priv *priv,
1801 ulong clk_id, ulong rate)
1802{
1803 struct rk3568_cru *cru = priv->cru;
1804 ulong pll_rate, now, best_rate = 0;
1805 u32 i, conid, con, sel, div, best_div = 0, best_sel = 0;
1806
1807 switch (clk_id) {
1808 case DCLK_VOP0:
1809 conid = 39;
1810 break;
1811 case DCLK_VOP1:
1812 conid = 40;
1813 break;
1814 case DCLK_VOP2:
1815 conid = 41;
1816 break;
1817 default:
1818 return -ENOENT;
1819 }
1820
1821 con = readl(&cru->clksel_con[conid]);
1822 sel = (con & DCLK0_VOP_SEL_MASK) >> DCLK0_VOP_SEL_SHIFT;
1823
1824 if (sel == DCLK_VOP_SEL_HPLL) {
1825 div = 1;
1826 rk_clrsetreg(&cru->clksel_con[conid],
1827 DCLK0_VOP_DIV_MASK | DCLK0_VOP_SEL_MASK,
1828 (DCLK_VOP_SEL_HPLL << DCLK0_VOP_SEL_SHIFT) |
1829 ((div - 1) << DCLK0_VOP_DIV_SHIFT));
1830 rk3568_pmu_pll_set_rate(priv, HPLL, div * rate);
1831 } else if (sel == DCLK_VOP_SEL_VPLL) {
1832 div = DIV_ROUND_UP(RK3568_VOP_PLL_LIMIT_FREQ, rate);
1833 rk_clrsetreg(&cru->clksel_con[conid],
1834 DCLK0_VOP_DIV_MASK | DCLK0_VOP_SEL_MASK,
1835 (DCLK_VOP_SEL_VPLL << DCLK0_VOP_SEL_SHIFT) |
1836 ((div - 1) << DCLK0_VOP_DIV_SHIFT));
1837 rockchip_pll_set_rate(&rk3568_pll_clks[VPLL],
1838 priv->cru, VPLL, div * rate);
1839 } else {
Elaine Zhangf12a1602023-10-11 18:29:43 +08001840 for (i = sel; i <= DCLK_VOP_SEL_CPLL; i++) {
Elaine Zhang5be90bb2021-06-02 11:39:24 +08001841 switch (i) {
1842 case DCLK_VOP_SEL_GPLL:
1843 pll_rate = priv->gpll_hz;
1844 break;
1845 case DCLK_VOP_SEL_CPLL:
1846 pll_rate = priv->cpll_hz;
1847 break;
1848 default:
1849 printf("do not support this vop pll sel\n");
1850 return -EINVAL;
1851 }
1852
1853 div = DIV_ROUND_UP(pll_rate, rate);
1854 if (div > 255)
1855 continue;
1856 now = pll_rate / div;
1857 if (abs(rate - now) < abs(rate - best_rate)) {
1858 best_rate = now;
1859 best_div = div;
1860 best_sel = i;
1861 }
1862 debug("p_rate=%lu, best_rate=%lu, div=%u, sel=%u\n",
1863 pll_rate, best_rate, best_div, best_sel);
1864 }
1865
1866 if (best_rate) {
1867 rk_clrsetreg(&cru->clksel_con[conid],
1868 DCLK0_VOP_DIV_MASK | DCLK0_VOP_SEL_MASK,
1869 best_sel << DCLK0_VOP_SEL_SHIFT |
1870 (best_div - 1) << DCLK0_VOP_DIV_SHIFT);
1871 } else {
1872 printf("do not support this vop freq %lu\n", rate);
1873 return -EINVAL;
1874 }
1875 }
1876 return rk3568_dclk_vop_get_clk(priv, clk_id);
1877}
1878
1879static ulong rk3568_gmac_src_get_clk(struct rk3568_clk_priv *priv,
1880 ulong mac_id)
1881{
1882 struct rk3568_cru *cru = priv->cru;
1883 u32 sel, con;
1884
1885 con = readl(&cru->clksel_con[31 + mac_id * 2]);
1886 sel = (con & CLK_MAC0_2TOP_SEL_MASK) >> CLK_MAC0_2TOP_SEL_SHIFT;
1887
1888 switch (sel) {
1889 case CLK_MAC0_2TOP_SEL_125M:
1890 return 125 * MHz;
1891 case CLK_MAC0_2TOP_SEL_50M:
1892 return 50 * MHz;
1893 case CLK_MAC0_2TOP_SEL_25M:
1894 return 25 * MHz;
1895 case CLK_MAC0_2TOP_SEL_PPLL:
1896 return rk3568_pmu_pll_get_rate(priv, HPLL);
1897 default:
1898 return -ENOENT;
1899 }
1900}
1901
1902static ulong rk3568_gmac_src_set_clk(struct rk3568_clk_priv *priv,
1903 ulong mac_id, ulong rate)
1904{
1905 struct rk3568_cru *cru = priv->cru;
1906 int src_clk;
1907
1908 switch (rate) {
1909 case 125 * MHz:
1910 src_clk = CLK_MAC0_2TOP_SEL_125M;
1911 break;
1912 case 50 * MHz:
1913 src_clk = CLK_MAC0_2TOP_SEL_50M;
1914 break;
1915 case 25 * MHz:
1916 src_clk = CLK_MAC0_2TOP_SEL_25M;
1917 break;
1918 default:
1919 return -ENOENT;
1920 }
1921
1922 rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2],
1923 CLK_MAC0_2TOP_SEL_MASK,
1924 src_clk << CLK_MAC0_2TOP_SEL_SHIFT);
1925
1926 return rk3568_gmac_src_get_clk(priv, mac_id);
1927}
1928
1929static ulong rk3568_gmac_out_get_clk(struct rk3568_clk_priv *priv,
1930 ulong mac_id)
1931{
1932 struct rk3568_cru *cru = priv->cru;
1933 u32 sel, con;
1934
1935 con = readl(&cru->clksel_con[31 + mac_id * 2]);
1936 sel = (con & CLK_MAC0_OUT_SEL_MASK) >> CLK_MAC0_OUT_SEL_SHIFT;
1937
1938 switch (sel) {
1939 case CLK_MAC0_OUT_SEL_125M:
1940 return 125 * MHz;
1941 case CLK_MAC0_OUT_SEL_50M:
1942 return 50 * MHz;
1943 case CLK_MAC0_OUT_SEL_25M:
1944 return 25 * MHz;
1945 case CLK_MAC0_OUT_SEL_24M:
1946 return OSC_HZ;
1947 default:
1948 return -ENOENT;
1949 }
1950}
1951
1952static ulong rk3568_gmac_out_set_clk(struct rk3568_clk_priv *priv,
1953 ulong mac_id, ulong rate)
1954{
1955 struct rk3568_cru *cru = priv->cru;
1956 int src_clk;
1957
1958 switch (rate) {
1959 case 125 * MHz:
1960 src_clk = CLK_MAC0_OUT_SEL_125M;
1961 break;
1962 case 50 * MHz:
1963 src_clk = CLK_MAC0_OUT_SEL_50M;
1964 break;
1965 case 25 * MHz:
1966 src_clk = CLK_MAC0_OUT_SEL_25M;
1967 break;
1968 case 24 * MHz:
1969 src_clk = CLK_MAC0_OUT_SEL_24M;
1970 break;
1971 default:
1972 return -ENOENT;
1973 }
1974
1975 rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2],
1976 CLK_MAC0_OUT_SEL_MASK,
1977 src_clk << CLK_MAC0_OUT_SEL_SHIFT);
1978
1979 return rk3568_gmac_out_get_clk(priv, mac_id);
1980}
1981
1982static ulong rk3568_gmac_ptp_ref_get_clk(struct rk3568_clk_priv *priv,
1983 ulong mac_id)
1984{
1985 struct rk3568_cru *cru = priv->cru;
1986 u32 sel, con;
1987
1988 con = readl(&cru->clksel_con[31 + mac_id * 2]);
1989 sel = (con & CLK_GMAC0_PTP_REF_SEL_MASK) >> CLK_GMAC0_PTP_REF_SEL_SHIFT;
1990
1991 switch (sel) {
1992 case CLK_GMAC0_PTP_REF_SEL_62_5M:
1993 return 62500 * KHz;
1994 case CLK_GMAC0_PTP_REF_SEL_100M:
1995 return 100 * MHz;
1996 case CLK_GMAC0_PTP_REF_SEL_50M:
1997 return 50 * MHz;
1998 case CLK_GMAC0_PTP_REF_SEL_24M:
1999 return OSC_HZ;
2000 default:
2001 return -ENOENT;
2002 }
2003}
2004
2005static ulong rk3568_gmac_ptp_ref_set_clk(struct rk3568_clk_priv *priv,
2006 ulong mac_id, ulong rate)
2007{
2008 struct rk3568_cru *cru = priv->cru;
2009 int src_clk;
2010
2011 switch (rate) {
2012 case 62500 * KHz:
2013 src_clk = CLK_GMAC0_PTP_REF_SEL_62_5M;
2014 break;
2015 case 100 * MHz:
2016 src_clk = CLK_GMAC0_PTP_REF_SEL_100M;
2017 break;
2018 case 50 * MHz:
2019 src_clk = CLK_GMAC0_PTP_REF_SEL_50M;
2020 break;
2021 case 24 * MHz:
2022 src_clk = CLK_GMAC0_PTP_REF_SEL_24M;
2023 break;
2024 default:
2025 return -ENOENT;
2026 }
2027
2028 rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2],
2029 CLK_GMAC0_PTP_REF_SEL_MASK,
2030 src_clk << CLK_GMAC0_PTP_REF_SEL_SHIFT);
2031
2032 return rk3568_gmac_ptp_ref_get_clk(priv, mac_id);
2033}
2034
2035static ulong rk3568_gmac_tx_rx_set_clk(struct rk3568_clk_priv *priv,
2036 ulong mac_id, ulong rate)
2037{
2038 struct rk3568_cru *cru = priv->cru;
2039 u32 con, sel, div_sel;
2040
2041 con = readl(&cru->clksel_con[31 + mac_id * 2]);
2042 sel = (con & RMII0_MODE_MASK) >> RMII0_MODE_SHIFT;
2043
2044 if (sel == RMII0_MODE_SEL_RGMII) {
2045 if (rate == 2500000)
2046 div_sel = RGMII0_CLK_SEL_2_5M;
2047 else if (rate == 25000000)
2048 div_sel = RGMII0_CLK_SEL_25M;
2049 else
2050 div_sel = RGMII0_CLK_SEL_125M;
2051 rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2],
2052 RGMII0_CLK_SEL_MASK,
2053 div_sel << RGMII0_CLK_SEL_SHIFT);
2054 } else if (sel == RMII0_MODE_SEL_RMII) {
2055 if (rate == 2500000)
2056 div_sel = RMII0_CLK_SEL_2_5M;
2057 else
2058 div_sel = RMII0_CLK_SEL_25M;
2059 rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2],
2060 RMII0_CLK_SEL_MASK,
2061 div_sel << RMII0_CLK_SEL_SHIFT);
2062 }
2063
2064 return 0;
2065}
2066
2067static ulong rk3568_ebc_get_clk(struct rk3568_clk_priv *priv)
2068{
2069 struct rk3568_cru *cru = priv->cru;
2070 u32 con, div, p_rate;
2071
2072 con = readl(&cru->clksel_con[79]);
2073 div = (con & CPLL_333M_DIV_MASK) >> CPLL_333M_DIV_SHIFT;
2074 p_rate = DIV_TO_RATE(priv->cpll_hz, div);
2075
2076 con = readl(&cru->clksel_con[43]);
2077 div = (con & DCLK_EBC_SEL_MASK) >> DCLK_EBC_SEL_SHIFT;
2078 switch (div) {
2079 case DCLK_EBC_SEL_GPLL_400M:
2080 return 400 * MHz;
2081 case DCLK_EBC_SEL_CPLL_333M:
2082 return p_rate;
2083 case DCLK_EBC_SEL_GPLL_200M:
2084 return 200 * MHz;
2085 default:
2086 return -ENOENT;
2087 }
2088}
2089
2090static ulong rk3568_ebc_set_clk(struct rk3568_clk_priv *priv, ulong rate)
2091{
2092 struct rk3568_cru *cru = priv->cru;
2093 int src_clk_div;
2094
2095 src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate);
2096 assert(src_clk_div - 1 <= 31);
2097 rk_clrsetreg(&cru->clksel_con[79],
2098 CPLL_333M_DIV_MASK,
2099 (src_clk_div - 1) << CPLL_333M_DIV_SHIFT);
2100 rk_clrsetreg(&cru->clksel_con[43],
2101 DCLK_EBC_SEL_MASK,
2102 DCLK_EBC_SEL_CPLL_333M << DCLK_EBC_SEL_SHIFT);
2103
2104 return rk3568_ebc_get_clk(priv);
2105}
2106
2107static ulong rk3568_rkvdec_get_clk(struct rk3568_clk_priv *priv, ulong clk_id)
2108{
2109 struct rk3568_cru *cru = priv->cru;
2110 u32 con, div, src, p_rate;
2111
2112 switch (clk_id) {
2113 case ACLK_RKVDEC_PRE:
2114 case ACLK_RKVDEC:
2115 con = readl(&cru->clksel_con[47]);
2116 src = (con & ACLK_RKVDEC_SEL_MASK) >> ACLK_RKVDEC_SEL_SHIFT;
2117 div = (con & ACLK_RKVDEC_DIV_MASK) >> ACLK_RKVDEC_DIV_SHIFT;
2118 if (src == ACLK_RKVDEC_SEL_CPLL)
2119 p_rate = priv->cpll_hz;
2120 else
2121 p_rate = priv->gpll_hz;
2122 return DIV_TO_RATE(p_rate, div);
2123 case CLK_RKVDEC_CORE:
2124 con = readl(&cru->clksel_con[49]);
2125 src = (con & CLK_RKVDEC_CORE_SEL_MASK)
2126 >> CLK_RKVDEC_CORE_SEL_SHIFT;
2127 div = (con & CLK_RKVDEC_CORE_DIV_MASK)
2128 >> CLK_RKVDEC_CORE_DIV_SHIFT;
2129 if (src == CLK_RKVDEC_CORE_SEL_CPLL)
2130 p_rate = priv->cpll_hz;
2131 else if (src == CLK_RKVDEC_CORE_SEL_NPLL)
2132 p_rate = priv->npll_hz;
2133 else if (src == CLK_RKVDEC_CORE_SEL_VPLL)
2134 p_rate = priv->vpll_hz;
2135 else
2136 p_rate = priv->gpll_hz;
2137 return DIV_TO_RATE(p_rate, div);
2138 default:
2139 return -ENOENT;
2140 }
2141}
2142
2143static ulong rk3568_rkvdec_set_clk(struct rk3568_clk_priv *priv,
2144 ulong clk_id, ulong rate)
2145{
2146 struct rk3568_cru *cru = priv->cru;
2147 int src_clk_div, src, p_rate;
2148
2149 switch (clk_id) {
2150 case ACLK_RKVDEC_PRE:
2151 case ACLK_RKVDEC:
2152 src = (readl(&cru->clksel_con[47]) & ACLK_RKVDEC_SEL_MASK)
2153 >> ACLK_RKVDEC_SEL_SHIFT;
2154 if (src == ACLK_RKVDEC_SEL_CPLL)
2155 p_rate = priv->cpll_hz;
2156 else
2157 p_rate = priv->gpll_hz;
2158 src_clk_div = DIV_ROUND_UP(p_rate, rate);
2159 assert(src_clk_div - 1 <= 31);
2160 rk_clrsetreg(&cru->clksel_con[47],
2161 ACLK_RKVDEC_SEL_MASK |
2162 ACLK_RKVDEC_DIV_MASK,
2163 (src << ACLK_RKVDEC_SEL_SHIFT) |
2164 (src_clk_div - 1) << ACLK_RKVDEC_DIV_SHIFT);
2165 break;
2166 case CLK_RKVDEC_CORE:
2167 src = (readl(&cru->clksel_con[49]) & CLK_RKVDEC_CORE_SEL_MASK)
2168 >> CLK_RKVDEC_CORE_SEL_SHIFT;
2169 if (src == CLK_RKVDEC_CORE_SEL_CPLL)
2170 p_rate = priv->cpll_hz;
2171 else if (src == CLK_RKVDEC_CORE_SEL_NPLL)
2172 p_rate = priv->npll_hz;
2173 else if (src == CLK_RKVDEC_CORE_SEL_VPLL)
2174 p_rate = priv->vpll_hz;
2175 else
2176 p_rate = priv->gpll_hz;
2177 src_clk_div = DIV_ROUND_UP(p_rate, rate);
2178 assert(src_clk_div - 1 <= 31);
2179 rk_clrsetreg(&cru->clksel_con[49],
2180 CLK_RKVDEC_CORE_SEL_MASK |
2181 CLK_RKVDEC_CORE_DIV_MASK,
2182 (src << CLK_RKVDEC_CORE_SEL_SHIFT) |
2183 (src_clk_div - 1) << CLK_RKVDEC_CORE_DIV_SHIFT);
2184 break;
2185 default:
2186 return -ENOENT;
2187 }
2188
2189 return rk3568_rkvdec_get_clk(priv, clk_id);
2190}
Jonas Karlman381848a2023-08-04 09:33:59 +00002191#endif
Elaine Zhang5be90bb2021-06-02 11:39:24 +08002192
2193static ulong rk3568_uart_get_rate(struct rk3568_clk_priv *priv, ulong clk_id)
2194{
2195 struct rk3568_cru *cru = priv->cru;
2196 u32 reg, con, fracdiv, div, src, p_src, p_rate;
2197 unsigned long m, n;
2198
2199 switch (clk_id) {
2200 case SCLK_UART1:
2201 reg = 52;
2202 break;
2203 case SCLK_UART2:
2204 reg = 54;
2205 break;
2206 case SCLK_UART3:
2207 reg = 56;
2208 break;
2209 case SCLK_UART4:
2210 reg = 58;
2211 break;
2212 case SCLK_UART5:
2213 reg = 60;
2214 break;
2215 case SCLK_UART6:
2216 reg = 62;
2217 break;
2218 case SCLK_UART7:
2219 reg = 64;
2220 break;
2221 case SCLK_UART8:
2222 reg = 66;
2223 break;
2224 case SCLK_UART9:
2225 reg = 68;
2226 break;
2227 default:
2228 return -ENOENT;
2229 }
2230 con = readl(&cru->clksel_con[reg]);
2231 src = (con & CLK_UART_SEL_MASK) >> CLK_UART_SEL_SHIFT;
2232 div = (con & CLK_UART_SRC_DIV_MASK) >> CLK_UART_SRC_DIV_SHIFT;
2233 p_src = (con & CLK_UART_SRC_SEL_MASK) >> CLK_UART_SRC_SEL_SHIFT;
2234 if (p_src == CLK_UART_SRC_SEL_GPLL)
2235 p_rate = priv->gpll_hz;
2236 else if (p_src == CLK_UART_SRC_SEL_CPLL)
2237 p_rate = priv->cpll_hz;
2238 else
2239 p_rate = 480000000;
2240 if (src == CLK_UART_SEL_SRC) {
2241 return DIV_TO_RATE(p_rate, div);
2242 } else if (src == CLK_UART_SEL_FRAC) {
2243 fracdiv = readl(&cru->clksel_con[reg + 1]);
2244 n = fracdiv & CLK_UART_FRAC_NUMERATOR_MASK;
2245 n >>= CLK_UART_FRAC_NUMERATOR_SHIFT;
2246 m = fracdiv & CLK_UART_FRAC_DENOMINATOR_MASK;
2247 m >>= CLK_UART_FRAC_DENOMINATOR_SHIFT;
2248 return DIV_TO_RATE(p_rate, div) * n / m;
2249 } else {
2250 return OSC_HZ;
2251 }
2252}
2253
2254static ulong rk3568_uart_set_rate(struct rk3568_clk_priv *priv,
2255 ulong clk_id, ulong rate)
2256{
2257 struct rk3568_cru *cru = priv->cru;
2258 u32 reg, clk_src, uart_src, div;
2259 unsigned long m = 0, n = 0, val;
2260
2261 if (priv->gpll_hz % rate == 0) {
2262 clk_src = CLK_UART_SRC_SEL_GPLL;
2263 uart_src = CLK_UART_SEL_SRC;
2264 div = DIV_ROUND_UP(priv->gpll_hz, rate);
2265 } else if (priv->cpll_hz % rate == 0) {
2266 clk_src = CLK_UART_SRC_SEL_CPLL;
2267 uart_src = CLK_UART_SEL_SRC;
2268 div = DIV_ROUND_UP(priv->gpll_hz, rate);
2269 } else if (rate == OSC_HZ) {
2270 clk_src = CLK_UART_SRC_SEL_GPLL;
2271 uart_src = CLK_UART_SEL_XIN24M;
2272 div = 2;
2273 } else {
2274 clk_src = CLK_UART_SRC_SEL_GPLL;
2275 uart_src = CLK_UART_SEL_FRAC;
2276 div = 2;
2277 rational_best_approximation(rate, priv->gpll_hz / div,
2278 GENMASK(16 - 1, 0),
2279 GENMASK(16 - 1, 0),
2280 &m, &n);
2281 }
2282
2283 switch (clk_id) {
2284 case SCLK_UART1:
2285 reg = 52;
2286 break;
2287 case SCLK_UART2:
2288 reg = 54;
2289 break;
2290 case SCLK_UART3:
2291 reg = 56;
2292 break;
2293 case SCLK_UART4:
2294 reg = 58;
2295 break;
2296 case SCLK_UART5:
2297 reg = 60;
2298 break;
2299 case SCLK_UART6:
2300 reg = 62;
2301 break;
2302 case SCLK_UART7:
2303 reg = 64;
2304 break;
2305 case SCLK_UART8:
2306 reg = 66;
2307 break;
2308 case SCLK_UART9:
2309 reg = 68;
2310 break;
2311 default:
2312 return -ENOENT;
2313 }
2314 rk_clrsetreg(&cru->clksel_con[reg],
2315 CLK_UART_SEL_MASK | CLK_UART_SRC_SEL_MASK |
2316 CLK_UART_SRC_DIV_MASK,
2317 (clk_src << CLK_UART_SRC_SEL_SHIFT) |
2318 (uart_src << CLK_UART_SEL_SHIFT) |
2319 ((div - 1) << CLK_UART_SRC_DIV_SHIFT));
2320 if (m && n) {
2321 val = m << CLK_UART_FRAC_NUMERATOR_SHIFT | n;
2322 writel(val, &cru->clksel_con[reg + 1]);
2323 }
2324
2325 return rk3568_uart_get_rate(priv, clk_id);
2326}
Elaine Zhang5be90bb2021-06-02 11:39:24 +08002327
2328static ulong rk3568_clk_get_rate(struct clk *clk)
2329{
2330 struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2331 ulong rate = 0;
2332
2333 if (!priv->gpll_hz) {
2334 printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
2335 return -ENOENT;
2336 }
2337
2338 switch (clk->id) {
2339 case PLL_APLL:
2340 case ARMCLK:
2341 rate = rockchip_pll_get_rate(&rk3568_pll_clks[APLL], priv->cru,
2342 APLL);
2343 break;
2344 case PLL_CPLL:
2345 rate = rockchip_pll_get_rate(&rk3568_pll_clks[CPLL], priv->cru,
2346 CPLL);
2347 break;
2348 case PLL_GPLL:
2349 rate = rockchip_pll_get_rate(&rk3568_pll_clks[GPLL], priv->cru,
2350 GPLL);
2351 break;
2352 case PLL_NPLL:
2353 rate = rockchip_pll_get_rate(&rk3568_pll_clks[NPLL], priv->cru,
2354 NPLL);
2355 break;
2356 case PLL_VPLL:
2357 rate = rockchip_pll_get_rate(&rk3568_pll_clks[VPLL], priv->cru,
2358 VPLL);
2359 break;
2360 case PLL_DPLL:
2361 rate = rockchip_pll_get_rate(&rk3568_pll_clks[DPLL], priv->cru,
2362 DPLL);
2363 break;
2364 case ACLK_BUS:
2365 case PCLK_BUS:
2366 case PCLK_WDT_NS:
2367 rate = rk3568_bus_get_clk(priv, clk->id);
2368 break;
2369 case ACLK_PERIMID:
2370 case HCLK_PERIMID:
2371 rate = rk3568_perimid_get_clk(priv, clk->id);
2372 break;
2373 case ACLK_TOP_HIGH:
2374 case ACLK_TOP_LOW:
2375 case HCLK_TOP:
2376 case PCLK_TOP:
2377 rate = rk3568_top_get_clk(priv, clk->id);
2378 break;
2379 case CLK_I2C1:
2380 case CLK_I2C2:
2381 case CLK_I2C3:
2382 case CLK_I2C4:
2383 case CLK_I2C5:
2384 rate = rk3568_i2c_get_clk(priv, clk->id);
2385 break;
2386 case CLK_SPI0:
2387 case CLK_SPI1:
2388 case CLK_SPI2:
2389 case CLK_SPI3:
2390 rate = rk3568_spi_get_clk(priv, clk->id);
2391 break;
2392 case CLK_PWM1:
2393 case CLK_PWM2:
2394 case CLK_PWM3:
2395 rate = rk3568_pwm_get_clk(priv, clk->id);
2396 break;
2397 case CLK_SARADC:
2398 case CLK_TSADC_TSEN:
2399 case CLK_TSADC:
2400 rate = rk3568_adc_get_clk(priv, clk->id);
2401 break;
2402 case HCLK_SDMMC0:
2403 case CLK_SDMMC0:
2404 case CLK_SDMMC1:
2405 case CLK_SDMMC2:
2406 rate = rk3568_sdmmc_get_clk(priv, clk->id);
2407 break;
2408 case SCLK_SFC:
2409 rate = rk3568_sfc_get_clk(priv);
2410 break;
2411 case NCLK_NANDC:
2412 rate = rk3568_nand_get_clk(priv);
2413 break;
2414 case CCLK_EMMC:
2415 rate = rk3568_emmc_get_clk(priv);
2416 break;
2417 case BCLK_EMMC:
2418 rate = rk3568_emmc_get_bclk(priv);
2419 break;
Elaine Zhang7b9b9262021-10-12 16:43:00 +08002420 case TCLK_EMMC:
2421 rate = OSC_HZ;
2422 break;
Elaine Zhang5be90bb2021-06-02 11:39:24 +08002423#ifndef CONFIG_SPL_BUILD
2424 case ACLK_VOP:
2425 rate = rk3568_aclk_vop_get_clk(priv);
2426 break;
2427 case DCLK_VOP0:
2428 case DCLK_VOP1:
2429 case DCLK_VOP2:
2430 rate = rk3568_dclk_vop_get_clk(priv, clk->id);
2431 break;
2432 case SCLK_GMAC0:
2433 case CLK_MAC0_2TOP:
2434 case CLK_MAC0_REFOUT:
2435 rate = rk3568_gmac_src_get_clk(priv, 0);
2436 break;
2437 case CLK_MAC0_OUT:
2438 rate = rk3568_gmac_out_get_clk(priv, 0);
2439 break;
2440 case CLK_GMAC0_PTP_REF:
2441 rate = rk3568_gmac_ptp_ref_get_clk(priv, 0);
2442 break;
2443 case SCLK_GMAC1:
2444 case CLK_MAC1_2TOP:
2445 case CLK_MAC1_REFOUT:
2446 rate = rk3568_gmac_src_get_clk(priv, 1);
2447 break;
2448 case CLK_MAC1_OUT:
2449 rate = rk3568_gmac_out_get_clk(priv, 1);
2450 break;
2451 case CLK_GMAC1_PTP_REF:
2452 rate = rk3568_gmac_ptp_ref_get_clk(priv, 1);
2453 break;
2454 case DCLK_EBC:
2455 rate = rk3568_ebc_get_clk(priv);
2456 break;
2457 case ACLK_RKVDEC_PRE:
2458 case ACLK_RKVDEC:
2459 case CLK_RKVDEC_CORE:
2460 rate = rk3568_rkvdec_get_clk(priv, clk->id);
2461 break;
2462 case TCLK_WDT_NS:
2463 rate = OSC_HZ;
2464 break;
Jonas Karlman381848a2023-08-04 09:33:59 +00002465#endif
Elaine Zhang5be90bb2021-06-02 11:39:24 +08002466 case SCLK_UART1:
2467 case SCLK_UART2:
2468 case SCLK_UART3:
2469 case SCLK_UART4:
2470 case SCLK_UART5:
2471 case SCLK_UART6:
2472 case SCLK_UART7:
2473 case SCLK_UART8:
2474 case SCLK_UART9:
2475 rate = rk3568_uart_get_rate(priv, clk->id);
2476 break;
Elaine Zhang5be90bb2021-06-02 11:39:24 +08002477 case ACLK_SECURE_FLASH:
2478 case ACLK_CRYPTO_NS:
2479 case HCLK_SECURE_FLASH:
2480 case HCLK_CRYPTO_NS:
2481 case CLK_CRYPTO_NS_RNG:
2482 case CLK_CRYPTO_NS_CORE:
2483 case CLK_CRYPTO_NS_PKA:
2484 rate = rk3568_crypto_get_rate(priv, clk->id);
2485 break;
2486 case CPLL_500M:
2487 case CPLL_333M:
2488 case CPLL_250M:
2489 case CPLL_125M:
2490 case CPLL_100M:
2491 case CPLL_62P5M:
2492 case CPLL_50M:
2493 case CPLL_25M:
2494 rate = rk3568_cpll_div_get_rate(priv, clk->id);
2495 break;
2496 default:
2497 return -ENOENT;
2498 }
2499
2500 return rate;
2501};
2502
2503static ulong rk3568_clk_set_rate(struct clk *clk, ulong rate)
2504{
2505 struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2506 ulong ret = 0;
2507
2508 if (!priv->gpll_hz) {
2509 printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
2510 return -ENOENT;
2511 }
2512
2513 switch (clk->id) {
2514 case PLL_APLL:
2515 case ARMCLK:
2516 if (priv->armclk_hz)
2517 rk3568_armclk_set_clk(priv, rate);
2518 priv->armclk_hz = rate;
2519 break;
2520 case PLL_CPLL:
2521 ret = rockchip_pll_set_rate(&rk3568_pll_clks[CPLL], priv->cru,
2522 CPLL, rate);
2523 priv->cpll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[CPLL],
2524 priv->cru, CPLL);
2525 break;
2526 case PLL_GPLL:
2527 ret = rockchip_pll_set_rate(&rk3568_pll_clks[GPLL], priv->cru,
2528 GPLL, rate);
2529 priv->gpll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[GPLL],
2530 priv->cru, GPLL);
2531 break;
2532 case PLL_NPLL:
2533 ret = rockchip_pll_set_rate(&rk3568_pll_clks[NPLL], priv->cru,
2534 NPLL, rate);
2535 break;
2536 case PLL_VPLL:
2537 ret = rockchip_pll_set_rate(&rk3568_pll_clks[VPLL], priv->cru,
2538 VPLL, rate);
2539 priv->vpll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[VPLL],
2540 priv->cru,
2541 VPLL);
2542 break;
2543 case ACLK_BUS:
2544 case PCLK_BUS:
2545 case PCLK_WDT_NS:
2546 ret = rk3568_bus_set_clk(priv, clk->id, rate);
2547 break;
2548 case ACLK_PERIMID:
2549 case HCLK_PERIMID:
2550 ret = rk3568_perimid_set_clk(priv, clk->id, rate);
2551 break;
2552 case ACLK_TOP_HIGH:
2553 case ACLK_TOP_LOW:
2554 case HCLK_TOP:
2555 case PCLK_TOP:
2556 ret = rk3568_top_set_clk(priv, clk->id, rate);
2557 break;
2558 case CLK_I2C1:
2559 case CLK_I2C2:
2560 case CLK_I2C3:
2561 case CLK_I2C4:
2562 case CLK_I2C5:
2563 ret = rk3568_i2c_set_clk(priv, clk->id, rate);
2564 break;
2565 case CLK_SPI0:
2566 case CLK_SPI1:
2567 case CLK_SPI2:
2568 case CLK_SPI3:
2569 ret = rk3568_spi_set_clk(priv, clk->id, rate);
2570 break;
2571 case CLK_PWM1:
2572 case CLK_PWM2:
2573 case CLK_PWM3:
2574 ret = rk3568_pwm_set_clk(priv, clk->id, rate);
2575 break;
2576 case CLK_SARADC:
2577 case CLK_TSADC_TSEN:
2578 case CLK_TSADC:
2579 ret = rk3568_adc_set_clk(priv, clk->id, rate);
2580 break;
2581 case HCLK_SDMMC0:
2582 case CLK_SDMMC0:
2583 case CLK_SDMMC1:
2584 case CLK_SDMMC2:
2585 ret = rk3568_sdmmc_set_clk(priv, clk->id, rate);
2586 break;
2587 case SCLK_SFC:
2588 ret = rk3568_sfc_set_clk(priv, rate);
2589 break;
2590 case NCLK_NANDC:
2591 ret = rk3568_nand_set_clk(priv, rate);
2592 break;
2593 case CCLK_EMMC:
2594 ret = rk3568_emmc_set_clk(priv, rate);
2595 break;
2596 case BCLK_EMMC:
2597 ret = rk3568_emmc_set_bclk(priv, rate);
2598 break;
Elaine Zhang7b9b9262021-10-12 16:43:00 +08002599 case TCLK_EMMC:
2600 ret = OSC_HZ;
2601 break;
Elaine Zhang5be90bb2021-06-02 11:39:24 +08002602#ifndef CONFIG_SPL_BUILD
2603 case ACLK_VOP:
2604 ret = rk3568_aclk_vop_set_clk(priv, rate);
2605 break;
2606 case DCLK_VOP0:
2607 case DCLK_VOP1:
2608 case DCLK_VOP2:
2609 ret = rk3568_dclk_vop_set_clk(priv, clk->id, rate);
2610 break;
2611 case SCLK_GMAC0:
2612 case CLK_MAC0_2TOP:
2613 case CLK_MAC0_REFOUT:
2614 ret = rk3568_gmac_src_set_clk(priv, 0, rate);
2615 break;
2616 case CLK_MAC0_OUT:
2617 ret = rk3568_gmac_out_set_clk(priv, 0, rate);
2618 break;
2619 case SCLK_GMAC0_RX_TX:
2620 ret = rk3568_gmac_tx_rx_set_clk(priv, 0, rate);
2621 break;
2622 case CLK_GMAC0_PTP_REF:
2623 ret = rk3568_gmac_ptp_ref_set_clk(priv, 0, rate);
2624 break;
2625 case SCLK_GMAC1:
2626 case CLK_MAC1_2TOP:
2627 case CLK_MAC1_REFOUT:
2628 ret = rk3568_gmac_src_set_clk(priv, 1, rate);
2629 break;
2630 case CLK_MAC1_OUT:
2631 ret = rk3568_gmac_out_set_clk(priv, 1, rate);
2632 break;
2633 case SCLK_GMAC1_RX_TX:
2634 ret = rk3568_gmac_tx_rx_set_clk(priv, 1, rate);
2635 break;
2636 case CLK_GMAC1_PTP_REF:
2637 ret = rk3568_gmac_ptp_ref_set_clk(priv, 1, rate);
2638 break;
2639 case DCLK_EBC:
2640 ret = rk3568_ebc_set_clk(priv, rate);
2641 break;
2642 case ACLK_RKVDEC_PRE:
2643 case ACLK_RKVDEC:
2644 case CLK_RKVDEC_CORE:
2645 ret = rk3568_rkvdec_set_clk(priv, clk->id, rate);
2646 break;
2647 case TCLK_WDT_NS:
2648 ret = OSC_HZ;
2649 break;
Jonas Karlman381848a2023-08-04 09:33:59 +00002650#endif
Elaine Zhang5be90bb2021-06-02 11:39:24 +08002651 case SCLK_UART1:
2652 case SCLK_UART2:
2653 case SCLK_UART3:
2654 case SCLK_UART4:
2655 case SCLK_UART5:
2656 case SCLK_UART6:
2657 case SCLK_UART7:
2658 case SCLK_UART8:
2659 case SCLK_UART9:
2660 ret = rk3568_uart_set_rate(priv, clk->id, rate);
2661 break;
Elaine Zhang5be90bb2021-06-02 11:39:24 +08002662 case ACLK_SECURE_FLASH:
2663 case ACLK_CRYPTO_NS:
2664 case HCLK_SECURE_FLASH:
2665 case HCLK_CRYPTO_NS:
2666 case CLK_CRYPTO_NS_RNG:
2667 case CLK_CRYPTO_NS_CORE:
2668 case CLK_CRYPTO_NS_PKA:
2669 ret = rk3568_crypto_set_rate(priv, clk->id, rate);
2670 break;
2671 case CPLL_500M:
2672 case CPLL_333M:
2673 case CPLL_250M:
2674 case CPLL_125M:
2675 case CPLL_100M:
2676 case CPLL_62P5M:
2677 case CPLL_50M:
2678 case CPLL_25M:
2679 ret = rk3568_cpll_div_set_rate(priv, clk->id, rate);
2680 break;
2681 default:
2682 return -ENOENT;
2683 }
2684
2685 return ret;
2686};
2687
2688#if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA))
2689static int rk3568_gmac0_src_set_parent(struct clk *clk, struct clk *parent)
2690{
2691 struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2692 struct rk3568_cru *cru = priv->cru;
2693
2694 if (parent->id == CLK_MAC0_2TOP)
2695 rk_clrsetreg(&cru->clksel_con[31],
2696 RMII0_EXTCLK_SEL_MASK,
2697 RMII0_EXTCLK_SEL_MAC0_TOP <<
2698 RMII0_EXTCLK_SEL_SHIFT);
2699 else
2700 rk_clrsetreg(&cru->clksel_con[31],
2701 RMII0_EXTCLK_SEL_MASK,
2702 RMII0_EXTCLK_SEL_IO << RMII0_EXTCLK_SEL_SHIFT);
2703 return 0;
2704}
2705
2706static int rk3568_gmac1_src_set_parent(struct clk *clk, struct clk *parent)
2707{
2708 struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2709 struct rk3568_cru *cru = priv->cru;
2710
2711 if (parent->id == CLK_MAC1_2TOP)
2712 rk_clrsetreg(&cru->clksel_con[33],
2713 RMII0_EXTCLK_SEL_MASK,
2714 RMII0_EXTCLK_SEL_MAC0_TOP <<
2715 RMII0_EXTCLK_SEL_SHIFT);
2716 else
2717 rk_clrsetreg(&cru->clksel_con[33],
2718 RMII0_EXTCLK_SEL_MASK,
2719 RMII0_EXTCLK_SEL_IO << RMII0_EXTCLK_SEL_SHIFT);
2720 return 0;
2721}
2722
2723static int rk3568_gmac0_tx_rx_set_parent(struct clk *clk, struct clk *parent)
2724{
2725 struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2726 struct rk3568_cru *cru = priv->cru;
2727
2728 if (parent->id == SCLK_GMAC0_RGMII_SPEED)
2729 rk_clrsetreg(&cru->clksel_con[31],
2730 RMII0_MODE_MASK,
2731 RMII0_MODE_SEL_RGMII << RMII0_MODE_SHIFT);
2732 else if (parent->id == SCLK_GMAC0_RMII_SPEED)
2733 rk_clrsetreg(&cru->clksel_con[31],
2734 RMII0_MODE_MASK,
2735 RMII0_MODE_SEL_RMII << RMII0_MODE_SHIFT);
2736 else
2737 rk_clrsetreg(&cru->clksel_con[31],
2738 RMII0_MODE_MASK,
2739 RMII0_MODE_SEL_GMII << RMII0_MODE_SHIFT);
2740
2741 return 0;
2742}
2743
2744static int rk3568_gmac1_tx_rx_set_parent(struct clk *clk, struct clk *parent)
2745{
2746 struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2747 struct rk3568_cru *cru = priv->cru;
2748
2749 if (parent->id == SCLK_GMAC1_RGMII_SPEED)
2750 rk_clrsetreg(&cru->clksel_con[33],
2751 RMII0_MODE_MASK,
2752 RMII0_MODE_SEL_RGMII << RMII0_MODE_SHIFT);
2753 else if (parent->id == SCLK_GMAC1_RMII_SPEED)
2754 rk_clrsetreg(&cru->clksel_con[33],
2755 RMII0_MODE_MASK,
2756 RMII0_MODE_SEL_RMII << RMII0_MODE_SHIFT);
2757 else
2758 rk_clrsetreg(&cru->clksel_con[33],
2759 RMII0_MODE_MASK,
2760 RMII0_MODE_SEL_GMII << RMII0_MODE_SHIFT);
2761
2762 return 0;
2763}
2764
2765static int rk3568_dclk_vop_set_parent(struct clk *clk, struct clk *parent)
2766{
2767 struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2768 struct rk3568_cru *cru = priv->cru;
2769 u32 con_id;
2770
2771 switch (clk->id) {
2772 case DCLK_VOP0:
2773 con_id = 39;
2774 break;
2775 case DCLK_VOP1:
2776 con_id = 40;
2777 break;
2778 case DCLK_VOP2:
2779 con_id = 41;
2780 break;
2781 default:
2782 return -EINVAL;
2783 }
2784 if (parent->id == PLL_VPLL) {
2785 rk_clrsetreg(&cru->clksel_con[con_id], DCLK0_VOP_SEL_MASK,
2786 DCLK_VOP_SEL_VPLL << DCLK0_VOP_SEL_SHIFT);
Elaine Zhangf12a1602023-10-11 18:29:43 +08002787 } else if (parent->id == PLL_HPLL) {
Elaine Zhang5be90bb2021-06-02 11:39:24 +08002788 rk_clrsetreg(&cru->clksel_con[con_id], DCLK0_VOP_SEL_MASK,
2789 DCLK_VOP_SEL_HPLL << DCLK0_VOP_SEL_SHIFT);
Elaine Zhangf12a1602023-10-11 18:29:43 +08002790 } else if (parent->id == PLL_CPLL) {
2791 rk_clrsetreg(&cru->clksel_con[con_id], DCLK0_VOP_SEL_MASK,
2792 DCLK_VOP_SEL_CPLL << DCLK0_VOP_SEL_SHIFT);
2793 } else {
2794 rk_clrsetreg(&cru->clksel_con[con_id], DCLK0_VOP_SEL_MASK,
2795 DCLK_VOP_SEL_GPLL << DCLK0_VOP_SEL_SHIFT);
Elaine Zhang5be90bb2021-06-02 11:39:24 +08002796 }
2797
2798 return 0;
2799}
2800
2801static int rk3568_rkvdec_set_parent(struct clk *clk, struct clk *parent)
2802{
2803 struct rk3568_clk_priv *priv = dev_get_priv(clk->dev);
2804 struct rk3568_cru *cru = priv->cru;
2805 u32 con_id, mask, shift;
2806
2807 switch (clk->id) {
2808 case ACLK_RKVDEC_PRE:
2809 con_id = 47;
2810 mask = ACLK_RKVDEC_SEL_MASK;
2811 shift = ACLK_RKVDEC_SEL_SHIFT;
2812 break;
2813 case CLK_RKVDEC_CORE:
2814 con_id = 49;
2815 mask = CLK_RKVDEC_CORE_SEL_MASK;
2816 shift = CLK_RKVDEC_CORE_SEL_SHIFT;
2817 break;
2818 default:
2819 return -EINVAL;
2820 }
2821 if (parent->id == PLL_CPLL) {
2822 rk_clrsetreg(&cru->clksel_con[con_id], mask,
2823 ACLK_RKVDEC_SEL_CPLL << shift);
2824 } else {
2825 rk_clrsetreg(&cru->clksel_con[con_id], mask,
2826 ACLK_RKVDEC_SEL_GPLL << shift);
2827 }
2828
2829 return 0;
2830}
2831
2832static int rk3568_clk_set_parent(struct clk *clk, struct clk *parent)
2833{
2834 switch (clk->id) {
2835 case SCLK_GMAC0:
2836 return rk3568_gmac0_src_set_parent(clk, parent);
2837 case SCLK_GMAC1:
2838 return rk3568_gmac1_src_set_parent(clk, parent);
2839 case SCLK_GMAC0_RX_TX:
2840 return rk3568_gmac0_tx_rx_set_parent(clk, parent);
2841 case SCLK_GMAC1_RX_TX:
2842 return rk3568_gmac1_tx_rx_set_parent(clk, parent);
2843 case DCLK_VOP0:
2844 case DCLK_VOP1:
2845 case DCLK_VOP2:
2846 return rk3568_dclk_vop_set_parent(clk, parent);
2847 case ACLK_RKVDEC_PRE:
2848 case CLK_RKVDEC_CORE:
2849 return rk3568_rkvdec_set_parent(clk, parent);
Jonas Karlman1f7e8ff2023-04-17 19:07:25 +00002850 case I2S1_MCLKOUT_TX:
Jonas Karlman146150c2023-08-04 09:34:00 +00002851 case SCLK_GMAC0_RGMII_SPEED:
2852 case SCLK_GMAC0_RMII_SPEED:
2853 case SCLK_GMAC1_RGMII_SPEED:
2854 case SCLK_GMAC1_RMII_SPEED:
Jonas Karlman1f7e8ff2023-04-17 19:07:25 +00002855 break;
Elaine Zhang5be90bb2021-06-02 11:39:24 +08002856 default:
2857 return -ENOENT;
2858 }
2859
2860 return 0;
2861}
2862#endif
2863
2864static struct clk_ops rk3568_clk_ops = {
2865 .get_rate = rk3568_clk_get_rate,
2866 .set_rate = rk3568_clk_set_rate,
2867#if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA))
2868 .set_parent = rk3568_clk_set_parent,
2869#endif
2870};
2871
2872static void rk3568_clk_init(struct rk3568_clk_priv *priv)
2873{
2874 int ret;
2875
2876 priv->sync_kernel = false;
2877 if (!priv->armclk_enter_hz) {
2878 priv->armclk_enter_hz =
2879 rockchip_pll_get_rate(&rk3568_pll_clks[APLL],
2880 priv->cru, APLL);
2881 priv->armclk_init_hz = priv->armclk_enter_hz;
2882 }
2883
2884 if (priv->armclk_init_hz != APLL_HZ) {
2885 ret = rk3568_armclk_set_clk(priv, APLL_HZ);
2886 if (!ret)
2887 priv->armclk_init_hz = APLL_HZ;
2888 }
2889 if (priv->cpll_hz != CPLL_HZ) {
2890 ret = rockchip_pll_set_rate(&rk3568_pll_clks[CPLL], priv->cru,
2891 CPLL, CPLL_HZ);
2892 if (!ret)
2893 priv->cpll_hz = CPLL_HZ;
2894 }
2895 if (priv->gpll_hz != GPLL_HZ) {
2896 ret = rockchip_pll_set_rate(&rk3568_pll_clks[GPLL], priv->cru,
2897 GPLL, GPLL_HZ);
2898 if (!ret)
2899 priv->gpll_hz = GPLL_HZ;
2900 }
2901
2902#ifdef CONFIG_SPL_BUILD
2903 ret = rk3568_bus_set_clk(priv, ACLK_BUS, 150000000);
2904 if (ret < 0)
2905 printf("Fail to set the ACLK_BUS clock.\n");
2906#endif
2907
2908 priv->ppll_hz = rk3568_pmu_pll_get_rate(priv, PPLL);
2909 priv->hpll_hz = rk3568_pmu_pll_get_rate(priv, HPLL);
2910}
2911
2912static int rk3568_clk_probe(struct udevice *dev)
2913{
2914 struct rk3568_clk_priv *priv = dev_get_priv(dev);
2915 int ret;
2916
2917 priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
2918 if (IS_ERR(priv->grf))
2919 return PTR_ERR(priv->grf);
2920
2921 rk3568_clk_init(priv);
2922
2923 /* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
2924 ret = clk_set_defaults(dev, 1);
2925 if (ret)
2926 debug("%s clk_set_defaults failed %d\n", __func__, ret);
2927 else
2928 priv->sync_kernel = true;
2929
2930 return 0;
2931}
2932
2933static int rk3568_clk_ofdata_to_platdata(struct udevice *dev)
2934{
2935 struct rk3568_clk_priv *priv = dev_get_priv(dev);
2936
2937 priv->cru = dev_read_addr_ptr(dev);
2938
2939 return 0;
2940}
2941
2942static int rk3568_clk_bind(struct udevice *dev)
2943{
2944 int ret;
2945 struct udevice *sys_child;
2946 struct sysreset_reg *priv;
2947
2948 /* The reset driver does not have a device node, so bind it here */
2949 ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
2950 &sys_child);
2951 if (ret) {
2952 debug("Warning: No sysreset driver: ret=%d\n", ret);
2953 } else {
2954 priv = malloc(sizeof(struct sysreset_reg));
2955 priv->glb_srst_fst_value = offsetof(struct rk3568_cru,
2956 glb_srst_fst);
2957 priv->glb_srst_snd_value = offsetof(struct rk3568_cru,
2958 glb_srsr_snd);
Peter Geis393cdce2023-03-14 00:38:26 +00002959 dev_set_priv(sys_child, priv);
Elaine Zhang5be90bb2021-06-02 11:39:24 +08002960 }
2961
2962#if CONFIG_IS_ENABLED(RESET_ROCKCHIP)
2963 ret = offsetof(struct rk3568_cru, softrst_con[0]);
2964 ret = rockchip_reset_bind(dev, ret, 30);
2965 if (ret)
Eugen Hristevf1798262023-04-11 10:17:56 +03002966 debug("Warning: software reset driver bind failed\n");
Elaine Zhang5be90bb2021-06-02 11:39:24 +08002967#endif
2968
2969 return 0;
2970}
2971
2972static const struct udevice_id rk3568_clk_ids[] = {
2973 { .compatible = "rockchip,rk3568-cru" },
2974 { }
2975};
2976
2977U_BOOT_DRIVER(rockchip_rk3568_cru) = {
2978 .name = "rockchip_rk3568_cru",
2979 .id = UCLASS_CLK,
2980 .of_match = rk3568_clk_ids,
2981 .priv_auto = sizeof(struct rk3568_clk_priv),
2982 .of_to_plat = rk3568_clk_ofdata_to_platdata,
2983 .ops = &rk3568_clk_ops,
2984 .bind = rk3568_clk_bind,
2985 .probe = rk3568_clk_probe,
2986#if CONFIG_IS_ENABLED(OF_PLATDATA)
2987 .plat_auto = sizeof(struct rk3568_clk_plat),
2988#endif
2989};