xref: /rk3399_ARM-atf/plat/mediatek/drivers/spm/mt8196/mt_spm_suspend.c (revision b47dddd061e92054c3b2096fc8aa9688bfef68d6)
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/delay_timer.h>
12 #include <drivers/gpio.h>
13 #include <lib/mmio.h>
14 
15 #include <constraints/mt_spm_rc_internal.h>
16 #include <drivers/spm/mt_spm_resource_req.h>
17 #include <lib/pm/mtk_pm.h>
18 #include <lpm_v2/mt_lp_api.h>
19 #include <lpm_v2/mt_lp_rqm.h>
20 #include <mt_spm.h>
21 #include <mt_spm_conservation.h>
22 #include <mt_spm_internal.h>
23 #include <mt_spm_reg.h>
24 #include <mt_spm_stats.h>
25 #include <mt_spm_suspend.h>
26 #if defined(CONFIG_MTK_VCOREDVFS_SUPPORT)
27 #include <mt_spm_vcorefs_exp.h>
28 #endif
29 
30 #define SPM_SUSPEND_SLEEP_PCM_FLAG	(SPM_FLAG_DISABLE_DDR_DFS | \
31 					 SPM_FLAG_DISABLE_EMI_DFS | \
32 					 SPM_FLAG_DISABLE_VLP_PDN | \
33 					 SPM_FLAG_DISABLE_BUS_DFS | \
34 					 SPM_FLAG_KEEP_CSYSPWRACK_HIGH | \
35 					 SPM_FLAG_ENABLE_AOV | \
36 					 SPM_FLAG_ENABLE_MD_MUMTAS | \
37 					 SPM_FLAG_SRAM_SLEEP_CTRL)
38 
39 #define SPM_SUSPEND_SLEEP_PCM_FLAG1	(SPM_FLAG1_ENABLE_ALCO_TRACE | \
40 					 SPM_FLAG1_ENABLE_SUSPEND_AVS)
41 
42 #define SPM_SUSPEND_PCM_FLAG	(SPM_FLAG_DISABLE_VCORE_DVS | \
43 				 SPM_FLAG_DISABLE_MCUPM_PDN | \
44 				 SPM_FLAG_DISABLE_VLP_PDN | \
45 				 SPM_FLAG_DISABLE_DDR_DFS | \
46 				 SPM_FLAG_DISABLE_EMI_DFS | \
47 				 SPM_FLAG_DISABLE_BUS_DFS | \
48 				 SPM_FLAG_ENABLE_MD_MUMTAS | \
49 				 SPM_FLAG_SRAM_SLEEP_CTRL)
50 
51 #define SPM_SUSPEND_PCM_FLAG1	(SPM_FLAG1_ENABLE_ALCO_TRACE | \
52 				 SPM_FLAG1_ENABLE_SUSPEND_AVS | \
53 				 SPM_FLAG1_ENABLE_CSOPLU_OFF)
54 
55 /* Suspend spm power control */
56 #define __WAKE_SRC_FOR_SUSPEND_COMMON__ ( \
57 	(R12_KP_IRQ_B) | \
58 	(R12_APWDT_EVENT_B) | \
59 	(R12_CONN2AP_WAKEUP_B) | \
60 	(R12_EINT_EVENT_B) | \
61 	(R12_CONN_WDT_IRQ_B) | \
62 	(R12_CCIF0_EVENT_B) | \
63 	(R12_CCIF1_EVENT_B) | \
64 	(R12_SCP2SPM_WAKEUP_B) | \
65 	(R12_ADSP2SPM_WAKEUP_B) | \
66 	(R12_USB0_CDSC_B) | \
67 	(R12_USB0_POWERDWN_B) | \
68 	(R12_UART_EVENT_B) |\
69 	(R12_SYS_TIMER_EVENT_B) | \
70 	(R12_EINT_EVENT_SECURE_B) | \
71 	(R12_SYS_CIRQ_IRQ_B) | \
72 	(R12_MD_WDT_B) | \
73 	(R12_AP2AP_PEER_WAKEUP_B) | \
74 	(R12_CPU_WAKEUP) | \
75 	(R12_APUSYS_WAKE_HOST_B)|\
76 	(R12_PCIE_WAKE_B))
77 
78 #if defined(CFG_MICROTRUST_TEE_SUPPORT)
79 #define WAKE_SRC_FOR_SUSPEND \
80 	(__WAKE_SRC_FOR_SUSPEND_COMMON__)
81 #else
82 #define WAKE_SRC_FOR_SUSPEND \
83 	(__WAKE_SRC_FOR_SUSPEND_COMMON__ | \
84 	 R12_SEJ_B)
85 #endif
86 static uint32_t gpio_bk1;
87 static uint32_t gpio_bk2;
88 static uint32_t gpio_bk3;
89 
90 static struct pwr_ctrl suspend_ctrl = {
91 	.wake_src = WAKE_SRC_FOR_SUSPEND,
92 
93 	/* SPM_SRC_REQ */
94 	.reg_spm_adsp_mailbox_req = 0,
95 	.reg_spm_apsrc_req = 0,
96 	.reg_spm_ddren_req = 0,
97 	.reg_spm_dvfs_req = 0,
98 	.reg_spm_emi_req = 0,
99 	.reg_spm_f26m_req = 0,
100 	.reg_spm_infra_req = 0,
101 	.reg_spm_pmic_req = 0,
102 	.reg_spm_scp_mailbox_req = 0,
103 	.reg_spm_sspm_mailbox_req = 0,
104 	.reg_spm_sw_mailbox_req = 0,
105 	.reg_spm_vcore_req = 1,
106 	.reg_spm_vrf18_req = 0,
107 	.adsp_mailbox_state = 0,
108 	.apsrc_state = 0,
109 	.ddren_state = 0,
110 	.dvfs_state = 0,
111 	.emi_state = 0,
112 	.f26m_state = 0,
113 	.infra_state = 0,
114 	.pmic_state = 0,
115 	.scp_mailbox_state = 0,
116 	.sspm_mailbox_state = 0,
117 	.sw_mailbox_state = 0,
118 	.vcore_state = 0,
119 	.vrf18_state = 0,
120 
121 	/* SPM_SRC_MASK_0 */
122 	.reg_apifr_apsrc_rmb = 0,
123 	.reg_apifr_ddren_rmb = 0,
124 	.reg_apifr_emi_rmb = 0,
125 	.reg_apifr_infra_rmb = 0,
126 	.reg_apifr_pmic_rmb = 0,
127 	.reg_apifr_srcclkena_mb = 0,
128 	.reg_apifr_vcore_rmb = 0,
129 	.reg_apifr_vrf18_rmb = 0,
130 	.reg_apu_apsrc_rmb = 1,
131 	.reg_apu_ddren_rmb = 0,
132 	.reg_apu_emi_rmb = 1,
133 	.reg_apu_infra_rmb = 1,
134 	.reg_apu_pmic_rmb = 1,
135 	.reg_apu_srcclkena_mb = 1,
136 	.reg_apu_vcore_rmb = 1,
137 	.reg_apu_vrf18_rmb = 1,
138 	.reg_audio_apsrc_rmb = 1,
139 	.reg_audio_ddren_rmb = 0,
140 	.reg_audio_emi_rmb = 1,
141 	.reg_audio_infra_rmb = 1,
142 	.reg_audio_pmic_rmb = 0,
143 	.reg_audio_srcclkena_mb = 1,
144 	.reg_audio_vcore_rmb = 1,
145 	.reg_audio_vrf18_rmb = 1,
146 
147 	/* SPM_SRC_MASK_1 */
148 	.reg_audio_dsp_apsrc_rmb = 1,
149 	.reg_audio_dsp_ddren_rmb = 0,
150 	.reg_audio_dsp_emi_rmb = 1,
151 	.reg_audio_dsp_infra_rmb = 1,
152 	.reg_audio_dsp_pmic_rmb = 1,
153 	.reg_audio_dsp_srcclkena_mb = 1,
154 	.reg_audio_dsp_vcore_rmb = 1,
155 	.reg_audio_dsp_vrf18_rmb = 1,
156 	.reg_cam_apsrc_rmb = 0,
157 	.reg_cam_ddren_rmb = 0,
158 	.reg_cam_emi_rmb = 0,
159 	.reg_cam_infra_rmb = 0,
160 	.reg_cam_pmic_rmb = 0,
161 	.reg_cam_srcclkena_mb = 0,
162 	.reg_cam_vrf18_rmb = 0,
163 	.reg_ccif_apsrc_rmb = 0xfff,
164 
165 	/* SPM_SRC_MASK_2 */
166 	.reg_ccif_emi_rmb = 0xfff,
167 	.reg_ccif_infra_rmb = 0xfff,
168 
169 	/* SPM_SRC_MASK_3 */
170 	.reg_ccif_pmic_rmb = 0xfff,
171 	.reg_ccif_srcclkena_mb = 0xfff,
172 
173 	/* SPM_SRC_MASK_4 */
174 	.reg_ccif_vcore_rmb = 0xfff,
175 	.reg_ccif_vrf18_rmb = 0xfff,
176 	.reg_ccu_apsrc_rmb = 0,
177 	.reg_ccu_ddren_rmb = 0,
178 	.reg_ccu_emi_rmb = 0,
179 	.reg_ccu_infra_rmb = 0,
180 	.reg_ccu_pmic_rmb = 0,
181 	.reg_ccu_srcclkena_mb = 0,
182 	.reg_ccu_vrf18_rmb = 0,
183 	.reg_cg_check_apsrc_rmb = 0,
184 
185 	/* SPM_SRC_MASK_5 */
186 	.reg_cg_check_ddren_rmb = 0,
187 	.reg_cg_check_emi_rmb = 0,
188 	.reg_cg_check_infra_rmb = 0,
189 	.reg_cg_check_pmic_rmb = 0,
190 	.reg_cg_check_srcclkena_mb = 0,
191 	.reg_cg_check_vcore_rmb = 1,
192 	.reg_cg_check_vrf18_rmb = 0,
193 	.reg_cksys_apsrc_rmb = 1,
194 	.reg_cksys_ddren_rmb = 0,
195 	.reg_cksys_emi_rmb = 1,
196 	.reg_cksys_infra_rmb = 1,
197 	.reg_cksys_pmic_rmb = 1,
198 	.reg_cksys_srcclkena_mb = 1,
199 	.reg_cksys_vcore_rmb = 1,
200 	.reg_cksys_vrf18_rmb = 1,
201 	.reg_cksys_1_apsrc_rmb = 1,
202 	.reg_cksys_1_ddren_rmb = 0,
203 	.reg_cksys_1_emi_rmb = 1,
204 	.reg_cksys_1_infra_rmb = 1,
205 	.reg_cksys_1_pmic_rmb = 1,
206 	.reg_cksys_1_srcclkena_mb = 1,
207 	.reg_cksys_1_vcore_rmb = 1,
208 	.reg_cksys_1_vrf18_rmb = 1,
209 
210 	/* SPM_SRC_MASK_6 */
211 	.reg_cksys_2_apsrc_rmb = 1,
212 	.reg_cksys_2_ddren_rmb = 0,
213 	.reg_cksys_2_emi_rmb = 1,
214 	.reg_cksys_2_infra_rmb = 1,
215 	.reg_cksys_2_pmic_rmb = 1,
216 	.reg_cksys_2_srcclkena_mb = 1,
217 	.reg_cksys_2_vcore_rmb = 1,
218 	.reg_cksys_2_vrf18_rmb = 1,
219 	.reg_conn_apsrc_rmb = 1,
220 	.reg_conn_ddren_rmb = 0,
221 	.reg_conn_emi_rmb = 1,
222 	.reg_conn_infra_rmb = 1,
223 	.reg_conn_pmic_rmb = 1,
224 	.reg_conn_srcclkena_mb = 1,
225 	.reg_conn_srcclkenb_mb = 1,
226 	.reg_conn_vcore_rmb = 1,
227 	.reg_conn_vrf18_rmb = 1,
228 	.reg_corecfg_apsrc_rmb = 0,
229 	.reg_corecfg_ddren_rmb = 0,
230 	.reg_corecfg_emi_rmb = 0,
231 	.reg_corecfg_infra_rmb = 0,
232 	.reg_corecfg_pmic_rmb = 0,
233 	.reg_corecfg_srcclkena_mb = 0,
234 	.reg_corecfg_vcore_rmb = 0,
235 	.reg_corecfg_vrf18_rmb = 0,
236 
237 	/* SPM_SRC_MASK_7 */
238 	.reg_cpueb_apsrc_rmb = 1,
239 	.reg_cpueb_ddren_rmb = 0,
240 	.reg_cpueb_emi_rmb = 1,
241 	.reg_cpueb_infra_rmb = 1,
242 	.reg_cpueb_pmic_rmb = 1,
243 	.reg_cpueb_srcclkena_mb = 1,
244 	.reg_cpueb_vcore_rmb = 0,
245 	.reg_cpueb_vrf18_rmb = 1,
246 	.reg_disp0_apsrc_rmb = 0,
247 	.reg_disp0_ddren_rmb = 0,
248 	.reg_disp0_emi_rmb = 0,
249 	.reg_disp0_infra_rmb = 0,
250 	.reg_disp0_pmic_rmb = 0,
251 	.reg_disp0_srcclkena_mb = 0,
252 	.reg_disp0_vrf18_rmb = 0,
253 	.reg_disp1_apsrc_rmb = 0,
254 	.reg_disp1_ddren_rmb = 0,
255 	.reg_disp1_emi_rmb = 0,
256 	.reg_disp1_infra_rmb = 0,
257 	.reg_disp1_pmic_rmb = 0,
258 	.reg_disp1_srcclkena_mb = 0,
259 	.reg_disp1_vrf18_rmb = 0,
260 	.reg_dpm_apsrc_rmb = 0xf,
261 	.reg_dpm_ddren_rmb = 0xf,
262 
263 	/* SPM_SRC_MASK_8 */
264 	.reg_dpm_emi_rmb = 0xf,
265 	.reg_dpm_infra_rmb = 0xf,
266 	.reg_dpm_pmic_rmb = 0xf,
267 	.reg_dpm_srcclkena_mb = 0xf,
268 	.reg_dpm_vcore_rmb = 0xf,
269 	.reg_dpm_vrf18_rmb = 0xf,
270 	.reg_dpmaif_apsrc_rmb = 1,
271 	.reg_dpmaif_ddren_rmb = 0,
272 	.reg_dpmaif_emi_rmb = 1,
273 	.reg_dpmaif_infra_rmb = 1,
274 	.reg_dpmaif_pmic_rmb = 1,
275 	.reg_dpmaif_srcclkena_mb = 1,
276 	.reg_dpmaif_vcore_rmb = 1,
277 	.reg_dpmaif_vrf18_rmb = 1,
278 
279 	/* SPM_SRC_MASK_9 */
280 	.reg_dvfsrc_level_rmb = 1,
281 	.reg_emisys_apsrc_rmb = 0,
282 	.reg_emisys_ddren_rmb = 0,
283 	.reg_emisys_emi_rmb = 0,
284 	.reg_emisys_infra_rmb = 0,
285 	.reg_emisys_pmic_rmb = 0,
286 	.reg_emisys_srcclkena_mb = 0,
287 	.reg_emisys_vcore_rmb = 0,
288 	.reg_emisys_vrf18_rmb = 0,
289 	.reg_gce_apsrc_rmb = 0,
290 	.reg_gce_ddren_rmb = 0,
291 	.reg_gce_emi_rmb = 0,
292 	.reg_gce_infra_rmb = 0,
293 	.reg_gce_pmic_rmb = 0,
294 	.reg_gce_srcclkena_mb = 0,
295 	.reg_gce_vcore_rmb = 0,
296 	.reg_gce_vrf18_rmb = 0,
297 	.reg_gpueb_apsrc_rmb = 1,
298 	.reg_gpueb_ddren_rmb = 0,
299 	.reg_gpueb_emi_rmb = 1,
300 	.reg_gpueb_infra_rmb = 1,
301 	.reg_gpueb_pmic_rmb = 1,
302 	.reg_gpueb_srcclkena_mb = 1,
303 	.reg_gpueb_vcore_rmb = 1,
304 	.reg_gpueb_vrf18_rmb = 1,
305 	.reg_hwccf_apsrc_rmb = 1,
306 	.reg_hwccf_ddren_rmb = 0,
307 	.reg_hwccf_emi_rmb = 1,
308 	.reg_hwccf_infra_rmb = 1,
309 	.reg_hwccf_pmic_rmb = 1,
310 	.reg_hwccf_srcclkena_mb = 1,
311 	.reg_hwccf_vcore_rmb = 1,
312 
313 	/* SPM_SRC_MASK_10 */
314 	.reg_hwccf_vrf18_rmb = 1,
315 	.reg_img_apsrc_rmb = 0,
316 	.reg_img_ddren_rmb = 0,
317 	.reg_img_emi_rmb = 0,
318 	.reg_img_infra_rmb = 0,
319 	.reg_img_pmic_rmb = 0,
320 	.reg_img_srcclkena_mb = 0,
321 	.reg_img_vrf18_rmb = 0,
322 	.reg_infrasys_apsrc_rmb = 0,
323 	.reg_infrasys_ddren_rmb = 0,
324 	.reg_infrasys_emi_rmb = 0,
325 	.reg_infrasys_infra_rmb = 0,
326 	.reg_infrasys_pmic_rmb = 0,
327 	.reg_infrasys_srcclkena_mb = 0,
328 	.reg_infrasys_vcore_rmb = 0,
329 	.reg_infrasys_vrf18_rmb = 0,
330 	.reg_ipic_infra_rmb = 1,
331 	.reg_ipic_vrf18_rmb = 1,
332 	.reg_mcu_apsrc_rmb = 1,
333 	.reg_mcu_ddren_rmb = 0,
334 	.reg_mcu_emi_rmb = 1,
335 	.reg_mcu_infra_rmb = 1,
336 	.reg_mcu_pmic_rmb = 1,
337 	.reg_mcu_srcclkena_mb = 1,
338 	.reg_mcu_vcore_rmb = 0,
339 	.reg_mcu_vrf18_rmb = 1,
340 	.reg_md_apsrc_rmb = 1,
341 	.reg_md_ddren_rmb = 0,
342 	.reg_md_emi_rmb = 1,
343 	.reg_md_infra_rmb = 1,
344 	.reg_md_pmic_rmb = 1,
345 	.reg_md_srcclkena_mb = 1,
346 
347 	/* SPM_SRC_MASK_11 */
348 	.reg_md_srcclkena1_mb = 1,
349 	.reg_md_vcore_rmb = 1,
350 	.reg_md_vrf18_rmb = 1,
351 	.reg_mm_proc_apsrc_rmb = 1,
352 	.reg_mm_proc_ddren_rmb = 0,
353 	.reg_mm_proc_emi_rmb = 1,
354 	.reg_mm_proc_infra_rmb = 1,
355 	.reg_mm_proc_pmic_rmb = 1,
356 	.reg_mm_proc_srcclkena_mb = 1,
357 	.reg_mm_proc_vcore_rmb = 1,
358 	.reg_mm_proc_vrf18_rmb = 1,
359 	.reg_mml0_apsrc_rmb = 0,
360 	.reg_mml0_ddren_rmb = 0,
361 	.reg_mml0_emi_rmb = 0,
362 	.reg_mml0_infra_rmb = 0,
363 	.reg_mml0_pmic_rmb = 0,
364 	.reg_mml0_srcclkena_mb = 0,
365 	.reg_mml0_vrf18_rmb = 0,
366 	.reg_mml1_apsrc_rmb = 0,
367 	.reg_mml1_ddren_rmb = 0,
368 	.reg_mml1_emi_rmb = 0,
369 	.reg_mml1_infra_rmb = 0,
370 	.reg_mml1_pmic_rmb = 0,
371 	.reg_mml1_srcclkena_mb = 0,
372 	.reg_mml1_vrf18_rmb = 0,
373 	.reg_ovl0_apsrc_rmb = 0,
374 	.reg_ovl0_ddren_rmb = 0,
375 	.reg_ovl0_emi_rmb = 0,
376 	.reg_ovl0_infra_rmb = 0,
377 	.reg_ovl0_pmic_rmb = 0,
378 	.reg_ovl0_srcclkena_mb = 0,
379 	.reg_ovl0_vrf18_rmb = 0,
380 
381 	/* SPM_SRC_MASK_12 */
382 	.reg_ovl1_apsrc_rmb = 0,
383 	.reg_ovl1_ddren_rmb = 0,
384 	.reg_ovl1_emi_rmb = 0,
385 	.reg_ovl1_infra_rmb = 0,
386 	.reg_ovl1_pmic_rmb = 0,
387 	.reg_ovl1_srcclkena_mb = 0,
388 	.reg_ovl1_vrf18_rmb = 0,
389 	.reg_pcie0_apsrc_rmb = 1,
390 	.reg_pcie0_ddren_rmb = 0,
391 	.reg_pcie0_emi_rmb = 1,
392 	.reg_pcie0_infra_rmb = 1,
393 	.reg_pcie0_pmic_rmb = 1,
394 	.reg_pcie0_srcclkena_mb = 1,
395 	.reg_pcie0_vcore_rmb = 1,
396 	.reg_pcie0_vrf18_rmb = 1,
397 	.reg_pcie1_apsrc_rmb = 1,
398 	.reg_pcie1_ddren_rmb = 0,
399 	.reg_pcie1_emi_rmb = 1,
400 	.reg_pcie1_infra_rmb = 1,
401 	.reg_pcie1_pmic_rmb = 1,
402 	.reg_pcie1_srcclkena_mb = 1,
403 	.reg_pcie1_vcore_rmb = 1,
404 	.reg_pcie1_vrf18_rmb = 1,
405 	.reg_perisys_apsrc_rmb = 1,
406 	.reg_perisys_ddren_rmb = 0,
407 	.reg_perisys_emi_rmb = 1,
408 	.reg_perisys_infra_rmb = 1,
409 	.reg_perisys_pmic_rmb = 1,
410 	.reg_perisys_srcclkena_mb = 1,
411 	.reg_perisys_vcore_rmb = 1,
412 	.reg_perisys_vrf18_rmb = 1,
413 	.reg_pmsr_apsrc_rmb = 1,
414 
415 	/* SPM_SRC_MASK_13 */
416 	.reg_pmsr_ddren_rmb = 0,
417 	.reg_pmsr_emi_rmb = 1,
418 	.reg_pmsr_infra_rmb = 1,
419 	.reg_pmsr_pmic_rmb = 1,
420 	.reg_pmsr_srcclkena_mb = 1,
421 	.reg_pmsr_vcore_rmb = 1,
422 	.reg_pmsr_vrf18_rmb = 1,
423 	.reg_scp_apsrc_rmb = 1,
424 	.reg_scp_ddren_rmb = 0,
425 	.reg_scp_emi_rmb = 1,
426 	.reg_scp_infra_rmb = 1,
427 	.reg_scp_pmic_rmb = 1,
428 	.reg_scp_srcclkena_mb = 1,
429 	.reg_scp_vcore_rmb = 1,
430 	.reg_scp_vrf18_rmb = 1,
431 	.reg_spu_hwr_apsrc_rmb = 1,
432 	.reg_spu_hwr_ddren_rmb = 0,
433 	.reg_spu_hwr_emi_rmb = 1,
434 	.reg_spu_hwr_infra_rmb = 1,
435 	.reg_spu_hwr_pmic_rmb = 1,
436 	.reg_spu_hwr_srcclkena_mb = 1,
437 	.reg_spu_hwr_vcore_rmb = 1,
438 	.reg_spu_hwr_vrf18_rmb = 1,
439 	.reg_spu_ise_apsrc_rmb = 1,
440 	.reg_spu_ise_ddren_rmb = 0,
441 	.reg_spu_ise_emi_rmb = 1,
442 	.reg_spu_ise_infra_rmb = 1,
443 	.reg_spu_ise_pmic_rmb = 1,
444 	.reg_spu_ise_srcclkena_mb = 1,
445 	.reg_spu_ise_vcore_rmb = 1,
446 	.reg_spu_ise_vrf18_rmb = 1,
447 
448 	/* SPM_SRC_MASK_14 */
449 	.reg_srcclkeni_infra_rmb = 0x3,
450 	.reg_srcclkeni_pmic_rmb = 0x3,
451 	.reg_srcclkeni_srcclkena_mb = 0x3,
452 	.reg_srcclkeni_vcore_rmb = 0x3,
453 	.reg_sspm_apsrc_rmb = 1,
454 	.reg_sspm_ddren_rmb = 0,
455 	.reg_sspm_emi_rmb = 1,
456 	.reg_sspm_infra_rmb = 1,
457 	.reg_sspm_pmic_rmb = 1,
458 	.reg_sspm_srcclkena_mb = 1,
459 	.reg_sspm_vrf18_rmb = 1,
460 	.reg_ssrsys_apsrc_rmb = 1,
461 	.reg_ssrsys_ddren_rmb = 0,
462 	.reg_ssrsys_emi_rmb = 1,
463 	.reg_ssrsys_infra_rmb = 1,
464 	.reg_ssrsys_pmic_rmb = 1,
465 	.reg_ssrsys_srcclkena_mb = 1,
466 	.reg_ssrsys_vcore_rmb = 1,
467 	.reg_ssrsys_vrf18_rmb = 1,
468 	.reg_ssusb_apsrc_rmb = 1,
469 	.reg_ssusb_ddren_rmb = 0,
470 	.reg_ssusb_emi_rmb = 1,
471 	.reg_ssusb_infra_rmb = 1,
472 	.reg_ssusb_pmic_rmb = 1,
473 	.reg_ssusb_srcclkena_mb = 1,
474 	.reg_ssusb_vcore_rmb = 1,
475 	.reg_ssusb_vrf18_rmb = 1,
476 	.reg_uart_hub_infra_rmb = 1,
477 
478 	/* SPM_SRC_MASK_15 */
479 	.reg_uart_hub_pmic_rmb = 1,
480 	.reg_uart_hub_srcclkena_mb = 1,
481 	.reg_uart_hub_vcore_rmb = 1,
482 	.reg_uart_hub_vrf18_rmb = 1,
483 	.reg_ufs_apsrc_rmb = 1,
484 	.reg_ufs_ddren_rmb = 0,
485 	.reg_ufs_emi_rmb = 1,
486 	.reg_ufs_infra_rmb = 1,
487 	.reg_ufs_pmic_rmb = 1,
488 	.reg_ufs_srcclkena_mb = 1,
489 	.reg_ufs_vcore_rmb = 1,
490 	.reg_ufs_vrf18_rmb = 1,
491 	.reg_vdec_apsrc_rmb = 0,
492 	.reg_vdec_ddren_rmb = 0,
493 	.reg_vdec_emi_rmb = 0,
494 	.reg_vdec_infra_rmb = 0,
495 	.reg_vdec_pmic_rmb = 0,
496 	.reg_vdec_srcclkena_mb = 0,
497 	.reg_vdec_vrf18_rmb = 0,
498 	.reg_venc_apsrc_rmb = 0,
499 	.reg_venc_ddren_rmb = 0,
500 	.reg_venc_emi_rmb = 0,
501 	.reg_venc_infra_rmb = 0,
502 	.reg_venc_pmic_rmb = 0,
503 	.reg_venc_srcclkena_mb = 0,
504 	.reg_venc_vrf18_rmb = 0,
505 	.reg_vlpcfg_apsrc_rmb = 1,
506 	.reg_vlpcfg_ddren_rmb = 0,
507 	.reg_vlpcfg_emi_rmb = 1,
508 	.reg_vlpcfg_infra_rmb = 1,
509 	.reg_vlpcfg_pmic_rmb = 1,
510 	.reg_vlpcfg_srcclkena_mb = 1,
511 
512 	/* SPM_SRC_MASK_16 */
513 	.reg_vlpcfg_vcore_rmb = 1,
514 	.reg_vlpcfg_vrf18_rmb = 1,
515 	.reg_vlpcfg1_apsrc_rmb = 1,
516 	.reg_vlpcfg1_ddren_rmb = 0,
517 	.reg_vlpcfg1_emi_rmb = 1,
518 	.reg_vlpcfg1_infra_rmb = 1,
519 	.reg_vlpcfg1_pmic_rmb = 0,
520 	.reg_vlpcfg1_srcclkena_mb = 1,
521 	.reg_vlpcfg1_vcore_rmb = 1,
522 	.reg_vlpcfg1_vrf18_rmb = 1,
523 
524 	/* SPM_EVENT_CON_MISC */
525 	.reg_srcclken_fast_resp = 0,
526 	.reg_csyspwrup_ack_mask = 1,
527 
528 	/* SPM_SRC_MASK_17 */
529 	.reg_spm_sw_vcore_rmb = 0x3,
530 	.reg_spm_sw_pmic_rmb = 0,
531 
532 	/* SPM_SRC_MASK_18 */
533 	.reg_spm_sw_srcclkena_mb = 0,
534 
535 	/* SPM_WAKE_MASK*/
536 	.reg_wake_mask = 0x81322012,
537 
538 	/* SPM_WAKEUP_EVENT_EXT_MASK */
539 	.reg_ext_wake_mask = 0xFFFFFFFF,
540 
541 	/*SW flag setting */
542 	.pcm_flags = SPM_SUSPEND_PCM_FLAG,
543 	.pcm_flags1 = SPM_SUSPEND_PCM_FLAG1,
544 };
545 
546 static struct suspend_dbg_ctrl suspend_spm_dbg_ext = {
547 	.sleep_suspend_cnt = 0,
548 };
549 
550 static struct dbg_ctrl suspend_spm_dbg = {
551 	.count = 0,
552 	.duration = 0,
553 	.ext = &suspend_spm_dbg_ext,
554 };
555 
556 static struct spm_lp_stat suspend_lp_stat;
557 
558 struct spm_lp_scen __spm_suspend = {
559 	.pwrctrl = &suspend_ctrl,
560 	.dbgctrl = &suspend_spm_dbg,
561 	.lpstat = &suspend_lp_stat,
562 };
563 
564 static uint8_t bak_spm_vcore_req;
565 
566 int mt_spm_suspend_mode_set(enum mt_spm_suspend_mode mode, void *prv)
567 {
568 
569 	if (mode == MT_SPM_SUSPEND_SLEEP) {
570 		suspend_ctrl.pcm_flags = SPM_SUSPEND_SLEEP_PCM_FLAG;
571 		suspend_ctrl.pcm_flags1 = SPM_SUSPEND_SLEEP_PCM_FLAG1;
572 		suspend_ctrl.reg_spm_vcore_req = 1;
573 	} else {
574 		suspend_ctrl.pcm_flags = SPM_SUSPEND_PCM_FLAG;
575 		suspend_ctrl.pcm_flags1 = SPM_SUSPEND_PCM_FLAG1;
576 	}
577 
578 	return 0;
579 }
580 
581 static void spm_CSOPLU_ctrl_leave_suspend(void)
582 {
583 	mmio_setbits_32(SPM_RSV_CSOPLU_REQ, (0x1));
584 }
585 
586 static void mt_spm_suspend_ec_pin(void)
587 {
588 	gpio_bk1 = mmio_read_32(MODE_BACKUP_REG);
589 	gpio_bk2 = mmio_read_32(DIR_BACKUP_REG);
590 	gpio_bk3 = mmio_read_32(DOUT_BACKUP_REG);
591 
592 	mmio_write_32(MODE_SET, SET_GPIO_MODE);
593 	gpio_set_direction(EC_SUSPEND_BK_PIN, GPIO_DIR_OUT);
594 	/* GPIO111 LOW */
595 	gpio_set_value(EC_SUSPEND_BK_PIN, GPIO_LEVEL_LOW);
596 	/* GPIO38 LOW */
597 	gpio_set_value(EC_SUSPEND_PIN, GPIO_LEVEL_LOW);
598 }
599 
600 static void mt_spm_resume_ec_pin(void)
601 {
602 	/* GPIO38 HIGH */
603 	gpio_set_value(EC_SUSPEND_PIN, GPIO_LEVEL_HIGH);
604 	/* GPIO111 HIGH */
605 	gpio_set_value(EC_SUSPEND_BK_PIN, GPIO_LEVEL_HIGH);
606 	udelay(10);
607 
608 	mmio_write_32(MODE_BACKUP_REG, gpio_bk1);
609 	mmio_write_32(DIR_BACKUP_REG, gpio_bk2);
610 	mmio_write_32(DOUT_BACKUP_REG, gpio_bk3);
611 }
612 
613 int mt_spm_suspend_enter(int state_id,
614 			 uint32_t ext_opand, uint32_t resource_req)
615 {
616 	int ret = 0;
617 
618 	bak_spm_vcore_req = suspend_ctrl.reg_spm_vcore_req;
619 
620 	/* if FMAudio, ADSP, USB headset is active, change to sleep mode */
621 	if (ext_opand & MT_SPM_EX_OP_SET_SUSPEND_MODE)
622 		mt_spm_suspend_mode_set(MT_SPM_SUSPEND_SLEEP,
623 					&resource_req);
624 	else
625 		mt_spm_suspend_mode_set(MT_SPM_SUSPEND_SYSTEM_PDN,
626 					&resource_req);
627 
628 	mmio_write_32(SPM2SW_MAILBOX_0, 0x1);
629 
630 	ext_opand |= MT_SPM_EX_OP_DEVICES_SAVE;
631 
632 #if defined(CONFIG_MTK_VCOREDVFS_SUPPORT)
633 	/* Notify vcoredvfs suspend enter */
634 	spm_vcorefs_plat_suspend();
635 #endif
636 
637 	ret = spm_conservation(state_id, ext_opand,
638 				&__spm_suspend, resource_req);
639 	if (ret == 0) {
640 		struct mt_lp_publish_event event = {
641 			.id = MT_LPM_PUBEVENTS_SYS_POWER_OFF,
642 			.val.u32 = 0,
643 			.level = MT_LP_SYSPOWER_LEVEL_SUSPEND,
644 		};
645 
646 		MT_LP_SUSPEND_PUBLISH_EVENT(&event);
647 	}
648 
649 	mt_spm_suspend_ec_pin();
650 
651 	return ret;
652 }
653 
654 void mt_spm_suspend_resume(int state_id, uint32_t ext_opand,
655 			   struct wake_status **status)
656 {
657 	struct mt_lp_publish_event event;
658 	struct wake_status *st = NULL;
659 
660 	ext_opand |= MT_SPM_EX_OP_DEVICES_SAVE;
661 
662 	mt_spm_resume_ec_pin();
663 	spm_conservation_finish(state_id, ext_opand, &__spm_suspend, &st);
664 
665 	spm_CSOPLU_ctrl_leave_suspend();
666 
667 	mt_spm_update_lp_stat(&suspend_lp_stat);
668 #if defined(CONFIG_MTK_VCOREDVFS_SUPPORT)
669 	/* Notify vcoredvfs suspend enter */
670 	spm_vcorefs_plat_resume();
671 	mmio_write_32(SPM2SW_MAILBOX_0, 0x0);
672 #endif
673 
674 	/*****************************************
675 	 * If FMAudio, ADSP, USB headset is active,
676 	 * change back to suspend mode and counting in resume
677 	 *****************************************/
678 
679 	if (ext_opand & MT_SPM_EX_OP_SET_SUSPEND_MODE) {
680 		mt_spm_suspend_mode_set(MT_SPM_SUSPEND_SYSTEM_PDN, NULL);
681 		suspend_spm_dbg_ext.sleep_suspend_cnt += 1;
682 	}
683 
684 	suspend_ctrl.reg_spm_vcore_req = bak_spm_vcore_req;
685 
686 	suspend_spm_dbg.count += 1;
687 	event.id = MT_LPM_PUBEVENTS_SYS_POWER_ON;
688 	event.val.u32 = 0;
689 	event.level = MT_LP_SYSPOWER_LEVEL_SUSPEND;
690 
691 	if (st) {
692 		if (st->tr.comm.r12 & R12_AP2AP_PEER_WAKEUP_B)
693 			event.val.u32 = MT_LPM_WAKE_MD_WAKEUP_DPMAIF;
694 		if (st->tr.comm.r12 & R12_CCIF0_EVENT_B)
695 			event.val.u32 = MT_LPM_WAKE_MD_WAKEUP_CCIF0;
696 		if (st->tr.comm.r12 & R12_CCIF1_EVENT_B)
697 			event.val.u32 = MT_LPM_WAKE_MD_WAKEUP_CCIF1;
698 	}
699 	if (status)
700 		*status = st;
701 	MT_LP_SUSPEND_PUBLISH_EVENT(&event);
702 }
703 
704 int mt_spm_suspend_get_spm_lp(struct spm_lp_scen **lp)
705 {
706 	if (!lp)
707 		return -1;
708 
709 	*lp = &__spm_suspend;
710 	return 0;
711 }
712