xref: /optee_os/core/include/kernel/pm.h (revision b8bb0afa738e6038bbd92b57742aa2526df9f20a)
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	16
32 
33 /*
34  * PM_OP_SUSPEND: platform is suspending to a target low power state
35  * PM_OP_RESUME: platform is resuming from low power state
36  */
37 enum pm_op {
38 	PM_OP_SUSPEND = 0,
39 	PM_OP_RESUME = 1,
40 };
41 
42 /*
43  * Registered callbacks are called the ordering directives specified
44  * by the PM_CB_ORDER_* value. Driver ordered callbacks at suspended
45  * first/resumed last. Core service ordered callbacks are suspended
46  * last/resumed first.
47  */
48 enum pm_callback_order {
49 	PM_CB_ORDER_DRIVER = 0,
50 	PM_CB_ORDER_CORE_SERVICE,
51 	PM_CB_ORDER_MAX
52 };
53 
54 #define PM_CALLBACK_HANDLE_INITIALIZER(_callback, _handle, _order)	\
55 		(struct pm_callback_handle){				\
56 			.callback = (_callback),			\
57 			.handle = (_handle),				\
58 			.order = (_order),				\
59 		}
60 
61 #define PM_CALLBACK_GET_HANDLE(pm_handle)	((pm_handle)->handle)
62 
63 /*
64  * Drivers and services can register a callback function for the platform
65  * suspend and resume sequences. A private address handle can be registered
66  * with the callback and retrieved from the callback. Callback can be
67  * registered with a specific call order as defined per PM_CB_ORDER_*.
68  *
69  * Callback shall return an error if failing to complete target transition.
70  * This information may be used by the platform to resume a platform on
71  * non-fatal failure to suspend.
72  *
73  * Callback implementations should ensure their functions belong to unpaged
74  * memory sections (see KEEP_PAGER()) since the callback is likely to be
75  * called from an unpaged execution context.
76  *
77  * Power Mamagement callback functions API:
78  *
79  * TEE_Result (*callback)(enum pm_op op,
80  *			  unsigned int pm_hint,
81  *			  const struct pm_callback_handle *pm_handle);
82  *
83  * @op - Target operation: either PM_SUSPEND or PM_RESUME
84  * @pm_hint - Hints on power state platform suspends to /resumes from.
85  *		PM_STATE_HINT_* defines the supported values.
86  * @pm_handle - Reference to the struct pm_callback_handle related to to
87  *		registered callback. Callback can retrieve the registered
88  *		private handle with PM_CALLBACK_GET_HANDLE().
89  *
90  * Return a TEE_Result compliant return code
91  */
92 /*
93  * struct pm_callback_handle store the callback registration directives.
94  *
95  * @callback - Registered callback function
96  * @handle - Registered private handler for the callback
97  * @order - Registered callback call order priority (PM_CB_ORDER_*)
98  */
99 struct pm_callback_handle {
100 	/* Set by the caller when registering a callback */
101 	TEE_Result (*callback)(enum pm_op op, uint32_t pm_hint,
102 			       const struct pm_callback_handle *pm_handle);
103 	void *handle;
104 	uint8_t order;
105 	/* Set by the system according to execution context */
106 	uint8_t flags;
107 };
108 
109 /*
110  * Register a callback for suspend/resume sequence
111  * Refer to struct pm_callback_handle for description of the callbacks
112  * API and the registration directives.
113  *
114  * @pm_handle: Reference callback registration directives
115  */
116 void register_pm_cb(struct pm_callback_handle *pm_handle);
117 
118 /*
119  * Register a driver callback for generic suspend/resume.
120  * Refer to struct pm_callback_handle for description of the callbacks
121  * API.
122  *
123  * @callback: Registered callback function
124  * @handle: Registered private handle argument for the callback
125  */
126 static inline void register_pm_driver_cb(
127 		TEE_Result (*callback)(
128 				enum pm_op op, uint32_t pm_hint,
129 				const struct pm_callback_handle *pm_handle),
130 		void *handle)
131 {
132 	register_pm_cb(&PM_CALLBACK_HANDLE_INITIALIZER(callback, handle,
133 						       PM_CB_ORDER_DRIVER));
134 }
135 
136 /*
137  * Request call to registered PM callbacks
138  *
139  * @op: Either PM_OP_SUSPEND or PM_OP_RESUME
140  * @pm_hint: Hint (PM_HINT_*) on state the platform suspends to/resumes from.
141  *
142  * Return a TEE_Result compliant status
143  */
144 TEE_Result pm_change_state(enum pm_op op, uint32_t pm_hint);
145 
146 #endif /*__KERNEL_PM_H*/
147