Commit 20b01669 authored by Rajendra Nayak's avatar Rajendra Nayak Committed by Kevin Hilman

OMAP3: PM: CPUidle: support retention and off-mode C-states

This patch adds support and enables state C4(MPU RET + CORE RET)
and MPU OFF states (C3 and C5.)
Signed-off-by: default avatarRajendra Nayak <rnayak@ti.com>
Signed-off-by: default avatarKevin Hilman <khilman@deeprootsystems.com>
parent 99e6a4d2
...@@ -26,6 +26,8 @@ ...@@ -26,6 +26,8 @@
#include <plat/prcm.h> #include <plat/prcm.h>
#include <plat/powerdomain.h> #include <plat/powerdomain.h>
#include <plat/irqs.h>
#include <plat/control.h>
#ifdef CONFIG_CPU_IDLE #ifdef CONFIG_CPU_IDLE
...@@ -50,10 +52,12 @@ struct omap3_processor_cx { ...@@ -50,10 +52,12 @@ struct omap3_processor_cx {
struct omap3_processor_cx omap3_power_states[OMAP3_MAX_STATES]; struct omap3_processor_cx omap3_power_states[OMAP3_MAX_STATES];
struct omap3_processor_cx current_cx_state; struct omap3_processor_cx current_cx_state;
struct powerdomain *mpu_pd; struct powerdomain *mpu_pd, *core_pd;
static int omap3_idle_bm_check(void) static int omap3_idle_bm_check(void)
{ {
if (!omap3_can_sleep())
return 1;
return 0; return 0;
} }
...@@ -79,24 +83,23 @@ static int omap3_enter_idle(struct cpuidle_device *dev, ...@@ -79,24 +83,23 @@ static int omap3_enter_idle(struct cpuidle_device *dev,
local_irq_disable(); local_irq_disable();
local_fiq_disable(); local_fiq_disable();
/* Program MPU to target state */ set_pwrdm_state(mpu_pd, cx->mpu_state);
if (cx->mpu_state < PWRDM_POWER_ON) set_pwrdm_state(core_pd, cx->core_state);
pwrdm_set_next_pwrst(mpu_pd, cx->mpu_state);
if (omap_irq_pending())
goto return_sleep_time;
/* Execute ARM wfi */ /* Execute ARM wfi */
omap_sram_idle(); omap_sram_idle();
/* Program MPU to ON */ return_sleep_time:
if (cx->mpu_state < PWRDM_POWER_ON)
pwrdm_set_next_pwrst(mpu_pd, PWRDM_POWER_ON);
getnstimeofday(&ts_postidle); getnstimeofday(&ts_postidle);
ts_idle = timespec_sub(ts_postidle, ts_preidle); ts_idle = timespec_sub(ts_postidle, ts_preidle);
local_irq_enable(); local_irq_enable();
local_fiq_enable(); local_fiq_enable();
return timespec_to_ns(&ts_idle); return (u32)timespec_to_ns(&ts_idle)/1000;
} }
/** /**
...@@ -153,7 +156,7 @@ void omap_init_power_states(void) ...@@ -153,7 +156,7 @@ void omap_init_power_states(void)
omap3_power_states[OMAP3_STATE_C2].flags = CPUIDLE_FLAG_TIME_VALID; omap3_power_states[OMAP3_STATE_C2].flags = CPUIDLE_FLAG_TIME_VALID;
/* C3 . MPU OFF + Core active */ /* C3 . MPU OFF + Core active */
omap3_power_states[OMAP3_STATE_C3].valid = 0; omap3_power_states[OMAP3_STATE_C3].valid = 1;
omap3_power_states[OMAP3_STATE_C3].type = OMAP3_STATE_C3; omap3_power_states[OMAP3_STATE_C3].type = OMAP3_STATE_C3;
omap3_power_states[OMAP3_STATE_C3].sleep_latency = 1500; omap3_power_states[OMAP3_STATE_C3].sleep_latency = 1500;
omap3_power_states[OMAP3_STATE_C3].wakeup_latency = 1800; omap3_power_states[OMAP3_STATE_C3].wakeup_latency = 1800;
...@@ -163,7 +166,7 @@ void omap_init_power_states(void) ...@@ -163,7 +166,7 @@ void omap_init_power_states(void)
omap3_power_states[OMAP3_STATE_C3].flags = CPUIDLE_FLAG_TIME_VALID; omap3_power_states[OMAP3_STATE_C3].flags = CPUIDLE_FLAG_TIME_VALID;
/* C4 . MPU CSWR + Core CSWR*/ /* C4 . MPU CSWR + Core CSWR*/
omap3_power_states[OMAP3_STATE_C4].valid = 0; omap3_power_states[OMAP3_STATE_C4].valid = 1;
omap3_power_states[OMAP3_STATE_C4].type = OMAP3_STATE_C4; omap3_power_states[OMAP3_STATE_C4].type = OMAP3_STATE_C4;
omap3_power_states[OMAP3_STATE_C4].sleep_latency = 2500; omap3_power_states[OMAP3_STATE_C4].sleep_latency = 2500;
omap3_power_states[OMAP3_STATE_C4].wakeup_latency = 7500; omap3_power_states[OMAP3_STATE_C4].wakeup_latency = 7500;
...@@ -174,7 +177,7 @@ void omap_init_power_states(void) ...@@ -174,7 +177,7 @@ void omap_init_power_states(void)
CPUIDLE_FLAG_CHECK_BM; CPUIDLE_FLAG_CHECK_BM;
/* C5 . MPU OFF + Core CSWR */ /* C5 . MPU OFF + Core CSWR */
omap3_power_states[OMAP3_STATE_C5].valid = 0; omap3_power_states[OMAP3_STATE_C5].valid = 1;
omap3_power_states[OMAP3_STATE_C5].type = OMAP3_STATE_C5; omap3_power_states[OMAP3_STATE_C5].type = OMAP3_STATE_C5;
omap3_power_states[OMAP3_STATE_C5].sleep_latency = 3000; omap3_power_states[OMAP3_STATE_C5].sleep_latency = 3000;
omap3_power_states[OMAP3_STATE_C5].wakeup_latency = 8500; omap3_power_states[OMAP3_STATE_C5].wakeup_latency = 8500;
...@@ -215,6 +218,7 @@ int omap3_idle_init(void) ...@@ -215,6 +218,7 @@ int omap3_idle_init(void)
struct cpuidle_device *dev; struct cpuidle_device *dev;
mpu_pd = pwrdm_lookup("mpu_pwrdm"); mpu_pd = pwrdm_lookup("mpu_pwrdm");
core_pd = pwrdm_lookup("core_pwrdm");
omap_init_power_states(); omap_init_power_states();
cpuidle_register_driver(&omap3_idle_driver); cpuidle_register_driver(&omap3_idle_driver);
......
...@@ -19,6 +19,8 @@ extern u32 sleep_while_idle; ...@@ -19,6 +19,8 @@ extern u32 sleep_while_idle;
extern void *omap3_secure_ram_storage; extern void *omap3_secure_ram_storage;
extern void omap3_pm_off_mode_enable(int); extern void omap3_pm_off_mode_enable(int);
extern void omap_sram_idle(void); extern void omap_sram_idle(void);
extern int omap3_can_sleep(void);
extern int set_pwrdm_state(struct powerdomain *pwrdm, u32 state);
extern int omap3_pm_get_suspend_state(struct powerdomain *pwrdm); extern int omap3_pm_get_suspend_state(struct powerdomain *pwrdm);
extern int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state); extern int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state);
......
...@@ -76,8 +76,6 @@ static struct powerdomain *mpu_pwrdm, *neon_pwrdm; ...@@ -76,8 +76,6 @@ static struct powerdomain *mpu_pwrdm, *neon_pwrdm;
static struct powerdomain *core_pwrdm, *per_pwrdm; static struct powerdomain *core_pwrdm, *per_pwrdm;
static struct powerdomain *cam_pwrdm; static struct powerdomain *cam_pwrdm;
static int set_pwrdm_state(struct powerdomain *pwrdm, u32 state);
static inline void omap3_per_save_context(void) static inline void omap3_per_save_context(void)
{ {
omap_gpio_save_context(); omap_gpio_save_context();
...@@ -503,7 +501,7 @@ static int omap3_fclks_active(void) ...@@ -503,7 +501,7 @@ static int omap3_fclks_active(void)
return 0; return 0;
} }
static int omap3_can_sleep(void) int omap3_can_sleep(void)
{ {
if (!sleep_while_idle) if (!sleep_while_idle)
return 0; return 0;
...@@ -517,7 +515,7 @@ static int omap3_can_sleep(void) ...@@ -517,7 +515,7 @@ static int omap3_can_sleep(void)
/* This sets pwrdm state (other than mpu & core. Currently only ON & /* This sets pwrdm state (other than mpu & core. Currently only ON &
* RET are supported. Function is assuming that clkdm doesn't have * RET are supported. Function is assuming that clkdm doesn't have
* hw_sup mode enabled. */ * hw_sup mode enabled. */
static int set_pwrdm_state(struct powerdomain *pwrdm, u32 state) int set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
{ {
u32 cur_state; u32 cur_state;
int sleep_switch = 0; int sleep_switch = 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