xref: /rk3399_ARM-atf/plat/mediatek/drivers/spm/mt8189/mt_spm_suspend.c (revision d57362bd92c2e5c8a1222fd763e24163c1234938)
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