diff options
author | Mario Kleiner <mario.kleiner.de@gmail.com> | 2014-06-11 09:51:23 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-07-09 11:18:24 -0700 |
commit | 06c9285bd091c31b24cab368dbc85469c0ee4dae (patch) | |
tree | df98403e09194829b470fc6858322cb1a4b41496 | |
parent | 4091d550aa42321436e3e995baf0b410dd30aaaa (diff) |
drm/nouveau/kms: reference vblank for crtc during pageflip.
commit ba124a41058b300a5464206d2d33803cc3dc82ec upstream.
Need to drm_vblank_get/put() the crtc involved in a
pending pageflip, or we might not get vblank irqs and
updates of vblank counts and timestamps for pageflip
events and flip completion.
Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_display.c | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 972c0c7e476..6601690ab29 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -734,6 +734,9 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, fb->bits_per_pixel, fb->pitches[0], crtc->x, crtc->y, new_bo->bo.offset }; + /* Keep vblanks on during flip, for the target crtc of this flip */ + drm_vblank_get(dev, nouveau_crtc(crtc)->index); + /* Emit a page flip */ if (nv_device(drm->device)->card_type >= NV_50) { ret = nv50_display_flip_next(crtc, fb, chan, swap_interval); @@ -777,6 +780,7 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, return 0; fail_unreserve: + drm_vblank_put(dev, nouveau_crtc(crtc)->index); ttm_bo_unreserve(&old_bo->bo); fail_unpin: mutex_unlock(&chan->cli->mutex); @@ -815,6 +819,9 @@ nouveau_finish_page_flip(struct nouveau_channel *chan, drm_send_vblank_event(dev, crtcid, s->event); } + /* Give up ownership of vblank for page-flipped crtc */ + drm_vblank_put(dev, s->crtc); + list_del(&s->head); if (ps) *ps = *s; |