[PATCH 44/55] heh

Chris Wilson chris at chris-wilson.co.uk
Mon Sep 19 10:36:58 UTC 2016


---
 drivers/gpu/drm/drm_atomic.c             | 29 ++++++++++++++++++-----------
 drivers/gpu/drm/drm_atomic_helper.c      | 31 +++++++++++++------------------
 drivers/gpu/drm/drm_crtc.c               |  2 --
 drivers/gpu/drm/drm_plane_helper.c       |  8 ++++++--
 drivers/gpu/drm/i915/intel_display.c     | 22 +++++++++++++++-------
 drivers/gpu/drm/i915/intel_drv.h         |  4 +++-
 drivers/gpu/drm/i915/intel_sprite.c      | 10 +++++-----
 include/drm/drm_atomic_helper.h          |  3 ++-
 include/drm/drm_crtc.h                   | 16 +++++++---------
 include/drm/drm_modeset_helper_vtables.h |  2 ++
 10 files changed, 71 insertions(+), 56 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 5dd70540219c..4580d35dff62 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -158,6 +158,7 @@ void drm_atomic_state_default_clear(struct drm_atomic_state *state)
 
 	for (i = 0; i < config->num_crtc; i++) {
 		struct drm_crtc *crtc = state->crtcs[i].ptr;
+		struct drm_pending_vblank_event *event;
 
 		if (!crtc)
 			continue;
@@ -166,12 +167,16 @@ void drm_atomic_state_default_clear(struct drm_atomic_state *state)
 						  state->crtcs[i].state);
 
 		if (state->crtcs[i].commit) {
-			kfree(state->crtcs[i].commit->event);
-			state->crtcs[i].commit->event = NULL;
 			drm_crtc_commit_put(state->crtcs[i].commit);
+			state->crtcs[i].commit = NULL;
+		}
+
+		event = state->crtcs[i].event;
+		if (event) {
+			drm_event_cancel_free(dev, &event->base);
+			state->crtcs[i].event = NULL;
 		}
 
-		state->crtcs[i].commit = NULL;
 		state->crtcs[i].ptr = NULL;
 		state->crtcs[i].state = NULL;
 	}
@@ -541,7 +546,6 @@ drm_atomic_crtc_get_property(struct drm_crtc *crtc,
 
 /**
  * drm_atomic_crtc_check - check crtc state
- * @crtc: crtc to check
  * @state: crtc state to check
  *
  * Provides core sanity checks for crtc state.
@@ -549,9 +553,11 @@ drm_atomic_crtc_get_property(struct drm_crtc *crtc,
  * RETURNS:
  * Zero on success, error code on failure
  */
-static int drm_atomic_crtc_check(struct drm_crtc *crtc,
-		struct drm_crtc_state *state)
+static int drm_atomic_crtc_check(struct drm_crtc_state *state,
+				 struct drm_pending_vblank_event *event)
 {
+	struct drm_crtc *crtc = state->crtc;
+
 	/* NOTE: we explicitly don't enforce constraints such as primary
 	 * layer covering entire screen, since that is something we want
 	 * to allow (on hw that supports it).  For hw that does not, it
@@ -593,7 +599,7 @@ static int drm_atomic_crtc_check(struct drm_crtc *crtc,
 	 * and legacy page_flip IOCTL which also reject service on a disabled
 	 * pipe.
 	 */
-	if (state->event && !state->active && !crtc->state->active) {
+	if (event && !state->active && !crtc->state->active) {
 		DRM_DEBUG_ATOMIC("[CRTC:%d] requesting event but off\n",
 				 crtc->base.id);
 		return -EINVAL;
@@ -1368,7 +1374,7 @@ int drm_atomic_check_only(struct drm_atomic_state *state)
 	}
 
 	for_each_crtc_in_state(state, crtc, crtc_state, i) {
-		ret = drm_atomic_crtc_check(crtc, crtc_state);
+		ret = drm_atomic_crtc_check(crtc_state, state->crtcs[i].event);
 		if (ret) {
 			DRM_DEBUG_ATOMIC("[CRTC:%d:%s] atomic core check failed\n",
 					 crtc->base.id, crtc->name);
@@ -1731,7 +1737,7 @@ retry:
 				goto out;
 			}
 
-			crtc_state->event = e;
+			state->crtcs[i].event = e;
 		}
 	}
 
@@ -1758,10 +1764,11 @@ out:
 		 */
 
 		for_each_crtc_in_state(state, crtc, crtc_state, i) {
-			if (!crtc_state->event)
+			if (!state->crtcs[i].event)
 				continue;
 
-			drm_event_cancel_free(dev, &crtc_state->event->base);
+			drm_event_cancel_free(dev,
+					      &state->crtcs[i].event->base);
 		}
 	}
 
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index d1ec053d36d5..35a6f841c385 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -1467,16 +1467,15 @@ int drm_atomic_helper_setup_commit(struct drm_atomic_state *state,
 			continue;
 		}
 
-		if (!crtc_state->event) {
-			commit->event = kzalloc(sizeof(*commit->event),
-						GFP_KERNEL);
-			if (!commit->event)
+		if (!state->crtcs[i].event) {
+			state->crtcs[i].event =
+				kzalloc(sizeof(*state->crtcs[i].event),
+					GFP_KERNEL);
+			if (!state->crtcs[i].event) 
 				return -ENOMEM;
-
-			crtc_state->event = commit->event;
 		}
 
-		crtc_state->event->base.completion = &commit->flip_done;
+		state->crtcs[i].event->base.completion = &commit->flip_done;
 	}
 
 	return 0;
@@ -1577,7 +1576,6 @@ void drm_atomic_helper_commit_hw_done(struct drm_atomic_state *state)
 			continue;
 
 		/* backend must have consumed any event by now */
-		WARN_ON(crtc->state->event);
 		spin_lock(&crtc->commit_lock);
 		complete_all(&commit->hw_done);
 		spin_unlock(&crtc->commit_lock);
@@ -1763,7 +1761,7 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev,
 		if (active_only && !crtc->state->active)
 			continue;
 
-		funcs->atomic_begin(crtc, old_crtc_state);
+		funcs->atomic_begin(crtc, old_state, old_crtc_state);
 	}
 
 	for_each_plane_in_state(old_state, plane, old_plane_state, i) {
@@ -1820,7 +1818,7 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev,
 		if (active_only && !crtc->state->active)
 			continue;
 
-		funcs->atomic_flush(crtc, old_crtc_state);
+		funcs->atomic_flush(crtc, old_state, old_crtc_state);
 	}
 }
 EXPORT_SYMBOL(drm_atomic_helper_commit_planes);
@@ -1856,7 +1854,7 @@ drm_atomic_helper_commit_planes_on_crtc(struct drm_crtc_state *old_crtc_state)
 
 	crtc_funcs = crtc->helper_private;
 	if (crtc_funcs && crtc_funcs->atomic_begin)
-		crtc_funcs->atomic_begin(crtc, old_crtc_state);
+		crtc_funcs->atomic_begin(crtc, old_state, old_crtc_state);
 
 	drm_for_each_plane_mask(plane, crtc->dev, plane_mask) {
 		struct drm_plane_state *old_plane_state =
@@ -1879,7 +1877,7 @@ drm_atomic_helper_commit_planes_on_crtc(struct drm_crtc_state *old_crtc_state)
 	}
 
 	if (crtc_funcs && crtc_funcs->atomic_flush)
-		crtc_funcs->atomic_flush(crtc, old_crtc_state);
+		crtc_funcs->atomic_flush(crtc, old_state, old_crtc_state);
 }
 EXPORT_SYMBOL(drm_atomic_helper_commit_planes_on_crtc);
 
@@ -1909,7 +1907,7 @@ drm_atomic_helper_disable_planes_on_crtc(struct drm_crtc_state *old_crtc_state,
 	struct drm_plane *plane;
 
 	if (atomic && crtc_funcs && crtc_funcs->atomic_begin)
-		crtc_funcs->atomic_begin(crtc, NULL);
+		crtc_funcs->atomic_begin(crtc, NULL, NULL);
 
 	drm_atomic_crtc_state_for_each_plane(plane, old_crtc_state) {
 		const struct drm_plane_helper_funcs *plane_funcs =
@@ -1924,7 +1922,7 @@ drm_atomic_helper_disable_planes_on_crtc(struct drm_crtc_state *old_crtc_state,
 	}
 
 	if (atomic && crtc_funcs && crtc_funcs->atomic_flush)
-		crtc_funcs->atomic_flush(crtc, NULL);
+		crtc_funcs->atomic_flush(crtc, NULL, NULL);
 }
 EXPORT_SYMBOL(drm_atomic_helper_disable_planes_on_crtc);
 
@@ -2041,8 +2039,6 @@ void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
 			list_add(&state->crtcs[i].commit->commit_entry,
 				 &crtc->commit_list);
 			spin_unlock(&crtc->commit_lock);
-
-			state->crtcs[i].commit->event = NULL;
 		}
 	}
 
@@ -2772,7 +2768,7 @@ retry:
 		ret = PTR_ERR(crtc_state);
 		goto fail;
 	}
-	crtc_state->event = event;
+	state->crtcs[drm_crtc_index(crtc)].event = event;
 
 	plane_state = drm_atomic_get_plane_state(state, plane);
 	if (IS_ERR(plane_state)) {
@@ -2978,7 +2974,6 @@ void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc,
 	state->connectors_changed = false;
 	state->color_mgmt_changed = false;
 	state->zpos_changed = false;
-	state->event = NULL;
 }
 EXPORT_SYMBOL(__drm_atomic_helper_crtc_duplicate_state);
 
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index d84a0ead8100..4af6a7525587 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -2036,8 +2036,6 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
 	else
 		ret = crtc->funcs->page_flip(crtc, fb, e, page_flip->flags);
 	if (ret) {
-		if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT)
-			drm_event_cancel_free(dev, &e->base);
 		/* Keep the old fb, don't unref it. */
 		crtc->primary->old_fb = NULL;
 	} else {
diff --git a/drivers/gpu/drm/drm_plane_helper.c b/drivers/gpu/drm/drm_plane_helper.c
index 7899fc1dcdb0..64d8622dc50a 100644
--- a/drivers/gpu/drm/drm_plane_helper.c
+++ b/drivers/gpu/drm/drm_plane_helper.c
@@ -465,7 +465,9 @@ int drm_plane_helper_commit(struct drm_plane *plane,
 
 	for (i = 0; i < 2; i++) {
 		if (crtc_funcs[i] && crtc_funcs[i]->atomic_begin)
-			crtc_funcs[i]->atomic_begin(crtc[i], crtc[i]->state);
+			crtc_funcs[i]->atomic_begin(crtc[i],
+						    plane_state->state,
+						    crtc[i]->state);
 	}
 
 	/*
@@ -480,7 +482,9 @@ int drm_plane_helper_commit(struct drm_plane *plane,
 
 	for (i = 0; i < 2; i++) {
 		if (crtc_funcs[i] && crtc_funcs[i]->atomic_flush)
-			crtc_funcs[i]->atomic_flush(crtc[i], crtc[i]->state);
+			crtc_funcs[i]->atomic_flush(crtc[i],
+						    plane_state->state,
+						    crtc[i]->state);
 	}
 
 	/*
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 569e29251602..cce01b419afb 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -113,8 +113,12 @@ static void vlv_prepare_pll(struct intel_crtc *crtc,
 			    const struct intel_crtc_state *pipe_config);
 static void chv_prepare_pll(struct intel_crtc *crtc,
 			    const struct intel_crtc_state *pipe_config);
-static void intel_begin_crtc_commit(struct drm_crtc *, struct drm_crtc_state *);
-static void intel_finish_crtc_commit(struct drm_crtc *, struct drm_crtc_state *);
+static void intel_begin_crtc_commit(struct drm_crtc *,
+				    struct drm_atomic_state *,
+				    struct drm_crtc_state *);
+static void intel_finish_crtc_commit(struct drm_crtc *,
+				     struct drm_atomic_state *,
+				     struct drm_crtc_state *);
 static void skl_init_scalers(struct drm_device *dev, struct intel_crtc *intel_crtc,
 	struct intel_crtc_state *crtc_state);
 static void skylake_pfit_enable(struct intel_crtc *crtc);
@@ -12023,7 +12027,7 @@ static void intel_mmio_flip_work_func(struct work_struct *w)
 		/* use_mmio_flip() retricts MMIO flips to ilk+ */
 		ilk_do_mmio_flip(crtc, work);
 
-	intel_pipe_update_end(crtc, work);
+	intel_pipe_update_end(crtc, work, NULL);
 }
 
 static int intel_default_queue_flip(struct drm_device *dev,
@@ -14465,12 +14469,12 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state)
 		bool modeset = needs_modeset(crtc->state);
 
 		/* Complete events for now disable pipes here. */
-		if (modeset && !crtc->state->active && crtc->state->event) {
+		if (modeset && !crtc->state->active && state->crtcs[i].event) {
 			spin_lock_irq(&dev->event_lock);
-			drm_crtc_send_vblank_event(crtc, crtc->state->event);
+			drm_crtc_send_vblank_event(crtc, state->crtcs[i].event);
 			spin_unlock_irq(&dev->event_lock);
 
-			crtc->state->event = NULL;
+			state->crtcs[i].event = NULL;
 		}
 	}
 
@@ -14801,6 +14805,7 @@ intel_check_primary_plane(struct drm_plane *plane,
 }
 
 static void intel_begin_crtc_commit(struct drm_crtc *crtc,
+				    struct drm_atomic_state *state,
 				    struct drm_crtc_state *old_crtc_state)
 {
 	struct drm_device *dev = crtc->dev;
@@ -14833,11 +14838,14 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc,
 }
 
 static void intel_finish_crtc_commit(struct drm_crtc *crtc,
+				     struct drm_atomic_state *state,
 				     struct drm_crtc_state *old_crtc_state)
 {
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct drm_pending_vblank_event *event;
 
-	intel_pipe_update_end(intel_crtc, NULL);
+	event = fetch_and_zero(&state->crtcs[drm_crtc_index(crtc)].event);
+	intel_pipe_update_end(intel_crtc, NULL, event);
 }
 
 /**
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index ebb2e7d4afa7..d9599f960e2d 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1778,7 +1778,9 @@ int intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane);
 int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
 			      struct drm_file *file_priv);
 void intel_pipe_update_start(struct intel_crtc *crtc);
-void intel_pipe_update_end(struct intel_crtc *crtc, struct intel_flip_work *work);
+void intel_pipe_update_end(struct intel_crtc *crtc,
+			   struct intel_flip_work *work,
+			   struct drm_pending_vblank_event *event);
 
 /* intel_tv.c */
 void intel_tv_init(struct drm_device *dev);
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index e1297da47a2c..44da0287c260 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -152,7 +152,9 @@ void intel_pipe_update_start(struct intel_crtc *crtc)
  * re-enables interrupts and verifies the update was actually completed
  * before a vblank using the value of @start_vbl_count.
  */
-void intel_pipe_update_end(struct intel_crtc *crtc, struct intel_flip_work *work)
+void intel_pipe_update_end(struct intel_crtc *crtc,
+			   struct intel_flip_work *work,
+			   struct drm_pending_vblank_event *event)
 {
 	enum pipe pipe = crtc->pipe;
 	int scanline_end = intel_get_crtc_scanline(crtc);
@@ -171,14 +173,12 @@ void intel_pipe_update_end(struct intel_crtc *crtc, struct intel_flip_work *work
 	 * Would be slightly nice to just grab the vblank count and arm the
 	 * event outside of the critical section - the spinlock might spin for a
 	 * while ... */
-	if (crtc->base.state->event) {
+	if (event) {
 		WARN_ON(drm_crtc_vblank_get(&crtc->base) != 0);
 
 		spin_lock(&crtc->base.dev->event_lock);
-		drm_crtc_arm_vblank_event(&crtc->base, crtc->base.state->event);
+		drm_crtc_arm_vblank_event(&crtc->base, event);
 		spin_unlock(&crtc->base.dev->event_lock);
-
-		crtc->base.state->event = NULL;
 	}
 
 	local_irq_enable();
diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
index 7ff92b09fd9c..902130bed541 100644
--- a/include/drm/drm_atomic_helper.h
+++ b/include/drm/drm_atomic_helper.h
@@ -75,7 +75,8 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev,
 				     uint32_t flags);
 void drm_atomic_helper_cleanup_planes(struct drm_device *dev,
 				      struct drm_atomic_state *old_state);
-void drm_atomic_helper_commit_planes_on_crtc(struct drm_crtc_state *old_crtc_state);
+void 
+drm_atomic_helper_commit_planes_on_crtc(struct drm_crtc_state *old_crtc_state);
 void
 drm_atomic_helper_disable_planes_on_crtc(struct drm_crtc_state *old_crtc_state,
 					 bool atomic);
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index b6e1853d2355..9ed4c5dadc74 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -169,8 +169,6 @@ struct drm_crtc_state {
 	struct drm_property_blob *ctm;
 	struct drm_property_blob *gamma_lut;
 
-	struct drm_pending_vblank_event *event;
-
 	struct drm_atomic_state *state;
 };
 
@@ -1282,13 +1280,6 @@ struct drm_crtc_commit {
 	 * Entry on the per-CRTC commit_list. Protected by crtc->commit_lock.
 	 */
 	struct list_head commit_entry;
-
-	/**
-	 * @event:
-	 *
-	 * &drm_pending_vblank_event pointer to clean up private events.
-	 */
-	struct drm_pending_vblank_event *event;
 };
 
 struct __drm_planes_state {
@@ -1300,6 +1291,13 @@ struct __drm_crtcs_state {
 	struct drm_crtc *ptr;
 	struct drm_crtc_state *state;
 	struct drm_crtc_commit *commit;
+
+	/**
+	 * @event:
+	 *
+	 * &drm_pending_vblank_event pointer to clean up private events.
+	 */
+	struct drm_pending_vblank_event *event;
 };
 
 struct __drm_connnectors_state {
diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h
index 10e449c86dbd..01923a672059 100644
--- a/include/drm/drm_modeset_helper_vtables.h
+++ b/include/drm/drm_modeset_helper_vtables.h
@@ -368,6 +368,7 @@ struct drm_crtc_helper_funcs {
 	 * transitional plane helpers, but it is optional.
 	 */
 	void (*atomic_begin)(struct drm_crtc *crtc,
+			     struct drm_atomic_state *state,
 			     struct drm_crtc_state *old_crtc_state);
 	/**
 	 * @atomic_flush:
@@ -392,6 +393,7 @@ struct drm_crtc_helper_funcs {
 	 * transitional plane helpers, but it is optional.
 	 */
 	void (*atomic_flush)(struct drm_crtc *crtc,
+			     struct drm_atomic_state *state,
 			     struct drm_crtc_state *old_crtc_state);
 
 	/**
-- 
2.9.3



More information about the Intel-gfx-trybot mailing list