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 <[email protected]> --- 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 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
