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