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

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.de


Signed-off-by: default avatarAbel Vesa <abel.vesa@nxp.com>
parent 58f4980c
Loading
Loading
Loading
Loading
+26 −33
Original line number Diff line number Diff line
@@ -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,
};