1# Driver Devicetree Entries 2 3Let's take a look at an example entry from 4``src/mainboard/google/hatch/variants/hatch/overridetree.cb``: 5 6``` 7device pci 15.0 on 8 chip drivers/i2c/generic 9 register "hid" = ""ELAN0000"" 10 register "desc" = ""ELAN Touchpad"" 11 register "irq" = "ACPI_IRQ_LEVEL_LOW(GPP_A21_IRQ)" 12 register "detect" = "1" 13 register "wake" = "GPE0_DW0_21" 14 device i2c 15 on end 15 end 16end # I2C #0 17``` 18 19When this entry is processed during ramstage, it will create a device in the 20ACPI SSDT table (all devices in devicetrees end up in the SSDT table). The ACPI 21generation routines in coreboot actually generate the raw bytecode that 22represents the device's structure, but looking at ASL code is easier to 23understand; see below for what the disassembled bytecode looks like: 24 25``` 26Scope (\_SB.PCI0.I2C0) 27{ 28 Device (D015) 29 { 30 Name (_HID, "ELAN0000") // _HID: Hardware ID 31 Name (_UID, Zero) // _UID: Unique ID 32 Name (_DDN, "ELAN Touchpad") // _DDN: DOS Device Name 33 Method (_STA, 0, NotSerialized) // _STA: Status 34 { 35 Return (0x0F) 36 } 37 Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings 38 { 39 I2cSerialBusV2 (0x0015, ControllerInitiated, 400000, 40 AddressingMode7Bit, "\\_SB.PCI0.I2C0", 41 0x00, ResourceConsumer, , Exclusive, ) 42 Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, ,, ) 43 { 44 0x0000002D, 45 } 46 }) 47 Name (_S0W, ACPI_DEVICE_SLEEP_D3_HOT) // _S0W: S0 Device Wake State 48 Name (_PRW, Package (0x02) // _PRW: Power Resources for Wake 49 { 50 0x15, // GPE #21 51 0x03 // Sleep state S3 52 }) 53 } 54} 55``` 56 57You can see it generates \_HID, \_UID, \_DDN, \_STA, \_CRS, \_S0W, and \_PRW 58names/methods in the Device's scope. 59 60## Utilizing a device driver 61 62The device driver must be enabled for your build. There will be a CONFIG option 63in the Kconfig file in the directory that the driver is in (e.g., 64``src/drivers/i2c/generic`` contains a Kconfig file; the option here is named 65CONFIG_DRIVERS_I2C_GENERIC). The config option will need to be added to your 66mainboard's Kconfig file (e.g., ``src/mainboard/google/hatch/Kconfig``) in order 67to be compiled into your build. 68 69## Diving into the above example: 70 71Let's take a look at how the devicetree language corresponds to the generated 72ASL. 73 74First, note this: 75 76``` 77 chip drivers/i2c/generic 78``` 79 80This means that the device driver we're using has a corresponding structure, 81located at ``src/drivers/i2c/generic/chip.h``, named **struct 82drivers_i2c_generic_config** and it contains many properties you can specify to 83be included in the ACPI table. 84 85### hid 86 87``` 88 register "hid" = ""ELAN0000"" 89``` 90 91This corresponds to **const char \*hid** in the struct. In the ACPI ASL, it 92translates to: 93 94``` 95 Name (_HID, "ELAN0000") // _HID: Hardware ID 96``` 97 98under the device. **This property is used to match the device to its driver 99during enumeration in the OS.** 100 101### desc 102 103``` 104 register "desc" = ""ELAN Touchpad"" 105``` 106 107corresponds to **const char \*desc** and in ASL: 108 109``` 110 Name (_DDN, "ELAN Touchpad") // _DDN: DOS Device Name 111``` 112 113### irq 114 115It also adds the interrupt, 116 117``` 118 Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, ,, ) 119 { 120 0x0000002D, 121 } 122``` 123 124which comes from: 125 126``` 127 register "irq" = "ACPI_IRQ_LEVEL_LOW(GPP_A21_IRQ)" 128``` 129 130The IRQ settings control the "Trigger" and "Polarity" settings seen above (level 131means it is a level-triggered interrupt as opposed to 132edge-triggered; active low means the interrupt is triggered when the signal is 133low). 134 135Also note that the IRQ names are SoC-specific, and you will need to 136find the names in your SoC's header file. The ACPI_* macros are defined in 137``src/arch/x86/include/acpi/acpi_device.h``. 138 139Using a GPIO as an IRQ requires that it is configured in coreboot correctly. 140This is often done in a mainboard-specific file named ``gpio.c``. 141 142AMD platforms don't have the ability to route GPIOs to the IO-APIC. Instead the 143GPIO controller needs to be used directly. You can do this by setting the 144`irq_gpio` register and using the `ACPI_GPIO_IRQ_X_X` macros. 145 146i.e., 147``` 148register "irq_gpio" = "ACPI_GPIO_IRQ_EDGE_LOW(GPIO_40)" 149``` 150 151### detect 152 153The next register is: 154 155``` 156 register "detect" = "1" 157``` 158 159This flag tells the I2C driver that it should attempt to detect the presence of 160the device (using an I2C zero-byte write), and only generate a SSDT entry if the 161device is actually present. This alleviates the OS from having to determine if 162a device is present or not (ChromeOS/Linux) and prevents resource conflict/ 163driver issues (Windows). 164 165Currently, the detect feature works and is hooked up for all I2C touchpads, 166and should be used any time a board has multiple touchpad options. 167I2C audio devices should also work without issue. 168 169Touchscreens can use this feature as well, but special care is needed to 170implement the proper power sequencing for the device to be detected. Generally, 171this means driving the enable GPIO high and holding the reset GPIO low in early 172GPIO init (bootblock/romstage), then releasing reset in ramstage. The first 173mainboards in the tree to implement this are google/skyrim and google/guybrush. 174This feature has also been used in downstream forks without issue for some time 175now on several other boards. 176 177### wake 178 179The last register is: 180 181``` 182 register "wake" = "GPE0_DW0_21" 183``` 184 185which indicates that the method of waking the system using the touchpad will be 186through a GPE, #21 associated with DW0, which is set up in devicetree.cb from 187this example. The "21" indicates GPP_X21, where GPP_X is mapped onto DW0 188elsewhere in the devicetree. 189 190### device 191 192The last bit of the definition of that device includes: 193 194``` 195 device i2c 15 on end 196``` 197 198which means it's an I2C device, with 7-bit address 0x15, and the device is "on", 199meaning it will be exposed in the ACPI table. The PCI device that the 200controller is located in determines which I2C bus the device is expected to be 201found on. In this example, this is I2C bus 0. This also determines the ACPI 202"Scope" that the device names and methods will live under, in this case 203"\_SB.PCI0.I2C0". 204 205## Wake sources 206 207The ACPI spec defines two methods to describe how a device can wake the system. 208Only one of these methods should be used, otherwise duplicate wake events will 209be generated. 210 211### Using GPEs as a wake source 212 213The `wake` property specified above is used to tell the ACPI subsystem that the 214device can use a GPE to wake the system. The OS can control whether to enable 215or disable the wake source by unmasking/masking off the GPE. 216 217The `GPIO` -> `GPE` mapping must be configured in firmware. On AMD platforms this is 218generally done by a mainboard specific `gpio.c` file that defines the GPIO 219using `PAD_SCI`. The `GPIO` -> `GPE` mapping is returned by the 220`soc_get_gpio_event_table` method that is defined in the SoC specific `gpio.c` 221file. On Intel platforms, you fill in the `pmc_gpe0_dw0`, `pmc_gpe0_dw1`, and 222`pmc_gpe0_dw2` fields in the devicetree to map 3 GPIO communities to `tier-1` 223GPEs (the rest are available as `tier-2` GPEs). 224 225Windows has a large caveat when using this method. If you use the `gpio_irq` 226property to define a `GpioInt` in the `_CRS`, and then use the `wake` property 227to define a `GPE`, Windows will 228[BSOD](https://github.com/MicrosoftDocs/windows-driver-docs/blob/staging/windows-driver-docs-pr/debugger/bug-check-0xa5--acpi-bios-error.md) 229complaining about an invalid ACPI configuration. 230> 0x1000D - A device used both GPE and GPIO interrupts, which is not supported. 231 232In order to avoid this error, you should use the `irq` property instead. AMD 233platforms don't support routing GPIOs to the IO-APIC, so this workaround isn't 234feasible. The other option is to use a wake capable GPIO as described below. 235 236### Using GPIO interrupts as a wake source 237 238The `ACPI_IRQ_WAKE_{EDGE,LEVEL}_{LOW,HIGH}` macros can be used when setting the 239`irq` or `gpio_irq` properties. This ends up setting `ExclusiveAndWake` or 240`SharedAndWake` on the `Interrupt` or `GpioInt` ACPI resource. 241 242This method has a few caveats: 243* On Intel and AMD platforms the IO-APIC can't wake the system. This means using 244 the `ACPI_IRQ_WAKE_*` macros with the `irq` property won't actually wake the 245 system. Instead you need to use the `gpio_irq` property, or a `GPE` as 246 described above. 247* The OS needs to know how to enable the `wake` bit on the GPIO. For linux this 248 means the platform specific GPIO controller driver must implement the 249 `irq_set_wake` callback. For AMD systems this wasn't 250 [implemented](https://github.com/torvalds/linux/commit/d62bd5ce12d79bcd6a6c3e4381daa7375dc21158) 251 until linux v5.15. If the controller doesn't define this callback, it's 252 possible for the firmware to manually set the `wake` bit on the GPIO. This is 253 often done in a mainboard-specific file named `gpio.c`. This is not 254 recommended because then it's not possible for the OS to disable the wake 255 source. 256* As of 257 [linux v6.0-rc5](https://github.com/torvalds/linux/releases/tag/v6.0-rc5), 258 the ACPI subsystem doesn't take the interrupt `wake` bit into account when 259 deciding on which power state to put the device in before suspending the 260 system. This means that if you define a power resource for a device via 261 `has_power_resource`, `enable_gpio`, etc, then the linux kernel will place the 262 device into D3Cold. i.e., power off the device. 263 264## Other auto-generated names 265 266(see [ACPI specification 2676.3](https://uefi.org/sites/default/files/resources/ACPI_6_3_final_Jan30.pdf) 268for more details on ACPI methods) 269 270### _S0W (S0 Device Wake State) 271\_S0W indicates the deepest S0 sleep state this device can wake itself from, 272which in this case is `ACPI_DEVICE_SLEEP_D3_HOT`, representing _D3hot_. 273D3Hot means the `PR3` power resources are still on and the device is still 274responsive on the bus. For i2c devices this is generally the same state as `D0`. 275 276### \_PRW (Power Resources for Wake) 277\_PRW indicates the power resources and events required for wake. There are no 278dependent power resources, but the GPE (GPE0_DW0_21) is mentioned here (0x15), 279as well as the deepest sleep state supporting waking the system (3), which is 280S3. 281 282### \_STA (Status) 283The \_STA method is generated automatically, and its values, 0xF, indicates the 284following: 285 286 Bit [0] – Set if the device is present. 287 Bit [1] – Set if the device is enabled and decoding its resources. 288 Bit [2] – Set if the device should be shown in the UI. 289 Bit [3] – Set if the device is functioning properly (cleared if device failed its diagnostics). 290 291### \_CRS (Current resource settings) 292The \_CRS method is generated automatically, as the driver knows it is an I2C 293controller, and so specifies how to configure the controller for proper 294operation with the touchpad. 295 296``` 297Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings 298{ 299 I2cSerialBusV2 (0x0015, ControllerInitiated, 400000, 300 AddressingMode7Bit, "\\_SB.PCI0.I2C0", 301 0x00, ResourceConsumer, , Exclusive, ) 302``` 303 304## Notes 305 306 - **All device driver entries in devicetrees end up in the SSDT table, and are 307 generated in coreboot's ramstage** 308 (The lone exception to this rule is i2c touchpads with the 'detect' flag set; 309 in this case, devices not present will not be added to the SSDT) 310