msm: vidc: Add encoder input buffers dynamic
Video encoder clients can queue new input buffers anytime.
Hence video driver should handle them as dynamic buffers.
CRs-Fixed: 2023979
Change-Id: I13a6693122207984d290f227ab01186c2e8a4970
Signed-off-by: Praneeth Paladugu <ppaladug@codeaurora.org>
Signed-off-by: Karthikeyan Periasamy <kperiasa@codeaurora.org>
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index 14725de..040c59a 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -2163,6 +2163,43 @@
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;
@@ -2182,6 +2219,9 @@
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);
@@ -2239,11 +2279,7 @@
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]);
@@ -2266,7 +2302,7 @@
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);
@@ -2297,45 +2333,6 @@
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)
{
@@ -2459,6 +2456,8 @@
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)
@@ -4854,20 +4853,22 @@
* 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.
+ * ref_count : 1 - f/w is holding reference. f/w may have released
+ * 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)) {
@@ -4876,7 +4877,7 @@
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 =