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