Commit 8e3fb9b8 authored by Tuukka Tikkanen's avatar Tuukka Tikkanen Committed by Tony Lindgren

ARM: OMAP: Optional timer modulo code

Adds support for running 32KHz timer at 100HZ using modulo code.

Signed-off-by: Tuukka Tikkanen <>
Signed-off-by: default avatarTony Lindgren <tony@atomide.com>
parent 09172659
...@@ -117,7 +117,9 @@ config OMAP_32K_TIMER_HZ ...@@ -117,7 +117,9 @@ config OMAP_32K_TIMER_HZ
default "128" default "128"
help help
Kernel internal timer frequency should be a divisor of 32768, Kernel internal timer frequency should be a divisor of 32768,
such as 64 or 128. such as 64 or 128. If ARM Linux default HZ=100 is used, the system
will still work, but the timer interrupt will use less efficient
modulo code.
config OMAP_DM_TIMER config OMAP_DM_TIMER
bool "Use dual-mode timer" bool "Use dual-mode timer"
......
...@@ -247,6 +247,13 @@ unsigned long long sched_clock(void) ...@@ -247,6 +247,13 @@ unsigned long long sched_clock(void)
#define OMAP_32K_TIMER_TCR 0x04 #define OMAP_32K_TIMER_TCR 0x04
#define OMAP_32K_TICKS_PER_HZ (32768 / HZ) #define OMAP_32K_TICKS_PER_HZ (32768 / HZ)
#if (32768 % HZ) != 0
/* We cannot ignore modulo.
* Potential error can be as high as several percent.
*/
#define OMAP_32K_TICK_MODULO (32768 % HZ)
static unsigned modulo_count = 0; /* Counts 1/HZ units */
#endif
/* /*
* TRM says 1 / HZ = ( TVR + 1) / 32768, so TRV = (32768 / HZ) - 1 * TRM says 1 / HZ = ( TVR + 1) / 32768, so TRV = (32768 / HZ) - 1
...@@ -324,6 +331,19 @@ static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id, ...@@ -324,6 +331,19 @@ static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id,
now = omap_32k_sync_timer_read(); now = omap_32k_sync_timer_read();
while (now - omap_32k_last_tick >= OMAP_32K_TICKS_PER_HZ) { while (now - omap_32k_last_tick >= OMAP_32K_TICKS_PER_HZ) {
#ifdef OMAP_32K_TICK_MODULO
/* Modulo addition may put omap_32k_last_tick ahead of now
* and cause unwanted repetition of the while loop.
*/
if (unlikely(now - omap_32k_last_tick == ~0))
break;
modulo_count += OMAP_32K_TICK_MODULO;
if (modulo_count > HZ) {
++omap_32k_last_tick;
modulo_count -= HZ;
}
#endif
omap_32k_last_tick += OMAP_32K_TICKS_PER_HZ; omap_32k_last_tick += OMAP_32K_TICKS_PER_HZ;
timer_tick(regs); timer_tick(regs);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment