From 6fda305e2f2f991b39d09e67d0b17c8c3d50f9a4 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 9 Oct 2013 15:59:42 +0100 Subject: 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 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=70132 Signed-off-by: Chris Wilson --- src/sna/sna_display.c | 50 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c index dddc6d7d..e893bcd7 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(¤t, 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, ¤t); + } + } + 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, ¤t)) + 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; } -- cgit v1.2.3