aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2013-11-10 22:59:40 -0500
committerBen Skeggs <bskeggs@redhat.com>2013-11-13 23:56:56 -0500
commitb9d9dcdaae4a9284ba3484c528f44a9db18faabf (patch)
tree43127a01e6ff791ea6b659ae9193751d708222e6
parent1e303c03af1e631de37ec77cc2513210910a812c (diff)
drm/nv11-: synchronise flips to vblank, unless async flip requested
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_display.c30
-rw-r--r--drivers/gpu/drm/nouveau/nv04_fbcon.c6
2 files changed, 32 insertions, 4 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
index 17422bc19529..7809d92183c4 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -398,6 +398,11 @@ nouveau_display_create(struct drm_device *dev)
398 dev->mode_config.preferred_depth = 24; 398 dev->mode_config.preferred_depth = 24;
399 dev->mode_config.prefer_shadow = 1; 399 dev->mode_config.prefer_shadow = 1;
400 400
401 if (nv_device(drm->device)->chipset < 0x11)
402 dev->mode_config.async_page_flip = false;
403 else
404 dev->mode_config.async_page_flip = true;
405
401 drm_kms_helper_poll_init(dev); 406 drm_kms_helper_poll_init(dev);
402 drm_kms_helper_poll_disable(dev); 407 drm_kms_helper_poll_disable(dev);
403 408
@@ -579,9 +584,9 @@ fail:
579 584
580int 585int
581nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, 586nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
582 struct drm_pending_vblank_event *event, 587 struct drm_pending_vblank_event *event, u32 flags)
583 uint32_t page_flip_flags)
584{ 588{
589 const int swap_interval = (flags & DRM_MODE_PAGE_FLIP_ASYNC) ? 0 : 1;
585 struct drm_device *dev = crtc->dev; 590 struct drm_device *dev = crtc->dev;
586 struct nouveau_drm *drm = nouveau_drm(dev); 591 struct nouveau_drm *drm = nouveau_drm(dev);
587 struct nouveau_bo *old_bo = nouveau_framebuffer(crtc->fb)->nvbo; 592 struct nouveau_bo *old_bo = nouveau_framebuffer(crtc->fb)->nvbo;
@@ -625,12 +630,29 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
625 630
626 /* Emit a page flip */ 631 /* Emit a page flip */
627 if (nv_device(drm->device)->card_type >= NV_50) { 632 if (nv_device(drm->device)->card_type >= NV_50) {
628 ret = nv50_display_flip_next(crtc, fb, chan, 0); 633 ret = nv50_display_flip_next(crtc, fb, chan, swap_interval);
629 if (ret) 634 if (ret)
630 goto fail_unreserve; 635 goto fail_unreserve;
631 } else { 636 } else {
632 struct nv04_display *dispnv04 = nv04_display(dev); 637 struct nv04_display *dispnv04 = nv04_display(dev);
633 nouveau_bo_ref(new_bo, &dispnv04->image[nouveau_crtc(crtc)->index]); 638 int head = nouveau_crtc(crtc)->index;
639
640 if (swap_interval) {
641 ret = RING_SPACE(chan, 8);
642 if (ret)
643 goto fail_unreserve;
644
645 BEGIN_NV04(chan, NvSubImageBlit, 0x012c, 1);
646 OUT_RING (chan, 0);
647 BEGIN_NV04(chan, NvSubImageBlit, 0x0134, 1);
648 OUT_RING (chan, head);
649 BEGIN_NV04(chan, NvSubImageBlit, 0x0100, 1);
650 OUT_RING (chan, 0);
651 BEGIN_NV04(chan, NvSubImageBlit, 0x0130, 1);
652 OUT_RING (chan, 0);
653 }
654
655 nouveau_bo_ref(new_bo, &dispnv04->image[head]);
634 } 656 }
635 657
636 ret = nouveau_page_flip_emit(chan, old_bo, new_bo, s, &fence); 658 ret = nouveau_page_flip_emit(chan, old_bo, new_bo, s, &fence);
diff --git a/drivers/gpu/drm/nouveau/nv04_fbcon.c b/drivers/gpu/drm/nouveau/nv04_fbcon.c
index 77dcc9c50777..8fe32bbed99a 100644
--- a/drivers/gpu/drm/nouveau/nv04_fbcon.c
+++ b/drivers/gpu/drm/nouveau/nv04_fbcon.c
@@ -255,6 +255,12 @@ nv04_fbcon_accel_init(struct fb_info *info)
255 OUT_RING(chan, NvCtxSurf2D); 255 OUT_RING(chan, NvCtxSurf2D);
256 BEGIN_NV04(chan, NvSubImageBlit, 0x02fc, 1); 256 BEGIN_NV04(chan, NvSubImageBlit, 0x02fc, 1);
257 OUT_RING(chan, 3); 257 OUT_RING(chan, 3);
258 if (device->chipset >= 0x11 /*XXX: oclass == 0x009f*/) {
259 BEGIN_NV04(chan, NvSubImageBlit, 0x0120, 3);
260 OUT_RING(chan, 0);
261 OUT_RING(chan, 1);
262 OUT_RING(chan, 2);
263 }
258 264
259 BEGIN_NV04(chan, NvSubGdiRect, 0x0000, 1); 265 BEGIN_NV04(chan, NvSubGdiRect, 0x0000, 1);
260 OUT_RING(chan, NvGdiRect); 266 OUT_RING(chan, NvGdiRect);