* [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:07 ` [PATCH v4 2/6] media: synopsys: Add support for RAW16 Bayer formats Guoniu Zhou
` (4 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
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 2:07 ` [PATCH v4 4/6] media: synopsys: Add PHY stopstate wait for i.MX93 Guoniu Zhou
` (2 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
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-20 11:12 ` Alexander Stein
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* 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-20 11:12 ` Alexander Stein
2026-05-21 9:29 ` G.N. Zhou (OSS)
0 siblings, 1 reply; 10+ messages in thread
From: Alexander Stein @ 2026-05-20 11:12 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, Guoniu Zhou
Cc: linux-media, linux-kernel, devicetree, imx, linux-arm-kernel,
linux-rockchip, Guoniu Zhou
Hi,
Am Dienstag, 19. Mai 2026, 04:07:41 CEST schrieb 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);
Did you actually test this on imx93? I'm trying to get my imx327 sensor to
run, but only run into this error message:
dw-mipi-csi2rx 4ae00000.mipi-csi: lanes are not in stop state: 0x0, expected 0x10003
Currently I'm using this DT node:
--8<--
mipi_csi: mipi-csi@4ae00000 {
compatible = "fsl,imx93-mipi-csi2";
reg = <0x4ae00000 0x10000>;
interrupts = <GIC_SPI 175 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk IMX93_CLK_MIPI_CSI_GATE>,
<&clk IMX93_CLK_CAM_PIX>;
clock-names = "per", "pixel";
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>;
phys = <&dphy_rx>;
phy-names = "dphy-rx";
status = "disabled";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
mipi_from_sensor: endpoint {
data-lanes = <1 2>;
bus-type = <MEDIA_BUS_TYPE_CSI2_DPHY>;
};
};
port@1 {
reg = <1>;
mipi_to_isi: endpoint {
remote-endpoint = <&isi_in>;
};
};
};
};
--8<--
Am I'm missing something?
best regards,
Alexander
> +
> + 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[] = {
>
>
--
TQ-Systems GmbH | Mühlstraße 2, Gut Delling | 82229 Seefeld, Germany
Amtsgericht München, HRB 105018
Geschäftsführer: Detlef Schneider, Rüdiger Stahl, Stefan Schneider
http://www.tq-group.com/
^ 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-20 11:12 ` Alexander Stein
@ 2026-05-21 9:29 ` G.N. Zhou (OSS)
2026-05-21 11:52 ` Alexander Stein
0 siblings, 1 reply; 10+ messages in thread
From: G.N. Zhou (OSS) @ 2026-05-21 9:29 UTC (permalink / raw)
To: Alexander Stein, 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, G.N. Zhou (OSS)
Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org,
devicetree@vger.kernel.org, imx@lists.linux.dev,
linux-arm-kernel@lists.infradead.org,
linux-rockchip@lists.infradead.org, G.N. Zhou (OSS)
Hi Alexander,
> -----Original Message-----
> From: Alexander Stein <alexander.stein@ew.tq-group.com>
> Sent: Wednesday, May 20, 2026 7:12 PM
> To: Michael Riesch <michael.riesch@collabora.com>; Mauro Carvalho Chehab
> <mchehab@kernel.org>; Rob Herring <robh@kernel.org>; Krzysztof Kozlowski
> <krzk+dt@kernel.org>; Conor Dooley <conor+dt@kernel.org>; Heiko Stuebner
> <heiko@sntech.de>; Laurent Pinchart <laurent.pinchart@ideasonboard.com>;
> Frank Li <frank.li@nxp.com>; Sakari Ailus <sakari.ailus@linux.intel.com>; Bryan
> O'Donoghue <bryan.odonoghue@linaro.org>; Mehdi Djait
> <mehdi.djait@linux.intel.com>; Hans Verkuil <hverkuil+cisco@kernel.org>;
> G.N. Zhou (OSS) <guoniu.zhou@oss.nxp.com>
> Cc: linux-media@vger.kernel.org; linux-kernel@vger.kernel.org;
> devicetree@vger.kernel.org; imx@lists.linux.dev; linux-arm-
> kernel@lists.infradead.org; linux-rockchip@lists.infradead.org; G.N. Zhou (OSS)
> <guoniu.zhou@oss.nxp.com>
> Subject: Re: [PATCH v4 4/6] media: synopsys: Add PHY stopstate wait for
> i.MX93
>
> Hi,
>
> Am Dienstag, 19. Mai 2026, 04:07:41 CEST schrieb 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);
>
> Did you actually test this on imx93? I'm trying to get my imx327 sensor to run,
> but only run into this error message:
> dw-mipi-csi2rx 4ae00000.mipi-csi: lanes are not in stop state: 0x0, expected
> 0x10003
Thanks for testing. Regarding the lane stop state error on i.MX93 with imx327:
This error indicates the CSI-2 lanes are not in LP-11 (stop) state when
expected. Please check:
1) Verify the sensor PHY is in LP-11 state before returning from the sensor's
s_stream(1) call. The CSI-2 receiver expects lanes to be in stop state
initially.
2) Check if the imx327 driver has a delay between starting the stream and
returning from s_stream(). If the sensor transitions PHY out of LP-11
state during this delay, the CSI driver's lane state check will fail
when it runs later. The sensor should remain in LP-11 until the CSI
controller completes its initialization.
You may need to remove any delays in the imx327 s_stream implementation, or
ensure the sensor stays in LP-11 state until the CSI receiver is ready.
If possible, could you share the imx327 driver code or check its s_stream implementation?
Best Regards
G.N Zhou
>
> Currently I'm using this DT node:
> --8<--
> mipi_csi: mipi-csi@4ae00000 {
> compatible = "fsl,imx93-mipi-csi2";
> reg = <0x4ae00000 0x10000>;
> interrupts = <GIC_SPI 175 IRQ_TYPE_LEVEL_HIGH>;
> clocks = <&clk IMX93_CLK_MIPI_CSI_GATE>,
> <&clk IMX93_CLK_CAM_PIX>;
> clock-names = "per", "pixel";
> 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>;
> phys = <&dphy_rx>;
> phy-names = "dphy-rx";
> status = "disabled";
>
> ports {
> #address-cells = <1>;
> #size-cells = <0>;
>
> port@0 {
> reg = <0>;
>
> mipi_from_sensor: endpoint {
> data-lanes = <1 2>;
> bus-type = <MEDIA_BUS_TYPE_CSI2_DPHY>;
> };
> };
>
> port@1 {
> reg = <1>;
>
> mipi_to_isi: endpoint {
> remote-endpoint = <&isi_in>;
> };
> };
> };
> };
> --8<--
>
> Am I'm missing something?
>
> best regards,
> Alexander
>
> > +
> > + 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[] = {
> >
> >
>
>
> --
> TQ-Systems GmbH | Mühlstraße 2, Gut Delling | 82229 Seefeld, Germany
> Amtsgericht München, HRB 105018
> Geschäftsführer: Detlef Schneider, Rüdiger Stahl, Stefan Schneider
> http://www.tq-group.com/
>
^ 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-21 9:29 ` G.N. Zhou (OSS)
@ 2026-05-21 11:52 ` Alexander Stein
0 siblings, 0 replies; 10+ messages in thread
From: Alexander Stein @ 2026-05-21 11:52 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, G.N. Zhou (OSS), G.N. Zhou (OSS)
Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org,
devicetree@vger.kernel.org, imx@lists.linux.dev,
linux-arm-kernel@lists.infradead.org,
linux-rockchip@lists.infradead.org, G.N. Zhou (OSS)
Hi,
thanks for the replay.
Am Donnerstag, 21. Mai 2026, 11:29:39 CEST schrieb G.N. Zhou (OSS):
> Hi Alexander,
>
> > -----Original Message-----
> > From: Alexander Stein <alexander.stein@ew.tq-group.com>
> > Sent: Wednesday, May 20, 2026 7:12 PM
> > To: Michael Riesch <michael.riesch@collabora.com>; Mauro Carvalho Chehab
> > <mchehab@kernel.org>; Rob Herring <robh@kernel.org>; Krzysztof Kozlowski
> > <krzk+dt@kernel.org>; Conor Dooley <conor+dt@kernel.org>; Heiko Stuebner
> > <heiko@sntech.de>; Laurent Pinchart <laurent.pinchart@ideasonboard.com>;
> > Frank Li <frank.li@nxp.com>; Sakari Ailus <sakari.ailus@linux.intel.com>; Bryan
> > O'Donoghue <bryan.odonoghue@linaro.org>; Mehdi Djait
> > <mehdi.djait@linux.intel.com>; Hans Verkuil <hverkuil+cisco@kernel.org>;
> > G.N. Zhou (OSS) <guoniu.zhou@oss.nxp.com>
> > Cc: linux-media@vger.kernel.org; linux-kernel@vger.kernel.org;
> > devicetree@vger.kernel.org; imx@lists.linux.dev; linux-arm-
> > kernel@lists.infradead.org; linux-rockchip@lists.infradead.org; G.N. Zhou (OSS)
> > <guoniu.zhou@oss.nxp.com>
> > Subject: Re: [PATCH v4 4/6] media: synopsys: Add PHY stopstate wait for
> > i.MX93
> >
> > Hi,
> >
> > Am Dienstag, 19. Mai 2026, 04:07:41 CEST schrieb 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);
> >
> > Did you actually test this on imx93? I'm trying to get my imx327 sensor to run,
> > but only run into this error message:
> > dw-mipi-csi2rx 4ae00000.mipi-csi: lanes are not in stop state: 0x0, expected
> > 0x10003
>
> Thanks for testing. Regarding the lane stop state error on i.MX93 with imx327:
>
> This error indicates the CSI-2 lanes are not in LP-11 (stop) state when
> expected. Please check:
>
> 1) Verify the sensor PHY is in LP-11 state before returning from the sensor's
> s_stream(1) call. The CSI-2 receiver expects lanes to be in stop state
> initially.
Well, this might be tricky as I don't have D-PHY capable scopes.
I can successfully use this sensor on a imx8mp, so I am expecting this to be
okay.
> 2) Check if the imx327 driver has a delay between starting the stream and
> returning from s_stream(). If the sensor transitions PHY out of LP-11
> state during this delay, the CSI driver's lane state check will fail
> when it runs later. The sensor should remain in LP-11 until the CSI
> controller completes its initialization.
In imx290_set_stream() and subsequently imx290_start_streaming() setting
IMX290_XMSTA starts the stream. I expect this is the point when the sensors
switches from LP-11 to HS. But again, I can't verify.
With enabling debug
> echo "module videodev +p" > /sys/kernel/debug/dynamic_debug/control
> echo 0xff > /sys/class/video4linux/video0/dev_debug
After I setup the media pipeline, running the command
> v4l2-ctl -z "platform:4ae40000.isi" -d "mxc_isi.0.capture" --stream-mmap --stream-count=1 --stream-to=imx93.raw
I get the following debug output:
--8<--
plane 0: bytesperline=3840 sizeimage=4147200
mxc-isi 4ae40000.isi: validating link "crossbar":2 -> "mxc_isi.0":0
mxc-isi 4ae40000.isi: validating stream "crossbar":2:0 -> "mxc_isi.0":0:0
mxc-isi 4ae40000.isi: validating link "dw-mipi-csi2rx 4ae00000.mipi-csi":1 -> "crossbar":0
mxc-isi 4ae40000.isi: validating stream "dw-mipi-csi2rx 4ae00000.mipi-csi":1:0 -> "crossbar":0:0
mxc-isi 4ae40000.isi: validating link "imx327 4-001a":0 -> "dw-mipi-csi2rx 4ae00000.mipi-csi":0
mxc-isi 4ae40000.isi: validating stream "imx327 4-001a":0:0 -> "dw-mipi-csi2rx 4ae00000.mipi-csi":0:0
mxc-isi 4ae40000.isi: enable streams "crossbar":2/0x1
mxc-isi 4ae40000.isi: collect_streams: "crossbar":2: found 0x1 enabled 0x0
imx290 4-001a: Frame descriptor on pad 0, type CSI-2
imx290 4-001a: stream 0, code 0x300f, length 0, flags 0x0000, vc 0, dt 0x2b
dw-mipi-csi2rx 4ae00000.mipi-csi: Frame descriptor on pad 1, type CSI-2
dw-mipi-csi2rx 4ae00000.mipi-csi: stream 0, code 0x300f, length 0, flags 0x0000, vc 0, dt 0x2b
mxc-isi 4ae40000.isi: enable streams "dw-mipi-csi2rx 4ae00000.mipi-csi":1/0x1
dw-mipi-csi2rx 4ae00000.mipi-csi: collect_streams: "dw-mipi-csi2rx 4ae00000.mipi-csi":1: found 0x1 enabled 0x0
mxc-isi 4ae40000.isi: enable streams "imx327 4-001a":0/0x1
imx290 4-001a: collect_streams: sub-device "imx327 4-001a" does not support streams
dw-mipi-csi2rx 4ae00000.mipi-csi: lanes are not in stop state: 0x0, expected 0x10003
mxc-isi 4ae40000.isi: disable streams "imx327 4-001a":0/0x1
imx290 4-001a: collect_streams: sub-device "imx327 4-001a" does not support streams
mxc-isi 4ae40000.isi: enable streams 1:0x1 failed: -110
mxc-isi 4ae40000.isi: failed to enable streams 0x1 on 'dw-mipi-csi2rx 4ae00000.mipi-csi':1: -110
mxc-isi 4ae40000.isi: enable streams 2:0x1 failed: -110
mxc-isi 4ae40000.isi: Failed to enable pipe 0
video0: VIDIOC_STREAMON: error -110: type=vid-cap-mplane
videodev: v4l2_release: video0: release
--8<--
For completeness this is my media device config
--8<--
# media-ctl -p
Media controller API version 7.1.0
Media device information
------------------------
driver mxc-isi
model FSL Capture Media Device
serial
bus info platform:4ae40000.isi
hw revision 0x0
driver version 7.1.0
Device topology
- entity 1: crossbar (3 pads, 2 links, 1 route)
type V4L2 subdev subtype Unknown flags 0
device node name /dev/v4l-subdev0
routes:
0/0 -> 2/0 [ACTIVE]
pad0: SINK,MUST_CONNECT
[stream:0 fmt:SRGGB10_1X10/1920x1080 field:none colorspace:raw]
<- "dw-mipi-csi2rx 4ae00000.mipi-cs":1 [ENABLED,IMMUTABLE]
pad1: SINK,MUST_CONNECT
pad2: SOURCE
[stream:0 fmt:SRGGB10_1X10/1920x1080 field:none colorspace:raw]
-> "mxc_isi.0":0 [ENABLED,IMMUTABLE]
- entity 5: mxc_isi.0 (2 pads, 2 links, 0 routes)
type V4L2 subdev subtype Unknown flags 0
device node name /dev/v4l-subdev1
pad0: SINK
[stream:0 fmt:SRGGB10_1X10/1920x1080 field:none colorspace:raw
compose.bounds:(0,0)/1920x1080
compose:(0,0)/1920x1080]
<- "crossbar":2 [ENABLED,IMMUTABLE]
pad1: SOURCE
[stream:0 fmt:SRGGB10_1X10/1920x1080 field:none colorspace:jpeg xfer:srgb ycbcr:601 quantization:full-range
crop.bounds:(0,0)/1920x1080
crop:(0,0)/1920x1080]
-> "mxc_isi.0.capture":0 [ENABLED,IMMUTABLE]
- entity 8: mxc_isi.0.capture (1 pad, 1 link)
type Node subtype V4L flags 0
device node name /dev/video0
pad0: SINK
<- "mxc_isi.0":1 [ENABLED,IMMUTABLE]
- entity 16: dw-mipi-csi2rx 4ae00000.mipi-cs (2 pads, 2 links, 1 route)
type V4L2 subdev subtype Unknown flags 0
device node name /dev/v4l-subdev2
routes:
0/0 -> 1/0 [ACTIVE]
pad0: SINK,MUST_CONNECT
[stream:0 fmt:SRGGB10_1X10/1920x1080 field:none colorspace:raw xfer:none ycbcr:601 quantization:full-range]
<- "imx327 4-001a":0 [ENABLED]
pad1: SOURCE
[stream:0 fmt:SRGGB10_1X10/1920x1080 field:none colorspace:raw xfer:none ycbcr:601 quantization:full-range]
-> "crossbar":0 [ENABLED,IMMUTABLE]
- entity 21: imx327 4-001a (1 pad, 1 link, 0 routes)
type V4L2 subdev subtype Sensor flags 0
device node name /dev/v4l-subdev3
pad0: SOURCE
[stream:0 fmt:SRGGB10_1X10/1920x1080 field:none colorspace:raw xfer:none ycbcr:601 quantization:full-range
crop.bounds:(0,0)/1945x1097
crop:(12,8)/1920x1080]
-> "dw-mipi-csi2rx 4ae00000.mipi-cs":0 [ENABLED]
--8<--
Anything odd here?
> You may need to remove any delays in the imx327 s_stream implementation, or
> ensure the sensor stays in LP-11 state until the CSI receiver is ready.
>
> If possible, could you share the imx327 driver code or check its s_stream implementation?
It's essentially upstream in drivers/media/i2c/imx290.c.
I only have a dummy implementation for get_frame_desc and a small adjustement
for my camera module regarding i2c access.
--8<--
static int imx290_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
struct v4l2_mbus_frame_desc *fd)
{
const struct v4l2_mbus_framefmt *format;
struct v4l2_subdev_state *state;
state = v4l2_subdev_lock_and_get_active_state(sd);
format = v4l2_subdev_state_get_format(state, pad);
v4l2_subdev_unlock_state(state);
fd->type = V4L2_MBUS_FRAME_DESC_TYPE_CSI2;
fd->num_entries = 1;
fd->entry[0].pixelcode = format->code;
fd->entry[0].stream = 0;
fd->entry[0].bus.csi2.vc = 0;
fd->entry[0].bus.csi2.dt = MIPI_CSI2_DT_RAW10; //TODO: get_data_type_by_code(format->code);
return 0;
}
--8<--
Another thing. I use https://lore.kernel.org/imx/20250701-95_cam-v1-2-c5172bab387b@nxp.com/
for the D-PHY. Is there any update/progress on that driver?
Best regards,
Alexander
--
TQ-Systems GmbH | Mühlstraße 2, Gut Delling | 82229 Seefeld, Germany
Amtsgericht München, HRB 105018
Geschäftsführer: Detlef Schneider, Rüdiger Stahl, Stefan Schneider
http://www.tq-group.com/
^ permalink raw reply [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