bugtracker icon indicating copy to clipboard operation
bugtracker copied to clipboard

dGPU draws power after sleep

Open Andrw0830 opened this issue 5 years ago • 9 comments

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: CPU_before-sleep After Sleep: CPU_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.

Andrw0830 avatar Sep 13 '20 15:09 Andrw0830

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).

averycblack avatar Sep 13 '20 16:09 averycblack

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.

averycblack avatar Sep 13 '20 21:09 averycblack

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.

Andrw0830 avatar Sep 14 '20 01:09 Andrw0830

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 avatar Oct 27 '20 14:10 benbender

@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

averycblack avatar Oct 27 '20 18:10 averycblack

_SB.PCI0.HGON() / _SB.PCI0.HGOF() belong to nvidias optimus-reference-implementation afaik.

benbender avatar Oct 27 '20 19:10 benbender

@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?

Andrw0830 avatar Oct 27 '20 19:10 Andrw0830

@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

averycblack avatar Oct 27 '20 21:10 averycblack

@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.

benbender avatar Oct 27 '20 21:10 benbender