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

Commit b7636c9d authored by Harsh Shah's avatar Harsh Shah Committed by Jing Zhou
Browse files

msm: camera: isp: Track put_buf per VFE



Update bit mask per VFE for put_buf instead of only count. In flush buf
update put buf mask first and put buffer if put_mask is same as get_mask

Change-Id: I8b128094e4ae62e5676a46e6a4624e4933234266
Signed-off-by: default avatarHarsh Shah <harshs@codeaurora.org>
Signed-off-by: default avatarJing Zhou <jzhou70@codeaurora.org>
parent fc6278f0
Loading
Loading
Loading
Loading
+42 −20
Original line number Diff line number Diff line
@@ -545,8 +545,8 @@ static int msm_isp_get_buf(struct msm_isp_buf_mgr *buf_mgr, uint32_t id,
		list_count = 0;
		list_for_each_entry(temp_buf_info,
			&bufq->share_head, share_list) {
			if (!temp_buf_info->buf_used[id]) {
				temp_buf_info->buf_used[id] = 1;
			if ((temp_buf_info->get_buf_mask & (1 << id)) == 0) {
				temp_buf_info->get_buf_mask |= (1 << id);
				temp_buf_info->buf_get_count++;
				*buf_cnt = temp_buf_info->buf_get_count;
				if (temp_buf_info->buf_get_count ==
@@ -564,7 +564,7 @@ static int msm_isp_get_buf(struct msm_isp_buf_mgr *buf_mgr, uint32_t id,
				spin_unlock_irqrestore(
					&bufq->bufq_lock, flags);
				return rc;
			} else if (temp_buf_info->buf_used[id] &&
			} else if ((temp_buf_info->get_buf_mask & (1 << id)) &&
				temp_buf_info->buf_reuse_flag) {
				spin_unlock_irqrestore(
					&bufq->bufq_lock, flags);
@@ -648,7 +648,7 @@ static int msm_isp_get_buf(struct msm_isp_buf_mgr *buf_mgr, uint32_t id,
				sizeof(struct msm_isp_buffer), GFP_ATOMIC);
			if (temp_buf_info) {
				temp_buf_info->buf_reuse_flag = 1;
				temp_buf_info->buf_used[id] = 1;
				temp_buf_info->get_buf_mask |= (1 << id);
				temp_buf_info->buf_get_count = 1;
				list_add_tail(&temp_buf_info->share_list,
					&bufq->share_head);
@@ -680,11 +680,10 @@ static int msm_isp_get_buf(struct msm_isp_buf_mgr *buf_mgr, uint32_t id,
					return -EFAULT;
				}
			}
			memset((*buf_info)->buf_used, 0,
				   sizeof(uint8_t) * bufq->buf_client_count);
			(*buf_info)->buf_used[id] = 1;
			(*buf_info)->get_buf_mask = (1 << id);
			(*buf_info)->buf_get_count = 1;
			(*buf_info)->buf_put_count = 0;
			(*buf_info)->put_buf_mask = 0;
			(*buf_info)->buf_reuse_flag = 0;
			if (!list_empty(&(*buf_info)->share_list)) {
				spin_unlock_irqrestore(&bufq->bufq_lock, flags);
@@ -795,7 +794,8 @@ static int msm_isp_put_buf(struct msm_isp_buf_mgr *buf_mgr,

	buf_info->buf_get_count = 0;
	buf_info->buf_put_count = 0;
	memset(buf_info->buf_used, 0, sizeof(buf_info->buf_used));
	buf_info->get_buf_mask = 0;
	buf_info->put_buf_mask = 0;

	rc = msm_isp_put_buf_unsafe(buf_mgr, bufq_handle, buf_index);

@@ -804,15 +804,15 @@ static int msm_isp_put_buf(struct msm_isp_buf_mgr *buf_mgr,
	return rc;
}

static int msm_isp_update_put_buf_cnt(struct msm_isp_buf_mgr *buf_mgr,
	uint32_t bufq_handle, uint32_t buf_index, struct timeval *tv,
	uint32_t frame_id)
static int msm_isp_update_put_buf_cnt_unsafe(
	struct msm_isp_buf_mgr *buf_mgr,
	uint32_t id, uint32_t bufq_handle, uint32_t buf_index,
	struct timeval *tv, uint32_t frame_id, unsigned long *flags)
{
	int rc = -1;
	struct msm_isp_bufq *bufq = NULL;
	struct msm_isp_buffer *buf_info = NULL;
	enum msm_isp_buffer_state state;
	unsigned long flags;

	bufq = msm_isp_get_bufq(buf_mgr, bufq_handle);
	if (!bufq) {
@@ -826,27 +826,28 @@ static int msm_isp_update_put_buf_cnt(struct msm_isp_buf_mgr *buf_mgr,
		return rc;
	}

	spin_lock_irqsave(&bufq->bufq_lock, flags);
	if (bufq->buf_type != ISP_SHARE_BUF ||
		buf_info->buf_put_count == 0) {
		buf_info->put_buf_mask == 0) {
		buf_info->frame_id = frame_id;
	}

	state = buf_info->state;
	if (state == MSM_ISP_BUFFER_STATE_DEQUEUED) {
		if (bufq->buf_type == ISP_SHARE_BUF) {
		if (bufq->buf_type == ISP_SHARE_BUF &&
			((buf_info->put_buf_mask & (1 << id)) == 0)) {
			buf_info->put_buf_mask |= (1 << id);
			buf_info->buf_put_count++;
			if (buf_info->buf_put_count != ISP_SHARE_BUF_CLIENT) {
				rc = buf_info->buf_put_count;
				spin_unlock_irqrestore(&bufq->bufq_lock, flags);
				return rc;
			}
		}
	} else {
		pr_warn("%s: Invalid state, stream id %x, state %d\n", __func__,
			bufq->stream_id, state);
		spin_unlock_irqrestore(&bufq->bufq_lock, flags);
		spin_unlock_irqrestore(&bufq->bufq_lock, *flags);
		dump_stack();
		spin_lock_irqsave(&bufq->bufq_lock, *flags);
		return rc;
	}

@@ -854,10 +855,30 @@ static int msm_isp_update_put_buf_cnt(struct msm_isp_buf_mgr *buf_mgr,
		buf_info->state = MSM_ISP_BUFFER_STATE_DIVERTED;
		buf_info->tv = tv;
	}
	spin_unlock_irqrestore(&bufq->bufq_lock, flags);
	return 0;
}

static int msm_isp_update_put_buf_cnt(struct msm_isp_buf_mgr *buf_mgr,
	uint32_t id, uint32_t bufq_handle, uint32_t buf_index,
	struct timeval *tv, uint32_t frame_id)
{
	int rc = -1;
	struct msm_isp_bufq *bufq = NULL;
	unsigned long flags;

	bufq = msm_isp_get_bufq(buf_mgr, bufq_handle);
	if (!bufq) {
		pr_err("Invalid bufq\n");
		return rc;
	}

	spin_lock_irqsave(&bufq->bufq_lock, flags);
	rc = msm_isp_update_put_buf_cnt_unsafe(buf_mgr, id, bufq_handle,
		buf_index, tv, frame_id, &flags);
	spin_unlock_irqrestore(&bufq->bufq_lock, flags);
	return rc;
}

static int msm_isp_buf_done(struct msm_isp_buf_mgr *buf_mgr,
	uint32_t bufq_handle, uint32_t buf_index,
	struct timeval *tv, uint32_t frame_id, uint32_t output_format)
@@ -915,8 +936,9 @@ done:
	return rc;
}

static int msm_isp_flush_buf(struct msm_isp_buf_mgr *buf_mgr,
		uint32_t bufq_handle, enum msm_isp_buffer_flush_t flush_type)
static int msm_isp_flush_buf(struct msm_isp_buf_mgr *buf_mgr, uint32_t id,
	uint32_t bufq_handle, enum msm_isp_buffer_flush_t flush_type,
	struct timeval *tv, uint32_t frame_id)
{
	int rc = -1, i;
	struct msm_isp_bufq *bufq = NULL;
+7 −6
Original line number Diff line number Diff line
@@ -101,7 +101,8 @@ struct msm_isp_buffer {

	/*Share buffer cache state*/
	struct list_head share_list;
	uint8_t buf_used[ISP_SHARE_BUF_CLIENT];
	uint8_t get_buf_mask;
	uint8_t put_buf_mask;
	uint8_t buf_get_count;
	uint8_t buf_put_count;
	uint8_t buf_reuse_flag;
@@ -158,8 +159,9 @@ struct msm_isp_buf_ops {
	int (*put_buf)(struct msm_isp_buf_mgr *buf_mgr,
		uint32_t bufq_handle, uint32_t buf_index);

	int (*flush_buf)(struct msm_isp_buf_mgr *buf_mgr,
		uint32_t bufq_handle, enum msm_isp_buffer_flush_t flush_type);
	int (*flush_buf)(struct msm_isp_buf_mgr *buf_mgr, uint32_t id,
	uint32_t bufq_handle, enum msm_isp_buffer_flush_t flush_type,
	struct timeval *tv, uint32_t frame_id);

	int (*buf_done)(struct msm_isp_buf_mgr *buf_mgr,
		uint32_t bufq_handle, uint32_t buf_index,
@@ -175,9 +177,8 @@ struct msm_isp_buf_ops {
	struct msm_isp_bufq * (*get_bufq)(struct msm_isp_buf_mgr *buf_mgr,
		uint32_t bufq_handle);
	int (*update_put_buf_cnt)(struct msm_isp_buf_mgr *buf_mgr,
		uint32_t bufq_handle, uint32_t buf_index,
		struct timeval *tv,
		uint32_t frame_id);
		uint32_t id, uint32_t bufq_handle, uint32_t buf_index,
		struct timeval *tv, uint32_t frame_id);
};

struct msm_isp_buf_mgr {
+27 −10
Original line number Diff line number Diff line
@@ -791,7 +791,7 @@ void msm_isp_notify(struct vfe_device *vfe_dev, uint32_t event_type,
				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",
				pr_debug("%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]->
@@ -1735,7 +1735,8 @@ static void msm_isp_process_done_buf(struct vfe_device *vfe_dev,
	}

	rc = vfe_dev->buf_mgr->ops->update_put_buf_cnt(vfe_dev->buf_mgr,
			buf->bufq_handle, buf->buf_idx, time_stamp, frame_id);
		vfe_dev->pdev->id, buf->bufq_handle, buf->buf_idx,
		time_stamp, frame_id);

	/* Buf divert return value represent whether the buf
	 * can be diverted. A positive return value means
@@ -1898,7 +1899,8 @@ int msm_isp_drop_frame(struct vfe_device *vfe_dev,

	if (done_buf) {
		rc = vfe_dev->buf_mgr->ops->update_put_buf_cnt(vfe_dev->buf_mgr,
			done_buf->bufq_handle, done_buf->buf_idx, 0, frame_id);
			vfe_dev->pdev->id, done_buf->bufq_handle,
			done_buf->buf_idx, 0, frame_id);
		if (rc == 0) {
			done_buf->buf_debug.put_state[
				done_buf->buf_debug.put_state_last] =
@@ -2173,6 +2175,7 @@ int msm_isp_axi_reset(struct vfe_device *vfe_dev,
	struct msm_vfe_axi_stream *stream_info;
	struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
	uint32_t bufq_handle = 0, bufq_id = 0;
	struct msm_isp_timestamp timestamp;

	if (!reset_cmd) {
		pr_err("%s: NULL pointer reset cmd %p\n", __func__, reset_cmd);
@@ -2183,6 +2186,8 @@ int msm_isp_axi_reset(struct vfe_device *vfe_dev,
	rc = vfe_dev->hw_info->vfe_ops.core_ops.reset_hw(vfe_dev,
		0, reset_cmd->blocking);

	msm_isp_get_timestamp(&timestamp);

	for (i = 0, j = 0; j < axi_data->num_active_stream &&
		i < VFE_AXI_SRC_MAX; i++, j++) {
		stream_info = &axi_data->stream_info[i];
@@ -2203,8 +2208,9 @@ int msm_isp_axi_reset(struct vfe_device *vfe_dev,
				continue;

			rc = vfe_dev->buf_mgr->ops->flush_buf(
				vfe_dev->buf_mgr, bufq_handle,
				MSM_ISP_BUFFER_FLUSH_ALL);
				vfe_dev->buf_mgr, vfe_dev->pdev->id,
				bufq_handle, MSM_ISP_BUFFER_FLUSH_ALL,
				&timestamp.buf_time, reset_cmd->frame_id);
			if (rc == -EFAULT) {
				msm_isp_halt_send_error(vfe_dev,
					ISP_EVENT_BUF_FATAL_ERROR);
@@ -2553,11 +2559,14 @@ static int msm_isp_stop_axi_stream(struct vfe_device *vfe_dev,
		(axi_data->src_info[VFE_PIX_0].input_mux == EXTERNAL_READ);
	uint32_t src_mask = 0, intf, bufq_id = 0, bufq_handle = 0;
	unsigned long flags;
	struct msm_isp_timestamp timestamp;

	if (stream_cfg_cmd->num_streams > MAX_NUM_STREAM ||
		stream_cfg_cmd->num_streams == 0)
		return -EINVAL;

	msm_isp_get_timestamp(&timestamp);

	for (i = 0; i < stream_cfg_cmd->num_streams; i++) {
		if (HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i]) >=
			VFE_AXI_SRC_MAX) {
@@ -2700,8 +2709,9 @@ static int msm_isp_stop_axi_stream(struct vfe_device *vfe_dev,
				continue;

			rc = vfe_dev->buf_mgr->ops->flush_buf(
				vfe_dev->buf_mgr, bufq_handle,
				MSM_ISP_BUFFER_FLUSH_ALL);
				vfe_dev->buf_mgr, vfe_dev->pdev->id,
				bufq_handle, MSM_ISP_BUFFER_FLUSH_ALL,
				&timestamp.buf_time, 0);
			if (rc == -EFAULT) {
				msm_isp_halt_send_error(vfe_dev,
					ISP_EVENT_BUF_FATAL_ERROR);
@@ -2822,7 +2832,7 @@ static int msm_isp_return_empty_buffer(struct vfe_device *vfe_dev,

	msm_isp_get_timestamp(&timestamp);
	rc = vfe_dev->buf_mgr->ops->update_put_buf_cnt(vfe_dev->buf_mgr,
		buf->bufq_handle, buf->buf_idx, 0, frame_id);
		vfe_dev->pdev->id, buf->bufq_handle, buf->buf_idx, 0, frame_id);
	if (rc == 0) {
		buf->buf_debug.put_state[buf->buf_debug.put_state_last] =
			MSM_ISP_BUFFER_STATE_DROP_REG;
@@ -3066,6 +3076,8 @@ int msm_isp_update_axi_stream(struct vfe_device *vfe_dev, void *arg)
	struct msm_vfe_axi_stream_cfg_update_info *update_info;
	struct msm_isp_sw_framskip *sw_skip_info = NULL;
	unsigned long flags;
	struct msm_isp_timestamp timestamp;
	uint32_t frame_id;

	/*num_stream is uint32 and update_info[] bound by MAX_NUM_STREAM*/
	if (update_cmd->num_streams > MAX_NUM_STREAM)
@@ -3114,9 +3126,14 @@ int msm_isp_update_axi_stream(struct vfe_device *vfe_dev, void *arg)
			break;
		case DISABLE_STREAM_BUF_DIVERT:
			stream_info->buf_divert = 0;
			msm_isp_get_timestamp(&timestamp);
			frame_id = vfe_dev->axi_data.src_info[
				SRC_TO_INTF(stream_info->stream_src)].frame_id;
			rc = vfe_dev->buf_mgr->ops->flush_buf(vfe_dev->buf_mgr,
				vfe_dev->pdev->id,
				stream_info->bufq_handle[VFE_BUF_QUEUE_DEFAULT],
				MSM_ISP_BUFFER_FLUSH_DIVERTED);
				MSM_ISP_BUFFER_FLUSH_DIVERTED,
				&timestamp.buf_time, frame_id);
			if (rc == -EFAULT) {
				msm_isp_halt_send_error(vfe_dev,
					ISP_EVENT_BUF_FATAL_ERROR);
+14 −5
Original line number Diff line number Diff line
@@ -140,7 +140,7 @@ static int32_t msm_isp_stats_buf_divert(struct vfe_device *vfe_dev,
	}

	rc = vfe_dev->buf_mgr->ops->update_put_buf_cnt(
		vfe_dev->buf_mgr, done_buf->bufq_handle,
		vfe_dev->buf_mgr, vfe_dev->pdev->id, done_buf->bufq_handle,
		done_buf->buf_idx, &ts->buf_time,
		frame_id);
	if (rc != 0) {
@@ -568,6 +568,9 @@ int msm_isp_stats_reset(struct vfe_device *vfe_dev)
	int i = 0, rc = 0;
	struct msm_vfe_stats_stream *stream_info = NULL;
	struct msm_vfe_stats_shared_data *stats_data = &vfe_dev->stats_data;
	struct msm_isp_timestamp timestamp;

	msm_isp_get_timestamp(&timestamp);

	for (i = 0; i < MSM_ISP_STATS_MAX; i++) {
		stream_info = &stats_data->stream_info[i];
@@ -575,8 +578,9 @@ int msm_isp_stats_reset(struct vfe_device *vfe_dev)
			continue;

		rc = vfe_dev->buf_mgr->ops->flush_buf(vfe_dev->buf_mgr,
			stream_info->bufq_handle,
			MSM_ISP_BUFFER_FLUSH_ALL);
			vfe_dev->pdev->id, stream_info->bufq_handle,
			MSM_ISP_BUFFER_FLUSH_ALL, &timestamp.buf_time,
			vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id);
		if (rc == -EFAULT) {
			msm_isp_halt_send_error(vfe_dev,
				ISP_EVENT_BUF_FATAL_ERROR);
@@ -688,6 +692,10 @@ static int msm_isp_stop_stats_stream(struct vfe_device *vfe_dev,
	uint32_t num_stats_comp_mask = 0;
	struct msm_vfe_stats_stream *stream_info;
	struct msm_vfe_stats_shared_data *stats_data = &vfe_dev->stats_data;
	struct msm_isp_timestamp timestamp;

	msm_isp_get_timestamp(&timestamp);

	num_stats_comp_mask =
		vfe_dev->hw_info->stats_hw_info->num_stats_comp_mask;

@@ -754,8 +762,9 @@ static int msm_isp_stop_stats_stream(struct vfe_device *vfe_dev,

		stream_info = &stats_data->stream_info[idx];
		rc = vfe_dev->buf_mgr->ops->flush_buf(vfe_dev->buf_mgr,
			stream_info->bufq_handle,
			MSM_ISP_BUFFER_FLUSH_ALL);
			vfe_dev->pdev->id, stream_info->bufq_handle,
			MSM_ISP_BUFFER_FLUSH_ALL, &timestamp.buf_time,
			vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id);
		if (rc == -EFAULT) {
			msm_isp_halt_send_error(vfe_dev,
				ISP_EVENT_BUF_FATAL_ERROR);