[U-Boot] [RFC] Review of U-Boot timer API

J. William Campbell
2011-05-24T22:32:11Z

On 5/24/2011 12:19 PM, Wolfgang Denk wrote:
> Dear Graeme Russ,
>
> In message<4DDBE22D.6050806@gmail.com> you wrote:
>>>> Why must get_timer() be used to perform "meaningful time measurement?"
>>> Excellent question! It was never intended to be used as such.
>> Because get_timer() as it currently stands can as it is assumed to return
>> milliseconds
> Yes, but without any guarantee for accuracy or resolution.
> This is good enough for timeouts, but nothing for time measurements.
>
>> OK, let's wind back - My original suggestion made no claim towards changing
>> what the API is used for, or how it looks to those who use it (for all
>> practical intents and purposes). I suggested:
>> - Removing set_timer() and reset_timer()
>> - Implement get_timer() as a platform independent function
> Trying to remember what I have read in this thread I believe we have
> an agreement on these.
>
>> Exposing ticks and tick_frequency to everyone via a 'tick' HAL
> I skip this. I don't even read it.
>
>> =======================
>> Not exposing ticks and tick_frequency to everyone
>>
>> In /lib/timer.c
>>
>> void prescaler(u32 ticks, u32 tick_frequency)
>> {
>> u32 current_ms;
>>
>> /* Bill's algorithm */
>>
>> /* result stored in gd->timer_in_ms; */
>> }
>>
>> In /arch/cpu/soc/timer.c or /arch/cpu/timer.c or /board/<board>/timer.c
>>
>> static u32 get_ticks(void)
> Currently we have unsigned long long get_ticks(void) which is better
> as it matches existing hardware.
>
> Note that we also have void wait_ticks(u32) as needed for udelay().
Hi All,
I didn't comment before on the definition of ticks, but I fear
that was unwise. The stated definition was:

A tick is defined as the smallest increment of system time as measured by a
computer system (seehttp://en.wikipedia.org/wiki/System_time):

System time is measured by a system clock, which is typically
implemented as a simple count of the number of ticks that have
transpired since some arbitrary starting date, called the
epoch.

Unfortunately, this definition is obsolete, and has been for quite some
years. When computers had a single timer, the above definition worked,
but it no longer does, as many (most?) computers have several hardware
timers. A "tick" today is the time increment of any particular timer of
a computer system. So, when one writes a function called get_ticks on a
PPC, does one mean read the decrementer, or does one read the RTC or
does one read the TB register(s) A similar situation exists on the
Blackfin BF531/2/3, that has a preformance counter, a real-time clock,
and three programmable timers. Which tick do you want? For each u-boot
implementation, we can pick one timer as the "master" timer, but it may
not be the one with the most rapid tick rate. It may be the one with the
most USEFUL tick rate for get_timer. If you take the above definition at
face value, only the fastest counter value has ticks, and all other
counters time increments are not ticks. If they are not ticks, what are
they?

This is one of the reasons I favor the performance monitoring system be
separate from the get_timer timing methodology, as it will often use a
different counter and time base anyway. That is also why I prefer to
have a conversion routine that converts timer values to seconds and
nano-seconds without reference to "tick" rates, so the user never has to
deal with these ambiguities. Yes, "under the hood", somebody does, but
that need not be specified in the external interface. )Nobody has yet
commented on my proposed performance measuring functions, and I know
this group well enough not to assume that silence implies consent! )

The prescaler function defined by Graeme needs to read some timer value.
It turns out that a u32 value is the most appropriate value for the
get_timer operation. The value desired is usually not of hardware timer
tick resolution. It should be the specific bits in the timer, such that
the LSB resolution is between 1 ms and 0.5 ms. We use greater resolution
that this only when the counter is short enough that we need lower
significance bits to make the counter 32 bits. For that reason, the
function should probably be call something like u32
read_timer_value(void). I really don't much care what it is called as
long as we understand what it does.

Best Regards,
Bill Campbell

>> static u32 get_tick_frequency(void)
>> {
>> u32 tick_frequency;
>>
>> /* Determine tick frequency */
>>
>> return tick_frequency;
>> }
> Note that we also have u32 usec2ticks(u32 usec) and u32 ticks2usec(u32 ticks).
>
> Best regards,
>
> Wolfgang Denk
>