mirror of
https://github.com/X11Libre/xf86-video-intel.git
synced 2026-03-24 01:24:12 +00:00
sna: Check link-status after a hotplug event
If the modeset fails, or the link subsequently fails, we need to perform the modeset again. To signal this the kernel sends us a hotplug uevent with a new link-status property set to bad. The kernel may have to take some corrective action which invalidates the current mode and so the following modeset may fail and we need to go and report to the client for them to choose the next course of action (reconfigure the displays). At the very least the kernel *requires* us to reapply the current mode. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
@@ -257,6 +257,8 @@ struct sna_output {
|
||||
int connector_type;
|
||||
int connector_type_id;
|
||||
|
||||
uint32_t link_status_idx;
|
||||
|
||||
uint32_t edid_idx;
|
||||
uint32_t edid_blob_id;
|
||||
uint32_t edid_len;
|
||||
@@ -311,6 +313,8 @@ enum { /* XXX copied from hw/xfree86/modes/xf86Crtc.c */
|
||||
|
||||
static void __sna_output_dpms(xf86OutputPtr output, int dpms, int fixup);
|
||||
static void sna_crtc_disable_cursor(struct sna *sna, struct sna_crtc *crtc);
|
||||
static bool sna_crtc_flip(struct sna *sna, struct sna_crtc *crtc,
|
||||
struct kgem_bo *bo, int x, int y);
|
||||
|
||||
static bool is_zaphod(ScrnInfoPtr scrn)
|
||||
{
|
||||
@@ -5140,6 +5144,8 @@ reset:
|
||||
sna_output->id = compat_conn.conn.connector_id;
|
||||
sna_output->is_panel = is_panel(compat_conn.conn.connector_type);
|
||||
sna_output->edid_idx = find_property(sna, sna_output, "EDID");
|
||||
sna_output->link_status_idx =
|
||||
find_property(sna, sna_output, "link-status");
|
||||
if (find_property(sna, sna_output, "scaling mode") != -1)
|
||||
sna_output->add_default_modes =
|
||||
xf86ReturnOptValBool(output->options, OPTION_DEFAULT_MODES, TRUE);
|
||||
@@ -5302,6 +5308,45 @@ bool sna_mode_find_hotplug_connector(struct sna *sna, unsigned id)
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
output_retrain_link(struct sna *sna, struct sna_output *output)
|
||||
{
|
||||
struct sna_crtc *crtc = to_sna_crtc(output->base->crtc);
|
||||
int crtc_x = crtc->offset & 0xffff;
|
||||
int crtc_y = crtc->offset >> 16;
|
||||
|
||||
return sna_crtc_flip(sna, crtc, crtc->bo, crtc_x, crtc_y);
|
||||
}
|
||||
|
||||
static bool
|
||||
output_check_link(struct sna *sna, struct sna_output *output)
|
||||
{
|
||||
uint64_t link_status;
|
||||
|
||||
if (!output->base->crtc)
|
||||
return true;
|
||||
|
||||
if (output->link_status_idx == -1)
|
||||
return true;
|
||||
|
||||
#define LINK_STATUS_GOOD 0
|
||||
link_status = output->prop_values[output->link_status_idx];
|
||||
DBG(("%s: link_status=%d\n", __FUNCTION__, link_status));
|
||||
if (link_status == LINK_STATUS_GOOD)
|
||||
return true;
|
||||
|
||||
/* Perform a modeset as required for "link-status" = BAD */
|
||||
if (!output_retrain_link(sna, output))
|
||||
return false;
|
||||
|
||||
/* Query the "link-status" again to confirm the modeset */
|
||||
update_properties(sna, output);
|
||||
|
||||
link_status = output->prop_values[output->link_status_idx];
|
||||
DBG(("%s: link_status=%d after modeset\n", __FUNCTION__, link_status));
|
||||
return link_status == LINK_STATUS_GOOD;
|
||||
}
|
||||
|
||||
static bool
|
||||
output_check_status(struct sna *sna, struct sna_output *output)
|
||||
{
|
||||
@@ -5311,9 +5356,6 @@ output_check_status(struct sna *sna, struct sna_output *output)
|
||||
xf86OutputStatus status;
|
||||
char *edid;
|
||||
|
||||
if (output->reprobe)
|
||||
return false;
|
||||
|
||||
VG_CLEAR(compat_conn);
|
||||
|
||||
compat_conn.conn.connection = -1;
|
||||
@@ -5330,6 +5372,12 @@ output_check_status(struct sna *sna, struct sna_output *output)
|
||||
&compat_conn.conn) == 0)
|
||||
output->update_properties = false;
|
||||
|
||||
if (!output_check_link(sna, output))
|
||||
return false;
|
||||
|
||||
if (output->reprobe)
|
||||
return false;
|
||||
|
||||
switch (compat_conn.conn.connection) {
|
||||
case DRM_MODE_CONNECTED:
|
||||
status = XF86OutputStatusConnected;
|
||||
|
||||
Reference in New Issue
Block a user