Am 02.07.2014 05:55, 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>

Both patches are Reviewed-by: Christian K?nig <christian.koenig at amd.com>

> ---
>
> v2: Rename RADEON_FLIP_SUBMITTED => RADEON_FLIP_READY
>
>   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 | 59 +++-------------------
>   drivers/gpu/drm/radeon/radeon_mode.h    |  3 +-
>   drivers/gpu/drm/radeon/rs600.c          | 28 +++--------
>   drivers/gpu/drm/radeon/rv770.c          | 24 ++-------
>   drivers/gpu/drm/radeon/si.c             | 52 +++-----------------
>   13 files changed, 64 insertions(+), 369 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 54674b7..1f2a960 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);
>   }
>   
>   /**
> @@ -786,7 +754,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]) {
> @@ -795,7 +763,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 baee3cd..662c181 100644
> --- a/drivers/gpu/drm/radeon/radeon_asic.c
> +++ b/drivers/gpu/drm/radeon/radeon_asic.c
> @@ -252,7 +252,6 @@ static struct radeon_asic r100_asic = {
>       },
>       .pflip = {
>               .page_flip = &r100_page_flip,
> -             .page_flip_pending = &r100_page_flip_pending,
>       },
>   };
>   
> @@ -319,7 +318,6 @@ static struct radeon_asic r200_asic = {
>       },
>       .pflip = {
>               .page_flip = &r100_page_flip,
> -             .page_flip_pending = &r100_page_flip_pending,
>       },
>   };
>   
> @@ -400,7 +398,6 @@ static struct radeon_asic r300_asic = {
>       },
>       .pflip = {
>               .page_flip = &r100_page_flip,
> -             .page_flip_pending = &r100_page_flip_pending,
>       },
>   };
>   
> @@ -467,7 +464,6 @@ static struct radeon_asic r300_asic_pcie = {
>       },
>       .pflip = {
>               .page_flip = &r100_page_flip,
> -             .page_flip_pending = &r100_page_flip_pending,
>       },
>   };
>   
> @@ -534,7 +530,6 @@ static struct radeon_asic r420_asic = {
>       },
>       .pflip = {
>               .page_flip = &r100_page_flip,
> -             .page_flip_pending = &r100_page_flip_pending,
>       },
>   };
>   
> @@ -601,7 +596,6 @@ static struct radeon_asic rs400_asic = {
>       },
>       .pflip = {
>               .page_flip = &r100_page_flip,
> -             .page_flip_pending = &r100_page_flip_pending,
>       },
>   };
>   
> @@ -670,7 +664,6 @@ static struct radeon_asic rs600_asic = {
>       },
>       .pflip = {
>               .page_flip = &rs600_page_flip,
> -             .page_flip_pending = &rs600_page_flip_pending,
>       },
>   };
>   
> @@ -739,7 +732,6 @@ static struct radeon_asic rs690_asic = {
>       },
>       .pflip = {
>               .page_flip = &rs600_page_flip,
> -             .page_flip_pending = &rs600_page_flip_pending,
>       },
>   };
>   
> @@ -806,7 +798,6 @@ static struct radeon_asic rv515_asic = {
>       },
>       .pflip = {
>               .page_flip = &rs600_page_flip,
> -             .page_flip_pending = &rs600_page_flip_pending,
>       },
>   };
>   
> @@ -873,7 +864,6 @@ static struct radeon_asic r520_asic = {
>       },
>       .pflip = {
>               .page_flip = &rs600_page_flip,
> -             .page_flip_pending = &rs600_page_flip_pending,
>       },
>   };
>   
> @@ -972,7 +962,6 @@ static struct radeon_asic r600_asic = {
>       },
>       .pflip = {
>               .page_flip = &rs600_page_flip,
> -             .page_flip_pending = &rs600_page_flip_pending,
>       },
>   };
>   
> @@ -1063,7 +1052,6 @@ static struct radeon_asic rv6xx_asic = {
>       },
>       .pflip = {
>               .page_flip = &rs600_page_flip,
> -             .page_flip_pending = &rs600_page_flip_pending,
>       },
>   };
>   
> @@ -1154,7 +1142,6 @@ static struct radeon_asic rs780_asic = {
>       },
>       .pflip = {
>               .page_flip = &rs600_page_flip,
> -             .page_flip_pending = &rs600_page_flip_pending,
>       },
>   };
>   
> @@ -1260,7 +1247,6 @@ static struct radeon_asic rv770_asic = {
>       },
>       .pflip = {
>               .page_flip = &rv770_page_flip,
> -             .page_flip_pending = &rv770_page_flip_pending,
>       },
>   };
>   
> @@ -1379,7 +1365,6 @@ static struct radeon_asic evergreen_asic = {
>       },
>       .pflip = {
>               .page_flip = &evergreen_page_flip,
> -             .page_flip_pending = &evergreen_page_flip_pending,
>       },
>   };
>   
> @@ -1471,7 +1456,6 @@ static struct radeon_asic sumo_asic = {
>       },
>       .pflip = {
>               .page_flip = &evergreen_page_flip,
> -             .page_flip_pending = &evergreen_page_flip_pending,
>       },
>   };
>   
> @@ -1564,7 +1548,6 @@ static struct radeon_asic btc_asic = {
>       },
>       .pflip = {
>               .page_flip = &evergreen_page_flip,
> -             .page_flip_pending = &evergreen_page_flip_pending,
>       },
>   };
>   
> @@ -1708,7 +1691,6 @@ static struct radeon_asic cayman_asic = {
>       },
>       .pflip = {
>               .page_flip = &evergreen_page_flip,
> -             .page_flip_pending = &evergreen_page_flip_pending,
>       },
>   };
>   
> @@ -1809,7 +1791,6 @@ static struct radeon_asic trinity_asic = {
>       },
>       .pflip = {
>               .page_flip = &evergreen_page_flip,
> -             .page_flip_pending = &evergreen_page_flip_pending,
>       },
>   };
>   
> @@ -1940,7 +1921,6 @@ static struct radeon_asic si_asic = {
>       },
>       .pflip = {
>               .page_flip = &evergreen_page_flip,
> -             .page_flip_pending = &evergreen_page_flip_pending,
>       },
>   };
>   
> @@ -2103,7 +2083,6 @@ static struct radeon_asic ci_asic = {
>       },
>       .pflip = {
>               .page_flip = &evergreen_page_flip,
> -             .page_flip_pending = &evergreen_page_flip_pending,
>       },
>   };
>   
> @@ -2208,7 +2187,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 f05270e..b49bfcd 100644
> --- a/drivers/gpu/drm/radeon/radeon_asic.h
> +++ b/drivers/gpu/drm/radeon/radeon_asic.h
> @@ -138,7 +138,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);
>   
> @@ -247,7 +246,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);
> @@ -452,7 +450,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);
> @@ -520,7 +517,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..103d0c6 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
>    *
> @@ -345,15 +301,18 @@ void radeon_crtc_handle_flip(struct radeon_device 
> *rdev, int crtc_id)
>   
>       spin_lock_irqsave(&rdev->ddev->event_lock, flags);
>       work = radeon_crtc->flip_work;
> -     if (radeon_crtc->flip_status != RADEON_FLIP_SUBMITTED) {
> +     if (radeon_crtc->flip_status != RADEON_FLIP_READY) {
>               DRM_DEBUG_DRIVER("radeon_crtc->flip_status = %d != "
> -                              "RADEON_FLIP_SUBMITTED(%d)\n",
> +                              "RADEON_FLIP_READY(%d)\n",
>                                radeon_crtc->flip_status,
> -                              RADEON_FLIP_SUBMITTED);
> +                              RADEON_FLIP_READY);
>               spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
>               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,10 +438,8 @@ 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);
> -
> -     radeon_crtc->flip_status = RADEON_FLIP_SUBMITTED;
> +     work->base = base;
> +     radeon_crtc->flip_status = RADEON_FLIP_READY;
>       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..00955e3 100644
> --- a/drivers/gpu/drm/radeon/radeon_mode.h
> +++ b/drivers/gpu/drm/radeon/radeon_mode.h
> @@ -304,7 +304,7 @@ struct radeon_atom_ss {
>   enum radeon_flip_status {
>       RADEON_FLIP_NONE,
>       RADEON_FLIP_PENDING,
> -     RADEON_FLIP_SUBMITTED
> +     RADEON_FLIP_READY
>   };
>   
>   struct radeon_crtc {
> @@ -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:

Reply via email to