1 /* 2 * Copyright (c) 2021, MediaTek Inc. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <stddef.h> 8 9 #include <assert.h> 10 #include <common/debug.h> 11 #include <lib/mmio.h> 12 13 #include <mt_spm.h> 14 #include <mt_spm_internal.h> 15 #include <mt_spm_pmic_wrap.h> 16 #include <mt_spm_reg.h> 17 #include <mt_spm_resource_req.h> 18 #include <platform_def.h> 19 #include <plat_pm.h> 20 21 /************************************** 22 * Define and Declare 23 **************************************/ 24 #define ROOT_CORE_ADDR_OFFSET 0x20000000 25 #define SPM_WAKEUP_EVENT_MASK_CLEAN_MASK 0xefffffff 26 #define SPM_INIT_DONE_US 20 27 28 static unsigned int mt_spm_bblpm_cnt; 29 30 const char *wakeup_src_str[32] = { 31 [0] = "R12_PCM_TIMER", 32 [1] = "R12_RESERVED_DEBUG_B", 33 [2] = "R12_KP_IRQ_B", 34 [3] = "R12_APWDT_EVENT_B", 35 [4] = "R12_APXGPT1_EVENT_B", 36 [5] = "R12_MSDC_WAKEUP_B", 37 [6] = "R12_EINT_EVENT_B", 38 [7] = "R12_IRRX_WAKEUP_B", 39 [8] = "R12_SBD_INTR_WAKEUP_B", 40 [9] = "R12_RESERVE0", 41 [10] = "R12_SC_SSPM2SPM_WAKEUP_B", 42 [11] = "R12_SC_SCP2SPM_WAKEUP_B", 43 [12] = "R12_SC_ADSP2SPM_WAKEUP_B", 44 [13] = "R12_WDT_WAKEUP_B", 45 [14] = "R12_USB_U2_B", 46 [15] = "R12_USB_TOP_B", 47 [16] = "R12_SYS_TIMER_EVENT_B", 48 [17] = "R12_EINT_EVENT_SECURE_B", 49 [18] = "R12_ECE_INT_HDMI_B", 50 [19] = "R12_RESERVE1", 51 [20] = "R12_AFE_IRQ_MCU_B", 52 [21] = "R12_THERM_CTRL_EVENT_B", 53 [22] = "R12_SCP_CIRQ_IRQ_B", 54 [23] = "R12_NNA2INFRA_WAKEUP_B", 55 [24] = "R12_CSYSPWREQ_B", 56 [25] = "R12_RESERVE2", 57 [26] = "R12_PCIE_WAKEUPEVENT_B", 58 [27] = "R12_SEJ_EVENT_B", 59 [28] = "R12_SPM_CPU_WAKEUPEVENT_B", 60 [29] = "R12_APUSYS", 61 [30] = "R12_RESERVE3", 62 [31] = "R12_RESERVE4", 63 }; 64 65 /************************************** 66 * Function and API 67 **************************************/ 68 69 wake_reason_t __spm_output_wake_reason(int state_id, 70 const struct wake_status *wakesta) 71 { 72 uint32_t i, bk_vtcxo_dur, spm_26m_off_pct = 0U; 73 wake_reason_t wr = WR_UNKNOWN; 74 75 if (wakesta == NULL) { 76 return WR_UNKNOWN; 77 } 78 79 if (wakesta->abort != 0U) { 80 ERROR("spmfw flow is aborted: 0x%x, timer_out = %u\n", 81 wakesta->abort, wakesta->timer_out); 82 } else { 83 for (i = 0U; i < 32U; i++) { 84 if ((wakesta->r12 & (1U << i)) != 0U) { 85 INFO("wake up by %s, timer_out = %u\n", 86 wakeup_src_str[i], wakesta->timer_out); 87 wr = WR_WAKE_SRC; 88 break; 89 } 90 } 91 } 92 93 INFO("r12 = 0x%x, r12_ext = 0x%x, r13 = 0x%x, debug_flag = 0x%x 0x%x\n", 94 wakesta->r12, wakesta->r12_ext, wakesta->r13, wakesta->debug_flag, 95 wakesta->debug_flag1); 96 INFO("raw_sta = 0x%x 0x%x 0x%x, idle_sta = 0x%x, cg_check_sta = 0x%x\n", 97 wakesta->raw_sta, wakesta->md32pcm_wakeup_sta, 98 wakesta->md32pcm_event_sta, wakesta->idle_sta, 99 wakesta->cg_check_sta); 100 INFO("req_sta = 0x%x 0x%x 0x%x 0x%x 0x%x, isr = 0x%x\n", 101 wakesta->req_sta0, wakesta->req_sta1, wakesta->req_sta2, 102 wakesta->req_sta3, wakesta->req_sta4, wakesta->isr); 103 INFO("rt_req_sta0 = 0x%x, rt_req_sta1 = 0x%x, rt_req_sta2 = 0x%x\n", 104 wakesta->rt_req_sta0, wakesta->rt_req_sta1, wakesta->rt_req_sta2); 105 INFO("rt_req_sta3 = 0x%x, dram_sw_con_3 = 0x%x, raw_ext_sta = 0x%x\n", 106 wakesta->rt_req_sta3, wakesta->rt_req_sta4, wakesta->raw_ext_sta); 107 INFO("wake_misc = 0x%x, pcm_flag = 0x%x 0x%x 0x%x 0x%x, req = 0x%x\n", 108 wakesta->wake_misc, wakesta->sw_flag0, wakesta->sw_flag1, 109 wakesta->b_sw_flag0, wakesta->b_sw_flag1, wakesta->src_req); 110 INFO("clk_settle = 0x%x, wlk_cntcv_l = 0x%x, wlk_cntcv_h = 0x%x\n", 111 wakesta->clk_settle, mmio_read_32(SYS_TIMER_VALUE_L), 112 mmio_read_32(SYS_TIMER_VALUE_H)); 113 114 if (wakesta->timer_out != 0U) { 115 bk_vtcxo_dur = mmio_read_32(SPM_BK_VTCXO_DUR); 116 spm_26m_off_pct = (100 * bk_vtcxo_dur) / wakesta->timer_out; 117 INFO("spm_26m_off_pct = %u\n", spm_26m_off_pct); 118 } 119 120 return wr; 121 } 122 123 void __spm_set_cpu_status(unsigned int cpu) 124 { 125 uint32_t root_core_addr; 126 127 if (cpu < 8U) { 128 mmio_write_32(ROOT_CPUTOP_ADDR, (1U << cpu)); 129 root_core_addr = SPM_CPU0_PWR_CON + (cpu * 0x4); 130 root_core_addr += ROOT_CORE_ADDR_OFFSET; 131 mmio_write_32(ROOT_CORE_ADDR, root_core_addr); 132 /* Notify MCUPM that preferred cpu wakeup */ 133 mmio_write_32(MCUPM_MBOX_WAKEUP_CPU, cpu); 134 } else { 135 ERROR("%s: error cpu number %d\n", __func__, cpu); 136 } 137 } 138 139 void __spm_src_req_update(const struct pwr_ctrl *pwrctrl, 140 unsigned int resource_usage) 141 { 142 uint8_t apsrc_req = ((resource_usage & MT_SPM_DRAM_S0) != 0U) ? 143 1 : pwrctrl->reg_spm_apsrc_req; 144 uint8_t ddr_en_req = ((resource_usage & MT_SPM_DRAM_S1) != 0U) ? 145 1 : pwrctrl->reg_spm_ddr_en_req; 146 uint8_t vrf18_req = ((resource_usage & MT_SPM_SYSPLL) != 0U) ? 147 1 : pwrctrl->reg_spm_vrf18_req; 148 uint8_t infra_req = ((resource_usage & MT_SPM_INFRA) != 0U) ? 149 1 : pwrctrl->reg_spm_infra_req; 150 uint8_t f26m_req = ((resource_usage & 151 (MT_SPM_26M | MT_SPM_XO_FPM)) != 0U) ? 152 1 : pwrctrl->reg_spm_f26m_req; 153 154 mmio_write_32(SPM_SRC_REQ, 155 ((apsrc_req & 0x1) << 0) | 156 ((f26m_req & 0x1) << 1) | 157 ((infra_req & 0x1) << 3) | 158 ((vrf18_req & 0x1) << 4) | 159 ((ddr_en_req & 0x1) << 7) | 160 ((pwrctrl->reg_spm_dvfs_req & 0x1) << 8) | 161 ((pwrctrl->reg_spm_sw_mailbox_req & 0x1) << 9) | 162 ((pwrctrl->reg_spm_sspm_mailbox_req & 0x1) << 10) | 163 ((pwrctrl->reg_spm_adsp_mailbox_req & 0x1) << 11) | 164 ((pwrctrl->reg_spm_scp_mailbox_req & 0x1) << 12)); 165 } 166 167 void __spm_set_power_control(const struct pwr_ctrl *pwrctrl) 168 { 169 /* Auto-gen Start */ 170 171 /* SPM_AP_STANDBY_CON */ 172 mmio_write_32(SPM_AP_STANDBY_CON, 173 ((pwrctrl->reg_wfi_op & 0x1) << 0) | 174 ((pwrctrl->reg_wfi_type & 0x1) << 1) | 175 ((pwrctrl->reg_mp0_cputop_idle_mask & 0x1) << 2) | 176 ((pwrctrl->reg_mp1_cputop_idle_mask & 0x1) << 3) | 177 ((pwrctrl->reg_mcusys_idle_mask & 0x1) << 4) | 178 ((pwrctrl->reg_md_apsrc_1_sel & 0x1) << 25) | 179 ((pwrctrl->reg_md_apsrc_0_sel & 0x1) << 26) | 180 ((pwrctrl->reg_conn_apsrc_sel & 0x1) << 29)); 181 182 /* SPM_SRC_REQ */ 183 mmio_write_32(SPM_SRC_REQ, 184 ((pwrctrl->reg_spm_apsrc_req & 0x1) << 0) | 185 ((pwrctrl->reg_spm_f26m_req & 0x1) << 1) | 186 ((pwrctrl->reg_spm_infra_req & 0x1) << 3) | 187 ((pwrctrl->reg_spm_vrf18_req & 0x1) << 4) | 188 ((pwrctrl->reg_spm_ddr_en_req & 0x1) << 7) | 189 ((pwrctrl->reg_spm_dvfs_req & 0x1) << 8) | 190 ((pwrctrl->reg_spm_sw_mailbox_req & 0x1) << 9) | 191 ((pwrctrl->reg_spm_sspm_mailbox_req & 0x1) << 10) | 192 ((pwrctrl->reg_spm_adsp_mailbox_req & 0x1) << 11) | 193 ((pwrctrl->reg_spm_scp_mailbox_req & 0x1) << 12)); 194 195 /* SPM_SRC_MASK */ 196 mmio_write_32(SPM_SRC_MASK, 197 ((pwrctrl->reg_sspm_srcclkena_0_mask_b & 0x1) << 0) | 198 ((pwrctrl->reg_sspm_infra_req_0_mask_b & 0x1) << 1) | 199 ((pwrctrl->reg_sspm_apsrc_req_0_mask_b & 0x1) << 2) | 200 ((pwrctrl->reg_sspm_vrf18_req_0_mask_b & 0x1) << 3) | 201 ((pwrctrl->reg_sspm_ddr_en_0_mask_b & 0x1) << 4) | 202 ((pwrctrl->reg_scp_srcclkena_mask_b & 0x1) << 5) | 203 ((pwrctrl->reg_scp_infra_req_mask_b & 0x1) << 6) | 204 ((pwrctrl->reg_scp_apsrc_req_mask_b & 0x1) << 7) | 205 ((pwrctrl->reg_scp_vrf18_req_mask_b & 0x1) << 8) | 206 ((pwrctrl->reg_scp_ddr_en_mask_b & 0x1) << 9) | 207 ((pwrctrl->reg_audio_dsp_srcclkena_mask_b & 0x1) << 10) | 208 ((pwrctrl->reg_audio_dsp_infra_req_mask_b & 0x1) << 11) | 209 ((pwrctrl->reg_audio_dsp_apsrc_req_mask_b & 0x1) << 12) | 210 ((pwrctrl->reg_audio_dsp_vrf18_req_mask_b & 0x1) << 13) | 211 ((pwrctrl->reg_audio_dsp_ddr_en_mask_b & 0x1) << 14) | 212 ((pwrctrl->reg_apu_srcclkena_mask_b & 0x1) << 15) | 213 ((pwrctrl->reg_apu_infra_req_mask_b & 0x1) << 16) | 214 ((pwrctrl->reg_apu_apsrc_req_mask_b & 0x1) << 17) | 215 ((pwrctrl->reg_apu_vrf18_req_mask_b & 0x1) << 18) | 216 ((pwrctrl->reg_apu_ddr_en_mask_b & 0x1) << 19) | 217 ((pwrctrl->reg_cpueb_srcclkena_mask_b & 0x1) << 20) | 218 ((pwrctrl->reg_cpueb_infra_req_mask_b & 0x1) << 21) | 219 ((pwrctrl->reg_cpueb_apsrc_req_mask_b & 0x1) << 22) | 220 ((pwrctrl->reg_cpueb_vrf18_req_mask_b & 0x1) << 23) | 221 ((pwrctrl->reg_cpueb_ddr_en_mask_b & 0x1) << 24) | 222 ((pwrctrl->reg_bak_psri_srcclkena_mask_b & 0x1) << 25) | 223 ((pwrctrl->reg_bak_psri_infra_req_mask_b & 0x1) << 26) | 224 ((pwrctrl->reg_bak_psri_apsrc_req_mask_b & 0x1) << 27) | 225 ((pwrctrl->reg_bak_psri_vrf18_req_mask_b & 0x1) << 28) | 226 ((pwrctrl->reg_bak_psri_ddr_en_mask_b & 0x1) << 29)); 227 228 /* SPM_SRC2_MASK */ 229 mmio_write_32(SPM_SRC2_MASK, 230 ((pwrctrl->reg_msdc0_srcclkena_mask_b & 0x1) << 0) | 231 ((pwrctrl->reg_msdc0_infra_req_mask_b & 0x1) << 1) | 232 ((pwrctrl->reg_msdc0_apsrc_req_mask_b & 0x1) << 2) | 233 ((pwrctrl->reg_msdc0_vrf18_req_mask_b & 0x1) << 3) | 234 ((pwrctrl->reg_msdc0_ddr_en_mask_b & 0x1) << 4) | 235 ((pwrctrl->reg_msdc1_srcclkena_mask_b & 0x1) << 5) | 236 ((pwrctrl->reg_msdc1_infra_req_mask_b & 0x1) << 6) | 237 ((pwrctrl->reg_msdc1_apsrc_req_mask_b & 0x1) << 7) | 238 ((pwrctrl->reg_msdc1_vrf18_req_mask_b & 0x1) << 8) | 239 ((pwrctrl->reg_msdc1_ddr_en_mask_b & 0x1) << 9) | 240 ((pwrctrl->reg_msdc2_srcclkena_mask_b & 0x1) << 10) | 241 ((pwrctrl->reg_msdc2_infra_req_mask_b & 0x1) << 11) | 242 ((pwrctrl->reg_msdc2_apsrc_req_mask_b & 0x1) << 12) | 243 ((pwrctrl->reg_msdc2_vrf18_req_mask_b & 0x1) << 13) | 244 ((pwrctrl->reg_msdc2_ddr_en_mask_b & 0x1) << 14) | 245 ((pwrctrl->reg_ufs_srcclkena_mask_b & 0x1) << 15) | 246 ((pwrctrl->reg_ufs_infra_req_mask_b & 0x1) << 16) | 247 ((pwrctrl->reg_ufs_apsrc_req_mask_b & 0x1) << 17) | 248 ((pwrctrl->reg_ufs_vrf18_req_mask_b & 0x1) << 18) | 249 ((pwrctrl->reg_ufs_ddr_en_mask_b & 0x1) << 19) | 250 ((pwrctrl->reg_usb_srcclkena_mask_b & 0x1) << 20) | 251 ((pwrctrl->reg_usb_infra_req_mask_b & 0x1) << 21) | 252 ((pwrctrl->reg_usb_apsrc_req_mask_b & 0x1) << 22) | 253 ((pwrctrl->reg_usb_vrf18_req_mask_b & 0x1) << 23) | 254 ((pwrctrl->reg_usb_ddr_en_mask_b & 0x1) << 24) | 255 ((pwrctrl->reg_pextp_p0_srcclkena_mask_b & 0x1) << 25) | 256 ((pwrctrl->reg_pextp_p0_infra_req_mask_b & 0x1) << 26) | 257 ((pwrctrl->reg_pextp_p0_apsrc_req_mask_b & 0x1) << 27) | 258 ((pwrctrl->reg_pextp_p0_vrf18_req_mask_b & 0x1) << 28) | 259 ((pwrctrl->reg_pextp_p0_ddr_en_mask_b & 0x1) << 29)); 260 261 /* SPM_SRC3_MASK */ 262 mmio_write_32(SPM_SRC3_MASK, 263 ((pwrctrl->reg_pextp_p1_srcclkena_mask_b & 0x1) << 0) | 264 ((pwrctrl->reg_pextp_p1_infra_req_mask_b & 0x1) << 1) | 265 ((pwrctrl->reg_pextp_p1_apsrc_req_mask_b & 0x1) << 2) | 266 ((pwrctrl->reg_pextp_p1_vrf18_req_mask_b & 0x1) << 3) | 267 ((pwrctrl->reg_pextp_p1_ddr_en_mask_b & 0x1) << 4) | 268 ((pwrctrl->reg_gce0_infra_req_mask_b & 0x1) << 5) | 269 ((pwrctrl->reg_gce0_apsrc_req_mask_b & 0x1) << 6) | 270 ((pwrctrl->reg_gce0_vrf18_req_mask_b & 0x1) << 7) | 271 ((pwrctrl->reg_gce0_ddr_en_mask_b & 0x1) << 8) | 272 ((pwrctrl->reg_gce1_infra_req_mask_b & 0x1) << 9) | 273 ((pwrctrl->reg_gce1_apsrc_req_mask_b & 0x1) << 10) | 274 ((pwrctrl->reg_gce1_vrf18_req_mask_b & 0x1) << 11) | 275 ((pwrctrl->reg_gce1_ddr_en_mask_b & 0x1) << 12) | 276 ((pwrctrl->reg_spm_srcclkena_reserved_mask_b & 0x1) << 13) | 277 ((pwrctrl->reg_spm_infra_req_reserved_mask_b & 0x1) << 14) | 278 ((pwrctrl->reg_spm_apsrc_req_reserved_mask_b & 0x1) << 15) | 279 ((pwrctrl->reg_spm_vrf18_req_reserved_mask_b & 0x1) << 16) | 280 ((pwrctrl->reg_spm_ddr_en_reserved_mask_b & 0x1) << 17) | 281 ((pwrctrl->reg_disp0_ddr_en_mask_b & 0x1) << 18) | 282 ((pwrctrl->reg_disp0_ddr_en_mask_b & 0x1) << 19) | 283 ((pwrctrl->reg_disp1_apsrc_req_mask_b & 0x1) << 20) | 284 ((pwrctrl->reg_disp1_ddr_en_mask_b & 0x1) << 21) | 285 ((pwrctrl->reg_disp2_apsrc_req_mask_b & 0x1) << 22) | 286 ((pwrctrl->reg_disp2_ddr_en_mask_b & 0x1) << 23) | 287 ((pwrctrl->reg_disp3_apsrc_req_mask_b & 0x1) << 24) | 288 ((pwrctrl->reg_disp3_ddr_en_mask_b & 0x1) << 25) | 289 ((pwrctrl->reg_infrasys_apsrc_req_mask_b & 0x1) << 26) | 290 ((pwrctrl->reg_infrasys_ddr_en_mask_b & 0x1) << 27)); 291 292 /* Mask MCUSYS request since SOC HW would check it */ 293 mmio_write_32(SPM_SRC4_MASK, 0x1fc0000); 294 295 /* SPM_WAKEUP_EVENT_MASK */ 296 mmio_write_32(SPM_WAKEUP_EVENT_MASK, 297 ((pwrctrl->reg_wakeup_event_mask & 0xffffffff) << 0)); 298 299 /* SPM_WAKEUP_EVENT_EXT_MASK */ 300 mmio_write_32(SPM_WAKEUP_EVENT_EXT_MASK, 301 ((pwrctrl->reg_ext_wakeup_event_mask & 0xffffffff) << 0)); 302 303 /* Auto-gen End */ 304 } 305 306 void __spm_disable_pcm_timer(void) 307 { 308 mmio_clrsetbits_32(PCM_CON1, RG_PCM_TIMER_EN_LSB, SPM_REGWR_CFG_KEY); 309 } 310 311 void __spm_set_wakeup_event(const struct pwr_ctrl *pwrctrl) 312 { 313 uint32_t val, mask; 314 315 /* toggle event counter clear */ 316 mmio_setbits_32(PCM_CON1, 317 SPM_REGWR_CFG_KEY | SPM_EVENT_COUNTER_CLR_LSB); 318 319 /* toggle for reset SYS TIMER start point */ 320 mmio_setbits_32(SYS_TIMER_CON, SYS_TIMER_START_EN_LSB); 321 322 if (pwrctrl->timer_val_cust == 0U) { 323 val = pwrctrl->timer_val; 324 } else { 325 val = pwrctrl->timer_val_cust; 326 } 327 328 mmio_write_32(PCM_TIMER_VAL, val); 329 mmio_setbits_32(PCM_CON1, SPM_REGWR_CFG_KEY | RG_PCM_TIMER_EN_LSB); 330 331 /* unmask AP wakeup source */ 332 if (pwrctrl->wake_src_cust == 0U) { 333 mask = pwrctrl->wake_src; 334 } else { 335 mask = pwrctrl->wake_src_cust; 336 } 337 338 mmio_write_32(SPM_WAKEUP_EVENT_MASK, ~mask); 339 340 /* unmask SPM ISR (keep TWAM setting) */ 341 mmio_setbits_32(SPM_IRQ_MASK, ISRM_RET_IRQ_AUX); 342 343 /* toggle event counter clear */ 344 mmio_clrsetbits_32(PCM_CON1, SPM_EVENT_COUNTER_CLR_LSB, 345 SPM_REGWR_CFG_KEY); 346 /* toggle for reset SYS TIMER start point */ 347 mmio_clrbits_32(SYS_TIMER_CON, SYS_TIMER_START_EN_LSB); 348 } 349 350 void __spm_set_pcm_flags(struct pwr_ctrl *pwrctrl) 351 { 352 /* set PCM flags and data */ 353 if (pwrctrl->pcm_flags_cust_clr != 0U) { 354 pwrctrl->pcm_flags &= ~pwrctrl->pcm_flags_cust_clr; 355 } 356 357 if (pwrctrl->pcm_flags_cust_set != 0U) { 358 pwrctrl->pcm_flags |= pwrctrl->pcm_flags_cust_set; 359 } 360 361 if (pwrctrl->pcm_flags1_cust_clr != 0U) { 362 pwrctrl->pcm_flags1 &= ~pwrctrl->pcm_flags1_cust_clr; 363 } 364 365 if (pwrctrl->pcm_flags1_cust_set != 0U) { 366 pwrctrl->pcm_flags1 |= pwrctrl->pcm_flags1_cust_set; 367 } 368 369 mmio_write_32(SPM_SW_FLAG_0, pwrctrl->pcm_flags); 370 mmio_write_32(SPM_SW_FLAG_1, pwrctrl->pcm_flags1); 371 mmio_write_32(SPM_SW_RSV_7, pwrctrl->pcm_flags); 372 mmio_write_32(SPM_SW_RSV_8, pwrctrl->pcm_flags1); 373 } 374 375 void __spm_get_wakeup_status(struct wake_status *wakesta, 376 unsigned int ext_status) 377 { 378 wakesta->tr.comm.r12 = mmio_read_32(SPM_BK_WAKE_EVENT); 379 wakesta->tr.comm.timer_out = mmio_read_32(SPM_BK_PCM_TIMER); 380 wakesta->tr.comm.r13 = mmio_read_32(PCM_REG13_DATA); 381 wakesta->tr.comm.req_sta0 = mmio_read_32(SRC_REQ_STA_0); 382 wakesta->tr.comm.req_sta1 = mmio_read_32(SRC_REQ_STA_1); 383 wakesta->tr.comm.req_sta2 = mmio_read_32(SRC_REQ_STA_2); 384 wakesta->tr.comm.req_sta3 = mmio_read_32(SRC_REQ_STA_3); 385 wakesta->tr.comm.req_sta4 = mmio_read_32(SRC_REQ_STA_4); 386 wakesta->tr.comm.debug_flag = mmio_read_32(PCM_WDT_LATCH_SPARE_0); 387 wakesta->tr.comm.debug_flag1 = mmio_read_32(PCM_WDT_LATCH_SPARE_1); 388 389 if ((ext_status & SPM_INTERNAL_STATUS_HW_S1) != 0U) { 390 wakesta->tr.comm.debug_flag |= (SPM_DBG_DEBUG_IDX_DDREN_WAKE | 391 SPM_DBG_DEBUG_IDX_DDREN_SLEEP); 392 mmio_write_32(PCM_WDT_LATCH_SPARE_0, 393 wakesta->tr.comm.debug_flag); 394 } 395 396 wakesta->tr.comm.b_sw_flag0 = mmio_read_32(SPM_SW_RSV_7); 397 wakesta->tr.comm.b_sw_flag1 = mmio_read_32(SPM_SW_RSV_8); 398 399 /* record below spm info for debug */ 400 wakesta->r12 = mmio_read_32(SPM_BK_WAKE_EVENT); 401 wakesta->r12_ext = mmio_read_32(SPM_WAKEUP_STA); 402 wakesta->raw_sta = mmio_read_32(SPM_WAKEUP_STA); 403 wakesta->raw_ext_sta = mmio_read_32(SPM_WAKEUP_EXT_STA); 404 wakesta->md32pcm_wakeup_sta = mmio_read_32(MD32PCM_WAKEUP_STA); 405 wakesta->md32pcm_event_sta = mmio_read_32(MD32PCM_EVENT_STA); 406 wakesta->src_req = mmio_read_32(SPM_SRC_REQ); 407 408 /* backup of SPM_WAKEUP_MISC */ 409 wakesta->wake_misc = mmio_read_32(SPM_BK_WAKE_MISC); 410 411 /* get sleep time, backup of PCM_TIMER_OUT */ 412 wakesta->timer_out = mmio_read_32(SPM_BK_PCM_TIMER); 413 414 /* get other SYS and co-clock status */ 415 wakesta->r13 = mmio_read_32(PCM_REG13_DATA); 416 wakesta->idle_sta = mmio_read_32(SUBSYS_IDLE_STA); 417 wakesta->req_sta0 = mmio_read_32(SRC_REQ_STA_0); 418 wakesta->req_sta1 = mmio_read_32(SRC_REQ_STA_1); 419 wakesta->req_sta2 = mmio_read_32(SRC_REQ_STA_2); 420 wakesta->req_sta3 = mmio_read_32(SRC_REQ_STA_3); 421 wakesta->req_sta4 = mmio_read_32(SRC_REQ_STA_4); 422 423 /* get HW CG check status */ 424 wakesta->cg_check_sta = mmio_read_32(SPM_CG_CHECK_STA); 425 426 /* get debug flag for PCM execution check */ 427 wakesta->debug_flag = mmio_read_32(PCM_WDT_LATCH_SPARE_0); 428 wakesta->debug_flag1 = mmio_read_32(PCM_WDT_LATCH_SPARE_1); 429 430 /* get backup SW flag status */ 431 wakesta->b_sw_flag0 = mmio_read_32(SPM_SW_RSV_7); 432 wakesta->b_sw_flag1 = mmio_read_32(SPM_SW_RSV_8); 433 434 wakesta->rt_req_sta0 = mmio_read_32(SPM_SW_RSV_2); 435 wakesta->rt_req_sta1 = mmio_read_32(SPM_SW_RSV_3); 436 wakesta->rt_req_sta2 = mmio_read_32(SPM_SW_RSV_4); 437 wakesta->rt_req_sta3 = mmio_read_32(SPM_SW_RSV_5); 438 wakesta->rt_req_sta4 = mmio_read_32(SPM_SW_RSV_6); 439 440 /* get ISR status */ 441 wakesta->isr = mmio_read_32(SPM_IRQ_STA); 442 443 /* get SW flag status */ 444 wakesta->sw_flag0 = mmio_read_32(SPM_SW_FLAG_0); 445 wakesta->sw_flag1 = mmio_read_32(SPM_SW_FLAG_1); 446 447 /* get CLK SETTLE */ 448 wakesta->clk_settle = mmio_read_32(SPM_CLK_SETTLE); 449 450 /* check abort */ 451 wakesta->abort = (wakesta->debug_flag & DEBUG_ABORT_MASK) | 452 (wakesta->debug_flag1 & DEBUG_ABORT_MASK_1); 453 } 454 455 void __spm_clean_after_wakeup(void) 456 { 457 mmio_write_32(SPM_BK_WAKE_EVENT, 458 mmio_read_32(SPM_WAKEUP_STA) | 459 mmio_read_32(SPM_BK_WAKE_EVENT)); 460 mmio_write_32(SPM_CPU_WAKEUP_EVENT, 0); 461 462 /* 463 * clean wakeup event raw status (for edge trigger event) 464 * bit[28] for cpu wake up event 465 */ 466 mmio_write_32(SPM_WAKEUP_EVENT_MASK, SPM_WAKEUP_EVENT_MASK_CLEAN_MASK); 467 468 /* clean ISR status (except TWAM) */ 469 mmio_setbits_32(SPM_IRQ_MASK, ISRM_ALL_EXC_TWAM); 470 mmio_write_32(SPM_IRQ_STA, ISRC_ALL_EXC_TWAM); 471 mmio_write_32(SPM_SWINT_CLR, PCM_SW_INT_ALL); 472 } 473 474 void __spm_set_pcm_wdt(int en) 475 { 476 mmio_clrsetbits_32(PCM_CON1, RG_PCM_WDT_EN_LSB, 477 SPM_REGWR_CFG_KEY); 478 479 if (en == 1) { 480 mmio_clrsetbits_32(PCM_CON1, RG_PCM_WDT_WAKE_LSB, 481 SPM_REGWR_CFG_KEY); 482 483 if (mmio_read_32(PCM_TIMER_VAL) > PCM_TIMER_MAX) { 484 mmio_write_32(PCM_TIMER_VAL, PCM_TIMER_MAX); 485 } 486 487 mmio_write_32(PCM_WDT_VAL, 488 mmio_read_32(PCM_TIMER_VAL) + PCM_WDT_TIMEOUT); 489 mmio_setbits_32(PCM_CON1, 490 SPM_REGWR_CFG_KEY | RG_PCM_WDT_EN_LSB); 491 } 492 } 493 494 void __spm_send_cpu_wakeup_event(void) 495 { 496 /* SPM will clear SPM_CPU_WAKEUP_EVENT */ 497 mmio_write_32(SPM_CPU_WAKEUP_EVENT, 1); 498 } 499 500 void __spm_ext_int_wakeup_req_clr(void) 501 { 502 mmio_write_32(EXT_INT_WAKEUP_REQ_CLR, mmio_read_32(ROOT_CPUTOP_ADDR)); 503 504 /* Clear spm2mcupm wakeup interrupt status */ 505 mmio_write_32(SPM2CPUEB_CON, 0); 506 } 507 508 void __spm_xo_soc_bblpm(int en) 509 { 510 if (en == 1) { 511 mmio_clrsetbits_32(RC_M00_SRCLKEN_CFG, 512 RC_SW_SRCLKEN_FPM, RC_SW_SRCLKEN_RC); 513 assert(mt_spm_bblpm_cnt == 0); 514 mt_spm_bblpm_cnt += 1; 515 } else { 516 mmio_clrsetbits_32(RC_M00_SRCLKEN_CFG, 517 RC_SW_SRCLKEN_RC, RC_SW_SRCLKEN_FPM); 518 mt_spm_bblpm_cnt -= 1; 519 } 520 } 521 522 void __spm_hw_s1_state_monitor(int en, unsigned int *status) 523 { 524 unsigned int reg; 525 526 reg = mmio_read_32(SPM_ACK_CHK_CON_3); 527 528 if (en == 1) { 529 reg &= ~SPM_ACK_CHK_3_CON_CLR_ALL; 530 mmio_write_32(SPM_ACK_CHK_CON_3, reg); 531 reg |= SPM_ACK_CHK_3_CON_EN; 532 mmio_write_32(SPM_ACK_CHK_CON_3, reg); 533 } else { 534 if (((reg & SPM_ACK_CHK_3_CON_RESULT) != 0U) && 535 (status != NULL)) { 536 *status |= SPM_INTERNAL_STATUS_HW_S1; 537 } 538 539 mmio_clrsetbits_32(SPM_ACK_CHK_CON_3, SPM_ACK_CHK_3_CON_EN, 540 SPM_ACK_CHK_3_CON_HW_MODE_TRIG | 541 SPM_ACK_CHK_3_CON_CLR_ALL); 542 } 543 } 544