Reinhard Meyer had written, on 10/26/2010 02:57 AM, the following: > Wolfgang Denk schrieb: >> Dear Reinhard Meyer, >> >> In message <4cc67ca1.9090...@emk-elektronik.de> you wrote: >>> If implemented with true 64 bits for get_ticks() that function is useable >>> for timeout programming: >>> >>> ulong timeval = get_timer (0); >>> >>> do { >>> ... >>> } while (get_timer (timeval) < TIMEOUT); >>> >>> It appears that the "base" parameter and return value is in CONFIG_SYS_HZ >>> units, and not in native ticks. That causes 64 bit mul/div every >>> time get_timer() is called. Won't hurt in a timeout loop, though. >> But it will hurt in othe rplaces. >> >> Also, this code _is_ a bit different, as "get_timer(0)" makes sure >> the counter starts ticking again at 0 > > Nope, it does not reset the counter itself. It returns the current > counter value (recalculated into CONFIG_SYS_HZ units). > Maybe you mean reset_timer() instead? > > In arm9226ejs/omap/timer.c udelay() is implemented with reset_timer() > and get_timer(). Since those functions are inherently not nestable, > beware of base=get_timer(0); do { ... udelay(xx); ... } while > (get_timer(base) < TIMEOUT); > constructs! At least the omap3+ code arch/arm/cpu/armv7/omap-common/timer.c __udelay() does'nt seem to reset the timer BUT, unsigned long long get_ticks(void) { return get_timer(0); } ulong get_timer(ulong base) { return get_timer_masked() - base; } ulong get_timer_masked(void) { /* current tick value */ ulong now = readl(&timer_base->tcrr) / (TIMER_CLOCK / CONFIG_SYS_HZ);
if (now >= lastinc) /* normal mode (non roll) */ /* move stamp fordward with absoulte diff ticks */ timestamp += (now - lastinc); else /* we have rollover of incrementer */ timestamp += ((TIMER_LOAD_VAL / (TIMER_CLOCK / CONFIG_SYS_HZ)) - lastinc) + now; lastinc = now; return timestamp; } if I am not mistaken, this is 32bit long.. but since we have as wdenk mentions below a 2^32 tick duration, we can safely go with an option such as: /* If we fail after 1 second wait, something is really bad */ #define MAX_RETRY_US (1 * 1000 * 1000) uint64_t etime; /* actually this could be u32 */ etime = get_ticks() + usec2ticks(MAX_RETRY_US); while (!(readl(&mmc_base->stat) & CC_MASK)) { if (get_ticks() <= etime) { printf("%s: timedout waiting for cc2!\n", __func__); return; } } sounds right? > >> , and get_timer() is defined to >> have millisecond resolution. > > Actually CONFIG_SYS_HZ (whatever that is). > >> So you have a guaranteed 2^32 >> milliseconds or 4294967 seconds or about 3.3 years available which >> indeed should be sufficient to implement standard timeouts. > > I think it is necessary to summarize all implicit or explicit documented > "defined to have's" regarding the timer and then to verify that all > implementations adhere to them. > yes indeed.. :( -- Regards, Nishanth Menon _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot