[Intel-gfx] [PATCH] drm/i915: Hook the force-restore into the highlevel modeset

Chris Wilson chris at chris-wilson.co.uk
Fri Jun 7 14:47:41 CEST 2013


On random machines, the BIOS changes the hardware state of the display
when it detects a lid event. In return, we have to then do a forced
restore of the users requested configuration as soon as we handle the
lid event. Currently, this is done by calling the lowlevel CRTC
configuration functions directly with the old state. This results in
a flash on all connected displays. However, since we probe the state of
the hardware left by the BIOS, we can instead hook into the higher level
modeset code which evaluates the minimum changes required to setup the
requested state. This converts the modeset back into a no-op on sane
machines, and eliminates the screen blanking.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=65486
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/intel_display.c |   26 ++++++++++++++++++++++++--
 drivers/gpu/drm/i915/intel_drv.h     |    5 +++++
 2 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index ba7e311..5b727a3b2 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -9632,11 +9632,33 @@ void intel_modeset_setup_hw_state(struct drm_device *dev,
 		 * checking (bogus) intermediate states.
 		 */
 		for_each_pipe(pipe) {
+			struct drm_mode_set set;
+			struct drm_connector *connector, *connectors[16];
 			struct drm_crtc *crtc =
 				dev_priv->pipe_to_crtc_mapping[pipe];
 
-			__intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y,
-					 crtc->fb);
+			set.crtc = crtc;
+			set.x = crtc->x;
+			set.y = crtc->y;
+			set.mode = crtc->fb ? &crtc->mode : NULL;
+			set.fb = crtc->fb;
+			set.connectors = connectors;
+			set.num_connectors = 0;
+
+			list_for_each_entry(connector,
+					    &dev->mode_config.connector_list,
+					    head) {
+				if (&intel_attached_crtc(connector)->base != crtc)
+					continue;
+
+				connectors[set.num_connectors++] = connector;
+				if (set.num_connectors == ARRAY_SIZE(connectors))
+					break;
+			}
+
+			if (intel_crtc_set_config(&set))
+				__intel_set_mode(crtc, &crtc->mode,
+						 crtc->x, crtc->y, crtc->fb);
 		}
 		list_for_each_entry(plane, &dev->mode_config.plane_list, head)
 			intel_plane_restore(plane);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 1f04b7f..ef3f809 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -648,6 +648,11 @@ static inline struct intel_encoder *intel_attached_encoder(struct drm_connector
 	return to_intel_connector(connector)->encoder;
 }
 
+static inline struct intel_crtc *intel_attached_crtc(struct drm_connector *connector)
+{
+	return to_intel_crtc(to_intel_connector(connector)->encoder->base.crtc);
+}
+
 static inline struct intel_digital_port *
 enc_to_dig_port(struct drm_encoder *encoder)
 {
-- 
1.7.10.4




More information about the Intel-gfx mailing list