author Ernst Schwab Wed, 17 Feb 2010 04:02:57 +0000 (21:02 -0700) committer Grant Likely Tue, 16 Feb 2010 21:26:58 +0000 (14:26 -0700) commit 4f4517c45f325ba511458465430a52864a5d0d30 tree 5785250ce5468b764adbef9988e7d6e135e1479d tree | snapshot parent 8a349d4b13c41c00564cd79f6fabdec347084758 commit | diff
spi: Correct SPI clock frequency setting in spi_mpc8xxx

Correct SPI clock frequency division factor rounding, preventing clock rates
higher than the maximum specified clock frequency being used.

When specifying spi-max-frequency = <10000000> in the device tree,
the resulting frequency was 11.1 MHz, with spibrg being 133333332.

According to the freescale data sheet , the spi clock rate is
spiclk = spibrg / (4 * (pm+1))

The existing code calculated
pm = mpc8xxx_spi->spibrg / (hz * 4); pm--;
resulting in pm = (int) (3.3333) - 1 = 2,
resulting in spiclk = 133333332/(4*(2+1)) = 11111111

With the fix,
pm = (mpc8xxx_spi->spibrg - 1) / (hz * 4) + 1; pm--;
resulting in pm = (int) (4.3333) - 1 = 3,
resulting in spiclk = 133333332/(4*(3+1)) = 8333333

Without the fix, for every desired SPI frequency that
is not exactly derivable from spibrg, pm will be too
small due to rounding down, resulting in a too high SPI clock,
so we need a pm which is one higher.

For values that are exactly derivable, spibrg will
be dividable by (hz*4) without remainder, and
(int) ((spibrg-1)/(hz*4)) will be one lower than
(int) (spibrg)/(hz*4), which is compensated by adding 1.
For these values, the fixed version calculates the same pm
as the unfixed version.

For all values that are not exactly derivable,
spibrg will be not dividable by (hz*4) without
remainder, and (int) ((spibrg-1)/(hz*4)) will be
the same as (int) (spibrg)/(hz*4), and the calculated pm will
be one higher than calculated by the unfixed version.

References:
 http://www.freescale.com/files/32bit/doc/ref_manual/MPC8315ERM.pdf,
page 22-10 -> 1398

Signed-off-by: Ernst Schwab <eschwab@online.de>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>