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: Sascha Hauer <s.hauer@pengutronix.de> Reviewed-by: Abel Vesa <abel.vesa@nxp.com> Link: https://lore.kernel.org/r/20220304125256.2125023-5-s.hauer@pengutronix.de Signed-off-by: Abel Vesa <abel.vesa@nxp.com>
This commit is contained in:
parent
58f4980ccb
commit
53990cf9d5
1 changed files with 26 additions and 33 deletions
|
@ -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,
|
||||||
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)
|
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;
|
u32 mdiv, pdiv, sdiv, kdiv, pll_div_ctl0, pll_div_ctl1;
|
||||||
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)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
|
|
||||||
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 {
|
||||||
|
kdiv = 0;
|
||||||
|
}
|
||||||
|
|
||||||
do_div(fvco, pdiv << sdiv);
|
return pll14xx_calc_rate(pll, mdiv, pdiv, sdiv, kdiv, parent_rate);
|
||||||
|
|
||||||
return fvco;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 = {
|
||||||
.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,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue