diff mbox

[RFC] drm/i915: support zero flicker boot

Message ID 20091022154241.446fb048@jbarnes-x200 (mailing list archive)
State Deferred, archived
Headers show

Commit Message

Jesse Barnes Oct. 22, 2009, 6:42 a.m. UTC
None
diff mbox

Patch

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);