[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