/* Correct target state based on inactivity timer expiry, etc */ static void adjust_target_states(struct system_power_state *target_state) { switch (target_state->mpu_state) { case PRCM_MPU_ACTIVE: case PRCM_MPU_INACTIVE: target_state->neon_state = PRCM_ON; break; case PRCM_MPU_CSWR_L2RET: case PRCM_MPU_OSWR_L2RET: case PRCM_MPU_CSWR_L2OFF: case PRCM_MPU_OSWR_L2OFF: target_state->neon_state = PRCM_RET; break; case PRCM_MPU_OFF: target_state->neon_state = PRCM_OFF; if (!enable_off) { target_state->mpu_state = PRCM_MPU_CSWR_L2RET; target_state->neon_state = PRCM_RET; } break; } if (target_state->core_state > PRCM_CORE_INACTIVE) { #ifdef CONFIG_OMAP34XX_OFFMODE #if 0 /* GPT context save in PER domain not yet implemented. Until it is, we do not * put PER to OFF. */ /* Core can be put to RET/OFF - This means PER can be put to * off if its inactivity timer has expired. */ if (perdomain_timer_pending()) target_state->per_state = PRCM_RET; else target_state->per_state = PRCM_OFF; #else target_state->per_state = PRCM_RET; #endif if (target_state->core_state == PRCM_CORE_OFF) { if (coredomain_timer_pending()) target_state->core_state = PRCM_CORE_CSWR_MEMRET; if (CM_FCLKEN_DSS & DSS_FCLK_MASK) target_state->core_state = PRCM_CORE_CSWR_MEMRET; if (!enable_off) { target_state->core_state = PRCM_CORE_CSWR_MEMRET; target_state->per_state = PRCM_RET; } } #else target_state->per_state = PRCM_RET; #endif } else target_state->per_state = PRCM_ON; if (target_state->core_state == PRCM_CORE_CSWR_MEMRET) memory_logic_res_setting(target_state); }
static int omap3_pm_suspend(void) { int sr1_status = 0; int sr2_status = 0; struct system_power_state trg_st; u32 suspend_state; int ret; sr1_status = disable_smartreflex(SR1_ID); sr2_status = disable_smartreflex(SR2_ID); #ifdef CONFIG_OMAP34XX_OFFMODE context_restore_update(DOM_PER); context_restore_update(DOM_CORE1); trg_st.mpu_state = PRCM_MPU_OFF; suspend_state = PRCM_OFF; #else trg_st.mpu_state = PRCM_MPU_CSWR_L2RET; suspend_state = PRCM_RET; #endif #ifndef CONFIG_ARCH_OMAP3410 trg_st.neon_state = suspend_state; trg_st.gfx_state = suspend_state; #endif trg_st.iva2_state = suspend_state; trg_st.dss_state = suspend_state; trg_st.cam_state = suspend_state; trg_st.per_state = suspend_state; #ifndef CONFIG_CORE_OFF /* If we keep CORE in RET instead of OFF, we also keep PER in RET. */ trg_st.per_state = PRCM_RET; #endif trg_st.usbhost_state = suspend_state; #ifndef CONFIG_ARCH_OMAP3410 if (trg_st.neon_state == PRCM_OFF) omap3_save_neon_context(); #endif if (trg_st.per_state == PRCM_OFF) omap3_save_per_context(); #ifdef CONFIG_CORE_OFF trg_st.core_state = PRCM_CORE_OFF; #else trg_st.core_state = PRCM_CORE_CSWR_MEMRET; #endif if (trg_st.core_state == PRCM_CORE_CSWR_MEMRET) { memory_logic_res_setting(&trg_st); } if (trg_st.core_state >= PRCM_CORE_OSWR_MEMRET) { prcm_save_core_context(trg_st.core_state); } #ifdef CONFIG_OMAP_32K_TIMER omap_disable_system_timer(); #endif #if CONFIG_MACH_SIRLOIN_3630 if( cpu_is_omap36xx() && is_omap3_rev_equal_to(OMAP3630_REV_ES1_1)) { /* * As a part of JEDEC violation workaround for 3630ES1.1 * set vdd2 voltage to 1.0875V (vsel == 39/ 0x27) */ if(trg_st.core_state >= PRCM_CORE_OFF ) { u32 target_opp = prcm_get_current_vdd2_opp(); sr_voltagescale(target_opp, target_opp, 0x27 ); } } #endif /* prcm_set_chip_power_mode() will suspend the system. Function will * return upon system wake-up. */ ret = prcm_set_chip_power_mode(&trg_st); if (ret != 0) printk(KERN_ERR "Could not enter target state in pm_suspend\n"); else { // printk(KERN_INFO // "Successfully put chip to target state in suspend\n"); } #ifndef CONFIG_ARCH_OMAP3410 if (trg_st.neon_state == PRCM_OFF) omap3_restore_neon_context(); #endif if (trg_st.per_state == PRCM_OFF) omap3_restore_per_context(); #ifdef CONFIG_CORE_OFF omap3_restore_core_settings(); #else if (trg_st.core_state >= PRCM_CORE_OSWR_MEMRET) { #ifdef CONFIG_OMAP34XX_OFFMODE context_restore_update(DOM_CORE1); #endif prcm_restore_core_context(trg_st.core_state); } if (trg_st.core_state > PRCM_CORE_CSWR_MEMRET) { restore_sram_functions(); /*restore sram data */ omap_sram_idle_setup(); } #endif if (sr1_status) enable_smartreflex(SR1_ID); if (sr2_status) enable_smartreflex(SR2_ID); #ifdef CONFIG_OMAP_32K_TIMER omap_enable_system_timer(); #endif return 0; }