summaryrefslogtreecommitdiff
path: root/drivers/media/platform/soc_camera/tegra_camera/vi2.c
diff options
context:
space:
mode:
authorBryan Wu <pengw@nvidia.com>2013-11-19 16:59:23 -0800
committerWinnie Hsu <whsu@nvidia.com>2014-09-26 10:49:14 -0700
commit447dd3f018c3a63350f10e67ba5edf02c77efeba (patch)
tree5ddcaf75ef21273fd0f00223f146665acdb232a3 /drivers/media/platform/soc_camera/tegra_camera/vi2.c
parenta4201ceac4a89a495d759885b1e2d5a1c1466073 (diff)
media: tegra_camera: vi2: support for real sensor
Add code to support RAW10 capture from real sensor like IMX135. Add flag to skip register program from second frame. Fix sync point operations. Bug 1380143 Change-Id: I19bcd17ddfba0e16b4b3a34ae8a4e5a0119e85e1 Signed-off-by: Bryan Wu <pengw@nvidia.com> Reviewed-on: http://git-master/r/337470 (cherry picked from commit ff1055fa436ffb5c1d57eee2e09c17578774d65f) Reviewed-on: http://git-master/r/498936 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Matthew Pedro <mapedro@nvidia.com> Reviewed-by: Winnie Hsu <whsu@nvidia.com>
Diffstat (limited to 'drivers/media/platform/soc_camera/tegra_camera/vi2.c')
-rw-r--r--drivers/media/platform/soc_camera/tegra_camera/vi2.c148
1 files changed, 84 insertions, 64 deletions
diff --git a/drivers/media/platform/soc_camera/tegra_camera/vi2.c b/drivers/media/platform/soc_camera/tegra_camera/vi2.c
index b97e0b341fe0..95f88bfd4129 100644
--- a/drivers/media/platform/soc_camera/tegra_camera/vi2.c
+++ b/drivers/media/platform/soc_camera/tegra_camera/vi2.c
@@ -236,7 +236,7 @@ static int vi2_port_is_valid(int port)
static struct tegra_camera_clk vi2_clks0[] = {
{
.name = "vi",
- .freq = 150000000,
+ .freq = 408000000,
.use_devname = 1,
},
{
@@ -245,7 +245,7 @@ static struct tegra_camera_clk vi2_clks0[] = {
},
{
.name = "csi",
- .freq = 0,
+ .freq = 408000000,
.use_devname = 1,
},
{
@@ -263,7 +263,7 @@ static struct tegra_camera_clk vi2_clks0[] = {
},
{
.name = "emc",
- .freq = 375000000,
+ .freq = 300000000,
},
{
.name = "cilab",
@@ -280,7 +280,7 @@ static struct tegra_camera_clk vi2_clks0[] = {
static struct tegra_camera_clk vi2_clks1[] = {
{
.name = "vi",
- .freq = 150000000,
+ .freq = 408000000,
.use_devname = 1,
},
{
@@ -289,7 +289,7 @@ static struct tegra_camera_clk vi2_clks1[] = {
},
{
.name = "csi",
- .freq = 0,
+ .freq = 408000000,
.use_devname = 1,
},
{
@@ -302,7 +302,7 @@ static struct tegra_camera_clk vi2_clks1[] = {
},
{
.name = "emc",
- .freq = 375000000,
+ .freq = 300000000,
},
{
.name = "cilcd",
@@ -442,37 +442,37 @@ static void vi2_free_syncpts(struct tegra_camera_dev *cam)
nvhost_free_syncpt(cam->syncpt_id_csi_b);
}
-static void vi2_save_syncpts(struct tegra_camera_dev *cam)
+static void vi2_incr_syncpts(struct tegra_camera_dev *cam)
{
u32 val;
if (!nvhost_syncpt_read_ext_check(cam->ndev,
cam->syncpt_id_csi_a, &val))
- cam->syncpt_csi_a = val;
+ cam->syncpt_csi_a = nvhost_syncpt_incr_max_ext(cam->ndev,
+ cam->syncpt_id_csi_a, 1);
if (!nvhost_syncpt_read_ext_check(cam->ndev,
cam->syncpt_id_csi_b, &val))
- cam->syncpt_csi_b = val;
-}
-
-static void vi2_incr_syncpts(struct tegra_camera_dev *cam)
-{
- nvhost_syncpt_cpu_incr_ext(cam->ndev, cam->syncpt_id_csi_a);
-
- nvhost_syncpt_cpu_incr_ext(cam->ndev, cam->syncpt_id_csi_b);
+ cam->syncpt_csi_b = nvhost_syncpt_incr_max_ext(cam->ndev,
+ cam->syncpt_id_csi_b, 1);
}
static void vi2_capture_clean(struct tegra_camera_dev *cam)
{
/* Clean up status */
TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_A_STATUS, 0xFFFFFFFF);
- TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CILA_STATUS, 0xFFFFFFFF);
TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_B_STATUS, 0xFFFFFFFF);
TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_C_STATUS, 0xFFFFFFFF);
TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_D_STATUS, 0xFFFFFFFF);
TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_E_STATUS, 0xFFFFFFFF);
+ TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CILA_STATUS, 0xFFFFFFFF);
+ TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CILB_STATUS, 0xFFFFFFFF);
+ TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CILC_STATUS, 0xFFFFFFFF);
+ TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CILD_STATUS, 0xFFFFFFFF);
TC_VI_REG_WT(cam, TEGRA_CSI_CSI_PIXEL_PARSER_A_STATUS, 0xFFFFFFFF);
+ TC_VI_REG_WT(cam, TEGRA_CSI_CSI_PIXEL_PARSER_B_STATUS, 0xFFFFFFFF);
TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_ERROR_STATUS, 0xFFFFFFFF);
+ TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_ERROR_STATUS, 0xFFFFFFFF);
}
static int vi2_capture_setup_csi_0(struct tegra_camera_dev *cam,
@@ -495,10 +495,6 @@ static int vi2_capture_setup_csi_0(struct tegra_camera_dev *cam,
else
TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x22020201);
- /* VI_MWA_REQ_DONE */
- TC_VI_REG_WT(cam, TEGRA_VI_CFG_VI_INCR_SYNCPT,
- (0x4 << 8) | cam->syncpt_id_csi_a);
-
if (cam->tpg_mode) {
TC_VI_REG_WT(cam, TEGRA_CSI_PATTERN_GENERATOR_CTRL_A,
((cam->tpg_mode - 1) << 2) | 0x1);
@@ -515,13 +511,21 @@ static int vi2_capture_setup_csi_0(struct tegra_camera_dev *cam,
TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_IMAGE_DEF, (64 << 16) | 0x1);
/* input format is RGB888 */
TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_CSI_IMAGE_DT, 36);
+
+ TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_CSI_IMAGE_SIZE_WC,
+ icd->user_width * 3);
+ } else {
+ /* output format RAW10 T_R16_I, only support direct to mem */
+ TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_IMAGE_DEF, (32 << 16) | 0x1);
+ /* input format is RAW10 */
+ TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_CSI_IMAGE_DT, 43);
+
+ TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_CSI_IMAGE_SIZE_WC,
+ icd->user_width * 10 / 8);
}
TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_CSI_IMAGE_SIZE,
- (icd->user_height << 16) | icd->user_width);
-
- TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_CSI_IMAGE_SIZE_WC,
- icd->user_width * 3);
+ (icd->user_height << 16) | icd->user_width);
return 0;
}
@@ -548,10 +552,6 @@ static int vi2_capture_setup_csi_1(struct tegra_camera_dev *cam,
else
TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x22010202);
- /* VI_MWB_REQ_DONE */
- TC_VI_REG_WT(cam, TEGRA_VI_CFG_VI_INCR_SYNCPT,
- (0x5 << 8) | cam->syncpt_id_csi_b);
-
if (cam->tpg_mode) {
TC_VI_REG_WT(cam, TEGRA_CSI_PATTERN_GENERATOR_CTRL_B,
((cam->tpg_mode - 1) << 2) | 0x1);
@@ -588,11 +588,14 @@ static int vi2_capture_setup(struct tegra_camera_dev *cam)
struct tegra_camera_platform_data *pdata = ssdesc->drv_priv;
int port = pdata->port;
- /*
- * MIPI pad controls
- * MIPI_CAL_MIPI_BIAS_PAD_CFG0_0 MIPI_BIAS_PAD_E_VCLAMP_REF 1
- * MIPI_CAL_MIPI_BIAS_PAD_CFG2_0 PAD_PDVREG 0
- */
+ /* Skip VI2/CSI2 setup for second and later frame capture */
+ 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,
@@ -663,6 +666,7 @@ static int vi2_capture_buffer_setup(struct tegra_camera_dev *cam,
case V4L2_PIX_FMT_SBGGR8:
case V4L2_PIX_FMT_SGBRG8:
case V4L2_PIX_FMT_SBGGR10:
+ case V4L2_PIX_FMT_SRGGB10:
case V4L2_PIX_FMT_RGB32:
switch (buf->output_channel) {
case 0:
@@ -701,6 +705,43 @@ static int vi2_capture_buffer_setup(struct tegra_camera_dev *cam,
return 0;
}
+static int vi2_capture_error_status(struct tegra_camera_dev *cam)
+{
+ int err;
+
+#ifdef DEBUG
+ err = TC_VI_REG_RD(cam, TEGRA_CSI_DEBUG_COUNTER_0);
+ if (err)
+ pr_err("TEGRA_CSI_DEBUG_COUNTER_0 0x%08x\n", err);
+#endif
+ err = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CIL_A_STATUS);
+ if (err)
+ pr_err("TEGRA_CSI_CSI_CIL_A_STATUS 0x%08x\n", err);
+ err = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CILA_STATUS);
+ if (err)
+ pr_err("TEGRA_CSI_CSI_CILA_STATUS 0x%08x\n", err);
+ err = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CIL_B_STATUS);
+ if (err)
+ pr_err("TEGRA_CSI_CSI_CIL_B_STATUS 0x%08x\n", err);
+ err = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CIL_C_STATUS);
+ if (err)
+ pr_err("TEGRA_CSI_CSI_CIL_C_STATUS 0x%08x\n", err);
+ err = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CIL_D_STATUS);
+ if (err)
+ pr_err("TEGRA_CSI_CSI_CIL_D_STATUS 0x%08x\n", err);
+ err = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CIL_E_STATUS);
+ if (err)
+ pr_err("TEGRA_CSI_CSI_CIL_E_STATUS 0x%08x\n", err);
+ err = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_PIXEL_PARSER_A_STATUS);
+ if (err)
+ pr_err("TEGRA_CSI_CSI_PIXEL_PARSER_A_STATUS 0x%08x\n", err);
+ err = TC_VI_REG_RD(cam, TEGRA_VI_CSI_0_ERROR_STATUS);
+ if (err)
+ pr_err("TEGRA_VI_CSI_0_ERROR_STATUS 0x%08x\n", err);
+
+ return err;
+}
+
static int vi2_capture_start(struct tegra_camera_dev *cam,
struct tegra_camera_buffer *buf)
{
@@ -716,7 +757,8 @@ static int vi2_capture_start(struct tegra_camera_dev *cam,
/* Only wait on CSI frame end syncpt if we're using CSI. */
if (port == TEGRA_CAMERA_PORT_CSI_A) {
- cam->syncpt_csi_a++;
+ TC_VI_REG_WT(cam, TEGRA_VI_CFG_VI_INCR_SYNCPT,
+ (6 << 8) | cam->syncpt_id_csi_a);
TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPA_COMMAND,
0x0000f005);
TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_SINGLE_SHOT, 0x1);
@@ -727,7 +769,8 @@ static int vi2_capture_start(struct tegra_camera_dev *cam,
NULL,
NULL);
} else if (port == TEGRA_CAMERA_PORT_CSI_B) {
- cam->syncpt_csi_b++;
+ 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,
0x0000f005);
TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_SINGLE_SHOT, 0x1);
@@ -739,35 +782,13 @@ static int vi2_capture_start(struct tegra_camera_dev *cam,
NULL);
}
- if (!err)
- return 0;
+ /* Mark SOF flag to Zero after we captured the FIRST frame */
+ if (cam->sof)
+ cam->sof = 0;
- err = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CIL_A_STATUS);
+ /* Capture syncpt timeout err, then dump error status */
if (err)
- pr_err("TEGRA_CSI_CSI_CIL_A_STATUS 0x%08x\n", err);
- err = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CILA_STATUS);
- if (err)
- pr_err("TEGRA_CSI_CSI_CILA_STATUS 0x%08x\n", err);
- err = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CIL_B_STATUS);
- if (err)
- pr_err("TEGRA_CSI_CSI_CIL_B_STATUS 0x%08x\n", err);
- err = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CIL_C_STATUS);
- if (err)
- pr_err("TEGRA_CSI_CSI_CIL_C_STATUS 0x%08x\n", err);
- err = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CIL_D_STATUS);
- if (err)
- pr_err("TEGRA_CSI_CSI_CIL_D_STATUS 0x%08x\n", err);
- err = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CIL_E_STATUS);
- if (err)
- pr_err("TEGRA_CSI_CSI_CIL_E_STATUS 0x%08x\n", err);
-
- err = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_PIXEL_PARSER_A_STATUS);
- if (err)
- pr_err("TEGRA_CSI_CSI_PIXEL_PARSER_A_STATUS 0x%08x\n", err);
-
- err = TC_VI_REG_RD(cam, TEGRA_VI_CSI_0_ERROR_STATUS);
- if (err)
- pr_err("TEGRA_VI_CSI_0_ERROR_STATUS 0x%08x\n", err);
+ err = vi2_capture_error_status(cam);
return err;
}
@@ -810,7 +831,6 @@ struct tegra_camera_ops vi2_ops = {
.init_syncpts = vi2_init_syncpts,
.free_syncpts = vi2_free_syncpts,
- .save_syncpts = vi2_save_syncpts,
.incr_syncpts = vi2_incr_syncpts,
.port_is_valid = vi2_port_is_valid,