summaryrefslogtreecommitdiff
path: root/src/soc/amd/common/acpi
diff options
context:
space:
mode:
authorRaul E Rangel <rrangel@chromium.org>2021-04-16 12:16:55 -0600
committerRaul Rangel <rrangel@chromium.org>2021-04-20 01:10:54 +0000
commitdfe3a2fcfca5ade7d82ed7e92758e5f329c28880 (patch)
treea1fb377724090e92540e0996046d72cc899e027e /src/soc/amd/common/acpi
parentb922cbbdd6bad68f9d3c6f1c6de6b557646c5dbb (diff)
soc/amd/{common,cezanne}: Add uPEP device
The uPEP device is required to support S0i3. The device has been written in ASL to make it easier to read and maintain. The device constraints are purely informational. We use a dummy constraint like the Intel platforms to keep both linux and Windows functional. In order for this device to be used by the linux kernel the ACPI_FADT_LOW_PWR_IDLE_S0 flag must be set. So including it unconditionally doesn't cause any problems. The AMD Modern Standby BIOS Implementation Guide defines two UUIDs, one for getting the device constraints, and one for handling notifications. This differs from the Intel specification and the linux driver implementation. For this reason I haven't implemented any of the notification callbacks yet. BUG=b:178728116 TEST=Boot OS and verify _DSM is called: [ 0.226701] lps0_device_attach: ACPI: \_SB_.PEP_: _DSM function mask: 0x3 [ 0.226722] lpi_device_get_constraints_amd: ACPI: \_SB_.PEP_: _DSM function 1 eval successful [ 0.226723] lpi_device_get_constraints_amd: ACPI: \_SB_.PEP_: LPI: constraints list begin: [ 0.226724] lpi_device_get_constraints_amd: ACPI: \_SB_.PEP_: LPI: constraints list end Signed-off-by: Raul E Rangel <rrangel@chromium.org> Change-Id: I2deef47eabe702efe1a0f3747c9f27bcec37464b Reviewed-on: https://review.coreboot.org/c/coreboot/+/52445 Reviewed-by: Marshall Dawson <marshalldawson3rd@gmail.com> Reviewed-by: Furquan Shaikh <furquan@google.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'src/soc/amd/common/acpi')
-rw-r--r--src/soc/amd/common/acpi/upep.asl131
1 files changed, 131 insertions, 0 deletions
diff --git a/src/soc/amd/common/acpi/upep.asl b/src/soc/amd/common/acpi/upep.asl
new file mode 100644
index 0000000000..3fcf2f7eb4
--- /dev/null
+++ b/src/soc/amd/common/acpi/upep.asl
@@ -0,0 +1,131 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#define PEPD_DSM_UUID "e3f32452-febc-43ce-9039-932122d37721"
+#define PEPD_DSM_LPI_ENUM_FUNCTIONS 0
+#define PEPD_DSM_LPI_ADDITIONAL_FUNCTIONS 1
+#define PEPD_DSM_LPI_GET_DEVICE_CONSTRAINTS 1
+
+#define PEPD_DSM_NOTIFICATIONS_UUID "11e00d56-ce64-47ce-837b-1f898f9aa461"
+#define PEPD_DSM_NOTIFICATION_ENUM_FUNCTIONS 0
+
+/*
+ * Power Engine Plug-in Device
+ *
+ * References:
+ * * Intel Low Power S0 Idle
+ * * AMD Modern Standby BIOS Implementation Guide - #56358
+ * * Linux Kernel: drivers/acpi/x86/s2idle.c
+ * * https://docs.microsoft.com/en-us/windows-hardware/design/device-experiences/modern-standby-firmware-notifications
+ */
+Scope (\_SB) {
+ Device (PEP) {
+ Name (_HID, "AMDI0005")
+ Name (_CID, EisaId ("PNP0D80"))
+ Name (_UID, One)
+
+ Method (_STA, 0, NotSerialized) {
+ Return (0x0F)
+ }
+
+ /*
+ * Device constraints for low power states (may be used for debugging).
+ * For now there is only one disabled dummy device, because Windows
+ * expects at least one device and crashes without it with a bluescreen
+ * (`INTERNAL_POWER_ERROR`). Returning an empty package does not work.
+ */
+ Name (DEVL, Package() {
+ Package() {
+ 0, /* Disabled */
+ "\\DUMY", /* \DUMY - not existent */
+ 0, /* Function States */
+ 0 /* Minimum D-state */
+ }
+ })
+
+ /*
+ * PEPD_DSM_UUID Helper method
+ *
+ * Arg0: Function Index
+ */
+ Method (DSM0, 1, Serialized) {
+ Switch (ToInteger(Arg0)) {
+ /*
+ * Return a bit field of the supported functions for
+ * this UUID.
+ */
+ Case (PEPD_DSM_LPI_ENUM_FUNCTIONS) {
+ Local0 = Buffer { 0x00 }
+ CreateByteField(Local0, 0x00, SUPP)
+
+ SUPP = PEPD_DSM_LPI_ADDITIONAL_FUNCTIONS
+ SUPP |= 1 << PEPD_DSM_LPI_GET_DEVICE_CONSTRAINTS
+
+ Return (Local0)
+ }
+ Case (PEPD_DSM_LPI_GET_DEVICE_CONSTRAINTS) {
+ Return (DEVL)
+ }
+ Default {
+ /* Unknown function */
+ Return (Buffer() { 0x00 })
+ }
+ }
+ }
+
+ /*
+ * PEPD_DSM_NOTIFICATIONS_UUID Helper method
+ *
+ * Arg0: Function Index
+ */
+ Method (DSM1, 1, Serialized) {
+ Switch (ToInteger(Arg0)) {
+ /*
+ * Return a bit field of the supported functions for
+ * this UUID.
+ */
+ Case (PEPD_DSM_NOTIFICATION_ENUM_FUNCTIONS) {
+ /*
+ * TODO(b/185586290): Add additional functions when
+ * linux kernel driver is fixed.
+ */
+ Return (Buffer() { 0x00 })
+ }
+ Default {
+ /* Unknown function */
+ Return (Buffer() { 0x00 })
+ }
+ }
+ }
+
+ /*
+ * Device Specific Method
+ *
+ * Arg0: UUID
+ * Arg1: Revision Id
+ * Arg2: Function Index
+ */
+ Method (_DSM, 4, Serialized) {
+ Switch (ToBuffer(Arg0)) {
+ Case (ToUUID(PEPD_DSM_UUID)) {
+ /* Unsupported Revision */
+ If (ToInteger(Arg1) != 0) {
+ Return (Buffer() { 0x00 })
+ }
+
+ Return (DSM0(Arg2))
+ }
+ Case (ToUUID(PEPD_DSM_NOTIFICATIONS_UUID)) {
+ /* Unsupported Revision */
+ If (ToInteger(Arg1) != 0) {
+ Return (Buffer() { 0x00 })
+ }
+
+ Return (DSM1(Arg2))
+ }
+ Default {
+ Return (Buffer { 0x00 })
+ }
+ }
+ }
+ }
+}