diff --git a/drivers/gpu/drm/virtio/virtgpu_debugfs.c b/drivers/gpu/drm/virtio/virtgpu_debugfs.c index a075f29b287b..853dd9aa397e 100644 --- a/drivers/gpu/drm/virtio/virtgpu_debugfs.c +++ b/drivers/gpu/drm/virtio/virtgpu_debugfs.c @@ -55,14 +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, "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); - 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); if (vgdev->host_visible_region.len) { @@ -102,30 +94,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) diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c index 76968ea7a759..e498b60af06d 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; } @@ -89,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; @@ -117,94 +136,20 @@ 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); - - struct drm_pending_vblank_event *e = xchg(&vgdev->cache_event[pipe], NULL); - /* Send cached event even it's still premature. */ - if (e) { - spin_lock_irq(&dev->event_lock); - drm_crtc_send_vblank_event(crtc, e); - 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 *old_e, *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; - old_e = xchg(&vgdev->cache_event[pipe], crtc->state->event); - if (old_e) { - spin_lock_irq(&drm->event_lock); - drm_crtc_send_vblank_event(crtc, old_e); - spin_unlock_irq(&drm->event_lock); - drm_crtc_vblank_put(crtc); - } - } - crtc->state->event = NULL; -} - 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) { @@ -213,13 +158,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_multi_plane) - virtio_gpu_resource_flush_sync(crtc); - - if(vgdev->has_scaling) - output->scaler_users = 0; + 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; + } + } /* * virtio-gpu can't do modeset and plane update operations @@ -234,7 +184,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, @@ -363,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); @@ -408,46 +344,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 = { @@ -456,79 +373,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 +385,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..bef47d273178 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); @@ -167,12 +165,6 @@ static unsigned int features[] = { VIRTIO_GPU_F_MODIFIER, 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, - 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 befc4bd8dcbe..e8c7034cecec 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -88,9 +88,9 @@ 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 prime; bool created; bool attached; bool host3d_blob, guest_blob; @@ -98,11 +98,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; }; #define gem_to_virtio_gpu_obj(gobj) \ container_of((gobj), struct virtio_gpu_object, base.base) @@ -184,12 +179,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 - -#define VBLANK_EVENT_CACHE_SIZE 3 - struct virtio_gpu_output { int index; struct drm_crtc crtc; @@ -201,9 +190,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) @@ -250,23 +236,14 @@ 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; - /* 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; @@ -290,12 +267,6 @@ struct virtio_gpu_device { bool has_modifier; 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; - bool has_multi_planar; bool has_indirect; bool has_resource_assign_uuid; bool has_resource_blob; @@ -320,7 +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[VIRTIO_GPU_MAX_SCANOUTS]; + struct virtio_gpu_vblank vblank[]; }; struct virtio_gpu_fpriv { @@ -397,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, @@ -491,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, @@ -515,9 +463,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); @@ -527,7 +472,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, @@ -553,12 +497,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 */ @@ -571,6 +509,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_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c index de502c8a0cd9..c33c057365f8 100644 --- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c +++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c @@ -114,13 +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_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; break; diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c index 8705ec980972..b75e50bbbf5c 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; @@ -241,24 +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_FLIP_SEQUENCE)) { - vgdev->has_flip_sequence = 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_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)) { @@ -294,16 +264,27 @@ 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 ? '+' : '-'); + + 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); - DRM_INFO("features: %ccontext_init %callow_p2p %cflip_sequence\n", - vgdev->has_context_init ? '+' : '-', - vgdev->has_allow_p2p ? '+' : '-', - vgdev->has_flip_sequence ? '+' : '-'); + 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, @@ -324,33 +305,10 @@ 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); - - 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"); - goto err_vqs; - } - ret = virtio_gpu_alloc_vbufs(vgdev); + ret = virtio_gpu_modeset_init(vgdev); if (ret) { - DRM_ERROR("failed to alloc vbufs\n"); - goto err_vbufs; + DRM_ERROR("modeset init failed\n"); + goto err_scanouts; } virtio_device_ready(vgdev->vdev); @@ -358,15 +316,6 @@ int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev) 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_gpu_vblankq_notify(vgdev); for(i=0; i < vgdev->num_vblankq; i++) diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c index 97af5af9551f..8395a0212f9d 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) { @@ -99,8 +99,6 @@ void virtio_gpu_cleanup_object(struct virtio_gpu_object *bo) 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)) { @@ -115,6 +113,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); } } @@ -315,16 +316,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_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c index 75bdfb7e565d..fcfa70a561a8 100644 --- a/drivers/gpu/drm/virtio/virtgpu_plane.c +++ b/drivers/gpu/drm/virtio/virtgpu_plane.c @@ -27,11 +27,11 @@ #include #include #include -#include +#include #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, @@ -46,20 +46,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; @@ -115,9 +101,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: /* @@ -156,105 +139,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) { @@ -264,13 +148,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; @@ -300,21 +178,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, @@ -374,123 +238,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]); - 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); - } - - 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) { @@ -501,8 +248,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); @@ -576,36 +321,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 ((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); - } - virtio_gpu_resource_flush(plane, rect.x1, rect.y1, @@ -613,6 +328,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) { @@ -621,6 +374,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; @@ -634,7 +389,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); @@ -645,10 +407,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; @@ -658,6 +431,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, @@ -751,11 +528,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, @@ -779,38 +551,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) @@ -825,22 +565,9 @@ 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); - if(vgdev->has_multi_planar) { - virtio_gpu_formats[nformats] = DRM_FORMAT_NV12; - nformats++; - } funcs = &virtio_gpu_primary_helper_funcs; } @@ -856,25 +583,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_prime.c b/drivers/gpu/drm/virtio/virtgpu_prime.c index e4aee3766855..688810d1b611 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,188 +144,203 @@ struct dma_buf *virtgpu_gem_prime_export(struct drm_gem_object *obj, return buf; } -struct drm_gem_object *virtgpu_gem_prime_import(struct drm_device *dev, - struct dma_buf *dma_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 drm_gem_object *obj; - struct dma_buf_attachment *attach; + struct scatterlist *sl; struct sg_table *sgt; - struct device *attach_dev = dev->dev; - struct virtio_gpu_device *vgdev = dev->dev_private; - int ret; - bool p2p = false; + long i, ret; - if (dma_buf->ops == &virtgpu_dmabuf_ops.ops) { - obj = dma_buf->priv; - if (obj->dev == dev) { - /* - * Importing dmabuf exported from our own gem increases - * refcount on gem itself instead of f_count of dmabuf. - */ - drm_gem_object_get(obj); - return obj; - } - } + dma_resv_assert_held(attach->dmabuf->resv); - if (strcmp(dev->dev->driver->name, "virtio-ivshmem") == 0 || - strcmp(dev->dev->driver->name, "virtio-guest-shm") == 0) - return ERR_PTR(-EINVAL); + ret = dma_resv_wait_timeout(attach->dmabuf->resv, + DMA_RESV_USAGE_KERNEL, + false, MAX_SCHEDULE_TIMEOUT); + if (ret <= 0) + return ret < 0 ? ret : -ETIMEDOUT; - if (!dev->driver->gem_prime_import_sg_table) - return ERR_PTR(-EINVAL); + sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); + if (IS_ERR(sgt)) + return PTR_ERR(sgt); - spin_lock(&dma_buf->name_lock); - if(vgdev->has_allow_p2p && dma_buf->name) { - if(strcmp(dma_buf->name, "p2p") == 0) - p2p = true; + *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; } - spin_unlock(&dma_buf->name_lock); - attach = ____dma_buf_dynamic_attach(dma_buf, attach_dev, NULL, NULL, - p2p); - if (IS_ERR(attach)) - return ERR_CAST(attach); + *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; + } - get_dma_buf(dma_buf); + bo->sgt = sgt; + return 0; +} - sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); - if (IS_ERR(sgt)) { - ret = PTR_ERR(sgt); - goto fail_detach; - } +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; - obj = dev->driver->gem_prime_import_sg_table(dev, attach, sgt); - if (IS_ERR(obj)) { - ret = PTR_ERR(obj); - goto fail_unmap; - } + if (attach) { + dma_resv_lock(resv, NULL); - obj->import_attach = attach; - obj->resv = dma_buf->resv; + virtio_gpu_detach_object_fenced(bo); - return obj; + if (bo->sgt) + dma_buf_unmap_attachment(attach, bo->sgt, + DMA_BIDIRECTIONAL); -fail_unmap: - dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL); -fail_detach: - dma_buf_detach(dma_buf, attach); - dma_buf_put(dma_buf); + dma_resv_unlock(resv); - return ERR_PTR(ret); + 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 virtio_gpu_sgt_to_mem_entry(struct virtio_gpu_device *vgdev, - struct sg_table *table, - struct virtio_gpu_mem_entry **ents, - unsigned int *nents) +static int virtgpu_dma_buf_init_obj(struct drm_device *dev, + struct virtio_gpu_object *bo, + struct dma_buf_attachment *attach) { - 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; - 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; - } + 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; - 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; - } + 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_sg_table( - struct drm_device *dev, struct dma_buf_attachment *attach, - struct sg_table *table) +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) { - size_t size = PAGE_ALIGN(attach->dmabuf->size); struct virtio_gpu_device *vgdev = dev->dev_private; - struct virtio_gpu_object_params params = { 0 }; + struct dma_buf_attachment *attach; 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); - } - - 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); - } - - 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); + if (buf->ops == &virtgpu_dmabuf_ops.ops) { + obj = buf->priv; + if (obj->dev == dev) { + /* + * Importing dmabuf exported from our own gem increases + * refcount on gem itself instead of f_count of dmabuf. + */ + drm_gem_object_get(obj); + return obj; + } } - ret = virtio_gpu_sgt_to_mem_entry(vgdev, table, &ents, &nents); - if (ret != 0) { - goto err_put_id; - } + if (!vgdev->has_resource_blob || vgdev->has_virgl_3d) + return drm_gem_prime_import(dev, buf); - bo->guest_blob = true; - bo->prime = true; + bo = kzalloc(sizeof(*bo), GFP_KERNEL); + if (!bo) + return ERR_PTR(-ENOMEM); - if (attach->peer2peer) - bo->locate = 1; + obj = &bo->base.base; + obj->funcs = &virtgpu_gem_dma_buf_funcs; + drm_gem_private_object_init(dev, obj, buf->size); - 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; + attach = dma_buf_dynamic_attach(buf, dev->dev, + &virtgpu_dma_buf_attach_ops, obj); + if (IS_ERR(attach)) { + kfree(bo); + return ERR_CAST(attach); } - virtio_gpu_cmd_resource_create_blob(vgdev, bo, ¶ms, - ents, nents); - virtio_gpu_object_save_restore_list(vgdev, bo, ¶ms); + 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; +} -err_free_ents: - kvfree(ents); -err_put_id: - virtio_gpu_resource_id_put(vgdev, bo->hw_res_handle); - return ERR_PTR(ret); +struct drm_gem_object *virtgpu_gem_prime_import_sg_table( + struct drm_device *dev, struct dma_buf_attachment *attach, + struct sg_table *table) +{ + return ERR_PTR(-ENODEV); } diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c index 0c1900318dee..f0a4d9b96e07 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 \ @@ -100,48 +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; - - struct drm_pending_vblank_event *e = xchg(&vgdev->cache_event[target], NULL); - if (!e) - return; + spin_unlock_irqrestore(&vgdev->vblank[target].vblank.qlock, irqflags); + drm_handle_vblank(dev, target); - if (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); - } - } } void virtio_gpu_cursor_ack(struct virtqueue *vq) @@ -673,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, @@ -880,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) { @@ -1005,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; @@ -1544,8 +1352,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, @@ -1573,18 +1381,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..c2ce71987e9b 100644 --- a/include/uapi/drm/virtgpu_drm.h +++ b/include/uapi/drm/virtgpu_drm.h @@ -98,8 +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. */ -#define VIRTGPU_PARAM_ALLOW_P2P 12 /* do we accept local memory addresses */ struct drm_virtgpu_getparam { __u64 param; @@ -181,7 +179,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..8b16a89f7f3d 100644 --- a/include/uapi/linux/virtio_gpu.h +++ b/include/uapi/linux/virtio_gpu.h @@ -71,35 +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 - -/* - * 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_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 -#define VIRTIO_GPU_TUNNEL_CMD_SET_SPRITE_SCALING 4 +#define VIRTIO_GPU_F_VBLANK 7 enum virtio_gpu_ctrl_type { VIRTIO_GPU_UNDEFINED = 0, @@ -121,11 +95,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, @@ -238,14 +207,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; @@ -254,46 +215,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; @@ -441,34 +362,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; @@ -492,7 +385,6 @@ struct virtio_gpu_config { __le32 num_scanouts; __le32 num_capsets; __le32 num_pipe; - __le32 output_bitmask; }; /* simple formats for fbcon/X use */