Jelajahi Sumber

driver: vidc: add support for control initialization

Add support for control initialization and set control
implementation. Modified hfi_create_header() and
hfi_create_packet() to handle offset and num_packets
within in the function itself.

Change-Id: If8560be8a884c5df2fcc91f75be90311f1003a41
Signed-off-by: Akshata Sahukar <[email protected]>
Signed-off-by: Maheshwar Ajja <[email protected]>
Akshata Sahukar 4 tahun lalu
induk
melakukan
6246ad4ce9

+ 1 - 0
Makefile

@@ -21,6 +21,7 @@ msm-vidc-objs   := driver/vidc/src/msm_vidc_v4l2.o \
                    driver/vidc/src/msm_vdec.o \
                    driver/vidc/src/msm_vdec.o \
                    driver/vidc/src/msm_venc.o \
                    driver/vidc/src/msm_venc.o \
                    driver/vidc/src/msm_vidc_driver.o \
                    driver/vidc/src/msm_vidc_driver.o \
+                   driver/vidc/src/msm_vidc_control.o \
                    driver/vidc/src/msm_vidc_buffer.o \
                    driver/vidc/src/msm_vidc_buffer.o \
                    driver/vidc/src/msm_vidc_probe.o \
                    driver/vidc/src/msm_vidc_probe.o \
                    driver/vidc/src/msm_vidc_dt.o \
                    driver/vidc/src/msm_vidc_dt.o \

+ 49 - 3
driver/platform/waipio/src/msm_vidc_waipio.c

@@ -10,6 +10,8 @@
 #include "msm_vidc_debug.h"
 #include "msm_vidc_debug.h"
 #include "msm_vidc_internal.h"
 #include "msm_vidc_internal.h"
 #include "msm_vidc_core.h"
 #include "msm_vidc_core.h"
+#include "msm_vidc_control.h"
+#include "hfi_property.h"
 
 
 #define DDR_TYPE_LPDDR4 0x6
 #define DDR_TYPE_LPDDR4 0x6
 #define DDR_TYPE_LPDDR4X 0x7
 #define DDR_TYPE_LPDDR4X 0x7
@@ -82,7 +84,14 @@ static struct msm_platform_core_capability core_data_waipio[] = {
 };
 };
 
 
 static struct msm_platform_inst_capability instance_data_waipio[] = {
 static struct msm_platform_inst_capability instance_data_waipio[] = {
-	/* {type, domains, codecs, min, max, step_or_mask, value} */
+	/* {cap, domain, codec,
+	 *      min, max, step_or_mask, value,
+	 *      v4l2_id, hfi_id,
+	 *      flags,
+	 *      parents,
+	 *      children,
+	 *      adjust, set}
+	 */
 	{FRAME_WIDTH, ENC|DEC, CODECS_ALL, 128, 8192, 1, 1920},
 	{FRAME_WIDTH, ENC|DEC, CODECS_ALL, 128, 8192, 1, 1920},
 	{FRAME_HEIGHT, ENC|DEC, CODECS_ALL, 128, 8192, 1, 1080},
 	{FRAME_HEIGHT, ENC|DEC, CODECS_ALL, 128, 8192, 1, 1080},
 	{PIX_FMTS, ENC, CODECS_ALL,
 	{PIX_FMTS, ENC, CODECS_ALL,
@@ -104,8 +113,45 @@ static struct msm_platform_inst_capability instance_data_waipio[] = {
 	/* ((1920 * 1088) / 256) * 960 fps */
 	/* ((1920 * 1088) / 256) * 960 fps */
 	{MBPS, ENC|DEC, CODECS_ALL, 64, 7833600, 1, 7833600},
 	{MBPS, ENC|DEC, CODECS_ALL, 64, 7833600, 1, 7833600},
 	{FRAME_RATE, ENC|DEC, CODECS_ALL, 1, 960, 1, 30},
 	{FRAME_RATE, ENC|DEC, CODECS_ALL, 1, 960, 1, 30},
-	{BIT_RATE, ENC|DEC, CODECS_ALL, 1, 220000000, 1, 20000000},
-	{BIT_RATE, ENC, HEVC, 1, 160000000, 1, 20000000},
+	{BIT_RATE, ENC|DEC, CODECS_ALL,
+		1, 220000000, 1, 20000000,
+		V4L2_CID_MPEG_VIDEO_BITRATE, HFI_PROP_TOTAL_BITRATE,
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		/* TO DO parents */ {0},
+		{LAYER_BITRATE, SLICE_BYTE}},
+
+	{BIT_RATE, ENC, HEVC,
+		1, 160000000, 1, 20000000,
+		V4L2_CID_MPEG_VIDEO_BITRATE, HFI_PROP_TOTAL_BITRATE,
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		/* TO DO parents */{0},
+		{LAYER_BITRATE, SLICE_BYTE}},
+
+	{ENTROPY_MODE, ENC, H264,
+		V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC,
+		V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC,
+		V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC |
+		V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC,
+		V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC,
+		V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE, HFI_PROP_CABAC_SESSION,
+		CAP_FLAG_MENU,
+		{PROFILE},
+		{BIT_RATE}},
+
+	{PROFILE, ENC|DEC, H264,
+		V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
+		V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10,
+		V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE |
+		V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE |
+		V4L2_MPEG_VIDEO_H264_PROFILE_MAIN |
+		V4L2_MPEG_VIDEO_H264_PROFILE_HIGH |
+		V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10,
+		V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
+		V4L2_CID_MPEG_VIDEO_H264_PROFILE, HFI_PROP_PROFILE,
+		CAP_FLAG_ROOT | CAP_FLAG_MENU,
+		{0},
+		{ENTROPY_MODE}},
+
 	{CABAC_BITRATE, ENC, H264, 1, 160000000, 1, 20000000},
 	{CABAC_BITRATE, ENC, H264, 1, 160000000, 1, 20000000},
 	{SCALE_X, ENC, CODECS_ALL, 8192, 65536, 1, 8192},
 	{SCALE_X, ENC, CODECS_ALL, 8192, 65536, 1, 8192},
 	{SCALE_Y, ENC, CODECS_ALL, 8192, 65536, 1, 8192},
 	{SCALE_Y, ENC, CODECS_ALL, 8192, 65536, 1, 8192},

+ 3 - 3
driver/vidc/inc/hfi_packet.h

@@ -20,9 +20,9 @@ u32 get_hfi_buffer_type(enum msm_vidc_domain_type domain,
 u32 get_hfi_codec(struct msm_vidc_inst *inst);
 u32 get_hfi_codec(struct msm_vidc_inst *inst);
 int get_hfi_buffer(struct msm_vidc_inst *inst,
 int get_hfi_buffer(struct msm_vidc_inst *inst,
 	struct msm_vidc_buffer *buffer, struct hfi_buffer *buf);
 	struct msm_vidc_buffer *buffer, struct hfi_buffer *buf);
-int hfi_create_header(u8 *pkt, u32 session_id,
-	u32 header_id, u32 num_packets, u32 total_size);
-int hfi_create_packet(u8 *packet, u32 packet_size, u32 *offset,
+int hfi_create_header(u8 *packet, u32 packet_size,
+	u32 session_id, u32 header_id);
+int hfi_create_packet(u8 *packet, u32 packet_size,
 	u32 pkt_type, u32 pkt_flags, u32 payload_type, u32 port,
 	u32 pkt_type, u32 pkt_flags, u32 payload_type, u32 port,
 	u32 packet_id, void *payload, u32 payload_size);
 	u32 packet_id, void *payload, u32 payload_size);
 int hfi_create_buffer(u8 *packet, u32 packet_size, u32 *offset,
 int hfi_create_buffer(u8 *packet, u32 packet_size, u32 *offset,

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

@@ -17,6 +17,5 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f);
 int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f);
 int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f);
 int msm_vdec_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f);
 int msm_vdec_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f);
 int msm_vdec_inst_init(struct msm_vidc_inst *inst);
 int msm_vdec_inst_init(struct msm_vidc_inst *inst);
-int msm_vdec_ctrl_init(struct msm_vidc_inst *inst);
 
 
 #endif // _MSM_VDEC_H_
 #endif // _MSM_VDEC_H_

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

@@ -13,6 +13,5 @@ int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f);
 int msm_venc_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f);
 int msm_venc_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f);
 int msm_venc_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f);
 int msm_venc_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f);
 int msm_venc_inst_init(struct msm_vidc_inst *inst);
 int msm_venc_inst_init(struct msm_vidc_inst *inst);
-int msm_venc_ctrl_init(struct msm_vidc_inst *inst);
 
 
 #endif // _MSM_VENC_H_
 #endif // _MSM_VENC_H_

+ 20 - 0
driver/vidc/inc/msm_vidc_control.h

@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _MSM_VIDC_CONTROL_H_
+#define _MSM_VIDC_CONTROL_H_
+
+#include "msm_vidc_inst.h"
+#include "msm_vidc_internal.h"
+
+enum msm_vidc_ctrl_list_type {
+	CHILD_LIST          = BIT(0),
+	FW_LIST             = BIT(1),
+};
+
+int msm_vidc_ctrl_init(struct msm_vidc_inst *inst);
+int msm_v4l2_op_s_ctrl(struct v4l2_ctrl *ctrl);
+
+#endif

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

@@ -81,6 +81,7 @@ int msm_vidc_release_internal_buffers(struct msm_vidc_inst *inst,
 		enum msm_vidc_buffer_type buffer_type);
 		enum msm_vidc_buffer_type buffer_type);
 int msm_vidc_add_session(struct msm_vidc_inst *inst);
 int msm_vidc_add_session(struct msm_vidc_inst *inst);
 int msm_vidc_session_open(struct msm_vidc_inst *inst);
 int msm_vidc_session_open(struct msm_vidc_inst *inst);
+int msm_vidc_get_inst_capability(struct msm_vidc_inst *inst, u32 codec);
 int msm_vidc_core_init(struct msm_vidc_core *core);
 int msm_vidc_core_init(struct msm_vidc_core *core);
 int msm_vidc_smmu_fault_handler(struct iommu_domain *domain,
 int msm_vidc_smmu_fault_handler(struct iommu_domain *domain,
 		struct device *dev, unsigned long iova, int flags, void *data);
 		struct device *dev, unsigned long iova, int flags, void *data);

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

@@ -89,6 +89,9 @@ struct msm_vidc_inst {
 	struct v4l2_fh                     event_handler;
 	struct v4l2_fh                     event_handler;
 	struct v4l2_ctrl                 **ctrls;
 	struct v4l2_ctrl                 **ctrls;
 	u32                                num_ctrls;
 	u32                                num_ctrls;
+	struct msm_vidc_inst_cap_entry     child_ctrls;
+	struct msm_vidc_inst_cap_entry     fw_ctrls;
+	bool                               request;
 	struct vb2_queue                   vb2q[MAX_PORT];
 	struct vb2_queue                   vb2q[MAX_PORT];
 	struct msm_vidc_crop               crop;
 	struct msm_vidc_crop               crop;
 	struct msm_vidc_properties         prop;
 	struct msm_vidc_properties         prop;

+ 21 - 5
driver/vidc/inc/msm_vidc_internal.h

@@ -64,6 +64,10 @@
 #define NUM_MBS_PER_FRAME(__height, __width) \
 #define NUM_MBS_PER_FRAME(__height, __width) \
 	((ALIGN(__height, 16) / 16) * (ALIGN(__width, 16) / 16))
 	((ALIGN(__height, 16) / 16) * (ALIGN(__width, 16) / 16))
 
 
+#define IS_PRIV_CTRL(idx) ( \
+	(V4L2_CTRL_ID2WHICH(idx) == V4L2_CTRL_CLASS_MPEG) && \
+	V4L2_CTRL_DRIVER_PRIV(idx))
+
 /*
 /*
  * Convert Q16 number into Integer and Fractional part upto 2 places.
  * Convert Q16 number into Integer and Fractional part upto 2 places.
  * Ex : 105752 / 65536 = 1.61; 1.61 in Q16 = 105752;
  * Ex : 105752 / 65536 = 1.61; 1.61 in Q16 = 105752;
@@ -174,6 +178,9 @@ enum msm_vidc_inst_capability_type {
 	MBPS,
 	MBPS,
 	FRAME_RATE,
 	FRAME_RATE,
 	BIT_RATE,
 	BIT_RATE,
+	BITRATE_MODE,
+	LAYER_BITRATE,
+	ENTROPY_MODE,
 	CABAC_BITRATE,
 	CABAC_BITRATE,
 	LTR_COUNT,
 	LTR_COUNT,
 	LCU_SIZE,
 	LCU_SIZE,
@@ -215,6 +222,7 @@ enum msm_vidc_inst_capability_type {
 };
 };
 
 
 enum msm_vidc_inst_capability_flags {
 enum msm_vidc_inst_capability_flags {
+	CAP_FLAG_NONE                    = 0,
 	CAP_FLAG_ROOT                    = BIT(0),
 	CAP_FLAG_ROOT                    = BIT(0),
 	CAP_FLAG_DYNAMIC_ALLOWED         = BIT(1),
 	CAP_FLAG_DYNAMIC_ALLOWED         = BIT(1),
 	CAP_FLAG_MENU                    = BIT(2),
 	CAP_FLAG_MENU                    = BIT(2),
@@ -226,13 +234,16 @@ struct msm_vidc_inst_cap {
 	s32 max;
 	s32 max;
 	u32 step_or_mask;
 	u32 step_or_mask;
 	s32 value;
 	s32 value;
-	enum msm_vidc_inst_capability_flags flags;
 	u32 v4l2_id;
 	u32 v4l2_id;
 	u32 hfi_id;
 	u32 hfi_id;
-	u8 parents[MAX_CAP_PARENTS];
-	u8 children[MAX_CAP_CHILDREN];
-	void (*adjust)(void *inst, s32 new_value);
-	int (*set)(void *inst, struct v4l2_ctrl *ctrl);
+	enum msm_vidc_inst_capability_flags flags;
+	enum msm_vidc_inst_capability_type parents[MAX_CAP_PARENTS];
+	enum msm_vidc_inst_capability_type children[MAX_CAP_CHILDREN];
+	int (*adjust)(void *inst,
+		enum msm_vidc_inst_capability_type cap_id,
+		struct v4l2_ctrl *ctrl);
+	int (*set)(void *inst,
+		enum msm_vidc_inst_capability_type cap_id);
 };
 };
 
 
 struct msm_vidc_inst_capability {
 struct msm_vidc_inst_capability {
@@ -246,6 +257,11 @@ struct msm_vidc_core_capability {
 	u32 value;
 	u32 value;
 };
 };
 
 
+struct msm_vidc_inst_cap_entry {
+	struct list_head list;
+	enum msm_vidc_inst_capability_type cap_id;
+};
+
 enum efuse_purpose {
 enum efuse_purpose {
 	SKU_VERSION = 0,
 	SKU_VERSION = 0,
 };
 };

+ 9 - 5
driver/vidc/inc/msm_vidc_platform.h

@@ -9,6 +9,7 @@
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
 
 
 #include "msm_vidc_internal.h"
 #include "msm_vidc_internal.h"
+#include <media/v4l2-ctrls.h>
 
 
 struct msm_platform_core_capability {
 struct msm_platform_core_capability {
 	enum msm_vidc_core_capability_type type;
 	enum msm_vidc_core_capability_type type;
@@ -23,13 +24,16 @@ struct msm_platform_inst_capability {
 	s32 max;
 	s32 max;
 	u32 step_or_mask;
 	u32 step_or_mask;
 	s32 value;
 	s32 value;
-	enum msm_vidc_inst_capability_flags flags;
 	u32 v4l2_id;
 	u32 v4l2_id;
 	u32 hfi_id;
 	u32 hfi_id;
-	u8 parents[MAX_CAP_PARENTS];
-	u8 children[MAX_CAP_CHILDREN];
-	void (*adjust)(void *inst, s32 new_value);
-	int (*set)(void *inst, struct v4l2_ctrl *ctrl);
+	enum msm_vidc_inst_capability_flags flags;
+	enum msm_vidc_inst_capability_type parents[MAX_CAP_PARENTS];
+	enum msm_vidc_inst_capability_type children[MAX_CAP_CHILDREN];
+	int (*adjust)(void *inst,
+		enum msm_vidc_inst_capability_type cap_id,
+		struct v4l2_ctrl *ctrl);
+	int (*set)(void *inst,
+		enum msm_vidc_inst_capability_type cap_id);
 };
 };
 
 
 struct msm_vidc_csc_coeff {
 struct msm_vidc_csc_coeff {

+ 83 - 112
driver/vidc/src/hfi_packet.c

@@ -115,7 +115,7 @@ int get_hfi_buffer(struct msm_vidc_inst *inst,
 	struct msm_vidc_buffer *buffer, struct hfi_buffer *buf)
 	struct msm_vidc_buffer *buffer, struct hfi_buffer *buf)
 {
 {
 	if (!inst || !buffer || !buf) {
 	if (!inst || !buffer || !buf) {
-		d_vpr_e("%: invalid params\n", __func__);
+		d_vpr_e("%s: invalid params\n", __func__);
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
@@ -136,36 +136,50 @@ int get_hfi_buffer(struct msm_vidc_inst *inst,
 	return 0;
 	return 0;
 }
 }
 
 
-int hfi_create_header(u8 *pkt, u32 session_id,
-	u32 header_id, u32 num_packets, u32 total_size)
+int hfi_create_header(u8 *packet, u32 packet_size, u32 session_id,
+	u32 header_id)
 {
 {
-	struct hfi_header *hdr = (struct hfi_header *)pkt;
+	struct hfi_header *hdr = (struct hfi_header *)packet;
+
+	if (!packet || packet_size < sizeof(struct hfi_header)) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
 
 
 	memset(hdr, 0, sizeof(struct hfi_header));
 	memset(hdr, 0, sizeof(struct hfi_header));
 
 
-	hdr->size = total_size;
+	hdr->size = sizeof(struct hfi_header);
 	hdr->session_id = session_id;
 	hdr->session_id = session_id;
 	hdr->header_id = header_id;
 	hdr->header_id = header_id;
-	hdr->num_packets = num_packets;
+	hdr->num_packets = 0;
 	return 0;
 	return 0;
 }
 }
 
 
-int hfi_create_packet(u8 *packet, u32 packet_size, u32 *offset,
+int hfi_create_packet(u8 *packet, u32 packet_size,
 	u32 pkt_type, u32 pkt_flags, u32 payload_type, u32 port,
 	u32 pkt_type, u32 pkt_flags, u32 payload_type, u32 port,
 	u32 packet_id, void *payload, u32 payload_size)
 	u32 packet_id, void *payload, u32 payload_size)
 {
 {
-	u32 available_size = packet_size - *offset;
-	u32 pkt_size = sizeof(struct hfi_packet) + payload_size;
-	struct hfi_packet *pkt = (struct hfi_packet *)(packet + *offset);
+	struct hfi_header *hdr;
+	struct hfi_packet *pkt;
+	u32 pkt_size;
 
 
-	if (available_size < pkt_size) {
-		d_vpr_e("%s: Bad packet Size for packet type %d\n",
-			__func__, pkt_type);
+	if (!packet) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
+	hdr = (struct hfi_header *)packet;
+	if (hdr->size < sizeof(struct hfi_header)) {
+		d_vpr_e("%s: invalid hdr size %d\n", __func__, hdr->size);
+		return -EINVAL;
+	}
+	pkt = (struct hfi_packet *)(packet + hdr->size);
+	pkt_size = sizeof(struct hfi_packet) + payload_size;
+	if (packet_size < hdr->size  + pkt_size) {
+		d_vpr_e("%s: invalid packet_size %d, %d %d\n",
+			__func__, packet_size, hdr->size, pkt_size);
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
-
 	memset(pkt, 0, pkt_size);
 	memset(pkt, 0, pkt_size);
-
 	pkt->size = pkt_size;
 	pkt->size = pkt_size;
 	pkt->type = pkt_type;
 	pkt->type = pkt_type;
 	pkt->flags = pkt_flags;
 	pkt->flags = pkt_flags;
@@ -175,7 +189,9 @@ int hfi_create_packet(u8 *packet, u32 packet_size, u32 *offset,
 	if (payload_size)
 	if (payload_size)
 		memcpy((u8 *)pkt + sizeof(struct hfi_packet),
 		memcpy((u8 *)pkt + sizeof(struct hfi_packet),
 			payload, payload_size);
 			payload, payload_size);
-	*offset = *offset + pkt->size;
+
+	hdr->num_packets++;
+	hdr->size += pkt->size;
 	return 0;
 	return 0;
 }
 }
 
 
@@ -183,22 +199,22 @@ int hfi_packet_sys_init(struct msm_vidc_core *core,
 	u8 *pkt, u32 pkt_size)
 	u8 *pkt, u32 pkt_size)
 {
 {
 	int rc = 0;
 	int rc = 0;
-	u32 offset = 0, payload = 0, num_packets = 0;
+	u32 payload = 0;
 
 
 	if (!core || !pkt) {
 	if (!core || !pkt) {
 		d_vpr_e("%s: Invalid params\n", __func__);
 		d_vpr_e("%s: Invalid params\n", __func__);
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
-	if (pkt_size < sizeof(struct hfi_header)) {
-		d_vpr_e("%s: Invalid packet size\n", __func__);
-		return -EINVAL;
-	}
+	rc = hfi_create_header(pkt, pkt_size,
+				   0 /*session_id*/,
+				   core->header_id++);
+	if (rc)
+		goto err_sys_init;
 
 
 	/* HFI_CMD_SYSTEM_INIT */
 	/* HFI_CMD_SYSTEM_INIT */
-	offset = sizeof(struct hfi_header);
 	payload = HFI_VIDEO_ARCH_OX;
 	payload = HFI_VIDEO_ARCH_OX;
-	rc = hfi_create_packet(pkt, pkt_size, &offset,
+	rc = hfi_create_packet(pkt, pkt_size,
 				   HFI_CMD_INIT,
 				   HFI_CMD_INIT,
 				   (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
 				   (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
 				   HFI_HOST_FLAGS_INTR_REQUIRED |
 				   HFI_HOST_FLAGS_INTR_REQUIRED |
@@ -210,11 +226,10 @@ int hfi_packet_sys_init(struct msm_vidc_core *core,
 				   sizeof(u32));
 				   sizeof(u32));
 	if (rc)
 	if (rc)
 		goto err_sys_init;
 		goto err_sys_init;
-	num_packets++;
 
 
 	/* HFI_PROP_INTRA_FRAME_POWER_COLLAPSE */
 	/* HFI_PROP_INTRA_FRAME_POWER_COLLAPSE */
 	payload = 0;
 	payload = 0;
-	rc = hfi_create_packet(pkt, pkt_size, &offset,
+	rc = hfi_create_packet(pkt, pkt_size,
 				   HFI_PROP_INTRA_FRAME_POWER_COLLAPSE,
 				   HFI_PROP_INTRA_FRAME_POWER_COLLAPSE,
 				   HFI_HOST_FLAGS_NONE,
 				   HFI_HOST_FLAGS_NONE,
 				   HFI_PAYLOAD_U32,
 				   HFI_PAYLOAD_U32,
@@ -224,11 +239,10 @@ int hfi_packet_sys_init(struct msm_vidc_core *core,
 				   sizeof(u32));
 				   sizeof(u32));
 	if (rc)
 	if (rc)
 		goto err_sys_init;
 		goto err_sys_init;
-	num_packets++;
 
 
 	/* HFI_PROP_UBWC_MAX_CHANNELS */
 	/* HFI_PROP_UBWC_MAX_CHANNELS */
 	payload = core->platform->data.ubwc_config->max_channels;
 	payload = core->platform->data.ubwc_config->max_channels;
-	rc = hfi_create_packet(pkt, pkt_size, &offset,
+	rc = hfi_create_packet(pkt, pkt_size,
 				   HFI_PROP_UBWC_MAX_CHANNELS,
 				   HFI_PROP_UBWC_MAX_CHANNELS,
 				   HFI_HOST_FLAGS_NONE,
 				   HFI_HOST_FLAGS_NONE,
 				   HFI_PAYLOAD_U32,
 				   HFI_PAYLOAD_U32,
@@ -238,11 +252,10 @@ int hfi_packet_sys_init(struct msm_vidc_core *core,
 				   sizeof(u32));
 				   sizeof(u32));
 	if (rc)
 	if (rc)
 		goto err_sys_init;
 		goto err_sys_init;
-	num_packets++;
 
 
 	/* HFI_PROP_UBWC_MAL_LENGTH */
 	/* HFI_PROP_UBWC_MAL_LENGTH */
 	payload = core->platform->data.ubwc_config->mal_length;
 	payload = core->platform->data.ubwc_config->mal_length;
-	rc = hfi_create_packet(pkt, pkt_size, &offset,
+	rc = hfi_create_packet(pkt, pkt_size,
 				   HFI_PROP_UBWC_MAL_LENGTH,
 				   HFI_PROP_UBWC_MAL_LENGTH,
 				   HFI_HOST_FLAGS_NONE,
 				   HFI_HOST_FLAGS_NONE,
 				   HFI_PAYLOAD_U32,
 				   HFI_PAYLOAD_U32,
@@ -252,11 +265,10 @@ int hfi_packet_sys_init(struct msm_vidc_core *core,
 				   sizeof(u32));
 				   sizeof(u32));
 	if (rc)
 	if (rc)
 		goto err_sys_init;
 		goto err_sys_init;
-	num_packets++;
 
 
 	/* HFI_PROP_UBWC_HBB */
 	/* HFI_PROP_UBWC_HBB */
 	payload = core->platform->data.ubwc_config->highest_bank_bit;
 	payload = core->platform->data.ubwc_config->highest_bank_bit;
-	rc = hfi_create_packet(pkt, pkt_size, &offset,
+	rc = hfi_create_packet(pkt, pkt_size,
 				   HFI_PROP_UBWC_HBB,
 				   HFI_PROP_UBWC_HBB,
 				   HFI_HOST_FLAGS_NONE,
 				   HFI_HOST_FLAGS_NONE,
 				   HFI_PAYLOAD_U32,
 				   HFI_PAYLOAD_U32,
@@ -266,11 +278,10 @@ int hfi_packet_sys_init(struct msm_vidc_core *core,
 				   sizeof(u32));
 				   sizeof(u32));
 	if (rc)
 	if (rc)
 		goto err_sys_init;
 		goto err_sys_init;
-	num_packets++;
 
 
 	/* HFI_PROP_UBWC_BANK_SWZL_LEVEL1 */
 	/* HFI_PROP_UBWC_BANK_SWZL_LEVEL1 */
 	payload = core->platform->data.ubwc_config->bank_swzl_level;
 	payload = core->platform->data.ubwc_config->bank_swzl_level;
-	rc = hfi_create_packet(pkt, pkt_size, &offset,
+	rc = hfi_create_packet(pkt, pkt_size,
 				   HFI_PROP_UBWC_BANK_SWZL_LEVEL1,
 				   HFI_PROP_UBWC_BANK_SWZL_LEVEL1,
 				   HFI_HOST_FLAGS_NONE,
 				   HFI_HOST_FLAGS_NONE,
 				   HFI_PAYLOAD_U32,
 				   HFI_PAYLOAD_U32,
@@ -280,11 +291,10 @@ int hfi_packet_sys_init(struct msm_vidc_core *core,
 				   sizeof(u32));
 				   sizeof(u32));
 	if (rc)
 	if (rc)
 		goto err_sys_init;
 		goto err_sys_init;
-	num_packets++;
 
 
 	/* HFI_PROP_UBWC_BANK_SWZL_LEVEL2 */
 	/* HFI_PROP_UBWC_BANK_SWZL_LEVEL2 */
 	payload = core->platform->data.ubwc_config->bank_swz2_level;
 	payload = core->platform->data.ubwc_config->bank_swz2_level;
-	rc = hfi_create_packet(pkt, pkt_size, &offset,
+	rc = hfi_create_packet(pkt, pkt_size,
 				   HFI_PROP_UBWC_BANK_SWZL_LEVEL2,
 				   HFI_PROP_UBWC_BANK_SWZL_LEVEL2,
 				   HFI_HOST_FLAGS_NONE,
 				   HFI_HOST_FLAGS_NONE,
 				   HFI_PAYLOAD_U32,
 				   HFI_PAYLOAD_U32,
@@ -294,11 +304,10 @@ int hfi_packet_sys_init(struct msm_vidc_core *core,
 				   sizeof(u32));
 				   sizeof(u32));
 	if (rc)
 	if (rc)
 		goto err_sys_init;
 		goto err_sys_init;
-	num_packets++;
 
 
 	/* HFI_PROP_UBWC_BANK_SWZL_LEVEL3 */
 	/* HFI_PROP_UBWC_BANK_SWZL_LEVEL3 */
 	payload = core->platform->data.ubwc_config->bank_swz3_level;
 	payload = core->platform->data.ubwc_config->bank_swz3_level;
-	rc = hfi_create_packet(pkt, pkt_size, &offset,
+	rc = hfi_create_packet(pkt, pkt_size,
 				   HFI_PROP_UBWC_BANK_SWZL_LEVEL3,
 				   HFI_PROP_UBWC_BANK_SWZL_LEVEL3,
 				   HFI_HOST_FLAGS_NONE,
 				   HFI_HOST_FLAGS_NONE,
 				   HFI_PAYLOAD_U32,
 				   HFI_PAYLOAD_U32,
@@ -308,11 +317,10 @@ int hfi_packet_sys_init(struct msm_vidc_core *core,
 				   sizeof(u32));
 				   sizeof(u32));
 	if (rc)
 	if (rc)
 		goto err_sys_init;
 		goto err_sys_init;
-	num_packets++;
 
 
 	/* HFI_PROP_UBWC_BANK_SPREADING */
 	/* HFI_PROP_UBWC_BANK_SPREADING */
 	payload = core->platform->data.ubwc_config->bank_spreading;
 	payload = core->platform->data.ubwc_config->bank_spreading;
-	rc = hfi_create_packet(pkt, pkt_size, &offset,
+	rc = hfi_create_packet(pkt, pkt_size,
 				   HFI_PROP_UBWC_BANK_SPREADING,
 				   HFI_PROP_UBWC_BANK_SPREADING,
 				   HFI_HOST_FLAGS_NONE,
 				   HFI_HOST_FLAGS_NONE,
 				   HFI_PAYLOAD_U32,
 				   HFI_PAYLOAD_U32,
@@ -320,15 +328,6 @@ int hfi_packet_sys_init(struct msm_vidc_core *core,
 				   core->packet_id++,
 				   core->packet_id++,
 				   &payload,
 				   &payload,
 				   sizeof(u32));
 				   sizeof(u32));
-	if (rc)
-		goto err_sys_init;
-	num_packets++;
-
-	rc = hfi_create_header(pkt, 0 /*session_id*/,
-				   core->header_id++,
-				   num_packets,
-				   offset);
-
 	if (rc)
 	if (rc)
 		goto err_sys_init;
 		goto err_sys_init;
 
 
@@ -344,16 +343,20 @@ int hfi_packet_image_version(struct msm_vidc_core *core,
 	u8 *pkt, u32 pkt_size)
 	u8 *pkt, u32 pkt_size)
 {
 {
 	int rc = 0;
 	int rc = 0;
-	u32 num_packets = 0, offset = 0;
 
 
 	if (!core || !pkt) {
 	if (!core || !pkt) {
 		d_vpr_e("%s: Invalid params\n", __func__);
 		d_vpr_e("%s: Invalid params\n", __func__);
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
+	rc = hfi_create_header(pkt, pkt_size,
+				   0 /*session_id*/,
+				   core->header_id++);
+	if (rc)
+		goto err_img_version;
+
 	/* HFI_PROP_IMAGE_VERSION */
 	/* HFI_PROP_IMAGE_VERSION */
-	offset = sizeof(struct hfi_header);
-	rc = hfi_create_packet(pkt, pkt_size, &offset,
+	rc = hfi_create_packet(pkt, pkt_size,
 				   HFI_PROP_IMAGE_VERSION,
 				   HFI_PROP_IMAGE_VERSION,
 				   (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
 				   (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
 				   HFI_HOST_FLAGS_INTR_REQUIRED |
 				   HFI_HOST_FLAGS_INTR_REQUIRED |
@@ -362,15 +365,6 @@ int hfi_packet_image_version(struct msm_vidc_core *core,
 				   HFI_PORT_NONE,
 				   HFI_PORT_NONE,
 				   core->packet_id++,
 				   core->packet_id++,
 				   NULL, 0);
 				   NULL, 0);
-	if (rc)
-		goto err_img_version;
-	num_packets++;
-
-	rc = hfi_create_header(pkt, 0 /*session_id*/,
-				   core->header_id++,
-				   num_packets,
-				   offset);
-
 	if (rc)
 	if (rc)
 		goto err_img_version;
 		goto err_img_version;
 
 
@@ -386,31 +380,26 @@ int hfi_packet_sys_pc_prep(struct msm_vidc_core *core,
 	u8 *pkt, u32 pkt_size)
 	u8 *pkt, u32 pkt_size)
 {
 {
 	int rc = 0;
 	int rc = 0;
-	u32 num_packets = 0, offset = 0;
 
 
 	if (!core || !pkt) {
 	if (!core || !pkt) {
 		d_vpr_e("%s: Invalid params\n", __func__);
 		d_vpr_e("%s: Invalid params\n", __func__);
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
+	rc = hfi_create_header(pkt, pkt_size,
+			   0 /*session_id*/,
+			   core->header_id++);
+	if (rc)
+		goto err_sys_pc;
+
 	/* HFI_CMD_POWER_COLLAPSE */
 	/* HFI_CMD_POWER_COLLAPSE */
-	offset = sizeof(struct hfi_header);
-	rc = hfi_create_packet(pkt, pkt_size, &offset,
+	rc = hfi_create_packet(pkt, pkt_size,
 				   HFI_CMD_POWER_COLLAPSE,
 				   HFI_CMD_POWER_COLLAPSE,
 				   HFI_HOST_FLAGS_NONE,
 				   HFI_HOST_FLAGS_NONE,
 				   HFI_PAYLOAD_NONE,
 				   HFI_PAYLOAD_NONE,
 				   HFI_PORT_NONE,
 				   HFI_PORT_NONE,
 				   core->packet_id++,
 				   core->packet_id++,
 				   NULL, 0);
 				   NULL, 0);
-	if (rc)
-		goto err_sys_pc;
-	num_packets++;
-
-	rc = hfi_create_header(pkt, 0 /*session_id*/,
-				   core->header_id++,
-				   num_packets,
-				   offset);
-
 	if (rc)
 	if (rc)
 		goto err_sys_pc;
 		goto err_sys_pc;
 
 
@@ -426,17 +415,22 @@ int hfi_packet_sys_debug_config(struct msm_vidc_core *core,
 	u8 *pkt, u32 pkt_size, u32 debug_config)
 	u8 *pkt, u32 pkt_size, u32 debug_config)
 {
 {
 	int rc = 0;
 	int rc = 0;
-	u32 num_packets = 0, offset = 0, payload = 0;
+	u32 payload = 0;
 
 
 	if (!core || !pkt) {
 	if (!core || !pkt) {
 		d_vpr_e("%s: Invalid params\n", __func__);
 		d_vpr_e("%s: Invalid params\n", __func__);
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
+	rc = hfi_create_header(pkt, pkt_size,
+				   0 /*session_id*/,
+				   core->header_id++);
+	if (rc)
+		goto err_debug;
+
 	/* HFI_PROP_DEBUG_CONFIG */
 	/* HFI_PROP_DEBUG_CONFIG */
-	offset = sizeof(struct hfi_header);
 	payload = debug_config; /*TODO:Change later*/
 	payload = debug_config; /*TODO:Change later*/
-	rc = hfi_create_packet(pkt, pkt_size, &offset,
+	rc = hfi_create_packet(pkt, pkt_size,
 				   HFI_PROP_DEBUG_CONFIG,
 				   HFI_PROP_DEBUG_CONFIG,
 				   HFI_HOST_FLAGS_NONE,
 				   HFI_HOST_FLAGS_NONE,
 				   HFI_PAYLOAD_U32_ENUM,
 				   HFI_PAYLOAD_U32_ENUM,
@@ -446,11 +440,10 @@ int hfi_packet_sys_debug_config(struct msm_vidc_core *core,
 				   sizeof(u32));
 				   sizeof(u32));
 	if (rc)
 	if (rc)
 		goto err_debug;
 		goto err_debug;
-	num_packets++;
 
 
 	/* HFI_PROP_DEBUG_LOG_LEVEL */
 	/* HFI_PROP_DEBUG_LOG_LEVEL */
 	payload = debug_config; /*TODO:Change later*/
 	payload = debug_config; /*TODO:Change later*/
-	rc = hfi_create_packet(pkt, pkt_size, &offset,
+	rc = hfi_create_packet(pkt, pkt_size,
 				   HFI_PROP_DEBUG_LOG_LEVEL,
 				   HFI_PROP_DEBUG_LOG_LEVEL,
 				   HFI_HOST_FLAGS_NONE,
 				   HFI_HOST_FLAGS_NONE,
 				   HFI_PAYLOAD_U32_ENUM,
 				   HFI_PAYLOAD_U32_ENUM,
@@ -458,15 +451,6 @@ int hfi_packet_sys_debug_config(struct msm_vidc_core *core,
 				   core->packet_id++,
 				   core->packet_id++,
 				   &payload,
 				   &payload,
 				   sizeof(u32));
 				   sizeof(u32));
-	if (rc)
-		goto err_debug;
-	num_packets++;
-
-	rc = hfi_create_header(pkt, 0 /*session_id*/,
-				   core->header_id++,
-				   num_packets,
-				   offset);
-
 	if (rc)
 	if (rc)
 		goto err_debug;
 		goto err_debug;
 
 
@@ -483,19 +467,22 @@ int hfi_packet_session_command(struct msm_vidc_inst *inst,
 	u32 payload_type, void *payload, u32 payload_size)
 	u32 payload_type, void *payload, u32 payload_size)
 {
 {
 	int rc = 0;
 	int rc = 0;
-	u32 num_packets = 0, offset = 0;
 	struct msm_vidc_core *core;
 	struct msm_vidc_core *core;
 
 
 	if (!inst || !inst->core) {
 	if (!inst || !inst->core) {
 		d_vpr_e("%s: Invalid params\n", __func__);
 		d_vpr_e("%s: Invalid params\n", __func__);
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
-
 	core = inst->core;
 	core = inst->core;
-	offset = sizeof(struct hfi_header);
+
+	rc = hfi_create_header(inst->packet, inst->packet_size,
+				   session_id,
+				   core->header_id++);
+	if (rc)
+		goto err_cmd;
+
 	rc = hfi_create_packet(inst->packet,
 	rc = hfi_create_packet(inst->packet,
 				inst->packet_size,
 				inst->packet_size,
-				&offset,
 				pkt_type,
 				pkt_type,
 				flags,
 				flags,
 				payload_type,
 				payload_type,
@@ -503,15 +490,6 @@ int hfi_packet_session_command(struct msm_vidc_inst *inst,
 				core->packet_id++,
 				core->packet_id++,
 				payload,
 				payload,
 				payload_size);
 				payload_size);
-	if (rc)
-		goto err_cmd;
-	num_packets++;
-
-	rc = hfi_create_header(inst->packet, session_id,
-				   core->header_id++,
-				   num_packets,
-				   offset);
-
 	if (rc)
 	if (rc)
 		goto err_cmd;
 		goto err_cmd;
 
 
@@ -528,18 +506,20 @@ int hfi_packet_session_property(struct msm_vidc_inst *inst,
 	void *payload, u32 payload_size)
 	void *payload, u32 payload_size)
 {
 {
 	int rc = 0;
 	int rc = 0;
-	u32 num_packets = 0, offset = 0;
 	struct msm_vidc_core *core;
 	struct msm_vidc_core *core;
 
 
 	if (!inst || !inst->core || !inst->packet) {
 	if (!inst || !inst->core || !inst->packet) {
 		d_vpr_e("%s: Invalid params\n", __func__);
 		d_vpr_e("%s: Invalid params\n", __func__);
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
-
 	core = inst->core;
 	core = inst->core;
-	offset = sizeof(struct hfi_header);
+
+	rc = hfi_create_header(inst->packet, inst->packet_size,
+				   inst->session_id, core->header_id++);
+	if (rc)
+		goto err_prop;
+
 	rc = hfi_create_packet(inst->packet, inst->packet_size,
 	rc = hfi_create_packet(inst->packet, inst->packet_size,
-				&offset,
 				pkt_type,
 				pkt_type,
 				flags,
 				flags,
 				payload_type,
 				payload_type,
@@ -547,15 +527,6 @@ int hfi_packet_session_property(struct msm_vidc_inst *inst,
 				core->packet_id++,
 				core->packet_id++,
 				payload,
 				payload,
 				payload_size);
 				payload_size);
-	if (rc)
-		goto err_prop;
-	num_packets++;
-
-	rc = hfi_create_header(inst->packet, inst->session_id,
-				   core->header_id++,
-				   num_packets,
-				   offset);
-
 	if (rc)
 	if (rc)
 		goto err_prop;
 		goto err_prop;
 
 

+ 3 - 50
driver/vidc/src/msm_vdec.c

@@ -18,30 +18,10 @@
 static int msm_vdec_codec_change(struct msm_vidc_inst *inst, u32 codec)
 static int msm_vdec_codec_change(struct msm_vidc_inst *inst, u32 codec)
 {
 {
 	int rc = 0;
 	int rc = 0;
-	int i;
-	struct msm_vidc_core *core;
 
 
 	d_vpr_h("%s()\n", __func__);
 	d_vpr_h("%s()\n", __func__);
-	if (!inst || !inst->core) {
-		d_vpr_e("%s: invalid params\n", __func__);
-		return -EINVAL;
-	}
-	core = inst->core;
 
 
-	inst->capabilities = NULL;
-	for (i = 0; i < core->codecs_count; i++) {
-		if (core->inst_caps[i].domain == MSM_VIDC_DECODER &&
-		    core->inst_caps[i].codec == get_vidc_codec_from_v4l2(
-				inst->fmts[INPUT_PORT].fmt.pix.pixelformat)) {
-			s_vpr_h(inst->sid, "%s: changed capabilities to %#x caps\n",
-				__func__, inst->fmts[INPUT_PORT].fmt.pix.pixelformat);
-			inst->capabilities = &core->inst_caps[i];
-		}
-	}
-	if (!inst->capabilities) {
-		s_vpr_e(inst->sid, "%s: capabilities not found\n", __func__);
-		return -EINVAL;
-	}
+	rc = msm_vidc_get_inst_capability(inst, codec);
 	return rc;
 	return rc;
 }
 }
 
 
@@ -498,7 +478,6 @@ int msm_vdec_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f)
 int msm_vdec_inst_init(struct msm_vidc_inst *inst)
 int msm_vdec_inst_init(struct msm_vidc_inst *inst)
 {
 {
 	int rc = 0;
 	int rc = 0;
-	int i;
 	struct msm_vidc_core *core;
 	struct msm_vidc_core *core;
 	struct v4l2_format *f;
 	struct v4l2_format *f;
 
 
@@ -574,35 +553,9 @@ int msm_vdec_inst_init(struct msm_vidc_inst *inst)
 	inst->prop.frame_rate = DEFAULT_FPS << 16;
 	inst->prop.frame_rate = DEFAULT_FPS << 16;
 	inst->prop.operating_rate = DEFAULT_FPS << 16;
 	inst->prop.operating_rate = DEFAULT_FPS << 16;
 
 
-	inst->capabilities = NULL;
-	for (i = 0; i < core->codecs_count; i++) {
-		if (core->inst_caps[i].domain == MSM_VIDC_DECODER &&
-		    core->inst_caps[i].codec == get_vidc_codec_from_v4l2(
-				inst->fmts[INPUT_PORT].fmt.pix.pixelformat)) {
-			s_vpr_h(inst->sid, "%s: assigned capabilities with %#x caps\n",
-				__func__, inst->fmts[INPUT_PORT].fmt.pix.pixelformat);
-			inst->capabilities = &core->inst_caps[i];
-		}
-	}
-	if (!inst->capabilities) {
-		s_vpr_e(inst->sid, "%s: capabilities not found\n", __func__);
-		return -EINVAL;
-	}
+	rc = msm_vdec_codec_change(inst,
+			inst->fmts[INPUT_PORT].fmt.pix.pixelformat);
 
 
 	return rc;
 	return rc;
 }
 }
 
 
-int msm_vdec_ctrl_init(struct msm_vidc_inst *inst)
-{
-	int rc = 0;
-	struct msm_vidc_core *core;
-
-	d_vpr_h("%s()\n", __func__);
-	if (!inst || !inst->core) {
-		d_vpr_e("%s: invalid params\n", __func__);
-		return -EINVAL;
-	}
-	core = inst->core;
-
-	return rc;
-}

+ 3 - 52
driver/vidc/src/msm_venc.c

@@ -17,31 +17,10 @@
 static int msm_venc_codec_change(struct msm_vidc_inst *inst, u32 codec)
 static int msm_venc_codec_change(struct msm_vidc_inst *inst, u32 codec)
 {
 {
 	int rc = 0;
 	int rc = 0;
-	int i;
-	struct msm_vidc_core *core;
 
 
 	d_vpr_h("%s()\n", __func__);
 	d_vpr_h("%s()\n", __func__);
-	if (!inst || !inst->core) {
-		d_vpr_e("%s: invalid params\n", __func__);
-		return -EINVAL;
-	}
-	core = inst->core;
-
-	inst->capabilities = NULL;
-	for (i = 0; i < core->codecs_count; i++) {
-		if (core->inst_caps[i].domain == MSM_VIDC_ENCODER &&
-		    core->inst_caps[i].codec == get_vidc_codec_from_v4l2(
-				inst->fmts[OUTPUT_PORT].fmt.pix.pixelformat)) {
-			s_vpr_h(inst->sid, "%s: assigned capabilities with %#x caps\n",
-				__func__, inst->fmts[OUTPUT_PORT].fmt.pix.pixelformat);
-			inst->capabilities = &core->inst_caps[i];
-		}
-	}
-	if (!inst->capabilities) {
-		s_vpr_e(inst->sid, "%s: capabilities not found\n", __func__);
-		return -EINVAL;
-	}
 
 
+	rc = msm_vidc_get_inst_capability(inst, codec);
 	return rc;
 	return rc;
 }
 }
 
 
@@ -284,7 +263,6 @@ int msm_venc_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f)
 int msm_venc_inst_init(struct msm_vidc_inst *inst)
 int msm_venc_inst_init(struct msm_vidc_inst *inst)
 {
 {
 	int rc = 0;
 	int rc = 0;
-	int i;
 	struct msm_vidc_core *core;
 	struct msm_vidc_core *core;
 	struct v4l2_format *f;
 	struct v4l2_format *f;
 
 
@@ -358,35 +336,8 @@ int msm_venc_inst_init(struct msm_vidc_inst *inst)
 	inst->prop.frame_rate = DEFAULT_FPS << 16;
 	inst->prop.frame_rate = DEFAULT_FPS << 16;
 	inst->prop.operating_rate = DEFAULT_FPS << 16;
 	inst->prop.operating_rate = DEFAULT_FPS << 16;
 
 
-	inst->capabilities = NULL;
-	for (i = 0; i < core->codecs_count; i++) {
-		if (core->inst_caps[i].domain == MSM_VIDC_ENCODER &&
-		    core->inst_caps[i].codec == get_vidc_codec_from_v4l2(
-				inst->fmts[OUTPUT_PORT].fmt.pix.pixelformat)) {
-			s_vpr_h(inst->sid, "%s: assigned capabilities with %#x caps\n",
-				__func__, inst->fmts[OUTPUT_PORT].fmt.pix.pixelformat);
-			inst->capabilities = &core->inst_caps[i];
-		}
-	}
-	if (!inst->capabilities) {
-		s_vpr_e(inst->sid, "%s: capabilities not found\n", __func__);
-		return -EINVAL;
-	}
-
-	return rc;
-}
-
-int msm_venc_ctrl_init(struct msm_vidc_inst *inst)
-{
-	int rc = 0;
-	struct msm_vidc_core *core;
-
-	d_vpr_h("%s()\n", __func__);
-	if (!inst || !inst->core) {
-		d_vpr_e("%s: invalid params\n", __func__);
-		return -EINVAL;
-	}
-	core = inst->core;
+	rc = msm_venc_codec_change(inst,
+			inst->fmts[OUTPUT_PORT].fmt.pix.pixelformat);
 
 
 	return rc;
 	return rc;
 }
 }

+ 16 - 7
driver/vidc/src/msm_vidc.c

@@ -13,6 +13,7 @@
 #include "msm_vidc_vb2.h"
 #include "msm_vidc_vb2.h"
 #include "msm_vidc_v4l2.h"
 #include "msm_vidc_v4l2.h"
 #include "msm_vidc_debug.h"
 #include "msm_vidc_debug.h"
+#include "msm_vidc_control.h"
 
 
 #define MSM_VIDC_DRV_NAME "msm_vidc_driver"
 #define MSM_VIDC_DRV_NAME "msm_vidc_driver"
 /* kernel/msm-4.19 */
 /* kernel/msm-4.19 */
@@ -266,7 +267,7 @@ int msm_vidc_s_ctrl(void *instance, struct v4l2_control *control)
 	if (!inst || !control)
 	if (!inst || !control)
 		return -EINVAL;
 		return -EINVAL;
 
 
-	return 0;//msm_comm_s_ctrl(instance, control);
+	return v4l2_s_ctrl(NULL, &inst->ctrl_handler, control);
 }
 }
 EXPORT_SYMBOL(msm_vidc_s_ctrl);
 EXPORT_SYMBOL(msm_vidc_s_ctrl);
 
 
@@ -621,6 +622,14 @@ void *msm_vidc_open(void *vidc_core, u32 session_type)
 	}
 	}
 	inst->core = core;
 	inst->core = core;
 
 
+	inst->capabilities = kzalloc(
+		sizeof(struct msm_vidc_inst_capability), GFP_KERNEL);
+	if (!inst->capabilities) {
+		s_vpr_e(inst->sid,
+			"%s: inst capability allocation failed\n", __func__);
+		return NULL;
+	}
+
 	rc = msm_vidc_add_session(inst);
 	rc = msm_vidc_add_session(inst);
 	if (rc) {
 	if (rc) {
 		d_vpr_e("%s: failed to get session id\n", __func__);
 		d_vpr_e("%s: failed to get session id\n", __func__);
@@ -653,8 +662,11 @@ void *msm_vidc_open(void *vidc_core, u32 session_type)
 	INIT_LIST_HEAD(&inst->maps.scratch_2.list);
 	INIT_LIST_HEAD(&inst->maps.scratch_2.list);
 	INIT_LIST_HEAD(&inst->maps.persist.list);
 	INIT_LIST_HEAD(&inst->maps.persist.list);
 	INIT_LIST_HEAD(&inst->maps.persist_1.list);
 	INIT_LIST_HEAD(&inst->maps.persist_1.list);
+	INIT_LIST_HEAD(&inst->child_ctrls.list);
+	INIT_LIST_HEAD(&inst->fw_ctrls.list);
 	inst->domain = session_type;
 	inst->domain = session_type;
 	inst->state = MSM_VIDC_OPEN;
 	inst->state = MSM_VIDC_OPEN;
+	inst->request = false;
 	//inst->debugfs_root =
 	//inst->debugfs_root =
 	//	msm_vidc_debugfs_init_inst(inst, core->debugfs_root);
 	//	msm_vidc_debugfs_init_inst(inst, core->debugfs_root);
 
 
@@ -662,17 +674,14 @@ void *msm_vidc_open(void *vidc_core, u32 session_type)
 		rc = msm_vdec_inst_init(inst);
 		rc = msm_vdec_inst_init(inst);
 		if (rc)
 		if (rc)
 			goto error;
 			goto error;
-		rc = msm_vdec_ctrl_init(inst);
-		if (rc)
-			goto error;
 	} else if (is_encode_session(inst)) {
 	} else if (is_encode_session(inst)) {
 		rc = msm_venc_inst_init(inst);
 		rc = msm_venc_inst_init(inst);
 		if (rc)
 		if (rc)
 			goto error;
 			goto error;
-		rc = msm_venc_ctrl_init(inst);
-		if (rc)
-			goto error;
 	}
 	}
+	rc = msm_vidc_ctrl_init(inst);
+	if (rc)
+		goto error;
 
 
 	rc = msm_vidc_vb2_queue_init(inst);
 	rc = msm_vidc_vb2_queue_init(inst);
 	if (rc)
 	if (rc)

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

@@ -0,0 +1,223 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ */
+
+#include "msm_vidc_control.h"
+#include "msm_vidc_debug.h"
+#include "hfi_packet.h"
+#include "hfi_property.h"
+#include "venus_hfi.h"
+#include "msm_vidc_internal.h"
+
+static bool is_priv_ctrl(u32 id)
+{
+	if (IS_PRIV_CTRL(id))
+		return true;
+
+	/*
+	 * Treat below standard controls as private because
+	 * we have added custom values to the controls
+	 */
+	switch (id) {
+	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+		return true;
+	}
+
+	return false;
+}
+
+static const char *const mpeg_video_rate_control[] = {
+	"VBR",
+	"CBR",
+	"CBR VFR",
+	"MBR",
+	"MBR VFR",
+	"CQ",
+	NULL
+};
+
+static const char *const mpeg_video_stream_format[] = {
+	"NAL Format Start Codes",
+	"NAL Format One NAL Per Buffer",
+	"NAL Format One Byte Length",
+	"NAL Format Two Byte Length",
+	"NAL Format Four Byte Length",
+	NULL,
+};
+
+static const char *const roi_map_type[] = {
+	"None",
+	"2-bit",
+	"2-bit",
+	NULL,
+};
+
+static const char * const * msm_vidc_get_qmenu_type(
+		struct msm_vidc_inst *inst, u32 control_id)
+{
+	switch (control_id) {
+	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+		return mpeg_video_rate_control;
+	case V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD:
+		return mpeg_video_stream_format;
+	/*
+	 * TODO(AS)
+	 * case V4L2_CID_MPEG_VIDC_VIDEO_ROI_TYPE:
+	 *	return roi_map_type;
+	 */
+	default:
+		s_vpr_e(inst->sid, "%s: No available qmenu for ctrl %#x",
+			__func__, control_id);
+		return NULL;
+	}
+}
+
+static const char *msm_vidc_get_priv_ctrl_name(u32 sid, u32 control_id)
+{
+	switch (control_id) {
+	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+		return "Video Bitrate Control";
+	case V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD:
+		return "NAL Format";
+	/*
+	 * TODO(AS)
+	 * case V4L2_CID_MPEG_VIDC_VIDEO_ROI_TYPE:
+	 *	return "ROI Type";
+	 */
+	default:
+		s_vpr_e(sid, "%s: ctrl name not available for ctrl id %#x",
+			__func__, control_id);
+		return NULL;
+	}
+}
+
+int msm_vidc_ctrl_init(struct msm_vidc_inst *inst)
+{
+	int rc = 0;
+	struct msm_vidc_inst_capability *capability;
+	struct msm_vidc_core *core;
+	int idx = 0;
+	struct v4l2_ctrl_config ctrl_cfg = {0};
+	int num_ctrls = 0, ctrl_idx = 0;
+
+	d_vpr_h("%s()\n", __func__);
+	if (!inst || !inst->core || !inst->capabilities) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
+	core = inst->core;
+	capability = inst->capabilities;
+
+	for (idx = 0; idx < INST_CAP_MAX; idx++) {
+		if (capability->cap[idx].v4l2_id)
+			num_ctrls++;
+	}
+	if (!num_ctrls) {
+		s_vpr_e(inst->sid, "%s: failed to allocate ctrl\n", __func__);
+		return -EINVAL;
+	}
+	inst->ctrls = kcalloc(num_ctrls,
+		sizeof(struct v4l2_ctrl *), GFP_KERNEL);
+	if (!inst->ctrls) {
+		s_vpr_e(inst->sid, "%s: failed to allocate ctrl\n", __func__);
+		return -ENOMEM;
+	}
+
+	rc = v4l2_ctrl_handler_init(&inst->ctrl_handler, num_ctrls);
+	if (rc) {
+		s_vpr_e(inst->sid, "control handler init failed, %d\n",
+				inst->ctrl_handler.error);
+		return rc;
+	}
+
+	for (idx = 0; idx < INST_CAP_MAX; idx++) {
+		struct v4l2_ctrl *ctrl;
+
+		if (ctrl_idx >= num_ctrls) {
+			s_vpr_e(inst->sid,
+				"invalid ctrl_idx, max allowed %d\n",
+				num_ctrls);
+			return -EINVAL;
+		}
+		if (!capability->cap[idx].v4l2_id)
+			continue;
+
+		if (is_priv_ctrl(capability->cap[idx].v4l2_id)) {
+			/* add private control */
+			ctrl_cfg.def = capability->cap[idx].value;
+			ctrl_cfg.flags = 0;
+			ctrl_cfg.id = capability->cap[idx].v4l2_id;
+			ctrl_cfg.max = capability->cap[idx].max;
+			ctrl_cfg.min = capability->cap[idx].min;
+			ctrl_cfg.menu_skip_mask =
+				~(capability->cap[idx].step_or_mask);
+			ctrl_cfg.ops = core->v4l2_ctrl_ops;
+			ctrl_cfg.step = capability->cap[idx].step_or_mask;
+			ctrl_cfg.type = (capability->cap[idx].flags &
+					CAP_FLAG_MENU) ?
+					V4L2_CTRL_TYPE_MENU :
+					V4L2_CTRL_TYPE_INTEGER;
+			ctrl_cfg.qmenu = msm_vidc_get_qmenu_type(inst,
+					capability->cap[idx].v4l2_id);
+			ctrl_cfg.name = msm_vidc_get_priv_ctrl_name(inst->sid,
+					capability->cap[idx].v4l2_id);
+			if (!ctrl_cfg.name || !ctrl_cfg.ops) {
+				s_vpr_e(inst->sid, "%s: invalid control, %d\n",
+					__func__, ctrl_cfg.id);
+				return -EINVAL;
+			}
+			ctrl = v4l2_ctrl_new_custom(&inst->ctrl_handler,
+					&ctrl_cfg, NULL);
+		} else {
+			if (capability->cap[idx].flags & CAP_FLAG_MENU) {
+				ctrl = v4l2_ctrl_new_std_menu(
+					&inst->ctrl_handler,
+					core->v4l2_ctrl_ops,
+					capability->cap[idx].v4l2_id,
+					capability->cap[idx].max,
+					~(capability->cap[idx].step_or_mask),
+					capability->cap[idx].value);
+			} else {
+				ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler,
+					core->v4l2_ctrl_ops,
+					capability->cap[idx].v4l2_id,
+					capability->cap[idx].min,
+					capability->cap[idx].max,
+					capability->cap[idx].step_or_mask,
+					capability->cap[idx].value);
+			}
+		}
+		if (!ctrl) {
+			s_vpr_e(inst->sid, "%s: invalid ctrl %s\n", __func__,
+				ctrl->name);
+			return -EINVAL;
+		}
+
+		rc = inst->ctrl_handler.error;
+		if (rc) {
+			s_vpr_e(inst->sid,
+				"error adding ctrl (%#x) to ctrl handle, %d\n",
+				capability->cap[idx].v4l2_id,
+				inst->ctrl_handler.error);
+			return rc;
+		}
+
+		/*
+		 * TODO(AS)
+		 * ctrl->flags |= capability->cap[idx].flags;
+		 */
+		ctrl->flags |= V4L2_CTRL_FLAG_EXECUTE_ON_WRITE;
+		inst->ctrls[ctrl_idx] = ctrl;
+		ctrl_idx++;
+	}
+	inst->num_ctrls = num_ctrls;
+
+	return rc;
+}
+
+int msm_v4l2_op_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	return 0;
+}
+

+ 32 - 0
driver/vidc/src/msm_vidc_driver.c

@@ -664,6 +664,38 @@ int msm_vidc_session_open(struct msm_vidc_inst *inst)
 	return 0;
 	return 0;
 }
 }
 
 
+int msm_vidc_get_inst_capability(struct msm_vidc_inst *inst, u32 codec)
+{
+	int rc = 0;
+	int i;
+	struct msm_vidc_core *core;
+
+	d_vpr_h("%s()\n", __func__);
+	if (!inst || !inst->core || !inst->capabilities) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
+	core = inst->core;
+
+	for (i = 0; i < core->codecs_count; i++) {
+		if (core->inst_caps[i].domain == inst->domain &&
+			core->inst_caps[i].codec == get_vidc_codec_from_v4l2(
+				codec)) {
+			s_vpr_h(inst->sid,
+				"%s: copied capabilities with %#x caps\n",
+				__func__, codec);
+			memcpy(inst->capabilities, &core->inst_caps[i],
+				sizeof(struct msm_vidc_inst_capability));
+		}
+	}
+	if (!inst->capabilities) {
+		s_vpr_e(inst->sid, "%s: capabilities not found\n", __func__);
+		return -EINVAL;
+	}
+
+	return rc;
+}
+
 static int msm_vidc_init_core_caps(struct msm_vidc_core *core)
 static int msm_vidc_init_core_caps(struct msm_vidc_core *core)
 {
 {
 	int rc = 0;
 	int rc = 0;

+ 2 - 2
driver/vidc/src/msm_vidc_platform.c

@@ -12,7 +12,7 @@
 #include "msm_vidc_debug.h"
 #include "msm_vidc_debug.h"
 #include "msm_vidc_v4l2.h"
 #include "msm_vidc_v4l2.h"
 #include "msm_vidc_vb2.h"
 #include "msm_vidc_vb2.h"
-
+#include "msm_vidc_control.h"
 
 
 static struct v4l2_file_operations msm_v4l2_file_operations = {
 static struct v4l2_file_operations msm_v4l2_file_operations = {
 	.owner                          = THIS_MODULE,
 	.owner                          = THIS_MODULE,
@@ -47,7 +47,7 @@ static struct v4l2_ioctl_ops msm_v4l2_ioctl_ops = {
 };
 };
 
 
 static struct v4l2_ctrl_ops msm_v4l2_ctrl_ops = {
 static struct v4l2_ctrl_ops msm_v4l2_ctrl_ops = {
-	//.s_ctrl                         = msm_vidc_s_ctrl,
+	.s_ctrl                         = msm_v4l2_op_s_ctrl,
 };
 };
 
 
 static struct vb2_ops msm_vb2_ops = {
 static struct vb2_ops msm_vb2_ops = {

+ 10 - 24
driver/vidc/src/venus_hfi.c

@@ -2563,7 +2563,6 @@ int venus_hfi_queue_buffer(struct msm_vidc_inst *inst,
 	int rc = 0;
 	int rc = 0;
 	struct msm_vidc_core *core;
 	struct msm_vidc_core *core;
 	struct hfi_buffer hfi_buffer;
 	struct hfi_buffer hfi_buffer;
-	u32 num_packets = 0, offset = 0;
 
 
 	d_vpr_h("%s(): inst %p\n", __func__, inst);
 	d_vpr_h("%s(): inst %p\n", __func__, inst);
 	if (!inst || !inst->core || !inst->packet) {
 	if (!inst || !inst->core || !inst->packet) {
@@ -2576,10 +2575,13 @@ int venus_hfi_queue_buffer(struct msm_vidc_inst *inst,
 	if (rc)
 	if (rc)
 		return rc;
 		return rc;
 
 
-	offset = sizeof(struct hfi_header);
+	rc = hfi_create_header(inst->packet, inst->packet_size,
+			   inst->session_id, core->header_id++);
+	if (rc)
+		return rc;
+
 	rc = hfi_create_packet(inst->packet,
 	rc = hfi_create_packet(inst->packet,
 				inst->packet_size,
 				inst->packet_size,
-				&offset,
 				HFI_CMD_BUFFER,
 				HFI_CMD_BUFFER,
 				(HFI_HOST_FLAGS_RESPONSE_REQUIRED |
 				(HFI_HOST_FLAGS_RESPONSE_REQUIRED |
 				HFI_HOST_FLAGS_INTR_REQUIRED),
 				HFI_HOST_FLAGS_INTR_REQUIRED),
@@ -2590,7 +2592,6 @@ int venus_hfi_queue_buffer(struct msm_vidc_inst *inst,
 				sizeof(hfi_buffer));
 				sizeof(hfi_buffer));
 	if (rc)
 	if (rc)
 		return rc;
 		return rc;
-	num_packets++;
 
 
 	if (metabuf) {
 	if (metabuf) {
 		rc = get_hfi_buffer(inst, metabuf, &hfi_buffer);
 		rc = get_hfi_buffer(inst, metabuf, &hfi_buffer);
@@ -2598,7 +2599,6 @@ int venus_hfi_queue_buffer(struct msm_vidc_inst *inst,
 			return rc;
 			return rc;
 		rc = hfi_create_packet(inst->packet,
 		rc = hfi_create_packet(inst->packet,
 				inst->packet_size,
 				inst->packet_size,
-				&offset,
 				HFI_CMD_BUFFER,
 				HFI_CMD_BUFFER,
 				HFI_HOST_FLAGS_NONE,
 				HFI_HOST_FLAGS_NONE,
 				HFI_PAYLOAD_STRUCTURE,
 				HFI_PAYLOAD_STRUCTURE,
@@ -2608,16 +2608,8 @@ int venus_hfi_queue_buffer(struct msm_vidc_inst *inst,
 				sizeof(hfi_buffer));
 				sizeof(hfi_buffer));
 		if (rc)
 		if (rc)
 			return rc;
 			return rc;
-		num_packets++;
 	}
 	}
 
 
-	rc = hfi_create_header(inst->packet, inst->session_id,
-			   core->header_id++,
-			   num_packets,
-			   offset);
-	if (rc)
-		return rc;
-
 	rc = __iface_cmdq_write(inst->core, inst->packet);
 	rc = __iface_cmdq_write(inst->core, inst->packet);
 	if (rc)
 	if (rc)
 		return rc;
 		return rc;
@@ -2631,7 +2623,6 @@ int venus_hfi_release_buffer(struct msm_vidc_inst *inst,
 	int rc = 0;
 	int rc = 0;
 	struct msm_vidc_core *core;
 	struct msm_vidc_core *core;
 	struct hfi_buffer hfi_buffer;
 	struct hfi_buffer hfi_buffer;
-	u32 num_packets = 0, offset = 0;
 
 
 	d_vpr_h("%s(): inst %p\n", __func__, inst);
 	d_vpr_h("%s(): inst %p\n", __func__, inst);
 	if (!inst || !buffer) {
 	if (!inst || !buffer) {
@@ -2652,10 +2643,13 @@ int venus_hfi_release_buffer(struct msm_vidc_inst *inst,
 	/* add pending release flag */
 	/* add pending release flag */
 	hfi_buffer.flags |= HFI_BUF_HOST_FLAG_RELEASE;
 	hfi_buffer.flags |= HFI_BUF_HOST_FLAG_RELEASE;
 
 
-	offset = sizeof(struct hfi_header);
+	rc = hfi_create_header(inst->packet, inst->packet_size,
+			   inst->session_id, core->header_id++);
+	if (rc)
+		return rc;
+
 	rc = hfi_create_packet(inst->packet,
 	rc = hfi_create_packet(inst->packet,
 				inst->packet_size,
 				inst->packet_size,
-				&offset,
 				HFI_CMD_BUFFER,
 				HFI_CMD_BUFFER,
 				(HFI_HOST_FLAGS_RESPONSE_REQUIRED |
 				(HFI_HOST_FLAGS_RESPONSE_REQUIRED |
 				HFI_HOST_FLAGS_INTR_REQUIRED),
 				HFI_HOST_FLAGS_INTR_REQUIRED),
@@ -2666,14 +2660,6 @@ int venus_hfi_release_buffer(struct msm_vidc_inst *inst,
 				sizeof(hfi_buffer));
 				sizeof(hfi_buffer));
 	if (rc)
 	if (rc)
 		return rc;
 		return rc;
-	num_packets++;
-
-	rc = hfi_create_header(inst->packet, inst->session_id,
-			   core->header_id++,
-			   num_packets,
-			   offset);
-	if (rc)
-		return rc;
 
 
 	rc = __iface_cmdq_write(inst->core, inst->packet);
 	rc = __iface_cmdq_write(inst->core, inst->packet);
 	if (rc)
 	if (rc)