lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250930040348.3702923-24-h.dewangan@samsung.com>
Date: Tue, 30 Sep 2025 09:33:42 +0530
From: Himanshu Dewangan <h.dewangan@...sung.com>
To: mchehab@...nel.org, robh@...nel.org, krzk+dt@...nel.org,
	conor+dt@...nel.org, sumit.semwal@...aro.org, christian.koenig@....com,
	alim.akhtar@...sung.com, manjun@...sung.com, nagaraju.s@...sung.com,
	ih0206.lee@...sung.com, jehyung.lee@...sung.com
Cc: linux-arm-kernel@...ts.infradead.org, linux-media@...r.kernel.org,
	devicetree@...r.kernel.org, linux-samsung-soc@...r.kernel.org,
	linux-kernel@...r.kernel.org, dri-devel@...ts.freedesktop.org,
	linaro-mm-sig@...ts.linaro.org, Himanshu Dewangan <h.dewangan@...sung.com>
Subject: [PATCH 23/29] media: mfc: Add encoder parameters, ROI & QoS support

From: Nagaraju Siddineni <nagaraju.s@...sung.com>

- Introduce a generic encoder‑parameter framework
  (slice mode, ASO order, QP config, timestamp delta).
- Expose full V4L2 encoder controls (frame tag, RC limits,
  level/profile, ROI, weighted prediction, hierarchical coding).
- Implemente ROI handling by building ROI registers from
  per‑buffer data.
- Update encoder resource manager: fixed core integration,
  excluded from migration/load‑balancing, ensured proper
  finalization per buffer type, and add encoder‑specific
  QoS step table.
- Disable bitrate‑driven load‑balancing for encoders;
  framerate updates now apply only to non‑encoder contexts.

Signed-off-by: Nagaraju Siddineni <nagaraju.s@...sung.com>
Signed-off-by: Himanshu Dewangan <h.dewangan@...sung.com>
---
 .../platform/samsung/exynos-mfc/Makefile      |   2 +-
 .../samsung/exynos-mfc/mfc_core_enc_param.c   | 848 ++++++++++++++++++
 .../samsung/exynos-mfc/mfc_core_enc_param.h   |  23 +
 .../samsung/exynos-mfc/mfc_ctx_ctrl.c         | 803 +++++++++++++++++
 .../platform/samsung/exynos-mfc/mfc_rm.c      |  89 +-
 .../platform/samsung/exynos-mfc/mfc_rm.h      |   2 +
 6 files changed, 1755 insertions(+), 12 deletions(-)
 create mode 100644 drivers/media/platform/samsung/exynos-mfc/mfc_core_enc_param.c
 create mode 100644 drivers/media/platform/samsung/exynos-mfc/mfc_core_enc_param.h

diff --git a/drivers/media/platform/samsung/exynos-mfc/Makefile b/drivers/media/platform/samsung/exynos-mfc/Makefile
index b6b312ae7f22..a257d5b0a576 100644
--- a/drivers/media/platform/samsung/exynos-mfc/Makefile
+++ b/drivers/media/platform/samsung/exynos-mfc/Makefile
@@ -13,7 +13,7 @@ exynos_mfc-y += mfc_core_hwlock.o mfc_core_intlock.o mfc_core_run.o
 exynos_mfc-y += mfc_core_pm.o
 exynos_mfc-y += mfc_core_sync.o mfc_core_sched_prio.o
 #Core HW access layer
-exynos_mfc-y += mfc_core_buf_ctrl.o mfc_core_cmd.o
+exynos_mfc-y += mfc_core_enc_param.o mfc_core_buf_ctrl.o mfc_core_cmd.o
 exynos_mfc-y += mfc_core_hw_reg_api.o mfc_core_reg_api.o
 #Plugin interface layer
 #Plugin control layer
diff --git a/drivers/media/platform/samsung/exynos-mfc/mfc_core_enc_param.c b/drivers/media/platform/samsung/exynos-mfc/mfc_core_enc_param.c
new file mode 100644
index 000000000000..9ff949df04ab
--- /dev/null
+++ b/drivers/media/platform/samsung/exynos-mfc/mfc_core_enc_param.c
@@ -0,0 +1,848 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
+ *              http://www.samsung.com
+ *
+ * mfc_core_enc_param.c file
+ *
+ * Nagaraju Siddineni, <nagaraju.s@...sung.com>
+ * Himanshu Dewangan, <h.dewangan@...sung.com>
+ */
+
+#include "mfc_core_enc_param.h"
+
+#include "mfc_core_reg_api.h"
+
+/* Definition */
+#define VBR_BIT_SAVE			20
+#define CBR_FIX_MAX			10
+#define CBR_I_LIMIT_WFD			6
+#define CBR_I_LIMIT_MAX			5
+
+static int mfc_transfer_to_rgb_format_ctrl[][2] = {
+	{ MFC_TRANSFER_RESERVED,	1},
+	{ MFC_TRANSFER_BT709,		1},
+	{ MFC_TRANSFER_UNSPECIFIED,	1},
+	{ MFC_TRANSFER_RESERVED,	1},
+	{ MFC_TRANSFER_GAMMA_22,	1},
+	{ MFC_TRANSFER_GAMMA_28,	1},
+	{ MFC_TRANSFER_SMPTE_170M,	0},
+	{ MFC_TRANSFER_SMPTE_240M,	1},
+	{ MFC_TRANSFER_LINEAR,		1},
+	{ MFC_TRANSFER_LOGARITHMIC,	1},
+	{ MFC_TRANSFER_LOGARITHMIC_S,	1},
+	{ MFC_TRANSFER_XvYCC,		1},
+	{ MFC_TRANSFER_BT1361,		1},
+	{ MFC_TRANSFER_SRGB,		1},
+	{ MFC_TRANSFER_BT2020_1,	1},
+	{ MFC_TRANSFER_BT2020_2,	1},
+	{ MFC_TRANSFER_ST2084,		1},
+	{ MFC_TRANSFER_ST428,		1},
+	{ MFC_TRANSFER_HLG,		1},
+};
+
+void mfc_core_set_slice_mode(struct mfc_core *core, struct mfc_ctx *ctx)
+{
+	struct mfc_enc *enc = ctx->enc_priv;
+
+	/* multi-slice control */
+	if (enc->slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES)
+		MFC_CORE_RAW_WRITEL((enc->slice_mode + 0x4), MFC_REG_E_MSLICE_MODE);
+	else if (enc->slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB_ROW)
+		MFC_CORE_RAW_WRITEL((enc->slice_mode - 0x2), MFC_REG_E_MSLICE_MODE);
+	else if (enc->slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_FIXED_BYTES)
+		MFC_CORE_RAW_WRITEL((enc->slice_mode + 0x3), MFC_REG_E_MSLICE_MODE);
+	else
+		MFC_CORE_RAW_WRITEL(enc->slice_mode, MFC_REG_E_MSLICE_MODE);
+
+	/* multi-slice MB number or bit size */
+	if (enc->slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB ||
+	    enc->slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB_ROW) {
+		MFC_CORE_RAW_WRITEL(enc->slice_size_mb, MFC_REG_E_MSLICE_SIZE_MB);
+	} else if (enc->slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES ||
+		   enc->slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_FIXED_BYTES) {
+		MFC_CORE_RAW_WRITEL(enc->slice_size_bits, MFC_REG_E_MSLICE_SIZE_BITS);
+	} else {
+		MFC_CORE_RAW_WRITEL(0x0, MFC_REG_E_MSLICE_SIZE_MB);
+		MFC_CORE_RAW_WRITEL(0x0, MFC_REG_E_MSLICE_SIZE_BITS);
+	}
+}
+
+void mfc_core_set_aso_slice_order_h264(struct mfc_core *core,
+				       struct mfc_ctx *ctx)
+{
+	struct mfc_enc *enc = ctx->enc_priv;
+	struct mfc_enc_params *p = &enc->params;
+	struct mfc_h264_enc_params *p_264 = &p->codec.h264;
+	int i;
+
+	if (p_264->aso_enable) {
+		for (i = 0; i < 8; i++)
+			MFC_CORE_RAW_WRITEL
+				(p_264->aso_slice_order[i],
+				 MFC_REG_E_H264_ASO_SLICE_ORDER_0 + i * 4);
+	}
+}
+
+void mfc_core_set_enc_config_qp(struct mfc_core *core, struct mfc_ctx *ctx)
+{
+	struct mfc_enc *enc = ctx->enc_priv;
+	struct mfc_enc_params *p = &enc->params;
+	unsigned int reg = 0;
+
+	if (!p->rc_frame && !p->rc_mb && p->dynamic_qp) {
+		reg = MFC_CORE_READL(MFC_REG_E_FIXED_PICTURE_QP);
+		reg &= ~(0xFF000000);
+		reg |= (enc->config_qp & 0xFF) << 24;
+		MFC_CORE_WRITEL(reg, MFC_REG_E_FIXED_PICTURE_QP);
+	}
+}
+
+void mfc_core_set_enc_ts_delta(struct mfc_core *core, struct mfc_ctx *ctx)
+{
+	struct mfc_enc *enc = ctx->enc_priv;
+	struct mfc_enc_params *p = &enc->params;
+	unsigned int reg = 0;
+	int ts_delta;
+
+	ts_delta = mfc_enc_get_ts_delta(ctx);
+
+	reg = MFC_CORE_READL(MFC_REG_E_TIME_STAMP_DELTA);
+	reg &= ~(0xFFFF);
+	reg |= (ts_delta & 0xFFFF);
+	MFC_CORE_WRITEL(reg, MFC_REG_E_TIME_STAMP_DELTA);
+	if (ctx->src_ts.ts_last_interval)
+		mfc_ctx_debug(3, "[DFR] fps %d -> %ld, delta: %d, reg: %#x\n",
+			      p->rc_framerate, USEC_PER_SEC / ctx->src_ts.ts_last_interval,
+			      ts_delta, reg);
+	else
+		mfc_ctx_debug(3, "[DFR] fps %d -> 0, delta: %d, reg: %#x\n",
+			      p->rc_framerate, ts_delta, reg);
+}
+
+static void __mfc_set_gop_size(struct mfc_core *core,
+			       struct mfc_ctx *ctx,
+			       int ctrl_mode)
+{
+	struct mfc_enc *enc = ctx->enc_priv;
+	struct mfc_enc_params *p = &enc->params;
+	unsigned int reg = 0;
+
+	if (ctrl_mode) {
+		p->i_frm_ctrl_mode = 1;
+		/*
+		 * gop_ctrl 1: gop_size means the I frame interval
+		 * gop_ctrl 0: gop_size means the number of P frames.
+		 */
+		if (p->gop_ctrl) {
+			p->i_frm_ctrl = p->gop_size;
+		} else {
+			p->i_frm_ctrl = p->gop_size * (p->num_b_frame + 1);
+			if (p->i_frm_ctrl >= 0x3FFFFFFF) {
+				mfc_ctx_info("I frame interval is bigger than max: %d\n",
+					     p->i_frm_ctrl);
+				p->i_frm_ctrl = 0x3FFFFFFF;
+			}
+		}
+	} else {
+		p->i_frm_ctrl_mode = 0;
+		p->i_frm_ctrl = p->gop_size;
+	}
+
+	mfc_ctx_debug(2, "I frame interval: %d, (P: %d, B: %d), ctrl mode: %d, gop ctrl: %d\n",
+		      p->i_frm_ctrl,
+		      p->gop_ctrl ? (p->gop_size / (p->num_b_frame + 1)) : p->gop_size,
+		      p->num_b_frame, p->i_frm_ctrl_mode, p->gop_ctrl);
+
+	/* pictype : IDR period, number of B */
+	reg = MFC_CORE_RAW_READL(MFC_REG_E_GOP_CONFIG);
+	mfc_clear_set_bits(reg, 0xFFFF, 0, p->i_frm_ctrl);
+	mfc_clear_set_bits(reg, 0x1, 19, p->i_frm_ctrl_mode);
+	/* if B frame is used, the performance falls by half */
+	mfc_clear_set_bits(reg, 0x3, 16, p->num_b_frame);
+	MFC_CORE_RAW_WRITEL(reg, MFC_REG_E_GOP_CONFIG);
+
+	reg = MFC_CORE_RAW_READL(MFC_REG_E_GOP_CONFIG2);
+	mfc_clear_set_bits(reg, 0x3FFF, 0, (p->i_frm_ctrl >> 16));
+	MFC_CORE_RAW_WRITEL(reg, MFC_REG_E_GOP_CONFIG2);
+}
+
+static void __mfc_set_default_params(struct mfc_core *core, struct mfc_ctx *ctx)
+{
+	struct mfc_dev *dev = ctx->dev;
+	int i;
+
+	mfc_ctx_debug(2, "Set default param -  enc_param_num: %d\n",
+		      dev->pdata->enc_param_num);
+	for (i = 0; i < dev->pdata->enc_param_num; i++) {
+		if (i >= MFC_MAX_DEFAULT_PARAM) {
+			mfc_ctx_err("enc_param_num(%d) is over max number(%d)\n",
+				    dev->pdata->enc_param_num,
+				    MFC_MAX_DEFAULT_PARAM);
+			break;
+		}
+		MFC_CORE_RAW_WRITEL
+			(dev->pdata->enc_param_val[i], dev->pdata->enc_param_addr[i]);
+		mfc_ctx_debug(2, "Set default param[%d] - addr:0x%x, val:0x%x\n",
+			      i, dev->pdata->enc_param_addr[i],
+			      dev->pdata->enc_param_val[i]);
+	}
+}
+
+static void __mfc_init_regs(struct mfc_core *core, struct mfc_ctx *ctx)
+{
+	/* Register initialization */
+	MFC_CORE_RAW_WRITEL(0x0, MFC_REG_E_FRAME_INSERTION);
+	MFC_CORE_RAW_WRITEL(0x0, MFC_REG_E_ROI_BUFFER_ADDR);
+	MFC_CORE_RAW_WRITEL(0x0, MFC_REG_E_PARAM_CHANGE);
+	MFC_CORE_RAW_WRITEL(0x0, MFC_REG_E_PICTURE_TAG);
+	MFC_CORE_RAW_WRITEL(0x0, MFC_REG_E_METADATA_BUFFER_ADDR);
+	MFC_CORE_RAW_WRITEL(0x0, MFC_REG_E_METADATA_BUFFER_SIZE);
+}
+
+static int __mfc_get_rgb_format_ctrl(struct mfc_ctx *ctx, struct mfc_enc_params *p)
+{
+	int ret = 0;
+
+	/*
+	 * User set color VUI information as below regardless of the standard.
+	 * ---------------------------------------------
+	 *	    VP9		 |	others
+	 * ----------------------|----------------------
+	 *   color space only	 | primaries, transfer
+	 * (primaries interface) |	,matrix
+	 * ---------------------------------------------
+	 * However, in case of RGB encoding, the F/W need to know
+	 * which to use RGB pixel format transform characteristic.
+	 * So, driver converts it based on the user's VUI information.
+	 * Return value
+	 *  0: ITU-R BT.601
+	 *  1: ITU-R BT.709
+	 * If Set to 3, use the coefficients of CSC formula determined by firmware
+	 * on COLOR_SPACE and COLOUR_PRIMARIES of E_VIDEO_SIGNAL_TYPE.
+	 *  3: Determined by firmware
+	 */
+
+	if (ctx->dev->pdata->enc_rgb_csc_by_fw) {
+		ret = 3;
+		mfc_ctx_debug(2, "[RGB] coefficients of CSC formula using VUI by F/W\n");
+	} else {
+		ret = mfc_transfer_to_rgb_format_ctrl[p->transfer_characteristics][1];
+		mfc_ctx_debug(2, "[RGB] transfer %d converts to RGB format ctrl %s\n",
+			      p->transfer_characteristics, ret ? "BT.709" : "BT.601");
+	}
+
+	return ret;
+}
+
+static void __mfc_set_video_signal_type(struct mfc_core *core, struct mfc_ctx *ctx)
+{
+	struct mfc_dev *dev = ctx->dev;
+	struct mfc_enc *enc = ctx->enc_priv;
+	struct mfc_enc_params *p = &enc->params;
+	unsigned int reg = 0;
+
+	if ((ctx->src_fmt->type & MFC_FMT_RGB) && !dev->pdata->enc_rgb_csc_by_fw) {
+		/* VIDEO_SIGNAL_TYPE_FLAG */
+		mfc_set_bits(reg, 0x1, 31, 0x1);
+		/* COLOUR_DESCRIPTION_PRESENT_FLAG */
+		mfc_set_bits(reg, 0x1, 24, 0x1);
+	} else if (MFC_FEATURE_SUPPORT(dev, dev->pdata->color_aspect_enc) &&
+		   p->check_color_range) {
+		/* VIDEO_SIGNAL_TYPE_FLAG */
+		mfc_set_bits(reg, 0x1, 31, 0x1);
+		/* COLOR_RANGE */
+		if (!(ctx->src_fmt->type & MFC_FMT_RGB))
+			mfc_set_bits(reg, 0x1, 25, p->color_range);
+
+		if (p->colour_primaries &&
+		    p->transfer_characteristics &&
+		    p->matrix_coefficients != 3) {
+			/* COLOUR_DESCRIPTION_PRESENT_FLAG */
+			mfc_set_bits(reg, 0x1, 24, 0x1);
+			/* COLOUR_PRIMARIES */
+			mfc_set_bits(reg, 0xFF, 16, p->colour_primaries);
+			/* TRANSFER_CHARACTERISTICS */
+			mfc_set_bits(reg, 0xFF, 8, p->transfer_characteristics);
+			/* MATRIX_COEFFICIENTS */
+			mfc_set_bits(reg, 0xFF, 0, p->matrix_coefficients);
+		}
+		mfc_ctx_debug(2, "[HDR] %s ENC Color aspect: range(%s), pri(%d), trans(%d), mat(%d)\n",
+			      "H264",
+			      p->color_range ? "Full" : "Limited", p->colour_primaries,
+			      p->transfer_characteristics, p->matrix_coefficients);
+	}
+	MFC_CORE_RAW_WRITEL(reg, MFC_REG_E_VIDEO_SIGNAL_TYPE);
+}
+
+static void __mfc_set_enc_params(struct mfc_core *core, struct mfc_ctx *ctx)
+{
+	struct mfc_dev *dev = ctx->dev;
+	struct mfc_enc *enc = ctx->enc_priv;
+	struct mfc_enc_params *p = &enc->params;
+	unsigned int reg = 0;
+	unsigned int fps = ctx->operating_framerate / 1000;
+
+	mfc_ctx_debug_enter();
+
+	__mfc_init_regs(core, ctx);
+	__mfc_set_default_params(core, ctx);
+
+	/* width */
+	MFC_CORE_RAW_WRITEL(ctx->crop_width, MFC_REG_E_CROPPED_FRAME_WIDTH);
+	/* height */
+	MFC_CORE_RAW_WRITEL(ctx->crop_height, MFC_REG_E_CROPPED_FRAME_HEIGHT);
+	/* cropped offset */
+	mfc_set_bits(reg, MFC_REG_E_FRAME_CROP_OFFSET_MASK,
+		     MFC_REG_E_FRAME_CROP_OFFSET_LEFT, ctx->crop_left);
+	mfc_set_bits(reg, MFC_REG_E_FRAME_CROP_OFFSET_MASK,
+		     MFC_REG_E_FRAME_CROP_OFFSET_TOP, ctx->crop_top);
+	MFC_CORE_RAW_WRITEL(reg, MFC_REG_E_FRAME_CROP_OFFSET);
+
+	/* multi-slice control */
+	/* multi-slice MB number or bit size */
+	enc->slice_mode = p->slice_mode;
+
+	if (p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB) {
+		enc->slice_size_mb = p->slice_mb;
+	} else if (p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES ||
+		   p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_FIXED_BYTES) {
+		enc->slice_size_bits = p->slice_bit;
+	} else if (p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB_ROW) {
+		enc->slice_size_mb = p->slice_mb_row * ((ctx->crop_width + 15) / 16);
+	} else {
+		enc->slice_size_mb = 0;
+		enc->slice_size_bits = 0;
+	}
+
+	mfc_core_set_slice_mode(core, ctx);
+
+	/* config qp */
+	enc->config_qp = p->config_qp;
+
+	/* cyclic intra refresh */
+	MFC_CORE_RAW_WRITEL(p->intra_refresh_mb, MFC_REG_E_IR_SIZE);
+
+	mfc_core_set_pixel_format(core, ctx, ctx->src_fmt->fourcc);
+
+	reg = MFC_CORE_RAW_READL(MFC_REG_E_ENC_OPTIONS);
+	/* frame skip mode */
+	mfc_clear_set_bits(reg, 0x3, 0, p->frame_skip_mode);
+	/* seq header ctrl */
+	mfc_clear_set_bits(reg, 0x1, 2, p->seq_hdr_mode);
+	/* cyclic intra refresh */
+	mfc_clear_bits(reg, 0x1, 4);
+	if (p->intra_refresh_mb)
+		mfc_set_bits(reg, 0x1, 4, 0x1);
+	/* disable seq header generation if OTF mode */
+	mfc_clear_bits(reg, 0x1, 6);
+
+	/* 'NON_REFERENCE_STORE_ENABLE' for debugging */
+	mfc_clear_bits(reg, 0x1, 9);
+
+	/* Predict motion search mode */
+	mfc_clear_set_bits(reg, 0x3, 22, p->mv_search_mode);
+
+	MFC_CORE_RAW_WRITEL(reg, MFC_REG_E_ENC_OPTIONS);
+
+	if (p->mv_hor_range) {
+		reg = MFC_CORE_RAW_READL(MFC_REG_E_MV_HOR_RANGE);
+		mfc_clear_set_bits(reg, 0x3fff, 0, p->mv_hor_range);
+		MFC_CORE_RAW_WRITEL(reg, MFC_REG_E_MV_HOR_RANGE);
+	}
+	if (p->mv_ver_range) {
+		reg = MFC_CORE_RAW_READL(MFC_REG_E_MV_VER_RANGE);
+		mfc_clear_set_bits(reg, 0x3fff, 0, p->mv_ver_range);
+		MFC_CORE_RAW_WRITEL(reg, MFC_REG_E_MV_VER_RANGE);
+	}
+
+	if (p->mv_search_mode == 2) {
+		reg = MFC_CORE_RAW_READL(MFC_REG_E_MV_HOR_RANGE);
+		mfc_clear_set_bits(reg, 0xff, 16, p->mv_hor_pos_l0);
+		mfc_clear_set_bits(reg, 0xff, 24, p->mv_hor_pos_l1);
+		MFC_CORE_RAW_WRITEL(reg, MFC_REG_E_MV_HOR_RANGE);
+
+		reg = MFC_CORE_RAW_READL(MFC_REG_E_MV_VER_RANGE);
+		mfc_clear_set_bits(reg, 0xff, 16, p->mv_ver_pos_l0);
+		mfc_clear_set_bits(reg, 0xff, 24, p->mv_ver_pos_l1);
+		MFC_CORE_RAW_WRITEL(reg, MFC_REG_E_MV_VER_RANGE);
+		mfc_ctx_debug(2, "MV search mode(%d), HOR (L0: %d, L1: %d), VER (L0: %d, L1: %d)\n",
+			      p->mv_search_mode,
+			      p->mv_hor_pos_l0, p->mv_hor_pos_l1,
+			      p->mv_ver_pos_l0, p->mv_ver_pos_l1);
+	}
+
+	if (ctx->src_fmt->type & MFC_FMT_RGB) {
+		reg = MFC_CORE_RAW_READL(MFC_REG_PIXEL_FORMAT);
+		mfc_clear_set_bits(reg, 0x1, 8, p->color_range);
+		mfc_clear_set_bits(reg, 0x3, 6, __mfc_get_rgb_format_ctrl(ctx, p));
+		mfc_ctx_debug(2, "[RGB] enc color_range %d, primaries %d, transfer %d\n",
+			      p->color_range, p->colour_primaries,
+			      p->transfer_characteristics);
+		MFC_CORE_RAW_WRITEL(reg, MFC_REG_PIXEL_FORMAT);
+	}
+
+	/* padding control & value */
+	MFC_CORE_RAW_WRITEL(0x0, MFC_REG_E_PADDING_CTRL);
+	if (p->pad) {
+		reg = 0;
+		/** enable */
+		mfc_set_bits(reg, 0x1, 31, 0x1);
+		/** cr value */
+		mfc_set_bits(reg, 0xFF, 16, p->pad_cr);
+		/** cb value */
+		mfc_set_bits(reg, 0xFF, 8, p->pad_cb);
+		/** y value */
+		mfc_set_bits(reg, 0xFF, 0, p->pad_luma);
+		MFC_CORE_RAW_WRITEL(reg, MFC_REG_E_PADDING_CTRL);
+	}
+
+	/* rate control config. */
+	reg = MFC_CORE_RAW_READL(MFC_REG_E_RC_CONFIG);
+	/* macroblock level rate control */
+	mfc_clear_set_bits(reg, 0x1, 8, p->rc_mb);
+	/* frame-level rate control */
+	mfc_clear_set_bits(reg, 0x1, 9, p->rc_frame);
+	/* drop control */
+	mfc_clear_set_bits(reg, 0x1, 10, p->drop_control);
+	if (MFC_FEATURE_SUPPORT(dev, dev->pdata->enc_ts_delta))
+		mfc_clear_set_bits(reg, 0x1, 20, 1);
+	MFC_CORE_RAW_WRITEL(reg, MFC_REG_E_RC_CONFIG);
+
+	/*
+	 * Delta value for framerate is timestamp(ms * 10) diff.
+	 * ex) 30fps: 333, 60fps: 166
+	 * Resolution unit is most sophisticated value
+	 * that can be determined within 16bit.
+	 * F/W calculates fps through resolution / delta.
+	 * ex) 10000 / 166 = 60fps
+	 */
+	p->rc_frame_delta = p->rc_framerate_res / p->rc_framerate;
+	reg = MFC_CORE_RAW_READL(MFC_REG_E_RC_FRAME_RATE);
+	mfc_clear_set_bits(reg, 0xFFFF, 16, p->rc_framerate_res);
+	mfc_clear_set_bits(reg, 0xFFFF, 0, p->rc_frame_delta);
+	MFC_CORE_RAW_WRITEL(reg, MFC_REG_E_RC_FRAME_RATE);
+
+	/* bit rate */
+	ctx->kbps = p->rc_bitrate / SZ_1K;
+	MFC_CORE_RAW_WRITEL(p->rc_bitrate, MFC_REG_E_RC_BIT_RATE);
+
+	if (MFC_FEATURE_SUPPORT(dev, dev->pdata->max_i_frame_size)) {
+		reg = MFC_CORE_RAW_READL(MFC_REG_E_RC_OPTIONS);
+		mfc_clear_set_bits(reg, 0xFFFF, 0, p->max_i_frame_size);
+		MFC_CORE_RAW_WRITEL(reg, MFC_REG_E_RC_OPTIONS);
+	}
+
+	reg = MFC_CORE_RAW_READL(MFC_REG_E_RC_MODE);
+	mfc_clear_bits(reg, 0x7, 0);
+	mfc_clear_bits(reg, 0x3, 4);
+	mfc_clear_bits(reg, 0xFF, 8);
+	if (p->rc_frame) {
+		if (p->rc_reaction_coeff <= CBR_I_LIMIT_MAX) {
+			mfc_set_bits(reg, 0x7, 0, MFC_REG_E_RC_CBR_I_LIMIT_VT);
+			/*
+			 * Ratio of intra for max frame size
+			 * is controlled when only CBR_I_LIMIT_VT mode.
+			 * And CBR_I_LIMIT_VT mode is valid for H.264, HEVC codec
+			 */
+			if (p->ratio_intra)
+				mfc_set_bits(reg, 0xFF, 8, p->ratio_intra);
+		} else if (p->rc_reaction_coeff <= CBR_FIX_MAX) {
+			if (MFC_FEATURE_SUPPORT(dev, dev->pdata->wfd_rc_mode) &&
+			    p->rc_reaction_coeff <= CBR_I_LIMIT_WFD) {
+				mfc_set_bits(reg, 0x7, 0, MFC_REG_E_RC_CBR_I_LIMIT_WFD);
+			} else {
+				mfc_set_bits(reg, 0x7, 0, MFC_REG_E_RC_CBR_FIX);
+			}
+		} else {
+			if (MFC_FEATURE_SUPPORT(dev, dev->pdata->wfd_rc_mode) &&
+			    p->rc_reaction_coeff <= VBR_BIT_SAVE) {
+				mfc_set_bits(reg, 0x7, 0, MFC_REG_E_RC_VBR_BS);
+			} else {
+				mfc_set_bits(reg, 0x7, 0, MFC_REG_E_RC_VBR);
+			}
+		}
+
+		if (p->rc_mb)
+			mfc_set_bits(reg, 0x3, 4, p->rc_pvc);
+	}
+
+	if (MFC_FEATURE_SUPPORT(dev, dev->pdata->min_quality_mode) && p->min_quality_mode) {
+		mfc_set_bits(reg, 0x1, 7, p->min_quality_mode);
+		mfc_ctx_debug(2, "MIN quality mode is enabled\n");
+	}
+
+	mfc_ctx_debug(3, "RC_MODE) rc coeff: %d, wfd_rc_mode: %d, rc_mode: %#x, max I size: %d\n",
+		      p->rc_reaction_coeff,
+		      MFC_FEATURE_SUPPORT(dev, dev->pdata->wfd_rc_mode),
+		      reg, p->max_i_frame_size);
+	MFC_CORE_RAW_WRITEL(reg, MFC_REG_E_RC_MODE);
+
+	/* high quality mode */
+	reg = MFC_CORE_RAW_READL(MFC_REG_E_HIGH_QUALITY_MODE);
+	if (p->wp_two_pass_enable) {
+		mfc_clear_set_bits(reg, 0x1, 0, p->wp_two_pass_enable);
+		mfc_ctx_debug(2, "WP two pass encoding is enabled\n");
+	}
+	if (p->adaptive_gop_enable) {
+		mfc_clear_set_bits(reg, 0x1, 4, p->adaptive_gop_enable);
+		mfc_ctx_debug(2, "Adaptive gop is enabled\n");
+	}
+	MFC_CORE_RAW_WRITEL(reg, MFC_REG_E_HIGH_QUALITY_MODE);
+
+	/* extended encoder ctrl */
+	/** vbv buffer size */
+	reg = MFC_CORE_RAW_READL(MFC_REG_E_VBV_BUFFER_SIZE);
+	mfc_clear_bits(reg, 0xFF, 0);
+	if (p->frame_skip_mode == V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT)
+		mfc_set_bits(reg, 0xFF, 0, p->vbv_buf_size);
+	MFC_CORE_RAW_WRITEL(reg, MFC_REG_E_VBV_BUFFER_SIZE);
+
+	/* Video signal type */
+	__mfc_set_video_signal_type(core, ctx);
+
+	/* Check performance decrease options */
+	if (!fps)
+		fps = p->rc_framerate;
+	if (IS_MFC_MAX_PERF(ctx, fps)) {
+		if (mfc_is_enc_bframe(ctx)) {
+			p->num_b_frame = 0;
+			if (IS_H264_ENC(ctx))
+				p->codec.h264.hier_qp_type =
+					V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P;
+			mfc_ctx_info("forcely can't be use B frame for 8K or 4K %d fps\n", fps);
+		}
+		if (p->num_refs_for_p > 1) {
+			p->num_refs_for_p = 1;
+			mfc_ctx_info("forcely use 1-ref frame for 8K or 4K %d fps\n", fps);
+		}
+	}
+
+	mfc_ctx_debug_leave();
+}
+
+static void __mfc_set_temporal_svc_h264(struct mfc_core *core,
+					struct mfc_ctx *ctx,
+					struct mfc_h264_enc_params *p_264)
+{
+	struct mfc_enc *enc = ctx->enc_priv;
+	struct mfc_enc_params *p = &enc->params;
+	unsigned int reg = 0, reg2 = 0;
+	int i;
+
+	reg = MFC_CORE_RAW_READL(MFC_REG_E_H264_OPTIONS_2);
+	/* pic_order_cnt_type = 0 for backward compatibilities */
+	mfc_clear_bits(reg, 0x3, 0);
+	/* Enable LTR */
+	mfc_clear_bits(reg, 0x1, 2);
+	if ((p_264->enable_ltr & 0x1) || p_264->num_of_ltr > 0)
+		mfc_set_bits(reg, 0x1, 2, 0x1);
+	/* Number of LTR */
+	mfc_clear_bits(reg, 0x3, 7);
+	if (p_264->num_of_ltr > 2)
+		mfc_set_bits(reg, 0x3, 7, (p_264->num_of_ltr - 2));
+	MFC_CORE_RAW_WRITEL(reg, MFC_REG_E_H264_OPTIONS_2);
+
+	/* Temporal SVC - qp type, layer number */
+	reg = MFC_CORE_RAW_READL(MFC_REG_E_NUM_T_LAYER);
+	mfc_clear_set_bits(reg, 0x1, 3, p_264->hier_qp_type);
+	mfc_clear_set_bits(reg, 0x7, 0, p_264->num_hier_layer);
+	mfc_clear_bits(reg, 0x7, 4);
+	if (p_264->hier_ref_type) {
+		mfc_set_bits(reg, 0x1, 7, 0x1);
+		mfc_set_bits(reg, 0x7, 4, p->num_hier_max_layer);
+	} else {
+		mfc_clear_bits(reg, 0x1, 7);
+		mfc_set_bits(reg, 0x7, 4, p_264->num_hier_layer);
+	}
+	mfc_clear_set_bits(reg, 0x1, 8, p->hier_bitrate_ctrl);
+	MFC_CORE_RAW_WRITEL(reg, MFC_REG_E_NUM_T_LAYER);
+	mfc_ctx_debug(3, "[HIERARCHICAL] hier_qp_enable %d, enable_ltr %d",
+		      p_264->hier_qp_enable, p_264->enable_ltr);
+	mfc_ctx_debug(3, "num_hier_layer %d, max_layer %d, hier_ref_type %d, NUM_T_LAYER 0x%x\n",
+		      p_264->num_hier_layer, p->num_hier_max_layer, p_264->hier_ref_type, reg);
+
+	/* QP & Bitrate for each layer */
+	for (i = 0; i < 7; i++) {
+		MFC_CORE_RAW_WRITEL
+			(p_264->hier_qp_layer[i],
+			 MFC_REG_E_HIERARCHICAL_QP_LAYER0 + i * 4);
+		/* If hier_bitrate_ctrl is set to 1, this is meaningless */
+		MFC_CORE_RAW_WRITEL
+			(p_264->hier_bit_layer[i],
+			 MFC_REG_E_HIERARCHICAL_BIT_RATE_LAYER0 + i * 4);
+		mfc_ctx_debug(3, "[HIERARCHICAL] layer[%d] QP: %#x, bitrate: %d(FW ctrl: %d)\n",
+			      i, p_264->hier_qp_layer[i],
+			      p_264->hier_bit_layer[i], p->hier_bitrate_ctrl);
+	}
+	if (p_264->set_priority) {
+		reg = 0;
+		reg2 = 0;
+		for (i = 0; i < (p_264->num_hier_layer & 0x7); i++) {
+			if (i <= 4)
+				mfc_set_bits(reg, 0x3F, (6 * i), (p_264->base_priority + i));
+			else
+				mfc_set_bits(reg2, 0x3F, (6 * (i - 5)), (p_264->base_priority + i));
+		}
+		MFC_CORE_RAW_WRITEL(reg, MFC_REG_E_H264_HD_SVC_EXTENSION_0);
+		MFC_CORE_RAW_WRITEL(reg2, MFC_REG_E_H264_HD_SVC_EXTENSION_1);
+		mfc_ctx_debug(3, "[HIERARCHICAL] priority EXTENSION0: %#x, EXTENSION1: %#x\n",
+			      reg, reg2);
+	}
+}
+
+static void __mfc_set_fmo_slice_map_h264(struct mfc_core *core,
+					 struct mfc_ctx *ctx,
+					 struct mfc_h264_enc_params *p_264)
+{
+	int i;
+
+	if (p_264->fmo_enable) {
+		switch (p_264->fmo_slice_map_type) {
+		case V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_INTERLEAVED_SLICES:
+			if (p_264->fmo_slice_num_grp > 4)
+				p_264->fmo_slice_num_grp = 4;
+			for (i = 0; i < (p_264->fmo_slice_num_grp & 0xF); i++)
+				MFC_CORE_RAW_WRITEL
+					(p_264->fmo_run_length[i] - 1,
+					 MFC_REG_E_H264_FMO_RUN_LENGTH_MINUS1_0 + i * 4);
+			break;
+		case V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_SCATTERED_SLICES:
+			if (p_264->fmo_slice_num_grp > 4)
+				p_264->fmo_slice_num_grp = 4;
+			break;
+		case V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_RASTER_SCAN:
+		case V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_WIPE_SCAN:
+			if (p_264->fmo_slice_num_grp > 2)
+				p_264->fmo_slice_num_grp = 2;
+			MFC_CORE_RAW_WRITEL
+				(p_264->fmo_sg_dir & 0x1, MFC_REG_E_H264_FMO_SLICE_GRP_CHANGE_DIR);
+			/* the valid range is 0 ~ number of macroblocks -1 */
+			MFC_CORE_RAW_WRITEL(p_264->fmo_sg_rate,
+					    MFC_REG_E_H264_FMO_SLICE_GRP_CHANGE_RATE_MINUS1);
+			break;
+		default:
+			mfc_ctx_err("Unsupported map type for FMO: %d\n",
+				    p_264->fmo_slice_map_type);
+			p_264->fmo_slice_map_type = 0;
+			p_264->fmo_slice_num_grp = 1;
+			break;
+		}
+
+		MFC_CORE_RAW_WRITEL
+			(p_264->fmo_slice_map_type, MFC_REG_E_H264_FMO_SLICE_GRP_MAP_TYPE);
+		MFC_CORE_RAW_WRITEL
+			(p_264->fmo_slice_num_grp - 1, MFC_REG_E_H264_FMO_NUM_SLICE_GRP_MINUS1);
+	} else {
+		MFC_CORE_RAW_WRITEL(0, MFC_REG_E_H264_FMO_NUM_SLICE_GRP_MINUS1);
+	}
+}
+
+static void __mfc_set_enc_params_h264(struct mfc_core *core,
+				      struct mfc_ctx *ctx)
+{
+	struct mfc_dev *dev = ctx->dev;
+	struct mfc_enc *enc = ctx->enc_priv;
+	struct mfc_enc_params *p = &enc->params;
+	struct mfc_h264_enc_params *p_264 = &p->codec.h264;
+	unsigned int mb = 0;
+	unsigned int reg = 0;
+
+	mfc_ctx_debug_enter();
+
+	p->rc_framerate_res = FRAME_RATE_RESOLUTION;
+	__mfc_set_enc_params(core, ctx);
+
+	if (p_264->num_hier_layer & 0x7) {
+		/* set gop_size without i_frm_ctrl mode */
+		__mfc_set_gop_size(core, ctx, 0);
+	} else {
+		/* set gop_size with i_frm_ctrl mode */
+		__mfc_set_gop_size(core, ctx, 1);
+	}
+
+	mb = WIDTH_MB((ctx)->crop_width) * HEIGHT_MB((ctx)->crop_height);
+	/* Level 6.0 case */
+	if (IS_LV60_MB(mb)) {
+		if (p_264->level < 60)
+			mfc_ctx_info("This resolution(mb: %d) recommends level6.0\n", mb);
+		/* In case of profile is baseline or constrained baseline */
+		if (p_264->profile == 0x0 || p_264->profile == 0x3)
+			mfc_ctx_info("This resolution(mb: %d) recommends high profile\n", mb);
+		if (!dev->pdata->support_8K_cavlc && p_264->entropy_mode != 0x1) {
+			mfc_ctx_info("Set Entropy mode CABAC\n");
+			p_264->entropy_mode = 1;
+		}
+	}
+
+	/* Level 5.1 case */
+	if (IS_LV51_MB(mb)) {
+		if (p_264->level < 51)
+			mfc_ctx_info("This resolution(mb: %d) recommends level5.1\n", mb);
+		/* In case of profile is baseline or constrained baseline */
+		if (p_264->profile == 0x0 || p_264->profile == 0x3)
+			mfc_ctx_info("This resolution(mb: %d) recommends high profile\n", mb);
+	}
+
+	/* profile & level */
+	reg = 0;
+	/** level */
+	mfc_clear_set_bits(reg, 0xFF, 8, p_264->level);
+	/** profile - 0 ~ 3 */
+	mfc_clear_set_bits(reg, 0x3F, 0, p_264->profile);
+	MFC_CORE_RAW_WRITEL(reg, MFC_REG_E_PICTURE_PROFILE);
+
+	reg = MFC_CORE_RAW_READL(MFC_REG_E_H264_OPTIONS);
+	/* entropy coding mode */
+	mfc_clear_set_bits(reg, 0x1, 0, p_264->entropy_mode);
+	/* loop filter ctrl */
+	mfc_clear_set_bits(reg, 0x3, 1, p_264->loop_filter_mode);
+	/* interlace */
+	mfc_clear_set_bits(reg, 0x1, 3, p_264->interlace);
+	/* intra picture period for H.264 open GOP */
+	mfc_clear_set_bits(reg, 0x1, 4, p_264->open_gop);
+	/* extended encoder ctrl */
+	mfc_clear_set_bits(reg, 0x1, 5, p_264->ar_vui);
+	/* ASO enable */
+	mfc_clear_set_bits(reg, 0x1, 6, p_264->aso_enable);
+	/* if num_refs_for_p is 2, the performance falls by half */
+	mfc_clear_set_bits(reg, 0x1, 7, (p->num_refs_for_p - 1));
+	/* Temporal SVC - hier qp enable */
+	mfc_clear_set_bits(reg, 0x1, 8, p_264->hier_qp_enable);
+	/* Weighted Prediction enable */
+	mfc_clear_set_bits(reg, 0x3, 9, p->weighted_enable);
+	if (p->weighted_enable)
+		mfc_ctx_debug(2, "WP mode is %d\n", p->weighted_enable);
+	/* 8x8 transform enable [12]: INTER_8x8_TRANS_ENABLE */
+	mfc_clear_set_bits(reg, 0x1, 12, p_264->_8x8_transform);
+	/* 8x8 transform enable [13]: INTRA_8x8_TRANS_ENABLE */
+	mfc_clear_set_bits(reg, 0x1, 13, p_264->_8x8_transform);
+	/* 'CONSTRAINED_INTRA_PRED_ENABLE' is disable */
+	mfc_clear_bits(reg, 0x1, 14);
+	/* sps pps control */
+	mfc_clear_set_bits(reg, 0x1, 29, p_264->prepend_sps_pps_to_idr);
+	/* VUI parameter disable */
+	mfc_clear_set_bits(reg, 0x1, 30, p_264->vui_enable);
+	/* Timing info */
+	mfc_set_bits(reg, 0x1, 31, p->timing_info_enable);
+	MFC_CORE_RAW_WRITEL(reg, MFC_REG_E_H264_OPTIONS);
+
+	/* cropped height */
+	if (p_264->interlace)
+		MFC_CORE_RAW_WRITEL(ctx->crop_height >> 1, MFC_REG_E_CROPPED_FRAME_HEIGHT);
+
+	/* loopfilter alpha offset */
+	reg = MFC_CORE_RAW_READL(MFC_REG_E_H264_LF_ALPHA_OFFSET);
+	mfc_clear_set_bits(reg, 0x1F, 0, p_264->loop_filter_alpha);
+	MFC_CORE_RAW_WRITEL(reg, MFC_REG_E_H264_LF_ALPHA_OFFSET);
+
+	/* loopfilter beta offset */
+	reg = MFC_CORE_RAW_READL(MFC_REG_E_H264_LF_BETA_OFFSET);
+	mfc_clear_set_bits(reg, 0x1F, 0, p_264->loop_filter_beta);
+	MFC_CORE_RAW_WRITEL(reg, MFC_REG_E_H264_LF_BETA_OFFSET);
+
+	/* rate control config. */
+	reg = MFC_CORE_RAW_READL(MFC_REG_E_RC_CONFIG);
+	/** frame QP */
+	mfc_clear_set_bits(reg, 0xFF, 0, p_264->rc_frame_qp);
+	mfc_clear_bits(reg, 0x1, 11);
+	if (!p->rc_frame && !p->rc_mb && p->dynamic_qp)
+		mfc_set_bits(reg, 0x1, 11, 0x1);
+	MFC_CORE_RAW_WRITEL(reg, MFC_REG_E_RC_CONFIG);
+
+	/* max & min value of QP for I frame */
+	reg = MFC_CORE_RAW_READL(MFC_REG_E_RC_QP_BOUND);
+	/** max I frame QP */
+	mfc_clear_set_bits(reg, 0xFF, 8, p_264->rc_max_qp);
+	/** min I frame QP */
+	mfc_clear_set_bits(reg, 0xFF, 0, p_264->rc_min_qp);
+	MFC_CORE_RAW_WRITEL(reg, MFC_REG_E_RC_QP_BOUND);
+
+	/* max & min value of QP for P/B frame */
+	reg = MFC_CORE_RAW_READL(MFC_REG_E_RC_QP_BOUND_PB);
+	/** max B frame QP */
+	mfc_clear_set_bits(reg, 0xFF, 24, p_264->rc_max_qp_b);
+	/** min B frame QP */
+	mfc_clear_set_bits(reg, 0xFF, 16, p_264->rc_min_qp_b);
+	/** max P frame QP */
+	mfc_clear_set_bits(reg, 0xFF, 8, p_264->rc_max_qp_p);
+	/** min P frame QP */
+	mfc_clear_set_bits(reg, 0xFF, 0, p_264->rc_min_qp_p);
+	MFC_CORE_RAW_WRITEL(reg, MFC_REG_E_RC_QP_BOUND_PB);
+
+	reg = MFC_CORE_RAW_READL(MFC_REG_E_FIXED_PICTURE_QP);
+	mfc_clear_set_bits(reg, 0xFF, 24, p->config_qp);
+	mfc_clear_set_bits(reg, 0xFF, 16, p_264->rc_b_frame_qp);
+	mfc_clear_set_bits(reg, 0xFF, 8, p_264->rc_p_frame_qp);
+	mfc_clear_set_bits(reg, 0xFF, 0, p_264->rc_frame_qp);
+	MFC_CORE_RAW_WRITEL(reg, MFC_REG_E_FIXED_PICTURE_QP);
+
+	/* chroma QP offset */
+	reg = MFC_CORE_RAW_READL(MFC_REG_E_H264_CHROMA_QP_OFFSET);
+	mfc_clear_set_bits(reg, 0x1F, 5, p->chroma_qp_offset_cr);
+	mfc_clear_set_bits(reg, 0x1F, 0, p->chroma_qp_offset_cb);
+	MFC_CORE_RAW_WRITEL(reg, MFC_REG_E_H264_CHROMA_QP_OFFSET);
+
+	MFC_CORE_RAW_WRITEL(0x0, MFC_REG_E_ASPECT_RATIO);
+	MFC_CORE_RAW_WRITEL(0x0, MFC_REG_E_EXTENDED_SAR);
+	if (p_264->ar_vui) {
+		/* aspect ration IDC */
+		reg = 0;
+		mfc_set_bits(reg, 0xFF, 0, p_264->ar_vui_idc);
+		MFC_CORE_RAW_WRITEL(reg, MFC_REG_E_ASPECT_RATIO);
+		if (p_264->ar_vui_idc == 0xFF) {
+			/* sample  AR info. */
+			reg = 0;
+			mfc_set_bits(reg, 0xFFFF, 16, p_264->ext_sar_width);
+			mfc_set_bits(reg, 0xFFFF, 0, p_264->ext_sar_height);
+			MFC_CORE_RAW_WRITEL(reg, MFC_REG_E_EXTENDED_SAR);
+		}
+	}
+	/* intra picture period for H.264 open GOP, value */
+	reg = MFC_CORE_RAW_READL(MFC_REG_E_H264_REFRESH_PERIOD);
+	mfc_clear_bits(reg, 0xFFFF, 0);
+	if (p_264->open_gop)
+		mfc_set_bits(reg, 0xFFFF, 0, p_264->open_gop_size);
+	MFC_CORE_RAW_WRITEL(reg, MFC_REG_E_H264_REFRESH_PERIOD);
+
+	/* Temporal SVC */
+	__mfc_set_temporal_svc_h264(core, ctx, p_264);
+
+	/* set frame pack sei generation */
+	if (p_264->sei_gen_enable) {
+		/* frame packing enable */
+		reg = MFC_CORE_RAW_READL(MFC_REG_E_H264_OPTIONS);
+		mfc_set_bits(reg, 0x1, 25, 0x1);
+		MFC_CORE_RAW_WRITEL(reg, MFC_REG_E_H264_OPTIONS);
+
+		/* set current frame0 flag & arrangement type */
+		reg = 0;
+		/** current frame0 flag */
+		mfc_set_bits(reg, 0x1, 2, p_264->sei_fp_curr_frame_0);
+		/** arrangement type */
+		mfc_set_bits(reg, 0x3, 0, (p_264->sei_fp_arrangement_type - 3));
+		MFC_CORE_RAW_WRITEL(reg, MFC_REG_E_H264_FRAME_PACKING_SEI_INFO);
+	}
+
+	__mfc_set_fmo_slice_map_h264(core, ctx, p_264);
+
+	mfc_ctx_debug_leave();
+}
+
+int mfc_core_set_enc_params(struct mfc_core *core, struct mfc_ctx *ctx)
+{
+	if (IS_H264_ENC(ctx)) {
+		__mfc_set_enc_params_h264(core, ctx);
+	} else {
+		mfc_ctx_err("Unknown codec for encoding (%x)\n", ctx->codec_mode);
+		return -EINVAL;
+	}
+
+	mfc_ctx_debug(5, "RC) Bitrate: %d / framerate: %#x / config %#x / mode %#x\n",
+		      MFC_CORE_RAW_READL(MFC_REG_E_RC_BIT_RATE),
+		      MFC_CORE_RAW_READL(MFC_REG_E_RC_FRAME_RATE),
+		      MFC_CORE_RAW_READL(MFC_REG_E_RC_CONFIG),
+		      MFC_CORE_RAW_READL(MFC_REG_E_RC_MODE));
+
+	return 0;
+}
diff --git a/drivers/media/platform/samsung/exynos-mfc/mfc_core_enc_param.h b/drivers/media/platform/samsung/exynos-mfc/mfc_core_enc_param.h
new file mode 100644
index 000000000000..ce15ae29abba
--- /dev/null
+++ b/drivers/media/platform/samsung/exynos-mfc/mfc_core_enc_param.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
+ *              http://www.samsung.com
+ *
+ * mfc_enc_param.h file
+ *
+ * Nagaraju Siddineni, <nagaraju.s@...sung.com>
+ * Himanshu Dewangan, <h.dewangan@...sung.com>
+ */
+
+#ifndef __MFC_ENC_PARAM_H
+#define __MFC_ENC_PARAM_H __FILE__
+
+#include "base/mfc_common.h"
+
+void mfc_core_set_slice_mode(struct mfc_core *core, struct mfc_ctx *ctx);
+void mfc_core_set_aso_slice_order_h264(struct mfc_core *core,
+				       struct mfc_ctx *ctx);
+void mfc_core_set_enc_config_qp(struct mfc_core *core, struct mfc_ctx *ctx);
+void mfc_core_set_enc_ts_delta(struct mfc_core *core, struct mfc_ctx *ctx);
+int mfc_core_set_enc_params(struct mfc_core *core, struct mfc_ctx *ctx);
+#endif /* __MFC_ENC_PARAM_H */
diff --git a/drivers/media/platform/samsung/exynos-mfc/mfc_ctx_ctrl.c b/drivers/media/platform/samsung/exynos-mfc/mfc_ctx_ctrl.c
index 8846230f1e20..4580aa3498cc 100644
--- a/drivers/media/platform/samsung/exynos-mfc/mfc_ctx_ctrl.c
+++ b/drivers/media/platform/samsung/exynos-mfc/mfc_ctx_ctrl.c
@@ -379,6 +379,768 @@ static struct mfc_ctrl_cfg mfc_dec_ctrl_list[] = {
 
 #define NUM_DEC_CTRL_CFGS ARRAY_SIZE(mfc_dec_ctrl_list)
 
+static struct mfc_ctrl_cfg mfc_enc_ctrl_list[] = {
+	{	/* set frame tag */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_PICTURE_TAG,
+		.mask = 0xFFFFFFFF,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_NONE,
+		.flag_addr = 0,
+		.flag_shft = 0,
+	},
+	{	/* get frame tag */
+		.type = MFC_CTRL_TYPE_GET_DST,
+		.id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG,
+		.is_volatile = 0,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_RET_PICTURE_TAG,
+		.mask = 0xFFFFFFFF,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_NONE,
+		.flag_addr = 0,
+		.flag_shft = 0,
+	},
+	{	/* encoded y physical addr */
+		.type = MFC_CTRL_TYPE_GET_DST,
+		.id = V4L2_CID_MPEG_MFC51_VIDEO_LUMA_ADDR,
+		.is_volatile = 0,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_ENCODED_SOURCE_FIRST_ADDR,
+		.mask = 0xFFFFFFFF,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_NONE,
+		.flag_addr = 0,
+		.flag_shft = 0,
+	},
+	{	/* encoded c physical addr */
+		.type = MFC_CTRL_TYPE_GET_DST,
+		.id = V4L2_CID_MPEG_MFC51_VIDEO_CHROMA_ADDR,
+		.is_volatile = 0,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_ENCODED_SOURCE_SECOND_ADDR,
+		.mask = 0xFFFFFFFF,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_NONE,
+		.flag_addr = 0,
+		.flag_shft = 0,
+	},
+	{	/* I, not coded frame insertion */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_FRAME_INSERTION,
+		.mask = 0x3,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_NONE,
+		.flag_addr = 0,
+		.flag_shft = 0,
+	},
+	{	/* I period change */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_MFC51_VIDEO_I_PERIOD_CH,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_GOP_CONFIG,
+		.mask = 0xFFFF,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = MFC_REG_E_PARAM_CHANGE,
+		.flag_shft = 0,
+	},
+	{	/* frame rate change */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_RATE_CH,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_RC_FRAME_RATE,
+		.mask = 0x0000FFFF,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = MFC_REG_E_PARAM_CHANGE,
+		.flag_shft = 1,
+	},
+	{	/* bit rate change */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_MFC51_VIDEO_BIT_RATE_CH,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_RC_BIT_RATE,
+		.mask = 0xFFFFFFFF,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = MFC_REG_E_PARAM_CHANGE,
+		.flag_shft = 2,
+	},
+	{	/* frame status (in slice or not) */
+		.type = MFC_CTRL_TYPE_GET_DST,
+		.id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_STATUS,
+		.is_volatile = 0,
+		.mode = MFC_CTRL_MODE_NONE,
+		.addr = 0,
+		.mask = 0xFFFFFFFF,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_NONE,
+		.flag_addr = 0,
+		.flag_shft = 0,
+	},
+	{	/* H.264 I frame QP Max change */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_RC_QP_BOUND,
+		.mask = 0xFF,
+		.shft = 8,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = MFC_REG_E_PARAM_CHANGE,
+		.flag_shft = 4,
+	},
+	{	/* H.264 I frame QP Min change */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_RC_QP_BOUND,
+		.mask = 0xFF,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = MFC_REG_E_PARAM_CHANGE,
+		.flag_shft = 4,
+	},
+	{	/* H.263 I frame QP Max change */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_H263_MAX_QP,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_RC_QP_BOUND,
+		.mask = 0xFF,
+		.shft = 8,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = MFC_REG_E_PARAM_CHANGE,
+		.flag_shft = 4,
+	},
+	{	/* H.263 I frame QP Min change */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_H263_MIN_QP,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_RC_QP_BOUND,
+		.mask = 0xFF,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = MFC_REG_E_PARAM_CHANGE,
+		.flag_shft = 4,
+	},
+	{	/* MPEG4 I frame QP Max change */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_RC_QP_BOUND,
+		.mask = 0xFF,
+		.shft = 8,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = MFC_REG_E_PARAM_CHANGE,
+		.flag_shft = 4,
+	},
+	{	/* MPEG4 I frame QP Min change */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_RC_QP_BOUND,
+		.mask = 0xFF,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = MFC_REG_E_PARAM_CHANGE,
+		.flag_shft = 4,
+	},
+	{	/* VP8 I frame QP Max change */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_VP8_MAX_QP,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_RC_QP_BOUND,
+		.mask = 0xFF,
+		.shft = 8,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = MFC_REG_E_PARAM_CHANGE,
+		.flag_shft = 4,
+	},
+	{	/* VP8 I frame QP Min change */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_VP8_MIN_QP,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_RC_QP_BOUND,
+		.mask = 0xFF,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = MFC_REG_E_PARAM_CHANGE,
+		.flag_shft = 4,
+	},
+	{	/* VP9 I frame QP Max change */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_VP9_MAX_QP,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_RC_QP_BOUND,
+		.mask = 0xFF,
+		.shft = 8,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = MFC_REG_E_PARAM_CHANGE,
+		.flag_shft = 4,
+	},
+	{	/* VP9 I frame QP Min change */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_VP9_MIN_QP,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_RC_QP_BOUND,
+		.mask = 0xFF,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = MFC_REG_E_PARAM_CHANGE,
+		.flag_shft = 4,
+	},
+	{	/* HEVC I frame QP Max change */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_RC_QP_BOUND,
+		.mask = 0xFF,
+		.shft = 8,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = MFC_REG_E_PARAM_CHANGE,
+		.flag_shft = 4,
+	},
+	{	/* HEVC I frame QP Min change */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_RC_QP_BOUND,
+		.mask = 0xFF,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = MFC_REG_E_PARAM_CHANGE,
+		.flag_shft = 4,
+	},
+	{	/* H.264 P frame QP Max change */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP_P,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_RC_QP_BOUND_PB,
+		.mask = 0xFF,
+		.shft = 8,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = MFC_REG_E_PARAM_CHANGE,
+		.flag_shft = 4,
+	},
+	{	/* H.264 P frame QP Min change */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP_P,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_RC_QP_BOUND_PB,
+		.mask = 0xFF,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = MFC_REG_E_PARAM_CHANGE,
+		.flag_shft = 4,
+	},
+	{	/* H.263 P frame QP Max change */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_H263_MAX_QP_P,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_RC_QP_BOUND_PB,
+		.mask = 0xFF,
+		.shft = 8,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = MFC_REG_E_PARAM_CHANGE,
+		.flag_shft = 4,
+	},
+	{	/* H.263 P frame QP Min change */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_H263_MIN_QP_P,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_RC_QP_BOUND_PB,
+		.mask = 0xFF,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = MFC_REG_E_PARAM_CHANGE,
+		.flag_shft = 4,
+	},
+	{	/* MPEG4 P frame QP Max change */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP_P,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_RC_QP_BOUND_PB,
+		.mask = 0xFF,
+		.shft = 8,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = MFC_REG_E_PARAM_CHANGE,
+		.flag_shft = 4,
+	},
+	{	/* MPEG4 P frame QP Min change */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP_P,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_RC_QP_BOUND_PB,
+		.mask = 0xFF,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = MFC_REG_E_PARAM_CHANGE,
+		.flag_shft = 4,
+	},
+	{	/* VP8 P frame QP Max change */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_VP8_MAX_QP_P,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_RC_QP_BOUND_PB,
+		.mask = 0xFF,
+		.shft = 8,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = MFC_REG_E_PARAM_CHANGE,
+		.flag_shft = 4,
+	},
+	{	/* VP8 P frame QP Min change */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_VP8_MIN_QP_P,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_RC_QP_BOUND_PB,
+		.mask = 0xFF,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = MFC_REG_E_PARAM_CHANGE,
+		.flag_shft = 4,
+	},
+	{	/* VP9 P frame QP Max change */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_VP9_MAX_QP_P,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_RC_QP_BOUND_PB,
+		.mask = 0xFF,
+		.shft = 8,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = MFC_REG_E_PARAM_CHANGE,
+		.flag_shft = 4,
+	},
+	{	/* VP9 P frame QP Min change */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_VP9_MIN_QP_P,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_RC_QP_BOUND_PB,
+		.mask = 0xFF,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = MFC_REG_E_PARAM_CHANGE,
+		.flag_shft = 4,
+	},
+	{	/* HEVC P frame QP Max change */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP_P,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_RC_QP_BOUND_PB,
+		.mask = 0xFF,
+		.shft = 8,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = MFC_REG_E_PARAM_CHANGE,
+		.flag_shft = 4,
+	},
+	{	/* HEVC P frame QP Min change */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP_P,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_RC_QP_BOUND_PB,
+		.mask = 0xFF,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = MFC_REG_E_PARAM_CHANGE,
+		.flag_shft = 4,
+	},
+	{	/* H.264 B frame QP Max change */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP_B,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_RC_QP_BOUND_PB,
+		.mask = 0xFF,
+		.shft = 24,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = MFC_REG_E_PARAM_CHANGE,
+		.flag_shft = 4,
+	},
+	{	/* H.264 B frame QP Min change */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP_B,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_RC_QP_BOUND_PB,
+		.mask = 0xFF,
+		.shft = 16,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = MFC_REG_E_PARAM_CHANGE,
+		.flag_shft = 4,
+	},
+	{	/* MPEG4 B frame QP Max change */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP_B,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_RC_QP_BOUND_PB,
+		.mask = 0xFF,
+		.shft = 24,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = MFC_REG_E_PARAM_CHANGE,
+		.flag_shft = 4,
+	},
+	{	/* MPEG4 B frame QP Min change */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP_B,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_RC_QP_BOUND_PB,
+		.mask = 0xFF,
+		.shft = 16,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = MFC_REG_E_PARAM_CHANGE,
+		.flag_shft = 4,
+	},
+	{	/* HEVC B frame QP Max change */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP_B,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_RC_QP_BOUND_PB,
+		.mask = 0xFF,
+		.shft = 24,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = MFC_REG_E_PARAM_CHANGE,
+		.flag_shft = 4,
+	},
+	{	/* HEVC B frame QP Min change */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP_B,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_RC_QP_BOUND_PB,
+		.mask = 0xFF,
+		.shft = 16,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = MFC_REG_E_PARAM_CHANGE,
+		.flag_shft = 4,
+	},
+	{	/* H.264 Dynamic Temporal Layer & bitrate change */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_CH,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_HIERARCHICAL_BIT_RATE_LAYER0,
+		.mask = 0xFFFFFFFF,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = MFC_REG_E_PARAM_CHANGE,
+		.flag_shft = 10,
+	},
+	{	/* HEVC Dynamic Temporal Layer & bitrate change */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_CH,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_HIERARCHICAL_BIT_RATE_LAYER0,
+		.mask = 0xFFFFFFFF,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = MFC_REG_E_PARAM_CHANGE,
+		.flag_shft = 10,
+	},
+	{	/* VP8 Dynamic Temporal Layer change */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_CH,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_HIERARCHICAL_BIT_RATE_LAYER0,
+		.mask = 0xFFFFFFFF,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = MFC_REG_E_PARAM_CHANGE,
+		.flag_shft = 10,
+	},
+	{	/* VP9 Dynamic Temporal Layer change */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_CH,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_HIERARCHICAL_BIT_RATE_LAYER0,
+		.mask = 0xFFFFFFFF,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = MFC_REG_E_PARAM_CHANGE,
+		.flag_shft = 10,
+	},
+	{	/* set level */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_PICTURE_PROFILE,
+		.mask = 0x000000FF,
+		.shft = 8,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = MFC_REG_E_PARAM_CHANGE,
+		.flag_shft = 5,
+	},
+	{	/* set profile */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_PICTURE_PROFILE,
+		.mask = 0x0000000F,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = MFC_REG_E_PARAM_CHANGE,
+		.flag_shft = 5,
+	},
+	{	/* set store LTR */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_MFC_H264_MARK_LTR,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_H264_NAL_CONTROL,
+		.mask = 0x00000003,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_NONE,
+		.flag_addr = 0,
+		.flag_shft = 0,
+	},
+	{	/* set use LTR */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_MFC_H264_USE_LTR,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_H264_NAL_CONTROL,
+		.mask = 0x00000003,
+		.shft = 2,
+		.flag_mode = MFC_CTRL_MODE_NONE,
+		.flag_addr = 0,
+		.flag_shft = 0,
+	},
+	{	/* set base layer priority */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_MFC_H264_BASE_PRIORITY,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_H264_HD_SVC_EXTENSION_0,
+		.mask = 0x0000003F,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = MFC_REG_E_PARAM_CHANGE,
+		.flag_shft = 12,
+	},
+	{	/* set QP per each frame */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_MFC_CONFIG_QP,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_FIXED_PICTURE_QP,
+		.mask = 0x000000FF,
+		.shft = 24,
+		.flag_mode = MFC_CTRL_MODE_NONE,
+		.flag_addr = 0,
+		.flag_shft = 0,
+	},
+	{	/* Region-Of-Interest control */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_ROI_CONTROL,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_RC_ROI_CTRL,
+		.mask = 0xFFFFFFFF,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_NONE,
+		.flag_addr = 0,
+		.flag_shft = 0,
+	},
+	{	/* set YSUM for weighted prediction */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_YSUM,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_WEIGHT_FOR_WEIGHTED_PREDICTION,
+		.mask = 0xFFFFFFFF,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_NONE,
+		.flag_shft = 0,
+	},
+	{	/* set base layer priority */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_RATIO_OF_INTRA,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_RC_MODE,
+		.mask = 0x000000FF,
+		.shft = 8,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = MFC_REG_E_PARAM_CHANGE,
+		.flag_shft = 13,
+	},
+	{	/* sync the timestamp for drop control */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_DROP_CONTROL,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_RC_FRAME_RATE,
+		.mask = 0x0000FFFF,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_NONE,
+		.flag_addr = 0,
+		.flag_shft = 0,
+	},
+	{	/* average QP of current frame */
+		.type = MFC_CTRL_TYPE_GET_DST,
+		.id = V4L2_CID_MPEG_VIDEO_AVERAGE_QP,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_NAL_DONE_INFO,
+		.mask = 0x000000FF,
+		.shft = 12,
+		.flag_mode = MFC_CTRL_MODE_NONE,
+		.flag_addr = 0,
+		.flag_shft = 0,
+	},
+	{	/* HOR range position of current frame */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_MV_HOR_POSITION_L0,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_MV_HOR_RANGE,
+		.mask = 0x000000FF,
+		.shft = 16,
+		.flag_mode = MFC_CTRL_MODE_NONE,
+		.flag_addr = 0,
+		.flag_shft = 0,
+	},
+	{	/* HOR range position of current frame */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_MV_HOR_POSITION_L1,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_MV_HOR_RANGE,
+		.mask = 0x000000FF,
+		.shft = 24,
+		.flag_mode = MFC_CTRL_MODE_NONE,
+		.flag_addr = 0,
+		.flag_shft = 0,
+	},
+	{	/* VER range position of current frame */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_MV_VER_POSITION_L0,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_MV_VER_RANGE,
+		.mask = 0x000000FF,
+		.shft = 16,
+		.flag_mode = MFC_CTRL_MODE_NONE,
+		.flag_addr = 0,
+		.flag_shft = 0,
+	},
+	{	/* VER range position of current frame */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_MV_VER_POSITION_L1,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_MV_VER_RANGE,
+		.mask = 0x000000FF,
+		.shft = 24,
+		.flag_mode = MFC_CTRL_MODE_NONE,
+		.flag_addr = 0,
+		.flag_shft = 0,
+	},
+	{	/* Max I frame size */
+		.type = MFC_CTRL_TYPE_SET_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_MAX_IFRAME_SIZE,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_RC_OPTIONS,
+		.mask = 0xFFFF,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = MFC_REG_E_PARAM_CHANGE,
+		.flag_shft = 20,
+	},
+	{	/* The number of skip MB */
+		.type = MFC_CTRL_TYPE_GET_DST,
+		.id = V4L2_CID_MPEG_VIDEO_SUM_SKIP_MB,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_SUM_SKIP_MB,
+		.mask = 0xFFFFFFFF,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_NONE,
+		.flag_addr = 0,
+		.flag_shft = 0,
+	},
+	{	/* The number of intra MB */
+		.type = MFC_CTRL_TYPE_GET_DST,
+		.id = V4L2_CID_MPEG_VIDEO_SUM_INTRA_MB,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_SUM_INTRA_MB,
+		.mask = 0xFFFFFFFF,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_NONE,
+		.flag_addr = 0,
+		.flag_shft = 0,
+	},
+	{	/* The number of intra MB */
+		.type = MFC_CTRL_TYPE_GET_DST,
+		.id = V4L2_CID_MPEG_VIDEO_SUM_ZERO_MV_MB,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = MFC_REG_E_SUM_ZERO_MV_MB,
+		.mask = 0xFFFFFFFF,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_NONE,
+		.flag_addr = 0,
+		.flag_shft = 0,
+	},
+	{	/* buffer additional information */
+		.type = MFC_CTRL_TYPE_SRC,
+		.id = V4L2_CID_MPEG_VIDEO_SRC_BUF_FLAG,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_NONE,
+		.flag_mode = MFC_CTRL_MODE_NONE,
+	},
+	{	/* buffer additional information */
+		.type = MFC_CTRL_TYPE_DST,
+		.id = V4L2_CID_MPEG_VIDEO_DST_BUF_FLAG,
+		.is_volatile = 1,
+		.mode = MFC_CTRL_MODE_NONE,
+		.flag_mode = MFC_CTRL_MODE_NONE,
+	}
+};
+
+#define NUM_ENC_CTRL_CFGS ARRAY_SIZE(mfc_enc_ctrl_list)
+
 static void mfc_ctrl_cleanup_ctx(struct mfc_ctx *ctx)
 {
 	struct mfc_ctx_ctrl *ctx_ctrl;
@@ -426,6 +1188,8 @@ static int mfc_ctrl_init_ctx(struct mfc_ctx *ctx)
 {
 	if (ctx->type == MFCINST_DECODER)
 		return __mfc_ctrl_init_ctx(ctx, mfc_dec_ctrl_list, NUM_DEC_CTRL_CFGS);
+	else if (ctx->type == MFCINST_ENCODER)
+		return __mfc_ctrl_init_ctx(ctx, mfc_enc_ctrl_list, NUM_ENC_CTRL_CFGS);
 
 	mfc_ctx_err("[CTRLS] invalid type %d\n", ctx->type);
 	return -EINVAL;
@@ -560,11 +1324,47 @@ static int mfc_ctrl_init_buf(struct mfc_ctx *ctx, enum mfc_ctrl_type type, unsig
 {
 	if (ctx->type == MFCINST_DECODER)
 		return __mfc_ctrl_init_buf(ctx, mfc_dec_ctrl_list, type, index, NUM_DEC_CTRL_CFGS);
+	else if (ctx->type == MFCINST_ENCODER)
+		return __mfc_ctrl_init_buf(ctx, mfc_enc_ctrl_list, type, index, NUM_ENC_CTRL_CFGS);
 
 	mfc_ctx_err("[CTRLS] invalid type %d\n", ctx->type);
 	return -EINVAL;
 }
 
+static void __mfc_enc_set_roi(struct mfc_ctx *ctx, struct mfc_buf_ctrl *buf_ctrl)
+{
+	struct mfc_enc *enc = ctx->enc_priv;
+	int index = 0;
+	unsigned int reg = 0;
+
+	index = enc->roi_index;
+	if (enc->roi_info[index].enable) {
+		enc->roi_index = (index + 1) % MFC_MAX_EXTRA_BUF;
+		reg |= enc->roi_info[index].enable;
+		reg &= ~(0xFF << 8);
+		reg |= (enc->roi_info[index].lower_qp << 8);
+		reg &= ~(0xFFFF << 16);
+		reg |= (enc->roi_info[index].upper_qp << 16);
+		/*
+		 * 2bit ROI
+		 * - All codec type: upper_qp and lower_qp is valid
+		 * 8bit ROI
+		 * - H.264/HEVC/MPEG4: upper_qp and lower_qp is invalid
+		 * - VP8/VP9: upper_qp and lower_qp is valid
+		 */
+		mfc_ctx_debug(3, "[ROI] buffer[%d] en %d QP lower %d upper %d reg %#x\n",
+			      index, enc->roi_info[index].enable,
+			      enc->roi_info[index].lower_qp,
+			      enc->roi_info[index].upper_qp,
+			      reg);
+	} else {
+		mfc_ctx_debug(3, "[ROI] buffer[%d] is not enabled\n", index);
+	}
+
+	buf_ctrl->val = reg;
+	buf_ctrl->old_val2 = index;
+}
+
 static void mfc_ctrl_to_buf(struct mfc_ctx *ctx, struct list_head *head)
 {
 	struct mfc_ctx_ctrl *ctx_ctrl;
@@ -588,6 +1388,9 @@ static void mfc_ctrl_to_buf(struct mfc_ctx *ctx, struct list_head *head)
 
 				ctx_ctrl->set.has_new = 0;
 
+				if (buf_ctrl->id == V4L2_CID_MPEG_VIDEO_ROI_CONTROL)
+					__mfc_enc_set_roi(ctx, buf_ctrl);
+
 				break;
 			}
 		}
diff --git a/drivers/media/platform/samsung/exynos-mfc/mfc_rm.c b/drivers/media/platform/samsung/exynos-mfc/mfc_rm.c
index a7db47e58589..4083d76640fd 100644
--- a/drivers/media/platform/samsung/exynos-mfc/mfc_rm.c
+++ b/drivers/media/platform/samsung/exynos-mfc/mfc_rm.c
@@ -685,12 +685,22 @@ static void __mfc_rm_migrate_all_to_one_core(struct mfc_dev *dev)
 			spin_unlock_irqrestore(&dev->ctx_list_lock, flags);
 			return;
 		}
-
-		if (tmp_ctx->op_core_type == MFC_OP_CORE_FIXED_0)
-			op_core_fixed0++;
-		else if (tmp_ctx->op_core_type == MFC_OP_CORE_FIXED_1)
-			op_core_fixed1++;
-
+		/* op core type */
+		if (tmp_ctx->type == MFCINST_ENCODER) {
+			/*
+			 * instance of encoder cannot be moved to another core.
+			 * So, treat main core as the fixed core.
+			 */
+			if (tmp_ctx->op_core_num[MFC_CORE_MAIN] == MFC_DEC_DEFAULT_CORE)
+				op_core_fixed0++;
+			else if (tmp_ctx->op_core_num[MFC_CORE_MAIN] == MFC_SURPLUS_CORE)
+				op_core_fixed1++;
+		} else {
+			if (tmp_ctx->op_core_type == MFC_OP_CORE_FIXED_0)
+				op_core_fixed0++;
+			else if (tmp_ctx->op_core_type == MFC_OP_CORE_FIXED_1)
+				op_core_fixed1++;
+		}
 		/* op main core */
 		if (tmp_ctx->op_core_num[MFC_CORE_MAIN] == MFC_DEC_DEFAULT_CORE)
 			op_core0++;
@@ -1344,6 +1354,14 @@ void mfc_rm_load_balancing(struct mfc_ctx *ctx, int load_add)
 			__mfc_rm_update_core_load(tmp_ctx, 0, 1);
 			continue;
 		}
+
+		if (tmp_ctx->type == MFCINST_ENCODER) {
+			mfc_ctx_debug(3, "[RMLB] encoder ctx[%d] can't be moved\n",
+				      tmp_ctx->num);
+			__mfc_rm_update_core_load(tmp_ctx, 0, IS_MULTI_MODE(tmp_ctx));
+			continue;
+		}
+
 		core_num = __mfc_rm_get_core_num_by_load(dev, tmp_ctx, MFC_DEC_DEFAULT_CORE);
 		if (IS_SWITCH_SINGLE_MODE(tmp_ctx) ||
 		    core_num == tmp_ctx->op_core_num[MFC_CORE_MAIN]) {
@@ -1440,8 +1458,10 @@ int mfc_rm_instance_init(struct mfc_dev *dev, struct mfc_ctx *ctx)
 	 * QoS portion data should be allocated
 	 * only once per instance after maincore is determined.
 	 */
-	num_qos_steps = core->core_pdata->num_default_qos_steps;
-
+	if (ctx->type == MFCINST_ENCODER)
+		num_qos_steps = core->core_pdata->num_encoder_qos_steps;
+	else
+		num_qos_steps = core->core_pdata->num_default_qos_steps;
 	ctx->mfc_qos_portion = vmalloc(sizeof(unsigned int) * num_qos_steps);
 	if (!ctx->mfc_qos_portion)
 		ret = -ENOMEM;
@@ -1916,6 +1936,46 @@ void mfc_rm_instance_dec_stop(struct mfc_dev *dev, struct mfc_ctx *ctx,
 	mfc_ctx_debug_leave();
 }
 
+void mfc_rm_instance_enc_stop(struct mfc_dev *dev, struct mfc_ctx *ctx,
+			      unsigned int type)
+{
+	struct mfc_core *core;
+	struct mfc_core *subcore;
+
+	mfc_ctx_debug_enter();
+
+	mfc_get_corelock_ctx(ctx);
+
+	core = mfc_get_main_core(dev, ctx);
+	if (!core) {
+		mfc_ctx_err("[RM] There is no main core\n");
+		mfc_release_corelock_ctx(ctx);
+		return;
+	}
+
+	if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+		core->core_ops->instance_q_flush(core, ctx);
+	} else if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+		if (IS_SWITCH_SINGLE_MODE(ctx)) {
+			subcore = mfc_get_sub_core(dev, ctx);
+			if (!subcore) {
+				mfc_ctx_err("[RM] There is no sub core for switch single\n");
+				goto err_subcore_stop;
+			}
+
+			core->core_ops->instance_finishing(core, ctx);
+			subcore->core_ops->instance_finishing(subcore, ctx);
+		} else {
+			core->core_ops->instance_finishing(core, ctx);
+		}
+	}
+
+err_subcore_stop:
+	mfc_release_corelock_ctx(ctx);
+
+	mfc_ctx_debug_leave();
+}
+
 int mfc_rm_subcore_seq_start(struct mfc_dev *dev, struct mfc_ctx *ctx)
 {
 	struct mfc_core *core;
@@ -2284,6 +2344,8 @@ void mfc_rm_qos_control(struct mfc_ctx *ctx, enum mfc_qos_control qos_control)
 			mfc_rm_load_balancing(ctx, MFC_RM_LOAD_ADD);
 
 		ctx->update_bitrate = false;
+		if (ctx->type == MFCINST_ENCODER)
+			ctx->update_framerate = false;
 		break;
 	default:
 		mfc_ctx_err("[RM] not supported QoS control type: %#x\n",
@@ -2528,9 +2590,14 @@ void mfc_rm_update_real_time(struct mfc_ctx *ctx)
 		}
 	} else {
 		if (new_prio == 0) {
-			/* In case of google photo app, user sets priority 0 */
-			new_prio = 1;
-			new_rt = MFC_RT_LOW;
+			if (ctx->type == MFCINST_ENCODER &&
+			    ctx->enc_priv->params.rc_framerate) {
+				new_rt = MFC_RT;
+			} else {
+				/* In case of google photo app, user sets priority 0 */
+				new_prio = 1;
+				new_rt = MFC_RT_LOW;
+			}
 		} else if (new_prio >= 1) {
 			new_rt = MFC_NON_RT;
 		} else {
diff --git a/drivers/media/platform/samsung/exynos-mfc/mfc_rm.h b/drivers/media/platform/samsung/exynos-mfc/mfc_rm.h
index b73ef905718a..39ec63392db3 100644
--- a/drivers/media/platform/samsung/exynos-mfc/mfc_rm.h
+++ b/drivers/media/platform/samsung/exynos-mfc/mfc_rm.h
@@ -94,6 +94,8 @@ int mfc_rm_instance_deinit(struct mfc_dev *dev, struct mfc_ctx *ctx);
 int mfc_rm_instance_open(struct mfc_dev *dev, struct mfc_ctx *ctx);
 void mfc_rm_instance_dec_stop(struct mfc_dev *dev, struct mfc_ctx *ctx,
 			      unsigned int type);
+void mfc_rm_instance_enc_stop(struct mfc_dev *dev, struct mfc_ctx *ctx,
+			      unsigned int type);
 int mfc_rm_subcore_seq_start(struct mfc_dev *dev, struct mfc_ctx *ctx);
 int mfc_rm_instance_setup(struct mfc_dev *dev, struct mfc_ctx *ctx);
 void mfc_rm_request_work(struct mfc_dev *dev, enum mfc_request_work work,
-- 
2.34.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ