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.c206
1 files changed, 140 insertions, 66 deletions
diff --git a/drivers/media/platform/soc_camera/tegra_camera/vi2.c b/drivers/media/platform/soc_camera/tegra_camera/vi2.c
index 7c2aa3688609..00b400799cdf 100644
--- a/drivers/media/platform/soc_camera/tegra_camera/vi2.c
+++ b/drivers/media/platform/soc_camera/tegra_camera/vi2.c
@@ -226,6 +226,66 @@
#define TEGRA_CSI_DEBUG_COUNTER_1 0xb00
#define TEGRA_CSI_DEBUG_COUNTER_2 0xb04
+/* These go into the TEGRA_VI_CSI_n_IMAGE_DEF registers bits 23:16 */
+#define TEGRA_IMAGE_FORMAT_T_L8 16
+#define TEGRA_IMAGE_FORMAT_T_R16_I 32
+#define TEGRA_IMAGE_FORMAT_T_B5G6R5 33
+#define TEGRA_IMAGE_FORMAT_T_R5G6B5 34
+#define TEGRA_IMAGE_FORMAT_T_A1B5G5R5 35
+#define TEGRA_IMAGE_FORMAT_T_A1R5G5B5 36
+#define TEGRA_IMAGE_FORMAT_T_B5G5R5A1 37
+#define TEGRA_IMAGE_FORMAT_T_R5G5B5A1 38
+#define TEGRA_IMAGE_FORMAT_T_A4B4G4R4 39
+#define TEGRA_IMAGE_FORMAT_T_A4R4G4B4 40
+#define TEGRA_IMAGE_FORMAT_T_B4G4R4A4 41
+#define TEGRA_IMAGE_FORMAT_T_R4G4B4A4 42
+#define TEGRA_IMAGE_FORMAT_T_A8B8G8R8 64
+#define TEGRA_IMAGE_FORMAT_T_A8R8G8B8 65
+#define TEGRA_IMAGE_FORMAT_T_B8G8R8A8 66
+#define TEGRA_IMAGE_FORMAT_T_R8G8B8A8 67
+#define TEGRA_IMAGE_FORMAT_T_A2B10G10R10 68
+#define TEGRA_IMAGE_FORMAT_T_A2R10G10B10 69
+#define TEGRA_IMAGE_FORMAT_T_B10G10R10A2 70
+#define TEGRA_IMAGE_FORMAT_T_R10G10B10A2 71
+#define TEGRA_IMAGE_FORMAT_T_A8Y8U8V8 193
+#define TEGRA_IMAGE_FORMAT_T_V8U8Y8A8 194
+#define TEGRA_IMAGE_FORMAT_T_A2Y10U10V10 197
+#define TEGRA_IMAGE_FORMAT_T_V10U10Y10A2 198
+#define TEGRA_IMAGE_FORMAT_T_Y8_U8__Y8_V8 200
+#define TEGRA_IMAGE_FORMAT_T_Y8_V8__Y8_U8 201
+#define TEGRA_IMAGE_FORMAT_T_U8_Y8__V8_Y8 202
+#define TEGRA_IMAGE_FORMAT_T_T_V8_Y8__U8_Y8 203
+#define TEGRA_IMAGE_FORMAT_T_T_Y8__U8__V8_N444 224
+#define TEGRA_IMAGE_FORMAT_T_Y8__U8V8_N444 225
+#define TEGRA_IMAGE_FORMAT_T_Y8__V8U8_N444 226
+#define TEGRA_IMAGE_FORMAT_T_Y8__U8__V8_N422 227
+#define TEGRA_IMAGE_FORMAT_T_Y8__U8V8_N422 228
+#define TEGRA_IMAGE_FORMAT_T_Y8__V8U8_N422 229
+#define TEGRA_IMAGE_FORMAT_T_Y8__U8__V8_N420 230
+#define TEGRA_IMAGE_FORMAT_T_Y8__U8V8_N420 231
+#define TEGRA_IMAGE_FORMAT_T_Y8__V8U8_N420 232
+#define TEGRA_IMAGE_FORMAT_T_X2Lc10Lb10La10 233
+#define TEGRA_IMAGE_FORMAT_T_A2R6R6R6R6R6 234
+
+/* These go into the TEGRA_VI_CSI_n_CSI_IMAGE_DT registers bits 7:0 */
+#define TEGRA_IMAGE_DT_YUV420_8 24
+#define TEGRA_IMAGE_DT_YUV420_10 25
+#define TEGRA_IMAGE_DT_YUV420CSPS_8 28
+#define TEGRA_IMAGE_DT_YUV420CSPS_10 29
+#define TEGRA_IMAGE_DT_YUV422_8 30
+#define TEGRA_IMAGE_DT_YUV422_10 31
+#define TEGRA_IMAGE_DT_RGB444 32
+#define TEGRA_IMAGE_DT_RGB555 33
+#define TEGRA_IMAGE_DT_RGB565 34
+#define TEGRA_IMAGE_DT_RGB666 35
+#define TEGRA_IMAGE_DT_RGB888 36
+#define TEGRA_IMAGE_DT_RAW6 40
+#define TEGRA_IMAGE_DT_RAW7 41
+#define TEGRA_IMAGE_DT_RAW8 42
+#define TEGRA_IMAGE_DT_RAW10 43
+#define TEGRA_IMAGE_DT_RAW12 44
+#define TEGRA_IMAGE_DT_RAW14 45
+
static int vi2_port_is_valid(int port)
{
return (((port) >= TEGRA_CAMERA_PORT_CSI_A) &&
@@ -481,6 +541,7 @@ static int vi2_capture_setup_csi_0(struct tegra_camera_dev *cam,
{
struct soc_camera_subdev_desc *ssdesc = &icd->sdesc->subdev_desc;
struct tegra_camera_platform_data *pdata = ssdesc->drv_priv;
+ int format = 0, data_type = 0, image_size = 0;
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);
@@ -508,24 +569,33 @@ static int vi2_capture_setup_csi_0(struct tegra_camera_dev *cam,
TC_VI_REG_WT(cam, TEGRA_CSI_PG_BLUE_FREQ_RATE_A, 0x0);
TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x22020202);
- /* output format A8B8G8R8, only support direct to mem */
- 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,
- (1 << 24) | (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);
+ format = TEGRA_IMAGE_FORMAT_T_A8B8G8R8;
+ data_type = TEGRA_IMAGE_DT_RGB888;
+ image_size = icd->user_width * 3;
+ } else if ((icd->current_fmt->code == V4L2_MBUS_FMT_UYVY8_2X8) ||
+ (icd->current_fmt->code == V4L2_MBUS_FMT_VYUY8_2X8) ||
+ (icd->current_fmt->code == V4L2_MBUS_FMT_YUYV8_2X8) ||
+ (icd->current_fmt->code == V4L2_MBUS_FMT_YVYU8_2X8)) {
+ /* TBD */
+ } else if ((icd->current_fmt->code == V4L2_MBUS_FMT_SBGGR8_1X8) ||
+ (icd->current_fmt->code == V4L2_MBUS_FMT_SGBRG8_1X8)) {
+ format = TEGRA_IMAGE_FORMAT_T_L8;
+ data_type = TEGRA_IMAGE_DT_RAW8;
+ image_size = icd->user_width;
+ } else if ((icd->current_fmt->code == V4L2_MBUS_FMT_SBGGR10_1X10) ||
+ (icd->current_fmt->code == V4L2_MBUS_FMT_SRGGB10_1X10)) {
+ format = TEGRA_IMAGE_FORMAT_T_R16_I;
+ data_type = TEGRA_IMAGE_DT_RAW10;
+ image_size = (icd->user_width * 10) >> 3;
}
+ TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_IMAGE_DEF,
+ (cam->tpg_mode ? 0 : 1 << 24) | (format << 16) | 0x1);
+
+ TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_CSI_IMAGE_DT, data_type);
+
+ TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_CSI_IMAGE_SIZE_WC, image_size);
+
TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_CSI_IMAGE_SIZE,
(icd->user_height << 16) | icd->user_width);
@@ -537,6 +607,7 @@ static int vi2_capture_setup_csi_1(struct tegra_camera_dev *cam,
{
struct soc_camera_subdev_desc *ssdesc = &icd->sdesc->subdev_desc;
struct tegra_camera_platform_data *pdata = ssdesc->drv_priv;
+ int format = 0, data_type = 0, image_size = 0;
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);
@@ -566,26 +637,32 @@ static int vi2_capture_setup_csi_1(struct tegra_camera_dev *cam,
TC_VI_REG_WT(cam, TEGRA_CSI_PG_BLUE_FREQ_RATE_B, 0x0);
TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x22020202);
- /* output format A8B8G8R8, only support direct to mem */
- TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_IMAGE_DEF, (64 << 16) | 0x1);
- /* input format is RGB888 */
- TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_CSI_IMAGE_DT, 36);
-
- TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_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_1_IMAGE_DEF,
- (1 << 24) | (32 << 16) | 0x1);
- /* input format is RAW10 */
- TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_CSI_IMAGE_DT, 43);
-
- TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_CSI_IMAGE_SIZE_WC,
- icd->user_width * 10 / 8);
+ format = TEGRA_IMAGE_FORMAT_T_A8B8G8R8;
+ data_type = TEGRA_IMAGE_DT_RGB888;
+ image_size = icd->user_width * 3;
+ } else if ((icd->current_fmt->code == V4L2_MBUS_FMT_UYVY8_2X8) ||
+ (icd->current_fmt->code == V4L2_MBUS_FMT_VYUY8_2X8) ||
+ (icd->current_fmt->code == V4L2_MBUS_FMT_YUYV8_2X8) ||
+ (icd->current_fmt->code == V4L2_MBUS_FMT_YVYU8_2X8)) {
+ /* TBD */
+ } else if ((icd->current_fmt->code == V4L2_MBUS_FMT_SBGGR8_1X8) ||
+ (icd->current_fmt->code == V4L2_MBUS_FMT_SGBRG8_1X8)) {
+ format = TEGRA_IMAGE_FORMAT_T_L8;
+ data_type = TEGRA_IMAGE_DT_RAW8;
+ image_size = icd->user_width;
+ } else if ((icd->current_fmt->code == V4L2_MBUS_FMT_SBGGR10_1X10) ||
+ (icd->current_fmt->code == V4L2_MBUS_FMT_SRGGB10_1X10)) {
+ format = TEGRA_IMAGE_FORMAT_T_R16_I;
+ data_type = TEGRA_IMAGE_DT_RAW10;
+ image_size = icd->user_width * 10 / 8;
}
- TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_CSI_IMAGE_SIZE,
- (icd->user_height << 16) | icd->user_width);
+ TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_IMAGE_DEF,
+ (cam->tpg_mode ? 0 : 1 << 24) | (format << 16) | 0x1);
+
+ TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_CSI_IMAGE_DT, data_type);
+
+ TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_CSI_IMAGE_SIZE_WC, image_size);
return 0;
}
@@ -716,41 +793,30 @@ static int vi2_capture_buffer_setup(struct tegra_camera_dev *cam,
return 0;
}
-static int vi2_capture_error_status(struct tegra_camera_dev *cam)
+static void vi2_capture_error_status(struct tegra_camera_dev *cam)
{
- int err;
+ u32 val;
#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);
+ val = TC_VI_REG_RD(cam, TEGRA_CSI_DEBUG_COUNTER_0);
+ pr_err("TEGRA_CSI_DEBUG_COUNTER_0 0x%08x\n", val);
#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;
+ val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CIL_A_STATUS);
+ pr_err("TEGRA_CSI_CSI_CIL_A_STATUS 0x%08x\n", val);
+ val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CILA_STATUS);
+ pr_err("TEGRA_CSI_CSI_CILA_STATUS 0x%08x\n", val);
+ val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CIL_B_STATUS);
+ pr_err("TEGRA_CSI_CSI_CIL_B_STATUS 0x%08x\n", val);
+ val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CIL_C_STATUS);
+ pr_err("TEGRA_CSI_CSI_CIL_C_STATUS 0x%08x\n", val);
+ val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CIL_D_STATUS);
+ pr_err("TEGRA_CSI_CSI_CIL_D_STATUS 0x%08x\n", val);
+ val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CIL_E_STATUS);
+ 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_VI_CSI_0_ERROR_STATUS);
+ pr_err("TEGRA_VI_CSI_0_ERROR_STATUS 0x%08x\n", val);
}
static int vi2_capture_start(struct tegra_camera_dev *cam,
@@ -799,9 +865,17 @@ static int vi2_capture_start(struct tegra_camera_dev *cam,
/* Capture syncpt timeout err, then dump error status */
if (err) {
- dev_err(&cam->ndev->dev, "CSI sync point failure\n");
+ if (port == TEGRA_CAMERA_PORT_CSI_A)
+ 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)
+ dev_err(&cam->ndev->dev,
+ "CSI_B syncpt timeout, syncpt = %d, err = %d\n",
+ cam->syncpt_csi_b, err);
vi2_capture_error_status(cam);
}
+
return err;
}