OMAP3: cpuidle: change the power domains modes determination logic
The achievable power modes of the power domains in cpuidle depends on the system wide 'enable_off_mode' knob in debugfs. Upon changing enable_off_mode, do not change the C-states 'valid' field but instead dynamically restrict the power modes when entering idle. The C-states 'valid' field is just used to enable/disable some C-states at init and shall not be changed later on. Signed-off-by: Jean Pihet <j-pihet@ti.com> Signed-off-by: Kevin Hilman <khilman@ti.com>
This commit is contained in:
parent
c6cd91de1c
commit
0490891819
|
@ -138,22 +138,40 @@ return_sleep_time:
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* next_valid_state - Find next valid c-state
|
* next_valid_state - Find next valid C-state
|
||||||
* @dev: cpuidle device
|
* @dev: cpuidle device
|
||||||
* @state: Currently selected c-state
|
* @state: Currently selected C-state
|
||||||
*
|
*
|
||||||
* If the current state is valid, it is returned back to the caller.
|
* If the current state is valid, it is returned back to the caller.
|
||||||
* Else, this function searches for a lower c-state which is still
|
* Else, this function searches for a lower c-state which is still
|
||||||
* valid.
|
* valid.
|
||||||
|
*
|
||||||
|
* A state is valid if the 'valid' field is enabled and
|
||||||
|
* if it satisfies the enable_off_mode condition.
|
||||||
*/
|
*/
|
||||||
static struct cpuidle_state *next_valid_state(struct cpuidle_device *dev,
|
static struct cpuidle_state *next_valid_state(struct cpuidle_device *dev,
|
||||||
struct cpuidle_state *curr)
|
struct cpuidle_state *curr)
|
||||||
{
|
{
|
||||||
struct cpuidle_state *next = NULL;
|
struct cpuidle_state *next = NULL;
|
||||||
struct omap3_idle_statedata *cx = cpuidle_get_statedata(curr);
|
struct omap3_idle_statedata *cx = cpuidle_get_statedata(curr);
|
||||||
|
u32 mpu_deepest_state = PWRDM_POWER_RET;
|
||||||
|
u32 core_deepest_state = PWRDM_POWER_RET;
|
||||||
|
|
||||||
|
if (enable_off_mode) {
|
||||||
|
mpu_deepest_state = PWRDM_POWER_OFF;
|
||||||
|
/*
|
||||||
|
* Erratum i583: valable for ES rev < Es1.2 on 3630.
|
||||||
|
* CORE OFF mode is not supported in a stable form, restrict
|
||||||
|
* instead the CORE state to RET.
|
||||||
|
*/
|
||||||
|
if (!IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583))
|
||||||
|
core_deepest_state = PWRDM_POWER_OFF;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check if current state is valid */
|
/* Check if current state is valid */
|
||||||
if (cx->valid) {
|
if ((cx->valid) &&
|
||||||
|
(cx->mpu_state >= mpu_deepest_state) &&
|
||||||
|
(cx->core_state >= core_deepest_state)) {
|
||||||
return curr;
|
return curr;
|
||||||
} else {
|
} else {
|
||||||
int idx = OMAP3_NUM_STATES - 1;
|
int idx = OMAP3_NUM_STATES - 1;
|
||||||
|
@ -176,7 +194,9 @@ static struct cpuidle_state *next_valid_state(struct cpuidle_device *dev,
|
||||||
idx--;
|
idx--;
|
||||||
for (; idx >= 0; idx--) {
|
for (; idx >= 0; idx--) {
|
||||||
cx = cpuidle_get_statedata(&dev->states[idx]);
|
cx = cpuidle_get_statedata(&dev->states[idx]);
|
||||||
if (cx->valid) {
|
if ((cx->valid) &&
|
||||||
|
(cx->mpu_state >= mpu_deepest_state) &&
|
||||||
|
(cx->core_state >= core_deepest_state)) {
|
||||||
next = &dev->states[idx];
|
next = &dev->states[idx];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -259,31 +279,6 @@ select_state:
|
||||||
|
|
||||||
DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev);
|
DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev);
|
||||||
|
|
||||||
/**
|
|
||||||
* omap3_cpuidle_update_states() - Update the cpuidle states
|
|
||||||
* @mpu_deepest_state: Enable states up to and including this for mpu domain
|
|
||||||
* @core_deepest_state: Enable states up to and including this for core domain
|
|
||||||
*
|
|
||||||
* This goes through the list of states available and enables and disables the
|
|
||||||
* validity of C states based on deepest state that can be achieved for the
|
|
||||||
* variable domain
|
|
||||||
*/
|
|
||||||
void omap3_cpuidle_update_states(u32 mpu_deepest_state, u32 core_deepest_state)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < OMAP3_NUM_STATES; i++) {
|
|
||||||
struct omap3_idle_statedata *cx = &omap3_idle_data[i];
|
|
||||||
|
|
||||||
if ((cx->mpu_state >= mpu_deepest_state) &&
|
|
||||||
(cx->core_state >= core_deepest_state)) {
|
|
||||||
cx->valid = 1;
|
|
||||||
} else {
|
|
||||||
cx->valid = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void omap3_pm_init_cpuidle(struct cpuidle_params *cpuidle_board_params)
|
void omap3_pm_init_cpuidle(struct cpuidle_params *cpuidle_board_params)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -393,11 +388,6 @@ int __init omap3_idle_init(void)
|
||||||
cx->mpu_state = PWRDM_POWER_OFF;
|
cx->mpu_state = PWRDM_POWER_OFF;
|
||||||
cx->core_state = PWRDM_POWER_OFF;
|
cx->core_state = PWRDM_POWER_OFF;
|
||||||
|
|
||||||
if (enable_off_mode)
|
|
||||||
omap3_cpuidle_update_states(PWRDM_POWER_OFF, PWRDM_POWER_OFF);
|
|
||||||
else
|
|
||||||
omap3_cpuidle_update_states(PWRDM_POWER_RET, PWRDM_POWER_RET);
|
|
||||||
|
|
||||||
dev->state_count = OMAP3_NUM_STATES;
|
dev->state_count = OMAP3_NUM_STATES;
|
||||||
if (cpuidle_register_device(dev)) {
|
if (cpuidle_register_device(dev)) {
|
||||||
printk(KERN_ERR "%s: CPUidle register device failed\n",
|
printk(KERN_ERR "%s: CPUidle register device failed\n",
|
||||||
|
|
|
@ -78,10 +78,6 @@ extern u32 sleep_while_idle;
|
||||||
#define sleep_while_idle 0
|
#define sleep_while_idle 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_CPU_IDLE)
|
|
||||||
extern void omap3_cpuidle_update_states(u32, u32);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
|
#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
|
||||||
extern void pm_dbg_update_time(struct powerdomain *pwrdm, int prev);
|
extern void pm_dbg_update_time(struct powerdomain *pwrdm, int prev);
|
||||||
extern int pm_dbg_regset_save(int reg_set);
|
extern int pm_dbg_regset_save(int reg_set);
|
||||||
|
|
|
@ -779,18 +779,6 @@ void omap3_pm_off_mode_enable(int enable)
|
||||||
else
|
else
|
||||||
state = PWRDM_POWER_RET;
|
state = PWRDM_POWER_RET;
|
||||||
|
|
||||||
#ifdef CONFIG_CPU_IDLE
|
|
||||||
/*
|
|
||||||
* Erratum i583: implementation for ES rev < Es1.2 on 3630. We cannot
|
|
||||||
* enable OFF mode in a stable form for previous revisions, restrict
|
|
||||||
* instead to RET
|
|
||||||
*/
|
|
||||||
if (IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583))
|
|
||||||
omap3_cpuidle_update_states(state, PWRDM_POWER_RET);
|
|
||||||
else
|
|
||||||
omap3_cpuidle_update_states(state, state);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
list_for_each_entry(pwrst, &pwrst_list, node) {
|
list_for_each_entry(pwrst, &pwrst_list, node) {
|
||||||
if (IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583) &&
|
if (IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583) &&
|
||||||
pwrst->pwrdm == core_pwrdm &&
|
pwrst->pwrdm == core_pwrdm &&
|
||||||
|
|
Loading…
Reference in New Issue