• Become a Premium Member for $25/year with no ads to improve your community experience.

GUIDE How to Disable Discrete Graphics in Dual GPU Laptops (NVIDIA/AMD) on macOS

EliteMacx86

Administrator
Staff member
Joined
Jul 22, 2018
Messages
7,247
Motherboard
Supermicro X11SPA-T
CPU
Intel Xeon W-3275 28 Core
Graphics
2xAMD RX 580 8GB
OS X/macOS
13.x
Bootloader
  1. OpenCore (UEFI)
Mac
  1. Mac mini
  2. MacBook Pro
Mobile Phone
  1. Android
  2. iOS
How to Disable Discrete Graphics in Dual GPU Laptops (NVIDIA/AMD) on macOS

An EliteMacx86 Exclusive Guide - This guide covers disabling Discrete Graphics in Dual GPU Laptops for NVIDIA and AMD on macOS. By following this guide, you'll be able to disable discrete graphics (NVIDIA/AMD) on your Dual GPU Laptops on macOS.

Overview


Many laptops have dual graphics such as AMD Radeon or NVIDIA Geforce which utilizes a switching mechanism to switch from the integrated graphics(Intel HD) to the discrete graphics as per the graphics demand. When using NVIDIA, this feature is referred to as Optimus Technology and AMD is referred to as AMD Switchable Graphics. When enabled, both IGPU and NVIDIA or AMD will be activated and will work under Optimus/Switching mode. However, this type of technology is not supported on Non-Apple computers when running macOS/OS X and should be disabled for a better cause to save power and generate less heat, improving the battery backup. However, a disadvantage can be that you cannot use such Laptops for graphics-hungry applications when running macOS. Users not having such needs can continue to disable the discrete graphics for a good cause and can have the advantage of more battery backup.

Disabling discrete Graphics is mandatory when having an Optimus or Switchable Graphics Technology as it can be difficult to install macOS and to save Battery life within OS X/macOS, which will generate less heat and noise. When Discrete Graphics isn't disabled, the GPU draws power even if it does not work on OS X/macOS. This can also cause sleep/wake failure. See Fixing Sleep for more information on Sleep/Wake.

For Disabling Unsupported IGPU

Available Methods for Disabling Discrete Graphics
Following are the methods available for unlocking the Discrete GPU. All these methods have been described below.

MethodsRemarks
BIOS Level
  • Easy to disable
  • Not supported by every Vendor
  • Cannot use the Discrete Graphics under other OS such as Windows or Linux
  • Discrete Graphics will not drain the battery.
  • Recommended if you don't have extensive Graphics requirements on other OS.
Kext Level
  • Easy to disable
  • Supported by every system
  • Discrete Graphics will drain the battery at a slower rate.
  • Not Recommended.
ACPI Level
  • Can be difficult to disable
  • Supported by every system
  • Can use the Discrete Graphics under other OS
  • Discrete Graphics will not drain battery.
  • Highly Recommended.

Disabling Discrete Graphics


This guide covers the disabling of discrete graphics in dual GPU laptops. The dual GPU laptops come in two variants:
  • Intel+NVIDIA (Optimus Technology)
  • Intel+AMD (Switching Technology)
Method #1: Disabling Discrete Graphics using BIOS Option
Using BIOS, you can disable the discrete GPU in Laptops. Disabling the discrete graphics in BIOS is not the best option as the device will be disabled in macOS as well as on Windows. To overcome this issue, you need ACPI patching which is a better option and the discrete GPU can be used in Windows or Linux. Most of the manufacturers do not give the option to disable the discrete Graphics under BIOS. However, a few manufacturers such as Clevo, Razer Blade, Lenovo, and Dell, do give the option to disable some of the selected models. If you disable it under BIOS, no need to patch the ACPI to disable the dGPU. However, if you keep the option enabled (to use it on other OS), you need to patch ACPI to disable the dGPU.

Method #2: Disabling Discrete Graphics using Kext
Using WhateverGreen, you can use a Boot Arg or a Device Property and can disable the discrete GPU in Laptops.

STEP 1: Add Required Kexts
The next step is to add the required kexts to disable discrete GPU. WhateverGreen doesn't work standalone. WhateverGreen and Lilu are needed together to work in conjunction in order to disable the discrete Graphics. This step shouldn't be required if you have followed the Installation Guide. However, if not, follow the steps below to add the kexts.

1. Download AppleALC and Lilu from the downloads section of this forum.
2. Mount your ESP.

For Clover:
If you're using Clover, copy both the kexts to EFI/Clover/Kext/Others directory.

For OpenCore:
If you're using OpenCore, copy both the kexts to EFI/OC/Kexts directory. You'll also need to add the kext entries in the Kernel section of your config.plist.

NOTES:
  • Download the latest version for better support.
  • Download only the RELEASE.zip file.
  • If the kext is already present in the directory, replace them with a new version
  • Do not use WhateverGreen.kext.dSYM and Lilu.kext.dSYM

STEP 2: Add Required WEG Properties
The next step is to add the WEG properties to the config.plist which will disable the discrete Graphics. Only use one of the methods, not both.

1. Mount your ESP.

Using Boot Arg
Depending on the bootloader you use, add the boot arg to your config.plist to disable the discrete GPU.

For Clover
1. Open config.plist from EFI/Clover directory
2. Go to the Boot section. Add -wegnoegpu under Boot Arguments.

For OpenCore
1. Open config.plist from EFI/OC directory.
2. Go to the NVRAM section. In the UUID 7C436110-AB2A-4BBB-A880-FE41995C9F82 add -wegnoegpu under boot-args.

Using Device Properties
Depending on the bootloader you use, add the following property to your config.plist to disable the discrete GPU

DevicesKeyValueType
PciRoot(0x0)/Pci(0x2,0x0)disable-external-gpu01000000DATA

2. Save config.plist

Method #3: Disabling Discrete Graphics using ACPI Patching

Using DSDT and SSDT method, you can disable the discrete GPU in Laptops and this is considered a more optimal and robust solution than method 1 described above.

A laptop from ASUS (X302LJ) has been used as an example for this guide which features Intel HD Graphics 5500 and NVIDIA Geforce 920M. The ACPI files have been extracted using the Clover F4 method. The native(untouched) files are under the origin folder and the patched ACPI files are under patched. The files have been provided in the attachment of this post.

Before you start with this guide, I recommend you to read about DSDT and SSDT patching on laptops. The guide covers the extraction of the ACPI files, disassembly, compiling, patching, saving, and installing. Read here:

To extract DSDT and SSDTs

For patching DSDT and SSDTs

STEP 1: Finding the required methods
To disable the DGPU, you'll need to find _OFF and _INI Method defined in your ACPI tables.

Finding _OFF Method
First, you'll need to find the SSDT with _OFF Method. To know this, we can use grep.
Open Terminal
Move to the working directory, where you dissembled the files.
Type:
Code:
grep -l Method.*_OFF *.dsl
Which results:
Code:
SSDT-10-SaSsdt .dsl
SSDT-11-SgPch.dsl
SSDT-12-OptTabl.dsl
Note down the SSDT with _OFF Method.

Finding _INI Method
Also, you need to find the DSDT and SSDT which contains the _INI Method
Type:
Code:
grep -l Method.*_INI *.dsl
Which results:
Code:
DSDT.dsl
SSDT-10-SaSsdt .dsl
SSDT-11-SgPch.dsl
SSDT-12-OptTabl.dsl
Note down the DSDT and SSDT with _INI Method.
Separate those DSDT and SSDT to any other directory.

NOTE:
  • The SSDT-10-SaSsdt.dsl, SSDT-11-SgPch.dsl and SSDT-12-OptTabl.dsl are listed again, this is where the _OFF and _INI are located.

But you need to confirm which exact SSDT has both the methods. To do so, follow the instructions below

Open the SSDT one by one and search for "Method (_INI". This is SSDT which needs to be patched.

When searching for the _INI method in "SSDT-10-SaSsdt.dsl", we find 4 _INI methods:
Code:
Method (_INI, 0, NotSerialized)  // _INI: Initialize
        {
            Store (LTRA, LTRS)
            Store (OBFA, OBFS)
        }

The second _INI
Code:
Method (_INI, 0, NotSerialized)  // _INI: Initialize
        {
            Store (LTRB, LTRS)
            Store (OBFB, OBFS)
        }
The third _INI
Code:
Method (_INI, 0, NotSerialized)  // _INI: Initialize
        {
            Store (LTRC, LTRS)
            Store (OBFC, OBFS)
        }
And the fourth _INI
Code:
Method (_INI, 0, NotSerialized)  // _INI: Initialize
        {
            If (LAnd (LNotEqual (And (ABAR, 0xFFFFC004), 0xFFFFC004), LNotEqual (And (ABAR, 0xFFFFC000), Zero)))
            {
                Store (ABAR, BARA)
                If (LNotEqual (ABAH, Zero))
                {
                    Or (BARA, ShiftLeft (ABAH, 0x20), BARA)
                }
            }
        }
In this case, none of the methods contains the address of the discrete graphics device. So we need to look for the other SSDT searching the same _INI method.

When searching for the _INI method in "SSDT-11-SgPch.dsl", we find one _INI method:
Code:
Method (_INI, 0, NotSerialized)  // _INI: Initialize
        {
            Store (Zero, \_SB.PCI0.RP05.PEGP._ADR)
        }
This is the SSDT we're looking for. This SSDT contains the address of the discrete graphics device.
If you look for the same method in "SSDT-12-OptTabl.dsl", we find one _INI method:
Code:
Method (_INI, 0, NotSerialized)  // _INI: Initialize
        {
            Store (DID1, Index (TLPK, Zero))
            Store (DID2, Index (TLPK, 0x02))
            Store (DID3, Index (TLPK, 0x04))
            Store (DID4, Index (TLPK, 0x06))
            Store (DID5, Index (TLPK, 0x08))
            Store (DID6, Index (TLPK, 0x0A))
            Store (DID7, Index (TLPK, 0x0C))
            Store (DID2, Index (TLPK, 0x0E))
            Store (DID1, Index (TLPK, 0x0F))
            Store (DID2, Index (TLPK, 0x11))
            Store (DID3, Index (TLPK, 0x12))
            Store (DID2, Index (TLPK, 0x14))
            Store (DID4, Index (TLPK, 0x15))
            Store (DID2, Index (TLPK, 0x17))
            Store (DID5, Index (TLPK, 0x18))
            Store (DID2, Index (TLPK, 0x1A))
            Store (DID6, Index (TLPK, 0x1B))
            Store (DID2, Index (TLPK, 0x1D))
            Store (DID7, Index (TLPK, 0x1E))
        }

But this is not the SSDT we're looking for as it doesn't have any _INI method with the discrete graphics device address.

NOTES:
  • The correct SSDT will have the address of the GPU. For e.g \_SB.PCI0.RP05.PEGP._ADR
  • Find the access location, ACPI path in the SSDT, and note down the EC. For e.g, \SB.PCI0.RP05.PEGP -> _INI
  • In case, if you haven't found the correct SSDT which contains _the INI method with the discrete graphics device address, search for another SSDT. The only left SSDT was "SSDT-12-OptTabl.dsl" which isn't what we're looking for. We find the method in the second SSDT so didn't need to look in the third SSDT. But to confirm, you must check it.

So we've got the _INI and need to look for the _OFF method. It's pretty clear that the path to _OFF should also have \SB.PCI0.RP05.PEGP-> _OFF

So, we know that the _OFF is located in either SSDT-10-SaSsdt.dsl, SSDT-11-SgPch.dsl or SSDT-12-OptTabl.dsl
When searching for the _OFF method in "SSDT-10-SaSsdt.dsl", we find 3 _OFF methods:
Code:
Method (_OFF, 0, Serialized)  // _OFF: Power Off
            {
                If (LNotEqual (OSYS, 0x07D9))
                {
                    PGOF (Zero)
                    Store (Zero, _STA)
                }
            }

The second _OFF
Code:
Method (_OFF, 0, Serialized)  // _OFF: Power Off
            {
                If (LNotEqual (OSYS, 0x07D9))
                {
                    PGOF (One)
                    Store (Zero, _STA)
                }
            }
The third _OFF
Code:
Method (_OFF, 0, Serialized)  // _OFF: Power Off
            {
                If (LNotEqual (OSYS, 0x07D9))
                {
                    PGOF (0x02)
                    Store (Zero, _STA)
                }
            }
In this case, none of the methods contains the address of the discrete graphics device. So we need to look for the other SSDT searching the same _OFF method.

When searching for the _INI method in "SSDT-11-SgPch.dsl", we find one _OFF method:
Code:
Method (_OFF, 0, Serialized)  // _OFF: Power Off
            {
                If (LNotEqual (OSYS, 0x07D9))
                {
                    \_SB.PCI0.RP05.PEGP.SGOF ()
                    Store (Zero, _STA)
                }
            }
This is the SSDT we're looking for. This SSDT contains the address of the discrete graphics device.
If you look for the same method in "SSDT-12-OptTabl.dsl", we find one _OFF method:
Code:
Method (_OFF, 0, Serialized)  // _OFF: Power Off
        {
            If (LEqual (CTXT, Zero))
            {
                If (LNotEqual (GPRF, One))
                {
                    Store (VGAR, VGAB)
                }

                Store (One, CTXT)
            }

            SGOF ()
        }

But this is not the SSDT we're looking for as it doesn't have any _OFF method with the discrete graphics device address.

NOTES:
  • The correct SSDT will have the address of the GPU. For e.g \_SB.PCI0.RP05.PEGP._SGOF
  • In case, if you haven't found the correct SSDT which contains the _OFF method with the discrete graphics device address, search for another SSDT. We find the method in the second SSDT. So that's the SSDT that we're looking for.

Now, we've got the SSDT which contains the _INI and the _OFF method. Now we need to look for the errors if any.
Compile the "SSDT-11-SgPch.dsl". Upon compiling, it has no errors. So we're good to go.
Now the patches can be applied.

STEP 2: Patching SSDT and DSDT
The next step is to patch the SSDT and DSDT to disable the DGPU.

Patches (SSDT)

[igpu] Rename GFX0 to IGPU
[gfx0] Disable from _INI (SSDT)

Patches (DSDT)

[igpu] Rename GFX0 to IGPU
[gfx0] Disable from _REG (DSDT)

Applying the Patches

For SSDT
:
Open the "SSDT-11-SgPch.dsl" using MaciASL.
Click on the Patch button
Find and select the patch from the left pane.
When applying the second patch, the patches will not get applied because of the incorrect address of the discrete graphics device. We need to replace the address of the graphics device. See notes below.
The default patch:
Code:
into method label _INI parent_label \_SB.PCI0.PEG0.PEGP insert
begin
//added to turn nvidia/radeon off\n
//External(\_SB.PCI0.PEG0.PEGP._OFF, MethodObj)\n
_OFF()\n
end;
which doesn't gets applied.
The modified patch (PEG0 changed to RP05):
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;
Click on Apply.
After applying the patch, the patched SSDT will read:
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()
        }
Click on Close.

NOTE:
  • If the patches don’t get applied, replace the address of your GPU instead of the default one in both the lines. For e.g. \SB.PCI0.RP05.PEGP. This is the same address that we noted down in the very first step when searching for the _INI method.

For DSDT :

For new Laptops


On several new Laptops, the patches will not be applied as there's no any _INI method. To fix this, follow the steps below.
1. Find the SSDT which has the _OFF method defined for the GPU.
2. Locate the GPU address in your SSDT, for e.g., \_SB.PCI0.PEG0.PEGP.
3. Find the _OFF method. It will be exact as "Method (_OFF, 0, Serialized) // _OFF: Power Off"
4. Above _OFF method in your SSDT, add "Method (_INI) {_OFF() } // added to call _OFF"
5. Apply the following patch
Code:
into method label _INI parent_label \_SB.PCI0.GFX0 insert
begin
//added to turn nvidia/radeon off\n
External(\_SB.PCI0.PEG0.PEGP._OFF, MethodObj)\n
\n
end;
6. Click on Apply.
7. Click on Close.

NOTES:
  • If the patches don’t get applied, replace the address of your GPU instead of the default one.
  • When compiling, if you get TGPC error, remove "External (_SB_.PCI0.PEG0.TGPC, IntObj) // (from opcode)" line from your SSDT.

For DSDT :
Open the DSDT using MaciASL.
Click on the Patch button
Find and select the patch from the left pane and click on Apply.
When using the second patch, the patches will get applied but we need to replace the address of the discrete graphics device. See notes below.
The default patch:
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;

The modified patch (PEG0 changed to RP05):
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.RP05.PEGP._OFF, MethodObj)\n
    \_SB.PCI0.RP05.PEGP._OFF()\n
}\n
end;
Click on Apply.

After applying the patch, the patched DSDT will read:
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)))
                {
                    External(\_SB.PCI0.RP05.PEGP._OFF, MethodObj)
                    \_SB.PCI0.RP05.PEGP._OFF()
                }
            }
        }
    }
Click on Close.

Note :
  • The patches will get applied but you’ll need to replace the address of your GPU instead of the default one in both the lines. For e.g \SB.PCI0.RP05.PEGP.

Compiling
After patching the DSDT and SSDTs, you need to compile the files.
Simply click on compile and look for errors. If there's an error, fix it and again click on Compile.
If there's no error, the files will be compiled successfully.

Note:
  • If you get [Unknown ASL Compiler exception ID] (TGPC [Integer]) error while compiling, remove "External (_SB_.PCI0.PEG0.TGPC, IntObj) // (from opcode)" line from your SSDT.

STEP 3: Saving the ACPI files

After compiling, the next step is to save the file for the installation.

1. Go to File
2. Select Save as
3. A dialogue box will appear asking for the location and the file extension to save the file.
4. Select ACPI(ACPI Machine Language)
5. Click on Save

Note:
  • It's a good idea to save the patched DSDT and SSDTs in any other location than the original.
And we're ready to place the files. At this point, all the patched files can be saved and placed in ACPI/patched.

Conclusion
DSDT.aml (includes _REG patch)
SSDT-11-SgPch.aml (includes _INI and _OFF patch)

STEP 4: Installing the DSDT and SSDT

The next step is to install the DSDT and SSDT. To install the DSDT and SSDT, follow the steps below.

1. Mount your ESP

For Clover:
If you're using Clover, copy all patched DSDT and SSDTs to EFI/Clover/ACPI/patched

For OpenCore:
If you're using OpenCore, copy patched DSDT and SSDTs to EFI/OC/ACPI. You'll also need to add the ACPI entries in ACPI>Add section of your config.plist

NOTE:
  • If your laptop has an NVIDIA discrete graphics device, use "nv_disable=1" as a boot args in config.plist file.


STEP 5: Restart your System


After performing all the above steps, restart your system for the applied changes to take effect.
The discrete graphics device should be disabled now.

Problem Reporting


Details:
  1. macOS version
  2. Copy of IOReg
  3. Kextcache output
Screenshots:
  • DPCIManager/Status
  • About This Mac
  • System Information/Graphics/Displays
Files:
  • For Clover, compress EFI/Clover, and exclude the themes folder.
  • For OpenCore, compress EFI/OC.
Notes:
  • Do not include the complete EFI folder.
  • Put all files in a folder with your name, compress files as Zip and attach files using site attachments only.
  • Do not use any external links.

Credits :
RehabMan

Sample Attachment

The ACPI files are attached below which have been used as an example in this guide:
 

Attachments

  • ASUS X302LJ_Sample ACPI Files .zip
    172.7 KB · Views: 542
Last edited:
I wanted to ask a question but am fine now! ;)
 
Last edited:
  • Like
Reactions: Chucksmmadu
My Laptop is:

Hp pavilion sleekbook 15 b001e

Intel Core i3-3217U CPU

NVIDIA GeForce GT 630M 1GB+intel hd graphics 4000

Disabling discrete NVIDIA

I want to modify dadt

dadt.png
 

Attachments

  • DSDT.zip
    29.9 KB · Views: 243
Hi,
both this command said no matches found !

grep -l Method.*_OFF *.dsl
grep -l Method.*_INI *.dsl

I open SSDT you mentioned in MaciASL and searched for _OFF and _INI But noting found !!!
here is my disassembled files
 

Attachments

  • origin.zip
    271.7 KB · Views: 237
simply add SSDT-DDGPU.aml to your patched acpi folder and it will disable it for you on the fly
 
simply add SSDT-DDGPU.aml to your patched acpi folder and it will disable it for you on the fly
That's a very quick method. If you need it without hassle, a quick way is to also use the bootflag. But you must disable it from ACPI for the power saving and performance.
 
That's a very quick method. If you need it without hassle, a quick way is to also use the bootflag. But you must disable it from ACPI for the power saving and performance.
So you mean using that ssdt alone, doesn't provide the power savings and performance boost?
 
Hi,
both this command said no matches found !

grep -l Method.*_OFF *.dsl
grep -l Method.*_INI *.dsl

I open SSDT you mentioned in MaciASL and searched for _OFF and _INI But noting found !!!
here is my disassembled files
Probably, you did NOT followed the guide. First you need to disassemble and then find it in Terminal.

For your ACPI set, you'll find the exact information if you follow the guide.

Code:
$ grep -l Method.*_OFF *.dsl

DSDT.dsl

SSDT-11-OptTabl.dsl

SSDT-4-CflH_Rvp.dsl

SSDT-5-Ther_Rvp.dsl


$ grep -l Method.*_INI *.dsl

DSDT.dsl

SSDT-11-OptTabl.dsl

SSDT-3-PegSsdt.dsl

You need to use DSDT.dsl and SSDT-11-OptTabl.dsl to disable the dGPU.
 
  • Like
Reactions: promisedSavior

Forum statistics

Threads
1,637
Messages
15,376
Members
23,452
Latest member
timothee