/* * cpu_pdn: * true = CPU dormant * false = CPU standby * pwrlevel: * 0 = AXI is off * 1 = AXI is 26M */ wake_reason_t spm_go_to_dpidle(bool cpu_pdn, u16 pwrlevel) { wake_status_t wakesta; unsigned long flags; struct mtk_irq_mask mask; wake_reason_t wr = WR_NONE; const pcm_desc_t *pcmdesc = &pcm_dpidle; const bool pcmwdt_en = false; spin_lock_irqsave(&spm_lock, flags); mt_irq_mask_all(&mask); mt_irq_unmask_for_sleep(MT_SPM_IRQ_ID); mt_cirq_clone_gic(); mt_cirq_enable(); spm_reset_and_init_pcm(); spm_kick_im_to_fetch(pcmdesc); if (spm_request_uart_to_sleep()) { wr = WR_UART_BUSY; goto RESTORE_IRQ; } spm_init_pcm_register(); spm_init_event_vector(pcmdesc); spm_set_pwrctl_for_dpidle(pwrlevel); spm_set_wakeup_event(0, WAKE_SRC_FOR_DPIDLE); spm_kick_pcm_to_run(cpu_pdn, false, pcmwdt_en); /* keep INFRA/DDRPHY power */ spm_dpidle_before_wfi(); spm_trigger_wfi_for_dpidle(cpu_pdn); spm_dpidle_after_wfi(); spm_get_wakeup_status(&wakesta); spm_clean_after_wakeup(pcmwdt_en); wr = spm_output_wake_reason(&wakesta, true); RESTORE_IRQ: mt_cirq_flush(); mt_cirq_disable(); mt_irq_mask_restore(&mask); spin_unlock_irqrestore(&spm_lock, flags); return wr; }
wake_reason_t spm_go_to_dpidle(u32 spm_flags, u32 spm_data) { struct wake_status wakesta; unsigned long flags; struct mtk_irq_mask mask; wake_reason_t wr = WR_NONE; struct pcm_desc *pcmdesc = __spm_dpidle.pcmdesc; struct pwr_ctrl *pwrctrl = __spm_dpidle.pwrctrl; #if SPM_AEE_RR_REC aee_rr_rec_deepidle_val(1<<SPM_DEEPIDLE_ENTER); #endif set_pwrctrl_pcm_flags(pwrctrl, spm_flags); //pwrctrl->timer_val = 1 * 32768; spm_dpidle_before_wfi(); lockdep_off(); spin_lock_irqsave(&__spm_lock, flags); mt_irq_mask_all(&mask); mt_irq_unmask_for_sleep(SPM_IRQ0_ID); mt_cirq_clone_gic(); mt_cirq_enable(); #if SPM_AEE_RR_REC aee_rr_rec_deepidle_val(aee_rr_curr_deepidle_val()|(1<<SPM_DEEPIDLE_ENTER_UART_SLEEP)); #endif if (request_uart_to_sleep()) { wr = WR_UART_BUSY; goto RESTORE_IRQ; } __spm_reset_and_init_pcm(pcmdesc); __spm_kick_im_to_fetch(pcmdesc); __spm_init_pcm_register(); __spm_init_event_vector(pcmdesc); __spm_set_power_control(pwrctrl); __spm_set_wakeup_event(pwrctrl); spm_dpidle_pre_process(); __spm_kick_pcm_to_run(pwrctrl); #if SPM_AEE_RR_REC aee_rr_rec_deepidle_val(aee_rr_curr_deepidle_val()|(1<<SPM_DEEPIDLE_ENTER_WFI)); #endif #ifdef SPM_DEEPIDLE_PROFILE_TIME gpt_get_cnt(SPM_PROFILE_APXGPT,&dpidle_profile[1]); #endif spm_trigger_wfi_for_dpidle(pwrctrl); #ifdef SPM_DEEPIDLE_PROFILE_TIME gpt_get_cnt(SPM_PROFILE_APXGPT,&dpidle_profile[2]); #endif #if SPM_AEE_RR_REC aee_rr_rec_deepidle_val(aee_rr_curr_deepidle_val()|(1<<SPM_DEEPIDLE_LEAVE_WFI)); #endif spm_dpidle_post_process(); __spm_get_wakeup_status(&wakesta); __spm_clean_after_wakeup(); #if SPM_AEE_RR_REC aee_rr_rec_deepidle_val(aee_rr_curr_deepidle_val()|(1<<SPM_DEEPIDLE_ENTER_UART_AWAKE)); #endif request_uart_to_wakeup(); wr = __spm_output_wake_reason(&wakesta, pcmdesc, false); RESTORE_IRQ: mt_cirq_flush(); mt_cirq_disable(); mt_irq_mask_restore(&mask); spin_unlock_irqrestore(&__spm_lock, flags); lockdep_on(); spm_dpidle_after_wfi(); #if SPM_AEE_RR_REC aee_rr_rec_deepidle_val(0); #endif return wr; }
wake_reason_t spm_go_to_dpidle(bool cpu_pdn, u8 pwrlevel) { wake_status_t *wakesta; unsigned long flags; struct mtk_irq_mask mask; wake_reason_t wr = WR_NONE; u32 con0; u32 top_ckgen_val = 0; spin_lock_irqsave(&spm_lock, flags); spm_stop_normal(); mt_irq_mask_all(&mask); mt_irq_unmask_for_sleep(MT_SPM0_IRQ_ID); mt_cirq_clone_gic(); mt_cirq_enable(); #ifdef SPM_DPIDLE_SECONDARY_KICK_IMPROVE if( spm_last_senario != pcm_config_dpidle.scenario)//dpidle SPM Initialize #endif { if(pwrlevel>2) { spm_crit2("Hey!! wrong PWR Level: %x",pwrlevel);//ASSERT Wrong Para!! goto RESTORE_IRQ; } pcm_config_dpidle.pcm_pwrlevel = 1 << pwrlevel ; pcm_config_dpidle.spm_request_uart_sleep = (pwrlevel == 0 ? true : false); pcm_config_dpidle.cpu_pdn = cpu_pdn; if (spm_init_pcm(&pcm_config_dpidle)==false) goto RESTORE_IRQ; #ifdef SPM_CLOCK_INIT enable_clock(MT_CG_MEMSLP_DLYER_SW_CG, "SPM_DPIDLE"); enable_clock(MT_CG_SPM_SW_CG, "SPM_DPIDLE"); #endif #ifdef SPM_DPIDLE_CLK_DBG_OUT //gpiodbg_monitor(); gpiodbg_emi_dbg_out(); gpiodbg_armcore_dbg_out(); #endif spm_kick_pcm(&pcm_config_dpidle); //spm_change_fw = 1; } #ifdef SPM_DPIDLE_SECONDARY_KICK_IMPROVE else { if( spm_secondary_kick(&pcm_config_dpidle)==false) goto RESTORE_IRQ; //spm_change_fw = 0; } #endif spm_dpidle_before_wfi(); //hopping 33M-->fixed 26M, 20130902 HG.Wei top_ckgen_val = spm_read(TOPCKGEN_BASE); spm_write(TOPCKGEN_BASE,top_ckgen_val&(~(1<<26))); snapshot_golden_setting(__FUNCTION__, __LINE__); spm_trigger_wfi(&pcm_config_dpidle); //hopping fixed 26M-->hopping 33M, 20130902 HG.Wei spm_write(TOPCKGEN_BASE,top_ckgen_val); spm_dpidle_after_wfi(); wakesta = spm_get_wakeup_status(&pcm_config_dpidle); wr = wakesta->wake_reason; spm_clean_after_wakeup(); #ifdef SPM_CLOCK_INIT disable_clock(MT_CG_SPM_SW_CG, "SPM_DPIDLE"); disable_clock(MT_CG_MEMSLP_DLYER_SW_CG, "SPM_DPIDLE"); #endif RESTORE_IRQ: mt_cirq_flush(); mt_cirq_disable(); mt_irq_mask_restore(&mask); spm_go_to_normal(); spin_unlock_irqrestore(&spm_lock, flags); return wr; }
wake_reason_t spm_go_to_dpidle(u32 spm_flags, u32 spm_data) { struct wake_status wakesta; unsigned long flags; struct mtk_irq_mask mask; wake_reason_t wr = WR_NONE; struct pcm_desc *pcmdesc = __spm_dpidle.pcmdesc; struct pwr_ctrl *pwrctrl = __spm_dpidle.pwrctrl; struct spm_lp_scen *lpscen; lpscen = spm_check_talking_get_lpscen(&__spm_dpidle, &spm_flags); pcmdesc = lpscen->pcmdesc; pwrctrl = lpscen->pwrctrl; set_pwrctrl_pcm_flags(pwrctrl, spm_flags); /* set PMIC WRAP table for deepidle power control */ mt_cpufreq_set_pmic_phase(PMIC_WRAP_PHASE_DEEPIDLE); spin_lock_irqsave(&__spm_lock, flags); mt_irq_mask_all(&mask); mt_irq_unmask_for_sleep(MT_SPM_IRQ_ID); mt_cirq_clone_gic(); mt_cirq_enable(); if (request_uart_to_sleep()) { wr = WR_UART_BUSY; goto RESTORE_IRQ; } __spm_reset_and_init_pcm(pcmdesc); __spm_kick_im_to_fetch(pcmdesc); __spm_init_pcm_register(); __spm_init_event_vector(pcmdesc); __spm_set_power_control(pwrctrl); __spm_set_wakeup_event(pwrctrl); __spm_kick_pcm_to_run(pwrctrl); spm_dpidle_before_wfi(); spm_trigger_wfi_for_dpidle(pwrctrl); spm_dpidle_after_wfi(); __spm_get_wakeup_status(&wakesta); __spm_clean_after_wakeup(); request_uart_to_wakeup(); wr = __spm_output_wake_reason(&wakesta, pcmdesc, false); RESTORE_IRQ: mt_cirq_flush(); mt_cirq_disable(); mt_irq_mask_restore(&mask); spin_unlock_irqrestore(&__spm_lock, flags); /* set PMIC WRAP table for normal power control */ mt_cpufreq_set_pmic_phase(PMIC_WRAP_PHASE_NORMAL); return wr; }