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