[U-Boot] [RFC] Timer API (again!)

Graeme Russ graeme.russ at gmail.com
Fri Sep 16 13:53:49 CEST 2011


Hi All,

Well, here we are again, a Timer API discussion :)

All things considered, I don't think the Linux approach is right for U-Boot
- It is designed to cater for way more use-cases than U-Boot will ever need
to deal with (time queues and call-backs in particular)

To summarise, in a nutshell, what _I_ think U-Boot need from a Timer API

 1. A reliable udelay() available as early as possible that is OK to delay
    longer than requested, but not shorter - Accuracy is not implied or
    assumed
 2. A method of obtaining a number of 'time intervals' which have elapsed
    since some random epoch (more info below)
 3. A nice way of making A->B time checks simple within the code

OK, some details:

1. I'm starting to thing this should be a function pointer or a flag in gd.
Why oh why would you do such a thing I hear you ask... udelay() is needed
_EARLY_ - It may well be needed for SDRAM or other hardware initialisation
prior to any reliable timer sub-system being available. But early udelay()
is often inaccurate and when the timer sub-system gets fully initialised,
it can be used for an accurate udelay(). x86 used to have an global data
flag that got set when the timer-subsystem got initialised. If the flag was
not set, udelay() would use one implementation, but if it was set, udelay()
would use a more accurate implementation. In the case of the eNET board, it
had an FPGA implementation of a microsecond timer which was even more
accurate that the CPU, so it had it's own implementation that should have
duplicated the 'if (gd->flags & TIMER_INIT)' but never did (this was OK
because udelay() was never needed before then)

I think a function pointer in gd would be a much neater way of handling the
fact that more accurate (and efficient) implementations of udelay() may
present themselves throughout the boot process

An other option would be to have the gd flag and make udelay() a lib
function which performs the test - If the arch timer has better than 1us
resolution it can set the flag and udelay() will use the timer API

2a (random epoch) - The timer sub-system should not rely on a particular
epoch (1970, 1901, 0, 1, since boot, since timer init, etc...) - By using
the full range of an unsigned variable, the epoch does not matter

2b (time interval) - We need to pick a base resolution for the timer API -
Linux uses nano-seconds and I believe this is a good choice. Big Fat Note:
The underlying hardware DOES NOT need to have nano-second resolution. The
only issue with nano-seconds is that it mandates a 64-bit timer - A few
people are against this idea - lets discuss. A 32-bit microsecond timer
provides ~4300 seconds (~1.2 hours) which _might_ be long enough, but
stand-alone applications doing burn-in tests may need longer. Going
milli-seconds means we cannot piggy-back udelay() on the timer API.

My preference is a 64-bit nano-second timer with udelay() piggy-backed on
the timer API (unless, like NIOS, the timer sub-system cannot provide
micro-second resolution, in which case the gd flag or function pointer does
not get set to use the timer API for udelay())

I really want to get the Timer API sorted this time around

Regards,

Graeme


More information about the U-Boot mailing list