/* mask to avoid affecting apsrc_state */ .conn_mask = 1, .md1_req_mask = 1, .md2_req_mask = 1, .ccif0_to_ap_mask = 1, .ccif0_to_md_mask = 1, .ccif1_to_ap_mask = 1, .ccif1_to_md_mask = 1, .ccifmd_md1_event_mask = 1, .ccifmd_md2_event_mask = 1, .gce_req_mask = 1, .disp_req_mask = 1, .mfg_req_mask = 1, }; struct spm_lp_scen __spm_vcore_dvfs = { .pcmdesc = &vcore_dvfs_pcm, .pwrctrl = &vcore_dvfs_ctrl, }; char *spm_dump_vcore_dvs_regs(char *p) { if (p) { p += sprintf(p, "SLEEP_DVFS_STA: 0x%x\n", spm_read(SPM_SLEEP_DVFS_STA)); p += sprintf(p, "PCM_SRC_REQ : 0x%x\n", spm_read(SPM_PCM_SRC_REQ)); p += sprintf(p, "PCM_REG13_DATA: 0x%x\n", spm_read(SPM_PCM_REG13_DATA)); p += sprintf(p, "PCM_REG12_DATA: 0x%x\n", spm_read(SPM_PCM_REG12_DATA)); p += sprintf(p, "PCM_REG12_MASK: 0x%x\n", spm_read(SPM_PCM_REG12_MASK)); p += sprintf(p, "AP_STANBY_CON : 0x%x\n", spm_read(SPM_AP_STANBY_CON)); p += sprintf(p, "PCM_IM_PTR : 0x%x (%u)\n", spm_read(SPM_PCM_IM_PTR), spm_read(SPM_PCM_IM_LEN)); p += sprintf(p, "PCM_REG6_DATA : 0x%x\n", spm_read(SPM_PCM_REG6_DATA)); p += sprintf(p, "PCM_REG11_DATA: 0x%x\n", spm_read(SPM_PCM_REG11_DATA)); } else { spm_err("[VcoreFS] SLEEP_DVFS_STA: 0x%x\n", spm_read(SPM_SLEEP_DVFS_STA)); spm_err("[VcoreFS] PCM_SRC_REQ : 0x%x\n", spm_read(SPM_PCM_SRC_REQ)); spm_err("[VcoreFS] PCM_REG13_DATA: 0x%x\n", spm_read(SPM_PCM_REG13_DATA)); spm_err("[VcoreFS] PCM_REG12_DATA: 0x%x\n", spm_read(SPM_PCM_REG12_DATA)); spm_err("[VcoreFS] PCM_REG12_MASK: 0x%x\n", spm_read(SPM_PCM_REG12_MASK)); spm_err("[VcoreFS] AP_STANBY_CON : 0x%x\n", spm_read(SPM_AP_STANBY_CON)); spm_err("[VcoreFS] PCM_IM_PTR : 0x%x (%u)\n", spm_read(SPM_PCM_IM_PTR), spm_read(SPM_PCM_IM_LEN)); spm_err("[VcoreFS] PCM_REG6_DATA : 0x%x\n", spm_read(SPM_PCM_REG6_DATA)); spm_err("[VcoreFS] PCM_REG11_DATA: 0x%x\n", spm_read(SPM_PCM_REG11_DATA)); spm_err("[VcoreFS] PCM_REG0_DATA : 0x%x\n", spm_read(SPM_PCM_REG0_DATA)); spm_err("[VcoreFS] PCM_REG1_DATA : 0x%x\n", spm_read(SPM_PCM_REG1_DATA)); spm_err("[VcoreFS] PCM_REG2_DATA : 0x%x\n", spm_read(SPM_PCM_REG2_DATA)); spm_err("[VcoreFS] PCM_REG3_DATA : 0x%x\n", spm_read(SPM_PCM_REG3_DATA)); spm_err("[VcoreFS] PCM_REG4_DATA : 0x%x\n", spm_read(SPM_PCM_REG4_DATA)); spm_err("[VcoreFS] PCM_REG5_DATA : 0x%x\n", spm_read(SPM_PCM_REG5_DATA)); spm_err("[VcoreFS] PCM_REG7_DATA : 0x%x\n", spm_read(SPM_PCM_REG7_DATA)); spm_err("[VcoreFS] PCM_REG8_DATA : 0x%x\n", spm_read(SPM_PCM_REG8_DATA)); spm_err("[VcoreFS] PCM_REG9_DATA : 0x%x\n", spm_read(SPM_PCM_REG9_DATA)); spm_err("[VcoreFS] PCM_REG10_DATA: 0x%x\n", spm_read(SPM_PCM_REG10_DATA)); spm_err("[VcoreFS] PCM_REG14_DATA: 0x%x\n", spm_read(SPM_PCM_REG14_DATA)); spm_err("[VcoreFS] PCM_REG15_DATA: %u\n" , spm_read(SPM_PCM_REG15_DATA)); } return p; } static void __go_to_vcore_dvfs(u32 spm_flags, u8 f26m_req, u8 apsrc_req) { struct pcm_desc *pcmdesc = __spm_vcore_dvfs.pcmdesc; struct pwr_ctrl *pwrctrl = __spm_vcore_dvfs.pwrctrl; set_pwrctrl_pcm_flags(pwrctrl, spm_flags | SPM_MD_VRF18_DIS); /* FIXME */ pwrctrl->pcm_f26m_req = f26m_req; pwrctrl->pcm_apsrc_req = apsrc_req; __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); } #define wait_pcm_complete_dvs(condition, timeout) \ ({ \ int i = 0; \ while (!(condition)) { \ if (i >= (timeout)) { \ i = -EBUSY; \ break; \ } \ udelay(1); \ i++; \ } \ i; \ }) static bool is_fw_not_existed(void) { return spm_read(SPM_PCM_REG1_DATA) != 0x1 || spm_read(SPM_PCM_REG11_DATA) == 0x55AA55AA; } #if 0 /* For ULTRA Mode */ static bool is_fw_not_support_uhpm(void) { u32 pcm_ptr = spm_read(SPM_PCM_IM_PTR); u32 vcore_ptr = base_va_to_pa(__spm_vcore_dvfs.pcmdesc->base); /*u32 sodi_ptr = base_va_to_pa(__spm_sodi.pcmdesc->base);*/ return pcm_ptr != vcore_ptr /*&& pcm_ptr != sodi_ptr*/; }
void __spm_kick_im_to_fetch(const struct pcm_desc *pcmdesc) { u32 ptr, len, con0; /* tell IM where is PCM code (use slave mode if code existed) */ ptr = base_va_to_pa(pcmdesc->base); len = pcmdesc->size - 1; if (spm_read(SPM_PCM_IM_PTR) != ptr || spm_read(SPM_PCM_IM_LEN) != len || pcmdesc->sess > 2) { spm_write(SPM_PCM_IM_PTR, ptr); spm_write(SPM_PCM_IM_LEN, len); } else { spm_write(SPM_PCM_CON1, spm_read(SPM_PCM_CON1) | CON1_CFG_KEY | CON1_IM_SLAVE); } /* kick IM to fetch (only toggle IM_KICK) */ con0 = spm_read(SPM_PCM_CON0) & ~(CON0_IM_KICK | CON0_PCM_KICK); spm_write(SPM_PCM_CON0, con0 | CON0_CFG_KEY | CON0_IM_KICK); spm_write(SPM_PCM_CON0, con0 | CON0_CFG_KEY); }