diff options
| author | David Andrey <david.andrey@netmodule.com> | 2012-12-07 16:51:32 +0100 | 
|---|---|---|
| committer | Michal Simek <michal.simek@xilinx.com> | 2013-04-30 11:39:10 +0200 | 
| commit | d54cc007878697a92e7f696b71a3eb203c0386e2 (patch) | |
| tree | b4dba36a37a114391b7b7df19e7add5a9993a3f9 | |
| parent | d10f68ae47b67acab8b110b5c605dde4197a1820 (diff) | |
| download | olio-uboot-2014.01-d54cc007878697a92e7f696b71a3eb203c0386e2.tar.xz olio-uboot-2014.01-d54cc007878697a92e7f696b71a3eb203c0386e2.zip | |
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>
| -rw-r--r-- | arch/arm/cpu/armv7/zynq/timer.c | 42 | 
1 files changed, 35 insertions, 7 deletions
| diff --git a/arch/arm/cpu/armv7/zynq/timer.c b/arch/arm/cpu/armv7/zynq/timer.c index 45b405a4b..5d8bb2409 100644 --- a/arch/arm/cpu/armv7/zynq/timer.c +++ b/arch/arm/cpu/armv7/zynq/timer.c @@ -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 */ |