Skip to contentSkip to conversation

ARM: imx: correct Audio/Video PLL rate calculation formula

PATCH Superseded Anson Huang 2 participants 3 messages Apr 23, 2015 – Apr 29, 2015 1 message not in the archive

Subsystems (3)

v1 of 5 Superseded Latest is v5 →

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 ARM: imx: correct Audio/Video PLL rate calculation formula

The audio/video PLL's rate calculation formula is as below in RM:

Fref * (DIV_SELECT + NUM / DENOM),

in original 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 calculation 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 exceed a 32 bit value, 64 bit value should be used.

---
 arch/arm/mach-imx/clk-pllv3.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
arch/arm/mach-imx/clk-pllv3.c +5 -1
index 641ebc5..f83cf0d 100644
@@ -203,8 +203,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 = parent_rate;
 
-	return (parent_rate * div) + ((parent_rate / mfd) * mfn);
+	temp64 *= mfn;
+	do_div(temp64, mfd);
+
+	return (parent_rate * div) + temp64;
 }
 
 static long clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long rate,
Signature · 1 line
1.9.1
#1 lore raw

PATCH 1/1 ARM: imx: correct Audio/Video PLL rate calculation formula

Quoted 8 lines · Anson Huang

The audio/video PLL's rate calculation formula is as below in RM:

Fref * (DIV_SELECT + NUM / DENOM),

in original clk-pllv3's code, below code is used:

(parent_rate * div) + ((parent_rate / mfd) * mfn

Quoted 7 lines

as it does NOT consider the float data using div, so below calculation 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 exceed a 32 bit value, 64 bit value should be used.

Can you provide some real world data (PLL output frequency) to demonstrate the difference between old and new formula?

Shawn

Quoted 27 lines
---
 arch/arm/mach-imx/clk-pllv3.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
arch/arm/mach-imx/clk-pllv3.c +5 -1
index 641ebc5..f83cf0d 100644
@@ -203,8 +203,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 = parent_rate;
 
-	return (parent_rate * div) + ((parent_rate / mfd) * mfn);
+	temp64 *= mfn;
+	do_div(temp64, mfd);
+
+	return (parent_rate * div) + temp64;
 }
 
 static long clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long rate,
Signature · 1 line
1.9.1

A message that is not in the archive (sent off-list or not yet received): [email protected]

#3 lore raw

PATCH 1/1 ARM: imx: correct Audio/Video PLL rate calculation formula

Hi Anson,

Quoted 37 lines · Anson Huang
Quoted 14 lines · Shawn Guo
Quoted 13 lines · Anson Huang

The audio/video PLL's rate calculation formula is as below in RM:

Fref * (DIV_SELECT + NUM / DENOM),

in original 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 calculation formula should be used as a decent method:

(parent_rate * div) + ((parent_rate * mfn) / mfd)

Quoted 8 lines
Quoted 2 lines

and we also need to consider parent_rate * mfd may exceed a 32 bit value, 64 bit value should be used.

Can you provide some real world data (PLL output frequency) to demonstrate the difference between old and new formula?

Shawn

I happen to meet this issue on i.MX7D, on i.MX7D, DRAM PLL is a Audio/Video type PLL, the target freq is 1066MHz, the register settings are as below:

PLL_DDRn: 8060202C -> div = 0x2C
DDR_NUM: 06AAAC4D -> mfn = 0x6AAAC4D
DDR_DENOM: 100003EC -> mfd = 0x100003EC

parent_rate = 24MHz.

with old formula, the (parent_rate / mfd) * mfn = 0 with new formula, the (parent_rate * mfn) / mfd = 10

Quoted 7 lines

so old formula gets PLL_DDR = 1056MHz, new formuls gets PLL_DDR = 1066MHz.

For other Audio/Video PLL, the result is also different, but the difference is less then 1MHz.

That is why I do this patch.

Okay. Can you please add these data into commit log and resend the patch? Also, all i.MX clock drivers are being moved into drivers/clk/imx/, so please rebase your patch on my imx/clk-move branch.

Shawn