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