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 <lkumar@codeaurora.org>
This commit is contained in:
Lokesh Kumar Aakulu 2017-06-21 00:44:43 +05:30
parent bfbbb3e4b2
commit 40cfe338ba
2 changed files with 30 additions and 5 deletions

View file

@ -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;

View file

@ -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,