
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