WREG32(AVIVO_D1MODE_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
               (viewport_w << 16) | viewport_h);
 
-       /* set pageflip to happen anywhere in vblank interval */
-       WREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0);
+       /* set pageflip to happen only at start of vblank interval (front porch) */
+       WREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 3);
 
        if (!atomic && fb && fb != crtc->primary->fb) {
                radeon_fb = to_radeon_framebuffer(fb);
 
        }
 
        /* Wait until we're out of the vertical blank period before the one
-        * targeted by the flip
+        * targeted by the flip. Always wait on pre DCE4 to avoid races with
+        * flip completion handling from vblank irq, as these old asics don't
+        * have reliable pageflip completion interrupts.
         */
        while (radeon_crtc->enabled &&
-              (radeon_get_crtc_scanoutpos(dev, work->crtc_id, 0,
-                                          &vpos, &hpos, NULL, NULL,
-                                          &crtc->hwmode)
+               (radeon_get_crtc_scanoutpos(dev, work->crtc_id, 0,
+                                           &vpos, &hpos, NULL, NULL,
+                                           &crtc->hwmode)
                & (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_IN_VBLANK)) ==
-              (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_IN_VBLANK) &&
-              (int)(work->target_vblank -
-                    dev->driver->get_vblank_counter(dev, work->crtc_id)) > 0)
+               (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_IN_VBLANK) &&
+               (!ASIC_IS_AVIVO(rdev) ||
+               ((int) (work->target_vblank -
+               dev->driver->get_vblank_counter(dev, work->crtc_id)) > 0)))
                usleep_range(1000, 2000);
 
        /* We borrow the event spin lock for protecting flip_status */
 
        for (i = 0; i < rdev->num_crtc; i++) {
                if (save->crtc_enabled[i]) {
                        tmp = RREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + crtc_offsets[i]);
-                       if ((tmp & 0x7) != 0) {
+                       if ((tmp & 0x7) != 3) {
                                tmp &= ~0x7;
+                               tmp |= 0x3;
                                WREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + crtc_offsets[i], tmp);
                        }
                        tmp = RREG32(AVIVO_D1GRPH_UPDATE + crtc_offsets[i]);