# [REGRESSION] 7.1: apple-gmux backlight dead on MacBookPro13,3 - PCI bridge left with VGA enable set and VGA 16-bit decode cleared, aliasing legacy VGA I/O over the gmux ports
## Summary Since Linux 7.1 the backlight on a MacBookPro13,3 (15" 2016, Touch Bar) cannot be controlled at all. `apple_gmux` still probes successfully during boot, but a few hundred milliseconds later the VGA arbiter reprograms `PCI_BRIDGE_CONTROL` of the root port `00:01.0` into a state where the bridge decodes legacy VGA I/O with only 10 address bits. `0x3c0-0x3df` then aliases onto `0x7c0-0x7df`, which is exactly where the gmux "indexed" protocol registers live, so the bridge claims those cycles and forwards them to the dGPU. Every gmux read returns `0xff` and every gmux write is swallowed. - Last known good: 6.16.10 (Arch `linux` 6.16.10.arch1-1) - Also good: 6.12.51 (Arch `linux-lts` 6.12.51-1) - Bad: 7.1.5 (Arch `linux` 7.1.5.arch1-2) ## Hardware ``` DMI: Apple Inc. MacBookPro13,3/Mac-A5C67F76ED83108C, BIOS 529.120.1.0.0 03/14/2024 00:01.0 PCI bridge [0604]: Intel 6th-10th Gen Core Processor PCIe Controller (x16) [8086:1901] (rev 07) 00:02.0 VGA compatible controller [0300]: Intel Skylake-H GT2 [HD Graphics 530] [8086:191b] (rev 06) -> i915 01:00.0 VGA compatible controller [0300]: AMD Baffin [Radeon Pro 455] [1002:67ef] (rev c7) -> amdgpu gmux: PNP HID APP000B, "Found gmux version 4.0.29 [indexed]" ``` ## Symptom ``` $ cat /sys/class/backlight/gmux_backlight/actual_brightness 16777215 ``` 16777215 is `0x00ffffff`, which is `GMUX_BRIGHTNESS_MASK` applied to an all-ones I/O read. Writes to `brightness` have no effect. `brightnessctl`, the Touch Bar brightness keys and the desktop brightness slider all fail, because all three go through this single backlight device. ## Root cause `PCI_BRIDGE_CONTROL` (offset 0x3e) of `00:01.0`, read after boot has settled: ``` 6.12.51-lts : 0x0012 bit1 SERR, bit4 VGA_16BIT set, bit3 VGA enable clear -> works 6.16.10-arch1 : (not read at register level, but backlight works) 7.1.5-arch1-2 : 0x000a bit1 SERR, bit3 VGA enable set, bit4 VGA_16BIT clear -> broken ``` With `PCI_BRIDGE_CTL_VGA` set and `PCI_BRIDGE_CTL_VGA_16BIT` clear, the bridge ignores address bits [15:10] for legacy VGA I/O, so the ranges alias: ``` 0x3b0-0x3bb -> 0x7b0-0x7bb 0x3c0-0x3df -> 0x7c0-0x7df ``` apple-gmux uses the following ports on this machine (PNP resource `0x700-0x7fe`): ``` GMUX_PORT_READ 0x7d0 GMUX_PORT_WRITE 0x7d4 index magic sequence 0x7cc / 0x7cd / 0x7ce ``` All of them fall inside the aliased window, so the bridge steals them. ## Direct verification via /dev/port on 7.1.5 Before: ``` inb(0x7cc) = ff inb(0x7cd) = ff inb(0x7ce) = ff inb(0x7d0) = ff inb(0x7d4) = ff ``` Set only the 16-bit decode bit, nothing else: ``` # setpci -s 00:01.0 BRIDGE_CONTROL=0010:0010 ``` After (gmux_is_indexed() magic sequence, write 0xaa/0x55/0x00 then read back): ``` outb(0x7cc, 0xaa); outb(0x7cd, 0x55); outb(0x7ce, 0x00) inb(0x7cc) = aa inb(0x7cd) = 55 -> gmux responds ``` Then: ``` # modprobe -r apple_gmux && modprobe apple_gmux apple_gmux: Found gmux version 4.0.29 [indexed] # cat /sys/class/backlight/gmux_backlight/actual_brightness 118 ``` 118 is the value the panel had actually been stuck at the whole time, which confirms that no write had ever reached the hardware. Writing 100 / 400 / 700 / 1023 afterwards changes the panel brightness, visually confirmed. ## Boot timeline 7.1.5-arch1-2 (broken): ``` [ 7.947] pci 0000:00:02.0: vgaarb: setting as boot VGA device [ 7.947] pci 0000:00:02.0: vgaarb: VGA device added: decodes=io+mem,owns=io+mem,locks=none [ 7.947] pci 0000:01:00.0: vgaarb: setting as boot VGA device (overriding previous) [ 7.948] pci 0000:01:00.0: vgaarb: VGA device added: decodes=io+mem,owns=none,locks=none [ 8.005] amdgpu 0000:01:00.0: vgaarb: deactivate vga console [ 9.494] apple_gmux: Found gmux version 4.0.29 [indexed] <-- probe still OK [ 10.059] i915 0000:00:02.0: vgaarb: VGA decodes changed: olddecodes=io+mem,decodes=io:owns=io+mem [ 11.150] i915 0000:00:02.0: vgaarb: VGA decodes changed: olddecodes=io,decodes=none:owns=io+mem [ 11.150] amdgpu 0000:01:00.0: vgaarb: VGA decodes changed: olddecodes=io+mem,decodes=none:owns=none ``` 6.16.10-arch1-1 (good): ``` [ 6.785] pci 0000:00:02.0: vgaarb: VGA device added: decodes=io+mem,owns=io+mem,locks=none [ 6.785] pci 0000:01:00.0: vgaarb: setting as boot VGA device (overriding previous) [ 6.785] pci 0000:01:00.0: vgaarb: VGA device added: decodes=io+mem,owns=none,locks=none [ 6.839] amdgpu 0000:01:00.0: vgaarb: deactivate vga console [ 8.339] apple_gmux: Found gmux version 4.0.29 [indexed] [ 8.348] i915 0000:00:02.0: vgaarb: VGA decodes changed: olddecodes=io+mem,decodes=none:owns=io+mem [ 8.349] amdgpu 0000:01:00.0: vgaarb: VGA decodes changed: olddecodes=io+mem,decodes=none:owns=none ``` 6.12.51-lts (good): ``` [ 8.480] apple_gmux: Found gmux version 4.0.29 [indexed] [ 8.487] i915 0000:00:02.0: vgaarb: VGA decodes changed: olddecodes=io+mem,decodes=none:owns=io+mem [ 8.489] amdgpu 0000:01:00.0: vgaarb: VGA decodes changed: olddecodes=io+mem,decodes=none:owns=none ``` The relevant difference: on 6.12 and 6.16 the i915 legacy decode goes `io+mem -> none` in a single step. On 7.1.5 it goes `io+mem -> io` and then, about 1.1 seconds later, `io -> none`. The final arbiter state is `decodes=none` for both devices on all three kernels, yet only on 7.1.5 does the bridge end up with `PCI_BRIDGE_CTL_VGA` set and `PCI_BRIDGE_CTL_VGA_16BIT` cleared. The intermediate `decodes=io` state appears to leave the bridge in the 10-bit aliasing configuration and the subsequent transition to `none` does not undo it. `drivers/platform/x86/apple-gmux.c` only received cosmetic changes during the 7.1 cycle, so this looks like a PCI / vgaarb side change rather than a driver bug. ## Workaround ``` # setpci -s 00:01.0 BRIDGE_CONTROL=0010:0010 # modprobe -r apple_gmux && modprobe apple_gmux ``` Setting the 16-bit decode bit is enough. This machine is KMS only and `amdgpu: vgaarb: deactivate vga console` has already happened, so nothing depends on 10-bit legacy VGA I/O aliasing here. ## Notes - The breakage happens after `apple_gmux` has already probed, so the driver reports no error. The failure is silent. - A machine with a discrete GPU behind `00:01.0` and gmux at `0x700-0x7fe` is the affected shape. MacBookPro13,1 and 13,2 have no dGPU and no bridge in the path, so they are presumably unaffected. #regzbot introduced: v6.16..v7.1
