[PATCH 71/81] drm/i915: Eliminate swap_old_new() hack in the atomic code

ville.syrjala at linux.intel.com ville.syrjala at linux.intel.com
Wed Dec 12 08:16:38 PST 2012


From: Ville Syrjälä <ville.syrjala at linux.intel.com>

Use the new_crtc and new_encoder pointes inside the intel_encoder and
intel_connector structures instead of swapping the crtc and encoder
pointers in the drm base structures around the disable calls.

Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
---
 drivers/gpu/drm/i915/intel_atomic.c |  115 ++++++++++++++--------------------
 1 files changed, 47 insertions(+), 68 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
index 3717e89..3f093d6 100644
--- a/drivers/gpu/drm/i915/intel_atomic.c
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -115,43 +115,57 @@ struct intel_atomic_state {
 	struct drm_encoder *saved_encoders;
 };
 
-static void update_connectors_bitmask(struct drm_crtc *crtc,
+static void update_connectors_bitmask(struct intel_crtc *intel_crtc,
 				      unsigned long *connectors_bitmask)
 {
-	struct drm_device *dev = crtc->dev;
-	struct drm_connector *connector;
+	struct drm_device *dev = intel_crtc->base.dev;
+	struct intel_connector *intel_connector;
 	unsigned int i = 0;
 
 	*connectors_bitmask = 0;
 
-	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-		if (connector->encoder && connector->encoder->crtc == crtc)
+	list_for_each_entry(intel_connector, &dev->mode_config.connector_list, base.head) {
+		if (intel_connector->new_encoder &&
+		    intel_connector->new_encoder->new_crtc == intel_crtc)
 			__set_bit(i, connectors_bitmask);
 
 		i++;
 	}
 }
 
-static void update_encoders_bitmask(struct drm_crtc *crtc,
+static void update_encoders_bitmask(struct intel_crtc *intel_crtc,
 				    unsigned long *encoders_bitmask)
 {
-	struct drm_device *dev = crtc->dev;
-	struct drm_encoder *encoder;
+	struct drm_device *dev = intel_crtc->base.dev;
+	struct intel_encoder *intel_encoder;
 	unsigned int i = 0;
 
 	*encoders_bitmask = 0;
 
-	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
-		if (encoder->crtc == crtc)
+	list_for_each_entry(intel_encoder, &dev->mode_config.encoder_list, base.head) {
+		if (intel_encoder->new_crtc == intel_crtc)
 			__set_bit(i, encoders_bitmask);
 
 		i++;
 	}
 }
 
+static bool intel_encoder_in_use(struct intel_encoder *intel_encoder)
+{
+	struct drm_device *dev = intel_encoder->base.dev;
+	struct intel_connector *intel_connector;
+
+	list_for_each_entry(intel_connector, &dev->mode_config.connector_list, base.head)
+		if (intel_connector->new_encoder == intel_encoder)
+			return true;
+
+	return false;
+}
+
 static int process_connectors(struct intel_crtc_state *s, const uint32_t *ids, int count_ids)
 {
 	struct drm_crtc *crtc = s->crtc;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	struct drm_device *dev = crtc->dev;
 	struct drm_connector *connectors[count_ids];
 	struct drm_connector *connector;
@@ -184,6 +198,9 @@ static int process_connectors(struct intel_crtc_state *s, const uint32_t *ids, i
 	}
 
 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+		struct intel_connector *intel_connector = to_intel_connector(connector);
+		struct intel_encoder *intel_encoder;
+
 		for (i = 0; i < count_ids; i++) {
 			if (connector == connectors[i])
 				break;
@@ -192,25 +209,28 @@ static int process_connectors(struct intel_crtc_state *s, const uint32_t *ids, i
 		/* this connector isn't in the set */
 		if (i == count_ids) {
 			/* remove the link to the encoder if this crtc was set to drive it */
-			if (connector->encoder && connector->encoder->crtc == crtc)
-				connector->encoder = NULL;
+			if (intel_connector->new_encoder &&
+			    intel_connector->new_encoder->new_crtc == intel_crtc)
+				intel_connector->new_encoder = NULL;
 			continue;
 		}
 
-		encoder = intel_best_encoder(connector);
+		intel_encoder = to_intel_encoder(intel_best_encoder(connector));
 
-		connector->encoder = encoder;
-		encoder->crtc = crtc;
+		intel_connector->new_encoder = intel_encoder;
+		intel_encoder->new_crtc = intel_crtc;
 	}
 
 	/* prune dangling encoder->crtc links pointing to this crtc  */
 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
-		if (encoder->crtc == crtc && !drm_helper_encoder_in_use(encoder))
-			encoder->crtc = NULL;
+		struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
+
+		if (intel_encoder->new_crtc == intel_crtc && !intel_encoder_in_use(intel_encoder))
+			intel_encoder->new_crtc = NULL;
 	}
 
-	update_connectors_bitmask(s->crtc, &s->connectors_bitmask);
-	update_encoders_bitmask(s->crtc, &s->encoders_bitmask);
+	update_connectors_bitmask(intel_crtc, &s->connectors_bitmask);
+	update_encoders_bitmask(intel_crtc, &s->encoders_bitmask);
 
 	return 0;
 }
@@ -232,19 +252,6 @@ static size_t intel_atomic_state_size(const struct drm_device *dev)
 		num_plane * sizeof state->saved_planes[0];
 }
 
-
-static void populate_old(struct drm_device *dev)
-{
-	struct drm_encoder *encoder;
-	struct drm_connector *connector;
-
-	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
-		encoder->old_crtc = encoder->crtc;
-
-	list_for_each_entry(connector, &dev->mode_config.connector_list, head)
-		connector->old_encoder = connector->encoder;
-}
-
 static void *intel_atomic_begin(struct drm_device *dev, struct drm_file *file,
 				uint32_t flags, uint64_t user_data)
 {
@@ -275,8 +282,6 @@ static void *intel_atomic_begin(struct drm_device *dev, struct drm_file *file,
 	state->saved_crtcs = (struct intel_crtc *)(state->saved_encoders + num_encoder);
 	state->saved_planes = (struct drm_plane *)(state->saved_crtcs + num_crtc);
 
-	populate_old(dev);
-
 	i = 0;
 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 		struct intel_crtc_state *s = &state->crtc[i++];
@@ -297,8 +302,8 @@ static void *intel_atomic_begin(struct drm_device *dev, struct drm_file *file,
 		s->old.x = crtc->x;
 		s->old.y = crtc->y;
 
-		update_connectors_bitmask(crtc, &s->connectors_bitmask);
-		update_encoders_bitmask(crtc, &s->encoders_bitmask);
+		update_connectors_bitmask(intel_crtc, &s->connectors_bitmask);
+		update_encoders_bitmask(intel_crtc, &s->encoders_bitmask);
 
 		s->old.connectors_bitmask = s->connectors_bitmask;
 		s->old.encoders_bitmask = s->encoders_bitmask;
@@ -1045,39 +1050,11 @@ static void queue_remaining_events(struct drm_device *dev, struct intel_atomic_s
 	}
 }
 
-static void swap_old_new(struct drm_device *dev,
-			 struct intel_atomic_state *s)
-{
-	struct drm_encoder *encoder;
-	struct drm_connector *connector;
-	int i;
-
-	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
-		swap(encoder->crtc, encoder->old_crtc);
-
-	list_for_each_entry(connector, &dev->mode_config.connector_list, head)
-		swap(connector->encoder, connector->old_encoder);
-
-	for (i = 0; i < dev->mode_config.num_crtc; i++) {
-		struct intel_crtc_state *st = &s->crtc[i];
-		struct drm_crtc *crtc = st->crtc;
-
-		swap(crtc->enabled, st->old.enabled);
-	}
-}
-
 static int apply_config(struct drm_device *dev,
 			struct intel_atomic_state *s)
 {
 	int i, ret;
 
-	/*
-	 * FIXME
-`	 * Hackish way to make crtc_disable() see the current
-	 * state (actually just some select pieces of it).
-	 */
-	swap_old_new(dev, s);
-
 	for (i = 0; i < dev->mode_config.num_crtc; i++) {
 		struct intel_crtc_state *st = &s->crtc[i];
 
@@ -1097,8 +1074,7 @@ static int apply_config(struct drm_device *dev,
 		crtc_prepare(st, st->crtc);
 	}
 
-	/* Undo the hack above. */
-	swap_old_new(dev, s);
+	intel_modeset_commit_output_state(dev);
 
 	for (i = 0; i < dev->mode_config.num_crtc; i++) {
 		struct intel_crtc_state *st = &s->crtc[i];
@@ -1204,6 +1180,9 @@ static void restore_state(struct drm_device *dev,
 	list_for_each_entry(plane, &dev->mode_config.plane_list, head)
 		*plane = s->saved_planes[i++];
 
+	/* must restore the new_crtc and new_encoder pointers as well */
+	intel_modeset_update_staged_output_state(dev);
+
 	/* FIXME props etc. */
 
 	/* was the hardware state clobbered? */
@@ -1318,8 +1297,9 @@ static int check_crtc(struct intel_crtc_state *s)
 
 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
 		const struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
+		struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
 
-		if (encoder->crtc != crtc)
+		if (intel_encoder->new_crtc != intel_crtc)
 			continue;
 
 		if (!encoder_funcs->mode_fixup(encoder, &crtc->mode, &crtc->hwmode))
@@ -1693,7 +1673,6 @@ static int intel_atomic_commit(struct drm_device *dev, void *state)
 
 	update_props(dev, s);
 
-	intel_modeset_update_staged_output_state(dev);
 
 	return 0;
 }
-- 
1.7.8.6



More information about the dri-devel mailing list