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,