summaryrefslogtreecommitdiff
path: root/zephyr/include/ap_power/ap_power.h
blob: 6c4d6c2347b8a6a024bc6e58432ff0b94f350ad0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
/* Copyright 2022 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

/**
 * @file
 * @brief Public APIs for AP power sequence.
 *
 * Defines the API for AP event notification,
 * the API to register and receive notification callbacks when
 * application processor (AP) events happen.
 *
 * When the Zephyr based AP power sequence config is enabled,
 * the callbacks are almost all invoked within the context
 * of the power sequence task, so the state is stable
 * during the callback. The only exception to this is AP_POWER_RESET, which is
 * invoked as a result of receiving a PLTRST# virtual wire signal (if enabled).
 *
 * When the legacy power sequence config is enabled, the callbacks are invoked
 * from the HOOK_CHIPSET notifications.
 */

#ifndef __AP_POWER_AP_POWER_H__
#define __AP_POWER_AP_POWER_H__

#include <zephyr/kernel.h>

/**
 * @brief AP power events for callback notification.
 */
enum ap_power_events {
	/**
	 * Transitioning from hard-off to soft-off.
	 *
	 * On x86 this is the transition up from G3 to S5.
	 */
	AP_POWER_PRE_INIT = BIT(0),
	/**
	 * Transitioning from soft-off to suspend.
	 *
	 * On x86 this is going from S5 to S3.
	 */
	AP_POWER_STARTUP = BIT(1),
	/**
	 * Transitioning from suspend to active.
	 *
	 * This event is emitted on all suspend-active transitions, regardless
	 * of suspend level. In particular, on x86 it is triggered by transition
	 * from either of S3 or S0ix to S0.
	 */
	AP_POWER_RESUME = BIT(2),
	/**
	 * Transitioning from active to suspend.
	 *
	 * This is the opposite of AP_POWER_RESUME. On x86, it is emitted when
	 * leaving S0 to either of S3 or S0ix.
	 */
	AP_POWER_SUSPEND = BIT(3),
#if CONFIG_PLATFORM_EC_CHIPSET_RESUME_INIT_HOOK
	/**
	 * Early transition from suspend to active.
	 *
	 * This event runs under the same conditions as AP_POWER_RESUME, but
	 * is guaranteed to run before AP_POWER_RESUME.
	 */
	AP_POWER_RESUME_INIT = BIT(4),
	/**
	 * Late transition from active to suspend.
	 *
	 * This event runs under the same conditions as AP_POWER_SUSPEND, but
	 * is guaranteed to run after AP_POWER_SUSPEND.
	 */
	AP_POWER_SUSPEND_COMPLETE = BIT(5),
#endif
	/**
	 * Transitioning from suspend to soft-off.
	 *
	 * This is the opposite of AP_POWER_STARTUP. On x86 it is the transition
	 * from S3 to S5.
	 */
	AP_POWER_SHUTDOWN = BIT(6),
	/**
	 * Late transition from suspend to soft-off.
	 *
	 * This runs under the same conditions as AP_POWER_SHUTDOWN, but runs
	 * after AP_POWER_SHUTDOWN.
	 */
	AP_POWER_SHUTDOWN_COMPLETE = BIT(7),
	/**
	 * Transitioning from soft-off to hard-off.
	 *
	 * This is the opposite of AP_POWER_PRE_INIT. On x86 it is the
	 * transition from S5 to G3.
	 */
	AP_POWER_HARD_OFF = BIT(8),
	/** Software reset occurred */
	AP_POWER_RESET = BIT(9),
	/**
	 * AP power state is now known.
	 *
	 * Prior to this event, the state of the AP is unknown
	 * and invalid. When this event is sent, the state is known
	 * and can be queried. Used by clients when their
	 * initialization depends upon the initial state of the AP.
	 */
	AP_POWER_INITIALIZED = BIT(10),

	/**
	 * S0ix suspend starts.
	 */
	AP_POWER_S0IX_SUSPEND_START = BIT(11),
	/**
	 * Transitioning from s0 to s0ix.
	 */
	AP_POWER_S0IX_SUSPEND = BIT(12),
	/**
	 * Transitioning from s0ix to s0.
	 */
	AP_POWER_S0IX_RESUME = BIT(13),
	/**
	 * si0x resume complete.
	 */
	AP_POWER_S0IX_RESUME_COMPLETE = BIT(14),
	/**
	 * Reset s0ix tracking.
	 */
	AP_POWER_S0IX_RESET_TRACKING = BIT(15),
};

/**
 * @brief AP data for callback argument.
 */
struct ap_power_ev_data {
	enum ap_power_events event;
	/* May need more data here */
};

struct ap_power_ev_callback;

/**
 * @brief Callback handler definition
 */
typedef void (*ap_power_ev_callback_handler_t)(struct ap_power_ev_callback *cb,
					       struct ap_power_ev_data data);

/**
 * @cond INTERNAL_HIDDEN
 *
 * Register a callback for the AP power events requested.
 * As many callbacks as needed can be added as long as each of them
 * are unique pointers of struct ap_power_ev_callback.
 * The storage must be static.
 *
 * ap_power_ev_init_callback can be used to initialize this structure.
 */
struct ap_power_ev_callback {
	sys_snode_t node; /* Only usable by AP power event code */
	ap_power_ev_callback_handler_t handler;
	enum ap_power_events events; /* Events to listen for */
};
/** @endcond */

/**
 * @brief Initialise a struct ap_power_ev_callback properly.
 *
 * @param callback A valid ap_power_ev_callback structure pointer.
 * @param handler The function pointer to call.
 * @param events The bitmask of events to be called for.
 */
static inline void
ap_power_ev_init_callback(struct ap_power_ev_callback *cb,
			  ap_power_ev_callback_handler_t handler,
			  enum ap_power_events events)
{
	__ASSERT(cb, "Callback pointer should not be NULL");
	__ASSERT(handler, "Callback handler pointer should not be NULL");

	cb->handler = handler;
	cb->events = events;
}

/**
 * @brief Update a callback event mask to listen for new events
 *
 * @param callback A valid ap_power_ev_callback structure pointer.
 * @param events The bitmask of events to add.
 */
void ap_power_ev_add_events(struct ap_power_ev_callback *cb,
			    enum ap_power_events events);

/**
 * @brief Update a callback event mask to remove events
 *
 * @param callback A valid ap_power_ev_callback structure pointer.
 * @param events The bitmask of events to remove.
 */
static inline void ap_power_ev_remove_events(struct ap_power_ev_callback *cb,
					     enum ap_power_events events)
{
	__ASSERT(cb, "Callback pointer should not be NULL");

	cb->events &= ~events;
}

/**
 * @brief Add an AP event callback.
 *
 * @param callback A valid ap_power_ev_callback structure pointer.
 * @return 0 on success, negative errno on failure.
 */
int ap_power_ev_add_callback(struct ap_power_ev_callback *cb);

/**
 * @brief Remove an AP event callback.
 *
 * @param callback A valid ap_power_ev_callback structure pointer.
 * @return 0 on success, negative errno on failure.
 */
int ap_power_ev_remove_callback(struct ap_power_ev_callback *cb);

#endif /* __AP_POWER_AP_POWER_H__ */