* [PATCH 1/2] ARM: imx: fix integer overflow in AV PLL round rate @ 2016-10-06 11:12 Emil Lundmark 2016-10-06 11:12 ` [PATCH 2/2] ARM: imx: improve precision of AV PLL to 1 Hz Emil Lundmark 2016-10-07 14:12 ` [PATCH 1/2] ARM: imx: fix integer overflow in AV PLL round rate Emil Lundmark 0 siblings, 2 replies; 8+ messages in thread From: Emil Lundmark @ 2016-10-06 11:12 UTC (permalink / raw) To: linux-arm-kernel Since parent_rate * mfn may overflow 32 bits, the result should be stored using 64 bits. This issue was previously addressed in ba7f4f557eb6, but this particular case was not fixed. Signed-off-by: Emil Lundmark <emil@limesaudio.com> --- drivers/clk/imx/clk-pllv3.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/clk/imx/clk-pllv3.c b/drivers/clk/imx/clk-pllv3.c index 19f9b62..bc7f163 100644 --- a/drivers/clk/imx/clk-pllv3.c +++ b/drivers/clk/imx/clk-pllv3.c @@ -247,7 +247,11 @@ static long clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long rate, do_div(temp64, parent_rate); mfn = temp64; - return parent_rate * div + parent_rate * mfn / mfd; + temp64 = (u64)parent_rate; + temp64 *= mfn; + do_div(temp64, mfd); + + return parent_rate * div + (u32)temp64; } static int clk_pllv3_av_set_rate(struct clk_hw *hw, unsigned long rate, -- 2.7.4 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/2] ARM: imx: improve precision of AV PLL to 1 Hz 2016-10-06 11:12 [PATCH 1/2] ARM: imx: fix integer overflow in AV PLL round rate Emil Lundmark @ 2016-10-06 11:12 ` Emil Lundmark 2016-10-07 7:48 ` Lothar Waßmann 2016-10-07 14:12 ` [PATCH 1/2] ARM: imx: fix integer overflow in AV PLL round rate Emil Lundmark 1 sibling, 1 reply; 8+ messages in thread From: Emil Lundmark @ 2016-10-06 11:12 UTC (permalink / raw) To: linux-arm-kernel The audio and video PLLs are designed to have a precision of 1 Hz if some conditions are met. The current implementation only allows a precision that depends on the rate of the parent clock. E.g., if the parent clock is 24 MHz, the precision will be 24 Hz; or more generally the precision will be p / 10^6 Hz where p is the parent clock rate. This comes down to how the register values for the PLL's fractional loop divider is chosen. The clock rate calculation for the PLL is PLL output frequency = Fref * (DIV_SELECT + NUM / DENOM) or with a shorter notation r = p * (d + a / b) In addition to all variables being integers, we also have the following conditions: 27 <= d <= 54 0 <= a <= 2^30-1 0 < b <= 2^30-1 a < b Here, d, a and b are register values for the fractional loop divider. We want to chose d, a and b such that f(p, r) = p, i.e. f is our round_rate function. Currently, d and b are chosen as d = r / p b = 10^6 hence we get the poor precision. And a is defined in terms of r, d, p and b: a = (r - d * p) * b / p I propose that if p <= 2^30-1 (i.e., the max value for b), we chose b as b = p The rationale behind this is that if b = p: a = (r - d * p) * b / p = (r - d * p) * p / p = r - d * p r = p * (d + a / b) = p * d + p * a / b = p * d + p * a / p = p * d + a and if d = r / p: a = r - d * p = r - r / p * p = 0 r = p * d + a = p * d + 0 = p * r / p = r I reckon this is the intention by the design of the clock rate formula. Signed-off-by: Emil Lundmark <emil@limesaudio.com> --- drivers/clk/imx/clk-pllv3.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/clk/imx/clk-pllv3.c b/drivers/clk/imx/clk-pllv3.c index bc7f163..5ff55ff 100644 --- a/drivers/clk/imx/clk-pllv3.c +++ b/drivers/clk/imx/clk-pllv3.c @@ -234,6 +234,7 @@ static long clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long max_rate = parent_rate * 54; u32 div; u32 mfn, mfd = 1000000; + u32 max_mfd = 0x3FFFFFFF; u64 temp64; if (rate > max_rate) @@ -241,6 +242,9 @@ static long clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long rate, else if (rate < min_rate) rate = min_rate; + if (parent_rate <= max_mfd) + mfd = parent_rate; + div = rate / parent_rate; temp64 = (u64) (rate - div * parent_rate); temp64 *= mfd; @@ -262,11 +266,15 @@ static int clk_pllv3_av_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long max_rate = parent_rate * 54; u32 val, div; u32 mfn, mfd = 1000000; + u32 max_mfd = 0x3FFFFFFF; u64 temp64; if (rate < min_rate || rate > max_rate) return -EINVAL; + if (parent_rate <= max_mfd) + mfd = parent_rate; + div = rate / parent_rate; temp64 = (u64) (rate - div * parent_rate); temp64 *= mfd; -- 2.7.4 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/2] ARM: imx: improve precision of AV PLL to 1 Hz 2016-10-06 11:12 ` [PATCH 2/2] ARM: imx: improve precision of AV PLL to 1 Hz Emil Lundmark @ 2016-10-07 7:48 ` Lothar Waßmann 2016-10-07 13:55 ` Emil Lundmark 0 siblings, 1 reply; 8+ messages in thread From: Lothar Waßmann @ 2016-10-07 7:48 UTC (permalink / raw) To: linux-arm-kernel Hi, On Thu, 6 Oct 2016 13:12:11 +0200 Emil Lundmark wrote: > The audio and video PLLs are designed to have a precision of 1 Hz if some > conditions are met. The current implementation only allows a precision that > depends on the rate of the parent clock. E.g., if the parent clock is 24 > MHz, the precision will be 24 Hz; or more generally the precision will be > > p / 10^6 Hz > > where p is the parent clock rate. This comes down to how the register > values for the PLL's fractional loop divider is chosen. > > The clock rate calculation for the PLL is > > PLL output frequency = Fref * (DIV_SELECT + NUM / DENOM) > > or with a shorter notation > > r = p * (d + a / b) > > In addition to all variables being integers, we also have the following > conditions: > > 27 <= d <= 54 > > 0 <= a <= 2^30-1 > Wrong. 'a' is a _signed_ number (see below)! So this should be: -2^29 <= a < 2^29 > 0 < b <= 2^30-1 > a < b > > Here, d, a and b are register values for the fractional loop divider. We > want to chose d, a and b such that f(p, r) = p, i.e. f is our round_rate > function. Currently, d and b are chosen as > > d = r / p > b = 10^6 > > hence we get the poor precision. And a is defined in terms of r, d, p and > b: > > a = (r - d * p) * b / p > > I propose that if p <= 2^30-1 (i.e., the max value for b), we chose b as > > b = p > According to the Reference Manual the "Absolute value should be less than denominator" |18.7.9 Numerator of Audio PLL Fractional Loop Divider Register | (CCM_ANALOG_PLL_AUDIO_NUM) |This register contains the numerator (A) of Audio PLL fractional loop divider.(Signed |number), absolute value should be less than denominator |Absolute value should be less than denominator Lothar Wa?mann ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 2/2] ARM: imx: improve precision of AV PLL to 1 Hz 2016-10-07 7:48 ` Lothar Waßmann @ 2016-10-07 13:55 ` Emil Lundmark 0 siblings, 0 replies; 8+ messages in thread From: Emil Lundmark @ 2016-10-07 13:55 UTC (permalink / raw) To: linux-arm-kernel On Fri, Oct 07, 2016 at 09:48:28AM +0200, Lothar Wa?mann wrote: > Hi, > > On Thu, 6 Oct 2016 13:12:11 +0200 Emil Lundmark wrote: > > The audio and video PLLs are designed to have a precision of 1 Hz if some > > conditions are met. The current implementation only allows a precision that > > depends on the rate of the parent clock. E.g., if the parent clock is 24 > > MHz, the precision will be 24 Hz; or more generally the precision will be > > > > p / 10^6 Hz > > > > where p is the parent clock rate. This comes down to how the register > > values for the PLL's fractional loop divider is chosen. > > > > The clock rate calculation for the PLL is > > > > PLL output frequency = Fref * (DIV_SELECT + NUM / DENOM) > > > > or with a shorter notation > > > > r = p * (d + a / b) > > > > In addition to all variables being integers, we also have the following > > conditions: > > > > 27 <= d <= 54 > > > > 0 <= a <= 2^30-1 > > > Wrong. 'a' is a _signed_ number (see below)! > So this should be: Correct, good catch! It is confusing that the denominator is defined as 'u32 mfn', I think it should be changed to 's32 mfn' instead. > -2^29 <= a < 2^29 > > > 0 < b <= 2^30-1 > > a < b > > > > Here, d, a and b are register values for the fractional loop divider. We > > want to chose d, a and b such that f(p, r) = p, i.e. f is our round_rate > > function. Currently, d and b are chosen as > > > > d = r / p > > b = 10^6 > > > > hence we get the poor precision. And a is defined in terms of r, d, p and > > b: > > > > a = (r - d * p) * b / p > > > > I propose that if p <= 2^30-1 (i.e., the max value for b), we chose b as > > > > b = p > > > According to the Reference Manual the "Absolute value should be less > than denominator" > |18.7.9 Numerator of Audio PLL Fractional Loop Divider Register > | (CCM_ANALOG_PLL_AUDIO_NUM) > |This register contains the numerator (A) of Audio PLL fractional loop divider.(Signed > |number), absolute value should be less than denominator > |Absolute value should be less than denominator > Yes, this changes everything. Lets revise my argument. We have the following: |a| < b d = r / p a = (r - d * p) * b / p If b = p, the expressions above still holds. Proof: |a| < b |(r - d * p) * b / p| < b |r - d * p| < p Which have two solutions, one of them is when p < 0, so we can skip that one. The other is when p > 0 and p * (d - 1) < r < p * (d + 1) Substitute d = r / p (r - p) < r < (r + p) <=> p > 0 So, as long as p > 0, we can chose b = p. However, we still have the constraint that b <= 2^30-1, so p <= 2^30-1. Which means that my proposed patch actually works, only my initial reasoning was wrong. For even more nitpicking, would it not be better to chose d = round(a / b)? Now, we essentially have d = floor(a / b) because of the integer division. So, with the current choice for d, would we not loose precision if p > 2^29-1? The question is, should we always chose b = p and ignore the precision loss if p > 2^30-1 (or p > 2^29-1)? -- Emil Lundmark ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 1/2] ARM: imx: fix integer overflow in AV PLL round rate 2016-10-06 11:12 [PATCH 1/2] ARM: imx: fix integer overflow in AV PLL round rate Emil Lundmark 2016-10-06 11:12 ` [PATCH 2/2] ARM: imx: improve precision of AV PLL to 1 Hz Emil Lundmark @ 2016-10-07 14:12 ` Emil Lundmark 2016-10-07 15:34 ` Fabio Estevam 1 sibling, 1 reply; 8+ messages in thread From: Emil Lundmark @ 2016-10-07 14:12 UTC (permalink / raw) To: linux-arm-kernel I realize that the two patches in this series does not actually depend on each other. This is my first contribution to Linux so I wonder if I should resubmit these as two separate patches instead? For example, what if the second patch in the series is not needed? Do you only accept the first patch then? Or what if I need to revise the second patch? It seems unnecessary to include the first patch in that case. I also got the threading wrong, but thats another story. -- Emil Lundmark ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 1/2] ARM: imx: fix integer overflow in AV PLL round rate 2016-10-07 14:12 ` [PATCH 1/2] ARM: imx: fix integer overflow in AV PLL round rate Emil Lundmark @ 2016-10-07 15:34 ` Fabio Estevam 2016-10-07 16:02 ` Emil Lundmark 0 siblings, 1 reply; 8+ messages in thread From: Fabio Estevam @ 2016-10-07 15:34 UTC (permalink / raw) To: linux-arm-kernel Hi Emil, On Fri, Oct 7, 2016 at 11:12 AM, Emil Lundmark <emil@limesaudio.com> wrote: > I realize that the two patches in this series does not actually depend on > each other. This is my first contribution to Linux so I wonder if I should > resubmit these as two separate patches instead? > > For example, what if the second patch in the series is not needed? Do you > only accept the first patch then? Or what if I need to revise the second > patch? It seems unnecessary to include the first patch in that case. > > I also got the threading wrong, but thats another story. It is better to resend these two patches and mark them as v2: [PATCH v2 1/2] [PATCH v2 2/2] Then put below the --- line what has changed from the previous one. If nothing changed just put "None". I am wondering if your patch series tries to fix the regression reported by Ken Lin or is it unrelated? http://lists.infradead.org/pipermail/linux-arm-kernel/2016-October/460451.html ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 1/2] ARM: imx: fix integer overflow in AV PLL round rate 2016-10-07 15:34 ` Fabio Estevam @ 2016-10-07 16:02 ` Emil Lundmark 2016-10-07 16:51 ` Fabio Estevam 0 siblings, 1 reply; 8+ messages in thread From: Emil Lundmark @ 2016-10-07 16:02 UTC (permalink / raw) To: linux-arm-kernel On Fri, Oct 07, 2016 at 12:34:42PM -0300, Fabio Estevam wrote: > Hi Emil, > > On Fri, Oct 7, 2016 at 11:12 AM, Emil Lundmark <emil@limesaudio.com> wrote: > > I realize that the two patches in this series does not actually depend on > > each other. This is my first contribution to Linux so I wonder if I should > > resubmit these as two separate patches instead? > > > > For example, what if the second patch in the series is not needed? Do you > > only accept the first patch then? Or what if I need to revise the second > > patch? It seems unnecessary to include the first patch in that case. > > > > I also got the threading wrong, but thats another story. > > It is better to resend these two patches and mark them as v2: > [PATCH v2 1/2] > [PATCH v2 2/2] > > Then put below the --- line what has changed from the previous one. If > nothing changed just put "None". > > I am wondering if your patch series tries to fix the regression > reported by Ken Lin or is it unrelated? > http://lists.infradead.org/pipermail/linux-arm-kernel/2016-October/460451.html I was not aware of that issue before but it seems related. Only the first patch in the series is relevant for solving the issue I was experiencing. I can't tell if it also solves theirs, but it's probable. The second part is really only nitpicking I discovered when debugging. Its intention is to allow a precision of 1 Hz instead of (most likely) 24 Hz. But when is that important for MHz clocks anyway? -- Emil Lundmark ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 1/2] ARM: imx: fix integer overflow in AV PLL round rate 2016-10-07 16:02 ` Emil Lundmark @ 2016-10-07 16:51 ` Fabio Estevam 0 siblings, 0 replies; 8+ messages in thread From: Fabio Estevam @ 2016-10-07 16:51 UTC (permalink / raw) To: linux-arm-kernel On Fri, Oct 7, 2016 at 1:02 PM, Emil Lundmark <emil@limesaudio.com> wrote: > I was not aware of that issue before but it seems related. Only the first > patch in the series is relevant for solving the issue I was experiencing. Also, in v2 please describe exactly the issue you were experiencing. Is the issue you observed a regression caused by ba7f4f557eb6 ("clk: imx: correct AV PLL rate formula")? If so, please state this in the commit log. ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2016-10-07 16:51 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2016-10-06 11:12 [PATCH 1/2] ARM: imx: fix integer overflow in AV PLL round rate Emil Lundmark 2016-10-06 11:12 ` [PATCH 2/2] ARM: imx: improve precision of AV PLL to 1 Hz Emil Lundmark 2016-10-07 7:48 ` Lothar Waßmann 2016-10-07 13:55 ` Emil Lundmark 2016-10-07 14:12 ` [PATCH 1/2] ARM: imx: fix integer overflow in AV PLL round rate Emil Lundmark 2016-10-07 15:34 ` Fabio Estevam 2016-10-07 16:02 ` Emil Lundmark 2016-10-07 16:51 ` Fabio Estevam
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).