[PATCH 1/2] drm/radeon: Program page flips to execute in hblank instead of vblank

Christian König deathsimple at vodafone.de
Tue Jul 1 03:12:19 PDT 2014


Am 01.07.2014 10:14, schrieb Michel Dänzer:
> From: Michel Dänzer <michel.daenzer at amd.com>
>
> But move the programming back to the vertical blank interrupt handler.
> And signal the flip as being completed immediately after programming it
> to the hardware.
>
> This way we don't have to guess whether or not the hardware will execute
> the flip in a given vertical blank period, avoiding a whole lot of
> trouble.
>
> Also, not using the page flip interrupt anymore avoids problems due to
> completing page flips earlier than expected by userspace.
>
> Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>

I would say to let's nuke rdev->irq.pflip as well and just rely on the 
flip_status to track weather or not there is an page flip scheduled.

Apart from that the two patches look good to me,
Christian.

> ---
>   drivers/gpu/drm/radeon/atombios_crtc.c  | 28 ++++-------
>   drivers/gpu/drm/radeon/cik.c            | 58 +++-------------------
>   drivers/gpu/drm/radeon/evergreen.c      | 86 +++++----------------------------
>   drivers/gpu/drm/radeon/r100.c           | 48 +++---------------
>   drivers/gpu/drm/radeon/r600.c           | 18 +------
>   drivers/gpu/drm/radeon/radeon.h         |  3 +-
>   drivers/gpu/drm/radeon/radeon_asic.c    | 22 ---------
>   drivers/gpu/drm/radeon/radeon_asic.h    |  4 --
>   drivers/gpu/drm/radeon/radeon_display.c | 51 ++-----------------
>   drivers/gpu/drm/radeon/radeon_mode.h    |  1 -
>   drivers/gpu/drm/radeon/rs600.c          | 28 +++--------
>   drivers/gpu/drm/radeon/rv770.c          | 24 ++-------
>   drivers/gpu/drm/radeon/si.c             | 52 +++-----------------
>   13 files changed, 59 insertions(+), 364 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
> index e911898..65cfdbb 100644
> --- a/drivers/gpu/drm/radeon/atombios_crtc.c
> +++ b/drivers/gpu/drm/radeon/atombios_crtc.c
> @@ -1284,6 +1284,10 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
>   		break;
>   	}
>   
> +	/* Make sure updates happen at vertical blank */
> +	WREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, 0);
> +	WREG32(EVERGREEN_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0);
> +
>   	WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset,
>   	       upper_32_bits(fb_location));
>   	WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset,
> @@ -1321,15 +1325,6 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
>   	WREG32(EVERGREEN_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
>   	       (viewport_w << 16) | viewport_h);
>   
> -	/* pageflip setup */
> -	/* make sure flip is at vb rather than hb */
> -	tmp = RREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset);
> -	tmp &= ~EVERGREEN_GRPH_SURFACE_UPDATE_H_RETRACE_EN;
> -	WREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, tmp);
> -
> -	/* set pageflip to happen anywhere in vblank interval */
> -	WREG32(EVERGREEN_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0);
> -
>   	if (!atomic && fb && fb != crtc->primary->fb) {
>   		radeon_fb = to_radeon_framebuffer(fb);
>   		rbo = gem_to_radeon_bo(radeon_fb->obj);
> @@ -1360,7 +1355,7 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc,
>   	uint64_t fb_location;
>   	uint32_t fb_format, fb_pitch_pixels, tiling_flags;
>   	u32 fb_swap = R600_D1GRPH_SWAP_ENDIAN_NONE;
> -	u32 tmp, viewport_w, viewport_h;
> +	u32 viewport_w, viewport_h;
>   	int r;
>   
>   	/* no fb bound */
> @@ -1451,6 +1446,10 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc,
>   	else
>   		WREG32(AVIVO_D2VGA_CONTROL, 0);
>   
> +	/* Make sure updates happen at vertical blank */
> +	WREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, 0);
> +	WREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0);
> +
>   	if (rdev->family >= CHIP_RV770) {
>   		if (radeon_crtc->crtc_id) {
>   			WREG32(R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location));
> @@ -1490,15 +1489,6 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc,
>   	WREG32(AVIVO_D1MODE_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
>   	       (viewport_w << 16) | viewport_h);
>   
> -	/* pageflip setup */
> -	/* make sure flip is at vb rather than hb */
> -	tmp = RREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset);
> -	tmp &= ~AVIVO_D1GRPH_SURFACE_UPDATE_H_RETRACE_EN;
> -	WREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, tmp);
> -
> -	/* set pageflip to happen anywhere in vblank interval */
> -	WREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0);
> -
>   	if (!atomic && fb && fb != crtc->primary->fb) {
>   		radeon_fb = to_radeon_framebuffer(fb);
>   		rbo = gem_to_radeon_bo(radeon_fb->obj);
> diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
> index 0f4b38f..d0a994c 100644
> --- a/drivers/gpu/drm/radeon/cik.c
> +++ b/drivers/gpu/drm/radeon/cik.c
> @@ -7143,25 +7143,6 @@ int cik_irq_set(struct radeon_device *rdev)
>   		WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, crtc6);
>   	}
>   
> -	if (rdev->num_crtc >= 2) {
> -		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET,
> -		       GRPH_PFLIP_INT_MASK);
> -		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET,
> -		       GRPH_PFLIP_INT_MASK);
> -	}
> -	if (rdev->num_crtc >= 4) {
> -		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET,
> -		       GRPH_PFLIP_INT_MASK);
> -		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET,
> -		       GRPH_PFLIP_INT_MASK);
> -	}
> -	if (rdev->num_crtc >= 6) {
> -		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET,
> -		       GRPH_PFLIP_INT_MASK);
> -		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET,
> -		       GRPH_PFLIP_INT_MASK);
> -	}
> -
>   	WREG32(DC_HPD1_INT_CONTROL, hpd1);
>   	WREG32(DC_HPD2_INT_CONTROL, hpd2);
>   	WREG32(DC_HPD3_INT_CONTROL, hpd3);
> @@ -7215,12 +7196,6 @@ static inline void cik_irq_ack(struct radeon_device *rdev)
>   			EVERGREEN_CRTC5_REGISTER_OFFSET);
>   	}
>   
> -	if (rdev->irq.stat_regs.cik.d1grph_int & GRPH_PFLIP_INT_OCCURRED)
> -		WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET,
> -		       GRPH_PFLIP_INT_CLEAR);
> -	if (rdev->irq.stat_regs.cik.d2grph_int & GRPH_PFLIP_INT_OCCURRED)
> -		WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET,
> -		       GRPH_PFLIP_INT_CLEAR);
>   	if (rdev->irq.stat_regs.cik.disp_int & LB_D1_VBLANK_INTERRUPT)
>   		WREG32(LB_VBLANK_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VBLANK_ACK);
>   	if (rdev->irq.stat_regs.cik.disp_int & LB_D1_VLINE_INTERRUPT)
> @@ -7231,12 +7206,6 @@ static inline void cik_irq_ack(struct radeon_device *rdev)
>   		WREG32(LB_VLINE_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VLINE_ACK);
>   
>   	if (rdev->num_crtc >= 4) {
> -		if (rdev->irq.stat_regs.cik.d3grph_int & GRPH_PFLIP_INT_OCCURRED)
> -			WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET,
> -			       GRPH_PFLIP_INT_CLEAR);
> -		if (rdev->irq.stat_regs.cik.d4grph_int & GRPH_PFLIP_INT_OCCURRED)
> -			WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET,
> -			       GRPH_PFLIP_INT_CLEAR);
>   		if (rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT)
>   			WREG32(LB_VBLANK_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VBLANK_ACK);
>   		if (rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VLINE_INTERRUPT)
> @@ -7248,12 +7217,6 @@ static inline void cik_irq_ack(struct radeon_device *rdev)
>   	}
>   
>   	if (rdev->num_crtc >= 6) {
> -		if (rdev->irq.stat_regs.cik.d5grph_int & GRPH_PFLIP_INT_OCCURRED)
> -			WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET,
> -			       GRPH_PFLIP_INT_CLEAR);
> -		if (rdev->irq.stat_regs.cik.d6grph_int & GRPH_PFLIP_INT_OCCURRED)
> -			WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET,
> -			       GRPH_PFLIP_INT_CLEAR);
>   		if (rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT)
>   			WREG32(LB_VBLANK_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VBLANK_ACK);
>   		if (rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VLINE_INTERRUPT)
> @@ -7459,7 +7422,7 @@ restart_ih:
>   						wake_up(&rdev->irq.vblank_queue);
>   					}
>   					if (atomic_read(&rdev->irq.pflip[0]))
> -						radeon_crtc_handle_vblank(rdev, 0);
> +						radeon_crtc_handle_flip(rdev, 0);
>   					rdev->irq.stat_regs.cik.disp_int &= ~LB_D1_VBLANK_INTERRUPT;
>   					DRM_DEBUG("IH: D1 vblank\n");
>   				}
> @@ -7485,7 +7448,7 @@ restart_ih:
>   						wake_up(&rdev->irq.vblank_queue);
>   					}
>   					if (atomic_read(&rdev->irq.pflip[1]))
> -						radeon_crtc_handle_vblank(rdev, 1);
> +						radeon_crtc_handle_flip(rdev, 1);
>   					rdev->irq.stat_regs.cik.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT;
>   					DRM_DEBUG("IH: D2 vblank\n");
>   				}
> @@ -7511,7 +7474,7 @@ restart_ih:
>   						wake_up(&rdev->irq.vblank_queue);
>   					}
>   					if (atomic_read(&rdev->irq.pflip[2]))
> -						radeon_crtc_handle_vblank(rdev, 2);
> +						radeon_crtc_handle_flip(rdev, 2);
>   					rdev->irq.stat_regs.cik.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT;
>   					DRM_DEBUG("IH: D3 vblank\n");
>   				}
> @@ -7537,7 +7500,7 @@ restart_ih:
>   						wake_up(&rdev->irq.vblank_queue);
>   					}
>   					if (atomic_read(&rdev->irq.pflip[3]))
> -						radeon_crtc_handle_vblank(rdev, 3);
> +						radeon_crtc_handle_flip(rdev, 3);
>   					rdev->irq.stat_regs.cik.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT;
>   					DRM_DEBUG("IH: D4 vblank\n");
>   				}
> @@ -7563,7 +7526,7 @@ restart_ih:
>   						wake_up(&rdev->irq.vblank_queue);
>   					}
>   					if (atomic_read(&rdev->irq.pflip[4]))
> -						radeon_crtc_handle_vblank(rdev, 4);
> +						radeon_crtc_handle_flip(rdev, 4);
>   					rdev->irq.stat_regs.cik.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT;
>   					DRM_DEBUG("IH: D5 vblank\n");
>   				}
> @@ -7589,7 +7552,7 @@ restart_ih:
>   						wake_up(&rdev->irq.vblank_queue);
>   					}
>   					if (atomic_read(&rdev->irq.pflip[5]))
> -						radeon_crtc_handle_vblank(rdev, 5);
> +						radeon_crtc_handle_flip(rdev, 5);
>   					rdev->irq.stat_regs.cik.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT;
>   					DRM_DEBUG("IH: D6 vblank\n");
>   				}
> @@ -7605,15 +7568,6 @@ restart_ih:
>   				break;
>   			}
>   			break;
> -		case 8: /* D1 page flip */
> -		case 10: /* D2 page flip */
> -		case 12: /* D3 page flip */
> -		case 14: /* D4 page flip */
> -		case 16: /* D5 page flip */
> -		case 18: /* D6 page flip */
> -			DRM_DEBUG("IH: D%d flip\n", ((src_id - 8) >> 1) + 1);
> -			radeon_crtc_handle_flip(rdev, (src_id - 8) >> 1);
> -			break;
>   		case 42: /* HPD hotplug */
>   			switch (src_data) {
>   			case 0:
> diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
> index 0443183..e7d685a 100644
> --- a/drivers/gpu/drm/radeon/evergreen.c
> +++ b/drivers/gpu/drm/radeon/evergreen.c
> @@ -1308,16 +1308,15 @@ void dce4_wait_for_vblank(struct radeon_device *rdev, int crtc)
>    * @crtc_base: new address of the crtc (GPU MC address)
>    *
>    * Does the actual pageflip (evergreen+).
> - * During vblank we take the crtc lock and wait for the update_pending
> - * bit to go high, when it does, we release the lock, and allow the
> - * double buffered update to take place.
> - * Returns the current update pending status.
>    */
>   void evergreen_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
>   {
>   	struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
>   	u32 tmp = RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset);
> -	int i;
> +
> +	/* Take surface updates at horizontal blank */
> +	WREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset,
> +	       EVERGREEN_GRPH_SURFACE_UPDATE_H_RETRACE_EN);
>   
>   	/* Lock the graphics update lock */
>   	tmp |= EVERGREEN_GRPH_UPDATE_LOCK;
> @@ -1334,36 +1333,11 @@ void evergreen_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
>   	WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
>   	       (u32)crtc_base);
>   
> -	/* Wait for update_pending to go high. */
> -	for (i = 0; i < rdev->usec_timeout; i++) {
> -		if (RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset) & EVERGREEN_GRPH_SURFACE_UPDATE_PENDING)
> -			break;
> -		udelay(1);
> -	}
> -	DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n");
> -
> -	/* Unlock the lock, so double-buffering can take place inside vblank */
> +	/* Unlock the lock, so double-buffering can take place inside hblank */
>   	tmp &= ~EVERGREEN_GRPH_UPDATE_LOCK;
>   	WREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset, tmp);
>   }
>   
> -/**
> - * evergreen_page_flip_pending - check if page flip is still pending
> - *
> - * @rdev: radeon_device pointer
> - * @crtc_id: crtc to check
> - *
> - * Returns the current update pending status.
> - */
> -bool evergreen_page_flip_pending(struct radeon_device *rdev, int crtc_id)
> -{
> -	struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
> -
> -	/* Return current update_pending status: */
> -	return !!(RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset) &
> -		EVERGREEN_GRPH_SURFACE_UPDATE_PENDING);
> -}
> -
>   /* get temperature in millidegrees */
>   int evergreen_get_temp(struct radeon_device *rdev)
>   {
> @@ -4541,23 +4515,6 @@ int evergreen_irq_set(struct radeon_device *rdev)
>   		WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, crtc6);
>   	}
>   
> -	WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET,
> -	       GRPH_PFLIP_INT_MASK);
> -	WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET,
> -	       GRPH_PFLIP_INT_MASK);
> -	if (rdev->num_crtc >= 4) {
> -		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET,
> -		       GRPH_PFLIP_INT_MASK);
> -		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET,
> -		       GRPH_PFLIP_INT_MASK);
> -	}
> -	if (rdev->num_crtc >= 6) {
> -		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET,
> -		       GRPH_PFLIP_INT_MASK);
> -		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET,
> -		       GRPH_PFLIP_INT_MASK);
> -	}
> -
>   	WREG32(DC_HPD1_INT_CONTROL, hpd1);
>   	WREG32(DC_HPD2_INT_CONTROL, hpd2);
>   	WREG32(DC_HPD3_INT_CONTROL, hpd3);
> @@ -4607,10 +4564,6 @@ static void evergreen_irq_ack(struct radeon_device *rdev)
>   	rdev->irq.stat_regs.evergreen.afmt_status5 = RREG32(AFMT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET);
>   	rdev->irq.stat_regs.evergreen.afmt_status6 = RREG32(AFMT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET);
>   
> -	if (rdev->irq.stat_regs.evergreen.d1grph_int & GRPH_PFLIP_INT_OCCURRED)
> -		WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
> -	if (rdev->irq.stat_regs.evergreen.d2grph_int & GRPH_PFLIP_INT_OCCURRED)
> -		WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
>   	if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VBLANK_INTERRUPT)
>   		WREG32(VBLANK_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VBLANK_ACK);
>   	if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VLINE_INTERRUPT)
> @@ -4621,10 +4574,6 @@ static void evergreen_irq_ack(struct radeon_device *rdev)
>   		WREG32(VLINE_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VLINE_ACK);
>   
>   	if (rdev->num_crtc >= 4) {
> -		if (rdev->irq.stat_regs.evergreen.d3grph_int & GRPH_PFLIP_INT_OCCURRED)
> -			WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
> -		if (rdev->irq.stat_regs.evergreen.d4grph_int & GRPH_PFLIP_INT_OCCURRED)
> -			WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
>   		if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT)
>   			WREG32(VBLANK_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VBLANK_ACK);
>   		if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT)
> @@ -4636,10 +4585,6 @@ static void evergreen_irq_ack(struct radeon_device *rdev)
>   	}
>   
>   	if (rdev->num_crtc >= 6) {
> -		if (rdev->irq.stat_regs.evergreen.d5grph_int & GRPH_PFLIP_INT_OCCURRED)
> -			WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
> -		if (rdev->irq.stat_regs.evergreen.d6grph_int & GRPH_PFLIP_INT_OCCURRED)
> -			WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
>   		if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT)
>   			WREG32(VBLANK_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VBLANK_ACK);
>   		if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT)
> @@ -4798,7 +4743,7 @@ restart_ih:
>   						wake_up(&rdev->irq.vblank_queue);
>   					}
>   					if (atomic_read(&rdev->irq.pflip[0]))
> -						radeon_crtc_handle_vblank(rdev, 0);
> +						radeon_crtc_handle_flip(rdev, 0);
>   					rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VBLANK_INTERRUPT;
>   					DRM_DEBUG("IH: D1 vblank\n");
>   				}
> @@ -4824,7 +4769,7 @@ restart_ih:
>   						wake_up(&rdev->irq.vblank_queue);
>   					}
>   					if (atomic_read(&rdev->irq.pflip[1]))
> -						radeon_crtc_handle_vblank(rdev, 1);
> +						radeon_crtc_handle_flip(rdev, 1);
>   					rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT;
>   					DRM_DEBUG("IH: D2 vblank\n");
>   				}
> @@ -4850,7 +4795,7 @@ restart_ih:
>   						wake_up(&rdev->irq.vblank_queue);
>   					}
>   					if (atomic_read(&rdev->irq.pflip[2]))
> -						radeon_crtc_handle_vblank(rdev, 2);
> +						radeon_crtc_handle_flip(rdev, 2);
>   					rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT;
>   					DRM_DEBUG("IH: D3 vblank\n");
>   				}
> @@ -4876,7 +4821,7 @@ restart_ih:
>   						wake_up(&rdev->irq.vblank_queue);
>   					}
>   					if (atomic_read(&rdev->irq.pflip[3]))
> -						radeon_crtc_handle_vblank(rdev, 3);
> +						radeon_crtc_handle_flip(rdev, 3);
>   					rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT;
>   					DRM_DEBUG("IH: D4 vblank\n");
>   				}
> @@ -4902,7 +4847,7 @@ restart_ih:
>   						wake_up(&rdev->irq.vblank_queue);
>   					}
>   					if (atomic_read(&rdev->irq.pflip[4]))
> -						radeon_crtc_handle_vblank(rdev, 4);
> +						radeon_crtc_handle_flip(rdev, 4);
>   					rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT;
>   					DRM_DEBUG("IH: D5 vblank\n");
>   				}
> @@ -4928,7 +4873,7 @@ restart_ih:
>   						wake_up(&rdev->irq.vblank_queue);
>   					}
>   					if (atomic_read(&rdev->irq.pflip[5]))
> -						radeon_crtc_handle_vblank(rdev, 5);
> +						radeon_crtc_handle_flip(rdev, 5);
>   					rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT;
>   					DRM_DEBUG("IH: D6 vblank\n");
>   				}
> @@ -4944,15 +4889,6 @@ restart_ih:
>   				break;
>   			}
>   			break;
> -		case 8: /* D1 page flip */
> -		case 10: /* D2 page flip */
> -		case 12: /* D3 page flip */
> -		case 14: /* D4 page flip */
> -		case 16: /* D5 page flip */
> -		case 18: /* D6 page flip */
> -			DRM_DEBUG("IH: D%d flip\n", ((src_id - 8) >> 1) + 1);
> -			radeon_crtc_handle_flip(rdev, (src_id - 8) >> 1);
> -			break;
>   		case 42: /* HPD hotplug */
>   			switch (src_data) {
>   			case 0:
> diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
> index ad99813..8d9f092 100644
> --- a/drivers/gpu/drm/radeon/r100.c
> +++ b/drivers/gpu/drm/radeon/r100.c
> @@ -149,50 +149,18 @@ void r100_wait_for_vblank(struct radeon_device *rdev, int crtc)
>    * @crtc_base: new address of the crtc (GPU MC address)
>    *
>    * Does the actual pageflip (r1xx-r4xx).
> - * During vblank we take the crtc lock and wait for the update_pending
> - * bit to go high, when it does, we release the lock, and allow the
> - * double buffered update to take place.
>    */
>   void r100_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
>   {
>   	struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
> -	u32 tmp = ((u32)crtc_base) | RADEON_CRTC_OFFSET__OFFSET_LOCK;
> -	int i;
> -
> -	/* Lock the graphics update lock */
> -	/* update the scanout addresses */
> -	WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, tmp);
> +	u32 crtc_offset_cntl = RREG32(RADEON_CRTC_OFFSET_CNTL);
>   
> -	/* Wait for update_pending to go high. */
> -	for (i = 0; i < rdev->usec_timeout; i++) {
> -		if (RREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset) & RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET)
> -			break;
> -		udelay(1);
> -	}
> -	DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n");
> -
> -	/* Unlock the lock, so double-buffering can take place inside vblank */
> -	tmp &= ~RADEON_CRTC_OFFSET__OFFSET_LOCK;
> -	WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, tmp);
> -
> -}
> -
> -/**
> - * r100_page_flip_pending - check if page flip is still pending
> - *
> - * @rdev: radeon_device pointer
> - * @crtc_id: crtc to check
> - *
> - * Check if the last pagefilp is still pending (r1xx-r4xx).
> - * Returns the current update pending status.
> - */
> -bool r100_page_flip_pending(struct radeon_device *rdev, int crtc_id)
> -{
> -	struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
> +	/* Take surface updates at horizontal blank */
> +	WREG32(RADEON_CRTC_OFFSET_CNTL,
> +	       crtc_offset_cntl | RADEON_CRTC_OFFSET_FLIP_CNTL);
>   
> -	/* Return current update_pending status: */
> -	return !!(RREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset) &
> -		RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET);
> +	/* Update the scanout address */
> +	WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, crtc_base);
>   }
>   
>   /**
> @@ -779,7 +747,7 @@ int r100_irq_process(struct radeon_device *rdev)
>   				wake_up(&rdev->irq.vblank_queue);
>   			}
>   			if (atomic_read(&rdev->irq.pflip[0]))
> -				radeon_crtc_handle_vblank(rdev, 0);
> +				radeon_crtc_handle_flip(rdev, 0);
>   		}
>   		if (status & RADEON_CRTC2_VBLANK_STAT) {
>   			if (rdev->irq.crtc_vblank_int[1]) {
> @@ -788,7 +756,7 @@ int r100_irq_process(struct radeon_device *rdev)
>   				wake_up(&rdev->irq.vblank_queue);
>   			}
>   			if (atomic_read(&rdev->irq.pflip[1]))
> -				radeon_crtc_handle_vblank(rdev, 1);
> +				radeon_crtc_handle_flip(rdev, 1);
>   		}
>   		if (status & RADEON_FP_DETECT_STAT) {
>   			queue_hotplug = true;
> diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
> index ae54f76..8f318ec 100644
> --- a/drivers/gpu/drm/radeon/r600.c
> +++ b/drivers/gpu/drm/radeon/r600.c
> @@ -3614,8 +3614,6 @@ int r600_irq_set(struct radeon_device *rdev)
>   	WREG32(CP_INT_CNTL, cp_int_cntl);
>   	WREG32(DMA_CNTL, dma_cntl);
>   	WREG32(DxMODE_INT_MASK, mode_int);
> -	WREG32(D1GRPH_INTERRUPT_CONTROL, DxGRPH_PFLIP_INT_MASK);
> -	WREG32(D2GRPH_INTERRUPT_CONTROL, DxGRPH_PFLIP_INT_MASK);
>   	WREG32(GRBM_INT_CNTL, grbm_int_cntl);
>   	if (ASIC_IS_DCE3(rdev)) {
>   		WREG32(DC_HPD1_INT_CONTROL, hpd1);
> @@ -3672,10 +3670,6 @@ static void r600_irq_ack(struct radeon_device *rdev)
>   	rdev->irq.stat_regs.r600.d1grph_int = RREG32(D1GRPH_INTERRUPT_STATUS);
>   	rdev->irq.stat_regs.r600.d2grph_int = RREG32(D2GRPH_INTERRUPT_STATUS);
>   
> -	if (rdev->irq.stat_regs.r600.d1grph_int & DxGRPH_PFLIP_INT_OCCURRED)
> -		WREG32(D1GRPH_INTERRUPT_STATUS, DxGRPH_PFLIP_INT_CLEAR);
> -	if (rdev->irq.stat_regs.r600.d2grph_int & DxGRPH_PFLIP_INT_OCCURRED)
> -		WREG32(D2GRPH_INTERRUPT_STATUS, DxGRPH_PFLIP_INT_CLEAR);
>   	if (rdev->irq.stat_regs.r600.disp_int & LB_D1_VBLANK_INTERRUPT)
>   		WREG32(D1MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK);
>   	if (rdev->irq.stat_regs.r600.disp_int & LB_D1_VLINE_INTERRUPT)
> @@ -3876,7 +3870,7 @@ restart_ih:
>   						wake_up(&rdev->irq.vblank_queue);
>   					}
>   					if (atomic_read(&rdev->irq.pflip[0]))
> -						radeon_crtc_handle_vblank(rdev, 0);
> +						radeon_crtc_handle_flip(rdev, 0);
>   					rdev->irq.stat_regs.r600.disp_int &= ~LB_D1_VBLANK_INTERRUPT;
>   					DRM_DEBUG("IH: D1 vblank\n");
>   				}
> @@ -3902,7 +3896,7 @@ restart_ih:
>   						wake_up(&rdev->irq.vblank_queue);
>   					}
>   					if (atomic_read(&rdev->irq.pflip[1]))
> -						radeon_crtc_handle_vblank(rdev, 1);
> +						radeon_crtc_handle_flip(rdev, 1);
>   					rdev->irq.stat_regs.r600.disp_int &= ~LB_D2_VBLANK_INTERRUPT;
>   					DRM_DEBUG("IH: D2 vblank\n");
>   				}
> @@ -3918,14 +3912,6 @@ restart_ih:
>   				break;
>   			}
>   			break;
> -		case 9: /* D1 pflip */
> -			DRM_DEBUG("IH: D1 flip\n");
> -			radeon_crtc_handle_flip(rdev, 0);
> -			break;
> -		case 11: /* D2 pflip */
> -			DRM_DEBUG("IH: D2 flip\n");
> -			radeon_crtc_handle_flip(rdev, 1);
> -			break;
>   		case 19: /* HPD/DAC hotplug */
>   			switch (src_data) {
>   			case 0:
> diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
> index 8e8ef08..7a45c93 100644
> --- a/drivers/gpu/drm/radeon/radeon.h
> +++ b/drivers/gpu/drm/radeon/radeon.h
> @@ -681,6 +681,7 @@ struct radeon_flip_work {
>   	struct work_struct		unpin_work;
>   	struct radeon_device		*rdev;
>   	int				crtc_id;
> +	uint64_t			base;
>   	struct drm_framebuffer		*fb;
>   	struct drm_pending_vblank_event *event;
>   	struct radeon_bo		*old_rbo;
> @@ -1884,7 +1885,6 @@ struct radeon_asic {
>   	/* pageflipping */
>   	struct {
>   		void (*page_flip)(struct radeon_device *rdev, int crtc, u64 crtc_base);
> -		bool (*page_flip_pending)(struct radeon_device *rdev, int crtc);
>   	} pflip;
>   };
>   
> @@ -2746,7 +2746,6 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v);
>   #define radeon_pm_init_profile(rdev) (rdev)->asic->pm.init_profile((rdev))
>   #define radeon_pm_get_dynpm_state(rdev) (rdev)->asic->pm.get_dynpm_state((rdev))
>   #define radeon_page_flip(rdev, crtc, base) (rdev)->asic->pflip.page_flip((rdev), (crtc), (base))
> -#define radeon_page_flip_pending(rdev, crtc) (rdev)->asic->pflip.page_flip_pending((rdev), (crtc))
>   #define radeon_wait_for_vblank(rdev, crtc) (rdev)->asic->display.wait_for_vblank((rdev), (crtc))
>   #define radeon_mc_wait_for_idle(rdev) (rdev)->asic->mc_wait_for_idle((rdev))
>   #define radeon_get_xclk(rdev) (rdev)->asic->get_xclk((rdev))
> diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c
> index 7ef3fc6..9943fb1 100644
> --- a/drivers/gpu/drm/radeon/radeon_asic.c
> +++ b/drivers/gpu/drm/radeon/radeon_asic.c
> @@ -249,7 +249,6 @@ static struct radeon_asic r100_asic = {
>   	},
>   	.pflip = {
>   		.page_flip = &r100_page_flip,
> -		.page_flip_pending = &r100_page_flip_pending,
>   	},
>   };
>   
> @@ -315,7 +314,6 @@ static struct radeon_asic r200_asic = {
>   	},
>   	.pflip = {
>   		.page_flip = &r100_page_flip,
> -		.page_flip_pending = &r100_page_flip_pending,
>   	},
>   };
>   
> @@ -395,7 +393,6 @@ static struct radeon_asic r300_asic = {
>   	},
>   	.pflip = {
>   		.page_flip = &r100_page_flip,
> -		.page_flip_pending = &r100_page_flip_pending,
>   	},
>   };
>   
> @@ -461,7 +458,6 @@ static struct radeon_asic r300_asic_pcie = {
>   	},
>   	.pflip = {
>   		.page_flip = &r100_page_flip,
> -		.page_flip_pending = &r100_page_flip_pending,
>   	},
>   };
>   
> @@ -527,7 +523,6 @@ static struct radeon_asic r420_asic = {
>   	},
>   	.pflip = {
>   		.page_flip = &r100_page_flip,
> -		.page_flip_pending = &r100_page_flip_pending,
>   	},
>   };
>   
> @@ -593,7 +588,6 @@ static struct radeon_asic rs400_asic = {
>   	},
>   	.pflip = {
>   		.page_flip = &r100_page_flip,
> -		.page_flip_pending = &r100_page_flip_pending,
>   	},
>   };
>   
> @@ -662,7 +656,6 @@ static struct radeon_asic rs600_asic = {
>   	},
>   	.pflip = {
>   		.page_flip = &rs600_page_flip,
> -		.page_flip_pending = &rs600_page_flip_pending,
>   	},
>   };
>   
> @@ -730,7 +723,6 @@ static struct radeon_asic rs690_asic = {
>   	},
>   	.pflip = {
>   		.page_flip = &rs600_page_flip,
> -		.page_flip_pending = &rs600_page_flip_pending,
>   	},
>   };
>   
> @@ -796,7 +788,6 @@ static struct radeon_asic rv515_asic = {
>   	},
>   	.pflip = {
>   		.page_flip = &rs600_page_flip,
> -		.page_flip_pending = &rs600_page_flip_pending,
>   	},
>   };
>   
> @@ -862,7 +853,6 @@ static struct radeon_asic r520_asic = {
>   	},
>   	.pflip = {
>   		.page_flip = &rs600_page_flip,
> -		.page_flip_pending = &rs600_page_flip_pending,
>   	},
>   };
>   
> @@ -961,7 +951,6 @@ static struct radeon_asic r600_asic = {
>   	},
>   	.pflip = {
>   		.page_flip = &rs600_page_flip,
> -		.page_flip_pending = &rs600_page_flip_pending,
>   	},
>   };
>   
> @@ -1052,7 +1041,6 @@ static struct radeon_asic rv6xx_asic = {
>   	},
>   	.pflip = {
>   		.page_flip = &rs600_page_flip,
> -		.page_flip_pending = &rs600_page_flip_pending,
>   	},
>   };
>   
> @@ -1143,7 +1131,6 @@ static struct radeon_asic rs780_asic = {
>   	},
>   	.pflip = {
>   		.page_flip = &rs600_page_flip,
> -		.page_flip_pending = &rs600_page_flip_pending,
>   	},
>   };
>   
> @@ -1249,7 +1236,6 @@ static struct radeon_asic rv770_asic = {
>   	},
>   	.pflip = {
>   		.page_flip = &rv770_page_flip,
> -		.page_flip_pending = &rv770_page_flip_pending,
>   	},
>   };
>   
> @@ -1368,7 +1354,6 @@ static struct radeon_asic evergreen_asic = {
>   	},
>   	.pflip = {
>   		.page_flip = &evergreen_page_flip,
> -		.page_flip_pending = &evergreen_page_flip_pending,
>   	},
>   };
>   
> @@ -1460,7 +1445,6 @@ static struct radeon_asic sumo_asic = {
>   	},
>   	.pflip = {
>   		.page_flip = &evergreen_page_flip,
> -		.page_flip_pending = &evergreen_page_flip_pending,
>   	},
>   };
>   
> @@ -1553,7 +1537,6 @@ static struct radeon_asic btc_asic = {
>   	},
>   	.pflip = {
>   		.page_flip = &evergreen_page_flip,
> -		.page_flip_pending = &evergreen_page_flip_pending,
>   	},
>   };
>   
> @@ -1697,7 +1680,6 @@ static struct radeon_asic cayman_asic = {
>   	},
>   	.pflip = {
>   		.page_flip = &evergreen_page_flip,
> -		.page_flip_pending = &evergreen_page_flip_pending,
>   	},
>   };
>   
> @@ -1798,7 +1780,6 @@ static struct radeon_asic trinity_asic = {
>   	},
>   	.pflip = {
>   		.page_flip = &evergreen_page_flip,
> -		.page_flip_pending = &evergreen_page_flip_pending,
>   	},
>   };
>   
> @@ -1929,7 +1910,6 @@ static struct radeon_asic si_asic = {
>   	},
>   	.pflip = {
>   		.page_flip = &evergreen_page_flip,
> -		.page_flip_pending = &evergreen_page_flip_pending,
>   	},
>   };
>   
> @@ -2092,7 +2072,6 @@ static struct radeon_asic ci_asic = {
>   	},
>   	.pflip = {
>   		.page_flip = &evergreen_page_flip,
> -		.page_flip_pending = &evergreen_page_flip_pending,
>   	},
>   };
>   
> @@ -2197,7 +2176,6 @@ static struct radeon_asic kv_asic = {
>   	},
>   	.pflip = {
>   		.page_flip = &evergreen_page_flip,
> -		.page_flip_pending = &evergreen_page_flip_pending,
>   	},
>   };
>   
> diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
> index 645a3de..170a80c 100644
> --- a/drivers/gpu/drm/radeon/radeon_asic.h
> +++ b/drivers/gpu/drm/radeon/radeon_asic.h
> @@ -137,7 +137,6 @@ extern void r100_pm_init_profile(struct radeon_device *rdev);
>   extern void r100_pm_get_dynpm_state(struct radeon_device *rdev);
>   extern void r100_page_flip(struct radeon_device *rdev, int crtc,
>   			   u64 crtc_base);
> -extern bool r100_page_flip_pending(struct radeon_device *rdev, int crtc);
>   extern void r100_wait_for_vblank(struct radeon_device *rdev, int crtc);
>   extern int r100_mc_wait_for_idle(struct radeon_device *rdev);
>   
> @@ -244,7 +243,6 @@ extern void rs600_pm_prepare(struct radeon_device *rdev);
>   extern void rs600_pm_finish(struct radeon_device *rdev);
>   extern void rs600_page_flip(struct radeon_device *rdev, int crtc,
>   			    u64 crtc_base);
> -extern bool rs600_page_flip_pending(struct radeon_device *rdev, int crtc);
>   void rs600_set_safe_registers(struct radeon_device *rdev);
>   extern void avivo_wait_for_vblank(struct radeon_device *rdev, int crtc);
>   extern int rs600_mc_wait_for_idle(struct radeon_device *rdev);
> @@ -449,7 +447,6 @@ int rv770_suspend(struct radeon_device *rdev);
>   int rv770_resume(struct radeon_device *rdev);
>   void rv770_pm_misc(struct radeon_device *rdev);
>   void rv770_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base);
> -bool rv770_page_flip_pending(struct radeon_device *rdev, int crtc);
>   void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc);
>   void r700_cp_stop(struct radeon_device *rdev);
>   void r700_cp_fini(struct radeon_device *rdev);
> @@ -517,7 +514,6 @@ int sumo_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk);
>   int evergreen_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk);
>   extern void evergreen_page_flip(struct radeon_device *rdev, int crtc,
>   				u64 crtc_base);
> -extern bool evergreen_page_flip_pending(struct radeon_device *rdev, int crtc);
>   extern void dce4_wait_for_vblank(struct radeon_device *rdev, int crtc);
>   void evergreen_disable_interrupt_state(struct radeon_device *rdev);
>   int evergreen_mc_wait_for_idle(struct radeon_device *rdev);
> diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
> index 65882cd..e66323e 100644
> --- a/drivers/gpu/drm/radeon/radeon_display.c
> +++ b/drivers/gpu/drm/radeon/radeon_display.c
> @@ -281,50 +281,6 @@ static void radeon_unpin_work_func(struct work_struct *__work)
>   	kfree(work);
>   }
>   
> -void radeon_crtc_handle_vblank(struct radeon_device *rdev, int crtc_id)
> -{
> -	struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
> -	unsigned long flags;
> -	u32 update_pending;
> -	int vpos, hpos;
> -
> -	/* can happen during initialization */
> -	if (radeon_crtc == NULL)
> -		return;
> -
> -	spin_lock_irqsave(&rdev->ddev->event_lock, flags);
> -	if (radeon_crtc->flip_status != RADEON_FLIP_SUBMITTED) {
> -		DRM_DEBUG_DRIVER("radeon_crtc->flip_status = %d != "
> -				 "RADEON_FLIP_SUBMITTED(%d)\n",
> -				 radeon_crtc->flip_status,
> -				 RADEON_FLIP_SUBMITTED);
> -		spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
> -		return;
> -	}
> -
> -	update_pending = radeon_page_flip_pending(rdev, crtc_id);
> -
> -	/* Has the pageflip already completed in crtc, or is it certain
> -	 * to complete in this vblank?
> -	 */
> -	if (update_pending &&
> -	    (DRM_SCANOUTPOS_VALID & radeon_get_crtc_scanoutpos(rdev->ddev, crtc_id, 0,
> -							       &vpos, &hpos, NULL, NULL)) &&
> -	    ((vpos >= (99 * rdev->mode_info.crtcs[crtc_id]->base.hwmode.crtc_vdisplay)/100) ||
> -	     (vpos < 0 && !ASIC_IS_AVIVO(rdev)))) {
> -		/* crtc didn't flip in this target vblank interval,
> -		 * but flip is pending in crtc. Based on the current
> -		 * scanout position we know that the current frame is
> -		 * (nearly) complete and the flip will (likely)
> -		 * complete before the start of the next frame.
> -		 */
> -		update_pending = 0;
> -	}
> -	spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
> -	if (!update_pending)
> -		radeon_crtc_handle_flip(rdev, crtc_id);
> -}
> -
>   /**
>    * radeon_crtc_handle_flip - page flip completed
>    *
> @@ -354,6 +310,9 @@ void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id)
>   		return;
>   	}
>   
> +	/* do the flip (mmio) */
> +	radeon_page_flip(rdev, radeon_crtc->crtc_id, work->base);
> +
>   	/* Pageflip completed. Clean up. */
>   	radeon_crtc->flip_status = RADEON_FLIP_NONE;
>   	radeon_crtc->flip_work = NULL;
> @@ -479,9 +438,7 @@ static void radeon_flip_work_func(struct work_struct *__work)
>   	/* set the proper interrupt */
>   	radeon_irq_kms_pflip_irq_get(rdev, radeon_crtc->crtc_id);
>   
> -	/* do the flip (mmio) */
> -	radeon_page_flip(rdev, radeon_crtc->crtc_id, base);
> -
> +	work->base = base;
>   	radeon_crtc->flip_status = RADEON_FLIP_SUBMITTED;
>   	spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
>   	up_read(&rdev->exclusive_lock);
> diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
> index ed6b6e0..1810a12 100644
> --- a/drivers/gpu/drm/radeon/radeon_mode.h
> +++ b/drivers/gpu/drm/radeon/radeon_mode.h
> @@ -913,7 +913,6 @@ bool radeon_fbdev_robj_is_fb(struct radeon_device *rdev, struct radeon_bo *robj)
>   
>   void radeon_fb_output_poll_changed(struct radeon_device *rdev);
>   
> -void radeon_crtc_handle_vblank(struct radeon_device *rdev, int crtc_id);
>   void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id);
>   
>   int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp, bool tiled);
> diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c
> index 818f4eb..b5e63a7 100644
> --- a/drivers/gpu/drm/radeon/rs600.c
> +++ b/drivers/gpu/drm/radeon/rs600.c
> @@ -113,7 +113,10 @@ void rs600_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
>   {
>   	struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
>   	u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset);
> -	int i;
> +
> +	/* Take surface updates at horizontal blank */
> +	WREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset,
> +	       AVIVO_D1GRPH_SURFACE_UPDATE_H_RETRACE_EN);
>   
>   	/* Lock the graphics update lock */
>   	tmp |= AVIVO_D1GRPH_UPDATE_LOCK;
> @@ -125,28 +128,11 @@ void rs600_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
>   	WREG32(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
>   	       (u32)crtc_base);
>   
> -	/* Wait for update_pending to go high. */
> -	for (i = 0; i < rdev->usec_timeout; i++) {
> -		if (RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING)
> -			break;
> -		udelay(1);
> -	}
> -	DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n");
> -
> -	/* Unlock the lock, so double-buffering can take place inside vblank */
> +	/* Unlock the lock, so double-buffering can take place inside hblank */
>   	tmp &= ~AVIVO_D1GRPH_UPDATE_LOCK;
>   	WREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset, tmp);
>   }
>   
> -bool rs600_page_flip_pending(struct radeon_device *rdev, int crtc_id)
> -{
> -	struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
> -
> -	/* Return current update_pending status: */
> -	return !!(RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) &
> -		AVIVO_D1GRPH_SURFACE_UPDATE_PENDING);
> -}
> -
>   void avivo_program_fmt(struct drm_encoder *encoder)
>   {
>   	struct drm_device *dev = encoder->dev;
> @@ -790,7 +776,7 @@ int rs600_irq_process(struct radeon_device *rdev)
>   				wake_up(&rdev->irq.vblank_queue);
>   			}
>   			if (atomic_read(&rdev->irq.pflip[0]))
> -				radeon_crtc_handle_vblank(rdev, 0);
> +				radeon_crtc_handle_flip(rdev, 0);
>   		}
>   		if (G_007EDC_LB_D2_VBLANK_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) {
>   			if (rdev->irq.crtc_vblank_int[1]) {
> @@ -799,7 +785,7 @@ int rs600_irq_process(struct radeon_device *rdev)
>   				wake_up(&rdev->irq.vblank_queue);
>   			}
>   			if (atomic_read(&rdev->irq.pflip[1]))
> -				radeon_crtc_handle_vblank(rdev, 1);
> +				radeon_crtc_handle_flip(rdev, 1);
>   		}
>   		if (G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) {
>   			queue_hotplug = true;
> diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
> index 97b7766..ef66be4 100644
> --- a/drivers/gpu/drm/radeon/rv770.c
> +++ b/drivers/gpu/drm/radeon/rv770.c
> @@ -805,7 +805,10 @@ void rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
>   {
>   	struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
>   	u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset);
> -	int i;
> +
> +	/* Take surface updates at horizontal blank */
> +	WREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset,
> +	       AVIVO_D1GRPH_SURFACE_UPDATE_H_RETRACE_EN);
>   
>   	/* Lock the graphics update lock */
>   	tmp |= AVIVO_D1GRPH_UPDATE_LOCK;
> @@ -824,28 +827,11 @@ void rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
>   	WREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
>   	       (u32)crtc_base);
>   
> -	/* Wait for update_pending to go high. */
> -	for (i = 0; i < rdev->usec_timeout; i++) {
> -		if (RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING)
> -			break;
> -		udelay(1);
> -	}
> -	DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n");
> -
> -	/* Unlock the lock, so double-buffering can take place inside vblank */
> +	/* Unlock the lock, so double-buffering can take place inside hblank */
>   	tmp &= ~AVIVO_D1GRPH_UPDATE_LOCK;
>   	WREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset, tmp);
>   }
>   
> -bool rv770_page_flip_pending(struct radeon_device *rdev, int crtc_id)
> -{
> -	struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
> -
> -	/* Return current update_pending status: */
> -	return !!(RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) &
> -		AVIVO_D1GRPH_SURFACE_UPDATE_PENDING);
> -}
> -
>   /* get temperature in millidegrees */
>   int rv770_get_temp(struct radeon_device *rdev)
>   {
> diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
> index c128bde..fee797f 100644
> --- a/drivers/gpu/drm/radeon/si.c
> +++ b/drivers/gpu/drm/radeon/si.c
> @@ -5917,25 +5917,6 @@ int si_irq_set(struct radeon_device *rdev)
>   		WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, crtc6);
>   	}
>   
> -	if (rdev->num_crtc >= 2) {
> -		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET,
> -		       GRPH_PFLIP_INT_MASK);
> -		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET,
> -		       GRPH_PFLIP_INT_MASK);
> -	}
> -	if (rdev->num_crtc >= 4) {
> -		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET,
> -		       GRPH_PFLIP_INT_MASK);
> -		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET,
> -		       GRPH_PFLIP_INT_MASK);
> -	}
> -	if (rdev->num_crtc >= 6) {
> -		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET,
> -		       GRPH_PFLIP_INT_MASK);
> -		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET,
> -		       GRPH_PFLIP_INT_MASK);
> -	}
> -
>   	if (!ASIC_IS_NODCE(rdev)) {
>   		WREG32(DC_HPD1_INT_CONTROL, hpd1);
>   		WREG32(DC_HPD2_INT_CONTROL, hpd2);
> @@ -5974,10 +5955,6 @@ static inline void si_irq_ack(struct radeon_device *rdev)
>   		rdev->irq.stat_regs.evergreen.d6grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET);
>   	}
>   
> -	if (rdev->irq.stat_regs.evergreen.d1grph_int & GRPH_PFLIP_INT_OCCURRED)
> -		WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
> -	if (rdev->irq.stat_regs.evergreen.d2grph_int & GRPH_PFLIP_INT_OCCURRED)
> -		WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
>   	if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VBLANK_INTERRUPT)
>   		WREG32(VBLANK_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VBLANK_ACK);
>   	if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VLINE_INTERRUPT)
> @@ -5988,10 +5965,6 @@ static inline void si_irq_ack(struct radeon_device *rdev)
>   		WREG32(VLINE_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VLINE_ACK);
>   
>   	if (rdev->num_crtc >= 4) {
> -		if (rdev->irq.stat_regs.evergreen.d3grph_int & GRPH_PFLIP_INT_OCCURRED)
> -			WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
> -		if (rdev->irq.stat_regs.evergreen.d4grph_int & GRPH_PFLIP_INT_OCCURRED)
> -			WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
>   		if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT)
>   			WREG32(VBLANK_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VBLANK_ACK);
>   		if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT)
> @@ -6003,10 +5976,6 @@ static inline void si_irq_ack(struct radeon_device *rdev)
>   	}
>   
>   	if (rdev->num_crtc >= 6) {
> -		if (rdev->irq.stat_regs.evergreen.d5grph_int & GRPH_PFLIP_INT_OCCURRED)
> -			WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
> -		if (rdev->irq.stat_regs.evergreen.d6grph_int & GRPH_PFLIP_INT_OCCURRED)
> -			WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
>   		if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT)
>   			WREG32(VBLANK_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VBLANK_ACK);
>   		if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT)
> @@ -6151,7 +6120,7 @@ restart_ih:
>   						wake_up(&rdev->irq.vblank_queue);
>   					}
>   					if (atomic_read(&rdev->irq.pflip[0]))
> -						radeon_crtc_handle_vblank(rdev, 0);
> +						radeon_crtc_handle_flip(rdev, 0);
>   					rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VBLANK_INTERRUPT;
>   					DRM_DEBUG("IH: D1 vblank\n");
>   				}
> @@ -6177,7 +6146,7 @@ restart_ih:
>   						wake_up(&rdev->irq.vblank_queue);
>   					}
>   					if (atomic_read(&rdev->irq.pflip[1]))
> -						radeon_crtc_handle_vblank(rdev, 1);
> +						radeon_crtc_handle_flip(rdev, 1);
>   					rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT;
>   					DRM_DEBUG("IH: D2 vblank\n");
>   				}
> @@ -6203,7 +6172,7 @@ restart_ih:
>   						wake_up(&rdev->irq.vblank_queue);
>   					}
>   					if (atomic_read(&rdev->irq.pflip[2]))
> -						radeon_crtc_handle_vblank(rdev, 2);
> +						radeon_crtc_handle_flip(rdev, 2);
>   					rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT;
>   					DRM_DEBUG("IH: D3 vblank\n");
>   				}
> @@ -6229,7 +6198,7 @@ restart_ih:
>   						wake_up(&rdev->irq.vblank_queue);
>   					}
>   					if (atomic_read(&rdev->irq.pflip[3]))
> -						radeon_crtc_handle_vblank(rdev, 3);
> +						radeon_crtc_handle_flip(rdev, 3);
>   					rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT;
>   					DRM_DEBUG("IH: D4 vblank\n");
>   				}
> @@ -6255,7 +6224,7 @@ restart_ih:
>   						wake_up(&rdev->irq.vblank_queue);
>   					}
>   					if (atomic_read(&rdev->irq.pflip[4]))
> -						radeon_crtc_handle_vblank(rdev, 4);
> +						radeon_crtc_handle_flip(rdev, 4);
>   					rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT;
>   					DRM_DEBUG("IH: D5 vblank\n");
>   				}
> @@ -6281,7 +6250,7 @@ restart_ih:
>   						wake_up(&rdev->irq.vblank_queue);
>   					}
>   					if (atomic_read(&rdev->irq.pflip[5]))
> -						radeon_crtc_handle_vblank(rdev, 5);
> +						radeon_crtc_handle_flip(rdev, 5);
>   					rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT;
>   					DRM_DEBUG("IH: D6 vblank\n");
>   				}
> @@ -6297,15 +6266,6 @@ restart_ih:
>   				break;
>   			}
>   			break;
> -		case 8: /* D1 page flip */
> -		case 10: /* D2 page flip */
> -		case 12: /* D3 page flip */
> -		case 14: /* D4 page flip */
> -		case 16: /* D5 page flip */
> -		case 18: /* D6 page flip */
> -			DRM_DEBUG("IH: D%d flip\n", ((src_id - 8) >> 1) + 1);
> -			radeon_crtc_handle_flip(rdev, (src_id - 8) >> 1);
> -			break;
>   		case 42: /* HPD hotplug */
>   			switch (src_data) {
>   			case 0:



More information about the dri-devel mailing list