|
@@ -203,3 +203,112 @@ static void omap_pm_wakeup_setup(void)
|
|
|
omap_writel(~level2_wake, OMAP_IH2_0_MIR);
|
|
|
|
|
|
/* INT_1610_WAKE_UP_REQ is needed for GPIO wakeup... */
|
|
|
+ omap_writel(~OMAP_IRQ_BIT(INT_1610_WAKE_UP_REQ),
|
|
|
+ OMAP_IH2_1_MIR);
|
|
|
+ omap_writel(~0x0, OMAP_IH2_2_MIR);
|
|
|
+ omap_writel(~0x0, OMAP_IH2_3_MIR);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* New IRQ agreement, recalculate in cascade order */
|
|
|
+ omap_writel(1, OMAP_IH2_CONTROL);
|
|
|
+ omap_writel(1, OMAP_IH1_CONTROL);
|
|
|
+}
|
|
|
+
|
|
|
+#define EN_DSPCK 13 /* ARM_CKCTL */
|
|
|
+#define EN_APICK 6 /* ARM_IDLECT2 */
|
|
|
+#define DSP_EN 1 /* ARM_RSTCT1 */
|
|
|
+
|
|
|
+void omap1_pm_suspend(void)
|
|
|
+{
|
|
|
+ unsigned long arg0 = 0, arg1 = 0;
|
|
|
+
|
|
|
+ printk(KERN_INFO "PM: OMAP%x is trying to enter deep sleep...\n",
|
|
|
+ omap_rev());
|
|
|
+
|
|
|
+ omap_serial_wake_trigger(1);
|
|
|
+
|
|
|
+ if (!cpu_is_omap15xx())
|
|
|
+ omap_writew(0xffff, ULPD_SOFT_DISABLE_REQ_REG);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Step 1: turn off interrupts (FIXME: NOTE: already disabled)
|
|
|
+ */
|
|
|
+
|
|
|
+ local_irq_disable();
|
|
|
+ local_fiq_disable();
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Step 2: save registers
|
|
|
+ *
|
|
|
+ * The omap is a strange/beautiful device. The caches, memory
|
|
|
+ * and register state are preserved across power saves.
|
|
|
+ * We have to save and restore very little register state to
|
|
|
+ * idle the omap.
|
|
|
+ *
|
|
|
+ * Save interrupt, MPUI, ARM and UPLD control registers.
|
|
|
+ */
|
|
|
+
|
|
|
+ if (cpu_is_omap7xx()) {
|
|
|
+ MPUI7XX_SAVE(OMAP_IH1_MIR);
|
|
|
+ MPUI7XX_SAVE(OMAP_IH2_0_MIR);
|
|
|
+ MPUI7XX_SAVE(OMAP_IH2_1_MIR);
|
|
|
+ MPUI7XX_SAVE(MPUI_CTRL);
|
|
|
+ MPUI7XX_SAVE(MPUI_DSP_BOOT_CONFIG);
|
|
|
+ MPUI7XX_SAVE(MPUI_DSP_API_CONFIG);
|
|
|
+ MPUI7XX_SAVE(EMIFS_CONFIG);
|
|
|
+ MPUI7XX_SAVE(EMIFF_SDRAM_CONFIG);
|
|
|
+
|
|
|
+ } else if (cpu_is_omap15xx()) {
|
|
|
+ MPUI1510_SAVE(OMAP_IH1_MIR);
|
|
|
+ MPUI1510_SAVE(OMAP_IH2_MIR);
|
|
|
+ MPUI1510_SAVE(MPUI_CTRL);
|
|
|
+ MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG);
|
|
|
+ MPUI1510_SAVE(MPUI_DSP_API_CONFIG);
|
|
|
+ MPUI1510_SAVE(EMIFS_CONFIG);
|
|
|
+ MPUI1510_SAVE(EMIFF_SDRAM_CONFIG);
|
|
|
+ } else if (cpu_is_omap16xx()) {
|
|
|
+ MPUI1610_SAVE(OMAP_IH1_MIR);
|
|
|
+ MPUI1610_SAVE(OMAP_IH2_0_MIR);
|
|
|
+ MPUI1610_SAVE(OMAP_IH2_1_MIR);
|
|
|
+ MPUI1610_SAVE(OMAP_IH2_2_MIR);
|
|
|
+ MPUI1610_SAVE(OMAP_IH2_3_MIR);
|
|
|
+ MPUI1610_SAVE(MPUI_CTRL);
|
|
|
+ MPUI1610_SAVE(MPUI_DSP_BOOT_CONFIG);
|
|
|
+ MPUI1610_SAVE(MPUI_DSP_API_CONFIG);
|
|
|
+ MPUI1610_SAVE(EMIFS_CONFIG);
|
|
|
+ MPUI1610_SAVE(EMIFF_SDRAM_CONFIG);
|
|
|
+ }
|
|
|
+
|
|
|
+ ARM_SAVE(ARM_CKCTL);
|
|
|
+ ARM_SAVE(ARM_IDLECT1);
|
|
|
+ ARM_SAVE(ARM_IDLECT2);
|
|
|
+ if (!(cpu_is_omap15xx()))
|
|
|
+ ARM_SAVE(ARM_IDLECT3);
|
|
|
+ ARM_SAVE(ARM_EWUPCT);
|
|
|
+ ARM_SAVE(ARM_RSTCT1);
|
|
|
+ ARM_SAVE(ARM_RSTCT2);
|
|
|
+ ARM_SAVE(ARM_SYSST);
|
|
|
+ ULPD_SAVE(ULPD_CLOCK_CTRL);
|
|
|
+ ULPD_SAVE(ULPD_STATUS_REQ);
|
|
|
+
|
|
|
+ /* (Step 3 removed - we now allow deep sleep by default) */
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Step 4: OMAP DSP Shutdown
|
|
|
+ */
|
|
|
+
|
|
|
+ /* stop DSP */
|
|
|
+ omap_writew(omap_readw(ARM_RSTCT1) & ~(1 << DSP_EN), ARM_RSTCT1);
|
|
|
+
|
|
|
+ /* shut down dsp_ck */
|
|
|
+ if (!cpu_is_omap7xx())
|
|
|
+ omap_writew(omap_readw(ARM_CKCTL) & ~(1 << EN_DSPCK), ARM_CKCTL);
|
|
|
+
|
|
|
+ /* temporarily enabling api_ck to access DSP registers */
|
|
|
+ omap_writew(omap_readw(ARM_IDLECT2) | 1 << EN_APICK, ARM_IDLECT2);
|
|
|
+
|
|
|
+ /* save DSP registers */
|
|
|
+ DSP_SAVE(DSP_IDLECT2);
|
|
|
+
|
|
|
+ /* Stop all DSP domain clocks */
|
|
|
+ __raw_writew(0, DSP_IDLECT2);
|