1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
4 * Author: Finley Xiao <finley.xiao@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_rv1126.h>
15 #include <asm/arch/grf_rv1126.h>
16 #include <asm/arch/hardware.h>
17 #include <asm/io.h>
18 #include <dm/lists.h>
19 #include <dt-bindings/clock/rv1126-cru.h>
20
21 DECLARE_GLOBAL_DATA_PTR;
22
23 #define RV1126_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 rv1126_cpu_rates[] = {
33 RV1126_CPUCLK_RATE(1200000000, 1, 5),
34 RV1126_CPUCLK_RATE(1008000000, 1, 5),
35 RV1126_CPUCLK_RATE(816000000, 1, 3),
36 RV1126_CPUCLK_RATE(600000000, 1, 3),
37 RV1126_CPUCLK_RATE(408000000, 1, 1),
38 };
39
40 static struct rockchip_pll_rate_table rv1126_pll_rates[] = {
41 /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
42 RK3036_PLL_RATE(1600000000, 3, 200, 1, 1, 1, 0),
43 RK3036_PLL_RATE(1400000000, 3, 350, 2, 1, 1, 0),
44 RK3036_PLL_RATE(1200000000, 1, 100, 2, 1, 1, 0),
45 RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0),
46 RK3036_PLL_RATE(1100000000, 3, 275, 2, 1, 1, 0),
47 RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0),
48 RK3036_PLL_RATE(1000000000, 3, 250, 2, 1, 1, 0),
49 RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0),
50 RK3036_PLL_RATE(800000000, 3, 200, 2, 1, 1, 0),
51 RK3036_PLL_RATE(600000000, 1, 100, 4, 1, 1, 0),
52 RK3036_PLL_RATE(594000000, 1, 99, 4, 1, 1, 0),
53 RK3036_PLL_RATE(500000000, 1, 125, 6, 1, 1, 0),
54 RK3036_PLL_RATE(200000000, 1, 100, 6, 2, 1, 0),
55 RK3036_PLL_RATE(100000000, 1, 100, 6, 4, 1, 0),
56 { /* sentinel */ },
57 };
58
59 static struct rockchip_pll_clock rv1126_pll_clks[] = {
60 [APLL] = PLL(pll_rk3328, PLL_APLL, RV1126_PLL_CON(0),
61 RV1126_MODE_CON, 0, 10, 0, rv1126_pll_rates),
62 [DPLL] = PLL(pll_rk3328, PLL_DPLL, RV1126_PLL_CON(8),
63 RV1126_MODE_CON, 2, 10, 0, NULL),
64 [CPLL] = PLL(pll_rk3328, PLL_CPLL, RV1126_PLL_CON(16),
65 RV1126_MODE_CON, 4, 10, 0, rv1126_pll_rates),
66 [HPLL] = PLL(pll_rk3328, PLL_HPLL, RV1126_PLL_CON(24),
67 RV1126_MODE_CON, 6, 10, 0, rv1126_pll_rates),
68 [GPLL] = PLL(pll_rk3328, PLL_GPLL, RV1126_PMU_PLL_CON(0),
69 RV1126_PMU_MODE, 0, 10, 0, rv1126_pll_rates),
70 };
71
72 #ifndef CONFIG_SPL_BUILD
73 #define RV1126_CLK_DUMP(_id, _name, _iscru) \
74 { \
75 .id = _id, \
76 .name = _name, \
77 .is_cru = _iscru, \
78 }
79
80 static const struct rv1126_clk_info clks_dump[] = {
81 RV1126_CLK_DUMP(PLL_APLL, "apll", true),
82 RV1126_CLK_DUMP(PLL_DPLL, "dpll", true),
83 RV1126_CLK_DUMP(PLL_GPLL, "gpll", false),
84 RV1126_CLK_DUMP(PLL_CPLL, "cpll", true),
85 RV1126_CLK_DUMP(PLL_HPLL, "hpll", true),
86 RV1126_CLK_DUMP(ACLK_PDBUS, "aclk_pdbus", true),
87 RV1126_CLK_DUMP(HCLK_PDBUS, "hclk_pdbus", true),
88 RV1126_CLK_DUMP(PCLK_PDBUS, "pclk_pdbus", true),
89 RV1126_CLK_DUMP(ACLK_PDPHP, "aclk_pdphp", true),
90 RV1126_CLK_DUMP(HCLK_PDPHP, "hclk_pdphp", true),
91 RV1126_CLK_DUMP(HCLK_PDAUDIO, "hclk_pdaudio", true),
92 RV1126_CLK_DUMP(HCLK_PDCORE_NIU, "hclk_pdcore", true),
93 RV1126_CLK_DUMP(PCLK_PDPMU, "pclk_pdpmu", false),
94 };
95 #endif
96
97 static ulong rv1126_gpll_set_rate(struct rv1126_clk_priv *priv,
98 struct rv1126_pmuclk_priv *pmu_priv,
99 ulong rate);
100 /*
101 *
102 * rational_best_approximation(31415, 10000,
103 * (1 << 8) - 1, (1 << 5) - 1, &n, &d);
104 *
105 * you may look at given_numerator as a fixed point number,
106 * with the fractional part size described in given_denominator.
107 *
108 * for theoretical background, see:
109 * http://en.wikipedia.org/wiki/Continued_fraction
110 */
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)111 static void rational_best_approximation(unsigned long given_numerator,
112 unsigned long given_denominator,
113 unsigned long max_numerator,
114 unsigned long max_denominator,
115 unsigned long *best_numerator,
116 unsigned long *best_denominator)
117 {
118 unsigned long n, d, n0, d0, n1, d1;
119
120 n = given_numerator;
121 d = given_denominator;
122 n0 = 0;
123 d1 = 0;
124 n1 = 1;
125 d0 = 1;
126 for (;;) {
127 unsigned long t, a;
128
129 if (n1 > max_numerator || d1 > max_denominator) {
130 n1 = n0;
131 d1 = d0;
132 break;
133 }
134 if (d == 0)
135 break;
136 t = d;
137 a = n / d;
138 d = n % d;
139 n = t;
140 t = n0 + a * n1;
141 n0 = n1;
142 n1 = t;
143 t = d0 + a * d1;
144 d0 = d1;
145 d1 = t;
146 }
147 *best_numerator = n1;
148 *best_denominator = d1;
149 }
150
rv1126_gpll_get_pmuclk(struct rv1126_pmuclk_priv * priv)151 static ulong rv1126_gpll_get_pmuclk(struct rv1126_pmuclk_priv *priv)
152 {
153 return rockchip_pll_get_rate(&rv1126_pll_clks[GPLL],
154 priv->pmucru, GPLL);
155 }
156
rv1126_gpll_set_pmuclk(struct rv1126_pmuclk_priv * pmu_priv,ulong rate)157 static ulong rv1126_gpll_set_pmuclk(struct rv1126_pmuclk_priv *pmu_priv, ulong rate)
158 {
159 struct udevice *cru_dev;
160 struct rv1126_clk_priv *priv;
161 int ret;
162
163 ret = uclass_get_device_by_driver(UCLASS_CLK,
164 DM_GET_DRIVER(rockchip_rv1126_cru),
165 &cru_dev);
166 if (ret) {
167 printf("%s: could not find cru device\n", __func__);
168 return ret;
169 }
170 priv = dev_get_priv(cru_dev);
171
172 if (rv1126_gpll_set_rate(priv, pmu_priv, rate)) {
173 printf("%s: failed to set gpll rate %lu\n", __func__, rate);
174 return -EINVAL;
175 }
176 return 0;
177 }
178
rv1126_rtc32k_get_pmuclk(struct rv1126_pmuclk_priv * priv)179 static ulong rv1126_rtc32k_get_pmuclk(struct rv1126_pmuclk_priv *priv)
180 {
181 struct rv1126_pmucru *pmucru = priv->pmucru;
182 unsigned long m, n;
183 u32 fracdiv;
184
185 fracdiv = readl(&pmucru->pmu_clksel_con[13]);
186 m = fracdiv & CLK_RTC32K_FRAC_NUMERATOR_MASK;
187 m >>= CLK_RTC32K_FRAC_NUMERATOR_SHIFT;
188 n = fracdiv & CLK_RTC32K_FRAC_DENOMINATOR_MASK;
189 n >>= CLK_RTC32K_FRAC_DENOMINATOR_SHIFT;
190
191 return OSC_HZ * m / n;
192 }
193
rv1126_rtc32k_set_pmuclk(struct rv1126_pmuclk_priv * priv,ulong rate)194 static ulong rv1126_rtc32k_set_pmuclk(struct rv1126_pmuclk_priv *priv,
195 ulong rate)
196 {
197 struct rv1126_pmucru *pmucru = priv->pmucru;
198 unsigned long m, n, val;
199
200 rk_clrsetreg(&pmucru->pmu_clksel_con[0], RTC32K_SEL_MASK,
201 RTC32K_SEL_OSC0_DIV32K << RTC32K_SEL_SHIFT);
202
203 rational_best_approximation(rate, OSC_HZ,
204 GENMASK(16 - 1, 0),
205 GENMASK(16 - 1, 0),
206 &m, &n);
207 val = m << CLK_RTC32K_FRAC_NUMERATOR_SHIFT | n;
208 writel(val, &pmucru->pmu_clksel_con[13]);
209
210 return rv1126_rtc32k_get_pmuclk(priv);
211 }
212
rv1126_i2c_get_pmuclk(struct rv1126_pmuclk_priv * priv,ulong clk_id)213 static ulong rv1126_i2c_get_pmuclk(struct rv1126_pmuclk_priv *priv,
214 ulong clk_id)
215 {
216 struct rv1126_pmucru *pmucru = priv->pmucru;
217 u32 div, con;
218
219 switch (clk_id) {
220 case CLK_I2C0:
221 con = readl(&pmucru->pmu_clksel_con[2]);
222 div = (con & CLK_I2C0_DIV_MASK) >> CLK_I2C0_DIV_SHIFT;
223 break;
224 case CLK_I2C2:
225 con = readl(&pmucru->pmu_clksel_con[3]);
226 div = (con & CLK_I2C1_DIV_MASK) >> CLK_I2C1_DIV_SHIFT;
227 break;
228 default:
229 return -ENOENT;
230 }
231
232 return DIV_TO_RATE(priv->gpll_hz, div);
233 }
234
rv1126_i2c_set_pmuclk(struct rv1126_pmuclk_priv * priv,ulong clk_id,ulong rate)235 static ulong rv1126_i2c_set_pmuclk(struct rv1126_pmuclk_priv *priv,
236 ulong clk_id, ulong rate)
237 {
238 struct rv1126_pmucru *pmucru = priv->pmucru;
239 int src_clk_div;
240
241 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
242 assert(src_clk_div - 1 <= 127);
243
244 switch (clk_id) {
245 case CLK_I2C0:
246 rk_clrsetreg(&pmucru->pmu_clksel_con[2], CLK_I2C0_DIV_MASK,
247 (src_clk_div - 1) << CLK_I2C0_DIV_SHIFT);
248 break;
249 case CLK_I2C2:
250 rk_clrsetreg(&pmucru->pmu_clksel_con[3], CLK_I2C2_DIV_MASK,
251 (src_clk_div - 1) << CLK_I2C2_DIV_SHIFT);
252 break;
253 default:
254 return -ENOENT;
255 }
256
257 return rv1126_i2c_get_pmuclk(priv, clk_id);
258 }
259
rv1126_pwm_get_pmuclk(struct rv1126_pmuclk_priv * priv,ulong clk_id)260 static ulong rv1126_pwm_get_pmuclk(struct rv1126_pmuclk_priv *priv,
261 ulong clk_id)
262 {
263 struct rv1126_pmucru *pmucru = priv->pmucru;
264 u32 div, sel, con;
265
266 switch (clk_id) {
267 case CLK_PWM0:
268 con = readl(&pmucru->pmu_clksel_con[6]);
269 sel = (con & CLK_PWM0_SEL_MASK) >> CLK_PWM0_SEL_SHIFT;
270 div = (con & CLK_PWM0_DIV_MASK) >> CLK_PWM0_DIV_SHIFT;
271 if (sel == CLK_PWM0_SEL_XIN24M)
272 return OSC_HZ;
273 break;
274 case CLK_PWM1:
275 con = readl(&pmucru->pmu_clksel_con[6]);
276 sel = (con & CLK_PWM1_SEL_MASK) >> CLK_PWM1_SEL_SHIFT;
277 div = (con & CLK_PWM1_DIV_MASK) >> CLK_PWM1_DIV_SHIFT;
278 if (sel == CLK_PWM1_SEL_XIN24M)
279 return OSC_HZ;
280 break;
281 default:
282 return -ENOENT;
283 }
284
285 return DIV_TO_RATE(priv->gpll_hz, div);
286 }
287
rv1126_pwm_set_pmuclk(struct rv1126_pmuclk_priv * priv,ulong clk_id,ulong rate)288 static ulong rv1126_pwm_set_pmuclk(struct rv1126_pmuclk_priv *priv,
289 ulong clk_id, ulong rate)
290 {
291 struct rv1126_pmucru *pmucru = priv->pmucru;
292 int src_clk_div;
293
294 switch (clk_id) {
295 case CLK_PWM0:
296 if (rate == OSC_HZ) {
297 rk_clrsetreg(&pmucru->pmu_clksel_con[6],
298 CLK_PWM0_SEL_MASK,
299 CLK_PWM0_SEL_XIN24M << CLK_PWM0_SEL_SHIFT);
300 rk_clrsetreg(&pmucru->pmu_clksel_con[6],
301 CLK_PWM0_DIV_MASK, 0);
302 } else {
303 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
304 assert(src_clk_div - 1 <= 127);
305 rk_clrsetreg(&pmucru->pmu_clksel_con[6],
306 CLK_PWM0_DIV_MASK,
307 (src_clk_div - 1) << CLK_PWM0_DIV_SHIFT);
308 rk_clrsetreg(&pmucru->pmu_clksel_con[6],
309 CLK_PWM0_SEL_MASK,
310 CLK_PWM0_SEL_GPLL << CLK_PWM0_SEL_SHIFT);
311 }
312 break;
313 case CLK_PWM1:
314 if (rate == OSC_HZ) {
315 rk_clrsetreg(&pmucru->pmu_clksel_con[6],
316 CLK_PWM1_SEL_MASK,
317 CLK_PWM1_SEL_XIN24M << CLK_PWM1_SEL_SHIFT);
318 rk_clrsetreg(&pmucru->pmu_clksel_con[6],
319 CLK_PWM1_DIV_MASK, 0);
320 } else {
321 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
322 assert(src_clk_div - 1 <= 127);
323 rk_clrsetreg(&pmucru->pmu_clksel_con[6],
324 CLK_PWM1_DIV_MASK,
325 (src_clk_div - 1) << CLK_PWM1_DIV_SHIFT);
326 rk_clrsetreg(&pmucru->pmu_clksel_con[6],
327 CLK_PWM1_SEL_MASK,
328 CLK_PWM1_SEL_GPLL << CLK_PWM1_SEL_SHIFT);
329 }
330 break;
331 default:
332 return -ENOENT;
333 }
334
335 return rv1126_pwm_get_pmuclk(priv, clk_id);
336 }
337
rv1126_spi_get_pmuclk(struct rv1126_pmuclk_priv * priv)338 static ulong rv1126_spi_get_pmuclk(struct rv1126_pmuclk_priv *priv)
339 {
340 struct rv1126_pmucru *pmucru = priv->pmucru;
341 u32 div, con;
342
343 con = readl(&pmucru->pmu_clksel_con[9]);
344 div = (con & CLK_SPI0_DIV_MASK) >> CLK_SPI0_DIV_SHIFT;
345
346 return DIV_TO_RATE(priv->gpll_hz, div);
347 }
348
rv1126_spi_set_pmuclk(struct rv1126_pmuclk_priv * priv,ulong rate)349 static ulong rv1126_spi_set_pmuclk(struct rv1126_pmuclk_priv *priv,
350 ulong rate)
351 {
352 struct rv1126_pmucru *pmucru = priv->pmucru;
353 int src_clk_div;
354
355 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
356 assert(src_clk_div - 1 <= 127);
357
358 rk_clrsetreg(&pmucru->pmu_clksel_con[9],
359 CLK_SPI0_SEL_MASK | CLK_SPI0_DIV_MASK,
360 CLK_SPI0_SEL_GPLL << CLK_SPI0_SEL_SHIFT |
361 (src_clk_div - 1) << CLK_SPI0_DIV_SHIFT);
362
363 return rv1126_spi_get_pmuclk(priv);
364 }
365
rv1126_pdpmu_get_pmuclk(struct rv1126_pmuclk_priv * priv)366 static ulong rv1126_pdpmu_get_pmuclk(struct rv1126_pmuclk_priv *priv)
367 {
368 struct rv1126_pmucru *pmucru = priv->pmucru;
369 u32 div, con;
370
371 con = readl(&pmucru->pmu_clksel_con[1]);
372 div = (con & PCLK_PDPMU_DIV_MASK) >> PCLK_PDPMU_DIV_SHIFT;
373
374 return DIV_TO_RATE(priv->gpll_hz, div);
375 }
376
rv1126_pdpmu_set_pmuclk(struct rv1126_pmuclk_priv * priv,ulong rate)377 static ulong rv1126_pdpmu_set_pmuclk(struct rv1126_pmuclk_priv *priv,
378 ulong rate)
379 {
380 struct rv1126_pmucru *pmucru = priv->pmucru;
381 int src_clk_div;
382
383 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
384 assert(src_clk_div - 1 <= 31);
385
386 rk_clrsetreg(&pmucru->pmu_clksel_con[1],
387 PCLK_PDPMU_DIV_MASK,
388 (src_clk_div - 1) << PCLK_PDPMU_DIV_SHIFT);
389
390 return rv1126_pdpmu_get_pmuclk(priv);
391 }
392
rv1126_pmuclk_get_rate(struct clk * clk)393 static ulong rv1126_pmuclk_get_rate(struct clk *clk)
394 {
395 struct rv1126_pmuclk_priv *priv = dev_get_priv(clk->dev);
396 ulong rate = 0;
397
398 if (!priv->gpll_hz) {
399 printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
400 return -ENOENT;
401 }
402
403 debug("%s %ld\n", __func__, clk->id);
404 switch (clk->id) {
405 case PLL_GPLL:
406 rate = rv1126_gpll_get_pmuclk(priv);
407 break;
408 case CLK_RTC32K:
409 rate = rv1126_rtc32k_get_pmuclk(priv);
410 break;
411 case CLK_I2C0:
412 case CLK_I2C2:
413 rate = rv1126_i2c_get_pmuclk(priv, clk->id);
414 break;
415 case CLK_PWM0:
416 case CLK_PWM1:
417 rate = rv1126_pwm_get_pmuclk(priv, clk->id);
418 break;
419 case CLK_SPI0:
420 rate = rv1126_spi_get_pmuclk(priv);
421 break;
422 case PCLK_PDPMU:
423 rate = rv1126_pdpmu_get_pmuclk(priv);
424 break;
425 default:
426 return -ENOENT;
427 }
428
429 return rate;
430 }
431
rv1126_pmuclk_set_rate(struct clk * clk,ulong rate)432 static ulong rv1126_pmuclk_set_rate(struct clk *clk, ulong rate)
433 {
434 struct rv1126_pmuclk_priv *priv = dev_get_priv(clk->dev);
435 ulong ret = 0;
436
437 if (!priv->gpll_hz) {
438 printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
439 return -ENOENT;
440 }
441
442 debug("%s %ld %ld\n", __func__, clk->id, rate);
443 switch (clk->id) {
444 case PLL_GPLL:
445 ret = rv1126_gpll_set_pmuclk(priv, rate);
446 break;
447 case CLK_RTC32K:
448 ret = rv1126_rtc32k_set_pmuclk(priv, rate);
449 break;
450 case CLK_I2C0:
451 case CLK_I2C2:
452 ret = rv1126_i2c_set_pmuclk(priv, clk->id, rate);
453 break;
454 case CLK_PWM0:
455 case CLK_PWM1:
456 ret = rv1126_pwm_set_pmuclk(priv, clk->id, rate);
457 break;
458 case CLK_SPI0:
459 ret = rv1126_spi_set_pmuclk(priv, rate);
460 break;
461 case PCLK_PDPMU:
462 ret = rv1126_pdpmu_set_pmuclk(priv, rate);
463 break;
464 default:
465 return -ENOENT;
466 }
467
468 return ret;
469 }
470
rv1126_rtc32k_set_parent(struct clk * clk,struct clk * parent)471 static int rv1126_rtc32k_set_parent(struct clk *clk, struct clk *parent)
472 {
473 struct rv1126_pmuclk_priv *priv = dev_get_priv(clk->dev);
474 struct rv1126_pmucru *pmucru = priv->pmucru;
475
476 if (parent->id == CLK_OSC0_DIV32K)
477 rk_clrsetreg(&pmucru->pmu_clksel_con[0], RTC32K_SEL_MASK,
478 RTC32K_SEL_OSC0_DIV32K << RTC32K_SEL_SHIFT);
479 else
480 rk_clrsetreg(&pmucru->pmu_clksel_con[0], RTC32K_SEL_MASK,
481 RTC32K_SEL_OSC1_32K << RTC32K_SEL_SHIFT);
482
483 return 0;
484 }
485
rv1126_pmuclk_set_parent(struct clk * clk,struct clk * parent)486 static int rv1126_pmuclk_set_parent(struct clk *clk, struct clk *parent)
487 {
488 switch (clk->id) {
489 case CLK_RTC32K:
490 return rv1126_rtc32k_set_parent(clk, parent);
491 default:
492 return -ENOENT;
493 }
494 }
495 static struct clk_ops rv1126_pmuclk_ops = {
496 .get_rate = rv1126_pmuclk_get_rate,
497 .set_rate = rv1126_pmuclk_set_rate,
498 .set_parent = rv1126_pmuclk_set_parent,
499 };
500
rv1126_pmuclk_probe(struct udevice * dev)501 static int rv1126_pmuclk_probe(struct udevice *dev)
502 {
503 struct rv1126_pmuclk_priv *priv = dev_get_priv(dev);
504
505 priv->gpll_hz = rv1126_gpll_get_pmuclk(priv);
506
507 return 0;
508 }
509
rv1126_pmuclk_ofdata_to_platdata(struct udevice * dev)510 static int rv1126_pmuclk_ofdata_to_platdata(struct udevice *dev)
511 {
512 struct rv1126_pmuclk_priv *priv = dev_get_priv(dev);
513
514 priv->pmucru = dev_read_addr_ptr(dev);
515
516 return 0;
517 }
518
rv1126_pmuclk_bind(struct udevice * dev)519 static int rv1126_pmuclk_bind(struct udevice *dev)
520 {
521 int ret = 0;
522 struct udevice *sf_child;
523 struct softreset_reg *sf_priv;
524
525 ret = device_bind_driver_to_node(dev, "rockchip_reset",
526 "reset", dev_ofnode(dev),
527 &sf_child);
528 if (ret) {
529 debug("Warning: No rockchip reset driver: ret=%d\n", ret);
530 } else {
531 sf_priv = malloc(sizeof(struct softreset_reg));
532 sf_priv->sf_reset_offset = offsetof(struct rv1126_pmucru,
533 pmu_softrst_con[0]);
534 sf_priv->sf_reset_num = 2;
535 sf_child->priv = sf_priv;
536 }
537
538 return 0;
539 }
540
541 static const struct udevice_id rv1126_pmuclk_ids[] = {
542 { .compatible = "rockchip,rv1126-pmucru" },
543 { }
544 };
545
546 U_BOOT_DRIVER(rockchip_rv1126_pmucru) = {
547 .name = "rockchip_rv1126_pmucru",
548 .id = UCLASS_CLK,
549 .of_match = rv1126_pmuclk_ids,
550 .priv_auto_alloc_size = sizeof(struct rv1126_pmuclk_priv),
551 .ofdata_to_platdata = rv1126_pmuclk_ofdata_to_platdata,
552 .ops = &rv1126_pmuclk_ops,
553 .bind = rv1126_pmuclk_bind,
554 .probe = rv1126_pmuclk_probe,
555 };
556
557
rv1126_armclk_set_clk(struct rv1126_clk_priv * priv,ulong hz)558 static int rv1126_armclk_set_clk(struct rv1126_clk_priv *priv, ulong hz)
559 {
560 struct rv1126_cru *cru = priv->cru;
561 const struct rockchip_cpu_rate_table *rate;
562 ulong old_rate;
563
564 rate = rockchip_get_cpu_settings(rv1126_cpu_rates, hz);
565 if (!rate) {
566 printf("%s unsupported rate\n", __func__);
567 return -EINVAL;
568 }
569
570 /*
571 * set up dependent divisors for DBG and ACLK clocks.
572 */
573 old_rate = rockchip_pll_get_rate(&rv1126_pll_clks[APLL],
574 priv->cru, APLL);
575 if (old_rate > hz) {
576 if (rockchip_pll_set_rate(&rv1126_pll_clks[APLL],
577 priv->cru, APLL, hz))
578 return -EINVAL;
579 rk_clrsetreg(&cru->clksel_con[1],
580 CORE_DBG_DIV_MASK | CORE_ACLK_DIV_MASK,
581 rate->pclk_div << CORE_DBG_DIV_SHIFT |
582 rate->aclk_div << CORE_ACLK_DIV_SHIFT);
583 } else if (old_rate < hz) {
584 rk_clrsetreg(&cru->clksel_con[1],
585 CORE_DBG_DIV_MASK | CORE_ACLK_DIV_MASK,
586 rate->pclk_div << CORE_DBG_DIV_SHIFT |
587 rate->aclk_div << CORE_ACLK_DIV_SHIFT);
588 if (rockchip_pll_set_rate(&rv1126_pll_clks[APLL],
589 priv->cru, APLL, hz))
590 return -EINVAL;
591 }
592
593 return 0;
594 }
595
rv1126_pdcore_get_clk(struct rv1126_clk_priv * priv)596 static ulong rv1126_pdcore_get_clk(struct rv1126_clk_priv *priv)
597 {
598 struct rv1126_cru *cru = priv->cru;
599 u32 con, div;
600
601 con = readl(&cru->clksel_con[0]);
602 div = (con & CORE_HCLK_DIV_MASK) >> CORE_HCLK_DIV_SHIFT;
603
604 return DIV_TO_RATE(priv->gpll_hz, div);
605 }
606
rv1126_pdcore_set_clk(struct rv1126_clk_priv * priv,ulong rate)607 static ulong rv1126_pdcore_set_clk(struct rv1126_clk_priv *priv, ulong rate)
608 {
609 struct rv1126_cru *cru = priv->cru;
610 int src_clk_div;
611 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
612 assert(src_clk_div - 1 <= 31);
613
614 rk_clrsetreg(&cru->clksel_con[0], CORE_HCLK_DIV_MASK,
615 (src_clk_div - 1) << CORE_HCLK_DIV_SHIFT);
616
617 return rv1126_pdcore_get_clk(priv);
618 }
619
rv1126_pdbus_get_clk(struct rv1126_clk_priv * priv,ulong clk_id)620 static ulong rv1126_pdbus_get_clk(struct rv1126_clk_priv *priv, ulong clk_id)
621 {
622 struct rv1126_cru *cru = priv->cru;
623 u32 con, div, sel, parent;
624
625 switch (clk_id) {
626 case ACLK_PDBUS:
627 con = readl(&cru->clksel_con[2]);
628 div = (con & ACLK_PDBUS_DIV_MASK) >> ACLK_PDBUS_DIV_SHIFT;
629 sel = (con & ACLK_PDBUS_SEL_MASK) >> ACLK_PDBUS_SEL_SHIFT;
630 if (sel == ACLK_PDBUS_SEL_GPLL)
631 parent = priv->gpll_hz;
632 else if (sel == ACLK_PDBUS_SEL_CPLL)
633 parent = priv->cpll_hz;
634 else
635 return -ENOENT;
636 break;
637 case HCLK_PDBUS:
638 con = readl(&cru->clksel_con[2]);
639 div = (con & HCLK_PDBUS_DIV_MASK) >> HCLK_PDBUS_DIV_SHIFT;
640 sel = (con & HCLK_PDBUS_SEL_MASK) >> HCLK_PDBUS_SEL_SHIFT;
641 if (sel == HCLK_PDBUS_SEL_GPLL)
642 parent = priv->gpll_hz;
643 else if (sel == HCLK_PDBUS_SEL_CPLL)
644 parent = priv->cpll_hz;
645 else
646 return -ENOENT;
647 break;
648 case PCLK_PDBUS:
649 case PCLK_WDT:
650 con = readl(&cru->clksel_con[3]);
651 div = (con & PCLK_PDBUS_DIV_MASK) >> PCLK_PDBUS_DIV_SHIFT;
652 sel = (con & PCLK_PDBUS_SEL_MASK) >> PCLK_PDBUS_SEL_SHIFT;
653 if (sel == PCLK_PDBUS_SEL_GPLL)
654 parent = priv->gpll_hz;
655 else if (sel == PCLK_PDBUS_SEL_CPLL)
656 parent = priv->cpll_hz;
657 else
658 return -ENOENT;
659 break;
660 default:
661 return -ENOENT;
662 }
663
664 return DIV_TO_RATE(parent, div);
665 }
666
rv1126_pdbus_set_clk(struct rv1126_clk_priv * priv,ulong clk_id,ulong rate)667 static ulong rv1126_pdbus_set_clk(struct rv1126_clk_priv *priv, ulong clk_id,
668 ulong rate)
669 {
670 struct rv1126_cru *cru = priv->cru;
671 int src_clk_div, clk_sel;
672
673 switch (clk_id) {
674 case ACLK_PDBUS:
675 if (CPLL_HZ % rate) {
676 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
677 clk_sel = ACLK_PDBUS_SEL_GPLL;
678 } else {
679 src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate);
680 clk_sel = ACLK_PDBUS_SEL_CPLL;
681 }
682 assert(src_clk_div - 1 <= 31);
683 rk_clrsetreg(&cru->clksel_con[2],
684 ACLK_PDBUS_SEL_MASK | ACLK_PDBUS_DIV_MASK,
685 clk_sel << ACLK_PDBUS_SEL_SHIFT |
686 (src_clk_div - 1) << ACLK_PDBUS_DIV_SHIFT);
687 break;
688 case HCLK_PDBUS:
689 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
690 assert(src_clk_div - 1 <= 31);
691 rk_clrsetreg(&cru->clksel_con[2],
692 HCLK_PDBUS_SEL_MASK | HCLK_PDBUS_DIV_MASK,
693 HCLK_PDBUS_SEL_GPLL << HCLK_PDBUS_SEL_SHIFT |
694 (src_clk_div - 1) << HCLK_PDBUS_DIV_SHIFT);
695 break;
696 case PCLK_PDBUS:
697 case PCLK_WDT:
698 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
699 assert(src_clk_div - 1 <= 31);
700 rk_clrsetreg(&cru->clksel_con[3],
701 PCLK_PDBUS_SEL_MASK | PCLK_PDBUS_DIV_MASK,
702 PCLK_PDBUS_SEL_GPLL << PCLK_PDBUS_SEL_SHIFT |
703 (src_clk_div - 1) << PCLK_PDBUS_DIV_SHIFT);
704 break;
705
706 default:
707 printf("do not support this pdbus freq\n");
708 return -EINVAL;
709 }
710
711 return rv1126_pdbus_get_clk(priv, clk_id);
712 }
713
rv1126_pdphp_get_clk(struct rv1126_clk_priv * priv,ulong clk_id)714 static ulong rv1126_pdphp_get_clk(struct rv1126_clk_priv *priv, ulong clk_id)
715 {
716 struct rv1126_cru *cru = priv->cru;
717 u32 con, div, parent;
718
719 switch (clk_id) {
720 case ACLK_PDPHP:
721 con = readl(&cru->clksel_con[53]);
722 div = (con & ACLK_PDPHP_DIV_MASK) >> ACLK_PDPHP_DIV_SHIFT;
723 parent = priv->gpll_hz;
724 break;
725 case HCLK_PDPHP:
726 con = readl(&cru->clksel_con[53]);
727 div = (con & HCLK_PDPHP_DIV_MASK) >> HCLK_PDPHP_DIV_SHIFT;
728 parent = priv->gpll_hz;
729 break;
730 default:
731 return -ENOENT;
732 }
733
734 return DIV_TO_RATE(parent, div);
735 }
736
rv1126_pdphp_set_clk(struct rv1126_clk_priv * priv,ulong clk_id,ulong rate)737 static ulong rv1126_pdphp_set_clk(struct rv1126_clk_priv *priv, ulong clk_id,
738 ulong rate)
739 {
740 struct rv1126_cru *cru = priv->cru;
741 int src_clk_div;
742
743 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
744 assert(src_clk_div - 1 <= 31);
745
746 switch (clk_id) {
747 case ACLK_PDPHP:
748 rk_clrsetreg(&cru->clksel_con[53],
749 ACLK_PDPHP_SEL_MASK | ACLK_PDPHP_DIV_MASK,
750 ACLK_PDPHP_SEL_GPLL << ACLK_PDPHP_SEL_SHIFT |
751 (src_clk_div - 1) << ACLK_PDPHP_DIV_SHIFT);
752 break;
753 case HCLK_PDPHP:
754 rk_clrsetreg(&cru->clksel_con[53],
755 HCLK_PDPHP_DIV_MASK,
756 (src_clk_div - 1) << HCLK_PDPHP_DIV_SHIFT);
757 break;
758 default:
759 printf("do not support this pdphp freq\n");
760 return -EINVAL;
761 }
762
763 return rv1126_pdphp_get_clk(priv, clk_id);
764 }
765
rv1126_pdaudio_get_clk(struct rv1126_clk_priv * priv)766 static ulong rv1126_pdaudio_get_clk(struct rv1126_clk_priv *priv)
767 {
768 struct rv1126_cru *cru = priv->cru;
769 u32 con, div;
770
771 con = readl(&cru->clksel_con[26]);
772 div = (con & HCLK_PDAUDIO_DIV_MASK) >> HCLK_PDAUDIO_DIV_SHIFT;
773
774 return DIV_TO_RATE(priv->gpll_hz, div);
775 }
776
rv1126_pdaudio_set_clk(struct rv1126_clk_priv * priv,ulong rate)777 static ulong rv1126_pdaudio_set_clk(struct rv1126_clk_priv *priv, ulong rate)
778 {
779 struct rv1126_cru *cru = priv->cru;
780 int src_clk_div;
781
782 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
783 assert(src_clk_div - 1 <= 31);
784
785 rk_clrsetreg(&cru->clksel_con[26], HCLK_PDAUDIO_DIV_MASK,
786 (src_clk_div - 1) << HCLK_PDAUDIO_DIV_SHIFT);
787
788 return rv1126_pdaudio_get_clk(priv);
789 }
790
rv1126_i2c_get_clk(struct rv1126_clk_priv * priv,ulong clk_id)791 static ulong rv1126_i2c_get_clk(struct rv1126_clk_priv *priv, ulong clk_id)
792 {
793 struct rv1126_cru *cru = priv->cru;
794 u32 div, con;
795
796 switch (clk_id) {
797 case CLK_I2C1:
798 con = readl(&cru->clksel_con[5]);
799 div = (con & CLK_I2C1_DIV_MASK) >> CLK_I2C1_DIV_SHIFT;
800 break;
801 case CLK_I2C3:
802 con = readl(&cru->clksel_con[5]);
803 div = (con & CLK_I2C3_DIV_MASK) >> CLK_I2C3_DIV_SHIFT;
804 break;
805 case CLK_I2C4:
806 con = readl(&cru->clksel_con[6]);
807 div = (con & CLK_I2C4_DIV_MASK) >> CLK_I2C4_DIV_SHIFT;
808 break;
809 case CLK_I2C5:
810 con = readl(&cru->clksel_con[6]);
811 div = (con & CLK_I2C5_DIV_MASK) >> CLK_I2C5_DIV_SHIFT;
812 break;
813 default:
814 return -ENOENT;
815 }
816
817 return DIV_TO_RATE(priv->gpll_hz, div);
818 }
819
rv1126_i2c_set_clk(struct rv1126_clk_priv * priv,ulong clk_id,ulong rate)820 static ulong rv1126_i2c_set_clk(struct rv1126_clk_priv *priv, ulong clk_id,
821 ulong rate)
822 {
823 struct rv1126_cru *cru = priv->cru;
824 int src_clk_div;
825
826 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
827 assert(src_clk_div - 1 <= 127);
828
829 switch (clk_id) {
830 case CLK_I2C1:
831 rk_clrsetreg(&cru->clksel_con[5], CLK_I2C1_DIV_MASK,
832 (src_clk_div - 1) << CLK_I2C1_DIV_SHIFT);
833 break;
834 case CLK_I2C3:
835 rk_clrsetreg(&cru->clksel_con[5], CLK_I2C3_DIV_MASK,
836 (src_clk_div - 1) << CLK_I2C3_DIV_SHIFT);
837 break;
838 case CLK_I2C4:
839 rk_clrsetreg(&cru->clksel_con[6], CLK_I2C4_DIV_MASK,
840 (src_clk_div - 1) << CLK_I2C4_DIV_SHIFT);
841 break;
842 case CLK_I2C5:
843 rk_clrsetreg(&cru->clksel_con[6], CLK_I2C5_DIV_MASK,
844 (src_clk_div - 1) << CLK_I2C5_DIV_SHIFT);
845 break;
846 default:
847 return -ENOENT;
848 }
849
850 return rv1126_i2c_get_clk(priv, clk_id);
851 }
852
rv1126_spi_get_clk(struct rv1126_clk_priv * priv)853 static ulong rv1126_spi_get_clk(struct rv1126_clk_priv *priv)
854 {
855 struct rv1126_cru *cru = priv->cru;
856 u32 div, con;
857
858 con = readl(&cru->clksel_con[8]);
859 div = (con & CLK_SPI1_DIV_MASK) >> CLK_SPI1_DIV_SHIFT;
860
861 return DIV_TO_RATE(priv->gpll_hz, div);
862 }
863
rv1126_spi_set_clk(struct rv1126_clk_priv * priv,ulong rate)864 static ulong rv1126_spi_set_clk(struct rv1126_clk_priv *priv, ulong rate)
865 {
866 struct rv1126_cru *cru = priv->cru;
867 int src_clk_div;
868
869 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
870 assert(src_clk_div - 1 <= 127);
871
872 rk_clrsetreg(&cru->clksel_con[8],
873 CLK_SPI1_SEL_MASK | CLK_SPI1_DIV_MASK,
874 CLK_SPI1_SEL_GPLL << CLK_SPI1_SEL_SHIFT |
875 (src_clk_div - 1) << CLK_SPI1_DIV_SHIFT);
876
877 return rv1126_spi_get_clk(priv);
878 }
879
rv1126_pwm_get_clk(struct rv1126_clk_priv * priv)880 static ulong rv1126_pwm_get_clk(struct rv1126_clk_priv *priv)
881 {
882 struct rv1126_cru *cru = priv->cru;
883 u32 div, sel, con;
884
885 con = readl(&cru->clksel_con[9]);
886 sel = (con & CLK_PWM2_SEL_MASK) >> CLK_PWM2_SEL_SHIFT;
887 div = (con & CLK_PWM2_DIV_MASK) >> CLK_PWM2_DIV_SHIFT;
888 if (sel == CLK_PWM2_SEL_XIN24M)
889 return OSC_HZ;
890
891 return DIV_TO_RATE(priv->gpll_hz, div);
892 }
893
rv1126_pwm_set_clk(struct rv1126_clk_priv * priv,ulong rate)894 static ulong rv1126_pwm_set_clk(struct rv1126_clk_priv *priv, ulong rate)
895 {
896 struct rv1126_cru *cru = priv->cru;
897 int src_clk_div;
898
899 if (rate == OSC_HZ) {
900 rk_clrsetreg(&cru->clksel_con[9], CLK_PWM2_SEL_MASK,
901 CLK_PWM2_SEL_XIN24M << CLK_PWM2_SEL_SHIFT);
902 rk_clrsetreg(&cru->clksel_con[9], CLK_PWM2_DIV_MASK, 0);
903 } else {
904 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
905 assert(src_clk_div - 1 <= 127);
906 rk_clrsetreg(&cru->clksel_con[9], CLK_PWM2_DIV_MASK,
907 (src_clk_div - 1) << CLK_PWM2_DIV_SHIFT);
908 rk_clrsetreg(&cru->clksel_con[9], CLK_PWM2_SEL_MASK,
909 CLK_PWM2_SEL_GPLL << CLK_PWM2_SEL_SHIFT);
910 }
911
912 return rv1126_pwm_get_clk(priv);
913 }
914
rv1126_saradc_get_clk(struct rv1126_clk_priv * priv)915 static ulong rv1126_saradc_get_clk(struct rv1126_clk_priv *priv)
916 {
917 struct rv1126_cru *cru = priv->cru;
918 u32 div, con;
919
920 con = readl(&cru->clksel_con[20]);
921 div = (con & CLK_SARADC_DIV_MASK) >> CLK_SARADC_DIV_SHIFT;
922
923 return DIV_TO_RATE(OSC_HZ, div);
924 }
925
rv1126_saradc_set_clk(struct rv1126_clk_priv * priv,ulong rate)926 static ulong rv1126_saradc_set_clk(struct rv1126_clk_priv *priv, ulong rate)
927 {
928 struct rv1126_cru *cru = priv->cru;
929 int src_clk_div;
930
931 src_clk_div = DIV_ROUND_UP(OSC_HZ, rate);
932 assert(src_clk_div - 1 <= 2047);
933 rk_clrsetreg(&cru->clksel_con[20], CLK_SARADC_DIV_MASK,
934 (src_clk_div - 1) << CLK_SARADC_DIV_SHIFT);
935
936 return rv1126_saradc_get_clk(priv);
937 }
938
rv1126_crypto_get_clk(struct rv1126_clk_priv * priv,ulong clk_id)939 static ulong rv1126_crypto_get_clk(struct rv1126_clk_priv *priv, ulong clk_id)
940 {
941 struct rv1126_cru *cru = priv->cru;
942 u32 div, sel, con, parent;
943
944 switch (clk_id) {
945 case CLK_CRYPTO_CORE:
946 con = readl(&cru->clksel_con[7]);
947 div = (con & CLK_CRYPTO_CORE_DIV_MASK) >> CLK_CRYPTO_CORE_DIV_SHIFT;
948 sel = (con & CLK_CRYPTO_CORE_SEL_MASK) >> CLK_CRYPTO_CORE_SEL_SHIFT;
949 if (sel == CLK_CRYPTO_CORE_SEL_GPLL)
950 parent = priv->gpll_hz;
951 else if (sel == CLK_CRYPTO_CORE_SEL_CPLL)
952 parent = priv->cpll_hz;
953 else
954 return -ENOENT;
955 break;
956 case CLK_CRYPTO_PKA:
957 con = readl(&cru->clksel_con[7]);
958 div = (con & CLK_CRYPTO_PKA_DIV_MASK) >> CLK_CRYPTO_PKA_DIV_SHIFT;
959 sel = (con & CLK_CRYPTO_PKA_SEL_MASK) >> CLK_CRYPTO_PKA_SEL_SHIFT;
960 if (sel == CLK_CRYPTO_PKA_SEL_GPLL)
961 parent = priv->gpll_hz;
962 else if (sel == CLK_CRYPTO_PKA_SEL_CPLL)
963 parent = priv->cpll_hz;
964 else
965 return -ENOENT;
966 break;
967 case ACLK_CRYPTO:
968 con = readl(&cru->clksel_con[4]);
969 div = (con & ACLK_CRYPTO_DIV_MASK) >> ACLK_CRYPTO_DIV_SHIFT;
970 sel = (con & ACLK_CRYPTO_SEL_MASK) >> ACLK_CRYPTO_SEL_SHIFT;
971 if (sel == ACLK_CRYPTO_SEL_GPLL)
972 parent = priv->gpll_hz;
973 else if (sel == ACLK_CRYPTO_SEL_CPLL)
974 parent = priv->cpll_hz;
975 else
976 return -ENOENT;
977 break;
978 default:
979 return -ENOENT;
980 }
981
982 return DIV_TO_RATE(parent, div);
983 }
984
rv1126_crypto_set_clk(struct rv1126_clk_priv * priv,ulong clk_id,ulong rate)985 static ulong rv1126_crypto_set_clk(struct rv1126_clk_priv *priv, ulong clk_id,
986 ulong rate)
987 {
988 struct rv1126_cru *cru = priv->cru;
989 int src_clk_div;
990
991 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
992 assert(src_clk_div - 1 <= 31);
993
994 switch (clk_id) {
995 case CLK_CRYPTO_CORE:
996 rk_clrsetreg(&cru->clksel_con[7],
997 CLK_CRYPTO_CORE_SEL_MASK |
998 CLK_CRYPTO_CORE_DIV_MASK,
999 CLK_CRYPTO_CORE_SEL_GPLL <<
1000 CLK_CRYPTO_CORE_SEL_SHIFT |
1001 (src_clk_div - 1) << CLK_CRYPTO_CORE_DIV_SHIFT);
1002 break;
1003 case CLK_CRYPTO_PKA:
1004 rk_clrsetreg(&cru->clksel_con[7],
1005 CLK_CRYPTO_PKA_SEL_MASK |
1006 CLK_CRYPTO_PKA_DIV_MASK,
1007 CLK_CRYPTO_PKA_SEL_GPLL <<
1008 CLK_CRYPTO_PKA_SEL_SHIFT |
1009 (src_clk_div - 1) << CLK_CRYPTO_PKA_DIV_SHIFT);
1010 break;
1011 case ACLK_CRYPTO:
1012 rk_clrsetreg(&cru->clksel_con[4],
1013 ACLK_CRYPTO_SEL_MASK | ACLK_CRYPTO_DIV_MASK,
1014 ACLK_CRYPTO_SEL_GPLL << ACLK_CRYPTO_SEL_SHIFT |
1015 (src_clk_div - 1) << ACLK_CRYPTO_DIV_SHIFT);
1016 break;
1017 default:
1018 return -ENOENT;
1019 }
1020
1021 return rv1126_crypto_get_clk(priv, clk_id);
1022 }
1023
rv1126_mmc_get_clk(struct rv1126_clk_priv * priv,ulong clk_id)1024 static ulong rv1126_mmc_get_clk(struct rv1126_clk_priv *priv, ulong clk_id)
1025 {
1026 struct rv1126_cru *cru = priv->cru;
1027 u32 div, sel, con, con_id;
1028
1029 switch (clk_id) {
1030 case HCLK_SDMMC:
1031 case CLK_SDMMC:
1032 con_id = 55;
1033 break;
1034 case HCLK_SDIO:
1035 case CLK_SDIO:
1036 con_id = 56;
1037 break;
1038 case HCLK_EMMC:
1039 case CLK_EMMC:
1040 case SCLK_EMMC_SAMPLE:
1041 con_id = 57;
1042 break;
1043 default:
1044 return -ENOENT;
1045 }
1046
1047 con = readl(&cru->clksel_con[con_id]);
1048 div = (con & EMMC_DIV_MASK) >> EMMC_DIV_SHIFT;
1049 sel = (con & EMMC_SEL_MASK) >> EMMC_SEL_SHIFT;
1050 if (sel == EMMC_SEL_GPLL)
1051 return DIV_TO_RATE(priv->gpll_hz, div) / 2;
1052 else if (sel == EMMC_SEL_CPLL)
1053 return DIV_TO_RATE(priv->cpll_hz, div) / 2;
1054 else if (sel == EMMC_SEL_XIN24M)
1055 return DIV_TO_RATE(OSC_HZ, div) / 2;
1056
1057 return -ENOENT;
1058 }
1059
rv1126_mmc_set_clk(struct rv1126_clk_priv * priv,ulong clk_id,ulong rate)1060 static ulong rv1126_mmc_set_clk(struct rv1126_clk_priv *priv, ulong clk_id,
1061 ulong rate)
1062 {
1063 struct rv1126_cru *cru = priv->cru;
1064 int src_clk_div;
1065 u32 con_id;
1066
1067 switch (clk_id) {
1068 case HCLK_SDMMC:
1069 case CLK_SDMMC:
1070 con_id = 55;
1071 break;
1072 case HCLK_SDIO:
1073 case CLK_SDIO:
1074 con_id = 56;
1075 break;
1076 case HCLK_EMMC:
1077 case CLK_EMMC:
1078 con_id = 57;
1079 break;
1080 default:
1081 return -ENOENT;
1082 }
1083
1084 /* Select clk_sdmmc/emmc source from GPLL by default */
1085 /* mmc clock defaulg div 2 internal, need provide double in cru */
1086 src_clk_div = DIV_ROUND_UP(priv->gpll_hz / 2, rate);
1087
1088 if (src_clk_div > 127) {
1089 /* use 24MHz source for 400KHz clock */
1090 src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, rate);
1091 rk_clrsetreg(&cru->clksel_con[con_id],
1092 EMMC_SEL_MASK | EMMC_DIV_MASK,
1093 EMMC_SEL_XIN24M << EMMC_SEL_SHIFT |
1094 (src_clk_div - 1) << EMMC_DIV_SHIFT);
1095 } else {
1096 rk_clrsetreg(&cru->clksel_con[con_id],
1097 EMMC_SEL_MASK | EMMC_DIV_MASK,
1098 EMMC_SEL_GPLL << EMMC_SEL_SHIFT |
1099 (src_clk_div - 1) << EMMC_DIV_SHIFT);
1100 }
1101
1102 return rv1126_mmc_get_clk(priv, clk_id);
1103 }
1104
rv1126_sfc_get_clk(struct rv1126_clk_priv * priv)1105 static ulong rv1126_sfc_get_clk(struct rv1126_clk_priv *priv)
1106 {
1107 struct rv1126_cru *cru = priv->cru;
1108 u32 div, sel, con, parent;
1109
1110 con = readl(&cru->clksel_con[58]);
1111 div = (con & SCLK_SFC_DIV_MASK) >> SCLK_SFC_DIV_SHIFT;
1112 sel = (con & SCLK_SFC_SEL_MASK) >> SCLK_SFC_SEL_SHIFT;
1113 if (sel == SCLK_SFC_SEL_GPLL)
1114 parent = priv->gpll_hz;
1115 else if (sel == SCLK_SFC_SEL_CPLL)
1116 parent = priv->cpll_hz;
1117 else
1118 return -ENOENT;
1119
1120 return DIV_TO_RATE(parent, div);
1121 }
1122
rv1126_sfc_set_clk(struct rv1126_clk_priv * priv,ulong rate)1123 static ulong rv1126_sfc_set_clk(struct rv1126_clk_priv *priv, ulong rate)
1124 {
1125 struct rv1126_cru *cru = priv->cru;
1126 int src_clk_div;
1127
1128 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
1129 rk_clrsetreg(&cru->clksel_con[58],
1130 SCLK_SFC_SEL_MASK | SCLK_SFC_DIV_MASK,
1131 SCLK_SFC_SEL_GPLL << SCLK_SFC_SEL_SHIFT |
1132 (src_clk_div - 1) << SCLK_SFC_DIV_SHIFT);
1133
1134 return rv1126_sfc_get_clk(priv);
1135 }
1136
rv1126_nand_get_clk(struct rv1126_clk_priv * priv)1137 static ulong rv1126_nand_get_clk(struct rv1126_clk_priv *priv)
1138 {
1139 struct rv1126_cru *cru = priv->cru;
1140 u32 div, sel, con, parent;
1141
1142 con = readl(&cru->clksel_con[59]);
1143 div = (con & CLK_NANDC_DIV_MASK) >> CLK_NANDC_DIV_SHIFT;
1144 sel = (con & CLK_NANDC_SEL_MASK) >> CLK_NANDC_SEL_SHIFT;
1145 if (sel == CLK_NANDC_SEL_GPLL)
1146 parent = priv->gpll_hz;
1147 else if (sel == CLK_NANDC_SEL_CPLL)
1148 parent = priv->cpll_hz;
1149 else
1150 return -ENOENT;
1151
1152 return DIV_TO_RATE(parent, div);
1153 }
1154
rv1126_nand_set_clk(struct rv1126_clk_priv * priv,ulong rate)1155 static ulong rv1126_nand_set_clk(struct rv1126_clk_priv *priv, ulong rate)
1156 {
1157 struct rv1126_cru *cru = priv->cru;
1158 int src_clk_div;
1159
1160 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
1161 rk_clrsetreg(&cru->clksel_con[59],
1162 CLK_NANDC_SEL_MASK | CLK_NANDC_DIV_MASK,
1163 CLK_NANDC_SEL_GPLL << CLK_NANDC_SEL_SHIFT |
1164 (src_clk_div - 1) << CLK_NANDC_DIV_SHIFT);
1165
1166 return rv1126_nand_get_clk(priv);
1167 }
1168
rv1126_aclk_vop_get_clk(struct rv1126_clk_priv * priv)1169 static ulong rv1126_aclk_vop_get_clk(struct rv1126_clk_priv *priv)
1170 {
1171 struct rv1126_cru *cru = priv->cru;
1172 u32 div, sel, con, parent;
1173
1174 con = readl(&cru->clksel_con[45]);
1175 div = (con & ACLK_PDVO_DIV_MASK) >> ACLK_PDVO_DIV_SHIFT;
1176 sel = (con & ACLK_PDVO_SEL_MASK) >> ACLK_PDVO_SEL_SHIFT;
1177 if (sel == ACLK_PDVO_SEL_GPLL)
1178 parent = priv->gpll_hz;
1179 else if (sel == ACLK_PDVO_SEL_CPLL)
1180 parent = priv->cpll_hz;
1181 else
1182 return -ENOENT;
1183
1184 return DIV_TO_RATE(parent, div);
1185 }
1186
rv1126_aclk_vop_set_clk(struct rv1126_clk_priv * priv,ulong rate)1187 static ulong rv1126_aclk_vop_set_clk(struct rv1126_clk_priv *priv, ulong rate)
1188 {
1189 struct rv1126_cru *cru = priv->cru;
1190 int src_clk_div;
1191
1192 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
1193 assert(src_clk_div - 1 <= 31);
1194 rk_clrsetreg(&cru->clksel_con[45],
1195 ACLK_PDVO_SEL_MASK | ACLK_PDVO_DIV_MASK,
1196 ACLK_PDVO_SEL_GPLL << ACLK_PDVO_SEL_SHIFT |
1197 (src_clk_div - 1) << ACLK_PDVO_DIV_SHIFT);
1198
1199 return rv1126_aclk_vop_get_clk(priv);
1200 }
1201
rv1126_dclk_vop_get_clk(struct rv1126_clk_priv * priv)1202 static ulong rv1126_dclk_vop_get_clk(struct rv1126_clk_priv *priv)
1203 {
1204 struct rv1126_cru *cru = priv->cru;
1205 u32 div, sel, con, parent;
1206
1207 con = readl(&cru->clksel_con[47]);
1208 div = (con & DCLK_VOP_DIV_MASK) >> DCLK_VOP_DIV_SHIFT;
1209 sel = (con & DCLK_VOP_SEL_MASK) >> DCLK_VOP_SEL_SHIFT;
1210 if (sel == DCLK_VOP_SEL_GPLL)
1211 parent = priv->gpll_hz;
1212 else if (sel == DCLK_VOP_SEL_CPLL)
1213 parent = priv->cpll_hz;
1214 else
1215 return -ENOENT;
1216
1217 return DIV_TO_RATE(parent, div);
1218 }
1219
rv1126_dclk_vop_set_clk(struct rv1126_clk_priv * priv,ulong rate)1220 static ulong rv1126_dclk_vop_set_clk(struct rv1126_clk_priv *priv, ulong rate)
1221 {
1222 struct rv1126_cru *cru = priv->cru;
1223 ulong pll_rate, now, best_rate = 0;
1224 u32 i, div, best_div = 0, best_sel = 0;
1225
1226 for (i = 0; i <= DCLK_VOP_SEL_CPLL; i++) {
1227 switch (i) {
1228 case DCLK_VOP_SEL_GPLL:
1229 pll_rate = priv->gpll_hz;
1230 break;
1231 case DCLK_VOP_SEL_CPLL:
1232 pll_rate = priv->cpll_hz;
1233 break;
1234 default:
1235 printf("do not support this vop pll sel\n");
1236 return -EINVAL;
1237 }
1238
1239 div = DIV_ROUND_UP(pll_rate, rate);
1240 if (div > 255)
1241 continue;
1242 now = pll_rate / div;
1243 if (abs(rate - now) < abs(rate - best_rate)) {
1244 best_rate = now;
1245 best_div = div;
1246 best_sel = i;
1247 }
1248 debug("pll_rate=%lu, best_rate=%lu, best_div=%u, best_sel=%u\n",
1249 pll_rate, best_rate, best_div, best_sel);
1250 }
1251
1252 if (best_rate) {
1253 rk_clrsetreg(&cru->clksel_con[47],
1254 DCLK_VOP_SEL_MASK | DCLK_VOP_DIV_MASK,
1255 best_sel << DCLK_VOP_SEL_SHIFT |
1256 (best_div - 1) << DCLK_VOP_DIV_SHIFT);
1257 } else {
1258 printf("do not support this vop freq %lu\n", rate);
1259 return -EINVAL;
1260 }
1261
1262
1263 return rv1126_dclk_vop_get_clk(priv);
1264 }
1265
rv1126_scr1_get_clk(struct rv1126_clk_priv * priv)1266 static ulong rv1126_scr1_get_clk(struct rv1126_clk_priv *priv)
1267 {
1268 struct rv1126_cru *cru = priv->cru;
1269 u32 div, sel, con, parent;
1270
1271 con = readl(&cru->clksel_con[3]);
1272 div = (con & CLK_SCR1_DIV_MASK) >> CLK_SCR1_DIV_SHIFT;
1273 sel = (con & CLK_SCR1_SEL_MASK) >> CLK_SCR1_SEL_SHIFT;
1274 if (sel == CLK_SCR1_SEL_GPLL)
1275 parent = priv->gpll_hz;
1276 else if (sel == CLK_SCR1_SEL_CPLL)
1277 parent = priv->cpll_hz;
1278 else
1279 return -ENOENT;
1280
1281 return DIV_TO_RATE(parent, div);
1282 }
1283
rv1126_scr1_set_clk(struct rv1126_clk_priv * priv,ulong rate)1284 static ulong rv1126_scr1_set_clk(struct rv1126_clk_priv *priv, ulong rate)
1285 {
1286 struct rv1126_cru *cru = priv->cru;
1287 int src_clk_div;
1288
1289 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
1290 assert(src_clk_div - 1 <= 31);
1291 rk_clrsetreg(&cru->clksel_con[3],
1292 CLK_SCR1_SEL_MASK | CLK_SCR1_DIV_MASK,
1293 CLK_SCR1_SEL_GPLL << CLK_SCR1_SEL_SHIFT |
1294 (src_clk_div - 1) << CLK_SCR1_DIV_SHIFT);
1295
1296 return rv1126_scr1_get_clk(priv);
1297 }
1298
rv1126_gmac_src_get_clk(struct rv1126_clk_priv * priv)1299 static ulong rv1126_gmac_src_get_clk(struct rv1126_clk_priv *priv)
1300 {
1301 struct rv1126_cru *cru = priv->cru;
1302 u32 div, sel, con, parent;
1303
1304 con = readl(&cru->clksel_con[63]);
1305 div = (con & CLK_GMAC_SRC_DIV_MASK) >> CLK_GMAC_SRC_DIV_SHIFT;
1306 sel = (con & CLK_GMAC_SRC_SEL_MASK) >> CLK_GMAC_SRC_SEL_SHIFT;
1307 if (sel == CLK_GMAC_SRC_SEL_CPLL)
1308 parent = priv->cpll_hz;
1309 else if (sel == CLK_GMAC_SRC_SEL_GPLL)
1310 parent = priv->gpll_hz;
1311 else
1312 return -ENOENT;
1313
1314 return DIV_TO_RATE(parent, div);
1315 }
1316
rv1126_gmac_src_set_clk(struct rv1126_clk_priv * priv,ulong rate)1317 static ulong rv1126_gmac_src_set_clk(struct rv1126_clk_priv *priv, ulong rate)
1318 {
1319 struct rv1126_cru *cru = priv->cru;
1320 int src_clk_div;
1321
1322 src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate);
1323 assert(src_clk_div - 1 <= 31);
1324 rk_clrsetreg(&cru->clksel_con[63],
1325 CLK_GMAC_SRC_SEL_MASK | CLK_GMAC_SRC_DIV_MASK,
1326 CLK_GMAC_SRC_SEL_CPLL << CLK_GMAC_SRC_SEL_SHIFT |
1327 (src_clk_div - 1) << CLK_GMAC_SRC_DIV_SHIFT);
1328
1329 return rv1126_gmac_src_get_clk(priv);
1330 }
1331
rv1126_gmac_out_get_clk(struct rv1126_clk_priv * priv)1332 static ulong rv1126_gmac_out_get_clk(struct rv1126_clk_priv *priv)
1333 {
1334 struct rv1126_cru *cru = priv->cru;
1335 u32 div, sel, con, parent;
1336
1337 con = readl(&cru->clksel_con[61]);
1338 div = (con & CLK_GMAC_OUT_DIV_MASK) >> CLK_GMAC_OUT_DIV_SHIFT;
1339 sel = (con & CLK_GMAC_OUT_SEL_MASK) >> CLK_GMAC_OUT_SEL_SHIFT;
1340 if (sel == CLK_GMAC_OUT_SEL_CPLL)
1341 parent = priv->cpll_hz;
1342 else if (sel == CLK_GMAC_OUT_SEL_GPLL)
1343 parent = priv->gpll_hz;
1344 else
1345 return -ENOENT;
1346
1347 return DIV_TO_RATE(parent, div);
1348 }
1349
rv1126_gmac_out_set_clk(struct rv1126_clk_priv * priv,ulong rate)1350 static ulong rv1126_gmac_out_set_clk(struct rv1126_clk_priv *priv, ulong rate)
1351 {
1352 struct rv1126_cru *cru = priv->cru;
1353 int src_clk_div;
1354
1355 src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate);
1356 assert(src_clk_div - 1 <= 31);
1357 rk_clrsetreg(&cru->clksel_con[61],
1358 CLK_GMAC_OUT_SEL_MASK | CLK_GMAC_OUT_DIV_MASK,
1359 CLK_GMAC_OUT_SEL_CPLL << CLK_GMAC_OUT_SEL_SHIFT |
1360 (src_clk_div - 1) << CLK_GMAC_OUT_DIV_SHIFT);
1361
1362 return rv1126_gmac_out_get_clk(priv);
1363 }
1364
rv1126_gmac_tx_rx_set_clk(struct rv1126_clk_priv * priv,ulong rate)1365 static ulong rv1126_gmac_tx_rx_set_clk(struct rv1126_clk_priv *priv, ulong rate)
1366 {
1367 struct rv1126_cru *cru = priv->cru;
1368 u32 con, sel, div_sel;
1369
1370 con = readl(&cru->gmac_con);
1371 sel = (con & GMAC_MODE_SEL_MASK) >> GMAC_MODE_SEL_SHIFT;
1372
1373 if (sel == GMAC_RGMII_MODE) {
1374 if (rate == 2500000)
1375 div_sel = RGMII_CLK_DIV50;
1376 else if (rate == 25000000)
1377 div_sel = RGMII_CLK_DIV5;
1378 else
1379 div_sel = RGMII_CLK_DIV0;
1380 rk_clrsetreg(&cru->gmac_con, RGMII_CLK_SEL_MASK,
1381 div_sel << RGMII_CLK_SEL_SHIFT);
1382 } else if (sel == GMAC_RMII_MODE) {
1383 if (rate == 2500000)
1384 div_sel = RMII_CLK_DIV20;
1385 else
1386 div_sel = RMII_CLK_DIV2;
1387 rk_clrsetreg(&cru->gmac_con, RMII_CLK_SEL_MASK,
1388 div_sel << RMII_CLK_SEL_SHIFT);
1389 }
1390
1391 return 0;
1392 }
1393
rv1126_pclk_gmac_get_clk(struct rv1126_clk_priv * priv)1394 static ulong rv1126_pclk_gmac_get_clk(struct rv1126_clk_priv *priv)
1395 {
1396 struct rv1126_cru *cru = priv->cru;
1397 u32 div, con, parent;
1398
1399 parent = rv1126_pdphp_get_clk(priv, ACLK_PDPHP);
1400
1401 con = readl(&cru->clksel_con[63]);
1402 div = (con & PCLK_GMAC_DIV_MASK) >> PCLK_GMAC_DIV_SHIFT;
1403
1404 return DIV_TO_RATE(parent, div);
1405 }
1406
1407 #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_KERNEL_BOOT)
rv1126_clk_mipicsi_out_get_clk(struct rv1126_clk_priv * priv)1408 static ulong rv1126_clk_mipicsi_out_get_clk(struct rv1126_clk_priv *priv)
1409 {
1410 struct rv1126_cru *cru = priv->cru;
1411 u32 div, fracdiv, sel, con, n, m, parent = priv->gpll_hz;
1412
1413 con = readl(&cru->clksel_con[73]);
1414 div = (con & MIPICSI_OUT_DIV_MASK) >> MIPICSI_OUT_DIV_SHIFT;
1415 sel = (con & MIPICSI_OUT_SEL_MASK) >> MIPICSI_OUT_SEL_SHIFT;
1416 if (sel == MIPICSI_OUT_SEL_XIN24M) {
1417 return OSC_HZ;
1418 } else if (sel == MIPICSI_OUT_SEL_FRACDIV) {
1419 parent = DIV_TO_RATE(parent, div);
1420 fracdiv = readl(&cru->clksel_con[74]);
1421 n = (fracdiv & 0xffff0000) >> 16;
1422 m = fracdiv & 0xffff;
1423 return parent * n / m;
1424 }
1425
1426 return DIV_TO_RATE(parent, div);
1427 }
1428
rv1126_clk_mipicsi_out_set_clk(struct rv1126_clk_priv * priv,ulong rate)1429 static ulong rv1126_clk_mipicsi_out_set_clk(struct rv1126_clk_priv *priv,
1430 ulong rate)
1431 { struct rv1126_cru *cru = priv->cru;
1432 int src_clk_div;
1433
1434 if (rate == OSC_HZ) {
1435 rk_clrsetreg(&cru->clksel_con[73], MIPICSI_OUT_SEL_MASK,
1436 MIPICSI_OUT_SEL_XIN24M << MIPICSI_OUT_SEL_SHIFT);
1437 } else if (rate == 27000000) {
1438 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, 297000000);
1439 rk_clrsetreg(&cru->clksel_con[73], MIPICSI_OUT_DIV_MASK,
1440 (src_clk_div - 1) << MIPICSI_OUT_DIV_SHIFT);
1441 rk_clrsetreg(&cru->clksel_con[73], MIPICSI_OUT_SEL_MASK,
1442 MIPICSI_OUT_SEL_FRACDIV << MIPICSI_OUT_SEL_SHIFT);
1443 writel(4 << 16 | 44, &cru->clksel_con[74]);
1444 } else {
1445 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
1446 assert(src_clk_div - 1 <= 31);
1447 rk_clrsetreg(&cru->clksel_con[73], MIPICSI_OUT_DIV_MASK,
1448 (src_clk_div - 1) << MIPICSI_OUT_DIV_SHIFT);
1449 rk_clrsetreg(&cru->clksel_con[73], MIPICSI_OUT_SEL_MASK,
1450 MIPICSI_OUT_SEL_DIV << MIPICSI_OUT_SEL_SHIFT);
1451 }
1452
1453 return rv1126_clk_mipicsi_out_get_clk(priv);
1454 }
1455
rv1126_clk_pdvi_ispp_get_clk(struct rv1126_clk_priv * priv,ulong clk_id)1456 static ulong rv1126_clk_pdvi_ispp_get_clk(struct rv1126_clk_priv *priv,
1457 ulong clk_id)
1458 {
1459 struct rv1126_cru *cru = priv->cru;
1460 u32 div, sel, con, parent, con_id;
1461
1462 switch (clk_id) {
1463 case ACLK_PDVI:
1464 con_id = 49;
1465 break;
1466 case ACLK_PDISPP:
1467 con_id = 68;
1468 break;
1469 case CLK_ISPP:
1470 con_id = 69;
1471 break;
1472 default:
1473 return -ENOENT;
1474 }
1475
1476 con = readl(&cru->clksel_con[con_id]);
1477 div = (con & ACLK_PDVI_DIV_MASK) >> ACLK_PDVI_DIV_SHIFT;
1478 sel = (con & ACLK_PDVI_SEL_MASK) >> ACLK_PDVI_SEL_SHIFT;
1479 if (sel == ACLK_PDVI_SEL_GPLL)
1480 parent = priv->gpll_hz;
1481 else if (sel == ACLK_PDVI_SEL_CPLL)
1482 parent = priv->cpll_hz;
1483 else if (sel == ACLK_PDVI_SEL_HPLL)
1484 parent = priv->hpll_hz;
1485 else
1486 return -ENOENT;
1487
1488 return DIV_TO_RATE(parent, div);
1489 }
1490
rv1126_clk_pdvi_ispp_set_clk(struct rv1126_clk_priv * priv,ulong clk_id,ulong rate)1491 static ulong rv1126_clk_pdvi_ispp_set_clk(struct rv1126_clk_priv *priv,
1492 ulong clk_id, ulong rate)
1493 {
1494 struct rv1126_cru *cru = priv->cru;
1495 u32 parent, sel, src_clk_div, con_id;
1496
1497 switch (clk_id) {
1498 case ACLK_PDVI:
1499 con_id = 49;
1500 break;
1501 case ACLK_PDISPP:
1502 con_id = 68;
1503 break;
1504 case CLK_ISPP:
1505 con_id = 69;
1506 break;
1507 default:
1508 return -ENOENT;
1509 }
1510
1511 if (!(priv->cpll_hz % rate)) {
1512 parent = priv->cpll_hz;
1513 sel = ACLK_PDVI_SEL_CPLL;
1514 } else if (!(priv->hpll_hz % rate)) {
1515 parent = priv->hpll_hz;
1516 sel = ACLK_PDVI_SEL_HPLL;
1517 } else {
1518 parent = priv->gpll_hz;
1519 sel = ACLK_PDVI_SEL_GPLL;
1520 }
1521
1522 src_clk_div = DIV_ROUND_UP(parent, rate);
1523 assert(src_clk_div - 1 <= 31);
1524 rk_clrsetreg(&cru->clksel_con[con_id],
1525 ACLK_PDVI_SEL_MASK | ACLK_PDVI_DIV_MASK,
1526 sel << ACLK_PDVI_SEL_SHIFT |
1527 (src_clk_div - 1) << ACLK_PDVI_DIV_SHIFT);
1528
1529 return rv1126_clk_pdvi_ispp_get_clk(priv, clk_id);
1530 }
1531
rv1126_clk_isp_get_clk(struct rv1126_clk_priv * priv)1532 static ulong rv1126_clk_isp_get_clk(struct rv1126_clk_priv *priv)
1533 {
1534 struct rv1126_cru *cru = priv->cru;
1535 u32 div, sel, con, parent;
1536
1537 con = readl(&cru->clksel_con[50]);
1538 div = (con & CLK_ISP_DIV_MASK) >> CLK_ISP_DIV_SHIFT;
1539 sel = (con & CLK_ISP_SEL_MASK) >> CLK_ISP_SEL_SHIFT;
1540 if (sel == CLK_ISP_SEL_GPLL)
1541 parent = priv->gpll_hz;
1542 else if (sel == CLK_ISP_SEL_CPLL)
1543 parent = priv->cpll_hz;
1544 else if (sel == CLK_ISP_SEL_HPLL)
1545 parent = priv->hpll_hz;
1546 else
1547 return -ENOENT;
1548
1549 return DIV_TO_RATE(parent, div);
1550 }
1551
rv1126_clk_isp_set_clk(struct rv1126_clk_priv * priv,ulong rate)1552 static ulong rv1126_clk_isp_set_clk(struct rv1126_clk_priv *priv, ulong rate)
1553 {
1554 struct rv1126_cru *cru = priv->cru;
1555 u32 parent, sel, src_clk_div;
1556
1557 if (!(priv->cpll_hz % rate)) {
1558 parent = priv->cpll_hz;
1559 sel = CLK_ISP_SEL_CPLL;
1560 } else if (!(priv->hpll_hz % rate)) {
1561 parent = priv->hpll_hz;
1562 sel = CLK_ISP_SEL_HPLL;
1563 } else {
1564 parent = priv->gpll_hz;
1565 sel = CLK_ISP_SEL_GPLL;
1566 }
1567
1568 src_clk_div = DIV_ROUND_UP(parent, rate);
1569 assert(src_clk_div - 1 <= 31);
1570 rk_clrsetreg(&cru->clksel_con[50],
1571 CLK_ISP_SEL_MASK | CLK_ISP_DIV_MASK,
1572 sel << CLK_ISP_SEL_SHIFT |
1573 (src_clk_div - 1) << CLK_ISP_DIV_SHIFT);
1574
1575 return rv1126_clk_isp_get_clk(priv);
1576 }
1577 #endif
1578
rv1126_dclk_decom_get_clk(struct rv1126_clk_priv * priv)1579 static ulong rv1126_dclk_decom_get_clk(struct rv1126_clk_priv *priv)
1580 {
1581 struct rv1126_cru *cru = priv->cru;
1582 u32 div, sel, con, parent;
1583
1584 con = readl(&cru->clksel_con[25]);
1585 div = (con & DCLK_DECOM_DIV_MASK) >> DCLK_DECOM_DIV_SHIFT;
1586 sel = (con & DCLK_DECOM_SEL_MASK) >> DCLK_DECOM_SEL_SHIFT;
1587 if (sel == DCLK_DECOM_SEL_GPLL)
1588 parent = priv->gpll_hz;
1589 else if (sel == DCLK_DECOM_SEL_CPLL)
1590 parent = priv->cpll_hz;
1591 else
1592 return -ENOENT;
1593
1594 return DIV_TO_RATE(parent, div);
1595 }
1596
rv1126_dclk_decom_set_clk(struct rv1126_clk_priv * priv,ulong rate)1597 static ulong rv1126_dclk_decom_set_clk(struct rv1126_clk_priv *priv, ulong rate)
1598 {
1599 struct rv1126_cru *cru = priv->cru;
1600 u32 src_clk_div;
1601
1602 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
1603 assert(src_clk_div - 1 <= 127);
1604 rk_clrsetreg(&cru->clksel_con[25],
1605 DCLK_DECOM_SEL_MASK | DCLK_DECOM_DIV_MASK,
1606 DCLK_DECOM_SEL_GPLL << DCLK_DECOM_SEL_SHIFT |
1607 (src_clk_div - 1) << DCLK_DECOM_DIV_SHIFT);
1608
1609 return rv1126_dclk_decom_get_clk(priv);
1610 }
1611
rv1126_clk_get_rate(struct clk * clk)1612 static ulong rv1126_clk_get_rate(struct clk *clk)
1613 {
1614 struct rv1126_clk_priv *priv = dev_get_priv(clk->dev);
1615 ulong rate = 0;
1616
1617 if (!priv->gpll_hz) {
1618 printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
1619 return -ENOENT;
1620 }
1621
1622 switch (clk->id) {
1623 case PLL_APLL:
1624 case ARMCLK:
1625 rate = rockchip_pll_get_rate(&rv1126_pll_clks[APLL], priv->cru,
1626 APLL);
1627 break;
1628 case PLL_CPLL:
1629 rate = rockchip_pll_get_rate(&rv1126_pll_clks[CPLL], priv->cru,
1630 CPLL);
1631 break;
1632 case PLL_HPLL:
1633 rate = rockchip_pll_get_rate(&rv1126_pll_clks[HPLL], priv->cru,
1634 HPLL);
1635 break;
1636 case PLL_DPLL:
1637 rate = rockchip_pll_get_rate(&rv1126_pll_clks[DPLL], priv->cru,
1638 DPLL);
1639 break;
1640 case HCLK_PDCORE_NIU:
1641 rate = rv1126_pdcore_get_clk(priv);
1642 break;
1643 case ACLK_PDBUS:
1644 case HCLK_PDBUS:
1645 case PCLK_PDBUS:
1646 case PCLK_WDT:
1647 rate = rv1126_pdbus_get_clk(priv, clk->id);
1648 break;
1649 case ACLK_PDPHP:
1650 case HCLK_PDPHP:
1651 rate = rv1126_pdphp_get_clk(priv, clk->id);
1652 break;
1653 case HCLK_PDAUDIO:
1654 rate = rv1126_pdaudio_get_clk(priv);
1655 break;
1656 case CLK_I2C1:
1657 case CLK_I2C3:
1658 case CLK_I2C4:
1659 case CLK_I2C5:
1660 rate = rv1126_i2c_get_clk(priv, clk->id);
1661 break;
1662 case CLK_SPI1:
1663 rate = rv1126_spi_get_clk(priv);
1664 break;
1665 case CLK_PWM2:
1666 rate = rv1126_pwm_get_clk(priv);
1667 break;
1668 case CLK_SARADC:
1669 rate = rv1126_saradc_get_clk(priv);
1670 break;
1671 case CLK_CRYPTO_CORE:
1672 case CLK_CRYPTO_PKA:
1673 case ACLK_CRYPTO:
1674 rate = rv1126_crypto_get_clk(priv, clk->id);
1675 break;
1676 case CLK_SDMMC:
1677 case HCLK_SDMMC:
1678 case CLK_SDIO:
1679 case HCLK_SDIO:
1680 case CLK_EMMC:
1681 case HCLK_EMMC:
1682 case SCLK_EMMC_SAMPLE:
1683 rate = rv1126_mmc_get_clk(priv, clk->id);
1684 break;
1685 case SCLK_SFC:
1686 rate = rv1126_sfc_get_clk(priv);
1687 break;
1688 case CLK_NANDC:
1689 rate = rv1126_nand_get_clk(priv);
1690 break;
1691 case ACLK_PDVO:
1692 case ACLK_VOP:
1693 rate = rv1126_aclk_vop_get_clk(priv);
1694 break;
1695 case DCLK_VOP:
1696 rate = rv1126_dclk_vop_get_clk(priv);
1697 break;
1698 case CLK_SCR1_CORE:
1699 rate = rv1126_scr1_get_clk(priv);
1700 break;
1701 case CLK_GMAC_SRC:
1702 rate = rv1126_gmac_src_get_clk(priv);
1703 break;
1704 case CLK_GMAC_ETHERNET_OUT:
1705 rate = rv1126_gmac_out_get_clk(priv);
1706 break;
1707 case PCLK_GMAC:
1708 rate = rv1126_pclk_gmac_get_clk(priv);
1709 break;
1710 #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_KERNEL_BOOT)
1711 case CLK_MIPICSI_OUT:
1712 rate = rv1126_clk_mipicsi_out_get_clk(priv);
1713 break;
1714 case CLK_ISP:
1715 rate = rv1126_clk_isp_get_clk(priv);
1716 break;
1717 case ACLK_PDVI:
1718 case ACLK_PDISPP:
1719 case CLK_ISPP:
1720 rate = rv1126_clk_pdvi_ispp_get_clk(priv, clk->id);
1721 break;
1722 #endif
1723 case DCLK_DECOM:
1724 rate = rv1126_dclk_decom_get_clk(priv);
1725 break;
1726 default:
1727 return -ENOENT;
1728 }
1729
1730 return rate;
1731 };
1732
rv1126_clk_set_rate(struct clk * clk,ulong rate)1733 static ulong rv1126_clk_set_rate(struct clk *clk, ulong rate)
1734 {
1735 struct rv1126_clk_priv *priv = dev_get_priv(clk->dev);
1736 ulong ret = 0;
1737
1738 if (!priv->gpll_hz) {
1739 printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
1740 return -ENOENT;
1741 }
1742
1743 switch (clk->id) {
1744 case PLL_APLL:
1745 case ARMCLK:
1746 if (priv->armclk_hz)
1747 rv1126_armclk_set_clk(priv, rate);
1748 priv->armclk_hz = rate;
1749 break;
1750 case PLL_CPLL:
1751 ret = rockchip_pll_set_rate(&rv1126_pll_clks[CPLL], priv->cru,
1752 CPLL, rate);
1753 break;
1754 case PLL_HPLL:
1755 ret = rockchip_pll_set_rate(&rv1126_pll_clks[HPLL], priv->cru,
1756 HPLL, rate);
1757 break;
1758 case ACLK_PDBUS:
1759 case HCLK_PDBUS:
1760 case PCLK_PDBUS:
1761 case PCLK_WDT:
1762 ret = rv1126_pdbus_set_clk(priv, clk->id, rate);
1763 break;
1764 case ACLK_PDPHP:
1765 case HCLK_PDPHP:
1766 ret = rv1126_pdphp_set_clk(priv, clk->id, rate);
1767 break;
1768 case HCLK_PDCORE_NIU:
1769 ret = rv1126_pdcore_set_clk(priv, rate);
1770 break;
1771 case HCLK_PDAUDIO:
1772 ret = rv1126_pdaudio_set_clk(priv, rate);
1773 break;
1774 case CLK_I2C1:
1775 case CLK_I2C3:
1776 case CLK_I2C4:
1777 case CLK_I2C5:
1778 ret = rv1126_i2c_set_clk(priv, clk->id, rate);
1779 break;
1780 case CLK_SPI1:
1781 ret = rv1126_spi_set_clk(priv, rate);
1782 break;
1783 case CLK_PWM2:
1784 ret = rv1126_pwm_set_clk(priv, rate);
1785 break;
1786 case CLK_SARADC:
1787 ret = rv1126_saradc_set_clk(priv, rate);
1788 break;
1789 case CLK_CRYPTO_CORE:
1790 case CLK_CRYPTO_PKA:
1791 case ACLK_CRYPTO:
1792 ret = rv1126_crypto_set_clk(priv, clk->id, rate);
1793 break;
1794 case CLK_SDMMC:
1795 case HCLK_SDMMC:
1796 case CLK_SDIO:
1797 case HCLK_SDIO:
1798 case CLK_EMMC:
1799 case HCLK_EMMC:
1800 ret = rv1126_mmc_set_clk(priv, clk->id, rate);
1801 break;
1802 case SCLK_SFC:
1803 ret = rv1126_sfc_set_clk(priv, rate);
1804 break;
1805 case CLK_NANDC:
1806 ret = rv1126_nand_set_clk(priv, rate);
1807 break;
1808 case ACLK_PDVO:
1809 case ACLK_VOP:
1810 ret = rv1126_aclk_vop_set_clk(priv, rate);
1811 break;
1812 case DCLK_VOP:
1813 ret = rv1126_dclk_vop_set_clk(priv, rate);
1814 break;
1815 case CLK_SCR1_CORE:
1816 ret = rv1126_scr1_set_clk(priv, rate);
1817 break;
1818 case CLK_GMAC_SRC:
1819 ret = rv1126_gmac_src_set_clk(priv, rate);
1820 break;
1821 case CLK_GMAC_ETHERNET_OUT:
1822 ret = rv1126_gmac_out_set_clk(priv, rate);
1823 break;
1824 case CLK_GMAC_TX_RX:
1825 ret = rv1126_gmac_tx_rx_set_clk(priv, rate);
1826 break;
1827 #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_KERNEL_BOOT)
1828 case CLK_MIPICSI_OUT:
1829 ret = rv1126_clk_mipicsi_out_set_clk(priv, rate);
1830 break;
1831 case CLK_ISP:
1832 ret = rv1126_clk_isp_set_clk(priv, rate);
1833 break;
1834 case ACLK_PDVI:
1835 case ACLK_PDISPP:
1836 case CLK_ISPP:
1837 ret = rv1126_clk_pdvi_ispp_set_clk(priv, clk->id, rate);
1838 break;
1839 #endif
1840 case DCLK_DECOM:
1841 ret = rv1126_dclk_decom_set_clk(priv, rate);
1842 break;
1843 default:
1844 return -ENOENT;
1845 }
1846
1847 return ret;
1848 };
1849
1850 #define ROCKCHIP_MMC_DELAY_SEL BIT(10)
1851 #define ROCKCHIP_MMC_DEGREE_MASK 0x3
1852 #define ROCKCHIP_MMC_DELAYNUM_OFFSET 2
1853 #define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
1854
1855 #define PSECS_PER_SEC 1000000000000LL
1856 /*
1857 * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to
1858 * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg.
1859 */
1860 #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60
1861
rv1126_mmc_get_phase(struct clk * clk)1862 int rv1126_mmc_get_phase(struct clk *clk)
1863 {
1864 struct rv1126_clk_priv *priv = dev_get_priv(clk->dev);
1865 struct rv1126_cru *cru = priv->cru;
1866 u32 raw_value, delay_num;
1867 u16 degrees = 0;
1868 ulong rate;
1869
1870 rate = rv1126_clk_get_rate(clk);
1871 if (rate < 0)
1872 return rate;
1873
1874 if (clk->id == SCLK_EMMC_SAMPLE)
1875 raw_value = readl(&cru->emmc_con[1]);
1876 else if (clk->id == SCLK_SDMMC_SAMPLE)
1877 raw_value = readl(&cru->sdmmc_con[1]);
1878 else
1879 raw_value = readl(&cru->sdio_con[1]);
1880
1881 raw_value >>= 1;
1882 degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90;
1883
1884 if (raw_value & ROCKCHIP_MMC_DELAY_SEL) {
1885 /* degrees/delaynum * 10000 */
1886 unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) *
1887 36 * (rate / 1000000);
1888
1889 delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK);
1890 delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET;
1891 degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000);
1892 }
1893
1894 return degrees % 360;
1895 }
1896
rv1126_mmc_set_phase(struct clk * clk,u32 degrees)1897 int rv1126_mmc_set_phase(struct clk *clk, u32 degrees)
1898 {
1899 struct rv1126_clk_priv *priv = dev_get_priv(clk->dev);
1900 struct rv1126_cru *cru = priv->cru;
1901 u8 nineties, remainder, delay_num;
1902 u32 raw_value, delay;
1903 ulong rate;
1904
1905 rate = rv1126_clk_get_rate(clk);
1906 if (rate < 0)
1907 return rate;
1908
1909 nineties = degrees / 90;
1910 remainder = (degrees % 90);
1911
1912 /*
1913 * Convert to delay; do a little extra work to make sure we
1914 * don't overflow 32-bit / 64-bit numbers.
1915 */
1916 delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */
1917 delay *= remainder;
1918 delay = DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 *
1919 (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10));
1920
1921 delay_num = (u8)min_t(u32, delay, 255);
1922
1923 raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0;
1924 raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET;
1925 raw_value |= nineties;
1926
1927 raw_value <<= 1;
1928 if (clk->id == SCLK_EMMC_SAMPLE)
1929 writel(raw_value | 0xffff0000, &cru->emmc_con[1]);
1930 else if (clk->id == SCLK_SDMMC_SAMPLE)
1931 writel(raw_value | 0xffff0000, &cru->sdmmc_con[1]);
1932 else
1933 writel(raw_value | 0xffff0000, &cru->sdio_con[1]);
1934
1935 debug("mmc set_phase(%d) delay_nums=%u reg=%#x actual_degrees=%d\n",
1936 degrees, delay_num, raw_value, rv1126_mmc_get_phase(clk));
1937
1938 return 0;
1939 }
1940
rv1126_clk_get_phase(struct clk * clk)1941 static int rv1126_clk_get_phase(struct clk *clk)
1942 {
1943 int ret;
1944
1945 debug("%s %ld\n", __func__, clk->id);
1946 switch (clk->id) {
1947 case SCLK_EMMC_SAMPLE:
1948 case SCLK_SDMMC_SAMPLE:
1949 case SCLK_SDIO_SAMPLE:
1950 ret = rv1126_mmc_get_phase(clk);
1951 break;
1952 default:
1953 return -ENOENT;
1954 }
1955
1956 return ret;
1957 }
1958
rv1126_clk_set_phase(struct clk * clk,int degrees)1959 static int rv1126_clk_set_phase(struct clk *clk, int degrees)
1960 {
1961 int ret;
1962
1963 debug("%s %ld\n", __func__, clk->id);
1964 switch (clk->id) {
1965 case SCLK_EMMC_SAMPLE:
1966 case SCLK_SDMMC_SAMPLE:
1967 case SCLK_SDIO_SAMPLE:
1968 ret = rv1126_mmc_set_phase(clk, degrees);
1969 break;
1970 default:
1971 return -ENOENT;
1972 }
1973
1974 return ret;
1975 }
1976
1977 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
rv1126_gmac_src_set_parent(struct clk * clk,struct clk * parent)1978 static int rv1126_gmac_src_set_parent(struct clk *clk, struct clk *parent)
1979 {
1980 struct rv1126_clk_priv *priv = dev_get_priv(clk->dev);
1981 struct rv1126_grf *grf = priv->grf;
1982
1983 if (parent->id == CLK_GMAC_SRC_M0)
1984 rk_clrsetreg(&grf->iofunc_con1, GMAC_SRC_SEL_MASK,
1985 GMAC_SRC_SEL_M0 << GMAC_SRC_SEL_SHIFT);
1986 else if(parent->id == CLK_GMAC_SRC_M1)
1987 rk_clrsetreg(&grf->iofunc_con1, GMAC_SRC_SEL_MASK,
1988 GMAC_SRC_SEL_M1 << GMAC_SRC_SEL_SHIFT);
1989
1990 return 0;
1991 }
1992
rv1126_gmac_src_m0_set_parent(struct clk * clk,struct clk * parent)1993 static int rv1126_gmac_src_m0_set_parent(struct clk *clk, struct clk *parent)
1994 {
1995 struct rv1126_clk_priv *priv = dev_get_priv(clk->dev);
1996 struct rv1126_cru *cru = priv->cru;
1997
1998 if (parent->id == CLK_GMAC_DIV)
1999 rk_clrsetreg(&cru->gmac_con, GMAC_SRC_M0_SEL_MASK,
2000 GMAC_SRC_M0_SEL_INT << GMAC_SRC_M0_SEL_SHIFT);
2001 else
2002 rk_clrsetreg(&cru->gmac_con, GMAC_SRC_M0_SEL_MASK,
2003 GMAC_SRC_M0_SEL_EXT << GMAC_SRC_M0_SEL_SHIFT);
2004
2005 return 0;
2006 }
2007
rv1126_gmac_src_m1_set_parent(struct clk * clk,struct clk * parent)2008 static int rv1126_gmac_src_m1_set_parent(struct clk *clk, struct clk *parent)
2009 {
2010 struct rv1126_clk_priv *priv = dev_get_priv(clk->dev);
2011 struct rv1126_cru *cru = priv->cru;
2012
2013 if (parent->id == CLK_GMAC_DIV)
2014 rk_clrsetreg(&cru->gmac_con, GMAC_SRC_M1_SEL_MASK,
2015 GMAC_SRC_M1_SEL_INT << GMAC_SRC_M1_SEL_SHIFT);
2016 else
2017 rk_clrsetreg(&cru->gmac_con, GMAC_SRC_M1_SEL_MASK,
2018 GMAC_SRC_M1_SEL_EXT << GMAC_SRC_M1_SEL_SHIFT);
2019
2020 return 0;
2021 }
2022
rv1126_gmac_tx_rx_set_parent(struct clk * clk,struct clk * parent)2023 static int rv1126_gmac_tx_rx_set_parent(struct clk *clk, struct clk *parent)
2024 {
2025 struct rv1126_clk_priv *priv = dev_get_priv(clk->dev);
2026 struct rv1126_cru *cru = priv->cru;
2027
2028 if (parent->id == RGMII_MODE_CLK)
2029 rk_clrsetreg(&cru->gmac_con, GMAC_MODE_SEL_MASK,
2030 GMAC_RGMII_MODE << GMAC_MODE_SEL_SHIFT);
2031 else
2032 rk_clrsetreg(&cru->gmac_con, GMAC_MODE_SEL_MASK,
2033 GMAC_RMII_MODE << GMAC_MODE_SEL_SHIFT);
2034
2035 return 0;
2036 }
2037
rv1126_clk_set_parent(struct clk * clk,struct clk * parent)2038 static int rv1126_clk_set_parent(struct clk *clk, struct clk *parent)
2039 {
2040 switch (clk->id) {
2041 case CLK_GMAC_SRC:
2042 return rv1126_gmac_src_set_parent(clk, parent);
2043 case CLK_GMAC_SRC_M0:
2044 return rv1126_gmac_src_m0_set_parent(clk, parent);
2045 case CLK_GMAC_SRC_M1:
2046 return rv1126_gmac_src_m1_set_parent(clk, parent);
2047 case CLK_GMAC_TX_RX:
2048 return rv1126_gmac_tx_rx_set_parent(clk, parent);
2049 default:
2050 return -ENOENT;
2051 }
2052
2053 return 0;
2054 }
2055 #endif
2056
2057 static struct clk_ops rv1126_clk_ops = {
2058 .get_rate = rv1126_clk_get_rate,
2059 .set_rate = rv1126_clk_set_rate,
2060 .get_phase = rv1126_clk_get_phase,
2061 .set_phase = rv1126_clk_set_phase,
2062 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
2063 .set_parent = rv1126_clk_set_parent,
2064 #endif
2065 };
2066
rv1126_gpll_set_rate(struct rv1126_clk_priv * priv,struct rv1126_pmuclk_priv * pmu_priv,ulong rate)2067 static ulong rv1126_gpll_set_rate(struct rv1126_clk_priv *priv,
2068 struct rv1126_pmuclk_priv *pmu_priv,
2069 ulong rate)
2070 {
2071 ulong emmc_rate, sfc_rate, nandc_rate;
2072 bool restore = false;
2073
2074 if (priv->gpll_hz != OSC_HZ) {
2075 emmc_rate = rv1126_mmc_get_clk(priv, CLK_EMMC);
2076 sfc_rate = rv1126_sfc_get_clk(priv);
2077 nandc_rate = rv1126_nand_get_clk(priv);
2078 debug("%s emmc=%lu, sfc=%lu, nandc=%lu\n", __func__,
2079 emmc_rate, sfc_rate, nandc_rate);
2080 restore = true;
2081 }
2082
2083 /*
2084 * the child div is big enough for gpll 1188MHz,
2085 * even maskrom has change some clocks.
2086 */
2087 if (rockchip_pll_set_rate(&rv1126_pll_clks[GPLL],
2088 pmu_priv->pmucru, GPLL, rate))
2089 return -EINVAL;
2090 pmu_priv->gpll_hz = rate;
2091 priv->gpll_hz = rate;
2092
2093 if (restore) {
2094 rv1126_mmc_set_clk(priv, CLK_EMMC, emmc_rate);
2095 rv1126_sfc_set_clk(priv, sfc_rate);
2096 rv1126_nand_set_clk(priv, nandc_rate);
2097 }
2098
2099 return 0;
2100 }
2101
rv1126_gpll_set_clk(struct rv1126_clk_priv * priv,ulong rate)2102 static int rv1126_gpll_set_clk(struct rv1126_clk_priv *priv, ulong rate)
2103 {
2104 struct udevice *pmucru_dev;
2105 struct rv1126_pmuclk_priv *pmu_priv;
2106 int ret;
2107
2108 ret = uclass_get_device_by_driver(UCLASS_CLK,
2109 DM_GET_DRIVER(rockchip_rv1126_pmucru),
2110 &pmucru_dev);
2111 if (ret) {
2112 printf("%s: could not find pmucru device\n", __func__);
2113 return ret;
2114 }
2115 pmu_priv = dev_get_priv(pmucru_dev);
2116 priv->gpll_hz = pmu_priv->gpll_hz;
2117
2118 if (rv1126_gpll_set_rate(priv, pmu_priv, rate)) {
2119 printf("%s: failed to set gpll rate %lu\n", __func__, rate);
2120 return -EINVAL;
2121 }
2122
2123 rv1126_pdpmu_set_pmuclk(pmu_priv, PCLK_PDPMU_HZ);
2124 rv1126_rtc32k_set_pmuclk(pmu_priv, CLK_OSC0_DIV_HZ);
2125
2126 return 0;
2127 }
2128
rv1126_clk_init(struct rv1126_clk_priv * priv)2129 static void rv1126_clk_init(struct rv1126_clk_priv *priv)
2130 {
2131 int ret;
2132
2133 priv->sync_kernel = false;
2134 if (!priv->armclk_enter_hz) {
2135 priv->armclk_enter_hz =
2136 rockchip_pll_get_rate(&rv1126_pll_clks[APLL],
2137 priv->cru, APLL);
2138 priv->armclk_init_hz = priv->armclk_enter_hz ;
2139 }
2140
2141 if (priv->armclk_init_hz != APLL_HZ) {
2142 ret = rv1126_armclk_set_clk(priv, APLL_HZ);
2143 if (!ret)
2144 priv->armclk_init_hz = APLL_HZ;
2145 }
2146 if (priv->cpll_hz != CPLL_HZ) {
2147 ret = rockchip_pll_set_rate(&rv1126_pll_clks[CPLL], priv->cru,
2148 CPLL, CPLL_HZ);
2149 if (!ret)
2150 priv->cpll_hz = CPLL_HZ;
2151 }
2152 if (priv->hpll_hz != HPLL_HZ) {
2153 ret = rockchip_pll_set_rate(&rv1126_pll_clks[HPLL], priv->cru,
2154 HPLL, HPLL_HZ);
2155 if (!ret)
2156 priv->hpll_hz = HPLL_HZ;
2157 }
2158 if (priv->gpll_hz != GPLL_HZ)
2159 rv1126_gpll_set_clk(priv, GPLL_HZ);
2160
2161 rv1126_pdbus_set_clk(priv, ACLK_PDBUS, ACLK_PDBUS_HZ);
2162 rv1126_pdbus_set_clk(priv, HCLK_PDBUS, HCLK_PDBUS_HZ);
2163 rv1126_pdbus_set_clk(priv, PCLK_PDBUS, PCLK_PDBUS_HZ);
2164 rv1126_pdphp_set_clk(priv, ACLK_PDPHP, ACLK_PDPHP_HZ);
2165 rv1126_pdphp_set_clk(priv, HCLK_PDPHP, HCLK_PDPHP_HZ);
2166 rv1126_pdcore_set_clk(priv, HCLK_PDCORE_HZ);
2167 rv1126_pdaudio_set_clk(priv, HCLK_PDAUDIO_HZ);
2168 #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_KERNEL_BOOT)
2169 rv1126_clk_pdvi_ispp_set_clk(priv, ACLK_PDVI, ACLK_PDVI_HZ);
2170 rv1126_clk_isp_set_clk(priv, CLK_ISP_HZ);
2171 rv1126_clk_pdvi_ispp_set_clk(priv, ACLK_PDISPP, ACLK_PDISPP_HZ);
2172 rv1126_clk_pdvi_ispp_set_clk(priv, CLK_ISPP, CLK_ISPP_HZ);
2173 rv1126_aclk_vop_set_clk(priv, ACLK_VOP_HZ);
2174 rv1126_dclk_vop_set_clk(priv, DCLK_VOP_HZ);
2175 #endif
2176 }
2177
rv1126_clk_probe(struct udevice * dev)2178 static int rv1126_clk_probe(struct udevice *dev)
2179 {
2180 struct rv1126_clk_priv *priv = dev_get_priv(dev);
2181 int ret;
2182
2183 priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
2184 if (IS_ERR(priv->grf))
2185 return PTR_ERR(priv->grf);
2186
2187 rv1126_clk_init(priv);
2188
2189 /* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
2190 ret = clk_set_defaults(dev);
2191 if (ret)
2192 debug("%s clk_set_defaults failed %d\n", __func__, ret);
2193 else
2194 priv->sync_kernel = true;
2195
2196 return 0;
2197 }
2198
rv1126_clk_ofdata_to_platdata(struct udevice * dev)2199 static int rv1126_clk_ofdata_to_platdata(struct udevice *dev)
2200 {
2201 struct rv1126_clk_priv *priv = dev_get_priv(dev);
2202
2203 priv->cru = dev_read_addr_ptr(dev);
2204
2205 return 0;
2206 }
2207
rv1126_clk_bind(struct udevice * dev)2208 static int rv1126_clk_bind(struct udevice *dev)
2209 {
2210 int ret;
2211 struct udevice *sys_child, *sf_child;
2212 struct sysreset_reg *priv;
2213 struct softreset_reg *sf_priv;
2214
2215 /* The reset driver does not have a device node, so bind it here */
2216 ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
2217 &sys_child);
2218 if (ret) {
2219 debug("Warning: No sysreset driver: ret=%d\n", ret);
2220 } else {
2221 priv = malloc(sizeof(struct sysreset_reg));
2222 priv->glb_srst_fst_value = offsetof(struct rv1126_cru,
2223 glb_srst_fst);
2224 priv->glb_srst_snd_value = offsetof(struct rv1126_cru,
2225 glb_srst_snd);
2226 sys_child->priv = priv;
2227 }
2228
2229 ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset",
2230 dev_ofnode(dev), &sf_child);
2231 if (ret) {
2232 debug("Warning: No rockchip reset driver: ret=%d\n", ret);
2233 } else {
2234 sf_priv = malloc(sizeof(struct softreset_reg));
2235 sf_priv->sf_reset_offset = offsetof(struct rv1126_cru,
2236 softrst_con[0]);
2237 sf_priv->sf_reset_num = 15;
2238 sf_child->priv = sf_priv;
2239 }
2240
2241 return 0;
2242 }
2243
2244 static const struct udevice_id rv1126_clk_ids[] = {
2245 { .compatible = "rockchip,rv1126-cru" },
2246 { }
2247 };
2248
2249 U_BOOT_DRIVER(rockchip_rv1126_cru) = {
2250 .name = "rockchip_rv1126_cru",
2251 .id = UCLASS_CLK,
2252 .of_match = rv1126_clk_ids,
2253 .priv_auto_alloc_size = sizeof(struct rv1126_clk_priv),
2254 .ofdata_to_platdata = rv1126_clk_ofdata_to_platdata,
2255 .ops = &rv1126_clk_ops,
2256 .bind = rv1126_clk_bind,
2257 .probe = rv1126_clk_probe,
2258 };
2259
2260 #ifndef CONFIG_SPL_BUILD
2261 /**
2262 * soc_clk_dump() - Print clock frequencies
2263 * Returns zero on success
2264 *
2265 * Implementation for the clk dump command.
2266 */
soc_clk_dump(void)2267 int soc_clk_dump(void)
2268 {
2269 struct udevice *cru_dev, *pmucru_dev;
2270 struct rv1126_clk_priv *priv;
2271 const struct rv1126_clk_info *clk_dump;
2272 struct clk clk;
2273 unsigned long clk_count = ARRAY_SIZE(clks_dump);
2274 unsigned long rate;
2275 int i, ret;
2276
2277 ret = uclass_get_device_by_driver(UCLASS_CLK,
2278 DM_GET_DRIVER(rockchip_rv1126_cru),
2279 &cru_dev);
2280 if (ret) {
2281 printf("%s failed to get cru device\n", __func__);
2282 return ret;
2283 }
2284
2285 ret = uclass_get_device_by_driver(UCLASS_CLK,
2286 DM_GET_DRIVER(rockchip_rv1126_pmucru),
2287 &pmucru_dev);
2288 if (ret) {
2289 printf("%s failed to get pmucru device\n", __func__);
2290 return ret;
2291 }
2292
2293 priv = dev_get_priv(cru_dev);
2294 printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n",
2295 priv->sync_kernel ? "sync kernel" : "uboot",
2296 priv->armclk_enter_hz / 1000,
2297 priv->armclk_init_hz / 1000,
2298 priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0,
2299 priv->set_armclk_rate ? " KHz" : "N/A");
2300 for (i = 0; i < clk_count; i++) {
2301 clk_dump = &clks_dump[i];
2302 if (clk_dump->name) {
2303 clk.id = clk_dump->id;
2304 if (clk_dump->is_cru)
2305 ret = clk_request(cru_dev, &clk);
2306 else
2307 ret = clk_request(pmucru_dev, &clk);
2308 if (ret < 0)
2309 return ret;
2310
2311 rate = clk_get_rate(&clk);
2312 clk_free(&clk);
2313 if (i == 0) {
2314 if (rate < 0)
2315 printf(" %s %s\n", clk_dump->name,
2316 "unknown");
2317 else
2318 printf(" %s %lu KHz\n", clk_dump->name,
2319 rate / 1000);
2320 } else {
2321 if (rate < 0)
2322 printf(" %s %s\n", clk_dump->name,
2323 "unknown");
2324 else
2325 printf(" %s %lu KHz\n", clk_dump->name,
2326 rate / 1000);
2327 }
2328 }
2329 }
2330
2331 return 0;
2332 }
2333 #endif
2334