Contribute
Register

HP ZBOOK VIDEO MUX CONTROL

Status
Not open for further replies.
Joined
Jul 21, 2011
Messages
379
Motherboard
Zbook G5 17"
CPU
i7
Graphics
AMD WX-4170
Mac
  1. MacBook Pro
  2. Mac mini
  3. Mac Pro
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.


Screen Shot 2021-10-11 at 12.57.34 AM.png

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.

Screen Shot 2021-10-11 at 1.00.04 AM.png


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.

Screen Shot 2021-10-10 at 8.55.18 PM.png


"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.

Screen Shot 2021-10-10 at 9.03.53 PM.png


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.

Screen Shot 2021-10-10 at 9.10.40 PM.png


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

  • Screen Shot 2021-10-11 at 12.59.48 AM.png
    Screen Shot 2021-10-11 at 12.59.48 AM.png
    86.5 KB · Views: 84
Last edited:
So, after a bit of trial and error with wake from sleep Mux state reverting to default. I made running all the screens by a supported DGPU while on Hybrid a 100% working setup. Hooray!

Screen Shot 2021-10-09 at 3.35.14 PM.png


(It even came with performance Gains)

Screen Shot 2021-10-11 at 11.42.04 AM.png


Now the power saving mode is still not working as it should.
There's a part of the puzzle I'm missing.

I can switch the external Mux to IGPU and I can see the IGPU handling all the screens, but only If the AMD driver for my WX card is loaded and "enables the outputs"?

Screen Shot 2021-10-08 at 7.13.06 PM.png


If I use the bootflag -wegnoegpu to simulate an unsupported DGPU or boot in UMA mode, there's nothing in the external outputs even when I know the mux is in the right position.

I remember that if I boot in UMA mode and don't inject all the framebuffer ports in config, even though external displays don't work, if I plug - unplug a monitor I get a Kernel Panic, so a part of the OS is aware there is a display connection notification, but at the time I though that because the MUX was in the wrong state, that the sense/notify was getting to the intel driver but no EDID was sent/received and that caused the KP. But now that the MUX is not the issue... what could be the problem?

My theory here is that the MXM slot being populated changes the bios configuration and may be messing with things at an ACPI level.

Either the connect-disconnect notification is reaching the wrong GPU, and if the driver for this GPU is loaded, then the OS re-syncs all displays and finds the output on the other GPU and this explains why it works if the AMD driver is loaded in my config. But doesn't if there's no driver to get that notify.

OR

The external display connector needs to be initiated by an I2C command by the driver and Apple's Intel driver doesn't have this function, but AMD's does, so again if the AMD driver is loaded, then the output is enabled.

This second option explains why in UMA mode where the intel driver should work doesn't, as there's no possibility of a wrong GPU being notified.

OR

If there's an MXM card, then the DDC lines deault to PEG0, and so we need a basic PEG0 driver so IGPU is made aware and takes over?

OR

Something else very obvious that I'm missing?

Needless to say all display outputs work in Linux and Windows in all modes, so this is an OSX problem only.
And it must be a very generic thing, since I can't find a particular HP Hybrid Laptop driver patch or anything like that.

Why is it that if there's no MXM card inserted, UMA is the only mode of display operation available and then all the display outputs work perfectly for IGPU?
I'm sure there must be another ACPI flag indicating there's an MXM card present, but finding this one is finding a second needle in a haystack, and I can't find it on Windows side since this is not a problem in that OS. And no way to run acpicall in OSX to test things out.

I need some help figuring this one out, and I'm sure a lot of people with unsupported DGPU's will benefit from this research.

Attached are my current OEM DSDT-SSDT, my OC hotpatch versions and the Mux-test.
For information on how to use them follow this post: https://www.tonymacx86.com/threads/hp-zbook-g5-17.266012/post-2278977
 

Attachments

  • SSDT-Mux-Test.aml.zip
    1 KB · Views: 104
  • ACPI ZBook-G5.zip
    102.8 KB · Views: 110
  • ACPI-OC.zip
    9.3 KB · Views: 112
Last edited:
It’s great. Although I’m still studying, it gives a very good idea. I think I will try to find a way to learn and replace.
 
My previous theory that the Mux was in the wrong position when in UMA mode has been debunked.
Using Rehabman's AcpiDebug and ioio I was able to query/flip the Muxes in real time, so I believe this is a DDC or Aux channel issue, and I hope someone with more knowledge wants to help.

Attaching mux flip video for fun.
Also latest debug version of my SSDT, with all the needed tools to test.

Need to add Acpidebug kext to your Bootloader + config. Then the ioio command for changing the mux on the fly is:

Code:
ioio -s org_rehabman_ACPIDebug dbg0 0     // Query Mux Status
ioio -s org_rehabman_ACPIDebug dbg1 0     // Flip LCD Mux
ioio -s org_rehabman_ACPIDebug dbg2 0     // Flip External Mux

The first one will print out mux status to console (search for acpi), the second and third flip the LCD and External mux respectively from whatever state they are currently, so if you loose display, just send the same command again.

Screen Shot 2021-10-17 at 8.30.38 PM.png
 

Attachments

  • MUX.mov.zip
    2 MB · Views: 117
  • Mux-Flipper 2.zip
    17.4 KB · Views: 86
Last edited:
New Logs trying to find cause.

Whatevergreen debug boot log
Hybrid mode with HDMI plugged to AMD Card - Working
Hybrid mode with HDMI plugged to IGPU Mux Flipped - Working
UMA mode with HDMI plug/unplug to IGPU - Not-working
 

Attachments

  • Hybrid AMD.txt
    27 KB · Views: 77
  • Hybrid IGPU.txt
    46 KB · Views: 68
  • IGPU-LOGS.txt
    46.7 KB · Views: 74
  • Whatevergreen-DBGLog.txt
    186.4 KB · Views: 72
Last edited:
Update:
I haven't been able to confirm the cause, but at least I believe I've narrowed down the problem.

Theory 1: The external outputs i2c bus is switched from bus 0 (igpu) to bus 3 (dgpu) when an mxm card is inserted, so the igpu can't get the display clock or edid info in OSX when it's in a different i2c bus.

Theory 2: The Parade mux itself is the one that can forward the display info to all gpus if given the right command by the gpu, but in this case the bios made it so that the default is to only forward this info to the dgpu, so we need more documentation on the Parade mux PS8461.

The reason this setup works in linux and windows is because they have either Parade mux control driver support or i2c drivers that can bridge between buses?
 
Status
Not open for further replies.
Back
Top