Hello Everyone, OK - Starting a new thread to discuss implementation details. This is a heads-up for arch/platform maintainers - Once this is a bit more stable, I will put it on the wiki
Assumed Capabilities of the Platform - Has a 'tick counter' that does not rely on software to increment - tick interval may by a fixed constant which cannot be controlled via software, or it could be programmable (PIT) API Functions (/lib/timer.c) - u32 get_timer(u32 start) - Returns the number of elapsed milliseconds since 'start' API Functions (/arch/...) - void udelay(u32 delay) - Used for 'short' delays (generally up to several seconds) - Can use the tick counter if it is fast enough - MUST NOT RESET THE TICK COUNTER 'Helper' Functions (/lib/timer.c) - void sync_timebase(void) - Updates the millisecond timer - Utilises HAL functions to access the platform's tick counter - Must be called more often than the rollover period of the platform's tick counter - Does not need to be called with a regular frequency (immune to interrupt skew) - Is always called by get_timer() - For platforms with short tick counter rollovers it should be called by an ISR - Bill Campbell wrote a good example which proved this can be common and arbitrary (and optionally free of divides and capable of maintaining accuracy even if the tick frequency is not an even division of 1ms) HAL Functions (/arch/... or /board/...) - u64 get_ticks(void) - Returns a tick count as an unsigned 64-bit integer - Abstracts the implementation of the platform tick counter (platform may by 32-bit 3MHz counter, might be a 16-bit 0-999 microsecond plus 16-bit 0-65535 millisecond etc) - u64 ticks_per_millisecond() - Returns the number of ticks (as returned by get_ticks()) per millisecond - void timer_isr() - Optional (particularly if tick counter rollover period is exceptionally log which is usually the case for native 64-bit tick counters) - Simply calls sync_timebase() - For platforms without any tick counter, this can implement one (but accuracy will be harmed due to usage of disable_interrupts() and enable_interrupts() in U-Boot So to get the new API up and running, only two functions are mandatory: get_ticks() which reads the hardware tick counter and deals with any 'funny stuff' including rollovers, short timers (12-bit for example), composite counters (16-bit 0-999 microsecond + 16-bit millisecond) and maintains a 'clean' 64-bit tick counter which rolls over from all 1's to all 0's. The 64-bit tick counter does not need to be reset to zero ever (even on startup - sync_timebase tacks care of all the details) ticks_per_millisecond() simply return the number of ticks in a millisecond - This may as simple as: inline u64 ticks_per_millisecond(void) { return CONFIG_SYS_TICK_PER_MS; } But it may be trickier if you have a programmable tick frequency The optional timer ISR is required if the tick counter has a short roll over duration (short is up to you - 1 second is short, 1 hour might be, 1 century is not) Regards, Graeme _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot