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>
16 #include <asm/arch-rockchip/clock.h>
17 #include <asm/arch-rockchip/cru_rv1108.h>
18 #include <asm/arch-rockchip/hardware.h>
19 #include <dm/device-internal.h>
21 #include <dt-bindings/clock/rv1108-cru.h>
22 #include <linux/delay.h>
23 #include <linux/stringify.h>
25 DECLARE_GLOBAL_DATA_PTR;
28 VCO_MAX_HZ = 2400U * 1000000,
29 VCO_MIN_HZ = 600 * 1000000,
30 OUTPUT_MAX_HZ = 2400U * 1000000,
31 OUTPUT_MIN_HZ = 24 * 1000000,
34 #define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1))
36 #define PLL_DIVISORS(hz, _refdiv, _postdiv1, _postdiv2) {\
38 .fbdiv = (u32)((u64)hz * _refdiv * _postdiv1 * _postdiv2 / OSC_HZ),\
39 .postdiv1 = _postdiv1, .postdiv2 = _postdiv2};\
40 _Static_assert(((u64)hz * _refdiv * _postdiv1 * _postdiv2 / OSC_HZ) *\
41 OSC_HZ / (_refdiv * _postdiv1 * _postdiv2) == hz,\
42 #hz "Hz cannot be hit with PLL "\
43 "divisors on line " __stringify(__LINE__));
45 static const struct pll_div apll_init_cfg = PLL_DIVISORS(APLL_HZ, 1, 3, 1);
46 static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2, 1);
48 /* use integer mode */
49 static inline int rv1108_pll_id(enum rk_clk_id clk_id)
62 printf("invalid pll id:%d\n", clk_id);
70 static int rkclk_set_pll(struct rv1108_cru *cru, enum rk_clk_id clk_id,
71 const struct pll_div *div)
73 int pll_id = rv1108_pll_id(clk_id);
74 struct rv1108_pll *pll = &cru->pll[pll_id];
76 /* All PLLs have same VCO and output frequency range restrictions. */
77 uint vco_hz = OSC_HZ / 1000 * div->fbdiv / div->refdiv * 1000;
78 uint output_hz = vco_hz / div->postdiv1 / div->postdiv2;
80 debug("PLL at %p: fb=%d, ref=%d, pst1=%d, pst2=%d, vco=%u Hz, output=%u Hz\n",
81 pll, div->fbdiv, div->refdiv, div->postdiv1,
82 div->postdiv2, vco_hz, output_hz);
83 assert(vco_hz >= VCO_MIN_HZ && vco_hz <= VCO_MAX_HZ &&
84 output_hz >= OUTPUT_MIN_HZ && output_hz <= OUTPUT_MAX_HZ);
87 * When power on or changing PLL setting,
88 * we must force PLL into slow mode to ensure output stable clock.
90 rk_clrsetreg(&pll->con3, WORK_MODE_MASK,
91 WORK_MODE_SLOW << WORK_MODE_SHIFT);
93 /* use integer mode */
94 rk_setreg(&pll->con3, 1 << DSMPD_SHIFT);
96 rk_setreg(&pll->con3, 1 << GLOBAL_POWER_DOWN_SHIFT);
98 rk_clrsetreg(&pll->con0, FBDIV_MASK, div->fbdiv << FBDIV_SHIFT);
99 rk_clrsetreg(&pll->con1, POSTDIV1_MASK | POSTDIV2_MASK | REFDIV_MASK,
100 (div->postdiv1 << POSTDIV1_SHIFT |
101 div->postdiv2 << POSTDIV2_SHIFT |
102 div->refdiv << REFDIV_SHIFT));
103 rk_clrsetreg(&pll->con2, FRACDIV_MASK,
104 (div->refdiv << REFDIV_SHIFT));
107 rk_clrreg(&pll->con3, 1 << GLOBAL_POWER_DOWN_SHIFT);
109 /* waiting for pll lock */
110 while (readl(&pll->con2) & (1 << LOCK_STA_SHIFT))
114 * set PLL into normal mode.
116 rk_clrsetreg(&pll->con3, WORK_MODE_MASK,
117 WORK_MODE_NORMAL << WORK_MODE_SHIFT);
122 static uint32_t rkclk_pll_get_rate(struct rv1108_cru *cru,
123 enum rk_clk_id clk_id)
125 uint32_t refdiv, fbdiv, postdiv1, postdiv2;
126 uint32_t con0, con1, con3;
127 int pll_id = rv1108_pll_id(clk_id);
128 struct rv1108_pll *pll = &cru->pll[pll_id];
131 con3 = readl(&pll->con3);
133 if (con3 & WORK_MODE_MASK) {
134 con0 = readl(&pll->con0);
135 con1 = readl(&pll->con1);
136 fbdiv = (con0 >> FBDIV_SHIFT) & FBDIV_MASK;
137 postdiv1 = (con1 & POSTDIV1_MASK) >> POSTDIV1_SHIFT;
138 postdiv2 = (con1 & POSTDIV2_MASK) >> POSTDIV2_SHIFT;
139 refdiv = (con1 >> REFDIV_SHIFT) & REFDIV_MASK;
140 freq = (24 * fbdiv / (refdiv * postdiv1 * postdiv2)) * 1000000;
148 static int rv1108_mac_set_clk(struct rv1108_cru *cru, ulong rate)
150 uint32_t con = readl(&cru->clksel_con[24]);
154 if ((con >> MAC_PLL_SEL_SHIFT) & MAC_PLL_SEL_GPLL)
155 pll_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
157 pll_rate = rkclk_pll_get_rate(cru, CLK_ARM);
159 /*default set 50MHZ for gmac*/
163 div = DIV_ROUND_UP(pll_rate, rate) - 1;
165 rk_clrsetreg(&cru->clksel_con[24], MAC_CLK_DIV_MASK,
166 div << MAC_CLK_DIV_SHIFT);
168 debug("Unsupported div for gmac:%d\n", div);
170 return DIV_TO_RATE(pll_rate, div);
173 static int rv1108_sfc_set_clk(struct rv1108_cru *cru, uint rate)
175 u32 con = readl(&cru->clksel_con[27]);
179 if ((con >> SFC_PLL_SEL_SHIFT) && SFC_PLL_SEL_GPLL)
180 pll_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
182 pll_rate = rkclk_pll_get_rate(cru, CLK_DDR);
184 div = DIV_ROUND_UP(pll_rate, rate) - 1;
186 rk_clrsetreg(&cru->clksel_con[27], SFC_CLK_DIV_MASK,
187 div << SFC_CLK_DIV_SHIFT);
189 debug("Unsupported sfc clk rate:%d\n", rate);
191 return DIV_TO_RATE(pll_rate, div);
194 static ulong rv1108_saradc_get_clk(struct rv1108_cru *cru)
198 val = readl(&cru->clksel_con[22]);
199 div = bitfield_extract(val, CLK_SARADC_DIV_CON_SHIFT,
200 CLK_SARADC_DIV_CON_WIDTH);
202 return DIV_TO_RATE(OSC_HZ, div);
205 static ulong rv1108_saradc_set_clk(struct rv1108_cru *cru, uint hz)
209 src_clk_div = DIV_ROUND_UP(OSC_HZ, hz) - 1;
210 assert(src_clk_div < 128);
212 rk_clrsetreg(&cru->clksel_con[22],
213 CLK_SARADC_DIV_CON_MASK,
214 src_clk_div << CLK_SARADC_DIV_CON_SHIFT);
216 return rv1108_saradc_get_clk(cru);
219 static ulong rv1108_aclk_vio1_get_clk(struct rv1108_cru *cru)
223 val = readl(&cru->clksel_con[28]);
224 div = bitfield_extract(val, ACLK_VIO1_CLK_DIV_SHIFT,
225 CLK_VIO_DIV_CON_WIDTH);
227 return DIV_TO_RATE(GPLL_HZ, div);
230 static ulong rv1108_aclk_vio1_set_clk(struct rv1108_cru *cru, uint hz)
234 src_clk_div = DIV_ROUND_UP(GPLL_HZ, hz) - 1;
235 assert(src_clk_div < 32);
237 rk_clrsetreg(&cru->clksel_con[28],
238 ACLK_VIO1_CLK_DIV_MASK | ACLK_VIO1_PLL_SEL_MASK,
239 (src_clk_div << ACLK_VIO1_CLK_DIV_SHIFT) |
240 (VIO_PLL_SEL_GPLL << ACLK_VIO1_PLL_SEL_SHIFT));
242 return rv1108_aclk_vio1_get_clk(cru);
245 static ulong rv1108_aclk_vio0_get_clk(struct rv1108_cru *cru)
249 val = readl(&cru->clksel_con[28]);
250 div = bitfield_extract(val, ACLK_VIO0_CLK_DIV_SHIFT,
251 CLK_VIO_DIV_CON_WIDTH);
253 return DIV_TO_RATE(GPLL_HZ, div);
256 static ulong rv1108_aclk_vio0_set_clk(struct rv1108_cru *cru, uint hz)
260 src_clk_div = DIV_ROUND_UP(GPLL_HZ, hz) - 1;
261 assert(src_clk_div < 32);
263 rk_clrsetreg(&cru->clksel_con[28],
264 ACLK_VIO0_CLK_DIV_MASK | ACLK_VIO0_PLL_SEL_MASK,
265 (src_clk_div << ACLK_VIO0_CLK_DIV_SHIFT) |
266 (VIO_PLL_SEL_GPLL << ACLK_VIO0_PLL_SEL_SHIFT));
268 /*HCLK_VIO default div = 4*/
269 rk_clrsetreg(&cru->clksel_con[29],
270 HCLK_VIO_CLK_DIV_MASK,
271 3 << HCLK_VIO_CLK_DIV_SHIFT);
272 /*PCLK_VIO default div = 4*/
273 rk_clrsetreg(&cru->clksel_con[29],
274 PCLK_VIO_CLK_DIV_MASK,
275 3 << PCLK_VIO_CLK_DIV_SHIFT);
277 return rv1108_aclk_vio0_get_clk(cru);
280 static ulong rv1108_dclk_vop_get_clk(struct rv1108_cru *cru)
284 val = readl(&cru->clksel_con[32]);
285 div = bitfield_extract(val, DCLK_VOP_CLK_DIV_SHIFT,
286 DCLK_VOP_DIV_CON_WIDTH);
288 return DIV_TO_RATE(GPLL_HZ, div);
291 static ulong rv1108_dclk_vop_set_clk(struct rv1108_cru *cru, uint hz)
295 src_clk_div = DIV_ROUND_UP(GPLL_HZ, hz) - 1;
296 assert(src_clk_div < 64);
298 rk_clrsetreg(&cru->clksel_con[32],
299 DCLK_VOP_CLK_DIV_MASK | DCLK_VOP_PLL_SEL_MASK |
301 (src_clk_div << DCLK_VOP_CLK_DIV_SHIFT) |
302 (DCLK_VOP_PLL_SEL_GPLL << DCLK_VOP_PLL_SEL_SHIFT) |
303 (DCLK_VOP_SEL_PLL << DCLK_VOP_SEL_SHIFT));
305 return rv1108_dclk_vop_get_clk(cru);
308 static ulong rv1108_aclk_bus_get_clk(struct rv1108_cru *cru)
311 ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
313 val = readl(&cru->clksel_con[2]);
314 div = bitfield_extract(val, ACLK_BUS_DIV_CON_SHIFT,
315 ACLK_BUS_DIV_CON_WIDTH);
317 return DIV_TO_RATE(parent_rate, div);
320 static ulong rv1108_aclk_bus_set_clk(struct rv1108_cru *cru, uint hz)
323 ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
325 src_clk_div = DIV_ROUND_UP(parent_rate, hz) - 1;
326 assert(src_clk_div < 32);
328 rk_clrsetreg(&cru->clksel_con[2],
329 ACLK_BUS_DIV_CON_MASK | ACLK_BUS_PLL_SEL_MASK,
330 (src_clk_div << ACLK_BUS_DIV_CON_SHIFT) |
331 (ACLK_BUS_PLL_SEL_GPLL << ACLK_BUS_PLL_SEL_SHIFT));
333 return rv1108_aclk_bus_get_clk(cru);
336 static ulong rv1108_aclk_peri_get_clk(struct rv1108_cru *cru)
339 ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
341 val = readl(&cru->clksel_con[23]);
342 div = bitfield_extract(val, ACLK_PERI_DIV_CON_SHIFT,
345 return DIV_TO_RATE(parent_rate, div);
348 static ulong rv1108_hclk_peri_get_clk(struct rv1108_cru *cru)
351 ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
353 val = readl(&cru->clksel_con[23]);
354 div = bitfield_extract(val, HCLK_PERI_DIV_CON_SHIFT,
357 return DIV_TO_RATE(parent_rate, div);
360 static ulong rv1108_pclk_peri_get_clk(struct rv1108_cru *cru)
363 ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
365 val = readl(&cru->clksel_con[23]);
366 div = bitfield_extract(val, PCLK_PERI_DIV_CON_SHIFT,
369 return DIV_TO_RATE(parent_rate, div);
372 static ulong rv1108_aclk_peri_set_clk(struct rv1108_cru *cru, uint hz)
375 ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
377 src_clk_div = DIV_ROUND_UP(parent_rate, hz) - 1;
378 assert(src_clk_div < 32);
380 rk_clrsetreg(&cru->clksel_con[23],
381 ACLK_PERI_DIV_CON_MASK | ACLK_PERI_PLL_SEL_MASK,
382 (src_clk_div << ACLK_PERI_DIV_CON_SHIFT) |
383 (ACLK_PERI_PLL_SEL_GPLL << ACLK_PERI_PLL_SEL_SHIFT));
385 return rv1108_aclk_peri_get_clk(cru);
388 static ulong rv1108_hclk_peri_set_clk(struct rv1108_cru *cru, uint hz)
391 ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
393 src_clk_div = DIV_ROUND_UP(parent_rate, hz) - 1;
394 assert(src_clk_div < 32);
396 rk_clrsetreg(&cru->clksel_con[23],
397 HCLK_PERI_DIV_CON_MASK,
398 (src_clk_div << HCLK_PERI_DIV_CON_SHIFT));
400 return rv1108_hclk_peri_get_clk(cru);
403 static ulong rv1108_pclk_peri_set_clk(struct rv1108_cru *cru, uint hz)
406 ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
408 src_clk_div = DIV_ROUND_UP(parent_rate, hz) - 1;
409 assert(src_clk_div < 32);
411 rk_clrsetreg(&cru->clksel_con[23],
412 PCLK_PERI_DIV_CON_MASK,
413 (src_clk_div << PCLK_PERI_DIV_CON_SHIFT));
415 return rv1108_pclk_peri_get_clk(cru);
418 static ulong rv1108_i2c_get_clk(struct rv1108_cru *cru, ulong clk_id)
424 con = readl(&cru->clksel_con[19]);
425 div = bitfield_extract(con, CLK_I2C0_DIV_CON_SHIFT,
429 con = readl(&cru->clksel_con[19]);
430 div = bitfield_extract(con, CLK_I2C1_DIV_CON_SHIFT,
434 con = readl(&cru->clksel_con[20]);
435 div = bitfield_extract(con, CLK_I2C2_DIV_CON_SHIFT,
439 con = readl(&cru->clksel_con[20]);
440 div = bitfield_extract(con, CLK_I2C3_DIV_CON_SHIFT,
444 printf("do not support this i2c bus\n");
448 return DIV_TO_RATE(GPLL_HZ, div);
451 static ulong rv1108_i2c_set_clk(struct rv1108_cru *cru, ulong clk_id, uint hz)
455 /* i2c0,4,8 src clock from ppll, i2c1,2,3,5,6,7 src clock from gpll*/
456 src_clk_div = GPLL_HZ / hz;
457 assert(src_clk_div - 1 <= 127);
461 rk_clrsetreg(&cru->clksel_con[19],
462 CLK_I2C0_DIV_CON_MASK | CLK_I2C1_PLL_SEL_MASK,
463 (src_clk_div << CLK_I2C0_DIV_CON_SHIFT) |
464 (CLK_I2C1_PLL_SEL_GPLL << CLK_I2C1_PLL_SEL_SHIFT));
467 rk_clrsetreg(&cru->clksel_con[19],
468 CLK_I2C1_DIV_CON_MASK | CLK_I2C1_PLL_SEL_MASK,
469 (src_clk_div << CLK_I2C1_DIV_CON_SHIFT) |
470 (CLK_I2C1_PLL_SEL_GPLL << CLK_I2C1_PLL_SEL_SHIFT));
473 rk_clrsetreg(&cru->clksel_con[20],
474 CLK_I2C2_DIV_CON_MASK | CLK_I2C3_PLL_SEL_MASK,
475 (src_clk_div << CLK_I2C2_DIV_CON_SHIFT) |
476 (CLK_I2C3_PLL_SEL_GPLL << CLK_I2C3_PLL_SEL_SHIFT));
479 rk_clrsetreg(&cru->clksel_con[20],
480 CLK_I2C3_DIV_CON_MASK | CLK_I2C3_PLL_SEL_MASK,
481 (src_clk_div << CLK_I2C3_DIV_CON_SHIFT) |
482 (CLK_I2C3_PLL_SEL_GPLL << CLK_I2C3_PLL_SEL_SHIFT));
485 printf("do not support this i2c bus\n");
489 return rv1108_i2c_get_clk(cru, clk_id);
492 static ulong rv1108_mmc_get_clk(struct rv1108_cru *cru)
497 con = readl(&cru->clksel_con[26]);
498 div = bitfield_extract(con, EMMC_CLK_DIV_SHIFT, 8);
500 con = readl(&cru->clksel_con[25]);
502 if ((con & EMMC_PLL_SEL_MASK) >> EMMC_PLL_SEL_SHIFT == EMMC_PLL_SEL_OSC)
503 mmc_clk = DIV_TO_RATE(OSC_HZ, div) / 2;
505 mmc_clk = DIV_TO_RATE(GPLL_HZ, div) / 2;
507 debug("%s div %d get_clk %ld\n", __func__, div, mmc_clk);
511 static ulong rv1108_mmc_set_clk(struct rv1108_cru *cru, ulong rate)
516 div = DIV_ROUND_UP(rkclk_pll_get_rate(cru, CLK_GENERAL), rate);
519 debug("%s source gpll\n", __func__);
520 rk_clrsetreg(&cru->clksel_con[25], EMMC_PLL_SEL_MASK,
521 (EMMC_PLL_SEL_GPLL << EMMC_PLL_SEL_SHIFT));
522 pll_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
524 debug("%s source 24m\n", __func__);
525 rk_clrsetreg(&cru->clksel_con[25], EMMC_PLL_SEL_MASK,
526 (EMMC_PLL_SEL_OSC << EMMC_PLL_SEL_SHIFT));
530 div = DIV_ROUND_UP(pll_rate / 2, rate);
531 rk_clrsetreg(&cru->clksel_con[26], EMMC_CLK_DIV_MASK,
532 ((div - 1) << EMMC_CLK_DIV_SHIFT));
534 debug("%s set_rate %ld div %d\n", __func__, rate, div);
536 return DIV_TO_RATE(pll_rate, div);
539 static ulong rv1108_clk_get_rate(struct clk *clk)
541 struct rv1108_clk_priv *priv = dev_get_priv(clk->dev);
545 return rkclk_pll_get_rate(priv->cru, clk->id);
547 return rv1108_saradc_get_clk(priv->cru);
549 return rv1108_aclk_vio0_get_clk(priv->cru);
551 return rv1108_aclk_vio1_get_clk(priv->cru);
553 return rv1108_dclk_vop_get_clk(priv->cru);
555 return rv1108_aclk_bus_get_clk(priv->cru);
557 return rv1108_aclk_peri_get_clk(priv->cru);
559 return rv1108_hclk_peri_get_clk(priv->cru);
561 return rv1108_pclk_peri_get_clk(priv->cru);
566 return rv1108_i2c_get_clk(priv->cru, clk->id);
569 case SCLK_EMMC_SAMPLE:
570 return rv1108_mmc_get_clk(priv->cru);
576 static ulong rv1108_clk_set_rate(struct clk *clk, ulong rate)
578 struct rv1108_clk_priv *priv = dev_get_priv(clk->dev);
583 new_rate = rv1108_mac_set_clk(priv->cru, rate);
586 new_rate = rv1108_sfc_set_clk(priv->cru, rate);
589 new_rate = rv1108_saradc_set_clk(priv->cru, rate);
592 new_rate = rv1108_aclk_vio0_set_clk(priv->cru, rate);
595 new_rate = rv1108_aclk_vio1_set_clk(priv->cru, rate);
598 new_rate = rv1108_dclk_vop_set_clk(priv->cru, rate);
601 new_rate = rv1108_aclk_bus_set_clk(priv->cru, rate);
604 new_rate = rv1108_aclk_peri_set_clk(priv->cru, rate);
607 new_rate = rv1108_hclk_peri_set_clk(priv->cru, rate);
610 new_rate = rv1108_pclk_peri_set_clk(priv->cru, rate);
616 new_rate = rv1108_i2c_set_clk(priv->cru, clk->id, rate);
620 new_rate = rv1108_mmc_set_clk(priv->cru, rate);
629 static const struct clk_ops rv1108_clk_ops = {
630 .get_rate = rv1108_clk_get_rate,
631 .set_rate = rv1108_clk_set_rate,
634 static void rkclk_init(struct rv1108_cru *cru)
636 unsigned int apll, dpll, gpll;
637 unsigned int aclk_bus, aclk_peri, hclk_peri, pclk_peri;
639 aclk_bus = rv1108_aclk_bus_set_clk(cru, ACLK_BUS_HZ / 2);
640 aclk_peri = rv1108_aclk_peri_set_clk(cru, ACLK_PERI_HZ / 2);
641 hclk_peri = rv1108_hclk_peri_set_clk(cru, HCLK_PERI_HZ / 2);
642 pclk_peri = rv1108_pclk_peri_set_clk(cru, PCLK_PERI_HZ / 2);
643 rv1108_aclk_vio0_set_clk(cru, 297000000);
644 rv1108_aclk_vio1_set_clk(cru, 297000000);
647 rkclk_set_pll(cru, CLK_ARM, &apll_init_cfg);
648 rkclk_set_pll(cru, CLK_GENERAL, &gpll_init_cfg);
649 aclk_bus = rv1108_aclk_bus_set_clk(cru, ACLK_BUS_HZ);
650 aclk_peri = rv1108_aclk_peri_set_clk(cru, ACLK_PERI_HZ);
651 hclk_peri = rv1108_hclk_peri_set_clk(cru, HCLK_PERI_HZ);
652 pclk_peri = rv1108_pclk_peri_set_clk(cru, PCLK_PERI_HZ);
654 apll = rkclk_pll_get_rate(cru, CLK_ARM);
655 dpll = rkclk_pll_get_rate(cru, CLK_DDR);
656 gpll = rkclk_pll_get_rate(cru, CLK_GENERAL);
658 rk_clrsetreg(&cru->clksel_con[0], CORE_CLK_DIV_MASK,
659 0 << MAC_CLK_DIV_SHIFT);
661 printf("APLL: %d DPLL:%d GPLL:%d\n", apll, dpll, gpll);
662 printf("ACLK_BUS: %d ACLK_PERI:%d HCLK_PERI:%d PCLK_PERI:%d\n",
663 aclk_bus, aclk_peri, hclk_peri, pclk_peri);
666 static int rv1108_clk_of_to_plat(struct udevice *dev)
668 struct rv1108_clk_priv *priv = dev_get_priv(dev);
670 priv->cru = dev_read_addr_ptr(dev);
675 static int rv1108_clk_probe(struct udevice *dev)
677 struct rv1108_clk_priv *priv = dev_get_priv(dev);
679 rkclk_init(priv->cru);
684 static int rv1108_clk_bind(struct udevice *dev)
687 struct udevice *sys_child;
688 struct sysreset_reg *priv;
690 /* The reset driver does not have a device node, so bind it here */
691 ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
694 debug("Warning: No sysreset driver: ret=%d\n", ret);
696 priv = malloc(sizeof(struct sysreset_reg));
697 priv->glb_srst_fst_value = offsetof(struct rv1108_cru,
699 priv->glb_srst_snd_value = offsetof(struct rv1108_cru,
701 dev_set_priv(sys_child, priv);
704 #if CONFIG_IS_ENABLED(RESET_ROCKCHIP)
705 ret = offsetof(struct rv1108_cru, softrst_con[0]);
706 ret = rockchip_reset_bind(dev, ret, 13);
708 debug("Warning: software reset driver bind faile\n");
714 static const struct udevice_id rv1108_clk_ids[] = {
715 { .compatible = "rockchip,rv1108-cru" },
719 U_BOOT_DRIVER(clk_rv1108) = {
720 .name = "clk_rv1108",
722 .of_match = rv1108_clk_ids,
723 .priv_auto = sizeof(struct rv1108_clk_priv),
724 .ops = &rv1108_clk_ops,
725 .bind = rv1108_clk_bind,
726 .of_to_plat = rv1108_clk_of_to_plat,
727 .probe = rv1108_clk_probe,