Message ID | 20240507065319.274976-2-xingyu.wu@starfivetech.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | Add notifier for PLL0 clock and set it 1.5GHz on | expand |
Xingyu Wu wrote: > Add notifier function for PLL0 clock. In the function, the cpu_root clock > should be operated by saving its current parent and setting a new safe > parent (osc clock) before setting the PLL0 clock rate. After setting PLL0 > rate, it should be switched back to the original parent clock. > > Fixes: e2c510d6d630 ("riscv: dts: starfive: Add cpu scaling for JH7110 SoC") > Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com> This looks much better, thanks! Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com> > --- > .../clk/starfive/clk-starfive-jh7110-sys.c | 31 ++++++++++++++++++- > drivers/clk/starfive/clk-starfive-jh71x0.h | 2 ++ > 2 files changed, 32 insertions(+), 1 deletion(-) > > diff --git a/drivers/clk/starfive/clk-starfive-jh7110-sys.c b/drivers/clk/starfive/clk-starfive-jh7110-sys.c > index 8f5e5abfa178..dafa3ae71751 100644 > --- a/drivers/clk/starfive/clk-starfive-jh7110-sys.c > +++ b/drivers/clk/starfive/clk-starfive-jh7110-sys.c > @@ -385,6 +385,32 @@ int jh7110_reset_controller_register(struct jh71x0_clk_priv *priv, > } > EXPORT_SYMBOL_GPL(jh7110_reset_controller_register); > > +/* > + * This clock notifier is called when the rate of PLL0 clock is to be changed. > + * The cpu_root clock should save the curent parent clock and swicth its parent > + * clock to osc before PLL0 rate will be changed. Then swicth its parent clock > + * back after the PLL0 rate is completed. > + */ > +static int jh7110_pll0_clk_notifier_cb(struct notifier_block *nb, > + unsigned long action, void *data) > +{ > + struct jh71x0_clk_priv *priv = container_of(nb, struct jh71x0_clk_priv, pll_clk_nb); > + struct clk *cpu_root = priv->reg[JH7110_SYSCLK_CPU_ROOT].hw.clk; > + int ret = 0; > + > + if (action == PRE_RATE_CHANGE) { > + struct clk *osc = clk_get(priv->dev, "osc"); > + > + priv->original_clk = clk_get_parent(cpu_root); > + ret = clk_set_parent(cpu_root, osc); > + clk_put(osc); > + } else if (action == POST_RATE_CHANGE) { > + ret = clk_set_parent(cpu_root, priv->original_clk); > + } > + > + return notifier_from_errno(ret); > +} > + > static int __init jh7110_syscrg_probe(struct platform_device *pdev) > { > struct jh71x0_clk_priv *priv; > @@ -413,7 +439,10 @@ static int __init jh7110_syscrg_probe(struct platform_device *pdev) > if (IS_ERR(priv->pll[0])) > return PTR_ERR(priv->pll[0]); > } else { > - clk_put(pllclk); > + priv->pll_clk_nb.notifier_call = jh7110_pll0_clk_notifier_cb; > + ret = clk_notifier_register(pllclk, &priv->pll_clk_nb); > + if (ret) > + return ret; > priv->pll[0] = NULL; > } > > diff --git a/drivers/clk/starfive/clk-starfive-jh71x0.h b/drivers/clk/starfive/clk-starfive-jh71x0.h > index 23e052fc1549..e3f441393e48 100644 > --- a/drivers/clk/starfive/clk-starfive-jh71x0.h > +++ b/drivers/clk/starfive/clk-starfive-jh71x0.h > @@ -114,6 +114,8 @@ struct jh71x0_clk_priv { > spinlock_t rmw_lock; > struct device *dev; > void __iomem *base; > + struct clk *original_clk; > + struct notifier_block pll_clk_nb; > struct clk_hw *pll[3]; > struct jh71x0_clk reg[]; > }; > -- > 2.25.1 > > > _______________________________________________ > linux-riscv mailing list > linux-riscv@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-riscv
diff --git a/drivers/clk/starfive/clk-starfive-jh7110-sys.c b/drivers/clk/starfive/clk-starfive-jh7110-sys.c index 8f5e5abfa178..dafa3ae71751 100644 --- a/drivers/clk/starfive/clk-starfive-jh7110-sys.c +++ b/drivers/clk/starfive/clk-starfive-jh7110-sys.c @@ -385,6 +385,32 @@ int jh7110_reset_controller_register(struct jh71x0_clk_priv *priv, } EXPORT_SYMBOL_GPL(jh7110_reset_controller_register); +/* + * This clock notifier is called when the rate of PLL0 clock is to be changed. + * The cpu_root clock should save the curent parent clock and swicth its parent + * clock to osc before PLL0 rate will be changed. Then swicth its parent clock + * back after the PLL0 rate is completed. + */ +static int jh7110_pll0_clk_notifier_cb(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct jh71x0_clk_priv *priv = container_of(nb, struct jh71x0_clk_priv, pll_clk_nb); + struct clk *cpu_root = priv->reg[JH7110_SYSCLK_CPU_ROOT].hw.clk; + int ret = 0; + + if (action == PRE_RATE_CHANGE) { + struct clk *osc = clk_get(priv->dev, "osc"); + + priv->original_clk = clk_get_parent(cpu_root); + ret = clk_set_parent(cpu_root, osc); + clk_put(osc); + } else if (action == POST_RATE_CHANGE) { + ret = clk_set_parent(cpu_root, priv->original_clk); + } + + return notifier_from_errno(ret); +} + static int __init jh7110_syscrg_probe(struct platform_device *pdev) { struct jh71x0_clk_priv *priv; @@ -413,7 +439,10 @@ static int __init jh7110_syscrg_probe(struct platform_device *pdev) if (IS_ERR(priv->pll[0])) return PTR_ERR(priv->pll[0]); } else { - clk_put(pllclk); + priv->pll_clk_nb.notifier_call = jh7110_pll0_clk_notifier_cb; + ret = clk_notifier_register(pllclk, &priv->pll_clk_nb); + if (ret) + return ret; priv->pll[0] = NULL; } diff --git a/drivers/clk/starfive/clk-starfive-jh71x0.h b/drivers/clk/starfive/clk-starfive-jh71x0.h index 23e052fc1549..e3f441393e48 100644 --- a/drivers/clk/starfive/clk-starfive-jh71x0.h +++ b/drivers/clk/starfive/clk-starfive-jh71x0.h @@ -114,6 +114,8 @@ struct jh71x0_clk_priv { spinlock_t rmw_lock; struct device *dev; void __iomem *base; + struct clk *original_clk; + struct notifier_block pll_clk_nb; struct clk_hw *pll[3]; struct jh71x0_clk reg[]; };
Add notifier function for PLL0 clock. In the function, the cpu_root clock should be operated by saving its current parent and setting a new safe parent (osc clock) before setting the PLL0 clock rate. After setting PLL0 rate, it should be switched back to the original parent clock. Fixes: e2c510d6d630 ("riscv: dts: starfive: Add cpu scaling for JH7110 SoC") Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com> --- .../clk/starfive/clk-starfive-jh7110-sys.c | 31 ++++++++++++++++++- drivers/clk/starfive/clk-starfive-jh71x0.h | 2 ++ 2 files changed, 32 insertions(+), 1 deletion(-)