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