dGPU draws power after sleep
Please stop and read this carefully. Otherwise your issue will be left unanswered and closed.
We require the following for guide issues:
-
Guide(s) in question: Disabling Laptop dGPUs
-
Link to page(s) with the issue: https://dortania.github.io/Getting-Started-With-ACPI/Laptops/laptop-disable.html
-
Clearly explain the issue(s) with the page(s) (if there is a visual issue, a screenshot is required): Using the SSDT-NoHybGfx.aml in OpenCore disables dGPU on boot, but when putting my laptop to sleep and looking at HWMonitor, the GPU uses more power than before entering sleep. Eg. In attached screenshots, before sleep, my CPU Package total power will go down to 0.60W, but after sleep, will not go below 1.40W. Have a Intel i7-7700 with a Intel 630/Nvidia 1050ti GPU Before Sleep:
After Sleep:

-
Include possible fixes
- Depending on the complexity of the fix, sources may be required: Incorporating the SSDT-PTSWAK.aml from Rehabman, but only including the dGPU stuff within SSDT-NoHybGfx.aml while also applying both renames _PTS and _WAK to _ZPTS and _ZWAK OpenCore patches causes power to remain proper after sleep.
Are you sure it's dGPU? My laptop does basically the exact same thing with package power and I've tried repeatedly shutting off the dGPU on wake from sleep. Additionally, dGPUs draw a lot of power generally - and CPU package is not a good way to look at total system usage (coconut battery works generally well for looking at total system draw).
I'm taking a look at it - and it does seem like GPU does have an affect on package power like you said. Though my system behaves really oddly - _OFF keeps package power high (but GPU off) no matter what. So I have to use the _DSM method, and package power still goes high after waking from sleep for me.
This would probably be helpful for other people though potentially.
Are you sure it's dGPU? My laptop does basically the exact same thing with package power and I've tried repeatedly shutting off the dGPU on wake from sleep. Additionally, dGPUs draw a lot of power generally - and CPU package is not a good way to look at total system usage (coconut battery works generally well for looking at total system draw).
Yeah I agree my method for measuring the differences were not that good as just noticed my battery life was always less when resuming from sleep, so using HWMonitor was the first tool where I've noticed that change. At first I didn't know what it was causing the high usage after sleep, but using the PTSWAK method in addition to the SSDT to disable the dGPU on boot, CPU power suddenly is where boot levels are and my battery life has improved.
I'm taking a look at it - and it does seem like GPU does have an affect on package power like you said. Though my system behaves really oddly - _OFF keeps package power high (but GPU off) no matter what. So I have to use the _DSM method, and package power still goes high after waking from sleep for me.
This would probably be helpful for other people though potentially.
Yeah just was posting hoping it would help other people and not sure if there is a way to also use the _DSM or _PS3 method for when the laptop is preparing to sleep (PTS) and when it wakes up (WAK). This method does work on boot, just seems to not keep in effect after sleep at least seems to with some configurations.
I am not as fluent is SSDT creation and understanding code, so certainly hope this helps in improving this project as wanted to post my findings.
Hey @1Revenger1 @Andrw0830,
according to my research the problem is vendor-specific. F.e. on my Thinkpda T480, one need to call RP01.HGOF () ("hybrid graphics off") to set some vars on the PCI-device which prohibit its restart on wake.
My solution:
DefinitionBlock("", "SSDT", 2, "T480", "_OFFDGPU", 0x00001000)
{
External (OSDW, MethodObj)
External (_SB.PCI0, DeviceObj)
External (_SB.PCI0.RP01, DeviceObj)
External (_SB.PCI0.HGOF, MethodObj) // 0 Arguments
External (P8XH, MethodObj) // 2 Arguments
External (_SB.PCI0.RP01.VDID, FieldUnitObj)
External (_SB.PCI0.RP01.LDIS, FieldUnitObj)
External (_SB.PCI0.LPCB.DGRT, IntObj)
External (_SB.PCI0.LPCB.DGON, IntObj)
// Disable dGPU on PCIe-Level
Scope (_SB.PCI0.RP01)
{
Method (DOFF, 0, Serialized)
{
Debug = "OFFDGPU:DOFF()"
// Debug = "OFFDGPU:VDID: (before)"
// Debug = VDID
// disable dGPU
\P8XH (Zero, 0x21)
^^HGOF ()
\P8XH (Zero, 0x22)
// disable rp01-pci-bridge
^^LPCB.DGRT = Zero
^^LPCB.DGON = Zero
LDIS = One
// Debug = "OFFDGPU:DGRT: (after)"
// Debug = ^^LPCB.DGRT
// Debug = "OFFDGPU:DGON: (after)"
// Debug = ^^LPCB.DGON
// Debug = "OFFDGPU:VDID: (after)"
// Debug = VDID
}
Method (_STA, 0, Serialized)
{
// Debug = "OFFDGPU:_STA"
If (OSDW())
{
DOFF ()
Return (Zero)
}
Return (0x0F)
}
Method (_PS0, 0, Serialized)
{
// Debug = "OFFDGPU:_PS0"
If (OSDW())
{
DOFF ()
}
}
Method (_PS3, 0, Serialized)
{
// Debug = "OFFDGPU:_PS3"
If (OSDW())
{
DOFF ()
}
}
}
}
@benbender looks like it differs between even models to - I don't have some of those methods and stuff like DGON are methods, while HGOF doesn't exist for me.
Yay...lol
_SB.PCI0.HGON() / _SB.PCI0.HGOF() belong to nvidias optimus-reference-implementation afaik.
@benbender Thanks for the findings! Yeah it sucks it seems like it is depends on what vendor you have. Wonder if there is a way to incorporate all the different call methods into one file so it will only call the ones that are relevant for the particular hardware.
Is there any files or details needed for troubleshooting the ones for my and maybe other Dell computers that have Nvidia Optimus?
@benbender are you aware what offsets are being set in ACPI? I'd guess that they'd be pretty similar even if the overlying methods are different.
Edit: Oh - found a method which enables/disables the PEG0 device which is the bridge to the Nvidia GPU. Called PGOF/PGON
@1Revenger1 yes - basically this method: https://github.com/daliansky/OC-little/blob/master/docs/16-%E7%A6%81%E6%AD%A2PCI%E8%AE%BE%E5%A4%87/SSDT-RP01.PXSX-disbale.dsl
But the problem with sleep is more likely some kind of method to reenable the dGPU on _WAK(), on the pciE-port or similar. And afaik, there is no standard or similar for this.
PS: One generic method could be to check in _TTS() if the PCIe-port is enabled and shut it down if it is. _TTS() runs pretty late.