From 455cd2b148a7e330b49a7b46c1d67c79c7bada43 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Fri, 28 Feb 2020 17:42:40 +0530 Subject: [PATCH] msm: vidc: update input tag implementation In qbuf (input) store input_tag to etb_data list and send it to firmware in etb. Firmware will return input_tag in ftb_done, store it in fbd_data list and return the same when client does dqbuf (output). Change-Id: I3589e5a3017cac49000fc64191f9f756bc4011f4 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc.c | 50 +++----------- msm/vidc/msm_vidc_common.c | 122 ++++------------------------------- msm/vidc/msm_vidc_common.h | 7 +- msm/vidc/msm_vidc_internal.h | 7 -- 4 files changed, 23 insertions(+), 163 deletions(-) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 95a033d740b0..7173d008e920 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -363,7 +363,6 @@ int msm_vidc_qbuf(void *instance, struct media_device *mdev, struct v4l2_buffer *b) { struct msm_vidc_inst *inst = instance; - struct msm_vidc_client_data *client_data = NULL; int rc = 0; unsigned int i = 0; struct buf_queue *q = NULL; @@ -402,16 +401,15 @@ int msm_vidc_qbuf(void *instance, struct media_device *mdev, } if (b->type == INPUT_MPLANE) { - client_data = msm_comm_store_client_data(inst, - b->m.planes[0].reserved[MSM_VIDC_INPUT_TAG_1]); - if (!client_data) { - s_vpr_e(inst->sid, - "%s: failed to store client data\n", __func__); + rc = msm_comm_store_input_tag(&inst->etb_data, b->index, + b->m.planes[0].reserved[MSM_VIDC_INPUT_TAG_1], + 0, inst->sid); + if (rc) { + s_vpr_e(inst->sid, "Failed to store input tag"); return -EINVAL; } - msm_comm_store_input_tag(&inst->etb_data, b->index, - client_data->id, 0, inst->sid); } + /* * set perf mode for image session buffers so that * they will be processed quickly @@ -442,8 +440,6 @@ int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b) int rc = 0; unsigned int i = 0; struct buf_queue *q = NULL; - u32 input_tag = 0, input_tag2 = 0; - bool remove; if (!inst || !b || !valid_v4l2_buffer(b, inst)) { d_vpr_e("%s: invalid params, %pK %pK\n", @@ -474,36 +470,15 @@ int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b) b->m.planes[i].reserved[MSM_VIDC_DATA_OFFSET] = b->m.planes[i].data_offset; } - /** - * Flush handling: - * Don't fetch tag - if flush issued at input/output port. - * Fetch tag - if atleast 1 ebd received after flush. (Flush_done - * event may be notified to userspace even before client - * dequeus all buffers at FBD, to avoid this race condition - * fetch tag atleast 1 ETB is successfully processed after flush) - */ - if (b->type == OUTPUT_MPLANE && !inst->in_flush && - !inst->out_flush && - (inst->session_type == MSM_VIDC_ENCODER || - inst->clk_data.buffer_counter)) { + if (b->type == OUTPUT_MPLANE) { rc = msm_comm_fetch_input_tag(&inst->fbd_data, b->index, - &input_tag, &input_tag2, inst->sid); + &b->m.planes[0].reserved[MSM_VIDC_INPUT_TAG_1], + &b->m.planes[0].reserved[MSM_VIDC_INPUT_TAG_2], + inst->sid); if (rc) { s_vpr_e(inst->sid, "Failed to fetch input tag"); return -EINVAL; } - /** - * During flush input_tag & input_tag2 will be zero. - * Check before retrieving client data - */ - if (input_tag) { - remove = !(b->flags & V4L2_BUF_FLAG_END_OF_SUBFRAME) && - !(b->flags & V4L2_BUF_FLAG_CODECCONFIG); - msm_comm_fetch_client_data(inst, remove, - input_tag, input_tag2, - &b->m.planes[0].reserved[MSM_VIDC_INPUT_TAG_1], - &b->m.planes[0].reserved[MSM_VIDC_INPUT_TAG_2]); - } } return rc; @@ -1470,7 +1445,6 @@ void *msm_vidc_open(int core_id, int session_type) INIT_MSM_VIDC_LIST(&inst->registeredbufs); INIT_MSM_VIDC_LIST(&inst->refbufs); INIT_MSM_VIDC_LIST(&inst->eosbufs); - INIT_MSM_VIDC_LIST(&inst->client_data); INIT_MSM_VIDC_LIST(&inst->etb_data); INIT_MSM_VIDC_LIST(&inst->fbd_data); INIT_MSM_VIDC_LIST(&inst->window_data); @@ -1575,7 +1549,6 @@ fail_bufq_capture: DEINIT_MSM_VIDC_LIST(&inst->registeredbufs); DEINIT_MSM_VIDC_LIST(&inst->eosbufs); DEINIT_MSM_VIDC_LIST(&inst->input_crs); - DEINIT_MSM_VIDC_LIST(&inst->client_data); DEINIT_MSM_VIDC_LIST(&inst->etb_data); DEINIT_MSM_VIDC_LIST(&inst->fbd_data); DEINIT_MSM_VIDC_LIST(&inst->window_data); @@ -1645,8 +1618,6 @@ static void msm_vidc_cleanup_instance(struct msm_vidc_inst *inst) if (msm_comm_release_input_tag(inst)) s_vpr_e(inst->sid, "Failed to release input_tag buffers\n"); - msm_comm_release_client_data(inst, true); - msm_comm_release_window_data(inst); msm_comm_release_eos_buffers(inst); @@ -1702,7 +1673,6 @@ int msm_vidc_destroy(struct msm_vidc_inst *inst) DEINIT_MSM_VIDC_LIST(&inst->registeredbufs); DEINIT_MSM_VIDC_LIST(&inst->eosbufs); DEINIT_MSM_VIDC_LIST(&inst->input_crs); - DEINIT_MSM_VIDC_LIST(&inst->client_data); DEINIT_MSM_VIDC_LIST(&inst->etb_data); DEINIT_MSM_VIDC_LIST(&inst->fbd_data); DEINIT_MSM_VIDC_LIST(&inst->window_data); diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index f51f5d82ab82..d1d0a851aa4a 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -2042,7 +2042,6 @@ static void handle_session_flush(enum hal_command_response cmd, void *data) if (flush_type == HAL_FLUSH_ALL) { msm_comm_clear_window_data(inst); - msm_comm_release_client_data(inst, false); inst->clk_data.buffer_counter = 0; } @@ -2511,6 +2510,7 @@ static void handle_fbd(enum hal_command_response cmd, void *data) u64 time_usec = 0; u32 planes[VIDEO_MAX_PLANES] = {0}; struct v4l2_format *f; + int rc = 0; if (!response) { d_vpr_e("Invalid response from vidc_hal\n"); @@ -2574,8 +2574,11 @@ static void handle_fbd(enum hal_command_response cmd, void *data) vb->timestamp = (time_usec * NSEC_PER_USEC); - msm_comm_store_input_tag(&inst->fbd_data, vb->index, - fill_buf_done->input_tag, fill_buf_done->input_tag2, inst->sid); + rc = msm_comm_store_input_tag(&inst->fbd_data, vb->index, + fill_buf_done->input_tag, + fill_buf_done->input_tag2, inst->sid); + if (rc) + s_vpr_e(inst->sid, "Failed to store input tag"); if (inst->session_type == MSM_VIDC_ENCODER) { if (inst->max_filled_len < fill_buf_done->filled_len1) @@ -6783,120 +6786,16 @@ bool kref_get_mbuf(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf) return ret; } -struct msm_vidc_client_data *msm_comm_store_client_data( - struct msm_vidc_inst *inst, u32 itag) -{ - struct msm_vidc_client_data *data = NULL, *temp = NULL; - - if (!inst) { - d_vpr_e("%s: invalid params\n", __func__); - return NULL; - } - - mutex_lock(&inst->client_data.lock); - list_for_each_entry(temp, &inst->client_data.list, list) { - if (!temp->id) { - data = temp; - break; - } - } - if (!data) { - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) { - s_vpr_e(inst->sid, "%s: No memory avilable", __func__); - goto exit; - } - INIT_LIST_HEAD(&data->list); - list_add_tail(&data->list, &inst->client_data.list); - } - - /** - * Special handling, if etb_counter reaches to 2^32 - 1, - * then start next value from 1 not 0. - */ - if (!inst->etb_counter) - inst->etb_counter = 1; - - data->id = inst->etb_counter++; - data->input_tag = itag; - -exit: - mutex_unlock(&inst->client_data.lock); - - return data; -} - -void msm_comm_fetch_client_data(struct msm_vidc_inst *inst, bool remove, - u32 itag, u32 itag2, u32 *otag, u32 *otag2) -{ - struct msm_vidc_client_data *temp, *next; - bool found_itag = false, found_itag2 = false; - - if (!inst || !otag || !otag2) { - d_vpr_e("%s: invalid params %pK %x %x\n", - __func__, inst, otag, otag2); - return; - } - /** - * Some interlace clips, both BF & TF is available in single ETB buffer. - * In that case, firmware copies same input_tag value to both input_tag - * and input_tag2 at FBD. - */ - if (!itag2 || itag == itag2) - found_itag2 = true; - mutex_lock(&inst->client_data.lock); - list_for_each_entry_safe(temp, next, &inst->client_data.list, list) { - if (temp->id == itag) { - *otag = temp->input_tag; - found_itag = true; - if (remove) - temp->id = 0; - } else if (!found_itag2 && temp->id == itag2) { - *otag2 = temp->input_tag; - found_itag2 = true; - if (remove) - temp->id = 0; - } - if (found_itag && found_itag2) - break; - } - mutex_unlock(&inst->client_data.lock); - - if (!found_itag || !found_itag2) { - s_vpr_e(inst->sid, "%s: client data not found - %u, %u\n", - __func__, itag, itag2); - } -} - -void msm_comm_release_client_data(struct msm_vidc_inst *inst, bool remove) -{ - struct msm_vidc_client_data *temp, *next; - - if (!inst) { - d_vpr_e("%s: invalid params\n", __func__); - return; - } - - mutex_lock(&inst->client_data.lock); - list_for_each_entry_safe(temp, next, &inst->client_data.list, list) { - temp->id = 0; - if (remove) { - list_del(&temp->list); - kfree(temp); - } - } - mutex_unlock(&inst->client_data.lock); -} - -void msm_comm_store_input_tag(struct msm_vidc_list *data_list, +int msm_comm_store_input_tag(struct msm_vidc_list *data_list, u32 index, u32 itag, u32 itag2, u32 sid) { struct msm_vidc_buf_data *pdata = NULL; bool found = false; + int rc = 0; if (!data_list) { s_vpr_e(sid, "%s: invalid params\n", __func__); - return; + return -EINVAL; } mutex_lock(&data_list->lock); @@ -6913,6 +6812,7 @@ void msm_comm_store_input_tag(struct msm_vidc_list *data_list, pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); if (!pdata) { s_vpr_e(sid, "%s: malloc failure.\n", __func__); + rc = -ENOMEM; goto exit; } pdata->index = index; @@ -6923,6 +6823,8 @@ void msm_comm_store_input_tag(struct msm_vidc_list *data_list, exit: mutex_unlock(&data_list->lock); + + return rc; } int msm_comm_fetch_input_tag(struct msm_vidc_list *data_list, diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index 39ec0fcd8a22..79a83cd42b3b 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -308,16 +308,11 @@ void print_vb2_buffer(const char *str, struct msm_vidc_inst *inst, struct vb2_buffer *vb2); void kref_put_mbuf(struct msm_vidc_buffer *mbuf); bool kref_get_mbuf(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf); -void msm_comm_store_input_tag(struct msm_vidc_list *data_list, +int msm_comm_store_input_tag(struct msm_vidc_list *data_list, u32 index, u32 itag, u32 itag2, u32 sid); int msm_comm_fetch_input_tag(struct msm_vidc_list *data_list, u32 index, u32 *itag, u32 *itag2, u32 sid); int msm_comm_release_input_tag(struct msm_vidc_inst *inst); -struct msm_vidc_client_data *msm_comm_store_client_data( - struct msm_vidc_inst *inst, u32 itag); -void msm_comm_fetch_client_data(struct msm_vidc_inst *inst, bool remove, - u32 itag, u32 itag2, u32 *mdata, u32 *mtarget); -void msm_comm_release_client_data(struct msm_vidc_inst *inst, bool remove); int msm_comm_qbufs_batch(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf); int msm_comm_qbuf_decode_batch(struct msm_vidc_inst *inst, diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index 33bbd0b24e00..a3b8400cb1f9 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -204,12 +204,6 @@ struct msm_vidc_window_data { u32 etb_count; }; -struct msm_vidc_client_data { - struct list_head list; - u32 id; - u32 input_tag; -}; - struct msm_vidc_common_data { char key[128]; int value; @@ -530,7 +524,6 @@ struct msm_vidc_inst { enum multi_stream stream_output_mode; struct v4l2_ctrl **ctrls; u32 num_ctrls; - u32 etb_counter; int bit_depth; struct kref kref; bool in_flush;