• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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