Commit c8da8c03 authored by Russell King's avatar Russell King Committed by Mauro Carvalho Chehab

[media] media: imx: csi: add support for bayer formats

Bayer formats must be treated as generic data and passthrough mode must
be used.  Add the correct setup for these formats.

- added check to csi_link_validate() to verify that destination is
  IDMAC output pad when passthrough conditions exist: bayer formats
  and 16-bit parallel buses.
Signed-off-by: default avatarRussell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: default avatarSteve Longerbeam <steve_longerbeam@mentor.com>
Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@s-opensource.com>
parent f5138526
...@@ -288,10 +288,11 @@ static int csi_idmac_setup_channel(struct csi_priv *priv) ...@@ -288,10 +288,11 @@ static int csi_idmac_setup_channel(struct csi_priv *priv)
struct imx_media_video_dev *vdev = priv->vdev; struct imx_media_video_dev *vdev = priv->vdev;
struct v4l2_fwnode_endpoint *sensor_ep; struct v4l2_fwnode_endpoint *sensor_ep;
struct v4l2_mbus_framefmt *infmt; struct v4l2_mbus_framefmt *infmt;
unsigned int burst_size;
struct ipu_image image; struct ipu_image image;
u32 passthrough_bits;
dma_addr_t phys[2]; dma_addr_t phys[2];
bool passthrough; bool passthrough;
u32 burst_size;
int ret; int ret;
infmt = &priv->format_mbus[CSI_SINK_PAD]; infmt = &priv->format_mbus[CSI_SINK_PAD];
...@@ -309,24 +310,52 @@ static int csi_idmac_setup_channel(struct csi_priv *priv) ...@@ -309,24 +310,52 @@ static int csi_idmac_setup_channel(struct csi_priv *priv)
image.phys0 = phys[0]; image.phys0 = phys[0];
image.phys1 = phys[1]; image.phys1 = phys[1];
ret = ipu_cpmem_set_image(priv->idmac_ch, &image);
if (ret)
goto unsetup_vb2;
burst_size = (image.pix.width & 0xf) ? 8 : 16;
ipu_cpmem_set_burstsize(priv->idmac_ch, burst_size);
/* /*
* If the sensor uses 16-bit parallel CSI bus, we must handle * Check for conditions that require the IPU to handle the
* the data internally in the IPU as 16-bit generic, aka * data internally as generic data, aka passthrough mode:
* passthrough mode. * - raw bayer formats
* - the sensor bus is 16-bit parallel
*/ */
switch (image.pix.pixelformat) {
case V4L2_PIX_FMT_SBGGR8:
case V4L2_PIX_FMT_SGBRG8:
case V4L2_PIX_FMT_SGRBG8:
case V4L2_PIX_FMT_SRGGB8:
burst_size = 8;
passthrough = true;
passthrough_bits = 8;
break;
case V4L2_PIX_FMT_SBGGR16:
case V4L2_PIX_FMT_SGBRG16:
case V4L2_PIX_FMT_SGRBG16:
case V4L2_PIX_FMT_SRGGB16:
burst_size = 4;
passthrough = true;
passthrough_bits = 16;
break;
default:
burst_size = (image.pix.width & 0xf) ? 8 : 16;
passthrough = (sensor_ep->bus_type != V4L2_MBUS_CSI2 && passthrough = (sensor_ep->bus_type != V4L2_MBUS_CSI2 &&
sensor_ep->bus.parallel.bus_width >= 16); sensor_ep->bus.parallel.bus_width >= 16);
passthrough_bits = 16;
break;
}
if (passthrough) if (passthrough) {
ipu_cpmem_set_format_passthrough(priv->idmac_ch, 16); ipu_cpmem_set_resolution(priv->idmac_ch, image.rect.width,
image.rect.height);
ipu_cpmem_set_stride(priv->idmac_ch, image.pix.bytesperline);
ipu_cpmem_set_buffer(priv->idmac_ch, 0, image.phys0);
ipu_cpmem_set_buffer(priv->idmac_ch, 1, image.phys1);
ipu_cpmem_set_format_passthrough(priv->idmac_ch,
passthrough_bits);
} else {
ret = ipu_cpmem_set_image(priv->idmac_ch, &image);
if (ret)
goto unsetup_vb2;
}
ipu_cpmem_set_burstsize(priv->idmac_ch, burst_size);
/* /*
* Set the channel for the direct CSI-->memory via SMFC * Set the channel for the direct CSI-->memory via SMFC
...@@ -800,6 +829,7 @@ static int csi_link_validate(struct v4l2_subdev *sd, ...@@ -800,6 +829,7 @@ static int csi_link_validate(struct v4l2_subdev *sd,
{ {
struct csi_priv *priv = v4l2_get_subdevdata(sd); struct csi_priv *priv = v4l2_get_subdevdata(sd);
struct v4l2_fwnode_endpoint *sensor_ep; struct v4l2_fwnode_endpoint *sensor_ep;
const struct imx_media_pixfmt *incc;
struct imx_media_subdev *sensor; struct imx_media_subdev *sensor;
bool is_csi2; bool is_csi2;
int ret; int ret;
...@@ -820,6 +850,16 @@ static int csi_link_validate(struct v4l2_subdev *sd, ...@@ -820,6 +850,16 @@ static int csi_link_validate(struct v4l2_subdev *sd,
priv->sensor = sensor; priv->sensor = sensor;
sensor_ep = &priv->sensor->sensor_ep; sensor_ep = &priv->sensor->sensor_ep;
is_csi2 = (sensor_ep->bus_type == V4L2_MBUS_CSI2); is_csi2 = (sensor_ep->bus_type == V4L2_MBUS_CSI2);
incc = priv->cc[CSI_SINK_PAD];
if (priv->dest != IPU_CSI_DEST_IDMAC &&
(incc->bayer || (!is_csi2 &&
sensor_ep->bus.parallel.bus_width >= 16))) {
v4l2_err(&priv->sd,
"bayer/16-bit parallel buses must go to IDMAC pad\n");
ret = -EINVAL;
goto out;
}
if (is_csi2) { if (is_csi2) {
int vc_num = 0; int vc_num = 0;
...@@ -844,7 +884,7 @@ static int csi_link_validate(struct v4l2_subdev *sd, ...@@ -844,7 +884,7 @@ static int csi_link_validate(struct v4l2_subdev *sd,
/* select either parallel or MIPI-CSI2 as input to CSI */ /* select either parallel or MIPI-CSI2 as input to CSI */
ipu_set_csi_src_mux(priv->ipu, priv->csi_id, is_csi2); ipu_set_csi_src_mux(priv->ipu, priv->csi_id, is_csi2);
out:
mutex_unlock(&priv->lock); mutex_unlock(&priv->lock);
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment