
[PATCH] IXP425: Fixing timer code
The non-interrupted timer code is inaccurate.
I found that the timing error of udelay() is caused by to much looping overhead. The actual timing routine was called repeatedly for each microsecond. When I used bigger slices it became more accurate.
Some IXP425 ports have this line in their config file:
#define CONFIG_SYS_HZ 3333333 /* spec says 66.666 MHz, but it appears to be 33 */
With this patch, this is nonsense. Instead you should use:
#ifdef CONFIG_USE_IRQ /* Interrupt driven timer wants system tick here */ #define CONFIG_SYS_HZ 1000 #else /* The code in cpu/ixp/timer.c needs timer clock tick in HZ */ #define CONFIG_SYS_HZ 66666666 #endif
The patch is against "latest" u-boot git-repository
Please (still) be patient if style of submission or patches are offending.
Signed-off-by: Stefan Althoefer stefan.althoefer@web.de ----
diff -uprN u-boot-orig//cpu/ixp/timer.c u-boot/cpu/ixp/timer.c --- u-boot-orig//cpu/ixp/timer.c 2008-12-02 17:25:31.000000000 +0100 +++ u-boot/cpu/ixp/timer.c 2008-12-02 22:27:22.000000000 +0100 @@ -46,6 +46,8 @@ void ixp425_udelay(unsigned long usec) */ unsigned long usecs = CONFIG_SYS_HZ/1000000L & ~IXP425_OST_RELOAD_MASK;
+ usecs *= usec; + *IXP425_OSST = IXP425_OSST_TIMER_1_PEND; usecs |= IXP425_OST_ONE_SHOT | IXP425_OST_ENABLE; *IXP425_OSRT1 = usecs; @@ -54,7 +56,13 @@ void ixp425_udelay(unsigned long usec)
void udelay (unsigned long usec) { - while (usec--) ixp425_udelay(1); + /* ipx425_udelay has big overhead, so call it in bigger slices */ + while (usec>1000){ + ixp425_udelay(1000); + usec -= 1000; + } + /* and now the rest */ + ixp425_udelay(usec); }
static ulong reload_constant = 0xfffffff0;