mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
Merge branch 'for_3.6/pm/performance' of git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-omap-pm into devel-pm
This commit is contained in:
commit
4556494b06
@ -77,20 +77,6 @@ static struct omap3_idle_statedata omap3_idle_data[] = {
|
||||
|
||||
static struct powerdomain *mpu_pd, *core_pd, *per_pd, *cam_pd;
|
||||
|
||||
static int _cpuidle_allow_idle(struct powerdomain *pwrdm,
|
||||
struct clockdomain *clkdm)
|
||||
{
|
||||
clkdm_allow_idle(clkdm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _cpuidle_deny_idle(struct powerdomain *pwrdm,
|
||||
struct clockdomain *clkdm)
|
||||
{
|
||||
clkdm_deny_idle(clkdm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __omap3_enter_idle(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv,
|
||||
int index)
|
||||
@ -108,8 +94,8 @@ static int __omap3_enter_idle(struct cpuidle_device *dev,
|
||||
|
||||
/* Deny idle for C1 */
|
||||
if (index == 0) {
|
||||
pwrdm_for_each_clkdm(mpu_pd, _cpuidle_deny_idle);
|
||||
pwrdm_for_each_clkdm(core_pd, _cpuidle_deny_idle);
|
||||
clkdm_deny_idle(mpu_pd->pwrdm_clkdms[0]);
|
||||
clkdm_deny_idle(core_pd->pwrdm_clkdms[0]);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -131,8 +117,8 @@ static int __omap3_enter_idle(struct cpuidle_device *dev,
|
||||
|
||||
/* Re-allow idle for C1 */
|
||||
if (index == 0) {
|
||||
pwrdm_for_each_clkdm(mpu_pd, _cpuidle_allow_idle);
|
||||
pwrdm_for_each_clkdm(core_pd, _cpuidle_allow_idle);
|
||||
clkdm_allow_idle(mpu_pd->pwrdm_clkdms[0]);
|
||||
clkdm_allow_idle(core_pd->pwrdm_clkdms[0]);
|
||||
}
|
||||
|
||||
return_sleep_time:
|
||||
@ -178,7 +164,7 @@ static int next_valid_state(struct cpuidle_device *dev,
|
||||
u32 mpu_deepest_state = PWRDM_POWER_RET;
|
||||
u32 core_deepest_state = PWRDM_POWER_RET;
|
||||
int idx;
|
||||
int next_index = -1;
|
||||
int next_index = 0; /* C1 is the default value */
|
||||
|
||||
if (enable_off_mode) {
|
||||
mpu_deepest_state = PWRDM_POWER_OFF;
|
||||
@ -209,12 +195,6 @@ static int next_valid_state(struct cpuidle_device *dev,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* C1 is always valid.
|
||||
* So, no need to check for 'next_index == -1' outside
|
||||
* this loop.
|
||||
*/
|
||||
|
||||
return next_index;
|
||||
}
|
||||
|
||||
@ -228,23 +208,22 @@ static int next_valid_state(struct cpuidle_device *dev,
|
||||
* the device to the specified or a safer state.
|
||||
*/
|
||||
static int omap3_enter_idle_bm(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv,
|
||||
struct cpuidle_driver *drv,
|
||||
int index)
|
||||
{
|
||||
int new_state_idx;
|
||||
u32 core_next_state, per_next_state = 0, per_saved_state = 0, cam_state;
|
||||
u32 core_next_state, per_next_state = 0, per_saved_state = 0;
|
||||
struct omap3_idle_statedata *cx;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Prevent idle completely if CAM is active.
|
||||
* Use only C1 if CAM is active.
|
||||
* CAM does not have wakeup capability in OMAP3.
|
||||
*/
|
||||
cam_state = pwrdm_read_pwrst(cam_pd);
|
||||
if (cam_state == PWRDM_POWER_ON) {
|
||||
if (pwrdm_read_pwrst(cam_pd) == PWRDM_POWER_ON)
|
||||
new_state_idx = drv->safe_state_index;
|
||||
goto select_state;
|
||||
}
|
||||
else
|
||||
new_state_idx = next_valid_state(dev, drv, index);
|
||||
|
||||
/*
|
||||
* FIXME: we currently manage device-specific idle states
|
||||
@ -254,24 +233,28 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,
|
||||
* its own code.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Prevent PER off if CORE is not in retention or off as this
|
||||
* would disable PER wakeups completely.
|
||||
*/
|
||||
cx = &omap3_idle_data[index];
|
||||
/* Program PER state */
|
||||
cx = &omap3_idle_data[new_state_idx];
|
||||
core_next_state = cx->core_state;
|
||||
per_next_state = per_saved_state = pwrdm_read_next_pwrst(per_pd);
|
||||
if ((per_next_state == PWRDM_POWER_OFF) &&
|
||||
(core_next_state > PWRDM_POWER_RET))
|
||||
per_next_state = PWRDM_POWER_RET;
|
||||
if (new_state_idx == 0) {
|
||||
/* In C1 do not allow PER state lower than CORE state */
|
||||
if (per_next_state < core_next_state)
|
||||
per_next_state = core_next_state;
|
||||
} else {
|
||||
/*
|
||||
* Prevent PER OFF if CORE is not in RETention or OFF as this
|
||||
* would disable PER wakeups completely.
|
||||
*/
|
||||
if ((per_next_state == PWRDM_POWER_OFF) &&
|
||||
(core_next_state > PWRDM_POWER_RET))
|
||||
per_next_state = PWRDM_POWER_RET;
|
||||
}
|
||||
|
||||
/* Are we changing PER target state? */
|
||||
if (per_next_state != per_saved_state)
|
||||
pwrdm_set_next_pwrst(per_pd, per_next_state);
|
||||
|
||||
new_state_idx = next_valid_state(dev, drv, index);
|
||||
|
||||
select_state:
|
||||
ret = omap3_enter_idle(dev, drv, new_state_idx);
|
||||
|
||||
/* Restore original PER state if it was modified */
|
||||
@ -288,7 +271,7 @@ struct cpuidle_driver omap3_idle_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.states = {
|
||||
{
|
||||
.enter = omap3_enter_idle,
|
||||
.enter = omap3_enter_idle_bm,
|
||||
.exit_latency = 2 + 2,
|
||||
.target_residency = 5,
|
||||
.flags = CPUIDLE_FLAG_TIME_VALID,
|
||||
|
@ -255,7 +255,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
pwrdm_pre_transition();
|
||||
pwrdm_pre_transition(NULL);
|
||||
|
||||
/*
|
||||
* Check MPUSS next state and save interrupt controller if needed.
|
||||
@ -287,7 +287,7 @@ 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);
|
||||
|
||||
pwrdm_post_transition();
|
||||
pwrdm_post_transition(NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -70,7 +70,6 @@ void (*omap3_do_wfi_sram)(void);
|
||||
|
||||
static struct powerdomain *mpu_pwrdm, *neon_pwrdm;
|
||||
static struct powerdomain *core_pwrdm, *per_pwrdm;
|
||||
static struct powerdomain *cam_pwrdm;
|
||||
|
||||
static void omap3_core_save_context(void)
|
||||
{
|
||||
@ -273,16 +272,21 @@ void omap_sram_idle(void)
|
||||
per_next_state = pwrdm_read_next_pwrst(per_pwrdm);
|
||||
core_next_state = pwrdm_read_next_pwrst(core_pwrdm);
|
||||
|
||||
pwrdm_pre_transition();
|
||||
if (mpu_next_state < PWRDM_POWER_ON) {
|
||||
pwrdm_pre_transition(mpu_pwrdm);
|
||||
pwrdm_pre_transition(neon_pwrdm);
|
||||
}
|
||||
|
||||
/* PER */
|
||||
if (per_next_state < PWRDM_POWER_ON) {
|
||||
pwrdm_pre_transition(per_pwrdm);
|
||||
per_going_off = (per_next_state == PWRDM_POWER_OFF) ? 1 : 0;
|
||||
omap2_gpio_prepare_for_idle(per_going_off);
|
||||
}
|
||||
|
||||
/* CORE */
|
||||
if (core_next_state < PWRDM_POWER_ON) {
|
||||
pwrdm_pre_transition(core_pwrdm);
|
||||
if (core_next_state == PWRDM_POWER_OFF) {
|
||||
omap3_core_save_context();
|
||||
omap3_cm_save_context();
|
||||
@ -335,16 +339,20 @@ void omap_sram_idle(void)
|
||||
omap2_prm_clear_mod_reg_bits(OMAP3430_AUTO_OFF_MASK,
|
||||
OMAP3430_GR_MOD,
|
||||
OMAP3_PRM_VOLTCTRL_OFFSET);
|
||||
pwrdm_post_transition(core_pwrdm);
|
||||
}
|
||||
omap3_intc_resume_idle();
|
||||
|
||||
pwrdm_post_transition();
|
||||
|
||||
/* PER */
|
||||
if (per_next_state < PWRDM_POWER_ON)
|
||||
if (per_next_state < PWRDM_POWER_ON) {
|
||||
omap2_gpio_resume_after_idle();
|
||||
pwrdm_post_transition(per_pwrdm);
|
||||
}
|
||||
|
||||
clkdm_allow_idle(mpu_pwrdm->pwrdm_clkdms[0]);
|
||||
if (mpu_next_state < PWRDM_POWER_ON) {
|
||||
pwrdm_post_transition(mpu_pwrdm);
|
||||
pwrdm_post_transition(neon_pwrdm);
|
||||
}
|
||||
}
|
||||
|
||||
static void omap3_pm_idle(void)
|
||||
@ -705,7 +713,6 @@ int __init omap3_pm_init(void)
|
||||
neon_pwrdm = pwrdm_lookup("neon_pwrdm");
|
||||
per_pwrdm = pwrdm_lookup("per_pwrdm");
|
||||
core_pwrdm = pwrdm_lookup("core_pwrdm");
|
||||
cam_pwrdm = pwrdm_lookup("cam_pwrdm");
|
||||
|
||||
neon_clkdm = clkdm_lookup("neon_clkdm");
|
||||
mpu_clkdm = clkdm_lookup("mpu_clkdm");
|
||||
|
@ -981,15 +981,23 @@ int pwrdm_state_switch(struct powerdomain *pwrdm)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int pwrdm_pre_transition(void)
|
||||
int pwrdm_pre_transition(struct powerdomain *pwrdm)
|
||||
{
|
||||
pwrdm_for_each(_pwrdm_pre_transition_cb, NULL);
|
||||
if (pwrdm)
|
||||
_pwrdm_pre_transition_cb(pwrdm, NULL);
|
||||
else
|
||||
pwrdm_for_each(_pwrdm_pre_transition_cb, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pwrdm_post_transition(void)
|
||||
int pwrdm_post_transition(struct powerdomain *pwrdm)
|
||||
{
|
||||
pwrdm_for_each(_pwrdm_post_transition_cb, NULL);
|
||||
if (pwrdm)
|
||||
_pwrdm_post_transition_cb(pwrdm, NULL);
|
||||
else
|
||||
pwrdm_for_each(_pwrdm_post_transition_cb, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -213,8 +213,8 @@ bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm);
|
||||
int pwrdm_wait_transition(struct powerdomain *pwrdm);
|
||||
|
||||
int pwrdm_state_switch(struct powerdomain *pwrdm);
|
||||
int pwrdm_pre_transition(void);
|
||||
int pwrdm_post_transition(void);
|
||||
int pwrdm_pre_transition(struct powerdomain *pwrdm);
|
||||
int pwrdm_post_transition(struct powerdomain *pwrdm);
|
||||
int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm);
|
||||
int pwrdm_get_context_loss_count(struct powerdomain *pwrdm);
|
||||
bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm);
|
||||
|
Loading…
x
Reference in New Issue
Block a user