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
mt_spm_suspend_mode_set(enum mt_spm_suspend_mode mode,void * prv)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
spm_CSOPLU_ctrl_leave_suspend(void)581 static void spm_CSOPLU_ctrl_leave_suspend(void)
582 {
583 mmio_setbits_32(SPM_RSV_CSOPLU_REQ, (0x1));
584 }
585
mt_spm_suspend_ec_pin(void)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
mt_spm_resume_ec_pin(void)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
mt_spm_suspend_enter(int state_id,uint32_t ext_opand,uint32_t resource_req)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
mt_spm_suspend_resume(int state_id,uint32_t ext_opand,struct wake_status ** status)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
mt_spm_suspend_get_spm_lp(struct spm_lp_scen ** lp)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