X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=arch%2Farm%2Fcpu%2Fpxa%2Ftimer.c;h=212b31eb6853f7d4182ef2b2b745dfe37abf8989;hb=84c617beb2ddcda03e36abe553432e2784ada6b7;hp=ec950c79660ebb1e0c9816a6d0e24a3c9ca3293b;hpb=37a3bda0c9c8a2ffbf7e2a9e121177a3385a0626;p=u-boot diff --git a/arch/arm/cpu/pxa/timer.c b/arch/arm/cpu/pxa/timer.c index ec950c7966..212b31eb68 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 - * Marius Groeger + * Marvell PXA2xx/3xx timer driver * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke + * Copyright (C) 2011 Marek Vasut * * See file CREDITS for list of people who contributed to this * project. @@ -31,71 +27,63 @@ #include #include -#ifdef CONFIG_USE_IRQ -#error: interrupts not implemented yet -#endif +DECLARE_GLOBAL_DATA_PTR; + +#define TIMER_LOAD_VAL 0xffffffff -#if defined(CONFIG_PXA27X) || defined(CONFIG_CPU_MONAHANS) -#define TIMER_FREQ_HZ 3250000 -#elif defined(CONFIG_PXA250) -#define TIMER_FREQ_HZ 3686400 +#define timestamp (gd->arch.tbl) +#define lastinc (gd->arch.lastinc) + +#if defined(CONFIG_CPU_PXA27X) || defined(CONFIG_CPU_MONAHANS) +#define TIMER_FREQ_HZ 3250000 +#elif defined(CONFIG_CPU_PXA25X) +#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) { - reset_timer(); - + writel(0, OSCR); return 0; } -void reset_timer (void) -{ - reset_timer_masked (); -} - -ulong get_timer (ulong base) -{ - return get_timer_masked () - base; -} - -void set_timer (ulong t) -{ - /* nop */ -} - -void __udelay (unsigned long usec) -{ - udelay_masked (usec); -} - - -void reset_timer_masked (void) +unsigned long long get_ticks(void) { - writel(0, OSCR); + /* Current tick value */ + uint32_t now = readl(OSCR); + + 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; @@ -105,25 +93,9 @@ 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 get_tbclk(void) { - ulong tbclk; - tbclk = TIMER_FREQ_HZ; - return tbclk; + return TIMER_FREQ_HZ; }