From nobody Mon Dec 15 21:31:27 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 39496330B3B; Fri, 14 Nov 2025 15:20:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763133620; cv=none; b=s4ucfJtItryUPxSe9w1HSh3HGIu2zMseN/Q1tbHKxx4rfzCztxCZ5yRIEXvYXtFv01g3FbWh9z2d9GNs5SQArHNYFzE/9oumK6pdBCZMtbcDqT1bhf5KklUjrsQ8qQOh+DmX7LN40c0la5ssSfw3SGkPC0BwwLIHbrhXVMMDpyA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763133620; c=relaxed/simple; bh=X/qSIGjNpstppc3cO7WlUXDDm9zEONg8uCFoJGVo9oU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=A+s7Ow8bTdPw+6FgxA0kboHXKEqpBjsaWjMgVFNczzPBglACPxdMRZciC/GAY7jNbmaTpnd9JlAsxNXL1Fen9IDk1FOJgVkRfwVV+tTQFFYUMxgCSJwflnv4axbBItngK8Ua+gowjaghOFM8ANBeFObSqjufkYBPiAAVLpe9vII= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=POnOo+m/; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="POnOo+m/" Received: by smtp.kernel.org (Postfix) with ESMTPS id E6A37C4CEFB; Fri, 14 Nov 2025 15:20:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1763133620; bh=X/qSIGjNpstppc3cO7WlUXDDm9zEONg8uCFoJGVo9oU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=POnOo+m/g94N6HSqtk+fUHzwFFhlVauDbW05op0kw1HN18RQ5+AgmrcAzwdtmgFsw SFjy1TgBfNat3n6qbV63NDHytKs5aDCkWiDbGGI/x+PSdIHFeovmqZLcm3InQaSavo 84v237RqN/dhJ06HuY7+Fedjvsmcp3MAYLbmjalipfIixyI/xfoahyHgc1DOrVGKt8 Q/nGiRR4DnT61h0N5z37p7oBwq35JXeZJDVG6lLtogDmyE3Ff9Jjy0EF/4dqO1jbbW RwY5uS3aJ6A+HDWXBy08ibxksE+lQogay7Ev3gqp5RqxL0U4HtkoKPj+/Zuo+pYOdW Zu5Zmq2E8dp5w== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id D1CF0CE7B1F; Fri, 14 Nov 2025 15:20:19 +0000 (UTC) From: Michael Riesch via B4 Relay Date: Fri, 14 Nov 2025 16:20:12 +0100 Subject: [PATCH v15 01/14] Documentation: admin-guide: media: add rockchip camera interface 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: <20240220-rk3568-vicap-v15-1-8f4915ee365d@collabora.com> References: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com> In-Reply-To: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com> To: Mehdi Djait , Maxime Chevallier , =?utf-8?q?Th=C3=A9o_Lebrun?= , Thomas Petazzoni , Gerald Loacker , Bryan O'Donoghue , Markus Elfring , Laurent Pinchart , Mauro Carvalho Chehab , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Heiko Stuebner , Kever Yang , Nicolas Dufresne , Sebastian Reichel , Collabora Kernel Team , Paul Kocialkowski , Alexander Shiyan , Val Packett , Rob Herring , Philipp Zabel , Sakari Ailus Cc: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, Michael Riesch , Michael Riesch X-Mailer: b4 0.12.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1763133617; l=5914; i=michael.riesch@collabora.com; s=20250410; h=from:subject:message-id; bh=U7iKC5Z7rC7C53Ap0NfSIOxBMvV/vyD4bqRRxsyBYTE=; b=s1irjTmQEJpMU0CABC09HN/+7EB35RhcbFy4muTxn0ZqmjeWz4B8bFTmn3c2LatGR6p1JqPjh SAVx9byzIizAAs0P33o1M4mpXI1rXzrQQJtO91n5kbhvXWxYSx4Clcz X-Developer-Key: i=michael.riesch@collabora.com; a=ed25519; pk=+MWX1fffLFZtTPG/I6XdYm/+OSvpRE8D9evQaWbiN04= X-Endpoint-Received: by B4 Relay for michael.riesch@collabora.com/20250410 with auth_id=371 X-Original-From: Michael Riesch Reply-To: michael.riesch@collabora.com From: Michael Riesch Add a document that describes the different variants of the Rockchip Camera Interface (CIF), their hardware layout, as well as their representation in the media controller centric rkcif device driver, which is located under drivers/media/platform/rockchip/rkcif. Reviewed-by: Heiko Stuebner Reviewed-by: Bryan O'Donoghue Signed-off-by: Michael Riesch --- .../admin-guide/media/rkcif-rk3568-vicap.dot | 8 +++ Documentation/admin-guide/media/rkcif.rst | 79 ++++++++++++++++++= ++++ Documentation/admin-guide/media/v4l-drivers.rst | 1 + MAINTAINERS | 7 ++ 4 files changed, 95 insertions(+) diff --git a/Documentation/admin-guide/media/rkcif-rk3568-vicap.dot b/Docum= entation/admin-guide/media/rkcif-rk3568-vicap.dot new file mode 100644 index 000000000000..3fac59335459 --- /dev/null +++ b/Documentation/admin-guide/media/rkcif-rk3568-vicap.dot @@ -0,0 +1,8 @@ +digraph board { + rankdir=3DTB + n00000001 [label=3D"{{ 0} | rkcif-dvp0\n/dev/v4l-subdev0 | = { 1}}", shape=3DMrecord, style=3Dfilled, fillcolor=3Dgreen] + n00000001:port1 -> n00000004 + n00000004 [label=3D"rkcif-dvp0-id0\n/dev/video0", shape=3Dbox, sty= le=3Dfilled, fillcolor=3Dyellow] + n00000025 [label=3D"{{} | it6801 2-0048\n/dev/v4l-subdev1 | { 0}}", shape=3DMrecord, style=3Dfilled, fillcolor=3Dgreen] + n00000025:port0 -> n00000001:port0 +} diff --git a/Documentation/admin-guide/media/rkcif.rst b/Documentation/admi= n-guide/media/rkcif.rst new file mode 100644 index 000000000000..2558c121abc4 --- /dev/null +++ b/Documentation/admin-guide/media/rkcif.rst @@ -0,0 +1,79 @@ +.. SPDX-License-Identifier: GPL-2.0 + +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +Rockchip Camera Interface (CIF) +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +Introduction +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +The Rockchip Camera Interface (CIF) is featured in many Rockchip SoCs in +different variants. +The different variants are combinations of common building blocks, such as + +* INTERFACE blocks of different types, namely + + * the Digital Video Port (DVP, a parallel data interface) + * the interface block for the MIPI CSI-2 receiver + +* CROP units + +* MIPI CSI-2 receiver (not available on all variants): This unit is referr= ed + to as MIPI CSI HOST in the Rockchip documentation. + Technically, it is a separate hardware block, but it is strongly coupled= to + the CIF and therefore included here. + +* MUX units (not available on all variants) that pass the video data to an + image signal processor (ISP) + +* SCALE units (not available on all variants) + +* DMA engines that transfer video data into system memory using a + double-buffering mechanism called ping-pong mode + +* Support for four streams per INTERFACE block (not available on all + variants), e.g., for MIPI CSI-2 Virtual Channels (VCs) + +This document describes the different variants of the CIF, their hardware +layout, as well as their representation in the media controller centric rk= cif +device driver, which is located under drivers/media/platform/rockchip/rkci= f. + +Variants +=3D=3D=3D=3D=3D=3D=3D=3D + +Rockchip PX30 Video Input Processor (VIP) +----------------------------------------- + +The PX30 Video Input Processor (VIP) features a digital video port that ac= cepts +parallel video data or BT.656. +Since these protocols do not feature multiple streams, the VIP has one DMA +engine that transfers the input video data into system memory. + +The rkcif driver represents this hardware variant by exposing one V4L2 sub= device +(the DVP INTERFACE/CROP block) and one V4L2 device (the DVP DMA engine). + +Rockchip RK3568 Video Capture (VICAP) +------------------------------------- + +The RK3568 Video Capture (VICAP) unit features a digital video port and a = MIPI +CSI-2 receiver that can receive video data independently. +The DVP accepts parallel video data, BT.656 and BT.1120. +Since the BT.1120 protocol may feature more than one stream, the RK3568 VI= CAP +DVP features four DMA engines that can capture different streams. +Similarly, the RK3568 VICAP MIPI CSI-2 receiver features four DMA engines = to +handle different Virtual Channels (VCs). + +The rkcif driver represents this hardware variant by exposing up the follo= wing +V4L2 subdevices: + +* rkcif-dvp0: INTERFACE/CROP block for the DVP + +and the following video devices: + +* rkcif-dvp0-id0: The support for multiple streams on the DVP is not yet + implemented, as it is hard to find test hardware. Thus, this video device + represents the first DMA engine of the RK3568 DVP. + +.. kernel-figure:: rkcif-rk3568-vicap.dot + :alt: Topology of the RK3568 Video Capture (VICAP) unit + :align: center diff --git a/Documentation/admin-guide/media/v4l-drivers.rst b/Documentatio= n/admin-guide/media/v4l-drivers.rst index 3bac5165b134..694fad685ff5 100644 --- a/Documentation/admin-guide/media/v4l-drivers.rst +++ b/Documentation/admin-guide/media/v4l-drivers.rst @@ -25,6 +25,7 @@ Video4Linux (V4L) driver-specific documentation qcom_camss raspberrypi-pisp-be rcar-fdp1 + rkcif rkisp1 raspberrypi-rp1-cfe saa7134 diff --git a/MAINTAINERS b/MAINTAINERS index 42b20f33f3bb..2e1f959bb5f4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -22242,6 +22242,13 @@ S: Maintained F: Documentation/devicetree/bindings/net/can/rockchip,rk3568v2-canfd.yaml F: drivers/net/can/rockchip/ =20 +ROCKCHIP CAMERA INTERFACE (RKCIF) DRIVER +M: Mehdi Djait +M: Michael Riesch +L: linux-media@vger.kernel.org +S: Maintained +F: Documentation/admin-guide/media/rkcif* + ROCKCHIP CRYPTO DRIVERS M: Corentin Labbe L: linux-crypto@vger.kernel.org --=20 2.39.5 From nobody Mon Dec 15 21:31:27 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 8405133C520; Fri, 14 Nov 2025 15:20:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763133620; cv=none; b=aFnks9AUvRGqVYP1b1Cw7/4d8YndDTwh/FOkBwSvCgtvGQIbxSprSrYyRcTq7FmUzhKQlmryU/34eCy9O1AV4BVZGEmE4NG7HWTCS1Qq8CIQ9nF56r7P+gIwuiYRYsh2MtwzrVuQ0YgD5RVZfW+oJ7LTbV7Z6R8TJepV4XxU/tE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763133620; c=relaxed/simple; bh=rtJkcFLFc1knvqExD8Pr/+VubLNDMv/tDbYdwMGF14s=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ZWkA1TZq2s/jJMLeHG+h1MyyoQJdy6eb/ZHNnDGTag3d+PHu0AIYePsjHpHkR4XUG3DiftNro1NVfv2RxrM7DiTbhuu+KRhJxzg52kByxANVV/HdWDlrFmaQiR9Aeur3vSkI+0/RZOqsUDOu4LdMSDlrK1k0TfVdCXJNPMtvZHo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=J7NFc4Yy; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="J7NFc4Yy" Received: by smtp.kernel.org (Postfix) with ESMTPS id EE15FC4CEF8; Fri, 14 Nov 2025 15:20:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1763133620; bh=rtJkcFLFc1knvqExD8Pr/+VubLNDMv/tDbYdwMGF14s=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=J7NFc4Yyn/swMlV5tdQe49rvyHbSNNDpj9Xeit+RnxxiQH6Rssi/CnMnyLjRyZgsp rVE0Ak0prko9SwAGPhz9NFX6rpGPbIUM5cWpxcRpTRP0Lf922ew5VGPt0MGXgFxuHF /SfdYaHBDcUe8EtGxdGTUiJ1D7LUi/E+nmjWyCVrhBCaG0AeiJ0oLGvjvRcOPXe5SK Pm/QJMDz52N5Sz04Xz8C3IhfAAJgAJF/DhI0IpBMluJXEFbRV0SERYCrBp29DVQite lHEVJRNhkMu4HBWdrHfS07jsjY60FYDPdZRqHNNIXYHGbBy9KQhG7rMqtvSRsV0Y2D dRIOKEdWA2MfA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id E0B88CE8D40; Fri, 14 Nov 2025 15:20:19 +0000 (UTC) From: Michael Riesch via B4 Relay Date: Fri, 14 Nov 2025 16:20:13 +0100 Subject: [PATCH v15 02/14] media: dt-bindings: video-interfaces: add defines for sampling modes 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: <20240220-rk3568-vicap-v15-2-8f4915ee365d@collabora.com> References: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com> In-Reply-To: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com> To: Mehdi Djait , Maxime Chevallier , =?utf-8?q?Th=C3=A9o_Lebrun?= , Thomas Petazzoni , Gerald Loacker , Bryan O'Donoghue , Markus Elfring , Laurent Pinchart , Mauro Carvalho Chehab , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Heiko Stuebner , Kever Yang , Nicolas Dufresne , Sebastian Reichel , Collabora Kernel Team , Paul Kocialkowski , Alexander Shiyan , Val Packett , Rob Herring , Philipp Zabel , Sakari Ailus Cc: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, Michael Riesch , Michael Riesch X-Mailer: b4 0.12.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1763133617; l=1070; i=michael.riesch@collabora.com; s=20250410; h=from:subject:message-id; bh=i0G3bjQUxPWSrwDi2kbON/7nXKFuVdlWiYyEBIeG7YY=; b=FEHaSk1PIArT1EGJtvOkdAjeayF31//VdjN6qurt+Wg6fMxwQlvw1u+zXDSZXD6qxpK1/ot5A EN9R6q1+sDrCcgH/oLObU+xd/jKbd6iw0/amM6811QvlY72UHMfqDv9 X-Developer-Key: i=michael.riesch@collabora.com; a=ed25519; pk=+MWX1fffLFZtTPG/I6XdYm/+OSvpRE8D9evQaWbiN04= X-Endpoint-Received: by B4 Relay for michael.riesch@collabora.com/20250410 with auth_id=371 X-Original-From: Michael Riesch Reply-To: michael.riesch@collabora.com From: Michael Riesch Add defines for the pixel clock sampling modes (rising edge, falling edge, dual edge) for parallel video interfaces. This avoids hardcoded constants in device tree sources. Acked-by: Rob Herring Signed-off-by: Michael Riesch Reviewed-by: Bryan O'Donoghue Signed-off-by: Michael Riesch --- include/dt-bindings/media/video-interfaces.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/dt-bindings/media/video-interfaces.h b/include/dt-bind= ings/media/video-interfaces.h index 88b9d05d8075..0b19c9b2e627 100644 --- a/include/dt-bindings/media/video-interfaces.h +++ b/include/dt-bindings/media/video-interfaces.h @@ -20,4 +20,8 @@ #define MEDIA_BUS_CSI2_CPHY_LINE_ORDER_CAB 4 #define MEDIA_BUS_CSI2_CPHY_LINE_ORDER_CBA 5 =20 +#define MEDIA_PCLK_SAMPLE_FALLING_EDGE 0 +#define MEDIA_PCLK_SAMPLE_RISING_EDGE 1 +#define MEDIA_PCLK_SAMPLE_DUAL_EDGE 2 + #endif /* __DT_BINDINGS_MEDIA_VIDEO_INTERFACES_H__ */ --=20 2.39.5 From nobody Mon Dec 15 21:31:27 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 51E2C331201; Fri, 14 Nov 2025 15:20:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763133620; cv=none; b=aP0evVmP5ihSiftLgN40L4T+ACC9jFXZ2+nt2qbbH7zxXsktWbRWb+o6gnra8fItvBqTIpv+72heLs2RFTnCAE+ricsFXltS3LNg2Afy9uFLIYuXAVZKWPWxIAWwztl4TXvSUl8ogg+l4XMMqN/5QLqauTpp9aR6vtG7OdxmXaY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763133620; c=relaxed/simple; bh=/1TF0zRtt7mWqpVWSJRUWVsD14mKx+O9cA7oSvQ2GAg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=cDiqJUwTfUi7FHTVcPuNH8TKvcdMVhpT81sbQeqAOscETLK1lx+Z3cHZxSWcz4HxxCMiObnyDhUS3zXJ5yEmL+nEAhouOWLeCqrjuZ+ZMPfva2MBprrdhEb8hONWsKxgJMd2se+GxZO8YREvxReH7ECWl30e0BjO/Yle2TUR8E4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=S1/5XHKn; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="S1/5XHKn" Received: by smtp.kernel.org (Postfix) with ESMTPS id 12CBCC2BC9E; Fri, 14 Nov 2025 15:20:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1763133620; bh=/1TF0zRtt7mWqpVWSJRUWVsD14mKx+O9cA7oSvQ2GAg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=S1/5XHKnnrphtqYGq9lCjBr49FveJYMd5UZGbfmfFtnTEPbueAi/CJpOsM4bWPIvS lDDFB/r7kxMy3fU+275iWD95x0UgRe8eymu7Ki1T1oHZtU8rDaYdkfILa1hPuzNTmA JkcnmC3cuMQlJUOR3w4ZAYLca4MvZQtkjY26JhvXXXbfrnuDRb2reSxWUPIWzxkgyP iEh4OaDg5BSL/F2pD4wDipzTd07ReX3ptNMwq1q8h2MFjikgShrHE/Af4q27vE5S2Y Y5WpMcIJawEji7Y0aZ7IzR6gzIYHLqRCeZ665ZJRHaB4/aQciA95SjVunkAPyc8BPx UrKYKtgCiK8cg== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id EFA87CE8D43; Fri, 14 Nov 2025 15:20:19 +0000 (UTC) From: Michael Riesch via B4 Relay Date: Fri, 14 Nov 2025 16:20:14 +0100 Subject: [PATCH v15 03/14] media: dt-bindings: add rockchip px30 vip 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: <20240220-rk3568-vicap-v15-3-8f4915ee365d@collabora.com> References: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com> In-Reply-To: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com> To: Mehdi Djait , Maxime Chevallier , =?utf-8?q?Th=C3=A9o_Lebrun?= , Thomas Petazzoni , Gerald Loacker , Bryan O'Donoghue , Markus Elfring , Laurent Pinchart , Mauro Carvalho Chehab , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Heiko Stuebner , Kever Yang , Nicolas Dufresne , Sebastian Reichel , Collabora Kernel Team , Paul Kocialkowski , Alexander Shiyan , Val Packett , Rob Herring , Philipp Zabel , Sakari Ailus Cc: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, Michael Riesch , Michael Riesch , Mehdi Djait X-Mailer: b4 0.12.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1763133617; l=4457; i=michael.riesch@collabora.com; s=20250410; h=from:subject:message-id; bh=vRqzxW1KzAytWflPY3j+Yj6I1g337dXGa/YElJym2cw=; b=0PIYjY2wJvJu2FEKF5O56pai9bLH+sWRzzYwY6P39UtUXDgpAhEYmudSpJWzGiGDJs+MF7fFg bk+tpQFVd6NDOYVOleCSmn/zOvoWgOEA0dRuWWnK4wqn7XIBNKDgdhl X-Developer-Key: i=michael.riesch@collabora.com; a=ed25519; pk=+MWX1fffLFZtTPG/I6XdYm/+OSvpRE8D9evQaWbiN04= X-Endpoint-Received: by B4 Relay for michael.riesch@collabora.com/20250410 with auth_id=371 X-Original-From: Michael Riesch Reply-To: michael.riesch@collabora.com From: Mehdi Djait Add documentation for the Rockchip PX30 Video Input Processor (VIP). Signed-off-by: Mehdi Djait [revised description] Reviewed-by: Rob Herring (Arm) Signed-off-by: Michael Riesch Reviewed-by: Bryan O'Donoghue Signed-off-by: Michael Riesch --- .../bindings/media/rockchip,px30-vip.yaml | 124 +++++++++++++++++= ++++ MAINTAINERS | 1 + 2 files changed, 125 insertions(+) diff --git a/Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml= b/Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml new file mode 100644 index 000000000000..cc08ce94bef7 --- /dev/null +++ b/Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml @@ -0,0 +1,124 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/rockchip,px30-vip.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Rockchip PX30 Video Input Processor (VIP) + +maintainers: + - Mehdi Djait + - Michael Riesch + +description: + The Rockchip PX30 Video Input Processor (VIP) receives the data from a c= amera + sensor or CCIR656 encoder and transfers it into system main memory by AX= I bus. + +properties: + compatible: + const: rockchip,px30-vip + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + items: + - description: ACLK + - description: HCLK + - description: PCLK + + clock-names: + items: + - const: aclk + - const: hclk + - const: pclk + + resets: + items: + - description: AXI + - description: AHB + - description: PCLK IN + + reset-names: + items: + - const: axi + - const: ahb + - const: pclkin + + power-domains: + maxItems: 1 + + ports: + $ref: /schemas/graph.yaml#/properties/ports + + properties: + port@0: + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false + description: input port on the parallel interface + + properties: + endpoint: + $ref: video-interfaces.yaml# + unevaluatedProperties: false + + properties: + bus-type: + enum: + - 5 # MEDIA_BUS_TYPE_PARALLEL + - 6 # MEDIA_BUS_TYPE_BT656 + + required: + - bus-type + + required: + - port@0 + +required: + - compatible + - reg + - interrupts + - clocks + - ports + +additionalProperties: false + +examples: + - | + #include + #include + #include + #include + + soc { + #address-cells =3D <2>; + #size-cells =3D <2>; + + video-capture@ff490000 { + compatible =3D "rockchip,px30-vip"; + reg =3D <0x0 0xff490000 0x0 0x200>; + interrupts =3D ; + clocks =3D <&cru ACLK_CIF>, <&cru HCLK_CIF>, <&cru PCLK_CIF>; + clock-names =3D "aclk", "hclk", "pclk"; + power-domains =3D <&power PX30_PD_VI>; + resets =3D <&cru SRST_CIF_A>, <&cru SRST_CIF_H>, <&cru SRST_CI= F_PCLKIN>; + reset-names =3D "axi", "ahb", "pclkin"; + + ports { + #address-cells =3D <1>; + #size-cells =3D <0>; + + port@0 { + reg =3D <0>; + + cif_in: endpoint { + remote-endpoint =3D <&tw9900_out>; + bus-type =3D ; + }; + }; + }; + }; + }; diff --git a/MAINTAINERS b/MAINTAINERS index 2e1f959bb5f4..3fa175e2b61f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -22248,6 +22248,7 @@ M: Michael Riesch L: linux-media@vger.kernel.org S: Maintained F: Documentation/admin-guide/media/rkcif* +F: Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml =20 ROCKCHIP CRYPTO DRIVERS M: Corentin Labbe --=20 2.39.5 From nobody Mon Dec 15 21:31:27 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 840F133C523; Fri, 14 Nov 2025 15:20:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763133620; cv=none; b=kDGkm+4gaK7hMbuw8l6BMS3CknQQREISzNESwwChgMFCjIRoISBIkTeCC0gbJgB29VjZITjVKOmDggeFRk7deYPHgAK0RxiyexdqFwmrwEZ/NWfBMCmGXGtXjuIfmiBalU9GN0ChWYn3ivxZHwhccLLkl8LDnHL65tLsUAW8Sdg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763133620; c=relaxed/simple; bh=vyklHyJJ6AnXSthSNzdcD33mecYIEHhqofjNrhE3VyI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=GblUTqqsFY+w3N6Y/DOsPMaYXmJdTSekDXJ89NQy3P3BQv7YB0m3lGPM2skOlNZMMcyDyMEQ+x8lu36nNNVk+i6LSp2cWOtW79G7YlUSAoscIRtfhGetqrM4rRu5K0B2tZ7QfuE8plZK0UaG85sp3sM5Xu0qCZXTo4c0dMyjqfo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=r4PhMkJ3; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="r4PhMkJ3" Received: by smtp.kernel.org (Postfix) with ESMTPS id 1B572C2BC86; Fri, 14 Nov 2025 15:20:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1763133620; bh=vyklHyJJ6AnXSthSNzdcD33mecYIEHhqofjNrhE3VyI=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=r4PhMkJ3FrA9a1axZjuNXbrvDPuO0h6Aa38HHF7aQK7EjL10XyrcFtm4wy0MV9Gnr ePGR4DWeixQiafxeptPXDrB9uVOoeClLfzL1kd6mdjd7lUZFQzizwbA2O1BtHv1AHa BM3oLh1gSSBWnQ8frWqTNZRrnv0XQB7/qaAtgswZ6PT6oaagczxgNeSs2W2Tl1LlAo CtQqoIwbTO2Ho0RdQXCO1i++5FCKJqeQY0kC45N0KnbmNg3g6x85hJIASfI9fDUBql Q0Lhzv6CgCqaa02rSghGXlWgiHZC6joJmrTKvQL9TFOrYfq65BCtibAZdxsbnpoBnK FQ0hBf+zIuK1g== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0C860CE8D42; Fri, 14 Nov 2025 15:20:20 +0000 (UTC) From: Michael Riesch via B4 Relay Date: Fri, 14 Nov 2025 16:20:15 +0100 Subject: [PATCH v15 04/14] media: dt-bindings: add rockchip rk3568 vicap 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: <20240220-rk3568-vicap-v15-4-8f4915ee365d@collabora.com> References: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com> In-Reply-To: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com> To: Mehdi Djait , Maxime Chevallier , =?utf-8?q?Th=C3=A9o_Lebrun?= , Thomas Petazzoni , Gerald Loacker , Bryan O'Donoghue , Markus Elfring , Laurent Pinchart , Mauro Carvalho Chehab , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Heiko Stuebner , Kever Yang , Nicolas Dufresne , Sebastian Reichel , Collabora Kernel Team , Paul Kocialkowski , Alexander Shiyan , Val Packett , Rob Herring , Philipp Zabel , Sakari Ailus Cc: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, Michael Riesch , Michael Riesch , Krzysztof Kozlowski X-Mailer: b4 0.12.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1763133617; l=6341; i=michael.riesch@collabora.com; s=20250410; h=from:subject:message-id; bh=lzTS1esR+Bdog1Fe1pZw6s80Wcnw0wXsF0gg8UDLXBw=; b=rHCW9NKvepQ/khrteb00bdWSQf2fSllygByDYaZvW0rLRddMgFv2oFHMN1gWAnqb2mJfEgcYw XFT2R94pE7RAD8jBkcELSqmdGdyM2mjXqEUI9BRR0DFKVCJYjnujlFL X-Developer-Key: i=michael.riesch@collabora.com; a=ed25519; pk=+MWX1fffLFZtTPG/I6XdYm/+OSvpRE8D9evQaWbiN04= X-Endpoint-Received: by B4 Relay for michael.riesch@collabora.com/20250410 with auth_id=371 X-Original-From: Michael Riesch Reply-To: michael.riesch@collabora.com From: Michael Riesch Add documentation for the Rockchip RK3568 Video Capture (VICAP) unit. Signed-off-by: Michael Riesch Reviewed-by: Krzysztof Kozlowski Reviewed-by: Bryan O'Donoghue Signed-off-by: Michael Riesch --- .../bindings/media/rockchip,rk3568-vicap.yaml | 172 +++++++++++++++++= ++++ MAINTAINERS | 1 + 2 files changed, 173 insertions(+) diff --git a/Documentation/devicetree/bindings/media/rockchip,rk3568-vicap.= yaml b/Documentation/devicetree/bindings/media/rockchip,rk3568-vicap.yaml new file mode 100644 index 000000000000..18cd0a5a5318 --- /dev/null +++ b/Documentation/devicetree/bindings/media/rockchip,rk3568-vicap.yaml @@ -0,0 +1,172 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/rockchip,rk3568-vicap.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Rockchip RK3568 Video Capture (VICAP) + +maintainers: + - Michael Riesch + +description: + The Rockchip RK3568 Video Capture (VICAP) block features a digital video + port (DVP, a parallel video interface) and a MIPI CSI-2 port. It receives + the data from camera sensors, video decoders, or other companion ICs and + transfers it into system main memory by AXI bus. + +properties: + compatible: + const: rockchip,rk3568-vicap + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + items: + - description: ACLK + - description: HCLK + - description: DCLK + - description: ICLK + + clock-names: + items: + - const: aclk + - const: hclk + - const: dclk + - const: iclk + + iommus: + maxItems: 1 + + resets: + items: + - description: ARST + - description: HRST + - description: DRST + - description: PRST + - description: IRST + + reset-names: + items: + - const: arst + - const: hrst + - const: drst + - const: prst + - const: irst + + rockchip,grf: + $ref: /schemas/types.yaml#/definitions/phandle + description: Phandle to general register file used for video input blo= ck control. + + power-domains: + maxItems: 1 + + ports: + $ref: /schemas/graph.yaml#/properties/ports + + properties: + port@0: + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false + description: The digital video port (DVP, a parallel video interfa= ce). + + properties: + endpoint: + $ref: video-interfaces.yaml# + unevaluatedProperties: false + + properties: + bus-type: + enum: + - 5 # MEDIA_BUS_TYPE_PARALLEL + - 6 # MEDIA_BUS_TYPE_BT656 + + rockchip,dvp-clk-delay: + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0 + minimum: 0 + maximum: 127 + description: + Delay the DVP path clock input to align the sampling pha= se, + only valid in dual edge sampling mode. Delay is zero by + default and can be adjusted optionally. + + required: + - bus-type + + port@1: + $ref: /schemas/graph.yaml#/properties/port + description: Port connected to the MIPI CSI-2 receiver output. + + properties: + endpoint: + $ref: video-interfaces.yaml# + unevaluatedProperties: false + +required: + - compatible + - reg + - interrupts + - clocks + - ports + +additionalProperties: false + +examples: + - | + #include + #include + #include + #include + #include + + soc { + #address-cells =3D <2>; + #size-cells =3D <2>; + + vicap: video-capture@fdfe0000 { + compatible =3D "rockchip,rk3568-vicap"; + reg =3D <0x0 0xfdfe0000 0x0 0x200>; + interrupts =3D ; + assigned-clocks =3D <&cru DCLK_VICAP>; + assigned-clock-rates =3D <300000000>; + clocks =3D <&cru ACLK_VICAP>, <&cru HCLK_VICAP>, + <&cru DCLK_VICAP>, <&cru ICLK_VICAP_G>; + clock-names =3D "aclk", "hclk", "dclk", "iclk"; + iommus =3D <&vicap_mmu>; + power-domains =3D <&power RK3568_PD_VI>; + resets =3D <&cru SRST_A_VICAP>, <&cru SRST_H_VICAP>, + <&cru SRST_D_VICAP>, <&cru SRST_P_VICAP>, + <&cru SRST_I_VICAP>; + reset-names =3D "arst", "hrst", "drst", "prst", "irst"; + rockchip,grf =3D <&grf>; + + ports { + #address-cells =3D <1>; + #size-cells =3D <0>; + + vicap_dvp: port@0 { + reg =3D <0>; + + vicap_dvp_input: endpoint { + bus-type =3D ; + bus-width =3D <16>; + pclk-sample =3D ; + remote-endpoint =3D <&it6801_output>; + }; + }; + + vicap_mipi: port@1 { + reg =3D <1>; + + vicap_mipi_input: endpoint { + remote-endpoint =3D <&csi_output>; + }; + }; + }; + }; + }; diff --git a/MAINTAINERS b/MAINTAINERS index 3fa175e2b61f..0a3959696154 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -22249,6 +22249,7 @@ L: linux-media@vger.kernel.org S: Maintained F: Documentation/admin-guide/media/rkcif* F: Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml +F: Documentation/devicetree/bindings/media/rockchip,rk3568-vicap.yaml =20 ROCKCHIP CRYPTO DRIVERS M: Corentin Labbe --=20 2.39.5 From nobody Mon Dec 15 21:31:27 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 A53F033CE82; Fri, 14 Nov 2025 15:20:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763133620; cv=none; b=YshOYocsfZaAbF6XvIvGsiHbQCnmuFjWHF0Sp1sFg/dtHjfUEVz98RsC4aqGNC27M466fKFVnY6UTBOkkLqBR02dpow+EOp3qrabPTUF4BdiV623a1+b4p3vsJKejdOBxwkS3u/WzVpNcsUA/7JnUYOe9kt+mtPVRMBOt1BsZgI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763133620; c=relaxed/simple; bh=dNRS/u2Cur0aQUVTVKq0CHh+/LPm8aobiExXj8EuXpA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=LYyoiyXuV+QyhENO+MM1GpiiOT0kbStqB7yethzBzG/fOUuBhOAw+hxWIAJgJqoIfnm76oznx54XsMDhbu2jkvhFQUNNBRxOOGGb99ghiTu3Kxz0JwyggPRKvi3sSPJ/hEWPaxnJ5a90MaM8hMnau77yFFa5aoI9Wqdh2E9yBZ4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=oJjmknlo; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="oJjmknlo" Received: by smtp.kernel.org (Postfix) with ESMTPS id 37160C4AF0E; Fri, 14 Nov 2025 15:20:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1763133620; bh=dNRS/u2Cur0aQUVTVKq0CHh+/LPm8aobiExXj8EuXpA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=oJjmknloO+fk0Rxz5QoZUxRPuES+yvhvsZ5cb581b4xknqjCRo3gICz3wRG0Y4Mcx lmpXtOeKSbNGgn7V7vuW9cX8YE9z/WmYMTJ5sR7FXBq7D6dabwPTlX6PchlZ8PxZYl UbiquTNJThoUKsi2b8IFbt+D+FvZlWjS9M/tOYWwpy2GiZgHR9v1brz9fVqcaPthoD up+UVpApWmbjeben0SRBFS1m9eIH2aW388EIggl6bSAXlfAoRZNG6W9a82We/6MMfx IyBbEsyaVac7HV0qdzYydOgM4Au7M3y2e7RIlZavc1S6i1WKt4g6mxqHQr/0bgrc0r DKTWbtp7plqQQ== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 23648CE7B13; Fri, 14 Nov 2025 15:20:20 +0000 (UTC) From: Michael Riesch via B4 Relay Date: Fri, 14 Nov 2025 16:20:16 +0100 Subject: [PATCH v15 05/14] media: rockchip: add driver for the rockchip camera interface 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: <20240220-rk3568-vicap-v15-5-8f4915ee365d@collabora.com> References: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com> In-Reply-To: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com> To: Mehdi Djait , Maxime Chevallier , =?utf-8?q?Th=C3=A9o_Lebrun?= , Thomas Petazzoni , Gerald Loacker , Bryan O'Donoghue , Markus Elfring , Laurent Pinchart , Mauro Carvalho Chehab , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Heiko Stuebner , Kever Yang , Nicolas Dufresne , Sebastian Reichel , Collabora Kernel Team , Paul Kocialkowski , Alexander Shiyan , Val Packett , Rob Herring , Philipp Zabel , Sakari Ailus Cc: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, Michael Riesch , Michael Riesch X-Mailer: b4 0.12.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1763133617; l=12611; i=michael.riesch@collabora.com; s=20250410; h=from:subject:message-id; bh=X5Afk2knntsfJmF9FDW7swXc75gD8jesDHe46dQtoXM=; b=304RDce8BK/nir1ZWLhjxX4T9qmrr+ygIlWXF5aoc22uB/h/ZRE09n6x3ltBQK62AN+dxeXCK 1/p+qzEAjNUA83rzRdyVPdtxIj6FiSOO4LZ6MS0JVDWgOJXDE8TeBc/ X-Developer-Key: i=michael.riesch@collabora.com; a=ed25519; pk=+MWX1fffLFZtTPG/I6XdYm/+OSvpRE8D9evQaWbiN04= X-Endpoint-Received: by B4 Relay for michael.riesch@collabora.com/20250410 with auth_id=371 X-Original-From: Michael Riesch Reply-To: michael.riesch@collabora.com From: Michael Riesch Add the skeleton for a media controller centric V4L2 driver for the Rockchip Camera Interface (CIF). The skeleton features support for the PX30 Video Input Processor (VIP) and the RK3568 Video Capture (VICAP) unit. Tested-by: Gerald Loacker Reviewed-by: Gerald Loacker Reviewed-by: Bryan O'Donoghue Reviewed-by: Mehdi Djait Signed-off-by: Michael Riesch --- MAINTAINERS | 1 + drivers/media/platform/rockchip/Kconfig | 1 + drivers/media/platform/rockchip/Makefile | 1 + drivers/media/platform/rockchip/rkcif/Kconfig | 18 ++ drivers/media/platform/rockchip/rkcif/Makefile | 4 + .../media/platform/rockchip/rkcif/rkcif-common.h | 55 +++++ drivers/media/platform/rockchip/rkcif/rkcif-dev.c | 262 +++++++++++++++++= ++++ 7 files changed, 342 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 0a3959696154..8d00d6d4b5bf 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -22250,6 +22250,7 @@ S: Maintained F: Documentation/admin-guide/media/rkcif* F: Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml F: Documentation/devicetree/bindings/media/rockchip,rk3568-vicap.yaml +F: drivers/media/platform/rockchip/rkcif/ =20 ROCKCHIP CRYPTO DRIVERS M: Corentin Labbe diff --git a/drivers/media/platform/rockchip/Kconfig b/drivers/media/platfo= rm/rockchip/Kconfig index 9bbeec4996aa..ba401d32f01b 100644 --- a/drivers/media/platform/rockchip/Kconfig +++ b/drivers/media/platform/rockchip/Kconfig @@ -3,5 +3,6 @@ comment "Rockchip media platform drivers" =20 source "drivers/media/platform/rockchip/rga/Kconfig" +source "drivers/media/platform/rockchip/rkcif/Kconfig" source "drivers/media/platform/rockchip/rkisp1/Kconfig" source "drivers/media/platform/rockchip/rkvdec/Kconfig" diff --git a/drivers/media/platform/rockchip/Makefile b/drivers/media/platf= orm/rockchip/Makefile index 286dc5c53f7e..0e0b2cbbd4bd 100644 --- a/drivers/media/platform/rockchip/Makefile +++ b/drivers/media/platform/rockchip/Makefile @@ -1,4 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only obj-y +=3D rga/ +obj-y +=3D rkcif/ obj-y +=3D rkisp1/ obj-y +=3D rkvdec/ diff --git a/drivers/media/platform/rockchip/rkcif/Kconfig b/drivers/media/= platform/rockchip/rkcif/Kconfig new file mode 100644 index 000000000000..efd82ac35bd8 --- /dev/null +++ b/drivers/media/platform/rockchip/rkcif/Kconfig @@ -0,0 +1,18 @@ +config VIDEO_ROCKCHIP_CIF + tristate "Rockchip Camera Interface (CIF)" + depends on VIDEO_DEV + depends on ARCH_ROCKCHIP || COMPILE_TEST + depends on V4L_PLATFORM_DRIVERS + depends on PM && COMMON_CLK + select MEDIA_CONTROLLER + select VIDEOBUF2_DMA_CONTIG + select V4L2_FWNODE + select VIDEO_V4L2_SUBDEV_API + help + This is a driver for Rockchip Camera Interface (CIF). It is featured + in many Rockchips SoCs in different variations, such as the PX30 + Video Input Processor (VIP, one Digital Video Port (DVP)) or the + RK3568 Video Capture (VICAP, one DVP, one MIPI CSI-2 receiver) unit. + + To compile this driver as a module, choose M here: the module + will be called rockchip-cif. diff --git a/drivers/media/platform/rockchip/rkcif/Makefile b/drivers/media= /platform/rockchip/rkcif/Makefile new file mode 100644 index 000000000000..c6837ed2f65c --- /dev/null +++ b/drivers/media/platform/rockchip/rkcif/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_VIDEO_ROCKCHIP_CIF) +=3D rockchip-cif.o + +rockchip-cif-objs +=3D rkcif-dev.o diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-common.h b/drivers= /media/platform/rockchip/rkcif/rkcif-common.h new file mode 100644 index 000000000000..b456a56b5ac4 --- /dev/null +++ b/drivers/media/platform/rockchip/rkcif/rkcif-common.h @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Rockchip Camera Interface (CIF) Driver + * + * Copyright (C) 2018 Rockchip Electronics Co., Ltd. + * Copyright (C) 2023 Mehdi Djait + * Copyright (C) 2025 Michael Riesch + * Copyright (C) 2025 Collabora, Ltd. + */ + +#ifndef _RKCIF_COMMON_H +#define _RKCIF_COMMON_H + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define RKCIF_DRIVER_NAME "rockchip-cif" +#define RKCIF_CLK_MAX 4 + +struct rkcif_remote { + struct v4l2_async_connection async_conn; + struct v4l2_subdev *sd; +}; + +struct rkcif_match_data { + const char *const *clks; + unsigned int clks_num; +}; + +struct rkcif_device { + struct device *dev; + + const struct rkcif_match_data *match_data; + struct clk_bulk_data clks[RKCIF_CLK_MAX]; + unsigned int clks_num; + struct regmap *grf; + struct reset_control *reset; + void __iomem *base_addr; + + struct media_device media_dev; + struct v4l2_device v4l2_dev; + struct v4l2_async_notifier notifier; +}; + +#endif diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-dev.c b/drivers/me= dia/platform/rockchip/rkcif/rkcif-dev.c new file mode 100644 index 000000000000..9215dbe90353 --- /dev/null +++ b/drivers/media/platform/rockchip/rkcif/rkcif-dev.c @@ -0,0 +1,262 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Rockchip Camera Interface (CIF) Driver + * + * Copyright (C) 2018 Rockchip Electronics Co., Ltd. + * Copyright (C) 2020 Maxime Chevallier + * Copyright (C) 2023 Mehdi Djait + * Copyright (C) 2025 Michael Riesch + * Copyright (C) 2025 Collabora, Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "rkcif-common.h" + +static const char *const px30_vip_clks[] =3D { + "aclk", + "hclk", + "pclk", +}; + +static const struct rkcif_match_data px30_vip_match_data =3D { + .clks =3D px30_vip_clks, + .clks_num =3D ARRAY_SIZE(px30_vip_clks), +}; + +static const char *const rk3568_vicap_clks[] =3D { + "aclk", + "hclk", + "dclk", + "iclk", +}; + +static const struct rkcif_match_data rk3568_vicap_match_data =3D { + .clks =3D rk3568_vicap_clks, + .clks_num =3D ARRAY_SIZE(rk3568_vicap_clks), +}; + +static const struct of_device_id rkcif_plat_of_match[] =3D { + { + .compatible =3D "rockchip,px30-vip", + .data =3D &px30_vip_match_data, + }, + { + .compatible =3D "rockchip,rk3568-vicap", + .data =3D &rk3568_vicap_match_data, + }, + {} +}; +MODULE_DEVICE_TABLE(of, rkcif_plat_of_match); + +static int rkcif_register(struct rkcif_device *rkcif) +{ + return 0; +} + +static void rkcif_unregister(struct rkcif_device *rkcif) +{ +} + +static int rkcif_notifier_bound(struct v4l2_async_notifier *notifier, + struct v4l2_subdev *sd, + struct v4l2_async_connection *asd) +{ + struct rkcif_remote *remote =3D + container_of(asd, struct rkcif_remote, async_conn); + + remote->sd =3D sd; + + return 0; +} + +static int rkcif_notifier_complete(struct v4l2_async_notifier *notifier) +{ + struct rkcif_device *rkcif =3D + container_of(notifier, struct rkcif_device, notifier); + + return v4l2_device_register_subdev_nodes(&rkcif->v4l2_dev); +} + +static const struct v4l2_async_notifier_operations rkcif_notifier_ops =3D { + .bound =3D rkcif_notifier_bound, + .complete =3D rkcif_notifier_complete, +}; + +static irqreturn_t rkcif_isr(int irq, void *ctx) +{ + irqreturn_t ret =3D IRQ_NONE; + + return ret; +} + +static int rkcif_probe(struct platform_device *pdev) +{ + struct device *dev =3D &pdev->dev; + struct rkcif_device *rkcif; + int ret, irq; + + rkcif =3D devm_kzalloc(dev, sizeof(*rkcif), GFP_KERNEL); + if (!rkcif) + return -ENOMEM; + + rkcif->match_data =3D of_device_get_match_data(dev); + if (!rkcif->match_data) + return -ENODEV; + + dev_set_drvdata(dev, rkcif); + rkcif->dev =3D dev; + + rkcif->base_addr =3D devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(rkcif->base_addr)) + return PTR_ERR(rkcif->base_addr); + + irq =3D platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + + ret =3D devm_request_irq(dev, irq, rkcif_isr, IRQF_SHARED, + dev_driver_string(dev), dev); + if (ret) + return dev_err_probe(dev, ret, "failed to request irq\n"); + + if (rkcif->match_data->clks_num > RKCIF_CLK_MAX) + return dev_err_probe(dev, -EINVAL, "invalid number of clocks\n"); + + rkcif->clks_num =3D rkcif->match_data->clks_num; + for (unsigned int i =3D 0; i < rkcif->clks_num; i++) + rkcif->clks[i].id =3D rkcif->match_data->clks[i]; + ret =3D devm_clk_bulk_get(dev, rkcif->clks_num, rkcif->clks); + if (ret) + return dev_err_probe(dev, ret, "failed to get clocks\n"); + + rkcif->reset =3D devm_reset_control_array_get_exclusive(dev); + if (IS_ERR(rkcif->reset)) + return PTR_ERR(rkcif->reset); + + rkcif->grf =3D syscon_regmap_lookup_by_phandle(dev->of_node, + "rockchip,grf"); + if (IS_ERR(rkcif->grf)) + rkcif->grf =3D NULL; + + pm_runtime_enable(&pdev->dev); + + rkcif->media_dev.dev =3D dev; + strscpy(rkcif->media_dev.model, RKCIF_DRIVER_NAME, + sizeof(rkcif->media_dev.model)); + media_device_init(&rkcif->media_dev); + + rkcif->v4l2_dev.mdev =3D &rkcif->media_dev; + ret =3D v4l2_device_register(dev, &rkcif->v4l2_dev); + if (ret) + goto err_media_dev_cleanup; + + ret =3D media_device_register(&rkcif->media_dev); + if (ret < 0) { + dev_err(dev, "failed to register media device: %d\n", ret); + goto err_v4l2_dev_unregister; + } + + v4l2_async_nf_init(&rkcif->notifier, &rkcif->v4l2_dev); + rkcif->notifier.ops =3D &rkcif_notifier_ops; + + ret =3D rkcif_register(rkcif); + if (ret) { + dev_err(dev, "failed to register media entities: %d\n", ret); + goto err_notifier_cleanup; + } + + ret =3D v4l2_async_nf_register(&rkcif->notifier); + if (ret) + goto err_rkcif_unregister; + + return 0; + +err_rkcif_unregister: + rkcif_unregister(rkcif); +err_notifier_cleanup: + v4l2_async_nf_cleanup(&rkcif->notifier); + media_device_unregister(&rkcif->media_dev); +err_v4l2_dev_unregister: + v4l2_device_unregister(&rkcif->v4l2_dev); +err_media_dev_cleanup: + media_device_cleanup(&rkcif->media_dev); + pm_runtime_disable(&pdev->dev); + return ret; +} + +static void rkcif_remove(struct platform_device *pdev) +{ + struct rkcif_device *rkcif =3D platform_get_drvdata(pdev); + + v4l2_async_nf_unregister(&rkcif->notifier); + rkcif_unregister(rkcif); + v4l2_async_nf_cleanup(&rkcif->notifier); + media_device_unregister(&rkcif->media_dev); + v4l2_device_unregister(&rkcif->v4l2_dev); + media_device_cleanup(&rkcif->media_dev); + pm_runtime_disable(&pdev->dev); +} + +static int rkcif_runtime_suspend(struct device *dev) +{ + struct rkcif_device *rkcif =3D dev_get_drvdata(dev); + + /* + * Reset CIF (CRU, DMA, FIFOs) to allow a clean resume. + * Since this resets the IOMMU too, we cannot issue this reset when + * resuming. + */ + reset_control_assert(rkcif->reset); + udelay(5); + reset_control_deassert(rkcif->reset); + + clk_bulk_disable_unprepare(rkcif->clks_num, rkcif->clks); + + return 0; +} + +static int rkcif_runtime_resume(struct device *dev) +{ + struct rkcif_device *rkcif =3D dev_get_drvdata(dev); + int ret; + + ret =3D clk_bulk_prepare_enable(rkcif->clks_num, rkcif->clks); + if (ret) { + dev_err(dev, "failed to enable clocks\n"); + return ret; + } + + return 0; +} + +static const struct dev_pm_ops rkcif_plat_pm_ops =3D { + .runtime_suspend =3D rkcif_runtime_suspend, + .runtime_resume =3D rkcif_runtime_resume, +}; + +static struct platform_driver rkcif_plat_drv =3D { + .driver =3D { + .name =3D RKCIF_DRIVER_NAME, + .of_match_table =3D rkcif_plat_of_match, + .pm =3D &rkcif_plat_pm_ops, + }, + .probe =3D rkcif_probe, + .remove =3D rkcif_remove, +}; +module_platform_driver(rkcif_plat_drv); + +MODULE_DESCRIPTION("Rockchip Camera Interface (CIF) platform driver"); +MODULE_LICENSE("GPL"); --=20 2.39.5 From nobody Mon Dec 15 21:31:27 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 865A433C52E; Fri, 14 Nov 2025 15:20:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763133620; cv=none; b=TxudlcB+7JPkcj3t+LcmT+dyCiviWxpQJmmwC0atz98ZaGHidjlHi3rhHlVpfF+F2pyxApApRBIdmafbzLTELWtVsJEVMO4vqwAGn46jpmv4bzltjaJ2kIhzSlFqFf+d4fKKffWgkcMVI5HF4eJL3tatPzCFU6dlkQbag85fqR4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763133620; c=relaxed/simple; bh=9PJvLCMLSR1gqbsmsiyncEbRLdnRQ9Z3ZQk3E2VnlnA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=laPUSEldPNRSKieRVsxJVrHJWDXBK22d+DZxxo4OwPHqC+t/NI/PgUibiEfAFaAiJeNka+91MJrZuEBOUp6l5ARGSzImDABUmse+xfmPxx/ATy/kASnknXD6t3TzwrYE6LPbVaQWFFbrWgRkOkWfPlrLt5TWJmnRSlB7OpTpvLg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=pBUO75z4; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="pBUO75z4" Received: by smtp.kernel.org (Postfix) with ESMTPS id 3EC33C2BCB6; Fri, 14 Nov 2025 15:20:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1763133620; bh=9PJvLCMLSR1gqbsmsiyncEbRLdnRQ9Z3ZQk3E2VnlnA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=pBUO75z4ZYMPUT0MDZigsZmAJNOh2OsEDYpCuKXG/3QuDTnU/ZzvrMQNg6ToSU2On AyHI6+/C37eHj5TxFRvMVEAtqxh92Ze88NhyVCih+9+wr2Y2ISeg3dkfeMYVuKtifg k2OnMguGQWBW35wrVbPP7UQX7aLMeMfz3njoeiTzPWrbReKfbOLVH+k19/+Lkr2SVp hbt0MZCgeAuUlryvLt1hF62JIhegbagY/fHZ47wBDZwbFnxNiN93WgKwKF5Xv4j28t CfvO5GSc2AE67wDQwUQYPJ/U2iuXabmxKeptXxp2ru3jEtke51OA0F8bkEvfwA915J GzA+lgNjSjr5w== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3694CCE8D44; Fri, 14 Nov 2025 15:20:20 +0000 (UTC) From: Michael Riesch via B4 Relay Date: Fri, 14 Nov 2025 16:20:17 +0100 Subject: [PATCH v15 06/14] media: rockchip: rkcif: add abstraction for interface and crop blocks 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: <20240220-rk3568-vicap-v15-6-8f4915ee365d@collabora.com> References: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com> In-Reply-To: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com> To: Mehdi Djait , Maxime Chevallier , =?utf-8?q?Th=C3=A9o_Lebrun?= , Thomas Petazzoni , Gerald Loacker , Bryan O'Donoghue , Markus Elfring , Laurent Pinchart , Mauro Carvalho Chehab , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Heiko Stuebner , Kever Yang , Nicolas Dufresne , Sebastian Reichel , Collabora Kernel Team , Paul Kocialkowski , Alexander Shiyan , Val Packett , Rob Herring , Philipp Zabel , Sakari Ailus Cc: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, Michael Riesch , Michael Riesch X-Mailer: b4 0.12.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1763133617; l=17564; i=michael.riesch@collabora.com; s=20250410; h=from:subject:message-id; bh=c5ZjBwI/g4DaNrcbXBU5a+V3eGwYcQgoYDF4ot74nbk=; b=MtfBqaAs2dokK7tGjRD5kli3+Rc27SX8YhaMejhliEfCY8AezVYHTMdhw2N951xbYfbQexPli DPryTSrezBFDc9Dj8ex3fSnXifFPd8gBVrxWcZsoR3LNllcGJy2qWbb X-Developer-Key: i=michael.riesch@collabora.com; a=ed25519; pk=+MWX1fffLFZtTPG/I6XdYm/+OSvpRE8D9evQaWbiN04= X-Endpoint-Received: by B4 Relay for michael.riesch@collabora.com/20250410 with auth_id=371 X-Original-From: Michael Riesch Reply-To: michael.riesch@collabora.com From: Michael Riesch Add an abstraction for the INTERFACE and CROP parts of the different Rockchip Camera Interface (CIF) variants. These parts are represented as V4L2 subdevice with one sink pad and one source pad. The sink pad is connected to a subdevice: either the subdevice provided by the driver of the companion chip connected to the DVP, or the subdevice provided by the MIPI CSI-2 receiver. The source pad is connected to V4l2 device(s) provided by one or many instance(s) of the DMA abstraction. Tested-by: Gerald Loacker Reviewed-by: Gerald Loacker Reviewed-by: Bryan O'Donoghue Reviewed-by: Mehdi Djait Signed-off-by: Michael Riesch --- drivers/media/platform/rockchip/rkcif/Makefile | 1 + .../media/platform/rockchip/rkcif/rkcif-common.h | 71 ++++ drivers/media/platform/rockchip/rkcif/rkcif-dev.c | 13 + .../platform/rockchip/rkcif/rkcif-interface.c | 405 +++++++++++++++++= ++++ .../platform/rockchip/rkcif/rkcif-interface.h | 31 ++ 5 files changed, 521 insertions(+) diff --git a/drivers/media/platform/rockchip/rkcif/Makefile b/drivers/media= /platform/rockchip/rkcif/Makefile index c6837ed2f65c..9d535fc27e51 100644 --- a/drivers/media/platform/rockchip/rkcif/Makefile +++ b/drivers/media/platform/rockchip/rkcif/Makefile @@ -2,3 +2,4 @@ obj-$(CONFIG_VIDEO_ROCKCHIP_CIF) +=3D rockchip-cif.o =20 rockchip-cif-objs +=3D rkcif-dev.o +rockchip-cif-objs +=3D rkcif-interface.o diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-common.h b/drivers= /media/platform/rockchip/rkcif/rkcif-common.h index b456a56b5ac4..f01536727a5d 100644 --- a/drivers/media/platform/rockchip/rkcif/rkcif-common.h +++ b/drivers/media/platform/rockchip/rkcif/rkcif-common.h @@ -27,9 +27,78 @@ #define RKCIF_DRIVER_NAME "rockchip-cif" #define RKCIF_CLK_MAX 4 =20 +enum rkcif_format_type { + RKCIF_FMT_TYPE_INVALID, + RKCIF_FMT_TYPE_YUV, + RKCIF_FMT_TYPE_RAW, +}; + +enum rkcif_interface_index { + RKCIF_DVP, + RKCIF_MIPI_BASE, + RKCIF_MIPI1 =3D RKCIF_MIPI_BASE, + RKCIF_MIPI2, + RKCIF_MIPI3, + RKCIF_MIPI4, + RKCIF_MIPI5, + RKCIF_MIPI6, + RKCIF_MIPI_MAX, + RKCIF_IF_MAX =3D RKCIF_MIPI_MAX +}; + +enum rkcif_interface_pad_index { + RKCIF_IF_PAD_SINK, + RKCIF_IF_PAD_SRC, + RKCIF_IF_PAD_MAX +}; + +enum rkcif_interface_status { + RKCIF_IF_INACTIVE, + RKCIF_IF_ACTIVE, +}; + +enum rkcif_interface_type { + RKCIF_IF_INVALID, + RKCIF_IF_DVP, + RKCIF_IF_MIPI, +}; + +struct rkcif_input_fmt { + u32 mbus_code; + + enum rkcif_format_type fmt_type; + enum v4l2_field field; +}; + +struct rkcif_interface; + struct rkcif_remote { struct v4l2_async_connection async_conn; struct v4l2_subdev *sd; + + struct rkcif_interface *interface; +}; + +struct rkcif_dvp { + u32 dvp_clk_delay; +}; + +struct rkcif_interface { + enum rkcif_interface_type type; + enum rkcif_interface_status status; + enum rkcif_interface_index index; + struct rkcif_device *rkcif; + struct rkcif_remote *remote; + const struct rkcif_input_fmt *in_fmts; + unsigned int in_fmts_num; + + struct media_pad pads[RKCIF_IF_PAD_MAX]; + struct v4l2_fwnode_endpoint vep; + struct v4l2_subdev sd; + + union { + struct rkcif_dvp dvp; + }; }; =20 struct rkcif_match_data { @@ -47,6 +116,8 @@ struct rkcif_device { struct reset_control *reset; void __iomem *base_addr; =20 + struct rkcif_interface interfaces[RKCIF_IF_MAX]; + struct media_device media_dev; struct v4l2_device v4l2_dev; struct v4l2_async_notifier notifier; diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-dev.c b/drivers/me= dia/platform/rockchip/rkcif/rkcif-dev.c index 9215dbe90353..49e53f70715c 100644 --- a/drivers/media/platform/rockchip/rkcif/rkcif-dev.c +++ b/drivers/media/platform/rockchip/rkcif/rkcif-dev.c @@ -74,8 +74,21 @@ static int rkcif_notifier_bound(struct v4l2_async_notifi= er *notifier, struct v4l2_subdev *sd, struct v4l2_async_connection *asd) { + struct rkcif_device *rkcif =3D + container_of(notifier, struct rkcif_device, notifier); struct rkcif_remote *remote =3D container_of(asd, struct rkcif_remote, async_conn); + struct media_pad *sink_pad =3D + &remote->interface->pads[RKCIF_IF_PAD_SINK]; + int ret; + + ret =3D v4l2_create_fwnode_links_to_pad(sd, sink_pad, + MEDIA_LNK_FL_ENABLED); + if (ret) { + dev_err(rkcif->dev, "failed to link source pad of %s\n", + sd->name); + return ret; + } =20 remote->sd =3D sd; =20 diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-interface.c b/driv= ers/media/platform/rockchip/rkcif/rkcif-interface.c new file mode 100644 index 000000000000..0fe9410e23ed --- /dev/null +++ b/drivers/media/platform/rockchip/rkcif/rkcif-interface.c @@ -0,0 +1,405 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Rockchip Camera Interface (CIF) Driver + * + * Copyright (C) 2025 Michael Riesch + * Copyright (C) 2025 Collabora, Ltd. + */ + +#include +#include +#include +#include + +#include "rkcif-common.h" +#include "rkcif-interface.h" + +static inline struct rkcif_interface *to_rkcif_interface(struct v4l2_subde= v *sd) +{ + return container_of(sd, struct rkcif_interface, sd); +} + +static const struct media_entity_operations rkcif_interface_media_ops =3D { + .link_validate =3D v4l2_subdev_link_validate, + .has_pad_interdep =3D v4l2_subdev_has_pad_interdep, +}; + +static int rkcif_interface_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_format *format) +{ + struct rkcif_interface *interface =3D to_rkcif_interface(sd); + const struct rkcif_input_fmt *input; + struct v4l2_mbus_framefmt *sink, *src; + struct v4l2_rect *crop; + u32 other_pad, other_stream; + int ret; + + /* the format on the source pad always matches the sink pad */ + if (format->pad =3D=3D RKCIF_IF_PAD_SRC) + return v4l2_subdev_get_fmt(sd, state, format); + + input =3D rkcif_interface_find_input_fmt(interface, true, + format->format.code); + format->format.code =3D input->mbus_code; + + sink =3D v4l2_subdev_state_get_format(state, format->pad, format->stream); + if (!sink) + return -EINVAL; + + *sink =3D format->format; + + /* propagate the format to the source pad */ + src =3D v4l2_subdev_state_get_opposite_stream_format(state, format->pad, + format->stream); + if (!src) + return -EINVAL; + + *src =3D *sink; + + ret =3D v4l2_subdev_routing_find_opposite_end(&state->routing, + format->pad, format->stream, + &other_pad, &other_stream); + if (ret) + return -EINVAL; + + crop =3D v4l2_subdev_state_get_crop(state, other_pad, other_stream); + if (!crop) + return -EINVAL; + + /* reset crop */ + crop->left =3D 0; + crop->top =3D 0; + crop->width =3D sink->width; + crop->height =3D sink->height; + + return 0; +} + +static int rkcif_interface_get_sel(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_selection *sel) +{ + struct v4l2_mbus_framefmt *sink; + struct v4l2_rect *crop; + int ret =3D 0; + + if (sel->pad !=3D RKCIF_IF_PAD_SRC) + return -EINVAL; + + sink =3D v4l2_subdev_state_get_opposite_stream_format(state, sel->pad, + sel->stream); + if (!sink) + return -EINVAL; + + crop =3D v4l2_subdev_state_get_crop(state, sel->pad, sel->stream); + if (!crop) + return -EINVAL; + + switch (sel->target) { + case V4L2_SEL_TGT_CROP_DEFAULT: + case V4L2_SEL_TGT_CROP_BOUNDS: + sel->r.left =3D 0; + sel->r.top =3D 0; + sel->r.width =3D sink->width; + sel->r.height =3D sink->height; + break; + case V4L2_SEL_TGT_CROP: + sel->r =3D *crop; + break; + default: + ret =3D -EINVAL; + } + + return ret; +} + +static int rkcif_interface_set_sel(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_selection *sel) +{ + struct v4l2_mbus_framefmt *sink, *src; + struct v4l2_rect *crop; + + if (sel->pad !=3D RKCIF_IF_PAD_SRC || sel->target !=3D V4L2_SEL_TGT_CROP) + return -EINVAL; + + sink =3D v4l2_subdev_state_get_opposite_stream_format(state, sel->pad, + sel->stream); + if (!sink) + return -EINVAL; + + src =3D v4l2_subdev_state_get_format(state, sel->pad, sel->stream); + if (!src) + return -EINVAL; + + crop =3D v4l2_subdev_state_get_crop(state, sel->pad, sel->stream); + if (!crop) + return -EINVAL; + + *crop =3D sel->r; + + src->height =3D sel->r.height; + src->width =3D sel->r.width; + + return 0; +} + +static int rkcif_interface_set_routing(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + enum v4l2_subdev_format_whence which, + struct v4l2_subdev_krouting *routing) +{ + int ret; + + ret =3D v4l2_subdev_routing_validate(sd, routing, + V4L2_SUBDEV_ROUTING_ONLY_1_TO_1); + if (ret) + return ret; + + ret =3D v4l2_subdev_set_routing(sd, state, routing); + + return ret; +} + +static int rkcif_interface_enable_streams(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + u32 pad, u64 streams_mask) +{ + struct v4l2_subdev *remote_sd; + struct media_pad *remote_pad; + u64 mask; + + remote_pad =3D + media_pad_remote_pad_first(&sd->entity.pads[RKCIF_IF_PAD_SINK]); + remote_sd =3D media_entity_to_v4l2_subdev(remote_pad->entity); + + mask =3D v4l2_subdev_state_xlate_streams(state, RKCIF_IF_PAD_SINK, + RKCIF_IF_PAD_SRC, &streams_mask); + + return v4l2_subdev_enable_streams(remote_sd, remote_pad->index, mask); +} + +static int rkcif_interface_disable_streams(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + u32 pad, u64 streams_mask) +{ + struct v4l2_subdev *remote_sd; + struct media_pad *remote_pad; + u64 mask; + + remote_pad =3D + media_pad_remote_pad_first(&sd->entity.pads[RKCIF_IF_PAD_SINK]); + remote_sd =3D media_entity_to_v4l2_subdev(remote_pad->entity); + + mask =3D v4l2_subdev_state_xlate_streams(state, RKCIF_IF_PAD_SINK, + RKCIF_IF_PAD_SRC, &streams_mask); + + return v4l2_subdev_disable_streams(remote_sd, remote_pad->index, mask); +} + +static const struct v4l2_subdev_pad_ops rkcif_interface_pad_ops =3D { + .get_fmt =3D v4l2_subdev_get_fmt, + .set_fmt =3D rkcif_interface_set_fmt, + .get_selection =3D rkcif_interface_get_sel, + .set_selection =3D rkcif_interface_set_sel, + .set_routing =3D rkcif_interface_set_routing, + .enable_streams =3D rkcif_interface_enable_streams, + .disable_streams =3D rkcif_interface_disable_streams, +}; + +static const struct v4l2_subdev_ops rkcif_interface_ops =3D { + .pad =3D &rkcif_interface_pad_ops, +}; + +static int rkcif_interface_init_state(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state) +{ + struct rkcif_interface *interface =3D to_rkcif_interface(sd); + struct v4l2_subdev_route routes[] =3D { + { + .sink_pad =3D RKCIF_IF_PAD_SINK, + .sink_stream =3D 0, + .source_pad =3D RKCIF_IF_PAD_SRC, + .source_stream =3D 0, + .flags =3D V4L2_SUBDEV_ROUTE_FL_ACTIVE, + }, + }; + struct v4l2_subdev_krouting routing =3D { + .len_routes =3D ARRAY_SIZE(routes), + .num_routes =3D ARRAY_SIZE(routes), + .routes =3D routes, + }; + const struct v4l2_mbus_framefmt dvp_default_format =3D { + .width =3D 3840, + .height =3D 2160, + .code =3D MEDIA_BUS_FMT_YUYV8_1X16, + .field =3D V4L2_FIELD_NONE, + .colorspace =3D V4L2_COLORSPACE_REC709, + .ycbcr_enc =3D V4L2_YCBCR_ENC_709, + .quantization =3D V4L2_QUANTIZATION_LIM_RANGE, + .xfer_func =3D V4L2_XFER_FUNC_NONE, + }; + const struct v4l2_mbus_framefmt mipi_default_format =3D { + .width =3D 3840, + .height =3D 2160, + .code =3D MEDIA_BUS_FMT_SRGGB10_1X10, + .field =3D V4L2_FIELD_NONE, + .colorspace =3D V4L2_COLORSPACE_RAW, + .ycbcr_enc =3D V4L2_YCBCR_ENC_601, + .quantization =3D V4L2_QUANTIZATION_FULL_RANGE, + .xfer_func =3D V4L2_XFER_FUNC_NONE, + }; + const struct v4l2_mbus_framefmt *default_format; + int ret; + + default_format =3D (interface->type =3D=3D RKCIF_IF_DVP) ? + &dvp_default_format : + &mipi_default_format; + + ret =3D v4l2_subdev_set_routing_with_fmt(sd, state, &routing, + default_format); + + return ret; +} + +static const struct v4l2_subdev_internal_ops rkcif_interface_internal_ops = =3D { + .init_state =3D rkcif_interface_init_state, +}; + +static int rkcif_interface_add(struct rkcif_interface *interface) +{ + struct rkcif_device *rkcif =3D interface->rkcif; + struct rkcif_remote *remote; + struct v4l2_async_notifier *ntf =3D &rkcif->notifier; + struct v4l2_fwnode_endpoint *vep =3D &interface->vep; + struct device *dev =3D rkcif->dev; + struct fwnode_handle *ep; + u32 dvp_clk_delay =3D 0; + int ret; + + ep =3D fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), interface->index, + 0, 0); + if (!ep) + return -ENODEV; + + vep->bus_type =3D V4L2_MBUS_UNKNOWN; + ret =3D v4l2_fwnode_endpoint_parse(ep, vep); + if (ret) + goto complete; + + if (interface->type =3D=3D RKCIF_IF_DVP) { + if (vep->bus_type !=3D V4L2_MBUS_BT656 && + vep->bus_type !=3D V4L2_MBUS_PARALLEL) { + ret =3D dev_err_probe(dev, -EINVAL, + "unsupported bus type\n"); + goto complete; + } + + fwnode_property_read_u32(ep, "rockchip,dvp-clk-delay", + &dvp_clk_delay); + interface->dvp.dvp_clk_delay =3D dvp_clk_delay; + } + + remote =3D v4l2_async_nf_add_fwnode_remote(ntf, ep, struct rkcif_remote); + if (IS_ERR(remote)) { + ret =3D PTR_ERR(remote); + goto complete; + } + + remote->interface =3D interface; + interface->remote =3D remote; + interface->status =3D RKCIF_IF_ACTIVE; + ret =3D 0; + +complete: + fwnode_handle_put(ep); + + return ret; +} + +int rkcif_interface_register(struct rkcif_device *rkcif, + struct rkcif_interface *interface) +{ + struct media_pad *pads =3D interface->pads; + struct v4l2_subdev *sd =3D &interface->sd; + int ret; + + interface->rkcif =3D rkcif; + + v4l2_subdev_init(sd, &rkcif_interface_ops); + sd->dev =3D rkcif->dev; + sd->entity.ops =3D &rkcif_interface_media_ops; + sd->entity.function =3D MEDIA_ENT_F_VID_IF_BRIDGE; + sd->flags |=3D V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_STREAMS; + sd->internal_ops =3D &rkcif_interface_internal_ops; + sd->owner =3D THIS_MODULE; + + if (interface->type =3D=3D RKCIF_IF_DVP) + snprintf(sd->name, sizeof(sd->name), "rkcif-dvp0"); + else if (interface->type =3D=3D RKCIF_IF_MIPI) + snprintf(sd->name, sizeof(sd->name), "rkcif-mipi%d", + interface->index - RKCIF_MIPI_BASE); + + pads[RKCIF_IF_PAD_SINK].flags =3D MEDIA_PAD_FL_SINK; + pads[RKCIF_IF_PAD_SRC].flags =3D MEDIA_PAD_FL_SOURCE; + ret =3D media_entity_pads_init(&sd->entity, RKCIF_IF_PAD_MAX, pads); + if (ret) + goto err; + + ret =3D v4l2_subdev_init_finalize(sd); + if (ret) + goto err_entity_cleanup; + + ret =3D v4l2_device_register_subdev(&rkcif->v4l2_dev, sd); + if (ret) { + dev_err(sd->dev, "failed to register subdev\n"); + goto err_subdev_cleanup; + } + + ret =3D rkcif_interface_add(interface); + if (ret) + goto err_subdev_unregister; + + return 0; + +err_subdev_unregister: + v4l2_device_unregister_subdev(sd); +err_subdev_cleanup: + v4l2_subdev_cleanup(sd); +err_entity_cleanup: + media_entity_cleanup(&sd->entity); +err: + return ret; +} + +void rkcif_interface_unregister(struct rkcif_interface *interface) +{ + struct v4l2_subdev *sd =3D &interface->sd; + + if (interface->status !=3D RKCIF_IF_ACTIVE) + return; + + v4l2_device_unregister_subdev(sd); + v4l2_subdev_cleanup(sd); + media_entity_cleanup(&sd->entity); +} + +const struct rkcif_input_fmt * +rkcif_interface_find_input_fmt(struct rkcif_interface *interface, bool ret= _def, + u32 mbus_code) +{ + const struct rkcif_input_fmt *fmt; + + WARN_ON(interface->in_fmts_num =3D=3D 0); + + for (unsigned int i =3D 0; i < interface->in_fmts_num; i++) { + fmt =3D &interface->in_fmts[i]; + if (fmt->mbus_code =3D=3D mbus_code) + return fmt; + } + if (ret_def) + return &interface->in_fmts[0]; + else + return NULL; +} diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-interface.h b/driv= ers/media/platform/rockchip/rkcif/rkcif-interface.h new file mode 100644 index 000000000000..f13aa28b6fa7 --- /dev/null +++ b/drivers/media/platform/rockchip/rkcif/rkcif-interface.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Rockchip Camera Interface (CIF) Driver + * + * Abstraction for the INTERFACE and CROP parts of the different CIF varia= nts. + * They shall be represented as V4L2 subdevice with one sink pad and one + * source pad. The sink pad is connected to a subdevice: either the subdev= ice + * provided by the driver of the companion chip connected to the DVP, or t= he + * subdevice provided by the MIPI CSI-2 receiver driver. The source pad is + * to V4l2 device(s) provided by one or many instance(s) of the DMA + * abstraction. + * + * Copyright (C) 2025 Michael Riesch + * Copyright (C) 2025 Collabora, Ltd. + */ + +#ifndef _RKCIF_INTERFACE_H +#define _RKCIF_INTERFACE_H + +#include "rkcif-common.h" + +int rkcif_interface_register(struct rkcif_device *rkcif, + struct rkcif_interface *interface); + +void rkcif_interface_unregister(struct rkcif_interface *interface); + +const struct rkcif_input_fmt * +rkcif_interface_find_input_fmt(struct rkcif_interface *interface, bool ret= _def, + u32 mbus_code); + +#endif --=20 2.39.5 From nobody Mon Dec 15 21:31:27 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 A6D6833CE83; Fri, 14 Nov 2025 15:20:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763133620; cv=none; b=O+TIQVXI5SJdLfwmwoNfAG9WSrs4KjE/p5lZ6CelIMay2pIcRv76Xli6+jHw/jz0eNowWErofn3U4ToWJ9zFjC0NmHsveWZ4aIih/oq2Z7EQm3MfhKLIZsDScfw5KqCEOtK70GbT4pGzrCRtaDe/PBVq5Gyr3LINnGRu1Rdjc/w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763133620; c=relaxed/simple; bh=IPXLhU9MhtGdosnWLKdXzkql1hQIHaUXNsfC5nuzr/I=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=GRXTAX0TEZmVmLZE6u8ghJWe/IQQkFXISQ9ZtRMIvAMX+2vKrUgf1tm0ftLGT1cS/4Uq0sAgsJFs0iRO8A75XaPefBmKdkt07NX/hBHK+IBD1/oEQrqf/gwqSiA/NQQPVd4vkBjMpvRGHZYULKbqgbAFijSOXcVfhSzlNHLkogE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=bIaDNzUJ; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="bIaDNzUJ" Received: by smtp.kernel.org (Postfix) with ESMTPS id 5514AC4AF14; Fri, 14 Nov 2025 15:20:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1763133620; bh=IPXLhU9MhtGdosnWLKdXzkql1hQIHaUXNsfC5nuzr/I=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=bIaDNzUJC8C5LpYHWToPJdziM/pNGzJzLFjh0pnbP1zr3U82yBrudb6TEUgUfegf4 qyPnxWsrVW6jnWt0DTu9gTnMSIYi0Y6QEPlnVQ8sYdPRwwrseY1nh/dHdgrf+rcp0Z bzkvW6B98hgps6TLsoN18F1h+W6/57yD+DpSrkdADW66Z2kUqqG2JlvwBYes8vFwsr PwfnxILv13ObiAiHN03QoB1JXmraLBPz/9GsKhSRVf7+0C8ph/ppTvSdk8KsLnWEKW YFWmdJSigpVBGB/eb6Ihsw2+W4UMraP7fr4lcM+lbKOEvpzpt3y81/Wb/Vc1411qkC Hys8IBwYejd6g== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4878DCE8D40; Fri, 14 Nov 2025 15:20:20 +0000 (UTC) From: Michael Riesch via B4 Relay Date: Fri, 14 Nov 2025 16:20:18 +0100 Subject: [PATCH v15 07/14] media: rockchip: rkcif: add abstraction for dma blocks 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: <20240220-rk3568-vicap-v15-7-8f4915ee365d@collabora.com> References: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com> In-Reply-To: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com> To: Mehdi Djait , Maxime Chevallier , =?utf-8?q?Th=C3=A9o_Lebrun?= , Thomas Petazzoni , Gerald Loacker , Bryan O'Donoghue , Markus Elfring , Laurent Pinchart , Mauro Carvalho Chehab , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Heiko Stuebner , Kever Yang , Nicolas Dufresne , Sebastian Reichel , Collabora Kernel Team , Paul Kocialkowski , Alexander Shiyan , Val Packett , Rob Herring , Philipp Zabel , Sakari Ailus Cc: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, Michael Riesch , Michael Riesch X-Mailer: b4 0.12.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1763133617; l=26331; i=michael.riesch@collabora.com; s=20250410; h=from:subject:message-id; bh=HsUs80iusj4Avc4anshfIleb6RLrRNvAXrGj0YqKc50=; b=r2bWrxos/xs4swKsfbr5cYYoOaOiSqsGW0Ws7WawNQNzeGOnLaWWEvsnx8Fo86G0Bm5kwniEX vWmYz13os5tAOmn7S5DVtcQvZHYgY3dLuJ4SE9RgjochmCi4u/7faFI X-Developer-Key: i=michael.riesch@collabora.com; a=ed25519; pk=+MWX1fffLFZtTPG/I6XdYm/+OSvpRE8D9evQaWbiN04= X-Endpoint-Received: by B4 Relay for michael.riesch@collabora.com/20250410 with auth_id=371 X-Original-From: Michael Riesch Reply-To: michael.riesch@collabora.com From: Michael Riesch Add an abstraction for the DMA parts and the ping-pong scheme (a double-buffering mechanism) of the different CIF variants. Each stream is represented as V4L2 device whose corresponding media entity has one sink pad. This sink pad is connected to an instance of the INTERFACE/CROP abstraction. Tested-by: Gerald Loacker Reviewed-by: Gerald Loacker Reviewed-by: Bryan O'Donoghue Reviewed-by: Mehdi Djait Signed-off-by: Michael Riesch --- drivers/media/platform/rockchip/rkcif/Makefile | 1 + .../media/platform/rockchip/rkcif/rkcif-common.h | 67 +++ .../platform/rockchip/rkcif/rkcif-interface.c | 37 ++ .../media/platform/rockchip/rkcif/rkcif-stream.c | 638 +++++++++++++++++= ++++ .../media/platform/rockchip/rkcif/rkcif-stream.h | 32 ++ 5 files changed, 775 insertions(+) diff --git a/drivers/media/platform/rockchip/rkcif/Makefile b/drivers/media= /platform/rockchip/rkcif/Makefile index 9d535fc27e51..256335d95050 100644 --- a/drivers/media/platform/rockchip/rkcif/Makefile +++ b/drivers/media/platform/rockchip/rkcif/Makefile @@ -3,3 +3,4 @@ obj-$(CONFIG_VIDEO_ROCKCHIP_CIF) +=3D rockchip-cif.o =20 rockchip-cif-objs +=3D rkcif-dev.o rockchip-cif-objs +=3D rkcif-interface.o +rockchip-cif-objs +=3D rkcif-stream.o diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-common.h b/drivers= /media/platform/rockchip/rkcif/rkcif-common.h index f01536727a5d..63d5b45c7afe 100644 --- a/drivers/media/platform/rockchip/rkcif/rkcif-common.h +++ b/drivers/media/platform/rockchip/rkcif/rkcif-common.h @@ -33,6 +33,14 @@ enum rkcif_format_type { RKCIF_FMT_TYPE_RAW, }; =20 +enum rkcif_id_index { + RKCIF_ID0, + RKCIF_ID1, + RKCIF_ID2, + RKCIF_ID3, + RKCIF_ID_MAX +}; + enum rkcif_interface_index { RKCIF_DVP, RKCIF_MIPI_BASE, @@ -63,6 +71,19 @@ enum rkcif_interface_type { RKCIF_IF_MIPI, }; =20 +struct rkcif_buffer { + struct vb2_v4l2_buffer vb; + struct list_head queue; + dma_addr_t buff_addr[VIDEO_MAX_PLANES]; + bool is_dummy; +}; + +struct rkcif_dummy_buffer { + struct rkcif_buffer buffer; + void *vaddr; + u32 size; +}; + struct rkcif_input_fmt { u32 mbus_code; =20 @@ -70,6 +91,12 @@ struct rkcif_input_fmt { enum v4l2_field field; }; =20 +struct rkcif_output_fmt { + u32 fourcc; + u32 mbus_code; + u8 cplanes; +}; + struct rkcif_interface; =20 struct rkcif_remote { @@ -79,6 +106,42 @@ struct rkcif_remote { struct rkcif_interface *interface; }; =20 +struct rkcif_stream { + enum rkcif_id_index id; + struct rkcif_device *rkcif; + struct rkcif_interface *interface; + const struct rkcif_output_fmt *out_fmts; + unsigned int out_fmts_num; + + /* in ping-pong mode, two buffers can be provided to the HW */ + struct rkcif_buffer *buffers[2]; + int frame_idx; + int frame_phase; + + /* in case of no available buffer, HW can write to the dummy buffer */ + struct rkcif_dummy_buffer dummy; + + bool stopping; + wait_queue_head_t wq_stopped; + + /* queue of available buffers plus spinlock that protects it */ + spinlock_t driver_queue_lock; + struct list_head driver_queue; + + /* lock used by the V4L2 core */ + struct mutex vlock; + + struct media_pad pad; + struct media_pipeline pipeline; + struct v4l2_pix_format_mplane pix; + struct vb2_queue buf_queue; + struct video_device vdev; + + void (*queue_buffer)(struct rkcif_stream *stream, unsigned int index); + int (*start_streaming)(struct rkcif_stream *stream); + void (*stop_streaming)(struct rkcif_stream *stream); +}; + struct rkcif_dvp { u32 dvp_clk_delay; }; @@ -89,6 +152,8 @@ struct rkcif_interface { enum rkcif_interface_index index; struct rkcif_device *rkcif; struct rkcif_remote *remote; + struct rkcif_stream streams[RKCIF_ID_MAX]; + unsigned int streams_num; const struct rkcif_input_fmt *in_fmts; unsigned int in_fmts_num; =20 @@ -99,6 +164,8 @@ struct rkcif_interface { union { struct rkcif_dvp dvp; }; + + void (*set_crop)(struct rkcif_stream *stream, u16 left, u16 top); }; =20 struct rkcif_match_data { diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-interface.c b/driv= ers/media/platform/rockchip/rkcif/rkcif-interface.c index 0fe9410e23ed..523103872b7a 100644 --- a/drivers/media/platform/rockchip/rkcif/rkcif-interface.c +++ b/drivers/media/platform/rockchip/rkcif/rkcif-interface.c @@ -157,15 +157,41 @@ static int rkcif_interface_set_routing(struct v4l2_su= bdev *sd, if (ret) return ret; =20 + for (unsigned int i =3D 0; i < routing->num_routes; i++) { + const struct v4l2_subdev_route *route =3D &routing->routes[i]; + + if (route->source_stream >=3D RKCIF_ID_MAX) + return -EINVAL; + } + ret =3D v4l2_subdev_set_routing(sd, state, routing); =20 return ret; } =20 +static int rkcif_interface_apply_crop(struct rkcif_stream *stream, + struct v4l2_subdev_state *state) +{ + struct rkcif_interface *interface =3D stream->interface; + struct v4l2_rect *crop; + + crop =3D v4l2_subdev_state_get_crop(state, RKCIF_IF_PAD_SRC, stream->id); + if (!crop) + return -EINVAL; + + if (interface->set_crop) + interface->set_crop(stream, crop->left, crop->top); + + return 0; +} + static int rkcif_interface_enable_streams(struct v4l2_subdev *sd, struct v4l2_subdev_state *state, u32 pad, u64 streams_mask) { + struct rkcif_interface *interface =3D to_rkcif_interface(sd); + struct rkcif_stream *stream; + struct v4l2_subdev_route *route; struct v4l2_subdev *remote_sd; struct media_pad *remote_pad; u64 mask; @@ -174,6 +200,17 @@ static int rkcif_interface_enable_streams(struct v4l2_= subdev *sd, media_pad_remote_pad_first(&sd->entity.pads[RKCIF_IF_PAD_SINK]); remote_sd =3D media_entity_to_v4l2_subdev(remote_pad->entity); =20 + /* DVP has one crop setting for all IDs */ + if (interface->type =3D=3D RKCIF_IF_DVP) { + stream =3D &interface->streams[RKCIF_ID0]; + rkcif_interface_apply_crop(stream, state); + } else { + for_each_active_route(&state->routing, route) { + stream =3D &interface->streams[route->sink_stream]; + rkcif_interface_apply_crop(stream, state); + } + } + mask =3D v4l2_subdev_state_xlate_streams(state, RKCIF_IF_PAD_SINK, RKCIF_IF_PAD_SRC, &streams_mask); =20 diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-stream.c b/drivers= /media/platform/rockchip/rkcif/rkcif-stream.c new file mode 100644 index 000000000000..fd6593f4702f --- /dev/null +++ b/drivers/media/platform/rockchip/rkcif/rkcif-stream.c @@ -0,0 +1,638 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Rockchip Camera Interface (CIF) Driver + * + * Copyright (C) 2025 Michael Riesch + * Copyright (C) 2025 Collabora, Ltd. + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include "rkcif-common.h" +#include "rkcif-stream.h" + +#define CIF_REQ_BUFS_MIN 1 +#define CIF_MIN_WIDTH 64 +#define CIF_MIN_HEIGHT 64 +#define CIF_MAX_WIDTH 8192 +#define CIF_MAX_HEIGHT 8192 + +static inline struct rkcif_buffer *to_rkcif_buffer(struct vb2_v4l2_buffer = *vb) +{ + return container_of(vb, struct rkcif_buffer, vb); +} + +static inline struct rkcif_stream *to_rkcif_stream(struct video_device *vd= ev) +{ + return container_of(vdev, struct rkcif_stream, vdev); +} + +static struct rkcif_buffer *rkcif_stream_pop_buffer(struct rkcif_stream *s= tream) +{ + struct rkcif_buffer *buffer; + + guard(spinlock_irqsave)(&stream->driver_queue_lock); + + if (list_empty(&stream->driver_queue)) + return NULL; + + buffer =3D list_first_entry(&stream->driver_queue, struct rkcif_buffer, + queue); + list_del(&buffer->queue); + + return buffer; +} + +static void rkcif_stream_push_buffer(struct rkcif_stream *stream, + struct rkcif_buffer *buffer) +{ + guard(spinlock_irqsave)(&stream->driver_queue_lock); + + list_add_tail(&buffer->queue, &stream->driver_queue); +} + +static inline void rkcif_stream_return_buffer(struct rkcif_buffer *buffer, + enum vb2_buffer_state state) +{ + struct vb2_v4l2_buffer *vb =3D &buffer->vb; + + vb2_buffer_done(&vb->vb2_buf, state); +} + +static void rkcif_stream_complete_buffer(struct rkcif_stream *stream, + struct rkcif_buffer *buffer) +{ + struct vb2_v4l2_buffer *vb =3D &buffer->vb; + + vb->vb2_buf.timestamp =3D ktime_get_ns(); + vb->sequence =3D stream->frame_idx; + vb2_buffer_done(&vb->vb2_buf, VB2_BUF_STATE_DONE); + stream->frame_idx++; +} + +void rkcif_stream_pingpong(struct rkcif_stream *stream) +{ + struct rkcif_buffer *buffer; + + buffer =3D stream->buffers[stream->frame_phase]; + if (!buffer->is_dummy) + rkcif_stream_complete_buffer(stream, buffer); + + buffer =3D rkcif_stream_pop_buffer(stream); + if (buffer) { + stream->buffers[stream->frame_phase] =3D buffer; + stream->buffers[stream->frame_phase]->is_dummy =3D false; + } else { + stream->buffers[stream->frame_phase] =3D &stream->dummy.buffer; + stream->buffers[stream->frame_phase]->is_dummy =3D true; + dev_dbg(stream->rkcif->dev, + "no buffer available, frame will be dropped\n"); + } + + if (stream->queue_buffer) + stream->queue_buffer(stream, stream->frame_phase); + + stream->frame_phase =3D 1 - stream->frame_phase; +} + +static int rkcif_stream_init_buffers(struct rkcif_stream *stream) +{ + struct v4l2_pix_format_mplane *pix =3D &stream->pix; + + stream->buffers[0] =3D rkcif_stream_pop_buffer(stream); + if (!stream->buffers[0]) + goto err_buff_0; + + stream->buffers[1] =3D rkcif_stream_pop_buffer(stream); + if (!stream->buffers[1]) + goto err_buff_1; + + if (stream->queue_buffer) { + stream->queue_buffer(stream, 0); + stream->queue_buffer(stream, 1); + } + + stream->dummy.size =3D pix->num_planes * pix->plane_fmt[0].sizeimage; + stream->dummy.vaddr =3D + dma_alloc_attrs(stream->rkcif->dev, stream->dummy.size, + &stream->dummy.buffer.buff_addr[0], GFP_KERNEL, + DMA_ATTR_NO_KERNEL_MAPPING); + if (!stream->dummy.vaddr) + goto err_dummy; + + for (unsigned int i =3D 1; i < pix->num_planes; i++) + stream->dummy.buffer.buff_addr[i] =3D + stream->dummy.buffer.buff_addr[i - 1] + + pix->plane_fmt[i - 1].bytesperline * pix->height; + + return 0; + +err_dummy: + rkcif_stream_return_buffer(stream->buffers[1], VB2_BUF_STATE_QUEUED); + stream->buffers[1] =3D NULL; + +err_buff_1: + rkcif_stream_return_buffer(stream->buffers[0], VB2_BUF_STATE_QUEUED); + stream->buffers[0] =3D NULL; +err_buff_0: + return -EINVAL; +} + +static void rkcif_stream_return_all_buffers(struct rkcif_stream *stream, + enum vb2_buffer_state state) +{ + struct rkcif_buffer *buffer; + + if (stream->buffers[0] && !stream->buffers[0]->is_dummy) { + rkcif_stream_return_buffer(stream->buffers[0], state); + stream->buffers[0] =3D NULL; + } + + if (stream->buffers[1] && !stream->buffers[1]->is_dummy) { + rkcif_stream_return_buffer(stream->buffers[1], state); + stream->buffers[1] =3D NULL; + } + + while ((buffer =3D rkcif_stream_pop_buffer(stream))) + rkcif_stream_return_buffer(buffer, state); + + if (stream->dummy.vaddr) { + dma_free_attrs(stream->rkcif->dev, stream->dummy.size, + stream->dummy.vaddr, + stream->dummy.buffer.buff_addr[0], + DMA_ATTR_NO_KERNEL_MAPPING); + stream->dummy.vaddr =3D NULL; + } +} + +static int rkcif_stream_setup_queue(struct vb2_queue *queue, + unsigned int *num_buffers, + unsigned int *num_planes, + unsigned int sizes[], + struct device *alloc_devs[]) +{ + struct rkcif_stream *stream =3D queue->drv_priv; + struct v4l2_pix_format_mplane *pix =3D &stream->pix; + + if (*num_planes) { + if (*num_planes !=3D pix->num_planes) + return -EINVAL; + + for (unsigned int i =3D 0; i < pix->num_planes; i++) + if (sizes[i] < pix->plane_fmt[i].sizeimage) + return -EINVAL; + } else { + *num_planes =3D pix->num_planes; + for (unsigned int i =3D 0; i < pix->num_planes; i++) + sizes[i] =3D pix->plane_fmt[i].sizeimage; + } + + return 0; +} + +static int rkcif_stream_prepare_buffer(struct vb2_buffer *vb) +{ + struct vb2_v4l2_buffer *vbuf =3D to_vb2_v4l2_buffer(vb); + struct rkcif_buffer *buffer =3D to_rkcif_buffer(vbuf); + struct rkcif_stream *stream =3D vb->vb2_queue->drv_priv; + const struct rkcif_output_fmt *fmt; + struct v4l2_pix_format_mplane *pix =3D &stream->pix; + unsigned int i; + + memset(buffer->buff_addr, 0, sizeof(buffer->buff_addr)); + for (i =3D 0; i < pix->num_planes; i++) + buffer->buff_addr[i] =3D vb2_dma_contig_plane_dma_addr(vb, i); + + /* apply fallback for non-mplane formats, if required */ + if (pix->num_planes =3D=3D 1) { + fmt =3D rkcif_stream_find_output_fmt(stream, true, + pix->pixelformat); + for (i =3D 1; i < fmt->cplanes; i++) + buffer->buff_addr[i] =3D + buffer->buff_addr[i - 1] + + pix->plane_fmt[i - 1].bytesperline * + pix->height; + } + + for (i =3D 0; i < pix->num_planes; i++) { + unsigned long size =3D pix->plane_fmt[i].sizeimage; + + if (vb2_plane_size(vb, i) < size) { + dev_err(stream->rkcif->dev, + "user buffer too small (%ld < %ld)\n", + vb2_plane_size(vb, i), size); + return -EINVAL; + } + + vb2_set_plane_payload(vb, i, size); + } + + vbuf->field =3D V4L2_FIELD_NONE; + + return 0; +} + +static void rkcif_stream_queue_buffer(struct vb2_buffer *vb) +{ + struct vb2_v4l2_buffer *vbuf =3D to_vb2_v4l2_buffer(vb); + struct rkcif_buffer *buffer =3D to_rkcif_buffer(vbuf); + struct rkcif_stream *stream =3D vb->vb2_queue->drv_priv; + + rkcif_stream_push_buffer(stream, buffer); +} + +static int rkcif_stream_start_streaming(struct vb2_queue *queue, + unsigned int count) +{ + struct rkcif_stream *stream =3D queue->drv_priv; + struct rkcif_device *rkcif =3D stream->rkcif; + u64 mask; + int ret; + + stream->frame_idx =3D 0; + stream->frame_phase =3D 0; + + ret =3D video_device_pipeline_start(&stream->vdev, &stream->pipeline); + if (ret) { + dev_err(rkcif->dev, "failed to start pipeline %d\n", ret); + goto err_out; + } + + ret =3D pm_runtime_resume_and_get(rkcif->dev); + if (ret < 0) { + dev_err(rkcif->dev, "failed to get runtime pm, %d\n", ret); + goto err_pipeline_stop; + } + + ret =3D rkcif_stream_init_buffers(stream); + if (ret) + goto err_runtime_put; + + if (stream->start_streaming) { + ret =3D stream->start_streaming(stream); + if (ret < 0) + goto err_runtime_put; + } + + mask =3D BIT_ULL(stream->id); + ret =3D v4l2_subdev_enable_streams(&stream->interface->sd, + RKCIF_IF_PAD_SRC, mask); + if (ret < 0) + goto err_stop_stream; + + return 0; + +err_stop_stream: + if (stream->stop_streaming) + stream->stop_streaming(stream); +err_runtime_put: + pm_runtime_put(rkcif->dev); +err_pipeline_stop: + video_device_pipeline_stop(&stream->vdev); +err_out: + rkcif_stream_return_all_buffers(stream, VB2_BUF_STATE_QUEUED); + return ret; +} + +static void rkcif_stream_stop_streaming(struct vb2_queue *queue) +{ + struct rkcif_stream *stream =3D queue->drv_priv; + struct rkcif_device *rkcif =3D stream->rkcif; + u64 mask; + int ret; + + mask =3D BIT_ULL(stream->id); + v4l2_subdev_disable_streams(&stream->interface->sd, RKCIF_IF_PAD_SRC, + mask); + + stream->stopping =3D true; + ret =3D wait_event_timeout(stream->wq_stopped, !stream->stopping, + msecs_to_jiffies(1000)); + + if (!ret && stream->stop_streaming) + stream->stop_streaming(stream); + + pm_runtime_put(rkcif->dev); + + rkcif_stream_return_all_buffers(stream, VB2_BUF_STATE_ERROR); + + video_device_pipeline_stop(&stream->vdev); +} + +static const struct vb2_ops rkcif_stream_vb2_ops =3D { + .queue_setup =3D rkcif_stream_setup_queue, + .buf_prepare =3D rkcif_stream_prepare_buffer, + .buf_queue =3D rkcif_stream_queue_buffer, + .wait_prepare =3D vb2_ops_wait_prepare, + .wait_finish =3D vb2_ops_wait_finish, + .start_streaming =3D rkcif_stream_start_streaming, + .stop_streaming =3D rkcif_stream_stop_streaming, +}; + +static int rkcif_stream_fill_format(struct rkcif_stream *stream, + struct v4l2_pix_format_mplane *pix) +{ + const struct rkcif_output_fmt *fmt; + u32 height, width; + int ret; + + fmt =3D rkcif_stream_find_output_fmt(stream, true, pix->pixelformat); + height =3D clamp_t(u32, pix->height, CIF_MIN_HEIGHT, CIF_MAX_HEIGHT); + width =3D clamp_t(u32, pix->width, CIF_MIN_WIDTH, CIF_MAX_WIDTH); + ret =3D v4l2_fill_pixfmt_mp(pix, fmt->fourcc, width, height); + if (ret) + return ret; + + pix->field =3D V4L2_FIELD_NONE; + + return 0; +} + +static int rkcif_stream_try_format(struct file *file, void *fh, + struct v4l2_format *f) +{ + struct rkcif_stream *stream =3D video_drvdata(file); + struct v4l2_pix_format_mplane *pix =3D &f->fmt.pix_mp; + + return rkcif_stream_fill_format(stream, pix); +} + +static int rkcif_stream_set_format(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct rkcif_stream *stream =3D video_drvdata(file); + struct v4l2_pix_format_mplane *pix =3D &f->fmt.pix_mp; + int ret; + + if (vb2_is_busy(&stream->buf_queue)) + return -EBUSY; + + ret =3D rkcif_stream_try_format(file, priv, f); + if (ret) + return ret; + + stream->pix =3D *pix; + + return 0; +} + +static int rkcif_stream_get_format(struct file *file, void *fh, + struct v4l2_format *f) +{ + struct rkcif_stream *stream =3D video_drvdata(file); + + f->fmt.pix_mp =3D stream->pix; + + return 0; +} + +static int rkcif_stream_enum_formats(struct file *file, void *priv, + struct v4l2_fmtdesc *f) +{ + struct rkcif_stream *stream =3D video_drvdata(file); + + if (f->index >=3D stream->out_fmts_num) + return -EINVAL; + + f->pixelformat =3D stream->out_fmts[f->index].fourcc; + + return 0; +} + +static int rkcif_stream_enum_framesizes(struct file *file, void *fh, + struct v4l2_frmsizeenum *fsize) +{ + struct rkcif_stream *stream =3D video_drvdata(file); + + if (fsize->index > 0) + return -EINVAL; + + if (!rkcif_stream_find_output_fmt(stream, false, fsize->pixel_format)) + return -EINVAL; + + fsize->type =3D V4L2_FRMSIZE_TYPE_STEPWISE; + fsize->stepwise.min_width =3D CIF_MIN_WIDTH; + fsize->stepwise.max_width =3D CIF_MAX_WIDTH; + fsize->stepwise.step_width =3D 8; + fsize->stepwise.min_height =3D CIF_MIN_HEIGHT; + fsize->stepwise.max_height =3D CIF_MAX_HEIGHT; + fsize->stepwise.step_height =3D 8; + + return 0; +} + +static int rkcif_stream_querycap(struct file *file, void *priv, + struct v4l2_capability *cap) +{ + struct rkcif_stream *stream =3D video_drvdata(file); + struct device *dev =3D stream->rkcif->dev; + + strscpy(cap->driver, dev->driver->name, sizeof(cap->driver)); + strscpy(cap->card, dev->driver->name, sizeof(cap->card)); + + return 0; +} + +static const struct v4l2_ioctl_ops rkcif_stream_ioctl_ops =3D { + .vidioc_reqbufs =3D vb2_ioctl_reqbufs, + .vidioc_querybuf =3D vb2_ioctl_querybuf, + .vidioc_create_bufs =3D vb2_ioctl_create_bufs, + .vidioc_qbuf =3D vb2_ioctl_qbuf, + .vidioc_expbuf =3D vb2_ioctl_expbuf, + .vidioc_dqbuf =3D vb2_ioctl_dqbuf, + .vidioc_prepare_buf =3D vb2_ioctl_prepare_buf, + .vidioc_streamon =3D vb2_ioctl_streamon, + .vidioc_streamoff =3D vb2_ioctl_streamoff, + .vidioc_try_fmt_vid_cap_mplane =3D rkcif_stream_try_format, + .vidioc_s_fmt_vid_cap_mplane =3D rkcif_stream_set_format, + .vidioc_g_fmt_vid_cap_mplane =3D rkcif_stream_get_format, + .vidioc_enum_fmt_vid_cap =3D rkcif_stream_enum_formats, + .vidioc_enum_framesizes =3D rkcif_stream_enum_framesizes, + .vidioc_querycap =3D rkcif_stream_querycap, +}; + +static int rkcif_stream_link_validate(struct media_link *link) +{ + struct video_device *vdev =3D + media_entity_to_video_device(link->sink->entity); + struct v4l2_mbus_framefmt *source_fmt; + struct v4l2_subdev *sd; + struct v4l2_subdev_state *state; + struct rkcif_stream *stream =3D to_rkcif_stream(vdev); + int ret =3D -EINVAL; + + if (!media_entity_remote_source_pad_unique(link->sink->entity)) + return -ENOTCONN; + + sd =3D media_entity_to_v4l2_subdev(link->source->entity); + + state =3D v4l2_subdev_lock_and_get_active_state(sd); + + source_fmt =3D v4l2_subdev_state_get_format(state, link->source->index, + stream->id); + if (!source_fmt) + goto out; + + if (source_fmt->height !=3D stream->pix.height || + source_fmt->width !=3D stream->pix.width) { + dev_dbg(stream->rkcif->dev, + "link '%s':%u -> '%s':%u not valid: %ux%u !=3D %ux%u\n", + link->source->entity->name, link->source->index, + link->sink->entity->name, link->sink->index, + source_fmt->width, source_fmt->height, + stream->pix.width, stream->pix.height); + goto out; + } + + ret =3D 0; + +out: + v4l2_subdev_unlock_state(state); + return ret; +} + +static const struct media_entity_operations rkcif_stream_media_ops =3D { + .link_validate =3D rkcif_stream_link_validate, +}; + +static const struct v4l2_file_operations rkcif_stream_file_ops =3D { + .open =3D v4l2_fh_open, + .release =3D vb2_fop_release, + .unlocked_ioctl =3D video_ioctl2, + .poll =3D vb2_fop_poll, + .mmap =3D vb2_fop_mmap, +}; + +static int rkcif_stream_init_vb2_queue(struct vb2_queue *q, + struct rkcif_stream *stream) +{ + q->type =3D V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + q->io_modes =3D VB2_MMAP | VB2_DMABUF; + q->drv_priv =3D stream; + q->ops =3D &rkcif_stream_vb2_ops; + q->mem_ops =3D &vb2_dma_contig_memops; + q->buf_struct_size =3D sizeof(struct rkcif_buffer); + q->min_queued_buffers =3D CIF_REQ_BUFS_MIN; + q->timestamp_flags =3D V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; + q->lock =3D &stream->vlock; + q->dev =3D stream->rkcif->dev; + + return vb2_queue_init(q); +} + +int rkcif_stream_register(struct rkcif_device *rkcif, + struct rkcif_stream *stream) +{ + struct rkcif_interface *interface =3D stream->interface; + struct v4l2_device *v4l2_dev =3D &rkcif->v4l2_dev; + struct video_device *vdev =3D &stream->vdev; + u32 link_flags =3D 0; + int ret; + + stream->rkcif =3D rkcif; + + INIT_LIST_HEAD(&stream->driver_queue); + spin_lock_init(&stream->driver_queue_lock); + + init_waitqueue_head(&stream->wq_stopped); + + mutex_init(&stream->vlock); + + vdev->device_caps =3D V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_STREAMING | + V4L2_CAP_IO_MC; + vdev->entity.ops =3D &rkcif_stream_media_ops; + vdev->fops =3D &rkcif_stream_file_ops; + vdev->ioctl_ops =3D &rkcif_stream_ioctl_ops; + vdev->lock =3D &stream->vlock; + vdev->minor =3D -1; + vdev->release =3D video_device_release_empty; + vdev->v4l2_dev =3D v4l2_dev; + vdev->vfl_dir =3D VFL_DIR_RX; + video_set_drvdata(vdev, stream); + + stream->pad.flags =3D MEDIA_PAD_FL_SINK; + + stream->pix.height =3D CIF_MIN_HEIGHT; + stream->pix.width =3D CIF_MIN_WIDTH; + rkcif_stream_fill_format(stream, &stream->pix); + + rkcif_stream_init_vb2_queue(&stream->buf_queue, stream); + + vdev->queue =3D &stream->buf_queue; + if (interface->type =3D=3D RKCIF_IF_DVP) + snprintf(vdev->name, sizeof(vdev->name), "rkcif-dvp0-id%d", + stream->id); + else if (interface->type =3D=3D RKCIF_IF_MIPI) + snprintf(vdev->name, sizeof(vdev->name), "rkcif-mipi%d-id%d", + interface->index - RKCIF_MIPI_BASE, stream->id); + + ret =3D media_entity_pads_init(&vdev->entity, 1, &stream->pad); + if (ret < 0) { + dev_err(rkcif->dev, + "failed to initialize stream media pad: %d\n", ret); + return ret; + } + + ret =3D video_register_device(vdev, VFL_TYPE_VIDEO, -1); + if (ret < 0) { + dev_err(rkcif->dev, "failed to register video device: %d\n", + ret); + goto err_media_entity_cleanup; + } + + /* enable only stream ID0 by default */ + if (stream->id =3D=3D RKCIF_ID0) + link_flags |=3D MEDIA_LNK_FL_ENABLED; + + ret =3D media_create_pad_link(&interface->sd.entity, RKCIF_IF_PAD_SRC, + &stream->vdev.entity, 0, link_flags); + if (ret) { + dev_err(rkcif->dev, "failed to link stream media pad: %d\n", + ret); + goto err_video_unregister; + } + + v4l2_info(v4l2_dev, "registered %s as /dev/video%d\n", vdev->name, + vdev->num); + + return 0; + +err_video_unregister: + video_unregister_device(&stream->vdev); +err_media_entity_cleanup: + media_entity_cleanup(&stream->vdev.entity); + return ret; +} + +void rkcif_stream_unregister(struct rkcif_stream *stream) +{ + video_unregister_device(&stream->vdev); + media_entity_cleanup(&stream->vdev.entity); +} + +const struct rkcif_output_fmt * +rkcif_stream_find_output_fmt(struct rkcif_stream *stream, bool ret_def, + u32 pixelfmt) +{ + const struct rkcif_output_fmt *fmt; + + WARN_ON(stream->out_fmts_num =3D=3D 0); + + for (unsigned int i =3D 0; i < stream->out_fmts_num; i++) { + fmt =3D &stream->out_fmts[i]; + if (fmt->fourcc =3D=3D pixelfmt) + return fmt; + } + + if (ret_def) + return &stream->out_fmts[0]; + else + return NULL; +} diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-stream.h b/drivers= /media/platform/rockchip/rkcif/rkcif-stream.h new file mode 100644 index 000000000000..590faf5d1a87 --- /dev/null +++ b/drivers/media/platform/rockchip/rkcif/rkcif-stream.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Rockchip Camera Interface (CIF) Driver + * + * Abstraction for the DMA part and the ping-pong scheme (a double-bufferi= ng + * mechanism) of the different CIF variants. + * Each stream is represented as V4L2 device whose corresponding media ent= ity + * has one sink pad. + * The sink pad is connected to an instance of the INTERFACE/CROP abstract= ion + * in rkcif-interface.c. + * + * Copyright (C) 2025 Michael Riesch + * Copyright (C) 2025 Collabora, Ltd. + */ + +#ifndef _RKCIF_STREAM_H +#define _RKCIF_STREAM_H + +#include "rkcif-common.h" + +void rkcif_stream_pingpong(struct rkcif_stream *stream); + +int rkcif_stream_register(struct rkcif_device *rkcif, + struct rkcif_stream *stream); + +void rkcif_stream_unregister(struct rkcif_stream *stream); + +const struct rkcif_output_fmt * +rkcif_stream_find_output_fmt(struct rkcif_stream *stream, bool ret_def, + u32 pixelfmt); + +#endif --=20 2.39.5 From nobody Mon Dec 15 21:31:27 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 D5424340285; Fri, 14 Nov 2025 15:20:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763133620; cv=none; b=jWgqSugqJsr3RgKg+rv671dy8bEQGKjv7Ei5hulpJtLXa3jok4qzMwNd1ilNKuIgUKlkvQQULu73nwmFEdYfmVMnBX12K6pKvLPdzz2RmU055rQqL1K8D6WbY8WyUr/8onF474k4RpalE2qzfskYgVWb65GYQMzDMUcsbZaA+VQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763133620; c=relaxed/simple; bh=GHnxTRuw22MR4qtuwF9W2TDh3o/kXnhIvkimy2U9IeY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=WmqfGF+5+DJeI82gj18+hfNsmeOOdZVNLC6XsJrL13bEoYdXq5c+5rjnshfgkDnGbST5s/HNqZxhSIN7gi+Rd3o0A2N/gdM32lHJE1SReslHZy8qef3SK3t75QLerbFb8gXc40KnepB88VBbWMgdQIj166Rb0szSYxVYTFnJ6OE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Q5T83CxV; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Q5T83CxV" Received: by smtp.kernel.org (Postfix) with ESMTPS id 6C900C4CEFB; Fri, 14 Nov 2025 15:20:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1763133620; bh=GHnxTRuw22MR4qtuwF9W2TDh3o/kXnhIvkimy2U9IeY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=Q5T83CxVBU8JJH2HAMaTRvni/bXk83FfRxEWkz3Q5I7p28n2oppB5/1azviQpizwZ 2wmR35QfNPXkAEyaaOa5bBcS1rjI/prhO0WZ5Id4EbbLlpH9mIHL/F2wq3/5rdvNzv 0ZniH1KPr3PkWn4eiIEh+YGezxKejt66rQfD98PZ9T9763XBMtB9mX+SnRs2NcPJr0 nb/CbNMqceLGoIr05ZnBQFhDoowiENExqrCk3B5cBXIcn/yVrad4fp+1uMb9icLq5O dHWPi/Z8w9si7AwdU0XPWzyI7PXSFUwLvWvFTcCjn+BS54HkmljbnDFWufEpgehY6y 9S4u5aRjerxeQ== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5D161CE8D43; Fri, 14 Nov 2025 15:20:20 +0000 (UTC) From: Michael Riesch via B4 Relay Date: Fri, 14 Nov 2025 16:20:19 +0100 Subject: [PATCH v15 08/14] media: rockchip: rkcif: add support for px30 vip dvp capture 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: <20240220-rk3568-vicap-v15-8-8f4915ee365d@collabora.com> References: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com> In-Reply-To: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com> To: Mehdi Djait , Maxime Chevallier , =?utf-8?q?Th=C3=A9o_Lebrun?= , Thomas Petazzoni , Gerald Loacker , Bryan O'Donoghue , Markus Elfring , Laurent Pinchart , Mauro Carvalho Chehab , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Heiko Stuebner , Kever Yang , Nicolas Dufresne , Sebastian Reichel , Collabora Kernel Team , Paul Kocialkowski , Alexander Shiyan , Val Packett , Rob Herring , Philipp Zabel , Sakari Ailus Cc: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, Michael Riesch , Michael Riesch X-Mailer: b4 0.12.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1763133617; l=27257; i=michael.riesch@collabora.com; s=20250410; h=from:subject:message-id; bh=4bio6dhNI8REHClVwTSJls2FCV0NnymBkYJ/imUqP68=; b=upTjyLT2wzZLXVRrbrMtC6H9SysVY4SPBBTN00rKQbgtwF8klKTukFyZk7jZ5lpV5my2P23Bt 1DK+eplgOV4BF1Ns+sC2YPFzX81qeKD2KFHIoXYn8sMm0tIz1Rz/8ur X-Developer-Key: i=michael.riesch@collabora.com; a=ed25519; pk=+MWX1fffLFZtTPG/I6XdYm/+OSvpRE8D9evQaWbiN04= X-Endpoint-Received: by B4 Relay for michael.riesch@collabora.com/20250410 with auth_id=371 X-Original-From: Michael Riesch Reply-To: michael.riesch@collabora.com From: Michael Riesch The PX30 Video Input Processor (VIP) unit features a Digital Video Port (DVP). Add support for the DVP in general and for the PX30 VIP DVP in particular. Tested-by: Gerald Loacker Reviewed-by: Gerald Loacker Reviewed-by: Bryan O'Donoghue Reviewed-by: Mehdi Djait Signed-off-by: Michael Riesch --- drivers/media/platform/rockchip/rkcif/Makefile | 1 + .../platform/rockchip/rkcif/rkcif-capture-dvp.c | 589 +++++++++++++++++= ++++ .../platform/rockchip/rkcif/rkcif-capture-dvp.h | 24 + .../media/platform/rockchip/rkcif/rkcif-common.h | 28 + drivers/media/platform/rockchip/rkcif/rkcif-dev.c | 15 + drivers/media/platform/rockchip/rkcif/rkcif-regs.h | 131 +++++ 6 files changed, 788 insertions(+) diff --git a/drivers/media/platform/rockchip/rkcif/Makefile b/drivers/media= /platform/rockchip/rkcif/Makefile index 256335d95050..a36e294d569d 100644 --- a/drivers/media/platform/rockchip/rkcif/Makefile +++ b/drivers/media/platform/rockchip/rkcif/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_VIDEO_ROCKCHIP_CIF) +=3D rockchip-cif.o =20 +rockchip-cif-objs +=3D rkcif-capture-dvp.o rockchip-cif-objs +=3D rkcif-dev.o rockchip-cif-objs +=3D rkcif-interface.o rockchip-cif-objs +=3D rkcif-stream.o diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-capture-dvp.c b/dr= ivers/media/platform/rockchip/rkcif/rkcif-capture-dvp.c new file mode 100644 index 000000000000..b40135035ab8 --- /dev/null +++ b/drivers/media/platform/rockchip/rkcif/rkcif-capture-dvp.c @@ -0,0 +1,589 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Rockchip Camera Interface (CIF) Driver + * + * Copyright (C) 2018 Rockchip Electronics Co., Ltd. + * Copyright (C) 2020 Maxime Chevallier + * Copyright (C) 2023 Mehdi Djait + * Copyright (C) 2025 Michael Riesch + * Copyright (C) 2025 Collabora, Ltd. + */ + +#include +#include +#include +#include + +#include "rkcif-capture-dvp.h" +#include "rkcif-common.h" +#include "rkcif-interface.h" +#include "rkcif-regs.h" +#include "rkcif-stream.h" + +static const struct rkcif_output_fmt dvp_out_fmts[] =3D { + { + .fourcc =3D V4L2_PIX_FMT_NV16, + .dvp_fmt_val =3D RKCIF_FORMAT_YUV_OUTPUT_422 | + RKCIF_FORMAT_UV_STORAGE_ORDER_UVUV, + .cplanes =3D 2, + }, + { + .fourcc =3D V4L2_PIX_FMT_NV16M, + .dvp_fmt_val =3D RKCIF_FORMAT_YUV_OUTPUT_422 | + RKCIF_FORMAT_UV_STORAGE_ORDER_UVUV, + .cplanes =3D 2, + }, + { + .fourcc =3D V4L2_PIX_FMT_NV61, + .dvp_fmt_val =3D RKCIF_FORMAT_YUV_OUTPUT_422 | + RKCIF_FORMAT_UV_STORAGE_ORDER_VUVU, + .cplanes =3D 2, + }, + { + .fourcc =3D V4L2_PIX_FMT_NV61M, + .dvp_fmt_val =3D RKCIF_FORMAT_YUV_OUTPUT_422 | + RKCIF_FORMAT_UV_STORAGE_ORDER_VUVU, + .cplanes =3D 2, + }, + { + .fourcc =3D V4L2_PIX_FMT_NV12, + .dvp_fmt_val =3D RKCIF_FORMAT_YUV_OUTPUT_420 | + RKCIF_FORMAT_UV_STORAGE_ORDER_UVUV, + .cplanes =3D 2, + }, + { + .fourcc =3D V4L2_PIX_FMT_NV12M, + .dvp_fmt_val =3D RKCIF_FORMAT_YUV_OUTPUT_420 | + RKCIF_FORMAT_UV_STORAGE_ORDER_UVUV, + .cplanes =3D 2, + }, + { + .fourcc =3D V4L2_PIX_FMT_NV21, + .dvp_fmt_val =3D RKCIF_FORMAT_YUV_OUTPUT_420 | + RKCIF_FORMAT_UV_STORAGE_ORDER_VUVU, + .cplanes =3D 2, + }, + { + .fourcc =3D V4L2_PIX_FMT_NV21M, + .dvp_fmt_val =3D RKCIF_FORMAT_YUV_OUTPUT_420 | + RKCIF_FORMAT_UV_STORAGE_ORDER_VUVU, + .cplanes =3D 2, + }, + { + .fourcc =3D V4L2_PIX_FMT_RGB24, + .cplanes =3D 1, + }, + { + .fourcc =3D V4L2_PIX_FMT_RGB565, + .cplanes =3D 1, + }, + { + .fourcc =3D V4L2_PIX_FMT_BGR666, + .cplanes =3D 1, + }, + { + .fourcc =3D V4L2_PIX_FMT_SRGGB8, + .cplanes =3D 1, + }, + { + .fourcc =3D V4L2_PIX_FMT_SGRBG8, + .cplanes =3D 1, + }, + { + .fourcc =3D V4L2_PIX_FMT_SGBRG8, + .cplanes =3D 1, + }, + { + .fourcc =3D V4L2_PIX_FMT_SBGGR8, + .cplanes =3D 1, + }, + { + .fourcc =3D V4L2_PIX_FMT_SRGGB10, + .cplanes =3D 1, + }, + { + .fourcc =3D V4L2_PIX_FMT_SGRBG10, + .cplanes =3D 1, + }, + { + .fourcc =3D V4L2_PIX_FMT_SGBRG10, + .cplanes =3D 1, + }, + { + .fourcc =3D V4L2_PIX_FMT_SBGGR10, + .cplanes =3D 1, + }, + { + .fourcc =3D V4L2_PIX_FMT_SRGGB12, + .cplanes =3D 1, + }, + { + .fourcc =3D V4L2_PIX_FMT_SGRBG12, + .cplanes =3D 1, + }, + { + .fourcc =3D V4L2_PIX_FMT_SGBRG12, + .cplanes =3D 1, + }, + { + .fourcc =3D V4L2_PIX_FMT_SBGGR12, + .cplanes =3D 1, + }, + { + .fourcc =3D V4L2_PIX_FMT_SBGGR16, + .cplanes =3D 1, + }, + { + .fourcc =3D V4L2_PIX_FMT_Y16, + .cplanes =3D 1, + }, +}; + +static const struct rkcif_input_fmt px30_dvp_in_fmts[] =3D { + { + .mbus_code =3D MEDIA_BUS_FMT_YUYV8_2X8, + .dvp_fmt_val =3D RKCIF_FORMAT_YUV_INPUT_422 | + RKCIF_FORMAT_YUV_INPUT_ORDER_YUYV, + .fmt_type =3D RKCIF_FMT_TYPE_YUV, + .field =3D V4L2_FIELD_NONE, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_YUYV8_2X8, + .dvp_fmt_val =3D RKCIF_FORMAT_YUV_INPUT_422 | + RKCIF_FORMAT_YUV_INPUT_ORDER_YUYV, + .fmt_type =3D RKCIF_FMT_TYPE_YUV, + .field =3D V4L2_FIELD_INTERLACED, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_YVYU8_2X8, + .dvp_fmt_val =3D RKCIF_FORMAT_YUV_INPUT_422 | + RKCIF_FORMAT_YUV_INPUT_ORDER_YVYU, + .fmt_type =3D RKCIF_FMT_TYPE_YUV, + .field =3D V4L2_FIELD_NONE, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_YVYU8_2X8, + .dvp_fmt_val =3D RKCIF_FORMAT_YUV_INPUT_422 | + RKCIF_FORMAT_YUV_INPUT_ORDER_YVYU, + .fmt_type =3D RKCIF_FMT_TYPE_YUV, + .field =3D V4L2_FIELD_INTERLACED, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_UYVY8_2X8, + .dvp_fmt_val =3D RKCIF_FORMAT_YUV_INPUT_422 | + RKCIF_FORMAT_YUV_INPUT_ORDER_UYVY, + .fmt_type =3D RKCIF_FMT_TYPE_YUV, + .field =3D V4L2_FIELD_NONE, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_UYVY8_2X8, + .dvp_fmt_val =3D RKCIF_FORMAT_YUV_INPUT_422 | + RKCIF_FORMAT_YUV_INPUT_ORDER_UYVY, + .fmt_type =3D RKCIF_FMT_TYPE_YUV, + .field =3D V4L2_FIELD_INTERLACED, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_VYUY8_2X8, + .dvp_fmt_val =3D RKCIF_FORMAT_YUV_INPUT_422 | + RKCIF_FORMAT_YUV_INPUT_ORDER_VYUY, + .fmt_type =3D RKCIF_FMT_TYPE_YUV, + .field =3D V4L2_FIELD_NONE, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_VYUY8_2X8, + .dvp_fmt_val =3D RKCIF_FORMAT_YUV_INPUT_422 | + RKCIF_FORMAT_YUV_INPUT_ORDER_VYUY, + .fmt_type =3D RKCIF_FMT_TYPE_YUV, + .field =3D V4L2_FIELD_INTERLACED, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_SBGGR8_1X8, + .dvp_fmt_val =3D RKCIF_FORMAT_INPUT_MODE_RAW | + RKCIF_FORMAT_RAW_DATA_WIDTH_8, + .fmt_type =3D RKCIF_FMT_TYPE_RAW, + .field =3D V4L2_FIELD_NONE, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_SGBRG8_1X8, + .dvp_fmt_val =3D RKCIF_FORMAT_INPUT_MODE_RAW | + RKCIF_FORMAT_RAW_DATA_WIDTH_8, + .fmt_type =3D RKCIF_FMT_TYPE_RAW, + .field =3D V4L2_FIELD_NONE, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_SGRBG8_1X8, + .dvp_fmt_val =3D RKCIF_FORMAT_INPUT_MODE_RAW | + RKCIF_FORMAT_RAW_DATA_WIDTH_8, + .fmt_type =3D RKCIF_FMT_TYPE_RAW, + .field =3D V4L2_FIELD_NONE, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_SRGGB8_1X8, + .dvp_fmt_val =3D RKCIF_FORMAT_INPUT_MODE_RAW | + RKCIF_FORMAT_RAW_DATA_WIDTH_8, + .fmt_type =3D RKCIF_FMT_TYPE_RAW, + .field =3D V4L2_FIELD_NONE, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_SBGGR10_1X10, + .dvp_fmt_val =3D RKCIF_FORMAT_INPUT_MODE_RAW | + RKCIF_FORMAT_RAW_DATA_WIDTH_10, + .fmt_type =3D RKCIF_FMT_TYPE_RAW, + .field =3D V4L2_FIELD_NONE, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_SGBRG10_1X10, + .dvp_fmt_val =3D RKCIF_FORMAT_INPUT_MODE_RAW | + RKCIF_FORMAT_RAW_DATA_WIDTH_10, + .fmt_type =3D RKCIF_FMT_TYPE_RAW, + .field =3D V4L2_FIELD_NONE, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_SGRBG10_1X10, + .dvp_fmt_val =3D RKCIF_FORMAT_INPUT_MODE_RAW | + RKCIF_FORMAT_RAW_DATA_WIDTH_10, + .fmt_type =3D RKCIF_FMT_TYPE_RAW, + .field =3D V4L2_FIELD_NONE, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_SRGGB10_1X10, + .dvp_fmt_val =3D RKCIF_FORMAT_INPUT_MODE_RAW | + RKCIF_FORMAT_RAW_DATA_WIDTH_10, + .fmt_type =3D RKCIF_FMT_TYPE_RAW, + .field =3D V4L2_FIELD_NONE, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_SBGGR12_1X12, + .dvp_fmt_val =3D RKCIF_FORMAT_INPUT_MODE_RAW | + RKCIF_FORMAT_RAW_DATA_WIDTH_12, + .fmt_type =3D RKCIF_FMT_TYPE_RAW, + .field =3D V4L2_FIELD_NONE, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_SGBRG12_1X12, + .dvp_fmt_val =3D RKCIF_FORMAT_INPUT_MODE_RAW | + RKCIF_FORMAT_RAW_DATA_WIDTH_12, + .fmt_type =3D RKCIF_FMT_TYPE_RAW, + .field =3D V4L2_FIELD_NONE, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_SGRBG12_1X12, + .dvp_fmt_val =3D RKCIF_FORMAT_INPUT_MODE_RAW | + RKCIF_FORMAT_RAW_DATA_WIDTH_12, + .fmt_type =3D RKCIF_FMT_TYPE_RAW, + .field =3D V4L2_FIELD_NONE, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_SRGGB12_1X12, + .dvp_fmt_val =3D RKCIF_FORMAT_INPUT_MODE_RAW | + RKCIF_FORMAT_RAW_DATA_WIDTH_12, + .fmt_type =3D RKCIF_FMT_TYPE_RAW, + .field =3D V4L2_FIELD_NONE, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_RGB888_1X24, + .field =3D V4L2_FIELD_NONE, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_Y8_1X8, + .dvp_fmt_val =3D RKCIF_FORMAT_INPUT_MODE_RAW | + RKCIF_FORMAT_RAW_DATA_WIDTH_8, + .fmt_type =3D RKCIF_FMT_TYPE_RAW, + .field =3D V4L2_FIELD_NONE, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_Y10_1X10, + .dvp_fmt_val =3D RKCIF_FORMAT_INPUT_MODE_RAW | + RKCIF_FORMAT_RAW_DATA_WIDTH_10, + .fmt_type =3D RKCIF_FMT_TYPE_RAW, + .field =3D V4L2_FIELD_NONE, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_Y12_1X12, + .dvp_fmt_val =3D RKCIF_FORMAT_INPUT_MODE_RAW | + RKCIF_FORMAT_RAW_DATA_WIDTH_12, + .fmt_type =3D RKCIF_FMT_TYPE_RAW, + .field =3D V4L2_FIELD_NONE, + } +}; + +const struct rkcif_dvp_match_data rkcif_px30_vip_dvp_match_data =3D { + .in_fmts =3D px30_dvp_in_fmts, + .in_fmts_num =3D ARRAY_SIZE(px30_dvp_in_fmts), + .out_fmts =3D dvp_out_fmts, + .out_fmts_num =3D ARRAY_SIZE(dvp_out_fmts), + .has_scaler =3D true, + .regs =3D { + [RKCIF_DVP_CTRL] =3D 0x00, + [RKCIF_DVP_INTEN] =3D 0x04, + [RKCIF_DVP_INTSTAT] =3D 0x08, + [RKCIF_DVP_FOR] =3D 0x0c, + [RKCIF_DVP_LINE_NUM_ADDR] =3D 0x10, + [RKCIF_DVP_FRM0_ADDR_Y] =3D 0x14, + [RKCIF_DVP_FRM0_ADDR_UV] =3D 0x18, + [RKCIF_DVP_FRM1_ADDR_Y] =3D 0x1c, + [RKCIF_DVP_FRM1_ADDR_UV] =3D 0x20, + [RKCIF_DVP_VIR_LINE_WIDTH] =3D 0x24, + [RKCIF_DVP_SET_SIZE] =3D 0x28, + [RKCIF_DVP_SCL_CTRL] =3D 0x48, + [RKCIF_DVP_FRAME_STATUS] =3D 0x60, + [RKCIF_DVP_LAST_LINE] =3D 0x68, + [RKCIF_DVP_LAST_PIX] =3D 0x6c, + }, +}; + +static inline unsigned int rkcif_dvp_get_addr(struct rkcif_device *rkcif, + unsigned int index) +{ + if (WARN_ON_ONCE(index >=3D RKCIF_DVP_REGISTER_MAX)) + return RKCIF_REGISTER_NOTSUPPORTED; + + return rkcif->match_data->dvp->regs[index]; +} + +static inline __maybe_unused void rkcif_dvp_write(struct rkcif_device *rkc= if, + unsigned int index, u32 val) +{ + unsigned int addr =3D rkcif_dvp_get_addr(rkcif, index); + + if (addr =3D=3D RKCIF_REGISTER_NOTSUPPORTED) + return; + + writel(val, rkcif->base_addr + addr); +} + +static inline __maybe_unused u32 rkcif_dvp_read(struct rkcif_device *rkcif, + unsigned int index) +{ + unsigned int addr =3D rkcif_dvp_get_addr(rkcif, index); + + if (addr =3D=3D RKCIF_REGISTER_NOTSUPPORTED) + return 0; + + return readl(rkcif->base_addr + addr); +} + +static void rkcif_dvp_queue_buffer(struct rkcif_stream *stream, + unsigned int index) +{ + struct rkcif_device *rkcif =3D stream->rkcif; + struct rkcif_buffer *buffer =3D stream->buffers[index]; + u32 frm_addr_y, frm_addr_uv; + + frm_addr_y =3D index ? RKCIF_DVP_FRM1_ADDR_Y : RKCIF_DVP_FRM0_ADDR_Y; + frm_addr_uv =3D index ? RKCIF_DVP_FRM1_ADDR_UV : RKCIF_DVP_FRM0_ADDR_UV; + + rkcif_dvp_write(rkcif, frm_addr_y, buffer->buff_addr[RKCIF_PLANE_Y]); + rkcif_dvp_write(rkcif, frm_addr_uv, buffer->buff_addr[RKCIF_PLANE_UV]); +} + +static int rkcif_dvp_start_streaming(struct rkcif_stream *stream) +{ + struct rkcif_device *rkcif =3D stream->rkcif; + struct rkcif_interface *interface =3D stream->interface; + struct v4l2_mbus_config_parallel *parallel; + struct v4l2_mbus_framefmt *source_fmt; + struct v4l2_subdev_state *state; + const struct rkcif_input_fmt *active_in_fmt; + const struct rkcif_output_fmt *active_out_fmt; + u32 val =3D 0; + int ret =3D -EINVAL; + + state =3D v4l2_subdev_lock_and_get_active_state(&interface->sd); + source_fmt =3D v4l2_subdev_state_get_format(state, RKCIF_IF_PAD_SRC, + stream->id); + if (!source_fmt) + goto out; + + active_in_fmt =3D rkcif_interface_find_input_fmt(interface, false, + source_fmt->code); + active_out_fmt =3D rkcif_stream_find_output_fmt(stream, false, + stream->pix.pixelformat); + if (!active_in_fmt || !active_out_fmt) + goto out; + + parallel =3D &interface->vep.bus.parallel; + if (parallel->bus_width =3D=3D 16 && + (parallel->flags & V4L2_MBUS_PCLK_SAMPLE_DUALEDGE)) + val |=3D RKCIF_FORMAT_BT1120_CLOCK_DOUBLE_EDGES; + val |=3D active_in_fmt->dvp_fmt_val; + val |=3D active_out_fmt->dvp_fmt_val; + rkcif_dvp_write(rkcif, RKCIF_DVP_FOR, val); + + val =3D stream->pix.width; + if (active_in_fmt->fmt_type =3D=3D RKCIF_FMT_TYPE_RAW) + val =3D stream->pix.width * 2; + rkcif_dvp_write(rkcif, RKCIF_DVP_VIR_LINE_WIDTH, val); + + val =3D RKCIF_XY_COORD(stream->pix.width, stream->pix.height); + rkcif_dvp_write(rkcif, RKCIF_DVP_SET_SIZE, val); + + rkcif_dvp_write(rkcif, RKCIF_DVP_FRAME_STATUS, RKCIF_FRAME_STAT_CLS); + rkcif_dvp_write(rkcif, RKCIF_DVP_INTSTAT, RKCIF_INTSTAT_CLS); + if (rkcif->match_data->dvp->has_scaler) { + val =3D active_in_fmt->fmt_type =3D=3D RKCIF_FMT_TYPE_YUV ? + RKCIF_SCL_CTRL_ENABLE_YUV_16BIT_BYPASS : + RKCIF_SCL_CTRL_ENABLE_RAW_16BIT_BYPASS; + rkcif_dvp_write(rkcif, RKCIF_DVP_SCL_CTRL, val); + } + + rkcif_dvp_write(rkcif, RKCIF_DVP_INTEN, + RKCIF_INTEN_FRAME_END_EN | + RKCIF_INTEN_PST_INF_FRAME_END_EN); + + rkcif_dvp_write(rkcif, RKCIF_DVP_CTRL, + RKCIF_CTRL_AXI_BURST_16 | RKCIF_CTRL_MODE_PINGPONG | + RKCIF_CTRL_ENABLE_CAPTURE); + + ret =3D 0; + +out: + v4l2_subdev_unlock_state(state); + return ret; +} + +static void rkcif_dvp_stop_streaming(struct rkcif_stream *stream) +{ + struct rkcif_device *rkcif =3D stream->rkcif; + u32 val; + + val =3D rkcif_dvp_read(rkcif, RKCIF_DVP_CTRL); + rkcif_dvp_write(rkcif, RKCIF_DVP_CTRL, + val & (~RKCIF_CTRL_ENABLE_CAPTURE)); + rkcif_dvp_write(rkcif, RKCIF_DVP_INTEN, 0x0); + rkcif_dvp_write(rkcif, RKCIF_DVP_INTSTAT, 0x3ff); + rkcif_dvp_write(rkcif, RKCIF_DVP_FRAME_STATUS, 0x0); + + stream->stopping =3D false; +} + +static void rkcif_dvp_reset_stream(struct rkcif_device *rkcif) +{ + u32 ctl =3D rkcif_dvp_read(rkcif, RKCIF_DVP_CTRL); + + rkcif_dvp_write(rkcif, RKCIF_DVP_CTRL, + ctl & (~RKCIF_CTRL_ENABLE_CAPTURE)); + rkcif_dvp_write(rkcif, RKCIF_DVP_CTRL, ctl | RKCIF_CTRL_ENABLE_CAPTURE); +} + +static void rkcif_dvp_set_crop(struct rkcif_stream *stream, u16 left, u16 = top) +{ + struct rkcif_device *rkcif =3D stream->rkcif; + u32 val; + + val =3D RKCIF_XY_COORD(left, top); + rkcif_dvp_write(rkcif, RKCIF_DVP_CROP, val); +} + +irqreturn_t rkcif_dvp_isr(int irq, void *ctx) +{ + struct device *dev =3D ctx; + struct rkcif_device *rkcif =3D dev_get_drvdata(dev); + struct rkcif_stream *stream; + u32 intstat, lastline, lastpix, cif_frmst; + irqreturn_t ret =3D IRQ_NONE; + + if (!rkcif->match_data->dvp) + return ret; + + intstat =3D rkcif_dvp_read(rkcif, RKCIF_DVP_INTSTAT); + cif_frmst =3D rkcif_dvp_read(rkcif, RKCIF_DVP_FRAME_STATUS); + lastline =3D RKCIF_FETCH_Y(rkcif_dvp_read(rkcif, RKCIF_DVP_LAST_LINE)); + lastpix =3D RKCIF_FETCH_Y(rkcif_dvp_read(rkcif, RKCIF_DVP_LAST_PIX)); + + if (intstat & RKCIF_INTSTAT_FRAME_END) { + rkcif_dvp_write(rkcif, RKCIF_DVP_INTSTAT, + RKCIF_INTSTAT_FRAME_END_CLR | + RKCIF_INTSTAT_LINE_END_CLR); + + stream =3D &rkcif->interfaces[RKCIF_DVP].streams[RKCIF_ID0]; + + if (stream->stopping) { + rkcif_dvp_stop_streaming(stream); + wake_up(&stream->wq_stopped); + ret =3D IRQ_HANDLED; + goto out; + } + + if (lastline !=3D stream->pix.height) { + v4l2_err(&rkcif->v4l2_dev, + "bad frame, irq:%#x frmst:%#x size:%dx%d\n", + intstat, cif_frmst, lastpix, lastline); + + rkcif_dvp_reset_stream(rkcif); + } + + rkcif_stream_pingpong(stream); + + ret =3D IRQ_HANDLED; + } +out: + return ret; +} + +int rkcif_dvp_register(struct rkcif_device *rkcif) +{ + struct rkcif_interface *interface; + unsigned int streams_num; + int ret; + + if (!rkcif->match_data->dvp) + return 0; + + interface =3D &rkcif->interfaces[RKCIF_DVP]; + interface->index =3D RKCIF_DVP; + interface->type =3D RKCIF_IF_DVP; + interface->in_fmts =3D rkcif->match_data->dvp->in_fmts; + interface->in_fmts_num =3D rkcif->match_data->dvp->in_fmts_num; + interface->set_crop =3D rkcif_dvp_set_crop; + ret =3D rkcif_interface_register(rkcif, interface); + if (ret) + return ret; + + if (rkcif->match_data->dvp->setup) + rkcif->match_data->dvp->setup(rkcif); + + streams_num =3D rkcif->match_data->dvp->has_ids ? 4 : 1; + for (unsigned int i =3D 0; i < streams_num; i++) { + struct rkcif_stream *stream =3D &interface->streams[i]; + + stream->id =3D i; + stream->interface =3D interface; + stream->out_fmts =3D rkcif->match_data->dvp->out_fmts; + stream->out_fmts_num =3D rkcif->match_data->dvp->out_fmts_num; + stream->queue_buffer =3D rkcif_dvp_queue_buffer; + stream->start_streaming =3D rkcif_dvp_start_streaming; + stream->stop_streaming =3D rkcif_dvp_stop_streaming; + + ret =3D rkcif_stream_register(rkcif, stream); + if (ret) + goto err_streams_unregister; + + interface->streams_num++; + } + + return 0; + +err_streams_unregister: + for (unsigned int i =3D 0; i < interface->streams_num; i++) + rkcif_stream_unregister(&interface->streams[i]); + + rkcif_interface_unregister(interface); + + return ret; +} + +void rkcif_dvp_unregister(struct rkcif_device *rkcif) +{ + struct rkcif_interface *interface; + + if (!rkcif->match_data->dvp) + return; + + interface =3D &rkcif->interfaces[RKCIF_DVP]; + + for (unsigned int i =3D 0; i < interface->streams_num; i++) + rkcif_stream_unregister(&interface->streams[i]); + + rkcif_interface_unregister(interface); +} diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-capture-dvp.h b/dr= ivers/media/platform/rockchip/rkcif/rkcif-capture-dvp.h new file mode 100644 index 000000000000..7b2da11497c3 --- /dev/null +++ b/drivers/media/platform/rockchip/rkcif/rkcif-capture-dvp.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Rockchip Camera Interface (CIF) Driver + * + * Copyright (C) 2018 Rockchip Electronics Co., Ltd. + * Copyright (C) 2023 Mehdi Djait + * Copyright (C) 2025 Michael Riesch + * Copyright (C) 2025 Collabora, Ltd. + */ + +#ifndef _RKCIF_CAPTURE_DVP_H +#define _RKCIF_CAPTURE_DVP_H + +#include "rkcif-common.h" + +extern const struct rkcif_dvp_match_data rkcif_px30_vip_dvp_match_data; + +int rkcif_dvp_register(struct rkcif_device *rkcif); + +void rkcif_dvp_unregister(struct rkcif_device *rkcif); + +irqreturn_t rkcif_dvp_isr(int irq, void *ctx); + +#endif diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-common.h b/drivers= /media/platform/rockchip/rkcif/rkcif-common.h index 63d5b45c7afe..c6ec578e1049 100644 --- a/drivers/media/platform/rockchip/rkcif/rkcif-common.h +++ b/drivers/media/platform/rockchip/rkcif/rkcif-common.h @@ -24,6 +24,8 @@ #include #include =20 +#include "rkcif-regs.h" + #define RKCIF_DRIVER_NAME "rockchip-cif" #define RKCIF_CLK_MAX 4 =20 @@ -84,17 +86,31 @@ struct rkcif_dummy_buffer { u32 size; }; =20 +enum rkcif_plane_index { + RKCIF_PLANE_Y, + RKCIF_PLANE_UV, + RKCIF_PLANE_MAX +}; + struct rkcif_input_fmt { u32 mbus_code; =20 enum rkcif_format_type fmt_type; enum v4l2_field field; + + union { + u32 dvp_fmt_val; + }; }; =20 struct rkcif_output_fmt { u32 fourcc; u32 mbus_code; u8 cplanes; + + union { + u32 dvp_fmt_val; + }; }; =20 struct rkcif_interface; @@ -168,9 +184,21 @@ struct rkcif_interface { void (*set_crop)(struct rkcif_stream *stream, u16 left, u16 top); }; =20 +struct rkcif_dvp_match_data { + const struct rkcif_input_fmt *in_fmts; + unsigned int in_fmts_num; + const struct rkcif_output_fmt *out_fmts; + unsigned int out_fmts_num; + void (*setup)(struct rkcif_device *rkcif); + bool has_scaler; + bool has_ids; + unsigned int regs[RKCIF_DVP_REGISTER_MAX]; +}; + struct rkcif_match_data { const char *const *clks; unsigned int clks_num; + const struct rkcif_dvp_match_data *dvp; }; =20 struct rkcif_device { diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-dev.c b/drivers/me= dia/platform/rockchip/rkcif/rkcif-dev.c index 49e53f70715c..207802073fd3 100644 --- a/drivers/media/platform/rockchip/rkcif/rkcif-dev.c +++ b/drivers/media/platform/rockchip/rkcif/rkcif-dev.c @@ -23,6 +23,7 @@ #include #include =20 +#include "rkcif-capture-dvp.h" #include "rkcif-common.h" =20 static const char *const px30_vip_clks[] =3D { @@ -34,6 +35,7 @@ static const char *const px30_vip_clks[] =3D { static const struct rkcif_match_data px30_vip_match_data =3D { .clks =3D px30_vip_clks, .clks_num =3D ARRAY_SIZE(px30_vip_clks), + .dvp =3D &rkcif_px30_vip_dvp_match_data, }; =20 static const char *const rk3568_vicap_clks[] =3D { @@ -63,11 +65,21 @@ MODULE_DEVICE_TABLE(of, rkcif_plat_of_match); =20 static int rkcif_register(struct rkcif_device *rkcif) { + int ret; + + ret =3D rkcif_dvp_register(rkcif); + if (ret && ret !=3D -ENODEV) + goto err; + return 0; + +err: + return ret; } =20 static void rkcif_unregister(struct rkcif_device *rkcif) { + rkcif_dvp_unregister(rkcif); } =20 static int rkcif_notifier_bound(struct v4l2_async_notifier *notifier, @@ -112,6 +124,9 @@ static irqreturn_t rkcif_isr(int irq, void *ctx) { irqreturn_t ret =3D IRQ_NONE; =20 + if (rkcif_dvp_isr(irq, ctx) =3D=3D IRQ_HANDLED) + ret =3D IRQ_HANDLED; + return ret; } =20 diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-regs.h b/drivers/m= edia/platform/rockchip/rkcif/rkcif-regs.h new file mode 100644 index 000000000000..91d42d31fd10 --- /dev/null +++ b/drivers/media/platform/rockchip/rkcif/rkcif-regs.h @@ -0,0 +1,131 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Rockchip Camera Interface (CIF) Driver + * + * Copyright (C) 2018 Rockchip Electronics Co., Ltd. + * Copyright (C) 2023 Mehdi Djait + * Copyright (C) 2025 Michael Riesch + */ + +#ifndef _RKCIF_REGS_H +#define _RKCIF_REGS_H + +#define RKCIF_REGISTER_NOTSUPPORTED 0x420000 +#define RKCIF_FETCH_Y(VAL) ((VAL) & 0x1fff) +#define RKCIF_XY_COORD(x, y) (((y) << 16) | (x)) + +/* DVP register contents */ +#define RKCIF_CTRL_ENABLE_CAPTURE BIT(0) +#define RKCIF_CTRL_MODE_PINGPONG BIT(1) +#define RKCIF_CTRL_MODE_LINELOOP BIT(2) +#define RKCIF_CTRL_AXI_BURST_16 (0xf << 12) + +#define RKCIF_INTEN_FRAME_END_EN BIT(0) +#define RKCIF_INTEN_LINE_ERR_EN BIT(2) +#define RKCIF_INTEN_BUS_ERR_EN BIT(6) +#define RKCIF_INTEN_SCL_ERR_EN BIT(7) +#define RKCIF_INTEN_PST_INF_FRAME_END_EN BIT(9) + +#define RKCIF_INTSTAT_CLS 0x3ff +#define RKCIF_INTSTAT_FRAME_END BIT(0) +#define RKCIF_INTSTAT_LINE_END BIT(1) +#define RKCIF_INTSTAT_LINE_ERR BIT(2) +#define RKCIF_INTSTAT_PIX_ERR BIT(3) +#define RKCIF_INTSTAT_DFIFO_OF BIT(5) +#define RKCIF_INTSTAT_BUS_ERR BIT(6) +#define RKCIF_INTSTAT_PRE_INF_FRAME_END BIT(8) +#define RKCIF_INTSTAT_PST_INF_FRAME_END BIT(9) +#define RKCIF_INTSTAT_FRAME_END_CLR BIT(0) +#define RKCIF_INTSTAT_LINE_END_CLR BIT(1) +#define RKCIF_INTSTAT_LINE_ERR_CLR BIT(2) +#define RKCIF_INTSTAT_PST_INF_FRAME_END_CLR BIT(9) +#define RKCIF_INTSTAT_ERR 0xfc + +#define RKCIF_FRAME_STAT_CLS 0x00 +#define RKCIF_FRAME_FRM0_STAT_CLS 0x20 + +#define RKCIF_FORMAT_VSY_HIGH_ACTIVE BIT(0) +#define RKCIF_FORMAT_HSY_LOW_ACTIVE BIT(1) + +#define RKCIF_FORMAT_INPUT_MODE_YUV (0x00 << 2) +#define RKCIF_FORMAT_INPUT_MODE_PAL (0x02 << 2) +#define RKCIF_FORMAT_INPUT_MODE_NTSC (0x03 << 2) +#define RKCIF_FORMAT_INPUT_MODE_BT1120 (0x07 << 2) +#define RKCIF_FORMAT_INPUT_MODE_RAW (0x04 << 2) +#define RKCIF_FORMAT_INPUT_MODE_JPEG (0x05 << 2) +#define RKCIF_FORMAT_INPUT_MODE_MIPI (0x06 << 2) + +#define RKCIF_FORMAT_YUV_INPUT_ORDER_UYVY (0x00 << 5) +#define RKCIF_FORMAT_YUV_INPUT_ORDER_YVYU (0x01 << 5) +#define RKCIF_FORMAT_YUV_INPUT_ORDER_VYUY (0x02 << 5) +#define RKCIF_FORMAT_YUV_INPUT_ORDER_YUYV (0x03 << 5) +#define RKCIF_FORMAT_YUV_INPUT_422 (0x00 << 7) +#define RKCIF_FORMAT_YUV_INPUT_420 BIT(7) + +#define RKCIF_FORMAT_INPUT_420_ORDER_ODD BIT(8) + +#define RKCIF_FORMAT_CCIR_INPUT_ORDER_EVEN BIT(9) + +#define RKCIF_FORMAT_RAW_DATA_WIDTH_8 (0x00 << 11) +#define RKCIF_FORMAT_RAW_DATA_WIDTH_10 (0x01 << 11) +#define RKCIF_FORMAT_RAW_DATA_WIDTH_12 (0x02 << 11) + +#define RKCIF_FORMAT_YUV_OUTPUT_422 (0x00 << 16) +#define RKCIF_FORMAT_YUV_OUTPUT_420 BIT(16) + +#define RKCIF_FORMAT_OUTPUT_420_ORDER_EVEN (0x00 << 17) +#define RKCIF_FORMAT_OUTPUT_420_ORDER_ODD BIT(17) + +#define RKCIF_FORMAT_RAWD_DATA_LITTLE_ENDIAN (0x00 << 18) +#define RKCIF_FORMAT_RAWD_DATA_BIG_ENDIAN BIT(18) + +#define RKCIF_FORMAT_UV_STORAGE_ORDER_UVUV (0x00 << 19) +#define RKCIF_FORMAT_UV_STORAGE_ORDER_VUVU BIT(19) + +#define RKCIF_FORMAT_BT1120_CLOCK_SINGLE_EDGES (0x00 << 24) +#define RKCIF_FORMAT_BT1120_CLOCK_DOUBLE_EDGES BIT(24) +#define RKCIF_FORMAT_BT1120_TRANSMIT_INTERFACE (0x00 << 25) +#define RKCIF_FORMAT_BT1120_TRANSMIT_PROGRESS BIT(25) +#define RKCIF_FORMAT_BT1120_YC_SWAP BIT(26) + +#define RKCIF_SCL_CTRL_ENABLE_SCL_DOWN BIT(0) +#define RKCIF_SCL_CTRL_ENABLE_SCL_UP BIT(1) +#define RKCIF_SCL_CTRL_ENABLE_YUV_16BIT_BYPASS BIT(4) +#define RKCIF_SCL_CTRL_ENABLE_RAW_16BIT_BYPASS BIT(5) +#define RKCIF_SCL_CTRL_ENABLE_32BIT_BYPASS BIT(6) +#define RKCIF_SCL_CTRL_DISABLE_32BIT_BYPASS (0x00 << 6) + +#define RKCIF_INTSTAT_F0_READY BIT(0) +#define RKCIF_INTSTAT_F1_READY BIT(1) + +/* GRF register offsets and contents */ +#define RK3568_GRF_VI_CON0 0x340 +#define RK3568_GRF_VI_CON1 0x344 +#define RK3568_GRF_VI_STATUS0 0x348 + +#define RK3568_GRF_VI_CON1_CIF_DATAPATH BIT(9) +#define RK3568_GRF_VI_CON1_CIF_CLK_DELAYNUM GENMASK(6, 0) + +#define RK3568_GRF_WRITE_ENABLE(x) ((x) << 16) + +enum rkcif_dvp_register_index { + RKCIF_DVP_CTRL, + RKCIF_DVP_INTEN, + RKCIF_DVP_INTSTAT, + RKCIF_DVP_FOR, + RKCIF_DVP_LINE_NUM_ADDR, + RKCIF_DVP_FRM0_ADDR_Y, + RKCIF_DVP_FRM0_ADDR_UV, + RKCIF_DVP_FRM1_ADDR_Y, + RKCIF_DVP_FRM1_ADDR_UV, + RKCIF_DVP_VIR_LINE_WIDTH, + RKCIF_DVP_SET_SIZE, + RKCIF_DVP_SCL_CTRL, + RKCIF_DVP_CROP, + RKCIF_DVP_FRAME_STATUS, + RKCIF_DVP_LAST_LINE, + RKCIF_DVP_LAST_PIX, + RKCIF_DVP_REGISTER_MAX +}; + +#endif --=20 2.39.5 From nobody Mon Dec 15 21:31:27 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 CA0E234027D; Fri, 14 Nov 2025 15:20:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763133620; cv=none; b=tr/X3wsEU8B0tfaMHXv4LTOl/KLg8QYJt0DTRiAcP/7qnkYe68pfDYnvnfyno6vvFCSdrdEMUXQkMOl59zJw/FvI7RUPLRBF59VVDpreJ8R6B1PKEXB+xa8SXmm9ZNjAkolnEZFlgdpxC73dYVeYgA38tQDT3JjI+wKb4vlB+nw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763133620; c=relaxed/simple; bh=EegfNTCZJhyP93HUaasjodtMI5xO9jzjfI3ApbhM3Do=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=CDecpS0phZmC6dA5RgfwNY7Rn3ZnRBHSmK4fsl0M3+vdLx3xIkrQpCU/ubOQFc6RmU+QQ26C1R95UrT6EMMu2XScHj66XFQQe6+dNYKQpA0hZJNUXPmY5zveQ0yGK2RUs418a9CadNAuvm3ok1sOpeZFEv2GS9qjTxheqD2cx6w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=OAAS4H4A; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="OAAS4H4A" Received: by smtp.kernel.org (Postfix) with ESMTPS id 95F24C19421; Fri, 14 Nov 2025 15:20:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1763133620; bh=EegfNTCZJhyP93HUaasjodtMI5xO9jzjfI3ApbhM3Do=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=OAAS4H4A9ESW21dxqt4lPtrOFHcmD9M7yh6E0P+7E27C4iAs89+52K25rLtFCh1Bv ciCA9eZ3WmvFEKekuMJyTBDM/rTm5QCRkASHXvQpU+ly6MhwRRPpgF+qeAmawoKvEL DIRhIs6299TyLMOjGHfNWBuJAVI2suZioZ+/5sz8HHjopnYsW4phxXiTg3us+PM52G 1B4cyYKaFKZw3my75HeizdS8h3l4thpt/d469f5jcf6JatP+HaFqfegklIIk5vR6/R pBIkntbI3KxHf7l+dcQdE41qn/xnQimGVgmjqHzrbeNRcYAnVT03G9JLEKJdwm2qhq XyTdqQ87ddgwQ== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8C221CE7B13; Fri, 14 Nov 2025 15:20:20 +0000 (UTC) From: Michael Riesch via B4 Relay Date: Fri, 14 Nov 2025 16:20:20 +0100 Subject: [PATCH v15 09/14] media: rockchip: rkcif: add support for rk3568 vicap dvp capture 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: <20240220-rk3568-vicap-v15-9-8f4915ee365d@collabora.com> References: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com> In-Reply-To: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com> To: Mehdi Djait , Maxime Chevallier , =?utf-8?q?Th=C3=A9o_Lebrun?= , Thomas Petazzoni , Gerald Loacker , Bryan O'Donoghue , Markus Elfring , Laurent Pinchart , Mauro Carvalho Chehab , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Heiko Stuebner , Kever Yang , Nicolas Dufresne , Sebastian Reichel , Collabora Kernel Team , Paul Kocialkowski , Alexander Shiyan , Val Packett , Rob Herring , Philipp Zabel , Sakari Ailus Cc: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, Michael Riesch , Michael Riesch X-Mailer: b4 0.12.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1763133617; l=10988; i=michael.riesch@collabora.com; s=20250410; h=from:subject:message-id; bh=zEP2Gc8wNycuvK3ypNJTSWlr0jpeC2f0fRQdULd72Ns=; b=K1inEkGJdPisVCfa9kAZacBCKJ+3qbWgshO32wiceNeMeKtP9xoiOp2oC337o4B+7XKGvXsON /iAfxNLpSn6AYfvOvZbTZfBuLIsz2+t2FLAHqBmq/hCHZdhCkuqJfmv X-Developer-Key: i=michael.riesch@collabora.com; a=ed25519; pk=+MWX1fffLFZtTPG/I6XdYm/+OSvpRE8D9evQaWbiN04= X-Endpoint-Received: by B4 Relay for michael.riesch@collabora.com/20250410 with auth_id=371 X-Original-From: Michael Riesch Reply-To: michael.riesch@collabora.com From: Michael Riesch The RK3568 Video Capture (VICAP) unit features a Digital Video Port (DVP). Add support for it. Tested-by: Gerald Loacker Reviewed-by: Gerald Loacker Reviewed-by: Bryan O'Donoghue Reviewed-by: Mehdi Djait Signed-off-by: Michael Riesch --- .../platform/rockchip/rkcif/rkcif-capture-dvp.c | 276 +++++++++++++++++= ++++ .../platform/rockchip/rkcif/rkcif-capture-dvp.h | 1 + drivers/media/platform/rockchip/rkcif/rkcif-dev.c | 1 + 3 files changed, 278 insertions(+) diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-capture-dvp.c b/dr= ivers/media/platform/rockchip/rkcif/rkcif-capture-dvp.c index b40135035ab8..dbaf7636aeeb 100644 --- a/drivers/media/platform/rockchip/rkcif/rkcif-capture-dvp.c +++ b/drivers/media/platform/rockchip/rkcif/rkcif-capture-dvp.c @@ -332,6 +332,282 @@ const struct rkcif_dvp_match_data rkcif_px30_vip_dvp_= match_data =3D { }, }; =20 +static const struct rkcif_input_fmt rk3568_dvp_in_fmts[] =3D { + { + .mbus_code =3D MEDIA_BUS_FMT_YUYV8_2X8, + .dvp_fmt_val =3D RKCIF_FORMAT_YUV_INPUT_422 | + RKCIF_FORMAT_YUV_INPUT_ORDER_YUYV, + .fmt_type =3D RKCIF_FMT_TYPE_YUV, + .field =3D V4L2_FIELD_NONE, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_YUYV8_2X8, + .dvp_fmt_val =3D RKCIF_FORMAT_YUV_INPUT_422 | + RKCIF_FORMAT_YUV_INPUT_ORDER_YUYV, + .fmt_type =3D RKCIF_FMT_TYPE_YUV, + .field =3D V4L2_FIELD_INTERLACED, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_YVYU8_2X8, + .dvp_fmt_val =3D RKCIF_FORMAT_YUV_INPUT_422 | + RKCIF_FORMAT_YUV_INPUT_ORDER_YVYU, + .fmt_type =3D RKCIF_FMT_TYPE_YUV, + .field =3D V4L2_FIELD_NONE, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_YVYU8_2X8, + .dvp_fmt_val =3D RKCIF_FORMAT_YUV_INPUT_422 | + RKCIF_FORMAT_YUV_INPUT_ORDER_YVYU, + .fmt_type =3D RKCIF_FMT_TYPE_YUV, + .field =3D V4L2_FIELD_INTERLACED, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_UYVY8_2X8, + .dvp_fmt_val =3D RKCIF_FORMAT_YUV_INPUT_422 | + RKCIF_FORMAT_YUV_INPUT_ORDER_UYVY, + .fmt_type =3D RKCIF_FMT_TYPE_YUV, + .field =3D V4L2_FIELD_NONE, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_UYVY8_2X8, + .dvp_fmt_val =3D RKCIF_FORMAT_YUV_INPUT_422 | + RKCIF_FORMAT_YUV_INPUT_ORDER_UYVY, + .fmt_type =3D RKCIF_FMT_TYPE_YUV, + .field =3D V4L2_FIELD_INTERLACED, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_VYUY8_2X8, + .dvp_fmt_val =3D RKCIF_FORMAT_YUV_INPUT_422 | + RKCIF_FORMAT_YUV_INPUT_ORDER_VYUY, + .fmt_type =3D RKCIF_FMT_TYPE_YUV, + .field =3D V4L2_FIELD_NONE, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_VYUY8_2X8, + .dvp_fmt_val =3D RKCIF_FORMAT_YUV_INPUT_422 | + RKCIF_FORMAT_YUV_INPUT_ORDER_VYUY, + .fmt_type =3D RKCIF_FMT_TYPE_YUV, + .field =3D V4L2_FIELD_INTERLACED, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_YUYV8_1X16, + .dvp_fmt_val =3D RKCIF_FORMAT_YUV_INPUT_422 | + RKCIF_FORMAT_YUV_INPUT_ORDER_YUYV | + RKCIF_FORMAT_INPUT_MODE_BT1120 | + RKCIF_FORMAT_BT1120_TRANSMIT_PROGRESS, + .field =3D V4L2_FIELD_NONE, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_YUYV8_1X16, + .dvp_fmt_val =3D RKCIF_FORMAT_YUV_INPUT_422 | + RKCIF_FORMAT_YUV_INPUT_ORDER_YUYV | + RKCIF_FORMAT_INPUT_MODE_BT1120, + .field =3D V4L2_FIELD_INTERLACED, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_YVYU8_1X16, + .dvp_fmt_val =3D RKCIF_FORMAT_YUV_INPUT_422 | + RKCIF_FORMAT_YUV_INPUT_ORDER_YVYU | + RKCIF_FORMAT_INPUT_MODE_BT1120 | + RKCIF_FORMAT_BT1120_TRANSMIT_PROGRESS, + .field =3D V4L2_FIELD_NONE, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_YVYU8_1X16, + .dvp_fmt_val =3D RKCIF_FORMAT_YUV_INPUT_422 | + RKCIF_FORMAT_YUV_INPUT_ORDER_YVYU | + RKCIF_FORMAT_INPUT_MODE_BT1120, + .field =3D V4L2_FIELD_INTERLACED, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_UYVY8_1X16, + .dvp_fmt_val =3D RKCIF_FORMAT_YUV_INPUT_422 | + RKCIF_FORMAT_YUV_INPUT_ORDER_YUYV | + RKCIF_FORMAT_INPUT_MODE_BT1120 | + RKCIF_FORMAT_BT1120_YC_SWAP | + RKCIF_FORMAT_BT1120_TRANSMIT_PROGRESS, + .field =3D V4L2_FIELD_NONE, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_UYVY8_1X16, + .dvp_fmt_val =3D RKCIF_FORMAT_YUV_INPUT_422 | + RKCIF_FORMAT_YUV_INPUT_ORDER_YUYV | + RKCIF_FORMAT_BT1120_YC_SWAP | + RKCIF_FORMAT_INPUT_MODE_BT1120, + .field =3D V4L2_FIELD_INTERLACED, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_VYUY8_1X16, + .dvp_fmt_val =3D RKCIF_FORMAT_YUV_INPUT_422 | + RKCIF_FORMAT_YUV_INPUT_ORDER_YVYU | + RKCIF_FORMAT_INPUT_MODE_BT1120 | + RKCIF_FORMAT_BT1120_YC_SWAP | + RKCIF_FORMAT_BT1120_TRANSMIT_PROGRESS, + .field =3D V4L2_FIELD_NONE, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_VYUY8_1X16, + .dvp_fmt_val =3D RKCIF_FORMAT_YUV_INPUT_422 | + RKCIF_FORMAT_YUV_INPUT_ORDER_YVYU | + RKCIF_FORMAT_BT1120_YC_SWAP | + RKCIF_FORMAT_INPUT_MODE_BT1120, + .field =3D V4L2_FIELD_INTERLACED, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_SBGGR8_1X8, + .dvp_fmt_val =3D RKCIF_FORMAT_INPUT_MODE_RAW | + RKCIF_FORMAT_RAW_DATA_WIDTH_8, + .fmt_type =3D RKCIF_FMT_TYPE_RAW, + .field =3D V4L2_FIELD_NONE, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_SGBRG8_1X8, + .dvp_fmt_val =3D RKCIF_FORMAT_INPUT_MODE_RAW | + RKCIF_FORMAT_RAW_DATA_WIDTH_8, + .fmt_type =3D RKCIF_FMT_TYPE_RAW, + .field =3D V4L2_FIELD_NONE, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_SGRBG8_1X8, + .dvp_fmt_val =3D RKCIF_FORMAT_INPUT_MODE_RAW | + RKCIF_FORMAT_RAW_DATA_WIDTH_8, + .fmt_type =3D RKCIF_FMT_TYPE_RAW, + .field =3D V4L2_FIELD_NONE, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_SRGGB8_1X8, + .dvp_fmt_val =3D RKCIF_FORMAT_INPUT_MODE_RAW | + RKCIF_FORMAT_RAW_DATA_WIDTH_8, + .fmt_type =3D RKCIF_FMT_TYPE_RAW, + .field =3D V4L2_FIELD_NONE, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_SBGGR10_1X10, + .dvp_fmt_val =3D RKCIF_FORMAT_INPUT_MODE_RAW | + RKCIF_FORMAT_RAW_DATA_WIDTH_10, + .fmt_type =3D RKCIF_FMT_TYPE_RAW, + .field =3D V4L2_FIELD_NONE, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_SGBRG10_1X10, + .dvp_fmt_val =3D RKCIF_FORMAT_INPUT_MODE_RAW | + RKCIF_FORMAT_RAW_DATA_WIDTH_10, + .fmt_type =3D RKCIF_FMT_TYPE_RAW, + .field =3D V4L2_FIELD_NONE, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_SGRBG10_1X10, + .dvp_fmt_val =3D RKCIF_FORMAT_INPUT_MODE_RAW | + RKCIF_FORMAT_RAW_DATA_WIDTH_10, + .fmt_type =3D RKCIF_FMT_TYPE_RAW, + .field =3D V4L2_FIELD_NONE, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_SRGGB10_1X10, + .dvp_fmt_val =3D RKCIF_FORMAT_INPUT_MODE_RAW | + RKCIF_FORMAT_RAW_DATA_WIDTH_10, + .fmt_type =3D RKCIF_FMT_TYPE_RAW, + .field =3D V4L2_FIELD_NONE, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_SBGGR12_1X12, + .dvp_fmt_val =3D RKCIF_FORMAT_INPUT_MODE_RAW | + RKCIF_FORMAT_RAW_DATA_WIDTH_12, + .fmt_type =3D RKCIF_FMT_TYPE_RAW, + .field =3D V4L2_FIELD_NONE, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_SGBRG12_1X12, + .dvp_fmt_val =3D RKCIF_FORMAT_INPUT_MODE_RAW | + RKCIF_FORMAT_RAW_DATA_WIDTH_12, + .fmt_type =3D RKCIF_FMT_TYPE_RAW, + .field =3D V4L2_FIELD_NONE, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_SGRBG12_1X12, + .dvp_fmt_val =3D RKCIF_FORMAT_INPUT_MODE_RAW | + RKCIF_FORMAT_RAW_DATA_WIDTH_12, + .fmt_type =3D RKCIF_FMT_TYPE_RAW, + .field =3D V4L2_FIELD_NONE, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_SRGGB12_1X12, + .dvp_fmt_val =3D RKCIF_FORMAT_INPUT_MODE_RAW | + RKCIF_FORMAT_RAW_DATA_WIDTH_12, + .fmt_type =3D RKCIF_FMT_TYPE_RAW, + .field =3D V4L2_FIELD_NONE, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_RGB888_1X24, + .field =3D V4L2_FIELD_NONE, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_Y8_1X8, + .dvp_fmt_val =3D RKCIF_FORMAT_INPUT_MODE_RAW | + RKCIF_FORMAT_RAW_DATA_WIDTH_8, + .fmt_type =3D RKCIF_FMT_TYPE_RAW, + .field =3D V4L2_FIELD_NONE, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_Y10_1X10, + .dvp_fmt_val =3D RKCIF_FORMAT_INPUT_MODE_RAW | + RKCIF_FORMAT_RAW_DATA_WIDTH_10, + .fmt_type =3D RKCIF_FMT_TYPE_RAW, + .field =3D V4L2_FIELD_NONE, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_Y12_1X12, + .dvp_fmt_val =3D RKCIF_FORMAT_INPUT_MODE_RAW | + RKCIF_FORMAT_RAW_DATA_WIDTH_12, + .fmt_type =3D RKCIF_FMT_TYPE_RAW, + .field =3D V4L2_FIELD_NONE, + }, +}; + +static void rk3568_dvp_grf_setup(struct rkcif_device *rkcif) +{ + u32 con1 =3D RK3568_GRF_WRITE_ENABLE(RK3568_GRF_VI_CON1_CIF_DATAPATH | + RK3568_GRF_VI_CON1_CIF_CLK_DELAYNUM); + + if (!rkcif->grf) + return; + + con1 |=3D rkcif->interfaces[RKCIF_DVP].dvp.dvp_clk_delay & + RK3568_GRF_VI_CON1_CIF_CLK_DELAYNUM; + + if (rkcif->interfaces[RKCIF_DVP].vep.bus.parallel.flags & + V4L2_MBUS_PCLK_SAMPLE_DUALEDGE) + con1 |=3D RK3568_GRF_VI_CON1_CIF_DATAPATH; + + regmap_write(rkcif->grf, RK3568_GRF_VI_CON1, con1); +} + +const struct rkcif_dvp_match_data rkcif_rk3568_vicap_dvp_match_data =3D { + .in_fmts =3D rk3568_dvp_in_fmts, + .in_fmts_num =3D ARRAY_SIZE(rk3568_dvp_in_fmts), + .out_fmts =3D dvp_out_fmts, + .out_fmts_num =3D ARRAY_SIZE(dvp_out_fmts), + .setup =3D rk3568_dvp_grf_setup, + .has_scaler =3D false, + .regs =3D { + [RKCIF_DVP_CTRL] =3D 0x00, + [RKCIF_DVP_INTEN] =3D 0x04, + [RKCIF_DVP_INTSTAT] =3D 0x08, + [RKCIF_DVP_FOR] =3D 0x0c, + [RKCIF_DVP_LINE_NUM_ADDR] =3D 0x2c, + [RKCIF_DVP_FRM0_ADDR_Y] =3D 0x14, + [RKCIF_DVP_FRM0_ADDR_UV] =3D 0x18, + [RKCIF_DVP_FRM1_ADDR_Y] =3D 0x1c, + [RKCIF_DVP_FRM1_ADDR_UV] =3D 0x20, + [RKCIF_DVP_VIR_LINE_WIDTH] =3D 0x24, + [RKCIF_DVP_SET_SIZE] =3D 0x28, + [RKCIF_DVP_CROP] =3D 0x34, + [RKCIF_DVP_FRAME_STATUS] =3D 0x3c, + [RKCIF_DVP_LAST_LINE] =3D 0x44, + [RKCIF_DVP_LAST_PIX] =3D 0x48, + }, +}; + static inline unsigned int rkcif_dvp_get_addr(struct rkcif_device *rkcif, unsigned int index) { diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-capture-dvp.h b/dr= ivers/media/platform/rockchip/rkcif/rkcif-capture-dvp.h index 7b2da11497c3..a4ed37833bd6 100644 --- a/drivers/media/platform/rockchip/rkcif/rkcif-capture-dvp.h +++ b/drivers/media/platform/rockchip/rkcif/rkcif-capture-dvp.h @@ -14,6 +14,7 @@ #include "rkcif-common.h" =20 extern const struct rkcif_dvp_match_data rkcif_px30_vip_dvp_match_data; +extern const struct rkcif_dvp_match_data rkcif_rk3568_vicap_dvp_match_data; =20 int rkcif_dvp_register(struct rkcif_device *rkcif); =20 diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-dev.c b/drivers/me= dia/platform/rockchip/rkcif/rkcif-dev.c index 207802073fd3..addc118ff8bf 100644 --- a/drivers/media/platform/rockchip/rkcif/rkcif-dev.c +++ b/drivers/media/platform/rockchip/rkcif/rkcif-dev.c @@ -48,6 +48,7 @@ static const char *const rk3568_vicap_clks[] =3D { static const struct rkcif_match_data rk3568_vicap_match_data =3D { .clks =3D rk3568_vicap_clks, .clks_num =3D ARRAY_SIZE(rk3568_vicap_clks), + .dvp =3D &rkcif_rk3568_vicap_dvp_match_data, }; =20 static const struct of_device_id rkcif_plat_of_match[] =3D { --=20 2.39.5 From nobody Mon Dec 15 21:31:27 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 D8D9C34029C; Fri, 14 Nov 2025 15:20:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763133621; cv=none; b=jreu8TuMvIxFJt62184wHXyk3Ozq+kdylgEEVzeKYoQW5ZYZLNypTmN0aEIhBOU1bKbRbYp1Eghsn7JZqSr/mkNLb1nTB728dRaxyRJNRkWycHFacdA/OkQ6PgnXlZPlQMhrPgvSng8spVLj6bKerjI0qFGIqZ944kEbTaPXUM8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763133621; c=relaxed/simple; bh=uI2gmuk6W6jKS5lvrE6qYjVwf9T0D5Cwegzz088e3Fs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=WlRhAIxHS8C0U4s+dgTqcFcdeeKbkXHI8i94YG2G4mvxSY6+jx3fvAl4RdXfoVr2z+jU3kK5RCyvUCfLsKO7hHVTDinGuvg4+YUQOjclDWeFrvYVJdajNhryfht2HbHCclpJPCfJUYMf3e3fx3eiT0MjuPfVKAHPj0b5allK5Dg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=nFvTACBG; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="nFvTACBG" Received: by smtp.kernel.org (Postfix) with ESMTPS id ABD63C4CEF8; Fri, 14 Nov 2025 15:20:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1763133620; bh=uI2gmuk6W6jKS5lvrE6qYjVwf9T0D5Cwegzz088e3Fs=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=nFvTACBGuIIt6LbXnadIqjxufFd4vJSwL4BRbNyydkBCehpvTDbjH32ONj1tuD2yg n1BSIfhA5ppbTEkzRZjNngSotsK3ngg/VB7jQ5SPFMUwpV/ltUc9pxLpyn2BkwXsnN 7DnB+IjcMck1QjN94P0COnuJxO+WRzyeKjR18zSomdft+cjPoCiGPorDhkYA1P4DCr esDlaB7nCbNKBFstEcseSkYNXxfW/Zlsx3I1XuuQ79ozoxP7VMUzAxd1vAsb3I4tYL XEhyYuHZJ1s30qE5D1EsHNiiH6T6zRfavBoneX3WU5UQ4PFx0GESk1DpYT3I1Uk+B3 r/wxVNabYxDdQ== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9E3BBCE7B1E; Fri, 14 Nov 2025 15:20:20 +0000 (UTC) From: Michael Riesch via B4 Relay Date: Fri, 14 Nov 2025 16:20:21 +0100 Subject: [PATCH v15 10/14] media: rockchip: rkcif: add support for rk3568 vicap mipi capture 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: <20240220-rk3568-vicap-v15-10-8f4915ee365d@collabora.com> References: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com> In-Reply-To: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com> To: Mehdi Djait , Maxime Chevallier , =?utf-8?q?Th=C3=A9o_Lebrun?= , Thomas Petazzoni , Gerald Loacker , Bryan O'Donoghue , Markus Elfring , Laurent Pinchart , Mauro Carvalho Chehab , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Heiko Stuebner , Kever Yang , Nicolas Dufresne , Sebastian Reichel , Collabora Kernel Team , Paul Kocialkowski , Alexander Shiyan , Val Packett , Rob Herring , Philipp Zabel , Sakari Ailus Cc: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, Michael Riesch , Michael Riesch X-Mailer: b4 0.12.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1763133617; l=27198; i=michael.riesch@collabora.com; s=20250410; h=from:subject:message-id; bh=V/SSFlqvsbMLOMKOYqjTmzEpKtCu2afX7wqm/Jhnx5Q=; b=MlXsSkuCk/263/z2OWV1KsA5tgsOPc179gSXSZ8h4E2uPh9uUjXG33qYBaEBlpUMupf3axuiQ ZLXBgGyYvFhB7bg80h0mIFEgyL5FNA34fPX3bdHUnUmnU0e5SeB+J8e X-Developer-Key: i=michael.riesch@collabora.com; a=ed25519; pk=+MWX1fffLFZtTPG/I6XdYm/+OSvpRE8D9evQaWbiN04= X-Endpoint-Received: by B4 Relay for michael.riesch@collabora.com/20250410 with auth_id=371 X-Original-From: Michael Riesch Reply-To: michael.riesch@collabora.com From: Michael Riesch The RK3568 Video Capture (VICAP) unit features a MIPI CSI-2 capture interface. Add support for the MIPI capture interface in general and for the RK3568 VICAP MIPI capture in particular. Signed-off-by: Michael Riesch Reviewed-by: Bryan O'Donoghue Reviewed-by: Mehdi Djait Signed-off-by: Michael Riesch --- drivers/media/platform/rockchip/rkcif/Makefile | 1 + .../platform/rockchip/rkcif/rkcif-capture-mipi.c | 777 +++++++++++++++++= ++++ .../platform/rockchip/rkcif/rkcif-capture-mipi.h | 23 + .../media/platform/rockchip/rkcif/rkcif-common.h | 29 + drivers/media/platform/rockchip/rkcif/rkcif-dev.c | 12 + drivers/media/platform/rockchip/rkcif/rkcif-regs.h | 22 + 6 files changed, 864 insertions(+) diff --git a/drivers/media/platform/rockchip/rkcif/Makefile b/drivers/media= /platform/rockchip/rkcif/Makefile index a36e294d569d..dca2bf45159f 100644 --- a/drivers/media/platform/rockchip/rkcif/Makefile +++ b/drivers/media/platform/rockchip/rkcif/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_VIDEO_ROCKCHIP_CIF) +=3D rockchip-cif.o =20 rockchip-cif-objs +=3D rkcif-capture-dvp.o +rockchip-cif-objs +=3D rkcif-capture-mipi.o rockchip-cif-objs +=3D rkcif-dev.o rockchip-cif-objs +=3D rkcif-interface.o rockchip-cif-objs +=3D rkcif-stream.o diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-capture-mipi.c b/d= rivers/media/platform/rockchip/rkcif/rkcif-capture-mipi.c new file mode 100644 index 000000000000..1b81bcc067ef --- /dev/null +++ b/drivers/media/platform/rockchip/rkcif/rkcif-capture-mipi.c @@ -0,0 +1,777 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Rockchip Camera Interface (CIF) Driver + * + * Copyright (C) 2018 Rockchip Electronics Co., Ltd. + * Copyright (C) 2025 Michael Riesch + * Copyright (C) 2025 Collabora, Ltd. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rkcif-capture-mipi.h" +#include "rkcif-common.h" +#include "rkcif-interface.h" +#include "rkcif-regs.h" +#include "rkcif-stream.h" + +#define RK3568_MIPI_CTRL0_HIGH_ALIGN BIT(31) +#define RK3568_MIPI_CTRL0_UV_SWAP_EN BIT(7) +#define RK3568_MIPI_CTRL0_COMPACT_EN BIT(6) +#define RK3568_MIPI_CTRL0_CROP_EN BIT(5) +#define RK3568_MIPI_CTRL0_WRDDR(type) ((type) << 1) + +#define RKCIF_MIPI_CTRL0_DT_ID(id) ((id) << 10) +#define RKCIF_MIPI_CTRL0_VC_ID(id) ((id) << 8) +#define RKCIF_MIPI_CTRL0_CAP_EN BIT(0) + +#define RKCIF_MIPI_INT_FRAME0_END(id) BIT(8 + (id) * 2 + 0) +#define RKCIF_MIPI_INT_FRAME1_END(id) BIT(8 + (id) * 2 + 1) + +static const struct rkcif_output_fmt mipi_out_fmts[] =3D { + /* YUV formats */ + { + .fourcc =3D V4L2_PIX_FMT_YUYV, + .mbus_code =3D MEDIA_BUS_FMT_YUYV8_1X16, + .depth =3D 16, + .cplanes =3D 1, + .mipi =3D { + .dt =3D MIPI_CSI2_DT_YUV422_8B, + .type =3D RKCIF_MIPI_TYPE_RAW8, + }, + }, + { + .fourcc =3D V4L2_PIX_FMT_UYVY, + .mbus_code =3D MEDIA_BUS_FMT_UYVY8_1X16, + .depth =3D 16, + .cplanes =3D 1, + .mipi =3D { + .dt =3D MIPI_CSI2_DT_YUV422_8B, + .type =3D RKCIF_MIPI_TYPE_RAW8, + }, + }, + { + .fourcc =3D V4L2_PIX_FMT_YVYU, + .mbus_code =3D MEDIA_BUS_FMT_YVYU8_1X16, + .depth =3D 16, + .cplanes =3D 1, + .mipi =3D { + .dt =3D MIPI_CSI2_DT_YUV422_8B, + .type =3D RKCIF_MIPI_TYPE_RAW8, + }, + }, + { + .fourcc =3D V4L2_PIX_FMT_VYUY, + .mbus_code =3D MEDIA_BUS_FMT_VYUY8_1X16, + .depth =3D 16, + .cplanes =3D 1, + .mipi =3D { + .dt =3D MIPI_CSI2_DT_YUV422_8B, + .type =3D RKCIF_MIPI_TYPE_RAW8, + }, + }, + /* RGB formats */ + { + .fourcc =3D V4L2_PIX_FMT_RGB24, + .mbus_code =3D MEDIA_BUS_FMT_RGB888_1X24, + .depth =3D 24, + .cplanes =3D 1, + .mipi =3D { + .dt =3D MIPI_CSI2_DT_RGB888, + .type =3D RKCIF_MIPI_TYPE_RGB888, + }, + }, + { + .fourcc =3D V4L2_PIX_FMT_BGR24, + .mbus_code =3D MEDIA_BUS_FMT_BGR888_1X24, + .depth =3D 24, + .cplanes =3D 1, + .mipi =3D { + .dt =3D MIPI_CSI2_DT_RGB888, + .type =3D RKCIF_MIPI_TYPE_RGB888, + }, + }, + /* Bayer formats */ + { + .fourcc =3D V4L2_PIX_FMT_SBGGR8, + .mbus_code =3D MEDIA_BUS_FMT_SBGGR8_1X8, + .depth =3D 8, + .cplanes =3D 1, + .mipi =3D { + .dt =3D MIPI_CSI2_DT_RAW8, + .type =3D RKCIF_MIPI_TYPE_RAW8, + }, + }, + { + .fourcc =3D V4L2_PIX_FMT_SGBRG8, + .mbus_code =3D MEDIA_BUS_FMT_SGBRG8_1X8, + .depth =3D 8, + .cplanes =3D 1, + .mipi =3D { + .dt =3D MIPI_CSI2_DT_RAW8, + .type =3D RKCIF_MIPI_TYPE_RAW8, + }, + }, + { + .fourcc =3D V4L2_PIX_FMT_SGRBG8, + .mbus_code =3D MEDIA_BUS_FMT_SGRBG8_1X8, + .depth =3D 8, + .cplanes =3D 1, + .mipi =3D { + .dt =3D MIPI_CSI2_DT_RAW8, + .type =3D RKCIF_MIPI_TYPE_RAW8, + }, + }, + { + .fourcc =3D V4L2_PIX_FMT_SRGGB8, + .mbus_code =3D MEDIA_BUS_FMT_SRGGB8_1X8, + .depth =3D 8, + .cplanes =3D 1, + .mipi =3D { + .dt =3D MIPI_CSI2_DT_RAW8, + .type =3D RKCIF_MIPI_TYPE_RAW8, + }, + }, + { + .fourcc =3D V4L2_PIX_FMT_SBGGR10, + .mbus_code =3D MEDIA_BUS_FMT_SBGGR10_1X10, + .depth =3D 10, + .cplanes =3D 1, + .mipi =3D { + .dt =3D MIPI_CSI2_DT_RAW10, + .type =3D RKCIF_MIPI_TYPE_RAW10, + }, + }, + { + .fourcc =3D V4L2_PIX_FMT_SBGGR10P, + .mbus_code =3D MEDIA_BUS_FMT_SBGGR10_1X10, + .depth =3D 10, + .cplanes =3D 1, + .mipi =3D { + .dt =3D MIPI_CSI2_DT_RAW10, + .compact =3D true, + .type =3D RKCIF_MIPI_TYPE_RAW10, + }, + }, + { + .fourcc =3D V4L2_PIX_FMT_SGBRG10, + .mbus_code =3D MEDIA_BUS_FMT_SGBRG10_1X10, + .depth =3D 10, + .cplanes =3D 1, + .mipi =3D { + .dt =3D MIPI_CSI2_DT_RAW10, + .type =3D RKCIF_MIPI_TYPE_RAW10, + }, + }, + { + .fourcc =3D V4L2_PIX_FMT_SGBRG10P, + .mbus_code =3D MEDIA_BUS_FMT_SGBRG10_1X10, + .depth =3D 10, + .cplanes =3D 1, + .mipi =3D { + .dt =3D MIPI_CSI2_DT_RAW10, + .compact =3D true, + .type =3D RKCIF_MIPI_TYPE_RAW10, + }, + }, + { + .fourcc =3D V4L2_PIX_FMT_SGRBG10, + .mbus_code =3D MEDIA_BUS_FMT_SGRBG10_1X10, + .depth =3D 10, + .cplanes =3D 1, + .mipi =3D { + .dt =3D MIPI_CSI2_DT_RAW10, + .type =3D RKCIF_MIPI_TYPE_RAW10, + }, + }, + { + .fourcc =3D V4L2_PIX_FMT_SGRBG10P, + .mbus_code =3D MEDIA_BUS_FMT_SGRBG10_1X10, + .depth =3D 10, + .cplanes =3D 1, + .mipi =3D { + .dt =3D MIPI_CSI2_DT_RAW10, + .compact =3D true, + .type =3D RKCIF_MIPI_TYPE_RAW10, + }, + }, + { + .fourcc =3D V4L2_PIX_FMT_SRGGB10, + .mbus_code =3D MEDIA_BUS_FMT_SRGGB10_1X10, + .depth =3D 10, + .cplanes =3D 1, + .mipi =3D { + .dt =3D MIPI_CSI2_DT_RAW10, + .type =3D RKCIF_MIPI_TYPE_RAW10, + }, + }, + { + .fourcc =3D V4L2_PIX_FMT_SRGGB10P, + .mbus_code =3D MEDIA_BUS_FMT_SRGGB10_1X10, + .depth =3D 10, + .cplanes =3D 1, + .mipi =3D { + .dt =3D MIPI_CSI2_DT_RAW10, + .compact =3D true, + .type =3D RKCIF_MIPI_TYPE_RAW10, + }, + }, + { + .fourcc =3D V4L2_PIX_FMT_SBGGR12, + .mbus_code =3D MEDIA_BUS_FMT_SBGGR12_1X12, + .depth =3D 12, + .cplanes =3D 1, + .mipi =3D { + .dt =3D MIPI_CSI2_DT_RAW12, + .type =3D RKCIF_MIPI_TYPE_RAW12, + }, + }, + { + .fourcc =3D V4L2_PIX_FMT_SBGGR12P, + .mbus_code =3D MEDIA_BUS_FMT_SBGGR12_1X12, + .depth =3D 12, + .cplanes =3D 1, + .mipi =3D { + .dt =3D MIPI_CSI2_DT_RAW12, + .compact =3D true, + .type =3D RKCIF_MIPI_TYPE_RAW12, + }, + }, + { + .fourcc =3D V4L2_PIX_FMT_SGBRG12, + .mbus_code =3D MEDIA_BUS_FMT_SGBRG12_1X12, + .depth =3D 12, + .cplanes =3D 1, + .mipi =3D { + .dt =3D MIPI_CSI2_DT_RAW12, + .type =3D RKCIF_MIPI_TYPE_RAW12, + }, + }, + { + .fourcc =3D V4L2_PIX_FMT_SGBRG12P, + .mbus_code =3D MEDIA_BUS_FMT_SGBRG12_1X12, + .depth =3D 12, + .cplanes =3D 1, + .mipi =3D { + .dt =3D MIPI_CSI2_DT_RAW12, + .compact =3D true, + .type =3D RKCIF_MIPI_TYPE_RAW12, + }, + }, + { + .fourcc =3D V4L2_PIX_FMT_SGRBG12, + .mbus_code =3D MEDIA_BUS_FMT_SGRBG12_1X12, + .depth =3D 12, + .cplanes =3D 1, + .mipi =3D { + .dt =3D MIPI_CSI2_DT_RAW12, + .type =3D RKCIF_MIPI_TYPE_RAW12, + }, + }, + { + .fourcc =3D V4L2_PIX_FMT_SGRBG12P, + .mbus_code =3D MEDIA_BUS_FMT_SGRBG12_1X12, + .depth =3D 12, + .cplanes =3D 1, + .mipi =3D { + .dt =3D MIPI_CSI2_DT_RAW12, + .compact =3D true, + .type =3D RKCIF_MIPI_TYPE_RAW12, + }, + }, + { + .fourcc =3D V4L2_PIX_FMT_SRGGB12, + .mbus_code =3D MEDIA_BUS_FMT_SRGGB12_1X12, + .depth =3D 12, + .cplanes =3D 1, + .mipi =3D { + .dt =3D MIPI_CSI2_DT_RAW12, + .type =3D RKCIF_MIPI_TYPE_RAW12, + }, + }, + { + .fourcc =3D V4L2_PIX_FMT_SRGGB12P, + .mbus_code =3D MEDIA_BUS_FMT_SRGGB12_1X12, + .depth =3D 12, + .cplanes =3D 1, + .mipi =3D { + .dt =3D MIPI_CSI2_DT_RAW12, + .compact =3D true, + .type =3D RKCIF_MIPI_TYPE_RAW12, + }, + }, +}; + +static const struct rkcif_input_fmt mipi_in_fmts[] =3D { + /* YUV formats */ + { + .mbus_code =3D MEDIA_BUS_FMT_YUYV8_1X16, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_UYVY8_1X16, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_YVYU8_1X16, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_VYUY8_1X16, + }, + /* RGB formats */ + { + .mbus_code =3D MEDIA_BUS_FMT_RGB888_1X24, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_BGR888_1X24, + }, + /* Bayer formats */ + { + .mbus_code =3D MEDIA_BUS_FMT_SBGGR8_1X8, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_SGBRG8_1X8, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_SGRBG8_1X8, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_SRGGB8_1X8, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_SBGGR10_1X10, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_SGBRG10_1X10, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_SGRBG10_1X10, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_SRGGB10_1X10, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_SBGGR12_1X12, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_SGBRG12_1X12, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_SGRBG12_1X12, + }, + { + .mbus_code =3D MEDIA_BUS_FMT_SRGGB12_1X12, + }, +}; + +static u32 +rkcif_rk3568_mipi_ctrl0(struct rkcif_stream *stream, + const struct rkcif_output_fmt *active_out_fmt) +{ + u32 ctrl0 =3D 0; + + ctrl0 |=3D RKCIF_MIPI_CTRL0_DT_ID(active_out_fmt->mipi.dt); + ctrl0 |=3D RKCIF_MIPI_CTRL0_CAP_EN; + ctrl0 |=3D RK3568_MIPI_CTRL0_CROP_EN; + + if (active_out_fmt->mipi.compact) + ctrl0 |=3D RK3568_MIPI_CTRL0_COMPACT_EN; + + switch (active_out_fmt->mipi.type) { + case RKCIF_MIPI_TYPE_RAW8: + break; + case RKCIF_MIPI_TYPE_RAW10: + ctrl0 |=3D RK3568_MIPI_CTRL0_WRDDR(0x1); + break; + case RKCIF_MIPI_TYPE_RAW12: + ctrl0 |=3D RK3568_MIPI_CTRL0_WRDDR(0x2); + break; + case RKCIF_MIPI_TYPE_RGB888: + ctrl0 |=3D RK3568_MIPI_CTRL0_WRDDR(0x3); + break; + case RKCIF_MIPI_TYPE_YUV422SP: + ctrl0 |=3D RK3568_MIPI_CTRL0_WRDDR(0x4); + break; + case RKCIF_MIPI_TYPE_YUV420SP: + ctrl0 |=3D RK3568_MIPI_CTRL0_WRDDR(0x5); + break; + case RKCIF_MIPI_TYPE_YUV400: + ctrl0 |=3D RK3568_MIPI_CTRL0_WRDDR(0x6); + break; + default: + break; + } + + return ctrl0; +} + +const struct rkcif_mipi_match_data rkcif_rk3568_vicap_mipi_match_data =3D { + .mipi_num =3D 1, + .mipi_ctrl0 =3D rkcif_rk3568_mipi_ctrl0, + .regs =3D { + [RKCIF_MIPI_CTRL] =3D 0x20, + [RKCIF_MIPI_INTEN] =3D 0xa4, + [RKCIF_MIPI_INTSTAT] =3D 0xa8, + }, + .regs_id =3D { + [RKCIF_ID0] =3D { + [RKCIF_MIPI_CTRL0] =3D 0x00, + [RKCIF_MIPI_CTRL1] =3D 0x04, + [RKCIF_MIPI_FRAME0_ADDR_Y] =3D 0x24, + [RKCIF_MIPI_FRAME0_ADDR_UV] =3D 0x2c, + [RKCIF_MIPI_FRAME0_VLW_Y] =3D 0x34, + [RKCIF_MIPI_FRAME0_VLW_UV] =3D 0x3c, + [RKCIF_MIPI_FRAME1_ADDR_Y] =3D 0x28, + [RKCIF_MIPI_FRAME1_ADDR_UV] =3D 0x30, + [RKCIF_MIPI_FRAME1_VLW_Y] =3D 0x38, + [RKCIF_MIPI_FRAME1_VLW_UV] =3D 0x40, + [RKCIF_MIPI_CROP_START] =3D 0xbc, + }, + [RKCIF_ID1] =3D { + [RKCIF_MIPI_CTRL0] =3D 0x08, + [RKCIF_MIPI_CTRL1] =3D 0x0c, + [RKCIF_MIPI_FRAME0_ADDR_Y] =3D 0x44, + [RKCIF_MIPI_FRAME0_ADDR_UV] =3D 0x4c, + [RKCIF_MIPI_FRAME0_VLW_Y] =3D 0x54, + [RKCIF_MIPI_FRAME0_VLW_UV] =3D 0x5c, + [RKCIF_MIPI_FRAME1_ADDR_Y] =3D 0x48, + [RKCIF_MIPI_FRAME1_ADDR_UV] =3D 0x50, + [RKCIF_MIPI_FRAME1_VLW_Y] =3D 0x58, + [RKCIF_MIPI_FRAME1_VLW_UV] =3D 0x60, + [RKCIF_MIPI_CROP_START] =3D 0xc0, + }, + [RKCIF_ID2] =3D { + [RKCIF_MIPI_CTRL0] =3D 0x10, + [RKCIF_MIPI_CTRL1] =3D 0x14, + [RKCIF_MIPI_FRAME0_ADDR_Y] =3D 0x64, + [RKCIF_MIPI_FRAME0_ADDR_UV] =3D 0x6c, + [RKCIF_MIPI_FRAME0_VLW_Y] =3D 0x74, + [RKCIF_MIPI_FRAME0_VLW_UV] =3D 0x7c, + [RKCIF_MIPI_FRAME1_ADDR_Y] =3D 0x68, + [RKCIF_MIPI_FRAME1_ADDR_UV] =3D 0x70, + [RKCIF_MIPI_FRAME1_VLW_Y] =3D 0x78, + [RKCIF_MIPI_FRAME1_VLW_UV] =3D 0x80, + [RKCIF_MIPI_CROP_START] =3D 0xc4, + }, + [RKCIF_ID3] =3D { + [RKCIF_MIPI_CTRL0] =3D 0x18, + [RKCIF_MIPI_CTRL1] =3D 0x1c, + [RKCIF_MIPI_FRAME0_ADDR_Y] =3D 0x84, + [RKCIF_MIPI_FRAME0_ADDR_UV] =3D 0x8c, + [RKCIF_MIPI_FRAME0_VLW_Y] =3D 0x94, + [RKCIF_MIPI_FRAME0_VLW_UV] =3D 0x9c, + [RKCIF_MIPI_FRAME1_ADDR_Y] =3D 0x88, + [RKCIF_MIPI_FRAME1_ADDR_UV] =3D 0x90, + [RKCIF_MIPI_FRAME1_VLW_Y] =3D 0x98, + [RKCIF_MIPI_FRAME1_VLW_UV] =3D 0xa0, + [RKCIF_MIPI_CROP_START] =3D 0xc8, + }, + }, + .blocks =3D { + { + .offset =3D 0x80, + }, + }, +}; + +static inline unsigned int rkcif_mipi_get_reg(struct rkcif_interface *inte= rface, + unsigned int index) +{ + struct rkcif_device *rkcif =3D interface->rkcif; + unsigned int block, offset, reg; + + block =3D interface->index - RKCIF_MIPI_BASE; + + if (WARN_ON_ONCE(block > RKCIF_MIPI_MAX - RKCIF_MIPI_BASE) || + WARN_ON_ONCE(index > RKCIF_MIPI_REGISTER_MAX)) + return RKCIF_REGISTER_NOTSUPPORTED; + + offset =3D rkcif->match_data->mipi->blocks[block].offset; + reg =3D rkcif->match_data->mipi->regs[index]; + if (reg =3D=3D RKCIF_REGISTER_NOTSUPPORTED) + return reg; + + return offset + reg; +} + +static inline unsigned int rkcif_mipi_id_get_reg(struct rkcif_stream *stre= am, + unsigned int index) +{ + struct rkcif_device *rkcif =3D stream->rkcif; + unsigned int block, id, offset, reg; + + block =3D stream->interface->index - RKCIF_MIPI_BASE; + id =3D stream->id; + + if (WARN_ON_ONCE(block > RKCIF_MIPI_MAX - RKCIF_MIPI_BASE) || + WARN_ON_ONCE(id > RKCIF_ID_MAX) || + WARN_ON_ONCE(index > RKCIF_MIPI_ID_REGISTER_MAX)) + return RKCIF_REGISTER_NOTSUPPORTED; + + offset =3D rkcif->match_data->mipi->blocks[block].offset; + reg =3D rkcif->match_data->mipi->regs_id[id][index]; + if (reg =3D=3D RKCIF_REGISTER_NOTSUPPORTED) + return reg; + + return offset + reg; +} + +static inline __maybe_unused void +rkcif_mipi_write(struct rkcif_interface *interface, unsigned int index, u3= 2 val) +{ + unsigned int addr =3D rkcif_mipi_get_reg(interface, index); + + if (addr =3D=3D RKCIF_REGISTER_NOTSUPPORTED) + return; + + writel(val, interface->rkcif->base_addr + addr); +} + +static inline __maybe_unused void +rkcif_mipi_stream_write(struct rkcif_stream *stream, unsigned int index, + u32 val) +{ + unsigned int addr =3D rkcif_mipi_id_get_reg(stream, index); + + if (addr =3D=3D RKCIF_REGISTER_NOTSUPPORTED) + return; + + writel(val, stream->rkcif->base_addr + addr); +} + +static inline __maybe_unused u32 +rkcif_mipi_read(struct rkcif_interface *interface, unsigned int index) +{ + unsigned int addr =3D rkcif_mipi_get_reg(interface, index); + + if (addr =3D=3D RKCIF_REGISTER_NOTSUPPORTED) + return 0; + + return readl(interface->rkcif->base_addr + addr); +} + +static inline __maybe_unused u32 +rkcif_mipi_stream_read(struct rkcif_stream *stream, unsigned int index) +{ + unsigned int addr =3D rkcif_mipi_id_get_reg(stream, index); + + if (addr =3D=3D RKCIF_REGISTER_NOTSUPPORTED) + return 0; + + return readl(stream->rkcif->base_addr + addr); +} + +static void rkcif_mipi_queue_buffer(struct rkcif_stream *stream, + unsigned int index) +{ + struct rkcif_buffer *buffer =3D stream->buffers[index]; + u32 frm_addr_y, frm_addr_uv; + + frm_addr_y =3D index ? RKCIF_MIPI_FRAME1_ADDR_Y : + RKCIF_MIPI_FRAME0_ADDR_Y; + frm_addr_uv =3D index ? RKCIF_MIPI_FRAME1_ADDR_UV : + RKCIF_MIPI_FRAME0_ADDR_UV; + + rkcif_mipi_stream_write(stream, frm_addr_y, + buffer->buff_addr[RKCIF_PLANE_Y]); + rkcif_mipi_stream_write(stream, frm_addr_uv, + buffer->buff_addr[RKCIF_PLANE_UV]); +} + +static int rkcif_mipi_start_streaming(struct rkcif_stream *stream) +{ + struct rkcif_interface *interface =3D stream->interface; + const struct rkcif_output_fmt *active_out_fmt; + const struct rkcif_mipi_match_data *match_data; + struct v4l2_subdev_state *state; + u32 ctrl0 =3D 0, ctrl1 =3D 0, int_temp =3D 0, int_mask =3D 0, vlw =3D 0; + u16 height, width; + int ret =3D -EINVAL; + + state =3D v4l2_subdev_lock_and_get_active_state(&interface->sd); + + active_out_fmt =3D rkcif_stream_find_output_fmt(stream, false, + stream->pix.pixelformat); + if (!active_out_fmt) + goto out; + + height =3D stream->pix.height; + width =3D stream->pix.width; + vlw =3D stream->pix.plane_fmt[0].bytesperline; + + match_data =3D stream->rkcif->match_data->mipi; + if (match_data->mipi_ctrl0) + ctrl0 =3D match_data->mipi_ctrl0(stream, active_out_fmt); + + ctrl1 =3D RKCIF_XY_COORD(width, height); + + int_mask |=3D RKCIF_MIPI_INT_FRAME0_END(stream->id); + int_mask |=3D RKCIF_MIPI_INT_FRAME1_END(stream->id); + + int_temp =3D rkcif_mipi_read(interface, RKCIF_MIPI_INTEN); + int_temp |=3D int_mask; + rkcif_mipi_write(interface, RKCIF_MIPI_INTEN, int_temp); + + int_temp =3D rkcif_mipi_read(interface, RKCIF_MIPI_INTSTAT); + int_temp &=3D ~int_mask; + rkcif_mipi_write(interface, RKCIF_MIPI_INTSTAT, int_temp); + + rkcif_mipi_stream_write(stream, RKCIF_MIPI_FRAME0_VLW_Y, vlw); + rkcif_mipi_stream_write(stream, RKCIF_MIPI_FRAME1_VLW_Y, vlw); + rkcif_mipi_stream_write(stream, RKCIF_MIPI_FRAME0_VLW_UV, vlw); + rkcif_mipi_stream_write(stream, RKCIF_MIPI_FRAME1_VLW_UV, vlw); + rkcif_mipi_stream_write(stream, RKCIF_MIPI_CROP_START, 0x0); + rkcif_mipi_stream_write(stream, RKCIF_MIPI_CTRL1, ctrl1); + rkcif_mipi_stream_write(stream, RKCIF_MIPI_CTRL0, ctrl0); + + ret =3D 0; + +out: + v4l2_subdev_unlock_state(state); + return ret; +} + +static void rkcif_mipi_stop_streaming(struct rkcif_stream *stream) +{ + struct rkcif_interface *interface =3D stream->interface; + struct v4l2_subdev_state *state; + u32 int_temp =3D 0, int_mask =3D 0; + + state =3D v4l2_subdev_lock_and_get_active_state(&interface->sd); + + rkcif_mipi_stream_write(stream, RKCIF_MIPI_CTRL0, 0); + + int_mask |=3D RKCIF_MIPI_INT_FRAME0_END(stream->id); + int_mask |=3D RKCIF_MIPI_INT_FRAME1_END(stream->id); + + int_temp =3D rkcif_mipi_read(interface, RKCIF_MIPI_INTEN); + int_temp &=3D ~int_mask; + rkcif_mipi_write(interface, RKCIF_MIPI_INTEN, int_temp); + + int_temp =3D rkcif_mipi_read(interface, RKCIF_MIPI_INTSTAT); + int_temp &=3D ~int_mask; + rkcif_mipi_write(interface, RKCIF_MIPI_INTSTAT, int_temp); + + stream->stopping =3D false; + + v4l2_subdev_unlock_state(state); +} + +static void rkcif_mipi_set_crop(struct rkcif_stream *stream, u16 left, u16= top) +{ + u32 val; + + val =3D RKCIF_XY_COORD(left, top); + rkcif_mipi_stream_write(stream, RKCIF_MIPI_CROP_START, val); +} + +irqreturn_t rkcif_mipi_isr(int irq, void *ctx) +{ + struct device *dev =3D ctx; + struct rkcif_device *rkcif =3D dev_get_drvdata(dev); + irqreturn_t ret =3D IRQ_NONE; + u32 intstat; + + for (unsigned int i =3D 0; i < rkcif->match_data->mipi->mipi_num; i++) { + enum rkcif_interface_index index =3D RKCIF_MIPI_BASE + i; + struct rkcif_interface *interface =3D &rkcif->interfaces[index]; + + intstat =3D rkcif_mipi_read(interface, RKCIF_MIPI_INTSTAT); + rkcif_mipi_write(interface, RKCIF_MIPI_INTSTAT, intstat); + + for (unsigned int j =3D 0; j < interface->streams_num; j++) { + struct rkcif_stream *stream =3D &interface->streams[j]; + + if (intstat & RKCIF_MIPI_INT_FRAME0_END(stream->id) || + intstat & RKCIF_MIPI_INT_FRAME1_END(stream->id)) { + ret =3D IRQ_HANDLED; + + if (stream->stopping) { + rkcif_mipi_stop_streaming(stream); + wake_up(&stream->wq_stopped); + continue; + } + + rkcif_stream_pingpong(stream); + } + } + } + + return ret; +} + +int rkcif_mipi_register(struct rkcif_device *rkcif) +{ + int ret; + + if (!rkcif->match_data->mipi) + return 0; + + for (unsigned int i =3D 0; i < rkcif->match_data->mipi->mipi_num; i++) { + enum rkcif_interface_index index =3D RKCIF_MIPI_BASE + i; + struct rkcif_interface *interface =3D &rkcif->interfaces[index]; + + interface->index =3D index; + interface->type =3D RKCIF_IF_MIPI; + interface->in_fmts =3D mipi_in_fmts; + interface->in_fmts_num =3D ARRAY_SIZE(mipi_in_fmts); + interface->set_crop =3D rkcif_mipi_set_crop; + interface->streams_num =3D 0; + ret =3D rkcif_interface_register(rkcif, interface); + if (ret) + continue; + + for (unsigned int j =3D 0; j < RKCIF_ID_MAX; j++) { + struct rkcif_stream *stream =3D &interface->streams[j]; + + stream->id =3D j; + stream->interface =3D interface; + stream->out_fmts =3D mipi_out_fmts; + stream->out_fmts_num =3D ARRAY_SIZE(mipi_out_fmts); + stream->queue_buffer =3D rkcif_mipi_queue_buffer; + stream->start_streaming =3D rkcif_mipi_start_streaming; + stream->stop_streaming =3D rkcif_mipi_stop_streaming; + ret =3D rkcif_stream_register(rkcif, stream); + if (ret) + goto err; + interface->streams_num++; + } + } + + return 0; + +err: + for (unsigned int i =3D 0; i < rkcif->match_data->mipi->mipi_num; i++) { + enum rkcif_interface_index index =3D RKCIF_MIPI_BASE + i; + struct rkcif_interface *interface =3D &rkcif->interfaces[index]; + + for (unsigned int j =3D 0; j < interface->streams_num; j++) + rkcif_stream_unregister(&interface->streams[j]); + + rkcif_interface_unregister(interface); + } + return ret; +} + +void rkcif_mipi_unregister(struct rkcif_device *rkcif) +{ + if (!rkcif->match_data->mipi) + return; + + for (unsigned int i =3D 0; i < rkcif->match_data->mipi->mipi_num; i++) { + enum rkcif_interface_index index =3D RKCIF_MIPI_BASE + i; + struct rkcif_interface *interface =3D &rkcif->interfaces[index]; + + for (unsigned int j =3D 0; j < interface->streams_num; j++) + rkcif_stream_unregister(&interface->streams[j]); + + rkcif_interface_unregister(interface); + } +} diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-capture-mipi.h b/d= rivers/media/platform/rockchip/rkcif/rkcif-capture-mipi.h new file mode 100644 index 000000000000..7f16eadc474c --- /dev/null +++ b/drivers/media/platform/rockchip/rkcif/rkcif-capture-mipi.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Rockchip Camera Interface (CIF) Driver + * + * Copyright (C) 2018 Rockchip Electronics Co., Ltd. + * Copyright (C) 2025 Michael Riesch + * Copyright (C) 2025 Collabora, Ltd. + */ + +#ifndef _RKCIF_CAPTURE_MIPI_H +#define _RKCIF_CAPTURE_MIPI_H + +#include "rkcif-common.h" + +extern const struct rkcif_mipi_match_data rkcif_rk3568_vicap_mipi_match_da= ta; + +int rkcif_mipi_register(struct rkcif_device *rkcif); + +void rkcif_mipi_unregister(struct rkcif_device *rkcif); + +irqreturn_t rkcif_mipi_isr(int irq, void *ctx); + +#endif diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-common.h b/drivers= /media/platform/rockchip/rkcif/rkcif-common.h index c6ec578e1049..dd92cfbc879f 100644 --- a/drivers/media/platform/rockchip/rkcif/rkcif-common.h +++ b/drivers/media/platform/rockchip/rkcif/rkcif-common.h @@ -73,6 +73,17 @@ enum rkcif_interface_type { RKCIF_IF_MIPI, }; =20 +enum rkcif_mipi_format_type { + RKCIF_MIPI_TYPE_INVALID, + RKCIF_MIPI_TYPE_RAW8, + RKCIF_MIPI_TYPE_RAW10, + RKCIF_MIPI_TYPE_RAW12, + RKCIF_MIPI_TYPE_RGB888, + RKCIF_MIPI_TYPE_YUV422SP, + RKCIF_MIPI_TYPE_YUV420SP, + RKCIF_MIPI_TYPE_YUV400, +}; + struct rkcif_buffer { struct vb2_v4l2_buffer vb; struct list_head queue; @@ -107,9 +118,15 @@ struct rkcif_output_fmt { u32 fourcc; u32 mbus_code; u8 cplanes; + u8 depth; =20 union { u32 dvp_fmt_val; + struct { + u8 dt; + bool compact; + enum rkcif_mipi_format_type type; + } mipi; }; }; =20 @@ -184,6 +201,17 @@ struct rkcif_interface { void (*set_crop)(struct rkcif_stream *stream, u16 left, u16 top); }; =20 +struct rkcif_mipi_match_data { + unsigned int mipi_num; + unsigned int regs[RKCIF_MIPI_REGISTER_MAX]; + unsigned int regs_id[RKCIF_ID_MAX][RKCIF_MIPI_ID_REGISTER_MAX]; + u32 (*mipi_ctrl0)(struct rkcif_stream *stream, + const struct rkcif_output_fmt *active_out_fmt); + struct { + unsigned int offset; + } blocks[RKCIF_MIPI_MAX - RKCIF_MIPI_BASE]; +}; + struct rkcif_dvp_match_data { const struct rkcif_input_fmt *in_fmts; unsigned int in_fmts_num; @@ -199,6 +227,7 @@ struct rkcif_match_data { const char *const *clks; unsigned int clks_num; const struct rkcif_dvp_match_data *dvp; + const struct rkcif_mipi_match_data *mipi; }; =20 struct rkcif_device { diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-dev.c b/drivers/me= dia/platform/rockchip/rkcif/rkcif-dev.c index addc118ff8bf..b4cf1146f131 100644 --- a/drivers/media/platform/rockchip/rkcif/rkcif-dev.c +++ b/drivers/media/platform/rockchip/rkcif/rkcif-dev.c @@ -24,6 +24,7 @@ #include =20 #include "rkcif-capture-dvp.h" +#include "rkcif-capture-mipi.h" #include "rkcif-common.h" =20 static const char *const px30_vip_clks[] =3D { @@ -49,6 +50,7 @@ static const struct rkcif_match_data rk3568_vicap_match_d= ata =3D { .clks =3D rk3568_vicap_clks, .clks_num =3D ARRAY_SIZE(rk3568_vicap_clks), .dvp =3D &rkcif_rk3568_vicap_dvp_match_data, + .mipi =3D &rkcif_rk3568_vicap_mipi_match_data, }; =20 static const struct of_device_id rkcif_plat_of_match[] =3D { @@ -72,14 +74,21 @@ static int rkcif_register(struct rkcif_device *rkcif) if (ret && ret !=3D -ENODEV) goto err; =20 + ret =3D rkcif_mipi_register(rkcif); + if (ret && ret !=3D -ENODEV) + goto err_dvp_unregister; + return 0; =20 +err_dvp_unregister: + rkcif_dvp_unregister(rkcif); err: return ret; } =20 static void rkcif_unregister(struct rkcif_device *rkcif) { + rkcif_mipi_unregister(rkcif); rkcif_dvp_unregister(rkcif); } =20 @@ -128,6 +137,9 @@ static irqreturn_t rkcif_isr(int irq, void *ctx) if (rkcif_dvp_isr(irq, ctx) =3D=3D IRQ_HANDLED) ret =3D IRQ_HANDLED; =20 + if (rkcif_mipi_isr(irq, ctx) =3D=3D IRQ_HANDLED) + ret =3D IRQ_HANDLED; + return ret; } =20 diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-regs.h b/drivers/m= edia/platform/rockchip/rkcif/rkcif-regs.h index 91d42d31fd10..3cf7ee19de30 100644 --- a/drivers/media/platform/rockchip/rkcif/rkcif-regs.h +++ b/drivers/media/platform/rockchip/rkcif/rkcif-regs.h @@ -128,4 +128,26 @@ enum rkcif_dvp_register_index { RKCIF_DVP_REGISTER_MAX }; =20 +enum rkcif_mipi_register_index { + RKCIF_MIPI_CTRL, + RKCIF_MIPI_INTEN, + RKCIF_MIPI_INTSTAT, + RKCIF_MIPI_REGISTER_MAX +}; + +enum rkcif_mipi_id_register_index { + RKCIF_MIPI_CTRL0, + RKCIF_MIPI_CTRL1, + RKCIF_MIPI_FRAME0_ADDR_Y, + RKCIF_MIPI_FRAME0_ADDR_UV, + RKCIF_MIPI_FRAME0_VLW_Y, + RKCIF_MIPI_FRAME0_VLW_UV, + RKCIF_MIPI_FRAME1_ADDR_Y, + RKCIF_MIPI_FRAME1_ADDR_UV, + RKCIF_MIPI_FRAME1_VLW_Y, + RKCIF_MIPI_FRAME1_VLW_UV, + RKCIF_MIPI_CROP_START, + RKCIF_MIPI_ID_REGISTER_MAX +}; + #endif --=20 2.39.5 From nobody Mon Dec 15 21:31:27 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 EBBED340D81; Fri, 14 Nov 2025 15:20:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763133621; cv=none; b=OQUviqhYn+E9Hr9ql4K8NIE7B7VYSdPgu1QuULrzRs5dXYkeikY8Qk/W1kApjr4gY1ozwoU5kpSR93lE8OeSUqX1lTWg7DaTcw7SmDa+jdOWZ+NeM0vs934UKXs3ouHa7DJtYIy5dU2EGcman+tPijVyUDzwkmhVTc16M+hHuRI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763133621; c=relaxed/simple; bh=69R/dgMaUTHNQDK0PKLoCtuW6EWBImqfW0Ki7yZtLCQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=dLdu+PlEfUbYSff/rGNfJb8CNhem7l2vY3LstqP0EHBHYuIq65fcyZTg3X1v1cOHI1VtN4dkuFe16YaJeCUGNpInFlhkWh6R+L4v9XbDmpSD8oC57C3NphT3ufhcRueQQzslbjDWtkE9y/V0dHBCH71MgLyaRHf1r2DPUjppAkM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ahrcm51L; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ahrcm51L" Received: by smtp.kernel.org (Postfix) with ESMTPS id B7B78C2BC86; Fri, 14 Nov 2025 15:20:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1763133620; bh=69R/dgMaUTHNQDK0PKLoCtuW6EWBImqfW0Ki7yZtLCQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=ahrcm51LkfcCHcXoT18vtAmjUDZ7WIQT4LgocHiEvHSpiyqjg/uBDVKY7K0pdMkCJ 9isXaKj6D884axODt2xgFdSVesE1ARikgWH4BoRm4pgIac4GSYzTXWWDc6KwQu2QY9 fY02Rg5zgJ+qr5MgDn6vnHIxSCzTICsApph+Npz+R724g0LakAbOhgeNcdEhjVn5GY Yt91bNZ4ew5WItwiTRewHCQij4KKuOPY9zQRM4jmY+sIB7eK20R9O7PGXGfi9qNEUc IYMTyIX4cNjKGzaTCuEbtLR6F3GB9THsRGB+I/raUEe+mxCnRaYw58KojXGfZ1DZOa S/Z8RLH+2ke8Q== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id ADDB5CE8D43; Fri, 14 Nov 2025 15:20:20 +0000 (UTC) From: Michael Riesch via B4 Relay Date: Fri, 14 Nov 2025 16:20:22 +0100 Subject: [PATCH v15 11/14] arm64: defconfig: enable rockchip camera interface 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: <20240220-rk3568-vicap-v15-11-8f4915ee365d@collabora.com> References: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com> In-Reply-To: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com> To: Mehdi Djait , Maxime Chevallier , =?utf-8?q?Th=C3=A9o_Lebrun?= , Thomas Petazzoni , Gerald Loacker , Bryan O'Donoghue , Markus Elfring , Laurent Pinchart , Mauro Carvalho Chehab , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Heiko Stuebner , Kever Yang , Nicolas Dufresne , Sebastian Reichel , Collabora Kernel Team , Paul Kocialkowski , Alexander Shiyan , Val Packett , Rob Herring , Philipp Zabel , Sakari Ailus Cc: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, Michael Riesch , Michael Riesch X-Mailer: b4 0.12.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1763133617; l=877; i=michael.riesch@collabora.com; s=20250410; h=from:subject:message-id; bh=81ZusjM5KxQyAL7FhST8rDN6grI5hqe9TzQy093k8Zs=; b=RW7xkBfdpjnMhr7/Hx6W3YWCs+IWWdQTvAweKZv3hlffRomiucTLdUfNVz04g7cNrEMhUm6fU YKDhbBi1//ICPToB2UvT9GnVxGDlveCnEG71Sc0VN8IgWX0G8KqI2Tb X-Developer-Key: i=michael.riesch@collabora.com; a=ed25519; pk=+MWX1fffLFZtTPG/I6XdYm/+OSvpRE8D9evQaWbiN04= X-Endpoint-Received: by B4 Relay for michael.riesch@collabora.com/20250410 with auth_id=371 X-Original-From: Michael Riesch Reply-To: michael.riesch@collabora.com From: Michael Riesch The Rockchip Camera Interface (CIF) is featured in many Rockchip SoCs in different variations. Enable the driver for it in the default configuration. Reviewed-by: Bryan O'Donoghue Reviewed-by: Mehdi Djait Signed-off-by: Michael Riesch --- arch/arm64/configs/defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index e3a2d37bd104..8eae6c70bfdf 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -883,6 +883,7 @@ CONFIG_VIDEO_RENESAS_FCP=3Dm CONFIG_VIDEO_RENESAS_FDP1=3Dm CONFIG_VIDEO_RENESAS_VSP1=3Dm CONFIG_VIDEO_RCAR_DRIF=3Dm +CONFIG_VIDEO_ROCKCHIP_CIF=3Dm CONFIG_VIDEO_ROCKCHIP_RGA=3Dm CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC=3Dm CONFIG_VIDEO_SAMSUNG_S5P_JPEG=3Dm --=20 2.39.5 From nobody Mon Dec 15 21:31:27 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 19766341AAA; Fri, 14 Nov 2025 15:20:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763133621; cv=none; b=N0EQrvBQ0GzzyA+/N2quedI05hes5LPOovdLdzw94ecOVDEaKfhDtxVrxrw4XCQkQtYOUxZqFwL9LgbL/O/NJio85uwL3wV6b/6nfu3bHRzkw1vUZr7UUEz2t/uNKW6qHSYXVjYfVRtRuL6atVMSoBlpzvbaar6c2hLURM0uClo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763133621; c=relaxed/simple; bh=Tz6jnD4R99+sBwzNPFxbH438Jp+SLdj3TJqQrSpfSJg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=gKQ/asZC7vgHlJFE+pPWQUDz0Pv17370pDy5/jz2rd6jC+mSnNyPq3Mrc40u0Jbs5K567bsmCjpR61KbbMy4MaFmfq0YNzRMr6popuTez3MU43RpPAlvwPdirtxwwH6oL8xKu4NcMXeuGJ2jnRW+y1EaqOL9ZfMuYZFcZcRzjio= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=fVO0Otfi; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="fVO0Otfi" Received: by smtp.kernel.org (Postfix) with ESMTPS id DB47AC116B1; Fri, 14 Nov 2025 15:20:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1763133620; bh=Tz6jnD4R99+sBwzNPFxbH438Jp+SLdj3TJqQrSpfSJg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=fVO0Otfi9RhbTv0T3Rj8/5ng7Xbfwo2n5aNAogd8tph3A1k9goDWAfs4kFnkv+4Ro aPQrucbavcIzuxJFRtQM4JuZfTd8f6+nAZr1o3h4TqNyqSyzJUVTW2MlEE2PWBWNYl 11j+gpMljeYSQ7yA5QE2t9L326o9oKr7EtGharlyo9IR+hIBb4do4DJrn1+mo7n+v+ LJLzldix9RTMbLz7VhVSKVchY9jmFNtNQWao9r/NGag0vssj04z0mpOZkUsFabNIs1 ofxUGbDWrBP1hOhHsgrk1IUChkUD76mJqoR00djwb5Ifc4LOa3ZG8wXTUPdoLiQ5Rm /4vgcJyl7of4A== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id BD532CE8D44; Fri, 14 Nov 2025 15:20:20 +0000 (UTC) From: Michael Riesch via B4 Relay Date: Fri, 14 Nov 2025 16:20:23 +0100 Subject: [PATCH v15 12/14] arm64: dts: rockchip: add the vip node to px30 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: <20240220-rk3568-vicap-v15-12-8f4915ee365d@collabora.com> References: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com> In-Reply-To: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com> To: Mehdi Djait , Maxime Chevallier , =?utf-8?q?Th=C3=A9o_Lebrun?= , Thomas Petazzoni , Gerald Loacker , Bryan O'Donoghue , Markus Elfring , Laurent Pinchart , Mauro Carvalho Chehab , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Heiko Stuebner , Kever Yang , Nicolas Dufresne , Sebastian Reichel , Collabora Kernel Team , Paul Kocialkowski , Alexander Shiyan , Val Packett , Rob Herring , Philipp Zabel , Sakari Ailus Cc: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, Michael Riesch , Michael Riesch , Mehdi Djait X-Mailer: b4 0.12.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1763133617; l=1332; i=michael.riesch@collabora.com; s=20250410; h=from:subject:message-id; bh=EwZeXY5MIObNAjpIDbc8b4sEOVnnQIy6dupHuKvt3ds=; b=yTj4DVFxirwVerOWEvdCbH6wZTDT+jtu5Yo3ycIWwarsvwsL+a6tDK3PMthb6JO5coaAf6Yp2 ZW+8LJZhDwKC4pJi+U7UioHRSS9GWtY+aRLhDCPprXqfLYKu8iNCd3L X-Developer-Key: i=michael.riesch@collabora.com; a=ed25519; pk=+MWX1fffLFZtTPG/I6XdYm/+OSvpRE8D9evQaWbiN04= X-Endpoint-Received: by B4 Relay for michael.riesch@collabora.com/20250410 with auth_id=371 X-Original-From: Michael Riesch Reply-To: michael.riesch@collabora.com From: Mehdi Djait Add the device tree node for the PX30 Video Input Processor (VIP). Signed-off-by: Mehdi Djait [added cosmetic changes] Signed-off-by: Michael Riesch Reviewed-by: Bryan O'Donoghue Signed-off-by: Michael Riesch --- arch/arm64/boot/dts/rockchip/px30.dtsi | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/px30.dtsi b/arch/arm64/boot/dts/r= ockchip/px30.dtsi index 46f64cd33b9b..ef52879d6a73 100644 --- a/arch/arm64/boot/dts/rockchip/px30.dtsi +++ b/arch/arm64/boot/dts/rockchip/px30.dtsi @@ -1280,6 +1280,18 @@ isp_mmu: iommu@ff4a8000 { #iommu-cells =3D <0>; }; =20 + cif: video-capture@ff490000 { + compatible =3D "rockchip,px30-vip"; + reg =3D <0x0 0xff490000 0x0 0x200>; + interrupts =3D ; + clocks =3D <&cru ACLK_CIF>, <&cru HCLK_CIF>, <&cru PCLK_CIF>; + clock-names =3D "aclk", "hclk", "pclk"; + power-domains =3D <&power PX30_PD_VI>; + resets =3D <&cru SRST_CIF_A>, <&cru SRST_CIF_H>, <&cru SRST_CIF_PCLKIN>; + reset-names =3D "axi", "ahb", "pclkin"; + status =3D "disabled"; + }; + qos_gmac: qos@ff518000 { compatible =3D "rockchip,px30-qos", "syscon"; reg =3D <0x0 0xff518000 0x0 0x20>; --=20 2.39.5 From nobody Mon Dec 15 21:31:27 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 36BAF340A44; Fri, 14 Nov 2025 15:20:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763133621; cv=none; b=BJwEeNAElWiYWtR+mqJRRBzTm4vCeoNweOE1RRvoDM/AysUgmTFKkbeZih4vzJO3BCs0sB/pfIGbcVpJoDgplBQzR+HHCCrr3qbjCqbwGJ7hkKhjjTtIUClH8UdtGm1znP4p0NstUugQXzeT7tm/3XZCvc9JsIdo4cgD34BVY10= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763133621; c=relaxed/simple; bh=vLqmAyKjYnSxPuih1KbKHGxXfnvwRJyOtYPRYAVnluo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=rmnaUrfxL1xxm8m2yxmZSX6koBFlKSmtUhb1gF4IxqCRyI/+gnPx++/qSlrw4AysslHMi1GOa4JBsbZKO8z9LOVFt0DQyKXkp+AKcaR6NQPBY7FKuNXJYbbVNgyTHbHWQg+zU7qDBVHeB4iUWlgbY+iQ5CRj9Na/8Qut09Z6+fQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=a/xTKfpb; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="a/xTKfpb" Received: by smtp.kernel.org (Postfix) with ESMTPS id E1034C2BCB0; Fri, 14 Nov 2025 15:20:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1763133621; bh=vLqmAyKjYnSxPuih1KbKHGxXfnvwRJyOtYPRYAVnluo=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=a/xTKfpb//AIhl0WJS8gYP0dmNM6WRgVBrELb5uX9mLITZ7bUulPbru/EkaL6XiJ7 k5snachywRVbY4II+jJQiFQQpMY75A7SuTSM1Phk7J63o3mu1DBrWEGBmSxQ0+Bw5e qFZOcFYEN/uG+n5KwYf0WNWtrVqaL4LLVWMx8jtlbGhAV2GuIg0xhBKIY5Ck3zrmmq sGWhAdmk9R4WiqPNxjdWBOIsbE6Gs2W2rgyfb41H4Y7e+3jnFyll/3aX8CizlviWBw kXbGpFrvKuLWFH0bfgfVJ9Ynyx+s03eBct/WDD55Z8ye+dyDrDWAPqg2daLsm4jZ2c iSe6d5431BAGA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id CDC2FCE7B13; Fri, 14 Nov 2025 15:20:20 +0000 (UTC) From: Michael Riesch via B4 Relay Date: Fri, 14 Nov 2025 16:20:24 +0100 Subject: [PATCH v15 13/14] arm64: dts: rockchip: add vicap node to rk356x 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: <20240220-rk3568-vicap-v15-13-8f4915ee365d@collabora.com> References: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com> In-Reply-To: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com> To: Mehdi Djait , Maxime Chevallier , =?utf-8?q?Th=C3=A9o_Lebrun?= , Thomas Petazzoni , Gerald Loacker , Bryan O'Donoghue , Markus Elfring , Laurent Pinchart , Mauro Carvalho Chehab , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Heiko Stuebner , Kever Yang , Nicolas Dufresne , Sebastian Reichel , Collabora Kernel Team , Paul Kocialkowski , Alexander Shiyan , Val Packett , Rob Herring , Philipp Zabel , Sakari Ailus Cc: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, Michael Riesch , Michael Riesch X-Mailer: b4 0.12.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1763133617; l=2110; i=michael.riesch@collabora.com; s=20250410; h=from:subject:message-id; bh=XnBnweWDPvohHeSHcTLfE0vYknd29lIqeTB/2ETOjTQ=; b=G8v7rcupkAme2u7aI9Kjhtw2A3vSWD2Z96fkiZ+8ItoFl69AyD4rOmxZaTwnGk2DX45K2F5Hj myefP1TUD/xBfMCtYbvjikIwfMH4H2Kk3xqt7Zz6EVl29LrZiUzk7hg X-Developer-Key: i=michael.riesch@collabora.com; a=ed25519; pk=+MWX1fffLFZtTPG/I6XdYm/+OSvpRE8D9evQaWbiN04= X-Endpoint-Received: by B4 Relay for michael.riesch@collabora.com/20250410 with auth_id=371 X-Original-From: Michael Riesch Reply-To: michael.riesch@collabora.com From: Michael Riesch Add the device tree node for the RK356x Video Capture (VICAP) unit. Signed-off-by: Michael Riesch Reviewed-by: Bryan O'Donoghue Signed-off-by: Michael Riesch --- arch/arm64/boot/dts/rockchip/rk356x-base.dtsi | 44 +++++++++++++++++++++++= ++++ 1 file changed, 44 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi b/arch/arm64/boo= t/dts/rockchip/rk356x-base.dtsi index fd2214b6fad4..e0e4dc85a3a9 100644 --- a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi @@ -564,6 +564,50 @@ gpu: gpu@fde60000 { status =3D "disabled"; }; =20 + vicap: video-capture@fdfe0000 { + compatible =3D "rockchip,rk3568-vicap"; + reg =3D <0x0 0xfdfe0000 0x0 0x200>; + interrupts =3D ; + assigned-clocks =3D <&cru DCLK_VICAP>; + assigned-clock-rates =3D <300000000>; + clocks =3D <&cru ACLK_VICAP>, <&cru HCLK_VICAP>, + <&cru DCLK_VICAP>, <&cru ICLK_VICAP_G>; + clock-names =3D "aclk", "hclk", "dclk", "iclk"; + iommus =3D <&vicap_mmu>; + power-domains =3D <&power RK3568_PD_VI>; + resets =3D <&cru SRST_A_VICAP>, <&cru SRST_H_VICAP>, + <&cru SRST_D_VICAP>, <&cru SRST_P_VICAP>, + <&cru SRST_I_VICAP>; + reset-names =3D "arst", "hrst", "drst", "prst", "irst"; + rockchip,grf =3D <&grf>; + status =3D "disabled"; + + ports { + #address-cells =3D <1>; + #size-cells =3D <0>; + + vicap_dvp: port@0 { + reg =3D <0>; + }; + + vicap_mipi: port@1 { + reg =3D <1>; + }; + }; + }; + + vicap_mmu: iommu@fdfe0800 { + compatible =3D "rockchip,rk3568-iommu"; + reg =3D <0x0 0xfdfe0800 0x0 0x100>; + interrupts =3D ; + clocks =3D <&cru ACLK_VICAP>, <&cru HCLK_VICAP>; + clock-names =3D "aclk", "iface"; + #iommu-cells =3D <0>; + power-domains =3D <&power RK3568_PD_VI>; + rockchip,disable-mmu-reset; + status =3D "disabled"; + }; + vpu: video-codec@fdea0400 { compatible =3D "rockchip,rk3568-vpu"; reg =3D <0x0 0xfdea0000 0x0 0x800>; --=20 2.39.5 From nobody Mon Dec 15 21:31:27 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 2F838342145; Fri, 14 Nov 2025 15:20:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763133621; cv=none; b=HgjB43z6Q0nuZRG606+uGtZJ9VDL7IDebJVOG5uCQln3vSz2HUjDr7lvNRv2x2oFm4Vq3K+ZBr14qhULlerQ12hLB7pFV1jgF5qIQuOKIJDLOq8qxicJpyf9JuG746OVFt5AOjb7WOUx58DGwHcbrxZYiJf29WM+7xdnyl9iZLs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763133621; c=relaxed/simple; bh=Zl4Mel46TcR7AjpUnvtEjIgKxbaBwJflcYSmq34rCyA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=DPX41qjauz73DhSCmft6eKegELSoxeNO8goExu6rYH9kj3Tl4fdbU0E5uu1/zPvGYYbOAoSeNQ4oP3GEjy9uHeAfwjO8T9cSH/nFlw9UlMomQEoepYy2lb6ez+9slN+bEPRcwjB4LkK7R6mws7Bf4OpJAqvr7SyABLCV/RRCOls= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=iAfQvPfi; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="iAfQvPfi" Received: by smtp.kernel.org (Postfix) with ESMTPS id E57B1C4CEF5; Fri, 14 Nov 2025 15:20:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1763133621; bh=Zl4Mel46TcR7AjpUnvtEjIgKxbaBwJflcYSmq34rCyA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=iAfQvPfi5SEADkrlUNoOM6I8Of1LYP0FGLct8zWunHT6+ytKuGxV8cnXyPGEyvXMQ t5jTYgBnFuRUumcwcf7D2AHe4F44j+LxRFhOL7nR8e0GLwuWPWYIgAL49WTzCGN3wO 1htSQfWSMwzxcQdVjGPiU0hNwfuenZNJMxFJiL7Ua8So64KaO/1J1bJIJY58OYbgq6 Epz3MJxDVjFUXRrx8pUZsyCAIqC4x5M3NAb9tM8Mmas9ZVtSIL2s8Z8d8ERWFfHFJL xN6At0nQ96mcBVN/pLGEDAB9vj07PQzCb+wS2DRnWO5xNT750op7wy3l43WpBnJNVE 1PLbFMtQx3LFg== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id DE98CCE8D40; Fri, 14 Nov 2025 15:20:20 +0000 (UTC) From: Michael Riesch via B4 Relay Date: Fri, 14 Nov 2025 16:20:25 +0100 Subject: [PATCH v15 14/14] arm64: dts: rockchip: enable vicap dvp on wolfvision pf5 io expander 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: <20240220-rk3568-vicap-v15-14-8f4915ee365d@collabora.com> References: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com> In-Reply-To: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com> To: Mehdi Djait , Maxime Chevallier , =?utf-8?q?Th=C3=A9o_Lebrun?= , Thomas Petazzoni , Gerald Loacker , Bryan O'Donoghue , Markus Elfring , Laurent Pinchart , Mauro Carvalho Chehab , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Heiko Stuebner , Kever Yang , Nicolas Dufresne , Sebastian Reichel , Collabora Kernel Team , Paul Kocialkowski , Alexander Shiyan , Val Packett , Rob Herring , Philipp Zabel , Sakari Ailus Cc: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, Michael Riesch , Michael Riesch X-Mailer: b4 0.12.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1763133617; l=1721; i=michael.riesch@collabora.com; s=20250410; h=from:subject:message-id; bh=0H9SWagLsWuudSJ0hjW87B9xG48FbT9CuvPeqAKM5fI=; b=ON8s1W20TM2jD3yggSPiBMjn3TVdy681hETUmgkXMbCzQ5bIRhnbvJJbaQ2nq4R7R+7KYcocC kcQo4gi6jRWDuQiwLMpSjUDm9L/HBnw6KmYYdm+LkgOlG3FcDZKi8dm X-Developer-Key: i=michael.riesch@collabora.com; a=ed25519; pk=+MWX1fffLFZtTPG/I6XdYm/+OSvpRE8D9evQaWbiN04= X-Endpoint-Received: by B4 Relay for michael.riesch@collabora.com/20250410 with auth_id=371 X-Original-From: Michael Riesch Reply-To: michael.riesch@collabora.com From: Michael Riesch The Digital Video Port (DVP, the 16-bit variant) of the RK3568 VICAP is broken out to the PF5 mainboard expansion header. Enable it in the device tree overlay for the WolfVision PF5 IO Expander board. Signed-off-by: Michael Riesch Reviewed-by: Gerald Loacker Tested-by: Gerald Loacker Reviewed-by: Bryan O'Donoghue Signed-off-by: Michael Riesch --- .../rockchip/rk3568-wolfvision-pf5-io-expander.dtso | 20 ++++++++++++++++= ++++ 1 file changed, 20 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3568-wolfvision-pf5-io-expander= .dtso b/arch/arm64/boot/dts/rockchip/rk3568-wolfvision-pf5-io-expander.dtso index 048933de2943..8cfce71dd318 100644 --- a/arch/arm64/boot/dts/rockchip/rk3568-wolfvision-pf5-io-expander.dtso +++ b/arch/arm64/boot/dts/rockchip/rk3568-wolfvision-pf5-io-expander.dtso @@ -11,6 +11,7 @@ #include #include #include +#include #include =20 &{/} { @@ -134,3 +135,22 @@ &usb2phy0_host { phy-supply =3D <&usb_host_vbus>; status =3D "okay"; }; + +&vicap { + pinctrl-names =3D "default"; + pinctrl-0 =3D <&cif_clk &cif_dvp_clk &cif_dvp_bus16>; + status =3D "okay"; +}; + +&vicap_dvp { + vicap_dvp_input: endpoint { + bus-type =3D ; + bus-width =3D <16>; + pclk-sample =3D ; + rockchip,dvp-clk-delay =3D <10>; + }; +}; + +&vicap_mmu { + status =3D "okay"; +}; --=20 2.39.5