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: