Commit e57b6d32 authored by Aakarsh Jain's avatar Aakarsh Jain Committed by Hans Verkuil
Browse files

media: s5p-mfc: Add initial support for MFCv12



Add support for MFCv12, with a new register file and necessary hw
control, decoder, encoder and structural changes. Add luma dbp, chroma
dpb and mv sizes for each codec as per the UM for MFCv12, along with
appropriate alignment.

Cc: linux-fsd@tesla.com
Signed-off-by: default avatarSmitha T Murthy <smithatmurthy@gmail.com>
Signed-off-by: default avatarAakarsh Jain <aakarsh.jain@samsung.com>
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
parent 199643db
Loading
Loading
Loading
Loading
+50 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Register definition file for Samsung MFC V12.x Interface (FIMV) driver
 *
 * Copyright (c) 2020 Samsung Electronics Co., Ltd.
 *     http://www.samsung.com/
 */

#ifndef _REGS_MFC_V12_H
#define _REGS_MFC_V12_H

#include <linux/sizes.h>
#include "regs-mfc-v10.h"

/* MFCv12 Context buffer sizes */
#define MFC_CTX_BUF_SIZE_V12		(30 * SZ_1K)
#define MFC_H264_DEC_CTX_BUF_SIZE_V12	(2 * SZ_1M)
#define MFC_OTHER_DEC_CTX_BUF_SIZE_V12	(30 * SZ_1K)
#define MFC_H264_ENC_CTX_BUF_SIZE_V12	(100 * SZ_1K)
#define MFC_HEVC_ENC_CTX_BUF_SIZE_V12	(40 * SZ_1K)
#define MFC_OTHER_ENC_CTX_BUF_SIZE_V12	(25 * SZ_1K)

/* MFCv12 variant defines */
#define MAX_FW_SIZE_V12			(SZ_1M)
#define MAX_CPB_SIZE_V12		(7 * SZ_1M)
#define MFC_VERSION_V12			0xC0
#define MFC_NUM_PORTS_V12		1
#define S5P_FIMV_CODEC_VP9_ENC		27

/* Encoder buffer size for MFCv12 */
#define ENC_V120_BASE_SIZE(x, y) \
	((((x) + 3) * ((y) + 3) * 8) \
	+ ((((y) * 64) + 2304) * ((x) + 7) / 8))

#define ENC_V120_H264_ME_SIZE(x, y) \
	ALIGN((ENC_V120_BASE_SIZE(x, y) \
	+ (DIV_ROUND_UP((x) * (y), 64) * 32)), 256)

#define ENC_V120_MPEG4_ME_SIZE(x, y) \
	ALIGN((ENC_V120_BASE_SIZE(x, y) \
	+ (DIV_ROUND_UP((x) * (y), 128) * 16)), 256)

#define ENC_V120_VP8_ME_SIZE(x, y) \
	ALIGN(ENC_V120_BASE_SIZE((x), (y)), 256)

#define ENC_V120_HEVC_ME_SIZE(x, y)     \
	ALIGN(((((x) + 3) * ((y) + 3) * 32)       \
	+ ((((y) * 128) + 2304) * ((x) + 3) / 4)), 256)

#endif /*_REGS_MFC_V12_H*/
+30 −0
Original line number Diff line number Diff line
@@ -790,6 +790,8 @@ static int s5p_mfc_open(struct file *file)
	INIT_LIST_HEAD(&ctx->dst_queue);
	ctx->src_queue_cnt = 0;
	ctx->dst_queue_cnt = 0;
	ctx->is_422 = 0;
	ctx->is_10bit = 0;
	/* Get context number */
	ctx->num = 0;
	while (dev->ctx[ctx->num]) {
@@ -1660,6 +1662,31 @@ static struct s5p_mfc_variant mfc_drvdata_v10 = {
	.fw_name[0]     = "s5p-mfc-v10.fw",
};

static struct s5p_mfc_buf_size_v6 mfc_buf_size_v12 = {
	.dev_ctx        = MFC_CTX_BUF_SIZE_V12,
	.h264_dec_ctx   = MFC_H264_DEC_CTX_BUF_SIZE_V12,
	.other_dec_ctx  = MFC_OTHER_DEC_CTX_BUF_SIZE_V12,
	.h264_enc_ctx   = MFC_H264_ENC_CTX_BUF_SIZE_V12,
	.hevc_enc_ctx   = MFC_HEVC_ENC_CTX_BUF_SIZE_V12,
	.other_enc_ctx  = MFC_OTHER_ENC_CTX_BUF_SIZE_V12,
};

static struct s5p_mfc_buf_size buf_size_v12 = {
	.fw     = MAX_FW_SIZE_V12,
	.cpb    = MAX_CPB_SIZE_V12,
	.priv   = &mfc_buf_size_v12,
};

static struct s5p_mfc_variant mfc_drvdata_v12 = {
	.version        = MFC_VERSION_V12,
	.version_bit    = MFC_V12_BIT,
	.port_num       = MFC_NUM_PORTS_V12,
	.buf_size       = &buf_size_v12,
	.fw_name[0]     = "s5p-mfc-v12.fw",
	.clk_names	= {"mfc"},
	.num_clocks	= 1,
};

static const struct of_device_id exynos_mfc_match[] = {
	{
		.compatible = "samsung,mfc-v5",
@@ -1682,6 +1709,9 @@ static const struct of_device_id exynos_mfc_match[] = {
	}, {
		.compatible = "samsung,mfc-v10",
		.data = &mfc_drvdata_v10,
	}, {
		.compatible = "tesla,fsd-mfc",
		.data = &mfc_drvdata_v12,
	},
	{},
};
+13 −4
Original line number Diff line number Diff line
@@ -19,7 +19,7 @@
#include <media/v4l2-ioctl.h>
#include <media/videobuf2-v4l2.h>
#include "regs-mfc.h"
#include "regs-mfc-v10.h"
#include "regs-mfc-v12.h"

#define S5P_MFC_NAME		"s5p-mfc"

@@ -621,6 +621,8 @@ struct s5p_mfc_codec_ops {
 *			v4l2 control framework
 * @ctrl_handler:	handler for v4l2 framework
 * @scratch_buf_size:	scratch buffer size
 * @is_10bit:		state to check 10bit support
 * @is_422:		state to check YUV422 10bit format
 */
struct s5p_mfc_ctx {
	struct s5p_mfc_dev *dev;
@@ -720,6 +722,8 @@ struct s5p_mfc_ctx {
	struct v4l2_ctrl *ctrls[MFC_MAX_CTRLS];
	struct v4l2_ctrl_handler ctrl_handler;
	size_t scratch_buf_size;
	int is_10bit;
	int is_422;
};

/*
@@ -775,6 +779,7 @@ void s5p_mfc_cleanup_queue(struct list_head *lh, struct vb2_queue *vq);
#define IS_MFCV7_PLUS(dev)	((dev)->variant->version >= 0x70)
#define IS_MFCV8_PLUS(dev)	((dev)->variant->version >= 0x80)
#define IS_MFCV10_PLUS(dev)	((dev)->variant->version >= 0xA0)
#define IS_MFCV12(dev)		((dev)->variant->version >= 0xC0)
#define FW_HAS_E_MIN_SCRATCH_BUF(dev) (IS_MFCV10_PLUS(dev))

#define MFC_V5_BIT	BIT(0)
@@ -782,11 +787,15 @@ void s5p_mfc_cleanup_queue(struct list_head *lh, struct vb2_queue *vq);
#define MFC_V7_BIT	BIT(2)
#define MFC_V8_BIT	BIT(3)
#define MFC_V10_BIT	BIT(5)
#define MFC_V12_BIT	BIT(7)

#define MFC_V5PLUS_BITS		(MFC_V5_BIT | MFC_V6_BIT | MFC_V7_BIT | \
					MFC_V8_BIT | MFC_V10_BIT)
					MFC_V8_BIT | MFC_V10_BIT | MFC_V12_BIT)
#define MFC_V6PLUS_BITS		(MFC_V6_BIT | MFC_V7_BIT | MFC_V8_BIT | \
					MFC_V10_BIT)
#define MFC_V7PLUS_BITS		(MFC_V7_BIT | MFC_V8_BIT | MFC_V10_BIT)
					MFC_V10_BIT | MFC_V12_BIT)
#define MFC_V7PLUS_BITS		(MFC_V7_BIT | MFC_V8_BIT | MFC_V10_BIT | \
					MFC_V12_BIT)

#define MFC_V10PLUS_BITS	(MFC_V10_BIT | MFC_V12_BIT)

#endif /* S5P_MFC_COMMON_H_ */
+1 −1
Original line number Diff line number Diff line
@@ -130,7 +130,7 @@ int s5p_mfc_reset(struct s5p_mfc_dev *dev)
			mfc_write(dev, 0, S5P_FIMV_REG_CLEAR_BEGIN_V6 + (i*4));

		/* check bus reset control before reset */
		if (dev->risc_on)
		if (dev->risc_on && !IS_MFCV12(dev))
			if (s5p_mfc_bus_reset(dev))
				return -EIO;
		/* Reset
+3 −3
Original line number Diff line number Diff line
@@ -146,7 +146,7 @@ static struct s5p_mfc_fmt formats[] = {
		.codec_mode	= S5P_FIMV_CODEC_HEVC_DEC,
		.type		= MFC_FMT_DEC,
		.num_planes	= 1,
		.versions	= MFC_V10_BIT,
		.versions	= MFC_V10PLUS_BITS,
		.flags		= V4L2_FMT_FLAG_DYN_RESOLUTION |
				  V4L2_FMT_FLAG_CONTINUOUS_BYTESTREAM,
	},
@@ -155,7 +155,7 @@ static struct s5p_mfc_fmt formats[] = {
		.codec_mode	= S5P_FIMV_CODEC_VP9_DEC,
		.type		= MFC_FMT_DEC,
		.num_planes	= 1,
		.versions	= MFC_V10_BIT,
		.versions	= MFC_V10PLUS_BITS,
		.flags		= V4L2_FMT_FLAG_DYN_RESOLUTION,
	},
};
@@ -355,7 +355,7 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
		pix_mp->width = ctx->buf_width;
		pix_mp->height = ctx->buf_height;
		pix_mp->field = V4L2_FIELD_NONE;
		pix_mp->num_planes = 2;
		pix_mp->num_planes = ctx->dst_fmt->num_planes;
		/* Set pixelformat to the format in which MFC
		   outputs the decoded frame */
		pix_mp->pixelformat = ctx->dst_fmt->fourcc;
Loading