Commit 094234fc authored by Leonard Crestez's avatar Leonard Crestez Committed by Shawn Guo
Browse files

clk: imx: pll14xx: Fix quick switch of S/K parameter



The PLL14xx on imx8m can change the S and K parameter without requiring
a reset and relock of the whole PLL.

Fix clk_pll144xx_mp_change register reading and use it for pll1443 as
well since no reset+relock is required on K changes either.

Signed-off-by: default avatarLeonard Crestez <leonard.crestez@nxp.com>
Fixes: 8646d4dc ("clk: imx: Add PLLs driver for imx8mm soc")
Signed-off-by: default avatarShawn Guo <shawnguo@kernel.org>
parent 54ecb8f7
Loading
Loading
Loading
Loading
+8 −32
Original line number Diff line number Diff line
@@ -112,43 +112,17 @@ static unsigned long clk_pll1443x_recalc_rate(struct clk_hw *hw,
	return fvco;
}

static inline bool clk_pll1416x_mp_change(const struct imx_pll14xx_rate_table *rate,
static inline bool clk_pll14xx_mp_change(const struct imx_pll14xx_rate_table *rate,
					  u32 pll_div)
{
	u32 old_mdiv, old_pdiv;

	old_mdiv = (pll_div >> MDIV_SHIFT) & MDIV_MASK;
	old_pdiv = (pll_div >> PDIV_SHIFT) & PDIV_MASK;
	old_mdiv = (pll_div & MDIV_MASK) >> MDIV_SHIFT;
	old_pdiv = (pll_div & PDIV_MASK) >> PDIV_SHIFT;

	return rate->mdiv != old_mdiv || rate->pdiv != old_pdiv;
}

static inline bool clk_pll1443x_mpk_change(const struct imx_pll14xx_rate_table *rate,
					  u32 pll_div_ctl0, u32 pll_div_ctl1)
{
	u32 old_mdiv, old_pdiv, old_kdiv;

	old_mdiv = (pll_div_ctl0 >> MDIV_SHIFT) & MDIV_MASK;
	old_pdiv = (pll_div_ctl0 >> PDIV_SHIFT) & PDIV_MASK;
	old_kdiv = (pll_div_ctl1 >> KDIV_SHIFT) & KDIV_MASK;

	return rate->mdiv != old_mdiv || rate->pdiv != old_pdiv ||
		rate->kdiv != old_kdiv;
}

static inline bool clk_pll1443x_mp_change(const struct imx_pll14xx_rate_table *rate,
					  u32 pll_div_ctl0, u32 pll_div_ctl1)
{
	u32 old_mdiv, old_pdiv, old_kdiv;

	old_mdiv = (pll_div_ctl0 >> MDIV_SHIFT) & MDIV_MASK;
	old_pdiv = (pll_div_ctl0 >> PDIV_SHIFT) & PDIV_MASK;
	old_kdiv = (pll_div_ctl1 >> KDIV_SHIFT) & KDIV_MASK;

	return rate->mdiv != old_mdiv || rate->pdiv != old_pdiv ||
		rate->kdiv != old_kdiv;
}

static int clk_pll14xx_wait_lock(struct clk_pll14xx *pll)
{
	u32 val;
@@ -174,7 +148,7 @@ static int clk_pll1416x_set_rate(struct clk_hw *hw, unsigned long drate,

	tmp = readl_relaxed(pll->base + 4);

	if (!clk_pll1416x_mp_change(rate, tmp)) {
	if (!clk_pll14xx_mp_change(rate, tmp)) {
		tmp &= ~(SDIV_MASK) << SDIV_SHIFT;
		tmp |= rate->sdiv << SDIV_SHIFT;
		writel_relaxed(tmp, pll->base + 4);
@@ -239,13 +213,15 @@ static int clk_pll1443x_set_rate(struct clk_hw *hw, unsigned long drate,
	}

	tmp = readl_relaxed(pll->base + 4);
	div_val = readl_relaxed(pll->base + 8);

	if (!clk_pll1443x_mpk_change(rate, tmp, div_val)) {
	if (!clk_pll14xx_mp_change(rate, tmp)) {
		tmp &= ~(SDIV_MASK) << SDIV_SHIFT;
		tmp |= rate->sdiv << SDIV_SHIFT;
		writel_relaxed(tmp, pll->base + 4);

		tmp = rate->kdiv << KDIV_SHIFT;
		writel_relaxed(tmp, pll->base + 8);

		return 0;
	}