summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAbhishek Kondaveeti <akondave@codeaurora.org>2016-02-02 12:20:14 +0530
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 21:21:04 -0700
commit6089ecbfc057c40652a410de859da2ce9754fe54 (patch)
tree8dfec75bc7d20e65bf6d9c18746599ddf0aed146
parent10a10539d08e116b220b820226e5ed99f37b117b (diff)
msm: isp: Avoid ping pong mismatch in CDS
Update AXI only when both ISPs issue reg update interrupt. CRs-Fixed: 955803 Change-Id: I8b7090e2b45de5a84e5ceca02aa083aefc6af600 Signed-off-by: Abhishek Kondaveeti <akondave@codeaurora.org>
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c60
1 files changed, 56 insertions, 4 deletions
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 e97b76ad2d30..e282ac6e1c78 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
@@ -22,6 +22,10 @@ static int msm_isp_update_dual_HW_ms_info_at_start(
struct vfe_device *vfe_dev,
enum msm_vfe_input_src stream_src);
+static int msm_isp_update_dual_HW_axi(
+ struct vfe_device *vfe_dev,
+ struct msm_vfe_axi_stream *stream_info);
+
#define DUAL_VFE_AND_VFE1(s, v) ((s->stream_src < RDI_INTF_0) && \
v->is_split && vfe_dev->pdev->id == ISP_VFE1)
@@ -1339,6 +1343,7 @@ void msm_isp_axi_cfg_update(struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info;
int num_stream = 0;
+ spin_lock_irqsave(&vfe_dev->common_data->common_dev_data_lock, flags);
for (i = 0; i < VFE_AXI_SRC_MAX; i++) {
if (SRC_TO_INTF(axi_data->stream_info[i].stream_src) !=
frame_src) {
@@ -1360,9 +1365,15 @@ void msm_isp_axi_cfg_update(struct vfe_device *vfe_dev,
cfg_wm_reg(vfe_dev, stream_info, j);
/*Resume AXI*/
stream_info->state = RESUME_PENDING;
- msm_isp_axi_stream_enable_cfg(
- vfe_dev, &axi_data->stream_info[i], 1);
- stream_info->state = RESUMING;
+ if (vfe_dev->is_split) {
+ msm_isp_update_dual_HW_axi(vfe_dev,
+ stream_info);
+ } else {
+ msm_isp_axi_stream_enable_cfg(
+ vfe_dev,
+ &axi_data->stream_info[i], 1);
+ stream_info->state = RESUMING;
+ }
} else if (stream_info->state == RESUMING) {
stream_info->runtime_output_format =
stream_info->output_format;
@@ -1370,7 +1381,8 @@ void msm_isp_axi_cfg_update(struct vfe_device *vfe_dev,
}
spin_unlock_irqrestore(&stream_info->lock, flags);
}
-
+ spin_unlock_irqrestore(&vfe_dev->common_data->common_dev_data_lock,
+ flags);
if (num_stream)
update_state = atomic_dec_return(
&axi_data->axi_cfg_update[frame_src]);
@@ -2401,6 +2413,46 @@ static int msm_isp_update_dual_HW_ms_info_at_stop(
return rc;
}
+static int msm_isp_update_dual_HW_axi(struct vfe_device *vfe_dev,
+ struct msm_vfe_axi_stream *stream_info)
+{
+ int rc, vfe_id;
+ uint32_t stream_idx = HANDLE_TO_IDX(stream_info->stream_handle);
+ struct dual_vfe_resource *dual_vfe_res = NULL;
+
+ if (stream_idx >= VFE_AXI_SRC_MAX) {
+ pr_err("%s: Invalid stream idx %d\n", __func__, stream_idx);
+ return -EINVAL;
+ }
+
+ dual_vfe_res = vfe_dev->common_data->dual_vfe_res;
+
+ if (!dual_vfe_res->vfe_dev[ISP_VFE0] ||
+ !dual_vfe_res->vfe_dev[ISP_VFE1] ||
+ !dual_vfe_res->axi_data[ISP_VFE0] ||
+ !dual_vfe_res->axi_data[ISP_VFE1]) {
+ pr_err("%s: Error in dual vfe resource\n", __func__);
+ rc = -EINVAL;
+ } else {
+ if (stream_info->state == RESUME_PENDING &&
+ (dual_vfe_res->axi_data[!vfe_dev->pdev->id]->
+ stream_info[stream_idx].state == RESUME_PENDING)) {
+ /* Update the AXI only after both ISPs receiving the
+ Reg update interrupt*/
+ for (vfe_id = 0; vfe_id < MAX_VFE; vfe_id++) {
+ rc = msm_isp_axi_stream_enable_cfg(
+ dual_vfe_res->vfe_dev[vfe_id],
+ &dual_vfe_res->axi_data[vfe_id]->
+ stream_info[stream_idx], 1);
+ dual_vfe_res->axi_data[vfe_id]->
+ stream_info[stream_idx].state =
+ RESUMING;
+ }
+ }
+ }
+ return rc;
+}
+
static int msm_isp_start_axi_stream(struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream_cfg_cmd *stream_cfg_cmd,
enum msm_isp_camif_update_state camif_update)