1 // SPDX-License-Identifier: GPL-2.0
3 * (C) Copyright 2016 Rockchip Electronics Co., Ltd
4 * Author: Andy Yan <andy.yan@rock-chips.com>
9 #include <clk-uclass.h>
14 #include <asm/arch-rockchip/clock.h>
15 #include <asm/arch-rockchip/cru_rv1108.h>
16 #include <asm/arch-rockchip/hardware.h>
18 #include <dt-bindings/clock/rv1108-cru.h>
20 DECLARE_GLOBAL_DATA_PTR;
23 VCO_MAX_HZ = 2400U * 1000000,
24 VCO_MIN_HZ = 600 * 1000000,
25 OUTPUT_MAX_HZ = 2400U * 1000000,
26 OUTPUT_MIN_HZ = 24 * 1000000,
29 #define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1))
31 #define PLL_DIVISORS(hz, _refdiv, _postdiv1, _postdiv2) {\
33 .fbdiv = (u32)((u64)hz * _refdiv * _postdiv1 * _postdiv2 / OSC_HZ),\
34 .postdiv1 = _postdiv1, .postdiv2 = _postdiv2};\
35 _Static_assert(((u64)hz * _refdiv * _postdiv1 * _postdiv2 / OSC_HZ) *\
36 OSC_HZ / (_refdiv * _postdiv1 * _postdiv2) == hz,\
37 #hz "Hz cannot be hit with PLL "\
38 "divisors on line " __stringify(__LINE__));
40 static const struct pll_div apll_init_cfg = PLL_DIVISORS(APLL_HZ, 1, 3, 1);
41 static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2, 1);
43 /* use integer mode */
44 static inline int rv1108_pll_id(enum rk_clk_id clk_id)
57 printf("invalid pll id:%d\n", clk_id);
65 static int rkclk_set_pll(struct rv1108_cru *cru, enum rk_clk_id clk_id,
66 const struct pll_div *div)
68 int pll_id = rv1108_pll_id(clk_id);
69 struct rv1108_pll *pll = &cru->pll[pll_id];
71 /* All PLLs have same VCO and output frequency range restrictions. */
72 uint vco_hz = OSC_HZ / 1000 * div->fbdiv / div->refdiv * 1000;
73 uint output_hz = vco_hz / div->postdiv1 / div->postdiv2;
75 debug("PLL at %p: fb=%d, ref=%d, pst1=%d, pst2=%d, vco=%u Hz, output=%u Hz\n",
76 pll, div->fbdiv, div->refdiv, div->postdiv1,
77 div->postdiv2, vco_hz, output_hz);
78 assert(vco_hz >= VCO_MIN_HZ && vco_hz <= VCO_MAX_HZ &&
79 output_hz >= OUTPUT_MIN_HZ && output_hz <= OUTPUT_MAX_HZ);
82 * When power on or changing PLL setting,
83 * we must force PLL into slow mode to ensure output stable clock.
85 rk_clrsetreg(&pll->con3, WORK_MODE_MASK,
86 WORK_MODE_SLOW << WORK_MODE_SHIFT);
88 /* use integer mode */
89 rk_setreg(&pll->con3, 1 << DSMPD_SHIFT);
91 rk_setreg(&pll->con3, 1 << GLOBAL_POWER_DOWN_SHIFT);
93 rk_clrsetreg(&pll->con0, FBDIV_MASK, div->fbdiv << FBDIV_SHIFT);
94 rk_clrsetreg(&pll->con1, POSTDIV1_MASK | POSTDIV2_MASK | REFDIV_MASK,
95 (div->postdiv1 << POSTDIV1_SHIFT |
96 div->postdiv2 << POSTDIV2_SHIFT |
97 div->refdiv << REFDIV_SHIFT));
98 rk_clrsetreg(&pll->con2, FRACDIV_MASK,
99 (div->refdiv << REFDIV_SHIFT));
102 rk_clrreg(&pll->con3, 1 << GLOBAL_POWER_DOWN_SHIFT);
104 /* waiting for pll lock */
105 while (readl(&pll->con2) & (1 << LOCK_STA_SHIFT))
109 * set PLL into normal mode.
111 rk_clrsetreg(&pll->con3, WORK_MODE_MASK,
112 WORK_MODE_NORMAL << WORK_MODE_SHIFT);
117 static uint32_t rkclk_pll_get_rate(struct rv1108_cru *cru,
118 enum rk_clk_id clk_id)
120 uint32_t refdiv, fbdiv, postdiv1, postdiv2;
121 uint32_t con0, con1, con3;
122 int pll_id = rv1108_pll_id(clk_id);
123 struct rv1108_pll *pll = &cru->pll[pll_id];
126 con3 = readl(&pll->con3);
128 if (con3 & WORK_MODE_MASK) {
129 con0 = readl(&pll->con0);
130 con1 = readl(&pll->con1);
131 fbdiv = (con0 >> FBDIV_SHIFT) & FBDIV_MASK;
132 postdiv1 = (con1 & POSTDIV1_MASK) >> POSTDIV1_SHIFT;
133 postdiv2 = (con1 & POSTDIV2_MASK) >> POSTDIV2_SHIFT;
134 refdiv = (con1 >> REFDIV_SHIFT) & REFDIV_MASK;
135 freq = (24 * fbdiv / (refdiv * postdiv1 * postdiv2)) * 1000000;
143 static int rv1108_mac_set_clk(struct rv1108_cru *cru, ulong rate)
145 uint32_t con = readl(&cru->clksel_con[24]);
149 if ((con >> MAC_PLL_SEL_SHIFT) & MAC_PLL_SEL_GPLL)
150 pll_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
152 pll_rate = rkclk_pll_get_rate(cru, CLK_ARM);
154 /*default set 50MHZ for gmac*/
158 div = DIV_ROUND_UP(pll_rate, rate) - 1;
160 rk_clrsetreg(&cru->clksel_con[24], MAC_CLK_DIV_MASK,
161 div << MAC_CLK_DIV_SHIFT);
163 debug("Unsupported div for gmac:%d\n", div);
165 return DIV_TO_RATE(pll_rate, div);
168 static int rv1108_sfc_set_clk(struct rv1108_cru *cru, uint rate)
170 u32 con = readl(&cru->clksel_con[27]);
174 if ((con >> SFC_PLL_SEL_SHIFT) && SFC_PLL_SEL_GPLL)
175 pll_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
177 pll_rate = rkclk_pll_get_rate(cru, CLK_DDR);
179 div = DIV_ROUND_UP(pll_rate, rate) - 1;
181 rk_clrsetreg(&cru->clksel_con[27], SFC_CLK_DIV_MASK,
182 div << SFC_CLK_DIV_SHIFT);
184 debug("Unsupported sfc clk rate:%d\n", rate);
186 return DIV_TO_RATE(pll_rate, div);
189 static ulong rv1108_saradc_get_clk(struct rv1108_cru *cru)
193 val = readl(&cru->clksel_con[22]);
194 div = bitfield_extract(val, CLK_SARADC_DIV_CON_SHIFT,
195 CLK_SARADC_DIV_CON_WIDTH);
197 return DIV_TO_RATE(OSC_HZ, div);
200 static ulong rv1108_saradc_set_clk(struct rv1108_cru *cru, uint hz)
204 src_clk_div = DIV_ROUND_UP(OSC_HZ, hz) - 1;
205 assert(src_clk_div < 128);
207 rk_clrsetreg(&cru->clksel_con[22],
208 CLK_SARADC_DIV_CON_MASK,
209 src_clk_div << CLK_SARADC_DIV_CON_SHIFT);
211 return rv1108_saradc_get_clk(cru);
214 static ulong rv1108_aclk_vio1_get_clk(struct rv1108_cru *cru)
218 val = readl(&cru->clksel_con[28]);
219 div = bitfield_extract(val, ACLK_VIO1_CLK_DIV_SHIFT,
220 CLK_VIO_DIV_CON_WIDTH);
222 return DIV_TO_RATE(GPLL_HZ, div);
225 static ulong rv1108_aclk_vio1_set_clk(struct rv1108_cru *cru, uint hz)
229 src_clk_div = DIV_ROUND_UP(GPLL_HZ, hz) - 1;
230 assert(src_clk_div < 32);
232 rk_clrsetreg(&cru->clksel_con[28],
233 ACLK_VIO1_CLK_DIV_MASK | ACLK_VIO1_PLL_SEL_MASK,
234 (src_clk_div << ACLK_VIO1_CLK_DIV_SHIFT) |
235 (VIO_PLL_SEL_GPLL << ACLK_VIO1_PLL_SEL_SHIFT));
237 return rv1108_aclk_vio1_get_clk(cru);
240 static ulong rv1108_aclk_vio0_get_clk(struct rv1108_cru *cru)
244 val = readl(&cru->clksel_con[28]);
245 div = bitfield_extract(val, ACLK_VIO0_CLK_DIV_SHIFT,
246 CLK_VIO_DIV_CON_WIDTH);
248 return DIV_TO_RATE(GPLL_HZ, div);
251 static ulong rv1108_aclk_vio0_set_clk(struct rv1108_cru *cru, uint hz)
255 src_clk_div = DIV_ROUND_UP(GPLL_HZ, hz) - 1;
256 assert(src_clk_div < 32);
258 rk_clrsetreg(&cru->clksel_con[28],
259 ACLK_VIO0_CLK_DIV_MASK | ACLK_VIO0_PLL_SEL_MASK,
260 (src_clk_div << ACLK_VIO0_CLK_DIV_SHIFT) |
261 (VIO_PLL_SEL_GPLL << ACLK_VIO0_PLL_SEL_SHIFT));
263 /*HCLK_VIO default div = 4*/
264 rk_clrsetreg(&cru->clksel_con[29],
265 HCLK_VIO_CLK_DIV_MASK,
266 3 << HCLK_VIO_CLK_DIV_SHIFT);
267 /*PCLK_VIO default div = 4*/
268 rk_clrsetreg(&cru->clksel_con[29],
269 PCLK_VIO_CLK_DIV_MASK,
270 3 << PCLK_VIO_CLK_DIV_SHIFT);
272 return rv1108_aclk_vio0_get_clk(cru);
275 static ulong rv1108_dclk_vop_get_clk(struct rv1108_cru *cru)
279 val = readl(&cru->clksel_con[32]);
280 div = bitfield_extract(val, DCLK_VOP_CLK_DIV_SHIFT,
281 DCLK_VOP_DIV_CON_WIDTH);
283 return DIV_TO_RATE(GPLL_HZ, div);
286 static ulong rv1108_dclk_vop_set_clk(struct rv1108_cru *cru, uint hz)
290 src_clk_div = DIV_ROUND_UP(GPLL_HZ, hz) - 1;
291 assert(src_clk_div < 64);
293 rk_clrsetreg(&cru->clksel_con[32],
294 DCLK_VOP_CLK_DIV_MASK | DCLK_VOP_PLL_SEL_MASK |
296 (src_clk_div << DCLK_VOP_CLK_DIV_SHIFT) |
297 (DCLK_VOP_PLL_SEL_GPLL << DCLK_VOP_PLL_SEL_SHIFT) |
298 (DCLK_VOP_SEL_PLL << DCLK_VOP_SEL_SHIFT));
300 return rv1108_dclk_vop_get_clk(cru);
303 static ulong rv1108_aclk_bus_get_clk(struct rv1108_cru *cru)
306 ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
308 val = readl(&cru->clksel_con[2]);
309 div = bitfield_extract(val, ACLK_BUS_DIV_CON_SHIFT,
310 ACLK_BUS_DIV_CON_WIDTH);
312 return DIV_TO_RATE(parent_rate, div);
315 static ulong rv1108_aclk_bus_set_clk(struct rv1108_cru *cru, uint hz)
318 ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
320 src_clk_div = DIV_ROUND_UP(parent_rate, hz) - 1;
321 assert(src_clk_div < 32);
323 rk_clrsetreg(&cru->clksel_con[2],
324 ACLK_BUS_DIV_CON_MASK | ACLK_BUS_PLL_SEL_MASK,
325 (src_clk_div << ACLK_BUS_DIV_CON_SHIFT) |
326 (ACLK_BUS_PLL_SEL_GPLL << ACLK_BUS_PLL_SEL_SHIFT));
328 return rv1108_aclk_bus_get_clk(cru);
331 static ulong rv1108_aclk_peri_get_clk(struct rv1108_cru *cru)
334 ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
336 val = readl(&cru->clksel_con[23]);
337 div = bitfield_extract(val, ACLK_PERI_DIV_CON_SHIFT,
340 return DIV_TO_RATE(parent_rate, div);
343 static ulong rv1108_hclk_peri_get_clk(struct rv1108_cru *cru)
346 ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
348 val = readl(&cru->clksel_con[23]);
349 div = bitfield_extract(val, HCLK_PERI_DIV_CON_SHIFT,
352 return DIV_TO_RATE(parent_rate, div);
355 static ulong rv1108_pclk_peri_get_clk(struct rv1108_cru *cru)
358 ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
360 val = readl(&cru->clksel_con[23]);
361 div = bitfield_extract(val, PCLK_PERI_DIV_CON_SHIFT,
364 return DIV_TO_RATE(parent_rate, div);
367 static ulong rv1108_aclk_peri_set_clk(struct rv1108_cru *cru, uint hz)
370 ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
372 src_clk_div = DIV_ROUND_UP(parent_rate, hz) - 1;
373 assert(src_clk_div < 32);
375 rk_clrsetreg(&cru->clksel_con[23],
376 ACLK_PERI_DIV_CON_MASK | ACLK_PERI_PLL_SEL_MASK,
377 (src_clk_div << ACLK_PERI_DIV_CON_SHIFT) |
378 (ACLK_PERI_PLL_SEL_GPLL << ACLK_PERI_PLL_SEL_SHIFT));
380 return rv1108_aclk_peri_get_clk(cru);
383 static ulong rv1108_hclk_peri_set_clk(struct rv1108_cru *cru, uint hz)
386 ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
388 src_clk_div = DIV_ROUND_UP(parent_rate, hz) - 1;
389 assert(src_clk_div < 32);
391 rk_clrsetreg(&cru->clksel_con[23],
392 HCLK_PERI_DIV_CON_MASK,
393 (src_clk_div << HCLK_PERI_DIV_CON_SHIFT));
395 return rv1108_hclk_peri_get_clk(cru);
398 static ulong rv1108_pclk_peri_set_clk(struct rv1108_cru *cru, uint hz)
401 ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
403 src_clk_div = DIV_ROUND_UP(parent_rate, hz) - 1;
404 assert(src_clk_div < 32);
406 rk_clrsetreg(&cru->clksel_con[23],
407 PCLK_PERI_DIV_CON_MASK,
408 (src_clk_div << PCLK_PERI_DIV_CON_SHIFT));
410 return rv1108_pclk_peri_get_clk(cru);
413 static ulong rv1108_i2c_get_clk(struct rv1108_cru *cru, ulong clk_id)
419 con = readl(&cru->clksel_con[19]);
420 div = bitfield_extract(con, CLK_I2C0_DIV_CON_SHIFT,
424 con = readl(&cru->clksel_con[19]);
425 div = bitfield_extract(con, CLK_I2C1_DIV_CON_SHIFT,
429 con = readl(&cru->clksel_con[20]);
430 div = bitfield_extract(con, CLK_I2C2_DIV_CON_SHIFT,
434 con = readl(&cru->clksel_con[20]);
435 div = bitfield_extract(con, CLK_I2C3_DIV_CON_SHIFT,
439 printf("do not support this i2c bus\n");
443 return DIV_TO_RATE(GPLL_HZ, div);
446 static ulong rv1108_i2c_set_clk(struct rv1108_cru *cru, ulong clk_id, uint hz)
450 /* i2c0,4,8 src clock from ppll, i2c1,2,3,5,6,7 src clock from gpll*/
451 src_clk_div = GPLL_HZ / hz;
452 assert(src_clk_div - 1 <= 127);
456 rk_clrsetreg(&cru->clksel_con[19],
457 CLK_I2C0_DIV_CON_MASK | CLK_I2C1_PLL_SEL_MASK,
458 (src_clk_div << CLK_I2C0_DIV_CON_SHIFT) |
459 (CLK_I2C1_PLL_SEL_GPLL << CLK_I2C1_PLL_SEL_SHIFT));
462 rk_clrsetreg(&cru->clksel_con[19],
463 CLK_I2C1_DIV_CON_MASK | CLK_I2C1_PLL_SEL_MASK,
464 (src_clk_div << CLK_I2C1_DIV_CON_SHIFT) |
465 (CLK_I2C1_PLL_SEL_GPLL << CLK_I2C1_PLL_SEL_SHIFT));
468 rk_clrsetreg(&cru->clksel_con[20],
469 CLK_I2C2_DIV_CON_MASK | CLK_I2C3_PLL_SEL_MASK,
470 (src_clk_div << CLK_I2C2_DIV_CON_SHIFT) |
471 (CLK_I2C3_PLL_SEL_GPLL << CLK_I2C3_PLL_SEL_SHIFT));
474 rk_clrsetreg(&cru->clksel_con[20],
475 CLK_I2C3_DIV_CON_MASK | CLK_I2C3_PLL_SEL_MASK,
476 (src_clk_div << CLK_I2C3_DIV_CON_SHIFT) |
477 (CLK_I2C3_PLL_SEL_GPLL << CLK_I2C3_PLL_SEL_SHIFT));
480 printf("do not support this i2c bus\n");
484 return rv1108_i2c_get_clk(cru, clk_id);
487 static ulong rv1108_mmc_get_clk(struct rv1108_cru *cru)
492 con = readl(&cru->clksel_con[26]);
493 div = bitfield_extract(con, EMMC_CLK_DIV_SHIFT, 8);
495 con = readl(&cru->clksel_con[25]);
497 if ((con & EMMC_PLL_SEL_MASK) >> EMMC_PLL_SEL_SHIFT == EMMC_PLL_SEL_OSC)
498 mmc_clk = DIV_TO_RATE(OSC_HZ, div) / 2;
500 mmc_clk = DIV_TO_RATE(GPLL_HZ, div) / 2;
502 debug("%s div %d get_clk %ld\n", __func__, div, mmc_clk);
506 static ulong rv1108_mmc_set_clk(struct rv1108_cru *cru, ulong rate)
511 div = DIV_ROUND_UP(rkclk_pll_get_rate(cru, CLK_GENERAL), rate);
514 debug("%s source gpll\n", __func__);
515 rk_clrsetreg(&cru->clksel_con[25], EMMC_PLL_SEL_MASK,
516 (EMMC_PLL_SEL_GPLL << EMMC_PLL_SEL_SHIFT));
517 pll_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
519 debug("%s source 24m\n", __func__);
520 rk_clrsetreg(&cru->clksel_con[25], EMMC_PLL_SEL_MASK,
521 (EMMC_PLL_SEL_OSC << EMMC_PLL_SEL_SHIFT));
525 div = DIV_ROUND_UP(pll_rate / 2, rate);
526 rk_clrsetreg(&cru->clksel_con[26], EMMC_CLK_DIV_MASK,
527 ((div - 1) << EMMC_CLK_DIV_SHIFT));
529 debug("%s set_rate %ld div %d\n", __func__, rate, div);
531 return DIV_TO_RATE(pll_rate, div);
534 static ulong rv1108_clk_get_rate(struct clk *clk)
536 struct rv1108_clk_priv *priv = dev_get_priv(clk->dev);
540 return rkclk_pll_get_rate(priv->cru, clk->id);
542 return rv1108_saradc_get_clk(priv->cru);
544 return rv1108_aclk_vio0_get_clk(priv->cru);
546 return rv1108_aclk_vio1_get_clk(priv->cru);
548 return rv1108_dclk_vop_get_clk(priv->cru);
550 return rv1108_aclk_bus_get_clk(priv->cru);
552 return rv1108_aclk_peri_get_clk(priv->cru);
554 return rv1108_hclk_peri_get_clk(priv->cru);
556 return rv1108_pclk_peri_get_clk(priv->cru);
561 return rv1108_i2c_get_clk(priv->cru, clk->id);
564 case SCLK_EMMC_SAMPLE:
565 return rv1108_mmc_get_clk(priv->cru);
571 static ulong rv1108_clk_set_rate(struct clk *clk, ulong rate)
573 struct rv1108_clk_priv *priv = dev_get_priv(clk->dev);
578 new_rate = rv1108_mac_set_clk(priv->cru, rate);
581 new_rate = rv1108_sfc_set_clk(priv->cru, rate);
584 new_rate = rv1108_saradc_set_clk(priv->cru, rate);
587 new_rate = rv1108_aclk_vio0_set_clk(priv->cru, rate);
590 new_rate = rv1108_aclk_vio1_set_clk(priv->cru, rate);
593 new_rate = rv1108_dclk_vop_set_clk(priv->cru, rate);
596 new_rate = rv1108_aclk_bus_set_clk(priv->cru, rate);
599 new_rate = rv1108_aclk_peri_set_clk(priv->cru, rate);
602 new_rate = rv1108_hclk_peri_set_clk(priv->cru, rate);
605 new_rate = rv1108_pclk_peri_set_clk(priv->cru, rate);
611 new_rate = rv1108_i2c_set_clk(priv->cru, clk->id, rate);
615 new_rate = rv1108_mmc_set_clk(priv->cru, rate);
624 static const struct clk_ops rv1108_clk_ops = {
625 .get_rate = rv1108_clk_get_rate,
626 .set_rate = rv1108_clk_set_rate,
629 static void rkclk_init(struct rv1108_cru *cru)
631 unsigned int apll, dpll, gpll;
632 unsigned int aclk_bus, aclk_peri, hclk_peri, pclk_peri;
634 aclk_bus = rv1108_aclk_bus_set_clk(cru, ACLK_BUS_HZ / 2);
635 aclk_peri = rv1108_aclk_peri_set_clk(cru, ACLK_PERI_HZ / 2);
636 hclk_peri = rv1108_hclk_peri_set_clk(cru, HCLK_PERI_HZ / 2);
637 pclk_peri = rv1108_pclk_peri_set_clk(cru, PCLK_PERI_HZ / 2);
638 rv1108_aclk_vio0_set_clk(cru, 297000000);
639 rv1108_aclk_vio1_set_clk(cru, 297000000);
642 rkclk_set_pll(cru, CLK_ARM, &apll_init_cfg);
643 rkclk_set_pll(cru, CLK_GENERAL, &gpll_init_cfg);
644 aclk_bus = rv1108_aclk_bus_set_clk(cru, ACLK_BUS_HZ);
645 aclk_peri = rv1108_aclk_peri_set_clk(cru, ACLK_PERI_HZ);
646 hclk_peri = rv1108_hclk_peri_set_clk(cru, HCLK_PERI_HZ);
647 pclk_peri = rv1108_pclk_peri_set_clk(cru, PCLK_PERI_HZ);
649 apll = rkclk_pll_get_rate(cru, CLK_ARM);
650 dpll = rkclk_pll_get_rate(cru, CLK_DDR);
651 gpll = rkclk_pll_get_rate(cru, CLK_GENERAL);
653 rk_clrsetreg(&cru->clksel_con[0], CORE_CLK_DIV_MASK,
654 0 << MAC_CLK_DIV_SHIFT);
656 printf("APLL: %d DPLL:%d GPLL:%d\n", apll, dpll, gpll);
657 printf("ACLK_BUS: %d ACLK_PERI:%d HCLK_PERI:%d PCLK_PERI:%d\n",
658 aclk_bus, aclk_peri, hclk_peri, pclk_peri);
661 static int rv1108_clk_ofdata_to_platdata(struct udevice *dev)
663 struct rv1108_clk_priv *priv = dev_get_priv(dev);
665 priv->cru = dev_read_addr_ptr(dev);
670 static int rv1108_clk_probe(struct udevice *dev)
672 struct rv1108_clk_priv *priv = dev_get_priv(dev);
674 rkclk_init(priv->cru);
679 static int rv1108_clk_bind(struct udevice *dev)
682 struct udevice *sys_child, *sf_child;
683 struct sysreset_reg *priv;
684 struct softreset_reg *sf_priv;
686 /* The reset driver does not have a device node, so bind it here */
687 ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
690 debug("Warning: No sysreset driver: ret=%d\n", ret);
692 priv = malloc(sizeof(struct sysreset_reg));
693 priv->glb_srst_fst_value = offsetof(struct rv1108_cru,
695 priv->glb_srst_snd_value = offsetof(struct rv1108_cru,
697 sys_child->priv = priv;
700 #if CONFIG_IS_ENABLED(CONFIG_RESET_ROCKCHIP)
701 ret = offsetof(struct rk3368_cru, softrst_con[0]);
702 ret = rockchip_reset_bind(dev, ret, 13);
704 debug("Warning: software reset driver bind faile\n");
706 ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset",
707 dev_ofnode(dev), &sf_child);
709 debug("Warning: No rockchip reset driver: ret=%d\n", ret);
711 sf_priv = malloc(sizeof(struct softreset_reg));
712 sf_priv->sf_reset_offset = offsetof(struct rv1108_cru,
714 sf_priv->sf_reset_num = 13;
715 sf_child->priv = sf_priv;
721 static const struct udevice_id rv1108_clk_ids[] = {
722 { .compatible = "rockchip,rv1108-cru" },
726 U_BOOT_DRIVER(clk_rv1108) = {
727 .name = "clk_rv1108",
729 .of_match = rv1108_clk_ids,
730 .priv_auto_alloc_size = sizeof(struct rv1108_clk_priv),
731 .ops = &rv1108_clk_ops,
732 .bind = rv1108_clk_bind,
733 .ofdata_to_platdata = rv1108_clk_ofdata_to_platdata,
734 .probe = rv1108_clk_probe,