[PATCH 25/49] heh

Chris Wilson chris at chris-wilson.co.uk
Fri Nov 11 20:39:54 UTC 2016


---
 drivers/gpu/drm/drm_atomic.c             | 29 +++++++++++++---------
 drivers/gpu/drm/drm_atomic_helper.c      | 31 ++++++++++-------------
 drivers/gpu/drm/drm_plane.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 ++++----
 drivers/gpu/drm/nouveau/nv50_display.c   |  8 +++---
 include/drm/drm_atomic.h                 | 42 ++++++++++++++++++++++++++++++++
 include/drm/drm_atomic_helper.h          |  3 ++-
 include/drm/drm_crtc.h                   | 42 --------------------------------
 include/drm/drm_modeset_helper_vtables.h |  2 ++
 12 files changed, 110 insertions(+), 93 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index f5ea7db4a48a..b2086cf5a46f 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -159,6 +159,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;
@@ -167,12 +168,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;
 	}
@@ -545,7 +550,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.
@@ -553,9 +557,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
@@ -597,7 +603,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;
@@ -1470,7 +1476,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);
@@ -1919,7 +1925,7 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,
 				goto out;
 			}
 
-			crtc_state->event = e;
+			state->crtcs[i].event = e;
 		}
 	}
 
@@ -1949,10 +1955,11 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,
 		 */
 
 		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 50077961228a..6c014d43f814 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -1464,16 +1464,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;
@@ -1574,7 +1573,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);
@@ -1760,7 +1758,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) {
@@ -1817,7 +1815,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);
@@ -1853,7 +1851,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 =
@@ -1876,7 +1874,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);
 
@@ -1906,7 +1904,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 =
@@ -1921,7 +1919,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);
 
@@ -2038,8 +2036,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;
 		}
 	}
 
@@ -2769,7 +2765,7 @@ int drm_atomic_helper_page_flip(struct drm_crtc *crtc,
 		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)) {
@@ -2975,7 +2971,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_plane.c b/drivers/gpu/drm/drm_plane.c
index 249c0ae52c6d..6b81a1b3967e 100644
--- a/drivers/gpu/drm/drm_plane.c
+++ b/drivers/gpu/drm/drm_plane.c
@@ -882,8 +882,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 7a7dddf604d7..143883f0844f 100644
--- a/drivers/gpu/drm/drm_plane_helper.c
+++ b/drivers/gpu/drm/drm_plane_helper.c
@@ -458,7 +458,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);
 	}
 
 	/*
@@ -473,7 +475,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 edadf8553c6a..71486e59fe27 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -112,11 +112,15 @@ 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 skl_init_scalers(struct drm_i915_private *dev_priv,
 			     struct intel_crtc *crtc,
 			     struct intel_crtc_state *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 skylake_pfit_enable(struct intel_crtc *crtc);
 static void ironlake_pfit_disable(struct intel_crtc *crtc, bool force);
 static void ironlake_pfit_enable(struct intel_crtc *crtc);
@@ -12039,7 +12043,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,
@@ -14568,12 +14572,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;
 		}
 	}
 
@@ -14910,6 +14914,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;
@@ -14944,11 +14949,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 bb96aef00824..431b7adafa5d 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1775,7 +1775,9 @@ struct intel_plane *intel_sprite_plane_create(struct drm_i915_private *dev_priv,
 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 59d1ad154173..1a483e5c0b33 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/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index a9855a4ec532..832cdbe3c9e8 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -2240,7 +2240,7 @@ nv50_head_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
 		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)) {
@@ -4085,12 +4085,12 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
 	}
 
 	for_each_crtc_in_state(state, crtc, crtc_state, i) {
-		if (crtc->state->event) {
+		if (state->crtcs[i].event) {
 			unsigned long flags;
 			spin_lock_irqsave(&crtc->dev->event_lock, flags);
-			drm_crtc_send_vblank_event(crtc, crtc->state->event);
+			drm_crtc_send_vblank_event(crtc, state->crtcs[i].event);
 			spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
-			crtc->state->event = NULL;
+			state->crtcs[i].event = NULL;
 		}
 	}
 
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index 331bb100b718..17aebddb8406 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -144,6 +144,48 @@ struct __drm_crtcs_state {
 	struct drm_crtc *ptr;
 	struct drm_crtc_state *state;
 	struct drm_crtc_commit *commit;
+
+	/**
+	 * @event:
+	 *
+	 * Optional pointer to a DRM event to signal upon completion of the
+	 * state update. The driver must send out the event when the atomic
+	 * commit operation completes. There are two cases:
+	 *
+	 *  - The event is for a CRTC which is being disabled through this
+	 *    atomic commit. In that case the event can be send out any time
+	 *    after the hardware has stopped scanning out the current
+	 *    framebuffers. It should contain the timestamp and counter for the
+	 *    last vblank before the display pipeline was shut off.
+	 *
+	 *  - For a CRTC which is enabled at the end of the commit (even when it
+	 *    undergoes an full modeset) the vblank timestamp and counter must
+	 *    be for the vblank right before the first frame that scans out the
+	 *    new set of buffers. Again the event can only be sent out after the
+	 *    hardware has stopped scanning out the old buffers.
+	 *
+	 *  - Events for disabled CRTCs are not allowed, and drivers can ignore
+	 *    that case.
+	 *
+	 * This can be handled by the drm_crtc_send_vblank_event() function,
+	 * which the driver should call on the provided event upon completion of
+	 * the atomic commit. Note that if the driver supports vblank signalling
+	 * and timestamping the vblank counters and timestamps must agree with
+	 * the ones returned from page flip events. With the current vblank
+	 * helper infrastructure this can be achieved by holding a vblank
+	 * reference while the page flip is pending, acquired through
+	 * drm_crtc_vblank_get() and released with drm_crtc_vblank_put().
+	 * Drivers are free to implement their own vblank counter and timestamp
+	 * tracking though, e.g. if they have accurate timestamp registers in
+	 * hardware.
+	 *
+	 * For hardware which supports some means to synchronize vblank
+	 * interrupt delivery with committing display state there's also
+	 * drm_crtc_arm_vblank_event(). See the documentation of that function
+	 * for a detailed discussion of the constraints it needs to be used
+	 * safely.
+	 */
+	struct drm_pending_vblank_event *event;
 };
 
 struct __drm_connnectors_state {
diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
index 7ff92b09fd9c..4f8d10921eee 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 8cca2a895981..3a436959b56e 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -164,48 +164,6 @@ struct drm_crtc_state {
 	struct drm_property_blob *ctm;
 	struct drm_property_blob *gamma_lut;
 
-	/**
-	 * @event:
-	 *
-	 * Optional pointer to a DRM event to signal upon completion of the
-	 * state update. The driver must send out the event when the atomic
-	 * commit operation completes. There are two cases:
-	 *
-	 *  - The event is for a CRTC which is being disabled through this
-	 *    atomic commit. In that case the event can be send out any time
-	 *    after the hardware has stopped scanning out the current
-	 *    framebuffers. It should contain the timestamp and counter for the
-	 *    last vblank before the display pipeline was shut off.
-	 *
-	 *  - For a CRTC which is enabled at the end of the commit (even when it
-	 *    undergoes an full modeset) the vblank timestamp and counter must
-	 *    be for the vblank right before the first frame that scans out the
-	 *    new set of buffers. Again the event can only be sent out after the
-	 *    hardware has stopped scanning out the old buffers.
-	 *
-	 *  - Events for disabled CRTCs are not allowed, and drivers can ignore
-	 *    that case.
-	 *
-	 * This can be handled by the drm_crtc_send_vblank_event() function,
-	 * which the driver should call on the provided event upon completion of
-	 * the atomic commit. Note that if the driver supports vblank signalling
-	 * and timestamping the vblank counters and timestamps must agree with
-	 * the ones returned from page flip events. With the current vblank
-	 * helper infrastructure this can be achieved by holding a vblank
-	 * reference while the page flip is pending, acquired through
-	 * drm_crtc_vblank_get() and released with drm_crtc_vblank_put().
-	 * Drivers are free to implement their own vblank counter and timestamp
-	 * tracking though, e.g. if they have accurate timestamp registers in
-	 * hardware.
-	 *
-	 * For hardware which supports some means to synchronize vblank
-	 * interrupt delivery with committing display state there's also
-	 * drm_crtc_arm_vblank_event(). See the documentation of that function
-	 * for a detailed discussion of the constraints it needs to be used
-	 * safely.
-	 */
-	struct drm_pending_vblank_event *event;
-
 	struct drm_atomic_state *state;
 };
 
diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h
index 72478cf82147..c7ccc2c607ef 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.10.2



More information about the Intel-gfx-trybot mailing list