msm: isp: Add pingpong status to tasklet command
We read pingpong status while handling axi and stats irqs in tasklet. Due to scheduling delays in tasklet pingpong status is changing by the time we read. So, read ping pong status in ISR and forward it to tasklet. Change-Id: Ib83929cb8e15c28e34ee06275a87b5d6fbfd00e6 Signed-off-by: Srikanth Uyyala <suyyala@codeaurora.org>
This commit is contained in:
parent
2c333d317c
commit
8aa5106e44
6 changed files with 30 additions and 25 deletions
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -155,9 +155,11 @@ struct msm_vfe_irq_ops {
|
|||
struct msm_isp_timestamp *ts);
|
||||
void (*process_axi_irq)(struct vfe_device *vfe_dev,
|
||||
uint32_t irq_status0, uint32_t irq_status1,
|
||||
uint32_t pingpong_status,
|
||||
struct msm_isp_timestamp *ts);
|
||||
void (*process_stats_irq)(struct vfe_device *vfe_dev,
|
||||
uint32_t irq_status0, uint32_t irq_status1,
|
||||
uint32_t pingpong_status,
|
||||
struct msm_isp_timestamp *ts);
|
||||
void (*config_irq)(struct vfe_device *vfe_dev,
|
||||
uint32_t irq_status0, uint32_t irq_status1,
|
||||
|
@ -596,6 +598,7 @@ struct msm_vfe_tasklet_queue_cmd {
|
|||
struct list_head list;
|
||||
uint32_t vfeInterruptStatus0;
|
||||
uint32_t vfeInterruptStatus1;
|
||||
uint32_t vfe_pingpong_status;
|
||||
struct msm_isp_timestamp ts;
|
||||
uint8_t cmd_used;
|
||||
struct vfe_device *vfe_dev;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -4202,11 +4202,11 @@ void msm_isp_process_axi_irq_stream(struct vfe_device *vfe_dev,
|
|||
|
||||
void msm_isp_process_axi_irq(struct vfe_device *vfe_dev,
|
||||
uint32_t irq_status0, uint32_t irq_status1,
|
||||
struct msm_isp_timestamp *ts)
|
||||
uint32_t pingpong_status, struct msm_isp_timestamp *ts)
|
||||
{
|
||||
int i, rc = 0;
|
||||
uint32_t comp_mask = 0, wm_mask = 0;
|
||||
uint32_t pingpong_status, stream_idx;
|
||||
uint32_t stream_idx;
|
||||
struct msm_vfe_axi_stream *stream_info;
|
||||
struct msm_vfe_axi_composite_info *comp_info;
|
||||
struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
|
||||
|
@ -4220,8 +4220,6 @@ void msm_isp_process_axi_irq(struct vfe_device *vfe_dev,
|
|||
return;
|
||||
|
||||
ISP_DBG("%s: status: 0x%x\n", __func__, irq_status0);
|
||||
pingpong_status =
|
||||
vfe_dev->hw_info->vfe_ops.axi_ops.get_pingpong_status(vfe_dev);
|
||||
|
||||
for (i = 0; i < axi_data->hw_info->num_comp_mask; i++) {
|
||||
rc = 0;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -54,7 +54,7 @@ void msm_isp_notify(struct vfe_device *vfe_dev, uint32_t event_type,
|
|||
|
||||
void msm_isp_process_axi_irq(struct vfe_device *vfe_dev,
|
||||
uint32_t irq_status0, uint32_t irq_status1,
|
||||
struct msm_isp_timestamp *ts);
|
||||
uint32_t pingpong_status, struct msm_isp_timestamp *ts);
|
||||
|
||||
void msm_isp_axi_disable_all_wm(struct vfe_device *vfe_dev);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -256,13 +256,12 @@ static int32_t msm_isp_stats_buf_divert(struct vfe_device *vfe_dev,
|
|||
|
||||
static int32_t msm_isp_stats_configure(struct vfe_device *vfe_dev,
|
||||
uint32_t stats_irq_mask, struct msm_isp_timestamp *ts,
|
||||
bool is_composite)
|
||||
uint32_t pingpong_status, bool is_composite)
|
||||
{
|
||||
int i, rc = 0;
|
||||
struct msm_isp_event_data buf_event;
|
||||
struct msm_isp_stats_event *stats_event = &buf_event.u.stats;
|
||||
struct msm_vfe_stats_stream *stream_info = NULL;
|
||||
uint32_t pingpong_status;
|
||||
uint32_t comp_stats_type_mask = 0;
|
||||
int result = 0;
|
||||
|
||||
|
@ -271,8 +270,6 @@ static int32_t msm_isp_stats_configure(struct vfe_device *vfe_dev,
|
|||
buf_event.mono_timestamp = ts->buf_time;
|
||||
|
||||
buf_event.frame_id = vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id;
|
||||
pingpong_status = vfe_dev->hw_info->
|
||||
vfe_ops.stats_ops.get_pingpong_status(vfe_dev);
|
||||
|
||||
for (i = 0; i < vfe_dev->hw_info->stats_hw_info->num_stats_type; i++) {
|
||||
if (!(stats_irq_mask & (1 << i)))
|
||||
|
@ -309,7 +306,7 @@ static int32_t msm_isp_stats_configure(struct vfe_device *vfe_dev,
|
|||
|
||||
void msm_isp_process_stats_irq(struct vfe_device *vfe_dev,
|
||||
uint32_t irq_status0, uint32_t irq_status1,
|
||||
struct msm_isp_timestamp *ts)
|
||||
uint32_t pingpong_status, struct msm_isp_timestamp *ts)
|
||||
{
|
||||
int j, rc;
|
||||
uint32_t atomic_stats_mask = 0;
|
||||
|
@ -337,7 +334,7 @@ void msm_isp_process_stats_irq(struct vfe_device *vfe_dev,
|
|||
/* Process non-composite irq */
|
||||
if (stats_irq_mask) {
|
||||
rc = msm_isp_stats_configure(vfe_dev, stats_irq_mask, ts,
|
||||
comp_flag);
|
||||
pingpong_status, comp_flag);
|
||||
}
|
||||
|
||||
/* Process composite irq */
|
||||
|
@ -350,7 +347,7 @@ void msm_isp_process_stats_irq(struct vfe_device *vfe_dev,
|
|||
&vfe_dev->stats_data.stats_comp_mask[j]);
|
||||
|
||||
rc = msm_isp_stats_configure(vfe_dev, atomic_stats_mask,
|
||||
ts, !comp_flag);
|
||||
ts, pingpong_status, !comp_flag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2013-2016, 2018 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -17,7 +17,7 @@
|
|||
|
||||
void msm_isp_process_stats_irq(struct vfe_device *vfe_dev,
|
||||
uint32_t irq_status0, uint32_t irq_status1,
|
||||
struct msm_isp_timestamp *ts);
|
||||
uint32_t pingpong_status, struct msm_isp_timestamp *ts);
|
||||
void msm_isp_stats_stream_update(struct vfe_device *vfe_dev);
|
||||
int msm_isp_cfg_stats_stream(struct vfe_device *vfe_dev, void *arg);
|
||||
int msm_isp_update_stats_stream(struct vfe_device *vfe_dev, void *arg);
|
||||
|
|
|
@ -2064,7 +2064,8 @@ void msm_isp_prepare_tasklet_debug_info(struct vfe_device *vfe_dev,
|
|||
}
|
||||
|
||||
static void msm_isp_enqueue_tasklet_cmd(struct vfe_device *vfe_dev,
|
||||
uint32_t irq_status0, uint32_t irq_status1)
|
||||
uint32_t irq_status0, uint32_t irq_status1,
|
||||
uint32_t ping_pong_status)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct msm_vfe_tasklet_queue_cmd *queue_cmd = NULL;
|
||||
|
@ -2087,8 +2088,8 @@ static void msm_isp_enqueue_tasklet_cmd(struct vfe_device *vfe_dev,
|
|||
}
|
||||
queue_cmd->vfeInterruptStatus0 = irq_status0;
|
||||
queue_cmd->vfeInterruptStatus1 = irq_status1;
|
||||
queue_cmd->vfe_pingpong_status = ping_pong_status;
|
||||
msm_isp_get_timestamp(&queue_cmd->ts, vfe_dev);
|
||||
|
||||
queue_cmd->cmd_used = 1;
|
||||
queue_cmd->vfe_dev = vfe_dev;
|
||||
|
||||
|
@ -2102,7 +2103,7 @@ static void msm_isp_enqueue_tasklet_cmd(struct vfe_device *vfe_dev,
|
|||
irqreturn_t msm_isp_process_irq(int irq_num, void *data)
|
||||
{
|
||||
struct vfe_device *vfe_dev = (struct vfe_device *) data;
|
||||
uint32_t irq_status0, irq_status1;
|
||||
uint32_t irq_status0, irq_status1, ping_pong_status;
|
||||
uint32_t error_mask0, error_mask1;
|
||||
|
||||
vfe_dev->hw_info->vfe_ops.irq_ops.
|
||||
|
@ -2113,6 +2114,8 @@ irqreturn_t msm_isp_process_irq(int irq_num, void *data)
|
|||
__func__, vfe_dev->pdev->id);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
ping_pong_status = vfe_dev->hw_info->vfe_ops.axi_ops.
|
||||
get_pingpong_status(vfe_dev);
|
||||
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);
|
||||
|
@ -2140,7 +2143,8 @@ irqreturn_t msm_isp_process_irq(int irq_num, void *data)
|
|||
return IRQ_HANDLED;
|
||||
}
|
||||
msm_isp_prepare_irq_debug_info(vfe_dev, irq_status0, irq_status1);
|
||||
msm_isp_enqueue_tasklet_cmd(vfe_dev, irq_status0, irq_status1);
|
||||
msm_isp_enqueue_tasklet_cmd(vfe_dev, irq_status0, irq_status1,
|
||||
ping_pong_status);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
@ -2153,7 +2157,7 @@ void msm_isp_do_tasklet(unsigned long data)
|
|||
struct msm_vfe_irq_ops *irq_ops;
|
||||
struct msm_vfe_tasklet_queue_cmd *queue_cmd;
|
||||
struct msm_isp_timestamp ts;
|
||||
uint32_t irq_status0, irq_status1;
|
||||
uint32_t irq_status0, irq_status1, pingpong_status;
|
||||
|
||||
while (1) {
|
||||
spin_lock_irqsave(&tasklet->tasklet_lock, flags);
|
||||
|
@ -2169,6 +2173,7 @@ void msm_isp_do_tasklet(unsigned long data)
|
|||
queue_cmd->vfe_dev = NULL;
|
||||
irq_status0 = queue_cmd->vfeInterruptStatus0;
|
||||
irq_status1 = queue_cmd->vfeInterruptStatus1;
|
||||
pingpong_status = queue_cmd->vfe_pingpong_status;
|
||||
ts = queue_cmd->ts;
|
||||
spin_unlock_irqrestore(&tasklet->tasklet_lock, flags);
|
||||
if (vfe_dev->vfe_open_cnt == 0) {
|
||||
|
@ -2193,9 +2198,11 @@ void msm_isp_do_tasklet(unsigned long data)
|
|||
}
|
||||
msm_isp_process_error_info(vfe_dev);
|
||||
irq_ops->process_stats_irq(vfe_dev,
|
||||
irq_status0, irq_status1, &ts);
|
||||
irq_status0, irq_status1,
|
||||
pingpong_status, &ts);
|
||||
irq_ops->process_axi_irq(vfe_dev,
|
||||
irq_status0, irq_status1, &ts);
|
||||
irq_status0, irq_status1,
|
||||
pingpong_status, &ts);
|
||||
irq_ops->process_camif_irq(vfe_dev,
|
||||
irq_status0, irq_status1, &ts);
|
||||
irq_ops->process_reg_update(vfe_dev,
|
||||
|
|
Loading…
Add table
Reference in a new issue