1 /* 2 * Copyright (c) 2025, Mediatek Inc. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <stdint.h> 8 #include <stdio.h> 9 10 #include <common/debug.h> 11 #include <lib/mmio.h> 12 13 #include <constraints/mt_spm_rc_internal.h> 14 #include <drivers/spm/mt_spm_resource_req.h> 15 #include <lib/pm/mtk_pm.h> 16 #include <lpm_v2/mt_lp_api.h> 17 #include <lpm_v2/mt_lp_rqm.h> 18 #include <mt_spm.h> 19 #include <mt_spm_conservation.h> 20 #include <mt_spm_internal.h> 21 #include <mt_spm_reg.h> 22 #include <mt_spm_stats.h> 23 #include <mt_spm_suspend.h> 24 #if defined(CONFIG_MTK_VCOREDVFS_SUPPORT) 25 #include <mt_spm_vcorefs_exp.h> 26 #endif 27 28 #define SPM_SUSPEND_SLEEP_PCM_FLAG \ 29 (SPM_FLAG_DISABLE_INFRA_PDN | SPM_FLAG_DISABLE_DPM_PDN | \ 30 SPM_FLAG_DISABLE_MCUPM_PDN | SPM_FLAG_DISABLE_VCORE_DVS | \ 31 SPM_FLAG_DISABLE_DDR_DFS | SPM_FLAG_DISABLE_EMI_DFS | \ 32 SPM_FLAG_DISABLE_BUS_DFS | SPM_FLAG_KEEP_CSYSPWRACK_HIGH | \ 33 SPM_FLAG_SRAM_SLEEP_CTRL) 34 35 #define SPM_SUSPEND_SLEEP_PCM_FLAG1 (SPM_FLAG1_ENABLE_VS2_VS3_VOTER) 36 37 #define SPM_SUSPEND_PCM_FLAG \ 38 (SPM_FLAG_DISABLE_VCORE_DVS | SPM_FLAG_DISABLE_DDR_DFS | \ 39 SPM_FLAG_DISABLE_EMI_DFS | SPM_FLAG_DISABLE_BUS_DFS | \ 40 SPM_FLAG_SRAM_SLEEP_CTRL) 41 42 #define SPM_SUSPEND_PCM_FLAG1 (SPM_FLAG1_ENABLE_VS2_VS3_VOTER) 43 44 /* Suspend spm power control */ 45 #define __WAKE_SRC_FOR_SUSPEND_COMMON__ \ 46 ((R12_PCM_TIMER_B) | (R12_KP_IRQ_B) | (R12_CONN2AP_WAKEUP_B) | \ 47 (R12_EINT_EVENT_B) | (R12_CONN_WDT_IRQ_B) | (R12_SSPM2SPM_WAKEUP_B) | \ 48 (R12_SCP2SPM_WAKEUP_B) | (R12_VADSP2SPM_WAKEUP_B) | \ 49 (R12_USB0_CDSC_B) | (R12_USB0_POWERDWN_B) | (R12_SBD_INTR_B) | \ 50 (R12_UART2SPM_IRQ_B) | (R12_SYS_TIMER_EVENT_B) | \ 51 (R12_EINT_EVENT_SECURE_B) | (R12_SYS_CIRQ_IRQ_B) | (R12_CPU_WAKEUP) | \ 52 (R12_APUSYS_WAKE_HOST_B) | (R12_PCIE_MAC_IRQ_WAKE_B) | \ 53 (R12_MSDC_WAKEUP_EVENT_B)) 54 55 #if defined(CFG_MICROTRUST_TEE_SUPPORT) 56 #define WAKE_SRC_FOR_SUSPEND (__WAKE_SRC_FOR_SUSPEND_COMMON__) 57 #else 58 #define WAKE_SRC_FOR_SUSPEND (__WAKE_SRC_FOR_SUSPEND_COMMON__ | R12_SEJ_B) 59 #endif 60 61 static struct pwr_ctrl suspend_ctrl = { 62 .wake_src = WAKE_SRC_FOR_SUSPEND, 63 64 /* Auto-gen Start */ 65 66 /* SPM_SRC_REQ */ 67 .reg_spm_adsp_mailbox_req = 0, 68 .reg_spm_apsrc_req = 0, 69 .reg_spm_ddren_req = 0, 70 .reg_spm_dvfs_req = 0, 71 .reg_spm_emi_req = 0, 72 .reg_spm_f26m_req = 0, 73 .reg_spm_infra_req = 0, 74 .reg_spm_pmic_req = 0, 75 .reg_spm_scp_mailbox_req = 0, 76 .reg_spm_sspm_mailbox_req = 0, 77 .reg_spm_sw_mailbox_req = 0, 78 .reg_spm_vcore_req = 0, 79 .reg_spm_vrf18_req = 0, 80 .adsp_mailbox_state = 0, 81 .apsrc_state = 0, 82 .ddren_state = 0, 83 .dvfs_state = 0, 84 .emi_state = 0, 85 .f26m_state = 0, 86 .infra_state = 0, 87 .pmic_state = 0, 88 .scp_mailbox_state = 0, 89 .sspm_mailbox_state = 0, 90 .sw_mailbox_state = 0, 91 .vcore_state = 0, 92 .vrf18_state = 0, 93 94 /* SPM_SRC_MASK_0 */ 95 .reg_apu_apsrc_req_mask_b = 0x1, 96 .reg_apu_ddren_req_mask_b = 0x1, 97 .reg_apu_emi_req_mask_b = 0x1, 98 .reg_apu_infra_req_mask_b = 0x1, 99 .reg_apu_pmic_req_mask_b = 0x1, 100 .reg_apu_srcclkena_mask_b = 0x1, 101 .reg_apu_vrf18_req_mask_b = 0x1, 102 .reg_audio_dsp_apsrc_req_mask_b = 0x0, 103 .reg_audio_dsp_ddren_req_mask_b = 0x0, 104 .reg_audio_dsp_emi_req_mask_b = 0x0, 105 .reg_audio_dsp_infra_req_mask_b = 0x0, 106 .reg_audio_dsp_pmic_req_mask_b = 0x0, 107 .reg_audio_dsp_srcclkena_mask_b = 0x0, 108 .reg_audio_dsp_vcore_req_mask_b = 0x0, 109 .reg_audio_dsp_vrf18_req_mask_b = 0x0, 110 .reg_cam_apsrc_req_mask_b = 0x1, 111 .reg_cam_ddren_req_mask_b = 0x1, 112 .reg_cam_emi_req_mask_b = 0x1, 113 .reg_cam_infra_req_mask_b = 0x0, 114 .reg_cam_pmic_req_mask_b = 0x0, 115 .reg_cam_srcclkena_mask_b = 0x0, 116 .reg_cam_vrf18_req_mask_b = 0x0, 117 .reg_mdp_emi_req_mask_b = 0x1, 118 119 /* SPM_SRC_MASK_1 */ 120 .reg_ccif_apsrc_req_mask_b = 0x0, 121 .reg_ccif_emi_req_mask_b = 0xfff, 122 123 /* SPM_SRC_MASK_2 */ 124 .reg_ccif_infra_req_mask_b = 0x0, 125 .reg_ccif_pmic_req_mask_b = 0xfff, 126 127 /* SPM_SRC_MASK_3 */ 128 .reg_ccif_srcclkena_mask_b = 0x0, 129 .reg_ccif_vrf18_req_mask_b = 0xfff, 130 .reg_ccu_apsrc_req_mask_b = 0x0, 131 .reg_ccu_ddren_req_mask_b = 0x0, 132 .reg_ccu_emi_req_mask_b = 0x0, 133 .reg_ccu_infra_req_mask_b = 0x0, 134 .reg_ccu_pmic_req_mask_b = 0x0, 135 .reg_ccu_srcclkena_mask_b = 0x0, 136 .reg_ccu_vrf18_req_mask_b = 0x0, 137 .reg_cg_check_apsrc_req_mask_b = 0x1, 138 139 /* SPM_SRC_MASK_4 */ 140 .reg_cg_check_ddren_req_mask_b = 0x1, 141 .reg_cg_check_emi_req_mask_b = 0x1, 142 .reg_cg_check_infra_req_mask_b = 0x1, 143 .reg_cg_check_pmic_req_mask_b = 0x1, 144 .reg_cg_check_srcclkena_mask_b = 0x1, 145 .reg_cg_check_vcore_req_mask_b = 0x1, 146 .reg_cg_check_vrf18_req_mask_b = 0x1, 147 .reg_conn_apsrc_req_mask_b = 0x1, 148 .reg_conn_ddren_req_mask_b = 0x1, 149 .reg_conn_emi_req_mask_b = 0x1, 150 .reg_conn_infra_req_mask_b = 0x1, 151 .reg_conn_pmic_req_mask_b = 0x1, 152 .reg_conn_srcclkena_mask_b = 0x1, 153 .reg_conn_srcclkenb_mask_b = 0x1, 154 .reg_conn_vcore_req_mask_b = 0x1, 155 .reg_conn_vrf18_req_mask_b = 0x1, 156 .reg_cpueb_apsrc_req_mask_b = 0x1, 157 .reg_cpueb_ddren_req_mask_b = 0x1, 158 .reg_cpueb_emi_req_mask_b = 0x1, 159 .reg_cpueb_infra_req_mask_b = 0x1, 160 .reg_cpueb_pmic_req_mask_b = 0x1, 161 .reg_cpueb_srcclkena_mask_b = 0x1, 162 .reg_cpueb_vrf18_req_mask_b = 0x1, 163 .reg_disp0_apsrc_req_mask_b = 0x1, 164 .reg_disp0_ddren_req_mask_b = 0x1, 165 .reg_disp0_emi_req_mask_b = 0x1, 166 .reg_disp0_infra_req_mask_b = 0x1, 167 .reg_disp0_pmic_req_mask_b = 0x0, 168 .reg_disp0_srcclkena_mask_b = 0x0, 169 .reg_disp0_vrf18_req_mask_b = 0x1, 170 .reg_disp1_apsrc_req_mask_b = 0x0, 171 .reg_disp1_ddren_req_mask_b = 0x0, 172 173 /* SPM_SRC_MASK_5 */ 174 .reg_disp1_emi_req_mask_b = 0x0, 175 .reg_disp1_infra_req_mask_b = 0x0, 176 .reg_disp1_pmic_req_mask_b = 0x0, 177 .reg_disp1_srcclkena_mask_b = 0x0, 178 .reg_disp1_vrf18_req_mask_b = 0x0, 179 .reg_dpm_apsrc_req_mask_b = 0xf, 180 .reg_dpm_ddren_req_mask_b = 0xf, 181 .reg_dpm_emi_req_mask_b = 0xf, 182 .reg_dpm_infra_req_mask_b = 0xf, 183 .reg_dpm_pmic_req_mask_b = 0xf, 184 .reg_dpm_srcclkena_mask_b = 0xf, 185 186 /* SPM_SRC_MASK_6 */ 187 .reg_dpm_vcore_req_mask_b = 0xf, 188 .reg_dpm_vrf18_req_mask_b = 0xf, 189 .reg_dpmaif_apsrc_req_mask_b = 0x1, 190 .reg_dpmaif_ddren_req_mask_b = 0x1, 191 .reg_dpmaif_emi_req_mask_b = 0x1, 192 .reg_dpmaif_infra_req_mask_b = 0x1, 193 .reg_dpmaif_pmic_req_mask_b = 0x1, 194 .reg_dpmaif_srcclkena_mask_b = 0x1, 195 .reg_dpmaif_vrf18_req_mask_b = 0x1, 196 .reg_dvfsrc_level_req_mask_b = 0x1, 197 .reg_emisys_apsrc_req_mask_b = 0x0, 198 .reg_emisys_ddren_req_mask_b = 0x1, 199 .reg_emisys_emi_req_mask_b = 0x0, 200 .reg_gce_d_apsrc_req_mask_b = 0x1, 201 .reg_gce_d_ddren_req_mask_b = 0x1, 202 .reg_gce_d_emi_req_mask_b = 0x1, 203 .reg_gce_d_infra_req_mask_b = 0x0, 204 .reg_gce_d_pmic_req_mask_b = 0x0, 205 .reg_gce_d_srcclkena_mask_b = 0x0, 206 .reg_gce_d_vrf18_req_mask_b = 0x0, 207 .reg_gce_m_apsrc_req_mask_b = 0x1, 208 .reg_gce_m_ddren_req_mask_b = 0x1, 209 .reg_gce_m_emi_req_mask_b = 0x1, 210 .reg_gce_m_infra_req_mask_b = 0x0, 211 .reg_gce_m_pmic_req_mask_b = 0x0, 212 .reg_gce_m_srcclkena_mask_b = 0x0, 213 214 /* SPM_SRC_MASK_7 */ 215 .reg_gce_m_vrf18_req_mask_b = 0x0, 216 .reg_gpueb_apsrc_req_mask_b = 0x0, 217 .reg_gpueb_ddren_req_mask_b = 0x0, 218 .reg_gpueb_emi_req_mask_b = 0x0, 219 .reg_gpueb_infra_req_mask_b = 0x0, 220 .reg_gpueb_pmic_req_mask_b = 0x0, 221 .reg_gpueb_srcclkena_mask_b = 0x0, 222 .reg_gpueb_vrf18_req_mask_b = 0x0, 223 .reg_hwccf_apsrc_req_mask_b = 0x1, 224 .reg_hwccf_ddren_req_mask_b = 0x1, 225 .reg_hwccf_emi_req_mask_b = 0x1, 226 .reg_hwccf_infra_req_mask_b = 0x1, 227 .reg_hwccf_pmic_req_mask_b = 0x1, 228 .reg_hwccf_srcclkena_mask_b = 0x1, 229 .reg_hwccf_vcore_req_mask_b = 0x1, 230 .reg_hwccf_vrf18_req_mask_b = 0x1, 231 .reg_img_apsrc_req_mask_b = 0x1, 232 .reg_img_ddren_req_mask_b = 0x1, 233 .reg_img_emi_req_mask_b = 0x1, 234 .reg_img_infra_req_mask_b = 0x0, 235 .reg_img_pmic_req_mask_b = 0x0, 236 .reg_img_srcclkena_mask_b = 0x0, 237 .reg_img_vrf18_req_mask_b = 0x0, 238 .reg_infrasys_apsrc_req_mask_b = 0x1, 239 .reg_infrasys_ddren_req_mask_b = 0x1, 240 .reg_infrasys_emi_req_mask_b = 0x1, 241 .reg_ipic_infra_req_mask_b = 0x1, 242 .reg_ipic_vrf18_req_mask_b = 0x1, 243 .reg_mcu_apsrc_req_mask_b = 0x0, 244 .reg_mcu_ddren_req_mask_b = 0x0, 245 .reg_mcu_emi_req_mask_b = 0x0, 246 247 /* SPM_SRC_MASK_8 */ 248 .reg_mcusys_apsrc_req_mask_b = 0x7, 249 .reg_mcusys_ddren_req_mask_b = 0x7, 250 .reg_mcusys_emi_req_mask_b = 0x7, 251 .reg_mcusys_infra_req_mask_b = 0x0, 252 253 /* SPM_SRC_MASK_9 */ 254 .reg_mcusys_pmic_req_mask_b = 0x0, 255 .reg_mcusys_srcclkena_mask_b = 0x0, 256 .reg_mcusys_vrf18_req_mask_b = 0x0, 257 .reg_md_apsrc_req_mask_b = 0x0, 258 .reg_md_ddren_req_mask_b = 0x0, 259 .reg_md_emi_req_mask_b = 0x0, 260 .reg_md_infra_req_mask_b = 0x0, 261 .reg_md_pmic_req_mask_b = 0x0, 262 .reg_md_srcclkena_mask_b = 0x0, 263 .reg_md_srcclkena1_mask_b = 0x0, 264 .reg_md_vcore_req_mask_b = 0x0, 265 266 /* SPM_SRC_MASK_10 */ 267 .reg_md_vrf18_req_mask_b = 0x0, 268 .reg_mdp_apsrc_req_mask_b = 0x0, 269 .reg_mdp_ddren_req_mask_b = 0x0, 270 .reg_mm_proc_apsrc_req_mask_b = 0x0, 271 .reg_mm_proc_ddren_req_mask_b = 0x0, 272 .reg_mm_proc_emi_req_mask_b = 0x0, 273 .reg_mm_proc_infra_req_mask_b = 0x0, 274 .reg_mm_proc_pmic_req_mask_b = 0x0, 275 .reg_mm_proc_srcclkena_mask_b = 0x0, 276 .reg_mm_proc_vrf18_req_mask_b = 0x0, 277 .reg_mmsys_apsrc_req_mask_b = 0x0, 278 .reg_mmsys_ddren_req_mask_b = 0x0, 279 .reg_mmsys_vrf18_req_mask_b = 0x0, 280 .reg_pcie0_apsrc_req_mask_b = 0x0, 281 .reg_pcie0_ddren_req_mask_b = 0x0, 282 .reg_pcie0_infra_req_mask_b = 0x0, 283 .reg_pcie0_srcclkena_mask_b = 0x0, 284 .reg_pcie0_vrf18_req_mask_b = 0x0, 285 .reg_pcie1_apsrc_req_mask_b = 0x0, 286 .reg_pcie1_ddren_req_mask_b = 0x0, 287 .reg_pcie1_infra_req_mask_b = 0x0, 288 .reg_pcie1_srcclkena_mask_b = 0x0, 289 .reg_pcie1_vrf18_req_mask_b = 0x0, 290 .reg_perisys_apsrc_req_mask_b = 0x1, 291 .reg_perisys_ddren_req_mask_b = 0x1, 292 .reg_perisys_emi_req_mask_b = 0x1, 293 .reg_perisys_infra_req_mask_b = 0x1, 294 .reg_perisys_pmic_req_mask_b = 0x1, 295 .reg_perisys_srcclkena_mask_b = 0x1, 296 .reg_perisys_vcore_req_mask_b = 0x1, 297 .reg_perisys_vrf18_req_mask_b = 0x1, 298 .reg_scp_apsrc_req_mask_b = 0x1, 299 300 /* SPM_SRC_MASK_11 */ 301 .reg_scp_ddren_req_mask_b = 0x1, 302 .reg_scp_emi_req_mask_b = 0x1, 303 .reg_scp_infra_req_mask_b = 0x1, 304 .reg_scp_pmic_req_mask_b = 0x1, 305 .reg_scp_srcclkena_mask_b = 0x1, 306 .reg_scp_vcore_req_mask_b = 0x1, 307 .reg_scp_vrf18_req_mask_b = 0x1, 308 .reg_srcclkeni_infra_req_mask_b = 0x1, 309 .reg_srcclkeni_pmic_req_mask_b = 0x1, 310 .reg_srcclkeni_srcclkena_mask_b = 0x1, 311 .reg_sspm_apsrc_req_mask_b = 0x1, 312 .reg_sspm_ddren_req_mask_b = 0x1, 313 .reg_sspm_emi_req_mask_b = 0x1, 314 .reg_sspm_infra_req_mask_b = 0x1, 315 .reg_sspm_pmic_req_mask_b = 0x1, 316 .reg_sspm_srcclkena_mask_b = 0x1, 317 .reg_sspm_vrf18_req_mask_b = 0x1, 318 .reg_ssr_apsrc_req_mask_b = 0x0, 319 .reg_ssr_ddren_req_mask_b = 0x0, 320 .reg_ssr_emi_req_mask_b = 0x0, 321 .reg_ssr_infra_req_mask_b = 0x0, 322 .reg_ssr_pmic_req_mask_b = 0x0, 323 .reg_ssr_srcclkena_mask_b = 0x0, 324 .reg_ssr_vrf18_req_mask_b = 0x0, 325 .reg_ufs_apsrc_req_mask_b = 0x1, 326 .reg_ufs_ddren_req_mask_b = 0x1, 327 .reg_ufs_emi_req_mask_b = 0x1, 328 .reg_ufs_infra_req_mask_b = 0x1, 329 .reg_ufs_pmic_req_mask_b = 0x1, 330 331 /* SPM_SRC_MASK_12 */ 332 .reg_ufs_srcclkena_mask_b = 0x1, 333 .reg_ufs_vrf18_req_mask_b = 0x1, 334 .reg_vdec_apsrc_req_mask_b = 0x1, 335 .reg_vdec_ddren_req_mask_b = 0x1, 336 .reg_vdec_emi_req_mask_b = 0x1, 337 .reg_vdec_infra_req_mask_b = 0x0, 338 .reg_vdec_pmic_req_mask_b = 0x0, 339 .reg_vdec_srcclkena_mask_b = 0x0, 340 .reg_vdec_vrf18_req_mask_b = 0x0, 341 .reg_venc_apsrc_req_mask_b = 0x1, 342 .reg_venc_ddren_req_mask_b = 0x1, 343 .reg_venc_emi_req_mask_b = 0x1, 344 .reg_venc_infra_req_mask_b = 0x0, 345 .reg_venc_pmic_req_mask_b = 0x0, 346 .reg_venc_srcclkena_mask_b = 0x0, 347 .reg_venc_vrf18_req_mask_b = 0x0, 348 .reg_ipe_apsrc_req_mask_b = 0x1, 349 .reg_ipe_ddren_req_mask_b = 0x1, 350 .reg_ipe_emi_req_mask_b = 0x1, 351 .reg_ipe_infra_req_mask_b = 0x1, 352 .reg_ipe_pmic_req_mask_b = 0x1, 353 .reg_ipe_srcclkena_mask_b = 0x1, 354 .reg_ipe_vrf18_req_mask_b = 0x1, 355 .reg_ufs_vcore_req_mask_b = 0x1, 356 357 /* SPM_EVENT_CON_MISC */ 358 .reg_srcclken_fast_resp = 0, 359 .reg_csyspwrup_ack_mask = 1, 360 361 /* Auto-gen End */ 362 363 /* SPM_WAKEUP_EVENT_MASK */ 364 .reg_wakeup_event_mask = 0xC1B33012, 365 366 /* SPM_WAKEUP_EVENT_EXT_MASK */ 367 .reg_ext_wakeup_event_mask = 0xFFFFFFFF, 368 369 /*sw flag setting */ 370 .pcm_flags = SPM_SUSPEND_PCM_FLAG, 371 .pcm_flags1 = SPM_SUSPEND_PCM_FLAG1, 372 }; 373 374 static struct suspend_dbg_ctrl suspend_spm_dbg_ext = { 375 .sleep_suspend_cnt = 0, 376 }; 377 378 static struct dbg_ctrl suspend_spm_dbg = { 379 .count = 0, 380 .duration = 0, 381 .ext = &suspend_spm_dbg_ext, 382 }; 383 384 static struct spm_lp_stat suspend_lp_stat; 385 386 struct spm_lp_scen __spm_suspend = { 387 .pwrctrl = &suspend_ctrl, 388 .dbgctrl = &suspend_spm_dbg, 389 .lpstat = &suspend_lp_stat, 390 }; 391 392 static uint8_t bak_spm_vcore_req; 393 394 int mt_spm_suspend_mode_set(enum mt_spm_suspend_mode mode, void *prv) 395 { 396 if (mode == MT_SPM_SUSPEND_SLEEP) { 397 suspend_ctrl.pcm_flags = SPM_SUSPEND_SLEEP_PCM_FLAG; 398 suspend_ctrl.pcm_flags1 = SPM_SUSPEND_SLEEP_PCM_FLAG1; 399 suspend_ctrl.reg_spm_vcore_req = 1; /* disable AOC */ 400 } else { 401 suspend_ctrl.pcm_flags = SPM_SUSPEND_PCM_FLAG; 402 suspend_ctrl.pcm_flags1 = SPM_SUSPEND_PCM_FLAG1; 403 } 404 return 0; 405 } 406 407 int mt_spm_suspend_enter(int state_id, uint32_t ext_opand, 408 uint32_t resource_req) 409 { 410 int ret = 0; 411 412 bak_spm_vcore_req = suspend_ctrl.reg_spm_vcore_req; 413 414 /* if FMAudio, ADSP, USB headset is active, change to sleep suspend mode */ 415 if (ext_opand & MT_SPM_EX_OP_SET_SUSPEND_MODE) 416 mt_spm_suspend_mode_set(MT_SPM_SUSPEND_SLEEP, NULL); 417 418 mmio_write_32(SPM2SW_MAILBOX_0, 0x1); 419 420 ext_opand |= MT_SPM_EX_OP_DEVICES_SAVE; 421 422 #if defined(CONFIG_MTK_VCOREDVFS_SUPPORT) 423 /* Notify vcoredvfs suspend enter */ 424 spm_vcorefs_plat_suspend(); 425 #endif 426 427 ret = spm_conservation(state_id, ext_opand, &__spm_suspend, 428 resource_req); 429 if (ret == 0) { 430 struct mt_lp_publish_event event = { 431 .id = MT_LPM_PUBEVENTS_SYS_POWER_OFF, 432 .val.u32 = 0, 433 .level = MT_LP_SYSPOWER_LEVEL_SUSPEND, 434 }; 435 436 MT_LP_SUSPEND_PUBLISH_EVENT(&event); 437 } 438 return ret; 439 } 440 441 void mt_spm_suspend_resume(int state_id, uint32_t ext_opand, 442 struct wake_status **status) 443 { 444 struct mt_lp_publish_event event; 445 struct wake_status *st = NULL; 446 447 ext_opand |= MT_SPM_EX_OP_DEVICES_SAVE; 448 449 spm_conservation_finish(state_id, ext_opand, &__spm_suspend, &st); 450 451 mt_spm_update_lp_stat(&suspend_lp_stat); 452 #if defined(CONFIG_MTK_VCOREDVFS_SUPPORT) 453 /* Notify vcoredvfs suspend enter */ 454 spm_vcorefs_plat_resume(); 455 mmio_write_32(SPM2SW_MAILBOX_0, 0x0); 456 #endif 457 458 /***************************************** 459 * if FMAudio, ADSP, USB headset is active, 460 * change back to suspend mode and counting in resume 461 *****************************************/ 462 463 if (ext_opand & MT_SPM_EX_OP_SET_SUSPEND_MODE) { 464 mt_spm_suspend_mode_set(MT_SPM_SUSPEND_SYSTEM_PDN, NULL); 465 suspend_spm_dbg_ext.sleep_suspend_cnt += 1; 466 } 467 468 suspend_ctrl.reg_spm_vcore_req = bak_spm_vcore_req; 469 470 suspend_spm_dbg.count += 1; 471 event.id = MT_LPM_PUBEVENTS_SYS_POWER_ON; 472 event.val.u32 = 0; 473 event.level = MT_LP_SYSPOWER_LEVEL_SUSPEND; 474 475 if (st) { 476 if (st->tr.comm.r12 & R12_AP2AP_PEER_WAKEUP_B) 477 event.val.u32 = MT_LPM_WAKE_MD_WAKEUP_DPMAIF; 478 if (st->tr.comm.r12 & R12_CCIF0_EVENT_B) 479 event.val.u32 = MT_LPM_WAKE_MD_WAKEUP_CCIF0; 480 if (st->tr.comm.r12 & R12_CCIF1_EVENT_B) 481 event.val.u32 = MT_LPM_WAKE_MD_WAKEUP_CCIF1; 482 } 483 if (status) 484 *status = st; 485 MT_LP_SUSPEND_PUBLISH_EVENT(&event); 486 } 487 488 int mt_spm_suspend_get_spm_lp(struct spm_lp_scen **lp) 489 { 490 if (!lp) 491 return -1; 492 493 *lp = &__spm_suspend; 494 return 0; 495 } 496