Browse Source

video: driver: add capabilities parsing logic

Parse capabilities from platform specific file.

Change-Id: I46e45995f24f92d374f749fd58c200542591b6a4
Signed-off-by: Akshata Sahukar <[email protected]>
Akshata Sahukar 4 năm trước cách đây
mục cha
commit
25f6fd7e7e

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

@@ -40,7 +40,7 @@
 #define CODECS_ALL     (MSM_VIDC_H264 | MSM_VIDC_HEVC | \
 			MSM_VIDC_VP9 | MSM_VIDC_MPEG2)
 
-static struct msm_vidc_core_data core_data_waipio[] = {
+static struct msm_platform_core_capability core_data_waipio[] = {
 	/* {type, value} */
 	{ENC_CODECS, H264|HEVC},
 	{DEC_CODECS, H264|HEVC|VP9|MPEG2},
@@ -81,7 +81,7 @@ static struct msm_vidc_core_data core_data_waipio[] = {
 	{AV_SYNC_WINDOW_SIZE, 40},
 };
 
-static struct msm_vidc_instance_data instance_data_waipio[] = {
+static struct msm_platform_inst_capability instance_data_waipio[] = {
 	/* {type, domains, codecs, min, max, step_or_menu, value} */
 	{FRAME_WIDTH, ENC|DEC, CODECS_ALL, 128, 8192, 1, 1920},
 	{FRAME_HEIGHT, ENC|DEC, CODECS_ALL, 128, 8192, 1, 1080},
@@ -92,7 +92,7 @@ static struct msm_vidc_instance_data instance_data_waipio[] = {
 	{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},
-	{CABAC_BIT_RATE, ENC, H264, 1, 160000000, 1, 20000000},
+	{CABAC_BITRATE, ENC, H264, 1, 160000000, 1, 20000000},
 	{SCALE_X, ENC, CODECS_ALL, 8192, 65536, 1, 8192},
 	{SCALE_Y, ENC, CODECS_ALL, 8192, 65536, 1, 8192},
 	{SCALE_X, DEC, CODECS_ALL, 65536, 65536, 1, 65536},

+ 2 - 0
driver/vidc/inc/msm_vidc_core.h

@@ -76,6 +76,8 @@ struct msm_vidc_core {
 	u32                                    spur_count;
 	u32                                    reg_count;
 	bool                                   power_enabled;
+	struct msm_vidc_core_capability       *capabilities;
+	struct msm_vidc_inst_capability       *inst_caps;
 	struct msm_vidc_mem_addr               sfr;
 	struct msm_vidc_mem_addr               iface_q_table;
 	struct msm_vidc_iface_q_info           iface_queues[VIDC_IFACEQ_NUMQ];

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

@@ -106,6 +106,7 @@ struct msm_vidc_inst {
 	bool                               session_created;
 	struct dentry                     *debugfs_root;
 	struct msm_vidc_debug              debug;
+	struct msm_vidc_inst_capability   *capabilities;
 };
 
 #endif // _MSM_VIDC_INST_H_

+ 42 - 4
driver/vidc/inc/msm_vidc_internal.h

@@ -36,6 +36,8 @@
 #define MAX_SUPPORTED_INSTANCES  16
 #define MAX_BSE_VPP_DELAY        6
 #define DEFAULT_BSE_VPP_DELAY    2
+#define MAX_CAP_PARENTS          16
+#define MAX_CAP_CHILDREN         16
 
 /* Maintains the number of FTB's between each FBD over a window */
 #define DCVS_FTB_WINDOW 16
@@ -130,8 +132,9 @@ enum msm_vidc_port_type {
 	MAX_PORT,
 };
 
-enum msm_vidc_core_data_type {
-	ENC_CODECS = 0,
+enum msm_vidc_core_capability_type {
+	CORE_CAP_NONE = 0,
+	ENC_CODECS,
 	DEC_CODECS,
 	MAX_SESSION_COUNT,
 	MAX_SECURE_SESSION_COUNT,
@@ -159,16 +162,18 @@ enum msm_vidc_core_data_type {
 	DECODE_BATCH_TIMEOUT,
 	AV_SYNC_WINDOW_SIZE,
 	CLK_FREQ_THRESHOLD,
+	CORE_CAP_MAX,
 };
 
-enum msm_vidc_instance_data_type {
+enum msm_vidc_inst_capability_type {
+	INST_CAP_NONE = 0,
 	FRAME_WIDTH,
 	FRAME_HEIGHT,
 	MBPF,
 	MBPS,
 	FRAME_RATE,
 	BIT_RATE,
-	CABAC_BIT_RATE,
+	CABAC_BITRATE,
 	LTR_COUNT,
 	LCU_SIZE,
 	POWER_SAVE_MBPS,
@@ -205,6 +210,39 @@ enum msm_vidc_instance_data_type {
 	MB_CYCLES_LP,
 	MB_CYCLES_FW,
 	MB_CYCLES_FW_VPP,
+	INST_CAP_MAX,
+};
+
+enum msm_vidc_inst_capability_flags {
+	CAP_FLAG_ROOT                    = BIT(0),
+	CAP_FLAG_DYNAMIC_ALLOWED         = BIT(1),
+	CAP_FLAG_MENU                    = BIT(2),
+};
+
+struct msm_vidc_inst_cap {
+	enum msm_vidc_inst_capability_type cap;
+	s32 min;
+	s32 max;
+	u32 step_or_menu;
+	s32 value;
+	enum msm_vidc_inst_capability_flags flags;
+	u32 v4l2_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);
+};
+
+struct msm_vidc_inst_capability {
+	enum msm_vidc_domain_type domain;
+	enum msm_vidc_codec_type codec;
+	struct msm_vidc_inst_cap cap[INST_CAP_MAX];
+};
+
+struct msm_vidc_core_capability {
+	enum msm_vidc_core_capability_type type;
+	u32 value;
 };
 
 enum efuse_purpose {

+ 18 - 11
driver/vidc/inc/msm_vidc_platform.h

@@ -10,19 +10,26 @@
 
 #include "msm_vidc_internal.h"
 
-struct msm_vidc_core_data {
-	enum msm_vidc_core_data_type type;
+struct msm_platform_core_capability {
+	enum msm_vidc_core_capability_type type;
 	u32 value;
 };
 
-struct msm_vidc_instance_data {
-	enum msm_vidc_instance_data_type type;
-	enum msm_vidc_domain_type domains;
-	enum msm_vidc_codec_type codecs;
-	u32 min;
-	u32 max;
+struct msm_platform_inst_capability {
+	enum msm_vidc_inst_capability_type cap;
+	enum msm_vidc_domain_type domain;
+	enum msm_vidc_codec_type codec;
+	s32 min;
+	s32 max;
 	u32 step_or_menu;
-	u32 value;
+	s32 value;
+	enum msm_vidc_inst_capability_flags flags;
+	u32 v4l2_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);
 };
 
 struct msm_vidc_csc_coeff {
@@ -61,9 +68,9 @@ struct msm_vidc_ubwc_config_data {
 };
 
 struct msm_vidc_platform_data {
-	struct msm_vidc_core_data *core_data;
+	struct msm_platform_core_capability *core_data;
 	u32 core_data_size;
-	struct msm_vidc_instance_data *instance_data;
+	struct msm_platform_inst_capability *instance_data;
 	u32 instance_data_size;
 	struct allowed_clock_rates_table *allowed_clks_tbl;
 	u32 allowed_clks_tbl_size;

+ 192 - 2
driver/vidc/src/msm_vidc_driver.c

@@ -9,11 +9,19 @@
 #include <media/msm_media_info.h>
 
 #include "msm_vidc_driver.h"
+#include "msm_vidc_platform.h"
 #include "msm_vidc_internal.h"
 #include "msm_vidc_memory.h"
 #include "msm_vidc_debug.h"
 #include "venus_hfi.h"
 
+#define COUNT_BITS(a, out) ({       \
+	while ((a) >= 1) {          \
+		(out) += (a) & (1); \
+		(a) >>= (1);        \
+	}                           \
+})
+
 void print_vidc_buffer(struct msm_vidc_inst *inst, struct msm_vidc_buffer *b)
 {
 }
@@ -542,12 +550,187 @@ int msm_vidc_session_open(struct msm_vidc_inst *inst)
 	return 0;
 }
 
+static int msm_vidc_init_core_caps(struct msm_vidc_core *core)
+{
+	int rc = 0;
+	int i, num_platform_caps;
+	struct msm_platform_core_capability *platform_data;
+
+	if (!core || !core->platform) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		rc = -EINVAL;
+		goto exit;
+	}
+
+	platform_data = core->platform->data.core_data;
+	if (!platform_data) {
+		d_vpr_e("%s: platform core data is NULL\n",
+				__func__);
+			rc = -EINVAL;
+			goto exit;
+	}
+
+	if (!core->capabilities) {
+		core->capabilities = kcalloc(1,
+			(sizeof(struct msm_vidc_core_capability) *
+			CORE_CAP_MAX), GFP_KERNEL);
+		if (!core->capabilities) {
+			d_vpr_e("%s: failed to allocate core capabilities\n",
+				__func__);
+			rc = -ENOMEM;
+			goto exit;
+		}
+	} else {
+		d_vpr_e("%s: capabilities memory is expected to be freed\n",
+			__func__);
+	}
+
+	num_platform_caps = core->platform->data.core_data_size;
+
+	/* loop over platform caps */
+	for (i = 0; i < num_platform_caps; i++) {
+		core->capabilities[platform_data[i].type].type = platform_data[i].type;
+		core->capabilities[platform_data[i].type].value = platform_data[i].value;
+	}
+
+exit:
+	return rc;
+}
+
+static void update_inst_capability(struct msm_platform_inst_capability *in,
+		struct msm_vidc_inst_capability *capability)
+{
+	if (!in || !capability) {
+		d_vpr_e("%s: invalid params %pK %pK\n",
+			__func__, in, capability);
+		return;
+	}
+	if (in->cap < INST_CAP_MAX) {
+		capability->cap[in->cap].cap = in->cap;
+		capability->cap[in->cap].min = in->min;
+		capability->cap[in->cap].max = in->max;
+		capability->cap[in->cap].step_or_menu = in->step_or_menu;
+		capability->cap[in->cap].value = in->value;
+		capability->cap[in->cap].flags = in->flags;
+		capability->cap[in->cap].v4l2_id = in->v4l2_id;
+		capability->cap[in->cap].hfi_id = in->hfi_id;
+		memcpy(capability->cap[in->cap].parents, in->parents,
+			sizeof(capability->cap[in->cap].parents));
+		memcpy(capability->cap[in->cap].children, in->children,
+			sizeof(capability->cap[in->cap].children));
+		capability->cap[in->cap].adjust = in->adjust;
+		capability->cap[in->cap].set = in->set;
+	} else {
+		d_vpr_e("%s: invalid cap %d\n",
+			__func__, in->cap);
+	}
+}
+
+static int msm_vidc_init_instance_caps(struct msm_vidc_core *core)
+{
+	int rc = 0;
+	u8 enc_valid_codecs, dec_valid_codecs;
+	u8 count_bits, enc_codec_count;
+	u8 codecs_count = 0;
+	int i, j, check_bit, num_platform_caps;
+	struct msm_platform_inst_capability *platform_data = NULL;
+
+	if (!core || !core->platform || !core->capabilities) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		rc = -EINVAL;
+		goto exit;
+	}
+
+	platform_data = core->platform->data.instance_data;
+	if (!platform_data) {
+		d_vpr_e("%s: platform instance data is NULL\n",
+				__func__);
+			rc = -EINVAL;
+			goto exit;
+	}
+
+	enc_valid_codecs = core->capabilities[ENC_CODECS].value;
+	count_bits = enc_valid_codecs;
+	COUNT_BITS(count_bits, codecs_count);
+	enc_codec_count = codecs_count;
+
+	dec_valid_codecs = core->capabilities[DEC_CODECS].value;
+	count_bits = dec_valid_codecs;
+	COUNT_BITS(count_bits, codecs_count);
+
+	if (!core->inst_caps) {
+		core->inst_caps = kcalloc(codecs_count,
+			sizeof(struct msm_vidc_inst_capability),
+			GFP_KERNEL);
+		if (!core->inst_caps) {
+			d_vpr_e("%s: failed to allocate core capabilities\n",
+				__func__);
+			rc = -ENOMEM;
+			goto exit;
+		}
+	} else {
+		d_vpr_e("%s: capabilities memory is expected to be freed\n",
+			__func__);
+	}
+
+	check_bit = 0;
+	/* determine codecs for enc domain */
+	for (i = 0; i < enc_codec_count; i++) {
+		while (check_bit < (sizeof(enc_valid_codecs) * 8)) {
+			if (enc_valid_codecs & BIT(check_bit)) {
+				core->inst_caps[i].domain = MSM_VIDC_ENCODER;
+				core->inst_caps[i].codec = enc_valid_codecs &
+						BIT(check_bit);
+				check_bit++;
+				break;
+			}
+			check_bit++;
+		}
+	}
+
+	/* reset checkbit to check from 0th bit of decoder codecs set bits*/
+	check_bit = 0;
+	/* determine codecs for dec domain */
+	for (; i < codecs_count; i++) {
+		while (check_bit < (sizeof(dec_valid_codecs) * 8)) {
+			if (dec_valid_codecs & BIT(check_bit)) {
+				core->inst_caps[i].domain = MSM_VIDC_DECODER;
+				core->inst_caps[i].codec = dec_valid_codecs &
+						BIT(check_bit);
+				check_bit++;
+				break;
+			}
+			check_bit++;
+		}
+	}
+
+	num_platform_caps = core->platform->data.instance_data_size;
+
+	d_vpr_h("%s: num caps %d\n", __func__, num_platform_caps);
+	/* loop over each platform capability */
+	for (i = 0; i < num_platform_caps; i++) {
+		/* select matching core codec and update it */
+		for (j = 0; j < codecs_count; j++) {
+			if ((platform_data[i].domain &
+				core->inst_caps[j].domain) &&
+				(platform_data[i].codec &
+				core->inst_caps[j].codec)) {
+				/* update core capability */
+				update_inst_capability(&platform_data[i],
+					&core->inst_caps[j]);
+			}
+		}
+	}
+exit:
+	return rc;
+}
+
 int msm_vidc_core_init(struct msm_vidc_core *core)
 {
-	int rc;
+	int rc = 0;
 
 	d_vpr_h("%s()\n", __func__);
-	if (!core) {
+	if (!core || !core->platform) {
 		d_vpr_e("%s: invalid params\n", __func__);
 		return -EINVAL;
 	}
@@ -563,6 +746,13 @@ int msm_vidc_core_init(struct msm_vidc_core *core)
 		goto unlock;
 	}
 
+	rc = msm_vidc_init_core_caps(core);
+	if (rc)
+		goto unlock;
+	rc = msm_vidc_init_instance_caps(core);
+	if (rc)
+		goto unlock;
+
 	rc = venus_hfi_core_init(core);
 	if (rc) {
 		d_vpr_e("%s: core init failed\n", __func__);

+ 1 - 1
include/uapi/vidc/media/msm_vidc_utils.h

@@ -29,4 +29,4 @@
 
 /* vendor controls end */
 
-#endif // __MSM_VIDC_UTILS_H__
+#endif