blob: b4dc3f9407c4e15a20d84a1daf82402afb77d0d8 [file] [log] [blame]
developer451d49d2022-11-16 21:52:21 +08001/*
2 * Copyright (c) 2023, MediaTek Inc. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <stddef.h>
8#include <stdio.h>
9#include <string.h>
10#include <common/debug.h>
11#include <lib/mmio.h>
12#include <drivers/spm/mt_spm_resource_req.h>
13#include <lib/pm/mtk_pm.h>
14#include <lpm/mt_lp_api.h>
15
16#include <mt_spm.h>
17#include <mt_spm_conservation.h>
18#include <mt_spm_idle.h>
19#include <mt_spm_internal.h>
20#include <mt_spm_reg.h>
21
22#define SPM_BYPASS_SYSPWREQ_GENERIC (1)
23
24#define __WAKE_SRC_FOR_IDLE_COMMON__ ( \
25 (R12_PCM_TIMER) | \
26 (R12_KP_IRQ_B) | \
27 (R12_APWDT_EVENT_B) | \
28 (R12_APXGPT1_EVENT_B) | \
29 (R12_MSDC_WAKEUP_B) | \
30 (R12_EINT_EVENT_B) | \
31 (R12_SBD_INTR_WAKEUP_B) | \
32 (R12_SSPM2SPM_WAKEUP_B) | \
33 (R12_SCP2SPM_WAKEUP_B) | \
34 (R12_ADSP2SPM_WAKEUP_B) | \
35 (R12_USBX_CDSC_B) | \
36 (R12_USBX_POWERDWN_B) | \
37 (R12_SYS_TIMER_EVENT_B) | \
38 (R12_EINT_EVENT_SECURE_B) | \
39 (R12_ECE_INT_HDMI_B) | \
40 (R12_AFE_IRQ_MCU_B) | \
41 (R12_SYS_CIRQ_IRQ_B) | \
42 (R12_PCIE_WAKEUPEVENT_B) | \
43 (R12_SPM_CPU_WAKEUPEVENT_B) | \
44 (R12_APUSYS_WAKE_HOST_B))
45
46#if defined(CFG_MICROTRUST_TEE_SUPPORT)
47#define WAKE_SRC_FOR_IDLE (__WAKE_SRC_FOR_IDLE_COMMON__)
48#else
49#define WAKE_SRC_FOR_IDLE (__WAKE_SRC_FOR_IDLE_COMMON__ | R12_SEJ_EVENT_B)
50#endif
51
52static struct pwr_ctrl idle_spm_pwr = {
53 .wake_src = WAKE_SRC_FOR_IDLE,
54
55 /* SPM_AP_STANDBY_CON */
56 /* [0] */
57 .reg_wfi_op = 0,
58 /* [1] */
59 .reg_wfi_type = 0,
60 /* [2] */
61 .reg_mp0_cputop_idle_mask = 0,
62 /* [3] */
63 .reg_mp1_cputop_idle_mask = 0,
64 /* [4] */
65 .reg_mcusys_idle_mask = 0,
66 /* [25] */
67 .reg_md_apsrc_1_sel = 0,
68 /* [26] */
69 .reg_md_apsrc_0_sel = 0,
70 /* [29] */
71 .reg_conn_apsrc_sel = 0,
72
73 /* SPM_SRC_REQ */
74 /* [0] */
75 .reg_spm_apsrc_req = 0,
76 /* [1] */
77 .reg_spm_f26m_req = 0,
78 /* [3] */
79 .reg_spm_infra_req = 0,
80 /* [4] */
81 .reg_spm_vrf18_req = 0,
82 /* [7] */
83 .reg_spm_ddr_en_req = 0,
84 /* [8] */
85 .reg_spm_dvfs_req = 0,
86 /* [9] */
87 .reg_spm_sw_mailbox_req = 0,
88 /* [10] */
89 .reg_spm_sspm_mailbox_req = 0,
90 /* [11] */
91 .reg_spm_adsp_mailbox_req = 0,
92 /* [12] */
93 .reg_spm_scp_mailbox_req = 0,
94
95 /* SPM_SRC_MASK */
96 /* [0] */
97 .reg_sspm_srcclkena_0_mask_b = 1,
98 /* [1] */
99 .reg_sspm_infra_req_0_mask_b = 1,
100 /* [2] */
101 .reg_sspm_apsrc_req_0_mask_b = 1,
102 /* [3] */
103 .reg_sspm_vrf18_req_0_mask_b = 1,
104 /* [4] */
105 .reg_sspm_ddr_en_0_mask_b = 1,
106 /* [5] */
107 .reg_scp_srcclkena_mask_b = 1,
108 /* [6] */
109 .reg_scp_infra_req_mask_b = 1,
110 /* [7] */
111 .reg_scp_apsrc_req_mask_b = 1,
112 /* [8] */
113 .reg_scp_vrf18_req_mask_b = 1,
114 /* [9] */
115 .reg_scp_ddr_en_mask_b = 1,
116 /* [10] */
117 .reg_audio_dsp_srcclkena_mask_b = 1,
118 /* [11] */
119 .reg_audio_dsp_infra_req_mask_b = 1,
120 /* [12] */
121 .reg_audio_dsp_apsrc_req_mask_b = 1,
122 /* [13] */
123 .reg_audio_dsp_vrf18_req_mask_b = 1,
124 /* [14] */
125 .reg_audio_dsp_ddr_en_mask_b = 1,
126 /* [15] */
127 .reg_apu_srcclkena_mask_b = 1,
128 /* [16] */
129 .reg_apu_infra_req_mask_b = 1,
130 /* [17] */
131 .reg_apu_apsrc_req_mask_b = 1,
132 /* [18] */
133 .reg_apu_vrf18_req_mask_b = 1,
134 /* [19] */
135 .reg_apu_ddr_en_mask_b = 1,
136 /* [20] */
137 .reg_cpueb_srcclkena_mask_b = 1,
138 /* [21] */
139 .reg_cpueb_infra_req_mask_b = 1,
140 /* [22] */
141 .reg_cpueb_apsrc_req_mask_b = 1,
142 /* [23] */
143 .reg_cpueb_vrf18_req_mask_b = 1,
144 /* [24] */
145 .reg_cpueb_ddr_en_mask_b = 1,
146 /* [25] */
147 .reg_bak_psri_srcclkena_mask_b = 0,
148 /* [26] */
149 .reg_bak_psri_infra_req_mask_b = 0,
150 /* [27] */
151 .reg_bak_psri_apsrc_req_mask_b = 0,
152 /* [28] */
153 .reg_bak_psri_vrf18_req_mask_b = 0,
154 /* [29] */
155 .reg_bak_psri_ddr_en_mask_b = 0,
156 /* [30] */
157 .reg_cam_ddren_req_mask_b = 1,
158 /* [31] */
159 .reg_img_ddren_req_mask_b = 1,
160
161 /* SPM_SRC2_MASK */
162 /* [0] */
163 .reg_msdc0_srcclkena_mask_b = 1,
164 /* [1] */
165 .reg_msdc0_infra_req_mask_b = 1,
166 /* [2] */
167 .reg_msdc0_apsrc_req_mask_b = 1,
168 /* [3] */
169 .reg_msdc0_vrf18_req_mask_b = 1,
170 /* [4] */
171 .reg_msdc0_ddr_en_mask_b = 1,
172 /* [5] */
173 .reg_msdc1_srcclkena_mask_b = 1,
174 /* [6] */
175 .reg_msdc1_infra_req_mask_b = 1,
176 /* [7] */
177 .reg_msdc1_apsrc_req_mask_b = 1,
178 /* [8] */
179 .reg_msdc1_vrf18_req_mask_b = 1,
180 /* [9] */
181 .reg_msdc1_ddr_en_mask_b = 1,
182 /* [10] */
183 .reg_msdc2_srcclkena_mask_b = 1,
184 /* [11] */
185 .reg_msdc2_infra_req_mask_b = 1,
186 /* [12] */
187 .reg_msdc2_apsrc_req_mask_b = 1,
188 /* [13] */
189 .reg_msdc2_vrf18_req_mask_b = 1,
190 /* [14] */
191 .reg_msdc2_ddr_en_mask_b = 1,
192 /* [15] */
193 .reg_ufs_srcclkena_mask_b = 1,
194 /* [16] */
195 .reg_ufs_infra_req_mask_b = 1,
196 /* [17] */
197 .reg_ufs_apsrc_req_mask_b = 1,
198 /* [18] */
199 .reg_ufs_vrf18_req_mask_b = 1,
200 /* [19] */
201 .reg_ufs_ddr_en_mask_b = 1,
202 /* [20] */
203 .reg_usb_srcclkena_mask_b = 1,
204 /* [21] */
205 .reg_usb_infra_req_mask_b = 1,
206 /* [22] */
207 .reg_usb_apsrc_req_mask_b = 1,
208 /* [23] */
209 .reg_usb_vrf18_req_mask_b = 1,
210 /* [24] */
211 .reg_usb_ddr_en_mask_b = 1,
212 /* [25] */
213 .reg_pextp_p0_srcclkena_mask_b = 1,
214 /* [26] */
215 .reg_pextp_p0_infra_req_mask_b = 1,
216 /* [27] */
217 .reg_pextp_p0_apsrc_req_mask_b = 1,
218 /* [28] */
219 .reg_pextp_p0_vrf18_req_mask_b = 1,
220 /* [29] */
221 .reg_pextp_p0_ddr_en_mask_b = 1,
222
223 /* SPM_SRC3_MASK */
224 /* [0] */
225 .reg_pextp_p1_srcclkena_mask_b = 1,
226 /* [1] */
227 .reg_pextp_p1_infra_req_mask_b = 1,
228 /* [2] */
229 .reg_pextp_p1_apsrc_req_mask_b = 1,
230 /* [3] */
231 .reg_pextp_p1_vrf18_req_mask_b = 1,
232 /* [4] */
233 .reg_pextp_p1_ddr_en_mask_b = 1,
234 /* [5] */
235 .reg_gce0_infra_req_mask_b = 1,
236 /* [6] */
237 .reg_gce0_apsrc_req_mask_b = 1,
238 /* [7] */
239 .reg_gce0_vrf18_req_mask_b = 1,
240 /* [8] */
241 .reg_gce0_ddr_en_mask_b = 1,
242 /* [9] */
243 .reg_gce1_infra_req_mask_b = 1,
244 /* [10] */
245 .reg_gce1_apsrc_req_mask_b = 1,
246 /* [11] */
247 .reg_gce1_vrf18_req_mask_b = 1,
248 /* [12] */
249 .reg_gce1_ddr_en_mask_b = 1,
250 /* [13] */
251 .reg_spm_srcclkena_reserved_mask_b = 1,
252 /* [14] */
253 .reg_spm_infra_req_reserved_mask_b = 1,
254 /* [15] */
255 .reg_spm_apsrc_req_reserved_mask_b = 1,
256 /* [16] */
257 .reg_spm_vrf18_req_reserved_mask_b = 1,
258 /* [17] */
259 .reg_spm_ddr_en_reserved_mask_b = 1,
260 /* [18] */
261 .reg_disp0_apsrc_req_mask_b = 1,
262 /* [19] */
263 .reg_disp0_ddr_en_mask_b = 1,
264 /* [20] */
265 .reg_disp1_apsrc_req_mask_b = 1,
266 /* [21] */
267 .reg_disp1_ddr_en_mask_b = 1,
268 /* [22] */
269 .reg_disp2_apsrc_req_mask_b = 1,
270 /* [23] */
271 .reg_disp2_ddr_en_mask_b = 1,
272 /* [24] */
273 .reg_disp3_apsrc_req_mask_b = 1,
274 /* [25] */
275 .reg_disp3_ddr_en_mask_b = 1,
276 /* [26] */
277 .reg_infrasys_apsrc_req_mask_b = 0,
278 /* [27] */
279 .reg_infrasys_ddr_en_mask_b = 1,
280
281 /* [28] */
282 .reg_cg_check_srcclkena_mask_b = 1,
283 /* [29] */
284 .reg_cg_check_apsrc_req_mask_b = 1,
285 /* [30] */
286 .reg_cg_check_vrf18_req_mask_b = 1,
287 /* [31] */
288 .reg_cg_check_ddr_en_mask_b = 1,
289
290 /* SPM_SRC4_MASK */
291 /* [8:0] */
292 .reg_mcusys_merge_apsrc_req_mask_b = 0,
293 /* [17:9] */
294 .reg_mcusys_merge_ddr_en_mask_b = 0,
295 /* [19:18] */
296 .reg_dramc_md32_infra_req_mask_b = 3,
297 /* [21:20] */
298 .reg_dramc_md32_vrf18_req_mask_b = 3,
299 /* [23:22] */
300 .reg_dramc_md32_ddr_en_mask_b = 0,
301 /* [24] */
302 .reg_dvfsrc_event_trigger_mask_b = 1,
303
304 /* SPM_WAKEUP_EVENT_MASK2 */
305 /* [3:0] */
306 .reg_sc_sw2spm_wakeup_mask_b = 0,
307 /* [4] */
308 .reg_sc_adsp2spm_wakeup_mask_b = 0,
309 /* [8:5] */
310 .reg_sc_sspm2spm_wakeup_mask_b = 0,
311 /* [9] */
312 .reg_sc_scp2spm_wakeup_mask_b = 0,
313 /* [10] */
314 .reg_csyspwrup_ack_mask = 0,
315 /* [11] */
316 .reg_csyspwrup_req_mask = 1,
317
318 /* SPM_WAKEUP_EVENT_MASK */
319 /* [31:0] */
320 .reg_wakeup_event_mask = 0xC1282203,
321
322 /* SPM_WAKEUP_EVENT_EXT_MASK */
323 /* [31:0] */
324 .reg_ext_wakeup_event_mask = 0xFFFFFFFF,
325};
326
327struct spm_lp_scen idle_spm_lp = {
328 .pwrctrl = &idle_spm_pwr,
329};
330
331int mt_spm_idle_generic_enter(int state_id, unsigned int ext_opand, spm_idle_conduct fn)
332{
333 int ret = 0;
334 unsigned int src_req = 0U;
335
336 if (fn != NULL) {
337 fn(state_id, &idle_spm_lp, &src_req);
338 }
339
340 ret = spm_conservation(state_id, ext_opand, &idle_spm_lp, src_req);
341
342 if (ret == 0) {
343 struct mt_lp_publish_event event = {
344 .id = MT_LPM_PUBEVENTS_SYS_POWER_OFF,
345 .val.u32 = 0U,
346 };
347
348 MT_LP_PUBLISH_EVENT(&event);
349 }
350 return ret;
351}
352
353void mt_spm_idle_generic_resume(int state_id, unsigned int ext_opand,
354 struct wake_status **status,
355 spm_idle_conduct_restore fn)
356{
357 struct mt_lp_publish_event event = {
358 .id = MT_LPM_PUBEVENTS_SYS_POWER_ON,
359 .val.u32 = 0U,
360 };
361
362 ext_opand |= (MT_SPM_EX_OP_TIME_CHECK | MT_SPM_EX_OP_TIME_OBS);
363 spm_conservation_finish(state_id, ext_opand, &idle_spm_lp, status);
364
365 if (spm_unlikely(fn)) {
366 fn(state_id, &idle_spm_lp, *status);
367 }
368 MT_LP_PUBLISH_EVENT(&event);
369}