[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