Devicetree
 help / color / mirror / Atom feed
* [PATCH v4 0/6] media: synopsys: enhancements and i.MX95 support
@ 2026-05-19  2:07 Guoniu Zhou
  2026-05-19  2:07 ` [PATCH v4 1/6] media: synopsys: Fix IPI using hardcoded datatype Guoniu Zhou
                   ` (5 more replies)
  0 siblings, 6 replies; 10+ messages in thread
From: Guoniu Zhou @ 2026-05-19  2:07 UTC (permalink / raw)
  To: Michael Riesch, Mauro Carvalho Chehab, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner,
	Laurent Pinchart, Frank Li, Sakari Ailus, Bryan O'Donoghue,
	Mehdi Djait, Hans Verkuil
  Cc: linux-media, linux-kernel, devicetree, imx, linux-arm-kernel,
	linux-rockchip, Guoniu Zhou, Krzysztof Kozlowski

This series enhances the Synopsys DesignWare MIPI CSI-2 receiver driver
with multiple stream support and adds i.MX95 platform support.

The i.MX95 variant is similar to i.MX93 but uses IDI instead of IPI. Since
IDI is software transparent, only a different register map is needed.

Tested on i.MX93 and i.MX95 platforms.

Signed-off-by: Guoniu Zhou <guoniu.zhou@oss.nxp.com>
---
Changes in v4:
- Rebase to latest media/next(bc1ba628e37c)
- Link to v3: https://lore.kernel.org/r/20260506-csi2_imx95-v3-0-953b6e1a80dd@oss.nxp.com

Changes in v3:
- Added Reviewed-by tag from Frank Li for patches 1-6
- Fix formats array out-of-bounds read during enumeration
- Add NULL check for csi2->formats to handle unexpected format lookup failures
- Call pm_runtime_put() after dw_mipi_csi2rx_stop()
- Balance PM runtime get/put for asymmetric stream enable/disable operations
- Add Reviewed-by tag from Krzysztof Kozlowski
- See each patch's changelog for details.
- Link to v2: https://lore.kernel.org/r/20260423-csi2_imx95-v2-0-934c02f3422a@oss.nxp.com

Changes in v2:
- Add two new patches
- Simplify error handling by keeping goto labels instead of early returns
- Removes redundant register availability check
- Uses read_poll_timeout() with dw_mipi_csi2rx_read() instead of
  readl_poll_timeout() with direct register address
- Fixes stopstate condition logic
- Check PHY stopstate after sensor enable instead of before to ensure
  correct timing.
- Optimize PHY stopstate polling parameters (1000us->10us, 2s->1ms) to
  balance performance and responsiveness.
- Add dedicated constraint block for i.MX95 to reflect different clock
  requirements (only per clock needed vs i.MX93 which needs both per and
  pixel clocks)
- Update commit message to include more details about interface differences
- Add Reviewed-by tag from Frank Li <Frank.Li@nxp.com>
- Update commit message
- See each patch's changelog for details.
- Link to v1: https://lore.kernel.org/r/20260415-csi2_imx95-v1-0-7d63f3508719@oss.nxp.com

---
Guoniu Zhou (6):
      media: synopsys: Fix IPI using hardcoded datatype
      media: synopsys: Add support for RAW16 Bayer formats
      media: synopsys: Add support for multiple streams
      media: synopsys: Add PHY stopstate wait for i.MX93
      media: dt-bindings: add NXP i.MX95 compatible string
      media: synopsys: Add support for i.MX95

 .../bindings/media/rockchip,rk3568-mipi-csi2.yaml  |  16 +++
 drivers/media/platform/synopsys/dw-mipi-csi2rx.c   | 128 ++++++++++++++++++---
 2 files changed, 131 insertions(+), 13 deletions(-)
---
base-commit: bc1ba628e37c93cf2abeb2c79716f49087f8a024
change-id: 20260414-csi2_imx95-65ad0e7f630a

Best regards,
-- 
Guoniu Zhou <guoniu.zhou@oss.nxp.com>


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v4 1/6] media: synopsys: Fix IPI using hardcoded datatype
  2026-05-19  2:07 [PATCH v4 0/6] media: synopsys: enhancements and i.MX95 support Guoniu Zhou
@ 2026-05-19  2:07 ` Guoniu Zhou
  2026-05-19  2:42   ` sashiko-bot
  2026-05-19  2:07 ` [PATCH v4 2/6] media: synopsys: Add support for RAW16 Bayer formats Guoniu Zhou
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 10+ messages in thread
From: Guoniu Zhou @ 2026-05-19  2:07 UTC (permalink / raw)
  To: Michael Riesch, Mauro Carvalho Chehab, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner,
	Laurent Pinchart, Frank Li, Sakari Ailus, Bryan O'Donoghue,
	Mehdi Djait, Hans Verkuil
  Cc: linux-media, linux-kernel, devicetree, imx, linux-arm-kernel,
	linux-rockchip, Guoniu Zhou

The imx93_csi2rx_dphy_ipi_enable() function configures the IPI datatype
using csi2->formats->csi_dt, which is initialized during probe but never
updated in set_fmt(). This causes the IPI to always use the probe-time
default datatype, ignoring the actual media bus format negotiated at
runtime. When userspace requests a different format, the IPI hardware is
configured with the wrong datatype, resulting in incorrect image output.

Fix by updating csi2->formats in the set_fmt callback to reflect the
currently negotiated format, ensuring the IPI configuration matches the
runtime datatype.

Fixes: ec40b431f0ab ("media: synopsys: csi2rx: add i.MX93 support")
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Guoniu Zhou <guoniu.zhou@oss.nxp.com>
---
Changes in v3:
- Fix formats array out-of-bounds read during enumeration
- Add NULL check for csi2->formats to handle unexpected format lookup failures

Changes in v2:
- New added in v2
---
 drivers/media/platform/synopsys/dw-mipi-csi2rx.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/synopsys/dw-mipi-csi2rx.c b/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
index 02eb4a6cafad..0b80e84983f9 100644
--- a/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
+++ b/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
@@ -311,7 +311,7 @@ dw_mipi_csi2rx_find_format(struct dw_mipi_csi2rx_device *csi2, u32 mbus_code)
 	WARN_ON(csi2->formats_num == 0);
 
 	for (unsigned int i = 0; i < csi2->formats_num; i++) {
-		const struct dw_mipi_csi2rx_format *format = &csi2->formats[i];
+		const struct dw_mipi_csi2rx_format *format = &formats[i];
 
 		if (format->code == mbus_code)
 			return format;
@@ -433,7 +433,7 @@ dw_mipi_csi2rx_enum_mbus_code(struct v4l2_subdev *sd,
 		if (code->index >= csi2->formats_num)
 			return -EINVAL;
 
-		code->code = csi2->formats[code->index].code;
+		code->code = formats[code->index].code;
 		return 0;
 	default:
 		return -EINVAL;
@@ -470,6 +470,17 @@ static int dw_mipi_csi2rx_set_fmt(struct v4l2_subdev *sd,
 
 	*src = *sink;
 
+	/* Store the CSIS format descriptor for active formats. */
+	if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
+		csi2->formats = fmt ? :
+			dw_mipi_csi2rx_find_format(csi2, default_format.code);
+
+		if (!csi2->formats) {
+			dev_err(csi2->dev, "Failed to find valid format\n");
+			return -EINVAL;
+		}
+	}
+
 	return 0;
 }
 

-- 
2.34.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v4 2/6] media: synopsys: Add support for RAW16 Bayer formats
  2026-05-19  2:07 [PATCH v4 0/6] media: synopsys: enhancements and i.MX95 support Guoniu Zhou
  2026-05-19  2:07 ` [PATCH v4 1/6] media: synopsys: Fix IPI using hardcoded datatype Guoniu Zhou
@ 2026-05-19  2:07 ` Guoniu Zhou
  2026-05-19  2:07 ` [PATCH v4 3/6] media: synopsys: Add support for multiple streams Guoniu Zhou
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Guoniu Zhou @ 2026-05-19  2:07 UTC (permalink / raw)
  To: Michael Riesch, Mauro Carvalho Chehab, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner,
	Laurent Pinchart, Frank Li, Sakari Ailus, Bryan O'Donoghue,
	Mehdi Djait, Hans Verkuil
  Cc: linux-media, linux-kernel, devicetree, imx, linux-arm-kernel,
	linux-rockchip, Guoniu Zhou

Add higher bit-depth raw image data support for the sensors, which supports
16-bit output.

Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Guoniu Zhou <guoniu.zhou@oss.nxp.com>
---
Changes in v2:
- Update commit message
---
 drivers/media/platform/synopsys/dw-mipi-csi2rx.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/drivers/media/platform/synopsys/dw-mipi-csi2rx.c b/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
index 0b80e84983f9..f45466ede2bb 100644
--- a/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
+++ b/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
@@ -252,6 +252,26 @@ static const struct dw_mipi_csi2rx_format formats[] = {
 		.depth = 12,
 		.csi_dt = MIPI_CSI2_DT_RAW12,
 	},
+	{
+		.code = MEDIA_BUS_FMT_SBGGR16_1X16,
+		.depth = 16,
+		.csi_dt = MIPI_CSI2_DT_RAW16,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SGBRG16_1X16,
+		.depth = 16,
+		.csi_dt = MIPI_CSI2_DT_RAW16,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SGRBG16_1X16,
+		.depth = 16,
+		.csi_dt = MIPI_CSI2_DT_RAW16,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SRGGB16_1X16,
+		.depth = 16,
+		.csi_dt = MIPI_CSI2_DT_RAW16,
+	},
 };
 
 static inline struct dw_mipi_csi2rx_device *to_csi2(struct v4l2_subdev *sd)

-- 
2.34.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v4 3/6] media: synopsys: Add support for multiple streams
  2026-05-19  2:07 [PATCH v4 0/6] media: synopsys: enhancements and i.MX95 support Guoniu Zhou
  2026-05-19  2:07 ` [PATCH v4 1/6] media: synopsys: Fix IPI using hardcoded datatype Guoniu Zhou
  2026-05-19  2:07 ` [PATCH v4 2/6] media: synopsys: Add support for RAW16 Bayer formats Guoniu Zhou
@ 2026-05-19  2:07 ` Guoniu Zhou
  2026-05-19  3:37   ` sashiko-bot
  2026-05-19  2:07 ` [PATCH v4 4/6] media: synopsys: Add PHY stopstate wait for i.MX93 Guoniu Zhou
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 10+ messages in thread
From: Guoniu Zhou @ 2026-05-19  2:07 UTC (permalink / raw)
  To: Michael Riesch, Mauro Carvalho Chehab, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner,
	Laurent Pinchart, Frank Li, Sakari Ailus, Bryan O'Donoghue,
	Mehdi Djait, Hans Verkuil
  Cc: linux-media, linux-kernel, devicetree, imx, linux-arm-kernel,
	linux-rockchip, Guoniu Zhou

The current driver only supports single stream operation. Add support
for multiple concurrent streams by tracking enabled streams with a
bitmask and only initializing the hardware once for the first stream.

This enables use cases such as surround view systems where multiple
camera streams need to be processed simultaneously through the same
CSI-2 receiver interface.

Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Guoniu Zhou <guoniu.zhou@oss.nxp.com>
---
Changes in v3:
- Call pm_runtime_put() after dw_mipi_csi2rx_stop()
- Balance PM runtime get/put for asymmetric stream enable/disable operations

Changes in v2:
- Simplify error handling by keeping goto labels instead of early returns
---
 drivers/media/platform/synopsys/dw-mipi-csi2rx.c | 35 ++++++++++++++++--------
 1 file changed, 24 insertions(+), 11 deletions(-)

diff --git a/drivers/media/platform/synopsys/dw-mipi-csi2rx.c b/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
index f45466ede2bb..92178a3dec5d 100644
--- a/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
+++ b/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
@@ -113,6 +113,7 @@ struct dw_mipi_csi2rx_device {
 
 	enum v4l2_mbus_type bus_type;
 	u32 lanes_num;
+	u64 enabled_streams;
 
 	const struct dw_mipi_csi2rx_drvdata *drvdata;
 };
@@ -539,26 +540,33 @@ static int dw_mipi_csi2rx_enable_streams(struct v4l2_subdev *sd,
 					       DW_MIPI_CSI2RX_PAD_SRC,
 					       &streams_mask);
 
-	ret = pm_runtime_resume_and_get(dev);
-	if (ret)
-		goto err;
+	if (!csi2->enabled_streams) {
+		ret = pm_runtime_resume_and_get(dev);
+		if (ret)
+			goto err;
 
-	ret = dw_mipi_csi2rx_start(csi2);
-	if (ret) {
-		dev_err(dev, "failed to enable CSI hardware\n");
-		goto err_pm_runtime_put;
+		ret = dw_mipi_csi2rx_start(csi2);
+		if (ret) {
+			dev_err(dev, "failed to enable CSI hardware\n");
+			goto err_pm_runtime_put;
+		}
 	}
 
 	ret = v4l2_subdev_enable_streams(remote_sd, remote_pad->index, mask);
 	if (ret)
 		goto err_csi_stop;
 
+	csi2->enabled_streams |= streams_mask;
+
 	return 0;
 
 err_csi_stop:
-	dw_mipi_csi2rx_stop(csi2);
+	/* Stop CSI hardware if no streams are enabled */
+	if (!csi2->enabled_streams)
+		dw_mipi_csi2rx_stop(csi2);
 err_pm_runtime_put:
-	pm_runtime_put(dev);
+	if (!csi2->enabled_streams)
+		pm_runtime_put(dev);
 err:
 	return ret;
 }
@@ -583,10 +591,15 @@ static int dw_mipi_csi2rx_disable_streams(struct v4l2_subdev *sd,
 					       &streams_mask);
 
 	ret = v4l2_subdev_disable_streams(remote_sd, remote_pad->index, mask);
+	if (ret)
+		dev_err(dev, "failed to disable streams on remote subdev: %d\n", ret);
 
-	dw_mipi_csi2rx_stop(csi2);
+	csi2->enabled_streams &= ~streams_mask;
 
-	pm_runtime_put(dev);
+	if (!csi2->enabled_streams) {
+		dw_mipi_csi2rx_stop(csi2);
+		pm_runtime_put(dev);
+	}
 
 	return ret;
 }

-- 
2.34.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v4 4/6] media: synopsys: Add PHY stopstate wait for i.MX93
  2026-05-19  2:07 [PATCH v4 0/6] media: synopsys: enhancements and i.MX95 support Guoniu Zhou
                   ` (2 preceding siblings ...)
  2026-05-19  2:07 ` [PATCH v4 3/6] media: synopsys: Add support for multiple streams Guoniu Zhou
@ 2026-05-19  2:07 ` Guoniu Zhou
  2026-05-19  4:01   ` sashiko-bot
  2026-05-19  2:07 ` [PATCH v4 5/6] media: dt-bindings: add NXP i.MX95 compatible string Guoniu Zhou
  2026-05-19  2:07 ` [PATCH v4 6/6] media: synopsys: Add support for i.MX95 Guoniu Zhou
  5 siblings, 1 reply; 10+ messages in thread
From: Guoniu Zhou @ 2026-05-19  2:07 UTC (permalink / raw)
  To: Michael Riesch, Mauro Carvalho Chehab, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner,
	Laurent Pinchart, Frank Li, Sakari Ailus, Bryan O'Donoghue,
	Mehdi Djait, Hans Verkuil
  Cc: linux-media, linux-kernel, devicetree, imx, linux-arm-kernel,
	linux-rockchip, Guoniu Zhou

Implement waiting for D-PHY lanes to enter stop state on i.MX93. This
ensures proper PHY initialization by verifying that the clock lane and
all active data lanes have entered the stop state before proceeding with
further operations.

Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Guoniu Zhou <guoniu.zhou@oss.nxp.com>
---
Changes in v2:
- Removes redundant register availability check
- Uses read_poll_timeout() with dw_mipi_csi2rx_read() instead of
  readl_poll_timeout() with direct register address
- Fixes stopstate condition logic
- Check PHY stopstate after sensor enable instead of before to ensure
  correct timing.
- Optimize PHY stopstate polling parameters (1000us->10us, 2s->1ms) to
  balance performance and responsiveness.
---
 drivers/media/platform/synopsys/dw-mipi-csi2rx.c | 36 ++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/drivers/media/platform/synopsys/dw-mipi-csi2rx.c b/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
index 92178a3dec5d..8a34aec550ad 100644
--- a/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
+++ b/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
@@ -11,6 +11,7 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/io.h>
+#include <linux/iopoll.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/phy/phy.h>
@@ -35,6 +36,8 @@
 #define DW_REG_EXIST		BIT(31)
 #define DW_REG(x)		(DW_REG_EXIST | (x))
 
+#define DPHY_STOPSTATE_CLK_LANE		BIT(16)
+
 #define DPHY_TEST_CTRL0_TEST_CLR	BIT(0)
 
 #define IPI_VCID_VC(x)			FIELD_PREP(GENMASK(1, 0), (x))
@@ -65,6 +68,7 @@ enum dw_mipi_csi2rx_regs_index {
 	DW_MIPI_CSI2RX_PHY_TST_CTRL0,
 	DW_MIPI_CSI2RX_PHY_TST_CTRL1,
 	DW_MIPI_CSI2RX_PHY_SHUTDOWNZ,
+	DW_MIPI_CSI2RX_PHY_STOPSTATE,
 	DW_MIPI_CSI2RX_IPI_DATATYPE,
 	DW_MIPI_CSI2RX_IPI_MEM_FLUSH,
 	DW_MIPI_CSI2RX_IPI_MODE,
@@ -87,6 +91,7 @@ struct dw_mipi_csi2rx_drvdata {
 	void (*dphy_assert_reset)(struct dw_mipi_csi2rx_device *csi2);
 	void (*dphy_deassert_reset)(struct dw_mipi_csi2rx_device *csi2);
 	void (*ipi_enable)(struct dw_mipi_csi2rx_device *csi2);
+	int (*wait_for_phy_stopstate)(struct dw_mipi_csi2rx_device *csi2);
 };
 
 struct dw_mipi_csi2rx_format {
@@ -139,6 +144,7 @@ static const u32 imx93_regs[DW_MIPI_CSI2RX_MAX] = {
 	[DW_MIPI_CSI2RX_PHY_SHUTDOWNZ] = DW_REG(0x40),
 	[DW_MIPI_CSI2RX_DPHY_RSTZ] = DW_REG(0x44),
 	[DW_MIPI_CSI2RX_PHY_STATE] = DW_REG(0x48),
+	[DW_MIPI_CSI2RX_PHY_STOPSTATE] = DW_REG(0x4c),
 	[DW_MIPI_CSI2RX_PHY_TST_CTRL0] = DW_REG(0x50),
 	[DW_MIPI_CSI2RX_PHY_TST_CTRL1] = DW_REG(0x54),
 	[DW_MIPI_CSI2RX_IPI_MODE] = DW_REG(0x80),
@@ -556,10 +562,19 @@ static int dw_mipi_csi2rx_enable_streams(struct v4l2_subdev *sd,
 	if (ret)
 		goto err_csi_stop;
 
+	if (!csi2->enabled_streams &&
+	    csi2->drvdata->wait_for_phy_stopstate) {
+		ret = csi2->drvdata->wait_for_phy_stopstate(csi2);
+		if (ret)
+			goto err_disable_streams;
+	}
+
 	csi2->enabled_streams |= streams_mask;
 
 	return 0;
 
+err_disable_streams:
+	v4l2_subdev_disable_streams(remote_sd, remote_pad->index, mask);
 err_csi_stop:
 	/* Stop CSI hardware if no streams are enabled */
 	if (!csi2->enabled_streams)
@@ -871,11 +886,32 @@ static void imx93_csi2rx_dphy_ipi_enable(struct dw_mipi_csi2rx_device *csi2)
 	dw_mipi_csi2rx_write(csi2, DW_MIPI_CSI2RX_IPI_MODE, val);
 }
 
+static int imx93_csi2rx_wait_for_phy_stopstate(struct dw_mipi_csi2rx_device *csi2)
+{
+	struct device *dev = csi2->dev;
+	u32 stopstate_mask;
+	u32 val;
+	int ret;
+
+	stopstate_mask = DPHY_STOPSTATE_CLK_LANE | GENMASK(csi2->lanes_num - 1, 0);
+
+	ret = read_poll_timeout(dw_mipi_csi2rx_read, val,
+				(val & stopstate_mask) == stopstate_mask,
+				 10, 1000, true,
+				 csi2, DW_MIPI_CSI2RX_PHY_STOPSTATE);
+	if (ret)
+		dev_err(dev, "lanes are not in stop state: %#x, expected %#x\n",
+			val, stopstate_mask);
+
+	return ret;
+}
+
 static const struct dw_mipi_csi2rx_drvdata imx93_drvdata = {
 	.regs = imx93_regs,
 	.dphy_assert_reset = imx93_csi2rx_dphy_assert_reset,
 	.dphy_deassert_reset = imx93_csi2rx_dphy_deassert_reset,
 	.ipi_enable = imx93_csi2rx_dphy_ipi_enable,
+	.wait_for_phy_stopstate = imx93_csi2rx_wait_for_phy_stopstate,
 };
 
 static const struct of_device_id dw_mipi_csi2rx_of_match[] = {

-- 
2.34.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v4 5/6] media: dt-bindings: add NXP i.MX95 compatible string
  2026-05-19  2:07 [PATCH v4 0/6] media: synopsys: enhancements and i.MX95 support Guoniu Zhou
                   ` (3 preceding siblings ...)
  2026-05-19  2:07 ` [PATCH v4 4/6] media: synopsys: Add PHY stopstate wait for i.MX93 Guoniu Zhou
@ 2026-05-19  2:07 ` Guoniu Zhou
  2026-05-19  2:07 ` [PATCH v4 6/6] media: synopsys: Add support for i.MX95 Guoniu Zhou
  5 siblings, 0 replies; 10+ messages in thread
From: Guoniu Zhou @ 2026-05-19  2:07 UTC (permalink / raw)
  To: Michael Riesch, Mauro Carvalho Chehab, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner,
	Laurent Pinchart, Frank Li, Sakari Ailus, Bryan O'Donoghue,
	Mehdi Djait, Hans Verkuil
  Cc: linux-media, linux-kernel, devicetree, imx, linux-arm-kernel,
	linux-rockchip, Guoniu Zhou, Krzysztof Kozlowski

The i.MX95 CSI-2 controller is nearly identical to i.MX93, with the
main difference being the data output interface:

i.MX93 use IPI (Image Pixel Interface), which requires:
- Pixel clock input
- Software configuration through registers

i.MX95 uses IDI (Image Data Interface), which:
- Does not require pixel clock
- Is software transparent (no register configuration needed)

Due to these differences in register layout and initialization needs,
the two variants cannot share the same compatible string. The driver
needs to distinguish between them to handle the interface correctly.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Guoniu Zhou <guoniu.zhou@oss.nxp.com>
---
Changes in v3:
- Add Reviewed-by tag from Krzysztof Kozlowski

Changes in v2:
- Add dedicated constraint block for i.MX95 to reflect different clock
  requirements (only per clock needed vs i.MX93 which needs both per
  and pixel clocks)
- Update commit message to include more details about interface differences
---
 .../bindings/media/rockchip,rk3568-mipi-csi2.yaml        | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/Documentation/devicetree/bindings/media/rockchip,rk3568-mipi-csi2.yaml b/Documentation/devicetree/bindings/media/rockchip,rk3568-mipi-csi2.yaml
index fbcf28e9e1da..8bfad0fca3b7 100644
--- a/Documentation/devicetree/bindings/media/rockchip,rk3568-mipi-csi2.yaml
+++ b/Documentation/devicetree/bindings/media/rockchip,rk3568-mipi-csi2.yaml
@@ -19,6 +19,7 @@ properties:
     oneOf:
       - enum:
           - fsl,imx93-mipi-csi2
+          - fsl,imx95-mipi-csi2
           - rockchip,rk3568-mipi-csi2
       - items:
           - enum:
@@ -140,6 +141,21 @@ allOf:
         clock-names:
           minItems: 2
 
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: fsl,imx95-mipi-csi2
+    then:
+      properties:
+        interrupts:
+          maxItems: 1
+        interrupt-names: false
+        clocks:
+          maxItems: 1
+        clock-names:
+          maxItems: 1
+
 examples:
   - |
     #include <dt-bindings/clock/rk3568-cru.h>

-- 
2.34.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v4 6/6] media: synopsys: Add support for i.MX95
  2026-05-19  2:07 [PATCH v4 0/6] media: synopsys: enhancements and i.MX95 support Guoniu Zhou
                   ` (4 preceding siblings ...)
  2026-05-19  2:07 ` [PATCH v4 5/6] media: dt-bindings: add NXP i.MX95 compatible string Guoniu Zhou
@ 2026-05-19  2:07 ` Guoniu Zhou
  5 siblings, 0 replies; 10+ messages in thread
From: Guoniu Zhou @ 2026-05-19  2:07 UTC (permalink / raw)
  To: Michael Riesch, Mauro Carvalho Chehab, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner,
	Laurent Pinchart, Frank Li, Sakari Ailus, Bryan O'Donoghue,
	Mehdi Djait, Hans Verkuil
  Cc: linux-media, linux-kernel, devicetree, imx, linux-arm-kernel,
	linux-rockchip, Guoniu Zhou

Add support for the i.MX95 MIPI CSI-2 receiver. The i.MX95 variant is
nearly identical to i.MX93, with the main difference being the use of
IDI (Image Data Interface) instead of IPI (Image Pixel Interface).
However, the IDI interface is transparent to software, requiring only
a different register map definition while sharing the same PHY control
functions with i.MX93.

Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Guoniu Zhou <guoniu.zhou@oss.nxp.com>
---
Changes in v2:
- Add Reviewed-by tag from Frank Li <Frank.Li@nxp.com>
---
 drivers/media/platform/synopsys/dw-mipi-csi2rx.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/drivers/media/platform/synopsys/dw-mipi-csi2rx.c b/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
index 8a34aec550ad..41e48365167e 100644
--- a/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
+++ b/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
@@ -154,6 +154,17 @@ static const u32 imx93_regs[DW_MIPI_CSI2RX_MAX] = {
 	[DW_MIPI_CSI2RX_IPI_SOFTRSTN] = DW_REG(0xa0),
 };
 
+static const u32 imx95_regs[DW_MIPI_CSI2RX_MAX] = {
+	[DW_MIPI_CSI2RX_N_LANES] = DW_REG(0x4),
+	[DW_MIPI_CSI2RX_RESETN] = DW_REG(0x8),
+	[DW_MIPI_CSI2RX_PHY_SHUTDOWNZ] = DW_REG(0x40),
+	[DW_MIPI_CSI2RX_DPHY_RSTZ] = DW_REG(0x44),
+	[DW_MIPI_CSI2RX_PHY_STATE] = DW_REG(0x48),
+	[DW_MIPI_CSI2RX_PHY_STOPSTATE] = DW_REG(0x4c),
+	[DW_MIPI_CSI2RX_PHY_TST_CTRL0] = DW_REG(0x50),
+	[DW_MIPI_CSI2RX_PHY_TST_CTRL1] = DW_REG(0x54),
+};
+
 static const struct v4l2_mbus_framefmt default_format = {
 	.width = 3840,
 	.height = 2160,
@@ -914,11 +925,22 @@ static const struct dw_mipi_csi2rx_drvdata imx93_drvdata = {
 	.wait_for_phy_stopstate = imx93_csi2rx_wait_for_phy_stopstate,
 };
 
+static const struct dw_mipi_csi2rx_drvdata imx95_drvdata = {
+	.regs = imx95_regs,
+	.dphy_assert_reset = imx93_csi2rx_dphy_assert_reset,
+	.dphy_deassert_reset = imx93_csi2rx_dphy_deassert_reset,
+	.wait_for_phy_stopstate = imx93_csi2rx_wait_for_phy_stopstate,
+};
+
 static const struct of_device_id dw_mipi_csi2rx_of_match[] = {
 	{
 		.compatible = "fsl,imx93-mipi-csi2",
 		.data = &imx93_drvdata,
 	},
+	{
+		.compatible = "fsl,imx95-mipi-csi2",
+		.data = &imx95_drvdata,
+	},
 	{
 		.compatible = "rockchip,rk3568-mipi-csi2",
 		.data = &rk3568_drvdata,

-- 
2.34.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH v4 1/6] media: synopsys: Fix IPI using hardcoded datatype
  2026-05-19  2:07 ` [PATCH v4 1/6] media: synopsys: Fix IPI using hardcoded datatype Guoniu Zhou
@ 2026-05-19  2:42   ` sashiko-bot
  0 siblings, 0 replies; 10+ messages in thread
From: sashiko-bot @ 2026-05-19  2:42 UTC (permalink / raw)
  To: Guoniu Zhou; +Cc: robh, conor+dt, Frank.Li, imx, devicetree

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] If userspace starts streaming without explicitly calling `VIDIOC_SUBDEV_S_FMT`, the driver will use an incorrect hardware datatype due to a mismatch between the probe-time pointer and the V4L2 default state.
- [High] Caching the active format in a device-global pointer (`csi2->formats`) during `set_fmt` circumvents the V4L2 subdev state API, causing state corruption and hardware misconfiguration when multiple streams are used.
- [Medium] The patch confusingly repurposes an array pointer (`csi2->formats`) into a single active state pointer, while retaining its paired array-bounds variable.
--

commit ac0f1e2d8d5a5aefaf04a50efcbfbc4c7693090d
Author: Guoniu Zhou <guoniu.zhou@oss.nxp.com>

media: synopsys: Fix IPI using hardcoded datatype

This commit updates the set_fmt callback to reflect the negotiated active
format by storing it in csi2->formats. This ensures the IPI configuration
matches the runtime datatype instead of the probe-time default.

> diff --git a/drivers/media/platform/synopsys/dw-mipi-csi2rx.c b/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
> index 02eb4a6cafade..0b80e84983f9e 100644
> --- a/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
> +++ b/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
> @@ -311,7 +311,7 @@ dw_mipi_csi2rx_find_format(struct dw_mipi_csi2rx_device *csi2, u32 mbus_code)
>  	WARN_ON(csi2->formats_num == 0);
>  
>  	for (unsigned int i = 0; i < csi2->formats_num; i++) {
> -		const struct dw_mipi_csi2rx_format *format = &csi2->formats[i];
> +		const struct dw_mipi_csi2rx_format *format = &formats[i];

Does this repurpose the csi2->formats array pointer to store a single active
format, while leaving csi2->formats_num as the array length?

This decouples the pointer from its length variable. Iterating over a global
formats array instead of the instance fields might also bypass device
encapsulation and create a semantic mismatch.

[ ... ]

> @@ -470,6 +470,17 @@ static int dw_mipi_csi2rx_set_fmt(struct v4l2_subdev *sd,
>  
>  	*src = *sink;
>  
> +	/* Store the CSIS format descriptor for active formats. */
> +	if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
> +		csi2->formats = fmt ? :
> +			dw_mipi_csi2rx_find_format(csi2, default_format.code);

Does caching the active format in a device-global pointer (csi2->formats)
circumvent the V4L2 subdev state API?

If multiple streams are configured via V4L2_SUBDEV_FL_STREAMS, it appears this
single pointer would be repeatedly overwritten, storing only the format of the
last configured stream.

Could this create a regression when the streams are enabled? The hardware would
be programmed with this last format, which could cause issues for any streams
that negotiated a different format. Would it be better to retrieve the active
format dynamically from sd->active_state via v4l2_subdev_state_get_format()
during stream enablement?

Additionally, does this introduce a regression if userspace starts streaming
without explicitly calling VIDIOC_SUBDEV_S_FMT?

During probe, csi2->formats is initialized to the base of the formats array,
pointing to the first element (MEDIA_BUS_FMT_YUYV8_1X16). The V4L2 subdev
active state is initialized to default_format (MEDIA_BUS_FMT_SRGGB10_1X10).

If set_fmt(ACTIVE) is never called, csi2->formats is never updated. The
hardware would then be configured for YUV422_8B instead of the expected RAW10,
causing a mismatch between the active V4L2 state and the actual hardware
configuration.

> +		if (!csi2->formats) {
> +			dev_err(csi2->dev, "Failed to find valid format\n");
> +			return -EINVAL;
> +		}
> +	}
> +
>  	return 0;
>  }

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260519-csi2_imx95-v4-0-84ea4bb78a88@oss.nxp.com?part=1

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v4 3/6] media: synopsys: Add support for multiple streams
  2026-05-19  2:07 ` [PATCH v4 3/6] media: synopsys: Add support for multiple streams Guoniu Zhou
@ 2026-05-19  3:37   ` sashiko-bot
  0 siblings, 0 replies; 10+ messages in thread
From: sashiko-bot @ 2026-05-19  3:37 UTC (permalink / raw)
  To: Guoniu Zhou; +Cc: Frank.Li, robh, conor+dt, imx, devicetree

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] Incorrect pad arguments to `v4l2_subdev_state_xlate_streams()` silently corrupt stream masks and cause PM runtime underflows.
- [High] Propagating a remote subdevice disable error causes state desynchronization and double PM runtime put on retry.
--

commit dc1fc68d798970cf70a238272f82256db2545536
Author: Guoniu Zhou <guoniu.zhou@oss.nxp.com>

media: synopsys: Add support for multiple streams

The driver is updated to support multiple concurrent streams by tracking
enabled streams with a bitmask, instead of only supporting single stream
operation. The hardware is now initialized only once for the first stream.

> diff --git a/drivers/media/platform/synopsys/dw-mipi-csi2rx.c b/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
> index f45466ede2bb7..92178a3dec5d5 100644
> --- a/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
> +++ b/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
[ ... ]
> @@ -539,26 +540,33 @@ static int dw_mipi_csi2rx_enable_streams(struct v4l2_subdev *sd,
>  					       DW_MIPI_CSI2RX_PAD_SRC,
>  					       &streams_mask);
>  
> -	ret = pm_runtime_resume_and_get(dev);
> -	if (ret)
> -		goto err;
> +	if (!csi2->enabled_streams) {
> +		ret = pm_runtime_resume_and_get(dev);

Does this sequence properly handle the streams_mask translation?

The .enable_streams() and .disable_streams() operations are exclusively
invoked on source pads, meaning streams_mask represents the streams on
DW_MIPI_CSI2RX_PAD_SRC.

When calling v4l2_subdev_state_xlate_streams(), the driver passes
DW_MIPI_CSI2RX_PAD_SINK as pad0 and DW_MIPI_CSI2RX_PAD_SRC as pad1. However,
the helper expects *streams to be the mask for pad0.

Because the helper evaluates the SRC streams mask against route->sink_stream,
translation will fail for any asymmetric routing where sink and source stream
IDs differ.

On failure, streams_mask is mutated to 0. In enable_streams(), this results
in pm_runtime_resume_and_get() executing, but csi2->enabled_streams remaining
0.

Since the V4L2 core still marks the stream as enabled, userspace could
interleave symmetric and asymmetric stream enable/disable calls (e.g., enable
symmetric -> PM get; enable asymmetric -> no PM get; disable symmetric ->
PM put; disable asymmetric -> PM put).

Could this sequence underflow the PM runtime usage counter and PHY power
count, breaking device power management?

[ ... ]
> @@ -583,10 +591,15 @@ static int dw_mipi_csi2rx_disable_streams(struct v4l2_subdev *sd,
>  					       &streams_mask);
>  
>  	ret = v4l2_subdev_disable_streams(remote_sd, remote_pad->index, mask);
> +	if (ret)
> +		dev_err(dev, "failed to disable streams on remote subdev: %d\n", ret);
>  
> -	dw_mipi_csi2rx_stop(csi2);
> +	csi2->enabled_streams &= ~streams_mask;
>  
> -	pm_runtime_put(dev);
> +	if (!csi2->enabled_streams) {
> +		dw_mipi_csi2rx_stop(csi2);
> +		pm_runtime_put(dev);
> +	}
>  
>  	return ret;

Could propagating the remote disable error here cause state synchronization
issues with the V4L2 core?

If v4l2_subdev_disable_streams() on the remote subdevice fails, the driver
proceeds to clear its local state (csi2->enabled_streams &= ~streams_mask),
shuts down the hardware, and calls pm_runtime_put() if the mask becomes 0.

The driver then returns the error to the V4L2 core. Because of this error,
the V4L2 core aborts and skips marking the stream as disabled, meaning the
framework still considers the stream active.

If userspace retries the disable operation, the driver will be invoked again.
Since csi2->enabled_streams was already cleared, !csi2->enabled_streams would
evaluate to true again. This results in a redundant dw_mipi_csi2rx_stop() and
pm_runtime_put() being executed.

Could this lead to a PM usage underflow and illegal writes to powered-off
PHY registers?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260519-csi2_imx95-v4-0-84ea4bb78a88@oss.nxp.com?part=3

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v4 4/6] media: synopsys: Add PHY stopstate wait for i.MX93
  2026-05-19  2:07 ` [PATCH v4 4/6] media: synopsys: Add PHY stopstate wait for i.MX93 Guoniu Zhou
@ 2026-05-19  4:01   ` sashiko-bot
  0 siblings, 0 replies; 10+ messages in thread
From: sashiko-bot @ 2026-05-19  4:01 UTC (permalink / raw)
  To: Guoniu Zhou; +Cc: imx, devicetree, robh, Frank.Li, conor+dt

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Waiting for the PHY stop state (LP-11) after enabling the remote sensor streams introduces a severe race condition, causing initialization timeouts and capture failures.
--

commit 804a163365664b371b9f8e8d039f139d325044c6
Author: Guoniu Zhou <guoniu.zhou@oss.nxp.com>

media: synopsys: Add PHY stopstate wait for i.MX93

This commit implements waiting for D-PHY lanes to enter stop state on
i.MX93. This ensures proper PHY initialization by verifying that the clock
lane and all active data lanes have entered the stop state before proceeding
with further operations.

> diff --git a/drivers/media/platform/synopsys/dw-mipi-csi2rx.c b/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
> index 92178a3dec5d5..8a34aec550ade 100644
> --- a/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
> +++ b/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
[ ... ]
> @@ -556,10 +562,19 @@ static int dw_mipi_csi2rx_enable_streams(struct v4l2_subdev *sd,
>  	if (ret)
>  		goto err_csi_stop;
>  
> +	if (!csi2->enabled_streams &&
> +	    csi2->drvdata->wait_for_phy_stopstate) {
> +		ret = csi2->drvdata->wait_for_phy_stopstate(csi2);
> +		if (ret)
> +			goto err_disable_streams;
> +	}

Is there a race condition between enabling the remote streams and waiting
for the PHY to enter the stop state (LP-11)?

In dw_mipi_csi2rx_enable_streams(), v4l2_subdev_enable_streams() is called
just before this wait_for_phy_stopstate() block. Enabling the sensor stream
commands it to leave the stop state and enter High Speed (HS) mode to
transmit data.

By the time the polling loop in wait_for_phy_stopstate() reads the
DW_MIPI_CSI2RX_PHY_STOPSTATE register, the sensor might have already
transitioned to HS mode, especially since the polling loop uses
sleep_before_read = true. In HS mode, the lanes are actively toggling and
are no longer in the stop state.

Could this cause the polling loop to never detect the required stop state,
resulting in a -ETIMEDOUT error and causing the stream enablement to fail?

Should the stop state check occur before enabling the remote subdev streams?

> +
>  	csi2->enabled_streams |= streams_mask;
>  
>  	return 0;

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260519-csi2_imx95-v4-0-84ea4bb78a88@oss.nxp.com?part=4

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2026-05-19  4:01 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-19  2:07 [PATCH v4 0/6] media: synopsys: enhancements and i.MX95 support Guoniu Zhou
2026-05-19  2:07 ` [PATCH v4 1/6] media: synopsys: Fix IPI using hardcoded datatype Guoniu Zhou
2026-05-19  2:42   ` sashiko-bot
2026-05-19  2:07 ` [PATCH v4 2/6] media: synopsys: Add support for RAW16 Bayer formats Guoniu Zhou
2026-05-19  2:07 ` [PATCH v4 3/6] media: synopsys: Add support for multiple streams Guoniu Zhou
2026-05-19  3:37   ` sashiko-bot
2026-05-19  2:07 ` [PATCH v4 4/6] media: synopsys: Add PHY stopstate wait for i.MX93 Guoniu Zhou
2026-05-19  4:01   ` sashiko-bot
2026-05-19  2:07 ` [PATCH v4 5/6] media: dt-bindings: add NXP i.MX95 compatible string Guoniu Zhou
2026-05-19  2:07 ` [PATCH v4 6/6] media: synopsys: Add support for i.MX95 Guoniu Zhou

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox