diff options
Diffstat (limited to 'drivers/gpu/drm/virtio')
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_display.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_drv.h | 25 | ||||
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_fence.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_gem.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_plane.c | 84 | ||||
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_vq.c | 23 |
6 files changed, 88 insertions, 58 deletions
diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c index e622485ae826..0966208ec30d 100644 --- a/drivers/gpu/drm/virtio/virtgpu_display.c +++ b/drivers/gpu/drm/virtio/virtgpu_display.c @@ -43,6 +43,9 @@ #define XRES_MAX 8192 #define YRES_MAX 8192 +#define drm_connector_to_virtio_gpu_output(x) \ + container_of(x, struct virtio_gpu_output, conn) + static const struct drm_crtc_funcs virtio_gpu_crtc_funcs = { .set_config = drm_atomic_helper_set_config, .destroy = drm_crtc_cleanup, @@ -59,7 +62,7 @@ static const struct drm_framebuffer_funcs virtio_gpu_fb_funcs = { .dirty = drm_atomic_helper_dirtyfb, }; -int +static int virtio_gpu_framebuffer_init(struct drm_device *dev, struct virtio_gpu_framebuffer *vgfb, const struct drm_mode_fb_cmd2 *mode_cmd, diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index eedae2a7b532..7e69c06e168e 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -103,8 +103,6 @@ struct virtio_gpu_fence { struct virtio_gpu_fence_driver *drv; struct list_head node; }; -#define to_virtio_fence(x) \ - container_of(x, struct virtio_gpu_fence, f) struct virtio_gpu_vbuffer { char *buf; @@ -135,10 +133,6 @@ struct virtio_gpu_output { }; #define drm_crtc_to_virtio_gpu_output(x) \ container_of(x, struct virtio_gpu_output, crtc) -#define drm_connector_to_virtio_gpu_output(x) \ - container_of(x, struct virtio_gpu_output, conn) -#define drm_encoder_to_virtio_gpu_output(x) \ - container_of(x, struct virtio_gpu_output, enc) struct virtio_gpu_framebuffer { struct drm_framebuffer base; @@ -183,6 +177,9 @@ struct virtio_gpu_device { struct kmem_cache *vbufs; bool vqs_ready; + bool disable_notify; + bool pending_notify; + struct ida resource_ida; wait_queue_head_t resp_wq; @@ -335,11 +332,10 @@ void virtio_gpu_dequeue_ctrl_func(struct work_struct *work); void virtio_gpu_dequeue_cursor_func(struct work_struct *work); void virtio_gpu_dequeue_fence_func(struct work_struct *work); +void virtio_gpu_disable_notify(struct virtio_gpu_device *vgdev); +void virtio_gpu_enable_notify(struct virtio_gpu_device *vgdev); + /* virtio_gpu_display.c */ -int virtio_gpu_framebuffer_init(struct drm_device *dev, - struct virtio_gpu_framebuffer *vgfb, - const struct drm_mode_fb_cmd2 *mode_cmd, - struct drm_gem_object *obj); void virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev); void virtio_gpu_modeset_fini(struct virtio_gpu_device *vgdev); @@ -350,7 +346,6 @@ struct drm_plane *virtio_gpu_plane_init(struct virtio_gpu_device *vgdev, int index); /* virtio_gpu_fence.c */ -bool virtio_fence_signaled(struct dma_fence *f); struct virtio_gpu_fence *virtio_gpu_fence_alloc( struct virtio_gpu_device *vgdev); void virtio_gpu_fence_emit(struct virtio_gpu_device *vgdev, @@ -366,18 +361,12 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev, struct virtio_gpu_object_params *params, struct virtio_gpu_object **bo_ptr, struct virtio_gpu_fence *fence); - /* virtgpu_prime.c */ struct drm_gem_object *virtgpu_gem_prime_import_sg_table( struct drm_device *dev, struct dma_buf_attachment *attach, struct sg_table *sgt); -static inline u64 virtio_gpu_object_mmap_offset(struct virtio_gpu_object *bo) -{ - return drm_vma_node_offset_addr(&bo->base.base.vma_node); -} - -/* virgl debufs */ +/* virgl debugfs */ int virtio_gpu_debugfs_init(struct drm_minor *minor); #endif diff --git a/drivers/gpu/drm/virtio/virtgpu_fence.c b/drivers/gpu/drm/virtio/virtgpu_fence.c index a4b9881ca1d3..5b2a4146c5bd 100644 --- a/drivers/gpu/drm/virtio/virtgpu_fence.c +++ b/drivers/gpu/drm/virtio/virtgpu_fence.c @@ -27,6 +27,9 @@ #include "virtgpu_drv.h" +#define to_virtio_fence(x) \ + container_of(x, struct virtio_gpu_fence, f) + static const char *virtio_get_driver_name(struct dma_fence *f) { return "virtio_gpu"; @@ -37,7 +40,7 @@ static const char *virtio_get_timeline_name(struct dma_fence *f) return "controlq"; } -bool virtio_fence_signaled(struct dma_fence *f) +static bool virtio_fence_signaled(struct dma_fence *f) { struct virtio_gpu_fence *fence = to_virtio_fence(f); diff --git a/drivers/gpu/drm/virtio/virtgpu_gem.c b/drivers/gpu/drm/virtio/virtgpu_gem.c index 4c1f579edfb3..0a2b62279647 100644 --- a/drivers/gpu/drm/virtio/virtgpu_gem.c +++ b/drivers/gpu/drm/virtio/virtgpu_gem.c @@ -96,14 +96,12 @@ int virtio_gpu_mode_dumb_mmap(struct drm_file *file_priv, uint32_t handle, uint64_t *offset_p) { struct drm_gem_object *gobj; - struct virtio_gpu_object *obj; BUG_ON(!offset_p); gobj = drm_gem_object_lookup(file_priv, handle); if (gobj == NULL) return -ENOENT; - obj = gem_to_virtio_gpu_obj(gobj); - *offset_p = virtio_gpu_object_mmap_offset(obj); + *offset_p = drm_vma_node_offset_addr(&gobj->vma_node); drm_gem_object_put_unlocked(gobj); return 0; } diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c index bc4bc4475a8c..ac42c84d2d7f 100644 --- a/drivers/gpu/drm/virtio/virtgpu_plane.c +++ b/drivers/gpu/drm/virtio/virtgpu_plane.c @@ -24,6 +24,7 @@ */ #include <drm/drm_atomic_helper.h> +#include <drm/drm_damage_helper.h> #include <drm/drm_fourcc.h> #include <drm/drm_plane_helper.h> @@ -88,7 +89,7 @@ static int virtio_gpu_plane_atomic_check(struct drm_plane *plane, struct drm_crtc_state *crtc_state; int ret; - if (!state->fb || !state->crtc) + if (!state->fb || WARN_ON(!state->crtc)) return 0; crtc_state = drm_atomic_get_crtc_state(state->state, state->crtc); @@ -103,22 +104,26 @@ static int virtio_gpu_plane_atomic_check(struct drm_plane *plane, } static void virtio_gpu_update_dumb_bo(struct virtio_gpu_device *vgdev, - struct virtio_gpu_object *bo, - struct drm_plane_state *state) + struct drm_plane_state *state, + struct drm_rect *rect) { + struct virtio_gpu_object *bo = + gem_to_virtio_gpu_obj(state->fb->obj[0]); struct virtio_gpu_object_array *objs; + uint32_t w = rect->x2 - rect->x1; + uint32_t h = rect->y2 - rect->y1; + uint32_t x = rect->x1; + uint32_t y = rect->y1; + uint32_t off = x * state->fb->format->cpp[0] + + y * state->fb->pitches[0]; objs = virtio_gpu_array_alloc(1); if (!objs) return; virtio_gpu_array_add_obj(objs, &bo->base.base); - virtio_gpu_cmd_transfer_to_host_2d - (vgdev, 0, - state->src_w >> 16, - state->src_h >> 16, - state->src_x >> 16, - state->src_y >> 16, - objs, NULL); + + virtio_gpu_cmd_transfer_to_host_2d(vgdev, off, w, h, x, y, + objs, NULL); } static void virtio_gpu_primary_plane_update(struct drm_plane *plane, @@ -127,8 +132,8 @@ static void virtio_gpu_primary_plane_update(struct drm_plane *plane, struct drm_device *dev = plane->dev; struct virtio_gpu_device *vgdev = dev->dev_private; struct virtio_gpu_output *output = NULL; - struct virtio_gpu_framebuffer *vgfb; struct virtio_gpu_object *bo; + struct drm_rect rect; if (plane->state->crtc) output = drm_crtc_to_virtio_gpu_output(plane->state->crtc); @@ -146,30 +151,43 @@ static void virtio_gpu_primary_plane_update(struct drm_plane *plane, return; } - vgfb = to_virtio_gpu_framebuffer(plane->state->fb); - bo = gem_to_virtio_gpu_obj(vgfb->base.obj[0]); + if (!drm_atomic_helper_damage_merged(old_state, plane->state, &rect)) + return; + + virtio_gpu_disable_notify(vgdev); + + bo = gem_to_virtio_gpu_obj(plane->state->fb->obj[0]); if (bo->dumb) - virtio_gpu_update_dumb_bo(vgdev, bo, plane->state); - - DRM_DEBUG("handle 0x%x, crtc %dx%d+%d+%d, src %dx%d+%d+%d\n", - bo->hw_res_handle, - plane->state->crtc_w, plane->state->crtc_h, - plane->state->crtc_x, plane->state->crtc_y, - plane->state->src_w >> 16, - plane->state->src_h >> 16, - plane->state->src_x >> 16, - plane->state->src_y >> 16); - virtio_gpu_cmd_set_scanout(vgdev, output->index, - bo->hw_res_handle, - plane->state->src_w >> 16, - plane->state->src_h >> 16, - plane->state->src_x >> 16, - plane->state->src_y >> 16); + virtio_gpu_update_dumb_bo(vgdev, plane->state, &rect); + + if (plane->state->fb != old_state->fb || + plane->state->src_w != old_state->src_w || + plane->state->src_h != old_state->src_h || + plane->state->src_x != old_state->src_x || + plane->state->src_y != old_state->src_y) { + DRM_DEBUG("handle 0x%x, crtc %dx%d+%d+%d, src %dx%d+%d+%d\n", + bo->hw_res_handle, + plane->state->crtc_w, plane->state->crtc_h, + plane->state->crtc_x, plane->state->crtc_y, + plane->state->src_w >> 16, + plane->state->src_h >> 16, + plane->state->src_x >> 16, + plane->state->src_y >> 16); + virtio_gpu_cmd_set_scanout(vgdev, output->index, + bo->hw_res_handle, + plane->state->src_w >> 16, + plane->state->src_h >> 16, + plane->state->src_x >> 16, + plane->state->src_y >> 16); + } + virtio_gpu_cmd_resource_flush(vgdev, bo->hw_res_handle, - plane->state->src_x >> 16, - plane->state->src_y >> 16, - plane->state->src_w >> 16, - plane->state->src_h >> 16); + rect.x1, + rect.y1, + rect.x2 - rect.x1, + rect.y2 - rect.y1); + + virtio_gpu_enable_notify(vgdev); } static int virtio_gpu_cursor_prepare_fb(struct drm_plane *plane, diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c index 9274c4063c70..5914e79d3429 100644 --- a/drivers/gpu/drm/virtio/virtgpu_vq.c +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c @@ -404,8 +404,12 @@ again: } notify = virtio_gpu_queue_ctrl_buffer_locked(vgdev, vbuf, vout); spin_unlock(&vgdev->ctrlq.qlock); - if (notify) - virtqueue_notify(vgdev->ctrlq.vq); + if (notify) { + if (vgdev->disable_notify) + vgdev->pending_notify = true; + else + virtqueue_notify(vgdev->ctrlq.vq); + } if (sgt) { sg_free_table(sgt); @@ -413,6 +417,21 @@ again: } } +void virtio_gpu_disable_notify(struct virtio_gpu_device *vgdev) +{ + vgdev->disable_notify = true; +} + +void virtio_gpu_enable_notify(struct virtio_gpu_device *vgdev) +{ + vgdev->disable_notify = false; + + if (!vgdev->pending_notify) + return; + vgdev->pending_notify = false; + virtqueue_notify(vgdev->ctrlq.vq); +} + static void virtio_gpu_queue_ctrl_buffer(struct virtio_gpu_device *vgdev, struct virtio_gpu_vbuffer *vbuf) { |