[PATCH 15/17] media: rockchip: rga: schedule jobs to multiple cores

From: Sven Püschel

Date: Fri Jun 05 2026 - 18:17:04 EST


Schedule jobs to multiple cores to utilize all RGA cores. To avoid race
conditions when selecting the next free core a dedicated spinlock is added.

Note that this doesn't increase the max frame rate of a single
stream, as a context will wait for the job to finish before starting
the next device_run call.

Signed-off-by: Sven Püschel <s.pueschel@xxxxxxxxxxxxxx>
---
drivers/media/platform/rockchip/rga/rga.c | 22 +++++++++++++++++++---
drivers/media/platform/rockchip/rga/rga.h | 1 +
2 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/platform/rockchip/rga/rga.c
index 9cebb461b3fd2..f00b7f99f2521 100644
--- a/drivers/media/platform/rockchip/rga/rga.c
+++ b/drivers/media/platform/rockchip/rga/rga.c
@@ -38,15 +38,31 @@ static void device_run(void *prv)
{
struct rga_ctx *ctx = prv;
struct rockchip_rga *rga = ctx->rga;
- struct rga_core *core = rga->cores[0];
+ struct rga_core *core = NULL;
struct vb2_v4l2_buffer *src, *dst;
unsigned long flags;
int ret;
+ unsigned int i;
+
+ spin_lock_irqsave(&rga->cores_lock, flags);
+ for (i = 0; i < rga->num_cores; i++) {
+ if (!rga->cores[i]->curr) {
+ core = rga->cores[i];
+ core->curr = ctx;
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&rga->cores_lock, flags);
+
+ WARN_ONCE(!core, "No free core although max parallel jobs matches the core count!\n");
+ if (!core)
+ return;

ret = pm_runtime_resume_and_get(core->dev);
if (ret < 0) {
v4l2_m2m_buf_done_and_job_finish(rga->m2m_dev, ctx->fh.m2m_ctx,
VB2_BUF_STATE_ERROR);
+ core->curr = NULL;
return;
}

@@ -58,8 +74,6 @@ static void device_run(void *prv)
}
spin_unlock_irqrestore(&rga->ctrl_lock, flags);

- core->curr = ctx;
-
src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
src->sequence = ctx->osequence++;

@@ -946,6 +960,7 @@ static int rga_bind(struct device *dev)
ret = PTR_ERR(rga->m2m_dev);
goto rel_vdev;
}
+ v4l2_m2m_set_max_parallel_jobs(rga->m2m_dev, rga->num_cores);

ret = video_register_device(vfd, VFL_TYPE_VIDEO, -1);
if (ret) {
@@ -1021,6 +1036,7 @@ static int rga_probe(struct platform_device *pdev)
return dev_err_probe(dev, -ENODEV, "failed to get match data\n");

spin_lock_init(&rga->ctrl_lock);
+ spin_lock_init(&rga->cores_lock);
mutex_init(&rga->mutex);

dev_set_drvdata(dev, rga);
diff --git a/drivers/media/platform/rockchip/rga/rga.h b/drivers/media/platform/rockchip/rga/rga.h
index 6237436b984eb..c0dfacdb6f212 100644
--- a/drivers/media/platform/rockchip/rga/rga.h
+++ b/drivers/media/platform/rockchip/rga/rga.h
@@ -85,6 +85,7 @@ struct rockchip_rga {
struct mutex mutex;
/* ctrl parm lock */
spinlock_t ctrl_lock;
+ spinlock_t cores_lock;

const struct rga_hw *hw;


--
2.54.0