Loading drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c +95 −243 Original line number Diff line number Diff line Loading @@ -75,31 +75,6 @@ static int msm_buf_check_head_sanity(struct msm_isp_bufq *bufq) return -EINVAL; } prev = bufq->share_head.prev; next = bufq->share_head.next; if (!prev) { pr_err("%s: Error! bufq->share_head.prev is NULL\n", __func__); return -EINVAL; } if (!next) { pr_err("%s: Error! bufq->share_head.next is NULL\n", __func__); return -EINVAL; } if (prev->next != &bufq->share_head) { pr_err("%s: Error! share_head prev->next is %p should be %p\n", __func__, prev->next, &bufq->share_head); return -EINVAL; } if (next->prev != &bufq->share_head) { pr_err("%s: Error! share_head next->prev is %p should be %p\n", __func__, next->prev, &bufq->share_head); return -EINVAL; } return rc; } Loading Loading @@ -187,9 +162,7 @@ static int msm_isp_free_bufq_handle(struct msm_isp_buf_mgr *buf_mgr, bufq->stream_id = 0; bufq->num_bufs = 0; bufq->buf_type = 0; memset(&bufq->head, 0, sizeof(bufq->head)); memset(&bufq->share_head, 0, sizeof(bufq->share_head)); bufq->buf_client_count = 0; INIT_LIST_HEAD(&bufq->head); return 0; } Loading Loading @@ -487,27 +460,12 @@ static int msm_isp_buf_unprepare(struct msm_isp_buf_mgr *buf_mgr, return 0; } static void msm_isp_debug_list(struct msm_isp_bufq *bufq, struct msm_isp_buffer *buf_info) { int i = 0; pr_err("%s: stream_id %x buf_info last_put_id = %d\n", __func__, bufq->stream_id, buf_info->buf_debug.put_state_last); for (i = 0; i < 2; i++) { pr_err("%s i %d put_state %d\n", __func__, i, buf_info->buf_debug.put_state[i]); } } static int msm_isp_get_buf(struct msm_isp_buf_mgr *buf_mgr, uint32_t id, uint32_t bufq_handle, struct msm_isp_buffer **buf_info, uint32_t *buf_cnt) uint32_t bufq_handle, struct msm_isp_buffer **buf_info) { int rc = -1; unsigned long flags; unsigned int list_count = 0; struct msm_isp_buffer *temp_buf_info = NULL; struct msm_isp_bufq *bufq = NULL; struct vb2_buffer *vb2_buf = NULL; Loading @@ -532,52 +490,6 @@ static int msm_isp_get_buf(struct msm_isp_buf_mgr *buf_mgr, uint32_t id, } *buf_info = NULL; *buf_cnt = 0; if (bufq->buf_type == ISP_SHARE_BUF) { if (msm_buf_check_head_sanity(bufq) < 0) { spin_unlock_irqrestore(&bufq->bufq_lock, flags); WARN(1, "%s buf_handle 0x%x is in bad state\n", __func__, bufq->bufq_handle); return -EFAULT; } list_count = 0; list_for_each_entry(temp_buf_info, &bufq->share_head, share_list) { if ((temp_buf_info->get_buf_mask & (1 << id)) == 0) { temp_buf_info->get_buf_mask |= (1 << id); temp_buf_info->buf_get_count++; *buf_cnt = temp_buf_info->buf_get_count; if (temp_buf_info->buf_get_count == bufq->buf_client_count) { list_del_init( &temp_buf_info->share_list); } if (temp_buf_info->buf_reuse_flag) { kfree(temp_buf_info); } else { *buf_info = temp_buf_info; rc = 0; } spin_unlock_irqrestore( &bufq->bufq_lock, flags); return rc; } else if ((temp_buf_info->get_buf_mask & (1 << id)) && temp_buf_info->buf_reuse_flag) { spin_unlock_irqrestore( &bufq->bufq_lock, flags); return rc; } list_count++; if (list_count > MAX_LIST_COUNT) { pr_err_ratelimited("%s: %d share_list corruption, list corrupt! count = %d\n", __func__, __LINE__, list_count); spin_unlock_irqrestore( &bufq->bufq_lock, flags); return -EINVAL; } } } switch (BUF_SRC(bufq->stream_id)) { case MSM_ISP_BUFFER_SRC_NATIVE: Loading @@ -588,11 +500,10 @@ static int msm_isp_get_buf(struct msm_isp_buf_mgr *buf_mgr, uint32_t id, if (msm_buf_check_head_sanity(bufq) < 0) { spin_unlock_irqrestore( &bufq->bufq_lock, flags); WARN(1, "%s buf_handle 0x%x buf_idx %d buf_reuse_flag %d\n", WARN(1, "%s buf_handle 0x%x buf_idx %d\n", __func__, bufq->bufq_handle, temp_buf_info->buf_idx, temp_buf_info->buf_reuse_flag); temp_buf_info->buf_idx); return -EFAULT; } *buf_info = temp_buf_info; Loading Loading @@ -641,68 +552,9 @@ static int msm_isp_get_buf(struct msm_isp_buf_mgr *buf_mgr, uint32_t id, } if (!(*buf_info)) { if (bufq->buf_type == ISP_SHARE_BUF) { temp_buf_info = kzalloc( sizeof(struct msm_isp_buffer), GFP_ATOMIC); if (temp_buf_info) { temp_buf_info->buf_reuse_flag = 1; temp_buf_info->get_buf_mask |= (1 << id); temp_buf_info->buf_get_count = 1; list_add_tail(&temp_buf_info->share_list, &bufq->share_head); if (msm_buf_check_head_sanity(bufq) < 0) { spin_unlock_irqrestore( &bufq->bufq_lock, flags); WARN(1, "%s buf_handle 0x%x buf_idx %d buf_reuse_flag %d\n", __func__, bufq->bufq_handle, temp_buf_info->buf_idx, temp_buf_info->buf_reuse_flag); return -EFAULT; } } else rc = -ENOMEM; } } else { (*buf_info)->state = MSM_ISP_BUFFER_STATE_DEQUEUED; if (bufq->buf_type == ISP_SHARE_BUF) { list_for_each_entry(temp_buf_info, &bufq->share_head, share_list) { if (temp_buf_info->buf_idx == (*buf_info)->buf_idx) { msm_isp_debug_list(bufq, temp_buf_info); spin_unlock_irqrestore( &bufq->bufq_lock, flags); WARN(1, "%s ERROR! Double ADD found\n", __func__); return -EFAULT; } } (*buf_info)->get_buf_mask = (1 << id); (*buf_info)->buf_get_count = 1; (*buf_info)->buf_put_count = 0; (*buf_info)->put_buf_mask = 0; (*buf_info)->buf_reuse_flag = 0; if (!list_empty(&(*buf_info)->share_list)) { spin_unlock_irqrestore(&bufq->bufq_lock, flags); WARN(1, "%s: buf %x/%x double add\n", __func__, bufq_handle, (*buf_info)->buf_idx); return -EFAULT; } list_add_tail(&(*buf_info)->share_list, &bufq->share_head); if (msm_buf_check_head_sanity(bufq) < 0) { spin_unlock_irqrestore(&bufq->bufq_lock, flags); WARN(1, "%s buf_handle 0x%x buf_idx %d buf_reuse_flag %d\n", __func__, bufq->bufq_handle, (*buf_info)->buf_idx, (*buf_info)->buf_reuse_flag); return -EFAULT; } } rc = 0; } spin_unlock_irqrestore(&bufq->bufq_lock, flags); Loading Loading @@ -730,6 +582,7 @@ static int msm_isp_put_buf_unsafe(struct msm_isp_buf_mgr *buf_mgr, switch (buf_info->state) { case MSM_ISP_BUFFER_STATE_PREPARED: case MSM_ISP_BUFFER_STATE_DEQUEUED: if (BUF_SRC(bufq->stream_id)) { if (!list_empty(&buf_info->list)) { WARN(1, "%s: buf %x/%x double add\n", Loading @@ -738,11 +591,10 @@ static int msm_isp_put_buf_unsafe(struct msm_isp_buf_mgr *buf_mgr, } list_add_tail(&buf_info->list, &bufq->head); if (msm_buf_check_head_sanity(bufq) < 0) { WARN(1, "%s buf_handle 0x%x buf_idx %d buf_reuse_flag %d\n", WARN(1, "%s buf_handle 0x%x buf_idx %d\n", __func__, bufq->bufq_handle, buf_info->buf_idx, buf_info->buf_reuse_flag); buf_info->buf_idx); return -EFAULT; } } else { Loading @@ -757,7 +609,6 @@ static int msm_isp_put_buf_unsafe(struct msm_isp_buf_mgr *buf_mgr, rc = 0; break; case MSM_ISP_BUFFER_STATE_QUEUED: case MSM_ISP_BUFFER_STATE_DEQUEUED: case MSM_ISP_BUFFER_STATE_DIVERTED: default: WARN(1, "%s: bufq 0x%x, buf idx 0x%x, incorrect state = %d", Loading Loading @@ -790,11 +641,6 @@ static int msm_isp_put_buf(struct msm_isp_buf_mgr *buf_mgr, spin_lock_irqsave(&bufq->bufq_lock, flags); buf_info->buf_get_count = 0; buf_info->buf_put_count = 0; buf_info->get_buf_mask = 0; buf_info->put_buf_mask = 0; rc = msm_isp_put_buf_unsafe(buf_mgr, bufq_handle, buf_index); spin_unlock_irqrestore(&bufq->bufq_lock, flags); Loading @@ -804,13 +650,13 @@ static int msm_isp_put_buf(struct msm_isp_buf_mgr *buf_mgr, static int msm_isp_update_put_buf_cnt_unsafe( struct msm_isp_buf_mgr *buf_mgr, uint32_t id, uint32_t bufq_handle, uint32_t buf_index, struct timeval *tv, uint32_t frame_id, unsigned long *flags) uint32_t id, uint32_t bufq_handle, int32_t buf_index, struct timeval *tv, uint32_t frame_id, uint32_t pingpong_bit) { int rc = -1; struct msm_isp_bufq *bufq = NULL; struct msm_isp_buffer *buf_info = NULL; enum msm_isp_buffer_state state; uint8_t *put_buf_mask = NULL; bufq = msm_isp_get_bufq(buf_mgr, bufq_handle); if (!bufq) { Loading @@ -818,38 +664,46 @@ static int msm_isp_update_put_buf_cnt_unsafe( return rc; } put_buf_mask = &bufq->put_buf_mask[pingpong_bit]; if (buf_index >= 0) { 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; return -EFAULT; } if (buf_info->state != MSM_ISP_BUFFER_STATE_DEQUEUED) { pr_err( "%s: Invalid state, bufq_handle %x stream id %x, state %d\n", __func__, bufq_handle, bufq->stream_id, buf_info->state); return -EFAULT; } BUG_ON(buf_info->pingpong_bit != pingpong_bit); } if (bufq->buf_type != ISP_SHARE_BUF || buf_info->put_buf_mask == 0) { (*put_buf_mask == 0)) { if (buf_info) buf_info->frame_id = frame_id; } state = buf_info->state; if (state == MSM_ISP_BUFFER_STATE_DEQUEUED) { if (bufq->buf_type == ISP_SHARE_BUF && ((buf_info->put_buf_mask & (1 << id)) == 0)) { buf_info->put_buf_mask |= (1 << id); buf_info->buf_put_count++; if (buf_info->buf_put_count != ISP_SHARE_BUF_CLIENT) { rc = buf_info->buf_put_count; return rc; } ((*put_buf_mask & (1 << id)) == 0)) { *put_buf_mask |= (1 << id); if (*put_buf_mask != ISP_SHARE_BUF_MASK) { rc = *put_buf_mask; return 1; } } else { pr_warn("%s: Invalid state, stream id %x, state %d\n", __func__, bufq->stream_id, state); spin_unlock_irqrestore(&bufq->bufq_lock, *flags); dump_stack(); spin_lock_irqsave(&bufq->bufq_lock, *flags); return rc; *put_buf_mask = 0; rc = 0; } else if (bufq->buf_type == ISP_SHARE_BUF && (*put_buf_mask & (1 << id)) != 0) { return -ENOTEMPTY; } if (MSM_ISP_BUFFER_SRC_NATIVE == BUF_SRC(bufq->stream_id)) { if (buf_info && MSM_ISP_BUFFER_SRC_NATIVE == BUF_SRC(bufq->stream_id)) { buf_info->state = MSM_ISP_BUFFER_STATE_DIVERTED; buf_info->tv = tv; } Loading @@ -857,8 +711,8 @@ static int msm_isp_update_put_buf_cnt_unsafe( } static int msm_isp_update_put_buf_cnt(struct msm_isp_buf_mgr *buf_mgr, uint32_t id, uint32_t bufq_handle, uint32_t buf_index, struct timeval *tv, uint32_t frame_id) uint32_t id, uint32_t bufq_handle, int32_t buf_index, struct timeval *tv, uint32_t frame_id, uint32_t pingpong_bit) { int rc = -1; struct msm_isp_bufq *bufq = NULL; Loading @@ -872,7 +726,12 @@ static int msm_isp_update_put_buf_cnt(struct msm_isp_buf_mgr *buf_mgr, spin_lock_irqsave(&bufq->bufq_lock, flags); rc = msm_isp_update_put_buf_cnt_unsafe(buf_mgr, id, bufq_handle, buf_index, tv, frame_id, &flags); buf_index, tv, frame_id, pingpong_bit); if (-ENOTEMPTY == rc) { pr_err("%s: Error! Uncleared put_buf_mask for pingpong(%d) from vfe %d bufq 0x%x buf_idx %d\n", __func__, pingpong_bit, id, bufq_handle, buf_index); rc = -EFAULT; } spin_unlock_irqrestore(&bufq->bufq_lock, flags); return rc; } Loading @@ -881,7 +740,7 @@ 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; int rc = 0; unsigned long flags; struct msm_isp_bufq *bufq = NULL; struct msm_isp_buffer *buf_info = NULL; Loading @@ -890,13 +749,13 @@ static int msm_isp_buf_done(struct msm_isp_buf_mgr *buf_mgr, bufq = msm_isp_get_bufq(buf_mgr, bufq_handle); if (!bufq) { pr_err("Invalid bufq\n"); return rc; return -EINVAL; } 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; return -EINVAL; } spin_lock_irqsave(&bufq->bufq_lock, flags); Loading Loading @@ -936,7 +795,7 @@ static int msm_isp_flush_buf(struct msm_isp_buf_mgr *buf_mgr, uint32_t id, uint32_t bufq_handle, enum msm_isp_buffer_flush_t flush_type, struct timeval *tv, uint32_t frame_id) { int rc = -1, i; int rc = 0, i; struct msm_isp_bufq *bufq = NULL; struct msm_isp_buffer *buf_info = NULL; unsigned long flags; Loading @@ -944,7 +803,7 @@ static int msm_isp_flush_buf(struct msm_isp_buf_mgr *buf_mgr, uint32_t id, bufq = msm_isp_get_bufq(buf_mgr, bufq_handle); if (!bufq) { pr_err("Invalid bufq\n"); return rc; return -EINVAL; } spin_lock_irqsave(&bufq->bufq_lock, flags); Loading @@ -965,40 +824,35 @@ static int msm_isp_flush_buf(struct msm_isp_buf_mgr *buf_mgr, uint32_t id, __func__); } else if (buf_info->state == MSM_ISP_BUFFER_STATE_DEQUEUED) { rc = msm_isp_update_put_buf_cnt_unsafe(buf_mgr, id, bufq_handle, buf_info->buf_idx, tv, frame_id, buf_info->pingpong_bit); if (-ENOTEMPTY == rc) { rc = 0; continue; } if (rc == 0) { buf_info->buf_debug.put_state[ buf_info->buf_debug.put_state_last] buf_info->buf_debug. put_state_last] = MSM_ISP_BUFFER_STATE_FLUSH; buf_info->buf_debug.put_state_last ^= 1; buf_info->state = MSM_ISP_BUFFER_STATE_PREPARED; buf_info->state = MSM_ISP_BUFFER_STATE_PREPARED; rc = msm_isp_put_buf_unsafe(buf_mgr, bufq_handle, buf_info->buf_idx); if (rc == -EFAULT) { spin_unlock_irqrestore(&bufq->bufq_lock, spin_unlock_irqrestore( &bufq->bufq_lock, flags); return rc; } } } } if (bufq->buf_type == ISP_SHARE_BUF) { while (!list_empty(&bufq->share_head)) { buf_info = list_entry((&bufq->share_head)->next, typeof(*buf_info), share_list); list_del_init(&(buf_info->share_list)); if (msm_buf_check_head_sanity(bufq) < 0) { spin_unlock_irqrestore(&bufq->bufq_lock, flags); WARN(1, "%s buf_handle 0x%x buf_idx %d buf_reuse_flag %d\n", __func__, bufq->bufq_handle, buf_info->buf_idx, buf_info->buf_reuse_flag); return -EFAULT; } if (buf_info->buf_reuse_flag) kfree(buf_info); } } spin_unlock_irqrestore(&bufq->bufq_lock, flags); return 0; } Loading @@ -1006,7 +860,7 @@ static int msm_isp_flush_buf(struct msm_isp_buf_mgr *buf_mgr, uint32_t id, static int msm_isp_buf_enqueue(struct msm_isp_buf_mgr *buf_mgr, struct msm_isp_qbuf_info *info) { int rc = -1, buf_state; int rc = 0, buf_state; struct msm_isp_bufq *bufq = NULL; struct msm_isp_buffer *buf_info = NULL; Loading @@ -1029,7 +883,7 @@ static int msm_isp_buf_enqueue(struct msm_isp_buf_mgr *buf_mgr, info->handle, info->buf_idx); if (!buf_info) { pr_err("%s: buf not found\n", __func__); return rc; return -EINVAL; } if (info->dirty_buf) { buf_info->buf_debug.put_state[ Loading Loading @@ -1059,7 +913,7 @@ static int msm_isp_buf_enqueue(struct msm_isp_buf_mgr *buf_mgr, info->handle, info->buf_idx); if (!buf_info) { pr_err("%s: buf not found\n", __func__); return rc; return -EINVAL; } buf_info->buf_debug.put_state[ Loading @@ -1075,7 +929,7 @@ static int msm_isp_buf_enqueue(struct msm_isp_buf_mgr *buf_mgr, } } } return rc; return 0; } static int msm_isp_buf_dequeue(struct msm_isp_buf_mgr *buf_mgr, Loading Loading @@ -1136,20 +990,20 @@ static int msm_isp_get_buf_src(struct msm_isp_buf_mgr *buf_mgr, static int msm_isp_request_bufq(struct msm_isp_buf_mgr *buf_mgr, struct msm_isp_buf_request *buf_request) { int rc = -1, i; int i; struct msm_isp_bufq *bufq = NULL; CDBG("%s: E\n", __func__); if (!buf_request->num_buf || buf_request->num_buf > VB2_MAX_FRAME) { pr_err("Invalid buffer request\n"); return rc; return -EINVAL; } buf_request->handle = msm_isp_get_buf_handle(buf_mgr, buf_request->session_id, buf_request->stream_id); if (!buf_request->handle) { pr_err("Invalid buffer handle\n"); return rc; return -EINVAL; } bufq = msm_isp_get_bufq(buf_mgr, buf_request->handle); Loading @@ -1157,7 +1011,7 @@ static int msm_isp_request_bufq(struct msm_isp_buf_mgr *buf_mgr, pr_err("%s: Invalid bufq stream_id %x\n", __func__, buf_request->stream_id); return rc; return -EINVAL; } bufq->bufs = kzalloc(sizeof(struct msm_isp_buffer) * Loading @@ -1165,7 +1019,7 @@ static int msm_isp_request_bufq(struct msm_isp_buf_mgr *buf_mgr, if (!bufq->bufs) { pr_err("No free memory for buf info\n"); msm_isp_free_bufq_handle(buf_mgr, buf_request->handle); return rc; return -ENOMEM; } spin_lock_init(&bufq->bufq_lock); bufq->bufq_handle = buf_request->handle; Loading @@ -1173,10 +1027,10 @@ static int msm_isp_request_bufq(struct msm_isp_buf_mgr *buf_mgr, bufq->stream_id = buf_request->stream_id; bufq->num_bufs = buf_request->num_buf; bufq->buf_type = buf_request->buf_type; if (bufq->buf_type == ISP_SHARE_BUF) bufq->buf_client_count = ISP_SHARE_BUF_CLIENT; for (i = 0; i < ISP_NUM_BUF_MASK; i++) bufq->put_buf_mask[i] = 0; INIT_LIST_HEAD(&bufq->head); INIT_LIST_HEAD(&bufq->share_head); for (i = 0; i < buf_request->num_buf; i++) { bufq->bufs[i].state = MSM_ISP_BUFFER_STATE_INITIALIZED; bufq->bufs[i].buf_debug.put_state[0] = Loading @@ -1187,7 +1041,6 @@ static int msm_isp_request_bufq(struct msm_isp_buf_mgr *buf_mgr, bufq->bufs[i].bufq_handle = bufq->bufq_handle; bufq->bufs[i].buf_idx = i; INIT_LIST_HEAD(&bufq->bufs[i].list); INIT_LIST_HEAD(&bufq->bufs[i].share_list); } return 0; Loading @@ -1198,11 +1051,10 @@ static int msm_isp_release_bufq(struct msm_isp_buf_mgr *buf_mgr, { struct msm_isp_bufq *bufq = NULL; unsigned long flags; int rc = -1; bufq = msm_isp_get_bufq(buf_mgr, bufq_handle); if (!bufq) { pr_err("Invalid bufq release\n"); return rc; return -EINVAL; } msm_isp_buf_unprepare_all(buf_mgr, bufq_handle); Loading drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h +12 −17 Original line number Diff line number Diff line Loading @@ -23,7 +23,12 @@ (id & ISP_NATIVE_BUF_BIT) ? MSM_ISP_BUFFER_SRC_NATIVE : \ MSM_ISP_BUFFER_SRC_HAL) #define ISP_SHARE_BUF_CLIENT 2 /* * This mask can be set dynamically if there are more than 2 VFE *.and 2 of those are used */ #define ISP_SHARE_BUF_MASK 0x3 #define ISP_NUM_BUF_MASK 2 #define BUF_MGR_NUM_BUF_Q 28 #define MAX_IOMMU_CTX 2 Loading Loading @@ -89,6 +94,8 @@ struct msm_isp_buffer { uint32_t bufq_handle; uint32_t frame_id; struct timeval *tv; /* Indicates whether buffer is used as ping ot pong buffer */ uint32_t pingpong_bit; /*Native buffer*/ struct list_head list; Loading @@ -98,14 +105,6 @@ struct msm_isp_buffer { /*Vb2 buffer data*/ struct vb2_buffer *vb2_buf; /*Share buffer cache state*/ struct list_head share_list; uint8_t get_buf_mask; uint8_t put_buf_mask; uint8_t buf_get_count; uint8_t buf_put_count; uint8_t buf_reuse_flag; }; struct msm_isp_bufq { Loading @@ -116,12 +115,9 @@ struct msm_isp_bufq { enum msm_isp_buf_type buf_type; struct msm_isp_buffer *bufs; spinlock_t bufq_lock; uint8_t put_buf_mask[ISP_NUM_BUF_MASK]; /*Native buffer queue*/ struct list_head head; /*Share buffer cache queue*/ struct list_head share_head; uint8_t buf_client_count; }; struct msm_isp_buf_ops { Loading @@ -144,8 +140,7 @@ struct msm_isp_buf_ops { uint32_t bufq_handle, uint32_t *buf_src); int (*get_buf)(struct msm_isp_buf_mgr *buf_mgr, uint32_t id, uint32_t bufq_handle, struct msm_isp_buffer **buf_info, uint32_t *buf_cnt); uint32_t bufq_handle, struct msm_isp_buffer **buf_info); int (*get_buf_by_index)(struct msm_isp_buf_mgr *buf_mgr, uint32_t bufq_handle, uint32_t buf_index, Loading Loading @@ -177,8 +172,8 @@ struct msm_isp_buf_ops { 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 id, uint32_t bufq_handle, uint32_t buf_index, struct timeval *tv, uint32_t frame_id); uint32_t id, uint32_t bufq_handle, int32_t buf_index, struct timeval *tv, uint32_t frame_id, uint32_t pingpong_bit); }; struct msm_isp_buf_mgr { Loading drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c +484 −408 File changed.Preview size limit exceeded, changes collapsed. Show changes drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c +162 −96 Original line number Diff line number Diff line Loading @@ -17,16 +17,40 @@ #include "msm_isp_axi_util.h" #include "msm_isp_stats_util.h" static inline void msm_isp_stats_cfg_wm_scratch(struct vfe_device *vfe_dev, struct msm_vfe_stats_stream *stream_info, uint32_t pingpong_status) { vfe_dev->hw_info->vfe_ops.stats_ops.update_ping_pong_addr( vfe_dev->vfe_base, stream_info, pingpong_status, vfe_dev->buf_mgr->scratch_buf_addr); } static inline void msm_isp_stats_cfg_stream_scratch(struct vfe_device *vfe_dev, struct msm_vfe_stats_stream *stream_info, uint32_t pingpong_status) { uint32_t stats_idx = STATS_IDX(stream_info->stream_handle); uint32_t pingpong_bit; uint32_t stats_pingpong_offset = vfe_dev->hw_info->stats_hw_info->stats_ping_pong_offset[ stats_idx]; pingpong_bit = (~(pingpong_status >> stats_pingpong_offset) & 0x1); msm_isp_stats_cfg_wm_scratch(vfe_dev, stream_info, pingpong_status); stream_info->buf[pingpong_bit] = NULL; } static int msm_isp_stats_cfg_ping_pong_address(struct vfe_device *vfe_dev, struct msm_vfe_stats_stream *stream_info, uint32_t pingpong_status, struct msm_isp_buffer **done_buf) struct msm_vfe_stats_stream *stream_info, uint32_t pingpong_status) { int rc = -1, vfe_id = 0; struct msm_isp_buffer *buf; uint32_t pingpong_bit = 0; uint32_t buf_cnt = 0; uint32_t bufq_handle = stream_info->bufq_handle; uint32_t stats_pingpong_offset; uint32_t bufq_handle = stream_info->bufq_handle; uint32_t stats_idx = STATS_IDX(stream_info->stream_handle); struct dual_vfe_resource *dual_vfe_res = NULL; struct msm_vfe_stats_stream *dual_vfe_stream_info = NULL; Loading @@ -42,23 +66,23 @@ static int msm_isp_stats_cfg_ping_pong_address(struct vfe_device *vfe_dev, stats_idx]; pingpong_bit = (~(pingpong_status >> stats_pingpong_offset) & 0x1); rc = vfe_dev->buf_mgr->ops->get_buf(vfe_dev->buf_mgr, vfe_dev->pdev->id, bufq_handle, &buf, &buf_cnt); vfe_dev->pdev->id, bufq_handle, &buf); if (rc == -EFAULT) { msm_isp_halt_send_error(vfe_dev, ISP_EVENT_BUF_FATAL_ERROR); return rc; } if (rc < 0) { if (rc < 0 || NULL == buf) vfe_dev->error_info.stats_framedrop_count[stats_idx]++; return rc; } if (buf->num_planes != 1) { if (buf && buf->num_planes != 1) { pr_err("%s: Invalid buffer\n", __func__); msm_isp_halt_send_error(vfe_dev, ISP_EVENT_BUF_FATAL_ERROR); rc = -EINVAL; goto buf_error; } if (vfe_dev->is_split && buf_cnt == MAX_VFE) { if (vfe_dev->is_split) { dual_vfe_res = vfe_dev->common_data->dual_vfe_res; if (!dual_vfe_res->vfe_base[ISP_VFE0] || !dual_vfe_res->stats_data[ISP_VFE0] || Loading @@ -74,26 +98,41 @@ static int msm_isp_stats_cfg_ping_pong_address(struct vfe_device *vfe_dev, dual_vfe_stream_info = &dual_vfe_res-> stats_data[vfe_id]-> stream_info[stats_idx]; if (buf) vfe_dev->hw_info->vfe_ops.stats_ops. update_ping_pong_addr( dual_vfe_res->vfe_base[vfe_id], dual_vfe_stream_info, pingpong_status, dual_vfe_stream_info, pingpong_status, buf->mapped_info[0].paddr + dual_vfe_stream_info->buffer_offset); dual_vfe_stream_info-> buffer_offset); else msm_isp_stats_cfg_stream_scratch( vfe_dev, dual_vfe_stream_info, pingpong_status); dual_vfe_stream_info->buf[pingpong_bit] = buf; } } } else if (!vfe_dev->is_split) { vfe_dev->hw_info->vfe_ops.stats_ops.update_ping_pong_addr( if (buf) vfe_dev->hw_info->vfe_ops.stats_ops. update_ping_pong_addr( vfe_dev->vfe_base, stream_info, pingpong_status, buf->mapped_info[0].paddr + stream_info->buffer_offset); } if (stream_info->buf[pingpong_bit] && done_buf) *done_buf = stream_info->buf[pingpong_bit]; else msm_isp_stats_cfg_stream_scratch(vfe_dev, stream_info, pingpong_status); stream_info->buf[pingpong_bit] = buf; } if (buf) buf->pingpong_bit = pingpong_bit; return 0; buf_error: vfe_dev->buf_mgr->ops->put_buf(vfe_dev->buf_mgr, Loading @@ -102,20 +141,24 @@ buf_error: } static int32_t msm_isp_stats_buf_divert(struct vfe_device *vfe_dev, struct msm_isp_buffer *done_buf, struct msm_isp_timestamp *ts, struct msm_isp_timestamp *ts, struct msm_isp_event_data *buf_event, struct msm_vfe_stats_stream *stream_info, uint32_t *comp_stats_type_mask) uint32_t *comp_stats_type_mask, uint32_t pingpong_status) { 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; int32_t buf_index = -1; uint32_t pingpong_bit; struct msm_isp_buffer *done_buf; uint32_t stats_pingpong_offset; uint32_t stats_idx; if (!vfe_dev || !done_buf || !ts || !buf_event || !stream_info || !comp_stats_type_mask) { pr_err("%s:%d failed: invalid params %p %p %p %p %p %p\n", __func__, __LINE__, vfe_dev, done_buf, ts, buf_event, stream_info, comp_stats_type_mask); if (!vfe_dev || !ts || !buf_event || !stream_info) { pr_err("%s:%d failed: invalid params %p %p %p %p\n", __func__, __LINE__, vfe_dev, ts, buf_event, stream_info); return -EINVAL; } frame_id = vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id; Loading @@ -138,39 +181,60 @@ static int32_t msm_isp_stats_buf_divert(struct vfe_device *vfe_dev, (struct msm_isp_sw_framskip)); } } stats_idx = STATS_IDX(stream_info->stream_handle); stats_pingpong_offset = vfe_dev->hw_info->stats_hw_info->stats_ping_pong_offset[ stats_idx]; pingpong_bit = (~(pingpong_status >> stats_pingpong_offset) & 0x1); done_buf = stream_info->buf[pingpong_bit]; if (done_buf) buf_index = done_buf->buf_idx; rc = vfe_dev->buf_mgr->ops->update_put_buf_cnt( vfe_dev->buf_mgr, vfe_dev->pdev->id, done_buf->bufq_handle, done_buf->buf_idx, &ts->buf_time, frame_id); if (rc != 0) { vfe_dev->buf_mgr, vfe_dev->pdev->id, stream_info->bufq_handle, buf_index, &ts->buf_time, frame_id, pingpong_bit); if (rc < 0) { if (rc == -EFAULT) msm_isp_halt_send_error(vfe_dev, ISP_EVENT_BUF_FATAL_ERROR); pr_err("stats_buf_divert: update put buf cnt fail\n"); return rc; } if (rc > 0) { ISP_DBG("%s: vfe_id %d buf_id %d bufq %x put_cnt 1\n", __func__, vfe_dev->pdev->id, done_buf->buf_idx, done_buf->bufq_handle); *comp_stats_type_mask |= 1 << stream_info->stats_type; stats_event->stats_buf_idxs [stream_info->stats_type] = done_buf->buf_idx; vfe_dev->pdev->id, buf_index, stream_info->bufq_handle); return rc; } if (drop_buffer) { /* Program next buffer */ rc = msm_isp_stats_cfg_ping_pong_address(vfe_dev, stream_info, pingpong_status); if (rc) return rc; if (drop_buffer && done_buf) { rc = vfe_dev->buf_mgr->ops->buf_done( vfe_dev->buf_mgr, done_buf->bufq_handle, done_buf->buf_idx, &ts->buf_time, frame_id, 0); if (rc == -EFAULT) { if (rc == -EFAULT) msm_isp_halt_send_error(vfe_dev, ISP_EVENT_BUF_FATAL_ERROR); return rc; } return rc; } if (done_buf) { stats_event->stats_buf_idxs [stream_info->stats_type] = done_buf->buf_idx; if (!stream_info->composite_flag) { if (NULL == comp_stats_type_mask) { stats_event->stats_mask = 1 << stream_info->stats_type; ISP_DBG("%s: stats frameid: 0x%x %d bufq %x\n", Loading @@ -184,6 +248,7 @@ static int32_t msm_isp_stats_buf_divert(struct vfe_device *vfe_dev, *comp_stats_type_mask |= 1 << stream_info->stats_type; } } return rc; } Loading @@ -195,10 +260,10 @@ static int32_t msm_isp_stats_configure(struct vfe_device *vfe_dev, int i, rc = 0; struct msm_isp_event_data buf_event; struct msm_isp_stats_event *stats_event = &buf_event.u.stats; struct msm_isp_buffer *done_buf; struct msm_vfe_stats_stream *stream_info = NULL; uint32_t pingpong_status; uint32_t comp_stats_type_mask = 0; int result = 0; memset(&buf_event, 0, sizeof(struct msm_isp_event_data)); buf_event.timestamp = ts->buf_time; Loading @@ -210,26 +275,24 @@ static int32_t msm_isp_stats_configure(struct vfe_device *vfe_dev, if (!(stats_irq_mask & (1 << i))) continue; stream_info = &vfe_dev->stats_data.stream_info[i]; if (stream_info->state == STATS_INACTIVE) { pr_debug("%s: Warning! Stream already inactive. Drop irq handling\n", __func__); continue; } done_buf = NULL; msm_isp_stats_cfg_ping_pong_address(vfe_dev, stream_info, pingpong_status, &done_buf); if (done_buf) { rc = msm_isp_stats_buf_divert(vfe_dev, done_buf, ts, &buf_event, stream_info, &comp_stats_type_mask); rc = msm_isp_stats_buf_divert(vfe_dev, ts, &buf_event, stream_info, is_composite ? &comp_stats_type_mask : NULL, pingpong_status); if (rc < 0) { pr_err("%s:%d failed: stats buf divert rc %d\n", __func__, __LINE__, rc); if (0 == result) result = rc; } } } if (is_composite && !rc && comp_stats_type_mask) { if (is_composite && comp_stats_type_mask) { ISP_DBG("%s:vfe_id %d comp_stats frameid %x,comp_mask %x\n", __func__, vfe_dev->pdev->id, buf_event.frame_id, comp_stats_type_mask); Loading @@ -238,7 +301,7 @@ static int32_t msm_isp_stats_configure(struct vfe_device *vfe_dev, ISP_EVENT_COMP_STATS_NOTIFY, &buf_event); comp_stats_type_mask = 0; } return rc; return result; } void msm_isp_process_stats_irq(struct vfe_device *vfe_dev, Loading Loading @@ -272,10 +335,6 @@ void msm_isp_process_stats_irq(struct vfe_device *vfe_dev, if (stats_irq_mask) { rc = msm_isp_stats_configure(vfe_dev, stats_irq_mask, ts, comp_flag); if (rc < 0) { pr_err("%s:%d failed individual stats rc %d\n", __func__, __LINE__, rc); } } /* Process composite irq */ Loading @@ -289,10 +348,6 @@ void msm_isp_process_stats_irq(struct vfe_device *vfe_dev, rc = msm_isp_stats_configure(vfe_dev, atomic_stats_mask, ts, !comp_flag); if (rc < 0) { pr_err("%s:%d failed comp stats %d rc %d\n", __func__, __LINE__, j, rc); } } } } Loading Loading @@ -397,6 +452,10 @@ int msm_isp_request_stats_stream(struct vfe_device *vfe_dev, void *arg) vfe_dev->hw_info->vfe_ops.stats_ops.cfg_wm_reg(vfe_dev, stream_info); msm_isp_stats_cfg_stream_scratch(vfe_dev, stream_info, VFE_PING_FLAG); msm_isp_stats_cfg_stream_scratch(vfe_dev, stream_info, VFE_PONG_FLAG); return rc; } Loading Loading @@ -450,18 +509,21 @@ static int msm_isp_init_stats_ping_pong_reg( return -EINVAL; } if ((vfe_dev->is_split && vfe_dev->pdev->id == 1) || !vfe_dev->is_split) { rc = msm_isp_stats_cfg_ping_pong_address(vfe_dev, stream_info, VFE_PING_FLAG, NULL); stream_info, VFE_PING_FLAG); if (rc < 0) { pr_err("%s: No free buffer for ping\n", __func__); return rc; } rc = msm_isp_stats_cfg_ping_pong_address(vfe_dev, stream_info, VFE_PONG_FLAG, NULL); stream_info, VFE_PONG_FLAG); if (rc < 0) { pr_err("%s: No free buffer for pong\n", __func__); return rc; } } return rc; } Loading Loading @@ -616,7 +678,6 @@ static int msm_isp_start_stats_stream(struct vfe_device *vfe_dev, uint32_t num_stats_comp_mask = 0; struct msm_vfe_stats_stream *stream_info; struct msm_vfe_stats_shared_data *stats_data = &vfe_dev->stats_data; num_stats_comp_mask = vfe_dev->hw_info->stats_hw_info->num_stats_comp_mask; rc = vfe_dev->hw_info->vfe_ops.stats_ops.check_streams( Loading Loading @@ -735,6 +796,11 @@ static int msm_isp_stop_stats_stream(struct vfe_device *vfe_dev, comp_stats_mask[stream_info->composite_flag-1] |= 1 << idx; msm_isp_stats_cfg_stream_scratch(vfe_dev, stream_info, VFE_PING_FLAG); msm_isp_stats_cfg_stream_scratch(vfe_dev, stream_info, VFE_PONG_FLAG); ISP_DBG("%s: stats_mask %x %x active streams %d\n", __func__, comp_stats_mask[0], comp_stats_mask[1], Loading drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c +10 −1 Original line number Diff line number Diff line Loading @@ -350,6 +350,15 @@ static inline u32 msm_isp_evt_mask_to_isp_event(u32 evt_mask) case ISP_EVENT_MASK_INDEX_MASK_FE_READ_DONE: evt_id = ISP_EVENT_FE_READ_DONE; break; case ISP_EVENT_MASK_INDEX_PING_PONG_MISMATCH: evt_id = ISP_EVENT_PING_PONG_MISMATCH; break; case ISP_EVENT_MASK_INDEX_REG_UPDATE_MISSING: evt_id = ISP_EVENT_REG_UPDATE_MISSING; break; case ISP_EVENT_MASK_INDEX_BUF_FATAL_ERROR: evt_id = ISP_EVENT_BUF_FATAL_ERROR; break; default: evt_id = ISP_EVENT_SUBS_MASK_NONE; break; Loading Loading @@ -424,7 +433,7 @@ static inline int msm_isp_process_event_subscription(struct v4l2_fh *fh, } for (evt_mask_index = ISP_EVENT_MASK_INDEX_STATS_NOTIFY; evt_mask_index <= ISP_EVENT_MASK_INDEX_MASK_FE_READ_DONE; evt_mask_index <= ISP_EVENT_MASK_INDEX_BUF_FATAL_ERROR; evt_mask_index++) { if (evt_mask & (1<<evt_mask_index)) { evt_id = msm_isp_evt_mask_to_isp_event(evt_mask_index); Loading Loading
drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c +95 −243 Original line number Diff line number Diff line Loading @@ -75,31 +75,6 @@ static int msm_buf_check_head_sanity(struct msm_isp_bufq *bufq) return -EINVAL; } prev = bufq->share_head.prev; next = bufq->share_head.next; if (!prev) { pr_err("%s: Error! bufq->share_head.prev is NULL\n", __func__); return -EINVAL; } if (!next) { pr_err("%s: Error! bufq->share_head.next is NULL\n", __func__); return -EINVAL; } if (prev->next != &bufq->share_head) { pr_err("%s: Error! share_head prev->next is %p should be %p\n", __func__, prev->next, &bufq->share_head); return -EINVAL; } if (next->prev != &bufq->share_head) { pr_err("%s: Error! share_head next->prev is %p should be %p\n", __func__, next->prev, &bufq->share_head); return -EINVAL; } return rc; } Loading Loading @@ -187,9 +162,7 @@ static int msm_isp_free_bufq_handle(struct msm_isp_buf_mgr *buf_mgr, bufq->stream_id = 0; bufq->num_bufs = 0; bufq->buf_type = 0; memset(&bufq->head, 0, sizeof(bufq->head)); memset(&bufq->share_head, 0, sizeof(bufq->share_head)); bufq->buf_client_count = 0; INIT_LIST_HEAD(&bufq->head); return 0; } Loading Loading @@ -487,27 +460,12 @@ static int msm_isp_buf_unprepare(struct msm_isp_buf_mgr *buf_mgr, return 0; } static void msm_isp_debug_list(struct msm_isp_bufq *bufq, struct msm_isp_buffer *buf_info) { int i = 0; pr_err("%s: stream_id %x buf_info last_put_id = %d\n", __func__, bufq->stream_id, buf_info->buf_debug.put_state_last); for (i = 0; i < 2; i++) { pr_err("%s i %d put_state %d\n", __func__, i, buf_info->buf_debug.put_state[i]); } } static int msm_isp_get_buf(struct msm_isp_buf_mgr *buf_mgr, uint32_t id, uint32_t bufq_handle, struct msm_isp_buffer **buf_info, uint32_t *buf_cnt) uint32_t bufq_handle, struct msm_isp_buffer **buf_info) { int rc = -1; unsigned long flags; unsigned int list_count = 0; struct msm_isp_buffer *temp_buf_info = NULL; struct msm_isp_bufq *bufq = NULL; struct vb2_buffer *vb2_buf = NULL; Loading @@ -532,52 +490,6 @@ static int msm_isp_get_buf(struct msm_isp_buf_mgr *buf_mgr, uint32_t id, } *buf_info = NULL; *buf_cnt = 0; if (bufq->buf_type == ISP_SHARE_BUF) { if (msm_buf_check_head_sanity(bufq) < 0) { spin_unlock_irqrestore(&bufq->bufq_lock, flags); WARN(1, "%s buf_handle 0x%x is in bad state\n", __func__, bufq->bufq_handle); return -EFAULT; } list_count = 0; list_for_each_entry(temp_buf_info, &bufq->share_head, share_list) { if ((temp_buf_info->get_buf_mask & (1 << id)) == 0) { temp_buf_info->get_buf_mask |= (1 << id); temp_buf_info->buf_get_count++; *buf_cnt = temp_buf_info->buf_get_count; if (temp_buf_info->buf_get_count == bufq->buf_client_count) { list_del_init( &temp_buf_info->share_list); } if (temp_buf_info->buf_reuse_flag) { kfree(temp_buf_info); } else { *buf_info = temp_buf_info; rc = 0; } spin_unlock_irqrestore( &bufq->bufq_lock, flags); return rc; } else if ((temp_buf_info->get_buf_mask & (1 << id)) && temp_buf_info->buf_reuse_flag) { spin_unlock_irqrestore( &bufq->bufq_lock, flags); return rc; } list_count++; if (list_count > MAX_LIST_COUNT) { pr_err_ratelimited("%s: %d share_list corruption, list corrupt! count = %d\n", __func__, __LINE__, list_count); spin_unlock_irqrestore( &bufq->bufq_lock, flags); return -EINVAL; } } } switch (BUF_SRC(bufq->stream_id)) { case MSM_ISP_BUFFER_SRC_NATIVE: Loading @@ -588,11 +500,10 @@ static int msm_isp_get_buf(struct msm_isp_buf_mgr *buf_mgr, uint32_t id, if (msm_buf_check_head_sanity(bufq) < 0) { spin_unlock_irqrestore( &bufq->bufq_lock, flags); WARN(1, "%s buf_handle 0x%x buf_idx %d buf_reuse_flag %d\n", WARN(1, "%s buf_handle 0x%x buf_idx %d\n", __func__, bufq->bufq_handle, temp_buf_info->buf_idx, temp_buf_info->buf_reuse_flag); temp_buf_info->buf_idx); return -EFAULT; } *buf_info = temp_buf_info; Loading Loading @@ -641,68 +552,9 @@ static int msm_isp_get_buf(struct msm_isp_buf_mgr *buf_mgr, uint32_t id, } if (!(*buf_info)) { if (bufq->buf_type == ISP_SHARE_BUF) { temp_buf_info = kzalloc( sizeof(struct msm_isp_buffer), GFP_ATOMIC); if (temp_buf_info) { temp_buf_info->buf_reuse_flag = 1; temp_buf_info->get_buf_mask |= (1 << id); temp_buf_info->buf_get_count = 1; list_add_tail(&temp_buf_info->share_list, &bufq->share_head); if (msm_buf_check_head_sanity(bufq) < 0) { spin_unlock_irqrestore( &bufq->bufq_lock, flags); WARN(1, "%s buf_handle 0x%x buf_idx %d buf_reuse_flag %d\n", __func__, bufq->bufq_handle, temp_buf_info->buf_idx, temp_buf_info->buf_reuse_flag); return -EFAULT; } } else rc = -ENOMEM; } } else { (*buf_info)->state = MSM_ISP_BUFFER_STATE_DEQUEUED; if (bufq->buf_type == ISP_SHARE_BUF) { list_for_each_entry(temp_buf_info, &bufq->share_head, share_list) { if (temp_buf_info->buf_idx == (*buf_info)->buf_idx) { msm_isp_debug_list(bufq, temp_buf_info); spin_unlock_irqrestore( &bufq->bufq_lock, flags); WARN(1, "%s ERROR! Double ADD found\n", __func__); return -EFAULT; } } (*buf_info)->get_buf_mask = (1 << id); (*buf_info)->buf_get_count = 1; (*buf_info)->buf_put_count = 0; (*buf_info)->put_buf_mask = 0; (*buf_info)->buf_reuse_flag = 0; if (!list_empty(&(*buf_info)->share_list)) { spin_unlock_irqrestore(&bufq->bufq_lock, flags); WARN(1, "%s: buf %x/%x double add\n", __func__, bufq_handle, (*buf_info)->buf_idx); return -EFAULT; } list_add_tail(&(*buf_info)->share_list, &bufq->share_head); if (msm_buf_check_head_sanity(bufq) < 0) { spin_unlock_irqrestore(&bufq->bufq_lock, flags); WARN(1, "%s buf_handle 0x%x buf_idx %d buf_reuse_flag %d\n", __func__, bufq->bufq_handle, (*buf_info)->buf_idx, (*buf_info)->buf_reuse_flag); return -EFAULT; } } rc = 0; } spin_unlock_irqrestore(&bufq->bufq_lock, flags); Loading Loading @@ -730,6 +582,7 @@ static int msm_isp_put_buf_unsafe(struct msm_isp_buf_mgr *buf_mgr, switch (buf_info->state) { case MSM_ISP_BUFFER_STATE_PREPARED: case MSM_ISP_BUFFER_STATE_DEQUEUED: if (BUF_SRC(bufq->stream_id)) { if (!list_empty(&buf_info->list)) { WARN(1, "%s: buf %x/%x double add\n", Loading @@ -738,11 +591,10 @@ static int msm_isp_put_buf_unsafe(struct msm_isp_buf_mgr *buf_mgr, } list_add_tail(&buf_info->list, &bufq->head); if (msm_buf_check_head_sanity(bufq) < 0) { WARN(1, "%s buf_handle 0x%x buf_idx %d buf_reuse_flag %d\n", WARN(1, "%s buf_handle 0x%x buf_idx %d\n", __func__, bufq->bufq_handle, buf_info->buf_idx, buf_info->buf_reuse_flag); buf_info->buf_idx); return -EFAULT; } } else { Loading @@ -757,7 +609,6 @@ static int msm_isp_put_buf_unsafe(struct msm_isp_buf_mgr *buf_mgr, rc = 0; break; case MSM_ISP_BUFFER_STATE_QUEUED: case MSM_ISP_BUFFER_STATE_DEQUEUED: case MSM_ISP_BUFFER_STATE_DIVERTED: default: WARN(1, "%s: bufq 0x%x, buf idx 0x%x, incorrect state = %d", Loading Loading @@ -790,11 +641,6 @@ static int msm_isp_put_buf(struct msm_isp_buf_mgr *buf_mgr, spin_lock_irqsave(&bufq->bufq_lock, flags); buf_info->buf_get_count = 0; buf_info->buf_put_count = 0; buf_info->get_buf_mask = 0; buf_info->put_buf_mask = 0; rc = msm_isp_put_buf_unsafe(buf_mgr, bufq_handle, buf_index); spin_unlock_irqrestore(&bufq->bufq_lock, flags); Loading @@ -804,13 +650,13 @@ static int msm_isp_put_buf(struct msm_isp_buf_mgr *buf_mgr, static int msm_isp_update_put_buf_cnt_unsafe( struct msm_isp_buf_mgr *buf_mgr, uint32_t id, uint32_t bufq_handle, uint32_t buf_index, struct timeval *tv, uint32_t frame_id, unsigned long *flags) uint32_t id, uint32_t bufq_handle, int32_t buf_index, struct timeval *tv, uint32_t frame_id, uint32_t pingpong_bit) { int rc = -1; struct msm_isp_bufq *bufq = NULL; struct msm_isp_buffer *buf_info = NULL; enum msm_isp_buffer_state state; uint8_t *put_buf_mask = NULL; bufq = msm_isp_get_bufq(buf_mgr, bufq_handle); if (!bufq) { Loading @@ -818,38 +664,46 @@ static int msm_isp_update_put_buf_cnt_unsafe( return rc; } put_buf_mask = &bufq->put_buf_mask[pingpong_bit]; if (buf_index >= 0) { 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; return -EFAULT; } if (buf_info->state != MSM_ISP_BUFFER_STATE_DEQUEUED) { pr_err( "%s: Invalid state, bufq_handle %x stream id %x, state %d\n", __func__, bufq_handle, bufq->stream_id, buf_info->state); return -EFAULT; } BUG_ON(buf_info->pingpong_bit != pingpong_bit); } if (bufq->buf_type != ISP_SHARE_BUF || buf_info->put_buf_mask == 0) { (*put_buf_mask == 0)) { if (buf_info) buf_info->frame_id = frame_id; } state = buf_info->state; if (state == MSM_ISP_BUFFER_STATE_DEQUEUED) { if (bufq->buf_type == ISP_SHARE_BUF && ((buf_info->put_buf_mask & (1 << id)) == 0)) { buf_info->put_buf_mask |= (1 << id); buf_info->buf_put_count++; if (buf_info->buf_put_count != ISP_SHARE_BUF_CLIENT) { rc = buf_info->buf_put_count; return rc; } ((*put_buf_mask & (1 << id)) == 0)) { *put_buf_mask |= (1 << id); if (*put_buf_mask != ISP_SHARE_BUF_MASK) { rc = *put_buf_mask; return 1; } } else { pr_warn("%s: Invalid state, stream id %x, state %d\n", __func__, bufq->stream_id, state); spin_unlock_irqrestore(&bufq->bufq_lock, *flags); dump_stack(); spin_lock_irqsave(&bufq->bufq_lock, *flags); return rc; *put_buf_mask = 0; rc = 0; } else if (bufq->buf_type == ISP_SHARE_BUF && (*put_buf_mask & (1 << id)) != 0) { return -ENOTEMPTY; } if (MSM_ISP_BUFFER_SRC_NATIVE == BUF_SRC(bufq->stream_id)) { if (buf_info && MSM_ISP_BUFFER_SRC_NATIVE == BUF_SRC(bufq->stream_id)) { buf_info->state = MSM_ISP_BUFFER_STATE_DIVERTED; buf_info->tv = tv; } Loading @@ -857,8 +711,8 @@ static int msm_isp_update_put_buf_cnt_unsafe( } static int msm_isp_update_put_buf_cnt(struct msm_isp_buf_mgr *buf_mgr, uint32_t id, uint32_t bufq_handle, uint32_t buf_index, struct timeval *tv, uint32_t frame_id) uint32_t id, uint32_t bufq_handle, int32_t buf_index, struct timeval *tv, uint32_t frame_id, uint32_t pingpong_bit) { int rc = -1; struct msm_isp_bufq *bufq = NULL; Loading @@ -872,7 +726,12 @@ static int msm_isp_update_put_buf_cnt(struct msm_isp_buf_mgr *buf_mgr, spin_lock_irqsave(&bufq->bufq_lock, flags); rc = msm_isp_update_put_buf_cnt_unsafe(buf_mgr, id, bufq_handle, buf_index, tv, frame_id, &flags); buf_index, tv, frame_id, pingpong_bit); if (-ENOTEMPTY == rc) { pr_err("%s: Error! Uncleared put_buf_mask for pingpong(%d) from vfe %d bufq 0x%x buf_idx %d\n", __func__, pingpong_bit, id, bufq_handle, buf_index); rc = -EFAULT; } spin_unlock_irqrestore(&bufq->bufq_lock, flags); return rc; } Loading @@ -881,7 +740,7 @@ 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; int rc = 0; unsigned long flags; struct msm_isp_bufq *bufq = NULL; struct msm_isp_buffer *buf_info = NULL; Loading @@ -890,13 +749,13 @@ static int msm_isp_buf_done(struct msm_isp_buf_mgr *buf_mgr, bufq = msm_isp_get_bufq(buf_mgr, bufq_handle); if (!bufq) { pr_err("Invalid bufq\n"); return rc; return -EINVAL; } 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; return -EINVAL; } spin_lock_irqsave(&bufq->bufq_lock, flags); Loading Loading @@ -936,7 +795,7 @@ static int msm_isp_flush_buf(struct msm_isp_buf_mgr *buf_mgr, uint32_t id, uint32_t bufq_handle, enum msm_isp_buffer_flush_t flush_type, struct timeval *tv, uint32_t frame_id) { int rc = -1, i; int rc = 0, i; struct msm_isp_bufq *bufq = NULL; struct msm_isp_buffer *buf_info = NULL; unsigned long flags; Loading @@ -944,7 +803,7 @@ static int msm_isp_flush_buf(struct msm_isp_buf_mgr *buf_mgr, uint32_t id, bufq = msm_isp_get_bufq(buf_mgr, bufq_handle); if (!bufq) { pr_err("Invalid bufq\n"); return rc; return -EINVAL; } spin_lock_irqsave(&bufq->bufq_lock, flags); Loading @@ -965,40 +824,35 @@ static int msm_isp_flush_buf(struct msm_isp_buf_mgr *buf_mgr, uint32_t id, __func__); } else if (buf_info->state == MSM_ISP_BUFFER_STATE_DEQUEUED) { rc = msm_isp_update_put_buf_cnt_unsafe(buf_mgr, id, bufq_handle, buf_info->buf_idx, tv, frame_id, buf_info->pingpong_bit); if (-ENOTEMPTY == rc) { rc = 0; continue; } if (rc == 0) { buf_info->buf_debug.put_state[ buf_info->buf_debug.put_state_last] buf_info->buf_debug. put_state_last] = MSM_ISP_BUFFER_STATE_FLUSH; buf_info->buf_debug.put_state_last ^= 1; buf_info->state = MSM_ISP_BUFFER_STATE_PREPARED; buf_info->state = MSM_ISP_BUFFER_STATE_PREPARED; rc = msm_isp_put_buf_unsafe(buf_mgr, bufq_handle, buf_info->buf_idx); if (rc == -EFAULT) { spin_unlock_irqrestore(&bufq->bufq_lock, spin_unlock_irqrestore( &bufq->bufq_lock, flags); return rc; } } } } if (bufq->buf_type == ISP_SHARE_BUF) { while (!list_empty(&bufq->share_head)) { buf_info = list_entry((&bufq->share_head)->next, typeof(*buf_info), share_list); list_del_init(&(buf_info->share_list)); if (msm_buf_check_head_sanity(bufq) < 0) { spin_unlock_irqrestore(&bufq->bufq_lock, flags); WARN(1, "%s buf_handle 0x%x buf_idx %d buf_reuse_flag %d\n", __func__, bufq->bufq_handle, buf_info->buf_idx, buf_info->buf_reuse_flag); return -EFAULT; } if (buf_info->buf_reuse_flag) kfree(buf_info); } } spin_unlock_irqrestore(&bufq->bufq_lock, flags); return 0; } Loading @@ -1006,7 +860,7 @@ static int msm_isp_flush_buf(struct msm_isp_buf_mgr *buf_mgr, uint32_t id, static int msm_isp_buf_enqueue(struct msm_isp_buf_mgr *buf_mgr, struct msm_isp_qbuf_info *info) { int rc = -1, buf_state; int rc = 0, buf_state; struct msm_isp_bufq *bufq = NULL; struct msm_isp_buffer *buf_info = NULL; Loading @@ -1029,7 +883,7 @@ static int msm_isp_buf_enqueue(struct msm_isp_buf_mgr *buf_mgr, info->handle, info->buf_idx); if (!buf_info) { pr_err("%s: buf not found\n", __func__); return rc; return -EINVAL; } if (info->dirty_buf) { buf_info->buf_debug.put_state[ Loading Loading @@ -1059,7 +913,7 @@ static int msm_isp_buf_enqueue(struct msm_isp_buf_mgr *buf_mgr, info->handle, info->buf_idx); if (!buf_info) { pr_err("%s: buf not found\n", __func__); return rc; return -EINVAL; } buf_info->buf_debug.put_state[ Loading @@ -1075,7 +929,7 @@ static int msm_isp_buf_enqueue(struct msm_isp_buf_mgr *buf_mgr, } } } return rc; return 0; } static int msm_isp_buf_dequeue(struct msm_isp_buf_mgr *buf_mgr, Loading Loading @@ -1136,20 +990,20 @@ static int msm_isp_get_buf_src(struct msm_isp_buf_mgr *buf_mgr, static int msm_isp_request_bufq(struct msm_isp_buf_mgr *buf_mgr, struct msm_isp_buf_request *buf_request) { int rc = -1, i; int i; struct msm_isp_bufq *bufq = NULL; CDBG("%s: E\n", __func__); if (!buf_request->num_buf || buf_request->num_buf > VB2_MAX_FRAME) { pr_err("Invalid buffer request\n"); return rc; return -EINVAL; } buf_request->handle = msm_isp_get_buf_handle(buf_mgr, buf_request->session_id, buf_request->stream_id); if (!buf_request->handle) { pr_err("Invalid buffer handle\n"); return rc; return -EINVAL; } bufq = msm_isp_get_bufq(buf_mgr, buf_request->handle); Loading @@ -1157,7 +1011,7 @@ static int msm_isp_request_bufq(struct msm_isp_buf_mgr *buf_mgr, pr_err("%s: Invalid bufq stream_id %x\n", __func__, buf_request->stream_id); return rc; return -EINVAL; } bufq->bufs = kzalloc(sizeof(struct msm_isp_buffer) * Loading @@ -1165,7 +1019,7 @@ static int msm_isp_request_bufq(struct msm_isp_buf_mgr *buf_mgr, if (!bufq->bufs) { pr_err("No free memory for buf info\n"); msm_isp_free_bufq_handle(buf_mgr, buf_request->handle); return rc; return -ENOMEM; } spin_lock_init(&bufq->bufq_lock); bufq->bufq_handle = buf_request->handle; Loading @@ -1173,10 +1027,10 @@ static int msm_isp_request_bufq(struct msm_isp_buf_mgr *buf_mgr, bufq->stream_id = buf_request->stream_id; bufq->num_bufs = buf_request->num_buf; bufq->buf_type = buf_request->buf_type; if (bufq->buf_type == ISP_SHARE_BUF) bufq->buf_client_count = ISP_SHARE_BUF_CLIENT; for (i = 0; i < ISP_NUM_BUF_MASK; i++) bufq->put_buf_mask[i] = 0; INIT_LIST_HEAD(&bufq->head); INIT_LIST_HEAD(&bufq->share_head); for (i = 0; i < buf_request->num_buf; i++) { bufq->bufs[i].state = MSM_ISP_BUFFER_STATE_INITIALIZED; bufq->bufs[i].buf_debug.put_state[0] = Loading @@ -1187,7 +1041,6 @@ static int msm_isp_request_bufq(struct msm_isp_buf_mgr *buf_mgr, bufq->bufs[i].bufq_handle = bufq->bufq_handle; bufq->bufs[i].buf_idx = i; INIT_LIST_HEAD(&bufq->bufs[i].list); INIT_LIST_HEAD(&bufq->bufs[i].share_list); } return 0; Loading @@ -1198,11 +1051,10 @@ static int msm_isp_release_bufq(struct msm_isp_buf_mgr *buf_mgr, { struct msm_isp_bufq *bufq = NULL; unsigned long flags; int rc = -1; bufq = msm_isp_get_bufq(buf_mgr, bufq_handle); if (!bufq) { pr_err("Invalid bufq release\n"); return rc; return -EINVAL; } msm_isp_buf_unprepare_all(buf_mgr, bufq_handle); Loading
drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h +12 −17 Original line number Diff line number Diff line Loading @@ -23,7 +23,12 @@ (id & ISP_NATIVE_BUF_BIT) ? MSM_ISP_BUFFER_SRC_NATIVE : \ MSM_ISP_BUFFER_SRC_HAL) #define ISP_SHARE_BUF_CLIENT 2 /* * This mask can be set dynamically if there are more than 2 VFE *.and 2 of those are used */ #define ISP_SHARE_BUF_MASK 0x3 #define ISP_NUM_BUF_MASK 2 #define BUF_MGR_NUM_BUF_Q 28 #define MAX_IOMMU_CTX 2 Loading Loading @@ -89,6 +94,8 @@ struct msm_isp_buffer { uint32_t bufq_handle; uint32_t frame_id; struct timeval *tv; /* Indicates whether buffer is used as ping ot pong buffer */ uint32_t pingpong_bit; /*Native buffer*/ struct list_head list; Loading @@ -98,14 +105,6 @@ struct msm_isp_buffer { /*Vb2 buffer data*/ struct vb2_buffer *vb2_buf; /*Share buffer cache state*/ struct list_head share_list; uint8_t get_buf_mask; uint8_t put_buf_mask; uint8_t buf_get_count; uint8_t buf_put_count; uint8_t buf_reuse_flag; }; struct msm_isp_bufq { Loading @@ -116,12 +115,9 @@ struct msm_isp_bufq { enum msm_isp_buf_type buf_type; struct msm_isp_buffer *bufs; spinlock_t bufq_lock; uint8_t put_buf_mask[ISP_NUM_BUF_MASK]; /*Native buffer queue*/ struct list_head head; /*Share buffer cache queue*/ struct list_head share_head; uint8_t buf_client_count; }; struct msm_isp_buf_ops { Loading @@ -144,8 +140,7 @@ struct msm_isp_buf_ops { uint32_t bufq_handle, uint32_t *buf_src); int (*get_buf)(struct msm_isp_buf_mgr *buf_mgr, uint32_t id, uint32_t bufq_handle, struct msm_isp_buffer **buf_info, uint32_t *buf_cnt); uint32_t bufq_handle, struct msm_isp_buffer **buf_info); int (*get_buf_by_index)(struct msm_isp_buf_mgr *buf_mgr, uint32_t bufq_handle, uint32_t buf_index, Loading Loading @@ -177,8 +172,8 @@ struct msm_isp_buf_ops { 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 id, uint32_t bufq_handle, uint32_t buf_index, struct timeval *tv, uint32_t frame_id); uint32_t id, uint32_t bufq_handle, int32_t buf_index, struct timeval *tv, uint32_t frame_id, uint32_t pingpong_bit); }; struct msm_isp_buf_mgr { Loading
drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c +484 −408 File changed.Preview size limit exceeded, changes collapsed. Show changes
drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c +162 −96 Original line number Diff line number Diff line Loading @@ -17,16 +17,40 @@ #include "msm_isp_axi_util.h" #include "msm_isp_stats_util.h" static inline void msm_isp_stats_cfg_wm_scratch(struct vfe_device *vfe_dev, struct msm_vfe_stats_stream *stream_info, uint32_t pingpong_status) { vfe_dev->hw_info->vfe_ops.stats_ops.update_ping_pong_addr( vfe_dev->vfe_base, stream_info, pingpong_status, vfe_dev->buf_mgr->scratch_buf_addr); } static inline void msm_isp_stats_cfg_stream_scratch(struct vfe_device *vfe_dev, struct msm_vfe_stats_stream *stream_info, uint32_t pingpong_status) { uint32_t stats_idx = STATS_IDX(stream_info->stream_handle); uint32_t pingpong_bit; uint32_t stats_pingpong_offset = vfe_dev->hw_info->stats_hw_info->stats_ping_pong_offset[ stats_idx]; pingpong_bit = (~(pingpong_status >> stats_pingpong_offset) & 0x1); msm_isp_stats_cfg_wm_scratch(vfe_dev, stream_info, pingpong_status); stream_info->buf[pingpong_bit] = NULL; } static int msm_isp_stats_cfg_ping_pong_address(struct vfe_device *vfe_dev, struct msm_vfe_stats_stream *stream_info, uint32_t pingpong_status, struct msm_isp_buffer **done_buf) struct msm_vfe_stats_stream *stream_info, uint32_t pingpong_status) { int rc = -1, vfe_id = 0; struct msm_isp_buffer *buf; uint32_t pingpong_bit = 0; uint32_t buf_cnt = 0; uint32_t bufq_handle = stream_info->bufq_handle; uint32_t stats_pingpong_offset; uint32_t bufq_handle = stream_info->bufq_handle; uint32_t stats_idx = STATS_IDX(stream_info->stream_handle); struct dual_vfe_resource *dual_vfe_res = NULL; struct msm_vfe_stats_stream *dual_vfe_stream_info = NULL; Loading @@ -42,23 +66,23 @@ static int msm_isp_stats_cfg_ping_pong_address(struct vfe_device *vfe_dev, stats_idx]; pingpong_bit = (~(pingpong_status >> stats_pingpong_offset) & 0x1); rc = vfe_dev->buf_mgr->ops->get_buf(vfe_dev->buf_mgr, vfe_dev->pdev->id, bufq_handle, &buf, &buf_cnt); vfe_dev->pdev->id, bufq_handle, &buf); if (rc == -EFAULT) { msm_isp_halt_send_error(vfe_dev, ISP_EVENT_BUF_FATAL_ERROR); return rc; } if (rc < 0) { if (rc < 0 || NULL == buf) vfe_dev->error_info.stats_framedrop_count[stats_idx]++; return rc; } if (buf->num_planes != 1) { if (buf && buf->num_planes != 1) { pr_err("%s: Invalid buffer\n", __func__); msm_isp_halt_send_error(vfe_dev, ISP_EVENT_BUF_FATAL_ERROR); rc = -EINVAL; goto buf_error; } if (vfe_dev->is_split && buf_cnt == MAX_VFE) { if (vfe_dev->is_split) { dual_vfe_res = vfe_dev->common_data->dual_vfe_res; if (!dual_vfe_res->vfe_base[ISP_VFE0] || !dual_vfe_res->stats_data[ISP_VFE0] || Loading @@ -74,26 +98,41 @@ static int msm_isp_stats_cfg_ping_pong_address(struct vfe_device *vfe_dev, dual_vfe_stream_info = &dual_vfe_res-> stats_data[vfe_id]-> stream_info[stats_idx]; if (buf) vfe_dev->hw_info->vfe_ops.stats_ops. update_ping_pong_addr( dual_vfe_res->vfe_base[vfe_id], dual_vfe_stream_info, pingpong_status, dual_vfe_stream_info, pingpong_status, buf->mapped_info[0].paddr + dual_vfe_stream_info->buffer_offset); dual_vfe_stream_info-> buffer_offset); else msm_isp_stats_cfg_stream_scratch( vfe_dev, dual_vfe_stream_info, pingpong_status); dual_vfe_stream_info->buf[pingpong_bit] = buf; } } } else if (!vfe_dev->is_split) { vfe_dev->hw_info->vfe_ops.stats_ops.update_ping_pong_addr( if (buf) vfe_dev->hw_info->vfe_ops.stats_ops. update_ping_pong_addr( vfe_dev->vfe_base, stream_info, pingpong_status, buf->mapped_info[0].paddr + stream_info->buffer_offset); } if (stream_info->buf[pingpong_bit] && done_buf) *done_buf = stream_info->buf[pingpong_bit]; else msm_isp_stats_cfg_stream_scratch(vfe_dev, stream_info, pingpong_status); stream_info->buf[pingpong_bit] = buf; } if (buf) buf->pingpong_bit = pingpong_bit; return 0; buf_error: vfe_dev->buf_mgr->ops->put_buf(vfe_dev->buf_mgr, Loading @@ -102,20 +141,24 @@ buf_error: } static int32_t msm_isp_stats_buf_divert(struct vfe_device *vfe_dev, struct msm_isp_buffer *done_buf, struct msm_isp_timestamp *ts, struct msm_isp_timestamp *ts, struct msm_isp_event_data *buf_event, struct msm_vfe_stats_stream *stream_info, uint32_t *comp_stats_type_mask) uint32_t *comp_stats_type_mask, uint32_t pingpong_status) { 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; int32_t buf_index = -1; uint32_t pingpong_bit; struct msm_isp_buffer *done_buf; uint32_t stats_pingpong_offset; uint32_t stats_idx; if (!vfe_dev || !done_buf || !ts || !buf_event || !stream_info || !comp_stats_type_mask) { pr_err("%s:%d failed: invalid params %p %p %p %p %p %p\n", __func__, __LINE__, vfe_dev, done_buf, ts, buf_event, stream_info, comp_stats_type_mask); if (!vfe_dev || !ts || !buf_event || !stream_info) { pr_err("%s:%d failed: invalid params %p %p %p %p\n", __func__, __LINE__, vfe_dev, ts, buf_event, stream_info); return -EINVAL; } frame_id = vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id; Loading @@ -138,39 +181,60 @@ static int32_t msm_isp_stats_buf_divert(struct vfe_device *vfe_dev, (struct msm_isp_sw_framskip)); } } stats_idx = STATS_IDX(stream_info->stream_handle); stats_pingpong_offset = vfe_dev->hw_info->stats_hw_info->stats_ping_pong_offset[ stats_idx]; pingpong_bit = (~(pingpong_status >> stats_pingpong_offset) & 0x1); done_buf = stream_info->buf[pingpong_bit]; if (done_buf) buf_index = done_buf->buf_idx; rc = vfe_dev->buf_mgr->ops->update_put_buf_cnt( vfe_dev->buf_mgr, vfe_dev->pdev->id, done_buf->bufq_handle, done_buf->buf_idx, &ts->buf_time, frame_id); if (rc != 0) { vfe_dev->buf_mgr, vfe_dev->pdev->id, stream_info->bufq_handle, buf_index, &ts->buf_time, frame_id, pingpong_bit); if (rc < 0) { if (rc == -EFAULT) msm_isp_halt_send_error(vfe_dev, ISP_EVENT_BUF_FATAL_ERROR); pr_err("stats_buf_divert: update put buf cnt fail\n"); return rc; } if (rc > 0) { ISP_DBG("%s: vfe_id %d buf_id %d bufq %x put_cnt 1\n", __func__, vfe_dev->pdev->id, done_buf->buf_idx, done_buf->bufq_handle); *comp_stats_type_mask |= 1 << stream_info->stats_type; stats_event->stats_buf_idxs [stream_info->stats_type] = done_buf->buf_idx; vfe_dev->pdev->id, buf_index, stream_info->bufq_handle); return rc; } if (drop_buffer) { /* Program next buffer */ rc = msm_isp_stats_cfg_ping_pong_address(vfe_dev, stream_info, pingpong_status); if (rc) return rc; if (drop_buffer && done_buf) { rc = vfe_dev->buf_mgr->ops->buf_done( vfe_dev->buf_mgr, done_buf->bufq_handle, done_buf->buf_idx, &ts->buf_time, frame_id, 0); if (rc == -EFAULT) { if (rc == -EFAULT) msm_isp_halt_send_error(vfe_dev, ISP_EVENT_BUF_FATAL_ERROR); return rc; } return rc; } if (done_buf) { stats_event->stats_buf_idxs [stream_info->stats_type] = done_buf->buf_idx; if (!stream_info->composite_flag) { if (NULL == comp_stats_type_mask) { stats_event->stats_mask = 1 << stream_info->stats_type; ISP_DBG("%s: stats frameid: 0x%x %d bufq %x\n", Loading @@ -184,6 +248,7 @@ static int32_t msm_isp_stats_buf_divert(struct vfe_device *vfe_dev, *comp_stats_type_mask |= 1 << stream_info->stats_type; } } return rc; } Loading @@ -195,10 +260,10 @@ static int32_t msm_isp_stats_configure(struct vfe_device *vfe_dev, int i, rc = 0; struct msm_isp_event_data buf_event; struct msm_isp_stats_event *stats_event = &buf_event.u.stats; struct msm_isp_buffer *done_buf; struct msm_vfe_stats_stream *stream_info = NULL; uint32_t pingpong_status; uint32_t comp_stats_type_mask = 0; int result = 0; memset(&buf_event, 0, sizeof(struct msm_isp_event_data)); buf_event.timestamp = ts->buf_time; Loading @@ -210,26 +275,24 @@ static int32_t msm_isp_stats_configure(struct vfe_device *vfe_dev, if (!(stats_irq_mask & (1 << i))) continue; stream_info = &vfe_dev->stats_data.stream_info[i]; if (stream_info->state == STATS_INACTIVE) { pr_debug("%s: Warning! Stream already inactive. Drop irq handling\n", __func__); continue; } done_buf = NULL; msm_isp_stats_cfg_ping_pong_address(vfe_dev, stream_info, pingpong_status, &done_buf); if (done_buf) { rc = msm_isp_stats_buf_divert(vfe_dev, done_buf, ts, &buf_event, stream_info, &comp_stats_type_mask); rc = msm_isp_stats_buf_divert(vfe_dev, ts, &buf_event, stream_info, is_composite ? &comp_stats_type_mask : NULL, pingpong_status); if (rc < 0) { pr_err("%s:%d failed: stats buf divert rc %d\n", __func__, __LINE__, rc); if (0 == result) result = rc; } } } if (is_composite && !rc && comp_stats_type_mask) { if (is_composite && comp_stats_type_mask) { ISP_DBG("%s:vfe_id %d comp_stats frameid %x,comp_mask %x\n", __func__, vfe_dev->pdev->id, buf_event.frame_id, comp_stats_type_mask); Loading @@ -238,7 +301,7 @@ static int32_t msm_isp_stats_configure(struct vfe_device *vfe_dev, ISP_EVENT_COMP_STATS_NOTIFY, &buf_event); comp_stats_type_mask = 0; } return rc; return result; } void msm_isp_process_stats_irq(struct vfe_device *vfe_dev, Loading Loading @@ -272,10 +335,6 @@ void msm_isp_process_stats_irq(struct vfe_device *vfe_dev, if (stats_irq_mask) { rc = msm_isp_stats_configure(vfe_dev, stats_irq_mask, ts, comp_flag); if (rc < 0) { pr_err("%s:%d failed individual stats rc %d\n", __func__, __LINE__, rc); } } /* Process composite irq */ Loading @@ -289,10 +348,6 @@ void msm_isp_process_stats_irq(struct vfe_device *vfe_dev, rc = msm_isp_stats_configure(vfe_dev, atomic_stats_mask, ts, !comp_flag); if (rc < 0) { pr_err("%s:%d failed comp stats %d rc %d\n", __func__, __LINE__, j, rc); } } } } Loading Loading @@ -397,6 +452,10 @@ int msm_isp_request_stats_stream(struct vfe_device *vfe_dev, void *arg) vfe_dev->hw_info->vfe_ops.stats_ops.cfg_wm_reg(vfe_dev, stream_info); msm_isp_stats_cfg_stream_scratch(vfe_dev, stream_info, VFE_PING_FLAG); msm_isp_stats_cfg_stream_scratch(vfe_dev, stream_info, VFE_PONG_FLAG); return rc; } Loading Loading @@ -450,18 +509,21 @@ static int msm_isp_init_stats_ping_pong_reg( return -EINVAL; } if ((vfe_dev->is_split && vfe_dev->pdev->id == 1) || !vfe_dev->is_split) { rc = msm_isp_stats_cfg_ping_pong_address(vfe_dev, stream_info, VFE_PING_FLAG, NULL); stream_info, VFE_PING_FLAG); if (rc < 0) { pr_err("%s: No free buffer for ping\n", __func__); return rc; } rc = msm_isp_stats_cfg_ping_pong_address(vfe_dev, stream_info, VFE_PONG_FLAG, NULL); stream_info, VFE_PONG_FLAG); if (rc < 0) { pr_err("%s: No free buffer for pong\n", __func__); return rc; } } return rc; } Loading Loading @@ -616,7 +678,6 @@ static int msm_isp_start_stats_stream(struct vfe_device *vfe_dev, uint32_t num_stats_comp_mask = 0; struct msm_vfe_stats_stream *stream_info; struct msm_vfe_stats_shared_data *stats_data = &vfe_dev->stats_data; num_stats_comp_mask = vfe_dev->hw_info->stats_hw_info->num_stats_comp_mask; rc = vfe_dev->hw_info->vfe_ops.stats_ops.check_streams( Loading Loading @@ -735,6 +796,11 @@ static int msm_isp_stop_stats_stream(struct vfe_device *vfe_dev, comp_stats_mask[stream_info->composite_flag-1] |= 1 << idx; msm_isp_stats_cfg_stream_scratch(vfe_dev, stream_info, VFE_PING_FLAG); msm_isp_stats_cfg_stream_scratch(vfe_dev, stream_info, VFE_PONG_FLAG); ISP_DBG("%s: stats_mask %x %x active streams %d\n", __func__, comp_stats_mask[0], comp_stats_mask[1], Loading
drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c +10 −1 Original line number Diff line number Diff line Loading @@ -350,6 +350,15 @@ static inline u32 msm_isp_evt_mask_to_isp_event(u32 evt_mask) case ISP_EVENT_MASK_INDEX_MASK_FE_READ_DONE: evt_id = ISP_EVENT_FE_READ_DONE; break; case ISP_EVENT_MASK_INDEX_PING_PONG_MISMATCH: evt_id = ISP_EVENT_PING_PONG_MISMATCH; break; case ISP_EVENT_MASK_INDEX_REG_UPDATE_MISSING: evt_id = ISP_EVENT_REG_UPDATE_MISSING; break; case ISP_EVENT_MASK_INDEX_BUF_FATAL_ERROR: evt_id = ISP_EVENT_BUF_FATAL_ERROR; break; default: evt_id = ISP_EVENT_SUBS_MASK_NONE; break; Loading Loading @@ -424,7 +433,7 @@ static inline int msm_isp_process_event_subscription(struct v4l2_fh *fh, } for (evt_mask_index = ISP_EVENT_MASK_INDEX_STATS_NOTIFY; evt_mask_index <= ISP_EVENT_MASK_INDEX_MASK_FE_READ_DONE; evt_mask_index <= ISP_EVENT_MASK_INDEX_BUF_FATAL_ERROR; evt_mask_index++) { if (evt_mask & (1<<evt_mask_index)) { evt_id = msm_isp_evt_mask_to_isp_event(evt_mask_index); Loading