aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorMagnus Damm <damm@opensource.se>2012-07-05 01:46:47 -0400
committerRafael J. Wysocki <rjw@sisk.pl>2012-07-05 17:13:42 -0400
commit3abd69d28b7ec7607bd6f559fe618bb7db815e1c (patch)
treedd56b62f8e6be1ddb4ffd633c6be5fc4e55fb6cc /arch
parent591e2ac424434ad1e9ee508ea021f37655b59eed (diff)
ARM: shmobile: sh7372 A3SM CPUIdle support
Add CPUIdle support for the A3SM power domain on sh7372. With this in place we can turn off more of the SoC during run time and save power. Makes use of the recently introduced sh7372 INTCA A3SM power domain wakeup support. Signed-off-by: Magnus Damm <damm@opensource.se> Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-shmobile/pm-sh7372.c50
1 files changed, 36 insertions, 14 deletions
diff --git a/arch/arm/mach-shmobile/pm-sh7372.c b/arch/arm/mach-shmobile/pm-sh7372.c
index 9edd95f4beda..a38be7f06d6a 100644
--- a/arch/arm/mach-shmobile/pm-sh7372.c
+++ b/arch/arm/mach-shmobile/pm-sh7372.c
@@ -300,9 +300,6 @@ static void sh7372_set_reset_vector(unsigned long address)
300 __raw_writel(0, APARMBAREA); 300 __raw_writel(0, APARMBAREA);
301} 301}
302 302
303#endif
304
305#ifdef CONFIG_SUSPEND
306static void sh7372_enter_sysc(int pllc0_on, unsigned long sleep_mode) 303static void sh7372_enter_sysc(int pllc0_on, unsigned long sleep_mode)
307{ 304{
308 if (pllc0_on) 305 if (pllc0_on)
@@ -448,17 +445,6 @@ static void sh7372_enter_a3sm_common(int pllc0_on)
448 sh7372_enter_sysc(pllc0_on, 1 << 12); 445 sh7372_enter_sysc(pllc0_on, 1 << 12);
449} 446}
450 447
451static void sh7372_enter_a4s_common(int pllc0_on)
452{
453 sh7372_intca_suspend();
454 memcpy((void *)SMFRAM, sh7372_resume_core_standby_sysc, 0x100);
455 sh7372_set_reset_vector(SMFRAM);
456 sh7372_enter_sysc(pllc0_on, 1 << 10);
457 sh7372_intca_resume();
458}
459
460#endif
461
462#ifdef CONFIG_CPU_IDLE 448#ifdef CONFIG_CPU_IDLE
463static int sh7372_do_idle_core_standby(unsigned long unused) 449static int sh7372_do_idle_core_standby(unsigned long unused)
464{ 450{
@@ -479,6 +465,16 @@ static void sh7372_enter_core_standby(void)
479 __raw_writel(0, SBAR); 465 __raw_writel(0, SBAR);
480} 466}
481 467
468static void sh7372_enter_a3sm_pll_on(void)
469{
470 sh7372_enter_a3sm_common(1);
471}
472
473static void sh7372_enter_a3sm_pll_off(void)
474{
475 sh7372_enter_a3sm_common(0);
476}
477
482static void sh7372_cpuidle_setup(struct cpuidle_driver *drv) 478static void sh7372_cpuidle_setup(struct cpuidle_driver *drv)
483{ 479{
484 struct cpuidle_state *state = &drv->states[drv->state_count]; 480 struct cpuidle_state *state = &drv->states[drv->state_count];
@@ -489,7 +485,24 @@ static void sh7372_cpuidle_setup(struct cpuidle_driver *drv)
489 state->target_residency = 20 + 10; 485 state->target_residency = 20 + 10;
490 state->flags = CPUIDLE_FLAG_TIME_VALID; 486 state->flags = CPUIDLE_FLAG_TIME_VALID;
491 shmobile_cpuidle_modes[drv->state_count] = sh7372_enter_core_standby; 487 shmobile_cpuidle_modes[drv->state_count] = sh7372_enter_core_standby;
488 drv->state_count++;
492 489
490 state = &drv->states[drv->state_count];
491 snprintf(state->name, CPUIDLE_NAME_LEN, "C3");
492 strncpy(state->desc, "A3SM PLL ON", CPUIDLE_DESC_LEN);
493 state->exit_latency = 20;
494 state->target_residency = 30 + 20;
495 state->flags = CPUIDLE_FLAG_TIME_VALID;
496 shmobile_cpuidle_modes[drv->state_count] = sh7372_enter_a3sm_pll_on;
497 drv->state_count++;
498
499 state = &drv->states[drv->state_count];
500 snprintf(state->name, CPUIDLE_NAME_LEN, "C4");
501 strncpy(state->desc, "A3SM PLL OFF", CPUIDLE_DESC_LEN);
502 state->exit_latency = 120;
503 state->target_residency = 30 + 120;
504 state->flags = CPUIDLE_FLAG_TIME_VALID;
505 shmobile_cpuidle_modes[drv->state_count] = sh7372_enter_a3sm_pll_off;
493 drv->state_count++; 506 drv->state_count++;
494} 507}
495 508
@@ -502,6 +515,14 @@ static void sh7372_cpuidle_init(void) {}
502#endif 515#endif
503 516
504#ifdef CONFIG_SUSPEND 517#ifdef CONFIG_SUSPEND
518static void sh7372_enter_a4s_common(int pllc0_on)
519{
520 sh7372_intca_suspend();
521 memcpy((void *)SMFRAM, sh7372_resume_core_standby_sysc, 0x100);
522 sh7372_set_reset_vector(SMFRAM);
523 sh7372_enter_sysc(pllc0_on, 1 << 10);
524 sh7372_intca_resume();
525}
505 526
506static int sh7372_enter_suspend(suspend_state_t suspend_state) 527static int sh7372_enter_suspend(suspend_state_t suspend_state)
507{ 528{
@@ -562,6 +583,7 @@ static void sh7372_suspend_init(void)
562#else 583#else
563static void sh7372_suspend_init(void) {} 584static void sh7372_suspend_init(void) {}
564#endif 585#endif
586#endif /* CONFIG_SUSPEND || CONFIG_CPU_IDLE */
565 587
566void __init sh7372_pm_init(void) 588void __init sh7372_pm_init(void)
567{ 589{