Skip to content

Commit

Permalink
ARM: OMAP: Use GPT iclk only when needed
Browse files Browse the repository at this point in the history
This patch makes the OMAP2 dmtimers module using the interface
clocks only while the registers are accessed (except GPT1 which has
iclk enabled all the time).

Signed-off-by: Timo Teras <timo.teras@solidboot.com>
Signed-off-by: Juha Yrjola <juha.yrjola@solidboot.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
  • Loading branch information
Timo Teras authored and Tony Lindgren committed Sep 25, 2006
1 parent 123e9a5 commit fa4bb62
Showing 1 changed file with 62 additions and 13 deletions.
75 changes: 62 additions & 13 deletions arch/arm/plat-omap/dmtimer.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ struct omap_dm_timer {

#ifdef CONFIG_ARCH_OMAP1

#define omap_dm_clk_enable(x)
#define omap_dm_clk_disable(x)

static struct omap_dm_timer dm_timers[] = {
{ .phys_base = 0xfffb1400, .irq = INT_1610_GPTIMER1 },
{ .phys_base = 0xfffb1c00, .irq = INT_1610_GPTIMER2 },
Expand All @@ -92,6 +95,9 @@ static struct omap_dm_timer dm_timers[] = {

#elif defined(CONFIG_ARCH_OMAP2)

#define omap_dm_clk_enable(x) clk_enable(x)
#define omap_dm_clk_disable(x) clk_disable(x)

static struct omap_dm_timer dm_timers[] = {
{ .phys_base = 0x48028000, .irq = INT_24XX_GPTIMER1 },
{ .phys_base = 0x4802a000, .irq = INT_24XX_GPTIMER2 },
Expand Down Expand Up @@ -168,11 +174,15 @@ static void omap_dm_timer_reset(struct omap_dm_timer *timer)

static void omap_dm_timer_prepare(struct omap_dm_timer *timer)
{
#ifdef CONFIG_ARCH_OMAP2
clk_enable(timer->iclk);
clk_enable(timer->fclk);
#endif
omap_dm_clk_enable(timer->fclk);
omap_dm_clk_enable(timer->iclk);

omap_dm_timer_reset(timer);

/* Leave iclk enabled for GPT1 as it is needed for the
* system timer to work properly. */
if (timer != &dm_timers[0])
omap_dm_clk_disable(timer->iclk);
}

struct omap_dm_timer *omap_dm_timer_request(void)
Expand Down Expand Up @@ -223,11 +233,14 @@ struct omap_dm_timer *omap_dm_timer_request_specific(int id)

void omap_dm_timer_free(struct omap_dm_timer *timer)
{
omap_dm_clk_enable(timer->iclk);
omap_dm_timer_reset(timer);
#ifdef CONFIG_ARCH_OMAP2
clk_disable(timer->iclk);
clk_disable(timer->fclk);
#endif
omap_dm_clk_disable(timer->iclk);

if (timer == &dm_timers[0])
omap_dm_clk_disable(timer->iclk);
omap_dm_clk_disable(timer->fclk);

WARN_ON(!timer->reserved);
timer->reserved = 0;
}
Expand Down Expand Up @@ -276,7 +289,7 @@ __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)

struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer)
{
return timer->fclk;
return timer->fclk;
}

__u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
Expand All @@ -288,29 +301,35 @@ __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)

void omap_dm_timer_trigger(struct omap_dm_timer *timer)
{
omap_dm_clk_enable(timer->iclk);
omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0);
omap_dm_clk_disable(timer->iclk);
}

void omap_dm_timer_start(struct omap_dm_timer *timer)
{
u32 l;

omap_dm_clk_enable(timer->iclk);
l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
if (!(l & OMAP_TIMER_CTRL_ST)) {
l |= OMAP_TIMER_CTRL_ST;
omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
}
omap_dm_clk_disable(timer->iclk);
}

void omap_dm_timer_stop(struct omap_dm_timer *timer)
{
u32 l;

omap_dm_clk_enable(timer->iclk);
l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
if (l & OMAP_TIMER_CTRL_ST) {
l &= ~0x1;
omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
}
omap_dm_clk_disable(timer->iclk);
}

#ifdef CONFIG_ARCH_OMAP1
Expand Down Expand Up @@ -348,6 +367,7 @@ void omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload,
{
u32 l;

omap_dm_clk_enable(timer->iclk);
l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
if (autoreload)
l |= OMAP_TIMER_CTRL_AR;
Expand All @@ -356,20 +376,23 @@ void omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload,
omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load);
omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0);
omap_dm_clk_disable(timer->iclk);
}

void omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
unsigned int match)
{
u32 l;

omap_dm_clk_enable(timer->iclk);
l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
if (enable)
l |= OMAP_TIMER_CTRL_CE;
else
l &= ~OMAP_TIMER_CTRL_CE;
omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG, match);
omap_dm_clk_disable(timer->iclk);
}


Expand All @@ -378,6 +401,7 @@ void omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
{
u32 l;

omap_dm_clk_enable(timer->iclk);
l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
l &= ~(OMAP_TIMER_CTRL_GPOCFG | OMAP_TIMER_CTRL_SCPWM |
OMAP_TIMER_CTRL_PT | (0x03 << 10));
Expand All @@ -387,45 +411,66 @@ void omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
l |= OMAP_TIMER_CTRL_PT;
l |= trigger << 10;
omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
omap_dm_clk_disable(timer->iclk);
}

void omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler)
{
u32 l;

omap_dm_clk_enable(timer->iclk);
l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
l &= ~(OMAP_TIMER_CTRL_PRE | (0x07 << 2));
if (prescaler >= 0x00 && prescaler <= 0x07) {
l |= OMAP_TIMER_CTRL_PRE;
l |= prescaler << 2;
}
omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
omap_dm_clk_disable(timer->iclk);
}

void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
unsigned int value)
{
omap_dm_clk_enable(timer->iclk);
omap_dm_timer_write_reg(timer, OMAP_TIMER_INT_EN_REG, value);
omap_dm_clk_disable(timer->iclk);
}

unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
{
return omap_dm_timer_read_reg(timer, OMAP_TIMER_STAT_REG);
unsigned int l;

omap_dm_clk_enable(timer->iclk);
l = omap_dm_timer_read_reg(timer, OMAP_TIMER_STAT_REG);
omap_dm_clk_disable(timer->iclk);

return l;
}

void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
{
omap_dm_clk_enable(timer->iclk);
omap_dm_timer_write_reg(timer, OMAP_TIMER_STAT_REG, value);
omap_dm_clk_disable(timer->iclk);
}

unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)
{
return omap_dm_timer_read_reg(timer, OMAP_TIMER_COUNTER_REG);
unsigned int l;

omap_dm_clk_enable(timer->iclk);
l = omap_dm_timer_read_reg(timer, OMAP_TIMER_COUNTER_REG);
omap_dm_clk_disable(timer->iclk);

return l;
}

void omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value)
{
return omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, value);
omap_dm_clk_enable(timer->iclk);
omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, value);
omap_dm_clk_disable(timer->iclk);
}

int omap_dm_timers_active(void)
Expand All @@ -436,9 +481,13 @@ int omap_dm_timers_active(void)
struct omap_dm_timer *timer;

timer = &dm_timers[i];
omap_dm_clk_enable(timer->iclk);
if (omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG) &
OMAP_TIMER_CTRL_ST)
OMAP_TIMER_CTRL_ST) {
omap_dm_clk_disable(timer->iclk);
return 1;
}
omap_dm_clk_disable(timer->iclk);
}
return 0;
}
Expand Down

0 comments on commit fa4bb62

Please sign in to comment.