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

Commit f96f3cfa authored by Jeongtae Park's avatar Jeongtae Park Committed by Mauro Carvalho Chehab
Browse files

[media] s5p-mfc: Update MFC v4l2 driver to support MFC6.x



Multi Format Codec 6.x is a hardware video coding acceleration
module present in new Exynos5 SoC series. It is capable of
handling several new video codecs for decoding and encoding.

Signed-off-by: default avatarJeongtae Park <jtp.park@samsung.com>
Signed-off-by: default avatarJanghyuck Kim <janghyuck.kim@samsung.com>
Signed-off-by: default avatarJaeryul Oh <jaeryul.oh@samsung.com>
Signed-off-by: default avatarNaveen Krishna Chatradhi <ch.naveen@samsung.com>
Signed-off-by: default avatarArun Kumar K <arun.kk@samsung.com>
Acked-by: default avatarKamil Debski <k.debski@samsung.com>
Signed-off-by: default avatarSylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 5b781e17
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -165,12 +165,12 @@ config VIDEO_SAMSUNG_S5P_JPEG
	  This is a v4l2 driver for Samsung S5P and EXYNOS4 JPEG codec

config VIDEO_SAMSUNG_S5P_MFC
	tristate "Samsung S5P MFC 5.1 Video Codec"
	tristate "Samsung S5P MFC Video Codec"
	depends on VIDEO_DEV && VIDEO_V4L2 && PLAT_S5P
	select VIDEOBUF2_DMA_CONTIG
	default n
	help
	    MFC 5.1 driver for V4L2.
	    MFC 5.1 and 6.x driver for V4L2

config VIDEO_MX2_EMMAPRP
	tristate "MX2 eMMa-PrP support"
+4 −4
Original line number Diff line number Diff line
obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MFC) := s5p-mfc.o
s5p-mfc-y += s5p_mfc.o s5p_mfc_intr.o s5p_mfc_opr.o
s5p-mfc-y += s5p_mfc.o s5p_mfc_intr.o
s5p-mfc-y += s5p_mfc_dec.o s5p_mfc_enc.o
s5p-mfc-y += s5p_mfc_ctrl.o s5p_mfc_cmd.o
s5p-mfc-y += s5p_mfc_pm.o
s5p-mfc-y += s5p_mfc_opr_v5.o s5p_mfc_cmd_v5.o
s5p-mfc-y += s5p_mfc_ctrl.o s5p_mfc_pm.o
s5p-mfc-y += s5p_mfc_opr.o s5p_mfc_opr_v5.o s5p_mfc_opr_v6.o
s5p-mfc-y += s5p_mfc_cmd.o s5p_mfc_cmd_v5.o s5p_mfc_cmd_v6.o
+21 −0
Original line number Diff line number Diff line
@@ -147,6 +147,7 @@
#define S5P_FIMV_ENC_PROFILE_H264_MAIN			0
#define S5P_FIMV_ENC_PROFILE_H264_HIGH			1
#define S5P_FIMV_ENC_PROFILE_H264_BASELINE		2
#define S5P_FIMV_ENC_PROFILE_H264_CONSTRAINED_BASELINE	3
#define S5P_FIMV_ENC_PROFILE_MPEG4_SIMPLE		0
#define S5P_FIMV_ENC_PROFILE_MPEG4_ADVANCED_SIMPLE	1
#define S5P_FIMV_ENC_PIC_STRUCT		0x083c /* picture field/frame flag */
@@ -216,6 +217,7 @@
#define S5P_FIMV_DEC_STATUS_RESOLUTION_MASK		(3<<4)
#define S5P_FIMV_DEC_STATUS_RESOLUTION_INC		(1<<4)
#define S5P_FIMV_DEC_STATUS_RESOLUTION_DEC		(2<<4)
#define S5P_FIMV_DEC_STATUS_RESOLUTION_SHIFT		4

/* Decode frame address */
#define S5P_FIMV_DECODE_Y_ADR			0x2024
@@ -380,6 +382,16 @@
#define S5P_FIMV_R2H_CMD_EDFU_INIT_RET		16
#define S5P_FIMV_R2H_CMD_ERR_RET		32

/* Dummy definition for MFCv6 compatibilty */
#define S5P_FIMV_CODEC_H264_MVC_DEC		-1
#define S5P_FIMV_R2H_CMD_FIELD_DONE_RET		-1
#define S5P_FIMV_MFC_RESET			-1
#define S5P_FIMV_RISC_ON			-1
#define S5P_FIMV_RISC_BASE_ADDRESS		-1
#define S5P_FIMV_CODEC_VP8_DEC			-1
#define S5P_FIMV_REG_CLEAR_BEGIN		0
#define S5P_FIMV_REG_CLEAR_COUNT		0

/* Error handling defines */
#define S5P_FIMV_ERR_WARNINGS_START		145
#define S5P_FIMV_ERR_DEC_MASK			0xFFFF
@@ -435,4 +447,13 @@
#define MFC_VERSION		0x51
#define MFC_NUM_PORTS		2

#define S5P_FIMV_SHARED_FRAME_PACK_SEI_AVAIL    0x16C
#define S5P_FIMV_SHARED_FRAME_PACK_ARRGMENT_ID  0x170
#define S5P_FIMV_SHARED_FRAME_PACK_SEI_INFO     0x174
#define S5P_FIMV_SHARED_FRAME_PACK_GRID_POS     0x178

/* Values for resolution change in display status */
#define S5P_FIMV_RES_INCREASE	1
#define S5P_FIMV_RES_DECREASE	2

#endif /* _REGS_FIMV_H */
+60 −4
Original line number Diff line number Diff line
@@ -330,12 +330,14 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx,

	dst_frame_status = s5p_mfc_hw_call(dev->mfc_ops, get_dspl_status, dev)
				& S5P_FIMV_DEC_STATUS_DECODING_STATUS_MASK;
	res_change = s5p_mfc_hw_call(dev->mfc_ops, get_dspl_status, dev)
				& S5P_FIMV_DEC_STATUS_RESOLUTION_MASK;
	res_change = (s5p_mfc_hw_call(dev->mfc_ops, get_dspl_status, dev)
				& S5P_FIMV_DEC_STATUS_RESOLUTION_MASK)
				>> S5P_FIMV_DEC_STATUS_RESOLUTION_SHIFT;
	mfc_debug(2, "Frame Status: %x\n", dst_frame_status);
	if (ctx->state == MFCINST_RES_CHANGE_INIT)
		ctx->state = MFCINST_RES_CHANGE_FLUSH;
	if (res_change) {
	if (res_change == S5P_FIMV_RES_INCREASE ||
		res_change == S5P_FIMV_RES_DECREASE) {
		ctx->state = MFCINST_RES_CHANGE_INIT;
		s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
		wake_up_ctx(ctx, reason, err);
@@ -494,10 +496,28 @@ static void s5p_mfc_handle_seq_done(struct s5p_mfc_ctx *ctx,

		ctx->dpb_count = s5p_mfc_hw_call(dev->mfc_ops, get_dpb_count,
				dev);
		ctx->mv_count = s5p_mfc_hw_call(dev->mfc_ops, get_mv_count,
				dev);
		if (ctx->img_width == 0 || ctx->img_height == 0)
			ctx->state = MFCINST_ERROR;
		else
			ctx->state = MFCINST_HEAD_PARSED;

		if ((ctx->codec_mode == S5P_MFC_CODEC_H264_DEC ||
			ctx->codec_mode == S5P_MFC_CODEC_H264_MVC_DEC) &&
				!list_empty(&ctx->src_queue)) {
			struct s5p_mfc_buf *src_buf;
			src_buf = list_entry(ctx->src_queue.next,
					struct s5p_mfc_buf, list);
			if (s5p_mfc_hw_call(dev->mfc_ops, get_consumed_stream,
						dev) <
					src_buf->b->v4l2_planes[0].bytesused)
				ctx->head_processed = 0;
			else
				ctx->head_processed = 1;
		} else {
			ctx->head_processed = 1;
		}
	}
	s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
	clear_work_bit(ctx);
@@ -526,7 +546,7 @@ static void s5p_mfc_handle_init_buffers(struct s5p_mfc_ctx *ctx,
	clear_work_bit(ctx);
	if (err == 0) {
		ctx->state = MFCINST_RUNNING;
		if (!ctx->dpb_flush_flag) {
		if (!ctx->dpb_flush_flag && ctx->head_processed) {
			spin_lock_irqsave(&dev->irqlock, flags);
			if (!list_empty(&ctx->src_queue)) {
				src_buf = list_entry(ctx->src_queue.next,
@@ -1071,6 +1091,7 @@ static int s5p_mfc_probe(struct platform_device *pdev)
		ret = -ENODEV;
		goto err_res;
	}

	dev->mem_dev_r = device_find_child(&dev->plat_dev->dev, "s5p-mfc-r",
					   match_child);
	if (!dev->mem_dev_r) {
@@ -1301,12 +1322,47 @@ static struct s5p_mfc_variant mfc_drvdata_v5 = {
	.port_num	= MFC_NUM_PORTS,
	.buf_size	= &buf_size_v5,
	.buf_align	= &mfc_buf_align_v5,
	.mclk_name	= "sclk_mfc",
	.fw_name	= "s5p-mfc.fw",
};

struct s5p_mfc_buf_size_v6 mfc_buf_size_v6 = {
	.dev_ctx	= MFC_CTX_BUF_SIZE_V6,
	.h264_dec_ctx	= MFC_H264_DEC_CTX_BUF_SIZE_V6,
	.other_dec_ctx	= MFC_OTHER_DEC_CTX_BUF_SIZE_V6,
	.h264_enc_ctx	= MFC_H264_ENC_CTX_BUF_SIZE_V6,
	.other_enc_ctx	= MFC_OTHER_ENC_CTX_BUF_SIZE_V6,
};

struct s5p_mfc_buf_size buf_size_v6 = {
	.fw	= MAX_FW_SIZE_V6,
	.cpb	= MAX_CPB_SIZE_V6,
	.priv	= &mfc_buf_size_v6,
};

struct s5p_mfc_buf_align mfc_buf_align_v6 = {
	.base = 0,
};

static struct s5p_mfc_variant mfc_drvdata_v6 = {
	.version	= MFC_VERSION_V6,
	.port_num	= MFC_NUM_PORTS_V6,
	.buf_size	= &buf_size_v6,
	.buf_align	= &mfc_buf_align_v6,
	.mclk_name      = "aclk_333",
	.fw_name        = "s5p-mfc-v6.fw",
};

static struct platform_device_id mfc_driver_ids[] = {
	{
		.name = "s5p-mfc",
		.driver_data = (unsigned long)&mfc_drvdata_v5,
	}, {
		.name = "s5p-mfc-v5",
		.driver_data = (unsigned long)&mfc_drvdata_v5,
	}, {
		.name = "s5p-mfc-v6",
		.driver_data = (unsigned long)&mfc_drvdata_v6,
	},
	{},
};
+6 −1
Original line number Diff line number Diff line
@@ -14,11 +14,16 @@
#include "s5p_mfc_common.h"
#include "s5p_mfc_debug.h"
#include "s5p_mfc_cmd_v5.h"
#include "s5p_mfc_cmd_v6.h"

static struct s5p_mfc_hw_cmds *s5p_mfc_cmds;

void s5p_mfc_init_hw_cmds(struct s5p_mfc_dev *dev)
{
	if (IS_MFCV6(dev))
		s5p_mfc_cmds = s5p_mfc_init_hw_cmds_v6();
	else
		s5p_mfc_cmds = s5p_mfc_init_hw_cmds_v5();

	dev->mfc_cmds = s5p_mfc_cmds;
}
Loading