OMAP3630: PM: Erratum i583: disable coreoff if < ES1.2
authorEduardo Valentin <eduardo.valentin@nokia.com>
Mon, 20 Dec 2010 20:05:09 +0000 (14:05 -0600)
committerKevin Hilman <khilman@deeprootsystems.com>
Tue, 21 Dec 2010 22:45:53 +0000 (14:45 -0800)
Limitation i583: Self_Refresh Exit issue after OFF mode

Issue:
When device is waking up from OFF mode, then SDRC state machine sends
inappropriate sequence violating JEDEC standards.

Impact:
OMAP3630 < ES1.2 is impacted as follows depending on the platform:
CS0: for 38.4MHz as internal sysclk, DDR content seen to be stable, while
for all other sysclk frequencies, varied levels of instability
seen based on varied parameters.
CS1: impacted

This patch takes option #3 as recommended by the Silicon erratum:
Avoid core power domain transitioning to OFF mode. Power consumption
impact is expected in this case.
To do this, we route core OFF requests to RET request on the impacted
revisions of silicon.

Acked-by: Jean Pihet <j-pihet@ti.com>
[nm@ti.com: rebased the code to 2.6.37-rc2- short circuit code changed a bit]
Signed-off-by: Nishanth Menon <nm@ti.com>
Signed-off-by: Eduardo Valentin <eduardo.valentin@nokia.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
arch/arm/mach-omap2/cpuidle34xx.c
arch/arm/mach-omap2/pm.h
arch/arm/mach-omap2/pm34xx.c

index f290e484e5766e5f6307a5f840c639df6a2c389a..0fb619c52588fee0a668191c0ee16cc1a3e435d0 100644 (file)
@@ -453,6 +453,18 @@ void omap_init_power_states(void)
        omap3_power_states[OMAP3_STATE_C7].core_state = PWRDM_POWER_OFF;
        omap3_power_states[OMAP3_STATE_C7].flags = CPUIDLE_FLAG_TIME_VALID |
                                CPUIDLE_FLAG_CHECK_BM;
+
+       /*
+        * Erratum i583: implementation for ES rev < Es1.2 on 3630. We cannot
+        * enable OFF mode in a stable form for previous revisions.
+        * we disable C7 state as a result.
+        */
+       if (IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583)) {
+               omap3_power_states[OMAP3_STATE_C7].valid = 0;
+               cpuidle_params_table[OMAP3_STATE_C7].valid = 0;
+               WARN_ONCE(1, "%s: core off state C7 disabled due to i583\n",
+                               __func__);
+       }
 }
 
 struct cpuidle_driver omap3_idle_driver = {
index 29663cc01a59bdeaf261f79f788b3d5598bef1a4..b4e66f9e1945dcf2029117655fa8655c45f64f61 100644 (file)
@@ -86,6 +86,7 @@ extern unsigned int omap24xx_cpu_suspend_sz;
 extern unsigned int omap34xx_cpu_suspend_sz;
 
 #define PM_RTA_ERRATUM_i608            (1 << 0)
+#define PM_SDRC_WAKEUP_ERRATUM_i583    (1 << 1)
 
 #if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3)
 extern u16 pm34xx_errata;
index 74bc15e71e9fe79497ecb25d0324596da498a103..a81ed251e6672695c4c5efef605e3020197960e9 100644 (file)
@@ -917,12 +917,29 @@ void omap3_pm_off_mode_enable(int enable)
                state = PWRDM_POWER_RET;
 
 #ifdef CONFIG_CPU_IDLE
-       omap3_cpuidle_update_states(state, state);
+       /*
+        * Erratum i583: implementation for ES rev < Es1.2 on 3630. We cannot
+        * enable OFF mode in a stable form for previous revisions, restrict
+        * instead to RET
+        */
+       if (IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583))
+               omap3_cpuidle_update_states(state, PWRDM_POWER_RET);
+       else
+               omap3_cpuidle_update_states(state, state);
 #endif
 
        list_for_each_entry(pwrst, &pwrst_list, node) {
-               pwrst->next_state = state;
-               omap_set_pwrdm_state(pwrst->pwrdm, state);
+               if (IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583) &&
+                               pwrst->pwrdm == core_pwrdm &&
+                               state == PWRDM_POWER_OFF) {
+                       pwrst->next_state = PWRDM_POWER_RET;
+                       WARN_ONCE(1,
+                               "%s: Core OFF disabled due to errata i583\n",
+                               __func__);
+               } else {
+                       pwrst->next_state = state;
+               }
+               omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
        }
 }
 
@@ -1000,6 +1017,8 @@ static void __init pm_errata_configure(void)
                pm34xx_errata |= PM_RTA_ERRATUM_i608;
                /* Enable the l2 cache toggling in sleep logic */
                enable_omap3630_toggle_l2_on_restore();
+               if (omap_rev() < OMAP3630_REV_ES1_2)
+                       pm34xx_errata |= PM_SDRC_WAKEUP_ERRATUM_i583;
        }
 }