msm: camera_v2: isp: handle frame drop in error case
when isp tasklet get delayed due to scheduling, recover pingpong mismatch from both isp and send back buffer to framework to avoid framedrop. Change-Id: If7357d7b2669f99eb45c364288f09954b9f0a710 Signed-off-by: Ramesh V <ramev@codeaurora.org> Signed-off-by: Sumalatha Malothu <smalot@codeaurora.org>
This commit is contained in:
parent
961798b123
commit
48b52acae3
1 changed files with 52 additions and 11 deletions
|
@ -2051,6 +2051,8 @@ static int msm_isp_cfg_ping_pong_address(
|
||||||
|
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
msm_isp_cfg_stream_scratch(stream_info, pingpong_status);
|
msm_isp_cfg_stream_scratch(stream_info, pingpong_status);
|
||||||
|
if (stream_info->controllable_output)
|
||||||
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2723,7 +2725,11 @@ int msm_isp_axi_reset(struct vfe_device *vfe_dev,
|
||||||
struct msm_isp_timestamp timestamp;
|
struct msm_isp_timestamp timestamp;
|
||||||
struct msm_vfe_frame_request_queue *queue_req;
|
struct msm_vfe_frame_request_queue *queue_req;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
uint32_t pingpong_status;
|
||||||
int vfe_idx;
|
int vfe_idx;
|
||||||
|
uint32_t pingpong_bit = 0;
|
||||||
|
uint32_t frame_id = 0;
|
||||||
|
struct timeval *time_stamp;
|
||||||
|
|
||||||
if (!reset_cmd) {
|
if (!reset_cmd) {
|
||||||
pr_err("%s: NULL pointer reset cmd %pK\n", __func__, reset_cmd);
|
pr_err("%s: NULL pointer reset cmd %pK\n", __func__, reset_cmd);
|
||||||
|
@ -2732,6 +2738,7 @@ int msm_isp_axi_reset(struct vfe_device *vfe_dev,
|
||||||
}
|
}
|
||||||
|
|
||||||
msm_isp_get_timestamp(×tamp, vfe_dev);
|
msm_isp_get_timestamp(×tamp, vfe_dev);
|
||||||
|
time_stamp = ×tamp.buf_time;
|
||||||
|
|
||||||
for (i = 0; i < VFE_AXI_SRC_MAX; i++) {
|
for (i = 0; i < VFE_AXI_SRC_MAX; i++) {
|
||||||
stream_info = msm_isp_get_stream_common_data(
|
stream_info = msm_isp_get_stream_common_data(
|
||||||
|
@ -2754,6 +2761,28 @@ int msm_isp_axi_reset(struct vfe_device *vfe_dev,
|
||||||
|
|
||||||
/* set ping pong to scratch before flush */
|
/* set ping pong to scratch before flush */
|
||||||
spin_lock_irqsave(&stream_info->lock, flags);
|
spin_lock_irqsave(&stream_info->lock, flags);
|
||||||
|
frame_id = vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id;
|
||||||
|
if (stream_info->controllable_output &&
|
||||||
|
stream_info->undelivered_request_cnt > 0) {
|
||||||
|
pingpong_status = VFE_PING_FLAG;
|
||||||
|
pingpong_bit = (~(pingpong_status >>
|
||||||
|
stream_info->wm[0][0]) & 0x1);
|
||||||
|
if (stream_info->buf[pingpong_bit] != NULL) {
|
||||||
|
msm_isp_process_done_buf(vfe_dev, stream_info,
|
||||||
|
stream_info->buf[pingpong_bit],
|
||||||
|
time_stamp,
|
||||||
|
frame_id);
|
||||||
|
}
|
||||||
|
pingpong_status = VFE_PONG_FLAG;
|
||||||
|
pingpong_bit = (~(pingpong_status >>
|
||||||
|
stream_info->wm[0][0]) & 0x1);
|
||||||
|
if (stream_info->buf[pingpong_bit] != NULL) {
|
||||||
|
msm_isp_process_done_buf(vfe_dev, stream_info,
|
||||||
|
stream_info->buf[pingpong_bit],
|
||||||
|
time_stamp,
|
||||||
|
frame_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
msm_isp_cfg_stream_scratch(stream_info,
|
msm_isp_cfg_stream_scratch(stream_info,
|
||||||
VFE_PING_FLAG);
|
VFE_PING_FLAG);
|
||||||
msm_isp_cfg_stream_scratch(stream_info,
|
msm_isp_cfg_stream_scratch(stream_info,
|
||||||
|
@ -3262,9 +3291,8 @@ static int msm_isp_start_axi_stream(struct vfe_device *vfe_dev_ioctl,
|
||||||
msm_isp_reset_framedrop(vfe_dev_ioctl, stream_info);
|
msm_isp_reset_framedrop(vfe_dev_ioctl, stream_info);
|
||||||
rc = msm_isp_init_stream_ping_pong_reg(stream_info);
|
rc = msm_isp_init_stream_ping_pong_reg(stream_info);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
pr_err("%s: No buffer for stream%d\n", __func__,
|
pr_err("%s: No buffer for stream%x\n", __func__,
|
||||||
HANDLE_TO_IDX(
|
stream_info->stream_id);
|
||||||
stream_cfg_cmd->stream_handle[i]));
|
|
||||||
spin_unlock_irqrestore(&stream_info->lock, flags);
|
spin_unlock_irqrestore(&stream_info->lock, flags);
|
||||||
mutex_unlock(&vfe_dev_ioctl->buf_mgr->lock);
|
mutex_unlock(&vfe_dev_ioctl->buf_mgr->lock);
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -3713,11 +3741,16 @@ static int msm_isp_request_frame(struct vfe_device *vfe_dev,
|
||||||
if (rc) {
|
if (rc) {
|
||||||
spin_unlock_irqrestore(&stream_info->lock, flags);
|
spin_unlock_irqrestore(&stream_info->lock, flags);
|
||||||
stream_info->undelivered_request_cnt--;
|
stream_info->undelivered_request_cnt--;
|
||||||
pr_err_ratelimited("%s:%d fail to cfg HAL buffer\n",
|
queue_req = list_first_entry_or_null(
|
||||||
__func__, __LINE__);
|
&stream_info->request_q,
|
||||||
queue_req->cmd_used = 0;
|
struct msm_vfe_frame_request_queue, list);
|
||||||
list_del(&queue_req->list);
|
if (queue_req) {
|
||||||
stream_info->request_q_cnt--;
|
queue_req->cmd_used = 0;
|
||||||
|
list_del(&queue_req->list);
|
||||||
|
stream_info->request_q_cnt--;
|
||||||
|
}
|
||||||
|
pr_err_ratelimited("%s:%d fail to cfg HAL buffer stream %x\n",
|
||||||
|
__func__, __LINE__, stream_info->stream_id);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3754,11 +3787,16 @@ static int msm_isp_request_frame(struct vfe_device *vfe_dev,
|
||||||
stream_info->undelivered_request_cnt--;
|
stream_info->undelivered_request_cnt--;
|
||||||
spin_unlock_irqrestore(&stream_info->lock,
|
spin_unlock_irqrestore(&stream_info->lock,
|
||||||
flags);
|
flags);
|
||||||
|
queue_req = list_first_entry_or_null(
|
||||||
|
&stream_info->request_q,
|
||||||
|
struct msm_vfe_frame_request_queue, list);
|
||||||
|
if (queue_req) {
|
||||||
|
queue_req->cmd_used = 0;
|
||||||
|
list_del(&queue_req->list);
|
||||||
|
stream_info->request_q_cnt--;
|
||||||
|
}
|
||||||
pr_err_ratelimited("%s:%d fail to cfg HAL buffer\n",
|
pr_err_ratelimited("%s:%d fail to cfg HAL buffer\n",
|
||||||
__func__, __LINE__);
|
__func__, __LINE__);
|
||||||
queue_req->cmd_used = 0;
|
|
||||||
list_del(&queue_req->list);
|
|
||||||
stream_info->request_q_cnt--;
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -4352,7 +4390,10 @@ void msm_isp_process_axi_irq_stream(struct vfe_device *vfe_dev,
|
||||||
|
|
||||||
frame_id_diff = vfe_dev->irq_sof_id - frame_id;
|
frame_id_diff = vfe_dev->irq_sof_id - frame_id;
|
||||||
if (stream_info->controllable_output && frame_id_diff > 1) {
|
if (stream_info->controllable_output && frame_id_diff > 1) {
|
||||||
|
pr_err_ratelimited("%s: scheduling problem do recovery irq_sof_id %d frame_id %d\n",
|
||||||
|
__func__, vfe_dev->irq_sof_id, frame_id);
|
||||||
/* scheduling problem need to do recovery */
|
/* scheduling problem need to do recovery */
|
||||||
|
stream_info->buf[pingpong_bit] = done_buf;
|
||||||
spin_unlock_irqrestore(&stream_info->lock, flags);
|
spin_unlock_irqrestore(&stream_info->lock, flags);
|
||||||
msm_isp_halt_send_error(vfe_dev,
|
msm_isp_halt_send_error(vfe_dev,
|
||||||
ISP_EVENT_PING_PONG_MISMATCH);
|
ISP_EVENT_PING_PONG_MISMATCH);
|
||||||
|
|
Loading…
Add table
Reference in a new issue