* [PATCH v2 0/4] media: imx8qxp: add parallel camera support
@ 2025-07-03 18:33 Frank Li via B4 Relay
2025-07-03 18:33 ` [PATCH v2 1/4] dt-bindings: media: add i.MX parallel csi support Frank Li via B4 Relay
` (3 more replies)
0 siblings, 4 replies; 9+ messages in thread
From: Frank Li via B4 Relay @ 2025-07-03 18:33 UTC (permalink / raw)
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, imx, linux-arm-kernel, linux-kernel, devicetree,
Frank Li, Alice Yuan, Robert Chiras, Zhipeng Wang
Add parallel camera support for i.MX8 chips.
The below patch to add new format support to test ov5640 sensor
media: nxp: isi: add support for UYVY8_2X8 and YUYV8_2X8 bus codes
The bindings and driver for parallel CSI
dt-bindings: media: add i.MX parallel csi support
media: nxp: add V4L2 subdev driver for parallel CSI
DTS part need depend on previous MIPI CSI patches.
https://lore.kernel.org/imx/20250522-8qxp_camera-v5-13-d4be869fdb7e@nxp.com/
arm64: dts: imx8: add parellel csi nodes
arm64: dts: imx8qxp-mek: add parallel ov5640 camera support
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
Changes in v2:
- remove patch media: nxp: isi: add support for UYVY8_2X8 and YUYV8_2X8 bus codes
because pcif controller convert 2x8 to 1x16 to match isi's input
- rename comaptible string to fsl,imx8qxp-pcif
- See each patches's change log for detail
- Link to v1: https://lore.kernel.org/r/20250630-imx8qxp_pcam-v1-0-eccd38d99201@nxp.com
---
Alice Yuan (2):
dt-bindings: media: add i.MX parallel csi support
media: nxp: add V4L2 subdev driver for parallel CSI
Frank Li (2):
arm64: dts: imx8: add parallel CSI node
arm64: dts: imx8qxp-mek: add parallel ov5640 camera support
.../devicetree/bindings/media/fsl,imx93-pcif.yaml | 109 +++
MAINTAINERS | 2 +
arch/arm64/boot/dts/freescale/Makefile | 3 +
arch/arm64/boot/dts/freescale/imx8-ss-img.dtsi | 13 +
.../dts/freescale/imx8qxp-mek-ov5640-parallel.dtso | 82 ++
arch/arm64/boot/dts/freescale/imx8qxp-ss-img.dtsi | 27 +
drivers/media/platform/nxp/Kconfig | 11 +
drivers/media/platform/nxp/Makefile | 1 +
drivers/media/platform/nxp/imx-parallel-csi.c | 944 +++++++++++++++++++++
9 files changed, 1192 insertions(+)
---
base-commit: 93355cfe8aec9e47fc93fbc940f1bbeedd62e249
change-id: 20250626-imx8qxp_pcam-d851238343c3
Best regards,
--
Frank Li <Frank.Li@nxp.com>
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v2 1/4] dt-bindings: media: add i.MX parallel csi support
2025-07-03 18:33 [PATCH v2 0/4] media: imx8qxp: add parallel camera support Frank Li via B4 Relay
@ 2025-07-03 18:33 ` Frank Li via B4 Relay
2025-07-07 7:01 ` Krzysztof Kozlowski
2025-07-03 18:33 ` [PATCH v2 2/4] media: nxp: add V4L2 subdev driver for parallel CSI Frank Li via B4 Relay
` (2 subsequent siblings)
3 siblings, 1 reply; 9+ messages in thread
From: Frank Li via B4 Relay @ 2025-07-03 18:33 UTC (permalink / raw)
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, imx, linux-arm-kernel, linux-kernel, devicetree,
Frank Li, Alice Yuan
From: Alice Yuan <alice.yuan@nxp.com>
Document the binding for parallel CSI controller found in i.MX8QXP, i.MX93
and i.MX91 SoCs.
Signed-off-by: Alice Yuan <alice.yuan@nxp.com>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
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..ff9a32e0bec1d1bd90d93f45dbd7825d1e12650e
--- /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 <Frank.Li@nxp.com>
+
+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 <dt-bindings/clock/imx93-clock.h>
+ #include <dt-bindings/power/fsl,imx93-power.h>
+
+ pcif@4ac10070 {
+ compatible = "fsl,imx93-pcif";
+ reg = <0x4ac10070 0x10>;
+ clocks = <&clk IMX93_CLK_MIPI_CSI_GATE>,
+ <&clk IMX93_CLK_MEDIA_APB>;
+ clock-names = "pixel", "ipg";
+ assigned-clocks = <&clk IMX93_CLK_CAM_PIX>;
+ assigned-clock-parents = <&clk IMX93_CLK_VIDEO_PLL>;
+ assigned-clock-rates = <140000000>;
+ power-domains = <&media_blk_ctrl IMX93_MEDIABLK_PD_MIPI_CSI>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ endpoint {
+ remote-endpoint = <&mt9m114_ep>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ endpoint {
+ remote-endpoint = <&isi_in>;
+ };
+ };
+ };
+ };
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index 8dc0f6609d1fe2e3eefd50088dbe566d9e107bfa..8ae0667d2bb41fb6a1549bd3b2b33f326cbd1303 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
--
2.34.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 2/4] media: nxp: add V4L2 subdev driver for parallel CSI
2025-07-03 18:33 [PATCH v2 0/4] media: imx8qxp: add parallel camera support Frank Li via B4 Relay
2025-07-03 18:33 ` [PATCH v2 1/4] dt-bindings: media: add i.MX parallel csi support Frank Li via B4 Relay
@ 2025-07-03 18:33 ` Frank Li via B4 Relay
2025-07-03 18:33 ` [PATCH v2 3/4] arm64: dts: imx8: add parallel CSI node Frank Li via B4 Relay
2025-07-03 18:33 ` [PATCH v2 4/4] arm64: dts: imx8qxp-mek: add parallel ov5640 camera support Frank Li via B4 Relay
3 siblings, 0 replies; 9+ messages in thread
From: Frank Li via B4 Relay @ 2025-07-03 18:33 UTC (permalink / raw)
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, imx, linux-arm-kernel, linux-kernel, devicetree,
Frank Li, Alice Yuan, Robert Chiras, Zhipeng Wang
From: Alice Yuan <alice.yuan@nxp.com>
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 <alice.yuan@nxp.com>
Signed-off-by: Robert Chiras <robert.chiras@nxp.com>
Signed-off-by: Zhipeng Wang <zhipeng.wang_1@nxp.com>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
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..d936d15269344023afbc36ecadf77d66655bbac0 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
diff --git a/drivers/media/platform/nxp/Kconfig b/drivers/media/platform/nxp/Kconfig
index 40e3436669e213fdc5da70821dc0b420e1821f4f..5df6f97d16f294875e40716985bae0d893345bdd 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.
+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"
# mem2mem drivers
diff --git a/drivers/media/platform/nxp/Makefile b/drivers/media/platform/nxp/Makefile
index 4d90eb71365259ebdda84ea58483e1c4131d3ac7..076592c58575cb6550ba824f2a10fed4410cb8cf 100644
--- a/drivers/media/platform/nxp/Makefile
+++ b/drivers/media/platform/nxp/Makefile
@@ -7,5 +7,6 @@ obj-y += imx8-isi/
obj-$(CONFIG_VIDEO_IMX7_CSI) += imx7-media-csi.o
obj-$(CONFIG_VIDEO_IMX8MQ_MIPI_CSI2) += imx8mq-mipi-csi2.o
obj-$(CONFIG_VIDEO_IMX_MIPI_CSIS) += imx-mipi-csis.o
+obj-$(CONFIG_VIDEO_IMX_PARALLEL_CSI) += imx-parallel-csi.o
obj-$(CONFIG_VIDEO_IMX_PXP) += imx-pxp.o
obj-$(CONFIG_VIDEO_MX2_EMMAPRP) += 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..1567739e68a2a8afc58b42e836c5b9a936af1cf5
--- /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 <linux/bits.h>
+#include <linux/clk.h>
+#include <linux/debugfs.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+#include <linux/reset.h>
+#include <linux/spinlock.h>
+
+#include <media/v4l2-common.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-mc.h>
+#include <media/v4l2-subdev.h>
+
+#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 = 0x0,
+ CSI_IN_DT_UYVY_BT656_10,
+ CSI_IN_DT_RGB_8,
+ CSI_IN_DT_BGR_8,
+ CSI_IN_DT_YVYU_8 = 0x5,
+ CSI_IN_DT_YUV_8,
+ CSI_IN_DT_RAW_8 = 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[] = {
+ "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[] = {
+ /* YUV formats. */
+ {
+ .code = MEDIA_BUS_FMT_UYVY8_2X8,
+ .output = MEDIA_BUS_FMT_UYVY8_1X16,
+ .data_type = CSI_IN_DT_YVYU_8,
+ .width = 16,
+ }, {
+ .code = MEDIA_BUS_FMT_YUYV8_2X8,
+ .output = MEDIA_BUS_FMT_YUYV8_1X16,
+ .data_type = CSI_IN_DT_YVYU_8,
+ .width = 16,
+ },
+};
+
+static const struct parallel_csi_plat_data imx8qxp_pdata = {
+ .version = PI_V1,
+ .if_ctrl_reg = 0x0,
+ .interface_status = 0x20,
+ .interface_ctrl_reg = 0x10,
+ .interface_ctrl_reg1 = 0x30,
+ .def_hsync_pol = 1,
+ .def_vsync_pol = 0,
+ .def_pixel_clk_pol = 0,
+ .def_csi_in_data_type = CSI_IN_DT_UYVY_BT656_8,
+};
+
+static const struct parallel_csi_plat_data imx93_pdata = {
+ .version = PI_V2,
+ .if_ctrl_reg = 0x0,
+ .interface_status = 0x4,
+ .interface_ctrl_reg = 0x8,
+ .interface_ctrl_reg1 = 0xc,
+ .def_hsync_pol = 0,
+ .def_vsync_pol = 1,
+ .def_pixel_clk_pol = 0,
+ .def_csi_in_data_type = CSI_IN_DT_YVYU_8,
+};
+
+static const struct parallel_csi_plat_data imx91_pdata = {
+ .version = PI_V2,
+ .if_ctrl_reg = 0x0,
+ .interface_status = 0x4,
+ .interface_ctrl_reg = 0x8,
+ .interface_ctrl_reg1 = 0xc,
+ .def_hsync_pol = 0,
+ .def_vsync_pol = 1,
+ .def_pixel_clk_pol = 0,
+ .def_csi_in_data_type = CSI_IN_DT_YVYU_8,
+};
+
+static void parallel_csi_regs_dump(struct parallel_csi_device *pcsidev)
+{
+ struct device *dev = pcsidev->dev;
+ const struct parallel_csi_plat_data *pdata = pcsidev->pdata;
+ u32 i;
+
+ struct {
+ u32 offset;
+ const char *const name;
+ } registers[] = {
+ { 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 = 0; i < ARRAY_SIZE(registers); i++) {
+ u32 reg = 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 = 0; i < ARRAY_SIZE(parallel_csi_formats); i++)
+ if (code == 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 = pcsidev->pdata;
+ u32 val;
+
+ /* Softwaret Reset */
+ val = readl(pcsidev->regs + pdata->interface_ctrl_reg);
+ val |= CSI_CTRL_REG_SOFTRST;
+ writel(val, pcsidev->regs + pdata->interface_ctrl_reg);
+
+ usleep_range(500, 1000);
+ val = readl(pcsidev->regs + pdata->interface_ctrl_reg);
+ val &= ~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 = pcsidev->pdata;
+ u32 val;
+
+ /* Software Reset */
+ parallel_csi_sw_reset(pcsidev);
+
+ /* Config PL Data Type */
+ val = readl(pcsidev->regs + pdata->if_ctrl_reg);
+ val |= IF_CTRL_REG_DATA_TYPE(DATA_TYPE_OUT_YUV444);
+ writel(val, pcsidev->regs + pdata->if_ctrl_reg);
+
+ /* Enable sync Force */
+ val = readl(pcsidev->regs + pdata->interface_ctrl_reg);
+ val |= (CSI_CTRL_REG_HSYNC_FORCE_EN | CSI_CTRL_REG_VSYNC_FORCE_EN);
+ writel(val, pcsidev->regs + pdata->interface_ctrl_reg);
+
+ /* Enable Pixel Link */
+ val = readl(pcsidev->regs + pdata->if_ctrl_reg);
+ val |= IF_CTRL_REG_PL_ENABLE;
+ writel(val, pcsidev->regs + pdata->if_ctrl_reg);
+
+ /* Enable Pixel Link */
+ val = readl(pcsidev->regs + pdata->if_ctrl_reg);
+ val |= IF_CTRL_REG_PL_VALID;
+ writel(val, pcsidev->regs + pdata->if_ctrl_reg);
+
+ /* Config CTRL REG */
+ val = readl(pcsidev->regs + pdata->interface_ctrl_reg);
+
+ val |= (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 |= CSI_CTRL_REG_UV_SWAP_EN;
+
+ if (pcsidev->mode & PI_GATE_CLOCK_MODE) {
+ val |= CSI_CTRL_REG_GCLK_MODE_EN;
+ } else if (pcsidev->mode & PI_CCIR_MODE) {
+ val |= (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 *pcsidev,
+ u32 *pixel_width, u32 *vsync_pulse,
+ const struct v4l2_mbus_framefmt *format)
+{
+ u32 version = pcsidev->pdata->version;
+
+ switch (version) {
+ case PI_V1:
+ *pixel_width = format->width - 1;
+ *vsync_pulse = format->width << 1;
+ break;
+ case PI_V2:
+ *pixel_width = format->width << 3;
+ *vsync_pulse = 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 *pcsidev,
+ const struct v4l2_mbus_framefmt *format)
+{
+ const struct parallel_csi_plat_data *pdata = pcsidev->pdata;
+ struct device *dev = 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 <= 0 || format->height <= 0) {
+ dev_err(dev, "%s width/height invalid\n", __func__);
+ return;
+ }
+
+ ret = get_interface_ctrl_reg1_param(pcsidev, &pixel_width,
+ &vsync_pulse, format);
+ if (ret < 0)
+ return;
+
+ val = (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 = pcsidev->pdata;
+ u32 val;
+
+ /* Enable CSI */
+ val = readl(pcsidev->regs + pdata->interface_ctrl_reg);
+ val |= CSI_CTRL_REG_CSI_EN;
+ writel(val, pcsidev->regs + pdata->interface_ctrl_reg);
+
+ /* Disable SYNC Force */
+ val = readl(pcsidev->regs + pdata->interface_ctrl_reg);
+ val &= ~(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 = pcsidev->pdata;
+ u32 val;
+
+ /* Enable Sync Force */
+ val = readl(pcsidev->regs + pdata->interface_ctrl_reg);
+ val |= (CSI_CTRL_REG_HSYNC_FORCE_EN | CSI_CTRL_REG_VSYNC_FORCE_EN);
+ writel(val, pcsidev->regs + pdata->interface_ctrl_reg);
+
+ /* Disable CSI */
+ val = readl(pcsidev->regs + pdata->interface_ctrl_reg);
+ val &= ~CSI_CTRL_REG_CSI_EN;
+ writel(val, pcsidev->regs + pdata->interface_ctrl_reg);
+
+ /* Disable Pixel Link */
+ val = readl(pcsidev->regs + pdata->if_ctrl_reg);
+ val &= ~(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 == MEDIA_BUS_FMT_YUYV8_2X8 ||
+ pcsidev_fmt->code == MEDIA_BUS_FMT_UYVY8_2X8)
+ pcsidev->uv_swap = 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 = notifier_to_parallel_csi_device(notifier);
+ struct media_pad *sink = &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 = {
+ .bound = parallel_csi_notify_bound,
+};
+
+static int parallel_csi_async_register(struct parallel_csi_device *pcsidev)
+{
+ struct v4l2_fwnode_endpoint vep = {
+ .bus_type = V4L2_MBUS_PARALLEL,
+ };
+ struct v4l2_async_connection *asd;
+ struct fwnode_handle *ep;
+ int ret;
+
+ v4l2_async_subdev_nf_init(&pcsidev->notifier, &pcsidev->sd);
+
+ ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(pcsidev->dev), 0, 0,
+ FWNODE_GRAPH_ENDPOINT_NEXT);
+ if (!ep)
+ return -ENOTCONN;
+
+ ret = v4l2_fwnode_endpoint_parse(ep, &vep);
+ if (ret)
+ goto err_parse;
+
+ asd = v4l2_async_nf_add_fwnode_remote(&pcsidev->notifier, ep,
+ struct v4l2_async_connection);
+ if (IS_ERR(asd)) {
+ ret = PTR_ERR(asd);
+ goto err_parse;
+ }
+
+ fwnode_handle_put(ep);
+
+ pcsidev->notifier.ops = ¶llel_csi_notify_ops;
+ ret = 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 = media_entity_to_v4l2_subdev(entity);
+ struct parallel_csi_device *pcsidev = 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 = media_entity_to_v4l2_subdev(remote_pad->entity);
+ if (flags & MEDIA_LNK_FL_ENABLED) {
+ if (pcsidev->source.sd)
+ return -EBUSY;
+
+ pcsidev->source.sd = remote_sd;
+ pcsidev->source.pad = remote_pad;
+ } else {
+ pcsidev->source.sd = NULL;
+ pcsidev->source.pad = NULL;
+ }
+
+ return 0;
+}
+
+static const struct media_entity_operations parallel_csi_entity_ops = {
+ .link_setup = parallel_csi_link_setup,
+ .link_validate = v4l2_subdev_link_validate,
+ .get_fwnode_pad = 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 = sd_to_parallel_csi_device(sd);
+ struct device *dev = 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 == 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 = find_parallel_csi_format(sdformat->format.code);
+ if (!pcsidev_fmt)
+ pcsidev_fmt = ¶llel_csi_formats[0];
+
+ switch (pcsidev_fmt->width % 8) {
+ case 0:
+ align = 0;
+ break;
+ case 4:
+ align = 1;
+ break;
+ case 2:
+ case 6:
+ align = 2;
+ break;
+ default:
+ /* 1, 3, 5, 7 */
+ align = 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 = v4l2_subdev_state_get_format(sd_state, sdformat->pad);
+ if (!fmt)
+ return -EINVAL;
+
+ fmt->code = pcsidev_fmt->code;
+ fmt->width = sdformat->format.width;
+ fmt->height = sdformat->format.height;
+ fmt->field = V4L2_FIELD_NONE;
+ fmt->colorspace = sdformat->format.colorspace;
+ fmt->quantization = sdformat->format.quantization;
+ fmt->xfer_func = sdformat->format.xfer_func;
+ fmt->ycbcr_enc = sdformat->format.ycbcr_enc;
+
+ sdformat->format = *fmt;
+
+ /* Propagate the format from sink to source. */
+ fmt = v4l2_subdev_state_get_format(sd_state, PARALLEL_CSI_PAD_SOURCE);
+ *fmt = sdformat->format;
+
+ /* The format on the source pad might change due to unpacking. */
+ fmt->code = 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 = {
+ .code = PARALLEL_CSI_DEF_MBUS_CODE,
+ .width = PARALLEL_CSI_DEF_PIX_WIDTH,
+ .height = PARALLEL_CSI_DEF_PIX_HEIGHT,
+ .field = V4L2_FIELD_NONE,
+ .colorspace = V4L2_COLORSPACE_SMPTE170M,
+ .xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(V4L2_COLORSPACE_SMPTE170M),
+ .ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(V4L2_COLORSPACE_SMPTE170M),
+ .quantization = 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 = {
+ .pad = PARALLEL_CSI_PAD_SINK,
+ };
+
+ fmt.format.code = parallel_csi_formats[0].code;
+ fmt.format.width = PARALLEL_CSI_DEF_PIX_WIDTH;
+ fmt.format.height = PARALLEL_CSI_DEF_PIX_HEIGHT;
+
+ fmt.format.colorspace = V4L2_COLORSPACE_SMPTE170M;
+ fmt.format.xfer_func =
+ V4L2_MAP_XFER_FUNC_DEFAULT(fmt.format.colorspace);
+ fmt.format.ycbcr_enc =
+ V4L2_MAP_YCBCR_ENC_DEFAULT(fmt.format.colorspace);
+ fmt.format.quantization =
+ 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 = 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 = v4l2_subdev_lock_and_get_active_state(sd);
+ format = v4l2_subdev_state_get_format(state, PARALLEL_CSI_PAD_SINK);
+ pcsidev_fmt = find_parallel_csi_format(format->code);
+
+ ret = pm_runtime_resume_and_get(pcsidev->dev);
+ if (ret < 0)
+ goto err_unlock;
+
+ parallel_csi_start_stream(pcsidev, format, pcsidev_fmt);
+
+ ret = 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 == PARALLEL_CSI_PAD_SOURCE) {
+ struct v4l2_mbus_framefmt *fmt;
+
+ if (code->index > 0)
+ return -EINVAL;
+
+ fmt = v4l2_subdev_state_get_format(sd_state, code->pad);
+ code->code = fmt->code;
+ return 0;
+ }
+
+ if (code->pad != PARALLEL_CSI_PAD_SINK)
+ return -EINVAL;
+
+ if (code->index >= ARRAY_SIZE(parallel_csi_formats))
+ return -EINVAL;
+
+ code->code = 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 = &fd->entry[0];
+ const struct parallel_csi_pix_format *pcsidev_fmt;
+ const struct v4l2_mbus_framefmt *fmt;
+ struct v4l2_subdev_state *state;
+
+ if (pad != PARALLEL_CSI_PAD_SOURCE)
+ return -EINVAL;
+
+ state = v4l2_subdev_lock_and_get_active_state(sd);
+ fmt = v4l2_subdev_state_get_format(state, PARALLEL_CSI_PAD_SOURCE);
+ pcsidev_fmt = find_parallel_csi_format(fmt->code);
+ v4l2_subdev_unlock_state(state);
+
+ if (!pcsidev_fmt)
+ return -EPIPE;
+
+ fd->type = V4L2_MBUS_FRAME_DESC_TYPE_PARALLEL;
+ fd->num_entries = 1;
+
+ entry->flags = 0;
+ entry->pixelcode = pcsidev_fmt->code;
+
+ return 0;
+}
+
+static const struct v4l2_subdev_video_ops parallel_csi_video_ops = {
+ .s_stream = parallel_csi_s_stream,
+};
+
+static const struct v4l2_subdev_pad_ops parallel_csi_pad_ops = {
+ .enum_mbus_code = parallel_csi_enum_mbus_code,
+ .get_fmt = v4l2_subdev_get_fmt,
+ .set_fmt = parallel_csi_set_fmt,
+ .get_frame_desc = parallel_csi_get_frame_desc,
+};
+
+static const struct v4l2_subdev_ops parallel_csi_subdev_ops = {
+ .pad = ¶llel_csi_pad_ops,
+ .video = ¶llel_csi_video_ops,
+};
+
+static const struct v4l2_subdev_internal_ops parallel_csi_internal_ops = {
+ .init_state = parallel_csi_init_state,
+};
+
+static int parallel_csi_clk_get(struct parallel_csi_device *pcsidev)
+{
+ unsigned int i;
+ int ret = 0;
+
+ for (i = 0; i < PCSIDEV_NUM_CLKS; i++)
+ pcsidev->clks[i].id = parallel_csi_clk_id[i];
+
+ ret = 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 = dev_get_drvdata(dev);
+ struct parallel_csi_device *pcsidev = 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 = dev_get_drvdata(dev);
+ struct parallel_csi_device *pcsidev = 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 = {
+ 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 = &pcsidev->sd;
+ int ret;
+
+ v4l2_subdev_init(sd, ¶llel_csi_subdev_ops);
+
+ sd->internal_ops = ¶llel_csi_internal_ops;
+ sd->owner = THIS_MODULE;
+ snprintf(sd->name, sizeof(sd->name), "parallel-%s",
+ dev_name(pcsidev->dev));
+
+ sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+ sd->ctrl_handler = NULL;
+
+ sd->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
+ sd->entity.ops = ¶llel_csi_entity_ops;
+
+ sd->dev = pcsidev->dev;
+
+ pcsidev->pads[PARALLEL_CSI_PAD_SINK].flags = MEDIA_PAD_FL_SINK | MEDIA_PAD_FL_MUST_CONNECT;
+ pcsidev->pads[PARALLEL_CSI_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE |
+ MEDIA_PAD_FL_MUST_CONNECT;
+
+ ret = media_entity_pads_init(&sd->entity, PARALLEL_CSI_PADS_NUM, pcsidev->pads);
+ if (ret)
+ return ret;
+
+ ret = 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 = 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 = &pdev->dev;
+ int ret = 0;
+
+ pcsidev = devm_kzalloc(dev, sizeof(*pcsidev), GFP_KERNEL);
+ if (!pcsidev)
+ return -ENOMEM;
+
+ pcsidev->dev = dev;
+ platform_set_drvdata(pdev, pcsidev);
+
+ pcsidev->pdata = of_device_get_match_data(dev);
+
+ pcsidev->regs = 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 = parallel_csi_clk_get(pcsidev);
+ if (ret < 0)
+ return ret;
+
+ ret = parallel_csi_subdev_init(pcsidev);
+ if (ret < 0)
+ return ret;
+
+ ret = devm_add_action_or_reset(dev, parallel_csi_cleanup, pcsidev);
+ if (ret)
+ return ret;
+
+ pcsidev->mode = PI_GATE_CLOCK_MODE;
+
+ platform_set_drvdata(pdev, &pcsidev->sd);
+
+ ret = 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[] = {
+ {.compatible = "fsl,imx8qxp-pcif", .data = &imx8qxp_pdata },
+ {.compatible = "fsl,imx91-pcif", .data = &imx91_pdata },
+ {.compatible = "fsl,imx93-pcif", .data = &imx93_pdata },
+ { },
+};
+
+MODULE_DEVICE_TABLE(of, _of_match);
+
+static struct platform_driver _driver = {
+ .probe = parallel_csi_probe,
+ .driver = {
+ .of_match_table = _of_match,
+ .name = "imx-parallel-csi",
+ .pm = pm_ptr(¶llel_csi_pm_ops),
+ },
+};
+
+module_platform_driver(_driver);
+
+MODULE_DESCRIPTION("i.MX9 Parallel CSI receiver driver");
+MODULE_LICENSE("GPL");
--
2.34.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 3/4] arm64: dts: imx8: add parallel CSI node
2025-07-03 18:33 [PATCH v2 0/4] media: imx8qxp: add parallel camera support Frank Li via B4 Relay
2025-07-03 18:33 ` [PATCH v2 1/4] dt-bindings: media: add i.MX parallel csi support Frank Li via B4 Relay
2025-07-03 18:33 ` [PATCH v2 2/4] media: nxp: add V4L2 subdev driver for parallel CSI Frank Li via B4 Relay
@ 2025-07-03 18:33 ` Frank Li via B4 Relay
2025-07-07 7:03 ` Krzysztof Kozlowski
2025-07-03 18:33 ` [PATCH v2 4/4] arm64: dts: imx8qxp-mek: add parallel ov5640 camera support Frank Li via B4 Relay
3 siblings, 1 reply; 9+ messages in thread
From: Frank Li via B4 Relay @ 2025-07-03 18:33 UTC (permalink / raw)
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, imx, linux-arm-kernel, linux-kernel, devicetree,
Frank Li
From: Frank Li <Frank.Li@nxp.com>
Add parallel CSI nodes.
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
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/boot/dts/freescale/imx8-ss-img.dtsi
index 2cf0f7208350a416d77b11140279d2f66f41498f..1f7bf9efdbca266fbda82d2bc84acd9a27ed0bd1 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 = "disabled";
};
+ parallel_csi: csi@58261000 {
+ compatible = "fsl,imx8qxp-pcif";
+ reg = <0x58261000 0x1000>;
+ clocks = <&pi0_pxl_lpcg IMX_LPCG_CLK_0>,
+ <&pi0_ipg_lpcg IMX_LPCG_CLK_4>;
+ clock-names = "pixel", "ipg";
+ assigned-clocks = <&clk IMX_SC_R_PI_0 IMX_SC_PM_CLK_PER>;
+ assigned-clock-parents = <&clk IMX_SC_R_PI_0_PLL IMX_SC_PM_CLK_PLL>;
+ assigned-clock-rates = <160000000>;
+ power-domains = <&pd IMX_SC_R_PI_0>;
+ status = "disabled";
+ };
+
pi0_ipg_lpcg: clock-controller@58263004 {
compatible = "fsl,imx8qxp-lpcg";
reg = <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..60aa43c45d15c8b0c2c425be52ed79458d8c96b9 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 = <&mipi_csi0_out>;
};
};
+
+ port@4 {
+ reg = <4>;
+
+ isi_in_4: endpoint {
+ remote-endpoint = <¶llel_csi_out>;
+ };
+ };
};
};
@@ -94,3 +102,22 @@ &jpegenc {
&mipi_csi_1 {
status = "disabled";
};
+
+¶llel_csi {
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ };
+
+ port@1 {
+ reg = <1>;
+
+ parallel_csi_out: endpoint {
+ remote-endpoint = <&isi_in_4>;
+ };
+ };
+ };
+};
--
2.34.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 4/4] arm64: dts: imx8qxp-mek: add parallel ov5640 camera support
2025-07-03 18:33 [PATCH v2 0/4] media: imx8qxp: add parallel camera support Frank Li via B4 Relay
` (2 preceding siblings ...)
2025-07-03 18:33 ` [PATCH v2 3/4] arm64: dts: imx8: add parallel CSI node Frank Li via B4 Relay
@ 2025-07-03 18:33 ` Frank Li via B4 Relay
3 siblings, 0 replies; 9+ messages in thread
From: Frank Li via B4 Relay @ 2025-07-03 18:33 UTC (permalink / raw)
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, imx, linux-arm-kernel, linux-kernel, devicetree,
Frank Li
From: Frank Li <Frank.Li@nxp.com>
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 <Frank.Li@nxp.com>
---
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/freescale/Makefile
index 02ef35578dbc7e05b35b781dbfca0f0bc124ead1..25787fc7143f36301f8b334d4b0d84d543e1f320 100644
--- a/arch/arm64/boot/dts/freescale/Makefile
+++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -330,6 +330,9 @@ dtb-$(CONFIG_ARCH_MXC) += imx8qxp-mek-pcie-ep.dtb
imx8qxp-mek-ov5640-csi-dtbs := imx8qxp-mek.dtb imx8qxp-mek-ov5640-csi.dtbo
dtb-${CONFIG_ARCH_MXC} += imx8qxp-mek-ov5640-csi.dtb
+imx8qxp-mek-ov5640-parallel-dtbs := imx8qxp-mek.dtb imx8qxp-mek-ov5640-parallel.dtbo
+dtb-${CONFIG_ARCH_MXC} += imx8qxp-mek-ov5640-parallel.dtb
+
dtb-$(CONFIG_ARCH_MXC) += imx8qxp-tqma8xqp-mba8xx.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8qxp-tqma8xqps-mb-smarc-2.dtb
dtb-$(CONFIG_ARCH_MXC) += 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..e184a5beb5c835e6801495ae2adc3b14cfcde2e5
--- /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 <dt-bindings/clock/imx8-lpcg.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/media/video-interfaces.h>
+#include <dt-bindings/pinctrl/pads-imx8qxp.h>
+
+&cm40_i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ov5640_pi: camera@3c {
+ compatible = "ovti,ov5640";
+ reg = <0x3c>;
+ clocks = <&pi0_misc_lpcg IMX_LPCG_CLK_0>;
+ clock-names = "xclk";
+ assigned-clocks = <&pi0_misc_lpcg IMX_LPCG_CLK_0>;
+ assigned-clock-rates = <24000000>;
+ AVDD-supply = <®_2v8>;
+ DOVDD-supply = <®_1v8>;
+ DVDD-supply = <®_1v5>;
+ pinctrl-0 = <&pinctrl_parallel_csi>;
+ pinctrl-names = "default";
+ powerdown-gpios = <&lsio_gpio3 2 GPIO_ACTIVE_HIGH>;
+ reset-gpios = <&lsio_gpio3 3 GPIO_ACTIVE_LOW>;
+
+ port {
+ ov5640_pi_ep: endpoint {
+ bus-type = <MEDIA_BUS_TYPE_PARALLEL>;
+ bus-width = <8>;
+ hsync-active = <1>;
+ pclk-sample = <1>;
+ remote-endpoint = <¶llel_csi_in>;
+ vsync-active = <0>;
+ };
+ };
+ };
+};
+
+&iomuxc {
+ pinctrl_parallel_csi: parallelcsigrp {
+ fsl,pins = <
+ 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 = "okay";
+};
+
+¶llel_csi {
+ status = "okay";
+
+ ports {
+ port@0 {
+ parallel_csi_in: endpoint {
+ remote-endpoint = <&ov5640_pi_ep>;
+ };
+ };
+ };
+};
--
2.34.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v2 1/4] dt-bindings: media: add i.MX parallel csi support
2025-07-03 18:33 ` [PATCH v2 1/4] dt-bindings: media: add i.MX parallel csi support Frank Li via B4 Relay
@ 2025-07-07 7:01 ` Krzysztof Kozlowski
2025-07-07 16:12 ` Frank Li
0 siblings, 1 reply; 9+ messages in thread
From: Krzysztof Kozlowski @ 2025-07-07 7:01 UTC (permalink / raw)
To: Frank Li
Cc: 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, linux-media,
imx, linux-arm-kernel, linux-kernel, devicetree, Alice Yuan
On Thu, Jul 03, 2025 at 02:33:06PM -0400, Frank Li wrote:
> +properties:
> + compatible:
> + oneOf:
> + - const: fsl,imx8qxp-pcif
> + - items:
> + - enum:
> + - fsl,imx91-pcif
> + - const: fsl,imx93-pcif
> + - const: fsl,imx93-pcif
This one should be an enum with imx8qxp.
> +
> + 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
Use the properties/port schema instead, you do not have any properties
here (although then question - don't you need anything from video
interfaces?)
> + unevaluatedProperties: false
> + description:
> + Input port node.
> +
> + port@1:
> + $ref: /schemas/graph.yaml#/$defs/port-base
Same here
> + unevaluatedProperties: false
> + description:
> + Output port node.
> +
> +required:
> + - compatible
> + - reg
> + - clocks
> + - clock-names
> + - power-domains
> + - ports
> +
> +additionalProperties: false
> +
> +examples:
> + - |
> + #include <dt-bindings/clock/imx93-clock.h>
> + #include <dt-bindings/power/fsl,imx93-power.h>
> +
> + pcif@4ac10070 {
That's a CPI bus from MIPI so cpi@, no?
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 3/4] arm64: dts: imx8: add parallel CSI node
2025-07-03 18:33 ` [PATCH v2 3/4] arm64: dts: imx8: add parallel CSI node Frank Li via B4 Relay
@ 2025-07-07 7:03 ` Krzysztof Kozlowski
0 siblings, 0 replies; 9+ messages in thread
From: Krzysztof Kozlowski @ 2025-07-07 7:03 UTC (permalink / raw)
To: Frank Li
Cc: 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, linux-media,
imx, linux-arm-kernel, linux-kernel, devicetree
On Thu, Jul 03, 2025 at 02:33:08PM -0400, Frank Li wrote:
> Add parallel CSI nodes.
CSI is serial. How this can be a parallel serial? Binding speaks nothing
about CSI, so this is just confusing. About which MIPI standard are we
talking here?
>
> Signed-off-by: Frank Li <Frank.Li@nxp.com>
> ---
> 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/boot/dts/freescale/imx8-ss-img.dtsi
> index 2cf0f7208350a416d77b11140279d2f66f41498f..1f7bf9efdbca266fbda82d2bc84acd9a27ed0bd1 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 = "disabled";
> };
>
> + parallel_csi: csi@58261000 {
And here it is called csi, not cpi, although binding calls pcif. Decide.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 1/4] dt-bindings: media: add i.MX parallel csi support
2025-07-07 7:01 ` Krzysztof Kozlowski
@ 2025-07-07 16:12 ` Frank Li
2025-07-08 6:24 ` Krzysztof Kozlowski
0 siblings, 1 reply; 9+ messages in thread
From: Frank Li @ 2025-07-07 16:12 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: 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, linux-media,
imx, linux-arm-kernel, linux-kernel, devicetree, Alice Yuan
On Mon, Jul 07, 2025 at 09:01:48AM +0200, Krzysztof Kozlowski wrote:
> On Thu, Jul 03, 2025 at 02:33:06PM -0400, Frank Li wrote:
> > +properties:
> > + compatible:
> > + oneOf:
> > + - const: fsl,imx8qxp-pcif
> > + - items:
> > + - enum:
> > + - fsl,imx91-pcif
> > + - const: fsl,imx93-pcif
> > + - const: fsl,imx93-pcif
>
> This one should be an enum with imx8qxp.
>
>
> > +
> > + 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
>
> Use the properties/port schema instead, you do not have any properties
> here (although then question - don't you need anything from video
> interfaces?)
>
> > + unevaluatedProperties: false
> > + description:
> > + Input port node.
> > +
> > + port@1:
> > + $ref: /schemas/graph.yaml#/$defs/port-base
>
> Same here
>
> > + unevaluatedProperties: false
> > + description:
> > + Output port node.
> > +
> > +required:
> > + - compatible
> > + - reg
> > + - clocks
> > + - clock-names
> > + - power-domains
> > + - ports
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > + - |
> > + #include <dt-bindings/clock/imx93-clock.h>
> > + #include <dt-bindings/power/fsl,imx93-power.h>
> > +
> > + pcif@4ac10070 {
>
> That's a CPI bus from MIPI so cpi@, no?
It is not MIPI. It is old camera interface, which use D0..7 and VSYNC ...
signal.
So Laurent purpose 'pcif', is it okay?
Frank
>
> Best regards,
> Krzysztof
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 1/4] dt-bindings: media: add i.MX parallel csi support
2025-07-07 16:12 ` Frank Li
@ 2025-07-08 6:24 ` Krzysztof Kozlowski
0 siblings, 0 replies; 9+ messages in thread
From: Krzysztof Kozlowski @ 2025-07-08 6:24 UTC (permalink / raw)
To: Frank Li
Cc: 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, linux-media,
imx, linux-arm-kernel, linux-kernel, devicetree, Alice Yuan
On 07/07/2025 18:12, Frank Li wrote:
>>> +examples:
>>> + - |
>>> + #include <dt-bindings/clock/imx93-clock.h>
>>> + #include <dt-bindings/power/fsl,imx93-power.h>
>>> +
>>> + pcif@4ac10070 {
>>
>> That's a CPI bus from MIPI so cpi@, no?
>
> It is not MIPI. It is old camera interface, which use D0..7 and VSYNC ...
> signal.
Hm? I did not say it is MIPI. MIPI is a organization. I said this is
CPI. pcif is the name of NXP block, not the name of the bus.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2025-07-08 6:24 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-03 18:33 [PATCH v2 0/4] media: imx8qxp: add parallel camera support Frank Li via B4 Relay
2025-07-03 18:33 ` [PATCH v2 1/4] dt-bindings: media: add i.MX parallel csi support Frank Li via B4 Relay
2025-07-07 7:01 ` Krzysztof Kozlowski
2025-07-07 16:12 ` Frank Li
2025-07-08 6:24 ` Krzysztof Kozlowski
2025-07-03 18:33 ` [PATCH v2 2/4] media: nxp: add V4L2 subdev driver for parallel CSI Frank Li via B4 Relay
2025-07-03 18:33 ` [PATCH v2 3/4] arm64: dts: imx8: add parallel CSI node Frank Li via B4 Relay
2025-07-07 7:03 ` Krzysztof Kozlowski
2025-07-03 18:33 ` [PATCH v2 4/4] arm64: dts: imx8qxp-mek: add parallel ov5640 camera support Frank Li via B4 Relay
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).