Patchwork [U-Boot] armv7, timer: move static data to global_data struct

login
register
mail settings
Submitter Heiko Schocher
Date Nov. 30, 2010, 7:02 a.m.
Message ID <1291100540-24293-1-git-send-email-hs@denx.de>
Download mbox | patch
Permalink /patch/73574/
State Not Applicable
Delegated to: Albert ARIBAUD
Headers show

Comments

Heiko Schocher - Nov. 30, 2010, 7:02 a.m.
timer.c use static data and change this before relocation,
where bss section (in which the static data is stored) is
not valid. Instead before relocation there is the .rel.dyn
section overlayed.

Move all static variables into global_data structure.

Tested on the omap3_beagle board.

Signed-off-by: Heiko Schocher <hs@denx.de>
cc: Albert ARIBAUD <albert.aribaud@free.fr>
cc: Steve Sakoman <steve@sakoman.com>
---
 arch/arm/cpu/armv7/mx5/timer.c         |   23 +++++++++----------
 arch/arm/cpu/armv7/omap-common/timer.c |   22 +++++++++---------
 arch/arm/cpu/armv7/s5p-common/timer.c  |   38 ++++++++++++++-----------------
 arch/arm/include/asm/global_data.h     |   10 ++++++++
 4 files changed, 49 insertions(+), 44 deletions(-)
Andreas Bießmann - Nov. 30, 2010, 7:14 a.m.
Dear Heiko Schocher,

Am 30.11.2010 um 08:02 schrieb Heiko Schocher:

> diff --git a/arch/arm/include/asm/global_data.h b/arch/arm/include/asm/global_data.h
> index ada3fbb..16dc27c 100644
> --- a/arch/arm/include/asm/global_data.h
> +++ b/arch/arm/include/asm/global_data.h
> @@ -61,6 +61,16 @@ typedef	struct	global_data {
> 	unsigned long	tbu;
> 	unsigned long long	timer_reset_value;
> #endif
> +#if defined(CONFIG_OMAP) || defined(CONFIG_MX51)
> +	unsigned long timestamp;
> +	unsigned long lastinc;
> +#endif
> +#if defined(CONFIG_S5P)
> +	unsigned long count_value;
> +	/* Internal tick units */
> +	unsigned long long timestamp;	/* Monotonic incrementing timer */
> +	unsigned long lastdec;		/* Last decremneter snapshot */
> +#endif
> 	unsigned long	relocaddr;	/* Start address of U-Boot in RAM */
> 	phys_size_t	ram_size;	/* RAM size */
> 	unsigned long	mon_len;	/* monitor len */

can't this generalized in some way?
AT91 still has some values like that in global_data, yesterday David Müller sent a patch for S3C24X0 to add some values like that to global_data ... we have a lot of arm cores out there, should each get his own style of global_data?

regards

Andreas Bießmann
Heiko Schocher - Nov. 30, 2010, 7:54 a.m.
Hello Andreas,

Andreas Bießmann wrote:
> Am 30.11.2010 um 08:02 schrieb Heiko Schocher:
> 
>> diff --git a/arch/arm/include/asm/global_data.h b/arch/arm/include/asm/global_data.h
>> index ada3fbb..16dc27c 100644
>> --- a/arch/arm/include/asm/global_data.h
>> +++ b/arch/arm/include/asm/global_data.h
>> @@ -61,6 +61,16 @@ typedef	struct	global_data {
>> 	unsigned long	tbu;
>> 	unsigned long long	timer_reset_value;
>> #endif
>> +#if defined(CONFIG_OMAP) || defined(CONFIG_MX51)
>> +	unsigned long timestamp;
>> +	unsigned long lastinc;
>> +#endif
>> +#if defined(CONFIG_S5P)
>> +	unsigned long count_value;
>> +	/* Internal tick units */
>> +	unsigned long long timestamp;	/* Monotonic incrementing timer */
>> +	unsigned long lastdec;		/* Last decremneter snapshot */
>> +#endif
>> 	unsigned long	relocaddr;	/* Start address of U-Boot in RAM */
>> 	phys_size_t	ram_size;	/* RAM size */
>> 	unsigned long	mon_len;	/* monitor len */
> 
> can't this generalized in some way?

Good question.

> AT91 still has some values like that in global_data, yesterday David Müller sent a patch for S3C24X0 to add some values like that to global_data ... we have a lot of arm cores out there, should each get his own style of global_data?

A common way would be better, ideas are welcome ;-)

For example we could rename for the armv7 timer variants the "lastinc"
and "lastdec" value in "lastval", so we could merge them ... if it
is possible to find a solution for all arm cores, I don;t know ...

bye,
Heiko
Thomas Weber - Nov. 30, 2010, 8 a.m.
Am 30.11.2010 08:02, schrieb Heiko Schocher:
> timer.c use static data and change this before relocation,
> where bss section (in which the static data is stored) is
> not valid. Instead before relocation there is the .rel.dyn
> section overlayed.
> 
> Move all static variables into global_data structure.
> 
> Tested on the omap3_beagle board.
> 
> Signed-off-by: Heiko Schocher <hs@denx.de>
> cc: Albert ARIBAUD <albert.aribaud@free.fr>
> cc: Steve Sakoman <steve@sakoman.com>
> ---
>  arch/arm/cpu/armv7/mx5/timer.c         |   23 +++++++++----------
>  arch/arm/cpu/armv7/omap-common/timer.c |   22 +++++++++---------
>  arch/arm/cpu/armv7/s5p-common/timer.c  |   38 ++++++++++++++-----------------
>  arch/arm/include/asm/global_data.h     |   10 ++++++++
>  4 files changed, 49 insertions(+), 44 deletions(-)
> 
> diff --git a/arch/arm/cpu/armv7/mx5/timer.c b/arch/arm/cpu/armv7/mx5/timer.c
> index 3044fcf..bfb22a7 100644
> --- a/arch/arm/cpu/armv7/mx5/timer.c
> +++ b/arch/arm/cpu/armv7/mx5/timer.c
> @@ -27,6 +27,8 @@
>  #include <asm/io.h>
>  #include <asm/arch/imx-regs.h>
>  
> +DECLARE_GLOBAL_DATA_PTR;
> +
>  /* General purpose timers registers */
>  struct mxc_gpt {
>  	unsigned int control;
> @@ -44,9 +46,6 @@ static struct mxc_gpt *cur_gpt = (struct mxc_gpt *)GPT1_BASE_ADDR;
>  #define GPTCR_CLKSOURCE_32 (4<<6)	/* Clock source */
>  #define GPTCR_TEN       (1)	/* Timer enable */
>  
> -static ulong timestamp;
> -static ulong lastinc;
> -
>  int timer_init(void)
>  {
>  	int i;
> @@ -75,21 +74,21 @@ void reset_timer(void)
>  void reset_timer_masked(void)
>  {
>  	ulong val = __raw_readl(&cur_gpt->counter);
> -	lastinc = val / (CONFIG_SYS_MX5_CLK32 / CONFIG_SYS_HZ);
> -	timestamp = 0;
> +	gd->lastinc = val / (CONFIG_SYS_MX5_CLK32 / CONFIG_SYS_HZ);
> +	gd->timestamp = 0;
>  }
>  
>  ulong get_timer_masked(void)
>  {
>  	ulong val = __raw_readl(&cur_gpt->counter);
>  	val /= (CONFIG_SYS_MX5_CLK32 / CONFIG_SYS_HZ);
> -	if (val >= lastinc)
> -		timestamp += (val - lastinc);
> +	if (val >= gd->lastinc)
> +		gd->timestamp += (val - gd->lastinc);
>  	else
> -		timestamp += ((0xFFFFFFFF / (CONFIG_SYS_MX5_CLK32 / CONFIG_SYS_HZ))
> -				- lastinc) + val;
> -	lastinc = val;
> -	return timestamp;
> +		gd->timestamp += ((0xFFFFFFFF / (CONFIG_SYS_MX5_CLK32 / CONFIG_SYS_HZ))
> +				- gd->lastinc) + val;
> +	gd->lastinc = val;
> +	return gd->timestamp;
>  }
>  
>  ulong get_timer(ulong base)
> @@ -99,7 +98,7 @@ ulong get_timer(ulong base)
>  
>  void set_timer(ulong t)
>  {
> -	timestamp = t;
> +	gd->timestamp = t;
>  }
>  
>  /* delay x useconds AND preserve advance timestamp value */
> diff --git a/arch/arm/cpu/armv7/omap-common/timer.c b/arch/arm/cpu/armv7/omap-common/timer.c
> index 6b8cf7b..8897b12 100644
> --- a/arch/arm/cpu/armv7/omap-common/timer.c
> +++ b/arch/arm/cpu/armv7/omap-common/timer.c
> @@ -35,8 +35,8 @@
>  #include <common.h>
>  #include <asm/io.h>
>  
> -static ulong timestamp;
> -static ulong lastinc;
> +DECLARE_GLOBAL_DATA_PTR;
> +
>  static struct gptimer *timer_base = (struct gptimer *)CONFIG_SYS_TIMERBASE;
>  
>  /*
> @@ -74,7 +74,7 @@ ulong get_timer(ulong base)
>  
>  void set_timer(ulong t)
>  {
> -	timestamp = t;
> +	gd->timestamp = t;
>  }
>  
>  /* delay x useconds */
> @@ -96,8 +96,8 @@ void __udelay(unsigned long usec)
>  void reset_timer_masked(void)
>  {
>  	/* reset time, capture current incrementer value time */
> -	lastinc = readl(&timer_base->tcrr) / (TIMER_CLOCK / CONFIG_SYS_HZ);
> -	timestamp = 0;		/* start "advancing" time stamp from 0 */
> +	gd->lastinc = readl(&timer_base->tcrr) / (TIMER_CLOCK / CONFIG_SYS_HZ);
> +	gd->timestamp = 0;		/* start "advancing" time stamp from 0 */
>  }
>  
>  ulong get_timer_masked(void)
> @@ -105,14 +105,14 @@ ulong get_timer_masked(void)
>  	/* current tick value */
>  	ulong now = readl(&timer_base->tcrr) / (TIMER_CLOCK / CONFIG_SYS_HZ);
>  
> -	if (now >= lastinc)	/* normal mode (non roll) */
> +	if (now >= gd->lastinc)	/* normal mode (non roll) */
>  		/* move stamp fordward with absoulte diff ticks */
> -		timestamp += (now - lastinc);
> +		gd->timestamp += (now - gd->lastinc);
>  	else	/* we have rollover of incrementer */
> -		timestamp += ((TIMER_LOAD_VAL / (TIMER_CLOCK / CONFIG_SYS_HZ))
> -				- lastinc) + now;
> -	lastinc = now;
> -	return timestamp;
> +		gd->timestamp += ((TIMER_LOAD_VAL / (TIMER_CLOCK / CONFIG_SYS_HZ))
> +				- gd->lastinc) + now;
> +	gd->lastinc = now;
> +	return gd->timestamp;
>  }
>  
>  /*
> diff --git a/arch/arm/cpu/armv7/s5p-common/timer.c b/arch/arm/cpu/armv7/s5p-common/timer.c
> index 0490650..2933ec0 100644
> --- a/arch/arm/cpu/armv7/s5p-common/timer.c
> +++ b/arch/arm/cpu/armv7/s5p-common/timer.c
> @@ -37,11 +37,7 @@
>  
>  #define TCON_TIMER4_SHIFT	20
>  
> -static unsigned long count_value;
> -
> -/* Internal tick units */
> -static unsigned long long timestamp;	/* Monotonic incrementing timer */
> -static unsigned long lastdec;		/* Last decremneter snapshot */
> +DECLARE_GLOBAL_DATA_PTR;
>  
>  /* macro to read the 16 bit timer */
>  static inline struct s5p_timer *s5p_get_base_timer(void)
> @@ -65,19 +61,19 @@ int timer_init(void)
>  	writel((PRESCALER_1 & 0xff) << 8, &timer->tcfg0);
>  	writel((MUX_DIV_2 & 0xf) << MUX4_DIV_SHIFT, &timer->tcfg1);
>  
> -	if (count_value == 0) {
> +	if (gd->count_value == 0) {
>  		/* reset initial value */
>  		/* count_value = 2085937.5(HZ) (per 1 sec)*/
> -		count_value = get_pwm_clk() / ((PRESCALER_1 + 1) *
> +		gd->count_value = get_pwm_clk() / ((PRESCALER_1 + 1) *
>  				(MUX_DIV_2 + 1));
>  
>  		/* count_value / 100 = 20859.375(HZ) (per 10 msec) */
> -		count_value = count_value / 100;
> +		gd->count_value = gd->count_value / 100;
>  	}
>  
>  	/* set count value */
> -	writel(count_value, &timer->tcntb4);
> -	lastdec = count_value;
> +	writel(gd->count_value, &timer->tcntb4);
> +	gd->lastdec = gd->count_value;
>  
>  	val = (readl(&timer->tcon) & ~(0x07 << TCON_TIMER4_SHIFT)) |
>  		TCON4_AUTO_RELOAD;
> @@ -88,7 +84,7 @@ int timer_init(void)
>  	/* start PWM timer 4 */
>  	writel(val | TCON4_START, &timer->tcon);
>  
> -	timestamp = 0;
> +	gd->timestamp = 0;
>  
>  	return 0;
>  }
> @@ -108,7 +104,7 @@ unsigned long get_timer(unsigned long base)
>  
>  void set_timer(unsigned long t)
>  {
> -	timestamp = t;
> +	gd->timestamp = t;
>  }
>  
>  /* delay x useconds */
> @@ -125,11 +121,11 @@ void __udelay(unsigned long usec)
>  		 * 3. finish normalize.
>  		 */
>  		tmo = usec / 1000;
> -		tmo *= (CONFIG_SYS_HZ * count_value / 10);
> +		tmo *= (CONFIG_SYS_HZ * gd->count_value / 10);
>  		tmo /= 1000;
>  	} else {
>  		/* else small number, don't kill it prior to HZ multiply */
> -		tmo = usec * CONFIG_SYS_HZ * count_value / 10;
> +		tmo = usec * CONFIG_SYS_HZ * gd->count_value / 10;
>  		tmo /= (1000 * 1000);
>  	}
>  
> @@ -154,8 +150,8 @@ void reset_timer_masked(void)
>  	struct s5p_timer *const timer = s5p_get_base_timer();
>  
>  	/* reset time */
> -	lastdec = readl(&timer->tcnto4);
> -	timestamp = 0;
> +	gd->lastdec = readl(&timer->tcnto4);
> +	gd->timestamp = 0;
>  }
>  
>  unsigned long get_timer_masked(void)
> @@ -163,14 +159,14 @@ unsigned long get_timer_masked(void)
>  	struct s5p_timer *const timer = s5p_get_base_timer();
>  	unsigned long now = readl(&timer->tcnto4);
>  
> -	if (lastdec >= now)
> -		timestamp += lastdec - now;
> +	if (gd->lastdec >= now)
> +		gd->timestamp += gd->lastdec - now;
>  	else
> -		timestamp += lastdec + count_value - now;
> +		gd->timestamp += gd->lastdec + gd->count_value - now;
>  
> -	lastdec = now;
> +	gd->lastdec = now;
>  
> -	return timestamp;
> +	return gd->timestamp;
>  }
>  
>  /*
> diff --git a/arch/arm/include/asm/global_data.h b/arch/arm/include/asm/global_data.h
> index ada3fbb..16dc27c 100644
> --- a/arch/arm/include/asm/global_data.h
> +++ b/arch/arm/include/asm/global_data.h
> @@ -61,6 +61,16 @@ typedef	struct	global_data {
>  	unsigned long	tbu;
>  	unsigned long long	timer_reset_value;
>  #endif
> +#if defined(CONFIG_OMAP) || defined(CONFIG_MX51)
> +	unsigned long timestamp;
> +	unsigned long lastinc;
> +#endif
> +#if defined(CONFIG_S5P)
> +	unsigned long count_value;
> +	/* Internal tick units */
> +	unsigned long long timestamp;	/* Monotonic incrementing timer */
> +	unsigned long lastdec;		/* Last decremneter snapshot */
> +#endif
>  	unsigned long	relocaddr;	/* Start address of U-Boot in RAM */
>  	phys_size_t	ram_size;	/* RAM size */
>  	unsigned long	mon_len;	/* monitor len */


Tested on Devkit8000 (OMAP3).

Tested-by: Thomas Weber <weber@corscience.de>
Wolfgang Denk - Nov. 30, 2010, 8:06 a.m.
Dear =?iso-8859-1?Q?Andreas_Bie=DFmann?=,

In message <0CD9BF11-6356-44A8-BABA-0AA08671D9FB@googlemail.com> you wrote:
> 
> > +#if defined(CONFIG_OMAP) || defined(CONFIG_MX51)
> > +	unsigned long timestamp;
> > +	unsigned long lastinc;
> > +#endif
> > +#if defined(CONFIG_S5P)
> > +	unsigned long count_value;
> > +	/* Internal tick units */
> > +	unsigned long long timestamp;	/* Monotonic incrementing timer */
> > +	unsigned long lastdec;		/* Last decremneter snapshot */
> > +#endif
> > 	unsigned long	relocaddr;	/* Start address of U-Boot in RAM */
> > 	phys_size_t	ram_size;	/* RAM size */
> > 	unsigned long	mon_len;	/* monitor len */
> 
> can't this generalized in some way?

It can, and it should.

But I suggest we handle such a cleanup as a separate task and defer it
until the next release (which means that any such patches will go to
the "next" branch if they come now).

I guess if we provide something like

	uint64_t   timebase;
	uint32_t   timelast;

this should cover most of the cases. We can add this without ifdef's,
and only eventually a few implementations may need another variable
added.

Patches welcome...

Best regards,

Wolfgang Denk
Andreas Bießmann - Nov. 30, 2010, 8:10 a.m.
Dear Heiko Schocher,

Am 30.11.2010 08:54, schrieb Heiko Schocher:
> Hello Andreas,
> 
> Andreas Bießmann wrote:
>> Am 30.11.2010 um 08:02 schrieb Heiko Schocher:
>>

[snip another ARM-SoC add to GD for timer]

>> can't this generalized in some way?
> 
> Good question.
> 
>> AT91 still has some values like that in global_data, yesterday David Müller sent a patch for S3C24X0 to add some values like that to global_data ... we have a lot of arm cores out there, should each get his own style of global_data?
> 
> A common way would be better, ideas are welcome ;-)

I think Reinhard is already thinking about a solution.

> For example we could rename for the armv7 timer variants the "lastinc"
> and "lastdec" value in "lastval", so we could merge them ... if it
> is possible to find a solution for all arm cores, I don;t know ...

A short look to the arm/cpu/**/timer.c showed that most of them use a 16
bit timer to provide an 32 bit timer value. For that class of timer
implementation it would be suffucient to have a 'uint32_t
last_timer_val' and an 'uint32_t timestamp' in GD.

regards

Andreas Bießmann
Minkyu Kang - Nov. 30, 2010, 8:11 a.m.
Dear Heiko,

On 30 November 2010 16:54, Heiko Schocher <hs@denx.de> wrote:
> Hello Andreas,
>
> Andreas Bießmann wrote:
>> Am 30.11.2010 um 08:02 schrieb Heiko Schocher:
>>
>>> diff --git a/arch/arm/include/asm/global_data.h b/arch/arm/include/asm/global_data.h
>>> index ada3fbb..16dc27c 100644
>>> --- a/arch/arm/include/asm/global_data.h
>>> +++ b/arch/arm/include/asm/global_data.h
>>> @@ -61,6 +61,16 @@ typedef   struct  global_data {
>>>      unsigned long   tbu;
>>>      unsigned long long      timer_reset_value;
>>> #endif
>>> +#if defined(CONFIG_OMAP) || defined(CONFIG_MX51)
>>> +    unsigned long timestamp;
>>> +    unsigned long lastinc;
>>> +#endif
>>> +#if defined(CONFIG_S5P)
>>> +    unsigned long count_value;
>>> +    /* Internal tick units */
>>> +    unsigned long long timestamp;   /* Monotonic incrementing timer */
>>> +    unsigned long lastdec;          /* Last decremneter snapshot */
>>> +#endif
>>>      unsigned long   relocaddr;      /* Start address of U-Boot in RAM */
>>>      phys_size_t     ram_size;       /* RAM size */
>>>      unsigned long   mon_len;        /* monitor len */
>>

Thanks for your work.
But, I already fixed it by other way.

http://patchwork.ozlabs.org/patch/72226/

Please remove s5p in your patch.
If need, I'll make the patch.

Thanks
Minkyu Kang

Patch

diff --git a/arch/arm/cpu/armv7/mx5/timer.c b/arch/arm/cpu/armv7/mx5/timer.c
index 3044fcf..bfb22a7 100644
--- a/arch/arm/cpu/armv7/mx5/timer.c
+++ b/arch/arm/cpu/armv7/mx5/timer.c
@@ -27,6 +27,8 @@ 
 #include <asm/io.h>
 #include <asm/arch/imx-regs.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
 /* General purpose timers registers */
 struct mxc_gpt {
 	unsigned int control;
@@ -44,9 +46,6 @@  static struct mxc_gpt *cur_gpt = (struct mxc_gpt *)GPT1_BASE_ADDR;
 #define GPTCR_CLKSOURCE_32 (4<<6)	/* Clock source */
 #define GPTCR_TEN       (1)	/* Timer enable */
 
-static ulong timestamp;
-static ulong lastinc;
-
 int timer_init(void)
 {
 	int i;
@@ -75,21 +74,21 @@  void reset_timer(void)
 void reset_timer_masked(void)
 {
 	ulong val = __raw_readl(&cur_gpt->counter);
-	lastinc = val / (CONFIG_SYS_MX5_CLK32 / CONFIG_SYS_HZ);
-	timestamp = 0;
+	gd->lastinc = val / (CONFIG_SYS_MX5_CLK32 / CONFIG_SYS_HZ);
+	gd->timestamp = 0;
 }
 
 ulong get_timer_masked(void)
 {
 	ulong val = __raw_readl(&cur_gpt->counter);
 	val /= (CONFIG_SYS_MX5_CLK32 / CONFIG_SYS_HZ);
-	if (val >= lastinc)
-		timestamp += (val - lastinc);
+	if (val >= gd->lastinc)
+		gd->timestamp += (val - gd->lastinc);
 	else
-		timestamp += ((0xFFFFFFFF / (CONFIG_SYS_MX5_CLK32 / CONFIG_SYS_HZ))
-				- lastinc) + val;
-	lastinc = val;
-	return timestamp;
+		gd->timestamp += ((0xFFFFFFFF / (CONFIG_SYS_MX5_CLK32 / CONFIG_SYS_HZ))
+				- gd->lastinc) + val;
+	gd->lastinc = val;
+	return gd->timestamp;
 }
 
 ulong get_timer(ulong base)
@@ -99,7 +98,7 @@  ulong get_timer(ulong base)
 
 void set_timer(ulong t)
 {
-	timestamp = t;
+	gd->timestamp = t;
 }
 
 /* delay x useconds AND preserve advance timestamp value */
diff --git a/arch/arm/cpu/armv7/omap-common/timer.c b/arch/arm/cpu/armv7/omap-common/timer.c
index 6b8cf7b..8897b12 100644
--- a/arch/arm/cpu/armv7/omap-common/timer.c
+++ b/arch/arm/cpu/armv7/omap-common/timer.c
@@ -35,8 +35,8 @@ 
 #include <common.h>
 #include <asm/io.h>
 
-static ulong timestamp;
-static ulong lastinc;
+DECLARE_GLOBAL_DATA_PTR;
+
 static struct gptimer *timer_base = (struct gptimer *)CONFIG_SYS_TIMERBASE;
 
 /*
@@ -74,7 +74,7 @@  ulong get_timer(ulong base)
 
 void set_timer(ulong t)
 {
-	timestamp = t;
+	gd->timestamp = t;
 }
 
 /* delay x useconds */
@@ -96,8 +96,8 @@  void __udelay(unsigned long usec)
 void reset_timer_masked(void)
 {
 	/* reset time, capture current incrementer value time */
-	lastinc = readl(&timer_base->tcrr) / (TIMER_CLOCK / CONFIG_SYS_HZ);
-	timestamp = 0;		/* start "advancing" time stamp from 0 */
+	gd->lastinc = readl(&timer_base->tcrr) / (TIMER_CLOCK / CONFIG_SYS_HZ);
+	gd->timestamp = 0;		/* start "advancing" time stamp from 0 */
 }
 
 ulong get_timer_masked(void)
@@ -105,14 +105,14 @@  ulong get_timer_masked(void)
 	/* current tick value */
 	ulong now = readl(&timer_base->tcrr) / (TIMER_CLOCK / CONFIG_SYS_HZ);
 
-	if (now >= lastinc)	/* normal mode (non roll) */
+	if (now >= gd->lastinc)	/* normal mode (non roll) */
 		/* move stamp fordward with absoulte diff ticks */
-		timestamp += (now - lastinc);
+		gd->timestamp += (now - gd->lastinc);
 	else	/* we have rollover of incrementer */
-		timestamp += ((TIMER_LOAD_VAL / (TIMER_CLOCK / CONFIG_SYS_HZ))
-				- lastinc) + now;
-	lastinc = now;
-	return timestamp;
+		gd->timestamp += ((TIMER_LOAD_VAL / (TIMER_CLOCK / CONFIG_SYS_HZ))
+				- gd->lastinc) + now;
+	gd->lastinc = now;
+	return gd->timestamp;
 }
 
 /*
diff --git a/arch/arm/cpu/armv7/s5p-common/timer.c b/arch/arm/cpu/armv7/s5p-common/timer.c
index 0490650..2933ec0 100644
--- a/arch/arm/cpu/armv7/s5p-common/timer.c
+++ b/arch/arm/cpu/armv7/s5p-common/timer.c
@@ -37,11 +37,7 @@ 
 
 #define TCON_TIMER4_SHIFT	20
 
-static unsigned long count_value;
-
-/* Internal tick units */
-static unsigned long long timestamp;	/* Monotonic incrementing timer */
-static unsigned long lastdec;		/* Last decremneter snapshot */
+DECLARE_GLOBAL_DATA_PTR;
 
 /* macro to read the 16 bit timer */
 static inline struct s5p_timer *s5p_get_base_timer(void)
@@ -65,19 +61,19 @@  int timer_init(void)
 	writel((PRESCALER_1 & 0xff) << 8, &timer->tcfg0);
 	writel((MUX_DIV_2 & 0xf) << MUX4_DIV_SHIFT, &timer->tcfg1);
 
-	if (count_value == 0) {
+	if (gd->count_value == 0) {
 		/* reset initial value */
 		/* count_value = 2085937.5(HZ) (per 1 sec)*/
-		count_value = get_pwm_clk() / ((PRESCALER_1 + 1) *
+		gd->count_value = get_pwm_clk() / ((PRESCALER_1 + 1) *
 				(MUX_DIV_2 + 1));
 
 		/* count_value / 100 = 20859.375(HZ) (per 10 msec) */
-		count_value = count_value / 100;
+		gd->count_value = gd->count_value / 100;
 	}
 
 	/* set count value */
-	writel(count_value, &timer->tcntb4);
-	lastdec = count_value;
+	writel(gd->count_value, &timer->tcntb4);
+	gd->lastdec = gd->count_value;
 
 	val = (readl(&timer->tcon) & ~(0x07 << TCON_TIMER4_SHIFT)) |
 		TCON4_AUTO_RELOAD;
@@ -88,7 +84,7 @@  int timer_init(void)
 	/* start PWM timer 4 */
 	writel(val | TCON4_START, &timer->tcon);
 
-	timestamp = 0;
+	gd->timestamp = 0;
 
 	return 0;
 }
@@ -108,7 +104,7 @@  unsigned long get_timer(unsigned long base)
 
 void set_timer(unsigned long t)
 {
-	timestamp = t;
+	gd->timestamp = t;
 }
 
 /* delay x useconds */
@@ -125,11 +121,11 @@  void __udelay(unsigned long usec)
 		 * 3. finish normalize.
 		 */
 		tmo = usec / 1000;
-		tmo *= (CONFIG_SYS_HZ * count_value / 10);
+		tmo *= (CONFIG_SYS_HZ * gd->count_value / 10);
 		tmo /= 1000;
 	} else {
 		/* else small number, don't kill it prior to HZ multiply */
-		tmo = usec * CONFIG_SYS_HZ * count_value / 10;
+		tmo = usec * CONFIG_SYS_HZ * gd->count_value / 10;
 		tmo /= (1000 * 1000);
 	}
 
@@ -154,8 +150,8 @@  void reset_timer_masked(void)
 	struct s5p_timer *const timer = s5p_get_base_timer();
 
 	/* reset time */
-	lastdec = readl(&timer->tcnto4);
-	timestamp = 0;
+	gd->lastdec = readl(&timer->tcnto4);
+	gd->timestamp = 0;
 }
 
 unsigned long get_timer_masked(void)
@@ -163,14 +159,14 @@  unsigned long get_timer_masked(void)
 	struct s5p_timer *const timer = s5p_get_base_timer();
 	unsigned long now = readl(&timer->tcnto4);
 
-	if (lastdec >= now)
-		timestamp += lastdec - now;
+	if (gd->lastdec >= now)
+		gd->timestamp += gd->lastdec - now;
 	else
-		timestamp += lastdec + count_value - now;
+		gd->timestamp += gd->lastdec + gd->count_value - now;
 
-	lastdec = now;
+	gd->lastdec = now;
 
-	return timestamp;
+	return gd->timestamp;
 }
 
 /*
diff --git a/arch/arm/include/asm/global_data.h b/arch/arm/include/asm/global_data.h
index ada3fbb..16dc27c 100644
--- a/arch/arm/include/asm/global_data.h
+++ b/arch/arm/include/asm/global_data.h
@@ -61,6 +61,16 @@  typedef	struct	global_data {
 	unsigned long	tbu;
 	unsigned long long	timer_reset_value;
 #endif
+#if defined(CONFIG_OMAP) || defined(CONFIG_MX51)
+	unsigned long timestamp;
+	unsigned long lastinc;
+#endif
+#if defined(CONFIG_S5P)
+	unsigned long count_value;
+	/* Internal tick units */
+	unsigned long long timestamp;	/* Monotonic incrementing timer */
+	unsigned long lastdec;		/* Last decremneter snapshot */
+#endif
 	unsigned long	relocaddr;	/* Start address of U-Boot in RAM */
 	phys_size_t	ram_size;	/* RAM size */
 	unsigned long	mon_len;	/* monitor len */