From c12f1bd4b76088ea66e3bec9ab9721a52b20cdf2 Mon Sep 17 00:00:00 2001 From: Lyude Paul Date: Thu, 7 Jun 2018 20:30:34 -0400 Subject: modesetting: Also disable CRTC in drmmode_output_disable() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit So, this did actually work on older kernels at one point in time, however it seems that this working was a result of some of the Linux kernel's atomic modesetting helpers not preserving the CRTC's enabled state in the right spots. This was fixed in: 846c7dfc1193 ("drm/atomic: Try to preserve the crtc enabled state in drm_atomic_remove_fb, v2") As a result, atomic commits which simply disassociate a DRM connector with it's CRTC while leaving the CRTC in an enabled state aren't enough to disable the CRTC, and result in the atomic commit failing. This currently can cause issues with MST hotplugging where X will end up failing to disable the MST outputs after they've left the system. A simple reproducer: - Start up Xorg - Connect an MST hub with displays connected to it - Remove the hub - Now there should be CRTCs stuck on the orphaned MST connectors, and X won't be able to reclaim them. Signed-off-by: Lyude Paul Cc: Louis-Francis Ratté-Boulianne Reviewed-by: Dave Airlie --- hw/xfree86/drivers/modesetting/drmmode_display.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c index ec11b3f56..53e055611 100644 --- a/hw/xfree86/drivers/modesetting/drmmode_display.c +++ b/hw/xfree86/drivers/modesetting/drmmode_display.c @@ -695,18 +695,21 @@ drmmode_output_disable(xf86OutputPtr output) { modesettingPtr ms = modesettingPTR(output->scrn); drmmode_output_private_ptr drmmode_output = output->driver_private; + xf86CrtcPtr crtc = drmmode_output->current_crtc; drmModeAtomicReq *req = drmModeAtomicAlloc(); uint32_t flags = DRM_MODE_ATOMIC_ALLOW_MODESET; - int ret; + int ret = 0; assert(ms->atomic_modeset); if (!req) return 1; - /* XXX Can we disable all outputs without disabling CRTC right away? */ - ret = connector_add_prop(req, drmmode_output, - DRMMODE_CONNECTOR_CRTC_ID, 0); + ret |= connector_add_prop(req, drmmode_output, + DRMMODE_CONNECTOR_CRTC_ID, 0); + if (crtc) + ret |= crtc_add_dpms_props(req, crtc, DPMSModeOff, NULL); + if (ret == 0) ret = drmModeAtomicCommit(ms->fd, req, flags, NULL); -- cgit v1.2.3