aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimo Teras <timo.teras@solidboot.com>2006-09-25 05:41:35 -0400
committerTony Lindgren <tony@atomide.com>2006-09-25 05:41:35 -0400
commitfa4bb626c660ada7cad3cc7e45da14f8ec17847c (patch)
tree8f8d3c09b2ace6721d36b3e53fe29bfcf44914f9
parent123e9a5573098dbb10194c18d6d575620d0e94f3 (diff)
ARM: OMAP: Use GPT iclk only when needed
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>
-rw-r--r--arch/arm/plat-omap/dmtimer.c75
1 files changed, 62 insertions, 13 deletions
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index 50524436de63..fb2a23e7c172 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -79,6 +79,9 @@ struct omap_dm_timer {
79 79
80#ifdef CONFIG_ARCH_OMAP1 80#ifdef CONFIG_ARCH_OMAP1
81 81
82#define omap_dm_clk_enable(x)
83#define omap_dm_clk_disable(x)
84
82static struct omap_dm_timer dm_timers[] = { 85static struct omap_dm_timer dm_timers[] = {
83 { .phys_base = 0xfffb1400, .irq = INT_1610_GPTIMER1 }, 86 { .phys_base = 0xfffb1400, .irq = INT_1610_GPTIMER1 },
84 { .phys_base = 0xfffb1c00, .irq = INT_1610_GPTIMER2 }, 87 { .phys_base = 0xfffb1c00, .irq = INT_1610_GPTIMER2 },
@@ -92,6 +95,9 @@ static struct omap_dm_timer dm_timers[] = {
92 95
93#elif defined(CONFIG_ARCH_OMAP2) 96#elif defined(CONFIG_ARCH_OMAP2)
94 97
98#define omap_dm_clk_enable(x) clk_enable(x)
99#define omap_dm_clk_disable(x) clk_disable(x)
100
95static struct omap_dm_timer dm_timers[] = { 101static struct omap_dm_timer dm_timers[] = {
96 { .phys_base = 0x48028000, .irq = INT_24XX_GPTIMER1 }, 102 { .phys_base = 0x48028000, .irq = INT_24XX_GPTIMER1 },
97 { .phys_base = 0x4802a000, .irq = INT_24XX_GPTIMER2 }, 103 { .phys_base = 0x4802a000, .irq = INT_24XX_GPTIMER2 },
@@ -168,11 +174,15 @@ static void omap_dm_timer_reset(struct omap_dm_timer *timer)
168 174
169static void omap_dm_timer_prepare(struct omap_dm_timer *timer) 175static void omap_dm_timer_prepare(struct omap_dm_timer *timer)
170{ 176{
171#ifdef CONFIG_ARCH_OMAP2 177 omap_dm_clk_enable(timer->fclk);
172 clk_enable(timer->iclk); 178 omap_dm_clk_enable(timer->iclk);
173 clk_enable(timer->fclk); 179
174#endif
175 omap_dm_timer_reset(timer); 180 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);
176} 186}
177 187
178struct omap_dm_timer *omap_dm_timer_request(void) 188struct omap_dm_timer *omap_dm_timer_request(void)
@@ -223,11 +233,14 @@ struct omap_dm_timer *omap_dm_timer_request_specific(int id)
223 233
224void omap_dm_timer_free(struct omap_dm_timer *timer) 234void omap_dm_timer_free(struct omap_dm_timer *timer)
225{ 235{
236 omap_dm_clk_enable(timer->iclk);
226 omap_dm_timer_reset(timer); 237 omap_dm_timer_reset(timer);
227#ifdef CONFIG_ARCH_OMAP2 238 omap_dm_clk_disable(timer->iclk);
228 clk_disable(timer->iclk); 239
229 clk_disable(timer->fclk); 240 if (timer == &dm_timers[0])
230#endif 241 omap_dm_clk_disable(timer->iclk);
242 omap_dm_clk_disable(timer->fclk);
243
231 WARN_ON(!timer->reserved); 244 WARN_ON(!timer->reserved);
232 timer->reserved = 0; 245 timer->reserved = 0;
233} 246}
@@ -276,7 +289,7 @@ __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
276 289
277struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer) 290struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer)
278{ 291{
279 return timer->fclk; 292 return timer->fclk;
280} 293}
281 294
282__u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask) 295__u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
@@ -288,29 +301,35 @@ __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
288 301
289void omap_dm_timer_trigger(struct omap_dm_timer *timer) 302void omap_dm_timer_trigger(struct omap_dm_timer *timer)
290{ 303{
304 omap_dm_clk_enable(timer->iclk);
291 omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0); 305 omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0);
306 omap_dm_clk_disable(timer->iclk);
292} 307}
293 308
294void omap_dm_timer_start(struct omap_dm_timer *timer) 309void omap_dm_timer_start(struct omap_dm_timer *timer)
295{ 310{
296 u32 l; 311 u32 l;
297 312
313 omap_dm_clk_enable(timer->iclk);
298 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); 314 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
299 if (!(l & OMAP_TIMER_CTRL_ST)) { 315 if (!(l & OMAP_TIMER_CTRL_ST)) {
300 l |= OMAP_TIMER_CTRL_ST; 316 l |= OMAP_TIMER_CTRL_ST;
301 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); 317 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
302 } 318 }
319 omap_dm_clk_disable(timer->iclk);
303} 320}
304 321
305void omap_dm_timer_stop(struct omap_dm_timer *timer) 322void omap_dm_timer_stop(struct omap_dm_timer *timer)
306{ 323{
307 u32 l; 324 u32 l;
308 325
326 omap_dm_clk_enable(timer->iclk);
309 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); 327 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
310 if (l & OMAP_TIMER_CTRL_ST) { 328 if (l & OMAP_TIMER_CTRL_ST) {
311 l &= ~0x1; 329 l &= ~0x1;
312 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); 330 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
313 } 331 }
332 omap_dm_clk_disable(timer->iclk);
314} 333}
315 334
316#ifdef CONFIG_ARCH_OMAP1 335#ifdef CONFIG_ARCH_OMAP1
@@ -348,6 +367,7 @@ void omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload,
348{ 367{
349 u32 l; 368 u32 l;
350 369
370 omap_dm_clk_enable(timer->iclk);
351 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); 371 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
352 if (autoreload) 372 if (autoreload)
353 l |= OMAP_TIMER_CTRL_AR; 373 l |= OMAP_TIMER_CTRL_AR;
@@ -356,6 +376,7 @@ void omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload,
356 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); 376 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
357 omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load); 377 omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load);
358 omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0); 378 omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0);
379 omap_dm_clk_disable(timer->iclk);
359} 380}
360 381
361void omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable, 382void omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
@@ -363,6 +384,7 @@ void omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
363{ 384{
364 u32 l; 385 u32 l;
365 386
387 omap_dm_clk_enable(timer->iclk);
366 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); 388 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
367 if (enable) 389 if (enable)
368 l |= OMAP_TIMER_CTRL_CE; 390 l |= OMAP_TIMER_CTRL_CE;
@@ -370,6 +392,7 @@ void omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
370 l &= ~OMAP_TIMER_CTRL_CE; 392 l &= ~OMAP_TIMER_CTRL_CE;
371 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); 393 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
372 omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG, match); 394 omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG, match);
395 omap_dm_clk_disable(timer->iclk);
373} 396}
374 397
375 398
@@ -378,6 +401,7 @@ void omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
378{ 401{
379 u32 l; 402 u32 l;
380 403
404 omap_dm_clk_enable(timer->iclk);
381 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); 405 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
382 l &= ~(OMAP_TIMER_CTRL_GPOCFG | OMAP_TIMER_CTRL_SCPWM | 406 l &= ~(OMAP_TIMER_CTRL_GPOCFG | OMAP_TIMER_CTRL_SCPWM |
383 OMAP_TIMER_CTRL_PT | (0x03 << 10)); 407 OMAP_TIMER_CTRL_PT | (0x03 << 10));
@@ -387,12 +411,14 @@ void omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
387 l |= OMAP_TIMER_CTRL_PT; 411 l |= OMAP_TIMER_CTRL_PT;
388 l |= trigger << 10; 412 l |= trigger << 10;
389 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); 413 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
414 omap_dm_clk_disable(timer->iclk);
390} 415}
391 416
392void 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)
393{ 418{
394 u32 l; 419 u32 l;
395 420
421 omap_dm_clk_enable(timer->iclk);
396 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); 422 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
397 l &= ~(OMAP_TIMER_CTRL_PRE | (0x07 << 2)); 423 l &= ~(OMAP_TIMER_CTRL_PRE | (0x07 << 2));
398 if (prescaler >= 0x00 && prescaler <= 0x07) { 424 if (prescaler >= 0x00 && prescaler <= 0x07) {
@@ -400,32 +426,51 @@ void omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler)
400 l |= prescaler << 2; 426 l |= prescaler << 2;
401 } 427 }
402 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); 428 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
429 omap_dm_clk_disable(timer->iclk);
403} 430}
404 431
405void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, 432void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
406 unsigned int value) 433 unsigned int value)
407{ 434{
435 omap_dm_clk_enable(timer->iclk);
408 omap_dm_timer_write_reg(timer, OMAP_TIMER_INT_EN_REG, value); 436 omap_dm_timer_write_reg(timer, OMAP_TIMER_INT_EN_REG, value);
437 omap_dm_clk_disable(timer->iclk);
409} 438}
410 439
411unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer) 440unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
412{ 441{
413 return omap_dm_timer_read_reg(timer, OMAP_TIMER_STAT_REG); 442 unsigned int l;
443
444 omap_dm_clk_enable(timer->iclk);
445 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_STAT_REG);
446 omap_dm_clk_disable(timer->iclk);
447
448 return l;
414} 449}
415 450
416void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value) 451void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
417{ 452{
453 omap_dm_clk_enable(timer->iclk);
418 omap_dm_timer_write_reg(timer, OMAP_TIMER_STAT_REG, value); 454 omap_dm_timer_write_reg(timer, OMAP_TIMER_STAT_REG, value);
455 omap_dm_clk_disable(timer->iclk);
419} 456}
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 omap_dm_clk_enable(timer->iclk);
463 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_COUNTER_REG);
464 omap_dm_clk_disable(timer->iclk);
465
466 return l;
424} 467}
425 468
426void omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value) 469void omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value)
427{ 470{
428 return omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, value); 471 omap_dm_clk_enable(timer->iclk);
472 omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, value);
473 omap_dm_clk_disable(timer->iclk);
429} 474}
430 475
431int omap_dm_timers_active(void) 476int omap_dm_timers_active(void)
@@ -436,9 +481,13 @@ int omap_dm_timers_active(void)
436 struct omap_dm_timer *timer; 481 struct omap_dm_timer *timer;
437 482
438 timer = &dm_timers[i]; 483 timer = &dm_timers[i];
484 omap_dm_clk_enable(timer->iclk);
439 if (omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG) & 485 if (omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG) &
440 OMAP_TIMER_CTRL_ST) 486 OMAP_TIMER_CTRL_ST) {
487 omap_dm_clk_disable(timer->iclk);
441 return 1; 488 return 1;
489 }
490 omap_dm_clk_disable(timer->iclk);
442 } 491 }
443 return 0; 492 return 0;
444} 493}