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