aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorTimo Teras <timo.teras@solidboot.com>2006-09-25 05:41:42 -0400
committerTony Lindgren <tony@atomide.com>2006-09-25 05:41:42 -0400
commit12583a70ac6b6641905e37fdd61a7f711fb4ce2b (patch)
tree3b494d5d846615c21ebe431f053e931eb403e5e4 /arch
parent893a668ee2a0bd28fbeb639ae97dd60ec8b7db66 (diff)
ARM: OMAP: Add enable/disable functions for dmtimer
Add enable/disable functions which effectively control the GPT iclk and fclk. 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>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/plat-omap/dmtimer.c73
1 files changed, 31 insertions, 42 deletions
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index fb2a23e7c172..8d6197497a74 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -75,6 +75,7 @@ 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
@@ -164,7 +165,7 @@ static void omap_dm_timer_reset(struct omap_dm_timer *timer)
164 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);
165 omap_dm_timer_wait_for_reset(timer); 166 omap_dm_timer_wait_for_reset(timer);
166 } 167 }
167 omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_SYS_CLK); 168 omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ);
168 169
169 /* Set to smart-idle mode */ 170 /* Set to smart-idle mode */
170 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);
@@ -174,15 +175,8 @@ static void omap_dm_timer_reset(struct omap_dm_timer *timer)
174 175
175static void omap_dm_timer_prepare(struct omap_dm_timer *timer) 176static void omap_dm_timer_prepare(struct omap_dm_timer *timer)
176{ 177{
177 omap_dm_clk_enable(timer->fclk); 178 omap_dm_timer_enable(timer);
178 omap_dm_clk_enable(timer->iclk);
179
180 omap_dm_timer_reset(timer); 179 omap_dm_timer_reset(timer);
181
182 /* Leave iclk enabled for GPT1 as it is needed for the
183 * system timer to work properly. */
184 if (timer != &dm_timers[0])
185 omap_dm_clk_disable(timer->iclk);
186} 180}
187 181
188struct omap_dm_timer *omap_dm_timer_request(void) 182struct omap_dm_timer *omap_dm_timer_request(void)
@@ -233,18 +227,36 @@ struct omap_dm_timer *omap_dm_timer_request_specific(int id)
233 227
234void omap_dm_timer_free(struct omap_dm_timer *timer) 228void omap_dm_timer_free(struct omap_dm_timer *timer)
235{ 229{
236 omap_dm_clk_enable(timer->iclk); 230 omap_dm_timer_enable(timer);
237 omap_dm_timer_reset(timer); 231 omap_dm_timer_reset(timer);
238 omap_dm_clk_disable(timer->iclk); 232 omap_dm_timer_disable(timer);
239
240 if (timer == &dm_timers[0])
241 omap_dm_clk_disable(timer->iclk);
242 omap_dm_clk_disable(timer->fclk);
243 233
244 WARN_ON(!timer->reserved); 234 WARN_ON(!timer->reserved);
245 timer->reserved = 0; 235 timer->reserved = 0;
246} 236}
247 237
238void omap_dm_timer_enable(struct omap_dm_timer *timer)
239{
240 if (timer->enabled)
241 return;
242
243 omap_dm_clk_enable(timer->fclk);
244 omap_dm_clk_enable(timer->iclk);
245
246 timer->enabled = 1;
247}
248
249void omap_dm_timer_disable(struct omap_dm_timer *timer)
250{
251 if (!timer->enabled)
252 return;
253
254 omap_dm_clk_disable(timer->iclk);
255 omap_dm_clk_disable(timer->fclk);
256
257 timer->enabled = 0;
258}
259
248int omap_dm_timer_get_irq(struct omap_dm_timer *timer) 260int omap_dm_timer_get_irq(struct omap_dm_timer *timer)
249{ 261{
250 return timer->irq; 262 return timer->irq;
@@ -301,35 +313,29 @@ __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
301 313
302void omap_dm_timer_trigger(struct omap_dm_timer *timer) 314void omap_dm_timer_trigger(struct omap_dm_timer *timer)
303{ 315{
304 omap_dm_clk_enable(timer->iclk);
305 omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0); 316 omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0);
306 omap_dm_clk_disable(timer->iclk);
307} 317}
308 318
309void omap_dm_timer_start(struct omap_dm_timer *timer) 319void omap_dm_timer_start(struct omap_dm_timer *timer)
310{ 320{
311 u32 l; 321 u32 l;
312 322
313 omap_dm_clk_enable(timer->iclk);
314 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); 323 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
315 if (!(l & OMAP_TIMER_CTRL_ST)) { 324 if (!(l & OMAP_TIMER_CTRL_ST)) {
316 l |= OMAP_TIMER_CTRL_ST; 325 l |= OMAP_TIMER_CTRL_ST;
317 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); 326 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
318 } 327 }
319 omap_dm_clk_disable(timer->iclk);
320} 328}
321 329
322void omap_dm_timer_stop(struct omap_dm_timer *timer) 330void omap_dm_timer_stop(struct omap_dm_timer *timer)
323{ 331{
324 u32 l; 332 u32 l;
325 333
326 omap_dm_clk_enable(timer->iclk);
327 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); 334 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
328 if (l & OMAP_TIMER_CTRL_ST) { 335 if (l & OMAP_TIMER_CTRL_ST) {
329 l &= ~0x1; 336 l &= ~0x1;
330 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); 337 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
331 } 338 }
332 omap_dm_clk_disable(timer->iclk);
333} 339}
334 340
335#ifdef CONFIG_ARCH_OMAP1 341#ifdef CONFIG_ARCH_OMAP1
@@ -367,7 +373,6 @@ void omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload,
367{ 373{
368 u32 l; 374 u32 l;
369 375
370 omap_dm_clk_enable(timer->iclk);
371 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); 376 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
372 if (autoreload) 377 if (autoreload)
373 l |= OMAP_TIMER_CTRL_AR; 378 l |= OMAP_TIMER_CTRL_AR;
@@ -376,7 +381,6 @@ void omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload,
376 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); 381 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
377 omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load); 382 omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load);
378 omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0); 383 omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0);
379 omap_dm_clk_disable(timer->iclk);
380} 384}
381 385
382void omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable, 386void omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
@@ -384,7 +388,6 @@ void omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
384{ 388{
385 u32 l; 389 u32 l;
386 390
387 omap_dm_clk_enable(timer->iclk);
388 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); 391 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
389 if (enable) 392 if (enable)
390 l |= OMAP_TIMER_CTRL_CE; 393 l |= OMAP_TIMER_CTRL_CE;
@@ -392,7 +395,6 @@ void omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
392 l &= ~OMAP_TIMER_CTRL_CE; 395 l &= ~OMAP_TIMER_CTRL_CE;
393 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); 396 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
394 omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG, match); 397 omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG, match);
395 omap_dm_clk_disable(timer->iclk);
396} 398}
397 399
398 400
@@ -401,7 +403,6 @@ void omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
401{ 403{
402 u32 l; 404 u32 l;
403 405
404 omap_dm_clk_enable(timer->iclk);
405 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); 406 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
406 l &= ~(OMAP_TIMER_CTRL_GPOCFG | OMAP_TIMER_CTRL_SCPWM | 407 l &= ~(OMAP_TIMER_CTRL_GPOCFG | OMAP_TIMER_CTRL_SCPWM |
407 OMAP_TIMER_CTRL_PT | (0x03 << 10)); 408 OMAP_TIMER_CTRL_PT | (0x03 << 10));
@@ -411,14 +412,12 @@ void omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
411 l |= OMAP_TIMER_CTRL_PT; 412 l |= OMAP_TIMER_CTRL_PT;
412 l |= trigger << 10; 413 l |= trigger << 10;
413 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); 414 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
414 omap_dm_clk_disable(timer->iclk);
415} 415}
416 416
417void omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler) 417void omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler)
418{ 418{
419 u32 l; 419 u32 l;
420 420
421 omap_dm_clk_enable(timer->iclk);
422 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); 421 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
423 l &= ~(OMAP_TIMER_CTRL_PRE | (0x07 << 2)); 422 l &= ~(OMAP_TIMER_CTRL_PRE | (0x07 << 2));
424 if (prescaler >= 0x00 && prescaler <= 0x07) { 423 if (prescaler >= 0x00 && prescaler <= 0x07) {
@@ -426,51 +425,40 @@ void omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler)
426 l |= prescaler << 2; 425 l |= prescaler << 2;
427 } 426 }
428 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); 427 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
429 omap_dm_clk_disable(timer->iclk);
430} 428}
431 429
432void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, 430void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
433 unsigned int value) 431 unsigned int value)
434{ 432{
435 omap_dm_clk_enable(timer->iclk);
436 omap_dm_timer_write_reg(timer, OMAP_TIMER_INT_EN_REG, value); 433 omap_dm_timer_write_reg(timer, OMAP_TIMER_INT_EN_REG, value);
437 omap_dm_clk_disable(timer->iclk);
438} 434}
439 435
440unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer) 436unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
441{ 437{
442 unsigned int l; 438 unsigned int l;
443 439
444 omap_dm_clk_enable(timer->iclk);
445 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_STAT_REG); 440 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_STAT_REG);
446 omap_dm_clk_disable(timer->iclk);
447 441
448 return l; 442 return l;
449} 443}
450 444
451void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value) 445void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
452{ 446{
453 omap_dm_clk_enable(timer->iclk);
454 omap_dm_timer_write_reg(timer, OMAP_TIMER_STAT_REG, value); 447 omap_dm_timer_write_reg(timer, OMAP_TIMER_STAT_REG, value);
455 omap_dm_clk_disable(timer->iclk);
456} 448}
457 449
458unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer) 450unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)
459{ 451{
460 unsigned int l; 452 unsigned int l;
461 453
462 omap_dm_clk_enable(timer->iclk);
463 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_COUNTER_REG); 454 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_COUNTER_REG);
464 omap_dm_clk_disable(timer->iclk);
465 455
466 return l; 456 return l;
467} 457}
468 458
469void omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value) 459void omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value)
470{ 460{
471 omap_dm_clk_enable(timer->iclk);
472 omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, value); 461 omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, value);
473 omap_dm_clk_disable(timer->iclk);
474} 462}
475 463
476int omap_dm_timers_active(void) 464int omap_dm_timers_active(void)
@@ -481,13 +469,14 @@ int omap_dm_timers_active(void)
481 struct omap_dm_timer *timer; 469 struct omap_dm_timer *timer;
482 470
483 timer = &dm_timers[i]; 471 timer = &dm_timers[i];
484 omap_dm_clk_enable(timer->iclk); 472
473 if (!timer->enabled)
474 continue;
475
485 if (omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG) & 476 if (omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG) &
486 OMAP_TIMER_CTRL_ST) { 477 OMAP_TIMER_CTRL_ST) {
487 omap_dm_clk_disable(timer->iclk);
488 return 1; 478 return 1;
489 } 479 }
490 omap_dm_clk_disable(timer->iclk);
491 } 480 }
492 return 0; 481 return 0;
493} 482}