diff mbox

[v2,12/21] drm/i915: Remove cs based page flip support.

Message ID 1463490484-19540-13-git-send-email-maarten.lankhorst@linux.intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Maarten Lankhorst May 17, 2016, 1:07 p.m. UTC
With mmio flips now available on all platforms it's time to remove
support for cs flips.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c  |  19 +-
 drivers/gpu/drm/i915/i915_irq.c      | 120 ++---------
 drivers/gpu/drm/i915/intel_display.c | 392 +----------------------------------
 drivers/gpu/drm/i915/intel_drv.h     |   9 +-
 4 files changed, 33 insertions(+), 507 deletions(-)

Comments

Patrik Jakobsson May 18, 2016, 8:31 p.m. UTC | #1
On Tue, May 17, 2016 at 03:07:55PM +0200, Maarten Lankhorst wrote:
> With mmio flips now available on all platforms it's time to remove
> support for cs flips.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

Reviewed-by: Patrik Jakobsson <patrik.jakobsson@linux.intel.com>

> ---
>  drivers/gpu/drm/i915/i915_debugfs.c  |  19 +-
>  drivers/gpu/drm/i915/i915_irq.c      | 120 ++---------
>  drivers/gpu/drm/i915/intel_display.c | 392 +----------------------------------
>  drivers/gpu/drm/i915/intel_drv.h     |   9 +-
>  4 files changed, 33 insertions(+), 507 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> index 6bce4fd8aaf4..4c6b48dbd6e2 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -599,7 +599,6 @@ static void i915_dump_pageflip(struct seq_file *m,
>  {
>  	const char pipe = pipe_name(crtc->pipe);
>  	u32 pending;
> -	u32 addr;
>  	int i;
>  
>  	pending = atomic_read(&work->pending);
> @@ -611,7 +610,6 @@ static void i915_dump_pageflip(struct seq_file *m,
>  			   pipe, plane_name(crtc->plane));
>  	}
>  
> -
>  	for (i = 0; i < work->num_planes; i++) {
>  		struct intel_plane_state *old_plane_state = work->old_plane_state[i];
>  		struct drm_plane *plane = old_plane_state->base.plane;
> @@ -635,22 +633,9 @@ static void i915_dump_pageflip(struct seq_file *m,
>  			   i915_gem_request_completed(req, true));
>  	}
>  
> -	seq_printf(m, "Flip queued on frame %d, (was ready on frame %d), now %d\n",
> -		   work->flip_queued_vblank,
> -		   work->flip_ready_vblank,
> +	seq_printf(m, "Flip queued on frame %d, now %d\n",
> +		   pending ? work->flip_queued_vblank : -1,
>  		   intel_crtc_get_vblank_counter(crtc));
> -	seq_printf(m, "%d prepares\n", atomic_read(&work->pending));
> -
> -	if (INTEL_INFO(dev_priv)->gen >= 4)
> -		addr = I915_HI_DISPBASE(I915_READ(DSPSURF(crtc->plane)));
> -	else
> -		addr = I915_READ(DSPADDR(crtc->plane));
> -	seq_printf(m, "Current scanout address 0x%08x\n", addr);
> -
> -	if (work->flip_queued_req) {
> -		seq_printf(m, "New framebuffer address 0x%08lx\n", (long)work->gtt_offset);
> -		seq_printf(m, "MMIO update completed? %d\n",  addr == work->gtt_offset);
> -	}
>  }
>  
>  static int i915_gem_pageflip_info(struct seq_file *m, void *data)
> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> index 3242a37fb304..5513c4cb02e0 100644
> --- a/drivers/gpu/drm/i915/i915_irq.c
> +++ b/drivers/gpu/drm/i915/i915_irq.c
> @@ -136,6 +136,12 @@ static const u32 hpd_bxt[HPD_NUM_PINS] = {
>  	POSTING_READ(type##IIR); \
>  } while (0)
>  
> +static void
> +intel_finish_page_flip_cs(struct drm_i915_private *dev_priv, unsigned pipe)
> +{
> +	DRM_DEBUG_KMS("Finished page flip\n");
> +}
> +
>  /*
>   * We should clear IMR at preinstall/uninstall, and just check at postinstall.
>   */
> @@ -1631,16 +1637,11 @@ static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir)
>  	}
>  }
>  
> -static bool intel_pipe_handle_vblank(struct drm_i915_private *dev_priv,
> +static void intel_pipe_handle_vblank(struct drm_i915_private *dev_priv,
>  				     enum pipe pipe)
>  {
> -	bool ret;
> -
> -	ret = drm_handle_vblank(dev_priv->dev, pipe);
> -	if (ret)
> +	if (drm_handle_vblank(dev_priv->dev, pipe))
>  		intel_finish_page_flip_mmio(dev_priv, pipe);
> -
> -	return ret;
>  }
>  
>  static void valleyview_pipestat_irq_ack(struct drm_i915_private *dev_priv,
> @@ -1707,9 +1708,8 @@ static void valleyview_pipestat_irq_handler(struct drm_i915_private *dev_priv,
>  	enum pipe pipe;
>  
>  	for_each_pipe(dev_priv, pipe) {
> -		if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS &&
> -		    intel_pipe_handle_vblank(dev_priv, pipe))
> -			intel_check_page_flip(dev_priv, pipe);
> +		if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS)
> +			intel_pipe_handle_vblank(dev_priv, pipe);
>  
>  		if (pipe_stats[pipe] & PLANE_FLIP_DONE_INT_STATUS_VLV)
>  			intel_finish_page_flip_cs(dev_priv, pipe);
> @@ -2155,9 +2155,8 @@ static void ilk_display_irq_handler(struct drm_i915_private *dev_priv,
>  		DRM_ERROR("Poison interrupt\n");
>  
>  	for_each_pipe(dev_priv, pipe) {
> -		if (de_iir & DE_PIPE_VBLANK(pipe) &&
> -		    intel_pipe_handle_vblank(dev_priv, pipe))
> -			intel_check_page_flip(dev_priv, pipe);
> +		if (de_iir & DE_PIPE_VBLANK(pipe))
> +			intel_pipe_handle_vblank(dev_priv, pipe);
>  
>  		if (de_iir & DE_PIPE_FIFO_UNDERRUN(pipe))
>  			intel_cpu_fifo_underrun_irq_handler(dev_priv, pipe);
> @@ -2206,9 +2205,8 @@ static void ivb_display_irq_handler(struct drm_i915_private *dev_priv,
>  		intel_opregion_asle_intr(dev_priv);
>  
>  	for_each_pipe(dev_priv, pipe) {
> -		if (de_iir & (DE_PIPE_VBLANK_IVB(pipe)) &&
> -		    intel_pipe_handle_vblank(dev_priv, pipe))
> -			intel_check_page_flip(dev_priv, pipe);
> +		if (de_iir & (DE_PIPE_VBLANK_IVB(pipe)))
> +			intel_pipe_handle_vblank(dev_priv, pipe);
>  
>  		/* plane/pipes map 1:1 on ilk+ */
>  		if (de_iir & DE_PLANE_FLIP_DONE_IVB(pipe))
> @@ -2407,9 +2405,8 @@ gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl)
>  		ret = IRQ_HANDLED;
>  		I915_WRITE(GEN8_DE_PIPE_IIR(pipe), iir);
>  
> -		if (iir & GEN8_PIPE_VBLANK &&
> -		    intel_pipe_handle_vblank(dev_priv, pipe))
> -			intel_check_page_flip(dev_priv, pipe);
> +		if (iir & GEN8_PIPE_VBLANK)
> +			intel_pipe_handle_vblank(dev_priv, pipe);
>  
>  		flip_done = iir;
>  		if (INTEL_INFO(dev_priv)->gen >= 9)
> @@ -3973,37 +3970,6 @@ static int i8xx_irq_postinstall(struct drm_device *dev)
>  	return 0;
>  }
>  
> -/*
> - * Returns true when a page flip has completed.
> - */
> -static bool i8xx_handle_vblank(struct drm_i915_private *dev_priv,
> -			       int plane, int pipe, u32 iir)
> -{
> -	u16 flip_pending = DISPLAY_PLANE_FLIP_PENDING(plane);
> -
> -	if (!intel_pipe_handle_vblank(dev_priv, pipe))
> -		return false;
> -
> -	if ((iir & flip_pending) == 0)
> -		goto check_page_flip;
> -
> -	/* We detect FlipDone by looking for the change in PendingFlip from '1'
> -	 * to '0' on the following vblank, i.e. IIR has the Pendingflip
> -	 * asserted following the MI_DISPLAY_FLIP, but ISR is deasserted, hence
> -	 * the flip is completed (no longer pending). Since this doesn't raise
> -	 * an interrupt per se, we watch for the change at vblank.
> -	 */
> -	if (I915_READ16(ISR) & flip_pending)
> -		goto check_page_flip;
> -
> -	intel_finish_page_flip_cs(dev_priv, pipe);
> -	return true;
> -
> -check_page_flip:
> -	intel_check_page_flip(dev_priv, pipe);
> -	return false;
> -}
> -
>  static irqreturn_t i8xx_irq_handler(int irq, void *arg)
>  {
>  	struct drm_device *dev = arg;
> @@ -4056,13 +4022,8 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg)
>  			notify_ring(&dev_priv->engine[RCS]);
>  
>  		for_each_pipe(dev_priv, pipe) {
> -			int plane = pipe;
> -			if (HAS_FBC(dev_priv))
> -				plane = !plane;
> -
> -			if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS &&
> -			    i8xx_handle_vblank(dev_priv, plane, pipe, iir))
> -				flip_mask &= ~DISPLAY_PLANE_FLIP_PENDING(plane);
> +			if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS)
> +				intel_pipe_handle_vblank(dev_priv, pipe);
>  
>  			if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS)
>  				i9xx_pipe_crc_irq_handler(dev_priv, pipe);
> @@ -4162,37 +4123,6 @@ static int i915_irq_postinstall(struct drm_device *dev)
>  	return 0;
>  }
>  
> -/*
> - * Returns true when a page flip has completed.
> - */
> -static bool i915_handle_vblank(struct drm_i915_private *dev_priv,
> -			       int plane, int pipe, u32 iir)
> -{
> -	u32 flip_pending = DISPLAY_PLANE_FLIP_PENDING(plane);
> -
> -	if (!intel_pipe_handle_vblank(dev_priv, pipe))
> -		return false;
> -
> -	if ((iir & flip_pending) == 0)
> -		goto check_page_flip;
> -
> -	/* We detect FlipDone by looking for the change in PendingFlip from '1'
> -	 * to '0' on the following vblank, i.e. IIR has the Pendingflip
> -	 * asserted following the MI_DISPLAY_FLIP, but ISR is deasserted, hence
> -	 * the flip is completed (no longer pending). Since this doesn't raise
> -	 * an interrupt per se, we watch for the change at vblank.
> -	 */
> -	if (I915_READ(ISR) & flip_pending)
> -		goto check_page_flip;
> -
> -	intel_finish_page_flip_cs(dev_priv, pipe);
> -	return true;
> -
> -check_page_flip:
> -	intel_check_page_flip(dev_priv, pipe);
> -	return false;
> -}
> -
>  static irqreturn_t i915_irq_handler(int irq, void *arg)
>  {
>  	struct drm_device *dev = arg;
> @@ -4253,13 +4183,8 @@ static irqreturn_t i915_irq_handler(int irq, void *arg)
>  			notify_ring(&dev_priv->engine[RCS]);
>  
>  		for_each_pipe(dev_priv, pipe) {
> -			int plane = pipe;
> -			if (HAS_FBC(dev_priv))
> -				plane = !plane;
> -
> -			if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS &&
> -			    i915_handle_vblank(dev_priv, plane, pipe, iir))
> -				flip_mask &= ~DISPLAY_PLANE_FLIP_PENDING(plane);
> +			if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS)
> +				intel_pipe_handle_vblank(dev_priv, pipe);
>  
>  			if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS)
>  				blc_event = true;
> @@ -4487,9 +4412,8 @@ static irqreturn_t i965_irq_handler(int irq, void *arg)
>  			notify_ring(&dev_priv->engine[VCS]);
>  
>  		for_each_pipe(dev_priv, pipe) {
> -			if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS &&
> -			    i915_handle_vblank(dev_priv, pipe, pipe, iir))
> -				flip_mask &= ~DISPLAY_PLANE_FLIP_PENDING(pipe);
> +			if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS)
> +				intel_pipe_handle_vblank(dev_priv, pipe);
>  
>  			if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS)
>  				blc_event = true;
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index b8b12177f1f0..19a382445306 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -48,11 +48,6 @@
>  #include <linux/reservation.h>
>  #include <linux/dma-buf.h>
>  
> -static bool is_mmio_work(struct intel_flip_work *work)
> -{
> -	return !work->flip_queued_req;
> -}
> -
>  /* Primary plane formats for gen <= 3 */
>  static const uint32_t i8xx_primary_formats[] = {
>  	DRM_FORMAT_C8,
> @@ -3102,14 +3097,6 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb,
>  	return -ENODEV;
>  }
>  
> -static void intel_complete_page_flips(struct drm_i915_private *dev_priv)
> -{
> -	struct intel_crtc *crtc;
> -
> -	for_each_intel_crtc(dev_priv->dev, crtc)
> -		intel_finish_page_flip_cs(dev_priv, crtc->pipe);
> -}
> -
>  static void intel_update_primary_planes(struct drm_device *dev)
>  {
>  	struct drm_crtc *crtc;
> @@ -3150,13 +3137,6 @@ void intel_prepare_reset(struct drm_i915_private *dev_priv)
>  
>  void intel_finish_reset(struct drm_i915_private *dev_priv)
>  {
> -	/*
> -	 * Flips in the rings will be nuked by the reset,
> -	 * so complete all pending flips so that user space
> -	 * will get its events and not get stuck.
> -	 */
> -	intel_complete_page_flips(dev_priv);
> -
>  	/* no reset support for gen2 */
>  	if (IS_GEN2(dev_priv))
>  		return;
> @@ -3834,26 +3814,7 @@ static int intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc)
>  	if (ret < 0)
>  		return ret;
>  
> -	if (ret == 0) {
> -		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> -		struct intel_flip_work *work;
> -
> -		spin_lock_irq(&dev->event_lock);
> -
> -		/*
> -		 * If we're waiting for page flips, it's the first
> -		 * flip on the list that's stuck.
> -		 */
> -		work = list_first_entry_or_null(&intel_crtc->flip_work,
> -						struct intel_flip_work, head);
> -
> -		if (work && !is_mmio_work(work) &&
> -		    !work_busy(&work->unpin_work)) {
> -			WARN_ONCE(1, "Removing stuck page flip\n");
> -			page_flip_completed(intel_crtc, work);
> -		}
> -		spin_unlock_irq(&dev->event_lock);
> -	}
> +	WARN(ret == 0, "Stuck page flip\n");
>  
>  	return 0;
>  }
> @@ -10925,9 +10886,6 @@ static void intel_unpin_work_fn(struct work_struct *__work)
>  
>  	intel_crtc_destroy_state(crtc, &work->old_crtc_state->base);
>  
> -	if (work->flip_queued_req)
> -		i915_gem_request_unreference(work->flip_queued_req);
> -
>  	for (i = 0; i < work->num_planes; i++) {
>  		struct intel_plane_state *old_plane_state =
>  			work->old_plane_state[i];
> @@ -10959,75 +10917,6 @@ static void intel_unpin_work_fn(struct work_struct *__work)
>  	kfree(work);
>  }
>  
> -/* Is 'a' after or equal to 'b'? */
> -static bool g4x_flip_count_after_eq(u32 a, u32 b)
> -{
> -	return !((a - b) & 0x80000000);
> -}
> -
> -static bool __pageflip_finished_cs(struct intel_crtc *crtc,
> -				   struct intel_flip_work *work)
> -{
> -	struct drm_device *dev = crtc->base.dev;
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> -	unsigned reset_counter;
> -
> -	reset_counter = i915_reset_counter(&dev_priv->gpu_error);
> -	if (crtc->reset_counter != reset_counter)
> -		return true;
> -
> -	/*
> -	 * The relevant registers doen't exist on pre-ctg.
> -	 * As the flip done interrupt doesn't trigger for mmio
> -	 * flips on gmch platforms, a flip count check isn't
> -	 * really needed there. But since ctg has the registers,
> -	 * include it in the check anyway.
> -	 */
> -	if (INTEL_INFO(dev)->gen < 5 && !IS_G4X(dev))
> -		return true;
> -
> -	/*
> -	 * BDW signals flip done immediately if the plane
> -	 * is disabled, even if the plane enable is already
> -	 * armed to occur at the next vblank :(
> -	 */
> -
> -	/*
> -	 * A DSPSURFLIVE check isn't enough in case the mmio and CS flips
> -	 * used the same base address. In that case the mmio flip might
> -	 * have completed, but the CS hasn't even executed the flip yet.
> -	 *
> -	 * A flip count check isn't enough as the CS might have updated
> -	 * the base address just after start of vblank, but before we
> -	 * managed to process the interrupt. This means we'd complete the
> -	 * CS flip too soon.
> -	 *
> -	 * Combining both checks should get us a good enough result. It may
> -	 * still happen that the CS flip has been executed, but has not
> -	 * yet actually completed. But in case the base address is the same
> -	 * anyway, we don't really care.
> -	 */
> -	return (I915_READ(DSPSURFLIVE(crtc->plane)) & ~0xfff) ==
> -		work->gtt_offset &&
> -		g4x_flip_count_after_eq(I915_READ(PIPE_FLIPCOUNT_G4X(crtc->pipe)),
> -					work->flip_count);
> -}
> -
> -static bool
> -__pageflip_finished_mmio(struct intel_crtc *crtc,
> -			       struct intel_flip_work *work)
> -{
> -	/*
> -	 * MMIO work completes when vblank is different from
> -	 * flip_queued_vblank.
> -	 *
> -	 * Reset counter value doesn't matter, this is handled by
> -	 * i915_wait_request finishing early, so no need to handle
> -	 * reset here.
> -	 */
> -	return intel_crtc_get_vblank_counter(crtc) != work->flip_queued_vblank;
> -}
> -
>  
>  static bool pageflip_finished(struct intel_crtc *crtc,
>  			      struct intel_flip_work *work)
> @@ -11037,44 +10926,11 @@ static bool pageflip_finished(struct intel_crtc *crtc,
>  
>  	smp_rmb();
>  
> -	if (is_mmio_work(work))
> -		return __pageflip_finished_mmio(crtc, work);
> -	else
> -		return __pageflip_finished_cs(crtc, work);
> -}
> -
> -void intel_finish_page_flip_cs(struct drm_i915_private *dev_priv, int pipe)
> -{
> -	struct drm_device *dev = dev_priv->dev;
> -	struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> -	struct intel_flip_work *work;
> -	unsigned long flags;
> -
> -	/* Ignore early vblank irqs */
> -	if (!crtc)
> -		return;
> -
>  	/*
> -	 * This is called both by irq handlers and the reset code (to complete
> -	 * lost pageflips) so needs the full irqsave spinlocks.
> +	 * MMIO work completes when vblank is different from
> +	 * flip_queued_vblank.
>  	 */
> -	spin_lock_irqsave(&dev->event_lock, flags);
> -	while (!list_empty(&intel_crtc->flip_work)) {
> -		work = list_first_entry(&intel_crtc->flip_work,
> -					struct intel_flip_work,
> -					head);
> -
> -		if (is_mmio_work(work))
> -			break;
> -
> -		if (!pageflip_finished(intel_crtc, work) ||
> -		    work_busy(&work->unpin_work))
> -			break;
> -
> -		page_flip_completed(intel_crtc, work);
> -	}
> -	spin_unlock_irqrestore(&dev->event_lock, flags);
> +	return intel_crtc_get_vblank_counter(crtc) != work->flip_queued_vblank;
>  }
>  
>  void intel_finish_page_flip_mmio(struct drm_i915_private *dev_priv, int pipe)
> @@ -11099,9 +10955,6 @@ void intel_finish_page_flip_mmio(struct drm_i915_private *dev_priv, int pipe)
>  					struct intel_flip_work,
>  					head);
>  
> -		if (!is_mmio_work(work))
> -			break;
> -
>  		if (!pageflip_finished(intel_crtc, work) ||
>  		    work_busy(&work->unpin_work))
>  			break;
> @@ -11111,16 +10964,6 @@ void intel_finish_page_flip_mmio(struct drm_i915_private *dev_priv, int pipe)
>  	spin_unlock_irqrestore(&dev->event_lock, flags);
>  }
>  
> -static inline void intel_mark_page_flip_active(struct intel_crtc *crtc,
> -					       struct intel_flip_work *work)
> -{
> -	work->flip_queued_vblank = intel_crtc_get_vblank_counter(crtc);
> -
> -	/* Ensure that the work item is consistent when activating it ... */
> -	smp_mb__before_atomic();
> -	atomic_set(&work->pending, 1);
> -}
> -
>  static int intel_gen2_queue_flip(struct drm_device *dev,
>  				 struct drm_crtc *crtc,
>  				 struct drm_framebuffer *fb,
> @@ -11352,154 +11195,6 @@ static int intel_gen7_queue_flip(struct drm_device *dev,
>  	return 0;
>  }
>  
> -static struct intel_engine_cs *
> -intel_get_flip_engine(struct drm_device *dev,
> -		      struct drm_i915_private *dev_priv,
> -		      struct drm_i915_gem_object *obj)
> -{
> -	if (IS_VALLEYVIEW(dev) || IS_IVYBRIDGE(dev) || IS_HASWELL(dev))
> -		return &dev_priv->engine[BCS];
> -
> -	if (dev_priv->info.gen >= 7) {
> -		struct intel_engine_cs *engine;
> -
> -		engine = i915_gem_request_get_engine(obj->last_write_req);
> -		if (engine && engine->id == RCS)
> -			return engine;
> -
> -		return &dev_priv->engine[BCS];
> -	} else
> -		return &dev_priv->engine[RCS];
> -}
> -
> -static bool
> -flip_fb_compatible(struct drm_device *dev,
> -		   struct drm_framebuffer *fb,
> -		   struct drm_framebuffer *old_fb)
> -{
> -	struct drm_i915_gem_object *obj = intel_fb_obj(fb);
> -	struct drm_i915_gem_object *old_obj = intel_fb_obj(old_fb);
> -
> -	if (old_fb->pixel_format != fb->pixel_format)
> -		return false;
> -
> -	if (INTEL_INFO(dev)->gen > 3 &&
> -	    (fb->offsets[0] != old_fb->offsets[0] ||
> -	     fb->pitches[0] != old_fb->pitches[0]))
> -		return false;
> -
> -			/* vlv: DISPLAY_FLIP fails to change tiling */
> -	if (IS_VALLEYVIEW(dev) && obj->tiling_mode != old_obj->tiling_mode)
> -		return false;
> -
> -	return true;
> -}
> -
> -static void
> -intel_display_flip_prepare(struct drm_device *dev, struct drm_crtc *crtc,
> -			   struct intel_flip_work *work)
> -{
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> -
> -	if (work->flip_prepared)
> -		return;
> -
> -	work->flip_prepared = true;
> -
> -	if (INTEL_INFO(dev)->gen >= 5 || IS_G4X(dev))
> -		work->flip_count = I915_READ(PIPE_FLIPCOUNT_G4X(intel_crtc->pipe)) + 1;
> -	work->flip_queued_vblank = drm_crtc_vblank_count(crtc);
> -
> -	intel_frontbuffer_flip_prepare(dev, work->new_crtc_state->fb_bits);
> -}
> -
> -static void intel_flip_schedule_request(struct intel_flip_work *work, struct drm_crtc *crtc)
> -{
> -	struct drm_device *dev = crtc->dev;
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> -	struct intel_plane_state *new_state = work->new_plane_state[0];
> -	struct intel_plane_state *old_state = work->old_plane_state[0];
> -	struct drm_framebuffer *fb, *old_fb;
> -	struct drm_i915_gem_request *request = NULL;
> -	struct intel_engine_cs *engine;
> -	struct drm_i915_gem_object *obj;
> -	struct fence *fence;
> -	int ret;
> -
> -	to_intel_crtc(crtc)->reset_counter = i915_reset_counter(&dev_priv->gpu_error);
> -	if (__i915_reset_in_progress_or_wedged(to_intel_crtc(crtc)->reset_counter))
> -		goto mmio;
> -
> -	if (i915_terminally_wedged(&dev_priv->gpu_error) ||
> -	    i915_reset_in_progress(&dev_priv->gpu_error) ||
> -	    i915.enable_execlists || i915.use_mmio_flip > 0 ||
> -	    !dev_priv->display.queue_flip)
> -		goto mmio;
> -
> -	/* Not right after modesetting, surface parameters need to be updated */
> -	if (needs_modeset(crtc->state) ||
> -	    to_intel_crtc_state(crtc->state)->update_pipe)
> -		goto mmio;
> -
> -	/* Only allow a mmio flip for a primary plane without a dma-buf fence */
> -	if (work->num_planes != 1 ||
> -	    new_state->base.plane != crtc->primary ||
> -	    new_state->base.fence)
> -		goto mmio;
> -
> -	fence = work->old_plane_state[0]->base.fence;
> -	if (fence && !fence_is_signaled(fence))
> -		goto mmio;
> -
> -	old_fb = old_state->base.fb;
> -	fb = new_state->base.fb;
> -	obj = intel_fb_obj(fb);
> -
> -	trace_i915_flip_request(to_intel_crtc(crtc)->plane, obj);
> -
> -	/* Only when updating a already visible fb. */
> -	if (!new_state->visible || !old_state->visible)
> -		goto mmio;
> -
> -	if (!flip_fb_compatible(dev, fb, old_fb))
> -		goto mmio;
> -
> -	engine = intel_get_flip_engine(dev, dev_priv, obj);
> -	if (i915.use_mmio_flip == 0 && obj->last_write_req &&
> -	    i915_gem_request_get_engine(obj->last_write_req) != engine)
> -		goto mmio;
> -
> -	work->gtt_offset = intel_plane_obj_offset(to_intel_plane(crtc->primary), obj, 0);
> -	work->gtt_offset += to_intel_crtc(crtc)->dspaddr_offset;
> -
> -	ret = i915_gem_object_sync(obj, engine, &request);
> -	if (!ret && !request) {
> -		request = i915_gem_request_alloc(engine, NULL);
> -		ret = PTR_ERR_OR_ZERO(request);
> -
> -		if (ret)
> -			request = NULL;
> -	}
> -
> -	intel_display_flip_prepare(dev, crtc, work);
> -
> -	if (!ret)
> -		ret = dev_priv->display.queue_flip(dev, crtc, fb, obj, request, 0);
> -
> -	if (!ret) {
> -		i915_gem_request_assign(&work->flip_queued_req, request);
> -		intel_mark_page_flip_active(to_intel_crtc(crtc), work);
> -		i915_add_request_no_flush(request);
> -		return;
> -	}
> -	if (request)
> -		i915_add_request_no_flush(request);
> -
> -mmio:
> -	schedule_work(&work->mmio_work);
> -}
> -
>  static void intel_mmio_flip_work_func(struct work_struct *w)
>  {
>  	struct intel_flip_work *work =
> @@ -11527,7 +11222,7 @@ static void intel_mmio_flip_work_func(struct work_struct *w)
>  					    &dev_priv->rps.mmioflips));
>  	}
>  
> -	intel_display_flip_prepare(dev, crtc, work);
> +	intel_frontbuffer_flip_prepare(dev, crtc_state->fb_bits);
>  
>  	intel_pipe_update_start(intel_crtc);
>  	if (!needs_modeset(&crtc_state->base)) {
> @@ -11552,80 +11247,6 @@ static void intel_mmio_flip_work_func(struct work_struct *w)
>  	intel_pipe_update_end(intel_crtc, work);
>  }
>  
> -static bool __pageflip_stall_check_cs(struct drm_i915_private *dev_priv,
> -				      struct intel_crtc *intel_crtc,
> -				      struct intel_flip_work *work)
> -{
> -	u32 addr, vblank;
> -
> -	if (!atomic_read(&work->pending) ||
> -	    work_busy(&work->unpin_work))
> -		return false;
> -
> -	smp_rmb();
> -
> -	vblank = intel_crtc_get_vblank_counter(intel_crtc);
> -	if (work->flip_ready_vblank == 0) {
> -		if (work->flip_queued_req &&
> -		    !i915_gem_request_completed(work->flip_queued_req, true))
> -			return false;
> -
> -		work->flip_ready_vblank = vblank;
> -	}
> -
> -	if (vblank - work->flip_ready_vblank < 3)
> -		return false;
> -
> -	/* Potential stall - if we see that the flip has happened,
> -	 * assume a missed interrupt. */
> -	if (INTEL_GEN(dev_priv) >= 4)
> -		addr = I915_HI_DISPBASE(I915_READ(DSPSURF(intel_crtc->plane)));
> -	else
> -		addr = I915_READ(DSPADDR(intel_crtc->plane));
> -
> -	/* There is a potential issue here with a false positive after a flip
> -	 * to the same address. We could address this by checking for a
> -	 * non-incrementing frame counter.
> -	 */
> -	return addr == work->gtt_offset;
> -}
> -
> -void intel_check_page_flip(struct drm_i915_private *dev_priv, int pipe)
> -{
> -	struct drm_device *dev = dev_priv->dev;
> -	struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> -	struct intel_flip_work *work;
> -
> -	WARN_ON(!in_interrupt());
> -
> -	if (crtc == NULL)
> -		return;
> -
> -	spin_lock(&dev->event_lock);
> -	while (!list_empty(&intel_crtc->flip_work)) {
> -		work = list_first_entry(&intel_crtc->flip_work,
> -					struct intel_flip_work, head);
> -
> -		if (is_mmio_work(work))
> -			break;
> -
> -		if (__pageflip_stall_check_cs(dev_priv, intel_crtc, work)) {
> -			WARN_ONCE(1,
> -				  "Kicking stuck page flip: queued at %d, now %d\n",
> -				work->flip_queued_vblank, intel_crtc_get_vblank_counter(intel_crtc));
> -			page_flip_completed(intel_crtc, work);
> -			continue;
> -		}
> -
> -		if (intel_crtc_get_vblank_counter(intel_crtc) - work->flip_queued_vblank > 1)
> -			intel_queue_rps_boost_for_request(work->flip_queued_req);
> -
> -		break;
> -	}
> -	spin_unlock(&dev->event_lock);
> -}
> -
>  static struct fence *intel_get_excl_fence(struct drm_i915_gem_object *obj)
>  {
>  	struct reservation_object *resv;
> @@ -11789,7 +11410,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
>  
>  	intel_fbc_pre_update(intel_crtc);
>  
> -	intel_flip_schedule_request(work, crtc);
> +	intel_crtc->reset_counter = i915_reset_counter(&dev_priv->gpu_error);
> +	schedule_work(&work->mmio_work);
>  
>  	mutex_unlock(&dev->struct_mutex);
>  
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 83c0b998fb88..c538d821a728 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -977,16 +977,12 @@ struct intel_flip_work {
>  
>  	struct drm_pending_vblank_event *event;
>  	atomic_t pending;
> -	u32 flip_count;
> -	u32 gtt_offset;
> -	struct drm_i915_gem_request *flip_queued_req;
>  	u32 flip_queued_vblank;
> -	u32 flip_ready_vblank;
>  
>  	unsigned put_power_domains;
>  	unsigned num_planes;
>  
> -	bool can_async_unpin, flip_prepared;
> +	bool can_async_unpin;
>  	unsigned fb_bits;
>  
>  	struct intel_crtc_state *old_crtc_state, *new_crtc_state;
> @@ -1202,9 +1198,8 @@ struct drm_framebuffer *
>  __intel_framebuffer_create(struct drm_device *dev,
>  			   struct drm_mode_fb_cmd2 *mode_cmd,
>  			   struct drm_i915_gem_object *obj);
> -void intel_finish_page_flip_cs(struct drm_i915_private *dev_priv, int pipe);
>  void intel_finish_page_flip_mmio(struct drm_i915_private *dev_priv, int pipe);
> -void intel_check_page_flip(struct drm_i915_private *dev_priv, int pipe);
> +
>  int intel_prepare_plane_fb(struct drm_plane *plane,
>  			   const struct drm_plane_state *new_state);
>  void intel_cleanup_plane_fb(struct drm_plane *plane,
> -- 
> 2.5.5
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 6bce4fd8aaf4..4c6b48dbd6e2 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -599,7 +599,6 @@  static void i915_dump_pageflip(struct seq_file *m,
 {
 	const char pipe = pipe_name(crtc->pipe);
 	u32 pending;
-	u32 addr;
 	int i;
 
 	pending = atomic_read(&work->pending);
@@ -611,7 +610,6 @@  static void i915_dump_pageflip(struct seq_file *m,
 			   pipe, plane_name(crtc->plane));
 	}
 
-
 	for (i = 0; i < work->num_planes; i++) {
 		struct intel_plane_state *old_plane_state = work->old_plane_state[i];
 		struct drm_plane *plane = old_plane_state->base.plane;
@@ -635,22 +633,9 @@  static void i915_dump_pageflip(struct seq_file *m,
 			   i915_gem_request_completed(req, true));
 	}
 
-	seq_printf(m, "Flip queued on frame %d, (was ready on frame %d), now %d\n",
-		   work->flip_queued_vblank,
-		   work->flip_ready_vblank,
+	seq_printf(m, "Flip queued on frame %d, now %d\n",
+		   pending ? work->flip_queued_vblank : -1,
 		   intel_crtc_get_vblank_counter(crtc));
-	seq_printf(m, "%d prepares\n", atomic_read(&work->pending));
-
-	if (INTEL_INFO(dev_priv)->gen >= 4)
-		addr = I915_HI_DISPBASE(I915_READ(DSPSURF(crtc->plane)));
-	else
-		addr = I915_READ(DSPADDR(crtc->plane));
-	seq_printf(m, "Current scanout address 0x%08x\n", addr);
-
-	if (work->flip_queued_req) {
-		seq_printf(m, "New framebuffer address 0x%08lx\n", (long)work->gtt_offset);
-		seq_printf(m, "MMIO update completed? %d\n",  addr == work->gtt_offset);
-	}
 }
 
 static int i915_gem_pageflip_info(struct seq_file *m, void *data)
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 3242a37fb304..5513c4cb02e0 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -136,6 +136,12 @@  static const u32 hpd_bxt[HPD_NUM_PINS] = {
 	POSTING_READ(type##IIR); \
 } while (0)
 
+static void
+intel_finish_page_flip_cs(struct drm_i915_private *dev_priv, unsigned pipe)
+{
+	DRM_DEBUG_KMS("Finished page flip\n");
+}
+
 /*
  * We should clear IMR at preinstall/uninstall, and just check at postinstall.
  */
@@ -1631,16 +1637,11 @@  static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir)
 	}
 }
 
-static bool intel_pipe_handle_vblank(struct drm_i915_private *dev_priv,
+static void intel_pipe_handle_vblank(struct drm_i915_private *dev_priv,
 				     enum pipe pipe)
 {
-	bool ret;
-
-	ret = drm_handle_vblank(dev_priv->dev, pipe);
-	if (ret)
+	if (drm_handle_vblank(dev_priv->dev, pipe))
 		intel_finish_page_flip_mmio(dev_priv, pipe);
-
-	return ret;
 }
 
 static void valleyview_pipestat_irq_ack(struct drm_i915_private *dev_priv,
@@ -1707,9 +1708,8 @@  static void valleyview_pipestat_irq_handler(struct drm_i915_private *dev_priv,
 	enum pipe pipe;
 
 	for_each_pipe(dev_priv, pipe) {
-		if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS &&
-		    intel_pipe_handle_vblank(dev_priv, pipe))
-			intel_check_page_flip(dev_priv, pipe);
+		if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS)
+			intel_pipe_handle_vblank(dev_priv, pipe);
 
 		if (pipe_stats[pipe] & PLANE_FLIP_DONE_INT_STATUS_VLV)
 			intel_finish_page_flip_cs(dev_priv, pipe);
@@ -2155,9 +2155,8 @@  static void ilk_display_irq_handler(struct drm_i915_private *dev_priv,
 		DRM_ERROR("Poison interrupt\n");
 
 	for_each_pipe(dev_priv, pipe) {
-		if (de_iir & DE_PIPE_VBLANK(pipe) &&
-		    intel_pipe_handle_vblank(dev_priv, pipe))
-			intel_check_page_flip(dev_priv, pipe);
+		if (de_iir & DE_PIPE_VBLANK(pipe))
+			intel_pipe_handle_vblank(dev_priv, pipe);
 
 		if (de_iir & DE_PIPE_FIFO_UNDERRUN(pipe))
 			intel_cpu_fifo_underrun_irq_handler(dev_priv, pipe);
@@ -2206,9 +2205,8 @@  static void ivb_display_irq_handler(struct drm_i915_private *dev_priv,
 		intel_opregion_asle_intr(dev_priv);
 
 	for_each_pipe(dev_priv, pipe) {
-		if (de_iir & (DE_PIPE_VBLANK_IVB(pipe)) &&
-		    intel_pipe_handle_vblank(dev_priv, pipe))
-			intel_check_page_flip(dev_priv, pipe);
+		if (de_iir & (DE_PIPE_VBLANK_IVB(pipe)))
+			intel_pipe_handle_vblank(dev_priv, pipe);
 
 		/* plane/pipes map 1:1 on ilk+ */
 		if (de_iir & DE_PLANE_FLIP_DONE_IVB(pipe))
@@ -2407,9 +2405,8 @@  gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl)
 		ret = IRQ_HANDLED;
 		I915_WRITE(GEN8_DE_PIPE_IIR(pipe), iir);
 
-		if (iir & GEN8_PIPE_VBLANK &&
-		    intel_pipe_handle_vblank(dev_priv, pipe))
-			intel_check_page_flip(dev_priv, pipe);
+		if (iir & GEN8_PIPE_VBLANK)
+			intel_pipe_handle_vblank(dev_priv, pipe);
 
 		flip_done = iir;
 		if (INTEL_INFO(dev_priv)->gen >= 9)
@@ -3973,37 +3970,6 @@  static int i8xx_irq_postinstall(struct drm_device *dev)
 	return 0;
 }
 
-/*
- * Returns true when a page flip has completed.
- */
-static bool i8xx_handle_vblank(struct drm_i915_private *dev_priv,
-			       int plane, int pipe, u32 iir)
-{
-	u16 flip_pending = DISPLAY_PLANE_FLIP_PENDING(plane);
-
-	if (!intel_pipe_handle_vblank(dev_priv, pipe))
-		return false;
-
-	if ((iir & flip_pending) == 0)
-		goto check_page_flip;
-
-	/* We detect FlipDone by looking for the change in PendingFlip from '1'
-	 * to '0' on the following vblank, i.e. IIR has the Pendingflip
-	 * asserted following the MI_DISPLAY_FLIP, but ISR is deasserted, hence
-	 * the flip is completed (no longer pending). Since this doesn't raise
-	 * an interrupt per se, we watch for the change at vblank.
-	 */
-	if (I915_READ16(ISR) & flip_pending)
-		goto check_page_flip;
-
-	intel_finish_page_flip_cs(dev_priv, pipe);
-	return true;
-
-check_page_flip:
-	intel_check_page_flip(dev_priv, pipe);
-	return false;
-}
-
 static irqreturn_t i8xx_irq_handler(int irq, void *arg)
 {
 	struct drm_device *dev = arg;
@@ -4056,13 +4022,8 @@  static irqreturn_t i8xx_irq_handler(int irq, void *arg)
 			notify_ring(&dev_priv->engine[RCS]);
 
 		for_each_pipe(dev_priv, pipe) {
-			int plane = pipe;
-			if (HAS_FBC(dev_priv))
-				plane = !plane;
-
-			if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS &&
-			    i8xx_handle_vblank(dev_priv, plane, pipe, iir))
-				flip_mask &= ~DISPLAY_PLANE_FLIP_PENDING(plane);
+			if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS)
+				intel_pipe_handle_vblank(dev_priv, pipe);
 
 			if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS)
 				i9xx_pipe_crc_irq_handler(dev_priv, pipe);
@@ -4162,37 +4123,6 @@  static int i915_irq_postinstall(struct drm_device *dev)
 	return 0;
 }
 
-/*
- * Returns true when a page flip has completed.
- */
-static bool i915_handle_vblank(struct drm_i915_private *dev_priv,
-			       int plane, int pipe, u32 iir)
-{
-	u32 flip_pending = DISPLAY_PLANE_FLIP_PENDING(plane);
-
-	if (!intel_pipe_handle_vblank(dev_priv, pipe))
-		return false;
-
-	if ((iir & flip_pending) == 0)
-		goto check_page_flip;
-
-	/* We detect FlipDone by looking for the change in PendingFlip from '1'
-	 * to '0' on the following vblank, i.e. IIR has the Pendingflip
-	 * asserted following the MI_DISPLAY_FLIP, but ISR is deasserted, hence
-	 * the flip is completed (no longer pending). Since this doesn't raise
-	 * an interrupt per se, we watch for the change at vblank.
-	 */
-	if (I915_READ(ISR) & flip_pending)
-		goto check_page_flip;
-
-	intel_finish_page_flip_cs(dev_priv, pipe);
-	return true;
-
-check_page_flip:
-	intel_check_page_flip(dev_priv, pipe);
-	return false;
-}
-
 static irqreturn_t i915_irq_handler(int irq, void *arg)
 {
 	struct drm_device *dev = arg;
@@ -4253,13 +4183,8 @@  static irqreturn_t i915_irq_handler(int irq, void *arg)
 			notify_ring(&dev_priv->engine[RCS]);
 
 		for_each_pipe(dev_priv, pipe) {
-			int plane = pipe;
-			if (HAS_FBC(dev_priv))
-				plane = !plane;
-
-			if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS &&
-			    i915_handle_vblank(dev_priv, plane, pipe, iir))
-				flip_mask &= ~DISPLAY_PLANE_FLIP_PENDING(plane);
+			if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS)
+				intel_pipe_handle_vblank(dev_priv, pipe);
 
 			if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS)
 				blc_event = true;
@@ -4487,9 +4412,8 @@  static irqreturn_t i965_irq_handler(int irq, void *arg)
 			notify_ring(&dev_priv->engine[VCS]);
 
 		for_each_pipe(dev_priv, pipe) {
-			if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS &&
-			    i915_handle_vblank(dev_priv, pipe, pipe, iir))
-				flip_mask &= ~DISPLAY_PLANE_FLIP_PENDING(pipe);
+			if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS)
+				intel_pipe_handle_vblank(dev_priv, pipe);
 
 			if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS)
 				blc_event = true;
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index b8b12177f1f0..19a382445306 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -48,11 +48,6 @@ 
 #include <linux/reservation.h>
 #include <linux/dma-buf.h>
 
-static bool is_mmio_work(struct intel_flip_work *work)
-{
-	return !work->flip_queued_req;
-}
-
 /* Primary plane formats for gen <= 3 */
 static const uint32_t i8xx_primary_formats[] = {
 	DRM_FORMAT_C8,
@@ -3102,14 +3097,6 @@  intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb,
 	return -ENODEV;
 }
 
-static void intel_complete_page_flips(struct drm_i915_private *dev_priv)
-{
-	struct intel_crtc *crtc;
-
-	for_each_intel_crtc(dev_priv->dev, crtc)
-		intel_finish_page_flip_cs(dev_priv, crtc->pipe);
-}
-
 static void intel_update_primary_planes(struct drm_device *dev)
 {
 	struct drm_crtc *crtc;
@@ -3150,13 +3137,6 @@  void intel_prepare_reset(struct drm_i915_private *dev_priv)
 
 void intel_finish_reset(struct drm_i915_private *dev_priv)
 {
-	/*
-	 * Flips in the rings will be nuked by the reset,
-	 * so complete all pending flips so that user space
-	 * will get its events and not get stuck.
-	 */
-	intel_complete_page_flips(dev_priv);
-
 	/* no reset support for gen2 */
 	if (IS_GEN2(dev_priv))
 		return;
@@ -3834,26 +3814,7 @@  static int intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc)
 	if (ret < 0)
 		return ret;
 
-	if (ret == 0) {
-		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-		struct intel_flip_work *work;
-
-		spin_lock_irq(&dev->event_lock);
-
-		/*
-		 * If we're waiting for page flips, it's the first
-		 * flip on the list that's stuck.
-		 */
-		work = list_first_entry_or_null(&intel_crtc->flip_work,
-						struct intel_flip_work, head);
-
-		if (work && !is_mmio_work(work) &&
-		    !work_busy(&work->unpin_work)) {
-			WARN_ONCE(1, "Removing stuck page flip\n");
-			page_flip_completed(intel_crtc, work);
-		}
-		spin_unlock_irq(&dev->event_lock);
-	}
+	WARN(ret == 0, "Stuck page flip\n");
 
 	return 0;
 }
@@ -10925,9 +10886,6 @@  static void intel_unpin_work_fn(struct work_struct *__work)
 
 	intel_crtc_destroy_state(crtc, &work->old_crtc_state->base);
 
-	if (work->flip_queued_req)
-		i915_gem_request_unreference(work->flip_queued_req);
-
 	for (i = 0; i < work->num_planes; i++) {
 		struct intel_plane_state *old_plane_state =
 			work->old_plane_state[i];
@@ -10959,75 +10917,6 @@  static void intel_unpin_work_fn(struct work_struct *__work)
 	kfree(work);
 }
 
-/* Is 'a' after or equal to 'b'? */
-static bool g4x_flip_count_after_eq(u32 a, u32 b)
-{
-	return !((a - b) & 0x80000000);
-}
-
-static bool __pageflip_finished_cs(struct intel_crtc *crtc,
-				   struct intel_flip_work *work)
-{
-	struct drm_device *dev = crtc->base.dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	unsigned reset_counter;
-
-	reset_counter = i915_reset_counter(&dev_priv->gpu_error);
-	if (crtc->reset_counter != reset_counter)
-		return true;
-
-	/*
-	 * The relevant registers doen't exist on pre-ctg.
-	 * As the flip done interrupt doesn't trigger for mmio
-	 * flips on gmch platforms, a flip count check isn't
-	 * really needed there. But since ctg has the registers,
-	 * include it in the check anyway.
-	 */
-	if (INTEL_INFO(dev)->gen < 5 && !IS_G4X(dev))
-		return true;
-
-	/*
-	 * BDW signals flip done immediately if the plane
-	 * is disabled, even if the plane enable is already
-	 * armed to occur at the next vblank :(
-	 */
-
-	/*
-	 * A DSPSURFLIVE check isn't enough in case the mmio and CS flips
-	 * used the same base address. In that case the mmio flip might
-	 * have completed, but the CS hasn't even executed the flip yet.
-	 *
-	 * A flip count check isn't enough as the CS might have updated
-	 * the base address just after start of vblank, but before we
-	 * managed to process the interrupt. This means we'd complete the
-	 * CS flip too soon.
-	 *
-	 * Combining both checks should get us a good enough result. It may
-	 * still happen that the CS flip has been executed, but has not
-	 * yet actually completed. But in case the base address is the same
-	 * anyway, we don't really care.
-	 */
-	return (I915_READ(DSPSURFLIVE(crtc->plane)) & ~0xfff) ==
-		work->gtt_offset &&
-		g4x_flip_count_after_eq(I915_READ(PIPE_FLIPCOUNT_G4X(crtc->pipe)),
-					work->flip_count);
-}
-
-static bool
-__pageflip_finished_mmio(struct intel_crtc *crtc,
-			       struct intel_flip_work *work)
-{
-	/*
-	 * MMIO work completes when vblank is different from
-	 * flip_queued_vblank.
-	 *
-	 * Reset counter value doesn't matter, this is handled by
-	 * i915_wait_request finishing early, so no need to handle
-	 * reset here.
-	 */
-	return intel_crtc_get_vblank_counter(crtc) != work->flip_queued_vblank;
-}
-
 
 static bool pageflip_finished(struct intel_crtc *crtc,
 			      struct intel_flip_work *work)
@@ -11037,44 +10926,11 @@  static bool pageflip_finished(struct intel_crtc *crtc,
 
 	smp_rmb();
 
-	if (is_mmio_work(work))
-		return __pageflip_finished_mmio(crtc, work);
-	else
-		return __pageflip_finished_cs(crtc, work);
-}
-
-void intel_finish_page_flip_cs(struct drm_i915_private *dev_priv, int pipe)
-{
-	struct drm_device *dev = dev_priv->dev;
-	struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-	struct intel_flip_work *work;
-	unsigned long flags;
-
-	/* Ignore early vblank irqs */
-	if (!crtc)
-		return;
-
 	/*
-	 * This is called both by irq handlers and the reset code (to complete
-	 * lost pageflips) so needs the full irqsave spinlocks.
+	 * MMIO work completes when vblank is different from
+	 * flip_queued_vblank.
 	 */
-	spin_lock_irqsave(&dev->event_lock, flags);
-	while (!list_empty(&intel_crtc->flip_work)) {
-		work = list_first_entry(&intel_crtc->flip_work,
-					struct intel_flip_work,
-					head);
-
-		if (is_mmio_work(work))
-			break;
-
-		if (!pageflip_finished(intel_crtc, work) ||
-		    work_busy(&work->unpin_work))
-			break;
-
-		page_flip_completed(intel_crtc, work);
-	}
-	spin_unlock_irqrestore(&dev->event_lock, flags);
+	return intel_crtc_get_vblank_counter(crtc) != work->flip_queued_vblank;
 }
 
 void intel_finish_page_flip_mmio(struct drm_i915_private *dev_priv, int pipe)
@@ -11099,9 +10955,6 @@  void intel_finish_page_flip_mmio(struct drm_i915_private *dev_priv, int pipe)
 					struct intel_flip_work,
 					head);
 
-		if (!is_mmio_work(work))
-			break;
-
 		if (!pageflip_finished(intel_crtc, work) ||
 		    work_busy(&work->unpin_work))
 			break;
@@ -11111,16 +10964,6 @@  void intel_finish_page_flip_mmio(struct drm_i915_private *dev_priv, int pipe)
 	spin_unlock_irqrestore(&dev->event_lock, flags);
 }
 
-static inline void intel_mark_page_flip_active(struct intel_crtc *crtc,
-					       struct intel_flip_work *work)
-{
-	work->flip_queued_vblank = intel_crtc_get_vblank_counter(crtc);
-
-	/* Ensure that the work item is consistent when activating it ... */
-	smp_mb__before_atomic();
-	atomic_set(&work->pending, 1);
-}
-
 static int intel_gen2_queue_flip(struct drm_device *dev,
 				 struct drm_crtc *crtc,
 				 struct drm_framebuffer *fb,
@@ -11352,154 +11195,6 @@  static int intel_gen7_queue_flip(struct drm_device *dev,
 	return 0;
 }
 
-static struct intel_engine_cs *
-intel_get_flip_engine(struct drm_device *dev,
-		      struct drm_i915_private *dev_priv,
-		      struct drm_i915_gem_object *obj)
-{
-	if (IS_VALLEYVIEW(dev) || IS_IVYBRIDGE(dev) || IS_HASWELL(dev))
-		return &dev_priv->engine[BCS];
-
-	if (dev_priv->info.gen >= 7) {
-		struct intel_engine_cs *engine;
-
-		engine = i915_gem_request_get_engine(obj->last_write_req);
-		if (engine && engine->id == RCS)
-			return engine;
-
-		return &dev_priv->engine[BCS];
-	} else
-		return &dev_priv->engine[RCS];
-}
-
-static bool
-flip_fb_compatible(struct drm_device *dev,
-		   struct drm_framebuffer *fb,
-		   struct drm_framebuffer *old_fb)
-{
-	struct drm_i915_gem_object *obj = intel_fb_obj(fb);
-	struct drm_i915_gem_object *old_obj = intel_fb_obj(old_fb);
-
-	if (old_fb->pixel_format != fb->pixel_format)
-		return false;
-
-	if (INTEL_INFO(dev)->gen > 3 &&
-	    (fb->offsets[0] != old_fb->offsets[0] ||
-	     fb->pitches[0] != old_fb->pitches[0]))
-		return false;
-
-			/* vlv: DISPLAY_FLIP fails to change tiling */
-	if (IS_VALLEYVIEW(dev) && obj->tiling_mode != old_obj->tiling_mode)
-		return false;
-
-	return true;
-}
-
-static void
-intel_display_flip_prepare(struct drm_device *dev, struct drm_crtc *crtc,
-			   struct intel_flip_work *work)
-{
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-
-	if (work->flip_prepared)
-		return;
-
-	work->flip_prepared = true;
-
-	if (INTEL_INFO(dev)->gen >= 5 || IS_G4X(dev))
-		work->flip_count = I915_READ(PIPE_FLIPCOUNT_G4X(intel_crtc->pipe)) + 1;
-	work->flip_queued_vblank = drm_crtc_vblank_count(crtc);
-
-	intel_frontbuffer_flip_prepare(dev, work->new_crtc_state->fb_bits);
-}
-
-static void intel_flip_schedule_request(struct intel_flip_work *work, struct drm_crtc *crtc)
-{
-	struct drm_device *dev = crtc->dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_plane_state *new_state = work->new_plane_state[0];
-	struct intel_plane_state *old_state = work->old_plane_state[0];
-	struct drm_framebuffer *fb, *old_fb;
-	struct drm_i915_gem_request *request = NULL;
-	struct intel_engine_cs *engine;
-	struct drm_i915_gem_object *obj;
-	struct fence *fence;
-	int ret;
-
-	to_intel_crtc(crtc)->reset_counter = i915_reset_counter(&dev_priv->gpu_error);
-	if (__i915_reset_in_progress_or_wedged(to_intel_crtc(crtc)->reset_counter))
-		goto mmio;
-
-	if (i915_terminally_wedged(&dev_priv->gpu_error) ||
-	    i915_reset_in_progress(&dev_priv->gpu_error) ||
-	    i915.enable_execlists || i915.use_mmio_flip > 0 ||
-	    !dev_priv->display.queue_flip)
-		goto mmio;
-
-	/* Not right after modesetting, surface parameters need to be updated */
-	if (needs_modeset(crtc->state) ||
-	    to_intel_crtc_state(crtc->state)->update_pipe)
-		goto mmio;
-
-	/* Only allow a mmio flip for a primary plane without a dma-buf fence */
-	if (work->num_planes != 1 ||
-	    new_state->base.plane != crtc->primary ||
-	    new_state->base.fence)
-		goto mmio;
-
-	fence = work->old_plane_state[0]->base.fence;
-	if (fence && !fence_is_signaled(fence))
-		goto mmio;
-
-	old_fb = old_state->base.fb;
-	fb = new_state->base.fb;
-	obj = intel_fb_obj(fb);
-
-	trace_i915_flip_request(to_intel_crtc(crtc)->plane, obj);
-
-	/* Only when updating a already visible fb. */
-	if (!new_state->visible || !old_state->visible)
-		goto mmio;
-
-	if (!flip_fb_compatible(dev, fb, old_fb))
-		goto mmio;
-
-	engine = intel_get_flip_engine(dev, dev_priv, obj);
-	if (i915.use_mmio_flip == 0 && obj->last_write_req &&
-	    i915_gem_request_get_engine(obj->last_write_req) != engine)
-		goto mmio;
-
-	work->gtt_offset = intel_plane_obj_offset(to_intel_plane(crtc->primary), obj, 0);
-	work->gtt_offset += to_intel_crtc(crtc)->dspaddr_offset;
-
-	ret = i915_gem_object_sync(obj, engine, &request);
-	if (!ret && !request) {
-		request = i915_gem_request_alloc(engine, NULL);
-		ret = PTR_ERR_OR_ZERO(request);
-
-		if (ret)
-			request = NULL;
-	}
-
-	intel_display_flip_prepare(dev, crtc, work);
-
-	if (!ret)
-		ret = dev_priv->display.queue_flip(dev, crtc, fb, obj, request, 0);
-
-	if (!ret) {
-		i915_gem_request_assign(&work->flip_queued_req, request);
-		intel_mark_page_flip_active(to_intel_crtc(crtc), work);
-		i915_add_request_no_flush(request);
-		return;
-	}
-	if (request)
-		i915_add_request_no_flush(request);
-
-mmio:
-	schedule_work(&work->mmio_work);
-}
-
 static void intel_mmio_flip_work_func(struct work_struct *w)
 {
 	struct intel_flip_work *work =
@@ -11527,7 +11222,7 @@  static void intel_mmio_flip_work_func(struct work_struct *w)
 					    &dev_priv->rps.mmioflips));
 	}
 
-	intel_display_flip_prepare(dev, crtc, work);
+	intel_frontbuffer_flip_prepare(dev, crtc_state->fb_bits);
 
 	intel_pipe_update_start(intel_crtc);
 	if (!needs_modeset(&crtc_state->base)) {
@@ -11552,80 +11247,6 @@  static void intel_mmio_flip_work_func(struct work_struct *w)
 	intel_pipe_update_end(intel_crtc, work);
 }
 
-static bool __pageflip_stall_check_cs(struct drm_i915_private *dev_priv,
-				      struct intel_crtc *intel_crtc,
-				      struct intel_flip_work *work)
-{
-	u32 addr, vblank;
-
-	if (!atomic_read(&work->pending) ||
-	    work_busy(&work->unpin_work))
-		return false;
-
-	smp_rmb();
-
-	vblank = intel_crtc_get_vblank_counter(intel_crtc);
-	if (work->flip_ready_vblank == 0) {
-		if (work->flip_queued_req &&
-		    !i915_gem_request_completed(work->flip_queued_req, true))
-			return false;
-
-		work->flip_ready_vblank = vblank;
-	}
-
-	if (vblank - work->flip_ready_vblank < 3)
-		return false;
-
-	/* Potential stall - if we see that the flip has happened,
-	 * assume a missed interrupt. */
-	if (INTEL_GEN(dev_priv) >= 4)
-		addr = I915_HI_DISPBASE(I915_READ(DSPSURF(intel_crtc->plane)));
-	else
-		addr = I915_READ(DSPADDR(intel_crtc->plane));
-
-	/* There is a potential issue here with a false positive after a flip
-	 * to the same address. We could address this by checking for a
-	 * non-incrementing frame counter.
-	 */
-	return addr == work->gtt_offset;
-}
-
-void intel_check_page_flip(struct drm_i915_private *dev_priv, int pipe)
-{
-	struct drm_device *dev = dev_priv->dev;
-	struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-	struct intel_flip_work *work;
-
-	WARN_ON(!in_interrupt());
-
-	if (crtc == NULL)
-		return;
-
-	spin_lock(&dev->event_lock);
-	while (!list_empty(&intel_crtc->flip_work)) {
-		work = list_first_entry(&intel_crtc->flip_work,
-					struct intel_flip_work, head);
-
-		if (is_mmio_work(work))
-			break;
-
-		if (__pageflip_stall_check_cs(dev_priv, intel_crtc, work)) {
-			WARN_ONCE(1,
-				  "Kicking stuck page flip: queued at %d, now %d\n",
-				work->flip_queued_vblank, intel_crtc_get_vblank_counter(intel_crtc));
-			page_flip_completed(intel_crtc, work);
-			continue;
-		}
-
-		if (intel_crtc_get_vblank_counter(intel_crtc) - work->flip_queued_vblank > 1)
-			intel_queue_rps_boost_for_request(work->flip_queued_req);
-
-		break;
-	}
-	spin_unlock(&dev->event_lock);
-}
-
 static struct fence *intel_get_excl_fence(struct drm_i915_gem_object *obj)
 {
 	struct reservation_object *resv;
@@ -11789,7 +11410,8 @@  static int intel_crtc_page_flip(struct drm_crtc *crtc,
 
 	intel_fbc_pre_update(intel_crtc);
 
-	intel_flip_schedule_request(work, crtc);
+	intel_crtc->reset_counter = i915_reset_counter(&dev_priv->gpu_error);
+	schedule_work(&work->mmio_work);
 
 	mutex_unlock(&dev->struct_mutex);
 
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 83c0b998fb88..c538d821a728 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -977,16 +977,12 @@  struct intel_flip_work {
 
 	struct drm_pending_vblank_event *event;
 	atomic_t pending;
-	u32 flip_count;
-	u32 gtt_offset;
-	struct drm_i915_gem_request *flip_queued_req;
 	u32 flip_queued_vblank;
-	u32 flip_ready_vblank;
 
 	unsigned put_power_domains;
 	unsigned num_planes;
 
-	bool can_async_unpin, flip_prepared;
+	bool can_async_unpin;
 	unsigned fb_bits;
 
 	struct intel_crtc_state *old_crtc_state, *new_crtc_state;
@@ -1202,9 +1198,8 @@  struct drm_framebuffer *
 __intel_framebuffer_create(struct drm_device *dev,
 			   struct drm_mode_fb_cmd2 *mode_cmd,
 			   struct drm_i915_gem_object *obj);
-void intel_finish_page_flip_cs(struct drm_i915_private *dev_priv, int pipe);
 void intel_finish_page_flip_mmio(struct drm_i915_private *dev_priv, int pipe);
-void intel_check_page_flip(struct drm_i915_private *dev_priv, int pipe);
+
 int intel_prepare_plane_fb(struct drm_plane *plane,
 			   const struct drm_plane_state *new_state);
 void intel_cleanup_plane_fb(struct drm_plane *plane,