Lines Matching +full:sp7021 +full:- +full:clkc
1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
7 #include <linux/clk-provider.h>
15 #include <dt-bindings/clock/sunplus,sp7021-clkc.h>
173 ret = -EINVAL; in plltv_integer_div()
178 clk->p[SEL_FRA] = 0; in plltv_integer_div()
179 clk->p[DIVR] = r; in plltv_integer_div()
180 clk->p[DIVN] = n; in plltv_integer_div()
181 clk->p[DIVM] = m_table[m]; in plltv_integer_div()
187 __func__, clk_hw_get_name(&clk->hw), freq); in plltv_integer_div()
234 for (ph = ARRAY_SIZE(pt) - 1; ph >= 0; ph--) { in plltv_fractional_div()
257 u32 df1 = f * (mod - nfra) / mod / pp[4]; in plltv_fractional_div()
259 df = df0 - df1; in plltv_fractional_div()
268 df_quotient = freq - df_quotient - 1; in plltv_fractional_div()
269 df_remainder = 1000 - df_remainder; in plltv_fractional_div()
271 df_quotient = df_quotient - freq; in plltv_fractional_div()
278 clk->p[SEL_FRA] = 1; in plltv_fractional_div()
279 clk->p[SDM_MOD] = sdm; in plltv_fractional_div()
280 clk->p[PH_SEL] = ph; in plltv_fractional_div()
281 clk->p[NFRA] = nfra; in plltv_fractional_div()
282 clk->p[DIVR] = r; in plltv_fractional_div()
283 clk->p[DIVM] = m; in plltv_fractional_div()
295 __func__, clk_hw_get_name(&clk->hw), freq); in plltv_fractional_div()
296 return -EINVAL; in plltv_fractional_div()
315 r0 = BIT(clk->bp_bit + 16); in plltv_set_rate()
316 r0 |= HWM_FIELD_PREP(MASK_SEL_FRA, clk->p[SEL_FRA]); in plltv_set_rate()
317 r0 |= HWM_FIELD_PREP(MASK_SDM_MOD, clk->p[SDM_MOD]); in plltv_set_rate()
318 r0 |= HWM_FIELD_PREP(MASK_PH_SEL, clk->p[PH_SEL]); in plltv_set_rate()
319 r0 |= HWM_FIELD_PREP(MASK_NFRA, clk->p[NFRA]); in plltv_set_rate()
321 r1 = HWM_FIELD_PREP(MASK_DIVR, clk->p[DIVR]); in plltv_set_rate()
323 r2 = HWM_FIELD_PREP(MASK_DIVN, clk->p[DIVN] - 1); in plltv_set_rate()
324 r2 |= HWM_FIELD_PREP(MASK_DIVM, clk->p[DIVM] - 1); in plltv_set_rate()
326 spin_lock_irqsave(&clk->lock, flags); in plltv_set_rate()
327 writel(r0, clk->reg); in plltv_set_rate()
328 writel(r1, clk->reg + 4); in plltv_set_rate()
329 writel(r2, clk->reg + 8); in plltv_set_rate()
330 spin_unlock_irqrestore(&clk->lock, flags); in plltv_set_rate()
376 const u32 *pp = pa[clk->p[0]].regs; in plla_set_rate()
380 spin_lock_irqsave(&clk->lock, flags); in plla_set_rate()
381 for (i = 0; i < ARRAY_SIZE(pa->regs); i++) in plla_set_rate()
382 writel(0xffff0000 | pp[i], clk->reg + (i * 4)); in plla_set_rate()
383 spin_unlock_irqrestore(&clk->lock, flags); in plla_set_rate()
392 while (--i) { in plla_round_rate()
396 clk->p[0] = i; in plla_round_rate()
406 u32 max = 1 << clk->div_width; in sp_pll_calc_div()
408 fbdiv = DIV_ROUND_CLOSEST(rate, clk->brate); in sp_pll_calc_div()
423 } else if (clk->div_width == DIV_A) { in sp_pll_round_rate()
425 } else if (clk->div_width == DIV_TV) { in sp_pll_round_rate()
430 ret = sp_pll_calc_div(clk, rate) * clk->brate; in sp_pll_round_rate()
440 u32 reg = readl(clk->reg); in sp_pll_recalc_rate()
443 if (reg & BIT(clk->bp_bit)) { in sp_pll_recalc_rate()
445 } else if (clk->div_width == DIV_A) { in sp_pll_recalc_rate()
446 ret = pa[clk->p[0]].rate; in sp_pll_recalc_rate()
447 } else if (clk->div_width == DIV_TV) { in sp_pll_recalc_rate()
450 r = FIELD_GET(MASK_DIVR, readl(clk->reg + 4)); in sp_pll_recalc_rate()
451 reg2 = readl(clk->reg + 8); in sp_pll_recalc_rate()
464 r1 = ret * (sdm_mod_vals[sdm] - nfra) / sdm_mod_vals[sdm] / pp[4]; in sp_pll_recalc_rate()
465 ret = (r0 - r1) / m; in sp_pll_recalc_rate()
473 u32 fbdiv = ((reg >> clk->div_shift) & ((1 << clk->div_width) - 1)) + 1; in sp_pll_recalc_rate()
475 ret = clk->brate * fbdiv; in sp_pll_recalc_rate()
488 reg = BIT(clk->bp_bit + 16); /* HIWORD_MASK */ in sp_pll_set_rate()
491 reg |= BIT(clk->bp_bit); /* bypass */ in sp_pll_set_rate()
492 } else if (clk->div_width == DIV_A) { in sp_pll_set_rate()
494 } else if (clk->div_width == DIV_TV) { in sp_pll_set_rate()
496 } else if (clk->div_width) { in sp_pll_set_rate()
498 u32 mask = GENMASK(clk->div_shift + clk->div_width - 1, clk->div_shift); in sp_pll_set_rate()
501 reg |= ((fbdiv - 1) << clk->div_shift) & mask; in sp_pll_set_rate()
504 spin_lock_irqsave(&clk->lock, flags); in sp_pll_set_rate()
505 writel(reg, clk->reg); in sp_pll_set_rate()
506 spin_unlock_irqrestore(&clk->lock, flags); in sp_pll_set_rate()
515 writel(BIT(clk->pd_bit + 16) | BIT(clk->pd_bit), clk->reg); in sp_pll_enable()
524 writel(BIT(clk->pd_bit + 16), clk->reg); in sp_pll_disable()
531 return readl(clk->reg) & BIT(clk->pd_bit); in sp_pll_is_enabled()
569 return ERR_PTR(-ENOMEM); in sp_pll_register()
571 pll->hw.init = &initd; in sp_pll_register()
572 pll->reg = reg; in sp_pll_register()
573 pll->pd_bit = pd_bit; in sp_pll_register()
574 pll->bp_bit = bp_bit; in sp_pll_register()
575 pll->brate = brate; in sp_pll_register()
576 pll->div_shift = shift; in sp_pll_register()
577 pll->div_width = width; in sp_pll_register()
578 spin_lock_init(&pll->lock); in sp_pll_register()
580 hw = &pll->hw; in sp_pll_register()
600 struct device *dev = &pdev->dev; in sp7021_clk_probe()
623 return -ENOMEM; in sp7021_clk_probe()
624 clk_data->num = CLK_MAX; in sp7021_clk_probe()
626 hws = clk_data->hws; in sp7021_clk_probe()
641 13, -1, 2500000, 0, 0, 0); in sp7021_clk_probe()
645 12, -1, 25000000, 0, 0, 0); in sp7021_clk_probe()
649 11, -1, 112500000, 0, 0, 0); in sp7021_clk_probe()
665 &to_sp_pll(hws[PLL_TV])->lock); in sp7021_clk_probe()
696 { .compatible = "sunplus,sp7021-clkc" },
704 .name = "sp7021-clk",
712 MODULE_DESCRIPTION("Clock driver for Sunplus SP7021 SoC");