diff options
| author | Abhishek Kondaveeti <akondave@codeaurora.org> | 2016-02-02 12:20:14 +0530 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 21:21:04 -0700 |
| commit | 6089ecbfc057c40652a410de859da2ce9754fe54 (patch) | |
| tree | 8dfec75bc7d20e65bf6d9c18746599ddf0aed146 | |
| parent | 10a10539d08e116b220b820226e5ed99f37b117b (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.c | 60 |
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) |
