camera: vfe32: Enable VFE configuration for inline JPEG encoding.
During inline JPEG encoding, one VFE output is routed into
internal memory (IMEM) instead of external memory. The JPEG
encoding hardware (GEMINI) will read from IMEM and generates
JPEG bitstream.
Change-Id: I12d3600524538ab85021dd8882af0404bddc488f
Signed-off-by: Shuzhen Wang <shuzhenw@codeaurora.org>
Signed-off-by: Kevin Chan <ktchan@codeaurora.org>
Signed-off-by: Jignesh Mehta <jigneshm@codeaurora.org>
diff --git a/arch/arm/mach-msm/include/mach/camera.h b/arch/arm/mach-msm/include/mach/camera.h
index 530d2c1..700e28c 100644
--- a/arch/arm/mach-msm/include/mach/camera.h
+++ b/arch/arm/mach-msm/include/mach/camera.h
@@ -52,6 +52,7 @@
VFE_MODE_OF_OPERATION_VIDEO,
VFE_MODE_OF_OPERATION_RAW_SNAPSHOT,
VFE_MODE_OF_OPERATION_ZSL,
+ VFE_MODE_OF_OPERATION_JPEG_SNAPSHOT,
VFE_LAST_MODE_OF_OPERATION_ENUM
};
@@ -87,6 +88,7 @@
VFE_MSG_V32_START,
VFE_MSG_V32_START_RECORDING, /* 20 */
VFE_MSG_V32_CAPTURE,
+ VFE_MSG_V32_JPEG_CAPTURE,
VFE_MSG_OUTPUT_IRQ,
VFE_MSG_V2X_PREVIEW,
VFE_MSG_V2X_CAPTURE,
diff --git a/drivers/media/video/msm/msm_isp.c b/drivers/media/video/msm/msm_isp.c
index c9a9f1b..16964b2 100644
--- a/drivers/media/video/msm/msm_isp.c
+++ b/drivers/media/video/msm/msm_isp.c
@@ -199,6 +199,19 @@
vfe_params.data = (void *)&free_buf;
rc = v4l2_subdev_call(sd, core, ioctl, 0, &vfe_params);
break;
+ case VFE_MSG_V32_JPEG_CAPTURE:
+ free_buf.num_planes = 1;
+ free_buf.ch_paddr[0] = IMEM_Y_OFFSET;
+ free_buf.ch_paddr[1] = IMEM_CBCR_OFFSET;
+ cfgcmd.cmd_type = CMD_CONFIG_PING_ADDR;
+ cfgcmd.value = &vfe_id;
+ vfe_params.vfe_cfg = &cfgcmd;
+ vfe_params.data = (void *)&free_buf;
+ rc = v4l2_subdev_call(sd, core, ioctl, 0, &vfe_params);
+ /* Write the same buffer into PONG */
+ cfgcmd.cmd_type = CMD_CONFIG_PONG_ADDR;
+ rc = v4l2_subdev_call(sd, core, ioctl, 0, &vfe_params);
+ break;
case VFE_MSG_OUTPUT_IRQ:
D("%s Got OUTPUT_IRQ: Getting free buf id = %d",
__func__, vfe_id);
diff --git a/drivers/media/video/msm/msm_vfe32.c b/drivers/media/video/msm/msm_vfe32.c
index 99d9911..89bdf0f 100644
--- a/drivers/media/video/msm/msm_vfe32.c
+++ b/drivers/media/video/msm/msm_vfe32.c
@@ -702,8 +702,6 @@
msm_io_w(VFE_IMASK_WHILE_STOPPING_1,
vfe32_ctrl->vfebase + VFE_IRQ_MASK_1);
- msm_io_dump(vfe32_ctrl->vfebase, vfe32_ctrl->register_total * 4);
-
/* Ensure the write order while writing
to the command register using the barrier */
msm_io_w_mb(1, vfe32_ctrl->vfebase + VFE_REG_UPDATE_CMD);
@@ -851,7 +849,9 @@
/* capture command is valid for both idle and active state. */
vfe32_ctrl->outpath.out1.capture_cnt = num_frames_capture;
if (vfe32_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB ||
- vfe32_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_MAIN) {
+ vfe32_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_MAIN ||
+ vfe32_ctrl->operation_mode == VFE_OUTPUTS_JPEG_AND_THUMB ||
+ vfe32_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_JPEG) {
vfe32_ctrl->outpath.out0.capture_cnt =
num_frames_capture;
}
@@ -887,6 +887,9 @@
vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch1]);
}
}
+
+ vfe32_ctrl->vfe_capture_count = num_frames_capture;
+
msm_io_w(irq_comp_mask, vfe32_ctrl->vfebase + VFE_IRQ_COMP_MASK);
msm_io_r(vfe32_ctrl->vfebase + VFE_IRQ_COMP_MASK);
msm_camio_bus_scale_cfg(
@@ -1286,16 +1289,31 @@
rc = vfe32_capture_raw(snapshot_cnt);
break;
case VFE_CMD_CAPTURE:
- pr_info("vfe32_proc_general: cmdID = %s\n",
- vfe32_general_cmd[cmd->id]);
+ CDBG("vfe32_proc_general: cmdID = %s op mode = %d\n",
+ vfe32_general_cmd[cmd->id], vfe32_ctrl->operation_mode);
if (copy_from_user(&snapshot_cnt, (void __user *)(cmd->value),
sizeof(uint32_t))) {
rc = -EFAULT;
goto proc_general_done;
}
- /* Configure primary channel */
- rc = vfe32_configure_pingpong_buffers(VFE_MSG_V32_CAPTURE,
- VFE_MSG_OUTPUT_PRIMARY);
+
+ if (vfe32_ctrl->operation_mode == VFE_OUTPUTS_JPEG_AND_THUMB ||
+ vfe32_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_JPEG) {
+ if (snapshot_cnt != 1) {
+ pr_err("only support 1 inline snapshot\n");
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
+ /* Configure primary channel for JPEG */
+ rc = vfe32_configure_pingpong_buffers(
+ VFE_MSG_V32_JPEG_CAPTURE,
+ VFE_MSG_OUTPUT_PRIMARY);
+ } else {
+ /* Configure primary channel */
+ rc = vfe32_configure_pingpong_buffers(
+ VFE_MSG_V32_CAPTURE,
+ VFE_MSG_OUTPUT_PRIMARY);
+ }
if (rc < 0) {
pr_err("%s error configuring pingpong buffers"
" for primary output", __func__);
@@ -2610,7 +2628,9 @@
}
if ((vfe32_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_MAIN) ||
- (vfe32_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB)) {
+ (vfe32_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB) ||
+ (vfe32_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_JPEG) ||
+ (vfe32_ctrl->operation_mode == VFE_OUTPUTS_JPEG_AND_THUMB)) {
/* in snapshot mode */
/* later we need to add check for live snapshot mode. */
if (vfe32_ctrl->frame_skip_pattern & (0x1 <<
@@ -2858,6 +2878,8 @@
*/
out_bool = ((vfe32_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_MAIN ||
vfe32_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB ||
+ vfe32_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_JPEG ||
+ vfe32_ctrl->operation_mode == VFE_OUTPUTS_JPEG_AND_THUMB ||
vfe32_ctrl->operation_mode == VFE_OUTPUTS_RAW ||
vfe32_ctrl->liveshot_state == VFE_STATE_STARTED ||
vfe32_ctrl->liveshot_state == VFE_STATE_STOP_REQUESTED ||
@@ -2899,6 +2921,10 @@
vfe32_ctrl->operation_mode ==
VFE_OUTPUTS_MAIN_AND_THUMB ||
vfe32_ctrl->operation_mode ==
+ VFE_OUTPUTS_THUMB_AND_JPEG ||
+ vfe32_ctrl->operation_mode ==
+ VFE_OUTPUTS_JPEG_AND_THUMB ||
+ vfe32_ctrl->operation_mode ==
VFE_OUTPUTS_RAW ||
vfe32_ctrl->liveshot_state == VFE_STATE_STOPPED)
vfe32_ctrl->outpath.out0.capture_cnt--;
@@ -3392,6 +3418,10 @@
vfe32_ctrl->operation_mode ==
VFE_OUTPUTS_MAIN_AND_THUMB ||
vfe32_ctrl->operation_mode ==
+ VFE_OUTPUTS_THUMB_AND_JPEG ||
+ vfe32_ctrl->operation_mode ==
+ VFE_OUTPUTS_JPEG_AND_THUMB ||
+ vfe32_ctrl->operation_mode ==
VFE_OUTPUTS_RAW) {
if ((vfe32_ctrl->outpath.out0.capture_cnt == 0)
&& (vfe32_ctrl->outpath.out1.
diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h
index 87fbbd2..1a6f68f 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -693,6 +693,9 @@
#define MSM_V4L2_CAM_OP_ZSL (MSM_V4L2_CAM_OP_DEFAULT+4)
/* camera operation mode for raw snapshot - one frame output queue */
#define MSM_V4L2_CAM_OP_RAW (MSM_V4L2_CAM_OP_DEFAULT+5)
+/* camera operation mode for jpeg snapshot - one frame output queue */
+#define MSM_V4L2_CAM_OP_JPEG_CAPTURE (MSM_V4L2_CAM_OP_DEFAULT+6)
+
#define MSM_V4L2_VID_CAP_TYPE 0
#define MSM_V4L2_STREAM_ON 1
diff --git a/include/media/msm_isp.h b/include/media/msm_isp.h
index 5dd1445..07784e2 100644
--- a/include/media/msm_isp.h
+++ b/include/media/msm_isp.h
@@ -241,6 +241,9 @@
#define VPE_SCALER_CONFIG_LEN 260
#define VPE_DIS_OFFSET_CFG_LEN 12
+#define IMEM_Y_OFFSET 0x2E000000
+#define IMEM_CBCR_OFFSET 0x2E00FA00
+
struct msm_vpe_op_mode_cfg {
uint8_t op_mode_cfg[VPE_OPERATION_MODE_CFG_LEN];
};
@@ -311,6 +314,8 @@
#define VFE_OUTPUTS_PREVIEW BIT(6)
#define VFE_OUTPUTS_VIDEO BIT(7)
#define VFE_OUTPUTS_RAW BIT(8)
+#define VFE_OUTPUTS_JPEG_AND_THUMB BIT(9)
+#define VFE_OUTPUTS_THUMB_AND_JPEG BIT(10)
#endif /*__MSM_ISP_H__*/