On Fri Nov 7 11:34:34 2025 +0100, Michael Tretter wrote:
> After media_pipeline_start() was called, the media graph is assumed to
> be validated. It won't be validated again if a second stream starts.
> 
> The imx-media-csi driver, however, changes hardware configuration in the
> link_validate() callback. This can result in started streams with
> misconfigured hardware.
> 
> In the concrete example, the ipu2_csi1 is driven by a parallel video
> input. After the media pipeline has been started with this
> configuration, a second stream is configured to use ipu1_csi0 with
> MIPI-CSI input from imx6-mipi-csi2. This may require the reconfiguration
> of ipu1_csi0 with ipu_set_csi_src_mux(). Since the media pipeline is
> already running, link_validate won't be called, and the ipu1_csi0 won't
> be reconfigured. The resulting video is broken, because the ipu1_csi0 is
> misconfigured, but no error is reported.
> 
> Move ipu_set_csi_src_mux from csi_link_validate to csi_start to ensure
> that input to ipu1_csi0 is configured correctly when starting the
> stream. This is a local reconfiguration in ipu1_csi0 and is possible
> while the media pipeline is running.
> 
> Since csi_start() is called with priv->lock already locked,
> csi_set_src() must not lock priv->lock again. Thus, the mutex_lock() is
> dropped.
> 
> Signed-off-by: Michael Tretter <[email protected]>
> Fixes: 4a34ec8e470c ("[media] media: imx: Add CSI subdev driver")
> Cc: [email protected]
> Reviewed-by: Frank Li <[email protected]>
> Reviewed-by: Philipp Zabel <[email protected]>
> Signed-off-by: Frank Li <[email protected]>
> Signed-off-by: Hans Verkuil <[email protected]>

Patch committed.

Thanks,
Hans Verkuil

 drivers/staging/media/imx/imx-media-csi.c | 44 +++++++++++++++++--------------
 1 file changed, 24 insertions(+), 20 deletions(-)

---

diff --git a/drivers/staging/media/imx/imx-media-csi.c 
b/drivers/staging/media/imx/imx-media-csi.c
index dc594b286f73..ef22a083f8eb 100644
--- a/drivers/staging/media/imx/imx-media-csi.c
+++ b/drivers/staging/media/imx/imx-media-csi.c
@@ -744,6 +744,28 @@ static int csi_setup(struct csi_priv *priv,
        return 0;
 }
 
+static void csi_set_src(struct csi_priv *priv,
+                       struct v4l2_mbus_config *mbus_cfg)
+{
+       bool is_csi2;
+
+       is_csi2 = !is_parallel_bus(mbus_cfg);
+       if (is_csi2) {
+               /*
+                * NOTE! It seems the virtual channels from the mipi csi-2
+                * receiver are used only for routing by the video mux's,
+                * or for hard-wired routing to the CSI's. Once the stream
+                * enters the CSI's however, they are treated internally
+                * in the IPU as virtual channel 0.
+                */
+               ipu_csi_set_mipi_datatype(priv->csi, 0,
+                                         &priv->format_mbus[CSI_SINK_PAD]);
+       }
+
+       /* select either parallel or MIPI-CSI2 as input to CSI */
+       ipu_set_csi_src_mux(priv->ipu, priv->csi_id, is_csi2);
+}
+
 static int csi_start(struct csi_priv *priv)
 {
        struct v4l2_mbus_config mbus_cfg = { .type = 0 };
@@ -760,6 +782,8 @@ static int csi_start(struct csi_priv *priv)
        input_fi = &priv->frame_interval[CSI_SINK_PAD];
        output_fi = &priv->frame_interval[priv->active_output_pad];
 
+       csi_set_src(priv, &mbus_cfg);
+
        /* start upstream */
        ret = v4l2_subdev_call(priv->src_sd, video, s_stream, 1);
        ret = (ret && ret != -ENOIOCTLCMD) ? ret : 0;
@@ -1130,7 +1154,6 @@ static int csi_link_validate(struct v4l2_subdev *sd,
 {
        struct csi_priv *priv = v4l2_get_subdevdata(sd);
        struct v4l2_mbus_config mbus_cfg = { .type = 0 };
-       bool is_csi2;
        int ret;
 
        ret = v4l2_subdev_link_validate_default(sd, link,
@@ -1145,25 +1168,6 @@ static int csi_link_validate(struct v4l2_subdev *sd,
                return ret;
        }
 
-       mutex_lock(&priv->lock);
-
-       is_csi2 = !is_parallel_bus(&mbus_cfg);
-       if (is_csi2) {
-               /*
-                * NOTE! It seems the virtual channels from the mipi csi-2
-                * receiver are used only for routing by the video mux's,
-                * or for hard-wired routing to the CSI's. Once the stream
-                * enters the CSI's however, they are treated internally
-                * in the IPU as virtual channel 0.
-                */
-               ipu_csi_set_mipi_datatype(priv->csi, 0,
-                                         &priv->format_mbus[CSI_SINK_PAD]);
-       }
-
-       /* select either parallel or MIPI-CSI2 as input to CSI */
-       ipu_set_csi_src_mux(priv->ipu, priv->csi_id, is_csi2);
-
-       mutex_unlock(&priv->lock);
        return ret;
 }
 
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to