* [U-Boot] [PATCH 1/2] arm: a320 timer: move static data to global_data struct
@ 2010-11-01 8:06 ratbert.chuang at gmail.com
2010-11-01 8:37 ` Reinhard Meyer
0 siblings, 1 reply; 8+ messages in thread
From: ratbert.chuang at gmail.com @ 2010-11-01 8:06 UTC (permalink / raw)
To: u-boot
From: Po-Yu Chuang <ratbert@faraday-tech.com>
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 <u-boot@emk-elektronik.de>'s patch
5dca710a3d7703e41da0e9894f2d71f9e25bea6b
Signed-off-by: Po-Yu Chuang <ratbert@faraday-tech.com>
---
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
diff --git a/arch/arm/cpu/arm920t/a320/timer.c b/arch/arm/cpu/arm920t/a320/timer.c
index d2e316f..ac48328 100644
--- a/arch/arm/cpu/arm920t/a320/timer.c
+++ b/arch/arm/cpu/arm920t/a320/timer.c
@@ -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)
{
diff --git a/arch/arm/include/asm/global_data.h b/arch/arm/include/asm/global_data.h
index ada3fbb..04c1564 100644
--- a/arch/arm/include/asm/global_data.h
+++ b/arch/arm/include/asm/global_data.h
@@ -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 */
diff --git a/board/faraday/a320evb/config.mk b/board/faraday/a320evb/config.mk
deleted file mode 100644
index b751d0d..0000000
--- a/board/faraday/a320evb/config.mk
+++ /dev/null
@@ -1,35 +0,0 @@
-#
-# (C) Copyright 2009 Faraday Technology
-# Po-Yu Chuang <ratbert@faraday-tech.com>
-#
-# 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
diff --git a/include/configs/a320evb.h b/include/configs/a320evb.h
index f67cf06..0284d40 100644
--- a/include/configs/a320evb.h
+++ b/include/configs/a320evb.h
@@ -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
*/
--
1.6.3.3
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [U-Boot] [PATCH 1/2] arm: a320 timer: move static data to global_data struct
2010-11-01 8:06 [U-Boot] [PATCH 1/2] arm: a320 timer: move static data to global_data struct ratbert.chuang at gmail.com
@ 2010-11-01 8:37 ` Reinhard Meyer
2010-11-01 8:44 ` Po-Yu Chuang
0 siblings, 1 reply; 8+ messages in thread
From: Reinhard Meyer @ 2010-11-01 8:37 UTC (permalink / raw)
To: u-boot
Dear ratbert.chuang,
> From: Po-Yu Chuang <ratbert@faraday-tech.com>
>
> 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 <u-boot@emk-elektronik.de>'s patch
> 5dca710a3d7703e41da0e9894f2d71f9e25bea6b
>
> Signed-off-by: Po-Yu Chuang <ratbert@faraday-tech.com>
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
^ permalink raw reply [flat|nested] 8+ messages in thread
* [U-Boot] [PATCH 1/2] arm: a320 timer: move static data to global_data struct
2010-11-01 8:37 ` Reinhard Meyer
@ 2010-11-01 8:44 ` Po-Yu Chuang
2010-12-20 9:00 ` [U-Boot] [PATCH v2 " Po-Yu Chuang
0 siblings, 1 reply; 8+ messages in thread
From: Po-Yu Chuang @ 2010-11-01 8:44 UTC (permalink / raw)
To: u-boot
Dear Reinhard,
On Mon, Nov 1, 2010 at 4:37 PM, Reinhard Meyer <u-boot@emk-elektronik.de> wrote:
> Dear ratbert.chuang,
>> From: Po-Yu Chuang <ratbert@faraday-tech.com>
>>
>> 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 <u-boot@emk-elektronik.de>'s patch
>> 5dca710a3d7703e41da0e9894f2d71f9e25bea6b
>>
>> Signed-off-by: Po-Yu Chuang <ratbert@faraday-tech.com>
>
> 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
^ permalink raw reply [flat|nested] 8+ messages in thread
* [U-Boot] [PATCH v2 1/2] arm: a320 timer: move static data to global_data struct
2010-11-01 8:44 ` Po-Yu Chuang
@ 2010-12-20 9:00 ` Po-Yu Chuang
2011-01-17 2:56 ` Po-Yu Chuang
2011-01-24 21:18 ` Albert ARIBAUD
0 siblings, 2 replies; 8+ messages in thread
From: Po-Yu Chuang @ 2010-12-20 9:00 UTC (permalink / raw)
To: u-boot
From: Po-Yu Chuang <ratbert@faraday-tech.com>
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 <u-boot@emk-elektronik.de>'s patch
5dca710a3d7703e41da0e9894f2d71f9e25bea6b
Signed-off-by: Po-Yu Chuang <ratbert@faraday-tech.com>
---
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(-)
diff --git a/arch/arm/cpu/arm920t/a320/timer.c b/arch/arm/cpu/arm920t/a320/timer.c
index d2e316f..5af94c2 100644
--- a/arch/arm/cpu/arm920t/a320/timer.c
+++ b/arch/arm/cpu/arm920t/a320/timer.c
@@ -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;
}
--
1.6.3.3
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [U-Boot] [PATCH v2 1/2] arm: a320 timer: move static data to global_data struct
2010-12-20 9:00 ` [U-Boot] [PATCH v2 " Po-Yu Chuang
@ 2011-01-17 2:56 ` Po-Yu Chuang
2011-01-18 21:45 ` Wolfgang Denk
2011-01-24 21:18 ` Albert ARIBAUD
1 sibling, 1 reply; 8+ messages in thread
From: Po-Yu Chuang @ 2011-01-17 2:56 UTC (permalink / raw)
To: u-boot
Dear Wolfgang,
On Mon, Dec 20, 2010 at 5:00 PM, Po-Yu Chuang <ratbert.chuang@gmail.com> wrote:
> From: Po-Yu Chuang <ratbert@faraday-tech.com>
>
> 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 <u-boot@emk-elektronik.de>'s patch
> 5dca710a3d7703e41da0e9894f2d71f9e25bea6b
>
> Signed-off-by: Po-Yu Chuang <ratbert@faraday-tech.com>
> ---
> 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(-)
Would you please check this patch series?
Or should I rebase and resubmit?
best regards,
Po-Yu Chuang
^ permalink raw reply [flat|nested] 8+ messages in thread
* [U-Boot] [PATCH v2 1/2] arm: a320 timer: move static data to global_data struct
2011-01-17 2:56 ` Po-Yu Chuang
@ 2011-01-18 21:45 ` Wolfgang Denk
2011-01-19 1:56 ` Po-Yu Chuang
0 siblings, 1 reply; 8+ messages in thread
From: Wolfgang Denk @ 2011-01-18 21:45 UTC (permalink / raw)
To: u-boot
Dear Po-Yu Chuang,
In message <AANLkTint_7+g+Fp2cv5qJb3kQtNbF15Y0MM7_s6HByCU@mail.gmail.com> you wrote:
>
> > From: Po-Yu Chuang <ratbert@faraday-tech.com>
> >
> > 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.
...
> 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
--
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
^ permalink raw reply [flat|nested] 8+ messages in thread
* [U-Boot] [PATCH v2 1/2] arm: a320 timer: move static data to global_data struct
2011-01-18 21:45 ` Wolfgang Denk
@ 2011-01-19 1:56 ` Po-Yu Chuang
0 siblings, 0 replies; 8+ messages in thread
From: Po-Yu Chuang @ 2011-01-19 1:56 UTC (permalink / raw)
To: u-boot
Dear Wolfgang,
On Wed, Jan 19, 2011 at 5:45 AM, Wolfgang Denk <wd@denx.de> wrote:
> Dear Po-Yu Chuang,
> In message <AANLkTint_7+g+Fp2cv5qJb3kQtNbF15Y0MM7_s6HByCU@mail.gmail.com> you wrote:
>> 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
^ permalink raw reply [flat|nested] 8+ messages in thread
* [U-Boot] [PATCH v2 1/2] arm: a320 timer: move static data to global_data struct
2010-12-20 9:00 ` [U-Boot] [PATCH v2 " Po-Yu Chuang
2011-01-17 2:56 ` Po-Yu Chuang
@ 2011-01-24 21:18 ` Albert ARIBAUD
1 sibling, 0 replies; 8+ messages in thread
From: Albert ARIBAUD @ 2011-01-24 21:18 UTC (permalink / raw)
To: u-boot
Le 20/12/2010 10:00, Po-Yu Chuang a ?crit :
> From: Po-Yu Chuang<ratbert@faraday-tech.com>
>
> 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<u-boot@emk-elektronik.de>'s patch
> 5dca710a3d7703e41da0e9894f2d71f9e25bea6b
>
> Signed-off-by: Po-Yu Chuang<ratbert@faraday-tech.com>
> ---
> 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(-)
>
> diff --git a/arch/arm/cpu/arm920t/a320/timer.c b/arch/arm/cpu/arm920t/a320/timer.c
> index d2e316f..5af94c2 100644
> --- a/arch/arm/cpu/arm920t/a320/timer.c
> +++ b/arch/arm/cpu/arm920t/a320/timer.c
> @@ -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;
> }
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,
--
Albert.
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2011-01-24 21:18 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-11-01 8:06 [U-Boot] [PATCH 1/2] arm: a320 timer: move static data to global_data struct ratbert.chuang at gmail.com
2010-11-01 8:37 ` Reinhard Meyer
2010-11-01 8:44 ` Po-Yu Chuang
2010-12-20 9:00 ` [U-Boot] [PATCH v2 " Po-Yu Chuang
2011-01-17 2:56 ` Po-Yu Chuang
2011-01-18 21:45 ` Wolfgang Denk
2011-01-19 1:56 ` Po-Yu Chuang
2011-01-24 21:18 ` Albert ARIBAUD
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.