[PATCH 11/19] ARM: OMAP4: PM: save/restore CM L3INSTR registers when MPU hits OSWR/OFF mode
Tero Kristo
t-kristo at ti.com
Fri Apr 20 05:33:44 EDT 2012
From: Rajendra Nayak <rnayak at 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 <rnayak at ti.com>
Signed-off-by: Santosh Shilimkar <santosh.shilimkar at ti.com>
[t-kristo at ti.com: added omap4 pm errata support]
Signed-off-by: Tero Kristo <t-kristo at 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
More information about the linux-arm-kernel
mailing list