[U-Boot] RFC: get_ticks() + get_tbclk()

Hello,
it is my understanding that get_ticks() shall return the count of a free running (hardware) counter that increments by a total of get_tbclk() every second. Both functions are long long.
I also understand that this counter does not necessarily increment at a rate of CONFIG_SYS_HZ, but at a hardware determined, usually much higher rate.
Is that understanding correct so far?
Looking at the current implementations of those functions, it seems that in some cases those two functions do not work in coherence. Most get_tbclk() implementations plainly return CONFIG_SYS_HZ without assuring that the timer is programmed to run at that rate.
Some do not work with long long values so there might be a small window where 0x0000ffff wraps back to 0x00000000 and a programmed timeout will fail.
Reinhard

might want to check out the thread i started over a year ago: [u-boot] core ticks/timer code it delves into these internals and may help you here -mike

Dear Mike Frysinger,
might want to check out the thread i started over a year ago: [u-boot] core ticks/timer code it delves into these internals and may help you here -mike
Thanks for the hint, and sorry to have started the topic again ;)
However it seems no resolution has come up since then.
For me it seems useful to keep both functions and have ticks increment at a hardware-convenient rate. If the hardware timer can be prescaled to increment at 1000 Hz that is fine, but I see no immediate need for that. If the hardware cannot be prescaled, and software would need to do a 64 bit multiply/divide on each timer read, that would really be overkill.
timer_reset() prevents you to have nested timeouts (if that ever comes up)
Reinhard

Dear Reinhard Meyer,
In message 4C98536C.6010003@emk-elektronik.de you wrote:
For me it seems useful to keep both functions and have ticks increment at a hardware-convenient rate. If the hardware timer can be prescaled to increment at 1000 Hz that is fine, but I see no immediate need for that. If the hardware cannot be prescaled, and software would need to do a 64 bit multiply/divide on each timer read, that would really be overkill.
Just FYI: the origin of these functions is (like usual) in the implementation for the Power Architecture.
There we have a 64 bit timebase register (split into two 32 bit registers, the upper half in tbu and the lower half in tbl). The timebase register gets incremented at a pretty high rate, usually every 4 or 16 system clocks).
get_ticks() just returns the content of the 64 bit timebase register.
[See also wait_ticks(0 which delays for a number of ticks, cf. "arch/powerpc/lib/ticks.S"]
get_tbclk() just returns the timebase clock (usually derived froom the system clock; see for exmaple "arch/powerpc/cpu/mpc5xxx/cpu.c": tbclk = (gd->bus_clk + 3L) / 4L; ).
Best regards,
Wolfgang Denk

Dear Wolfgang Denk,
In message 4C98536C.6010003@emk-elektronik.de you wrote:
For me it seems useful to keep both functions and have ticks increment at a hardware-convenient rate. If the hardware timer can be prescaled to increment at 1000 Hz that is fine, but I see no immediate need for that. If the hardware cannot be prescaled, and software would need to do a 64 bit multiply/divide on each timer read, that would really be overkill.
Just FYI: the origin of these functions is (like usual) in the implementation for the Power Architecture.
There we have a 64 bit timebase register (split into two 32 bit registers, the upper half in tbu and the lower half in tbl). The timebase register gets incremented at a pretty high rate, usually every 4 or 16 system clocks).
get_ticks() just returns the content of the 64 bit timebase register.
Yes, of course. So the current ARM926EJS/AT91 implementation is actually in the right direction, although not perfected yet. I am going to look into that.
Reinhard
participants (3)
-
Mike Frysinger
-
Reinhard Meyer
-
Wolfgang Denk