diff options
author | Timo Teras <timo.teras@solidboot.com> | 2006-09-25 05:41:42 -0400 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2006-09-25 05:41:42 -0400 |
commit | 12583a70ac6b6641905e37fdd61a7f711fb4ce2b (patch) | |
tree | 3b494d5d846615c21ebe431f053e931eb403e5e4 /arch | |
parent | 893a668ee2a0bd28fbeb639ae97dd60ec8b7db66 (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.c | 73 |
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 | ||
175 | static void omap_dm_timer_prepare(struct omap_dm_timer *timer) | 176 | static 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 | ||
188 | struct omap_dm_timer *omap_dm_timer_request(void) | 182 | struct 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 | ||
234 | void omap_dm_timer_free(struct omap_dm_timer *timer) | 228 | void 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 | ||
238 | void 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 | |||
249 | void 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 | |||
248 | int omap_dm_timer_get_irq(struct omap_dm_timer *timer) | 260 | int 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 | ||
302 | void omap_dm_timer_trigger(struct omap_dm_timer *timer) | 314 | void 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 | ||
309 | void omap_dm_timer_start(struct omap_dm_timer *timer) | 319 | void 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 | ||
322 | void omap_dm_timer_stop(struct omap_dm_timer *timer) | 330 | void 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 | ||
382 | void omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable, | 386 | void 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 | ||
417 | void omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler) | 417 | void 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 | ||
432 | void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, | 430 | void 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 | ||
440 | unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer) | 436 | unsigned 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 | ||
451 | void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value) | 445 | void 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 | ||
458 | unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer) | 450 | unsigned 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 | ||
469 | void omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value) | 459 | void 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 | ||
476 | int omap_dm_timers_active(void) | 464 | int 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 | } |