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

Commit 6ac720fd 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: Sync start SOF of dual VFE in MS mode"

parents 1958b8d1 8d9112da
Loading
Loading
Loading
Loading
+42 −12
Original line number Original line Diff line number Diff line
@@ -646,11 +646,12 @@ void msm_isp_increment_frame_id(struct vfe_device *vfe_dev,
	struct msm_vfe_sof_info *master_sof_info = NULL;
	struct msm_vfe_sof_info *master_sof_info = NULL;
	int32_t time, master_time, delta;
	int32_t time, master_time, delta;
	uint32_t sof_incr = 0;
	uint32_t sof_incr = 0;
	unsigned long flags;


	if (vfe_dev->axi_data.src_info[frame_src].frame_id == 0)
	if (vfe_dev->axi_data.src_info[frame_src].frame_id == 0)
		msm_isp_update_dual_HW_ms_info_at_start(vfe_dev, frame_src);
		msm_isp_update_dual_HW_ms_info_at_start(vfe_dev, frame_src);


	spin_lock(&vfe_dev->common_data->common_dev_data_lock);
	spin_lock_irqsave(&vfe_dev->common_data->common_dev_data_lock, flags);
	dual_hw_type =
	dual_hw_type =
		vfe_dev->axi_data.src_info[frame_src].dual_hw_type;
		vfe_dev->axi_data.src_info[frame_src].dual_hw_type;
	ms_type =
	ms_type =
@@ -677,8 +678,10 @@ void msm_isp_increment_frame_id(struct vfe_device *vfe_dev,
			master_sof_info;
			master_sof_info;
		master_time = master_sof_info->mono_timestamp_ms;
		master_time = master_sof_info->mono_timestamp_ms;
		delta = vfe_dev->common_data->ms_resource.sof_delta_threshold;
		delta = vfe_dev->common_data->ms_resource.sof_delta_threshold;
		ISP_DBG("%s: Slave time %d Master time %d delta %d\n",
		ISP_DBG("%s: vfe %d frame %d Slave time %d Master time %d delta %d\n",
			__func__, time, master_time, time - master_time);
			__func__, vfe_dev->pdev->id,
			vfe_dev->axi_data.src_info[frame_src].frame_id,
			time, master_time, time - master_time);


		if (time - master_time > delta)
		if (time - master_time > delta)
			sof_incr = 1;
			sof_incr = 1;
@@ -726,7 +729,8 @@ void msm_isp_increment_frame_id(struct vfe_device *vfe_dev,
		sof_info->mono_timestamp_ms = ts->buf_time.tv_sec * 1000 +
		sof_info->mono_timestamp_ms = ts->buf_time.tv_sec * 1000 +
			ts->buf_time.tv_usec / 1000;
			ts->buf_time.tv_usec / 1000;
	}
	}
	spin_unlock(&vfe_dev->common_data->common_dev_data_lock);
	spin_unlock_irqrestore(&vfe_dev->common_data->common_dev_data_lock,
		flags);
}
}


void msm_isp_notify(struct vfe_device *vfe_dev, uint32_t event_type,
void msm_isp_notify(struct vfe_device *vfe_dev, uint32_t event_type,
@@ -742,6 +746,26 @@ void msm_isp_notify(struct vfe_device *vfe_dev, uint32_t event_type,
	switch (event_type) {
	switch (event_type) {
	case ISP_EVENT_SOF:
	case ISP_EVENT_SOF:
		if (frame_src == VFE_PIX_0) {
		if (frame_src == VFE_PIX_0) {
			/* Frame id is incremented in CAMIF SOF. Event is sent
			 * in EPOCH. If by this time, both VFE dont have same
			 * frame_id, then we have scheduling issues or some
			 * other s/w issue */
			if (vfe_dev->is_split &&
				vfe_dev->common_data->dual_vfe_res->
					axi_data[0]->
					src_info[VFE_PIX_0].frame_id !=
				vfe_dev->common_data->dual_vfe_res->
					axi_data[1]->
					src_info[VFE_PIX_0].frame_id) {
				pr_err_ratelimited("%s: Error! 2 VFE out of sync vfe0 frame_id %u vfe1 %u\n",
					__func__,
					vfe_dev->common_data->dual_vfe_res->
						axi_data[0]->
						src_info[VFE_PIX_0].frame_id,
					vfe_dev->common_data->dual_vfe_res->
						axi_data[1]->
						src_info[VFE_PIX_0].frame_id);
			}
			if (vfe_dev->isp_sof_debug < ISP_SOF_DEBUG_COUNT)
			if (vfe_dev->isp_sof_debug < ISP_SOF_DEBUG_COUNT)
				pr_err("%s: PIX0 frame id: %u\n", __func__,
				pr_err("%s: PIX0 frame id: %u\n", __func__,
				vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id);
				vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id);
@@ -2152,6 +2176,7 @@ static int msm_isp_update_dual_HW_ms_info_at_start(
	struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
	struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
	struct msm_vfe_src_info *src_info = NULL;
	struct msm_vfe_src_info *src_info = NULL;
	uint32_t vfe_id = 0;
	uint32_t vfe_id = 0;
	unsigned long flags;


	if (stream_src >= VFE_SRC_MAX) {
	if (stream_src >= VFE_SRC_MAX) {
		pr_err("%s: Error! Invalid src %u\n", __func__, stream_src);
		pr_err("%s: Error! Invalid src %u\n", __func__, stream_src);
@@ -2162,23 +2187,29 @@ static int msm_isp_update_dual_HW_ms_info_at_start(
	if (src_info->dual_hw_type != DUAL_HW_MASTER_SLAVE)
	if (src_info->dual_hw_type != DUAL_HW_MASTER_SLAVE)
		return rc;
		return rc;


	spin_lock_irqsave(&vfe_dev->common_data->common_dev_data_lock, flags);
	if (src_info->dual_hw_ms_info.dual_hw_ms_type ==
	if (src_info->dual_hw_ms_info.dual_hw_ms_type ==
		MS_TYPE_MASTER) {
		MS_TYPE_MASTER) {
		spin_lock(&vfe_dev->common_data->common_dev_data_lock);
		if (vfe_dev->common_data->ms_resource.master_active == 1) {
			spin_unlock_irqrestore(&vfe_dev->common_data->
				common_dev_data_lock, flags);
			return rc;
		}

		vfe_dev->common_data->ms_resource.master_active = 1;
		vfe_dev->common_data->ms_resource.master_active = 1;
		spin_unlock(&vfe_dev->common_data->common_dev_data_lock);


		/*
		/*
		 * If any slaves are active, then find the max slave
		 * If any slaves are active, then find the max slave
		 * frame_id and set it to Master, so master will start
		 * frame_id and set it to Master, so master will start
		 * higher and then the slave can copy master frame_id
		 * higher and then the slave can copy master frame_id
		 * without repeating.
		 * without repeating.
		 * For safety, add some buffer, currently 5.
		 */
		 */
		if (!vfe_dev->common_data->ms_resource.slave_active_mask)
		if (!vfe_dev->common_data->ms_resource.slave_active_mask) {
			spin_unlock_irqrestore(&vfe_dev->common_data->
				common_dev_data_lock, flags);
			return rc;
			return rc;
		}


		spin_lock(&vfe_dev->common_data->common_dev_data_lock);
		for (j = 0, k = 0; k < MS_NUM_SLAVE_MAX; k++) {
		for (j = 0, k = 0; k < MS_NUM_SLAVE_MAX; k++) {
			if (!(vfe_dev->common_data->ms_resource.
			if (!(vfe_dev->common_data->ms_resource.
				reserved_slave_mask & (1 << k)))
				reserved_slave_mask & (1 << k)))
@@ -2203,19 +2234,18 @@ static int msm_isp_update_dual_HW_ms_info_at_start(
			vfe_dev->common_data->dual_vfe_res->axi_data[vfe_id]->
			vfe_dev->common_data->dual_vfe_res->axi_data[vfe_id]->
				src_info[stream_src].frame_id = max_sof + 1;
				src_info[stream_src].frame_id = max_sof + 1;
		}
		}
		spin_unlock(&vfe_dev->common_data->common_dev_data_lock);


		ISP_DBG("%s: Setting Master frame_id to %u\n", __func__,
		ISP_DBG("%s: Setting Master frame_id to %u\n", __func__,
			max_sof + 1);
			max_sof + 1);
	} else {
	} else {
		spin_lock(&vfe_dev->common_data->common_dev_data_lock);
		if (src_info->dual_hw_ms_info.sof_info != NULL) {
		if (src_info->dual_hw_ms_info.sof_info != NULL) {
			slave_id = src_info->dual_hw_ms_info.slave_id;
			slave_id = src_info->dual_hw_ms_info.slave_id;
			vfe_dev->common_data->ms_resource.slave_active_mask |=
			vfe_dev->common_data->ms_resource.slave_active_mask |=
				(1 << slave_id);
				(1 << slave_id);
		}
		}
		spin_unlock(&vfe_dev->common_data->common_dev_data_lock);
	}
	}
	spin_unlock_irqrestore(&vfe_dev->common_data->common_dev_data_lock,
		flags);


	return rc;
	return rc;
}
}
+11 −11
Original line number Original line Diff line number Diff line
@@ -701,19 +701,16 @@ static int msm_isp_set_dual_HW_master_slave_mode(
	dual_hw_ms_cmd = (struct msm_isp_set_dual_hw_ms_cmd *)arg;
	dual_hw_ms_cmd = (struct msm_isp_set_dual_hw_ms_cmd *)arg;
	vfe_dev->common_data->ms_resource.dual_hw_type = DUAL_HW_MASTER_SLAVE;
	vfe_dev->common_data->ms_resource.dual_hw_type = DUAL_HW_MASTER_SLAVE;
	vfe_dev->vfe_ub_policy = MSM_WM_UB_EQUAL_SLICING;
	vfe_dev->vfe_ub_policy = MSM_WM_UB_EQUAL_SLICING;
	if (dual_hw_ms_cmd->primary_intf >= VFE_SRC_MAX) {
	if (dual_hw_ms_cmd->primary_intf < VFE_SRC_MAX) {
		pr_err("%s: Error! Invalid SRC param %d\n", __func__,
		src_info = &vfe_dev->axi_data.
			dual_hw_ms_cmd->primary_intf);
			src_info[dual_hw_ms_cmd->primary_intf];
		return -EINVAL;
	}

	src_info = &vfe_dev->axi_data.src_info[dual_hw_ms_cmd->primary_intf];

		src_info->dual_hw_ms_info.dual_hw_ms_type =
		src_info->dual_hw_ms_info.dual_hw_ms_type =
			dual_hw_ms_cmd->dual_hw_ms_type;
			dual_hw_ms_cmd->dual_hw_ms_type;
	}


	/* No lock needed here since ioctl lock protects 2 session from race */
	/* No lock needed here since ioctl lock protects 2 session from race */
	if (dual_hw_ms_cmd->dual_hw_ms_type == MS_TYPE_MASTER) {
	if (src_info != NULL &&
		dual_hw_ms_cmd->dual_hw_ms_type == MS_TYPE_MASTER) {
		src_info->dual_hw_type = DUAL_HW_MASTER_SLAVE;
		src_info->dual_hw_type = DUAL_HW_MASTER_SLAVE;
		ISP_DBG("%s: Master\n", __func__);
		ISP_DBG("%s: Master\n", __func__);


@@ -721,7 +718,7 @@ static int msm_isp_set_dual_HW_master_slave_mode(
			&vfe_dev->common_data->ms_resource.master_sof_info;
			&vfe_dev->common_data->ms_resource.master_sof_info;
		vfe_dev->common_data->ms_resource.sof_delta_threshold =
		vfe_dev->common_data->ms_resource.sof_delta_threshold =
			dual_hw_ms_cmd->sof_delta_threshold;
			dual_hw_ms_cmd->sof_delta_threshold;
	} else {
	} else if (src_info != NULL) {
		spin_lock(&vfe_dev->common_data->common_dev_data_lock);
		spin_lock(&vfe_dev->common_data->common_dev_data_lock);
		src_info->dual_hw_type = DUAL_HW_MASTER_SLAVE;
		src_info->dual_hw_type = DUAL_HW_MASTER_SLAVE;
		ISP_DBG("%s: Slave\n", __func__);
		ISP_DBG("%s: Slave\n", __func__);
@@ -750,6 +747,9 @@ static int msm_isp_set_dual_HW_master_slave_mode(
		}
		}
	}
	}
	ISP_DBG("%s: num_src %d\n", __func__, dual_hw_ms_cmd->num_src);
	ISP_DBG("%s: num_src %d\n", __func__, dual_hw_ms_cmd->num_src);
	/* This for loop is for non-primary intf to be marked with Master/Slave
	 * in order for frame id sync. But their timestamp is not saved.
	 * So no sof_info resource is allocated */
	for (i = 0; i < dual_hw_ms_cmd->num_src; i++) {
	for (i = 0; i < dual_hw_ms_cmd->num_src; i++) {
		if (dual_hw_ms_cmd->input_src[i] >= VFE_SRC_MAX) {
		if (dual_hw_ms_cmd->input_src[i] >= VFE_SRC_MAX) {
			pr_err("%s: Error! Invalid SRC param %d\n", __func__,
			pr_err("%s: Error! Invalid SRC param %d\n", __func__,