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