Skip to content

Commit

Permalink
OMAP3: cpuidle: change the power domains modes determination logic
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jean Pihet authored and Kevin Hilman committed May 20, 2011
1 parent c6cd91d commit 0490891
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 50 deletions.
58 changes: 24 additions & 34 deletions arch/arm/mach-omap2/cpuidle34xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,22 +138,40 @@ static int omap3_enter_idle(struct cpuidle_device *dev,
}

/**
* next_valid_state - Find next valid c-state
* next_valid_state - Find next valid C-state
* @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.
* Else, this function searches for a lower c-state which is still
* 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,
struct cpuidle_state *curr)
{
struct cpuidle_state *next = NULL;
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 */
if (cx->valid) {
if ((cx->valid) &&
(cx->mpu_state >= mpu_deepest_state) &&
(cx->core_state >= core_deepest_state)) {
return curr;
} else {
int idx = OMAP3_NUM_STATES - 1;
Expand All @@ -176,7 +194,9 @@ static struct cpuidle_state *next_valid_state(struct cpuidle_device *dev,
idx--;
for (; idx >= 0; 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];
break;
}
Expand Down Expand Up @@ -259,31 +279,6 @@ static int omap3_enter_idle_bm(struct cpuidle_device *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)
{
int i;
Expand Down Expand Up @@ -393,11 +388,6 @@ int __init omap3_idle_init(void)
cx->mpu_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;
if (cpuidle_register_device(dev)) {
printk(KERN_ERR "%s: CPUidle register device failed\n",
Expand Down
4 changes: 0 additions & 4 deletions arch/arm/mach-omap2/pm.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,6 @@ extern u32 sleep_while_idle;
#define sleep_while_idle 0
#endif

#if defined(CONFIG_CPU_IDLE)
extern void omap3_cpuidle_update_states(u32, u32);
#endif

#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
extern void pm_dbg_update_time(struct powerdomain *pwrdm, int prev);
extern int pm_dbg_regset_save(int reg_set);
Expand Down
12 changes: 0 additions & 12 deletions arch/arm/mach-omap2/pm34xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -779,18 +779,6 @@ void omap3_pm_off_mode_enable(int enable)
else
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) {
if (IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583) &&
pwrst->pwrdm == core_pwrdm &&
Expand Down

0 comments on commit 0490891

Please sign in to comment.