Contribute
Register

[Guide] Disabling discrete graphics in dual-GPU laptops

Hello RehabMan ASUS notebook off the case of independent graphics card, https://www.tonymacx86.com/threads/...ete-graphics-in-dual-gpu-laptops.163772/#ACPI
Is the need to extract all the SSDT files and fix it, Clover configuration DropOem = ture! But your latest technology update and recommended to forget DropOem = turehttps://www.tonymacx86.com/threads/...tops-with-clover.148093/page-325#post-1501951
Xmlenx
Encountered this special case how to shield the discrete graphics.
The
In DSDT / FIX / EC0 to EC__ for \ _SB.PCI0.LPCB.EC0.SPIN (0x96, Zero) seems to have an impact, re-enter the system after the extraction code will be missing! Because I can not enter the system, can only upload the document is not sure, but also look at that is the DSDT. The
 

Attachments

  • patched.zip
    50.8 KB · Views: 64
  • Turn off the video card.zip
    4.4 MB · Views: 69
  • origin.zip
    50.1 KB · Views: 62
Overview

The purpose of this guide is to show you how to disable the discrete graphics device with DSDT/SSDT edits in "switched" dual-GPU laptops (eg. Intel+Nvidia[Optimus] and Intel+Radeon).

Because only the Intel device can be used in these laptops, the discrete device is generally left active and using power, contributing to heat, noise, and battery usage. Although the device can usually be disabled in BIOS, it is better to disable it with a custom ACPI setup so the device can still be used when booting Windows.

Although it is a relatively simple patch (sometimes only a one line change), because of the fact that the patch is done to one or more SSDTs, there are many pitfalls to fall into. Also, certain machine/ACPI configurations require different approaches, leading to more complexity. The example DSDT/SSDT set that this guide uses is one of the more complex setups, so it covers most of the issues you might run into with your own.

You should follow this walkthrough with the example before patching your own.

The laptop being used for this guide/example is an "Asus UX303LN" with Intel HD4400 + Nvidia. The Clover F4 extracted tables (ACPI/origin directory) are provided in an attachment to this post.


Patching requirements

The goal is quite simple. These machines provide an _OFF method, usually in an SSDT, that can be called to power down the discrete device. The easiest fix is to call _OFF from the corresponding _INI method. Note that the _OFF method may be in DSDT or may have a different name (GPOF, OPOF, _PS3, etc.)

Certain implementations of _OFF cannot be called from _INI as they access the EC (Embedded Controller) space. For these machines, _OFF (or a portion of it) must be delayed until _REG (when Arg0==3 and Arg1==1, see ACPI spec for more information regarding _REG). In some cases, calling from _REG is too late and it is either not effective or leads to a crash. In such a case, editing _OFF to remove EC dependencies is necessary, so it can be called from _INI. The code that was removed from _OFF is then inserted into _REG so the effect is the same although the EC work is done later. This is the case with the example ACPI setup in this guide.


Basic patching

It is important to understand how to extract, disassemble and patch your DSDT/SSDT files, and how to install them for your bootloader, etc. This subject is covered in my guide: http://www.tonymacx86.com/yosemite-laptop-support/152573-guide-patching-laptop-dsdt-ssdts.html. You should be familiar with it before attempting this guide.

Because patching for the basics is important, we'll do that first here before getting started on the patching required for disabling the Nvidia card in the example.

First the files are extracted (you can simply download the example files), then disassembled with iasl:
Code:
iasl -da -dl *.aml

After disassembly we can proceed to patch the various files. In this example, we'll patch almost all the files.

For DSDT.dsl:
"Fix PARSEOP_ZERO Error" (be sure to uncommment the "more agressive" patches)
"Fix ADBG Error"
"Rename _DSM methods to XDSM"
"IRQ Fix"
"SMBUS Fix"
"OS Check Fix (Windows 8)"
"Add IMEI"
"RTC Fix"
"Fix _WAK Arg0 v2"
"Fix _WAK IAOE" (new patch)
"Rename GFX0 to IGPU"
"Rename B0D3 to HDAU" (new patch)
"ASUS N55SL/VivoBook"
"USB3 _PRW(0x6D) and Rename XHC to XHC1" (new patch)
"Audio Layout 12"

For SSDT-0.dsl:
"Remove _PSS placeholders" (new patch)

SSDT-2x, SSDT-3x, SSDT-4x are not included as they are dynamically loaded.
SSDT-1, SSDT-5, SSDT-6, SSDT-8 require no patches.

For SSDT-7.dsl:
"Rename GFX0 to IGPU"

For SSDT-9.dsl
"Rename GFX0 to IGPU"
"Brightness Fix (Haswell)"
"Rename B0D3 to HDAU" (new patch)

SSDT-10.dsl:
"Rename GFX0 to IGPU"

SSDT-11.dsl
"Rename _DSM methods to XDSM"
"Rename GFX0 to IGPU"
"Cleanup/Fix Errors (SSDT)"

SSDT-12.dsl:
"Rename GFX0 to IGPU"

At that point, all files should compile without error.

You can test with iasl:
Code:
iasl *.dsl

Note: You may want to insure your native AML files are safely tucked away somewhere before compiling the patched *.dsl, as iasl will overwrite any existing *.aml with the compilation result.

Some notes on the choices above:
- B0D3 (even if named differently) can be found with 'grep -B3 _ADR.*0x00030000 *.dsl'
- GFX0 (even if named differently) can be found with 'grep -B3 _ADR.*0x00020000 *.dsl'
- "Rename GFX0 to IGPU" is applied to any file with GFX0 references. This is "balancing renames". You can find all such files with 'grep -l GFX0 *.dsl'
- same goes for "Rename B0D3 to HDAU". Find all files with 'grep -l B0D3 *.dsl'
- "Remove _DSM methods" (or "Rename _DSM methods to XDSM") is applied early and to any file with _DSM methods (you can find them with 'grep -l Method.*_DSM *.dsl'
- instead of dropping CPU related SSDTs, here we are keeping them (patching if necessary). It avoids having to use the "Fix PNOT/PPNT" patch with DSDT.
- the battery patch is specific to the target machine, in this case an Asus laptop


Patching for discrete disable

Remember the goal? Call _OFF from _INI... At this point we have a set of DSDT/SSDT that compile without errors, have balanced renames and have no duplicate _DSM methods.

Now... how to find the SSDT that has _OFF. We can use grep:
Code:
grep -l Method.*_OFF *.dsl

Which shows:
Code:
SSDT-10.dsl
SSDT-11.dsl

Also, it is nice to know where the _INI methods are:
Code:
grep -l Method.*_INI *.dsl

Which shows:
Code:
DSDT.dsl
SSDT-10.dsl
SSDT-11.dsl
SSDT-9.dsl

Note: SSDT-10 and SSDT-11 are listed again. This is likely where the _OFF and associated _INI are located...

We could also open each file individually into MaciASL and search for _OFF and _INI, but using grep is a bit easier and faster.

When we open SSDT-10.dsl and look for "Method (_INI", we find this:
Code:
        Method (_INI, 0, NotSerialized)  // _INI: Initialize
        {
            Store (Zero, \_SB.PCI0.RP05.PEGP._ADR)
        }

This is a typical _INI method for a discrete device, and one that we want to patch so it calls _OFF.

If we click in the method body, we can see the ACPI "path" that this method lives in. MaciASL shows it on the status bar: SSDT -> \_SB.PCI0.RP05.PEGP -> _INI. Now we know that the path to _OFF should also be \_SB.PCI0.RP05.PEGP._OFF.

So, we know that _OFF is either in SSDT-10.dsl or SSDT-11.dsl. If you open SSDT-10.dsl and look for _OFF, you find it is a method inside a PowerResource macro. This is not the _OFF method we want. Open SSDT-11.dsl and look there and you'll find a regular _OFF method, which is what we are looking for. So now we know where _OFF is. We need to know, as it is necessary to review the code for potential EC access.

In SSDT-11.dsl, _OFF is defined as follows:
Code:
        Method (_OFF, 0, Serialized)  // _OFF: Power Off
        {
            If (LEqual (CTXT, Zero))
            {
                \_SB.PCI0.LPCB.EC0.SPIN (0x96, Zero)
                If (LNotEqual (GPRF, One))
                {
                    Store (VGAR, VGAB)
                }

                Store (One, CTXT)
            }

            SGOF ()
        }

If you examine the code, you can see it accesses the EC (\_SB.PCI0.LPCB.EC0.SPIN (0x96, Zero). This is going to be a problem and will prevent _OFF from executing fully when called from _INI. Keep in mind it is not always this obvious. The code could have called a method not directly related to the EC, which in turn calls a method in the EC (indirect access). So you may need to do some digging. This example was obvious as the method path includes EC0.

The best way to deal with the EC access is to remove the offending code from _OFF.

We can do it manually, or use a patch like this:
Code:
into method label _OFF parent_label \_SB.PCI0.RP05.PEGP code_regex .*EC.* removeall_matched;

The modified _OFF method is this:
Code:
        Method (_OFF, 0, Serialized)  // _OFF: Power Off
        {
            If (LEqual (CTXT, Zero))
            {
                If (LNotEqual (GPRF, One))
                {
                    Store (VGAR, VGAB)
                }

                Store (One, CTXT)
            }

            SGOF ()
        }

We should still have the line that we removed, \_SB.PCI0.LPCB.EC0.SPIN (0x96, Zero), executed in _REG, so keep that in mind.

Now that we have fixed _OFF, let's call it from _INI, defined in SSDT-10.dsl.

We can apply patch "Disable from _INI (SSDT)". But our method's path is slightly different from what is common, so we need to modify the patch. Also, we are calling to _OFF which is defined in SSDT-11.dsl, so we need the External declaration.

The modified patch follows:
Code:
into method label _INI parent_label \_SB.PCI0.RP05.PEGP insert
begin
//added to turn nvidia/radeon off\n
External(\_SB.PCI0.RP05.PEGP._OFF, MethodObj)\n
_OFF()\n
end;

After applying this patch, the patched _INI now reads:
Code:
        Method (_INI, 0, NotSerialized)  // _INI: Initialize
        {
            Store (Zero, \_SB.PCI0.RP05.PEGP._ADR)
            //added to turn nvidia/radeon off
            External(\_SB.PCI0.RP05.PEGP._OFF, MethodObj)
            _OFF()
        }

Now we need to turn our attention to DSDT _REG. The _REG method needs to do the EC work that _OFF used to do before we patched it.

Here is the original _REG (for EC0) in DSDT:
Code:
            Method (_REG, 2, NotSerialized)  // _REG: Region Availability
            {
                If (LEqual (Arg0, 0x03))
                {
                    Store (Arg1, ECFL)
                }
            }

There is a patch in my repo to call _OFF from _REG. We can use it as a base for what we need:
Code:
into method label _REG parent_hid PNP0C09 insert
begin
//added to turn nvidia/radeon off\n
If (LAnd(LEqual(Arg0,3),LEqual(Arg1,1)))\n
{\n
    External(\_SB.PCI0.PEG0.PEGP._OFF, MethodObj)\n
    \_SB.PCI0.PEG0.PEGP._OFF()\n
}\n
end;

Instead of calling _OFF, we want it to call SPIN as the original _OFF did.

The modified patch is:
Code:
into method label _REG parent_hid PNP0C09 insert
begin
//added to turn nvidia/radeon off\n
If (LAnd(LEqual(Arg0,3),LEqual(Arg1,1)))\n
{\n
    \_SB.PCI0.LPCB.EC0.SPIN (0x96, Zero)\n
}\n
end;

The modified _REG after patching:
Code:
            Method (_REG, 2, NotSerialized)  // _REG: Region Availability
            {
                If (LEqual (Arg0, 0x03))
                {
                    Store (Arg1, ECFL)
                }
                //added to turn nvidia/radeon off
                If (LAnd(LEqual(Arg0,3),LEqual(Arg1,1)))
                {
                    \_SB.PCI0.LPCB.EC0.SPIN (0x96, Zero)
                }
            }

And that concludes patching. At this point all files can be compiled in batch and placed where the bootloader can load them.

Note that this example is complex and not all laptops will have the same configuration. For most, the _INI and _OFF associated with the discrete device are in the same SSDT. In that case it is not necessary to use the External declaration. You can use the "Call _OFF from _INI (SSDT)" patch directly. Some even have it in DSDT (again you can use the patch directly). And not all _OFF methods access the EC, so the movement of the EC related code to _REG is not needed.

It is also possible that the EC related code is more than one line. All such code should be moved to _REG.

Please note that all files must be installed correctly so that the bootloader will load them in the correct order. This is covered in the main DSDT/SSDT patching guide. Also, as is covered in the guide, you must drop OEM SSDTs in order to provide patched ones (Chameleon: DropSSDT=Yes, Clover: DropOem=true)


Sleep/Wake Problems

Some laptops have issues with sleep/wake or even shutdown/restart with this patch in place. This was the case with the HP ProBook (with Radeon). The fix is to re-enable the card before sleeping and disable it on wake.

There is a patch in the repository to accomplish this. It is called "Disable/Enable on _WAK/_PTS (DSDT)".

But since this DSDT has _OFF/_ON at a different path than the patch expects, we need to modify it.

Original patch:
Code:
into method label _PTS code_regex ([\s\S]*) replace_matched
begin
External(\\_SB.PCI0.PEG0.PEGP._ON, MethodObj)\n
If (CondRefOf(\\_SB.PCI0.PEG0.PEGP._ON)) { \\_SB.PCI0.PEG0.PEGP._ON() }\n
%1
end;

into method label _WAK code_regex (Return\s+\(.*) replace_matched
begin
External(\\_SB.PCI0.PEG0.PEGP._OFF, MethodObj)\n
If (CondRefOf(\\_SB.PCI0.PEG0.PEGP._OFF)) { \\_SB.PCI0.PEG0.PEGP._OFF() }\n
%1
end;

Modified patch (PEG0 changed to RP05):
Code:
into method label _PTS code_regex ([\s\S]*) replace_matched
begin
External(\\_SB.PCI0.RP05.PEGP._ON, MethodObj)\n
If (CondRefOf(\\_SB.PCI0.RP05.PEGP._ON)) { \\_SB.PCI0.RP05.PEGP._ON() }\n
%1
end;

into method label _WAK code_regex (Return\s+\(.*) replace_matched
begin
External(\\_SB.PCI0.RP05.PEGP._OFF, MethodObj)\n
If (CondRefOf(\\_SB.PCI0.RP05.PEGP._OFF)) { \\_SB.PCI0.RP05.PEGP._OFF() }\n
%1
end;

If your laptop doesn't have problems with sleep/wake/restart/shutdown with the discrete device disabled, then you do not need this patch. You need to test your laptop first to determine if it is needed.

Older laptops

You will notice that older laptops may not have _OFF, or may have an empty _OFF. In such cases, you may notice that _PS3 is required. In some cases, _PS3 will not work unless the invoke the associated _DSM with appropriate params. Details are in post #96 of this thread: http://www.tonymacx86.com/yosemite-...graphics-dual-gpu-laptops-10.html#post1056748


Problem Reporting

If you have problems with your DSDT/SSDTs in patching or fixing errors, please provide all the native files that you're working with.

If you attempt to disable your discrete card according to this guide and it is not working, please provide the following troubleshooting data...

Download patchmatic: https://bitbucket.org/RehabMan/os-x-maciasl-patchmatic/downloads/RehabMan-patchmatic-2015-0107.zip
Extract the 'patchmatic' binary from the ZIP. Copy it to /usr/bin, such that you have the binary at /usr/bin/patchmatic.

In terminal,
Code:
rm -R ~/Downloads/RehabMan
mkdir ~/Downloads/RehabMan
cd ~/Downloads/RehabMan
patchmatic -extract

Post contents of Downloads/RehabMan directory (as ZIP).

Also, post ioreg: http://www.tonymacx86.com/audio/58368-guide-how-make-copy-ioreg.html. Please, use the IORegistryExplorer v2.1 attached to the post! DO NOT reply with an ioreg from any other version of IORegistryExplorer.app.

And output from:
Code:
kextstat|grep -y acpiplat
kextstat|grep -y appleintelcpu

If you're using Clover, post EFI/Clover folder as ZIP (make sure you press F4 at the main Clover screen prior to capturing EFI/Clover). If you're using Chameleon/Chimera, post /Extra folder. Please eliminate themes for a smaller upload/download package.

All data should be provided in ZIP format.


Sample Attachment

The following files are used as the example ACPI set in this guide:


hello rehabman, i was follow your guide to disable nvidia but no luck , my nvidia didnt disable at all,, i follow your guide using two method :
first - in clover i check drop all ssdt, i get stuck on prohibited sign,
second - uncheck drop all ssdt and i can go to desktop but nvidia didnt disable,
Asus a456ur - 10.12.6
intel 6200u
intel hd 520 and nvidia 930mx
here's my clover folder, extracted patchmatic and ioreg copy, hope you can help me ,
 

Attachments

  • Archive.zip
    8.3 MB · Views: 138
Hello RehabMan ASUS notebook off the case of independent graphics card, https://www.tonymacx86.com/threads/...ete-graphics-in-dual-gpu-laptops.163772/#ACPI
Is the need to extract all the SSDT files and fix it, Clover configuration DropOem = ture! But your latest technology update and recommended to forget DropOem = turehttps://www.tonymacx86.com/threads/...tops-with-clover.148093/page-325#post-1501951
Xmlenx
Encountered this special case how to shield the discrete graphics.
The
In DSDT / FIX / EC0 to EC__ for \ _SB.PCI0.LPCB.EC0.SPIN (0x96, Zero) seems to have an impact, re-enter the system after the extraction code will be missing! Because I can not enter the system, can only upload the document is not sure, but also look at that is the DSDT. The

Please try to describe your issue clearly.
And read post #1, "Problem Reporting" again. Carefully (you forgot to press F4, no ioreg, no kextcache output, no patchmatic -extract etc).
 
hello rehabman, i was follow your guide to disable nvidia but no luck , my nvidia didnt disable at all,, i follow your guide using two method :
first - in clover i check drop all ssdt, i get stuck on prohibited sign,
second - uncheck drop all ssdt and i can go to desktop but nvidia didnt disable,
Asus a456ur - 10.12.6
intel 6200u
intel hd 520 and nvidia 930mx
here's my clover folder, extracted patchmatic and ioreg copy, hope you can help me ,

Your ACPI configuration is wrong. SortedOrder must be used to set SSDT load order.
 
I am using CLOVER。What does this tip mean? Is there a solution?
 

Attachments

  • CLOVER.zip
    615.1 KB · Views: 86
  • 1987511153.jpg
    1987511153.jpg
    237.1 KB · Views: 82
I am using CLOVER。What does this tip mean? Is there a solution?

I don't understand your question.
And you forgot to press F4 before collecting EFI/Clover.
If you have an issue, provide details and "Problem Reporting" files as per post #1.
 
Your ACPI configuration is wrong. SortedOrder must be used to set SSDT load order.
so i need yo sorted order to SSDT and drop oem SSDT in ACPI config ? but if i drop oem i got prohibited sign when i boot to osx, and i have ssdt pnlf and ssdt power management using ssdtPRGen do i need remove them if i use ssdt0-13 ? i first test i remove them to see if nvidia disable or not,
my file for problem reporting is in attached files,
 
so i need yo sorted order to SSDT and drop oem SSDT in ACPI config ? but if i drop oem i got prohibited sign when i boot to osx, and i have ssdt pnlf and ssdt power management using ssdtPRGen do i need remove them if i use ssdt0-13 ? i first test i remove them to see if nvidia disable or not,
my file for problem reporting is in attached files,

SortedOrder is required to set order of the SSDTs.
DropOem=true is required to drop OEM SSDTs to make way for patched SSDTs in ACPI/patched.
 
[QUOTE = "RehabMan, post: 1561552, member: 429483"] SortedOrder order to set the SSDT.
DropOem = true need to remove the OEM SSDT, in order to repair SSDT in ACPI / patch. [/ QUOTE]
After selecting EC0 to EC can not be closed NAVIDA! USB3.0 and 2.0 point do not know the location, wake up no sound output!
MacBook Air: 提取 facai8 $ kextstat | grep -y acpiplat

13 2 0xffffff7f82be1000 0x66000 0x66000 com.apple.driver.AppleACPIPlatform(5.0)65E05472-6AE7-3308-8CC8-FA6CB0DB2AEE <12 11 7 6 5 4 3 1>

MacBook Air: 提取 facai8 $ kextstat | grep -y appleintelcpu

MacBook Air: 提取 facai8 $ kextstat | grep -y applehda

97 1 0xffffff7f82896000 0x1d000 0x1d000 com.apple.driver.AppleHDAController(279.48)ED51F180-19C8-3DE1-AF81-0E389D98ADDE <96 95 79 12 7 6 5 4 3 1>

127 0 0xffffff7f82a18000 0xb5000 0xb5000 com.apple.driver.AppleHDA(279.48)806B8C17-50CA-3C6B-90B3-195F38D8FB89 <126 101 97 96 95 79 6 5 4 3 1>

MacBook Air: 提取 facai8 $ kextstat | grep -y acpiplat

13 2 0xffffff7f82be1000 0x66000 0x66000 com.apple.driver.AppleACPIPlatform(5.0)65E05472-6AE7-3308-8CC8-FA6CB0DB2AEE <12 11 7 6 5 4 3 1>
 

Attachments

  • EC_MacBook Air.ioreg
    7.1 MB · Views: 79
  • NO_EC0_TO_EC_OFF_Navida.zip
    52.4 KB · Views: 80
  • EC0_TO_EC_no_OFF_NAVIDA.zip
    52.4 KB · Views: 84
  • CLOVER.zip
    1.3 MB · Views: 74
  • JASON的MacBook Air.ioreg
    4.5 MB · Views: 146
Last edited:
[QUOTE = "RehabMan, post: 1561552, member: 429483"] SortedOrder order to set the SSDT.
DropOem = true need to remove the OEM SSDT, in order to repair SSDT in ACPI / patch. [/ QUOTE]
After selecting EC0 to EC can not be closed NAVIDA! USB3.0 and 2.0 point do not know the location, wake up no sound output!
MacBook Air: 提取 facai8 $ kextstat | grep -y acpiplat

13 2 0xffffff7f82be1000 0x66000 0x66000 com.apple.driver.AppleACPIPlatform(5.0)65E05472-6AE7-3308-8CC8-FA6CB0DB2AEE <12 11 7 6 5 4 3 1>

MacBook Air: 提取 facai8 $ kextstat | grep -y appleintelcpu

MacBook Air: 提取 facai8 $ kextstat | grep -y applehda

97 1 0xffffff7f82896000 0x1d000 0x1d000 com.apple.driver.AppleHDAController(279.48)ED51F180-19C8-3DE1-AF81-0E389D98ADDE <96 95 79 12 7 6 5 4 3 1>

127 0 0xffffff7f82a18000 0xb5000 0xb5000 com.apple.driver.AppleHDA(279.48)806B8C17-50CA-3C6B-90B3-195F38D8FB89 <126 101 97 96 95 79 6 5 4 3 1>

MacBook Air: 提取 facai8 $ kextstat | grep -y acpiplat

13 2 0xffffff7f82be1000 0x66000 0x66000 com.apple.driver.AppleACPIPlatform(5.0)65E05472-6AE7-3308-8CC8-FA6CB0DB2AEE <12 11 7 6 5 4 3 1>

Same question asked/answered here:
https://www.tonymacx86.com/threads/...g-battery-status.116102/page-406#post-1561148
 
Back
Top