From 40cfe338ba3042177e92e6897529aa91f8fe23d8 Mon Sep 17 00:00:00 2001 From: Lokesh Kumar Aakulu Date: Wed, 21 Jun 2017 00:44:43 +0530 Subject: [PATCH] msm: camera: isp: Avoid reading stale ping pong status When write masters are reloaded pingpong status regi- -ster will not be reset. Instead, it would be holding a stale data, until new axi_done irq is interrupted. So, place a check to validate the pingpong register value based on the reloaded status of write masters. Change-Id: Id14b886154f8a8ef8d5c05338023d8172d6925d0 Signed-off-by: Lokesh Kumar Aakulu --- .../platform/msm/camera_v2/isp/msm_isp.h | 2 +- .../msm/camera_v2/isp/msm_isp_axi_util.c | 33 ++++++++++++++++--- 2 files changed, 30 insertions(+), 5 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 d64cee834bea..1f1435fe282e 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h @@ -456,7 +456,7 @@ struct msm_vfe_axi_stream { uint32_t runtime_output_format; enum msm_stream_rdi_input_type rdi_input_type; struct msm_isp_sw_framskip sw_skip; - uint8_t sw_ping_pong_bit; + int8_t sw_ping_pong_bit; struct vfe_device *vfe_dev[MAX_VFE]; int num_isp; 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 e2f068a21c28..81583282ed69 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 @@ -1699,6 +1699,9 @@ static int msm_isp_update_deliver_count(struct vfe_device *vfe_dev, rc = -EINVAL; goto done; } else { + /*After wm reload, we get bufdone for ping buffer*/ + if (stream_info->sw_ping_pong_bit == -1) + stream_info->sw_ping_pong_bit = 0; stream_info->undelivered_request_cnt--; if (pingpong_bit != stream_info->sw_ping_pong_bit) { pr_err("%s:%d ping pong bit actual %d sw %d\n", @@ -3477,7 +3480,14 @@ static int msm_isp_request_frame(struct vfe_device *vfe_dev, spin_lock_irqsave(&stream_info->lock, flags); vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info); - if (stream_info->undelivered_request_cnt == 1) { + /* + * When wm reloaded, pingpong status register would be stale, pingpong + * status would be updated only after AXI_DONE interrupt processed. + * So, we should avoid reading value from pingpong status register + * until buf_done happens for ping buffer. + */ + if ((stream_info->undelivered_request_cnt == 1) && + (stream_info->sw_ping_pong_bit != -1)) { pingpong_status = vfe_dev->hw_info->vfe_ops.axi_ops.get_pingpong_status( vfe_dev); @@ -3550,10 +3560,25 @@ static int msm_isp_request_frame(struct vfe_device *vfe_dev, stream_info->vfe_dev[k]->vfe_base, wm_mask); } - stream_info->sw_ping_pong_bit = 0; + /* + * sw_ping_pong_bit is updated only when AXI_DONE. + * so now reset this bit to -1. + */ + stream_info->sw_ping_pong_bit = -1; } else if (stream_info->undelivered_request_cnt == 2) { - rc = msm_isp_cfg_ping_pong_address( - stream_info, pingpong_status); + if (stream_info->sw_ping_pong_bit == -1) { + /* + * This means wm is reloaded & ping buffer is + * already configured. And AXI_DONE for ping + * is still pending. So, config pong buffer + * now. + */ + rc = msm_isp_cfg_ping_pong_address(stream_info, + VFE_PONG_FLAG); + } else { + rc = msm_isp_cfg_ping_pong_address( + stream_info, pingpong_status); + } if (rc) { stream_info->undelivered_request_cnt--; spin_unlock_irqrestore(&stream_info->lock,