Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d2c86455 authored by Abhishek Kondaveeti's avatar Abhishek Kondaveeti Committed by Gerrit - the friendly Code Review server
Browse files

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: default avatarAbhishek Kondaveeti <akondave@codeaurora.org>
parent 676c9bc2
Loading
Loading
Loading
Loading
+56 −5
Original line number Diff line number Diff line
@@ -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)

@@ -1322,6 +1326,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) {
@@ -1343,9 +1348,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;
			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);
					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;
@@ -1353,7 +1364,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]);
@@ -1786,7 +1798,6 @@ static int msm_isp_process_done_buf(struct vfe_device *vfe_dev,
				__func__, buf->bufq_handle);
			return -EINVAL;
		}

		if ((bufq != NULL) && bufq->buf_type == ISP_SHARE_BUF)
			msm_isp_send_event(vfe_dev->common_data->
				dual_vfe_res->vfe_dev[ISP_VFE1],
@@ -2394,6 +2405,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)