From c166381d4013fd32512f124c237f4213ae9888e9 Mon Sep 17 00:00:00 2001 From: Jean Pihet Date: Thu, 9 Dec 2010 18:39:58 +0100 Subject: OMAP2+: disable idle early in the suspend sequence Some bad interaction between the idle and the suspend paths has been identified: the idle code is called during the suspend enter and exit sequences. This could cause corruption or lock-up of resources. The solution is to move the calls to disable_hlt at the very beginning of the suspend sequence (ex. in omap3_pm_begin instead of omap3_pm_prepare), and the call to enable_hlt at the very end of the suspend sequence (ex. in omap3_pm_end instead of omap3_pm_finish). Tested with RET and OFF on Beagle and OMAP3EVM. Signed-off-by: Jean Pihet Cc: Kevin Hilman Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/pm34xx.c | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) (limited to 'arch/arm/mach-omap2/pm34xx.c') diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 648b8c50d024..5bf344a3fcf5 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -529,12 +529,6 @@ out: } #ifdef CONFIG_SUSPEND -static int omap3_pm_prepare(void) -{ - disable_hlt(); - return 0; -} - static int omap3_pm_suspend(void) { struct power_state *pwrst; @@ -597,14 +591,10 @@ static int omap3_pm_enter(suspend_state_t unused) return ret; } -static void omap3_pm_finish(void) -{ - enable_hlt(); -} - /* Hooks to enable / disable UART interrupts during suspend */ static int omap3_pm_begin(suspend_state_t state) { + disable_hlt(); suspend_state = state; omap_uart_enable_irqs(0); return 0; @@ -614,15 +604,14 @@ static void omap3_pm_end(void) { suspend_state = PM_SUSPEND_ON; omap_uart_enable_irqs(1); + enable_hlt(); return; } static struct platform_suspend_ops omap_pm_ops = { .begin = omap3_pm_begin, .end = omap3_pm_end, - .prepare = omap3_pm_prepare, .enter = omap3_pm_enter, - .finish = omap3_pm_finish, .valid = suspend_valid_only_mem, }; #endif /* CONFIG_SUSPEND */ -- cgit v1.2.1 From 8cdfd83473d9b408b924b5d32777ac3fddd251ff Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Mon, 20 Dec 2010 14:05:05 -0600 Subject: OMAP3: pm: introduce errata handling Introduce errata handling for OMAP3. This patch introduces errata variable and stub for initialization which will be filled up by follow-on patches. Signed-off-by: Nishanth Menon Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/pm34xx.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'arch/arm/mach-omap2/pm34xx.c') diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 5bf344a3fcf5..288bee32e2b2 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -68,6 +68,9 @@ static inline bool is_suspending(void) #define OMAP343X_TABLE_VALUE_OFFSET 0xc0 #define OMAP343X_CONTROL_REG_VALUE_OFFSET 0xc8 +/* pm34xx errata defined in pm.h */ +u16 pm34xx_errata; + struct power_state { struct powerdomain *pwrdm; u32 next_state; @@ -991,6 +994,10 @@ void omap_push_sram_idle(void) save_secure_ram_context_sz); } +static void __init pm_errata_configure(void) +{ +} + static int __init omap3_pm_init(void) { struct power_state *pwrst, *tmp; @@ -1000,6 +1007,8 @@ static int __init omap3_pm_init(void) if (!cpu_is_omap34xx()) return -ENODEV; + pm_errata_configure(); + printk(KERN_ERR "Power Management for TI OMAP3.\n"); /* XXX prcm_setup_regs needs to be before enabling hw -- cgit v1.2.1 From 458e999eb14a301d4176783c8fcb277f5d009b4e Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Mon, 20 Dec 2010 14:05:06 -0600 Subject: OMAP3630: PM: Erratum i608: disable RTA Erratum id: i608 RTA (Retention Till Access) feature is not supported and leads to device stability issues when enabled. This impacts modules with embedded memories on OMAP3630 Workaround is to disable RTA on boot and coming out of core off. For disabling RTA coming out of off mode, we do this by overriding the restore pointer for 3630 as the first point of entry before caches are touched and is common for GP and HS devices. To disable earlier than this could be possible by modifying the PPA for HS devices, but not for GP devices. Cc: Kevin Hilman Cc: Tony Lindgren Acked-by: Jean Pihet Acked-by: Santosh Shilimkar [ambresh@ti.com: co-developer] Signed-off-by: Ambresh K Signed-off-by: Nishanth Menon Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/pm34xx.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'arch/arm/mach-omap2/pm34xx.c') diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 288bee32e2b2..7dbc00005464 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -996,6 +996,8 @@ void omap_push_sram_idle(void) static void __init pm_errata_configure(void) { + if (cpu_is_omap3630()) + pm34xx_errata |= PM_RTA_ERRATUM_i608; } static int __init omap3_pm_init(void) @@ -1056,6 +1058,14 @@ static int __init omap3_pm_init(void) pm_idle = omap3_pm_idle; omap3_idle_init(); + /* + * RTA is disabled during initialization as per erratum i608 + * it is safer to disable RTA by the bootloader, but we would like + * to be doubly sure here and prevent any mishaps. + */ + if (IS_PM34XX_ERRATUM(PM_RTA_ERRATUM_i608)) + omap3630_ctrl_disable_rta(); + clkdm_add_wkdep(neon_clkdm, mpu_clkdm); if (omap_type() != OMAP2_DEVICE_TYPE_GP) { omap3_secure_ram_storage = -- cgit v1.2.1 From c4236d2e7913d18d058a018f0d19473eb6a11a3c Mon Sep 17 00:00:00 2001 From: Peter 'p2' De Schrijver Date: Mon, 20 Dec 2010 14:05:07 -0600 Subject: OMAP3630: PM: Disable L2 cache while invalidating L2 cache While coming out of MPU OSWR/OFF states, L2 controller is reseted. The reset behavior is implementation specific as per ARMv7 TRM and hence $L2 needs to be invalidated before it's use. Since the AUXCTRL register is also reconfigured, disable L2 cache before invalidating it and re-enables it afterwards. This is as per Cortex-A8 ARM documentation. Currently this is identified as being needed on OMAP3630 as the disable/enable is done from "public side" while, on OMAP3430, this is done in the "secure side". Cc: Kevin Hilman Cc: Tony Lindgren Acked-by: Jean Pihet Acked-by: Santosh Shilimkar [nm@ti.com: ported to 2.6.37-rc2, added hooks to enable the logic only on 3630] Signed-off-by: Nishanth Menon Signed-off-by: Eduardo Valentin Signed-off-by: Peter 'p2' De Schrijver Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/pm34xx.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'arch/arm/mach-omap2/pm34xx.c') diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 7dbc00005464..96e309d44e14 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -996,8 +996,11 @@ void omap_push_sram_idle(void) static void __init pm_errata_configure(void) { - if (cpu_is_omap3630()) + if (cpu_is_omap3630()) { pm34xx_errata |= PM_RTA_ERRATUM_i608; + /* Enable the l2 cache toggling in sleep logic */ + enable_omap3630_toggle_l2_on_restore(); + } } static int __init omap3_pm_init(void) -- cgit v1.2.1 From 80723c3fe457a5d29c178da4ac72983f47b37ed7 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Mon, 20 Dec 2010 14:05:08 -0600 Subject: OMAP3: PM: make omap3_cpuidle_update_states independent of enable_off_mode Currently omap3_cpuidle_update_states makes whole sale decision on which C states to update based on enable_off_mode variable Instead, achieve the same functionality by independently providing mpu and core deepest states the system is allowed to achieve and update the idle states accordingly. Acked-by: Santosh Shilimkar Acked-by: Jean Pihet Signed-off-by: Nishanth Menon [khilman: fixed additional user of this API in OMAP CPUidle driver] Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/pm34xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/arm/mach-omap2/pm34xx.c') diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 96e309d44e14..74bc15e71e9f 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -917,7 +917,7 @@ void omap3_pm_off_mode_enable(int enable) state = PWRDM_POWER_RET; #ifdef CONFIG_CPU_IDLE - omap3_cpuidle_update_states(); + omap3_cpuidle_update_states(state, state); #endif list_for_each_entry(pwrst, &pwrst_list, node) { -- cgit v1.2.1 From cc1b6028878646a2419b27e5f590b5e9fe01dc3d Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Mon, 20 Dec 2010 14:05:09 -0600 Subject: OMAP3630: PM: Erratum i583: disable coreoff if < ES1.2 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 [nm@ti.com: rebased the code to 2.6.37-rc2- short circuit code changed a bit] Signed-off-by: Nishanth Menon Signed-off-by: Eduardo Valentin Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/pm34xx.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) (limited to 'arch/arm/mach-omap2/pm34xx.c') diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 74bc15e71e9f..a81ed251e667 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -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; } } -- cgit v1.2.1 From 8352129166b8270253a746f336a4429b349b023d Mon Sep 17 00:00:00 2001 From: Jean Pihet Date: Sat, 18 Dec 2010 16:44:46 +0100 Subject: OMAP3: add comments for low power code errata Errata covered: - 1.157 & 1.185 - i443 - i581 Tested on N900 and Beagleboard with full RET and OFF modes, using cpuidle and suspend. Signed-off-by: Jean Pihet Acked-by: Santosh Shilimkar Tested-by: Nishanth Menon Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/pm34xx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/arm/mach-omap2/pm34xx.c') diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index a81ed251e667..c45b4fa1deeb 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -146,7 +146,7 @@ static void omap3_core_save_context(void) /* * Force write last pad into memory, as this can fail in some - * cases according to erratas 1.157, 1.185 + * cases according to errata 1.157, 1.185 */ omap_ctrl_writel(omap_ctrl_readl(OMAP343X_PADCONF_ETK_D14), OMAP343X_CONTROL_MEM_WKUP + 0x2a0); @@ -433,7 +433,7 @@ void omap_sram_idle(void) /* * On EMU/HS devices ROM code restores a SRDC value * from scratchpad which has automatic self refresh on timeout - * of AUTO_CNT = 1 enabled. This takes care of errata 1.142. + * of AUTO_CNT = 1 enabled. This takes care of erratum ID i443. * Hence store/restore the SDRC_POWER register here. */ if (omap_rev() >= OMAP3430_REV_ES3_0 && -- cgit v1.2.1