From: Rajendra Nayak <rna...@ti.com>

On HS devices on the way out of MPU OSWR and OFF ROM code wrongly
overwrites the CM L3INSTR registers. So to avoid this, save them and
restore on the way out from MPU OSWR/OFF.

Signed-off-by: Rajendra Nayak <rna...@ti.com>
Signed-off-by: Santosh Shilimkar <santosh.shilim...@ti.com>
[t-kri...@ti.com: added omap4 pm errata support]
Signed-off-by: Tero Kristo <t-kri...@ti.com>
---
 arch/arm/mach-omap2/omap-mpuss-lowpower.c |   35 ++++++++++++++++++++++++++++-
 arch/arm/mach-omap2/pm.h                  |    1 +
 arch/arm/mach-omap2/pm44xx.c              |    8 ++++++
 3 files changed, 43 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c 
b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
index 208d4a4..2ae5e2c 100644
--- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
@@ -95,6 +95,12 @@ static struct reg_tuple ivahd_reg[] = {
        {.addr = OMAP4430_PM_IVAHD_PWRSTCTRL}
 };
 
+static struct reg_tuple l3instr_reg[] = {
+       {.addr = OMAP4430_CM_L3INSTR_L3_3_CLKCTRL},
+       {.addr = OMAP4430_CM_L3INSTR_L3_INSTR_CLKCTRL},
+       {.addr = OMAP4430_CM_L3INSTR_OCP_WP1_CLKCTRL},
+};
+
 /*
  * Program the wakeup routine address for the CPU0 and CPU1
  * used for OFF or DORMANT wakeup.
@@ -262,6 +268,28 @@ static inline void restore_ivahd_tesla_regs(void)
                __raw_writel(ivahd_reg[i].val, ivahd_reg[i].addr);
 }
 
+static inline void save_l3instr_regs(void)
+{
+       int i;
+
+       if (!IS_PM44XX_ERRATUM(PM_OMAP4_ROM_L3INSTR_ERRATUM))
+               return;
+
+       for (i = 0; i < ARRAY_SIZE(l3instr_reg); i++)
+               l3instr_reg[i].val = __raw_readl(l3instr_reg[i].addr);
+}
+
+static inline void restore_l3instr_regs(void)
+{
+       int i;
+
+       if (!IS_PM44XX_ERRATUM(PM_OMAP4_ROM_L3INSTR_ERRATUM))
+               return;
+
+       for (i = 0; i < ARRAY_SIZE(l3instr_reg); i++)
+               __raw_writel(l3instr_reg[i].val, l3instr_reg[i].addr);
+}
+
 /**
  * omap4_enter_lowpower: OMAP4 MPUSS Low Power Entry Function
  * The purpose of this function is to manage low power programming
@@ -321,13 +349,16 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int 
power_state)
                omap4_cm_prepare_off();
                omap4_dpll_prepare_off();
                save_ivahd_tesla_regs();
+               save_l3instr_regs();
                save_state = 3;
        } else if ((pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_RET) &&
                (pwrdm_read_logic_retst(mpuss_pd) == PWRDM_POWER_OFF)) {
                save_ivahd_tesla_regs();
+               save_l3instr_regs();
                save_state = 2;
        } else if (pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_OFF) {
                save_ivahd_tesla_regs();
+               save_l3instr_regs();
                save_state = 3;
        }
 
@@ -352,8 +383,10 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int 
power_state)
        wakeup_cpu = smp_processor_id();
        set_cpu_next_pwrst(wakeup_cpu, PWRDM_POWER_ON);
 
-       if (omap4_mpuss_read_prev_context_state())
+       if (omap4_mpuss_read_prev_context_state()) {
                restore_ivahd_tesla_regs();
+               restore_l3instr_regs();
+       }
 
        if (omap4_device_prev_state_off()) {
                omap4_dpll_resume_off();
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 051aeb9..c312d57 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -132,6 +132,7 @@ static inline void 
enable_omap3630_toggle_l2_on_restore(void) { }
 #endif         /* defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) */
 
 #define PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM       (1 << 0)
+#define PM_OMAP4_ROM_L3INSTR_ERRATUM           (1 << 1)
 
 #if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP4)
 extern u16 pm44xx_errata;
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
index 67cb799..0472921 100644
--- a/arch/arm/mach-omap2/pm44xx.c
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -272,6 +272,14 @@ static int __init omap4_pm_init(void)
        if (cpu_is_omap443x() && omap_type() != OMAP2_DEVICE_TYPE_GP)
                pm44xx_errata |= PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM;
 
+       /*
+        * Similar to above errata, ROM code modifies L3INSTR clock
+        * registers also and these must be saved / restored during
+        * MPU OSWR / device off.
+        */
+       if (omap_type() != OMAP2_DEVICE_TYPE_GP)
+               pm44xx_errata |= PM_OMAP4_ROM_L3INSTR_ERRATUM;
+
 #ifdef CONFIG_SUSPEND
        omap_pm_suspend = omap4_pm_suspend;
 #endif
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to