diff options
author | Nishanth Menon <nm@ti.com> | 2011-10-03 16:42:35 -0500 |
---|---|---|
committer | Todd Poynor <toddpoynor@google.com> | 2011-10-06 18:47:28 -0700 |
commit | 91756461f157a317be3ae6c43aca245e87c82914 (patch) | |
tree | 9377658d489b41459e736b53dca8afeb7226e9b0 | |
parent | fc2fbe4cf392293cf4ae8c43986ca5ea0cd0e102 (diff) | |
download | kernel_samsung_tuna-91756461f157a317be3ae6c43aca245e87c82914.zip kernel_samsung_tuna-91756461f157a317be3ae6c43aca245e87c82914.tar.gz kernel_samsung_tuna-91756461f157a317be3ae6c43aca245e87c82914.tar.bz2 |
OMAP4: PM: dont program to greater LP state on suspend
OMAP4 TRM chapter "Power domain transitions" clearly indicate
the approved states that each power domain can transition to.
As part of this programming, stepping down is possible to
lower power state, however, step up is required to ON mode.
Enumerating this:
PWRDM_POWER_ON ->PWRDM_POWER_INACTIVE, PWRDM_POWER_RET, PWRDM_POWER_OFF
PWRDM_POWER_INACTIVE -> PWRDM_POWER_RET, PWRDM_POWER_OFF
PWRDM_POWER_RET -> PWRDM_POWER_OFF
PWRDM_POWER_INACTIVE, PWRDM_POWER_RET, PWRDM_POWER_OFF -> PWRDM_POWER_ON
We currently ignore this transition limitation while programming to
suspend path. This can cause issues if we attempt OSWR/CSWR after
achieving a module level OFF previously (saved_state would be OFF
but achievable state might indicate point to a retention transition)
in such cases, it is better than we dont program the state.
Change-Id: I185c0b4bf88f2f4442deb9374e9d0dedab7ef36a
Reported-by: Todd Poynor <toddpoynor@google.com>
Signed-off-by: Nishanth Menon <nm@ti.com>
-rw-r--r-- | arch/arm/mach-omap2/pm44xx.c | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c index cecfa24..ead759a 100644 --- a/arch/arm/mach-omap2/pm44xx.c +++ b/arch/arm/mach-omap2/pm44xx.c @@ -513,13 +513,18 @@ static void omap4_configure_pwdm_suspend(bool is_off_mode) als = get_achievable_state(pwrst->pwrdm->pwrsts_logic_ret, logic_state, parent_power_domain); - pwrdm_set_logic_retst(pwrst->pwrdm, als); + if (als < pwrst->saved_logic_state) + pwrdm_set_logic_retst(pwrst->pwrdm, als); } if (pwrst->pwrdm->pwrsts) { pwrst->next_state = get_achievable_state(pwrst->pwrdm->pwrsts, state, parent_power_domain); - omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state); + if (pwrst->next_state < pwrst->saved_state) + omap_set_pwrdm_state(pwrst->pwrdm, + pwrst->next_state); + else + pwrst->next_state = pwrst->saved_state; } } } |