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

Commit 62bcdd9d authored by Lokesh Kumar Aakulu's avatar Lokesh Kumar Aakulu Committed by Ramesh V
Browse files

msm: camera_v2: Fix page fault issue in camera ISP



Fix page fault in ISP when there is no reg update
for two consecutive request frame time.

Change-Id: Ie246f146c1ec0785e0e6fa0671dd2ff28fbe6b38
Signed-off-by: default avatarLokesh Kumar Aakulu <lkumar@codeaurora.org>
parent c60fdaf3
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -424,6 +424,12 @@ enum msm_isp_comp_irq_types {

#define MSM_VFE_REQUESTQ_SIZE 8

struct msm_isp_pending_buf_info {
	uint32_t is_buf_done_pending;
	struct msm_isp_buffer *buf;
	uint32_t frame_id;
};

struct msm_vfe_axi_stream {
	uint32_t frame_id;
	enum msm_vfe_axi_state state;
@@ -480,6 +486,7 @@ struct msm_vfe_axi_stream {
	uint32_t vfe_mask;
	uint32_t composite_irq[MSM_ISP_COMP_IRQ_MAX];
	int lpm_mode;
	struct msm_isp_pending_buf_info pending_buf_info;
};

struct msm_vfe_axi_composite_info {
+65 −3
Original line number Diff line number Diff line
@@ -30,6 +30,13 @@ static void __msm_isp_axi_stream_update(
			struct msm_vfe_axi_stream *stream_info,
			struct msm_isp_timestamp *ts);

static int msm_isp_process_done_buf(struct vfe_device *vfe_dev,
	struct msm_vfe_axi_stream *stream_info, struct msm_isp_buffer *buf,
	struct timeval *time_stamp, uint32_t frame_id);
static void msm_isp_free_pending_buffer(
	struct vfe_device *vfe_dev,
	struct msm_vfe_axi_stream *stream_info,
	struct msm_isp_timestamp *ts);
static int msm_isp_update_stream_bandwidth(
		struct msm_vfe_axi_stream *stream_info, int enable);

@@ -670,6 +677,10 @@ void msm_isp_process_reg_upd_epoch_irq(struct vfe_device *vfe_dev,
		case MSM_ISP_COMP_IRQ_REG_UPD:
			stream_info->activated_framedrop_period =
				stream_info->requested_framedrop_period;
			/* Free Pending Buffers which are backed-up due to
			 * delay in RUP from userspace to Avoid pageFault
			 */
			msm_isp_free_pending_buffer(vfe_dev, stream_info, ts);
			__msm_isp_axi_stream_update(stream_info, ts);
			break;
		case MSM_ISP_COMP_IRQ_EPOCH:
@@ -1572,6 +1583,40 @@ static void msm_isp_axi_stream_enable_cfg(
	}
}

static void msm_isp_free_pending_buffer(
			struct vfe_device *vfe_dev,
			struct msm_vfe_axi_stream *stream_info,
			struct msm_isp_timestamp *ts)
{
	struct timeval *time_stamp;
	struct msm_isp_buffer *done_buf = NULL;
	uint32_t frame_id;
	int rc;

	if (!stream_info->controllable_output ||
		!stream_info->pending_buf_info.is_buf_done_pending)	{
		return;
	}

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

	done_buf = stream_info->pending_buf_info.buf;
	frame_id = stream_info->pending_buf_info.frame_id;
	if (done_buf) {
		rc = msm_isp_process_done_buf(vfe_dev, stream_info,
			done_buf, time_stamp, frame_id);
		if (rc == 0) {
			stream_info->pending_buf_info.buf = NULL;
			stream_info->pending_buf_info.is_buf_done_pending = 0;
		}
	}
}

static void __msm_isp_axi_stream_update(
			struct msm_vfe_axi_stream *stream_info,
			struct msm_isp_timestamp *ts)
@@ -2094,7 +2139,6 @@ static int msm_isp_process_done_buf(struct vfe_device *vfe_dev,
	uint32_t buf_src;
	uint8_t drop_frame = 0;
	struct msm_isp_bufq *bufq = NULL;

	memset(&buf_event, 0, sizeof(buf_event));

	if (stream_idx >= VFE_AXI_SRC_MAX) {
@@ -3050,6 +3094,12 @@ static void __msm_isp_stop_axi_streams(struct vfe_device *vfe_dev,
		msm_isp_cfg_stream_scratch(stream_info, VFE_PONG_FLAG);
		stream_info->undelivered_request_cnt = 0;
		vfe_dev->irq_sof_id = 0;
		if (stream_info->controllable_output &&
			stream_info->pending_buf_info.is_buf_done_pending) {
			msm_isp_free_pending_buffer(vfe_dev, stream_info,
				&timestamp);
			stream_info->pending_buf_info.is_buf_done_pending = 0;
		}
		for (k = 0; k < stream_info->num_isp; k++) {
			vfe_dev = stream_info->vfe_dev[k];
			if (stream_info->num_planes > 1)
@@ -4390,11 +4440,23 @@ void msm_isp_process_axi_irq_stream(struct vfe_device *vfe_dev,
		}
		spin_unlock_irqrestore(&stream_info->lock, flags);
	} else {
		/* If there is no regupdate from userspace then dont
		 * free buffer immediately, delegate it to RegUpdateAck
		 */
		if (stream_info->controllable_output &&
			!(vfe_dev->reg_update_requested &
				BIT((uint32_t)VFE_PIX_0))) {
			stream_info->pending_buf_info.is_buf_done_pending = 1;
			stream_info->pending_buf_info.buf = done_buf;
			stream_info->pending_buf_info.frame_id = frame_id;
		}
		spin_unlock_irqrestore(&stream_info->lock, flags);
		if (stream_info->pending_buf_info.is_buf_done_pending != 1) {
			msm_isp_process_done_buf(vfe_dev, stream_info,
				done_buf, time_stamp, frame_id);
		}
	}
}

void msm_isp_process_axi_irq(struct vfe_device *vfe_dev,
	uint32_t irq_status0, uint32_t irq_status1, uint32_t dual_irq_status,