1 /*
2  * Copyright (c) 2013-2019, Arm Limited and Contributors. All rights reserved.
3  * Copyright (c) 2023, NVIDIA Corporation. All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #ifndef PSCI_H
9 #define PSCI_H
10 
11 #include <platform_def.h>	/* for PLAT_NUM_PWR_DOMAINS */
12 
13 #include <common/bl_common.h>
14 #include <lib/bakery_lock.h>
15 #include <lib/psci/psci_lib.h>	/* To maintain compatibility for SPDs */
16 #include <lib/utils_def.h>
17 
18 /*******************************************************************************
19  * Number of power domains whose state this PSCI implementation can track
20  ******************************************************************************/
21 #ifdef PLAT_NUM_PWR_DOMAINS
22 #define PSCI_NUM_PWR_DOMAINS	PLAT_NUM_PWR_DOMAINS
23 #else
24 #define PSCI_NUM_PWR_DOMAINS	(U(2) * PLATFORM_CORE_COUNT)
25 #endif
26 
27 #define PSCI_NUM_NON_CPU_PWR_DOMAINS	(PSCI_NUM_PWR_DOMAINS - \
28 					 PLATFORM_CORE_COUNT)
29 
30 /* This is the power level corresponding to a CPU */
31 #define PSCI_CPU_PWR_LVL	U(0)
32 
33 /*
34  * The maximum power level supported by PSCI. Since PSCI CPU_SUSPEND
35  * uses the old power_state parameter format which has 2 bits to specify the
36  * power level, this constant is defined to be 3.
37  */
38 #define PSCI_MAX_PWR_LVL	U(3)
39 
40 /*******************************************************************************
41  * Defines for runtime services function ids
42  ******************************************************************************/
43 #define PSCI_VERSION			U(0x84000000)
44 #define PSCI_CPU_SUSPEND_AARCH32	U(0x84000001)
45 #define PSCI_CPU_SUSPEND_AARCH64	U(0xc4000001)
46 #define PSCI_CPU_OFF			U(0x84000002)
47 #define PSCI_CPU_ON_AARCH32		U(0x84000003)
48 #define PSCI_CPU_ON_AARCH64		U(0xc4000003)
49 #define PSCI_AFFINITY_INFO_AARCH32	U(0x84000004)
50 #define PSCI_AFFINITY_INFO_AARCH64	U(0xc4000004)
51 #define PSCI_MIG_AARCH32		U(0x84000005)
52 #define PSCI_MIG_AARCH64		U(0xc4000005)
53 #define PSCI_MIG_INFO_TYPE		U(0x84000006)
54 #define PSCI_MIG_INFO_UP_CPU_AARCH32	U(0x84000007)
55 #define PSCI_MIG_INFO_UP_CPU_AARCH64	U(0xc4000007)
56 #define PSCI_SYSTEM_OFF			U(0x84000008)
57 #define PSCI_SYSTEM_RESET		U(0x84000009)
58 #define PSCI_FEATURES			U(0x8400000A)
59 #define PSCI_NODE_HW_STATE_AARCH32	U(0x8400000d)
60 #define PSCI_NODE_HW_STATE_AARCH64	U(0xc400000d)
61 #define PSCI_SYSTEM_SUSPEND_AARCH32	U(0x8400000E)
62 #define PSCI_SYSTEM_SUSPEND_AARCH64	U(0xc400000E)
63 #define PSCI_SET_SUSPEND_MODE		U(0x8400000F)
64 #define PSCI_STAT_RESIDENCY_AARCH32	U(0x84000010)
65 #define PSCI_STAT_RESIDENCY_AARCH64	U(0xc4000010)
66 #define PSCI_STAT_COUNT_AARCH32		U(0x84000011)
67 #define PSCI_STAT_COUNT_AARCH64		U(0xc4000011)
68 #define PSCI_SYSTEM_RESET2_AARCH32	U(0x84000012)
69 #define PSCI_SYSTEM_RESET2_AARCH64	U(0xc4000012)
70 #define PSCI_MEM_PROTECT		U(0x84000013)
71 #define PSCI_MEM_CHK_RANGE_AARCH32	U(0x84000014)
72 #define PSCI_MEM_CHK_RANGE_AARCH64	U(0xc4000014)
73 
74 /*
75  * Number of PSCI calls (above) implemented
76  */
77 #if ENABLE_PSCI_STAT
78 #if PSCI_OS_INIT_MODE
79 #define PSCI_NUM_CALLS			U(30)
80 #else
81 #define PSCI_NUM_CALLS			U(29)
82 #endif
83 #else
84 #if PSCI_OS_INIT_MODE
85 #define PSCI_NUM_CALLS			U(26)
86 #else
87 #define PSCI_NUM_CALLS			U(25)
88 #endif
89 #endif
90 
91 /* The macros below are used to identify PSCI calls from the SMC function ID */
92 #define PSCI_FID_MASK			U(0xffe0)
93 #define PSCI_FID_VALUE			U(0)
94 #define is_psci_fid(_fid) \
95 	(((_fid) & PSCI_FID_MASK) == PSCI_FID_VALUE)
96 
97 /*******************************************************************************
98  * PSCI Migrate and friends
99  ******************************************************************************/
100 #define PSCI_TOS_UP_MIG_CAP	0
101 #define PSCI_TOS_NOT_UP_MIG_CAP	1
102 #define PSCI_TOS_NOT_PRESENT_MP	2
103 
104 /*******************************************************************************
105  * PSCI CPU_SUSPEND 'power_state' parameter specific defines
106  ******************************************************************************/
107 #define PSTATE_ID_SHIFT		U(0)
108 
109 #if PSCI_EXTENDED_STATE_ID
110 #define PSTATE_VALID_MASK	U(0xB0000000)
111 #define PSTATE_TYPE_SHIFT	U(30)
112 #define PSTATE_ID_MASK		U(0xfffffff)
113 #else
114 #define PSTATE_VALID_MASK	U(0xFCFE0000)
115 #define PSTATE_TYPE_SHIFT	U(16)
116 #define PSTATE_PWR_LVL_SHIFT	U(24)
117 #define PSTATE_ID_MASK		U(0xffff)
118 #define PSTATE_PWR_LVL_MASK	U(0x3)
119 
120 #define psci_get_pstate_pwrlvl(pstate)	(((pstate) >> PSTATE_PWR_LVL_SHIFT) & \
121 					PSTATE_PWR_LVL_MASK)
122 #define psci_make_powerstate(state_id, type, pwrlvl) \
123 			(((state_id) & PSTATE_ID_MASK) << PSTATE_ID_SHIFT) |\
124 			(((type) & PSTATE_TYPE_MASK) << PSTATE_TYPE_SHIFT) |\
125 			(((pwrlvl) & PSTATE_PWR_LVL_MASK) << PSTATE_PWR_LVL_SHIFT)
126 #endif /* __PSCI_EXTENDED_STATE_ID__ */
127 
128 #define PSTATE_TYPE_STANDBY	U(0x0)
129 #define PSTATE_TYPE_POWERDOWN	U(0x1)
130 #define PSTATE_TYPE_MASK	U(0x1)
131 
132 /*******************************************************************************
133  * PSCI CPU_FEATURES feature flag specific defines
134  ******************************************************************************/
135 /* Features flags for CPU SUSPEND power state parameter format. Bits [1:1] */
136 #define FF_PSTATE_SHIFT		U(1)
137 #define FF_PSTATE_ORIG		U(0)
138 #define FF_PSTATE_EXTENDED	U(1)
139 #if PSCI_EXTENDED_STATE_ID
140 #define FF_PSTATE		FF_PSTATE_EXTENDED
141 #else
142 #define FF_PSTATE		FF_PSTATE_ORIG
143 #endif
144 
145 /* Features flags for CPU SUSPEND OS Initiated mode support. Bits [0:0] */
146 #define FF_MODE_SUPPORT_SHIFT		U(0)
147 #if PSCI_OS_INIT_MODE
148 #define FF_SUPPORTS_OS_INIT_MODE	U(1)
149 #else
150 #define FF_SUPPORTS_OS_INIT_MODE	U(0)
151 #endif
152 
153 /*******************************************************************************
154  * PSCI version
155  ******************************************************************************/
156 #define PSCI_MAJOR_VER		(U(1) << 16)
157 #define PSCI_MINOR_VER		U(0x1)
158 
159 /*******************************************************************************
160  * PSCI error codes
161  ******************************************************************************/
162 #define PSCI_E_SUCCESS		0
163 #define PSCI_E_NOT_SUPPORTED	-1
164 #define PSCI_E_INVALID_PARAMS	-2
165 #define PSCI_E_DENIED		-3
166 #define PSCI_E_ALREADY_ON	-4
167 #define PSCI_E_ON_PENDING	-5
168 #define PSCI_E_INTERN_FAIL	-6
169 #define PSCI_E_NOT_PRESENT	-7
170 #define PSCI_E_DISABLED		-8
171 #define PSCI_E_INVALID_ADDRESS	-9
172 
173 #define PSCI_INVALID_MPIDR	~((u_register_t)0)
174 
175 /*
176  * SYSTEM_RESET2 macros
177  */
178 #define PSCI_RESET2_TYPE_VENDOR_SHIFT	U(31)
179 #define PSCI_RESET2_TYPE_VENDOR		(U(1) << PSCI_RESET2_TYPE_VENDOR_SHIFT)
180 #define PSCI_RESET2_TYPE_ARCH		(U(0) << PSCI_RESET2_TYPE_VENDOR_SHIFT)
181 #define PSCI_RESET2_SYSTEM_WARM_RESET	(PSCI_RESET2_TYPE_ARCH | U(0))
182 
183 #ifndef __ASSEMBLER__
184 
185 #include <stdint.h>
186 
187 /* Function to help build the psci capabilities bitfield */
188 
define_psci_cap(unsigned int x)189 static inline unsigned int define_psci_cap(unsigned int x)
190 {
191 	return U(1) << (x & U(0x1f));
192 }
193 
194 
195 /* Power state helper functions */
196 
psci_get_pstate_id(unsigned int power_state)197 static inline unsigned int psci_get_pstate_id(unsigned int power_state)
198 {
199 	return ((power_state) >> PSTATE_ID_SHIFT) & PSTATE_ID_MASK;
200 }
201 
psci_get_pstate_type(unsigned int power_state)202 static inline unsigned int psci_get_pstate_type(unsigned int power_state)
203 {
204 	return ((power_state) >> PSTATE_TYPE_SHIFT) & PSTATE_TYPE_MASK;
205 }
206 
psci_check_power_state(unsigned int power_state)207 static inline unsigned int psci_check_power_state(unsigned int power_state)
208 {
209 	return ((power_state) & PSTATE_VALID_MASK);
210 }
211 
212 /*
213  * These are the states reported by the PSCI_AFFINITY_INFO API for the specified
214  * CPU. The definitions of these states can be found in Section 5.7.1 in the
215  * PSCI specification (ARM DEN 0022C).
216  */
217 typedef enum {
218 	AFF_STATE_ON = U(0),
219 	AFF_STATE_OFF = U(1),
220 	AFF_STATE_ON_PENDING = U(2)
221 } aff_info_state_t;
222 
223 /*
224  * These are the power states reported by PSCI_NODE_HW_STATE API for the
225  * specified CPU. The definitions of these states can be found in Section 5.15.3
226  * of PSCI specification (ARM DEN 0022C).
227  */
228 #define HW_ON		0
229 #define HW_OFF		1
230 #define HW_STANDBY	2
231 
232 /*
233  * Macro to represent invalid affinity level within PSCI.
234  */
235 #define PSCI_INVALID_PWR_LVL	(PLAT_MAX_PWR_LVL + U(1))
236 
237 /*
238  * Type for representing the local power state at a particular level.
239  */
240 typedef uint8_t plat_local_state_t;
241 
242 /* The local state macro used to represent RUN state. */
243 #define PSCI_LOCAL_STATE_RUN	U(0)
244 
245 /*
246  * Function to test whether the plat_local_state is RUN state
247  */
is_local_state_run(unsigned int plat_local_state)248 static inline int is_local_state_run(unsigned int plat_local_state)
249 {
250 	return (plat_local_state == PSCI_LOCAL_STATE_RUN) ? 1 : 0;
251 }
252 
253 /*
254  * Function to test whether the plat_local_state is RETENTION state
255  */
is_local_state_retn(unsigned int plat_local_state)256 static inline int is_local_state_retn(unsigned int plat_local_state)
257 {
258 	return ((plat_local_state > PSCI_LOCAL_STATE_RUN) &&
259 		(plat_local_state <= PLAT_MAX_RET_STATE)) ? 1 : 0;
260 }
261 
262 /*
263  * Function to test whether the plat_local_state is OFF state
264  */
is_local_state_off(unsigned int plat_local_state)265 static inline int is_local_state_off(unsigned int plat_local_state)
266 {
267 	return ((plat_local_state > PLAT_MAX_RET_STATE) &&
268 		(plat_local_state <= PLAT_MAX_OFF_STATE)) ? 1 : 0;
269 }
270 
271 /*****************************************************************************
272  * This data structure defines the representation of the power state parameter
273  * for its exchange between the generic PSCI code and the platform port. For
274  * example, it is used by the platform port to specify the requested power
275  * states during a power management operation. It is used by the generic code to
276  * inform the platform about the target power states that each level should
277  * enter.
278  ****************************************************************************/
279 typedef struct psci_power_state {
280 	/*
281 	 * The pwr_domain_state[] stores the local power state at each level
282 	 * for the CPU.
283 	 */
284 	plat_local_state_t pwr_domain_state[PLAT_MAX_PWR_LVL + U(1)];
285 #if PSCI_OS_INIT_MODE
286 	/*
287 	 * The highest power level at which the current CPU is the last running
288 	 * CPU.
289 	 */
290 	unsigned int last_at_pwrlvl;
291 #endif
292 } psci_power_state_t;
293 
294 /*******************************************************************************
295  * Structure used to store per-cpu information relevant to the PSCI service.
296  * It is populated in the per-cpu data array. In return we get a guarantee that
297  * this information will not reside on a cache line shared with another cpu.
298  ******************************************************************************/
299 typedef struct psci_cpu_data {
300 	/* State as seen by PSCI Affinity Info API */
301 	aff_info_state_t aff_info_state;
302 
303 	/*
304 	 * Highest power level which takes part in a power management
305 	 * operation.
306 	 */
307 	unsigned int target_pwrlvl;
308 
309 	/* The local power state of this CPU */
310 	plat_local_state_t local_state;
311 } psci_cpu_data_t;
312 
313 /*******************************************************************************
314  * Structure populated by platform specific code to export routines which
315  * perform common low level power management functions
316  ******************************************************************************/
317 typedef struct plat_psci_ops {
318 	void (*cpu_standby)(plat_local_state_t cpu_state);
319 	int (*pwr_domain_on)(u_register_t mpidr);
320 	void (*pwr_domain_off)(const psci_power_state_t *target_state);
321 	int (*pwr_domain_off_early)(const psci_power_state_t *target_state);
322 #if PSCI_OS_INIT_MODE
323 	int (*pwr_domain_validate_suspend)(
324 				const psci_power_state_t *target_state);
325 #endif
326 	void (*pwr_domain_suspend_pwrdown_early)(
327 				const psci_power_state_t *target_state);
328 	void (*pwr_domain_suspend)(const psci_power_state_t *target_state);
329 	void (*pwr_domain_on_finish)(const psci_power_state_t *target_state);
330 	void (*pwr_domain_on_finish_late)(
331 				const psci_power_state_t *target_state);
332 	void (*pwr_domain_suspend_finish)(
333 				const psci_power_state_t *target_state);
334 	void __dead2 (*pwr_domain_pwr_down_wfi)(
335 				const psci_power_state_t *target_state);
336 	void __dead2 (*system_off)(void);
337 	void __dead2 (*system_reset)(void);
338 	int (*validate_power_state)(unsigned int power_state,
339 				    psci_power_state_t *req_state);
340 	int (*validate_ns_entrypoint)(uintptr_t ns_entrypoint);
341 	void (*get_sys_suspend_power_state)(
342 				    psci_power_state_t *req_state);
343 	int (*get_pwr_lvl_state_idx)(plat_local_state_t pwr_domain_state,
344 				    int pwrlvl);
345 	int (*translate_power_state_by_mpidr)(u_register_t mpidr,
346 				    unsigned int power_state,
347 				    psci_power_state_t *output_state);
348 	int (*get_node_hw_state)(u_register_t mpidr, unsigned int power_level);
349 	int (*mem_protect_chk)(uintptr_t base, u_register_t length);
350 	int (*read_mem_protect)(int *val);
351 	int (*write_mem_protect)(int val);
352 	int (*system_reset2)(int is_vendor,
353 				int reset_type, u_register_t cookie);
354 } plat_psci_ops_t;
355 
356 /*******************************************************************************
357  * Function & Data prototypes
358  ******************************************************************************/
359 unsigned int psci_version(void);
360 int psci_cpu_on(u_register_t target_cpu,
361 		uintptr_t entrypoint,
362 		u_register_t context_id);
363 int psci_cpu_suspend(unsigned int power_state,
364 		     uintptr_t entrypoint,
365 		     u_register_t context_id);
366 int psci_system_suspend(uintptr_t entrypoint, u_register_t context_id);
367 int psci_cpu_off(void);
368 int psci_affinity_info(u_register_t target_affinity,
369 		       unsigned int lowest_affinity_level);
370 int psci_migrate(u_register_t target_cpu);
371 int psci_migrate_info_type(void);
372 u_register_t psci_migrate_info_up_cpu(void);
373 int psci_node_hw_state(u_register_t target_cpu,
374 		       unsigned int power_level);
375 int psci_features(unsigned int psci_fid);
376 #if PSCI_OS_INIT_MODE
377 int psci_set_suspend_mode(unsigned int mode);
378 #endif
379 void __dead2 psci_power_down_wfi(void);
380 void psci_arch_setup(void);
381 
382 #endif /*__ASSEMBLER__*/
383 
384 #endif /* PSCI_H */
385