arm: a320: fix broken timer
PATCH 1/1 arm: a320: fix broken timer
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.
Remove reset_timer_masked() get_timer_masked()
reference: arch/arm/cpu/arm926ejs/at91/timer.c
Based on Reinhard Meyer <[email protected]>'s patches 5dca710a3d7703e41da0e9894f2d71f9e25bea6b cfff263f41e32c7ba2ee9162a8cc6423eb5a8390
--- arch/arm/cpu/arm920t/a320/timer.c | 134 ++++++++++++++----------------------- 1 files changed, 50 insertions(+), 84 deletions(-)
arch/arm/cpu/arm920t/a320/timer.c +50 -84
@@ -18,20 +18,35 @@*/ #include <common.h> +#include <div64.h> #include <asm/io.h> #include <faraday/ftpmu010.h> #include <faraday/fttmr010.h> -static ulong timestamp; -static ulong lastdec; - -static struct fttmr010 *tmr = (struct fttmr010 *)CONFIG_FTTMR010_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 ;unsigned int cr;debug ("%s()\n" , __func__);
@@ -59,106 +74,57 @@ 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 -*/ -void reset_timer_masked (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); -} - -/* -* 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 +* Get the current 64 bit timer tick count */ -ulong get_timer (ulong base) +unsigned long long get_ticks (void ) { -debug ("%s(%lx)\n" , __func__, base); -return get_timer_masked () - base; +struct fttmr010 *tmr = (struct fttmr010 *)CONFIG_FTTMR010_BASE ; +ulong now =TIMER_LOAD_VAL -readl (&tmr->timer3_counter); + +/* 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 start; +ulong tmo; + + start =get_ticks ();/* get current timestamp */ + tmo =usec_to_tick (usec);/* convert usecs to ticks */ +while ((get_ticks () - start) < tmo) + ;/* loop till time has passed */ }/* -* This function is derived from PowerPC code (read timebase as long long). -* On ARM it just returns the timer value. +* get_timer(base) can be used to check for timeouts or +* to measure elasped time relative to an event: +* +* ulong start_time = get_timer(0) sets start_time to the current +* time value. +* get_timer(start_time) returns the time elapsed since then. +* +* The time is used in CONFIG_SYS_HZ units! */ -unsigned long long get_ticks (void ) +ulong get_timer (ulong base) { -debug ("%s()\n" , __func__); -return get_timer (0 ); +return tick_to_time (get_ticks ()) - 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.7.4.1
PATCH 1/1 arm: a320: fix broken timer
Hi Albert and Po-Yu,
2011/8/11 Po-Yu Chuang <[email protected]>
Quoted 6 lines
From: Po-Yu Chuang <[email protected]>
timer.cused static data and are called before relocation. Move all static variables intoglobal_datastructure. Also cleanuptimer.cfrom unused stubs and make it truly use 64 bit tick values.
This patch has been tested by Macpaul on AG101 and AG101P boards.
--
Best regards,
Macpaul Lin
PATCH 1/1 arm: a320: fix broken timer
Dear Albert
Quoted 6 lines · ???
Hi Albert and Po-Yu,
2011/8/11 Po-Yu Chuang <[email protected]>
Quoted 3 lines
From: Po-Yu Chuang <[email protected]>
Quoted 7 lines
Quoted 3 lines
timer.cused static data and are called before relocation. Move all static variables intoglobal_datastructure. Also cleanuptimer.cfrom unused stubs and make it truly use 64 bit tick values.This patch has been tested by Macpaul on AG101 and AG101P boards.
Tested-by Macpaul Lin <[email protected]>
This patch was posted 2 months ago and is still not in mainline. Is there any problem?
Best regards,
Po-Yu Chuang
PATCH 1/1 arm: a320: fix broken timer
Hi Po-Yu,
Le 18/10/2011 04:34, Po-Yu Chuang a ?crit :
Quoted 13 lines
Dear Albert
Quoted 10 lines · ???
Hi Albert and Po-Yu,
2011/8/11 Po-Yu Chuang<[email protected]>
Quoted 6 lines
From: Po-Yu Chuang<[email protected]>
timer.cused static data and are called before relocation. Move all static variables intoglobal_datastructure. Also cleanuptimer.cfrom unused stubs and make it truly use 64 bit tick values.
Quoted 6 lines
Quoted 3 lines
This patch has been tested by Macpaul on AG101 and AG101P boards.
Tested-by Macpaul Lin<[email protected]>This patch was posted 2 months ago and is still not in mainline. Is there any problem?
None, except my own slowness.
Applied to u-boot-arm/master, and apologies.
Quoted 2 lines
Best regards,
Po-Yu Chuang
Amicalement,
Signature · 1 line
Albert.