From bce627fdfc15e4fcd6fcbe978b47e2a6156bffab Mon Sep 17 00:00:00 2001 From: Junzhe Zou Date: Mon, 19 Dec 2016 17:25:40 -0800 Subject: [PATCH] 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 --- .../platform/msm/camera_v2/isp/msm_isp.h | 3 ++ .../platform/msm/camera_v2/isp/msm_isp40.c | 1 + .../platform/msm/camera_v2/isp/msm_isp44.c | 1 + .../platform/msm/camera_v2/isp/msm_isp46.c | 1 + .../platform/msm/camera_v2/isp/msm_isp47.c | 10 ++++ .../platform/msm/camera_v2/isp/msm_isp47.h | 2 + .../platform/msm/camera_v2/isp/msm_isp48.c | 1 + .../msm/camera_v2/isp/msm_isp_axi_util.c | 50 +++++++++++++------ .../platform/msm/camera_v2/isp/msm_isp_util.c | 5 +- 9 files changed, 57 insertions(+), 17 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h index 0325c5ded3cf..289222923e48 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h @@ -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 { diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c index 8e549c338bdd..8bee38254de6 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c @@ -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, diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp44.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp44.c index 957cbc292be3..25d51dde1391 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp44.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp44.c @@ -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, diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp46.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp46.c index cc768db875db..549a0050362b 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp46.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp46.c @@ -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, diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c index b704e84cc140..caba69f373e8 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c @@ -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, diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp47.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp47.h index 22a1a21bce9a..420c37c35c2a 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp47.h +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp47.h @@ -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, diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp48.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp48.c index 5b4d6aa63055..01bc0fce4fed 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp48.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp48.c @@ -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, diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c index 8488405b561a..e9066ad762fc 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c @@ -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, diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c index 507198721ccc..13e629900f2a 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c @@ -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 */