* [PATCH 1/5] accel/rocket: Fix error path in BO creation
2026-02-17 21:39 [PATCH 0/5] accel/rocket: Support standalone DPU/PPU tasks and pipelined workloads Ross Cawston
@ 2026-02-17 21:39 ` Ross Cawston
2026-02-17 21:39 ` [PATCH 2/5] accel/rocket: Enable ping-pong mode only for multi-task jobs Ross Cawston
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Ross Cawston @ 2026-02-17 21:39 UTC (permalink / raw)
To: Tomeu Vizoso, Oded Gabbay, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter
Cc: dri-devel, linux-kernel, Ross Cawston
Check the return value of iommu_map_sgtable() after releasing the
mm_lock. Previously an error would be silently ignored.
Signed-off-by: Ross Cawston <ross@r-sc.ca>
---
drivers/accel/rocket/rocket_gem.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/accel/rocket/rocket_gem.c b/drivers/accel/rocket/rocket_gem.c
index 624c4ecf5a34..db1ff3544af2 100644
--- a/drivers/accel/rocket/rocket_gem.c
+++ b/drivers/accel/rocket/rocket_gem.c
@@ -95,6 +95,8 @@ int rocket_ioctl_create_bo(struct drm_device *dev, void *data, struct drm_file *
rkt_obj->size, PAGE_SIZE,
0, 0);
mutex_unlock(&rocket_priv->mm_lock);
+ if (ret)
+ goto err;
ret = iommu_map_sgtable(rocket_priv->domain->domain,
rkt_obj->mm.start,
--
2.52.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 2/5] accel/rocket: Enable ping-pong mode only for multi-task jobs
2026-02-17 21:39 [PATCH 0/5] accel/rocket: Support standalone DPU/PPU tasks and pipelined workloads Ross Cawston
2026-02-17 21:39 ` [PATCH 1/5] accel/rocket: Fix error path in BO creation Ross Cawston
@ 2026-02-17 21:39 ` Ross Cawston
2026-02-17 21:39 ` [PATCH 3/5] accel/rocket: Add per-task flags and interrupt mask to UAPI and kernel Ross Cawston
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Ross Cawston @ 2026-02-17 21:39 UTC (permalink / raw)
To: Tomeu Vizoso, Oded Gabbay, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter
Cc: dri-devel, linux-kernel, Ross Cawston
Ping-pong mode (PC_TASK_CON_TASK_PP_EN) is required for chaining multiple
tasks in a job, but is unnecessary overhead for single-task jobs.
Set it conditionally based on job->task_count to avoid pointless buffer
management cycles and slightly reduce per-job latency/power on simple
workloads.
No functional change or risk of corruption for existing jobs - backward
compatible.
Signed-off-by: Ross Cawston <ross@r-sc.ca>
---
drivers/accel/rocket/rocket_job.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/accel/rocket/rocket_job.c b/drivers/accel/rocket/rocket_job.c
index acd606160dc9..369b60805d5f 100644
--- a/drivers/accel/rocket/rocket_job.c
+++ b/drivers/accel/rocket/rocket_job.c
@@ -143,7 +143,7 @@ static void rocket_job_hw_submit(struct rocket_core *core, struct rocket_job *jo
rocket_pc_writel(core, TASK_CON, PC_TASK_CON_RESERVED_0(1) |
PC_TASK_CON_TASK_COUNT_CLEAR(1) |
PC_TASK_CON_TASK_NUMBER(1) |
- PC_TASK_CON_TASK_PP_EN(1));
+ PC_TASK_CON_TASK_PP_EN(job->task_count > 1 ? 1 : 0));
rocket_pc_writel(core, TASK_DMA_BASE_ADDR, PC_TASK_DMA_BASE_ADDR_DMA_BASE_ADDR(0x0));
--
2.52.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 3/5] accel/rocket: Add per-task flags and interrupt mask to UAPI and kernel
2026-02-17 21:39 [PATCH 0/5] accel/rocket: Support standalone DPU/PPU tasks and pipelined workloads Ross Cawston
2026-02-17 21:39 ` [PATCH 1/5] accel/rocket: Fix error path in BO creation Ross Cawston
2026-02-17 21:39 ` [PATCH 2/5] accel/rocket: Enable ping-pong mode only for multi-task jobs Ross Cawston
@ 2026-02-17 21:39 ` Ross Cawston
2026-02-17 21:39 ` [PATCH 4/5] accel/rocket: Skip CNA/Core S_POINTER initialization for standalone tasks Ross Cawston
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Ross Cawston @ 2026-02-17 21:39 UTC (permalink / raw)
To: Tomeu Vizoso, Oded Gabbay, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter
Cc: dri-devel, linux-kernel, Ross Cawston
Add two new fields to struct drm_rocket_task (UAPI) and struct rocket_task
(kernel):
- u32 int_mask: which block completion interrupt(s) should signal task done
- u32 flags: currently only ROCKET_TASK_SKIP_CNA_CORE
In rocket_copy_tasks():
- copy the new fields
- default int_mask to DPU_0 | DPU_1 when userspace passes zero (backward compatible)
No functional change yet - old userspace continues to work unchanged.
Signed-off-by: Ross Cawston <ross@r-sc.ca>
---
drivers/accel/rocket/rocket_job.c | 8 ++++++++
drivers/accel/rocket/rocket_job.h | 2 ++
include/uapi/drm/rocket_accel.h | 25 +++++++++++++++++++++++++
3 files changed, 35 insertions(+)
diff --git a/drivers/accel/rocket/rocket_job.c b/drivers/accel/rocket/rocket_job.c
index 369b60805d5f..34898084cc56 100644
--- a/drivers/accel/rocket/rocket_job.c
+++ b/drivers/accel/rocket/rocket_job.c
@@ -96,6 +96,14 @@ rocket_copy_tasks(struct drm_device *dev,
rjob->tasks[i].regcmd = task.regcmd;
rjob->tasks[i].regcmd_count = task.regcmd_count;
+ rjob->tasks[i].int_mask = task.int_mask;
+ rjob->tasks[i].flags = task.flags;
+
+ /* Default to DPU completion if no mask specified */
+ if (!rjob->tasks[i].int_mask) {
+ rjob->tasks[i].int_mask = PC_INTERRUPT_MASK_DPU_0 |
+ PC_INTERRUPT_MASK_DPU_1;
+ }
}
return 0;
diff --git a/drivers/accel/rocket/rocket_job.h b/drivers/accel/rocket/rocket_job.h
index 4ae00feec3b9..6931dfed8615 100644
--- a/drivers/accel/rocket/rocket_job.h
+++ b/drivers/accel/rocket/rocket_job.h
@@ -13,6 +13,8 @@
struct rocket_task {
u64 regcmd;
u32 regcmd_count;
+ u32 int_mask;
+ u32 flags;
};
struct rocket_job {
diff --git a/include/uapi/drm/rocket_accel.h b/include/uapi/drm/rocket_accel.h
index d0685e372b79..ae0d8e48afcd 100644
--- a/include/uapi/drm/rocket_accel.h
+++ b/include/uapi/drm/rocket_accel.h
@@ -90,6 +90,11 @@ struct drm_rocket_fini_bo {
__u32 reserved;
};
+/**
+ * Flags for drm_rocket_task.flags
+ */
+#define ROCKET_TASK_SKIP_CNA_CORE 0x1
+
/**
* struct drm_rocket_task - A task to be run on the NPU
*
@@ -106,6 +111,26 @@ struct drm_rocket_task {
* buffer
*/
__u32 regcmd_count;
+
+ /**
+ * Input: Interrupt mask specifying which block completion signals
+ * that this task is done. Uses PC_INTERRUPT_MASK_* bits.
+ *
+ * For conv/DPU tasks: DPU_0 | DPU_1 (0x0300)
+ * For PPU tasks: PPU_0 | PPU_1 (0x0C00)
+ *
+ * If zero, defaults to DPU_0 | DPU_1 for backwards compatibility.
+ */
+ __u32 int_mask;
+
+ /**
+ * Input: Task flags.
+ *
+ * ROCKET_TASK_SKIP_CNA_CORE: Skip CNA and Core S_POINTER MMIO
+ * writes for this task. Used for standalone DPU element-wise
+ * and PPU pooling tasks that don't use CNA/Core.
+ */
+ __u32 flags;
};
/**
--
2.52.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 4/5] accel/rocket: Skip CNA/Core S_POINTER initialization for standalone tasks
2026-02-17 21:39 [PATCH 0/5] accel/rocket: Support standalone DPU/PPU tasks and pipelined workloads Ross Cawston
` (2 preceding siblings ...)
2026-02-17 21:39 ` [PATCH 3/5] accel/rocket: Add per-task flags and interrupt mask to UAPI and kernel Ross Cawston
@ 2026-02-17 21:39 ` Ross Cawston
2026-02-17 21:39 ` [PATCH 5/5] accel/rocket: Use per-task interrupt mask and handle PPU completion interrupts Ross Cawston
2026-07-06 19:27 ` [PATCH 0/5] accel/rocket: Support standalone DPU/PPU tasks and pipelined workloads Heiko Stübner
5 siblings, 0 replies; 7+ messages in thread
From: Ross Cawston @ 2026-02-17 21:39 UTC (permalink / raw)
To: Tomeu Vizoso, Oded Gabbay, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter
Cc: dri-devel, linux-kernel, Ross Cawston
Standalone DPU (element-wise) and PPU (pooling, etc.) tasks do not use
the CNA or Core blocks. Writing S_POINTER to those blocks re-arms them
with stale/uninitialized state, leading to corruption.
Introduce ROCKET_TASK_SKIP_CNA_CORE flag (added in previous patch) so
userspace can indicate such tasks. When set, skip the CNA and Core
S_POINTER MMIO writes.
Also move the per-core extra bit (bit 28 × core index) inside the same
conditional - it is only needed when CNA/Core are actually used.
Signed-off-by: Ross Cawston <ross@r-sc.ca>
---
drivers/accel/rocket/rocket_job.c | 41 +++++++++++++++++++++++++++------------
1 file changed, 29 insertions(+), 12 deletions(-)
diff --git a/drivers/accel/rocket/rocket_job.c b/drivers/accel/rocket/rocket_job.c
index 34898084cc56..1dcc0c945f7f 100644
--- a/drivers/accel/rocket/rocket_job.c
+++ b/drivers/accel/rocket/rocket_job.c
@@ -116,7 +116,6 @@ rocket_copy_tasks(struct drm_device *dev,
static void rocket_job_hw_submit(struct rocket_core *core, struct rocket_job *job)
{
struct rocket_task *task;
- unsigned int extra_bit;
/* Don't queue the job if a reset is in progress */
if (atomic_read(&core->reset.pending))
@@ -129,17 +128,35 @@ static void rocket_job_hw_submit(struct rocket_core *core, struct rocket_job *jo
rocket_pc_writel(core, BASE_ADDRESS, 0x1);
- /* From rknpu, in the TRM this bit is marked as reserved */
- extra_bit = 0x10000000 * core->index;
- rocket_cna_writel(core, S_POINTER, CNA_S_POINTER_POINTER_PP_EN(1) |
- CNA_S_POINTER_EXECUTER_PP_EN(1) |
- CNA_S_POINTER_POINTER_PP_MODE(1) |
- extra_bit);
-
- rocket_core_writel(core, S_POINTER, CORE_S_POINTER_POINTER_PP_EN(1) |
- CORE_S_POINTER_EXECUTER_PP_EN(1) |
- CORE_S_POINTER_POINTER_PP_MODE(1) |
- extra_bit);
+ /*
+ * Initialize CNA and Core S_POINTER for ping-pong mode via MMIO.
+ *
+ * Each core needs a per-core extra_bit (bit 28 * core_index) which
+ * the TRM marks as reserved but the BSP rknpu driver sets. Without
+ * it, non-zero cores hang. This MUST be done via MMIO (not regcmd)
+ * because userspace doesn't know which core the scheduler picks.
+ *
+ * For standalone DPU/PPU tasks (element-wise ops, pooling), CNA
+ * and Core have no work. Writing their S_POINTERs would re-arm
+ * them with stale state from the previous conv task, corrupting
+ * the DPU/PPU output. Userspace signals this via the
+ * ROCKET_TASK_SKIP_CNA_CORE flag.
+ */
+ if (!(task->flags & ROCKET_TASK_SKIP_CNA_CORE)) {
+ unsigned int extra_bit = 0x10000000 * core->index;
+
+ rocket_cna_writel(core, S_POINTER,
+ CNA_S_POINTER_POINTER_PP_EN(1) |
+ CNA_S_POINTER_EXECUTER_PP_EN(1) |
+ CNA_S_POINTER_POINTER_PP_MODE(1) |
+ extra_bit);
+
+ rocket_core_writel(core, S_POINTER,
+ CORE_S_POINTER_POINTER_PP_EN(1) |
+ CORE_S_POINTER_EXECUTER_PP_EN(1) |
+ CORE_S_POINTER_POINTER_PP_MODE(1) |
+ extra_bit);
+ }
rocket_pc_writel(core, BASE_ADDRESS, task->regcmd);
rocket_pc_writel(core, REGISTER_AMOUNTS,
--
2.52.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 5/5] accel/rocket: Use per-task interrupt mask and handle PPU completion interrupts
2026-02-17 21:39 [PATCH 0/5] accel/rocket: Support standalone DPU/PPU tasks and pipelined workloads Ross Cawston
` (3 preceding siblings ...)
2026-02-17 21:39 ` [PATCH 4/5] accel/rocket: Skip CNA/Core S_POINTER initialization for standalone tasks Ross Cawston
@ 2026-02-17 21:39 ` Ross Cawston
2026-07-06 19:27 ` [PATCH 0/5] accel/rocket: Support standalone DPU/PPU tasks and pipelined workloads Heiko Stübner
5 siblings, 0 replies; 7+ messages in thread
From: Ross Cawston @ 2026-02-17 21:39 UTC (permalink / raw)
To: Tomeu Vizoso, Oded Gabbay, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter
Cc: dri-devel, linux-kernel, Ross Cawston
The current driver hard-codes interrupt mask and clear to DPU_0 | DPU_1
and only checks DPU completion in the IRQ handler. This causes timeouts
on PPU-only tasks and DPU→PPU pipelined jobs.
Use the new per-task int_mask field to set INTERRUPT_MASK to the
correct terminal block(s):
- conv / standalone DPU → DPU_0 | DPU_1
- PPU / DPU→PPU pipeline → PPU_0 | PPU_1
Also:
- clear all relevant interrupt bits (0x1ffff) instead of just DPU
- accept PPU_0 / PPU_1 completions in the IRQ handler
Fixes correct completion detection for non-convolutional and pipelined
workloads.
Signed-off-by: Ross Cawston <ross@r-sc.ca>
---
drivers/accel/rocket/rocket_job.c | 29 +++++++++++++++++++++++++----
1 file changed, 25 insertions(+), 4 deletions(-)
diff --git a/drivers/accel/rocket/rocket_job.c b/drivers/accel/rocket/rocket_job.c
index 1dcc0c945f7f..ce54913baa46 100644
--- a/drivers/accel/rocket/rocket_job.c
+++ b/drivers/accel/rocket/rocket_job.c
@@ -162,8 +162,20 @@ static void rocket_job_hw_submit(struct rocket_core *core, struct rocket_job *jo
rocket_pc_writel(core, REGISTER_AMOUNTS,
PC_REGISTER_AMOUNTS_PC_DATA_AMOUNT((task->regcmd_count + 1) / 2 - 1));
- rocket_pc_writel(core, INTERRUPT_MASK, PC_INTERRUPT_MASK_DPU_0 | PC_INTERRUPT_MASK_DPU_1);
- rocket_pc_writel(core, INTERRUPT_CLEAR, PC_INTERRUPT_CLEAR_DPU_0 | PC_INTERRUPT_CLEAR_DPU_1);
+ /*
+ * Enable interrupts for the last block in this task's pipeline.
+ *
+ * The int_mask field from userspace specifies which block completion
+ * signals that this task is done:
+ * - Conv/DPU tasks: DPU_0 | DPU_1
+ * - PPU tasks (DPU→PPU pipeline): PPU_0 | PPU_1
+ *
+ * Only enabling the terminal block's interrupt prevents the kernel
+ * from stopping the pipeline early (e.g. DPU fires before PPU has
+ * finished writing its output).
+ */
+ rocket_pc_writel(core, INTERRUPT_MASK, task->int_mask);
+ rocket_pc_writel(core, INTERRUPT_CLEAR, 0x1ffff);
rocket_pc_writel(core, TASK_CON, PC_TASK_CON_RESERVED_0(1) |
PC_TASK_CON_TASK_COUNT_CLEAR(1) |
@@ -449,8 +461,17 @@ static irqreturn_t rocket_job_irq_handler(int irq, void *data)
WARN_ON(raw_status & PC_INTERRUPT_RAW_STATUS_DMA_READ_ERROR);
WARN_ON(raw_status & PC_INTERRUPT_RAW_STATUS_DMA_WRITE_ERROR);
- if (!(raw_status & PC_INTERRUPT_RAW_STATUS_DPU_0 ||
- raw_status & PC_INTERRUPT_RAW_STATUS_DPU_1))
+ /*
+ * Check for any job completion interrupt: DPU or PPU.
+ *
+ * Conv and standalone DPU jobs signal via DPU_0/DPU_1.
+ * PPU pooling jobs signal via PPU_0/PPU_1.
+ * We must recognize both to avoid PPU job timeouts.
+ */
+ if (!(raw_status & (PC_INTERRUPT_RAW_STATUS_DPU_0 |
+ PC_INTERRUPT_RAW_STATUS_DPU_1 |
+ PC_INTERRUPT_RAW_STATUS_PPU_0 |
+ PC_INTERRUPT_RAW_STATUS_PPU_1)))
return IRQ_NONE;
rocket_pc_writel(core, INTERRUPT_MASK, 0x0);
--
2.52.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH 0/5] accel/rocket: Support standalone DPU/PPU tasks and pipelined workloads
2026-02-17 21:39 [PATCH 0/5] accel/rocket: Support standalone DPU/PPU tasks and pipelined workloads Ross Cawston
` (4 preceding siblings ...)
2026-02-17 21:39 ` [PATCH 5/5] accel/rocket: Use per-task interrupt mask and handle PPU completion interrupts Ross Cawston
@ 2026-07-06 19:27 ` Heiko Stübner
5 siblings, 0 replies; 7+ messages in thread
From: Heiko Stübner @ 2026-07-06 19:27 UTC (permalink / raw)
To: Tomeu Vizoso, Oded Gabbay, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, dri-devel
Cc: dri-devel, linux-kernel, Ross Cawston, Ross Cawston
Hi Ross,
Am Dienstag, 17. Februar 2026, 22:39:48 Mitteleuropäische Sommerzeit schrieb Ross Cawston:
> The Rocket NPU supports multiple workload types beyond convolutional jobs:
> - Standalone post-processing (PPU) tasks (pooling, element-wise ops, etc.)
> - Pipelined DPU→PPU workloads
>
> The current driver has limitations preventing these from working correctly:
> - CNA/Core S_POINTER registers are always written, re-arming stale state
> - Interrupt handling is hard-coded to DPU only, causing PPU timeouts
> - Ping-pong mode is always enabled
>
> This series fixes these while preserving backward compatibility.
>
> Patch breakdown:
> 1/5 Fix error path in BO creation (cleanup/fix)
> 2/5 Enable ping-pong mode only for multi-task jobs (optimization)
> 3/5 Add per-task int_mask and flags to UAPI/kernel (new knobs)
> 4/5 Skip CNA/Core S_POINTER init for standalone tasks
> 5/5 Use per-task interrupt mask and handle PPU completions
>
> Derived from vendor BSP behavior.
>
> Tested on OrangePi 5 Ultra and Radxa Rock 5B (RK3588).
>
> Thanks for review!
Extending Rocket's range sounds really cool.
Curious me wants to know how to test these new parts.
I was assuming some mesa thing, but didn't find a PR for it, so it
must be something else?
Thanks a lot
Heiko
> Signed-off-by: Ross Cawston <ross@r-sc.ca>
> ---
> Ross Cawston (5):
> accel/rocket: Fix error path in BO creation
> accel/rocket: Enable ping-pong mode only for multi-task jobs
> accel/rocket: Add per-task flags and interrupt mask to UAPI and kernel
> accel/rocket: Skip CNA/Core S_POINTER initialization for standalone tasks
> accel/rocket: Use per-task interrupt mask and handle PPU completion interrupts
>
> drivers/accel/rocket/rocket_gem.c | 2 +
> drivers/accel/rocket/rocket_job.c | 80 ++++++++++++++++++++++++++++++---------
> drivers/accel/rocket/rocket_job.h | 2 +
> include/uapi/drm/rocket_accel.h | 25 ++++++++++++
> 4 files changed, 92 insertions(+), 17 deletions(-)
> ---
> base-commit: 17f8d2009367c3da82882f70ccbdca9f8c7b5f20
> change-id: 20260217-accel-rocket-clean-base-57c0e88651e6
>
> Best regards,
>
^ permalink raw reply [flat|nested] 7+ messages in thread