@@ -110,8 +110,8 @@ static struct powerdomain *_pwrdm_deps_lookup(struct powerdomain *pwrdm,
static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag)
{
- int prev;
- int state;
+ u8 prev;
+ u8 state;
if (pwrdm == NULL)
return -EINVAL;
@@ -218,7 +218,9 @@ int pwrdm_register(struct powerdomain *pwrdm)
pr_debug("powerdomain: registered %s\n", pwrdm->name);
ret = 0;
-
+ pwrdm->next_state =
+ prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTCTRL,
+ OMAP_POWERSTATE_MASK);
pr_unlock:
write_unlock_irqrestore(&pwrdm_rwlock, flags);
@@ -699,19 +701,38 @@ int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm)
*/
int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
{
+ u8 prg_pwrst;
+
if (!pwrdm)
return -EINVAL;
+ if (pwrdm->next_state == pwrst)
+ return 0;
+
if (!(pwrdm->pwrsts & (1 << pwrst)))
return -EINVAL;
pr_debug("powerdomain: setting next powerstate for %s to %0x\n",
pwrdm->name, pwrst);
+ /* INACTIVE is reserved, so we program pwrdm as ON */
+ if (pwrst == PWRDM_POWER_INACTIVE)
+ prg_pwrst = PWRDM_POWER_ON;
+ else
+ prg_pwrst = pwrst;
+
prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK,
- (pwrst << OMAP_POWERSTATE_SHIFT),
+ (prg_pwrst << OMAP_POWERSTATE_SHIFT),
pwrdm->prcm_offs, PM_PWSTCTRL);
+ /* If next state is ON, prevent idle */
+ if (pwrst == PWRDM_POWER_ON)
+ omap2_clkdm_deny_idle(pwrdm->pwrdm_clkdms[0]);
+ else
+ omap2_clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]);
+
+ pwrdm->next_state = pwrst;
+
return 0;
}
@@ -728,8 +749,7 @@ int pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
if (!pwrdm)
return -EINVAL;
- return prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTCTRL,
- OMAP_POWERSTATE_MASK);
+ return pwrdm->next_state;
}
/**
@@ -165,7 +165,7 @@ static struct powerdomain iva2_pwrdm = {
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
.dep_bit = OMAP3430_PM_WKDEP_MPU_EN_IVA2_SHIFT,
.wkdep_srcs = iva2_wkdeps,
- .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts = PWRSTS_OFF_RET_INA_ON,
.pwrsts_logic_ret = PWRSTS_OFF_RET,
.banks = 4,
.pwrsts_mem_ret = {
@@ -188,7 +188,7 @@ static struct powerdomain mpu_34xx_pwrdm = {
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
.dep_bit = OMAP3430_EN_MPU_SHIFT,
.wkdep_srcs = mpu_34xx_wkdeps,
- .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts = PWRSTS_OFF_RET_INA_ON,
.pwrsts_logic_ret = PWRSTS_OFF_RET,
.flags = PWRDM_HAS_MPU_QUIRK,
.banks = 1,
@@ -207,7 +207,7 @@ static struct powerdomain core_34xx_pre_es3_1_pwrdm = {
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES1 |
CHIP_IS_OMAP3430ES2 |
CHIP_IS_OMAP3430ES3_0),
- .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts = PWRSTS_OFF_RET_INA_ON,
.dep_bit = OMAP3430_EN_CORE_SHIFT,
.banks = 2,
.pwrsts_mem_ret = {
@@ -215,8 +215,8 @@ static struct powerdomain core_34xx_pre_es3_1_pwrdm = {
[1] = PWRSTS_OFF_RET, /* MEM2RETSTATE */
},
.pwrsts_mem_on = {
- [0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */
- [1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */
+ [0] = PWRSTS_OFF_RET_INA_ON, /* MEM1ONSTATE */
+ [1] = PWRSTS_OFF_RET_INA_ON, /* MEM2ONSTATE */
},
};
@@ -225,7 +225,7 @@ static struct powerdomain core_34xx_es3_1_pwrdm = {
.name = "core_pwrdm",
.prcm_offs = CORE_MOD,
.omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES3_1),
- .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts = PWRSTS_OFF_RET_INA_ON,
.dep_bit = OMAP3430_EN_CORE_SHIFT,
.flags = PWRDM_HAS_HDWR_SAR, /* for USBTLL only */
.banks = 2,
@@ -234,8 +234,8 @@ static struct powerdomain core_34xx_es3_1_pwrdm = {
[1] = PWRSTS_OFF_RET, /* MEM2RETSTATE */
},
.pwrsts_mem_on = {
- [0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */
- [1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */
+ [0] = PWRSTS_OFF_RET_INA_ON, /* MEM1ONSTATE */
+ [1] = PWRSTS_OFF_RET_INA_ON, /* MEM2ONSTATE */
},
};
@@ -247,7 +247,7 @@ static struct powerdomain dss_pwrdm = {
.dep_bit = OMAP3430_PM_WKDEP_MPU_EN_DSS_SHIFT,
.wkdep_srcs = cam_dss_wkdeps,
.sleepdep_srcs = dss_per_usbhost_sleepdeps,
- .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts = PWRSTS_OFF_RET_INA_ON,
.pwrsts_logic_ret = PWRDM_POWER_RET,
.banks = 1,
.pwrsts_mem_ret = {
@@ -287,7 +287,7 @@ static struct powerdomain cam_pwrdm = {
.prcm_offs = OMAP3430_CAM_MOD,
.wkdep_srcs = cam_dss_wkdeps,
.sleepdep_srcs = cam_gfx_sleepdeps,
- .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts = PWRSTS_OFF_RET_INA_ON,
.pwrsts_logic_ret = PWRDM_POWER_RET,
.banks = 1,
.pwrsts_mem_ret = {
@@ -305,7 +305,7 @@ static struct powerdomain per_pwrdm = {
.dep_bit = OMAP3430_EN_PER_SHIFT,
.wkdep_srcs = per_usbhost_wkdeps,
.sleepdep_srcs = dss_per_usbhost_sleepdeps,
- .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts = PWRSTS_OFF_RET_INA_ON,
.pwrsts_logic_ret = PWRSTS_OFF_RET,
.banks = 1,
.pwrsts_mem_ret = {
@@ -327,7 +327,7 @@ static struct powerdomain neon_pwrdm = {
.prcm_offs = OMAP3430_NEON_MOD,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
.wkdep_srcs = neon_wkdeps,
- .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts = PWRSTS_OFF_RET_INA_ON,
.pwrsts_logic_ret = PWRDM_POWER_RET,
};
@@ -337,7 +337,7 @@ static struct powerdomain usbhost_pwrdm = {
.omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
.wkdep_srcs = per_usbhost_wkdeps,
.sleepdep_srcs = dss_per_usbhost_sleepdeps,
- .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts = PWRSTS_OFF_RET_INA_ON,
.pwrsts_logic_ret = PWRDM_POWER_RET,
/*
* REVISIT: Enabling usb host save and restore mechanism seems to
@@ -39,6 +39,9 @@
#define PWRSTS_OFF_RET_ON (PWRSTS_OFF_RET | (1 << PWRDM_POWER_ON))
+#define PWRSTS_OFF_RET_INA_ON (PWRSTS_OFF_RET_ON | \
+ (1 << PWRDM_POWER_INACTIVE))
+
/* Powerdomain flags */
#define PWRDM_HAS_HDWR_SAR (1 << 0) /* hardware save-and-restore support */
@@ -123,6 +126,7 @@ struct powerdomain {
struct list_head node;
int state;
+ int next_state;
unsigned state_counter[PWRDM_MAX_PWRSTS];
#ifdef CONFIG_PM_DEBUG