aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/timer.c
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2011-09-16 18:44:20 -0400
committerTony Lindgren <tony@atomide.com>2011-09-19 13:28:10 -0400
commitee17f1147f010898e97dea2524b2aa3bcd2447a4 (patch)
treeb8526aa2d3f8f6830ec6f9f6834fc206850d48bc /arch/arm/mach-omap2/timer.c
parentceb1c532ba6220900e61ec7073a9234661efa450 (diff)
ARM: OMAP: Add support for dmtimer v2 ip
The registers are slightly different between v1 and v2 ip that is available in omap4 and later for some timers. Add support for v2 ip by mapping the interrupt related registers separately and adding func_base for the functional registers. Also disable dmtimer driver features on omap4 for now as those need the hwmod conversion series to deal with enabling the timers properly in omap_dm_timer_init. Signed-off-by: Afzal Mohammed <afzal@ti.com> Tested-by: Hemant Pedanekar <hemantp@ti.com> Signed-off-by: Tony Lindgren <tony@atomide.com>
Diffstat (limited to 'arch/arm/mach-omap2/timer.c')
-rw-r--r--arch/arm/mach-omap2/timer.c23
1 files changed, 12 insertions, 11 deletions
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index cf1de7d2630..69466f38841 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -78,7 +78,7 @@ static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id)
78{ 78{
79 struct clock_event_device *evt = &clockevent_gpt; 79 struct clock_event_device *evt = &clockevent_gpt;
80 80
81 __omap_dm_timer_write_status(clkev.io_base, OMAP_TIMER_INT_OVERFLOW); 81 __omap_dm_timer_write_status(&clkev, OMAP_TIMER_INT_OVERFLOW);
82 82
83 evt->event_handler(evt); 83 evt->event_handler(evt);
84 return IRQ_HANDLED; 84 return IRQ_HANDLED;
@@ -93,7 +93,7 @@ static struct irqaction omap2_gp_timer_irq = {
93static int omap2_gp_timer_set_next_event(unsigned long cycles, 93static int omap2_gp_timer_set_next_event(unsigned long cycles,
94 struct clock_event_device *evt) 94 struct clock_event_device *evt)
95{ 95{
96 __omap_dm_timer_load_start(clkev.io_base, OMAP_TIMER_CTRL_ST, 96 __omap_dm_timer_load_start(&clkev, OMAP_TIMER_CTRL_ST,
97 0xffffffff - cycles, 1); 97 0xffffffff - cycles, 1);
98 98
99 return 0; 99 return 0;
@@ -104,16 +104,16 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode mode,
104{ 104{
105 u32 period; 105 u32 period;
106 106
107 __omap_dm_timer_stop(clkev.io_base, 1, clkev.rate); 107 __omap_dm_timer_stop(&clkev, 1, clkev.rate);
108 108
109 switch (mode) { 109 switch (mode) {
110 case CLOCK_EVT_MODE_PERIODIC: 110 case CLOCK_EVT_MODE_PERIODIC:
111 period = clkev.rate / HZ; 111 period = clkev.rate / HZ;
112 period -= 1; 112 period -= 1;
113 /* Looks like we need to first set the load value separately */ 113 /* Looks like we need to first set the load value separately */
114 __omap_dm_timer_write(clkev.io_base, OMAP_TIMER_LOAD_REG, 114 __omap_dm_timer_write(&clkev, OMAP_TIMER_LOAD_REG,
115 0xffffffff - period, 1); 115 0xffffffff - period, 1);
116 __omap_dm_timer_load_start(clkev.io_base, 116 __omap_dm_timer_load_start(&clkev,
117 OMAP_TIMER_CTRL_AR | OMAP_TIMER_CTRL_ST, 117 OMAP_TIMER_CTRL_AR | OMAP_TIMER_CTRL_ST,
118 0xffffffff - period, 1); 118 0xffffffff - period, 1);
119 break; 119 break;
@@ -189,7 +189,8 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
189 clk_put(src); 189 clk_put(src);
190 } 190 }
191 } 191 }
192 __omap_dm_timer_reset(timer->io_base, 1, 1); 192 __omap_dm_timer_init_regs(timer);
193 __omap_dm_timer_reset(timer, 1, 1);
193 timer->posted = 1; 194 timer->posted = 1;
194 195
195 timer->rate = clk_get_rate(timer->fclk); 196 timer->rate = clk_get_rate(timer->fclk);
@@ -210,7 +211,7 @@ static void __init omap2_gp_clockevent_init(int gptimer_id,
210 omap2_gp_timer_irq.dev_id = (void *)&clkev; 211 omap2_gp_timer_irq.dev_id = (void *)&clkev;
211 setup_irq(clkev.irq, &omap2_gp_timer_irq); 212 setup_irq(clkev.irq, &omap2_gp_timer_irq);
212 213
213 __omap_dm_timer_int_enable(clkev.io_base, OMAP_TIMER_INT_OVERFLOW); 214 __omap_dm_timer_int_enable(&clkev, OMAP_TIMER_INT_OVERFLOW);
214 215
215 clockevent_gpt.mult = div_sc(clkev.rate, NSEC_PER_SEC, 216 clockevent_gpt.mult = div_sc(clkev.rate, NSEC_PER_SEC,
216 clockevent_gpt.shift); 217 clockevent_gpt.shift);
@@ -251,7 +252,7 @@ static struct omap_dm_timer clksrc;
251static DEFINE_CLOCK_DATA(cd); 252static DEFINE_CLOCK_DATA(cd);
252static cycle_t clocksource_read_cycles(struct clocksource *cs) 253static cycle_t clocksource_read_cycles(struct clocksource *cs)
253{ 254{
254 return (cycle_t)__omap_dm_timer_read_counter(clksrc.io_base, 1); 255 return (cycle_t)__omap_dm_timer_read_counter(&clksrc, 1);
255} 256}
256 257
257static struct clocksource clocksource_gpt = { 258static struct clocksource clocksource_gpt = {
@@ -266,7 +267,7 @@ static void notrace dmtimer_update_sched_clock(void)
266{ 267{
267 u32 cyc; 268 u32 cyc;
268 269
269 cyc = __omap_dm_timer_read_counter(clksrc.io_base, 1); 270 cyc = __omap_dm_timer_read_counter(&clksrc, 1);
270 271
271 update_sched_clock(&cd, cyc, (u32)~0); 272 update_sched_clock(&cd, cyc, (u32)~0);
272} 273}
@@ -276,7 +277,7 @@ unsigned long long notrace sched_clock(void)
276 u32 cyc = 0; 277 u32 cyc = 0;
277 278
278 if (clksrc.reserved) 279 if (clksrc.reserved)
279 cyc = __omap_dm_timer_read_counter(clksrc.io_base, 1); 280 cyc = __omap_dm_timer_read_counter(&clksrc, 1);
280 281
281 return cyc_to_sched_clock(&cd, cyc, (u32)~0); 282 return cyc_to_sched_clock(&cd, cyc, (u32)~0);
282} 283}
@@ -293,7 +294,7 @@ static void __init omap2_gp_clocksource_init(int gptimer_id,
293 pr_info("OMAP clocksource: GPTIMER%d at %lu Hz\n", 294 pr_info("OMAP clocksource: GPTIMER%d at %lu Hz\n",
294 gptimer_id, clksrc.rate); 295 gptimer_id, clksrc.rate);
295 296
296 __omap_dm_timer_load_start(clksrc.io_base, 297 __omap_dm_timer_load_start(&clksrc,
297 OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0, 1); 298 OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0, 1);
298 init_sched_clock(&cd, dmtimer_update_sched_clock, 32, clksrc.rate); 299 init_sched_clock(&cd, dmtimer_update_sched_clock, 32, clksrc.rate);
299 300