@ -25,6 +25,7 @@
# include <common.h>
# include <asm/io.h>
# include <div64.h>
# include <asm/arch/imx-regs.h>
/* General purpose timers registers */
@ -50,6 +51,22 @@ DECLARE_GLOBAL_DATA_PTR;
# define timestamp (gd->tbl)
# define lastinc (gd->lastinc)
static inline unsigned long long tick_to_time ( unsigned long long tick )
{
tick * = CONFIG_SYS_HZ ;
do_div ( tick , CLK_32KHZ ) ;
return tick ;
}
static inline unsigned long long us_to_tick ( unsigned long long usec )
{
usec * = CLK_32KHZ ;
do_div ( usec , 1000000 ) ;
return usec ;
}
int timer_init ( void )
{
int i ;
@ -75,36 +92,58 @@ int timer_init(void)
return 0 ;
}
ulong get_timer_masked ( void )
unsigned long long get_ticks ( void )
{
ulong val = __raw_readl ( & cur_gpt - > counter ) ;
val / = ( CLK_32KHZ / CONFIG_SYS_HZ ) ;
if ( val > = lastinc )
timestamp + = ( val - lastinc ) ;
else
timestamp + = ( ( 0xFFFFFFFF / ( CLK_32KHZ / CONFIG_SYS_HZ ) )
- lastinc ) + val ;
lastinc = val ;
ulong now = __raw_readl ( & cur_gpt - > counter ) ; /* current tick value */
if ( now > = lastinc ) {
/*
* normal mode ( non roll )
* move stamp forward with absolut diff ticks
*/
timestamp + = ( now - lastinc ) ;
} else {
/* we have rollover of incrementer */
timestamp + = ( 0xFFFFFFFF - lastinc ) + now ;
}
lastinc = now ;
return timestamp ;
}
ulong get_timer_masked ( void )
{
/*
* get_ticks ( ) returns a long long ( 64 bit ) , it wraps in
* 2 ^ 64 / CONFIG_MX25_CLK32 = 2 ^ 64 / 2 ^ 15 = 2 ^ 49 ~ 5 * 10 ^ 14 ( s ) ~
* 5 * 10 ^ 9 days . . . and get_ticks ( ) * CONFIG_SYS_HZ wraps in
* 5 * 10 ^ 6 days - long enough .
*/
return tick_to_time ( get_ticks ( ) ) ;
}
ulong get_timer ( ulong base )
{
return get_timer_masked ( ) - base ;
}
/* delay x useconds AND preserve advance timestamp value */
/* delay x useconds AND preserve advance timstamp value */
void __udelay ( unsigned long usec )
{
unsigned long now , start , tmo ;
tmo = usec * ( CLK_32KHZ / 1000 ) / 1000 ;
if ( ! tmo )
tmo = 1 ;
unsigned long long tmp ;
ulong tmo ;
now = start = readl ( & cur_gpt - > counter ) ;
tmo = us_to_tick ( usec ) ;
tmp = get_ticks ( ) + tmo ; /* get current timestamp */
while ( ( now - start ) < tmo )
now = readl ( & cur_gpt - > counter ) ;
while ( get_ticks ( ) < tmp ) /* loop till event */
/*NOP*/ ;
}
/*
* This function is derived from PowerPC code ( timebase clock frequency ) .
* On ARM it returns the number of timer ticks per second .
*/
ulong get_tbclk ( void )
{
return CLK_32KHZ ;
}