msm: isp: update logic to reject invalid frame
Frame request should only be accepted between SOF and EOF, otherwise pingpong buffer will be switched before VFE configure the correct buffer, which causes pingpong mismatch. Rejecting all the request after EOF will make sure pingpong buffers are written correctly and hardware have enough time to be configured. Use a bool value to indicate if vfe is in correct region to accept frame request. Set this value at SOF irq and reset it at EOF irq. CRs-Fixed: 1108472 Change-Id: Ibc8689a07aaf508cd706e532f9e2e764da8b4c37 Signed-off-by: Junzhe Zou <jnzhezou@codeaurora.org>
This commit is contained in:
parent
6f55033ecf
commit
bce627fdfc
9 changed files with 57 additions and 17 deletions
|
@ -162,6 +162,8 @@ struct msm_vfe_irq_ops {
|
|||
void (*config_irq)(struct vfe_device *vfe_dev,
|
||||
uint32_t irq_status0, uint32_t irq_status1,
|
||||
enum msm_isp_irq_operation);
|
||||
void (*preprocess_camif_irq)(struct vfe_device *vfe_dev,
|
||||
uint32_t irq_status0);
|
||||
};
|
||||
|
||||
struct msm_vfe_axi_ops {
|
||||
|
@ -494,6 +496,7 @@ struct msm_vfe_src_info {
|
|||
struct timeval time_stamp;
|
||||
enum msm_vfe_dual_hw_type dual_hw_type;
|
||||
struct msm_vfe_dual_hw_ms_info dual_hw_ms_info;
|
||||
bool accept_frame;
|
||||
};
|
||||
|
||||
struct msm_vfe_fetch_engine_info {
|
||||
|
|
|
@ -2218,6 +2218,7 @@ struct msm_vfe_hardware_info vfe40_hw_info = {
|
|||
.process_stats_irq = msm_isp_process_stats_irq,
|
||||
.process_epoch_irq = msm_vfe40_process_epoch_irq,
|
||||
.config_irq = msm_vfe40_config_irq,
|
||||
.preprocess_camif_irq = msm_isp47_preprocess_camif_irq,
|
||||
},
|
||||
.axi_ops = {
|
||||
.reload_wm = msm_vfe40_axi_reload_wm,
|
||||
|
|
|
@ -1825,6 +1825,7 @@ struct msm_vfe_hardware_info vfe44_hw_info = {
|
|||
.process_stats_irq = msm_isp_process_stats_irq,
|
||||
.process_epoch_irq = msm_vfe44_process_epoch_irq,
|
||||
.config_irq = msm_vfe44_config_irq,
|
||||
.preprocess_camif_irq = msm_isp47_preprocess_camif_irq,
|
||||
},
|
||||
.axi_ops = {
|
||||
.reload_wm = msm_vfe44_axi_reload_wm,
|
||||
|
|
|
@ -1902,6 +1902,7 @@ struct msm_vfe_hardware_info vfe46_hw_info = {
|
|||
.process_stats_irq = msm_isp_process_stats_irq,
|
||||
.process_epoch_irq = msm_vfe46_process_epoch_irq,
|
||||
.config_irq = msm_vfe46_config_irq,
|
||||
.preprocess_camif_irq = msm_isp47_preprocess_camif_irq,
|
||||
},
|
||||
.axi_ops = {
|
||||
.reload_wm = msm_vfe46_axi_reload_wm,
|
||||
|
|
|
@ -685,6 +685,15 @@ void msm_vfe47_process_epoch_irq(struct vfe_device *vfe_dev,
|
|||
}
|
||||
}
|
||||
|
||||
void msm_isp47_preprocess_camif_irq(struct vfe_device *vfe_dev,
|
||||
uint32_t irq_status0)
|
||||
{
|
||||
if (irq_status0 & BIT(1))
|
||||
vfe_dev->axi_data.src_info[VFE_PIX_0].accept_frame = false;
|
||||
if (irq_status0 & BIT(0))
|
||||
vfe_dev->axi_data.src_info[VFE_PIX_0].accept_frame = true;
|
||||
}
|
||||
|
||||
void msm_vfe47_reg_update(struct vfe_device *vfe_dev,
|
||||
enum msm_vfe_input_src frame_src)
|
||||
{
|
||||
|
@ -2915,6 +2924,7 @@ struct msm_vfe_hardware_info vfe47_hw_info = {
|
|||
.process_epoch_irq = msm_vfe47_process_epoch_irq,
|
||||
.config_irq = msm_vfe47_config_irq,
|
||||
.read_irq_status = msm_vfe47_read_irq_status,
|
||||
.preprocess_camif_irq = msm_isp47_preprocess_camif_irq,
|
||||
},
|
||||
.axi_ops = {
|
||||
.reload_wm = msm_vfe47_axi_reload_wm,
|
||||
|
|
|
@ -42,6 +42,8 @@ void msm_vfe47_process_reg_update(struct vfe_device *vfe_dev,
|
|||
void msm_vfe47_process_epoch_irq(struct vfe_device *vfe_dev,
|
||||
uint32_t irq_status0, uint32_t irq_status1,
|
||||
struct msm_isp_timestamp *ts);
|
||||
void msm_isp47_preprocess_camif_irq(struct vfe_device *vfe_dev,
|
||||
uint32_t irq_status0);
|
||||
void msm_vfe47_reg_update(struct vfe_device *vfe_dev,
|
||||
enum msm_vfe_input_src frame_src);
|
||||
long msm_vfe47_reset_hardware(struct vfe_device *vfe_dev,
|
||||
|
|
|
@ -368,6 +368,7 @@ struct msm_vfe_hardware_info vfe48_hw_info = {
|
|||
.process_stats_irq = msm_isp_process_stats_irq,
|
||||
.process_epoch_irq = msm_vfe47_process_epoch_irq,
|
||||
.config_irq = msm_vfe47_config_irq,
|
||||
.preprocess_camif_irq = msm_isp47_preprocess_camif_irq,
|
||||
},
|
||||
.axi_ops = {
|
||||
.reload_wm = msm_vfe47_axi_reload_wm,
|
||||
|
|
|
@ -3339,27 +3339,40 @@ static int msm_isp_request_frame(struct vfe_device *vfe_dev,
|
|||
}
|
||||
|
||||
frame_src = SRC_TO_INTF(stream_info->stream_src);
|
||||
pingpong_status = vfe_dev->hw_info->
|
||||
vfe_ops.axi_ops.get_pingpong_status(vfe_dev);
|
||||
/*
|
||||
* If PIX stream is active then RDI path uses SOF frame ID of PIX
|
||||
* In case of standalone RDI streaming, SOF are used from
|
||||
* individual intf.
|
||||
*/
|
||||
if (((vfe_dev->axi_data.src_info[VFE_PIX_0].active) && (frame_id <=
|
||||
vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id)) ||
|
||||
((!vfe_dev->axi_data.src_info[VFE_PIX_0].active) && (frame_id <=
|
||||
vfe_dev->axi_data.src_info[frame_src].frame_id)) ||
|
||||
stream_info->undelivered_request_cnt >= MAX_BUFFERS_IN_HW) {
|
||||
pr_debug("%s:%d invalid request_frame %d cur frame id %d pix %d\n",
|
||||
/*
|
||||
* If frame_id = 1 then no eof check is needed
|
||||
*/
|
||||
if (vfe_dev->axi_data.src_info[VFE_PIX_0].active &&
|
||||
vfe_dev->axi_data.src_info[VFE_PIX_0].accept_frame == false) {
|
||||
pr_debug("%s:%d invalid time to request frame %d\n",
|
||||
__func__, __LINE__, frame_id);
|
||||
goto error;
|
||||
}
|
||||
if ((vfe_dev->axi_data.src_info[VFE_PIX_0].active && (frame_id !=
|
||||
vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id + vfe_dev->
|
||||
axi_data.src_info[VFE_PIX_0].sof_counter_step)) ||
|
||||
((!vfe_dev->axi_data.src_info[VFE_PIX_0].active) && (frame_id !=
|
||||
vfe_dev->axi_data.src_info[frame_src].frame_id + vfe_dev->
|
||||
axi_data.src_info[frame_src].sof_counter_step))) {
|
||||
pr_debug("%s:%d invalid frame id %d cur frame id %d pix %d\n",
|
||||
__func__, __LINE__, frame_id,
|
||||
vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id,
|
||||
vfe_dev->axi_data.src_info[VFE_PIX_0].active);
|
||||
|
||||
rc = msm_isp_return_empty_buffer(vfe_dev, stream_info,
|
||||
user_stream_id, frame_id, buf_index, frame_src);
|
||||
if (rc < 0)
|
||||
pr_err("%s:%d failed: return_empty_buffer src %d\n",
|
||||
__func__, __LINE__, frame_src);
|
||||
return 0;
|
||||
goto error;
|
||||
}
|
||||
if (stream_info->undelivered_request_cnt >= MAX_BUFFERS_IN_HW) {
|
||||
pr_debug("%s:%d invalid undelivered_request_cnt %d frame id %d\n",
|
||||
__func__, __LINE__,
|
||||
stream_info->undelivered_request_cnt,
|
||||
vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id);
|
||||
goto error;
|
||||
}
|
||||
if ((frame_src == VFE_PIX_0) && !stream_info->undelivered_request_cnt &&
|
||||
MSM_VFE_STREAM_STOP_PERIOD !=
|
||||
|
@ -3439,9 +3452,6 @@ static int msm_isp_request_frame(struct vfe_device *vfe_dev,
|
|||
}
|
||||
stream_info->sw_ping_pong_bit = 0;
|
||||
} 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(
|
||||
stream_info, pingpong_status);
|
||||
if (rc) {
|
||||
|
@ -3467,6 +3477,14 @@ static int msm_isp_request_frame(struct vfe_device *vfe_dev,
|
|||
spin_unlock_irqrestore(&stream_info->lock, flags);
|
||||
|
||||
return rc;
|
||||
error:
|
||||
rc = msm_isp_return_empty_buffer(vfe_dev, stream_info,
|
||||
user_stream_id, frame_id, buf_index, frame_src);
|
||||
if (rc < 0)
|
||||
pr_err("%s:%d failed: return_empty_buffer src %d\n",
|
||||
__func__, __LINE__, frame_src);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static int msm_isp_add_buf_queue(struct vfe_device *vfe_dev,
|
||||
|
|
|
@ -2092,7 +2092,10 @@ irqreturn_t msm_isp_process_irq(int irq_num, void *data)
|
|||
__func__, vfe_dev->pdev->id);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
if (vfe_dev->hw_info->vfe_ops.irq_ops.preprocess_camif_irq) {
|
||||
vfe_dev->hw_info->vfe_ops.irq_ops.preprocess_camif_irq(
|
||||
vfe_dev, irq_status0);
|
||||
}
|
||||
if (msm_isp_process_overflow_irq(vfe_dev,
|
||||
&irq_status0, &irq_status1, 0)) {
|
||||
/* if overflow initiated no need to handle the interrupts */
|
||||
|
|
Loading…
Add table
Reference in a new issue