xf86-video-intel: 2 commits - src/sna/sna_display.c src/sna/sna_driver.c src/sna/sna.h

Chris Wilson ickle at kemper.freedesktop.org
Fri Oct 21 10:34:33 UTC 2016


 src/sna/sna.h         |    1 +
 src/sna/sna_display.c |   27 +++++++++++++++++++++++++--
 src/sna/sna_driver.c  |    9 +++++++--
 3 files changed, 33 insertions(+), 4 deletions(-)

New commits:
commit b9cebe59f9ddc1b38e47514e04a37b6de4efe2df
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Oct 21 09:52:18 2016 +0100

    sna: Ignore the current CRTC mode following a hotplug event
    
    If we detect a change in the output status, ignore the residual mode on
    the CRTC. We use this CRTC mode during inheritance to provide
    continuity and to make xrandr look neat we ensure that the mode is
    included in the output list. However, following a hotplug event the
    current mode may now be invalid and needs to be pruned.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 5e8c50a..9d60d9a 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -272,6 +272,7 @@ struct sna_output {
 
 	uint32_t last_detect;
 	uint32_t status;
+	unsigned int hotplug_count;
 	bool update_properties;
 	bool reprobe;
 
@@ -3971,7 +3972,7 @@ sna_output_get_modes(xf86OutputPtr output)
 	sna_output_attach_tile(output);
 
 	current = NULL;
-	if (output->crtc) {
+	if (output->crtc && !sna_output->hotplug_count) {
 		struct drm_mode_crtc mode;
 
 		VG_CLEAR(mode);
@@ -5302,6 +5303,7 @@ void sna_mode_discover(struct sna *sna, bool tell)
 			} else {
 				DBG(("%s: output %s (id=%d), changed state, reprobing\n",
 				     __FUNCTION__, output->name, sna_output->id));
+				sna_output->hotplug_count++;
 				sna_output->last_detect = 0;
 				changed |= 4;
 			}
commit 6a2e5bca4214a3785f20fa8ba3dce5325ef75a27
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Oct 21 09:46:23 2016 +0100

    sna: Force a reprobe for the specified hotplug connector
    
    If the kernel can provide us with the exact connector that needs
    reprobing following a hotplug event, use it.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index fb5c007..09f57cc 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -470,6 +470,7 @@ extern void sna_shadow_unset_crtc(struct sna *sna, xf86CrtcPtr crtc);
 extern bool sna_pixmap_discard_shadow_damage(struct sna_pixmap *priv,
 					     const RegionRec *region);
 extern void sna_mode_set_primary(struct sna *sna);
+extern bool sna_mode_find_hotplug_connector(struct sna *sna, unsigned id);
 extern void sna_mode_close(struct sna *sna);
 extern void sna_mode_fini(struct sna *sna);
 
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index ea7e287..5e8c50a 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -273,6 +273,7 @@ struct sna_output {
 	uint32_t last_detect;
 	uint32_t status;
 	bool update_properties;
+	bool reprobe;
 
 	int num_modes;
 	struct drm_mode_modeinfo *modes;
@@ -3548,6 +3549,7 @@ sna_output_detect(xf86OutputPtr output)
 	DBG(("%s(%s): found %d modes, connection status=%d\n",
 	     __FUNCTION__, output->name, sna_output->num_modes, compat_conn.conn.connection));
 
+	sna_output->reprobe = false;
 	sna_output->last_detect = now;
 	switch (compat_conn.conn.connection) {
 	case DRM_MODE_CONNECTED:
@@ -5147,6 +5149,22 @@ static bool disable_unused_crtc(struct sna *sna)
 	return update;
 }
 
+bool sna_mode_find_hotplug_connector(struct sna *sna, unsigned id)
+{
+	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
+	int i;
+
+	for (i = 0; i < sna->mode.num_real_output; i++) {
+		struct sna_output *output = to_sna_output(config->output[i]);
+		if (output->id == id) {
+			output->reprobe = true;
+			return true;
+		}
+	}
+
+	return false;
+}
+
 static bool
 output_check_status(struct sna *sna, struct sna_output *output)
 {
@@ -5156,6 +5174,9 @@ 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;
@@ -5237,7 +5258,7 @@ void sna_mode_discover(struct sna *sna, bool tell)
 	     res.count_connectors, sna->mode.num_real_output,
 	     res.count_encoders, res.count_crtcs));
 	if (res.count_connectors > 32)
-		return;
+		res.count_connectors = 32;
 
 	assert(sna->mode.num_real_crtc == res.count_crtcs || is_zaphod(sna->scrn));
 	assert(sna->mode.max_crtc_width  == res.max_width);
diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c
index 57562b2..c731e58 100644
--- a/src/sna/sna_driver.c
+++ b/src/sna/sna_driver.c
@@ -796,8 +796,13 @@ sna_handle_uevents(int fd, void *closure)
 			const char *str;
 
 			str = udev_device_get_property_value(dev, "HOTPLUG");
-			if (str && atoi(str) == 1)
-				hotplug = true;
+			if (str && atoi(str) == 1) {
+				str = udev_device_get_property_value(dev, "CONNECTOR");
+				if (str)
+					hotplug |= sna_mode_find_hotplug_connector(sna, atoi(str));
+				else
+					hotplug = true;
+			}
 		}
 
 		udev_device_unref(dev);


More information about the xorg-commit mailing list