On a MTL laptop with a ThinkPad Thunderbolt 4 dock (Synaptics VMM6212) and a TV behind it, powering the TV on makes the dock drop the upstream HPD for about 1.76 s. The MST topology is torn down and rebuilt, and the display stays black for about 5 s. The drm.debug log of the report shows two "Failed to get ACT after 3000 ms, last status: 04" errors, and in both cases the driver waits for an ACT it never triggered (timestamps from that log):
- 24262.495: intel_dp_retrain_link() forces a modeset on the pipe still bound to the old, unregistered MST connector, while the topology is being rediscovered. drm_dp_add_payload_part1() fails with "VCPI 1 for port ... not in topology", but the enable goes on and waits 3 s for an ACT, with no write to DPCD 0x1c0-0x1c2 in between. - 24267.035: userspace disables the same pipe afterwards. drm_dp_remove_payload_part1() prints "not in topology, not sending remove", and the disable waits another 3 s for an ACT. The new connector is only registered after the first wait is over. Patch 1 makes drm_dp_remove_payload_part1() tell whether it removed the payload from the branch device. The existing callers ignore the return value. Patch 2 stops retraining the link when the MST sinks of all the active pipes are gone, and skips the wait for the ACT at the branch if the payload wasn't allocated or removed there. I haven't tested this on the reporter's setup yet, the analysis is based on the log attached to the issue. Patch 1 touches the drm core, it is included here for patch 2 to build. Issue: https://gitlab.freedesktop.org/drm/i915/kernel/-/work_items/17741 v2: - patch 1: drm_dp_remove_payload_part1() returns true only if the payload was allocated to the DFP or the remote end, and not just if the port is in the topology (Sashiko). Kernel-doc updated accordingly. - patch 2 (Sashiko): - Skip the link retrain only if all the active pipes have a disconnected MST sink, otherwise the link isn't retrained when some streams stay. - Check that the port is in the topology too, as the connector unregistration is asynchronous. - Keep the ACT generation and the wait for it in the source, skip only the wait at the branch. - Do the same on enable, where the wait at the branch was unguarded. - v1 was sent twice, the first time by mistake without threading: https://patchwork.freedesktop.org/series/177320/ Xiao Lu (2): drm/dp_mst: Return whether drm_dp_remove_payload_part1() removed the payload drm/i915/dp_mst: Skip link retrain and the ACT wait for disconnected MST streams drivers/gpu/drm/display/drm_dp_mst_topology.c | 17 ++++- .../drm/i915/display/intel_dp_link_training.c | 8 +++ drivers/gpu/drm/i915/display/intel_dp_mst.c | 69 +++++++++++++++---- drivers/gpu/drm/i915/display/intel_dp_mst.h | 1 + include/drm/display/drm_dp_mst_helper.h | 2 +- 5 files changed, 82 insertions(+), 15 deletions(-) -- 2.43.0
