summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLyude Paul <lyude@redhat.com>2018-06-07 20:30:34 -0400
committerAdam Jackson <ajax@redhat.com>2018-08-01 11:01:37 -0400
commit821f38fa56087fcb11d2d2483366307fc88bf365 (patch)
tree13e1369422e957c73528671df0149d28ff2590c2
parent2f4d0d84266b82d8838b8b9b7972f45d66f0e2d1 (diff)
modesetting: Also disable CRTC in drmmode_output_disable()
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 <lyude@redhat.com> Cc: Louis-Francis Ratté-Boulianne <lfrb@collabora.com> Reviewed-by: Dave Airlie <airlied@redhat.com> (cherry picked from commit c12f1bd4b76088ea66e3bec9ab9721a52b20cdf2)
-rw-r--r--hw/xfree86/drivers/modesetting/drmmode_display.c11
1 files 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);