[PATCH v2 15/17] media: rockchip: rga: bind all cores to the master
From: Sven Püschel <hidden>
Date: 2026-09-16 15:15:23
Also in:
linux-media, linux-rockchip, lkml
Subsystem:
arm/rockchip soc support, media input infrastructure (v4l/dvb), rockchip raster 2d graphic acceleration unit driver, the rest · Maintainers:
Heiko Stuebner, Mauro Carvalho Chehab, Jacob Chen, Ezequiel Garcia, Linus Torvalds
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 <redacted> --- 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