blob: b40fa873b184492c45ad34e1cb89a80771b63c2f [file] [log] [blame]
Edward-JW Yang1c7fd0b2021-06-28 11:29:51 +08001/*
2 * Copyright (c) 2021, MediaTek Inc. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <common/debug.h>
8#include <lib/mmio.h>
9#include <mt_spm.h>
10#include <mt_spm_conservation.h>
11#include <mt_spm_internal.h>
12#include <mt_spm_rc_internal.h>
13#include <mt_spm_reg.h>
14#include <mt_spm_resource_req.h>
15#include <mt_spm_suspend.h>
16#include <plat_pm.h>
17#include <uart.h>
18
19#define SPM_SUSPEND_SLEEP_PCM_FLAG \
20 (SPM_FLAG_DISABLE_INFRA_PDN | \
21 SPM_FLAG_DISABLE_VCORE_DVS | \
22 SPM_FLAG_DISABLE_VCORE_DFS | \
23 SPM_FLAG_KEEP_CSYSPWRACK_HIGH | \
24 SPM_FLAG_DISABLE_DRAMC_MCU_SRAM_SLEEP | \
25 SPM_FLAG_SRAM_SLEEP_CTRL)
26
27#define SPM_SUSPEND_SLEEP_PCM_FLAG1 0
28
29#define SPM_SUSPEND_PCM_FLAG \
30 (SPM_FLAG_DISABLE_VCORE_DVS | \
31 SPM_FLAG_DISABLE_VCORE_DFS | \
32 SPM_FLAG_ENABLE_TIA_WORKAROUND | \
33 SPM_FLAG_DISABLE_DRAMC_MCU_SRAM_SLEEP | \
34 SPM_FLAG_SRAM_SLEEP_CTRL)
35
36#define SPM_SUSPEND_PCM_FLAG1 0
37
38/* Suspend spm power control */
39#define __WAKE_SRC_FOR_SUSPEND_COMMON__ \
40 (R12_PCM_TIMER | \
41 R12_KP_IRQ_B | \
42 R12_APWDT_EVENT_B | \
43 R12_CONN2AP_SPM_WAKEUP_B | \
44 R12_EINT_EVENT_B | \
45 R12_CONN_WDT_IRQ_B | \
46 R12_CCIF0_EVENT_B | \
47 R12_SSPM2SPM_WAKEUP_B | \
48 R12_SCP2SPM_WAKEUP_B | \
49 R12_ADSP2SPM_WAKEUP_B | \
50 R12_USBX_CDSC_B | \
51 R12_USBX_POWERDWN_B | \
52 R12_SYS_TIMER_EVENT_B | \
53 R12_EINT_EVENT_SECURE_B | \
54 R12_SYS_CIRQ_IRQ_B | \
55 R12_MD2AP_PEER_EVENT_B | \
56 R12_MD1_WDT_B | \
57 R12_CLDMA_EVENT_B | \
58 R12_REG_CPU_WAKEUP | \
59 R12_APUSYS_WAKE_HOST_B)
60
61#if defined(CFG_MICROTRUST_TEE_SUPPORT)
62#define WAKE_SRC_FOR_SUSPEND (__WAKE_SRC_FOR_SUSPEND_COMMON__)
63#else
64#define WAKE_SRC_FOR_SUSPEND \
65 (__WAKE_SRC_FOR_SUSPEND_COMMON__ | \
66 R12_SEJ_EVENT_B)
67#endif
68
69static struct pwr_ctrl suspend_ctrl = {
70 .wake_src = WAKE_SRC_FOR_SUSPEND,
71
72 /* SPM_AP_STANDBY_CON */
73 /* [0] */
74 .reg_wfi_op = 0,
75 /* [1] */
76 .reg_wfi_type = 0,
77 /* [2] */
78 .reg_mp0_cputop_idle_mask = 0,
79 /* [3] */
80 .reg_mp1_cputop_idle_mask = 0,
81 /* [4] */
82 .reg_mcusys_idle_mask = 0,
83 /* [25] */
84 .reg_md_apsrc_1_sel = 0,
85 /* [26] */
86 .reg_md_apsrc_0_sel = 0,
87 /* [29] */
88 .reg_conn_apsrc_sel = 0,
89
90 /* SPM_SRC_REQ */
91 /* [0] */
92 .reg_spm_apsrc_req = 0,
93 /* [1] */
94 .reg_spm_f26m_req = 0,
95 /* [3] */
96 .reg_spm_infra_req = 0,
97 /* [4] */
98 .reg_spm_vrf18_req = 0,
99 /* [7] FIXME: default disable HW Auto S1*/
developer4dfd8e22021-07-20 09:40:58 +0800100 .reg_spm_ddr_en_req = 1,
Edward-JW Yang1c7fd0b2021-06-28 11:29:51 +0800101 /* [8] */
102 .reg_spm_dvfs_req = 0,
103 /* [9] */
104 .reg_spm_sw_mailbox_req = 0,
105 /* [10] */
106 .reg_spm_sspm_mailbox_req = 0,
107 /* [11] */
108 .reg_spm_adsp_mailbox_req = 0,
109 /* [12] */
110 .reg_spm_scp_mailbox_req = 0,
111
112 /* SPM_SRC_MASK */
113 /* [0] */
114 .reg_sspm_srcclkena_0_mask_b = 1,
115 /* [1] */
116 .reg_sspm_infra_req_0_mask_b = 1,
117 /* [2] */
118 .reg_sspm_apsrc_req_0_mask_b = 1,
119 /* [3] */
120 .reg_sspm_vrf18_req_0_mask_b = 1,
121 /* [4] */
122 .reg_sspm_ddr_en_0_mask_b = 1,
123 /* [5] */
124 .reg_scp_srcclkena_mask_b = 1,
125 /* [6] */
126 .reg_scp_infra_req_mask_b = 1,
127 /* [7] */
128 .reg_scp_apsrc_req_mask_b = 1,
129 /* [8] */
130 .reg_scp_vrf18_req_mask_b = 1,
131 /* [9] */
132 .reg_scp_ddr_en_mask_b = 1,
133 /* [10] */
134 .reg_audio_dsp_srcclkena_mask_b = 1,
135 /* [11] */
136 .reg_audio_dsp_infra_req_mask_b = 1,
137 /* [12] */
138 .reg_audio_dsp_apsrc_req_mask_b = 1,
139 /* [13] */
140 .reg_audio_dsp_vrf18_req_mask_b = 1,
141 /* [14] */
142 .reg_audio_dsp_ddr_en_mask_b = 1,
143 /* [15] */
144 .reg_apu_srcclkena_mask_b = 1,
145 /* [16] */
146 .reg_apu_infra_req_mask_b = 1,
147 /* [17] */
148 .reg_apu_apsrc_req_mask_b = 1,
149 /* [18] */
150 .reg_apu_vrf18_req_mask_b = 1,
151 /* [19] */
152 .reg_apu_ddr_en_mask_b = 1,
153 /* [20] */
154 .reg_cpueb_srcclkena_mask_b = 1,
155 /* [21] */
156 .reg_cpueb_infra_req_mask_b = 1,
157 /* [22] */
158 .reg_cpueb_apsrc_req_mask_b = 1,
159 /* [23] */
160 .reg_cpueb_vrf18_req_mask_b = 1,
161 /* [24] */
162 .reg_cpueb_ddr_en_mask_b = 1,
163 /* [25] */
164 .reg_bak_psri_srcclkena_mask_b = 0,
165 /* [26] */
166 .reg_bak_psri_infra_req_mask_b = 0,
167 /* [27] */
168 .reg_bak_psri_apsrc_req_mask_b = 0,
169 /* [28] */
170 .reg_bak_psri_vrf18_req_mask_b = 0,
171 /* [29] */
172 .reg_bak_psri_ddr_en_mask_b = 0,
173
174 /* SPM_SRC2_MASK */
175 /* [0] */
176 .reg_msdc0_srcclkena_mask_b = 1,
177 /* [1] */
178 .reg_msdc0_infra_req_mask_b = 1,
179 /* [2] */
180 .reg_msdc0_apsrc_req_mask_b = 1,
181 /* [3] */
182 .reg_msdc0_vrf18_req_mask_b = 1,
183 /* [4] */
184 .reg_msdc0_ddr_en_mask_b = 1,
185 /* [5] */
186 .reg_msdc1_srcclkena_mask_b = 1,
187 /* [6] */
188 .reg_msdc1_infra_req_mask_b = 1,
189 /* [7] */
190 .reg_msdc1_apsrc_req_mask_b = 1,
191 /* [8] */
192 .reg_msdc1_vrf18_req_mask_b = 1,
193 /* [9] */
194 .reg_msdc1_ddr_en_mask_b = 1,
195 /* [10] */
196 .reg_msdc2_srcclkena_mask_b = 1,
197 /* [11] */
198 .reg_msdc2_infra_req_mask_b = 1,
199 /* [12] */
200 .reg_msdc2_apsrc_req_mask_b = 1,
201 /* [13] */
202 .reg_msdc2_vrf18_req_mask_b = 1,
203 /* [14] */
204 .reg_msdc2_ddr_en_mask_b = 1,
205 /* [15] */
206 .reg_ufs_srcclkena_mask_b = 0,
207 /* [16] */
208 .reg_ufs_infra_req_mask_b = 0,
209 /* [17] */
210 .reg_ufs_apsrc_req_mask_b = 0,
211 /* [18] */
212 .reg_ufs_vrf18_req_mask_b = 0,
213 /* [19] */
214 .reg_ufs_ddr_en_mask_b = 0,
215 /* [20] */
216 .reg_usb_srcclkena_mask_b = 1,
217 /* [21] */
218 .reg_usb_infra_req_mask_b = 1,
219 /* [22] */
220 .reg_usb_apsrc_req_mask_b = 1,
221 /* [23] */
222 .reg_usb_vrf18_req_mask_b = 1,
223 /* [24] */
224 .reg_usb_ddr_en_mask_b = 1,
225 /* [25] */
226 .reg_pextp_p0_srcclkena_mask_b = 1,
227 /* [26] */
228 .reg_pextp_p0_infra_req_mask_b = 1,
229 /* [27] */
230 .reg_pextp_p0_apsrc_req_mask_b = 1,
231 /* [28] */
232 .reg_pextp_p0_vrf18_req_mask_b = 1,
233 /* [29] */
234 .reg_pextp_p0_ddr_en_mask_b = 1,
235
236 /* SPM_SRC3_MASK */
237 /* [0] */
238 .reg_pextp_p1_srcclkena_mask_b = 1,
239 /* [1] */
240 .reg_pextp_p1_infra_req_mask_b = 1,
241 /* [2] */
242 .reg_pextp_p1_apsrc_req_mask_b = 1,
243 /* [3] */
244 .reg_pextp_p1_vrf18_req_mask_b = 1,
245 /* [4] */
246 .reg_pextp_p1_ddr_en_mask_b = 1,
247 /* [5] */
248 .reg_gce0_infra_req_mask_b = 1,
249 /* [6] */
250 .reg_gce0_apsrc_req_mask_b = 1,
251 /* [7] */
252 .reg_gce0_vrf18_req_mask_b = 1,
253 /* [8] */
254 .reg_gce0_ddr_en_mask_b = 1,
255 /* [9] */
256 .reg_gce1_infra_req_mask_b = 1,
257 /* [10] */
258 .reg_gce1_apsrc_req_mask_b = 1,
259 /* [11] */
260 .reg_gce1_vrf18_req_mask_b = 1,
261 /* [12] */
262 .reg_gce1_ddr_en_mask_b = 1,
263 /* [13] */
264 .reg_spm_srcclkena_reserved_mask_b = 1,
265 /* [14] */
266 .reg_spm_infra_req_reserved_mask_b = 1,
267 /* [15] */
268 .reg_spm_apsrc_req_reserved_mask_b = 1,
269 /* [16] */
270 .reg_spm_vrf18_req_reserved_mask_b = 1,
271 /* [17] */
272 .reg_spm_ddr_en_reserved_mask_b = 1,
273 /* [18] */
274 .reg_disp0_apsrc_req_mask_b = 1,
275 /* [19] */
276 .reg_disp0_ddr_en_mask_b = 1,
277 /* [20] */
278 .reg_disp1_apsrc_req_mask_b = 1,
279 /* [21] */
280 .reg_disp1_ddr_en_mask_b = 1,
281 /* [22] */
282 .reg_disp2_apsrc_req_mask_b = 1,
283 /* [23] */
284 .reg_disp2_ddr_en_mask_b = 1,
285 /* [24] */
286 .reg_disp3_apsrc_req_mask_b = 1,
287 /* [25] */
288 .reg_disp3_ddr_en_mask_b = 1,
289 /* [26] */
290 .reg_infrasys_apsrc_req_mask_b = 0,
291 /* [27] */
292 .reg_infrasys_ddr_en_mask_b = 1,
293
294 /* [28] */
295 .reg_cg_check_srcclkena_mask_b = 1,
296 /* [29] */
297 .reg_cg_check_apsrc_req_mask_b = 1,
298 /* [30] */
299 .reg_cg_check_vrf18_req_mask_b = 1,
300 /* [31] */
301 .reg_cg_check_ddr_en_mask_b = 1,
302
303 /* SPM_SRC4_MASK */
304 /* [8:0] */
305 .reg_mcusys_merge_apsrc_req_mask_b = 0x17,
306 /* [17:9] */
307 .reg_mcusys_merge_ddr_en_mask_b = 0x17,
308 /* [19:18] */
309 .reg_dramc_md32_infra_req_mask_b = 0,
310 /* [21:20] */
311 .reg_dramc_md32_vrf18_req_mask_b = 0,
312 /* [23:22] */
313 .reg_dramc_md32_ddr_en_mask_b = 0,
314 /* [24] */
315 .reg_dvfsrc_event_trigger_mask_b = 1,
316
317 /* SPM_WAKEUP_EVENT_MASK2 */
318 /* [3:0] */
319 .reg_sc_sw2spm_wakeup_mask_b = 0,
320 /* [4] */
321 .reg_sc_adsp2spm_wakeup_mask_b = 0,
322 /* [8:5] */
323 .reg_sc_sspm2spm_wakeup_mask_b = 0,
324 /* [9] */
325 .reg_sc_scp2spm_wakeup_mask_b = 0,
326 /* [10] */
327 .reg_csyspwrup_ack_mask = 0,
328 /* [11] */
329 .reg_csyspwrup_req_mask = 1,
330
331 /* SPM_WAKEUP_EVENT_MASK */
332 /* [31:0] */
333 .reg_wakeup_event_mask = 0xC1382213,
334
335 /* SPM_WAKEUP_EVENT_EXT_MASK */
336 /* [31:0] */
337 .reg_ext_wakeup_event_mask = 0xFFFFFFFF,
338};
339
340struct spm_lp_scen __spm_suspend = {
341 .pwrctrl = &suspend_ctrl,
342};
343
344int mt_spm_suspend_mode_set(int mode)
345{
346 if (mode == MT_SPM_SUSPEND_SLEEP) {
347 suspend_ctrl.pcm_flags = SPM_SUSPEND_SLEEP_PCM_FLAG;
348 suspend_ctrl.pcm_flags1 = SPM_SUSPEND_SLEEP_PCM_FLAG1;
349 } else {
350 suspend_ctrl.pcm_flags = SPM_SUSPEND_PCM_FLAG;
351 suspend_ctrl.pcm_flags1 = SPM_SUSPEND_PCM_FLAG1;
352 }
353
354 return 0;
355}
356
357int mt_spm_suspend_enter(int state_id, unsigned int ext_opand,
358 unsigned int resource_req)
359{
360 /* If FMAudio / ADSP is active, change to sleep suspend mode */
361 if ((ext_opand & MT_SPM_EX_OP_SET_SUSPEND_MODE) != 0U) {
362 mt_spm_suspend_mode_set(MT_SPM_SUSPEND_SLEEP);
363 }
364
365 /* Notify MCUPM that device is going suspend flow */
366 mmio_write_32(MCUPM_MBOX_OFFSET_PDN, MCUPM_POWER_DOWN);
367
368 /* Notify UART to sleep */
369 mt_uart_save();
370
371 return spm_conservation(state_id, ext_opand,
372 &__spm_suspend, resource_req);
373}
374
375void mt_spm_suspend_resume(int state_id, unsigned int ext_opand,
376 struct wake_status **status)
377{
378 spm_conservation_finish(state_id, ext_opand, &__spm_suspend, status);
379
380 /* Notify UART to wakeup */
381 mt_uart_restore();
382
383 /* Notify MCUPM that device leave suspend */
384 mmio_write_32(MCUPM_MBOX_OFFSET_PDN, 0);
385
386 /* If FMAudio / ADSP is active, change back to suspend mode */
387 if ((ext_opand & MT_SPM_EX_OP_SET_SUSPEND_MODE) != 0U) {
388 mt_spm_suspend_mode_set(MT_SPM_SUSPEND_SYSTEM_PDN);
389 }
390}
391
392void mt_spm_suspend_init(void)
393{
394 spm_conservation_pwrctrl_init(__spm_suspend.pwrctrl);
395}