summaryrefslogtreecommitdiff
path: root/drivers/media/platform/soc_camera/tegra_camera/vi2.c
diff options
context:
space:
mode:
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,