xref: /optee_os/core/include/kernel/pm.h (revision 25675979615c01f3c6bfbe105f53e07e939dd739)
1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*
3  * Copyright (c) 2018, Linaro Limited
4  */
5 
6 #ifndef __KERNEL_PM_H
7 #define __KERNEL_PM_H
8 
9 #include <stdbool.h>
10 #include <stdint.h>
11 #include <tee_api_types.h>
12 
13 /*
14  * Platform hints on targeted power state. Hints are stored in a 32bit
15  * unsigned value. Lower bits defines generic resource bit flags. Higher
16  * bits stores a platform specific value specific platform driver may
17  * understand. Registered callbacks may choose to use or ignore these hints.
18  *
19  * PM_HINT_CLOCK_STATE - When set clock shall be suspended/restored
20  * PM_HINT_POWER_STATE - When set device power shall be suspended/restored
21  * PM_HINT_IO_STATE - When set IO pins shall be suspended/restored
22  * PM_HINT_CONTEXT_STATE - When set the full context be suspended/restored
23  * PM_HINT_PLATFORM_STATE_MASK - Bit mask reserved for platform specific hints
24  * PM_HINT_PLATFORM_STATE_SHIFT - LSBit position of platform specific hints mask
25  */
26 #define PM_HINT_CLOCK_STATE		BIT(0)
27 #define PM_HINT_POWER_STATE		BIT(1)
28 #define PM_HINT_IO_STATE		BIT(2)
29 #define PM_HINT_CONTEXT_STATE		BIT(3)
30 #define PM_HINT_PLATFORM_STATE_MASK	GENMASK_32(31, 16)
31 #define PM_HINT_PLATFORM_STATE_SHIFT	U(16)
32 
33 #define PM_HINT_STATE(_x)		((_x) & ~PM_HINT_PLATFORM_STATE_MASK)
34 #define PM_HINT_PLATFORM_STATE(_x) \
35 	(((_x) & PM_HINT_PLATFORM_STATE_MASK) >> PM_HINT_PLATFORM_STATE_SHIFT)
36 
37 #define PM_HINT_IS_STATE(_x, _name) ((_x) & PM_HINT_ ## _name ## _STATE)
38 
39 /*
40  * PM_OP_SUSPEND: platform is suspending to a target low power state
41  * PM_OP_RESUME: platform is resuming from low power state
42  */
43 enum pm_op {
44 	PM_OP_SUSPEND = 0,
45 	PM_OP_RESUME = 1,
46 };
47 
48 /*
49  * Registered callbacks are called the ordering directives specified
50  * by the PM_CB_ORDER_* value. Driver ordered callbacks at suspended
51  * first/resumed last. Core service ordered callbacks are suspended
52  * last/resumed first.
53  */
54 enum pm_callback_order {
55 	PM_CB_ORDER_DRIVER = 0,
56 	PM_CB_ORDER_CORE_SERVICE,
57 	PM_CB_ORDER_MAX
58 };
59 
60 #define PM_CALLBACK_HANDLE_INITIALIZER(_callback, _handle, _order, _name)\
61 		((struct pm_callback_handle){				\
62 			.callback = (_callback),			\
63 			.handle = (_handle),				\
64 			.order = (_order),				\
65 			.name = (_name),				\
66 		})
67 
68 #define PM_CALLBACK_GET_HANDLE(pm_handle)	((pm_handle)->handle)
69 
70 struct pm_callback_handle;
71 typedef TEE_Result (*pm_callback)(enum pm_op op, uint32_t pm_hint,
72 				  const struct pm_callback_handle *pm_handle);
73 
74 /*
75  * Drivers and services can register a callback function for the platform
76  * suspend and resume sequences. A private address handle can be registered
77  * with the callback and retrieved from the callback. Callback can be
78  * registered with a specific call order as defined per PM_CB_ORDER_*.
79  *
80  * Callback shall return an error if failing to complete target transition.
81  * This information may be used by the platform to resume a platform on
82  * non-fatal failure to suspend.
83  *
84  * Callback implementations should ensure their functions belong to unpaged
85  * memory sections (see DECLARE_KEEP_PAGER()) since the callback is likely to
86  * be called from an unpaged execution context.
87  *
88  * Power Mamagement callback functions API:
89  *
90  * TEE_Result (*callback)(enum pm_op op,
91  *			  unsigned int pm_hint,
92  *			  const struct pm_callback_handle *pm_handle);
93  *
94  * @op - Target operation: either PM_SUSPEND or PM_RESUME
95  * @pm_hint - Hints on power state platform suspends to /resumes from.
96  *		PM_STATE_HINT_* defines the supported values.
97  * @pm_handle - Reference to the struct pm_callback_handle related to to
98  *		registered callback. Callback can retrieve the registered
99  *		private handle with PM_CALLBACK_GET_HANDLE().
100  *
101  * Return a TEE_Result compliant return code
102  */
103 /*
104  * struct pm_callback_handle store the callback registration directives.
105  *
106  * @callback - Registered callback function
107  * @handle - Registered private handler for the callback
108  * @order - Registered callback call order priority (PM_CB_ORDER_*)
109  * @flags - Flags set by pm core to keep track of execution
110  * @name - Registered callback name
111  */
112 struct pm_callback_handle {
113 	/* Set by the caller when registering a callback */
114 	pm_callback callback;
115 	void *handle;
116 	uint8_t order;
117 	/* Set by the system according to execution context */
118 	uint8_t flags;
119 	const char *name;
120 };
121 
122 /*
123  * Register a callback for suspend/resume sequence
124  * Refer to struct pm_callback_handle for description of the callbacks
125  * API and the registration directives.
126  *
127  * @pm_handle: Reference callback registration directives
128  */
129 void register_pm_cb(struct pm_callback_handle *pm_handle);
130 
131 /*
132  * Register a driver callback for generic suspend/resume.
133  * Refer to struct pm_callback_handle for description of the callbacks
134  * API.
135  *
136  * @callback: Registered callback function
137  * @handle: Registered private handle argument for the callback
138  * @name: Registered callback name
139  */
140 static inline void register_pm_driver_cb(pm_callback callback, void *handle,
141 					 const char *name)
142 {
143 	register_pm_cb(&PM_CALLBACK_HANDLE_INITIALIZER(callback, handle,
144 						       PM_CB_ORDER_DRIVER,
145 						       name));
146 }
147 
148 /*
149  * Register a core service callback for generic suspend/resume.
150  * Refer to struct pm_callback_handle for description of the callbacks
151  * API.
152  *
153  * @callback: Registered callback function
154  * @handle: Registered private handle argument for the callback
155  * @name: Registered callback name
156  */
157 static inline void register_pm_core_service_cb(pm_callback callback,
158 					       void *handle, const char *name)
159 {
160 	register_pm_cb(&PM_CALLBACK_HANDLE_INITIALIZER(callback, handle,
161 						PM_CB_ORDER_CORE_SERVICE,
162 						name));
163 }
164 
165 /*
166  * Request call to registered PM callbacks
167  *
168  * @op: Either PM_OP_SUSPEND or PM_OP_RESUME
169  * @pm_hint: Hint (PM_HINT_*) on state the platform suspends to/resumes from.
170  *
171  * Return a TEE_Result compliant status
172  */
173 TEE_Result pm_change_state(enum pm_op op, uint32_t pm_hint);
174 
175 #endif /*__KERNEL_PM_H*/
176