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