[PATCH 5/5] accel/rocket: Use per-task interrupt mask and handle PPU completion interrupts

From: Ross Cawston

Date: Tue Feb 17 2026 - 16:40:55 EST


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@xxxxxxx>
---
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