Commit 6099dd37 authored by Rajendra Nayak's avatar Rajendra Nayak Committed by Nishanth Menon

ARM: OMAP5 / DRA7: Enable CPU RET on suspend

On OMAP5 / DRA7, prevent a CPU powerdomain OFF and resulting MPU OSWR
and instead attempt a CPU RET and side effect, MPU RET in suspend.

NOTE: the hardware was originally designed to be capable of achieving
deep power states such as OFF and OSWR, however due to various issues
and risks, deepest valid state was determined to be CSWR - hence we use
the errata framework to handle this case.
Signed-off-by: default avatarRajendra Nayak <rnayak@ti.com>
[nm@ti.com: updates]
Signed-off-by: default avatarNishanth Menon <nm@ti.com>
Reviewed-by: default avatarKevin Hilman <khilman@linaro.org>
Tested-by: default avatarKevin Hilman <khilman@linaro.org>
parent e97c4eb3
...@@ -242,6 +242,10 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) ...@@ -242,6 +242,10 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
save_state = 1; save_state = 1;
break; break;
case PWRDM_POWER_RET: case PWRDM_POWER_RET:
if (IS_PM44XX_ERRATUM(PM_OMAP4_CPU_OSWR_DISABLE)) {
save_state = 0;
break;
}
default: default:
/* /*
* CPUx CSWR is invalid hardware state. Also CPUx OSWR * CPUx CSWR is invalid hardware state. Also CPUx OSWR
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include "soc.h" #include "soc.h"
#include "omap4-sar-layout.h" #include "omap4-sar-layout.h"
#include "common.h" #include "common.h"
#include "pm.h"
#define AM43XX_NR_REG_BANKS 7 #define AM43XX_NR_REG_BANKS 7
#define AM43XX_IRQS 224 #define AM43XX_IRQS 224
...@@ -381,7 +382,7 @@ static struct notifier_block irq_notifier_block = { ...@@ -381,7 +382,7 @@ static struct notifier_block irq_notifier_block = {
static void __init irq_pm_init(void) static void __init irq_pm_init(void)
{ {
/* FIXME: Remove this when MPU OSWR support is added */ /* FIXME: Remove this when MPU OSWR support is added */
if (!soc_is_omap54xx()) if (!IS_PM44XX_ERRATUM(PM_OMAP4_CPU_OSWR_DISABLE))
cpu_pm_register_notifier(&irq_notifier_block); cpu_pm_register_notifier(&irq_notifier_block);
} }
#else #else
......
...@@ -101,6 +101,7 @@ static inline void enable_omap3630_toggle_l2_on_restore(void) { } ...@@ -101,6 +101,7 @@ static inline void enable_omap3630_toggle_l2_on_restore(void) { }
#endif /* defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) */ #endif /* defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) */
#define PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD (1 << 0) #define PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD (1 << 0)
#define PM_OMAP4_CPU_OSWR_DISABLE (1 << 1)
#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP4) #if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP4)
extern u16 pm44xx_errata; extern u16 pm44xx_errata;
......
...@@ -36,6 +36,8 @@ struct power_state { ...@@ -36,6 +36,8 @@ struct power_state {
struct list_head node; struct list_head node;
}; };
static u32 cpu_suspend_state = PWRDM_POWER_OFF;
static LIST_HEAD(pwrst_list); static LIST_HEAD(pwrst_list);
#ifdef CONFIG_SUSPEND #ifdef CONFIG_SUSPEND
...@@ -66,7 +68,7 @@ static int omap4_pm_suspend(void) ...@@ -66,7 +68,7 @@ static int omap4_pm_suspend(void)
* domain CSWR is not supported by hardware. * domain CSWR is not supported by hardware.
* More details can be found in OMAP4430 TRM section 4.3.4.2. * More details can be found in OMAP4430 TRM section 4.3.4.2.
*/ */
omap4_enter_lowpower(cpu_id, PWRDM_POWER_OFF); omap4_enter_lowpower(cpu_id, cpu_suspend_state);
/* Restore next powerdomain state */ /* Restore next powerdomain state */
list_for_each_entry(pwrst, &pwrst_list, node) { list_for_each_entry(pwrst, &pwrst_list, node) {
...@@ -112,8 +114,11 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) ...@@ -112,8 +114,11 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
* through hotplug path and CPU0 explicitly programmed * through hotplug path and CPU0 explicitly programmed
* further down in the code path * further down in the code path
*/ */
if (!strncmp(pwrdm->name, "cpu", 3)) if (!strncmp(pwrdm->name, "cpu", 3)) {
if (IS_PM44XX_ERRATUM(PM_OMAP4_CPU_OSWR_DISABLE))
cpu_suspend_state = PWRDM_POWER_RET;
return 0; return 0;
}
pwrst = kmalloc(sizeof(struct power_state), GFP_ATOMIC); pwrst = kmalloc(sizeof(struct power_state), GFP_ATOMIC);
if (!pwrst) if (!pwrst)
...@@ -238,6 +243,9 @@ int __init omap4_pm_init_early(void) ...@@ -238,6 +243,9 @@ int __init omap4_pm_init_early(void)
if (cpu_is_omap446x()) if (cpu_is_omap446x())
pm44xx_errata |= PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD; pm44xx_errata |= PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD;
if (soc_is_omap54xx() || soc_is_dra7xx())
pm44xx_errata |= PM_OMAP4_CPU_OSWR_DISABLE;
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment