/* 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 #define PEPD_DSM_NOTIFICATION_ADDITIONAL_FUNCTIONS 1 #define PEPD_DSM_NOTIFICATION_LOW_POWER_ENTRY 5 #define PEPD_DSM_NOTIFICATION_LOW_POWER_EXIT 6 External(\_SB.MS0X, MethodObj) /* * 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() { 0, 1, /* Only 1 dummy device for now */ 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) { Local0 = Buffer { 0x00 } CreateByteField(Local0, 0x00, SUPP) SUPP = PEPD_DSM_NOTIFICATION_ADDITIONAL_FUNCTIONS SUPP |= 1 << PEPD_DSM_NOTIFICATION_LOW_POWER_ENTRY SUPP |= 1 << PEPD_DSM_NOTIFICATION_LOW_POWER_EXIT Return (Local0) } Case (PEPD_DSM_NOTIFICATION_LOW_POWER_ENTRY) { /* provide board level S0ix hook */ If (CondRefOf (\_SB.MS0X)) { \_SB.MS0X(1) } Return (Buffer() { 0x00 }) } Case (PEPD_DSM_NOTIFICATION_LOW_POWER_EXIT) { /* provide board level S0ix hook */ If (CondRefOf (\_SB.MS0X)) { \_SB.MS0X(0) } 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 }) } } } } }