Signed-off-by: Faith Ekstrand <[email protected]>
---
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