Skip to content
Snippets Groups Projects
Commit 9a774f3e authored by Jacky Bai's avatar Jacky Bai
Browse files

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: default avatarJacky Bai <ping.bai@nxp.com>
Reviewed-by: default avatarAnson Huang <Anson.Huang@nxp.com>
parent 35c88640
No related merge requests found
......@@ -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[] = {
......
......@@ -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,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment