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