From: Matthias Kaehlcke <matthias@kaehlcke.net>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 2/2 rev2] ep93xx: Refactoring of timer code
Date: Wed, 24 Feb 2010 00:22:09 +0100 [thread overview]
Message-ID: <20100223232209.GR20201@darwin> (raw)
In-Reply-To: <7ee75976e78e2f82b4163fe1ff4233a850d4393c.1266966938.git.matthias@kaehlcke.net>
ep93xx: Refactoring of the timer code, including the following changes
* use a free running timer instead of a periodical one
* use unsigned long long for total number of ticks
* hold the timer state in a structure instead of separate variables
* increment the timer counter instead of decrementing it
* remove unused function udelay_masked()
* remove unused function set_timer()
Signed-off-by: Matthias Kaehlcke <matthias@kaehlcke.net>
---
Changes with regard to rev1:
* use TIMER_FREQ directly instead of recalculating it with rounding errors
cpu/arm920t/ep93xx/timer.c | 70 ++++++++++++++++---------------------------
1 files changed, 26 insertions(+), 44 deletions(-)
diff --git a/cpu/arm920t/ep93xx/timer.c b/cpu/arm920t/ep93xx/timer.c
index 98c759c..b1a01a0 100644
--- a/cpu/arm920t/ep93xx/timer.c
+++ b/cpu/arm920t/ep93xx/timer.c
@@ -34,16 +34,18 @@
#include <div64.h>
#define TIMER_CLKSEL (1 << 3)
-#define TIMER_MODE (1 << 6)
#define TIMER_ENABLE (1 << 7)
-#define TIMER_FREQ 508469
-#define TIMER_LOAD_VAL (TIMER_FREQ / CONFIG_SYS_HZ)
+#define TIMER_FREQ 508469
+#define TIMER_MAX_VAL 0xFFFFFFFF
-static ulong timestamp;
-static ulong lastdec;
+static struct ep93xx_timer
+{
+ unsigned long long ticks;
+ unsigned long last_update;
+} timer;
-static inline unsigned long clk_to_systicks(unsigned long clk_ticks)
+static inline unsigned long clk_to_systicks(unsigned long long clk_ticks)
{
unsigned long long sys_ticks = (clk_ticks * CONFIG_SYS_HZ);
do_div(sys_ticks, TIMER_FREQ);
@@ -57,10 +59,10 @@ static inline unsigned long usecs_to_ticks(unsigned long usecs)
if (usecs >= 1000) {
ticks = usecs / 1000;
- ticks *= (TIMER_LOAD_VAL * CONFIG_SYS_HZ);
+ ticks *= TIMER_FREQ;
ticks /= 1000;
} else {
- ticks = usecs * TIMER_LOAD_VAL * CONFIG_SYS_HZ;
+ ticks = usecs * TIMER_FREQ;
ticks /= (1000 * 1000);
}
@@ -71,7 +73,7 @@ static inline unsigned long read_timer(void)
{
struct timer_regs *timer = (struct timer_regs *)TIMER_BASE;
- return readl(&timer->timer3.value);
+ return TIMER_MAX_VAL - readl(&timer->timer3.value);
}
/*
@@ -81,17 +83,15 @@ unsigned long long get_ticks(void)
{
const unsigned long now = read_timer();
- if (lastdec >= now) {
- /* normal mode */
- timestamp += lastdec - now;
- } else {
- /* we have an overflow ... */
- timestamp += lastdec + TIMER_LOAD_VAL - now;
- }
+ if (now >= timer.last_update)
+ timer.ticks += now - timer.last_update;
+ else
+ /* an overflow occurred */
+ timer.ticks += TIMER_MAX_VAL - timer.last_update + now;
- lastdec = now;
+ timer.last_update = now;
- return timestamp;
+ return timer.ticks;
}
unsigned long get_timer_masked(void)
@@ -106,8 +106,8 @@ unsigned long get_timer(unsigned long base)
void reset_timer_masked(void)
{
- lastdec = read_timer();
- timestamp = 0;
+ timer.last_update = read_timer();
+ timer.ticks = 0;
}
void reset_timer(void)
@@ -115,28 +115,11 @@ void reset_timer(void)
reset_timer_masked();
}
-void set_timer(unsigned long t)
-{
- timestamp = t;
-}
-
void __udelay(unsigned long usec)
{
- const unsigned long ticks = usecs_to_ticks(usec);
- const unsigned long target = clk_to_systicks(ticks) + get_timer(0);
-
- while (get_timer_masked() < target)
- /* noop */;
-}
-
-void udelay_masked(unsigned long usec)
-{
- const unsigned long ticks = usecs_to_ticks(usec);
- const unsigned long target = clk_to_systicks(ticks) + get_timer(0);
-
- reset_timer_masked();
+ const unsigned long target = get_ticks() + usecs_to_ticks(usec);
- while (get_timer_masked() < target)
+ while (get_ticks() < target)
/* noop */;
}
@@ -147,12 +130,11 @@ int timer_init(void)
/* use timer 3 with 508KHz and free running */
writel(TIMER_CLKSEL, &timer->timer3.control);
- /* auto load, manual update of Timer 3 */
- lastdec = TIMER_LOAD_VAL;
- writel(TIMER_LOAD_VAL, &timer->timer3.load);
+ /* set initial timer value 3 */
+ writel(TIMER_MAX_VAL, &timer->timer3.load);
- /* Enable the timer and periodic mode */
- writel(TIMER_ENABLE | TIMER_MODE | TIMER_CLKSEL,
+ /* Enable the timer */
+ writel(TIMER_ENABLE | TIMER_CLKSEL,
&timer->timer3.control);
reset_timer_masked();
--
1.6.5
next parent reply other threads:[~2010-02-23 23:22 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <7ee75976e78e2f82b4163fe1ff4233a850d4393c.1266966938.git.matthias@kaehlcke.net>
2010-02-23 23:22 ` Matthias Kaehlcke [this message]
2010-02-25 15:54 ` [U-Boot] [PATCH 2/2 rev2] ep93xx: Refactoring of timer code Tom
2010-02-25 18:15 ` Matthias Kaehlcke
2010-02-25 19:22 ` Alessandro Rubini
2010-02-25 19:47 ` Matthias Kaehlcke
2010-02-26 0:13 ` Tom
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=20100223232209.GR20201@darwin \
--to=matthias@kaehlcke.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