diff mbox

[41/81] drm/i915: Add primary plane disable logic to atomic mode setting code

Message ID 1355329008-31459-42-git-send-email-ville.syrjala@linux.intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Ville Syrjälä Dec. 12, 2012, 4:16 p.m. UTC
From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Enable/disable the primary plane accordingly when the sprite plane
coverage changes.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_atomic.c |   41 +++++++++++++++++++++++++++++++++++
 1 files changed, 41 insertions(+), 0 deletions(-)
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
index 238a843..41885fa 100644
--- a/drivers/gpu/drm/i915/intel_atomic.c
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -93,6 +93,7 @@  struct intel_crtc_state {
 	bool changed;
 	struct drm_pending_atomic_event *event;
 	struct intel_flip *flip;
+	bool primary_disabled;
 
 	struct {
 		bool enabled;
@@ -318,6 +319,8 @@  static void *intel_atomic_begin(struct drm_device *dev, struct drm_file *file,
 
 		s->old.connectors_bitmask = s->connectors_bitmask;
 		s->old.encoders_bitmask = s->encoders_bitmask;
+
+		s->primary_disabled = intel_crtc->primary_disabled;
 	}
 
 	i = 0;
@@ -1157,6 +1160,9 @@  static int apply_config(struct drm_device *dev,
 						 intel_crtc->cursor_addr);
 		}
 
+		if (!st->primary_disabled)
+			intel_enable_primary(crtc);
+
 		for (j = 0; j < dev->mode_config.num_plane; j++) {
 			struct intel_plane_state *pst = &s->plane[j];
 			struct drm_plane *plane = pst->plane;
@@ -1170,6 +1176,9 @@  static int apply_config(struct drm_device *dev,
 			else if (!pst->coords.visible && pst->old.crtc == crtc)
 				intel_plane->disable_plane(plane);
 		}
+
+		if (st->primary_disabled)
+			intel_disable_primary(crtc);
 	}
 
 	/* don't restore the old state in end() */
@@ -1207,6 +1216,7 @@  static void restore_state(struct drm_device *dev,
 		intel_crtc->cursor_width = s->saved_crtcs[i].cursor_width;
 		intel_crtc->cursor_height = s->saved_crtcs[i].cursor_height;
 		intel_crtc->cursor_visible = s->saved_crtcs[i].cursor_visible;
+		intel_crtc->primary_disabled = s->saved_crtcs[i].primary_disabled;
 
 		i++;
 	}
@@ -1346,6 +1356,28 @@  static int check_crtc(struct intel_crtc_state *s)
 	return 0;
 }
 
+static void update_primary_visibility(struct drm_device *dev,
+				      struct intel_atomic_state *s,
+				      const struct drm_crtc *crtc,
+				      const struct drm_plane *plane,
+				      const struct intel_plane_coords *coords)
+{
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	bool primary_disabled =
+		coords->visible &&
+		coords->crtc_x == 0 &&
+		coords->crtc_y == 0 &&
+		coords->crtc_w == crtc->mode.hdisplay &&
+		coords->crtc_h == crtc->mode.vdisplay;
+
+	if (primary_disabled != intel_crtc->primary_disabled) {
+		struct intel_crtc_state *st = get_crtc_state(dev, s, crtc);
+		st->fb_dirty = true;
+		st->primary_disabled = primary_disabled;
+		s->dirty = true;
+	}
+}
+
 static int intel_atomic_check(struct drm_device *dev, void *state)
 {
 	struct intel_atomic_state *s = state;
@@ -1430,6 +1462,12 @@  static int intel_atomic_check(struct drm_device *dev, void *state)
 		ret = intel_check_plane(plane, plane->crtc, plane->fb, &st->coords);
 		if (ret)
 			return ret;
+
+		/* FIXME doesn't correctly handle cases where plane moves between crtcs */
+		if (plane->crtc)
+			update_primary_visibility(dev, s, plane->crtc, plane, &st->coords);
+		else if (st->old.crtc)
+			update_primary_visibility(dev, s, st->old.crtc, plane, &st->coords);
 	}
 
 	return 0;
@@ -2295,6 +2333,9 @@  static void atomic_pipe_commit(struct drm_device *dev,
 
 		intel_flip->crtc = crtc;
 
+		/* update primary_disabled befoer calc_plane() */
+		intel_crtc->primary_disabled = st->primary_disabled;
+
 		/* should already be checked so can't fail */
 		/* FIXME refactor the failing parts? */
 		dev_priv->display.calc_plane(crtc, crtc->fb, crtc->x, crtc->y);