summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBryan Wu <pengw@nvidia.com>2014-09-18 17:45:35 -0700
committerWinnie Hsu <whsu@nvidia.com>2015-01-07 18:06:02 -0800
commit5cc760088433a2b55c0f9d02b5279732eda335b5 (patch)
tree56be31de5246b2bafc8ea73d0a47b3a5f4ac99a1
parent373c23c7936c05f615d3db569198c10be3d9d4b2 (diff)
media: tegra_v4l2_camera: add CSI_B/CSI_C support
Bug 1560636 Change-Id: I2d27c631da0f4b6540af9b4da9ba9e212a4a56c5 Signed-off-by: Bryan Wu <pengw@nvidia.com> Reviewed-on: http://git-master/r/539003 Reviewed-by: Venkat Moganty <vmoganty@nvidia.com> (cherry picked from commit e9b82e8a6e6edf5fc00e88c8610b9c2bb67f3872) Reviewed-on: http://git-master/r/665996 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Winnie Hsu <whsu@nvidia.com>
-rw-r--r--drivers/media/platform/soc_camera/tegra_camera/vi2.c160
1 files changed, 112 insertions, 48 deletions
diff --git a/drivers/media/platform/soc_camera/tegra_camera/vi2.c b/drivers/media/platform/soc_camera/tegra_camera/vi2.c
index 09a3a6173a9f..8937eb813ea7 100644
--- a/drivers/media/platform/soc_camera/tegra_camera/vi2.c
+++ b/drivers/media/platform/soc_camera/tegra_camera/vi2.c
@@ -289,7 +289,7 @@
static int vi2_port_is_valid(int port)
{
return (((port) >= TEGRA_CAMERA_PORT_CSI_A) &&
- ((port) <= TEGRA_CAMERA_PORT_CSI_E));
+ ((port) <= TEGRA_CAMERA_PORT_CSI_C));
}
/* Clock settings for camera */
@@ -544,6 +544,13 @@ static int vi2_capture_setup_csi_0(struct tegra_camera_dev *cam,
struct tegra_camera_platform_data *pdata = ssdesc->drv_priv;
int format = 0, data_type = 0, image_size = 0;
+#ifdef DEBUG
+ TC_VI_REG_WT(cam, TEGRA_CSI_DEBUG_CONTROL,
+ 0x3 | (0x1 << 5) | (0x40 << 8));
+#endif
+
+ TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CILA_CONTROL0, 0x9);
+ TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CILB_CONTROL0, 0x9);
TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPA_COMMAND, 0xf007);
TC_VI_REG_WT(cam, TEGRA_CSI_CSI_PIXEL_PARSER_A_INTERRUPT_MASK, 0x0);
TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_A_CONTROL0, 0x280301f0);
@@ -610,6 +617,17 @@ static int vi2_capture_setup_csi_1(struct tegra_camera_dev *cam,
struct tegra_camera_platform_data *pdata = ssdesc->drv_priv;
int format = 0, data_type = 0, image_size = 0;
+#ifdef DEBUG
+ TC_VI_REG_WT(cam, TEGRA_CSI_DEBUG_CONTROL,
+ 0x5 | (0x1 << 5) | (0x50 << 8));
+#endif
+
+ if (pdata->port == TEGRA_CAMERA_PORT_CSI_B) {
+ TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CILC_CONTROL0, 0x9);
+ TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CILD_CONTROL0, 0x9);
+ } else if (pdata->port == TEGRA_CAMERA_PORT_CSI_C)
+ TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CILE_CONTROL0, 0x9);
+
TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPB_COMMAND, 0xf007);
TC_VI_REG_WT(cam, TEGRA_CSI_CSI_PIXEL_PARSER_B_INTERRUPT_MASK, 0x0);
TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_B_CONTROL0, 0x280301f1);
@@ -621,7 +639,7 @@ static int vi2_capture_setup_csi_1(struct tegra_camera_dev *cam,
0x3f0000 | (pdata->lanes - 1));
if (pdata->lanes == 4)
TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x21010202);
- else if (pdata->lanes == 1 && pdata->port == TEGRA_CAMERA_PORT_CSI_E)
+ else if (pdata->lanes == 1 && pdata->port == TEGRA_CAMERA_PORT_CSI_C)
TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x12020202);
else
TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x22010202);
@@ -665,6 +683,9 @@ static int vi2_capture_setup_csi_1(struct tegra_camera_dev *cam,
TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_CSI_IMAGE_SIZE_WC, image_size);
+ TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_CSI_IMAGE_SIZE,
+ (icd->user_height << 16) | icd->user_width);
+
return 0;
}
@@ -681,11 +702,6 @@ static int vi2_capture_setup(struct tegra_camera_dev *cam)
if (!cam->sof)
return 0;
-#ifdef DEBUG
- TC_VI_REG_WT(cam, TEGRA_CSI_DEBUG_CONTROL,
- 0x3 | (0x1 << 5) | (0x40 << 8));
-#endif
-
/*
* PAD_CILA_PDVCLAMP 0, PAD_CILA_PDIO_CLK 0,
* PAD_CILA_PDIO 0, PAD_AB_BK_MODE 1
@@ -716,21 +732,11 @@ static int vi2_capture_setup(struct tegra_camera_dev *cam)
TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_D_INTERRUPT_MASK, 0x0);
TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_E_INTERRUPT_MASK, 0x0);
- /*
- * TODO: these values should be different with different
- * sensor connected.
- * Hardcode THS settle value just for TPG testing
- */
- TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CILA_CONTROL0, 0x8);
- TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CILB_CONTROL0, 0x8);
- TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CILC_CONTROL0, 0xa);
- TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CILD_CONTROL0, 0xa);
- TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CILE_CONTROL0, 0xa);
-
/* Setup registers for CSI-A and CSI-B inputs */
if (port == TEGRA_CAMERA_PORT_CSI_A)
return vi2_capture_setup_csi_0(cam, icd);
- else if (port == TEGRA_CAMERA_PORT_CSI_B)
+ else if (port == TEGRA_CAMERA_PORT_CSI_B ||
+ port == TEGRA_CAMERA_PORT_CSI_C)
return vi2_capture_setup_csi_1(cam, icd);
else
return -ENODEV;
@@ -742,6 +748,9 @@ static int vi2_capture_buffer_setup(struct tegra_camera_dev *cam,
struct soc_camera_device *icd = buf->icd;
int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
icd->current_fmt->host_fmt);
+ struct soc_camera_subdev_desc *ssdesc = &icd->sdesc->subdev_desc;
+ struct tegra_camera_platform_data *pdata = ssdesc->drv_priv;
+ int port = pdata->port;
switch (icd->current_fmt->host_fmt->fourcc) {
case V4L2_PIX_FMT_YUV420:
@@ -757,31 +766,79 @@ static int vi2_capture_buffer_setup(struct tegra_camera_dev *cam,
case V4L2_PIX_FMT_SBGGR10:
case V4L2_PIX_FMT_SRGGB10:
case V4L2_PIX_FMT_RGB32:
- switch (buf->output_channel) {
- case 0:
- TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_SURFACE0_OFFSET_MSB,
- 0x0);
- TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_SURFACE0_OFFSET_LSB,
- buf->buffer_addr);
- TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_SURFACE0_STRIDE,
- bytes_per_line);
- break;
- case 1:
- TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_SURFACE1_OFFSET_MSB,
- 0x0);
- TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_SURFACE1_OFFSET_LSB,
- buf->buffer_addr);
- TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_SURFACE1_STRIDE,
- bytes_per_line);
- break;
- case 2:
- TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_SURFACE2_OFFSET_MSB,
- 0x0);
- TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_SURFACE2_OFFSET_LSB,
- buf->buffer_addr);
- TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_SURFACE2_STRIDE,
- bytes_per_line);
- break;
+ if (port == TEGRA_CAMERA_PORT_CSI_A) {
+ switch (buf->output_channel) {
+ case 0:
+ TC_VI_REG_WT(cam,
+ TEGRA_VI_CSI_0_SURFACE0_OFFSET_MSB,
+ 0x0);
+ TC_VI_REG_WT(cam,
+ TEGRA_VI_CSI_0_SURFACE0_OFFSET_LSB,
+ buf->buffer_addr);
+ TC_VI_REG_WT(cam,
+ TEGRA_VI_CSI_0_SURFACE0_STRIDE,
+ bytes_per_line);
+ break;
+ case 1:
+ TC_VI_REG_WT(cam,
+ TEGRA_VI_CSI_0_SURFACE1_OFFSET_MSB,
+ 0x0);
+ TC_VI_REG_WT(cam,
+ TEGRA_VI_CSI_0_SURFACE1_OFFSET_LSB,
+ buf->buffer_addr);
+ TC_VI_REG_WT(cam,
+ TEGRA_VI_CSI_0_SURFACE1_STRIDE,
+ bytes_per_line);
+ break;
+ case 2:
+ TC_VI_REG_WT(cam,
+ TEGRA_VI_CSI_0_SURFACE2_OFFSET_MSB,
+ 0x0);
+ TC_VI_REG_WT(cam,
+ TEGRA_VI_CSI_0_SURFACE2_OFFSET_LSB,
+ buf->buffer_addr);
+ TC_VI_REG_WT(cam,
+ TEGRA_VI_CSI_0_SURFACE2_STRIDE,
+ bytes_per_line);
+ break;
+ }
+ } else if (port == TEGRA_CAMERA_PORT_CSI_B ||
+ port == TEGRA_CAMERA_PORT_CSI_C) {
+ switch (buf->output_channel) {
+ case 0:
+ TC_VI_REG_WT(cam,
+ TEGRA_VI_CSI_1_SURFACE0_OFFSET_MSB,
+ 0x0);
+ TC_VI_REG_WT(cam,
+ TEGRA_VI_CSI_1_SURFACE0_OFFSET_LSB,
+ buf->buffer_addr);
+ TC_VI_REG_WT(cam,
+ TEGRA_VI_CSI_1_SURFACE0_STRIDE,
+ bytes_per_line);
+ break;
+ case 1:
+ TC_VI_REG_WT(cam,
+ TEGRA_VI_CSI_1_SURFACE1_OFFSET_MSB,
+ 0x0);
+ TC_VI_REG_WT(cam,
+ TEGRA_VI_CSI_1_SURFACE1_OFFSET_LSB,
+ buf->buffer_addr);
+ TC_VI_REG_WT(cam,
+ TEGRA_VI_CSI_1_SURFACE1_STRIDE,
+ bytes_per_line);
+ break;
+ case 2:
+ TC_VI_REG_WT(cam,
+ TEGRA_VI_CSI_1_SURFACE2_OFFSET_MSB,
+ 0x0);
+ TC_VI_REG_WT(cam,
+ TEGRA_VI_CSI_1_SURFACE2_OFFSET_LSB,
+ buf->buffer_addr);
+ TC_VI_REG_WT(cam,
+ TEGRA_VI_CSI_1_SURFACE2_STRIDE,
+ bytes_per_line);
+ break;
+ }
}
break;
@@ -816,8 +873,12 @@ static void vi2_capture_error_status(struct tegra_camera_dev *cam)
pr_err("TEGRA_CSI_CSI_CIL_E_STATUS 0x%08x\n", val);
val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_PIXEL_PARSER_A_STATUS);
pr_err("TEGRA_CSI_CSI_PIXEL_PARSER_A_STATUS 0x%08x\n", val);
+ val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_PIXEL_PARSER_B_STATUS);
+ pr_err("TEGRA_CSI_CSI_PIXEL_PARSER_B_STATUS 0x%08x\n", val);
val = TC_VI_REG_RD(cam, TEGRA_VI_CSI_0_ERROR_STATUS);
pr_err("TEGRA_VI_CSI_0_ERROR_STATUS 0x%08x\n", val);
+ val = TC_VI_REG_RD(cam, TEGRA_VI_CSI_1_ERROR_STATUS);
+ pr_err("TEGRA_VI_CSI_1_ERROR_STATUS 0x%08x\n", val);
}
static int vi2_capture_start(struct tegra_camera_dev *cam,
@@ -846,7 +907,8 @@ static int vi2_capture_start(struct tegra_camera_dev *cam,
TEGRA_SYNCPT_CSI_WAIT_TIMEOUT,
NULL,
NULL);
- } else if (port == TEGRA_CAMERA_PORT_CSI_B) {
+ } else if (port == TEGRA_CAMERA_PORT_CSI_B ||
+ port == TEGRA_CAMERA_PORT_CSI_C) {
TC_VI_REG_WT(cam, TEGRA_VI_CFG_VI_INCR_SYNCPT,
(7 << 8) | cam->syncpt_id_csi_b);
TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPB_COMMAND,
@@ -870,9 +932,10 @@ static int vi2_capture_start(struct tegra_camera_dev *cam,
dev_err(&cam->ndev->dev,
"CSI_A syncpt timeout, syncpt = %d, err = %d\n",
cam->syncpt_csi_a, err);
- else if (port == TEGRA_CAMERA_PORT_CSI_B)
+ else if (port == TEGRA_CAMERA_PORT_CSI_B ||
+ port == TEGRA_CAMERA_PORT_CSI_C)
dev_err(&cam->ndev->dev,
- "CSI_B syncpt timeout, syncpt = %d, err = %d\n",
+ "CSI_B/CSI_C syncpt timeout, syncpt = %d, err = %d\n",
cam->syncpt_csi_b, err);
vi2_capture_error_status(cam);
}
@@ -885,7 +948,8 @@ static int vi2_capture_stop(struct tegra_camera_dev *cam, int port)
if (port == TEGRA_CAMERA_PORT_CSI_A)
TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPA_COMMAND,
0x0000f002);
- else if (port == TEGRA_CAMERA_PORT_CSI_B)
+ else if (port == TEGRA_CAMERA_PORT_CSI_B ||
+ port == TEGRA_CAMERA_PORT_CSI_C)
TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPB_COMMAND,
0x0000f002);