From nobody Fri Sep 25 04:43:51 2026 Received: from mx1.white.stw.pengutronix.de (mx1.white.stw.pengutronix.de [185.203.200.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D56412561A2; Wed, 16 Sep 2026 15:09:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.200.13 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789571392; cv=none; b=YcHUdwLf84lDHnLJ3q8K8xNEurrWT+Aa1MZwTS38yaXCNiCn/Zd+Y9s9Ab8S6Z6zDyxH9tfWkZmNDeh8tVOnspyZhaJk2lDvOooC3f2hHdSfz/SGNt0Tt6dwNO/ARDQbSznMOnOijJO54M8gQF03rPwLZfGi5N5YECngfaHPCtE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789571392; c=relaxed/simple; bh=LCfWlMyulSCbWE4yYcWf7ZdZcQMd2XNaUgsH9b4WqKw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=nRrqr7EVzqcRxBEKasHzT9fZoPvQHv24r1xUqq71p4qT4OeJo9cPyBjUHiPuW0+d27dtVAW4K6SCQPsop73qwY3Kt4YF7CLk/JOpVnNOfCoUfbuNqhMgWz1cwAycmf+FMEoWfZmXZ1jKJfW4Fvsp+xEAzFDGK+HiY+65II5T/hY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.200.13 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de X-PTX-Original-Recipient: ezequiel@vanguardiasur.com.ar X-PTX-Original-Recipient: jacob-chen@iotwrt.com X-PTX-Original-Recipient: mchehab@kernel.org X-PTX-Original-Recipient: detlev.casanova@collabora.com X-PTX-Original-Recipient: heiko@sntech.de X-PTX-Original-Recipient: linux-kernel@vger.kernel.org X-PTX-Original-Recipient: linux-media@vger.kernel.org X-PTX-Original-Recipient: linux-arm-kernel@lists.infradead.org X-PTX-Original-Recipient: linux-rockchip@lists.infradead.org X-PTX-Original-Recipient: lgs201920130244@gmail.com X-PTX-Original-Recipient: p.zabel@pengutronix.de X-PTX-Original-Recipient: kernel@pengutronix.de X-PTX-Original-Recipient: s.pueschel@pengutronix.de X-PTX-Original-Recipient: m.tretter@pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de (drehscheibe.grey.stw.pengutronix.de [IPv6:2a0a:edc0:0:c01:1d::a2]) (Authenticated sender: relay-from-drehscheibe.grey.stw.pengutronix.de) by mx1.white.stw.pengutronix.de (Postfix) with ESMTPSA id 174532020F4; Wed, 16 Sep 2026 17:09:47 +0200 (CEST) Received: from ptz.office.stw.pengutronix.de ([2a0a:edc0:0:900:1d::77] helo=peter.mobile.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtp (Exim 4.96) (envelope-from ) id 1x6rGc-001Fsx-37; Wed, 16 Sep 2026 17:09:47 +0200 From: =?utf-8?q?Sven_P=C3=BCschel?= Date: Wed, 16 Sep 2026 17:09:42 +0200 Subject: [PATCH v2 01/17] media: rockchip: rga: zero cmdbuf in shared code Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260916-spu-rga3multicore-v2-1-23aa2cb74e61@pengutronix.de> References: <20260916-spu-rga3multicore-v2-0-23aa2cb74e61@pengutronix.de> In-Reply-To: <20260916-spu-rga3multicore-v2-0-23aa2cb74e61@pengutronix.de> To: Jacob Chen , Ezequiel Garcia , Mauro Carvalho Chehab , Heiko Stuebner , Philipp Zabel Cc: linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, kernel@pengutronix.de, Detlev Casanova , Michael Tretter , Guangshuo Li , =?utf-8?q?Sven_P=C3=BCschel?= X-Mailer: b4 0.15.2 Zero the command buffer (cmdbuf) in the shared code instead of the individual RGA2/RGA3 implementations. Besides centralizing the memset operation this also uses the cmdbuf_size member for the memset size, which is also used as the size for the actual allocation. Signed-off-by: Sven P=C3=BCschel --- drivers/media/platform/rockchip/rga/rga-hw.c | 2 -- drivers/media/platform/rockchip/rga/rga.c | 1 + drivers/media/platform/rockchip/rga/rga.h | 3 +++ drivers/media/platform/rockchip/rga/rga3-hw.c | 2 -- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/rockchip/rga/rga-hw.c b/drivers/media/p= latform/rockchip/rga/rga-hw.c index be1bc8ddbd03b..4d7b0a03820a1 100644 --- a/drivers/media/platform/rockchip/rga/rga-hw.c +++ b/drivers/media/platform/rockchip/rga/rga-hw.c @@ -443,8 +443,6 @@ static void rga_cmd_set(struct rga_ctx *ctx, =20 static void rga_hw_setup_cmdbuf(struct rga_ctx *ctx) { - memset(ctx->cmdbuf_virt, 0, RGA_CMDBUF_SIZE); - rga_cmd_set_mode(ctx); rga_cmd_set_trans_info(ctx); } diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/plat= form/rockchip/rga/rga.c index b3cb6bf8eb863..bd0afd33affe4 100644 --- a/drivers/media/platform/rockchip/rga/rga.c +++ b/drivers/media/platform/rockchip/rga/rga.c @@ -41,6 +41,7 @@ static void device_run(void *prv) spin_lock_irqsave(&rga->ctrl_lock, flags); if (ctx->cmdbuf_dirty) { ctx->cmdbuf_dirty =3D false; + memset(ctx->cmdbuf_virt, 0, rga->hw->cmdbuf_size); rga->hw->setup_cmdbuf(ctx); } spin_unlock_irqrestore(&rga->ctrl_lock, flags); diff --git a/drivers/media/platform/rockchip/rga/rga.h b/drivers/media/plat= form/rockchip/rga/rga.h index bd431534d0d39..2b4f5694375a4 100644 --- a/drivers/media/platform/rockchip/rga/rga.h +++ b/drivers/media/platform/rockchip/rga/rga.h @@ -152,6 +152,9 @@ struct rga_hw { u8 stride_alignment; u8 features; =20 + /* + * Requires that the cmdbuf is already zeroed. + */ void (*setup_cmdbuf)(struct rga_ctx *ctx); void (*start)(struct rockchip_rga *rga, struct rga_vb_buffer *src, struct rga_vb_buffer *dst); diff --git a/drivers/media/platform/rockchip/rga/rga3-hw.c b/drivers/media/= platform/rockchip/rga/rga3-hw.c index c4a71306278ba..46ba6d270f232 100644 --- a/drivers/media/platform/rockchip/rga/rga3-hw.c +++ b/drivers/media/platform/rockchip/rga/rga3-hw.c @@ -261,8 +261,6 @@ static void rga3_cmd_set_wr_format(struct rga_ctx *ctx) =20 static void rga3_hw_setup_cmdbuf(struct rga_ctx *ctx) { - memset(ctx->cmdbuf_virt, 0, RGA3_CMDBUF_SIZE); - rga3_cmd_set_win0_format(ctx); rga3_cmd_set_trans_info(ctx); rga3_cmd_set_wr_format(ctx); --=20 2.55.0 From nobody Fri Sep 25 04:43:51 2026 Received: from mx1.white.stw.pengutronix.de (mx1.white.stw.pengutronix.de [185.203.200.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BDEB836A374; Wed, 16 Sep 2026 15:09:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.200.13 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789571391; cv=none; b=mIx/UsZjlO7ayetfyHBKabTVb0UOc4N0jFCeTgh58zKCKN57G6Yg3fpBGWpbxT0SP4Fn+3YBrI6b7vr/ZfJOO23wiUD/rNGSuOxQajzJF6oLr1++LTrEHUwxGEXfZoAYk/hgZ4Q3IGzyMUpBSV7R2O91lKLjV/LVfXH0Yxmdybo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789571391; c=relaxed/simple; bh=v/YOzl4wt8ytYX4K8Ic7RoOs5A/Frfh4PmR1atoRt2U=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=tAzmoGD2V7tIeDoehRARemVX0ce+uqS50/xUJ2eAJ4mLBB+hZ2DadK4vdBPpKDXrkHDa8VM5YC+AN8E1+y3h19tXbvrdePHYb4zIsgOoubsVyFiZIyZnAQWVGG4Seb6ZZ7Qqy0I/uVE96eoAXXPIx86E0ILdivdemPFIr1rthEs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.200.13 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de X-PTX-Original-Recipient: ezequiel@vanguardiasur.com.ar X-PTX-Original-Recipient: jacob-chen@iotwrt.com X-PTX-Original-Recipient: mchehab@kernel.org X-PTX-Original-Recipient: detlev.casanova@collabora.com X-PTX-Original-Recipient: heiko@sntech.de X-PTX-Original-Recipient: linux-kernel@vger.kernel.org X-PTX-Original-Recipient: linux-media@vger.kernel.org X-PTX-Original-Recipient: linux-arm-kernel@lists.infradead.org X-PTX-Original-Recipient: linux-rockchip@lists.infradead.org X-PTX-Original-Recipient: lgs201920130244@gmail.com X-PTX-Original-Recipient: p.zabel@pengutronix.de X-PTX-Original-Recipient: kernel@pengutronix.de X-PTX-Original-Recipient: s.pueschel@pengutronix.de X-PTX-Original-Recipient: m.tretter@pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de (drehscheibe.grey.stw.pengutronix.de [IPv6:2a0a:edc0:0:c01:1d::a2]) (Authenticated sender: relay-from-drehscheibe.grey.stw.pengutronix.de) by mx1.white.stw.pengutronix.de (Postfix) with ESMTPSA id C10552059ED; Wed, 16 Sep 2026 17:09:47 +0200 (CEST) Received: from ptz.office.stw.pengutronix.de ([2a0a:edc0:0:900:1d::77] helo=peter.mobile.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtp (Exim 4.96) (envelope-from ) id 1x6rGd-001Fsx-2A; Wed, 16 Sep 2026 17:09:47 +0200 From: =?utf-8?q?Sven_P=C3=BCschel?= Date: Wed, 16 Sep 2026 17:09:43 +0200 Subject: [PATCH v2 02/17] media: rockchip: rga: add comment about pixel alignment for YUV formats Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260916-spu-rga3multicore-v2-2-23aa2cb74e61@pengutronix.de> References: <20260916-spu-rga3multicore-v2-0-23aa2cb74e61@pengutronix.de> In-Reply-To: <20260916-spu-rga3multicore-v2-0-23aa2cb74e61@pengutronix.de> To: Jacob Chen , Ezequiel Garcia , Mauro Carvalho Chehab , Heiko Stuebner , Philipp Zabel Cc: linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, kernel@pengutronix.de, Detlev Casanova , Michael Tretter , Guangshuo Li , =?utf-8?q?Sven_P=C3=BCschel?= X-Mailer: b4 0.15.2 Add a comment to clarify the use of fixed step_height values for all YUV formats. While the commit introducing the change already explains the reasoning, add an explicit comment to improve the visibility of the reasoning. Signed-off-by: Sven P=C3=BCschel --- drivers/media/platform/rockchip/rga/rga.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/plat= form/rockchip/rga/rga.c index bd0afd33affe4..efe5541078214 100644 --- a/drivers/media/platform/rockchip/rga/rga.c +++ b/drivers/media/platform/rockchip/rga/rga.c @@ -414,6 +414,16 @@ static int vidioc_try_fmt(struct file *file, void *pri= v, struct v4l2_format *f) .step_height =3D 1, }; =20 + /* + * Technically 4:2:2 YUV formats don't need a step_height of 2. + * But for the RGA3 this is explicitly documented in section 5.6.3 + * of the RK3588 TRM Part 2. + * And the RGA2 vendor driver also checks that the height (and width) + * is aligned to 2 when a YUV format is used. + * + * Therefore be safe and always align width and height to 2 + * when a YUV format is used. + */ if (v4l2_is_format_yuv(v4l2_format_info(pix_fmt->pixelformat))) { frmsize.step_width =3D 2; frmsize.step_height =3D 2; --=20 2.55.0 From nobody Fri Sep 25 04:43:51 2026 Received: from mx1.white.stw.pengutronix.de (mx1.white.stw.pengutronix.de [185.203.200.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 75A3F3815E8; Wed, 16 Sep 2026 15:09:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.200.13 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789571394; cv=none; b=I7KK8b752HIQJX2wzeHukqa8owR1GD1uc+DRzWKPHyPlon98O7VrcOjOFULwbpAfdjAdR+UU9hqzYOc1ocwSCWD1uKLc/CCSBYLS4v2bUcGOy38qpzQoS80C1hE+tO29y8VTG7+8AxqgI1VUdxPe0IVPCt5HfoymBpVnqde1Ds8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789571394; c=relaxed/simple; bh=SaLfQm36VUoqbMuVy62pw9cRyJGDK8TihHHaeRK8jpg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=WL9Phxaj5UPdGdsiQPTy86RpMhOuXKf5T3DNkzJVGgPQACz+kh7wMkn+RUiZJscOKfdz9n7bbIUw22pJCbNowccwZtCp/CsIyXj1LqA3Y5KR4ftYuUkQ6l6DvfYKbndEg94XDcdmzB+YJjI6AC5MHEMu1Yl5WilaJskr9PWS2Uk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.200.13 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de X-PTX-Original-Recipient: ezequiel@vanguardiasur.com.ar X-PTX-Original-Recipient: jacob-chen@iotwrt.com X-PTX-Original-Recipient: mchehab@kernel.org X-PTX-Original-Recipient: detlev.casanova@collabora.com X-PTX-Original-Recipient: heiko@sntech.de X-PTX-Original-Recipient: linux-kernel@vger.kernel.org X-PTX-Original-Recipient: linux-media@vger.kernel.org X-PTX-Original-Recipient: linux-arm-kernel@lists.infradead.org X-PTX-Original-Recipient: linux-rockchip@lists.infradead.org X-PTX-Original-Recipient: lgs201920130244@gmail.com X-PTX-Original-Recipient: p.zabel@pengutronix.de X-PTX-Original-Recipient: kernel@pengutronix.de X-PTX-Original-Recipient: s.pueschel@pengutronix.de X-PTX-Original-Recipient: m.tretter@pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de (drehscheibe.grey.stw.pengutronix.de [IPv6:2a0a:edc0:0:c01:1d::a2]) (Authenticated sender: relay-from-drehscheibe.grey.stw.pengutronix.de) by mx1.white.stw.pengutronix.de (Postfix) with ESMTPSA id 7EF132059F0; Wed, 16 Sep 2026 17:09:48 +0200 (CEST) Received: from ptz.office.stw.pengutronix.de ([2a0a:edc0:0:900:1d::77] helo=peter.mobile.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtp (Exim 4.96) (envelope-from ) id 1x6rGe-001Fsx-1G; Wed, 16 Sep 2026 17:09:48 +0200 From: =?utf-8?q?Sven_P=C3=BCschel?= Date: Wed, 16 Sep 2026 17:09:44 +0200 Subject: [PATCH v2 03/17] media: rockchip: rga: move early return into if condition in vidioc_enum_fmt Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260916-spu-rga3multicore-v2-3-23aa2cb74e61@pengutronix.de> References: <20260916-spu-rga3multicore-v2-0-23aa2cb74e61@pengutronix.de> In-Reply-To: <20260916-spu-rga3multicore-v2-0-23aa2cb74e61@pengutronix.de> To: Jacob Chen , Ezequiel Garcia , Mauro Carvalho Chehab , Heiko Stuebner , Philipp Zabel Cc: linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, kernel@pengutronix.de, Detlev Casanova , Michael Tretter , Guangshuo Li , =?utf-8?q?Sven_P=C3=BCschel?= X-Mailer: b4 0.15.2 Instead of a doing an early return when we don't have a capture device, merge the condition with the following if condition. This improves readability, as the condition now explicitly contains a check for a capture device instead of returning when we don't have a capture device. Also use the V4L2_TYPE_IS_CAPTURE helper and improve the comment. The early return if was copied from the vivid drivers vivid_enum_fmt_vid function. Signed-off-by: Sven P=C3=BCschel --- drivers/media/platform/rockchip/rga/rga.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/plat= form/rockchip/rga/rga.c index efe5541078214..8c03422d669cf 100644 --- a/drivers/media/platform/rockchip/rga/rga.c +++ b/drivers/media/platform/rockchip/rga/rga.c @@ -372,12 +372,14 @@ static int vidioc_enum_fmt(struct file *file, void *p= riv, struct v4l2_fmtdesc *f if (ret !=3D 0) return ret; =20 - if (f->type !=3D V4L2_BUF_TYPE_VIDEO_CAPTURE && - f->type !=3D V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) - return 0; - - /* allow changing the quantization and xfer func for YUV formats */ - if (v4l2_is_format_yuv(v4l2_format_info(f->pixelformat))) + /* + * Allow changing the quantization and ycbcr_enc func for YUV formats + * on the capture side for RGB -> YUV conversions. + * + * These flags are only relevant for capture devices. + */ + if (V4L2_TYPE_IS_CAPTURE(f->type) && + v4l2_is_format_yuv(v4l2_format_info(f->pixelformat))) f->flags |=3D V4L2_FMT_FLAG_CSC_QUANTIZATION | V4L2_FMT_FLAG_CSC_YCBCR_ENC; =20 --=20 2.55.0 From nobody Fri Sep 25 04:43:51 2026 Received: from mx1.white.stw.pengutronix.de (mx1.white.stw.pengutronix.de [185.203.200.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0499B381E84; Wed, 16 Sep 2026 15:09:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.200.13 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789571393; cv=none; b=tlBQkhA9/CXKlkgWRoRj7toBNGY2nIbO6yX3FCmfcvy7veZ2DVGgR3qE1BZ4uB/cDX63Ql6zkpGjyqC7IHgJpSHzOx504zfLk2XwXLf/zf8L20sS5NkTinVMgPI2ac81cu93MrubnlhQCZMLPn43qvEsb9CWii+BJ8KQQzWWQT4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789571393; c=relaxed/simple; bh=4qbgGBhRrBAKfPSB7uxdFY2A8hhPgUBkBWt1DgKs+Js=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Zy+aEVi16N3YHNY4IJRHLS66pH7tMZi+ZFCSe7zHjULzZs2xh9xv/kJyS6eMDPeIoJAAIQHExE/ybmi5Pb+N7j0fs0jEsIfbIQp6o2jL0aczfM+pPHSJmdtm/IMoREZBPn44onzcsuV4IxEitQYNATLY18wVCyjW37CJT3jK7Jw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.200.13 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de X-PTX-Original-Recipient: ezequiel@vanguardiasur.com.ar X-PTX-Original-Recipient: jacob-chen@iotwrt.com X-PTX-Original-Recipient: mchehab@kernel.org X-PTX-Original-Recipient: detlev.casanova@collabora.com X-PTX-Original-Recipient: heiko@sntech.de X-PTX-Original-Recipient: linux-kernel@vger.kernel.org X-PTX-Original-Recipient: linux-media@vger.kernel.org X-PTX-Original-Recipient: linux-arm-kernel@lists.infradead.org X-PTX-Original-Recipient: linux-rockchip@lists.infradead.org X-PTX-Original-Recipient: lgs201920130244@gmail.com X-PTX-Original-Recipient: p.zabel@pengutronix.de X-PTX-Original-Recipient: kernel@pengutronix.de X-PTX-Original-Recipient: s.pueschel@pengutronix.de X-PTX-Original-Recipient: m.tretter@pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de (drehscheibe.grey.stw.pengutronix.de [IPv6:2a0a:edc0:0:c01:1d::a2]) (Authenticated sender: relay-from-drehscheibe.grey.stw.pengutronix.de) by mx1.white.stw.pengutronix.de (Postfix) with ESMTPSA id 3A5DC2059F2; Wed, 16 Sep 2026 17:09:49 +0200 (CEST) Received: from ptz.office.stw.pengutronix.de ([2a0a:edc0:0:900:1d::77] helo=peter.mobile.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtp (Exim 4.96) (envelope-from ) id 1x6rGf-001Fsx-0N; Wed, 16 Sep 2026 17:09:49 +0200 From: =?utf-8?q?Sven_P=C3=BCschel?= Date: Wed, 16 Sep 2026 17:09:45 +0200 Subject: [PATCH v2 04/17] media: rockchip: rga: removed unused regmap member Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260916-spu-rga3multicore-v2-4-23aa2cb74e61@pengutronix.de> References: <20260916-spu-rga3multicore-v2-0-23aa2cb74e61@pengutronix.de> In-Reply-To: <20260916-spu-rga3multicore-v2-0-23aa2cb74e61@pengutronix.de> To: Jacob Chen , Ezequiel Garcia , Mauro Carvalho Chehab , Heiko Stuebner , Philipp Zabel Cc: linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, kernel@pengutronix.de, Detlev Casanova , Michael Tretter , Guangshuo Li , =?utf-8?q?Sven_P=C3=BCschel?= X-Mailer: b4 0.15.2 The grf member variable is never accessed or written by the RGA driver. Therefore drop it from the rockchip_rga struct. Signed-off-by: Sven P=C3=BCschel --- drivers/media/platform/rockchip/rga/rga.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/platform/rockchip/rga/rga.h b/drivers/media/plat= form/rockchip/rga/rga.h index 2b4f5694375a4..0e62337f8dd38 100644 --- a/drivers/media/platform/rockchip/rga/rga.h +++ b/drivers/media/platform/rockchip/rga/rga.h @@ -71,7 +71,6 @@ struct rockchip_rga { struct video_device *vfd; =20 struct device *dev; - struct regmap *grf; void __iomem *regs; struct clk_bulk_data *clks; int num_clks; --=20 2.55.0 From nobody Fri Sep 25 04:43:51 2026 Received: from mx1.white.stw.pengutronix.de (mx1.white.stw.pengutronix.de [185.203.200.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B675C3932C3; Wed, 16 Sep 2026 15:09:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.200.13 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789571396; cv=none; b=Pan7qWqhBuqN+19OKdmHn+QKOIkDDz63BJNXP69MCkUl4RgFkpcQG7H0BJz+g8GTxUZfDXng5KpkNagbCMFNIh+B0YdjXfNOUQymXJ0VrjVDi+aqUsROTUgYwBYODFASXs33ZaV1nQsQPsIncvuxb3FAEJ58DHtZlTu0D/LKaUQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789571396; c=relaxed/simple; bh=3DbUNM/U7+cBB1aeOYZgdZv12xTbkgeY4ZzAFCkBQKE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=EQigG2K5RYhf3soioxTtFrXcI4FOcHF4aJaTgwZqUQRyfqNw+WxD4qDCH62XS65n9EsiXpaSNJ8i7r8naWZ6r5JEhPc39/pEJeC4SeHrHqHa7jxrN3o+qJsJOw7AZ4fCOOH2p0Hkw0CB6JIbWIYMTeyfm0/9QBSeKSBUMLHvZkA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.200.13 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de X-PTX-Original-Recipient: ezequiel@vanguardiasur.com.ar X-PTX-Original-Recipient: jacob-chen@iotwrt.com X-PTX-Original-Recipient: mchehab@kernel.org X-PTX-Original-Recipient: detlev.casanova@collabora.com X-PTX-Original-Recipient: heiko@sntech.de X-PTX-Original-Recipient: linux-kernel@vger.kernel.org X-PTX-Original-Recipient: linux-media@vger.kernel.org X-PTX-Original-Recipient: linux-arm-kernel@lists.infradead.org X-PTX-Original-Recipient: linux-rockchip@lists.infradead.org X-PTX-Original-Recipient: lgs201920130244@gmail.com X-PTX-Original-Recipient: p.zabel@pengutronix.de X-PTX-Original-Recipient: kernel@pengutronix.de X-PTX-Original-Recipient: s.pueschel@pengutronix.de X-PTX-Original-Recipient: m.tretter@pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de (drehscheibe.grey.stw.pengutronix.de [IPv6:2a0a:edc0:0:c01:1d::a2]) (Authenticated sender: relay-from-drehscheibe.grey.stw.pengutronix.de) by mx1.white.stw.pengutronix.de (Postfix) with ESMTPSA id E87682059F3; Wed, 16 Sep 2026 17:09:49 +0200 (CEST) Received: from ptz.office.stw.pengutronix.de ([2a0a:edc0:0:900:1d::77] helo=peter.mobile.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtp (Exim 4.96) (envelope-from ) id 1x6rGf-001Fsx-2g; Wed, 16 Sep 2026 17:09:49 +0200 From: =?utf-8?q?Sven_P=C3=BCschel?= Date: Wed, 16 Sep 2026 17:09:46 +0200 Subject: [PATCH v2 05/17] media: rockchip: rga: use devres version of pm_runtime_enable Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260916-spu-rga3multicore-v2-5-23aa2cb74e61@pengutronix.de> References: <20260916-spu-rga3multicore-v2-0-23aa2cb74e61@pengutronix.de> In-Reply-To: <20260916-spu-rga3multicore-v2-0-23aa2cb74e61@pengutronix.de> To: Jacob Chen , Ezequiel Garcia , Mauro Carvalho Chehab , Heiko Stuebner , Philipp Zabel Cc: linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, kernel@pengutronix.de, Detlev Casanova , Michael Tretter , Guangshuo Li , =?utf-8?q?Sven_P=C3=BCschel?= X-Mailer: b4 0.15.2 Use the devres version of pm_runtime_enable named devm_pm_runtime_enable to ease up the cleanup handling. Also it avoids having a mixed cleanup order due to the following devm_platform_ioremap_resource being cleaned up anyways after the probe function has returned. This also changes some dev_err calls to dev_err_probe for convenient returning. This may not print these messages in the error case, as dev_err_probe may handle them differently based on the error (e.g. ENOMEM won't be printed). Signed-off-by: Sven P=C3=BCschel --- v2 - added --- drivers/media/platform/rockchip/rga/rga.c | 34 +++++++++++----------------= ---- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/plat= form/rockchip/rga/rga.c index 8c03422d669cf..d7f0712177b70 100644 --- a/drivers/media/platform/rockchip/rga/rga.c +++ b/drivers/media/platform/rockchip/rga/rga.c @@ -797,37 +797,31 @@ static int rga_probe(struct platform_device *pdev) if (ret) return dev_err_probe(&pdev->dev, ret, "Unable to parse OF data\n"); =20 - pm_runtime_enable(rga->dev); + ret =3D devm_pm_runtime_enable(rga->dev); + if (ret) + return ret; =20 rga->regs =3D devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(rga->regs)) { - ret =3D PTR_ERR(rga->regs); - goto err_put_clk; - } + if (IS_ERR(rga->regs)) + return PTR_ERR(rga->regs); =20 irq =3D platform_get_irq(pdev, 0); - if (irq < 0) { - ret =3D irq; - goto err_put_clk; - } + if (irq < 0) + return irq; =20 ret =3D devm_request_irq(rga->dev, irq, rga_isr, rga_has_internal_iommu(rga) ? 0 : IRQF_SHARED, dev_name(rga->dev), rga); - if (ret < 0) { - dev_err(rga->dev, "failed to request irq\n"); - goto err_put_clk; - } + if (ret < 0) + return dev_err_probe(rga->dev, ret, "failed to request irq\n"); =20 ret =3D dma_set_mask_and_coherent(rga->dev, DMA_BIT_MASK(32)); - if (ret) { - dev_err(rga->dev, "32-bit DMA not supported"); - goto err_put_clk; - } + if (ret) + dev_err_probe(rga->dev, ret, "32-bit DMA not supported"); =20 ret =3D v4l2_device_register(&pdev->dev, &rga->v4l2_dev); if (ret) - goto err_put_clk; + return ret; vfd =3D video_device_alloc(); if (!vfd) { v4l2_err(&rga->v4l2_dev, "Failed to allocate video device\n"); @@ -877,8 +871,6 @@ static int rga_probe(struct platform_device *pdev) video_device_release(vfd); unreg_v4l2_dev: v4l2_device_unregister(&rga->v4l2_dev); -err_put_clk: - pm_runtime_disable(rga->dev); =20 return ret; } @@ -892,8 +884,6 @@ static void rga_remove(struct platform_device *pdev) v4l2_m2m_release(rga->m2m_dev); video_unregister_device(rga->vfd); v4l2_device_unregister(&rga->v4l2_dev); - - pm_runtime_disable(rga->dev); } =20 static int __maybe_unused rga_runtime_suspend(struct device *dev) --=20 2.55.0 From nobody Fri Sep 25 04:43:51 2026 Received: from mx1.white.stw.pengutronix.de (mx1.white.stw.pengutronix.de [185.203.200.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B2867392823; Wed, 16 Sep 2026 15:09:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.200.13 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789571396; cv=none; b=KXvD/quUKTsmUrokPFKHW9qwxvoMjMacVd3dMo117EdXrRT4aedRMa0chHK7BcDQAdVmaSJ0iA2Rjb2N11liM1KwC1TxaLUw1TEm7s21YOH48BHIIRSGlbFGicklXCozga2/LmbtLmDQcgnsXuBWrF43ssc89sHoCi4pRDRSMiA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789571396; c=relaxed/simple; bh=nokP+HkAeAsjfnIgakz0YeqhxsbLRHxZzyuuYyYFs6o=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=jvxuf3VHYuelhMYQ3MkODqM5H7W0znvDCGMD87D02U+LhMnG69um2LdnhdXs/vZJP92eiROXzPW53c+yMVfhX9NppzjmCbW5rgzY9dpZNMnak8LqQxhdQVuFzE7PNHxGDxTHThO8krcaPPvJTGF/fgNsCu+q5m95WMLeFiw+53k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.200.13 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de X-PTX-Original-Recipient: ezequiel@vanguardiasur.com.ar X-PTX-Original-Recipient: jacob-chen@iotwrt.com X-PTX-Original-Recipient: mchehab@kernel.org X-PTX-Original-Recipient: detlev.casanova@collabora.com X-PTX-Original-Recipient: heiko@sntech.de X-PTX-Original-Recipient: linux-kernel@vger.kernel.org X-PTX-Original-Recipient: linux-media@vger.kernel.org X-PTX-Original-Recipient: linux-arm-kernel@lists.infradead.org X-PTX-Original-Recipient: linux-rockchip@lists.infradead.org X-PTX-Original-Recipient: lgs201920130244@gmail.com X-PTX-Original-Recipient: p.zabel@pengutronix.de X-PTX-Original-Recipient: kernel@pengutronix.de X-PTX-Original-Recipient: s.pueschel@pengutronix.de X-PTX-Original-Recipient: m.tretter@pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de (drehscheibe.grey.stw.pengutronix.de [IPv6:2a0a:edc0:0:c01:1d::a2]) (Authenticated sender: relay-from-drehscheibe.grey.stw.pengutronix.de) by mx1.white.stw.pengutronix.de (Postfix) with ESMTPSA id A68D72059F6; Wed, 16 Sep 2026 17:09:50 +0200 (CEST) Received: from ptz.office.stw.pengutronix.de ([2a0a:edc0:0:900:1d::77] helo=peter.mobile.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtp (Exim 4.96) (envelope-from ) id 1x6rGg-001Fsx-1n; Wed, 16 Sep 2026 17:09:50 +0200 From: =?utf-8?q?Sven_P=C3=BCschel?= Date: Wed, 16 Sep 2026 17:09:47 +0200 Subject: [PATCH v2 06/17] media: v4l2-mem2mem: drop curr_ctx member from v4l2_m2m_dev struct Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260916-spu-rga3multicore-v2-6-23aa2cb74e61@pengutronix.de> References: <20260916-spu-rga3multicore-v2-0-23aa2cb74e61@pengutronix.de> In-Reply-To: <20260916-spu-rga3multicore-v2-0-23aa2cb74e61@pengutronix.de> To: Jacob Chen , Ezequiel Garcia , Mauro Carvalho Chehab , Heiko Stuebner , Philipp Zabel Cc: linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, kernel@pengutronix.de, Detlev Casanova , Michael Tretter , Guangshuo Li , =?utf-8?q?Sven_P=C3=BCschel?= X-Mailer: b4 0.15.2 Drop the curr_ctx member from the v4l2_m2m_dev struct in preparation of adding support for running multiple jobs in parallel. The curr_ctx member of a v4l2_m2m_dev was used to track the currently running context. But the currently running context will always be at the top of the job_queue. As the TRANS_RUNNING flag can be used to check if the queue head is already running, the curr_ctx member can be completely dropped. By eliminating the struct member the code is mostly agnostic whenever only one job is running at a time or multiple run at the same time. The main exception is the v4l2_m2m_get_curr_priv function, which is by it's design incompatible with running multiple jobs in parallel. Signed-off-by: Sven P=C3=BCschel --- v2: - split curr_ctx removal into a separate commit - add WARN_ON to _v4l2_m2m_job_finish to prevent mismatching context to device (and an unused m2m_dev argument) - rewrite v4l2_m2m_get_curr_priv to get private data inside the spinlock (https://sashiko.dev/#/patchset/20260606-spu-rga3multicore-v1-0-3ec2b1567= 5f7%40pengutronix.de?part=3D5) --- drivers/media/v4l2-core/v4l2-mem2mem.c | 61 ++++++++++++++++++------------= ---- 1 file changed, 33 insertions(+), 28 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-co= re/v4l2-mem2mem.c index a65cbb124cfe0..60cca94195166 100644 --- a/drivers/media/v4l2-core/v4l2-mem2mem.c +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c @@ -84,7 +84,6 @@ static const char * const m2m_entity_name[] =3D { * v4l2_m2m_unregister_media_controller(). * @intf_devnode: &struct media_intf devnode pointer with the interface * with controls the M2M device. - * @curr_ctx: currently running instance * @job_queue: instances queued to run * @job_spinlock: protects job_queue * @job_work: worker to run queued jobs. @@ -93,7 +92,6 @@ static const char * const m2m_entity_name[] =3D { * @kref: device reference count */ struct v4l2_m2m_dev { - struct v4l2_m2m_ctx *curr_ctx; #ifdef CONFIG_MEDIA_CONTROLLER struct media_entity *source; struct media_pad source_pad; @@ -232,8 +230,14 @@ void *v4l2_m2m_get_curr_priv(struct v4l2_m2m_dev *m2m_= dev) void *ret =3D NULL; =20 spin_lock_irqsave(&m2m_dev->job_spinlock, flags); - if (m2m_dev->curr_ctx) - ret =3D m2m_dev->curr_ctx->priv; + if (!list_empty(&m2m_dev->job_queue)) { + struct v4l2_m2m_ctx *first_ctx =3D + list_first_entry(&m2m_dev->job_queue, + struct v4l2_m2m_ctx, queue); + + if (first_ctx->job_flags & TRANS_RUNNING) + ret =3D first_ctx->priv; + } spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); =20 return ret; @@ -252,14 +256,9 @@ EXPORT_SYMBOL(v4l2_m2m_get_curr_priv); static void v4l2_m2m_try_run(struct v4l2_m2m_dev *m2m_dev) { unsigned long flags; + struct v4l2_m2m_ctx *chosen_ctx; =20 spin_lock_irqsave(&m2m_dev->job_spinlock, flags); - if (NULL !=3D m2m_dev->curr_ctx) { - spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); - dprintk("Another instance is running, won't run now\n"); - return; - } - if (list_empty(&m2m_dev->job_queue)) { spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); dprintk("No job pending\n"); @@ -272,13 +271,18 @@ static void v4l2_m2m_try_run(struct v4l2_m2m_dev *m2m= _dev) return; } =20 - m2m_dev->curr_ctx =3D list_first_entry(&m2m_dev->job_queue, - struct v4l2_m2m_ctx, queue); - m2m_dev->curr_ctx->job_flags |=3D TRANS_RUNNING; + chosen_ctx =3D list_first_entry(&m2m_dev->job_queue, struct v4l2_m2m_ctx,= queue); + if (chosen_ctx->job_flags & TRANS_RUNNING) { + spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); + dprintk("Another instance is running, won't run now\n"); + return; + } + + chosen_ctx->job_flags |=3D TRANS_RUNNING; spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); =20 - dprintk("Running job on m2m_ctx: %p\n", m2m_dev->curr_ctx); - m2m_dev->m2m_ops->device_run(m2m_dev->curr_ctx->priv); + dprintk("Running job on m2m_ctx: %p\n", chosen_ctx); + m2m_dev->m2m_ops->device_run(chosen_ctx->priv); } =20 /* @@ -469,15 +473,16 @@ static void v4l2_m2m_schedule_next_job(struct v4l2_m2= m_dev *m2m_dev, static bool _v4l2_m2m_job_finish(struct v4l2_m2m_dev *m2m_dev, struct v4l2_m2m_ctx *m2m_ctx) { - if (!m2m_dev->curr_ctx || m2m_dev->curr_ctx !=3D m2m_ctx) { + if (!m2m_ctx || !(m2m_ctx->job_flags & TRANS_RUNNING)) { dprintk("Called by an instance not currently running\n"); return false; } =20 - list_del(&m2m_dev->curr_ctx->queue); - m2m_dev->curr_ctx->job_flags &=3D ~(TRANS_QUEUED | TRANS_RUNNING); - wake_up(&m2m_dev->curr_ctx->finished); - m2m_dev->curr_ctx =3D NULL; + WARN_ON(m2m_dev !=3D m2m_ctx->m2m_dev); + + list_del(&m2m_ctx->queue); + m2m_ctx->job_flags &=3D ~(TRANS_QUEUED | TRANS_RUNNING); + wake_up(&m2m_ctx->finished); return true; } =20 @@ -548,12 +553,15 @@ void v4l2_m2m_suspend(struct v4l2_m2m_dev *m2m_dev) =20 spin_lock_irqsave(&m2m_dev->job_spinlock, flags); m2m_dev->job_queue_flags |=3D QUEUE_PAUSED; - curr_ctx =3D m2m_dev->curr_ctx; + if (list_empty(&m2m_dev->job_queue)) { + spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); + return; + } + + curr_ctx =3D list_first_entry(&m2m_dev->job_queue, struct v4l2_m2m_ctx, q= ueue); spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); =20 - if (curr_ctx) - wait_event(curr_ctx->finished, - !(curr_ctx->job_flags & TRANS_RUNNING)); + wait_event(curr_ctx->finished, !(curr_ctx->job_flags & TRANS_RUNNING)); } EXPORT_SYMBOL(v4l2_m2m_suspend); =20 @@ -896,10 +904,8 @@ int v4l2_m2m_streamoff(struct file *file, struct v4l2_= m2m_ctx *m2m_ctx, q_ctx->num_rdy =3D 0; spin_unlock_irqrestore(&q_ctx->rdy_spinlock, flags); =20 - if (m2m_dev->curr_ctx =3D=3D m2m_ctx) { - m2m_dev->curr_ctx =3D NULL; + if (m2m_ctx->job_flags & TRANS_RUNNING) wake_up(&m2m_ctx->finished); - } spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags_job); =20 return 0; @@ -1194,7 +1200,6 @@ struct v4l2_m2m_dev *v4l2_m2m_init(const struct v4l2_= m2m_ops *m2m_ops) if (!m2m_dev) return ERR_PTR(-ENOMEM); =20 - m2m_dev->curr_ctx =3D NULL; m2m_dev->m2m_ops =3D m2m_ops; INIT_LIST_HEAD(&m2m_dev->job_queue); spin_lock_init(&m2m_dev->job_spinlock); --=20 2.55.0 From nobody Fri Sep 25 04:43:51 2026 Received: from mx1.white.stw.pengutronix.de (mx1.white.stw.pengutronix.de [185.203.200.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 88E08390CAA; Wed, 16 Sep 2026 15:09:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.200.13 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789571397; cv=none; b=rlQFZiYOUiTtL5XZRidlVAJ3pZuSjBuBCYeVZp8+HtD2NH0hZLqPDnxqCi7NNTCoDlNp41Fh5lTZqs5SpGYu4iLeiGus2RsRVAhRZCyu0DIsmRoXtFMY/ve0k5+lRZ84hMJpbzC25aTe2EoYZgOSTAwJNLEX7/ynsdxAQRZnfz4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789571397; c=relaxed/simple; bh=b8vYvIwZonhhpPmFyxHVDlkAmuTWWgbvt4JU+6Pdmqc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=JWIyzoEWbEC88tg2ZFuXcD5kgbWogNeAF8ptPXMINtB1HGMKOTurNwUAQVDrBf7jihlItdEHicFpy6jtO+YmUmfS0QGaIV8JCpA40G7nnXOKzVljamTTyIunuBHT68LUV7Mq+eh602Sk3cAn4ARMHNEc6cj2SSDz6G9B650Yc2k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.200.13 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de X-PTX-Original-Recipient: ezequiel@vanguardiasur.com.ar X-PTX-Original-Recipient: jacob-chen@iotwrt.com X-PTX-Original-Recipient: mchehab@kernel.org X-PTX-Original-Recipient: detlev.casanova@collabora.com X-PTX-Original-Recipient: heiko@sntech.de X-PTX-Original-Recipient: linux-kernel@vger.kernel.org X-PTX-Original-Recipient: linux-media@vger.kernel.org X-PTX-Original-Recipient: linux-arm-kernel@lists.infradead.org X-PTX-Original-Recipient: linux-rockchip@lists.infradead.org X-PTX-Original-Recipient: lgs201920130244@gmail.com X-PTX-Original-Recipient: p.zabel@pengutronix.de X-PTX-Original-Recipient: kernel@pengutronix.de X-PTX-Original-Recipient: s.pueschel@pengutronix.de X-PTX-Original-Recipient: m.tretter@pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de (drehscheibe.grey.stw.pengutronix.de [IPv6:2a0a:edc0:0:c01:1d::a2]) (Authenticated sender: relay-from-drehscheibe.grey.stw.pengutronix.de) by mx1.white.stw.pengutronix.de (Postfix) with ESMTPSA id 642872059F8; Wed, 16 Sep 2026 17:09:51 +0200 (CEST) Received: from ptz.office.stw.pengutronix.de ([2a0a:edc0:0:900:1d::77] helo=peter.mobile.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtp (Exim 4.96) (envelope-from ) id 1x6rGh-001Fsx-0u; Wed, 16 Sep 2026 17:09:51 +0200 From: =?utf-8?q?Sven_P=C3=BCschel?= Date: Wed, 16 Sep 2026 17:09:48 +0200 Subject: [PATCH v2 07/17] media: v4l2-mem2mem: support running multiple jobs in parallel Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260916-spu-rga3multicore-v2-7-23aa2cb74e61@pengutronix.de> References: <20260916-spu-rga3multicore-v2-0-23aa2cb74e61@pengutronix.de> In-Reply-To: <20260916-spu-rga3multicore-v2-0-23aa2cb74e61@pengutronix.de> To: Jacob Chen , Ezequiel Garcia , Mauro Carvalho Chehab , Heiko Stuebner , Philipp Zabel Cc: linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, kernel@pengutronix.de, Detlev Casanova , Michael Tretter , Guangshuo Li , =?utf-8?q?Sven_P=C3=BCschel?= X-Mailer: b4 0.15.2 Add support for running multiple jobs in parallel for SoCs containing multiple identical devices. An example is the Rockchip RK3588 SoC, which contains two identical RGA3 devices. Therefore it is desirable to have the kernel schedule the work across all available devices and only expose one video device to the userspace. To avoid queueing too many parallel jobs, the v4l2_m2m_set_max_parallel_jobs method is added. It allows a driver to set the number of parallel jobs and avoids calling device_run when the given number of jobs is already running. This is set to 1 by default to prevent parallel job runs. Drivers with the need and support for scheduling jobs can adjust this value accordingly. Note that this change doesn't allow a context to be used multiple times in parallel. So a single stream won't be able to utilize multiple devices at once, but N streams can utilize up to N devices. This is caused by the fact that a context is not added multiple times to the job_list and also holds the job_flags to distinguish if it's currently running. Signed-off-by: Sven P=C3=BCschel --- v2 - split out the removal of the curr_ctx member - add EXPORT_SYMBOL to v4l2_m2m_set_max_parallel_jobs (indirectly pointed out by Detlev) - document v4l2_m2m_get_curr_priv being incompatible with parallel jobs - add documentation comment for the added function - rework v4l2_m2m_suspend to avoid potential errors due to looping outside of a spinlock over the list (https://sashiko.dev/#/patchset/20260606-spu-rga3multicore-v1-0-3ec2b1567= 5f7%40pengutronix.de?part=3D5) --- drivers/media/v4l2-core/v4l2-mem2mem.c | 51 ++++++++++++++++++++++++++----= ---- include/media/v4l2-mem2mem.h | 18 ++++++++++++ 2 files changed, 58 insertions(+), 11 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-co= re/v4l2-mem2mem.c index 60cca94195166..f1b6255984087 100644 --- a/drivers/media/v4l2-core/v4l2-mem2mem.c +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c @@ -88,6 +88,7 @@ static const char * const m2m_entity_name[] =3D { * @job_spinlock: protects job_queue * @job_work: worker to run queued jobs. * @job_queue_flags: flags of the queue status, %QUEUE_PAUSED. + * @max_parallel_jobs: max job_queue instances number marked as running * @m2m_ops: driver callbacks * @kref: device reference count */ @@ -106,6 +107,7 @@ struct v4l2_m2m_dev { spinlock_t job_spinlock; struct work_struct job_work; unsigned long job_queue_flags; + u32 max_parallel_jobs; =20 const struct v4l2_m2m_ops *m2m_ops; =20 @@ -121,6 +123,13 @@ static struct v4l2_m2m_queue_ctx *get_queue_ctx(struct= v4l2_m2m_ctx *m2m_ctx, return &m2m_ctx->cap_q_ctx; } =20 +void v4l2_m2m_set_max_parallel_jobs(struct v4l2_m2m_dev *m2m_dev, + u32 max_parallel_jobs) +{ + m2m_dev->max_parallel_jobs =3D max_parallel_jobs; +} +EXPORT_SYMBOL(v4l2_m2m_set_max_parallel_jobs); + struct vb2_queue *v4l2_m2m_get_vq(struct v4l2_m2m_ctx *m2m_ctx, enum v4l2_buf_type type) { @@ -256,7 +265,9 @@ EXPORT_SYMBOL(v4l2_m2m_get_curr_priv); static void v4l2_m2m_try_run(struct v4l2_m2m_dev *m2m_dev) { unsigned long flags; - struct v4l2_m2m_ctx *chosen_ctx; + struct v4l2_m2m_ctx *chosen_ctx =3D NULL; + struct v4l2_m2m_ctx *ctx; + u32 running_jobs =3D 0; =20 spin_lock_irqsave(&m2m_dev->job_spinlock, flags); if (list_empty(&m2m_dev->job_queue)) { @@ -271,10 +282,22 @@ static void v4l2_m2m_try_run(struct v4l2_m2m_dev *m2m= _dev) return; } =20 - chosen_ctx =3D list_first_entry(&m2m_dev->job_queue, struct v4l2_m2m_ctx,= queue); - if (chosen_ctx->job_flags & TRANS_RUNNING) { + list_for_each_entry(ctx, &m2m_dev->job_queue, queue) { + if (!(ctx->job_flags & TRANS_RUNNING)) { + chosen_ctx =3D ctx; + break; + } + + running_jobs++; + } + if (running_jobs >=3D m2m_dev->max_parallel_jobs) { spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); - dprintk("Another instance is running, won't run now\n"); + dprintk("Maximum number of parallel jobs reached\n"); + return; + } + if (!chosen_ctx) { + spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); + dprintk("All jobs already running\n"); return; } =20 @@ -549,19 +572,24 @@ EXPORT_SYMBOL(v4l2_m2m_buf_done_and_job_finish); void v4l2_m2m_suspend(struct v4l2_m2m_dev *m2m_dev) { unsigned long flags; - struct v4l2_m2m_ctx *curr_ctx; =20 spin_lock_irqsave(&m2m_dev->job_spinlock, flags); m2m_dev->job_queue_flags |=3D QUEUE_PAUSED; - if (list_empty(&m2m_dev->job_queue)) { + + while (!list_empty(&m2m_dev->job_queue)) { + /* Running jobs are always at the start of the queue */ + struct v4l2_m2m_ctx *first_ctx =3D + list_first_entry(&m2m_dev->job_queue, + struct v4l2_m2m_ctx, queue); + + if (!(first_ctx->job_flags & TRANS_RUNNING)) + break; + spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); - return; + wait_event(first_ctx->finished, !(first_ctx->job_flags & TRANS_RUNNING)); + spin_lock_irqsave(&m2m_dev->job_spinlock, flags); } - - curr_ctx =3D list_first_entry(&m2m_dev->job_queue, struct v4l2_m2m_ctx, q= ueue); spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); - - wait_event(curr_ctx->finished, !(curr_ctx->job_flags & TRANS_RUNNING)); } EXPORT_SYMBOL(v4l2_m2m_suspend); =20 @@ -1205,6 +1233,7 @@ struct v4l2_m2m_dev *v4l2_m2m_init(const struct v4l2_= m2m_ops *m2m_ops) spin_lock_init(&m2m_dev->job_spinlock); INIT_WORK(&m2m_dev->job_work, v4l2_m2m_device_run_work); kref_init(&m2m_dev->kref); + m2m_dev->max_parallel_jobs =3D 1; =20 return m2m_dev; } diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h index 31de25d792b98..37ffd33b653f2 100644 --- a/include/media/v4l2-mem2mem.h +++ b/include/media/v4l2-mem2mem.h @@ -144,6 +144,10 @@ struct v4l2_m2m_buffer { * v4l2_m2m_get_curr_priv() - return driver private data for the currently * running instance or NULL if no instance is running * + * It is incompatible with using parallel instances enabled by calling + * v4l2_m2m_set_max_parallel_jobs(), as it is undefined which private data= of + * the parallel running instances is returned. + * * @m2m_dev: opaque pointer to the internal data to handle M2M context */ void *v4l2_m2m_get_curr_priv(struct v4l2_m2m_dev *m2m_dev); @@ -594,6 +598,20 @@ static inline void v4l2_m2m_set_dst_buffered(struct v4= l2_m2m_ctx *m2m_ctx, m2m_ctx->cap_q_ctx.buffered =3D buffered; } =20 +/** + * v4l2_m2m_set_max_parallel_jobs() - adjust the limit of the maximum numb= er of + * jobs being run in parallel. + * + * By default only one job is allowed to be run at any time. A driver with + * multiple cores can call this function to (dynamically) adjust this limit + * based on the underlying hardware capabilities. + * + * @m2m_dev: opaque pointer to the internal data to handle M2M context + * @max_parallel_jobs: maximum number of jobs to queue in parallel + */ +void v4l2_m2m_set_max_parallel_jobs(struct v4l2_m2m_dev *m2m_dev, + u32 max_parallel_jobs); + /** * v4l2_m2m_ctx_release() - release m2m context * --=20 2.55.0 From nobody Fri Sep 25 04:43:51 2026 Received: from mx1.white.stw.pengutronix.de (mx1.white.stw.pengutronix.de [185.203.200.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B29C4392C25; Wed, 16 Sep 2026 15:09:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.200.13 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789571395; cv=none; b=SzO/BRXI6S6k0dSDWBfeEh99EzxdVTGkDNuL8R6zYswfoQCcTXUghwNBbdnpJvOx5JduzPZ/JWqj6WxB3vQIpv8SeF3CXDa495JuUxxrqTZmFG6RmjDtKoUKkN+6vu1J7Gu2H+GfIDObPK+m2If3VGqf4dcOpmSOYCsNc0WjOUU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789571395; c=relaxed/simple; bh=mdWzl/Ow+GuOloQXpteITJ1YNj09nrOSxskSEWFP0ac=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=baUvFF28XbBSqxK1OSoISf/txvCeWgvpZ0OniGTrsyTSN6Y9xa7pYawJcOVHLBbCSfTGZXWa3PfwGnorr3bQ6JJjsTIZpOML5ZDt3DOKh1wV+K8+JGq7F8AgkdOp5ph45oYqHlW9hhS2MdUdqWATSl/DaUIxBUsWVlbSoTf/woY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.200.13 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de X-PTX-Original-Recipient: ezequiel@vanguardiasur.com.ar X-PTX-Original-Recipient: jacob-chen@iotwrt.com X-PTX-Original-Recipient: mchehab@kernel.org X-PTX-Original-Recipient: detlev.casanova@collabora.com X-PTX-Original-Recipient: heiko@sntech.de X-PTX-Original-Recipient: linux-kernel@vger.kernel.org X-PTX-Original-Recipient: linux-media@vger.kernel.org X-PTX-Original-Recipient: linux-arm-kernel@lists.infradead.org X-PTX-Original-Recipient: linux-rockchip@lists.infradead.org X-PTX-Original-Recipient: lgs201920130244@gmail.com X-PTX-Original-Recipient: p.zabel@pengutronix.de X-PTX-Original-Recipient: kernel@pengutronix.de X-PTX-Original-Recipient: s.pueschel@pengutronix.de X-PTX-Original-Recipient: m.tretter@pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de (drehscheibe.grey.stw.pengutronix.de [IPv6:2a0a:edc0:0:c01:1d::a2]) (Authenticated sender: relay-from-drehscheibe.grey.stw.pengutronix.de) by mx1.white.stw.pengutronix.de (Postfix) with ESMTPSA id 2277C2059FA; Wed, 16 Sep 2026 17:09:52 +0200 (CEST) Received: from ptz.office.stw.pengutronix.de ([2a0a:edc0:0:900:1d::77] helo=peter.mobile.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtp (Exim 4.96) (envelope-from ) id 1x6rGi-001Fsx-01; Wed, 16 Sep 2026 17:09:52 +0200 From: =?utf-8?q?Sven_P=C3=BCschel?= Date: Wed, 16 Sep 2026 17:09:49 +0200 Subject: [PATCH v2 08/17] media: rockchip: rga: move power handling to device_run Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260916-spu-rga3multicore-v2-8-23aa2cb74e61@pengutronix.de> References: <20260916-spu-rga3multicore-v2-0-23aa2cb74e61@pengutronix.de> In-Reply-To: <20260916-spu-rga3multicore-v2-0-23aa2cb74e61@pengutronix.de> To: Jacob Chen , Ezequiel Garcia , Mauro Carvalho Chehab , Heiko Stuebner , Philipp Zabel Cc: linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, kernel@pengutronix.de, Detlev Casanova , Michael Tretter , Guangshuo Li , =?utf-8?q?Sven_P=C3=BCschel?= X-Mailer: b4 0.15.2 Move the power handling to the device_run function in preparation for enabling multiple cores. This allows to power the only the necessary cores instead of powering all available cores. As the decision on which core the given job is executed will be done in device_run, we can only power to correct core there. To avoid unpowering the core in a streaming state switch to autosuspend. This avoids powering down the core when the next frame is scheduled in the next 50ms. The timeout maps to a framerate of 20fps, which should be pretty uncommon in a normal video stream. Signed-off-by: Sven P=C3=BCschel --- v2 - also set autosuspend flag with pm_runtime_use_autosuspend (https://sashiko.dev/#/patchset/20260606-spu-rga3multicore-v1-0-3ec2b1567= 5f7%40pengutronix.de?part=3D6) --- drivers/media/platform/rockchip/rga/rga-buf.c | 12 ------------ drivers/media/platform/rockchip/rga/rga.c | 13 +++++++++++++ 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/drivers/media/platform/rockchip/rga/rga-buf.c b/drivers/media/= platform/rockchip/rga/rga-buf.c index c0ea6003336bf..3f7c3c68e0cb8 100644 --- a/drivers/media/platform/rockchip/rga/rga-buf.c +++ b/drivers/media/platform/rockchip/rga/rga-buf.c @@ -242,14 +242,6 @@ static int rga_buf_prepare_streaming(struct vb2_queue = *q) static int rga_buf_start_streaming(struct vb2_queue *q, unsigned int count) { struct rga_ctx *ctx =3D vb2_get_drv_priv(q); - struct rockchip_rga *rga =3D ctx->rga; - int ret; - - ret =3D pm_runtime_resume_and_get(rga->dev); - if (ret < 0) { - rga_buf_return_buffers(q, VB2_BUF_STATE_QUEUED); - return ret; - } =20 if (V4L2_TYPE_IS_OUTPUT(q->type)) ctx->osequence =3D 0; @@ -261,11 +253,7 @@ static int rga_buf_start_streaming(struct vb2_queue *q= , unsigned int count) =20 static void rga_buf_stop_streaming(struct vb2_queue *q) { - struct rga_ctx *ctx =3D vb2_get_drv_priv(q); - struct rockchip_rga *rga =3D ctx->rga; - rga_buf_return_buffers(q, VB2_BUF_STATE_ERROR); - pm_runtime_put(rga->dev); } =20 const struct vb2_ops rga_qops =3D { diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/plat= form/rockchip/rga/rga.c index d7f0712177b70..c24bc8e26b91e 100644 --- a/drivers/media/platform/rockchip/rga/rga.c +++ b/drivers/media/platform/rockchip/rga/rga.c @@ -37,6 +37,14 @@ static void device_run(void *prv) struct rockchip_rga *rga =3D ctx->rga; struct vb2_v4l2_buffer *src, *dst; unsigned long flags; + int ret; + + ret =3D pm_runtime_resume_and_get(rga->dev); + if (ret < 0) { + v4l2_m2m_buf_done_and_job_finish(rga->m2m_dev, ctx->fh.m2m_ctx, + VB2_BUF_STATE_ERROR); + return; + } =20 spin_lock_irqsave(&rga->ctrl_lock, flags); if (ctx->cmdbuf_dirty) { @@ -81,6 +89,8 @@ static irqreturn_t rga_isr(int irq, void *prv) v4l2_m2m_buf_done(src, VB2_BUF_STATE_DONE); v4l2_m2m_buf_done(dst, VB2_BUF_STATE_DONE); v4l2_m2m_job_finish(rga->m2m_dev, ctx->fh.m2m_ctx); + + pm_runtime_put_autosuspend(rga->dev); } =20 return IRQ_HANDLED; @@ -801,6 +811,9 @@ static int rga_probe(struct platform_device *pdev) if (ret) return ret; =20 + pm_runtime_set_autosuspend_delay(rga->dev, 50); + pm_runtime_use_autosuspend(rga->dev); + rga->regs =3D devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(rga->regs)) return PTR_ERR(rga->regs); --=20 2.55.0 From nobody Fri Sep 25 04:43:51 2026 Received: from mx1.white.stw.pengutronix.de (mx1.white.stw.pengutronix.de [185.203.200.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id ED0BE3955FB; Wed, 16 Sep 2026 15:09:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.200.13 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789571397; cv=none; b=Oa6cKzXCM8oNMBZTri+xyNYMlBQCmn/ikNh0ZsGPLZKoniwV+cTKNofgQbEQY4tnjFQmPoGHCpIRQFb1n31m2LuqlkhTDmkjYAQJVxLA5fSQiCFTv6DVswmvvdufQsC1H7DfcuI/muPl3ayYLXm+YLTlMJTBA5yItiM4RIQa9Nk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789571397; c=relaxed/simple; bh=6lYoDfIk4NpAcOB/cW6IiEbe+rssQS994U/XwaDkBi8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ePvdl9JqrPIL3goVaKnBRAf3FiiaLTtfomrSFMjPfqk9dQKWkzxby4G0pVUwc+DsJkRrrSjTo0POqCXziN4IjIOogOuHV+AYKAWVuqxdsyMsWj/UyE3SRICDvf6BUwjy41kREX91PamH+V0OKYjUmMEV5zRLfMFUSWo3LcDY0Ow= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.200.13 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de X-PTX-Original-Recipient: ezequiel@vanguardiasur.com.ar X-PTX-Original-Recipient: jacob-chen@iotwrt.com X-PTX-Original-Recipient: mchehab@kernel.org X-PTX-Original-Recipient: detlev.casanova@collabora.com X-PTX-Original-Recipient: heiko@sntech.de X-PTX-Original-Recipient: linux-kernel@vger.kernel.org X-PTX-Original-Recipient: linux-media@vger.kernel.org X-PTX-Original-Recipient: linux-arm-kernel@lists.infradead.org X-PTX-Original-Recipient: linux-rockchip@lists.infradead.org X-PTX-Original-Recipient: lgs201920130244@gmail.com X-PTX-Original-Recipient: p.zabel@pengutronix.de X-PTX-Original-Recipient: kernel@pengutronix.de X-PTX-Original-Recipient: s.pueschel@pengutronix.de X-PTX-Original-Recipient: m.tretter@pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de (drehscheibe.grey.stw.pengutronix.de [IPv6:2a0a:edc0:0:c01:1d::a2]) (Authenticated sender: relay-from-drehscheibe.grey.stw.pengutronix.de) by mx1.white.stw.pengutronix.de (Postfix) with ESMTPSA id CF4A32059FC; Wed, 16 Sep 2026 17:09:52 +0200 (CEST) Received: from ptz.office.stw.pengutronix.de ([2a0a:edc0:0:900:1d::77] helo=peter.mobile.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtp (Exim 4.96) (envelope-from ) id 1x6rGi-001Fsx-2K; Wed, 16 Sep 2026 17:09:52 +0200 From: =?utf-8?q?Sven_P=C3=BCschel?= Date: Wed, 16 Sep 2026 17:09:50 +0200 Subject: [PATCH v2 09/17] media: rockchip: rga: adjust get_version to return the version Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260916-spu-rga3multicore-v2-9-23aa2cb74e61@pengutronix.de> References: <20260916-spu-rga3multicore-v2-0-23aa2cb74e61@pengutronix.de> In-Reply-To: <20260916-spu-rga3multicore-v2-0-23aa2cb74e61@pengutronix.de> To: Jacob Chen , Ezequiel Garcia , Mauro Carvalho Chehab , Heiko Stuebner , Philipp Zabel Cc: linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, kernel@pengutronix.de, Detlev Casanova , Michael Tretter , Guangshuo Li , =?utf-8?q?Sven_P=C3=BCschel?= X-Mailer: b4 0.15.2 Adjust get_version to return the version instead of directly updating it in the rockchip_rga structure. This is done in preparation for a multi-core support to check that cores with the same compatible share the same version. Signed-off-by: Sven P=C3=BCschel --- drivers/media/platform/rockchip/rga/rga-hw.c | 10 +++++++--- drivers/media/platform/rockchip/rga/rga.c | 2 +- drivers/media/platform/rockchip/rga/rga.h | 2 +- drivers/media/platform/rockchip/rga/rga3-hw.c | 8 +++++--- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/rockchip/rga/rga-hw.c b/drivers/media/p= latform/rockchip/rga/rga-hw.c index 4d7b0a03820a1..190104f3b2954 100644 --- a/drivers/media/platform/rockchip/rga/rga-hw.c +++ b/drivers/media/platform/rockchip/rga/rga-hw.c @@ -474,10 +474,14 @@ static bool rga_handle_irq(struct rockchip_rga *rga) return intr & RGA_INT_COMMAND_FINISHED; } =20 -static void rga_get_version(struct rockchip_rga *rga) +static struct rockchip_rga_version rga_get_version(struct rockchip_rga *rg= a) { - rga->version.major =3D (rga_read(rga, RGA_VERSION_INFO) >> 24) & 0xFF; - rga->version.minor =3D (rga_read(rga, RGA_VERSION_INFO) >> 20) & 0x0F; + u32 version =3D rga_read(rga, RGA_VERSION_INFO); + + return (struct rockchip_rga_version) { + .major =3D (version >> 24) & 0xFF, + .minor =3D (version >> 20) & 0x0F, + }; } =20 static struct rga_fmt formats[] =3D { diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/plat= form/rockchip/rga/rga.c index c24bc8e26b91e..2107d0f4a1659 100644 --- a/drivers/media/platform/rockchip/rga/rga.c +++ b/drivers/media/platform/rockchip/rga/rga.c @@ -860,7 +860,7 @@ static int rga_probe(struct platform_device *pdev) if (ret < 0) goto rel_m2m; =20 - rga->hw->get_version(rga); + rga->version =3D rga->hw->get_version(rga); =20 v4l2_info(&rga->v4l2_dev, "HW Version: 0x%02x.%02x\n", rga->version.major, rga->version.minor); diff --git a/drivers/media/platform/rockchip/rga/rga.h b/drivers/media/plat= form/rockchip/rga/rga.h index 0e62337f8dd38..0e854cdf739f4 100644 --- a/drivers/media/platform/rockchip/rga/rga.h +++ b/drivers/media/platform/rockchip/rga/rga.h @@ -158,7 +158,7 @@ struct rga_hw { void (*start)(struct rockchip_rga *rga, struct rga_vb_buffer *src, struct rga_vb_buffer *dst); bool (*handle_irq)(struct rockchip_rga *rga); - void (*get_version)(struct rockchip_rga *rga); + struct rockchip_rga_version (*get_version)(struct rockchip_rga *rga); void *(*adjust_and_map_format)(struct rga_ctx *ctx, struct v4l2_pix_format_mplane *format, bool is_output); diff --git a/drivers/media/platform/rockchip/rga/rga3-hw.c b/drivers/media/= platform/rockchip/rga/rga3-hw.c index 46ba6d270f232..a80dd7609ccfe 100644 --- a/drivers/media/platform/rockchip/rga/rga3-hw.c +++ b/drivers/media/platform/rockchip/rga/rga3-hw.c @@ -299,12 +299,14 @@ static bool rga3_handle_irq(struct rockchip_rga *rga) return FIELD_GET(RGA3_INT_FRM_DONE, intr); } =20 -static void rga3_get_version(struct rockchip_rga *rga) +static struct rockchip_rga_version rga3_get_version(struct rockchip_rga *r= ga) { u32 version =3D rga_read(rga, RGA3_VERSION_NUM); =20 - rga->version.major =3D FIELD_GET(RGA3_VERSION_NUM_MAJOR, version); - rga->version.minor =3D FIELD_GET(RGA3_VERSION_NUM_MINOR, version); + return (struct rockchip_rga_version) { + .major =3D FIELD_GET(RGA3_VERSION_NUM_MAJOR, version), + .minor =3D FIELD_GET(RGA3_VERSION_NUM_MINOR, version), + }; } =20 static struct rga3_fmt rga3_formats[] =3D { --=20 2.55.0 From nobody Fri Sep 25 04:43:51 2026 Received: from mx1.white.stw.pengutronix.de (mx1.white.stw.pengutronix.de [185.203.200.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 71CE1379C3F; Wed, 16 Sep 2026 15:15:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.200.13 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789571703; cv=none; b=OS095FXgi5oTcZ/ew3eldwA+1rUPvc05KVVPOV+6sC9FmVSGAk+U5HArT5qCvtp+y/G/yHAOtQZJE48zsUEIk367i7n//zkUYZCufXBH2Z5eE5MS7HkSPh8tC58pUGV9vktL2jnXVt5VLo/m8ek/uIvDZ88QX2D4eSROu8SS758= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789571703; c=relaxed/simple; bh=x4D50AK+nxP14CvtpemUAdya/WhpUWxBpUdgfosMqOI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=iWy9kE3c9cQjwzYSI5VmCrou9ol1dR4JfvEuofJStjTKwIe813lJ4IcIo1YY13Dem8yFxGCT/nYgpmERFS/dLDNC3cBIhFg7nn6qOVRVIQme05qzcZGy2ifK6MIlB2rWFrdNnrlbc2N8XyVXle1efP5RBkxFMWdw8ULAPl+kVYM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.200.13 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de X-PTX-Original-Recipient: ezequiel@vanguardiasur.com.ar X-PTX-Original-Recipient: jacob-chen@iotwrt.com X-PTX-Original-Recipient: mchehab@kernel.org X-PTX-Original-Recipient: detlev.casanova@collabora.com X-PTX-Original-Recipient: heiko@sntech.de X-PTX-Original-Recipient: linux-kernel@vger.kernel.org X-PTX-Original-Recipient: linux-media@vger.kernel.org X-PTX-Original-Recipient: linux-arm-kernel@lists.infradead.org X-PTX-Original-Recipient: linux-rockchip@lists.infradead.org X-PTX-Original-Recipient: lgs201920130244@gmail.com X-PTX-Original-Recipient: p.zabel@pengutronix.de X-PTX-Original-Recipient: kernel@pengutronix.de X-PTX-Original-Recipient: s.pueschel@pengutronix.de X-PTX-Original-Recipient: m.tretter@pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de (drehscheibe.grey.stw.pengutronix.de [IPv6:2a0a:edc0:0:c01:1d::a2]) (Authenticated sender: relay-from-drehscheibe.grey.stw.pengutronix.de) by mx1.white.stw.pengutronix.de (Postfix) with ESMTPSA id 61474205A00; Wed, 16 Sep 2026 17:14:58 +0200 (CEST) Received: from ptz.office.stw.pengutronix.de ([2a0a:edc0:0:900:1d::77] helo=peter.mobile.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtp (Exim 4.96) (envelope-from ) id 1x6rGj-001Fsx-1O; Wed, 16 Sep 2026 17:09:53 +0200 From: =?utf-8?q?Sven_P=C3=BCschel?= Date: Wed, 16 Sep 2026 17:09:51 +0200 Subject: [PATCH v2 10/17] media: rockchip: rga: add rga_core structure Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260916-spu-rga3multicore-v2-10-23aa2cb74e61@pengutronix.de> References: <20260916-spu-rga3multicore-v2-0-23aa2cb74e61@pengutronix.de> In-Reply-To: <20260916-spu-rga3multicore-v2-0-23aa2cb74e61@pengutronix.de> To: Jacob Chen , Ezequiel Garcia , Mauro Carvalho Chehab , Heiko Stuebner , Philipp Zabel Cc: linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, kernel@pengutronix.de, Detlev Casanova , Michael Tretter , Guangshuo Li , =?utf-8?q?Sven_P=C3=BCschel?= X-Mailer: b4 0.15.2 Add a rga_core structure to separate the core specific data from the m2m device. This is done in preparation for multi-core support, where multiple identical cores are exposed as a single m2m device to the user-space. Allocation related calls are explicitly done on the first core, as the scheduling decisions will be made on demand after the buffers have been allocated and filled. In preparation of storing the rockchip_rga struct on a dedicated master platform device, the rga_core struct is allocated on it's own and only a pointer is saved in the rockchip_rga struct. Signed-off-by: Sven P=C3=BCschel --- v2: - fixed NULL pointer dereference of devm_kzalloc (pointed out by Sashiko and Nicolas) - removed unintended whitespace deletion --- drivers/media/platform/rockchip/rga/rga-buf.c | 4 +- drivers/media/platform/rockchip/rga/rga-hw.c | 32 ++++---- drivers/media/platform/rockchip/rga/rga.c | 105 +++++++++++++++-------= ---- drivers/media/platform/rockchip/rga/rga.h | 38 ++++++---- drivers/media/platform/rockchip/rga/rga3-hw.c | 24 +++--- 5 files changed, 110 insertions(+), 93 deletions(-) diff --git a/drivers/media/platform/rockchip/rga/rga-buf.c b/drivers/media/= platform/rockchip/rga/rga-buf.c index 3f7c3c68e0cb8..47a8d5a4500a3 100644 --- a/drivers/media/platform/rockchip/rga/rga-buf.c +++ b/drivers/media/platform/rockchip/rga/rga-buf.c @@ -93,7 +93,7 @@ static int rga_buf_init(struct vb2_buffer *vb) n_desc =3D DIV_ROUND_UP(size, PAGE_SIZE); =20 rbuf->n_desc =3D n_desc; - rbuf->dma_desc =3D dma_alloc_coherent(rga->dev, + rbuf->dma_desc =3D dma_alloc_coherent(rga->cores[0]->dev, rbuf->n_desc * sizeof(*rbuf->dma_desc), &rbuf->dma_desc_pa, GFP_KERNEL); if (!rbuf->dma_desc) @@ -191,7 +191,7 @@ static void rga_buf_cleanup(struct vb2_buffer *vb) if (!rga_has_internal_iommu(rga)) return; =20 - dma_free_coherent(rga->dev, rbuf->n_desc * sizeof(*rbuf->dma_desc), + dma_free_coherent(rga->cores[0]->dev, rbuf->n_desc * sizeof(*rbuf->dma_de= sc), rbuf->dma_desc, rbuf->dma_desc_pa); } =20 diff --git a/drivers/media/platform/rockchip/rga/rga-hw.c b/drivers/media/p= latform/rockchip/rga/rga-hw.c index 190104f3b2954..9a5da4e1716ca 100644 --- a/drivers/media/platform/rockchip/rga/rga-hw.c +++ b/drivers/media/platform/rockchip/rga/rga-hw.c @@ -417,10 +417,10 @@ static void rga_cmd_set_mode(struct rga_ctx *ctx) dest[(RGA_MODE_CTRL - RGA_MODE_BASE_REG) >> 2] =3D mode.val; } =20 -static void rga_cmd_set(struct rga_ctx *ctx, +static void rga_cmd_set(struct rga_core *core, struct rga_vb_buffer *src, struct rga_vb_buffer *dst) { - struct rockchip_rga *rga =3D ctx->rga; + struct rga_ctx *ctx =3D core->curr; =20 rga_cmd_set_src_addr(ctx, src->dma_desc_pa); /* @@ -434,10 +434,10 @@ static void rga_cmd_set(struct rga_ctx *ctx, rga_cmd_set_src_info(ctx, &src->dma_addrs); rga_cmd_set_dst_info(ctx, &dst->dma_addrs); =20 - rga_write(rga, RGA_CMD_BASE, ctx->cmdbuf_phy); + rga_write(core, RGA_CMD_BASE, ctx->cmdbuf_phy); =20 /* sync CMD buf for RGA */ - dma_sync_single_for_device(rga->dev, ctx->cmdbuf_phy, + dma_sync_single_for_device(core->rga->cores[0]->dev, ctx->cmdbuf_phy, PAGE_SIZE, DMA_BIDIRECTIONAL); } =20 @@ -447,36 +447,34 @@ static void rga_hw_setup_cmdbuf(struct rga_ctx *ctx) rga_cmd_set_trans_info(ctx); } =20 -static void rga_hw_start(struct rockchip_rga *rga, +static void rga_hw_start(struct rga_core *core, struct rga_vb_buffer *src, struct rga_vb_buffer *dst) { - struct rga_ctx *ctx =3D rga->curr; - - rga_cmd_set(ctx, src, dst); + rga_cmd_set(core, src, dst); =20 - rga_write(rga, RGA_SYS_CTRL, 0x00); + rga_write(core, RGA_SYS_CTRL, 0x00); =20 - rga_write(rga, RGA_SYS_CTRL, 0x22); + rga_write(core, RGA_SYS_CTRL, 0x22); =20 - rga_write(rga, RGA_INT, 0x600); + rga_write(core, RGA_INT, 0x600); =20 - rga_write(rga, RGA_CMD_CTRL, 0x1); + rga_write(core, RGA_CMD_CTRL, 0x1); } =20 -static bool rga_handle_irq(struct rockchip_rga *rga) +static bool rga_handle_irq(struct rga_core *core) { int intr; =20 - intr =3D rga_read(rga, RGA_INT) & 0xf; + intr =3D rga_read(core, RGA_INT) & 0xf; =20 - rga_mod(rga, RGA_INT, intr << 4, 0xf << 4); + rga_mod(core, RGA_INT, intr << 4, 0xf << 4); =20 return intr & RGA_INT_COMMAND_FINISHED; } =20 -static struct rockchip_rga_version rga_get_version(struct rockchip_rga *rg= a) +static struct rockchip_rga_version rga_get_version(struct rga_core *core) { - u32 version =3D rga_read(rga, RGA_VERSION_INFO); + u32 version =3D rga_read(core, RGA_VERSION_INFO); =20 return (struct rockchip_rga_version) { .major =3D (version >> 24) & 0xFF, diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/plat= form/rockchip/rga/rga.c index 2107d0f4a1659..bcfc19d29af74 100644 --- a/drivers/media/platform/rockchip/rga/rga.c +++ b/drivers/media/platform/rockchip/rga/rga.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -35,11 +36,12 @@ static void device_run(void *prv) { struct rga_ctx *ctx =3D prv; struct rockchip_rga *rga =3D ctx->rga; + struct rga_core *core =3D rga->cores[0]; struct vb2_v4l2_buffer *src, *dst; unsigned long flags; int ret; =20 - ret =3D pm_runtime_resume_and_get(rga->dev); + ret =3D 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); @@ -54,27 +56,28 @@ static void device_run(void *prv) } spin_unlock_irqrestore(&rga->ctrl_lock, flags); =20 - rga->curr =3D ctx; + core->curr =3D ctx; =20 src =3D v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); src->sequence =3D ctx->osequence++; =20 dst =3D v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); =20 - rga->hw->start(rga, vb_to_rga(src), vb_to_rga(dst)); + rga->hw->start(core, vb_to_rga(src), vb_to_rga(dst)); } =20 static irqreturn_t rga_isr(int irq, void *prv) { - struct rockchip_rga *rga =3D prv; + struct rga_core *core =3D prv; + struct rockchip_rga *rga =3D core->rga; =20 - if (rga->hw->handle_irq(rga)) { + if (rga->hw->handle_irq(core)) { struct vb2_v4l2_buffer *src, *dst; - struct rga_ctx *ctx =3D rga->curr; + struct rga_ctx *ctx =3D core->curr; =20 WARN_ON(!ctx); =20 - rga->curr =3D NULL; + core->curr =3D NULL; =20 src =3D v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); dst =3D v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); @@ -90,7 +93,7 @@ static irqreturn_t rga_isr(int irq, void *prv) v4l2_m2m_buf_done(dst, VB2_BUF_STATE_DONE); v4l2_m2m_job_finish(rga->m2m_dev, ctx->fh.m2m_ctx); =20 - pm_runtime_put_autosuspend(rga->dev); + pm_runtime_put_autosuspend(core->dev); } =20 return IRQ_HANDLED; @@ -118,7 +121,7 @@ queue_init(void *priv, struct vb2_queue *src_vq, struct= vb2_queue *dst_vq) src_vq->buf_struct_size =3D sizeof(struct rga_vb_buffer); src_vq->timestamp_flags =3D V4L2_BUF_FLAG_TIMESTAMP_COPY; src_vq->lock =3D &ctx->rga->mutex; - src_vq->dev =3D ctx->rga->v4l2_dev.dev; + src_vq->dev =3D ctx->rga->cores[0]->dev; =20 ret =3D vb2_queue_init(src_vq); if (ret) @@ -136,7 +139,7 @@ queue_init(void *priv, struct vb2_queue *src_vq, struct= vb2_queue *dst_vq) dst_vq->buf_struct_size =3D sizeof(struct rga_vb_buffer); dst_vq->timestamp_flags =3D V4L2_BUF_FLAG_TIMESTAMP_COPY; dst_vq->lock =3D &ctx->rga->mutex; - dst_vq->dev =3D ctx->rga->v4l2_dev.dev; + dst_vq->dev =3D ctx->rga->cores[0]->dev; =20 return vb2_queue_init(dst_vq); } @@ -275,7 +278,7 @@ static int rga_open(struct file *file) return -ENOMEM; =20 /* Create CMD buffer */ - ctx->cmdbuf_virt =3D dma_alloc_attrs(rga->dev, rga->hw->cmdbuf_size, + ctx->cmdbuf_virt =3D dma_alloc_attrs(rga->cores[0]->dev, rga->hw->cmdbuf_= size, &ctx->cmdbuf_phy, GFP_KERNEL, DMA_ATTR_WRITE_COMBINE); if (!ctx->cmdbuf_virt) { @@ -322,7 +325,7 @@ static int rga_open(struct file *file) unlock_mutex: mutex_unlock(&rga->mutex); rel_cmdbuf: - dma_free_attrs(rga->dev, rga->hw->cmdbuf_size, ctx->cmdbuf_virt, + dma_free_attrs(rga->cores[0]->dev, rga->hw->cmdbuf_size, ctx->cmdbuf_virt, ctx->cmdbuf_phy, DMA_ATTR_WRITE_COMBINE); rel_ctx: kfree(ctx); @@ -342,7 +345,7 @@ static int rga_release(struct file *file) v4l2_fh_del(&ctx->fh, file); v4l2_fh_exit(&ctx->fh); =20 - dma_free_attrs(rga->dev, rga->hw->cmdbuf_size, ctx->cmdbuf_virt, + dma_free_attrs(rga->cores[0]->dev, rga->hw->cmdbuf_size, ctx->cmdbuf_virt, ctx->cmdbuf_phy, DMA_ATTR_WRITE_COMBINE); =20 kfree(ctx); @@ -689,26 +692,26 @@ static const struct video_device rga_videodev =3D { .device_caps =3D V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING, }; =20 -static int rga_parse_dt(struct rockchip_rga *rga) +static int rga_parse_dt(struct rga_core *core) { struct reset_control *core_rst, *axi_rst, *ahb_rst; int ret; =20 - core_rst =3D devm_reset_control_get(rga->dev, "core"); + core_rst =3D devm_reset_control_get(core->dev, "core"); if (IS_ERR(core_rst)) { - dev_err(rga->dev, "failed to get core reset controller\n"); + dev_err(core->dev, "failed to get core reset controller\n"); return PTR_ERR(core_rst); } =20 - axi_rst =3D devm_reset_control_get(rga->dev, "axi"); + axi_rst =3D devm_reset_control_get(core->dev, "axi"); if (IS_ERR(axi_rst)) { - dev_err(rga->dev, "failed to get axi reset controller\n"); + dev_err(core->dev, "failed to get axi reset controller\n"); return PTR_ERR(axi_rst); } =20 - ahb_rst =3D devm_reset_control_get(rga->dev, "ahb"); + ahb_rst =3D devm_reset_control_get(core->dev, "ahb"); if (IS_ERR(ahb_rst)) { - dev_err(rga->dev, "failed to get ahb reset controller\n"); + dev_err(core->dev, "failed to get ahb reset controller\n"); return PTR_ERR(ahb_rst); } =20 @@ -724,12 +727,12 @@ static int rga_parse_dt(struct rockchip_rga *rga) udelay(1); reset_control_deassert(ahb_rst); =20 - ret =3D devm_clk_bulk_get_all(rga->dev, &rga->clks); + ret =3D devm_clk_bulk_get_all(core->dev, &core->clks); if (ret < 0) { - dev_err(rga->dev, "failed to get clocks\n"); + dev_err(core->dev, "failed to get clocks\n"); return ret; } - rga->num_clks =3D ret; + core->num_clks =3D ret; =20 return 0; } @@ -780,6 +783,7 @@ static int rga_disable_multicore(struct device *dev) static int rga_probe(struct platform_device *pdev) { struct rockchip_rga *rga; + struct rga_core *core; struct video_device *vfd; int ret =3D 0; int irq; @@ -791,7 +795,7 @@ static int rga_probe(struct platform_device *pdev) if (ret) return ret; =20 - rga =3D devm_kzalloc(&pdev->dev, sizeof(*rga), GFP_KERNEL); + rga =3D devm_kzalloc(&pdev->dev, sizeof(*rga) + 1 * sizeof(*rga->cores), = GFP_KERNEL); if (!rga) return -ENOMEM; =20 @@ -799,38 +803,46 @@ static int rga_probe(struct platform_device *pdev) if (!rga->hw) return dev_err_probe(&pdev->dev, -ENODEV, "failed to get match data\n"); =20 - rga->dev =3D &pdev->dev; spin_lock_init(&rga->ctrl_lock); mutex_init(&rga->mutex); =20 - ret =3D rga_parse_dt(rga); + core =3D devm_kzalloc(&pdev->dev, sizeof(*core), GFP_KERNEL); + if (!core) + return -ENOMEM; + + core->rga =3D rga; + core->dev =3D &pdev->dev; + + rga->cores[0] =3D core; + + ret =3D rga_parse_dt(core); if (ret) return dev_err_probe(&pdev->dev, ret, "Unable to parse OF data\n"); =20 - ret =3D devm_pm_runtime_enable(rga->dev); + ret =3D devm_pm_runtime_enable(core->dev); if (ret) return ret; =20 - pm_runtime_set_autosuspend_delay(rga->dev, 50); - pm_runtime_use_autosuspend(rga->dev); + pm_runtime_set_autosuspend_delay(core->dev, 50); + pm_runtime_use_autosuspend(core->dev); =20 - rga->regs =3D devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(rga->regs)) - return PTR_ERR(rga->regs); + core->regs =3D devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(core->regs)) + return PTR_ERR(core->regs); =20 irq =3D platform_get_irq(pdev, 0); if (irq < 0) return irq; =20 - ret =3D devm_request_irq(rga->dev, irq, rga_isr, + ret =3D devm_request_irq(core->dev, irq, rga_isr, rga_has_internal_iommu(rga) ? 0 : IRQF_SHARED, - dev_name(rga->dev), rga); + dev_name(core->dev), core); if (ret < 0) - return dev_err_probe(rga->dev, ret, "failed to request irq\n"); + return dev_err_probe(core->dev, ret, "failed to request irq\n"); =20 - ret =3D dma_set_mask_and_coherent(rga->dev, DMA_BIT_MASK(32)); + ret =3D dma_set_mask_and_coherent(core->dev, DMA_BIT_MASK(32)); if (ret) - dev_err_probe(rga->dev, ret, "32-bit DMA not supported"); + dev_err_probe(core->dev, ret, "32-bit DMA not supported"); =20 ret =3D v4l2_device_register(&pdev->dev, &rga->v4l2_dev); if (ret) @@ -848,7 +860,7 @@ static int rga_probe(struct platform_device *pdev) video_set_drvdata(vfd, rga); rga->vfd =3D vfd; =20 - platform_set_drvdata(pdev, rga); + platform_set_drvdata(pdev, core); rga->m2m_dev =3D v4l2_m2m_init(&rga_m2m_ops); if (IS_ERR(rga->m2m_dev)) { v4l2_err(&rga->v4l2_dev, "Failed to init mem2mem device\n"); @@ -856,16 +868,16 @@ static int rga_probe(struct platform_device *pdev) goto rel_vdev; } =20 - ret =3D pm_runtime_resume_and_get(rga->dev); + ret =3D pm_runtime_resume_and_get(core->dev); if (ret < 0) goto rel_m2m; =20 - rga->version =3D rga->hw->get_version(rga); + rga->version =3D rga->hw->get_version(core); =20 v4l2_info(&rga->v4l2_dev, "HW Version: 0x%02x.%02x\n", rga->version.major, rga->version.minor); =20 - pm_runtime_put(rga->dev); + pm_runtime_put(core->dev); =20 ret =3D video_register_device(vfd, VFL_TYPE_VIDEO, -1); if (ret) { @@ -890,7 +902,8 @@ static int rga_probe(struct platform_device *pdev) =20 static void rga_remove(struct platform_device *pdev) { - struct rockchip_rga *rga =3D platform_get_drvdata(pdev); + struct rga_core *core =3D platform_get_drvdata(pdev); + struct rockchip_rga *rga =3D core->rga; =20 v4l2_info(&rga->v4l2_dev, "Removing\n"); =20 @@ -901,18 +914,18 @@ static void rga_remove(struct platform_device *pdev) =20 static int __maybe_unused rga_runtime_suspend(struct device *dev) { - struct rockchip_rga *rga =3D dev_get_drvdata(dev); + struct rga_core *core =3D dev_get_drvdata(dev); =20 - clk_bulk_disable_unprepare(rga->num_clks, rga->clks); + clk_bulk_disable_unprepare(core->num_clks, core->clks); =20 return 0; } =20 static int __maybe_unused rga_runtime_resume(struct device *dev) { - struct rockchip_rga *rga =3D dev_get_drvdata(dev); + struct rga_core *core =3D dev_get_drvdata(dev); =20 - return clk_bulk_prepare_enable(rga->num_clks, rga->clks); + return clk_bulk_prepare_enable(core->num_clks, core->clks); } =20 static const struct dev_pm_ops rga_pm =3D { diff --git a/drivers/media/platform/rockchip/rga/rga.h b/drivers/media/plat= form/rockchip/rga/rga.h index 0e854cdf739f4..94e14c2a2ba6e 100644 --- a/drivers/media/platform/rockchip/rga/rga.h +++ b/drivers/media/platform/rockchip/rga/rga.h @@ -36,6 +36,16 @@ struct rockchip_rga_version { u32 minor; }; =20 +struct rga_core { + struct device *dev; + void __iomem *regs; + struct clk_bulk_data *clks; + int num_clks; + + struct rockchip_rga *rga; + struct rga_ctx *curr; +}; + struct rga_ctx { struct v4l2_fh fh; struct rockchip_rga *rga; @@ -70,10 +80,6 @@ struct rockchip_rga { struct v4l2_m2m_dev *m2m_dev; struct video_device *vfd; =20 - struct device *dev; - void __iomem *regs; - struct clk_bulk_data *clks; - int num_clks; struct rockchip_rga_version version; =20 /* vfd lock */ @@ -81,9 +87,9 @@ struct rockchip_rga { /* ctrl parm lock */ spinlock_t ctrl_lock; =20 - struct rga_ctx *curr; - const struct rga_hw *hw; + + struct rga_core *cores[]; }; =20 struct rga_addrs { @@ -119,22 +125,22 @@ int rga_check_scaling(const struct rga_hw *hw, const = struct v4l2_rect *crop_in, extern const struct vb2_ops rga_qops; =20 /* RGA Hardware */ -static inline void rga_write(struct rockchip_rga *rga, u32 reg, u32 value) +static inline void rga_write(struct rga_core *core, u32 reg, u32 value) { - writel(value, rga->regs + reg); + writel(value, core->regs + reg); }; =20 -static inline u32 rga_read(struct rockchip_rga *rga, u32 reg) +static inline u32 rga_read(struct rga_core *core, u32 reg) { - return readl(rga->regs + reg); + return readl(core->regs + reg); }; =20 -static inline void rga_mod(struct rockchip_rga *rga, u32 reg, u32 val, u32= mask) +static inline void rga_mod(struct rga_core *core, u32 reg, u32 val, u32 ma= sk) { - u32 temp =3D rga_read(rga, reg) & ~(mask); + u32 temp =3D rga_read(core, reg) & ~(mask); =20 temp |=3D val & mask; - rga_write(rga, reg, temp); + rga_write(core, reg, temp); }; =20 #define RGA_FEATURE_FLIP BIT(0) @@ -155,10 +161,10 @@ struct rga_hw { * Requires that the cmdbuf is already zeroed. */ void (*setup_cmdbuf)(struct rga_ctx *ctx); - void (*start)(struct rockchip_rga *rga, + void (*start)(struct rga_core *core, struct rga_vb_buffer *src, struct rga_vb_buffer *dst); - bool (*handle_irq)(struct rockchip_rga *rga); - struct rockchip_rga_version (*get_version)(struct rockchip_rga *rga); + bool (*handle_irq)(struct rga_core *core); + struct rockchip_rga_version (*get_version)(struct rga_core *core); void *(*adjust_and_map_format)(struct rga_ctx *ctx, struct v4l2_pix_format_mplane *format, bool is_output); diff --git a/drivers/media/platform/rockchip/rga/rga3-hw.c b/drivers/media/= platform/rockchip/rga/rga3-hw.c index a80dd7609ccfe..745760d830a61 100644 --- a/drivers/media/platform/rockchip/rga/rga3-hw.c +++ b/drivers/media/platform/rockchip/rga/rga3-hw.c @@ -266,42 +266,42 @@ static void rga3_hw_setup_cmdbuf(struct rga_ctx *ctx) rga3_cmd_set_wr_format(ctx); } =20 -static void rga3_hw_start(struct rockchip_rga *rga, +static void rga3_hw_start(struct rga_core *core, struct rga_vb_buffer *src, struct rga_vb_buffer *dst) { - struct rga_ctx *ctx =3D rga->curr; + struct rga_ctx *ctx =3D core->curr; =20 rga3_cmd_set_win0_addr(ctx, &src->dma_addrs); rga3_cmd_set_wr_addr(ctx, &dst->dma_addrs); =20 - rga_write(rga, RGA3_CMD_ADDR, ctx->cmdbuf_phy); + rga_write(core, RGA3_CMD_ADDR, ctx->cmdbuf_phy); =20 /* sync CMD buf for RGA */ - dma_sync_single_for_device(rga->dev, ctx->cmdbuf_phy, + dma_sync_single_for_device(core->rga->cores[0]->dev, ctx->cmdbuf_phy, PAGE_SIZE, DMA_BIDIRECTIONAL); =20 /* set to master mode and start the conversion */ - rga_write(rga, RGA3_SYS_CTRL, + rga_write(core, RGA3_SYS_CTRL, FIELD_PREP(RGA3_CMD_MODE, RGA3_CMD_MODE_MASTER)); - rga_write(rga, RGA3_INT_EN, FIELD_PREP(RGA3_INT_FRM_DONE, 1)); - rga_write(rga, RGA3_CMD_CTRL, + rga_write(core, RGA3_INT_EN, FIELD_PREP(RGA3_INT_FRM_DONE, 1)); + rga_write(core, RGA3_CMD_CTRL, FIELD_PREP(RGA3_CMD_LINE_START_PULSE, 1)); } =20 -static bool rga3_handle_irq(struct rockchip_rga *rga) +static bool rga3_handle_irq(struct rga_core *core) { u32 intr; =20 - intr =3D rga_read(rga, RGA3_INT_RAW); + intr =3D rga_read(core, RGA3_INT_RAW); /* clear all interrupts */ - rga_write(rga, RGA3_INT_CLR, intr); + rga_write(core, RGA3_INT_CLR, intr); =20 return FIELD_GET(RGA3_INT_FRM_DONE, intr); } =20 -static struct rockchip_rga_version rga3_get_version(struct rockchip_rga *r= ga) +static struct rockchip_rga_version rga3_get_version(struct rga_core *core) { - u32 version =3D rga_read(rga, RGA3_VERSION_NUM); + u32 version =3D rga_read(core, RGA3_VERSION_NUM); =20 return (struct rockchip_rga_version) { .major =3D FIELD_GET(RGA3_VERSION_NUM_MAJOR, version), --=20 2.55.0 From nobody Fri Sep 25 04:43:51 2026 Received: from mx1.white.stw.pengutronix.de (mx1.white.stw.pengutronix.de [185.203.200.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E20E238E8A9; Wed, 16 Sep 2026 15:15:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.200.13 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789571710; cv=none; b=nV+ncDdILqMmzKfRK7Ha2HBgZRnd7NIVyzArZQBkRRUDoSwybZSR2iBsITTxTkn4ZkiWxRvFQqgIcv8yL/T/TbqSvPecQuEuHmMlPfP67xj4YnJF27rercMTztE0KVfISOSLre9DkcCoubboZCF+7DDr7612EjkhhtPJbdp6Rg8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789571710; c=relaxed/simple; bh=Kb1WAioSBjDBT9zdQKjZ05AsDU04Lf5cxplc2oKHs6s=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=SC7WvlWYV56xbyyxvnCZ7ZqOGlyA2mY25ezJMOmgDoPQp6gbG7IqV3w4izB6b6FUIxJt+iqU4Ugrq3q/AE/+gwZ2FxGzNnZRNN5sdZJ5ZpUl0Pe3WgonLnFgkGvv2tRjpv5vtDAw2xqndSWEZeE0ym30GOnPMYAdz3CPF+chl+Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.200.13 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de X-PTX-Original-Recipient: ezequiel@vanguardiasur.com.ar X-PTX-Original-Recipient: jacob-chen@iotwrt.com X-PTX-Original-Recipient: mchehab@kernel.org X-PTX-Original-Recipient: detlev.casanova@collabora.com X-PTX-Original-Recipient: heiko@sntech.de X-PTX-Original-Recipient: linux-kernel@vger.kernel.org X-PTX-Original-Recipient: linux-media@vger.kernel.org X-PTX-Original-Recipient: linux-arm-kernel@lists.infradead.org X-PTX-Original-Recipient: linux-rockchip@lists.infradead.org X-PTX-Original-Recipient: lgs201920130244@gmail.com X-PTX-Original-Recipient: p.zabel@pengutronix.de X-PTX-Original-Recipient: kernel@pengutronix.de X-PTX-Original-Recipient: s.pueschel@pengutronix.de X-PTX-Original-Recipient: m.tretter@pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de (drehscheibe.grey.stw.pengutronix.de [IPv6:2a0a:edc0:0:c01:1d::a2]) (Authenticated sender: relay-from-drehscheibe.grey.stw.pengutronix.de) by mx1.white.stw.pengutronix.de (Postfix) with ESMTPSA id 111FD205A09; Wed, 16 Sep 2026 17:14:59 +0200 (CEST) Received: from ptz.office.stw.pengutronix.de ([2a0a:edc0:0:900:1d::77] helo=peter.mobile.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtp (Exim 4.96) (envelope-from ) id 1x6rGk-001Fsx-0d; Wed, 16 Sep 2026 17:09:54 +0200 From: =?utf-8?q?Sven_P=C3=BCschel?= Date: Wed, 16 Sep 2026 17:09:52 +0200 Subject: [PATCH v2 11/17] media: rockchip: rga: use components to manage multiple cores Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260916-spu-rga3multicore-v2-11-23aa2cb74e61@pengutronix.de> References: <20260916-spu-rga3multicore-v2-0-23aa2cb74e61@pengutronix.de> In-Reply-To: <20260916-spu-rga3multicore-v2-0-23aa2cb74e61@pengutronix.de> To: Jacob Chen , Ezequiel Garcia , Mauro Carvalho Chehab , Heiko Stuebner , Philipp Zabel Cc: linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, kernel@pengutronix.de, Detlev Casanova , Michael Tretter , Guangshuo Li , =?utf-8?q?Sven_P=C3=BCschel?= X-Mailer: b4 0.15.2 Use component helpers to manage multiple cores and aggregate them into a central master device. This gives us a dedicated master device and ensures that all cores (components) are properly set up before creating the video device. This commit only sets up a basic component device. Instead of the rga_disable_multicore function only the first core is added to the master device. To avoid the secondary core creating an additional video device the whole core probe implementation is moved to the bind method, which is only called when the core is bound to a master device. As we use devres (devm_*) functions for resource cleanup in the probe, it is technically incorrect to use them in a component bind function. It'll be properly split out again in the follow-up commits to avoid having one big migration commit. The implementation is based on the etnaviv gpu driver, which also groups multiple gpu cores under a single etnaviv master device. Signed-off-by: Sven P=C3=BCschel --- v2 - clarify that devres in component bind functions is technically incorrect and only done to keep the commits split up - use dev_err_probe instead of dev_err + return for a failed component_add - remove if (!match) check in rga_probe, as it's only called when we have found at least one dt entry (and sashiko pointed out that it's an err ptr) - add platform_device_id table to avoid a manual binding --- drivers/media/platform/rockchip/rga/rga.c | 263 ++++++++++++++++++++++++--= ---- 1 file changed, 209 insertions(+), 54 deletions(-) diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/plat= form/rockchip/rga/rga.c index bcfc19d29af74..367df0ee7b02f 100644 --- a/drivers/media/platform/rockchip/rga/rga.c +++ b/drivers/media/platform/rockchip/rga/rga.c @@ -5,6 +5,7 @@ */ =20 #include +#include #include #include #include @@ -737,51 +738,9 @@ static int rga_parse_dt(struct rga_core *core) return 0; } =20 -/* - * Some SoCs, like RK3588 have multiple identical RGA3 cores, but the - * kernel is currently missing support for multi-core handling. Exposing - * separate devices for each core to userspace is bad, since that does - * not allow scheduling tasks properly (and creates ABI). With this workar= ound - * the driver will only probe for the first core and early exit for the ot= her - * cores. Once the driver gains multi-core support, the same technique - * for detecting the main core can be used to cluster all cores together. - */ -static int rga_disable_multicore(struct device *dev) -{ - struct device_node *node =3D NULL; - const char *compatible; - bool is_main_core; - int ret; - - /* Intentionally ignores the fallback strings */ - ret =3D of_property_read_string(dev->of_node, "compatible", &compatible); - if (ret) - return ret; - - /* The first compatible and available node found is considered the main c= ore */ - do { - node =3D of_find_compatible_node(node, NULL, compatible); - if (of_device_is_available(node)) - break; - } while (node); - - if (!node) - return -EINVAL; - - is_main_core =3D (dev->of_node =3D=3D node); - - of_node_put(node); - - if (!is_main_core) { - dev_info(dev, "missing multi-core support, ignoring this instance\n"); - return -ENODEV; - } - - return 0; -} - -static int rga_probe(struct platform_device *pdev) +static int rga_core_bind(struct device *dev, struct device *master, void *= data) { + struct platform_device *pdev =3D to_platform_device(dev); struct rockchip_rga *rga; struct rga_core *core; struct video_device *vfd; @@ -791,10 +750,6 @@ static int rga_probe(struct platform_device *pdev) if (!pdev->dev.of_node) return -ENODEV; =20 - ret =3D rga_disable_multicore(&pdev->dev); - if (ret) - return ret; - rga =3D devm_kzalloc(&pdev->dev, sizeof(*rga) + 1 * sizeof(*rga->cores), = GFP_KERNEL); if (!rga) return -ENOMEM; @@ -900,9 +855,10 @@ static int rga_probe(struct platform_device *pdev) return ret; } =20 -static void rga_remove(struct platform_device *pdev) +static void rga_core_unbind(struct device *dev, struct device *master, + void *data) { - struct rga_core *core =3D platform_get_drvdata(pdev); + struct rga_core *core =3D dev_get_drvdata(dev); struct rockchip_rga *rga =3D core->rga; =20 v4l2_info(&rga->v4l2_dev, "Removing\n"); @@ -912,6 +868,27 @@ static void rga_remove(struct platform_device *pdev) v4l2_device_unregister(&rga->v4l2_dev); } =20 +static const struct component_ops rga_core_ops =3D { + .bind =3D rga_core_bind, + .unbind =3D rga_core_unbind, +}; + +static int rga_core_probe(struct platform_device *pdev) +{ + int ret =3D 0; + + ret =3D component_add(&pdev->dev, &rga_core_ops); + if (ret < 0) + return dev_err_probe(&pdev->dev, ret, "failed to register component\n"); + + return 0; +} + +static void rga_core_remove(struct platform_device *pdev) +{ + component_del(&pdev->dev, &rga_core_ops); +} + static int __maybe_unused rga_runtime_suspend(struct device *dev) { struct rga_core *core =3D dev_get_drvdata(dev); @@ -928,11 +905,12 @@ static int __maybe_unused rga_runtime_resume(struct d= evice *dev) return clk_bulk_prepare_enable(core->num_clks, core->clks); } =20 -static const struct dev_pm_ops rga_pm =3D { +static const struct dev_pm_ops rga_core_pm =3D { SET_RUNTIME_PM_OPS(rga_runtime_suspend, rga_runtime_resume, NULL) }; =20 +/* add new compatibles also to the rga_ids struct */ static const struct of_device_id rockchip_rga_match[] =3D { { .compatible =3D "rockchip,rk3288-rga", @@ -951,17 +929,194 @@ static const struct of_device_id rockchip_rga_match[= ] =3D { =20 MODULE_DEVICE_TABLE(of, rockchip_rga_match); =20 +static struct platform_driver rga_core_pdrv =3D { + .probe =3D rga_core_probe, + .remove =3D rga_core_remove, + .driver =3D { + .name =3D RGA_NAME "-core", + .pm =3D &rga_core_pm, + .of_match_table =3D rockchip_rga_match, + }, +}; + +static int rga_bind(struct device *dev) +{ + int ret; + + ret =3D component_bind_all(dev, NULL); + if (ret) { + dev_err(dev, "component bind failed\n"); + return ret; + } + + return 0; +} + +static void rga_unbind(struct device *dev) +{ + component_unbind_all(dev, NULL); +} + +struct component_master_ops rga_master_ops =3D { + .bind =3D rga_bind, + .unbind =3D rga_unbind, +}; + +static int rga_probe(struct platform_device *pdev) +{ + const struct of_device_id *match_desc =3D pdev->dev.platform_data; + struct device *dev =3D &pdev->dev; + struct component_match *match =3D NULL; + struct device_node *core_node; + + if (!match_desc) + return dev_err_probe(dev, -ENODEV, "missing platform data\n"); + + for_each_compatible_node(core_node, NULL, match_desc->compatible) { + if (!of_device_is_available(core_node)) + continue; + + of_node_get(core_node); + component_match_add_release(dev, &match, component_release_of, + component_compare_of, core_node); + + /* + * 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 ite= ration. + */ + of_node_put(core_node); + break; + } + + return component_master_add_with_match(dev, &rga_master_ops, match); +} + +static void rga_remove(struct platform_device *pdev) +{ + component_master_del(&pdev->dev, &rga_master_ops); +} + +/* + * Keep in sync with the compatible names of rockchip_rga_match, as we nam= e the + * virtual component master platform device (allocating the /dev/video dev= ice) + * based on the compatible value. + */ +static struct platform_device_id rga_ids[] =3D { + { + .name =3D "rockchip,rk3288-rga", + }, + { + .name =3D "rockchip,rk3399-rga", + }, + { + .name =3D "rockchip,rk3588-rga3", + }, + {}, +}; + static struct platform_driver rga_pdrv =3D { .probe =3D rga_probe, .remove =3D rga_remove, .driver =3D { .name =3D RGA_NAME, - .pm =3D &rga_pm, - .of_match_table =3D rockchip_rga_match, }, + .id_table =3D rga_ids, }; =20 -module_platform_driver(rga_pdrv); +static bool rga_of_has_available_node(const char *compat) +{ + struct device_node *node; + + for_each_compatible_node(node, NULL, compat) { + if (of_device_is_available(node)) { + of_node_put(node); + return true; + } + } + + return false; +} + +static int rga_create_platform_device(struct platform_device **ppdev, + const struct of_device_id *match) +{ + struct platform_device *pdev; + int ret; + + pdev =3D platform_device_alloc(match->compatible, PLATFORM_DEVID_NONE); + if (!pdev) + return -ENOMEM; + + ret =3D platform_device_add_data(pdev, match, sizeof(*match)); + if (ret) + goto free_platform_device; + + ret =3D platform_device_add(pdev); + if (ret) + goto free_platform_device; + + *ppdev =3D pdev; + + return 0; + +free_platform_device: + platform_device_put(pdev); + return ret; +} + +static struct platform_device *master_pdevs[ARRAY_SIZE(rockchip_rga_match)= - 1]; + +static int __init rga_init(void) +{ + int ret; + unsigned int i; + + ret =3D platform_driver_register(&rga_core_pdrv); + if (ret !=3D 0) + return ret; + + ret =3D platform_driver_register(&rga_pdrv); + if (ret !=3D 0) + goto unregister_core_driver; + + for (i =3D 0; i < ARRAY_SIZE(master_pdevs); i++) { + if (!rga_of_has_available_node( + rockchip_rga_match[i].compatible)) + continue; + + ret =3D rga_create_platform_device(&master_pdevs[i], + &rockchip_rga_match[i]); + if (ret) + goto unregister_platform_devices; + } + + return 0; + +unregister_platform_devices: + for (i =3D 0; i < ARRAY_SIZE(master_pdevs); i++) { + platform_device_unregister(master_pdevs[i]); + master_pdevs[i] =3D NULL; + } + platform_driver_unregister(&rga_pdrv); +unregister_core_driver: + platform_driver_unregister(&rga_core_pdrv); + return ret; +} +module_init(rga_init); + +static void __exit rga_exit(void) +{ + unsigned int i; + + for (i =3D 0; i < ARRAY_SIZE(master_pdevs); i++) { + platform_device_unregister(master_pdevs[i]); + master_pdevs[i] =3D NULL; + } + platform_driver_unregister(&rga_pdrv); + platform_driver_unregister(&rga_core_pdrv); +} +module_exit(rga_exit); =20 MODULE_AUTHOR("Jacob Chen "); MODULE_DESCRIPTION("Rockchip Raster 2d Graphic Acceleration Unit"); --=20 2.55.0 From nobody Fri Sep 25 04:43:51 2026 Received: from mx1.white.stw.pengutronix.de (mx1.white.stw.pengutronix.de [185.203.200.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CF7673AFAED; Wed, 16 Sep 2026 15:15:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.200.13 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789571707; cv=none; b=c9ILrzDkJy/DBEdDZWuWg7xRVrDqbZKVe1UiGXy/fCiwBrIq7/ufgUbtole4WOleqeDidWVL/hopjmVmU9FS1hH2pkYr7ebxQodSE9bsM4ppi0mYlgBRONHdfkKGDiNC9ZIbRzst2uT1jy9A5sG6uuIza+bxCKIDFqXf0RxazfU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789571707; c=relaxed/simple; bh=ygtkTR8WXgTZZeBapS+R9oHRk6VqN+yFXE46h+6kcms=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ZlkAGQPysVM0VTZSgmf+kKdJo0GPL8egAJYeykqaRwBPls9krQPrxJzN2krGPq+QSqFgOoe3mHzK6I10BhBQ1vmYVm32Y05YJkYhn6kRLnskzHZvfVDTOKkCxQc19/pqFOwceToG32Tn4QH9i2WG7f2m5GmfLqL71Ll1bKIAPH0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.200.13 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de X-PTX-Original-Recipient: ezequiel@vanguardiasur.com.ar X-PTX-Original-Recipient: jacob-chen@iotwrt.com X-PTX-Original-Recipient: mchehab@kernel.org X-PTX-Original-Recipient: detlev.casanova@collabora.com X-PTX-Original-Recipient: heiko@sntech.de X-PTX-Original-Recipient: linux-kernel@vger.kernel.org X-PTX-Original-Recipient: linux-media@vger.kernel.org X-PTX-Original-Recipient: linux-arm-kernel@lists.infradead.org X-PTX-Original-Recipient: linux-rockchip@lists.infradead.org X-PTX-Original-Recipient: lgs201920130244@gmail.com X-PTX-Original-Recipient: p.zabel@pengutronix.de X-PTX-Original-Recipient: kernel@pengutronix.de X-PTX-Original-Recipient: s.pueschel@pengutronix.de X-PTX-Original-Recipient: m.tretter@pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de (drehscheibe.grey.stw.pengutronix.de [IPv6:2a0a:edc0:0:c01:1d::a2]) (Authenticated sender: relay-from-drehscheibe.grey.stw.pengutronix.de) by mx1.white.stw.pengutronix.de (Postfix) with ESMTPSA id D4618205A07; Wed, 16 Sep 2026 17:14:58 +0200 (CEST) Received: from ptz.office.stw.pengutronix.de ([2a0a:edc0:0:900:1d::77] helo=peter.mobile.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtp (Exim 4.96) (envelope-from ) id 1x6rGk-001Fsx-2z; Wed, 16 Sep 2026 17:09:54 +0200 From: =?utf-8?q?Sven_P=C3=BCschel?= Date: Wed, 16 Sep 2026 17:09:53 +0200 Subject: [PATCH v2 12/17] media: rockchip: rga: move rockchip_rga allocation to master probe Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260916-spu-rga3multicore-v2-12-23aa2cb74e61@pengutronix.de> References: <20260916-spu-rga3multicore-v2-0-23aa2cb74e61@pengutronix.de> In-Reply-To: <20260916-spu-rga3multicore-v2-0-23aa2cb74e61@pengutronix.de> To: Jacob Chen , Ezequiel Garcia , Mauro Carvalho Chehab , Heiko Stuebner , Philipp Zabel Cc: linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, kernel@pengutronix.de, Detlev Casanova , Michael Tretter , Guangshuo Li , =?utf-8?q?Sven_P=C3=BCschel?= X-Mailer: b4 0.15.2 Move the rockchip_rga struct allocation to the master component probe function in preparation of enabling all cores. This also adjusts the allocation to use the actual number of cores found in the of tree instead of being fixed to one core. Signed-off-by: Sven P=C3=BCschel --- drivers/media/platform/rockchip/rga/rga.c | 32 ++++++++++++++++++---------= ---- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/plat= form/rockchip/rga/rga.c index 367df0ee7b02f..37ccac5b406a4 100644 --- a/drivers/media/platform/rockchip/rga/rga.c +++ b/drivers/media/platform/rockchip/rga/rga.c @@ -741,7 +741,7 @@ static int rga_parse_dt(struct rga_core *core) static int rga_core_bind(struct device *dev, struct device *master, void *= data) { struct platform_device *pdev =3D to_platform_device(dev); - struct rockchip_rga *rga; + struct rockchip_rga *rga =3D data; struct rga_core *core; struct video_device *vfd; int ret =3D 0; @@ -750,17 +750,6 @@ static int rga_core_bind(struct device *dev, struct de= vice *master, void *data) if (!pdev->dev.of_node) return -ENODEV; =20 - rga =3D devm_kzalloc(&pdev->dev, sizeof(*rga) + 1 * sizeof(*rga->cores), = GFP_KERNEL); - if (!rga) - return -ENOMEM; - - rga->hw =3D of_device_get_match_data(&pdev->dev); - if (!rga->hw) - return dev_err_probe(&pdev->dev, -ENODEV, "failed to get match data\n"); - - spin_lock_init(&rga->ctrl_lock); - mutex_init(&rga->mutex); - core =3D devm_kzalloc(&pdev->dev, sizeof(*core), GFP_KERNEL); if (!core) return -ENOMEM; @@ -941,9 +930,10 @@ static struct platform_driver rga_core_pdrv =3D { =20 static int rga_bind(struct device *dev) { + struct rockchip_rga *rga =3D dev_get_drvdata(dev); int ret; =20 - ret =3D component_bind_all(dev, NULL); + ret =3D component_bind_all(dev, rga); if (ret) { dev_err(dev, "component bind failed\n"); return ret; @@ -968,6 +958,8 @@ static int rga_probe(struct platform_device *pdev) struct device *dev =3D &pdev->dev; struct component_match *match =3D NULL; struct device_node *core_node; + struct rockchip_rga *rga; + u8 num_cores =3D 0; =20 if (!match_desc) return dev_err_probe(dev, -ENODEV, "missing platform data\n"); @@ -979,6 +971,7 @@ static int rga_probe(struct platform_device *pdev) of_node_get(core_node); component_match_add_release(dev, &match, component_release_of, component_compare_of, core_node); + num_cores++; =20 /* * As multi core is not implemented yet, @@ -989,6 +982,19 @@ static int rga_probe(struct platform_device *pdev) break; } =20 + rga =3D devm_kzalloc(dev, sizeof(*rga) + num_cores * sizeof(*rga->cores),= GFP_KERNEL); + if (!rga) + return -ENOMEM; + + rga->hw =3D match_desc->data; + if (!rga->hw) + return dev_err_probe(dev, -ENODEV, "failed to get match data\n"); + + spin_lock_init(&rga->ctrl_lock); + mutex_init(&rga->mutex); + + dev_set_drvdata(dev, rga); + return component_master_add_with_match(dev, &rga_master_ops, match); } =20 --=20 2.55.0 From nobody Fri Sep 25 04:43:51 2026 Received: from mx1.white.stw.pengutronix.de (mx1.white.stw.pengutronix.de [185.203.200.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 71D74380FD8; Wed, 16 Sep 2026 15:15:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.200.13 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789571703; cv=none; b=HcmTgUX4tLu9ZcEU6bmJCIei4eFYTRYzX6Onx1d4NIS+Y7PST01o7qLs1JfQr+JAi9g/O+wowXB43rZCtL1cUYP9exuGaxGYPeANSsyRPEBFYWVCQkphpNY95Jpv7VvCEgXq/CgeDrhsGjMprgaD/mvnl/GPbH+TpI6DInuvW5g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789571703; c=relaxed/simple; bh=fpzSuIufPZ56HXqu87ytoBKywkjsrqHiUe554CEMGsA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=K8Ak4GqtRsMcmRnKDZz+i8XHbv7INB0AxqHYj2hHSdzPrXBp6YT9tQPm/c+kKCBn1xmzqXAiLN8ZlfMFDlsg5sKaq5sWXhxj2d6HjNTKEm7sKKxGHby3FUbdZVaKALulg7bwYCZUaWMPHA+KY4bhUTE2bKmlEbTtPlpZGVn+5z0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.200.13 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de X-PTX-Original-Recipient: ezequiel@vanguardiasur.com.ar X-PTX-Original-Recipient: jacob-chen@iotwrt.com X-PTX-Original-Recipient: mchehab@kernel.org X-PTX-Original-Recipient: detlev.casanova@collabora.com X-PTX-Original-Recipient: heiko@sntech.de X-PTX-Original-Recipient: linux-kernel@vger.kernel.org X-PTX-Original-Recipient: linux-media@vger.kernel.org X-PTX-Original-Recipient: linux-arm-kernel@lists.infradead.org X-PTX-Original-Recipient: linux-rockchip@lists.infradead.org X-PTX-Original-Recipient: lgs201920130244@gmail.com X-PTX-Original-Recipient: p.zabel@pengutronix.de X-PTX-Original-Recipient: kernel@pengutronix.de X-PTX-Original-Recipient: s.pueschel@pengutronix.de X-PTX-Original-Recipient: m.tretter@pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de (drehscheibe.grey.stw.pengutronix.de [IPv6:2a0a:edc0:0:c01:1d::a2]) (Authenticated sender: relay-from-drehscheibe.grey.stw.pengutronix.de) by mx1.white.stw.pengutronix.de (Postfix) with ESMTPSA id 7998C205A01; Wed, 16 Sep 2026 17:14:58 +0200 (CEST) Received: from ptz.office.stw.pengutronix.de ([2a0a:edc0:0:900:1d::77] helo=peter.mobile.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtp (Exim 4.96) (envelope-from ) id 1x6rGl-001Fsx-25; Wed, 16 Sep 2026 17:09:55 +0200 From: =?utf-8?q?Sven_P=C3=BCschel?= Date: Wed, 16 Sep 2026 17:09:54 +0200 Subject: [PATCH v2 13/17] media: rockchip: rga: move core initialization from bind to probe Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260916-spu-rga3multicore-v2-13-23aa2cb74e61@pengutronix.de> References: <20260916-spu-rga3multicore-v2-0-23aa2cb74e61@pengutronix.de> In-Reply-To: <20260916-spu-rga3multicore-v2-0-23aa2cb74e61@pengutronix.de> To: Jacob Chen , Ezequiel Garcia , Mauro Carvalho Chehab , Heiko Stuebner , Philipp Zabel Cc: linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, kernel@pengutronix.de, Detlev Casanova , Michael Tretter , Guangshuo Li , =?utf-8?q?Sven_P=C3=BCschel?= X-Mailer: b4 0.15.2 Move the core initialization from the core binding function to the core probing function. This better matches the actual sequence, where the core probe initializes most things and the bind function just binds the core to the actual rga struct from the master device. As the probe has no rockchip_rga struct, it has to get the rga_hw struct from the of match data to determine if the given core has an iommu. Signed-off-by: Sven P=C3=BCschel --- v2 - indirectly fixed component_add error path not using goto err_put_clk by using devres version for pm (pointed out by Sashiko and Nicolas) - reordered commit for a better diff - Avoid NULL pointer deref when interrupt fires on an unbound core --- drivers/media/platform/rockchip/rga/rga.c | 97 ++++++++++++++++++---------= ---- 1 file changed, 55 insertions(+), 42 deletions(-) diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/plat= form/rockchip/rga/rga.c index 37ccac5b406a4..fa34b93b1b7a5 100644 --- a/drivers/media/platform/rockchip/rga/rga.c +++ b/drivers/media/platform/rockchip/rga/rga.c @@ -72,6 +72,10 @@ static irqreturn_t rga_isr(int irq, void *prv) struct rga_core *core =3D prv; struct rockchip_rga *rga =3D core->rga; =20 + /* ignore interrupt on an unbound core */ + if (!rga) + return IRQ_HANDLED; + if (rga->hw->handle_irq(core)) { struct vb2_v4l2_buffer *src, *dst; struct rga_ctx *ctx =3D core->curr; @@ -740,55 +744,16 @@ static int rga_parse_dt(struct rga_core *core) =20 static int rga_core_bind(struct device *dev, struct device *master, void *= data) { - struct platform_device *pdev =3D to_platform_device(dev); struct rockchip_rga *rga =3D data; - struct rga_core *core; + struct rga_core *core =3D dev_get_drvdata(dev); struct video_device *vfd; int ret =3D 0; - int irq; - - if (!pdev->dev.of_node) - return -ENODEV; - - core =3D devm_kzalloc(&pdev->dev, sizeof(*core), GFP_KERNEL); - if (!core) - return -ENOMEM; =20 core->rga =3D rga; - core->dev =3D &pdev->dev; =20 rga->cores[0] =3D core; =20 - ret =3D rga_parse_dt(core); - if (ret) - return dev_err_probe(&pdev->dev, ret, "Unable to parse OF data\n"); - - ret =3D devm_pm_runtime_enable(core->dev); - if (ret) - return ret; - - pm_runtime_set_autosuspend_delay(core->dev, 50); - pm_runtime_use_autosuspend(core->dev); - - core->regs =3D devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(core->regs)) - return PTR_ERR(core->regs); - - irq =3D platform_get_irq(pdev, 0); - if (irq < 0) - return irq; - - ret =3D devm_request_irq(core->dev, irq, rga_isr, - rga_has_internal_iommu(rga) ? 0 : IRQF_SHARED, - dev_name(core->dev), core); - if (ret < 0) - return dev_err_probe(core->dev, ret, "failed to request irq\n"); - - ret =3D dma_set_mask_and_coherent(core->dev, DMA_BIT_MASK(32)); - if (ret) - dev_err_probe(core->dev, ret, "32-bit DMA not supported"); - - ret =3D v4l2_device_register(&pdev->dev, &rga->v4l2_dev); + ret =3D v4l2_device_register(dev, &rga->v4l2_dev); if (ret) return ret; vfd =3D video_device_alloc(); @@ -804,7 +769,6 @@ static int rga_core_bind(struct device *dev, struct dev= ice *master, void *data) video_set_drvdata(vfd, rga); rga->vfd =3D vfd; =20 - platform_set_drvdata(pdev, core); rga->m2m_dev =3D v4l2_m2m_init(&rga_m2m_ops); if (IS_ERR(rga->m2m_dev)) { v4l2_err(&rga->v4l2_dev, "Failed to init mem2mem device\n"); @@ -855,6 +819,8 @@ static void rga_core_unbind(struct device *dev, struct = device *master, v4l2_m2m_release(rga->m2m_dev); video_unregister_device(rga->vfd); v4l2_device_unregister(&rga->v4l2_dev); + + core->rga =3D NULL; } =20 static const struct component_ops rga_core_ops =3D { @@ -864,7 +830,54 @@ static const struct component_ops rga_core_ops =3D { =20 static int rga_core_probe(struct platform_device *pdev) { + struct rga_core *core; + const struct rga_hw *hw; int ret =3D 0; + int irq; + + if (!pdev->dev.of_node) + return -ENODEV; + + hw =3D of_device_get_match_data(&pdev->dev); + if (!hw) + return dev_err_probe(&pdev->dev, -ENODEV, "failed to get match data\n"); + + core =3D devm_kzalloc(&pdev->dev, sizeof(*core), GFP_KERNEL); + if (!core) + return -ENOMEM; + + core->dev =3D &pdev->dev; + + ret =3D rga_parse_dt(core); + if (ret) + return dev_err_probe(&pdev->dev, ret, "Unable to parse OF data\n"); + + ret =3D devm_pm_runtime_enable(core->dev); + if (ret) + return ret; + + pm_runtime_set_autosuspend_delay(core->dev, 50); + pm_runtime_use_autosuspend(core->dev); + + core->regs =3D devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(core->regs)) + return PTR_ERR(core->regs); + + irq =3D platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + + ret =3D devm_request_irq(core->dev, irq, rga_isr, + hw->has_internal_iommu ? 0 : IRQF_SHARED, + dev_name(core->dev), core); + if (ret < 0) + return dev_err_probe(core->dev, ret, "failed to request irq\n"); + + ret =3D dma_set_mask_and_coherent(core->dev, DMA_BIT_MASK(32)); + if (ret) + dev_err_probe(core->dev, ret, "32-bit DMA not supported"); + + platform_set_drvdata(pdev, core); =20 ret =3D component_add(&pdev->dev, &rga_core_ops); if (ret < 0) --=20 2.55.0 From nobody Fri Sep 25 04:43:51 2026 Received: from mx1.white.stw.pengutronix.de (mx1.white.stw.pengutronix.de [185.203.200.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EDDD03B05AF; Wed, 16 Sep 2026 15:15:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.200.13 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789571708; cv=none; b=eWzZV1E/yr4glZMr+idIBukOTnX5XKlHUTM6gzIgTUHGO0eLy0eGSrSAJrD5agVEd+le8sWOH2D+WKX+7lvZvmaRxBHc/l8EOu4vOm2eYMEn/V0epXOY1acn9Cz6vecGZJ6EfBZDwOeVa8Knwc3Awg2SU3RnlmP71Lx/ZidMvNQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789571708; c=relaxed/simple; bh=f27ZCoxWeT7HAcE81yjH/TAOEILBfk/HNVRKV2A+xCY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=E7jn28owNQJkDk/TKpWWxGp3b2+9IAcrPZUbh10xgi+x9s7XXyC209qRZKpCAd8z4EG1rUvQRvzPJHkB+TI4RLHSBCozVJwp1ClJ73UUIgZwp2IQo6xrZDNRhpIFct+3iZOWB48aaPqb9HuPnMDdIWSFQWF1DiZbViUIUiXX4Xk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.200.13 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de X-PTX-Original-Recipient: ezequiel@vanguardiasur.com.ar X-PTX-Original-Recipient: jacob-chen@iotwrt.com X-PTX-Original-Recipient: mchehab@kernel.org X-PTX-Original-Recipient: detlev.casanova@collabora.com X-PTX-Original-Recipient: heiko@sntech.de X-PTX-Original-Recipient: linux-kernel@vger.kernel.org X-PTX-Original-Recipient: linux-media@vger.kernel.org X-PTX-Original-Recipient: linux-arm-kernel@lists.infradead.org X-PTX-Original-Recipient: linux-rockchip@lists.infradead.org X-PTX-Original-Recipient: lgs201920130244@gmail.com X-PTX-Original-Recipient: p.zabel@pengutronix.de X-PTX-Original-Recipient: kernel@pengutronix.de X-PTX-Original-Recipient: s.pueschel@pengutronix.de X-PTX-Original-Recipient: m.tretter@pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de (drehscheibe.grey.stw.pengutronix.de [IPv6:2a0a:edc0:0:c01:1d::a2]) (Authenticated sender: relay-from-drehscheibe.grey.stw.pengutronix.de) by mx1.white.stw.pengutronix.de (Postfix) with ESMTPSA id EA247205A08; Wed, 16 Sep 2026 17:14:58 +0200 (CEST) Received: from ptz.office.stw.pengutronix.de ([2a0a:edc0:0:900:1d::77] helo=peter.mobile.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtp (Exim 4.96) (envelope-from ) id 1x6rGm-001Fsx-1G; Wed, 16 Sep 2026 17:09:56 +0200 From: =?utf-8?q?Sven_P=C3=BCschel?= Date: Wed, 16 Sep 2026 17:09:55 +0200 Subject: [PATCH v2 14/17] media: rockchip: rga: move video device to the master Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260916-spu-rga3multicore-v2-14-23aa2cb74e61@pengutronix.de> References: <20260916-spu-rga3multicore-v2-0-23aa2cb74e61@pengutronix.de> In-Reply-To: <20260916-spu-rga3multicore-v2-0-23aa2cb74e61@pengutronix.de> To: Jacob Chen , Ezequiel Garcia , Mauro Carvalho Chehab , Heiko Stuebner , Philipp Zabel Cc: linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, kernel@pengutronix.de, Detlev Casanova , Michael Tretter , Guangshuo Li , =?utf-8?q?Sven_P=C3=BCschel?= X-Mailer: b4 0.15.2 Move the video device allocation and registration to the master component bind function in preparation for binding multiple cores to the master. Moving it to the master bind function allows to only register the v4l2 device when all cores have been successfully bound to the master device. This also causes the video device to be bound against the master platform device instead of a specific core. As v4l2_device_register sets the drvdata (if it hasn't been set) to it's v4l2_device struct pointer, v4l2_device_unregister also zeroes it if the drvdata matches this pointer. This creates a problem, as the driver allocates it's main rockchip_rga struct during probe and sets it as it's drvdata. As the v4l2_device struct is the first element of the rockchip_rga struct, it has the same pointer than the rockchip_rga struct. Therefore v4l2_device_unregister incorrectly assumes that it has set the drvdata and clears it. This causes problems, as unbinding a core will unbind the master component, but not remove it. Therefore when adding the core again, the master component will be bound again and tries to access an NULL pointer. As the rga core binding expects the rockchip_rga struct to be fully initialized, bind the cores as the last step of the rga master bind. This also avoids a potential isr to hit just between the core bind and the actual initialization of the m2m device. Signed-off-by: Sven P=C3=BCschel --- v2 - unbind components in the error handling of rga bind (https://sashiko.dev/#/patchset/20260606-spu-rga3multicore-v1-0-3ec2b1567= 5f7%40pengutronix.de?part=3D11) - Bind cores at the end, as they expect a fully initialized rga struct (https://sashiko.dev/#/patchset/20260606-spu-rga3multicore-v1-0-3ec2b1567= 5f7%40pengutronix.de?part=3D11) - Fix v4l2_device_unregister clearing the drvdata set on probe --- drivers/media/platform/rockchip/rga/rga.c | 109 ++++++++++++++++----------= ---- 1 file changed, 58 insertions(+), 51 deletions(-) diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/plat= form/rockchip/rga/rga.c index fa34b93b1b7a5..39fcb5623095b 100644 --- a/drivers/media/platform/rockchip/rga/rga.c +++ b/drivers/media/platform/rockchip/rga/rga.c @@ -746,39 +746,15 @@ static int rga_core_bind(struct device *dev, struct d= evice *master, void *data) { struct rockchip_rga *rga =3D data; struct rga_core *core =3D dev_get_drvdata(dev); - struct video_device *vfd; int ret =3D 0; =20 core->rga =3D rga; =20 rga->cores[0] =3D core; =20 - ret =3D v4l2_device_register(dev, &rga->v4l2_dev); - if (ret) - return ret; - vfd =3D video_device_alloc(); - if (!vfd) { - v4l2_err(&rga->v4l2_dev, "Failed to allocate video device\n"); - ret =3D -ENOMEM; - goto unreg_v4l2_dev; - } - *vfd =3D rga_videodev; - vfd->lock =3D &rga->mutex; - vfd->v4l2_dev =3D &rga->v4l2_dev; - - video_set_drvdata(vfd, rga); - rga->vfd =3D vfd; - - rga->m2m_dev =3D v4l2_m2m_init(&rga_m2m_ops); - if (IS_ERR(rga->m2m_dev)) { - v4l2_err(&rga->v4l2_dev, "Failed to init mem2mem device\n"); - ret =3D PTR_ERR(rga->m2m_dev); - goto rel_vdev; - } - ret =3D pm_runtime_resume_and_get(core->dev); if (ret < 0) - goto rel_m2m; + return ret; =20 rga->version =3D rga->hw->get_version(core); =20 @@ -787,38 +763,13 @@ static int rga_core_bind(struct device *dev, struct d= evice *master, void *data) =20 pm_runtime_put(core->dev); =20 - ret =3D video_register_device(vfd, VFL_TYPE_VIDEO, -1); - if (ret) { - v4l2_err(&rga->v4l2_dev, "Failed to register video device\n"); - goto rel_m2m; - } - - v4l2_info(&rga->v4l2_dev, "Registered %s as /dev/%s\n", - vfd->name, video_device_node_name(vfd)); - return 0; - -rel_m2m: - v4l2_m2m_release(rga->m2m_dev); -rel_vdev: - video_device_release(vfd); -unreg_v4l2_dev: - v4l2_device_unregister(&rga->v4l2_dev); - - return ret; } =20 static void rga_core_unbind(struct device *dev, struct device *master, void *data) { struct rga_core *core =3D dev_get_drvdata(dev); - struct rockchip_rga *rga =3D core->rga; - - v4l2_info(&rga->v4l2_dev, "Removing\n"); - - v4l2_m2m_release(rga->m2m_dev); - video_unregister_device(rga->vfd); - v4l2_device_unregister(&rga->v4l2_dev); =20 core->rga =3D NULL; } @@ -944,20 +895,76 @@ static struct platform_driver rga_core_pdrv =3D { static int rga_bind(struct device *dev) { struct rockchip_rga *rga =3D dev_get_drvdata(dev); + struct video_device *vfd; int ret; =20 + ret =3D v4l2_device_register(dev, &rga->v4l2_dev); + if (ret) + return ret; + vfd =3D video_device_alloc(); + if (!vfd) { + v4l2_err(&rga->v4l2_dev, "Failed to allocate video device\n"); + ret =3D -ENOMEM; + goto unreg_v4l2_dev; + } + *vfd =3D rga_videodev; + vfd->lock =3D &rga->mutex; + vfd->v4l2_dev =3D &rga->v4l2_dev; + + video_set_drvdata(vfd, rga); + rga->vfd =3D vfd; + + rga->m2m_dev =3D v4l2_m2m_init(&rga_m2m_ops); + if (IS_ERR(rga->m2m_dev)) { + v4l2_err(&rga->v4l2_dev, "Failed to init mem2mem device\n"); + ret =3D PTR_ERR(rga->m2m_dev); + goto rel_vdev; + } + + ret =3D video_register_device(vfd, VFL_TYPE_VIDEO, -1); + if (ret) { + v4l2_err(&rga->v4l2_dev, "Failed to register video device\n"); + goto rel_m2m; + } + ret =3D component_bind_all(dev, rga); if (ret) { dev_err(dev, "component bind failed\n"); - return ret; + goto rel_m2m; } =20 + v4l2_info(&rga->v4l2_dev, "Registered %s as /dev/%s\n", + vfd->name, video_device_node_name(vfd)); + return 0; + +rel_m2m: + v4l2_m2m_release(rga->m2m_dev); +rel_vdev: + video_device_release(vfd); +unreg_v4l2_dev: + v4l2_device_unregister(&rga->v4l2_dev); + dev_set_drvdata(dev, rga); + return ret; } =20 static void rga_unbind(struct device *dev) { + struct rockchip_rga *rga =3D dev_get_drvdata(dev); + + v4l2_info(&rga->v4l2_dev, "Removing\n"); + component_unbind_all(dev, NULL); + + v4l2_m2m_release(rga->m2m_dev); + video_unregister_device(rga->vfd); + v4l2_device_unregister(&rga->v4l2_dev); + /* + * As &rga->v4l2_dev =3D=3D rga, v4l2_device_unregister (incorrectly) + * clears the drvdata. Therefore just set it again + * (ensuring it's correct regardless of the struct member position) + */ + dev_set_drvdata(dev, rga); } =20 struct component_master_ops rga_master_ops =3D { --=20 2.55.0 From nobody Fri Sep 25 04:43:51 2026 Received: from mx1.white.stw.pengutronix.de (mx1.white.stw.pengutronix.de [185.203.200.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C961234AB19; Wed, 16 Sep 2026 15:15:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.200.13 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789571703; cv=none; b=s5eGhlnXFpXwuK0sCPVVOgMEJ9SAkt1UaBhIOpPc4ijGyl1r2T0KgQVlXaDIvmvwv6INTcvvGYzd2S4QU8vMTaqNXYkaiM7ExIaDsCTUFVvW8xXs/QoZzZo0o1ldEGOLqc9DMCOpXUIPVtYfIJUhq0V0cH1zIc/js/0t9JSJyz8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789571703; c=relaxed/simple; bh=dTdnVEWbXF1Sf9XkqT0fJtspANjSBkIuXBW0zyWR7E4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=jexFQ7jxM+SIvZEExExI6nStHkcFL3gWleD1T0NGxsccaHfMhqMpcA05vxnmfbjd4A6q11NKjlkMfdxCmI4VnQXhCmLUMInFAzV7lujmLGfTw2evwCEreZtIE6hjS6YewwMxo847pgHhCIbwhFyYxlS4G7msY91POt0C6YIlTek= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.200.13 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de X-PTX-Original-Recipient: ezequiel@vanguardiasur.com.ar X-PTX-Original-Recipient: jacob-chen@iotwrt.com X-PTX-Original-Recipient: mchehab@kernel.org X-PTX-Original-Recipient: detlev.casanova@collabora.com X-PTX-Original-Recipient: heiko@sntech.de X-PTX-Original-Recipient: linux-kernel@vger.kernel.org X-PTX-Original-Recipient: linux-media@vger.kernel.org X-PTX-Original-Recipient: linux-arm-kernel@lists.infradead.org X-PTX-Original-Recipient: linux-rockchip@lists.infradead.org X-PTX-Original-Recipient: lgs201920130244@gmail.com X-PTX-Original-Recipient: p.zabel@pengutronix.de X-PTX-Original-Recipient: kernel@pengutronix.de X-PTX-Original-Recipient: s.pueschel@pengutronix.de X-PTX-Original-Recipient: m.tretter@pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de (drehscheibe.grey.stw.pengutronix.de [IPv6:2a0a:edc0:0:c01:1d::a2]) (Authenticated sender: relay-from-drehscheibe.grey.stw.pengutronix.de) by mx1.white.stw.pengutronix.de (Postfix) with ESMTPSA id BCA07205A04; Wed, 16 Sep 2026 17:14:58 +0200 (CEST) Received: from ptz.office.stw.pengutronix.de ([2a0a:edc0:0:900:1d::77] helo=peter.mobile.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtp (Exim 4.96) (envelope-from ) id 1x6rGn-001Fsx-0N; Wed, 16 Sep 2026 17:09:57 +0200 From: =?utf-8?q?Sven_P=C3=BCschel?= Date: Wed, 16 Sep 2026 17:09:56 +0200 Subject: [PATCH v2 15/17] media: rockchip: rga: bind all cores to the master Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260916-spu-rga3multicore-v2-15-23aa2cb74e61@pengutronix.de> References: <20260916-spu-rga3multicore-v2-0-23aa2cb74e61@pengutronix.de> In-Reply-To: <20260916-spu-rga3multicore-v2-0-23aa2cb74e61@pengutronix.de> To: Jacob Chen , Ezequiel Garcia , Mauro Carvalho Chehab , Heiko Stuebner , Philipp Zabel Cc: linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, kernel@pengutronix.de, Detlev Casanova , Michael Tretter , Guangshuo Li , =?utf-8?q?Sven_P=C3=BCschel?= X-Mailer: b4 0.15.2 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=C3=BCschel --- 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-3ec2b1567= 5f7%40pengutronix.de?part=3D13) - 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/plat= form/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 d= evice *master, void *data) { struct rockchip_rga *rga =3D data; struct rga_core *core =3D dev_get_drvdata(dev); + struct rockchip_rga_version version; int ret =3D 0; =20 core->rga =3D rga; =20 - rga->cores[0] =3D core; - ret =3D pm_runtime_resume_and_get(core->dev); if (ret < 0) return ret; =20 - rga->version =3D rga->hw->get_version(core); + version =3D rga->hw->get_version(core); =20 v4l2_info(&rga->v4l2_dev, "HW Version: 0x%02x.%02x\n", rga->version.major, rga->version.minor); =20 + if (rga->num_cores) { + /* we are not the first core, expect that we have the same version */ + if (rga->version.major !=3D version.major || rga->version.minor !=3D ver= sion.minor) { + v4l2_err(&rga->v4l2_dev, "Detected multi-core setup with different core= versions!\n"); + return -ENODEV; + } + } else + rga->version =3D version; + pm_runtime_put(core->dev); =20 + rga->cores[rga->num_cores++] =3D core; + return 0; } =20 @@ -770,6 +780,18 @@ static void rga_core_unbind(struct device *dev, struct= device *master, void *data) { struct rga_core *core =3D dev_get_drvdata(dev); + struct rockchip_rga *rga =3D core->rga; + u8 i; + + /* Remove our core from the list */ + for (i =3D 0; i < rga->num_cores; i++) { + if (rga->cores[i] !=3D core) + continue; + + rga->cores[i] =3D rga->cores[rga->num_cores - 1]; + rga->num_cores--; + break; + } =20 core->rga =3D 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 ite= ration. - */ - of_node_put(core_node); - break; } =20 rga =3D 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/plat= form/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 { =20 const struct rga_hw *hw; =20 + u8 num_cores; struct rga_core *cores[]; }; =20 --=20 2.55.0 From nobody Fri Sep 25 04:43:51 2026 Received: from mx1.white.stw.pengutronix.de (mx1.white.stw.pengutronix.de [185.203.200.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 72A66382F35; Wed, 16 Sep 2026 15:15:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.200.13 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789571703; cv=none; b=mIW78LlaoQhZOi+dvi2+/KMauEQevTvGq1vtHPmTsISRCOhv0jNY7NGySj/hGwPcyzsEFQfDn1+Qxq0CoGkT/JSVciEjTdlMSiAISe5vFPdUv31HZwB4o6XKVq2SwB6Utcewe9ZwJfoWxTbFgBARTTm13hQDbqSzjTVsd00KumA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789571703; c=relaxed/simple; bh=yxFG0aC/dfArZCiuejwoEokZSKztmcMpVr7xcbfJCd0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=NfQ2umrY/p6IWn/Vg4qgD0uDLilLxmqBIvGoPe4VC0Cnbvj50kFzeZiPEihETjNcO75SS5YJy4odBeY/GOXqv4qI1fkzFHxkpqhPboIAJKK59UoRKunYtKVGeRgzONaUDvAjHGriXOu18qR38TOEGXZeI1/A7WjhvSMt3FTT3LY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.200.13 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de X-PTX-Original-Recipient: ezequiel@vanguardiasur.com.ar X-PTX-Original-Recipient: jacob-chen@iotwrt.com X-PTX-Original-Recipient: mchehab@kernel.org X-PTX-Original-Recipient: detlev.casanova@collabora.com X-PTX-Original-Recipient: heiko@sntech.de X-PTX-Original-Recipient: linux-kernel@vger.kernel.org X-PTX-Original-Recipient: linux-media@vger.kernel.org X-PTX-Original-Recipient: linux-arm-kernel@lists.infradead.org X-PTX-Original-Recipient: linux-rockchip@lists.infradead.org X-PTX-Original-Recipient: lgs201920130244@gmail.com X-PTX-Original-Recipient: p.zabel@pengutronix.de X-PTX-Original-Recipient: kernel@pengutronix.de X-PTX-Original-Recipient: s.pueschel@pengutronix.de X-PTX-Original-Recipient: m.tretter@pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de (drehscheibe.grey.stw.pengutronix.de [IPv6:2a0a:edc0:0:c01:1d::a2]) (Authenticated sender: relay-from-drehscheibe.grey.stw.pengutronix.de) by mx1.white.stw.pengutronix.de (Postfix) with ESMTPSA id A5AD3205A03; Wed, 16 Sep 2026 17:14:58 +0200 (CEST) Received: from ptz.office.stw.pengutronix.de ([2a0a:edc0:0:900:1d::77] helo=peter.mobile.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtp (Exim 4.96) (envelope-from ) id 1x6rGn-001Fsx-2l; Wed, 16 Sep 2026 17:09:57 +0200 From: =?utf-8?q?Sven_P=C3=BCschel?= Date: Wed, 16 Sep 2026 17:09:57 +0200 Subject: [PATCH v2 16/17] media: rockchip: rga: put all cores into first core iommu domain Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260916-spu-rga3multicore-v2-16-23aa2cb74e61@pengutronix.de> References: <20260916-spu-rga3multicore-v2-0-23aa2cb74e61@pengutronix.de> In-Reply-To: <20260916-spu-rga3multicore-v2-0-23aa2cb74e61@pengutronix.de> To: Jacob Chen , Ezequiel Garcia , Mauro Carvalho Chehab , Heiko Stuebner , Philipp Zabel Cc: linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, kernel@pengutronix.de, Detlev Casanova , Michael Tretter , Guangshuo Li , =?utf-8?q?Sven_P=C3=BCschel?= X-Mailer: b4 0.15.2 Put all cores into the iommu domain of the first core to allow them to be used by any core. All buffers accessed by the hardware are allocated on the first core, as the scheduling to a specific core is done after the allocation. Therefore put all cores into the same domain to have the same iommu mapping on all cores. Signed-off-by: Sven P=C3=BCschel --- v2 - Fixed domain not being an err ptr (https://sashiko.dev/#/patchset/20260606-spu-rga3multicore-v1-0-3ec2b1567= 5f7%40pengutronix.de?part=3D14) - Detach domain on unbind callback (https://sashiko.dev/#/patchset/20260606-spu-rga3multicore-v1-0-3ec2b1567= 5f7%40pengutronix.de?part=3D14) --- drivers/media/platform/rockchip/rga/rga.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/plat= form/rockchip/rga/rga.c index 5348fcc03c525..b2eeae0a61771 100644 --- a/drivers/media/platform/rockchip/rga/rga.c +++ b/drivers/media/platform/rockchip/rga/rga.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -761,6 +762,19 @@ static int rga_core_bind(struct device *dev, struct de= vice *master, void *data) rga->version.major, rga->version.minor); =20 if (rga->num_cores) { + /* Attach to the first cores iommu */ + struct iommu_domain *domain =3D iommu_get_domain_for_dev(rga->cores[0]->= dev); + + if (!domain) { + dev_err(core->dev, "Couldn't get domain of the first core\n"); + return -ENODEV; + } + ret =3D iommu_attach_device(domain, core->dev); + if (ret) { + dev_err(core->dev, "Couldn't attach to the domain of the first core\n"); + return ret; + } + /* we are not the first core, expect that we have the same version */ if (rga->version.major !=3D version.major || rga->version.minor !=3D ver= sion.minor) { v4l2_err(&rga->v4l2_dev, "Detected multi-core setup with different core= versions!\n"); @@ -788,6 +802,14 @@ static void rga_core_unbind(struct device *dev, struct= device *master, if (rga->cores[i] !=3D core) continue; =20 + if (i) { + /* Detach from the first core iommu */ + struct iommu_domain *domain =3D iommu_get_domain_for_dev(rga->cores[0]-= >dev); + + if (domain) + iommu_detach_device(domain, core->dev); + } + rga->cores[i] =3D rga->cores[rga->num_cores - 1]; rga->num_cores--; break; --=20 2.55.0 From nobody Fri Sep 25 04:43:51 2026 Received: from mx1.white.stw.pengutronix.de (mx1.white.stw.pengutronix.de [185.203.200.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 721CB381E84; Wed, 16 Sep 2026 15:15:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.200.13 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789571703; cv=none; b=HDYwhVO1x2L239Lp3UfxQiVbW+AIq2/X0izDqQ4sXQG657Q1ZWAQ8t4I2IM31tR82pLGTR+0KEshepnTxGUitCRhWt6tllLhK68JHbQ0Doi3EpywW4hfsN62/rd+HKygXDC/xj1HtE1qpxkq9QGjdHzOi8INQINSCrdUvdxVjEA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789571703; c=relaxed/simple; bh=8/JFR7SViEhASw4/EUA55yLQovWOsRkldENr6I2by+Y=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=DxxiyWTlDPIjjxgIhDyRg/j8cz282uJHvtj2jyEUe+U/jD/TTAAogqjJkKhMkWeHZPJL2awTWJbwg9ShE3Igcd3E4ZrtoeldbE5cFD62ImW4pYCBBUFhmjoVYGdIZaHYUFYBfE9/HIbZkiGPHd3Z+kSSXVbbv+c6US86OtWGUn4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.200.13 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de X-PTX-Original-Recipient: ezequiel@vanguardiasur.com.ar X-PTX-Original-Recipient: jacob-chen@iotwrt.com X-PTX-Original-Recipient: mchehab@kernel.org X-PTX-Original-Recipient: detlev.casanova@collabora.com X-PTX-Original-Recipient: heiko@sntech.de X-PTX-Original-Recipient: linux-kernel@vger.kernel.org X-PTX-Original-Recipient: linux-media@vger.kernel.org X-PTX-Original-Recipient: linux-arm-kernel@lists.infradead.org X-PTX-Original-Recipient: linux-rockchip@lists.infradead.org X-PTX-Original-Recipient: lgs201920130244@gmail.com X-PTX-Original-Recipient: p.zabel@pengutronix.de X-PTX-Original-Recipient: kernel@pengutronix.de X-PTX-Original-Recipient: s.pueschel@pengutronix.de X-PTX-Original-Recipient: m.tretter@pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de (drehscheibe.grey.stw.pengutronix.de [IPv6:2a0a:edc0:0:c01:1d::a2]) (Authenticated sender: relay-from-drehscheibe.grey.stw.pengutronix.de) by mx1.white.stw.pengutronix.de (Postfix) with ESMTPSA id 8F694205A02; Wed, 16 Sep 2026 17:14:58 +0200 (CEST) Received: from ptz.office.stw.pengutronix.de ([2a0a:edc0:0:900:1d::77] helo=peter.mobile.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtp (Exim 4.96) (envelope-from ) id 1x6rGo-001Fsx-1s; Wed, 16 Sep 2026 17:09:58 +0200 From: =?utf-8?q?Sven_P=C3=BCschel?= Date: Wed, 16 Sep 2026 17:09:58 +0200 Subject: [PATCH v2 17/17] media: rockchip: rga: schedule jobs to multiple cores Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260916-spu-rga3multicore-v2-17-23aa2cb74e61@pengutronix.de> References: <20260916-spu-rga3multicore-v2-0-23aa2cb74e61@pengutronix.de> In-Reply-To: <20260916-spu-rga3multicore-v2-0-23aa2cb74e61@pengutronix.de> To: Jacob Chen , Ezequiel Garcia , Mauro Carvalho Chehab , Heiko Stuebner , Philipp Zabel Cc: linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, kernel@pengutronix.de, Detlev Casanova , Michael Tretter , Guangshuo Li , =?utf-8?q?Sven_P=C3=BCschel?= X-Mailer: b4 0.15.2 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=C3=BCschel --- v2 - Set core->curr to null first in pm_runtime_resume_and_get error path (https://sashiko.dev/#/patchset/20260606-spu-rga3multicore-v1-0-3ec2b1567= 5f7%40pengutronix.de?part=3D15) - Also protect adding/removing cores with the spinlock in bind/unbind --- drivers/media/platform/rockchip/rga/rga.c | 30 +++++++++++++++++++++++++++= --- drivers/media/platform/rockchip/rga/rga.h | 1 + 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/plat= form/rockchip/rga/rga.c index b2eeae0a61771..6294825eaacfd 100644 --- a/drivers/media/platform/rockchip/rga/rga.c +++ b/drivers/media/platform/rockchip/rga/rga.c @@ -38,13 +38,29 @@ static void device_run(void *prv) { struct rga_ctx *ctx =3D prv; struct rockchip_rga *rga =3D ctx->rga; - struct rga_core *core =3D rga->cores[0]; + struct rga_core *core =3D NULL; struct vb2_v4l2_buffer *src, *dst; unsigned long flags; int ret; + unsigned int i; + + spin_lock_irqsave(&rga->cores_lock, flags); + for (i =3D 0; i < rga->num_cores; i++) { + if (!rga->cores[i]->curr) { + core =3D rga->cores[i]; + core->curr =3D ctx; + break; + } + } + spin_unlock_irqrestore(&rga->cores_lock, flags); + + WARN_ONCE(!core, "No free core although max parallel jobs matches the cor= e count!\n"); + if (!core) + return; =20 ret =3D pm_runtime_resume_and_get(core->dev); if (ret < 0) { + core->curr =3D NULL; v4l2_m2m_buf_done_and_job_finish(rga->m2m_dev, ctx->fh.m2m_ctx, VB2_BUF_STATE_ERROR); return; @@ -58,8 +74,6 @@ static void device_run(void *prv) } spin_unlock_irqrestore(&rga->ctrl_lock, flags); =20 - core->curr =3D ctx; - src =3D v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); src->sequence =3D ctx->osequence++; =20 @@ -748,6 +762,7 @@ static int rga_core_bind(struct device *dev, struct dev= ice *master, void *data) struct rockchip_rga *rga =3D data; struct rga_core *core =3D dev_get_drvdata(dev); struct rockchip_rga_version version; + unsigned long flags; int ret =3D 0; =20 core->rga =3D rga; @@ -785,7 +800,9 @@ static int rga_core_bind(struct device *dev, struct dev= ice *master, void *data) =20 pm_runtime_put(core->dev); =20 + spin_lock_irqsave(&rga->cores_lock, flags); rga->cores[rga->num_cores++] =3D core; + spin_unlock_irqrestore(&rga->cores_lock, flags); =20 return 0; } @@ -796,6 +813,7 @@ static void rga_core_unbind(struct device *dev, struct = device *master, struct rga_core *core =3D dev_get_drvdata(dev); struct rockchip_rga *rga =3D core->rga; u8 i; + unsigned long flags; =20 /* Remove our core from the list */ for (i =3D 0; i < rga->num_cores; i++) { @@ -810,8 +828,10 @@ static void rga_core_unbind(struct device *dev, struct= device *master, iommu_detach_device(domain, core->dev); } =20 + spin_lock_irqsave(&rga->cores_lock, flags); rga->cores[i] =3D rga->cores[rga->num_cores - 1]; rga->num_cores--; + spin_unlock_irqrestore(&rga->cores_lock, flags); break; } =20 @@ -977,6 +997,9 @@ static int rga_bind(struct device *dev) goto rel_m2m; } =20 + /* after binding all cores num_cores has the proper number of cores */ + v4l2_m2m_set_max_parallel_jobs(rga->m2m_dev, rga->num_cores); + v4l2_info(&rga->v4l2_dev, "Registered %s as /dev/%s\n", vfd->name, video_device_node_name(vfd)); =20 @@ -1047,6 +1070,7 @@ static int rga_probe(struct platform_device *pdev) return dev_err_probe(dev, -ENODEV, "failed to get match data\n"); =20 spin_lock_init(&rga->ctrl_lock); + spin_lock_init(&rga->cores_lock); mutex_init(&rga->mutex); =20 dev_set_drvdata(dev, rga); diff --git a/drivers/media/platform/rockchip/rga/rga.h b/drivers/media/plat= form/rockchip/rga/rga.h index 522021c3e0249..b046083244bf6 100644 --- a/drivers/media/platform/rockchip/rga/rga.h +++ b/drivers/media/platform/rockchip/rga/rga.h @@ -86,6 +86,7 @@ struct rockchip_rga { struct mutex mutex; /* ctrl parm lock */ spinlock_t ctrl_lock; + spinlock_t cores_lock; =20 const struct rga_hw *hw; =20 --=20 2.55.0