Contribute
Register

[Guide] Disabling discrete graphics in dual-GPU laptops

I'm having troubles to get sleep to work. Yesterday I upgraded from 10.10.5 to 10.11.5 (clean install), patched all DSDT, SSDT again. Sleep was working on 10.10.5, I just had to press power button twice from sleep state (one to wake up the system, second to turn on the screen).

Now on 10.11.5 When I put my laptop to sleep, it seems to work. It takes around 20 seconds and the power led starts to blink as expected, no fan or any other noises. However, when the power button is pressed to wake up I hear the fans start, but after a few seconds the system shutdown (using Disable/Enable on _WAK/_PTS). Without Disable/Enable on _WAK/_PTS I also hear the fans start, but the system just hangs there without showing anything on screen (I need to force shutdown using power button).

As usual, needed information attached.

You did not press F4 to collect ACPI/origin. Please read "Problem Reporting" carefully.
 

Attachments

  • Samsung_AB6.zip
    2.2 MB · Views: 77
You should not be calling _OFF from _REG. Call only from _INI.

Removed the _OFF from _REG (DSDT).

Now the system shutdown during boot. If I drop SSDT7 (where I call _OFF from _INI), the system boots.

Perhaps I need to edit something on SSDT8 too? SSDT8 contains the _OFF method.

Code:
        Method (_OFF, 0, Serialized)  // _OFF: Power Off
        {
            SGOF ()
            If (LEqual (\ECON, One))
            {
                Store (Zero, \_SB.PCI0.LPCB.H_EC.OPST)
            }

            Notify (\_SB.PCI0.PEG0, Zero)
        }
 
Removed the _OFF from _REG (DSDT).

Now the system shutdown during boot. If I drop SSDT7 (where I call _OFF from _INI), the system boots.

Since you made a change, you now need to provide the new EFI/Clover you're using.

Perhaps I need to edit something on SSDT8 too? SSDT8 contains the _OFF method.

Code:
        Method (_OFF, 0, Serialized)  // _OFF: Power Off
        {
            SGOF ()
            If (LEqual (\ECON, One))
            {
                Store (Zero, \_SB.PCI0.LPCB.H_EC.OPST)
            }

            Notify (\_SB.PCI0.PEG0, Zero)
        }

If that is your _OFF, you need to move the EC related code into _REG, per guide.
 
Since you made a change, you now need to provide the new EFI/Clover you're using.



If that is your _OFF, you need to move the EC related code into _REG, per guide.

_REG from DSDT
Code:
                    Method (_REG, 2, NotSerialized)  // _REG: Region Availability
                    {
                        If (LAnd (LEqual (Arg0, 0x03), LEqual (Arg1, One)))
                        {
                            Store (One, ECON)
                            If (LAnd (LEqual (ALSE, 0x02), IGDS))
                            {
                                Store (^ALSD._ALI (), ^^^GFX0.ALSI)
                            }

                            Store (0x03, ^^^GFX0.CLID)
                            Store (ACEX, PWRS)
                            If (LOr (LEqual (And (CPTY, 0x80), 0x80), LNotEqual (TIST, One)))
                            {
                                Store (TZCH (), RIST)
                                Store (RIST, PPCS)
                            }

                            PNOT ()
                        }
                    }

_OFF method from SSDT-8
Code:
Method (_OFF, 0, Serialized)  // _OFF: Power Off
        {
            SGOF ()
            If (LEqual (\ECON, One))
            {
                Store (Zero, \_SB.PCI0.LPCB.H_EC.OPST)
            }

            Notify (\_SB.PCI0.PEG0, Zero)
        }

This seems so different for me from your sample on the guide. Could you please point me which part of the code from SSDT8 I need to move to _REG from DSDT?
 
_REG from DSDT
Code:
                    Method (_REG, 2, NotSerialized)  // _REG: Region Availability
                    {
                        If (LAnd (LEqual (Arg0, 0x03), LEqual (Arg1, One)))
                        {
                            Store (One, ECON)
                            If (LAnd (LEqual (ALSE, 0x02), IGDS))
                            {
                                Store (^ALSD._ALI (), ^^^GFX0.ALSI)
                            }

                            Store (0x03, ^^^GFX0.CLID)
                            Store (ACEX, PWRS)
                            If (LOr (LEqual (And (CPTY, 0x80), 0x80), LNotEqual (TIST, One)))
                            {
                                Store (TZCH (), RIST)
                                Store (RIST, PPCS)
                            }

                            PNOT ()
                        }
                    }

_OFF method from SSDT-8
Code:
Method (_OFF, 0, Serialized)  // _OFF: Power Off
        {
            SGOF ()
            If (LEqual (\ECON, One))
            {
                Store (Zero, \_SB.PCI0.LPCB.H_EC.OPST)
            }

            Notify (\_SB.PCI0.PEG0, Zero)
        }

This seems so different for me from your sample on the guide. Could you please point me which part of the code from SSDT8 I need to move to _REG from DSDT?

The EC related code is:
Code:
            If (LEqual (\ECON, One))
            {
                Store (Zero, \_SB.PCI0.LPCB.H_EC.OPST)
            }

You should check SGOF too.
 
The EC related code is:
Code:
            If (LEqual (\ECON, One))
            {
                Store (Zero, \_SB.PCI0.LPCB.H_EC.OPST)
            }

You should check SGOF too.

SGOF is on SSDT-7, here's the code:
Code:
        Method (SGOF, 0, Serialized)
        {
            Store (LCTL, ELCT)
            Store (SSID, HVID)
            Store (One, LNKD)
            While (LNotEqual (LNKS, Zero))
            {
                Sleep (One)
            }

            Store (0x02, AFES)
            SGPO (HLRS, One)
            SGPO (PWEN, Zero)
            Return (Zero)
        }

So, _REG with EC code from _OFF would be like this?
Code:
                    Method (_REG, 2, NotSerialized)  // _REG: Region Availability
                    {
                        If (LAnd (LEqual (Arg0, 0x03), LEqual (Arg1, One)))
                        {
                            Store (One, ECON)
                            If (LAnd (LEqual (ALSE, 0x02), IGDS))
                            {
                                Store (^ALSD._ALI (), ^^^GFX0.ALSI)
                            }

                            Store (0x03, ^^^GFX0.CLID)
                            Store (ACEX, PWRS)
                            If (LOr (LEqual (And (CPTY, 0x80), 0x80), LNotEqual (TIST, One)))
                            {
                                Store (TZCH (), RIST)
                                Store (RIST, PPCS)
                            }
                        If (LEqual (\ECON, One))
                       {
                           Store (Zero, \_SB.PCI0.LPCB.H_EC.OPST)
                       }

                            PNOT ()
                        }
                    }
 
SGOF is on SSDT-7, here's the code:
Code:
        Method (SGOF, 0, Serialized)
        {
            Store (LCTL, ELCT)
            Store (SSID, HVID)
            Store (One, LNKD)
            While (LNotEqual (LNKS, Zero))
            {
                Sleep (One)
            }

            Store (0x02, AFES)
            SGPO (HLRS, One)
            SGPO (PWEN, Zero)
            Return (Zero)
        }

No EC related code there. But you might want to check SGPO just to make sure.

So, _REG with EC code from _OFF would be like this?
Code:
                    Method (_REG, 2, NotSerialized)  // _REG: Region Availability
                    {
                        If (LAnd (LEqual (Arg0, 0x03), LEqual (Arg1, One)))
                        {
                            Store (One, ECON)
                            If (LAnd (LEqual (ALSE, 0x02), IGDS))
                            {
                                Store (^ALSD._ALI (), ^^^GFX0.ALSI)
                            }

                            Store (0x03, ^^^GFX0.CLID)
                            Store (ACEX, PWRS)
                            If (LOr (LEqual (And (CPTY, 0x80), 0x80), LNotEqual (TIST, One)))
                            {
                                Store (TZCH (), RIST)
                                Store (RIST, PPCS)
                            }
                        If (LEqual (\ECON, One))
                       {
                           Store (Zero, \_SB.PCI0.LPCB.H_EC.OPST)
                       }

                            PNOT ()
                        }
                    }

No. You should do the EC related things only when _REG is called with the arguments that indicate the EC is ready. It is covered in the guide.

Note: Maybe it is just the poor indentation you're using (you should verify).
 
No EC related code there. But you might want to check SGPO just to make sure.

My SGPO code, also on SSDT-7, anything that I should change here?
Code:
        Method (SGPO, 2, Serialized)
        {
            ShiftRight (Arg0, 0x07, Local3)
            And (Arg0, 0x7F, Arg0)
            If (LEqual (Local3, Zero))
            {
                Not (Arg1, Local3)
                And (Local3, One, Local3)
            }
            Else
            {
                And (Arg1, One, Local3)
            }

            If (LLess (Arg0, 0x20))
            {
                ShiftLeft (Local3, Arg0, Local0)
                ShiftLeft (One, Arg0, Local1)
                And (\_SB.PCI0.PEG0.PEGP.LVL0, Not (Local1), Local2)
                Or (Local2, Local0, \_SB.PCI0.PEG0.PEGP.LVL0)
            }
            ElseIf (LLess (Arg0, 0x40))
            {
                ShiftLeft (Local3, Subtract (Arg0, 0x20), Local0)
                ShiftLeft (One, Subtract (Arg0, 0x20), Local1)
                And (\_SB.PCI0.PEG0.PEGP.LVL1, Not (Local1), Local2)
                Or (Local2, Local0, \_SB.PCI0.PEG0.PEGP.LVL1)
            }
            ElseIf (LLess (Arg0, 0x7F))
            {
                ShiftLeft (Local3, Subtract (Arg0, 0x40), Local0)
                ShiftLeft (One, Subtract (Arg0, 0x40), Local1)
                And (\_SB.PCI0.PEG0.PEGP.LVL2, Not (Local1), Local2)
                Or (Local2, Local0, \_SB.PCI0.PEG0.PEGP.LVL2)
            }

            Return (One)
        }

No. You should do the EC related things only when _REG is called with the arguments that indicate the EC is ready. It is covered in the guide.

Note: Maybe it is just the poor indentation you're using (you should verify).

Sorry for the indentation, I think it's correct now:
Code:
                    Method (_REG, 2, NotSerialized)  // _REG: Region Availability
                    {
                        If (LAnd (LEqual (Arg0, 0x03), LEqual (Arg1, One)))
                        {
                            Store (One, ECON)
                            If (LAnd (LEqual (ALSE, 0x02), IGDS))
                            {
                                Store (^ALSD._ALI (), ^^^GFX0.ALSI)
                            }

                            Store (0x03, ^^^GFX0.CLID)
                            Store (ACEX, PWRS)
                            If (LOr (LEqual (And (CPTY, 0x80), 0x80), LNotEqual (TIST, One)))
                            {
                                Store (TZCH (), RIST)
                                Store (RIST, PPCS)
                            }

                            PNOT ()
                        }
                       If (LEqual (\ECON, One))
                       {
                           Store (Zero, \_SB.PCI0.LPCB.H_EC.OPST)
                       }
                    }
 
Back
Top