From 9d340c2ab2a075843205ebb2cd516aa58b81d805 Mon Sep 17 00:00:00 2001 From: "Xue, Bosheng" Date: Wed, 16 Apr 2025 16:32:52 +0800 Subject: [PATCH 01/43] Revert "drm/virtio: process virtgpu bo before bo free" This reverts commit 28ae3c02469558be8fbf54cfc45fbd87797bee5c. --- drivers/gpu/drm/virtio/virtgpu_object.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c index 97af5af9551f..06a72085fd0d 100644 --- a/drivers/gpu/drm/virtio/virtgpu_object.c +++ b/drivers/gpu/drm/virtio/virtgpu_object.c @@ -98,9 +98,6 @@ void virtio_gpu_cleanup_object(struct virtio_gpu_object *bo) struct virtio_gpu_device *vgdev = bo->base.base.dev->dev_private; virtio_gpu_resource_id_put(vgdev, bo->hw_res_handle); - virtio_gpu_object_del_restore_list(vgdev, bo); - if (bo->prime) - kfree(bo->ents); if (virtio_gpu_is_shmem(bo)) { drm_gem_shmem_free(&bo->base); } else if (virtio_gpu_is_vram(bo)) { @@ -116,6 +113,11 @@ void virtio_gpu_cleanup_object(struct virtio_gpu_object *bo) drm_gem_object_release(&vram->base.base.base); kfree(vram); } + + if (bo->prime) + kfree(bo->ents); + + virtio_gpu_object_del_restore_list(vgdev, bo); } static void virtio_gpu_free_object(struct drm_gem_object *obj) From 3b09b78fa6521db5353a52b92d0788b8b0a06be8 Mon Sep 17 00:00:00 2001 From: "Xue, Bosheng" Date: Wed, 16 Apr 2025 16:32:53 +0800 Subject: [PATCH 02/43] Revert "drm/virtio: fix vqs_info memory allocation issue" This reverts commit c8fcb93e508755398462c057124c180016343a6c. --- drivers/gpu/drm/virtio/virtgpu_kms.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c index 8705ec980972..ad40cfb136ad 100644 --- a/drivers/gpu/drm/virtio/virtgpu_kms.c +++ b/drivers/gpu/drm/virtio/virtgpu_kms.c @@ -140,7 +140,7 @@ int virtio_gpu_find_vqs(struct virtio_gpu_device *vgdev) callbacks = kmalloc_array(total_vqs, sizeof(vq_callback_t *), GFP_KERNEL); names = kmalloc_array(total_vqs, sizeof(char *), GFP_KERNEL); - vqs_info = kmalloc_array(total_vqs, sizeof(struct virtqueue_info), + vqs_info = kmalloc_array(total_vqs, sizeof(struct virtqueue_info *), GFP_KERNEL); if (!callbacks || !vqs || !names || !vqs_info) { From 0797373ea523d71c11c080e3d8badcc7cef3008a Mon Sep 17 00:00:00 2001 From: "Xue, Bosheng" Date: Wed, 16 Apr 2025 16:32:54 +0800 Subject: [PATCH 03/43] Revert "drm/virtio: Reinstall vblank event when flip sequence doesn't pass" This reverts commit c9b1772f933f8532be7db1c9163684e23095a02f. --- drivers/gpu/drm/virtio/virtgpu_vq.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c index 0c1900318dee..4308b8677b45 100644 --- a/drivers/gpu/drm/virtio/virtgpu_vq.c +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c @@ -123,24 +123,12 @@ void virtio_gpu_vblank_ack(struct virtqueue *vq) return; struct drm_pending_vblank_event *e = xchg(&vgdev->cache_event[target], NULL); - if (!e) - return; - - if (drm_vblank_passed(atomic64_read(&vgdev->flip_sequence[target]), - e->sequence)) { + if (e && drm_vblank_passed(atomic64_read(&vgdev->flip_sequence[target]), + e->sequence)) { spin_lock_irqsave(&dev->event_lock, irqflags); drm_crtc_send_vblank_event(&vgdev->outputs[target].crtc, e); spin_unlock_irqrestore(&dev->event_lock, irqflags); drm_crtc_vblank_put(&vgdev->outputs[target].crtc); - } else { - WARN_ON((e = xchg(&vgdev->cache_event[target], e)) != NULL); - if (e) { - /* Should not come here ever, just in case... */ - spin_lock_irqsave(&dev->event_lock, irqflags); - drm_crtc_send_vblank_event(&vgdev->outputs[target].crtc, e); - spin_unlock_irqrestore(&dev->event_lock, irqflags); - drm_crtc_vblank_put(&vgdev->outputs[target].crtc); - } } } From 40353764e4e8b5f74904dcbf7cfa91eb739921f4 Mon Sep 17 00:00:00 2001 From: "Xue, Bosheng" Date: Wed, 16 Apr 2025 16:32:55 +0800 Subject: [PATCH 04/43] Revert "drm/virtio: Protect cached vblank event with atomic operations" This reverts commit 8735926f92f6c392e78b1d1f3a1c560c8728308d. --- drivers/gpu/drm/virtio/virtgpu_display.c | 14 +++++++------- drivers/gpu/drm/virtio/virtgpu_vq.c | 3 ++- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c index 76968ea7a759..361079a31c94 100644 --- a/drivers/gpu/drm/virtio/virtgpu_display.c +++ b/drivers/gpu/drm/virtio/virtgpu_display.c @@ -119,11 +119,11 @@ static void virtio_gpu_crtc_atomic_disable(struct drm_crtc *crtc, struct virtio_gpu_output *output = drm_crtc_to_virtio_gpu_output(crtc); const unsigned pipe = drm_crtc_index(crtc); - struct drm_pending_vblank_event *e = xchg(&vgdev->cache_event[pipe], NULL); /* Send cached event even it's still premature. */ - if (e) { + if (vgdev->cache_event[pipe]) { spin_lock_irq(&dev->event_lock); - drm_crtc_send_vblank_event(crtc, e); + drm_crtc_send_vblank_event(crtc, vgdev->cache_event[pipe]); + vgdev->cache_event[pipe] = NULL; spin_unlock_irq(&dev->event_lock); drm_crtc_vblank_put(crtc); } @@ -142,7 +142,7 @@ static void virtio_gpu_crtc_atomic_begin(struct drm_crtc *crtc, struct virtio_gpu_device *vgdev = crtc->dev->dev_private; struct drm_device *drm = crtc->dev; const unsigned pipe = drm_crtc_index(crtc); - struct drm_pending_vblank_event *old_e, *e = crtc->state->event; + struct drm_pending_vblank_event *e = crtc->state->event; if (!vgdev->has_vblank || !crtc->state->event) return; @@ -165,13 +165,13 @@ static void virtio_gpu_crtc_atomic_begin(struct drm_crtc *crtc, } else { crtc->state->event->sequence = atomic64_read(&vgdev->flip_sequence[pipe]) + 1; - old_e = xchg(&vgdev->cache_event[pipe], crtc->state->event); - if (old_e) { + if (vgdev->cache_event[pipe] != NULL) { spin_lock_irq(&drm->event_lock); - drm_crtc_send_vblank_event(crtc, old_e); + drm_crtc_send_vblank_event(crtc, vgdev->cache_event[pipe]); spin_unlock_irq(&drm->event_lock); drm_crtc_vblank_put(crtc); } + vgdev->cache_event[pipe] = crtc->state->event; } crtc->state->event = NULL; } diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c index 4308b8677b45..2fd173f8c69f 100644 --- a/drivers/gpu/drm/virtio/virtgpu_vq.c +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c @@ -122,11 +122,12 @@ void virtio_gpu_vblank_ack(struct virtqueue *vq) if (!vgdev->has_flip_sequence) return; - struct drm_pending_vblank_event *e = xchg(&vgdev->cache_event[target], NULL); + struct drm_pending_vblank_event *e = vgdev->cache_event[target]; if (e && drm_vblank_passed(atomic64_read(&vgdev->flip_sequence[target]), e->sequence)) { spin_lock_irqsave(&dev->event_lock, irqflags); drm_crtc_send_vblank_event(&vgdev->outputs[target].crtc, e); + vgdev->cache_event[target] = NULL; spin_unlock_irqrestore(&dev->event_lock, irqflags); drm_crtc_vblank_put(&vgdev->outputs[target].crtc); } From cb5d0bbb43d26d073736866b7c671f5b91deb5f0 Mon Sep 17 00:00:00 2001 From: "Xue, Bosheng" Date: Wed, 16 Apr 2025 16:32:55 +0800 Subject: [PATCH 05/43] Revert "drm/virtio: add support for VF LMEM type BLOB creation" This reverts commit edaa21c64c91a8c24941f3a097b9b5920436b0e2. --- drivers/gpu/drm/virtio/virtgpu_drv.h | 4 ---- drivers/gpu/drm/virtio/virtgpu_ioctl.c | 1 - drivers/gpu/drm/virtio/virtgpu_kms.c | 6 ------ drivers/gpu/drm/virtio/virtgpu_prime.c | 12 ------------ drivers/gpu/drm/virtio/virtgpu_vq.c | 16 ++-------------- include/uapi/drm/virtgpu_drm.h | 1 - include/uapi/linux/virtio_gpu.h | 1 - 7 files changed, 2 insertions(+), 39 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index befc4bd8dcbe..071b70dea813 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -99,8 +99,6 @@ struct virtio_gpu_object { int uuid_state; uuid_t uuid; /* Address cache for prime object */ - int locate; - /* Address cache for prime object */ struct virtio_gpu_mem_entry *ents; uint32_t nents; }; @@ -265,8 +263,6 @@ struct virtio_gpu_device { atomic64_t flip_sequence[VIRTIO_GPU_MAX_SCANOUTS]; uint32_t num_scanouts; uint32_t num_vblankq; - /* Setting '1' indicates the spcecific scanout is for dgpu output*/ - uint32_t output_cap_mask; struct virtio_gpu_queue ctrlq; struct virtio_gpu_queue cursorq; diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c index de502c8a0cd9..34d4605ffb03 100644 --- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c +++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c @@ -119,7 +119,6 @@ static int virtio_gpu_getparam_ioctl(struct drm_device *dev, void *data, break; case VIRTGPU_PARAM_ALLOW_P2P: value = vgdev->has_allow_p2p ? 1 : 0; - value = (value & 0xffff) | ((vgdev->output_cap_mask & 0xffff) << 16); break; case VIRTGPU_PARAM_EXPLICIT_DEBUG_NAME: value = vgdev->has_context_init ? 1 : 0; diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c index ad40cfb136ad..497e77d5a6fb 100644 --- a/drivers/gpu/drm/virtio/virtgpu_kms.c +++ b/drivers/gpu/drm/virtio/virtgpu_kms.c @@ -336,12 +336,6 @@ int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev) for(i=0; inum_vblankq; i++) spin_lock_init(&vgdev->vblank[i].vblank.qlock); - if (vgdev->has_allow_p2p) { - virtio_cread_le(vgdev->vdev, struct virtio_gpu_config, - output_bitmask, &vgdev->output_cap_mask); - DRM_INFO("p2p crtc bitmask 0x%x \r\n", vgdev->output_cap_mask); - } - ret = virtio_gpu_find_vqs(vgdev); if (ret) { DRM_ERROR("failed to find virt queues\n"); diff --git a/drivers/gpu/drm/virtio/virtgpu_prime.c b/drivers/gpu/drm/virtio/virtgpu_prime.c index e4aee3766855..9b82d82dd338 100644 --- a/drivers/gpu/drm/virtio/virtgpu_prime.c +++ b/drivers/gpu/drm/virtio/virtgpu_prime.c @@ -151,7 +151,6 @@ struct drm_gem_object *virtgpu_gem_prime_import(struct drm_device *dev, struct device *attach_dev = dev->dev; struct virtio_gpu_device *vgdev = dev->dev_private; int ret; - bool p2p = false; if (dma_buf->ops == &virtgpu_dmabuf_ops.ops) { obj = dma_buf->priv; @@ -172,13 +171,6 @@ struct drm_gem_object *virtgpu_gem_prime_import(struct drm_device *dev, if (!dev->driver->gem_prime_import_sg_table) return ERR_PTR(-EINVAL); - spin_lock(&dma_buf->name_lock); - if(vgdev->has_allow_p2p && dma_buf->name) { - if(strcmp(dma_buf->name, "p2p") == 0) - p2p = true; - } - spin_unlock(&dma_buf->name_lock); - attach = ____dma_buf_dynamic_attach(dma_buf, attach_dev, NULL, NULL, p2p); if (IS_ERR(attach)) @@ -298,10 +290,6 @@ struct drm_gem_object *virtgpu_gem_prime_import_sg_table( bo->guest_blob = true; bo->prime = true; - - if (attach->peer2peer) - bo->locate = 1; - params.blob_mem = VIRTGPU_BLOB_MEM_GUEST; params.blob_flags = VIRTGPU_BLOB_FLAG_USE_SHAREABLE; params.blob = true; diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c index 2fd173f8c69f..a7274e9a4db3 100644 --- a/drivers/gpu/drm/virtio/virtgpu_vq.c +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c @@ -1533,8 +1533,8 @@ void virtio_gpu_cmd_unmap(struct virtio_gpu_device *vgdev, virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); } -static void -virtio_gpu_cmd_resource_create_blob_internal(struct virtio_gpu_device *vgdev, +void +virtio_gpu_cmd_resource_create_blob(struct virtio_gpu_device *vgdev, struct virtio_gpu_object *bo, struct virtio_gpu_object_params *params, struct virtio_gpu_mem_entry *ents, @@ -1562,18 +1562,6 @@ virtio_gpu_cmd_resource_create_blob_internal(struct virtio_gpu_device *vgdev, bo->created = true; } -void -virtio_gpu_cmd_resource_create_blob(struct virtio_gpu_device *vgdev, - struct virtio_gpu_object *bo, - struct virtio_gpu_object_params *params, - struct virtio_gpu_mem_entry *ents, - uint32_t nents) -{ - if(bo->locate && vgdev->has_allow_p2p) - params->blob_flags |= VIRTGPU_BLOB_FLAG_USE_DEVICE_MEM; - virtio_gpu_cmd_resource_create_blob_internal(vgdev, bo, params, ents, nents); -} - void virtio_gpu_cmd_set_scanout_blob(struct virtio_gpu_device *vgdev, uint32_t scanout_id, struct virtio_gpu_object *bo, diff --git a/include/uapi/drm/virtgpu_drm.h b/include/uapi/drm/virtgpu_drm.h index 7e04f4ed93c9..a08074086a3d 100644 --- a/include/uapi/drm/virtgpu_drm.h +++ b/include/uapi/drm/virtgpu_drm.h @@ -181,7 +181,6 @@ struct drm_virtgpu_resource_create_blob { #define VIRTGPU_BLOB_FLAG_USE_MAPPABLE 0x0001 #define VIRTGPU_BLOB_FLAG_USE_SHAREABLE 0x0002 #define VIRTGPU_BLOB_FLAG_USE_CROSS_DEVICE 0x0004 -#define VIRTGPU_BLOB_FLAG_USE_DEVICE_MEM 0x0008 /* zero is invalid blob_mem */ __u32 blob_mem; __u32 blob_flags; diff --git a/include/uapi/linux/virtio_gpu.h b/include/uapi/linux/virtio_gpu.h index 658b32420077..6fd4bf60cced 100644 --- a/include/uapi/linux/virtio_gpu.h +++ b/include/uapi/linux/virtio_gpu.h @@ -492,7 +492,6 @@ struct virtio_gpu_config { __le32 num_scanouts; __le32 num_capsets; __le32 num_pipe; - __le32 output_bitmask; }; /* simple formats for fbcon/X use */ From b590da2684b75eb3053da2295c6b8ff2bb249ebe Mon Sep 17 00:00:00 2001 From: "Xue, Bosheng" Date: Wed, 16 Apr 2025 16:32:56 +0800 Subject: [PATCH 06/43] Revert "drm/virtio: Use flip sequence from virtio-GPU back-end" This reverts commit 6547410f640feac44e2a0ce266782b0b025acf88. --- drivers/gpu/drm/virtio/virtgpu_debugfs.c | 1 - drivers/gpu/drm/virtio/virtgpu_display.c | 145 +++-------------------- drivers/gpu/drm/virtio/virtgpu_drv.c | 1 - drivers/gpu/drm/virtio/virtgpu_drv.h | 11 -- drivers/gpu/drm/virtio/virtgpu_kms.c | 9 +- drivers/gpu/drm/virtio/virtgpu_vq.c | 28 +---- include/uapi/linux/virtio_gpu.h | 6 +- 7 files changed, 24 insertions(+), 177 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_debugfs.c b/drivers/gpu/drm/virtio/virtgpu_debugfs.c index a075f29b287b..cbca7289a1b0 100644 --- a/drivers/gpu/drm/virtio/virtgpu_debugfs.c +++ b/drivers/gpu/drm/virtio/virtgpu_debugfs.c @@ -57,7 +57,6 @@ static int virtio_gpu_features(struct seq_file *m, void *data) virtio_gpu_add_bool(m, "context init", vgdev->has_context_init); virtio_gpu_add_bool(m, "scaling", vgdev->has_scaling); virtio_gpu_add_bool(m, "allow_p2p", vgdev->has_allow_p2p); - virtio_gpu_add_bool(m, "flip_sequence", vgdev->has_flip_sequence); virtio_gpu_add_bool(m, "multi_plane", vgdev->has_multi_plane); virtio_gpu_add_bool(m, "rotation", vgdev->has_rotation); virtio_gpu_add_bool(m, "pixel_blend_mode", vgdev->has_pixel_blend_mode); diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c index 361079a31c94..cfa2ed6d037f 100644 --- a/drivers/gpu/drm/virtio/virtgpu_display.c +++ b/drivers/gpu/drm/virtio/virtgpu_display.c @@ -55,9 +55,8 @@ static int virtio_irq_enable_vblank(struct drm_crtc *crtc) struct virtio_gpu_device *vgdev = dev->dev_private; struct virtio_gpu_output *output = drm_crtc_to_virtio_gpu_output(crtc); - do { - virtio_gpu_vblank_poll_arm(vgdev->vblank[output->index].vblank.vq); - } while (!virtqueue_enable_cb(vgdev->vblank[output->index].vblank.vq)); + virtio_gpu_vblank_poll_arm(vgdev->vblank[output->index].vblank.vq); + virtqueue_enable_cb(vgdev->vblank[output->index].vblank.vq); return 0; } @@ -117,65 +116,14 @@ static void virtio_gpu_crtc_atomic_disable(struct drm_crtc *crtc, struct drm_device *dev = crtc->dev; struct virtio_gpu_device *vgdev = dev->dev_private; struct virtio_gpu_output *output = drm_crtc_to_virtio_gpu_output(crtc); - const unsigned pipe = drm_crtc_index(crtc); - - /* Send cached event even it's still premature. */ - if (vgdev->cache_event[pipe]) { - spin_lock_irq(&dev->event_lock); - drm_crtc_send_vblank_event(crtc, vgdev->cache_event[pipe]); - vgdev->cache_event[pipe] = NULL; - spin_unlock_irq(&dev->event_lock); - drm_crtc_vblank_put(crtc); - } - if (vgdev->has_vblank) { + if(vgdev->has_vblank) { drm_crtc_vblank_off(crtc); } - virtio_gpu_cmd_set_scanout(vgdev, output->index, 0, 0, 0, 0, 0); virtio_gpu_notify(vgdev); } -static void virtio_gpu_crtc_atomic_begin(struct drm_crtc *crtc, - struct drm_atomic_state *state) -{ - struct virtio_gpu_device *vgdev = crtc->dev->dev_private; - struct drm_device *drm = crtc->dev; - const unsigned pipe = drm_crtc_index(crtc); - struct drm_pending_vblank_event *e = crtc->state->event; - - if (!vgdev->has_vblank || !crtc->state->event) - return; - - if (drm_crtc_vblank_get(crtc)) { - /* Cannot enable vblank, send it right now. */ - spin_lock_irq(&drm->event_lock); - drm_crtc_send_vblank_event(crtc, e); - spin_unlock_irq(&drm->event_lock); - crtc->state->event = NULL; - return; - } - - if (!vgdev->has_flip_sequence) { - spin_lock_irq(&drm->event_lock); - /* Let drm_handle_vblank signal it later in the vblank interrupt - * and the vblank refcount will be released at that time. */ - drm_crtc_arm_vblank_event(crtc, e); - spin_unlock_irq(&drm->event_lock); - } else { - crtc->state->event->sequence = - atomic64_read(&vgdev->flip_sequence[pipe]) + 1; - if (vgdev->cache_event[pipe] != NULL) { - spin_lock_irq(&drm->event_lock); - drm_crtc_send_vblank_event(crtc, vgdev->cache_event[pipe]); - spin_unlock_irq(&drm->event_lock); - drm_crtc_vblank_put(crtc); - } - vgdev->cache_event[pipe] = crtc->state->event; - } - crtc->state->event = NULL; -} - static int virtio_gpu_crtc_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state) { @@ -213,8 +161,18 @@ static void virtio_gpu_crtc_atomic_flush(struct drm_crtc *crtc, struct virtio_gpu_output *output = drm_crtc_to_virtio_gpu_output(crtc); struct drm_device *drm = crtc->dev; struct virtio_gpu_device *vgdev = drm->dev_private; - const unsigned pipe = drm_crtc_index(crtc); + if(vgdev->has_vblank) { + if (crtc->state->event) { + spin_lock_irq(&drm->event_lock); + if (drm_crtc_vblank_get(crtc) != 0) + drm_crtc_send_vblank_event(crtc, crtc->state->event); + else + drm_crtc_arm_vblank_event(crtc, crtc->state->event); + spin_unlock_irq(&drm->event_lock); + crtc->state->event = NULL; + } + } if(vgdev->has_multi_plane) virtio_gpu_resource_flush_sync(crtc); @@ -234,7 +192,6 @@ static void virtio_gpu_crtc_atomic_flush(struct drm_crtc *crtc, static const struct drm_crtc_helper_funcs virtio_gpu_crtc_helper_funcs = { .mode_set_nofb = virtio_gpu_crtc_mode_set_nofb, - .atomic_begin = virtio_gpu_crtc_atomic_begin, .atomic_check = virtio_gpu_crtc_atomic_check, .atomic_flush = virtio_gpu_crtc_atomic_flush, .atomic_enable = virtio_gpu_crtc_atomic_enable, @@ -456,79 +413,6 @@ static const struct drm_mode_config_funcs virtio_gpu_mode_funcs = { .atomic_commit = drm_atomic_helper_commit, }; -static void -virtio_gpu_wait_for_vblanks(struct drm_device *dev, - struct drm_atomic_state *old_state) -{ - struct virtio_gpu_device *vgdev = dev->dev_private; - struct drm_crtc *crtc; - struct drm_crtc_state *old_crtc_state, *new_crtc_state; - int i, ret; - unsigned int crtc_mask = 0; - - /* - * Legacy cursor ioctls are completely unsynced, and userspace - * relies on that (by doing tons of cursor updates). - */ - if (old_state->legacy_cursor_update) - return; - - for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) { - if (!new_crtc_state->active) - continue; - - ret = drm_crtc_vblank_get(crtc); - if (ret != 0) - continue; - - crtc_mask |= drm_crtc_mask(crtc); - old_state->crtcs[i].last_vblank_count = - vgdev->has_vblank && vgdev->has_flip_sequence ? - atomic64_read(&vgdev->flip_sequence[i]) : - drm_crtc_vblank_count(crtc); - } - - for_each_old_crtc_in_state(old_state, crtc, old_crtc_state, i) { - if (!(crtc_mask & drm_crtc_mask(crtc))) - continue; - - ret = wait_event_timeout(dev->vblank[i].queue, - old_state->crtcs[i].last_vblank_count != - (vgdev->has_vblank && vgdev->has_flip_sequence ? - atomic64_read(&vgdev->flip_sequence[i]) : - drm_crtc_vblank_count(crtc)), - msecs_to_jiffies(100)); - - WARN(!ret, "[CRTC:%d:%s] vblank wait timed out\n", - crtc->base.id, crtc->name); - - drm_crtc_vblank_put(crtc); - } -} - -static void virtio_gpu_commit_tail(struct drm_atomic_state *old_state) -{ - struct drm_device *dev = old_state->dev; - - drm_atomic_helper_commit_modeset_disables(dev, old_state); - - drm_atomic_helper_commit_planes(dev, old_state, 0); - - drm_atomic_helper_commit_modeset_enables(dev, old_state); - - drm_atomic_helper_fake_vblank(old_state); - - drm_atomic_helper_commit_hw_done(old_state); - - virtio_gpu_wait_for_vblanks(dev, old_state); - - drm_atomic_helper_cleanup_planes(dev, old_state); -} - -static struct drm_mode_config_helper_funcs virtgio_gpu_mode_config_helpers = { - .atomic_commit_tail = virtio_gpu_commit_tail, -}; - int virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev) { int i, ret; @@ -541,7 +425,6 @@ int virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev) return ret; vgdev->ddev->mode_config.funcs = &virtio_gpu_mode_funcs; - vgdev->ddev->mode_config.helper_private = &virtgio_gpu_mode_config_helpers; /* modes will be validated against the framebuffer size */ vgdev->ddev->mode_config.min_width = XRES_MIN; diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c index afe760361dd7..e0469d1e8faf 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.c +++ b/drivers/gpu/drm/virtio/virtgpu_drv.c @@ -168,7 +168,6 @@ static unsigned int features[] = { VIRTIO_GPU_F_SCALING, VIRTIO_GPU_F_VBLANK, VIRTIO_GPU_F_ALLOW_P2P, - VIRTIO_GPU_F_FLIP_SEQUENCE, VIRTIO_GPU_F_MULTI_PLANE, VIRTIO_GPU_F_ROTATION, VIRTIO_GPU_F_PIXEL_BLEND_MODE, diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index 071b70dea813..48557fcf37fa 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -185,9 +185,6 @@ struct virtio_gpu_vbuffer { #define VIRTIO_GPU_MAX_PLANES 6 /*hardcode igpu scaler number ver>11 */ #define SKL_NUM_SCALERS 2 - -#define VBLANK_EVENT_CACHE_SIZE 3 - struct virtio_gpu_output { int index; struct drm_crtc crtc; @@ -248,19 +245,12 @@ struct virtio_gpu_vblank { uint32_t buf[4]; }; -static inline bool drm_vblank_passed(u64 seq, u64 ref) -{ - return (seq - ref) <= (1 << 23); -} - struct virtio_gpu_device { struct drm_device *ddev; struct virtio_device *vdev; struct virtio_gpu_output outputs[VIRTIO_GPU_MAX_SCANOUTS]; - struct drm_pending_vblank_event *cache_event[VIRTIO_GPU_MAX_SCANOUTS]; - atomic64_t flip_sequence[VIRTIO_GPU_MAX_SCANOUTS]; uint32_t num_scanouts; uint32_t num_vblankq; struct virtio_gpu_queue ctrlq; @@ -287,7 +277,6 @@ struct virtio_gpu_device { bool has_scaling; bool has_vblank; bool has_allow_p2p; - bool has_flip_sequence; bool has_multi_plane; bool has_rotation; bool has_pixel_blend_mode; diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c index 497e77d5a6fb..10ac86a69263 100644 --- a/drivers/gpu/drm/virtio/virtgpu_kms.c +++ b/drivers/gpu/drm/virtio/virtgpu_kms.c @@ -244,9 +244,6 @@ int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev) if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_ALLOW_P2P)) { vgdev->has_allow_p2p = true; } - if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_FLIP_SEQUENCE)) { - vgdev->has_flip_sequence = true; - } if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_MULTI_PLANE)) { vgdev->has_multi_plane = true; } @@ -300,10 +297,8 @@ int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev) vgdev->has_modifier ? '+' : '-', vgdev->has_multi_plane ? '+' : '-'); - DRM_INFO("features: %ccontext_init %callow_p2p %cflip_sequence\n", - vgdev->has_context_init ? '+' : '-', - vgdev->has_allow_p2p ? '+' : '-', - vgdev->has_flip_sequence ? '+' : '-'); + DRM_INFO("features: %ccontext_init\n", + vgdev->has_context_init ? '+' : '-'); /* get display info */ virtio_cread_le(vgdev->vdev, struct virtio_gpu_config, diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c index a7274e9a4db3..20f67da27ee5 100644 --- a/drivers/gpu/drm/virtio/virtgpu_vq.c +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c @@ -100,37 +100,21 @@ void virtio_gpu_vblank_ack(struct virtqueue *vq) unsigned long irqflags; unsigned int len; unsigned int *ret_value; - unsigned target = 0; + int target = 0; while((target < vgdev->num_vblankq) && (vgdev->vblank[target].vblank.vq != vq)) { target++; } - while ((ret_value = virtqueue_get_buf(vgdev->vblank[target].vblank.vq, &len)) != NULL) { - spin_lock_irqsave(&vgdev->vblank[target].vblank.qlock, irqflags); - virtgpu_irqqueue_buf(vgdev->vblank[target].vblank.vq, ret_value); - spin_unlock_irqrestore(&vgdev->vblank[target].vblank.qlock, irqflags); - - drm_handle_vblank(dev, target); - - if (*ret_value != 0) { - atomic64_set(&vgdev->flip_sequence[target], *ret_value); - } + spin_lock_irqsave(&vgdev->vblank[target].vblank.qlock, irqflags); + if((ret_value = virtqueue_get_buf(vgdev->vblank[target].vblank.vq, &len)) != NULL) { + virtgpu_irqqueue_buf(vgdev->vblank[target].vblank.vq, ret_value); } - if (!vgdev->has_flip_sequence) - return; + spin_unlock_irqrestore(&vgdev->vblank[target].vblank.qlock, irqflags); + drm_handle_vblank(dev, target); - struct drm_pending_vblank_event *e = vgdev->cache_event[target]; - if (e && drm_vblank_passed(atomic64_read(&vgdev->flip_sequence[target]), - e->sequence)) { - spin_lock_irqsave(&dev->event_lock, irqflags); - drm_crtc_send_vblank_event(&vgdev->outputs[target].crtc, e); - vgdev->cache_event[target] = NULL; - spin_unlock_irqrestore(&dev->event_lock, irqflags); - drm_crtc_vblank_put(&vgdev->outputs[target].crtc); - } } void virtio_gpu_cursor_ack(struct virtqueue *vq) diff --git a/include/uapi/linux/virtio_gpu.h b/include/uapi/linux/virtio_gpu.h index 6fd4bf60cced..1603994f97f4 100644 --- a/include/uapi/linux/virtio_gpu.h +++ b/include/uapi/linux/virtio_gpu.h @@ -75,6 +75,8 @@ #define VIRTIO_GPU_F_VBLANK 7 +#define VIRTIO_GPU_F_ALLOW_P2P 13 + /* * VIRTIO_GPU_CMD_FLUSH_SPRITE * VIRTIO_GPU_CMD_FLUSH_SYNC @@ -92,10 +94,6 @@ #define VIRTIO_GPU_F_MULTI_PLANAR_FORMAT 12 -#define VIRTIO_GPU_F_ALLOW_P2P 13 - -#define VIRTIO_GPU_F_FLIP_SEQUENCE 14 - #define VIRTIO_GPU_TUNNEL_CMD_SET_ROTATION 1 #define VIRTIO_GPU_TUNNEL_CMD_SET_BLEND 2 #define VIRTIO_GPU_TUNNEL_CMD_SET_PLANARS 3 From ed5ad7adf47513e7d11774e97fce985b5a9eec69 Mon Sep 17 00:00:00 2001 From: "Xue, Bosheng" Date: Wed, 16 Apr 2025 16:32:57 +0800 Subject: [PATCH 07/43] Revert "drm/virtio: Add a debugfs file to show object info" This reverts commit 3040ab5ce544bf4417c86044a02d40645fe70237. --- drivers/gpu/drm/virtio/virtgpu_debugfs.c | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_debugfs.c b/drivers/gpu/drm/virtio/virtgpu_debugfs.c index cbca7289a1b0..4045f4f0a125 100644 --- a/drivers/gpu/drm/virtio/virtgpu_debugfs.c +++ b/drivers/gpu/drm/virtio/virtgpu_debugfs.c @@ -101,30 +101,10 @@ virtio_gpu_debugfs_host_visible_mm(struct seq_file *m, void *data) return 0; } -static int -virtio_gpu_debugfs_objects(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *)m->private; - struct virtio_gpu_device *vgdev = node->minor->dev->dev_private; - struct virtio_gpu_object_restore *curr, *tmp; - - list_for_each_entry_safe(curr, tmp, &vgdev->obj_rec, node) { - seq_printf(m, "hw_res_handle=%u, prime=%d\n", - curr->bo->hw_res_handle, curr->bo->prime); - if (curr->bo->prime) - for (unsigned i = 0; i < curr->bo->nents; ++i) - seq_printf(m, "\taddr=%lx, size=%x\n", - curr->bo->ents[i].addr, - curr->bo->ents[i].length); - } - return 0; -} - static struct drm_info_list virtio_gpu_debugfs_list[] = { { "virtio-gpu-features", virtio_gpu_features }, { "virtio-gpu-irq-fence", virtio_gpu_debugfs_irq_info, 0, NULL }, { "virtio-gpu-host-visible-mm", virtio_gpu_debugfs_host_visible_mm }, - { "virtio-gpu-objects", virtio_gpu_debugfs_objects }, }; #define VIRTIO_GPU_DEBUGFS_ENTRIES ARRAY_SIZE(virtio_gpu_debugfs_list) From 22fbec0198736bb28a26d80bb6dc015dc02cca23 Mon Sep 17 00:00:00 2001 From: "Xue, Bosheng" Date: Wed, 16 Apr 2025 16:32:57 +0800 Subject: [PATCH 08/43] Revert "drm/virtio: Save address entries of PRIME objects" This reverts commit 8087db20704d4a74019567356386ce317517fd07. --- drivers/gpu/drm/virtio/virtgpu_drv.h | 4 ---- drivers/gpu/drm/virtio/virtgpu_object.c | 17 +++-------------- drivers/gpu/drm/virtio/virtgpu_prime.c | 11 ----------- 3 files changed, 3 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index 48557fcf37fa..7edcf88aa9f2 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -90,7 +90,6 @@ struct virtio_gpu_object { struct drm_gem_shmem_object base; uint32_t hw_res_handle; bool dumb; - bool prime; bool created; bool attached; bool host3d_blob, guest_blob; @@ -98,9 +97,6 @@ struct virtio_gpu_object { int uuid_state; uuid_t uuid; - /* Address cache for prime object */ - struct virtio_gpu_mem_entry *ents; - uint32_t nents; }; #define gem_to_virtio_gpu_obj(gobj) \ container_of((gobj), struct virtio_gpu_object, base.base) diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c index 06a72085fd0d..fb3a0abe1088 100644 --- a/drivers/gpu/drm/virtio/virtgpu_object.c +++ b/drivers/gpu/drm/virtio/virtgpu_object.c @@ -113,10 +113,6 @@ void virtio_gpu_cleanup_object(struct virtio_gpu_object *bo) drm_gem_object_release(&vram->base.base.base); kfree(vram); } - - if (bo->prime) - kfree(bo->ents); - virtio_gpu_object_del_restore_list(vgdev, bo); } @@ -317,16 +313,9 @@ int virtio_gpu_object_restore_all(struct virtio_gpu_device *vgdev) int ret; list_for_each_entry_safe(curr, tmp, &vgdev->obj_rec, node) { - if (curr->bo->prime) { - nents = curr->bo->nents; - ents = kmemdup(curr->bo->ents, - nents * sizeof(struct virtio_gpu_mem_entry), - GFP_KERNEL); - } else { - ret = virtio_gpu_object_shmem_init(vgdev, curr->bo, &ents, &nents); - if (ret) - break; - } + ret = virtio_gpu_object_shmem_init(vgdev, curr->bo, &ents, &nents); + if (ret) + break; if (curr->params.blob) { virtio_gpu_cmd_resource_create_blob(vgdev, curr->bo, &curr->params, diff --git a/drivers/gpu/drm/virtio/virtgpu_prime.c b/drivers/gpu/drm/virtio/virtgpu_prime.c index 9b82d82dd338..27456ea8c6ef 100644 --- a/drivers/gpu/drm/virtio/virtgpu_prime.c +++ b/drivers/gpu/drm/virtio/virtgpu_prime.c @@ -289,28 +289,17 @@ struct drm_gem_object *virtgpu_gem_prime_import_sg_table( } bo->guest_blob = true; - bo->prime = true; params.blob_mem = VIRTGPU_BLOB_MEM_GUEST; params.blob_flags = VIRTGPU_BLOB_FLAG_USE_SHAREABLE; params.blob = true; params.size = size; - bo->nents = nents; - bo->ents = kmemdup(ents, nents * sizeof(struct virtio_gpu_mem_entry), - GFP_KERNEL); - if (!bo->ents) { - ret = -ENOMEM; - goto err_free_ents; - } - virtio_gpu_cmd_resource_create_blob(vgdev, bo, ¶ms, ents, nents); virtio_gpu_object_save_restore_list(vgdev, bo, ¶ms); return obj; -err_free_ents: - kvfree(ents); err_put_id: virtio_gpu_resource_id_put(vgdev, bo->hw_res_handle); return ERR_PTR(ret); From fee43f6f2cccff4c3b672f9f5797092374e5a9f3 Mon Sep 17 00:00:00 2001 From: "Xue, Bosheng" Date: Wed, 16 Apr 2025 16:32:58 +0800 Subject: [PATCH 09/43] Revert "drm/virtio: put set modifier ahead of set scanout" This reverts commit b8188f7e10ba9d9330d8ae3dd852feeab3400e93. --- drivers/gpu/drm/virtio/virtgpu_drv.h | 1 - drivers/gpu/drm/virtio/virtgpu_plane.c | 4 ++-- drivers/gpu/drm/virtio/virtgpu_vq.c | 2 -- include/uapi/linux/virtio_gpu.h | 2 +- 4 files changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index 7edcf88aa9f2..09e80e37dcfe 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -489,7 +489,6 @@ virtio_gpu_cmd_set_scanout_blob(struct virtio_gpu_device *vgdev, uint32_t x, uint32_t y); void virtio_gpu_cmd_set_modifier(struct virtio_gpu_device *vgdev, uint32_t scanout_id, - struct virtio_gpu_object *bo, struct drm_framebuffer *fb); void virtio_gpu_cmd_set_scaling(struct virtio_gpu_device *vgdev, diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c index 75bdfb7e565d..4678610a985d 100644 --- a/drivers/gpu/drm/virtio/virtgpu_plane.c +++ b/drivers/gpu/drm/virtio/virtgpu_plane.c @@ -545,8 +545,6 @@ static void virtio_gpu_primary_plane_update(struct drm_plane *plane, plane->state->src_y >> 16); if (bo->host3d_blob || bo->guest_blob) { - if (vgdev->has_modifier) - virtio_gpu_cmd_set_modifier(vgdev, output->index, bo, plane->state->fb); virtio_gpu_cmd_set_scanout_blob (vgdev, output->index, bo, plane->state->fb, @@ -554,6 +552,8 @@ static void virtio_gpu_primary_plane_update(struct drm_plane *plane, plane->state->src_h >> 16, plane->state->src_x >> 16, plane->state->src_y >> 16); + if (vgdev->has_modifier) + virtio_gpu_cmd_set_modifier(vgdev, output->index, plane->state->fb); } else { virtio_gpu_cmd_set_scanout(vgdev, output->index, diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c index 20f67da27ee5..5931d7eedfa4 100644 --- a/drivers/gpu/drm/virtio/virtgpu_vq.c +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c @@ -1584,7 +1584,6 @@ void virtio_gpu_cmd_set_scanout_blob(struct virtio_gpu_device *vgdev, void virtio_gpu_cmd_set_modifier(struct virtio_gpu_device *vgdev, uint32_t scanout_id, - struct virtio_gpu_object *bo, struct drm_framebuffer *fb) { struct virtio_gpu_set_modifier *cmd_p; @@ -1595,7 +1594,6 @@ void virtio_gpu_cmd_set_modifier(struct virtio_gpu_device *vgdev, cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_SET_MODIFIER); cmd_p->modifier = cpu_to_le64(fb->modifier); cmd_p->scanout_id = cpu_to_le32(scanout_id); - cmd_p->resource_id = cpu_to_le32(bo->hw_res_handle); virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); } diff --git a/include/uapi/linux/virtio_gpu.h b/include/uapi/linux/virtio_gpu.h index 1603994f97f4..4de5414b4d05 100644 --- a/include/uapi/linux/virtio_gpu.h +++ b/include/uapi/linux/virtio_gpu.h @@ -559,7 +559,7 @@ struct virtio_gpu_set_modifier { struct virtio_gpu_ctrl_hdr hdr; __le64 modifier; __le32 scanout_id; - __le32 resource_id; + __le32 padding; }; /* VIRTIO_GPU_CMD_RESOURCE_MAP_BLOB */ From dc4698bfadd235bc444a536feb31d8e028fdd9d0 Mon Sep 17 00:00:00 2001 From: "Xue, Bosheng" Date: Wed, 16 Apr 2025 16:32:59 +0800 Subject: [PATCH 10/43] Revert "drm/virtio: Expose allow_p2p capability to user space" This reverts commit 063a3ab9b773ce94ec1dd53691d7464f78829ceb. --- drivers/gpu/drm/virtio/virtgpu_ioctl.c | 3 --- include/uapi/drm/virtgpu_drm.h | 1 - 2 files changed, 4 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c index 34d4605ffb03..11dbb65d0827 100644 --- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c +++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c @@ -117,9 +117,6 @@ static int virtio_gpu_getparam_ioctl(struct drm_device *dev, void *data, case VIRTGPU_PARAM_QUERY_DEV: value = (strcmp(dev->dev->driver->name, "virtio-pci") == 0) ? 1 : 0; break; - case VIRTGPU_PARAM_ALLOW_P2P: - value = vgdev->has_allow_p2p ? 1 : 0; - break; case VIRTGPU_PARAM_EXPLICIT_DEBUG_NAME: value = vgdev->has_context_init ? 1 : 0; break; diff --git a/include/uapi/drm/virtgpu_drm.h b/include/uapi/drm/virtgpu_drm.h index a08074086a3d..438366f77360 100644 --- a/include/uapi/drm/virtgpu_drm.h +++ b/include/uapi/drm/virtgpu_drm.h @@ -99,7 +99,6 @@ struct drm_virtgpu_execbuffer { #define VIRTGPU_PARAM_SUPPORTED_CAPSET_IDs 7 /* Bitmask of supported capability set ids */ #define VIRTGPU_PARAM_EXPLICIT_DEBUG_NAME 8 /* Ability to set debug name from userspace */ #define VIRTGPU_PARAM_QUERY_DEV 11 /* Query the virtio device name. */ -#define VIRTGPU_PARAM_ALLOW_P2P 12 /* do we accept local memory addresses */ struct drm_virtgpu_getparam { __u64 param; From 070a131c7f4824efc822e3c1b576c04273e1e7a7 Mon Sep 17 00:00:00 2001 From: "Xue, Bosheng" Date: Wed, 16 Apr 2025 16:32:59 +0800 Subject: [PATCH 11/43] Revert "drm/virtio: set max vblank number" This reverts commit a401268ee58ff4d2653d4e68ca331b12bd981824. --- drivers/gpu/drm/virtio/virtgpu_drv.h | 2 +- drivers/gpu/drm/virtio/virtgpu_kms.c | 42 +++++++++++++--------------- 2 files changed, 20 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index 09e80e37dcfe..bd73a05a6b60 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -301,7 +301,7 @@ struct virtio_gpu_device { spinlock_t resource_export_lock; /* protects map state and host_visible_mm */ spinlock_t host_visible_lock; - struct virtio_gpu_vblank vblank[VIRTIO_GPU_MAX_SCANOUTS]; + struct virtio_gpu_vblank vblank[]; }; struct virtio_gpu_fpriv { diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c index 10ac86a69263..c858589c4c9b 100644 --- a/drivers/gpu/drm/virtio/virtgpu_kms.c +++ b/drivers/gpu/drm/virtio/virtgpu_kms.c @@ -300,6 +300,25 @@ int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev) DRM_INFO("features: %ccontext_init\n", vgdev->has_context_init ? '+' : '-'); + vgdev->num_vblankq = 0; + if(vgdev->has_vblank) + virtio_cread_le(vgdev->vdev, struct virtio_gpu_config, + num_pipe, &vgdev->num_vblankq); + + for(i=0; inum_vblankq; i++) + spin_lock_init(&vgdev->vblank[i].vblank.qlock); + + ret = virtio_gpu_find_vqs(vgdev); + if (ret) { + DRM_ERROR("failed to find virt queues\n"); + goto err_vqs; + } + ret = virtio_gpu_alloc_vbufs(vgdev); + if (ret) { + DRM_ERROR("failed to alloc vbufs\n"); + goto err_vbufs; + } + /* get display info */ virtio_cread_le(vgdev->vdev, struct virtio_gpu_config, num_scanouts, &num_scanouts); @@ -319,29 +338,6 @@ int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev) num_capsets, &num_capsets); DRM_INFO("number of cap sets: %d\n", num_capsets); - vgdev->num_vblankq = 0; - if(vgdev->has_vblank) - virtio_cread_le(vgdev->vdev, struct virtio_gpu_config, - num_pipe, &vgdev->num_vblankq); - if (vgdev->num_vblankq > vgdev->num_scanouts) { - DRM_WARN("virtio gpu has wrong vblank number\n"); - vgdev->num_vblankq = vgdev->num_scanouts; - } - - for(i=0; inum_vblankq; i++) - spin_lock_init(&vgdev->vblank[i].vblank.qlock); - - ret = virtio_gpu_find_vqs(vgdev); - if (ret) { - DRM_ERROR("failed to find virt queues\n"); - goto err_vqs; - } - ret = virtio_gpu_alloc_vbufs(vgdev); - if (ret) { - DRM_ERROR("failed to alloc vbufs\n"); - goto err_vbufs; - } - virtio_device_ready(vgdev->vdev); if (num_capsets) From 91e3216f43dabaacd93904566444f451f5696140 Mon Sep 17 00:00:00 2001 From: "Xue, Bosheng" Date: Wed, 16 Apr 2025 16:33:00 +0800 Subject: [PATCH 12/43] Revert "drm/virtio: virtio gpu: add import dmabuf check" This reverts commit d2979b915ae8f0a8d3605f16c435d14b20b08202. --- drivers/gpu/drm/virtio/virtgpu_kms.c | 6 ------ drivers/gpu/drm/virtio/virtgpu_prime.c | 4 ---- 2 files changed, 10 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c index c858589c4c9b..6da193177c67 100644 --- a/drivers/gpu/drm/virtio/virtgpu_kms.c +++ b/drivers/gpu/drm/virtio/virtgpu_kms.c @@ -291,12 +291,6 @@ int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev) vgdev->has_resource_blob ? '+' : '-', vgdev->has_host_visible ? '+' : '-'); - DRM_INFO("features: %cscaling %cvblank %cmodifier %cmulti_plane", - vgdev->has_scaling ? '+' : '-', - vgdev->has_vblank ? '+' : '-', - vgdev->has_modifier ? '+' : '-', - vgdev->has_multi_plane ? '+' : '-'); - DRM_INFO("features: %ccontext_init\n", vgdev->has_context_init ? '+' : '-'); diff --git a/drivers/gpu/drm/virtio/virtgpu_prime.c b/drivers/gpu/drm/virtio/virtgpu_prime.c index 27456ea8c6ef..fea9ecea180c 100644 --- a/drivers/gpu/drm/virtio/virtgpu_prime.c +++ b/drivers/gpu/drm/virtio/virtgpu_prime.c @@ -164,10 +164,6 @@ struct drm_gem_object *virtgpu_gem_prime_import(struct drm_device *dev, } } - if (strcmp(dev->dev->driver->name, "virtio-ivshmem") == 0 || - strcmp(dev->dev->driver->name, "virtio-guest-shm") == 0) - return ERR_PTR(-EINVAL); - if (!dev->driver->gem_prime_import_sg_table) return ERR_PTR(-EINVAL); From 08505523cef0dc24ba948925b4d6fb4e6b92ab56 Mon Sep 17 00:00:00 2001 From: "Xue, Bosheng" Date: Wed, 16 Apr 2025 16:33:00 +0800 Subject: [PATCH 13/43] Revert "drm/virtio: Add ioctl to distinguish virtio-gpu and virtio-ivshemem" This reverts commit f1b693b17eeb7a80115c6455566639c5fcaa89a4. --- drivers/gpu/drm/virtio/virtgpu_ioctl.c | 3 --- include/uapi/drm/virtgpu_drm.h | 1 - 2 files changed, 4 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c index 11dbb65d0827..c33c057365f8 100644 --- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c +++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c @@ -114,9 +114,6 @@ static int virtio_gpu_getparam_ioctl(struct drm_device *dev, void *data, case VIRTGPU_PARAM_SUPPORTED_CAPSET_IDs: value = vgdev->capset_id_mask; break; - case VIRTGPU_PARAM_QUERY_DEV: - value = (strcmp(dev->dev->driver->name, "virtio-pci") == 0) ? 1 : 0; - break; case VIRTGPU_PARAM_EXPLICIT_DEBUG_NAME: value = vgdev->has_context_init ? 1 : 0; break; diff --git a/include/uapi/drm/virtgpu_drm.h b/include/uapi/drm/virtgpu_drm.h index 438366f77360..c2ce71987e9b 100644 --- a/include/uapi/drm/virtgpu_drm.h +++ b/include/uapi/drm/virtgpu_drm.h @@ -98,7 +98,6 @@ struct drm_virtgpu_execbuffer { #define VIRTGPU_PARAM_CONTEXT_INIT 6 /* DRM_VIRTGPU_CONTEXT_INIT */ #define VIRTGPU_PARAM_SUPPORTED_CAPSET_IDs 7 /* Bitmask of supported capability set ids */ #define VIRTGPU_PARAM_EXPLICIT_DEBUG_NAME 8 /* Ability to set debug name from userspace */ -#define VIRTGPU_PARAM_QUERY_DEV 11 /* Query the virtio device name. */ struct drm_virtgpu_getparam { __u64 param; From ac706320dbab7412ce8b67323c15d7a2b175a3ec Mon Sep 17 00:00:00 2001 From: "Xue, Bosheng" Date: Wed, 16 Apr 2025 16:33:01 +0800 Subject: [PATCH 14/43] Revert "drm/virtio: Fix virtio-gpu uses symbol from namespace DMA_BUF but not import it" This reverts commit d94a698cd304daf8ce6ffd865e160229694f0c85. --- drivers/gpu/drm/virtio/virtgpu_drv.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c index e0469d1e8faf..53d5cd1f750a 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.c +++ b/drivers/gpu/drm/virtio/virtgpu_drv.c @@ -46,8 +46,6 @@ static const struct drm_driver driver; static int virtio_gpu_modeset = -1; -MODULE_IMPORT_NS(DMA_BUF); - MODULE_PARM_DESC(modeset, "Disable/Enable modesetting"); module_param_named(modeset, virtio_gpu_modeset, int, 0400); From 43825584304102e645cd03d44b5895f53d4a9700 Mon Sep 17 00:00:00 2001 From: "Xue, Bosheng" Date: Wed, 16 Apr 2025 16:33:02 +0800 Subject: [PATCH 15/43] Revert "drm/virtio: Change value of feature ALLOW_P2P to 13" This reverts commit e67127c1d48fd58b0c40b3a0b6a6d35bcc76b515. --- include/uapi/linux/virtio_gpu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/uapi/linux/virtio_gpu.h b/include/uapi/linux/virtio_gpu.h index 4de5414b4d05..09a8842ad7a7 100644 --- a/include/uapi/linux/virtio_gpu.h +++ b/include/uapi/linux/virtio_gpu.h @@ -75,7 +75,7 @@ #define VIRTIO_GPU_F_VBLANK 7 -#define VIRTIO_GPU_F_ALLOW_P2P 13 +#define VIRTIO_GPU_F_ALLOW_P2P 31 /* * VIRTIO_GPU_CMD_FLUSH_SPRITE From 606307fb302275909f5f9c7e5139ed69a6a4e412 Mon Sep 17 00:00:00 2001 From: "Xue, Bosheng" Date: Wed, 16 Apr 2025 16:33:02 +0800 Subject: [PATCH 16/43] Revert "drm/virtio: Add multiple planar format buffer support" This reverts commit 5fe73007be14eadc2e8d88297206a57c4f3948c9. --- drivers/gpu/drm/virtio/virtgpu_debugfs.c | 1 - drivers/gpu/drm/virtio/virtgpu_display.c | 57 ++++++++++++------------ drivers/gpu/drm/virtio/virtgpu_drv.c | 1 - drivers/gpu/drm/virtio/virtgpu_drv.h | 1 - drivers/gpu/drm/virtio/virtgpu_kms.c | 3 -- drivers/gpu/drm/virtio/virtgpu_plane.c | 27 +---------- include/uapi/linux/virtio_gpu.h | 1 - 7 files changed, 31 insertions(+), 60 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_debugfs.c b/drivers/gpu/drm/virtio/virtgpu_debugfs.c index 4045f4f0a125..0ee1b528cff7 100644 --- a/drivers/gpu/drm/virtio/virtgpu_debugfs.c +++ b/drivers/gpu/drm/virtio/virtgpu_debugfs.c @@ -60,7 +60,6 @@ static int virtio_gpu_features(struct seq_file *m, void *data) virtio_gpu_add_bool(m, "multi_plane", vgdev->has_multi_plane); virtio_gpu_add_bool(m, "rotation", vgdev->has_rotation); virtio_gpu_add_bool(m, "pixel_blend_mode", vgdev->has_pixel_blend_mode); - virtio_gpu_add_bool(m, "multi_planar", vgdev->has_multi_planar); virtio_gpu_add_bool(m, "modifier", vgdev->has_modifier); virtio_gpu_add_int(m, "cap sets", vgdev->num_capsets); virtio_gpu_add_int(m, "scanouts", vgdev->num_scanouts); diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c index cfa2ed6d037f..20978c766a00 100644 --- a/drivers/gpu/drm/virtio/virtgpu_display.c +++ b/drivers/gpu/drm/virtio/virtgpu_display.c @@ -88,6 +88,26 @@ static const struct drm_framebuffer_funcs virtio_gpu_fb_funcs = { .dirty = drm_atomic_helper_dirtyfb, }; +static 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) +{ + int ret; + + vgfb->base.obj[0] = obj; + + drm_helper_mode_fill_fb_struct(dev, &vgfb->base, mode_cmd); + + ret = drm_framebuffer_init(dev, &vgfb->base, &virtio_gpu_fb_funcs); + if (ret) { + vgfb->base.obj[0] = NULL; + return ret; + } + return 0; +} + static void virtio_gpu_crtc_mode_set_nofb(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; @@ -365,46 +385,27 @@ virtio_gpu_user_framebuffer_create(struct drm_device *dev, { struct drm_gem_object *obj = NULL; struct virtio_gpu_framebuffer *virtio_gpu_fb; - - const struct drm_format_info *info; - struct drm_gem_object *objs[DRM_FORMAT_MAX_PLANES]; - - unsigned int i; int ret; - info = drm_get_format_info(dev, mode_cmd); - if (!info) { - drm_dbg_kms(dev, "Failed to get FB format info\n"); + /* lookup object associated with res handle */ + obj = drm_gem_object_lookup(file_priv, mode_cmd->handles[0]); + if (!obj) return ERR_PTR(-EINVAL); - } virtio_gpu_fb = kzalloc(sizeof(*virtio_gpu_fb), GFP_KERNEL); if (virtio_gpu_fb == NULL) { + drm_gem_object_put(obj); return ERR_PTR(-ENOMEM); } - for (i = 0; i < info->num_planes; i++) { - objs[i] = drm_gem_object_lookup(file_priv, mode_cmd->handles[i]); - if (!objs[i]) { - drm_dbg_kms(dev, "Failed to lookup GEM object\n"); - goto error; - } - virtio_gpu_fb->base.obj[i] = objs[i]; + ret = virtio_gpu_framebuffer_init(dev, virtio_gpu_fb, mode_cmd, obj); + if (ret) { + kfree(virtio_gpu_fb); + drm_gem_object_put(obj); + return NULL; } - drm_helper_mode_fill_fb_struct(dev, &virtio_gpu_fb->base, mode_cmd); - ret = drm_framebuffer_init(dev, &virtio_gpu_fb->base, &virtio_gpu_fb_funcs); - if (ret) - goto error; - return &virtio_gpu_fb->base; -error: - kfree(virtio_gpu_fb); - while (i > 0) { - --i; - drm_gem_object_put(objs[i]); - } - return ERR_PTR(ret); } static const struct drm_mode_config_funcs virtio_gpu_mode_funcs = { diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c index 53d5cd1f750a..8a20167e8159 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.c +++ b/drivers/gpu/drm/virtio/virtgpu_drv.c @@ -169,7 +169,6 @@ static unsigned int features[] = { VIRTIO_GPU_F_MULTI_PLANE, VIRTIO_GPU_F_ROTATION, VIRTIO_GPU_F_PIXEL_BLEND_MODE, - VIRTIO_GPU_F_MULTI_PLANAR_FORMAT, }; #ifdef CONFIG_PM_SLEEP diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index bd73a05a6b60..2761ee82beac 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -276,7 +276,6 @@ struct virtio_gpu_device { bool has_multi_plane; bool has_rotation; bool has_pixel_blend_mode; - bool has_multi_planar; bool has_indirect; bool has_resource_assign_uuid; bool has_resource_blob; diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c index 6da193177c67..30a6ef76e849 100644 --- a/drivers/gpu/drm/virtio/virtgpu_kms.c +++ b/drivers/gpu/drm/virtio/virtgpu_kms.c @@ -253,9 +253,6 @@ int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev) if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_PIXEL_BLEND_MODE)) { vgdev->has_pixel_blend_mode = true; } - if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_MULTI_PLANAR_FORMAT)) { - vgdev->has_multi_planar = true; - } if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_RESOURCE_BLOB)) { vgdev->has_resource_blob = true; if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_MODIFIER)) { diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c index 4678610a985d..d0a50077205c 100644 --- a/drivers/gpu/drm/virtio/virtgpu_plane.c +++ b/drivers/gpu/drm/virtio/virtgpu_plane.c @@ -31,7 +31,7 @@ #include "virtgpu_drv.h" -static uint32_t virtio_gpu_formats[] = { +static const uint32_t virtio_gpu_formats[] = { DRM_FORMAT_XRGB8888, DRM_FORMAT_ARGB8888, DRM_FORMAT_BGRX8888, @@ -115,9 +115,6 @@ uint32_t virtio_gpu_translate_format(uint32_t drm_fourcc) case DRM_FORMAT_ABGR8888: format = VIRTIO_GPU_FORMAT_R8G8B8A8_UNORM; break; - case DRM_FORMAT_NV12: - format = DRM_FORMAT_NV12; - break; #endif default: /* @@ -396,12 +393,7 @@ static void virtio_gpu_resource_flush_sprite(struct drm_plane *plane, int indx, kfree(fence); return; } - virtio_gpu_array_add_obj(objs, vgfb->base.obj[0]); - for(i=1; iformat->num_planes; i++) { - if(vgfb->base.obj[i] != vgfb->base.obj[0]) - virtio_gpu_array_add_obj(objs, vgfb->base.obj[i]); - } virtio_gpu_array_lock_resv(objs); } @@ -590,18 +582,7 @@ static void virtio_gpu_primary_plane_update(struct drm_plane *plane, cmd_set[cnt].data32[1]=(uint32_t)plane->state->alpha; cnt++; } - if ((vgdev->has_multi_planar) && (plane->state->fb->format->num_planes > 1)) { - struct virtio_gpu_framebuffer *vgfb; - cmd_set[cnt].cmd = VIRTIO_GPU_TUNNEL_CMD_SET_PLANARS; - cmd_set[cnt].size = plane->state->fb->format->num_planes-1; - vgfb = to_virtio_gpu_framebuffer(plane->state->fb); - for(i=1; i< plane->state->fb->format->num_planes; i++) { - struct virtio_gpu_object *bo; - bo = gem_to_virtio_gpu_obj(vgfb->base.obj[i]); - cmd_set[cnt].data32[i-1] = bo->hw_res_handle; - } - cnt++; - } + if(cnt) { virtio_gpu_cmd_send_misc(vgdev, output->index, plane->index, cmd_set, cnt); } @@ -837,10 +818,6 @@ struct drm_plane *virtio_gpu_plane_init(struct virtio_gpu_device *vgdev, } else { formats = virtio_gpu_formats; nformats = ARRAY_SIZE(virtio_gpu_formats); - if(vgdev->has_multi_planar) { - virtio_gpu_formats[nformats] = DRM_FORMAT_NV12; - nformats++; - } funcs = &virtio_gpu_primary_helper_funcs; } diff --git a/include/uapi/linux/virtio_gpu.h b/include/uapi/linux/virtio_gpu.h index 09a8842ad7a7..b9334480ef96 100644 --- a/include/uapi/linux/virtio_gpu.h +++ b/include/uapi/linux/virtio_gpu.h @@ -92,7 +92,6 @@ #define VIRTIO_GPU_F_PIXEL_BLEND_MODE 11 -#define VIRTIO_GPU_F_MULTI_PLANAR_FORMAT 12 #define VIRTIO_GPU_TUNNEL_CMD_SET_ROTATION 1 #define VIRTIO_GPU_TUNNEL_CMD_SET_BLEND 2 From 6fac09df9a2bd079c7c024ac2456588a3f7e0a92 Mon Sep 17 00:00:00 2001 From: "Xue, Bosheng" Date: Wed, 16 Apr 2025 16:33:03 +0800 Subject: [PATCH 17/43] Revert "drm/virtio: Add sprite planes support for virtio gpu" This reverts commit faee350652fbf59ea89bee61c6cbaa21132a6849. --- drivers/gpu/drm/virtio/virtgpu_debugfs.c | 3 - drivers/gpu/drm/virtio/virtgpu_display.c | 41 --- drivers/gpu/drm/virtio/virtgpu_drv.c | 3 - drivers/gpu/drm/virtio/virtgpu_drv.h | 36 --- drivers/gpu/drm/virtio/virtgpu_kms.c | 34 +-- drivers/gpu/drm/virtio/virtgpu_plane.c | 336 +---------------------- drivers/gpu/drm/virtio/virtgpu_vq.c | 167 +---------- include/uapi/linux/virtio_gpu.h | 102 ------- 8 files changed, 8 insertions(+), 714 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_debugfs.c b/drivers/gpu/drm/virtio/virtgpu_debugfs.c index 0ee1b528cff7..bfcb1ac9ab8c 100644 --- a/drivers/gpu/drm/virtio/virtgpu_debugfs.c +++ b/drivers/gpu/drm/virtio/virtgpu_debugfs.c @@ -57,9 +57,6 @@ static int virtio_gpu_features(struct seq_file *m, void *data) virtio_gpu_add_bool(m, "context init", vgdev->has_context_init); virtio_gpu_add_bool(m, "scaling", vgdev->has_scaling); virtio_gpu_add_bool(m, "allow_p2p", vgdev->has_allow_p2p); - virtio_gpu_add_bool(m, "multi_plane", vgdev->has_multi_plane); - virtio_gpu_add_bool(m, "rotation", vgdev->has_rotation); - virtio_gpu_add_bool(m, "pixel_blend_mode", vgdev->has_pixel_blend_mode); virtio_gpu_add_bool(m, "modifier", vgdev->has_modifier); virtio_gpu_add_int(m, "cap sets", vgdev->num_capsets); virtio_gpu_add_int(m, "scanouts", vgdev->num_scanouts); diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c index 20978c766a00..e498b60af06d 100644 --- a/drivers/gpu/drm/virtio/virtgpu_display.c +++ b/drivers/gpu/drm/virtio/virtgpu_display.c @@ -147,32 +147,9 @@ static void virtio_gpu_crtc_atomic_disable(struct drm_crtc *crtc, static int virtio_gpu_crtc_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state) { - struct virtio_gpu_output *output = NULL; - struct drm_device *dev = crtc->dev; - int num_scalers_need; - struct virtio_gpu_device *vgdev = dev->dev_private; - - output = drm_crtc_to_virtio_gpu_output(crtc); - if(vgdev->has_scaling) { - num_scalers_need = hweight32(output->scaler_users); - if(num_scalers_need > SKL_NUM_SCALERS) { - drm_dbg_kms(dev, "Too many scaling requests %d > %d\n", num_scalers_need, SKL_NUM_SCALERS); - output->scaler_users = 0; - return -EINVAL; - } - } return 0; } -static void virtio_gpu_resource_flush_sync(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - struct virtio_gpu_device *vgdev = dev->dev_private; - struct virtio_gpu_output *output = drm_crtc_to_virtio_gpu_output(crtc); - virtio_gpu_cmd_flush_sync(vgdev, output->index); - virtio_gpu_notify(vgdev); -} - static void virtio_gpu_crtc_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_state *state) { @@ -193,11 +170,6 @@ static void virtio_gpu_crtc_atomic_flush(struct drm_crtc *crtc, crtc->state->event = NULL; } } - if(vgdev->has_multi_plane) - virtio_gpu_resource_flush_sync(crtc); - - if(vgdev->has_scaling) - output->scaler_users = 0; /* * virtio-gpu can't do modeset and plane update operations @@ -340,25 +312,12 @@ static int vgdev_output_init(struct virtio_gpu_device *vgdev, int index) output->info.r.height = cpu_to_le32(YRES_DEF); } - if(vgdev->has_scaling) - output->scaler_users = 0; primary = virtio_gpu_plane_init(vgdev, DRM_PLANE_TYPE_PRIMARY, index); if (IS_ERR(primary)) return PTR_ERR(primary); cursor = virtio_gpu_plane_init(vgdev, DRM_PLANE_TYPE_CURSOR, index); if (IS_ERR(cursor)) return PTR_ERR(cursor); - - if(vgdev->has_multi_plane) { - struct drm_plane *sprite; - int i; - for(i=0; i< vgdev->outputs[index].plane_num; i++) { - sprite = virtio_gpu_plane_init(vgdev, DRM_PLANE_TYPE_OVERLAY, index); - if (IS_ERR(sprite)) - return PTR_ERR(sprite); - } - } - drm_crtc_init_with_planes(dev, crtc, primary, cursor, &virtio_gpu_crtc_funcs, NULL); drm_crtc_helper_add(crtc, &virtio_gpu_crtc_helper_funcs); diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c index 8a20167e8159..5385b43b28ed 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.c +++ b/drivers/gpu/drm/virtio/virtgpu_drv.c @@ -166,9 +166,6 @@ static unsigned int features[] = { VIRTIO_GPU_F_SCALING, VIRTIO_GPU_F_VBLANK, VIRTIO_GPU_F_ALLOW_P2P, - VIRTIO_GPU_F_MULTI_PLANE, - VIRTIO_GPU_F_ROTATION, - VIRTIO_GPU_F_PIXEL_BLEND_MODE, }; #ifdef CONFIG_PM_SLEEP diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index 2761ee82beac..6fa8093564f6 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -178,9 +178,6 @@ struct virtio_gpu_vbuffer { uint32_t seqno; }; -#define VIRTIO_GPU_MAX_PLANES 6 -/*hardcode igpu scaler number ver>11 */ -#define SKL_NUM_SCALERS 2 struct virtio_gpu_output { int index; struct drm_crtc crtc; @@ -192,9 +189,6 @@ struct virtio_gpu_output { int cur_x; int cur_y; bool needs_modeset; - int plane_num; - uint64_t rotation[VIRTIO_GPU_MAX_PLANES]; - unsigned scaler_users; }; #define drm_crtc_to_virtio_gpu_output(x) \ container_of(x, struct virtio_gpu_output, crtc) @@ -273,9 +267,6 @@ struct virtio_gpu_device { bool has_scaling; bool has_vblank; bool has_allow_p2p; - bool has_multi_plane; - bool has_rotation; - bool has_pixel_blend_mode; bool has_indirect; bool has_resource_assign_uuid; bool has_resource_blob; @@ -377,21 +368,6 @@ 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, uint32_t x, uint32_t y); - -void virtio_gpu_cmd_flush_sync(struct virtio_gpu_device *vgdev, - uint32_t scanout_id); - -void virtio_gpu_cmd_resource_flush_sprite(struct virtio_gpu_device *vgdev, - uint32_t scanout_id, - uint32_t plane_indx, - struct drm_framebuffer *fb, - uint32_t *resource_id, - uint32_t resource_cnt, - uint32_t x, uint32_t y, - uint32_t width, uint32_t height, - struct virtio_gpu_object_array *objs, - struct virtio_gpu_fence *fence); - void virtio_gpu_object_attach(struct virtio_gpu_device *vgdev, struct virtio_gpu_object *obj, struct virtio_gpu_mem_entry *ents, @@ -471,14 +447,6 @@ virtio_gpu_cmd_resource_create_blob(struct virtio_gpu_device *vgdev, struct virtio_gpu_object_params *params, struct virtio_gpu_mem_entry *ents, uint32_t nents); - - -int virtio_gpu_cmd_get_planes_info(struct virtio_gpu_device *vgdev, int idx); - - -int virtio_gpu_cmd_get_plane_rotation(struct virtio_gpu_device *vgdev, - uint32_t plane_id, uint32_t scanout_indx); - void virtio_gpu_cmd_set_scanout_blob(struct virtio_gpu_device *vgdev, uint32_t scanout_id, @@ -494,9 +462,6 @@ void virtio_gpu_cmd_set_scaling(struct virtio_gpu_device *vgdev, uint32_t scanout_id, struct drm_rect *rect_dst); -void virtio_gpu_cmd_send_misc(struct virtio_gpu_device *vgdev, uint32_t scanout_id, - uint32_t plane_indx, struct virtio_gpu_cmd *cmdp, int cnt); - /* virtgpu_display.c */ int virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev); void virtio_gpu_modeset_fini(struct virtio_gpu_device *vgdev); @@ -506,7 +471,6 @@ uint32_t virtio_gpu_translate_format(uint32_t drm_fourcc); struct drm_plane *virtio_gpu_plane_init(struct virtio_gpu_device *vgdev, enum drm_plane_type type, int index); -void virtio_update_planes_info(int index, int num, u32 *info); /* virtgpu_fence.c */ struct virtio_gpu_fence *virtio_gpu_fence_alloc(struct virtio_gpu_device *vgdev, diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c index 30a6ef76e849..4d450e6751b8 100644 --- a/drivers/gpu/drm/virtio/virtgpu_kms.c +++ b/drivers/gpu/drm/virtio/virtgpu_kms.c @@ -114,18 +114,6 @@ static void virtio_gpu_get_capsets(struct virtio_gpu_device *vgdev, vgdev->num_capsets = num_capsets; } -static void virtio_gpu_get_planes(struct virtio_gpu_device *vgdev) -{ - int i; - for(i=0; i < vgdev->num_scanouts; i++) { - vgdev->outputs[i].plane_num = 0; - virtio_gpu_cmd_get_planes_info(vgdev, i); - virtio_gpu_notify(vgdev); - wait_event_timeout(vgdev->resp_wq, - vgdev->outputs[i].plane_num, 5 * HZ); - } -} - int virtio_gpu_find_vqs(struct virtio_gpu_device *vgdev) { struct virtqueue_info *vqs_info; @@ -244,15 +232,6 @@ int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev) if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_ALLOW_P2P)) { vgdev->has_allow_p2p = true; } - if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_MULTI_PLANE)) { - vgdev->has_multi_plane = true; - } - if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_ROTATION)) { - vgdev->has_rotation = true; - } - if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_PIXEL_BLEND_MODE)) { - vgdev->has_pixel_blend_mode = true; - } if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_RESOURCE_BLOB)) { vgdev->has_resource_blob = true; if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_MODIFIER)) { @@ -329,20 +308,17 @@ int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev) num_capsets, &num_capsets); DRM_INFO("number of cap sets: %d\n", num_capsets); - virtio_device_ready(vgdev->vdev); - - if (num_capsets) - virtio_gpu_get_capsets(vgdev, num_capsets); - - if(vgdev->has_multi_plane) - virtio_gpu_get_planes(vgdev); - ret = virtio_gpu_modeset_init(vgdev); if (ret) { DRM_ERROR("modeset init failed\n"); goto err_scanouts; } + virtio_device_ready(vgdev->vdev); + + if (num_capsets) + virtio_gpu_get_capsets(vgdev, num_capsets); + virtio_gpu_vblankq_notify(vgdev); for(i=0; i < vgdev->num_vblankq; i++) diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c index d0a50077205c..3ca5bb5a3ebb 100644 --- a/drivers/gpu/drm/virtio/virtgpu_plane.c +++ b/drivers/gpu/drm/virtio/virtgpu_plane.c @@ -27,7 +27,6 @@ #include #include #include -#include #include "virtgpu_drv.h" @@ -46,20 +45,6 @@ static const uint32_t virtio_gpu_cursor_formats[] = { DRM_FORMAT_HOST_ARGB8888, }; -static struct plane_format { - uint32_t size; - uint32_t format_info[128]; -}; - -static struct output_planes_format { - - /* presumably take 5 as the max, since i915 only has 5 planes per pipe */ - struct plane_format planes[5]; - int sprite_plane_index; - -} virtio_gpu_output_planes_formats[16]; - - uint32_t virtio_gpu_translate_format(uint32_t drm_fourcc) { uint32_t format; @@ -153,105 +138,6 @@ static struct drm_plane_funcs virtio_gpu_plane_funcs = { .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, }; -static int virtio_gpu_check_plane_rotation(struct drm_plane_state *state, - struct virtio_gpu_output *output) -{ - int index; - index = state->plane->index; - - if(!(state->rotation & output->rotation[index])) { - DRM_DEBUG("sprite plane rotation check failed \n"); - return -EINVAL; - } - return 0; -} - -#define ICL_MAX_SRC_W 5120 -#define ICL_MAX_SRC_H 4096 -#define ICL_MAX_DST_W 5120 -#define ICL_MAX_DST_H 4096 -#define SKL_MIN_SRC_W 8 -#define SKL_MIN_SRC_H 8 -#define SKL_MIN_DST_W 8 -#define SKL_MIN_DST_H 8 - -static int virtio_gpu_check_plane_scaling(struct drm_plane_state *state, - struct virtio_gpu_output *output) -{ - int scaler_user = drm_plane_index(state->plane); - int src_w, src_h, dst_w, dst_h; - struct drm_framebuffer *fb = state->fb; - output = drm_crtc_to_virtio_gpu_output(state->crtc); - src_w = state->src_w >> 16; - src_h = state->src_h >> 16; - dst_w = state->crtc_w; - dst_h = state->crtc_h; - - if (src_w == dst_w && src_h == dst_h) - return 0; - /*hard code the format and scale check as physical gpu */ - if (src_w > ICL_MAX_SRC_W || src_h > ICL_MAX_SRC_H || - dst_w > ICL_MAX_DST_W || dst_h > ICL_MAX_DST_H || - src_w < SKL_MIN_SRC_W || src_h < SKL_MIN_SRC_H || - dst_w < SKL_MIN_DST_W || dst_h < SKL_MIN_DST_H) { - - drm_dbg_kms(state->plane->dev, - "scaler_user index %u: src %ux%u dst %ux%u " - "size is out of scaler range\n", - scaler_user, src_w, src_h, - dst_w, dst_h); - - return -EINVAL; - - } - - if(fb) { - switch (fb->format->format) { - case DRM_FORMAT_RGB565: - case DRM_FORMAT_XBGR8888: - case DRM_FORMAT_XRGB8888: - case DRM_FORMAT_ABGR8888: - case DRM_FORMAT_ARGB8888: - case DRM_FORMAT_XRGB2101010: - case DRM_FORMAT_XBGR2101010: - case DRM_FORMAT_ARGB2101010: - case DRM_FORMAT_ABGR2101010: - case DRM_FORMAT_YUYV: - case DRM_FORMAT_YVYU: - case DRM_FORMAT_UYVY: - case DRM_FORMAT_VYUY: - case DRM_FORMAT_NV12: - case DRM_FORMAT_XYUV8888: - case DRM_FORMAT_P010: - case DRM_FORMAT_P012: - case DRM_FORMAT_P016: - case DRM_FORMAT_Y210: - case DRM_FORMAT_Y212: - case DRM_FORMAT_Y216: - case DRM_FORMAT_XVYU2101010: - case DRM_FORMAT_XVYU12_16161616: - case DRM_FORMAT_XVYU16161616: - case DRM_FORMAT_XBGR16161616F: - case DRM_FORMAT_ABGR16161616F: - case DRM_FORMAT_XRGB16161616F: - case DRM_FORMAT_ARGB16161616F: - break; - default: - drm_dbg_kms(state->plane->dev, - "[PLANE:%d:%s] FB:%d unsupported scaling format 0x%x\n", - state->plane->index, state->plane->name, - fb->base.id, fb->format->format); - return -EINVAL; - } - } - output->scaler_users |= (1 << scaler_user); - drm_dbg_kms(state->plane->dev, - "staged scaling request for %ux%u->%ux%u in scale check ", - src_w, src_h, dst_w, dst_h); - - return 0; -} - static int virtio_gpu_plane_atomic_check(struct drm_plane *plane, struct drm_atomic_state *state) { @@ -261,13 +147,7 @@ static int virtio_gpu_plane_atomic_check(struct drm_plane *plane, plane); struct drm_device *dev = plane->dev; struct virtio_gpu_device *vgdev = dev->dev_private; - bool is_cursor = 1; - struct virtio_gpu_output *output = NULL; - output = drm_crtc_to_virtio_gpu_output(new_plane_state->crtc); - - if(plane->type == DRM_PLANE_TYPE_PRIMARY && !vgdev->has_multi_plane) - is_cursor = 0; - + bool is_cursor = plane->type == DRM_PLANE_TYPE_CURSOR; struct drm_crtc_state *crtc_state; int ret; int min_scale = DRM_PLANE_NO_SCALING; @@ -297,21 +177,7 @@ static int virtio_gpu_plane_atomic_check(struct drm_plane *plane, min_scale, max_scale, is_cursor, true); - if(ret) { - DRM_DEBUG("sprite plane scaling check failed ret:%d \n", ret); - return ret; - } - - if(min_scale == 1) { - ret = virtio_gpu_check_plane_scaling(new_plane_state, output); - if(ret) - return ret; - } - - if(vgdev->has_rotation && new_plane_state->rotation) { - return virtio_gpu_check_plane_rotation(new_plane_state, output); - } - return 0; + return ret; } static void virtio_gpu_update_dumb_bo(struct virtio_gpu_device *vgdev, @@ -371,118 +237,6 @@ static void virtio_gpu_resource_flush(struct drm_plane *plane, } } -static void virtio_gpu_resource_flush_sprite(struct drm_plane *plane, int indx, - struct drm_framebuffer *fb, - 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_array *objs = NULL; - struct virtio_gpu_fence *fence = NULL; - uint32_t resource_id[4]; - int i, cnt=0; - - vgfb = to_virtio_gpu_framebuffer(plane->state->fb); - fence = virtio_gpu_fence_alloc(vgdev, vgdev->fence_drv.context, 0); - - if (fence) { - objs = virtio_gpu_array_alloc(1); - if (!objs) { - kfree(fence); - return; - } - virtio_gpu_array_add_obj(objs, vgfb->base.obj[0]); - virtio_gpu_array_lock_resv(objs); - } - - for(i=0; i<4; i++) { - if(vgfb->base.obj[i]) { - struct virtio_gpu_object *bo; - bo = gem_to_virtio_gpu_obj(vgfb->base.obj[i]); - resource_id[i] = bo->hw_res_handle; - cnt++; - } else { - resource_id[i] = 0; - } - } - - virtio_gpu_cmd_resource_flush_sprite(vgdev, indx, plane->index,fb, - resource_id, cnt, x, y, width, height, objs, fence); - - virtio_gpu_notify(vgdev); - - if (fence) { - dma_fence_wait_timeout(&fence->f, true, - msecs_to_jiffies(50)); - dma_fence_put(&fence->f); - } -} - -static void virtio_gpu_sprite_plane_update(struct drm_plane *plane, - struct drm_atomic_state *state) -{ - struct drm_device *dev = plane->dev; - struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state, - plane); - struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state, - plane); - struct drm_framebuffer *fb = new_state->fb; - - struct virtio_gpu_device *vgdev = dev->dev_private; - struct virtio_gpu_output *output = NULL; - struct virtio_gpu_cmd cmd_set[3]; - int cnt = 0; - - if (plane->state->crtc) - output = drm_crtc_to_virtio_gpu_output(plane->state->crtc); - if (old_state->crtc) - output = drm_crtc_to_virtio_gpu_output(old_state->crtc); - if (WARN_ON(!output)) - return; - - if (!plane->state->fb || !output->crtc.state->active) { - DRM_DEBUG("sprite nofb\n"); - return; - } - - if ((vgdev->has_rotation) && plane->state->rotation) { - cmd_set[cnt].cmd = VIRTIO_GPU_TUNNEL_CMD_SET_ROTATION; - cmd_set[cnt].size = 2; - cmd_set[cnt].data64[0]= plane->state->rotation; - cnt++; - } - if (vgdev->has_scaling) { - cmd_set[cnt].cmd = VIRTIO_GPU_TUNNEL_CMD_SET_SPRITE_SCALING; - cmd_set[cnt].size = 4; - cmd_set[cnt].data32[0] = plane->state->crtc_x; - cmd_set[cnt].data32[1] = plane->state->crtc_y; - cmd_set[cnt].data32[2] = plane->state->crtc_w; - cmd_set[cnt].data32[3] = plane->state->crtc_h; - cnt++; - } - - if ((vgdev->has_pixel_blend_mode) && (plane->state->fb->format->has_alpha)) { - cmd_set[cnt].cmd = VIRTIO_GPU_TUNNEL_CMD_SET_BLEND; - cmd_set[cnt].size = 2; - cmd_set[cnt].data32[0]= plane->state->pixel_blend_mode; - cmd_set[cnt].data32[1]=(uint32_t)plane->state->alpha; - cnt++; - } - - if(cnt) { - virtio_gpu_cmd_send_misc(vgdev, output->index, plane->index, cmd_set, cnt); - } - virtio_gpu_resource_flush_sprite(plane, - output->index, - fb, - plane->state->src_x >> 16, - plane->state->src_y >> 16, - plane->state->src_w >> 16, - plane->state->src_h >> 16); -} - static void virtio_gpu_primary_plane_update(struct drm_plane *plane, struct drm_atomic_state *state) { @@ -493,8 +247,6 @@ static void virtio_gpu_primary_plane_update(struct drm_plane *plane, struct virtio_gpu_output *output = NULL; struct virtio_gpu_object *bo; struct drm_rect rect; - struct virtio_gpu_cmd cmd_set[3]; - int i, cnt = 0; if (plane->state->crtc) output = drm_crtc_to_virtio_gpu_output(plane->state->crtc); @@ -568,25 +320,6 @@ static void virtio_gpu_primary_plane_update(struct drm_plane *plane, virtio_gpu_cmd_set_scaling(vgdev, output->index, &rect_dst); } - if ((vgdev->has_rotation) && plane->state->rotation) { - cmd_set[cnt].cmd = VIRTIO_GPU_TUNNEL_CMD_SET_ROTATION; - cmd_set[cnt].size = 2; - cmd_set[cnt].data64[0]= plane->state->rotation; - cnt++; - } - - if ((vgdev->has_pixel_blend_mode) && (plane->state->fb->format->has_alpha)) { - cmd_set[cnt].cmd = VIRTIO_GPU_TUNNEL_CMD_SET_BLEND ; - cmd_set[cnt].size = 2; - cmd_set[cnt].data32[0]= plane->state->pixel_blend_mode; - cmd_set[cnt].data32[1]=(uint32_t)plane->state->alpha; - cnt++; - } - - if(cnt) { - virtio_gpu_cmd_send_misc(vgdev, output->index, plane->index, cmd_set, cnt); - } - virtio_gpu_resource_flush(plane, rect.x1, rect.y1, @@ -732,11 +465,6 @@ static const struct drm_plane_helper_funcs virtio_gpu_cursor_helper_funcs = { .atomic_update = virtio_gpu_cursor_plane_update, }; -static const struct drm_plane_helper_funcs virtio_gpu_sprite_helper_funcs = { - .atomic_check = virtio_gpu_plane_atomic_check, - .atomic_update = virtio_gpu_sprite_plane_update, -}; - static const uint64_t virtio_gpu_format_modifiers[] = { DRM_FORMAT_MOD_LINEAR, I915_FORMAT_MOD_X_TILED, @@ -760,38 +488,6 @@ static bool virtio_gpu_plane_format_mod_supported(struct drm_plane *_plane, } } -void virtio_update_planes_info(int index, int num, u32 *info) -{ - int plane_indx, format_indx; - int size = 0; - int pos = 0; - - for(plane_indx=0; plane_indxresp_wq, - vgdev->outputs[scanout_indx].rotation[plane_id], 5 * HZ); - -} - struct drm_plane *virtio_gpu_plane_init(struct virtio_gpu_device *vgdev, enum drm_plane_type type, int index) @@ -806,15 +502,6 @@ struct drm_plane *virtio_gpu_plane_init(struct virtio_gpu_device *vgdev, formats = virtio_gpu_cursor_formats; nformats = ARRAY_SIZE(virtio_gpu_cursor_formats); funcs = &virtio_gpu_cursor_helper_funcs; - - } else if (type == DRM_PLANE_TYPE_OVERLAY) { - formats = virtio_gpu_output_planes_formats[index]. - planes[virtio_gpu_output_planes_formats[index].sprite_plane_index].format_info; - nformats = virtio_gpu_output_planes_formats[index]. - planes[virtio_gpu_output_planes_formats[index].sprite_plane_index].size; - funcs = &virtio_gpu_sprite_helper_funcs; - virtio_gpu_output_planes_formats[index].sprite_plane_index++; - } else { formats = virtio_gpu_formats; nformats = ARRAY_SIZE(virtio_gpu_formats); @@ -833,25 +520,6 @@ struct drm_plane *virtio_gpu_plane_init(struct virtio_gpu_device *vgdev, formats, nformats, NULL, type, NULL); } - if (vgdev->has_rotation) { - vgdev->outputs[index].rotation[plane->index] = 0; - virtio_gpu_get_plane_rotation(vgdev, plane->index, index); - vgdev->outputs[index].rotation[plane->index] = - DRM_MODE_ROTATE_0|vgdev->outputs[index].rotation[plane->index]; - - drm_plane_create_rotation_property(plane, - DRM_MODE_ROTATE_0, - vgdev->outputs[index].rotation[plane->index]); - } - - if(vgdev->has_pixel_blend_mode) { - drm_plane_create_alpha_property(plane); - drm_plane_create_blend_mode_property(plane, - BIT(DRM_MODE_BLEND_PIXEL_NONE) | - BIT(DRM_MODE_BLEND_PREMULTI) | - BIT(DRM_MODE_BLEND_COVERAGE)); - } - if (IS_ERR(plane)) return plane; diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c index 5931d7eedfa4..bc96d9ad2a24 100644 --- a/drivers/gpu/drm/virtio/virtgpu_vq.c +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c @@ -38,7 +38,7 @@ #include "virtgpu_drv.h" #include "virtgpu_trace.h" -#define MAX_INLINE_CMD_SIZE 512 +#define MAX_INLINE_CMD_SIZE 96 #define MAX_INLINE_RESP_SIZE 24 #define VBUFFER_SIZE (sizeof(struct virtio_gpu_vbuffer) \ + MAX_INLINE_CMD_SIZE \ @@ -646,89 +646,6 @@ void virtio_gpu_cmd_set_scanout(struct virtio_gpu_device *vgdev, virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); } - -void virtio_gpu_cmd_flush_sync(struct virtio_gpu_device *vgdev, - uint32_t scanout_id) -{ - struct virtio_gpu_flush_sync *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)); - - cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_FLUSH_SYNC); - cmd_p->scanout_id = cpu_to_le32(scanout_id); - - virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); - -} - -void virtio_gpu_cmd_resource_flush_sprite(struct virtio_gpu_device *vgdev, - uint32_t scanout_id, - uint32_t plane_indx, - struct drm_framebuffer *fb, - uint32_t *resource_id, - uint32_t resource_cnt, - uint32_t x, uint32_t y, - uint32_t width, uint32_t height, - struct virtio_gpu_object_array *objs, - struct virtio_gpu_fence *fence) -{ - struct virtio_gpu_flush_sprite *cmd_p; - struct virtio_gpu_vbuffer *vbuf; - uint32_t format = fb->format->format; - int i; - cmd_p = virtio_gpu_alloc_cmd(vgdev, &vbuf, sizeof(*cmd_p)); - memset(cmd_p, 0, sizeof(*cmd_p)); - vbuf->objs = objs; - - for (i = 0; i < 4; i++) - cmd_p->resource_id[i] = cpu_to_le32(resource_id[i]); - - cmd_p->resource_cnt = cpu_to_le32(resource_cnt); - cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_FLUSH_SPRITE); - cmd_p->scanout_id = cpu_to_le32(scanout_id); - cmd_p->plane_id = cpu_to_le32(plane_indx); - cmd_p->r.width = cpu_to_le32(width); - cmd_p->r.height = cpu_to_le32(height); - cmd_p->r.x = cpu_to_le32(x); - cmd_p->r.y = cpu_to_le32(y); - cmd_p->width = cpu_to_le32(fb->width); - cmd_p->height = cpu_to_le32(fb->height); - cmd_p->format = cpu_to_le32(format); - cmd_p->modifier = cpu_to_le64(fb->modifier); - - for (i = 0; i < 4; i++) { - cmd_p->strides[i] = cpu_to_le32(fb->pitches[i]); - cmd_p->offsets[i] = cpu_to_le32(fb->offsets[i]); - } - - virtio_gpu_queue_fenced_ctrl_buffer(vgdev, vbuf, fence); -} - -void virtio_gpu_cmd_send_misc(struct virtio_gpu_device *vgdev, uint32_t scanout_id, - uint32_t plane_indx, struct virtio_gpu_cmd *cmdp, int cnt) -{ - struct virtio_gpu_set_misc *cmd_p; - struct virtio_gpu_vbuffer *vbuf; - int i,j; - cmd_p = virtio_gpu_alloc_cmd(vgdev, &vbuf, sizeof(*cmd_p)); - memset(cmd_p, 0, sizeof(*cmd_p)); - cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_SET_MISC); - cmd_p->scanout_id = cpu_to_le32(scanout_id); - cmd_p->plane_id= cpu_to_le32(plane_indx); - cmd_p->cmd_cnt = cpu_to_le32(cnt); - for(i=0; icmd[i].cmd = cpu_to_le32(p->cmd); - cmd_p->cmd[i].size= cpu_to_le32(p->size); - for(j=0; jsize; j++) { - cmd_p->cmd[i].data32[j] = cpu_to_le32(p->data32[j]); - } - } - virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); -} - void virtio_gpu_cmd_resource_flush(struct virtio_gpu_device *vgdev, uint32_t resource_id, uint32_t x, uint32_t y, @@ -853,23 +770,6 @@ static void virtio_gpu_cmd_get_display_info_cb(struct virtio_gpu_device *vgdev, drm_kms_helper_hotplug_event(vgdev->ddev); } -static void virtio_gpu_cmd_get_plane_info_cb(struct virtio_gpu_device *vgdev, - struct virtio_gpu_vbuffer *vbuf) -{ - struct virtio_gpu_cmd_get_planes *cmd = - (struct virtio_gpu_cmd_get_planes *)vbuf->buf; - struct virtio_gpu_resp_planes *resp = - (struct virtio_gpu_resp_planes *)vbuf->resp_buf; - int indx = le32_to_cpu(cmd->scanout); - - spin_lock(&vgdev->display_info_lock); - vgdev->outputs[indx].plane_num = le32_to_cpu(resp->plane_num); - if(vgdev->outputs[indx].plane_num) - virtio_update_planes_info(indx, le32_to_cpu(resp->plane_num), resp->info); - spin_unlock(&vgdev->display_info_lock); - wake_up(&vgdev->resp_wq); -} - static void virtio_gpu_cmd_get_capset_info_cb(struct virtio_gpu_device *vgdev, struct virtio_gpu_vbuffer *vbuf) { @@ -978,71 +878,6 @@ int virtio_gpu_cmd_get_display_info(struct virtio_gpu_device *vgdev) return 0; } -static void virtio_gpu_cmd_get_plane_rotation_cb(struct virtio_gpu_device *vgdev, - struct virtio_gpu_vbuffer *vbuf) -{ - struct virtio_gpu_cmd_get_plane_rotation *cmd = - (struct virtio_gpu_cmd_get_plane_rotation *)vbuf->buf; - struct virtio_gpu_resp_plane_rotation *resp = - (struct virtio_gpu_resp_plane_rotation *)vbuf->resp_buf; - - int indx = le32_to_cpu(cmd->scanout_id); - int plane_indx = le32_to_cpu(cmd->plane_id); - spin_lock(&vgdev->display_info_lock); - vgdev->outputs[indx].rotation[plane_indx] = le64_to_cpu(resp->rotation[0]); - spin_unlock(&vgdev->display_info_lock); - wake_up(&vgdev->resp_wq); -} - -int virtio_gpu_cmd_get_plane_rotation(struct virtio_gpu_device *vgdev, - uint32_t plane_id, uint32_t scanout_indx) -{ - struct virtio_gpu_cmd_get_plane_rotation *cmd_p; - struct virtio_gpu_vbuffer *vbuf; - void *resp_buf; - - resp_buf = kzalloc(sizeof(struct virtio_gpu_resp_plane_rotation), - GFP_KERNEL); - if (!resp_buf) - return -ENOMEM; - - cmd_p = virtio_gpu_alloc_cmd_resp - (vgdev, &virtio_gpu_cmd_get_plane_rotation_cb, &vbuf, - sizeof(*cmd_p), sizeof(struct virtio_gpu_resp_plane_rotation), - resp_buf); - memset(cmd_p, 0, sizeof(*cmd_p)); - - cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_GET_PLANE_ROTATION); - cmd_p->plane_id = cpu_to_le32(plane_id); - cmd_p->scanout_id = cpu_to_le32(scanout_indx); - virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); - return 0; - -} - -int virtio_gpu_cmd_get_planes_info(struct virtio_gpu_device *vgdev, int idx) -{ - struct virtio_gpu_cmd_get_planes *cmd_p; - struct virtio_gpu_vbuffer *vbuf; - void *resp_buf; - - resp_buf = kzalloc(sizeof(struct virtio_gpu_resp_planes), - GFP_KERNEL); - if (!resp_buf) - return -ENOMEM; - - cmd_p = virtio_gpu_alloc_cmd_resp - (vgdev, &virtio_gpu_cmd_get_plane_info_cb, &vbuf, - sizeof(*cmd_p), sizeof(struct virtio_gpu_resp_planes), - resp_buf); - memset(cmd_p, 0, sizeof(*cmd_p)); - - cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_GET_PLANES); - cmd_p->scanout = cpu_to_le32(idx); - virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); - return 0; -} - int virtio_gpu_cmd_get_capset_info(struct virtio_gpu_device *vgdev, int idx) { struct virtio_gpu_get_capset_info *cmd_p; diff --git a/include/uapi/linux/virtio_gpu.h b/include/uapi/linux/virtio_gpu.h index b9334480ef96..62811f9238e7 100644 --- a/include/uapi/linux/virtio_gpu.h +++ b/include/uapi/linux/virtio_gpu.h @@ -77,27 +77,6 @@ #define VIRTIO_GPU_F_ALLOW_P2P 31 -/* - * VIRTIO_GPU_CMD_FLUSH_SPRITE - * VIRTIO_GPU_CMD_FLUSH_SYNC - * VIRTIO_GPU_CMD_GET_PLANES - */ -#define VIRTIO_GPU_F_MULTI_PLANE 9 - -/* - *VIRTIO_GPU_CMD_GET_PLANE_ROTATION - *VIRTIO_GPU_CMD_SET_ROTATION - */ -#define VIRTIO_GPU_F_ROTATION 10 - -#define VIRTIO_GPU_F_PIXEL_BLEND_MODE 11 - - -#define VIRTIO_GPU_TUNNEL_CMD_SET_ROTATION 1 -#define VIRTIO_GPU_TUNNEL_CMD_SET_BLEND 2 -#define VIRTIO_GPU_TUNNEL_CMD_SET_PLANARS 3 -#define VIRTIO_GPU_TUNNEL_CMD_SET_SPRITE_SCALING 4 - enum virtio_gpu_ctrl_type { VIRTIO_GPU_UNDEFINED = 0, @@ -118,11 +97,6 @@ enum virtio_gpu_ctrl_type { VIRTIO_GPU_CMD_SET_SCANOUT_BLOB, VIRTIO_GPU_CMD_SET_MODIFIER, VIRTIO_GPU_CMD_SET_SCALING, - VIRTIO_GPU_CMD_FLUSH_SPRITE, - VIRTIO_GPU_CMD_FLUSH_SYNC, - VIRTIO_GPU_CMD_GET_PLANES, - VIRTIO_GPU_CMD_GET_PLANE_ROTATION, - VIRTIO_GPU_CMD_SET_MISC, /* 3d commands */ VIRTIO_GPU_CMD_CTX_CREATE = 0x0200, @@ -235,14 +209,6 @@ struct virtio_gpu_set_scanout { __le32 resource_id; }; -/* VIRTIO_GPU_CMD_FLUSH_SYNC*/ -struct virtio_gpu_flush_sync{ - struct virtio_gpu_ctrl_hdr hdr; - __le32 scanout_id; - __le32 padding; -}; - - /* VIRTIO_GPU_CMD_RESOURCE_FLUSH */ struct virtio_gpu_resource_flush { struct virtio_gpu_ctrl_hdr hdr; @@ -251,46 +217,6 @@ struct virtio_gpu_resource_flush { __le32 padding; }; -/* VIRTIO_GPU_CMD_FLUSH_SPRITE */ -struct virtio_gpu_flush_sprite { - struct virtio_gpu_ctrl_hdr hdr; - struct virtio_gpu_rect r; - __le32 scanout_id; - __le32 plane_id; - __le32 resource_id[4]; - __le32 resource_cnt; - __le32 format; - __le32 width; - __le32 height; - __le64 modifier; - __le32 strides[4]; - __le32 offsets[4]; -}; - -#define MAX_SUPPORT_CMD 6 -struct virtio_gpu_cmd { - uint32_t cmd; - uint32_t size; - union { - uint64_t data64[8]; - uint32_t data32[16]; - }; -}; - -struct virtio_gpu_cmd_tunnel { - __le32 cmd; - __le32 size; - __le32 data32[16]; -}; -/* VIRTIO_GPU_CMD_SET_MISC */ -struct virtio_gpu_set_misc { - struct virtio_gpu_ctrl_hdr hdr; - __le32 scanout_id; - __le32 plane_id; - __le32 cmd_cnt; - __le32 padding; - struct virtio_gpu_cmd_tunnel cmd[MAX_SUPPORT_CMD]; -}; /* VIRTIO_GPU_CMD_SET_SCALING */ struct virtio_gpu_set_scaling { struct virtio_gpu_ctrl_hdr hdr; @@ -438,34 +364,6 @@ struct virtio_gpu_resp_capset { __u8 capset_data[]; }; -/*VIRTIO_GPU_CMD_GET_PLANE_ROTATION*/ -struct virtio_gpu_cmd_get_plane_rotation{ - struct virtio_gpu_ctrl_hdr hdr; - __le32 scanout_id; - __le32 plane_id; -}; -/* VIRTIO_GPU_RESP_OK_PLANE_ROTATION */ -struct virtio_gpu_resp_plane_rotation{ - struct virtio_gpu_ctrl_hdr hdr; - __le32 count; - __le32 padding; - __le64 rotation[10]; -}; - -/* VIRTIO_GPU_CMD_GET_PLANES*/ -struct virtio_gpu_cmd_get_planes{ - struct virtio_gpu_ctrl_hdr hdr; - __le32 scanout; - __le32 padding; -}; -/* VIRTIO_GPU_RESP_OK_PLANES*/ -struct virtio_gpu_resp_planes{ - struct virtio_gpu_ctrl_hdr hdr; - __le32 plane_num; - __le32 size; - __le32 info[1024]; -}; - /* VIRTIO_GPU_CMD_GET_EDID */ struct virtio_gpu_cmd_get_edid { struct virtio_gpu_ctrl_hdr hdr; From 636940c2cf1a7eb5fd167789a6ae63d2e6adb5ba Mon Sep 17 00:00:00 2001 From: "Xue, Bosheng" Date: Wed, 16 Apr 2025 16:33:04 +0800 Subject: [PATCH 18/43] Revert "drm/virtio: Show more capabilities in debugfs" This reverts commit e927937bd9611ef89c8918aedf72f1c22291d291. --- drivers/gpu/drm/virtio/virtgpu_debugfs.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_debugfs.c b/drivers/gpu/drm/virtio/virtgpu_debugfs.c index bfcb1ac9ab8c..853dd9aa397e 100644 --- a/drivers/gpu/drm/virtio/virtgpu_debugfs.c +++ b/drivers/gpu/drm/virtio/virtgpu_debugfs.c @@ -55,9 +55,6 @@ static int virtio_gpu_features(struct seq_file *m, void *data) virtio_gpu_add_bool(m, "blob resources", vgdev->has_resource_blob); virtio_gpu_add_bool(m, "context init", vgdev->has_context_init); - virtio_gpu_add_bool(m, "scaling", vgdev->has_scaling); - virtio_gpu_add_bool(m, "allow_p2p", vgdev->has_allow_p2p); - virtio_gpu_add_bool(m, "modifier", vgdev->has_modifier); virtio_gpu_add_int(m, "cap sets", vgdev->num_capsets); virtio_gpu_add_int(m, "scanouts", vgdev->num_scanouts); if (vgdev->host_visible_region.len) { From d940c5ded91a57152f914b2cc5b81840909bb7a8 Mon Sep 17 00:00:00 2001 From: "Xue, Bosheng" Date: Wed, 16 Apr 2025 16:33:04 +0800 Subject: [PATCH 19/43] Revert "drm/virtio: Set peer2peer flag when VIRTIO_GPU_F_ALLOW_P2P is present" This reverts commit 111bdf04c656955de480807486b8a9696e067174. --- drivers/gpu/drm/virtio/virtgpu_prime.c | 46 +++----------------------- 1 file changed, 4 insertions(+), 42 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_prime.c b/drivers/gpu/drm/virtio/virtgpu_prime.c index fea9ecea180c..1410025a224b 100644 --- a/drivers/gpu/drm/virtio/virtgpu_prime.c +++ b/drivers/gpu/drm/virtio/virtgpu_prime.c @@ -143,17 +143,12 @@ struct dma_buf *virtgpu_gem_prime_export(struct drm_gem_object *obj, } struct drm_gem_object *virtgpu_gem_prime_import(struct drm_device *dev, - struct dma_buf *dma_buf) + struct dma_buf *buf) { struct drm_gem_object *obj; - struct dma_buf_attachment *attach; - struct sg_table *sgt; - struct device *attach_dev = dev->dev; - struct virtio_gpu_device *vgdev = dev->dev_private; - int ret; - if (dma_buf->ops == &virtgpu_dmabuf_ops.ops) { - obj = dma_buf->priv; + if (buf->ops == &virtgpu_dmabuf_ops.ops) { + obj = buf->priv; if (obj->dev == dev) { /* * Importing dmabuf exported from our own gem increases @@ -164,40 +159,7 @@ struct drm_gem_object *virtgpu_gem_prime_import(struct drm_device *dev, } } - if (!dev->driver->gem_prime_import_sg_table) - return ERR_PTR(-EINVAL); - - attach = ____dma_buf_dynamic_attach(dma_buf, attach_dev, NULL, NULL, - p2p); - if (IS_ERR(attach)) - return ERR_CAST(attach); - - get_dma_buf(dma_buf); - - sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); - if (IS_ERR(sgt)) { - ret = PTR_ERR(sgt); - goto fail_detach; - } - - obj = dev->driver->gem_prime_import_sg_table(dev, attach, sgt); - if (IS_ERR(obj)) { - ret = PTR_ERR(obj); - goto fail_unmap; - } - - obj->import_attach = attach; - obj->resv = dma_buf->resv; - - return obj; - -fail_unmap: - dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL); -fail_detach: - dma_buf_detach(dma_buf, attach); - dma_buf_put(dma_buf); - - return ERR_PTR(ret); + return drm_gem_prime_import(dev, buf); } static int virtio_gpu_sgt_to_mem_entry(struct virtio_gpu_device *vgdev, From 92553d0bd599cc770fb7e83afe4ef550acb5336d Mon Sep 17 00:00:00 2001 From: "Xue, Bosheng" Date: Wed, 16 Apr 2025 16:33:05 +0800 Subject: [PATCH 20/43] Revert "drm/virtio: Add allow_p2p capability" This reverts commit fefb6e0973e90012ef00c9cccd74c3dec0abf7ce. --- drivers/gpu/drm/virtio/virtgpu_drv.c | 1 - drivers/gpu/drm/virtio/virtgpu_drv.h | 1 - drivers/gpu/drm/virtio/virtgpu_kms.c | 3 --- include/uapi/linux/virtio_gpu.h | 6 ++---- 4 files changed, 2 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c index 5385b43b28ed..bef47d273178 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.c +++ b/drivers/gpu/drm/virtio/virtgpu_drv.c @@ -165,7 +165,6 @@ static unsigned int features[] = { VIRTIO_GPU_F_MODIFIER, VIRTIO_GPU_F_SCALING, VIRTIO_GPU_F_VBLANK, - VIRTIO_GPU_F_ALLOW_P2P, }; #ifdef CONFIG_PM_SLEEP diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index 6fa8093564f6..1354e61865a0 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -266,7 +266,6 @@ struct virtio_gpu_device { bool has_modifier; bool has_scaling; bool has_vblank; - bool has_allow_p2p; bool has_indirect; bool has_resource_assign_uuid; bool has_resource_blob; diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c index 4d450e6751b8..45b4a262b961 100644 --- a/drivers/gpu/drm/virtio/virtgpu_kms.c +++ b/drivers/gpu/drm/virtio/virtgpu_kms.c @@ -229,9 +229,6 @@ int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev) if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_VBLANK)) { vgdev->has_vblank = true; } - if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_ALLOW_P2P)) { - vgdev->has_allow_p2p = true; - } if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_RESOURCE_BLOB)) { vgdev->has_resource_blob = true; if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_MODIFIER)) { diff --git a/include/uapi/linux/virtio_gpu.h b/include/uapi/linux/virtio_gpu.h index 62811f9238e7..c182802ff00c 100644 --- a/include/uapi/linux/virtio_gpu.h +++ b/include/uapi/linux/virtio_gpu.h @@ -71,11 +71,9 @@ /* *VIRTIO_GPU_CMD_SET_SCALING */ -#define VIRTIO_GPU_F_SCALING 6 +#define VIRTIO_GPU_F_SCALING 6 -#define VIRTIO_GPU_F_VBLANK 7 - -#define VIRTIO_GPU_F_ALLOW_P2P 31 +#define VIRTIO_GPU_F_VBLANK 7 enum virtio_gpu_ctrl_type { VIRTIO_GPU_UNDEFINED = 0, From a3620e3075d53430e5e195d1410b8a27961a65aa Mon Sep 17 00:00:00 2001 From: "Xue, Bosheng" Date: Wed, 16 Apr 2025 16:33:05 +0800 Subject: [PATCH 21/43] Revert "drm/virtio: Use DMA API in PRIME importing code" This reverts commit a246a0fa0d0810a8338328882f61d6d91d1f53ec. --- drivers/gpu/drm/virtio/virtgpu_prime.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_prime.c b/drivers/gpu/drm/virtio/virtgpu_prime.c index 1410025a224b..e6ba0a4fe90c 100644 --- a/drivers/gpu/drm/virtio/virtgpu_prime.c +++ b/drivers/gpu/drm/virtio/virtgpu_prime.c @@ -170,16 +170,7 @@ static int virtio_gpu_sgt_to_mem_entry(struct virtio_gpu_device *vgdev, struct scatterlist *sg; int si; - /** - * TODO: We must always use DMA addresses for the following two reasons: - * - * 1. By design we are not allowed to access the struct page backing a - * scatter list, especially when config DMABUF_DEBUG is turned on in - * which case the addresses will be mangled by the core. - * 2. DMA addresses are required for dGPU local memory sharing between - * host and guest. - */ - const bool use_dma_api = true; + bool use_dma_api = !virtio_has_dma_quirk(vgdev->vdev); if (use_dma_api) *nents = table->nents; else @@ -228,8 +219,6 @@ struct drm_gem_object *virtgpu_gem_prime_import_sg_table( return ERR_PTR(-ENODEV); } - drm_info(dev, "%s: table = %p, orig_nents = %u, nents = %u\n", - __func__, table, table->orig_nents, table->nents); obj = drm_gem_shmem_prime_import_sg_table(dev, attach, table); if (IS_ERR(obj)) { return ERR_CAST(obj); From 302e46d9368392f6b107051f7aad1fb45aae9727 Mon Sep 17 00:00:00 2001 From: "Xue, Bosheng" Date: Wed, 16 Apr 2025 16:33:06 +0800 Subject: [PATCH 22/43] Revert "drm/virtio: Support tile-4 modifier" This reverts commit 8685e3b8fb30ff8d5ecb21b47dd3b31ee8bfffe2. --- drivers/gpu/drm/virtio/virtgpu_plane.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c index 3ca5bb5a3ebb..5f7bb0783243 100644 --- a/drivers/gpu/drm/virtio/virtgpu_plane.c +++ b/drivers/gpu/drm/virtio/virtgpu_plane.c @@ -469,7 +469,6 @@ static const uint64_t virtio_gpu_format_modifiers[] = { DRM_FORMAT_MOD_LINEAR, I915_FORMAT_MOD_X_TILED, I915_FORMAT_MOD_Y_TILED, - I915_FORMAT_MOD_4_TILED, DRM_FORMAT_MOD_INVALID }; @@ -481,7 +480,6 @@ static bool virtio_gpu_plane_format_mod_supported(struct drm_plane *_plane, case DRM_FORMAT_MOD_LINEAR: case I915_FORMAT_MOD_X_TILED: case I915_FORMAT_MOD_Y_TILED: - case I915_FORMAT_MOD_4_TILED: return true; default: return false; From 02ea52e3bd753821c5413535fb8416f1c0c6436d Mon Sep 17 00:00:00 2001 From: "Xue, Bosheng" Date: Wed, 16 Apr 2025 16:33:07 +0800 Subject: [PATCH 23/43] Revert "drm/virtio: improve virtio gpu vblank operation" This reverts commit 95310de3a8c8787f29e480f8d5cbfbb734be5c02. --- drivers/gpu/drm/virtio/virtgpu_display.c | 29 ++++++++---------------- drivers/gpu/drm/virtio/virtgpu_drv.c | 12 +--------- 2 files changed, 10 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c index e498b60af06d..b4fd3ef0c8ad 100644 --- a/drivers/gpu/drm/virtio/virtgpu_display.c +++ b/drivers/gpu/drm/virtio/virtgpu_display.c @@ -123,11 +123,6 @@ static void virtio_gpu_crtc_mode_set_nofb(struct drm_crtc *crtc) static void virtio_gpu_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *state) { - struct drm_device *dev = crtc->dev; - struct virtio_gpu_device *vgdev = dev->dev_private; - if(vgdev->has_vblank) { - drm_crtc_vblank_on(crtc); - } } static void virtio_gpu_crtc_atomic_disable(struct drm_crtc *crtc, @@ -137,9 +132,6 @@ static void virtio_gpu_crtc_atomic_disable(struct drm_crtc *crtc, struct virtio_gpu_device *vgdev = dev->dev_private; struct virtio_gpu_output *output = drm_crtc_to_virtio_gpu_output(crtc); - if(vgdev->has_vblank) { - drm_crtc_vblank_off(crtc); - } virtio_gpu_cmd_set_scanout(vgdev, output->index, 0, 0, 0, 0, 0); virtio_gpu_notify(vgdev); } @@ -157,20 +149,17 @@ static void virtio_gpu_crtc_atomic_flush(struct drm_crtc *crtc, crtc); struct virtio_gpu_output *output = drm_crtc_to_virtio_gpu_output(crtc); struct drm_device *drm = crtc->dev; - struct virtio_gpu_device *vgdev = drm->dev_private; - - if(vgdev->has_vblank) { - if (crtc->state->event) { - spin_lock_irq(&drm->event_lock); - if (drm_crtc_vblank_get(crtc) != 0) - drm_crtc_send_vblank_event(crtc, crtc->state->event); - else - drm_crtc_arm_vblank_event(crtc, crtc->state->event); - spin_unlock_irq(&drm->event_lock); - crtc->state->event = NULL; - } + + spin_lock_irq(&drm->event_lock); + + + if (crtc->state->event) { + drm_crtc_send_vblank_event(crtc, crtc->state->event); + crtc->state->event = NULL; } + spin_unlock_irq(&drm->event_lock); + /* * virtio-gpu can't do modeset and plane update operations * independent from each other. So the actual modeset happens diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c index bef47d273178..47202aa417da 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.c +++ b/drivers/gpu/drm/virtio/virtgpu_drv.c @@ -180,7 +180,6 @@ static int virtgpu_freeze(struct virtio_device *vdev) return error; } - vdev->config->reset(vdev); flush_work(&vgdev->obj_free_work); flush_work(&vgdev->ctrlq.dequeue_work); flush_work(&vgdev->cursorq.dequeue_work); @@ -194,7 +193,7 @@ static int virtgpu_restore(struct virtio_device *vdev) { struct drm_device *dev = vdev->priv; struct virtio_gpu_device *vgdev = dev->dev_private; - int error, i; + int error; error = virtio_gpu_find_vqs(vgdev); if (error) { @@ -204,15 +203,6 @@ static int virtgpu_restore(struct virtio_device *vdev) virtio_device_ready(vdev); - - if(vgdev->has_vblank) { - virtio_gpu_vblankq_notify(vgdev); - - for(i = 0; i < vgdev->num_vblankq; i++) - virtqueue_disable_cb(vgdev->vblank[i].vblank.vq); - } - - error = virtio_gpu_object_restore_all(vgdev); if (error) { DRM_ERROR("Failed to recover objects\n"); From 177dbbde209af720ffada8a2ff7aa4e0949102cb Mon Sep 17 00:00:00 2001 From: "Xue, Bosheng" Date: Wed, 16 Apr 2025 16:33:07 +0800 Subject: [PATCH 24/43] Revert "drm/virtio: enable vblank for crtc" This reverts commit 8cbda7db81e89c126df55fdddee4a503ad0a856b. --- drivers/gpu/drm/virtio/virtgpu_display.c | 36 ----------- drivers/gpu/drm/virtio/virtgpu_drv.c | 11 ---- drivers/gpu/drm/virtio/virtgpu_drv.h | 3 - drivers/gpu/drm/virtio/virtgpu_kms.c | 8 --- drivers/gpu/drm/virtio/virtgpu_vq.c | 79 ------------------------ 5 files changed, 137 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c index b4fd3ef0c8ad..3dae4e95d4ed 100644 --- a/drivers/gpu/drm/virtio/virtgpu_display.c +++ b/drivers/gpu/drm/virtio/virtgpu_display.c @@ -32,7 +32,6 @@ #include #include #include -#include #include "virtgpu_drv.h" @@ -48,28 +47,6 @@ #define drm_connector_to_virtio_gpu_output(x) \ container_of(x, struct virtio_gpu_output, conn) -static int virtio_irq_enable_vblank(struct drm_crtc *crtc) -{ - - struct drm_device *dev = crtc->dev; - struct virtio_gpu_device *vgdev = dev->dev_private; - struct virtio_gpu_output *output = drm_crtc_to_virtio_gpu_output(crtc); - - virtio_gpu_vblank_poll_arm(vgdev->vblank[output->index].vblank.vq); - virtqueue_enable_cb(vgdev->vblank[output->index].vblank.vq); - return 0; -} - -static void virtio_irq_disable_vblank(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - struct virtio_gpu_device *vgdev; - vgdev = dev->dev_private; - struct virtio_gpu_output *output = drm_crtc_to_virtio_gpu_output(crtc); - - virtqueue_disable_cb(vgdev->vblank[output->index].vblank.vq); -} - static const struct drm_crtc_funcs virtio_gpu_crtc_funcs = { .set_config = drm_atomic_helper_set_config, .destroy = drm_crtc_cleanup, @@ -78,8 +55,6 @@ static const struct drm_crtc_funcs virtio_gpu_crtc_funcs = { .reset = drm_atomic_helper_crtc_reset, .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, - .enable_vblank = virtio_irq_enable_vblank, - .disable_vblank = virtio_irq_disable_vblank, }; static const struct drm_framebuffer_funcs virtio_gpu_fb_funcs = { @@ -148,17 +123,6 @@ static void virtio_gpu_crtc_atomic_flush(struct drm_crtc *crtc, struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc); struct virtio_gpu_output *output = drm_crtc_to_virtio_gpu_output(crtc); - struct drm_device *drm = crtc->dev; - - spin_lock_irq(&drm->event_lock); - - - if (crtc->state->event) { - drm_crtc_send_vblank_event(crtc, crtc->state->event); - crtc->state->event = NULL; - } - - spin_unlock_irq(&drm->event_lock); /* * virtio-gpu can't do modeset and plane update operations diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c index 47202aa417da..4a90ed289873 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.c +++ b/drivers/gpu/drm/virtio/virtgpu_drv.c @@ -38,7 +38,6 @@ #include #include #include -#include #include "virtgpu_drv.h" @@ -72,7 +71,6 @@ static int virtio_gpu_probe(struct virtio_device *vdev) { struct drm_device *dev; int ret; - struct virtio_gpu_device *pgpudev; if (drm_firmware_drivers_only() && virtio_gpu_modeset == -1) return -EINVAL; @@ -102,15 +100,6 @@ static int virtio_gpu_probe(struct virtio_device *vdev) if (ret) goto err_free; - pgpudev = dev->dev_private; - if(pgpudev->num_vblankq) { - ret = drm_vblank_init(dev, pgpudev->num_vblankq); - if (ret) { - DRM_ERROR("could not init vblank\n"); - goto err_deinit; - } - } - ret = drm_dev_register(dev, 0); if (ret) goto err_deinit; diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index 1354e61865a0..676b7a6e41b2 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -423,12 +423,9 @@ virtio_gpu_cmd_resource_create_3d(struct virtio_gpu_device *vgdev, struct virtio_gpu_fence *fence); void virtio_gpu_ctrl_ack(struct virtqueue *vq); void virtio_gpu_cursor_ack(struct virtqueue *vq); -void virtio_gpu_vblank_ack(struct virtqueue *vq); -void virtio_gpu_vblank_poll_arm(struct virtqueue *vq); void virtio_gpu_dequeue_ctrl_func(struct work_struct *work); void virtio_gpu_dequeue_cursor_func(struct work_struct *work); void virtio_gpu_notify(struct virtio_gpu_device *vgdev); -void virtio_gpu_vblankq_notify(struct virtio_gpu_device *vgdev); int virtio_gpu_cmd_resource_assign_uuid(struct virtio_gpu_device *vgdev, diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c index 45b4a262b961..9a63ea3b7f77 100644 --- a/drivers/gpu/drm/virtio/virtgpu_kms.c +++ b/drivers/gpu/drm/virtio/virtgpu_kms.c @@ -175,7 +175,6 @@ int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev) struct virtio_gpu_device *vgdev; u32 num_scanouts, num_capsets; int ret = 0; - int i; if (!virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) return -ENODEV; @@ -315,13 +314,6 @@ int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev) if (num_capsets) virtio_gpu_get_capsets(vgdev, num_capsets); - - virtio_gpu_vblankq_notify(vgdev); - - for(i=0; i < vgdev->num_vblankq; i++) - virtqueue_disable_cb(vgdev->vblank[i].vblank.vq); - - if (vgdev->num_scanouts) { if (vgdev->has_edid) virtio_gpu_cmd_get_edids(vgdev); diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c index bc96d9ad2a24..594b365b44af 100644 --- a/drivers/gpu/drm/virtio/virtgpu_vq.c +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c @@ -31,10 +31,8 @@ #include #include -#include #include -#include #include "virtgpu_drv.h" #include "virtgpu_trace.h" @@ -63,60 +61,6 @@ void virtio_gpu_ctrl_ack(struct virtqueue *vq) schedule_work(&vgdev->ctrlq.dequeue_work); } -static void virtgpu_irqqueue_buf(struct virtqueue *vq, - uint32_t *evtbuf) -{ - struct scatterlist sg[1]; - sg_init_one(sg, evtbuf, sizeof(*evtbuf)); - virtqueue_add_inbuf(vq, sg, 1, evtbuf, GFP_ATOMIC); -} - -void virtio_gpu_vblank_poll_arm(struct virtqueue *vq) -{ - struct drm_device *dev = vq->vdev->priv; - struct virtio_gpu_device *vgdev = dev->dev_private; - unsigned long irqflags; - unsigned int len; - unsigned int *ret_value; - int target = 0; - - while((target < vgdev->num_vblankq) && (vgdev->vblank[target].vblank.vq != vq)) { - target++; - } - - spin_lock_irqsave(&vgdev->vblank[target].vblank.qlock, irqflags); - if((ret_value = virtqueue_get_buf(vq, &len)) != NULL) { - - virtgpu_irqqueue_buf(vq, ret_value); - } - virtqueue_kick(vq); - spin_unlock_irqrestore(&vgdev->vblank[target].vblank.qlock, irqflags); -} - -void virtio_gpu_vblank_ack(struct virtqueue *vq) -{ - struct drm_device *dev = vq->vdev->priv; - struct virtio_gpu_device *vgdev = dev->dev_private; - unsigned long irqflags; - unsigned int len; - unsigned int *ret_value; - int target = 0; - - while((target < vgdev->num_vblankq) && (vgdev->vblank[target].vblank.vq != vq)) { - target++; - } - - spin_lock_irqsave(&vgdev->vblank[target].vblank.qlock, irqflags); - if((ret_value = virtqueue_get_buf(vgdev->vblank[target].vblank.vq, &len)) != NULL) { - - virtgpu_irqqueue_buf(vgdev->vblank[target].vblank.vq, ret_value); - } - - spin_unlock_irqrestore(&vgdev->vblank[target].vblank.qlock, irqflags); - drm_handle_vblank(dev, target); - -} - void virtio_gpu_cursor_ack(struct virtqueue *vq) { struct drm_device *dev = vq->vdev->priv; @@ -478,29 +422,6 @@ static int virtio_gpu_queue_fenced_ctrl_buffer(struct virtio_gpu_device *vgdev, return ret; } - - -void virtio_gpu_vblankq_notify(struct virtio_gpu_device *vgdev) -{ - int size,i; - - for(i=0; i < vgdev->num_vblankq; i++) { - spin_lock(&vgdev->vblank[i].vblank.qlock); - - size = virtqueue_get_vring_size(vgdev->vblank[i].vblank.vq); - if (size > ARRAY_SIZE(vgdev->vblank[i].buf)) - size = ARRAY_SIZE(vgdev->vblank[i].buf); - - virtgpu_irqqueue_buf(vgdev->vblank[i].vblank.vq, &vgdev->vblank[i].buf[0]); - - virtqueue_kick(vgdev->vblank[i].vblank.vq); - - spin_unlock(&vgdev->vblank[i].vblank.qlock); - - } - -} - void virtio_gpu_notify(struct virtio_gpu_device *vgdev) { bool notify; From 5849567ceca548bfe5be37907b0be2d8e4880349 Mon Sep 17 00:00:00 2001 From: "Xue, Bosheng" Date: Wed, 16 Apr 2025 16:33:08 +0800 Subject: [PATCH 25/43] Revert "drm/virtio: suppport configurable queue number" This reverts commit e36444b2d6e04cb3a38e4b97fc4ddee5cbe5050b. --- drivers/gpu/drm/virtio/virtgpu_drv.c | 1 - drivers/gpu/drm/virtio/virtgpu_drv.h | 10 +--- drivers/gpu/drm/virtio/virtgpu_kms.c | 78 ++++++---------------------- include/uapi/linux/virtio_gpu.h | 2 - 4 files changed, 16 insertions(+), 75 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c index 4a90ed289873..d076bb16a7c3 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.c +++ b/drivers/gpu/drm/virtio/virtgpu_drv.c @@ -153,7 +153,6 @@ static unsigned int features[] = { VIRTIO_GPU_F_CONTEXT_INIT, VIRTIO_GPU_F_MODIFIER, VIRTIO_GPU_F_SCALING, - VIRTIO_GPU_F_VBLANK, }; #ifdef CONFIG_PM_SLEEP diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index 676b7a6e41b2..db8840472d2a 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -230,11 +230,6 @@ struct virtio_gpu_drv_cap_cache { atomic_t is_valid; }; -struct virtio_gpu_vblank { - struct virtio_gpu_queue vblank; - uint32_t buf[4]; -}; - struct virtio_gpu_device { struct drm_device *ddev; @@ -242,10 +237,9 @@ struct virtio_gpu_device { struct virtio_gpu_output outputs[VIRTIO_GPU_MAX_SCANOUTS]; uint32_t num_scanouts; - uint32_t num_vblankq; + struct virtio_gpu_queue ctrlq; struct virtio_gpu_queue cursorq; - struct kmem_cache *vbufs; atomic_t pending_commands; @@ -265,7 +259,6 @@ struct virtio_gpu_device { bool has_edid; bool has_modifier; bool has_scaling; - bool has_vblank; bool has_indirect; bool has_resource_assign_uuid; bool has_resource_blob; @@ -290,7 +283,6 @@ struct virtio_gpu_device { spinlock_t resource_export_lock; /* protects map state and host_visible_mm */ spinlock_t host_visible_lock; - struct virtio_gpu_vblank vblank[]; }; struct virtio_gpu_fpriv { diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c index 9a63ea3b7f77..251bd3e1ec22 100644 --- a/drivers/gpu/drm/virtio/virtgpu_kms.c +++ b/drivers/gpu/drm/virtio/virtgpu_kms.c @@ -116,58 +116,21 @@ static void virtio_gpu_get_capsets(struct virtio_gpu_device *vgdev, int virtio_gpu_find_vqs(struct virtio_gpu_device *vgdev) { - struct virtqueue_info *vqs_info; - vq_callback_t **callbacks; - struct virtqueue **vqs; - int i, total_vqs, err; - const char **names; - int ret = 0; - - total_vqs = vgdev->num_vblankq + 2; - vqs = kcalloc(total_vqs, sizeof(*vqs), GFP_KERNEL); - callbacks = kmalloc_array(total_vqs, sizeof(vq_callback_t *), - GFP_KERNEL); - names = kmalloc_array(total_vqs, sizeof(char *), GFP_KERNEL); - vqs_info = kmalloc_array(total_vqs, sizeof(struct virtqueue_info *), - GFP_KERNEL); - - if (!callbacks || !vqs || !names || !vqs_info) { - err = -ENOMEM; - goto out; - } - - callbacks[0] = virtio_gpu_ctrl_ack; - callbacks[1] = virtio_gpu_cursor_ack; - names[0] = "control"; - names[1] = "cursor"; - for (i = 2; i < total_vqs; i++) { - callbacks[i] = virtio_gpu_vblank_ack; - names[i] = "vblank"; - } - - for (i = 0; i < total_vqs; i++) { - vqs_info[i].callback = callbacks[i]; - vqs_info[i].name = names[i]; - } - - ret = virtio_find_vqs(vgdev->vdev, total_vqs, vqs, vqs_info, NULL); - if (ret) - goto out; - - vgdev->ctrlq.vq = vqs[0]; - vgdev->cursorq.vq = vqs[1]; - - for (i = 2; i < total_vqs; i++) - vgdev->vblank[i-2].vblank.vq = vqs[i]; - - ret = 0; -out: - kfree(names); - - kfree(callbacks); - kfree(vqs); - kfree(vqs_info); - return ret; + struct virtqueue_info vqs_info[] = { + { "control", virtio_gpu_ctrl_ack }, + { "cursor", virtio_gpu_cursor_ack }, + }; + struct virtqueue *vqs[2]; + int ret; + + ret = virtio_find_vqs(vgdev->vdev, 2, vqs, vqs_info, NULL); + if (ret) + return ret; + + vgdev->ctrlq.vq = vqs[0]; + vgdev->cursorq.vq = vqs[1]; + + return 0; } int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev) @@ -225,9 +188,6 @@ int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev) if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_SCALING)) { vgdev->has_scaling = true; } - if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_VBLANK)) { - vgdev->has_vblank = true; - } if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_RESOURCE_BLOB)) { vgdev->has_resource_blob = true; if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_MODIFIER)) { @@ -266,14 +226,6 @@ int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev) DRM_INFO("features: %ccontext_init\n", vgdev->has_context_init ? '+' : '-'); - vgdev->num_vblankq = 0; - if(vgdev->has_vblank) - virtio_cread_le(vgdev->vdev, struct virtio_gpu_config, - num_pipe, &vgdev->num_vblankq); - - for(i=0; inum_vblankq; i++) - spin_lock_init(&vgdev->vblank[i].vblank.qlock); - ret = virtio_gpu_find_vqs(vgdev); if (ret) { DRM_ERROR("failed to find virt queues\n"); diff --git a/include/uapi/linux/virtio_gpu.h b/include/uapi/linux/virtio_gpu.h index c182802ff00c..87705a96c32d 100644 --- a/include/uapi/linux/virtio_gpu.h +++ b/include/uapi/linux/virtio_gpu.h @@ -73,7 +73,6 @@ */ #define VIRTIO_GPU_F_SCALING 6 -#define VIRTIO_GPU_F_VBLANK 7 enum virtio_gpu_ctrl_type { VIRTIO_GPU_UNDEFINED = 0, @@ -384,7 +383,6 @@ struct virtio_gpu_config { __le32 events_clear; __le32 num_scanouts; __le32 num_capsets; - __le32 num_pipe; }; /* simple formats for fbcon/X use */ From 85a704c5bb2a821fecee6725d84b4b2a5e319390 Mon Sep 17 00:00:00 2001 From: "Xue, Bosheng" Date: Wed, 16 Apr 2025 16:33:09 +0800 Subject: [PATCH 26/43] Revert "drm/virtio: add scaling support" This reverts commit 3d0a8eba6766fc51ee6962dd9b35bf899c12cc26. --- drivers/gpu/drm/virtio/virtgpu_drv.c | 1 - drivers/gpu/drm/virtio/virtgpu_drv.h | 6 ------ drivers/gpu/drm/virtio/virtgpu_kms.c | 3 --- drivers/gpu/drm/virtio/virtgpu_plane.c | 23 ++--------------------- drivers/gpu/drm/virtio/virtgpu_vq.c | 20 -------------------- include/uapi/linux/virtio_gpu.h | 14 -------------- 6 files changed, 2 insertions(+), 65 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c index d076bb16a7c3..7fc987a0e3ed 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.c +++ b/drivers/gpu/drm/virtio/virtgpu_drv.c @@ -152,7 +152,6 @@ static unsigned int features[] = { VIRTIO_GPU_F_RESOURCE_BLOB, VIRTIO_GPU_F_CONTEXT_INIT, VIRTIO_GPU_F_MODIFIER, - VIRTIO_GPU_F_SCALING, }; #ifdef CONFIG_PM_SLEEP diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index db8840472d2a..f2e2325eb7de 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -258,7 +258,6 @@ struct virtio_gpu_device { bool has_virgl_3d; bool has_edid; bool has_modifier; - bool has_scaling; bool has_indirect; bool has_resource_assign_uuid; bool has_resource_blob; @@ -445,11 +444,6 @@ virtio_gpu_cmd_set_scanout_blob(struct virtio_gpu_device *vgdev, void virtio_gpu_cmd_set_modifier(struct virtio_gpu_device *vgdev, uint32_t scanout_id, struct drm_framebuffer *fb); - -void virtio_gpu_cmd_set_scaling(struct virtio_gpu_device *vgdev, - uint32_t scanout_id, - struct drm_rect *rect_dst); - /* virtgpu_display.c */ int virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev); void virtio_gpu_modeset_fini(struct virtio_gpu_device *vgdev); diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c index 251bd3e1ec22..ad53cd72faf9 100644 --- a/drivers/gpu/drm/virtio/virtgpu_kms.c +++ b/drivers/gpu/drm/virtio/virtgpu_kms.c @@ -185,9 +185,6 @@ int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev) if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_RESOURCE_UUID)) { vgdev->has_resource_assign_uuid = true; } - if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_SCALING)) { - vgdev->has_scaling = true; - } if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_RESOURCE_BLOB)) { vgdev->has_resource_blob = true; if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_MODIFIER)) { diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c index 5f7bb0783243..69b04e123f8c 100644 --- a/drivers/gpu/drm/virtio/virtgpu_plane.c +++ b/drivers/gpu/drm/virtio/virtgpu_plane.c @@ -145,13 +145,9 @@ static int virtio_gpu_plane_atomic_check(struct drm_plane *plane, plane); struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane); - struct drm_device *dev = plane->dev; - struct virtio_gpu_device *vgdev = dev->dev_private; bool is_cursor = plane->type == DRM_PLANE_TYPE_CURSOR; struct drm_crtc_state *crtc_state; int ret; - int min_scale = DRM_PLANE_NO_SCALING; - int max_scale = DRM_PLANE_NO_SCALING; if (!new_plane_state->fb || WARN_ON(!new_plane_state->crtc)) return 0; @@ -169,13 +165,9 @@ static int virtio_gpu_plane_atomic_check(struct drm_plane *plane, if (IS_ERR(crtc_state)) return PTR_ERR(crtc_state); - if(vgdev->has_scaling && (new_plane_state->fb->format->format != DRM_FORMAT_C8)) { - min_scale = 1; - max_scale = 0x30000-1; - } ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state, - min_scale, - max_scale, + DRM_PLANE_NO_SCALING, + DRM_PLANE_NO_SCALING, is_cursor, true); return ret; } @@ -309,17 +301,6 @@ static void virtio_gpu_primary_plane_update(struct drm_plane *plane, } } - if(vgdev->has_scaling) { - struct drm_rect rect_dst; - - rect_dst.x1 = plane->state->crtc_x; - rect_dst.y1 = plane->state->crtc_y; - rect_dst.x2 = plane->state->crtc_w; - rect_dst.y2 = plane->state->crtc_h; - - virtio_gpu_cmd_set_scaling(vgdev, output->index, &rect_dst); - } - virtio_gpu_resource_flush(plane, rect.x1, rect.y1, diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c index 594b365b44af..0b0528bfe320 100644 --- a/drivers/gpu/drm/virtio/virtgpu_vq.c +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c @@ -1352,23 +1352,3 @@ void virtio_gpu_cmd_set_modifier(struct virtio_gpu_device *vgdev, cmd_p->scanout_id = cpu_to_le32(scanout_id); virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); } - -void virtio_gpu_cmd_set_scaling(struct virtio_gpu_device *vgdev, - uint32_t scanout_id, - struct drm_rect *rect_dst) -{ - struct virtio_gpu_set_scaling *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)); - cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_SET_SCALING); - cmd_p->scanout_id = cpu_to_le32(scanout_id); - - cmd_p->dst.width = cpu_to_le32(rect_dst->x2); - cmd_p->dst.height = cpu_to_le32(rect_dst->y2); - cmd_p->dst.x = cpu_to_le32(rect_dst->x1); - cmd_p->dst.y = cpu_to_le32(rect_dst->y1); - - virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); -} diff --git a/include/uapi/linux/virtio_gpu.h b/include/uapi/linux/virtio_gpu.h index 87705a96c32d..d5c84fb4b68b 100644 --- a/include/uapi/linux/virtio_gpu.h +++ b/include/uapi/linux/virtio_gpu.h @@ -68,11 +68,6 @@ *VIRTIO_GPU_CMD_SET_MODIFIER */ #define VIRTIO_GPU_F_MODIFIER 5 -/* -*VIRTIO_GPU_CMD_SET_SCALING -*/ -#define VIRTIO_GPU_F_SCALING 6 - enum virtio_gpu_ctrl_type { VIRTIO_GPU_UNDEFINED = 0, @@ -93,7 +88,6 @@ enum virtio_gpu_ctrl_type { VIRTIO_GPU_CMD_RESOURCE_CREATE_BLOB, VIRTIO_GPU_CMD_SET_SCANOUT_BLOB, VIRTIO_GPU_CMD_SET_MODIFIER, - VIRTIO_GPU_CMD_SET_SCALING, /* 3d commands */ VIRTIO_GPU_CMD_CTX_CREATE = 0x0200, @@ -214,14 +208,6 @@ struct virtio_gpu_resource_flush { __le32 padding; }; -/* VIRTIO_GPU_CMD_SET_SCALING */ -struct virtio_gpu_set_scaling { - struct virtio_gpu_ctrl_hdr hdr; - struct virtio_gpu_rect dst; - __le32 scanout_id; - __le32 padding; -}; - /* VIRTIO_GPU_CMD_TRANSFER_TO_HOST_2D: simple transfer to_host */ struct virtio_gpu_transfer_to_host_2d { struct virtio_gpu_ctrl_hdr hdr; From ffaeefca4db38d28bd162e74ad9a62c3dabb5950 Mon Sep 17 00:00:00 2001 From: "Xue, Bosheng" Date: Wed, 16 Apr 2025 16:33:09 +0800 Subject: [PATCH 27/43] Revert "drivers: virtgpu: Add support for gem buffer import" This reverts commit deb637803da00d2bb8ec9243a05edf58d4dd08e7. --- drivers/gpu/drm/virtio/virtgpu_drv.h | 6 -- drivers/gpu/drm/virtio/virtgpu_object.c | 4 +- drivers/gpu/drm/virtio/virtgpu_prime.c | 85 +------------------------ 3 files changed, 3 insertions(+), 92 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index f2e2325eb7de..63fe3fe65ee0 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -478,12 +478,6 @@ bool virtio_gpu_is_shmem(struct virtio_gpu_object *bo); int virtio_gpu_resource_id_get(struct virtio_gpu_device *vgdev, uint32_t *resid); -void virtio_gpu_resource_id_put(struct virtio_gpu_device *vgdev, uint32_t id); - -void virtio_gpu_object_save_restore_list(struct virtio_gpu_device *vgdev, - struct virtio_gpu_object *bo, - struct virtio_gpu_object_params *params); - int virtio_gpu_object_restore_all(struct virtio_gpu_device *vgdev); /* virtgpu_prime.c */ diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c index fb3a0abe1088..3fd2bfb39d70 100644 --- a/drivers/gpu/drm/virtio/virtgpu_object.c +++ b/drivers/gpu/drm/virtio/virtgpu_object.c @@ -54,14 +54,14 @@ int virtio_gpu_resource_id_get(struct virtio_gpu_device *vgdev, uint32_t *resid) return 0; } -void virtio_gpu_resource_id_put(struct virtio_gpu_device *vgdev, uint32_t id) +static void virtio_gpu_resource_id_put(struct virtio_gpu_device *vgdev, uint32_t id) { if (!virtio_gpu_virglrenderer_workaround) { ida_free(&vgdev->resource_ida, id - 1); } } -void virtio_gpu_object_save_restore_list(struct virtio_gpu_device *vgdev, +static void virtio_gpu_object_save_restore_list(struct virtio_gpu_device *vgdev, struct virtio_gpu_object *bo, struct virtio_gpu_object_params *params) { diff --git a/drivers/gpu/drm/virtio/virtgpu_prime.c b/drivers/gpu/drm/virtio/virtgpu_prime.c index e6ba0a4fe90c..44425f20d91a 100644 --- a/drivers/gpu/drm/virtio/virtgpu_prime.c +++ b/drivers/gpu/drm/virtio/virtgpu_prime.c @@ -162,92 +162,9 @@ struct drm_gem_object *virtgpu_gem_prime_import(struct drm_device *dev, return drm_gem_prime_import(dev, buf); } -static int virtio_gpu_sgt_to_mem_entry(struct virtio_gpu_device *vgdev, - struct sg_table *table, - struct virtio_gpu_mem_entry **ents, - unsigned int *nents) -{ - struct scatterlist *sg; - int si; - - bool use_dma_api = !virtio_has_dma_quirk(vgdev->vdev); - if (use_dma_api) - *nents = table->nents; - else - *nents = table->orig_nents; - - *ents = kvmalloc_array(*nents, - sizeof(struct virtio_gpu_mem_entry), - GFP_KERNEL); - if (!(*ents)) { - DRM_ERROR("failed to allocate ent list\n"); - return -ENOMEM; - } - - if (use_dma_api) { - for_each_sgtable_dma_sg(table, sg, si) { - (*ents)[si].addr = cpu_to_le64(sg_dma_address(sg)); - (*ents)[si].length = cpu_to_le32(sg_dma_len(sg)); - (*ents)[si].padding = 0; - } - } else { - for_each_sgtable_sg(table, sg, si) { - (*ents)[si].addr = cpu_to_le64(sg_phys(sg)); - (*ents)[si].length = cpu_to_le32(sg->length); - (*ents)[si].padding = 0; - } - } - - return 0; - -} - struct drm_gem_object *virtgpu_gem_prime_import_sg_table( struct drm_device *dev, struct dma_buf_attachment *attach, struct sg_table *table) { - size_t size = PAGE_ALIGN(attach->dmabuf->size); - struct virtio_gpu_device *vgdev = dev->dev_private; - struct virtio_gpu_object_params params = { 0 }; - struct virtio_gpu_object *bo; - struct drm_gem_object *obj; - struct virtio_gpu_mem_entry *ents; - unsigned int nents; - int ret; - - if (!vgdev->has_resource_blob || vgdev->has_virgl_3d) { - return ERR_PTR(-ENODEV); - } - - obj = drm_gem_shmem_prime_import_sg_table(dev, attach, table); - if (IS_ERR(obj)) { - return ERR_CAST(obj); - } - - bo = gem_to_virtio_gpu_obj(obj); - ret = virtio_gpu_resource_id_get(vgdev, &bo->hw_res_handle); - if (ret < 0) { - return ERR_PTR(ret); - } - - ret = virtio_gpu_sgt_to_mem_entry(vgdev, table, &ents, &nents); - if (ret != 0) { - goto err_put_id; - } - - bo->guest_blob = true; - params.blob_mem = VIRTGPU_BLOB_MEM_GUEST; - params.blob_flags = VIRTGPU_BLOB_FLAG_USE_SHAREABLE; - params.blob = true; - params.size = size; - - virtio_gpu_cmd_resource_create_blob(vgdev, bo, ¶ms, - ents, nents); - virtio_gpu_object_save_restore_list(vgdev, bo, ¶ms); - - return obj; - -err_put_id: - virtio_gpu_resource_id_put(vgdev, bo->hw_res_handle); - return ERR_PTR(ret); + return ERR_PTR(-ENODEV); } From a65c9edc1d2e7987ae30e3d49424d2c957ae628c Mon Sep 17 00:00:00 2001 From: "Xue, Bosheng" Date: Wed, 16 Apr 2025 16:33:10 +0800 Subject: [PATCH 28/43] Revert "drivers: virtgpu: Add virtio-gpu tiling format support" This reverts commit d247d778a70400fbb03cde472072dedbebd09c39. --- drivers/gpu/drm/virtio/virtgpu_display.c | 3 +- drivers/gpu/drm/virtio/virtgpu_drv.c | 1 - drivers/gpu/drm/virtio/virtgpu_drv.h | 5 +-- drivers/gpu/drm/virtio/virtgpu_kms.c | 3 -- drivers/gpu/drm/virtio/virtgpu_plane.c | 41 +++--------------------- drivers/gpu/drm/virtio/virtgpu_vq.c | 15 --------- include/uapi/linux/virtio_gpu.h | 12 ------- 7 files changed, 6 insertions(+), 74 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c index 3dae4e95d4ed..ba9505098bf3 100644 --- a/drivers/gpu/drm/virtio/virtgpu_display.c +++ b/drivers/gpu/drm/virtio/virtgpu_display.c @@ -345,8 +345,7 @@ int virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev) vgdev->ddev->mode_config.max_width = XRES_MAX; vgdev->ddev->mode_config.max_height = YRES_MAX; - if (!vgdev->has_modifier) - vgdev->ddev->mode_config.fb_modifiers_not_supported = true; + vgdev->ddev->mode_config.fb_modifiers_not_supported = true; for (i = 0 ; i < vgdev->num_scanouts; ++i) vgdev_output_init(vgdev, i); diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c index 7fc987a0e3ed..f4f62326a98f 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.c +++ b/drivers/gpu/drm/virtio/virtgpu_drv.c @@ -151,7 +151,6 @@ static unsigned int features[] = { VIRTIO_GPU_F_RESOURCE_UUID, VIRTIO_GPU_F_RESOURCE_BLOB, VIRTIO_GPU_F_CONTEXT_INIT, - VIRTIO_GPU_F_MODIFIER, }; #ifdef CONFIG_PM_SLEEP diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index 63fe3fe65ee0..8ac9c11afd70 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -257,7 +257,6 @@ struct virtio_gpu_device { bool has_virgl_3d; bool has_edid; - bool has_modifier; bool has_indirect; bool has_resource_assign_uuid; bool has_resource_blob; @@ -441,9 +440,7 @@ virtio_gpu_cmd_set_scanout_blob(struct virtio_gpu_device *vgdev, struct drm_framebuffer *fb, uint32_t width, uint32_t height, uint32_t x, uint32_t y); -void virtio_gpu_cmd_set_modifier(struct virtio_gpu_device *vgdev, - uint32_t scanout_id, - struct drm_framebuffer *fb); + /* virtgpu_display.c */ int virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev); void virtio_gpu_modeset_fini(struct virtio_gpu_device *vgdev); diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c index ad53cd72faf9..a6d0ee783bf0 100644 --- a/drivers/gpu/drm/virtio/virtgpu_kms.c +++ b/drivers/gpu/drm/virtio/virtgpu_kms.c @@ -187,9 +187,6 @@ int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev) } if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_RESOURCE_BLOB)) { vgdev->has_resource_blob = true; - if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_MODIFIER)) { - vgdev->has_modifier = true; - } } if (virtio_get_shm_region(vgdev->vdev, &vgdev->host_visible_region, VIRTIO_GPU_SHM_ID_HOST_VISIBLE)) { diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c index 69b04e123f8c..86e6559e2c92 100644 --- a/drivers/gpu/drm/virtio/virtgpu_plane.c +++ b/drivers/gpu/drm/virtio/virtgpu_plane.c @@ -130,7 +130,7 @@ drm_plane_state *virtio_gpu_plane_duplicate_state(struct drm_plane *plane) return &new->base; } -static struct drm_plane_funcs virtio_gpu_plane_funcs = { +static const struct drm_plane_funcs virtio_gpu_plane_funcs = { .update_plane = drm_atomic_helper_update_plane, .disable_plane = drm_atomic_helper_disable_plane, .reset = drm_atomic_helper_plane_reset, @@ -288,9 +288,6 @@ static void virtio_gpu_primary_plane_update(struct drm_plane *plane, plane->state->src_h >> 16, plane->state->src_x >> 16, plane->state->src_y >> 16); - if (vgdev->has_modifier) - virtio_gpu_cmd_set_modifier(vgdev, output->index, plane->state->fb); - } else { virtio_gpu_cmd_set_scanout(vgdev, output->index, bo->hw_res_handle, @@ -446,27 +443,6 @@ static const struct drm_plane_helper_funcs virtio_gpu_cursor_helper_funcs = { .atomic_update = virtio_gpu_cursor_plane_update, }; -static const uint64_t virtio_gpu_format_modifiers[] = { - DRM_FORMAT_MOD_LINEAR, - I915_FORMAT_MOD_X_TILED, - I915_FORMAT_MOD_Y_TILED, - DRM_FORMAT_MOD_INVALID -}; - - -static bool virtio_gpu_plane_format_mod_supported(struct drm_plane *_plane, - u32 format, u64 modifier) -{ - switch (modifier) { - case DRM_FORMAT_MOD_LINEAR: - case I915_FORMAT_MOD_X_TILED: - case I915_FORMAT_MOD_Y_TILED: - return true; - default: - return false; - } -} - struct drm_plane *virtio_gpu_plane_init(struct virtio_gpu_device *vgdev, enum drm_plane_type type, int index) @@ -487,18 +463,9 @@ struct drm_plane *virtio_gpu_plane_init(struct virtio_gpu_device *vgdev, funcs = &virtio_gpu_primary_helper_funcs; } - if (vgdev->has_modifier) { - const uint64_t *modifiers = virtio_gpu_format_modifiers; - virtio_gpu_plane_funcs.format_mod_supported = virtio_gpu_plane_format_mod_supported; - plane = drmm_universal_plane_alloc(dev, struct drm_plane, dev, - 1 << index, &virtio_gpu_plane_funcs, - formats, nformats, modifiers, type, NULL); - } else { - plane = drmm_universal_plane_alloc(dev, struct drm_plane, dev, - 1 << index, &virtio_gpu_plane_funcs, - formats, nformats, NULL, type, NULL); - } - + plane = drmm_universal_plane_alloc(dev, struct drm_plane, dev, + 1 << index, &virtio_gpu_plane_funcs, + formats, nformats, NULL, type, NULL); if (IS_ERR(plane)) return plane; diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c index 0b0528bfe320..ad91624df42d 100644 --- a/drivers/gpu/drm/virtio/virtgpu_vq.c +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c @@ -1337,18 +1337,3 @@ void virtio_gpu_cmd_set_scanout_blob(struct virtio_gpu_device *vgdev, virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); } - -void virtio_gpu_cmd_set_modifier(struct virtio_gpu_device *vgdev, - uint32_t scanout_id, - struct drm_framebuffer *fb) -{ - struct virtio_gpu_set_modifier *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)); - cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_SET_MODIFIER); - cmd_p->modifier = cpu_to_le64(fb->modifier); - cmd_p->scanout_id = cpu_to_le32(scanout_id); - virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); -} diff --git a/include/uapi/linux/virtio_gpu.h b/include/uapi/linux/virtio_gpu.h index d5c84fb4b68b..bf2c9cabd207 100644 --- a/include/uapi/linux/virtio_gpu.h +++ b/include/uapi/linux/virtio_gpu.h @@ -64,10 +64,6 @@ * context_init and multiple timelines */ #define VIRTIO_GPU_F_CONTEXT_INIT 4 -/* - *VIRTIO_GPU_CMD_SET_MODIFIER - */ -#define VIRTIO_GPU_F_MODIFIER 5 enum virtio_gpu_ctrl_type { VIRTIO_GPU_UNDEFINED = 0, @@ -87,7 +83,6 @@ enum virtio_gpu_ctrl_type { VIRTIO_GPU_CMD_RESOURCE_ASSIGN_UUID, VIRTIO_GPU_CMD_RESOURCE_CREATE_BLOB, VIRTIO_GPU_CMD_SET_SCANOUT_BLOB, - VIRTIO_GPU_CMD_SET_MODIFIER, /* 3d commands */ VIRTIO_GPU_CMD_CTX_CREATE = 0x0200, @@ -433,13 +428,6 @@ struct virtio_gpu_set_scanout_blob { __le32 strides[4]; __le32 offsets[4]; }; -/* VIRTIO_GPU_CMD_SET_MODIFIER */ -struct virtio_gpu_set_modifier { - struct virtio_gpu_ctrl_hdr hdr; - __le64 modifier; - __le32 scanout_id; - __le32 padding; -}; /* VIRTIO_GPU_CMD_RESOURCE_MAP_BLOB */ struct virtio_gpu_resource_map_blob { From a4a0611193d41240b8207bb2ef13e92988dec3d8 Mon Sep 17 00:00:00 2001 From: "Xue, Bosheng" Date: Wed, 16 Apr 2025 16:33:11 +0800 Subject: [PATCH 29/43] Revert "drm/virtio: save and restore virtio_gpu_objects" This reverts commit bf23154be7cfe3478bb4448d42b24f2a2b3441ef. --- drivers/gpu/drm/virtio/virtgpu_drv.c | 6 --- drivers/gpu/drm/virtio/virtgpu_drv.h | 10 ---- drivers/gpu/drm/virtio/virtgpu_kms.c | 1 - drivers/gpu/drm/virtio/virtgpu_object.c | 65 ------------------------- 4 files changed, 82 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c index f4f62326a98f..576af6140fac 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.c +++ b/drivers/gpu/drm/virtio/virtgpu_drv.c @@ -189,12 +189,6 @@ static int virtgpu_restore(struct virtio_device *vdev) virtio_device_ready(vdev); - error = virtio_gpu_object_restore_all(vgdev); - if (error) { - DRM_ERROR("Failed to recover objects\n"); - return error; - } - error = drm_mode_config_helper_resume(dev); if (error) { DRM_ERROR("resume error %d\n", error); diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index 8ac9c11afd70..c2ce3738c3f0 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -125,12 +125,6 @@ struct virtio_gpu_object_array { struct drm_gem_object *objs[] __counted_by(total); }; -struct virtio_gpu_object_restore { - struct virtio_gpu_object *bo; - struct virtio_gpu_object_params params; - struct list_head node; -}; - struct virtio_gpu_vbuffer; struct virtio_gpu_device; @@ -270,7 +264,6 @@ struct virtio_gpu_device { struct work_struct obj_free_work; spinlock_t obj_free_lock; struct list_head obj_free_list; - struct list_head obj_rec; struct virtio_gpu_drv_capset *capsets; uint32_t num_capsets; @@ -474,9 +467,6 @@ bool virtio_gpu_is_shmem(struct virtio_gpu_object *bo); int virtio_gpu_resource_id_get(struct virtio_gpu_device *vgdev, uint32_t *resid); - -int virtio_gpu_object_restore_all(struct virtio_gpu_device *vgdev); - /* virtgpu_prime.c */ int virtio_gpu_resource_assign_uuid(struct virtio_gpu_device *vgdev, struct virtio_gpu_object *bo); diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c index a6d0ee783bf0..6c1af77ea083 100644 --- a/drivers/gpu/drm/virtio/virtgpu_kms.c +++ b/drivers/gpu/drm/virtio/virtgpu_kms.c @@ -162,7 +162,6 @@ int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev) vgdev->fence_drv.context = dma_fence_context_alloc(1); spin_lock_init(&vgdev->fence_drv.lock); INIT_LIST_HEAD(&vgdev->fence_drv.fences); - INIT_LIST_HEAD(&vgdev->obj_rec); INIT_LIST_HEAD(&vgdev->cap_cache); INIT_WORK(&vgdev->config_changed_work, virtio_gpu_config_changed_work_func); diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c index 3fd2bfb39d70..d18263ddd972 100644 --- a/drivers/gpu/drm/virtio/virtgpu_object.c +++ b/drivers/gpu/drm/virtio/virtgpu_object.c @@ -61,38 +61,6 @@ static void virtio_gpu_resource_id_put(struct virtio_gpu_device *vgdev, uint32_t } } -static void virtio_gpu_object_save_restore_list(struct virtio_gpu_device *vgdev, - struct virtio_gpu_object *bo, - struct virtio_gpu_object_params *params) -{ - struct virtio_gpu_object_restore *new; - - new = kvmalloc(sizeof(*new), GFP_KERNEL); - if (!new) { - DRM_ERROR("Fail to allocate virtio_gpu_object_restore"); - return; - } - - new->bo = bo; - memcpy(&new->params, params, sizeof(*params)); - - list_add_tail(&new->node, &vgdev->obj_rec); -} - -static void virtio_gpu_object_del_restore_list(struct virtio_gpu_device *vgdev, - struct virtio_gpu_object *bo) -{ - struct virtio_gpu_object_restore *curr, *tmp; - - list_for_each_entry_safe(curr, tmp, &vgdev->obj_rec, node) { - if (bo == curr->bo) { - list_del(&curr->node); - kvfree(curr); - break; - } - } -} - void virtio_gpu_cleanup_object(struct virtio_gpu_object *bo) { struct virtio_gpu_device *vgdev = bo->base.base.dev->dev_private; @@ -113,7 +81,6 @@ void virtio_gpu_cleanup_object(struct virtio_gpu_object *bo) drm_gem_object_release(&vram->base.base.base); kfree(vram); } - virtio_gpu_object_del_restore_list(vgdev, bo); } static void virtio_gpu_free_object(struct drm_gem_object *obj) @@ -287,11 +254,8 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev, objs, fence); virtio_gpu_object_attach(vgdev, bo, ents, nents); } - /* add submitted object to restore list */ - virtio_gpu_object_save_restore_list(vgdev, bo, params); *bo_ptr = bo; - return 0; err_put_objs: @@ -304,32 +268,3 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev, drm_gem_shmem_free(shmem_obj); return ret; } - -int virtio_gpu_object_restore_all(struct virtio_gpu_device *vgdev) -{ - struct virtio_gpu_object_restore *curr, *tmp; - struct virtio_gpu_mem_entry *ents; - unsigned int nents; - int ret; - - list_for_each_entry_safe(curr, tmp, &vgdev->obj_rec, node) { - ret = virtio_gpu_object_shmem_init(vgdev, curr->bo, &ents, &nents); - if (ret) - break; - - if (curr->params.blob) { - virtio_gpu_cmd_resource_create_blob(vgdev, curr->bo, &curr->params, - ents, nents); - } else if (curr->params.virgl) { - virtio_gpu_cmd_resource_create_3d(vgdev, curr->bo, &curr->params, - NULL, NULL); - virtio_gpu_object_attach(vgdev, curr->bo, ents, nents); - } else { - virtio_gpu_cmd_create_resource(vgdev, curr->bo, &curr->params, - NULL, NULL); - virtio_gpu_object_attach(vgdev, curr->bo, ents, nents); - } - } - - return ret; -} From d09e27a14cd2f42e02bf322b68e07671648e567f Mon Sep 17 00:00:00 2001 From: "Xue, Bosheng" Date: Wed, 16 Apr 2025 16:33:11 +0800 Subject: [PATCH 30/43] Revert "drm/virtio: freeze and restore hooks to support suspend and resume" This reverts commit 24e099faab14996f045f34362682edf16392387b. --- drivers/gpu/drm/virtio/virtgpu_drv.c | 53 +--------------------------- drivers/gpu/drm/virtio/virtgpu_drv.h | 1 - drivers/gpu/drm/virtio/virtgpu_kms.c | 23 ++++-------- 3 files changed, 7 insertions(+), 70 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c index 576af6140fac..6a67c6297d58 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.c +++ b/drivers/gpu/drm/virtio/virtgpu_drv.c @@ -152,53 +152,6 @@ static unsigned int features[] = { VIRTIO_GPU_F_RESOURCE_BLOB, VIRTIO_GPU_F_CONTEXT_INIT, }; - -#ifdef CONFIG_PM_SLEEP -static int virtgpu_freeze(struct virtio_device *vdev) -{ - struct drm_device *dev = vdev->priv; - struct virtio_gpu_device *vgdev = dev->dev_private; - int error; - - error = drm_mode_config_helper_suspend(dev); - if (error) { - DRM_ERROR("suspend error %d\n", error); - return error; - } - - flush_work(&vgdev->obj_free_work); - flush_work(&vgdev->ctrlq.dequeue_work); - flush_work(&vgdev->cursorq.dequeue_work); - flush_work(&vgdev->config_changed_work); - vdev->config->del_vqs(vdev); - - return 0; -} - -static int virtgpu_restore(struct virtio_device *vdev) -{ - struct drm_device *dev = vdev->priv; - struct virtio_gpu_device *vgdev = dev->dev_private; - int error; - - error = virtio_gpu_find_vqs(vgdev); - if (error) { - DRM_ERROR("failed to find virt queues\n"); - return error; - } - - virtio_device_ready(vdev); - - error = drm_mode_config_helper_resume(dev); - if (error) { - DRM_ERROR("resume error %d\n", error); - return error; - } - - return 0; -} -#endif - static struct virtio_driver virtio_gpu_driver = { .feature_table = features, .feature_table_size = ARRAY_SIZE(features), @@ -206,11 +159,7 @@ static struct virtio_driver virtio_gpu_driver = { .id_table = id_table, .probe = virtio_gpu_probe, .remove = virtio_gpu_remove, - .config_changed = virtio_gpu_config_changed, -#ifdef CONFIG_PM_SLEEP - .freeze = virtgpu_freeze, - .restore = virtgpu_restore, -#endif + .config_changed = virtio_gpu_config_changed }; module_virtio_driver(virtio_gpu_driver); diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index c2ce3738c3f0..fb4cbd11c879 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -299,7 +299,6 @@ void virtio_gpu_deinit(struct drm_device *dev); void virtio_gpu_release(struct drm_device *dev); int virtio_gpu_driver_open(struct drm_device *dev, struct drm_file *file); void virtio_gpu_driver_postclose(struct drm_device *dev, struct drm_file *file); -int virtio_gpu_find_vqs(struct virtio_gpu_device *vgdev); /* virtgpu_gem.c */ int virtio_gpu_gem_object_open(struct drm_gem_object *obj, diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c index 6c1af77ea083..7dfb2006c561 100644 --- a/drivers/gpu/drm/virtio/virtgpu_kms.c +++ b/drivers/gpu/drm/virtio/virtgpu_kms.c @@ -114,28 +114,15 @@ static void virtio_gpu_get_capsets(struct virtio_gpu_device *vgdev, vgdev->num_capsets = num_capsets; } -int virtio_gpu_find_vqs(struct virtio_gpu_device *vgdev) +int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev) { struct virtqueue_info vqs_info[] = { { "control", virtio_gpu_ctrl_ack }, { "cursor", virtio_gpu_cursor_ack }, }; - struct virtqueue *vqs[2]; - int ret; - - ret = virtio_find_vqs(vgdev->vdev, 2, vqs, vqs_info, NULL); - if (ret) - return ret; - - vgdev->ctrlq.vq = vqs[0]; - vgdev->cursorq.vq = vqs[1]; - - return 0; -} - -int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev) -{ struct virtio_gpu_device *vgdev; + /* this will expand later */ + struct virtqueue *vqs[2]; u32 num_scanouts, num_capsets; int ret = 0; @@ -219,11 +206,13 @@ int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev) DRM_INFO("features: %ccontext_init\n", vgdev->has_context_init ? '+' : '-'); - ret = virtio_gpu_find_vqs(vgdev); + ret = virtio_find_vqs(vgdev->vdev, 2, vqs, vqs_info, NULL); if (ret) { DRM_ERROR("failed to find virt queues\n"); goto err_vqs; } + vgdev->ctrlq.vq = vqs[0]; + vgdev->cursorq.vq = vqs[1]; ret = virtio_gpu_alloc_vbufs(vgdev); if (ret) { DRM_ERROR("failed to alloc vbufs\n"); From 883d883ccdb425ecdbeeb8cd5c3d83b789f50c85 Mon Sep 17 00:00:00 2001 From: "Xue, Bosheng" Date: Wed, 16 Apr 2025 16:33:12 +0800 Subject: [PATCH 31/43] Revert "Revert "drm/virtio: Add a helper to map and note the dma addrs and lengths"" This reverts commit d52c6ef63a48b88186eb4f3287874aaed2d6efb5. --- drivers/gpu/drm/virtio/virtgpu_drv.h | 5 +++ drivers/gpu/drm/virtio/virtgpu_prime.c | 42 ++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index fb4cbd11c879..f42ca9d8ed10 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -88,6 +88,7 @@ struct virtio_gpu_object_params { struct virtio_gpu_object { struct drm_gem_shmem_object base; + struct sg_table *sgt; uint32_t hw_res_handle; bool dumb; bool created; @@ -476,6 +477,10 @@ struct drm_gem_object *virtgpu_gem_prime_import(struct drm_device *dev, struct drm_gem_object *virtgpu_gem_prime_import_sg_table( struct drm_device *dev, struct dma_buf_attachment *attach, struct sg_table *sgt); +int virtgpu_dma_buf_import_sgt(struct virtio_gpu_mem_entry **ents, + unsigned int *nents, + struct virtio_gpu_object *bo, + struct dma_buf_attachment *attach); /* virtgpu_debugfs.c */ void virtio_gpu_debugfs_init(struct drm_minor *minor); diff --git a/drivers/gpu/drm/virtio/virtgpu_prime.c b/drivers/gpu/drm/virtio/virtgpu_prime.c index 44425f20d91a..8e63aa67270a 100644 --- a/drivers/gpu/drm/virtio/virtgpu_prime.c +++ b/drivers/gpu/drm/virtio/virtgpu_prime.c @@ -27,6 +27,8 @@ #include "virtgpu_drv.h" +MODULE_IMPORT_NS(DMA_BUF); + static int virtgpu_virtio_get_uuid(struct dma_buf *buf, uuid_t *uuid) { @@ -142,6 +144,46 @@ struct dma_buf *virtgpu_gem_prime_export(struct drm_gem_object *obj, return buf; } +int virtgpu_dma_buf_import_sgt(struct virtio_gpu_mem_entry **ents, + unsigned int *nents, + struct virtio_gpu_object *bo, + struct dma_buf_attachment *attach) +{ + struct scatterlist *sl; + struct sg_table *sgt; + long i, ret; + + dma_resv_assert_held(attach->dmabuf->resv); + + ret = dma_resv_wait_timeout(attach->dmabuf->resv, + DMA_RESV_USAGE_KERNEL, + false, MAX_SCHEDULE_TIMEOUT); + if (ret <= 0) + return ret < 0 ? ret : -ETIMEDOUT; + + sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); + if (IS_ERR(sgt)) + return PTR_ERR(sgt); + + *ents = kvmalloc_array(sgt->nents, + sizeof(struct virtio_gpu_mem_entry), + GFP_KERNEL); + if (!(*ents)) { + dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL); + return -ENOMEM; + } + + *nents = sgt->nents; + for_each_sgtable_dma_sg(sgt, sl, i) { + (*ents)[i].addr = cpu_to_le64(sg_dma_address(sl)); + (*ents)[i].length = cpu_to_le32(sg_dma_len(sl)); + (*ents)[i].padding = 0; + } + + bo->sgt = sgt; + return 0; +} + struct drm_gem_object *virtgpu_gem_prime_import(struct drm_device *dev, struct dma_buf *buf) { From 935009767c4aacb2ee86cc2b134dd1e2159a59bc Mon Sep 17 00:00:00 2001 From: "Xue, Bosheng" Date: Wed, 16 Apr 2025 16:33:12 +0800 Subject: [PATCH 32/43] Revert "Revert "drm/virtio: Add helpers to initialize and free the imported object"" This reverts commit 47dd2b5d1a6f70219c5a2fb610ecb4ded68a8584. --- drivers/gpu/drm/virtio/virtgpu_object.c | 3 + drivers/gpu/drm/virtio/virtgpu_prime.c | 75 +++++++++++++++++++++++++ 2 files changed, 78 insertions(+) diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c index d18263ddd972..5517cff8715c 100644 --- a/drivers/gpu/drm/virtio/virtgpu_object.c +++ b/drivers/gpu/drm/virtio/virtgpu_object.c @@ -80,6 +80,9 @@ void virtio_gpu_cleanup_object(struct virtio_gpu_object *bo) drm_gem_free_mmap_offset(&vram->base.base.base); drm_gem_object_release(&vram->base.base.base); kfree(vram); + } else { + drm_gem_object_release(&bo->base.base); + kfree(bo); } } diff --git a/drivers/gpu/drm/virtio/virtgpu_prime.c b/drivers/gpu/drm/virtio/virtgpu_prime.c index 8e63aa67270a..887b635dec6f 100644 --- a/drivers/gpu/drm/virtio/virtgpu_prime.c +++ b/drivers/gpu/drm/virtio/virtgpu_prime.c @@ -184,6 +184,81 @@ int virtgpu_dma_buf_import_sgt(struct virtio_gpu_mem_entry **ents, return 0; } +static void virtgpu_dma_buf_free_obj(struct drm_gem_object *obj) +{ + struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(obj); + struct virtio_gpu_device *vgdev = obj->dev->dev_private; + struct dma_buf_attachment *attach = obj->import_attach; + + if (attach) { + virtio_gpu_detach_object_fenced(bo); + + if (bo->sgt) + dma_buf_unmap_attachment_unlocked(attach, bo->sgt, + DMA_BIDIRECTIONAL); + + dma_buf_detach(attach->dmabuf, attach); + dma_buf_put(attach->dmabuf); + } + + if (bo->created) { + virtio_gpu_cmd_unref_resource(vgdev, bo); + virtio_gpu_notify(vgdev); + return; + } + virtio_gpu_cleanup_object(bo); +} + +static int virtgpu_dma_buf_init_obj(struct drm_device *dev, + struct virtio_gpu_object *bo, + struct dma_buf_attachment *attach) +{ + struct virtio_gpu_device *vgdev = dev->dev_private; + struct virtio_gpu_object_params params = { 0 }; + struct dma_resv *resv = attach->dmabuf->resv; + struct virtio_gpu_mem_entry *ents = NULL; + unsigned int nents; + int ret; + + ret = virtio_gpu_resource_id_get(vgdev, &bo->hw_res_handle); + if (ret) { + virtgpu_dma_buf_free_obj(&bo->base.base); + return ret; + } + + dma_resv_lock(resv, NULL); + + ret = dma_buf_pin(attach); + if (ret) + goto err_pin; + + ret = virtgpu_dma_buf_import_sgt(&ents, &nents, bo, attach); + if (ret) + goto err_import; + + params.blob = true; + params.blob_mem = VIRTGPU_BLOB_MEM_GUEST; + params.blob_flags = VIRTGPU_BLOB_FLAG_USE_SHAREABLE; + params.size = attach->dmabuf->size; + + virtio_gpu_cmd_resource_create_blob(vgdev, bo, ¶ms, + ents, nents); + bo->guest_blob = true; + bo->attached = true; + + dma_buf_unpin(attach); + dma_resv_unlock(resv); + + return 0; + +err_import: + dma_buf_unpin(attach); +err_pin: + dma_resv_unlock(resv); + virtgpu_dma_buf_free_obj(&bo->base.base); + return ret; +} + struct drm_gem_object *virtgpu_gem_prime_import(struct drm_device *dev, struct dma_buf *buf) { From 2424acfa31b07d990c1745750dacc4f625180344 Mon Sep 17 00:00:00 2001 From: "Xue, Bosheng" Date: Wed, 16 Apr 2025 16:33:13 +0800 Subject: [PATCH 33/43] Revert "Revert "drm/virtio: Import prime buffers from other devices as guest blobs"" This reverts commit f9c9cc9011f7eace3cc2dc11a4d8668ba65bfb78. --- drivers/gpu/drm/virtio/virtgpu_prime.c | 65 ++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_prime.c b/drivers/gpu/drm/virtio/virtgpu_prime.c index 887b635dec6f..688810d1b611 100644 --- a/drivers/gpu/drm/virtio/virtgpu_prime.c +++ b/drivers/gpu/drm/virtio/virtgpu_prime.c @@ -189,13 +189,18 @@ static void virtgpu_dma_buf_free_obj(struct drm_gem_object *obj) struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(obj); struct virtio_gpu_device *vgdev = obj->dev->dev_private; struct dma_buf_attachment *attach = obj->import_attach; + struct dma_resv *resv = attach->dmabuf->resv; if (attach) { + dma_resv_lock(resv, NULL); + virtio_gpu_detach_object_fenced(bo); if (bo->sgt) - dma_buf_unmap_attachment_unlocked(attach, bo->sgt, - DMA_BIDIRECTIONAL); + dma_buf_unmap_attachment(attach, bo->sgt, + DMA_BIDIRECTIONAL); + + dma_resv_unlock(resv); dma_buf_detach(attach->dmabuf, attach); dma_buf_put(attach->dmabuf); @@ -259,10 +264,39 @@ static int virtgpu_dma_buf_init_obj(struct drm_device *dev, return ret; } +static const struct drm_gem_object_funcs virtgpu_gem_dma_buf_funcs = { + .free = virtgpu_dma_buf_free_obj, +}; + +static void virtgpu_dma_buf_move_notify(struct dma_buf_attachment *attach) +{ + struct drm_gem_object *obj = attach->importer_priv; + struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(obj); + + if (bo->created && kref_read(&obj->refcount)) { + virtio_gpu_detach_object_fenced(bo); + + if (bo->sgt) + dma_buf_unmap_attachment(attach, bo->sgt, + DMA_BIDIRECTIONAL); + + bo->sgt = NULL; + } +} + +static const struct dma_buf_attach_ops virtgpu_dma_buf_attach_ops = { + .allow_peer2peer = true, + .move_notify = virtgpu_dma_buf_move_notify +}; + struct drm_gem_object *virtgpu_gem_prime_import(struct drm_device *dev, struct dma_buf *buf) { + struct virtio_gpu_device *vgdev = dev->dev_private; + struct dma_buf_attachment *attach; + struct virtio_gpu_object *bo; struct drm_gem_object *obj; + int ret; if (buf->ops == &virtgpu_dmabuf_ops.ops) { obj = buf->priv; @@ -276,7 +310,32 @@ struct drm_gem_object *virtgpu_gem_prime_import(struct drm_device *dev, } } - return drm_gem_prime_import(dev, buf); + if (!vgdev->has_resource_blob || vgdev->has_virgl_3d) + return drm_gem_prime_import(dev, buf); + + bo = kzalloc(sizeof(*bo), GFP_KERNEL); + if (!bo) + return ERR_PTR(-ENOMEM); + + obj = &bo->base.base; + obj->funcs = &virtgpu_gem_dma_buf_funcs; + drm_gem_private_object_init(dev, obj, buf->size); + + attach = dma_buf_dynamic_attach(buf, dev->dev, + &virtgpu_dma_buf_attach_ops, obj); + if (IS_ERR(attach)) { + kfree(bo); + return ERR_CAST(attach); + } + + obj->import_attach = attach; + get_dma_buf(buf); + + ret = virtgpu_dma_buf_init_obj(dev, bo, attach); + if (ret < 0) + return ERR_PTR(ret); + + return obj; } struct drm_gem_object *virtgpu_gem_prime_import_sg_table( From d01d991d3f415225d4e28caa63ee1b903c0ba249 Mon Sep 17 00:00:00 2001 From: "Xue, Bosheng" Date: Wed, 16 Apr 2025 16:33:14 +0800 Subject: [PATCH 34/43] Revert "Revert "drm/virtio: Add prepare and cleanup routines for imported dmabuf obj"" This reverts commit 8cb0bb940a16c8703b6b4cbbc627c52b41531ad5. --- drivers/gpu/drm/virtio/virtgpu_plane.c | 65 +++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c index 86e6559e2c92..4a11f7db6bf3 100644 --- a/drivers/gpu/drm/virtio/virtgpu_plane.c +++ b/drivers/gpu/drm/virtio/virtgpu_plane.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "virtgpu_drv.h" @@ -305,6 +306,44 @@ static void virtio_gpu_primary_plane_update(struct drm_plane *plane, rect.y2 - rect.y1); } +static int virtio_gpu_prepare_imported_obj(struct drm_plane *plane, + struct drm_plane_state *new_state, + struct drm_gem_object *obj) +{ + struct virtio_gpu_device *vgdev = plane->dev->dev_private; + struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(obj); + struct dma_buf_attachment *attach = obj->import_attach; + struct dma_resv *resv = attach->dmabuf->resv; + struct virtio_gpu_mem_entry *ents = NULL; + unsigned int nents; + int ret; + + dma_resv_lock(resv, NULL); + + ret = dma_buf_pin(attach); + if (ret) { + dma_resv_unlock(resv); + return ret; + } + + if (!bo->sgt) { + ret = virtgpu_dma_buf_import_sgt(&ents, &nents, + bo, attach); + if (ret) + goto err; + + virtio_gpu_object_attach(vgdev, bo, ents, nents); + } + + dma_resv_unlock(resv); + return 0; + +err: + dma_buf_unpin(attach); + dma_resv_unlock(resv); + return ret; +} + static int virtio_gpu_plane_prepare_fb(struct drm_plane *plane, struct drm_plane_state *new_state) { @@ -313,6 +352,8 @@ static int virtio_gpu_plane_prepare_fb(struct drm_plane *plane, struct virtio_gpu_framebuffer *vgfb; struct virtio_gpu_plane_state *vgplane_st; struct virtio_gpu_object *bo; + struct drm_gem_object *obj; + int ret; if (!new_state->fb) return 0; @@ -326,7 +367,14 @@ static int virtio_gpu_plane_prepare_fb(struct drm_plane *plane, if (!bo || (plane->type == DRM_PLANE_TYPE_PRIMARY && !bo->guest_blob)) return 0; - if (bo->dumb) { + obj = new_state->fb->obj[0]; + if (obj->import_attach) { + ret = virtio_gpu_prepare_imported_obj(plane, new_state, obj); + if (ret) + return ret; + } + + if (bo->dumb || obj->import_attach) { vgplane_st->fence = virtio_gpu_fence_alloc(vgdev, vgdev->fence_drv.context, 0); @@ -337,10 +385,21 @@ static int virtio_gpu_plane_prepare_fb(struct drm_plane *plane, return 0; } +static void virtio_gpu_cleanup_imported_obj(struct drm_gem_object *obj) +{ + struct dma_buf_attachment *attach = obj->import_attach; + struct dma_resv *resv = attach->dmabuf->resv; + + dma_resv_lock(resv, NULL); + dma_buf_unpin(attach); + dma_resv_unlock(resv); +} + static void virtio_gpu_plane_cleanup_fb(struct drm_plane *plane, struct drm_plane_state *state) { struct virtio_gpu_plane_state *vgplane_st; + struct drm_gem_object *obj; if (!state->fb) return; @@ -350,6 +409,10 @@ static void virtio_gpu_plane_cleanup_fb(struct drm_plane *plane, dma_fence_put(&vgplane_st->fence->f); vgplane_st->fence = NULL; } + + obj = state->fb->obj[0]; + if (obj->import_attach) + virtio_gpu_cleanup_imported_obj(obj); } static void virtio_gpu_cursor_plane_update(struct drm_plane *plane, From bb6761b39968271236e9d7187b7772fae8925891 Mon Sep 17 00:00:00 2001 From: Dongwon Kim Date: Tue, 28 Jun 2022 11:23:10 -0700 Subject: [PATCH 35/43] drm/virtio: freeze and restore hooks to support suspend and resume from PKT kernel, add function virtio_gpu_find_vqs virtio device needs to delete before VM suspend happens then reinitialize all virtqueues again upon resume Tracked-On: OAM-130450 Signed-off-by: Zhao, Shirley Signed-off-by: Dongwon Kim --- drivers/gpu/drm/virtio/virtgpu_drv.c | 53 +++++++++++++++++++++++++++- drivers/gpu/drm/virtio/virtgpu_drv.h | 1 + drivers/gpu/drm/virtio/virtgpu_kms.c | 23 ++++++++---- 3 files changed, 70 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c index 6a67c6297d58..576af6140fac 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.c +++ b/drivers/gpu/drm/virtio/virtgpu_drv.c @@ -152,6 +152,53 @@ static unsigned int features[] = { VIRTIO_GPU_F_RESOURCE_BLOB, VIRTIO_GPU_F_CONTEXT_INIT, }; + +#ifdef CONFIG_PM_SLEEP +static int virtgpu_freeze(struct virtio_device *vdev) +{ + struct drm_device *dev = vdev->priv; + struct virtio_gpu_device *vgdev = dev->dev_private; + int error; + + error = drm_mode_config_helper_suspend(dev); + if (error) { + DRM_ERROR("suspend error %d\n", error); + return error; + } + + flush_work(&vgdev->obj_free_work); + flush_work(&vgdev->ctrlq.dequeue_work); + flush_work(&vgdev->cursorq.dequeue_work); + flush_work(&vgdev->config_changed_work); + vdev->config->del_vqs(vdev); + + return 0; +} + +static int virtgpu_restore(struct virtio_device *vdev) +{ + struct drm_device *dev = vdev->priv; + struct virtio_gpu_device *vgdev = dev->dev_private; + int error; + + error = virtio_gpu_find_vqs(vgdev); + if (error) { + DRM_ERROR("failed to find virt queues\n"); + return error; + } + + virtio_device_ready(vdev); + + error = drm_mode_config_helper_resume(dev); + if (error) { + DRM_ERROR("resume error %d\n", error); + return error; + } + + return 0; +} +#endif + static struct virtio_driver virtio_gpu_driver = { .feature_table = features, .feature_table_size = ARRAY_SIZE(features), @@ -159,7 +206,11 @@ static struct virtio_driver virtio_gpu_driver = { .id_table = id_table, .probe = virtio_gpu_probe, .remove = virtio_gpu_remove, - .config_changed = virtio_gpu_config_changed + .config_changed = virtio_gpu_config_changed, +#ifdef CONFIG_PM_SLEEP + .freeze = virtgpu_freeze, + .restore = virtgpu_restore, +#endif }; module_virtio_driver(virtio_gpu_driver); diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index f42ca9d8ed10..c7ee3de79246 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -300,6 +300,7 @@ void virtio_gpu_deinit(struct drm_device *dev); void virtio_gpu_release(struct drm_device *dev); int virtio_gpu_driver_open(struct drm_device *dev, struct drm_file *file); void virtio_gpu_driver_postclose(struct drm_device *dev, struct drm_file *file); +int virtio_gpu_find_vqs(struct virtio_gpu_device *vgdev); /* virtgpu_gem.c */ int virtio_gpu_gem_object_open(struct drm_gem_object *obj, diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c index 7dfb2006c561..6c1af77ea083 100644 --- a/drivers/gpu/drm/virtio/virtgpu_kms.c +++ b/drivers/gpu/drm/virtio/virtgpu_kms.c @@ -114,15 +114,28 @@ static void virtio_gpu_get_capsets(struct virtio_gpu_device *vgdev, vgdev->num_capsets = num_capsets; } -int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev) +int virtio_gpu_find_vqs(struct virtio_gpu_device *vgdev) { struct virtqueue_info vqs_info[] = { { "control", virtio_gpu_ctrl_ack }, { "cursor", virtio_gpu_cursor_ack }, }; - struct virtio_gpu_device *vgdev; - /* this will expand later */ struct virtqueue *vqs[2]; + int ret; + + ret = virtio_find_vqs(vgdev->vdev, 2, vqs, vqs_info, NULL); + if (ret) + return ret; + + vgdev->ctrlq.vq = vqs[0]; + vgdev->cursorq.vq = vqs[1]; + + return 0; +} + +int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev) +{ + struct virtio_gpu_device *vgdev; u32 num_scanouts, num_capsets; int ret = 0; @@ -206,13 +219,11 @@ int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev) DRM_INFO("features: %ccontext_init\n", vgdev->has_context_init ? '+' : '-'); - ret = virtio_find_vqs(vgdev->vdev, 2, vqs, vqs_info, NULL); + ret = virtio_gpu_find_vqs(vgdev); if (ret) { DRM_ERROR("failed to find virt queues\n"); goto err_vqs; } - vgdev->ctrlq.vq = vqs[0]; - vgdev->cursorq.vq = vqs[1]; ret = virtio_gpu_alloc_vbufs(vgdev); if (ret) { DRM_ERROR("failed to alloc vbufs\n"); From 59530b663b148fab75dbf9080588d1ce67874782 Mon Sep 17 00:00:00 2001 From: Dongwon Kim Date: Thu, 18 Aug 2022 16:19:33 -0700 Subject: [PATCH 36/43] drm/virtio: save and restore virtio_gpu_objects from PKT kernel Host KVM/QEMU loses all graphic resourses submitted by guest OS upon resumption from sleep or hibernation. This will cause invalid resource errors when the guest OS makes any request to the host regarding those resources. One way to prevent this problem is to let virtio-gpu driver resubmit all existing resources upon resumption. A linked-list for keeping references of all created virtio_gpu_object and its params is added for this save and restore mechanism. Virtio-gpu objects are added to the list whenever a new object is created and sent to the host. All backed-up objects will then be re-sent to the host in .resume function with 'create resource' virtio gpu command. Tracked-On: OAM-130450 Signed-off-by: Zhao, Shirley Signed-off-by: Dongwon Kim --- drivers/gpu/drm/virtio/virtgpu_drv.c | 6 +++ drivers/gpu/drm/virtio/virtgpu_drv.h | 10 ++++ drivers/gpu/drm/virtio/virtgpu_kms.c | 1 + drivers/gpu/drm/virtio/virtgpu_object.c | 65 +++++++++++++++++++++++++ 4 files changed, 82 insertions(+) diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c index 576af6140fac..f4f62326a98f 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.c +++ b/drivers/gpu/drm/virtio/virtgpu_drv.c @@ -189,6 +189,12 @@ static int virtgpu_restore(struct virtio_device *vdev) virtio_device_ready(vdev); + error = virtio_gpu_object_restore_all(vgdev); + if (error) { + DRM_ERROR("Failed to recover objects\n"); + return error; + } + error = drm_mode_config_helper_resume(dev); if (error) { DRM_ERROR("resume error %d\n", error); diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index c7ee3de79246..b3acd7cced24 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -126,6 +126,12 @@ struct virtio_gpu_object_array { struct drm_gem_object *objs[] __counted_by(total); }; +struct virtio_gpu_object_restore { + struct virtio_gpu_object *bo; + struct virtio_gpu_object_params params; + struct list_head node; +}; + struct virtio_gpu_vbuffer; struct virtio_gpu_device; @@ -265,6 +271,7 @@ struct virtio_gpu_device { struct work_struct obj_free_work; spinlock_t obj_free_lock; struct list_head obj_free_list; + struct list_head obj_rec; struct virtio_gpu_drv_capset *capsets; uint32_t num_capsets; @@ -468,6 +475,9 @@ bool virtio_gpu_is_shmem(struct virtio_gpu_object *bo); int virtio_gpu_resource_id_get(struct virtio_gpu_device *vgdev, uint32_t *resid); + +int virtio_gpu_object_restore_all(struct virtio_gpu_device *vgdev); + /* virtgpu_prime.c */ int virtio_gpu_resource_assign_uuid(struct virtio_gpu_device *vgdev, struct virtio_gpu_object *bo); diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c index 6c1af77ea083..a6d0ee783bf0 100644 --- a/drivers/gpu/drm/virtio/virtgpu_kms.c +++ b/drivers/gpu/drm/virtio/virtgpu_kms.c @@ -162,6 +162,7 @@ int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev) vgdev->fence_drv.context = dma_fence_context_alloc(1); spin_lock_init(&vgdev->fence_drv.lock); INIT_LIST_HEAD(&vgdev->fence_drv.fences); + INIT_LIST_HEAD(&vgdev->obj_rec); INIT_LIST_HEAD(&vgdev->cap_cache); INIT_WORK(&vgdev->config_changed_work, virtio_gpu_config_changed_work_func); diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c index 5517cff8715c..8395a0212f9d 100644 --- a/drivers/gpu/drm/virtio/virtgpu_object.c +++ b/drivers/gpu/drm/virtio/virtgpu_object.c @@ -61,11 +61,44 @@ static void virtio_gpu_resource_id_put(struct virtio_gpu_device *vgdev, uint32_t } } +static void virtio_gpu_object_save_restore_list(struct virtio_gpu_device *vgdev, + struct virtio_gpu_object *bo, + struct virtio_gpu_object_params *params) +{ + struct virtio_gpu_object_restore *new; + + new = kvmalloc(sizeof(*new), GFP_KERNEL); + if (!new) { + DRM_ERROR("Fail to allocate virtio_gpu_object_restore"); + return; + } + + new->bo = bo; + memcpy(&new->params, params, sizeof(*params)); + + list_add_tail(&new->node, &vgdev->obj_rec); +} + +static void virtio_gpu_object_del_restore_list(struct virtio_gpu_device *vgdev, + struct virtio_gpu_object *bo) +{ + struct virtio_gpu_object_restore *curr, *tmp; + + list_for_each_entry_safe(curr, tmp, &vgdev->obj_rec, node) { + if (bo == curr->bo) { + list_del(&curr->node); + kvfree(curr); + break; + } + } +} + void virtio_gpu_cleanup_object(struct virtio_gpu_object *bo) { struct virtio_gpu_device *vgdev = bo->base.base.dev->dev_private; virtio_gpu_resource_id_put(vgdev, bo->hw_res_handle); + virtio_gpu_object_del_restore_list(vgdev, bo); if (virtio_gpu_is_shmem(bo)) { drm_gem_shmem_free(&bo->base); } else if (virtio_gpu_is_vram(bo)) { @@ -257,8 +290,11 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev, objs, fence); virtio_gpu_object_attach(vgdev, bo, ents, nents); } + /* add submitted object to restore list */ + virtio_gpu_object_save_restore_list(vgdev, bo, params); *bo_ptr = bo; + return 0; err_put_objs: @@ -271,3 +307,32 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev, drm_gem_shmem_free(shmem_obj); return ret; } + +int virtio_gpu_object_restore_all(struct virtio_gpu_device *vgdev) +{ + struct virtio_gpu_object_restore *curr, *tmp; + struct virtio_gpu_mem_entry *ents; + unsigned int nents; + int ret; + + list_for_each_entry_safe(curr, tmp, &vgdev->obj_rec, node) { + ret = virtio_gpu_object_shmem_init(vgdev, curr->bo, &ents, &nents); + if (ret) + break; + + if (curr->params.blob) { + virtio_gpu_cmd_resource_create_blob(vgdev, curr->bo, &curr->params, + ents, nents); + } else if (curr->params.virgl) { + virtio_gpu_cmd_resource_create_3d(vgdev, curr->bo, &curr->params, + NULL, NULL); + virtio_gpu_object_attach(vgdev, curr->bo, ents, nents); + } else { + virtio_gpu_cmd_create_resource(vgdev, curr->bo, &curr->params, + NULL, NULL); + virtio_gpu_object_attach(vgdev, curr->bo, ents, nents); + } + } + + return ret; +} From 8c142a1be1a2d73e26d53720de3239c6d8b449b9 Mon Sep 17 00:00:00 2001 From: Yifan Liu Date: Sat, 22 Jul 2023 03:13:52 +0000 Subject: [PATCH 37/43] drivers: virtgpu: Add virtio-gpu tiling format support shirley update Add tiling support featured with feature bit VIRTIO_GPU_F_MODIFIER, so buffer created by virtio gpu with intel_x_tiling and intel_y_tiling format could be rendered directly by i915. Tracked-On: OAM-130450 Change-Id: I8c6447736c4edbc8947ab0ea7b72d48d9e85a7c4 Signed-off-by: hangliu1 Signed-off-by: Yifan Liu Signed-off-by: Zhao, Shirley --- drivers/gpu/drm/virtio/virtgpu_display.c | 3 +- drivers/gpu/drm/virtio/virtgpu_drv.c | 1 + drivers/gpu/drm/virtio/virtgpu_drv.h | 5 ++- drivers/gpu/drm/virtio/virtgpu_kms.c | 3 ++ drivers/gpu/drm/virtio/virtgpu_plane.c | 41 +++++++++++++++++++++--- drivers/gpu/drm/virtio/virtgpu_vq.c | 15 +++++++++ include/uapi/linux/virtio_gpu.h | 12 +++++++ 7 files changed, 74 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c index ba9505098bf3..3dae4e95d4ed 100644 --- a/drivers/gpu/drm/virtio/virtgpu_display.c +++ b/drivers/gpu/drm/virtio/virtgpu_display.c @@ -345,7 +345,8 @@ int virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev) vgdev->ddev->mode_config.max_width = XRES_MAX; vgdev->ddev->mode_config.max_height = YRES_MAX; - vgdev->ddev->mode_config.fb_modifiers_not_supported = true; + if (!vgdev->has_modifier) + vgdev->ddev->mode_config.fb_modifiers_not_supported = true; for (i = 0 ; i < vgdev->num_scanouts; ++i) vgdev_output_init(vgdev, i); diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c index f4f62326a98f..7fc987a0e3ed 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.c +++ b/drivers/gpu/drm/virtio/virtgpu_drv.c @@ -151,6 +151,7 @@ static unsigned int features[] = { VIRTIO_GPU_F_RESOURCE_UUID, VIRTIO_GPU_F_RESOURCE_BLOB, VIRTIO_GPU_F_CONTEXT_INIT, + VIRTIO_GPU_F_MODIFIER, }; #ifdef CONFIG_PM_SLEEP diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index b3acd7cced24..2d43006c3cb8 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -258,6 +258,7 @@ struct virtio_gpu_device { bool has_virgl_3d; bool has_edid; + bool has_modifier; bool has_indirect; bool has_resource_assign_uuid; bool has_resource_blob; @@ -441,7 +442,9 @@ virtio_gpu_cmd_set_scanout_blob(struct virtio_gpu_device *vgdev, struct drm_framebuffer *fb, uint32_t width, uint32_t height, uint32_t x, uint32_t y); - +void virtio_gpu_cmd_set_modifier(struct virtio_gpu_device *vgdev, + uint32_t scanout_id, + struct drm_framebuffer *fb); /* virtgpu_display.c */ int virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev); void virtio_gpu_modeset_fini(struct virtio_gpu_device *vgdev); diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c index a6d0ee783bf0..ad53cd72faf9 100644 --- a/drivers/gpu/drm/virtio/virtgpu_kms.c +++ b/drivers/gpu/drm/virtio/virtgpu_kms.c @@ -187,6 +187,9 @@ int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev) } if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_RESOURCE_BLOB)) { vgdev->has_resource_blob = true; + if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_MODIFIER)) { + vgdev->has_modifier = true; + } } if (virtio_get_shm_region(vgdev->vdev, &vgdev->host_visible_region, VIRTIO_GPU_SHM_ID_HOST_VISIBLE)) { diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c index 4a11f7db6bf3..d75853dd348d 100644 --- a/drivers/gpu/drm/virtio/virtgpu_plane.c +++ b/drivers/gpu/drm/virtio/virtgpu_plane.c @@ -131,7 +131,7 @@ drm_plane_state *virtio_gpu_plane_duplicate_state(struct drm_plane *plane) return &new->base; } -static const struct drm_plane_funcs virtio_gpu_plane_funcs = { +static struct drm_plane_funcs virtio_gpu_plane_funcs = { .update_plane = drm_atomic_helper_update_plane, .disable_plane = drm_atomic_helper_disable_plane, .reset = drm_atomic_helper_plane_reset, @@ -289,6 +289,9 @@ static void virtio_gpu_primary_plane_update(struct drm_plane *plane, plane->state->src_h >> 16, plane->state->src_x >> 16, plane->state->src_y >> 16); + if (vgdev->has_modifier) + virtio_gpu_cmd_set_modifier(vgdev, output->index, plane->state->fb); + } else { virtio_gpu_cmd_set_scanout(vgdev, output->index, bo->hw_res_handle, @@ -506,6 +509,27 @@ static const struct drm_plane_helper_funcs virtio_gpu_cursor_helper_funcs = { .atomic_update = virtio_gpu_cursor_plane_update, }; +static const uint64_t virtio_gpu_format_modifiers[] = { + DRM_FORMAT_MOD_LINEAR, + I915_FORMAT_MOD_X_TILED, + I915_FORMAT_MOD_Y_TILED, + DRM_FORMAT_MOD_INVALID +}; + + +static bool virtio_gpu_plane_format_mod_supported(struct drm_plane *_plane, + u32 format, u64 modifier) +{ + switch (modifier) { + case DRM_FORMAT_MOD_LINEAR: + case I915_FORMAT_MOD_X_TILED: + case I915_FORMAT_MOD_Y_TILED: + return true; + default: + return false; + } +} + struct drm_plane *virtio_gpu_plane_init(struct virtio_gpu_device *vgdev, enum drm_plane_type type, int index) @@ -526,9 +550,18 @@ struct drm_plane *virtio_gpu_plane_init(struct virtio_gpu_device *vgdev, funcs = &virtio_gpu_primary_helper_funcs; } - plane = drmm_universal_plane_alloc(dev, struct drm_plane, dev, - 1 << index, &virtio_gpu_plane_funcs, - formats, nformats, NULL, type, NULL); + if (vgdev->has_modifier) { + const uint64_t *modifiers = virtio_gpu_format_modifiers; + virtio_gpu_plane_funcs.format_mod_supported = virtio_gpu_plane_format_mod_supported; + plane = drmm_universal_plane_alloc(dev, struct drm_plane, dev, + 1 << index, &virtio_gpu_plane_funcs, + formats, nformats, modifiers, type, NULL); + } else { + plane = drmm_universal_plane_alloc(dev, struct drm_plane, dev, + 1 << index, &virtio_gpu_plane_funcs, + formats, nformats, NULL, type, NULL); + } + if (IS_ERR(plane)) return plane; diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c index ad91624df42d..0b0528bfe320 100644 --- a/drivers/gpu/drm/virtio/virtgpu_vq.c +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c @@ -1337,3 +1337,18 @@ void virtio_gpu_cmd_set_scanout_blob(struct virtio_gpu_device *vgdev, virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); } + +void virtio_gpu_cmd_set_modifier(struct virtio_gpu_device *vgdev, + uint32_t scanout_id, + struct drm_framebuffer *fb) +{ + struct virtio_gpu_set_modifier *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)); + cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_SET_MODIFIER); + cmd_p->modifier = cpu_to_le64(fb->modifier); + cmd_p->scanout_id = cpu_to_le32(scanout_id); + virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); +} diff --git a/include/uapi/linux/virtio_gpu.h b/include/uapi/linux/virtio_gpu.h index bf2c9cabd207..d5c84fb4b68b 100644 --- a/include/uapi/linux/virtio_gpu.h +++ b/include/uapi/linux/virtio_gpu.h @@ -64,6 +64,10 @@ * context_init and multiple timelines */ #define VIRTIO_GPU_F_CONTEXT_INIT 4 +/* + *VIRTIO_GPU_CMD_SET_MODIFIER + */ +#define VIRTIO_GPU_F_MODIFIER 5 enum virtio_gpu_ctrl_type { VIRTIO_GPU_UNDEFINED = 0, @@ -83,6 +87,7 @@ enum virtio_gpu_ctrl_type { VIRTIO_GPU_CMD_RESOURCE_ASSIGN_UUID, VIRTIO_GPU_CMD_RESOURCE_CREATE_BLOB, VIRTIO_GPU_CMD_SET_SCANOUT_BLOB, + VIRTIO_GPU_CMD_SET_MODIFIER, /* 3d commands */ VIRTIO_GPU_CMD_CTX_CREATE = 0x0200, @@ -428,6 +433,13 @@ struct virtio_gpu_set_scanout_blob { __le32 strides[4]; __le32 offsets[4]; }; +/* VIRTIO_GPU_CMD_SET_MODIFIER */ +struct virtio_gpu_set_modifier { + struct virtio_gpu_ctrl_hdr hdr; + __le64 modifier; + __le32 scanout_id; + __le32 padding; +}; /* VIRTIO_GPU_CMD_RESOURCE_MAP_BLOB */ struct virtio_gpu_resource_map_blob { From f2f64d1483a8ff43a790559b374e621fa0f07860 Mon Sep 17 00:00:00 2001 From: Hang Liu Date: Tue, 11 Jul 2023 11:16:00 +0800 Subject: [PATCH 38/43] drm/virtio: add scaling support The gem buffer created by i915 in guest vm may be smaller than the resolution determined by the mode setting operation. In that case, a new framebuffer may be created by virtio gpu driver, and i915 rendering must be utilized to do the composition. To save the effort, pass the dst crtc info to the backend which will scale the gem buffer to the crtc. Tests done: - Android Boot / reboot / recovery - Android Boot using ACRN / fastboot - Wifi / Wifi Hotspot - BT / File Transfer - Audio / Video Playback - ADB - Web Browsing - Settings - Type C check - Factory reset Tracked-On: OAM-130450 Signed-off-by: Hang Liu Signed-off-by: Zhao, Shirley --- drivers/gpu/drm/virtio/virtgpu_drv.c | 1 + drivers/gpu/drm/virtio/virtgpu_drv.h | 6 ++++++ drivers/gpu/drm/virtio/virtgpu_kms.c | 3 +++ drivers/gpu/drm/virtio/virtgpu_plane.c | 23 +++++++++++++++++++++-- drivers/gpu/drm/virtio/virtgpu_vq.c | 20 ++++++++++++++++++++ include/uapi/linux/virtio_gpu.h | 14 ++++++++++++++ 6 files changed, 65 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c index 7fc987a0e3ed..d076bb16a7c3 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.c +++ b/drivers/gpu/drm/virtio/virtgpu_drv.c @@ -152,6 +152,7 @@ static unsigned int features[] = { VIRTIO_GPU_F_RESOURCE_BLOB, VIRTIO_GPU_F_CONTEXT_INIT, VIRTIO_GPU_F_MODIFIER, + VIRTIO_GPU_F_SCALING, }; #ifdef CONFIG_PM_SLEEP diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index 2d43006c3cb8..61b9506b5579 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -259,6 +259,7 @@ struct virtio_gpu_device { bool has_virgl_3d; bool has_edid; bool has_modifier; + bool has_scaling; bool has_indirect; bool has_resource_assign_uuid; bool has_resource_blob; @@ -445,6 +446,11 @@ virtio_gpu_cmd_set_scanout_blob(struct virtio_gpu_device *vgdev, void virtio_gpu_cmd_set_modifier(struct virtio_gpu_device *vgdev, uint32_t scanout_id, struct drm_framebuffer *fb); + +void virtio_gpu_cmd_set_scaling(struct virtio_gpu_device *vgdev, + uint32_t scanout_id, + struct drm_rect *rect_dst); + /* virtgpu_display.c */ int virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev); void virtio_gpu_modeset_fini(struct virtio_gpu_device *vgdev); diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c index ad53cd72faf9..251bd3e1ec22 100644 --- a/drivers/gpu/drm/virtio/virtgpu_kms.c +++ b/drivers/gpu/drm/virtio/virtgpu_kms.c @@ -185,6 +185,9 @@ int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev) if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_RESOURCE_UUID)) { vgdev->has_resource_assign_uuid = true; } + if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_SCALING)) { + vgdev->has_scaling = true; + } if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_RESOURCE_BLOB)) { vgdev->has_resource_blob = true; if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_MODIFIER)) { diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c index d75853dd348d..e57e7a307ebd 100644 --- a/drivers/gpu/drm/virtio/virtgpu_plane.c +++ b/drivers/gpu/drm/virtio/virtgpu_plane.c @@ -146,9 +146,13 @@ static int virtio_gpu_plane_atomic_check(struct drm_plane *plane, plane); struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane); + struct drm_device *dev = plane->dev; + struct virtio_gpu_device *vgdev = dev->dev_private; bool is_cursor = plane->type == DRM_PLANE_TYPE_CURSOR; struct drm_crtc_state *crtc_state; int ret; + int min_scale = DRM_PLANE_NO_SCALING; + int max_scale = DRM_PLANE_NO_SCALING; if (!new_plane_state->fb || WARN_ON(!new_plane_state->crtc)) return 0; @@ -166,9 +170,13 @@ static int virtio_gpu_plane_atomic_check(struct drm_plane *plane, if (IS_ERR(crtc_state)) return PTR_ERR(crtc_state); + if(vgdev->has_scaling && (new_plane_state->fb->format->format != DRM_FORMAT_C8)) { + min_scale = 1; + max_scale = 0x30000-1; + } ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state, - DRM_PLANE_NO_SCALING, - DRM_PLANE_NO_SCALING, + min_scale, + max_scale, is_cursor, true); return ret; } @@ -302,6 +310,17 @@ static void virtio_gpu_primary_plane_update(struct drm_plane *plane, } } + if(vgdev->has_scaling) { + struct drm_rect rect_dst; + + rect_dst.x1 = plane->state->crtc_x; + rect_dst.y1 = plane->state->crtc_y; + rect_dst.x2 = plane->state->crtc_w; + rect_dst.y2 = plane->state->crtc_h; + + virtio_gpu_cmd_set_scaling(vgdev, output->index, &rect_dst); + } + virtio_gpu_resource_flush(plane, rect.x1, rect.y1, diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c index 0b0528bfe320..594b365b44af 100644 --- a/drivers/gpu/drm/virtio/virtgpu_vq.c +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c @@ -1352,3 +1352,23 @@ void virtio_gpu_cmd_set_modifier(struct virtio_gpu_device *vgdev, cmd_p->scanout_id = cpu_to_le32(scanout_id); virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); } + +void virtio_gpu_cmd_set_scaling(struct virtio_gpu_device *vgdev, + uint32_t scanout_id, + struct drm_rect *rect_dst) +{ + struct virtio_gpu_set_scaling *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)); + cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_SET_SCALING); + cmd_p->scanout_id = cpu_to_le32(scanout_id); + + cmd_p->dst.width = cpu_to_le32(rect_dst->x2); + cmd_p->dst.height = cpu_to_le32(rect_dst->y2); + cmd_p->dst.x = cpu_to_le32(rect_dst->x1); + cmd_p->dst.y = cpu_to_le32(rect_dst->y1); + + virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); +} diff --git a/include/uapi/linux/virtio_gpu.h b/include/uapi/linux/virtio_gpu.h index d5c84fb4b68b..87705a96c32d 100644 --- a/include/uapi/linux/virtio_gpu.h +++ b/include/uapi/linux/virtio_gpu.h @@ -68,6 +68,11 @@ *VIRTIO_GPU_CMD_SET_MODIFIER */ #define VIRTIO_GPU_F_MODIFIER 5 +/* +*VIRTIO_GPU_CMD_SET_SCALING +*/ +#define VIRTIO_GPU_F_SCALING 6 + enum virtio_gpu_ctrl_type { VIRTIO_GPU_UNDEFINED = 0, @@ -88,6 +93,7 @@ enum virtio_gpu_ctrl_type { VIRTIO_GPU_CMD_RESOURCE_CREATE_BLOB, VIRTIO_GPU_CMD_SET_SCANOUT_BLOB, VIRTIO_GPU_CMD_SET_MODIFIER, + VIRTIO_GPU_CMD_SET_SCALING, /* 3d commands */ VIRTIO_GPU_CMD_CTX_CREATE = 0x0200, @@ -208,6 +214,14 @@ struct virtio_gpu_resource_flush { __le32 padding; }; +/* VIRTIO_GPU_CMD_SET_SCALING */ +struct virtio_gpu_set_scaling { + struct virtio_gpu_ctrl_hdr hdr; + struct virtio_gpu_rect dst; + __le32 scanout_id; + __le32 padding; +}; + /* VIRTIO_GPU_CMD_TRANSFER_TO_HOST_2D: simple transfer to_host */ struct virtio_gpu_transfer_to_host_2d { struct virtio_gpu_ctrl_hdr hdr; From 48474514528452ea57e2fcaa187b8c8d837481ed Mon Sep 17 00:00:00 2001 From: Hang Liu Date: Sat, 1 Jul 2023 11:09:56 +0800 Subject: [PATCH 39/43] drm/virtio: suppport configurable queue number virtio backend set the vblank queue number in the config space, since vblank interrupt reuse the virtio queue interrupt. Tests done: - Android Boot / reboot / recovery - Android Boot using ACRN / fastboot - Wifi / Wifi Hotspot - BT / File Transfer - Audio / Video Playback - ADB - Web Browsing - Settings - Type C check - Factory reset Tracked-On: OAM-130450 Signed-off-by: Hang Liu Signed-off-by: Zhao, Shirley --- drivers/gpu/drm/virtio/virtgpu_drv.c | 1 + drivers/gpu/drm/virtio/virtgpu_drv.h | 10 +++- drivers/gpu/drm/virtio/virtgpu_kms.c | 78 ++++++++++++++++++++++------ include/uapi/linux/virtio_gpu.h | 2 + 4 files changed, 75 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c index d076bb16a7c3..4a90ed289873 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.c +++ b/drivers/gpu/drm/virtio/virtgpu_drv.c @@ -153,6 +153,7 @@ static unsigned int features[] = { VIRTIO_GPU_F_CONTEXT_INIT, VIRTIO_GPU_F_MODIFIER, VIRTIO_GPU_F_SCALING, + VIRTIO_GPU_F_VBLANK, }; #ifdef CONFIG_PM_SLEEP diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index 61b9506b5579..ba9ffb6622aa 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -231,6 +231,11 @@ struct virtio_gpu_drv_cap_cache { atomic_t is_valid; }; +struct virtio_gpu_vblank { + struct virtio_gpu_queue vblank; + uint32_t buf[4]; +}; + struct virtio_gpu_device { struct drm_device *ddev; @@ -238,9 +243,10 @@ struct virtio_gpu_device { struct virtio_gpu_output outputs[VIRTIO_GPU_MAX_SCANOUTS]; uint32_t num_scanouts; - + uint32_t num_vblankq; struct virtio_gpu_queue ctrlq; struct virtio_gpu_queue cursorq; + struct kmem_cache *vbufs; atomic_t pending_commands; @@ -260,6 +266,7 @@ struct virtio_gpu_device { bool has_edid; bool has_modifier; bool has_scaling; + bool has_vblank; bool has_indirect; bool has_resource_assign_uuid; bool has_resource_blob; @@ -284,6 +291,7 @@ struct virtio_gpu_device { spinlock_t resource_export_lock; /* protects map state and host_visible_mm */ spinlock_t host_visible_lock; + struct virtio_gpu_vblank vblank[]; }; struct virtio_gpu_fpriv { diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c index 251bd3e1ec22..a9f3f14721f0 100644 --- a/drivers/gpu/drm/virtio/virtgpu_kms.c +++ b/drivers/gpu/drm/virtio/virtgpu_kms.c @@ -116,21 +116,58 @@ static void virtio_gpu_get_capsets(struct virtio_gpu_device *vgdev, int virtio_gpu_find_vqs(struct virtio_gpu_device *vgdev) { - struct virtqueue_info vqs_info[] = { - { "control", virtio_gpu_ctrl_ack }, - { "cursor", virtio_gpu_cursor_ack }, - }; - struct virtqueue *vqs[2]; - int ret; - - ret = virtio_find_vqs(vgdev->vdev, 2, vqs, vqs_info, NULL); - if (ret) - return ret; - - vgdev->ctrlq.vq = vqs[0]; - vgdev->cursorq.vq = vqs[1]; - - return 0; + struct virtqueue_info *vqs_info; + vq_callback_t **callbacks; + struct virtqueue **vqs; + int i, total_vqs, err; + const char **names; + int ret = 0; + + total_vqs = vgdev->num_vblankq + 2; + vqs = kcalloc(total_vqs, sizeof(*vqs), GFP_KERNEL); + callbacks = kmalloc_array(total_vqs, sizeof(vq_callback_t *), + GFP_KERNEL); + names = kmalloc_array(total_vqs, sizeof(char *), GFP_KERNEL); + vqs_info = kmalloc_array(total_vqs, sizeof(struct virtqueue_info), + GFP_KERNEL); + + if (!callbacks || !vqs || !names || !vqs_info) { + err = -ENOMEM; + goto out; + } + + callbacks[0] = virtio_gpu_ctrl_ack; + callbacks[1] = virtio_gpu_cursor_ack; + names[0] = "control"; + names[1] = "cursor"; + for (i = 2; i < total_vqs; i++) { + callbacks[i] = virtio_gpu_vblank_ack; + names[i] = "vblank"; + } + + for (i = 0; i < total_vqs; i++) { + vqs_info[i].callback = callbacks[i]; + vqs_info[i].name = names[i]; + } + + ret = virtio_find_vqs(vgdev->vdev, total_vqs, vqs, vqs_info, NULL); + if (ret) + goto out; + + vgdev->ctrlq.vq = vqs[0]; + vgdev->cursorq.vq = vqs[1]; + + for (i = 2; i < total_vqs; i++) + vgdev->vblank[i-2].vblank.vq = vqs[i]; + + ret = 0; +out: + kfree(names); + + kfree(callbacks); + kfree(vqs); + kfree(vqs_info); + return ret; } int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev) @@ -188,6 +225,9 @@ int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev) if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_SCALING)) { vgdev->has_scaling = true; } + if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_VBLANK)) { + vgdev->has_vblank = true; + } if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_RESOURCE_BLOB)) { vgdev->has_resource_blob = true; if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_MODIFIER)) { @@ -226,6 +266,14 @@ int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev) DRM_INFO("features: %ccontext_init\n", vgdev->has_context_init ? '+' : '-'); + vgdev->num_vblankq = 0; + if(vgdev->has_vblank) + virtio_cread_le(vgdev->vdev, struct virtio_gpu_config, + num_pipe, &vgdev->num_vblankq); + + for(i=0; inum_vblankq; i++) + spin_lock_init(&vgdev->vblank[i].vblank.qlock); + ret = virtio_gpu_find_vqs(vgdev); if (ret) { DRM_ERROR("failed to find virt queues\n"); diff --git a/include/uapi/linux/virtio_gpu.h b/include/uapi/linux/virtio_gpu.h index 87705a96c32d..c182802ff00c 100644 --- a/include/uapi/linux/virtio_gpu.h +++ b/include/uapi/linux/virtio_gpu.h @@ -73,6 +73,7 @@ */ #define VIRTIO_GPU_F_SCALING 6 +#define VIRTIO_GPU_F_VBLANK 7 enum virtio_gpu_ctrl_type { VIRTIO_GPU_UNDEFINED = 0, @@ -383,6 +384,7 @@ struct virtio_gpu_config { __le32 events_clear; __le32 num_scanouts; __le32 num_capsets; + __le32 num_pipe; }; /* simple formats for fbcon/X use */ From 86f5db5fde9cf70198a3f41c8728b4c778e0b7a9 Mon Sep 17 00:00:00 2001 From: Hang Liu Date: Sat, 1 Jul 2023 12:30:18 +0800 Subject: [PATCH 40/43] drm/virtio: enable vblank for crtc virtio gpu backend inject virtual vblank interrupt for each virtio gpu crtc. The purpose for doing this is to avoid the potential image tearing caused by the concurrent accessing the same framebuffer by rendering engine in guest and display engine in host. Tests done: - Android Boot / reboot / recovery - Android Boot using ACRN / fastboot - Wifi / Wifi Hotspot - BT / File Transfer - Audio / Video Playback - ADB - Web Browsing - Settings - Type C check - Factory reset Tracked-On: OAM-130450 Signed-off-by: Hang Liu Signed-off-by: Zhao, Shirley --- drivers/gpu/drm/virtio/virtgpu_display.c | 36 +++++++++++ drivers/gpu/drm/virtio/virtgpu_drv.c | 11 ++++ drivers/gpu/drm/virtio/virtgpu_drv.h | 3 + drivers/gpu/drm/virtio/virtgpu_kms.c | 8 +++ drivers/gpu/drm/virtio/virtgpu_vq.c | 79 ++++++++++++++++++++++++ 5 files changed, 137 insertions(+) diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c index 3dae4e95d4ed..b4fd3ef0c8ad 100644 --- a/drivers/gpu/drm/virtio/virtgpu_display.c +++ b/drivers/gpu/drm/virtio/virtgpu_display.c @@ -32,6 +32,7 @@ #include #include #include +#include #include "virtgpu_drv.h" @@ -47,6 +48,28 @@ #define drm_connector_to_virtio_gpu_output(x) \ container_of(x, struct virtio_gpu_output, conn) +static int virtio_irq_enable_vblank(struct drm_crtc *crtc) +{ + + struct drm_device *dev = crtc->dev; + struct virtio_gpu_device *vgdev = dev->dev_private; + struct virtio_gpu_output *output = drm_crtc_to_virtio_gpu_output(crtc); + + virtio_gpu_vblank_poll_arm(vgdev->vblank[output->index].vblank.vq); + virtqueue_enable_cb(vgdev->vblank[output->index].vblank.vq); + return 0; +} + +static void virtio_irq_disable_vblank(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct virtio_gpu_device *vgdev; + vgdev = dev->dev_private; + struct virtio_gpu_output *output = drm_crtc_to_virtio_gpu_output(crtc); + + virtqueue_disable_cb(vgdev->vblank[output->index].vblank.vq); +} + static const struct drm_crtc_funcs virtio_gpu_crtc_funcs = { .set_config = drm_atomic_helper_set_config, .destroy = drm_crtc_cleanup, @@ -55,6 +78,8 @@ static const struct drm_crtc_funcs virtio_gpu_crtc_funcs = { .reset = drm_atomic_helper_crtc_reset, .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, + .enable_vblank = virtio_irq_enable_vblank, + .disable_vblank = virtio_irq_disable_vblank, }; static const struct drm_framebuffer_funcs virtio_gpu_fb_funcs = { @@ -123,6 +148,17 @@ static void virtio_gpu_crtc_atomic_flush(struct drm_crtc *crtc, struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc); struct virtio_gpu_output *output = drm_crtc_to_virtio_gpu_output(crtc); + struct drm_device *drm = crtc->dev; + + spin_lock_irq(&drm->event_lock); + + + if (crtc->state->event) { + drm_crtc_send_vblank_event(crtc, crtc->state->event); + crtc->state->event = NULL; + } + + spin_unlock_irq(&drm->event_lock); /* * virtio-gpu can't do modeset and plane update operations diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c index 4a90ed289873..47202aa417da 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.c +++ b/drivers/gpu/drm/virtio/virtgpu_drv.c @@ -38,6 +38,7 @@ #include #include #include +#include #include "virtgpu_drv.h" @@ -71,6 +72,7 @@ static int virtio_gpu_probe(struct virtio_device *vdev) { struct drm_device *dev; int ret; + struct virtio_gpu_device *pgpudev; if (drm_firmware_drivers_only() && virtio_gpu_modeset == -1) return -EINVAL; @@ -100,6 +102,15 @@ static int virtio_gpu_probe(struct virtio_device *vdev) if (ret) goto err_free; + pgpudev = dev->dev_private; + if(pgpudev->num_vblankq) { + ret = drm_vblank_init(dev, pgpudev->num_vblankq); + if (ret) { + DRM_ERROR("could not init vblank\n"); + goto err_deinit; + } + } + ret = drm_dev_register(dev, 0); if (ret) goto err_deinit; diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index ba9ffb6622aa..907b1387e71a 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -424,9 +424,12 @@ virtio_gpu_cmd_resource_create_3d(struct virtio_gpu_device *vgdev, struct virtio_gpu_fence *fence); void virtio_gpu_ctrl_ack(struct virtqueue *vq); void virtio_gpu_cursor_ack(struct virtqueue *vq); +void virtio_gpu_vblank_ack(struct virtqueue *vq); +void virtio_gpu_vblank_poll_arm(struct virtqueue *vq); void virtio_gpu_dequeue_ctrl_func(struct work_struct *work); void virtio_gpu_dequeue_cursor_func(struct work_struct *work); void virtio_gpu_notify(struct virtio_gpu_device *vgdev); +void virtio_gpu_vblankq_notify(struct virtio_gpu_device *vgdev); int virtio_gpu_cmd_resource_assign_uuid(struct virtio_gpu_device *vgdev, diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c index a9f3f14721f0..b75e50bbbf5c 100644 --- a/drivers/gpu/drm/virtio/virtgpu_kms.c +++ b/drivers/gpu/drm/virtio/virtgpu_kms.c @@ -175,6 +175,7 @@ int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev) struct virtio_gpu_device *vgdev; u32 num_scanouts, num_capsets; int ret = 0; + int i; if (!virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) return -ENODEV; @@ -314,6 +315,13 @@ int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev) if (num_capsets) virtio_gpu_get_capsets(vgdev, num_capsets); + + virtio_gpu_vblankq_notify(vgdev); + + for(i=0; i < vgdev->num_vblankq; i++) + virtqueue_disable_cb(vgdev->vblank[i].vblank.vq); + + if (vgdev->num_scanouts) { if (vgdev->has_edid) virtio_gpu_cmd_get_edids(vgdev); diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c index 594b365b44af..bc96d9ad2a24 100644 --- a/drivers/gpu/drm/virtio/virtgpu_vq.c +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c @@ -31,8 +31,10 @@ #include #include +#include #include +#include #include "virtgpu_drv.h" #include "virtgpu_trace.h" @@ -61,6 +63,60 @@ void virtio_gpu_ctrl_ack(struct virtqueue *vq) schedule_work(&vgdev->ctrlq.dequeue_work); } +static void virtgpu_irqqueue_buf(struct virtqueue *vq, + uint32_t *evtbuf) +{ + struct scatterlist sg[1]; + sg_init_one(sg, evtbuf, sizeof(*evtbuf)); + virtqueue_add_inbuf(vq, sg, 1, evtbuf, GFP_ATOMIC); +} + +void virtio_gpu_vblank_poll_arm(struct virtqueue *vq) +{ + struct drm_device *dev = vq->vdev->priv; + struct virtio_gpu_device *vgdev = dev->dev_private; + unsigned long irqflags; + unsigned int len; + unsigned int *ret_value; + int target = 0; + + while((target < vgdev->num_vblankq) && (vgdev->vblank[target].vblank.vq != vq)) { + target++; + } + + spin_lock_irqsave(&vgdev->vblank[target].vblank.qlock, irqflags); + if((ret_value = virtqueue_get_buf(vq, &len)) != NULL) { + + virtgpu_irqqueue_buf(vq, ret_value); + } + virtqueue_kick(vq); + spin_unlock_irqrestore(&vgdev->vblank[target].vblank.qlock, irqflags); +} + +void virtio_gpu_vblank_ack(struct virtqueue *vq) +{ + struct drm_device *dev = vq->vdev->priv; + struct virtio_gpu_device *vgdev = dev->dev_private; + unsigned long irqflags; + unsigned int len; + unsigned int *ret_value; + int target = 0; + + while((target < vgdev->num_vblankq) && (vgdev->vblank[target].vblank.vq != vq)) { + target++; + } + + spin_lock_irqsave(&vgdev->vblank[target].vblank.qlock, irqflags); + if((ret_value = virtqueue_get_buf(vgdev->vblank[target].vblank.vq, &len)) != NULL) { + + virtgpu_irqqueue_buf(vgdev->vblank[target].vblank.vq, ret_value); + } + + spin_unlock_irqrestore(&vgdev->vblank[target].vblank.qlock, irqflags); + drm_handle_vblank(dev, target); + +} + void virtio_gpu_cursor_ack(struct virtqueue *vq) { struct drm_device *dev = vq->vdev->priv; @@ -422,6 +478,29 @@ static int virtio_gpu_queue_fenced_ctrl_buffer(struct virtio_gpu_device *vgdev, return ret; } + + +void virtio_gpu_vblankq_notify(struct virtio_gpu_device *vgdev) +{ + int size,i; + + for(i=0; i < vgdev->num_vblankq; i++) { + spin_lock(&vgdev->vblank[i].vblank.qlock); + + size = virtqueue_get_vring_size(vgdev->vblank[i].vblank.vq); + if (size > ARRAY_SIZE(vgdev->vblank[i].buf)) + size = ARRAY_SIZE(vgdev->vblank[i].buf); + + virtgpu_irqqueue_buf(vgdev->vblank[i].vblank.vq, &vgdev->vblank[i].buf[0]); + + virtqueue_kick(vgdev->vblank[i].vblank.vq); + + spin_unlock(&vgdev->vblank[i].vblank.qlock); + + } + +} + void virtio_gpu_notify(struct virtio_gpu_device *vgdev) { bool notify; From 66eaa17aa6a1bb018d84a34318393614c909d323 Mon Sep 17 00:00:00 2001 From: "Xue, Bosheng" Date: Wed, 10 Apr 2024 20:53:01 +0800 Subject: [PATCH 41/43] drm/virtio: improve virtio gpu vblank operation set vblank on/off during atomic enable/disable, add vblank_get to protect vblank event operation, process vblank during virtio gpu restore. Tracked-On: OAM-130450 Signed-off-by: Xue, Bosheng Signed-off-by: Zhao, Shirley --- drivers/gpu/drm/virtio/virtgpu_display.c | 29 ++++++++++++++++-------- drivers/gpu/drm/virtio/virtgpu_drv.c | 12 +++++++++- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c index b4fd3ef0c8ad..e498b60af06d 100644 --- a/drivers/gpu/drm/virtio/virtgpu_display.c +++ b/drivers/gpu/drm/virtio/virtgpu_display.c @@ -123,6 +123,11 @@ static void virtio_gpu_crtc_mode_set_nofb(struct drm_crtc *crtc) static void virtio_gpu_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *state) { + struct drm_device *dev = crtc->dev; + struct virtio_gpu_device *vgdev = dev->dev_private; + if(vgdev->has_vblank) { + drm_crtc_vblank_on(crtc); + } } static void virtio_gpu_crtc_atomic_disable(struct drm_crtc *crtc, @@ -132,6 +137,9 @@ static void virtio_gpu_crtc_atomic_disable(struct drm_crtc *crtc, struct virtio_gpu_device *vgdev = dev->dev_private; struct virtio_gpu_output *output = drm_crtc_to_virtio_gpu_output(crtc); + if(vgdev->has_vblank) { + drm_crtc_vblank_off(crtc); + } virtio_gpu_cmd_set_scanout(vgdev, output->index, 0, 0, 0, 0, 0); virtio_gpu_notify(vgdev); } @@ -149,17 +157,20 @@ static void virtio_gpu_crtc_atomic_flush(struct drm_crtc *crtc, crtc); struct virtio_gpu_output *output = drm_crtc_to_virtio_gpu_output(crtc); struct drm_device *drm = crtc->dev; - - spin_lock_irq(&drm->event_lock); - - - if (crtc->state->event) { - drm_crtc_send_vblank_event(crtc, crtc->state->event); - crtc->state->event = NULL; + struct virtio_gpu_device *vgdev = drm->dev_private; + + if(vgdev->has_vblank) { + if (crtc->state->event) { + spin_lock_irq(&drm->event_lock); + if (drm_crtc_vblank_get(crtc) != 0) + drm_crtc_send_vblank_event(crtc, crtc->state->event); + else + drm_crtc_arm_vblank_event(crtc, crtc->state->event); + spin_unlock_irq(&drm->event_lock); + crtc->state->event = NULL; + } } - spin_unlock_irq(&drm->event_lock); - /* * virtio-gpu can't do modeset and plane update operations * independent from each other. So the actual modeset happens diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c index 47202aa417da..bef47d273178 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.c +++ b/drivers/gpu/drm/virtio/virtgpu_drv.c @@ -180,6 +180,7 @@ static int virtgpu_freeze(struct virtio_device *vdev) return error; } + vdev->config->reset(vdev); flush_work(&vgdev->obj_free_work); flush_work(&vgdev->ctrlq.dequeue_work); flush_work(&vgdev->cursorq.dequeue_work); @@ -193,7 +194,7 @@ static int virtgpu_restore(struct virtio_device *vdev) { struct drm_device *dev = vdev->priv; struct virtio_gpu_device *vgdev = dev->dev_private; - int error; + int error, i; error = virtio_gpu_find_vqs(vgdev); if (error) { @@ -203,6 +204,15 @@ static int virtgpu_restore(struct virtio_device *vdev) virtio_device_ready(vdev); + + if(vgdev->has_vblank) { + virtio_gpu_vblankq_notify(vgdev); + + for(i = 0; i < vgdev->num_vblankq; i++) + virtqueue_disable_cb(vgdev->vblank[i].vblank.vq); + } + + error = virtio_gpu_object_restore_all(vgdev); if (error) { DRM_ERROR("Failed to recover objects\n"); From 2239a6a9331be4629ea0660f2e85a9e3c469ca20 Mon Sep 17 00:00:00 2001 From: HeYue Date: Fri, 23 Feb 2024 09:22:00 +0800 Subject: [PATCH 42/43] drm/virtio: Support tile-4 modifier Tile-4 is supported by Intel DG2. Support it could benefit performance. Tracked-On: OAM-130450 Signed-off-by: HeYue Signed-off-by: Zhao, Shirley --- drivers/gpu/drm/virtio/virtgpu_plane.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c index e57e7a307ebd..94a598304ae2 100644 --- a/drivers/gpu/drm/virtio/virtgpu_plane.c +++ b/drivers/gpu/drm/virtio/virtgpu_plane.c @@ -532,6 +532,7 @@ static const uint64_t virtio_gpu_format_modifiers[] = { DRM_FORMAT_MOD_LINEAR, I915_FORMAT_MOD_X_TILED, I915_FORMAT_MOD_Y_TILED, + I915_FORMAT_MOD_4_TILED, DRM_FORMAT_MOD_INVALID }; @@ -543,6 +544,7 @@ static bool virtio_gpu_plane_format_mod_supported(struct drm_plane *_plane, case DRM_FORMAT_MOD_LINEAR: case I915_FORMAT_MOD_X_TILED: case I915_FORMAT_MOD_Y_TILED: + case I915_FORMAT_MOD_4_TILED: return true; default: return false; From eb358d438cc2242d6c5172c429e0e1b84f71ba19 Mon Sep 17 00:00:00 2001 From: "Xue, Bosheng" Date: Fri, 25 Oct 2024 19:27:54 +0800 Subject: [PATCH 43/43] drm/virtio: put set modifier ahead of set scanout put set modifier ahead of set scanout to avoid set scaout operation can not get the lastest modifier, and refine set modifer api to pass resource id to backend. Tracked-On: OAM-130450 Signed-off-by: Xue, Bosheng Signed-off-by: Zhao, Shirley --- drivers/gpu/drm/virtio/virtgpu_drv.h | 1 + drivers/gpu/drm/virtio/virtgpu_plane.c | 4 ++-- drivers/gpu/drm/virtio/virtgpu_vq.c | 2 ++ include/uapi/linux/virtio_gpu.h | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index 907b1387e71a..e8c7034cecec 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -456,6 +456,7 @@ virtio_gpu_cmd_set_scanout_blob(struct virtio_gpu_device *vgdev, uint32_t x, uint32_t y); void virtio_gpu_cmd_set_modifier(struct virtio_gpu_device *vgdev, uint32_t scanout_id, + struct virtio_gpu_object *bo, struct drm_framebuffer *fb); void virtio_gpu_cmd_set_scaling(struct virtio_gpu_device *vgdev, diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c index 94a598304ae2..fcfa70a561a8 100644 --- a/drivers/gpu/drm/virtio/virtgpu_plane.c +++ b/drivers/gpu/drm/virtio/virtgpu_plane.c @@ -290,6 +290,8 @@ static void virtio_gpu_primary_plane_update(struct drm_plane *plane, plane->state->src_y >> 16); if (bo->host3d_blob || bo->guest_blob) { + if (vgdev->has_modifier) + virtio_gpu_cmd_set_modifier(vgdev, output->index, bo, plane->state->fb); virtio_gpu_cmd_set_scanout_blob (vgdev, output->index, bo, plane->state->fb, @@ -297,8 +299,6 @@ static void virtio_gpu_primary_plane_update(struct drm_plane *plane, plane->state->src_h >> 16, plane->state->src_x >> 16, plane->state->src_y >> 16); - if (vgdev->has_modifier) - virtio_gpu_cmd_set_modifier(vgdev, output->index, plane->state->fb); } else { virtio_gpu_cmd_set_scanout(vgdev, output->index, diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c index bc96d9ad2a24..f0a4d9b96e07 100644 --- a/drivers/gpu/drm/virtio/virtgpu_vq.c +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c @@ -1419,6 +1419,7 @@ void virtio_gpu_cmd_set_scanout_blob(struct virtio_gpu_device *vgdev, void virtio_gpu_cmd_set_modifier(struct virtio_gpu_device *vgdev, uint32_t scanout_id, + struct virtio_gpu_object *bo, struct drm_framebuffer *fb) { struct virtio_gpu_set_modifier *cmd_p; @@ -1429,6 +1430,7 @@ void virtio_gpu_cmd_set_modifier(struct virtio_gpu_device *vgdev, cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_SET_MODIFIER); cmd_p->modifier = cpu_to_le64(fb->modifier); cmd_p->scanout_id = cpu_to_le32(scanout_id); + cmd_p->resource_id = cpu_to_le32(bo->hw_res_handle); virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); } diff --git a/include/uapi/linux/virtio_gpu.h b/include/uapi/linux/virtio_gpu.h index c182802ff00c..8b16a89f7f3d 100644 --- a/include/uapi/linux/virtio_gpu.h +++ b/include/uapi/linux/virtio_gpu.h @@ -454,7 +454,7 @@ struct virtio_gpu_set_modifier { struct virtio_gpu_ctrl_hdr hdr; __le64 modifier; __le32 scanout_id; - __le32 padding; + __le32 resource_id; }; /* VIRTIO_GPU_CMD_RESOURCE_MAP_BLOB */