aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/omap-mpuss-lowpower.c
diff options
context:
space:
mode:
authorSantosh Shilimkar <santosh.shilimkar@ti.com>2011-06-06 05:03:29 -0400
committerKevin Hilman <khilman@ti.com>2011-12-08 14:29:01 -0500
commit3ba2a7393e6be48ad7f545a743cd6f46325ba8fd (patch)
tree6bd945957e1b7bd526419ca67e9dbd6072ccdaa2 /arch/arm/mach-omap2/omap-mpuss-lowpower.c
parent5e94c6e33e7c4726ef09f46c267e9ca232c5148a (diff)
ARM: OMAP4: PM: Add MPUSS power domain OSWR support
This patch adds the MPUSS OSWR (Open Switch Retention) support. The MPUSS OSWR configuration is as below. - CPUx L1 and logic lost, MPUSS logic lost, L2 memory is retained OMAP4460 onwards, MPUSS power domain doesn't support OFF state any more anymore just like CORE power domain. The deepest state supported is OSWR. On OMAP4430 secure devices too, MPUSS off mode can't be used because of a bug which alters Ducati and Tesla states. Hence MPUSS off mode as an independent state isn't supported on OMAP44XX devices. Ofcourse when MPUSS power domain transitions to OSWR along with device off mode, it eventually hits off state since memory contents are lost. Hence the MPUSS off mode independent state is not attempted without device off mode. All the necessary infrastructure code for MPUSS off mode is in place as part of this series. Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com> Acked-by: Jean Pihet <j-pihet@ti.com> Reviewed-by: Kevin Hilman <khilman@ti.com> Tested-by: Vishwanath BS <vishwanath.bs@ti.com> Signed-off-by: Kevin Hilman <khilman@ti.com>
Diffstat (limited to 'arch/arm/mach-omap2/omap-mpuss-lowpower.c')
-rw-r--r--arch/arm/mach-omap2/omap-mpuss-lowpower.c65
1 files changed, 62 insertions, 3 deletions
diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
index 907a048fe5e9..549aff1bfecb 100644
--- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
@@ -24,8 +24,8 @@
24 * ON ON ON 24 * ON ON ON
25 * ON(Inactive) OFF ON(Inactive) 25 * ON(Inactive) OFF ON(Inactive)
26 * OFF OFF CSWR 26 * OFF OFF CSWR
27 * OFF OFF OSWR (*TBD) 27 * OFF OFF OSWR
28 * OFF OFF OFF* (*TBD) 28 * OFF OFF OFF(Device OFF *TBD)
29 * ---------------------------------------------- 29 * ----------------------------------------------
30 * 30 *
31 * Note: CPU0 is the master core and it is the last CPU to go down 31 * Note: CPU0 is the master core and it is the last CPU to go down
@@ -56,7 +56,11 @@
56#include "common.h" 56#include "common.h"
57#include "omap4-sar-layout.h" 57#include "omap4-sar-layout.h"
58#include "pm.h" 58#include "pm.h"
59#include "powerdomain.h" 59#include "prcm_mpu44xx.h"
60#include "prminst44xx.h"
61#include "prcm44xx.h"
62#include "prm44xx.h"
63#include "prm-regbits-44xx.h"
60 64
61#ifdef CONFIG_SMP 65#ifdef CONFIG_SMP
62 66
@@ -138,6 +142,48 @@ static void scu_pwrst_prepare(unsigned int cpu_id, unsigned int cpu_state)
138 __raw_writel(scu_pwr_st, pm_info->scu_sar_addr); 142 __raw_writel(scu_pwr_st, pm_info->scu_sar_addr);
139} 143}
140 144
145/* Helper functions for MPUSS OSWR */
146static inline void mpuss_clear_prev_logic_pwrst(void)
147{
148 u32 reg;
149
150 reg = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
151 OMAP4430_PRM_MPU_INST, OMAP4_RM_MPU_MPU_CONTEXT_OFFSET);
152 omap4_prminst_write_inst_reg(reg, OMAP4430_PRM_PARTITION,
153 OMAP4430_PRM_MPU_INST, OMAP4_RM_MPU_MPU_CONTEXT_OFFSET);
154}
155
156static inline void cpu_clear_prev_logic_pwrst(unsigned int cpu_id)
157{
158 u32 reg;
159
160 if (cpu_id) {
161 reg = omap4_prcm_mpu_read_inst_reg(OMAP4430_PRCM_MPU_CPU1_INST,
162 OMAP4_RM_CPU1_CPU1_CONTEXT_OFFSET);
163 omap4_prcm_mpu_write_inst_reg(reg, OMAP4430_PRCM_MPU_CPU1_INST,
164 OMAP4_RM_CPU1_CPU1_CONTEXT_OFFSET);
165 } else {
166 reg = omap4_prcm_mpu_read_inst_reg(OMAP4430_PRCM_MPU_CPU0_INST,
167 OMAP4_RM_CPU0_CPU0_CONTEXT_OFFSET);
168 omap4_prcm_mpu_write_inst_reg(reg, OMAP4430_PRCM_MPU_CPU0_INST,
169 OMAP4_RM_CPU0_CPU0_CONTEXT_OFFSET);
170 }
171}
172
173/**
174 * omap4_mpuss_read_prev_context_state:
175 * Function returns the MPUSS previous context state
176 */
177u32 omap4_mpuss_read_prev_context_state(void)
178{
179 u32 reg;
180
181 reg = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
182 OMAP4430_PRM_MPU_INST, OMAP4_RM_MPU_MPU_CONTEXT_OFFSET);
183 reg &= OMAP4430_LOSTCONTEXT_DFF_MASK;
184 return reg;
185}
186
141/* 187/*
142 * Store the CPU cluster state for L2X0 low power operations. 188 * Store the CPU cluster state for L2X0 low power operations.
143 */ 189 */
@@ -210,8 +256,18 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
210 return -ENXIO; 256 return -ENXIO;
211 } 257 }
212 258
259 /*
260 * Check MPUSS next state and save interrupt controller if needed.
261 * In MPUSS OSWR or device OFF, interrupt controller contest is lost.
262 */
263 mpuss_clear_prev_logic_pwrst();
213 pwrdm_clear_all_prev_pwrst(mpuss_pd); 264 pwrdm_clear_all_prev_pwrst(mpuss_pd);
265 if ((pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_RET) &&
266 (pwrdm_read_logic_retst(mpuss_pd) == PWRDM_POWER_OFF))
267 save_state = 2;
268
214 clear_cpu_prev_pwrst(cpu); 269 clear_cpu_prev_pwrst(cpu);
270 cpu_clear_prev_logic_pwrst(cpu);
215 set_cpu_next_pwrst(cpu, power_state); 271 set_cpu_next_pwrst(cpu, power_state);
216 set_cpu_wakeup_addr(cpu, virt_to_phys(omap4_cpu_resume)); 272 set_cpu_wakeup_addr(cpu, virt_to_phys(omap4_cpu_resume));
217 scu_pwrst_prepare(cpu, power_state); 273 scu_pwrst_prepare(cpu, power_state);
@@ -294,6 +350,7 @@ int __init omap4_mpuss_init(void)
294 350
295 /* Clear CPU previous power domain state */ 351 /* Clear CPU previous power domain state */
296 pwrdm_clear_all_prev_pwrst(pm_info->pwrdm); 352 pwrdm_clear_all_prev_pwrst(pm_info->pwrdm);
353 cpu_clear_prev_logic_pwrst(0);
297 354
298 /* Initialise CPU0 power domain state to ON */ 355 /* Initialise CPU0 power domain state to ON */
299 pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON); 356 pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON);
@@ -310,6 +367,7 @@ int __init omap4_mpuss_init(void)
310 367
311 /* Clear CPU previous power domain state */ 368 /* Clear CPU previous power domain state */
312 pwrdm_clear_all_prev_pwrst(pm_info->pwrdm); 369 pwrdm_clear_all_prev_pwrst(pm_info->pwrdm);
370 cpu_clear_prev_logic_pwrst(1);
313 371
314 /* Initialise CPU1 power domain state to ON */ 372 /* Initialise CPU1 power domain state to ON */
315 pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON); 373 pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON);
@@ -320,6 +378,7 @@ int __init omap4_mpuss_init(void)
320 return -ENODEV; 378 return -ENODEV;
321 } 379 }
322 pwrdm_clear_all_prev_pwrst(mpuss_pd); 380 pwrdm_clear_all_prev_pwrst(mpuss_pd);
381 mpuss_clear_prev_logic_pwrst();
323 382
324 /* Save device type on scratchpad for low level code to use */ 383 /* Save device type on scratchpad for low level code to use */
325 if (omap_type() != OMAP2_DEVICE_TYPE_GP) 384 if (omap_type() != OMAP2_DEVICE_TYPE_GP)