/* * Force write last pad into memory, as this can fail in some * cases according to errata 1.157, 1.185
*/
omap_ctrl_writel(omap_ctrl_readl(OMAP343X_PADCONF_ETK_D14),
OMAP343X_CONTROL_MEM_WKUP + 0x2a0);
/* Save the Interrupt controller context */
omap_intc_save_context(); /* Save the system control module context, padconf already save above*/
omap3_control_save_context();
}
staticvoid omap3_core_restore_context(void)
{ /* Restore the control module context, padconf restored by h/w */
omap3_control_restore_context(); /* Restore the interrupt controller context */
omap_intc_restore_context();
}
/* * FIXME: This function should be called before entering off-mode after * OMAP3 secure services have been accessed. Currently it is only called * once during boot sequence, but this works as we are not using secure * services.
*/ staticvoid omap3_save_secure_ram_context(void)
{
u32 ret; int mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm);
if (omap_type() != OMAP2_DEVICE_TYPE_GP) { /* * MPU next state must be set to POWER_ON temporarily, * otherwise the WFI executed inside the ROM code * will hang the system.
*/
pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON);
ret = omap3_save_secure_ram(omap3_secure_ram_storage,
OMAP3_SAVE_SECURE_RAM_SZ);
pwrdm_set_next_pwrst(mpu_pwrdm, mpu_next_state); /* Following is for error tracking, it should not happen */ if (ret) {
pr_err("save_secure_sram() returns %08x\n", ret); while (1)
;
}
}
}
static irqreturn_t _prcm_int_handle_io(int irq, void *unused)
{ int c;
c = omap_prm_clear_mod_irqs(WKUP_MOD, 1, OMAP3430_ST_IO_MASK |
OMAP3430_ST_IO_CHAIN_MASK);
return c ? IRQ_HANDLED : IRQ_NONE;
}
static irqreturn_t _prcm_int_handle_wakeup(int irq, void *unused)
{ int c;
/* * Clear all except ST_IO and ST_IO_CHAIN for wkup module, * these are handled in a separate handler to avoid acking * IO events before parsing in mux code
*/
c = omap_prm_clear_mod_irqs(WKUP_MOD, 1, ~(OMAP3430_ST_IO_MASK |
OMAP3430_ST_IO_CHAIN_MASK));
c += omap_prm_clear_mod_irqs(CORE_MOD, 1, ~0);
c += omap_prm_clear_mod_irqs(OMAP3430_PER_MOD, 1, ~0); if (omap_rev() > OMAP3430_REV_ES1_0) {
c += omap_prm_clear_mod_irqs(CORE_MOD, 3, ~0);
c += omap_prm_clear_mod_irqs(OMAP3430ES2_USBHOST_MOD, 1, ~0);
}
__cpuidle void omap_sram_idle(bool rcuidle)
{ /* Variable to tell what needs to be saved and restored
* in omap_sram_idle*/ /* save_state = 0 => Nothing to save and restored */ /* save_state = 1 => Only L1 and logic lost */ /* save_state = 2 => Only L2 lost */ /* save_state = 3 => L1, L2 and logic lost */ int save_state = 0; int mpu_next_state = PWRDM_POWER_ON; int per_next_state = PWRDM_POWER_ON; int core_next_state = PWRDM_POWER_ON;
u32 sdrc_pwr = 0; int error;
mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm); switch (mpu_next_state) { case PWRDM_POWER_ON: case PWRDM_POWER_RET: /* No need to save context */
save_state = 0; break; case PWRDM_POWER_OFF:
save_state = 3; break; default: /* Invalid state */
pr_err("Invalid mpu state in sram_idle\n"); return;
}
/* NEON control */ if (pwrdm_read_pwrst(neon_pwrdm) == PWRDM_POWER_ON)
pwrdm_set_next_pwrst(neon_pwrdm, mpu_next_state);
/* PER */ if (per_next_state == PWRDM_POWER_OFF) {
error = cpu_cluster_pm_enter(); if (error) return;
}
/* CORE */ if (core_next_state < PWRDM_POWER_ON) { if (core_next_state == PWRDM_POWER_OFF) {
omap3_core_save_context();
omap3_cm_save_context();
}
}
/* Configure PMIC signaling for I2C4 or sys_off_mode */
omap3_vc_set_pmic_signaling(core_next_state);
omap3_intc_prepare_idle();
/* * On EMU/HS devices ROM code restores a SRDC value * from scratchpad which has automatic self refresh on timeout * of AUTO_CNT = 1 enabled. This takes care of erratum ID i443. * Hence store/restore the SDRC_POWER register here.
*/ if (cpu_is_omap3430() && omap_rev() >= OMAP3430_REV_ES3_0 &&
(omap_type() == OMAP2_DEVICE_TYPE_EMU ||
omap_type() == OMAP2_DEVICE_TYPE_SEC) &&
core_next_state == PWRDM_POWER_OFF)
sdrc_pwr = sdrc_read_reg(SDRC_POWER);
/* * omap3_arm_context is the location where some ARM context * get saved. The rest is placed on the stack, and restored * from there before resuming.
*/ if (save_state)
omap34xx_save_context(omap3_arm_context);
/* Restore normal SDRC POWER settings */ if (cpu_is_omap3430() && omap_rev() >= OMAP3430_REV_ES3_0 &&
(omap_type() == OMAP2_DEVICE_TYPE_EMU ||
omap_type() == OMAP2_DEVICE_TYPE_SEC) &&
core_next_state == PWRDM_POWER_OFF)
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();
}
pwrdm_post_transition(NULL);
/* PER */ if (per_next_state == PWRDM_POWER_OFF)
cpu_cluster_pm_exit();
}
staticvoid omap3_pm_idle(void)
{ if (omap_irq_pending()) return;
omap3_do_wfi();
}
#ifdef CONFIG_SUSPEND staticint omap3_pm_suspend(void)
{ struct power_state *pwrst; int state, ret = 0;
/* Read current next_pwrsts */
list_for_each_entry(pwrst, &pwrst_list, node)
pwrst->saved_state = pwrdm_read_next_pwrst(pwrst->pwrdm); /* Set ones wanted by suspend */
list_for_each_entry(pwrst, &pwrst_list, node) { if (omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state)) goto restore; if (pwrdm_clear_all_prev_pwrst(pwrst->pwrdm)) goto restore;
}
omap3_intc_suspend();
omap_sram_idle(false);
restore: /* Restore next_pwrsts */
list_for_each_entry(pwrst, &pwrst_list, node) {
state = pwrdm_read_prev_pwrst(pwrst->pwrdm); if (state > pwrst->next_state) {
pr_info("Powerdomain (%s) didn't enter target state %d\n",
pwrst->pwrdm->name, pwrst->next_state);
ret = -1;
}
omap_set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state);
} if (ret)
pr_err("Could not enter target state in pm_suspend\n"); else
pr_info("Successfully put all powerdomains to target state\n");
/* * Push functions to SRAM * * The minimum set of functions is pushed to SRAM for execution: * - omap3_do_wfi for erratum i581 WA,
*/ void omap_push_sram_idle(void)
{
omap3_do_wfi_sram = omap_sram_push(omap3_do_wfi, omap3_do_wfi_sz);
}
staticvoid __init pm_errata_configure(void)
{ if (cpu_is_omap3630()) {
pm34xx_errata |= PM_RTA_ERRATUM_i608; /* Enable the l2 cache toggling in sleep logic */
enable_omap3630_toggle_l2_on_restore(); if (omap_rev() < OMAP3630_REV_ES1_2)
pm34xx_errata |= (PM_SDRC_WAKEUP_ERRATUM_i583 |
PM_PER_MEMORIES_ERRATUM_i582);
} elseif (cpu_is_omap34xx()) {
pm34xx_errata |= PM_PER_MEMORIES_ERRATUM_i582;
}
}
/* * RTA is disabled during initialization as per erratum i608 * it is safer to disable RTA by the bootloader, but we would like * to be doubly sure here and prevent any mishaps.
*/ if (IS_PM34XX_ERRATUM(PM_RTA_ERRATUM_i608))
omap3630_ctrl_disable_rta();
/* * The UART3/4 FIFO and the sidetone memory in McBSP2/3 are * not correctly reset when the PER powerdomain comes back * from OFF or OSWR when the CORE powerdomain is kept active. * See OMAP36xx Erratum i582 "PER Domain reset issue after * Domain-OFF/OSWR Wakeup". This wakeup dependency is not a * complete workaround. The kernel must also prevent the PER * powerdomain from going to OSWR/OFF while the CORE * powerdomain is not going to OSWR/OFF. And if PER last * power state was off while CORE last power state was ON, the * UART3/4 and McBSP2/3 SIDETONE devices need to run a * self-test using their loopback tests; if that fails, those * devices are unusable until the PER/CORE can complete a transition * from ON to OSWR/OFF and then back to ON. * * XXX Technically this workaround is only needed if off-mode * or OSWR is enabled.
*/ if (IS_PM34XX_ERRATUM(PM_PER_MEMORIES_ERRATUM_i582))
clkdm_add_wkdep(per_clkdm, wkup_clkdm);
clkdm_add_wkdep(neon_clkdm, mpu_clkdm); if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
omap3_secure_ram_storage =
kmalloc(OMAP3_SAVE_SECURE_RAM_SZ, GFP_KERNEL); if (!omap3_secure_ram_storage)
pr_err("Memory allocation failed when allocating for secure sram context\n");
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.