summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacky Bai <ping.bai@nxp.com>2019-02-19 19:06:56 +0800
committerJacky Bai <ping.bai@nxp.com>2019-02-20 18:00:15 +0800
commit9a774f3e8bfce2fcd2472b8656f84a452276a7a8 (patch)
tree438a83348e7e32d3b1462edd5433f0fdc8a12e2b
parent35c88640b84656f479810cc51e4ea570303f6c8f (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.c4
-rw-r--r--drivers/clk/imx/clk-intpll.c17
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,