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 <sjg@chromium.org> 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 19 /* Length of an ACPI name string, excluding null terminator */ 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 25 /* Number of nested objects supported */ 26 #define ACPIGEN_LENSTACK_SIZE 10 27 28 #if !defined(__ACPI__) 29 30 struct nhlt; 31 struct udevice; 32 33 /** enum acpi_dump_option - selects what ACPI information to dump */ 34 enum acpi_dump_option { 35 ACPI_DUMP_LIST, /* Just the list of items */ 36 ACPI_DUMP_CONTENTS, /* Include the binary contents also */ 37 }; 38 39 /** 40 * struct acpi_ctx - Context used for writing ACPI tables 41 * 42 * This contains a few useful pieces of information used when writing 43 * 44 * @base: Base address of ACPI tables 45 * @current: Current address for writing 46 * @rsdp: Pointer to the Root System Description Pointer, typically used when 47 * adding a new table. The RSDP holds pointers to the RSDT and XSDT. 48 * @rsdt: Pointer to the Root System Description Table 49 * @xsdt: Pointer to the Extended System Description Table 50 * @nhlt: Intel Non-High-Definition-Audio Link Table (NHLT) pointer, used to 51 * build up information that audio codecs need to provide in the NHLT ACPI 52 * table 53 * @len_stack: Stack of 'length' words to fix up later 54 * @ltop: Points to current top of stack (0 = empty) 55 */ 56 struct acpi_ctx { 57 void *base; 58 void *current; 59 struct acpi_rsdp *rsdp; 60 struct acpi_rsdt *rsdt; 61 struct acpi_xsdt *xsdt; 62 struct nhlt *nhlt; 63 char *len_stack[ACPIGEN_LENSTACK_SIZE]; 64 int ltop; 65 }; 66 67 /** 68 * struct acpi_ops - ACPI operations supported by driver model 69 */ 70 struct acpi_ops { 71 /** 72 * get_name() - Obtain the ACPI name of a device 73 * 74 * @dev: Device to check 75 * @out_name: Place to put the name, must hold at least ACPI_NAME_MAX 76 * bytes 77 * @return 0 if OK, -ENOENT if no name is available, other -ve value on 78 * other error 79 */ 80 int (*get_name)(const struct udevice *dev, char *out_name); 81 82 /** 83 * write_tables() - Write out any tables required by this device 84 * 85 * @dev: Device to write 86 * @ctx: ACPI context to use 87 * @return 0 if OK, -ve on error 88 */ 89 int (*write_tables)(const struct udevice *dev, struct acpi_ctx *ctx); 90 91 /** 92 * fill_ssdt() - Generate SSDT code for a device 93 * 94 * This is called to create the SSDT code. The method should write out 95 * whatever ACPI code is needed by this device. It will end up in the 96 * SSDT table. 97 * 98 * Note that this is called 'fill' because the entire contents of the 99 * SSDT is build by calling this method on all devices. 100 * 101 * @dev: Device to write 102 * @ctx: ACPI context to use 103 * @return 0 if OK, -ve on error 104 */ 105 int (*fill_ssdt)(const struct udevice *dev, struct acpi_ctx *ctx); 106 107 /** 108 * inject_dsdt() - Generate DSDT code for a device 109 * 110 * This is called to create the DSDT code. The method should write out 111 * whatever ACPI code is needed by this device. It will end up in the 112 * DSDT table. 113 * 114 * Note that this is called 'inject' because the output of calling this 115 * method on all devices is injected into the DSDT, the bulk of which 116 * is written in .asl files for the board. 117 * 118 * @dev: Device to write 119 * @ctx: ACPI context to use 120 * @return 0 if OK, -ve on error 121 */ 122 int (*inject_dsdt)(const struct udevice *dev, struct acpi_ctx *ctx); 123 124 /** 125 * setup_nhlt() - Set up audio information for this device 126 * 127 * The method can add information to ctx->nhlt if it likes 128 * 129 * @return 0 if OK, -ENODATA if nothing to add, -ve on error 130 */ 131 int (*setup_nhlt)(const struct udevice *dev, struct acpi_ctx *ctx); 132 }; 133 134 #define device_get_acpi_ops(dev) ((dev)->driver->acpi_ops) 135 136 /** 137 * acpi_get_name() - Obtain the ACPI name of a device 138 * 139 * @dev: Device to check 140 * @out_name: Place to put the name, must hold at least ACPI_NAME_MAX 141 * bytes 142 * @return 0 if OK, -ENOENT if no name is available, other -ve value on 143 * other error 144 */ 145 int acpi_get_name(const struct udevice *dev, char *out_name); 146 147 /** 148 * acpi_copy_name() - Copy an ACPI name to an output buffer 149 * 150 * This convenience function can be used to return a literal string as a name 151 * in functions that implement the get_name() method. 152 * 153 * For example: 154 * 155 * static int mydev_get_name(const struct udevice *dev, char *out_name) 156 * { 157 * return acpi_copy_name(out_name, "WIBB"); 158 * } 159 * 160 * @out_name: Place to put the name 161 * @name: Name to copy 162 * @return 0 (always) 163 */ 164 int acpi_copy_name(char *out_name, const char *name); 165 166 /** 167 * acpi_write_dev_tables() - Write ACPI tables required by devices 168 * 169 * This scans through all devices and tells them to write any tables they want 170 * to write. 171 * 172 * @return 0 if OK, -ve if any device returned an error 173 */ 174 int acpi_write_dev_tables(struct acpi_ctx *ctx); 175 176 /** 177 * acpi_fill_ssdt() - Generate ACPI tables for SSDT 178 * 179 * This is called to create the SSDT code for all devices. 180 * 181 * @ctx: ACPI context to use 182 * @return 0 if OK, -ve on error 183 */ 184 int acpi_fill_ssdt(struct acpi_ctx *ctx); 185 186 /** 187 * acpi_inject_dsdt() - Generate ACPI tables for DSDT 188 * 189 * This is called to create the DSDT code for all devices. 190 * 191 * @ctx: ACPI context to use 192 * @return 0 if OK, -ve on error 193 */ 194 int acpi_inject_dsdt(struct acpi_ctx *ctx); 195 196 /** 197 * acpi_setup_nhlt() - Set up audio information 198 * 199 * This is called to set up the nhlt information for all devices. 200 * 201 * @ctx: ACPI context to use 202 * @nhlt: Pointer to nhlt information to add to 203 * @return 0 if OK, -ve on error 204 */ 205 int acpi_setup_nhlt(struct acpi_ctx *ctx, struct nhlt *nhlt); 206 207 /** 208 * acpi_dump_items() - Dump out the collected ACPI items 209 * 210 * This lists the ACPI DSDT and SSDT items generated by the various U-Boot 211 * drivers. 212 * 213 * @option: Sets what should be dumpyed 214 */ 215 void acpi_dump_items(enum acpi_dump_option option); 216 217 /** 218 * acpi_get_path() - Get the full ACPI path for a device 219 * 220 * This checks for any override in the device tree and calls acpi_device_path() 221 * if not 222 * 223 * @dev: Device to check 224 * @out_path: Buffer to place the path in (should be ACPI_PATH_MAX long) 225 * @maxlen: Size of buffer (typically ACPI_PATH_MAX) 226 * @return 0 if OK, -ve on error 227 */ 228 int acpi_get_path(const struct udevice *dev, char *out_path, int maxlen); 229 230 /** 231 * acpi_reset_items() - Reset the list of ACPI items to empty 232 * 233 * This list keeps track of DSDT and SSDT items that are generated 234 * programmatically. The 'acpi items' command shows the list. Use this function 235 * to empty the list, before writing new items. 236 */ 237 void acpi_reset_items(void); 238 239 #endif /* __ACPI__ */ 240 241 #endif 242