virtio-gpu: add page flip support
authorGerd Hoffmann <kraxel@redhat.com>
Wed, 23 Sep 2015 10:19:11 +0000 (12:19 +0200)
committerGerd Hoffmann <kraxel@redhat.com>
Fri, 16 Oct 2015 08:44:03 +0000 (10:44 +0200)
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
drivers/gpu/drm/virtio/virtgpu_display.c

index c9c1427..f545913 100644 (file)
@@ -125,6 +125,51 @@ static int virtio_gpu_crtc_cursor_move(struct drm_crtc *crtc,
        return 0;
 }
 
+static int virtio_gpu_page_flip(struct drm_crtc *crtc,
+                               struct drm_framebuffer *fb,
+                               struct drm_pending_vblank_event *event,
+                               uint32_t flags)
+{
+       struct virtio_gpu_device *vgdev = crtc->dev->dev_private;
+       struct virtio_gpu_output *output =
+               container_of(crtc, struct virtio_gpu_output, crtc);
+       struct drm_plane *plane = crtc->primary;
+       struct virtio_gpu_framebuffer *vgfb;
+       struct virtio_gpu_object *bo;
+       unsigned long irqflags;
+       uint32_t handle;
+
+       plane->fb = fb;
+       vgfb = to_virtio_gpu_framebuffer(plane->fb);
+       bo = gem_to_virtio_gpu_obj(vgfb->obj);
+       handle = bo->hw_res_handle;
+
+       DRM_DEBUG("handle 0x%x%s, crtc %dx%d\n", handle,
+                 bo->dumb ? ", dumb" : "",
+                 crtc->mode.hdisplay, crtc->mode.vdisplay);
+       if (bo->dumb) {
+               virtio_gpu_cmd_transfer_to_host_2d
+                       (vgdev, handle, 0,
+                        cpu_to_le32(crtc->mode.hdisplay),
+                        cpu_to_le32(crtc->mode.vdisplay),
+                        0, 0, NULL);
+       }
+       virtio_gpu_cmd_set_scanout(vgdev, output->index, handle,
+                                  crtc->mode.hdisplay,
+                                  crtc->mode.vdisplay, 0, 0);
+       virtio_gpu_cmd_resource_flush(vgdev, handle, 0, 0,
+                                     crtc->mode.hdisplay,
+                                     crtc->mode.vdisplay);
+
+       if (event) {
+               spin_lock_irqsave(&crtc->dev->event_lock, irqflags);
+               drm_send_vblank_event(crtc->dev, -1, event);
+               spin_unlock_irqrestore(&crtc->dev->event_lock, irqflags);
+       }
+
+       return 0;
+}
+
 static const struct drm_crtc_funcs virtio_gpu_crtc_funcs = {
        .cursor_set2            = virtio_gpu_crtc_cursor_set,
        .cursor_move            = virtio_gpu_crtc_cursor_move,
@@ -132,9 +177,7 @@ static const struct drm_crtc_funcs virtio_gpu_crtc_funcs = {
        .set_config             = drm_atomic_helper_set_config,
        .destroy                = drm_crtc_cleanup,
 
-#if 0 /* not (yet) working without vblank support according to docs */
-       .page_flip              = drm_atomic_helper_page_flip,
-#endif
+       .page_flip              = virtio_gpu_page_flip,
        .reset                  = drm_atomic_helper_crtc_reset,
        .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
        .atomic_destroy_state   = drm_atomic_helper_crtc_destroy_state,