From 23438e94910fb4b8cfd9745d5de49b88758287b6 Mon Sep 17 00:00:00 2001 From: Stanislav Lisovskiy Date: Mon, 19 Nov 2018 18:10:35 +0200 Subject: [PATCH xf86-video-intel] Fix plug/unplug problem for DP MST Current ddx implementation seem not to propagate DP MST output changes properly as kernel constantly allocates/deallocates those during plug/unplug, thus changing connector id all the time. Also kernel seems to return different connector ids for the same output for DP MST devices, which seem to confuse userspace. RRCrtcNotify doesn't check connector state and might think that connector is still there while it is not => this leads to a lost modeset call, when DP is plugged again. So check the connector state and force removing it from outputs and also assign crtc to zero. --- src/sna/sna_display.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c index 96e7b1bc..d779b46a 100644 --- a/src/sna/sna_display.c +++ b/src/sna/sna_display.c @@ -5505,12 +5505,11 @@ output_check_link(struct sna *sna, struct sna_output *output) } static bool -output_check_status(struct sna *sna, struct sna_output *output) +output_check_status(struct sna *sna, struct sna_output *output, xf86OutputStatus *status) { union compat_mode_get_connector compat_conn; struct drm_mode_modeinfo dummy; struct drm_mode_get_blob blob; - xf86OutputStatus status; char *edid; VG_CLEAR(compat_conn); @@ -5537,20 +5536,20 @@ output_check_status(struct sna *sna, struct sna_output *output) switch (compat_conn.conn.connection) { case DRM_MODE_CONNECTED: - status = XF86OutputStatusConnected; + *status = XF86OutputStatusConnected; break; case DRM_MODE_DISCONNECTED: - status = XF86OutputStatusDisconnected; + *status = XF86OutputStatusDisconnected; break; default: case DRM_MODE_UNKNOWNCONNECTION: - status = XF86OutputStatusUnknown; + *status = XF86OutputStatusUnknown; break; } - if (output->status != status) + if (output->status != *status) return false; - if (status != XF86OutputStatusConnected) + if (*status != XF86OutputStatusConnected) return true; if (output->num_modes != compat_conn.conn.count_modes) @@ -5636,13 +5635,14 @@ void sna_mode_discover(struct sna *sna, bool tell) for (i = 0; i < sna->mode.num_real_output; i++) { xf86OutputPtr output = config->output[i]; + xf86OutputStatus status; struct sna_output *sna_output = to_sna_output(output); if (sna_output->id == 0) continue; if (sna_output->serial == serial) { - if (output_check_status(sna, sna_output)) { + if (output_check_status(sna, sna_output, &status)) { DBG(("%s: output %s (id=%d), retained state\n", __FUNCTION__, output->name, sna_output->id)); sna_output->last_detect = now; @@ -5653,7 +5653,8 @@ void sna_mode_discover(struct sna *sna, bool tell) sna_output->last_detect = 0; changed |= 4; } - continue; + if (status != XF86OutputStatusDisconnected) + continue; } DBG(("%s: removing output %s (id=%d), serial=%u [now %u]\n", -- 2.17.1