1 /*
2 * (C) Copyright 2017 Rockchip Electronics Co., Ltd
3 *
4 * SPDX-License-Identifier: GPL-2.0
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/cpu.h>
15 #include <asm/arch/cru_px30.h>
16 #include <asm/arch/hardware.h>
17 #include <asm/io.h>
18 #include <dm/lists.h>
19 #include <dt-bindings/clock/px30-cru.h>
20
21 DECLARE_GLOBAL_DATA_PTR;
22
23 enum {
24 VCO_MAX_HZ = 3200U * 1000000,
25 VCO_MIN_HZ = 800 * 1000000,
26 OUTPUT_MAX_HZ = 3200U * 1000000,
27 OUTPUT_MIN_HZ = 24 * 1000000,
28 };
29
30 #define PX30_VOP_PLL_LIMIT 600000000
31
32 #define PX30_PLL_RATE(_rate, _refdiv, _fbdiv, _postdiv1, \
33 _postdiv2, _dsmpd, _frac) \
34 { \
35 .rate = _rate##U, \
36 .fbdiv = _fbdiv, \
37 .postdiv1 = _postdiv1, \
38 .refdiv = _refdiv, \
39 .postdiv2 = _postdiv2, \
40 .dsmpd = _dsmpd, \
41 .frac = _frac, \
42 }
43
44 #define PX30_CPUCLK_RATE(_rate, _aclk_div, _pclk_div) \
45 { \
46 .rate = _rate##U, \
47 .aclk_div = _aclk_div, \
48 .pclk_div = _pclk_div, \
49 }
50
51 #define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1))
52
53 #define PX30_CLK_DUMP(_id, _name, _iscru) \
54 { \
55 .id = _id, \
56 .name = _name, \
57 .is_cru = _iscru, \
58 }
59
60 static struct pll_rate_table px30_pll_rates[] = {
61 /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
62 PX30_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0),
63 PX30_PLL_RATE(1188000000, 2, 99, 1, 1, 1, 0),
64 PX30_PLL_RATE(1100000000, 12, 550, 1, 1, 1, 0),
65 PX30_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0),
66 PX30_PLL_RATE(1000000000, 6, 500, 2, 1, 1, 0),
67 PX30_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0),
68 PX30_PLL_RATE(600000000, 1, 75, 3, 1, 1, 0),
69 };
70
71 static const struct px30_clk_info clks_dump[] = {
72 PX30_CLK_DUMP(PLL_APLL, "apll", true),
73 PX30_CLK_DUMP(PLL_DPLL, "dpll", true),
74 PX30_CLK_DUMP(PLL_CPLL, "cpll", true),
75 PX30_CLK_DUMP(PLL_NPLL, "npll", true),
76 PX30_CLK_DUMP(PLL_GPLL, "gpll", false),
77 PX30_CLK_DUMP(ACLK_BUS_PRE, "aclk_bus", true),
78 PX30_CLK_DUMP(HCLK_BUS_PRE, "hclk_bus", true),
79 PX30_CLK_DUMP(PCLK_BUS_PRE, "pclk_bus", true),
80 PX30_CLK_DUMP(ACLK_PERI_PRE, "aclk_peri", true),
81 PX30_CLK_DUMP(HCLK_PERI_PRE, "hclk_peri", true),
82 PX30_CLK_DUMP(PCLK_PMU_PRE, "pclk_pmu", false),
83 };
84
85 static struct cpu_rate_table px30_cpu_rates[] = {
86 PX30_CPUCLK_RATE(1200000000, 1, 5),
87 PX30_CPUCLK_RATE(1008000000, 1, 5),
88 PX30_CPUCLK_RATE(816000000, 1, 3),
89 PX30_CPUCLK_RATE(600000000, 1, 3),
90 PX30_CPUCLK_RATE(408000000, 1, 1),
91 };
92
93 static u8 pll_mode_shift[PLL_COUNT] = {
94 APLL_MODE_SHIFT, DPLL_MODE_SHIFT, CPLL_MODE_SHIFT,
95 NPLL_MODE_SHIFT, GPLL_MODE_SHIFT
96 };
97 static u32 pll_mode_mask[PLL_COUNT] = {
98 APLL_MODE_MASK, DPLL_MODE_MASK, CPLL_MODE_MASK,
99 NPLL_MODE_MASK, GPLL_MODE_MASK
100 };
101
102 static struct pll_rate_table auto_table;
103
104 static ulong px30_clk_get_pll_rate(struct px30_clk_priv *priv,
105 enum px30_pll_id pll_id);
106
pll_clk_set_by_auto(u32 drate)107 static struct pll_rate_table *pll_clk_set_by_auto(u32 drate)
108 {
109 struct pll_rate_table *rate = &auto_table;
110 u32 ref_khz = OSC_HZ / KHz, refdiv, fbdiv = 0;
111 u32 postdiv1, postdiv2 = 1;
112 u32 fref_khz;
113 u32 diff_khz, best_diff_khz;
114 const u32 max_refdiv = 63, max_fbdiv = 3200, min_fbdiv = 16;
115 const u32 max_postdiv1 = 7, max_postdiv2 = 7;
116 u32 vco_khz;
117 u32 rate_khz = drate / KHz;
118
119 if (!drate) {
120 printf("%s: the frequency can't be 0 Hz\n", __func__);
121 return NULL;
122 }
123
124 postdiv1 = DIV_ROUND_UP(VCO_MIN_HZ / 1000, rate_khz);
125 if (postdiv1 > max_postdiv1) {
126 postdiv2 = DIV_ROUND_UP(postdiv1, max_postdiv1);
127 postdiv1 = DIV_ROUND_UP(postdiv1, postdiv2);
128 }
129
130 vco_khz = rate_khz * postdiv1 * postdiv2;
131
132 if (vco_khz < (VCO_MIN_HZ / KHz) || vco_khz > (VCO_MAX_HZ / KHz) ||
133 postdiv2 > max_postdiv2) {
134 printf("%s: Cannot find out a supported VCO for Freq (%uHz)\n",
135 __func__, rate_khz);
136 return NULL;
137 }
138
139 rate->postdiv1 = postdiv1;
140 rate->postdiv2 = postdiv2;
141
142 best_diff_khz = vco_khz;
143 for (refdiv = 1; refdiv < max_refdiv && best_diff_khz; refdiv++) {
144 fref_khz = ref_khz / refdiv;
145
146 fbdiv = vco_khz / fref_khz;
147 if ((fbdiv >= max_fbdiv) || (fbdiv <= min_fbdiv))
148 continue;
149 diff_khz = vco_khz - fbdiv * fref_khz;
150 if (fbdiv + 1 < max_fbdiv && diff_khz > fref_khz / 2) {
151 fbdiv++;
152 diff_khz = fref_khz - diff_khz;
153 }
154
155 if (diff_khz >= best_diff_khz)
156 continue;
157
158 best_diff_khz = diff_khz;
159 rate->refdiv = refdiv;
160 rate->fbdiv = fbdiv;
161 }
162
163 if (best_diff_khz > 4 * (MHz / KHz)) {
164 printf("%s: Failed to match output frequency %u bestis %u Hz\n",
165 __func__, rate_khz,
166 best_diff_khz * KHz);
167 return NULL;
168 }
169
170 return rate;
171 }
172
get_pll_settings(unsigned long rate)173 static const struct pll_rate_table *get_pll_settings(unsigned long rate)
174 {
175 unsigned int rate_count = ARRAY_SIZE(px30_pll_rates);
176 int i;
177
178 for (i = 0; i < rate_count; i++) {
179 if (rate == px30_pll_rates[i].rate)
180 return &px30_pll_rates[i];
181 }
182
183 return pll_clk_set_by_auto(rate);
184 }
185
get_cpu_settings(unsigned long rate)186 static const struct cpu_rate_table *get_cpu_settings(unsigned long rate)
187 {
188 unsigned int rate_count = ARRAY_SIZE(px30_cpu_rates);
189 int i;
190
191 for (i = 0; i < rate_count; i++) {
192 if (rate == px30_cpu_rates[i].rate)
193 return &px30_cpu_rates[i];
194 }
195
196 return NULL;
197 }
198
199 /*
200 * How to calculate the PLL(from TRM V0.3 Part 1 Page 63):
201 * Formulas also embedded within the Fractional PLL Verilog model:
202 * If DSMPD = 1 (DSM is disabled, "integer mode")
203 * FOUTVCO = FREF / REFDIV * FBDIV
204 * FOUTPOSTDIV = FOUTVCO / POSTDIV1 / POSTDIV2
205 * Where:
206 * FOUTVCO = Fractional PLL non-divided output frequency
207 * FOUTPOSTDIV = Fractional PLL divided output frequency
208 * (output of second post divider)
209 * FREF = Fractional PLL input reference frequency, (the OSC_HZ 24MHz input)
210 * REFDIV = Fractional PLL input reference clock divider
211 * FBDIV = Integer value programmed into feedback divide
212 *
213 */
rkclk_set_pll(struct px30_pll * pll,unsigned int * mode,enum px30_pll_id pll_id,unsigned long drate)214 static int rkclk_set_pll(struct px30_pll *pll, unsigned int *mode,
215 enum px30_pll_id pll_id,
216 unsigned long drate)
217 {
218 const struct pll_rate_table *rate;
219 uint vco_hz, output_hz;
220
221 rate = get_pll_settings(drate);
222 if (!rate) {
223 printf("%s unsupport rate\n", __func__);
224 return -EINVAL;
225 }
226
227 /* All PLLs have same VCO and output frequency range restrictions. */
228 vco_hz = OSC_HZ / 1000 * rate->fbdiv / rate->refdiv * 1000;
229 output_hz = vco_hz / rate->postdiv1 / rate->postdiv2;
230
231 debug("PLL at %p: fb=%d, ref=%d, pst1=%d, pst2=%d, vco=%u Hz, output=%u Hz\n",
232 pll, rate->fbdiv, rate->refdiv, rate->postdiv1,
233 rate->postdiv2, vco_hz, output_hz);
234 assert(vco_hz >= VCO_MIN_HZ && vco_hz <= VCO_MAX_HZ &&
235 output_hz >= OUTPUT_MIN_HZ && output_hz <= OUTPUT_MAX_HZ);
236
237 /*
238 * When power on or changing PLL setting,
239 * we must force PLL into slow mode to ensure output stable clock.
240 */
241 rk_clrsetreg(mode, pll_mode_mask[pll_id],
242 PLLMUX_FROM_XIN24M << pll_mode_shift[pll_id]);
243
244 /* use integer mode */
245 rk_setreg(&pll->con1, 1 << PLL_DSMPD_SHIFT);
246 /* Power down */
247 rk_setreg(&pll->con1, 1 << PLL_PD_SHIFT);
248
249 rk_clrsetreg(&pll->con0,
250 PLL_POSTDIV1_MASK | PLL_FBDIV_MASK,
251 (rate->postdiv1 << PLL_POSTDIV1_SHIFT) | rate->fbdiv);
252 rk_clrsetreg(&pll->con1, PLL_POSTDIV2_MASK | PLL_REFDIV_MASK,
253 (rate->postdiv2 << PLL_POSTDIV2_SHIFT |
254 rate->refdiv << PLL_REFDIV_SHIFT));
255
256 /* Power Up */
257 rk_clrreg(&pll->con1, 1 << PLL_PD_SHIFT);
258
259 /* waiting for pll lock */
260 while (!(readl(&pll->con1) & (1 << PLL_LOCK_STATUS_SHIFT)))
261 udelay(1);
262
263 rk_clrsetreg(mode, pll_mode_mask[pll_id],
264 PLLMUX_FROM_PLL << pll_mode_shift[pll_id]);
265
266 return 0;
267 }
268
rkclk_pll_get_rate(struct px30_pll * pll,unsigned int * mode,enum px30_pll_id pll_id)269 static uint32_t rkclk_pll_get_rate(struct px30_pll *pll, unsigned int *mode,
270 enum px30_pll_id pll_id)
271 {
272 u32 refdiv, fbdiv, postdiv1, postdiv2;
273 u32 con, shift, mask;
274
275 con = readl(mode);
276 shift = pll_mode_shift[pll_id];
277 mask = pll_mode_mask[pll_id];
278
279 switch ((con & mask) >> shift) {
280 case PLLMUX_FROM_XIN24M:
281 return OSC_HZ;
282 case PLLMUX_FROM_PLL:
283 /* normal mode */
284 con = readl(&pll->con0);
285 postdiv1 = (con & PLL_POSTDIV1_MASK) >> PLL_POSTDIV1_SHIFT;
286 fbdiv = (con & PLL_FBDIV_MASK) >> PLL_FBDIV_SHIFT;
287 con = readl(&pll->con1);
288 postdiv2 = (con & PLL_POSTDIV2_MASK) >> PLL_POSTDIV2_SHIFT;
289 refdiv = (con & PLL_REFDIV_MASK) >> PLL_REFDIV_SHIFT;
290 return (24 * fbdiv / (refdiv * postdiv1 * postdiv2)) * 1000000;
291 case PLLMUX_FROM_RTC32K:
292 default:
293 return 32768;
294 }
295 }
296
px30_i2c_get_clk(struct px30_clk_priv * priv,ulong clk_id)297 static ulong px30_i2c_get_clk(struct px30_clk_priv *priv, ulong clk_id)
298 {
299 struct px30_cru *cru = priv->cru;
300 u32 div, con;
301
302 switch (clk_id) {
303 case SCLK_I2C0:
304 con = readl(&cru->clksel_con[49]);
305 div = con >> CLK_I2C0_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK;
306 break;
307 case SCLK_I2C1:
308 con = readl(&cru->clksel_con[49]);
309 div = con >> CLK_I2C1_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK;
310 break;
311 case SCLK_I2C2:
312 con = readl(&cru->clksel_con[50]);
313 div = con >> CLK_I2C2_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK;
314 break;
315 case SCLK_I2C3:
316 con = readl(&cru->clksel_con[50]);
317 div = con >> CLK_I2C3_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK;
318 break;
319 default:
320 printf("do not support this i2c bus\n");
321 return -EINVAL;
322 }
323
324 return DIV_TO_RATE(priv->gpll_hz, div);
325 }
326
px30_i2c_set_clk(struct px30_clk_priv * priv,ulong clk_id,uint hz)327 static ulong px30_i2c_set_clk(struct px30_clk_priv *priv, ulong clk_id, uint hz)
328 {
329 struct px30_cru *cru = priv->cru;
330 int src_clk_div;
331
332 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
333 assert(src_clk_div - 1 <= 127);
334
335 switch (clk_id) {
336 case SCLK_I2C0:
337 rk_clrsetreg(&cru->clksel_con[49],
338 CLK_I2C_DIV_CON_MASK << CLK_I2C0_DIV_CON_SHIFT |
339 CLK_I2C_PLL_SEL_MASK << CLK_I2C0_PLL_SEL_SHIFT,
340 (src_clk_div - 1) << CLK_I2C0_DIV_CON_SHIFT |
341 CLK_I2C_PLL_SEL_GPLL << CLK_I2C0_PLL_SEL_SHIFT);
342 break;
343 case SCLK_I2C1:
344 rk_clrsetreg(&cru->clksel_con[49],
345 CLK_I2C_DIV_CON_MASK << CLK_I2C1_DIV_CON_SHIFT |
346 CLK_I2C_PLL_SEL_MASK << CLK_I2C1_PLL_SEL_SHIFT,
347 (src_clk_div - 1) << CLK_I2C1_DIV_CON_SHIFT |
348 CLK_I2C_PLL_SEL_GPLL << CLK_I2C1_PLL_SEL_SHIFT);
349 break;
350 case SCLK_I2C2:
351 rk_clrsetreg(&cru->clksel_con[50],
352 CLK_I2C_DIV_CON_MASK << CLK_I2C2_DIV_CON_SHIFT |
353 CLK_I2C_PLL_SEL_MASK << CLK_I2C2_PLL_SEL_SHIFT,
354 (src_clk_div - 1) << CLK_I2C2_DIV_CON_SHIFT |
355 CLK_I2C_PLL_SEL_GPLL << CLK_I2C2_PLL_SEL_SHIFT);
356 break;
357 case SCLK_I2C3:
358 rk_clrsetreg(&cru->clksel_con[50],
359 CLK_I2C_DIV_CON_MASK << CLK_I2C3_DIV_CON_SHIFT |
360 CLK_I2C_PLL_SEL_MASK << CLK_I2C3_PLL_SEL_SHIFT,
361 (src_clk_div - 1) << CLK_I2C3_DIV_CON_SHIFT |
362 CLK_I2C_PLL_SEL_GPLL << CLK_I2C3_PLL_SEL_SHIFT);
363 break;
364 default:
365 printf("do not support this i2c bus\n");
366 return -EINVAL;
367 }
368
369 return px30_i2c_get_clk(priv, clk_id);
370 }
371
372 /*
373 * calculate best rational approximation for a given fraction
374 * taking into account restricted register size, e.g. to find
375 * appropriate values for a pll with 5 bit denominator and
376 * 8 bit numerator register fields, trying to set up with a
377 * frequency ratio of 3.1415, one would say:
378 *
379 * rational_best_approximation(31415, 10000,
380 * (1 << 8) - 1, (1 << 5) - 1, &n, &d);
381 *
382 * you may look at given_numerator as a fixed point number,
383 * with the fractional part size described in given_denominator.
384 *
385 * for theoretical background, see:
386 * http://en.wikipedia.org/wiki/Continued_fraction
387 */
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)388 static void rational_best_approximation(
389 unsigned long given_numerator, unsigned long given_denominator,
390 unsigned long max_numerator, unsigned long max_denominator,
391 unsigned long *best_numerator, unsigned long *best_denominator)
392 {
393 unsigned long n, d, n0, d0, n1, d1;
394
395 n = given_numerator;
396 d = given_denominator;
397 n0 = 0;
398 d1 = 0;
399 n1 = 1;
400 d0 = 1;
401 for (;;) {
402 unsigned long t, a;
403
404 if (n1 > max_numerator || d1 > max_denominator) {
405 n1 = n0;
406 d1 = d0;
407 break;
408 }
409 if (d == 0)
410 break;
411 t = d;
412 a = n / d;
413 d = n % d;
414 n = t;
415 t = n0 + a * n1;
416 n0 = n1;
417 n1 = t;
418 t = d0 + a * d1;
419 d0 = d1;
420 d1 = t;
421 }
422 *best_numerator = n1;
423 *best_denominator = d1;
424 }
425
px30_i2s_get_clk(struct px30_clk_priv * priv,ulong clk_id)426 static ulong px30_i2s_get_clk(struct px30_clk_priv *priv, ulong clk_id)
427 {
428 u32 con, fracdiv, gate;
429 u32 clk_src = GPLL_HZ / 2;
430 unsigned long m, n;
431 struct px30_cru *cru = priv->cru;
432
433 switch (clk_id) {
434 case SCLK_I2S1:
435 con = readl(&cru->clksel_con[30]);
436 fracdiv = readl(&cru->clksel_con[31]);
437 gate = readl(&cru->clkgate_con[10]);
438 n = fracdiv & CLK_I2S1_FRAC_NUMERATOR_MASK;
439 n >>= CLK_I2S1_FRAC_NUMERATOR_SHIFT;
440 m = fracdiv & CLK_I2S1_FRAC_DENOMINATOR_MASK;
441 m >>= CLK_I2S1_FRAC_DENOMINATOR_SHIFT;
442 debug("con30: 0x%x, gate: 0x%x, frac: 0x%x\n",
443 con, gate, fracdiv);
444 break;
445 default:
446 printf("do not support this i2s bus\n");
447 return -EINVAL;
448 }
449
450 return clk_src * n / m;
451 }
452
px30_i2s_set_clk(struct px30_clk_priv * priv,ulong clk_id,uint hz)453 static ulong px30_i2s_set_clk(struct px30_clk_priv *priv, ulong clk_id, uint hz)
454 {
455 u32 clk_src;
456 unsigned long m, n, val;
457 struct px30_cru *cru = priv->cru;
458
459 clk_src = GPLL_HZ / 2;
460 rational_best_approximation(hz, clk_src,
461 GENMASK(16 - 1, 0),
462 GENMASK(16 - 1, 0),
463 &m, &n);
464 switch (clk_id) {
465 case SCLK_I2S1:
466 rk_clrsetreg(&cru->clksel_con[30],
467 CLK_I2S1_PLL_SEL_MASK, CLK_I2S1_PLL_SEL_GPLL);
468 rk_clrsetreg(&cru->clksel_con[30],
469 CLK_I2S1_DIV_CON_MASK, 0x1);
470 rk_clrsetreg(&cru->clksel_con[30],
471 CLK_I2S1_SEL_MASK, CLK_I2S1_SEL_FRAC);
472 val = m << CLK_I2S1_FRAC_NUMERATOR_SHIFT | n;
473 writel(val, &cru->clksel_con[31]);
474 rk_clrsetreg(&cru->clkgate_con[10],
475 CLK_I2S1_OUT_MCLK_PAD_MASK,
476 CLK_I2S1_OUT_MCLK_PAD_ENABLE);
477 break;
478 default:
479 printf("do not support this i2s bus\n");
480 return -EINVAL;
481 }
482
483 return px30_i2s_get_clk(priv, clk_id);
484 }
485
px30_i2s1_mclk_get_clk(struct px30_clk_priv * priv,ulong clk_id)486 static ulong px30_i2s1_mclk_get_clk(struct px30_clk_priv *priv, ulong clk_id)
487 {
488 struct px30_cru *cru = priv->cru;
489 u32 con;
490
491 con = readl(&cru->clksel_con[30]);
492
493 if (con & CLK_I2S1_OUT_SEL_MASK)
494 return 12000000;
495
496 return px30_i2s_get_clk(priv, SCLK_I2S1);
497 }
498
px30_i2s1_mclk_set_clk(struct px30_clk_priv * priv,ulong clk_id,ulong hz)499 static ulong px30_i2s1_mclk_set_clk(struct px30_clk_priv *priv, ulong clk_id,
500 ulong hz)
501 {
502 struct px30_cru *cru = priv->cru;
503
504 if (hz == 12000000) {
505 rk_clrsetreg(&cru->clksel_con[30], CLK_I2S1_OUT_SEL_MASK,
506 CLK_I2S1_OUT_SEL_OSC);
507 } else {
508 px30_i2s_set_clk(priv, SCLK_I2S1, hz);
509 rk_clrsetreg(&cru->clksel_con[30], CLK_I2S1_OUT_SEL_MASK,
510 CLK_I2S1_OUT_SEL_I2S1);
511 }
512
513 rk_clrsetreg(&cru->clkgate_con[10], CLK_I2S1_OUT_MCLK_PAD_MASK,
514 CLK_I2S1_OUT_MCLK_PAD_ENABLE);
515
516 return px30_i2s1_mclk_get_clk(priv, clk_id);
517 }
518
px30_nandc_get_clk(struct px30_clk_priv * priv)519 static ulong px30_nandc_get_clk(struct px30_clk_priv *priv)
520 {
521 struct px30_cru *cru = priv->cru;
522 u32 div, con;
523
524 con = readl(&cru->clksel_con[15]);
525 div = (con & NANDC_DIV_MASK) >> NANDC_DIV_SHIFT;
526
527 return DIV_TO_RATE(priv->gpll_hz, div);
528 }
529
px30_nandc_set_clk(struct px30_clk_priv * priv,ulong set_rate)530 static ulong px30_nandc_set_clk(struct px30_clk_priv *priv,
531 ulong set_rate)
532 {
533 struct px30_cru *cru = priv->cru;
534 int src_clk_div;
535
536 /* Select nandc source from GPLL by default */
537 /* nandc clock defaulg div 2 internal, need provide double in cru */
538 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, set_rate);
539 assert(src_clk_div - 1 <= 31);
540
541 rk_clrsetreg(&cru->clksel_con[15],
542 NANDC_CLK_SEL_MASK | NANDC_PLL_MASK |
543 NANDC_DIV_MASK,
544 NANDC_CLK_SEL_NANDC << NANDC_CLK_SEL_SHIFT |
545 NANDC_SEL_GPLL << NANDC_PLL_SHIFT |
546 (src_clk_div - 1) << NANDC_DIV_SHIFT);
547
548 return px30_nandc_get_clk(priv);
549 }
550
px30_mmc_get_clk(struct px30_clk_priv * priv,uint clk_id)551 static ulong px30_mmc_get_clk(struct px30_clk_priv *priv, uint clk_id)
552 {
553 struct px30_cru *cru = priv->cru;
554 u32 div, con, con_id;
555
556 switch (clk_id) {
557 case HCLK_SDMMC:
558 case SCLK_SDMMC:
559 con_id = 16;
560 break;
561 case HCLK_EMMC:
562 case SCLK_EMMC:
563 case SCLK_EMMC_SAMPLE:
564 con_id = 20;
565 break;
566 default:
567 return -EINVAL;
568 }
569
570 con = readl(&cru->clksel_con[con_id]);
571 div = (con & EMMC_DIV_MASK) >> EMMC_DIV_SHIFT;
572
573 if ((con & EMMC_PLL_MASK) >> EMMC_PLL_SHIFT
574 == EMMC_SEL_24M)
575 return DIV_TO_RATE(OSC_HZ, div) / 2;
576 else
577 return DIV_TO_RATE(priv->gpll_hz, div) / 2;
578
579 }
580
px30_mmc_set_clk(struct px30_clk_priv * priv,ulong clk_id,ulong set_rate)581 static ulong px30_mmc_set_clk(struct px30_clk_priv *priv,
582 ulong clk_id, ulong set_rate)
583 {
584 struct px30_cru *cru = priv->cru;
585 int src_clk_div;
586 u32 con_id;
587
588 switch (clk_id) {
589 case HCLK_SDMMC:
590 case SCLK_SDMMC:
591 con_id = 16;
592 break;
593 case HCLK_EMMC:
594 case SCLK_EMMC:
595 con_id = 20;
596 break;
597 default:
598 return -EINVAL;
599 }
600
601 /* Select clk_sdmmc/emmc source from GPLL by default */
602 /* mmc clock defaulg div 2 internal, need provide double in cru */
603 src_clk_div = DIV_ROUND_UP(priv->gpll_hz / 2, set_rate);
604
605 if (src_clk_div > 127) {
606 /* use 24MHz source for 400KHz clock */
607 src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, set_rate);
608 rk_clrsetreg(&cru->clksel_con[con_id],
609 EMMC_PLL_MASK | EMMC_DIV_MASK,
610 EMMC_SEL_24M << EMMC_PLL_SHIFT |
611 (src_clk_div - 1) << EMMC_DIV_SHIFT);
612 } else {
613 rk_clrsetreg(&cru->clksel_con[con_id],
614 EMMC_PLL_MASK | EMMC_DIV_MASK,
615 EMMC_SEL_GPLL << EMMC_PLL_SHIFT |
616 (src_clk_div - 1) << EMMC_DIV_SHIFT);
617 }
618 rk_clrsetreg(&cru->clksel_con[con_id +1], EMMC_CLK_SEL_MASK,
619 EMMC_CLK_SEL_EMMC);
620
621 return px30_mmc_get_clk(priv, clk_id);
622 }
623
px30_sfc_get_clk(struct px30_clk_priv * priv,uint clk_id)624 static ulong px30_sfc_get_clk(struct px30_clk_priv *priv, uint clk_id)
625 {
626 struct px30_cru *cru = priv->cru;
627 u32 div, con;
628
629 con = readl(&cru->clksel_con[22]);
630 div = (con & SFC_DIV_CON_MASK) >> SFC_DIV_CON_SHIFT;
631
632 return DIV_TO_RATE(priv->gpll_hz, div);
633 }
634
px30_sfc_set_clk(struct px30_clk_priv * priv,ulong clk_id,ulong set_rate)635 static ulong px30_sfc_set_clk(struct px30_clk_priv *priv,
636 ulong clk_id, ulong set_rate)
637 {
638 struct px30_cru *cru = priv->cru;
639 int src_clk_div;
640
641 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, set_rate);
642 rk_clrsetreg(&cru->clksel_con[22],
643 SFC_PLL_SEL_MASK | SFC_DIV_CON_MASK,
644 0 << SFC_PLL_SEL_SHIFT |
645 (src_clk_div - 1) << SFC_DIV_CON_SHIFT);
646
647 return px30_sfc_get_clk(priv, clk_id);
648 }
649
px30_pwm_get_clk(struct px30_clk_priv * priv,ulong clk_id)650 static ulong px30_pwm_get_clk(struct px30_clk_priv *priv, ulong clk_id)
651 {
652 struct px30_cru *cru = priv->cru;
653 u32 div, con;
654
655 switch (clk_id) {
656 case SCLK_PWM0:
657 con = readl(&cru->clksel_con[52]);
658 div = con >> CLK_PWM0_DIV_CON_SHIFT & CLK_PWM_DIV_CON_MASK;
659 break;
660 case SCLK_PWM1:
661 con = readl(&cru->clksel_con[52]);
662 div = con >> CLK_PWM1_DIV_CON_SHIFT & CLK_PWM_DIV_CON_MASK;
663 break;
664 default:
665 printf("do not support this pwm bus\n");
666 return -EINVAL;
667 }
668
669 return DIV_TO_RATE(priv->gpll_hz, div);
670 }
671
px30_pwm_set_clk(struct px30_clk_priv * priv,ulong clk_id,uint hz)672 static ulong px30_pwm_set_clk(struct px30_clk_priv *priv, ulong clk_id, uint hz)
673 {
674 struct px30_cru *cru = priv->cru;
675 int src_clk_div;
676
677 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
678 assert(src_clk_div - 1 <= 127);
679
680 switch (clk_id) {
681 case SCLK_PWM0:
682 rk_clrsetreg(&cru->clksel_con[52],
683 CLK_PWM_DIV_CON_MASK << CLK_PWM0_DIV_CON_SHIFT |
684 CLK_PWM_PLL_SEL_MASK << CLK_PWM0_PLL_SEL_SHIFT,
685 (src_clk_div - 1) << CLK_PWM0_DIV_CON_SHIFT |
686 CLK_PWM_PLL_SEL_GPLL << CLK_PWM0_PLL_SEL_SHIFT);
687 break;
688 case SCLK_PWM1:
689 rk_clrsetreg(&cru->clksel_con[52],
690 CLK_PWM_DIV_CON_MASK << CLK_PWM1_DIV_CON_SHIFT |
691 CLK_PWM_PLL_SEL_MASK << CLK_PWM1_PLL_SEL_SHIFT,
692 (src_clk_div - 1) << CLK_PWM1_DIV_CON_SHIFT |
693 CLK_PWM_PLL_SEL_GPLL << CLK_PWM1_PLL_SEL_SHIFT);
694 break;
695 default:
696 printf("do not support this pwm bus\n");
697 return -EINVAL;
698 }
699
700 return px30_pwm_get_clk(priv, clk_id);
701 }
702
px30_saradc_get_clk(struct px30_clk_priv * priv)703 static ulong px30_saradc_get_clk(struct px30_clk_priv *priv)
704 {
705 struct px30_cru *cru = priv->cru;
706 u32 div, con;
707
708 con = readl(&cru->clksel_con[55]);
709 div = con >> CLK_SARADC_DIV_CON_SHIFT & CLK_SARADC_DIV_CON_MASK;
710
711 return DIV_TO_RATE(OSC_HZ, div);
712 }
713
px30_saradc_set_clk(struct px30_clk_priv * priv,uint hz)714 static ulong px30_saradc_set_clk(struct px30_clk_priv *priv, uint hz)
715 {
716 struct px30_cru *cru = priv->cru;
717 int src_clk_div;
718
719 src_clk_div = DIV_ROUND_UP(OSC_HZ, hz);
720 assert(src_clk_div - 1 <= 2047);
721
722 rk_clrsetreg(&cru->clksel_con[55],
723 CLK_SARADC_DIV_CON_MASK,
724 (src_clk_div - 1) << CLK_SARADC_DIV_CON_SHIFT);
725
726 return px30_saradc_get_clk(priv);
727 }
728
px30_tsadc_get_clk(struct px30_clk_priv * priv)729 static ulong px30_tsadc_get_clk(struct px30_clk_priv *priv)
730 {
731 struct px30_cru *cru = priv->cru;
732 u32 div, con;
733
734 con = readl(&cru->clksel_con[54]);
735 div = con >> CLK_SARADC_DIV_CON_SHIFT & CLK_SARADC_DIV_CON_MASK;
736
737 return DIV_TO_RATE(OSC_HZ, div);
738 }
739
px30_tsadc_set_clk(struct px30_clk_priv * priv,uint hz)740 static ulong px30_tsadc_set_clk(struct px30_clk_priv *priv, uint hz)
741 {
742 struct px30_cru *cru = priv->cru;
743 int src_clk_div;
744
745 src_clk_div = DIV_ROUND_UP(OSC_HZ, hz);
746 assert(src_clk_div - 1 <= 2047);
747
748 rk_clrsetreg(&cru->clksel_con[54],
749 CLK_SARADC_DIV_CON_MASK,
750 (src_clk_div - 1) << CLK_SARADC_DIV_CON_SHIFT);
751
752 return px30_tsadc_get_clk(priv);
753 }
754
px30_spi_get_clk(struct px30_clk_priv * priv,ulong clk_id)755 static ulong px30_spi_get_clk(struct px30_clk_priv *priv, ulong clk_id)
756 {
757 struct px30_cru *cru = priv->cru;
758 u32 div, con;
759
760 switch (clk_id) {
761 case SCLK_SPI0:
762 con = readl(&cru->clksel_con[53]);
763 div = con >> CLK_SPI0_DIV_CON_SHIFT & CLK_SPI_DIV_CON_MASK;
764 break;
765 case SCLK_SPI1:
766 con = readl(&cru->clksel_con[53]);
767 div = con >> CLK_SPI1_DIV_CON_SHIFT & CLK_SPI_DIV_CON_MASK;
768 break;
769 default:
770 printf("do not support this pwm bus\n");
771 return -EINVAL;
772 }
773
774 return DIV_TO_RATE(priv->gpll_hz, div);
775 }
776
px30_spi_set_clk(struct px30_clk_priv * priv,ulong clk_id,uint hz)777 static ulong px30_spi_set_clk(struct px30_clk_priv *priv, ulong clk_id, uint hz)
778 {
779 struct px30_cru *cru = priv->cru;
780 int src_clk_div;
781
782 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
783 assert(src_clk_div - 1 <= 127);
784
785 switch (clk_id) {
786 case SCLK_SPI0:
787 rk_clrsetreg(&cru->clksel_con[53],
788 CLK_SPI_DIV_CON_MASK << CLK_SPI0_DIV_CON_SHIFT |
789 CLK_SPI_PLL_SEL_MASK << CLK_SPI0_PLL_SEL_SHIFT,
790 (src_clk_div - 1) << CLK_SPI0_DIV_CON_SHIFT |
791 CLK_SPI_PLL_SEL_GPLL << CLK_SPI0_PLL_SEL_SHIFT);
792 break;
793 case SCLK_SPI1:
794 rk_clrsetreg(&cru->clksel_con[53],
795 CLK_SPI_DIV_CON_MASK << CLK_SPI1_DIV_CON_SHIFT |
796 CLK_SPI_PLL_SEL_MASK << CLK_SPI1_PLL_SEL_SHIFT,
797 (src_clk_div - 1) << CLK_SPI1_DIV_CON_SHIFT |
798 CLK_SPI_PLL_SEL_GPLL << CLK_SPI1_PLL_SEL_SHIFT);
799 break;
800 default:
801 printf("do not support this pwm bus\n");
802 return -EINVAL;
803 }
804
805 return px30_spi_get_clk(priv, clk_id);
806 }
807
px30_vop_get_clk(struct px30_clk_priv * priv,ulong clk_id)808 static ulong px30_vop_get_clk(struct px30_clk_priv *priv, ulong clk_id)
809 {
810 struct px30_cru *cru = priv->cru;
811 u32 div, con, parent;
812
813 switch (clk_id) {
814 case ACLK_VOPB:
815 case ACLK_VOPL:
816 con = readl(&cru->clksel_con[3]);
817 div = con & ACLK_VO_DIV_MASK;
818 parent = priv->gpll_hz;
819 break;
820 case DCLK_VOPB:
821 con = readl(&cru->clksel_con[5]);
822 div = con & DCLK_VOPB_DIV_MASK;
823 parent = rkclk_pll_get_rate(&cru->pll[CPLL], &cru->mode, CPLL);
824 break;
825 case DCLK_VOPL:
826 con = readl(&cru->clksel_con[8]);
827 div = con & DCLK_VOPL_DIV_MASK;
828 parent = rkclk_pll_get_rate(&cru->pll[NPLL], &cru->mode, NPLL);
829 break;
830 default:
831 return -ENOENT;
832 }
833
834 return DIV_TO_RATE(parent, div);
835 }
836
px30_vop_set_clk(struct px30_clk_priv * priv,ulong clk_id,uint hz)837 static ulong px30_vop_set_clk(struct px30_clk_priv *priv, ulong clk_id, uint hz)
838 {
839 struct px30_cru *cru = priv->cru;
840 ulong npll_hz;
841 int src_clk_div;
842
843 switch (clk_id) {
844 case ACLK_VOPB:
845 case ACLK_VOPL:
846 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
847 assert(src_clk_div - 1 <= 31);
848 rk_clrsetreg(&cru->clksel_con[3],
849 ACLK_VO_PLL_MASK | ACLK_VO_DIV_MASK,
850 ACLK_VO_SEL_GPLL << ACLK_VO_PLL_SHIFT |
851 (src_clk_div - 1) << ACLK_VO_DIV_SHIFT);
852 break;
853 case DCLK_VOPB:
854 if (hz < PX30_VOP_PLL_LIMIT) {
855 src_clk_div = DIV_ROUND_UP(PX30_VOP_PLL_LIMIT, hz);
856 if (src_clk_div % 2)
857 src_clk_div = src_clk_div - 1;
858 } else {
859 src_clk_div = 1;
860 }
861 assert(src_clk_div - 1 <= 255);
862 rkclk_set_pll(&cru->pll[CPLL], &cru->mode, CPLL, hz * src_clk_div);
863 rk_clrsetreg(&cru->clksel_con[5],
864 DCLK_VOPB_SEL_MASK | DCLK_VOPB_PLL_SEL_MASK |
865 DCLK_VOPB_DIV_MASK,
866 DCLK_VOPB_SEL_DIVOUT << DCLK_VOPB_SEL_SHIFT |
867 DCLK_VOPB_PLL_SEL_CPLL << DCLK_VOPB_PLL_SEL_SHIFT |
868 (src_clk_div - 1) << DCLK_VOPB_DIV_SHIFT);
869 break;
870 case DCLK_VOPL:
871 npll_hz = px30_clk_get_pll_rate(priv, NPLL);
872 if (npll_hz >= PX30_VOP_PLL_LIMIT && npll_hz >= hz && npll_hz % hz == 0) {
873 src_clk_div = npll_hz / hz;
874 assert(src_clk_div - 1 <= 255);
875 } else {
876 if (hz < PX30_VOP_PLL_LIMIT) {
877 src_clk_div = DIV_ROUND_UP(PX30_VOP_PLL_LIMIT, hz);
878 if (src_clk_div % 2)
879 src_clk_div = src_clk_div - 1;
880 } else {
881 src_clk_div = 1;
882 }
883 assert(src_clk_div - 1 <= 255);
884 rkclk_set_pll(&cru->pll[NPLL], &cru->mode, NPLL, hz * src_clk_div);
885 }
886 rk_clrsetreg(&cru->clksel_con[8],
887 DCLK_VOPL_SEL_MASK | DCLK_VOPL_PLL_SEL_MASK |
888 DCLK_VOPL_DIV_MASK,
889 DCLK_VOPL_SEL_DIVOUT << DCLK_VOPL_SEL_SHIFT |
890 DCLK_VOPL_PLL_SEL_NPLL << DCLK_VOPL_PLL_SEL_SHIFT |
891 (src_clk_div - 1) << DCLK_VOPL_DIV_SHIFT);
892 break;
893 default:
894 printf("do not support this vop freq\n");
895 return -EINVAL;
896 }
897
898 return px30_vop_get_clk(priv, clk_id);
899 }
900
px30_bus_get_clk(struct px30_clk_priv * priv,ulong clk_id)901 static ulong px30_bus_get_clk(struct px30_clk_priv *priv, ulong clk_id)
902 {
903 struct px30_cru *cru = priv->cru;
904 u32 div, con, parent;
905
906 switch (clk_id) {
907 case ACLK_BUS_PRE:
908 con = readl(&cru->clksel_con[23]);
909 div = (con & BUS_ACLK_DIV_MASK) >> BUS_ACLK_DIV_SHIFT;
910 parent = priv->gpll_hz;
911 break;
912 case HCLK_BUS_PRE:
913 con = readl(&cru->clksel_con[24]);
914 div = (con & BUS_HCLK_DIV_MASK) >> BUS_HCLK_DIV_SHIFT;
915 parent = priv->gpll_hz;
916 break;
917 case PCLK_BUS_PRE:
918 case PCLK_WDT_NS:
919 parent = px30_bus_get_clk(priv, ACLK_BUS_PRE);
920 con = readl(&cru->clksel_con[24]);
921 div = (con & BUS_PCLK_DIV_MASK) >> BUS_PCLK_DIV_SHIFT;
922 break;
923 default:
924 return -ENOENT;
925 }
926
927 return DIV_TO_RATE(parent, div);
928 }
929
px30_bus_set_clk(struct px30_clk_priv * priv,ulong clk_id,ulong hz)930 static ulong px30_bus_set_clk(struct px30_clk_priv *priv, ulong clk_id,
931 ulong hz)
932 {
933 struct px30_cru *cru = priv->cru;
934 int src_clk_div;
935
936 /*
937 * select gpll as pd_bus bus clock source and
938 * set up dependent divisors for PCLK/HCLK and ACLK clocks.
939 */
940 switch (clk_id) {
941 case ACLK_BUS_PRE:
942 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
943 assert(src_clk_div - 1 <= 31);
944 rk_clrsetreg(&cru->clksel_con[23],
945 BUS_PLL_SEL_MASK | BUS_ACLK_DIV_MASK,
946 BUS_PLL_SEL_GPLL << BUS_PLL_SEL_SHIFT |
947 (src_clk_div - 1) << BUS_ACLK_DIV_SHIFT);
948 break;
949 case HCLK_BUS_PRE:
950 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
951 assert(src_clk_div - 1 <= 31);
952 rk_clrsetreg(&cru->clksel_con[24],
953 BUS_PLL_SEL_MASK | BUS_HCLK_DIV_MASK,
954 BUS_PLL_SEL_GPLL << BUS_PLL_SEL_SHIFT |
955 (src_clk_div - 1) << BUS_HCLK_DIV_SHIFT);
956 break;
957 case PCLK_BUS_PRE:
958 src_clk_div =
959 DIV_ROUND_UP(px30_bus_get_clk(priv, ACLK_BUS_PRE), hz);
960 assert(src_clk_div - 1 <= 3);
961 rk_clrsetreg(&cru->clksel_con[24],
962 BUS_PCLK_DIV_MASK,
963 (src_clk_div - 1) << BUS_PCLK_DIV_SHIFT);
964 break;
965 default:
966 printf("do not support this bus freq\n");
967 return -EINVAL;
968 }
969
970 return px30_bus_get_clk(priv, clk_id);
971 }
972
px30_peri_get_clk(struct px30_clk_priv * priv,ulong clk_id)973 static ulong px30_peri_get_clk(struct px30_clk_priv *priv, ulong clk_id)
974 {
975 struct px30_cru *cru = priv->cru;
976 u32 div, con, parent;
977
978 switch (clk_id) {
979 case ACLK_PERI_PRE:
980 con = readl(&cru->clksel_con[14]);
981 div = (con & PERI_ACLK_DIV_MASK) >> PERI_ACLK_DIV_SHIFT;
982 parent = priv->gpll_hz;
983 break;
984 case HCLK_PERI_PRE:
985 con = readl(&cru->clksel_con[14]);
986 div = (con & PERI_HCLK_DIV_MASK) >> PERI_HCLK_DIV_SHIFT;
987 parent = priv->gpll_hz;
988 break;
989 default:
990 return -ENOENT;
991 }
992
993 return DIV_TO_RATE(parent, div);
994 }
995
px30_peri_set_clk(struct px30_clk_priv * priv,ulong clk_id,ulong hz)996 static ulong px30_peri_set_clk(struct px30_clk_priv *priv, ulong clk_id,
997 ulong hz)
998 {
999 struct px30_cru *cru = priv->cru;
1000 int src_clk_div;
1001
1002 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
1003 assert(src_clk_div - 1 <= 31);
1004
1005 /*
1006 * select gpll as pd_peri bus clock source and
1007 * set up dependent divisors for HCLK and ACLK clocks.
1008 */
1009 switch (clk_id) {
1010 case ACLK_PERI_PRE:
1011 rk_clrsetreg(&cru->clksel_con[14],
1012 PERI_PLL_SEL_MASK | PERI_ACLK_DIV_MASK,
1013 PERI_PLL_GPLL << PERI_PLL_SEL_SHIFT |
1014 (src_clk_div - 1) << PERI_ACLK_DIV_SHIFT);
1015 break;
1016 case HCLK_PERI_PRE:
1017 rk_clrsetreg(&cru->clksel_con[14],
1018 PERI_PLL_SEL_MASK | PERI_HCLK_DIV_MASK,
1019 PERI_PLL_GPLL << PERI_PLL_SEL_SHIFT |
1020 (src_clk_div - 1) << PERI_HCLK_DIV_SHIFT);
1021 break;
1022 default:
1023 printf("do not support this peri freq\n");
1024 return -EINVAL;
1025 }
1026
1027 return px30_peri_get_clk(priv, clk_id);
1028 }
1029
px30_otp_get_clk(struct px30_clk_priv * priv,ulong clk_id)1030 static ulong px30_otp_get_clk(struct px30_clk_priv *priv, ulong clk_id)
1031 {
1032 struct px30_cru *cru = priv->cru;
1033 u32 src, div, con, parent;
1034
1035 if (soc_is_px30s()) {
1036 con = readl(&cru->clksel_con[56]);
1037 src = (con & CLK_OTP_S_SEL_MASK) >> CLK_OTP_S_SEL_SHIFT;
1038 div = (con & CLK_OTP_S_DIV_CON_MASK) >> CLK_OTP_S_DIV_CON_SHIFT;
1039 if (src)
1040 return DIV_TO_RATE(priv->gpll_hz, div);
1041 else
1042 return DIV_TO_RATE(OSC_HZ, div);
1043 }
1044
1045 switch (clk_id) {
1046 case SCLK_OTP:
1047 con = readl(&cru->clksel_con[56]);
1048 div = (con & CLK_OTP_DIV_CON_MASK) >> CLK_OTP_DIV_CON_SHIFT;
1049 parent = OSC_HZ;
1050 break;
1051 case SCLK_OTP_USR:
1052 con = readl(&cru->clksel_con[56]);
1053 div = (con & CLK_OTP_USR_DIV_CON_MASK) >>
1054 CLK_OTP_USR_DIV_CON_SHIFT;
1055 parent = px30_otp_get_clk(priv, SCLK_OTP);
1056 break;
1057 default:
1058 return -ENOENT;
1059 }
1060
1061 return DIV_TO_RATE(parent, div);
1062 }
1063
px30_otp_set_clk(struct px30_clk_priv * priv,ulong clk_id,ulong hz)1064 static ulong px30_otp_set_clk(struct px30_clk_priv *priv, ulong clk_id,
1065 ulong hz)
1066 {
1067 struct px30_cru *cru = priv->cru;
1068 u32 src, div, parent;
1069
1070 if (soc_is_px30s()) {
1071 if ((OSC_HZ % hz) == 0) {
1072 src = 0;
1073 parent = OSC_HZ;
1074 } else {
1075 src = 1;
1076 parent = priv->gpll_hz;
1077 }
1078 div = DIV_ROUND_UP(parent, hz);
1079 rk_clrsetreg(&cru->clksel_con[56],
1080 CLK_OTP_S_SEL_MASK | CLK_OTP_S_DIV_CON_MASK,
1081 src << CLK_OTP_S_SEL_SHIFT |
1082 (div - 1) << CLK_OTP_S_DIV_CON_SHIFT);
1083 return px30_otp_get_clk(priv, clk_id);
1084 }
1085
1086 switch (clk_id) {
1087 case SCLK_OTP:
1088 div = DIV_ROUND_UP(OSC_HZ, hz);
1089 rk_clrsetreg(&cru->clksel_con[56],
1090 CLK_OTP_DIV_CON_MASK,
1091 (div - 1) << CLK_OTP_DIV_CON_SHIFT);
1092 break;
1093 case SCLK_OTP_USR:
1094 div = DIV_ROUND_UP(px30_otp_get_clk(priv, SCLK_OTP), hz);
1095 rk_clrsetreg(&cru->clksel_con[56],
1096 CLK_OTP_USR_DIV_CON_MASK,
1097 (div - 1) << CLK_OTP_USR_DIV_CON_SHIFT);
1098 break;
1099 default:
1100 printf("do not support this peri freq\n");
1101 return -EINVAL;
1102 }
1103
1104 return px30_otp_get_clk(priv, clk_id);
1105 }
1106
px30_crypto_get_clk(struct px30_clk_priv * priv,ulong clk_id)1107 static ulong px30_crypto_get_clk(struct px30_clk_priv *priv, ulong clk_id)
1108 {
1109 struct px30_cru *cru = priv->cru;
1110 u32 div, con, parent;
1111
1112 switch (clk_id) {
1113 case SCLK_CRYPTO:
1114 con = readl(&cru->clksel_con[25]);
1115 div = (con & CRYPTO_DIV_MASK) >> CRYPTO_DIV_SHIFT;
1116 parent = priv->gpll_hz;
1117 break;
1118 case SCLK_CRYPTO_APK:
1119 con = readl(&cru->clksel_con[25]);
1120 div = (con & CRYPTO_APK_DIV_MASK) >> CRYPTO_APK_DIV_SHIFT;
1121 parent = priv->gpll_hz;
1122 break;
1123 default:
1124 return -ENOENT;
1125 }
1126
1127 return DIV_TO_RATE(parent, div);
1128 }
1129
px30_crypto_set_clk(struct px30_clk_priv * priv,ulong clk_id,ulong hz)1130 static ulong px30_crypto_set_clk(struct px30_clk_priv *priv, ulong clk_id,
1131 ulong hz)
1132 {
1133 struct px30_cru *cru = priv->cru;
1134 int src_clk_div;
1135
1136 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
1137 assert(src_clk_div - 1 <= 31);
1138
1139 /*
1140 * select gpll as crypto clock source and
1141 * set up dependent divisors for crypto clocks.
1142 */
1143 switch (clk_id) {
1144 case SCLK_CRYPTO:
1145 rk_clrsetreg(&cru->clksel_con[25],
1146 CRYPTO_PLL_SEL_MASK | CRYPTO_DIV_MASK,
1147 CRYPTO_PLL_SEL_GPLL << CRYPTO_PLL_SEL_SHIFT |
1148 (src_clk_div - 1) << CRYPTO_DIV_SHIFT);
1149 break;
1150 case SCLK_CRYPTO_APK:
1151 rk_clrsetreg(&cru->clksel_con[25],
1152 CRYPTO_APK_PLL_SEL_MASK | CRYPTO_APK_DIV_MASK,
1153 CRYPTO_PLL_SEL_GPLL << CRYPTO_APK_SEL_SHIFT |
1154 (src_clk_div - 1) << CRYPTO_APK_DIV_SHIFT);
1155 break;
1156 default:
1157 printf("do not support this peri freq\n");
1158 return -EINVAL;
1159 }
1160
1161 return px30_crypto_get_clk(priv, clk_id);
1162 }
1163
1164 #ifndef CONFIG_SPL_BUILD
px30_mac_set_clk(struct clk * clk,uint hz)1165 static ulong px30_mac_set_clk(struct clk *clk, uint hz)
1166 {
1167 struct px30_clk_priv *priv = dev_get_priv(clk->dev);
1168 struct px30_cru *cru = priv->cru;
1169 u32 con = readl(&cru->clksel_con[22]);
1170 ulong pll_rate;
1171 u8 div;
1172
1173 if ((con >> GMAC_PLL_SEL_SHIFT) & GMAC_PLL_SEL_CPLL)
1174 pll_rate = px30_clk_get_pll_rate(priv, CPLL);
1175 else if ((con >> GMAC_PLL_SEL_SHIFT) & GMAC_PLL_SEL_NPLL)
1176 pll_rate = px30_clk_get_pll_rate(priv, NPLL);
1177 else
1178 pll_rate = priv->gpll_hz;
1179
1180 /*default set 50MHZ for gmac*/
1181 if (!hz)
1182 hz = 50000000;
1183
1184 div = DIV_ROUND_UP(pll_rate, hz) - 1;
1185 assert(div < 32);
1186 rk_clrsetreg(&cru->clksel_con[22], CLK_GMAC_DIV_MASK,
1187 div << CLK_GMAC_DIV_SHIFT);
1188
1189 return DIV_TO_RATE(pll_rate, div);
1190 }
1191
px30_mac_set_speed_clk(struct clk * clk,uint hz)1192 static int px30_mac_set_speed_clk(struct clk *clk, uint hz)
1193 {
1194 struct px30_clk_priv *priv = dev_get_priv(clk->dev);
1195 struct px30_cru *cru = priv->cru;
1196
1197 if (hz != 2500000 && hz != 25000000) {
1198 debug("Unsupported mac speed:%d\n", hz);
1199 return -EINVAL;
1200 }
1201
1202 rk_clrsetreg(&cru->clksel_con[23], RMII_CLK_SEL_MASK,
1203 ((hz == 2500000) ? 0 : 1) << RMII_CLK_SEL_SHIFT);
1204
1205 return 0;
1206 }
1207
1208 #endif
1209
px30_clk_get_gpll_rate(ulong * rate)1210 static int px30_clk_get_gpll_rate(ulong *rate)
1211 {
1212 struct udevice *pmucru_dev;
1213 struct px30_pmuclk_priv *priv;
1214 int ret;
1215
1216 ret = uclass_get_device_by_driver(UCLASS_CLK,
1217 DM_GET_DRIVER(rockchip_px30_pmucru),
1218 &pmucru_dev);
1219 if (ret) {
1220 printf("%s: could not find pmucru device\n", __func__);
1221 return ret;
1222 }
1223 priv = dev_get_priv(pmucru_dev);
1224 *rate = priv->gpll_hz;
1225
1226 return 0;
1227 }
1228
px30_clk_get_pll_rate(struct px30_clk_priv * priv,enum px30_pll_id pll_id)1229 static ulong px30_clk_get_pll_rate(struct px30_clk_priv *priv,
1230 enum px30_pll_id pll_id)
1231 {
1232 struct px30_cru *cru = priv->cru;
1233
1234 return rkclk_pll_get_rate(&cru->pll[pll_id], &cru->mode, pll_id);
1235 }
1236
px30_clk_set_pll_rate(struct px30_clk_priv * priv,enum px30_pll_id pll_id,ulong hz)1237 static ulong px30_clk_set_pll_rate(struct px30_clk_priv *priv,
1238 enum px30_pll_id pll_id, ulong hz)
1239 {
1240 struct px30_cru *cru = priv->cru;
1241
1242 if (rkclk_set_pll(&cru->pll[pll_id], &cru->mode, pll_id, hz))
1243 return -EINVAL;
1244 return rkclk_pll_get_rate(&cru->pll[pll_id], &cru->mode, pll_id);
1245 }
1246
px30_armclk_set_clk(struct px30_clk_priv * priv,ulong hz)1247 static ulong px30_armclk_set_clk(struct px30_clk_priv *priv, ulong hz)
1248 {
1249 struct px30_cru *cru = priv->cru;
1250 const struct cpu_rate_table *rate;
1251 ulong old_rate;
1252
1253 rate = get_cpu_settings(hz);
1254 if (!rate) {
1255 printf("%s unsupport rate\n", __func__);
1256 return -EINVAL;
1257 }
1258
1259 /*
1260 * select apll as cpu/core clock pll source and
1261 * set up dependent divisors for PERI and ACLK clocks.
1262 * core hz : apll = 1:1
1263 */
1264 old_rate = px30_clk_get_pll_rate(priv, APLL);
1265 if (old_rate > hz) {
1266 if (rkclk_set_pll(&cru->pll[APLL], &cru->mode, APLL, hz))
1267 return -EINVAL;
1268 rk_clrsetreg(&cru->clksel_con[0],
1269 CORE_CLK_PLL_SEL_MASK | CORE_DIV_CON_MASK |
1270 CORE_ACLK_DIV_MASK | CORE_DBG_DIV_MASK,
1271 rate->aclk_div << CORE_ACLK_DIV_SHIFT |
1272 rate->pclk_div << CORE_DBG_DIV_SHIFT |
1273 CORE_CLK_PLL_SEL_APLL << CORE_CLK_PLL_SEL_SHIFT |
1274 0 << CORE_DIV_CON_SHIFT);
1275 } else if (old_rate < hz) {
1276 rk_clrsetreg(&cru->clksel_con[0],
1277 CORE_CLK_PLL_SEL_MASK | CORE_DIV_CON_MASK |
1278 CORE_ACLK_DIV_MASK | CORE_DBG_DIV_MASK,
1279 rate->aclk_div << CORE_ACLK_DIV_SHIFT |
1280 rate->pclk_div << CORE_DBG_DIV_SHIFT |
1281 CORE_CLK_PLL_SEL_APLL << CORE_CLK_PLL_SEL_SHIFT |
1282 0 << CORE_DIV_CON_SHIFT);
1283 if (rkclk_set_pll(&cru->pll[APLL], &cru->mode, APLL, hz))
1284 return -EINVAL;
1285 }
1286
1287 return px30_clk_get_pll_rate(priv, APLL);
1288 }
1289
px30_clk_get_rate(struct clk * clk)1290 static ulong px30_clk_get_rate(struct clk *clk)
1291 {
1292 struct px30_clk_priv *priv = dev_get_priv(clk->dev);
1293 ulong rate = 0;
1294
1295 if (!priv->gpll_hz && clk->id > ARMCLK) {
1296 printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
1297 return -ENOENT;
1298 }
1299
1300 debug("%s %ld\n", __func__, clk->id);
1301 switch (clk->id) {
1302 case PLL_APLL:
1303 rate = px30_clk_get_pll_rate(priv, APLL);
1304 break;
1305 case PLL_DPLL:
1306 rate = px30_clk_get_pll_rate(priv, DPLL);
1307 break;
1308 case PLL_CPLL:
1309 rate = px30_clk_get_pll_rate(priv, CPLL);
1310 break;
1311 case PLL_NPLL:
1312 rate = px30_clk_get_pll_rate(priv, NPLL);
1313 break;
1314 case ARMCLK:
1315 rate = px30_clk_get_pll_rate(priv, APLL);
1316 break;
1317 case HCLK_SDMMC:
1318 case HCLK_EMMC:
1319 case SCLK_SDMMC:
1320 case SCLK_EMMC:
1321 case SCLK_EMMC_SAMPLE:
1322 rate = px30_mmc_get_clk(priv, clk->id);
1323 break;
1324 case SCLK_SFC:
1325 rate = px30_sfc_get_clk(priv, clk->id);
1326 break;
1327 case SCLK_I2C0:
1328 case SCLK_I2C1:
1329 case SCLK_I2C2:
1330 case SCLK_I2C3:
1331 rate = px30_i2c_get_clk(priv, clk->id);
1332 break;
1333 case SCLK_I2S1:
1334 rate = px30_i2s_get_clk(priv, clk->id);
1335 break;
1336 case SCLK_I2S1_OUT:
1337 rate = px30_i2s1_mclk_get_clk(priv, clk->id);
1338 break;
1339 case SCLK_PWM0:
1340 case SCLK_PWM1:
1341 rate = px30_pwm_get_clk(priv, clk->id);
1342 break;
1343 case SCLK_SARADC:
1344 rate = px30_saradc_get_clk(priv);
1345 break;
1346 case SCLK_TSADC:
1347 rate = px30_tsadc_get_clk(priv);
1348 break;
1349 case SCLK_SPI0:
1350 case SCLK_SPI1:
1351 rate = px30_spi_get_clk(priv, clk->id);
1352 break;
1353 case ACLK_VOPB:
1354 case ACLK_VOPL:
1355 case DCLK_VOPB:
1356 case DCLK_VOPL:
1357 rate = px30_vop_get_clk(priv, clk->id);
1358 break;
1359 case ACLK_BUS_PRE:
1360 case HCLK_BUS_PRE:
1361 case PCLK_BUS_PRE:
1362 case PCLK_WDT_NS:
1363 rate = px30_bus_get_clk(priv, clk->id);
1364 break;
1365 case ACLK_PERI_PRE:
1366 case HCLK_PERI_PRE:
1367 rate = px30_peri_get_clk(priv, clk->id);
1368 break;
1369 case SCLK_OTP:
1370 case SCLK_OTP_USR:
1371 rate = px30_otp_get_clk(priv, clk->id);
1372 break;
1373 case SCLK_CRYPTO:
1374 case SCLK_CRYPTO_APK:
1375 rate = px30_crypto_get_clk(priv, clk->id);
1376 break;
1377 default:
1378 return -ENOENT;
1379 }
1380
1381 return rate;
1382 }
1383
px30_clk_set_rate(struct clk * clk,ulong rate)1384 static ulong px30_clk_set_rate(struct clk *clk, ulong rate)
1385 {
1386 struct px30_clk_priv *priv = dev_get_priv(clk->dev);
1387 ulong ret = 0;
1388
1389 if (!priv->gpll_hz && clk->id > ARMCLK) {
1390 printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
1391 return -ENOENT;
1392 }
1393
1394 debug("%s %ld %ld\n", __func__, clk->id, rate);
1395 switch (clk->id) {
1396 case PLL_NPLL:
1397 ret = px30_clk_set_pll_rate(priv, NPLL, rate);
1398 break;
1399 case ARMCLK:
1400 if (priv->armclk_hz)
1401 px30_armclk_set_clk(priv, rate);
1402 priv->armclk_hz = rate;
1403 break;
1404 case HCLK_SDMMC:
1405 case HCLK_EMMC:
1406 case SCLK_SDMMC:
1407 case SCLK_EMMC:
1408 ret = px30_mmc_set_clk(priv, clk->id, rate);
1409 break;
1410 case SCLK_SFC:
1411 ret = px30_sfc_set_clk(priv, clk->id, rate);
1412 break;
1413 case SCLK_I2C0:
1414 case SCLK_I2C1:
1415 case SCLK_I2C2:
1416 case SCLK_I2C3:
1417 ret = px30_i2c_set_clk(priv, clk->id, rate);
1418 break;
1419 case SCLK_I2S1:
1420 ret = px30_i2s_set_clk(priv, clk->id, rate);
1421 break;
1422 case SCLK_I2S1_OUT:
1423 ret = px30_i2s1_mclk_set_clk(priv, clk->id, rate);
1424 break;
1425 case SCLK_PWM0:
1426 case SCLK_PWM1:
1427 ret = px30_pwm_set_clk(priv, clk->id, rate);
1428 break;
1429 case SCLK_SARADC:
1430 ret = px30_saradc_set_clk(priv, rate);
1431 break;
1432 case SCLK_TSADC:
1433 ret = px30_tsadc_set_clk(priv, rate);
1434 break;
1435 case SCLK_SPI0:
1436 case SCLK_SPI1:
1437 ret = px30_spi_set_clk(priv, clk->id, rate);
1438 break;
1439 case ACLK_VOPB:
1440 case ACLK_VOPL:
1441 case DCLK_VOPB:
1442 case DCLK_VOPL:
1443 ret = px30_vop_set_clk(priv, clk->id, rate);
1444 break;
1445 case ACLK_BUS_PRE:
1446 case HCLK_BUS_PRE:
1447 case PCLK_BUS_PRE:
1448 ret = px30_bus_set_clk(priv, clk->id, rate);
1449 break;
1450 case ACLK_PERI_PRE:
1451 case HCLK_PERI_PRE:
1452 ret = px30_peri_set_clk(priv, clk->id, rate);
1453 break;
1454 case SCLK_OTP:
1455 case SCLK_OTP_USR:
1456 ret = px30_otp_set_clk(priv, clk->id, rate);
1457 break;
1458 case SCLK_CRYPTO:
1459 case SCLK_CRYPTO_APK:
1460 ret = px30_crypto_set_clk(priv, clk->id, rate);
1461 break;
1462 #ifndef CONFIG_SPL_BUILD
1463 case SCLK_GMAC:
1464 case SCLK_GMAC_SRC:
1465 ret = px30_mac_set_clk(clk, rate);
1466 break;
1467 case SCLK_GMAC_RMII:
1468 ret = px30_mac_set_speed_clk(clk, rate);
1469 break;
1470 #endif
1471 default:
1472 return -ENOENT;
1473 }
1474
1475 return ret;
1476 }
1477
1478 #define ROCKCHIP_MMC_DELAY_SEL BIT(10)
1479 #define ROCKCHIP_MMC_DEGREE_MASK 0x3
1480 #define ROCKCHIP_MMC_DELAYNUM_OFFSET 2
1481 #define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
1482
1483 #define PSECS_PER_SEC 1000000000000LL
1484 /*
1485 * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to
1486 * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg.
1487 */
1488 #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60
1489
rockchip_mmc_get_phase(struct clk * clk)1490 int rockchip_mmc_get_phase(struct clk *clk)
1491 {
1492 struct px30_clk_priv *priv = dev_get_priv(clk->dev);
1493 struct px30_cru *cru = priv->cru;
1494 u32 raw_value, delay_num;
1495 u16 degrees = 0;
1496 ulong rate;
1497
1498 rate = px30_clk_get_rate(clk);
1499
1500 if (rate < 0)
1501 return rate;
1502
1503 if (clk->id == SCLK_EMMC_SAMPLE)
1504 raw_value = readl(&cru->emmc_con[1]);
1505 else
1506 raw_value = readl(&cru->sdmmc_con[1]);
1507
1508 raw_value >>= 1;
1509 degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90;
1510
1511 if (raw_value & ROCKCHIP_MMC_DELAY_SEL) {
1512 /* degrees/delaynum * 10000 */
1513 unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) *
1514 36 * (rate / 1000000);
1515
1516 delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK);
1517 delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET;
1518 degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000);
1519 }
1520
1521 return degrees % 360;
1522 }
1523
rockchip_mmc_set_phase(struct clk * clk,u32 degrees)1524 int rockchip_mmc_set_phase(struct clk *clk, u32 degrees)
1525 {
1526 struct px30_clk_priv *priv = dev_get_priv(clk->dev);
1527 struct px30_cru *cru = priv->cru;
1528 u8 nineties, remainder, delay_num;
1529 u32 raw_value, delay;
1530 ulong rate;
1531
1532 rate = px30_clk_get_rate(clk);
1533
1534 if (rate < 0)
1535 return rate;
1536
1537 nineties = degrees / 90;
1538 remainder = (degrees % 90);
1539
1540 /*
1541 * Convert to delay; do a little extra work to make sure we
1542 * don't overflow 32-bit / 64-bit numbers.
1543 */
1544 delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */
1545 delay *= remainder;
1546 delay = DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 *
1547 (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10));
1548
1549 delay_num = (u8)min_t(u32, delay, 255);
1550
1551 raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0;
1552 raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET;
1553 raw_value |= nineties;
1554
1555 raw_value <<= 1;
1556 if (clk->id == SCLK_EMMC_SAMPLE)
1557 writel(raw_value | 0xffff0000, &cru->emmc_con[1]);
1558 else
1559 writel(raw_value | 0xffff0000, &cru->sdmmc_con[1]);
1560
1561 debug("mmc set_phase(%d) delay_nums=%u reg=%#x actual_degrees=%d\n",
1562 degrees, delay_num, raw_value, rockchip_mmc_get_phase(clk));
1563
1564 return 0;
1565 }
1566
px30_clk_get_phase(struct clk * clk)1567 static int px30_clk_get_phase(struct clk *clk)
1568 {
1569 int ret;
1570
1571 debug("%s %ld\n", __func__, clk->id);
1572 switch (clk->id) {
1573 case SCLK_EMMC_SAMPLE:
1574 case SCLK_SDMMC_SAMPLE:
1575 ret = rockchip_mmc_get_phase(clk);
1576 break;
1577 default:
1578 return -ENOENT;
1579 }
1580
1581 return ret;
1582 }
1583
px30_clk_set_phase(struct clk * clk,int degrees)1584 static int px30_clk_set_phase(struct clk *clk, int degrees)
1585 {
1586 int ret;
1587
1588 debug("%s %ld\n", __func__, clk->id);
1589 switch (clk->id) {
1590 case SCLK_EMMC_SAMPLE:
1591 case SCLK_SDMMC_SAMPLE:
1592 ret = rockchip_mmc_set_phase(clk, degrees);
1593 break;
1594 default:
1595 return -ENOENT;
1596 }
1597
1598 return ret;
1599 }
1600
1601 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
px30_gmac_set_parent(struct clk * clk,struct clk * parent)1602 static int px30_gmac_set_parent(struct clk *clk, struct clk *parent)
1603 {
1604 struct px30_clk_priv *priv = dev_get_priv(clk->dev);
1605 struct px30_cru *cru = priv->cru;
1606
1607 if (parent->id == SCLK_GMAC_SRC) {
1608 debug("%s: switching GAMC to SCLK_GMAC_SRC\n", __func__);
1609 rk_clrsetreg(&cru->clksel_con[23], RMII_EXTCLK_SEL_MASK,
1610 RMII_EXTCLK_SEL_INT << RMII_EXTCLK_SEL_SHIFT);
1611 } else {
1612 debug("%s: switching GMAC to external clock\n", __func__);
1613 rk_clrsetreg(&cru->clksel_con[23], RMII_EXTCLK_SEL_MASK,
1614 RMII_EXTCLK_SEL_EXT << RMII_EXTCLK_SEL_SHIFT);
1615 }
1616 return 0;
1617 }
1618
px30_clk_set_parent(struct clk * clk,struct clk * parent)1619 static int px30_clk_set_parent(struct clk *clk, struct clk *parent)
1620 {
1621 switch (clk->id) {
1622 case SCLK_GMAC:
1623 return px30_gmac_set_parent(clk, parent);
1624 default:
1625 return -ENOENT;
1626 }
1627 }
1628 #endif
1629
1630 static struct clk_ops px30_clk_ops = {
1631 .get_rate = px30_clk_get_rate,
1632 .set_rate = px30_clk_set_rate,
1633 .get_phase = px30_clk_get_phase,
1634 .set_phase = px30_clk_set_phase,
1635 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
1636 .set_parent = px30_clk_set_parent,
1637 #endif
1638 };
1639
px30_clk_probe(struct udevice * dev)1640 static int px30_clk_probe(struct udevice *dev)
1641 {
1642 struct px30_clk_priv *priv = dev_get_priv(dev);
1643 int ret;
1644
1645 priv->sync_kernel = false;
1646 if (!priv->armclk_enter_hz) {
1647 priv->armclk_enter_hz = px30_clk_get_pll_rate(priv, APLL);
1648 priv->armclk_init_hz = priv->armclk_enter_hz;
1649 }
1650 if (px30_clk_get_pll_rate(priv, APLL) != APLL_HZ) {
1651 ret = px30_armclk_set_clk(priv, APLL_HZ);
1652 if (ret < 0)
1653 printf("%s failed to set armclk rate\n", __func__);
1654 priv->armclk_init_hz = APLL_HZ;
1655 }
1656
1657 /* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
1658 ret = clk_set_defaults(dev);
1659 if (ret)
1660 debug("%s clk_set_defaults failed %d\n", __func__, ret);
1661 else
1662 priv->sync_kernel = true;
1663
1664 if (!priv->gpll_hz) {
1665 ret = px30_clk_get_gpll_rate(&priv->gpll_hz);
1666 if (ret) {
1667 printf("%s failed to get gpll rate\n", __func__);
1668 return ret;
1669 }
1670 }
1671
1672 return 0;
1673 }
1674
px30_clk_ofdata_to_platdata(struct udevice * dev)1675 static int px30_clk_ofdata_to_platdata(struct udevice *dev)
1676 {
1677 struct px30_clk_priv *priv = dev_get_priv(dev);
1678
1679 priv->cru = dev_read_addr_ptr(dev);
1680
1681 return 0;
1682 }
1683
px30_clk_bind(struct udevice * dev)1684 static int px30_clk_bind(struct udevice *dev)
1685 {
1686 int ret;
1687 struct udevice *sys_child, *sf_child;
1688 struct sysreset_reg *priv;
1689 struct softreset_reg *sf_priv;
1690
1691 /* The reset driver does not have a device node, so bind it here */
1692 ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
1693 &sys_child);
1694 if (ret) {
1695 debug("Warning: No sysreset driver: ret=%d\n", ret);
1696 } else {
1697 priv = malloc(sizeof(struct sysreset_reg));
1698 priv->glb_srst_fst_value = offsetof(struct px30_cru,
1699 glb_srst_fst);
1700 priv->glb_srst_snd_value = offsetof(struct px30_cru,
1701 glb_srst_snd);
1702 sys_child->priv = priv;
1703 }
1704
1705 ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset",
1706 dev_ofnode(dev), &sf_child);
1707 if (ret) {
1708 debug("Warning: No rockchip reset driver: ret=%d\n", ret);
1709 } else {
1710 sf_priv = malloc(sizeof(struct softreset_reg));
1711 sf_priv->sf_reset_offset = offsetof(struct px30_cru,
1712 softrst_con[0]);
1713 sf_priv->sf_reset_num = 12;
1714 sf_child->priv = sf_priv;
1715 }
1716
1717 return 0;
1718 }
1719
1720 static const struct udevice_id px30_clk_ids[] = {
1721 { .compatible = "rockchip,px30-cru" },
1722 { }
1723 };
1724
1725 U_BOOT_DRIVER(rockchip_px30_cru) = {
1726 .name = "rockchip_px30_cru",
1727 .id = UCLASS_CLK,
1728 .of_match = px30_clk_ids,
1729 .priv_auto_alloc_size = sizeof(struct px30_clk_priv),
1730 .ofdata_to_platdata = px30_clk_ofdata_to_platdata,
1731 .ops = &px30_clk_ops,
1732 .bind = px30_clk_bind,
1733 .probe = px30_clk_probe,
1734 };
1735
px30_pclk_pmu_get_pmuclk(struct px30_pmuclk_priv * priv)1736 static ulong px30_pclk_pmu_get_pmuclk(struct px30_pmuclk_priv *priv)
1737 {
1738 struct px30_pmucru *pmucru = priv->pmucru;
1739 u32 div, con;
1740
1741 con = readl(&pmucru->pmu_clksel_con[0]);
1742 div = (con & CLK_PMU_PCLK_DIV_MASK) >> CLK_PMU_PCLK_DIV_SHIFT;
1743
1744 return DIV_TO_RATE(priv->gpll_hz, div);
1745 }
1746
px30_pclk_pmu_set_pmuclk(struct px30_pmuclk_priv * priv,ulong hz)1747 static ulong px30_pclk_pmu_set_pmuclk(struct px30_pmuclk_priv *priv, ulong hz)
1748 {
1749 struct px30_pmucru *pmucru = priv->pmucru;
1750 int src_clk_div;
1751
1752 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
1753 assert(src_clk_div - 1 <= 31);
1754
1755 rk_clrsetreg(&pmucru->pmu_clksel_con[0],
1756 CLK_PMU_PCLK_DIV_MASK,
1757 (src_clk_div - 1) << CLK_PMU_PCLK_DIV_SHIFT);
1758
1759 return px30_pclk_pmu_get_pmuclk(priv);
1760 }
1761
px30_gpll_get_pmuclk(struct px30_pmuclk_priv * priv)1762 static ulong px30_gpll_get_pmuclk(struct px30_pmuclk_priv *priv)
1763 {
1764 struct px30_pmucru *pmucru = priv->pmucru;
1765
1766 return rkclk_pll_get_rate(&pmucru->pll, &pmucru->pmu_mode, GPLL);
1767 }
1768
px30_gpll_set_pmuclk(struct px30_pmuclk_priv * priv,ulong hz)1769 static ulong px30_gpll_set_pmuclk(struct px30_pmuclk_priv *priv, ulong hz)
1770 {
1771 struct udevice *cru_dev;
1772 struct px30_clk_priv *cru_priv;
1773 struct px30_pmucru *pmucru = priv->pmucru;
1774 u32 div;
1775 ulong emmc_rate, sdmmc_rate, nandc_rate, sfc_rate;
1776 ulong aclk_bus_rate, hclk_bus_rate, pclk_bus_rate;
1777 ulong aclk_peri_rate, hclk_peri_rate, pclk_pmu_rate;
1778 int ret;
1779
1780 ret = uclass_get_device_by_name(UCLASS_CLK,
1781 "clock-controller@ff2b0000",
1782 &cru_dev);
1783 if (ret) {
1784 printf("%s failed to get cru device\n", __func__);
1785 return ret;
1786 }
1787 cru_priv = dev_get_priv(cru_dev);
1788
1789 if (priv->gpll_hz == hz)
1790 return priv->gpll_hz;
1791
1792 cru_priv->gpll_hz = priv->gpll_hz;
1793 div = DIV_ROUND_UP(hz, priv->gpll_hz);
1794
1795 /* save clock rate */
1796 aclk_bus_rate = px30_bus_get_clk(cru_priv, ACLK_BUS_PRE);
1797 hclk_bus_rate = px30_bus_get_clk(cru_priv, HCLK_BUS_PRE);
1798 pclk_bus_rate = px30_bus_get_clk(cru_priv, PCLK_BUS_PRE);
1799 aclk_peri_rate = px30_peri_get_clk(cru_priv, ACLK_PERI_PRE);
1800 hclk_peri_rate = px30_peri_get_clk(cru_priv, HCLK_PERI_PRE);
1801 pclk_pmu_rate = px30_pclk_pmu_get_pmuclk(priv);
1802 debug("%s aclk_bus=%lu, hclk_bus=%lu, pclk_bus=%lu\n", __func__,
1803 aclk_bus_rate, hclk_bus_rate, pclk_bus_rate);
1804 debug("%s aclk_peri=%lu, hclk_peri=%lu, pclk_pmu=%lu\n", __func__,
1805 aclk_peri_rate, hclk_peri_rate, pclk_pmu_rate);
1806 emmc_rate = px30_mmc_get_clk(cru_priv, SCLK_EMMC);
1807 sdmmc_rate = px30_mmc_get_clk(cru_priv, SCLK_SDMMC);
1808 nandc_rate = px30_nandc_get_clk(cru_priv);
1809 sfc_rate = px30_sfc_get_clk(cru_priv, SCLK_SFC);
1810 debug("%s emmc=%lu, sdmmc=%lu, nandc=%lu sfc=%lu\n", __func__,
1811 emmc_rate, sdmmc_rate, nandc_rate, sfc_rate);
1812
1813 /* avoid rate too large, reduce rate first */
1814 px30_bus_set_clk(cru_priv, ACLK_BUS_PRE, aclk_bus_rate / div);
1815 px30_bus_set_clk(cru_priv, HCLK_BUS_PRE, hclk_bus_rate / div);
1816 px30_bus_set_clk(cru_priv, PCLK_BUS_PRE, pclk_bus_rate / div);
1817 px30_peri_set_clk(cru_priv, ACLK_PERI_PRE, aclk_peri_rate / div);
1818 px30_peri_set_clk(cru_priv, HCLK_PERI_PRE, hclk_peri_rate / div);
1819 px30_pclk_pmu_set_pmuclk(priv, pclk_pmu_rate / div);
1820
1821 px30_mmc_set_clk(cru_priv, SCLK_EMMC, emmc_rate / div);
1822 px30_mmc_set_clk(cru_priv, SCLK_SDMMC, sdmmc_rate / div);
1823 px30_nandc_set_clk(cru_priv, nandc_rate / div);
1824 px30_sfc_set_clk(cru_priv, SCLK_SFC, sfc_rate / div);
1825
1826 /* change gpll rate */
1827 rkclk_set_pll(&pmucru->pll, &pmucru->pmu_mode, GPLL, hz);
1828 priv->gpll_hz = px30_gpll_get_pmuclk(priv);
1829 cru_priv->gpll_hz = priv->gpll_hz;
1830
1831 /* restore clock rate */
1832 px30_bus_set_clk(cru_priv, ACLK_BUS_PRE, aclk_bus_rate);
1833 px30_bus_set_clk(cru_priv, HCLK_BUS_PRE, hclk_bus_rate);
1834 px30_bus_set_clk(cru_priv, PCLK_BUS_PRE, pclk_bus_rate);
1835 px30_peri_set_clk(cru_priv, ACLK_PERI_PRE, aclk_peri_rate);
1836 px30_peri_set_clk(cru_priv, HCLK_PERI_PRE, hclk_peri_rate);
1837 px30_pclk_pmu_set_pmuclk(priv, pclk_pmu_rate);
1838
1839 px30_mmc_set_clk(cru_priv, SCLK_EMMC, emmc_rate);
1840 px30_mmc_set_clk(cru_priv, SCLK_SDMMC, sdmmc_rate);
1841 px30_nandc_set_clk(cru_priv, nandc_rate);
1842 px30_sfc_set_clk(cru_priv, SCLK_SFC, sfc_rate);
1843
1844 return priv->gpll_hz;
1845 }
1846
px30_pmuclk_get_rate(struct clk * clk)1847 static ulong px30_pmuclk_get_rate(struct clk *clk)
1848 {
1849 struct px30_pmuclk_priv *priv = dev_get_priv(clk->dev);
1850 ulong rate = 0;
1851
1852 debug("%s %ld\n", __func__, clk->id);
1853 switch (clk->id) {
1854 case PLL_GPLL:
1855 rate = px30_gpll_get_pmuclk(priv);
1856 break;
1857 case PCLK_PMU_PRE:
1858 rate = px30_pclk_pmu_get_pmuclk(priv);
1859 break;
1860 default:
1861 return -ENOENT;
1862 }
1863
1864 return rate;
1865 }
1866
px30_pmuclk_set_rate(struct clk * clk,ulong rate)1867 static ulong px30_pmuclk_set_rate(struct clk *clk, ulong rate)
1868 {
1869 struct px30_pmuclk_priv *priv = dev_get_priv(clk->dev);
1870 ulong ret = 0;
1871
1872 debug("%s %ld %ld\n", __func__, clk->id, rate);
1873 switch (clk->id) {
1874 case PLL_GPLL:
1875 ret = px30_gpll_set_pmuclk(priv, rate);
1876 break;
1877 case PCLK_PMU_PRE:
1878 ret = px30_pclk_pmu_set_pmuclk(priv, rate);
1879 break;
1880 default:
1881 return -ENOENT;
1882 }
1883
1884 return ret;
1885 }
1886
1887 static struct clk_ops px30_pmuclk_ops = {
1888 .get_rate = px30_pmuclk_get_rate,
1889 .set_rate = px30_pmuclk_set_rate,
1890 };
1891
px30_clk_init(struct px30_pmuclk_priv * priv)1892 static void px30_clk_init(struct px30_pmuclk_priv *priv)
1893 {
1894 struct udevice *cru_dev;
1895 struct px30_clk_priv *cru_priv;
1896 ulong npll_hz;
1897 int ret;
1898
1899 ret = uclass_get_device_by_name(UCLASS_CLK,
1900 "clock-controller@ff2b0000", &cru_dev);
1901 if (ret) {
1902 printf("%s failed to get cru device\n", __func__);
1903 return;
1904 }
1905
1906 cru_priv = dev_get_priv(cru_dev);
1907
1908 /* Source from xin_osc0_half before gpll rate. */
1909 px30_i2s1_mclk_set_clk(cru_priv, SCLK_I2S1_OUT, 12000000);
1910
1911 priv->gpll_hz = px30_gpll_get_pmuclk(priv);
1912 if (priv->gpll_hz != GPLL_HZ) {
1913 ret = px30_gpll_set_pmuclk(priv, GPLL_HZ);
1914 if (ret < 0)
1915 printf("%s failed to set gpll rate\n", __func__);
1916 }
1917
1918 cru_priv->gpll_hz = priv->gpll_hz;
1919
1920 npll_hz = px30_clk_get_pll_rate(cru_priv, NPLL);
1921 if (npll_hz != NPLL_HZ) {
1922 ret = px30_clk_set_pll_rate(cru_priv, NPLL, NPLL_HZ);
1923 if (ret < 0)
1924 printf("%s failed to set npll rate\n", __func__);
1925 }
1926
1927 px30_bus_set_clk(cru_priv, ACLK_BUS_PRE, ACLK_BUS_HZ);
1928 px30_bus_set_clk(cru_priv, HCLK_BUS_PRE, HCLK_BUS_HZ);
1929 px30_bus_set_clk(cru_priv, PCLK_BUS_PRE, PCLK_BUS_HZ);
1930 px30_peri_set_clk(cru_priv, ACLK_PERI_PRE, ACLK_PERI_HZ);
1931 px30_peri_set_clk(cru_priv, HCLK_PERI_PRE, HCLK_PERI_HZ);
1932 px30_pclk_pmu_set_pmuclk(priv, PCLK_PMU_HZ);
1933
1934 /* Source from gpll as default set. */
1935 px30_i2s1_mclk_set_clk(cru_priv, SCLK_I2S1_OUT, 11289600);
1936 }
1937
px30_pmuclk_probe(struct udevice * dev)1938 static int px30_pmuclk_probe(struct udevice *dev)
1939 {
1940 struct px30_pmuclk_priv *priv = dev_get_priv(dev);
1941 int ret;
1942
1943 px30_clk_init(priv);
1944
1945 /* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
1946 ret = clk_set_defaults(dev);
1947 if (ret)
1948 debug("%s clk_set_defaults failed %d\n", __func__, ret);
1949
1950 return 0;
1951 }
1952
px30_pmuclk_ofdata_to_platdata(struct udevice * dev)1953 static int px30_pmuclk_ofdata_to_platdata(struct udevice *dev)
1954 {
1955 struct px30_pmuclk_priv *priv = dev_get_priv(dev);
1956
1957 priv->pmucru = dev_read_addr_ptr(dev);
1958
1959 return 0;
1960 }
1961
1962 static const struct udevice_id px30_pmuclk_ids[] = {
1963 { .compatible = "rockchip,px30-pmucru" },
1964 { }
1965 };
1966
1967 U_BOOT_DRIVER(rockchip_px30_pmucru) = {
1968 .name = "rockchip_px30_pmucru",
1969 .id = UCLASS_CLK,
1970 .of_match = px30_pmuclk_ids,
1971 .priv_auto_alloc_size = sizeof(struct px30_pmuclk_priv),
1972 .ofdata_to_platdata = px30_pmuclk_ofdata_to_platdata,
1973 .ops = &px30_pmuclk_ops,
1974 .probe = px30_pmuclk_probe,
1975 };
1976
1977 /**
1978 * soc_clk_dump() - Print clock frequencies
1979 * Returns zero on success
1980 *
1981 * Implementation for the clk dump command.
1982 */
soc_clk_dump(void)1983 int soc_clk_dump(void)
1984 {
1985 struct udevice *cru_dev, *pmucru_dev;
1986 struct px30_clk_priv *priv;
1987 const struct px30_clk_info *clk_dump;
1988 struct clk clk;
1989 unsigned long clk_count = ARRAY_SIZE(clks_dump);
1990 unsigned long rate;
1991 int i, ret;
1992
1993 ret = uclass_get_device_by_driver(UCLASS_CLK,
1994 DM_GET_DRIVER(rockchip_px30_cru),
1995 &cru_dev);
1996 if (ret) {
1997 printf("%s failed to get cru device\n", __func__);
1998 return ret;
1999 }
2000
2001 ret = uclass_get_device_by_driver(UCLASS_CLK,
2002 DM_GET_DRIVER(rockchip_px30_pmucru),
2003 &pmucru_dev);
2004 if (ret) {
2005 printf("%s failed to get pmucru device\n", __func__);
2006 return ret;
2007 }
2008
2009 priv = dev_get_priv(cru_dev);
2010 printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n",
2011 priv->sync_kernel ? "sync kernel" : "uboot",
2012 priv->armclk_enter_hz / 1000,
2013 priv->armclk_init_hz / 1000,
2014 priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0,
2015 priv->set_armclk_rate ? " KHz" : "N/A");
2016 for (i = 0; i < clk_count; i++) {
2017 clk_dump = &clks_dump[i];
2018 if (clk_dump->name) {
2019 clk.id = clk_dump->id;
2020 if (clk_dump->is_cru)
2021 ret = clk_request(cru_dev, &clk);
2022 else
2023 ret = clk_request(pmucru_dev, &clk);
2024 if (ret < 0)
2025 return ret;
2026
2027 rate = clk_get_rate(&clk);
2028 clk_free(&clk);
2029 if (i == 0) {
2030 if (rate < 0)
2031 printf(" %s %s\n", clk_dump->name,
2032 "unknown");
2033 else
2034 printf(" %s %lu KHz\n", clk_dump->name,
2035 rate / 1000);
2036 } else {
2037 if (rate < 0)
2038 printf(" %s %s\n", clk_dump->name,
2039 "unknown");
2040 else
2041 printf(" %s %lu KHz\n", clk_dump->name,
2042 rate / 1000);
2043 }
2044 }
2045 }
2046
2047 return 0;
2048 }
2049