drm/apple: don't latch ->crashed when the poweroff clear swap times out - #2
Chromatischer wants to merge 1 commit into
Conversation
iomfb_poweroff() submits a clear swap and waits 50 ms for it. When the display is a Type-C output that has already been unplugged, the firmware has nothing left to swap to and swallows the request: IOMFB: swap_submit_dcp: swallowed swap ID 1348 as fControllerPowerState is 0 for External Display The completion misses its window, the wait times out, and ->crashed is set with nothing logged. dcp_crtc_atomic_check() then returns -EINVAL for every commit on that CRTC, so the next plug trains the link, reads a 256-byte EDID and a full mode list, and reports the connector as connected -- while the screen stays dark. The compositor walks every mode down to 640x480, has each one rejected, and gives up. Only a reboot clears it. One unplug is enough to reach that state. The DCP has not crashed: a real firmware crash arrives through dcp_rtk_crashed(), which sets the same flag and says so. A swallowed clear swap on the way down is the ordinary unplug. Warn instead, and keep the early return. Carrying on into iomfb_abort_swaps_dcp() and setPowerState(0) leaves less state behind and matches what the setPowerState(0) wait further down already does on its own timeout, so it was tried first -- but for a display that is already gone it is worse. The dptx HPD deassert then fails: apple-dcp 271c00000.dcp: failed to deassert Type-C DPTX HPD: -110 and the next plug borrows the route and reports connected=0 without ever asserting HPD, so the display does not come back at all. The early return is load-bearing. Tested on J313 (M1 MacBook Air, t8103) with a Type-C to HDMI adapter. Plug, unplug, replug and suspend/resume all bring the display back; before, one unplug left it enumerated but unusable for the rest of the boot. Signed-off-by: Chromatischer <dominik@hildania.de> Assisted-by: Claude:claude-opus-5
6060a10 to
c1e902d
Compare
|
| /* | ||
| * An unplugged display leaves this swap unacknowledged. That | ||
| * is not a crash, and ->crashed rejects every later commit on | ||
| * this CRTC until reboot. Return rather than continuing the | ||
| * teardown: that path fails the dptx HPD deassert and the | ||
| * display never comes back. | ||
| */ | ||
| dev_warn(dcp->dev, | ||
| "poweroff: clear swap did not complete in 50 ms\n"); |
There was a problem hiding this comment.
A clear-swap timeout can also occur when the DCP silently stops responding. RTKit only calls dcp_rtk_crashed() after an explicit crashlog message, so a silent wedge does not set dcp->crashed. This change treats every timeout as benign, allowing later atomic checks and readiness waits to keep sending work to unresponsive firmware instead of failing fast, which can cause repeated command timeouts. Only suppress the crash latch when the timeout can be attributed to a disconnected output.
| dev_warn(dcp->dev, | ||
| "poweroff: clear swap did not complete in 50 ms\n"); |
There was a problem hiding this comment.
This branch is described as an expected result of routinely unplugging an external display, but it emits an unconditional warning each time. That makes normal hot-unplug activity look like a driver fault and adds avoidable kernel-log noise. Use an informational or debug-level message, or rate-limit the diagnostic.
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
One unplug of a Type-C display kills that output until reboot. This is the
-EINVAL-after-replug from aurora-silicon#2 on J416c. It is notpossible_crtcs.iomfb_poweroff()waits 50 ms for a clear swap. On unplug the display is already gone and the firmware swallows it:so the completion misses its window and
iomfb_template.c:939setsdcp->crashed = true, silently.dcp_crtc_atomic_check()then rejects every later commit on that CRTC. The replug still trains the link and reads a 256-byte EDID and 31 modes, so the connector readsconnectedwhile the screen stays dark and the compositor gives up after 141 rejected commits. Nothing is logged — the other assignment,dcp_rtk_crashed(), prints "DCP has crashed"; this one prints nothing.Warn instead. A real firmware crash still arrives through
dcp_rtk_crashed().The early return is load-bearing. Continuing into
iomfb_abort_swaps_dcp()andsetPowerState(0)was built and tested first — for a display that is already gone the dptx HPD deassert then fails with-110, the next plug never asserts HPD, and the display does not come back at all.Tested on J313 (M1 MacBook Air, t8103), USB-C to HDMI adapter, LG 4K at 3840x2160@30: plug, unplug, replug and suspend/resume all bring the display back. Rejected atomic commits 141 → 0.