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