From: Martin Peres <martin.pe...@linux.intel.com>

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.

(Ported from xserver commit bcee1b76aa0db8525b491485e90b8740763d7de6)

[ Michel: Bump libdrm dependency to >= 2.4.78 for
  DRM_MODE_LINK_STATUS_BAD ]

Signed-off-by: Michel Dänzer <michel.daen...@amd.com>
---
 configure.ac          |  2 +-
 src/drmmode_display.c | 43 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/configure.ac b/configure.ac
index c9bc0a958..170f42ef7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -70,7 +70,7 @@ XORG_DRIVER_CHECK_EXT(XV, videoproto)
 XORG_DRIVER_CHECK_EXT(DPMSExtension, xextproto)
 
 # Checks for libraries.
-PKG_CHECK_MODULES(LIBDRM, [libdrm >= 2.4.60])
+PKG_CHECK_MODULES(LIBDRM, [libdrm >= 2.4.78])
 PKG_CHECK_MODULES(LIBDRM_RADEON, [libdrm_radeon])
 
 # Obtain compiler/linker options for the driver dependencies
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 4839b415c..f926bc018 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -2826,6 +2826,49 @@ radeon_mode_hotplug(ScrnInfoPtr scrn, drmmode_ptr 
drmmode)
        Bool changed = FALSE;
        int num_dvi = 0, num_hdmi = 0;
 
+       /* 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(pRADEONEnt->fd, con_id);
+               for (j = 0; koutput && j < koutput->count_props; j++) {
+                       drmModePropertyPtr props;
+                       props = drmModeGetProperty(pRADEONEnt->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(pRADEONEnt->fd);
        if (!mode_res)
                goto out;
-- 
2.14.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to