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

Commit 8f532a7f authored by Arun Kumar K's avatar Arun Kumar K Committed by Mauro Carvalho Chehab
Browse files

[media] s5p-mfc: Add MFC variant data to device context



MFC variant data replaces various macros used in the driver
which will change in a different version of MFC hardware.
Also does a cleanup of MFC context structure and common files.

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 43a1ea1f
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -12,6 +12,9 @@
#ifndef _REGS_FIMV_H
#define _REGS_FIMV_H

#include <linux/kernel.h>
#include <linux/sizes.h>

#define S5P_FIMV_REG_SIZE	(S5P_FIMV_END_ADDR - S5P_FIMV_START_ADDR)
#define S5P_FIMV_REG_COUNT	((S5P_FIMV_END_ADDR - S5P_FIMV_START_ADDR) / 4)

@@ -414,5 +417,22 @@
#define S5P_FIMV_SHARED_EXTENDED_SAR		0x0078
#define S5P_FIMV_SHARED_H264_I_PERIOD		0x009C
#define S5P_FIMV_SHARED_RC_CONTROL_CONFIG	0x00A0
#define S5P_FIMV_SHARED_DISP_FRAME_TYPE_SHIFT	2

/* Offset used by the hardware to store addresses */
#define MFC_OFFSET_SHIFT	11

#define FIRMWARE_ALIGN		(128 * SZ_1K)	/* 128KB */
#define MFC_H264_CTX_BUF_SIZE	(600 * SZ_1K)	/* 600KB per H264 instance */
#define MFC_CTX_BUF_SIZE	(10 * SZ_1K)	/* 10KB per instance */
#define DESC_BUF_SIZE		(128 * SZ_1K)	/* 128KB for DESC buffer */
#define SHARED_BUF_SIZE		(8 * SZ_1K)	/* 8KB for shared buffer */

#define DEF_CPB_SIZE		(256 * SZ_1K)	/* 256KB */
#define MAX_CPB_SIZE		(4 * SZ_1M)	/* 4MB */
#define MAX_FW_SIZE		(384 * SZ_1K)

#define MFC_VERSION		0x51
#define MFC_NUM_PORTS		2

#endif /* _REGS_FIMV_H */
+41 −37
Original line number Diff line number Diff line
@@ -477,7 +477,6 @@ static void s5p_mfc_handle_seq_done(struct s5p_mfc_ctx *ctx,
				 unsigned int reason, unsigned int err)
{
	struct s5p_mfc_dev *dev;
	unsigned int guard_width, guard_height;

	if (ctx == NULL)
		return;
@@ -491,40 +490,8 @@ static void s5p_mfc_handle_seq_done(struct s5p_mfc_ctx *ctx,
		ctx->img_height = s5p_mfc_hw_call(dev->mfc_ops, get_img_height,
				dev);

		ctx->buf_width = ALIGN(ctx->img_width,
						S5P_FIMV_NV12MT_HALIGN);
		ctx->buf_height = ALIGN(ctx->img_height,
						S5P_FIMV_NV12MT_VALIGN);
		mfc_debug(2, "SEQ Done: Movie dimensions %dx%d, "
			"buffer dimensions: %dx%d\n", ctx->img_width,
				ctx->img_height, ctx->buf_width,
						ctx->buf_height);
		if (ctx->codec_mode == S5P_FIMV_CODEC_H264_DEC) {
			ctx->luma_size = ALIGN(ctx->buf_width *
				ctx->buf_height, S5P_FIMV_DEC_BUF_ALIGN);
			ctx->chroma_size = ALIGN(ctx->buf_width *
					 ALIGN((ctx->img_height >> 1),
					       S5P_FIMV_NV12MT_VALIGN),
					       S5P_FIMV_DEC_BUF_ALIGN);
			ctx->mv_size = ALIGN(ctx->buf_width *
					ALIGN((ctx->buf_height >> 2),
					S5P_FIMV_NV12MT_VALIGN),
					S5P_FIMV_DEC_BUF_ALIGN);
		} else {
			guard_width = ALIGN(ctx->img_width + 24,
					S5P_FIMV_NV12MT_HALIGN);
			guard_height = ALIGN(ctx->img_height + 16,
						S5P_FIMV_NV12MT_VALIGN);
			ctx->luma_size = ALIGN(guard_width *
				guard_height, S5P_FIMV_DEC_BUF_ALIGN);
			guard_width = ALIGN(ctx->img_width + 16,
						S5P_FIMV_NV12MT_HALIGN);
			guard_height = ALIGN((ctx->img_height >> 1) + 4,
						S5P_FIMV_NV12MT_VALIGN);
			ctx->chroma_size = ALIGN(guard_width *
				guard_height, S5P_FIMV_DEC_BUF_ALIGN);
			ctx->mv_size = 0;
		}
		s5p_mfc_hw_call(dev->mfc_ops, dec_calc_dpb_size, ctx);

		ctx->dpb_count = s5p_mfc_hw_call(dev->mfc_ops, get_dpb_count,
				dev);
		if (ctx->img_width == 0 || ctx->img_height == 0)
@@ -1066,6 +1033,9 @@ static int s5p_mfc_probe(struct platform_device *pdev)
		return -ENODEV;
	}

	dev->variant = (struct s5p_mfc_variant *)
		platform_get_device_id(pdev)->driver_data;

	ret = s5p_mfc_init_pm(dev);
	if (ret < 0) {
		dev_err(&pdev->dev, "failed to get mfc clock source\n");
@@ -1309,9 +1279,43 @@ static const struct dev_pm_ops s5p_mfc_pm_ops = {
			   NULL)
};

struct s5p_mfc_buf_size_v5 mfc_buf_size_v5 = {
	.h264_ctx	= MFC_H264_CTX_BUF_SIZE,
	.non_h264_ctx	= MFC_CTX_BUF_SIZE,
	.dsc		= DESC_BUF_SIZE,
	.shm		= SHARED_BUF_SIZE,
};

struct s5p_mfc_buf_size buf_size_v5 = {
	.fw	= MAX_FW_SIZE,
	.cpb	= MAX_CPB_SIZE,
	.priv	= &mfc_buf_size_v5,
};

struct s5p_mfc_buf_align mfc_buf_align_v5 = {
	.base = MFC_BASE_ALIGN_ORDER,
};

static struct s5p_mfc_variant mfc_drvdata_v5 = {
	.version	= MFC_VERSION,
	.port_num	= MFC_NUM_PORTS,
	.buf_size	= &buf_size_v5,
	.buf_align	= &mfc_buf_align_v5,
};

static struct platform_device_id mfc_driver_ids[] = {
	{
		.name = "s5p-mfc",
		.driver_data = (unsigned long)&mfc_drvdata_v5,
	},
	{},
};
MODULE_DEVICE_TABLE(platform, mfc_driver_ids);

static struct platform_driver s5p_mfc_driver = {
	.probe		= s5p_mfc_probe,
	.remove		= __devexit_p(s5p_mfc_remove),
	.id_table	= mfc_driver_ids,
	.driver	= {
		.name	= S5P_MFC_NAME,
		.owner	= THIS_MODULE,
+2 −2
Original line number Diff line number Diff line
@@ -113,8 +113,8 @@ int s5p_mfc_open_inst_cmd_v5(struct s5p_mfc_ctx *ctx)
		h2r_args.arg[0] = S5P_FIMV_CODEC_NONE;
	};
	h2r_args.arg[1] = 0; /* no crc & no pixelcache */
	h2r_args.arg[2] = ctx->ctx_ofs;
	h2r_args.arg[3] = ctx->ctx_size;
	h2r_args.arg[2] = ctx->ctx.ofs;
	h2r_args.arg[3] = ctx->ctx.size;
	ret = s5p_mfc_cmd_host2risc_v5(dev, S5P_FIMV_H2R_CMD_OPEN_INSTANCE,
								&h2r_args);
	if (ret) {
+52 −33
Original line number Diff line number Diff line
@@ -30,17 +30,6 @@
*  while mmaping */
#define DST_QUEUE_OFF_BASE      (TASK_SIZE / 2)

/* Offset used by the hardware to store addresses */
#define MFC_OFFSET_SHIFT	11

#define FIRMWARE_ALIGN		0x20000		/* 128KB */
#define MFC_H264_CTX_BUF_SIZE	0x96000		/* 600KB per H264 instance */
#define MFC_CTX_BUF_SIZE	0x2800		/* 10KB per instance */
#define DESC_BUF_SIZE		0x20000		/* 128KB for DESC buffer */
#define SHARED_BUF_SIZE		0x2000		/* 8KB for shared buffer */

#define DEF_CPB_SIZE		0x40000		/* 512KB */

#define MFC_BANK1_ALLOC_CTX	0
#define MFC_BANK2_ALLOC_CTX	1

@@ -210,6 +199,48 @@ struct s5p_mfc_pm {
	struct device	*device;
};

struct s5p_mfc_buf_size_v5 {
	unsigned int h264_ctx;
	unsigned int non_h264_ctx;
	unsigned int dsc;
	unsigned int shm;
};

struct s5p_mfc_buf_size {
	unsigned int fw;
	unsigned int cpb;
	void *priv;
};

struct s5p_mfc_buf_align {
	unsigned int base;
};

struct s5p_mfc_variant {
	unsigned int version;
	unsigned int port_num;
	struct s5p_mfc_buf_size *buf_size;
	struct s5p_mfc_buf_align *buf_align;
};

/**
 * struct s5p_mfc_priv_buf - represents internal used buffer
 * @alloc:		allocation-specific context for each buffer
 *			(videobuf2 allocator)
 * @ofs:		offset of each buffer, will be used for MFC
 * @virt:		kernel virtual address, only valid when the
 *			buffer accessed by driver
 * @dma:		DMA address, only valid when kernel DMA API used
 * @size:		size of the buffer
 */
struct s5p_mfc_priv_buf {
	void		*alloc;
	unsigned long	ofs;
	void		*virt;
	dma_addr_t	dma;
	size_t		size;
};

/**
 * struct s5p_mfc_dev - The struct containing driver internal parameters.
 *
@@ -224,6 +255,7 @@ struct s5p_mfc_pm {
 * @dec_ctrl_handler:	control framework handler for decoding
 * @enc_ctrl_handler:	control framework handler for encoding
 * @pm:			power management control
 * @variant:		MFC hardware variant information
 * @num_inst:		couter of active MFC instances
 * @irqlock:		lock for operations on videobuf2 queues
 * @condlock:		lock for changing/checking if a context is ready to be
@@ -262,6 +294,7 @@ struct s5p_mfc_dev {
	struct v4l2_ctrl_handler dec_ctrl_handler;
	struct v4l2_ctrl_handler enc_ctrl_handler;
	struct s5p_mfc_pm	pm;
	struct s5p_mfc_variant	*variant;
	int num_inst;
	spinlock_t irqlock;	/* lock when operating on videobuf2 queues */
	spinlock_t condlock;	/* lock when changing/checking if a context is
@@ -302,7 +335,6 @@ struct s5p_mfc_h264_enc_params {
	u8 max_ref_pic;
	u8 num_ref_pic_4p;
	int _8x8_transform;
	int rc_mb;
	int rc_mb_dark;
	int rc_mb_smooth;
	int rc_mb_static;
@@ -321,6 +353,7 @@ struct s5p_mfc_h264_enc_params {
	enum v4l2_mpeg_video_h264_level level_v4l2;
	int level;
	u16 cpb_size;
	int interlace;
};

/**
@@ -359,6 +392,7 @@ struct s5p_mfc_enc_params {
	u8 pad_cb;
	u8 pad_cr;
	int rc_frame;
	int rc_mb;
	u32 rc_bitrate;
	u16 rc_reaction_coeff;
	u16 vbv_size;
@@ -370,7 +404,6 @@ struct s5p_mfc_enc_params {
	u8 num_b_frame;
	u32 rc_framerate_num;
	u32 rc_framerate_denom;
	int interlace;

	union {
		struct s5p_mfc_h264_enc_params h264;
@@ -455,14 +488,9 @@ struct s5p_mfc_codec_ops {
 * @dpb_count:		count of the DPB buffers required by MFC hw
 * @total_dpb_count:	count of DPB buffers with additional buffers
 *			requested by the application
 * @ctx_buf:		handle to the memory associated with this context
 * @ctx_phys:		address of the memory associated with this context
 * @ctx_size:		size of the memory associated with this context
 * @desc_buf:		description buffer for decoding handle
 * @desc_phys:		description buffer for decoding address
 * @shm_alloc:		handle for the shared memory buffer
 * @shm:		virtual address for the shared memory buffer
 * @shm_ofs:		address offset for shared memory
 * @ctx:		context buffer information
 * @dsc:		descriptor buffer information
 * @shm:		shared memory buffer information
 * @enc_params:		encoding parameters for MFC
 * @enc_dst_buf_size:	size of the buffers for encoder output
 * @frame_type:		used to force the type of the next encoded frame
@@ -547,18 +575,9 @@ struct s5p_mfc_ctx {
	int total_dpb_count;

	/* Buffers */
	void *ctx_buf;
	size_t ctx_phys;
	size_t ctx_ofs;
	size_t ctx_size;

	void *desc_buf;
	size_t desc_phys;


	void *shm_alloc;
	void *shm;
	size_t shm_ofs;
	struct s5p_mfc_priv_buf ctx;
	struct s5p_mfc_priv_buf dsc;
	struct s5p_mfc_priv_buf shm;

	struct s5p_mfc_enc_params enc_params;

+6 −1
Original line number Diff line number Diff line
@@ -43,7 +43,12 @@ int s5p_mfc_alloc_and_load_firmware(struct s5p_mfc_dev *dev)
		mfc_err("Firmware is not present in the /lib/firmware directory nor compiled in kernel\n");
		return -EINVAL;
	}
	dev->fw_size = ALIGN(fw_blob->size, FIRMWARE_ALIGN);
	dev->fw_size = dev->variant->buf_size->fw;
	if (fw_blob->size > dev->fw_size) {
		mfc_err("MFC firmware is too big to be loaded\n");
		release_firmware(fw_blob);
		return -ENOMEM;
	}
	if (s5p_mfc_bitproc_buf) {
		mfc_err("Attempting to allocate firmware when it seems that it is already loaded\n");
		release_firmware(fw_blob);
Loading