Repository navigation
drm/apple: set an external mode again once the display is on - #295
Conversation
An external mode is set with the display powered down, and the display
is powered up after it. For a mode that needs DSC (3840x2160 at 100 and
120 Hz on the J514S HDMI and Type-C ports) the firmware refuses that mode
set ("Modeset done, but pipe not enabled") and resets DSC, and the
power-on only configures DSC: the timings start in a mode set the
firmware makes on its own, after a hotplug notification it sends itself.
A swap that reaches it before then is dropped ("swallowed swap ID 1 as
timings are not enabled") and never completed, so A407 times out after
5 s and the display stays dark until a reboot. A fresh attach lost that
race 3 times out of 3. Without DSC, the power-on starts the timings
itself.
Set the mode once more after the power-on, with the pipe enabled. The
firmware then starts the timings before that call returns, before the
first swap; its own mode set finds them running. KUnit cases check
the calls of an attach and of a mode change.
Signed-off-by: Eryk Wieliczko <eryk@wieliczko.ninja>
Assisted-by: Claude:claude-opus-5-5
chriskearney
left a comment
There was a problem hiding this comment.
Reviewed exact head 7ef3bc1. No source-level blocker found: the second A411 follows successful power-on under the existing RPC lock, and its failure cannot publish the mode as live. Existing admission, already-showing fast path and error handling remain intact.
Independent validation: 27/27 source-extracted host controls passed; the unmodified base fails the added-order check, and 6/6 focused mutants were detected. These cover command ordering, IDs, status/transport failures, locking and scope. The new production-function KUnit suite also passed 2/2 in PR CI. The exact per-file merge onto 31748f0 is clean and preserves #225/#287. The later integration tip 919b433 adds only host-test/CI-vouch files, leaving these driver inputs unchanged.
Our physical display coverage adds J516S, built-in HDMI, 3840×2160@120 Hz with DSC (timing 53, color 88):
- Cold attach after boot completed the A411 → A472-on → A411 sequence successfully; output off/on also returned successful mode status.
- Visual inspection confirmed a clean picture. The declared DCP/DART fault checks recorded zero matches.
- The tested #298 package combines the source-disjoint #295/#297 changes on 31748f0; the primary A2 display test had #297's HDMI-audio opt-in off. Supplemental opt-in B attach/replug observations also returned mode status 0; only those display observations are included here.
One early sn201202x/SPMI “Got interrupt but selection not complete?” warning remains recorded and unattributed. That source is byte-identical between the tested package and 31748f0; it is not hidden by the display-fault result or attributed to this patch.
The author's J514S results on older 3bdf11d plus the patch—3/3 failing fresh attaches before, 5/5 successful after, and 43-mode sweeps per port—remain separate, attributed author evidence, with the stated limit that not every picture was visually inspected.
Our new qualification is bounded to the J516S HDMI observations above. It does not establish USB-C, boot-with-sink-attached, suspend, audio-playback or other-board/default coverage. The source supports approval of this fix; normal current-base merge-queue CI is still required. The earlier PR CI used the older ec8bf85 base, and the combined-package run does not replace that gate.
Problem
On the M3 Pro (J514S), a 4K TV attached at its preferred 3840x2160 @ 100 Hz mode stays dark: the system stalls for about 5 s, then the external display processor is stopped until a reboot (
DCP call 0x41343037 failed: -110; recovery requires a reboot). The same happens on the HDMI port. These are attaches in a mode that needs DSC; 4K @ 120 Hz (also DSC) came up in all 5 attaches we logged, so the race does not hit every DSC attach. 60 Hz never hit it.Cause
dcp_v14_external_modeset()sets the mode (A411) with the display powered down, then powers it up (A472). The firmware log of a failing attach:With DSC, the mode set on the unpowered pipe fails and resets DSC, and the power-on only configures DSC. The timings start later, in a mode set the firmware makes after a hotplug notification it sends itself. A swap that reaches the firmware before then is dropped without a completion, and A407 waits for that completion until it times out.
Without DSC, the power-on itself starts the timings (
deferring: 2 -> 4andswitch to normal mode succeededboth come before A472 returns), so the first swap is shown.The race is lost depending on timing. Re-enabling an already running external display processor won 16 of 16 times, but a fresh attach (plugging in, or booting with the display attached) lost 3 of 3.
Fix
Set the mode once more after the power-on, with the pipe enabled. The firmware then starts the timings before that call returns, so before the first swap. Its own mode set after the hotplug notification then finds them running (
set_timings() called after timings were started, the same as a non-DSC attach already logs).Testing
J514S (M3 Pro), Omarchy
linux-aurora 7.2.11.aurora11(integration/aurora 3bdf11d) plus this patch (rebased onto ec8bf85 for this PR without conflicts; #259 only touches the panel backlight). The display is a 4K TV with 43 modes, including 3840x2160 @ 100/120/119.88 Hz with DSC.dcp_v14_external_modesetwith two cases: an attach (display off) sends A411, A472 on, A411; a mode change sends A472 off, A411, A472 on, A411.run-kunit.py: 144 suites, 1735 cases: 1732 pass, 0 fail, 3 skip (the expected ones inkunit-expected.json), no splats; the new suite passes 2/2.check-commits.py/checkpatch.pl --strict: 0 errors; the only warning is the generic "does MAINTAINERS need updating?" for the new test file, anddrivers/gpu/drm/apple/is already covered.The check was for crashes and timeouts only. The picture on the TV was not inspected for every mode.
Notes
🤖 Generated with Claude Code