arm: zynq: U-Boot udelay < 1000 FIX

Rework the __udelay function of U-Boot Zynq Arch to handle
delay < 1000 usec

Signed-off-by: David Andrey <david.andrey@netmodule.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
Reviewed-by: Tom Rini <trini@ti.com>
This commit is contained in:
David Andrey 2012-12-07 16:51:32 +01:00 committed by Michal Simek
parent d10f68ae47
commit d54cc00787

View File

@ -114,15 +114,43 @@ ulong get_timer_masked(void)
void __udelay(unsigned long usec)
{
unsigned long long tmp;
ulong tmo;
u32 countticks;
u32 timeend;
u32 timediff;
u32 timenow;
tmo = usec / (1000000 / CONFIG_SYS_HZ);
tmp = get_ticks() + tmo; /* Get current timestamp */
if (usec == 0)
return;
while (get_ticks() < tmp) { /* Loop till event */
/* NOP */;
}
countticks = (u32) (((unsigned long long) TIMER_TICK_HZ * usec) /
1000000);
/* decrementing timer */
timeend = readl(&timer_base->counter) - countticks;
#if TIMER_LOAD_VAL != 0xFFFFFFFF
/* do not manage multiple overflow */
if (countticks >= TIMER_LOAD_VAL)
countticks = TIMER_LOAD_VAL - 1;
#endif
do {
timenow = readl(&timer_base->counter);
if (timenow >= timeend) {
/* normal case */
timediff = timenow - timeend;
} else {
if ((TIMER_LOAD_VAL - timeend + timenow) <=
countticks) {
/* overflow */
timediff = TIMER_LOAD_VAL - timeend + timenow;
} else {
/* missed the exact match */
break;
}
}
} while (timediff > 0);
}
/* Timer without interrupts */