if (ret)
                goto fail;
 
-       if (drm->device.info.family < NV_DEVICE_INFO_V0_FERMI)
-               BEGIN_NV04(chan, NvSubSw, NV_SW_PAGE_FLIP, 1);
-       else
-               BEGIN_NVC0(chan, FermiSw, NV_SW_PAGE_FLIP, 1);
+       BEGIN_NV04(chan, NvSubSw, NV_SW_PAGE_FLIP, 1);
        OUT_RING  (chan, 0x00000000);
        FIRE_RING (chan);
 
        struct nouveau_channel *chan;
        struct nouveau_cli *cli;
        struct nouveau_fence *fence;
+       struct nv04_display *dispnv04 = nv04_display(dev);
+       int head = nouveau_crtc(crtc)->index;
        int ret;
 
        chan = drm->channel;
        drm_crtc_vblank_get(crtc);
 
        /* Emit a page flip */
-       if (drm->device.info.family >= NV_DEVICE_INFO_V0_TESLA) {
-               ret = nv50_display_flip_next(crtc, fb, chan, swap_interval);
+       if (swap_interval) {
+               ret = RING_SPACE(chan, 8);
                if (ret)
                        goto fail_unreserve;
-       } else {
-               struct nv04_display *dispnv04 = nv04_display(dev);
-               int head = nouveau_crtc(crtc)->index;
-
-               if (swap_interval) {
-                       ret = RING_SPACE(chan, 8);
-                       if (ret)
-                               goto fail_unreserve;
-
-                       BEGIN_NV04(chan, NvSubImageBlit, 0x012c, 1);
-                       OUT_RING  (chan, 0);
-                       BEGIN_NV04(chan, NvSubImageBlit, 0x0134, 1);
-                       OUT_RING  (chan, head);
-                       BEGIN_NV04(chan, NvSubImageBlit, 0x0100, 1);
-                       OUT_RING  (chan, 0);
-                       BEGIN_NV04(chan, NvSubImageBlit, 0x0130, 1);
-                       OUT_RING  (chan, 0);
-               }
 
-               nouveau_bo_ref(new_bo, &dispnv04->image[head]);
+               BEGIN_NV04(chan, NvSubImageBlit, 0x012c, 1);
+               OUT_RING  (chan, 0);
+               BEGIN_NV04(chan, NvSubImageBlit, 0x0134, 1);
+               OUT_RING  (chan, head);
+               BEGIN_NV04(chan, NvSubImageBlit, 0x0100, 1);
+               OUT_RING  (chan, 0);
+               BEGIN_NV04(chan, NvSubImageBlit, 0x0130, 1);
+               OUT_RING  (chan, 0);
        }
 
+       nouveau_bo_ref(new_bo, &dispnv04->image[head]);
+
        ret = nouveau_page_flip_emit(chan, old_bo, new_bo, s, &fence);
        if (ret)
                goto fail_unreserve;
 
        s = list_first_entry(&fctx->flip, struct nouveau_page_flip_state, head);
        if (s->event) {
-               if (drm->device.info.family < NV_DEVICE_INFO_V0_TESLA) {
-                       drm_crtc_arm_vblank_event(s->crtc, s->event);
-               } else {
-                       drm_crtc_send_vblank_event(s->crtc, s->event);
-
-                       /* Give up ownership of vblank for page-flipped crtc */
-                       drm_crtc_vblank_put(s->crtc);
-               }
-       }
-       else {
+               drm_crtc_arm_vblank_event(s->crtc, s->event);
+       } else {
                /* Give up ownership of vblank for page-flipped crtc */
                drm_crtc_vblank_put(s->crtc);
        }
        struct nouveau_page_flip_state state;
 
        if (!nouveau_finish_page_flip(chan, &state)) {
-               if (drm->device.info.family < NV_DEVICE_INFO_V0_TESLA) {
-                       nv_set_crtc_base(drm->dev, drm_crtc_index(state.crtc),
-                                        state.offset + state.crtc->y *
-                                        state.pitch + state.crtc->x *
-                                        state.bpp / 8);
-               }
+               nv_set_crtc_base(drm->dev, drm_crtc_index(state.crtc),
+                                state.offset + state.crtc->y *
+                                state.pitch + state.crtc->x *
+                                state.bpp / 8);
        }
 
        return NVIF_NOTIFY_KEEP;
 
 
 struct nv50_head {
        struct nouveau_crtc base;
-       struct nouveau_bo *image;
        struct nv50_ovly ovly;
        struct nv50_oimm oimm;
-
-       struct nv50_base *_base;
 };
 
 #define nv50_head(c) ((struct nv50_head *)nouveau_crtc(c))
        *((p)++) = _d;                                                         \
 } while(0)
 
-static bool
-evo_sync_wait(void *data)
-{
-       if (nouveau_bo_rd32(data, EVO_MAST_NTFY) != 0x00000000)
-               return true;
-       usleep_range(1, 2);
-       return false;
-}
-
-static int
-evo_sync(struct drm_device *dev)
-{
-       struct nvif_device *device = &nouveau_drm(dev)->device;
-       struct nv50_disp *disp = nv50_disp(dev);
-       struct nv50_mast *mast = nv50_mast(dev);
-       u32 *push = evo_wait(mast, 8);
-       if (push) {
-               nouveau_bo_wr32(disp->sync, EVO_MAST_NTFY, 0x00000000);
-               evo_mthd(push, 0x0084, 1);
-               evo_data(push, 0x80000000 | EVO_MAST_NTFY);
-               evo_mthd(push, 0x0080, 2);
-               evo_data(push, 0x00000000);
-               evo_data(push, 0x00000000);
-               evo_kick(push, mast);
-               if (nvif_msec(device, 2000,
-                       if (evo_sync_wait(disp->sync))
-                               break;
-               ) >= 0)
-                       return 0;
-       }
-
-       return -EBUSY;
-}
-
 /******************************************************************************
  * Plane
  *****************************************************************************/
        u16 ntfy;
        u16 sema;
        u32 data;
-
-       struct nv50_wndw_atom asy;
 };
 
 struct nv50_wndw_func {
                                &base->wndw.notify);
 }
 
-/******************************************************************************
- * Page flipping channel
- *****************************************************************************/
-struct nouveau_bo *
-nv50_display_crtc_sema(struct drm_device *dev, int crtc)
-{
-       return nv50_disp(dev)->sync;
-}
-
-struct nv50_display_flip {
-       struct nv50_disp *disp;
-       struct nv50_base *base;
-};
-
-static bool
-nv50_display_flip_wait(void *data)
-{
-       struct nv50_display_flip *flip = data;
-       if (nouveau_bo_rd32(flip->disp->sync, flip->base->wndw.sema / 4) ==
-                                             flip->base->wndw.data)
-               return true;
-       usleep_range(1, 2);
-       return false;
-}
-
-void
-nv50_display_flip_stop(struct drm_crtc *crtc)
-{
-       struct nvif_device *device = &nouveau_drm(crtc->dev)->device;
-       struct nv50_base *base = nv50_head(crtc)->_base;
-       struct nv50_wndw *wndw = &base->wndw;
-       struct nv50_wndw_atom *asyw = &wndw->asy;
-       struct nv50_display_flip flip = {
-               .disp = nv50_disp(crtc->dev),
-               .base = base,
-       };
-
-       asyw->state.crtc = NULL;
-       asyw->state.fb = NULL;
-       nv50_wndw_atomic_check(&wndw->plane, &asyw->state);
-       nv50_wndw_flush_clr(wndw, 0, true, asyw);
-
-       nvif_msec(device, 2000,
-               if (nv50_display_flip_wait(&flip))
-                       break;
-       );
-}
-
-int
-nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb,
-                      struct nouveau_channel *chan, u32 swap_interval)
-{
-       struct nouveau_framebuffer *nv_fb = nouveau_framebuffer(fb);
-       struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
-       struct nv50_head *head = nv50_head(crtc);
-       struct nv50_base *base = nv50_head(crtc)->_base;
-       struct nv50_wndw *wndw = &base->wndw;
-       struct nv50_wndw_atom *asyw = &wndw->asy;
-       int ret;
-
-       if (crtc->primary->fb->width != fb->width ||
-           crtc->primary->fb->height != fb->height)
-               return -EINVAL;
-
-       if (chan == NULL)
-               evo_sync(crtc->dev);
-
-       if (chan && chan->user.oclass < G82_CHANNEL_GPFIFO) {
-               ret = RING_SPACE(chan, 8);
-               if (ret)
-                       return ret;
-
-               BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 2);
-               OUT_RING  (chan, NvEvoSema0 + nv_crtc->index);
-               OUT_RING  (chan, base->wndw.sema ^ 0x10);
-               BEGIN_NV04(chan, 0, NV11_SUBCHAN_SEMAPHORE_RELEASE, 1);
-               OUT_RING  (chan, base->wndw.data + 1);
-               BEGIN_NV04(chan, 0, NV11_SUBCHAN_SEMAPHORE_OFFSET, 2);
-               OUT_RING  (chan, base->wndw.sema);
-               OUT_RING  (chan, base->wndw.data);
-       } else
-       if (chan && chan->user.oclass < FERMI_CHANNEL_GPFIFO) {
-               u64 addr = nv84_fence_crtc(chan, nv_crtc->index) + base->wndw.sema;
-               ret = RING_SPACE(chan, 12);
-               if (ret)
-                       return ret;
-
-               BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 1);
-               OUT_RING  (chan, chan->vram.handle);
-               BEGIN_NV04(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4);
-               OUT_RING  (chan, upper_32_bits(addr ^ 0x10));
-               OUT_RING  (chan, lower_32_bits(addr ^ 0x10));
-               OUT_RING  (chan, base->wndw.data + 1);
-               OUT_RING  (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_WRITE_LONG);
-               BEGIN_NV04(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4);
-               OUT_RING  (chan, upper_32_bits(addr));
-               OUT_RING  (chan, lower_32_bits(addr));
-               OUT_RING  (chan, base->wndw.data);
-               OUT_RING  (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_EQUAL);
-       } else
-       if (chan) {
-               u64 addr = nv84_fence_crtc(chan, nv_crtc->index) + base->wndw.sema;
-               ret = RING_SPACE(chan, 10);
-               if (ret)
-                       return ret;
-
-               BEGIN_NVC0(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4);
-               OUT_RING  (chan, upper_32_bits(addr ^ 0x10));
-               OUT_RING  (chan, lower_32_bits(addr ^ 0x10));
-               OUT_RING  (chan, base->wndw.data + 1);
-               OUT_RING  (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_WRITE_LONG |
-                                NVC0_SUBCHAN_SEMAPHORE_TRIGGER_YIELD);
-               BEGIN_NVC0(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4);
-               OUT_RING  (chan, upper_32_bits(addr));
-               OUT_RING  (chan, lower_32_bits(addr));
-               OUT_RING  (chan, base->wndw.data);
-               OUT_RING  (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_EQUAL |
-                                NVC0_SUBCHAN_SEMAPHORE_TRIGGER_YIELD);
-       }
-
-       if (chan) {
-               base->wndw.sema ^= 0x10;
-               base->wndw.data++;
-               FIRE_RING (chan);
-       }
-
-       /* queue the flip */
-       asyw->state.crtc = &head->base.base;
-       asyw->state.fb = fb;
-       asyw->interval = swap_interval;
-       asyw->image.handle = nv_fb->r_handle;
-       asyw->image.offset = nv_fb->nvbo->bo.offset;
-       asyw->sema.handle = base->chan.base.sync.handle;
-       asyw->sema.offset = base->wndw.sema;
-       asyw->sema.acquire = base->wndw.data++;
-       asyw->sema.release = base->wndw.data;
-       nv50_wndw_atomic_check(&wndw->plane, &asyw->state);
-       asyw->set.sema = true;
-       nv50_wndw_flush_set(wndw, 0, asyw);
-       nv50_wndw_wait_armed(wndw, asyw);
-
-       nouveau_bo_ref(nv_fb->nvbo, &head->image);
-       return 0;
-}
-
 /******************************************************************************
  * Head
  *****************************************************************************/
        }
 
        crtc = &head->base.base;
-       head->_base = base;
-
        drm_crtc_init_with_planes(dev, crtc, &base->wndw.plane,
                                  &curs->wndw.plane, &nv50_crtc_func,
                                  "head-%d", head->base.index);
 int
 nv50_display_init(struct drm_device *dev)
 {
-       struct nv50_disp *disp = nv50_disp(dev);
        struct drm_encoder *encoder;
        struct drm_plane *plane;
        struct drm_crtc *crtc;
        if (!push)
                return -EBUSY;
 
-       list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
-               struct nv50_wndw *wndw = &nv50_head(crtc)->_base->wndw;
-
-               nv50_crtc_lut_load(crtc);
-               nouveau_bo_wr32(disp->sync, wndw->sema / 4, wndw->data);
-       }
-
        evo_mthd(push, 0x0088, 1);
        evo_data(push, nv50_mast(dev)->base.sync.handle);
        evo_kick(push, nv50_mast(dev));
                }
        }
 
+       drm_for_each_crtc(crtc, dev) {
+               nv50_crtc_lut_load(crtc);
+       }
+
        drm_for_each_plane(plane, dev) {
                struct nv50_wndw *wndw = nv50_wndw(plane);
                if (plane->funcs != &nv50_wndw)