Disabling the discrete GPU on a Thinkpad T490
I made the error of opting for a model with a discrete GPU, that I never use.
Unfortunately, it is impossible to disable by 'conventional' means: Lenovo did
not bother to add a BIOS switch, and the usual bbswitch
/ Optimus / VGA switcheroo are unable
to send the proper command to the device.
Someone described how to override the ACPI tables directly, but I put it off while trying to find a better way. It seems there is none. As I will never remember this stuff next time I need it, and because the procedure is slightly different, let's put it all in a memo.
Dump the raw ACPI tables
On Archlinux, the package 'acpica' must be installed to get the ACPI tools.
mkdir dsdt && cd dsdt
acpidump -b
mkdir raw && mv *.dat raw
mkdir dsl && mv *.dsl dsl
Find the GPU reference in the ACPI tables:
grep -rn GPU dsl
...
dsl/ssdt11.dsl:412: TGPU = \_SB.PCI0.LPCB.EC.HKEY.GPTL /* External reference */
dsl/ssdt11.dsl:413: Local0 [0x08] = TGPU /* \_SB_.PCI0.RP09.PEGP.TGPU */
\_SB_.PCI0.RP09.PEGP
is the reference we seek.
Next search where _ON_: Power On
is used in conjunction with the GPU reference.
Edit the table and give it a higher version
I found it in ssdt12.dsl
, where I apply the following diff:
diff --git a/dsl/ssdt12.dsl b/dsl/ssdt12.dsl
index 0902ac1..66b9bfe 100644
--- a/dsl/ssdt12.dsl
+++ b/dsl/ssdt12.dsl
@@ -18,7 +18,7 @@
* Compiler ID "INTL"
* Compiler Version 0x20160527 (538314023)
*/
-DefinitionBlock ("", "SSDT", 2, "LENOVO", "SgRpSsdt", 0x00001000)
+DefinitionBlock ("", "SSDT", 2, "LENOVO", "SgRpSsdt", 0x00001001)
{
External (_SB_.GGIV, MethodObj) // 1 Arguments
External (_SB_.GGOV, MethodObj) // 1 Arguments
@@ -343,7 +343,17 @@ DefinitionBlock ("", "SSDT", 2, "LENOVO", "SgRpSsdt", 0x00001000)
PCMR = 0x07
PWRS = Zero
Sleep (0x10)
- \_SB.PCI0.HGON ()
+
+ // Set this ACPI OSI flag to enable the dGPU.
+ If (\_OSI ("T490-Hybrid-Graphics"))
+ {
+ \_SB.PCI0.HGON ()
+ }
+ Else
+ {
+ \_SB.PCI0.HGOF ()
+ }
+
_STA = One
}
@@ -455,7 +465,15 @@ DefinitionBlock ("", "SSDT", 2, "LENOVO", "SgRpSsdt", 0x00001000)
Method (_ON, 0, Serialized) // _ON_: Power On
{
- \_SB.PCI0.HGON ()
+ // Set this ACPI OSI flag to enable the dGPU.
+ If (\_OSI ("T490-Hybrid-Graphics"))
+ {
+ \_SB.PCI0.HGON ()
+ }
+ Else
+ {
+ \_SB.PCI0.HGOF ()
+ }
Return (Zero)
}
Compile the new table:
iasl -tc dsl/ssdt12.dsl
Package and override during boot
mkdir -p img/kernel/firmware/acpi && cd img
cp ../dsl/ssdt12.aml kernel/firmware/acpi/
find kernel | cpio -H newc --create > acpi_override
cp acpi_override /boot
Then read acpi_override
during boot in grub using initrd.
I put it where Intel / AMD microcode is being loaded.
dmesg | grep -i "ssdt"
[ 0.018697] ACPI: SSDT ACPI table found in initrd [kernel/firmware/acpi/ssdt12.aml][0xe3c]
...
[ 0.018886] ACPI: Table Upgrade: override [SSDT-LENOVO-SgRpSsdt]