From nobody Wed Oct 8 00:42:34 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 1F0C527586B; Thu, 3 Jul 2025 18:33:12 +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=1751567593; cv=none; b=Zfd05t2XbPtqZG737oAZ7qX1bOyNfn7JQVvf2lCqa09ipp6PnZxHzTDL7WtWvf9pqkbaHTLVNgEN5ihUQPxwWy4OsI4TIt9/t7gbrNQbW2fRq9A3RXuuQqK31Fd7aecb1saq0E0v3crarg6eB5+IpVsX5M/gpu/VFDgdqHlVxGc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751567593; c=relaxed/simple; bh=+RKXSd49QNGxofon9O/ZcqEa2ERFrhs7K98DpEYCjC0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=icfa9VX10uXMrlIPA8s1qrAFwrsS1KjZewSKbSEtj6vkuZ0Fs8hZvr6VaEFWpCUjB7N0xdbb92AjWTmiDEUvKR5fMpYEBKLfK5t3wIq/RHzdxlVFbsgsJUYvoRcXCB8yMknSMjnl8BJaxjVbIxy3SFBtAsn7Zwo8DctQ7ycM/dk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=FvZ0T79U; 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="FvZ0T79U" Received: by smtp.kernel.org (Postfix) with ESMTPS id A17EFC4CEED; Thu, 3 Jul 2025 18:33:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1751567592; bh=+RKXSd49QNGxofon9O/ZcqEa2ERFrhs7K98DpEYCjC0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=FvZ0T79U5BC4bXeJoKKGOoYWP/Jkmx2D+LX++NlPea5UNG092WKAk6ck4szKB5/gn lICR87gKfM2tzA9aAqCQIxd5GRM0onRg6HXafN5ExRpwRruua1BtdeWynLgwQAS8qm 1R8sRx7Ivlx39CXkmqCDDn1c0DdN+BRq+j9wUNuO1BmC2mIy1wMi2mqtyHoXolEmYE t35iaG6BxCBaEKMMAMrIGG52roi4JvGnZEMHqfjUhf7Cal1B1bVdym832wEMNVzGro m+MkqM2mR6OJSK3FNLEwHSgWEYNZ5iEWbEASaSWCM/Ew1G+C47/4Bk+xfjhFays8vJ DG31TbkL6fwuA== 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 912ECC83F03; Thu, 3 Jul 2025 18:33:12 +0000 (UTC) From: Frank Li via B4 Relay Date: Thu, 03 Jul 2025 14:33:06 -0400 Subject: [PATCH v2 1/4] dt-bindings: media: add i.MX parallel csi support 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: <20250703-imx8qxp_pcam-v2-1-188be85f06f1@nxp.com> References: <20250703-imx8qxp_pcam-v2-0-188be85f06f1@nxp.com> In-Reply-To: <20250703-imx8qxp_pcam-v2-0-188be85f06f1@nxp.com> To: Laurent Pinchart , Mauro Carvalho Chehab , Shawn Guo , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam , Rui Miguel Silva , Martin Kepplinger , Purism Kernel Team , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Philipp Zabel Cc: linux-media@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Frank Li , Alice Yuan X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1751567591; l=4271; i=Frank.Li@nxp.com; s=20240130; h=from:subject:message-id; bh=F6iDqFZ8amoJXqI666QahOsEJxKCsFei15ZM+Oj2BqQ=; b=7ppXxyhOnTf0rhvMnaPHXuBxIhJFJ6XuY6YkyCBO1UEaSQ0AIcE7qhCD4ApvPzaVhKGn9xJQK xYkZ3SuXoc+Ajmw8pv+yKY8oUs119hDRMkjhSlxTDhbOWu8O0pz9FuR X-Developer-Key: i=Frank.Li@nxp.com; a=ed25519; pk=I0L1sDUfPxpAkRvPKy7MdauTuSENRq+DnA+G4qcS94Q= X-Endpoint-Received: by B4 Relay for Frank.Li@nxp.com/20240130 with auth_id=121 X-Original-From: Frank Li Reply-To: Frank.Li@nxp.com From: Alice Yuan Document the binding for parallel CSI controller found in i.MX8QXP, i.MX93 and i.MX91 SoCs. Signed-off-by: Alice Yuan Signed-off-by: Frank Li --- Change in v2: - use pcif surfix as Laurent Pinchart's suggest. - put power-domains into required list --- .../devicetree/bindings/media/fsl,imx93-pcif.yaml | 109 +++++++++++++++++= ++++ MAINTAINERS | 1 + 2 files changed, 110 insertions(+) diff --git a/Documentation/devicetree/bindings/media/fsl,imx93-pcif.yaml b/= Documentation/devicetree/bindings/media/fsl,imx93-pcif.yaml new file mode 100644 index 0000000000000000000000000000000000000000..ff9a32e0bec1d1bd90d93f45dbd= 7825d1e12650e --- /dev/null +++ b/Documentation/devicetree/bindings/media/fsl,imx93-pcif.yaml @@ -0,0 +1,109 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/fsl,imx93-pcif.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: i.MX8/9 Parallel Camera Interface + +maintainers: + - Frank Li + +description: | + This is device node for the Parallel Camera Interface which enables the + chip to connect directly to external Parallel CMOS image sensors. + Supports up to 80MHz input clock from sensor. + Supports the following input data formats + - 8-bit/10-bit Camera Sensor Interface (CSI) + - 8-bit data port for RGB, YCbCr, and YUV data input + - 8-bit/10-bit data ports for Bayer data input + Parallel Camera Interface is hooked to the Imaging subsystem via the + Pixel Link. + +properties: + compatible: + oneOf: + - const: fsl,imx8qxp-pcif + - items: + - enum: + - fsl,imx91-pcif + - const: fsl,imx93-pcif + - const: fsl,imx93-pcif + + reg: + maxItems: 1 + + clocks: + maxItems: 2 + + clock-names: + items: + - const: pixel + - const: ipg + + 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 node. + + port@1: + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false + description: + Output port node. + +required: + - compatible + - reg + - clocks + - clock-names + - power-domains + - ports + +additionalProperties: false + +examples: + - | + #include + #include + + pcif@4ac10070 { + compatible =3D "fsl,imx93-pcif"; + reg =3D <0x4ac10070 0x10>; + clocks =3D <&clk IMX93_CLK_MIPI_CSI_GATE>, + <&clk IMX93_CLK_MEDIA_APB>; + clock-names =3D "pixel", "ipg"; + assigned-clocks =3D <&clk IMX93_CLK_CAM_PIX>; + assigned-clock-parents =3D <&clk IMX93_CLK_VIDEO_PLL>; + assigned-clock-rates =3D <140000000>; + power-domains =3D <&media_blk_ctrl IMX93_MEDIABLK_PD_MIPI_CSI>; + + ports { + #address-cells =3D <1>; + #size-cells =3D <0>; + + port@0 { + reg =3D <0>; + + endpoint { + remote-endpoint =3D <&mt9m114_ep>; + }; + }; + + port@1 { + reg =3D <1>; + endpoint { + remote-endpoint =3D <&isi_in>; + }; + }; + }; + }; +... diff --git a/MAINTAINERS b/MAINTAINERS index 8dc0f6609d1fe2e3eefd50088dbe566d9e107bfa..8ae0667d2bb41fb6a1549bd3b2b= 33f326cbd1303 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -15107,6 +15107,7 @@ L: linux-media@vger.kernel.org S: Maintained T: git git://linuxtv.org/media.git F: Documentation/admin-guide/media/imx7.rst +F: Documentation/devicetree/bindings/media/fsl,imx93-pcif.yaml F: Documentation/devicetree/bindings/media/nxp,imx-mipi-csi2.yaml F: Documentation/devicetree/bindings/media/nxp,imx7-csi.yaml F: Documentation/devicetree/bindings/media/nxp,imx8mq-mipi-csi2.yaml --=20 2.34.1 From nobody Wed Oct 8 00:42:34 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 1EFE51D5CE5; Thu, 3 Jul 2025 18:33:12 +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=1751567593; cv=none; b=KJdMSUdk0hf8zO74E/f5JMs6fRcFft3bAbl497d0t48QMVmrdBYn1cKwpWPYhZ1RTy5VjT42PulPiUsoeKbFtoGdxOToHGQBPdHWtnTgrCEmUOG3UYIw+LDyYl1ka+uqTEPS856fE2Rwg3SbqK4eO7W1vcZj4kLI01NOmljslS4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751567593; c=relaxed/simple; bh=UvF1XDzd6J3giIA0gcLirQGgjIINbh1GEIgY9UB/pWA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=QNgG1xRlmE9NezvOj53j9f434mgczCzy9Q8505XmU8dI8EiaoDpFPlZ2sHr+GzOsPC7YVDKsjNVqdbWvk7WZoFx/yes1wmyzV1Plx7u4z+gxH3xBqM391GvPyXtfVr6ZcXCNVOwzs0ELhS03nNgjS2a1asbfgul6QrFbCtjD+wc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=j0opY7Ro; 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="j0opY7Ro" Received: by smtp.kernel.org (Postfix) with ESMTPS id B1028C4CEEB; Thu, 3 Jul 2025 18:33:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1751567592; bh=UvF1XDzd6J3giIA0gcLirQGgjIINbh1GEIgY9UB/pWA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=j0opY7RoBChHFmi0Pk8s9wXx4g9bonoZTOBESAP71L3pQHHr5sE3dGo6faqVPfMS5 4WXnmwXpjHqUYjbZpBfrMi1bzggvZixIf7b+WqGS4A4ISVreFjKLrql7pYVfT6QP70 yO1DdJ+Vxrn+g09rHcoBs68xXLvrdjNtsPCyo+qAYirXDn8yH1HaXqgvDve09JGPLL KyF7FfI6+KNyCp90yVEEttfS3vsLj9y0cuUZIIhSBY/RCFJIMRuiTrBRl4O8Jz52BA TifB1m0AmnbZq/8HWneoiggsh6FUHYkBwe+NjeQH02QCxPJLqO469cJfNmm2vSD22V lXdsuP0BDbCBQ== 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 A0529C83F07; Thu, 3 Jul 2025 18:33:12 +0000 (UTC) From: Frank Li via B4 Relay Date: Thu, 03 Jul 2025 14:33:07 -0400 Subject: [PATCH v2 2/4] media: nxp: add V4L2 subdev driver for parallel CSI 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: <20250703-imx8qxp_pcam-v2-2-188be85f06f1@nxp.com> References: <20250703-imx8qxp_pcam-v2-0-188be85f06f1@nxp.com> In-Reply-To: <20250703-imx8qxp_pcam-v2-0-188be85f06f1@nxp.com> To: Laurent Pinchart , Mauro Carvalho Chehab , Shawn Guo , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam , Rui Miguel Silva , Martin Kepplinger , Purism Kernel Team , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Philipp Zabel Cc: linux-media@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Frank Li , Alice Yuan , Robert Chiras , Zhipeng Wang X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1751567591; l=30642; i=Frank.Li@nxp.com; s=20240130; h=from:subject:message-id; bh=WSJM4SnlZSBhwQs4OQdFPt2E+/xiOhaAr8PLvKbllPg=; b=C6g2zPo/j/KLIc/CCXB7HYziu645t/Tph42u1okGynAhbBPJx2JuqiOpbSSXrA5Ncx+TSmDdp 5AQih77GNdHAZNMthxO+1XO0qraQPTZ3SZPBKWhtVjW9hWhPjcM00pX X-Developer-Key: i=Frank.Li@nxp.com; a=ed25519; pk=I0L1sDUfPxpAkRvPKy7MdauTuSENRq+DnA+G4qcS94Q= X-Endpoint-Received: by B4 Relay for Frank.Li@nxp.com/20240130 with auth_id=121 X-Original-From: Frank Li Reply-To: Frank.Li@nxp.com From: Alice Yuan Add a V4L2 sub-device driver for the parallel CSI controller found on i.MX8QXP, i.MX8QM, and i.MX93 SoCs. This controller supports parallel camera sensors and enables image data capture through a parallel interface. Signed-off-by: Alice Yuan Signed-off-by: Robert Chiras Signed-off-by: Zhipeng Wang Signed-off-by: Frank Li --- change in v2 - remove MODULE_ALIAS - use devm_pm_runtime_enable() and cleanup remove function - change output format to 1x16. controller convert 2x8 to 1x16 format --- MAINTAINERS | 1 + drivers/media/platform/nxp/Kconfig | 11 + drivers/media/platform/nxp/Makefile | 1 + drivers/media/platform/nxp/imx-parallel-csi.c | 944 ++++++++++++++++++++++= ++++ 4 files changed, 957 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 8ae0667d2bb41fb6a1549bd3b2b33f326cbd1303..d936d15269344023afbc36ecadf= 77d66655bbac0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -15112,6 +15112,7 @@ F: Documentation/devicetree/bindings/media/nxp,imx-= mipi-csi2.yaml F: Documentation/devicetree/bindings/media/nxp,imx7-csi.yaml F: Documentation/devicetree/bindings/media/nxp,imx8mq-mipi-csi2.yaml F: drivers/media/platform/nxp/imx-mipi-csis.c +F: drivers/media/platform/nxp/imx-parallel-csi.c F: drivers/media/platform/nxp/imx7-media-csi.c F: drivers/media/platform/nxp/imx8mq-mipi-csi2.c =20 diff --git a/drivers/media/platform/nxp/Kconfig b/drivers/media/platform/nx= p/Kconfig index 40e3436669e213fdc5da70821dc0b420e1821f4f..5df6f97d16f294875e40716985b= ae0d893345bdd 100644 --- a/drivers/media/platform/nxp/Kconfig +++ b/drivers/media/platform/nxp/Kconfig @@ -39,6 +39,17 @@ config VIDEO_IMX_MIPI_CSIS Video4Linux2 sub-device driver for the MIPI CSI-2 CSIS receiver v3.3/v3.6.3 found on some i.MX7 and i.MX8 SoCs. =20 +config VIDEO_IMX_PARALLEL_CSI + tristate "NXP i.MX9/i.MX8 Parallel CSI Driver" + depends on ARCH_MXC || COMPILE_TEST + depends on VIDEO_DEV + select MEDIA_CONTROLLER + select V4L2_FWNODE + select VIDEO_V4L2_SUBDEV_API + help + Video4Linux2 sub-device driver for PARALLEL CSI receiver found + on some iMX8 and iMX9 SoCs. + source "drivers/media/platform/nxp/imx8-isi/Kconfig" =20 # mem2mem drivers diff --git a/drivers/media/platform/nxp/Makefile b/drivers/media/platform/n= xp/Makefile index 4d90eb71365259ebdda84ea58483e1c4131d3ac7..076592c58575cb6550ba824f2a1= 0fed4410cb8cf 100644 --- a/drivers/media/platform/nxp/Makefile +++ b/drivers/media/platform/nxp/Makefile @@ -7,5 +7,6 @@ obj-y +=3D imx8-isi/ obj-$(CONFIG_VIDEO_IMX7_CSI) +=3D imx7-media-csi.o obj-$(CONFIG_VIDEO_IMX8MQ_MIPI_CSI2) +=3D imx8mq-mipi-csi2.o obj-$(CONFIG_VIDEO_IMX_MIPI_CSIS) +=3D imx-mipi-csis.o +obj-$(CONFIG_VIDEO_IMX_PARALLEL_CSI) +=3D imx-parallel-csi.o obj-$(CONFIG_VIDEO_IMX_PXP) +=3D imx-pxp.o obj-$(CONFIG_VIDEO_MX2_EMMAPRP) +=3D mx2_emmaprp.o diff --git a/drivers/media/platform/nxp/imx-parallel-csi.c b/drivers/media/= platform/nxp/imx-parallel-csi.c new file mode 100644 index 0000000000000000000000000000000000000000..1567739e68a2a8afc58b42e836c= 5b9a936af1cf5 --- /dev/null +++ b/drivers/media/platform/nxp/imx-parallel-csi.c @@ -0,0 +1,944 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * i.MX Parallel CSI receiver driver. + * + * Copyright 2019-2025 NXP + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#define PARALLEL_CSI_DEF_MBUS_CODE MEDIA_BUS_FMT_UYVY8_2X8 +#define PARALLEL_CSI_DEF_PIX_WIDTH 1920 +#define PARALLEL_CSI_DEF_PIX_HEIGHT 1080 + +#define PARALLEL_CSI_MAX_PIX_WIDTH 0xffff +#define PARALLEL_CSI_MAX_PIX_HEIGHT 0xffff + +#define CI_PI_BASE_OFFSET 0x0 + +#define PARALLEL_CSI_PAD_SINK 0 +#define PARALLEL_CSI_PAD_SOURCE 1 +#define PARALLEL_CSI_PADS_NUM 2 + +/* CI_PI INTERFACE Control */ +#define IF_CTRL_REG_PL_ENABLE BIT(0) +#define IF_CTRL_REG_PL_VALID BIT(1) +#define IF_CTRL_REG_DATA_TYPE_SEL BIT(8) +#define IF_CTRL_REG_DATA_TYPE(x) FIELD_PREP(GENMASK(13, 9), (x)) + +#define DATA_TYPE_OUT_NULL 0x00 +#define DATA_TYPE_OUT_RGB 0x04 +#define DATA_TYPE_OUT_YUV444 0x08 +#define DATA_TYPE_OUT_YYU420_ODD 0x10 +#define DATA_TYPE_OUT_YYU420_EVEN 0x12 +#define DATA_TYPE_OUT_YYY_ODD 0x18 +#define DATA_TYPE_OUT_UYVY_EVEN 0x1a +#define DATA_TYPE_OUT_RAW 0x1c + +#define IF_CTRL_REG_IF_FORCE_HSYNV_OVERRIDE 0x4 +#define IF_CTRL_REG_IF_FORCE_VSYNV_OVERRIDE 0x2 +#define IF_CTRL_REG_IF_FORCE_DATA_ENABLE_OVERRIDE 0x1 + +/* CSI INTERFACE CONTROL REG */ +#define CSI_CTRL_REG_CSI_EN BIT(0) +#define CSI_CTRL_REG_PIXEL_CLK_POL BIT(1) +#define CSI_CTRL_REG_HSYNC_POL BIT(2) +#define CSI_CTRL_REG_VSYNC_POL BIT(3) +#define CSI_CTRL_REG_DE_POL BIT(4) +#define CSI_CTRL_REG_PIXEL_DATA_POL BIT(5) +#define CSI_CTRL_REG_CCIR_EXT_VSYNC_EN BIT(6) +#define CSI_CTRL_REG_CCIR_EN BIT(7) +#define CSI_CTRL_REG_CCIR_VIDEO_MODE BIT(8) +#define CSI_CTRL_REG_CCIR_NTSC_EN BIT(9) +#define CSI_CTRL_REG_CCIR_VSYNC_RESET_EN BIT(10) +#define CSI_CTRL_REG_CCIR_ECC_ERR_CORRECT_EN BIT(11) +#define CSI_CTRL_REG_HSYNC_FORCE_EN BIT(12) +#define CSI_CTRL_REG_VSYNC_FORCE_EN BIT(13) +#define CSI_CTRL_REG_GCLK_MODE_EN BIT(14) +#define CSI_CTRL_REG_VALID_SEL BIT(15) +#define CSI_CTRL_REG_RAW_OUT_SEL BIT(16) +#define CSI_CTRL_REG_HSYNC_OUT_SEL BIT(17) +#define CSI_CTRL_REG_HSYNC_PULSE(x) FIELD_PREP(GENMASK(21, 19), (x)) +#define CSI_CTRL_REG_UV_SWAP_EN BIT(22) +#define CSI_CTRL_REG_DATA_TYPE_IN(x) FIELD_PREP(GENMASK(26, 23), (x)) +#define CSI_CTRL_REG_MASK_VSYNC_COUNTER(x) FIELD_PREP(GENMASK(28, 27), (x)) +#define CSI_CTRL_REG_SOFTRST BIT(31) + +/* CSI interface Status */ +#define CSI_STATUS_FIELD_TOGGLE BIT(0) +#define CSI_STATUS_ECC_ERROR BIT(1) + +/* CSI INTERFACE CONTROL REG1 */ +#define CSI_CTRL_REG1_PIXEL_WIDTH(v) FIELD_PREP(GENMASK(15, 0), (v)) +#define CSI_CTRL_REG1_VSYNC_PULSE(v) FIELD_PREP(GENMASK(31, 16), (v)) + +/* Need match field DATA_TYPE_IN definition at CSI CTRL register */ +enum csi_in_data_type { + CSI_IN_DT_UYVY_BT656_8 =3D 0x0, + CSI_IN_DT_UYVY_BT656_10, + CSI_IN_DT_RGB_8, + CSI_IN_DT_BGR_8, + CSI_IN_DT_YVYU_8 =3D 0x5, + CSI_IN_DT_YUV_8, + CSI_IN_DT_RAW_8 =3D 0x9, + CSI_IN_DT_RAW_10, +}; + +enum { + PI_MODE_INIT, + PI_GATE_CLOCK_MODE, + PI_CCIR_MODE, +}; + +enum { + PI_V1, + PI_V2, +}; + +static const char *const parallel_csi_clk_id[] =3D { + "pixel", + "ipg", +}; + +#define PCSIDEV_NUM_CLKS ARRAY_SIZE(parallel_csi_clk_id) + +struct parallel_csi_plat_data { + u32 version; + u32 if_ctrl_reg; + u32 interface_status; + u32 interface_ctrl_reg; + u32 interface_ctrl_reg1; + u8 def_hsync_pol; + u8 def_vsync_pol; + u8 def_pixel_clk_pol; + u8 def_csi_in_data_type; +}; + +struct csi_pm_domain { + struct device *dev; + struct device_link *link; +}; + +struct parallel_csi_device { + struct device *dev; + void __iomem *regs; + struct reset_control *mrst; + struct regulator *pcsi_phy_regulator; + struct clk_bulk_data clks[PCSIDEV_NUM_CLKS]; + + struct v4l2_subdev sd; + struct media_pad pads[PARALLEL_CSI_PADS_NUM]; + struct v4l2_async_notifier notifier; + + struct v4l2_mbus_framefmt format; + const struct parallel_csi_plat_data *pdata; + struct parallel_csi_pix_format const *pcsidev_fmt; + + struct { + struct v4l2_subdev *sd; + const struct media_pad *pad; + } source; + + struct csi_pm_domain pm_domains[2]; + + u8 mode; + u8 uv_swap; +}; + +struct parallel_csi_pix_format { + u32 code; + u32 output; + u32 data_type; + u8 width; +}; + +static const struct parallel_csi_pix_format parallel_csi_formats[] =3D { + /* YUV formats. */ + { + .code =3D MEDIA_BUS_FMT_UYVY8_2X8, + .output =3D MEDIA_BUS_FMT_UYVY8_1X16, + .data_type =3D CSI_IN_DT_YVYU_8, + .width =3D 16, + }, { + .code =3D MEDIA_BUS_FMT_YUYV8_2X8, + .output =3D MEDIA_BUS_FMT_YUYV8_1X16, + .data_type =3D CSI_IN_DT_YVYU_8, + .width =3D 16, + }, +}; + +static const struct parallel_csi_plat_data imx8qxp_pdata =3D { + .version =3D PI_V1, + .if_ctrl_reg =3D 0x0, + .interface_status =3D 0x20, + .interface_ctrl_reg =3D 0x10, + .interface_ctrl_reg1 =3D 0x30, + .def_hsync_pol =3D 1, + .def_vsync_pol =3D 0, + .def_pixel_clk_pol =3D 0, + .def_csi_in_data_type =3D CSI_IN_DT_UYVY_BT656_8, +}; + +static const struct parallel_csi_plat_data imx93_pdata =3D { + .version =3D PI_V2, + .if_ctrl_reg =3D 0x0, + .interface_status =3D 0x4, + .interface_ctrl_reg =3D 0x8, + .interface_ctrl_reg1 =3D 0xc, + .def_hsync_pol =3D 0, + .def_vsync_pol =3D 1, + .def_pixel_clk_pol =3D 0, + .def_csi_in_data_type =3D CSI_IN_DT_YVYU_8, +}; + +static const struct parallel_csi_plat_data imx91_pdata =3D { + .version =3D PI_V2, + .if_ctrl_reg =3D 0x0, + .interface_status =3D 0x4, + .interface_ctrl_reg =3D 0x8, + .interface_ctrl_reg1 =3D 0xc, + .def_hsync_pol =3D 0, + .def_vsync_pol =3D 1, + .def_pixel_clk_pol =3D 0, + .def_csi_in_data_type =3D CSI_IN_DT_YVYU_8, +}; + +static void parallel_csi_regs_dump(struct parallel_csi_device *pcsidev) +{ + struct device *dev =3D pcsidev->dev; + const struct parallel_csi_plat_data *pdata =3D pcsidev->pdata; + u32 i; + + struct { + u32 offset; + const char *const name; + } registers[] =3D { + { pdata->if_ctrl_reg, "HW_IF_CTRL_REG" }, + { pdata->interface_ctrl_reg, "HW_CSI_CTRL_REG" }, + { pdata->interface_status, "HW_CSI_STATUS" }, + { pdata->interface_ctrl_reg1, "HW_CSI_CTRL_REG1" }, + + }; + + for (i =3D 0; i < ARRAY_SIZE(registers); i++) { + u32 reg =3D readl(pcsidev->regs + registers[i].offset); + + dev_dbg(dev, "%20s[0x%.2x]: 0x%.8x\n", + registers[i].name, registers[i].offset, reg); + } +} + +static const struct parallel_csi_pix_format *find_parallel_csi_format(u32 = code) +{ + unsigned int i; + + for (i =3D 0; i < ARRAY_SIZE(parallel_csi_formats); i++) + if (code =3D=3D parallel_csi_formats[i].code) + return ¶llel_csi_formats[i]; + + return NULL; +} + +static void parallel_csi_sw_reset(struct parallel_csi_device *pcsidev) +{ + const struct parallel_csi_plat_data *pdata =3D pcsidev->pdata; + u32 val; + + /* Softwaret Reset */ + val =3D readl(pcsidev->regs + pdata->interface_ctrl_reg); + val |=3D CSI_CTRL_REG_SOFTRST; + writel(val, pcsidev->regs + pdata->interface_ctrl_reg); + + usleep_range(500, 1000); + val =3D readl(pcsidev->regs + pdata->interface_ctrl_reg); + val &=3D ~CSI_CTRL_REG_SOFTRST; + writel(val, pcsidev->regs + pdata->interface_ctrl_reg); +} + +static void parallel_csi_hw_config(struct parallel_csi_device *pcsidev) +{ + const struct parallel_csi_plat_data *pdata =3D pcsidev->pdata; + u32 val; + + /* Software Reset */ + parallel_csi_sw_reset(pcsidev); + + /* Config PL Data Type */ + val =3D readl(pcsidev->regs + pdata->if_ctrl_reg); + val |=3D IF_CTRL_REG_DATA_TYPE(DATA_TYPE_OUT_YUV444); + writel(val, pcsidev->regs + pdata->if_ctrl_reg); + + /* Enable sync Force */ + val =3D readl(pcsidev->regs + pdata->interface_ctrl_reg); + val |=3D (CSI_CTRL_REG_HSYNC_FORCE_EN | CSI_CTRL_REG_VSYNC_FORCE_EN); + writel(val, pcsidev->regs + pdata->interface_ctrl_reg); + + /* Enable Pixel Link */ + val =3D readl(pcsidev->regs + pdata->if_ctrl_reg); + val |=3D IF_CTRL_REG_PL_ENABLE; + writel(val, pcsidev->regs + pdata->if_ctrl_reg); + + /* Enable Pixel Link */ + val =3D readl(pcsidev->regs + pdata->if_ctrl_reg); + val |=3D IF_CTRL_REG_PL_VALID; + writel(val, pcsidev->regs + pdata->if_ctrl_reg); + + /* Config CTRL REG */ + val =3D readl(pcsidev->regs + pdata->interface_ctrl_reg); + + val |=3D (CSI_CTRL_REG_DATA_TYPE_IN(pdata->def_csi_in_data_type) | + FIELD_PREP(CSI_CTRL_REG_HSYNC_POL, pdata->def_hsync_pol) | + FIELD_PREP(CSI_CTRL_REG_VSYNC_POL, pdata->def_vsync_pol) | + FIELD_PREP(CSI_CTRL_REG_PIXEL_CLK_POL, pdata->def_pixel_clk_pol) | + CSI_CTRL_REG_MASK_VSYNC_COUNTER(3) | + CSI_CTRL_REG_HSYNC_PULSE(2)); + + if (pcsidev->uv_swap) + val |=3D CSI_CTRL_REG_UV_SWAP_EN; + + if (pcsidev->mode & PI_GATE_CLOCK_MODE) { + val |=3D CSI_CTRL_REG_GCLK_MODE_EN; + } else if (pcsidev->mode & PI_CCIR_MODE) { + val |=3D (CSI_CTRL_REG_CCIR_EN | + CSI_CTRL_REG_CCIR_VSYNC_RESET_EN | + CSI_CTRL_REG_CCIR_EXT_VSYNC_EN | + CSI_CTRL_REG_CCIR_ECC_ERR_CORRECT_EN); + } + + writel(val, pcsidev->regs + pdata->interface_ctrl_reg); +} + +static int get_interface_ctrl_reg1_param(struct parallel_csi_device *pcsid= ev, + u32 *pixel_width, u32 *vsync_pulse, + const struct v4l2_mbus_framefmt *format) +{ + u32 version =3D pcsidev->pdata->version; + + switch (version) { + case PI_V1: + *pixel_width =3D format->width - 1; + *vsync_pulse =3D format->width << 1; + break; + case PI_V2: + *pixel_width =3D format->width << 3; + *vsync_pulse =3D format->width - 1; + break; + default: + dev_err(pcsidev->dev, "Not support PI version %d\n", version); + return -EINVAL; + } + + return 0; +} + +static void parallel_csi_config_ctrl_reg1(struct parallel_csi_device *pcsi= dev, + const struct v4l2_mbus_framefmt *format) +{ + const struct parallel_csi_plat_data *pdata =3D pcsidev->pdata; + struct device *dev =3D pcsidev->dev; + u32 pixel_width; + u32 vsync_pulse; + u32 val; + int ret; + + dev_dbg(dev, "%s %dx%d, fmt->code:0x%0x\n", __func__, + format->width, format->height, format->code); + + if (format->width <=3D 0 || format->height <=3D 0) { + dev_err(dev, "%s width/height invalid\n", __func__); + return; + } + + ret =3D get_interface_ctrl_reg1_param(pcsidev, &pixel_width, + &vsync_pulse, format); + if (ret < 0) + return; + + val =3D (CSI_CTRL_REG1_PIXEL_WIDTH(pixel_width) | + CSI_CTRL_REG1_VSYNC_PULSE(vsync_pulse)); + writel(val, pcsidev->regs + pdata->interface_ctrl_reg1); +} + +static void parallel_csi_enable(struct parallel_csi_device *pcsidev) +{ + const struct parallel_csi_plat_data *pdata =3D pcsidev->pdata; + u32 val; + + /* Enable CSI */ + val =3D readl(pcsidev->regs + pdata->interface_ctrl_reg); + val |=3D CSI_CTRL_REG_CSI_EN; + writel(val, pcsidev->regs + pdata->interface_ctrl_reg); + + /* Disable SYNC Force */ + val =3D readl(pcsidev->regs + pdata->interface_ctrl_reg); + val &=3D ~(CSI_CTRL_REG_HSYNC_FORCE_EN | CSI_CTRL_REG_VSYNC_FORCE_EN); + writel(val, pcsidev->regs + pdata->interface_ctrl_reg); +} + +static void parallel_csi_disable(struct parallel_csi_device *pcsidev) +{ + const struct parallel_csi_plat_data *pdata =3D pcsidev->pdata; + u32 val; + + /* Enable Sync Force */ + val =3D readl(pcsidev->regs + pdata->interface_ctrl_reg); + val |=3D (CSI_CTRL_REG_HSYNC_FORCE_EN | CSI_CTRL_REG_VSYNC_FORCE_EN); + writel(val, pcsidev->regs + pdata->interface_ctrl_reg); + + /* Disable CSI */ + val =3D readl(pcsidev->regs + pdata->interface_ctrl_reg); + val &=3D ~CSI_CTRL_REG_CSI_EN; + writel(val, pcsidev->regs + pdata->interface_ctrl_reg); + + /* Disable Pixel Link */ + val =3D readl(pcsidev->regs + pdata->if_ctrl_reg); + val &=3D ~(IF_CTRL_REG_PL_VALID | IF_CTRL_REG_PL_ENABLE); + writel(val, pcsidev->regs + pdata->if_ctrl_reg); +} + +static void parallel_csi_start_stream(struct parallel_csi_device *pcsidev, + const struct v4l2_mbus_framefmt *format, + const struct parallel_csi_pix_format *pcsidev_fmt) +{ + if (pcsidev_fmt->code =3D=3D MEDIA_BUS_FMT_YUYV8_2X8 || + pcsidev_fmt->code =3D=3D MEDIA_BUS_FMT_UYVY8_2X8) + pcsidev->uv_swap =3D 1; + + parallel_csi_hw_config(pcsidev); + parallel_csi_config_ctrl_reg1(pcsidev, format); + parallel_csi_enable(pcsidev); + parallel_csi_regs_dump(pcsidev); +} + +static void parallel_csi_stop_stream(struct parallel_csi_device *pcsidev) +{ + parallel_csi_regs_dump(pcsidev); + parallel_csi_disable(pcsidev); +} + +/* -----------------------------------------------------------------------= ------ + * Async subdev notifier + */ + +static struct parallel_csi_device * +notifier_to_parallel_csi_device(struct v4l2_async_notifier *n) +{ + return container_of(n, struct parallel_csi_device, notifier); +} + +static struct parallel_csi_device * +sd_to_parallel_csi_device(struct v4l2_subdev *sdev) +{ + return container_of(sdev, struct parallel_csi_device, sd); +} + +static int parallel_csi_notify_bound(struct v4l2_async_notifier *notifier, + struct v4l2_subdev *sd, + struct v4l2_async_connection *asd) +{ + struct parallel_csi_device *pcsidev =3D notifier_to_parallel_csi_device(n= otifier); + struct media_pad *sink =3D &pcsidev->sd.entity.pads[PARALLEL_CSI_PAD_SINK= ]; + + return v4l2_create_fwnode_links_to_pad(sd, sink, 0); +} + +static const struct v4l2_async_notifier_operations parallel_csi_notify_ops= =3D { + .bound =3D parallel_csi_notify_bound, +}; + +static int parallel_csi_async_register(struct parallel_csi_device *pcsidev) +{ + struct v4l2_fwnode_endpoint vep =3D { + .bus_type =3D V4L2_MBUS_PARALLEL, + }; + struct v4l2_async_connection *asd; + struct fwnode_handle *ep; + int ret; + + v4l2_async_subdev_nf_init(&pcsidev->notifier, &pcsidev->sd); + + ep =3D fwnode_graph_get_endpoint_by_id(dev_fwnode(pcsidev->dev), 0, 0, + FWNODE_GRAPH_ENDPOINT_NEXT); + if (!ep) + return -ENOTCONN; + + ret =3D v4l2_fwnode_endpoint_parse(ep, &vep); + if (ret) + goto err_parse; + + asd =3D v4l2_async_nf_add_fwnode_remote(&pcsidev->notifier, ep, + struct v4l2_async_connection); + if (IS_ERR(asd)) { + ret =3D PTR_ERR(asd); + goto err_parse; + } + + fwnode_handle_put(ep); + + pcsidev->notifier.ops =3D ¶llel_csi_notify_ops; + ret =3D v4l2_async_nf_register(&pcsidev->notifier); + if (ret) + return ret; + + return v4l2_async_register_subdev(&pcsidev->sd); + +err_parse: + fwnode_handle_put(ep); + + return ret; +} + +/* -----------------------------------------------------------------------= ------ + * Media entity operations + */ + +static int parallel_csi_link_setup(struct media_entity *entity, + const struct media_pad *local_pad, + const struct media_pad *remote_pad, + u32 flags) +{ + struct v4l2_subdev *sd =3D media_entity_to_v4l2_subdev(entity); + struct parallel_csi_device *pcsidev =3D sd_to_parallel_csi_device(sd); + struct v4l2_subdev *remote_sd; + + dev_dbg(pcsidev->dev, "link setup %s -> %s", remote_pad->entity->name, + local_pad->entity->name); + + /* We only care about the link to the source. */ + if (!(local_pad->flags & MEDIA_PAD_FL_SINK)) + return 0; + + remote_sd =3D media_entity_to_v4l2_subdev(remote_pad->entity); + if (flags & MEDIA_LNK_FL_ENABLED) { + if (pcsidev->source.sd) + return -EBUSY; + + pcsidev->source.sd =3D remote_sd; + pcsidev->source.pad =3D remote_pad; + } else { + pcsidev->source.sd =3D NULL; + pcsidev->source.pad =3D NULL; + } + + return 0; +} + +static const struct media_entity_operations parallel_csi_entity_ops =3D { + .link_setup =3D parallel_csi_link_setup, + .link_validate =3D v4l2_subdev_link_validate, + .get_fwnode_pad =3D v4l2_subdev_get_fwnode_pad_1_to_1, +}; + +static int parallel_csi_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_format *sdformat) +{ + struct parallel_csi_pix_format const *pcsidev_fmt; + struct parallel_csi_device *pcsidev =3D sd_to_parallel_csi_device(sd); + struct device *dev =3D pcsidev->dev; + struct v4l2_mbus_framefmt *fmt; + unsigned int align; + + /* + * The Parallel csi can't transcode in any way, the source format + * can't be modified. + */ + if (sdformat->pad =3D=3D PARALLEL_CSI_PAD_SOURCE) + return v4l2_subdev_get_fmt(sd, sd_state, sdformat); + + /* + * Validate the media bus code and clamp and align the size. + * + * The total number of bits per line must be a multiple of 8. We thus + * need to align the width for formats that are not multiples of 8 + * bits. + */ + pcsidev_fmt =3D find_parallel_csi_format(sdformat->format.code); + if (!pcsidev_fmt) + pcsidev_fmt =3D ¶llel_csi_formats[0]; + + switch (pcsidev_fmt->width % 8) { + case 0: + align =3D 0; + break; + case 4: + align =3D 1; + break; + case 2: + case 6: + align =3D 2; + break; + default: + /* 1, 3, 5, 7 */ + align =3D 3; + break; + } + + v4l_bound_align_image(&sdformat->format.width, 1, + PARALLEL_CSI_MAX_PIX_WIDTH, align, + &sdformat->format.height, 1, + PARALLEL_CSI_MAX_PIX_HEIGHT, 0, 0); + + fmt =3D v4l2_subdev_state_get_format(sd_state, sdformat->pad); + if (!fmt) + return -EINVAL; + + fmt->code =3D pcsidev_fmt->code; + fmt->width =3D sdformat->format.width; + fmt->height =3D sdformat->format.height; + fmt->field =3D V4L2_FIELD_NONE; + fmt->colorspace =3D sdformat->format.colorspace; + fmt->quantization =3D sdformat->format.quantization; + fmt->xfer_func =3D sdformat->format.xfer_func; + fmt->ycbcr_enc =3D sdformat->format.ycbcr_enc; + + sdformat->format =3D *fmt; + + /* Propagate the format from sink to source. */ + fmt =3D v4l2_subdev_state_get_format(sd_state, PARALLEL_CSI_PAD_SOURCE); + *fmt =3D sdformat->format; + + /* The format on the source pad might change due to unpacking. */ + fmt->code =3D pcsidev_fmt->output; + + dev_dbg(dev, "%s: fmt_code:0x%0x, %dx%d\n", __func__, + fmt->code, fmt->width, fmt->height); + return 0; +} + +static const struct v4l2_mbus_framefmt parallel_csi_default_fmt =3D { + .code =3D PARALLEL_CSI_DEF_MBUS_CODE, + .width =3D PARALLEL_CSI_DEF_PIX_WIDTH, + .height =3D PARALLEL_CSI_DEF_PIX_HEIGHT, + .field =3D V4L2_FIELD_NONE, + .colorspace =3D V4L2_COLORSPACE_SMPTE170M, + .xfer_func =3D V4L2_MAP_XFER_FUNC_DEFAULT(V4L2_COLORSPACE_SMPTE170M), + .ycbcr_enc =3D V4L2_MAP_YCBCR_ENC_DEFAULT(V4L2_COLORSPACE_SMPTE170M), + .quantization =3D V4L2_QUANTIZATION_LIM_RANGE, +}; + +static int parallel_csi_init_state(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state) +{ + struct v4l2_subdev_format fmt =3D { + .pad =3D PARALLEL_CSI_PAD_SINK, + }; + + fmt.format.code =3D parallel_csi_formats[0].code; + fmt.format.width =3D PARALLEL_CSI_DEF_PIX_WIDTH; + fmt.format.height =3D PARALLEL_CSI_DEF_PIX_HEIGHT; + + fmt.format.colorspace =3D V4L2_COLORSPACE_SMPTE170M; + fmt.format.xfer_func =3D + V4L2_MAP_XFER_FUNC_DEFAULT(fmt.format.colorspace); + fmt.format.ycbcr_enc =3D + V4L2_MAP_YCBCR_ENC_DEFAULT(fmt.format.colorspace); + fmt.format.quantization =3D + V4L2_MAP_QUANTIZATION_DEFAULT(false, + fmt.format.colorspace, + fmt.format.ycbcr_enc); + + return parallel_csi_set_fmt(sd, sd_state, &fmt); +} + +static int parallel_csi_s_stream(struct v4l2_subdev *sd, int enable) +{ + struct parallel_csi_device *pcsidev =3D sd_to_parallel_csi_device(sd); + const struct v4l2_mbus_framefmt *format; + const struct parallel_csi_pix_format *pcsidev_fmt; + struct v4l2_subdev_state *state; + int ret; + + if (!enable) { + v4l2_subdev_disable_streams(pcsidev->source.sd, + pcsidev->source.pad->index, BIT(0)); + + parallel_csi_stop_stream(pcsidev); + + pm_runtime_put(pcsidev->dev); + + return 0; + } + + state =3D v4l2_subdev_lock_and_get_active_state(sd); + format =3D v4l2_subdev_state_get_format(state, PARALLEL_CSI_PAD_SINK); + pcsidev_fmt =3D find_parallel_csi_format(format->code); + + ret =3D pm_runtime_resume_and_get(pcsidev->dev); + if (ret < 0) + goto err_unlock; + + parallel_csi_start_stream(pcsidev, format, pcsidev_fmt); + + ret =3D v4l2_subdev_enable_streams(pcsidev->source.sd, + pcsidev->source.pad->index, BIT(0)); + if (ret < 0) + goto err_stop; + + v4l2_subdev_unlock_state(state); + + return 0; + +err_stop: + parallel_csi_stop_stream(pcsidev); + pm_runtime_put(pcsidev->dev); +err_unlock: + v4l2_subdev_unlock_state(state); + return ret; +} + +static int parallel_csi_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_mbus_code_enum *code) +{ + /* + * The PARALLEL CSI can't transcode in any way, the source format + * is identical to the sink format. + */ + if (code->pad =3D=3D PARALLEL_CSI_PAD_SOURCE) { + struct v4l2_mbus_framefmt *fmt; + + if (code->index > 0) + return -EINVAL; + + fmt =3D v4l2_subdev_state_get_format(sd_state, code->pad); + code->code =3D fmt->code; + return 0; + } + + if (code->pad !=3D PARALLEL_CSI_PAD_SINK) + return -EINVAL; + + if (code->index >=3D ARRAY_SIZE(parallel_csi_formats)) + return -EINVAL; + + code->code =3D parallel_csi_formats[code->index].code; + + return 0; +} + +static int parallel_csi_get_frame_desc(struct v4l2_subdev *sd, + unsigned int pad, + struct v4l2_mbus_frame_desc *fd) +{ + struct v4l2_mbus_frame_desc_entry *entry =3D &fd->entry[0]; + const struct parallel_csi_pix_format *pcsidev_fmt; + const struct v4l2_mbus_framefmt *fmt; + struct v4l2_subdev_state *state; + + if (pad !=3D PARALLEL_CSI_PAD_SOURCE) + return -EINVAL; + + state =3D v4l2_subdev_lock_and_get_active_state(sd); + fmt =3D v4l2_subdev_state_get_format(state, PARALLEL_CSI_PAD_SOURCE); + pcsidev_fmt =3D find_parallel_csi_format(fmt->code); + v4l2_subdev_unlock_state(state); + + if (!pcsidev_fmt) + return -EPIPE; + + fd->type =3D V4L2_MBUS_FRAME_DESC_TYPE_PARALLEL; + fd->num_entries =3D 1; + + entry->flags =3D 0; + entry->pixelcode =3D pcsidev_fmt->code; + + return 0; +} + +static const struct v4l2_subdev_video_ops parallel_csi_video_ops =3D { + .s_stream =3D parallel_csi_s_stream, +}; + +static const struct v4l2_subdev_pad_ops parallel_csi_pad_ops =3D { + .enum_mbus_code =3D parallel_csi_enum_mbus_code, + .get_fmt =3D v4l2_subdev_get_fmt, + .set_fmt =3D parallel_csi_set_fmt, + .get_frame_desc =3D parallel_csi_get_frame_desc, +}; + +static const struct v4l2_subdev_ops parallel_csi_subdev_ops =3D { + .pad =3D ¶llel_csi_pad_ops, + .video =3D ¶llel_csi_video_ops, +}; + +static const struct v4l2_subdev_internal_ops parallel_csi_internal_ops =3D= { + .init_state =3D parallel_csi_init_state, +}; + +static int parallel_csi_clk_get(struct parallel_csi_device *pcsidev) +{ + unsigned int i; + int ret =3D 0; + + for (i =3D 0; i < PCSIDEV_NUM_CLKS; i++) + pcsidev->clks[i].id =3D parallel_csi_clk_id[i]; + + ret =3D devm_clk_bulk_get(pcsidev->dev, PCSIDEV_NUM_CLKS, pcsidev->clks); + + return ret; +} + +/* ---------------------------------------------------------------------- + * Suspend/resume + */ +static int __maybe_unused parallel_csi_runtime_suspend(struct device *dev) +{ + struct v4l2_subdev *sd =3D dev_get_drvdata(dev); + struct parallel_csi_device *pcsidev =3D sd_to_parallel_csi_device(sd); + + clk_bulk_disable_unprepare(PCSIDEV_NUM_CLKS, pcsidev->clks); + + return 0; +} + +static int __maybe_unused parallel_csi_runtime_resume(struct device *dev) +{ + struct v4l2_subdev *sd =3D dev_get_drvdata(dev); + struct parallel_csi_device *pcsidev =3D sd_to_parallel_csi_device(sd); + + return clk_bulk_prepare_enable(PCSIDEV_NUM_CLKS, pcsidev->clks); +} + +static const struct dev_pm_ops parallel_csi_pm_ops =3D { + RUNTIME_PM_OPS(parallel_csi_runtime_suspend, parallel_csi_runtime_resume,= NULL) +}; + +static int parallel_csi_subdev_init(struct parallel_csi_device *pcsidev) +{ + struct v4l2_subdev *sd =3D &pcsidev->sd; + int ret; + + v4l2_subdev_init(sd, ¶llel_csi_subdev_ops); + + sd->internal_ops =3D ¶llel_csi_internal_ops; + sd->owner =3D THIS_MODULE; + snprintf(sd->name, sizeof(sd->name), "parallel-%s", + dev_name(pcsidev->dev)); + + sd->flags |=3D V4L2_SUBDEV_FL_HAS_DEVNODE; + sd->ctrl_handler =3D NULL; + + sd->entity.function =3D MEDIA_ENT_F_VID_IF_BRIDGE; + sd->entity.ops =3D ¶llel_csi_entity_ops; + + sd->dev =3D pcsidev->dev; + + pcsidev->pads[PARALLEL_CSI_PAD_SINK].flags =3D MEDIA_PAD_FL_SINK | MEDIA_= PAD_FL_MUST_CONNECT; + pcsidev->pads[PARALLEL_CSI_PAD_SOURCE].flags =3D MEDIA_PAD_FL_SOURCE | + MEDIA_PAD_FL_MUST_CONNECT; + + ret =3D media_entity_pads_init(&sd->entity, PARALLEL_CSI_PADS_NUM, pcside= v->pads); + if (ret) + return ret; + + ret =3D v4l2_subdev_init_finalize(sd); + if (ret) + media_entity_cleanup(&sd->entity); + + return ret; +} + +static void parallel_csi_cleanup(void *data) +{ + struct parallel_csi_device *pcsidev =3D data; + + v4l2_subdev_cleanup(&pcsidev->sd); + media_entity_cleanup(&pcsidev->sd.entity); + v4l2_async_nf_unregister(&pcsidev->notifier); + v4l2_async_nf_cleanup(&pcsidev->notifier); + v4l2_async_unregister_subdev(&pcsidev->sd); +} + +static int parallel_csi_probe(struct platform_device *pdev) +{ + struct parallel_csi_device *pcsidev; + struct device *dev =3D &pdev->dev; + int ret =3D 0; + + pcsidev =3D devm_kzalloc(dev, sizeof(*pcsidev), GFP_KERNEL); + if (!pcsidev) + return -ENOMEM; + + pcsidev->dev =3D dev; + platform_set_drvdata(pdev, pcsidev); + + pcsidev->pdata =3D of_device_get_match_data(dev); + + pcsidev->regs =3D devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(pcsidev->regs)) + return dev_err_probe(dev, PTR_ERR(pcsidev->regs), + "Failed to get regs\n"); + + ret =3D parallel_csi_clk_get(pcsidev); + if (ret < 0) + return ret; + + ret =3D parallel_csi_subdev_init(pcsidev); + if (ret < 0) + return ret; + + ret =3D devm_add_action_or_reset(dev, parallel_csi_cleanup, pcsidev); + if (ret) + return ret; + + pcsidev->mode =3D PI_GATE_CLOCK_MODE; + + platform_set_drvdata(pdev, &pcsidev->sd); + + ret =3D parallel_csi_async_register(pcsidev); + if (ret < 0) + return ret; + + devm_pm_runtime_enable(dev); + + return 0; +} + +static const struct of_device_id _of_match[] =3D { + {.compatible =3D "fsl,imx8qxp-pcif", .data =3D &imx8qxp_pdata }, + {.compatible =3D "fsl,imx91-pcif", .data =3D &imx91_pdata }, + {.compatible =3D "fsl,imx93-pcif", .data =3D &imx93_pdata }, + { }, +}; + +MODULE_DEVICE_TABLE(of, _of_match); + +static struct platform_driver _driver =3D { + .probe =3D parallel_csi_probe, + .driver =3D { + .of_match_table =3D _of_match, + .name =3D "imx-parallel-csi", + .pm =3D pm_ptr(¶llel_csi_pm_ops), + }, +}; + +module_platform_driver(_driver); + +MODULE_DESCRIPTION("i.MX9 Parallel CSI receiver driver"); +MODULE_LICENSE("GPL"); --=20 2.34.1 From nobody Wed Oct 8 00:42:34 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 3366228A3E2; Thu, 3 Jul 2025 18:33:12 +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=1751567593; cv=none; b=ZSnCxJ5OuRLeq154Gur+yqeBBl0B3fDGzVj1DhWJIfP3VJ7vjf2/2wJVlT1F8Vrdd0Gzh2ovzunfT9eoJNOex6MyBt8mxnn+W0ScRXPKR6qPu21b5OxCyAwe+qO9sz28VDENV0c7NHRvtRN66xe87qDIR/JfsO4jxMo5CYk/vms= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751567593; c=relaxed/simple; bh=lnATMb/XmCNNMy1igSdCLxsZP2Vd/a/i5coedasJ6Ec=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=RiFznfOxZn+ZcrMocce+s2D9803ISFSvahxuJshF2ubWiAL5iRHbkiOhAR2vlGONqMgToDHCJNJbXNW56FuFudtVhfqJOL4HzW5Rl2B1/MvEIXQ7+iPdEN7ozh9IQIKtT1wxeZUjhNpxD1RtvqiJK1Q+VnlWJ91dgqMu02cL9/M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=qwwzqZjc; 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="qwwzqZjc" Received: by smtp.kernel.org (Postfix) with ESMTPS id C0AAAC4AF09; Thu, 3 Jul 2025 18:33:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1751567592; bh=lnATMb/XmCNNMy1igSdCLxsZP2Vd/a/i5coedasJ6Ec=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=qwwzqZjcKtOl8/553fhUXtGV5cSS+O56najS82u0rLCWI5zFaQwv7KxGgmdECxS3U s2dkH5ydHtL1Xrb/O4ydhNxlIcwhLzhYLJEK75Yudxr95MZRHdFMyT/FH9aUq9OYtZ Lj4Gc4ESm9tQ1RCKRSeY1bmk/iF/oZbLqowhr0TVgrcBPr3mO3xtn/yXtcB6Yhy3nX y4mbGrRkH7p8JaNBQ/TAhSYiX5iVSecnD78N1MfwLRCfWx/CTGTRCiZG3+d05TPVlk OhIMHdeNtrbFiHQBTfgXD3J1C3AYtEEohNsePKJiThhvWfLsAZoJn7yGtefFj2E0sR /35+V/uFd7Edg== 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 AF646C83F0A; Thu, 3 Jul 2025 18:33:12 +0000 (UTC) From: Frank Li via B4 Relay Date: Thu, 03 Jul 2025 14:33:08 -0400 Subject: [PATCH v2 3/4] arm64: dts: imx8: add parallel CSI node 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: <20250703-imx8qxp_pcam-v2-3-188be85f06f1@nxp.com> References: <20250703-imx8qxp_pcam-v2-0-188be85f06f1@nxp.com> In-Reply-To: <20250703-imx8qxp_pcam-v2-0-188be85f06f1@nxp.com> To: Laurent Pinchart , Mauro Carvalho Chehab , Shawn Guo , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam , Rui Miguel Silva , Martin Kepplinger , Purism Kernel Team , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Philipp Zabel Cc: linux-media@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Frank Li X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1751567591; l=2229; i=Frank.Li@nxp.com; s=20240130; h=from:subject:message-id; bh=egvyIYm9Ny7RwG4VqCUmjTBkLSU8NimkbRJ5GJUfMCg=; b=0DiK8tKXGe724gjHRzMZk45Ar6ghYBLBifnXK2kF2u5SRCj3q649yBEdL/Rg9kJnjnsrMYMyP KvscQ92k649AaIVhdfok6kql5Di1O3TLWV46TiUjkLyRHXO0YE1oDIc X-Developer-Key: i=Frank.Li@nxp.com; a=ed25519; pk=I0L1sDUfPxpAkRvPKy7MdauTuSENRq+DnA+G4qcS94Q= X-Endpoint-Received: by B4 Relay for Frank.Li@nxp.com/20240130 with auth_id=121 X-Original-From: Frank Li Reply-To: Frank.Li@nxp.com From: Frank Li Add parallel CSI nodes. Signed-off-by: Frank Li --- changes in v2 - update compatible string to match binding's change --- arch/arm64/boot/dts/freescale/imx8-ss-img.dtsi | 13 +++++++++++ arch/arm64/boot/dts/freescale/imx8qxp-ss-img.dtsi | 27 +++++++++++++++++++= ++++ 2 files changed, 40 insertions(+) diff --git a/arch/arm64/boot/dts/freescale/imx8-ss-img.dtsi b/arch/arm64/bo= ot/dts/freescale/imx8-ss-img.dtsi index 2cf0f7208350a416d77b11140279d2f66f41498f..1f7bf9efdbca266fbda82d2bc84= acd9a27ed0bd1 100644 --- a/arch/arm64/boot/dts/freescale/imx8-ss-img.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8-ss-img.dtsi @@ -224,6 +224,19 @@ irqsteer_parallel: irqsteer@58260000 { status =3D "disabled"; }; =20 + parallel_csi: csi@58261000 { + compatible =3D "fsl,imx8qxp-pcif"; + reg =3D <0x58261000 0x1000>; + clocks =3D <&pi0_pxl_lpcg IMX_LPCG_CLK_0>, + <&pi0_ipg_lpcg IMX_LPCG_CLK_4>; + clock-names =3D "pixel", "ipg"; + assigned-clocks =3D <&clk IMX_SC_R_PI_0 IMX_SC_PM_CLK_PER>; + assigned-clock-parents =3D <&clk IMX_SC_R_PI_0_PLL IMX_SC_PM_CLK_PLL>; + assigned-clock-rates =3D <160000000>; + power-domains =3D <&pd IMX_SC_R_PI_0>; + status =3D "disabled"; + }; + pi0_ipg_lpcg: clock-controller@58263004 { compatible =3D "fsl,imx8qxp-lpcg"; reg =3D <0x58263004 0x4>; diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-ss-img.dtsi b/arch/arm64= /boot/dts/freescale/imx8qxp-ss-img.dtsi index 50015f8dd4e43b507c879479e7320cb58ec8bf74..60aa43c45d15c8b0c2c425be52e= d79458d8c96b9 100644 --- a/arch/arm64/boot/dts/freescale/imx8qxp-ss-img.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8qxp-ss-img.dtsi @@ -62,6 +62,14 @@ isi_in_2: endpoint { remote-endpoint =3D <&mipi_csi0_out>; }; }; + + port@4 { + reg =3D <4>; + + isi_in_4: endpoint { + remote-endpoint =3D <¶llel_csi_out>; + }; + }; }; }; =20 @@ -94,3 +102,22 @@ &jpegenc { &mipi_csi_1 { status =3D "disabled"; }; + +¶llel_csi { + ports { + #address-cells =3D <1>; + #size-cells =3D <0>; + + port@0 { + reg =3D <0>; + }; + + port@1 { + reg =3D <1>; + + parallel_csi_out: endpoint { + remote-endpoint =3D <&isi_in_4>; + }; + }; + }; +}; --=20 2.34.1 From nobody Wed Oct 8 00:42:34 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 335F428A1EE; Thu, 3 Jul 2025 18:33:12 +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=1751567593; cv=none; b=XTvC75xS2g/ZJdV2khTMT6rSVzMlrnLucZi0aYcEksqI09gvGcyJi4l0b0Us0u/O2jifXWtS4RGDqTx0T+Up33HGX5BAK5m6ySCktjiVxaPf34rVDStoUNBFhwYddFXYPnFDhWpy8xgdofxyU/I3Q/kyiVpuyfHWtun2lG8Md/8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751567593; c=relaxed/simple; bh=twKLCDvgvJ4N3es1zViUdUytVpc1yuuskuyBdmZ+9lY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=GR049/tMCV8+9qE0wbT/+SX+1PmTfjBCLYtV0JBGjapNXYCecgXm1FQldyDdQOWk8k7k0yAzTkXC8KqDaDfx5eCfABgZ5/EHIx+gQHyVeTZsKI26mCqjR6Hkr/wb9HWH5X1eTYFowt67f2e6mB+er/Xn1+n4tLfeLt7f9HaifcU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=R9uvwg7H; 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="R9uvwg7H" Received: by smtp.kernel.org (Postfix) with ESMTPS id C5E7FC4AF0B; Thu, 3 Jul 2025 18:33:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1751567592; bh=twKLCDvgvJ4N3es1zViUdUytVpc1yuuskuyBdmZ+9lY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=R9uvwg7H/tZrWUiU2XNSphV19N7RZhq3VTIpr7RkePXVvXiuqfSjEbdEzy1u3/L8b BFLr0DNU/yhCT7/1IUGjYrZD/H05T7tEsS0jatIK1XXfmfDWAUPuGGBDy8c23cOExj 99fYWcPpD/ie3wppt3cOBlDSeYIDsq3Hr+XpZ2pZ6oILdUhX5+oqPnhX2yZNxn9iKM cDxSZ9sAdczy71F/0yRRIpGi10PELYcwYHEwGh61oXrPqdUz1J0KtPNjV7NBnE43JE TwJk1hGaFpCJt7EdrJ0AVHb6dA0HIynhRAO3yFkVg9dZmdIUzqjuQ8/ajijWxBMs1n aLjKhv9aeVDcg== 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 BD1BBC83F05; Thu, 3 Jul 2025 18:33:12 +0000 (UTC) From: Frank Li via B4 Relay Date: Thu, 03 Jul 2025 14:33:09 -0400 Subject: [PATCH v2 4/4] arm64: dts: imx8qxp-mek: add parallel ov5640 camera support 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: <20250703-imx8qxp_pcam-v2-4-188be85f06f1@nxp.com> References: <20250703-imx8qxp_pcam-v2-0-188be85f06f1@nxp.com> In-Reply-To: <20250703-imx8qxp_pcam-v2-0-188be85f06f1@nxp.com> To: Laurent Pinchart , Mauro Carvalho Chehab , Shawn Guo , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam , Rui Miguel Silva , Martin Kepplinger , Purism Kernel Team , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Philipp Zabel Cc: linux-media@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Frank Li X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1751567591; l=3715; i=Frank.Li@nxp.com; s=20240130; h=from:subject:message-id; bh=xrlatQtLaiuinBwAmL4cEzL3pNe437Uvr/YWmYMVyX4=; b=OrYhgbxp0mxYiuvD4zwpejFQ9E/eldojxDR2ZfCT44z4t7F/rAzD6h8/JvNn4OeWKbkLfnHiQ jMyCzGG8e6aCOEQMci3BgiDtLjGFLAEhTs1FhhzET3OdH5wncSPru8A X-Developer-Key: i=Frank.Li@nxp.com; a=ed25519; pk=I0L1sDUfPxpAkRvPKy7MdauTuSENRq+DnA+G4qcS94Q= X-Endpoint-Received: by B4 Relay for Frank.Li@nxp.com/20240130 with auth_id=121 X-Original-From: Frank Li Reply-To: Frank.Li@nxp.com From: Frank Li Add parallel ov5640 nodes in imx8qxp-mek and create overlay file to enable it because it can work at two mode: MIPI and parallel mode. Signed-off-by: Frank Li --- change in v2 - move ov5640 part to overlay file - rename to imx8qxp-mek-ov5640-parallel.dtso - remove data-lanes --- arch/arm64/boot/dts/freescale/Makefile | 3 + .../dts/freescale/imx8qxp-mek-ov5640-parallel.dtso | 82 ++++++++++++++++++= ++++ 2 files changed, 85 insertions(+) diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/f= reescale/Makefile index 02ef35578dbc7e05b35b781dbfca0f0bc124ead1..25787fc7143f36301f8b334d4b0= d84d543e1f320 100644 --- a/arch/arm64/boot/dts/freescale/Makefile +++ b/arch/arm64/boot/dts/freescale/Makefile @@ -330,6 +330,9 @@ dtb-$(CONFIG_ARCH_MXC) +=3D imx8qxp-mek-pcie-ep.dtb imx8qxp-mek-ov5640-csi-dtbs :=3D imx8qxp-mek.dtb imx8qxp-mek-ov5640-csi.dt= bo dtb-${CONFIG_ARCH_MXC} +=3D imx8qxp-mek-ov5640-csi.dtb =20 +imx8qxp-mek-ov5640-parallel-dtbs :=3D imx8qxp-mek.dtb imx8qxp-mek-ov5640-p= arallel.dtbo +dtb-${CONFIG_ARCH_MXC} +=3D imx8qxp-mek-ov5640-parallel.dtb + dtb-$(CONFIG_ARCH_MXC) +=3D imx8qxp-tqma8xqp-mba8xx.dtb dtb-$(CONFIG_ARCH_MXC) +=3D imx8qxp-tqma8xqps-mb-smarc-2.dtb dtb-$(CONFIG_ARCH_MXC) +=3D imx8ulp-evk.dtb diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-mek-ov5640-parallel.dtso= b/arch/arm64/boot/dts/freescale/imx8qxp-mek-ov5640-parallel.dtso new file mode 100644 index 0000000000000000000000000000000000000000..e184a5beb5c835e6801495ae2ad= c3b14cfcde2e5 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8qxp-mek-ov5640-parallel.dtso @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2025 NXP + */ + +/dts-v1/; +/plugin/; + +#include +#include +#include +#include + +&cm40_i2c { + #address-cells =3D <1>; + #size-cells =3D <0>; + + ov5640_pi: camera@3c { + compatible =3D "ovti,ov5640"; + reg =3D <0x3c>; + clocks =3D <&pi0_misc_lpcg IMX_LPCG_CLK_0>; + clock-names =3D "xclk"; + assigned-clocks =3D <&pi0_misc_lpcg IMX_LPCG_CLK_0>; + assigned-clock-rates =3D <24000000>; + AVDD-supply =3D <®_2v8>; + DOVDD-supply =3D <®_1v8>; + DVDD-supply =3D <®_1v5>; + pinctrl-0 =3D <&pinctrl_parallel_csi>; + pinctrl-names =3D "default"; + powerdown-gpios =3D <&lsio_gpio3 2 GPIO_ACTIVE_HIGH>; + reset-gpios =3D <&lsio_gpio3 3 GPIO_ACTIVE_LOW>; + + port { + ov5640_pi_ep: endpoint { + bus-type =3D ; + bus-width =3D <8>; + hsync-active =3D <1>; + pclk-sample =3D <1>; + remote-endpoint =3D <¶llel_csi_in>; + vsync-active =3D <0>; + }; + }; + }; +}; + +&iomuxc { + pinctrl_parallel_csi: parallelcsigrp { + fsl,pins =3D < + IMX8QXP_CSI_D00_CI_PI_D02 0xc0000041 + IMX8QXP_CSI_D01_CI_PI_D03 0xc0000041 + IMX8QXP_CSI_D02_CI_PI_D04 0xc0000041 + IMX8QXP_CSI_D03_CI_PI_D05 0xc0000041 + IMX8QXP_CSI_D04_CI_PI_D06 0xc0000041 + IMX8QXP_CSI_D05_CI_PI_D07 0xc0000041 + IMX8QXP_CSI_D06_CI_PI_D08 0xc0000041 + IMX8QXP_CSI_D07_CI_PI_D09 0xc0000041 + + IMX8QXP_CSI_MCLK_CI_PI_MCLK 0xc0000041 + IMX8QXP_CSI_PCLK_CI_PI_PCLK 0xc0000041 + IMX8QXP_CSI_HSYNC_CI_PI_HSYNC 0xc0000041 + IMX8QXP_CSI_VSYNC_CI_PI_VSYNC 0xc0000041 + IMX8QXP_CSI_EN_LSIO_GPIO3_IO02 0xc0000041 + IMX8QXP_CSI_RESET_LSIO_GPIO3_IO03 0xc0000041 + >; + }; +}; + +&isi { + status =3D "okay"; +}; + +¶llel_csi { + status =3D "okay"; + + ports { + port@0 { + parallel_csi_in: endpoint { + remote-endpoint =3D <&ov5640_pi_ep>; + }; + }; + }; +}; --=20 2.34.1