diff options
author | Jacky Bai <ping.bai@nxp.com> | 2019-02-19 19:06:56 +0800 |
---|---|---|
committer | Jacky Bai <ping.bai@nxp.com> | 2019-02-20 18:00:15 +0800 |
commit | 9a774f3e8bfce2fcd2472b8656f84a452276a7a8 (patch) | |
tree | 438a83348e7e32d3b1462edd5433f0fdc8a12e2b | |
parent | 35c88640b84656f479810cc51e4ea570303f6c8f (diff) |
MLK-20947 clk: imx: update the audio pll rate table on imx8mm
Audio PLL is a frac pll, the config for this PLL should follow
below limitation:
Fout = ((m + k / 65536) * FIN) / (p * 2^s),
Fvco = ((m + k / 65536) * FIN) / p
Fref = FIN / p
a). 6MHz <= Fref <= 25MHz;
b). 1 <= p <= 63;
c). 64 <= m <= 1023;
d). 0 <= s <= 6;
e). -32768 <= k <= 32767;
due to the frac part calculation deviation, frac pll 'recalc_rate'
is updated to look up the pll rate from table first.
Signed-off-by: Jacky Bai <ping.bai@nxp.com>
Reviewed-by: Anson Huang <Anson.Huang@nxp.com>
-rw-r--r-- | drivers/clk/imx/clk-imx8mm.c | 4 | ||||
-rw-r--r-- | drivers/clk/imx/clk-intpll.c | 17 |
2 files changed, 18 insertions, 3 deletions
diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c index 3cd9c57ed8b8..5709bfce578c 100644 --- a/drivers/clk/imx/clk-imx8mm.c +++ b/drivers/clk/imx/clk-imx8mm.c @@ -77,8 +77,8 @@ static const struct imx_int_pll_rate_table imx8mm_intpll_tbl[] = { }; static const struct imx_int_pll_rate_table imx8mm_audiopll_tbl[] = { - PLL_1443X_RATE(786432000U, 655, 5, 2, 23593), - PLL_1443X_RATE(722534400U, 301, 5, 1, 3670), + PLL_1443X_RATE(786432000U, 262, 2, 2, 9437), + PLL_1443X_RATE(722534400U, 361, 3, 2, 17511), }; static const struct imx_int_pll_rate_table imx8mm_videopll_tbl[] = { diff --git a/drivers/clk/imx/clk-intpll.c b/drivers/clk/imx/clk-intpll.c index a783a8a67eec..4c8e0685b8ba 100644 --- a/drivers/clk/imx/clk-intpll.c +++ b/drivers/clk/imx/clk-intpll.c @@ -98,9 +98,12 @@ static unsigned long clk_int_pll1443x_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { struct clk_int_pll *pll = to_clk_int_pll(hw); + const struct imx_int_pll_rate_table *rate_table = pll->rate_table; u32 mdiv, pdiv, sdiv, pll_gnrl, pll_div_ctl0, pll_div_ctl1; short int kdiv; u64 fvco = parent_rate; + long rate = 0; + int i; pll_gnrl = readl_relaxed(pll->base); pll_div_ctl0 = readl_relaxed(pll->base + 4); @@ -110,13 +113,25 @@ static unsigned long clk_int_pll1443x_recalc_rate(struct clk_hw *hw, sdiv = (pll_div_ctl0 & SDIV_MASK) >> SDIV_SHIFT; kdiv = pll_div_ctl1 & KDIV_MASK; + /* + * Sometimes, the recalculated rate has deviation due to + * the frac part. So find the accurate pll rate from the table + * first, if no match rate in the table, use the rate calculated + * from the equation below. + */ + for (i = 0; i < pll->rate_count; i++) { + if (rate_table[i].pdiv == pdiv && rate_table[i].mdiv == mdiv && + rate_table[i].sdiv == sdiv && rate_table[i].kdiv == kdiv) + rate = rate_table[i].rate; + } + /* fvco = (m * 65536 + k) * Fin / (p * 65536) */ fvco *= (mdiv * 65536 + kdiv); pdiv *= 65536; do_div(fvco, pdiv << sdiv); - return (unsigned long)fvco; + return rate ? (unsigned long) rate : (unsigned long)fvco; } static inline bool clk_int_pll1416x_mp_change(const struct imx_int_pll_rate_table *rate, |