Merge "msm📷 add trace log support for VFE events"
This commit is contained in:
commit
19d79e95f1
5 changed files with 168 additions and 18 deletions
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2013-2019, 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
|
||||
|
@ -416,6 +416,12 @@ enum msm_isp_comp_irq_types {
|
|||
|
||||
#define MSM_VFE_REQUESTQ_SIZE 8
|
||||
|
||||
struct msm_isp_pending_buf_info {
|
||||
uint32_t is_buf_done_pending;
|
||||
struct msm_isp_buffer *buf;
|
||||
uint32_t frame_id;
|
||||
};
|
||||
|
||||
struct msm_vfe_axi_stream {
|
||||
uint32_t frame_id;
|
||||
enum msm_vfe_axi_state state;
|
||||
|
@ -472,6 +478,7 @@ struct msm_vfe_axi_stream {
|
|||
uint32_t vfe_mask;
|
||||
uint32_t composite_irq[MSM_ISP_COMP_IRQ_MAX];
|
||||
int lpm_mode;
|
||||
struct msm_isp_pending_buf_info pending_buf_info;
|
||||
};
|
||||
|
||||
struct msm_vfe_axi_composite_info {
|
||||
|
@ -746,6 +753,7 @@ struct msm_vfe_common_dev_data {
|
|||
/* Irq debug Info */
|
||||
struct msm_vfe_irq_dump vfe_irq_dump;
|
||||
struct msm_vfe_tasklet tasklets[MAX_VFE + 1];
|
||||
uint32_t drop_reconfig;
|
||||
};
|
||||
|
||||
struct msm_vfe_common_subdev {
|
||||
|
@ -848,6 +856,9 @@ struct vfe_device {
|
|||
/* total bandwidth per vfe */
|
||||
uint64_t total_bandwidth;
|
||||
struct isp_kstate *isp_page;
|
||||
|
||||
/* irq info */
|
||||
uint32_t irq_sof_id;
|
||||
};
|
||||
|
||||
struct vfe_parent_device {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2013-2019, 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
|
||||
|
@ -714,8 +714,10 @@ void msm_isp47_preprocess_camif_irq(struct vfe_device *vfe_dev,
|
|||
{
|
||||
if (irq_status0 & BIT(3))
|
||||
vfe_dev->axi_data.src_info[VFE_PIX_0].accept_frame = false;
|
||||
if (irq_status0 & BIT(0))
|
||||
if (irq_status0 & BIT(0)) {
|
||||
vfe_dev->axi_data.src_info[VFE_PIX_0].accept_frame = true;
|
||||
vfe_dev->irq_sof_id++;
|
||||
}
|
||||
}
|
||||
|
||||
void msm_vfe47_reg_update(struct vfe_device *vfe_dev,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2013-2019, 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
|
||||
|
@ -16,6 +16,7 @@
|
|||
#include "msm_isp_stats_util.h"
|
||||
#include "msm_isp_axi_util.h"
|
||||
#include "msm_isp48.h"
|
||||
#include "trace/events/msm_cam.h"
|
||||
|
||||
#define HANDLE_TO_IDX(handle) (handle & 0xFF)
|
||||
#define ISP_SOF_DEBUG_COUNT 0
|
||||
|
@ -27,6 +28,13 @@ static void __msm_isp_axi_stream_update(
|
|||
struct msm_vfe_axi_stream *stream_info,
|
||||
struct msm_isp_timestamp *ts);
|
||||
|
||||
static int msm_isp_process_done_buf(struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_axi_stream *stream_info, struct msm_isp_buffer *buf,
|
||||
struct timeval *time_stamp, uint32_t frame_id);
|
||||
static void msm_isp_free_pending_buffer(
|
||||
struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_axi_stream *stream_info,
|
||||
struct msm_isp_timestamp *ts);
|
||||
static int msm_isp_update_stream_bandwidth(
|
||||
struct msm_vfe_axi_stream *stream_info, int enable);
|
||||
|
||||
|
@ -659,12 +667,18 @@ void msm_isp_process_reg_upd_epoch_irq(struct vfe_device *vfe_dev,
|
|||
case MSM_ISP_COMP_IRQ_REG_UPD:
|
||||
stream_info->activated_framedrop_period =
|
||||
stream_info->requested_framedrop_period;
|
||||
/* Free Pending Buffers which are backed-up due to
|
||||
* delay in RUP from userspace to Avoid pageFault
|
||||
*/
|
||||
msm_isp_free_pending_buffer(vfe_dev, stream_info, ts);
|
||||
__msm_isp_axi_stream_update(stream_info, ts);
|
||||
break;
|
||||
case MSM_ISP_COMP_IRQ_EPOCH:
|
||||
if (stream_info->state == ACTIVE)
|
||||
if (stream_info->state == ACTIVE) {
|
||||
msm_isp_update_framedrop_reg(stream_info,
|
||||
vfe_dev->isp_page->drop_reconfig);
|
||||
vfe_dev->common_data->drop_reconfig);
|
||||
vfe_dev->common_data->drop_reconfig = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
WARN(1, "Invalid irq %d\n", irq);
|
||||
|
@ -1035,8 +1049,12 @@ void msm_isp_notify(struct vfe_device *vfe_dev, uint32_t event_type,
|
|||
vfe_dev->isp_raw2_debug++;
|
||||
}
|
||||
|
||||
ISP_DBG("%s: vfe %d frame_src %d\n", __func__,
|
||||
vfe_dev->pdev->id, frame_src);
|
||||
ISP_DBG("%s: vfe %d frame_src %d frameid %d\n", __func__,
|
||||
vfe_dev->pdev->id, frame_src,
|
||||
vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id);
|
||||
trace_msm_cam_isp_status_dump("SOFNOTIFY:", vfe_dev->pdev->id,
|
||||
vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id,
|
||||
0, 0);
|
||||
|
||||
/*
|
||||
* Cannot support dual_cam and framedrop same time in union.
|
||||
|
@ -1521,6 +1539,40 @@ static void msm_isp_axi_stream_enable_cfg(
|
|||
}
|
||||
}
|
||||
|
||||
static void msm_isp_free_pending_buffer(
|
||||
struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_axi_stream *stream_info,
|
||||
struct msm_isp_timestamp *ts)
|
||||
{
|
||||
struct timeval *time_stamp;
|
||||
struct msm_isp_buffer *done_buf = NULL;
|
||||
uint32_t frame_id;
|
||||
int rc;
|
||||
|
||||
if (!stream_info->controllable_output ||
|
||||
!stream_info->pending_buf_info.is_buf_done_pending) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (vfe_dev->vt_enable) {
|
||||
msm_isp_get_avtimer_ts(ts);
|
||||
time_stamp = &ts->vt_time;
|
||||
} else {
|
||||
time_stamp = &ts->buf_time;
|
||||
}
|
||||
|
||||
done_buf = stream_info->pending_buf_info.buf;
|
||||
frame_id = stream_info->pending_buf_info.frame_id;
|
||||
if (done_buf) {
|
||||
rc = msm_isp_process_done_buf(vfe_dev, stream_info,
|
||||
done_buf, time_stamp, frame_id);
|
||||
if (rc == 0) {
|
||||
stream_info->pending_buf_info.buf = NULL;
|
||||
stream_info->pending_buf_info.is_buf_done_pending = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void __msm_isp_axi_stream_update(
|
||||
struct msm_vfe_axi_stream *stream_info,
|
||||
struct msm_isp_timestamp *ts)
|
||||
|
@ -2739,6 +2791,7 @@ int msm_isp_axi_reset(struct vfe_device *vfe_dev,
|
|||
axi_data->src_info[SRC_TO_INTF(stream_info->
|
||||
stream_src)].frame_id =
|
||||
reset_cmd->frame_id;
|
||||
temp_vfe_dev->irq_sof_id = reset_cmd->frame_id;
|
||||
}
|
||||
msm_isp_reset_burst_count_and_frame_drop(
|
||||
vfe_dev, stream_info);
|
||||
|
@ -3011,6 +3064,13 @@ static void __msm_isp_stop_axi_streams(struct vfe_device *vfe_dev,
|
|||
msm_isp_cfg_stream_scratch(stream_info, VFE_PING_FLAG);
|
||||
msm_isp_cfg_stream_scratch(stream_info, VFE_PONG_FLAG);
|
||||
stream_info->undelivered_request_cnt = 0;
|
||||
vfe_dev->irq_sof_id = 0;
|
||||
if (stream_info->controllable_output &&
|
||||
stream_info->pending_buf_info.is_buf_done_pending) {
|
||||
msm_isp_free_pending_buffer(vfe_dev, stream_info,
|
||||
×tamp);
|
||||
stream_info->pending_buf_info.is_buf_done_pending = 0;
|
||||
}
|
||||
for (k = 0; k < stream_info->num_isp; k++) {
|
||||
vfe_dev = stream_info->vfe_dev[k];
|
||||
if (stream_info->num_planes > 1)
|
||||
|
@ -3174,7 +3234,6 @@ static int msm_isp_start_axi_stream(struct vfe_device *vfe_dev_ioctl,
|
|||
mutex_unlock(&vfe_dev_ioctl->buf_mgr->lock);
|
||||
goto error;
|
||||
}
|
||||
|
||||
msm_isp_calculate_bandwidth(stream_info);
|
||||
for (k = 0; k < stream_info->num_isp; k++) {
|
||||
msm_isp_get_stream_wm_mask(stream_info->vfe_dev[k],
|
||||
|
@ -3520,16 +3579,25 @@ static int msm_isp_request_frame(struct vfe_device *vfe_dev,
|
|||
*/
|
||||
if (vfe_dev->axi_data.src_info[frame_src].active &&
|
||||
frame_src == VFE_PIX_0 &&
|
||||
vfe_dev->axi_data.src_info[frame_src].accept_frame == false) {
|
||||
vfe_dev->axi_data.src_info[frame_src].accept_frame == false &&
|
||||
(stream_info->undelivered_request_cnt <=
|
||||
MAX_BUFFERS_IN_HW)
|
||||
) {
|
||||
pr_debug("%s:%d invalid time to request frame %d\n",
|
||||
__func__, __LINE__, frame_id);
|
||||
vfe_dev->isp_page->drop_reconfig = 1;
|
||||
/*keep it in vfe_dev variable also to avoid skip pattern
|
||||
* programming the variable in page can be overwritten by MCT
|
||||
*/
|
||||
vfe_dev->common_data->drop_reconfig = 1;
|
||||
} else if ((vfe_dev->axi_data.src_info[frame_src].active) &&
|
||||
(frame_id ==
|
||||
vfe_dev->axi_data.src_info[frame_src].frame_id) &&
|
||||
((frame_id ==
|
||||
vfe_dev->axi_data.src_info[frame_src].frame_id) ||
|
||||
(frame_id == vfe_dev->irq_sof_id)) &&
|
||||
(stream_info->undelivered_request_cnt <=
|
||||
MAX_BUFFERS_IN_HW)) {
|
||||
vfe_dev->isp_page->drop_reconfig = 1;
|
||||
vfe_dev->common_data->drop_reconfig = 1;
|
||||
pr_debug("%s: vfe_%d request_frame %d cur frame id %d pix %d\n",
|
||||
__func__, vfe_dev->pdev->id, frame_id,
|
||||
vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id,
|
||||
|
@ -4263,9 +4331,25 @@ void msm_isp_process_axi_irq_stream(struct vfe_device *vfe_dev,
|
|||
ISP_DBG("%s: Error configuring ping_pong\n",
|
||||
__func__);
|
||||
} else if (done_buf && (done_buf->is_drop_reconfig != 1)) {
|
||||
int32_t frame_id_diff;
|
||||
/* irq_sof should be always >= tasklet SOF id
|
||||
* For dual camera usecase irq_sof could be behind
|
||||
* as software frameid sync logic epoch event could
|
||||
* update slave frame id so update if irqsof < tasklet sof
|
||||
*/
|
||||
if (vfe_dev->irq_sof_id < frame_id)
|
||||
vfe_dev->irq_sof_id = frame_id;
|
||||
|
||||
frame_id_diff = vfe_dev->irq_sof_id - frame_id;
|
||||
if (stream_info->controllable_output && frame_id_diff > 1) {
|
||||
/*scheduling problem need to do recovery*/
|
||||
spin_unlock_irqrestore(&stream_info->lock, flags);
|
||||
msm_isp_halt_send_error(vfe_dev,
|
||||
ISP_EVENT_PING_PONG_MISMATCH);
|
||||
return;
|
||||
}
|
||||
msm_isp_cfg_stream_scratch(stream_info, pingpong_status);
|
||||
}
|
||||
|
||||
if (!done_buf) {
|
||||
if (stream_info->buf_divert) {
|
||||
vfe_dev->error_info.stream_framedrop_count[
|
||||
|
@ -4314,11 +4398,28 @@ void msm_isp_process_axi_irq_stream(struct vfe_device *vfe_dev,
|
|||
* then dont issue buf-done for current buffer
|
||||
*/
|
||||
done_buf->is_drop_reconfig = 0;
|
||||
if (!stream_info->buf[pingpong_bit]) {
|
||||
/*samebuffer is not re-programeed so program scratch*/
|
||||
msm_isp_cfg_stream_scratch(stream_info,
|
||||
pingpong_status);
|
||||
}
|
||||
spin_unlock_irqrestore(&stream_info->lock, flags);
|
||||
} else {
|
||||
/* If there is no regupdate from userspace then dont
|
||||
* free buffer immediately, delegate it to RegUpdateAck
|
||||
*/
|
||||
if (stream_info->controllable_output &&
|
||||
!(vfe_dev->reg_update_requested &
|
||||
BIT((uint32_t)VFE_PIX_0))) {
|
||||
stream_info->pending_buf_info.is_buf_done_pending = 1;
|
||||
stream_info->pending_buf_info.buf = done_buf;
|
||||
stream_info->pending_buf_info.frame_id = frame_id;
|
||||
}
|
||||
spin_unlock_irqrestore(&stream_info->lock, flags);
|
||||
msm_isp_process_done_buf(vfe_dev, stream_info,
|
||||
done_buf, time_stamp, frame_id);
|
||||
if (stream_info->pending_buf_info.is_buf_done_pending != 1) {
|
||||
msm_isp_process_done_buf(vfe_dev, stream_info,
|
||||
done_buf, time_stamp, frame_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2013-2019, 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
|
||||
|
@ -2090,6 +2090,10 @@ static void msm_isp_enqueue_tasklet_cmd(struct vfe_device *vfe_dev,
|
|||
} else {
|
||||
atomic_add(1, &vfe_dev->irq_cnt);
|
||||
}
|
||||
atomic_add(1, &vfe_dev->irq_cnt);
|
||||
trace_msm_cam_isp_status_dump("VFE_IRQ:", vfe_dev->pdev->id,
|
||||
vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id,
|
||||
irq_status0, irq_status1);
|
||||
queue_cmd->vfeInterruptStatus0 = irq_status0;
|
||||
queue_cmd->vfeInterruptStatus1 = irq_status1;
|
||||
queue_cmd->vfe_pingpong_status = ping_pong_status;
|
||||
|
@ -2189,6 +2193,9 @@ void msm_isp_do_tasklet(unsigned long data)
|
|||
atomic_sub(1, &vfe_dev->irq_cnt);
|
||||
msm_isp_prepare_tasklet_debug_info(vfe_dev,
|
||||
irq_status0, irq_status1, ts);
|
||||
trace_msm_cam_isp_status_dump("VFE_TASKLET:", vfe_dev->pdev->id,
|
||||
vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id,
|
||||
irq_status0, irq_status1);
|
||||
irq_ops = &vfe_dev->hw_info->vfe_ops.irq_ops;
|
||||
irq_ops->process_reset_irq(vfe_dev,
|
||||
irq_status0, irq_status1);
|
||||
|
@ -2291,7 +2298,8 @@ int msm_isp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
|
|||
vfe_dev->isp_raw0_debug = 0;
|
||||
vfe_dev->isp_raw1_debug = 0;
|
||||
vfe_dev->isp_raw2_debug = 0;
|
||||
|
||||
vfe_dev->irq_sof_id = 0;
|
||||
vfe_dev->common_data->drop_reconfig = 0;
|
||||
if (vfe_dev->hw_info->vfe_ops.core_ops.init_hw(vfe_dev) < 0) {
|
||||
pr_err("%s: init hardware failed\n", __func__);
|
||||
vfe_dev->vfe_open_cnt--;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2016, 2019, 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
|
||||
|
@ -131,6 +131,34 @@ TRACE_EVENT(msm_cam_ping_pong_debug_dump,
|
|||
)
|
||||
);
|
||||
|
||||
TRACE_EVENT(msm_cam_isp_status_dump,
|
||||
TP_PROTO(char *event, uint32_t vfe_id, uint32_t frame_id,
|
||||
uint32_t irq_status0, uint32_t irq_status1),
|
||||
TP_ARGS(event, vfe_id, frame_id, irq_status0,
|
||||
irq_status1),
|
||||
TP_STRUCT__entry(
|
||||
__field(char *, event)
|
||||
__field(unsigned int, vfe_id)
|
||||
__field(unsigned int, frame_id)
|
||||
__field(unsigned int, irq_status0)
|
||||
__field(unsigned int, irq_status1)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__entry->event = event;
|
||||
__entry->vfe_id = vfe_id;
|
||||
__entry->frame_id = frame_id;
|
||||
__entry->irq_status0 = irq_status0;
|
||||
__entry->irq_status1 = irq_status1;
|
||||
),
|
||||
TP_printk("%s vfe %d, frame %d, irq_st0 %x, irq_st1 %x\n",
|
||||
__entry->event,
|
||||
__entry->vfe_id,
|
||||
__entry->frame_id,
|
||||
__entry->irq_status0,
|
||||
__entry->irq_status1
|
||||
)
|
||||
);
|
||||
|
||||
#endif /* _MSM_CAM_TRACE_H */
|
||||
/* This part must be outside protection */
|
||||
#include <trace/define_trace.h>
|
||||
|
|
Loading…
Add table
Reference in a new issue