common: Drop linux/delay.h from common header
[oweals/u-boot.git] / drivers / clk / rockchip / clk_px30.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * (C) Copyright 2017 Rockchip Electronics Co., Ltd
4  */
5
6 #include <common.h>
7 #include <bitfield.h>
8 #include <clk-uclass.h>
9 #include <dm.h>
10 #include <errno.h>
11 #include <log.h>
12 #include <malloc.h>
13 #include <syscon.h>
14 #include <asm/arch-rockchip/clock.h>
15 #include <asm/arch-rockchip/cru_px30.h>
16 #include <asm/arch-rockchip/hardware.h>
17 #include <asm/io.h>
18 #include <dm/lists.h>
19 #include <dt-bindings/clock/px30-cru.h>
20 #include <linux/delay.h>
21
22 DECLARE_GLOBAL_DATA_PTR;
23
24 enum {
25         VCO_MAX_HZ      = 3200U * 1000000,
26         VCO_MIN_HZ      = 800 * 1000000,
27         OUTPUT_MAX_HZ   = 3200U * 1000000,
28         OUTPUT_MIN_HZ   = 24 * 1000000,
29 };
30
31 #define PX30_VOP_PLL_LIMIT                      600000000
32
33 #define PX30_PLL_RATE(_rate, _refdiv, _fbdiv, _postdiv1,        \
34                         _postdiv2, _dsmpd, _frac)               \
35 {                                                               \
36         .rate   = _rate##U,                                     \
37         .fbdiv = _fbdiv,                                        \
38         .postdiv1 = _postdiv1,                                  \
39         .refdiv = _refdiv,                                      \
40         .postdiv2 = _postdiv2,                                  \
41         .dsmpd = _dsmpd,                                        \
42         .frac = _frac,                                          \
43 }
44
45 #define PX30_CPUCLK_RATE(_rate, _aclk_div, _pclk_div)           \
46 {                                                               \
47         .rate   = _rate##U,                                     \
48         .aclk_div = _aclk_div,                                  \
49         .pclk_div = _pclk_div,                                  \
50 }
51
52 #define DIV_TO_RATE(input_rate, div)    ((input_rate) / ((div) + 1))
53
54 #define PX30_CLK_DUMP(_id, _name, _iscru)       \
55 {                                               \
56         .id = _id,                              \
57         .name = _name,                          \
58         .is_cru = _iscru,                       \
59 }
60
61 static struct pll_rate_table px30_pll_rates[] = {
62         /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
63         PX30_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0),
64         PX30_PLL_RATE(1188000000, 2, 99, 1, 1, 1, 0),
65         PX30_PLL_RATE(1100000000, 12, 550, 1, 1, 1, 0),
66         PX30_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0),
67         PX30_PLL_RATE(1000000000, 6, 500, 2, 1, 1, 0),
68         PX30_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0),
69         PX30_PLL_RATE(600000000, 1, 75, 3, 1, 1, 0),
70 };
71
72 static struct cpu_rate_table px30_cpu_rates[] = {
73         PX30_CPUCLK_RATE(1200000000, 1, 5),
74         PX30_CPUCLK_RATE(1008000000, 1, 5),
75         PX30_CPUCLK_RATE(816000000, 1, 3),
76         PX30_CPUCLK_RATE(600000000, 1, 3),
77         PX30_CPUCLK_RATE(408000000, 1, 1),
78 };
79
80 static u8 pll_mode_shift[PLL_COUNT] = {
81         APLL_MODE_SHIFT, DPLL_MODE_SHIFT, CPLL_MODE_SHIFT,
82         NPLL_MODE_SHIFT, GPLL_MODE_SHIFT
83 };
84
85 static u32 pll_mode_mask[PLL_COUNT] = {
86         APLL_MODE_MASK, DPLL_MODE_MASK, CPLL_MODE_MASK,
87         NPLL_MODE_MASK, GPLL_MODE_MASK
88 };
89
90 static struct pll_rate_table auto_table;
91
92 static ulong px30_clk_get_pll_rate(struct px30_clk_priv *priv,
93                                    enum px30_pll_id pll_id);
94
95 static struct pll_rate_table *pll_clk_set_by_auto(u32 drate)
96 {
97         struct pll_rate_table *rate = &auto_table;
98         u32 ref_khz = OSC_HZ / KHz, refdiv, fbdiv = 0;
99         u32 postdiv1, postdiv2 = 1;
100         u32 fref_khz;
101         u32 diff_khz, best_diff_khz;
102         const u32 max_refdiv = 63, max_fbdiv = 3200, min_fbdiv = 16;
103         const u32 max_postdiv1 = 7, max_postdiv2 = 7;
104         u32 vco_khz;
105         u32 rate_khz = drate / KHz;
106
107         if (!drate) {
108                 printf("%s: the frequency can't be 0 Hz\n", __func__);
109                 return NULL;
110         }
111
112         postdiv1 = DIV_ROUND_UP(VCO_MIN_HZ / 1000, rate_khz);
113         if (postdiv1 > max_postdiv1) {
114                 postdiv2 = DIV_ROUND_UP(postdiv1, max_postdiv1);
115                 postdiv1 = DIV_ROUND_UP(postdiv1, postdiv2);
116         }
117
118         vco_khz = rate_khz * postdiv1 * postdiv2;
119
120         if (vco_khz < (VCO_MIN_HZ / KHz) || vco_khz > (VCO_MAX_HZ / KHz) ||
121             postdiv2 > max_postdiv2) {
122                 printf("%s: Cannot find out a supported VCO for Freq (%uHz)\n",
123                        __func__, rate_khz);
124                 return NULL;
125         }
126
127         rate->postdiv1 = postdiv1;
128         rate->postdiv2 = postdiv2;
129
130         best_diff_khz = vco_khz;
131         for (refdiv = 1; refdiv < max_refdiv && best_diff_khz; refdiv++) {
132                 fref_khz = ref_khz / refdiv;
133
134                 fbdiv = vco_khz / fref_khz;
135                 if (fbdiv >= max_fbdiv || fbdiv <= min_fbdiv)
136                         continue;
137
138                 diff_khz = vco_khz - fbdiv * fref_khz;
139                 if (fbdiv + 1 < max_fbdiv && diff_khz > fref_khz / 2) {
140                         fbdiv++;
141                         diff_khz = fref_khz - diff_khz;
142                 }
143
144                 if (diff_khz >= best_diff_khz)
145                         continue;
146
147                 best_diff_khz = diff_khz;
148                 rate->refdiv = refdiv;
149                 rate->fbdiv = fbdiv;
150         }
151
152         if (best_diff_khz > 4 * (MHz / KHz)) {
153                 printf("%s: Failed to match output frequency %u bestis %u Hz\n",
154                        __func__, rate_khz,
155                        best_diff_khz * KHz);
156                 return NULL;
157         }
158
159         return rate;
160 }
161
162 static const struct pll_rate_table *get_pll_settings(unsigned long rate)
163 {
164         unsigned int rate_count = ARRAY_SIZE(px30_pll_rates);
165         int i;
166
167         for (i = 0; i < rate_count; i++) {
168                 if (rate == px30_pll_rates[i].rate)
169                         return &px30_pll_rates[i];
170         }
171
172         return pll_clk_set_by_auto(rate);
173 }
174
175 static const struct cpu_rate_table *get_cpu_settings(unsigned long rate)
176 {
177         unsigned int rate_count = ARRAY_SIZE(px30_cpu_rates);
178         int i;
179
180         for (i = 0; i < rate_count; i++) {
181                 if (rate == px30_cpu_rates[i].rate)
182                         return &px30_cpu_rates[i];
183         }
184
185         return NULL;
186 }
187
188 /*
189  * How to calculate the PLL(from TRM V0.3 Part 1 Page 63):
190  * Formulas also embedded within the Fractional PLL Verilog model:
191  * If DSMPD = 1 (DSM is disabled, "integer mode")
192  * FOUTVCO = FREF / REFDIV * FBDIV
193  * FOUTPOSTDIV = FOUTVCO / POSTDIV1 / POSTDIV2
194  * Where:
195  * FOUTVCO = Fractional PLL non-divided output frequency
196  * FOUTPOSTDIV = Fractional PLL divided output frequency
197  *               (output of second post divider)
198  * FREF = Fractional PLL input reference frequency, (the OSC_HZ 24MHz input)
199  * REFDIV = Fractional PLL input reference clock divider
200  * FBDIV = Integer value programmed into feedback divide
201  *
202  */
203 static int rkclk_set_pll(struct px30_pll *pll, unsigned int *mode,
204                          enum px30_pll_id pll_id,
205                          unsigned long drate)
206 {
207         const struct pll_rate_table *rate;
208         uint vco_hz, output_hz;
209
210         rate = get_pll_settings(drate);
211         if (!rate) {
212                 printf("%s unsupport rate\n", __func__);
213                 return -EINVAL;
214         }
215
216         /* All PLLs have same VCO and output frequency range restrictions. */
217         vco_hz = OSC_HZ / 1000 * rate->fbdiv / rate->refdiv * 1000;
218         output_hz = vco_hz / rate->postdiv1 / rate->postdiv2;
219
220         debug("PLL at %p: fb=%d, ref=%d, pst1=%d, pst2=%d, vco=%u Hz, output=%u Hz\n",
221               pll, rate->fbdiv, rate->refdiv, rate->postdiv1,
222               rate->postdiv2, vco_hz, output_hz);
223         assert(vco_hz >= VCO_MIN_HZ && vco_hz <= VCO_MAX_HZ &&
224                output_hz >= OUTPUT_MIN_HZ && output_hz <= OUTPUT_MAX_HZ);
225
226         /*
227          * When power on or changing PLL setting,
228          * we must force PLL into slow mode to ensure output stable clock.
229          */
230         rk_clrsetreg(mode, pll_mode_mask[pll_id],
231                      PLLMUX_FROM_XIN24M << pll_mode_shift[pll_id]);
232
233         /* use integer mode */
234         rk_setreg(&pll->con1, 1 << PLL_DSMPD_SHIFT);
235         /* Power down */
236         rk_setreg(&pll->con1, 1 << PLL_PD_SHIFT);
237
238         rk_clrsetreg(&pll->con0,
239                      PLL_POSTDIV1_MASK | PLL_FBDIV_MASK,
240                      (rate->postdiv1 << PLL_POSTDIV1_SHIFT) | rate->fbdiv);
241         rk_clrsetreg(&pll->con1, PLL_POSTDIV2_MASK | PLL_REFDIV_MASK,
242                      (rate->postdiv2 << PLL_POSTDIV2_SHIFT |
243                      rate->refdiv << PLL_REFDIV_SHIFT));
244
245         /* Power Up */
246         rk_clrreg(&pll->con1, 1 << PLL_PD_SHIFT);
247
248         /* waiting for pll lock */
249         while (!(readl(&pll->con1) & (1 << PLL_LOCK_STATUS_SHIFT)))
250                 udelay(1);
251
252         rk_clrsetreg(mode, pll_mode_mask[pll_id],
253                      PLLMUX_FROM_PLL << pll_mode_shift[pll_id]);
254
255         return 0;
256 }
257
258 static uint32_t rkclk_pll_get_rate(struct px30_pll *pll, unsigned int *mode,
259                                    enum px30_pll_id pll_id)
260 {
261         u32 refdiv, fbdiv, postdiv1, postdiv2;
262         u32 con, shift, mask;
263
264         con = readl(mode);
265         shift = pll_mode_shift[pll_id];
266         mask = pll_mode_mask[pll_id];
267
268         switch ((con & mask) >> shift) {
269         case PLLMUX_FROM_XIN24M:
270                 return OSC_HZ;
271         case PLLMUX_FROM_PLL:
272                 /* normal mode */
273                 con = readl(&pll->con0);
274                 postdiv1 = (con & PLL_POSTDIV1_MASK) >> PLL_POSTDIV1_SHIFT;
275                 fbdiv = (con & PLL_FBDIV_MASK) >> PLL_FBDIV_SHIFT;
276                 con = readl(&pll->con1);
277                 postdiv2 = (con & PLL_POSTDIV2_MASK) >> PLL_POSTDIV2_SHIFT;
278                 refdiv = (con & PLL_REFDIV_MASK) >> PLL_REFDIV_SHIFT;
279                 return (24 * fbdiv / (refdiv * postdiv1 * postdiv2)) * 1000000;
280         case PLLMUX_FROM_RTC32K:
281         default:
282                 return 32768;
283         }
284 }
285
286 static ulong px30_i2c_get_clk(struct px30_clk_priv *priv, ulong clk_id)
287 {
288         struct px30_cru *cru = priv->cru;
289         u32 div, con;
290
291         switch (clk_id) {
292         case SCLK_I2C0:
293                 con = readl(&cru->clksel_con[49]);
294                 div = con >> CLK_I2C0_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK;
295                 break;
296         case SCLK_I2C1:
297                 con = readl(&cru->clksel_con[49]);
298                 div = con >> CLK_I2C1_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK;
299                 break;
300         case SCLK_I2C2:
301                 con = readl(&cru->clksel_con[50]);
302                 div = con >> CLK_I2C2_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK;
303                 break;
304         case SCLK_I2C3:
305                 con = readl(&cru->clksel_con[50]);
306                 div = con >> CLK_I2C3_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK;
307                 break;
308         default:
309                 printf("do not support this i2c bus\n");
310                 return -EINVAL;
311         }
312
313         return DIV_TO_RATE(priv->gpll_hz, div);
314 }
315
316 static ulong px30_i2c_set_clk(struct px30_clk_priv *priv, ulong clk_id, uint hz)
317 {
318         struct px30_cru *cru = priv->cru;
319         int src_clk_div;
320
321         src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
322         assert(src_clk_div - 1 <= 127);
323
324         switch (clk_id) {
325         case SCLK_I2C0:
326                 rk_clrsetreg(&cru->clksel_con[49],
327                              CLK_I2C_DIV_CON_MASK << CLK_I2C0_DIV_CON_SHIFT |
328                              CLK_I2C_PLL_SEL_MASK << CLK_I2C0_PLL_SEL_SHIFT,
329                              (src_clk_div - 1) << CLK_I2C0_DIV_CON_SHIFT |
330                              CLK_I2C_PLL_SEL_GPLL << CLK_I2C0_PLL_SEL_SHIFT);
331                 break;
332         case SCLK_I2C1:
333                 rk_clrsetreg(&cru->clksel_con[49],
334                              CLK_I2C_DIV_CON_MASK << CLK_I2C1_DIV_CON_SHIFT |
335                              CLK_I2C_PLL_SEL_MASK << CLK_I2C1_PLL_SEL_SHIFT,
336                              (src_clk_div - 1) << CLK_I2C1_DIV_CON_SHIFT |
337                              CLK_I2C_PLL_SEL_GPLL << CLK_I2C1_PLL_SEL_SHIFT);
338                 break;
339         case SCLK_I2C2:
340                 rk_clrsetreg(&cru->clksel_con[50],
341                              CLK_I2C_DIV_CON_MASK << CLK_I2C2_DIV_CON_SHIFT |
342                              CLK_I2C_PLL_SEL_MASK << CLK_I2C2_PLL_SEL_SHIFT,
343                              (src_clk_div - 1) << CLK_I2C2_DIV_CON_SHIFT |
344                              CLK_I2C_PLL_SEL_GPLL << CLK_I2C2_PLL_SEL_SHIFT);
345                 break;
346         case SCLK_I2C3:
347                 rk_clrsetreg(&cru->clksel_con[50],
348                              CLK_I2C_DIV_CON_MASK << CLK_I2C3_DIV_CON_SHIFT |
349                              CLK_I2C_PLL_SEL_MASK << CLK_I2C3_PLL_SEL_SHIFT,
350                              (src_clk_div - 1) << CLK_I2C3_DIV_CON_SHIFT |
351                              CLK_I2C_PLL_SEL_GPLL << CLK_I2C3_PLL_SEL_SHIFT);
352                 break;
353         default:
354                 printf("do not support this i2c bus\n");
355                 return -EINVAL;
356         }
357
358         return px30_i2c_get_clk(priv, clk_id);
359 }
360
361 /*
362  * calculate best rational approximation for a given fraction
363  * taking into account restricted register size, e.g. to find
364  * appropriate values for a pll with 5 bit denominator and
365  * 8 bit numerator register fields, trying to set up with a
366  * frequency ratio of 3.1415, one would say:
367  *
368  * rational_best_approximation(31415, 10000,
369  *              (1 << 8) - 1, (1 << 5) - 1, &n, &d);
370  *
371  * you may look at given_numerator as a fixed point number,
372  * with the fractional part size described in given_denominator.
373  *
374  * for theoretical background, see:
375  * http://en.wikipedia.org/wiki/Continued_fraction
376  */
377 static void rational_best_approximation(unsigned long given_numerator,
378                                         unsigned long given_denominator,
379                                         unsigned long max_numerator,
380                                         unsigned long max_denominator,
381                                         unsigned long *best_numerator,
382                                         unsigned long *best_denominator)
383 {
384         unsigned long n, d, n0, d0, n1, d1;
385
386         n = given_numerator;
387         d = given_denominator;
388         n0 = 0;
389         d1 = 0;
390         n1 = 1;
391         d0 = 1;
392         for (;;) {
393                 unsigned long t, a;
394
395                 if (n1 > max_numerator || d1 > max_denominator) {
396                         n1 = n0;
397                         d1 = d0;
398                         break;
399                 }
400                 if (d == 0)
401                         break;
402                 t = d;
403                 a = n / d;
404                 d = n % d;
405                 n = t;
406                 t = n0 + a * n1;
407                 n0 = n1;
408                 n1 = t;
409                 t = d0 + a * d1;
410                 d0 = d1;
411                 d1 = t;
412         }
413         *best_numerator = n1;
414         *best_denominator = d1;
415 }
416
417 static ulong px30_i2s_get_clk(struct px30_clk_priv *priv, ulong clk_id)
418 {
419         u32 con, fracdiv, gate;
420         u32 clk_src = priv->gpll_hz / 2;
421         unsigned long m, n;
422         struct px30_cru *cru = priv->cru;
423
424         switch (clk_id) {
425         case SCLK_I2S1:
426                 con = readl(&cru->clksel_con[30]);
427                 fracdiv = readl(&cru->clksel_con[31]);
428                 gate = readl(&cru->clkgate_con[10]);
429                 m = fracdiv & CLK_I2S1_FRAC_NUMERATOR_MASK;
430                 m >>= CLK_I2S1_FRAC_NUMERATOR_SHIFT;
431                 n = fracdiv & CLK_I2S1_FRAC_DENOMINATOR_MASK;
432                 n >>= CLK_I2S1_FRAC_DENOMINATOR_SHIFT;
433                 debug("con30: 0x%x, gate: 0x%x, frac: 0x%x\n",
434                       con, gate, fracdiv);
435                 break;
436         default:
437                 printf("do not support this i2s bus\n");
438                 return -EINVAL;
439         }
440
441         return clk_src * n / m;
442 }
443
444 static ulong px30_i2s_set_clk(struct px30_clk_priv *priv, ulong clk_id, uint hz)
445 {
446         u32 clk_src;
447         unsigned long m, n, val;
448         struct px30_cru *cru = priv->cru;
449
450         clk_src = priv->gpll_hz / 2;
451         rational_best_approximation(hz, clk_src,
452                                     GENMASK(16 - 1, 0),
453                                     GENMASK(16 - 1, 0),
454                                     &m, &n);
455         switch (clk_id) {
456         case SCLK_I2S1:
457                 rk_clrsetreg(&cru->clksel_con[30],
458                              CLK_I2S1_PLL_SEL_MASK, CLK_I2S1_PLL_SEL_GPLL);
459                 rk_clrsetreg(&cru->clksel_con[30],
460                              CLK_I2S1_DIV_CON_MASK, 0x1);
461                 rk_clrsetreg(&cru->clksel_con[30],
462                              CLK_I2S1_SEL_MASK, CLK_I2S1_SEL_FRAC);
463                 val = m << CLK_I2S1_FRAC_NUMERATOR_SHIFT | n;
464                 writel(val, &cru->clksel_con[31]);
465                 rk_clrsetreg(&cru->clkgate_con[10],
466                              CLK_I2S1_OUT_MCLK_PAD_MASK,
467                              CLK_I2S1_OUT_MCLK_PAD_ENABLE);
468                 break;
469         default:
470                 printf("do not support this i2s bus\n");
471                 return -EINVAL;
472         }
473
474         return px30_i2s_get_clk(priv, clk_id);
475 }
476
477 static ulong px30_nandc_get_clk(struct px30_clk_priv *priv)
478 {
479         struct px30_cru *cru = priv->cru;
480         u32 div, con;
481
482         con = readl(&cru->clksel_con[15]);
483         div = (con & NANDC_DIV_MASK) >> NANDC_DIV_SHIFT;
484
485         return DIV_TO_RATE(priv->gpll_hz, div);
486 }
487
488 static ulong px30_nandc_set_clk(struct px30_clk_priv *priv,
489                                 ulong set_rate)
490 {
491         struct px30_cru *cru = priv->cru;
492         int src_clk_div;
493
494         /* Select nandc source from GPLL by default */
495         /* nandc clock defaulg div 2 internal, need provide double in cru */
496         src_clk_div = DIV_ROUND_UP(priv->gpll_hz, set_rate);
497         assert(src_clk_div - 1 <= 31);
498
499         rk_clrsetreg(&cru->clksel_con[15],
500                      NANDC_CLK_SEL_MASK | NANDC_PLL_MASK |
501                      NANDC_DIV_MASK,
502                      NANDC_CLK_SEL_NANDC << NANDC_CLK_SEL_SHIFT |
503                      NANDC_SEL_GPLL << NANDC_PLL_SHIFT |
504                      (src_clk_div - 1) << NANDC_DIV_SHIFT);
505
506         return px30_nandc_get_clk(priv);
507 }
508
509 static ulong px30_mmc_get_clk(struct px30_clk_priv *priv, uint clk_id)
510 {
511         struct px30_cru *cru = priv->cru;
512         u32 div, con, con_id;
513
514         switch (clk_id) {
515         case HCLK_SDMMC:
516         case SCLK_SDMMC:
517                 con_id = 16;
518                 break;
519         case HCLK_EMMC:
520         case SCLK_EMMC:
521         case SCLK_EMMC_SAMPLE:
522                 con_id = 20;
523                 break;
524         default:
525                 return -EINVAL;
526         }
527
528         con = readl(&cru->clksel_con[con_id]);
529         div = (con & EMMC_DIV_MASK) >> EMMC_DIV_SHIFT;
530
531         if ((con & EMMC_PLL_MASK) >> EMMC_PLL_SHIFT
532             == EMMC_SEL_24M)
533                 return DIV_TO_RATE(OSC_HZ, div) / 2;
534         else
535                 return DIV_TO_RATE(priv->gpll_hz, div) / 2;
536 }
537
538 static ulong px30_mmc_set_clk(struct px30_clk_priv *priv,
539                               ulong clk_id, ulong set_rate)
540 {
541         struct px30_cru *cru = priv->cru;
542         int src_clk_div;
543         u32 con_id;
544
545         switch (clk_id) {
546         case HCLK_SDMMC:
547         case SCLK_SDMMC:
548                 con_id = 16;
549                 break;
550         case HCLK_EMMC:
551         case SCLK_EMMC:
552                 con_id = 20;
553                 break;
554         default:
555                 return -EINVAL;
556         }
557
558         /* Select clk_sdmmc/emmc source from GPLL by default */
559         /* mmc clock defaulg div 2 internal, need provide double in cru */
560         src_clk_div = DIV_ROUND_UP(priv->gpll_hz / 2, set_rate);
561
562         if (src_clk_div > 127) {
563                 /* use 24MHz source for 400KHz clock */
564                 src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, set_rate);
565                 rk_clrsetreg(&cru->clksel_con[con_id],
566                              EMMC_PLL_MASK | EMMC_DIV_MASK,
567                              EMMC_SEL_24M << EMMC_PLL_SHIFT |
568                              (src_clk_div - 1) << EMMC_DIV_SHIFT);
569         } else {
570                 rk_clrsetreg(&cru->clksel_con[con_id],
571                              EMMC_PLL_MASK | EMMC_DIV_MASK,
572                              EMMC_SEL_GPLL << EMMC_PLL_SHIFT |
573                              (src_clk_div - 1) << EMMC_DIV_SHIFT);
574         }
575         rk_clrsetreg(&cru->clksel_con[con_id + 1], EMMC_CLK_SEL_MASK,
576                      EMMC_CLK_SEL_EMMC);
577
578         return px30_mmc_get_clk(priv, clk_id);
579 }
580
581 static ulong px30_pwm_get_clk(struct px30_clk_priv *priv, ulong clk_id)
582 {
583         struct px30_cru *cru = priv->cru;
584         u32 div, con;
585
586         switch (clk_id) {
587         case SCLK_PWM0:
588                 con = readl(&cru->clksel_con[52]);
589                 div = con >> CLK_PWM0_DIV_CON_SHIFT & CLK_PWM_DIV_CON_MASK;
590                 break;
591         case SCLK_PWM1:
592                 con = readl(&cru->clksel_con[52]);
593                 div = con >> CLK_PWM1_DIV_CON_SHIFT & CLK_PWM_DIV_CON_MASK;
594                 break;
595         default:
596                 printf("do not support this pwm bus\n");
597                 return -EINVAL;
598         }
599
600         return DIV_TO_RATE(priv->gpll_hz, div);
601 }
602
603 static ulong px30_pwm_set_clk(struct px30_clk_priv *priv, ulong clk_id, uint hz)
604 {
605         struct px30_cru *cru = priv->cru;
606         int src_clk_div;
607
608         src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
609         assert(src_clk_div - 1 <= 127);
610
611         switch (clk_id) {
612         case SCLK_PWM0:
613                 rk_clrsetreg(&cru->clksel_con[52],
614                              CLK_PWM_DIV_CON_MASK << CLK_PWM0_DIV_CON_SHIFT |
615                              CLK_PWM_PLL_SEL_MASK << CLK_PWM0_PLL_SEL_SHIFT,
616                              (src_clk_div - 1) << CLK_PWM0_DIV_CON_SHIFT |
617                              CLK_PWM_PLL_SEL_GPLL << CLK_PWM0_PLL_SEL_SHIFT);
618                 break;
619         case SCLK_PWM1:
620                 rk_clrsetreg(&cru->clksel_con[52],
621                              CLK_PWM_DIV_CON_MASK << CLK_PWM1_DIV_CON_SHIFT |
622                              CLK_PWM_PLL_SEL_MASK << CLK_PWM1_PLL_SEL_SHIFT,
623                              (src_clk_div - 1) << CLK_PWM1_DIV_CON_SHIFT |
624                              CLK_PWM_PLL_SEL_GPLL << CLK_PWM1_PLL_SEL_SHIFT);
625                 break;
626         default:
627                 printf("do not support this pwm bus\n");
628                 return -EINVAL;
629         }
630
631         return px30_pwm_get_clk(priv, clk_id);
632 }
633
634 static ulong px30_saradc_get_clk(struct px30_clk_priv *priv)
635 {
636         struct px30_cru *cru = priv->cru;
637         u32 div, con;
638
639         con = readl(&cru->clksel_con[55]);
640         div = con >> CLK_SARADC_DIV_CON_SHIFT & CLK_SARADC_DIV_CON_MASK;
641
642         return DIV_TO_RATE(OSC_HZ, div);
643 }
644
645 static ulong px30_saradc_set_clk(struct px30_clk_priv *priv, uint hz)
646 {
647         struct px30_cru *cru = priv->cru;
648         int src_clk_div;
649
650         src_clk_div = DIV_ROUND_UP(OSC_HZ, hz);
651         assert(src_clk_div - 1 <= 2047);
652
653         rk_clrsetreg(&cru->clksel_con[55],
654                      CLK_SARADC_DIV_CON_MASK,
655                      (src_clk_div - 1) << CLK_SARADC_DIV_CON_SHIFT);
656
657         return px30_saradc_get_clk(priv);
658 }
659
660 static ulong px30_tsadc_get_clk(struct px30_clk_priv *priv)
661 {
662         struct px30_cru *cru = priv->cru;
663         u32 div, con;
664
665         con = readl(&cru->clksel_con[54]);
666         div = con >> CLK_SARADC_DIV_CON_SHIFT & CLK_SARADC_DIV_CON_MASK;
667
668         return DIV_TO_RATE(OSC_HZ, div);
669 }
670
671 static ulong px30_tsadc_set_clk(struct px30_clk_priv *priv, uint hz)
672 {
673         struct px30_cru *cru = priv->cru;
674         int src_clk_div;
675
676         src_clk_div = DIV_ROUND_UP(OSC_HZ, hz);
677         assert(src_clk_div - 1 <= 2047);
678
679         rk_clrsetreg(&cru->clksel_con[54],
680                      CLK_SARADC_DIV_CON_MASK,
681                      (src_clk_div - 1) << CLK_SARADC_DIV_CON_SHIFT);
682
683         return px30_tsadc_get_clk(priv);
684 }
685
686 static ulong px30_spi_get_clk(struct px30_clk_priv *priv, ulong clk_id)
687 {
688         struct px30_cru *cru = priv->cru;
689         u32 div, con;
690
691         switch (clk_id) {
692         case SCLK_SPI0:
693                 con = readl(&cru->clksel_con[53]);
694                 div = con >> CLK_SPI0_DIV_CON_SHIFT & CLK_SPI_DIV_CON_MASK;
695                 break;
696         case SCLK_SPI1:
697                 con = readl(&cru->clksel_con[53]);
698                 div = con >> CLK_SPI1_DIV_CON_SHIFT & CLK_SPI_DIV_CON_MASK;
699                 break;
700         default:
701                 printf("do not support this pwm bus\n");
702                 return -EINVAL;
703         }
704
705         return DIV_TO_RATE(priv->gpll_hz, div);
706 }
707
708 static ulong px30_spi_set_clk(struct px30_clk_priv *priv, ulong clk_id, uint hz)
709 {
710         struct px30_cru *cru = priv->cru;
711         int src_clk_div;
712
713         src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
714         assert(src_clk_div - 1 <= 127);
715
716         switch (clk_id) {
717         case SCLK_SPI0:
718                 rk_clrsetreg(&cru->clksel_con[53],
719                              CLK_SPI_DIV_CON_MASK << CLK_SPI0_DIV_CON_SHIFT |
720                              CLK_SPI_PLL_SEL_MASK << CLK_SPI0_PLL_SEL_SHIFT,
721                              (src_clk_div - 1) << CLK_SPI0_DIV_CON_SHIFT |
722                              CLK_SPI_PLL_SEL_GPLL << CLK_SPI0_PLL_SEL_SHIFT);
723                 break;
724         case SCLK_SPI1:
725                 rk_clrsetreg(&cru->clksel_con[53],
726                              CLK_SPI_DIV_CON_MASK << CLK_SPI1_DIV_CON_SHIFT |
727                              CLK_SPI_PLL_SEL_MASK << CLK_SPI1_PLL_SEL_SHIFT,
728                              (src_clk_div - 1) << CLK_SPI1_DIV_CON_SHIFT |
729                              CLK_SPI_PLL_SEL_GPLL << CLK_SPI1_PLL_SEL_SHIFT);
730                 break;
731         default:
732                 printf("do not support this pwm bus\n");
733                 return -EINVAL;
734         }
735
736         return px30_spi_get_clk(priv, clk_id);
737 }
738
739 static ulong px30_vop_get_clk(struct px30_clk_priv *priv, ulong clk_id)
740 {
741         struct px30_cru *cru = priv->cru;
742         u32 div, con, parent;
743
744         switch (clk_id) {
745         case ACLK_VOPB:
746         case ACLK_VOPL:
747                 con = readl(&cru->clksel_con[3]);
748                 div = con & ACLK_VO_DIV_MASK;
749                 parent = priv->gpll_hz;
750                 break;
751         case DCLK_VOPB:
752                 con = readl(&cru->clksel_con[5]);
753                 div = con & DCLK_VOPB_DIV_MASK;
754                 parent = rkclk_pll_get_rate(&cru->pll[CPLL], &cru->mode, CPLL);
755                 break;
756         case DCLK_VOPL:
757                 con = readl(&cru->clksel_con[8]);
758                 div = con & DCLK_VOPL_DIV_MASK;
759                 parent = rkclk_pll_get_rate(&cru->pll[NPLL], &cru->mode, NPLL);
760                 break;
761         default:
762                 return -ENOENT;
763         }
764
765         return DIV_TO_RATE(parent, div);
766 }
767
768 static ulong px30_vop_set_clk(struct px30_clk_priv *priv, ulong clk_id, uint hz)
769 {
770         struct px30_cru *cru = priv->cru;
771         ulong npll_hz;
772         int src_clk_div;
773
774         switch (clk_id) {
775         case ACLK_VOPB:
776         case ACLK_VOPL:
777                 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
778                 assert(src_clk_div - 1 <= 31);
779                 rk_clrsetreg(&cru->clksel_con[3],
780                              ACLK_VO_PLL_MASK | ACLK_VO_DIV_MASK,
781                              ACLK_VO_SEL_GPLL << ACLK_VO_PLL_SHIFT |
782                              (src_clk_div - 1) << ACLK_VO_DIV_SHIFT);
783                 break;
784         case DCLK_VOPB:
785                 if (hz < PX30_VOP_PLL_LIMIT) {
786                         src_clk_div = DIV_ROUND_UP(PX30_VOP_PLL_LIMIT, hz);
787                         if (src_clk_div % 2)
788                                 src_clk_div = src_clk_div - 1;
789                 } else {
790                         src_clk_div = 1;
791                 }
792                 assert(src_clk_div - 1 <= 255);
793                 rkclk_set_pll(&cru->pll[CPLL], &cru->mode,
794                               CPLL, hz * src_clk_div);
795                 rk_clrsetreg(&cru->clksel_con[5],
796                              DCLK_VOPB_SEL_MASK | DCLK_VOPB_PLL_SEL_MASK |
797                              DCLK_VOPB_DIV_MASK,
798                              DCLK_VOPB_SEL_DIVOUT << DCLK_VOPB_SEL_SHIFT |
799                              DCLK_VOPB_PLL_SEL_CPLL << DCLK_VOPB_PLL_SEL_SHIFT |
800                              (src_clk_div - 1) << DCLK_VOPB_DIV_SHIFT);
801                 break;
802         case DCLK_VOPL:
803                 npll_hz = px30_clk_get_pll_rate(priv, NPLL);
804                 if (npll_hz >= PX30_VOP_PLL_LIMIT && npll_hz >= hz &&
805                     npll_hz % hz == 0) {
806                         src_clk_div = npll_hz / hz;
807                         assert(src_clk_div - 1 <= 255);
808                 } else {
809                         if (hz < PX30_VOP_PLL_LIMIT) {
810                                 src_clk_div = DIV_ROUND_UP(PX30_VOP_PLL_LIMIT,
811                                                            hz);
812                                 if (src_clk_div % 2)
813                                         src_clk_div = src_clk_div - 1;
814                         } else {
815                                 src_clk_div = 1;
816                         }
817                         assert(src_clk_div - 1 <= 255);
818                         rkclk_set_pll(&cru->pll[NPLL], &cru->mode, NPLL,
819                                       hz * src_clk_div);
820                 }
821                 rk_clrsetreg(&cru->clksel_con[8],
822                              DCLK_VOPL_SEL_MASK | DCLK_VOPL_PLL_SEL_MASK |
823                              DCLK_VOPL_DIV_MASK,
824                              DCLK_VOPL_SEL_DIVOUT << DCLK_VOPL_SEL_SHIFT |
825                              DCLK_VOPL_PLL_SEL_NPLL << DCLK_VOPL_PLL_SEL_SHIFT |
826                              (src_clk_div - 1) << DCLK_VOPL_DIV_SHIFT);
827                 break;
828         default:
829                 printf("do not support this vop freq\n");
830                 return -EINVAL;
831         }
832
833         return px30_vop_get_clk(priv, clk_id);
834 }
835
836 static ulong px30_bus_get_clk(struct px30_clk_priv *priv, ulong clk_id)
837 {
838         struct px30_cru *cru = priv->cru;
839         u32 div, con, parent;
840
841         switch (clk_id) {
842         case ACLK_BUS_PRE:
843                 con = readl(&cru->clksel_con[23]);
844                 div = (con & BUS_ACLK_DIV_MASK) >> BUS_ACLK_DIV_SHIFT;
845                 parent = priv->gpll_hz;
846                 break;
847         case HCLK_BUS_PRE:
848                 con = readl(&cru->clksel_con[24]);
849                 div = (con & BUS_HCLK_DIV_MASK) >> BUS_HCLK_DIV_SHIFT;
850                 parent = priv->gpll_hz;
851                 break;
852         case PCLK_BUS_PRE:
853         case PCLK_WDT_NS:
854                 parent = px30_bus_get_clk(priv, ACLK_BUS_PRE);
855                 con = readl(&cru->clksel_con[24]);
856                 div = (con & BUS_PCLK_DIV_MASK) >> BUS_PCLK_DIV_SHIFT;
857                 break;
858         default:
859                 return -ENOENT;
860         }
861
862         return DIV_TO_RATE(parent, div);
863 }
864
865 static ulong px30_bus_set_clk(struct px30_clk_priv *priv, ulong clk_id,
866                               ulong hz)
867 {
868         struct px30_cru *cru = priv->cru;
869         int src_clk_div;
870
871         /*
872          * select gpll as pd_bus bus clock source and
873          * set up dependent divisors for PCLK/HCLK and ACLK clocks.
874          */
875         switch (clk_id) {
876         case ACLK_BUS_PRE:
877                 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
878                 assert(src_clk_div - 1 <= 31);
879                 rk_clrsetreg(&cru->clksel_con[23],
880                              BUS_PLL_SEL_MASK | BUS_ACLK_DIV_MASK,
881                              BUS_PLL_SEL_GPLL << BUS_PLL_SEL_SHIFT |
882                              (src_clk_div - 1) << BUS_ACLK_DIV_SHIFT);
883                 break;
884         case HCLK_BUS_PRE:
885                 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
886                 assert(src_clk_div - 1 <= 31);
887                 rk_clrsetreg(&cru->clksel_con[24],
888                              BUS_PLL_SEL_MASK | BUS_HCLK_DIV_MASK,
889                              BUS_PLL_SEL_GPLL << BUS_PLL_SEL_SHIFT |
890                              (src_clk_div - 1) << BUS_HCLK_DIV_SHIFT);
891                 break;
892         case PCLK_BUS_PRE:
893                 src_clk_div =
894                         DIV_ROUND_UP(px30_bus_get_clk(priv, ACLK_BUS_PRE), hz);
895                 assert(src_clk_div - 1 <= 3);
896                 rk_clrsetreg(&cru->clksel_con[24],
897                              BUS_PCLK_DIV_MASK,
898                              (src_clk_div - 1) << BUS_PCLK_DIV_SHIFT);
899                 break;
900         default:
901                 printf("do not support this bus freq\n");
902                 return -EINVAL;
903         }
904
905         return px30_bus_get_clk(priv, clk_id);
906 }
907
908 static ulong px30_peri_get_clk(struct px30_clk_priv *priv, ulong clk_id)
909 {
910         struct px30_cru *cru = priv->cru;
911         u32 div, con, parent;
912
913         switch (clk_id) {
914         case ACLK_PERI_PRE:
915                 con = readl(&cru->clksel_con[14]);
916                 div = (con & PERI_ACLK_DIV_MASK) >> PERI_ACLK_DIV_SHIFT;
917                 parent = priv->gpll_hz;
918                 break;
919         case HCLK_PERI_PRE:
920                 con = readl(&cru->clksel_con[14]);
921                 div = (con & PERI_HCLK_DIV_MASK) >> PERI_HCLK_DIV_SHIFT;
922                 parent = priv->gpll_hz;
923                 break;
924         default:
925                 return -ENOENT;
926         }
927
928         return DIV_TO_RATE(parent, div);
929 }
930
931 static ulong px30_peri_set_clk(struct px30_clk_priv *priv, ulong clk_id,
932                                ulong hz)
933 {
934         struct px30_cru *cru = priv->cru;
935         int src_clk_div;
936
937         src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
938         assert(src_clk_div - 1 <= 31);
939
940         /*
941          * select gpll as pd_peri bus clock source and
942          * set up dependent divisors for HCLK and ACLK clocks.
943          */
944         switch (clk_id) {
945         case ACLK_PERI_PRE:
946                 rk_clrsetreg(&cru->clksel_con[14],
947                              PERI_PLL_SEL_MASK | PERI_ACLK_DIV_MASK,
948                              PERI_PLL_GPLL << PERI_PLL_SEL_SHIFT |
949                              (src_clk_div - 1) << PERI_ACLK_DIV_SHIFT);
950                 break;
951         case HCLK_PERI_PRE:
952                 rk_clrsetreg(&cru->clksel_con[14],
953                              PERI_PLL_SEL_MASK | PERI_HCLK_DIV_MASK,
954                              PERI_PLL_GPLL << PERI_PLL_SEL_SHIFT |
955                              (src_clk_div - 1) << PERI_HCLK_DIV_SHIFT);
956                 break;
957         default:
958                 printf("do not support this peri freq\n");
959                 return -EINVAL;
960         }
961
962         return px30_peri_get_clk(priv, clk_id);
963 }
964
965 #ifndef CONFIG_SPL_BUILD
966 static ulong px30_crypto_get_clk(struct px30_clk_priv *priv, ulong clk_id)
967 {
968         struct px30_cru *cru = priv->cru;
969         u32 div, con, parent;
970
971         switch (clk_id) {
972         case SCLK_CRYPTO:
973                 con = readl(&cru->clksel_con[25]);
974                 div = (con & CRYPTO_DIV_MASK) >> CRYPTO_DIV_SHIFT;
975                 parent = priv->gpll_hz;
976                 break;
977         case SCLK_CRYPTO_APK:
978                 con = readl(&cru->clksel_con[25]);
979                 div = (con & CRYPTO_APK_DIV_MASK) >> CRYPTO_APK_DIV_SHIFT;
980                 parent = priv->gpll_hz;
981                 break;
982         default:
983                 return -ENOENT;
984         }
985
986         return DIV_TO_RATE(parent, div);
987 }
988
989 static ulong px30_crypto_set_clk(struct px30_clk_priv *priv, ulong clk_id,
990                                  ulong hz)
991 {
992         struct px30_cru *cru = priv->cru;
993         int src_clk_div;
994
995         src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
996         assert(src_clk_div - 1 <= 31);
997
998         /*
999          * select gpll as crypto clock source and
1000          * set up dependent divisors for crypto clocks.
1001          */
1002         switch (clk_id) {
1003         case SCLK_CRYPTO:
1004                 rk_clrsetreg(&cru->clksel_con[25],
1005                              CRYPTO_PLL_SEL_MASK | CRYPTO_DIV_MASK,
1006                              CRYPTO_PLL_SEL_GPLL << CRYPTO_PLL_SEL_SHIFT |
1007                              (src_clk_div - 1) << CRYPTO_DIV_SHIFT);
1008                 break;
1009         case SCLK_CRYPTO_APK:
1010                 rk_clrsetreg(&cru->clksel_con[25],
1011                              CRYPTO_APK_PLL_SEL_MASK | CRYPTO_APK_DIV_MASK,
1012                              CRYPTO_PLL_SEL_GPLL << CRYPTO_APK_SEL_SHIFT |
1013                              (src_clk_div - 1) << CRYPTO_APK_DIV_SHIFT);
1014                 break;
1015         default:
1016                 printf("do not support this peri freq\n");
1017                 return -EINVAL;
1018         }
1019
1020         return px30_crypto_get_clk(priv, clk_id);
1021 }
1022
1023 static ulong px30_i2s1_mclk_get_clk(struct px30_clk_priv *priv, ulong clk_id)
1024 {
1025         struct px30_cru *cru = priv->cru;
1026         u32 con;
1027
1028         con = readl(&cru->clksel_con[30]);
1029
1030         if (!(con & CLK_I2S1_OUT_SEL_MASK))
1031                 return -ENOENT;
1032
1033         return 12000000;
1034 }
1035
1036 static ulong px30_i2s1_mclk_set_clk(struct px30_clk_priv *priv, ulong clk_id,
1037                                     ulong hz)
1038 {
1039         struct px30_cru *cru = priv->cru;
1040
1041         if (hz != 12000000) {
1042                 printf("do not support this i2s1_mclk freq\n");
1043                 return -EINVAL;
1044         }
1045
1046         rk_clrsetreg(&cru->clksel_con[30], CLK_I2S1_OUT_SEL_MASK,
1047                      CLK_I2S1_OUT_SEL_OSC);
1048         rk_clrsetreg(&cru->clkgate_con[10], CLK_I2S1_OUT_MCLK_PAD_MASK,
1049                      CLK_I2S1_OUT_MCLK_PAD_ENABLE);
1050
1051         return px30_i2s1_mclk_get_clk(priv, clk_id);
1052 }
1053
1054 static ulong px30_mac_set_clk(struct px30_clk_priv *priv, uint hz)
1055 {
1056         struct px30_cru *cru = priv->cru;
1057         u32 con = readl(&cru->clksel_con[22]);
1058         ulong pll_rate;
1059         u8 div;
1060
1061         if ((con >> GMAC_PLL_SEL_SHIFT) & GMAC_PLL_SEL_CPLL)
1062                 pll_rate = px30_clk_get_pll_rate(priv, CPLL);
1063         else if ((con >> GMAC_PLL_SEL_SHIFT) & GMAC_PLL_SEL_NPLL)
1064                 pll_rate = px30_clk_get_pll_rate(priv, NPLL);
1065         else
1066                 pll_rate = priv->gpll_hz;
1067
1068         /*default set 50MHZ for gmac*/
1069         if (!hz)
1070                 hz = 50000000;
1071
1072         div = DIV_ROUND_UP(pll_rate, hz) - 1;
1073         assert(div < 32);
1074         rk_clrsetreg(&cru->clksel_con[22], CLK_GMAC_DIV_MASK,
1075                      div << CLK_GMAC_DIV_SHIFT);
1076
1077         return DIV_TO_RATE(pll_rate, div);
1078 }
1079
1080 static int px30_mac_set_speed_clk(struct px30_clk_priv *priv, uint hz)
1081 {
1082         struct px30_cru *cru = priv->cru;
1083
1084         if (hz != 2500000 && hz != 25000000) {
1085                 debug("Unsupported mac speed:%d\n", hz);
1086                 return -EINVAL;
1087         }
1088
1089         rk_clrsetreg(&cru->clksel_con[23], RMII_CLK_SEL_MASK,
1090                      ((hz == 2500000) ? 0 : 1) << RMII_CLK_SEL_SHIFT);
1091
1092         return 0;
1093 }
1094
1095 #endif
1096
1097 static ulong px30_clk_get_pll_rate(struct px30_clk_priv *priv,
1098                                    enum px30_pll_id pll_id)
1099 {
1100         struct px30_cru *cru = priv->cru;
1101
1102         return rkclk_pll_get_rate(&cru->pll[pll_id], &cru->mode, pll_id);
1103 }
1104
1105 static ulong px30_clk_set_pll_rate(struct px30_clk_priv *priv,
1106                                    enum px30_pll_id pll_id, ulong hz)
1107 {
1108         struct px30_cru *cru = priv->cru;
1109
1110         if (rkclk_set_pll(&cru->pll[pll_id], &cru->mode, pll_id, hz))
1111                 return -EINVAL;
1112         return rkclk_pll_get_rate(&cru->pll[pll_id], &cru->mode, pll_id);
1113 }
1114
1115 static ulong px30_armclk_set_clk(struct px30_clk_priv *priv, ulong hz)
1116 {
1117         struct px30_cru *cru = priv->cru;
1118         const struct cpu_rate_table *rate;
1119         ulong old_rate;
1120
1121         rate = get_cpu_settings(hz);
1122         if (!rate) {
1123                 printf("%s unsupport rate\n", __func__);
1124                 return -EINVAL;
1125         }
1126
1127         /*
1128          * select apll as cpu/core clock pll source and
1129          * set up dependent divisors for PERI and ACLK clocks.
1130          * core hz : apll = 1:1
1131          */
1132         old_rate = px30_clk_get_pll_rate(priv, APLL);
1133         if (old_rate > hz) {
1134                 if (rkclk_set_pll(&cru->pll[APLL], &cru->mode, APLL, hz))
1135                         return -EINVAL;
1136                 rk_clrsetreg(&cru->clksel_con[0],
1137                              CORE_CLK_PLL_SEL_MASK | CORE_DIV_CON_MASK |
1138                              CORE_ACLK_DIV_MASK | CORE_DBG_DIV_MASK,
1139                              rate->aclk_div << CORE_ACLK_DIV_SHIFT |
1140                              rate->pclk_div << CORE_DBG_DIV_SHIFT |
1141                              CORE_CLK_PLL_SEL_APLL << CORE_CLK_PLL_SEL_SHIFT |
1142                              0 << CORE_DIV_CON_SHIFT);
1143         } else if (old_rate < hz) {
1144                 rk_clrsetreg(&cru->clksel_con[0],
1145                              CORE_CLK_PLL_SEL_MASK | CORE_DIV_CON_MASK |
1146                              CORE_ACLK_DIV_MASK | CORE_DBG_DIV_MASK,
1147                              rate->aclk_div << CORE_ACLK_DIV_SHIFT |
1148                              rate->pclk_div << CORE_DBG_DIV_SHIFT |
1149                              CORE_CLK_PLL_SEL_APLL << CORE_CLK_PLL_SEL_SHIFT |
1150                              0 << CORE_DIV_CON_SHIFT);
1151                 if (rkclk_set_pll(&cru->pll[APLL], &cru->mode, APLL, hz))
1152                         return -EINVAL;
1153         }
1154
1155         return px30_clk_get_pll_rate(priv, APLL);
1156 }
1157
1158 static ulong px30_clk_get_rate(struct clk *clk)
1159 {
1160         struct px30_clk_priv *priv = dev_get_priv(clk->dev);
1161         ulong rate = 0;
1162
1163         if (!priv->gpll_hz && clk->id > ARMCLK) {
1164                 printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
1165                 return -ENOENT;
1166         }
1167
1168         debug("%s %ld\n", __func__, clk->id);
1169         switch (clk->id) {
1170         case PLL_APLL:
1171                 rate = px30_clk_get_pll_rate(priv, APLL);
1172                 break;
1173         case PLL_DPLL:
1174                 rate = px30_clk_get_pll_rate(priv, DPLL);
1175                 break;
1176         case PLL_CPLL:
1177                 rate = px30_clk_get_pll_rate(priv, CPLL);
1178                 break;
1179         case PLL_NPLL:
1180                 rate = px30_clk_get_pll_rate(priv, NPLL);
1181                 break;
1182         case ARMCLK:
1183                 rate = px30_clk_get_pll_rate(priv, APLL);
1184                 break;
1185         case HCLK_SDMMC:
1186         case HCLK_EMMC:
1187         case SCLK_SDMMC:
1188         case SCLK_EMMC:
1189         case SCLK_EMMC_SAMPLE:
1190                 rate = px30_mmc_get_clk(priv, clk->id);
1191                 break;
1192         case SCLK_I2C0:
1193         case SCLK_I2C1:
1194         case SCLK_I2C2:
1195         case SCLK_I2C3:
1196                 rate = px30_i2c_get_clk(priv, clk->id);
1197                 break;
1198         case SCLK_I2S1:
1199                 rate = px30_i2s_get_clk(priv, clk->id);
1200                 break;
1201         case SCLK_NANDC:
1202                 rate = px30_nandc_get_clk(priv);
1203                 break;
1204         case SCLK_PWM0:
1205         case SCLK_PWM1:
1206                 rate = px30_pwm_get_clk(priv, clk->id);
1207                 break;
1208         case SCLK_SARADC:
1209                 rate = px30_saradc_get_clk(priv);
1210                 break;
1211         case SCLK_TSADC:
1212                 rate = px30_tsadc_get_clk(priv);
1213                 break;
1214         case SCLK_SPI0:
1215         case SCLK_SPI1:
1216                 rate = px30_spi_get_clk(priv, clk->id);
1217                 break;
1218         case ACLK_VOPB:
1219         case ACLK_VOPL:
1220         case DCLK_VOPB:
1221         case DCLK_VOPL:
1222                 rate = px30_vop_get_clk(priv, clk->id);
1223                 break;
1224         case ACLK_BUS_PRE:
1225         case HCLK_BUS_PRE:
1226         case PCLK_BUS_PRE:
1227         case PCLK_WDT_NS:
1228                 rate = px30_bus_get_clk(priv, clk->id);
1229                 break;
1230         case ACLK_PERI_PRE:
1231         case HCLK_PERI_PRE:
1232                 rate = px30_peri_get_clk(priv, clk->id);
1233                 break;
1234 #ifndef CONFIG_SPL_BUILD
1235         case SCLK_CRYPTO:
1236         case SCLK_CRYPTO_APK:
1237                 rate = px30_crypto_get_clk(priv, clk->id);
1238                 break;
1239 #endif
1240         default:
1241                 return -ENOENT;
1242         }
1243
1244         return rate;
1245 }
1246
1247 static ulong px30_clk_set_rate(struct clk *clk, ulong rate)
1248 {
1249         struct px30_clk_priv *priv = dev_get_priv(clk->dev);
1250         ulong ret = 0;
1251
1252         if (!priv->gpll_hz && clk->id > ARMCLK) {
1253                 printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
1254                 return -ENOENT;
1255         }
1256
1257         debug("%s %ld %ld\n", __func__, clk->id, rate);
1258         switch (clk->id) {
1259         case PLL_NPLL:
1260                 ret = px30_clk_set_pll_rate(priv, NPLL, rate);
1261                 break;
1262         case ARMCLK:
1263                 ret = px30_armclk_set_clk(priv, rate);
1264                 break;
1265         case HCLK_SDMMC:
1266         case HCLK_EMMC:
1267         case SCLK_SDMMC:
1268         case SCLK_EMMC:
1269                 ret = px30_mmc_set_clk(priv, clk->id, rate);
1270                 break;
1271         case SCLK_I2C0:
1272         case SCLK_I2C1:
1273         case SCLK_I2C2:
1274         case SCLK_I2C3:
1275                 ret = px30_i2c_set_clk(priv, clk->id, rate);
1276                 break;
1277         case SCLK_I2S1:
1278                 ret = px30_i2s_set_clk(priv, clk->id, rate);
1279                 break;
1280         case SCLK_NANDC:
1281                 ret = px30_nandc_set_clk(priv, rate);
1282                 break;
1283         case SCLK_PWM0:
1284         case SCLK_PWM1:
1285                 ret = px30_pwm_set_clk(priv, clk->id, rate);
1286                 break;
1287         case SCLK_SARADC:
1288                 ret = px30_saradc_set_clk(priv, rate);
1289                 break;
1290         case SCLK_TSADC:
1291                 ret = px30_tsadc_set_clk(priv, rate);
1292                 break;
1293         case SCLK_SPI0:
1294         case SCLK_SPI1:
1295                 ret = px30_spi_set_clk(priv, clk->id, rate);
1296                 break;
1297         case ACLK_VOPB:
1298         case ACLK_VOPL:
1299         case DCLK_VOPB:
1300         case DCLK_VOPL:
1301                 ret = px30_vop_set_clk(priv, clk->id, rate);
1302                 break;
1303         case ACLK_BUS_PRE:
1304         case HCLK_BUS_PRE:
1305         case PCLK_BUS_PRE:
1306                 ret = px30_bus_set_clk(priv, clk->id, rate);
1307                 break;
1308         case ACLK_PERI_PRE:
1309         case HCLK_PERI_PRE:
1310                 ret = px30_peri_set_clk(priv, clk->id, rate);
1311                 break;
1312 #ifndef CONFIG_SPL_BUILD
1313         case SCLK_CRYPTO:
1314         case SCLK_CRYPTO_APK:
1315                 ret = px30_crypto_set_clk(priv, clk->id, rate);
1316                 break;
1317         case SCLK_I2S1_OUT:
1318                 ret = px30_i2s1_mclk_set_clk(priv, clk->id, rate);
1319                 break;
1320         case SCLK_GMAC:
1321         case SCLK_GMAC_SRC:
1322                 ret = px30_mac_set_clk(priv, rate);
1323                 break;
1324         case SCLK_GMAC_RMII:
1325                 ret = px30_mac_set_speed_clk(priv, rate);
1326                 break;
1327 #endif
1328         default:
1329                 return -ENOENT;
1330         }
1331
1332         return ret;
1333 }
1334
1335 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
1336 static int px30_gmac_set_parent(struct clk *clk, struct clk *parent)
1337 {
1338         struct px30_clk_priv *priv = dev_get_priv(clk->dev);
1339         struct px30_cru *cru = priv->cru;
1340
1341         if (parent->id == SCLK_GMAC_SRC) {
1342                 debug("%s: switching GAMC to SCLK_GMAC_SRC\n", __func__);
1343                 rk_clrsetreg(&cru->clksel_con[23], RMII_EXTCLK_SEL_MASK,
1344                              RMII_EXTCLK_SEL_INT << RMII_EXTCLK_SEL_SHIFT);
1345         } else {
1346                 debug("%s: switching GMAC to external clock\n", __func__);
1347                 rk_clrsetreg(&cru->clksel_con[23], RMII_EXTCLK_SEL_MASK,
1348                              RMII_EXTCLK_SEL_EXT << RMII_EXTCLK_SEL_SHIFT);
1349         }
1350         return 0;
1351 }
1352
1353 static int px30_clk_set_parent(struct clk *clk, struct clk *parent)
1354 {
1355         switch (clk->id) {
1356         case SCLK_GMAC:
1357                 return px30_gmac_set_parent(clk, parent);
1358         default:
1359                 return -ENOENT;
1360         }
1361 }
1362 #endif
1363
1364 static int px30_clk_enable(struct clk *clk)
1365 {
1366         switch (clk->id) {
1367         case HCLK_HOST:
1368         case SCLK_GMAC:
1369         case SCLK_GMAC_RX_TX:
1370         case SCLK_MAC_REF:
1371         case SCLK_MAC_REFOUT:
1372         case ACLK_GMAC:
1373         case PCLK_GMAC:
1374         case SCLK_GMAC_RMII:
1375                 /* Required to successfully probe the Designware GMAC driver */
1376                 return 0;
1377         }
1378
1379         debug("%s: unsupported clk %ld\n", __func__, clk->id);
1380         return -ENOENT;
1381 }
1382
1383 static struct clk_ops px30_clk_ops = {
1384         .get_rate = px30_clk_get_rate,
1385         .set_rate = px30_clk_set_rate,
1386 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
1387         .set_parent = px30_clk_set_parent,
1388 #endif
1389         .enable = px30_clk_enable,
1390 };
1391
1392 static void px30_clk_init(struct px30_clk_priv *priv)
1393 {
1394         ulong npll_hz;
1395         int ret;
1396
1397         npll_hz = px30_clk_get_pll_rate(priv, NPLL);
1398         if (npll_hz != NPLL_HZ) {
1399                 ret = px30_clk_set_pll_rate(priv, NPLL, NPLL_HZ);
1400                 if (ret < 0)
1401                         printf("%s failed to set npll rate\n", __func__);
1402         }
1403
1404         px30_bus_set_clk(priv, ACLK_BUS_PRE, ACLK_BUS_HZ);
1405         px30_bus_set_clk(priv, HCLK_BUS_PRE, HCLK_BUS_HZ);
1406         px30_bus_set_clk(priv, PCLK_BUS_PRE, PCLK_BUS_HZ);
1407         px30_peri_set_clk(priv, ACLK_PERI_PRE, ACLK_PERI_HZ);
1408         px30_peri_set_clk(priv, HCLK_PERI_PRE, HCLK_PERI_HZ);
1409 }
1410
1411 static int px30_clk_probe(struct udevice *dev)
1412 {
1413         struct px30_clk_priv *priv = dev_get_priv(dev);
1414         struct clk clk_gpll;
1415         int ret;
1416
1417         if (px30_clk_get_pll_rate(priv, APLL) != APLL_HZ)
1418                 px30_armclk_set_clk(priv, APLL_HZ);
1419
1420         /* get the GPLL rate from the pmucru */
1421         ret = clk_get_by_name(dev, "gpll", &clk_gpll);
1422         if (ret) {
1423                 printf("%s: failed to get gpll clk from pmucru\n", __func__);
1424                 return ret;
1425         }
1426
1427         priv->gpll_hz = clk_get_rate(&clk_gpll);
1428
1429         px30_clk_init(priv);
1430
1431         return 0;
1432 }
1433
1434 static int px30_clk_ofdata_to_platdata(struct udevice *dev)
1435 {
1436         struct px30_clk_priv *priv = dev_get_priv(dev);
1437
1438         priv->cru = dev_read_addr_ptr(dev);
1439
1440         return 0;
1441 }
1442
1443 static int px30_clk_bind(struct udevice *dev)
1444 {
1445         int ret;
1446         struct udevice *sys_child;
1447         struct sysreset_reg *priv;
1448
1449         /* The reset driver does not have a device node, so bind it here */
1450         ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
1451                                  &sys_child);
1452         if (ret) {
1453                 debug("Warning: No sysreset driver: ret=%d\n", ret);
1454         } else {
1455                 priv = malloc(sizeof(struct sysreset_reg));
1456                 priv->glb_srst_fst_value = offsetof(struct px30_cru,
1457                                                     glb_srst_fst);
1458                 priv->glb_srst_snd_value = offsetof(struct px30_cru,
1459                                                     glb_srst_snd);
1460                 sys_child->priv = priv;
1461         }
1462
1463 #if CONFIG_IS_ENABLED(RESET_ROCKCHIP)
1464         ret = offsetof(struct px30_cru, softrst_con[0]);
1465         ret = rockchip_reset_bind(dev, ret, 12);
1466         if (ret)
1467                 debug("Warning: software reset driver bind faile\n");
1468 #endif
1469
1470         return 0;
1471 }
1472
1473 static const struct udevice_id px30_clk_ids[] = {
1474         { .compatible = "rockchip,px30-cru" },
1475         { }
1476 };
1477
1478 U_BOOT_DRIVER(rockchip_px30_cru) = {
1479         .name           = "rockchip_px30_cru",
1480         .id             = UCLASS_CLK,
1481         .of_match       = px30_clk_ids,
1482         .priv_auto_alloc_size = sizeof(struct px30_clk_priv),
1483         .ofdata_to_platdata = px30_clk_ofdata_to_platdata,
1484         .ops            = &px30_clk_ops,
1485         .bind           = px30_clk_bind,
1486         .probe          = px30_clk_probe,
1487 };
1488
1489 static ulong px30_pclk_pmu_get_pmuclk(struct px30_pmuclk_priv *priv)
1490 {
1491         struct px30_pmucru *pmucru = priv->pmucru;
1492         u32 div, con;
1493
1494         con = readl(&pmucru->pmu_clksel_con[0]);
1495         div = (con & CLK_PMU_PCLK_DIV_MASK) >> CLK_PMU_PCLK_DIV_SHIFT;
1496
1497         return DIV_TO_RATE(priv->gpll_hz, div);
1498 }
1499
1500 static ulong px30_pclk_pmu_set_pmuclk(struct px30_pmuclk_priv *priv, ulong hz)
1501 {
1502         struct px30_pmucru *pmucru = priv->pmucru;
1503         int src_clk_div;
1504
1505         src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
1506         assert(src_clk_div - 1 <= 31);
1507
1508         rk_clrsetreg(&pmucru->pmu_clksel_con[0],
1509                      CLK_PMU_PCLK_DIV_MASK,
1510                      (src_clk_div - 1) << CLK_PMU_PCLK_DIV_SHIFT);
1511
1512         return px30_pclk_pmu_get_pmuclk(priv);
1513 }
1514
1515 static ulong px30_pmuclk_get_gpll_rate(struct px30_pmuclk_priv *priv)
1516 {
1517         struct px30_pmucru *pmucru = priv->pmucru;
1518
1519         return rkclk_pll_get_rate(&pmucru->pll, &pmucru->pmu_mode, GPLL);
1520 }
1521
1522 static ulong px30_pmuclk_set_gpll_rate(struct px30_pmuclk_priv *priv, ulong hz)
1523 {
1524         struct px30_pmucru *pmucru = priv->pmucru;
1525         ulong pclk_pmu_rate;
1526         u32 div;
1527
1528         if (priv->gpll_hz == hz)
1529                 return priv->gpll_hz;
1530
1531         div = DIV_ROUND_UP(hz, priv->gpll_hz);
1532
1533         /* save clock rate */
1534         pclk_pmu_rate = px30_pclk_pmu_get_pmuclk(priv);
1535
1536         /* avoid rate too large, reduce rate first */
1537         px30_pclk_pmu_set_pmuclk(priv, pclk_pmu_rate / div);
1538
1539         /* change gpll rate */
1540         rkclk_set_pll(&pmucru->pll, &pmucru->pmu_mode, GPLL, hz);
1541         priv->gpll_hz = px30_pmuclk_get_gpll_rate(priv);
1542
1543         /* restore clock rate */
1544         px30_pclk_pmu_set_pmuclk(priv, pclk_pmu_rate);
1545
1546         return priv->gpll_hz;
1547 }
1548
1549 static ulong px30_pmuclk_get_rate(struct clk *clk)
1550 {
1551         struct px30_pmuclk_priv *priv = dev_get_priv(clk->dev);
1552         ulong rate = 0;
1553
1554         debug("%s %ld\n", __func__, clk->id);
1555         switch (clk->id) {
1556         case PLL_GPLL:
1557                 rate = px30_pmuclk_get_gpll_rate(priv);
1558                 break;
1559         case PCLK_PMU_PRE:
1560                 rate = px30_pclk_pmu_get_pmuclk(priv);
1561                 break;
1562         default:
1563                 return -ENOENT;
1564         }
1565
1566         return rate;
1567 }
1568
1569 static ulong px30_pmuclk_set_rate(struct clk *clk, ulong rate)
1570 {
1571         struct px30_pmuclk_priv *priv = dev_get_priv(clk->dev);
1572         ulong ret = 0;
1573
1574         debug("%s %ld %ld\n", __func__, clk->id, rate);
1575         switch (clk->id) {
1576         case PLL_GPLL:
1577                 ret = px30_pmuclk_set_gpll_rate(priv, rate);
1578                 break;
1579         case PCLK_PMU_PRE:
1580                 ret = px30_pclk_pmu_set_pmuclk(priv, rate);
1581                 break;
1582         default:
1583                 return -ENOENT;
1584         }
1585
1586         return ret;
1587 }
1588
1589 static struct clk_ops px30_pmuclk_ops = {
1590         .get_rate = px30_pmuclk_get_rate,
1591         .set_rate = px30_pmuclk_set_rate,
1592 };
1593
1594 static void px30_pmuclk_init(struct px30_pmuclk_priv *priv)
1595 {
1596         priv->gpll_hz = px30_pmuclk_get_gpll_rate(priv);
1597         px30_pmuclk_set_gpll_rate(priv, GPLL_HZ);
1598
1599         px30_pclk_pmu_set_pmuclk(priv, PCLK_PMU_HZ);
1600 }
1601
1602 static int px30_pmuclk_probe(struct udevice *dev)
1603 {
1604         struct px30_pmuclk_priv *priv = dev_get_priv(dev);
1605
1606         px30_pmuclk_init(priv);
1607
1608         return 0;
1609 }
1610
1611 static int px30_pmuclk_ofdata_to_platdata(struct udevice *dev)
1612 {
1613         struct px30_pmuclk_priv *priv = dev_get_priv(dev);
1614
1615         priv->pmucru = dev_read_addr_ptr(dev);
1616
1617         return 0;
1618 }
1619
1620 static const struct udevice_id px30_pmuclk_ids[] = {
1621         { .compatible = "rockchip,px30-pmucru" },
1622         { }
1623 };
1624
1625 U_BOOT_DRIVER(rockchip_px30_pmucru) = {
1626         .name           = "rockchip_px30_pmucru",
1627         .id             = UCLASS_CLK,
1628         .of_match       = px30_pmuclk_ids,
1629         .priv_auto_alloc_size = sizeof(struct px30_pmuclk_priv),
1630         .ofdata_to_platdata = px30_pmuclk_ofdata_to_platdata,
1631         .ops            = &px30_pmuclk_ops,
1632         .probe          = px30_pmuclk_probe,
1633 };