mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-16 09:02:21 -04:00
media: staging: imx: request mbus_config in csi_start
Request the upstream mbus_config in csi_start, which starts the stream,
instead of caching it in link_validate.
This allows to get rid of the mbus_cfg field in the struct csi_priv and
avoids state in the driver.
Fixes: 4a34ec8e47 ("[media] media: imx: Add CSI subdev driver")
Cc: stable@vger.kernel.org
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
This commit is contained in:
committed by
Hans Verkuil
parent
072a8f60aa
commit
9df2aaa648
@@ -97,9 +97,6 @@ struct csi_priv {
|
||||
/* the mipi virtual channel number at link validate */
|
||||
int vc_num;
|
||||
|
||||
/* media bus config of the upstream subdevice CSI is receiving from */
|
||||
struct v4l2_mbus_config mbus_cfg;
|
||||
|
||||
spinlock_t irqlock; /* protect eof_irq handler */
|
||||
struct timer_list eof_timeout_timer;
|
||||
int eof_irq;
|
||||
@@ -403,7 +400,8 @@ static void csi_idmac_unsetup_vb2_buf(struct csi_priv *priv,
|
||||
}
|
||||
|
||||
/* init the SMFC IDMAC channel */
|
||||
static int csi_idmac_setup_channel(struct csi_priv *priv)
|
||||
static int csi_idmac_setup_channel(struct csi_priv *priv,
|
||||
struct v4l2_mbus_config *mbus_cfg)
|
||||
{
|
||||
struct imx_media_video_dev *vdev = priv->vdev;
|
||||
const struct imx_media_pixfmt *incc;
|
||||
@@ -432,7 +430,7 @@ static int csi_idmac_setup_channel(struct csi_priv *priv)
|
||||
image.phys0 = phys[0];
|
||||
image.phys1 = phys[1];
|
||||
|
||||
passthrough = requires_passthrough(&priv->mbus_cfg, infmt, incc);
|
||||
passthrough = requires_passthrough(mbus_cfg, infmt, incc);
|
||||
passthrough_cycles = 1;
|
||||
|
||||
/*
|
||||
@@ -572,11 +570,12 @@ static void csi_idmac_unsetup(struct csi_priv *priv,
|
||||
csi_idmac_unsetup_vb2_buf(priv, state);
|
||||
}
|
||||
|
||||
static int csi_idmac_setup(struct csi_priv *priv)
|
||||
static int csi_idmac_setup(struct csi_priv *priv,
|
||||
struct v4l2_mbus_config *mbus_cfg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = csi_idmac_setup_channel(priv);
|
||||
ret = csi_idmac_setup_channel(priv, mbus_cfg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -595,7 +594,8 @@ static int csi_idmac_setup(struct csi_priv *priv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int csi_idmac_start(struct csi_priv *priv)
|
||||
static int csi_idmac_start(struct csi_priv *priv,
|
||||
struct v4l2_mbus_config *mbus_cfg)
|
||||
{
|
||||
struct imx_media_video_dev *vdev = priv->vdev;
|
||||
int ret;
|
||||
@@ -619,7 +619,7 @@ static int csi_idmac_start(struct csi_priv *priv)
|
||||
priv->last_eof = false;
|
||||
priv->nfb4eof = false;
|
||||
|
||||
ret = csi_idmac_setup(priv);
|
||||
ret = csi_idmac_setup(priv, mbus_cfg);
|
||||
if (ret) {
|
||||
v4l2_err(&priv->sd, "csi_idmac_setup failed: %d\n", ret);
|
||||
goto out_free_dma_buf;
|
||||
@@ -701,7 +701,8 @@ static void csi_idmac_stop(struct csi_priv *priv)
|
||||
}
|
||||
|
||||
/* Update the CSI whole sensor and active windows */
|
||||
static int csi_setup(struct csi_priv *priv)
|
||||
static int csi_setup(struct csi_priv *priv,
|
||||
struct v4l2_mbus_config *mbus_cfg)
|
||||
{
|
||||
struct v4l2_mbus_framefmt *infmt, *outfmt;
|
||||
const struct imx_media_pixfmt *incc;
|
||||
@@ -719,7 +720,7 @@ static int csi_setup(struct csi_priv *priv)
|
||||
* if cycles is set, we need to handle this over multiple cycles as
|
||||
* generic/bayer data
|
||||
*/
|
||||
if (is_parallel_bus(&priv->mbus_cfg) && incc->cycles) {
|
||||
if (is_parallel_bus(mbus_cfg) && incc->cycles) {
|
||||
if_fmt.width *= incc->cycles;
|
||||
crop.width *= incc->cycles;
|
||||
}
|
||||
@@ -730,7 +731,7 @@ static int csi_setup(struct csi_priv *priv)
|
||||
priv->crop.width == 2 * priv->compose.width,
|
||||
priv->crop.height == 2 * priv->compose.height);
|
||||
|
||||
ipu_csi_init_interface(priv->csi, &priv->mbus_cfg, &if_fmt, outfmt);
|
||||
ipu_csi_init_interface(priv->csi, mbus_cfg, &if_fmt, outfmt);
|
||||
|
||||
ipu_csi_set_dest(priv->csi, priv->dest);
|
||||
|
||||
@@ -745,9 +746,17 @@ static int csi_setup(struct csi_priv *priv)
|
||||
|
||||
static int csi_start(struct csi_priv *priv)
|
||||
{
|
||||
struct v4l2_mbus_config mbus_cfg = { .type = 0 };
|
||||
struct v4l2_fract *input_fi, *output_fi;
|
||||
int ret;
|
||||
|
||||
ret = csi_get_upstream_mbus_config(priv, &mbus_cfg);
|
||||
if (ret) {
|
||||
v4l2_err(&priv->sd,
|
||||
"failed to get upstream media bus configuration\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
input_fi = &priv->frame_interval[CSI_SINK_PAD];
|
||||
output_fi = &priv->frame_interval[priv->active_output_pad];
|
||||
|
||||
@@ -758,7 +767,7 @@ static int csi_start(struct csi_priv *priv)
|
||||
return ret;
|
||||
|
||||
/* Skip first few frames from a BT.656 source */
|
||||
if (priv->mbus_cfg.type == V4L2_MBUS_BT656) {
|
||||
if (mbus_cfg.type == V4L2_MBUS_BT656) {
|
||||
u32 delay_usec, bad_frames = 20;
|
||||
|
||||
delay_usec = DIV_ROUND_UP_ULL((u64)USEC_PER_SEC *
|
||||
@@ -769,12 +778,12 @@ static int csi_start(struct csi_priv *priv)
|
||||
}
|
||||
|
||||
if (priv->dest == IPU_CSI_DEST_IDMAC) {
|
||||
ret = csi_idmac_start(priv);
|
||||
ret = csi_idmac_start(priv, &mbus_cfg);
|
||||
if (ret)
|
||||
goto stop_upstream;
|
||||
}
|
||||
|
||||
ret = csi_setup(priv);
|
||||
ret = csi_setup(priv, &mbus_cfg);
|
||||
if (ret)
|
||||
goto idmac_stop;
|
||||
|
||||
@@ -1138,7 +1147,6 @@ static int csi_link_validate(struct v4l2_subdev *sd,
|
||||
|
||||
mutex_lock(&priv->lock);
|
||||
|
||||
priv->mbus_cfg = mbus_cfg;
|
||||
is_csi2 = !is_parallel_bus(&mbus_cfg);
|
||||
if (is_csi2) {
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user