Loading drivers/media/platform/msm/vidc/msm_vidc.c +10 −9 Original line number Diff line number Diff line Loading @@ -497,11 +497,12 @@ static inline enum hal_buffer get_hal_buffer_type( return -EINVAL; } static inline bool is_dynamic_output_buffer_mode(struct v4l2_buffer *b, static inline bool is_dynamic_buffer_mode(struct v4l2_buffer *b, struct msm_vidc_inst *inst) { return b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && inst->buffer_mode_set[CAPTURE_PORT] == HAL_BUFFER_MODE_DYNAMIC; enum vidc_ports port = b->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ? OUTPUT_PORT : CAPTURE_PORT; return inst->buffer_mode_set[port] == HAL_BUFFER_MODE_DYNAMIC; } Loading Loading @@ -558,7 +559,7 @@ int map_and_register_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b) } mutex_lock(&inst->registeredbufs.lock); temp = get_registered_buf(inst, b, i, &plane); if (temp && !is_dynamic_output_buffer_mode(b, inst)) { if (temp && !is_dynamic_buffer_mode(b, inst)) { dprintk(VIDC_DBG, "This memory region has already been prepared\n"); rc = 0; Loading @@ -566,7 +567,7 @@ int map_and_register_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b) goto exit; } if (temp && is_dynamic_output_buffer_mode(b, inst) && !i) { if (temp && is_dynamic_buffer_mode(b, inst) && !i) { /* * Buffer is already present in registered list * increment ref_count, populate new values of v4l2 Loading Loading @@ -599,7 +600,7 @@ int map_and_register_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b) if (rc == 1) { rc = 0; goto exit; } else if (rc == 2) { } else if (rc >= 2) { rc = -EEXIST; goto exit; } Loading Loading @@ -629,7 +630,7 @@ int map_and_register_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b) } /* We maintain one ref count for all planes*/ if (!i && is_dynamic_output_buffer_mode(b, inst)) { if (!i && is_dynamic_buffer_mode(b, inst)) { rc = buf_ref_get(inst, binfo); if (rc < 0) goto exit; Loading Loading @@ -874,7 +875,7 @@ int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b) rc = map_and_register_buf(inst, b); if (rc == -EEXIST) { if (atomic_read(&inst->in_flush) && is_dynamic_output_buffer_mode(b, inst)) { is_dynamic_buffer_mode(b, inst)) { dprintk(VIDC_ERR, "Flush in progress, do not hold any buffers in driver\n"); msm_comm_flush_dynamic_buffers(inst); Loading Loading @@ -998,7 +999,7 @@ int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b) return rc; if (is_dynamic_output_buffer_mode(b, inst)) { if (is_dynamic_buffer_mode(b, inst)) { buffer_info->dequeued = true; dprintk(VIDC_DBG, "[DEQUEUED]: fd[0] = %d\n", Loading drivers/media/platform/msm/vidc/msm_vidc_common.c +59 −58 Original line number Diff line number Diff line Loading @@ -2163,6 +2163,43 @@ static struct vb2_buffer *get_vb_from_device_addr(struct buf_queue *bufq, return vb; } static void handle_dynamic_buffer(struct msm_vidc_inst *inst, ion_phys_addr_t device_addr, u32 flags) { struct buffer_info *binfo = NULL, *temp = NULL; /* * Update reference count and release OR queue back the buffer, * only when firmware is not holding a reference. */ binfo = device_to_uvaddr(&inst->registeredbufs, device_addr); if (!binfo) { dprintk(VIDC_ERR, "%s buffer not found in registered list\n", __func__); return; } if (flags & HAL_BUFFERFLAG_READONLY) { dprintk(VIDC_DBG, "FBD fd[0] = %d -> Reference with f/w, addr: %pa\n", binfo->fd[0], &device_addr); } else { dprintk(VIDC_DBG, "FBD fd[0] = %d -> FBD_ref_released, addr: %pa\n", binfo->fd[0], &device_addr); mutex_lock(&inst->registeredbufs.lock); list_for_each_entry(temp, &inst->registeredbufs.list, list) { if (temp == binfo) { buf_ref_put(inst, binfo); break; } } mutex_unlock(&inst->registeredbufs.lock); } } static void handle_ebd(enum hal_command_response cmd, void *data) { struct msm_vidc_cb_data_done *response = data; Loading @@ -2182,6 +2219,9 @@ static void handle_ebd(enum hal_command_response cmd, void *data) dprintk(VIDC_WARN, "Got a response for an inactive session\n"); return; } if (inst->buffer_mode_set[OUTPUT_PORT] == HAL_BUFFER_MODE_DYNAMIC) handle_dynamic_buffer(inst, response->input_done.packet_buffer, 0); vb = get_vb_from_device_addr(&inst->bufq[OUTPUT_PORT], response->input_done.packet_buffer); Loading Loading @@ -2239,11 +2279,7 @@ int buf_ref_get(struct msm_vidc_inst *inst, struct buffer_info *binfo) atomic_inc(&binfo->ref_count); cnt = atomic_read(&binfo->ref_count); if (cnt > 2) { dprintk(VIDC_DBG, "%s: invalid ref_cnt: %d\n", __func__, cnt); cnt = -EINVAL; } if (cnt == 2) if (cnt >= 2) inst->buffers_held_in_driver++; dprintk(VIDC_DBG, "REF_GET[%d] fd[0] = %d\n", cnt, binfo->fd[0]); Loading @@ -2266,7 +2302,7 @@ int buf_ref_put(struct msm_vidc_inst *inst, struct buffer_info *binfo) dprintk(VIDC_DBG, "REF_PUT[%d] fd[0] = %d\n", cnt, binfo->fd[0]); if (!cnt) release_buf = true; else if (cnt == 1) else if (cnt >= 1) qbuf_again = true; else { dprintk(VIDC_DBG, "%s: invalid ref_cnt: %d\n", __func__, cnt); Loading Loading @@ -2297,45 +2333,6 @@ int buf_ref_put(struct msm_vidc_inst *inst, struct buffer_info *binfo) return cnt; } static void handle_dynamic_buffer(struct msm_vidc_inst *inst, ion_phys_addr_t device_addr, u32 flags) { struct buffer_info *binfo = NULL, *temp = NULL; /* * Update reference count and release OR queue back the buffer, * only when firmware is not holding a reference. */ if (inst->buffer_mode_set[CAPTURE_PORT] == HAL_BUFFER_MODE_DYNAMIC) { binfo = device_to_uvaddr(&inst->registeredbufs, device_addr); if (!binfo) { dprintk(VIDC_ERR, "%s buffer not found in registered list\n", __func__); return; } if (flags & HAL_BUFFERFLAG_READONLY) { dprintk(VIDC_DBG, "FBD fd[0] = %d -> Reference with f/w, addr: %pa\n", binfo->fd[0], &device_addr); } else { dprintk(VIDC_DBG, "FBD fd[0] = %d -> FBD_ref_released, addr: %pa\n", binfo->fd[0], &device_addr); mutex_lock(&inst->registeredbufs.lock); list_for_each_entry(temp, &inst->registeredbufs.list, list) { if (temp == binfo) { buf_ref_put(inst, binfo); break; } } mutex_unlock(&inst->registeredbufs.lock); } } } static int handle_multi_stream_buffers(struct msm_vidc_inst *inst, ion_phys_addr_t dev_addr) { Loading Loading @@ -2459,6 +2456,8 @@ static void handle_fbd(enum hal_command_response cmd, void *data) vb->planes[extra_idx].data_offset = 0; } if (inst->buffer_mode_set[CAPTURE_PORT] == HAL_BUFFER_MODE_DYNAMIC) handle_dynamic_buffer(inst, fill_buf_done->packet_buffer1, fill_buf_done->flags1); if (fill_buf_done->flags1 & HAL_BUFFERFLAG_READONLY) Loading Loading @@ -4854,20 +4853,22 @@ void msm_comm_flush_dynamic_buffers(struct msm_vidc_inst *inst) * driver should not queue any new buffer it has been holding. * * Each dynamic o/p buffer can have one of following ref_count: * ref_count : 0 - f/w has released reference and sent fbd back. * The buffer has been returned back to client. * ref_count : 0 - f/w has released reference and sent dynamic * buffer back. The buffer has been returned * back to client. * * ref_count : 1 - f/w is holding reference. f/w may have released * fbd as read_only OR fbd is pending. f/w will * release reference before sending flush_done. * dynamic buffer as read_only OR dynamic buffer is * pending. f/w will release reference before sending * flush_done. * * ref_count : 2 - f/w is holding reference, f/w has released fbd as * read_only, which client has queued back to driver. * driver holds this buffer and will queue back * only when f/w releases the reference. During * flush_done, f/w will release the reference but driver * should not queue back the buffer to f/w. * Flush all buffers with ref_count 2. * ref_count : >=2 - f/w is holding reference, f/w has released dynamic * buffer as read_only, which client has queued back * to driver. Driver holds this buffer and will queue * back only when f/w releases the reference. During * flush_done, f/w will release the reference but * driver should not queue back the buffer to f/w. * Flush all buffers with ref_count >= 2. */ mutex_lock(&inst->registeredbufs.lock); if (!list_empty(&inst->registeredbufs.list)) { Loading @@ -4876,7 +4877,7 @@ void msm_comm_flush_dynamic_buffers(struct msm_vidc_inst *inst) list_for_each_entry(binfo, &inst->registeredbufs.list, list) { if (binfo->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && atomic_read(&binfo->ref_count) == 2) { atomic_read(&binfo->ref_count) >= 2) { atomic_dec(&binfo->ref_count); buf_event.type = Loading drivers/media/platform/msm/vidc/msm_vidc_debug.c +1 −1 Original line number Diff line number Diff line Loading @@ -50,7 +50,7 @@ static struct debug_buffer dbg_buf; }) #define DYNAMIC_BUF_OWNER(__binfo) ({ \ atomic_read(&__binfo->ref_count) == 2 ? "video driver" : "firmware";\ atomic_read(&__binfo->ref_count) >= 2 ? "video driver" : "firmware";\ }) static int core_info_open(struct inode *inode, struct file *file) Loading Loading
drivers/media/platform/msm/vidc/msm_vidc.c +10 −9 Original line number Diff line number Diff line Loading @@ -497,11 +497,12 @@ static inline enum hal_buffer get_hal_buffer_type( return -EINVAL; } static inline bool is_dynamic_output_buffer_mode(struct v4l2_buffer *b, static inline bool is_dynamic_buffer_mode(struct v4l2_buffer *b, struct msm_vidc_inst *inst) { return b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && inst->buffer_mode_set[CAPTURE_PORT] == HAL_BUFFER_MODE_DYNAMIC; enum vidc_ports port = b->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ? OUTPUT_PORT : CAPTURE_PORT; return inst->buffer_mode_set[port] == HAL_BUFFER_MODE_DYNAMIC; } Loading Loading @@ -558,7 +559,7 @@ int map_and_register_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b) } mutex_lock(&inst->registeredbufs.lock); temp = get_registered_buf(inst, b, i, &plane); if (temp && !is_dynamic_output_buffer_mode(b, inst)) { if (temp && !is_dynamic_buffer_mode(b, inst)) { dprintk(VIDC_DBG, "This memory region has already been prepared\n"); rc = 0; Loading @@ -566,7 +567,7 @@ int map_and_register_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b) goto exit; } if (temp && is_dynamic_output_buffer_mode(b, inst) && !i) { if (temp && is_dynamic_buffer_mode(b, inst) && !i) { /* * Buffer is already present in registered list * increment ref_count, populate new values of v4l2 Loading Loading @@ -599,7 +600,7 @@ int map_and_register_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b) if (rc == 1) { rc = 0; goto exit; } else if (rc == 2) { } else if (rc >= 2) { rc = -EEXIST; goto exit; } Loading Loading @@ -629,7 +630,7 @@ int map_and_register_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b) } /* We maintain one ref count for all planes*/ if (!i && is_dynamic_output_buffer_mode(b, inst)) { if (!i && is_dynamic_buffer_mode(b, inst)) { rc = buf_ref_get(inst, binfo); if (rc < 0) goto exit; Loading Loading @@ -874,7 +875,7 @@ int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b) rc = map_and_register_buf(inst, b); if (rc == -EEXIST) { if (atomic_read(&inst->in_flush) && is_dynamic_output_buffer_mode(b, inst)) { is_dynamic_buffer_mode(b, inst)) { dprintk(VIDC_ERR, "Flush in progress, do not hold any buffers in driver\n"); msm_comm_flush_dynamic_buffers(inst); Loading Loading @@ -998,7 +999,7 @@ int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b) return rc; if (is_dynamic_output_buffer_mode(b, inst)) { if (is_dynamic_buffer_mode(b, inst)) { buffer_info->dequeued = true; dprintk(VIDC_DBG, "[DEQUEUED]: fd[0] = %d\n", Loading
drivers/media/platform/msm/vidc/msm_vidc_common.c +59 −58 Original line number Diff line number Diff line Loading @@ -2163,6 +2163,43 @@ static struct vb2_buffer *get_vb_from_device_addr(struct buf_queue *bufq, return vb; } static void handle_dynamic_buffer(struct msm_vidc_inst *inst, ion_phys_addr_t device_addr, u32 flags) { struct buffer_info *binfo = NULL, *temp = NULL; /* * Update reference count and release OR queue back the buffer, * only when firmware is not holding a reference. */ binfo = device_to_uvaddr(&inst->registeredbufs, device_addr); if (!binfo) { dprintk(VIDC_ERR, "%s buffer not found in registered list\n", __func__); return; } if (flags & HAL_BUFFERFLAG_READONLY) { dprintk(VIDC_DBG, "FBD fd[0] = %d -> Reference with f/w, addr: %pa\n", binfo->fd[0], &device_addr); } else { dprintk(VIDC_DBG, "FBD fd[0] = %d -> FBD_ref_released, addr: %pa\n", binfo->fd[0], &device_addr); mutex_lock(&inst->registeredbufs.lock); list_for_each_entry(temp, &inst->registeredbufs.list, list) { if (temp == binfo) { buf_ref_put(inst, binfo); break; } } mutex_unlock(&inst->registeredbufs.lock); } } static void handle_ebd(enum hal_command_response cmd, void *data) { struct msm_vidc_cb_data_done *response = data; Loading @@ -2182,6 +2219,9 @@ static void handle_ebd(enum hal_command_response cmd, void *data) dprintk(VIDC_WARN, "Got a response for an inactive session\n"); return; } if (inst->buffer_mode_set[OUTPUT_PORT] == HAL_BUFFER_MODE_DYNAMIC) handle_dynamic_buffer(inst, response->input_done.packet_buffer, 0); vb = get_vb_from_device_addr(&inst->bufq[OUTPUT_PORT], response->input_done.packet_buffer); Loading Loading @@ -2239,11 +2279,7 @@ int buf_ref_get(struct msm_vidc_inst *inst, struct buffer_info *binfo) atomic_inc(&binfo->ref_count); cnt = atomic_read(&binfo->ref_count); if (cnt > 2) { dprintk(VIDC_DBG, "%s: invalid ref_cnt: %d\n", __func__, cnt); cnt = -EINVAL; } if (cnt == 2) if (cnt >= 2) inst->buffers_held_in_driver++; dprintk(VIDC_DBG, "REF_GET[%d] fd[0] = %d\n", cnt, binfo->fd[0]); Loading @@ -2266,7 +2302,7 @@ int buf_ref_put(struct msm_vidc_inst *inst, struct buffer_info *binfo) dprintk(VIDC_DBG, "REF_PUT[%d] fd[0] = %d\n", cnt, binfo->fd[0]); if (!cnt) release_buf = true; else if (cnt == 1) else if (cnt >= 1) qbuf_again = true; else { dprintk(VIDC_DBG, "%s: invalid ref_cnt: %d\n", __func__, cnt); Loading Loading @@ -2297,45 +2333,6 @@ int buf_ref_put(struct msm_vidc_inst *inst, struct buffer_info *binfo) return cnt; } static void handle_dynamic_buffer(struct msm_vidc_inst *inst, ion_phys_addr_t device_addr, u32 flags) { struct buffer_info *binfo = NULL, *temp = NULL; /* * Update reference count and release OR queue back the buffer, * only when firmware is not holding a reference. */ if (inst->buffer_mode_set[CAPTURE_PORT] == HAL_BUFFER_MODE_DYNAMIC) { binfo = device_to_uvaddr(&inst->registeredbufs, device_addr); if (!binfo) { dprintk(VIDC_ERR, "%s buffer not found in registered list\n", __func__); return; } if (flags & HAL_BUFFERFLAG_READONLY) { dprintk(VIDC_DBG, "FBD fd[0] = %d -> Reference with f/w, addr: %pa\n", binfo->fd[0], &device_addr); } else { dprintk(VIDC_DBG, "FBD fd[0] = %d -> FBD_ref_released, addr: %pa\n", binfo->fd[0], &device_addr); mutex_lock(&inst->registeredbufs.lock); list_for_each_entry(temp, &inst->registeredbufs.list, list) { if (temp == binfo) { buf_ref_put(inst, binfo); break; } } mutex_unlock(&inst->registeredbufs.lock); } } } static int handle_multi_stream_buffers(struct msm_vidc_inst *inst, ion_phys_addr_t dev_addr) { Loading Loading @@ -2459,6 +2456,8 @@ static void handle_fbd(enum hal_command_response cmd, void *data) vb->planes[extra_idx].data_offset = 0; } if (inst->buffer_mode_set[CAPTURE_PORT] == HAL_BUFFER_MODE_DYNAMIC) handle_dynamic_buffer(inst, fill_buf_done->packet_buffer1, fill_buf_done->flags1); if (fill_buf_done->flags1 & HAL_BUFFERFLAG_READONLY) Loading Loading @@ -4854,20 +4853,22 @@ void msm_comm_flush_dynamic_buffers(struct msm_vidc_inst *inst) * driver should not queue any new buffer it has been holding. * * Each dynamic o/p buffer can have one of following ref_count: * ref_count : 0 - f/w has released reference and sent fbd back. * The buffer has been returned back to client. * ref_count : 0 - f/w has released reference and sent dynamic * buffer back. The buffer has been returned * back to client. * * ref_count : 1 - f/w is holding reference. f/w may have released * fbd as read_only OR fbd is pending. f/w will * release reference before sending flush_done. * dynamic buffer as read_only OR dynamic buffer is * pending. f/w will release reference before sending * flush_done. * * ref_count : 2 - f/w is holding reference, f/w has released fbd as * read_only, which client has queued back to driver. * driver holds this buffer and will queue back * only when f/w releases the reference. During * flush_done, f/w will release the reference but driver * should not queue back the buffer to f/w. * Flush all buffers with ref_count 2. * ref_count : >=2 - f/w is holding reference, f/w has released dynamic * buffer as read_only, which client has queued back * to driver. Driver holds this buffer and will queue * back only when f/w releases the reference. During * flush_done, f/w will release the reference but * driver should not queue back the buffer to f/w. * Flush all buffers with ref_count >= 2. */ mutex_lock(&inst->registeredbufs.lock); if (!list_empty(&inst->registeredbufs.list)) { Loading @@ -4876,7 +4877,7 @@ void msm_comm_flush_dynamic_buffers(struct msm_vidc_inst *inst) list_for_each_entry(binfo, &inst->registeredbufs.list, list) { if (binfo->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && atomic_read(&binfo->ref_count) == 2) { atomic_read(&binfo->ref_count) >= 2) { atomic_dec(&binfo->ref_count); buf_event.type = Loading
drivers/media/platform/msm/vidc/msm_vidc_debug.c +1 −1 Original line number Diff line number Diff line Loading @@ -50,7 +50,7 @@ static struct debug_buffer dbg_buf; }) #define DYNAMIC_BUF_OWNER(__binfo) ({ \ atomic_read(&__binfo->ref_count) == 2 ? "video driver" : "firmware";\ atomic_read(&__binfo->ref_count) >= 2 ? "video driver" : "firmware";\ }) static int core_info_open(struct inode *inode, struct file *file) Loading