jlempen / Surface-Go-2-OpenCore

macOS on the Core m3-8100Y Microsoft Surface Go 2 thanks to Acidanthera's OpenCore bootloader
MIT License
27 stars 3 forks source link

Hibernation results in instant wake if Surface Type Cover is connected #1

Closed lazd closed 11 months ago

lazd commented 1 year ago

I know sleep doesn't work (wakes up to a Surface logo that never goes away), but I did find that hibernate works great with one caveat: if you have the Surface Type Cover connected, it instantly wakes up.

  1. Disable all Bluetooth kexts -- these have also been causing some instant wake issues, so we want to rule them out for this test.
  2. Enable hibernate with sudo pmset -a hibernatemode 25;
  3. With the Surface Type Cover connected, choose Apple Menu -> Sleep. You'll see it go all the way to sleep and power off, then immediately wake up, boot to OpenCore, then restore from hibernate (it does so in 14-16 seconds!).
  4. Run pmset -g log | grep -e "Sleep.*due to" -e "Wake.*due to" and observe:
2023-04-06 10:02:55 -0700 Sleep                 Entering Sleep state due to 'Software Sleep pid=167':TCPKeepAlive=disabled Using AC (Charge:100%) 32 secs   
2023-04-06 10:03:27 -0700 Wake                  Wake from Standby [CDNVA] : due to /Lid Open Using AC (Charge:100%) 

Then, disconnect the type cover and choose Apple Menu -> Sleep again. No instant wake! If you then press the power button, it wakes right back up and comes alive in 14-16 seconds.

As stated above, I was getting some GLAN XDCI wakes before removing all Bluetooth kexts, as well as a couple random kernel panics, but that's for another issue once I figure this out...

lazd commented 1 year ago

@balopez83 I saw you were working on Surface stuff as well, any ideas here?

balopez83 commented 1 year ago

@lazd Judging by the date of last update to this EFI, I suspect it is using an old version of VoodooI2C that simply needs to be updated. I have a version of the VoodooI2C.kext and VoodooI2CHID.kext that is patched to support the Surface Type Cover natively that can be pulled from my Surface Pro 3 repository here and this should resolve this issue. The vanilla release of VoodooI2C will also work and has now been patched however you won't have full support touch screen support or TypeCover support.

Not sure if the touch screen is enabled with this EFI but if you use the latest version of BigSurface.kext instead of VoodooI2C.kext (removing all kexts and patches indicated on that github page) you will likely gain touch support as well. The latest version of BigSurface.kext has also implemented my patches to resolve the reboot issue caused by kernel panics.

Hope this helps but if not just send me another message and I can look into this deeper..

balopez83 commented 1 year ago

@lazd One other thing; I have actually never had full sleep or hibernation support working on the Surface devices however I may test that again now after you issue here. The only thing that I have gotten working is more of an high power sleep. I don't think I have ever tested this without the Type Cover connected and so while I hope hibernation has been resolved with the latest patches it might actually shed some light on the real issue and why I never cracked hibernation. Please test either the latest BigSurface or my patched kext and see if it resolves your issue with hibernation and let me know. I have some things going on personally that will keep me from looking into this for awhile but depending on what you report back I will take a look.

lazd commented 1 year ago

hey @balopez83! I pinged you on Gitter earlier, you still use it?

Yes, touch is enabled and I'm running the latest main branch of VoodooI2C, plus some patches I recently submitted that fix double, right click, and phantom touches (see https://github.com/VoodooI2C/VoodooI2CHID/pull/69). I do have the Type Cover trackpad patch from this PR https://github.com/VoodooI2C/VoodooI2CHID/pull/48 pulled into the build I'm using, so I'm good there. My touchscreen works perfectly (except no pen support), and my TypeCover + trackpad work great (all buttons work, multitouch, etc).

I've removed VoodooI2C, ran older version of it, etc, and it doesn't prevent this issue -- the only way to stop it is to unplug the type cover!

Let me try BigSurface.kext, and your patched VoodooI2C, but I should definitely note that this Surface Go 2 has different hardware than other Surfaces, and the README for BigSurface does not list it as compatible, so I think we're in uncharted territory here...

Hardwre

Working

Partially working

Not working

lazd commented 1 year ago

I have a version of the VoodooI2C.kext and VoodooI2CHID.kext that is patched to support the Surface Type Cover natively that can be pulled from my Surface Pro 3 repository here and this should resolve this issue.

@balopez83 I gave your VoodooI2C and VoodooI2CHID kexts a try, and unfortunately it still wakes right up.

I also tried covering each one of the pins individually on the Type Cover, and there was only one that I could cover and still have the Type Cover work, but that didn't help sleep.

I've also tried creating scripts that run on sleep and wake with sleepwatcher, and in those scripts I've tried unloading kexts on sleep:

I was going to try to use uhubctl in conjunction with sleepwatcher to disable USB ports on sleep, but it doesn't recognize any of the inbuilt USB devices (only hubs that I connect externally), so I can't use that to power down the keyboard on sleep.

Finally, I tried editing my SSDT-EC-USBX-LAPTOP.aml to set kUSBSleepPowerSupply and kUSBSleepPortCurrentLimit to Zero, but that did nothing. I have a feeling there's some patching that could be done to shut off the USB controller on sleep... We don't have to worry about turning it on again on wake, since powering back on from hibernation is just a complete boot (and a handoff to macOS to restore from hibernation), so I'd assume it would just come back on... Any ideas there?

lazd commented 1 year ago

Also, it's worth noting that pmset reports /Lid for the reason of both the instant wake AND if you hibernate without the Type Cover connected, and wake using the power button...

Successful hibernate with Type Cover disconnected (wake with power button)

2023-04-06 11:59:24 -0700 Sleep                 Entering Sleep state due to 'Software Sleep pid=168':TCPKeepAlive=disabled Using AC (Charge:100%) 12313 secs
2023-04-06 15:24:37 -0700 Wake                  Wake from Standby [CDNVA] : due to /Lid Open Using AC (Charge:100%) 536 secs  

Hibernate + instant wake with Type Cover connected

2023-04-07 09:25:42 -0700 Sleep                 Entering Sleep state due to 'Software Sleep pid=170':TCPKeepAlive=disabled Using AC (Charge:100%) 37 secs   
2023-04-07 09:26:19 -0700 Wake                  Wake from Standby [CDNVA] : due to /Lid Open Using AC (Charge:100%)     

That seems a little strange... I tried setting sudo pmset lidwake 0, but of course, that has no effect (option doesn't show up in pmset -g anyway).

My guess is that the Type Cover is doing something funky as it's being powered down, because I see its keyboard backlight on for about 20 seconds as the machine is going into hibernation. Then, it shuts off for a few seconds, then comes back on for a few seconds... A few seconds later, I see the Surface logo as the machine wakes up.

lazd commented 1 year ago

Well this ended up being way easier than I made it. I applied the GPRW/UPRW/LANC Instant Wake Patch and it hibernates without instant wake and wakes up from hibernation perfectly.

I had tried this before, but had only added the SSDT, I hadn't applied to patch! The reason I reported it was working in Big Sur was because the config.plist from kingo's repo had the patch applied.

Mystery solved!

balopez83 commented 1 year ago

@lazd Sorry it took so long to get back to you. I'm glad you figured it out. I did assume it had to do with the way i2c interacts over USB. It seems notoriously problematic on Surface devices.

I'll look into that patch as well as it might be the fix to resolve sleep on other Surface devices.

lazd commented 1 year ago

No worries, thanks @balopez83! Now I just have to solve HDMI/DisplayPort over Type-C, Stylus, device power button for sleep, and HiDPI resolutions when rotated and it'll be good to go!

You should get a Surface Go 2, it's a cute little machine and seems like a bit more of it is working under macOS than the larger Surfaces!

balopez83 commented 1 year ago

@lazd maybe someday but for now I prob won't be able to help too much.

I do have a question. Does your Surface Go 2 have S4 sleep in your DSDT? I think on Surface devices it's labeled a little differently but the Sx sleep options should be there. I ask cause the older Surface devices don't have it which I think prevents Hibernation from working however I could be wrong. If you don't have it then perhaps I am still missing something.

lazd commented 1 year ago

@balopez83 yep it's definitely mentioned in there, you can peep the DSDT here.

Hibernation has been working pretty decently since this change, though I have had a couple random KPs, the most recent one seemingly due to VoodooI2CServices/IOUSBHostFamily. No problems hibernating/waking over the last 3 days before this, though!

balopez83 commented 1 year ago

@lazd

Any chance you can send me your config and acpi files for the go? I got the Surface pro 3 to hibernate properly finally but the Surface pro 4 and Book won't and I can't figure it out. The DSDT of the go is very similar and so don't quite understand why it seems to fail.

lazd commented 1 year ago

@balopez83 yep, sent on Gitter!

u8915055 commented 1 year ago

Any chance whoever has the surface go 2 could show me an output of pmset -g? I have one and i have been playing with the various options to get it to hibernate but it just wont. Ofcourse sleep does the surface logo of death sort of thing. Im using the EFI repository in this project here but i upgraded what was available on opencore 0.94. The machine is running fine, a little battery hungry (power mgmt doenst seem to slow the CPU down maybe) but touchscreen and pen and all work just fine. I just cant get any form of sleep or hibernate to disk to work. The screen goes blank and eventually it just reboots.

Here's my output of pmset -g. Oh and for some reason the power button my surface go 2 does nothing.

System-wide power settings:
Currently in use:
 standby              0
 womp                 0
 halfdim              1
 hibernatefile        /var/vm/sleepimage
 proximitywake        0
 powernap             0
 gpuswitch            2
 networkoversleep     0
 disksleep            10
 standbydelayhigh     86400
 sleep                0 (sleep prevented by nsurlsessiond)
 hibernatemode        0
 ttyskeepawake        0
 displaysleep         10
 tcpkeepalive         0
 highstandbythreshold 50
 lowpowermode         0
 standbydelaylow      10800

Thank you!

balopez83 commented 1 year ago

@u8915055 See @lazd comment above regarding GPRW Patching

It needs to be added to your ACPI folder and your config.plist. Once done and once you set your PMSET to 25 it should work properly. I believe it's two total SSDT files and 3 DSDT patches to get it working.

The above fix worked on quite a few Surface devices including the Go

lazd commented 1 year ago

Any chance whoever has the surface go 2 could show me an output of pmset -g?

@u8915055 Sure, here ya go:

System-wide power settings:
 SleepDisabled      0
Currently in use:
 standby              1
 halfdim              1
 hibernatefile        /var/vm/sleepimage
 proximitywake        0
 gpuswitch            2
 powernap             0
 disksleep            10
 standbydelayhigh     86400
 sleep                1 (sleep prevented by nsurlsessiond, nsurlsessiond, nsurlsessiond, nsurlsessiond, nsurlsessiond, nsurlsessiond, nsurlsessiond, nsurlsessiond, nsurlsessiond, nsurlsessiond, nsurlsessiond, nsurlsessiond, nsurlsessiond, nsurlsessiond, nsurlsessiond, nsurlses
 hibernatemode        25
 ttyskeepawake        1
 displaysleep         2
 tcpkeepalive         1
 highstandbythreshold 50
 lowpowermode         0
 standbydelaylow      10800

Here are my shell functions I wrote while testing sleep, use togglehibernate to enable hibernate power management settings:

# pass 0 to disable, anything else to enable
function togglehibernate() {
    if [ "$1" -eq "0" ]
        then
            echo Disabling hibernate
            togglesleep 1
        else
            echo Enabling hibernate
            togglesleep 1
            sudo pmset -a hibernatemode 25;
    fi
}

# pass 0 to disable, anything else to enable
function togglesleep() {
    if [ "$1" -eq "0" ]
        then
            echo Disabling sleep
            sudo pmset -a sleep 0; sudo pmset -a hibernatemode 0; sudo pmset -a disablesleep 1;
        else
            echo Enabling sleep
            sudo pmset -a sleep 1; sudo pmset -a hibernatemode 3; sudo pmset -a disablesleep 0;
            sudo pmset restoredefaults;
    fi
}
lazd commented 1 year ago

but touchscreen and pen and all work just fine

@u8915055 You said you have pen working? I could never get my pen working at all! Any tricks? Note that I did author some new code over at VoodooI2C to make the touchscreen work nicer with fingers, that's worth checking out. They should drop in VoodooI2C 2.9, which will release later this year. I attached the kexts for you to give it a whirl -- can you please test and confirm if your pen works with the next kexts??

VoodooI2C-SurfaceTouch.zip

u8915055 commented 1 year ago

Hey there @lazd , ya i will admit im very new to this.. so im still working away on understanding the ACPI stuff and what i would need to do following your instructions to get hibernate to work properly. However i used this repository to build my EFI for my Surface Go 2 and then most recently upgraded to opencore 0.94 by just copying over the relevant drivers and such and its been working. Now i have to admit i tried the pen after the 0.94 upgrade and im not sure it was or wasnt working before that as i couldnt find my pen :). Im more than happy to share whatever details may help you with the pen. Just tell me what you need.. The pen works really well including the button for right click.

On that note. Again learning the whole DSDT SSDT ACPI thing.. and slowly figuring it out. But to make the patches you mentioned above to get hibernate going, sounds like i need to include an EFI tool to show me the current DSDT of the machine and then using that info i would copy over one or more of those updated GPRW UPRW LANC files depending on what i find on my machine, correct? Then i also have to make the patches in the config.plist to go with those?

Thanks for your help.

u8915055 commented 1 year ago

Oh, and i just saw the voodooI2C-SurfaceTouch file you included. Ill give that a try. I will say that when i took the stock repository here and built my EFI, and then upgraded it to 0.94 opencore.. i did not upgrade any drivers that were not included in the opencore bundle. So i didnt upgrade VoodooI2c yet.. its still runnign the version on this repository. It says its version 2.6.5.

The finger touch works, but ya as is isnt very useful.. big finger, little icons.. :)

I will give that a try.. im really getting into this now so ill have more results.

lazd commented 11 months ago

I'll go ahead and close this issue since it's solved!