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

Commit 1a73374a authored by Stanimir Varbanov's avatar Stanimir Varbanov Committed by Mauro Carvalho Chehab
Browse files

media: venus: hfi_parser: add common capability parser



This adds common capability parser for all supported Venus
versions. Having it will help to enumerate better the supported
raw formats and codecs and also the capabilities for every
codec like max/min width/height, framerate, bitrate and so on.

Signed-off-by: default avatarStanimir Varbanov <stanimir.varbanov@linaro.org>
Reviewed-by: default avatarTomasz Figa <tfiga@chromium.org>
Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+samsung@kernel.org>
parent aa3a8414
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -2,7 +2,8 @@
# Makefile for Qualcomm Venus driver

venus-core-objs += core.o helpers.o firmware.o \
		   hfi_venus.o hfi_msgs.o hfi_cmds.o hfi.o
		   hfi_venus.o hfi_msgs.o hfi_cmds.o hfi.o \
		   hfi_parser.o

venus-dec-objs += vdec.o vdec_ctrls.o
venus-enc-objs += venc.o venc_ctrls.o
+85 −0
Original line number Diff line number Diff line
@@ -152,6 +152,83 @@ static void venus_clks_disable(struct venus_core *core)
		clk_disable_unprepare(core->clks[i]);
}

static u32 to_v4l2_codec_type(u32 codec)
{
	switch (codec) {
	case HFI_VIDEO_CODEC_H264:
		return V4L2_PIX_FMT_H264;
	case HFI_VIDEO_CODEC_H263:
		return V4L2_PIX_FMT_H263;
	case HFI_VIDEO_CODEC_MPEG1:
		return V4L2_PIX_FMT_MPEG1;
	case HFI_VIDEO_CODEC_MPEG2:
		return V4L2_PIX_FMT_MPEG2;
	case HFI_VIDEO_CODEC_MPEG4:
		return V4L2_PIX_FMT_MPEG4;
	case HFI_VIDEO_CODEC_VC1:
		return V4L2_PIX_FMT_VC1_ANNEX_G;
	case HFI_VIDEO_CODEC_VP8:
		return V4L2_PIX_FMT_VP8;
	case HFI_VIDEO_CODEC_VP9:
		return V4L2_PIX_FMT_VP9;
	case HFI_VIDEO_CODEC_DIVX:
	case HFI_VIDEO_CODEC_DIVX_311:
		return V4L2_PIX_FMT_XVID;
	default:
		return 0;
	}
}

static int venus_enumerate_codecs(struct venus_core *core, u32 type)
{
	const struct hfi_inst_ops dummy_ops = {};
	struct venus_inst *inst;
	u32 codec, codecs;
	unsigned int i;
	int ret;

	if (core->res->hfi_version != HFI_VERSION_1XX)
		return 0;

	inst = kzalloc(sizeof(*inst), GFP_KERNEL);
	if (!inst)
		return -ENOMEM;

	mutex_init(&inst->lock);
	inst->core = core;
	inst->session_type = type;
	if (type == VIDC_SESSION_TYPE_DEC)
		codecs = core->dec_codecs;
	else
		codecs = core->enc_codecs;

	ret = hfi_session_create(inst, &dummy_ops);
	if (ret)
		goto err;

	for (i = 0; i < MAX_CODEC_NUM; i++) {
		codec = (1 << i) & codecs;
		if (!codec)
			continue;

		ret = hfi_session_init(inst, to_v4l2_codec_type(codec));
		if (ret)
			goto done;

		ret = hfi_session_deinit(inst);
		if (ret)
			goto done;
	}

done:
	hfi_session_destroy(inst);
err:
	mutex_destroy(&inst->lock);
	kfree(inst);

	return ret;
}

static int venus_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
@@ -219,6 +296,14 @@ static int venus_probe(struct platform_device *pdev)
	if (ret)
		goto err_venus_shutdown;

	ret = venus_enumerate_codecs(core, VIDC_SESSION_TYPE_DEC);
	if (ret)
		goto err_venus_shutdown;

	ret = venus_enumerate_codecs(core, VIDC_SESSION_TYPE_ENC);
	if (ret)
		goto err_venus_shutdown;

	ret = v4l2_device_register(dev, &core->v4l2_dev);
	if (ret)
		goto err_core_deinit;
+44 −30
Original line number Diff line number Diff line
@@ -57,6 +57,30 @@ struct venus_format {
	u32 type;
};

#define MAX_PLANES		4
#define MAX_FMT_ENTRIES		32
#define MAX_CAP_ENTRIES		32
#define MAX_ALLOC_MODE_ENTRIES	16
#define MAX_CODEC_NUM		32

struct raw_formats {
	u32 buftype;
	u32 fmt;
};

struct venus_caps {
	u32 codec;
	u32 domain;
	bool cap_bufs_mode_dynamic;
	unsigned int num_caps;
	struct hfi_capability caps[MAX_CAP_ENTRIES];
	unsigned int num_pl;
	struct hfi_profile_level pl[HFI_MAX_PROFILE_COUNT];
	unsigned int num_fmts;
	struct raw_formats fmts[MAX_FMT_ENTRIES];
	bool valid;	/* used only for Venus v1xx */
};

/**
 * struct venus_core - holds core parameters valid for all instances
 *
@@ -113,8 +137,8 @@ struct venus_core {
	unsigned int error;
	bool sys_error;
	const struct hfi_core_ops *core_ops;
	u32 enc_codecs;
	u32 dec_codecs;
	unsigned long enc_codecs;
	unsigned long dec_codecs;
	unsigned int max_sessions_supported;
#define ENC_ROTATION_CAPABILITY		0x1
#define ENC_SCALING_CAPABILITY		0x2
@@ -124,6 +148,8 @@ struct venus_core {
	void *priv;
	const struct hfi_ops *ops;
	struct delayed_work work;
	struct venus_caps caps[MAX_CODEC_NUM];
	unsigned int codecs_count;
};

struct vdec_controls {
@@ -216,6 +242,7 @@ struct venus_buffer {
 * @reconfig:	a flag raised by decoder when the stream resolution changed
 * @reconfig_width:	holds the new width
 * @reconfig_height:	holds the new height
 * @hfi_codec:		current codec for this instance in HFI space
 * @sequence_cap:	a sequence counter for capture queue
 * @sequence_out:	a sequence counter for output queue
 * @m2m_dev:	a reference to m2m device structure
@@ -228,22 +255,8 @@ struct venus_buffer {
 * @priv:	a private for HFI operations callbacks
 * @session_type:	the type of the session (decoder or encoder)
 * @hprop:	a union used as a holder by get property
 * @cap_width:	width capability
 * @cap_height:	height capability
 * @cap_mbs_per_frame:	macroblocks per frame capability
 * @cap_mbs_per_sec:	macroblocks per second capability
 * @cap_framerate:	framerate capability
 * @cap_scale_x:		horizontal scaling capability
 * @cap_scale_y:		vertical scaling capability
 * @cap_bitrate:		bitrate capability
 * @cap_hier_p:		hier capability
 * @cap_ltr_count:	LTR count capability
 * @cap_secure_output2_threshold: secure OUTPUT2 threshold capability
 * @cap_bufs_mode_static:	buffers allocation mode capability
 * @cap_bufs_mode_dynamic:	buffers allocation mode capability
 * @pl_count:	count of supported profiles/levels
 * @pl:		supported profiles/levels
 * @bufreq:	holds buffer requirements
 */
struct venus_inst {
	struct list_head list;
@@ -280,6 +293,7 @@ struct venus_inst {
	bool reconfig;
	u32 reconfig_width;
	u32 reconfig_height;
	u32 hfi_codec;
	u32 sequence_cap;
	u32 sequence_out;
	struct v4l2_m2m_dev *m2m_dev;
@@ -291,22 +305,8 @@ struct venus_inst {
	const struct hfi_inst_ops *ops;
	u32 session_type;
	union hfi_get_property hprop;
	struct hfi_capability cap_width;
	struct hfi_capability cap_height;
	struct hfi_capability cap_mbs_per_frame;
	struct hfi_capability cap_mbs_per_sec;
	struct hfi_capability cap_framerate;
	struct hfi_capability cap_scale_x;
	struct hfi_capability cap_scale_y;
	struct hfi_capability cap_bitrate;
	struct hfi_capability cap_hier_p;
	struct hfi_capability cap_ltr_count;
	struct hfi_capability cap_secure_output2_threshold;
	bool cap_bufs_mode_static;
	bool cap_bufs_mode_dynamic;
	unsigned int pl_count;
	struct hfi_profile_level pl[HFI_MAX_PROFILE_COUNT];
	struct hfi_buffer_requirements bufreq[HFI_BUFFER_TYPE_MAX];
};

#define IS_V1(core)	((core)->res->hfi_version == HFI_VERSION_1XX)
@@ -326,4 +326,18 @@ static inline void *to_hfi_priv(struct venus_core *core)
	return core->priv;
}

static inline struct venus_caps *
venus_caps_by_codec(struct venus_core *core, u32 codec, u32 domain)
{
	unsigned int c;

	for (c = 0; c < core->codecs_count; c++) {
		if (core->caps[c].codec == codec &&
		    core->caps[c].domain == domain)
			return &core->caps[c];
	}

	return NULL;
}

#endif
+2 −3
Original line number Diff line number Diff line
@@ -203,13 +203,12 @@ int hfi_session_init(struct venus_inst *inst, u32 pixfmt)
{
	struct venus_core *core = inst->core;
	const struct hfi_ops *ops = core->ops;
	u32 codec;
	int ret;

	codec = to_codec_type(pixfmt);
	inst->hfi_codec = to_codec_type(pixfmt);
	reinit_completion(&inst->done);

	ret = ops->session_init(inst, inst->session_type, codec);
	ret = ops->session_init(inst, inst->session_type, inst->hfi_codec);
	if (ret)
		return ret;

+14 −14
Original line number Diff line number Diff line
@@ -858,10 +858,23 @@ struct hfi_uncompressed_format_select {
	u32 format;
};

struct hfi_uncompressed_plane_constraints {
	u32 stride_multiples;
	u32 max_stride;
	u32 min_plane_buffer_height_multiple;
	u32 buffer_alignment;
};

struct hfi_uncompressed_plane_info {
	u32 format;
	u32 num_planes;
	struct hfi_uncompressed_plane_constraints plane_constraints[1];
};

struct hfi_uncompressed_format_supported {
	u32 buffer_type;
	u32 format_entries;
	u32 format_info[1];
	struct hfi_uncompressed_plane_info plane_info[1];
};

struct hfi_uncompressed_plane_actual {
@@ -875,19 +888,6 @@ struct hfi_uncompressed_plane_actual_info {
	struct hfi_uncompressed_plane_actual plane_format[1];
};

struct hfi_uncompressed_plane_constraints {
	u32 stride_multiples;
	u32 max_stride;
	u32 min_plane_buffer_height_multiple;
	u32 buffer_alignment;
};

struct hfi_uncompressed_plane_info {
	u32 format;
	u32 num_planes;
	struct hfi_uncompressed_plane_constraints plane_format[1];
};

struct hfi_uncompressed_plane_actual_constraints_info {
	u32 buffer_type;
	u32 num_planes;
Loading