[U-Boot] [PATCH v2] arm925t: Fix CONFIG_SYS_HZ to 1000

Let CONFIG_SYS_HZ to have value of 1000 effectively fixing all users of get_timer.
Changes since original version: * Set PTV=2 (divisor 8) for boards using 12MHz timer clock source to improve timer resolution.
Signed-off-by: Ladislav Michl ladis@linux-mips.org
diff --git a/cpu/arm925t/interrupts.c b/cpu/arm925t/interrupts.c index e5c77f7..ec2a978 100644 --- a/cpu/arm925t/interrupts.c +++ b/cpu/arm925t/interrupts.c @@ -1,4 +1,7 @@ /* + * (C) Copyright 2009 + * 2N Telekomunikace, <www.2n.cz> + * * (C) Copyright 2003 * Texas Instruments, <www.ti.com> * @@ -37,7 +40,8 @@ #include <configs/omap1510.h> #include <asm/io.h>
-#define TIMER_LOAD_VAL 0xffffffff +#define TIMER_LOAD_VAL 0xffffffff +#define TIMER_CLOCK (CONFIG_SYS_CLK_FREQ / (2 << CONFIG_SYS_PTV))
static uint32_t timestamp; static uint32_t lastdec; @@ -79,85 +83,41 @@ void set_timer (ulong t) /* delay x useconds AND preserve advance timestamp value */ void udelay (unsigned long usec) { - ulong tmo, tmp; - - if (usec >= 1000) { /* if "big" number, spread normalization to seconds */ - tmo = usec / 1000; /* start to normalize for usec to ticks per sec */ - tmo *= CONFIG_SYS_HZ; /* find number of "ticks" to wait to achieve target */ - tmo /= 1000; /* finish normalize. */ - } else { /* else small number, don't kill it prior to HZ multiply */ - tmo = usec * CONFIG_SYS_HZ; - tmo /= (1000*1000); + int32_t tmo = usec * (TIMER_CLOCK / 1000) / 1000; + uint32_t now, last = __raw_readl(CONFIG_SYS_TIMERBASE + READ_TIM); + + while (tmo > 0) { + now = __raw_readl(CONFIG_SYS_TIMERBASE + READ_TIM); + if (last < now) /* count down timer underflow */ + tmo -= TIMER_LOAD_VAL - now + last; + else + tmo -= last - now; + last = now; } - - tmp = get_timer (0); /* get current timestamp */ - if ((tmo + tmp + 1) < tmp) /* if setting this fordward will roll time stamp */ - reset_timer_masked (); /* reset "advancing" timestamp to 0, set lastdec value */ - else - tmo += tmp; /* else, set advancing stamp wake up time */ - - while (get_timer_masked () < tmo) /* loop till event */ - /*NOP*/; }
void reset_timer_masked (void) { /* reset time */ - lastdec = __raw_readl(CONFIG_SYS_TIMERBASE + READ_TIM); + lastdec = __raw_readl(CONFIG_SYS_TIMERBASE + READ_TIM) / + (TIMER_CLOCK / CONFIG_SYS_HZ); timestamp = 0; /* start "advancing" time stamp from 0 */ }
ulong get_timer_masked (void) { - uint32_t now = __raw_readl(CONFIG_SYS_TIMERBASE + READ_TIM); - - if (lastdec >= now) { /* normal mode (non roll) */ - /* normal mode */ - timestamp += lastdec - now; /* move stamp fordward with absoulte diff ticks */ - } else { /* we have overflow of the count down timer */ - /* nts = ts + ld + (TLV - now) - * ts=old stamp, ld=time that passed before passing through -1 - * (TLV-now) amount of time after passing though -1 - * nts = new "advancing time stamp"...it could also roll and cause problems. - */ - timestamp += lastdec + TIMER_LOAD_VAL - now; - } + uint32_t now = __raw_readl(CONFIG_SYS_TIMERBASE + READ_TIM) / + (TIMER_CLOCK / CONFIG_SYS_HZ); + if (lastdec < now) /* count down timer underflow */ + timestamp += TIMER_LOAD_VAL / (TIMER_CLOCK / CONFIG_SYS_HZ) - + now + lastdec; + else + timestamp += lastdec - now; lastdec = now;
return timestamp; }
-/* waits specified delay value and resets timestamp */ -void udelay_masked (unsigned long usec) -{ -#ifdef CONFIG_INNOVATOROMAP1510 - #define LOOPS_PER_MSEC 60 /* tuned on omap1510 */ - volatile int i, time_remaining = LOOPS_PER_MSEC*usec; - for (i=time_remaining; i>0; i--) { } -#else - - ulong tmo; - ulong endtime; - signed long diff; - - if (usec >= 1000) { /* if "big" number, spread normalization to seconds */ - tmo = usec / 1000; /* start to normalize for usec to ticks per sec */ - tmo *= CONFIG_SYS_HZ; /* find number of "ticks" to wait to achieve target */ - tmo /= 1000; /* finish normalize. */ - } else { /* else small number, don't kill it prior to HZ multiply */ - tmo = usec * CONFIG_SYS_HZ; - tmo /= (1000*1000); - } - - endtime = get_timer_masked () + tmo; - - do { - ulong now = get_timer_masked (); - diff = endtime - now; - } while (diff >= 0); -#endif -} - /* * This function is derived from PowerPC code (read timebase as long long). * On ARM it just returns the timer value. diff --git a/include/configs/SX1.h b/include/configs/SX1.h index caa6592..6149276 100644 --- a/include/configs/SX1.h +++ b/include/configs/SX1.h @@ -135,12 +135,12 @@
#define CONFIG_SYS_LOAD_ADDR 0x10000000 /* default load address */
-/* The 1510 has 3 timers, they can be driven by the RefClk (12Mhz) or by DPLL1. +/* The 1510 has 3 timers, they can be driven by the RefClk (12MHz) or by DPLL1. * This time is further subdivided by a local divisor. */ #define CONFIG_SYS_TIMERBASE OMAP1510_TIMER1_BASE /* use timer 1 */ -#define CONFIG_SYS_PTV 7 /* 2^(PTV+1), divide by 256 */ -#define CONFIG_SYS_HZ ((CONFIG_SYS_CLK_FREQ)/(2 << CONFIG_SYS_PTV)) +#define CONFIG_SYS_PTV 2 /* Divisor: 2^(PTV+1) => 8 */ +#define CONFIG_SYS_HZ 1000
/*----------------------------------------------------------------------- * Stack sizes diff --git a/include/configs/netstar.h b/include/configs/netstar.h index 39560de..5cfee66 100644 --- a/include/configs/netstar.h +++ b/include/configs/netstar.h @@ -222,12 +222,12 @@
#define CONFIG_SYS_LOAD_ADDR PHYS_SDRAM_1 + 0x400000 /* default load address */
-/* The 1510 has 3 timers, they can be driven by the RefClk (12Mhz) or by DPLL1. +/* The 1510 has 3 timers, they can be driven by the RefClk (12MHz) or by DPLL1. * This time is further subdivided by a local divisor. */ #define CONFIG_SYS_TIMERBASE OMAP1510_TIMER1_BASE -#define CONFIG_SYS_PTV 7 /* 2^(pvt+1), divide by 256 */ -#define CONFIG_SYS_HZ ((CONFIG_SYS_CLK_FREQ)/(2 << CONFIG_SYS_PTV)) +#define CONFIG_SYS_PTV 7 +#define CONFIG_SYS_HZ 1000
#define OMAP5910_DPLL_DIV 1 #define OMAP5910_DPLL_MUL ((CONFIG_SYS_CLK_FREQ * \ diff --git a/include/configs/omap1510inn.h b/include/configs/omap1510inn.h index 6c1c5ec..8408209 100644 --- a/include/configs/omap1510inn.h +++ b/include/configs/omap1510inn.h @@ -132,12 +132,12 @@
#define CONFIG_SYS_LOAD_ADDR 0x10000000 /* default load address */
-/* The 1510 has 3 timers, they can be driven by the RefClk (12Mhz) or by DPLL1. +/* The 1510 has 3 timers, they can be driven by the RefClk (12MHz) or by DPLL1. * This time is further subdivided by a local divisor. */ #define CONFIG_SYS_TIMERBASE OMAP1510_TIMER1_BASE /* use timer 1 */ -#define CONFIG_SYS_PTV 7 /* 2^(PTV+1), divide by 256 */ -#define CONFIG_SYS_HZ ((CONFIG_SYS_CLK_FREQ)/(2 << CONFIG_SYS_PTV)) +#define CONFIG_SYS_PTV 2 /* Divisor: 2^(PTV+1) => 8 */ +#define CONFIG_SYS_HZ 1000
/*----------------------------------------------------------------------- * Stack sizes diff --git a/include/configs/voiceblue.h b/include/configs/voiceblue.h index 3f97843..aa8efaa 100644 --- a/include/configs/voiceblue.h +++ b/include/configs/voiceblue.h @@ -210,12 +210,12 @@ #define CONFIG_SYS_MEMTEST_START PHYS_SDRAM_1 #define CONFIG_SYS_MEMTEST_END PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE - PHYS_SDRAM_1_RESERVED
-/* The 1510 has 3 timers, they can be driven by the RefClk (12Mhz) or by DPLL1. +/* The 1510 has 3 timers, they can be driven by the RefClk (12MHz) or by DPLL1. * This time is further subdivided by a local divisor. */ #define CONFIG_SYS_TIMERBASE OMAP1510_TIMER1_BASE #define CONFIG_SYS_PTV 7 /* 2^(PTV+1), divide by 256 */ -#define CONFIG_SYS_HZ ((CONFIG_SYS_CLK_FREQ)/(2 << CONFIG_SYS_PTV)) +#define CONFIG_SYS_HZ 1000
#define OMAP5910_DPLL_DIV 1 #define OMAP5910_DPLL_MUL ((CONFIG_SYS_CLK_FREQ * \

Ladislav Michl wrote:
Let CONFIG_SYS_HZ to have value of 1000 effectively fixing all users of get_timer.
Changes since original version:
- Set PTV=2 (divisor 8) for boards using 12MHz timer clock source to improve timer resolution.
Signed-off-by: Ladislav Michl ladis@linux-mips.org
Acked-by: Dirk Behme dirk.behme@googlemail.com
diff --git a/cpu/arm925t/interrupts.c b/cpu/arm925t/interrupts.c index e5c77f7..ec2a978 100644 --- a/cpu/arm925t/interrupts.c +++ b/cpu/arm925t/interrupts.c @@ -1,4 +1,7 @@ /*
- (C) Copyright 2009
- 2N Telekomunikace, <www.2n.cz>
- (C) Copyright 2003
- Texas Instruments, <www.ti.com>
@@ -37,7 +40,8 @@ #include <configs/omap1510.h> #include <asm/io.h>
-#define TIMER_LOAD_VAL 0xffffffff +#define TIMER_LOAD_VAL 0xffffffff +#define TIMER_CLOCK (CONFIG_SYS_CLK_FREQ / (2 << CONFIG_SYS_PTV))
static uint32_t timestamp; static uint32_t lastdec; @@ -79,85 +83,41 @@ void set_timer (ulong t) /* delay x useconds AND preserve advance timestamp value */ void udelay (unsigned long usec) {
- ulong tmo, tmp;
- if (usec >= 1000) { /* if "big" number, spread normalization to seconds */
tmo = usec / 1000; /* start to normalize for usec to ticks per sec */
tmo *= CONFIG_SYS_HZ; /* find number of "ticks" to wait to achieve target */
tmo /= 1000; /* finish normalize. */
- } else { /* else small number, don't kill it prior to HZ multiply */
tmo = usec * CONFIG_SYS_HZ;
tmo /= (1000*1000);
- int32_t tmo = usec * (TIMER_CLOCK / 1000) / 1000;
- uint32_t now, last = __raw_readl(CONFIG_SYS_TIMERBASE + READ_TIM);
- while (tmo > 0) {
now = __raw_readl(CONFIG_SYS_TIMERBASE + READ_TIM);
if (last < now) /* count down timer underflow */
tmo -= TIMER_LOAD_VAL - now + last;
else
tmo -= last - now;
}last = now;
- tmp = get_timer (0); /* get current timestamp */
- if ((tmo + tmp + 1) < tmp) /* if setting this fordward will roll time stamp */
reset_timer_masked (); /* reset "advancing" timestamp to 0, set lastdec value */
- else
tmo += tmp; /* else, set advancing stamp wake up time */
- while (get_timer_masked () < tmo) /* loop till event */
/*NOP*/;
}
void reset_timer_masked (void) { /* reset time */
- lastdec = __raw_readl(CONFIG_SYS_TIMERBASE + READ_TIM);
- lastdec = __raw_readl(CONFIG_SYS_TIMERBASE + READ_TIM) /
timestamp = 0; /* start "advancing" time stamp from 0 */(TIMER_CLOCK / CONFIG_SYS_HZ);
}
ulong get_timer_masked (void) {
- uint32_t now = __raw_readl(CONFIG_SYS_TIMERBASE + READ_TIM);
- if (lastdec >= now) { /* normal mode (non roll) */
/* normal mode */
timestamp += lastdec - now; /* move stamp fordward with absoulte diff ticks */
- } else { /* we have overflow of the count down timer */
/* nts = ts + ld + (TLV - now)
* ts=old stamp, ld=time that passed before passing through -1
* (TLV-now) amount of time after passing though -1
* nts = new "advancing time stamp"...it could also roll and cause problems.
*/
timestamp += lastdec + TIMER_LOAD_VAL - now;
- }
uint32_t now = __raw_readl(CONFIG_SYS_TIMERBASE + READ_TIM) /
(TIMER_CLOCK / CONFIG_SYS_HZ);
if (lastdec < now) /* count down timer underflow */
timestamp += TIMER_LOAD_VAL / (TIMER_CLOCK / CONFIG_SYS_HZ) -
now + lastdec;
else
timestamp += lastdec - now;
lastdec = now;
return timestamp;
}
-/* waits specified delay value and resets timestamp */ -void udelay_masked (unsigned long usec) -{ -#ifdef CONFIG_INNOVATOROMAP1510
- #define LOOPS_PER_MSEC 60 /* tuned on omap1510 */
- volatile int i, time_remaining = LOOPS_PER_MSEC*usec;
- for (i=time_remaining; i>0; i--) { }
-#else
- ulong tmo;
- ulong endtime;
- signed long diff;
- if (usec >= 1000) { /* if "big" number, spread normalization to seconds */
tmo = usec / 1000; /* start to normalize for usec to ticks per sec */
tmo *= CONFIG_SYS_HZ; /* find number of "ticks" to wait to achieve target */
tmo /= 1000; /* finish normalize. */
- } else { /* else small number, don't kill it prior to HZ multiply */
tmo = usec * CONFIG_SYS_HZ;
tmo /= (1000*1000);
- }
- endtime = get_timer_masked () + tmo;
- do {
ulong now = get_timer_masked ();
diff = endtime - now;
- } while (diff >= 0);
-#endif -}
/*
- This function is derived from PowerPC code (read timebase as long long).
- On ARM it just returns the timer value.
diff --git a/include/configs/SX1.h b/include/configs/SX1.h index caa6592..6149276 100644 --- a/include/configs/SX1.h +++ b/include/configs/SX1.h @@ -135,12 +135,12 @@
#define CONFIG_SYS_LOAD_ADDR 0x10000000 /* default load address */
-/* The 1510 has 3 timers, they can be driven by the RefClk (12Mhz) or by DPLL1. +/* The 1510 has 3 timers, they can be driven by the RefClk (12MHz) or by DPLL1.
- This time is further subdivided by a local divisor.
*/ #define CONFIG_SYS_TIMERBASE OMAP1510_TIMER1_BASE /* use timer 1 */ -#define CONFIG_SYS_PTV 7 /* 2^(PTV+1), divide by 256 */ -#define CONFIG_SYS_HZ ((CONFIG_SYS_CLK_FREQ)/(2 << CONFIG_SYS_PTV)) +#define CONFIG_SYS_PTV 2 /* Divisor: 2^(PTV+1) => 8 */ +#define CONFIG_SYS_HZ 1000
/*-----------------------------------------------------------------------
- Stack sizes
diff --git a/include/configs/netstar.h b/include/configs/netstar.h index 39560de..5cfee66 100644 --- a/include/configs/netstar.h +++ b/include/configs/netstar.h @@ -222,12 +222,12 @@
#define CONFIG_SYS_LOAD_ADDR PHYS_SDRAM_1 + 0x400000 /* default load address */
-/* The 1510 has 3 timers, they can be driven by the RefClk (12Mhz) or by DPLL1. +/* The 1510 has 3 timers, they can be driven by the RefClk (12MHz) or by DPLL1.
- This time is further subdivided by a local divisor.
*/ #define CONFIG_SYS_TIMERBASE OMAP1510_TIMER1_BASE -#define CONFIG_SYS_PTV 7 /* 2^(pvt+1), divide by 256 */ -#define CONFIG_SYS_HZ ((CONFIG_SYS_CLK_FREQ)/(2 << CONFIG_SYS_PTV)) +#define CONFIG_SYS_PTV 7 +#define CONFIG_SYS_HZ 1000
#define OMAP5910_DPLL_DIV 1 #define OMAP5910_DPLL_MUL ((CONFIG_SYS_CLK_FREQ * \ diff --git a/include/configs/omap1510inn.h b/include/configs/omap1510inn.h index 6c1c5ec..8408209 100644 --- a/include/configs/omap1510inn.h +++ b/include/configs/omap1510inn.h @@ -132,12 +132,12 @@
#define CONFIG_SYS_LOAD_ADDR 0x10000000 /* default load address */
-/* The 1510 has 3 timers, they can be driven by the RefClk (12Mhz) or by DPLL1. +/* The 1510 has 3 timers, they can be driven by the RefClk (12MHz) or by DPLL1.
- This time is further subdivided by a local divisor.
*/ #define CONFIG_SYS_TIMERBASE OMAP1510_TIMER1_BASE /* use timer 1 */ -#define CONFIG_SYS_PTV 7 /* 2^(PTV+1), divide by 256 */ -#define CONFIG_SYS_HZ ((CONFIG_SYS_CLK_FREQ)/(2 << CONFIG_SYS_PTV)) +#define CONFIG_SYS_PTV 2 /* Divisor: 2^(PTV+1) => 8 */ +#define CONFIG_SYS_HZ 1000
/*-----------------------------------------------------------------------
- Stack sizes
diff --git a/include/configs/voiceblue.h b/include/configs/voiceblue.h index 3f97843..aa8efaa 100644 --- a/include/configs/voiceblue.h +++ b/include/configs/voiceblue.h @@ -210,12 +210,12 @@ #define CONFIG_SYS_MEMTEST_START PHYS_SDRAM_1 #define CONFIG_SYS_MEMTEST_END PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE - PHYS_SDRAM_1_RESERVED
-/* The 1510 has 3 timers, they can be driven by the RefClk (12Mhz) or by DPLL1. +/* The 1510 has 3 timers, they can be driven by the RefClk (12MHz) or by DPLL1.
- This time is further subdivided by a local divisor.
*/ #define CONFIG_SYS_TIMERBASE OMAP1510_TIMER1_BASE #define CONFIG_SYS_PTV 7 /* 2^(PTV+1), divide by 256 */ -#define CONFIG_SYS_HZ ((CONFIG_SYS_CLK_FREQ)/(2 << CONFIG_SYS_PTV)) +#define CONFIG_SYS_HZ 1000
#define OMAP5910_DPLL_DIV 1 #define OMAP5910_DPLL_MUL ((CONFIG_SYS_CLK_FREQ * \

On 01:12 Wed 22 Apr , Ladislav Michl wrote:
Let CONFIG_SYS_HZ to have value of 1000 effectively fixing all users of get_timer.
Changes since original version:
- Set PTV=2 (divisor 8) for boards using 12MHz timer clock source to improve timer resolution.
please put in the commit message & code the timer resolution & precision and please specify on which board you test it in the commit message
Best Regards, J.

On Thu, Apr 23, 2009 at 09:34:21AM +0200, Jean-Christophe PLAGNIOL-VILLARD wrote:
On 01:12 Wed 22 Apr , Ladislav Michl wrote:
Let CONFIG_SYS_HZ to have value of 1000 effectively fixing all users of get_timer.
Changes since original version:
- Set PTV=2 (divisor 8) for boards using 12MHz timer clock source to improve timer resolution.
please put in the commit message & code the timer resolution & precision and please specify on which board you test it in the commit message
Okay. To eliminate human factor, I will use a scope hooked on gpio pin (we all love exact methods, don't we?) and include those results in the commit message. However, I cannot do this sooner than at next week. Patch will appear as v3 on mailing list.
Best regards, ladis

On 12:50 Thu 23 Apr , Ladislav Michl wrote:
On Thu, Apr 23, 2009 at 09:34:21AM +0200, Jean-Christophe PLAGNIOL-VILLARD wrote:
On 01:12 Wed 22 Apr , Ladislav Michl wrote:
Let CONFIG_SYS_HZ to have value of 1000 effectively fixing all users of get_timer.
Changes since original version:
- Set PTV=2 (divisor 8) for boards using 12MHz timer clock source to improve timer resolution.
please put in the commit message & code the timer resolution & precision and please specify on which board you test it in the commit message
Okay. To eliminate human factor, I will use a scope hooked on gpio pin (we all love exact methods, don't we?) and include those results in the commit message. However, I cannot do this sooner than at next week. Patch will appear as v3 on mailing list.
Do you have any idea when the V3 will availlable?
Best Regards, J.

Dear Jean-Christophe,
Jean-Christophe PLAGNIOL-VILLARD wrote:
On 01:12 Wed 22 Apr , Ladislav Michl wrote:
Let CONFIG_SYS_HZ to have value of 1000 effectively fixing all users of get_timer.
Changes since original version:
- Set PTV=2 (divisor 8) for boards using 12MHz timer clock source to improve timer resolution.
please put in the commit message & code the timer resolution & precision and please specify on which board you test it in the commit message
It would be nice if we could get proper commit messages from you in future then, too. ;)
Dirk
P.S.: E.g.
http://lists.denx.de/pipermail/u-boot/2009-March/049743.html http://lists.denx.de/pipermail/u-boot/2009-March/049871.html http://lists.denx.de/pipermail/u-boot/2009-March/049804.html http://lists.denx.de/pipermail/u-boot/2009-March/049741.html
participants (3)
-
Dirk Behme
-
Jean-Christophe PLAGNIOL-VILLARD
-
Ladislav Michl