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

Commit f9ef817a authored by Praneeth Paladugu's avatar Praneeth Paladugu
Browse files

msm: vidc: Add support for decoder STOP command



Decoder STOP command is to signal HW that this is the EOS
buffer. HW returns all the pending ETB's and FTB's. One of
the FTB_DONE's will have EOS flag back to client. With this,
driver don't need to support zero_bytes_used input buffers.

CRs-Fixed: 2078801
Signed-off-by: default avatarPraneeth Paladugu <ppaladug@codeaurora.org>
Change-Id: I44c60db1c98707501b5637eba5d1d81663d6a722
parent 4d9a308b
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -1110,7 +1110,7 @@ static inline int vb2_bufq_init(struct msm_vidc_inst *inst,

	q->mem_ops = &msm_vidc_vb2_mem_ops;
	q->drv_priv = inst;
	q->allow_zero_bytesused = 1;
	q->allow_zero_bytesused = !V4L2_TYPE_IS_OUTPUT(type);
	q->copy_timestamp = 1;
	return vb2_queue_init(q);
}
@@ -1493,6 +1493,7 @@ void *msm_vidc_open(int core_id, int session_type)
	INIT_MSM_VIDC_LIST(&inst->outputbufs);
	INIT_MSM_VIDC_LIST(&inst->registeredbufs);
	INIT_MSM_VIDC_LIST(&inst->reconbufs);
	INIT_MSM_VIDC_LIST(&inst->eosbufs);

	kref_init(&inst->kref);

@@ -1597,6 +1598,7 @@ void *msm_vidc_open(int core_id, int session_type)
	DEINIT_MSM_VIDC_LIST(&inst->pending_getpropq);
	DEINIT_MSM_VIDC_LIST(&inst->outputbufs);
	DEINIT_MSM_VIDC_LIST(&inst->registeredbufs);
	DEINIT_MSM_VIDC_LIST(&inst->eosbufs);

	kfree(inst);
	inst = NULL;
@@ -1644,6 +1646,8 @@ static void msm_vidc_cleanup_instance(struct msm_vidc_inst *inst)
	 */
	msm_comm_validate_output_buffers(inst);

	msm_comm_release_eos_buffers(inst);

	if (msm_comm_release_output_buffers(inst, true))
		dprintk(VIDC_ERR,
			"Failed to release output buffers\n");
@@ -1688,6 +1692,7 @@ int msm_vidc_destroy(struct msm_vidc_inst *inst)
	DEINIT_MSM_VIDC_LIST(&inst->pending_getpropq);
	DEINIT_MSM_VIDC_LIST(&inst->outputbufs);
	DEINIT_MSM_VIDC_LIST(&inst->registeredbufs);
	DEINIT_MSM_VIDC_LIST(&inst->eosbufs);

	mutex_destroy(&inst->sync_lock);
	mutex_destroy(&inst->bufq[CAPTURE_PORT].lock);
+105 −0
Original line number Diff line number Diff line
@@ -2172,6 +2172,26 @@ int msm_comm_vb2_buffer_done(struct msm_vidc_inst *inst,
	return 0;
}

static bool is_eos_buffer(struct msm_vidc_inst *inst, u32 device_addr)
{
	struct eos_buf *temp, *next;
	bool found = false;

	mutex_lock(&inst->eosbufs.lock);
	list_for_each_entry_safe(temp, next, &inst->eosbufs.list, list) {
		if (temp->smem.device_addr == device_addr) {
			found = true;
			list_del(&temp->list);
			msm_comm_smem_free(inst, &temp->smem);
			kfree(temp);
			break;
		}
	}
	mutex_unlock(&inst->eosbufs.lock);

	return found;
}

static void handle_ebd(enum hal_command_response cmd, void *data)
{
	struct msm_vidc_cb_data_done *response = data;
@@ -2196,6 +2216,13 @@ static void handle_ebd(enum hal_command_response cmd, void *data)
	}

	empty_buf_done = (struct vidc_hal_ebd *)&response->input_done;
	/* If this is internal EOS buffer, handle it in driver */
	if (is_eos_buffer(inst, empty_buf_done->packet_buffer)) {
		dprintk(VIDC_DBG, "Received EOS buffer %pK\n",
			(void *)(u64)empty_buf_done->packet_buffer);
		goto exit;
	}

	planes[0] = empty_buf_done->packet_buffer;
	planes[1] = empty_buf_done->extra_data_buffer;

@@ -3643,6 +3670,64 @@ int msm_vidc_comm_cmd(void *instance, union msm_v4l2_cmd *cmd)
		rc = msm_comm_session_continue(inst);
		break;
	}
	case V4L2_DEC_CMD_STOP:
	{
		struct vidc_frame_data data = {0};
		struct hfi_device *hdev;
		struct eos_buf *binfo;
		u32 smem_flags = 0;

		get_inst(inst->core, inst);
		if (inst->session_type != MSM_VIDC_DECODER) {
			dprintk(VIDC_DBG,
				"Non-Decoder session. DEC_STOP is not valid\n");
			rc = -EINVAL;
			goto exit;
		}

		binfo = kzalloc(sizeof(*binfo), GFP_KERNEL);
		if (!binfo) {
			dprintk(VIDC_ERR, "%s: Out of memory\n", __func__);
			rc = -ENOMEM;
			goto exit;
		}

		if (inst->flags & VIDC_SECURE)
			smem_flags |= SMEM_SECURE;

		rc = msm_comm_smem_alloc(inst,
				SZ_4K, 1, smem_flags,
				HAL_BUFFER_INPUT, 0, &binfo->smem);
		if (rc) {
			dprintk(VIDC_ERR,
				"Failed to allocate output memory\n");
			goto exit;
		}

		mutex_lock(&inst->eosbufs.lock);
		list_add_tail(&binfo->list, &inst->eosbufs.list);
		mutex_unlock(&inst->eosbufs.lock);

		data.alloc_len = binfo->smem.size;
		data.device_addr = binfo->smem.device_addr;
		data.clnt_data = data.device_addr;
		data.buffer_type = HAL_BUFFER_INPUT;
		data.filled_len = 0;
		data.offset = 0;
		data.flags = HAL_BUFFERFLAG_EOS;
		data.timestamp = LLONG_MAX;
		data.extradata_addr = data.device_addr;
		data.extradata_size = 0;
		dprintk(VIDC_DBG, "Queueing EOS buffer %pK\n",
			(void *)(u64)data.device_addr);
		hdev = inst->core->device;

		rc = call_hfi_op(hdev, session_etb, inst->session,
				&data);
exit:
		put_inst(inst);
		break;
	}
	default:
		dprintk(VIDC_ERR, "Unknown Command %d\n", which_cmd);
		rc = -ENOTSUPP;
@@ -4424,6 +4509,26 @@ int msm_comm_release_scratch_buffers(struct msm_vidc_inst *inst,
	return rc;
}

void msm_comm_release_eos_buffers(struct msm_vidc_inst *inst)
{
	struct eos_buf *buf, *next;

	if (!inst) {
		dprintk(VIDC_ERR,
			"Invalid instance pointer = %pK\n", inst);
		return;
	}

	mutex_lock(&inst->eosbufs.lock);
	list_for_each_entry_safe(buf, next, &inst->eosbufs.list, list) {
		list_del(&buf->list);
		kfree(buf);
	}
	INIT_LIST_HEAD(&inst->eosbufs.list);
	mutex_unlock(&inst->eosbufs.lock);
}


int msm_comm_release_recon_buffers(struct msm_vidc_inst *inst)
{
	struct recon_buf *buf, *next;
+1 −0
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ int msm_comm_release_scratch_buffers(struct msm_vidc_inst *inst,
					bool check_for_reuse);
int msm_comm_release_persist_buffers(struct msm_vidc_inst *inst);
int msm_comm_release_recon_buffers(struct msm_vidc_inst *inst);
void msm_comm_release_eos_buffers(struct msm_vidc_inst *inst);
int msm_comm_release_output_buffers(struct msm_vidc_inst *inst,
	bool force_release);
void msm_comm_validate_output_buffers(struct msm_vidc_inst *inst);
+6 −0
Original line number Diff line number Diff line
@@ -150,6 +150,11 @@ struct recon_buf {
	u32 CF;
};

struct eos_buf {
	struct list_head list;
	struct msm_smem smem;
};

struct internal_buf {
	struct list_head list;
	enum hal_buffer buffer_type;
@@ -326,6 +331,7 @@ struct msm_vidc_inst {
	struct msm_vidc_list pending_getpropq;
	struct msm_vidc_list outputbufs;
	struct msm_vidc_list reconbufs;
	struct msm_vidc_list eosbufs;
	struct msm_vidc_list registeredbufs;
	struct buffer_requirements buff_req;
	struct smem_client *mem_client;