From dfe3a2fcfca5ade7d82ed7e92758e5f329c28880 Mon Sep 17 00:00:00 2001 From: Raul E Rangel Date: Fri, 16 Apr 2021 12:16:55 -0600 Subject: [PATCH] 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 Change-Id: I2deef47eabe702efe1a0f3747c9f27bcec37464b Reviewed-on: https://review.coreboot.org/c/coreboot/+/52445 Reviewed-by: Marshall Dawson Reviewed-by: Furquan Shaikh Tested-by: build bot (Jenkins) --- src/soc/amd/cezanne/acpi/soc.asl | 2 + src/soc/amd/common/acpi/upep.asl | 131 +++++++++++++++++++++++++++++++ 2 files changed, 133 insertions(+) create mode 100644 src/soc/amd/common/acpi/upep.asl diff --git a/src/soc/amd/cezanne/acpi/soc.asl b/src/soc/amd/cezanne/acpi/soc.asl index 30b44c948d..be511042e4 100644 --- a/src/soc/amd/cezanne/acpi/soc.asl +++ b/src/soc/amd/cezanne/acpi/soc.asl @@ -19,6 +19,8 @@ Scope(\_SB) { #include +#include + /* * Platform Wake Notify * 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 }) + } + } + } + } +}