summaryrefslogtreecommitdiff
path: root/include/power.h
blob: ccf0ab19c606ca9b203ca6045c128a9054c95e83 (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
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
/* Copyright 2013 The ChromiumOS Authors
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

/* Common power interface for all chipsets */

#ifndef __CROS_EC_POWER_H
#define __CROS_EC_POWER_H

#include "common.h"
#include "compiler.h"
#include "gpio.h"
#include "task_id.h"

FORWARD_DECLARE_ENUM(power_state) {
	/* Steady states */
	POWER_G3 = 0,	/*
			 * System is off (not technically all the way into G3,
			 * which means totally unpowered...)
			 */
	POWER_S5,		/* System is soft-off */
	POWER_S3,		/* Suspend; RAM on, processor is asleep */
	POWER_S0,		/* System is on */
#ifdef CONFIG_POWER_S0IX
	POWER_S0ix,
#endif
	/* Transitions */
	POWER_G3S5,	/* G3 -> S5 (at system init time) */
	POWER_S5S3,	/* S5 -> S3 */
	POWER_S3S0,	/* S3 -> S0 */
	POWER_S0S3,	/* S0 -> S3 */
	POWER_S3S5,	/* S3 -> S5 */
	POWER_S5G3,	/* S5 -> G3 */
#ifdef CONFIG_POWER_S0IX
	POWER_S0ixS0,   /* S0ix -> S0 */
	POWER_S0S0ix,   /* S0 -> S0ix */
#endif
};

/*
 * Power signal flags:
 *
 * +-----------------+------------------------------------+
 * |     Bit #       |           Description              |
 * +------------------------------------------------------+
 * |       0         |      Active level (low/high)       |
 * +------------------------------------------------------+
 * |       1         |    Signal interrupt state at boot  |
 * +------------------------------------------------------+
 * |     2 : 32      |            Reserved                |
 * +-----------------+------------------------------------+
 */

#define POWER_SIGNAL_ACTIVE_STATE	BIT(0)
#define POWER_SIGNAL_ACTIVE_LOW	(0 << 0)
#define POWER_SIGNAL_ACTIVE_HIGH	BIT(0)

#define POWER_SIGNAL_INTR_STATE	BIT(1)
#define POWER_SIGNAL_DISABLE_AT_BOOT	BIT(1)

/* Information on an power signal */
struct power_signal_info {
	enum gpio_signal gpio;	/* GPIO for signal */
	uint32_t flags;		/* See POWER_SIGNAL_* macros */
	const char *name;	/* Name of signal */
};

/*
 * Each board must provide its signal list and a corresponding enum
 * power_signal.
 */
#ifdef CONFIG_POWER_SIGNAL_RUNTIME_CONFIG
extern struct power_signal_info power_signal_list[];
#else
extern const struct power_signal_info power_signal_list[];
#endif

/* Convert enum power_signal to a mask for signal functions */
#define POWER_SIGNAL_MASK(signal) (1 << (signal))

/**
 * Return current input signal state (one or more POWER_SIGNAL_MASK()s).
 */
uint32_t power_get_signals(void);

/**
 * Check if provided power signal is currently asserted.
 *
 * @param s		Power signal that needs to be checked.
 *
 * @return 1 if power signal is asserted, 0 otherwise.
 */
int power_signal_is_asserted(const struct power_signal_info *s);

/**
 * Get the level of provided input signal.
 */
__overridable int power_signal_get_level(enum gpio_signal signal);

/**
 * Enable interrupt for provided input signal.
 */
int power_signal_enable_interrupt(enum gpio_signal signal);

/**
 * Disable interrupt for provided input signal.
 */
int power_signal_disable_interrupt(enum gpio_signal signal);

/**
 * Check for required inputs
 *
 * @param want		Mask of signals which must be present (one or more
 *			POWER_SIGNAL_MASK()s).
 *
 * @return Non-zero if all present; zero if a required signal is missing.
 */
int power_has_signals(uint32_t want);

/**
 * Wait for power input signals to be present using default timeout
 *
 * @param want		Wanted signals which must be present (one or more
 *			POWER_SIGNAL_MASK()s).  If want=0, stops waiting for
 *			signals.
 * @return EC_SUCCESS when all inputs are present, or ERROR_TIMEOUT if timeout
 * before reaching the desired state.
 */
int power_wait_signals(uint32_t want);

/**
 * Wait for power input signals to be present
 *
 * @param want		Wanted signals which must be present (one or more
 *			POWER_SIGNAL_MASK()s).  If want=0, stops waiting for
 *			signals.
 * @param timeout       Timeout in usec to wait for signals to be present.
 * @return EC_SUCCESS when all inputs are present, or ERROR_TIMEOUT if timeout
 * before reaching the desired state.
 */
int power_wait_signals_timeout(uint32_t want, int timeout);

/**
 * Wait for power input signals to be the desired state.
 *
 * @param want		Desired signals states. (one or more
 *			POWER_SIGNAL_MASK()s). Signals can be presented or be
 *			disappeared.
 * @param mask		Masked signals that param 'want' cares.
 * @param timeout	Timeout in usec to wait for signals be in the deisred
 *			state.
 * @return EC_SUCCESS when masked signals = wanted signals, or ERROR_TIMEOUT
 * if timeout before reaching the desired state.
 */
int power_wait_mask_signals_timeout(uint32_t want, uint32_t mask, int timeout);


/**
 * Set the low-level power chipset state.
 *
 * @param new_state New chipset state.
 */
void power_set_state(enum power_state new_state);

/**
 * Set the low-level chipset power state.
 *
 * @return Current chipset power state
 */
#ifdef HAS_TASK_CHIPSET
enum power_state power_get_state(void);
#else
static inline enum power_state power_get_state(void) {
	return POWER_G3;
}
#endif

/*
 * Set the wake mask according to the current power state.
 */
void power_update_wake_mask(void);

/**
 * Chipset-specific initialization
 *
 * @return The state the chipset should start in.  Usually POWER_G3, but may
 * be POWER_G0 if the chipset was already on and we've jumped to this image.
 */
enum power_state power_chipset_init(void);

/**
 * Chipset-specific state handler
 *
 * @return The updated state for the chipset.
 */
enum power_state power_handle_state(enum power_state state);

/**
 * Interrupt handler for power signal GPIOs.
 */
#ifdef HAS_TASK_CHIPSET
void power_signal_interrupt(enum gpio_signal signal);
#else
static inline void power_signal_interrupt(enum gpio_signal signal) { }
#endif /* !HAS_TASK_CHIPSET */

/**
 * Interrupt handler for rsmrst signal GPIO. This interrupt handler should be
 * used when there is a requirement to have minimum pass through delay between
 * the rsmrst coming to the EC and the rsmrst that goes to the PCH for high->low
 * transitions. Low->high transitions are still handled from within the chipset
 * task power state machine.
 *
 * @param signal - The gpio signal that triggered the interrupt.
 */
void intel_x86_rsmrst_signal_interrupt(enum gpio_signal signal);

/**
 * pause_in_s5 getter method.
 *
 * @return Whether we should pause in S5 when shutting down.
 */
int power_get_pause_in_s5(void);

/**
 * pause_in_s5 setter method.
 *
 * @param pause True if we should pause in S5 when shutting down.
 */
void power_set_pause_in_s5(int pause);

#ifdef CONFIG_POWER_TRACK_HOST_SLEEP_STATE
/**
 * Get sleep state of host, as reported by the host.
 *
 * @return Believed sleep state of host.
 */
enum host_sleep_event power_get_host_sleep_state(void);

/**
 * Set sleep state of host.
 *
 * @param state The new state to set.
 */
void power_set_host_sleep_state(enum host_sleep_event state);

/* Context to pass to a host sleep command handler. */
struct host_sleep_event_context {
	uint32_t sleep_transitions; /* Number of sleep transitions observed */
	uint16_t sleep_timeout_ms;  /* Timeout in milliseconds */
};

/**
 * Provide callback to allow chipset to take any action on host sleep event
 * command.
 *
 * @param state Current host sleep state updated by the host.
 * @param ctx Possible sleep parameters and return values, depending on state.
 */
__override_proto void power_chipset_handle_host_sleep_event(
		enum host_sleep_event state,
		struct host_sleep_event_context *ctx);

/**
 * Provide callback to allow board to take any action on host sleep event
 * command.
 *
 * @param state Current host sleep state updated by the host.
 */
__override_proto void power_board_handle_host_sleep_event(
		enum host_sleep_event state);

/*
 * This is the default state of host sleep event. Calls to
 * power_reset_host_sleep_state will set host sleep event to this
 * value. EC components listening to host sleep event updates can check for this
 * special value to know if the state was reset.
 */
#define HOST_SLEEP_EVENT_DEFAULT_RESET		0

enum sleep_notify_type {
	SLEEP_NOTIFY_NONE,
	SLEEP_NOTIFY_SUSPEND,
	SLEEP_NOTIFY_RESUME,
};

/**
 * Set the sleep notify
 *
 * It is called in power_chipset_handle_host_sleep_event(), to set the sleep
 * notify. The sleep notify is assigned based on the host sleep state.
 *
 * @param notify The sleep notify to set.
 */
void sleep_set_notify(enum sleep_notify_type notify);

/**
 * Notify the given hook is the sleep notify is matched.
 *
 * @param check_state: The sleep notify to check.
 * @param hook_id: The hook to notify.
 */
void sleep_notify_transition(int check_state, int hook_id);

/**
 * Called during the suspend transition, to increase the transition counter.
 */
void sleep_suspend_transition(void);

/**
 * Called during the resume transition, to increase the transition counter.
 */
void sleep_resume_transition(void);

/**
 * Start the suspend process.
 *
 * It is called in power_chipset_handle_host_sleep_event(), after it receives
 * a host sleep event to hint that the suspend process starts.
 *
 * @param ctx Possible sleep parameters and return values, depending on state.
 * @param callback Will be called if timed out, i.e. suspend hang.
 */
void sleep_start_suspend(struct host_sleep_event_context *ctx,
			 void (*callback)(void));

/**
 * Complete the resume process.
 *
 * It is called in power_chipset_handle_host_sleep_event(), after it receives
 * a host sleep event to hint that the resume process completes.
 *
 * @param ctx Possible sleep parameters and return values, depending on state.
 */
void sleep_complete_resume(struct host_sleep_event_context *ctx);

/**
 * Reset the transition counter and timer.
 */
void sleep_reset_tracking(void);

#ifdef CONFIG_POWER_S0IX
/**
 * Reset the sleep state reported by the host.
 *
 * @param sleep_event Reset sleep state.
 */
void power_reset_host_sleep_state(void);
#endif /* CONFIG_POWER_S0IX */
#endif /* CONFIG_POWER_TRACK_HOST_SLEEP_STATE */

/**
 * Board specific implementation to enable/disable the PP5000 rail.
 *
 * NOTE: The default implementation is to simply set GPIO_EN_PP5000.  If a
 * board's implementation differs, they should implement this function.
 *
 * @param enable: 0 to disable PP5000 rail , otherwise enable PP5000 rail.
 */
__override_proto void board_power_5v_enable(int enable);

/**
 * Enable/Disable the PP5000 rail.
 *
 * This function will turn on the 5V rail immediately if requested.  However,
 * the rail will not turn off until all tasks want it off.
 *
 * NOTE: Be careful when calling from deferred functions, as they will all be
 * executed within the same task context! (The HOOKS task).
 *
 * @param tid: The caller's task ID.
 * @param enable: 1 to turn on the rail, 0 to request the rail to be turned off.
 */
void power_5v_enable(task_id_t tid, int enable);

#endif  /* __CROS_EC_POWER_H */