summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/virtio
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2021-12-08 23:43:50 -0800
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2021-12-08 23:43:50 -0800
commit5d8dfaa71d87f742c53309b95cb6a8b274119027 (patch)
tree83fa5199868fb98dbe7dcb0791bc462bac77265b /drivers/gpu/drm/virtio
parent8c374ef45416281c7172dc29ed438dfb445795f1 (diff)
parent8bb7eca972ad531c9b149c0a51ab43a417385813 (diff)
Merge tag 'v5.15' into next
Sync up with the mainline to get the latest APIs and DT bindings.
Diffstat (limited to 'drivers/gpu/drm/virtio')
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_drv.c14
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_drv.h4
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_gem.c8
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_ioctl.c5
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_kms.c4
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_object.c3
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_plane.c64
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_prime.c2
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_vq.c7
9 files changed, 88 insertions, 23 deletions
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c
index a21dc3ad6f88..ed85a7863256 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.c
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.c
@@ -31,6 +31,7 @@
#include <linux/pci.h>
#include <drm/drm.h>
+#include <drm/drm_aperture.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_drv.h>
#include <drm/drm_file.h>
@@ -50,13 +51,16 @@ static int virtio_gpu_pci_quirk(struct drm_device *dev, struct virtio_device *vd
const char *pname = dev_name(&pdev->dev);
bool vga = (pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA;
char unique[20];
+ int ret;
DRM_INFO("pci: %s detected at %s\n",
vga ? "virtio-vga" : "virtio-gpu-pci",
pname);
- if (vga)
- drm_fb_helper_remove_conflicting_pci_framebuffers(pdev,
- "virtiodrmfb");
+ if (vga) {
+ ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &driver);
+ if (ret)
+ return ret;
+ }
/*
* Normally the drm_dev_set_unique() call is done by core DRM.
@@ -121,11 +125,13 @@ static int virtio_gpu_probe(struct virtio_device *vdev)
ret = drm_dev_register(dev, 0);
if (ret)
- goto err_free;
+ goto err_deinit;
drm_fbdev_generic_setup(vdev->priv, 32);
return 0;
+err_deinit:
+ virtio_gpu_deinit(dev);
err_free:
drm_dev_put(dev);
return ret;
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h
index d9dbc4f258f3..d4e610a44e12 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.h
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
@@ -315,7 +315,9 @@ void virtio_gpu_cmd_transfer_to_host_2d(struct virtio_gpu_device *vgdev,
void virtio_gpu_cmd_resource_flush(struct virtio_gpu_device *vgdev,
uint32_t resource_id,
uint32_t x, uint32_t y,
- uint32_t width, uint32_t height);
+ uint32_t width, uint32_t height,
+ struct virtio_gpu_object_array *objs,
+ struct virtio_gpu_fence *fence);
void virtio_gpu_cmd_set_scanout(struct virtio_gpu_device *vgdev,
uint32_t scanout_id, uint32_t resource_id,
uint32_t width, uint32_t height,
diff --git a/drivers/gpu/drm/virtio/virtgpu_gem.c b/drivers/gpu/drm/virtio/virtgpu_gem.c
index 8502400b2f9c..2de61b63ef91 100644
--- a/drivers/gpu/drm/virtio/virtgpu_gem.c
+++ b/drivers/gpu/drm/virtio/virtgpu_gem.c
@@ -64,6 +64,7 @@ int virtio_gpu_mode_dumb_create(struct drm_file *file_priv,
{
struct drm_gem_object *gobj;
struct virtio_gpu_object_params params = { 0 };
+ struct virtio_gpu_device *vgdev = dev->dev_private;
int ret;
uint32_t pitch;
@@ -79,6 +80,13 @@ int virtio_gpu_mode_dumb_create(struct drm_file *file_priv,
params.height = args->height;
params.size = args->size;
params.dumb = true;
+
+ if (vgdev->has_resource_blob && !vgdev->has_virgl_3d) {
+ params.blob_mem = VIRTGPU_BLOB_MEM_GUEST;
+ params.blob_flags = VIRTGPU_BLOB_FLAG_USE_SHAREABLE;
+ params.blob = true;
+ }
+
ret = virtio_gpu_gem_create(file_priv, dev, &params, &gobj,
&args->handle);
if (ret)
diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
index 669f2ee39515..5c1ad1596889 100644
--- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c
+++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
@@ -451,10 +451,9 @@ static int virtio_gpu_wait_ioctl(struct drm_device *dev, void *data,
return -ENOENT;
if (args->flags & VIRTGPU_WAIT_NOWAIT) {
- ret = dma_resv_test_signaled_rcu(obj->resv, true);
+ ret = dma_resv_test_signaled(obj->resv, true);
} else {
- ret = dma_resv_wait_timeout_rcu(obj->resv, true, true,
- timeout);
+ ret = dma_resv_wait_timeout(obj->resv, true, true, timeout);
}
if (ret == 0)
ret = -EBUSY;
diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c
index b375394193be..f3379059f324 100644
--- a/drivers/gpu/drm/virtio/virtgpu_kms.c
+++ b/drivers/gpu/drm/virtio/virtgpu_kms.c
@@ -234,6 +234,7 @@ err_scanouts:
err_vbufs:
vgdev->vdev->config->del_vqs(vgdev->vdev);
err_vqs:
+ dev->dev_private = NULL;
kfree(vgdev);
return ret;
}
@@ -264,6 +265,9 @@ void virtio_gpu_release(struct drm_device *dev)
{
struct virtio_gpu_device *vgdev = dev->dev_private;
+ if (!vgdev)
+ return;
+
virtio_gpu_modeset_fini(vgdev);
virtio_gpu_free_vbufs(vgdev);
virtio_gpu_cleanup_cap_cache(vgdev);
diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c
index 4ff1ec28e630..f648b0e24447 100644
--- a/drivers/gpu/drm/virtio/virtgpu_object.c
+++ b/drivers/gpu/drm/virtio/virtgpu_object.c
@@ -254,6 +254,9 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev,
}
if (params->blob) {
+ if (params->blob_mem == VIRTGPU_BLOB_MEM_GUEST)
+ bo->guest_blob = true;
+
virtio_gpu_cmd_resource_create_blob(vgdev, bo, params,
ents, nents);
} else if (params->virgl) {
diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c
index 4e1b17548007..a49fd9480381 100644
--- a/drivers/gpu/drm/virtio/virtgpu_plane.c
+++ b/drivers/gpu/drm/virtio/virtgpu_plane.c
@@ -129,6 +129,40 @@ static void virtio_gpu_update_dumb_bo(struct virtio_gpu_device *vgdev,
objs, NULL);
}
+static void virtio_gpu_resource_flush(struct drm_plane *plane,
+ uint32_t x, uint32_t y,
+ uint32_t width, uint32_t height)
+{
+ struct drm_device *dev = plane->dev;
+ struct virtio_gpu_device *vgdev = dev->dev_private;
+ struct virtio_gpu_framebuffer *vgfb;
+ struct virtio_gpu_object *bo;
+
+ vgfb = to_virtio_gpu_framebuffer(plane->state->fb);
+ bo = gem_to_virtio_gpu_obj(vgfb->base.obj[0]);
+ if (vgfb->fence) {
+ struct virtio_gpu_object_array *objs;
+
+ objs = virtio_gpu_array_alloc(1);
+ if (!objs)
+ return;
+ virtio_gpu_array_add_obj(objs, vgfb->base.obj[0]);
+ virtio_gpu_array_lock_resv(objs);
+ virtio_gpu_cmd_resource_flush(vgdev, bo->hw_res_handle, x, y,
+ width, height, objs, vgfb->fence);
+ virtio_gpu_notify(vgdev);
+
+ dma_fence_wait_timeout(&vgfb->fence->f, true,
+ msecs_to_jiffies(50));
+ dma_fence_put(&vgfb->fence->f);
+ vgfb->fence = NULL;
+ } else {
+ virtio_gpu_cmd_resource_flush(vgdev, bo->hw_res_handle, x, y,
+ width, height, NULL, NULL);
+ virtio_gpu_notify(vgdev);
+ }
+}
+
static void virtio_gpu_primary_plane_update(struct drm_plane *plane,
struct drm_atomic_state *state)
{
@@ -198,16 +232,15 @@ static void virtio_gpu_primary_plane_update(struct drm_plane *plane,
}
}
- virtio_gpu_cmd_resource_flush(vgdev, bo->hw_res_handle,
- rect.x1,
- rect.y1,
- rect.x2 - rect.x1,
- rect.y2 - rect.y1);
- virtio_gpu_notify(vgdev);
+ virtio_gpu_resource_flush(plane,
+ rect.x1,
+ rect.y1,
+ rect.x2 - rect.x1,
+ rect.y2 - rect.y1);
}
-static int virtio_gpu_cursor_prepare_fb(struct drm_plane *plane,
- struct drm_plane_state *new_state)
+static int virtio_gpu_plane_prepare_fb(struct drm_plane *plane,
+ struct drm_plane_state *new_state)
{
struct drm_device *dev = plane->dev;
struct virtio_gpu_device *vgdev = dev->dev_private;
@@ -219,7 +252,10 @@ static int virtio_gpu_cursor_prepare_fb(struct drm_plane *plane,
vgfb = to_virtio_gpu_framebuffer(new_state->fb);
bo = gem_to_virtio_gpu_obj(vgfb->base.obj[0]);
- if (bo && bo->dumb && (plane->state->fb != new_state->fb)) {
+ if (!bo || (plane->type == DRM_PLANE_TYPE_PRIMARY && !bo->guest_blob))
+ return 0;
+
+ if (bo->dumb && (plane->state->fb != new_state->fb)) {
vgfb->fence = virtio_gpu_fence_alloc(vgdev);
if (!vgfb->fence)
return -ENOMEM;
@@ -228,8 +264,8 @@ static int virtio_gpu_cursor_prepare_fb(struct drm_plane *plane,
return 0;
}
-static void virtio_gpu_cursor_cleanup_fb(struct drm_plane *plane,
- struct drm_plane_state *old_state)
+static void virtio_gpu_plane_cleanup_fb(struct drm_plane *plane,
+ struct drm_plane_state *old_state)
{
struct virtio_gpu_framebuffer *vgfb;
@@ -321,13 +357,15 @@ static void virtio_gpu_cursor_plane_update(struct drm_plane *plane,
}
static const struct drm_plane_helper_funcs virtio_gpu_primary_helper_funcs = {
+ .prepare_fb = virtio_gpu_plane_prepare_fb,
+ .cleanup_fb = virtio_gpu_plane_cleanup_fb,
.atomic_check = virtio_gpu_plane_atomic_check,
.atomic_update = virtio_gpu_primary_plane_update,
};
static const struct drm_plane_helper_funcs virtio_gpu_cursor_helper_funcs = {
- .prepare_fb = virtio_gpu_cursor_prepare_fb,
- .cleanup_fb = virtio_gpu_cursor_cleanup_fb,
+ .prepare_fb = virtio_gpu_plane_prepare_fb,
+ .cleanup_fb = virtio_gpu_plane_cleanup_fb,
.atomic_check = virtio_gpu_plane_atomic_check,
.atomic_update = virtio_gpu_cursor_plane_update,
};
diff --git a/drivers/gpu/drm/virtio/virtgpu_prime.c b/drivers/gpu/drm/virtio/virtgpu_prime.c
index 807a27a16365..e45dbf14b307 100644
--- a/drivers/gpu/drm/virtio/virtgpu_prime.c
+++ b/drivers/gpu/drm/virtio/virtgpu_prime.c
@@ -98,6 +98,8 @@ struct dma_buf *virtgpu_gem_prime_export(struct drm_gem_object *obj,
} else {
bo->uuid_state = STATE_ERR;
}
+ } else if (!(bo->blob_flags & VIRTGPU_BLOB_FLAG_USE_CROSS_DEVICE)) {
+ bo->uuid_state = STATE_ERR;
}
exp_info.ops = &virtgpu_dmabuf_ops.ops;
diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c
index cf84d382dd41..2e71e91278b4 100644
--- a/drivers/gpu/drm/virtio/virtgpu_vq.c
+++ b/drivers/gpu/drm/virtio/virtgpu_vq.c
@@ -576,13 +576,16 @@ void virtio_gpu_cmd_set_scanout(struct virtio_gpu_device *vgdev,
void virtio_gpu_cmd_resource_flush(struct virtio_gpu_device *vgdev,
uint32_t resource_id,
uint32_t x, uint32_t y,
- uint32_t width, uint32_t height)
+ uint32_t width, uint32_t height,
+ struct virtio_gpu_object_array *objs,
+ struct virtio_gpu_fence *fence)
{
struct virtio_gpu_resource_flush *cmd_p;
struct virtio_gpu_vbuffer *vbuf;
cmd_p = virtio_gpu_alloc_cmd(vgdev, &vbuf, sizeof(*cmd_p));
memset(cmd_p, 0, sizeof(*cmd_p));
+ vbuf->objs = objs;
cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_RESOURCE_FLUSH);
cmd_p->resource_id = cpu_to_le32(resource_id);
@@ -591,7 +594,7 @@ void virtio_gpu_cmd_resource_flush(struct virtio_gpu_device *vgdev,
cmd_p->r.x = cpu_to_le32(x);
cmd_p->r.y = cpu_to_le32(y);
- virtio_gpu_queue_ctrl_buffer(vgdev, vbuf);
+ virtio_gpu_queue_fenced_ctrl_buffer(vgdev, vbuf, fence);
}
void virtio_gpu_cmd_transfer_to_host_2d(struct virtio_gpu_device *vgdev,