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

Commit e1b54da6 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: Add support for more than one buffer per HW stream"

parents 95625d9f a048a234
Loading
Loading
Loading
Loading
+16 −4
Original line number Diff line number Diff line
@@ -286,6 +286,14 @@ enum msm_vfe_axi_stream_type {
	BURST_STREAM,
};

struct msm_vfe_frame_request_queue {
	struct list_head list;
	enum msm_vfe_buff_queue_id buff_queue_id;
	uint8_t cmd_used;
};

#define MSM_VFE_REQUESTQ_SIZE 8

struct msm_vfe_axi_stream {
	uint32_t frame_id;
	enum msm_vfe_axi_state state;
@@ -298,11 +306,15 @@ struct msm_vfe_axi_stream {
	struct msm_isp_buffer *buf[2];
	uint32_t session_id;
	uint32_t stream_id;
	uint32_t bufq_handle;
	uint32_t bufq_scratch_handle;
	uint32_t controllable_output;
	uint32_t bufq_handle[VFE_BUF_QUEUE_MAX];
	uint8_t controllable_output;
	uint8_t undelivered_request_cnt;
	uint8_t request_q_idx;
	uint32_t request_q_cnt;
	struct list_head request_q;
	struct msm_vfe_frame_request_queue
			request_queue_cmd[MSM_VFE_REQUESTQ_SIZE];
	uint32_t stream_handle;
	uint32_t request_frm_num;
	uint8_t buf_divert;
	enum msm_vfe_axi_stream_type stream_type;
	uint32_t vt_enable;
+244 −230
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ int msm_isp_axi_create_stream(
		stream_cfg_cmd->controllable_output;
	if (stream_cfg_cmd->controllable_output)
		stream_cfg_cmd->frame_skip_pattern = SKIP_ALL;
	INIT_LIST_HEAD(&axi_data->stream_info[i].request_q);
	return 0;
}

@@ -348,49 +349,6 @@ void msm_isp_axi_free_comp_mask(struct msm_vfe_axi_shared_data *axi_data,
	axi_data->num_used_composite_mask--;
}

int msm_isp_axi_get_bufq_handles(
		struct vfe_device *vfe_dev,
		struct msm_vfe_axi_stream *stream_info)
{
	int rc = 0;

	if (stream_info->stream_id & ISP_SCRATCH_BUF_BIT) {
		stream_info->bufq_handle =
			vfe_dev->buf_mgr->ops->get_bufq_handle(
		vfe_dev->buf_mgr, stream_info->session_id,
		stream_info->stream_id & ~ISP_SCRATCH_BUF_BIT);
		if (stream_info->bufq_handle == 0) {
			pr_err("%s: Stream 0x%x has no valid buffer queue\n",
				__func__, (unsigned int)stream_info->stream_id);
			rc = -EINVAL;
			return rc;
		}

		stream_info->bufq_scratch_handle =
			vfe_dev->buf_mgr->ops->get_bufq_handle(
		vfe_dev->buf_mgr, stream_info->session_id,
		stream_info->stream_id);
		if (stream_info->bufq_scratch_handle == 0) {
			pr_err("%s: Stream 0x%x has no valid buffer queue\n",
				__func__, (unsigned int)stream_info->stream_id);
			rc = -EINVAL;
			return rc;
		}
	} else {
		stream_info->bufq_handle =
			vfe_dev->buf_mgr->ops->get_bufq_handle(
		vfe_dev->buf_mgr, stream_info->session_id,
		stream_info->stream_id);
		if (stream_info->bufq_handle == 0) {
			pr_err("%s: Stream 0x%x has no valid buffer queue\n",
				__func__, (unsigned int)stream_info->stream_id);
			rc = -EINVAL;
			return rc;
		}
	}
	return rc;
}

int msm_isp_axi_check_stream_state(
	struct vfe_device *vfe_dev,
	struct msm_vfe_axi_stream_cfg_cmd *stream_cfg_cmd)
@@ -431,12 +389,6 @@ int msm_isp_axi_check_stream_state(
			}
		}
		spin_unlock_irqrestore(&stream_info->lock, flags);

		if (stream_cfg_cmd->cmd == START_STREAM) {
			rc = msm_isp_axi_get_bufq_handles(vfe_dev, stream_info);
			if (rc)
				break;
		}
	}
	return rc;
}
@@ -950,17 +902,18 @@ static void msm_isp_get_done_buf(struct vfe_device *vfe_dev,

	if (stream_info->controllable_output) {
		stream_info->buf[pingpong_bit] = NULL;
		stream_info->request_frm_num--;
		stream_info->undelivered_request_cnt--;
	}
}

static int msm_isp_cfg_ping_pong_address(struct vfe_device *vfe_dev,
	struct msm_vfe_axi_stream *stream_info, uint32_t pingpong_status,
	uint32_t pingpong_bit)
	struct msm_vfe_axi_stream *stream_info, uint32_t pingpong_status)
{
	int i, rc = -1;
	struct msm_isp_buffer *buf = NULL;
	uint32_t bufq_handle = 0;
	struct msm_vfe_frame_request_queue *queue_req;
	uint32_t pingpong_bit;
	uint32_t stream_idx = HANDLE_TO_IDX(stream_info->stream_handle);

	if (stream_idx >= MAX_NUM_STREAM) {
@@ -968,17 +921,29 @@ static int msm_isp_cfg_ping_pong_address(struct vfe_device *vfe_dev,
		return rc;
	}

	if (stream_info->controllable_output && !stream_info->request_frm_num)
	if (!stream_info->controllable_output) {
		bufq_handle = stream_info->bufq_handle[VFE_BUF_QUEUE_DEFAULT];
	} else {
		queue_req = list_first_entry_or_null(&stream_info->request_q,
			struct msm_vfe_frame_request_queue, list);
		if (!queue_req)
			return 0;

	bufq_handle = stream_info->bufq_handle;
	if (SRC_TO_INTF(stream_info->stream_src) < VFE_SRC_MAX)
		queue_req->cmd_used = 0;
		bufq_handle = stream_info->
			bufq_handle[queue_req->buff_queue_id];
		list_del(&queue_req->list);
		stream_info->request_q_cnt--;

		if (!bufq_handle) {
			pr_err("%s: Drop request. Shared stream is stopped.\n",
				__func__);
			return -EINVAL;
		}
	}

	rc = vfe_dev->buf_mgr->ops->get_buf(vfe_dev->buf_mgr,
			vfe_dev->pdev->id, bufq_handle, &buf);
	else {
		pr_err("%s: Invalid stream index\n", __func__);
		rc = -1;
	}

	if (rc < 0) {
		vfe_dev->error_info.stream_framedrop_count[stream_idx]++;
@@ -997,6 +962,7 @@ static int msm_isp_cfg_ping_pong_address(struct vfe_device *vfe_dev,
			pingpong_status, buf->mapped_info[i].paddr +
			stream_info->plane_cfg[i].plane_addr_offset);

	pingpong_bit = (~(pingpong_status >> stream_info->wm[0]) & 0x1);
	stream_info->buf[pingpong_bit] = buf;

	return 0;
@@ -1018,10 +984,7 @@ static void msm_isp_process_done_buf(struct vfe_device *vfe_dev,
	uint32_t buf_src;
	memset(&buf_event, 0, sizeof(buf_event));

	if (SRC_TO_INTF(stream_info->stream_src) < VFE_SRC_MAX)
		frame_id = vfe_dev->axi_data.
			src_info[SRC_TO_INTF(stream_info->stream_src)].frame_id;
	else {
	if (SRC_TO_INTF(stream_info->stream_src) >= VFE_SRC_MAX) {
		pr_err("%s: Invalid stream index, put buf back to vb2 queue\n",
			__func__);
		vfe_dev->buf_mgr->ops->put_buf(vfe_dev->buf_mgr,
@@ -1029,13 +992,18 @@ static void msm_isp_process_done_buf(struct vfe_device *vfe_dev,
		return;
	}

	if (buf && ts) {
	if (!buf || !ts)
		return;

	frame_id = vfe_dev->axi_data.
		src_info[SRC_TO_INTF(stream_info->stream_src)].frame_id;

	if (vfe_dev->vt_enable) {
		msm_isp_get_avtimer_ts(ts);
		time_stamp = &ts->vt_time;
		}
		else
	} else {
		time_stamp = &ts->buf_time;
	}

	rc = vfe_dev->buf_mgr->ops->get_buf_src(vfe_dev->buf_mgr,
					buf->bufq_handle, &buf_src);
@@ -1048,44 +1016,34 @@ static void msm_isp_process_done_buf(struct vfe_device *vfe_dev,
		 * can be diverted. A positive return value means
		 * other ISP hardware is still processing the frame.
		 */
			if (rc == 0) {
				buf_event.input_intf =
					SRC_TO_INTF(stream_info->stream_src);
		if (rc)
			return;

		buf_event.input_intf = SRC_TO_INTF(stream_info->stream_src);
		buf_event.frame_id = frame_id;
		buf_event.timestamp = *time_stamp;
				buf_event.u.buf_done.session_id =
					stream_info->session_id;
				buf_event.u.buf_done.stream_id =
					stream_info->stream_id;
				buf_event.u.buf_done.handle =
					stream_info->bufq_handle;
		buf_event.u.buf_done.session_id = stream_info->session_id;
		buf_event.u.buf_done.stream_id = stream_info->stream_id;
		buf_event.u.buf_done.handle = buf->bufq_handle;
		buf_event.u.buf_done.buf_idx = buf->buf_idx;
		buf_event.u.buf_done.output_format =
			stream_info->runtime_output_format;
				msm_isp_send_event(vfe_dev,
					ISP_EVENT_BUF_DIVERT + stream_idx,
		msm_isp_send_event(vfe_dev, ISP_EVENT_BUF_DIVERT + stream_idx,
			&buf_event);
			}
	} else {
			buf_event.input_intf =
				SRC_TO_INTF(stream_info->stream_src);
		buf_event.input_intf = SRC_TO_INTF(stream_info->stream_src);
		buf_event.frame_id = frame_id;
		buf_event.timestamp = ts->buf_time;
			buf_event.u.buf_done.session_id =
				stream_info->session_id;
			buf_event.u.buf_done.stream_id =
				stream_info->stream_id;
		buf_event.u.buf_done.session_id = stream_info->session_id;
		buf_event.u.buf_done.stream_id = stream_info->stream_id;
		buf_event.u.buf_done.output_format =
			stream_info->runtime_output_format;
			msm_isp_send_event(vfe_dev,
				ISP_EVENT_BUF_DONE, &buf_event);
		msm_isp_send_event(vfe_dev, ISP_EVENT_BUF_DONE, &buf_event);
		vfe_dev->buf_mgr->ops->buf_done(vfe_dev->buf_mgr,
				buf->bufq_handle, buf->buf_idx,
				time_stamp, frame_id,
			buf->bufq_handle, buf->buf_idx, time_stamp, frame_id,
			stream_info->runtime_output_format);
	}
}
}

static enum msm_isp_camif_update_state
	msm_isp_get_camif_update_state(struct vfe_device *vfe_dev,
@@ -1229,7 +1187,7 @@ static int msm_isp_init_stream_ping_pong_reg(
	int rc = 0;
	/*Set address for both PING & PONG register */
	rc = msm_isp_cfg_ping_pong_address(vfe_dev,
		stream_info, VFE_PING_FLAG, 0);
		stream_info, VFE_PING_FLAG);
	if (rc < 0) {
		pr_err("%s: No free buffer for ping\n",
			   __func__);
@@ -1245,7 +1203,7 @@ static int msm_isp_init_stream_ping_pong_reg(
		msm_isp_cfg_pong_address(vfe_dev, stream_info);
	} else {
		rc = msm_isp_cfg_ping_pong_address(vfe_dev,
			stream_info, VFE_PONG_FLAG, 1);
			stream_info, VFE_PONG_FLAG);
		if (rc < 0) {
			pr_err("%s: No free buffer for pong\n",
				   __func__);
@@ -1312,6 +1270,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;
	struct msm_isp_bufq *bufq = NULL;
	uint32_t bufq_handle = 0, bufq_id = 0;

	if (!reset_cmd) {
		pr_err("%s: NULL pointer reset cmd %p\n", __func__, reset_cmd);
@@ -1336,11 +1295,16 @@ int msm_isp_axi_reset(struct vfe_device *vfe_dev,
			continue;
		}

		for (bufq_id = 0; bufq_id < VFE_BUF_QUEUE_MAX; bufq_id++) {
			bufq_handle = stream_info->bufq_handle[bufq_id];
			if (!bufq_handle)
				continue;

			bufq = vfe_dev->buf_mgr->ops->get_bufq(vfe_dev->buf_mgr,
			stream_info->bufq_handle);
				bufq_handle);
			if (!bufq) {
			pr_err("%s: bufq null %p by handle %x\n", __func__,
				bufq, stream_info->bufq_handle);
				pr_err("%s: bufq null %p by handle %x\n",
					__func__, bufq, bufq_handle);
				continue;
			}

@@ -1348,13 +1312,15 @@ int msm_isp_axi_reset(struct vfe_device *vfe_dev,
				msm_isp_deinit_stream_ping_pong_reg(vfe_dev,
					stream_info);
			} else {
			vfe_dev->buf_mgr->ops->flush_buf(vfe_dev->buf_mgr,
				stream_info->bufq_handle,
				vfe_dev->buf_mgr->ops->flush_buf(
					vfe_dev->buf_mgr, bufq_handle,
					MSM_ISP_BUFFER_FLUSH_ALL);
			}
		axi_data->src_info[SRC_TO_INTF(stream_info->stream_src)].
			frame_id = reset_cmd->frame_id;
		msm_isp_reset_burst_count_and_frame_drop(vfe_dev, stream_info);
			axi_data->src_info[SRC_TO_INTF(stream_info->
				stream_src)]. frame_id = reset_cmd->frame_id;
			msm_isp_reset_burst_count_and_frame_drop(vfe_dev,
				stream_info);
		}
	}

	if (rc < 0)
@@ -1633,81 +1599,122 @@ int msm_isp_cfg_axi_stream(struct vfe_device *vfe_dev, void *arg)
}

static int msm_isp_request_frame(struct vfe_device *vfe_dev,
	struct msm_vfe_axi_stream *stream_info, uint32_t request_frm_num)
	struct msm_vfe_axi_stream *stream_info, uint32_t user_stream_id)
{
	struct msm_vfe_axi_stream_request_cmd stream_cfg_cmd;
	struct msm_vfe_frame_request_queue *queue_req;
	uint32_t pingpong_status, wm_reload_mask = 0x0;
	unsigned long flags;
	int rc = 0;
	uint32_t pingpong_status, pingpong_bit, wm_reload_mask = 0x0;

	if (!stream_info->controllable_output)
		return 0;

	if (!request_frm_num) {
		pr_err("%s: Invalid frame request.\n", __func__);
	spin_lock_irqsave(&stream_info->lock, flags);
	queue_req = &stream_info->request_queue_cmd[stream_info->request_q_idx];
	if (queue_req->cmd_used) {
		spin_unlock_irqrestore(&stream_info->lock, flags);
		pr_err_ratelimited("%s: Request queue overflow.\n", __func__);
		return -EINVAL;
	}

	stream_info->request_frm_num += request_frm_num;
	if (user_stream_id == stream_info->stream_id)
		queue_req->buff_queue_id = VFE_BUF_QUEUE_DEFAULT;
	else
		queue_req->buff_queue_id = VFE_BUF_QUEUE_SHARED;

	if (!stream_info->bufq_handle[queue_req->buff_queue_id]) {
		spin_unlock_irqrestore(&stream_info->lock, flags);
		pr_err("%s:%d stream is stoped\n", __func__, __LINE__);
		return 0;
	}
	queue_req->cmd_used = 1;

	stream_info->request_q_idx =
		(stream_info->request_q_idx + 1) % MSM_VFE_REQUESTQ_SIZE;
	list_add_tail(&queue_req->list, &stream_info->request_q);
	stream_info->request_q_cnt++;

	stream_info->undelivered_request_cnt++;

	stream_cfg_cmd.axi_stream_handle = stream_info->stream_handle;
	stream_cfg_cmd.frame_skip_pattern = NO_SKIP;
	stream_cfg_cmd.init_frame_drop = 0;
	stream_cfg_cmd.burst_count = stream_info->request_frm_num;
	stream_cfg_cmd.burst_count = stream_info->request_q_cnt;
	msm_isp_calculate_framedrop(&vfe_dev->axi_data, &stream_cfg_cmd);
	msm_isp_reset_framedrop(vfe_dev, stream_info);

	if (stream_info->request_frm_num != request_frm_num) {
		pingpong_status =
			vfe_dev->hw_info->vfe_ops.axi_ops.get_pingpong_status(
				vfe_dev);
		pingpong_bit = (~(pingpong_status >> stream_info->wm[0]) & 0x1);

		if (!stream_info->buf[pingpong_bit]) {
	if (stream_info->undelivered_request_cnt == 1) {
		rc = msm_isp_cfg_ping_pong_address(vfe_dev, stream_info,
				pingpong_status, pingpong_bit);
			VFE_PING_FLAG);
		if (rc) {
			spin_unlock_irqrestore(&stream_info->lock, flags);
			pr_err("%s:%d fail to set ping pong address\n",
				__func__, __LINE__);
			return rc;
		}
		}

		if (!stream_info->buf[!pingpong_bit] && request_frm_num > 1) {
		msm_isp_get_stream_wm_mask(stream_info, &wm_reload_mask);
		vfe_dev->hw_info->vfe_ops.axi_ops.reload_wm(vfe_dev,
			wm_reload_mask);
	} else if (stream_info->undelivered_request_cnt == 2) {
		pingpong_status =
			vfe_dev->hw_info->vfe_ops.axi_ops.get_pingpong_status(
				vfe_dev);

		rc = msm_isp_cfg_ping_pong_address(vfe_dev, stream_info,
				~pingpong_status, !pingpong_bit);
			pingpong_status);
		if (rc) {
			spin_unlock_irqrestore(&stream_info->lock, flags);
			pr_err("%s:%d fail to set ping pong address\n",
				__func__, __LINE__);
			return rc;
		}
	}
	} else {
		if (!stream_info->buf[0]) {
			rc = msm_isp_cfg_ping_pong_address(vfe_dev, stream_info,
				VFE_PING_FLAG, 0);
			if (rc) {
				pr_err("%s:%d fail to set ping pong address\n",
					__func__, __LINE__);

	spin_unlock_irqrestore(&stream_info->lock, flags);

	return rc;
}

static int msm_isp_add_buf_queue(struct vfe_device *vfe_dev,
	struct msm_vfe_axi_stream *stream_info, uint32_t stream_id)
{
	int rc = 0;
	uint32_t bufq_id = 0;

	if (stream_id == stream_info->stream_id)
		bufq_id = VFE_BUF_QUEUE_DEFAULT;
	else
		bufq_id = VFE_BUF_QUEUE_SHARED;

	stream_info->bufq_handle[bufq_id] =
		vfe_dev->buf_mgr->ops->get_bufq_handle(vfe_dev->buf_mgr,
			stream_info->session_id, stream_id);
	if (stream_info->bufq_handle[bufq_id] == 0) {
		pr_err("%s: failed: No valid buffer queue for stream: 0x%x\n",
			__func__, stream_id);
		rc = -EINVAL;
	}

		if (!stream_info->buf[1] && request_frm_num > 1) {
			rc = msm_isp_cfg_ping_pong_address(vfe_dev, stream_info,
				VFE_PONG_FLAG, 1);
			if (rc) {
				pr_err("%s:%d fail to set ping pong address\n",
					__func__, __LINE__);
	return rc;
}
		}

		msm_isp_get_stream_wm_mask(stream_info, &wm_reload_mask);
		vfe_dev->hw_info->vfe_ops.axi_ops.reload_wm(vfe_dev,
			wm_reload_mask);
	}
static void msm_isp_remove_buf_queue(struct vfe_device *vfe_dev,
	struct msm_vfe_axi_stream *stream_info, uint32_t stream_id)
{
	uint32_t bufq_id = 0;
	unsigned long flags;

	if (stream_id == stream_info->stream_id)
		bufq_id = VFE_BUF_QUEUE_DEFAULT;
	else
		bufq_id = VFE_BUF_QUEUE_SHARED;

	spin_lock_irqsave(&stream_info->lock, flags);
	stream_info->bufq_handle[bufq_id] = 0;
	spin_unlock_irqrestore(&stream_info->lock, flags);

	return rc;
}

int msm_isp_update_axi_stream(struct vfe_device *vfe_dev, void *arg)
@@ -1756,7 +1763,7 @@ int msm_isp_update_axi_stream(struct vfe_device *vfe_dev, void *arg)
		case DISABLE_STREAM_BUF_DIVERT:
			stream_info->buf_divert = 0;
			vfe_dev->buf_mgr->ops->flush_buf(vfe_dev->buf_mgr,
					stream_info->bufq_handle,
				stream_info->bufq_handle[VFE_BUF_QUEUE_DEFAULT],
				MSM_ISP_BUFFER_FLUSH_DIVERTED);
			break;
		case UPDATE_STREAM_FRAMEDROP_PATTERN: {
@@ -1801,12 +1808,29 @@ int msm_isp_update_axi_stream(struct vfe_device *vfe_dev, void *arg)
		}
		case UPDATE_STREAM_REQUEST_FRAMES: {
			rc = msm_isp_request_frame(vfe_dev, stream_info,
				update_info->request_frm_num);
				update_info->user_stream_id);
			if (rc)
				pr_err("%s failed to request frame!\n",
					__func__);
			break;
		}
		case UPDATE_STREAM_ADD_BUFQ: {
			rc = msm_isp_add_buf_queue(vfe_dev, stream_info,
				update_info->user_stream_id);
			if (rc)
				pr_err("%s failed to add bufq!\n", __func__);
			break;
		}
		case UPDATE_STREAM_REMOVE_BUFQ: {
			msm_isp_remove_buf_queue(vfe_dev, stream_info,
				update_info->user_stream_id);

			rc = msm_isp_axi_wait_for_cfg_done(vfe_dev, NO_UPDATE);
			if (rc < 0)
				pr_err("%s: wait for config done failed\n",
					__func__);
			break;
		}
		default:
			pr_err("%s: Invalid update type\n", __func__);
			return -EINVAL;
@@ -1826,7 +1850,7 @@ void msm_isp_process_axi_irq(struct vfe_device *vfe_dev,
	struct msm_vfe_axi_stream *stream_info;
	struct msm_vfe_axi_composite_info *comp_info;
	struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
	uint32_t pingpong_bit = 0;
	unsigned long flags;

	comp_mask = vfe_dev->hw_info->vfe_ops.axi_ops.
		get_comp_mask(irq_status0, irq_status1);
@@ -1842,45 +1866,37 @@ void msm_isp_process_axi_irq(struct vfe_device *vfe_dev,
	for (i = 0; i < axi_data->hw_info->num_comp_mask; i++) {
		rc = 0;
		comp_info = &axi_data->composite_info[i];
		wm_mask &= ~(comp_info->stream_composite_mask);
		if (comp_mask & (1 << i)) {
			if (!comp_info->stream_handle) {
				pr_err("%s: Invalid handle for composite irq\n",
					__func__);
			} else {
				stream_idx =
					HANDLE_TO_IDX(comp_info->stream_handle);
				stream_info =
					&axi_data->stream_info[stream_idx];
				ISP_DBG("%s: stream id %x frame id: 0x%x\n",
					__func__, stream_info->stream_id,
					stream_info->frame_id);
				continue;
			}
			stream_idx = HANDLE_TO_IDX(comp_info->stream_handle);
			stream_info = &axi_data->stream_info[stream_idx];
			ISP_DBG("%s: stream id %x frame id: 0x%x\n", __func__,
				stream_info->stream_id, stream_info->frame_id);
			stream_info->frame_id++;

				pingpong_bit = (~(pingpong_status >>
					stream_info->wm[0]) & 0x1);

			if (stream_info->stream_type == BURST_STREAM)
					stream_info->
						runtime_num_burst_capture--;
				stream_info->runtime_num_burst_capture--;

			spin_lock_irqsave(&stream_info->lock, flags);
			msm_isp_get_done_buf(vfe_dev, stream_info,
				pingpong_status, &done_buf);
				if (stream_info->stream_type ==
					CONTINUOUS_STREAM ||
					stream_info->
					runtime_num_burst_capture > 1) {
					rc = msm_isp_cfg_ping_pong_address(
							vfe_dev, stream_info,
							pingpong_status,
							pingpong_bit);
			if (stream_info->stream_type == CONTINUOUS_STREAM ||
				stream_info->runtime_num_burst_capture > 1) {
				rc = msm_isp_cfg_ping_pong_address(vfe_dev,
					stream_info, pingpong_status);
			}
			spin_unlock_irqrestore(&stream_info->lock, flags);

			if (done_buf && !rc)
					msm_isp_process_done_buf(vfe_dev,
					stream_info, done_buf, ts);
				msm_isp_process_done_buf(vfe_dev, stream_info,
					done_buf, ts);
		}
	}
		wm_mask &= ~(comp_info->stream_composite_mask);
	}

	for (i = 0; i < axi_data->hw_info->num_wm; i++) {
		if (wm_mask & (1 << i)) {
@@ -1891,25 +1907,23 @@ void msm_isp_process_axi_irq(struct vfe_device *vfe_dev,
			}
			stream_idx = HANDLE_TO_IDX(axi_data->free_wm[i]);
			stream_info = &axi_data->stream_info[stream_idx];
			ISP_DBG("%s: stream id %x frame id: 0x%x\n",
				__func__,
			ISP_DBG("%s: stream id %x frame id: 0x%x\n", __func__,
				stream_info->stream_id, stream_info->frame_id);
			stream_info->frame_id++;

			pingpong_bit = (~(pingpong_status >>
				stream_info->wm[0]) & 0x1);

			if (stream_info->stream_type == BURST_STREAM)
				stream_info->runtime_num_burst_capture--;

			spin_lock_irqsave(&stream_info->lock, flags);
			msm_isp_get_done_buf(vfe_dev, stream_info,
						pingpong_status, &done_buf);
			if (stream_info->stream_type == CONTINUOUS_STREAM ||
				stream_info->runtime_num_burst_capture > 1) {
				rc = msm_isp_cfg_ping_pong_address(vfe_dev,
					stream_info, pingpong_status,
					pingpong_bit);
					stream_info, pingpong_status);
			}
			spin_unlock_irqrestore(&stream_info->lock, flags);

			if (done_buf && !rc)
				msm_isp_process_done_buf(vfe_dev,
				stream_info, done_buf, ts);
+9 −1
Original line number Diff line number Diff line
@@ -221,6 +221,8 @@ enum msm_vfe_axi_stream_update_type {
	UPDATE_STREAM_STATS_FRAMEDROP_PATTERN,
	UPDATE_STREAM_AXI_CONFIG,
	UPDATE_STREAM_REQUEST_FRAMES,
	UPDATE_STREAM_ADD_BUFQ,
	UPDATE_STREAM_REMOVE_BUFQ,
};

enum msm_vfe_iommu_type {
@@ -228,10 +230,16 @@ enum msm_vfe_iommu_type {
	IOMMU_DETACH,
};

enum msm_vfe_buff_queue_id {
	VFE_BUF_QUEUE_DEFAULT,
	VFE_BUF_QUEUE_SHARED,
	VFE_BUF_QUEUE_MAX,
};

struct msm_vfe_axi_stream_cfg_update_info {
	uint32_t stream_handle;
	uint32_t output_format;
	uint32_t request_frm_num;
	uint32_t user_stream_id;
	enum msm_vfe_frame_skip_pattern skip_pattern;
	struct msm_vfe_axi_plane_cfg plane_cfg[MAX_PLANES_PER_STREAM];
};