void __udelay(unsigned long usec)
{
- unsigned long long tmp;
- ulong tmo;
-
- tmo = usec / (1000000 / CONFIG_SYS_HZ);
- tmp = get_ticks() + tmo; /* Get current timestamp */
-
- while (get_ticks() < tmp) { /* Loop till event */
- /* NOP */;
- }
+ u32 countticks;
+ u32 timeend;
+ u32 timediff;
+ u32 timenow;
+
+ if (usec == 0)
+ return;
+
+ 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 */