summaryrefslogtreecommitdiff
path: root/include/power.h
blob: fac596d44cb492dac6179ade27e0901e36277dba (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
/* Copyright 2013 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.
 */

/* Common power interface for all chipsets */

#ifndef __CROS_EC_POWER_H
#define __CROS_EC_POWER_H

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

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.
 */
extern const struct power_signal_info power_signal_list[];

/* 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.
 */
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		Mask of 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		Mask of 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);

/**
 * 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
 */
enum power_state power_get_state(void);

/*
 * 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

#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 */

/**
 * 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 */