1/* SPDX-License-Identifier: GPL-2.0-only */ 2 3#define PEPD_DSM_UUID "e3f32452-febc-43ce-9039-932122d37721" 4#define PEPD_DSM_LPI_ENUM_FUNCTIONS 0 5#define PEPD_DSM_LPI_ADDITIONAL_FUNCTIONS 1 6#define PEPD_DSM_LPI_GET_DEVICE_CONSTRAINTS 1 7 8#define PEPD_DSM_NOTIFICATIONS_UUID "11e00d56-ce64-47ce-837b-1f898f9aa461" 9#define PEPD_DSM_NOTIFICATION_ENUM_FUNCTIONS 0 10#define PEPD_DSM_NOTIFICATION_ADDITIONAL_FUNCTIONS 1 11#define PEPD_DSM_NOTIFICATION_LOW_POWER_ENTRY 5 12#define PEPD_DSM_NOTIFICATION_LOW_POWER_EXIT 6 13 14External(\_SB.MS0X, MethodObj) 15 16/* 17 * Power Engine Plug-in Device 18 * 19 * References: 20 * * Intel Low Power S0 Idle 21 * * AMD Modern Standby BIOS Implementation Guide - #56358 22 * * Linux Kernel: drivers/acpi/x86/s2idle.c 23 * * https://docs.microsoft.com/en-us/windows-hardware/design/device-experiences/modern-standby-firmware-notifications 24 */ 25Scope (\_SB) { 26 Device (PEP) { 27 Name (_HID, "AMDI0005") 28 Name (_CID, EisaId ("PNP0D80")) 29 Name (_UID, 1) 30 31 Method (_STA, 0, NotSerialized) { 32 Return (0x0F) 33 } 34 35 /* 36 * Device constraints for low power states (may be used for debugging). 37 * For now there is only one disabled dummy device, because Windows 38 * expects at least one device and crashes without it with a bluescreen 39 * (`INTERNAL_POWER_ERROR`). Returning an empty package does not work. 40 */ 41 Name (DEVL, Package() { 42 0, 43 1, /* Only 1 dummy device for now */ 44 45 Package() { 46 Package() { 47 0, /* Disabled */ 48 "\\DUMY", /* \DUMY - not existent */ 49 0, /* Function States */ 50 0 /* Minimum D-state */ 51 } 52 } 53 }) 54 55 /* 56 * PEPD_DSM_UUID Helper method 57 * 58 * Arg0: Function Index 59 */ 60 Method (DSM0, 1, Serialized) { 61 Switch (ToInteger(Arg0)) { 62 /* 63 * Return a bit field of the supported functions for 64 * this UUID. 65 */ 66 Case (PEPD_DSM_LPI_ENUM_FUNCTIONS) { 67 Local0 = Buffer { 0x00 } 68 CreateByteField(Local0, 0x00, SUPP) 69 70 SUPP = PEPD_DSM_LPI_ADDITIONAL_FUNCTIONS 71 SUPP |= 1 << PEPD_DSM_LPI_GET_DEVICE_CONSTRAINTS 72 73 Return (Local0) 74 } 75 Case (PEPD_DSM_LPI_GET_DEVICE_CONSTRAINTS) { 76 Return (DEVL) 77 } 78 Default { 79 /* Unknown function */ 80 Return (Buffer() { 0x00 }) 81 } 82 } 83 } 84 85 /* 86 * PEPD_DSM_NOTIFICATIONS_UUID Helper method 87 * 88 * Arg0: Function Index 89 */ 90 Method (DSM1, 1, Serialized) { 91 Switch (ToInteger(Arg0)) { 92 /* 93 * Return a bit field of the supported functions for 94 * this UUID. 95 */ 96 Case (PEPD_DSM_NOTIFICATION_ENUM_FUNCTIONS) { 97 Local0 = Buffer { 0x00 } 98 CreateByteField(Local0, 0x00, SUPP) 99 100 SUPP = PEPD_DSM_NOTIFICATION_ADDITIONAL_FUNCTIONS 101 SUPP |= 1 << PEPD_DSM_NOTIFICATION_LOW_POWER_ENTRY 102 SUPP |= 1 << PEPD_DSM_NOTIFICATION_LOW_POWER_EXIT 103 104 Return (Local0) 105 } 106 Case (PEPD_DSM_NOTIFICATION_LOW_POWER_ENTRY) { 107 /* provide board level S0ix hook */ 108 If (CondRefOf (\_SB.MS0X)) { 109 \_SB.MS0X(1) 110 } 111 Return (Buffer() { 0x00 }) 112 } 113 Case (PEPD_DSM_NOTIFICATION_LOW_POWER_EXIT) { 114 /* provide board level S0ix hook */ 115 If (CondRefOf (\_SB.MS0X)) { 116 \_SB.MS0X(0) 117 } 118 Return (Buffer() { 0x00 }) 119 } 120 Default { 121 /* Unknown function */ 122 Return (Buffer() { 0x00 }) 123 } 124 } 125 } 126 127 /* 128 * Device Specific Method 129 * 130 * Arg0: UUID 131 * Arg1: Revision Id 132 * Arg2: Function Index 133 */ 134 Method (_DSM, 4, Serialized) { 135 Switch (ToBuffer(Arg0)) { 136 Case (ToUUID(PEPD_DSM_UUID)) { 137 /* Unsupported Revision */ 138 If (ToInteger(Arg1) != 0) { 139 Return (Buffer() { 0x00 }) 140 } 141 142 Return (DSM0(Arg2)) 143 } 144 Case (ToUUID(PEPD_DSM_NOTIFICATIONS_UUID)) { 145 /* Unsupported Revision */ 146 If (ToInteger(Arg1) != 0) { 147 Return (Buffer() { 0x00 }) 148 } 149 150 Return (DSM1(Arg2)) 151 } 152 Default { 153 Return (Buffer { 0x00 }) 154 } 155 } 156 } 157 } 158} 159