xf86-video-intel: src/sna/sna_display.c

Chris Wilson ickle at kemper.freedesktop.org
Wed Oct 9 08:10:40 PDT 2013


 src/sna/sna_display.c |   50 ++++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 44 insertions(+), 6 deletions(-)

New commits:
commit 6fda305e2f2f991b39d09e67d0b17c8c3d50f9a4
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Oct 9 15:59:42 2013 +0100

    sna: Append the current mode to the output list if not found
    
    If for some reason the current mode on the CRTC (inherited most likely
    from fastboot) doesn't match any of the modes reported by the output, we
    end up with a stray mode that the client cannot control.
    
    Reported-by: Jiri Slaby <jirislaby at gmail.com>
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=70132
    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 dddc6d7..e893bcd 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -2039,21 +2039,46 @@ sna_output_get_modes(xf86OutputPtr output)
 {
 	struct sna_output *sna_output = output->driver_private;
 	DisplayModePtr Modes = NULL;
+	DisplayModeRec current;
+	bool has_current = false;
 	int i;
 
-	DBG(("%s\n", __FUNCTION__));
+	DBG(("%s(%s)\n", __FUNCTION__, output->name));
 
 	sna_output_attach_edid(output);
 
+	memset(&current, 0, sizeof(current));
+	if (output->crtc) {
+		struct drm_mode_crtc mode;
+
+		VG_CLEAR(mode);
+		mode.crtc_id = to_sna_crtc(output->crtc)->id;
+
+		if (drmIoctl(to_sna(output->scrn)->kgem.fd, DRM_IOCTL_MODE_GETCRTC, &mode) == 0) {
+			DBG(("%s: CRTC:%d, pipe=%d: has mode?=%d\n", __FUNCTION__,
+			     to_sna_crtc(output->crtc)->id,
+			     to_sna_crtc(output->crtc)->pipe,
+			     mode.mode_valid && mode.mode.clock));
+
+			if (mode.mode_valid && mode.mode.clock)
+				mode_from_kmode(output->scrn, &mode.mode, &current);
+		}
+	}
+
 	for (i = 0; i < sna_output->num_modes; i++) {
 		DisplayModePtr Mode;
 
 		Mode = calloc(1, sizeof(DisplayModeRec));
-		if (Mode)
-			Modes = xf86ModesAdd(Modes,
-					     mode_from_kmode(output->scrn,
-							     &sna_output->modes[i],
-							     Mode));
+		if (Mode) {
+			Mode = mode_from_kmode(output->scrn,
+					       &sna_output->modes[i],
+					       Mode);
+
+			if (!has_current && xf86ModesEqual(Mode, &current))
+				has_current = true;
+
+			Modes = xf86ModesAdd(Modes, Mode);
+		}
 	}
 
 	/*
@@ -2081,6 +2106,19 @@ sna_output_get_modes(xf86OutputPtr output)
 		Modes = sna_output_panel_edid(output, Modes);
 	}
 
+	if (!has_current && current.Clock) {
+		DisplayModePtr Mode;
+
+		Mode = calloc(1, sizeof(DisplayModeRec));
+		if (Mode) {
+			*Mode = current;
+			Mode->name = strdup(Mode->name);
+			output->probed_modes =
+				xf86ModesAdd(output->probed_modes, Mode);
+		}
+	}
+	free(current.name);
+
 	return Modes;
 }
 


More information about the xorg-commit mailing list