From: J. William Campbell <jwilliamcampbell@comcast.net>
To: u-boot@lists.denx.de
Subject: [U-Boot] [RFC] ARM timing code refactoring
Date: Mon, 24 Jan 2011 08:23:34 -0800 [thread overview]
Message-ID: <4D3DA786.6080409@comcast.net> (raw)
In-Reply-To: <20110124130200.3AF71B187@gemini.denx.de>
On 1/24/2011 5:02 AM, Wolfgang Denk wrote:
> Dear Albert ARIBAUD,
>
> In message<4D3D2942.4060600@free.fr> you wrote:
>> That is assuming a 64-bit timebase, isn't it? for CPUs / SoCs that don't>
>> have such a timebase but only a 32-bit timer, the bogo_ms/jiffy would>
>> not go through the full 32-bit range, which would cause issues with the>
>> timing loops on rollover -- and while a timeout of more than 65 sec may>
>> not be too likely, a timeout starting near the wraparound value of>
>> bogo_ms still could happen.
Hi All,
If you use my approach of shifting right by n bits (in order to
get a counter that has "about" 1 ms resolution), zeros are shifted into
the top. The counter would never reach more than (32-n) bits in
magnitude. This is easily fixed by creating a "virtual" n msbs for the
counter, as must be done if a 64 bit counter is to be simulated.
Actually, I only need "n" bits, but in any case it requires detecting
that the counter has "backed up" mod 32 bits and if so, increase the
virtual counter by 1.
If you really, really, really want a timer that "ticks" at a 1 ms rate,
instead of bogo_ms/jiffies, I propose the following:
u32 get_time()
{
u32 delta_t_bogo_ms;
u32 t_save;
#if defined(TIMER_IS_64_BITS)
u64 tick;
read(&tick);
t_save = tick >> gd->timer_shift;
delta_t_bogo_ms = t_bogo_ms - gd->prev_timer;
#else
read(t_save);
delta_t_bogo_ms = (t_save - gd->prev_timer) >> gd->timer_shift;
#endif
gd->prev_timer = t_save; /* save previous counter */
if (delta_t_bogo_ms < gd->bogo_ms_per_65_sec)
{
gd->fract_timer += delta_t_bogo_ms *
gd->cvt_bogo_ms_to_ms; /* accumulate fraction of ms */
gd->timer_in_ms += gd->fract_timer >> 16;
gd->fract_timer &= 0X0000FFFF;
}
else
gd->fract_timer = 0; /* start accumulating from 0 fraction */
return(gd->timer_in_ms)
}
This routine will create a timer in ms, that will be
accurate as long as this routine is called either once about ever 65
seconds or once per time base rollover, whichever is less. Nested timer
use is ok. If the timer is not called frequently enough, it will return
the same value twice, but after that it will start timing normally. This
shouldn't matter, as the second returned value will be the start of a
timing loop. Timeout values can be the full 32 bits, as long as you keep
calling the routine frequently enough. No initialization is required.
Note that you can (and probably should) use the bottom 32
bits of the hardware timebase as a 32 bit timebase unless the clock
would overflow in 65 seconds (running faster than about 66 MHz), or if
you want to relax the 65 seconds.
If you want to save a word in the gd data, use 0X10000 instead of
bogo_ms_per_65_sec (or a more precise value if you know it). Note that
gd->timer_shift and gd->cvt_bogo_ms_to_ms can also be replaced by
constants if the clock speed is fixed.
This is more expensive than using the bogo_ms timer, but does have the
advantage that everything is in ms. FWIW, I think converting from ms to
some other unit for loop control is fine, as long as we have a standard
routine to do that that is "cheap". However, others may not agree. For
sure, passing around 64 bit tick values to do this process is, IMHO,
vast overkill and not a good general solution, as many processors really
don't like to do 64 bit operations.
Best Regards.
Bill Campbell
> Sorry, but I don't get it. What exactly is the problem with a 32 bit
> counter, and why would it not go through the full 32-bit range?
>
> Best regards,
>
> Wolfgang Denk
>
next prev parent reply other threads:[~2011-01-24 16:23 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-01-22 10:20 [U-Boot] [RFC] ARM timing code refactoring Albert ARIBAUD
2011-01-22 10:42 ` Reinhard Meyer
2011-01-22 11:32 ` Albert ARIBAUD
2011-01-22 11:00 ` [U-Boot] [RFC] U-boot (was: ARM) " Reinhard Meyer
2011-01-22 12:22 ` [U-Boot] [RFC] U-boot Albert ARIBAUD
2011-01-22 19:19 ` [U-Boot] [RFC] ARM timing code refactoring Wolfgang Denk
2011-01-22 20:17 ` Albert ARIBAUD
2011-01-22 21:26 ` Wolfgang Denk
2011-01-22 21:51 ` Reinhard Meyer
2011-01-23 10:12 ` Wolfgang Denk
2011-01-23 10:26 ` Reinhard Meyer
2011-01-23 16:23 ` Wolfgang Denk
2011-01-23 18:47 ` Reinhard Meyer
2011-01-23 19:35 ` Wolfgang Denk
2011-01-23 20:59 ` Albert ARIBAUD
2011-01-23 21:22 ` Reinhard Meyer
2011-01-23 22:01 ` Reinhard Meyer
2011-01-23 22:57 ` Wolfgang Denk
2011-01-24 1:42 ` J. William Campbell
2011-01-24 7:24 ` Albert ARIBAUD
2011-01-24 7:50 ` Reinhard Meyer
2011-01-24 12:59 ` Wolfgang Denk
2011-01-24 8:25 ` Andreas Bießmann
2011-01-24 11:58 ` Albert ARIBAUD
2011-01-24 12:06 ` Albert ARIBAUD
2011-01-24 12:58 ` Andreas Bießmann
2011-01-24 12:54 ` Wolfgang Denk
2011-01-24 13:02 ` Wolfgang Denk
2011-01-24 16:23 ` J. William Campbell [this message]
2011-01-22 22:13 ` Albert ARIBAUD
2011-01-23 16:15 ` Wolfgang Denk
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4D3DA786.6080409@comcast.net \
--to=jwilliamcampbell@comcast.net \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox