summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c46
-rw-r--r--include/uapi/media/msmb_isp.h12
2 files changed, 47 insertions, 11 deletions
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 225572c00ff2..fbac6d81ded0 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
@@ -631,6 +631,7 @@ void msm_isp_check_for_output_error(struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info;
struct msm_vfe_axi_shared_data *axi_data;
int i;
+ uint32_t stream_idx;
if (!vfe_dev || !sof_info) {
pr_err("%s %d failed: vfe_dev %pK sof_info %pK\n", __func__,
@@ -648,17 +649,31 @@ void msm_isp_check_for_output_error(struct vfe_device *vfe_dev,
if (!vfe_dev->reg_updated) {
sof_info->regs_not_updated =
vfe_dev->reg_update_requested;
- for (i = 0; i < VFE_AXI_SRC_MAX; i++) {
- struct msm_vfe_axi_stream *temp_stream_info;
- stream_info = &axi_data->stream_info[i];
- if (stream_info->state != ACTIVE ||
- !stream_info->controllable_output ||
- (SRC_TO_INTF(stream_info->stream_src) !=
- VFE_PIX_0))
+ }
+ for (i = 0; i < VFE_AXI_SRC_MAX; i++) {
+ struct msm_vfe_axi_stream *temp_stream_info;
+
+ stream_info = &axi_data->stream_info[i];
+ stream_idx = HANDLE_TO_IDX(stream_info->stream_handle);
+
+ /*
+ * Process drop only if controllable ACTIVE PIX stream &&
+ * reg_not_updated
+ * OR stream is in RESUMING state.
+ * Other cases there is no drop to report, so continue.
+ */
+ if (!((stream_info->state == ACTIVE &&
+ stream_info->controllable_output &&
+ (SRC_TO_INTF(stream_info->stream_src) ==
+ VFE_PIX_0)) ||
+ stream_info->state == RESUMING))
continue;
+
+ if (stream_info->controllable_output &&
+ !vfe_dev->reg_updated) {
temp_stream_info =
msm_isp_get_controllable_stream(vfe_dev,
- stream_info);
+ stream_info);
if (temp_stream_info->undelivered_request_cnt) {
if (msm_isp_drop_frame(vfe_dev, stream_info, ts,
sof_info)) {
@@ -666,7 +681,18 @@ void msm_isp_check_for_output_error(struct vfe_device *vfe_dev,
}
}
}
+
+ if (stream_info->state == RESUMING &&
+ !stream_info->controllable_output) {
+ ISP_DBG("%s: axi_updating_mask stream_id %x frame_id %d\n",
+ __func__, stream_idx, vfe_dev->axi_data.
+ src_info[SRC_TO_INTF(stream_info->stream_src)]
+ .frame_id);
+ sof_info->axi_updating_mask |=
+ 1 << stream_idx;
+ }
}
+
vfe_dev->reg_updated = 0;
/* report frame drop per stream */
@@ -1875,8 +1901,8 @@ int msm_isp_drop_frame(struct vfe_device *vfe_dev,
__func__, done_buf->bufq_handle);
return -EINVAL;
}
- sof_info->reg_update_fail_mask |=
- 1 << (bufq->bufq_handle & 0xF);
+ sof_info->reg_update_fail_mask_ext |=
+ (bufq->bufq_handle & 0xFF);
}
spin_unlock_irqrestore(&stream_info->lock, flags);
diff --git a/include/uapi/media/msmb_isp.h b/include/uapi/media/msmb_isp.h
index 7f7ebd3ba21f..e658f4b56df9 100644
--- a/include/uapi/media/msmb_isp.h
+++ b/include/uapi/media/msmb_isp.h
@@ -719,7 +719,7 @@ struct msm_isp_output_info {
/* This structure is piggybacked with SOF event */
struct msm_isp_sof_info {
uint8_t regs_not_updated;
- /* mask with AXI_SRC for regs not updated */
+ /* mask with bufq_handle for regs not updated */
uint16_t reg_update_fail_mask;
/* mask with bufq_handle for get_buf failed */
uint32_t stream_get_buf_fail_mask;
@@ -727,7 +727,17 @@ struct msm_isp_sof_info {
uint16_t stats_get_buf_fail_mask;
/* delta between master and slave */
struct msm_isp_ms_delta_info ms_delta_info;
+ /*
+ * mask with AXI_SRC in paused state. In PAUSED
+ * state there is no Buffer output. So this mask is used
+ * to report drop.
+ */
+ uint16_t axi_updating_mask;
+ /* extended mask with bufq_handle for regs not updated */
+ uint32_t reg_update_fail_mask_ext;
};
+#define AXI_UPDATING_MASK 1
+#define REG_UPDATE_FAIL_MASK_EXT 1
struct msm_isp_event_data {
/*Wall clock except for buffer divert events