summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp.h6
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp47.c6
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c49
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c5
4 files changed, 53 insertions, 13 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 9bc6fde36774..cef2cd9ffcf1 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
@@ -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
@@ -746,6 +746,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 +849,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 {
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c
index a8341a7ff3e6..cf9e7547d4e2 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c
@@ -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,
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 79b45b6678b0..011a1d4019eb 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
@@ -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
@@ -662,9 +662,11 @@ void msm_isp_process_reg_upd_epoch_irq(struct vfe_device *vfe_dev,
__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);
@@ -2739,6 +2741,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 +3014,7 @@ 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;
for (k = 0; k < stream_info->num_isp; k++) {
vfe_dev = stream_info->vfe_dev[k];
if (stream_info->num_planes > 1)
@@ -3174,7 +3178,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 +3523,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 +4275,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,6 +4342,11 @@ 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 {
spin_unlock_irqrestore(&stream_info->lock, flags);
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
index 684b331d9ac4..05c955ac7cd5 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
@@ -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
@@ -2291,7 +2291,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--;