[PATCH v2 15/17] media: rockchip: rga: bind all cores to the master
From: Sven Püschel
Date: Wed Sep 16 2026 - 11:30:17 EST
Bind all core components to the master component. Previously only the
first core has been added to the master device to avoid creating
multiple video devices. As the video device creation has been moved to
the master component, it allows us to bind all cores without creating
additional video devices.
We expect that all cores to report the same version number, as we only
add cores with the same compatible value. This is important, as we
setup the command buffer before actually scheduling the work to a
specific core. Therefore adjusting command buffers depending on the
version register only works when all cores have the same value.
Signed-off-by: Sven Püschel <s.pueschel@xxxxxxxxxxxxxx>
---
v2:
- Fail (instead of warn) on a multi-core version mismatch
- Also decrease the num_cores when unbinding a core
(https://sashiko.dev/#/patchset/20260606-spu-rga3multicore-v1-0-3ec2b15675f7%40pengutronix.de?part=13)
- move rga->cores at the end of core_bind here
(previously done while moving code to rga_core_probe)
---
drivers/media/platform/rockchip/rga/rga.c | 36 +++++++++++++++++++++----------
drivers/media/platform/rockchip/rga/rga.h | 1 +
2 files changed, 26 insertions(+), 11 deletions(-)
diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/platform/rockchip/rga/rga.c
index 39fcb5623095b..5348fcc03c525 100644
--- a/drivers/media/platform/rockchip/rga/rga.c
+++ b/drivers/media/platform/rockchip/rga/rga.c
@@ -746,23 +746,33 @@ static int rga_core_bind(struct device *dev, struct device *master, void *data)
{
struct rockchip_rga *rga = data;
struct rga_core *core = dev_get_drvdata(dev);
+ struct rockchip_rga_version version;
int ret = 0;
core->rga = rga;
- rga->cores[0] = core;
-
ret = pm_runtime_resume_and_get(core->dev);
if (ret < 0)
return ret;
- rga->version = rga->hw->get_version(core);
+ version = rga->hw->get_version(core);
v4l2_info(&rga->v4l2_dev, "HW Version: 0x%02x.%02x\n",
rga->version.major, rga->version.minor);
+ if (rga->num_cores) {
+ /* we are not the first core, expect that we have the same version */
+ if (rga->version.major != version.major || rga->version.minor != version.minor) {
+ v4l2_err(&rga->v4l2_dev, "Detected multi-core setup with different core versions!\n");
+ return -ENODEV;
+ }
+ } else
+ rga->version = version;
+
pm_runtime_put(core->dev);
+ rga->cores[rga->num_cores++] = core;
+
return 0;
}
@@ -770,6 +780,18 @@ static void rga_core_unbind(struct device *dev, struct device *master,
void *data)
{
struct rga_core *core = dev_get_drvdata(dev);
+ struct rockchip_rga *rga = core->rga;
+ u8 i;
+
+ /* Remove our core from the list */
+ for (i = 0; i < rga->num_cores; i++) {
+ if (rga->cores[i] != core)
+ continue;
+
+ rga->cores[i] = rga->cores[rga->num_cores - 1];
+ rga->num_cores--;
+ break;
+ }
core->rga = NULL;
}
@@ -992,14 +1014,6 @@ static int rga_probe(struct platform_device *pdev)
component_match_add_release(dev, &match, component_release_of,
component_compare_of, core_node);
num_cores++;
-
- /*
- * As multi core is not implemented yet,
- * break out of the loop to only have one core per rockchip_rga struct.
- * Also put the node, which otherwise would've been done by the loop iteration.
- */
- of_node_put(core_node);
- break;
}
rga = devm_kzalloc(dev, sizeof(*rga) + num_cores * sizeof(*rga->cores), GFP_KERNEL);
diff --git a/drivers/media/platform/rockchip/rga/rga.h b/drivers/media/platform/rockchip/rga/rga.h
index 94e14c2a2ba6e..522021c3e0249 100644
--- a/drivers/media/platform/rockchip/rga/rga.h
+++ b/drivers/media/platform/rockchip/rga/rga.h
@@ -89,6 +89,7 @@ struct rockchip_rga {
const struct rga_hw *hw;
+ u8 num_cores;
struct rga_core *cores[];
};
--
2.55.0