On Thu, 7 Sept 2023 at 08:22, Varadarajan Narayanan <quic_varada@xxxxxxxxxxx> wrote: > > Stromer plus APSS PLL does not support dynamic frequency scaling. > To switch between frequencies, we have to shut down the PLL, > configure the L and ALPHA values and turn on again. So introduce the > separate set of ops for Stromer Plus PLL. > > Signed-off-by: Kathiravan T <quic_kathirav@xxxxxxxxxxx> > Signed-off-by: Varadarajan Narayanan <quic_varada@xxxxxxxxxxx> > --- > drivers/clk/qcom/clk-alpha-pll.c | 68 ++++++++++++++++++++++++++++++++++++++++ > drivers/clk/qcom/clk-alpha-pll.h | 1 + > 2 files changed, 69 insertions(+) > > diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c > index e4ef645..2ef81f7 100644 > --- a/drivers/clk/qcom/clk-alpha-pll.c > +++ b/drivers/clk/qcom/clk-alpha-pll.c > @@ -2479,3 +2479,71 @@ const struct clk_ops clk_alpha_pll_stromer_ops = { > .set_rate = clk_alpha_pll_stromer_set_rate, > }; > EXPORT_SYMBOL_GPL(clk_alpha_pll_stromer_ops); > + > +static int clk_alpha_pll_stromer_plus_determine_rate(struct clk_hw *hw, > + struct clk_rate_request *req) > +{ > + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); > + u32 l, alpha_width = pll_alpha_width(pll); > + u64 a; > + > + req->rate = alpha_pll_round_rate(req->rate, req->best_parent_rate, &l, > + &a, alpha_width); > + return 0; > +} What is the plL_alpha_width on stromer_plus? Does clk_alpha_pll_stromer_determine_rate() work for you? > + > +static int clk_alpha_pll_stromer_plus_set_rate(struct clk_hw *hw, > + unsigned long rate, > + unsigned long prate) > +{ > + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); > + u32 l, alpha_width = pll_alpha_width(pll); > + int ret; > + u64 a; > + > + rate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width); > + > + regmap_write(pll->clkr.regmap, PLL_MODE(pll), 0); > + > + /* Delay of 2 output clock ticks required until output is disabled */ > + udelay(1); > + > + regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l); > + > + if (alpha_width > ALPHA_BITWIDTH) > + a <<= alpha_width - ALPHA_BITWIDTH; > + > + regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), a); > + regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL_U(pll), > + a >> ALPHA_BITWIDTH); > + > + regmap_write(pll->clkr.regmap, PLL_MODE(pll), PLL_BYPASSNL); > + > + /* Wait five micro seconds or more */ > + udelay(5); > + regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll), PLL_RESET_N, > + PLL_RESET_N); > + > + /* The lock time should be less than 50 micro seconds worst case */ > + udelay(50); > + > + ret = wait_for_pll_enable_lock(pll); > + if (ret) { > + pr_err("alpha pll running in 800 MHz with source GPLL0\n"); > + return ret; > + } > + regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll), PLL_OUTCTRL, > + PLL_OUTCTRL); > + > + return 0; > +} > + > +const struct clk_ops clk_alpha_pll_stromer_plus_ops = { > + .enable = clk_alpha_pll_enable, > + .disable = clk_alpha_pll_disable, > + .is_enabled = clk_alpha_pll_is_enabled, > + .recalc_rate = clk_alpha_pll_recalc_rate, > + .determine_rate = clk_alpha_pll_stromer_plus_determine_rate, > + .set_rate = clk_alpha_pll_stromer_plus_set_rate, > +}; > +EXPORT_SYMBOL_GPL(clk_alpha_pll_stromer_plus_ops); > diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h > index e4bd863..903fbab 100644 > --- a/drivers/clk/qcom/clk-alpha-pll.h > +++ b/drivers/clk/qcom/clk-alpha-pll.h > @@ -152,6 +152,7 @@ extern const struct clk_ops clk_alpha_pll_postdiv_ops; > extern const struct clk_ops clk_alpha_pll_huayra_ops; > extern const struct clk_ops clk_alpha_pll_postdiv_ro_ops; > extern const struct clk_ops clk_alpha_pll_stromer_ops; > +extern const struct clk_ops clk_alpha_pll_stromer_plus_ops; > > extern const struct clk_ops clk_alpha_pll_fabia_ops; > extern const struct clk_ops clk_alpha_pll_fixed_fabia_ops; > -- > 2.7.4 > -- With best wishes Dmitry