On 6/12/25 11:55 AM, Taniya Das wrote: > The alpha PLLs which slew to a new frequency at runtime would require > the PLL to calibrate at the mid point of the VCO. Add the new PLL ops > which can support the slewing of the PLL to a new frequency. > > Reviewed-by: Imran Shaik <quic_imrashai@xxxxxxxxxxx> > Signed-off-by: Taniya Das <quic_tdas@xxxxxxxxxxx> > --- > drivers/clk/qcom/clk-alpha-pll.c | 170 +++++++++++++++++++++++++++++++++++++++ > drivers/clk/qcom/clk-alpha-pll.h | 1 + > 2 files changed, 171 insertions(+) > > diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c > index cec0afea8e446010f0d4140d4ef63121706dde47..5e4a755b849970281e7742ef83219b7eeaa406c3 100644 > --- a/drivers/clk/qcom/clk-alpha-pll.c > +++ b/drivers/clk/qcom/clk-alpha-pll.c > @@ -2960,3 +2960,173 @@ const struct clk_ops clk_alpha_pll_regera_ops = { > .set_rate = clk_zonda_pll_set_rate, > }; > EXPORT_SYMBOL_GPL(clk_alpha_pll_regera_ops); > + > +static int clk_alpha_pll_slew_update(struct clk_alpha_pll *pll) > +{ > + int ret; > + u32 val; > + > + regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll), PLL_UPDATE, PLL_UPDATE); There's an ever sweeter sugar-syntax for this case - regmap_set_bits() > + regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val); > + > + ret = wait_for_pll_update(pll); > + if (ret) > + return ret; > + /* > + * Hardware programming mandates a wait of at least 570ns before polling the LOCK > + * detect bit. Have a delay of 1us just to be safe. > + */ > + mb(); Since you read the value of PLL_MODE back, the barrier is unnecessary [...] > + > + regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l); > + regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), lower_32_bits(a)); > + regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL_U(pll), upper_32_bits(a)); > + > + /* Ensure that the write above goes before slewing the PLL */ > + mb(); Here however, the write may not arrive at the clock controller before you proceed to slew_update() > + > + if (clk_hw_is_enabled(hw)) > + return clk_alpha_pll_slew_update(pll); > + > + return 0; > +} > + > +/* > + * Slewing plls should be bought up at frequency which is in the middle of the > + * desired VCO range. So after bringing up the pll at calibration freq, set it > + * back to desired frequency(that was set by previous clk_set_rate). > + */ > +static int clk_alpha_pll_calibrate(struct clk_hw *hw) > +{ > + unsigned long calibration_freq, freq_hz; > + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); > + struct clk_hw *parent; > + const struct pll_vco *vco; > + u32 l; > + int rc; > + u64 a; A reverse-Christmas-tree sorting would be nice Konrad