Merge branch 'pull/v3.18/powerdomain-fixes' of https://github.com/nmenon/linux-2.6-playground into omap-for-v3.18/fixes-not-urgent
This commit is contained in:
@@ -298,6 +298,10 @@ int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
|
|||||||
if (omap_rev() == OMAP4430_REV_ES1_0)
|
if (omap_rev() == OMAP4430_REV_ES1_0)
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
|
|
||||||
|
/* Use the achievable power state for the domain */
|
||||||
|
power_state = pwrdm_get_valid_lp_state(pm_info->pwrdm,
|
||||||
|
false, power_state);
|
||||||
|
|
||||||
if (power_state == PWRDM_POWER_OFF)
|
if (power_state == PWRDM_POWER_OFF)
|
||||||
cpu_state = 1;
|
cpu_state = 1;
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ u16 pm44xx_errata;
|
|||||||
struct power_state {
|
struct power_state {
|
||||||
struct powerdomain *pwrdm;
|
struct powerdomain *pwrdm;
|
||||||
u32 next_state;
|
u32 next_state;
|
||||||
|
u32 next_logic_state;
|
||||||
#ifdef CONFIG_SUSPEND
|
#ifdef CONFIG_SUSPEND
|
||||||
u32 saved_state;
|
u32 saved_state;
|
||||||
u32 saved_logic_state;
|
u32 saved_logic_state;
|
||||||
@@ -54,7 +55,7 @@ static int omap4_pm_suspend(void)
|
|||||||
/* Set targeted power domain states by suspend */
|
/* Set targeted power domain states by suspend */
|
||||||
list_for_each_entry(pwrst, &pwrst_list, node) {
|
list_for_each_entry(pwrst, &pwrst_list, node) {
|
||||||
omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
|
omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
|
||||||
pwrdm_set_logic_retst(pwrst->pwrdm, PWRDM_POWER_OFF);
|
pwrdm_set_logic_retst(pwrst->pwrdm, pwrst->next_logic_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -120,7 +121,11 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
pwrst->pwrdm = pwrdm;
|
pwrst->pwrdm = pwrdm;
|
||||||
pwrst->next_state = PWRDM_POWER_RET;
|
pwrst->next_state = pwrdm_get_valid_lp_state(pwrdm, false,
|
||||||
|
PWRDM_POWER_RET);
|
||||||
|
pwrst->next_logic_state = pwrdm_get_valid_lp_state(pwrdm, true,
|
||||||
|
PWRDM_POWER_OFF);
|
||||||
|
|
||||||
list_add(&pwrst->node, &pwrst_list);
|
list_add(&pwrst->node, &pwrst_list);
|
||||||
|
|
||||||
return omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
|
return omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
|
||||||
|
|||||||
@@ -546,7 +546,8 @@ int pwrdm_for_each_clkdm(struct powerdomain *pwrdm,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
for (i = 0; i < PWRDM_MAX_CLKDMS && !ret; i++)
|
for (i = 0; i < PWRDM_MAX_CLKDMS && !ret; i++)
|
||||||
ret = (*fn)(pwrdm, pwrdm->pwrdm_clkdms[i]);
|
if (pwrdm->pwrdm_clkdms[i])
|
||||||
|
ret = (*fn)(pwrdm, pwrdm->pwrdm_clkdms[i]);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -1079,6 +1080,82 @@ int pwrdm_post_transition(struct powerdomain *pwrdm)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pwrdm_get_valid_lp_state() - Find best match deep power state
|
||||||
|
* @pwrdm: power domain for which we want to find best match
|
||||||
|
* @is_logic_state: Are we looking for logic state match here? Should
|
||||||
|
* be one of PWRDM_xxx macro values
|
||||||
|
* @req_state: requested power state
|
||||||
|
*
|
||||||
|
* Returns: closest match for requested power state. default fallback
|
||||||
|
* is RET for logic state and ON for power state.
|
||||||
|
*
|
||||||
|
* This does a search from the power domain data looking for the
|
||||||
|
* closest valid power domain state that the hardware can achieve.
|
||||||
|
* PRCM definitions for PWRSTCTRL allows us to program whatever
|
||||||
|
* configuration we'd like, and PRCM will actually attempt such
|
||||||
|
* a transition, however if the powerdomain does not actually support it,
|
||||||
|
* we endup with a hung system. The valid power domain states are already
|
||||||
|
* available in our powerdomain data files. So this function tries to do
|
||||||
|
* the following:
|
||||||
|
* a) find if we have an exact match to the request - no issues.
|
||||||
|
* b) else find if a deeper power state is possible.
|
||||||
|
* c) failing which, it tries to find closest higher power state for the
|
||||||
|
* request.
|
||||||
|
*/
|
||||||
|
u8 pwrdm_get_valid_lp_state(struct powerdomain *pwrdm,
|
||||||
|
bool is_logic_state, u8 req_state)
|
||||||
|
{
|
||||||
|
u8 pwrdm_states = is_logic_state ? pwrdm->pwrsts_logic_ret :
|
||||||
|
pwrdm->pwrsts;
|
||||||
|
/* For logic, ret is highest and others, ON is highest */
|
||||||
|
u8 default_pwrst = is_logic_state ? PWRDM_POWER_RET : PWRDM_POWER_ON;
|
||||||
|
u8 new_pwrst;
|
||||||
|
bool found;
|
||||||
|
|
||||||
|
/* If it is already supported, nothing to search */
|
||||||
|
if (pwrdm_states & BIT(req_state))
|
||||||
|
return req_state;
|
||||||
|
|
||||||
|
if (!req_state)
|
||||||
|
goto up_search;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* So, we dont have a exact match
|
||||||
|
* Can we get a deeper power state match?
|
||||||
|
*/
|
||||||
|
new_pwrst = req_state - 1;
|
||||||
|
found = true;
|
||||||
|
while (!(pwrdm_states & BIT(new_pwrst))) {
|
||||||
|
/* No match even at OFF? Not available */
|
||||||
|
if (new_pwrst == PWRDM_POWER_OFF) {
|
||||||
|
found = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
new_pwrst--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
up_search:
|
||||||
|
/* OK, no deeper ones, can we get a higher match? */
|
||||||
|
new_pwrst = req_state + 1;
|
||||||
|
while (!(pwrdm_states & BIT(new_pwrst))) {
|
||||||
|
if (new_pwrst > PWRDM_POWER_ON) {
|
||||||
|
WARN(1, "powerdomain: %s: Fix max powerstate to ON\n",
|
||||||
|
pwrdm->name);
|
||||||
|
return PWRDM_POWER_ON;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (new_pwrst == default_pwrst)
|
||||||
|
break;
|
||||||
|
new_pwrst++;
|
||||||
|
}
|
||||||
|
done:
|
||||||
|
return new_pwrst;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* omap_set_pwrdm_state - change a powerdomain's current power state
|
* omap_set_pwrdm_state - change a powerdomain's current power state
|
||||||
* @pwrdm: struct powerdomain * to change the power state of
|
* @pwrdm: struct powerdomain * to change the power state of
|
||||||
|
|||||||
@@ -39,6 +39,7 @@
|
|||||||
#define PWRSTS_OFF_RET (PWRSTS_OFF | PWRSTS_RET)
|
#define PWRSTS_OFF_RET (PWRSTS_OFF | PWRSTS_RET)
|
||||||
#define PWRSTS_RET_ON (PWRSTS_RET | PWRSTS_ON)
|
#define PWRSTS_RET_ON (PWRSTS_RET | PWRSTS_ON)
|
||||||
#define PWRSTS_OFF_RET_ON (PWRSTS_OFF_RET | PWRSTS_ON)
|
#define PWRSTS_OFF_RET_ON (PWRSTS_OFF_RET | PWRSTS_ON)
|
||||||
|
#define PWRSTS_INA_ON (PWRSTS_INACTIVE | PWRSTS_ON)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -219,6 +220,9 @@ struct voltagedomain *pwrdm_get_voltdm(struct powerdomain *pwrdm);
|
|||||||
|
|
||||||
int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm);
|
int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm);
|
||||||
|
|
||||||
|
u8 pwrdm_get_valid_lp_state(struct powerdomain *pwrdm,
|
||||||
|
bool is_logic_state, u8 req_state);
|
||||||
|
|
||||||
int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst);
|
int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst);
|
||||||
int pwrdm_read_next_pwrst(struct powerdomain *pwrdm);
|
int pwrdm_read_next_pwrst(struct powerdomain *pwrdm);
|
||||||
int pwrdm_read_pwrst(struct powerdomain *pwrdm);
|
int pwrdm_read_pwrst(struct powerdomain *pwrdm);
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ static struct powerdomain core_54xx_pwrdm = {
|
|||||||
.prcm_offs = OMAP54XX_PRM_CORE_INST,
|
.prcm_offs = OMAP54XX_PRM_CORE_INST,
|
||||||
.prcm_partition = OMAP54XX_PRM_PARTITION,
|
.prcm_partition = OMAP54XX_PRM_PARTITION,
|
||||||
.pwrsts = PWRSTS_RET_ON,
|
.pwrsts = PWRSTS_RET_ON,
|
||||||
.pwrsts_logic_ret = PWRSTS_OFF_RET,
|
.pwrsts_logic_ret = PWRSTS_RET,
|
||||||
.banks = 5,
|
.banks = 5,
|
||||||
.pwrsts_mem_ret = {
|
.pwrsts_mem_ret = {
|
||||||
[0] = PWRSTS_OFF_RET, /* core_nret_bank */
|
[0] = PWRSTS_OFF_RET, /* core_nret_bank */
|
||||||
@@ -107,8 +107,8 @@ static struct powerdomain cpu0_54xx_pwrdm = {
|
|||||||
.voltdm = { .name = "mpu" },
|
.voltdm = { .name = "mpu" },
|
||||||
.prcm_offs = OMAP54XX_PRCM_MPU_PRM_C0_INST,
|
.prcm_offs = OMAP54XX_PRCM_MPU_PRM_C0_INST,
|
||||||
.prcm_partition = OMAP54XX_PRCM_MPU_PARTITION,
|
.prcm_partition = OMAP54XX_PRCM_MPU_PARTITION,
|
||||||
.pwrsts = PWRSTS_OFF_RET_ON,
|
.pwrsts = PWRSTS_RET_ON,
|
||||||
.pwrsts_logic_ret = PWRSTS_OFF_RET,
|
.pwrsts_logic_ret = PWRSTS_RET,
|
||||||
.banks = 1,
|
.banks = 1,
|
||||||
.pwrsts_mem_ret = {
|
.pwrsts_mem_ret = {
|
||||||
[0] = PWRSTS_OFF_RET, /* cpu0_l1 */
|
[0] = PWRSTS_OFF_RET, /* cpu0_l1 */
|
||||||
@@ -124,8 +124,8 @@ static struct powerdomain cpu1_54xx_pwrdm = {
|
|||||||
.voltdm = { .name = "mpu" },
|
.voltdm = { .name = "mpu" },
|
||||||
.prcm_offs = OMAP54XX_PRCM_MPU_PRM_C1_INST,
|
.prcm_offs = OMAP54XX_PRCM_MPU_PRM_C1_INST,
|
||||||
.prcm_partition = OMAP54XX_PRCM_MPU_PARTITION,
|
.prcm_partition = OMAP54XX_PRCM_MPU_PARTITION,
|
||||||
.pwrsts = PWRSTS_OFF_RET_ON,
|
.pwrsts = PWRSTS_RET_ON,
|
||||||
.pwrsts_logic_ret = PWRSTS_OFF_RET,
|
.pwrsts_logic_ret = PWRSTS_RET,
|
||||||
.banks = 1,
|
.banks = 1,
|
||||||
.pwrsts_mem_ret = {
|
.pwrsts_mem_ret = {
|
||||||
[0] = PWRSTS_OFF_RET, /* cpu1_l1 */
|
[0] = PWRSTS_OFF_RET, /* cpu1_l1 */
|
||||||
@@ -158,7 +158,7 @@ static struct powerdomain mpu_54xx_pwrdm = {
|
|||||||
.prcm_offs = OMAP54XX_PRM_MPU_INST,
|
.prcm_offs = OMAP54XX_PRM_MPU_INST,
|
||||||
.prcm_partition = OMAP54XX_PRM_PARTITION,
|
.prcm_partition = OMAP54XX_PRM_PARTITION,
|
||||||
.pwrsts = PWRSTS_RET_ON,
|
.pwrsts = PWRSTS_RET_ON,
|
||||||
.pwrsts_logic_ret = PWRSTS_OFF_RET,
|
.pwrsts_logic_ret = PWRSTS_RET,
|
||||||
.banks = 2,
|
.banks = 2,
|
||||||
.pwrsts_mem_ret = {
|
.pwrsts_mem_ret = {
|
||||||
[0] = PWRSTS_OFF_RET, /* mpu_l2 */
|
[0] = PWRSTS_OFF_RET, /* mpu_l2 */
|
||||||
|
|||||||
@@ -160,8 +160,8 @@ static struct powerdomain core_7xx_pwrdm = {
|
|||||||
.name = "core_pwrdm",
|
.name = "core_pwrdm",
|
||||||
.prcm_offs = DRA7XX_PRM_CORE_INST,
|
.prcm_offs = DRA7XX_PRM_CORE_INST,
|
||||||
.prcm_partition = DRA7XX_PRM_PARTITION,
|
.prcm_partition = DRA7XX_PRM_PARTITION,
|
||||||
.pwrsts = PWRSTS_RET_ON,
|
.pwrsts = PWRSTS_INA_ON,
|
||||||
.pwrsts_logic_ret = PWRSTS_OFF_RET,
|
.pwrsts_logic_ret = PWRSTS_RET,
|
||||||
.banks = 5,
|
.banks = 5,
|
||||||
.pwrsts_mem_ret = {
|
.pwrsts_mem_ret = {
|
||||||
[0] = PWRSTS_OFF_RET, /* core_nret_bank */
|
[0] = PWRSTS_OFF_RET, /* core_nret_bank */
|
||||||
@@ -193,8 +193,8 @@ static struct powerdomain cpu0_7xx_pwrdm = {
|
|||||||
.name = "cpu0_pwrdm",
|
.name = "cpu0_pwrdm",
|
||||||
.prcm_offs = DRA7XX_MPU_PRCM_PRM_C0_INST,
|
.prcm_offs = DRA7XX_MPU_PRCM_PRM_C0_INST,
|
||||||
.prcm_partition = DRA7XX_MPU_PRCM_PARTITION,
|
.prcm_partition = DRA7XX_MPU_PRCM_PARTITION,
|
||||||
.pwrsts = PWRSTS_OFF_RET_ON,
|
.pwrsts = PWRSTS_RET_ON,
|
||||||
.pwrsts_logic_ret = PWRSTS_OFF_RET,
|
.pwrsts_logic_ret = PWRSTS_RET,
|
||||||
.banks = 1,
|
.banks = 1,
|
||||||
.pwrsts_mem_ret = {
|
.pwrsts_mem_ret = {
|
||||||
[0] = PWRSTS_OFF_RET, /* cpu0_l1 */
|
[0] = PWRSTS_OFF_RET, /* cpu0_l1 */
|
||||||
@@ -209,8 +209,8 @@ static struct powerdomain cpu1_7xx_pwrdm = {
|
|||||||
.name = "cpu1_pwrdm",
|
.name = "cpu1_pwrdm",
|
||||||
.prcm_offs = DRA7XX_MPU_PRCM_PRM_C1_INST,
|
.prcm_offs = DRA7XX_MPU_PRCM_PRM_C1_INST,
|
||||||
.prcm_partition = DRA7XX_MPU_PRCM_PARTITION,
|
.prcm_partition = DRA7XX_MPU_PRCM_PARTITION,
|
||||||
.pwrsts = PWRSTS_OFF_RET_ON,
|
.pwrsts = PWRSTS_RET_ON,
|
||||||
.pwrsts_logic_ret = PWRSTS_OFF_RET,
|
.pwrsts_logic_ret = PWRSTS_RET,
|
||||||
.banks = 1,
|
.banks = 1,
|
||||||
.pwrsts_mem_ret = {
|
.pwrsts_mem_ret = {
|
||||||
[0] = PWRSTS_OFF_RET, /* cpu1_l1 */
|
[0] = PWRSTS_OFF_RET, /* cpu1_l1 */
|
||||||
@@ -243,7 +243,7 @@ static struct powerdomain mpu_7xx_pwrdm = {
|
|||||||
.prcm_offs = DRA7XX_PRM_MPU_INST,
|
.prcm_offs = DRA7XX_PRM_MPU_INST,
|
||||||
.prcm_partition = DRA7XX_PRM_PARTITION,
|
.prcm_partition = DRA7XX_PRM_PARTITION,
|
||||||
.pwrsts = PWRSTS_RET_ON,
|
.pwrsts = PWRSTS_RET_ON,
|
||||||
.pwrsts_logic_ret = PWRSTS_OFF_RET,
|
.pwrsts_logic_ret = PWRSTS_RET,
|
||||||
.banks = 2,
|
.banks = 2,
|
||||||
.pwrsts_mem_ret = {
|
.pwrsts_mem_ret = {
|
||||||
[0] = PWRSTS_OFF_RET, /* mpu_l2 */
|
[0] = PWRSTS_OFF_RET, /* mpu_l2 */
|
||||||
|
|||||||
Reference in New Issue
Block a user