Lines Matching +full:clock +full:- +full:div
1 // SPDX-License-Identifier: GPL-2.0
8 #include <clk-uclass.h>
12 #include <asm/arch/clock.h>
18 #include <dt-bindings/clock/rk3328-cru.h>
29 ((input_rate) / (output_rate) - 1);
30 #define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1)) argument
185 * the div restructions of pll in integer mode, these are defined in
198 * FOUTVCO = Fractional PLL non-divided output frequency
202 * REFDIV = Fractional PLL input reference clock divider
207 const struct pll_div *div) in rkclk_set_pll() argument
216 pll_con = cru->apll_con; in rkclk_set_pll()
220 pll_con = cru->dpll_con; in rkclk_set_pll()
224 pll_con = cru->cpll_con; in rkclk_set_pll()
228 pll_con = cru->gpll_con; in rkclk_set_pll()
232 pll_con = cru->npll_con; in rkclk_set_pll()
241 u32 vco_khz = OSC_HZ / 1000 * div->fbdiv / div->refdiv; in rkclk_set_pll()
242 u32 output_khz = vco_khz / div->postdiv1 / div->postdiv2; in rkclk_set_pll()
246 pll_con, div->fbdiv, div->refdiv, div->postdiv1, in rkclk_set_pll()
247 div->postdiv2, vco_khz, output_khz); in rkclk_set_pll()
250 div->fbdiv >= PLL_DIV_MIN && div->fbdiv <= PLL_DIV_MAX); in rkclk_set_pll()
254 * we must force PLL into slow mode to ensure output stable clock. in rkclk_set_pll()
256 rk_clrsetreg(&cru->mode_con, mode_mask, PLL_MODE_SLOW << mode_shift); in rkclk_set_pll()
264 (div->fbdiv << PLL_FBDIV_SHIFT) | in rkclk_set_pll()
265 (div->postdiv1 << PLL_POSTDIV1_SHIFT)); in rkclk_set_pll()
268 (div->postdiv2 << PLL_POSTDIV2_SHIFT) | in rkclk_set_pll()
269 (div->refdiv << PLL_REFDIV_SHIFT)); in rkclk_set_pll()
276 rk_clrsetreg(&cru->mode_con, mode_mask, PLL_MODE_NORM << mode_shift); in rkclk_set_pll()
290 aclk_div = GPLL_HZ / PERIHP_ACLK_HZ - 1; in rkclk_init()
291 hclk_div = PERIHP_ACLK_HZ / PERIHP_HCLK_HZ - 1; in rkclk_init()
292 pclk_div = PERIHP_ACLK_HZ / PERIHP_PCLK_HZ - 1; in rkclk_init()
294 rk_clrsetreg(&cru->clksel_con[28], in rkclk_init()
298 rk_clrsetreg(&cru->clksel_con[29], in rkclk_init()
313 clk_core_div = APLL_HZ / CLK_CORE_HZ - 1; in rk3328_configure_cpu()
314 aclkm_div = APLL_HZ / ACLKM_CORE_HZ / (clk_core_div + 1) - 1; in rk3328_configure_cpu()
315 pclk_dbg_div = APLL_HZ / PCLK_DBG_HZ / (clk_core_div + 1) - 1; in rk3328_configure_cpu()
317 rk_clrsetreg(&cru->clksel_con[0], in rk3328_configure_cpu()
322 rk_clrsetreg(&cru->clksel_con[1], in rk3328_configure_cpu()
331 u32 div, con; in rk3328_i2c_get_clk() local
335 con = readl(&cru->clksel_con[34]); in rk3328_i2c_get_clk()
336 div = con >> CLK_I2C0_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK; in rk3328_i2c_get_clk()
339 con = readl(&cru->clksel_con[34]); in rk3328_i2c_get_clk()
340 div = con >> CLK_I2C1_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK; in rk3328_i2c_get_clk()
343 con = readl(&cru->clksel_con[35]); in rk3328_i2c_get_clk()
344 div = con >> CLK_I2C2_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK; in rk3328_i2c_get_clk()
347 con = readl(&cru->clksel_con[35]); in rk3328_i2c_get_clk()
348 div = con >> CLK_I2C3_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK; in rk3328_i2c_get_clk()
352 return -EINVAL; in rk3328_i2c_get_clk()
355 return DIV_TO_RATE(GPLL_HZ, div); in rk3328_i2c_get_clk()
363 assert(src_clk_div - 1 < 127); in rk3328_i2c_set_clk()
367 rk_clrsetreg(&cru->clksel_con[34], in rk3328_i2c_set_clk()
370 (src_clk_div - 1) << CLK_I2C0_DIV_CON_SHIFT | in rk3328_i2c_set_clk()
374 rk_clrsetreg(&cru->clksel_con[34], in rk3328_i2c_set_clk()
377 (src_clk_div - 1) << CLK_I2C1_DIV_CON_SHIFT | in rk3328_i2c_set_clk()
381 rk_clrsetreg(&cru->clksel_con[35], in rk3328_i2c_set_clk()
384 (src_clk_div - 1) << CLK_I2C2_DIV_CON_SHIFT | in rk3328_i2c_set_clk()
388 rk_clrsetreg(&cru->clksel_con[35], in rk3328_i2c_set_clk()
391 (src_clk_div - 1) << CLK_I2C3_DIV_CON_SHIFT | in rk3328_i2c_set_clk()
396 return -EINVAL; in rk3328_i2c_set_clk()
413 if (readl(&grf->mac_con[1]) & BIT(10) && in rk3328_gmac2io_set_clk()
414 readl(&grf->soc_con[4]) & BIT(14)) { in rk3328_gmac2io_set_clk()
415 /* An external clock will always generate the right rate... */ in rk3328_gmac2io_set_clk()
418 u32 con = readl(&cru->clksel_con[27]); in rk3328_gmac2io_set_clk()
420 u8 div; in rk3328_gmac2io_set_clk() local
427 div = DIV_ROUND_UP(pll_rate, rate) - 1; in rk3328_gmac2io_set_clk()
428 if (div <= 0x1f) in rk3328_gmac2io_set_clk()
429 rk_clrsetreg(&cru->clksel_con[27], GMAC2IO_CLK_DIV_MASK, in rk3328_gmac2io_set_clk()
430 div << GMAC2IO_CLK_DIV_SHIFT); in rk3328_gmac2io_set_clk()
432 debug("Unsupported div for gmac:%d\n", div); in rk3328_gmac2io_set_clk()
434 return DIV_TO_RATE(pll_rate, div); in rk3328_gmac2io_set_clk()
442 u32 div, con, con_id; in rk3328_mmc_get_clk() local
454 return -EINVAL; in rk3328_mmc_get_clk()
456 con = readl(&cru->clksel_con[con_id]); in rk3328_mmc_get_clk()
457 div = (con & CLK_EMMC_DIV_CON_MASK) >> CLK_EMMC_DIV_CON_SHIFT; in rk3328_mmc_get_clk()
461 return DIV_TO_RATE(OSC_HZ, div) / 2; in rk3328_mmc_get_clk()
463 return DIV_TO_RATE(GPLL_HZ, div) / 2; in rk3328_mmc_get_clk()
482 return -EINVAL; in rk3328_mmc_set_clk()
485 /* mmc clock defaulg div 2 internal, need provide double in cru */ in rk3328_mmc_set_clk()
489 /* use 24MHz source for 400KHz clock */ in rk3328_mmc_set_clk()
491 rk_clrsetreg(&cru->clksel_con[con_id], in rk3328_mmc_set_clk()
494 (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT); in rk3328_mmc_set_clk()
496 rk_clrsetreg(&cru->clksel_con[con_id], in rk3328_mmc_set_clk()
499 (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT); in rk3328_mmc_set_clk()
507 u32 div, con; in rk3328_pwm_get_clk() local
509 con = readl(&cru->clksel_con[24]); in rk3328_pwm_get_clk()
510 div = (con & CLK_PWM_DIV_CON_MASK) >> CLK_PWM_DIV_CON_SHIFT; in rk3328_pwm_get_clk()
512 return DIV_TO_RATE(GPLL_HZ, div); in rk3328_pwm_get_clk()
517 u32 div = GPLL_HZ / hz; in rk3328_pwm_set_clk() local
519 rk_clrsetreg(&cru->clksel_con[24], in rk3328_pwm_set_clk()
522 (div - 1) << CLK_PWM_DIV_CON_SHIFT); in rk3328_pwm_set_clk()
524 return DIV_TO_RATE(GPLL_HZ, div); in rk3328_pwm_set_clk()
529 u32 div, val; in rk3328_saradc_get_clk() local
531 val = readl(&cru->clksel_con[23]); in rk3328_saradc_get_clk()
532 div = bitfield_extract(val, CLK_SARADC_DIV_CON_SHIFT, in rk3328_saradc_get_clk()
535 return DIV_TO_RATE(OSC_HZ, div); in rk3328_saradc_get_clk()
542 src_clk_div = DIV_ROUND_UP(OSC_HZ, hz) - 1; in rk3328_saradc_set_clk()
545 rk_clrsetreg(&cru->clksel_con[23], in rk3328_saradc_set_clk()
554 struct rk3328_clk_priv *priv = dev_get_priv(clk->dev); in rk3328_clk_get_rate()
557 switch (clk->id) { in rk3328_clk_get_rate()
564 rate = rk3328_mmc_get_clk(priv->cru, clk->id); in rk3328_clk_get_rate()
570 rate = rk3328_i2c_get_clk(priv->cru, clk->id); in rk3328_clk_get_rate()
573 rate = rk3328_pwm_get_clk(priv->cru); in rk3328_clk_get_rate()
576 rate = rk3328_saradc_get_clk(priv->cru); in rk3328_clk_get_rate()
579 return -ENOENT; in rk3328_clk_get_rate()
587 struct rk3328_clk_priv *priv = dev_get_priv(clk->dev); in rk3328_clk_set_rate()
590 switch (clk->id) { in rk3328_clk_set_rate()
597 ret = rk3328_mmc_set_clk(priv->cru, clk->id, rate); in rk3328_clk_set_rate()
603 ret = rk3328_i2c_set_clk(priv->cru, clk->id, rate); in rk3328_clk_set_rate()
606 ret = rk3328_gmac2io_set_clk(priv->cru, rate); in rk3328_clk_set_rate()
609 ret = rk3328_pwm_set_clk(priv->cru, rate); in rk3328_clk_set_rate()
612 ret = rk3328_saradc_set_clk(priv->cru, rate); in rk3328_clk_set_rate()
648 return -ENOENT; in rk3328_clk_set_rate()
663 * If the requested parent is in the same clock-controller and the id in rk3328_gmac2io_set_parent()
664 * is SCLK_MAC2IO_SRC ("clk_mac2io_src"), switch to the internal clock. in rk3328_gmac2io_set_parent()
666 if ((parent->dev == clk->dev) && (parent->id == SCLK_MAC2IO_SRC)) { in rk3328_gmac2io_set_parent()
668 rk_clrreg(&grf->mac_con[1], BIT(10)); in rk3328_gmac2io_set_parent()
673 * Otherwise, we need to check the clock-output-names of the in rk3328_gmac2io_set_parent()
676 ret = dev_read_string_index(parent->dev, "clock-output-names", in rk3328_gmac2io_set_parent()
677 parent->id, &clock_output_name); in rk3328_gmac2io_set_parent()
679 return -ENODATA; in rk3328_gmac2io_set_parent()
681 /* If this is "gmac_clkin", switch to the external clock input */ in rk3328_gmac2io_set_parent()
684 rk_setreg(&grf->mac_con[1], BIT(10)); in rk3328_gmac2io_set_parent()
688 return -EINVAL; in rk3328_gmac2io_set_parent()
700 * If the requested parent is in the same clock-controller and the id in rk3328_gmac2io_ext_set_parent()
701 * is SCLK_MAC2IO ("clk_mac2io"), switch to the internal clock. in rk3328_gmac2io_ext_set_parent()
703 if ((parent->dev == clk->dev) && (parent->id == SCLK_MAC2IO)) { in rk3328_gmac2io_ext_set_parent()
705 rk_clrreg(&grf->soc_con[4], BIT(14)); in rk3328_gmac2io_ext_set_parent()
710 * Otherwise, we need to check the clock-output-names of the in rk3328_gmac2io_ext_set_parent()
713 ret = dev_read_string_index(parent->dev, "clock-output-names", in rk3328_gmac2io_ext_set_parent()
714 parent->id, &clock_output_name); in rk3328_gmac2io_ext_set_parent()
716 return -ENODATA; in rk3328_gmac2io_ext_set_parent()
718 /* If this is "gmac_clkin", switch to the external clock input */ in rk3328_gmac2io_ext_set_parent()
721 rk_setreg(&grf->soc_con[4], BIT(14)); in rk3328_gmac2io_ext_set_parent()
725 return -EINVAL; in rk3328_gmac2io_ext_set_parent()
730 switch (clk->id) { in rk3328_clk_set_parent()
744 debug("%s: unsupported clk %ld\n", __func__, clk->id); in rk3328_clk_set_parent()
745 return -ENOENT; in rk3328_clk_set_parent()
758 rkclk_init(priv->cru); in rk3328_clk_probe()
767 priv->cru = dev_read_addr_ptr(dev); in rk3328_clk_ofdata_to_platdata()
785 priv->glb_srst_fst_value = offsetof(struct rk3328_cru, in rk3328_clk_bind()
787 priv->glb_srst_snd_value = offsetof(struct rk3328_cru, in rk3328_clk_bind()
789 sys_child->priv = priv; in rk3328_clk_bind()
803 { .compatible = "rockchip,rk3328-cru" },