Loading drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c +51 −8 Original line number Diff line number Diff line Loading @@ -238,7 +238,8 @@ static int msm_isp_buf_prepare(struct msm_isp_buf_mgr *buf_mgr, bufq = msm_isp_get_bufq(buf_mgr, buf_info->bufq_handle); if (!bufq) { pr_err("%s: Invalid bufq\n", __func__); pr_err("%s: Invalid bufq\n", __func__); return rc; } Loading Loading @@ -610,9 +611,8 @@ static int msm_isp_put_buf_unsafe(struct msm_isp_buf_mgr *buf_mgr, return rc; } static int msm_isp_buf_done(struct msm_isp_buf_mgr *buf_mgr, uint32_t bufq_handle, uint32_t buf_index, struct timeval *tv, uint32_t frame_id, uint32_t output_format) static int msm_isp_update_put_buf_cnt(struct msm_isp_buf_mgr *buf_mgr, uint32_t bufq_handle, uint32_t buf_index) { int rc = -1; unsigned long flags; Loading Loading @@ -647,6 +647,41 @@ static int msm_isp_buf_done(struct msm_isp_buf_mgr *buf_mgr, return rc; } } spin_unlock_irqrestore(&bufq->bufq_lock, flags); } return 0; } static int msm_isp_buf_done(struct msm_isp_buf_mgr *buf_mgr, uint32_t bufq_handle, uint32_t buf_index, struct timeval *tv, uint32_t frame_id, uint32_t output_format) { int rc = -1; unsigned long flags; struct msm_isp_bufq *bufq = NULL; struct msm_isp_buffer *buf_info = NULL; enum msm_isp_buffer_state state; bufq = msm_isp_get_bufq(buf_mgr, bufq_handle); if (!bufq) { pr_err("Invalid bufq\n"); return rc; } buf_info = msm_isp_get_buf_ptr(buf_mgr, bufq_handle, buf_index); if (!buf_info) { pr_err("%s: buf not found\n", __func__); return rc; } spin_lock_irqsave(&bufq->bufq_lock, flags); state = buf_info->state; spin_unlock_irqrestore(&bufq->bufq_lock, flags); if (state == MSM_ISP_BUFFER_STATE_DEQUEUED || state == MSM_ISP_BUFFER_STATE_DIVERTED) { spin_lock_irqsave(&bufq->bufq_lock, flags); buf_info->state = MSM_ISP_BUFFER_STATE_DISPATCHED; spin_unlock_irqrestore(&bufq->bufq_lock, flags); if (MSM_ISP_BUFFER_SRC_HAL == BUF_SRC(bufq->stream_id)) { Loading @@ -656,6 +691,8 @@ static int msm_isp_buf_done(struct msm_isp_buf_mgr *buf_mgr, buf_mgr->vb2_ops->buf_done(buf_info->vb2_buf, bufq->session_id, bufq->stream_id); } else { pr_err("%s: Error wrong buf done %d\n", __func__, state); rc = msm_isp_put_buf(buf_mgr, buf_info->bufq_handle, buf_info->buf_idx); if (rc < 0) { Loading Loading @@ -785,7 +822,8 @@ static int msm_isp_buf_enqueue(struct msm_isp_buf_mgr *buf_mgr, } else { bufq = msm_isp_get_bufq(buf_mgr, info->handle); if (!bufq) { pr_err("%s: Invalid bufq\n", __func__); pr_err("%s: Invalid bufq\n", __func__); return rc; } if (BUF_SRC(bufq->stream_id)) Loading @@ -806,7 +844,8 @@ static int msm_isp_buf_enqueue(struct msm_isp_buf_mgr *buf_mgr, rc = msm_isp_put_buf(buf_mgr, info->handle, info->buf_idx); if (rc < 0) { pr_err("%s: Buf put failed\n", __func__); pr_err("%s: Buf put failed stream %x\n", __func__, bufq->stream_id); return rc; } } Loading Loading @@ -836,7 +875,8 @@ static int msm_isp_get_buf_src(struct msm_isp_buf_mgr *buf_mgr, bufq = msm_isp_get_bufq(buf_mgr, bufq_handle); if (!bufq) { pr_err("%s: Invalid bufq\n", __func__); pr_err("%s: Invalid bufq\n", __func__); return -EINVAL; } *buf_src = BUF_SRC(bufq->stream_id); Loading Loading @@ -865,7 +905,9 @@ static int msm_isp_request_bufq(struct msm_isp_buf_mgr *buf_mgr, bufq = msm_isp_get_bufq(buf_mgr, buf_request->handle); if (!bufq) { pr_err("Invalid buffer queue\n"); pr_err("%s: Invalid bufq stream_id %x\n", __func__, buf_request->stream_id); return rc; } Loading Loading @@ -1194,6 +1236,7 @@ static struct msm_isp_buf_ops isp_buf_ops = { .buf_mgr_deinit = msm_isp_deinit_isp_buf_mgr, .buf_mgr_debug = msm_isp_buf_mgr_debug, .get_bufq = msm_isp_get_bufq, .update_put_buf_cnt = msm_isp_update_put_buf_cnt, }; int msm_isp_create_isp_buf_mgr( Loading drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h +2 −0 Original line number Diff line number Diff line Loading @@ -152,6 +152,8 @@ struct msm_isp_buf_ops { int (*buf_mgr_debug) (struct msm_isp_buf_mgr *buf_mgr); struct msm_isp_bufq * (*get_bufq)(struct msm_isp_buf_mgr *buf_mgr, uint32_t bufq_handle); int (*update_put_buf_cnt)(struct msm_isp_buf_mgr *buf_mgr, uint32_t bufq_handle, uint32_t buf_index); }; struct msm_isp_buf_mgr { Loading drivers/media/platform/msm/camera_v2/isp/msm_isp.h +3 −1 Original line number Diff line number Diff line /* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. /* Copyright (c) 2013-2015, 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 Loading Loading @@ -350,6 +350,7 @@ struct msm_vfe_axi_stream { uint8_t runtime_framedrop_update_burst; uint32_t runtime_output_format; enum msm_stream_memory_input_t memory_input; struct msm_isp_sw_framskip sw_skip; }; struct msm_vfe_axi_composite_info { Loading Loading @@ -434,6 +435,7 @@ struct msm_vfe_stats_stream { uint32_t framedrop_period; uint32_t irq_subsample_pattern; uint32_t init_stats_frame_drop; struct msm_isp_sw_framskip sw_skip; uint32_t buffer_offset; struct msm_isp_buffer *buf[2]; Loading drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c +81 −5 Original line number Diff line number Diff line /* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. /* Copyright (c) 2013-2015, 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 Loading Loading @@ -1044,27 +1044,48 @@ static void msm_isp_process_done_buf(struct vfe_device *vfe_dev, struct msm_isp_timestamp *ts) { int rc; unsigned long flags; struct msm_isp_event_data buf_event; struct timeval *time_stamp; uint32_t stream_idx = HANDLE_TO_IDX(stream_info->stream_handle); uint32_t frame_id; uint32_t buf_src; uint8_t drop_frame = 0; memset(&buf_event, 0, sizeof(buf_event)); frame_id = vfe_dev->axi_data. src_info[SRC_TO_INTF(stream_info->stream_src)].frame_id; if (SRC_TO_INTF(stream_info->stream_src) >= VFE_SRC_MAX) { pr_err("%s: Invalid stream index, put buf back to vb2 queue\n", __func__); vfe_dev->buf_mgr->ops->put_buf(vfe_dev->buf_mgr, rc = vfe_dev->buf_mgr->ops->put_buf(vfe_dev->buf_mgr, buf->bufq_handle, buf->buf_idx); return; } if (stream_info->stream_type != BURST_STREAM && (stream_info->sw_skip.stream_src_mask & (1 << stream_info->stream_src))) { /* Hw stream output of this src is requested for drop */ if (stream_info->sw_skip.skip_mode == SKIP_ALL) { /* drop all buffers */ drop_frame = 1; } else if (stream_info->sw_skip.skip_mode == SKIP_RANGE && (stream_info->sw_skip.min_frame_id <= frame_id && stream_info->sw_skip.max_frame_id >= frame_id)) { drop_frame = 1; } else if (frame_id > stream_info->sw_skip.max_frame_id) { spin_lock_irqsave(&stream_info->lock, flags); memset(&stream_info->sw_skip, 0, sizeof(struct msm_isp_sw_framskip)); spin_unlock_irqrestore(&stream_info->lock, flags); } } if (!buf || !ts) return; frame_id = vfe_dev->axi_data. src_info[SRC_TO_INTF(stream_info->stream_src)].frame_id; if (vfe_dev->vt_enable) { msm_isp_get_avtimer_ts(ts); time_stamp = &ts->vt_time; Loading @@ -1086,6 +1107,20 @@ static void msm_isp_process_done_buf(struct vfe_device *vfe_dev, if (rc) return; if (drop_frame) { /* Put but if dual vfe usecase and * both vfe have done using buf */ rc = vfe_dev->buf_mgr->ops->put_buf(vfe_dev->buf_mgr, buf->bufq_handle, buf->buf_idx); if (!rc) { ISP_DBG("%s:%d] vfe_id %d Buffer dropped %d\n", __func__, __LINE__, vfe_dev->pdev->id, frame_id); return; } } buf_event.input_intf = SRC_TO_INTF(stream_info->stream_src); buf_event.frame_id = frame_id; buf_event.timestamp = *time_stamp; Loading @@ -1098,6 +1133,28 @@ static void msm_isp_process_done_buf(struct vfe_device *vfe_dev, msm_isp_send_event(vfe_dev, ISP_EVENT_BUF_DIVERT + stream_idx, &buf_event); } else { rc = vfe_dev->buf_mgr->ops->update_put_buf_cnt(vfe_dev->buf_mgr, buf->bufq_handle, buf->buf_idx); /* Buf done state return value represent whether the buf * can be dispatched. A positive return value means * other ISP hardware is still processing the frame. */ if (rc) return; if (drop_frame) { /* Put but if dual vfe usecase and * both vfe have done using buf */ rc = vfe_dev->buf_mgr->ops->put_buf(vfe_dev->buf_mgr, buf->bufq_handle, buf->buf_idx); if (!rc) { ISP_DBG("%s:%d] vfe_id %d Buffer dropped %d\n", __func__, __LINE__, vfe_dev->pdev->id, frame_id); return; } } buf_event.input_intf = SRC_TO_INTF(stream_info->stream_src); buf_event.frame_id = frame_id; buf_event.timestamp = ts->buf_time; Loading Loading @@ -1824,6 +1881,8 @@ int msm_isp_update_axi_stream(struct vfe_device *vfe_dev, void *arg) struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; struct msm_vfe_axi_stream_update_cmd *update_cmd = arg; struct msm_vfe_axi_stream_cfg_update_info *update_info; struct msm_isp_sw_framskip *sw_skip_info = NULL; unsigned long flags; /*num_stream is uint32 and update_info[] bound by MAX_NUM_STREAM*/ if (update_cmd->num_streams > MAX_NUM_STREAM) Loading Loading @@ -1889,6 +1948,23 @@ int msm_isp_update_axi_stream(struct vfe_device *vfe_dev, void *arg) } break; } case UPDATE_STREAM_SW_FRAME_DROP: { sw_skip_info = &update_info->sw_skip_info; if (sw_skip_info->stream_src_mask != 0) { /* SW image buffer drop */ pr_debug("%s:%x sw skip type %x mode %d min %d max %d\n", __func__, stream_info->stream_id, sw_skip_info->stats_type_mask, sw_skip_info->skip_mode, sw_skip_info->min_frame_id, sw_skip_info->max_frame_id); spin_lock_irqsave(&stream_info->lock, flags); stream_info->sw_skip = *sw_skip_info; spin_unlock_irqrestore(&stream_info->lock, flags); } break; } case UPDATE_STREAM_AXI_CONFIG: { for (j = 0; j < stream_info->num_planes; j++) { stream_info->plane_cfg[j] = Loading drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c +50 −7 Original line number Diff line number Diff line /* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. /* Copyright (c) 2013-2015, 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 Loading Loading @@ -73,8 +73,9 @@ static int32_t msm_isp_stats_buf_divert(struct vfe_device *vfe_dev, struct msm_vfe_stats_stream *stream_info, uint32_t *comp_stats_type_mask) { int32_t rc = 0; int32_t rc = 0, frame_id = 0, drop_buffer = 0; struct msm_isp_stats_event *stats_event = NULL; struct msm_isp_sw_framskip *sw_skip = NULL; if (!vfe_dev || !done_buf || !ts || !buf_event || !stream_info || !comp_stats_type_mask) { Loading @@ -83,16 +84,40 @@ static int32_t msm_isp_stats_buf_divert(struct vfe_device *vfe_dev, stream_info, comp_stats_type_mask); return -EINVAL; } frame_id = vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id; sw_skip = &stream_info->sw_skip; stats_event = &buf_event->u.stats; if (sw_skip->stats_type_mask & (1 << stream_info->stats_type)) { /* Hw stream output of this src is requested for drop */ if (sw_skip->skip_mode == SKIP_ALL) { /* drop all buffers */ drop_buffer = 1; } else if (sw_skip->skip_mode == SKIP_RANGE && (sw_skip->min_frame_id <= frame_id && sw_skip->max_frame_id >= frame_id)) { drop_buffer = 1; } else if (frame_id > sw_skip->max_frame_id) { memset(sw_skip, 0, sizeof (struct msm_isp_sw_framskip)); } } rc = vfe_dev->buf_mgr->ops->buf_divert( vfe_dev->buf_mgr, done_buf->bufq_handle, done_buf->buf_idx, &ts->buf_time, vfe_dev->axi_data. src_info[VFE_PIX_0].frame_id); frame_id); if (rc != 0) return rc; if (drop_buffer) { vfe_dev->buf_mgr->ops->put_buf( vfe_dev->buf_mgr, done_buf->bufq_handle, done_buf->buf_idx); return rc; } stats_event->stats_buf_idxs [stream_info->stats_type] = done_buf->buf_idx; Loading Loading @@ -135,7 +160,6 @@ static int32_t msm_isp_stats_configure(struct vfe_device *vfe_dev, for (i = 0; i < vfe_dev->hw_info->stats_hw_info->num_stats_type; i++) { if (!(stats_irq_mask & (1 << i))) continue; stream_info = &vfe_dev->stats_data.stream_info[i]; done_buf = NULL; msm_isp_stats_cfg_ping_pong_address(vfe_dev, Loading Loading @@ -673,6 +697,7 @@ int msm_isp_update_stats_stream(struct vfe_device *vfe_dev, void *arg) struct msm_vfe_stats_shared_data *stats_data = &vfe_dev->stats_data; struct msm_vfe_axi_stream_update_cmd *update_cmd = arg; struct msm_vfe_axi_stream_cfg_update_info *update_info = NULL; struct msm_isp_sw_framskip *sw_skip_info = NULL; /*validate request*/ for (i = 0; i < update_cmd->num_streams; i++) { Loading Loading @@ -713,6 +738,24 @@ int msm_isp_update_stats_stream(struct vfe_device *vfe_dev, void *arg) vfe_dev, stream_info); break; } case UPDATE_STREAM_SW_FRAME_DROP: { sw_skip_info = &update_info->sw_skip_info; if (!stream_info->sw_skip.stream_src_mask) stream_info->sw_skip = *sw_skip_info; if (sw_skip_info->stats_type_mask != 0) { /* No image buffer skip, only stats skip */ pr_debug("%s:%x skip type %x mode %d min %d max %d\n", __func__, stream_info->stream_id, sw_skip_info->stats_type_mask, sw_skip_info->skip_mode, sw_skip_info->min_frame_id, sw_skip_info->max_frame_id); stream_info->sw_skip.stats_type_mask = sw_skip_info->stats_type_mask; } break; } default: pr_err("%s: Invalid update type\n", __func__); Loading Loading
drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c +51 −8 Original line number Diff line number Diff line Loading @@ -238,7 +238,8 @@ static int msm_isp_buf_prepare(struct msm_isp_buf_mgr *buf_mgr, bufq = msm_isp_get_bufq(buf_mgr, buf_info->bufq_handle); if (!bufq) { pr_err("%s: Invalid bufq\n", __func__); pr_err("%s: Invalid bufq\n", __func__); return rc; } Loading Loading @@ -610,9 +611,8 @@ static int msm_isp_put_buf_unsafe(struct msm_isp_buf_mgr *buf_mgr, return rc; } static int msm_isp_buf_done(struct msm_isp_buf_mgr *buf_mgr, uint32_t bufq_handle, uint32_t buf_index, struct timeval *tv, uint32_t frame_id, uint32_t output_format) static int msm_isp_update_put_buf_cnt(struct msm_isp_buf_mgr *buf_mgr, uint32_t bufq_handle, uint32_t buf_index) { int rc = -1; unsigned long flags; Loading Loading @@ -647,6 +647,41 @@ static int msm_isp_buf_done(struct msm_isp_buf_mgr *buf_mgr, return rc; } } spin_unlock_irqrestore(&bufq->bufq_lock, flags); } return 0; } static int msm_isp_buf_done(struct msm_isp_buf_mgr *buf_mgr, uint32_t bufq_handle, uint32_t buf_index, struct timeval *tv, uint32_t frame_id, uint32_t output_format) { int rc = -1; unsigned long flags; struct msm_isp_bufq *bufq = NULL; struct msm_isp_buffer *buf_info = NULL; enum msm_isp_buffer_state state; bufq = msm_isp_get_bufq(buf_mgr, bufq_handle); if (!bufq) { pr_err("Invalid bufq\n"); return rc; } buf_info = msm_isp_get_buf_ptr(buf_mgr, bufq_handle, buf_index); if (!buf_info) { pr_err("%s: buf not found\n", __func__); return rc; } spin_lock_irqsave(&bufq->bufq_lock, flags); state = buf_info->state; spin_unlock_irqrestore(&bufq->bufq_lock, flags); if (state == MSM_ISP_BUFFER_STATE_DEQUEUED || state == MSM_ISP_BUFFER_STATE_DIVERTED) { spin_lock_irqsave(&bufq->bufq_lock, flags); buf_info->state = MSM_ISP_BUFFER_STATE_DISPATCHED; spin_unlock_irqrestore(&bufq->bufq_lock, flags); if (MSM_ISP_BUFFER_SRC_HAL == BUF_SRC(bufq->stream_id)) { Loading @@ -656,6 +691,8 @@ static int msm_isp_buf_done(struct msm_isp_buf_mgr *buf_mgr, buf_mgr->vb2_ops->buf_done(buf_info->vb2_buf, bufq->session_id, bufq->stream_id); } else { pr_err("%s: Error wrong buf done %d\n", __func__, state); rc = msm_isp_put_buf(buf_mgr, buf_info->bufq_handle, buf_info->buf_idx); if (rc < 0) { Loading Loading @@ -785,7 +822,8 @@ static int msm_isp_buf_enqueue(struct msm_isp_buf_mgr *buf_mgr, } else { bufq = msm_isp_get_bufq(buf_mgr, info->handle); if (!bufq) { pr_err("%s: Invalid bufq\n", __func__); pr_err("%s: Invalid bufq\n", __func__); return rc; } if (BUF_SRC(bufq->stream_id)) Loading @@ -806,7 +844,8 @@ static int msm_isp_buf_enqueue(struct msm_isp_buf_mgr *buf_mgr, rc = msm_isp_put_buf(buf_mgr, info->handle, info->buf_idx); if (rc < 0) { pr_err("%s: Buf put failed\n", __func__); pr_err("%s: Buf put failed stream %x\n", __func__, bufq->stream_id); return rc; } } Loading Loading @@ -836,7 +875,8 @@ static int msm_isp_get_buf_src(struct msm_isp_buf_mgr *buf_mgr, bufq = msm_isp_get_bufq(buf_mgr, bufq_handle); if (!bufq) { pr_err("%s: Invalid bufq\n", __func__); pr_err("%s: Invalid bufq\n", __func__); return -EINVAL; } *buf_src = BUF_SRC(bufq->stream_id); Loading Loading @@ -865,7 +905,9 @@ static int msm_isp_request_bufq(struct msm_isp_buf_mgr *buf_mgr, bufq = msm_isp_get_bufq(buf_mgr, buf_request->handle); if (!bufq) { pr_err("Invalid buffer queue\n"); pr_err("%s: Invalid bufq stream_id %x\n", __func__, buf_request->stream_id); return rc; } Loading Loading @@ -1194,6 +1236,7 @@ static struct msm_isp_buf_ops isp_buf_ops = { .buf_mgr_deinit = msm_isp_deinit_isp_buf_mgr, .buf_mgr_debug = msm_isp_buf_mgr_debug, .get_bufq = msm_isp_get_bufq, .update_put_buf_cnt = msm_isp_update_put_buf_cnt, }; int msm_isp_create_isp_buf_mgr( Loading
drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h +2 −0 Original line number Diff line number Diff line Loading @@ -152,6 +152,8 @@ struct msm_isp_buf_ops { int (*buf_mgr_debug) (struct msm_isp_buf_mgr *buf_mgr); struct msm_isp_bufq * (*get_bufq)(struct msm_isp_buf_mgr *buf_mgr, uint32_t bufq_handle); int (*update_put_buf_cnt)(struct msm_isp_buf_mgr *buf_mgr, uint32_t bufq_handle, uint32_t buf_index); }; struct msm_isp_buf_mgr { Loading
drivers/media/platform/msm/camera_v2/isp/msm_isp.h +3 −1 Original line number Diff line number Diff line /* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. /* Copyright (c) 2013-2015, 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 Loading Loading @@ -350,6 +350,7 @@ struct msm_vfe_axi_stream { uint8_t runtime_framedrop_update_burst; uint32_t runtime_output_format; enum msm_stream_memory_input_t memory_input; struct msm_isp_sw_framskip sw_skip; }; struct msm_vfe_axi_composite_info { Loading Loading @@ -434,6 +435,7 @@ struct msm_vfe_stats_stream { uint32_t framedrop_period; uint32_t irq_subsample_pattern; uint32_t init_stats_frame_drop; struct msm_isp_sw_framskip sw_skip; uint32_t buffer_offset; struct msm_isp_buffer *buf[2]; Loading
drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c +81 −5 Original line number Diff line number Diff line /* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. /* Copyright (c) 2013-2015, 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 Loading Loading @@ -1044,27 +1044,48 @@ static void msm_isp_process_done_buf(struct vfe_device *vfe_dev, struct msm_isp_timestamp *ts) { int rc; unsigned long flags; struct msm_isp_event_data buf_event; struct timeval *time_stamp; uint32_t stream_idx = HANDLE_TO_IDX(stream_info->stream_handle); uint32_t frame_id; uint32_t buf_src; uint8_t drop_frame = 0; memset(&buf_event, 0, sizeof(buf_event)); frame_id = vfe_dev->axi_data. src_info[SRC_TO_INTF(stream_info->stream_src)].frame_id; if (SRC_TO_INTF(stream_info->stream_src) >= VFE_SRC_MAX) { pr_err("%s: Invalid stream index, put buf back to vb2 queue\n", __func__); vfe_dev->buf_mgr->ops->put_buf(vfe_dev->buf_mgr, rc = vfe_dev->buf_mgr->ops->put_buf(vfe_dev->buf_mgr, buf->bufq_handle, buf->buf_idx); return; } if (stream_info->stream_type != BURST_STREAM && (stream_info->sw_skip.stream_src_mask & (1 << stream_info->stream_src))) { /* Hw stream output of this src is requested for drop */ if (stream_info->sw_skip.skip_mode == SKIP_ALL) { /* drop all buffers */ drop_frame = 1; } else if (stream_info->sw_skip.skip_mode == SKIP_RANGE && (stream_info->sw_skip.min_frame_id <= frame_id && stream_info->sw_skip.max_frame_id >= frame_id)) { drop_frame = 1; } else if (frame_id > stream_info->sw_skip.max_frame_id) { spin_lock_irqsave(&stream_info->lock, flags); memset(&stream_info->sw_skip, 0, sizeof(struct msm_isp_sw_framskip)); spin_unlock_irqrestore(&stream_info->lock, flags); } } if (!buf || !ts) return; frame_id = vfe_dev->axi_data. src_info[SRC_TO_INTF(stream_info->stream_src)].frame_id; if (vfe_dev->vt_enable) { msm_isp_get_avtimer_ts(ts); time_stamp = &ts->vt_time; Loading @@ -1086,6 +1107,20 @@ static void msm_isp_process_done_buf(struct vfe_device *vfe_dev, if (rc) return; if (drop_frame) { /* Put but if dual vfe usecase and * both vfe have done using buf */ rc = vfe_dev->buf_mgr->ops->put_buf(vfe_dev->buf_mgr, buf->bufq_handle, buf->buf_idx); if (!rc) { ISP_DBG("%s:%d] vfe_id %d Buffer dropped %d\n", __func__, __LINE__, vfe_dev->pdev->id, frame_id); return; } } buf_event.input_intf = SRC_TO_INTF(stream_info->stream_src); buf_event.frame_id = frame_id; buf_event.timestamp = *time_stamp; Loading @@ -1098,6 +1133,28 @@ static void msm_isp_process_done_buf(struct vfe_device *vfe_dev, msm_isp_send_event(vfe_dev, ISP_EVENT_BUF_DIVERT + stream_idx, &buf_event); } else { rc = vfe_dev->buf_mgr->ops->update_put_buf_cnt(vfe_dev->buf_mgr, buf->bufq_handle, buf->buf_idx); /* Buf done state return value represent whether the buf * can be dispatched. A positive return value means * other ISP hardware is still processing the frame. */ if (rc) return; if (drop_frame) { /* Put but if dual vfe usecase and * both vfe have done using buf */ rc = vfe_dev->buf_mgr->ops->put_buf(vfe_dev->buf_mgr, buf->bufq_handle, buf->buf_idx); if (!rc) { ISP_DBG("%s:%d] vfe_id %d Buffer dropped %d\n", __func__, __LINE__, vfe_dev->pdev->id, frame_id); return; } } buf_event.input_intf = SRC_TO_INTF(stream_info->stream_src); buf_event.frame_id = frame_id; buf_event.timestamp = ts->buf_time; Loading Loading @@ -1824,6 +1881,8 @@ int msm_isp_update_axi_stream(struct vfe_device *vfe_dev, void *arg) struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; struct msm_vfe_axi_stream_update_cmd *update_cmd = arg; struct msm_vfe_axi_stream_cfg_update_info *update_info; struct msm_isp_sw_framskip *sw_skip_info = NULL; unsigned long flags; /*num_stream is uint32 and update_info[] bound by MAX_NUM_STREAM*/ if (update_cmd->num_streams > MAX_NUM_STREAM) Loading Loading @@ -1889,6 +1948,23 @@ int msm_isp_update_axi_stream(struct vfe_device *vfe_dev, void *arg) } break; } case UPDATE_STREAM_SW_FRAME_DROP: { sw_skip_info = &update_info->sw_skip_info; if (sw_skip_info->stream_src_mask != 0) { /* SW image buffer drop */ pr_debug("%s:%x sw skip type %x mode %d min %d max %d\n", __func__, stream_info->stream_id, sw_skip_info->stats_type_mask, sw_skip_info->skip_mode, sw_skip_info->min_frame_id, sw_skip_info->max_frame_id); spin_lock_irqsave(&stream_info->lock, flags); stream_info->sw_skip = *sw_skip_info; spin_unlock_irqrestore(&stream_info->lock, flags); } break; } case UPDATE_STREAM_AXI_CONFIG: { for (j = 0; j < stream_info->num_planes; j++) { stream_info->plane_cfg[j] = Loading
drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c +50 −7 Original line number Diff line number Diff line /* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. /* Copyright (c) 2013-2015, 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 Loading Loading @@ -73,8 +73,9 @@ static int32_t msm_isp_stats_buf_divert(struct vfe_device *vfe_dev, struct msm_vfe_stats_stream *stream_info, uint32_t *comp_stats_type_mask) { int32_t rc = 0; int32_t rc = 0, frame_id = 0, drop_buffer = 0; struct msm_isp_stats_event *stats_event = NULL; struct msm_isp_sw_framskip *sw_skip = NULL; if (!vfe_dev || !done_buf || !ts || !buf_event || !stream_info || !comp_stats_type_mask) { Loading @@ -83,16 +84,40 @@ static int32_t msm_isp_stats_buf_divert(struct vfe_device *vfe_dev, stream_info, comp_stats_type_mask); return -EINVAL; } frame_id = vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id; sw_skip = &stream_info->sw_skip; stats_event = &buf_event->u.stats; if (sw_skip->stats_type_mask & (1 << stream_info->stats_type)) { /* Hw stream output of this src is requested for drop */ if (sw_skip->skip_mode == SKIP_ALL) { /* drop all buffers */ drop_buffer = 1; } else if (sw_skip->skip_mode == SKIP_RANGE && (sw_skip->min_frame_id <= frame_id && sw_skip->max_frame_id >= frame_id)) { drop_buffer = 1; } else if (frame_id > sw_skip->max_frame_id) { memset(sw_skip, 0, sizeof (struct msm_isp_sw_framskip)); } } rc = vfe_dev->buf_mgr->ops->buf_divert( vfe_dev->buf_mgr, done_buf->bufq_handle, done_buf->buf_idx, &ts->buf_time, vfe_dev->axi_data. src_info[VFE_PIX_0].frame_id); frame_id); if (rc != 0) return rc; if (drop_buffer) { vfe_dev->buf_mgr->ops->put_buf( vfe_dev->buf_mgr, done_buf->bufq_handle, done_buf->buf_idx); return rc; } stats_event->stats_buf_idxs [stream_info->stats_type] = done_buf->buf_idx; Loading Loading @@ -135,7 +160,6 @@ static int32_t msm_isp_stats_configure(struct vfe_device *vfe_dev, for (i = 0; i < vfe_dev->hw_info->stats_hw_info->num_stats_type; i++) { if (!(stats_irq_mask & (1 << i))) continue; stream_info = &vfe_dev->stats_data.stream_info[i]; done_buf = NULL; msm_isp_stats_cfg_ping_pong_address(vfe_dev, Loading Loading @@ -673,6 +697,7 @@ int msm_isp_update_stats_stream(struct vfe_device *vfe_dev, void *arg) struct msm_vfe_stats_shared_data *stats_data = &vfe_dev->stats_data; struct msm_vfe_axi_stream_update_cmd *update_cmd = arg; struct msm_vfe_axi_stream_cfg_update_info *update_info = NULL; struct msm_isp_sw_framskip *sw_skip_info = NULL; /*validate request*/ for (i = 0; i < update_cmd->num_streams; i++) { Loading Loading @@ -713,6 +738,24 @@ int msm_isp_update_stats_stream(struct vfe_device *vfe_dev, void *arg) vfe_dev, stream_info); break; } case UPDATE_STREAM_SW_FRAME_DROP: { sw_skip_info = &update_info->sw_skip_info; if (!stream_info->sw_skip.stream_src_mask) stream_info->sw_skip = *sw_skip_info; if (sw_skip_info->stats_type_mask != 0) { /* No image buffer skip, only stats skip */ pr_debug("%s:%x skip type %x mode %d min %d max %d\n", __func__, stream_info->stream_id, sw_skip_info->stats_type_mask, sw_skip_info->skip_mode, sw_skip_info->min_frame_id, sw_skip_info->max_frame_id); stream_info->sw_skip.stats_type_mask = sw_skip_info->stats_type_mask; } break; } default: pr_err("%s: Invalid update type\n", __func__); Loading