
On Mar 14, 2011, at 14:19, York Sun wrote:
On Wed, 2011-02-23 at 11:35 -0500, Kyle Moffett wrote:
The current FreeScale MPC-8xxx DDR SPD interpreter is using full 64-bit integer divide operations to convert between nanoseconds and DDR clock cycles given arbitrary DDR clock frequencies.
Since all of the inputs to this are 32-bit (nanoseconds, clock cycles, and DDR frequencies), we can easily restructure the computation to use the "do_div()" function to perform 64-bit/32-bit divide operations.
This decreases compute time rather significantly for each conversion and avoids bringing in a very complicated function from libgcc.
It should be noted that nothing else in U-Boot or the Linux kernel seems to require a full 64-bit divide on any 32-bit PowerPC.
Build-and-boot-tested on the HWW-1U-1A board using DDR2 SPD detection.
Signed-off-by: Kyle Moffett Kyle.D.Moffett@boeing.com Cc: Andy Fleming afleming@gmail.com Cc: Kumar Gala kumar.gala@freescale.com Cc: Wolfgang Denk wd@denx.de Cc: Kim Phillips kim.phillips@freescale.com
Ok, so this patch touches a rather sensitive part of the fsl_ddr logic.
I spent a fair amount of time trying to verify that the resulting math is exactly the same as it was before, but the consequences of a mistake are insideous timing problems. Additional in-depth review would be much appreciated.
What's the gain of the changes? A smaller footprint? Going forward from 32- to 64-bit, are we going to change it back?
On 64-bit this change is basically a no-op, because do_div() is implemented as a literal 64-bit divide operation and the instruction scheduling works out almost the same.
On 32-bit PowerPC a fully accurate 64/64 divide (__udivdi3 in libgcc) is 1.1kb of code and hundreds or thousands of dependent cycles to compute, all of which is linked in from libgcc. Another 1.2kb of code comes in for __umoddi3.
The original reason I wrote this patch is that the native "libgcc" on my boards is hard-float and therefore generates warnings when linking to it from soft-float code. The toolchain is the native Debian powerpc (or powerpcspe), and most other native PowerPC distributions are also hard-float-only.
When I combine this patch with the other patch I posted to create a minimal internal libgcc with a few 64-bit shift functions from the linux kernel, I can successfully build U-Boot on those native PowerPC systems.
Cheers, Kyle Moffett