From 3abd69d28b7ec7607bd6f559fe618bb7db815e1c Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 5 Jul 2012 14:46:47 +0900 Subject: [PATCH] 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 Signed-off-by: Rafael J. Wysocki --- arch/arm/mach-shmobile/pm-sh7372.c | 50 +++++++++++++++++++++--------- 1 file 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) __raw_writel(0, APARMBAREA); } -#endif - -#ifdef CONFIG_SUSPEND static void sh7372_enter_sysc(int pllc0_on, unsigned long sleep_mode) { if (pllc0_on) @@ -448,17 +445,6 @@ static void sh7372_enter_a3sm_common(int pllc0_on) sh7372_enter_sysc(pllc0_on, 1 << 12); } -static void sh7372_enter_a4s_common(int pllc0_on) -{ - sh7372_intca_suspend(); - memcpy((void *)SMFRAM, sh7372_resume_core_standby_sysc, 0x100); - sh7372_set_reset_vector(SMFRAM); - sh7372_enter_sysc(pllc0_on, 1 << 10); - sh7372_intca_resume(); -} - -#endif - #ifdef CONFIG_CPU_IDLE static int sh7372_do_idle_core_standby(unsigned long unused) { @@ -479,6 +465,16 @@ static void sh7372_enter_core_standby(void) __raw_writel(0, SBAR); } +static void sh7372_enter_a3sm_pll_on(void) +{ + sh7372_enter_a3sm_common(1); +} + +static void sh7372_enter_a3sm_pll_off(void) +{ + sh7372_enter_a3sm_common(0); +} + static void sh7372_cpuidle_setup(struct cpuidle_driver *drv) { struct cpuidle_state *state = &drv->states[drv->state_count]; @@ -489,7 +485,24 @@ static void sh7372_cpuidle_setup(struct cpuidle_driver *drv) state->target_residency = 20 + 10; state->flags = CPUIDLE_FLAG_TIME_VALID; shmobile_cpuidle_modes[drv->state_count] = sh7372_enter_core_standby; + drv->state_count++; + state = &drv->states[drv->state_count]; + snprintf(state->name, CPUIDLE_NAME_LEN, "C3"); + strncpy(state->desc, "A3SM PLL ON", CPUIDLE_DESC_LEN); + state->exit_latency = 20; + state->target_residency = 30 + 20; + state->flags = CPUIDLE_FLAG_TIME_VALID; + shmobile_cpuidle_modes[drv->state_count] = sh7372_enter_a3sm_pll_on; + drv->state_count++; + + state = &drv->states[drv->state_count]; + snprintf(state->name, CPUIDLE_NAME_LEN, "C4"); + strncpy(state->desc, "A3SM PLL OFF", CPUIDLE_DESC_LEN); + state->exit_latency = 120; + state->target_residency = 30 + 120; + state->flags = CPUIDLE_FLAG_TIME_VALID; + shmobile_cpuidle_modes[drv->state_count] = sh7372_enter_a3sm_pll_off; drv->state_count++; } @@ -502,6 +515,14 @@ static void sh7372_cpuidle_init(void) {} #endif #ifdef CONFIG_SUSPEND +static void sh7372_enter_a4s_common(int pllc0_on) +{ + sh7372_intca_suspend(); + memcpy((void *)SMFRAM, sh7372_resume_core_standby_sysc, 0x100); + sh7372_set_reset_vector(SMFRAM); + sh7372_enter_sysc(pllc0_on, 1 << 10); + sh7372_intca_resume(); +} static int sh7372_enter_suspend(suspend_state_t suspend_state) { @@ -562,6 +583,7 @@ static void sh7372_suspend_init(void) #else static void sh7372_suspend_init(void) {} #endif +#endif /* CONFIG_SUSPEND || CONFIG_CPU_IDLE */ void __init sh7372_pm_init(void) { -- 2.39.5