diff options
author | Anson Huang <b20788@freescale.com> | 2015-04-02 10:34:27 +0800 |
---|---|---|
committer | guoyin.chen <guoyin.chen@freescale.com> | 2015-05-08 17:24:54 +0800 |
commit | bf876f399bb9fc06d1bdc9a5d865e4967e25b39b (patch) | |
tree | 07fa1b782111634e76d391df77a39e80bf6c13ad | |
parent | 606e35231eb48268ad1a0561e2598193b44a003b (diff) |
MLK-10547-1 ARM: imx: correct AV PLL rate formula
The audio/video PLL's rate caculation is as below in RM:
Fref * (DIV_SELECT + NUM / DENOM), in origin clk-pllv3's
code, below code is used:
(parent_rate * div) + ((parent_rate / mfd) * mfn
as it does NOT consider the float data using div, so below
formula should be used as a decent method:
(parent_rate * div) + ((parent_rate * mfn) / mfd)
and we also need to consider parent_rate * mfd may overflow
a 32 bit value, 64 bit value should be used.
After updating this formula, the dram PLL's rate is
1066MHz, which is correct, while the old formula gets
1056MHz.
Signed-off-by: Anson Huang <b20788@freescale.com>
-rw-r--r-- | arch/arm/mach-imx/clk-pllv3.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/arch/arm/mach-imx/clk-pllv3.c b/arch/arm/mach-imx/clk-pllv3.c index f6d43a854604..45d728369907 100644 --- a/arch/arm/mach-imx/clk-pllv3.c +++ b/arch/arm/mach-imx/clk-pllv3.c @@ -252,8 +252,12 @@ static unsigned long clk_pllv3_av_recalc_rate(struct clk_hw *hw, u32 mfn = readl_relaxed(pll->base + pll->num_offset); u32 mfd = readl_relaxed(pll->base + pll->denom_offset); u32 div = readl_relaxed(pll->base) & pll->div_mask; + u64 temp64 = (u64)parent_rate; - return (parent_rate * div) + ((parent_rate / mfd) * mfn); + temp64 *= mfn; + do_div(temp64, mfd); + + return (parent_rate * div) + (u32)temp64; } static long clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long rate, |