From: Marek Vasut <marek.vasut@gmail.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH] Update s3c24x0 timer implementation
Date: Mon, 24 Oct 2011 15:58:36 +0200 [thread overview]
Message-ID: <201110241558.36834.marek.vasut@gmail.com> (raw)
In-Reply-To: <CAJtrzLNz3TBBRHoNtHkuGci4YJZ9PLrJfvGaR_XdVbrdcprxbQ@mail.gmail.com>
> Dear Wolfgang Denk,
>
> Thank you for your response.
>
> >> Since the .rel.text section is required by the relocation code, I
> >> assume that .bss global variables cannot be used until after
> >> relocation?
> >
> > Why do you have to make such assumptions? That's documented
> > behaviour. Didn't you RTFM?
>
> I thought I had done a thorough search previously but after receiving
> your response I managed to find some of the details outlined in the
> README file.
>
> I have attached an updated patch below which hopefully addresses the
> other issues you highlighted.
Hehe, you should RTFM ;-) http://www.denx.de/wiki/U-Boot/Patches
Generally, use git send-email to send the patch.
>
> Kind Regards,
>
> Mark Norman
>
>
>
> The s3c24x0 timer has been updated to use the global_data struct.
> Restructured code based on other timer.c files.
> Updated comments and several parameters.
>
> Signed-off-by: Mark Norman <mpnorman@gmail.com>
> ---
> arch/arm/cpu/arm920t/s3c24x0/timer.c | 155
> +++++++++++++-------------------- arch/arm/include/asm/global_data.h |
> 4 +
> 2 files changed, 65 insertions(+), 94 deletions(-)
>
> diff --git a/arch/arm/cpu/arm920t/s3c24x0/timer.c
> b/arch/arm/cpu/arm920t/s3c24x0/timer.c
> index 9571870..5695c62 100644
> --- a/arch/arm/cpu/arm920t/s3c24x0/timer.c
> +++ b/arch/arm/cpu/arm920t/s3c24x0/timer.c
> @@ -35,142 +35,109 @@
> #include <asm/io.h>
> #include <asm/arch/s3c24x0_cpu.h>
>
> -int timer_load_val = 0;
> -static ulong timer_clk;
> +DECLARE_GLOBAL_DATA_PTR;
>
> -/* macro to read the 16 bit timer */
> -static inline ulong READ_TIMER(void)
> +/* Read the 16 bit timer */
> +static inline ulong read_timer(void)
> {
> struct s3c24x0_timers *timers = s3c24x0_get_base_timers();
>
> return readl(&timers->tcnto4) & 0xffff;
> }
>
> -static ulong timestamp;
> -static ulong lastdec;
> -
> int timer_init(void)
> {
> + /*
> + * PWM Timer 4 is used because it has no output.
> + * Prescaler is hard fixed at 250, divider at 2.
> + * This generates a Timer clock frequency of 100kHz (@PCLK=50MHz) and
> + * therefore 10us timer ticks.
> + */
> + const ulong prescaler = 250;
> struct s3c24x0_timers *timers = s3c24x0_get_base_timers();
> ulong tmr;
>
> - /* use PWM Timer 4 because it has no output */
> - /* prescaler for Timer 4 is 16 */
> - writel(0x0f00, &timers->tcfg0);
> - if (timer_load_val == 0) {
> - /*
> - * for 10 ms clock period @ PCLK with 4 bit divider = 1/2
> - * (default) and prescaler = 16. Should be 10390
> - * @33.25MHz and 15625 @ 50 MHz
> - */
> - timer_load_val = get_PCLK() / (2 * 16 * 100);
> - timer_clk = get_PCLK() / (2 * 16);
> - }
> - /* load value for 10 ms timeout */
> - lastdec = timer_load_val;
> - writel(timer_load_val, &timers->tcntb4);
> - /* auto load, manual update of timer 4 */
> + /* Set prescaler for Timer 4 */
> + writel((prescaler-1) << 8, &timers->tcfg0);
Can we get rid of the magic numbers please?
> +
> + /* Calculate timer freq, approx 100kHz @ PCLK=50MHz. */
> + gd->timer_rate_hz = get_PCLK() / (2 * prescaler);
Can get_PCLK() be renamed to be lower-case only?
> +
> + /* Set timer for 0.5s timeout (50000 ticks @ 10us ticks). */
> + gd->timer_reset_value = 50000;
> + writel(gd->timer_reset_value, &timers->tcntb4);
> + gd->lastdec = gd->timer_reset_value;
> +
> + /* Load the initial timer 4 count value using the manual update bit. */
> tmr = (readl(&timers->tcon) & ~0x0700000) | 0x0600000;
Magic values :-(
> writel(tmr, &timers->tcon);
> - /* auto load, start timer 4 */
> +
> + /* Configure timer 4 for auto reload and start it. */
> tmr = (tmr & ~0x0700000) | 0x0500000;
> writel(tmr, &timers->tcon);
> - timestamp = 0;
> +
> + gd->timestamp = 0;
>
> return (0);
return 0;
if you're cleaning this crap up, do it all at once ;-)
> }
>
> /*
> - * timer without interrupts
> + * Get the number of ticks (in CONFIG_SYS_HZ resolution)
> */
> -ulong get_timer(ulong base)
> +unsigned long long get_ticks(void)
> {
> - return get_timer_masked() - base;
> + return get_timer(0);
> }
>
> -void __udelay (unsigned long usec)
> +unsigned long get_timer_raw(void)
> {
> - ulong tmo;
> - ulong start = get_ticks();
> + ulong now = read_timer();
>
> - tmo = usec / 1000;
> - tmo *= (timer_load_val * 100);
> - tmo /= 1000;
> + if (gd->lastdec >= now) {
> + /* normal mode */
> + gd->timestamp += gd->lastdec - now;
> + } else {
> + /* we have an overflow ... */
> + gd->timestamp += gd->lastdec + gd->timer_reset_value - now;
> + }
> + gd->lastdec = now;
>
> - while ((ulong) (get_ticks() - start) < tmo)
> - /*NOP*/;
> + return gd->timestamp;
> }
>
> -ulong get_timer_masked(void)
> +/*
> + * This function is derived from PowerPC code (timebase clock frequency).
> + * On ARM it returns the number of timer ticks per second.
> + */
> +ulong get_tbclk(void)
> {
> - ulong tmr = get_ticks();
> -
> - return tmr / (timer_clk / CONFIG_SYS_HZ);
> + return CONFIG_SYS_HZ;
> }
>
> -void udelay_masked(unsigned long usec)
> +ulong get_timer_masked(void)
> {
> - ulong tmo;
> - ulong endtime;
> - signed long diff;
> -
> - if (usec >= 1000) {
> - tmo = usec / 1000;
> - tmo *= (timer_load_val * 100);
> - tmo /= 1000;
> - } else {
> - tmo = usec * (timer_load_val * 100);
> - tmo /= (1000 * 1000);
> - }
> + unsigned long tmr = get_timer_raw();
>
> - endtime = get_ticks() + tmo;
> + return (tmr * CONFIG_SYS_HZ) / gd->timer_rate_hz;
> +}
>
> - do {
> - ulong now = get_ticks();
> - diff = endtime - now;
> - } while (diff >= 0);
> +ulong get_timer(ulong base)
> +{
> + return get_timer_masked() - base;
> }
>
> -/*
> - * This function is derived from PowerPC code (read timebase as long
> long). - * On ARM it just returns the timer value.
> - */
> -unsigned long long get_ticks(void)
> +void __udelay(unsigned long usec)
> {
> - ulong now = READ_TIMER();
> + unsigned long tmp;
> + unsigned long tmo;
>
> - if (lastdec >= now) {
> - /* normal mode */
> - timestamp += lastdec - now;
> - } else {
> - /* we have an overflow ... */
> - timestamp += lastdec + timer_load_val - now;
> - }
> - lastdec = now;
> + /* convert usec to ticks. */
> + tmo = ((gd->timer_rate_hz / 1000) * usec) / 1000;
>
> - return timestamp;
> -}
> + tmp = get_timer_raw() + tmo; /* get current timestamp */
>
> -/*
> - * This function is derived from PowerPC code (timebase clock frequency).
> - * On ARM it returns the number of timer ticks per second.
> - */
> -ulong get_tbclk(void)
> -{
> - ulong tbclk;
> -
> -#if defined(CONFIG_SMDK2400)
> - tbclk = timer_load_val * 100;
> -#elif defined(CONFIG_SBC2410X) || \
> - defined(CONFIG_SMDK2410) || \
> - defined(CONFIG_S3C2440) || \
> - defined(CONFIG_VCMA9)
> - tbclk = CONFIG_SYS_HZ;
> -#else
> -# error "tbclk not configured"
> -#endif
> -
> - return tbclk;
> + while (get_timer_raw() < tmp) /* loop till event */
> + /*NOP*/;
> }
>
> /*
> diff --git a/arch/arm/include/asm/global_data.h
> b/arch/arm/include/asm/global_data.h
> index fac98d5..b836915 100644
> --- a/arch/arm/include/asm/global_data.h
> +++ b/arch/arm/include/asm/global_data.h
> @@ -67,6 +67,10 @@ typedef struct global_data {
> #ifdef CONFIG_IXP425
> unsigned long timestamp;
> #endif
> +#ifdef CONFIG_S3C24X0
> + unsigned long lastdec;
> + unsigned long timestamp;
> +#endif
I wonder about this change ...
> unsigned long relocaddr; /* Start address of U-Boot in RAM */
> phys_size_t ram_size; /* RAM size */
> unsigned long mon_len; /* monitor len */
Cheers
next prev parent reply other threads:[~2011-10-24 13:58 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-10-23 11:52 [U-Boot] [PATCH] Update s3c24x0 timer implementation Mark Norman
2011-10-23 17:22 ` Wolfgang Denk
2011-10-24 11:27 ` Mark Norman
2011-10-24 13:58 ` Marek Vasut [this message]
2011-10-31 11:27 ` Mark Norman
2011-10-24 19:34 ` Wolfgang Denk
-- strict thread matches above, loose matches on Subject: below --
2011-10-31 10:58 Mark Norman
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=201110241558.36834.marek.vasut@gmail.com \
--to=marek.vasut@gmail.com \
--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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.