Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 38ec6801 authored by Govindaraj Rajagopal's avatar Govindaraj Rajagopal
Browse files

msm: vidc: queue batched buffers upon timeout



Client expects all the buffers to be returned in certain scenarios
but driver does not return due to decode batching feature. Add
timer_list functionality to queue batched buffers to video hardware
upon timeout, so that all the buffers will be returned to client.

Change-Id: I926de1da93d941ff2a64bfec1bbd351de2f3a601
Signed-off-by: default avatarGovindaraj Rajagopal <grajagop@codeaurora.org>
parent 58b6ed92
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -1793,6 +1793,16 @@ static const struct v4l2_ctrl_ops msm_vidc_ctrl_ops = {
	.g_volatile_ctrl = msm_vidc_op_g_volatile_ctrl,
};

static void batch_timer_callback(unsigned long data)
{
	struct msm_vidc_inst *inst = (struct msm_vidc_inst *)data;

	if (!inst->batch.enable)
		return;

	schedule_work(&inst->batch_work);
}

void *msm_vidc_open(int core_id, int session_type)
{
	struct msm_vidc_inst *inst = NULL;
@@ -1928,6 +1938,10 @@ void *msm_vidc_open(int core_id, int session_type)
		}
	}

	INIT_WORK(&inst->batch_work, msm_vidc_batch_handler);
	setup_timer(&inst->batch_timer,
				batch_timer_callback, (unsigned long)inst);

	return inst;
fail_init:
	mutex_lock(&core->lock);
@@ -2007,6 +2021,8 @@ static void msm_vidc_cleanup_instance(struct msm_vidc_inst *inst)
	}
	mutex_unlock(&inst->registeredbufs.lock);

	del_timer(&inst->batch_timer);

	msm_comm_free_freq_table(inst);

	msm_comm_free_input_cr_table(inst);
+63 −26
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
#include "msm_vidc_clocks.h"
#include "msm_cvp.h"

#define MSM_VIDC_QBUF_BATCH_TIMEOUT 300
#define IS_ALREADY_IN_STATE(__p, __d) (\
	(__p >= __d)\
)
@@ -4334,6 +4335,26 @@ static int msm_comm_qbuf_to_hfi(struct msm_vidc_inst *inst,
	return rc;
}

void msm_vidc_batch_handler(struct work_struct *work)
{
	int rc = 0;
	struct msm_vidc_inst *inst;

	inst = container_of(work, struct msm_vidc_inst, batch_work);
	rc = msm_comm_scale_clocks_and_bus(inst);
	if (rc)
		dprintk(VIDC_ERR, "%s: scale clocks failed\n", __func__);

	dprintk(VIDC_INFO,
		"%s: queing batch pending buffers to firmware\n", __func__);

	rc = msm_comm_qbufs_batch(inst, NULL);
	if (rc) {
		dprintk(VIDC_ERR, "%s: Failed batch-qbuf to hfi: %d\n",
			__func__, rc);
	}
}

static int msm_comm_qbuf_in_rbr(struct msm_vidc_inst *inst,
		struct msm_vidc_buffer *mbuf)
{
@@ -4431,6 +4452,42 @@ int msm_comm_qbufs(struct msm_vidc_inst *inst)
	return rc;
}

int msm_comm_qbufs_batch(struct msm_vidc_inst *inst,
		struct msm_vidc_buffer *mbuf)
{
	int rc = 0;
	struct msm_vidc_buffer *buf;

	mutex_lock(&inst->registeredbufs.lock);
	list_for_each_entry(buf, &inst->registeredbufs.list, list) {
		/* Don't queue if buffer is not CAPTURE_MPLANE */
		if (buf->vvb.vb2_buf.type !=
			V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
			goto loop_end;
		/* Don't queue if buffer is not a deferred buffer */
		if (!(buf->flags & MSM_VIDC_FLAG_DEFERRED))
			goto loop_end;
		/* Don't queue if RBR event is pending on this buffer */
		if (buf->flags & MSM_VIDC_FLAG_RBR_PENDING)
			goto loop_end;

		print_vidc_buffer(VIDC_DBG, "batch-qbuf", inst, buf);
		rc = msm_comm_qbuf_to_hfi(inst, buf);
		if (rc) {
			dprintk(VIDC_ERR, "%s: Failed batch qbuf to hfi: %d\n",
				__func__, rc);
			break;
		}
loop_end:
		/* Queue pending buffers till the current buffer only */
		if (buf == mbuf)
			break;
	}
	mutex_unlock(&inst->registeredbufs.lock);

	return rc;
}

/*
 * msm_comm_qbuf_decode_batch - count the buffers which are not queued to
 *              firmware yet (count includes rbr pending buffers too) and
@@ -4443,7 +4500,6 @@ int msm_comm_qbuf_decode_batch(struct msm_vidc_inst *inst,
{
	int rc = 0;
	u32 count = 0;
	struct msm_vidc_buffer *buf;

	if (!inst || !mbuf) {
		dprintk(VIDC_ERR, "%s: Invalid arguments\n", __func__);
@@ -4466,6 +4522,8 @@ int msm_comm_qbuf_decode_batch(struct msm_vidc_inst *inst,
	 * due to batching
	*/
	if (inst->clk_data.buffer_counter > SKIP_BATCH_WINDOW) {
		mod_timer(&inst->batch_timer, jiffies +
			msecs_to_jiffies(MSM_VIDC_QBUF_BATCH_TIMEOUT));
		count = num_pending_qbufs(inst,
			V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
		if (count < inst->batch.size) {
@@ -4479,32 +4537,11 @@ int msm_comm_qbuf_decode_batch(struct msm_vidc_inst *inst,
	if (rc)
		dprintk(VIDC_ERR, "%s: scale clocks failed\n", __func__);

	mutex_lock(&inst->registeredbufs.lock);
	list_for_each_entry(buf, &inst->registeredbufs.list, list) {
		/* Don't queue if buffer is not CAPTURE_MPLANE */
		if (buf->vvb.vb2_buf.type !=
			V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
			goto loop_end;
		/* Don't queue if buffer is not a deferred buffer */
		if (!(buf->flags & MSM_VIDC_FLAG_DEFERRED))
			goto loop_end;
		/* Don't queue if RBR event is pending on this buffer */
		if (buf->flags & MSM_VIDC_FLAG_RBR_PENDING)
			goto loop_end;

		print_vidc_buffer(VIDC_DBG, "batch-qbuf", inst, buf);
		rc = msm_comm_qbuf_to_hfi(inst, buf);
	rc = msm_comm_qbufs_batch(inst, mbuf);
	if (rc) {
		dprintk(VIDC_ERR, "%s: Failed qbuf to hfi: %d\n",
			__func__, rc);
			break;
	}
loop_end:
		/* Queue pending buffers till the current buffer only */
		if (buf == mbuf)
			break;
	}
	mutex_unlock(&inst->registeredbufs.lock);

	return rc;
}
+3 −0
Original line number Diff line number Diff line
@@ -249,8 +249,11 @@ void msm_comm_store_mark_data(struct msm_vidc_list *data_list,
void msm_comm_fetch_mark_data(struct msm_vidc_list *data_list,
		u32 index, u32 *mark_data, u32 *mark_target);
int msm_comm_release_mark_data(struct msm_vidc_inst *inst);
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,
		struct msm_vidc_buffer *mbuf);
int msm_comm_num_queued_bufs(struct msm_vidc_inst *inst, u32 type);
bool msm_comm_check_for_inst_overload(struct msm_vidc_core *core);
void msm_vidc_batch_handler(struct work_struct *work);
#endif
+3 −0
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@
#include "msm_vidc.h"
#include <media/msm_media_info.h>
#include "vidc_hfi_api.h"
#include <linux/timer.h>

#define MSM_VIDC_DRV_NAME "msm_vidc_driver"
#define MSM_VIDC_VERSION KERNEL_VERSION(0, 0, 1)
@@ -476,6 +477,8 @@ struct msm_vidc_inst {
	struct msm_vidc_codec_data *codec_data;
	struct hal_hdr10_pq_sei hdr10_sei_params;
	struct batch_mode batch;
	struct timer_list batch_timer;
	struct work_struct batch_work;
};

extern struct msm_vidc_drv *vidc_driver;