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

Commit 7be50345 authored by Senthil kumar Rajagopal's avatar Senthil kumar Rajagopal Committed by Gerrit - the friendly Code Review server
Browse files

msm: camera: isp: Frameid mismatch recovery



If 2 vfe write different frames to same buffer, it causes split.
Add frame id to buf to detect such errors and trigger recovery in
that case.
Also remove prints from process_error_info() and send the framedrop
info as piggyback in SOF event.

Change-Id: I353bf8c5b5df0dbb2f1e973d53f36e8cb23fb1b6
Signed-off-by: default avatarSenthil Kumar Rajagopal <skrajago@codeaurora.org>
Signed-off-by: default avatarHarsh Shah <harshs@codeaurora.org>
parent 4e258b6d
Loading
Loading
Loading
Loading
+20 −17
Original line number Diff line number Diff line
@@ -270,8 +270,9 @@ static int msm_isp_buf_prepare(struct msm_isp_buf_mgr *buf_mgr,
	}

	if (buf_info->state != MSM_ISP_BUFFER_STATE_INITIALIZED) {
		pr_err("%s: Invalid buffer state: %d\n",
			__func__, buf_info->state);
		pr_err("%s: Invalid buffer state: %d bufq %x buf-id %d\n",
			__func__, buf_info->state, bufq->bufq_handle,
			buf_info->buf_idx);
		spin_unlock_irqrestore(&bufq->bufq_lock, flags);
		return rc;
	}
@@ -680,10 +681,9 @@ static int msm_isp_put_buf_unsafe(struct msm_isp_buf_mgr *buf_mgr,
}

static int msm_isp_update_put_buf_cnt(struct msm_isp_buf_mgr *buf_mgr,
	uint32_t bufq_handle, uint32_t buf_index)
	uint32_t bufq_handle, uint32_t buf_index, uint32_t frame_id)
{
	int rc = -1;
	unsigned long flags;
	struct msm_isp_bufq *bufq = NULL;
	struct msm_isp_buffer *buf_info = NULL;
	enum msm_isp_buffer_state state;
@@ -700,22 +700,23 @@ static int msm_isp_update_put_buf_cnt(struct msm_isp_buf_mgr *buf_mgr,
		return rc;
	}

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

	state = buf_info->state;
	if (state == MSM_ISP_BUFFER_STATE_DEQUEUED ||
		state == MSM_ISP_BUFFER_STATE_DIVERTED) {
		spin_lock_irqsave(&bufq->bufq_lock, flags);
		if (bufq->buf_type == ISP_SHARE_BUF) {
			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;
			}
		}
		spin_unlock_irqrestore(&bufq->bufq_lock, flags);
	} else {
		pr_warn("%s: Invalid state\n", __func__);
	}

	return 0;
@@ -829,7 +830,6 @@ static int msm_isp_buf_divert(struct msm_isp_buf_mgr *buf_mgr,
	struct timeval *tv, uint32_t frame_id)
{
	int rc = -1;
	unsigned long flags;
	struct msm_isp_bufq *bufq = NULL;
	struct msm_isp_buffer *buf_info = NULL;

@@ -845,12 +845,15 @@ static int msm_isp_buf_divert(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->frame_id = frame_id;
	}

	if (bufq->buf_type == ISP_SHARE_BUF) {
		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;
		}
	}
@@ -858,9 +861,7 @@ static int msm_isp_buf_divert(struct msm_isp_buf_mgr *buf_mgr,
	if (buf_info->state == MSM_ISP_BUFFER_STATE_DEQUEUED) {
		buf_info->state = MSM_ISP_BUFFER_STATE_DIVERTED;
		buf_info->tv = tv;
		buf_info->frame_id = frame_id;
	}
	spin_unlock_irqrestore(&bufq->bufq_lock, flags);

	return 0;
}
@@ -1025,6 +1026,7 @@ static int msm_isp_request_bufq(struct msm_isp_buf_mgr *buf_mgr,
		bufq->bufs[i].state = MSM_ISP_BUFFER_STATE_INITIALIZED;
		bufq->bufs[i].bufq_handle = bufq->bufq_handle;
		bufq->bufs[i].buf_idx = i;
		spin_lock_init(&bufq->bufs[i].lock);
	}

	return 0;
@@ -1220,6 +1222,7 @@ static int msm_isp_init_isp_buf_mgr(
	buf_mgr->client = msm_ion_client_create(ctx_name);
	buf_mgr->buf_handle_cnt = 0;
	buf_mgr->pagefault_debug = 0;
	buf_mgr->frameId_mismatch_recovery = 0;
	mutex_unlock(&buf_mgr->lock);
	return 0;
bufq_error:
@@ -1281,7 +1284,7 @@ static int msm_isp_buf_mgr_debug(struct msm_isp_buf_mgr *buf_mgr)
	struct msm_isp_buffer *bufs = NULL;
	uint32_t i = 0, j = 0, k = 0, rc = 0;
	char *print_buf = NULL, temp_buf[512];
	uint32_t start_addr = 0, end_addr = 0, print_buf_size = 1024;
	uint32_t start_addr = 0, end_addr = 0, print_buf_size = 2500;
	if (!buf_mgr) {
		pr_err_ratelimited("%s: %d] NULL buf_mgr\n",
			__func__, __LINE__);
@@ -1296,7 +1299,7 @@ static int msm_isp_buf_mgr_debug(struct msm_isp_buf_mgr *buf_mgr)
	for (i = 0; i < BUF_MGR_NUM_BUF_Q; i++) {
		if (buf_mgr->bufq[i].bufq_handle != 0) {
			snprintf(temp_buf, sizeof(temp_buf),
				"handle %x stream %x num_bufs %d",
				"handle %x stream %x num_bufs %d\n",
				buf_mgr->bufq[i].bufq_handle,
				buf_mgr->bufq[i].stream_id,
				buf_mgr->bufq[i].num_bufs);
+4 −1
Original line number Diff line number Diff line
@@ -83,6 +83,7 @@ struct msm_isp_buffer {

	/*Vb2 buffer data*/
	struct vb2_buffer *vb2_buf;
	spinlock_t lock;

	/*Share buffer cache state*/
	struct list_head share_list;
@@ -156,13 +157,15 @@ 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);
		uint32_t bufq_handle, uint32_t buf_index,
		uint32_t frame_id);
};

struct msm_isp_buf_mgr {
	int init_done;
	uint32_t open_count;
	uint32_t pagefault_debug;
	uint32_t frameId_mismatch_recovery;
	uint16_t num_buf_q;
	struct msm_isp_bufq *bufq;

+0 −11
Original line number Diff line number Diff line
@@ -348,16 +348,6 @@ void msm_isp_update_req_history(uint32_t client, uint64_t ab,
}

#ifdef CONFIG_COMPAT
struct msm_isp_event_data32 {
	struct compat_timeval timestamp;
	struct compat_timeval mono_timestamp;
	enum msm_vfe_input_src input_intf;
	uint32_t frame_id;
	union {
		struct msm_isp_stats_event stats;
		struct msm_isp_buf_event buf_done;
	} u;
};
static long msm_isp_dqevent(struct file *file, struct v4l2_fh *vfh, void *arg)
{
	long rc;
@@ -389,7 +379,6 @@ static long msm_isp_dqevent(struct file *file, struct v4l2_fh *vfh, void *arg)
				event_data->mono_timestamp.tv_sec;
		event_data32->mono_timestamp.tv_usec =
				event_data->mono_timestamp.tv_usec;
		event_data32->input_intf = event_data->input_intf;
		event_data32->frame_id = event_data->frame_id;
		memcpy(&(event_data32->u), &(event_data->u),
					sizeof(event_data32->u));
+3 −2
Original line number Diff line number Diff line
@@ -479,10 +479,11 @@ struct msm_vfe_error_info {
	uint32_t error_mask1;
	uint32_t violation_status;
	uint32_t camif_status;
	uint32_t stream_framedrop_count[MAX_NUM_STREAM];
	uint32_t stats_framedrop_count[MSM_ISP_STATS_MAX];
	uint8_t stream_framedrop_count[MAX_NUM_STREAM];
	uint8_t stats_framedrop_count[MSM_ISP_STATS_MAX];
	uint32_t info_dump_frame_count;
	uint32_t error_count;
	uint32_t framedrop_flag;
};

struct msm_isp_statistics {
+1 −0
Original line number Diff line number Diff line
@@ -1446,6 +1446,7 @@ static int msm_vfe46_axi_restart(struct vfe_device *vfe_dev,
	msm_camera_io_w(0x7FFFFFFF, vfe_dev->vfe_base + 0x64);
	msm_camera_io_w(0xFFFFFEFF, vfe_dev->vfe_base + 0x68);
	msm_camera_io_w(0x1, vfe_dev->vfe_base + 0x58);
	msm_camera_io_w_mb(0x20000, vfe_dev->vfe_base + 0x3CC);

	/* Start AXI */
	msm_camera_io_w(0x0, vfe_dev->vfe_base + 0x374);
Loading