diff options
| -rw-r--r-- | arch/arm/cpu/pxa/timer.c | 85 | 
1 files changed, 34 insertions, 51 deletions
| diff --git a/arch/arm/cpu/pxa/timer.c b/arch/arm/cpu/pxa/timer.c index 0ad64dd94..b7b0da98a 100644 --- a/arch/arm/cpu/pxa/timer.c +++ b/arch/arm/cpu/pxa/timer.c @@ -1,11 +1,7 @@  /* - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH <www.elinos.com> - * Marius Groeger <mgroeger@sysgo.de> + * Marvell PXA2xx/3xx timer driver   * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH <www.elinos.com> - * Alex Zuepke <azu@sysgo.de> + * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>   *   * See file CREDITS for list of people who contributed to this   * project. @@ -31,55 +27,63 @@  #include <common.h>  #include <div64.h> -#ifdef CONFIG_USE_IRQ -#error: interrupts not implemented yet -#endif +DECLARE_GLOBAL_DATA_PTR; + +#define	TIMER_LOAD_VAL	0xffffffff + +#define	timestamp	(gd->tbl) +#define	lastinc		(gd->lastinc)  #if defined(CONFIG_CPU_PXA27X) || defined(CONFIG_CPU_MONAHANS) -#define TIMER_FREQ_HZ 3250000 +#define	TIMER_FREQ_HZ	3250000  #elif defined(CONFIG_CPU_PXA25X) -#define TIMER_FREQ_HZ 3686400 +#define	TIMER_FREQ_HZ	3686400  #else  #error "Timer frequency unknown - please config PXA CPU type"  #endif -static inline unsigned long long tick_to_time(unsigned long long tick) +static unsigned long long tick_to_time(unsigned long long tick)  { -	tick *= CONFIG_SYS_HZ; -	do_div(tick, TIMER_FREQ_HZ); -	return tick; +	return tick * CONFIG_SYS_HZ / TIMER_FREQ_HZ;  } -static inline unsigned long long us_to_tick(unsigned long long us) +static unsigned long long us_to_tick(unsigned long long us)  { -	us = us * TIMER_FREQ_HZ + 999999; -	do_div(us, 1000000); -	return us; +	return (us * TIMER_FREQ_HZ) / 1000000;  } -int timer_init (void) +int timer_init(void)  {  	writel(0, OSCR); -  	return 0;  } -ulong get_timer (ulong base) +unsigned long long get_ticks(void)  { -	return get_timer_masked () - base; -} +	/* Current tick value */ +	uint32_t now = readl(OSCR); -void __udelay (unsigned long usec) -{ -	udelay_masked (usec); +	if (now >= lastinc) { +		/* +		 * Normal mode (non roll) +		 * Move stamp forward with absolute diff ticks +		 */ +		timestamp += (now - lastinc); +	} else { +		/* We have rollover of incrementer */ +		timestamp += (TIMER_LOAD_VAL - lastinc) + now; +	} + +	lastinc = now; +	return timestamp;  } -ulong get_timer_masked (void) +ulong get_timer(ulong base)  { -	return tick_to_time(get_ticks()); +	return tick_to_time(get_ticks()) - base;  } -void udelay_masked (unsigned long usec) +void __udelay(unsigned long usec)  {  	unsigned long long tmp;  	ulong tmo; @@ -89,25 +93,4 @@ void udelay_masked (unsigned long usec)  	while (get_ticks() < tmp)	/* loop till event */  		 /*NOP*/; - -} - -/* - * This function is derived from PowerPC code (read timebase as long long). - * On ARM it just returns the timer value. - */ -unsigned long long get_ticks(void) -{ -	return readl(OSCR); -} - -/* - * 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) -{ -	ulong tbclk; -	tbclk = TIMER_FREQ_HZ; -	return tbclk;  } |