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