- Joined
- Jul 21, 2011
- Messages
- 379
- Motherboard
- Zbook G5 17"
- CPU
- i7
- Graphics
- AMD WX-4170
- Mac
This thread is to detail my research and findings to try to perfect mux control and hopefully help anyone with a Muxed laptop get control of their display outputs. (SSDT at the moment and hopefully to make a driver in the future)
Ok so a little background.
Zbook's are HP's top of the line laptops and some 15" and all 17" models have MXM cards as a secondary GPU (DGPU)
For baseline I'm using a G5 (Generation 5) version that has an Intel Coffeelake CPU with UHD630 IGPU and a separate WX-4170 MXM DGPU.
The laptop has 3 operating modes as far as graphics are concerned.
- UMA (IGPU only for all displays and DGPU is OFF)
- Hybrid (IGPU for LCD and MXM for External Displays)
- Discrete (MXM for all displays and IGPU is OFF)
Now the problem is that these configurations are not perfect for our Hackintoshes because if you want to harness all the DGPU power for games/3D/Video work using a compatible MXM DGPU, you need to use Discrete mode and you not only loose Intel Quicksync as well as Jpeg quicklook, etc...but also OSX support only goes as far as Mojave since the MXM ROM is cooked in the BIOS and it is not Apple compatible because of a faulty memory training module. (And you also need to use an imac SMBIOS to solve some of these, but then you get another set of different issues)
If you want to save battery and use IGPU only, then the problem is that if the MXM card slot is populated, then the external outputs default to the MXM card and we only get the LCD display. So no external monitors if there's a DGPU even if it's turned off in BIOS.
And finally the Hybrid config only gets full MXM power for external displays, and you get no DRM on internal LCD. This only works if you have a compatible DGPU.
A real MacbookPro can switch DGPU and IGPU at runtime depending on load, and while achieving this would be nice, I wanted to be able to at least get full power from my MXM DGPU whenever I needed it, and power savings (without sacrificing external monitors) when not.
The catch is that the only way to make this happen is by controlling the MUX chips on the laptop (glorified source selector switches) for the different video outputs. This of course is not documented by HP anywhere, and it is normally done by the GPU driver through I2C control methods which are not present in OSX as this hardware configuration doesn't exist in normal Apple machines. (Hybrid Graphics)
Needless to say, it took me a while to better understand the cryptic SSDT's/DSDT that HP uses for these laptops, but after some analyzing, a lot of searching and reading (and a lot of luck), I stumbled on a method used by G7 laptops that control the Mux at ACPI level.
Now since this issue perfectly described a Mux switch problem and pointed at a solution, I searched for HGME in my SSDT's and came out empty, so with the help of a kind G7 user who sent me his SSDT's and after comparing them against my G5, I matched HGME to my method HGMD from the AMDSGTBL (AMD Secondary Graphics Table) SSDT.
So now I know the name of the Mux control method in HP Zbook G5, now let's dig in.
In HGMD there's an IF statement that caught my eye.
"IF ((\GTOS () == 0x09))" and by following \GTOS down the rabbit hole into the DSDT you get \GOSI, and before that \_OSI which is defined by ACPI by the OS currently loaded. Basically the Bios enables or disables features based on what OS you're using. So going back to the the AMDSGTBL SSDT, this method checks which OS version you have and enables or disables features based on it, and in this case, if the OS is older than a particular one, then it executes the method HGGW (One, SDTE, SDTG, SDTA, One).
(If you follow the entire IF chain, you will find method HGGR, which looks very similar to HGGW but uses method GGOV instead to "GET" value, while 'S'GOV "SET" value, and if set to One, then runs HGGW)
I went to Windows and using AIDA64 I ran the different methods on it's ACPI browser and Boom! the external mux got switched. So basically the laptop doesn't give the Hybrid option if your OS is below a certain feature level. So after eliminating the other things that HGGW performs, I narrowed the command down to \_SB.SGOV and 2 values.
The first (Arg2) is sent by HGMD and is SDTG.
So after finding this and testing it I went back to the DSDT and looked for SDTG.
With AIDA64 I queried SDTG for it's value as well as SDTA and SDTE, and I saw that the DSDT also had other variables with similar A.E.G ending, and similar values.
SDPE = 00000000
SDPG = 50593802 ( 0x0304000A )
SDPA = 00000000
SDTE = 00000000
SDTG = 50659332 ( 0x03050004 ) - External Mux
SDTA = 00000000
GETE = 00000000
GETG = 50659336 ( 0x03050008 )
GETA = 00000000
SUOT = 00000000
SUOG = 50659328 ( 0x03050000 ) LCD Power On/OFF ?
SUOA = 00000000
So I realized that the "G" ending in those variables was a device address of some sort.
So I executed \_SB.SGOV and those variables, and with some nothing happened, but on SUOG + 0x01 my LCD powered OFF so I thought it was LCD power control, but on a chat with @EdwardGeo I tested it again and realized it was in fact the LCD Mux, but because the windows AMD driver didn't expect to have a display attached to the LCD output, it was black/OFF. but when I used this on my SSDT on OSX, then everything changed.
And it kind of makes sense, LCD = SUOG = ( 0x03050000 ) | EXT = SDTG = ( 0x03050004 ) the adresses are next to each other.
So this is when things got interesting. I was able to switch the external mux to be run by IGPU in Hybrid mode as well as run the LCD by the DGPU and keep the IGPU in a connector-less framebuffer to make use of quicksync, etc... And have the DRM provided by the AMD card on the internal screen.
I thought this was it as far as solving the problem and I tweaked my SSDT to make it easier to edit and to make sure the Mux setting remained set on wake, and this is when I found the remaining glitch.
Ok so a little background.
Zbook's are HP's top of the line laptops and some 15" and all 17" models have MXM cards as a secondary GPU (DGPU)
For baseline I'm using a G5 (Generation 5) version that has an Intel Coffeelake CPU with UHD630 IGPU and a separate WX-4170 MXM DGPU.
The laptop has 3 operating modes as far as graphics are concerned.
- UMA (IGPU only for all displays and DGPU is OFF)
- Hybrid (IGPU for LCD and MXM for External Displays)
- Discrete (MXM for all displays and IGPU is OFF)
Now the problem is that these configurations are not perfect for our Hackintoshes because if you want to harness all the DGPU power for games/3D/Video work using a compatible MXM DGPU, you need to use Discrete mode and you not only loose Intel Quicksync as well as Jpeg quicklook, etc...but also OSX support only goes as far as Mojave since the MXM ROM is cooked in the BIOS and it is not Apple compatible because of a faulty memory training module. (And you also need to use an imac SMBIOS to solve some of these, but then you get another set of different issues)
If you want to save battery and use IGPU only, then the problem is that if the MXM card slot is populated, then the external outputs default to the MXM card and we only get the LCD display. So no external monitors if there's a DGPU even if it's turned off in BIOS.
And finally the Hybrid config only gets full MXM power for external displays, and you get no DRM on internal LCD. This only works if you have a compatible DGPU.
A real MacbookPro can switch DGPU and IGPU at runtime depending on load, and while achieving this would be nice, I wanted to be able to at least get full power from my MXM DGPU whenever I needed it, and power savings (without sacrificing external monitors) when not.
The catch is that the only way to make this happen is by controlling the MUX chips on the laptop (glorified source selector switches) for the different video outputs. This of course is not documented by HP anywhere, and it is normally done by the GPU driver through I2C control methods which are not present in OSX as this hardware configuration doesn't exist in normal Apple machines. (Hybrid Graphics)
Needless to say, it took me a while to better understand the cryptic SSDT's/DSDT that HP uses for these laptops, but after some analyzing, a lot of searching and reading (and a lot of luck), I stumbled on a method used by G7 laptops that control the Mux at ACPI level.
Implement _DSM with UUID "3e5b41c6-eb1d-4260-9d15-c71fbadae414" (#3113) · Issues · drm / intel · GitLab
On HP Fury G7 Workstations, graphics output is re-routed from Intel GFX to discrete GFX after S3: Before S3, HDMI plugged:
gitlab.freedesktop.org
Now since this issue perfectly described a Mux switch problem and pointed at a solution, I searched for HGME in my SSDT's and came out empty, so with the help of a kind G7 user who sent me his SSDT's and after comparing them against my G5, I matched HGME to my method HGMD from the AMDSGTBL (AMD Secondary Graphics Table) SSDT.
So now I know the name of the Mux control method in HP Zbook G5, now let's dig in.
In HGMD there's an IF statement that caught my eye.
"IF ((\GTOS () == 0x09))" and by following \GTOS down the rabbit hole into the DSDT you get \GOSI, and before that \_OSI which is defined by ACPI by the OS currently loaded. Basically the Bios enables or disables features based on what OS you're using. So going back to the the AMDSGTBL SSDT, this method checks which OS version you have and enables or disables features based on it, and in this case, if the OS is older than a particular one, then it executes the method HGGW (One, SDTE, SDTG, SDTA, One).
(If you follow the entire IF chain, you will find method HGGR, which looks very similar to HGGW but uses method GGOV instead to "GET" value, while 'S'GOV "SET" value, and if set to One, then runs HGGW)
I went to Windows and using AIDA64 I ran the different methods on it's ACPI browser and Boom! the external mux got switched. So basically the laptop doesn't give the Hybrid option if your OS is below a certain feature level. So after eliminating the other things that HGGW performs, I narrowed the command down to \_SB.SGOV and 2 values.
The first (Arg2) is sent by HGMD and is SDTG.
So after finding this and testing it I went back to the DSDT and looked for SDTG.
With AIDA64 I queried SDTG for it's value as well as SDTA and SDTE, and I saw that the DSDT also had other variables with similar A.E.G ending, and similar values.
SDPE = 00000000
SDPG = 50593802 ( 0x0304000A )
SDPA = 00000000
SDTE = 00000000
SDTG = 50659332 ( 0x03050004 ) - External Mux
SDTA = 00000000
GETE = 00000000
GETG = 50659336 ( 0x03050008 )
GETA = 00000000
SUOT = 00000000
SUOG = 50659328 ( 0x03050000 ) LCD Power On/OFF ?
SUOA = 00000000
So I realized that the "G" ending in those variables was a device address of some sort.
So I executed \_SB.SGOV and those variables, and with some nothing happened, but on SUOG + 0x01 my LCD powered OFF so I thought it was LCD power control, but on a chat with @EdwardGeo I tested it again and realized it was in fact the LCD Mux, but because the windows AMD driver didn't expect to have a display attached to the LCD output, it was black/OFF. but when I used this on my SSDT on OSX, then everything changed.
And it kind of makes sense, LCD = SUOG = ( 0x03050000 ) | EXT = SDTG = ( 0x03050004 ) the adresses are next to each other.
So this is when things got interesting. I was able to switch the external mux to be run by IGPU in Hybrid mode as well as run the LCD by the DGPU and keep the IGPU in a connector-less framebuffer to make use of quicksync, etc... And have the DRM provided by the AMD card on the internal screen.
I thought this was it as far as solving the problem and I tweaked my SSDT to make it easier to edit and to make sure the Mux setting remained set on wake, and this is when I found the remaining glitch.
Attachments
Last edited: