xserver: Branch 'master'

Eric Anholt anholt at kemper.freedesktop.org
Wed Apr 12 18:00:16 UTC 2017


 hw/xfree86/drivers/modesetting/drmmode_display.c |   51 +++++++++++++++++++++++
 1 file changed, 51 insertions(+)

New commits:
commit bcee1b76aa0db8525b491485e90b8740763d7de6
Author: Martin Peres <martin.peres at linux.intel.com>
Date:   Mon Apr 10 16:48:21 2017 +0300

    modesetting: re-set the crtc's mode when link-status goes BAD
    
    Despite all the careful planning of the kernel, a link may become
    insufficient to handle the currently-set mode. At this point, the
    kernel should mark this particular configuration as being broken
    and potentially prune the mode before setting the offending connector's
    link-status to BAD and send the userspace a hotplug event. This may
    happen right after a modeset or later on.
    
    Upon receiving a hot-plug event, we iterate through the connectors to
    re-apply the currently-set mode on all the connectors that have a
    link-status property set to BAD. The kernel may be able to get the
    link to work by dropping to using a lower link bpp (with the same
    display bpp). However, the modeset may fail if the kernel has pruned
    the mode, so to make users aware of this problem a warning is outputed
    in the logs to warn about having a potentially-black display.
    
    This patch does not modify the current behaviour of always propagating
    the events to the randr clients. This allows desktop environments to
    re-probe the connectors and select a new resolution based on the new
    (currated) mode list if a mode disapeared. This behaviour is expected in
    order to pass the Display Port compliance tests.
    
    Signed-off-by: Martin Peres <martin.peres at linux.intel.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index c1e489e48..516eb7691 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -2253,6 +2253,10 @@ drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn)
 }
 
 #ifdef CONFIG_UDEV_KMS
+
+#define DRM_MODE_LINK_STATUS_GOOD       0
+#define DRM_MODE_LINK_STATUS_BAD        1
+
 static void
 drmmode_handle_uevents(int fd, void *closure)
 {
@@ -2272,6 +2276,49 @@ drmmode_handle_uevents(int fd, void *closure)
     if (!found)
         return;
 
+    /* Try to re-set the mode on all the connectors with a BAD link-state:
+     * This may happen if a link degrades and a new modeset is necessary, using
+     * different link-training parameters. If the kernel found that the current
+     * mode is not achievable anymore, it should have pruned the mode before
+     * sending the hotplug event. Try to re-set the currently-set mode to keep
+     * the display alive, this will fail if the mode has been pruned.
+     * In any case, we will send randr events for the Desktop Environment to
+     * deal with it, if it wants to.
+     */
+    for (i = 0; i < config->num_output; i++) {
+        xf86OutputPtr output = config->output[i];
+        drmmode_output_private_ptr drmmode_output = output->driver_private;
+        uint32_t con_id = drmmode_output->mode_output->connector_id;
+        drmModeConnectorPtr koutput;
+
+        /* Get an updated view of the properties for the current connector and
+         * look for the link-status property
+         */
+        koutput = drmModeGetConnectorCurrent(drmmode->fd, con_id);
+        for (j = 0; koutput && j < koutput->count_props; j++) {
+            drmModePropertyPtr props;
+            props = drmModeGetProperty(drmmode->fd, koutput->props[j]);
+            if (props && props->flags & DRM_MODE_PROP_ENUM &&
+                !strcmp(props->name, "link-status") &&
+                koutput->prop_values[j] == DRM_MODE_LINK_STATUS_BAD) {
+                xf86CrtcPtr crtc = output->crtc;
+                if (!crtc)
+                    continue;
+
+                /* the connector got a link failure, re-set the current mode */
+                drmmode_set_mode_major(crtc, &crtc->mode, crtc->rotation,
+                                       crtc->x, crtc->y);
+
+                xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+                           "hotplug event: connector %u's link-state is BAD, "
+                           "tried resetting the current mode. You may be left"
+                           "with a black screen if this fails...\n", con_id);
+            }
+            drmModeFreeProperty(props);
+        }
+        drmModeFreeConnector(koutput);
+    }
+
     mode_res = drmModeGetResources(drmmode->fd);
     if (!mode_res)
         goto out;
@@ -2336,6 +2383,10 @@ out_free_res:
 out:
     RRGetInfo(xf86ScrnToScreen(scrn), TRUE);
 }
+
+#undef DRM_MODE_LINK_STATUS_BAD
+#undef DRM_MODE_LINK_STATUS_GOOD
+
 #endif
 
 void


More information about the xorg-commit mailing list