Commit 01abf5fb authored by Yunfei Dong's avatar Yunfei Dong Committed by Mauro Carvalho Chehab
Browse files

media: mediatek: vcodec: separate struct 'mtk_vcodec_ctx'



Adding different context struct for encoder and decoder and removing
struct 'mtk_vcodec_ctx'.

Signed-off-by: default avatarYunfei Dong <yunfei.dong@mediatek.com>
Reviewed-by: default avatarNicolas Dufresne <nicolas.dufresne@collabora.com>
Reviewed-by: default avatarAngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
parent 41f03c67
Loading
Loading
Loading
Loading
+76 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (c) 2023 MediaTek Inc.
 * Author: Yunfei Dong <yunfei.dong@mediatek.com>
 */

#ifndef _MTK_VCODEC_COM_DRV_H_
#define _MTK_VCODEC_COM_DRV_H_

#include <linux/platform_device.h>
#include <linux/videodev2.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-mem2mem.h>
#include <media/videobuf2-core.h>

#define MTK_VCODEC_MAX_PLANES	3

/**
 * enum mtk_instance_state - The state of an MTK Vcodec instance.
 * @MTK_STATE_FREE: default state when instance is created
 * @MTK_STATE_INIT: vcodec instance is initialized
 * @MTK_STATE_HEADER: vdec had sps/pps header parsed or venc
 *			had sps/pps header encoded
 * @MTK_STATE_FLUSH: vdec is flushing. Only used by decoder
 * @MTK_STATE_ABORT: vcodec should be aborted
 */
enum mtk_instance_state {
	MTK_STATE_FREE = 0,
	MTK_STATE_INIT = 1,
	MTK_STATE_HEADER = 2,
	MTK_STATE_FLUSH = 3,
	MTK_STATE_ABORT = 4,
};

enum mtk_fmt_type {
	MTK_FMT_DEC = 0,
	MTK_FMT_ENC = 1,
	MTK_FMT_FRAME = 2,
};

/*
 * struct mtk_video_fmt - Structure used to store information about pixelformats
 */
struct mtk_video_fmt {
	u32	fourcc;
	enum mtk_fmt_type	type;
	u32	num_planes;
	u32	flags;
	struct v4l2_frmsize_stepwise frmsize;
};

/*
 * struct mtk_q_data - Structure used to store information about queue
 */
struct mtk_q_data {
	unsigned int	visible_width;
	unsigned int	visible_height;
	unsigned int	coded_width;
	unsigned int	coded_height;
	enum v4l2_field	field;
	unsigned int	bytesperline[MTK_VCODEC_MAX_PLANES];
	unsigned int	sizeimage[MTK_VCODEC_MAX_PLANES];
	const struct mtk_video_fmt	*fmt;
};

/*
 * enum mtk_instance_type - The type of an MTK Vcodec instance.
 */
enum mtk_instance_type {
	MTK_INST_DECODER		= 0,
	MTK_INST_ENCODER		= 1,
};

#endif /* _MTK_VCODEC_COM_DRV_H_ */
+3 −3
Original line number Diff line number Diff line
@@ -10,7 +10,7 @@
#include "mtk_vcodec_drv.h"
#include "mtk_vcodec_util.h"

static void mtk_vdec_dbgfs_get_format_type(struct mtk_vcodec_ctx *ctx, char *buf,
static void mtk_vdec_dbgfs_get_format_type(struct mtk_vcodec_dec_ctx *ctx, char *buf,
					   int *used, int total)
{
	int curr_len;
@@ -91,7 +91,7 @@ static ssize_t mtk_vdec_dbgfs_read(struct file *filp, char __user *ubuf,
	struct mtk_vcodec_dev *vcodec_dev = filp->private_data;
	struct mtk_vcodec_dbgfs *dbgfs = &vcodec_dev->dbgfs;
	struct mtk_vcodec_dbgfs_inst *dbgfs_inst;
	struct mtk_vcodec_ctx *ctx;
	struct mtk_vcodec_dec_ctx *ctx;
	int total_len = 200 * (dbgfs->inst_count == 0 ? 1 : dbgfs->inst_count);
	int used_len = 0, curr_len, ret;
	bool dbgfs_index[MTK_VDEC_DBGFS_MAX] = {0};
@@ -143,7 +143,7 @@ static const struct file_operations vdec_fops = {
	.read = mtk_vdec_dbgfs_read,
};

void mtk_vcodec_dbgfs_create(struct mtk_vcodec_ctx *ctx)
void mtk_vcodec_dbgfs_create(struct mtk_vcodec_dec_ctx *ctx)
{
	struct mtk_vcodec_dbgfs_inst *dbgfs_inst;
	struct mtk_vcodec_dev *vcodec_dev = ctx->dev;
+5 −5
Original line number Diff line number Diff line
@@ -8,7 +8,7 @@
#define __MTK_VCODEC_DBGFS_H__

struct mtk_vcodec_dev;
struct mtk_vcodec_ctx;
struct mtk_vcodec_dec_ctx;

/*
 * enum mtk_vdec_dbgfs_log_index  - used to get different debug information
@@ -22,12 +22,12 @@ enum mtk_vdec_dbgfs_log_index {
/**
 * struct mtk_vcodec_dbgfs_inst  - debugfs information for each inst
 * @node:       list node for each inst
 * @vcodec_ctx: struct mtk_vcodec_ctx
 * @vcodec_ctx: struct mtk_vcodec_dec_ctx
 * @inst_id:    index of the context that the same with ctx->id
 */
struct mtk_vcodec_dbgfs_inst {
	struct list_head node;
	struct mtk_vcodec_ctx *vcodec_ctx;
	struct mtk_vcodec_dec_ctx *vcodec_ctx;
	int inst_id;
};

@@ -50,12 +50,12 @@ struct mtk_vcodec_dbgfs {
};

#if defined(CONFIG_DEBUG_FS)
void mtk_vcodec_dbgfs_create(struct mtk_vcodec_ctx *ctx);
void mtk_vcodec_dbgfs_create(struct mtk_vcodec_dec_ctx *ctx);
void mtk_vcodec_dbgfs_remove(struct mtk_vcodec_dev *vcodec_dev, int ctx_id);
void mtk_vcodec_dbgfs_init(struct mtk_vcodec_dev *vcodec_dev, bool is_encode);
void mtk_vcodec_dbgfs_deinit(struct mtk_vcodec_dev *vcodec_dev);
#else
static inline void mtk_vcodec_dbgfs_create(struct mtk_vcodec_ctx *ctx)
static inline void mtk_vcodec_dbgfs_create(struct mtk_vcodec_dec_ctx *ctx)
{
}

+30 −30
Original line number Diff line number Diff line
@@ -35,7 +35,7 @@ mtk_vdec_find_format(struct v4l2_format *f,
	return NULL;
}

static bool mtk_vdec_get_cap_fmt(struct mtk_vcodec_ctx *ctx, int format_index)
static bool mtk_vdec_get_cap_fmt(struct mtk_vcodec_dec_ctx *ctx, int format_index)
{
	const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata;
	const struct mtk_video_fmt *fmt;
@@ -55,7 +55,7 @@ static bool mtk_vdec_get_cap_fmt(struct mtk_vcodec_ctx *ctx, int format_index)
	return false;
}

static struct mtk_q_data *mtk_vdec_get_q_data(struct mtk_vcodec_ctx *ctx,
static struct mtk_q_data *mtk_vdec_get_q_data(struct mtk_vcodec_dec_ctx *ctx,
					      enum v4l2_buf_type type)
{
	if (V4L2_TYPE_IS_OUTPUT(type))
@@ -74,7 +74,7 @@ static int vidioc_try_decoder_cmd(struct file *file, void *priv,
static int vidioc_decoder_cmd(struct file *file, void *priv,
				struct v4l2_decoder_cmd *cmd)
{
	struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
	struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv);
	struct vb2_queue *src_vq, *dst_vq;
	int ret;

@@ -112,23 +112,23 @@ static int vidioc_decoder_cmd(struct file *file, void *priv,
	return 0;
}

void mtk_vdec_unlock(struct mtk_vcodec_ctx *ctx)
void mtk_vdec_unlock(struct mtk_vcodec_dec_ctx *ctx)
{
	mutex_unlock(&ctx->dev->dec_mutex[ctx->hw_id]);
}

void mtk_vdec_lock(struct mtk_vcodec_ctx *ctx)
void mtk_vdec_lock(struct mtk_vcodec_dec_ctx *ctx)
{
	mutex_lock(&ctx->dev->dec_mutex[ctx->hw_id]);
}

void mtk_vcodec_dec_release(struct mtk_vcodec_ctx *ctx)
void mtk_vcodec_dec_release(struct mtk_vcodec_dec_ctx *ctx)
{
	vdec_if_deinit(ctx);
	ctx->state = MTK_STATE_FREE;
}

void mtk_vcodec_dec_set_default_params(struct mtk_vcodec_ctx *ctx)
void mtk_vcodec_dec_set_default_params(struct mtk_vcodec_dec_ctx *ctx)
{
	struct mtk_q_data *q_data;

@@ -169,7 +169,7 @@ void mtk_vcodec_dec_set_default_params(struct mtk_vcodec_ctx *ctx)
static int vidioc_vdec_qbuf(struct file *file, void *priv,
			    struct v4l2_buffer *buf)
{
	struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
	struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv);

	if (ctx->state == MTK_STATE_ABORT) {
		mtk_v4l2_vdec_err(ctx, "[%d] Call on QBUF after unrecoverable error", ctx->id);
@@ -182,7 +182,7 @@ static int vidioc_vdec_qbuf(struct file *file, void *priv,
static int vidioc_vdec_dqbuf(struct file *file, void *priv,
			     struct v4l2_buffer *buf)
{
	struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
	struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv);

	if (ctx->state == MTK_STATE_ABORT) {
		mtk_v4l2_vdec_err(ctx, "[%d] Call on DQBUF after unrecoverable error", ctx->id);
@@ -194,7 +194,7 @@ static int vidioc_vdec_dqbuf(struct file *file, void *priv,

static int mtk_vcodec_dec_get_chip_name(void *priv)
{
	struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
	struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv);
	struct device *dev = &ctx->dev->plat_dev->dev;

	if (of_device_is_compatible(dev->of_node, "mediatek,mt8173-vcodec-dec"))
@@ -216,7 +216,7 @@ static int mtk_vcodec_dec_get_chip_name(void *priv)
static int vidioc_vdec_querycap(struct file *file, void *priv,
				struct v4l2_capability *cap)
{
	struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
	struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv);
	struct device *dev = &ctx->dev->plat_dev->dev;
	int platform_name = mtk_vcodec_dec_get_chip_name(priv);

@@ -229,7 +229,7 @@ static int vidioc_vdec_querycap(struct file *file, void *priv,
static int vidioc_vdec_subscribe_evt(struct v4l2_fh *fh,
				     const struct v4l2_event_subscription *sub)
{
	struct mtk_vcodec_ctx *ctx = fh_to_ctx(fh);
	struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(fh);

	if (ctx->dev->vdec_pdata->uses_stateless_api)
		return v4l2_ctrl_subscribe_event(fh, sub);
@@ -244,7 +244,7 @@ static int vidioc_vdec_subscribe_evt(struct v4l2_fh *fh,
	}
}

static int vidioc_try_fmt(struct mtk_vcodec_ctx *ctx, struct v4l2_format *f,
static int vidioc_try_fmt(struct mtk_vcodec_dec_ctx *ctx, struct v4l2_format *f,
			  const struct mtk_video_fmt *fmt)
{
	struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
@@ -312,7 +312,7 @@ static int vidioc_try_fmt_vid_cap_mplane(struct file *file, void *priv,
				struct v4l2_format *f)
{
	const struct mtk_video_fmt *fmt;
	struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
	struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv);
	const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata;

	fmt = mtk_vdec_find_format(f, dec_pdata);
@@ -330,7 +330,7 @@ static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv,
{
	struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
	const struct mtk_video_fmt *fmt;
	struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
	struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv);
	const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata;

	fmt = mtk_vdec_find_format(f, dec_pdata);
@@ -351,7 +351,7 @@ static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv,
static int vidioc_vdec_g_selection(struct file *file, void *priv,
			struct v4l2_selection *s)
{
	struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
	struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv);
	struct mtk_q_data *q_data;

	if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
@@ -400,7 +400,7 @@ static int vidioc_vdec_g_selection(struct file *file, void *priv,
static int vidioc_vdec_s_selection(struct file *file, void *priv,
				struct v4l2_selection *s)
{
	struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
	struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv);

	if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
		return -EINVAL;
@@ -422,7 +422,7 @@ static int vidioc_vdec_s_selection(struct file *file, void *priv,
static int vidioc_vdec_s_fmt(struct file *file, void *priv,
			     struct v4l2_format *f)
{
	struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
	struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv);
	struct v4l2_pix_format_mplane *pix_mp;
	struct mtk_q_data *q_data;
	int ret = 0;
@@ -552,7 +552,7 @@ static int vidioc_enum_framesizes(struct file *file, void *priv,
				struct v4l2_frmsizeenum *fsize)
{
	int i = 0;
	struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
	struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv);
	const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata;

	if (fsize->index != 0)
@@ -584,7 +584,7 @@ static int vidioc_enum_framesizes(struct file *file, void *priv,
static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, void *priv,
			   bool output_queue)
{
	struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
	struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv);
	const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata;
	const struct mtk_video_fmt *fmt;
	int i, j = 0;
@@ -630,7 +630,7 @@ static int vidioc_vdec_enum_fmt_vid_out(struct file *file, void *priv,
static int vidioc_vdec_g_fmt(struct file *file, void *priv,
			     struct v4l2_format *f)
{
	struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
	struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv);
	struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
	struct vb2_queue *vq;
	struct mtk_q_data *q_data;
@@ -719,7 +719,7 @@ int vb2ops_vdec_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
			    unsigned int *nplanes, unsigned int sizes[],
			    struct device *alloc_devs[])
{
	struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vq);
	struct mtk_vcodec_dec_ctx *ctx = vb2_get_drv_priv(vq);
	struct mtk_q_data *q_data;
	unsigned int i;

@@ -761,7 +761,7 @@ int vb2ops_vdec_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,

int vb2ops_vdec_buf_prepare(struct vb2_buffer *vb)
{
	struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
	struct mtk_vcodec_dec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
	struct mtk_q_data *q_data;
	int i;

@@ -785,7 +785,7 @@ int vb2ops_vdec_buf_prepare(struct vb2_buffer *vb)

void vb2ops_vdec_buf_finish(struct vb2_buffer *vb)
{
	struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
	struct mtk_vcodec_dec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
	struct vb2_v4l2_buffer *vb2_v4l2;
	struct mtk_video_dec_buf *buf;
	bool buf_error;
@@ -823,7 +823,7 @@ int vb2ops_vdec_buf_init(struct vb2_buffer *vb)

int vb2ops_vdec_start_streaming(struct vb2_queue *q, unsigned int count)
{
	struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(q);
	struct mtk_vcodec_dec_ctx *ctx = vb2_get_drv_priv(q);

	if (ctx->state == MTK_STATE_FLUSH)
		ctx->state = MTK_STATE_HEADER;
@@ -834,7 +834,7 @@ int vb2ops_vdec_start_streaming(struct vb2_queue *q, unsigned int count)
void vb2ops_vdec_stop_streaming(struct vb2_queue *q)
{
	struct vb2_v4l2_buffer *src_buf = NULL, *dst_buf = NULL;
	struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(q);
	struct mtk_vcodec_dec_ctx *ctx = vb2_get_drv_priv(q);
	int ret;

	mtk_v4l2_vdec_dbg(3, ctx, "[%d] (%d) state=(%x) ctx->decoded_frame_cnt=%d",
@@ -889,7 +889,7 @@ void vb2ops_vdec_stop_streaming(struct vb2_queue *q)

static void m2mops_vdec_device_run(void *priv)
{
	struct mtk_vcodec_ctx *ctx = priv;
	struct mtk_vcodec_dec_ctx *ctx = priv;
	struct mtk_vcodec_dev *dev = ctx->dev;

	queue_work(dev->decode_workqueue, &ctx->decode_work);
@@ -897,7 +897,7 @@ static void m2mops_vdec_device_run(void *priv)

static int m2mops_vdec_job_ready(void *m2m_priv)
{
	struct mtk_vcodec_ctx *ctx = m2m_priv;
	struct mtk_vcodec_dec_ctx *ctx = m2m_priv;

	mtk_v4l2_vdec_dbg(3, ctx, "[%d]", ctx->id);

@@ -916,7 +916,7 @@ static int m2mops_vdec_job_ready(void *m2m_priv)

static void m2mops_vdec_job_abort(void *priv)
{
	struct mtk_vcodec_ctx *ctx = priv;
	struct mtk_vcodec_dec_ctx *ctx = priv;

	ctx->state = MTK_STATE_ABORT;
}
@@ -964,7 +964,7 @@ const struct v4l2_ioctl_ops mtk_vdec_ioctl_ops = {
int mtk_vcodec_dec_queue_init(void *priv, struct vb2_queue *src_vq,
			   struct vb2_queue *dst_vq)
{
	struct mtk_vcodec_ctx *ctx = priv;
	struct mtk_vcodec_dec_ctx *ctx = priv;
	int ret = 0;

	mtk_v4l2_vdec_dbg(3, ctx, "[%d]", ctx->id);
+6 −4
Original line number Diff line number Diff line
@@ -11,6 +11,8 @@
#include <media/videobuf2-core.h>
#include <media/v4l2-mem2mem.h>

#include "mtk_vcodec_dec_drv.h"

#define VCODEC_DEC_ALIGNED_64 64
#define VCODEC_CAPABILITY_4K_DISABLED	0x10
#define VCODEC_DEC_4K_CODED_WIDTH	4096U
@@ -78,12 +80,12 @@ extern const struct mtk_vcodec_dec_pdata mtk_vdec_single_core_pdata;
 * mtk_vdec_lock get decoder hw lock and set curr_ctx
 * to ctx instance that get lock
 */
void mtk_vdec_unlock(struct mtk_vcodec_ctx *ctx);
void mtk_vdec_lock(struct mtk_vcodec_ctx *ctx);
void mtk_vdec_unlock(struct mtk_vcodec_dec_ctx *ctx);
void mtk_vdec_lock(struct mtk_vcodec_dec_ctx *ctx);
int mtk_vcodec_dec_queue_init(void *priv, struct vb2_queue *src_vq,
			   struct vb2_queue *dst_vq);
void mtk_vcodec_dec_set_default_params(struct mtk_vcodec_ctx *ctx);
void mtk_vcodec_dec_release(struct mtk_vcodec_ctx *ctx);
void mtk_vcodec_dec_set_default_params(struct mtk_vcodec_dec_ctx *ctx);
void mtk_vcodec_dec_release(struct mtk_vcodec_dec_ctx *ctx);

/*
 * VB2 ops
Loading