xref: /arm-trusted-firmware/plat/nxp/common/psci/plat_psci.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright 2018-2020 NXP
3*91f16700Schasinglulu  *
4*91f16700Schasinglulu  * SPDX-License-Identifier: BSD-3-Clause
5*91f16700Schasinglulu  *
6*91f16700Schasinglulu  */
7*91f16700Schasinglulu 
8*91f16700Schasinglulu #include <common/debug.h>
9*91f16700Schasinglulu 
10*91f16700Schasinglulu #include <plat_gic.h>
11*91f16700Schasinglulu #include <plat_common.h>
12*91f16700Schasinglulu #include <plat_psci.h>
13*91f16700Schasinglulu #ifdef NXP_WARM_BOOT
14*91f16700Schasinglulu #include <plat_warm_rst.h>
15*91f16700Schasinglulu #endif
16*91f16700Schasinglulu 
17*91f16700Schasinglulu #include <platform_def.h>
18*91f16700Schasinglulu 
19*91f16700Schasinglulu #if (SOC_CORE_OFF || SOC_CORE_PWR_DWN)
20*91f16700Schasinglulu static void __dead2 _no_return_wfi(void)
21*91f16700Schasinglulu {
22*91f16700Schasinglulu _bl31_dead_wfi:
23*91f16700Schasinglulu 	wfi();
24*91f16700Schasinglulu 	goto _bl31_dead_wfi;
25*91f16700Schasinglulu }
26*91f16700Schasinglulu #endif
27*91f16700Schasinglulu 
28*91f16700Schasinglulu #if (SOC_CORE_RELEASE || SOC_CORE_PWR_DWN)
29*91f16700Schasinglulu  /* the entry for core warm boot */
30*91f16700Schasinglulu static uintptr_t warmboot_entry = (uintptr_t) NULL;
31*91f16700Schasinglulu #endif
32*91f16700Schasinglulu 
33*91f16700Schasinglulu #if (SOC_CORE_RELEASE)
34*91f16700Schasinglulu static int _pwr_domain_on(u_register_t mpidr)
35*91f16700Schasinglulu {
36*91f16700Schasinglulu 	int core_pos = plat_core_pos(mpidr);
37*91f16700Schasinglulu 	int rc = PSCI_E_INVALID_PARAMS;
38*91f16700Schasinglulu 	u_register_t core_mask;
39*91f16700Schasinglulu 
40*91f16700Schasinglulu 	if (core_pos >= 0 && core_pos < PLATFORM_CORE_COUNT) {
41*91f16700Schasinglulu 
42*91f16700Schasinglulu 		_soc_set_start_addr(warmboot_entry);
43*91f16700Schasinglulu 
44*91f16700Schasinglulu 		dsb();
45*91f16700Schasinglulu 		isb();
46*91f16700Schasinglulu 
47*91f16700Schasinglulu 		core_mask = (1 << core_pos);
48*91f16700Schasinglulu 		rc = _psci_cpu_on(core_mask);
49*91f16700Schasinglulu 	}
50*91f16700Schasinglulu 
51*91f16700Schasinglulu 	return (rc);
52*91f16700Schasinglulu }
53*91f16700Schasinglulu #endif
54*91f16700Schasinglulu 
55*91f16700Schasinglulu #if (SOC_CORE_OFF)
56*91f16700Schasinglulu static void _pwr_domain_off(const psci_power_state_t *target_state)
57*91f16700Schasinglulu {
58*91f16700Schasinglulu 	u_register_t core_mask  = plat_my_core_mask();
59*91f16700Schasinglulu 	u_register_t core_state = _getCoreState(core_mask);
60*91f16700Schasinglulu 
61*91f16700Schasinglulu 	 /* set core state in internal data */
62*91f16700Schasinglulu 	core_state = CORE_OFF_PENDING;
63*91f16700Schasinglulu 	_setCoreState(core_mask, core_state);
64*91f16700Schasinglulu 
65*91f16700Schasinglulu 	_psci_cpu_prep_off(core_mask);
66*91f16700Schasinglulu }
67*91f16700Schasinglulu #endif
68*91f16700Schasinglulu 
69*91f16700Schasinglulu #if (SOC_CORE_OFF || SOC_CORE_PWR_DWN)
70*91f16700Schasinglulu static void __dead2 _pwr_down_wfi(const psci_power_state_t *target_state)
71*91f16700Schasinglulu {
72*91f16700Schasinglulu 	u_register_t core_mask  = plat_my_core_mask();
73*91f16700Schasinglulu 	u_register_t core_state = _getCoreState(core_mask);
74*91f16700Schasinglulu 
75*91f16700Schasinglulu 	switch (core_state) {
76*91f16700Schasinglulu #if (SOC_CORE_OFF)
77*91f16700Schasinglulu 	case CORE_OFF_PENDING:
78*91f16700Schasinglulu 		/* set core state in internal data */
79*91f16700Schasinglulu 		core_state = CORE_OFF;
80*91f16700Schasinglulu 		_setCoreState(core_mask, core_state);
81*91f16700Schasinglulu 
82*91f16700Schasinglulu 		 /* turn the core off */
83*91f16700Schasinglulu 		_psci_cpu_off_wfi(core_mask, warmboot_entry);
84*91f16700Schasinglulu 	break;
85*91f16700Schasinglulu #endif
86*91f16700Schasinglulu #if (SOC_CORE_PWR_DWN)
87*91f16700Schasinglulu 	case CORE_PWR_DOWN:
88*91f16700Schasinglulu 		 /* power-down the core */
89*91f16700Schasinglulu 		_psci_cpu_pwrdn_wfi(core_mask, warmboot_entry);
90*91f16700Schasinglulu 		break;
91*91f16700Schasinglulu #endif
92*91f16700Schasinglulu #if (SOC_SYSTEM_PWR_DWN)
93*91f16700Schasinglulu 	case SYS_OFF_PENDING:
94*91f16700Schasinglulu 		/* set core state in internal data */
95*91f16700Schasinglulu 		core_state = SYS_OFF;
96*91f16700Schasinglulu 		_setCoreState(core_mask, core_state);
97*91f16700Schasinglulu 
98*91f16700Schasinglulu 		/* power-down the system */
99*91f16700Schasinglulu 		_psci_sys_pwrdn_wfi(core_mask, warmboot_entry);
100*91f16700Schasinglulu 		break;
101*91f16700Schasinglulu #endif
102*91f16700Schasinglulu 	default:
103*91f16700Schasinglulu 		_no_return_wfi();
104*91f16700Schasinglulu 	break;
105*91f16700Schasinglulu 	}
106*91f16700Schasinglulu }
107*91f16700Schasinglulu #endif
108*91f16700Schasinglulu 
109*91f16700Schasinglulu #if (SOC_CORE_RELEASE || SOC_CORE_RESTART)
110*91f16700Schasinglulu static void _pwr_domain_wakeup(const psci_power_state_t *target_state)
111*91f16700Schasinglulu {
112*91f16700Schasinglulu 	u_register_t core_mask  = plat_my_core_mask();
113*91f16700Schasinglulu 	u_register_t core_state = _getCoreState(core_mask);
114*91f16700Schasinglulu 
115*91f16700Schasinglulu 	switch (core_state) {
116*91f16700Schasinglulu 	case CORE_PENDING: /* this core is coming out of reset */
117*91f16700Schasinglulu 
118*91f16700Schasinglulu 		 /* soc per cpu setup */
119*91f16700Schasinglulu 		soc_init_percpu();
120*91f16700Schasinglulu 
121*91f16700Schasinglulu 		 /* gic per cpu setup */
122*91f16700Schasinglulu 		plat_gic_pcpu_init();
123*91f16700Schasinglulu 
124*91f16700Schasinglulu 		 /* set core state in internal data */
125*91f16700Schasinglulu 		core_state = CORE_RELEASED;
126*91f16700Schasinglulu 		_setCoreState(core_mask, core_state);
127*91f16700Schasinglulu 		break;
128*91f16700Schasinglulu 
129*91f16700Schasinglulu #if (SOC_CORE_RESTART)
130*91f16700Schasinglulu 	case CORE_WAKEUP:
131*91f16700Schasinglulu 
132*91f16700Schasinglulu 		 /* this core is waking up from OFF */
133*91f16700Schasinglulu 		_psci_wakeup(core_mask);
134*91f16700Schasinglulu 
135*91f16700Schasinglulu 		 /* set core state in internal data */
136*91f16700Schasinglulu 		core_state = CORE_RELEASED;
137*91f16700Schasinglulu 		_setCoreState(core_mask, core_state);
138*91f16700Schasinglulu 
139*91f16700Schasinglulu 	break;
140*91f16700Schasinglulu #endif
141*91f16700Schasinglulu 	}
142*91f16700Schasinglulu }
143*91f16700Schasinglulu #endif
144*91f16700Schasinglulu 
145*91f16700Schasinglulu #if (SOC_CORE_STANDBY)
146*91f16700Schasinglulu static void _pwr_cpu_standby(plat_local_state_t  cpu_state)
147*91f16700Schasinglulu {
148*91f16700Schasinglulu 	u_register_t core_mask  = plat_my_core_mask();
149*91f16700Schasinglulu 	u_register_t core_state;
150*91f16700Schasinglulu 
151*91f16700Schasinglulu 	if (cpu_state == PLAT_MAX_RET_STATE) {
152*91f16700Schasinglulu 
153*91f16700Schasinglulu 		/* set core state to standby */
154*91f16700Schasinglulu 		core_state = CORE_STANDBY;
155*91f16700Schasinglulu 		_setCoreState(core_mask, core_state);
156*91f16700Schasinglulu 
157*91f16700Schasinglulu 		_psci_core_entr_stdby(core_mask);
158*91f16700Schasinglulu 
159*91f16700Schasinglulu 		/* when we are here, the core is waking up
160*91f16700Schasinglulu 		 * set core state to released
161*91f16700Schasinglulu 		 */
162*91f16700Schasinglulu 		core_state = CORE_RELEASED;
163*91f16700Schasinglulu 		_setCoreState(core_mask, core_state);
164*91f16700Schasinglulu 	}
165*91f16700Schasinglulu }
166*91f16700Schasinglulu #endif
167*91f16700Schasinglulu 
168*91f16700Schasinglulu #if (SOC_CORE_PWR_DWN)
169*91f16700Schasinglulu static void _pwr_suspend(const psci_power_state_t *state)
170*91f16700Schasinglulu {
171*91f16700Schasinglulu 
172*91f16700Schasinglulu 	u_register_t core_mask  = plat_my_core_mask();
173*91f16700Schasinglulu 	u_register_t core_state;
174*91f16700Schasinglulu 
175*91f16700Schasinglulu 	if (state->pwr_domain_state[PLAT_MAX_LVL] == PLAT_MAX_OFF_STATE) {
176*91f16700Schasinglulu #if (SOC_SYSTEM_PWR_DWN)
177*91f16700Schasinglulu 		_psci_sys_prep_pwrdn(core_mask);
178*91f16700Schasinglulu 
179*91f16700Schasinglulu 		 /* set core state */
180*91f16700Schasinglulu 		core_state = SYS_OFF_PENDING;
181*91f16700Schasinglulu 		_setCoreState(core_mask, core_state);
182*91f16700Schasinglulu #endif
183*91f16700Schasinglulu 	} else if (state->pwr_domain_state[PLAT_MAX_LVL]
184*91f16700Schasinglulu 				== PLAT_MAX_RET_STATE) {
185*91f16700Schasinglulu #if (SOC_SYSTEM_STANDBY)
186*91f16700Schasinglulu 		_psci_sys_prep_stdby(core_mask);
187*91f16700Schasinglulu 
188*91f16700Schasinglulu 		 /* set core state */
189*91f16700Schasinglulu 		core_state = CORE_STANDBY;
190*91f16700Schasinglulu 		_setCoreState(core_mask, core_state);
191*91f16700Schasinglulu #endif
192*91f16700Schasinglulu 	}
193*91f16700Schasinglulu 
194*91f16700Schasinglulu 	else if (state->pwr_domain_state[PLAT_CLSTR_LVL] ==
195*91f16700Schasinglulu 					PLAT_MAX_OFF_STATE) {
196*91f16700Schasinglulu #if (SOC_CLUSTER_PWR_DWN)
197*91f16700Schasinglulu 		_psci_clstr_prep_pwrdn(core_mask);
198*91f16700Schasinglulu 
199*91f16700Schasinglulu 		 /* set core state */
200*91f16700Schasinglulu 		core_state = CORE_PWR_DOWN;
201*91f16700Schasinglulu 		_setCoreState(core_mask, core_state);
202*91f16700Schasinglulu #endif
203*91f16700Schasinglulu 	}
204*91f16700Schasinglulu 
205*91f16700Schasinglulu 	else if (state->pwr_domain_state[PLAT_CLSTR_LVL] ==
206*91f16700Schasinglulu 					PLAT_MAX_RET_STATE) {
207*91f16700Schasinglulu #if (SOC_CLUSTER_STANDBY)
208*91f16700Schasinglulu 		_psci_clstr_prep_stdby(core_mask);
209*91f16700Schasinglulu 
210*91f16700Schasinglulu 		 /* set core state */
211*91f16700Schasinglulu 		core_state = CORE_STANDBY;
212*91f16700Schasinglulu 		_setCoreState(core_mask, core_state);
213*91f16700Schasinglulu #endif
214*91f16700Schasinglulu 	}
215*91f16700Schasinglulu 
216*91f16700Schasinglulu 	else if (state->pwr_domain_state[PLAT_CORE_LVL] == PLAT_MAX_OFF_STATE) {
217*91f16700Schasinglulu #if (SOC_CORE_PWR_DWN)
218*91f16700Schasinglulu 		 /* prep the core for power-down */
219*91f16700Schasinglulu 		_psci_core_prep_pwrdn(core_mask);
220*91f16700Schasinglulu 
221*91f16700Schasinglulu 		 /* set core state */
222*91f16700Schasinglulu 		core_state = CORE_PWR_DOWN;
223*91f16700Schasinglulu 		_setCoreState(core_mask, core_state);
224*91f16700Schasinglulu #endif
225*91f16700Schasinglulu 	}
226*91f16700Schasinglulu 
227*91f16700Schasinglulu 	else if (state->pwr_domain_state[PLAT_CORE_LVL] == PLAT_MAX_RET_STATE) {
228*91f16700Schasinglulu #if (SOC_CORE_STANDBY)
229*91f16700Schasinglulu 		_psci_core_prep_stdby(core_mask);
230*91f16700Schasinglulu 
231*91f16700Schasinglulu 		 /* set core state */
232*91f16700Schasinglulu 		core_state = CORE_STANDBY;
233*91f16700Schasinglulu 		_setCoreState(core_mask, core_state);
234*91f16700Schasinglulu #endif
235*91f16700Schasinglulu 	}
236*91f16700Schasinglulu 
237*91f16700Schasinglulu }
238*91f16700Schasinglulu #endif
239*91f16700Schasinglulu 
240*91f16700Schasinglulu #if (SOC_CORE_PWR_DWN)
241*91f16700Schasinglulu static void _pwr_suspend_finish(const psci_power_state_t *state)
242*91f16700Schasinglulu {
243*91f16700Schasinglulu 
244*91f16700Schasinglulu 	u_register_t core_mask  = plat_my_core_mask();
245*91f16700Schasinglulu 	u_register_t core_state;
246*91f16700Schasinglulu 
247*91f16700Schasinglulu 
248*91f16700Schasinglulu 	if (state->pwr_domain_state[PLAT_MAX_LVL] == PLAT_MAX_OFF_STATE) {
249*91f16700Schasinglulu #if (SOC_SYSTEM_PWR_DWN)
250*91f16700Schasinglulu 		_psci_sys_exit_pwrdn(core_mask);
251*91f16700Schasinglulu 
252*91f16700Schasinglulu 		/* when we are here, the core is back up
253*91f16700Schasinglulu 		 * set core state to released
254*91f16700Schasinglulu 		 */
255*91f16700Schasinglulu 		core_state = CORE_RELEASED;
256*91f16700Schasinglulu 		_setCoreState(core_mask, core_state);
257*91f16700Schasinglulu #endif
258*91f16700Schasinglulu 	} else if (state->pwr_domain_state[PLAT_MAX_LVL]
259*91f16700Schasinglulu 				== PLAT_MAX_RET_STATE) {
260*91f16700Schasinglulu #if (SOC_SYSTEM_STANDBY)
261*91f16700Schasinglulu 		_psci_sys_exit_stdby(core_mask);
262*91f16700Schasinglulu 
263*91f16700Schasinglulu 		/* when we are here, the core is waking up
264*91f16700Schasinglulu 		 * set core state to released
265*91f16700Schasinglulu 		 */
266*91f16700Schasinglulu 		core_state = CORE_RELEASED;
267*91f16700Schasinglulu 		_setCoreState(core_mask, core_state);
268*91f16700Schasinglulu #endif
269*91f16700Schasinglulu 	}
270*91f16700Schasinglulu 
271*91f16700Schasinglulu 	else if (state->pwr_domain_state[PLAT_CLSTR_LVL] ==
272*91f16700Schasinglulu 						PLAT_MAX_OFF_STATE) {
273*91f16700Schasinglulu #if (SOC_CLUSTER_PWR_DWN)
274*91f16700Schasinglulu 		_psci_clstr_exit_pwrdn(core_mask);
275*91f16700Schasinglulu 
276*91f16700Schasinglulu 		/* when we are here, the core is waking up
277*91f16700Schasinglulu 		 * set core state to released
278*91f16700Schasinglulu 		 */
279*91f16700Schasinglulu 		core_state = CORE_RELEASED;
280*91f16700Schasinglulu 		_setCoreState(core_mask, core_state);
281*91f16700Schasinglulu #endif
282*91f16700Schasinglulu 	}
283*91f16700Schasinglulu 
284*91f16700Schasinglulu 	else if (state->pwr_domain_state[PLAT_CLSTR_LVL] ==
285*91f16700Schasinglulu 						PLAT_MAX_RET_STATE) {
286*91f16700Schasinglulu #if (SOC_CLUSTER_STANDBY)
287*91f16700Schasinglulu 		_psci_clstr_exit_stdby(core_mask);
288*91f16700Schasinglulu 
289*91f16700Schasinglulu 		/* when we are here, the core is waking up
290*91f16700Schasinglulu 		 * set core state to released
291*91f16700Schasinglulu 		 */
292*91f16700Schasinglulu 		core_state = CORE_RELEASED;
293*91f16700Schasinglulu 		_setCoreState(core_mask, core_state);
294*91f16700Schasinglulu #endif
295*91f16700Schasinglulu 	}
296*91f16700Schasinglulu 
297*91f16700Schasinglulu 	else if (state->pwr_domain_state[PLAT_CORE_LVL] == PLAT_MAX_OFF_STATE) {
298*91f16700Schasinglulu #if (SOC_CORE_PWR_DWN)
299*91f16700Schasinglulu 		_psci_core_exit_pwrdn(core_mask);
300*91f16700Schasinglulu 
301*91f16700Schasinglulu 		/* when we are here, the core is back up
302*91f16700Schasinglulu 		 * set core state to released
303*91f16700Schasinglulu 		 */
304*91f16700Schasinglulu 		core_state = CORE_RELEASED;
305*91f16700Schasinglulu 		_setCoreState(core_mask, core_state);
306*91f16700Schasinglulu #endif
307*91f16700Schasinglulu 	}
308*91f16700Schasinglulu 
309*91f16700Schasinglulu 	else if (state->pwr_domain_state[PLAT_CORE_LVL] == PLAT_MAX_RET_STATE) {
310*91f16700Schasinglulu #if (SOC_CORE_STANDBY)
311*91f16700Schasinglulu 		_psci_core_exit_stdby(core_mask);
312*91f16700Schasinglulu 
313*91f16700Schasinglulu 		/* when we are here, the core is waking up
314*91f16700Schasinglulu 		 * set core state to released
315*91f16700Schasinglulu 		 */
316*91f16700Schasinglulu 		core_state = CORE_RELEASED;
317*91f16700Schasinglulu 		_setCoreState(core_mask, core_state);
318*91f16700Schasinglulu #endif
319*91f16700Schasinglulu 	}
320*91f16700Schasinglulu 
321*91f16700Schasinglulu }
322*91f16700Schasinglulu #endif
323*91f16700Schasinglulu 
324*91f16700Schasinglulu #if (SOC_CORE_STANDBY || SOC_CORE_PWR_DWN)
325*91f16700Schasinglulu 
326*91f16700Schasinglulu #define PWR_STATE_TYPE_MASK    0x00010000
327*91f16700Schasinglulu #define PWR_STATE_TYPE_STNDBY  0x0
328*91f16700Schasinglulu #define PWR_STATE_TYPE_PWRDWN  0x00010000
329*91f16700Schasinglulu #define PWR_STATE_LVL_MASK     0x03000000
330*91f16700Schasinglulu #define PWR_STATE_LVL_CORE     0x0
331*91f16700Schasinglulu #define PWR_STATE_LVL_CLSTR    0x01000000
332*91f16700Schasinglulu #define PWR_STATE_LVL_SYS      0x02000000
333*91f16700Schasinglulu #define PWR_STATE_LVL_MAX      0x03000000
334*91f16700Schasinglulu 
335*91f16700Schasinglulu  /* turns a requested power state into a target power state
336*91f16700Schasinglulu   * based on SoC capabilities
337*91f16700Schasinglulu   */
338*91f16700Schasinglulu static int _pwr_state_validate(uint32_t pwr_state,
339*91f16700Schasinglulu 				    psci_power_state_t *state)
340*91f16700Schasinglulu {
341*91f16700Schasinglulu 	int stat   = PSCI_E_INVALID_PARAMS;
342*91f16700Schasinglulu 	int pwrdn  = (pwr_state & PWR_STATE_TYPE_MASK);
343*91f16700Schasinglulu 	int lvl    = (pwr_state & PWR_STATE_LVL_MASK);
344*91f16700Schasinglulu 
345*91f16700Schasinglulu 	switch (lvl) {
346*91f16700Schasinglulu 	case PWR_STATE_LVL_MAX:
347*91f16700Schasinglulu 		if (pwrdn && SOC_SYSTEM_PWR_DWN)
348*91f16700Schasinglulu 			state->pwr_domain_state[PLAT_MAX_LVL] =
349*91f16700Schasinglulu 				PLAT_MAX_OFF_STATE;
350*91f16700Schasinglulu 		else if (SOC_SYSTEM_STANDBY)
351*91f16700Schasinglulu 			state->pwr_domain_state[PLAT_MAX_LVL] =
352*91f16700Schasinglulu 				PLAT_MAX_RET_STATE;
353*91f16700Schasinglulu 		 /* fallthrough */
354*91f16700Schasinglulu 	case PWR_STATE_LVL_SYS:
355*91f16700Schasinglulu 		if (pwrdn && SOC_SYSTEM_PWR_DWN)
356*91f16700Schasinglulu 			state->pwr_domain_state[PLAT_SYS_LVL] =
357*91f16700Schasinglulu 				PLAT_MAX_OFF_STATE;
358*91f16700Schasinglulu 		else if (SOC_SYSTEM_STANDBY)
359*91f16700Schasinglulu 			state->pwr_domain_state[PLAT_SYS_LVL] =
360*91f16700Schasinglulu 				PLAT_MAX_RET_STATE;
361*91f16700Schasinglulu 		 /* fallthrough */
362*91f16700Schasinglulu 	case PWR_STATE_LVL_CLSTR:
363*91f16700Schasinglulu 		if (pwrdn && SOC_CLUSTER_PWR_DWN)
364*91f16700Schasinglulu 			state->pwr_domain_state[PLAT_CLSTR_LVL] =
365*91f16700Schasinglulu 				PLAT_MAX_OFF_STATE;
366*91f16700Schasinglulu 		else if (SOC_CLUSTER_STANDBY)
367*91f16700Schasinglulu 			state->pwr_domain_state[PLAT_CLSTR_LVL] =
368*91f16700Schasinglulu 				PLAT_MAX_RET_STATE;
369*91f16700Schasinglulu 		 /* fallthrough */
370*91f16700Schasinglulu 	case PWR_STATE_LVL_CORE:
371*91f16700Schasinglulu 		stat = PSCI_E_SUCCESS;
372*91f16700Schasinglulu 
373*91f16700Schasinglulu 		if (pwrdn && SOC_CORE_PWR_DWN)
374*91f16700Schasinglulu 			state->pwr_domain_state[PLAT_CORE_LVL] =
375*91f16700Schasinglulu 				PLAT_MAX_OFF_STATE;
376*91f16700Schasinglulu 		else if (SOC_CORE_STANDBY)
377*91f16700Schasinglulu 			state->pwr_domain_state[PLAT_CORE_LVL] =
378*91f16700Schasinglulu 				PLAT_MAX_RET_STATE;
379*91f16700Schasinglulu 		break;
380*91f16700Schasinglulu 	}
381*91f16700Schasinglulu 	return (stat);
382*91f16700Schasinglulu }
383*91f16700Schasinglulu 
384*91f16700Schasinglulu #endif
385*91f16700Schasinglulu 
386*91f16700Schasinglulu #if (SOC_SYSTEM_PWR_DWN)
387*91f16700Schasinglulu static void _pwr_state_sys_suspend(psci_power_state_t *req_state)
388*91f16700Schasinglulu {
389*91f16700Schasinglulu 
390*91f16700Schasinglulu 	/* if we need to have per-SoC settings, then we need to
391*91f16700Schasinglulu 	 * extend this by calling into psci_utils.S and from there
392*91f16700Schasinglulu 	 * on down to the SoC.S files
393*91f16700Schasinglulu 	 */
394*91f16700Schasinglulu 
395*91f16700Schasinglulu 	req_state->pwr_domain_state[PLAT_MAX_LVL]   = PLAT_MAX_OFF_STATE;
396*91f16700Schasinglulu 	req_state->pwr_domain_state[PLAT_SYS_LVL]   = PLAT_MAX_OFF_STATE;
397*91f16700Schasinglulu 	req_state->pwr_domain_state[PLAT_CLSTR_LVL] = PLAT_MAX_OFF_STATE;
398*91f16700Schasinglulu 	req_state->pwr_domain_state[PLAT_CORE_LVL]  = PLAT_MAX_OFF_STATE;
399*91f16700Schasinglulu 
400*91f16700Schasinglulu }
401*91f16700Schasinglulu #endif
402*91f16700Schasinglulu 
403*91f16700Schasinglulu #if defined(NXP_WARM_BOOT) && (SOC_SYSTEM_RESET2)
404*91f16700Schasinglulu static int psci_system_reset2(int is_vendor,
405*91f16700Schasinglulu 			      int reset_type,
406*91f16700Schasinglulu 			      u_register_t cookie)
407*91f16700Schasinglulu {
408*91f16700Schasinglulu 	int ret = 0;
409*91f16700Schasinglulu 
410*91f16700Schasinglulu 	INFO("Executing the sequence of warm reset.\n");
411*91f16700Schasinglulu 	ret = prep_n_execute_warm_reset();
412*91f16700Schasinglulu 
413*91f16700Schasinglulu 	return ret;
414*91f16700Schasinglulu }
415*91f16700Schasinglulu #endif
416*91f16700Schasinglulu 
417*91f16700Schasinglulu static plat_psci_ops_t _psci_pm_ops = {
418*91f16700Schasinglulu #if (SOC_SYSTEM_OFF)
419*91f16700Schasinglulu 	.system_off = _psci_system_off,
420*91f16700Schasinglulu #endif
421*91f16700Schasinglulu #if (SOC_SYSTEM_RESET)
422*91f16700Schasinglulu 	.system_reset = _psci_system_reset,
423*91f16700Schasinglulu #endif
424*91f16700Schasinglulu #if defined(NXP_WARM_BOOT) && (SOC_SYSTEM_RESET2)
425*91f16700Schasinglulu 	.system_reset2 = psci_system_reset2,
426*91f16700Schasinglulu #endif
427*91f16700Schasinglulu #if (SOC_CORE_RELEASE || SOC_CORE_RESTART)
428*91f16700Schasinglulu 	 /* core released or restarted */
429*91f16700Schasinglulu 	.pwr_domain_on_finish = _pwr_domain_wakeup,
430*91f16700Schasinglulu #endif
431*91f16700Schasinglulu #if (SOC_CORE_OFF)
432*91f16700Schasinglulu 	 /* core shutting down */
433*91f16700Schasinglulu 	.pwr_domain_off	= _pwr_domain_off,
434*91f16700Schasinglulu #endif
435*91f16700Schasinglulu #if (SOC_CORE_OFF || SOC_CORE_PWR_DWN)
436*91f16700Schasinglulu 	.pwr_domain_pwr_down_wfi = _pwr_down_wfi,
437*91f16700Schasinglulu #endif
438*91f16700Schasinglulu #if (SOC_CORE_STANDBY || SOC_CORE_PWR_DWN)
439*91f16700Schasinglulu 	 /* cpu_suspend */
440*91f16700Schasinglulu 	.validate_power_state = _pwr_state_validate,
441*91f16700Schasinglulu #if (SOC_CORE_STANDBY)
442*91f16700Schasinglulu 	.cpu_standby = _pwr_cpu_standby,
443*91f16700Schasinglulu #endif
444*91f16700Schasinglulu #if (SOC_CORE_PWR_DWN)
445*91f16700Schasinglulu 	.pwr_domain_suspend        = _pwr_suspend,
446*91f16700Schasinglulu 	.pwr_domain_suspend_finish = _pwr_suspend_finish,
447*91f16700Schasinglulu #endif
448*91f16700Schasinglulu #endif
449*91f16700Schasinglulu #if (SOC_SYSTEM_PWR_DWN)
450*91f16700Schasinglulu 	.get_sys_suspend_power_state = _pwr_state_sys_suspend,
451*91f16700Schasinglulu #endif
452*91f16700Schasinglulu #if (SOC_CORE_RELEASE)
453*91f16700Schasinglulu 	 /* core executing psci_cpu_on */
454*91f16700Schasinglulu 	.pwr_domain_on	= _pwr_domain_on
455*91f16700Schasinglulu #endif
456*91f16700Schasinglulu };
457*91f16700Schasinglulu 
458*91f16700Schasinglulu #if (SOC_CORE_RELEASE  || SOC_CORE_PWR_DWN)
459*91f16700Schasinglulu int plat_setup_psci_ops(uintptr_t sec_entrypoint,
460*91f16700Schasinglulu 			const plat_psci_ops_t **psci_ops)
461*91f16700Schasinglulu {
462*91f16700Schasinglulu 	warmboot_entry = sec_entrypoint;
463*91f16700Schasinglulu 	*psci_ops = &_psci_pm_ops;
464*91f16700Schasinglulu 	return 0;
465*91f16700Schasinglulu }
466*91f16700Schasinglulu 
467*91f16700Schasinglulu #else
468*91f16700Schasinglulu 
469*91f16700Schasinglulu int plat_setup_psci_ops(uintptr_t sec_entrypoint,
470*91f16700Schasinglulu 			const plat_psci_ops_t **psci_ops)
471*91f16700Schasinglulu {
472*91f16700Schasinglulu 	*psci_ops = &_psci_pm_ops;
473*91f16700Schasinglulu 	return 0;
474*91f16700Schasinglulu }
475*91f16700Schasinglulu #endif
476