[PATCH 2/2] ARM: imx: improve precision of AV PLL to 1 Hz
Emil Lundmark
emil at limesaudio.com
Fri Oct 7 06:55:10 PDT 2016
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
More information about the linux-arm-kernel
mailing list