1 /* 2 * Copyright (c) 2023, MediaTek Inc. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <stddef.h> 9 #include <stdio.h> 10 #include <string.h> 11 12 #include <common/debug.h> 13 #include <drivers/delay_timer.h> 14 #include <lib/mmio.h> 15 16 #include <drivers/spm/mt_spm_resource_req.h> 17 #include "mt_spm.h" 18 #include "mt_spm_internal.h" 19 #include "mt_spm_pmic_wrap.h" 20 #include "mt_spm_reg.h" 21 #include <platform_def.h> 22 23 #define SPM_INIT_DONE_US (20) /* Simulation result */ 24 25 wake_reason_t __spm_output_wake_reason(const struct wake_status *wakesta) 26 { 27 wake_reason_t wr = WR_UNKNOWN; 28 29 if (wakesta == NULL) { 30 return wr; 31 } 32 33 if (wakesta->is_abort != 0U) { 34 VERBOSE("SPM EARLY WAKE r12 = 0x%x, debug_flag = 0x%x 0x%x\n", 35 wakesta->tr.comm.r12, 36 wakesta->tr.comm.debug_flag, wakesta->tr.comm.debug_flag1); 37 VERBOSE("SPM EARLY WAKE sw_flag = 0x%x 0x%x b_sw_flag = 0x%x 0x%x\n", 38 wakesta->sw_flag0, wakesta->sw_flag1, 39 wakesta->tr.comm.b_sw_flag0, wakesta->tr.comm.b_sw_flag1); 40 } 41 42 if ((wakesta->tr.comm.r12 & R12_PCM_TIMER) != 0U) { 43 44 if ((wakesta->wake_misc & WAKE_MISC_PCM_TIMER_EVENT) != 0U) { 45 wr = WR_PCM_TIMER; 46 } 47 } 48 49 return wr; 50 } 51 52 void __spm_set_cpu_status(unsigned int cpu) 53 { 54 if (cpu >= 8) { 55 ERROR("%s: error cpu number %d\n", __func__, cpu); 56 return; 57 } 58 mmio_write_32(ROOT_CPUTOP_ADDR, BIT(cpu)); 59 mmio_write_32(ROOT_CORE_ADDR, SPM_CPU0_PWR_CON + (cpu * 0x4) + 0x20000000); 60 /* Notify MCUPM to wake the target CPU up */ 61 mmio_write_32(MCUPM_MBOX_WAKEUP_CPU, cpu); 62 } 63 64 void __spm_src_req_update(const struct pwr_ctrl *pwrctrl, unsigned int resource_usage) 65 { 66 67 uint8_t reg_spm_apsrc_req = (resource_usage & MT_SPM_DRAM_S0) ? 68 1 : pwrctrl->reg_spm_apsrc_req; 69 uint8_t reg_spm_ddr_en_req = (resource_usage & MT_SPM_DRAM_S1) ? 70 1 : pwrctrl->reg_spm_ddr_en_req; 71 uint8_t reg_spm_vrf18_req = (resource_usage & MT_SPM_SYSPLL) ? 72 1 : pwrctrl->reg_spm_vrf18_req; 73 uint8_t reg_spm_infra_req = (resource_usage & MT_SPM_INFRA) ? 74 1 : pwrctrl->reg_spm_infra_req; 75 uint8_t reg_spm_f26m_req = (resource_usage & (MT_SPM_26M | MT_SPM_XO_FPM)) ? 76 1 : pwrctrl->reg_spm_f26m_req; 77 78 /* SPM_SRC_REQ */ 79 mmio_write_32(SPM_SRC_REQ, 80 ((reg_spm_apsrc_req & 0x1) << 0) | 81 ((reg_spm_f26m_req & 0x1) << 1) | 82 ((reg_spm_infra_req & 0x1) << 3) | 83 ((reg_spm_vrf18_req & 0x1) << 4) | 84 ((reg_spm_ddr_en_req & 0x1) << 7) | 85 ((pwrctrl->reg_spm_dvfs_req & 0x1) << 8) | 86 ((pwrctrl->reg_spm_sw_mailbox_req & 0x1) << 9) | 87 ((pwrctrl->reg_spm_sspm_mailbox_req & 0x1) << 10) | 88 ((pwrctrl->reg_spm_adsp_mailbox_req & 0x1) << 11) | 89 ((pwrctrl->reg_spm_scp_mailbox_req & 0x1) << 12)); 90 } 91 92 void __spm_set_power_control(const struct pwr_ctrl *pwrctrl) 93 { 94 /* SPM_AP_STANDBY_CON */ 95 mmio_write_32(SPM_AP_STANDBY_CON, 96 ((pwrctrl->reg_wfi_op & 0x1) << 0) | 97 ((pwrctrl->reg_wfi_type & 0x1) << 1) | 98 ((pwrctrl->reg_mp0_cputop_idle_mask & 0x1) << 2) | 99 ((pwrctrl->reg_mp1_cputop_idle_mask & 0x1) << 3) | 100 ((pwrctrl->reg_mcusys_idle_mask & 0x1) << 4) | 101 ((pwrctrl->reg_md_apsrc_1_sel & 0x1) << 25) | 102 ((pwrctrl->reg_md_apsrc_0_sel & 0x1) << 26) | 103 ((pwrctrl->reg_conn_apsrc_sel & 0x1) << 29)); 104 105 /* SPM_SRC_REQ */ 106 mmio_write_32(SPM_SRC_REQ, 107 ((pwrctrl->reg_spm_apsrc_req & 0x1) << 0) | 108 ((pwrctrl->reg_spm_f26m_req & 0x1) << 1) | 109 ((pwrctrl->reg_spm_infra_req & 0x1) << 3) | 110 ((pwrctrl->reg_spm_vrf18_req & 0x1) << 4) | 111 ((pwrctrl->reg_spm_ddr_en_req & 0x1) << 7) | 112 ((pwrctrl->reg_spm_dvfs_req & 0x1) << 8) | 113 ((pwrctrl->reg_spm_sw_mailbox_req & 0x1) << 9) | 114 ((pwrctrl->reg_spm_sspm_mailbox_req & 0x1) << 10) | 115 ((pwrctrl->reg_spm_adsp_mailbox_req & 0x1) << 11) | 116 ((pwrctrl->reg_spm_scp_mailbox_req & 0x1) << 12)); 117 118 /* SPM_SRC_MASK */ 119 mmio_write_32(SPM_SRC_MASK, 120 ((pwrctrl->reg_sspm_srcclkena_0_mask_b & 0x1) << 0) | 121 ((pwrctrl->reg_sspm_infra_req_0_mask_b & 0x1) << 1) | 122 ((pwrctrl->reg_sspm_apsrc_req_0_mask_b & 0x1) << 2) | 123 ((pwrctrl->reg_sspm_vrf18_req_0_mask_b & 0x1) << 3) | 124 ((pwrctrl->reg_sspm_ddr_en_0_mask_b & 0x1) << 4) | 125 ((pwrctrl->reg_scp_srcclkena_mask_b & 0x1) << 5) | 126 ((pwrctrl->reg_scp_infra_req_mask_b & 0x1) << 6) | 127 ((pwrctrl->reg_scp_apsrc_req_mask_b & 0x1) << 7) | 128 ((pwrctrl->reg_scp_vrf18_req_mask_b & 0x1) << 8) | 129 ((pwrctrl->reg_scp_ddr_en_mask_b & 0x1) << 9) | 130 ((pwrctrl->reg_audio_dsp_srcclkena_mask_b & 0x1) << 10) | 131 ((pwrctrl->reg_audio_dsp_infra_req_mask_b & 0x1) << 11) | 132 ((pwrctrl->reg_audio_dsp_apsrc_req_mask_b & 0x1) << 12) | 133 ((pwrctrl->reg_audio_dsp_vrf18_req_mask_b & 0x1) << 13) | 134 ((pwrctrl->reg_audio_dsp_ddr_en_mask_b & 0x1) << 14) | 135 ((pwrctrl->reg_apu_srcclkena_mask_b & 0x1) << 15) | 136 ((pwrctrl->reg_apu_infra_req_mask_b & 0x1) << 16) | 137 ((pwrctrl->reg_apu_apsrc_req_mask_b & 0x1) << 17) | 138 ((pwrctrl->reg_apu_vrf18_req_mask_b & 0x1) << 18) | 139 ((pwrctrl->reg_apu_ddr_en_mask_b & 0x1) << 19) | 140 ((pwrctrl->reg_cpueb_srcclkena_mask_b & 0x1) << 20) | 141 ((pwrctrl->reg_cpueb_infra_req_mask_b & 0x1) << 21) | 142 ((pwrctrl->reg_cpueb_apsrc_req_mask_b & 0x1) << 22) | 143 ((pwrctrl->reg_cpueb_vrf18_req_mask_b & 0x1) << 23) | 144 ((pwrctrl->reg_cpueb_ddr_en_mask_b & 0x1) << 24) | 145 ((pwrctrl->reg_bak_psri_srcclkena_mask_b & 0x1) << 25) | 146 ((pwrctrl->reg_bak_psri_infra_req_mask_b & 0x1) << 26) | 147 ((pwrctrl->reg_bak_psri_apsrc_req_mask_b & 0x1) << 27) | 148 ((pwrctrl->reg_bak_psri_vrf18_req_mask_b & 0x1) << 28) | 149 ((pwrctrl->reg_bak_psri_ddr_en_mask_b & 0x1) << 29) | 150 ((pwrctrl->reg_cam_ddren_req_mask_b & 0x1) << 30) | 151 ((pwrctrl->reg_img_ddren_req_mask_b & 0x1) << 31)); 152 153 /* SPM_SRC2_MASK */ 154 mmio_write_32(SPM_SRC2_MASK, 155 ((pwrctrl->reg_msdc0_srcclkena_mask_b & 0x1) << 0) | 156 ((pwrctrl->reg_msdc0_infra_req_mask_b & 0x1) << 1) | 157 ((pwrctrl->reg_msdc0_apsrc_req_mask_b & 0x1) << 2) | 158 ((pwrctrl->reg_msdc0_vrf18_req_mask_b & 0x1) << 3) | 159 ((pwrctrl->reg_msdc0_ddr_en_mask_b & 0x1) << 4) | 160 ((pwrctrl->reg_msdc1_srcclkena_mask_b & 0x1) << 5) | 161 ((pwrctrl->reg_msdc1_infra_req_mask_b & 0x1) << 6) | 162 ((pwrctrl->reg_msdc1_apsrc_req_mask_b & 0x1) << 7) | 163 ((pwrctrl->reg_msdc1_vrf18_req_mask_b & 0x1) << 8) | 164 ((pwrctrl->reg_msdc1_ddr_en_mask_b & 0x1) << 9) | 165 ((pwrctrl->reg_msdc2_srcclkena_mask_b & 0x1) << 10) | 166 ((pwrctrl->reg_msdc2_infra_req_mask_b & 0x1) << 11) | 167 ((pwrctrl->reg_msdc2_apsrc_req_mask_b & 0x1) << 12) | 168 ((pwrctrl->reg_msdc2_vrf18_req_mask_b & 0x1) << 13) | 169 ((pwrctrl->reg_msdc2_ddr_en_mask_b & 0x1) << 14) | 170 ((pwrctrl->reg_ufs_srcclkena_mask_b & 0x1) << 15) | 171 ((pwrctrl->reg_ufs_infra_req_mask_b & 0x1) << 16) | 172 ((pwrctrl->reg_ufs_apsrc_req_mask_b & 0x1) << 17) | 173 ((pwrctrl->reg_ufs_vrf18_req_mask_b & 0x1) << 18) | 174 ((pwrctrl->reg_ufs_ddr_en_mask_b & 0x1) << 19) | 175 ((pwrctrl->reg_usb_srcclkena_mask_b & 0x1) << 20) | 176 ((pwrctrl->reg_usb_infra_req_mask_b & 0x1) << 21) | 177 ((pwrctrl->reg_usb_apsrc_req_mask_b & 0x1) << 22) | 178 ((pwrctrl->reg_usb_vrf18_req_mask_b & 0x1) << 23) | 179 ((pwrctrl->reg_usb_ddr_en_mask_b & 0x1) << 24) | 180 ((pwrctrl->reg_pextp_p0_srcclkena_mask_b & 0x1) << 25) | 181 ((pwrctrl->reg_pextp_p0_infra_req_mask_b & 0x1) << 26) | 182 ((pwrctrl->reg_pextp_p0_apsrc_req_mask_b & 0x1) << 27) | 183 ((pwrctrl->reg_pextp_p0_vrf18_req_mask_b & 0x1) << 28) | 184 ((pwrctrl->reg_pextp_p0_ddr_en_mask_b & 0x1) << 29)); 185 186 /* SPM_SRC3_MASK */ 187 mmio_write_32(SPM_SRC3_MASK, 188 ((pwrctrl->reg_pextp_p1_srcclkena_mask_b & 0x1) << 0) | 189 ((pwrctrl->reg_pextp_p1_infra_req_mask_b & 0x1) << 1) | 190 ((pwrctrl->reg_pextp_p1_apsrc_req_mask_b & 0x1) << 2) | 191 ((pwrctrl->reg_pextp_p1_vrf18_req_mask_b & 0x1) << 3) | 192 ((pwrctrl->reg_pextp_p1_ddr_en_mask_b & 0x1) << 4) | 193 ((pwrctrl->reg_gce0_infra_req_mask_b & 0x1) << 5) | 194 ((pwrctrl->reg_gce0_apsrc_req_mask_b & 0x1) << 6) | 195 ((pwrctrl->reg_gce0_vrf18_req_mask_b & 0x1) << 7) | 196 ((pwrctrl->reg_gce0_ddr_en_mask_b & 0x1) << 8) | 197 ((pwrctrl->reg_gce1_infra_req_mask_b & 0x1) << 9) | 198 ((pwrctrl->reg_gce1_apsrc_req_mask_b & 0x1) << 10) | 199 ((pwrctrl->reg_gce1_vrf18_req_mask_b & 0x1) << 11) | 200 ((pwrctrl->reg_gce1_ddr_en_mask_b & 0x1) << 12) | 201 ((pwrctrl->reg_spm_srcclkena_reserved_mask_b & 0x1) << 13) | 202 ((pwrctrl->reg_spm_infra_req_reserved_mask_b & 0x1) << 14) | 203 ((pwrctrl->reg_spm_apsrc_req_reserved_mask_b & 0x1) << 15) | 204 ((pwrctrl->reg_spm_vrf18_req_reserved_mask_b & 0x1) << 16) | 205 ((pwrctrl->reg_spm_ddr_en_reserved_mask_b & 0x1) << 17) | 206 ((pwrctrl->reg_disp0_ddr_en_mask_b & 0x1) << 18) | 207 ((pwrctrl->reg_disp0_ddr_en_mask_b & 0x1) << 19) | 208 ((pwrctrl->reg_disp1_apsrc_req_mask_b & 0x1) << 20) | 209 ((pwrctrl->reg_disp1_ddr_en_mask_b & 0x1) << 21) | 210 ((pwrctrl->reg_disp2_apsrc_req_mask_b & 0x1) << 22) | 211 ((pwrctrl->reg_disp2_ddr_en_mask_b & 0x1) << 23) | 212 ((pwrctrl->reg_disp3_apsrc_req_mask_b & 0x1) << 24) | 213 ((pwrctrl->reg_disp3_ddr_en_mask_b & 0x1) << 25) | 214 ((pwrctrl->reg_infrasys_apsrc_req_mask_b & 0x1) << 26) | 215 ((pwrctrl->reg_infrasys_ddr_en_mask_b & 0x1) << 27)); 216 217 /* SPM_SRC4_MASK */ 218 mmio_write_32(SPM_SRC4_MASK, 219 ((pwrctrl->reg_mcusys_merge_apsrc_req_mask_b & 0x1ff) << 0) | 220 ((pwrctrl->reg_mcusys_merge_ddr_en_mask_b & 0x1ff) << 9) | 221 ((pwrctrl->reg_dramc_md32_infra_req_mask_b & 0x3) << 18) | 222 ((pwrctrl->reg_dramc_md32_vrf18_req_mask_b & 0x3) << 20) | 223 ((pwrctrl->reg_dramc_md32_ddr_en_mask_b & 0x3) << 22) | 224 ((pwrctrl->reg_dvfsrc_event_trigger_mask_b & 0x1) << 24)); 225 226 /* SPM_WAKEUP_EVENT_MASK */ 227 mmio_write_32(SPM_WAKEUP_EVENT_MASK, 228 ((pwrctrl->reg_wakeup_event_mask & 0xffffffff) << 0)); 229 230 /* SPM_WAKEUP_EVENT_EXT_MASK */ 231 mmio_write_32(SPM_WAKEUP_EVENT_EXT_MASK, 232 ((pwrctrl->reg_ext_wakeup_event_mask & 0xffffffff) << 0)); 233 } 234 235 void __spm_set_wakeup_event(const struct pwr_ctrl *pwrctrl) 236 { 237 unsigned int val, mask; 238 239 /* toggle event counter clear */ 240 mmio_setbits_32(PCM_CON1, SPM_REGWR_CFG_KEY | SPM_EVENT_COUNTER_CLR_LSB); 241 /* toggle for reset SYS TIMER start point */ 242 mmio_setbits_32(SYS_TIMER_CON, SYS_TIMER_START_EN_LSB); 243 244 if (pwrctrl->timer_val_cust == 0U) { 245 val = (pwrctrl->timer_val != 0U) ? pwrctrl->timer_val : PCM_TIMER_MAX; 246 } else { 247 val = pwrctrl->timer_val_cust; 248 } 249 250 mmio_write_32(PCM_TIMER_VAL, val); 251 mmio_setbits_32(PCM_CON1, SPM_REGWR_CFG_KEY | RG_PCM_TIMER_EN_LSB); 252 253 /* unmask AP wakeup source */ 254 if (pwrctrl->wake_src_cust == 0U) { 255 mask = pwrctrl->wake_src; 256 } else { 257 mask = pwrctrl->wake_src_cust; 258 } 259 260 mmio_write_32(SPM_WAKEUP_EVENT_MASK, ~mask); 261 262 /* unmask SPM ISR (keep TWAM setting) */ 263 mmio_setbits_32(SPM_IRQ_MASK, ISRM_RET_IRQ_AUX); 264 265 /* toggle event counter clear */ 266 mmio_clrsetbits_32(PCM_CON1, SPM_EVENT_COUNTER_CLR_LSB, SPM_REGWR_CFG_KEY); 267 /* toggle for reset SYS TIMER start point */ 268 mmio_clrbits_32(SYS_TIMER_CON, SYS_TIMER_START_EN_LSB); 269 } 270 271 void __spm_set_pcm_flags(struct pwr_ctrl *pwrctrl) 272 { 273 /* set PCM flags and data */ 274 if (pwrctrl->pcm_flags_cust_clr != 0U) { 275 pwrctrl->pcm_flags &= ~pwrctrl->pcm_flags_cust_clr; 276 } 277 if (pwrctrl->pcm_flags_cust_set != 0U) { 278 pwrctrl->pcm_flags |= pwrctrl->pcm_flags_cust_set; 279 } 280 if (pwrctrl->pcm_flags1_cust_clr != 0U) { 281 pwrctrl->pcm_flags1 &= ~pwrctrl->pcm_flags1_cust_clr; 282 } 283 if (pwrctrl->pcm_flags1_cust_set != 0U) { 284 pwrctrl->pcm_flags1 |= pwrctrl->pcm_flags1_cust_set; 285 } 286 287 mmio_write_32(SPM_SW_FLAG_0, pwrctrl->pcm_flags); 288 289 mmio_write_32(SPM_SW_FLAG_1, pwrctrl->pcm_flags1); 290 291 mmio_write_32(SPM_SW_RSV_7, pwrctrl->pcm_flags); 292 293 mmio_write_32(SPM_SW_RSV_8, pwrctrl->pcm_flags1); 294 } 295 296 void __spm_get_wakeup_status(struct wake_status *wakesta, unsigned int ext_status) 297 { 298 /* get wakeup event */ 299 wakesta->tr.comm.r12 = mmio_read_32(SPM_BK_WAKE_EVENT); /* backup of PCM_REG12_DATA */ 300 wakesta->r12_ext = mmio_read_32(SPM_WAKEUP_EXT_STA); 301 wakesta->tr.comm.raw_sta = mmio_read_32(SPM_WAKEUP_STA); 302 wakesta->raw_ext_sta = mmio_read_32(SPM_WAKEUP_EXT_STA); 303 wakesta->md32pcm_wakeup_sta = mmio_read_32(MD32PCM_WAKEUP_STA); 304 wakesta->md32pcm_event_sta = mmio_read_32(MD32PCM_EVENT_STA); 305 wakesta->wake_misc = mmio_read_32(SPM_BK_WAKE_MISC); /* backup of SPM_WAKEUP_MISC */ 306 307 /* get sleep time */ 308 wakesta->tr.comm.timer_out = 309 mmio_read_32(SPM_BK_PCM_TIMER); /* backup of PCM_TIMER_OUT */ 310 311 /* get other SYS and co-clock status */ 312 wakesta->tr.comm.r13 = mmio_read_32(PCM_REG13_DATA); 313 wakesta->idle_sta = mmio_read_32(SUBSYS_IDLE_STA); 314 wakesta->tr.comm.req_sta0 = mmio_read_32(SRC_REQ_STA_0); 315 wakesta->tr.comm.req_sta1 = mmio_read_32(SRC_REQ_STA_1); 316 wakesta->tr.comm.req_sta2 = mmio_read_32(SRC_REQ_STA_2); 317 wakesta->tr.comm.req_sta3 = mmio_read_32(SRC_REQ_STA_3); 318 wakesta->tr.comm.req_sta4 = mmio_read_32(SRC_REQ_STA_4); 319 320 /* get debug flag for PCM execution check */ 321 wakesta->tr.comm.debug_flag = mmio_read_32(PCM_WDT_LATCH_SPARE_0); 322 wakesta->tr.comm.debug_flag1 = mmio_read_32(PCM_WDT_LATCH_SPARE_1); 323 324 if ((ext_status & SPM_INTERNAL_STATUS_HW_S1) != 0U) { 325 wakesta->tr.comm.debug_flag |= (SPM_DBG_DEBUG_IDX_DDREN_WAKE | 326 SPM_DBG_DEBUG_IDX_DDREN_SLEEP); 327 mmio_write_32(PCM_WDT_LATCH_SPARE_0, wakesta->tr.comm.debug_flag); 328 } 329 330 /* get backup SW flag status */ 331 wakesta->tr.comm.b_sw_flag0 = mmio_read_32(SPM_SW_RSV_7); /* SPM_SW_RSV_7 */ 332 wakesta->tr.comm.b_sw_flag1 = mmio_read_32(SPM_SW_RSV_8); /* SPM_SW_RSV_8 */ 333 334 /* get ISR status */ 335 wakesta->isr = mmio_read_32(SPM_IRQ_STA); 336 337 /* get SW flag status */ 338 wakesta->sw_flag0 = mmio_read_32(SPM_SW_FLAG_0); 339 wakesta->sw_flag1 = mmio_read_32(SPM_SW_FLAG_1); 340 341 /* check abort */ 342 wakesta->is_abort = wakesta->tr.comm.debug_flag & DEBUG_ABORT_MASK; 343 wakesta->is_abort |= wakesta->tr.comm.debug_flag1 & DEBUG_ABORT_MASK_1; 344 } 345 346 void __spm_clean_after_wakeup(void) 347 { 348 /* 349 * Copy SPM_WAKEUP_STA to SPM_BK_WAKE_EVENT before clear SPM_WAKEUP_STA 350 * 351 * CPU dormant driver @kernel will copy edge-trig IRQ pending 352 * (recorded @SPM_BK_WAKE_EVENT) to GIC 353 */ 354 mmio_write_32(SPM_BK_WAKE_EVENT, mmio_read_32(SPM_WAKEUP_STA) | 355 mmio_read_32(SPM_BK_WAKE_EVENT)); 356 357 /* clean CPU wakeup event */ 358 mmio_write_32(SPM_CPU_WAKEUP_EVENT, 0U); 359 360 /* clean wakeup event raw status (for edge trigger event) */ 361 mmio_write_32(SPM_WAKEUP_EVENT_MASK, 0xefffffff); /* bit[28] for cpu wake up event */ 362 363 /* clean ISR status (except TWAM) */ 364 mmio_setbits_32(SPM_IRQ_MASK, ISRM_ALL_EXC_TWAM); 365 mmio_write_32(SPM_IRQ_STA, ISRC_ALL_EXC_TWAM); 366 mmio_write_32(SPM_SWINT_CLR, PCM_SW_INT_ALL); 367 } 368 369 void __spm_set_pcm_wdt(int en) 370 { 371 /* enable PCM WDT (normal mode) to start count if needed */ 372 if (en != 0) { 373 mmio_clrsetbits_32(PCM_CON1, RG_PCM_WDT_WAKE_LSB, SPM_REGWR_CFG_KEY); 374 375 if (mmio_read_32(PCM_TIMER_VAL) > PCM_TIMER_MAX) { 376 mmio_write_32(PCM_TIMER_VAL, PCM_TIMER_MAX); 377 } 378 mmio_write_32(PCM_WDT_VAL, mmio_read_32(PCM_TIMER_VAL) + PCM_WDT_TIMEOUT); 379 mmio_setbits_32(PCM_CON1, SPM_REGWR_CFG_KEY | RG_PCM_WDT_EN_LSB); 380 } else { 381 mmio_clrsetbits_32(PCM_CON1, RG_PCM_WDT_EN_LSB, SPM_REGWR_CFG_KEY); 382 } 383 } 384 385 void __spm_send_cpu_wakeup_event(void) 386 { 387 mmio_write_32(SPM_CPU_WAKEUP_EVENT, 1); 388 /* SPM will clear SPM_CPU_WAKEUP_EVENT */ 389 } 390 391 void __spm_ext_int_wakeup_req_clr(void) 392 { 393 mmio_write_32(EXT_INT_WAKEUP_REQ_CLR, mmio_read_32(ROOT_CPUTOP_ADDR)); 394 395 /* clear spm2mcupm wakeup interrupt status */ 396 mmio_write_32(SPM2CPUEB_CON, 0); 397 } 398 399 void __spm_clean_before_wfi(void) 400 { 401 } 402 403 void __spm_hw_s1_state_monitor(int en, unsigned int *status) 404 { 405 unsigned int reg; 406 407 if (en != 0) { 408 mmio_clrsetbits_32(SPM_ACK_CHK_CON_3, SPM_ACK_CHK_3_CON_CLR_ALL, 409 SPM_ACK_CHK_3_CON_EN); 410 } else { 411 reg = mmio_read_32(SPM_ACK_CHK_CON_3); 412 413 if ((reg & SPM_ACK_CHK_3_CON_RESULT) != 0U) { 414 if (status != NULL) { 415 *status |= SPM_INTERNAL_STATUS_HW_S1; 416 } 417 } 418 419 mmio_clrsetbits_32(SPM_ACK_CHK_CON_3, SPM_ACK_CHK_3_CON_EN, 420 (SPM_ACK_CHK_3_CON_HW_MODE_TRIG | SPM_ACK_CHK_3_CON_CLR_ALL)); 421 } 422 } 423