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