msm: camera: Enhance framedrop control

Expand supported framedrop pattern to support
high frame rate features.

Change-Id: I1e8b7837985ac7be6d794eb36033e0f20c06c0a2
Signed-off-by: Kevin Chan <ktchan@codeaurora.org>
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
index 460e530..f6b97d4 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
@@ -234,6 +234,7 @@
 	uint8_t buf_divert;
 	enum msm_vfe_axi_stream_type stream_type;
 
+	uint32_t framedrop_period;
 	uint32_t framedrop_pattern;
 	uint32_t init_frame_drop;
 	uint32_t burst_frame_count;/*number of sof before burst stop*/
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
index 81c6626..a522bd6 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
@@ -421,23 +421,27 @@
 static void msm_vfe32_cfg_framedrop(struct vfe_device *vfe_dev,
 	struct msm_vfe_axi_stream *stream_info)
 {
-	uint32_t framedrop_pattern = 0;
+	uint32_t framedrop_pattern = 0, framedrop_period = 0;
 
-	if (stream_info->init_frame_drop == 0)
+	if (stream_info->init_frame_drop == 0) {
 		framedrop_pattern = stream_info->framedrop_pattern;
+		framedrop_period = stream_info->framedrop_period;
+	}
 
 	if (stream_info->stream_type == BURST_STREAM &&
-		stream_info->burst_frame_count == 0)
+		stream_info->burst_frame_count == 0) {
 		framedrop_pattern = 0;
+		framedrop_period = 0;
+	}
 
 	if (stream_info->stream_src == PIX_ENCODER) {
-		msm_camera_io_w(0x1F, vfe_dev->vfe_base + 0x504);
-		msm_camera_io_w(0x1F, vfe_dev->vfe_base + 0x508);
+		msm_camera_io_w(framedrop_period, vfe_dev->vfe_base + 0x504);
+		msm_camera_io_w(framedrop_period, vfe_dev->vfe_base + 0x508);
 		msm_camera_io_w(framedrop_pattern, vfe_dev->vfe_base + 0x50C);
 		msm_camera_io_w(framedrop_pattern, vfe_dev->vfe_base + 0x510);
 	} else if (stream_info->stream_src == PIX_VIEWFINDER) {
-		msm_camera_io_w(0x1F, vfe_dev->vfe_base + 0x514);
-		msm_camera_io_w(0x1F, vfe_dev->vfe_base + 0x518);
+		msm_camera_io_w(framedrop_period, vfe_dev->vfe_base + 0x514);
+		msm_camera_io_w(framedrop_period, vfe_dev->vfe_base + 0x518);
 		msm_camera_io_w(framedrop_pattern, vfe_dev->vfe_base + 0x51C);
 		msm_camera_io_w(framedrop_pattern, vfe_dev->vfe_base + 0x520);
 	}
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
index fb8445e..dba59d7 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
@@ -292,8 +292,11 @@
 	if (irq_status0 & (1 << 0)) {
 		ISP_DBG("%s: SOF IRQ\n", __func__);
 		if (vfe_dev->axi_data.src_info[VFE_PIX_0].raw_stream_count > 0
-		&& vfe_dev->axi_data.src_info[VFE_PIX_0].pix_stream_count == 0)
+			&& vfe_dev->axi_data.src_info[VFE_PIX_0].
+			pix_stream_count == 0) {
 			msm_isp_sof_notify(vfe_dev, VFE_PIX_0, tv);
+			msm_isp_update_framedrop_reg(vfe_dev);
+		}
 	}
 	if (irq_status0 & (1 << 1))
 		ISP_DBG("%s: EOF IRQ\n", __func__);
@@ -553,19 +556,29 @@
 static void msm_vfe40_cfg_framedrop(struct vfe_device *vfe_dev,
 	struct msm_vfe_axi_stream *stream_info)
 {
-	uint32_t i;
-	uint32_t framedrop_pattern = 0;
+	uint32_t i, temp;
+	uint32_t framedrop_pattern = 0, framedrop_period = 0;
 
-	if (stream_info->init_frame_drop == 0)
+	if (stream_info->init_frame_drop == 0) {
 		framedrop_pattern = stream_info->framedrop_pattern;
+		framedrop_period = stream_info->framedrop_period;
+	}
 
 	if (stream_info->stream_type == BURST_STREAM &&
-			stream_info->burst_frame_count == 0)
+			stream_info->burst_frame_count == 0) {
 		framedrop_pattern = 0;
+		framedrop_period = 0;
+	}
 
-	for (i = 0; i < stream_info->num_planes; i++)
+	for (i = 0; i < stream_info->num_planes; i++) {
 		msm_camera_io_w(framedrop_pattern, vfe_dev->vfe_base +
 			VFE40_WM_BASE(stream_info->wm[i]) + 0x1C);
+		temp = msm_camera_io_r(vfe_dev->vfe_base +
+			VFE40_WM_BASE(stream_info->wm[i]) + 0xC);
+		temp &= 0xFFFFFF83;
+		msm_camera_io_w(temp | framedrop_period << 2,
+		vfe_dev->vfe_base + VFE40_WM_BASE(stream_info->wm[i]) + 0xC);
+	}
 
 	msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x378);
 }
@@ -706,9 +719,6 @@
 			(stream_cfg_cmd->axi_stream_handle & 0xFF)];
 	uint32_t wm_base = VFE40_WM_BASE(stream_info->wm[plane_idx]);
 
-	/*WR_ADDR_CFG*/
-	msm_camera_io_w(0x7C, vfe_dev->vfe_base + wm_base + 0xC);
-
 	/*WR_IMAGE_SIZE*/
 	val =
 		((msm_isp_cal_word_per_line(stream_cfg_cmd->output_format,
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
index 7647c82..606ee89 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
@@ -427,38 +427,31 @@
 		&axi_data->stream_info[
 		(stream_cfg_cmd->axi_stream_handle & 0xFF)];
 	uint32_t framedrop_period = 1;
-
 	switch (stream_cfg_cmd->frame_skip_pattern) {
 	case NO_SKIP:
-		stream_info->framedrop_pattern = VFE_NO_DROP;
-		framedrop_period = 1;
-		break;
 	case EVERY_2FRAME:
-		stream_info->framedrop_pattern = VFE_DROP_EVERY_2FRAME;
-		framedrop_period = 2;
-		break;
+	case EVERY_3FRAME:
 	case EVERY_4FRAME:
-		stream_info->framedrop_pattern = VFE_DROP_EVERY_4FRAME;
-		framedrop_period = 4;
-		break;
+	case EVERY_5FRAME:
+	case EVERY_6FRAME:
+	case EVERY_7FRAME:
 	case EVERY_8FRAME:
-		stream_info->framedrop_pattern = VFE_DROP_EVERY_8FRAME;
-		framedrop_period = 8;
+		framedrop_period = stream_cfg_cmd->frame_skip_pattern + 1;
 		break;
 	case EVERY_16FRAME:
-		stream_info->framedrop_pattern = VFE_DROP_EVERY_16FRAME;
 		framedrop_period = 16;
 		break;
 	case EVERY_32FRAME:
-		stream_info->framedrop_pattern = VFE_DROP_EVERY_32FRAME;
 		framedrop_period = 32;
 		break;
 	default:
-		stream_info->framedrop_pattern = VFE_NO_DROP;
 		framedrop_period = 1;
 		break;
 	}
 
+	stream_info->framedrop_pattern = 0x1;
+	stream_info->framedrop_period = framedrop_period - 1;
+
 	if (stream_cfg_cmd->init_frame_drop < framedrop_period) {
 		stream_info->framedrop_pattern <<=
 			stream_cfg_cmd->init_frame_drop;
@@ -970,7 +963,6 @@
 	struct msm_vfe_axi_composite_info *comp_info;
 	struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
 
-	ISP_DBG("%s: status: 0x%x\n", __func__, irq_status0);
 	comp_mask = vfe_dev->hw_info->vfe_ops.axi_ops.
 		get_comp_mask(irq_status0, irq_status1);
 	wm_mask = vfe_dev->hw_info->vfe_ops.axi_ops.
@@ -978,6 +970,7 @@
 	if (!(comp_mask || wm_mask))
 		return;
 
+	ISP_DBG("%s: status: 0x%x\n", __func__, irq_status0);
 	pingpong_status =
 		vfe_dev->hw_info->vfe_ops.axi_ops.get_pingpong_status(vfe_dev);
 
diff --git a/include/media/msmb_isp.h b/include/media/msmb_isp.h
index b538218..c9d3f15 100644
--- a/include/media/msmb_isp.h
+++ b/include/media/msmb_isp.h
@@ -52,7 +52,11 @@
 enum msm_vfe_frame_skip_pattern {
 	NO_SKIP,
 	EVERY_2FRAME,
+	EVERY_3FRAME,
 	EVERY_4FRAME,
+	EVERY_5FRAME,
+	EVERY_6FRAME,
+	EVERY_7FRAME,
 	EVERY_8FRAME,
 	EVERY_16FRAME,
 	EVERY_32FRAME,