omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
PM_WKEN);
- /* Do a readback to assure write has been done */
- omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN);
- while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN) &
+ while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST) &
OMAP3430_ST_IO_CHAIN_MASK)) {
timeout++;
- if (timeout > 1000) {
+ if (timeout > 100) {
pr_err("Wake up daisy chain activation failed.\n");
return;
}
- omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK,
- WKUP_MOD, PM_WKEN);
+ udelay(1);
}
+
+ omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, WKUP_MOD,
+ PM_WKST);
}
static void omap3_disable_io_chain(void)
int per_next_state = PWRDM_POWER_ON;
int core_next_state = PWRDM_POWER_ON;
int per_going_off;
- int core_prev_state, per_prev_state;
+ int per_prev_state;
u32 sdrc_pwr = 0;
mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm);
sdrc_write_reg(sdrc_pwr, SDRC_POWER);
/* CORE */
+ if (core_next_state < PWRDM_POWER_ON &&
+ pwrdm_read_prev_pwrst(core_pwrdm) == PWRDM_POWER_OFF) {
+ omap3_core_restore_context();
+ omap3_cm_restore_context();
+ omap3_sram_restore_context();
+ omap2_sms_restore_context();
+ } else {
+ /*
+ * In off-mode resume path above, omap3_core_restore_context
+ * also handles the INTC autoidle restore done here so limit
+ * this to non-off mode resume paths so we don't do it twice.
+ */
+ omap3_intc_resume_idle();
+ }
if (core_next_state < PWRDM_POWER_ON) {
- core_prev_state = pwrdm_read_prev_pwrst(core_pwrdm);
- if (core_prev_state == PWRDM_POWER_OFF) {
- omap3_core_restore_context();
- omap3_cm_restore_context();
- omap3_sram_restore_context();
- omap2_sms_restore_context();
- }
omap_uart_resume_idle(0);
omap_uart_resume_idle(1);
pwrdm_post_transition(core_pwrdm);
}
- omap3_intc_resume_idle();
/* PER */
if (per_next_state < PWRDM_POWER_ON) {
local_irq_enable();
}
+void omap3_pm_alow_pmic_idle(int allow)
+{
+ /* enable sys_clkreq signalling on RET */
+ omap2_prm_rmw_mod_reg_bits((OMAP3430_AUTO_OFF_MASK | OMAP3430_AUTO_RET_MASK
+ | OMAP3430_AUTO_SLEEP_MASK), allow ? OMAP3430_AUTO_RET_MASK : 0,
+ OMAP3430_GR_MOD, OMAP3_PRM_VOLTCTRL_OFFSET);
+}
+EXPORT_SYMBOL(omap3_pm_alow_pmic_idle);
+
#ifdef CONFIG_SUSPEND
static int omap3_pm_suspend(void)
{
OMAP3630_EN_UART4_MASK : 0;
u32 omap3630_grpsel_uart4_mask = cpu_is_omap3630() ?
OMAP3630_GRPSEL_UART4_MASK : 0;
+#ifdef CONFIG_OMAP3_DISABLE_UART4
+ omap3630_en_uart4_mask = omap3630_grpsel_uart4_mask = 0;
+#endif
/* XXX This should be handled by hwmod code or SCM init code */
omap_ctrl_writel(OMAP3430_AUTOIDLE_MASK, OMAP2_CONTROL_SYSCONFIG);
omap3_iva_idle();
omap3_d2d_idle();
- /* enable sys_clkreq signalling */
- omap2_prm_rmw_mod_reg_bits((OMAP3430_AUTO_OFF_MASK | OMAP3430_AUTO_RET_MASK
- | OMAP3430_AUTO_SLEEP_MASK), OMAP3430_AUTO_RET_MASK,
- OMAP3430_GR_MOD, OMAP3_PRM_VOLTCTRL_OFFSET);
+ omap3_pm_alow_pmic_idle(1);
}
void omap3_pm_off_mode_enable(int enable)
pwrst->next_state = PWRDM_POWER_RET;
pr_warn("%s: Core OFF disabled due to errata i583\n",
__func__);
+ } else if (enable < 3 && pwrst->pwrdm == per_pwrdm) {
+ /* pandora hack */
+ pwrst->next_state = PWRDM_POWER_RET;
} else {
pwrst->next_state = state;
}
if (pwrdm_has_hdwr_sar(pwrdm))
pwrdm_enable_hdwr_sar(pwrdm);
+ /* pandora OFF hacks, notes for missing:
+ * - core_pwrdm - loses GPIO state?!
+ * - per_pwrdm - must keep RET because of GPIOs
+ * - neon_pwrdm - depends on mpu_pwrdm
+ * - mpu_pwrdm - sometimes hangs?
+ * notes for enabled:
+ * - usbhost_pwrdm - does driver reload + reinit anyway, no runtime PM
+ * - sgx_pwrdm - only OFF is supported
+ * - dss_pwrdm - works, needs working context_loss counter
+ * - cam_pwrdm - not used
+ * - iva2_pwrdm - c64_tools reprograms with direct reg hits anyway
+ */
+ if ( pwrdm == pwrdm_lookup("usbhost_pwrdm")
+ || pwrdm == pwrdm_lookup("sgx_pwrdm")
+ || pwrdm == pwrdm_lookup("cam_pwrdm")
+ || pwrdm == pwrdm_lookup("iva2_pwrdm")
+ )
+ pwrst->next_state = PWRDM_POWER_OFF;
+
+ /* on OMAP3, at least on ES2.1, DSS drains more in OFF than in RET?? */
+ else if (cpu_is_omap3630() && pwrdm == pwrdm_lookup("dss_pwrdm"))
+ pwrst->next_state = PWRDM_POWER_OFF;
+
return omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
}