Skip to contentSkip to conversation

arm: a320 timer: move static data to global_data struct

PATCH Superseded ratbert.chuang at gmail.com 4 participants 8 messages Nov 1, 2010 – Jan 24, 2011 Arm (32-bit)

lore
Share & tools
lore
#0 lore raw

PATCH 1/2 arm: a320 timer: move static data to global_data struct

From: Po-Yu Chuang <[email protected]>

timer.c used static data and are called before relocation. Move all static variables into global_data structure. Also cleanup timer.c from unused stubs and make it truly use 64 bit tick values.

Based on Reinhard Meyer <[email protected]>'s patch 5dca710a3d7703e41da0e9894f2d71f9e25bea6b

---
 arch/arm/cpu/arm920t/a320/timer.c  |  137 ++++++++++++++----------------------
 arch/arm/include/asm/global_data.h |    5 ++
 board/faraday/a320evb/config.mk    |   35 ---------
 include/configs/a320evb.h          |    2 +
 4 files changed, 59 insertions(+), 120 deletions(-)
 delete mode 100644 board/faraday/a320evb/config.mk
arch/arm/cpu/arm920t/a320/timer.c +52 -85
index d2e316f..ac48328 100644
@@ -18,10 +18,13 @@
  */
 
 #include <common.h>
+#include <div64.h>
 #include <asm/io.h>
 #include <asm/arch/ftpmu010.h>
 #include <asm/arch/fttmr010.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
 static ulong timestamp;
 static ulong lastdec;
 
@@ -31,6 +34,22 @@ static struct ftpmu010 *pmu = (struct ftpmu010 *)CONFIG_FTPMU010_BASE;
 #define TIMER_CLOCK	32768
 #define TIMER_LOAD_VAL	0xffffffff
 
+static inline unsigned long long tick_to_time(unsigned long long tick)
+{
+	tick *= CONFIG_SYS_HZ;
+	do_div(tick, TIMER_CLOCK);
+
+	return tick;
+}
+
+static inline unsigned long long usec_to_tick(unsigned long long usec)
+{
+	usec *= TIMER_CLOCK;
+	do_div(usec, 1000000);
+
+	return TIMER_LOAD_VAL - usec;
+}
+
 int timer_init(void)
 {
 	unsigned int oscc;
@@ -76,115 +95,63 @@ int timer_init(void)
 	cr |= FTTMR010_TM3_ENABLE;
 	writel(cr, &tmr->cr);
 
-	/* init the timestamp and lastdec value */
-	reset_timer_masked();
+	gd->tbu = gd->tbl = 0;
 
 	return 0;
 }
 
 /*
- * timer without interrupts
- */
-
-/*
- * reset time
+ * Get the current 64 bit timer tick count
  */
-void reset_timer_masked(void)
+unsigned long long get_ticks(void)
 {
-	/* capure current decrementer value time */
-	lastdec = readl(&tmr->timer3_counter) / (TIMER_CLOCK / CONFIG_SYS_HZ);
-	timestamp = 0;		/* start "advancing" time stamp from 0 */
-
-	debug("%s(): lastdec = %lx\n", __func__, lastdec);
-}
+	ulong now = TIMER_LOAD_VAL - readl(&tmr->timer3_counter);
 
-void reset_timer(void)
-{
 	debug("%s()\n", __func__);
-	reset_timer_masked();
-}
 
-/*
- * return timer ticks
- */
-ulong get_timer_masked(void)
-{
-	/* current tick value */
-	ulong now = readl(&tmr->timer3_counter) / (TIMER_CLOCK / CONFIG_SYS_HZ);
-
-	debug("%s(): now = %lx, lastdec = %lx\n", __func__, now, lastdec);
-
-	if (lastdec >= now) {
-		/*
-		 * normal mode (non roll)
-		 * move stamp fordward with absoulte diff ticks
-		 */
-		timestamp += lastdec - now;
-	} 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;
-	}
-
-	lastdec = now;
-
-	debug("%s() returns %lx\n", __func__, timestamp);
-
-	return timestamp;
-}
-
-/*
- * return difference between timer ticks and base
- */
-ulong get_timer(ulong base)
-{
-	debug("%s(%lx)\n", __func__, base);
-	return get_timer_masked() - base;
-}
-
-void set_timer(ulong t)
-{
-	debug("%s(%lx)\n", __func__, t);
-	timestamp = t;
+	/* increment tbu if tbl has rolled over */
+	if (now < gd->tbl)
+		gd->tbu++;
+	gd->tbl = now;
+	return (((unsigned long long)gd->tbu) << 32) | gd->tbl;
 }
 
 /* delay x useconds AND preserve advance timestamp value */
 void __udelay(unsigned long usec)
 {
-	long tmo = usec * (TIMER_CLOCK / 1000) / 1000;
-	unsigned long now, last = readl(&tmr->timer3_counter);
-
-	debug("%s(%lu)\n", __func__, usec);
-	while (tmo > 0) {
-		now = readl(&tmr->timer3_counter);
-		if (now > last) /* count down timer overflow */
-			tmo -= TIMER_LOAD_VAL + last - now;
-		else
-			tmo -= last - now;
-		last = now;
-	}
+	unsigned long long tmp;
+	ulong tmo;
+
+	tmo = usec_to_tick(usec);
+	tmp = get_ticks() + tmo;	/* get current timestamp */
+
+	while (get_ticks() < tmp)	/* loop till event */
+		;
 }
 
 /*
- * This function is derived from PowerPC code (read timebase as long long).
- * On ARM it just returns the timer value.
+ * reset_timer() and get_timer(base) are a pair of functions that are used by
+ * some timeout/sleep mechanisms in u-boot.
+ *
+ * reset_timer() marks the current time as epoch and
+ * get_timer(base) works relative to that epoch.
+ *
+ * The time is used in CONFIG_SYS_HZ units!
  */
-unsigned long long get_ticks(void)
+void reset_timer(void)
 {
 	debug("%s()\n", __func__);
-	return get_timer(0);
+	gd->timer_reset_value = get_ticks();
+}
+
+ulong get_timer(ulong base)
+{
+	debug("%s(%lx)\n", __func__, base);
+	return tick_to_time(get_ticks() - gd->timer_reset_value) - base;
 }
 
 /*
- * This function is derived from PowerPC code (timebase clock frequency).
- * On ARM it returns the number of timer ticks per second.
+ * Return the number of timer ticks per second.
  */
 ulong get_tbclk(void)
 {
arch/arm/include/asm/global_data.h +5 -0
index ada3fbb..04c1564 100644
@@ -61,6 +61,11 @@ typedef	struct	global_data {
 	unsigned long	tbu;
 	unsigned long long	timer_reset_value;
 #endif
+#ifdef CONFIG_FTTMR010_BASE
+	unsigned long	tbl;
+	unsigned long	tbu;
+	unsigned long long	timer_reset_value;
+#endif
 	unsigned long	relocaddr;	/* Start address of U-Boot in RAM */
 	phys_size_t	ram_size;	/* RAM size */
 	unsigned long	mon_len;	/* monitor len */
board/faraday/a320evb/config.mk deleted +0 -35
deleted file mode 100644
index b751d0d..0000000
@@ -1,35 +0,0 @@
-#
-# (C) Copyright 2009 Faraday Technology
-# Po-Yu Chuang <[email protected]>
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation; either version 2 of
-# the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
-# MA 02111-1307 USA
-#
-
-# Faraday A320 board with FA526/FA626TE/ARM926EJ-S cpus
-#
-# see http://www.faraday-tech.com/ for more information
-
-# A320 has 1 bank of 64 MB DRAM
-#
-# 1000'0000 to 1400'0000
-#
-# Linux-Kernel is expected to be at 1000'8000, entry 1000'8000
-#
-# we load ourself to 13f8'0000
-#
-# download area is 1200'0000
-
-CONFIG_SYS_TEXT_BASE = 0x13f80000
include/configs/a320evb.h +2 -0
index f67cf06..0284d40 100644
@@ -148,6 +148,8 @@
 #define CONFIG_SYS_MEMTEST_START	0x10000000
 #define CONFIG_SYS_MEMTEST_END		0x13F00000
 
+#define CONFIG_SYS_TEXT_BASE		0
+
 /*-----------------------------------------------------------------------
  * Static memory controller configuration
  */
Signature · 1 line
1.6.3.3
#1 lore raw

PATCH 1/2 arm: a320 timer: move static data to global_data struct

Dear ratbert.chuang,

Quoted 10 lines

From: Po-Yu Chuang <[email protected]>

timer.c used static data and are called before relocation. Move all static variables into global_data structure. Also cleanup timer.c from unused stubs and make it truly use 64 bit tick values.

Based on Reinhard Meyer <[email protected]>'s patch 5dca710a3d7703e41da0e9894f2d71f9e25bea6b

Can you hold on with this for a few days?
Recent discussions about the timer issue have revealed that there are potential improvements and mainly udelay() needs a minor fix to prevent a potential failure after a few billion years.

I have improvements in mind and will implement them in a few days, and would appreciate if not so perfect code would not be copied and spread before that ;)

Best Regards,
Reinhard

#2 lore raw

PATCH 1/2 arm: a320 timer: move static data to global_data struct

Dear Reinhard,

Quoted 12 lines · Reinhard Meyer

Dear ratbert.chuang,

Quoted 10 lines

From: Po-Yu Chuang <[email protected]>

timer.c used static data and are called before relocation. Move all static variables into global_data structure. Also cleanup timer.c from unused stubs and make it truly use 64 bit tick values.

Based on Reinhard Meyer <[email protected]>'s patch 5dca710a3d7703e41da0e9894f2d71f9e25bea6b

Quoted 8 lines

Can you hold on with this for a few days?
Recent discussions about the timer issue have revealed that there are potential improvements and mainly udelay() needs a minor fix to prevent a potential failure after a few billion years.

I have improvements in mind and will implement them in a few days, and would appreciate if not so perfect code would not be copied and spread before that ;)

Sure.
I'll wait for your patch and resubmit then. :-)

Best Regards,
Po-Yu Chuang

#3 lore raw

PATCH v2 1/2 arm: a320 timer: move static data to global_data struct

From: Po-Yu Chuang <[email protected]>

timer.c used static data and are called before relocation. Move all static variables into global_data structure. Also cleanup timer.c from unused stubs and make it truly use 64 bit tick values.

Based on Reinhard Meyer <[email protected]>'s patch 5dca710a3d7703e41da0e9894f2d71f9e25bea6b

---
v2:
rebase
use gd->timer_rate_hz.
remove unused global variable timestamp and lastdec. move register bases to local variables

 arch/arm/cpu/arm920t/a320/timer.c |  147 ++++++++++++++-----------------------
 1 files changed, 56 insertions(+), 91 deletions(-)
arch/arm/cpu/arm920t/a320/timer.c +56 -91
index d2e316f..5af94c2 100644
@@ -18,21 +18,36 @@
  */
 
 #include <common.h>
+#include <div64.h>
 #include <asm/io.h>
 #include <asm/arch/ftpmu010.h>
 #include <asm/arch/fttmr010.h>
 
-static ulong timestamp;
-static ulong lastdec;
-
-static struct fttmr010 *tmr = (struct fttmr010 *)CONFIG_FTTMR010_BASE;
-static struct ftpmu010 *pmu = (struct ftpmu010 *)CONFIG_FTPMU010_BASE;
+DECLARE_GLOBAL_DATA_PTR;
 
 #define TIMER_CLOCK	32768
 #define TIMER_LOAD_VAL	0xffffffff
 
+static inline unsigned long long tick_to_time(unsigned long long tick)
+{
+	tick *= CONFIG_SYS_HZ;
+	do_div(tick, gd->timer_rate_hz);
+
+	return tick;
+}
+
+static inline unsigned long long usec_to_tick(unsigned long long usec)
+{
+	usec *= gd->timer_rate_hz;
+	do_div(usec, 1000000);
+
+	return usec;
+}
+
 int timer_init(void)
 {
+	struct fttmr010 *tmr = (struct fttmr010 *)CONFIG_FTTMR010_BASE;
+	struct ftpmu010 *pmu = (struct ftpmu010 *)CONFIG_FTPMU010_BASE;
 	unsigned int oscc;
 	unsigned int cr;
 
@@ -76,118 +91,68 @@ int timer_init(void)
 	cr |= FTTMR010_TM3_ENABLE;
 	writel(cr, &tmr->cr);
 
-	/* init the timestamp and lastdec value */
-	reset_timer_masked();
+	gd->timer_rate_hz = TIMER_CLOCK;
+	gd->tbu = gd->tbl = 0;
 
 	return 0;
 }
 
 /*
- * timer without interrupts
- */
-
-/*
- * reset time
+ * Get the current 64 bit timer tick count
  */
-void reset_timer_masked(void)
+unsigned long long get_ticks(void)
 {
-	/* capure current decrementer value time */
-	lastdec = readl(&tmr->timer3_counter) / (TIMER_CLOCK / CONFIG_SYS_HZ);
-	timestamp = 0;		/* start "advancing" time stamp from 0 */
-
-	debug("%s(): lastdec = %lx\n", __func__, lastdec);
-}
+	struct fttmr010 *tmr = (struct fttmr010 *)CONFIG_FTTMR010_BASE;
+	ulong now = TIMER_LOAD_VAL - readl(&tmr->timer3_counter);
 
-void reset_timer(void)
-{
 	debug("%s()\n", __func__);
-	reset_timer_masked();
-}
 
-/*
- * return timer ticks
- */
-ulong get_timer_masked(void)
-{
-	/* current tick value */
-	ulong now = readl(&tmr->timer3_counter) / (TIMER_CLOCK / CONFIG_SYS_HZ);
-
-	debug("%s(): now = %lx, lastdec = %lx\n", __func__, now, lastdec);
-
-	if (lastdec >= now) {
-		/*
-		 * normal mode (non roll)
-		 * move stamp fordward with absoulte diff ticks
-		 */
-		timestamp += lastdec - now;
-	} 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;
-	}
-
-	lastdec = now;
-
-	debug("%s() returns %lx\n", __func__, timestamp);
-
-	return timestamp;
-}
-
-/*
- * return difference between timer ticks and base
- */
-ulong get_timer(ulong base)
-{
-	debug("%s(%lx)\n", __func__, base);
-	return get_timer_masked() - base;
-}
-
-void set_timer(ulong t)
-{
-	debug("%s(%lx)\n", __func__, t);
-	timestamp = t;
+	/* increment tbu if tbl has rolled over */
+	if (now < gd->tbl)
+		gd->tbu++;
+	gd->tbl = now;
+	return (((unsigned long long)gd->tbu) << 32) | gd->tbl;
 }
 
 /* delay x useconds AND preserve advance timestamp value */
 void __udelay(unsigned long usec)
 {
-	long tmo = usec * (TIMER_CLOCK / 1000) / 1000;
-	unsigned long now, last = readl(&tmr->timer3_counter);
-
-	debug("%s(%lu)\n", __func__, usec);
-	while (tmo > 0) {
-		now = readl(&tmr->timer3_counter);
-		if (now > last) /* count down timer overflow */
-			tmo -= TIMER_LOAD_VAL + last - now;
-		else
-			tmo -= last - now;
-		last = now;
-	}
+	unsigned long long tmp;
+	ulong tmo;
+
+	tmo = usec_to_tick(usec);
+	tmp = get_ticks() + tmo;	/* get current timestamp */
+
+	while (get_ticks() < tmp)	/* loop till event */
+		;
 }
 
 /*
- * This function is derived from PowerPC code (read timebase as long long).
- * On ARM it just returns the timer value.
+ * reset_timer() and get_timer(base) are a pair of functions that are used by
+ * some timeout/sleep mechanisms in u-boot.
+ *
+ * reset_timer() marks the current time as epoch and
+ * get_timer(base) works relative to that epoch.
+ *
+ * The time is used in CONFIG_SYS_HZ units!
  */
-unsigned long long get_ticks(void)
+void reset_timer(void)
 {
 	debug("%s()\n", __func__);
-	return get_timer(0);
+	gd->timer_reset_value = get_ticks();
+}
+
+ulong get_timer(ulong base)
+{
+	debug("%s(%lx)\n", __func__, base);
+	return tick_to_time(get_ticks() - gd->timer_reset_value) - base;
 }
 
 /*
- * This function is derived from PowerPC code (timebase clock frequency).
- * On ARM it returns the number of timer ticks per second.
+ * Return the number of timer ticks per second.
  */
 ulong get_tbclk(void)
 {
 	debug("%s()\n", __func__);
-	return CONFIG_SYS_HZ;
+	return gd->timer_rate_hz;
 }
Signature · 1 line
1.6.3.3
#4 lore raw

PATCH v2 1/2 arm: a320 timer: move static data to global_data struct

Dear Wolfgang,

Quoted 17 lines · Po-Yu Chuang

From: Po-Yu Chuang <[email protected]>

timer.c used static data and are called before relocation. Move all static variables into global_data structure. Also cleanup timer.c from unused stubs and make it truly use 64 bit tick values.

Based on Reinhard Meyer <[email protected]>'s patch 5dca710a3d7703e41da0e9894f2d71f9e25bea6b

---
v2:
rebase
use gd->timer_rate_hz.
remove unused global variable timestamp and lastdec. move register bases to local variables

Quoted 2 lines

?arch/arm/cpu/arm920t/a320/timer.c | ?147 ++++++++++++++----------------------- ?1 files changed, 56 insertions(+), 91 deletions(-)

Would you please check this patch series?
Or should I rebase and resubmit?

best regards,
Po-Yu Chuang

#5 lore raw

PATCH v2 1/2 arm: a320 timer: move static data to global_data struct

Dear Po-Yu Chuang,

Quoted 6 lines · In message <[email protected]> you…
Quoted 6 lines

From: Po-Yu Chuang <[email protected]>

timer.c used static data and are called before relocation. Move all static variables into global_data structure. Also cleanup timer.c from unused stubs and make it truly use 64 bit tick values.

...

Quoted 2 lines

Would you please check this patch series?
Or should I rebase and resubmit?

This is mostly in the responsibility of Albert, the ARM custodian.

Best regards,

Wolfgang Denk

Signature · 5 lines
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Presidency:  The greased pig in the field game of American politics.
- Ambrose Bierce
#6 lore raw

PATCH v2 1/2 arm: a320 timer: move static data to global_data struct

Dear Wolfgang,

Quoted 6 lines · Wolfgang Denk

Dear Po-Yu Chuang,

Quoted 2 lines · In message <[email protected]> you…

Would you please check this patch series?
Or should I rebase and resubmit?

This is mostly in the responsibility of Albert, the ARM custodian.

Sorry, I didn't noticed that we have new custodian now.

Thanks,
Po-Yu Chuang

#7 lore raw

PATCH v2 1/2 arm: a320 timer: move static data to global_data struct

In reply to Po-Yu Chuang

Le 20/12/2010 10:00, Po-Yu Chuang a ?crit :

Quoted 211 lines

From: Po-Yu Chuang<[email protected]>

timer.c used static data and are called before relocation. Move all static variables into global_data structure. Also cleanup timer.c from unused stubs and make it truly use 64 bit tick values.

Based on Reinhard Meyer<[email protected]>'s patch 5dca710a3d7703e41da0e9894f2d71f9e25bea6b

---
v2:
rebase
use gd->timer_rate_hz.
remove unused global variable timestamp and lastdec. move register bases to local variables

  arch/arm/cpu/arm920t/a320/timer.c |  147 ++++++++++++++-----------------------
  1 files changed, 56 insertions(+), 91 deletions(-)
arch/arm/cpu/arm920t/a320/timer.c +54 -88
index d2e316f..5af94c2 100644
@@ -18,21 +18,36 @@
   */
 
  #include<common.h>
+#include<div64.h>
  #include<asm/io.h>
  #include<asm/arch/ftpmu010.h>
  #include<asm/arch/fttmr010.h>
 
-static ulong timestamp;
-static ulong lastdec;
-
-static struct fttmr010 *tmr = (struct fttmr010 *)CONFIG_FTTMR010_BASE;
-static struct ftpmu010 *pmu = (struct ftpmu010 *)CONFIG_FTPMU010_BASE;
+DECLARE_GLOBAL_DATA_PTR;
 
  #define TIMER_CLOCK	32768
  #define TIMER_LOAD_VAL	0xffffffff
 
+static inline unsigned long long tick_to_time(unsigned long long tick)
+{
+	tick *= CONFIG_SYS_HZ;
+	do_div(tick, gd->timer_rate_hz);
+
+	return tick;
+}
+
+static inline unsigned long long usec_to_tick(unsigned long long usec)
+{
+	usec *= gd->timer_rate_hz;
+	do_div(usec, 1000000);
+
+	return usec;
+}
+
  int timer_init(void)
  {
+	struct fttmr010 *tmr = (struct fttmr010 *)CONFIG_FTTMR010_BASE;
+	struct ftpmu010 *pmu = (struct ftpmu010 *)CONFIG_FTPMU010_BASE;
  	unsigned int oscc;
  	unsigned int cr;
 
@@ -76,118 +91,68 @@ int timer_init(void)
  	cr |= FTTMR010_TM3_ENABLE;
  	writel(cr,&tmr->cr);
 
-	/* init the timestamp and lastdec value */
-	reset_timer_masked();
+	gd->timer_rate_hz = TIMER_CLOCK;
+	gd->tbu = gd->tbl = 0;
 
  	return 0;
  }
 
  /*
- * timer without interrupts
- */
-
-/*
- * reset time
+ * Get the current 64 bit timer tick count
   */
-void reset_timer_masked(void)
+unsigned long long get_ticks(void)
  {
-	/* capure current decrementer value time */
-	lastdec = readl(&tmr->timer3_counter) / (TIMER_CLOCK / CONFIG_SYS_HZ);
-	timestamp = 0;		/* start "advancing" time stamp from 0 */
-
-	debug("%s(): lastdec = %lx\n", __func__, lastdec);
-}
+	struct fttmr010 *tmr = (struct fttmr010 *)CONFIG_FTTMR010_BASE;
+	ulong now = TIMER_LOAD_VAL - readl(&tmr->timer3_counter);
 
-void reset_timer(void)
-{
  	debug("%s()\n", __func__);
-	reset_timer_masked();
-}
 
-/*
- * return timer ticks
- */
-ulong get_timer_masked(void)
-{
-	/* current tick value */
-	ulong now = readl(&tmr->timer3_counter) / (TIMER_CLOCK / CONFIG_SYS_HZ);
-
-	debug("%s(): now = %lx, lastdec = %lx\n", __func__, now, lastdec);
-
-	if (lastdec>= now) {
-		/*
-		 * normal mode (non roll)
-		 * move stamp fordward with absoulte diff ticks
-		 */
-		timestamp += lastdec - now;
-	} 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;
-	}
-
-	lastdec = now;
-
-	debug("%s() returns %lx\n", __func__, timestamp);
-
-	return timestamp;
-}
-
-/*
- * return difference between timer ticks and base
- */
-ulong get_timer(ulong base)
-{
-	debug("%s(%lx)\n", __func__, base);
-	return get_timer_masked() - base;
-}
-
-void set_timer(ulong t)
-{
-	debug("%s(%lx)\n", __func__, t);
-	timestamp = t;
+	/* increment tbu if tbl has rolled over */
+	if (now<  gd->tbl)
+		gd->tbu++;
+	gd->tbl = now;
+	return (((unsigned long long)gd->tbu)<<  32) | gd->tbl;
  }
 
  /* delay x useconds AND preserve advance timestamp value */
  void __udelay(unsigned long usec)
  {
-	long tmo = usec * (TIMER_CLOCK / 1000) / 1000;
-	unsigned long now, last = readl(&tmr->timer3_counter);
-
-	debug("%s(%lu)\n", __func__, usec);
-	while (tmo>  0) {
-		now = readl(&tmr->timer3_counter);
-		if (now>  last) /* count down timer overflow */
-			tmo -= TIMER_LOAD_VAL + last - now;
-		else
-			tmo -= last - now;
-		last = now;
-	}
+	unsigned long long tmp;
+	ulong tmo;
+
+	tmo = usec_to_tick(usec);
+	tmp = get_ticks() + tmo;	/* get current timestamp */
+
+	while (get_ticks()<  tmp)	/* loop till event */
+		;
  }
 
  /*
- * This function is derived from PowerPC code (read timebase as long long).
- * On ARM it just returns the timer value.
+ * reset_timer() and get_timer(base) are a pair of functions that are used by
+ * some timeout/sleep mechanisms in u-boot.
+ *
+ * reset_timer() marks the current time as epoch and
+ * get_timer(base) works relative to that epoch.
+ *
+ * The time is used in CONFIG_SYS_HZ units!
   */
-unsigned long long get_ticks(void)
+void reset_timer(void)
  {
  	debug("%s()\n", __func__);
-	return get_timer(0);
+	gd->timer_reset_value = get_ticks();
+}
+
+ulong get_timer(ulong base)
+{
+	debug("%s(%lx)\n", __func__, base);
+	return tick_to_time(get_ticks() - gd->timer_reset_value) - base;
  }
 
  /*

arch/arm/cpu/arm920t/a320/timer.c int timer_init(void) · line 158

Quoted 10 lines
arch/arm/cpu/arm920t/a320/timer.c +2 -3
- * This function is derived from PowerPC code (timebase clock frequency).
- * On ARM it returns the number of timer ticks per second.
+ * Return the number of timer ticks per second.
   */
  ulong get_tbclk(void)
  {
  	debug("%s()\n", __func__);
-	return CONFIG_SYS_HZ;
+	return gd->timer_rate_hz;
  }

At the moment I won't apply changes to timer code which are more than simple fixes, because we are in a discussion to normalize the use of timers in U-boot; depending on the outcome, this patch could need to be reversed in the end.

Meanwhile, a patch with only the fixes to the use of static variables remains welcome.

Amicalement,

Signature · 1 line
Albert.