Prechádzať zdrojové kódy

video: driver: packetize dynamic controls with buffer

packetize dynamic controls set via request api along
with corresponding input buffer under the same hfi header
and queue to FW.

Change-Id: I8bf82f7ccb1ab16c42ce02189a208f5f7cb8dc70
Signed-off-by: Darshana Patil <[email protected]>
Darshana Patil 3 rokov pred
rodič
commit
7c4952934b

+ 1 - 0
driver/vidc/inc/msm_vidc_inst.h

@@ -144,6 +144,7 @@ struct msm_vidc_inst {
 	struct list_head                   caps_list;
 	struct list_head                   children_list;
 	struct list_head                   firmware_list;
+	struct list_head                   pending_pkts; /* list of struct hfi_pending_packet */
 	bool                               once_per_session_set;
 	bool                               ipsc_properties_set;
 	bool                               opsc_properties_set;

+ 3 - 0
driver/vidc/inc/msm_vidc_memory.h

@@ -11,6 +11,8 @@
 struct msm_vidc_core;
 struct msm_vidc_inst;
 
+#define MSM_MEM_POOL_PACKET_SIZE 1024
+
 struct msm_memory_dmabuf {
 	struct list_head       list;
 	struct dma_buf        *dmabuf;
@@ -23,6 +25,7 @@ enum msm_memory_pool_type {
 	MSM_MEM_POOL_ALLOC,
 	MSM_MEM_POOL_TIMESTAMP,
 	MSM_MEM_POOL_DMABUF,
+	MSM_MEM_POOL_PACKET,
 	MSM_MEM_POOL_MAX,
 };
 

+ 5 - 0
driver/vidc/inc/venus_hfi.h

@@ -28,6 +28,11 @@ struct vidc_buffer_addr_info {
 	u32 response_required;
 };
 
+struct hfi_pending_packet {
+	struct list_head       list;
+	void                  *data;
+};
+
 int venus_hfi_session_property(struct msm_vidc_inst *inst,
 	u32 pkt_type, u32 flags, u32 port,
 	u32 payload_type, void *payload, u32 payload_size);

+ 1 - 0
driver/vidc/src/msm_vidc.c

@@ -945,6 +945,7 @@ void *msm_vidc_open(void *vidc_core, u32 session_type)
 	INIT_LIST_HEAD(&inst->firmware_list);
 	INIT_LIST_HEAD(&inst->enc_input_crs);
 	INIT_LIST_HEAD(&inst->dmabuf_tracker);
+	INIT_LIST_HEAD(&inst->pending_pkts);
 	for (i = 0; i < MAX_SIGNAL; i++)
 		init_completion(&inst->completions[i]);
 

+ 0 - 8
driver/vidc/src/msm_vidc_control.c

@@ -945,14 +945,6 @@ int msm_v4l2_op_s_ctrl(struct v4l2_ctrl *ctrl)
 		kfree(curr_node);
 	}
 
-	/* dynamic controls with request will be set along with qbuf */
-	if (inst->request) {
-		i_vpr_l(inst,
-			"%s: request api enabled, dynamic ctrls to be set with qbuf\n",
-			__func__);
-		return 0;
-	}
-
 	/* Dynamic set control ASAP */
 	rc = msm_vidc_set_v4l2_properties(inst);
 	if (rc) {

+ 3 - 0
driver/vidc/src/msm_vidc_memory.c

@@ -17,6 +17,7 @@
 #include "msm_vidc_dt.h"
 #include "msm_vidc_core.h"
 #include "msm_vidc_events.h"
+#include "venus_hfi.h"
 
 struct msm_vidc_buf_region_name {
 	enum msm_vidc_buffer_region region;
@@ -589,6 +590,8 @@ static struct msm_vidc_type_size_name buftype_size_name_arr[] = {
 	{MSM_MEM_POOL_ALLOC,      sizeof(struct msm_vidc_alloc),      "MSM_MEM_POOL_ALLOC"      },
 	{MSM_MEM_POOL_TIMESTAMP,  sizeof(struct msm_vidc_timestamp),  "MSM_MEM_POOL_TIMESTAMP"  },
 	{MSM_MEM_POOL_DMABUF,     sizeof(struct msm_memory_dmabuf),   "MSM_MEM_POOL_DMABUF"     },
+	{MSM_MEM_POOL_PACKET,     sizeof(struct hfi_pending_packet) + MSM_MEM_POOL_PACKET_SIZE,
+		"MSM_MEM_POOL_PACKET"},
 };
 
 int msm_memory_pools_init(struct msm_vidc_inst *inst)

+ 89 - 0
driver/vidc/src/venus_hfi.c

@@ -3047,6 +3047,43 @@ unlock:
 	return rc;
 }
 
+static int venus_hfi_cache_packet(struct msm_vidc_inst *inst)
+{
+	int rc = 0;
+	struct hfi_header *hdr;
+	struct hfi_pending_packet *packet;
+
+	if (!inst->packet) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
+
+	hdr = (struct hfi_header *)inst->packet;
+	if (hdr->size < sizeof(struct hfi_header)) {
+		d_vpr_e("%s: invalid hdr size %d\n", __func__, hdr->size);
+		return -EINVAL;
+	}
+
+	packet = msm_memory_pool_alloc(inst, MSM_MEM_POOL_PACKET);
+	if (!packet) {
+		i_vpr_e(inst, "%s: failed to allocate pending packet\n", __func__);
+		return -ENOMEM;
+	}
+
+	INIT_LIST_HEAD(&packet->list);
+	list_add_tail(&packet->list, &inst->pending_pkts);
+	packet->data = (u8 *)packet + sizeof(struct hfi_pending_packet);
+
+	if (hdr->size > MSM_MEM_POOL_PACKET_SIZE) {
+		i_vpr_e(inst, "%s: header size %d exceeds pool packet size %d\n",
+			__func__, hdr->size, MSM_MEM_POOL_PACKET_SIZE);
+		return -EINVAL;
+	}
+	memcpy(packet->data, inst->packet, hdr->size);
+
+	return rc;
+}
+
 int venus_hfi_session_property(struct msm_vidc_inst *inst,
 	u32 pkt_type, u32 flags, u32 port, u32 payload_type,
 	void *payload, u32 payload_size)
@@ -3081,6 +3118,12 @@ int venus_hfi_session_property(struct msm_vidc_inst *inst,
 	if (rc)
 		goto unlock;
 
+	/* skip sending packet to firmware */
+	if (inst->request) {
+		rc = venus_hfi_cache_packet(inst);
+		goto unlock;
+	}
+
 	rc = __iface_cmdq_write(inst->core, inst->packet);
 	if (rc)
 		goto unlock;
@@ -3381,6 +3424,48 @@ unlock:
 	return rc;
 }
 
+static int venus_hfi_add_pending_packets(struct msm_vidc_inst *inst)
+{
+	int rc = 0;
+	int num_packets = 0;
+	struct hfi_pending_packet *pkt_info, *dummy;
+	struct hfi_header *hdr, *src_hdr;
+	struct hfi_packet *src_pkt;
+
+	if (!inst || !inst->packet) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
+
+	hdr = (struct hfi_header *)inst->packet;
+	if (hdr->size < sizeof(struct hfi_header)) {
+		i_vpr_e(inst, "%s: invalid hdr size %d\n",
+			__func__, hdr->size);
+		return -EINVAL;
+	}
+
+	list_for_each_entry_safe(pkt_info, dummy, &inst->pending_pkts, list) {
+		src_hdr = (struct hfi_header *)(pkt_info->data);
+		num_packets = src_hdr->num_packets;
+		src_pkt = (struct hfi_packet *)((u8 *)src_hdr + sizeof(struct hfi_header));
+		while (num_packets > 0) {
+			memcpy((u8 *)hdr + hdr->size, (void *)src_pkt, src_pkt->size);
+			hdr->num_packets++;
+			hdr->size += src_pkt->size;
+			num_packets--;
+			src_pkt = (struct hfi_packet *)((u8 *)src_pkt + src_pkt->size);
+			if ((u8 *)src_pkt < (u8 *)src_hdr ||
+					(u8 *)src_pkt > (u8 *)src_hdr + hdr->size) {
+				i_vpr_e(inst, "%s: invalid packet address\n", __func__);
+				return -EINVAL;
+			}
+		}
+		list_del(&pkt_info->list);
+		msm_memory_pool_free(inst, pkt_info);
+	}
+	return rc;
+}
+
 int venus_hfi_queue_buffer(struct msm_vidc_inst *inst,
 	struct msm_vidc_buffer *buffer, struct msm_vidc_buffer *metabuf)
 {
@@ -3438,6 +3523,10 @@ int venus_hfi_queue_buffer(struct msm_vidc_inst *inst,
 			goto unlock;
 	}
 
+	rc = venus_hfi_add_pending_packets(inst);
+	if (rc)
+		goto unlock;
+
 	rc = __iface_cmdq_write(inst->core, inst->packet);
 	if (rc)
 		goto unlock;