Commit b9d9dcda authored by Ben Skeggs's avatar Ben Skeggs

drm/nv11-: synchronise flips to vblank, unless async flip requested

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 1e303c03
...@@ -398,6 +398,11 @@ nouveau_display_create(struct drm_device *dev) ...@@ -398,6 +398,11 @@ nouveau_display_create(struct drm_device *dev)
dev->mode_config.preferred_depth = 24; dev->mode_config.preferred_depth = 24;
dev->mode_config.prefer_shadow = 1; dev->mode_config.prefer_shadow = 1;
if (nv_device(drm->device)->chipset < 0x11)
dev->mode_config.async_page_flip = false;
else
dev->mode_config.async_page_flip = true;
drm_kms_helper_poll_init(dev); drm_kms_helper_poll_init(dev);
drm_kms_helper_poll_disable(dev); drm_kms_helper_poll_disable(dev);
...@@ -579,9 +584,9 @@ nouveau_page_flip_emit(struct nouveau_channel *chan, ...@@ -579,9 +584,9 @@ nouveau_page_flip_emit(struct nouveau_channel *chan,
int int
nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
struct drm_pending_vblank_event *event, struct drm_pending_vblank_event *event, u32 flags)
uint32_t page_flip_flags)
{ {
const int swap_interval = (flags & DRM_MODE_PAGE_FLIP_ASYNC) ? 0 : 1;
struct drm_device *dev = crtc->dev; struct drm_device *dev = crtc->dev;
struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_bo *old_bo = nouveau_framebuffer(crtc->fb)->nvbo; 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,12 +630,29 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
/* Emit a page flip */ /* Emit a page flip */
if (nv_device(drm->device)->card_type >= NV_50) { if (nv_device(drm->device)->card_type >= NV_50) {
ret = nv50_display_flip_next(crtc, fb, chan, 0); ret = nv50_display_flip_next(crtc, fb, chan, swap_interval);
if (ret) if (ret)
goto fail_unreserve; goto fail_unreserve;
} else { } else {
struct nv04_display *dispnv04 = nv04_display(dev); struct nv04_display *dispnv04 = nv04_display(dev);
nouveau_bo_ref(new_bo, &dispnv04->image[nouveau_crtc(crtc)->index]); 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]);
} }
ret = nouveau_page_flip_emit(chan, old_bo, new_bo, s, &fence); ret = nouveau_page_flip_emit(chan, old_bo, new_bo, s, &fence);
......
...@@ -255,6 +255,12 @@ nv04_fbcon_accel_init(struct fb_info *info) ...@@ -255,6 +255,12 @@ nv04_fbcon_accel_init(struct fb_info *info)
OUT_RING(chan, NvCtxSurf2D); OUT_RING(chan, NvCtxSurf2D);
BEGIN_NV04(chan, NvSubImageBlit, 0x02fc, 1); BEGIN_NV04(chan, NvSubImageBlit, 0x02fc, 1);
OUT_RING(chan, 3); OUT_RING(chan, 3);
if (device->chipset >= 0x11 /*XXX: oclass == 0x009f*/) {
BEGIN_NV04(chan, NvSubImageBlit, 0x0120, 3);
OUT_RING(chan, 0);
OUT_RING(chan, 1);
OUT_RING(chan, 2);
}
BEGIN_NV04(chan, NvSubGdiRect, 0x0000, 1); BEGIN_NV04(chan, NvSubGdiRect, 0x0000, 1);
OUT_RING(chan, NvGdiRect); OUT_RING(chan, NvGdiRect);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment