Message ID | 20220225082937.2746176-5-s.hauer@pengutronix.de (mailing list archive) |
---|---|
State | Superseded, archived |
Headers | show |
Series | clk: i.MX: PLL14xx: Support dynamic rates | expand |
On 22-02-25 09:29:33, Sascha Hauer wrote: > The PLL driver has support for two different PLLs: The pll1416x and > the pll1443x. The latter has support for an additional kdiv value. > recalc_rate can be the same calculation when kdiv is assumed to be zero > for the PLL which doesn't support that value. > > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> Reviewed-by: Abel Vesa <abel.vesa@nxp.com> > --- > drivers/clk/imx/clk-pll14xx.c | 59 +++++++++++++++-------------------- > 1 file changed, 26 insertions(+), 33 deletions(-) > > diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c > index fabb380b87305..ebd5d888fea6d 100644 > --- a/drivers/clk/imx/clk-pll14xx.c > +++ b/drivers/clk/imx/clk-pll14xx.c > @@ -97,6 +97,20 @@ static const struct imx_pll14xx_rate_table *imx_get_pll_settings( > return NULL; > } > > +static long pll14xx_calc_rate(struct clk_pll14xx *pll, int mdiv, int pdiv, > + int sdiv, int kdiv, unsigned long prate) > +{ > + u64 fvco = prate; > + > + /* fvco = (m * 65536 + k) * Fin / (p * 65536) */ > + fvco *= (mdiv * 65536 + kdiv); > + pdiv *= 65536; > + > + do_div(fvco, pdiv << sdiv); > + > + return fvco; > +} > + > static long clk_pll14xx_round_rate(struct clk_hw *hw, unsigned long rate, > unsigned long *prate) > { > @@ -113,46 +127,25 @@ static long clk_pll14xx_round_rate(struct clk_hw *hw, unsigned long rate, > return rate_table[i - 1].rate; > } > > -static unsigned long clk_pll1416x_recalc_rate(struct clk_hw *hw, > - unsigned long parent_rate) > -{ > - struct clk_pll14xx *pll = to_clk_pll14xx(hw); > - u32 mdiv, pdiv, sdiv, pll_div; > - u64 fvco = parent_rate; > - > - pll_div = readl_relaxed(pll->base + DIV_CTL0); > - mdiv = FIELD_GET(MDIV_MASK, pll_div); > - pdiv = FIELD_GET(PDIV_MASK, pll_div); > - sdiv = FIELD_GET(SDIV_MASK, pll_div); > - > - fvco *= mdiv; > - do_div(fvco, pdiv << sdiv); > - > - return fvco; > -} > - > -static unsigned long clk_pll1443x_recalc_rate(struct clk_hw *hw, > +static unsigned long clk_pll14xx_recalc_rate(struct clk_hw *hw, > unsigned long parent_rate) > { > struct clk_pll14xx *pll = to_clk_pll14xx(hw); > - u32 mdiv, pdiv, sdiv, pll_div_ctl0, pll_div_ctl1; > - short int kdiv; > - u64 fvco = parent_rate; > + u32 mdiv, pdiv, sdiv, kdiv, pll_div_ctl0, pll_div_ctl1; > > pll_div_ctl0 = readl_relaxed(pll->base + DIV_CTL0); > - pll_div_ctl1 = readl_relaxed(pll->base + DIV_CTL1); > mdiv = FIELD_GET(MDIV_MASK, pll_div_ctl0); > pdiv = FIELD_GET(PDIV_MASK, pll_div_ctl0); > sdiv = FIELD_GET(SDIV_MASK, pll_div_ctl0); > - kdiv = FIELD_GET(KDIV_MASK, pll_div_ctl1); > > - /* fvco = (m * 65536 + k) * Fin / (p * 65536) */ > - fvco *= (mdiv * 65536 + kdiv); > - pdiv *= 65536; > - > - do_div(fvco, pdiv << sdiv); > + if (pll->type == PLL_1443X) { > + pll_div_ctl1 = readl_relaxed(pll->base + DIV_CTL1); > + kdiv = FIELD_GET(KDIV_MASK, pll_div_ctl1); > + } else { > + kdiv = 0; > + } > > - return fvco; > + return pll14xx_calc_rate(pll, mdiv, pdiv, sdiv, kdiv, parent_rate); > } > > static inline bool clk_pll14xx_mp_change(const struct imx_pll14xx_rate_table *rate, > @@ -363,20 +356,20 @@ static const struct clk_ops clk_pll1416x_ops = { > .prepare = clk_pll14xx_prepare, > .unprepare = clk_pll14xx_unprepare, > .is_prepared = clk_pll14xx_is_prepared, > - .recalc_rate = clk_pll1416x_recalc_rate, > + .recalc_rate = clk_pll14xx_recalc_rate, > .round_rate = clk_pll14xx_round_rate, > .set_rate = clk_pll1416x_set_rate, > }; > > static const struct clk_ops clk_pll1416x_min_ops = { > - .recalc_rate = clk_pll1416x_recalc_rate, > + .recalc_rate = clk_pll14xx_recalc_rate, > }; > > static const struct clk_ops clk_pll1443x_ops = { > .prepare = clk_pll14xx_prepare, > .unprepare = clk_pll14xx_unprepare, > .is_prepared = clk_pll14xx_is_prepared, > - .recalc_rate = clk_pll1443x_recalc_rate, > + .recalc_rate = clk_pll14xx_recalc_rate, > .round_rate = clk_pll14xx_round_rate, > .set_rate = clk_pll1443x_set_rate, > }; > -- > 2.30.2 >
diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c index fabb380b87305..ebd5d888fea6d 100644 --- a/drivers/clk/imx/clk-pll14xx.c +++ b/drivers/clk/imx/clk-pll14xx.c @@ -97,6 +97,20 @@ static const struct imx_pll14xx_rate_table *imx_get_pll_settings( return NULL; } +static long pll14xx_calc_rate(struct clk_pll14xx *pll, int mdiv, int pdiv, + int sdiv, int kdiv, unsigned long prate) +{ + u64 fvco = prate; + + /* fvco = (m * 65536 + k) * Fin / (p * 65536) */ + fvco *= (mdiv * 65536 + kdiv); + pdiv *= 65536; + + do_div(fvco, pdiv << sdiv); + + return fvco; +} + static long clk_pll14xx_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *prate) { @@ -113,46 +127,25 @@ static long clk_pll14xx_round_rate(struct clk_hw *hw, unsigned long rate, return rate_table[i - 1].rate; } -static unsigned long clk_pll1416x_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct clk_pll14xx *pll = to_clk_pll14xx(hw); - u32 mdiv, pdiv, sdiv, pll_div; - u64 fvco = parent_rate; - - pll_div = readl_relaxed(pll->base + DIV_CTL0); - mdiv = FIELD_GET(MDIV_MASK, pll_div); - pdiv = FIELD_GET(PDIV_MASK, pll_div); - sdiv = FIELD_GET(SDIV_MASK, pll_div); - - fvco *= mdiv; - do_div(fvco, pdiv << sdiv); - - return fvco; -} - -static unsigned long clk_pll1443x_recalc_rate(struct clk_hw *hw, +static unsigned long clk_pll14xx_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { struct clk_pll14xx *pll = to_clk_pll14xx(hw); - u32 mdiv, pdiv, sdiv, pll_div_ctl0, pll_div_ctl1; - short int kdiv; - u64 fvco = parent_rate; + u32 mdiv, pdiv, sdiv, kdiv, pll_div_ctl0, pll_div_ctl1; pll_div_ctl0 = readl_relaxed(pll->base + DIV_CTL0); - pll_div_ctl1 = readl_relaxed(pll->base + DIV_CTL1); mdiv = FIELD_GET(MDIV_MASK, pll_div_ctl0); pdiv = FIELD_GET(PDIV_MASK, pll_div_ctl0); sdiv = FIELD_GET(SDIV_MASK, pll_div_ctl0); - kdiv = FIELD_GET(KDIV_MASK, pll_div_ctl1); - /* fvco = (m * 65536 + k) * Fin / (p * 65536) */ - fvco *= (mdiv * 65536 + kdiv); - pdiv *= 65536; - - do_div(fvco, pdiv << sdiv); + if (pll->type == PLL_1443X) { + pll_div_ctl1 = readl_relaxed(pll->base + DIV_CTL1); + kdiv = FIELD_GET(KDIV_MASK, pll_div_ctl1); + } else { + kdiv = 0; + } - return fvco; + return pll14xx_calc_rate(pll, mdiv, pdiv, sdiv, kdiv, parent_rate); } static inline bool clk_pll14xx_mp_change(const struct imx_pll14xx_rate_table *rate, @@ -363,20 +356,20 @@ static const struct clk_ops clk_pll1416x_ops = { .prepare = clk_pll14xx_prepare, .unprepare = clk_pll14xx_unprepare, .is_prepared = clk_pll14xx_is_prepared, - .recalc_rate = clk_pll1416x_recalc_rate, + .recalc_rate = clk_pll14xx_recalc_rate, .round_rate = clk_pll14xx_round_rate, .set_rate = clk_pll1416x_set_rate, }; static const struct clk_ops clk_pll1416x_min_ops = { - .recalc_rate = clk_pll1416x_recalc_rate, + .recalc_rate = clk_pll14xx_recalc_rate, }; static const struct clk_ops clk_pll1443x_ops = { .prepare = clk_pll14xx_prepare, .unprepare = clk_pll14xx_unprepare, .is_prepared = clk_pll14xx_is_prepared, - .recalc_rate = clk_pll1443x_recalc_rate, + .recalc_rate = clk_pll14xx_recalc_rate, .round_rate = clk_pll14xx_round_rate, .set_rate = clk_pll1443x_set_rate, };
The PLL driver has support for two different PLLs: The pll1416x and the pll1443x. The latter has support for an additional kdiv value. recalc_rate can be the same calculation when kdiv is assumed to be zero for the PLL which doesn't support that value. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> --- drivers/clk/imx/clk-pll14xx.c | 59 +++++++++++++++-------------------- 1 file changed, 26 insertions(+), 33 deletions(-)