Signed-off-by: Faith Ekstrand <faith.ekstr...@collabora.com> --- drivers/gpu/drm/panthor/panthor_drv.c | 47 ++++++++++++++++++++++- drivers/gpu/drm/panthor/panthor_gem.c | 20 ++++++++++ drivers/gpu/drm/panthor/panthor_gem.h | 3 ++ include/uapi/drm/panthor_drm.h | 55 +++++++++++++++++++++++++++ 4 files changed, 124 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/panthor/panthor_drv.c b/drivers/gpu/drm/panthor/panthor_drv.c index 06ae6a2aeb16..1527966604e1 100644 --- a/drivers/gpu/drm/panthor/panthor_drv.c +++ b/drivers/gpu/drm/panthor/panthor_drv.c @@ -175,7 +175,8 @@ panthor_get_uobj_array(const struct drm_panthor_obj_array *in, u32 min_stride, PANTHOR_UOBJ_DECL(struct drm_panthor_sync_op, timeline_value), \ PANTHOR_UOBJ_DECL(struct drm_panthor_queue_submit, syncs), \ PANTHOR_UOBJ_DECL(struct drm_panthor_queue_create, ringbuf_size), \ - PANTHOR_UOBJ_DECL(struct drm_panthor_vm_bind_op, syncs)) + PANTHOR_UOBJ_DECL(struct drm_panthor_vm_bind_op, syncs), \ + PANTHOR_UOBJ_DECL(struct drm_panthor_bo_sync_op, size)) /** * PANTHOR_UOBJ_SET() - Copy a kernel object to a user object. @@ -1398,6 +1399,49 @@ static int panthor_ioctl_set_user_mmio_offset(struct drm_device *ddev, return 0; } +#define PANTHOR_BO_SYNC_OP_FLAGS \ + (DRM_PANTHOR_BO_SYNC_TO_DEVICE | \ + DRM_PANTHOR_BO_SYNC_FROM_DEVICE) + +static int panthor_ioctl_bo_sync(struct drm_device *ddev, void *data, + struct drm_file *file) +{ + struct drm_panthor_bo_sync *args = data; + struct drm_panthor_bo_sync_op *ops; + struct drm_gem_object *obj; + int ret = 0; + + ret = PANTHOR_UOBJ_GET_ARRAY(ops, &args->ops); + if (ret) + return ret; + + for (u32 i = 0; i < args->ops.count; i++) { + if (ops[i].flags & ~PANTHOR_BO_SYNC_OP_FLAGS) { + ret = -EINVAL; + goto err_ops; + } + + obj = drm_gem_object_lookup(file, ops[i].handle); + if (!obj) { + ret = -ENOENT; + goto err_ops; + } + + ret = panthor_gem_bo_sync(obj, ops[i].flags, + ops[i].offset, ops[i].size); + + drm_gem_object_put(obj); + + if (ret) + goto err_ops; + } + +err_ops: + kvfree(ops); + + return ret; +} + static int panthor_open(struct drm_device *ddev, struct drm_file *file) { @@ -1481,6 +1525,7 @@ static const struct drm_ioctl_desc panthor_drm_driver_ioctls[] = { PANTHOR_IOCTL(GROUP_SUBMIT, group_submit, DRM_RENDER_ALLOW), PANTHOR_IOCTL(BO_SET_LABEL, bo_set_label, DRM_RENDER_ALLOW), PANTHOR_IOCTL(SET_USER_MMIO_OFFSET, set_user_mmio_offset, DRM_RENDER_ALLOW), + PANTHOR_IOCTL(BO_SYNC, bo_sync, DRM_RENDER_ALLOW), }; static int panthor_mmap(struct file *filp, struct vm_area_struct *vma) diff --git a/drivers/gpu/drm/panthor/panthor_gem.c b/drivers/gpu/drm/panthor/panthor_gem.c index 530bad12d545..31f5d76002ec 100644 --- a/drivers/gpu/drm/panthor/panthor_gem.c +++ b/drivers/gpu/drm/panthor/panthor_gem.c @@ -344,6 +344,26 @@ panthor_gem_kernel_bo_set_label(struct panthor_kernel_bo *bo, const char *label) panthor_gem_bo_set_label(bo->obj, str); } +int +panthor_gem_bo_sync(struct drm_gem_object *obj, u32 flags, + u64 offset, u64 size) +{ + struct panthor_gem_object *bo = to_panthor_bo(obj); + enum dma_data_direction dir = DMA_NONE; + + if ((flags & DRM_PANTHOR_BO_SYNC_TO_DEVICE) && + (flags & DRM_PANTHOR_BO_SYNC_FROM_DEVICE)) + return -EINVAL; + else if (flags & DRM_PANTHOR_BO_SYNC_TO_DEVICE) + dir = DMA_TO_DEVICE; + else if (flags & DRM_PANTHOR_BO_SYNC_FROM_DEVICE) + dir = DMA_FROM_DEVICE; + else + return 0; + + return drm_gem_shmem_sync_mmap(&bo->base, offset, size, dir); +} + #ifdef CONFIG_DEBUG_FS struct gem_size_totals { size_t size; diff --git a/drivers/gpu/drm/panthor/panthor_gem.h b/drivers/gpu/drm/panthor/panthor_gem.h index 8fc7215e9b90..36fe392ee627 100644 --- a/drivers/gpu/drm/panthor/panthor_gem.h +++ b/drivers/gpu/drm/panthor/panthor_gem.h @@ -159,6 +159,9 @@ panthor_gem_create_with_handle(struct drm_file *file, void panthor_gem_bo_set_label(struct drm_gem_object *obj, const char *label); void panthor_gem_kernel_bo_set_label(struct panthor_kernel_bo *bo, const char *label); +int panthor_gem_bo_sync(struct drm_gem_object *obj, u32 flags, + u64 offset, u64 size); + static inline u64 panthor_kernel_bo_gpuva(struct panthor_kernel_bo *bo) { diff --git a/include/uapi/drm/panthor_drm.h b/include/uapi/drm/panthor_drm.h index bf47369c0220..77b3ca5f6150 100644 --- a/include/uapi/drm/panthor_drm.h +++ b/include/uapi/drm/panthor_drm.h @@ -144,6 +144,9 @@ enum drm_panthor_ioctl_id { * pgoff_t size. */ DRM_PANTHOR_SET_USER_MMIO_OFFSET, + + /** @DRM_PANTHOR_BO_SYNC: Sync BO data to/from the device */ + DRM_PANTHOR_BO_SYNC, }; /** @@ -1047,6 +1050,56 @@ struct drm_panthor_set_user_mmio_offset { __u64 offset; }; +/** + * enum drm_panthor_bo_sync_op_flags - BO sync flags + */ +enum drm_panthor_bo_sync_op_flags { + /** + * @DRM_PANTHOR_BO_SYNC_TO_DEVICE: Sync data from the CPU to the + * device. + */ + DRM_PANTHOR_BO_SYNC_TO_DEVICE = (1 << 0), + + /** + * @DRM_PANTHOR_BO_SYNC_TO_DEVICE: Sync data from the device to the + * CPU. + */ + DRM_PANTHOR_BO_SYNC_FROM_DEVICE = (1 << 1), +}; + +/** + * struct drm_panthor_bo_sync_op - BO map sync op + */ +struct drm_panthor_bo_sync_op { + /** @handle: Handle of the buffer object to sync. */ + __u32 handle; + + /** @flags: Flags controlling the sync operation. */ + __u32 flags; + + /** + * @offset: Offset into the BO at which the sync range starts. + * + * This will be rounded down to the nearest cache line as needed. + */ + __u64 offset; + + /** + * @size: Size of the range to sync + * + * @size + @offset will be rounded up to the nearest cache line as + * needed. + */ + __u64 size; +}; + +struct drm_panthor_bo_sync { + /** + * @ops: Array of struct drm_panthor_bo_sync_op sync operations. + */ + struct drm_panthor_obj_array ops; +}; + /** * DRM_IOCTL_PANTHOR() - Build a Panthor IOCTL number * @__access: Access type. Must be R, W or RW. @@ -1093,6 +1146,8 @@ enum { DRM_IOCTL_PANTHOR(WR, BO_SET_LABEL, bo_set_label), DRM_IOCTL_PANTHOR_SET_USER_MMIO_OFFSET = DRM_IOCTL_PANTHOR(WR, SET_USER_MMIO_OFFSET, set_user_mmio_offset), + DRM_IOCTL_PANTHOR_BO_SYNC = + DRM_IOCTL_PANTHOR(WR, BO_SYNC, bo_sync), }; #if defined(__cplusplus) -- 2.50.1