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:
parent
bfbbb3e4b2
commit
40cfe338ba
2 changed files with 30 additions and 5 deletions
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Reference in a new issue