From: Ekansh Gupta ekansh.gupta@oss.qualcomm.com
Expose two new DRM IOCTLs that allow user-space to allocate DMA-backed GEM buffer objects and retrieve their mmap offsets.
DRM_IOCTL_QDA_GEM_CREATE (drm_qda_gem_create) Allocates a DMA-coherent GEM buffer of the requested size. The memory manager assigns an IOMMU context bank to the calling process on first use and performs the DMA allocation against that bank. Returns a GEM handle that identifies the buffer for subsequent operations.
DRM_IOCTL_QDA_GEM_MMAP_OFFSET (drm_qda_gem_mmap_offset) Returns the mmap offset for an existing GEM handle. The offset can be passed directly to mmap() to map the buffer into user-space. Imported DMA-BUF objects are rejected by drm_gem_dumb_map_offset().
DRIVER_GEM is added to driver_features now that GEM IOCTLs are present.
Assisted-by: Claude:claude-4-6-sonnet Signed-off-by: Ekansh Gupta ekansh.gupta@oss.qualcomm.com --- drivers/accel/qda/qda_drv.c | 4 +++- drivers/accel/qda/qda_ioctl.c | 50 +++++++++++++++++++++++++++++++++++++++++++ drivers/accel/qda/qda_ioctl.h | 2 ++ include/uapi/drm/qda_accel.h | 36 +++++++++++++++++++++++++++++++ 4 files changed, 91 insertions(+), 1 deletion(-)
diff --git a/drivers/accel/qda/qda_drv.c b/drivers/accel/qda/qda_drv.c index 1b534fea50c8..c9b9e56dcb28 100644 --- a/drivers/accel/qda/qda_drv.c +++ b/drivers/accel/qda/qda_drv.c @@ -53,10 +53,12 @@ DEFINE_DRM_ACCEL_FOPS(qda_accel_fops);
static const struct drm_ioctl_desc qda_ioctls[] = { DRM_IOCTL_DEF_DRV(QDA_QUERY, qda_ioctl_query, 0), + DRM_IOCTL_DEF_DRV(QDA_GEM_CREATE, qda_ioctl_gem_create, 0), + DRM_IOCTL_DEF_DRV(QDA_GEM_MMAP_OFFSET, qda_ioctl_gem_mmap_offset, 0), };
static const struct drm_driver qda_drm_driver = { - .driver_features = DRIVER_COMPUTE_ACCEL, + .driver_features = DRIVER_GEM | DRIVER_COMPUTE_ACCEL, .fops = &qda_accel_fops, .open = qda_open, .postclose = qda_postclose, diff --git a/drivers/accel/qda/qda_ioctl.c b/drivers/accel/qda/qda_ioctl.c index 761d3567c33f..1769c85a3e98 100644 --- a/drivers/accel/qda/qda_ioctl.c +++ b/drivers/accel/qda/qda_ioctl.c @@ -3,6 +3,7 @@ #include <drm/drm_ioctl.h> #include <drm/qda_accel.h> #include "qda_drv.h" +#include "qda_gem.h" #include "qda_ioctl.h"
/** @@ -24,3 +25,52 @@ int qda_ioctl_query(struct drm_device *dev, void *data, struct drm_file *file_pr
return 0; } + +/** + * qda_ioctl_gem_create() - Create a GEM buffer object + * @dev: DRM device structure + * @data: User-space data (struct drm_qda_gem_create) + * @file_priv: DRM file private data + * + * Return: 0 on success, negative error code on failure + */ +int qda_ioctl_gem_create(struct drm_device *dev, void *data, struct drm_file *file_priv) +{ + struct drm_qda_gem_create *args = data; + struct drm_gem_object *gem_obj; + struct qda_dev *qdev; + + if (args->pad) + return -EINVAL; + + qdev = qda_dev_from_drm(dev); + if (!qdev->iommu_mgr) + return -ENODEV; + + gem_obj = qda_gem_create_object(dev, qdev->iommu_mgr, args->size, file_priv); + if (IS_ERR(gem_obj)) + return PTR_ERR(gem_obj); + + return qda_gem_create_handle(file_priv, gem_obj, &args->handle); +} + +/** + * qda_ioctl_gem_mmap_offset() - Get the mmap offset for a GEM object + * @dev: DRM device structure + * @data: User-space data (struct drm_qda_gem_mmap_offset) + * @file_priv: DRM file private data + * + * Uses drm_gem_dumb_map_offset() which rejects imported dma-buf objects + * (mmap of imported objects is not allowed). + * + * Return: 0 on success, negative error code on failure + */ +int qda_ioctl_gem_mmap_offset(struct drm_device *dev, void *data, struct drm_file *file_priv) +{ + struct drm_qda_gem_mmap_offset *args = data; + + if (args->pad) + return -EINVAL; + + return drm_gem_dumb_map_offset(file_priv, dev, args->handle, &args->offset); +} diff --git a/drivers/accel/qda/qda_ioctl.h b/drivers/accel/qda/qda_ioctl.h index b8fd536a111f..d1cbbfb6d965 100644 --- a/drivers/accel/qda/qda_ioctl.h +++ b/drivers/accel/qda/qda_ioctl.h @@ -9,5 +9,7 @@ #include "qda_drv.h"
int qda_ioctl_query(struct drm_device *dev, void *data, struct drm_file *file_priv); +int qda_ioctl_gem_create(struct drm_device *dev, void *data, struct drm_file *file_priv); +int qda_ioctl_gem_mmap_offset(struct drm_device *dev, void *data, struct drm_file *file_priv);
#endif /* __QDA_IOCTL_H__ */ diff --git a/include/uapi/drm/qda_accel.h b/include/uapi/drm/qda_accel.h index 1971a4263065..319e21aae0d6 100644 --- a/include/uapi/drm/qda_accel.h +++ b/include/uapi/drm/qda_accel.h @@ -19,6 +19,8 @@ extern "C" { * They are used with DRM_COMMAND_BASE to create the full IOCTL numbers. */ #define DRM_QDA_QUERY 0x00 +#define DRM_QDA_GEM_CREATE 0x01 +#define DRM_QDA_GEM_MMAP_OFFSET 0x02
/* * QDA IOCTL definitions @@ -29,6 +31,10 @@ extern "C" { */ #define DRM_IOCTL_QDA_QUERY DRM_IOR(DRM_COMMAND_BASE + DRM_QDA_QUERY, \ struct drm_qda_query) +#define DRM_IOCTL_QDA_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_QDA_GEM_CREATE, \ + struct drm_qda_gem_create) +#define DRM_IOCTL_QDA_GEM_MMAP_OFFSET DRM_IOWR(DRM_COMMAND_BASE + DRM_QDA_GEM_MMAP_OFFSET, \ + struct drm_qda_gem_mmap_offset)
/** * struct drm_qda_query - Device information query structure @@ -42,6 +48,36 @@ struct drm_qda_query { __u8 dsp_name[16]; };
+/** + * struct drm_qda_gem_create - GEM buffer object creation parameters + * @size: Size of the GEM object to create in bytes (input) + * @handle: Allocated GEM handle (output) + * + * This structure is used with DRM_IOCTL_QDA_GEM_CREATE to allocate + * a new GEM buffer object. + */ +struct drm_qda_gem_create { + __u64 size; + __u32 handle; + __u32 pad; +}; + +/** + * struct drm_qda_gem_mmap_offset - GEM object mmap offset query + * @offset: mmap offset for the GEM object (output) + * @handle: GEM handle (input) + * @pad: Padding for 64-bit alignment + * + * This structure is used with DRM_IOCTL_QDA_GEM_MMAP_OFFSET to retrieve + * the mmap offset that can be used with mmap() to map the GEM object into + * user space. + */ +struct drm_qda_gem_mmap_offset { + __u64 offset; + __u32 handle; + __u32 pad; +}; + #if defined(__cplusplus) } #endif