]>
Commit | Line | Data |
---|---|---|
7ca2850c SG |
1 | /* SPDX-License-Identifier: GPL-2.0+ */ |
2 | /* | |
3 | * Core ACPI (Advanced Configuration and Power Interface) support | |
4 | * | |
5 | * Copyright 2019 Google LLC | |
6 | * Written by Simon Glass <[email protected]> | |
7 | */ | |
8 | ||
9 | #ifndef __DM_ACPI_H__ | |
10 | #define __DM_ACPI_H__ | |
11 | ||
12 | /* Allow operations to be optional for ACPI */ | |
13 | #if CONFIG_IS_ENABLED(ACPIGEN) | |
14 | #define ACPI_OPS_PTR(_ptr) .acpi_ops = _ptr, | |
15 | #else | |
16 | #define ACPI_OPS_PTR(_ptr) | |
17 | #endif | |
18 | ||
7e148f2e | 19 | /* Length of an ACPI name string, excluding null terminator */ |
7ca2850c SG |
20 | #define ACPI_NAME_LEN 4 |
21 | ||
22 | /* Length of an ACPI name string including nul terminator */ | |
23 | #define ACPI_NAME_MAX (ACPI_NAME_LEN + 1) | |
24 | ||
7e148f2e SG |
25 | /* Number of nested objects supported */ |
26 | #define ACPIGEN_LENSTACK_SIZE 10 | |
27 | ||
89c2798f SG |
28 | #if !defined(__ACPI__) |
29 | ||
6afa63a5 SG |
30 | #include <linker_lists.h> |
31 | ||
b4e84334 | 32 | struct nhlt; |
401d1c4f | 33 | struct udevice; |
b4e84334 | 34 | |
a4f82089 SG |
35 | /** enum acpi_dump_option - selects what ACPI information to dump */ |
36 | enum acpi_dump_option { | |
37 | ACPI_DUMP_LIST, /* Just the list of items */ | |
38 | ACPI_DUMP_CONTENTS, /* Include the binary contents also */ | |
39 | }; | |
40 | ||
93f7f827 SG |
41 | /** |
42 | * struct acpi_ctx - Context used for writing ACPI tables | |
43 | * | |
44 | * This contains a few useful pieces of information used when writing | |
45 | * | |
61cc9339 | 46 | * @base: Base address of ACPI tables |
93f7f827 | 47 | * @current: Current address for writing |
fb746fde SG |
48 | * @tab_start: Address of start of the table being written. This is set up |
49 | * before the writer or driver method is called. It must not be changed by the | |
50 | * method | |
29b35112 SG |
51 | * @rsdp: Pointer to the Root System Description Pointer, typically used when |
52 | * adding a new table. The RSDP holds pointers to the RSDT and XSDT. | |
53 | * @rsdt: Pointer to the Root System Description Table | |
b38309b7 | 54 | * @xsdt: Pointer to the Extended System Description Table |
a53d38f8 | 55 | * @facs: Pointer to the Firmware ACPI Control Structure |
eacb6d0b | 56 | * @dsdt: Pointer to the Differentiated System Description Table |
b4e84334 SG |
57 | * @nhlt: Intel Non-High-Definition-Audio Link Table (NHLT) pointer, used to |
58 | * build up information that audio codecs need to provide in the NHLT ACPI | |
59 | * table | |
7e148f2e SG |
60 | * @len_stack: Stack of 'length' words to fix up later |
61 | * @ltop: Points to current top of stack (0 = empty) | |
93f7f827 SG |
62 | */ |
63 | struct acpi_ctx { | |
61cc9339 | 64 | void *base; |
93f7f827 | 65 | void *current; |
fb746fde | 66 | void *tab_start; |
29b35112 SG |
67 | struct acpi_rsdp *rsdp; |
68 | struct acpi_rsdt *rsdt; | |
b38309b7 | 69 | struct acpi_xsdt *xsdt; |
a53d38f8 | 70 | struct acpi_facs *facs; |
eacb6d0b | 71 | struct acpi_table_header *dsdt; |
b4e84334 | 72 | struct nhlt *nhlt; |
7e148f2e SG |
73 | char *len_stack[ACPIGEN_LENSTACK_SIZE]; |
74 | int ltop; | |
93f7f827 SG |
75 | }; |
76 | ||
6afa63a5 SG |
77 | /** |
78 | * enum acpi_writer_flags_t - flags to use for the ACPI writers | |
94ba15a3 SG |
79 | * |
80 | * ACPIWF_ALIGN64 - align to 64 bytes after writing this one (default is 16) | |
6afa63a5 SG |
81 | */ |
82 | enum acpi_writer_flags_t { | |
94ba15a3 | 83 | ACPIWF_ALIGN64 = 1 << 0, |
6afa63a5 SG |
84 | }; |
85 | ||
86 | struct acpi_writer; | |
87 | ||
88 | /** | |
89 | * acpi_writer_func() - Function that can write an ACPI table | |
90 | * | |
91 | * @ctx: ACPI context to use for writing | |
92 | * @entry: Linker-list entry for this writer | |
93 | * @return 0 if OK, -ve on error | |
94 | */ | |
95 | typedef int (*acpi_writer_func)(struct acpi_ctx *ctx, | |
96 | const struct acpi_writer *entry); | |
97 | ||
98 | /** | |
99 | * struct acpi_writer - an ACPI table that can be written | |
100 | * | |
101 | * @name: Name of the writer | |
102 | * @table: Table name that is generated (e.g. "DSDT") | |
103 | * @h_write: Writer function | |
104 | */ | |
105 | struct acpi_writer { | |
106 | const char *name; | |
107 | const char *table; | |
108 | acpi_writer_func h_write; | |
109 | int flags; | |
110 | }; | |
111 | ||
94ba15a3 | 112 | /* Declare a new ACPI-table writer */ |
6afa63a5 SG |
113 | #define ACPI_WRITER(_name, _table, _write, _flags) \ |
114 | ll_entry_declare(struct acpi_writer, _name, acpi_writer) = { \ | |
115 | .name = #_name, \ | |
116 | .table = _table, \ | |
117 | .h_write = _write, \ | |
118 | .flags = _flags, \ | |
119 | } | |
120 | ||
94ba15a3 SG |
121 | /* Get a pointer to a given ACPI-table writer */ |
122 | #define ACPI_WRITER_GET(_name) \ | |
123 | ll_entry_get(struct acpi_writer, _name, acpi_writer) | |
124 | ||
7ca2850c SG |
125 | /** |
126 | * struct acpi_ops - ACPI operations supported by driver model | |
127 | */ | |
128 | struct acpi_ops { | |
129 | /** | |
130 | * get_name() - Obtain the ACPI name of a device | |
131 | * | |
132 | * @dev: Device to check | |
133 | * @out_name: Place to put the name, must hold at least ACPI_NAME_MAX | |
134 | * bytes | |
135 | * @return 0 if OK, -ENOENT if no name is available, other -ve value on | |
136 | * other error | |
137 | */ | |
138 | int (*get_name)(const struct udevice *dev, char *out_name); | |
93f7f827 SG |
139 | |
140 | /** | |
141 | * write_tables() - Write out any tables required by this device | |
142 | * | |
143 | * @dev: Device to write | |
144 | * @ctx: ACPI context to use | |
145 | * @return 0 if OK, -ve on error | |
146 | */ | |
147 | int (*write_tables)(const struct udevice *dev, struct acpi_ctx *ctx); | |
b5183172 | 148 | |
763bad3e PR |
149 | /** |
150 | * fill_madt() - Generate MADT sub-tables for a device | |
151 | * | |
152 | * This is called to create the MADT table. The method should write out | |
153 | * whatever sub-table is needed by this device. It will end up in the | |
154 | * MADT table. | |
155 | * | |
156 | * Note that this is called 'fill' because the entire contents of the | |
157 | * MADT is build by calling this method on all devices. | |
158 | * | |
159 | * @dev: Device to write | |
160 | * @ctx: ACPI context to use | |
161 | * @return 0 if OK, -ve on error | |
162 | */ | |
163 | int (*fill_madt)(const struct udevice *dev, struct acpi_ctx *ctx); | |
164 | ||
b5183172 SG |
165 | /** |
166 | * fill_ssdt() - Generate SSDT code for a device | |
167 | * | |
168 | * This is called to create the SSDT code. The method should write out | |
169 | * whatever ACPI code is needed by this device. It will end up in the | |
170 | * SSDT table. | |
171 | * | |
01694589 SG |
172 | * Note that this is called 'fill' because the entire contents of the |
173 | * SSDT is build by calling this method on all devices. | |
174 | * | |
b5183172 SG |
175 | * @dev: Device to write |
176 | * @ctx: ACPI context to use | |
177 | * @return 0 if OK, -ve on error | |
178 | */ | |
179 | int (*fill_ssdt)(const struct udevice *dev, struct acpi_ctx *ctx); | |
01694589 SG |
180 | |
181 | /** | |
182 | * inject_dsdt() - Generate DSDT code for a device | |
183 | * | |
184 | * This is called to create the DSDT code. The method should write out | |
185 | * whatever ACPI code is needed by this device. It will end up in the | |
186 | * DSDT table. | |
187 | * | |
188 | * Note that this is called 'inject' because the output of calling this | |
189 | * method on all devices is injected into the DSDT, the bulk of which | |
190 | * is written in .asl files for the board. | |
191 | * | |
192 | * @dev: Device to write | |
193 | * @ctx: ACPI context to use | |
194 | * @return 0 if OK, -ve on error | |
195 | */ | |
196 | int (*inject_dsdt)(const struct udevice *dev, struct acpi_ctx *ctx); | |
b4e84334 SG |
197 | |
198 | /** | |
199 | * setup_nhlt() - Set up audio information for this device | |
200 | * | |
201 | * The method can add information to ctx->nhlt if it likes | |
202 | * | |
203 | * @return 0 if OK, -ENODATA if nothing to add, -ve on error | |
204 | */ | |
205 | int (*setup_nhlt)(const struct udevice *dev, struct acpi_ctx *ctx); | |
7ca2850c SG |
206 | }; |
207 | ||
208 | #define device_get_acpi_ops(dev) ((dev)->driver->acpi_ops) | |
209 | ||
210 | /** | |
211 | * acpi_get_name() - Obtain the ACPI name of a device | |
212 | * | |
213 | * @dev: Device to check | |
214 | * @out_name: Place to put the name, must hold at least ACPI_NAME_MAX | |
215 | * bytes | |
185f812c | 216 | * Return: 0 if OK, -ENOENT if no name is available, other -ve value on |
7ca2850c SG |
217 | * other error |
218 | */ | |
219 | int acpi_get_name(const struct udevice *dev, char *out_name); | |
220 | ||
221 | /** | |
222 | * acpi_copy_name() - Copy an ACPI name to an output buffer | |
223 | * | |
224 | * This convenience function can be used to return a literal string as a name | |
225 | * in functions that implement the get_name() method. | |
226 | * | |
227 | * For example: | |
228 | * | |
229 | * static int mydev_get_name(const struct udevice *dev, char *out_name) | |
230 | * { | |
231 | * return acpi_copy_name(out_name, "WIBB"); | |
232 | * } | |
233 | * | |
234 | * @out_name: Place to put the name | |
235 | * @name: Name to copy | |
185f812c | 236 | * Return: 0 (always) |
7ca2850c SG |
237 | */ |
238 | int acpi_copy_name(char *out_name, const char *name); | |
239 | ||
93f7f827 SG |
240 | /** |
241 | * acpi_write_dev_tables() - Write ACPI tables required by devices | |
242 | * | |
243 | * This scans through all devices and tells them to write any tables they want | |
244 | * to write. | |
245 | * | |
185f812c | 246 | * Return: 0 if OK, -ve if any device returned an error |
93f7f827 SG |
247 | */ |
248 | int acpi_write_dev_tables(struct acpi_ctx *ctx); | |
249 | ||
763bad3e PR |
250 | /** |
251 | * acpi_fill_madt_subtbl() - Generate ACPI tables for MADT | |
252 | * | |
253 | * This is called to create the MADT sub-tables for all devices. | |
254 | * | |
255 | * @ctx: ACPI context to use | |
256 | * Return: 0 if OK, -ve on error | |
257 | */ | |
258 | int acpi_fill_madt_subtbl(struct acpi_ctx *ctx); | |
259 | ||
b5183172 SG |
260 | /** |
261 | * acpi_fill_ssdt() - Generate ACPI tables for SSDT | |
262 | * | |
263 | * This is called to create the SSDT code for all devices. | |
264 | * | |
265 | * @ctx: ACPI context to use | |
185f812c | 266 | * Return: 0 if OK, -ve on error |
b5183172 SG |
267 | */ |
268 | int acpi_fill_ssdt(struct acpi_ctx *ctx); | |
269 | ||
01694589 SG |
270 | /** |
271 | * acpi_inject_dsdt() - Generate ACPI tables for DSDT | |
272 | * | |
273 | * This is called to create the DSDT code for all devices. | |
274 | * | |
275 | * @ctx: ACPI context to use | |
185f812c | 276 | * Return: 0 if OK, -ve on error |
01694589 SG |
277 | */ |
278 | int acpi_inject_dsdt(struct acpi_ctx *ctx); | |
279 | ||
b4e84334 SG |
280 | /** |
281 | * acpi_setup_nhlt() - Set up audio information | |
282 | * | |
283 | * This is called to set up the nhlt information for all devices. | |
284 | * | |
285 | * @ctx: ACPI context to use | |
286 | * @nhlt: Pointer to nhlt information to add to | |
185f812c | 287 | * Return: 0 if OK, -ve on error |
b4e84334 SG |
288 | */ |
289 | int acpi_setup_nhlt(struct acpi_ctx *ctx, struct nhlt *nhlt); | |
290 | ||
2d7c7382 SG |
291 | /** |
292 | * acpi_add_other_item() - Add a new table to the list of ACPI tables | |
293 | * | |
294 | * This adds an entry of type ACPIT_TYPE_OTHER | |
295 | * | |
296 | * @ctx: ACPI context | |
297 | * @writer: Writer entry that generated the data | |
298 | * @type: Table type it refers to | |
299 | * @start: The start of the data (the end is obtained from ctx->current) | |
300 | * @return 0 if OK, -ENOSPC if too many items, -ENOMEM if out of memory | |
301 | */ | |
302 | int acpi_add_other_item(struct acpi_ctx *ctx, const struct acpi_writer *writer, | |
303 | void *start); | |
304 | ||
a4f82089 SG |
305 | /** |
306 | * acpi_dump_items() - Dump out the collected ACPI items | |
307 | * | |
308 | * This lists the ACPI DSDT and SSDT items generated by the various U-Boot | |
309 | * drivers. | |
310 | * | |
311 | * @option: Sets what should be dumpyed | |
312 | */ | |
313 | void acpi_dump_items(enum acpi_dump_option option); | |
314 | ||
f1858957 SG |
315 | /** |
316 | * acpi_get_path() - Get the full ACPI path for a device | |
317 | * | |
318 | * This checks for any override in the device tree and calls acpi_device_path() | |
319 | * if not | |
320 | * | |
321 | * @dev: Device to check | |
322 | * @out_path: Buffer to place the path in (should be ACPI_PATH_MAX long) | |
323 | * @maxlen: Size of buffer (typically ACPI_PATH_MAX) | |
185f812c | 324 | * Return: 0 if OK, -ve on error |
f1858957 SG |
325 | */ |
326 | int acpi_get_path(const struct udevice *dev, char *out_path, int maxlen); | |
327 | ||
18434aec SG |
328 | /** |
329 | * acpi_reset_items() - Reset the list of ACPI items to empty | |
330 | * | |
331 | * This list keeps track of DSDT and SSDT items that are generated | |
332 | * programmatically. The 'acpi items' command shows the list. Use this function | |
333 | * to empty the list, before writing new items. | |
334 | */ | |
335 | void acpi_reset_items(void); | |
336 | ||
6afa63a5 SG |
337 | /** |
338 | * acpi_write_one() - Call a single ACPI writer entry | |
339 | * | |
340 | * This handles aligning the context afterwards, if the entry flags indicate | |
341 | * that. | |
342 | * | |
343 | * @ctx: ACPI context to use | |
344 | * @entry: Entry to call | |
345 | * @return 0 if OK, -ENOENT if this writer produced an empty entry, other -ve | |
346 | * value on error | |
347 | */ | |
348 | int acpi_write_one(struct acpi_ctx *ctx, const struct acpi_writer *entry); | |
349 | ||
cc1f8c39 SG |
350 | /** |
351 | * acpi_setup_ctx() - Set up a new ACPI context | |
352 | * | |
353 | * This zeros the context and sets up the base and current pointers, ensuring | |
354 | * that they are aligned. Then it writes the acpi_start and acpi_ctx values in | |
355 | * global_data | |
356 | * | |
357 | * @ctx: ACPI context to set up | |
358 | * @start: Start address for ACPI table | |
359 | */ | |
360 | void acpi_setup_ctx(struct acpi_ctx *ctx, ulong start); | |
361 | ||
94ba15a3 SG |
362 | /** |
363 | * acpi_write_one() - Call a single ACPI writer entry | |
364 | * | |
365 | * This handles aligning the context afterwards, if the entry flags indicate | |
366 | * that. | |
367 | * | |
368 | * @ctx: ACPI context to use | |
369 | * @entry: Entry to call | |
370 | * @return 0 if OK, -ENOENT if this writer produced an empty entry, other -ve | |
371 | * value on error | |
372 | */ | |
373 | int acpi_write_one(struct acpi_ctx *ctx, const struct acpi_writer *entry); | |
374 | ||
89c2798f SG |
375 | #endif /* __ACPI__ */ |
376 | ||
7ca2850c | 377 | #endif |