Commit 53990cf9 authored by Sascha Hauer's avatar Sascha Hauer Committed by Abel Vesa

clk: imx: pll14xx: consolidate rate calculation

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: default avatarSascha Hauer <s.hauer@pengutronix.de>
Reviewed-by: default avatarAbel Vesa <abel.vesa@nxp.com>
Link: https://lore.kernel.org/r/20220304125256.2125023-5-s.hauer@pengutronix.deSigned-off-by: default avatarAbel Vesa <abel.vesa@nxp.com>
parent 58f4980c
...@@ -97,6 +97,20 @@ static const struct imx_pll14xx_rate_table *imx_get_pll_settings( ...@@ -97,6 +97,20 @@ static const struct imx_pll14xx_rate_table *imx_get_pll_settings(
return NULL; 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, static long clk_pll14xx_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *prate) unsigned long *prate)
{ {
...@@ -113,46 +127,25 @@ static long clk_pll14xx_round_rate(struct clk_hw *hw, unsigned long rate, ...@@ -113,46 +127,25 @@ static long clk_pll14xx_round_rate(struct clk_hw *hw, unsigned long rate,
return rate_table[i - 1].rate; return rate_table[i - 1].rate;
} }
static unsigned long clk_pll1416x_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;
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,
unsigned long parent_rate) unsigned long parent_rate)
{ {
struct clk_pll14xx *pll = to_clk_pll14xx(hw); struct clk_pll14xx *pll = to_clk_pll14xx(hw);
u32 mdiv, pdiv, sdiv, pll_div_ctl0, pll_div_ctl1; u32 mdiv, pdiv, sdiv, kdiv, pll_div_ctl0, pll_div_ctl1;
short int kdiv;
u64 fvco = parent_rate;
pll_div_ctl0 = readl_relaxed(pll->base + DIV_CTL0); 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); mdiv = FIELD_GET(MDIV_MASK, pll_div_ctl0);
pdiv = FIELD_GET(PDIV_MASK, pll_div_ctl0); pdiv = FIELD_GET(PDIV_MASK, pll_div_ctl0);
sdiv = FIELD_GET(SDIV_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) */ if (pll->type == PLL_1443X) {
fvco *= (mdiv * 65536 + kdiv); pll_div_ctl1 = readl_relaxed(pll->base + DIV_CTL1);
pdiv *= 65536; kdiv = FIELD_GET(KDIV_MASK, pll_div_ctl1);
} else {
do_div(fvco, pdiv << sdiv); 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, 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 = { ...@@ -363,20 +356,20 @@ static const struct clk_ops clk_pll1416x_ops = {
.prepare = clk_pll14xx_prepare, .prepare = clk_pll14xx_prepare,
.unprepare = clk_pll14xx_unprepare, .unprepare = clk_pll14xx_unprepare,
.is_prepared = clk_pll14xx_is_prepared, .is_prepared = clk_pll14xx_is_prepared,
.recalc_rate = clk_pll1416x_recalc_rate, .recalc_rate = clk_pll14xx_recalc_rate,
.round_rate = clk_pll14xx_round_rate, .round_rate = clk_pll14xx_round_rate,
.set_rate = clk_pll1416x_set_rate, .set_rate = clk_pll1416x_set_rate,
}; };
static const struct clk_ops clk_pll1416x_min_ops = { 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 = { static const struct clk_ops clk_pll1443x_ops = {
.prepare = clk_pll14xx_prepare, .prepare = clk_pll14xx_prepare,
.unprepare = clk_pll14xx_unprepare, .unprepare = clk_pll14xx_unprepare,
.is_prepared = clk_pll14xx_is_prepared, .is_prepared = clk_pll14xx_is_prepared,
.recalc_rate = clk_pll1443x_recalc_rate, .recalc_rate = clk_pll14xx_recalc_rate,
.round_rate = clk_pll14xx_round_rate, .round_rate = clk_pll14xx_round_rate,
.set_rate = clk_pll1443x_set_rate, .set_rate = clk_pll1443x_set_rate,
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment