[PATCH xserver 7/7] modesetting: Squash link-status check into output re-evaluation loop

Daniel Martin consume.noise at gmail.com
Mon Nov 20 10:02:10 UTC 2017


By using a helper function it looks more streamlined and we don't do to
drmModeGetConnectorCurrent() in drmmode_handle_uevents() twice.

Signed-off-by: Daniel Martin <consume.noise at gmail.com>
---
 hw/xfree86/drivers/modesetting/drmmode_display.c | 99 +++++++++++-------------
 1 file changed, 47 insertions(+), 52 deletions(-)

diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index e0c9f0e69..fdf059583 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -1255,6 +1255,26 @@ koutput_equals_output(int fd, xf86OutputPtr output,
     return !strcmp(koutput_path_blob->data, drmmode_output->path_blob->data);
 }
 
+/* TODO: Defines can be removed with libdrm >= v2.4.78 */
+#define DRM_MODE_LINK_STATUS_GOOD       0
+#define DRM_MODE_LINK_STATUS_BAD        1
+
+static Bool
+koutput_link_status_good(int fd, drmModeConnectorPtr koutput)
+{
+    int idx = koutput_get_prop_idx(fd, koutput,
+            DRM_MODE_PROP_ENUM, "link-status");
+
+    /* Unknown property? Treat as link-status == good. */
+    if (idx == -1)
+        return TRUE;
+
+    return (koutput->prop_values[idx] == DRM_MODE_LINK_STATUS_GOOD);
+}
+
+#undef DRM_MODE_LINK_STATUS_BAD
+#undef DRM_MODE_LINK_STATUS_GOOD
+
 #endif
 
 static void
@@ -2279,9 +2299,6 @@ 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)
 {
@@ -2301,51 +2318,6 @@ 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];
-        xf86CrtcPtr crtc = output->crtc;
-        drmmode_output_private_ptr drmmode_output = output->driver_private;
-        uint32_t con_id, idx;
-        drmModeConnectorPtr koutput;
-
-        if (crtc == NULL || drmmode_output->output_id == -1)
-            continue;
-
-        con_id = drmmode_output->output_id;
-        /* Get an updated view of the properties for the current connector and
-         * look for the link-status property
-         */
-        koutput = drmModeGetConnectorCurrent(drmmode->fd, con_id);
-        if (!koutput)
-            continue;
-
-        idx = koutput_get_prop_idx(drmmode->fd, koutput,
-                DRM_MODE_PROP_ENUM, "link-status");
-
-        if ((idx > -1) &&
-                (koutput->prop_values[idx] == DRM_MODE_LINK_STATUS_BAD)) {
-            /* 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);
-        }
-
-        drmModeFreeConnector(koutput);
-    }
-
     mode_res = drmModeGetResources(drmmode->fd);
     if (!mode_res)
         goto out;
@@ -2359,6 +2331,7 @@ drmmode_handle_uevents(int fd, void *closure)
     for (i = 0; i < mode_res->count_connectors; i++) {
         drmModePropertyBlobPtr path_blob;
         drmModeConnectorPtr koutput;
+        xf86OutputPtr output;
 
         koutput = drmModeGetConnectorCurrent(drmmode->fd,
                 mode_res->connectors[i]);
@@ -2369,7 +2342,7 @@ drmmode_handle_uevents(int fd, void *closure)
         found = FALSE;
 
         for (j = 0; j < config->num_output; j++) {
-            xf86OutputPtr output = config->output[j];
+            output = config->output[j];
             drmmode_output_private_ptr drmmode_output;
 
             drmmode_output = output->driver_private;
@@ -2388,6 +2361,31 @@ drmmode_handle_uevents(int fd, void *closure)
         if (!found) {
             changed = TRUE;
             drmmode_output_init(scrn, drmmode, mode_res, i, TRUE, 0);
+        } else
+        if (output->crtc && !koutput_link_status_good(drmmode->fd, koutput)) {
+            /* 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.
+             */
+            xf86CrtcPtr crtc = output->crtc;
+
+            drmmode_set_mode_major(crtc, &crtc->mode, crtc->rotation,
+                                   crtc->x, crtc->y);
+
+            xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+                       "hotplug event: output %s's link-state is BAD, "
+                       "tried resetting the current mode. You may be left"
+                       "with a black screen if this fails...\n",
+                       output->name);
+
+            changed = TRUE;
         }
 
         drmModeFreePropertyBlob(path_blob);
@@ -2434,9 +2432,6 @@ out:
     RRGetInfo(xf86ScrnToScreen(scrn), TRUE);
 }
 
-#undef DRM_MODE_LINK_STATUS_BAD
-#undef DRM_MODE_LINK_STATUS_GOOD
-
 #endif
 
 void
-- 
2.13.6



More information about the xorg-devel mailing list