[Intel-gfx] [RFC] drm/i915: support zero flicker boot

Jesse Barnes jbarnes at virtuousgeek.org
Thu Oct 22 08:42:41 CEST 2009


If the BIOS programs the native panel mode at boot and the boot loader
leaves it alone, we should be able to boot with zero flicker.  This
patch fixes up the "mode_switch" test in drm_crtc_helper's set_config
function and adds code to the i915 display init function to set the
current CRTC mode and enable flag.  If the eventual mode programmed
matches the current mode, we should have no need to turn the display
off and then on again.

Any thoughts?  Peter you may already have a similar bit of code for the
testing you've been doing?

Jesse

diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index fe86974..3c5abd8 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -753,9 +753,8 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
 	/* We should be able to check here if the fb has the same properties
 	 * and then just flip_or_move it */
 	if (set->crtc->fb != set->fb) {
-		/* If we have no fb then treat it as a full mode set */
-		if (set->crtc->fb == NULL) {
-			DRM_DEBUG_KMS("crtc has no fb, full mode set\n");
+		/* If the CRTC is off then treat it as a full mode set */
+		if (!set->crtc->enabled) {
 			mode_changed = true;
 		} else if (set->fb == NULL) {
 			mode_changed = true;
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 298d317..ed60508 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3573,11 +3573,15 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	int pipe = intel_crtc->pipe;
 	struct drm_display_mode *mode;
+	int pipeconf = I915_READ((pipe == 0) ? PIPEACONF : PIPEBCONF);
 	int htot = I915_READ((pipe == 0) ? HTOTAL_A : HTOTAL_B);
 	int hsync = I915_READ((pipe == 0) ? HSYNC_A : HSYNC_B);
 	int vtot = I915_READ((pipe == 0) ? VTOTAL_A : VTOTAL_B);
 	int vsync = I915_READ((pipe == 0) ? VSYNC_A : VSYNC_B);
 
+	if (!(pipeconf & PIPEACONF_ENABLE))
+		return NULL;
+
 	mode = kzalloc(sizeof(*mode), GFP_KERNEL);
 	if (!mode)
 		return NULL;
@@ -4310,6 +4314,29 @@ static void intel_init_display(struct drm_device *dev)
 	}
 }
 
+/**
+ * intel_get_current_modes - get current mode timings for each CRTC
+ * @dev: DRM device
+ *
+ * Setting each CRTC's mode field with the current values can help us avoid
+ * flicker in the case where the BIOS already put us in a native mode.
+ */
+static void intel_get_current_modes(struct drm_device *dev)
+{
+	struct drm_crtc *crtc;
+	struct drm_display_mode *mode;
+
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+		mode = intel_crtc_mode_get(dev, crtc);
+		if (!mode) {
+			crtc->enabled = false;
+			continue;
+		}
+		crtc->mode = *mode; /* copy the mode over */
+		kfree(mode);
+	}
+}
+
 void intel_modeset_init(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -4362,6 +4389,8 @@ void intel_modeset_init(struct drm_device *dev)
 
 	intel_init_clock_gating(dev);
 
+	intel_get_current_modes(dev);
+
 	INIT_WORK(&dev_priv->idle_work, intel_idle_update);
 	setup_timer(&dev_priv->idle_timer, intel_gpu_idle_timer,
 		    (unsigned long)dev);



More information about the Intel-gfx mailing list