aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-omap/dmtimer.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/plat-omap/dmtimer.c')
-rw-r--r--arch/arm/plat-omap/dmtimer.c76
1 files changed, 61 insertions, 15 deletions
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index 50524436de63..bcbb8d7392be 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -75,10 +75,14 @@ struct omap_dm_timer {
75#endif 75#endif
76 void __iomem *io_base; 76 void __iomem *io_base;
77 unsigned reserved:1; 77 unsigned reserved:1;
78 unsigned enabled:1;
78}; 79};
79 80
80#ifdef CONFIG_ARCH_OMAP1 81#ifdef CONFIG_ARCH_OMAP1
81 82
83#define omap_dm_clk_enable(x)
84#define omap_dm_clk_disable(x)
85
82static struct omap_dm_timer dm_timers[] = { 86static struct omap_dm_timer dm_timers[] = {
83 { .phys_base = 0xfffb1400, .irq = INT_1610_GPTIMER1 }, 87 { .phys_base = 0xfffb1400, .irq = INT_1610_GPTIMER1 },
84 { .phys_base = 0xfffb1c00, .irq = INT_1610_GPTIMER2 }, 88 { .phys_base = 0xfffb1c00, .irq = INT_1610_GPTIMER2 },
@@ -92,6 +96,9 @@ static struct omap_dm_timer dm_timers[] = {
92 96
93#elif defined(CONFIG_ARCH_OMAP2) 97#elif defined(CONFIG_ARCH_OMAP2)
94 98
99#define omap_dm_clk_enable(x) clk_enable(x)
100#define omap_dm_clk_disable(x) clk_disable(x)
101
95static struct omap_dm_timer dm_timers[] = { 102static struct omap_dm_timer dm_timers[] = {
96 { .phys_base = 0x48028000, .irq = INT_24XX_GPTIMER1 }, 103 { .phys_base = 0x48028000, .irq = INT_24XX_GPTIMER1 },
97 { .phys_base = 0x4802a000, .irq = INT_24XX_GPTIMER2 }, 104 { .phys_base = 0x4802a000, .irq = INT_24XX_GPTIMER2 },
@@ -154,24 +161,28 @@ static void omap_dm_timer_reset(struct omap_dm_timer *timer)
154{ 161{
155 u32 l; 162 u32 l;
156 163
157 if (timer != &dm_timers[0]) { 164 if (!cpu_class_is_omap2() || timer != &dm_timers[0]) {
158 omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06); 165 omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06);
159 omap_dm_timer_wait_for_reset(timer); 166 omap_dm_timer_wait_for_reset(timer);
160 } 167 }
161 omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_SYS_CLK); 168 omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ);
162 169
163 /* Set to smart-idle mode */ 170 /* Set to smart-idle mode */
164 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_OCP_CFG_REG); 171 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_OCP_CFG_REG);
165 l |= 0x02 << 3; 172 l |= 0x02 << 3;
173
174 if (cpu_class_is_omap2() && timer == &dm_timers[0]) {
175 /* Enable wake-up only for GPT1 on OMAP2 CPUs*/
176 l |= 1 << 2;
177 /* Non-posted mode */
178 omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0);
179 }
166 omap_dm_timer_write_reg(timer, OMAP_TIMER_OCP_CFG_REG, l); 180 omap_dm_timer_write_reg(timer, OMAP_TIMER_OCP_CFG_REG, l);
167} 181}
168 182
169static void omap_dm_timer_prepare(struct omap_dm_timer *timer) 183static void omap_dm_timer_prepare(struct omap_dm_timer *timer)
170{ 184{
171#ifdef CONFIG_ARCH_OMAP2 185 omap_dm_timer_enable(timer);
172 clk_enable(timer->iclk);
173 clk_enable(timer->fclk);
174#endif
175 omap_dm_timer_reset(timer); 186 omap_dm_timer_reset(timer);
176} 187}
177 188
@@ -223,15 +234,36 @@ struct omap_dm_timer *omap_dm_timer_request_specific(int id)
223 234
224void omap_dm_timer_free(struct omap_dm_timer *timer) 235void omap_dm_timer_free(struct omap_dm_timer *timer)
225{ 236{
237 omap_dm_timer_enable(timer);
226 omap_dm_timer_reset(timer); 238 omap_dm_timer_reset(timer);
227#ifdef CONFIG_ARCH_OMAP2 239 omap_dm_timer_disable(timer);
228 clk_disable(timer->iclk); 240
229 clk_disable(timer->fclk);
230#endif
231 WARN_ON(!timer->reserved); 241 WARN_ON(!timer->reserved);
232 timer->reserved = 0; 242 timer->reserved = 0;
233} 243}
234 244
245void omap_dm_timer_enable(struct omap_dm_timer *timer)
246{
247 if (timer->enabled)
248 return;
249
250 omap_dm_clk_enable(timer->fclk);
251 omap_dm_clk_enable(timer->iclk);
252
253 timer->enabled = 1;
254}
255
256void omap_dm_timer_disable(struct omap_dm_timer *timer)
257{
258 if (!timer->enabled)
259 return;
260
261 omap_dm_clk_disable(timer->iclk);
262 omap_dm_clk_disable(timer->fclk);
263
264 timer->enabled = 0;
265}
266
235int omap_dm_timer_get_irq(struct omap_dm_timer *timer) 267int omap_dm_timer_get_irq(struct omap_dm_timer *timer)
236{ 268{
237 return timer->irq; 269 return timer->irq;
@@ -276,7 +308,7 @@ __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
276 308
277struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer) 309struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer)
278{ 310{
279 return timer->fclk; 311 return timer->fclk;
280} 312}
281 313
282__u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask) 314__u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
@@ -406,11 +438,16 @@ void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
406 unsigned int value) 438 unsigned int value)
407{ 439{
408 omap_dm_timer_write_reg(timer, OMAP_TIMER_INT_EN_REG, value); 440 omap_dm_timer_write_reg(timer, OMAP_TIMER_INT_EN_REG, value);
441 omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG, value);
409} 442}
410 443
411unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer) 444unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
412{ 445{
413 return omap_dm_timer_read_reg(timer, OMAP_TIMER_STAT_REG); 446 unsigned int l;
447
448 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_STAT_REG);
449
450 return l;
414} 451}
415 452
416void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value) 453void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
@@ -420,12 +457,16 @@ void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
420 457
421unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer) 458unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)
422{ 459{
423 return omap_dm_timer_read_reg(timer, OMAP_TIMER_COUNTER_REG); 460 unsigned int l;
461
462 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_COUNTER_REG);
463
464 return l;
424} 465}
425 466
426void omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value) 467void omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value)
427{ 468{
428 return omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, value); 469 omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, value);
429} 470}
430 471
431int omap_dm_timers_active(void) 472int omap_dm_timers_active(void)
@@ -436,9 +477,14 @@ int omap_dm_timers_active(void)
436 struct omap_dm_timer *timer; 477 struct omap_dm_timer *timer;
437 478
438 timer = &dm_timers[i]; 479 timer = &dm_timers[i];
480
481 if (!timer->enabled)
482 continue;
483
439 if (omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG) & 484 if (omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG) &
440 OMAP_TIMER_CTRL_ST) 485 OMAP_TIMER_CTRL_ST) {
441 return 1; 486 return 1;
487 }
442 } 488 }
443 return 0; 489 return 0;
444} 490}