void spm_go_to_vcore_dvfs(u32 spm_flags, u32 spm_data) { struct pcm_desc *pcmdesc = __spm_vcore_dvfs.pcmdesc; struct pwr_ctrl *pwrctrl = __spm_vcore_dvfs.pwrctrl; unsigned long flags; spin_lock_irqsave(&__spm_lock, flags); mt_cpufreq_set_pmic_phase(PMIC_WRAP_PHASE_NORMAL); set_pwrctrl_pcm_flags(pwrctrl, spm_flags); __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); spin_unlock_irqrestore(&__spm_lock, flags); }
static void spm_sodi_post_process(void) { __spm_dpidle_sodi_restore_pmic_setting(vsram_vosel_on_lb); /* set PMIC WRAP table for normal power control */ mt_cpufreq_set_pmic_phase(PMIC_WRAP_PHASE_NORMAL); }
static void spm_sodi_pre_process(void) { /* set PMIC WRAP table for deepidle power control */ mt_cpufreq_set_pmic_phase(PMIC_WRAP_PHASE_DEEPIDLE); vsram_vosel_on_lb = __spm_dpidle_sodi_set_pmic_setting(); }
static void spm_dpidle_pre_process(void) { //spm_i2c_control(I2C_CHANNEL, 1); /* set PMIC WRAP table for deepidle power control */ mt_cpufreq_set_pmic_phase(PMIC_WRAP_PHASE_DEEPIDLE); }
static void spm_sodi_post_process(void) { pmic_set_register_value(PMIC_VSRAM_VOSEL_ON_LB,vsram_vosel_on_lb); /* set PMIC WRAP table for normal power control */ mt_cpufreq_set_pmic_phase(PMIC_WRAP_PHASE_NORMAL); }
static void spm_sodi_pre_process(void) { /* set PMIC WRAP table for deepidle power control */ mt_cpufreq_set_pmic_phase(PMIC_WRAP_PHASE_DEEPIDLE); /* [521562] merge ALPS02212031(For_JHZ6735M_65C_L_ALPS.L1.MP3.V1_P82) patch by liming.zhu at 20150818 bigen*/ vsram_vosel_on_lb = __spm_dpidle_sodi_set_pmic_setting(); /* [521562] merge ALPS02212031(For_JHZ6735M_65C_L_ALPS.L1.MP3.V1_P82) patch by liming.zhu at 20150818 end*/ }
static void spm_dpidle_post_process(void) { /* //TODO spm_i2c_control(I2C_CHANNEL, 0); */ /* set PMIC WRAP table for normal power control */ mt_cpufreq_set_pmic_phase(PMIC_WRAP_PHASE_NORMAL); }
static void spm_sodi_pre_process(void) { /* set PMIC WRAP table for deepidle power control */ mt_cpufreq_set_pmic_phase(PMIC_WRAP_PHASE_DEEPIDLE); vsram_vosel_on_lb = pmic_get_register_value(PMIC_VSRAM_VOSEL_ON_LB); spm_write(SPM_PCM_RESERVE3,(pmic_get_register_value(PMIC_VSRAM_VOSEL_OFFSET)<<8)|pmic_get_register_value(PMIC_VSRAM_VOSEL_DELTA));//delta = 0v pmic_set_register_value(PMIC_VSRAM_VOSEL_ON_LB,(vsram_vosel_on_lb&0xff80)|0x28);//0.85v }
static void spm_sodi_post_process(void) { /* [521562] merge ALPS02212031(For_JHZ6735M_65C_L_ALPS.L1.MP3.V1_P82) patch by liming.zhu at 20150818 bigen*/ __spm_dpidle_sodi_restore_pmic_setting(vsram_vosel_on_lb); /* [521562] merge ALPS02212031(For_JHZ6735M_65C_L_ALPS.L1.MP3.V1_P82) patch by liming.zhu at 20150818 end*/ /* set PMIC WRAP table for normal power control */ mt_cpufreq_set_pmic_phase(PMIC_WRAP_PHASE_NORMAL); }
static void spm_dpidle_post_process(void) { /* //TODO spm_i2c_control(I2C_CHANNEL, 0); spm_write(0xF0001070 , g_bus_ctrl); //26:26 enable */ pmic_set_register_value(PMIC_VSRAM_VOSEL_ON_LB,vsram_vosel_on_lb); /* set PMIC WRAP table for normal power control */ mt_cpufreq_set_pmic_phase(PMIC_WRAP_PHASE_NORMAL); }
static void spm_dpidle_post_process(void) { /* //TODO spm_i2c_control(I2C_CHANNEL, 0); spm_write(0xF0001070 , g_bus_ctrl); //26:26 enable */ /* [521562] merge ALPS02212031(For_JHZ6735M_65C_L_ALPS.L1.MP3.V1_P82) patch by liming.zhu at 20150818 bigen*/ __spm_dpidle_sodi_restore_pmic_setting(vsram_vosel_on_lb); /* [521562] merge ALPS02212031(For_JHZ6735M_65C_L_ALPS.L1.MP3.V1_P82) patch by liming.zhu at 20150818 end*/ /* set PMIC WRAP table for normal power control */ mt_cpufreq_set_pmic_phase(PMIC_WRAP_PHASE_NORMAL); }
void spm_go_to_vcore_dvfs(u32 spm_flags, u32 spm_data) { unsigned long flags; spin_lock_irqsave(&__spm_lock, flags); mt_cpufreq_set_pmic_phase(PMIC_WRAP_PHASE_NORMAL); __go_to_vcore_dvfs(spm_flags, 0, 0); spm_crit("[VcoreFS] STA: 0x%x, REQ: 0x%x\n", spm_read(SPM_SLEEP_DVFS_STA), spm_read(SPM_PCM_SRC_REQ)); spin_unlock_irqrestore(&__spm_lock, flags); }
static void spm_dpidle_pre_process(void) { /* //TODO spm_i2c_control(I2C_CHANNEL, 1);//D1,D2 no ext bulk g_bus_ctrl=spm_read(0xF0001070); spm_write(0xF0001070 , g_bus_ctrl | (1 << 21)); //bus dcm disable g_sys_ck_sel = spm_read(0xF0001108); //spm_write(0xF0001108 , g_sys_ck_sel &~ (1<<1) ); spm_write(0xF0001108 , 0x0); spm_write(0xF0000204 , spm_read(0xF0000204) | (1 << 0)); // BUS 26MHz enable */ /* set PMIC WRAP table for deepidle power control */ mt_cpufreq_set_pmic_phase(PMIC_WRAP_PHASE_DEEPIDLE); /* [521562] merge ALPS02212031(For_JHZ6735M_65C_L_ALPS.L1.MP3.V1_P82) patch by liming.zhu at 20150818 bigen*/ vsram_vosel_on_lb = __spm_dpidle_sodi_set_pmic_setting(); /* [521562] merge ALPS02212031(For_JHZ6735M_65C_L_ALPS.L1.MP3.V1_P82) patch by liming.zhu at 20150818 end*/ }
static void spm_dpidle_pre_process(void) { /* //TODO spm_i2c_control(I2C_CHANNEL, 1);//D1,D2 no ext bulk g_bus_ctrl=spm_read(0xF0001070); spm_write(0xF0001070 , g_bus_ctrl | (1 << 21)); //bus dcm disable g_sys_ck_sel = spm_read(0xF0001108); //spm_write(0xF0001108 , g_sys_ck_sel &~ (1<<1) ); spm_write(0xF0001108 , 0x0); spm_write(0xF0000204 , spm_read(0xF0000204) | (1 << 0)); // BUS 26MHz enable */ /* set PMIC WRAP table for deepidle power control */ mt_cpufreq_set_pmic_phase(PMIC_WRAP_PHASE_DEEPIDLE); vsram_vosel_on_lb = pmic_get_register_value(PMIC_VSRAM_VOSEL_ON_LB); spm_write(SPM_PCM_RESERVE3,(pmic_get_register_value(PMIC_VSRAM_VOSEL_OFFSET)<<8)|pmic_get_register_value(PMIC_VSRAM_VOSEL_DELTA));//delta = 0v pmic_set_register_value(PMIC_VSRAM_VOSEL_ON_LB,(vsram_vosel_on_lb&0xff80)|0x28);//0.85v }
static void spm_suspend_pre_process(struct pwr_ctrl *pwrctrl) { /* set PMIC WRAP table for suspend power control */ mt_cpufreq_set_pmic_phase(PMIC_WRAP_PHASE_SUSPEND); // FIXME: wait for dual-vcore suspend test finish. #if 1 if (is_dualvcore_pdn(pwrctrl->pcm_flags)) { /* set LTE pd mode to avoid LTE power on after dual-vcore resume */ //spm_write(AP_PLL_CON7, spm_read(AP_PLL_CON7) | 0xF); // set before dual-vcore suspend mt_cpufreq_apply_pmic_cmd(IDX_SP_VCORE_PDN_EN_HW_MODE); // if dual-vcore suspend enable, set VCORE_PND_EN to HW mode //mt6331_upmu_set_rg_int_en_chrdet(0); // disable charger detection to avoid abnormal EINT. //mt6331_upmu_set_rg_int_en_rtc(0); // mask rtc to avoid abnormal EINT. } else #endif mt_cpufreq_apply_pmic_cmd(IDX_SP_VCORE_PDN_EN_SW_MODE); // if dual-vcore suspend disable, set VCORE_PND_EN to SW mode spm_i2c_control(I2C_CHANNEL, 1); }
/* static bool spm_set_suspend_pcm_ver(u32 *suspend_flags) { u32 flag; flag = *suspend_flags; if(mt_get_clk_mem_sel()==MEMPLL3PLL) { __spm_suspend.pcmdesc = &suspend_pcm_3pll; flag |= SPM_VCORE_DVS_DIS; } else if(mt_get_clk_mem_sel()==MEMPLL1PLL) { __spm_suspend.pcmdesc = &suspend_pcm_1pll; flag &= ~SPM_VCORE_DVS_DIS; } else return false; *suspend_flags = flag; return true; } */ static void spm_suspend_pre_process(struct pwr_ctrl *pwrctrl) { #if 0 u32 rdata1 = 0, rdata2 = 0; #endif /* set PMIC WRAP table for suspend power control */ mt_cpufreq_set_pmic_phase(PMIC_WRAP_PHASE_SUSPEND); spm_i2c_control(I2C_CHANNEL, 1); #if 0 /* for infra pdn (emi driving) */ spm_write(0xF0004000, spm_read(0xF0004000) | (1 << 24)); /* MEMPLL control for SPM */ spm_write(0xF000F5C8, 0x3010F030); spm_write(0xF000F5CC, 0x50101010); #endif //spm_write(0xF0001070 , spm_read(0xF0001070) | (1 << 21)); // 26:26 enable //spm_write(0xF0000204 , spm_read(0xF0000204) | (1 << 0)); // BUS 26MHz enable //spm_write(0xF0001108 , 0x0); #ifdef CONFIG_MD32_SUPPORT //spm_write(MD32_BASE+0x2C, (spm_read(MD32_BASE+0x2C) & ~0xFFFF) | 0xcafe); #endif #if 0 pwrap_read(0x2c2, &rdata1); pwrap_write(0x2c2, 0x0123); pwrap_read(0x2c2, &rdata2); if(rdata2 != 0x0123) { spm_crit2("suspend pmic wrapper 0x2c2, rdata1 = 0x%x, rdata2 = 0x%x\n", rdata1, rdata2); BUG(); } #endif }
static void spm_suspend_post_process(struct pwr_ctrl *pwrctrl) { #if 0 u32 rdata1 = 0, rdata2 = 0; pwrap_read(0x2c2, &rdata1); pwrap_write(0x2c2, 0x3210); pwrap_read(0x2c2, &rdata2); if(rdata2 != 0x3210) { spm_crit2("resume pmic wrapper 0x2c2, rdata1 = 0x%x, rdata2 = 0x%x\n", rdata1, rdata2); BUG(); } #endif #ifdef CONFIG_MD32_SUPPORT //spm_write(MD32_BASE+0x2C, spm_read(MD32_BASE+0x2C) & ~0xFFFF); #endif /* set PMIC WRAP table for normal power control */ mt_cpufreq_set_pmic_phase(PMIC_WRAP_PHASE_NORMAL); spm_i2c_control(I2C_CHANNEL, 0); }
static void spm_suspend_post_process(struct pwr_ctrl *pwrctrl) { // FIXME: wait for dual-vcore suspend test finish. #if 1 if (is_dualvcore_pdn(pwrctrl->pcm_flags)) { /* restore LTE pd mode after dual-vcore resume */ //spm_write(AP_PLL_CON7, spm_read(AP_PLL_CON7) & ~0xF); // set after dual-vcore resume /* enable charger detection */ //mt6331_upmu_set_rg_int_en_chrdet(1); /* enable rtc */ //mt6331_upmu_set_rg_int_en_rtc(1); /* set VCORE_PND_EN to SW mode */ mt_cpufreq_apply_pmic_cmd(IDX_SP_VCORE_PDN_EN_SW_MODE); } #endif /* set PMIC WRAP table for normal power control */ mt_cpufreq_set_pmic_phase(PMIC_WRAP_PHASE_NORMAL); spm_i2c_control(I2C_CHANNEL, 0); }
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; }
/* * cpu_pdn: * true = CPU dormant * false = CPU standby * pwrlevel: * 0 = AXI is off * 1 = AXI is 26M * pwake_time: * >= 0 = specific wakeup period */ wake_reason_t spm_go_to_sleep_dpidle(u32 spm_flags, u32 spm_data) { u32 sec = 0; u32 dpidle_timer_val = 0; u32 dpidle_wake_src = 0; int wd_ret; struct wake_status wakesta; unsigned long flags; struct mtk_irq_mask mask; struct wd_api *wd_api; static wake_reason_t last_wr = WR_NONE; struct pcm_desc *pcmdesc = __spm_dpidle.pcmdesc; struct pwr_ctrl *pwrctrl = __spm_dpidle.pwrctrl; /* backup original dpidle setting */ dpidle_timer_val = pwrctrl->timer_val; dpidle_wake_src = pwrctrl->wake_src; set_pwrctrl_pcm_flags(pwrctrl, spm_flags); #if SPM_PWAKE_EN sec = spm_get_wake_period(-1 /* FIXME */, last_wr); #endif pwrctrl->timer_val = sec * 32768; pwrctrl->wake_src = spm_get_sleep_wakesrc(); wd_ret = get_wd_api(&wd_api); if (!wd_ret) wd_api->wd_suspend_notify(); 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(); /* set PMIC WRAP table for deepidle power control */ mt_cpufreq_set_pmic_phase(PMIC_WRAP_PHASE_DEEPIDLE); spm_crit2("sleep_deepidle, sec = %u, wakesrc = 0x%x [%u]\n", sec, pwrctrl->wake_src, is_cpu_pdn(pwrctrl->pcm_flags)); __spm_reset_and_init_pcm(pcmdesc); __spm_kick_im_to_fetch(pcmdesc); if (request_uart_to_sleep()) { last_wr = WR_UART_BUSY; goto RESTORE_IRQ; } __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_pre_process(); spm_trigger_wfi_for_dpidle(pwrctrl); spm_dpidle_post_process(); __spm_get_wakeup_status(&wakesta); __spm_clean_after_wakeup(); request_uart_to_wakeup(); last_wr = __spm_output_wake_reason(&wakesta, pcmdesc, true); RESTORE_IRQ: /* set PMIC WRAP table for normal power control */ mt_cpufreq_set_pmic_phase(PMIC_WRAP_PHASE_NORMAL); mt_cirq_flush(); mt_cirq_disable(); mt_irq_mask_restore(&mask); spin_unlock_irqrestore(&__spm_lock, flags); if (!wd_ret) wd_api->wd_resume_notify(); /* restore original dpidle setting */ pwrctrl->timer_val = dpidle_timer_val; pwrctrl->wake_src = dpidle_wake_src; return last_wr; }
void spm_go_to_sodi(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_sodi.pcmdesc; struct pwr_ctrl *pwrctrl = __spm_sodi.pwrctrl; #if SPM_AEE_RR_REC aee_rr_rec_sodi_val(1<<SPM_SODI_ENTER); #endif set_pwrctrl_pcm_flags(pwrctrl, spm_flags); /* set PMIC WRAP table for deepidle power control */ mt_cpufreq_set_pmic_phase(PMIC_WRAP_PHASE_SODI); soidle_before_wfi(0); lockdep_off(); spin_lock_irqsave(&__spm_lock, flags); mt_irq_mask_all(&mask); mt_irq_unmask_for_sleep(SPM_IRQ0_ID/*MT_SPM_IRQ_ID*/); mt_cirq_clone_gic(); mt_cirq_enable(); #if SPM_AEE_RR_REC aee_rr_rec_sodi_val(aee_rr_curr_sodi_val()|(1<<SPM_SODI_ENTER_SPM_FLOW)); #endif __spm_reset_and_init_pcm(pcmdesc); #if 0 /* 0: mempll shutdown mode; 1: cg mode */ gSpm_SODI_mempll_pwr_mode ? (pwrctrl->pcm_flags |= SPM_MEMPLL_CPU) : (pwrctrl->pcm_flags &= ~SPM_MEMPLL_CPU); #endif __spm_kick_im_to_fetch(pcmdesc); __spm_init_pcm_register(); __spm_init_event_vector(pcmdesc); /* set pcm_apsrc_req to be 1 if 10006b0c[0] is 1 */ if ((spm_read(SPM_PCM_SRC_REQ) & 1) || pwrctrl->pcm_apsrc_req) pwrctrl->pcm_apsrc_req = 1; else pwrctrl->pcm_apsrc_req = 0; __spm_set_power_control(pwrctrl); __spm_set_wakeup_event(pwrctrl); /* set pcm_flags[18] to be 1 if 10006b08[7] is 1 */ if ((spm_read(SPM_PCM_FLAGS) & SPM_MEMPLL_RESET) || gSpm_SODI_mempll_pwr_mode || (pwrctrl->pcm_flags_cust & SPM_MEMPLL_CPU)) pwrctrl->pcm_flags |= SPM_MEMPLL_CPU; else pwrctrl->pcm_flags &= ~SPM_MEMPLL_CPU; __spm_kick_pcm_to_run(pwrctrl); #if SPM_AEE_RR_REC aee_rr_rec_sodi_val(aee_rr_curr_sodi_val()|(1<<SPM_SODI_ENTER_WFI)); #endif spm_trigger_wfi_for_sodi(pwrctrl); #if SPM_AEE_RR_REC aee_rr_rec_sodi_val(aee_rr_curr_sodi_val()|(1<<SPM_SODI_LEAVE_WFI)); #endif __spm_get_wakeup_status(&wakesta); __spm_clean_after_wakeup(); wr = __spm_output_wake_reason(&wakesta, pcmdesc, false); /* for test */ /* wr = __spm_output_wake_reason(&wakesta, pcmdesc, true); */ #if SPM_AEE_RR_REC aee_rr_rec_sodi_val(aee_rr_curr_sodi_val()|(1<<SPM_SODI_LEAVE_SPM_FLOW)); #endif mt_cirq_flush(); mt_cirq_disable(); mt_irq_mask_restore(&mask); spin_unlock_irqrestore(&__spm_lock, flags); lockdep_on(); soidle_after_wfi(0); /* set PMIC WRAP table for normal power control */ mt_cpufreq_set_pmic_phase(PMIC_WRAP_PHASE_NORMAL); #if SPM_AEE_RR_REC aee_rr_rec_sodi_val(0); #endif //return wr; }