msm: camera: Add recording state machine in vfe 3.2.
-The recording state machine which was present for
earlier targets is missing in vfe 3.2. Add this to
avoid any issues that might be seen during
starting/stopping of video recording.
-Also remove the msleep during streamoff. This is
no longer needed, since the state machine handles
this case properly.
Signed-off-by: Kiran Kumar H N <hurlisal@codeaurora.org>
diff --git a/drivers/media/video/msm/msm.c b/drivers/media/video/msm/msm.c
index 1f9f667..490f12e 100644
--- a/drivers/media/video/msm/msm.c
+++ b/drivers/media/video/msm/msm.c
@@ -798,7 +798,6 @@
if (rc < 0)
pr_err("%s: hw failed to stop streaming\n", __func__);
- msleep(67);
/* stop buffer streaming */
rc = vb2_streamoff(&pcam_inst->vid_bufq, V4L2_BUF_TYPE_VIDEO_CAPTURE);
D("%s, videobuf_streamoff returns %d\n", __func__, rc);
diff --git a/drivers/media/video/msm/msm_vfe32.c b/drivers/media/video/msm/msm_vfe32.c
index 1b06c43..9cdf4ac 100644
--- a/drivers/media/video/msm/msm_vfe32.c
+++ b/drivers/media/video/msm/msm_vfe32.c
@@ -706,8 +706,7 @@
vfe32_ctrl->update_ack_pending = FALSE;
spin_unlock_irqrestore(&vfe32_ctrl->update_ack_lock, flags);
- vfe32_ctrl->req_stop_video_rec = FALSE;
- vfe32_ctrl->req_start_video_rec = FALSE;
+ vfe32_ctrl->recording_state = VFE_REC_STATE_IDLE;
atomic_set(&vfe32_ctrl->vstate, 0);
@@ -895,41 +894,17 @@
atomic_set(&vfe32_ctrl->vstate, 1);
}
-#define ENQUEUED_BUFFERS 3
static int vfe32_start_recording(void)
{
- vfe32_ctrl->req_start_video_rec = TRUE;
- /* Mask with 0x7 to extract the pixel pattern*/
- switch (msm_io_r(vfe32_ctrl->vfebase + VFE_CFG) & 0x7) {
- case VFE_YUV_YCbYCr:
- case VFE_YUV_YCrYCb:
- case VFE_YUV_CbYCrY:
- case VFE_YUV_CrYCbY:
- msm_io_w_mb(1,
- vfe32_ctrl->vfebase + VFE_REG_UPDATE_CMD);
- break;
- default:
- break;
- }
+ vfe32_ctrl->recording_state = VFE_REC_STATE_START_REQUESTED;
+ msm_io_w_mb(1, vfe32_ctrl->vfebase + VFE_REG_UPDATE_CMD);
return 0;
}
static int vfe32_stop_recording(void)
{
- vfe32_ctrl->req_stop_video_rec = TRUE;
- /* Mask with 0x7 to extract the pixel pattern*/
- switch (msm_io_r(vfe32_ctrl->vfebase + VFE_CFG) & 0x7) {
- case VFE_YUV_YCbYCr:
- case VFE_YUV_YCrYCb:
- case VFE_YUV_CbYCrY:
- case VFE_YUV_CrYCbY:
- msm_io_w_mb(1,
- vfe32_ctrl->vfebase + VFE_REG_UPDATE_CMD);
- break;
- default:
- break;
- }
-
+ vfe32_ctrl->recording_state = VFE_REC_STATE_STOP_REQUESTED;
+ msm_io_w_mb(1, vfe32_ctrl->vfebase + VFE_REG_UPDATE_CMD);
return 0;
}
@@ -2097,27 +2072,14 @@
{
uint32_t temp, old_val;
unsigned long flags;
- if (vfe32_ctrl->req_start_video_rec) {
+ if (vfe32_ctrl->recording_state == VFE_REC_STATE_START_REQUESTED) {
if (vfe32_ctrl->outpath.output_mode & VFE32_OUTPUT_MODE_V) {
msm_io_w(1, vfe32_ctrl->vfebase +
vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out2.ch0]);
msm_io_w(1, vfe32_ctrl->vfebase +
vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out2.ch1]);
- /* Mask with 0x7 to extract the pixel pattern*/
- switch (msm_io_r(vfe32_ctrl->vfebase + VFE_CFG)
- & 0x7) {
- case VFE_YUV_YCbYCr:
- case VFE_YUV_YCrYCb:
- case VFE_YUV_CbYCrY:
- case VFE_YUV_CrYCbY:
- msm_io_w_mb(1,
- vfe32_ctrl->vfebase + VFE_REG_UPDATE_CMD);
- break;
- default:
- break;
- }
}
- vfe32_ctrl->req_start_video_rec = FALSE;
+ vfe32_ctrl->recording_state = VFE_REC_STATE_STARTED;
if (vpe_ctrl && vpe_ctrl->dis_en) {
old_val = msm_io_r(
vfe32_ctrl->vfebase + VFE_MODULE_CFG);
@@ -2125,29 +2087,16 @@
msm_io_w(old_val,
vfe32_ctrl->vfebase + VFE_MODULE_CFG);
}
+ msm_io_w_mb(1, vfe32_ctrl->vfebase + VFE_REG_UPDATE_CMD);
CDBG("start video triggered .\n");
- } else if (vfe32_ctrl->req_stop_video_rec) {
+ } else if (vfe32_ctrl->recording_state ==
+ VFE_REC_STATE_STOP_REQUESTED) {
if (vfe32_ctrl->outpath.output_mode & VFE32_OUTPUT_MODE_V) {
- msm_io_w(0, vfe32_ctrl->vfebase +
+ msm_io_w_mb(0, vfe32_ctrl->vfebase +
vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out2.ch0]);
- msm_io_w(0, vfe32_ctrl->vfebase +
+ msm_io_w_mb(0, vfe32_ctrl->vfebase +
vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out2.ch1]);
- /* Mask with 0x7 to extract the pixel pattern*/
- switch (msm_io_r(vfe32_ctrl->vfebase + VFE_CFG)
- & 0x7) {
- case VFE_YUV_YCbYCr:
- case VFE_YUV_YCrYCb:
- case VFE_YUV_CbYCrY:
- case VFE_YUV_CrYCbY:
- msm_io_w_mb(1,
- vfe32_ctrl->vfebase + VFE_REG_UPDATE_CMD);
- break;
- default:
- break;
- }
}
- vfe32_ctrl->req_stop_video_rec = FALSE;
- vfe32_send_msg_no_payload(MSG_ID_STOP_REC_ACK);
/*disable rs& cs when stop recording. */
old_val = msm_io_r(vfe32_ctrl->vfebase + VFE_MODULE_CFG);
@@ -2160,6 +2109,19 @@
vfe32_send_msg_no_payload(MSG_ID_START_ACK);
vfe32_ctrl->start_ack_pending = FALSE;
} else {
+ if (vfe32_ctrl->recording_state ==
+ VFE_REC_STATE_STOP_REQUESTED) {
+ vfe32_ctrl->recording_state = VFE_REC_STATE_STOPPED;
+ /* request a reg update and send STOP_REC_ACK
+ * when we process the next reg update irq.
+ */
+ msm_io_w_mb(1,
+ vfe32_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+ } else if (vfe32_ctrl->recording_state ==
+ VFE_REC_STATE_STOPPED) {
+ vfe32_send_msg_no_payload(MSG_ID_STOP_REC_ACK);
+ vfe32_ctrl->recording_state = VFE_REC_STATE_IDLE;
+ }
spin_lock_irqsave(&vfe32_ctrl->update_ack_lock, flags);
if (vfe32_ctrl->update_ack_pending == TRUE) {
vfe32_ctrl->update_ack_pending = FALSE;
@@ -2564,6 +2526,13 @@
uint32_t ping_pong;
uint32_t pyaddr, pcbcraddr;
struct msm_free_buf *free_buf = NULL;
+
+ if (vfe32_ctrl->recording_state == VFE_REC_STATE_STOP_REQUESTED) {
+ vfe32_ctrl->outpath.out2.frame_drop_cnt++;
+ CDBG("%s: path_irq_2 - recording stop requested ", __func__);
+ return;
+ }
+
free_buf = vfe32_check_free_buffer(VFE_MSG_OUTPUT_IRQ,
VFE_MSG_OUTPUT_V);
/* we render frames in the following conditions:
diff --git a/drivers/media/video/msm/msm_vfe32.h b/drivers/media/video/msm/msm_vfe32.h
index 83dda77..97b94da 100644
--- a/drivers/media/video/msm/msm_vfe32.h
+++ b/drivers/media/video/msm/msm_vfe32.h
@@ -183,6 +183,14 @@
VFE_STATE_ACTIVE
};
+enum vfe_recording_state {
+ VFE_REC_STATE_IDLE,
+ VFE_REC_STATE_START_REQUESTED,
+ VFE_REC_STATE_STARTED,
+ VFE_REC_STATE_STOP_REQUESTED,
+ VFE_REC_STATE_STOPPED,
+};
+
#define V32_DUMMY_0 0
#define V32_SET_CLK 1
#define V32_RESET 2
@@ -1061,8 +1069,7 @@
int8_t stop_ack_pending;
int8_t reset_ack_pending;
int8_t update_ack_pending;
- int8_t req_start_video_rec;
- int8_t req_stop_video_rec;
+ enum vfe_recording_state recording_state;
int8_t update_linear;
spinlock_t tasklet_lock;