Skip to content

Commit

Permalink
ARM: OMAP: DMTimer: Optimize by adding load and start
Browse files Browse the repository at this point in the history
This patch optimizes the timer load and start sequence.  By combining the
load and start a needless posted wait can be removed from the system timer
execution path.

* Before patch register writes are taking up .078% @ 500MHz during idle.

 Address                 |total  |min  |max      |avr     |count|ratio%
 old\process\default_idle|7.369s |0.0us|999.902ms|14.477ms|509. |62.661%
 ld\Global\cpu_v7_do_idle|4.265s |0.0us|375.786ms|24.374ms|175. |36.270%
                (UNKNOWN)|17.503ms|0.us|531.080us|5.119us|3419. |0.148%
 r\omap_dm_timer_set_load|8.135ms|0.0us|79.887us|15.065us|540.  |0.069% <--
 \vmlinux-old\Global\_end|2.023ms|0.0us|4.000us|0.560us|3613.   |0.017%
 -old\Global\__raw_readsw|1.962ms|0.0us|108.610us|9.167us|214.  |0.016%
 old\smc91x\smc_interrupt|1.353ms|0.0us|10.212us|2.348us|576.   |0.011%
 s/namei\__link_path_walk|1.161ms|0.0us|4.310us|0.762us|  1524. |0.009%
 \omap_dm_timer_write_reg|1.085ms|0.0us|126.150us|2.153us|504.  |0.009% <--

* After patch timer functions do not show up in top listings for long captures.

Signed-off-by: Richard Woodruff <r-woodruff2@ti.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
  • Loading branch information
Richard Woodruff authored and Tony Lindgren committed Jul 3, 2008
1 parent 0f0d080 commit 3fddd09
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 7 deletions.
9 changes: 3 additions & 6 deletions arch/arm/mach-omap2/timer-gp.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,7 @@ static struct irqaction omap2_gp_timer_irq = {
static int omap2_gp_timer_set_next_event(unsigned long cycles,
struct clock_event_device *evt)
{
omap_dm_timer_set_load(gptimer, 0, 0xffffffff - cycles);
omap_dm_timer_start(gptimer);
omap_dm_timer_set_load_start(gptimer, 0, 0xffffffff - cycles);

return 0;
}
Expand All @@ -77,8 +76,7 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode mode,
period = clk_get_rate(omap_dm_timer_get_fclk(gptimer)) / HZ;
period -= 1;

omap_dm_timer_set_load(gptimer, 1, 0xffffffff - period);
omap_dm_timer_start(gptimer);
omap_dm_timer_set_load_start(gptimer, 1, 0xffffffff - period);
break;
case CLOCK_EVT_MODE_ONESHOT:
break;
Expand Down Expand Up @@ -172,8 +170,7 @@ static void __init omap2_gp_clocksource_init(void)
tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gpt));
tick_period = (tick_rate / HZ) - 1;

omap_dm_timer_set_load(gpt, 1, 0);
omap_dm_timer_start(gpt);
omap_dm_timer_set_load_start(gpt, 1, 0);

clocksource_gpt.mult =
clocksource_khz2mult(tick_rate/1000, clocksource_gpt.shift);
Expand Down
19 changes: 18 additions & 1 deletion arch/arm/plat-omap/dmtimer.c
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,24 @@ void omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload,
omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0);
}

/* Optimized set_load which removes costly spin wait in timer_start */
void omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload,
unsigned int load)
{
u32 l;

l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
if (autoreload)
l |= OMAP_TIMER_CTRL_AR;
else
l &= ~OMAP_TIMER_CTRL_AR;
l |= OMAP_TIMER_CTRL_ST;

omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, load);
omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load);
omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
}

void omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
unsigned int match)
{
Expand All @@ -560,7 +578,6 @@ void omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG, match);
}


void omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
int toggle, int trigger)
{
Expand Down
1 change: 1 addition & 0 deletions include/asm-arm/arch-omap/dmtimer.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ void omap_dm_timer_stop(struct omap_dm_timer *timer);

void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source);
void omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload, unsigned int value);
void omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload, unsigned int value);
void omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable, unsigned int match);
void omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on, int toggle, int trigger);
void omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler);
Expand Down

0 comments on commit 3fddd09

Please sign in to comment.