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