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

Commit c911d770 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: camera: isp: Fix the framedrop setting issue"

parents dbc80892 1f0cf54f
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -616,6 +616,7 @@ struct dual_vfe_resource {
	struct msm_vfe_stats_shared_data *stats_data[MAX_VFE];
	struct msm_vfe_axi_shared_data *axi_data[MAX_VFE];
	uint32_t wm_reload_mask[MAX_VFE];
	uint32_t epoch_sync_mask;
};

struct master_slave_resource_info {
+90 −1
Original line number Diff line number Diff line
@@ -543,6 +543,89 @@ static void msm_isp_cfg_framedrop_reg(struct vfe_device *vfe_dev,
	}
}

/**
 * msm_isp_check_epoch_status() -  check the epock signal for framedrop
 *
 * @vfe_dev: The h/w on which the epoch signel is reveived
 * @frame_src: The source of the epoch signal for this frame
 *
 * For dual vfe case and pixel stream, if both vfe's epoch signal is
 * received, this function will return success.
 * It will also return the vfe1 for further process
 * For none dual VFE stream or none pixl source, this
 * funciton will just return success.
 *
 * Returns  1 - epoch received is complete.
 *          0 - epoch reveived is not complete.
 */
static int msm_isp_check_epoch_status(struct vfe_device **vfe_dev,
	enum msm_vfe_input_src frame_src)
{
	struct vfe_device *vfe_dev_cur = *vfe_dev;
	struct vfe_device *vfe_dev_other = NULL;
	uint32_t vfe_id_other = 0;
	uint32_t vfe_id_cur = 0;
	uint32_t epoch_mask = 0;
	unsigned long flags;
	int completed = 0;

	spin_lock_irqsave(
		&vfe_dev_cur->common_data->common_dev_data_lock, flags);

	if (vfe_dev_cur->is_split &&
		frame_src == VFE_PIX_0) {
		if (vfe_dev_cur->pdev->id == ISP_VFE0) {
			vfe_id_cur = ISP_VFE0;
			vfe_id_other = ISP_VFE1;
		} else {
			vfe_id_cur = ISP_VFE1;
			vfe_id_other = ISP_VFE0;
		}
		vfe_dev_other = vfe_dev_cur->common_data->dual_vfe_res->
			vfe_dev[vfe_id_other];

		if (vfe_dev_cur->common_data->dual_vfe_res->
			epoch_sync_mask & (1 << vfe_id_cur)) {
			/* serious scheduling delay */
			pr_err("Missing epoch: vfe %d, epoch mask 0x%x\n",
				vfe_dev_cur->pdev->id,
				vfe_dev_cur->common_data->dual_vfe_res->
					epoch_sync_mask);
			goto fatal;
		}

		vfe_dev_cur->common_data->dual_vfe_res->
			epoch_sync_mask |= (1 << vfe_id_cur);

		epoch_mask = (1 << vfe_id_cur) | (1 << vfe_id_other);
		if ((vfe_dev_cur->common_data->dual_vfe_res->
			epoch_sync_mask & epoch_mask) == epoch_mask) {

			if (vfe_id_other == ISP_VFE0)
				*vfe_dev = vfe_dev_cur;
			else
				*vfe_dev = vfe_dev_other;

			vfe_dev_cur->common_data->dual_vfe_res->
				epoch_sync_mask &= ~epoch_mask;
			completed = 1;
		}
	} else
		completed = 1;

	spin_unlock_irqrestore(
		&vfe_dev_cur->common_data->common_dev_data_lock, flags);

	return completed;
fatal:
	spin_unlock_irqrestore(
		&vfe_dev_cur->common_data->common_dev_data_lock, flags);
	/* new error event code will be added later */
	msm_isp_halt_send_error(vfe_dev_cur, ISP_EVENT_PING_PONG_MISMATCH);
	return 0;
}


/**
 * msm_isp_update_framedrop_reg() - Update frame period pattern on h/w
 * @vfe_dev: The h/w on which the perion pattern is updated.
@@ -558,10 +641,15 @@ void msm_isp_update_framedrop_reg(struct vfe_device *vfe_dev,
	enum msm_vfe_input_src frame_src)
{
	int i;
	struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
	struct msm_vfe_axi_shared_data *axi_data = NULL;
	struct msm_vfe_axi_stream *stream_info;
	unsigned long flags;

	if (msm_isp_check_epoch_status(&vfe_dev, frame_src) != 1)
		return;

	axi_data = &vfe_dev->axi_data;

	for (i = 0; i < VFE_AXI_SRC_MAX; i++) {
		if (SRC_TO_INTF(axi_data->stream_info[i].stream_src) !=
			frame_src) {
@@ -2581,6 +2669,7 @@ static int msm_isp_start_axi_stream(struct vfe_device *vfe_dev,
		vfe_dev->hw_info->vfe_ops.core_ops.
			update_camif_state(vfe_dev, camif_update);
		vfe_dev->axi_data.camif_state = CAMIF_ENABLE;
		vfe_dev->common_data->dual_vfe_res->epoch_sync_mask = 0;
	}

	if (wait_for_complete) {
+7 −2
Original line number Diff line number Diff line
@@ -2153,11 +2153,16 @@ int msm_isp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)

	ISP_DBG("%s open_cnt %u\n", __func__, vfe_dev->vfe_open_cnt);

	if (vfe_dev->common_data == NULL) {
		pr_err("%s: Error in probe. No common_data\n", __func__);
	if (vfe_dev->common_data == NULL ||
		vfe_dev->common_data->dual_vfe_res == NULL) {
		pr_err("%s: Error in probe. No common_data or dual vfe res\n",
			__func__);
		return -EINVAL;
	}

	if (vfe_dev->pdev->id == ISP_VFE0)
		vfe_dev->common_data->dual_vfe_res->epoch_sync_mask = 0;

	mutex_lock(&vfe_dev->realtime_mutex);
	mutex_lock(&vfe_dev->core_mutex);