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;