On Fri, Jun 6, 2025 at 1:29 AM Tomeu Vizoso tomeu@tomeuvizoso.net wrote:
Using the DRM GPU scheduler infrastructure, with a scheduler for each core.
Userspace can decide for a series of tasks to be executed sequentially in the same core, so SRAM locality can be taken advantage of.
The job submission code was initially based on Panfrost.
v2:
- Remove hardcoded number of cores
- Misc. style fixes (Jeffrey Hugo)
- Repack IOCTL struct (Jeffrey Hugo)
v3:
- Adapt to a split of the register block in the DT bindings (Nicolas Frattaroli)
- Make use of GPL-2.0-only for the copyright notice (Jeff Hugo)
- Use drm_* logging functions (Thomas Zimmermann)
- Rename reg i/o macros (Thomas Zimmermann)
- Add padding to ioctls and check for zero (Jeff Hugo)
- Improve error handling (Nicolas Frattaroli)
v6:
- Use mutexes guard (Markus Elfring)
- Use u64_to_user_ptr (Jeff Hugo)
- Drop rocket_fence (Rob Herring)
v7:
- Assign its own IOMMU domain to each client, for isolation (Daniel Stone and Robin Murphy)
Signed-off-by: Tomeu Vizoso tomeu@tomeuvizoso.net
[...]
--- a/include/uapi/drm/rocket_accel.h +++ b/include/uapi/drm/rocket_accel.h @@ -12,8 +12,10 @@ extern "C" { #endif
#define DRM_ROCKET_CREATE_BO 0x00 +#define DRM_ROCKET_SUBMIT 0x01
#define DRM_IOCTL_ROCKET_CREATE_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_ROCKET_CREATE_BO, struct drm_rocket_create_bo) +#define DRM_IOCTL_ROCKET_SUBMIT DRM_IOW(DRM_COMMAND_BASE + DRM_ROCKET_SUBMIT, struct drm_rocket_submit)
/**
- struct drm_rocket_create_bo - ioctl argument for creating Rocket BOs.
@@ -37,6 +39,68 @@ struct drm_rocket_create_bo { __u64 offset; };
+/**
- struct drm_rocket_task - A task to be run on the NPU
- A task is the smallest unit of work that can be run on the NPU.
- */
+struct drm_rocket_task {
/** Input: DMA address to NPU mapping of register command buffer */
__u64 regcmd;
/** Input: Number of commands in the register command buffer */
__u32 regcmd_count;
/** Reserved, must be zero. */
__u32 reserved;
+};
+/**
- struct drm_rocket_job - A job to be run on the NPU
- The kernel will schedule the execution of this job taking into account its
- dependencies with other jobs. All tasks in the same job will be executed
- sequentially on the same core, to benefit from memory residency in SRAM.
- */
+struct drm_rocket_job {
/** Input: Pointer to an array of struct drm_rocket_task. */
__u64 tasks;
/** Input: Pointer to a u32 array of the BOs that are read by the job. */
__u64 in_bo_handles;
/** Input: Pointer to a u32 array of the BOs that are written to by the job. */
__u64 out_bo_handles;
/** Input: Number of tasks passed in. */
__u32 task_count;
/** Input: Number of input BO handles passed in (size is that times 4). */
__u32 in_bo_handle_count;
/** Input: Number of output BO handles passed in (size is that times 4). */
__u32 out_bo_handle_count;
/** Reserved, must be zero. */
__u32 reserved;
+};
+/**
- struct drm_rocket_submit - ioctl argument for submitting commands to the NPU.
- The kernel will schedule the execution of these jobs in dependency order.
- */
+struct drm_rocket_submit {
/** Input: Pointer to an array of struct drm_rocket_job. */
__u64 jobs;
/** Input: Number of jobs passed in. */
__u32 job_count;
Isn't there a problem if you need to expand drm_rocket_job beyond using the 1 reserved field? You can't add to the struct because then you don't know the size here. So you have to modify drm_rocket_submit to modify drm_rocket_job. Maybe better if you plan for that now rather than later by making the size explicit.
Though etnaviv at least has similar issues.
Rob
/** Reserved, must be zero. */
__u32 reserved;
+};
linaro-mm-sig@lists.linaro.org