|
|
|
@ -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) |
|
|
|
|
{ |
|
|
|
|
return get_timer_masked () - base; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void __udelay (unsigned long usec) |
|
|
|
|
unsigned long long get_ticks(void) |
|
|
|
|
{ |
|
|
|
|
udelay_masked (usec); |
|
|
|
|
/* 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; |
|
|
|
@ -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; |
|
|
|
|
} |
|
|
|
|