[COMMON] media: mfc: DRV4.0: change to intuitive file name.
authorSunyoung Kang <sy0816.kang@samsung.com>
Tue, 26 Jun 2018 06:10:09 +0000 (15:10 +0900)
committerSunyoung Kang <sy0816.kang@samsung.com>
Mon, 23 Jul 2018 06:18:51 +0000 (15:18 +0900)
This changes the file names more intuitively.

mfc_regs_v10.h => mfc_regs.h
mfc_reg.c/h => mfc_reg_api.c/h
mfc_cal.c/h => mfc_hw_reg_api.c/h
mfc_dec_ops.c => mfc_dec_ctrl.c
mfc_enc_ops.c => mfc_enc_ctrl.c
mfc_dec.c/h => mfc_dec_v4l2.c/h
mfc_enc.c/h => mfc_enc_v4l2.c/h
mfc_dec_vb2_ops.c => mfc_dec_vb2.c
mfc_enc_vb2_ops.c => mfc_enc_vb2.c
mfc_irq.c/h => mfc_isr.c/h

Change-Id: Ie217f5ccead5ab12888ec3fe83c292be10a0f553
Signed-off-by: Sunyoung Kang <sy0816.kang@samsung.com>
46 files changed:
drivers/media/platform/exynos/mfc/Makefile
drivers/media/platform/exynos/mfc/mfc.c
drivers/media/platform/exynos/mfc/mfc_cal.c [deleted file]
drivers/media/platform/exynos/mfc/mfc_cal.h [deleted file]
drivers/media/platform/exynos/mfc/mfc_cmd.c
drivers/media/platform/exynos/mfc/mfc_common.h
drivers/media/platform/exynos/mfc/mfc_ctrl.c
drivers/media/platform/exynos/mfc/mfc_dec.c [deleted file]
drivers/media/platform/exynos/mfc/mfc_dec.h [deleted file]
drivers/media/platform/exynos/mfc/mfc_dec_ctrl.c [new file with mode: 0644]
drivers/media/platform/exynos/mfc/mfc_dec_ops.c [deleted file]
drivers/media/platform/exynos/mfc/mfc_dec_v4l2.c [new file with mode: 0644]
drivers/media/platform/exynos/mfc/mfc_dec_v4l2.h [new file with mode: 0644]
drivers/media/platform/exynos/mfc/mfc_dec_vb2.c [new file with mode: 0644]
drivers/media/platform/exynos/mfc/mfc_dec_vb2_ops.c [deleted file]
drivers/media/platform/exynos/mfc/mfc_enc.c [deleted file]
drivers/media/platform/exynos/mfc/mfc_enc.h [deleted file]
drivers/media/platform/exynos/mfc/mfc_enc_ctrl.c [new file with mode: 0644]
drivers/media/platform/exynos/mfc/mfc_enc_ops.c [deleted file]
drivers/media/platform/exynos/mfc/mfc_enc_param.c
drivers/media/platform/exynos/mfc/mfc_enc_v4l2.c [new file with mode: 0644]
drivers/media/platform/exynos/mfc/mfc_enc_v4l2.h [new file with mode: 0644]
drivers/media/platform/exynos/mfc/mfc_enc_vb2.c [new file with mode: 0644]
drivers/media/platform/exynos/mfc/mfc_enc_vb2_ops.c [deleted file]
drivers/media/platform/exynos/mfc/mfc_hw_reg_api.c [new file with mode: 0644]
drivers/media/platform/exynos/mfc/mfc_hw_reg_api.h [new file with mode: 0644]
drivers/media/platform/exynos/mfc/mfc_hwlock.c
drivers/media/platform/exynos/mfc/mfc_inst.c
drivers/media/platform/exynos/mfc/mfc_irq.c [deleted file]
drivers/media/platform/exynos/mfc/mfc_irq.h [deleted file]
drivers/media/platform/exynos/mfc/mfc_isr.c [new file with mode: 0644]
drivers/media/platform/exynos/mfc/mfc_isr.h [new file with mode: 0644]
drivers/media/platform/exynos/mfc/mfc_mmcache.c
drivers/media/platform/exynos/mfc/mfc_nal_q.c
drivers/media/platform/exynos/mfc/mfc_opr.c
drivers/media/platform/exynos/mfc/mfc_otf.c
drivers/media/platform/exynos/mfc/mfc_perf_measure.h
drivers/media/platform/exynos/mfc/mfc_pm.c
drivers/media/platform/exynos/mfc/mfc_reg.c [deleted file]
drivers/media/platform/exynos/mfc/mfc_reg.h [deleted file]
drivers/media/platform/exynos/mfc/mfc_reg_api.c [new file with mode: 0644]
drivers/media/platform/exynos/mfc/mfc_reg_api.h [new file with mode: 0644]
drivers/media/platform/exynos/mfc/mfc_regs.h [new file with mode: 0644]
drivers/media/platform/exynos/mfc/mfc_regs_v10.h [deleted file]
drivers/media/platform/exynos/mfc/mfc_sync.c
drivers/media/platform/exynos/mfc/mfc_watchdog.c

index 72eddaeb1112e7216f4bc8aaaf5d5d9ec83f3277..40c8cf76551eb58d9d3105678dc37c188eee45a5 100644 (file)
@@ -1,8 +1,8 @@
 obj-$(CONFIG_VIDEO_EXYNOS_MFC) := exynos_mfc.o
-exynos_mfc-y += mfc.o mfc_irq.o mfc_dec.o mfc_dec_vb2_ops.o mfc_enc.o mfc_enc_vb2_ops.o
+exynos_mfc-y += mfc.o mfc_isr.o mfc_dec_v4l2.o mfc_dec_vb2.o mfc_enc_v4l2.o mfc_enc_vb2.o
 exynos_mfc-y += mfc_ctrl.o mfc_hwlock.o mfc_nal_q.o mfc_watchdog.o mfc_opr.o mfc_sync.o
-exynos_mfc-y += mfc_pm.o mfc_inst.o mfc_cmd.o mfc_cal.o mfc_reg.o mfc_perf_measure.o
-exynos_mfc-y += mfc_dec_ops.o mfc_enc_ops.o mfc_enc_param.o
+exynos_mfc-y += mfc_pm.o mfc_inst.o mfc_cmd.o mfc_hw_reg_api.o mfc_reg_api.o mfc_perf_measure.o
+exynos_mfc-y += mfc_dec_ctrl.o mfc_enc_ctrl.o mfc_enc_param.o
 exynos_mfc-y += mfc_queue.o mfc_buf.o mfc_utils.o mfc_qos.o mfc_mem.o
 exynos_mfc-y += mfc_debugfs.o mfc_otf.o
 exynos_mfc-y += mfc_mmcache.o
index 5aef071bd3ebe751ed4fe06b821e17b50459567b..8f5e8d3eedc3b6243b6b7b6ba64da658a7fa58c4 100644 (file)
@@ -23,9 +23,9 @@
 
 #include "mfc_common.h"
 
-#include "mfc_irq.h"
-#include "mfc_dec.h"
-#include "mfc_enc.h"
+#include "mfc_isr.h"
+#include "mfc_dec_v4l2.h"
+#include "mfc_enc_v4l2.h"
 
 #include "mfc_ctrl.h"
 #include "mfc_hwlock.h"
@@ -38,9 +38,9 @@
 
 #include "mfc_inst.h"
 #include "mfc_pm.h"
-#include "mfc_cal.h"
 #include "mfc_perf_measure.h"
-#include "mfc_reg.h"
+#include "mfc_reg_api.h"
+#include "mfc_hw_reg_api.h"
 #include "mfc_mmcache.h"
 
 #include "mfc_qos.h"
diff --git a/drivers/media/platform/exynos/mfc/mfc_cal.c b/drivers/media/platform/exynos/mfc/mfc_cal.c
deleted file mode 100644 (file)
index 56f9a1c..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * drivers/media/platform/exynos/mfc/mfc_cal.c
- *
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <trace/events/mfc.h>
-
-#include "mfc_cal.h"
-#include "mfc_pm.h"
-
-/* Reset the device */
-int mfc_reset_mfc(struct mfc_dev *dev)
-{
-       int i;
-
-       mfc_debug_enter();
-
-       if (!dev) {
-               mfc_err_dev("no mfc device to run\n");
-               return -EINVAL;
-       }
-
-       /* Zero Initialization of MFC registers */
-       MFC_WRITEL(0, MFC_REG_RISC2HOST_CMD);
-       MFC_WRITEL(0, MFC_REG_HOST2RISC_CMD);
-       MFC_WRITEL(0, MFC_REG_FW_VERSION);
-
-       for (i = 0; i < MFC_REG_REG_CLEAR_COUNT; i++)
-               MFC_WRITEL(0, MFC_REG_REG_CLEAR_BEGIN + (i*4));
-
-       MFC_WRITEL(0x1FFF, MFC_REG_MFC_RESET);
-       MFC_WRITEL(0, MFC_REG_MFC_RESET);
-
-       mfc_debug_leave();
-
-       return 0;
-}
-
-void mfc_set_risc_base_addr(struct mfc_dev *dev,
-                                       enum mfc_buf_usage_type buf_type)
-{
-       struct mfc_special_buf *fw_buf;
-
-       fw_buf = &dev->fw_buf;
-
-       if (buf_type == MFCBUF_DRM)
-               fw_buf = &dev->drm_fw_buf;
-
-       MFC_WRITEL(fw_buf->daddr, MFC_REG_RISC_BASE_ADDRESS);
-       mfc_debug(2, "[MEMINFO][F/W] %s Base Address : %#x\n",
-                       buf_type == MFCBUF_DRM ? "DRM" : "NORMAL", fw_buf->daddr);
-       MFC_TRACE_DEV("%s F/W Base Address : %#x\n",
-                       buf_type == MFCBUF_DRM ? "DRM" : "NORMAL", fw_buf->daddr);
-}
-
-void mfc_cmd_host2risc(struct mfc_dev *dev, int cmd)
-{
-       mfc_debug(1, "Issue the command: %d\n", cmd);
-       MFC_TRACE_DEV(">> CMD : %d, (dev:0x%lx, bits:%lx, owned:%d, wl:%d, trans:%d)\n",
-                       cmd, dev->hwlock.dev, dev->hwlock.bits, dev->hwlock.owned_by_irq,
-                       dev->hwlock.wl_count, dev->hwlock.transfer_owner);
-
-       trace_mfc_frame_start(dev->curr_ctx, cmd, 0, 0);
-       /* Reset RISC2HOST command except nal q stop command */
-       if (cmd != MFC_REG_H2R_CMD_STOP_QUEUE)
-               MFC_WRITEL(0x0, MFC_REG_RISC2HOST_CMD);
-
-       /* Start the timeout watchdog */
-       if ((cmd != MFC_REG_H2R_CMD_NAL_QUEUE) && (cmd != MFC_REG_H2R_CMD_STOP_QUEUE))
-               mfc_watchdog_start_tick(dev);
-
-       if (dbg_enable) {
-               /* For FW debugging */
-               mfc_dbg_set_addr(dev);
-               mfc_dbg_enable(dev);
-       }
-
-       /* Issue the command */
-       MFC_WRITEL(cmd, MFC_REG_HOST2RISC_CMD);
-       MFC_WRITEL(0x1, MFC_REG_HOST2RISC_INT);
-}
-
-/* Check whether HW interrupt has occurred or not */
-int mfc_check_risc2host(struct mfc_dev *dev)
-{
-       if (mfc_pm_get_pwr_ref_cnt(dev) && mfc_pm_get_clk_ref_cnt(dev)) {
-               if (MFC_READL(MFC_REG_RISC2HOST_INT))
-                       return MFC_READL(MFC_REG_RISC2HOST_CMD);
-               else
-                       return 0;
-       }
-
-       return 0;
-}
diff --git a/drivers/media/platform/exynos/mfc/mfc_cal.h b/drivers/media/platform/exynos/mfc/mfc_cal.h
deleted file mode 100644 (file)
index 7bed92c..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * drivers/media/platform/exynos/mfc/mfc_cal.h
- *
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef __MFC_CAL_H
-#define __MFC_CAL_H __FILE__
-
-#include "mfc_reg.h"
-
-#include "mfc_common.h"
-
-#include "mfc_utils.h"
-
-
-#define mfc_get_int_reason()   (MFC_READL(MFC_REG_RISC2HOST_CMD)               \
-                                               & MFC_REG_RISC2HOST_CMD_MASK)
-#define mfc_clear_int_sfr()                            \
-               do {                                                    \
-                       MFC_WRITEL(0, MFC_REG_RISC2HOST_CMD);   \
-                       MFC_WRITEL(0, MFC_REG_RISC2HOST_INT);   \
-               } while (0)
-
-static inline int mfc_stop_bus(struct mfc_dev *dev)
-{
-       unsigned int status;
-       unsigned long timeout;
-
-       /* Reset */
-       MFC_WRITEL(0x1, MFC_REG_MFC_BUS_RESET_CTRL);
-
-       timeout = jiffies + msecs_to_jiffies(MFC_BW_TIMEOUT);
-       /* Check bus status */
-       do {
-               if (time_after(jiffies, timeout)) {
-                       mfc_err_dev("Timeout while resetting MFC.\n");
-                       return -EIO;
-               }
-               status = MFC_READL(MFC_REG_MFC_BUS_RESET_CTRL);
-       } while ((status & 0x2) == 0);
-
-       return 0;
-}
-
-static inline void mfc_start_bus(struct mfc_dev *dev)
-{
-       int val;
-
-       val = MFC_READL(MFC_REG_MFC_BUS_RESET_CTRL);
-       val &= ~(0x1);
-       MFC_WRITEL(val, MFC_REG_MFC_BUS_RESET_CTRL);
-}
-
-static inline void mfc_risc_on(struct mfc_dev *dev)
-{
-       mfc_clean_dev_int_flags(dev);
-
-       MFC_WRITEL(0x1, MFC_REG_RISC_ON);
-       MFC_WRITEL(0x0, MFC_REG_MFC_OFF);
-       mfc_debug(1, "RISC_ON\n");
-       MFC_TRACE_DEV(">> RISC ON\n");
-}
-
-static inline void mfc_risc_off(struct mfc_dev *dev)
-{
-       unsigned int status;
-       unsigned long timeout;
-
-       timeout = jiffies + msecs_to_jiffies(MFC_BW_TIMEOUT);
-       /* Check pending status */
-       do {
-               if (time_after(jiffies, timeout)) {
-                       mfc_err_dev("Timeout while pendng clear\n");
-                       mfc_err_dev("MFC access pending state: %#x\n", status);
-                       mfc_err_dev("MFC access pending R: %#x, W: %#x\n",
-                                       MFC_READL(MFC_REG_MFC_RPEND),
-                                       MFC_READL(MFC_REG_MFC_WPEND));
-                       break;
-               }
-               status = MFC_READL(MFC_REG_MFC_BUS_STATUS);
-       } while (status != 0);
-
-       MFC_WRITEL(0x0, MFC_REG_RISC_ON);
-}
-
-static inline void mfc_mfc_off(struct mfc_dev *dev)
-{
-       mfc_info_dev("MFC h/w state: %d\n",
-                       MFC_READL(MFC_REG_MFC_STATE) & 0x7);
-       MFC_WRITEL(0x1, MFC_REG_MFC_OFF);
-}
-
-static inline void mfc_enable_all_clocks(struct mfc_dev *dev)
-{
-       /* Enable all FW clock gating */
-       MFC_WRITEL(0xFFFFFFFF, MFC_REG_MFC_FW_CLOCK);
-}
-
-int mfc_reset_mfc(struct mfc_dev *dev);
-void mfc_set_risc_base_addr(struct mfc_dev *dev,
-                               enum mfc_buf_usage_type buf_type);
-void mfc_cmd_host2risc(struct mfc_dev *dev, int cmd);
-int mfc_check_risc2host(struct mfc_dev *dev);
-
-#endif /* __MFC_CAL_H */
index 87dad6691230f4c7ce51fbecf6f1b26e69d9c7ca..bbbb4fb5bf4f58ea0a25160751d1520fd89c750b 100644 (file)
@@ -14,8 +14,8 @@
 
 #include "mfc_cmd.h"
 
-#include "mfc_cal.h"
-#include "mfc_reg.h"
+#include "mfc_reg_api.h"
+#include "mfc_hw_reg_api.h"
 #include "mfc_mmcache.h"
 
 #include "mfc_utils.h"
index c45acb36903e84cc9059658ae2aabff79efa40d1..33481ca6aa86d2410990faa9e1bf9f3639b86b10 100644 (file)
@@ -22,7 +22,7 @@
 #include <media/videobuf2-dma-sg.h>
 #include <asm/cacheflush.h>
 
-#include "mfc_regs_v10.h"
+#include "mfc_regs.h"
 #include "mfc_macros.h"
 #include "mfc_debug.h"
 #include "exynos_mfc_media.h"
index cef16fa01ba08b71c6aa260034537a0a8a0c265e..9da4eb37d58e6c9bcb7c24b24a3f0a6bc7c5636c 100644 (file)
@@ -18,8 +18,8 @@
 
 #include "mfc_pm.h"
 #include "mfc_cmd.h"
-#include "mfc_cal.h"
-#include "mfc_reg.h"
+#include "mfc_reg_api.h"
+#include "mfc_hw_reg_api.h"
 
 #include "mfc_utils.h"
 
diff --git a/drivers/media/platform/exynos/mfc/mfc_dec.c b/drivers/media/platform/exynos/mfc/mfc_dec.c
deleted file mode 100644 (file)
index 9c004a2..0000000
+++ /dev/null
@@ -1,1279 +0,0 @@
-/*
- * drivers/media/platform/exynos/mfc/mfc_dec.c
- *
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include "mfc_dec.h"
-#include "mfc_dec_internal.h"
-
-#include "mfc_hwlock.h"
-#include "mfc_opr.h"
-#include "mfc_sync.h"
-#include "mfc_mmcache.h"
-
-#include "mfc_qos.h"
-#include "mfc_queue.h"
-#include "mfc_utils.h"
-#include "mfc_buf.h"
-#include "mfc_mem.h"
-
-#define MAX_FRAME_SIZE         (2*1024*1024)
-
-/* Find selected format description */
-static struct mfc_fmt *__mfc_dec_find_format(struct mfc_ctx *ctx,
-               unsigned int pixelformat)
-{
-       struct mfc_dev *dev = ctx->dev;
-       struct mfc_fmt *fmt = NULL;
-       unsigned long i;
-
-       for (i = 0; i < NUM_FORMATS; i++) {
-               if (dec_formats[i].fourcc == pixelformat) {
-                       fmt = (struct mfc_fmt *)&dec_formats[i];
-                       break;
-               }
-       }
-
-       if (!dev->pdata->support_10bit && (fmt->type & MFC_FMT_10BIT)) {
-               mfc_err_ctx("[FRAME] 10bit is not supported\n");
-               fmt = NULL;
-       }
-       if (!dev->pdata->support_422 && (fmt->type & MFC_FMT_422)) {
-               mfc_err_ctx("[FRAME] 422 is not supported\n");
-               fmt = NULL;
-       }
-
-       return fmt;
-}
-
-static struct v4l2_queryctrl *__mfc_dec_get_ctrl(int id)
-{
-       unsigned long i;
-
-       for (i = 0; i < NUM_CTRLS; ++i)
-               if (id == controls[i].id)
-                       return &controls[i];
-
-       return NULL;
-}
-
-/* Check whether a ctrl value if correct */
-static int __mfc_dec_check_ctrl_val(struct mfc_ctx *ctx, struct v4l2_control *ctrl)
-{
-       struct v4l2_queryctrl *c;
-
-       c = __mfc_dec_get_ctrl(ctrl->id);
-       if (!c) {
-               mfc_err_ctx("[CTRLS] not supported control id (%#x)\n", ctrl->id);
-               return -EINVAL;
-       }
-
-       if (ctrl->value < c->minimum || ctrl->value > c->maximum
-               || (c->step != 0 && ctrl->value % c->step != 0)) {
-               mfc_err_ctx("[CTRLS] Invalid control value (%#x)\n", ctrl->value);
-               return -ERANGE;
-       }
-
-       return 0;
-}
-
-/* Query capabilities of the device */
-static int vidioc_querycap(struct file *file, void *priv,
-                          struct v4l2_capability *cap)
-{
-       strncpy(cap->driver, "MFC", sizeof(cap->driver) - 1);
-       strncpy(cap->card, "decoder", sizeof(cap->card) - 1);
-       cap->bus_info[0] = 0;
-       cap->version = KERNEL_VERSION(1, 0, 0);
-       cap->device_caps = V4L2_CAP_VIDEO_CAPTURE
-                       | V4L2_CAP_VIDEO_OUTPUT
-                       | V4L2_CAP_VIDEO_CAPTURE_MPLANE
-                       | V4L2_CAP_VIDEO_OUTPUT_MPLANE
-                       | V4L2_CAP_STREAMING
-                       | V4L2_CAP_DEVICE_CAPS;
-
-       cap->capabilities = cap->device_caps;
-
-       return 0;
-}
-
-static int __mfc_dec_enum_fmt(struct mfc_dev *dev, struct v4l2_fmtdesc *f,
-               unsigned int type)
-{
-       struct mfc_fmt *fmt;
-       unsigned long i, j = 0;
-
-       for (i = 0; i < NUM_FORMATS; ++i) {
-               if (!(dec_formats[i].type & type))
-                       continue;
-               if (!dev->pdata->support_10bit && (dec_formats[i].type & MFC_FMT_10BIT))
-                       continue;
-               if (!dev->pdata->support_422 && (dec_formats[i].type & MFC_FMT_422))
-                       continue;
-
-               if (j == f->index) {
-                       fmt = &dec_formats[i];
-                       strlcpy(f->description, fmt->name,
-                               sizeof(f->description));
-                       f->pixelformat = fmt->fourcc;
-
-                       return 0;
-               }
-
-               ++j;
-       }
-
-       return -EINVAL;
-}
-
-static int vidioc_enum_fmt_vid_cap_mplane(struct file *file, void *pirv,
-               struct v4l2_fmtdesc *f)
-{
-       struct mfc_dev *dev = video_drvdata(file);
-
-       return __mfc_dec_enum_fmt(dev, f, MFC_FMT_FRAME);
-}
-
-static int vidioc_enum_fmt_vid_out_mplane(struct file *file, void *prov,
-               struct v4l2_fmtdesc *f)
-{
-       struct mfc_dev *dev = video_drvdata(file);
-
-       return __mfc_dec_enum_fmt(dev, f, MFC_FMT_STREAM);
-}
-
-static void __mfc_dec_change_format(struct mfc_ctx *ctx)
-{
-       struct mfc_dev *dev = ctx->dev;
-       u32 org_fmt = ctx->dst_fmt->fourcc;
-
-       if (ctx->is_10bit && ctx->is_422) {
-               switch (org_fmt) {
-               case V4L2_PIX_FMT_NV16M_S10B:
-               case V4L2_PIX_FMT_NV61M_S10B:
-               case V4L2_PIX_FMT_NV16M_P210:
-               case V4L2_PIX_FMT_NV61M_P210:
-                       /* It is right format */
-                       break;
-               case V4L2_PIX_FMT_NV12M:
-               case V4L2_PIX_FMT_NV16M:
-               case V4L2_PIX_FMT_NV12M_S10B:
-               case V4L2_PIX_FMT_NV12M_P010:
-                       ctx->dst_fmt = __mfc_dec_find_format(ctx, V4L2_PIX_FMT_NV16M_S10B);
-                       break;
-               case V4L2_PIX_FMT_NV21M:
-               case V4L2_PIX_FMT_NV61M:
-               case V4L2_PIX_FMT_NV21M_S10B:
-               case V4L2_PIX_FMT_NV21M_P010:
-                       ctx->dst_fmt = __mfc_dec_find_format(ctx, V4L2_PIX_FMT_NV61M_S10B);
-                       break;
-               default:
-                       ctx->dst_fmt = __mfc_dec_find_format(ctx, V4L2_PIX_FMT_NV16M_S10B);
-                       break;
-               }
-               ctx->raw_buf.num_planes = 2;
-       } else if (ctx->is_10bit && !ctx->is_422) {
-               if (ctx->dst_fmt->mem_planes == 1) {
-                       /* YUV420 only supports the single plane */
-                       ctx->dst_fmt = __mfc_dec_find_format(ctx, V4L2_PIX_FMT_NV12N_10B);
-               } else {
-                       switch (org_fmt) {
-                       case V4L2_PIX_FMT_NV12M_S10B:
-                       case V4L2_PIX_FMT_NV21M_S10B:
-                       case V4L2_PIX_FMT_NV12M_P010:
-                       case V4L2_PIX_FMT_NV21M_P010:
-                               /* It is right format */
-                               break;
-                       case V4L2_PIX_FMT_NV12M:
-                       case V4L2_PIX_FMT_NV16M:
-                       case V4L2_PIX_FMT_NV16M_S10B:
-                       case V4L2_PIX_FMT_NV16M_P210:
-                               if (dev->pdata->P010_decoding)
-                                       ctx->dst_fmt = __mfc_dec_find_format(ctx, V4L2_PIX_FMT_NV12M_P010);
-                               else
-                                       ctx->dst_fmt = __mfc_dec_find_format(ctx, V4L2_PIX_FMT_NV12M_S10B);
-                               break;
-                       case V4L2_PIX_FMT_NV21M:
-                       case V4L2_PIX_FMT_NV61M:
-                       case V4L2_PIX_FMT_NV61M_S10B:
-                       case V4L2_PIX_FMT_NV61M_P210:
-                               ctx->dst_fmt = __mfc_dec_find_format(ctx, V4L2_PIX_FMT_NV21M_S10B);
-                               break;
-                       default:
-                               if (dev->pdata->P010_decoding)
-                                       ctx->dst_fmt = __mfc_dec_find_format(ctx, V4L2_PIX_FMT_NV12M_P010);
-                               else
-                                       ctx->dst_fmt = __mfc_dec_find_format(ctx, V4L2_PIX_FMT_NV12M_S10B);
-                               break;
-                       }
-               }
-               ctx->raw_buf.num_planes = 2;
-       } else if (!ctx->is_10bit && ctx->is_422) {
-               switch (org_fmt) {
-               case V4L2_PIX_FMT_NV16M:
-               case V4L2_PIX_FMT_NV61M:
-                       /* It is right format */
-                       break;
-               case V4L2_PIX_FMT_NV12M:
-               case V4L2_PIX_FMT_NV12M_S10B:
-               case V4L2_PIX_FMT_NV16M_S10B:
-               case V4L2_PIX_FMT_NV12M_P010:
-               case V4L2_PIX_FMT_NV16M_P210:
-                       ctx->dst_fmt = __mfc_dec_find_format(ctx, V4L2_PIX_FMT_NV16M);
-                       break;
-               case V4L2_PIX_FMT_NV21M:
-               case V4L2_PIX_FMT_NV21M_S10B:
-               case V4L2_PIX_FMT_NV61M_S10B:
-               case V4L2_PIX_FMT_NV21M_P010:
-               case V4L2_PIX_FMT_NV61M_P210:
-                       ctx->dst_fmt = __mfc_dec_find_format(ctx, V4L2_PIX_FMT_NV61M);
-                       break;
-               default:
-                       ctx->dst_fmt = __mfc_dec_find_format(ctx, V4L2_PIX_FMT_NV16M);
-                       break;
-               }
-               ctx->raw_buf.num_planes = 2;
-       } else {
-               /* YUV420 8bit */
-               switch (org_fmt) {
-               case V4L2_PIX_FMT_NV16M:
-               case V4L2_PIX_FMT_NV12M_S10B:
-               case V4L2_PIX_FMT_NV16M_S10B:
-               case V4L2_PIX_FMT_NV12M_P010:
-               case V4L2_PIX_FMT_NV16M_P210:
-                       ctx->dst_fmt = __mfc_dec_find_format(ctx, V4L2_PIX_FMT_NV12M);
-                       break;
-               case V4L2_PIX_FMT_NV61M:
-               case V4L2_PIX_FMT_NV21M_S10B:
-               case V4L2_PIX_FMT_NV61M_S10B:
-               case V4L2_PIX_FMT_NV21M_P010:
-               case V4L2_PIX_FMT_NV61M_P210:
-                       ctx->dst_fmt = __mfc_dec_find_format(ctx, V4L2_PIX_FMT_NV21M);
-                       break;
-               default:
-                       /* It is right format */
-                       break;
-               }
-       }
-
-       if (org_fmt != ctx->dst_fmt->fourcc)
-               mfc_info_ctx("[FRAME] format is changed to %s\n", ctx->dst_fmt->name);
-}
-
-/* Get format */
-static int vidioc_g_fmt_vid_cap_mplane(struct file *file, void *priv,
-                                               struct v4l2_format *f)
-{
-       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
-       struct mfc_dec *dec;
-       struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
-       struct mfc_raw_info *raw;
-       int i;
-
-       mfc_debug_enter();
-
-       dec = ctx->dec_priv;
-       if (!dec) {
-               mfc_err_dev("no mfc decoder to run\n");
-               return -EINVAL;
-       }
-
-       mfc_debug(2, "dec dst g_fmt, state: %d\n", ctx->state);
-
-       if (ctx->state == MFCINST_GOT_INST ||
-           ctx->state == MFCINST_RES_CHANGE_FLUSH ||
-           ctx->state == MFCINST_RES_CHANGE_END) {
-               /* If the MFC is parsing the header,
-                * so wait until it is finished */
-               if (mfc_wait_for_done_ctx(ctx,
-                               MFC_REG_R2H_CMD_SEQ_DONE_RET)) {
-                               mfc_err_dev("header parsing failed\n");
-                               return -EAGAIN;
-               }
-       }
-
-       if (ctx->state >= MFCINST_HEAD_PARSED &&
-           ctx->state < MFCINST_ABORT) {
-               /* This is run on CAPTURE (deocde output) */
-
-               /* only NV16(61) format is supported for 422 format */
-               /* only 2 plane is supported for 10bit */
-               __mfc_dec_change_format(ctx);
-
-               raw = &ctx->raw_buf;
-               /* Width and height are set to the dimensions
-                  of the movie, the buffer is bigger and
-                  further processing stages should crop to this
-                  rectangle. */
-               mfc_dec_calc_dpb_size(ctx);
-
-               if (IS_LOW_MEM) {
-                       unsigned int dpb_size;
-                       /*
-                        * If total memory requirement is too big for this device,
-                        * then it returns error.
-                        * DPB size : Total plane size * the number of DPBs
-                        * 5: the number of extra DPBs
-                        * 3: the number of DPBs for Android framework
-                        * 600MB: being used to return an error,
-                        * when 8K resolution video clip is being tried to be decoded
-                        */
-                       dpb_size = (ctx->raw_buf.total_plane_size * (ctx->dpb_count + 5 + 3));
-                       if (dpb_size > SZ_600M) {
-                               mfc_info_ctx("required memory size is too big (%dx%d, dpb: %d)\n",
-                                               ctx->img_width, ctx->img_height, ctx->dpb_count);
-                               return -EINVAL;
-                       }
-               }
-
-               pix_fmt_mp->width = ctx->img_width;
-               pix_fmt_mp->height = ctx->img_height;
-               pix_fmt_mp->num_planes = ctx->dst_fmt->mem_planes;
-
-               if (dec->is_interlaced)
-                       pix_fmt_mp->field = V4L2_FIELD_INTERLACED;
-               else
-                       pix_fmt_mp->field = V4L2_FIELD_NONE;
-
-               /* Set pixelformat to the format in which MFC
-                  outputs the decoded frame */
-               pix_fmt_mp->pixelformat = ctx->dst_fmt->fourcc;
-               for (i = 0; i < ctx->dst_fmt->mem_planes; i++) {
-                       pix_fmt_mp->plane_fmt[i].bytesperline = raw->stride[i];
-                       if (ctx->dst_fmt->mem_planes == 1) {
-                               pix_fmt_mp->plane_fmt[i].sizeimage = raw->total_plane_size;
-                       } else {
-                               if (ctx->is_10bit)
-                                       pix_fmt_mp->plane_fmt[i].sizeimage = raw->plane_size[i]
-                                               + raw->plane_size_2bits[i];
-                               else
-                                       pix_fmt_mp->plane_fmt[i].sizeimage = raw->plane_size[i];
-                       }
-               }
-       }
-
-       mfc_debug_leave();
-
-       return 0;
-}
-
-static int vidioc_g_fmt_vid_out_mplane(struct file *file, void *priv,
-                                               struct v4l2_format *f)
-{
-       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
-       struct mfc_dec *dec;
-       struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
-
-       mfc_debug_enter();
-
-       dec = ctx->dec_priv;
-       if (!dec) {
-               mfc_err_dev("no mfc decoder to run\n");
-               return -EINVAL;
-       }
-
-       mfc_debug(4, "dec src g_fmt, state: %d\n", ctx->state);
-
-       /* This is run on OUTPUT
-          The buffer contains compressed image
-          so width and height have no meaning */
-       pix_fmt_mp->width = 0;
-       pix_fmt_mp->height = 0;
-       pix_fmt_mp->field = V4L2_FIELD_NONE;
-       pix_fmt_mp->plane_fmt[0].bytesperline = dec->src_buf_size;
-       pix_fmt_mp->plane_fmt[0].sizeimage = dec->src_buf_size;
-       pix_fmt_mp->pixelformat = ctx->src_fmt->fourcc;
-       pix_fmt_mp->num_planes = ctx->src_fmt->mem_planes;
-
-       mfc_debug_leave();
-
-       return 0;
-}
-
-/* Try format */
-static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
-{
-       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
-       struct mfc_fmt *fmt;
-       struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
-
-       fmt = __mfc_dec_find_format(ctx, pix_fmt_mp->pixelformat);
-       if (!fmt) {
-               mfc_err_dev("Unsupported format for %s\n",
-                               V4L2_TYPE_IS_OUTPUT(f->type) ? "source" : "destination");
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-/* Set format */
-static int vidioc_s_fmt_vid_cap_mplane(struct file *file, void *priv,
-                                                       struct v4l2_format *f)
-{
-       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
-       struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
-
-       mfc_debug_enter();
-
-       if (ctx->vq_dst.streaming) {
-               mfc_err_ctx("queue busy\n");
-               return -EBUSY;
-       }
-
-       ctx->dst_fmt = __mfc_dec_find_format(ctx, pix_fmt_mp->pixelformat);
-       if (!ctx->dst_fmt) {
-               mfc_err_ctx("Unsupported format for destination\n");
-               return -EINVAL;
-       }
-       ctx->raw_buf.num_planes = ctx->dst_fmt->num_planes;
-       mfc_info_ctx("[FRAME] dec dst pixelformat : %s\n", ctx->dst_fmt->name);
-
-       mfc_debug_leave();
-
-       return 0;
-}
-
-static int __mfc_force_close_inst(struct mfc_dev *dev, struct mfc_ctx *ctx)
-{
-       if (ctx->inst_no == MFC_NO_INSTANCE_SET)
-               return 0;
-
-       mfc_change_state(ctx, MFCINST_RETURN_INST);
-       mfc_set_bit(ctx->num, &dev->work_bits);
-       mfc_clean_ctx_int_flags(ctx);
-       if (mfc_just_run(dev, ctx->num)) {
-               mfc_err_ctx("Failed to run MFC\n");
-               mfc_release_hwlock_ctx(ctx);
-               mfc_cleanup_work_bit_and_try_run(ctx);
-               return -EIO;
-       }
-
-       /* Wait until instance is returned or timeout occured */
-       if (mfc_wait_for_done_ctx(ctx,
-                               MFC_REG_R2H_CMD_CLOSE_INSTANCE_RET)) {
-               mfc_err_ctx("Waiting for CLOSE_INSTANCE timed out\n");
-               mfc_release_hwlock_ctx(ctx);
-               mfc_cleanup_work_bit_and_try_run(ctx);
-               return -EIO;
-       }
-
-       /* Free resources */
-       mfc_release_instance_context(ctx);
-       mfc_change_state(ctx, MFCINST_INIT);
-
-       return 0;
-}
-
-static int vidioc_s_fmt_vid_out_mplane(struct file *file, void *priv,
-                                                       struct v4l2_format *f)
-{
-       struct mfc_dev *dev = video_drvdata(file);
-       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
-       struct mfc_dec *dec = ctx->dec_priv;
-       struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
-       int ret = 0;
-
-       mfc_debug_enter();
-
-       if (ctx->vq_src.streaming) {
-               mfc_err_ctx("queue busy\n");
-               return -EBUSY;
-       }
-
-       ctx->src_fmt = __mfc_dec_find_format(ctx, pix_fmt_mp->pixelformat);
-       if (!ctx->src_fmt) {
-               mfc_err_ctx("Unsupported format for source\n");
-               return -EINVAL;
-       }
-
-       ctx->codec_mode = ctx->src_fmt->codec_mode;
-       mfc_info_ctx("[STREAM] Dec src codec(%d): %s\n",
-                       ctx->codec_mode, ctx->src_fmt->name);
-
-       ctx->pix_format = pix_fmt_mp->pixelformat;
-       if ((pix_fmt_mp->width > 0) && (pix_fmt_mp->height > 0)) {
-               ctx->img_height = pix_fmt_mp->height;
-               ctx->img_width = pix_fmt_mp->width;
-       }
-
-       /* As this buffer will contain compressed data, the size is set
-        * to the maximum size. */
-       if (pix_fmt_mp->plane_fmt[0].sizeimage)
-               dec->src_buf_size = pix_fmt_mp->plane_fmt[0].sizeimage;
-       else
-               dec->src_buf_size = MAX_FRAME_SIZE;
-       mfc_debug(2, "[STREAM] sizeimage: %d\n", pix_fmt_mp->plane_fmt[0].sizeimage);
-       pix_fmt_mp->plane_fmt[0].bytesperline = 0;
-
-       MFC_TRACE_CTX_HWLOCK("**DEC s_fmt\n");
-       ret = mfc_get_hwlock_ctx(ctx);
-       if (ret < 0) {
-               mfc_err_ctx("Failed to get hwlock\n");
-               return -EBUSY;
-       }
-
-       /* In case of calling s_fmt twice or more */
-       ret = __mfc_force_close_inst(dev, ctx);
-       if (ret) {
-               mfc_err_ctx("Failed to close already opening instance\n");
-               return -EIO;
-       }
-
-       ret = mfc_alloc_instance_context(ctx);
-       if (ret) {
-               mfc_err_ctx("Failed to allocate dec instance[%d] buffers\n",
-                               ctx->num);
-               mfc_release_hwlock_ctx(ctx);
-               return -ENOMEM;
-       }
-
-       mfc_set_bit(ctx->num, &dev->work_bits);
-       ret = mfc_just_run(dev, ctx->num);
-       if (ret) {
-               mfc_err_ctx("Failed to run MFC\n");
-               mfc_release_hwlock_ctx(ctx);
-               mfc_cleanup_work_bit_and_try_run(ctx);
-               mfc_release_instance_context(ctx);
-               return -EIO;
-       }
-
-       if (mfc_wait_for_done_ctx(ctx,
-                       MFC_REG_R2H_CMD_OPEN_INSTANCE_RET)) {
-               mfc_release_hwlock_ctx(ctx);
-               mfc_cleanup_work_bit_and_try_run(ctx);
-               mfc_release_instance_context(ctx);
-               return -EIO;
-       }
-
-       mfc_release_hwlock_ctx(ctx);
-
-       mfc_debug(2, "Got instance number: %d\n", ctx->inst_no);
-
-       if (mfc_dec_ctx_ready(ctx))
-               mfc_set_bit(ctx->num, &dev->work_bits);
-       if (mfc_is_work_to_do(dev))
-               queue_work(dev->butler_wq, &dev->butler_work);
-
-       mfc_debug_leave();
-
-       return 0;
-}
-
-/* Reqeust buffers */
-static int vidioc_reqbufs(struct file *file, void *priv,
-               struct v4l2_requestbuffers *reqbufs)
-{
-       struct mfc_dev *dev = video_drvdata(file);
-       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
-       struct mfc_dec *dec;
-       int ret = 0;
-
-       mfc_debug_enter();
-
-       if (!dev) {
-               mfc_err_dev("no mfc device to run\n");
-               return -EINVAL;
-       }
-
-       dec = ctx->dec_priv;
-       if (!dec) {
-               mfc_err_dev("no mfc decoder to run\n");
-               return -EINVAL;
-       }
-
-       if (reqbufs->memory == V4L2_MEMORY_MMAP) {
-               mfc_err_ctx("Not supported memory type (%d)\n", reqbufs->memory);
-               return -EINVAL;
-       }
-
-       if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
-               mfc_debug(4, "dec src reqbuf(%d)\n", reqbufs->count);
-               /* Can only request buffers after
-                  an instance has been opened.*/
-               if (ctx->state == MFCINST_GOT_INST) {
-                       if (reqbufs->count == 0) {
-                               ret = vb2_reqbufs(&ctx->vq_src, reqbufs);
-                               ctx->output_state = QUEUE_FREE;
-                               return ret;
-                       }
-
-                       /* Decoding */
-                       if (ctx->output_state != QUEUE_FREE) {
-                               mfc_err_ctx("Bufs have already been requested\n");
-                               return -EINVAL;
-                       }
-
-                       ret = vb2_reqbufs(&ctx->vq_src, reqbufs);
-                       if (ret) {
-                               mfc_err_ctx("vb2_reqbufs on src failed\n");
-                               return ret;
-                       }
-
-                       ctx->output_state = QUEUE_BUFS_REQUESTED;
-               }
-       } else if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-               mfc_debug(4, "dec dst reqbuf(%d)\n", reqbufs->count);
-               if (reqbufs->count == 0) {
-                       ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
-
-                       if (dev->has_mmcache && dev->mmcache.is_on_status)
-                               mfc_invalidate_mmcache(dev);
-
-                       mfc_release_codec_buffers(ctx);
-                       ctx->capture_state = QUEUE_FREE;
-                       return ret;
-               }
-
-               dec->dst_memtype = reqbufs->memory;
-
-               if (ctx->capture_state != QUEUE_FREE) {
-                       mfc_err_ctx("Bufs have already been requested\n");
-                       return -EINVAL;
-               }
-
-               ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
-               if (ret) {
-                       mfc_err_ctx("vb2_reqbufs on capture failed\n");
-                       return ret;
-               }
-
-               if (reqbufs->count < ctx->dpb_count) {
-                       mfc_err_ctx("Not enough buffers allocated\n");
-                       reqbufs->count = 0;
-                       vb2_reqbufs(&ctx->vq_dst, reqbufs);
-                       return -ENOMEM;
-               }
-
-               dec->total_dpb_count = reqbufs->count;
-
-               ret = mfc_alloc_codec_buffers(ctx);
-               if (ret) {
-                       mfc_err_ctx("Failed to allocate decoding buffers\n");
-                       reqbufs->count = 0;
-                       vb2_reqbufs(&ctx->vq_dst, reqbufs);
-                       return -ENOMEM;
-               }
-
-               ctx->capture_state = QUEUE_BUFS_REQUESTED;
-
-               if (mfc_dec_ctx_ready(ctx))
-                       mfc_set_bit(ctx->num, &dev->work_bits);
-
-               mfc_try_run(dev);
-       }
-
-       mfc_debug_leave();
-
-       return ret;
-}
-
-/* Query buffer */
-static int vidioc_querybuf(struct file *file, void *priv,
-                                                  struct v4l2_buffer *buf)
-{
-       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
-       int ret;
-
-       mfc_debug_enter();
-
-       if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-               mfc_debug(4, "dec dst querybuf, state: %d\n", ctx->state);
-               ret = vb2_querybuf(&ctx->vq_dst, buf);
-               if (ret != 0) {
-                       mfc_err_dev("dec dst: error in vb2_querybuf()\n");
-                       return ret;
-               }
-       } else if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
-               mfc_debug(4, "dec src querybuf, state: %d\n", ctx->state);
-               ret = vb2_querybuf(&ctx->vq_src, buf);
-               if (ret != 0) {
-                       mfc_err_dev("dec src: error in vb2_querybuf()\n");
-                       return ret;
-               }
-       } else {
-               mfc_err_dev("invalid buf type (%d)\n", buf->type);
-               return -EINVAL;
-       }
-
-       mfc_debug_leave();
-
-       return ret;
-}
-
-/* Queue a buffer */
-static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
-{
-       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
-       int ret = -EINVAL;
-
-       mfc_debug_enter();
-
-       if (ctx->state == MFCINST_ERROR) {
-               mfc_err_ctx("Call on QBUF after unrecoverable error\n");
-               return -EIO;
-       }
-
-       if (V4L2_TYPE_IS_MULTIPLANAR(buf->type) && !buf->length) {
-               mfc_err_ctx("multiplanar but length is zero\n");
-               return -EIO;
-       }
-
-       if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
-               mfc_debug(4, "dec src buf[%d] Q\n", buf->index);
-               if (buf->m.planes[0].bytesused > buf->m.planes[0].length) {
-                       mfc_err_ctx("data size (%d) must be less than "
-                                       "buffer size(%d)\n",
-                                       buf->m.planes[0].bytesused,
-                                       buf->m.planes[0].length);
-                       return -EIO;
-               }
-
-               mfc_qos_update_framerate(ctx);
-
-               if (!buf->m.planes[0].bytesused) {
-                       buf->m.planes[0].bytesused = buf->m.planes[0].length;
-                       mfc_debug(2, "Src size zero, changed to buf size %d\n",
-                                       buf->m.planes[0].bytesused);
-               } else {
-                       mfc_debug(2, "Src size = %d\n", buf->m.planes[0].bytesused);
-               }
-               ret = vb2_qbuf(&ctx->vq_src, buf);
-       } else {
-               mfc_debug(4, "dec dst buf[%d] Q\n", buf->index);
-               ret = vb2_qbuf(&ctx->vq_dst, buf);
-       }
-
-       mfc_debug_leave();
-       return ret;
-}
-
-/* Dequeue a buffer */
-static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
-{
-       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
-       struct mfc_dec *dec = ctx->dec_priv;
-       struct dec_dpb_ref_info *dstBuf, *srcBuf;
-       int ret;
-       int ncount = 0;
-
-       mfc_debug_enter();
-
-       if (ctx->state == MFCINST_ERROR) {
-               mfc_err_ctx("Call on DQBUF after unrecoverable error\n");
-               return -EIO;
-       }
-       if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
-               mfc_debug(4, "dec src buf[%d] DQ\n", buf->index);
-               ret = vb2_dqbuf(&ctx->vq_src, buf, file->f_flags & O_NONBLOCK);
-       } else {
-               mfc_debug(4, "dec dst buf[%d] DQ\n", buf->index);
-               ret = vb2_dqbuf(&ctx->vq_dst, buf, file->f_flags & O_NONBLOCK);
-
-               if (buf->index >= MFC_MAX_DPBS) {
-                       mfc_err_ctx("buffer index[%d] range over\n", buf->index);
-                       return -EINVAL;
-               }
-
-               /* Memcpy from dec->ref_info to shared memory */
-               srcBuf = &dec->ref_info[buf->index];
-               for (ncount = 0; ncount < MFC_MAX_DPBS; ncount++) {
-                       if (srcBuf->dpb[ncount].fd[0] == MFC_INFO_INIT_FD)
-                               break;
-                       mfc_debug(2, "[DPB] DQ index[%d] Released FD = %d\n",
-                                       buf->index, srcBuf->dpb[ncount].fd[0]);
-               }
-
-               if (dec->sh_handle.vaddr != NULL) {
-                       dstBuf = (struct dec_dpb_ref_info *)
-                                       dec->sh_handle.vaddr + buf->index;
-                       memcpy(dstBuf, srcBuf, sizeof(struct dec_dpb_ref_info));
-                       dstBuf->index = buf->index;
-               }
-       }
-       mfc_debug_leave();
-       return ret;
-}
-
-/* Stream on */
-static int vidioc_streamon(struct file *file, void *priv,
-                          enum v4l2_buf_type type)
-{
-       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
-       int ret = -EINVAL;
-
-       mfc_debug_enter();
-
-       if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
-               mfc_debug(4, "dec src streamon\n");
-               ret = vb2_streamon(&ctx->vq_src, type);
-       } else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-               mfc_debug(4, "dec dst streamon\n");
-               ret = vb2_streamon(&ctx->vq_dst, type);
-
-               if (!ret)
-                       mfc_qos_on(ctx);
-       } else {
-               mfc_err_ctx("unknown v4l2 buffer type\n");
-       }
-
-       mfc_debug(2, "src: %d, dst: %d,  state = %d, dpb_count = %d\n",
-                 mfc_get_queue_count(&ctx->buf_queue_lock, &ctx->src_buf_queue),
-                 mfc_get_queue_count(&ctx->buf_queue_lock, &ctx->dst_buf_queue),
-                 ctx->state, ctx->dpb_count);
-
-       mfc_debug_leave();
-
-       return ret;
-}
-
-/* Stream off, which equals to a pause */
-static int vidioc_streamoff(struct file *file, void *priv,
-                           enum v4l2_buf_type type)
-{
-       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
-       int ret = -EINVAL;
-
-       mfc_debug_enter();
-
-       if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
-               mfc_debug(4, "dec src streamoff\n");
-               mfc_qos_reset_last_framerate(ctx);
-
-               ret = vb2_streamoff(&ctx->vq_src, type);
-       } else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-               mfc_debug(4, "dec dst streamoff\n");
-               ret = vb2_streamoff(&ctx->vq_dst, type);
-               if (!ret)
-                       mfc_qos_off(ctx);
-       } else {
-               mfc_err_ctx("unknown v4l2 buffer type\n");
-       }
-
-       mfc_debug_leave();
-
-       return ret;
-}
-
-/* Query a ctrl */
-static int vidioc_queryctrl(struct file *file, void *priv,
-                           struct v4l2_queryctrl *qc)
-{
-       struct v4l2_queryctrl *c;
-
-       c = __mfc_dec_get_ctrl(qc->id);
-       if (!c) {
-               mfc_err_dev("[CTRLS] not supported control id (%#x)\n", qc->id);
-               return -EINVAL;
-       }
-
-       *qc = *c;
-       return 0;
-}
-
-static int __mfc_dec_ext_info(struct mfc_ctx *ctx)
-{
-       struct mfc_dev *dev = ctx->dev;
-       int val = 0;
-
-       val |= DEC_SET_DYNAMIC_DPB;
-       if (MFC_FEATURE_SUPPORT(dev, dev->pdata->skype))
-               val |= DEC_SET_SKYPE_FLAG;
-
-       mfc_debug(5, "[CTRLS] ext info val: %#x\n", val);
-
-       return val;
-}
-
-/* Get ctrl */
-static int __mfc_dec_get_ctrl_val(struct mfc_ctx *ctx, struct v4l2_control *ctrl)
-{
-       struct mfc_dev *dev;
-       struct mfc_dec *dec;
-       struct mfc_ctx_ctrl *ctx_ctrl;
-       int found = 0;
-
-       if (!ctx) {
-               mfc_err_dev("no mfc context to run\n");
-               return -EINVAL;
-       }
-       dev = ctx->dev;
-       if (!dev) {
-               mfc_err_dev("no mfc device to run\n");
-               return -EINVAL;
-       }
-       dec = ctx->dec_priv;
-       if (!dec) {
-               mfc_err_dev("no mfc decoder to run\n");
-               return -EINVAL;
-       }
-
-       switch (ctrl->id) {
-       case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER:
-               ctrl->value = dec->loop_filter_mpeg4;
-               break;
-       case V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY:
-               ctrl->value = dec->display_delay;
-               break;
-       case V4L2_CID_CACHEABLE:
-               mfc_debug(5, "it is supported only V4L2_MEMORY_MMAP\n");
-               break;
-       case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
-               if (ctx->state >= MFCINST_HEAD_PARSED &&
-                   ctx->state < MFCINST_ABORT) {
-                       ctrl->value = ctx->dpb_count;
-                       break;
-               } else if (ctx->state != MFCINST_INIT) {
-                       mfc_err_ctx("Decoding not initialised\n");
-                       return -EINVAL;
-               }
-
-               /* Should wait for the header to be parsed */
-               if (mfc_wait_for_done_ctx(ctx,
-                               MFC_REG_R2H_CMD_SEQ_DONE_RET)) {
-                       mfc_cleanup_work_bit_and_try_run(ctx);
-                       return -EIO;
-               }
-
-               if (ctx->state >= MFCINST_HEAD_PARSED &&
-                   ctx->state < MFCINST_ABORT) {
-                       ctrl->value = ctx->dpb_count;
-               } else {
-                       mfc_err_ctx("Decoding not initialised\n");
-                       return -EINVAL;
-               }
-               break;
-       case V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE:
-               ctrl->value = dec->slice_enable;
-               break;
-       case V4L2_CID_MPEG_MFC51_VIDEO_PACKED_PB:
-               /* Not used */
-               break;
-       case V4L2_CID_MPEG_MFC51_VIDEO_CRC_ENABLE:
-               ctrl->value = dec->crc_enable;
-               break;
-       case V4L2_CID_MPEG_MFC51_VIDEO_CHECK_STATE:
-               if (ctx->is_dpb_realloc && ctx->state == MFCINST_HEAD_PARSED)
-                       ctrl->value = MFCSTATE_DEC_S3D_REALLOC;
-               else if (ctx->state == MFCINST_RES_CHANGE_FLUSH
-                               || ctx->state == MFCINST_RES_CHANGE_END
-                               || ctx->state == MFCINST_HEAD_PARSED)
-                       ctrl->value = MFCSTATE_DEC_RES_DETECT;
-               else if (ctx->state == MFCINST_FINISHING)
-                       ctrl->value = MFCSTATE_DEC_TERMINATING;
-               else
-                       ctrl->value = MFCSTATE_PROCESSING;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING:
-               ctrl->value = dec->sei_parse;
-               break;
-       case V4L2_CID_MPEG_MFC51_VIDEO_I_FRAME_DECODING:
-               ctrl->value = dec->idr_decoding;
-               break;
-       case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_RATE:
-               ctrl->value = mfc_qos_get_framerate(ctx);
-               break;
-       case V4L2_CID_MPEG_MFC_GET_VERSION_INFO:
-               ctrl->value = dev->pdata->ip_ver;
-               break;
-       case V4L2_CID_MPEG_VIDEO_QOS_RATIO:
-               ctrl->value = ctx->qos_ratio;
-               break;
-       case V4L2_CID_MPEG_MFC_SET_DYNAMIC_DPB_MODE:
-               ctrl->value = dec->is_dynamic_dpb;
-               break;
-       case V4L2_CID_MPEG_MFC_GET_EXT_INFO:
-               ctrl->value = __mfc_dec_ext_info(ctx);
-               break;
-       case V4L2_CID_MPEG_MFC_GET_10BIT_INFO:
-               ctrl->value = ctx->is_10bit;
-               break;
-       case V4L2_CID_MPEG_MFC_GET_DRIVER_INFO:
-               ctrl->value = MFC_DRIVER_INFO;
-               break;
-       default:
-               list_for_each_entry(ctx_ctrl, &ctx->ctrls, list) {
-                       if (!(ctx_ctrl->type & MFC_CTRL_TYPE_GET))
-                               continue;
-
-                       if (ctx_ctrl->id == ctrl->id) {
-                               if (ctx_ctrl->has_new) {
-                                       ctx_ctrl->has_new = 0;
-                                       ctrl->value = ctx_ctrl->val;
-                               } else {
-                                       mfc_debug(5, "[CTRLS] Control value "\
-                                                       "is not up to date: "\
-                                                       "0x%08x\n", ctrl->id);
-                                       return -EINVAL;
-                               }
-
-                               found = 1;
-                               break;
-                       }
-               }
-
-               if (!found) {
-                       mfc_err_ctx("Invalid control: 0x%08x\n", ctrl->id);
-                       return -EINVAL;
-               }
-               break;
-       }
-
-       mfc_debug(5, "[CTRLS] get id: %#x, value: %d\n", ctrl->id, ctrl->value);
-
-       return 0;
-}
-
-/* Get a ctrl */
-static int vidioc_g_ctrl(struct file *file, void *priv,
-                       struct v4l2_control *ctrl)
-{
-       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
-       int ret = 0;
-
-       mfc_debug_enter();
-       ret = __mfc_dec_get_ctrl_val(ctx, ctrl);
-       mfc_debug_leave();
-
-       return ret;
-}
-
-/* Set a ctrl */
-static int vidioc_s_ctrl(struct file *file, void *priv,
-                        struct v4l2_control *ctrl)
-{
-       struct mfc_dev *dev = video_drvdata(file);
-       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
-       struct mfc_dec *dec;
-       struct mfc_ctx_ctrl *ctx_ctrl;
-       int ret = 0;
-       int found = 0;
-
-       mfc_debug_enter();
-
-       if (!dev) {
-               mfc_err_dev("no mfc device to run\n");
-               return -EINVAL;
-       }
-
-       dec = ctx->dec_priv;
-       if (!dec) {
-               mfc_err_dev("no mfc decoder to run\n");
-               return -EINVAL;
-       }
-
-       ret = __mfc_dec_check_ctrl_val(ctx, ctrl);
-       if (ret)
-               return ret;
-
-       mfc_debug(5, "[CTRLS] set id: %#x, value: %d\n", ctrl->id, ctrl->value);
-
-       switch (ctrl->id) {
-       case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER:
-               dec->loop_filter_mpeg4 = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY:
-               dec->display_delay = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE:
-               dec->slice_enable = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC51_VIDEO_PACKED_PB:
-               /* Not used */
-               break;
-       case V4L2_CID_MPEG_MFC51_VIDEO_CRC_ENABLE:
-               dec->crc_enable = ctrl->value;
-               break;
-       case V4L2_CID_CACHEABLE:
-               mfc_debug(5, "it is supported only V4L2_MEMORY_MMAP\n");
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING:
-               dec->sei_parse = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC51_VIDEO_I_FRAME_DECODING:
-               dec->idr_decoding = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_DECODER_IMMEDIATE_DISPLAY:
-               dec->immediate_display = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_DECODER_DECODING_TIMESTAMP_MODE:
-               dec->is_dts_mode = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_DECODER_WAIT_DECODING_START:
-               ctx->wait_state = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC_SET_DUAL_DPB_MODE:
-               mfc_err_dev("[DPB] not supported CID: 0x%x\n",ctrl->id);
-               break;
-       case V4L2_CID_MPEG_VIDEO_QOS_RATIO:
-               ctx->qos_ratio = ctrl->value;
-               mfc_info_ctx("[QoS] set %d qos_ratio\n", ctrl->value);
-               break;
-       case V4L2_CID_MPEG_MFC_SET_DYNAMIC_DPB_MODE:
-               dec->is_dynamic_dpb = ctrl->value;
-               if (dec->is_dynamic_dpb == 0)
-                       mfc_err_dev("[DPB] is_dynamic_dpb is 0. it has to be enabled\n");
-               break;
-       case V4L2_CID_MPEG_MFC_SET_USER_SHARED_HANDLE:
-               if (dec->sh_handle.fd == -1) {
-                       dec->sh_handle.fd = ctrl->value;
-                       if (mfc_mem_get_user_shared_handle(ctx, &dec->sh_handle))
-                               return -EINVAL;
-                       else
-                               mfc_debug(2, "[MEMINFO][DPB] shared handle fd: %d, vaddr: 0x%p\n",
-                                               dec->sh_handle.fd, dec->sh_handle.vaddr);
-               }
-               break;
-       case V4L2_CID_MPEG_MFC_SET_BUF_PROCESS_TYPE:
-               ctx->buf_process_type = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_BLACK_BAR_DETECT:
-               dec->detect_black_bar = ctrl->value;
-               break;
-       default:
-               list_for_each_entry(ctx_ctrl, &ctx->ctrls, list) {
-                       if (!(ctx_ctrl->type & MFC_CTRL_TYPE_SET))
-                               continue;
-
-                       if (ctx_ctrl->id == ctrl->id) {
-                               ctx_ctrl->has_new = 1;
-                               ctx_ctrl->val = ctrl->value;
-
-                               found = 1;
-                               break;
-                       }
-               }
-
-               if (!found) {
-                       mfc_err_ctx("Invalid control: 0x%08x\n", ctrl->id);
-                       return -EINVAL;
-               }
-               break;
-       }
-
-       mfc_debug_leave();
-
-       return 0;
-}
-
-/* Get cropping information */
-static int vidioc_g_crop(struct file *file, void *priv,
-               struct v4l2_crop *cr)
-{
-       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
-       struct mfc_dec *dec = ctx->dec_priv;
-
-       mfc_debug_enter();
-
-       if (!ready_to_get_crop(ctx)) {
-               mfc_debug(2, "ready to get crop failed\n");
-               return -EINVAL;
-       }
-
-       if (ctx->state == MFCINST_RUNNING && dec->detect_black_bar
-                       && dec->black_bar_updated) {
-               cr->c.left = dec->black_bar.left;
-               cr->c.top = dec->black_bar.top;
-               cr->c.width = dec->black_bar.width;
-               cr->c.height = dec->black_bar.height;
-               mfc_debug(2, "[FRAME][BLACKBAR] Cropping info: l=%d t=%d w=%d h=%d\n",
-                               dec->black_bar.left,
-                               dec->black_bar.top,
-                               dec->black_bar.width,
-                               dec->black_bar.height);
-       } else {
-               if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_H264 ||
-                       ctx->src_fmt->fourcc == V4L2_PIX_FMT_HEVC ||
-                       ctx->src_fmt->fourcc == V4L2_PIX_FMT_BPG) {
-                       cr->c.left = dec->cr_left;
-                       cr->c.top = dec->cr_top;
-                       cr->c.width = ctx->img_width - dec->cr_left - dec->cr_right;
-                       cr->c.height = ctx->img_height - dec->cr_top - dec->cr_bot;
-                       mfc_debug(2, "[FRAME] Cropping info: l=%d t=%d " \
-                                       "w=%d h=%d (r=%d b=%d fw=%d fh=%d)\n",
-                                       dec->cr_left, dec->cr_top,
-                                       cr->c.width, cr->c.height,
-                                       dec->cr_right, dec->cr_bot,
-                                       ctx->img_width, ctx->img_height);
-               } else {
-                       cr->c.left = 0;
-                       cr->c.top = 0;
-                       cr->c.width = ctx->img_width;
-                       cr->c.height = ctx->img_height;
-                       mfc_debug(2, "[FRAME] Cropping info: w=%d h=%d fw=%d fh=%d\n",
-                                       cr->c.width, cr->c.height,
-                                       ctx->img_width, ctx->img_height);
-               }
-       }
-
-       mfc_debug_leave();
-       return 0;
-}
-
-static int vidioc_g_ext_ctrls(struct file *file, void *priv,
-                       struct v4l2_ext_controls *f)
-{
-       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
-       struct v4l2_ext_control *ext_ctrl;
-       struct v4l2_control ctrl;
-       int i;
-       int ret = 0;
-
-       if (f->which != V4L2_CTRL_CLASS_MPEG)
-               return -EINVAL;
-
-       for (i = 0; i < f->count; i++) {
-               ext_ctrl = (f->controls + i);
-
-               ctrl.id = ext_ctrl->id;
-
-               ret = __mfc_dec_get_ctrl_val(ctx, &ctrl);
-               if (ret == 0) {
-                       ext_ctrl->value = ctrl.value;
-               } else {
-                       f->error_idx = i;
-                       break;
-               }
-
-               mfc_debug(5, "[CTRLS][%d] id: %#x, value: %d\n",
-                               i, ext_ctrl->id, ext_ctrl->value);
-       }
-
-       return ret;
-}
-
-/* v4l2_ioctl_ops */
-static const struct v4l2_ioctl_ops mfc_dec_ioctl_ops = {
-       .vidioc_querycap                = vidioc_querycap,
-       .vidioc_enum_fmt_vid_cap_mplane = vidioc_enum_fmt_vid_cap_mplane,
-       .vidioc_enum_fmt_vid_out_mplane = vidioc_enum_fmt_vid_out_mplane,
-       .vidioc_g_fmt_vid_cap_mplane    = vidioc_g_fmt_vid_cap_mplane,
-       .vidioc_g_fmt_vid_out_mplane    = vidioc_g_fmt_vid_out_mplane,
-       .vidioc_try_fmt_vid_cap_mplane  = vidioc_try_fmt,
-       .vidioc_try_fmt_vid_out_mplane  = vidioc_try_fmt,
-       .vidioc_s_fmt_vid_cap_mplane    = vidioc_s_fmt_vid_cap_mplane,
-       .vidioc_s_fmt_vid_out_mplane    = vidioc_s_fmt_vid_out_mplane,
-       .vidioc_reqbufs                 = vidioc_reqbufs,
-       .vidioc_querybuf                = vidioc_querybuf,
-       .vidioc_qbuf                    = vidioc_qbuf,
-       .vidioc_dqbuf                   = vidioc_dqbuf,
-       .vidioc_streamon                = vidioc_streamon,
-       .vidioc_streamoff               = vidioc_streamoff,
-       .vidioc_queryctrl               = vidioc_queryctrl,
-       .vidioc_g_ctrl                  = vidioc_g_ctrl,
-       .vidioc_s_ctrl                  = vidioc_s_ctrl,
-       .vidioc_g_crop                  = vidioc_g_crop,
-       .vidioc_g_ext_ctrls             = vidioc_g_ext_ctrls,
-};
-
-const struct v4l2_ioctl_ops *mfc_get_dec_v4l2_ioctl_ops(void)
-{
-       return &mfc_dec_ioctl_ops;
-}
diff --git a/drivers/media/platform/exynos/mfc/mfc_dec.h b/drivers/media/platform/exynos/mfc/mfc_dec.h
deleted file mode 100644 (file)
index b9f9081..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * drivers/media/platform/exynos/mfc/mfc_dec.h
- *
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef __MFC_DEC_H
-#define __MFC_DEC_H __FILE__
-
-#include "mfc_common.h"
-
-const struct v4l2_ioctl_ops *mfc_get_dec_v4l2_ioctl_ops(void);
-
-#endif /* __MFC_DEC_H */
diff --git a/drivers/media/platform/exynos/mfc/mfc_dec_ctrl.c b/drivers/media/platform/exynos/mfc/mfc_dec_ctrl.c
new file mode 100644 (file)
index 0000000..6cbedd7
--- /dev/null
@@ -0,0 +1,896 @@
+/*
+ * drivers/media/platform/exynos/mfc/mfc_dec_ops.c
+ *
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include  "mfc_common.h"
+
+#include "mfc_reg_api.h"
+
+#define NUM_CTRL_CFGS ARRAY_SIZE(mfc_ctrl_list)
+
+struct mfc_ctrl_cfg mfc_ctrl_list[] = {
+       {
+               .type = MFC_CTRL_TYPE_SET,
+               .id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG,
+               .is_volatile = 1,
+               .mode = MFC_CTRL_MODE_SFR,
+               .addr = MFC_REG_D_PICTURE_TAG,
+               .mask = 0xFFFFFFFF,
+               .shft = 0,
+               .flag_mode = MFC_CTRL_MODE_NONE,
+               .flag_addr = 0,
+               .flag_shft = 0,
+       },
+       {
+               .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_D_RET_PICTURE_TAG_TOP,
+               .mask = 0xFFFFFFFF,
+               .shft = 0,
+               .flag_mode = MFC_CTRL_MODE_NONE,
+               .flag_addr = 0,
+               .flag_shft = 0,
+       },
+       {
+               .type = MFC_CTRL_TYPE_GET_DST,
+               .id = V4L2_CID_MPEG_MFC51_VIDEO_DISPLAY_STATUS,
+               .is_volatile = 0,
+               .mode = MFC_CTRL_MODE_SFR,
+               .addr = MFC_REG_D_DISPLAY_STATUS,
+               .mask = 0x7,
+               .shft = 0,
+               .flag_mode = MFC_CTRL_MODE_NONE,
+               .flag_addr = 0,
+               .flag_shft = 0,
+       },
+       /* CRC related definitions are based on non-H.264 type */
+       {
+               .type = MFC_CTRL_TYPE_GET_DST,
+               .id = V4L2_CID_MPEG_MFC51_VIDEO_CRC_DATA_LUMA,
+               .is_volatile = 0,
+               .mode = MFC_CTRL_MODE_SFR,
+               .addr = MFC_REG_D_DISPLAY_FIRST_PLANE_CRC,
+               .mask = 0xFFFFFFFF,
+               .shft = 0,
+               .flag_mode = MFC_CTRL_MODE_NONE,
+               .flag_addr = 0,
+               .flag_shft = 0,
+       },
+       {
+               .type = MFC_CTRL_TYPE_GET_DST,
+               .id = V4L2_CID_MPEG_MFC51_VIDEO_CRC_DATA_CHROMA,
+               .is_volatile = 0,
+               .mode = MFC_CTRL_MODE_SFR,
+               .addr = MFC_REG_D_DISPLAY_SECOND_PLANE_CRC,
+               .mask = 0xFFFFFFFF,
+               .shft = 0,
+               .flag_mode = MFC_CTRL_MODE_NONE,
+               .flag_addr = 0,
+               .flag_shft = 0,
+       },
+       {
+               .type = MFC_CTRL_TYPE_GET_DST,
+               .id = V4L2_CID_MPEG_MFC51_VIDEO_CRC_DATA_CHROMA1,
+               .is_volatile = 0,
+               .mode = MFC_CTRL_MODE_SFR,
+               .addr = MFC_REG_D_DISPLAY_THIRD_PLANE_CRC,
+               .mask = 0xFFFFFFFF,
+               .shft = 0,
+               .flag_mode = MFC_CTRL_MODE_NONE,
+               .flag_addr = 0,
+               .flag_shft = 0,
+       },
+       {
+               .type = MFC_CTRL_TYPE_GET_DST,
+               .id = V4L2_CID_MPEG_MFC51_VIDEO_CRC_DATA_2BIT_LUMA,
+               .is_volatile = 0,
+               .mode = MFC_CTRL_MODE_SFR,
+               .addr = MFC_REG_D_DISPLAY_FIRST_PLANE_2BIT_CRC,
+               .mask = 0xFFFFFFFF,
+               .shft = 0,
+               .flag_mode = MFC_CTRL_MODE_NONE,
+               .flag_addr = 0,
+               .flag_shft = 0,
+       },
+       {
+               .type = MFC_CTRL_TYPE_GET_DST,
+               .id = V4L2_CID_MPEG_MFC51_VIDEO_CRC_DATA_2BIT_CHROMA,
+               .is_volatile = 0,
+               .mode = MFC_CTRL_MODE_SFR,
+               .addr = MFC_REG_D_DISPLAY_SECOND_PLANE_2BIT_CRC,
+               .mask = 0xFFFFFFFF,
+               .shft = 0,
+               .flag_mode = MFC_CTRL_MODE_NONE,
+               .flag_addr = 0,
+               .flag_shft = 0,
+       },
+       {
+               .type = MFC_CTRL_TYPE_GET_DST,
+               .id = V4L2_CID_MPEG_MFC51_VIDEO_CRC_GENERATED,
+               .is_volatile = 0,
+               .mode = MFC_CTRL_MODE_SFR,
+               .addr = MFC_REG_D_DISPLAY_STATUS,
+               .mask = 0x1,
+               .shft = 6,
+               .flag_mode = MFC_CTRL_MODE_NONE,
+               .flag_addr = 0,
+               .flag_shft = 0,
+       },
+       {
+               .type = MFC_CTRL_TYPE_GET_DST,
+               .id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_AVAIL,
+               .is_volatile = 0,
+               .mode = MFC_CTRL_MODE_SFR,
+               .addr = MFC_REG_D_SEI_AVAIL,
+               .mask = 0x1,
+               .shft = 0,
+               .flag_mode = MFC_CTRL_MODE_NONE,
+               .flag_addr = 0,
+               .flag_shft = 0,
+       },
+       {
+               .type = MFC_CTRL_TYPE_GET_DST,
+               .id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRGMENT_ID,
+               .is_volatile = 0,
+               .mode = MFC_CTRL_MODE_SFR,
+               .addr = MFC_REG_D_FRAME_PACK_ARRGMENT_ID,
+               .mask = 0xFFFFFFFF,
+               .shft = 0,
+               .flag_mode = MFC_CTRL_MODE_NONE,
+               .flag_addr = 0,
+               .flag_shft = 0,
+       },
+       {
+               .type = MFC_CTRL_TYPE_GET_DST,
+               .id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_INFO,
+               .is_volatile = 0,
+               .mode = MFC_CTRL_MODE_SFR,
+               .addr = MFC_REG_D_FRAME_PACK_SEI_INFO,
+               .mask = 0x3FFFF,
+               .shft = 0,
+               .flag_mode = MFC_CTRL_MODE_NONE,
+               .flag_addr = 0,
+               .flag_shft = 0,
+       },
+       {
+               .type = MFC_CTRL_TYPE_GET_DST,
+               .id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_GRID_POS,
+               .is_volatile = 0,
+               .mode = MFC_CTRL_MODE_SFR,
+               .addr = MFC_REG_D_FRAME_PACK_GRID_POS,
+               .mask = 0xFFFF,
+               .shft = 0,
+               .flag_mode = MFC_CTRL_MODE_NONE,
+               .flag_addr = 0,
+               .flag_shft = 0,
+       },
+       {
+               .type = MFC_CTRL_TYPE_GET_DST,
+               .id = V4L2_CID_MPEG_VIDEO_H264_MVC_VIEW_ID,
+               .is_volatile = 0,
+               .mode = MFC_CTRL_MODE_SFR,
+               .addr = MFC_REG_D_MVC_VIEW_ID,
+               .mask = 0xFFFF,
+               .shft = 0,
+               .flag_mode = MFC_CTRL_MODE_NONE,
+               .flag_addr = 0,
+               .flag_shft = 0,
+       },
+       {
+               .type = MFC_CTRL_TYPE_GET_DST,
+               .id = V4L2_CID_MPEG_VIDEO_SEI_MAX_PIC_AVERAGE_LIGHT,
+               .is_volatile = 0,
+               .mode = MFC_CTRL_MODE_SFR,
+               .addr = MFC_REG_D_CONTENT_LIGHT_LEVEL_INFO_SEI,
+               .mask = 0xFFFF,
+               .shft = 0,
+               .flag_mode = MFC_CTRL_MODE_NONE,
+               .flag_addr = 0,
+               .flag_shft = 0,
+       },
+       {
+               .type = MFC_CTRL_TYPE_GET_DST,
+               .id = V4L2_CID_MPEG_VIDEO_SEI_MAX_CONTENT_LIGHT,
+               .is_volatile = 0,
+               .mode = MFC_CTRL_MODE_SFR,
+               .addr = MFC_REG_D_CONTENT_LIGHT_LEVEL_INFO_SEI,
+               .mask = 0xFFFF,
+               .shft = 16,
+               .flag_mode = MFC_CTRL_MODE_NONE,
+               .flag_addr = 0,
+               .flag_shft = 0,
+       },
+       {
+               .type = MFC_CTRL_TYPE_GET_DST,
+               .id = V4L2_CID_MPEG_VIDEO_SEI_MAX_DISPLAY_LUMINANCE,
+               .is_volatile = 0,
+               .mode = MFC_CTRL_MODE_SFR,
+               .addr = MFC_REG_D_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_0,
+               .mask = 0xFFFFFFFF,
+               .shft = 0,
+               .flag_mode = MFC_CTRL_MODE_NONE,
+               .flag_addr = 0,
+               .flag_shft = 0,
+       },
+       {
+               .type = MFC_CTRL_TYPE_GET_DST,
+               .id = V4L2_CID_MPEG_VIDEO_SEI_MIN_DISPLAY_LUMINANCE,
+               .is_volatile = 0,
+               .mode = MFC_CTRL_MODE_SFR,
+               .addr = MFC_REG_D_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_1,
+               .mask = 0xFFFFFFFF,
+               .shft = 0,
+               .flag_mode = MFC_CTRL_MODE_NONE,
+               .flag_addr = 0,
+               .flag_shft = 0,
+       },
+       {
+               .type = MFC_CTRL_TYPE_GET_DST,
+               .id = V4L2_CID_MPEG_VIDEO_MATRIX_COEFFICIENTS,
+               .is_volatile = 0,
+               .mode = MFC_CTRL_MODE_SFR,
+               .addr = MFC_REG_D_VIDEO_SIGNAL_TYPE,
+               .mask = 0xFF,
+               .shft = 0,
+               .flag_mode = MFC_CTRL_MODE_NONE,
+               .flag_addr = 0,
+               .flag_shft = 0,
+       },
+       {
+               .type = MFC_CTRL_TYPE_GET_DST,
+               .id = V4L2_CID_MPEG_VIDEO_FORMAT,
+               .is_volatile = 0,
+               .mode = MFC_CTRL_MODE_SFR,
+               .addr = MFC_REG_D_VIDEO_SIGNAL_TYPE,
+               .mask = 0x7,
+               .shft = 26,
+               .flag_mode = MFC_CTRL_MODE_NONE,
+               .flag_addr = 0,
+               .flag_shft = 0,
+       },
+       {
+               .type = MFC_CTRL_TYPE_GET_DST,
+               .id = V4L2_CID_MPEG_VIDEO_FULL_RANGE_FLAG,
+               .is_volatile = 0,
+               .mode = MFC_CTRL_MODE_SFR,
+               .addr = MFC_REG_D_VIDEO_SIGNAL_TYPE,
+               .mask = 0x1,
+               .shft = 25,
+               .flag_mode = MFC_CTRL_MODE_NONE,
+               .flag_addr = 0,
+               .flag_shft = 0,
+       },
+       {
+               .type = MFC_CTRL_TYPE_GET_DST,
+               .id = V4L2_CID_MPEG_VIDEO_COLOUR_PRIMARIES,
+               .is_volatile = 0,
+               .mode = MFC_CTRL_MODE_SFR,
+               .addr = MFC_REG_D_VIDEO_SIGNAL_TYPE,
+               .mask = 0xFF,
+               .shft = 16,
+               .flag_mode = MFC_CTRL_MODE_NONE,
+               .flag_addr = 0,
+               .flag_shft = 0,
+       },
+       {
+               .type = MFC_CTRL_TYPE_GET_DST,
+               .id = V4L2_CID_MPEG_VIDEO_TRANSFER_CHARACTERISTICS,
+               .is_volatile = 0,
+               .mode = MFC_CTRL_MODE_SFR,
+               .addr = MFC_REG_D_VIDEO_SIGNAL_TYPE,
+               .mask = 0xFF,
+               .shft = 8,
+               .flag_mode = MFC_CTRL_MODE_NONE,
+               .flag_addr = 0,
+               .flag_shft = 0,
+       },
+       {
+               .type = MFC_CTRL_TYPE_GET_DST,
+               .id = V4L2_CID_MPEG_VIDEO_SEI_WHITE_POINT,
+               .is_volatile = 0,
+               .mode = MFC_CTRL_MODE_SFR,
+               .addr = MFC_REG_D_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_2,
+               .mask = 0xFFFFFFFF,
+               .shft = 0,
+               .flag_mode = MFC_CTRL_MODE_NONE,
+               .flag_addr = 0,
+               .flag_shft = 0,
+       },
+       {
+               .type = MFC_CTRL_TYPE_GET_DST,
+               .id = V4L2_CID_MPEG_VIDEO_SEI_DISPLAY_PRIMARIES_0,
+               .is_volatile = 0,
+               .mode = MFC_CTRL_MODE_SFR,
+               .addr = MFC_REG_D_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_3,
+               .mask = 0xFFFFFFFF,
+               .shft = 0,
+               .flag_mode = MFC_CTRL_MODE_NONE,
+               .flag_addr = 0,
+               .flag_shft = 0,
+       },
+       {
+               .type = MFC_CTRL_TYPE_GET_DST,
+               .id = V4L2_CID_MPEG_VIDEO_SEI_DISPLAY_PRIMARIES_1,
+               .is_volatile = 0,
+               .mode = MFC_CTRL_MODE_SFR,
+               .addr = MFC_REG_D_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_4,
+               .mask = 0xFFFFFFFF,
+               .shft = 0,
+               .flag_mode = MFC_CTRL_MODE_NONE,
+               .flag_addr = 0,
+               .flag_shft = 0,
+       },
+       {
+               .type = MFC_CTRL_TYPE_GET_DST,
+               .id = V4L2_CID_MPEG_VIDEO_SEI_DISPLAY_PRIMARIES_2,
+               .is_volatile = 0,
+               .mode = MFC_CTRL_MODE_SFR,
+               .addr = MFC_REG_D_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_5,
+               .mask = 0xFFFFFFFF,
+               .shft = 0,
+               .flag_mode = MFC_CTRL_MODE_NONE,
+               .flag_addr = 0,
+               .flag_shft = 0,
+       },
+};
+
+static int mfc_dec_cleanup_ctx_ctrls(struct mfc_ctx *ctx)
+{
+       struct mfc_ctx_ctrl *ctx_ctrl;
+
+       while (!list_empty(&ctx->ctrls)) {
+               ctx_ctrl = list_entry((&ctx->ctrls)->next,
+                                     struct mfc_ctx_ctrl, list);
+               list_del(&ctx_ctrl->list);
+               kfree(ctx_ctrl);
+       }
+
+       INIT_LIST_HEAD(&ctx->ctrls);
+
+       return 0;
+}
+
+static int mfc_dec_init_ctx_ctrls(struct mfc_ctx *ctx)
+{
+       unsigned long i;
+       struct mfc_ctx_ctrl *ctx_ctrl;
+
+       INIT_LIST_HEAD(&ctx->ctrls);
+
+       for (i = 0; i < NUM_CTRL_CFGS; i++) {
+               ctx_ctrl = kzalloc(sizeof(struct mfc_ctx_ctrl), GFP_KERNEL);
+               if (ctx_ctrl == NULL) {
+                       mfc_err_dev("Failed to allocate context control "\
+                                       "id: 0x%08x, type: %d\n",
+                                       mfc_ctrl_list[i].id,
+                                       mfc_ctrl_list[i].type);
+
+                       mfc_dec_cleanup_ctx_ctrls(ctx);
+
+                       return -ENOMEM;
+               }
+
+               ctx_ctrl->type = mfc_ctrl_list[i].type;
+               ctx_ctrl->id = mfc_ctrl_list[i].id;
+               ctx_ctrl->addr = mfc_ctrl_list[i].addr;
+               ctx_ctrl->has_new = 0;
+               ctx_ctrl->val = 0;
+
+               list_add_tail(&ctx_ctrl->list, &ctx->ctrls);
+       }
+
+       return 0;
+}
+
+static void __mfc_dec_remove_buf_ctrls(struct list_head *head)
+{
+       struct mfc_buf_ctrl *buf_ctrl;
+
+       while (!list_empty(head)) {
+               buf_ctrl = list_entry(head->next,
+                               struct mfc_buf_ctrl, list);
+               list_del(&buf_ctrl->list);
+               kfree(buf_ctrl);
+       }
+
+       INIT_LIST_HEAD(head);
+}
+
+static void mfc_dec_reset_buf_ctrls(struct list_head *head)
+{
+       struct mfc_buf_ctrl *buf_ctrl;
+
+       list_for_each_entry(buf_ctrl, head, list) {
+               buf_ctrl->has_new = 0;
+               buf_ctrl->val = 0;
+               buf_ctrl->old_val = 0;
+               buf_ctrl->updated = 0;
+       }
+}
+
+static int mfc_dec_init_buf_ctrls(struct mfc_ctx *ctx,
+       enum mfc_ctrl_type type, unsigned int index)
+{
+       unsigned long i;
+       struct mfc_ctx_ctrl *ctx_ctrl;
+       struct mfc_buf_ctrl *buf_ctrl;
+       struct list_head *head;
+
+       if (index >= MFC_MAX_BUFFERS) {
+               mfc_err_dev("Per-buffer control index is out of range\n");
+               return -EINVAL;
+       }
+
+       if (type & MFC_CTRL_TYPE_SRC) {
+               if (test_bit(index, &ctx->src_ctrls_avail)) {
+                       mfc_dec_reset_buf_ctrls(&ctx->src_ctrls[index]);
+
+                       return 0;
+               }
+
+               head = &ctx->src_ctrls[index];
+       } else if (type & MFC_CTRL_TYPE_DST) {
+               if (test_bit(index, &ctx->dst_ctrls_avail)) {
+                       mfc_dec_reset_buf_ctrls(&ctx->dst_ctrls[index]);
+
+                       return 0;
+               }
+
+               head = &ctx->dst_ctrls[index];
+       } else {
+               mfc_err_dev("Control type mismatch. type : %d\n", type);
+               return -EINVAL;
+       }
+
+       INIT_LIST_HEAD(head);
+
+       list_for_each_entry(ctx_ctrl, &ctx->ctrls, list) {
+               if (!(type & ctx_ctrl->type))
+                       continue;
+
+               /* find matched control configuration index */
+               for (i = 0; i < NUM_CTRL_CFGS; i++) {
+                       if (ctx_ctrl->id == mfc_ctrl_list[i].id)
+                               break;
+               }
+
+               if (i == NUM_CTRL_CFGS) {
+                       mfc_err_dev("Failed to find buffer control "\
+                                       "id: 0x%08x, type: %d\n",
+                                       ctx_ctrl->id, ctx_ctrl->type);
+                       continue;
+               }
+
+               buf_ctrl = kzalloc(sizeof(struct mfc_buf_ctrl), GFP_KERNEL);
+               if (buf_ctrl == NULL) {
+                       mfc_err_dev("Failed to allocate buffer control "\
+                                       "id: 0x%08x, type: %d\n",
+                                       mfc_ctrl_list[i].id,
+                                       mfc_ctrl_list[i].type);
+
+                       __mfc_dec_remove_buf_ctrls(head);
+
+                       return -ENOMEM;
+               }
+
+               buf_ctrl->id = ctx_ctrl->id;
+               buf_ctrl->type = ctx_ctrl->type;
+               buf_ctrl->addr = ctx_ctrl->addr;
+
+               buf_ctrl->is_volatile = mfc_ctrl_list[i].is_volatile;
+               buf_ctrl->mode = mfc_ctrl_list[i].mode;
+               buf_ctrl->mask = mfc_ctrl_list[i].mask;
+               buf_ctrl->shft = mfc_ctrl_list[i].shft;
+               buf_ctrl->flag_mode = mfc_ctrl_list[i].flag_mode;
+               buf_ctrl->flag_addr = mfc_ctrl_list[i].flag_addr;
+               buf_ctrl->flag_shft = mfc_ctrl_list[i].flag_shft;
+
+               list_add_tail(&buf_ctrl->list, head);
+       }
+
+       mfc_dec_reset_buf_ctrls(head);
+
+       if (type & MFC_CTRL_TYPE_SRC)
+               set_bit(index, &ctx->src_ctrls_avail);
+       else
+               set_bit(index, &ctx->dst_ctrls_avail);
+
+       return 0;
+}
+
+static int mfc_dec_cleanup_buf_ctrls(struct mfc_ctx *ctx,
+       enum mfc_ctrl_type type, unsigned int index)
+{
+       struct list_head *head;
+
+       if (index >= MFC_MAX_BUFFERS) {
+               mfc_err_dev("Per-buffer control index is out of range\n");
+               return -EINVAL;
+       }
+
+       if (type & MFC_CTRL_TYPE_SRC) {
+               if (!(test_and_clear_bit(index, &ctx->src_ctrls_avail))) {
+                       return 0;
+               }
+
+               head = &ctx->src_ctrls[index];
+       } else if (type & MFC_CTRL_TYPE_DST) {
+               if (!(test_and_clear_bit(index, &ctx->dst_ctrls_avail))) {
+                       return 0;
+               }
+
+               head = &ctx->dst_ctrls[index];
+       } else {
+               mfc_err_dev("Control type mismatch. type : %d\n", type);
+               return -EINVAL;
+       }
+
+       __mfc_dec_remove_buf_ctrls(head);
+
+       return 0;
+}
+
+static int mfc_dec_to_buf_ctrls(struct mfc_ctx *ctx, struct list_head *head)
+{
+       struct mfc_ctx_ctrl *ctx_ctrl;
+       struct mfc_buf_ctrl *buf_ctrl;
+
+       list_for_each_entry(ctx_ctrl, &ctx->ctrls, list) {
+               if (!(ctx_ctrl->type & MFC_CTRL_TYPE_SET) || !ctx_ctrl->has_new)
+                       continue;
+
+               list_for_each_entry(buf_ctrl, head, list) {
+                       if (!(buf_ctrl->type & MFC_CTRL_TYPE_SET))
+                               continue;
+
+                       if (buf_ctrl->id == ctx_ctrl->id) {
+                               buf_ctrl->has_new = 1;
+                               buf_ctrl->val = ctx_ctrl->val;
+                               if (buf_ctrl->is_volatile)
+                                       buf_ctrl->updated = 0;
+
+                               ctx_ctrl->has_new = 0;
+                               break;
+                       }
+               }
+       }
+
+       return 0;
+}
+
+static int mfc_dec_to_ctx_ctrls(struct mfc_ctx *ctx, struct list_head *head)
+{
+       struct mfc_ctx_ctrl *ctx_ctrl;
+       struct mfc_buf_ctrl *buf_ctrl;
+
+       list_for_each_entry(buf_ctrl, head, list) {
+               if (!(buf_ctrl->type & MFC_CTRL_TYPE_GET) || !buf_ctrl->has_new)
+                       continue;
+
+               list_for_each_entry(ctx_ctrl, &ctx->ctrls, list) {
+                       if (!(ctx_ctrl->type & MFC_CTRL_TYPE_GET))
+                               continue;
+
+                       if (ctx_ctrl->id == buf_ctrl->id) {
+                               ctx_ctrl->has_new = 1;
+                               ctx_ctrl->val = buf_ctrl->val;
+
+                               buf_ctrl->has_new = 0;
+                       }
+               }
+       }
+
+       return 0;
+}
+
+static int mfc_dec_set_buf_ctrls_val(struct mfc_ctx *ctx, struct list_head *head)
+{
+       struct mfc_buf_ctrl *buf_ctrl;
+       struct mfc_dec *dec = ctx->dec_priv;
+       struct mfc_dev *dev = ctx->dev;
+       unsigned int value = 0;
+
+       list_for_each_entry(buf_ctrl, head, list) {
+               if (!(buf_ctrl->type & MFC_CTRL_TYPE_SET) || !buf_ctrl->has_new)
+                       continue;
+
+               /* read old vlaue */
+               value = MFC_READL(buf_ctrl->addr);
+
+               /* save old vlaue for recovery */
+               if (buf_ctrl->is_volatile)
+                       buf_ctrl->old_val = (value >> buf_ctrl->shft) & buf_ctrl->mask;
+
+               /* write new value */
+               value &= ~(buf_ctrl->mask << buf_ctrl->shft);
+               value |= ((buf_ctrl->val & buf_ctrl->mask) << buf_ctrl->shft);
+               MFC_WRITEL(value, buf_ctrl->addr);
+
+               /* set change flag bit */
+               if (buf_ctrl->flag_mode == MFC_CTRL_MODE_SFR) {
+                       value = MFC_READL(buf_ctrl->flag_addr);
+                       value |= (1 << buf_ctrl->flag_shft);
+                       MFC_WRITEL(value, buf_ctrl->flag_addr);
+               }
+
+               buf_ctrl->has_new = 0;
+               buf_ctrl->updated = 1;
+
+               if (buf_ctrl->id == V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG)
+                       dec->stored_tag = buf_ctrl->val;
+
+               mfc_debug(6, "[CTRLS] Set buffer control id: 0x%08x, val: %d\n",
+                               buf_ctrl->id, buf_ctrl->val);
+       }
+
+       return 0;
+}
+
+static int mfc_dec_get_buf_ctrls_val(struct mfc_ctx *ctx, struct list_head *head)
+{
+       struct mfc_buf_ctrl *buf_ctrl;
+       struct mfc_dev *dev = ctx->dev;
+       struct mfc_dec *dec = ctx->dec_priv;
+       unsigned int value = 0;
+
+       list_for_each_entry(buf_ctrl, head, list) {
+               if (!(buf_ctrl->type & MFC_CTRL_TYPE_GET))
+                       continue;
+
+               value = MFC_READL(buf_ctrl->addr);
+               value = (value >> buf_ctrl->shft) & buf_ctrl->mask;
+
+               buf_ctrl->val = value;
+               buf_ctrl->has_new = 1;
+
+               if (IS_VP9_DEC(ctx)) {
+                       if (buf_ctrl->id == V4L2_CID_MPEG_VIDEO_FULL_RANGE_FLAG)
+                               buf_ctrl->val = dec->color_range;
+                       else if (buf_ctrl->id == V4L2_CID_MPEG_VIDEO_COLOUR_PRIMARIES)
+                               buf_ctrl->val = dec->color_space;
+               }
+
+               mfc_debug(6, "[CTRLS] Get buffer control id: 0x%08x, val: %d\n",
+                               buf_ctrl->id, buf_ctrl->val);
+       }
+
+       return 0;
+}
+
+static int mfc_dec_set_buf_ctrls_val_nal_q_dec(struct mfc_ctx *ctx,
+                       struct list_head *head, DecoderInputStr *pInStr)
+{
+       struct mfc_buf_ctrl *buf_ctrl;
+       struct mfc_dec *dec = ctx->dec_priv;
+
+       mfc_debug_enter();
+
+       list_for_each_entry(buf_ctrl, head, list) {
+               if (!(buf_ctrl->type & MFC_CTRL_TYPE_SET) || !buf_ctrl->has_new)
+                       continue;
+               switch (buf_ctrl->id) {
+               case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG:
+                       pInStr->PictureTag &= ~(buf_ctrl->mask << buf_ctrl->shft);
+                       pInStr->PictureTag |=
+                               (buf_ctrl->val & buf_ctrl->mask) << buf_ctrl->shft;
+                       dec->stored_tag = buf_ctrl->val;
+                       break;
+               /* If new dynamic controls are added, insert here */
+               default:
+                       mfc_info_ctx("[NALQ] can't find control, id: 0x%x\n",
+                                       buf_ctrl->id);
+               }
+               buf_ctrl->has_new = 0;
+               buf_ctrl->updated = 1;
+
+               mfc_debug(6, "[NALQ][CTRLS] Set buffer control id: 0x%08x, val: %d\n",
+                               buf_ctrl->id, buf_ctrl->val);
+       }
+
+       mfc_debug_leave();
+
+       return 0;
+}
+
+static int mfc_dec_get_buf_ctrls_val_nal_q_dec(struct mfc_ctx *ctx,
+                       struct list_head *head, DecoderOutputStr *pOutStr)
+{
+       struct mfc_dec *dec = ctx->dec_priv;
+       struct mfc_buf_ctrl *buf_ctrl;
+       unsigned int value = 0;
+
+       mfc_debug_enter();
+
+       list_for_each_entry(buf_ctrl, head, list) {
+               if (!(buf_ctrl->type & MFC_CTRL_TYPE_GET))
+                       continue;
+               switch (buf_ctrl->id) {
+               case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG:
+                       value = pOutStr->PictureTagTop;
+                       break;
+               case V4L2_CID_MPEG_MFC51_VIDEO_DISPLAY_STATUS:
+                       value = pOutStr->DisplayStatus;
+                       break;
+               case V4L2_CID_MPEG_MFC51_VIDEO_CRC_DATA_LUMA:
+                       value = pOutStr->DisplayFirstCrc;
+                       break;
+               case V4L2_CID_MPEG_MFC51_VIDEO_CRC_DATA_CHROMA:
+                       value = pOutStr->DisplaySecondCrc;
+                       break;
+               case V4L2_CID_MPEG_MFC51_VIDEO_CRC_DATA_CHROMA1:
+                       value = pOutStr->DisplayThirdCrc;
+                       break;
+               case V4L2_CID_MPEG_MFC51_VIDEO_CRC_DATA_2BIT_LUMA:
+                       value = pOutStr->DisplayFirst2BitCrc;
+                       break;
+               case V4L2_CID_MPEG_MFC51_VIDEO_CRC_DATA_2BIT_CHROMA:
+                       value = pOutStr->DisplaySecond2BitCrc;
+                       break;
+               case V4L2_CID_MPEG_MFC51_VIDEO_CRC_GENERATED:
+                       value = pOutStr->DisplayStatus;
+                       break;
+               case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_AVAIL:
+                       value = pOutStr->SeiAvail;
+                       break;
+               case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRGMENT_ID:
+                       value = pOutStr->FramePackArrgmentId;
+                       break;
+               case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_INFO:
+                       value = pOutStr->FramePackSeiInfo;
+                       break;
+               case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_GRID_POS:
+                       value = pOutStr->FramePackGridPos;
+                       break;
+               case V4L2_CID_MPEG_VIDEO_H264_MVC_VIEW_ID:
+                       value = 0;
+                       break;
+               /* TO-DO: SEI information has to be added in NAL-Q */
+               case V4L2_CID_MPEG_VIDEO_SEI_MAX_PIC_AVERAGE_LIGHT:
+               case V4L2_CID_MPEG_VIDEO_SEI_MAX_CONTENT_LIGHT:
+                       value = pOutStr->ContentLightLevelInfoSei;
+                       break;
+               case V4L2_CID_MPEG_VIDEO_SEI_MAX_DISPLAY_LUMINANCE:
+                       value = pOutStr->MasteringDisplayColourVolumeSei0;
+                       break;
+               case V4L2_CID_MPEG_VIDEO_SEI_MIN_DISPLAY_LUMINANCE:
+                       value = pOutStr->MasteringDisplayColourVolumeSei1;
+                       break;
+               case V4L2_CID_MPEG_VIDEO_FULL_RANGE_FLAG:
+               case V4L2_CID_MPEG_VIDEO_COLOUR_PRIMARIES:
+               case V4L2_CID_MPEG_VIDEO_FORMAT:
+               case V4L2_CID_MPEG_VIDEO_TRANSFER_CHARACTERISTICS:
+               case V4L2_CID_MPEG_VIDEO_MATRIX_COEFFICIENTS:
+                       value = pOutStr->VideoSignalType;
+                       break;
+               case V4L2_CID_MPEG_VIDEO_SEI_WHITE_POINT:
+                       value = pOutStr->MasteringDisplayColourVolumeSei2;
+                       break;
+               case V4L2_CID_MPEG_VIDEO_SEI_DISPLAY_PRIMARIES_0:
+                       value = pOutStr->MasteringDisplayColourVolumeSei3;
+                       break;
+               case V4L2_CID_MPEG_VIDEO_SEI_DISPLAY_PRIMARIES_1:
+                       value = pOutStr->MasteringDisplayColourVolumeSei4;
+                       break;
+               case V4L2_CID_MPEG_VIDEO_SEI_DISPLAY_PRIMARIES_2:
+                       value = pOutStr->MasteringDisplayColourVolumeSei5;
+                       break;
+                       /* If new dynamic controls are added, insert here */
+               default:
+                       mfc_info_ctx("[NALQ] can't find control, id: 0x%x\n",
+                                       buf_ctrl->id);
+               }
+               value = (value >> buf_ctrl->shft) & buf_ctrl->mask;
+
+               buf_ctrl->val = value;
+               buf_ctrl->has_new = 1;
+
+               if (IS_VP9_DEC(ctx)) {
+                       if (buf_ctrl->id == V4L2_CID_MPEG_VIDEO_FULL_RANGE_FLAG)
+                               buf_ctrl->val = dec->color_range;
+                       else if (buf_ctrl->id == V4L2_CID_MPEG_VIDEO_COLOUR_PRIMARIES)
+                               buf_ctrl->val = dec->color_space;
+               }
+
+               mfc_debug(6, "[NALQ][CTRLS] Get buffer control id: 0x%08x, val: %d\n",
+                               buf_ctrl->id, buf_ctrl->val);
+       }
+
+       mfc_debug_leave();
+
+       return 0;
+}
+
+static int mfc_dec_recover_buf_ctrls_val(struct mfc_ctx *ctx, struct list_head *head)
+{
+       struct mfc_buf_ctrl *buf_ctrl;
+       struct mfc_dev *dev = ctx->dev;
+       unsigned int value = 0;
+
+       list_for_each_entry(buf_ctrl, head, list) {
+               if (!(buf_ctrl->type & MFC_CTRL_TYPE_SET)
+                       || !buf_ctrl->is_volatile
+                       || !buf_ctrl->updated)
+                       continue;
+
+               value = MFC_READL(buf_ctrl->addr);
+               value &= ~(buf_ctrl->mask << buf_ctrl->shft);
+               value |= ((buf_ctrl->old_val & buf_ctrl->mask) << buf_ctrl->shft);
+               MFC_WRITEL(value, buf_ctrl->addr);
+
+               /* clear change flag bit */
+               if (buf_ctrl->flag_mode == MFC_CTRL_MODE_SFR) {
+                       value = MFC_READL(buf_ctrl->flag_addr);
+                       value &= ~(1 << buf_ctrl->flag_shft);
+                       MFC_WRITEL(value, buf_ctrl->flag_addr);
+               }
+
+               buf_ctrl->updated = 0;
+               mfc_debug(6, "[CTRLS] Recover buffer control id: 0x%08x, old val: %d\n",
+                               buf_ctrl->id, buf_ctrl->old_val);
+       }
+
+       return 0;
+}
+
+static int mfc_dec_get_buf_update_val(struct mfc_ctx *ctx,
+                       struct list_head *head, unsigned int id, int value)
+{
+       struct mfc_buf_ctrl *buf_ctrl;
+
+       list_for_each_entry(buf_ctrl, head, list) {
+               if (buf_ctrl->id == id) {
+                       buf_ctrl->val = value;
+                       mfc_debug(6, "[CTRLS] Update buffer control id: 0x%08x, val: %d\n",
+                                       buf_ctrl->id, buf_ctrl->val);
+                       break;
+               }
+       }
+
+       return 0;
+}
+
+static int mfc_dec_recover_buf_ctrls_nal_q(struct mfc_ctx *ctx,
+               struct list_head *head)
+{
+       struct mfc_buf_ctrl *buf_ctrl;
+
+       list_for_each_entry(buf_ctrl, head, list) {
+               if (!(buf_ctrl->type & MFC_CTRL_TYPE_SET)
+                               || !(buf_ctrl->updated))
+                       continue;
+
+               buf_ctrl->has_new = 1;
+               buf_ctrl->updated = 0;
+               mfc_debug(6, "[NALQ][CTRLS] Recover buffer control id: 0x%08x, val: %d\n",
+                               buf_ctrl->id, buf_ctrl->val);
+       }
+
+       return 0;
+}
+
+struct mfc_ctrls_ops decoder_ctrls_ops = {
+       .init_ctx_ctrls                 = mfc_dec_init_ctx_ctrls,
+       .cleanup_ctx_ctrls              = mfc_dec_cleanup_ctx_ctrls,
+       .init_buf_ctrls                 = mfc_dec_init_buf_ctrls,
+       .reset_buf_ctrls                = mfc_dec_reset_buf_ctrls,
+       .cleanup_buf_ctrls              = mfc_dec_cleanup_buf_ctrls,
+       .to_buf_ctrls                   = mfc_dec_to_buf_ctrls,
+       .to_ctx_ctrls                   = mfc_dec_to_ctx_ctrls,
+       .set_buf_ctrls_val              = mfc_dec_set_buf_ctrls_val,
+       .get_buf_ctrls_val              = mfc_dec_get_buf_ctrls_val,
+       .set_buf_ctrls_val_nal_q_dec    = mfc_dec_set_buf_ctrls_val_nal_q_dec,
+       .get_buf_ctrls_val_nal_q_dec    = mfc_dec_get_buf_ctrls_val_nal_q_dec,
+       .recover_buf_ctrls_val          = mfc_dec_recover_buf_ctrls_val,
+       .get_buf_update_val             = mfc_dec_get_buf_update_val,
+       .recover_buf_ctrls_nal_q        = mfc_dec_recover_buf_ctrls_nal_q,
+};
diff --git a/drivers/media/platform/exynos/mfc/mfc_dec_ops.c b/drivers/media/platform/exynos/mfc/mfc_dec_ops.c
deleted file mode 100644 (file)
index cbc0bfc..0000000
+++ /dev/null
@@ -1,896 +0,0 @@
-/*
- * drivers/media/platform/exynos/mfc/mfc_dec_ops.c
- *
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include  "mfc_common.h"
-
-#include "mfc_reg.h"
-
-#define NUM_CTRL_CFGS ARRAY_SIZE(mfc_ctrl_list)
-
-struct mfc_ctrl_cfg mfc_ctrl_list[] = {
-       {
-               .type = MFC_CTRL_TYPE_SET,
-               .id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG,
-               .is_volatile = 1,
-               .mode = MFC_CTRL_MODE_SFR,
-               .addr = MFC_REG_D_PICTURE_TAG,
-               .mask = 0xFFFFFFFF,
-               .shft = 0,
-               .flag_mode = MFC_CTRL_MODE_NONE,
-               .flag_addr = 0,
-               .flag_shft = 0,
-       },
-       {
-               .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_D_RET_PICTURE_TAG_TOP,
-               .mask = 0xFFFFFFFF,
-               .shft = 0,
-               .flag_mode = MFC_CTRL_MODE_NONE,
-               .flag_addr = 0,
-               .flag_shft = 0,
-       },
-       {
-               .type = MFC_CTRL_TYPE_GET_DST,
-               .id = V4L2_CID_MPEG_MFC51_VIDEO_DISPLAY_STATUS,
-               .is_volatile = 0,
-               .mode = MFC_CTRL_MODE_SFR,
-               .addr = MFC_REG_D_DISPLAY_STATUS,
-               .mask = 0x7,
-               .shft = 0,
-               .flag_mode = MFC_CTRL_MODE_NONE,
-               .flag_addr = 0,
-               .flag_shft = 0,
-       },
-       /* CRC related definitions are based on non-H.264 type */
-       {
-               .type = MFC_CTRL_TYPE_GET_DST,
-               .id = V4L2_CID_MPEG_MFC51_VIDEO_CRC_DATA_LUMA,
-               .is_volatile = 0,
-               .mode = MFC_CTRL_MODE_SFR,
-               .addr = MFC_REG_D_DISPLAY_FIRST_PLANE_CRC,
-               .mask = 0xFFFFFFFF,
-               .shft = 0,
-               .flag_mode = MFC_CTRL_MODE_NONE,
-               .flag_addr = 0,
-               .flag_shft = 0,
-       },
-       {
-               .type = MFC_CTRL_TYPE_GET_DST,
-               .id = V4L2_CID_MPEG_MFC51_VIDEO_CRC_DATA_CHROMA,
-               .is_volatile = 0,
-               .mode = MFC_CTRL_MODE_SFR,
-               .addr = MFC_REG_D_DISPLAY_SECOND_PLANE_CRC,
-               .mask = 0xFFFFFFFF,
-               .shft = 0,
-               .flag_mode = MFC_CTRL_MODE_NONE,
-               .flag_addr = 0,
-               .flag_shft = 0,
-       },
-       {
-               .type = MFC_CTRL_TYPE_GET_DST,
-               .id = V4L2_CID_MPEG_MFC51_VIDEO_CRC_DATA_CHROMA1,
-               .is_volatile = 0,
-               .mode = MFC_CTRL_MODE_SFR,
-               .addr = MFC_REG_D_DISPLAY_THIRD_PLANE_CRC,
-               .mask = 0xFFFFFFFF,
-               .shft = 0,
-               .flag_mode = MFC_CTRL_MODE_NONE,
-               .flag_addr = 0,
-               .flag_shft = 0,
-       },
-       {
-               .type = MFC_CTRL_TYPE_GET_DST,
-               .id = V4L2_CID_MPEG_MFC51_VIDEO_CRC_DATA_2BIT_LUMA,
-               .is_volatile = 0,
-               .mode = MFC_CTRL_MODE_SFR,
-               .addr = MFC_REG_D_DISPLAY_FIRST_PLANE_2BIT_CRC,
-               .mask = 0xFFFFFFFF,
-               .shft = 0,
-               .flag_mode = MFC_CTRL_MODE_NONE,
-               .flag_addr = 0,
-               .flag_shft = 0,
-       },
-       {
-               .type = MFC_CTRL_TYPE_GET_DST,
-               .id = V4L2_CID_MPEG_MFC51_VIDEO_CRC_DATA_2BIT_CHROMA,
-               .is_volatile = 0,
-               .mode = MFC_CTRL_MODE_SFR,
-               .addr = MFC_REG_D_DISPLAY_SECOND_PLANE_2BIT_CRC,
-               .mask = 0xFFFFFFFF,
-               .shft = 0,
-               .flag_mode = MFC_CTRL_MODE_NONE,
-               .flag_addr = 0,
-               .flag_shft = 0,
-       },
-       {
-               .type = MFC_CTRL_TYPE_GET_DST,
-               .id = V4L2_CID_MPEG_MFC51_VIDEO_CRC_GENERATED,
-               .is_volatile = 0,
-               .mode = MFC_CTRL_MODE_SFR,
-               .addr = MFC_REG_D_DISPLAY_STATUS,
-               .mask = 0x1,
-               .shft = 6,
-               .flag_mode = MFC_CTRL_MODE_NONE,
-               .flag_addr = 0,
-               .flag_shft = 0,
-       },
-       {
-               .type = MFC_CTRL_TYPE_GET_DST,
-               .id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_AVAIL,
-               .is_volatile = 0,
-               .mode = MFC_CTRL_MODE_SFR,
-               .addr = MFC_REG_D_SEI_AVAIL,
-               .mask = 0x1,
-               .shft = 0,
-               .flag_mode = MFC_CTRL_MODE_NONE,
-               .flag_addr = 0,
-               .flag_shft = 0,
-       },
-       {
-               .type = MFC_CTRL_TYPE_GET_DST,
-               .id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRGMENT_ID,
-               .is_volatile = 0,
-               .mode = MFC_CTRL_MODE_SFR,
-               .addr = MFC_REG_D_FRAME_PACK_ARRGMENT_ID,
-               .mask = 0xFFFFFFFF,
-               .shft = 0,
-               .flag_mode = MFC_CTRL_MODE_NONE,
-               .flag_addr = 0,
-               .flag_shft = 0,
-       },
-       {
-               .type = MFC_CTRL_TYPE_GET_DST,
-               .id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_INFO,
-               .is_volatile = 0,
-               .mode = MFC_CTRL_MODE_SFR,
-               .addr = MFC_REG_D_FRAME_PACK_SEI_INFO,
-               .mask = 0x3FFFF,
-               .shft = 0,
-               .flag_mode = MFC_CTRL_MODE_NONE,
-               .flag_addr = 0,
-               .flag_shft = 0,
-       },
-       {
-               .type = MFC_CTRL_TYPE_GET_DST,
-               .id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_GRID_POS,
-               .is_volatile = 0,
-               .mode = MFC_CTRL_MODE_SFR,
-               .addr = MFC_REG_D_FRAME_PACK_GRID_POS,
-               .mask = 0xFFFF,
-               .shft = 0,
-               .flag_mode = MFC_CTRL_MODE_NONE,
-               .flag_addr = 0,
-               .flag_shft = 0,
-       },
-       {
-               .type = MFC_CTRL_TYPE_GET_DST,
-               .id = V4L2_CID_MPEG_VIDEO_H264_MVC_VIEW_ID,
-               .is_volatile = 0,
-               .mode = MFC_CTRL_MODE_SFR,
-               .addr = MFC_REG_D_MVC_VIEW_ID,
-               .mask = 0xFFFF,
-               .shft = 0,
-               .flag_mode = MFC_CTRL_MODE_NONE,
-               .flag_addr = 0,
-               .flag_shft = 0,
-       },
-       {
-               .type = MFC_CTRL_TYPE_GET_DST,
-               .id = V4L2_CID_MPEG_VIDEO_SEI_MAX_PIC_AVERAGE_LIGHT,
-               .is_volatile = 0,
-               .mode = MFC_CTRL_MODE_SFR,
-               .addr = MFC_REG_D_CONTENT_LIGHT_LEVEL_INFO_SEI,
-               .mask = 0xFFFF,
-               .shft = 0,
-               .flag_mode = MFC_CTRL_MODE_NONE,
-               .flag_addr = 0,
-               .flag_shft = 0,
-       },
-       {
-               .type = MFC_CTRL_TYPE_GET_DST,
-               .id = V4L2_CID_MPEG_VIDEO_SEI_MAX_CONTENT_LIGHT,
-               .is_volatile = 0,
-               .mode = MFC_CTRL_MODE_SFR,
-               .addr = MFC_REG_D_CONTENT_LIGHT_LEVEL_INFO_SEI,
-               .mask = 0xFFFF,
-               .shft = 16,
-               .flag_mode = MFC_CTRL_MODE_NONE,
-               .flag_addr = 0,
-               .flag_shft = 0,
-       },
-       {
-               .type = MFC_CTRL_TYPE_GET_DST,
-               .id = V4L2_CID_MPEG_VIDEO_SEI_MAX_DISPLAY_LUMINANCE,
-               .is_volatile = 0,
-               .mode = MFC_CTRL_MODE_SFR,
-               .addr = MFC_REG_D_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_0,
-               .mask = 0xFFFFFFFF,
-               .shft = 0,
-               .flag_mode = MFC_CTRL_MODE_NONE,
-               .flag_addr = 0,
-               .flag_shft = 0,
-       },
-       {
-               .type = MFC_CTRL_TYPE_GET_DST,
-               .id = V4L2_CID_MPEG_VIDEO_SEI_MIN_DISPLAY_LUMINANCE,
-               .is_volatile = 0,
-               .mode = MFC_CTRL_MODE_SFR,
-               .addr = MFC_REG_D_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_1,
-               .mask = 0xFFFFFFFF,
-               .shft = 0,
-               .flag_mode = MFC_CTRL_MODE_NONE,
-               .flag_addr = 0,
-               .flag_shft = 0,
-       },
-       {
-               .type = MFC_CTRL_TYPE_GET_DST,
-               .id = V4L2_CID_MPEG_VIDEO_MATRIX_COEFFICIENTS,
-               .is_volatile = 0,
-               .mode = MFC_CTRL_MODE_SFR,
-               .addr = MFC_REG_D_VIDEO_SIGNAL_TYPE,
-               .mask = 0xFF,
-               .shft = 0,
-               .flag_mode = MFC_CTRL_MODE_NONE,
-               .flag_addr = 0,
-               .flag_shft = 0,
-       },
-       {
-               .type = MFC_CTRL_TYPE_GET_DST,
-               .id = V4L2_CID_MPEG_VIDEO_FORMAT,
-               .is_volatile = 0,
-               .mode = MFC_CTRL_MODE_SFR,
-               .addr = MFC_REG_D_VIDEO_SIGNAL_TYPE,
-               .mask = 0x7,
-               .shft = 26,
-               .flag_mode = MFC_CTRL_MODE_NONE,
-               .flag_addr = 0,
-               .flag_shft = 0,
-       },
-       {
-               .type = MFC_CTRL_TYPE_GET_DST,
-               .id = V4L2_CID_MPEG_VIDEO_FULL_RANGE_FLAG,
-               .is_volatile = 0,
-               .mode = MFC_CTRL_MODE_SFR,
-               .addr = MFC_REG_D_VIDEO_SIGNAL_TYPE,
-               .mask = 0x1,
-               .shft = 25,
-               .flag_mode = MFC_CTRL_MODE_NONE,
-               .flag_addr = 0,
-               .flag_shft = 0,
-       },
-       {
-               .type = MFC_CTRL_TYPE_GET_DST,
-               .id = V4L2_CID_MPEG_VIDEO_COLOUR_PRIMARIES,
-               .is_volatile = 0,
-               .mode = MFC_CTRL_MODE_SFR,
-               .addr = MFC_REG_D_VIDEO_SIGNAL_TYPE,
-               .mask = 0xFF,
-               .shft = 16,
-               .flag_mode = MFC_CTRL_MODE_NONE,
-               .flag_addr = 0,
-               .flag_shft = 0,
-       },
-       {
-               .type = MFC_CTRL_TYPE_GET_DST,
-               .id = V4L2_CID_MPEG_VIDEO_TRANSFER_CHARACTERISTICS,
-               .is_volatile = 0,
-               .mode = MFC_CTRL_MODE_SFR,
-               .addr = MFC_REG_D_VIDEO_SIGNAL_TYPE,
-               .mask = 0xFF,
-               .shft = 8,
-               .flag_mode = MFC_CTRL_MODE_NONE,
-               .flag_addr = 0,
-               .flag_shft = 0,
-       },
-       {
-               .type = MFC_CTRL_TYPE_GET_DST,
-               .id = V4L2_CID_MPEG_VIDEO_SEI_WHITE_POINT,
-               .is_volatile = 0,
-               .mode = MFC_CTRL_MODE_SFR,
-               .addr = MFC_REG_D_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_2,
-               .mask = 0xFFFFFFFF,
-               .shft = 0,
-               .flag_mode = MFC_CTRL_MODE_NONE,
-               .flag_addr = 0,
-               .flag_shft = 0,
-       },
-       {
-               .type = MFC_CTRL_TYPE_GET_DST,
-               .id = V4L2_CID_MPEG_VIDEO_SEI_DISPLAY_PRIMARIES_0,
-               .is_volatile = 0,
-               .mode = MFC_CTRL_MODE_SFR,
-               .addr = MFC_REG_D_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_3,
-               .mask = 0xFFFFFFFF,
-               .shft = 0,
-               .flag_mode = MFC_CTRL_MODE_NONE,
-               .flag_addr = 0,
-               .flag_shft = 0,
-       },
-       {
-               .type = MFC_CTRL_TYPE_GET_DST,
-               .id = V4L2_CID_MPEG_VIDEO_SEI_DISPLAY_PRIMARIES_1,
-               .is_volatile = 0,
-               .mode = MFC_CTRL_MODE_SFR,
-               .addr = MFC_REG_D_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_4,
-               .mask = 0xFFFFFFFF,
-               .shft = 0,
-               .flag_mode = MFC_CTRL_MODE_NONE,
-               .flag_addr = 0,
-               .flag_shft = 0,
-       },
-       {
-               .type = MFC_CTRL_TYPE_GET_DST,
-               .id = V4L2_CID_MPEG_VIDEO_SEI_DISPLAY_PRIMARIES_2,
-               .is_volatile = 0,
-               .mode = MFC_CTRL_MODE_SFR,
-               .addr = MFC_REG_D_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_5,
-               .mask = 0xFFFFFFFF,
-               .shft = 0,
-               .flag_mode = MFC_CTRL_MODE_NONE,
-               .flag_addr = 0,
-               .flag_shft = 0,
-       },
-};
-
-static int mfc_dec_cleanup_ctx_ctrls(struct mfc_ctx *ctx)
-{
-       struct mfc_ctx_ctrl *ctx_ctrl;
-
-       while (!list_empty(&ctx->ctrls)) {
-               ctx_ctrl = list_entry((&ctx->ctrls)->next,
-                                     struct mfc_ctx_ctrl, list);
-               list_del(&ctx_ctrl->list);
-               kfree(ctx_ctrl);
-       }
-
-       INIT_LIST_HEAD(&ctx->ctrls);
-
-       return 0;
-}
-
-static int mfc_dec_init_ctx_ctrls(struct mfc_ctx *ctx)
-{
-       unsigned long i;
-       struct mfc_ctx_ctrl *ctx_ctrl;
-
-       INIT_LIST_HEAD(&ctx->ctrls);
-
-       for (i = 0; i < NUM_CTRL_CFGS; i++) {
-               ctx_ctrl = kzalloc(sizeof(struct mfc_ctx_ctrl), GFP_KERNEL);
-               if (ctx_ctrl == NULL) {
-                       mfc_err_dev("Failed to allocate context control "\
-                                       "id: 0x%08x, type: %d\n",
-                                       mfc_ctrl_list[i].id,
-                                       mfc_ctrl_list[i].type);
-
-                       mfc_dec_cleanup_ctx_ctrls(ctx);
-
-                       return -ENOMEM;
-               }
-
-               ctx_ctrl->type = mfc_ctrl_list[i].type;
-               ctx_ctrl->id = mfc_ctrl_list[i].id;
-               ctx_ctrl->addr = mfc_ctrl_list[i].addr;
-               ctx_ctrl->has_new = 0;
-               ctx_ctrl->val = 0;
-
-               list_add_tail(&ctx_ctrl->list, &ctx->ctrls);
-       }
-
-       return 0;
-}
-
-static void __mfc_dec_remove_buf_ctrls(struct list_head *head)
-{
-       struct mfc_buf_ctrl *buf_ctrl;
-
-       while (!list_empty(head)) {
-               buf_ctrl = list_entry(head->next,
-                               struct mfc_buf_ctrl, list);
-               list_del(&buf_ctrl->list);
-               kfree(buf_ctrl);
-       }
-
-       INIT_LIST_HEAD(head);
-}
-
-static void mfc_dec_reset_buf_ctrls(struct list_head *head)
-{
-       struct mfc_buf_ctrl *buf_ctrl;
-
-       list_for_each_entry(buf_ctrl, head, list) {
-               buf_ctrl->has_new = 0;
-               buf_ctrl->val = 0;
-               buf_ctrl->old_val = 0;
-               buf_ctrl->updated = 0;
-       }
-}
-
-static int mfc_dec_init_buf_ctrls(struct mfc_ctx *ctx,
-       enum mfc_ctrl_type type, unsigned int index)
-{
-       unsigned long i;
-       struct mfc_ctx_ctrl *ctx_ctrl;
-       struct mfc_buf_ctrl *buf_ctrl;
-       struct list_head *head;
-
-       if (index >= MFC_MAX_BUFFERS) {
-               mfc_err_dev("Per-buffer control index is out of range\n");
-               return -EINVAL;
-       }
-
-       if (type & MFC_CTRL_TYPE_SRC) {
-               if (test_bit(index, &ctx->src_ctrls_avail)) {
-                       mfc_dec_reset_buf_ctrls(&ctx->src_ctrls[index]);
-
-                       return 0;
-               }
-
-               head = &ctx->src_ctrls[index];
-       } else if (type & MFC_CTRL_TYPE_DST) {
-               if (test_bit(index, &ctx->dst_ctrls_avail)) {
-                       mfc_dec_reset_buf_ctrls(&ctx->dst_ctrls[index]);
-
-                       return 0;
-               }
-
-               head = &ctx->dst_ctrls[index];
-       } else {
-               mfc_err_dev("Control type mismatch. type : %d\n", type);
-               return -EINVAL;
-       }
-
-       INIT_LIST_HEAD(head);
-
-       list_for_each_entry(ctx_ctrl, &ctx->ctrls, list) {
-               if (!(type & ctx_ctrl->type))
-                       continue;
-
-               /* find matched control configuration index */
-               for (i = 0; i < NUM_CTRL_CFGS; i++) {
-                       if (ctx_ctrl->id == mfc_ctrl_list[i].id)
-                               break;
-               }
-
-               if (i == NUM_CTRL_CFGS) {
-                       mfc_err_dev("Failed to find buffer control "\
-                                       "id: 0x%08x, type: %d\n",
-                                       ctx_ctrl->id, ctx_ctrl->type);
-                       continue;
-               }
-
-               buf_ctrl = kzalloc(sizeof(struct mfc_buf_ctrl), GFP_KERNEL);
-               if (buf_ctrl == NULL) {
-                       mfc_err_dev("Failed to allocate buffer control "\
-                                       "id: 0x%08x, type: %d\n",
-                                       mfc_ctrl_list[i].id,
-                                       mfc_ctrl_list[i].type);
-
-                       __mfc_dec_remove_buf_ctrls(head);
-
-                       return -ENOMEM;
-               }
-
-               buf_ctrl->id = ctx_ctrl->id;
-               buf_ctrl->type = ctx_ctrl->type;
-               buf_ctrl->addr = ctx_ctrl->addr;
-
-               buf_ctrl->is_volatile = mfc_ctrl_list[i].is_volatile;
-               buf_ctrl->mode = mfc_ctrl_list[i].mode;
-               buf_ctrl->mask = mfc_ctrl_list[i].mask;
-               buf_ctrl->shft = mfc_ctrl_list[i].shft;
-               buf_ctrl->flag_mode = mfc_ctrl_list[i].flag_mode;
-               buf_ctrl->flag_addr = mfc_ctrl_list[i].flag_addr;
-               buf_ctrl->flag_shft = mfc_ctrl_list[i].flag_shft;
-
-               list_add_tail(&buf_ctrl->list, head);
-       }
-
-       mfc_dec_reset_buf_ctrls(head);
-
-       if (type & MFC_CTRL_TYPE_SRC)
-               set_bit(index, &ctx->src_ctrls_avail);
-       else
-               set_bit(index, &ctx->dst_ctrls_avail);
-
-       return 0;
-}
-
-static int mfc_dec_cleanup_buf_ctrls(struct mfc_ctx *ctx,
-       enum mfc_ctrl_type type, unsigned int index)
-{
-       struct list_head *head;
-
-       if (index >= MFC_MAX_BUFFERS) {
-               mfc_err_dev("Per-buffer control index is out of range\n");
-               return -EINVAL;
-       }
-
-       if (type & MFC_CTRL_TYPE_SRC) {
-               if (!(test_and_clear_bit(index, &ctx->src_ctrls_avail))) {
-                       return 0;
-               }
-
-               head = &ctx->src_ctrls[index];
-       } else if (type & MFC_CTRL_TYPE_DST) {
-               if (!(test_and_clear_bit(index, &ctx->dst_ctrls_avail))) {
-                       return 0;
-               }
-
-               head = &ctx->dst_ctrls[index];
-       } else {
-               mfc_err_dev("Control type mismatch. type : %d\n", type);
-               return -EINVAL;
-       }
-
-       __mfc_dec_remove_buf_ctrls(head);
-
-       return 0;
-}
-
-static int mfc_dec_to_buf_ctrls(struct mfc_ctx *ctx, struct list_head *head)
-{
-       struct mfc_ctx_ctrl *ctx_ctrl;
-       struct mfc_buf_ctrl *buf_ctrl;
-
-       list_for_each_entry(ctx_ctrl, &ctx->ctrls, list) {
-               if (!(ctx_ctrl->type & MFC_CTRL_TYPE_SET) || !ctx_ctrl->has_new)
-                       continue;
-
-               list_for_each_entry(buf_ctrl, head, list) {
-                       if (!(buf_ctrl->type & MFC_CTRL_TYPE_SET))
-                               continue;
-
-                       if (buf_ctrl->id == ctx_ctrl->id) {
-                               buf_ctrl->has_new = 1;
-                               buf_ctrl->val = ctx_ctrl->val;
-                               if (buf_ctrl->is_volatile)
-                                       buf_ctrl->updated = 0;
-
-                               ctx_ctrl->has_new = 0;
-                               break;
-                       }
-               }
-       }
-
-       return 0;
-}
-
-static int mfc_dec_to_ctx_ctrls(struct mfc_ctx *ctx, struct list_head *head)
-{
-       struct mfc_ctx_ctrl *ctx_ctrl;
-       struct mfc_buf_ctrl *buf_ctrl;
-
-       list_for_each_entry(buf_ctrl, head, list) {
-               if (!(buf_ctrl->type & MFC_CTRL_TYPE_GET) || !buf_ctrl->has_new)
-                       continue;
-
-               list_for_each_entry(ctx_ctrl, &ctx->ctrls, list) {
-                       if (!(ctx_ctrl->type & MFC_CTRL_TYPE_GET))
-                               continue;
-
-                       if (ctx_ctrl->id == buf_ctrl->id) {
-                               ctx_ctrl->has_new = 1;
-                               ctx_ctrl->val = buf_ctrl->val;
-
-                               buf_ctrl->has_new = 0;
-                       }
-               }
-       }
-
-       return 0;
-}
-
-static int mfc_dec_set_buf_ctrls_val(struct mfc_ctx *ctx, struct list_head *head)
-{
-       struct mfc_buf_ctrl *buf_ctrl;
-       struct mfc_dec *dec = ctx->dec_priv;
-       struct mfc_dev *dev = ctx->dev;
-       unsigned int value = 0;
-
-       list_for_each_entry(buf_ctrl, head, list) {
-               if (!(buf_ctrl->type & MFC_CTRL_TYPE_SET) || !buf_ctrl->has_new)
-                       continue;
-
-               /* read old vlaue */
-               value = MFC_READL(buf_ctrl->addr);
-
-               /* save old vlaue for recovery */
-               if (buf_ctrl->is_volatile)
-                       buf_ctrl->old_val = (value >> buf_ctrl->shft) & buf_ctrl->mask;
-
-               /* write new value */
-               value &= ~(buf_ctrl->mask << buf_ctrl->shft);
-               value |= ((buf_ctrl->val & buf_ctrl->mask) << buf_ctrl->shft);
-               MFC_WRITEL(value, buf_ctrl->addr);
-
-               /* set change flag bit */
-               if (buf_ctrl->flag_mode == MFC_CTRL_MODE_SFR) {
-                       value = MFC_READL(buf_ctrl->flag_addr);
-                       value |= (1 << buf_ctrl->flag_shft);
-                       MFC_WRITEL(value, buf_ctrl->flag_addr);
-               }
-
-               buf_ctrl->has_new = 0;
-               buf_ctrl->updated = 1;
-
-               if (buf_ctrl->id == V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG)
-                       dec->stored_tag = buf_ctrl->val;
-
-               mfc_debug(6, "[CTRLS] Set buffer control id: 0x%08x, val: %d\n",
-                               buf_ctrl->id, buf_ctrl->val);
-       }
-
-       return 0;
-}
-
-static int mfc_dec_get_buf_ctrls_val(struct mfc_ctx *ctx, struct list_head *head)
-{
-       struct mfc_buf_ctrl *buf_ctrl;
-       struct mfc_dev *dev = ctx->dev;
-       struct mfc_dec *dec = ctx->dec_priv;
-       unsigned int value = 0;
-
-       list_for_each_entry(buf_ctrl, head, list) {
-               if (!(buf_ctrl->type & MFC_CTRL_TYPE_GET))
-                       continue;
-
-               value = MFC_READL(buf_ctrl->addr);
-               value = (value >> buf_ctrl->shft) & buf_ctrl->mask;
-
-               buf_ctrl->val = value;
-               buf_ctrl->has_new = 1;
-
-               if (IS_VP9_DEC(ctx)) {
-                       if (buf_ctrl->id == V4L2_CID_MPEG_VIDEO_FULL_RANGE_FLAG)
-                               buf_ctrl->val = dec->color_range;
-                       else if (buf_ctrl->id == V4L2_CID_MPEG_VIDEO_COLOUR_PRIMARIES)
-                               buf_ctrl->val = dec->color_space;
-               }
-
-               mfc_debug(6, "[CTRLS] Get buffer control id: 0x%08x, val: %d\n",
-                               buf_ctrl->id, buf_ctrl->val);
-       }
-
-       return 0;
-}
-
-static int mfc_dec_set_buf_ctrls_val_nal_q_dec(struct mfc_ctx *ctx,
-                       struct list_head *head, DecoderInputStr *pInStr)
-{
-       struct mfc_buf_ctrl *buf_ctrl;
-       struct mfc_dec *dec = ctx->dec_priv;
-
-       mfc_debug_enter();
-
-       list_for_each_entry(buf_ctrl, head, list) {
-               if (!(buf_ctrl->type & MFC_CTRL_TYPE_SET) || !buf_ctrl->has_new)
-                       continue;
-               switch (buf_ctrl->id) {
-               case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG:
-                       pInStr->PictureTag &= ~(buf_ctrl->mask << buf_ctrl->shft);
-                       pInStr->PictureTag |=
-                               (buf_ctrl->val & buf_ctrl->mask) << buf_ctrl->shft;
-                       dec->stored_tag = buf_ctrl->val;
-                       break;
-               /* If new dynamic controls are added, insert here */
-               default:
-                       mfc_info_ctx("[NALQ] can't find control, id: 0x%x\n",
-                                       buf_ctrl->id);
-               }
-               buf_ctrl->has_new = 0;
-               buf_ctrl->updated = 1;
-
-               mfc_debug(6, "[NALQ][CTRLS] Set buffer control id: 0x%08x, val: %d\n",
-                               buf_ctrl->id, buf_ctrl->val);
-       }
-
-       mfc_debug_leave();
-
-       return 0;
-}
-
-static int mfc_dec_get_buf_ctrls_val_nal_q_dec(struct mfc_ctx *ctx,
-                       struct list_head *head, DecoderOutputStr *pOutStr)
-{
-       struct mfc_dec *dec = ctx->dec_priv;
-       struct mfc_buf_ctrl *buf_ctrl;
-       unsigned int value = 0;
-
-       mfc_debug_enter();
-
-       list_for_each_entry(buf_ctrl, head, list) {
-               if (!(buf_ctrl->type & MFC_CTRL_TYPE_GET))
-                       continue;
-               switch (buf_ctrl->id) {
-               case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG:
-                       value = pOutStr->PictureTagTop;
-                       break;
-               case V4L2_CID_MPEG_MFC51_VIDEO_DISPLAY_STATUS:
-                       value = pOutStr->DisplayStatus;
-                       break;
-               case V4L2_CID_MPEG_MFC51_VIDEO_CRC_DATA_LUMA:
-                       value = pOutStr->DisplayFirstCrc;
-                       break;
-               case V4L2_CID_MPEG_MFC51_VIDEO_CRC_DATA_CHROMA:
-                       value = pOutStr->DisplaySecondCrc;
-                       break;
-               case V4L2_CID_MPEG_MFC51_VIDEO_CRC_DATA_CHROMA1:
-                       value = pOutStr->DisplayThirdCrc;
-                       break;
-               case V4L2_CID_MPEG_MFC51_VIDEO_CRC_DATA_2BIT_LUMA:
-                       value = pOutStr->DisplayFirst2BitCrc;
-                       break;
-               case V4L2_CID_MPEG_MFC51_VIDEO_CRC_DATA_2BIT_CHROMA:
-                       value = pOutStr->DisplaySecond2BitCrc;
-                       break;
-               case V4L2_CID_MPEG_MFC51_VIDEO_CRC_GENERATED:
-                       value = pOutStr->DisplayStatus;
-                       break;
-               case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_AVAIL:
-                       value = pOutStr->SeiAvail;
-                       break;
-               case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRGMENT_ID:
-                       value = pOutStr->FramePackArrgmentId;
-                       break;
-               case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_INFO:
-                       value = pOutStr->FramePackSeiInfo;
-                       break;
-               case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_GRID_POS:
-                       value = pOutStr->FramePackGridPos;
-                       break;
-               case V4L2_CID_MPEG_VIDEO_H264_MVC_VIEW_ID:
-                       value = 0;
-                       break;
-               /* TO-DO: SEI information has to be added in NAL-Q */
-               case V4L2_CID_MPEG_VIDEO_SEI_MAX_PIC_AVERAGE_LIGHT:
-               case V4L2_CID_MPEG_VIDEO_SEI_MAX_CONTENT_LIGHT:
-                       value = pOutStr->ContentLightLevelInfoSei;
-                       break;
-               case V4L2_CID_MPEG_VIDEO_SEI_MAX_DISPLAY_LUMINANCE:
-                       value = pOutStr->MasteringDisplayColourVolumeSei0;
-                       break;
-               case V4L2_CID_MPEG_VIDEO_SEI_MIN_DISPLAY_LUMINANCE:
-                       value = pOutStr->MasteringDisplayColourVolumeSei1;
-                       break;
-               case V4L2_CID_MPEG_VIDEO_FULL_RANGE_FLAG:
-               case V4L2_CID_MPEG_VIDEO_COLOUR_PRIMARIES:
-               case V4L2_CID_MPEG_VIDEO_FORMAT:
-               case V4L2_CID_MPEG_VIDEO_TRANSFER_CHARACTERISTICS:
-               case V4L2_CID_MPEG_VIDEO_MATRIX_COEFFICIENTS:
-                       value = pOutStr->VideoSignalType;
-                       break;
-               case V4L2_CID_MPEG_VIDEO_SEI_WHITE_POINT:
-                       value = pOutStr->MasteringDisplayColourVolumeSei2;
-                       break;
-               case V4L2_CID_MPEG_VIDEO_SEI_DISPLAY_PRIMARIES_0:
-                       value = pOutStr->MasteringDisplayColourVolumeSei3;
-                       break;
-               case V4L2_CID_MPEG_VIDEO_SEI_DISPLAY_PRIMARIES_1:
-                       value = pOutStr->MasteringDisplayColourVolumeSei4;
-                       break;
-               case V4L2_CID_MPEG_VIDEO_SEI_DISPLAY_PRIMARIES_2:
-                       value = pOutStr->MasteringDisplayColourVolumeSei5;
-                       break;
-                       /* If new dynamic controls are added, insert here */
-               default:
-                       mfc_info_ctx("[NALQ] can't find control, id: 0x%x\n",
-                                       buf_ctrl->id);
-               }
-               value = (value >> buf_ctrl->shft) & buf_ctrl->mask;
-
-               buf_ctrl->val = value;
-               buf_ctrl->has_new = 1;
-
-               if (IS_VP9_DEC(ctx)) {
-                       if (buf_ctrl->id == V4L2_CID_MPEG_VIDEO_FULL_RANGE_FLAG)
-                               buf_ctrl->val = dec->color_range;
-                       else if (buf_ctrl->id == V4L2_CID_MPEG_VIDEO_COLOUR_PRIMARIES)
-                               buf_ctrl->val = dec->color_space;
-               }
-
-               mfc_debug(6, "[NALQ][CTRLS] Get buffer control id: 0x%08x, val: %d\n",
-                               buf_ctrl->id, buf_ctrl->val);
-       }
-
-       mfc_debug_leave();
-
-       return 0;
-}
-
-static int mfc_dec_recover_buf_ctrls_val(struct mfc_ctx *ctx, struct list_head *head)
-{
-       struct mfc_buf_ctrl *buf_ctrl;
-       struct mfc_dev *dev = ctx->dev;
-       unsigned int value = 0;
-
-       list_for_each_entry(buf_ctrl, head, list) {
-               if (!(buf_ctrl->type & MFC_CTRL_TYPE_SET)
-                       || !buf_ctrl->is_volatile
-                       || !buf_ctrl->updated)
-                       continue;
-
-               value = MFC_READL(buf_ctrl->addr);
-               value &= ~(buf_ctrl->mask << buf_ctrl->shft);
-               value |= ((buf_ctrl->old_val & buf_ctrl->mask) << buf_ctrl->shft);
-               MFC_WRITEL(value, buf_ctrl->addr);
-
-               /* clear change flag bit */
-               if (buf_ctrl->flag_mode == MFC_CTRL_MODE_SFR) {
-                       value = MFC_READL(buf_ctrl->flag_addr);
-                       value &= ~(1 << buf_ctrl->flag_shft);
-                       MFC_WRITEL(value, buf_ctrl->flag_addr);
-               }
-
-               buf_ctrl->updated = 0;
-               mfc_debug(6, "[CTRLS] Recover buffer control id: 0x%08x, old val: %d\n",
-                               buf_ctrl->id, buf_ctrl->old_val);
-       }
-
-       return 0;
-}
-
-static int mfc_dec_get_buf_update_val(struct mfc_ctx *ctx,
-                       struct list_head *head, unsigned int id, int value)
-{
-       struct mfc_buf_ctrl *buf_ctrl;
-
-       list_for_each_entry(buf_ctrl, head, list) {
-               if (buf_ctrl->id == id) {
-                       buf_ctrl->val = value;
-                       mfc_debug(6, "[CTRLS] Update buffer control id: 0x%08x, val: %d\n",
-                                       buf_ctrl->id, buf_ctrl->val);
-                       break;
-               }
-       }
-
-       return 0;
-}
-
-static int mfc_dec_recover_buf_ctrls_nal_q(struct mfc_ctx *ctx,
-               struct list_head *head)
-{
-       struct mfc_buf_ctrl *buf_ctrl;
-
-       list_for_each_entry(buf_ctrl, head, list) {
-               if (!(buf_ctrl->type & MFC_CTRL_TYPE_SET)
-                               || !(buf_ctrl->updated))
-                       continue;
-
-               buf_ctrl->has_new = 1;
-               buf_ctrl->updated = 0;
-               mfc_debug(6, "[NALQ][CTRLS] Recover buffer control id: 0x%08x, val: %d\n",
-                               buf_ctrl->id, buf_ctrl->val);
-       }
-
-       return 0;
-}
-
-struct mfc_ctrls_ops decoder_ctrls_ops = {
-       .init_ctx_ctrls                 = mfc_dec_init_ctx_ctrls,
-       .cleanup_ctx_ctrls              = mfc_dec_cleanup_ctx_ctrls,
-       .init_buf_ctrls                 = mfc_dec_init_buf_ctrls,
-       .reset_buf_ctrls                = mfc_dec_reset_buf_ctrls,
-       .cleanup_buf_ctrls              = mfc_dec_cleanup_buf_ctrls,
-       .to_buf_ctrls                   = mfc_dec_to_buf_ctrls,
-       .to_ctx_ctrls                   = mfc_dec_to_ctx_ctrls,
-       .set_buf_ctrls_val              = mfc_dec_set_buf_ctrls_val,
-       .get_buf_ctrls_val              = mfc_dec_get_buf_ctrls_val,
-       .set_buf_ctrls_val_nal_q_dec    = mfc_dec_set_buf_ctrls_val_nal_q_dec,
-       .get_buf_ctrls_val_nal_q_dec    = mfc_dec_get_buf_ctrls_val_nal_q_dec,
-       .recover_buf_ctrls_val          = mfc_dec_recover_buf_ctrls_val,
-       .get_buf_update_val             = mfc_dec_get_buf_update_val,
-       .recover_buf_ctrls_nal_q        = mfc_dec_recover_buf_ctrls_nal_q,
-};
diff --git a/drivers/media/platform/exynos/mfc/mfc_dec_v4l2.c b/drivers/media/platform/exynos/mfc/mfc_dec_v4l2.c
new file mode 100644 (file)
index 0000000..27dc711
--- /dev/null
@@ -0,0 +1,1279 @@
+/*
+ * drivers/media/platform/exynos/mfc/mfc_dec_v4l2.c
+ *
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include "mfc_dec_v4l2.h"
+#include "mfc_dec_internal.h"
+
+#include "mfc_hwlock.h"
+#include "mfc_opr.h"
+#include "mfc_sync.h"
+#include "mfc_mmcache.h"
+
+#include "mfc_qos.h"
+#include "mfc_queue.h"
+#include "mfc_utils.h"
+#include "mfc_buf.h"
+#include "mfc_mem.h"
+
+#define MAX_FRAME_SIZE         (2*1024*1024)
+
+/* Find selected format description */
+static struct mfc_fmt *__mfc_dec_find_format(struct mfc_ctx *ctx,
+               unsigned int pixelformat)
+{
+       struct mfc_dev *dev = ctx->dev;
+       struct mfc_fmt *fmt = NULL;
+       unsigned long i;
+
+       for (i = 0; i < NUM_FORMATS; i++) {
+               if (dec_formats[i].fourcc == pixelformat) {
+                       fmt = (struct mfc_fmt *)&dec_formats[i];
+                       break;
+               }
+       }
+
+       if (!dev->pdata->support_10bit && (fmt->type & MFC_FMT_10BIT)) {
+               mfc_err_ctx("[FRAME] 10bit is not supported\n");
+               fmt = NULL;
+       }
+       if (!dev->pdata->support_422 && (fmt->type & MFC_FMT_422)) {
+               mfc_err_ctx("[FRAME] 422 is not supported\n");
+               fmt = NULL;
+       }
+
+       return fmt;
+}
+
+static struct v4l2_queryctrl *__mfc_dec_get_ctrl(int id)
+{
+       unsigned long i;
+
+       for (i = 0; i < NUM_CTRLS; ++i)
+               if (id == controls[i].id)
+                       return &controls[i];
+
+       return NULL;
+}
+
+/* Check whether a ctrl value if correct */
+static int __mfc_dec_check_ctrl_val(struct mfc_ctx *ctx, struct v4l2_control *ctrl)
+{
+       struct v4l2_queryctrl *c;
+
+       c = __mfc_dec_get_ctrl(ctrl->id);
+       if (!c) {
+               mfc_err_ctx("[CTRLS] not supported control id (%#x)\n", ctrl->id);
+               return -EINVAL;
+       }
+
+       if (ctrl->value < c->minimum || ctrl->value > c->maximum
+               || (c->step != 0 && ctrl->value % c->step != 0)) {
+               mfc_err_ctx("[CTRLS] Invalid control value (%#x)\n", ctrl->value);
+               return -ERANGE;
+       }
+
+       return 0;
+}
+
+/* Query capabilities of the device */
+static int vidioc_querycap(struct file *file, void *priv,
+                          struct v4l2_capability *cap)
+{
+       strncpy(cap->driver, "MFC", sizeof(cap->driver) - 1);
+       strncpy(cap->card, "decoder", sizeof(cap->card) - 1);
+       cap->bus_info[0] = 0;
+       cap->version = KERNEL_VERSION(1, 0, 0);
+       cap->device_caps = V4L2_CAP_VIDEO_CAPTURE
+                       | V4L2_CAP_VIDEO_OUTPUT
+                       | V4L2_CAP_VIDEO_CAPTURE_MPLANE
+                       | V4L2_CAP_VIDEO_OUTPUT_MPLANE
+                       | V4L2_CAP_STREAMING
+                       | V4L2_CAP_DEVICE_CAPS;
+
+       cap->capabilities = cap->device_caps;
+
+       return 0;
+}
+
+static int __mfc_dec_enum_fmt(struct mfc_dev *dev, struct v4l2_fmtdesc *f,
+               unsigned int type)
+{
+       struct mfc_fmt *fmt;
+       unsigned long i, j = 0;
+
+       for (i = 0; i < NUM_FORMATS; ++i) {
+               if (!(dec_formats[i].type & type))
+                       continue;
+               if (!dev->pdata->support_10bit && (dec_formats[i].type & MFC_FMT_10BIT))
+                       continue;
+               if (!dev->pdata->support_422 && (dec_formats[i].type & MFC_FMT_422))
+                       continue;
+
+               if (j == f->index) {
+                       fmt = &dec_formats[i];
+                       strlcpy(f->description, fmt->name,
+                               sizeof(f->description));
+                       f->pixelformat = fmt->fourcc;
+
+                       return 0;
+               }
+
+               ++j;
+       }
+
+       return -EINVAL;
+}
+
+static int vidioc_enum_fmt_vid_cap_mplane(struct file *file, void *pirv,
+               struct v4l2_fmtdesc *f)
+{
+       struct mfc_dev *dev = video_drvdata(file);
+
+       return __mfc_dec_enum_fmt(dev, f, MFC_FMT_FRAME);
+}
+
+static int vidioc_enum_fmt_vid_out_mplane(struct file *file, void *prov,
+               struct v4l2_fmtdesc *f)
+{
+       struct mfc_dev *dev = video_drvdata(file);
+
+       return __mfc_dec_enum_fmt(dev, f, MFC_FMT_STREAM);
+}
+
+static void __mfc_dec_change_format(struct mfc_ctx *ctx)
+{
+       struct mfc_dev *dev = ctx->dev;
+       u32 org_fmt = ctx->dst_fmt->fourcc;
+
+       if (ctx->is_10bit && ctx->is_422) {
+               switch (org_fmt) {
+               case V4L2_PIX_FMT_NV16M_S10B:
+               case V4L2_PIX_FMT_NV61M_S10B:
+               case V4L2_PIX_FMT_NV16M_P210:
+               case V4L2_PIX_FMT_NV61M_P210:
+                       /* It is right format */
+                       break;
+               case V4L2_PIX_FMT_NV12M:
+               case V4L2_PIX_FMT_NV16M:
+               case V4L2_PIX_FMT_NV12M_S10B:
+               case V4L2_PIX_FMT_NV12M_P010:
+                       ctx->dst_fmt = __mfc_dec_find_format(ctx, V4L2_PIX_FMT_NV16M_S10B);
+                       break;
+               case V4L2_PIX_FMT_NV21M:
+               case V4L2_PIX_FMT_NV61M:
+               case V4L2_PIX_FMT_NV21M_S10B:
+               case V4L2_PIX_FMT_NV21M_P010:
+                       ctx->dst_fmt = __mfc_dec_find_format(ctx, V4L2_PIX_FMT_NV61M_S10B);
+                       break;
+               default:
+                       ctx->dst_fmt = __mfc_dec_find_format(ctx, V4L2_PIX_FMT_NV16M_S10B);
+                       break;
+               }
+               ctx->raw_buf.num_planes = 2;
+       } else if (ctx->is_10bit && !ctx->is_422) {
+               if (ctx->dst_fmt->mem_planes == 1) {
+                       /* YUV420 only supports the single plane */
+                       ctx->dst_fmt = __mfc_dec_find_format(ctx, V4L2_PIX_FMT_NV12N_10B);
+               } else {
+                       switch (org_fmt) {
+                       case V4L2_PIX_FMT_NV12M_S10B:
+                       case V4L2_PIX_FMT_NV21M_S10B:
+                       case V4L2_PIX_FMT_NV12M_P010:
+                       case V4L2_PIX_FMT_NV21M_P010:
+                               /* It is right format */
+                               break;
+                       case V4L2_PIX_FMT_NV12M:
+                       case V4L2_PIX_FMT_NV16M:
+                       case V4L2_PIX_FMT_NV16M_S10B:
+                       case V4L2_PIX_FMT_NV16M_P210:
+                               if (dev->pdata->P010_decoding)
+                                       ctx->dst_fmt = __mfc_dec_find_format(ctx, V4L2_PIX_FMT_NV12M_P010);
+                               else
+                                       ctx->dst_fmt = __mfc_dec_find_format(ctx, V4L2_PIX_FMT_NV12M_S10B);
+                               break;
+                       case V4L2_PIX_FMT_NV21M:
+                       case V4L2_PIX_FMT_NV61M:
+                       case V4L2_PIX_FMT_NV61M_S10B:
+                       case V4L2_PIX_FMT_NV61M_P210:
+                               ctx->dst_fmt = __mfc_dec_find_format(ctx, V4L2_PIX_FMT_NV21M_S10B);
+                               break;
+                       default:
+                               if (dev->pdata->P010_decoding)
+                                       ctx->dst_fmt = __mfc_dec_find_format(ctx, V4L2_PIX_FMT_NV12M_P010);
+                               else
+                                       ctx->dst_fmt = __mfc_dec_find_format(ctx, V4L2_PIX_FMT_NV12M_S10B);
+                               break;
+                       }
+               }
+               ctx->raw_buf.num_planes = 2;
+       } else if (!ctx->is_10bit && ctx->is_422) {
+               switch (org_fmt) {
+               case V4L2_PIX_FMT_NV16M:
+               case V4L2_PIX_FMT_NV61M:
+                       /* It is right format */
+                       break;
+               case V4L2_PIX_FMT_NV12M:
+               case V4L2_PIX_FMT_NV12M_S10B:
+               case V4L2_PIX_FMT_NV16M_S10B:
+               case V4L2_PIX_FMT_NV12M_P010:
+               case V4L2_PIX_FMT_NV16M_P210:
+                       ctx->dst_fmt = __mfc_dec_find_format(ctx, V4L2_PIX_FMT_NV16M);
+                       break;
+               case V4L2_PIX_FMT_NV21M:
+               case V4L2_PIX_FMT_NV21M_S10B:
+               case V4L2_PIX_FMT_NV61M_S10B:
+               case V4L2_PIX_FMT_NV21M_P010:
+               case V4L2_PIX_FMT_NV61M_P210:
+                       ctx->dst_fmt = __mfc_dec_find_format(ctx, V4L2_PIX_FMT_NV61M);
+                       break;
+               default:
+                       ctx->dst_fmt = __mfc_dec_find_format(ctx, V4L2_PIX_FMT_NV16M);
+                       break;
+               }
+               ctx->raw_buf.num_planes = 2;
+       } else {
+               /* YUV420 8bit */
+               switch (org_fmt) {
+               case V4L2_PIX_FMT_NV16M:
+               case V4L2_PIX_FMT_NV12M_S10B:
+               case V4L2_PIX_FMT_NV16M_S10B:
+               case V4L2_PIX_FMT_NV12M_P010:
+               case V4L2_PIX_FMT_NV16M_P210:
+                       ctx->dst_fmt = __mfc_dec_find_format(ctx, V4L2_PIX_FMT_NV12M);
+                       break;
+               case V4L2_PIX_FMT_NV61M:
+               case V4L2_PIX_FMT_NV21M_S10B:
+               case V4L2_PIX_FMT_NV61M_S10B:
+               case V4L2_PIX_FMT_NV21M_P010:
+               case V4L2_PIX_FMT_NV61M_P210:
+                       ctx->dst_fmt = __mfc_dec_find_format(ctx, V4L2_PIX_FMT_NV21M);
+                       break;
+               default:
+                       /* It is right format */
+                       break;
+               }
+       }
+
+       if (org_fmt != ctx->dst_fmt->fourcc)
+               mfc_info_ctx("[FRAME] format is changed to %s\n", ctx->dst_fmt->name);
+}
+
+/* Get format */
+static int vidioc_g_fmt_vid_cap_mplane(struct file *file, void *priv,
+                                               struct v4l2_format *f)
+{
+       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+       struct mfc_dec *dec;
+       struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
+       struct mfc_raw_info *raw;
+       int i;
+
+       mfc_debug_enter();
+
+       dec = ctx->dec_priv;
+       if (!dec) {
+               mfc_err_dev("no mfc decoder to run\n");
+               return -EINVAL;
+       }
+
+       mfc_debug(2, "dec dst g_fmt, state: %d\n", ctx->state);
+
+       if (ctx->state == MFCINST_GOT_INST ||
+           ctx->state == MFCINST_RES_CHANGE_FLUSH ||
+           ctx->state == MFCINST_RES_CHANGE_END) {
+               /* If the MFC is parsing the header,
+                * so wait until it is finished */
+               if (mfc_wait_for_done_ctx(ctx,
+                               MFC_REG_R2H_CMD_SEQ_DONE_RET)) {
+                               mfc_err_dev("header parsing failed\n");
+                               return -EAGAIN;
+               }
+       }
+
+       if (ctx->state >= MFCINST_HEAD_PARSED &&
+           ctx->state < MFCINST_ABORT) {
+               /* This is run on CAPTURE (deocde output) */
+
+               /* only NV16(61) format is supported for 422 format */
+               /* only 2 plane is supported for 10bit */
+               __mfc_dec_change_format(ctx);
+
+               raw = &ctx->raw_buf;
+               /* Width and height are set to the dimensions
+                  of the movie, the buffer is bigger and
+                  further processing stages should crop to this
+                  rectangle. */
+               mfc_dec_calc_dpb_size(ctx);
+
+               if (IS_LOW_MEM) {
+                       unsigned int dpb_size;
+                       /*
+                        * If total memory requirement is too big for this device,
+                        * then it returns error.
+                        * DPB size : Total plane size * the number of DPBs
+                        * 5: the number of extra DPBs
+                        * 3: the number of DPBs for Android framework
+                        * 600MB: being used to return an error,
+                        * when 8K resolution video clip is being tried to be decoded
+                        */
+                       dpb_size = (ctx->raw_buf.total_plane_size * (ctx->dpb_count + 5 + 3));
+                       if (dpb_size > SZ_600M) {
+                               mfc_info_ctx("required memory size is too big (%dx%d, dpb: %d)\n",
+                                               ctx->img_width, ctx->img_height, ctx->dpb_count);
+                               return -EINVAL;
+                       }
+               }
+
+               pix_fmt_mp->width = ctx->img_width;
+               pix_fmt_mp->height = ctx->img_height;
+               pix_fmt_mp->num_planes = ctx->dst_fmt->mem_planes;
+
+               if (dec->is_interlaced)
+                       pix_fmt_mp->field = V4L2_FIELD_INTERLACED;
+               else
+                       pix_fmt_mp->field = V4L2_FIELD_NONE;
+
+               /* Set pixelformat to the format in which MFC
+                  outputs the decoded frame */
+               pix_fmt_mp->pixelformat = ctx->dst_fmt->fourcc;
+               for (i = 0; i < ctx->dst_fmt->mem_planes; i++) {
+                       pix_fmt_mp->plane_fmt[i].bytesperline = raw->stride[i];
+                       if (ctx->dst_fmt->mem_planes == 1) {
+                               pix_fmt_mp->plane_fmt[i].sizeimage = raw->total_plane_size;
+                       } else {
+                               if (ctx->is_10bit)
+                                       pix_fmt_mp->plane_fmt[i].sizeimage = raw->plane_size[i]
+                                               + raw->plane_size_2bits[i];
+                               else
+                                       pix_fmt_mp->plane_fmt[i].sizeimage = raw->plane_size[i];
+                       }
+               }
+       }
+
+       mfc_debug_leave();
+
+       return 0;
+}
+
+static int vidioc_g_fmt_vid_out_mplane(struct file *file, void *priv,
+                                               struct v4l2_format *f)
+{
+       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+       struct mfc_dec *dec;
+       struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
+
+       mfc_debug_enter();
+
+       dec = ctx->dec_priv;
+       if (!dec) {
+               mfc_err_dev("no mfc decoder to run\n");
+               return -EINVAL;
+       }
+
+       mfc_debug(4, "dec src g_fmt, state: %d\n", ctx->state);
+
+       /* This is run on OUTPUT
+          The buffer contains compressed image
+          so width and height have no meaning */
+       pix_fmt_mp->width = 0;
+       pix_fmt_mp->height = 0;
+       pix_fmt_mp->field = V4L2_FIELD_NONE;
+       pix_fmt_mp->plane_fmt[0].bytesperline = dec->src_buf_size;
+       pix_fmt_mp->plane_fmt[0].sizeimage = dec->src_buf_size;
+       pix_fmt_mp->pixelformat = ctx->src_fmt->fourcc;
+       pix_fmt_mp->num_planes = ctx->src_fmt->mem_planes;
+
+       mfc_debug_leave();
+
+       return 0;
+}
+
+/* Try format */
+static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
+{
+       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+       struct mfc_fmt *fmt;
+       struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
+
+       fmt = __mfc_dec_find_format(ctx, pix_fmt_mp->pixelformat);
+       if (!fmt) {
+               mfc_err_dev("Unsupported format for %s\n",
+                               V4L2_TYPE_IS_OUTPUT(f->type) ? "source" : "destination");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+/* Set format */
+static int vidioc_s_fmt_vid_cap_mplane(struct file *file, void *priv,
+                                                       struct v4l2_format *f)
+{
+       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+       struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
+
+       mfc_debug_enter();
+
+       if (ctx->vq_dst.streaming) {
+               mfc_err_ctx("queue busy\n");
+               return -EBUSY;
+       }
+
+       ctx->dst_fmt = __mfc_dec_find_format(ctx, pix_fmt_mp->pixelformat);
+       if (!ctx->dst_fmt) {
+               mfc_err_ctx("Unsupported format for destination\n");
+               return -EINVAL;
+       }
+       ctx->raw_buf.num_planes = ctx->dst_fmt->num_planes;
+       mfc_info_ctx("[FRAME] dec dst pixelformat : %s\n", ctx->dst_fmt->name);
+
+       mfc_debug_leave();
+
+       return 0;
+}
+
+static int __mfc_force_close_inst(struct mfc_dev *dev, struct mfc_ctx *ctx)
+{
+       if (ctx->inst_no == MFC_NO_INSTANCE_SET)
+               return 0;
+
+       mfc_change_state(ctx, MFCINST_RETURN_INST);
+       mfc_set_bit(ctx->num, &dev->work_bits);
+       mfc_clean_ctx_int_flags(ctx);
+       if (mfc_just_run(dev, ctx->num)) {
+               mfc_err_ctx("Failed to run MFC\n");
+               mfc_release_hwlock_ctx(ctx);
+               mfc_cleanup_work_bit_and_try_run(ctx);
+               return -EIO;
+       }
+
+       /* Wait until instance is returned or timeout occured */
+       if (mfc_wait_for_done_ctx(ctx,
+                               MFC_REG_R2H_CMD_CLOSE_INSTANCE_RET)) {
+               mfc_err_ctx("Waiting for CLOSE_INSTANCE timed out\n");
+               mfc_release_hwlock_ctx(ctx);
+               mfc_cleanup_work_bit_and_try_run(ctx);
+               return -EIO;
+       }
+
+       /* Free resources */
+       mfc_release_instance_context(ctx);
+       mfc_change_state(ctx, MFCINST_INIT);
+
+       return 0;
+}
+
+static int vidioc_s_fmt_vid_out_mplane(struct file *file, void *priv,
+                                                       struct v4l2_format *f)
+{
+       struct mfc_dev *dev = video_drvdata(file);
+       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+       struct mfc_dec *dec = ctx->dec_priv;
+       struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
+       int ret = 0;
+
+       mfc_debug_enter();
+
+       if (ctx->vq_src.streaming) {
+               mfc_err_ctx("queue busy\n");
+               return -EBUSY;
+       }
+
+       ctx->src_fmt = __mfc_dec_find_format(ctx, pix_fmt_mp->pixelformat);
+       if (!ctx->src_fmt) {
+               mfc_err_ctx("Unsupported format for source\n");
+               return -EINVAL;
+       }
+
+       ctx->codec_mode = ctx->src_fmt->codec_mode;
+       mfc_info_ctx("[STREAM] Dec src codec(%d): %s\n",
+                       ctx->codec_mode, ctx->src_fmt->name);
+
+       ctx->pix_format = pix_fmt_mp->pixelformat;
+       if ((pix_fmt_mp->width > 0) && (pix_fmt_mp->height > 0)) {
+               ctx->img_height = pix_fmt_mp->height;
+               ctx->img_width = pix_fmt_mp->width;
+       }
+
+       /* As this buffer will contain compressed data, the size is set
+        * to the maximum size. */
+       if (pix_fmt_mp->plane_fmt[0].sizeimage)
+               dec->src_buf_size = pix_fmt_mp->plane_fmt[0].sizeimage;
+       else
+               dec->src_buf_size = MAX_FRAME_SIZE;
+       mfc_debug(2, "[STREAM] sizeimage: %d\n", pix_fmt_mp->plane_fmt[0].sizeimage);
+       pix_fmt_mp->plane_fmt[0].bytesperline = 0;
+
+       MFC_TRACE_CTX_HWLOCK("**DEC s_fmt\n");
+       ret = mfc_get_hwlock_ctx(ctx);
+       if (ret < 0) {
+               mfc_err_ctx("Failed to get hwlock\n");
+               return -EBUSY;
+       }
+
+       /* In case of calling s_fmt twice or more */
+       ret = __mfc_force_close_inst(dev, ctx);
+       if (ret) {
+               mfc_err_ctx("Failed to close already opening instance\n");
+               return -EIO;
+       }
+
+       ret = mfc_alloc_instance_context(ctx);
+       if (ret) {
+               mfc_err_ctx("Failed to allocate dec instance[%d] buffers\n",
+                               ctx->num);
+               mfc_release_hwlock_ctx(ctx);
+               return -ENOMEM;
+       }
+
+       mfc_set_bit(ctx->num, &dev->work_bits);
+       ret = mfc_just_run(dev, ctx->num);
+       if (ret) {
+               mfc_err_ctx("Failed to run MFC\n");
+               mfc_release_hwlock_ctx(ctx);
+               mfc_cleanup_work_bit_and_try_run(ctx);
+               mfc_release_instance_context(ctx);
+               return -EIO;
+       }
+
+       if (mfc_wait_for_done_ctx(ctx,
+                       MFC_REG_R2H_CMD_OPEN_INSTANCE_RET)) {
+               mfc_release_hwlock_ctx(ctx);
+               mfc_cleanup_work_bit_and_try_run(ctx);
+               mfc_release_instance_context(ctx);
+               return -EIO;
+       }
+
+       mfc_release_hwlock_ctx(ctx);
+
+       mfc_debug(2, "Got instance number: %d\n", ctx->inst_no);
+
+       if (mfc_dec_ctx_ready(ctx))
+               mfc_set_bit(ctx->num, &dev->work_bits);
+       if (mfc_is_work_to_do(dev))
+               queue_work(dev->butler_wq, &dev->butler_work);
+
+       mfc_debug_leave();
+
+       return 0;
+}
+
+/* Reqeust buffers */
+static int vidioc_reqbufs(struct file *file, void *priv,
+               struct v4l2_requestbuffers *reqbufs)
+{
+       struct mfc_dev *dev = video_drvdata(file);
+       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+       struct mfc_dec *dec;
+       int ret = 0;
+
+       mfc_debug_enter();
+
+       if (!dev) {
+               mfc_err_dev("no mfc device to run\n");
+               return -EINVAL;
+       }
+
+       dec = ctx->dec_priv;
+       if (!dec) {
+               mfc_err_dev("no mfc decoder to run\n");
+               return -EINVAL;
+       }
+
+       if (reqbufs->memory == V4L2_MEMORY_MMAP) {
+               mfc_err_ctx("Not supported memory type (%d)\n", reqbufs->memory);
+               return -EINVAL;
+       }
+
+       if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+               mfc_debug(4, "dec src reqbuf(%d)\n", reqbufs->count);
+               /* Can only request buffers after
+                  an instance has been opened.*/
+               if (ctx->state == MFCINST_GOT_INST) {
+                       if (reqbufs->count == 0) {
+                               ret = vb2_reqbufs(&ctx->vq_src, reqbufs);
+                               ctx->output_state = QUEUE_FREE;
+                               return ret;
+                       }
+
+                       /* Decoding */
+                       if (ctx->output_state != QUEUE_FREE) {
+                               mfc_err_ctx("Bufs have already been requested\n");
+                               return -EINVAL;
+                       }
+
+                       ret = vb2_reqbufs(&ctx->vq_src, reqbufs);
+                       if (ret) {
+                               mfc_err_ctx("vb2_reqbufs on src failed\n");
+                               return ret;
+                       }
+
+                       ctx->output_state = QUEUE_BUFS_REQUESTED;
+               }
+       } else if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+               mfc_debug(4, "dec dst reqbuf(%d)\n", reqbufs->count);
+               if (reqbufs->count == 0) {
+                       ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
+
+                       if (dev->has_mmcache && dev->mmcache.is_on_status)
+                               mfc_invalidate_mmcache(dev);
+
+                       mfc_release_codec_buffers(ctx);
+                       ctx->capture_state = QUEUE_FREE;
+                       return ret;
+               }
+
+               dec->dst_memtype = reqbufs->memory;
+
+               if (ctx->capture_state != QUEUE_FREE) {
+                       mfc_err_ctx("Bufs have already been requested\n");
+                       return -EINVAL;
+               }
+
+               ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
+               if (ret) {
+                       mfc_err_ctx("vb2_reqbufs on capture failed\n");
+                       return ret;
+               }
+
+               if (reqbufs->count < ctx->dpb_count) {
+                       mfc_err_ctx("Not enough buffers allocated\n");
+                       reqbufs->count = 0;
+                       vb2_reqbufs(&ctx->vq_dst, reqbufs);
+                       return -ENOMEM;
+               }
+
+               dec->total_dpb_count = reqbufs->count;
+
+               ret = mfc_alloc_codec_buffers(ctx);
+               if (ret) {
+                       mfc_err_ctx("Failed to allocate decoding buffers\n");
+                       reqbufs->count = 0;
+                       vb2_reqbufs(&ctx->vq_dst, reqbufs);
+                       return -ENOMEM;
+               }
+
+               ctx->capture_state = QUEUE_BUFS_REQUESTED;
+
+               if (mfc_dec_ctx_ready(ctx))
+                       mfc_set_bit(ctx->num, &dev->work_bits);
+
+               mfc_try_run(dev);
+       }
+
+       mfc_debug_leave();
+
+       return ret;
+}
+
+/* Query buffer */
+static int vidioc_querybuf(struct file *file, void *priv,
+                                                  struct v4l2_buffer *buf)
+{
+       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+       int ret;
+
+       mfc_debug_enter();
+
+       if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+               mfc_debug(4, "dec dst querybuf, state: %d\n", ctx->state);
+               ret = vb2_querybuf(&ctx->vq_dst, buf);
+               if (ret != 0) {
+                       mfc_err_dev("dec dst: error in vb2_querybuf()\n");
+                       return ret;
+               }
+       } else if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+               mfc_debug(4, "dec src querybuf, state: %d\n", ctx->state);
+               ret = vb2_querybuf(&ctx->vq_src, buf);
+               if (ret != 0) {
+                       mfc_err_dev("dec src: error in vb2_querybuf()\n");
+                       return ret;
+               }
+       } else {
+               mfc_err_dev("invalid buf type (%d)\n", buf->type);
+               return -EINVAL;
+       }
+
+       mfc_debug_leave();
+
+       return ret;
+}
+
+/* Queue a buffer */
+static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
+{
+       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+       int ret = -EINVAL;
+
+       mfc_debug_enter();
+
+       if (ctx->state == MFCINST_ERROR) {
+               mfc_err_ctx("Call on QBUF after unrecoverable error\n");
+               return -EIO;
+       }
+
+       if (V4L2_TYPE_IS_MULTIPLANAR(buf->type) && !buf->length) {
+               mfc_err_ctx("multiplanar but length is zero\n");
+               return -EIO;
+       }
+
+       if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+               mfc_debug(4, "dec src buf[%d] Q\n", buf->index);
+               if (buf->m.planes[0].bytesused > buf->m.planes[0].length) {
+                       mfc_err_ctx("data size (%d) must be less than "
+                                       "buffer size(%d)\n",
+                                       buf->m.planes[0].bytesused,
+                                       buf->m.planes[0].length);
+                       return -EIO;
+               }
+
+               mfc_qos_update_framerate(ctx);
+
+               if (!buf->m.planes[0].bytesused) {
+                       buf->m.planes[0].bytesused = buf->m.planes[0].length;
+                       mfc_debug(2, "Src size zero, changed to buf size %d\n",
+                                       buf->m.planes[0].bytesused);
+               } else {
+                       mfc_debug(2, "Src size = %d\n", buf->m.planes[0].bytesused);
+               }
+               ret = vb2_qbuf(&ctx->vq_src, buf);
+       } else {
+               mfc_debug(4, "dec dst buf[%d] Q\n", buf->index);
+               ret = vb2_qbuf(&ctx->vq_dst, buf);
+       }
+
+       mfc_debug_leave();
+       return ret;
+}
+
+/* Dequeue a buffer */
+static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
+{
+       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+       struct mfc_dec *dec = ctx->dec_priv;
+       struct dec_dpb_ref_info *dstBuf, *srcBuf;
+       int ret;
+       int ncount = 0;
+
+       mfc_debug_enter();
+
+       if (ctx->state == MFCINST_ERROR) {
+               mfc_err_ctx("Call on DQBUF after unrecoverable error\n");
+               return -EIO;
+       }
+       if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+               mfc_debug(4, "dec src buf[%d] DQ\n", buf->index);
+               ret = vb2_dqbuf(&ctx->vq_src, buf, file->f_flags & O_NONBLOCK);
+       } else {
+               mfc_debug(4, "dec dst buf[%d] DQ\n", buf->index);
+               ret = vb2_dqbuf(&ctx->vq_dst, buf, file->f_flags & O_NONBLOCK);
+
+               if (buf->index >= MFC_MAX_DPBS) {
+                       mfc_err_ctx("buffer index[%d] range over\n", buf->index);
+                       return -EINVAL;
+               }
+
+               /* Memcpy from dec->ref_info to shared memory */
+               srcBuf = &dec->ref_info[buf->index];
+               for (ncount = 0; ncount < MFC_MAX_DPBS; ncount++) {
+                       if (srcBuf->dpb[ncount].fd[0] == MFC_INFO_INIT_FD)
+                               break;
+                       mfc_debug(2, "[DPB] DQ index[%d] Released FD = %d\n",
+                                       buf->index, srcBuf->dpb[ncount].fd[0]);
+               }
+
+               if (dec->sh_handle.vaddr != NULL) {
+                       dstBuf = (struct dec_dpb_ref_info *)
+                                       dec->sh_handle.vaddr + buf->index;
+                       memcpy(dstBuf, srcBuf, sizeof(struct dec_dpb_ref_info));
+                       dstBuf->index = buf->index;
+               }
+       }
+       mfc_debug_leave();
+       return ret;
+}
+
+/* Stream on */
+static int vidioc_streamon(struct file *file, void *priv,
+                          enum v4l2_buf_type type)
+{
+       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+       int ret = -EINVAL;
+
+       mfc_debug_enter();
+
+       if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+               mfc_debug(4, "dec src streamon\n");
+               ret = vb2_streamon(&ctx->vq_src, type);
+       } else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+               mfc_debug(4, "dec dst streamon\n");
+               ret = vb2_streamon(&ctx->vq_dst, type);
+
+               if (!ret)
+                       mfc_qos_on(ctx);
+       } else {
+               mfc_err_ctx("unknown v4l2 buffer type\n");
+       }
+
+       mfc_debug(2, "src: %d, dst: %d,  state = %d, dpb_count = %d\n",
+                 mfc_get_queue_count(&ctx->buf_queue_lock, &ctx->src_buf_queue),
+                 mfc_get_queue_count(&ctx->buf_queue_lock, &ctx->dst_buf_queue),
+                 ctx->state, ctx->dpb_count);
+
+       mfc_debug_leave();
+
+       return ret;
+}
+
+/* Stream off, which equals to a pause */
+static int vidioc_streamoff(struct file *file, void *priv,
+                           enum v4l2_buf_type type)
+{
+       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+       int ret = -EINVAL;
+
+       mfc_debug_enter();
+
+       if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+               mfc_debug(4, "dec src streamoff\n");
+               mfc_qos_reset_last_framerate(ctx);
+
+               ret = vb2_streamoff(&ctx->vq_src, type);
+       } else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+               mfc_debug(4, "dec dst streamoff\n");
+               ret = vb2_streamoff(&ctx->vq_dst, type);
+               if (!ret)
+                       mfc_qos_off(ctx);
+       } else {
+               mfc_err_ctx("unknown v4l2 buffer type\n");
+       }
+
+       mfc_debug_leave();
+
+       return ret;
+}
+
+/* Query a ctrl */
+static int vidioc_queryctrl(struct file *file, void *priv,
+                           struct v4l2_queryctrl *qc)
+{
+       struct v4l2_queryctrl *c;
+
+       c = __mfc_dec_get_ctrl(qc->id);
+       if (!c) {
+               mfc_err_dev("[CTRLS] not supported control id (%#x)\n", qc->id);
+               return -EINVAL;
+       }
+
+       *qc = *c;
+       return 0;
+}
+
+static int __mfc_dec_ext_info(struct mfc_ctx *ctx)
+{
+       struct mfc_dev *dev = ctx->dev;
+       int val = 0;
+
+       val |= DEC_SET_DYNAMIC_DPB;
+       if (MFC_FEATURE_SUPPORT(dev, dev->pdata->skype))
+               val |= DEC_SET_SKYPE_FLAG;
+
+       mfc_debug(5, "[CTRLS] ext info val: %#x\n", val);
+
+       return val;
+}
+
+/* Get ctrl */
+static int __mfc_dec_get_ctrl_val(struct mfc_ctx *ctx, struct v4l2_control *ctrl)
+{
+       struct mfc_dev *dev;
+       struct mfc_dec *dec;
+       struct mfc_ctx_ctrl *ctx_ctrl;
+       int found = 0;
+
+       if (!ctx) {
+               mfc_err_dev("no mfc context to run\n");
+               return -EINVAL;
+       }
+       dev = ctx->dev;
+       if (!dev) {
+               mfc_err_dev("no mfc device to run\n");
+               return -EINVAL;
+       }
+       dec = ctx->dec_priv;
+       if (!dec) {
+               mfc_err_dev("no mfc decoder to run\n");
+               return -EINVAL;
+       }
+
+       switch (ctrl->id) {
+       case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER:
+               ctrl->value = dec->loop_filter_mpeg4;
+               break;
+       case V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY:
+               ctrl->value = dec->display_delay;
+               break;
+       case V4L2_CID_CACHEABLE:
+               mfc_debug(5, "it is supported only V4L2_MEMORY_MMAP\n");
+               break;
+       case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
+               if (ctx->state >= MFCINST_HEAD_PARSED &&
+                   ctx->state < MFCINST_ABORT) {
+                       ctrl->value = ctx->dpb_count;
+                       break;
+               } else if (ctx->state != MFCINST_INIT) {
+                       mfc_err_ctx("Decoding not initialised\n");
+                       return -EINVAL;
+               }
+
+               /* Should wait for the header to be parsed */
+               if (mfc_wait_for_done_ctx(ctx,
+                               MFC_REG_R2H_CMD_SEQ_DONE_RET)) {
+                       mfc_cleanup_work_bit_and_try_run(ctx);
+                       return -EIO;
+               }
+
+               if (ctx->state >= MFCINST_HEAD_PARSED &&
+                   ctx->state < MFCINST_ABORT) {
+                       ctrl->value = ctx->dpb_count;
+               } else {
+                       mfc_err_ctx("Decoding not initialised\n");
+                       return -EINVAL;
+               }
+               break;
+       case V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE:
+               ctrl->value = dec->slice_enable;
+               break;
+       case V4L2_CID_MPEG_MFC51_VIDEO_PACKED_PB:
+               /* Not used */
+               break;
+       case V4L2_CID_MPEG_MFC51_VIDEO_CRC_ENABLE:
+               ctrl->value = dec->crc_enable;
+               break;
+       case V4L2_CID_MPEG_MFC51_VIDEO_CHECK_STATE:
+               if (ctx->is_dpb_realloc && ctx->state == MFCINST_HEAD_PARSED)
+                       ctrl->value = MFCSTATE_DEC_S3D_REALLOC;
+               else if (ctx->state == MFCINST_RES_CHANGE_FLUSH
+                               || ctx->state == MFCINST_RES_CHANGE_END
+                               || ctx->state == MFCINST_HEAD_PARSED)
+                       ctrl->value = MFCSTATE_DEC_RES_DETECT;
+               else if (ctx->state == MFCINST_FINISHING)
+                       ctrl->value = MFCSTATE_DEC_TERMINATING;
+               else
+                       ctrl->value = MFCSTATE_PROCESSING;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING:
+               ctrl->value = dec->sei_parse;
+               break;
+       case V4L2_CID_MPEG_MFC51_VIDEO_I_FRAME_DECODING:
+               ctrl->value = dec->idr_decoding;
+               break;
+       case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_RATE:
+               ctrl->value = mfc_qos_get_framerate(ctx);
+               break;
+       case V4L2_CID_MPEG_MFC_GET_VERSION_INFO:
+               ctrl->value = dev->pdata->ip_ver;
+               break;
+       case V4L2_CID_MPEG_VIDEO_QOS_RATIO:
+               ctrl->value = ctx->qos_ratio;
+               break;
+       case V4L2_CID_MPEG_MFC_SET_DYNAMIC_DPB_MODE:
+               ctrl->value = dec->is_dynamic_dpb;
+               break;
+       case V4L2_CID_MPEG_MFC_GET_EXT_INFO:
+               ctrl->value = __mfc_dec_ext_info(ctx);
+               break;
+       case V4L2_CID_MPEG_MFC_GET_10BIT_INFO:
+               ctrl->value = ctx->is_10bit;
+               break;
+       case V4L2_CID_MPEG_MFC_GET_DRIVER_INFO:
+               ctrl->value = MFC_DRIVER_INFO;
+               break;
+       default:
+               list_for_each_entry(ctx_ctrl, &ctx->ctrls, list) {
+                       if (!(ctx_ctrl->type & MFC_CTRL_TYPE_GET))
+                               continue;
+
+                       if (ctx_ctrl->id == ctrl->id) {
+                               if (ctx_ctrl->has_new) {
+                                       ctx_ctrl->has_new = 0;
+                                       ctrl->value = ctx_ctrl->val;
+                               } else {
+                                       mfc_debug(5, "[CTRLS] Control value "\
+                                                       "is not up to date: "\
+                                                       "0x%08x\n", ctrl->id);
+                                       return -EINVAL;
+                               }
+
+                               found = 1;
+                               break;
+                       }
+               }
+
+               if (!found) {
+                       mfc_err_ctx("Invalid control: 0x%08x\n", ctrl->id);
+                       return -EINVAL;
+               }
+               break;
+       }
+
+       mfc_debug(5, "[CTRLS] get id: %#x, value: %d\n", ctrl->id, ctrl->value);
+
+       return 0;
+}
+
+/* Get a ctrl */
+static int vidioc_g_ctrl(struct file *file, void *priv,
+                       struct v4l2_control *ctrl)
+{
+       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+       int ret = 0;
+
+       mfc_debug_enter();
+       ret = __mfc_dec_get_ctrl_val(ctx, ctrl);
+       mfc_debug_leave();
+
+       return ret;
+}
+
+/* Set a ctrl */
+static int vidioc_s_ctrl(struct file *file, void *priv,
+                        struct v4l2_control *ctrl)
+{
+       struct mfc_dev *dev = video_drvdata(file);
+       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+       struct mfc_dec *dec;
+       struct mfc_ctx_ctrl *ctx_ctrl;
+       int ret = 0;
+       int found = 0;
+
+       mfc_debug_enter();
+
+       if (!dev) {
+               mfc_err_dev("no mfc device to run\n");
+               return -EINVAL;
+       }
+
+       dec = ctx->dec_priv;
+       if (!dec) {
+               mfc_err_dev("no mfc decoder to run\n");
+               return -EINVAL;
+       }
+
+       ret = __mfc_dec_check_ctrl_val(ctx, ctrl);
+       if (ret)
+               return ret;
+
+       mfc_debug(5, "[CTRLS] set id: %#x, value: %d\n", ctrl->id, ctrl->value);
+
+       switch (ctrl->id) {
+       case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER:
+               dec->loop_filter_mpeg4 = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY:
+               dec->display_delay = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE:
+               dec->slice_enable = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC51_VIDEO_PACKED_PB:
+               /* Not used */
+               break;
+       case V4L2_CID_MPEG_MFC51_VIDEO_CRC_ENABLE:
+               dec->crc_enable = ctrl->value;
+               break;
+       case V4L2_CID_CACHEABLE:
+               mfc_debug(5, "it is supported only V4L2_MEMORY_MMAP\n");
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING:
+               dec->sei_parse = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC51_VIDEO_I_FRAME_DECODING:
+               dec->idr_decoding = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_DECODER_IMMEDIATE_DISPLAY:
+               dec->immediate_display = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_DECODER_DECODING_TIMESTAMP_MODE:
+               dec->is_dts_mode = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_DECODER_WAIT_DECODING_START:
+               ctx->wait_state = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC_SET_DUAL_DPB_MODE:
+               mfc_err_dev("[DPB] not supported CID: 0x%x\n",ctrl->id);
+               break;
+       case V4L2_CID_MPEG_VIDEO_QOS_RATIO:
+               ctx->qos_ratio = ctrl->value;
+               mfc_info_ctx("[QoS] set %d qos_ratio\n", ctrl->value);
+               break;
+       case V4L2_CID_MPEG_MFC_SET_DYNAMIC_DPB_MODE:
+               dec->is_dynamic_dpb = ctrl->value;
+               if (dec->is_dynamic_dpb == 0)
+                       mfc_err_dev("[DPB] is_dynamic_dpb is 0. it has to be enabled\n");
+               break;
+       case V4L2_CID_MPEG_MFC_SET_USER_SHARED_HANDLE:
+               if (dec->sh_handle.fd == -1) {
+                       dec->sh_handle.fd = ctrl->value;
+                       if (mfc_mem_get_user_shared_handle(ctx, &dec->sh_handle))
+                               return -EINVAL;
+                       else
+                               mfc_debug(2, "[MEMINFO][DPB] shared handle fd: %d, vaddr: 0x%p\n",
+                                               dec->sh_handle.fd, dec->sh_handle.vaddr);
+               }
+               break;
+       case V4L2_CID_MPEG_MFC_SET_BUF_PROCESS_TYPE:
+               ctx->buf_process_type = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_BLACK_BAR_DETECT:
+               dec->detect_black_bar = ctrl->value;
+               break;
+       default:
+               list_for_each_entry(ctx_ctrl, &ctx->ctrls, list) {
+                       if (!(ctx_ctrl->type & MFC_CTRL_TYPE_SET))
+                               continue;
+
+                       if (ctx_ctrl->id == ctrl->id) {
+                               ctx_ctrl->has_new = 1;
+                               ctx_ctrl->val = ctrl->value;
+
+                               found = 1;
+                               break;
+                       }
+               }
+
+               if (!found) {
+                       mfc_err_ctx("Invalid control: 0x%08x\n", ctrl->id);
+                       return -EINVAL;
+               }
+               break;
+       }
+
+       mfc_debug_leave();
+
+       return 0;
+}
+
+/* Get cropping information */
+static int vidioc_g_crop(struct file *file, void *priv,
+               struct v4l2_crop *cr)
+{
+       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+       struct mfc_dec *dec = ctx->dec_priv;
+
+       mfc_debug_enter();
+
+       if (!ready_to_get_crop(ctx)) {
+               mfc_debug(2, "ready to get crop failed\n");
+               return -EINVAL;
+       }
+
+       if (ctx->state == MFCINST_RUNNING && dec->detect_black_bar
+                       && dec->black_bar_updated) {
+               cr->c.left = dec->black_bar.left;
+               cr->c.top = dec->black_bar.top;
+               cr->c.width = dec->black_bar.width;
+               cr->c.height = dec->black_bar.height;
+               mfc_debug(2, "[FRAME][BLACKBAR] Cropping info: l=%d t=%d w=%d h=%d\n",
+                               dec->black_bar.left,
+                               dec->black_bar.top,
+                               dec->black_bar.width,
+                               dec->black_bar.height);
+       } else {
+               if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_H264 ||
+                       ctx->src_fmt->fourcc == V4L2_PIX_FMT_HEVC ||
+                       ctx->src_fmt->fourcc == V4L2_PIX_FMT_BPG) {
+                       cr->c.left = dec->cr_left;
+                       cr->c.top = dec->cr_top;
+                       cr->c.width = ctx->img_width - dec->cr_left - dec->cr_right;
+                       cr->c.height = ctx->img_height - dec->cr_top - dec->cr_bot;
+                       mfc_debug(2, "[FRAME] Cropping info: l=%d t=%d " \
+                                       "w=%d h=%d (r=%d b=%d fw=%d fh=%d)\n",
+                                       dec->cr_left, dec->cr_top,
+                                       cr->c.width, cr->c.height,
+                                       dec->cr_right, dec->cr_bot,
+                                       ctx->img_width, ctx->img_height);
+               } else {
+                       cr->c.left = 0;
+                       cr->c.top = 0;
+                       cr->c.width = ctx->img_width;
+                       cr->c.height = ctx->img_height;
+                       mfc_debug(2, "[FRAME] Cropping info: w=%d h=%d fw=%d fh=%d\n",
+                                       cr->c.width, cr->c.height,
+                                       ctx->img_width, ctx->img_height);
+               }
+       }
+
+       mfc_debug_leave();
+       return 0;
+}
+
+static int vidioc_g_ext_ctrls(struct file *file, void *priv,
+                       struct v4l2_ext_controls *f)
+{
+       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+       struct v4l2_ext_control *ext_ctrl;
+       struct v4l2_control ctrl;
+       int i;
+       int ret = 0;
+
+       if (f->which != V4L2_CTRL_CLASS_MPEG)
+               return -EINVAL;
+
+       for (i = 0; i < f->count; i++) {
+               ext_ctrl = (f->controls + i);
+
+               ctrl.id = ext_ctrl->id;
+
+               ret = __mfc_dec_get_ctrl_val(ctx, &ctrl);
+               if (ret == 0) {
+                       ext_ctrl->value = ctrl.value;
+               } else {
+                       f->error_idx = i;
+                       break;
+               }
+
+               mfc_debug(5, "[CTRLS][%d] id: %#x, value: %d\n",
+                               i, ext_ctrl->id, ext_ctrl->value);
+       }
+
+       return ret;
+}
+
+/* v4l2_ioctl_ops */
+static const struct v4l2_ioctl_ops mfc_dec_ioctl_ops = {
+       .vidioc_querycap                = vidioc_querycap,
+       .vidioc_enum_fmt_vid_cap_mplane = vidioc_enum_fmt_vid_cap_mplane,
+       .vidioc_enum_fmt_vid_out_mplane = vidioc_enum_fmt_vid_out_mplane,
+       .vidioc_g_fmt_vid_cap_mplane    = vidioc_g_fmt_vid_cap_mplane,
+       .vidioc_g_fmt_vid_out_mplane    = vidioc_g_fmt_vid_out_mplane,
+       .vidioc_try_fmt_vid_cap_mplane  = vidioc_try_fmt,
+       .vidioc_try_fmt_vid_out_mplane  = vidioc_try_fmt,
+       .vidioc_s_fmt_vid_cap_mplane    = vidioc_s_fmt_vid_cap_mplane,
+       .vidioc_s_fmt_vid_out_mplane    = vidioc_s_fmt_vid_out_mplane,
+       .vidioc_reqbufs                 = vidioc_reqbufs,
+       .vidioc_querybuf                = vidioc_querybuf,
+       .vidioc_qbuf                    = vidioc_qbuf,
+       .vidioc_dqbuf                   = vidioc_dqbuf,
+       .vidioc_streamon                = vidioc_streamon,
+       .vidioc_streamoff               = vidioc_streamoff,
+       .vidioc_queryctrl               = vidioc_queryctrl,
+       .vidioc_g_ctrl                  = vidioc_g_ctrl,
+       .vidioc_s_ctrl                  = vidioc_s_ctrl,
+       .vidioc_g_crop                  = vidioc_g_crop,
+       .vidioc_g_ext_ctrls             = vidioc_g_ext_ctrls,
+};
+
+const struct v4l2_ioctl_ops *mfc_get_dec_v4l2_ioctl_ops(void)
+{
+       return &mfc_dec_ioctl_ops;
+}
diff --git a/drivers/media/platform/exynos/mfc/mfc_dec_v4l2.h b/drivers/media/platform/exynos/mfc/mfc_dec_v4l2.h
new file mode 100644 (file)
index 0000000..2617461
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * drivers/media/platform/exynos/mfc/mfc_dec_v4l2.h
+ *
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __MFC_DEC_V4L2_H
+#define __MFC_DEC_V4L2_H __FILE__
+
+#include "mfc_common.h"
+
+const struct v4l2_ioctl_ops *mfc_get_dec_v4l2_ioctl_ops(void);
+
+#endif /* __MFC_DEC_V4L2_H */
diff --git a/drivers/media/platform/exynos/mfc/mfc_dec_vb2.c b/drivers/media/platform/exynos/mfc/mfc_dec_vb2.c
new file mode 100644 (file)
index 0000000..a07446e
--- /dev/null
@@ -0,0 +1,633 @@
+/*
+ * drivers/media/platform/exynos/mfc/mfc_dec_vb2_ops.c
+ *
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include  "mfc_common.h"
+
+#include "mfc_hwlock.h"
+#include "mfc_nal_q.h"
+#include "mfc_opr.h"
+#include "mfc_sync.h"
+
+#include "mfc_queue.h"
+#include "mfc_utils.h"
+#include "mfc_buf.h"
+#include "mfc_mem.h"
+
+static int mfc_dec_queue_setup(struct vb2_queue *vq,
+                               unsigned int *buf_count, unsigned int *plane_count,
+                               unsigned int psize[], struct device *alloc_devs[])
+{
+       struct mfc_ctx *ctx;
+       struct mfc_dev *dev;
+       struct mfc_dec *dec;
+       struct mfc_raw_info *raw;
+       int i;
+
+       mfc_debug_enter();
+
+       if (!vq) {
+               mfc_err_dev("no vb2_queue info\n");
+               return -EINVAL;
+       }
+
+       ctx = vq->drv_priv;
+       if (!ctx) {
+               mfc_err_dev("no mfc context to run\n");
+               return -EINVAL;
+       }
+       dev = ctx->dev;
+       if (!dev) {
+               mfc_err_dev("no mfc device to run\n");
+               return -EINVAL;
+       }
+       dec = ctx->dec_priv;
+       if (!dec) {
+               mfc_err_dev("no mfc decoder to run\n");
+               return -EINVAL;
+       }
+
+       raw = &ctx->raw_buf;
+
+       /* Video output for decoding (source)
+        * this can be set after getting an instance */
+       if (ctx->state == MFCINST_GOT_INST &&
+           vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+               mfc_debug(4, "dec src\n");
+               /* A single plane is required for input */
+               *plane_count = 1;
+               if (*buf_count < 1)
+                       *buf_count = 1;
+               if (*buf_count > MFC_MAX_BUFFERS)
+                       *buf_count = MFC_MAX_BUFFERS;
+
+               psize[0] = dec->src_buf_size;
+               alloc_devs[0] = dev->device;
+       /* Video capture for decoding (destination)
+        * this can be set after the header was parsed */
+       } else if (ctx->state == MFCINST_HEAD_PARSED &&
+                  vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+               mfc_debug(4, "dec dst\n");
+               /* Output plane count is different by the pixel format */
+               *plane_count = ctx->dst_fmt->mem_planes;
+               /* Setup buffer count */
+               if (*buf_count < ctx->dpb_count)
+                       *buf_count = ctx->dpb_count;
+               if (*buf_count > MFC_MAX_BUFFERS)
+                       *buf_count = MFC_MAX_BUFFERS;
+
+               if (ctx->dst_fmt->mem_planes == 1) {
+                       psize[0] = raw->total_plane_size;
+                       alloc_devs[0] = dev->device;
+               } else {
+                       for (i = 0; i < ctx->dst_fmt->num_planes; i++) {
+                               psize[i] = raw->plane_size[i];
+                               alloc_devs[i] = dev->device;
+                       }
+               }
+       } else {
+               mfc_err_ctx("State seems invalid. State = %d, vq->type = %d\n",
+                                                       ctx->state, vq->type);
+               return -EINVAL;
+       }
+
+       mfc_debug(2, "buf_count: %d, plane_count: %d, type: %#x\n",
+                       *buf_count, *plane_count, vq->type);
+       for (i = 0; i < *plane_count; i++)
+               mfc_debug(2, "plane[%d] size: %d\n", i, psize[i]);
+
+       mfc_debug_leave();
+
+       return 0;
+}
+
+static void mfc_dec_unlock(struct vb2_queue *q)
+{
+       struct mfc_ctx *ctx = q->drv_priv;
+       struct mfc_dev *dev;
+
+       if (!ctx) {
+               mfc_err_dev("no mfc context to run\n");
+               return;
+       }
+       dev = ctx->dev;
+       if (!dev) {
+               mfc_err_dev("no mfc device to run\n");
+               return;
+       }
+
+       mutex_unlock(&dev->mfc_mutex);
+}
+
+static void mfc_dec_lock(struct vb2_queue *q)
+{
+       struct mfc_ctx *ctx = q->drv_priv;
+       struct mfc_dev *dev;
+
+       if (!ctx) {
+               mfc_err_dev("no mfc context to run\n");
+               return;
+       }
+       dev = ctx->dev;
+       if (!dev) {
+               mfc_err_dev("no mfc device to run\n");
+               return;
+       }
+
+       mutex_lock(&dev->mfc_mutex);
+}
+
+static int mfc_dec_buf_init(struct vb2_buffer *vb)
+{
+       struct vb2_queue *vq = vb->vb2_queue;
+       struct mfc_ctx *ctx = vq->drv_priv;
+       struct mfc_dev *dev;
+       struct mfc_dec *dec;
+       struct mfc_buf *buf = vb_to_mfc_buf(vb);
+       dma_addr_t start_raw;
+       int i, ret;
+
+       mfc_debug_enter();
+       if (!ctx) {
+               mfc_err_dev("no mfc context to run\n");
+               return -EINVAL;
+       }
+       dev = ctx->dev;
+       if (!dev) {
+               mfc_err_dev("no mfc device to run\n");
+               return -EINVAL;
+       }
+       dec = ctx->dec_priv;
+       if (!dec) {
+               mfc_err_dev("no mfc decoder to run\n");
+               return -EINVAL;
+       }
+
+       if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+               ret = mfc_check_vb_with_fmt(ctx->dst_fmt, vb);
+               if (ret < 0)
+                       return ret;
+
+               start_raw = mfc_mem_get_daddr_vb(vb, 0);
+               if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_NV12N) {
+                       buf->addr[0][0] = start_raw;
+                       buf->addr[0][1] = NV12N_CBCR_BASE(start_raw,
+                                                       ctx->img_width,
+                                                       ctx->img_height);
+               } else if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_NV12N_10B) {
+                       buf->addr[0][0] = start_raw;
+                       buf->addr[0][1] = NV12N_10B_CBCR_BASE(start_raw,
+                                                       ctx->img_width,
+                                                       ctx->img_height);
+               } else if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420N) {
+                       buf->addr[0][0] = start_raw;
+                       buf->addr[0][1] = YUV420N_CB_BASE(start_raw,
+                                                       ctx->img_width,
+                                                       ctx->img_height);
+                       buf->addr[0][2] = YUV420N_CR_BASE(start_raw,
+                                                       ctx->img_width,
+                                                       ctx->img_height);
+               } else {
+                       for (i = 0; i < ctx->dst_fmt->mem_planes; i++)
+                               buf->addr[0][i] = mfc_mem_get_daddr_vb(vb, i);
+               }
+
+               if (call_cop(ctx, init_buf_ctrls, ctx, MFC_CTRL_TYPE_DST,
+                                       vb->index) < 0)
+                       mfc_err_ctx("failed in init_buf_ctrls\n");
+       } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+               ret = mfc_check_vb_with_fmt(ctx->src_fmt, vb);
+               if (ret < 0)
+                       return ret;
+
+               buf->addr[0][0] = mfc_mem_get_daddr_vb(vb, 0);
+
+               if (call_cop(ctx, init_buf_ctrls, ctx, MFC_CTRL_TYPE_SRC,
+                                       vb->index) < 0)
+                       mfc_err_ctx("failed in init_buf_ctrls\n");
+       } else {
+               mfc_err_ctx("mfc_dec_buf_init: unknown queue type\n");
+               return -EINVAL;
+       }
+
+       mfc_debug_leave();
+
+       return 0;
+}
+
+static int mfc_dec_buf_prepare(struct vb2_buffer *vb)
+{
+       struct vb2_queue *vq = vb->vb2_queue;
+       struct mfc_ctx *ctx = vq->drv_priv;
+       struct mfc_dec *dec;
+       struct mfc_raw_info *raw;
+       unsigned int index = vb->index;
+       size_t buf_size;
+       int i;
+
+       if (!ctx) {
+               mfc_err_dev("no mfc context to run\n");
+               return -EINVAL;
+       }
+       dec = ctx->dec_priv;
+       if (!dec) {
+               mfc_err_dev("no mfc decoder to run\n");
+               return -EINVAL;
+       }
+       if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+               raw = &ctx->raw_buf;
+               /* check the size per plane */
+               if (ctx->dst_fmt->mem_planes == 1) {
+                       buf_size = vb2_plane_size(vb, 0);
+                       mfc_debug(2, "[FRAME] single plane vb size: %lu, calc size: %d\n",
+                                       buf_size, raw->total_plane_size);
+                       if (buf_size < raw->total_plane_size) {
+                               mfc_err_ctx("[FRAME] single plane size(%d) is smaller than (%d)\n",
+                                               buf_size, raw->total_plane_size);
+                               return -EINVAL;
+                       }
+               } else {
+                       for (i = 0; i < ctx->dst_fmt->mem_planes; i++) {
+                               buf_size = vb2_plane_size(vb, i);
+                               mfc_debug(2, "[FRAME] plane[%d] vb size: %lu, calc size: %d\n",
+                                               i, buf_size, raw->plane_size[i]);
+                               if (buf_size < raw->plane_size[i]) {
+                                       mfc_err_ctx("[FRAME] plane[%d] size(%d) is smaller than (%d)\n",
+                                                       i, buf_size, raw->plane_size[i]);
+                                       return -EINVAL;
+                               }
+                       }
+               }
+       } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+               buf_size = vb2_plane_size(vb, 0);
+               mfc_debug(2, "[STREAM] vb size: %lu, calc size: %d\n",
+                               buf_size, dec->src_buf_size);
+
+               if (buf_size < dec->src_buf_size) {
+                       mfc_err_ctx("[STREAM] size(%d) is smaller than (%d)\n",
+                                       buf_size, dec->src_buf_size);
+                       return -EINVAL;
+               }
+
+               if (call_cop(ctx, to_buf_ctrls, ctx, &ctx->src_ctrls[index]) < 0)
+                       mfc_err_ctx("failed in to_buf_ctrls\n");
+       }
+
+       return 0;
+}
+
+static void mfc_dec_buf_finish(struct vb2_buffer *vb)
+{
+       struct vb2_queue *vq = vb->vb2_queue;
+       struct mfc_ctx *ctx = vq->drv_priv;
+       unsigned int index = vb->index;
+
+       if (!ctx) {
+               mfc_err_dev("no mfc context to run\n");
+               return;
+       }
+
+       if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+               if (call_cop(ctx, to_ctx_ctrls, ctx, &ctx->dst_ctrls[index]) < 0)
+                       mfc_err_ctx("failed in to_ctx_ctrls\n");
+       } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+               if (call_cop(ctx, to_ctx_ctrls, ctx, &ctx->src_ctrls[index]) < 0)
+                       mfc_err_ctx("failed in to_ctx_ctrls\n");
+       }
+}
+
+static void mfc_dec_buf_cleanup(struct vb2_buffer *vb)
+{
+       struct vb2_queue *vq = vb->vb2_queue;
+       struct mfc_ctx *ctx = vq->drv_priv;
+       unsigned int index = vb->index;
+
+       mfc_debug_enter();
+       if (!ctx) {
+               mfc_err_dev("no mfc context to run\n");
+               return;
+       }
+
+       if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+               if (call_cop(ctx, cleanup_buf_ctrls, ctx,
+                                       MFC_CTRL_TYPE_DST, index) < 0)
+                       mfc_err_ctx("failed in cleanup_buf_ctrls\n");
+       } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+               if (call_cop(ctx, cleanup_buf_ctrls, ctx,
+                                       MFC_CTRL_TYPE_SRC, index) < 0)
+                       mfc_err_ctx("failed in cleanup_buf_ctrls\n");
+       } else {
+               mfc_err_ctx("mfc_dec_buf_cleanup: unknown queue type\n");
+       }
+
+       mfc_debug_leave();
+}
+
+static int mfc_dec_start_streaming(struct vb2_queue *q, unsigned int count)
+{
+       struct mfc_ctx *ctx = q->drv_priv;
+       struct mfc_dev *dev;
+
+       if (!ctx) {
+               mfc_err_dev("no mfc context to run\n");
+               return -EINVAL;
+       }
+
+       dev = ctx->dev;
+       if (!dev) {
+               mfc_err_dev("no mfc device to run\n");
+               return -EINVAL;
+       }
+
+       if (ctx->state == MFCINST_FINISHING)
+               mfc_change_state(ctx, MFCINST_RUNNING);
+
+       /* If context is ready then dev = work->data;schedule it to run */
+       if (mfc_dec_ctx_ready(ctx)) {
+               mfc_set_bit(ctx->num, &dev->work_bits);
+       }
+
+       mfc_try_run(dev);
+
+       return 0;
+}
+
+static void __mfc_dec_src_stop_streaming(struct mfc_ctx *ctx)
+{
+       struct mfc_dev *dev;
+       struct mfc_dec *dec;
+       struct mfc_buf *src_mb;
+       int index, csd, condition = 0;
+       int ret = 0;
+
+       dev = ctx->dev;
+       if (!dev) {
+               mfc_err_dev("no mfc device to run\n");
+               return;
+       }
+
+       dec = ctx->dec_priv;
+       if (!dec) {
+               mfc_err_dev("no mfc decoder to run\n");
+               return;
+       }
+
+       while (1) {
+               csd = mfc_peek_buf_csd(&ctx->buf_queue_lock, &ctx->src_buf_queue);
+
+               if (csd == 1) {
+                       mfc_clean_ctx_int_flags(ctx);
+                       if (need_to_special_parsing(ctx)) {
+                               mfc_change_state(ctx, MFCINST_SPECIAL_PARSING);
+                               condition = MFC_REG_R2H_CMD_SEQ_DONE_RET;
+                               mfc_info_ctx("try to special parsing! (before NAL_START)\n");
+                       } else if (need_to_special_parsing_nal(ctx)) {
+                               mfc_change_state(ctx, MFCINST_SPECIAL_PARSING_NAL);
+                               condition = MFC_REG_R2H_CMD_FRAME_DONE_RET;
+                               mfc_info_ctx("try to special parsing! (after NAL_START)\n");
+                       } else {
+                               mfc_info_ctx("can't parsing CSD!, state = %d\n", ctx->state);
+                       }
+
+                       if (condition) {
+                               mfc_set_bit(ctx->num, &dev->work_bits);
+
+                               ret = mfc_just_run(dev, ctx->num);
+                               if (ret) {
+                                       mfc_err_ctx("Failed to run MFC\n");
+                               } else {
+                                       if (mfc_wait_for_done_ctx(ctx, condition))
+                                               mfc_err_ctx("special parsing time out\n");
+                               }
+                       }
+               }
+
+               src_mb = mfc_get_del_buf(&ctx->buf_queue_lock, &ctx->src_buf_queue, MFC_BUF_NO_TOUCH_USED);
+               if (!src_mb)
+                       break;
+
+               index = src_mb->vb.vb2_buf.index;
+
+               if (ctx->is_drm)
+                       mfc_stream_unprotect(ctx, src_mb, index);
+               vb2_set_plane_payload(&src_mb->vb.vb2_buf, 0, 0);
+               vb2_buffer_done(&src_mb->vb.vb2_buf, VB2_BUF_STATE_ERROR);
+       }
+
+       dec->consumed = 0;
+       dec->remained_size = 0;
+       ctx->check_dump = 0;
+
+       mfc_init_queue(&ctx->src_buf_queue);
+
+       index = 0;
+       while (index < MFC_MAX_BUFFERS) {
+               index = find_next_bit(&ctx->src_ctrls_avail,
+                               MFC_MAX_BUFFERS, index);
+               if (index < MFC_MAX_BUFFERS)
+                       call_cop(ctx, reset_buf_ctrls, &ctx->src_ctrls[index]);
+               index++;
+       }
+}
+
+static void __mfc_dec_dst_stop_streaming(struct mfc_ctx *ctx)
+{
+       struct mfc_dec *dec;
+       int index = 0;
+
+       dec = ctx->dec_priv;
+       if (!dec) {
+               mfc_err_dev("no mfc decoder to run\n");
+               return;
+       }
+
+       mfc_cleanup_assigned_fd(ctx);
+       mfc_cleanup_queue(&ctx->buf_queue_lock, &ctx->ref_buf_queue);
+
+       dec->dynamic_used = 0;
+       dec->err_reuse_flag = 0;
+       dec->dec_only_release_flag = 0;
+
+       mfc_cleanup_queue(&ctx->buf_queue_lock, &ctx->dst_buf_queue);
+
+       ctx->is_dpb_realloc = 0;
+       dec->available_dpb = 0;
+
+       dec->y_addr_for_pb = 0;
+
+       mfc_cleanup_assigned_dpb(ctx);
+
+       while (index < MFC_MAX_BUFFERS) {
+               index = find_next_bit(&ctx->dst_ctrls_avail,
+                               MFC_MAX_BUFFERS, index);
+               if (index < MFC_MAX_BUFFERS)
+                       call_cop(ctx, reset_buf_ctrls, &ctx->dst_ctrls[index]);
+               index++;
+       }
+
+       if (ctx->wait_state == WAIT_INITBUF_DONE ||
+                       ctx->wait_state == WAIT_DECODING) {
+               ctx->wait_state = WAIT_NONE;
+               mfc_debug(2, "Decoding can be started now\n");
+       }
+}
+
+static void mfc_dec_stop_streaming(struct vb2_queue *q)
+{
+       struct mfc_ctx *ctx = q->drv_priv;
+       struct mfc_dev *dev;
+       int ret = 0;
+       int prev_state;
+
+       if (!ctx) {
+               mfc_err_dev("no mfc context to run\n");
+               return;
+       }
+
+       dev = ctx->dev;
+       if (!dev) {
+               mfc_err_dev("no mfc device to run\n");
+               return;
+       }
+
+       mfc_info_ctx("dec stop_streaming is called, hwlock : %d, type : %d\n",
+                               test_bit(ctx->num, &dev->hwlock.bits), q->type);
+       MFC_TRACE_CTX("** DEC streamoff(type:%d)\n", q->type);
+
+       MFC_TRACE_CTX_HWLOCK("**DEC streamoff(type:%d)\n", q->type);
+       /* If a H/W operation is in progress, wait for it complete */
+       ret = mfc_get_hwlock_ctx(ctx);
+       if (ret < 0) {
+               mfc_err_ctx("Failed to get hwlock\n");
+               return;
+       }
+
+       if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+               __mfc_dec_dst_stop_streaming(ctx);
+       else if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+               __mfc_dec_src_stop_streaming(ctx);
+
+       if (ctx->state == MFCINST_FINISHING)
+               mfc_change_state(ctx, MFCINST_RUNNING);
+
+       if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && need_to_dpb_flush(ctx)) {
+               prev_state = ctx->state;
+               mfc_change_state(ctx, MFCINST_DPB_FLUSHING);
+               mfc_set_bit(ctx->num, &dev->work_bits);
+               mfc_clean_ctx_int_flags(ctx);
+               mfc_info_ctx("try to DPB flush\n");
+               ret = mfc_just_run(dev, ctx->num);
+               if (ret) {
+                       mfc_err_ctx("Failed to run MFC\n");
+                       mfc_release_hwlock_ctx(ctx);
+                       mfc_cleanup_work_bit_and_try_run(ctx);
+                       return;
+               }
+
+               if (mfc_wait_for_done_ctx(ctx, MFC_REG_R2H_CMD_DPB_FLUSH_RET)) {
+                       mfc_err_ctx("time out during DPB flush\n");
+                       dev->logging_data->cause |= (1 << MFC_CAUSE_FAIL_DPB_FLUSH);
+                       call_dop(dev, dump_and_stop_always, dev);
+               }
+
+               mfc_change_state(ctx, prev_state);
+       }
+
+       mfc_debug(2, "buffer cleanup & flush is done in stop_streaming, type : %d\n", q->type);
+
+       mfc_clear_bit(ctx->num, &dev->work_bits);
+       mfc_release_hwlock_ctx(ctx);
+
+       if (mfc_dec_ctx_ready(ctx))
+               mfc_set_bit(ctx->num, &dev->work_bits);
+       if (mfc_is_work_to_do(dev))
+               queue_work(dev->butler_wq, &dev->butler_work);
+}
+
+static void mfc_dec_buf_queue(struct vb2_buffer *vb)
+{
+       struct vb2_queue *vq = vb->vb2_queue;
+       struct mfc_ctx *ctx = vq->drv_priv;
+       struct mfc_dev *dev;
+       struct mfc_dec *dec;
+       struct mfc_buf *buf = vb_to_mfc_buf(vb);
+       int i;
+       unsigned char *stream_vir = NULL;
+
+       mfc_debug_enter();
+       if (!ctx) {
+               mfc_err_dev("no mfc context to run\n");
+               return;
+       }
+
+       dev = ctx->dev;
+       if (!dev) {
+               mfc_err_dev("no mfc device to run\n");
+               return;
+       }
+
+       dec = ctx->dec_priv;
+       if (!dec) {
+               mfc_err_dev("no mfc decoder to run\n");
+               return;
+       }
+
+       if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+               mfc_debug(2, "[BUFINFO] ctx[%d] add src index:%d, addr: 0x%08llx\n",
+                               ctx->num, vb->index, buf->addr[0][0]);
+               if (dec->dst_memtype == V4L2_MEMORY_DMABUF &&
+                               ctx->state < MFCINST_HEAD_PARSED && !ctx->is_drm)
+                       stream_vir = vb2_plane_vaddr(vb, 0);
+
+               buf->vir_addr = stream_vir;
+
+               mfc_add_tail_buf(&ctx->buf_queue_lock, &ctx->src_buf_queue, buf);
+
+               MFC_TRACE_CTX("Q src[%d] fd: %d, %#llx\n",
+                               vb->index, vb->planes[0].m.fd, buf->addr[0][0]);
+       } else if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+               for (i = 0; i < ctx->dst_fmt->mem_planes; i++)
+                       mfc_debug(2, "[BUFINFO] ctx[%d] add dst index: %d, addr[%d]: 0x%08llx\n",
+                                       ctx->num, vb->index, i, buf->addr[0][i]);
+               mfc_store_dpb(ctx, vb);
+
+               if ((dec->dst_memtype == V4L2_MEMORY_USERPTR || dec->dst_memtype == V4L2_MEMORY_DMABUF) &&
+                               mfc_is_queue_count_same(&ctx->buf_queue_lock,
+                                       &ctx->dst_buf_queue, dec->total_dpb_count))
+                       ctx->capture_state = QUEUE_BUFS_MMAPED;
+
+               MFC_TRACE_CTX("Q dst[%d] fd: %d, %#llx / avail %#lx used %#x\n",
+                               vb->index, vb->planes[0].m.fd, buf->addr[0][0],
+                               dec->available_dpb, dec->dynamic_used);
+       } else {
+               mfc_err_ctx("Unsupported buffer type (%d)\n", vq->type);
+       }
+
+       if (mfc_dec_ctx_ready(ctx)) {
+               mfc_set_bit(ctx->num, &dev->work_bits);
+               mfc_try_run(dev);
+       }
+
+       mfc_debug_leave();
+}
+
+struct vb2_ops mfc_dec_qops = {
+       .queue_setup            = mfc_dec_queue_setup,
+       .wait_prepare           = mfc_dec_unlock,
+       .wait_finish            = mfc_dec_lock,
+       .buf_init               = mfc_dec_buf_init,
+       .buf_prepare            = mfc_dec_buf_prepare,
+       .buf_finish             = mfc_dec_buf_finish,
+       .buf_cleanup            = mfc_dec_buf_cleanup,
+       .start_streaming        = mfc_dec_start_streaming,
+       .stop_streaming         = mfc_dec_stop_streaming,
+       .buf_queue              = mfc_dec_buf_queue,
+};
diff --git a/drivers/media/platform/exynos/mfc/mfc_dec_vb2_ops.c b/drivers/media/platform/exynos/mfc/mfc_dec_vb2_ops.c
deleted file mode 100644 (file)
index a07446e..0000000
+++ /dev/null
@@ -1,633 +0,0 @@
-/*
- * drivers/media/platform/exynos/mfc/mfc_dec_vb2_ops.c
- *
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include  "mfc_common.h"
-
-#include "mfc_hwlock.h"
-#include "mfc_nal_q.h"
-#include "mfc_opr.h"
-#include "mfc_sync.h"
-
-#include "mfc_queue.h"
-#include "mfc_utils.h"
-#include "mfc_buf.h"
-#include "mfc_mem.h"
-
-static int mfc_dec_queue_setup(struct vb2_queue *vq,
-                               unsigned int *buf_count, unsigned int *plane_count,
-                               unsigned int psize[], struct device *alloc_devs[])
-{
-       struct mfc_ctx *ctx;
-       struct mfc_dev *dev;
-       struct mfc_dec *dec;
-       struct mfc_raw_info *raw;
-       int i;
-
-       mfc_debug_enter();
-
-       if (!vq) {
-               mfc_err_dev("no vb2_queue info\n");
-               return -EINVAL;
-       }
-
-       ctx = vq->drv_priv;
-       if (!ctx) {
-               mfc_err_dev("no mfc context to run\n");
-               return -EINVAL;
-       }
-       dev = ctx->dev;
-       if (!dev) {
-               mfc_err_dev("no mfc device to run\n");
-               return -EINVAL;
-       }
-       dec = ctx->dec_priv;
-       if (!dec) {
-               mfc_err_dev("no mfc decoder to run\n");
-               return -EINVAL;
-       }
-
-       raw = &ctx->raw_buf;
-
-       /* Video output for decoding (source)
-        * this can be set after getting an instance */
-       if (ctx->state == MFCINST_GOT_INST &&
-           vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
-               mfc_debug(4, "dec src\n");
-               /* A single plane is required for input */
-               *plane_count = 1;
-               if (*buf_count < 1)
-                       *buf_count = 1;
-               if (*buf_count > MFC_MAX_BUFFERS)
-                       *buf_count = MFC_MAX_BUFFERS;
-
-               psize[0] = dec->src_buf_size;
-               alloc_devs[0] = dev->device;
-       /* Video capture for decoding (destination)
-        * this can be set after the header was parsed */
-       } else if (ctx->state == MFCINST_HEAD_PARSED &&
-                  vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-               mfc_debug(4, "dec dst\n");
-               /* Output plane count is different by the pixel format */
-               *plane_count = ctx->dst_fmt->mem_planes;
-               /* Setup buffer count */
-               if (*buf_count < ctx->dpb_count)
-                       *buf_count = ctx->dpb_count;
-               if (*buf_count > MFC_MAX_BUFFERS)
-                       *buf_count = MFC_MAX_BUFFERS;
-
-               if (ctx->dst_fmt->mem_planes == 1) {
-                       psize[0] = raw->total_plane_size;
-                       alloc_devs[0] = dev->device;
-               } else {
-                       for (i = 0; i < ctx->dst_fmt->num_planes; i++) {
-                               psize[i] = raw->plane_size[i];
-                               alloc_devs[i] = dev->device;
-                       }
-               }
-       } else {
-               mfc_err_ctx("State seems invalid. State = %d, vq->type = %d\n",
-                                                       ctx->state, vq->type);
-               return -EINVAL;
-       }
-
-       mfc_debug(2, "buf_count: %d, plane_count: %d, type: %#x\n",
-                       *buf_count, *plane_count, vq->type);
-       for (i = 0; i < *plane_count; i++)
-               mfc_debug(2, "plane[%d] size: %d\n", i, psize[i]);
-
-       mfc_debug_leave();
-
-       return 0;
-}
-
-static void mfc_dec_unlock(struct vb2_queue *q)
-{
-       struct mfc_ctx *ctx = q->drv_priv;
-       struct mfc_dev *dev;
-
-       if (!ctx) {
-               mfc_err_dev("no mfc context to run\n");
-               return;
-       }
-       dev = ctx->dev;
-       if (!dev) {
-               mfc_err_dev("no mfc device to run\n");
-               return;
-       }
-
-       mutex_unlock(&dev->mfc_mutex);
-}
-
-static void mfc_dec_lock(struct vb2_queue *q)
-{
-       struct mfc_ctx *ctx = q->drv_priv;
-       struct mfc_dev *dev;
-
-       if (!ctx) {
-               mfc_err_dev("no mfc context to run\n");
-               return;
-       }
-       dev = ctx->dev;
-       if (!dev) {
-               mfc_err_dev("no mfc device to run\n");
-               return;
-       }
-
-       mutex_lock(&dev->mfc_mutex);
-}
-
-static int mfc_dec_buf_init(struct vb2_buffer *vb)
-{
-       struct vb2_queue *vq = vb->vb2_queue;
-       struct mfc_ctx *ctx = vq->drv_priv;
-       struct mfc_dev *dev;
-       struct mfc_dec *dec;
-       struct mfc_buf *buf = vb_to_mfc_buf(vb);
-       dma_addr_t start_raw;
-       int i, ret;
-
-       mfc_debug_enter();
-       if (!ctx) {
-               mfc_err_dev("no mfc context to run\n");
-               return -EINVAL;
-       }
-       dev = ctx->dev;
-       if (!dev) {
-               mfc_err_dev("no mfc device to run\n");
-               return -EINVAL;
-       }
-       dec = ctx->dec_priv;
-       if (!dec) {
-               mfc_err_dev("no mfc decoder to run\n");
-               return -EINVAL;
-       }
-
-       if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-               ret = mfc_check_vb_with_fmt(ctx->dst_fmt, vb);
-               if (ret < 0)
-                       return ret;
-
-               start_raw = mfc_mem_get_daddr_vb(vb, 0);
-               if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_NV12N) {
-                       buf->addr[0][0] = start_raw;
-                       buf->addr[0][1] = NV12N_CBCR_BASE(start_raw,
-                                                       ctx->img_width,
-                                                       ctx->img_height);
-               } else if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_NV12N_10B) {
-                       buf->addr[0][0] = start_raw;
-                       buf->addr[0][1] = NV12N_10B_CBCR_BASE(start_raw,
-                                                       ctx->img_width,
-                                                       ctx->img_height);
-               } else if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420N) {
-                       buf->addr[0][0] = start_raw;
-                       buf->addr[0][1] = YUV420N_CB_BASE(start_raw,
-                                                       ctx->img_width,
-                                                       ctx->img_height);
-                       buf->addr[0][2] = YUV420N_CR_BASE(start_raw,
-                                                       ctx->img_width,
-                                                       ctx->img_height);
-               } else {
-                       for (i = 0; i < ctx->dst_fmt->mem_planes; i++)
-                               buf->addr[0][i] = mfc_mem_get_daddr_vb(vb, i);
-               }
-
-               if (call_cop(ctx, init_buf_ctrls, ctx, MFC_CTRL_TYPE_DST,
-                                       vb->index) < 0)
-                       mfc_err_ctx("failed in init_buf_ctrls\n");
-       } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
-               ret = mfc_check_vb_with_fmt(ctx->src_fmt, vb);
-               if (ret < 0)
-                       return ret;
-
-               buf->addr[0][0] = mfc_mem_get_daddr_vb(vb, 0);
-
-               if (call_cop(ctx, init_buf_ctrls, ctx, MFC_CTRL_TYPE_SRC,
-                                       vb->index) < 0)
-                       mfc_err_ctx("failed in init_buf_ctrls\n");
-       } else {
-               mfc_err_ctx("mfc_dec_buf_init: unknown queue type\n");
-               return -EINVAL;
-       }
-
-       mfc_debug_leave();
-
-       return 0;
-}
-
-static int mfc_dec_buf_prepare(struct vb2_buffer *vb)
-{
-       struct vb2_queue *vq = vb->vb2_queue;
-       struct mfc_ctx *ctx = vq->drv_priv;
-       struct mfc_dec *dec;
-       struct mfc_raw_info *raw;
-       unsigned int index = vb->index;
-       size_t buf_size;
-       int i;
-
-       if (!ctx) {
-               mfc_err_dev("no mfc context to run\n");
-               return -EINVAL;
-       }
-       dec = ctx->dec_priv;
-       if (!dec) {
-               mfc_err_dev("no mfc decoder to run\n");
-               return -EINVAL;
-       }
-       if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-               raw = &ctx->raw_buf;
-               /* check the size per plane */
-               if (ctx->dst_fmt->mem_planes == 1) {
-                       buf_size = vb2_plane_size(vb, 0);
-                       mfc_debug(2, "[FRAME] single plane vb size: %lu, calc size: %d\n",
-                                       buf_size, raw->total_plane_size);
-                       if (buf_size < raw->total_plane_size) {
-                               mfc_err_ctx("[FRAME] single plane size(%d) is smaller than (%d)\n",
-                                               buf_size, raw->total_plane_size);
-                               return -EINVAL;
-                       }
-               } else {
-                       for (i = 0; i < ctx->dst_fmt->mem_planes; i++) {
-                               buf_size = vb2_plane_size(vb, i);
-                               mfc_debug(2, "[FRAME] plane[%d] vb size: %lu, calc size: %d\n",
-                                               i, buf_size, raw->plane_size[i]);
-                               if (buf_size < raw->plane_size[i]) {
-                                       mfc_err_ctx("[FRAME] plane[%d] size(%d) is smaller than (%d)\n",
-                                                       i, buf_size, raw->plane_size[i]);
-                                       return -EINVAL;
-                               }
-                       }
-               }
-       } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
-               buf_size = vb2_plane_size(vb, 0);
-               mfc_debug(2, "[STREAM] vb size: %lu, calc size: %d\n",
-                               buf_size, dec->src_buf_size);
-
-               if (buf_size < dec->src_buf_size) {
-                       mfc_err_ctx("[STREAM] size(%d) is smaller than (%d)\n",
-                                       buf_size, dec->src_buf_size);
-                       return -EINVAL;
-               }
-
-               if (call_cop(ctx, to_buf_ctrls, ctx, &ctx->src_ctrls[index]) < 0)
-                       mfc_err_ctx("failed in to_buf_ctrls\n");
-       }
-
-       return 0;
-}
-
-static void mfc_dec_buf_finish(struct vb2_buffer *vb)
-{
-       struct vb2_queue *vq = vb->vb2_queue;
-       struct mfc_ctx *ctx = vq->drv_priv;
-       unsigned int index = vb->index;
-
-       if (!ctx) {
-               mfc_err_dev("no mfc context to run\n");
-               return;
-       }
-
-       if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-               if (call_cop(ctx, to_ctx_ctrls, ctx, &ctx->dst_ctrls[index]) < 0)
-                       mfc_err_ctx("failed in to_ctx_ctrls\n");
-       } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
-               if (call_cop(ctx, to_ctx_ctrls, ctx, &ctx->src_ctrls[index]) < 0)
-                       mfc_err_ctx("failed in to_ctx_ctrls\n");
-       }
-}
-
-static void mfc_dec_buf_cleanup(struct vb2_buffer *vb)
-{
-       struct vb2_queue *vq = vb->vb2_queue;
-       struct mfc_ctx *ctx = vq->drv_priv;
-       unsigned int index = vb->index;
-
-       mfc_debug_enter();
-       if (!ctx) {
-               mfc_err_dev("no mfc context to run\n");
-               return;
-       }
-
-       if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-               if (call_cop(ctx, cleanup_buf_ctrls, ctx,
-                                       MFC_CTRL_TYPE_DST, index) < 0)
-                       mfc_err_ctx("failed in cleanup_buf_ctrls\n");
-       } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
-               if (call_cop(ctx, cleanup_buf_ctrls, ctx,
-                                       MFC_CTRL_TYPE_SRC, index) < 0)
-                       mfc_err_ctx("failed in cleanup_buf_ctrls\n");
-       } else {
-               mfc_err_ctx("mfc_dec_buf_cleanup: unknown queue type\n");
-       }
-
-       mfc_debug_leave();
-}
-
-static int mfc_dec_start_streaming(struct vb2_queue *q, unsigned int count)
-{
-       struct mfc_ctx *ctx = q->drv_priv;
-       struct mfc_dev *dev;
-
-       if (!ctx) {
-               mfc_err_dev("no mfc context to run\n");
-               return -EINVAL;
-       }
-
-       dev = ctx->dev;
-       if (!dev) {
-               mfc_err_dev("no mfc device to run\n");
-               return -EINVAL;
-       }
-
-       if (ctx->state == MFCINST_FINISHING)
-               mfc_change_state(ctx, MFCINST_RUNNING);
-
-       /* If context is ready then dev = work->data;schedule it to run */
-       if (mfc_dec_ctx_ready(ctx)) {
-               mfc_set_bit(ctx->num, &dev->work_bits);
-       }
-
-       mfc_try_run(dev);
-
-       return 0;
-}
-
-static void __mfc_dec_src_stop_streaming(struct mfc_ctx *ctx)
-{
-       struct mfc_dev *dev;
-       struct mfc_dec *dec;
-       struct mfc_buf *src_mb;
-       int index, csd, condition = 0;
-       int ret = 0;
-
-       dev = ctx->dev;
-       if (!dev) {
-               mfc_err_dev("no mfc device to run\n");
-               return;
-       }
-
-       dec = ctx->dec_priv;
-       if (!dec) {
-               mfc_err_dev("no mfc decoder to run\n");
-               return;
-       }
-
-       while (1) {
-               csd = mfc_peek_buf_csd(&ctx->buf_queue_lock, &ctx->src_buf_queue);
-
-               if (csd == 1) {
-                       mfc_clean_ctx_int_flags(ctx);
-                       if (need_to_special_parsing(ctx)) {
-                               mfc_change_state(ctx, MFCINST_SPECIAL_PARSING);
-                               condition = MFC_REG_R2H_CMD_SEQ_DONE_RET;
-                               mfc_info_ctx("try to special parsing! (before NAL_START)\n");
-                       } else if (need_to_special_parsing_nal(ctx)) {
-                               mfc_change_state(ctx, MFCINST_SPECIAL_PARSING_NAL);
-                               condition = MFC_REG_R2H_CMD_FRAME_DONE_RET;
-                               mfc_info_ctx("try to special parsing! (after NAL_START)\n");
-                       } else {
-                               mfc_info_ctx("can't parsing CSD!, state = %d\n", ctx->state);
-                       }
-
-                       if (condition) {
-                               mfc_set_bit(ctx->num, &dev->work_bits);
-
-                               ret = mfc_just_run(dev, ctx->num);
-                               if (ret) {
-                                       mfc_err_ctx("Failed to run MFC\n");
-                               } else {
-                                       if (mfc_wait_for_done_ctx(ctx, condition))
-                                               mfc_err_ctx("special parsing time out\n");
-                               }
-                       }
-               }
-
-               src_mb = mfc_get_del_buf(&ctx->buf_queue_lock, &ctx->src_buf_queue, MFC_BUF_NO_TOUCH_USED);
-               if (!src_mb)
-                       break;
-
-               index = src_mb->vb.vb2_buf.index;
-
-               if (ctx->is_drm)
-                       mfc_stream_unprotect(ctx, src_mb, index);
-               vb2_set_plane_payload(&src_mb->vb.vb2_buf, 0, 0);
-               vb2_buffer_done(&src_mb->vb.vb2_buf, VB2_BUF_STATE_ERROR);
-       }
-
-       dec->consumed = 0;
-       dec->remained_size = 0;
-       ctx->check_dump = 0;
-
-       mfc_init_queue(&ctx->src_buf_queue);
-
-       index = 0;
-       while (index < MFC_MAX_BUFFERS) {
-               index = find_next_bit(&ctx->src_ctrls_avail,
-                               MFC_MAX_BUFFERS, index);
-               if (index < MFC_MAX_BUFFERS)
-                       call_cop(ctx, reset_buf_ctrls, &ctx->src_ctrls[index]);
-               index++;
-       }
-}
-
-static void __mfc_dec_dst_stop_streaming(struct mfc_ctx *ctx)
-{
-       struct mfc_dec *dec;
-       int index = 0;
-
-       dec = ctx->dec_priv;
-       if (!dec) {
-               mfc_err_dev("no mfc decoder to run\n");
-               return;
-       }
-
-       mfc_cleanup_assigned_fd(ctx);
-       mfc_cleanup_queue(&ctx->buf_queue_lock, &ctx->ref_buf_queue);
-
-       dec->dynamic_used = 0;
-       dec->err_reuse_flag = 0;
-       dec->dec_only_release_flag = 0;
-
-       mfc_cleanup_queue(&ctx->buf_queue_lock, &ctx->dst_buf_queue);
-
-       ctx->is_dpb_realloc = 0;
-       dec->available_dpb = 0;
-
-       dec->y_addr_for_pb = 0;
-
-       mfc_cleanup_assigned_dpb(ctx);
-
-       while (index < MFC_MAX_BUFFERS) {
-               index = find_next_bit(&ctx->dst_ctrls_avail,
-                               MFC_MAX_BUFFERS, index);
-               if (index < MFC_MAX_BUFFERS)
-                       call_cop(ctx, reset_buf_ctrls, &ctx->dst_ctrls[index]);
-               index++;
-       }
-
-       if (ctx->wait_state == WAIT_INITBUF_DONE ||
-                       ctx->wait_state == WAIT_DECODING) {
-               ctx->wait_state = WAIT_NONE;
-               mfc_debug(2, "Decoding can be started now\n");
-       }
-}
-
-static void mfc_dec_stop_streaming(struct vb2_queue *q)
-{
-       struct mfc_ctx *ctx = q->drv_priv;
-       struct mfc_dev *dev;
-       int ret = 0;
-       int prev_state;
-
-       if (!ctx) {
-               mfc_err_dev("no mfc context to run\n");
-               return;
-       }
-
-       dev = ctx->dev;
-       if (!dev) {
-               mfc_err_dev("no mfc device to run\n");
-               return;
-       }
-
-       mfc_info_ctx("dec stop_streaming is called, hwlock : %d, type : %d\n",
-                               test_bit(ctx->num, &dev->hwlock.bits), q->type);
-       MFC_TRACE_CTX("** DEC streamoff(type:%d)\n", q->type);
-
-       MFC_TRACE_CTX_HWLOCK("**DEC streamoff(type:%d)\n", q->type);
-       /* If a H/W operation is in progress, wait for it complete */
-       ret = mfc_get_hwlock_ctx(ctx);
-       if (ret < 0) {
-               mfc_err_ctx("Failed to get hwlock\n");
-               return;
-       }
-
-       if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
-               __mfc_dec_dst_stop_streaming(ctx);
-       else if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
-               __mfc_dec_src_stop_streaming(ctx);
-
-       if (ctx->state == MFCINST_FINISHING)
-               mfc_change_state(ctx, MFCINST_RUNNING);
-
-       if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && need_to_dpb_flush(ctx)) {
-               prev_state = ctx->state;
-               mfc_change_state(ctx, MFCINST_DPB_FLUSHING);
-               mfc_set_bit(ctx->num, &dev->work_bits);
-               mfc_clean_ctx_int_flags(ctx);
-               mfc_info_ctx("try to DPB flush\n");
-               ret = mfc_just_run(dev, ctx->num);
-               if (ret) {
-                       mfc_err_ctx("Failed to run MFC\n");
-                       mfc_release_hwlock_ctx(ctx);
-                       mfc_cleanup_work_bit_and_try_run(ctx);
-                       return;
-               }
-
-               if (mfc_wait_for_done_ctx(ctx, MFC_REG_R2H_CMD_DPB_FLUSH_RET)) {
-                       mfc_err_ctx("time out during DPB flush\n");
-                       dev->logging_data->cause |= (1 << MFC_CAUSE_FAIL_DPB_FLUSH);
-                       call_dop(dev, dump_and_stop_always, dev);
-               }
-
-               mfc_change_state(ctx, prev_state);
-       }
-
-       mfc_debug(2, "buffer cleanup & flush is done in stop_streaming, type : %d\n", q->type);
-
-       mfc_clear_bit(ctx->num, &dev->work_bits);
-       mfc_release_hwlock_ctx(ctx);
-
-       if (mfc_dec_ctx_ready(ctx))
-               mfc_set_bit(ctx->num, &dev->work_bits);
-       if (mfc_is_work_to_do(dev))
-               queue_work(dev->butler_wq, &dev->butler_work);
-}
-
-static void mfc_dec_buf_queue(struct vb2_buffer *vb)
-{
-       struct vb2_queue *vq = vb->vb2_queue;
-       struct mfc_ctx *ctx = vq->drv_priv;
-       struct mfc_dev *dev;
-       struct mfc_dec *dec;
-       struct mfc_buf *buf = vb_to_mfc_buf(vb);
-       int i;
-       unsigned char *stream_vir = NULL;
-
-       mfc_debug_enter();
-       if (!ctx) {
-               mfc_err_dev("no mfc context to run\n");
-               return;
-       }
-
-       dev = ctx->dev;
-       if (!dev) {
-               mfc_err_dev("no mfc device to run\n");
-               return;
-       }
-
-       dec = ctx->dec_priv;
-       if (!dec) {
-               mfc_err_dev("no mfc decoder to run\n");
-               return;
-       }
-
-       if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
-               mfc_debug(2, "[BUFINFO] ctx[%d] add src index:%d, addr: 0x%08llx\n",
-                               ctx->num, vb->index, buf->addr[0][0]);
-               if (dec->dst_memtype == V4L2_MEMORY_DMABUF &&
-                               ctx->state < MFCINST_HEAD_PARSED && !ctx->is_drm)
-                       stream_vir = vb2_plane_vaddr(vb, 0);
-
-               buf->vir_addr = stream_vir;
-
-               mfc_add_tail_buf(&ctx->buf_queue_lock, &ctx->src_buf_queue, buf);
-
-               MFC_TRACE_CTX("Q src[%d] fd: %d, %#llx\n",
-                               vb->index, vb->planes[0].m.fd, buf->addr[0][0]);
-       } else if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-               for (i = 0; i < ctx->dst_fmt->mem_planes; i++)
-                       mfc_debug(2, "[BUFINFO] ctx[%d] add dst index: %d, addr[%d]: 0x%08llx\n",
-                                       ctx->num, vb->index, i, buf->addr[0][i]);
-               mfc_store_dpb(ctx, vb);
-
-               if ((dec->dst_memtype == V4L2_MEMORY_USERPTR || dec->dst_memtype == V4L2_MEMORY_DMABUF) &&
-                               mfc_is_queue_count_same(&ctx->buf_queue_lock,
-                                       &ctx->dst_buf_queue, dec->total_dpb_count))
-                       ctx->capture_state = QUEUE_BUFS_MMAPED;
-
-               MFC_TRACE_CTX("Q dst[%d] fd: %d, %#llx / avail %#lx used %#x\n",
-                               vb->index, vb->planes[0].m.fd, buf->addr[0][0],
-                               dec->available_dpb, dec->dynamic_used);
-       } else {
-               mfc_err_ctx("Unsupported buffer type (%d)\n", vq->type);
-       }
-
-       if (mfc_dec_ctx_ready(ctx)) {
-               mfc_set_bit(ctx->num, &dev->work_bits);
-               mfc_try_run(dev);
-       }
-
-       mfc_debug_leave();
-}
-
-struct vb2_ops mfc_dec_qops = {
-       .queue_setup            = mfc_dec_queue_setup,
-       .wait_prepare           = mfc_dec_unlock,
-       .wait_finish            = mfc_dec_lock,
-       .buf_init               = mfc_dec_buf_init,
-       .buf_prepare            = mfc_dec_buf_prepare,
-       .buf_finish             = mfc_dec_buf_finish,
-       .buf_cleanup            = mfc_dec_buf_cleanup,
-       .start_streaming        = mfc_dec_start_streaming,
-       .stop_streaming         = mfc_dec_stop_streaming,
-       .buf_queue              = mfc_dec_buf_queue,
-};
diff --git a/drivers/media/platform/exynos/mfc/mfc_enc.c b/drivers/media/platform/exynos/mfc/mfc_enc.c
deleted file mode 100644 (file)
index ab5249b..0000000
+++ /dev/null
@@ -1,2061 +0,0 @@
-/*
- * drivers/media/platform/exynos/mfc/mfc_enc.c
- *
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include "mfc_enc.h"
-#include "mfc_enc_internal.h"
-
-#include "mfc_hwlock.h"
-#include "mfc_otf.h"
-#include "mfc_opr.h"
-#include "mfc_sync.h"
-
-#include "mfc_qos.h"
-#include "mfc_queue.h"
-#include "mfc_utils.h"
-#include "mfc_buf.h"
-#include "mfc_mem.h"
-
-static struct mfc_fmt *__mfc_enc_find_format(struct mfc_ctx *ctx,
-               unsigned int pixelformat)
-{
-       struct mfc_dev *dev = ctx->dev;
-       struct mfc_fmt *fmt = NULL;
-       unsigned long i;
-
-       for (i = 0; i < NUM_FORMATS; i++) {
-               if (enc_formats[i].fourcc == pixelformat) {
-                       fmt = (struct mfc_fmt *)&enc_formats[i];
-                       break;
-               }
-       }
-
-       if (!dev->pdata->support_10bit && (fmt->type & MFC_FMT_10BIT)) {
-               mfc_err_ctx("[FRAME] 10bit is not supported\n");
-               fmt = NULL;
-       }
-       if (!dev->pdata->support_422 && (fmt->type & MFC_FMT_422)) {
-               mfc_err_ctx("[FRAME] 422 is not supported\n");
-               fmt = NULL;
-       }
-       if (!dev->pdata->support_rgb && (fmt->type & MFC_FMT_RGB)) {
-               mfc_err_ctx("[FRAME] RGB is not supported\n");
-               fmt = NULL;
-       }
-
-       return fmt;
-}
-
-static struct v4l2_queryctrl *__mfc_enc_get_ctrl(int id)
-{
-       unsigned long i;
-
-       for (i = 0; i < NUM_CTRLS; ++i)
-               if (id == controls[i].id)
-                       return &controls[i];
-       return NULL;
-}
-
-static int __mfc_enc_check_ctrl_val(struct mfc_ctx *ctx, struct v4l2_control *ctrl)
-{
-       struct v4l2_queryctrl *c;
-
-       c = __mfc_enc_get_ctrl(ctrl->id);
-       if (!c) {
-               mfc_err_ctx("[CTRLS] not supported control id (%#x)\n", ctrl->id);
-               return -EINVAL;
-       }
-
-       if (ctrl->id == V4L2_CID_MPEG_VIDEO_GOP_SIZE
-           && ctrl->value > c->maximum) {
-               mfc_info_ctx("GOP_SIZE is changed to max(%d -> %d)\n",
-                                ctrl->value, c->maximum);
-               ctrl->value = c->maximum;
-       }
-
-       if (ctrl->id == V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER) {
-               if ((ctrl->value & ~(1 << 16)) < c->minimum || (ctrl->value & ~(1 << 16)) > c->maximum
-                   || (c->step != 0 && (ctrl->value & ~(1 << 16)) % c->step != 0)) {
-                       mfc_err_ctx("[CTRLS][HIERARCHICAL] Invalid control value for %#x (%#x)\n",
-                                       ctrl->id, ctrl->value);
-                       return -ERANGE;
-               } else {
-                       return 0;
-               }
-       }
-
-       if (ctrl->value < c->minimum || ctrl->value > c->maximum
-           || (c->step != 0 && ctrl->value % c->step != 0)) {
-               mfc_err_ctx("[CTRLS] Invalid control value for %#x (%#x)\n",
-                               ctrl->id, ctrl->value);
-               return -ERANGE;
-       }
-
-       return 0;
-}
-
-static inline int __mfc_enc_h264_profile(struct mfc_ctx *ctx, int profile)
-{
-       int ret = 0;
-
-       switch (profile) {
-       case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
-               ret = MFC_REG_E_PROFILE_H264_MAIN;
-               break;
-       case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
-               ret = MFC_REG_E_PROFILE_H264_HIGH;
-               break;
-       case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
-               ret = MFC_REG_E_PROFILE_H264_BASELINE;
-               break;
-       case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
-               ret = MFC_REG_E_PROFILE_H264_CONSTRAINED_BASELINE;
-               break;
-       case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH:
-               ret = MFC_REG_E_PROFILE_H264_CONSTRAINED_HIGH;
-               break;
-       default:
-               ret = -EINVAL;
-       }
-
-       return ret;
-}
-
-/* Query capabilities of the device */
-static int vidioc_querycap(struct file *file, void *priv,
-                          struct v4l2_capability *cap)
-{
-       strncpy(cap->driver, "MFC", sizeof(cap->driver) - 1);
-       strncpy(cap->card, "encoder", sizeof(cap->card) - 1);
-       cap->bus_info[0] = 0;
-       cap->version = KERNEL_VERSION(1, 0, 0);
-       cap->device_caps = V4L2_CAP_VIDEO_CAPTURE
-                       | V4L2_CAP_VIDEO_OUTPUT
-                       | V4L2_CAP_VIDEO_CAPTURE_MPLANE
-                       | V4L2_CAP_VIDEO_OUTPUT_MPLANE
-                       | V4L2_CAP_STREAMING
-                       | V4L2_CAP_DEVICE_CAPS;
-
-       cap->capabilities = cap->device_caps;
-
-       return 0;
-}
-
-static int __mfc_enc_enum_fmt(struct mfc_dev *dev, struct v4l2_fmtdesc *f,
-               unsigned int type)
-{
-       struct mfc_fmt *fmt;
-       unsigned long i, j = 0;
-
-       for (i = 0; i < NUM_FORMATS; ++i) {
-               if (!(enc_formats[i].type & type))
-                       continue;
-               if (!dev->pdata->support_10bit && (enc_formats[i].type & MFC_FMT_10BIT))
-                       continue;
-               if (!dev->pdata->support_422 && (enc_formats[i].type & MFC_FMT_422))
-                       continue;
-               if (!dev->pdata->support_rgb && (enc_formats[i].type & MFC_FMT_RGB))
-                       continue;
-
-               if (j == f->index) {
-                       fmt = &enc_formats[i];
-                       strlcpy(f->description, fmt->name,
-                               sizeof(f->description));
-                       f->pixelformat = fmt->fourcc;
-
-                       return 0;
-               }
-
-               ++j;
-       }
-
-       return -EINVAL;
-}
-
-static int vidioc_enum_fmt_vid_cap_mplane(struct file *file, void *pirv,
-               struct v4l2_fmtdesc *f)
-{
-       struct mfc_dev *dev = video_drvdata(file);
-
-       return __mfc_enc_enum_fmt(dev, f, MFC_FMT_STREAM);
-}
-
-static int vidioc_enum_fmt_vid_out_mplane(struct file *file, void *prov,
-               struct v4l2_fmtdesc *f)
-{
-       struct mfc_dev *dev = video_drvdata(file);
-
-       return __mfc_enc_enum_fmt(dev, f, MFC_FMT_FRAME);
-}
-
-static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
-{
-       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
-       struct mfc_enc *enc = ctx->enc_priv;
-       struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
-       struct mfc_raw_info *raw;
-       int i;
-
-       mfc_debug_enter();
-
-       if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-               mfc_debug(4, "enc dst g_fmt\n");
-               /* This is run on output (encoder dest) */
-               pix_fmt_mp->width = 0;
-               pix_fmt_mp->height = 0;
-               pix_fmt_mp->field = V4L2_FIELD_NONE;
-               pix_fmt_mp->pixelformat = ctx->dst_fmt->fourcc;
-               pix_fmt_mp->num_planes = ctx->dst_fmt->mem_planes;
-
-               pix_fmt_mp->plane_fmt[0].bytesperline = enc->dst_buf_size;
-               pix_fmt_mp->plane_fmt[0].sizeimage = enc->dst_buf_size;
-       } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
-               mfc_debug(4, "enc src g_fmt\n");
-               /* This is run on capture (encoder src) */
-               raw = &ctx->raw_buf;
-
-               pix_fmt_mp->width = ctx->img_width;
-               pix_fmt_mp->height = ctx->img_height;
-               pix_fmt_mp->field = V4L2_FIELD_NONE;
-               pix_fmt_mp->pixelformat = ctx->src_fmt->fourcc;
-               pix_fmt_mp->num_planes = ctx->src_fmt->mem_planes;
-               for (i = 0; i < ctx->src_fmt->mem_planes; i++) {
-                       pix_fmt_mp->plane_fmt[i].bytesperline = raw->stride[i];
-                       pix_fmt_mp->plane_fmt[i].sizeimage = raw->plane_size[i];
-               }
-       } else {
-               mfc_err_dev("invalid buf type (%d)\n", f->type);
-               return -EINVAL;
-       }
-
-       mfc_debug_leave();
-
-       return 0;
-}
-
-static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
-{
-       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
-       struct mfc_fmt *fmt;
-       struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
-
-       fmt = __mfc_enc_find_format(ctx, pix_fmt_mp->pixelformat);
-       if (!fmt) {
-               mfc_err_dev("Unsupported format for %s\n",
-                               V4L2_TYPE_IS_OUTPUT(f->type) ? "source" : "destination");
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static void __mfc_enc_check_format(struct mfc_ctx *ctx)
-{
-       switch (ctx->src_fmt->fourcc) {
-       case V4L2_PIX_FMT_NV16M_S10B:
-       case V4L2_PIX_FMT_NV61M_S10B:
-       case V4L2_PIX_FMT_NV16M_P210:
-       case V4L2_PIX_FMT_NV61M_P210:
-               mfc_debug(2, "[FRAME][10BIT] is 422 and 10bit format\n");
-               ctx->is_10bit = 1;
-               ctx->is_422 = 1;
-               break;
-       case V4L2_PIX_FMT_NV16M:
-       case V4L2_PIX_FMT_NV61M:
-               mfc_debug(2, "[FRAME] is 422 format\n");
-               ctx->is_10bit = 0;
-               ctx->is_422 = 1;
-               break;
-       case V4L2_PIX_FMT_NV12M_S10B:
-       case V4L2_PIX_FMT_NV12M_P010:
-       case V4L2_PIX_FMT_NV21M_S10B:
-       case V4L2_PIX_FMT_NV21M_P010:
-               mfc_debug(2, "[FRAME][10BIT] is 10bit format\n");
-               ctx->is_10bit = 1;
-               ctx->is_422 = 0;
-               break;
-       default:
-               ctx->is_10bit = 0;
-               ctx->is_422 = 0;
-               break;
-       }
-       mfc_debug(2, "[FRAME] 10bit: %d, 422: %d\n", ctx->is_10bit, ctx->is_422);
-}
-
-static int __mfc_enc_check_resolution(struct mfc_ctx *ctx)
-{
-       int max_width = 0, max_height = 0, min_width = 0, min_height = 0, swap_check = 0;
-
-       /* Check max resolution */
-       switch (ctx->codec_mode) {
-       case MFC_REG_CODEC_HEVC_ENC:
-               if (ctx->is_422) {
-                       max_width = 65536;
-                       max_height = 8192;
-                       swap_check = 1;
-               } else {
-                       max_width = 8192;
-                       max_height = 8192;
-               }
-               break;
-       case MFC_REG_CODEC_BPG_ENC:
-               max_width = 65536;
-               max_height = 8192;
-               swap_check = 1;
-               break;
-       case MFC_REG_CODEC_H264_ENC:
-       case MFC_REG_CODEC_VP8_ENC:
-               max_width = 8192;
-               max_height = 8192;
-               break;
-       case MFC_REG_CODEC_VP9_ENC:
-               max_width = 4096;
-               max_height = 8192;
-               break;
-       case MFC_REG_CODEC_MPEG4_ENC:
-               max_width = 2048;
-               max_height = 2048;
-               break;
-       case MFC_REG_CODEC_H263_ENC:
-               max_width = 2048;
-               max_height = 1152;
-               break;
-       default:
-               mfc_err_ctx("Not supported codec(%d)\n", ctx->codec_mode);
-               return -EINVAL;
-       }
-
-       if (swap_check) {
-               if (!((ctx->crop_width < max_width && ctx->crop_height < max_height) ||
-                               (ctx->crop_width < max_height && ctx->crop_height < max_width))) {
-                       mfc_err_ctx("Resolution is too big(%dx%d > %dxi%d or %dx%d\n",
-                                       ctx->crop_width, ctx->crop_height, max_width, max_height,
-                                       max_height, max_width);
-                       return -EINVAL;
-               }
-       } else {
-               if (ctx->crop_width > max_width || ctx->crop_height > max_height) {
-                       mfc_err_ctx("Resolution is too big(%dx%d > %dx%d)\n",
-                                       ctx->crop_width, ctx->crop_height, max_width, max_height);
-                       return -EINVAL;
-               }
-       }
-
-       /* Check min resolution */
-       switch (ctx->codec_mode) {
-       case MFC_REG_CODEC_HEVC_ENC:
-       case MFC_REG_CODEC_BPG_ENC:
-       case MFC_REG_CODEC_VP9_ENC:
-               min_width = 64;
-               min_height = 64;
-               break;
-       case MFC_REG_CODEC_H264_ENC:
-       case MFC_REG_CODEC_VP8_ENC:
-       case MFC_REG_CODEC_MPEG4_ENC:
-       case MFC_REG_CODEC_H263_ENC:
-               min_width = 32;
-               min_height = 32;
-               break;
-       default:
-               mfc_err_ctx("Not supported codec(%d)\n", ctx->codec_mode);
-               return -EINVAL;
-       }
-
-       if (ctx->crop_width < min_width || ctx->crop_height < min_height) {
-               mfc_err_ctx("Resolution is too small(%dx%d < %dx%d)\n",
-                               ctx->crop_width, ctx->crop_height, min_width, min_height);
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static int vidioc_s_fmt_vid_cap_mplane(struct file *file, void *priv,
-                                                       struct v4l2_format *f)
-{
-       struct mfc_dev *dev = video_drvdata(file);
-       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
-       struct mfc_enc *enc = ctx->enc_priv;
-       struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
-       int ret = 0;
-
-       mfc_debug_enter();
-
-       if (ctx->vq_dst.streaming) {
-               mfc_err_ctx("dst queue busy\n");
-               return -EBUSY;
-       }
-
-       ctx->dst_fmt = __mfc_enc_find_format(ctx, pix_fmt_mp->pixelformat);
-       if (!ctx->dst_fmt) {
-               mfc_err_ctx("Unsupported format for destination\n");
-               return -EINVAL;
-       }
-
-       ctx->codec_mode = ctx->dst_fmt->codec_mode;
-       mfc_info_ctx("[STREAM] Enc dst codec(%d) : %s\n",
-                       ctx->codec_mode, ctx->dst_fmt->name);
-
-       if (__mfc_enc_check_resolution(ctx)) {
-               mfc_err_ctx("Unsupported resolution\n");
-               return -EINVAL;
-       }
-
-       if (ctx->otf_handle) {
-               if (ctx->dst_fmt->fourcc != V4L2_PIX_FMT_H264 &&
-                               ctx->dst_fmt->fourcc != V4L2_PIX_FMT_HEVC) {
-                       mfc_err_ctx("[OTF] only H.264 and HEVC is supported\n");
-                       return -EINVAL;
-               }
-               if (mfc_otf_init(ctx)) {
-                       mfc_err_ctx("[OTF] otf_init failed\n");
-                       mfc_otf_destroy(ctx);
-                       return -EINVAL;
-               }
-       }
-
-       enc->dst_buf_size = pix_fmt_mp->plane_fmt[0].sizeimage;
-       pix_fmt_mp->plane_fmt[0].bytesperline = 0;
-
-       ret = mfc_alloc_instance_context(ctx);
-       if (ret) {
-               mfc_err_ctx("Failed to allocate enc instance[%d] buffers\n",
-                               ctx->num);
-               return -ENOMEM;
-       }
-
-       mfc_change_state(ctx, MFCINST_INIT);
-
-       ctx->capture_state = QUEUE_FREE;
-
-       ret = mfc_alloc_enc_roi_buffer(ctx);
-       if (ret) {
-               mfc_err_ctx("[ROI] Failed to allocate ROI buffers\n");
-               mfc_release_instance_context(ctx);
-               return -ENOMEM;
-       }
-
-       MFC_TRACE_CTX_HWLOCK("**ENC s_fmt\n");
-
-       ret = mfc_get_hwlock_ctx(ctx);
-       if (ret < 0) {
-               mfc_err_dev("Failed to get hwlock\n");
-               mfc_release_instance_context(ctx);
-               mfc_release_enc_roi_buffer(ctx);
-               return -EBUSY;
-       }
-
-       mfc_set_bit(ctx->num, &dev->work_bits);
-       ret = mfc_just_run(dev, ctx->num);
-       if (ret) {
-               mfc_err_ctx("Failed to run MFC\n");
-               mfc_release_hwlock_ctx(ctx);
-               mfc_cleanup_work_bit_and_try_run(ctx);
-               mfc_release_instance_context(ctx);
-               mfc_release_enc_roi_buffer(ctx);
-               return -EIO;
-       }
-
-       if (mfc_wait_for_done_ctx(ctx,
-                               MFC_REG_R2H_CMD_OPEN_INSTANCE_RET)) {
-               mfc_err_ctx("time out during open instance\n");
-               mfc_release_hwlock_ctx(ctx);
-               mfc_cleanup_work_bit_and_try_run(ctx);
-               mfc_release_instance_context(ctx);
-               mfc_release_enc_roi_buffer(ctx);
-               return -EIO;
-       }
-       mfc_release_hwlock_ctx(ctx);
-
-       mfc_debug(2, "Got instance number: %d\n", ctx->inst_no);
-
-       if (mfc_enc_ctx_ready(ctx))
-               mfc_set_bit(ctx->num, &dev->work_bits);
-       if (ctx->otf_handle && mfc_otf_ctx_ready(ctx))
-               mfc_set_bit(ctx->num, &dev->work_bits);
-       if (mfc_is_work_to_do(dev))
-               queue_work(dev->butler_wq, &dev->butler_work);
-
-       mfc_debug_leave();
-       return 0;
-}
-
-static int vidioc_s_fmt_vid_out_mplane(struct file *file, void *priv,
-                                                       struct v4l2_format *f)
-{
-       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
-       struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
-
-       mfc_debug_enter();
-
-       if (ctx->vq_src.streaming) {
-               mfc_err_ctx("src queue busy\n");
-               return -EBUSY;
-       }
-
-       if (ctx->otf_handle) {
-               mfc_info_ctx("[OTF] skip source s_fmt\n");
-               return 0;
-       }
-
-       ctx->src_fmt = __mfc_enc_find_format(ctx, pix_fmt_mp->pixelformat);
-       if (!ctx->src_fmt) {
-               mfc_err_ctx("Unsupported format for source\n");
-               return -EINVAL;
-       }
-
-       if (ctx->src_fmt->mem_planes != pix_fmt_mp->num_planes) {
-               mfc_err_ctx("[FRAME] enc src plane number is different (%d != %d)\n",
-                               ctx->src_fmt->mem_planes, pix_fmt_mp->num_planes);
-               return -EINVAL;
-       }
-
-       ctx->raw_buf.num_planes = ctx->src_fmt->num_planes;
-       ctx->img_width = pix_fmt_mp->width;
-       ctx->img_height = pix_fmt_mp->height;
-       ctx->buf_stride = pix_fmt_mp->plane_fmt[0].bytesperline;
-
-       __mfc_enc_check_format(ctx);
-
-       if (ctx->state == MFCINST_RUNNING) {
-               mfc_change_state(ctx, MFCINST_GOT_INST);
-               mfc_info_ctx("[DRC] Enc resolution is changed\n");
-       }
-
-       mfc_info_ctx("[FRAME] enc src pixelformat : %s\n", ctx->src_fmt->name);
-       mfc_info_ctx("[FRAME] resolution w: %d, h: %d, stride: %d\n",
-                       pix_fmt_mp->width, pix_fmt_mp->height, ctx->buf_stride);
-
-       /*
-        * It should be keep till buffer size and stride was calculated.
-        * And it can be changed to real encoding size, if user call the s_crop.
-        */
-       ctx->crop_width = ctx->img_width;
-       ctx->crop_height = ctx->img_height;
-       mfc_enc_calc_src_size(ctx);
-
-       ctx->output_state = QUEUE_FREE;
-
-       mfc_debug_leave();
-       return 0;
-}
-
-static int vidioc_g_crop(struct file *file, void *fh, struct v4l2_crop *cr)
-{
-       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
-
-       mfc_debug_enter();
-
-       cr->c.left = ctx->crop_left;
-       cr->c.top = ctx->crop_top;
-       cr->c.width = ctx->crop_width;
-       cr->c.height = ctx->crop_height;
-
-       mfc_debug(2, "[FRAME] enc crop w: %d, h: %d, offset l: %d t: %d\n",
-                       ctx->crop_width, ctx->crop_height, ctx->crop_left, ctx->crop_top);
-
-       mfc_debug_leave();
-
-       return 0;
-}
-
-static int vidioc_s_crop(struct file *file, void *priv, const struct v4l2_crop *cr)
-{
-       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
-
-       mfc_debug_enter();
-
-       if (cr->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
-               mfc_err_ctx("not supported type (It can only in the source)\n");
-               return -EINVAL;
-       }
-
-       if (cr->c.left < 0 || cr->c.top < 0) {
-               mfc_err_ctx("[FRAME] crop position is negative\n");
-               return -EINVAL;
-       }
-
-       if ((cr->c.height > ctx->img_height) || (cr->c.top > ctx->img_height) ||
-                       (cr->c.width > ctx->img_width) || (cr->c.left > ctx->img_width) ||
-                       (cr->c.left <= (ctx->img_width - cr->c.width)) ||
-                       (cr->c.top <= (ctx->img_height - cr->c.height))) {
-               mfc_err_ctx("[FRAME] Out of crop range: (%d,%d,%d,%d) from %dx%d\n",
-                               cr->c.left, cr->c.top, cr->c.width, cr->c.height,
-                               ctx->img_width, ctx->img_height);
-               return -EINVAL;
-       }
-
-       ctx->crop_top = cr->c.top;
-       ctx->crop_left = cr->c.left;
-       ctx->crop_height = cr->c.height;
-       ctx->crop_width = cr->c.width;
-
-       mfc_debug(3, "[FRAME] enc original: %dx%d, crop: %dx%d, offset l: %d t: %d\n",
-                       ctx->img_width, ctx->img_height,
-                       ctx->crop_width, ctx->crop_height,
-                       ctx->crop_left, ctx->crop_top);
-
-       return 0;
-}
-
-static int vidioc_reqbufs(struct file *file, void *priv,
-                                         struct v4l2_requestbuffers *reqbufs)
-{
-       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
-       int ret = 0;
-
-       mfc_debug_enter();
-
-       if (reqbufs->memory == V4L2_MEMORY_MMAP) {
-               mfc_err_ctx("Not supported memory type (%d)\n", reqbufs->memory);
-               return -EINVAL;
-       }
-
-       if (ctx->otf_handle) {
-               mfc_info_ctx("[OTF] skip reqbufs\n");
-               return 0;
-       }
-
-       if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-               mfc_debug(4, "enc dst reqbuf(%d)\n", reqbufs->count);
-               if (reqbufs->count == 0) {
-                       ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
-                       ctx->capture_state = QUEUE_FREE;
-                       return ret;
-               }
-
-               if (ctx->capture_state != QUEUE_FREE) {
-                       mfc_err_ctx("invalid capture state: %d\n", ctx->capture_state);
-                       return -EINVAL;
-               }
-
-               ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
-               if (ret) {
-                       mfc_err_ctx("error in vb2_reqbufs() for E(D)\n");
-                       return ret;
-               }
-
-               ctx->capture_state = QUEUE_BUFS_REQUESTED;
-       } else if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
-               mfc_debug(4, "enc src reqbuf(%d)\n", reqbufs->count);
-               if (reqbufs->count == 0) {
-                       ret = vb2_reqbufs(&ctx->vq_src, reqbufs);
-                       ctx->output_state = QUEUE_FREE;
-                       return ret;
-               }
-
-               if (ctx->output_state != QUEUE_FREE) {
-                       mfc_err_ctx("invalid output state: %d\n", ctx->output_state);
-                       return -EINVAL;
-               }
-
-               ret = vb2_reqbufs(&ctx->vq_src, reqbufs);
-               if (ret) {
-                       mfc_err_ctx("error in vb2_reqbufs() for E(S)\n");
-                       return ret;
-               }
-
-               ctx->output_state = QUEUE_BUFS_REQUESTED;
-       } else {
-               mfc_err_ctx("invalid buf type (%d)\n", reqbufs->type);
-               return -EINVAL;
-       }
-
-       mfc_debug_leave();
-
-       return ret;
-}
-
-static int vidioc_querybuf(struct file *file, void *priv,
-                                                  struct v4l2_buffer *buf)
-{
-       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
-       int ret = 0;
-
-       mfc_debug_enter();
-
-       if (ctx->otf_handle) {
-               mfc_info_ctx("[OTF] skip source querybuf\n");
-               return 0;
-       }
-
-       if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-               mfc_debug(4, "enc dst querybuf, state: %d\n", ctx->state);
-               ret = vb2_querybuf(&ctx->vq_dst, buf);
-               if (ret != 0) {
-                       mfc_err_dev("enc dst: error in vb2_querybuf()\n");
-                       return ret;
-               }
-       } else if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
-               mfc_debug(4, "enc src querybuf, state: %d\n", ctx->state);
-               ret = vb2_querybuf(&ctx->vq_src, buf);
-               if (ret != 0) {
-                       mfc_err_dev("enc src: error in vb2_querybuf()\n");
-                       return ret;
-               }
-       } else {
-               mfc_err_dev("invalid buf type (%d)\n", buf->type);
-               return -EINVAL;
-       }
-
-       mfc_debug_leave();
-
-       return ret;
-}
-
-/* Queue a buffer */
-static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
-{
-       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
-       int i, ret = -EINVAL;
-
-       mfc_debug_enter();
-
-       if (ctx->otf_handle) {
-               mfc_info_ctx("[OTF] skip qbuf\n");
-               return 0;
-       }
-
-       if (ctx->state == MFCINST_ERROR) {
-               mfc_err_ctx("Call on QBUF after unrecoverable error\n");
-               return -EIO;
-       }
-
-       if (V4L2_TYPE_IS_MULTIPLANAR(buf->type) && !buf->length) {
-               mfc_err_ctx("multiplanar but length is zero\n");
-               return -EIO;
-       }
-
-       if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
-               mfc_debug(4, "enc src buf[%d] Q\n", buf->index);
-               for (i = 0; i < ctx->src_fmt->num_planes; i++) {
-                       if (!buf->m.planes[i].bytesused) {
-                               mfc_debug(2, "[FRAME] enc src[%d] size zero, "
-                                               "changed to buf size %d\n",
-                                               i, buf->m.planes[i].length);
-                               buf->m.planes[i].bytesused = buf->m.planes[i].length;
-                       } else {
-                               mfc_debug(2, "[FRAME] enc src[%d] size %d\n",
-                                               i, buf->m.planes[i].bytesused);
-                       }
-               }
-               ret = vb2_qbuf(&ctx->vq_src, buf);
-       } else {
-               mfc_debug(4, "enc dst buf[%d] Q\n", buf->index);
-               ret = vb2_qbuf(&ctx->vq_dst, buf);
-       }
-
-       mfc_debug_leave();
-       return ret;
-}
-
-/* Dequeue a buffer */
-static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
-{
-       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
-       int ret;
-
-       mfc_debug_enter();
-
-       if (ctx->otf_handle) {
-               mfc_info_ctx("[OTF] skip dqbuf\n");
-               return 0;
-       }
-
-       if (ctx->state == MFCINST_ERROR) {
-               mfc_err_ctx("Call on DQBUF after unrecoverable error\n");
-               return -EIO;
-       }
-       if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
-               mfc_debug(4, "enc src buf[%d] DQ\n", buf->index);
-               ret = vb2_dqbuf(&ctx->vq_src, buf, file->f_flags & O_NONBLOCK);
-       } else {
-               mfc_debug(4, "enc dst buf[%d] DQ\n", buf->index);
-               ret = vb2_dqbuf(&ctx->vq_dst, buf, file->f_flags & O_NONBLOCK);
-       }
-       mfc_debug_leave();
-       return ret;
-}
-
-/* Stream on */
-static int vidioc_streamon(struct file *file, void *priv,
-                          enum v4l2_buf_type type)
-{
-       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
-       int ret = -EINVAL;
-
-       mfc_debug_enter();
-
-       if (ctx->otf_handle) {
-               mfc_info_ctx("[OTF] skip streamon\n");
-               return 0;
-       }
-
-       if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
-               mfc_debug(4, "enc src streamon\n");
-               ret = vb2_streamon(&ctx->vq_src, type);
-
-               if (!ret) {
-                       mfc_qos_on(ctx);
-               }
-       } else {
-               mfc_debug(4, "enc dst streamon\n");
-               ret = vb2_streamon(&ctx->vq_dst, type);
-       }
-
-       mfc_debug(2, "src: %d, dst: %d, state = %d, dpb_count = %d\n",
-                 mfc_get_queue_count(&ctx->buf_queue_lock, &ctx->src_buf_queue),
-                 mfc_get_queue_count(&ctx->buf_queue_lock, &ctx->dst_buf_queue),
-                 ctx->state, ctx->dpb_count);
-       mfc_debug_leave();
-       return ret;
-}
-
-/* Stream off, which equals to a pause */
-static int vidioc_streamoff(struct file *file, void *priv,
-                           enum v4l2_buf_type type)
-{
-       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
-       int ret;
-
-       mfc_debug_enter();
-
-       if (ctx->otf_handle) {
-               mfc_info_ctx("[OTF] skip streamoff\n");
-               return 0;
-       }
-
-       ret = -EINVAL;
-       if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
-               mfc_debug(4, "enc src streamoff\n");
-               mfc_qos_reset_last_framerate(ctx);
-
-               ret = vb2_streamoff(&ctx->vq_src, type);
-               if (!ret)
-                       mfc_qos_off(ctx);
-       } else {
-               mfc_debug(4, "enc dst streamoff\n");
-               ret = vb2_streamoff(&ctx->vq_dst, type);
-       }
-
-       mfc_debug_leave();
-
-       return ret;
-}
-
-/* Query a ctrl */
-static int vidioc_queryctrl(struct file *file, void *priv,
-                           struct v4l2_queryctrl *qc)
-{
-       struct v4l2_queryctrl *c;
-
-       c = __mfc_enc_get_ctrl(qc->id);
-       if (!c) {
-               mfc_err_dev("[CTRLS] not supported control id (%#x)\n", qc->id);
-               return -EINVAL;
-       }
-
-       *qc = *c;
-       return 0;
-}
-
-static int __mfc_enc_ext_info(struct mfc_ctx *ctx)
-{
-       struct mfc_dev *dev = ctx->dev;
-       int val = 0;
-
-       val |= ENC_SET_SPARE_SIZE;
-       val |= ENC_SET_TEMP_SVC_CH;
-
-       if (MFC_FEATURE_SUPPORT(dev, dev->pdata->skype))
-               val |= ENC_SET_SKYPE_FLAG;
-
-       val |= ENC_SET_ROI_CONTROL;
-       val |= ENC_SET_QP_BOUND_PB;
-       val |= ENC_SET_FIXED_SLICE;
-       val |= ENC_SET_PVC_MODE;
-       val |= ENC_SET_RATIO_OF_INTRA;
-
-       if (MFC_FEATURE_SUPPORT(dev, dev->pdata->color_aspect_enc))
-               val |= ENC_SET_COLOR_ASPECT;
-
-       val |= ENC_SET_HP_BITRATE_CONTROL;
-
-       if (MFC_FEATURE_SUPPORT(dev, dev->pdata->static_info_enc))
-               val |= ENC_SET_STATIC_INFO;
-
-       mfc_debug(5, "[CTRLS] ext info val: %#x\n", val);
-
-       return val;
-}
-
-static int __mfc_enc_get_ctrl_val(struct mfc_ctx *ctx, struct v4l2_control *ctrl)
-{
-       struct mfc_dev *dev = ctx->dev;
-       struct mfc_enc *enc = ctx->enc_priv;
-       struct mfc_ctx_ctrl *ctx_ctrl;
-       int ret = 0;
-       int found = 0;
-
-       switch (ctrl->id) {
-       case V4L2_CID_CACHEABLE:
-               mfc_debug(5, "it is supported only V4L2_MEMORY_MMAP\n");
-               break;
-       case V4L2_CID_MPEG_MFC51_VIDEO_STREAM_SIZE:
-               ctrl->value = enc->dst_buf_size;
-               break;
-       case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TYPE:
-               ctrl->value = enc->frame_type;
-               break;
-       case V4L2_CID_MPEG_MFC51_VIDEO_CHECK_STATE:
-               ctrl->value = MFCSTATE_PROCESSING;
-               break;
-       case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG:
-       case V4L2_CID_MPEG_MFC51_VIDEO_LUMA_ADDR:
-       case V4L2_CID_MPEG_MFC51_VIDEO_CHROMA_ADDR:
-       case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_STATUS:
-               list_for_each_entry(ctx_ctrl, &ctx->ctrls, list) {
-                       if (!(ctx_ctrl->type & MFC_CTRL_TYPE_GET))
-                               continue;
-
-                       if (ctx_ctrl->id == ctrl->id) {
-                               if (ctx_ctrl->has_new) {
-                                       ctx_ctrl->has_new = 0;
-                                       ctrl->value = ctx_ctrl->val;
-                               } else {
-                                       mfc_debug(5, "[CTRLS] Control value "\
-                                                       "is not up to date: "\
-                                                       "0x%08x\n", ctrl->id);
-                                       return -EINVAL;
-                               }
-
-                               found = 1;
-                               break;
-                       }
-               }
-
-               if (!found) {
-                       mfc_err_ctx("Invalid control: 0x%08x\n", ctrl->id);
-                       return -EINVAL;
-               }
-               break;
-       case V4L2_CID_MPEG_MFC_GET_VERSION_INFO:
-               ctrl->value = dev->pdata->ip_ver;
-               break;
-       case V4L2_CID_MPEG_MFC_GET_DRIVER_INFO:
-               ctrl->value = MFC_DRIVER_INFO;
-               break;
-       case V4L2_CID_MPEG_MFC_GET_EXTRA_BUFFER_SIZE:
-               ctrl->value = MFC_LINEAR_BUF_SIZE;
-               break;
-       case V4L2_CID_MPEG_VIDEO_QOS_RATIO:
-               ctrl->value = ctx->qos_ratio;
-               break;
-       case V4L2_CID_MPEG_MFC_GET_EXT_INFO:
-               ctrl->value = __mfc_enc_ext_info(ctx);
-               break;
-       case V4L2_CID_MPEG_VIDEO_BPG_HEADER_SIZE:
-               ctrl->value = enc->header_size;
-               break;
-       default:
-               mfc_err_ctx("Invalid control: 0x%08x\n", ctrl->id);
-               ret = -EINVAL;
-               break;
-       }
-
-       mfc_debug(5, "[CTRLS] get id: %#x, value: %d\n", ctrl->id, ctrl->value);
-
-       return ret;
-}
-
-static int vidioc_g_ctrl(struct file *file, void *priv,
-                        struct v4l2_control *ctrl)
-{
-       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
-       int ret = 0;
-
-       mfc_debug_enter();
-       ret = __mfc_enc_get_ctrl_val(ctx, ctrl);
-       mfc_debug_leave();
-
-       return ret;
-}
-
-static inline int __mfc_enc_h264_level(enum v4l2_mpeg_video_h264_level lvl)
-{
-       static unsigned int t[V4L2_MPEG_VIDEO_H264_LEVEL_5_1 + 1] = {
-               /* V4L2_MPEG_VIDEO_H264_LEVEL_1_0   */ 10,
-               /* V4L2_MPEG_VIDEO_H264_LEVEL_1B    */ 9,
-               /* V4L2_MPEG_VIDEO_H264_LEVEL_1_1   */ 11,
-               /* V4L2_MPEG_VIDEO_H264_LEVEL_1_2   */ 12,
-               /* V4L2_MPEG_VIDEO_H264_LEVEL_1_3   */ 13,
-               /* V4L2_MPEG_VIDEO_H264_LEVEL_2_0   */ 20,
-               /* V4L2_MPEG_VIDEO_H264_LEVEL_2_1   */ 21,
-               /* V4L2_MPEG_VIDEO_H264_LEVEL_2_2   */ 22,
-               /* V4L2_MPEG_VIDEO_H264_LEVEL_3_0   */ 30,
-               /* V4L2_MPEG_VIDEO_H264_LEVEL_3_1   */ 31,
-               /* V4L2_MPEG_VIDEO_H264_LEVEL_3_2   */ 32,
-               /* V4L2_MPEG_VIDEO_H264_LEVEL_4_0   */ 40,
-               /* V4L2_MPEG_VIDEO_H264_LEVEL_4_1   */ 41,
-               /* V4L2_MPEG_VIDEO_H264_LEVEL_4_2   */ 42,
-               /* V4L2_MPEG_VIDEO_H264_LEVEL_5_0   */ 50,
-               /* V4L2_MPEG_VIDEO_H264_LEVEL_5_1   */ 51,
-       };
-       return t[lvl];
-}
-
-static inline int __mfc_enc_mpeg4_level(enum v4l2_mpeg_video_mpeg4_level lvl)
-{
-       static unsigned int t[V4L2_MPEG_VIDEO_MPEG4_LEVEL_6 + 1] = {
-               /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_0             */ 0,
-               /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B, Simple    */ 9,
-               /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_1             */ 1,
-               /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_2             */ 2,
-               /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_3             */ 3,
-               /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_3B, Advanced  */ 7,
-               /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_4             */ 4,
-               /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_5             */ 5,
-               /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_6,  Simple    */ 6,
-       };
-       return t[lvl];
-}
-
-static inline int __mfc_enc_vui_sar_idc(enum v4l2_mpeg_video_h264_vui_sar_idc sar)
-{
-       static unsigned int t[V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED + 1] = {
-               /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_UNSPECIFIED     */ 0,
-               /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_1x1             */ 1,
-               /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_12x11           */ 2,
-               /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_10x11           */ 3,
-               /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_16x11           */ 4,
-               /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_40x33           */ 5,
-               /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_24x11           */ 6,
-               /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_20x11           */ 7,
-               /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_32x11           */ 8,
-               /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_80x33           */ 9,
-               /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_18x11           */ 10,
-               /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_15x11           */ 11,
-               /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_64x33           */ 12,
-               /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_160x99          */ 13,
-               /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_4x3             */ 14,
-               /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_3x2             */ 15,
-               /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_2x1             */ 16,
-               /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED        */ 255,
-       };
-       return t[sar];
-}
-
-static int __mfc_enc_set_param(struct mfc_ctx *ctx, struct v4l2_control *ctrl)
-{
-       struct mfc_enc *enc = ctx->enc_priv;
-       struct mfc_enc_params *p = &enc->params;
-       int ret = 0;
-
-       switch (ctrl->id) {
-       case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
-               p->gop_size = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE:
-               p->slice_mode =
-                       (enum v4l2_mpeg_video_multi_slice_mode)ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB:
-               p->slice_mb = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES:
-               p->slice_bit = ctrl->value * 8;
-               break;
-       case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB_ROW:
-               p->slice_mb_row = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB:
-               p->intra_refresh_mb = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC51_VIDEO_PADDING:
-               p->pad = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC51_VIDEO_PADDING_YUV:
-               p->pad_luma = (ctrl->value >> 16) & 0xff;
-               p->pad_cb = (ctrl->value >> 8) & 0xff;
-               p->pad_cr = (ctrl->value >> 0) & 0xff;
-               break;
-       case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE:
-               p->rc_frame = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_BITRATE:
-               p->rc_bitrate = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF:
-               p->rc_reaction_coeff = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE:
-               enc->force_frame_type = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_VBV_SIZE:
-               p->vbv_buf_size = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_HEADER_MODE:
-               p->seq_hdr_mode =
-                       (enum v4l2_mpeg_video_header_mode)(ctrl->value);
-               break;
-       case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE:
-               p->frame_skip_mode =
-                       (enum v4l2_mpeg_mfc51_video_frame_skip_mode)
-                       (ctrl->value);
-               break;
-       case V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT:
-               p->fixed_target_bit = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_B_FRAMES:
-               p->num_b_frame = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
-               p->codec.h264.profile =
-               __mfc_enc_h264_profile(ctx, (enum v4l2_mpeg_video_h264_profile)(ctrl->value));
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
-               p->codec.h264.level =
-               __mfc_enc_h264_level((enum v4l2_mpeg_video_h264_level)(ctrl->value));
-               break;
-       case V4L2_CID_MPEG_MFC51_VIDEO_H264_INTERLACE:
-               p->codec.h264.interlace = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE:
-               p->codec.h264.loop_filter_mode =
-               (enum v4l2_mpeg_video_h264_loop_filter_mode)(ctrl->value);
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA:
-               p->codec.h264.loop_filter_alpha = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA:
-               p->codec.h264.loop_filter_beta = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
-               p->codec.h264.entropy_mode =
-                       (enum v4l2_mpeg_video_h264_entropy_mode)(ctrl->value);
-               break;
-       case V4L2_CID_MPEG_MFC51_VIDEO_H264_NUM_REF_PIC_FOR_P:
-               p->num_refs_for_p = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM:
-               p->codec.h264._8x8_transform = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE:
-               p->rc_mb = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC51_VIDEO_H264_RC_FRAME_RATE:
-               p->rc_framerate = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP:
-               p->codec.h264.rc_frame_qp = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_MIN_QP:
-               p->codec.h264.rc_min_qp = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_MAX_QP:
-               p->codec.h264.rc_max_qp = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_MIN_QP_P:
-               p->codec.h264.rc_min_qp_p = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_MAX_QP_P:
-               p->codec.h264.rc_max_qp_p = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_MIN_QP_B:
-               p->codec.h264.rc_min_qp_b = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_MAX_QP_B:
-               p->codec.h264.rc_max_qp_b = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_DARK:
-               p->codec.h264.rc_mb_dark = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_SMOOTH:
-               p->codec.h264.rc_mb_smooth = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_STATIC:
-               p->codec.h264.rc_mb_static = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_ACTIVITY:
-               p->codec.h264.rc_mb_activity = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP:
-               p->codec.h264.rc_p_frame_qp = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP:
-               p->codec.h264.rc_b_frame_qp = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE:
-               p->codec.h264.ar_vui = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC:
-               p->codec.h264.ar_vui_idc =
-               __mfc_enc_vui_sar_idc((enum v4l2_mpeg_video_h264_vui_sar_idc)(ctrl->value));
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH:
-               p->codec.h264.ext_sar_width = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT:
-               p->codec.h264.ext_sar_height = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
-               p->codec.h264.open_gop = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD:
-               p->codec.h264.open_gop_size = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING:
-               p->codec.h264.hier_qp_enable = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE:
-               p->codec.h264.hier_qp_type =
-               (enum v4l2_mpeg_video_h264_hierarchical_coding_type)(ctrl->value);
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER:
-               p->codec.h264.num_hier_layer = ctrl->value & 0x7;
-               p->codec.h264.hier_ref_type = (ctrl->value >> 16) & 0x1;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP:
-               p->codec.h264.hier_qp_layer[(ctrl->value >> 16) & 0x7]
-                       = ctrl->value & 0xFF;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT0:
-               p->codec.h264.hier_bit_layer[0] = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT1:
-               p->codec.h264.hier_bit_layer[1] = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT2:
-               p->codec.h264.hier_bit_layer[2] = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT3:
-               p->codec.h264.hier_bit_layer[3] = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT4:
-               p->codec.h264.hier_bit_layer[4] = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT5:
-               p->codec.h264.hier_bit_layer[5] = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT6:
-               p->codec.h264.hier_bit_layer[6] = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING:
-               p->codec.h264.sei_gen_enable = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_CURRENT_FRAME_0:
-               p->codec.h264.sei_fp_curr_frame_0 = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE:
-               p->codec.h264.sei_fp_arrangement_type = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_FMO:
-               p->codec.h264.fmo_enable = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE:
-               switch ((enum v4l2_mpeg_video_h264_fmo_map_type)(ctrl->value)) {
-               case V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_INTERLEAVED_SLICES:
-               case V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_SCATTERED_SLICES:
-               case V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_RASTER_SCAN:
-               case V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_WIPE_SCAN:
-                       p->codec.h264.fmo_slice_map_type = ctrl->value;
-                       break;
-               default:
-                       ret = -EINVAL;
-               }
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_FMO_SLICE_GROUP:
-               p->codec.h264.fmo_slice_num_grp = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH:
-               p->codec.h264.fmo_run_length[(ctrl->value >> 30) & 0x3]
-                       = ctrl->value & 0x3FFFFFFF;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_DIRECTION:
-               p->codec.h264.fmo_sg_dir = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_RATE:
-               p->codec.h264.fmo_sg_rate = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_ASO:
-               p->codec.h264.aso_enable = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_ASO_SLICE_ORDER:
-               p->codec.h264.aso_slice_order[(ctrl->value >> 18) & 0x7]
-                       &= ~(0xFF << (((ctrl->value >> 16) & 0x3) << 3));
-               p->codec.h264.aso_slice_order[(ctrl->value >> 18) & 0x7]
-                       |= (ctrl->value & 0xFF) << \
-                               (((ctrl->value >> 16) & 0x3) << 3);
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_PREPEND_SPSPPS_TO_IDR:
-               p->codec.h264.prepend_sps_pps_to_idr = ctrl->value ? 1 : 0;
-               break;
-       case V4L2_CID_MPEG_MFC_H264_ENABLE_LTR:
-               p->codec.h264.enable_ltr = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC_H264_NUM_OF_LTR:
-               p->codec.h264.num_of_ltr = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC_H264_BASE_PRIORITY:
-               p->codec.h264.base_priority = ctrl->value;
-               p->codec.h264.set_priority = 1;
-               break;
-       case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:
-               switch ((enum v4l2_mpeg_video_mpeg4_profile)(ctrl->value)) {
-               case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE:
-                       p->codec.mpeg4.profile =
-                               MFC_REG_E_PROFILE_MPEG4_SIMPLE;
-                       break;
-               case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE:
-                       p->codec.mpeg4.profile =
-                       MFC_REG_E_PROFILE_MPEG4_ADVANCED_SIMPLE;
-                       break;
-               default:
-                       ret = -EINVAL;
-               }
-               break;
-       case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL:
-               p->codec.mpeg4.level =
-               __mfc_enc_mpeg4_level((enum v4l2_mpeg_video_mpeg4_level)(ctrl->value));
-               break;
-       case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP:
-               p->codec.mpeg4.rc_frame_qp = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP:
-               p->codec.mpeg4.rc_min_qp = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP:
-               p->codec.mpeg4.rc_max_qp = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP_P:
-               p->codec.mpeg4.rc_min_qp_p = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP_P:
-               p->codec.mpeg4.rc_max_qp_p = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP_B:
-               p->codec.mpeg4.rc_min_qp_b = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP_B:
-               p->codec.mpeg4.rc_max_qp_b = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_MPEG4_QPEL:
-               p->codec.mpeg4.quarter_pixel = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP:
-               p->codec.mpeg4.rc_p_frame_qp = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP:
-               p->codec.mpeg4.rc_b_frame_qp = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC51_VIDEO_MPEG4_VOP_TIME_RES:
-               p->codec.mpeg4.vop_time_res = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC51_VIDEO_MPEG4_VOP_FRM_DELTA:
-               p->codec.mpeg4.vop_frm_delta = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC51_VIDEO_H263_RC_FRAME_RATE:
-               p->rc_framerate = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP:
-               p->codec.mpeg4.rc_frame_qp = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H263_MIN_QP:
-               p->codec.mpeg4.rc_min_qp = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H263_MAX_QP:
-               p->codec.mpeg4.rc_max_qp = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H263_MIN_QP_P:
-               p->codec.mpeg4.rc_min_qp_p = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H263_MAX_QP_P:
-               p->codec.mpeg4.rc_max_qp_p = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP:
-               p->codec.mpeg4.rc_p_frame_qp = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC70_VIDEO_VP8_VERSION:
-               p->codec.vp8.vp8_version = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC70_VIDEO_VP8_RC_FRAME_RATE:
-               p->rc_framerate = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_VP8_MIN_QP:
-               p->codec.vp8.rc_min_qp = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_VP8_MAX_QP:
-               p->codec.vp8.rc_max_qp = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_VP8_MIN_QP_P:
-               p->codec.vp8.rc_min_qp_p = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_VP8_MAX_QP_P:
-               p->codec.vp8.rc_max_qp_p = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_VP8_I_FRAME_QP:
-               p->codec.vp8.rc_frame_qp = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_VP8_P_FRAME_QP:
-               p->codec.vp8.rc_p_frame_qp = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC70_VIDEO_VP8_NUM_OF_PARTITIONS:
-               p->codec.vp8.vp8_numberofpartitions = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC70_VIDEO_VP8_FILTER_LEVEL:
-               p->codec.vp8.vp8_filterlevel = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC70_VIDEO_VP8_FILTER_SHARPNESS:
-               p->codec.vp8.vp8_filtersharpness = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC70_VIDEO_VP8_GOLDEN_FRAMESEL:
-               p->codec.vp8.vp8_goldenframesel = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC70_VIDEO_VP8_GF_REFRESH_PERIOD:
-               p->codec.vp8.vp8_gfrefreshperiod = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC70_VIDEO_VP8_HIERARCHY_QP_ENABLE:
-               p->codec.vp8.hier_qp_enable = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC70_VIDEO_VP8_HIERARCHY_QP_LAYER0:
-               p->codec.vp8.hier_qp_layer[(ctrl->value >> 16) & 0x3]
-                       = ctrl->value & 0xFF;
-               break;
-       case V4L2_CID_MPEG_MFC70_VIDEO_VP8_HIERARCHY_QP_LAYER1:
-               p->codec.vp8.hier_qp_layer[(ctrl->value >> 16) & 0x3]
-                       = ctrl->value & 0xFF;
-               break;
-       case V4L2_CID_MPEG_MFC70_VIDEO_VP8_HIERARCHY_QP_LAYER2:
-               p->codec.vp8.hier_qp_layer[(ctrl->value >> 16) & 0x3]
-                       = ctrl->value & 0xFF;
-               break;
-       case V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_BIT0:
-               p->codec.vp8.hier_bit_layer[0] = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_BIT1:
-               p->codec.vp8.hier_bit_layer[1] = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_BIT2:
-               p->codec.vp8.hier_bit_layer[2] = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC70_VIDEO_VP8_REF_NUMBER_FOR_PFRAMES:
-               p->num_refs_for_p = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC70_VIDEO_VP8_DISABLE_INTRA_MD4X4:
-               p->codec.vp8.intra_4x4mode_disable = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC70_VIDEO_VP8_NUM_TEMPORAL_LAYER:
-               p->codec.vp8.num_hier_layer = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_VP9_VERSION:
-               p->codec.vp9.vp9_version = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_VP9_RC_FRAME_RATE:
-               p->rc_framerate = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_VP9_MIN_QP:
-               p->codec.vp9.rc_min_qp = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_VP9_MAX_QP:
-               p->codec.vp9.rc_max_qp = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_VP9_MIN_QP_P:
-               p->codec.vp9.rc_min_qp_p = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_VP9_MAX_QP_P:
-               p->codec.vp9.rc_max_qp_p = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_VP9_I_FRAME_QP:
-               p->codec.vp9.rc_frame_qp = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_VP9_P_FRAME_QP:
-               p->codec.vp9.rc_p_frame_qp = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_VP9_GOLDEN_FRAMESEL:
-               p->codec.vp9.vp9_goldenframesel = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_VP9_GF_REFRESH_PERIOD:
-               p->codec.vp9.vp9_gfrefreshperiod = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_VP9_HIERARCHY_QP_ENABLE:
-               p->codec.vp9.hier_qp_enable = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_QP:
-               p->codec.vp9.hier_qp_layer[(ctrl->value >> 16) & 0x3]
-                       = ctrl->value & 0xFF;
-               break;
-       case V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_BIT0:
-               p->codec.vp9.hier_bit_layer[0] = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_BIT1:
-               p->codec.vp9.hier_bit_layer[1] = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_BIT2:
-               p->codec.vp9.hier_bit_layer[2] = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_VP9_REF_NUMBER_FOR_PFRAMES:
-               p->num_refs_for_p = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER:
-               p->codec.vp9.num_hier_layer = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_VP9_MAX_PARTITION_DEPTH:
-               p->codec.vp9.max_partition_depth = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_VP9_DISABLE_INTRA_PU_SPLIT:
-               p->codec.vp9.intra_pu_split_disable = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_DISABLE_IVF_HEADER:
-               p->ivf_header_disable = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_VP9_PROFILE:
-               p->codec.vp9.profile = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP:
-               p->codec.hevc.rc_frame_qp = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP:
-               p->codec.hevc.rc_p_frame_qp = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP:
-               p->codec.hevc.rc_b_frame_qp = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_RC_FRAME_RATE:
-               p->rc_framerate = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP:
-               p->codec.hevc.rc_min_qp = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP:
-               p->codec.hevc.rc_max_qp = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP_P:
-               p->codec.hevc.rc_min_qp_p = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP_P:
-               p->codec.hevc.rc_max_qp_p = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP_B:
-               p->codec.hevc.rc_min_qp_b = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP_B:
-               p->codec.hevc.rc_max_qp_b = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL:
-               p->codec.hevc.level = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE:
-               p->codec.hevc.profile = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_ADAPTIVE_RC_DARK:
-               p->codec.hevc.rc_lcu_dark = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_ADAPTIVE_RC_SMOOTH:
-               p->codec.hevc.rc_lcu_smooth = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_ADAPTIVE_RC_STATIC:
-               p->codec.hevc.rc_lcu_static = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_ADAPTIVE_RC_ACTIVITY:
-               p->codec.hevc.rc_lcu_activity = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_TIER_FLAG:
-               p->codec.hevc.tier_flag = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_MAX_PARTITION_DEPTH:
-               p->codec.hevc.max_partition_depth = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_REF_NUMBER_FOR_PFRAMES:
-               p->num_refs_for_p = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_REFRESH_TYPE:
-               p->codec.hevc.refreshtype = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_CONST_INTRA_PRED_ENABLE:
-               p->codec.hevc.const_intra_period_enable = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LOSSLESS_CU_ENABLE:
-               p->codec.hevc.lossless_cu_enable = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_WAVEFRONT_ENABLE:
-               p->codec.hevc.wavefront_enable = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LF_DISABLE:
-               p->codec.hevc.loopfilter_disable = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LF_SLICE_BOUNDARY:
-               p->codec.hevc.loopfilter_across = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LTR_ENABLE:
-               p->codec.hevc.enable_ltr = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_QP_ENABLE:
-               p->codec.hevc.hier_qp_enable = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_TYPE:
-               p->codec.hevc.hier_qp_type =
-               (enum v4l2_mpeg_video_hevc_hierarchical_coding_type)(ctrl->value);
-               break;
-       case V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER:
-               p->codec.hevc.num_hier_layer = ctrl->value & 0x7;
-               p->codec.hevc.hier_ref_type = (ctrl->value >> 16) & 0x1;
-               break;
-       case V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_QP:
-               p->codec.hevc.hier_qp_layer[(ctrl->value >> 16) & 0x7]
-                       = ctrl->value & 0xFF;
-               break;
-       case V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT0:
-               p->codec.hevc.hier_bit_layer[0] = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT1:
-               p->codec.hevc.hier_bit_layer[1] = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT2:
-               p->codec.hevc.hier_bit_layer[2] = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT3:
-               p->codec.hevc.hier_bit_layer[3] = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT4:
-               p->codec.hevc.hier_bit_layer[4] = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT5:
-               p->codec.hevc.hier_bit_layer[5] = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT6:
-               p->codec.hevc.hier_bit_layer[6] = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_GENERAL_PB_ENABLE:
-               p->codec.hevc.general_pb_enable = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_TEMPORAL_ID_ENABLE:
-               p->codec.hevc.temporal_id_enable = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_STRONG_SMOTHING_FLAG:
-               p->codec.hevc.strong_intra_smooth = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_DISABLE_INTRA_PU_SPLIT:
-               p->codec.hevc.intra_pu_split_disable = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_DISABLE_TMV_PREDICTION:
-               p->codec.hevc.tmv_prediction_disable = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_MAX_NUM_MERGE_MV_MINUS1:
-               p->codec.hevc.max_num_merge_mv = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_WITHOUT_STARTCODE_ENABLE:
-               p->codec.hevc.encoding_nostartcode_enable = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_REFRESH_PERIOD:
-               p->codec.hevc.refreshperiod = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LF_BETA_OFFSET_DIV2:
-               p->codec.hevc.lf_beta_offset_div2 = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LF_TC_OFFSET_DIV2:
-               p->codec.hevc.lf_tc_offset_div2 = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD:
-               p->codec.hevc.size_of_length_field = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_USER_REF:
-               p->codec.hevc.user_ref = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_STORE_REF:
-               p->codec.hevc.store_ref = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_ROI_ENABLE:
-               p->roi_enable = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC_H264_VUI_RESTRICTION_ENABLE:
-               p->codec.h264.vui_enable = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_HEVC_PREPEND_SPSPPS_TO_IDR:
-               p->codec.hevc.prepend_sps_pps_to_idr = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC_CONFIG_QP_ENABLE:
-               p->dynamic_qp = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC_CONFIG_QP:
-               p->config_qp = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_RC_PVC_ENABLE:
-               /* It is valid for H.264, HEVC, VP8, VP9 */
-               p->rc_pvc = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_TEMPORAL_SHORTTERM_MAX_LAYER:
-               p->num_hier_max_layer = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_SIGN_DATA_HIDING:
-               break;
-       case V4L2_CID_MPEG_VIDEO_WEIGHTED_ENABLE:
-               p->weighted_enable = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_BPG_THUMBNAIL_SIZE:
-               /* It should be included when NAL_START */
-               p->codec.bpg.thumb_size = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_BPG_EXIF_SIZE:
-               /* It should be included when NAL_START */
-               p->codec.bpg.exif_size = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_RATIO_OF_INTRA:
-               p->ratio_intra = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_FULL_RANGE_FLAG:
-               p->check_color_range = 1;
-               p->color_range = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_COLOUR_PRIMARIES:
-               p->colour_primaries = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_TRANSFER_CHARACTERISTICS:
-               p->transfer_characteristics = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_MATRIX_COEFFICIENTS:
-               p->matrix_coefficients = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_HIERARCHICAL_BITRATE_CTRL:
-               p->hier_bitrate_ctrl = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_STATIC_INFO_ENABLE:
-               p->static_info_enable = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_SEI_MAX_PIC_AVERAGE_LIGHT:
-               p->max_pic_average_light = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_SEI_MAX_CONTENT_LIGHT:
-               p->max_content_light = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_SEI_MAX_DISPLAY_LUMINANCE:
-               p->max_display_luminance = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_SEI_MIN_DISPLAY_LUMINANCE:
-               p->min_display_luminance = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_SEI_WHITE_POINT:
-               p->white_point = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_SEI_DISPLAY_PRIMARIES_0:
-               p->display_primaries_0 = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_SEI_DISPLAY_PRIMARIES_1:
-               p->display_primaries_1 = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_SEI_DISPLAY_PRIMARIES_2:
-               p->display_primaries_2 = ctrl->value;
-               break;
-       default:
-               mfc_err_ctx("Invalid control: 0x%08x\n", ctrl->id);
-               ret = -EINVAL;
-       }
-
-       return ret;
-}
-
-static int __mfc_enc_set_ctrl_val(struct mfc_ctx *ctx, struct v4l2_control *ctrl)
-{
-       struct mfc_enc *enc = ctx->enc_priv;
-       struct mfc_enc_params *p = &enc->params;
-       struct mfc_ctx_ctrl *ctx_ctrl;
-       int ret = 0;
-       int found = 0;
-       int index = 0;
-
-       mfc_debug(5, "[CTRLS] id: %#x, value: %d\n", ctrl->id, ctrl->value);
-
-       switch (ctrl->id) {
-       case V4L2_CID_CACHEABLE:
-               mfc_debug(5, "it is supported only V4L2_MEMORY_MMAP\n");
-               break;
-       case V4L2_CID_MPEG_VIDEO_QOS_RATIO:
-               ctx->qos_ratio = ctrl->value;
-               break;
-       case V4L2_CID_MPEG_VIDEO_H264_MAX_QP:
-       case V4L2_CID_MPEG_VIDEO_H263_MAX_QP:
-       case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP:
-       case V4L2_CID_MPEG_VIDEO_VP8_MAX_QP:
-       case V4L2_CID_MPEG_VIDEO_VP9_MAX_QP:
-       case V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP:
-       case V4L2_CID_MPEG_VIDEO_H264_MIN_QP:
-       case V4L2_CID_MPEG_VIDEO_H263_MIN_QP:
-       case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP:
-       case V4L2_CID_MPEG_VIDEO_VP8_MIN_QP:
-       case V4L2_CID_MPEG_VIDEO_VP9_MIN_QP:
-       case V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP:
-       case V4L2_CID_MPEG_VIDEO_H264_MAX_QP_P:
-       case V4L2_CID_MPEG_VIDEO_H263_MAX_QP_P:
-       case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP_P:
-       case V4L2_CID_MPEG_VIDEO_VP8_MAX_QP_P:
-       case V4L2_CID_MPEG_VIDEO_VP9_MAX_QP_P:
-       case V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP_P:
-       case V4L2_CID_MPEG_VIDEO_H264_MIN_QP_P:
-       case V4L2_CID_MPEG_VIDEO_H263_MIN_QP_P:
-       case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP_P:
-       case V4L2_CID_MPEG_VIDEO_VP8_MIN_QP_P:
-       case V4L2_CID_MPEG_VIDEO_VP9_MIN_QP_P:
-       case V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP_P:
-       case V4L2_CID_MPEG_VIDEO_H264_MAX_QP_B:
-       case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP_B:
-       case V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP_B:
-       case V4L2_CID_MPEG_VIDEO_H264_MIN_QP_B:
-       case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP_B:
-       case V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP_B:
-       case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG:
-       case V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE:
-       case V4L2_CID_MPEG_MFC51_VIDEO_I_PERIOD_CH:
-       case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_RATE_CH:
-       case V4L2_CID_MPEG_MFC51_VIDEO_BIT_RATE_CH:
-       case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_CH:
-       case V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_CH:
-       case V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_CH:
-       case V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_CH:
-       case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
-       case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
-       case V4L2_CID_MPEG_MFC_H264_MARK_LTR:
-       case V4L2_CID_MPEG_MFC_H264_USE_LTR:
-       case V4L2_CID_MPEG_MFC_H264_BASE_PRIORITY:
-       case V4L2_CID_MPEG_MFC_CONFIG_QP:
-       case V4L2_CID_MPEG_VIDEO_ROI_CONTROL:
-       case V4L2_CID_MPEG_VIDEO_YSUM:
-       case V4L2_CID_MPEG_VIDEO_RATIO_OF_INTRA:
-               list_for_each_entry(ctx_ctrl, &ctx->ctrls, list) {
-                       if (!(ctx_ctrl->type & MFC_CTRL_TYPE_SET))
-                               continue;
-
-                       if (ctx_ctrl->id == ctrl->id) {
-                               ctx_ctrl->has_new = 1;
-                               ctx_ctrl->val = ctrl->value;
-                               if (ctx_ctrl->id == \
-                                       V4L2_CID_MPEG_MFC51_VIDEO_FRAME_RATE_CH) {
-                                       ctx_ctrl->val &= ~(0xFFFF << 16);
-                                       ctx_ctrl->val |= ctx_ctrl->val << 16;
-                                       ctx_ctrl->val &= ~(0xFFFF);
-                                       ctx_ctrl->val |= p->rc_frame_delta & 0xFFFF;
-                               }
-                               if (((ctx_ctrl->id == \
-                                       V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_CH) ||
-                                       (ctx_ctrl->id == \
-                                       V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_CH) ||
-                                       (ctx_ctrl->id == \
-                                       V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_CH) ||
-                                       (ctx_ctrl->id == \
-                                       V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_CH)) &&
-                                       (enc->sh_handle_svc.fd == -1)) {
-                                               enc->sh_handle_svc.fd = ctrl->value;
-                                               if (mfc_mem_get_user_shared_handle(ctx,
-                                                                       &enc->sh_handle_svc))
-                                                       return -EINVAL;
-                                               else
-                                                       mfc_debug(2, "[MEMINFO][HIERARCHICAL] shared handle fd: %d, vaddr: 0x%p\n",
-                                                                       enc->sh_handle_svc.fd,
-                                                                       enc->sh_handle_svc.vaddr);
-                               }
-                               if (ctx_ctrl->id == V4L2_CID_MPEG_MFC51_VIDEO_I_PERIOD_CH &&
-                                               p->i_frm_ctrl_mode) {
-                                       ctx_ctrl->val = ctx_ctrl->val * (p->num_b_frame + 1);
-                                       if (ctx_ctrl->val >= 0x3FFFFFFF) {
-                                               mfc_info_ctx("I frame interval is bigger than max: %d\n",
-                                                               ctx_ctrl->val);
-                                               ctx_ctrl->val = 0x3FFFFFFF;
-                                       }
-                               }
-                               if (ctx_ctrl->id == V4L2_CID_MPEG_VIDEO_H264_LEVEL)
-                                       ctx_ctrl->val = __mfc_enc_h264_level((enum v4l2_mpeg_video_h264_level)(ctrl->value));
-                               if (ctx_ctrl->id == V4L2_CID_MPEG_VIDEO_H264_PROFILE)
-                                       ctx_ctrl->val = __mfc_enc_h264_profile(ctx, (enum v4l2_mpeg_video_h264_profile)(ctrl->value));
-                               if (ctx_ctrl->id == V4L2_CID_MPEG_VIDEO_ROI_CONTROL) {
-                                       if (enc->sh_handle_roi.fd == -1) {
-                                               enc->sh_handle_roi.fd = ctrl->value;
-                                               if (mfc_mem_get_user_shared_handle(ctx,
-                                                                       &enc->sh_handle_roi))
-                                                       return -EINVAL;
-                                               else
-                                                       mfc_debug(2, "[MEMINFO][ROI] shared handle fd: %d, vaddr: 0x%p\n",
-                                                                       enc->sh_handle_roi.fd,
-                                                                       enc->sh_handle_roi.vaddr);
-                                       }
-                                       index = enc->roi_index;
-                                       memcpy(&enc->roi_info[index],
-                                                       enc->sh_handle_roi.vaddr,
-                                                       sizeof(struct mfc_enc_roi_info));
-                                       if (copy_from_user(enc->roi_buf[index].vaddr,
-                                                       enc->roi_info[index].addr,
-                                                       enc->roi_info[index].size))
-                                               return -EFAULT;
-                               }
-
-                               found = 1;
-                               break;
-                       }
-               }
-
-               if (!found) {
-                       mfc_err_ctx("Invalid control: 0x%08x\n", ctrl->id);
-                       return -EINVAL;
-               }
-               break;
-       default:
-               ret = __mfc_enc_set_param(ctx, ctrl);
-               break;
-       }
-
-       return ret;
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
-                        struct v4l2_control *ctrl)
-{
-       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
-       int ret = 0;
-
-       mfc_debug_enter();
-
-       ret = __mfc_enc_check_ctrl_val(ctx, ctrl);
-       if (ret != 0)
-               return ret;
-
-       ret = __mfc_enc_set_ctrl_val(ctx, ctrl);
-
-       mfc_debug_leave();
-
-       return ret;
-}
-
-static int vidioc_g_ext_ctrls(struct file *file, void *priv,
-                             struct v4l2_ext_controls *f)
-{
-       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
-       struct v4l2_ext_control *ext_ctrl;
-       struct v4l2_control ctrl;
-       int i;
-       int ret = 0;
-
-       if (f->which != V4L2_CTRL_CLASS_MPEG)
-               return -EINVAL;
-
-       for (i = 0; i < f->count; i++) {
-               ext_ctrl = (f->controls + i);
-
-               ctrl.id = ext_ctrl->id;
-
-               ret = __mfc_enc_get_ctrl_val(ctx, &ctrl);
-               if (ret == 0) {
-                       ext_ctrl->value = ctrl.value;
-               } else {
-                       f->error_idx = i;
-                       break;
-               }
-
-               mfc_debug(5, "[CTRLS][%d] id: %#x, value: %d\n",
-                               i, ext_ctrl->id, ext_ctrl->value);
-       }
-
-       return ret;
-}
-
-static int vidioc_s_ext_ctrls(struct file *file, void *priv,
-                               struct v4l2_ext_controls *f)
-{
-       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
-       struct v4l2_ext_control *ext_ctrl;
-       struct v4l2_control ctrl;
-       int i;
-       int ret = 0;
-
-       if (f->which != V4L2_CTRL_CLASS_MPEG)
-               return -EINVAL;
-
-       for (i = 0; i < f->count; i++) {
-               ext_ctrl = (f->controls + i);
-
-               ctrl.id = ext_ctrl->id;
-               ctrl.value = ext_ctrl->value;
-
-               ret = __mfc_enc_check_ctrl_val(ctx, &ctrl);
-               if (ret != 0) {
-                       f->error_idx = i;
-                       break;
-               }
-
-               ret = __mfc_enc_set_param(ctx, &ctrl);
-               if (ret != 0) {
-                       f->error_idx = i;
-                       break;
-               }
-
-               mfc_debug(5, "[CTRLS][%d] id: %#x, value: %d\n",
-                               i, ext_ctrl->id, ext_ctrl->value);
-       }
-
-       return ret;
-}
-
-static int vidioc_try_ext_ctrls(struct file *file, void *priv,
-                               struct v4l2_ext_controls *f)
-{
-       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
-       struct v4l2_ext_control *ext_ctrl;
-       struct v4l2_control ctrl;
-       int i;
-       int ret = 0;
-
-       if (f->which != V4L2_CTRL_CLASS_MPEG)
-               return -EINVAL;
-
-       for (i = 0; i < f->count; i++) {
-               ext_ctrl = (f->controls + i);
-
-               ctrl.id = ext_ctrl->id;
-               ctrl.value = ext_ctrl->value;
-
-               ret = __mfc_enc_check_ctrl_val(ctx, &ctrl);
-               if (ret != 0) {
-                       f->error_idx = i;
-                       break;
-               }
-
-               mfc_debug(2, "[%d] id: 0x%08x, value: %d\n", i, ext_ctrl->id, ext_ctrl->value);
-       }
-
-       return ret;
-}
-
-static const struct v4l2_ioctl_ops mfc_enc_ioctl_ops = {
-       .vidioc_querycap                = vidioc_querycap,
-       .vidioc_enum_fmt_vid_cap_mplane = vidioc_enum_fmt_vid_cap_mplane,
-       .vidioc_enum_fmt_vid_out_mplane = vidioc_enum_fmt_vid_out_mplane,
-       .vidioc_g_fmt_vid_cap_mplane    = vidioc_g_fmt,
-       .vidioc_g_fmt_vid_out_mplane    = vidioc_g_fmt,
-       .vidioc_try_fmt_vid_cap_mplane  = vidioc_try_fmt,
-       .vidioc_try_fmt_vid_out_mplane  = vidioc_try_fmt,
-       .vidioc_s_fmt_vid_cap_mplane    = vidioc_s_fmt_vid_cap_mplane,
-       .vidioc_s_fmt_vid_out_mplane    = vidioc_s_fmt_vid_out_mplane,
-       .vidioc_g_crop                  = vidioc_g_crop,
-       .vidioc_s_crop                  = vidioc_s_crop,
-       .vidioc_reqbufs                 = vidioc_reqbufs,
-       .vidioc_querybuf                = vidioc_querybuf,
-       .vidioc_qbuf                    = vidioc_qbuf,
-       .vidioc_dqbuf                   = vidioc_dqbuf,
-       .vidioc_streamon                = vidioc_streamon,
-       .vidioc_streamoff               = vidioc_streamoff,
-       .vidioc_queryctrl               = vidioc_queryctrl,
-       .vidioc_g_ctrl                  = vidioc_g_ctrl,
-       .vidioc_s_ctrl                  = vidioc_s_ctrl,
-       .vidioc_g_ext_ctrls             = vidioc_g_ext_ctrls,
-       .vidioc_s_ext_ctrls             = vidioc_s_ext_ctrls,
-       .vidioc_try_ext_ctrls           = vidioc_try_ext_ctrls,
-};
-
-const struct v4l2_ioctl_ops *mfc_get_enc_v4l2_ioctl_ops(void)
-{
-       return &mfc_enc_ioctl_ops;
-}
diff --git a/drivers/media/platform/exynos/mfc/mfc_enc.h b/drivers/media/platform/exynos/mfc/mfc_enc.h
deleted file mode 100644 (file)
index f2092fa..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * drivers/media/platform/exynos/mfc/mfc_enc.h
- *
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef __MFC_ENC_H
-#define __MFC_ENC_H __FILE__
-
-#include "mfc_common.h"
-
-const struct v4l2_ioctl_ops *mfc_get_enc_v4l2_ioctl_ops(void);
-
-#endif /* __MFC_ENC_H */
diff --git a/drivers/media/platform/exynos/mfc/mfc_enc_ctrl.c b/drivers/media/platform/exynos/mfc/mfc_enc_ctrl.c
new file mode 100644 (file)
index 0000000..eb6269a
--- /dev/null
@@ -0,0 +1,1622 @@
+/*
+ * drivers/media/platform/exynos/mfc/mfc_enc_ops.c
+ *
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include "mfc_common.h"
+
+#include "mfc_reg_api.h"
+
+static int __mfc_enc_ctrl_read_cst(struct mfc_ctx *ctx,
+               struct mfc_buf_ctrl *buf_ctrl)
+{
+       int ret;
+       struct mfc_enc *enc = ctx->enc_priv;
+
+       switch (buf_ctrl->id) {
+       case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_STATUS:
+               ret = !enc->in_slice;
+               break;
+       default:
+               mfc_err_ctx("not support custom per-buffer control\n");
+               ret = -EINVAL;
+               break;
+       }
+
+       return ret;
+}
+
+static struct mfc_ctrl_cfg mfc_ctrl_list[] = {
+       {       /* set frame tag */
+               .type = MFC_CTRL_TYPE_SET,
+               .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,
+               .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,
+               .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,
+               .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 = 0xFFFFFFFF,
+               .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,
+               .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_CST,
+               .addr = 0,
+               .mask = 0xFFFFFFFF,
+               .shft = 0,
+               .flag_mode = MFC_CTRL_MODE_NONE,
+               .flag_addr = 0,
+               .flag_shft = 0,
+               .read_cst = __mfc_enc_ctrl_read_cst,
+               .write_cst = NULL,
+       },
+       {       /* H.264 I frame QP Max change */
+               .type = MFC_CTRL_TYPE_SET,
+               .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,
+               .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,
+               .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,
+               .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,
+               .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,
+               .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,
+               .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,
+               .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,
+               .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,
+               .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,
+               .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,
+               .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,
+               .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,
+               .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,
+               .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,
+               .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,
+               .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,
+               .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,
+               .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,
+               .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,
+               .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,
+               .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,
+               .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,
+               .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,
+               .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,
+               .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,
+               .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,
+               .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,
+               .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,
+               .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,
+               .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,
+               .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,
+               .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,
+               .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,
+               .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,
+               .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,
+               .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,
+               .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,
+               .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,
+               .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,
+               .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,
+               .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_mode = 0,
+               .flag_shft = 0,
+       },
+       {       /* set base layer priority */
+               .type = MFC_CTRL_TYPE_SET,
+               .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,
+       }
+};
+
+#define NUM_CTRL_CFGS ARRAY_SIZE(mfc_ctrl_list)
+
+static int mfc_enc_cleanup_ctx_ctrls(struct mfc_ctx *ctx)
+{
+       struct mfc_ctx_ctrl *ctx_ctrl;
+
+       while (!list_empty(&ctx->ctrls)) {
+               ctx_ctrl = list_entry((&ctx->ctrls)->next,
+                                     struct mfc_ctx_ctrl, list);
+               list_del(&ctx_ctrl->list);
+               kfree(ctx_ctrl);
+       }
+
+       INIT_LIST_HEAD(&ctx->ctrls);
+
+       return 0;
+}
+
+static int mfc_enc_get_buf_update_val(struct mfc_ctx *ctx,
+                       struct list_head *head, unsigned int id, int value)
+{
+       struct mfc_buf_ctrl *buf_ctrl;
+
+       list_for_each_entry(buf_ctrl, head, list) {
+               if (buf_ctrl->id == id) {
+                       buf_ctrl->val = value;
+                       mfc_debug(6, "[CTRLS] Update buffer control id: 0x%08x, val: %d\n",
+                                       buf_ctrl->id, buf_ctrl->val);
+                       break;
+               }
+       }
+
+       return 0;
+}
+
+static int mfc_enc_init_ctx_ctrls(struct mfc_ctx *ctx)
+{
+       unsigned long i;
+       struct mfc_ctx_ctrl *ctx_ctrl;
+
+       INIT_LIST_HEAD(&ctx->ctrls);
+
+       for (i = 0; i < NUM_CTRL_CFGS; i++) {
+               ctx_ctrl = kzalloc(sizeof(struct mfc_ctx_ctrl), GFP_KERNEL);
+               if (ctx_ctrl == NULL) {
+                       mfc_err_dev("Failed to allocate context control "\
+                                       "id: 0x%08x, type: %d\n",
+                                       mfc_ctrl_list[i].id,
+                                       mfc_ctrl_list[i].type);
+
+                       mfc_enc_cleanup_ctx_ctrls(ctx);
+
+                       return -ENOMEM;
+               }
+
+               ctx_ctrl->type = mfc_ctrl_list[i].type;
+               ctx_ctrl->id = mfc_ctrl_list[i].id;
+               ctx_ctrl->has_new = 0;
+               ctx_ctrl->val = 0;
+
+               list_add_tail(&ctx_ctrl->list, &ctx->ctrls);
+       }
+
+       return 0;
+}
+
+static void mfc_enc_reset_buf_ctrls(struct list_head *head)
+{
+       struct mfc_buf_ctrl *buf_ctrl;
+
+       list_for_each_entry(buf_ctrl, head, list) {
+               buf_ctrl->has_new = 0;
+               buf_ctrl->val = 0;
+               buf_ctrl->old_val = 0;
+               buf_ctrl->updated = 0;
+       }
+}
+
+static void __mfc_enc_remove_buf_ctrls(struct list_head *head)
+{
+       struct mfc_buf_ctrl *buf_ctrl;
+
+       while (!list_empty(head)) {
+               buf_ctrl = list_entry(head->next,
+                               struct mfc_buf_ctrl, list);
+               list_del(&buf_ctrl->list);
+               kfree(buf_ctrl);
+       }
+
+       INIT_LIST_HEAD(head);
+}
+
+static int mfc_enc_init_buf_ctrls(struct mfc_ctx *ctx,
+       enum mfc_ctrl_type type, unsigned int index)
+{
+       unsigned long i;
+       struct mfc_buf_ctrl *buf_ctrl;
+       struct list_head *head;
+
+       if (index >= MFC_MAX_BUFFERS) {
+               mfc_err_dev("Per-buffer control index is out of range\n");
+               return -EINVAL;
+       }
+
+       if (type & MFC_CTRL_TYPE_SRC) {
+               if (test_bit(index, &ctx->src_ctrls_avail)) {
+                       mfc_enc_reset_buf_ctrls(&ctx->src_ctrls[index]);
+
+                       return 0;
+               }
+
+               head = &ctx->src_ctrls[index];
+       } else if (type & MFC_CTRL_TYPE_DST) {
+               if (test_bit(index, &ctx->dst_ctrls_avail)) {
+                       mfc_enc_reset_buf_ctrls(&ctx->dst_ctrls[index]);
+
+                       return 0;
+               }
+
+               head = &ctx->dst_ctrls[index];
+       } else {
+               mfc_err_dev("Control type mismatch. type : %d\n", type);
+               return -EINVAL;
+       }
+
+       INIT_LIST_HEAD(head);
+
+       for (i = 0; i < NUM_CTRL_CFGS; i++) {
+               if (!(type & mfc_ctrl_list[i].type))
+                       continue;
+
+               buf_ctrl = kzalloc(sizeof(struct mfc_buf_ctrl), GFP_KERNEL);
+               if (buf_ctrl == NULL) {
+                       mfc_err_dev("Failed to allocate buffer control "\
+                                       "id: 0x%08x, type: %d\n",
+                                       mfc_ctrl_list[i].id,
+                                       mfc_ctrl_list[i].type);
+
+                       __mfc_enc_remove_buf_ctrls(head);
+
+                       return -ENOMEM;
+               }
+
+               buf_ctrl->type = mfc_ctrl_list[i].type;
+               buf_ctrl->id = mfc_ctrl_list[i].id;
+               buf_ctrl->is_volatile = mfc_ctrl_list[i].is_volatile;
+               buf_ctrl->mode = mfc_ctrl_list[i].mode;
+               buf_ctrl->addr = mfc_ctrl_list[i].addr;
+               buf_ctrl->mask = mfc_ctrl_list[i].mask;
+               buf_ctrl->shft = mfc_ctrl_list[i].shft;
+               buf_ctrl->flag_mode = mfc_ctrl_list[i].flag_mode;
+               buf_ctrl->flag_addr = mfc_ctrl_list[i].flag_addr;
+               buf_ctrl->flag_shft = mfc_ctrl_list[i].flag_shft;
+               if (buf_ctrl->mode == MFC_CTRL_MODE_CST) {
+                       buf_ctrl->read_cst = mfc_ctrl_list[i].read_cst;
+                       buf_ctrl->write_cst = mfc_ctrl_list[i].write_cst;
+               }
+
+               list_add_tail(&buf_ctrl->list, head);
+       }
+
+       mfc_enc_reset_buf_ctrls(head);
+
+       if (type & MFC_CTRL_TYPE_SRC)
+               set_bit(index, &ctx->src_ctrls_avail);
+       else
+               set_bit(index, &ctx->dst_ctrls_avail);
+
+       return 0;
+}
+
+static int mfc_enc_cleanup_buf_ctrls(struct mfc_ctx *ctx,
+       enum mfc_ctrl_type type, unsigned int index)
+{
+       struct list_head *head;
+
+       if (index >= MFC_MAX_BUFFERS) {
+               mfc_err_dev("Per-buffer control index is out of range\n");
+               return -EINVAL;
+       }
+
+       if (type & MFC_CTRL_TYPE_SRC) {
+               if (!(test_and_clear_bit(index, &ctx->src_ctrls_avail))) {
+                       return 0;
+               }
+
+               head = &ctx->src_ctrls[index];
+       } else if (type & MFC_CTRL_TYPE_DST) {
+               if (!(test_and_clear_bit(index, &ctx->dst_ctrls_avail))) {
+                       return 0;
+               }
+
+               head = &ctx->dst_ctrls[index];
+       } else {
+               mfc_err_dev("Control type mismatch. type : %d\n", type);
+               return -EINVAL;
+       }
+
+       __mfc_enc_remove_buf_ctrls(head);
+
+       return 0;
+}
+
+static int mfc_enc_to_buf_ctrls(struct mfc_ctx *ctx, struct list_head *head)
+{
+       struct mfc_ctx_ctrl *ctx_ctrl;
+       struct mfc_buf_ctrl *buf_ctrl;
+       struct mfc_enc *enc = ctx->enc_priv;
+       int index = 0;
+       unsigned int reg = 0;
+
+       list_for_each_entry(ctx_ctrl, &ctx->ctrls, list) {
+               if (!(ctx_ctrl->type & MFC_CTRL_TYPE_SET) || !ctx_ctrl->has_new)
+                       continue;
+
+               list_for_each_entry(buf_ctrl, head, list) {
+                       if (!(buf_ctrl->type & MFC_CTRL_TYPE_SET))
+                               continue;
+
+                       if (buf_ctrl->id == ctx_ctrl->id) {
+                               buf_ctrl->has_new = 1;
+                               buf_ctrl->val = ctx_ctrl->val;
+                               if (buf_ctrl->is_volatile)
+                                       buf_ctrl->updated = 0;
+
+                               ctx_ctrl->has_new = 0;
+                               if (buf_ctrl->id == V4L2_CID_MPEG_VIDEO_ROI_CONTROL) {
+                                       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);
+                                               mfc_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_debug(3, "[ROI] buffer[%d] is not enabled\n", index);
+                                       }
+                                       buf_ctrl->val = reg;
+                                       buf_ctrl->old_val2 = index;
+                               }
+                               break;
+                       }
+               }
+       }
+
+       return 0;
+}
+
+static int mfc_enc_to_ctx_ctrls(struct mfc_ctx *ctx, struct list_head *head)
+{
+       struct mfc_ctx_ctrl *ctx_ctrl;
+       struct mfc_buf_ctrl *buf_ctrl;
+
+       list_for_each_entry(buf_ctrl, head, list) {
+               if (!(buf_ctrl->type & MFC_CTRL_TYPE_GET) || !buf_ctrl->has_new)
+                       continue;
+
+               list_for_each_entry(ctx_ctrl, &ctx->ctrls, list) {
+                       if (!(ctx_ctrl->type & MFC_CTRL_TYPE_GET))
+                               continue;
+
+                       if (ctx_ctrl->id == buf_ctrl->id) {
+                               if (ctx_ctrl->has_new)
+                                       mfc_debug(8,
+                                       "Overwrite context control "\
+                                       "value id: 0x%08x, val: %d\n",
+                                               ctx_ctrl->id, ctx_ctrl->val);
+
+                               ctx_ctrl->has_new = 1;
+                               ctx_ctrl->val = buf_ctrl->val;
+
+                               buf_ctrl->has_new = 0;
+                       }
+               }
+       }
+
+       return 0;
+}
+
+static void __mfc_enc_set_buf_ctrls_temporal_svc(struct mfc_ctx *ctx,
+                       struct mfc_buf_ctrl *buf_ctrl)
+{
+       struct mfc_dev *dev = ctx->dev;
+       struct mfc_enc *enc = ctx->enc_priv;
+       unsigned int value = 0, value2 = 0;
+       struct temporal_layer_info temporal_LC;
+       unsigned int i;
+       struct mfc_enc_params *p = &enc->params;
+
+       if (buf_ctrl->id
+               == V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_CH ||
+               buf_ctrl->id
+               == V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_CH ||
+               buf_ctrl->id
+               == V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_CH ||
+               buf_ctrl->id
+               == V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_CH) {
+               memcpy(&temporal_LC,
+                       enc->sh_handle_svc.vaddr, sizeof(struct temporal_layer_info));
+
+               if(((temporal_LC.temporal_layer_count & 0x7) < 1) ||
+                       ((temporal_LC.temporal_layer_count > 3) && IS_VP8_ENC(ctx)) ||
+                       ((temporal_LC.temporal_layer_count > 3) && IS_VP9_ENC(ctx))) {
+                       /* clear NUM_T_LAYER_CHANGE */
+                       value = MFC_READL(buf_ctrl->flag_addr);
+                       value &= ~(1 << 10);
+                       MFC_WRITEL(value, buf_ctrl->flag_addr);
+                       mfc_err_ctx("[HIERARCHICAL] layer count is invalid : %d\n",
+                                       temporal_LC.temporal_layer_count);
+                       return;
+               }
+
+               if (IS_H264_ENC(ctx))
+                       p->codec.h264.num_hier_layer = temporal_LC.temporal_layer_count & 0x7;
+
+               /* enable RC_BIT_RATE_CHANGE */
+               value = MFC_READL(buf_ctrl->flag_addr);
+               if (temporal_LC.temporal_layer_bitrate[0] > 0 || p->hier_bitrate_ctrl)
+                       /* set RC_BIT_RATE_CHANGE */
+                       value |= (1 << 2);
+               else
+                       /* clear RC_BIT_RATE_CHANGE */
+                       value &= ~(1 << 2);
+               MFC_WRITEL(value, buf_ctrl->flag_addr);
+
+               mfc_debug(3, "[HIERARCHICAL] layer count %d, E_PARAM_CHANGE %#x\n",
+                               temporal_LC.temporal_layer_count & 0x7, value);
+
+               value = MFC_READL(MFC_REG_E_NUM_T_LAYER);
+               buf_ctrl->old_val2 = value;
+               value &= ~(0x7);
+               value |= (temporal_LC.temporal_layer_count & 0x7);
+               value &= ~(0x1 << 8);
+               value |= (p->hier_bitrate_ctrl & 0x1) << 8;
+               MFC_WRITEL(value, MFC_REG_E_NUM_T_LAYER);
+               mfc_debug(3, "[HIERARCHICAL] E_NUM_T_LAYER %#x\n", value);
+               for (i = 0; i < (temporal_LC.temporal_layer_count & 0x7); i++) {
+                       mfc_debug(3, "[HIERARCHICAL] layer bitrate[%d] %d (FW ctrl: %d)\n",
+                                       i, temporal_LC.temporal_layer_bitrate[i], p->hier_bitrate_ctrl);
+                       MFC_WRITEL(temporal_LC.temporal_layer_bitrate[i],
+                                       buf_ctrl->addr + i * 4);
+               }
+               /* priority change */
+               if (IS_H264_ENC(ctx)) {
+                       value = 0;
+                       value2 = 0;
+                       for (i = 0; i < (p->codec.h264.num_hier_layer & 0x07); i++) {
+                               if (i <= 4)
+                                       value |= ((p->codec.h264.base_priority & 0x3F) + i)
+                                               << (6 * i);
+                               else
+                                       value2 |= ((p->codec.h264.base_priority & 0x3F) + i)
+                                               << (6 * (i - 5));
+                       }
+                       MFC_WRITEL(value, MFC_REG_E_H264_HD_SVC_EXTENSION_0);
+                       MFC_WRITEL(value2, MFC_REG_E_H264_HD_SVC_EXTENSION_1);
+                       mfc_debug(3, "[HIERARCHICAL] EXTENSION0 %#x, EXTENSION1 %#x\n",
+                                       value, value2);
+
+                       value = MFC_READL(buf_ctrl->flag_addr);
+                       value |= (1 << 12);
+                       MFC_WRITEL(value, buf_ctrl->flag_addr);
+                       mfc_debug(3, "[HIERARCHICAL] E_PARAM_CHANGE %#x\n", value);
+               }
+
+       }
+
+       /* temproral layer priority */
+       if (buf_ctrl->id == V4L2_CID_MPEG_MFC_H264_BASE_PRIORITY) {
+               value = MFC_READL(MFC_REG_E_H264_HD_SVC_EXTENSION_0);
+               buf_ctrl->old_val |= value & 0x3FFFFFC0;
+               value &= ~(0x3FFFFFC0);
+               value2 = MFC_READL(MFC_REG_E_H264_HD_SVC_EXTENSION_1);
+               buf_ctrl->old_val2 = value2 & 0x0FFF;
+               value2 &= ~(0x0FFF);
+               for (i = 0; i < (p->codec.h264.num_hier_layer & 0x07); i++) {
+                       if (i <= 4)
+                               value |= ((buf_ctrl->val & 0x3F) + i) << (6 * i);
+                       else
+                               value2 |= ((buf_ctrl->val & 0x3F) + i) << (6 * (i - 5));
+               }
+               MFC_WRITEL(value, MFC_REG_E_H264_HD_SVC_EXTENSION_0);
+               MFC_WRITEL(value2, MFC_REG_E_H264_HD_SVC_EXTENSION_1);
+               p->codec.h264.base_priority = buf_ctrl->val;
+               mfc_debug(3, "[HIERARCHICAL] EXTENSION0 %#x, EXTENSION1 %#x\n",
+                               value, value2);
+       }
+}
+
+static void __mfc_enc_set_buf_ctrls_exception(struct mfc_ctx *ctx,
+                       struct mfc_buf_ctrl *buf_ctrl)
+{
+       struct mfc_dev *dev = ctx->dev;
+       struct mfc_enc *enc = ctx->enc_priv;
+       struct mfc_enc_params *p = &enc->params;
+       unsigned int value = 0;
+
+       if (buf_ctrl->id == V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG)
+               enc->stored_tag = buf_ctrl->val;
+
+       /* temporal layer setting */
+       __mfc_enc_set_buf_ctrls_temporal_svc(ctx, buf_ctrl);
+
+       if (buf_ctrl->id == V4L2_CID_MPEG_MFC_H264_MARK_LTR) {
+               value = MFC_READL(MFC_REG_E_H264_NAL_CONTROL);
+               buf_ctrl->old_val2 = (value >> 8) & 0x7;
+               value &= ~(0x7 << 8);
+               value |= (buf_ctrl->val & 0x7) << 8;
+               MFC_WRITEL(value, MFC_REG_E_H264_NAL_CONTROL);
+       }
+       if (buf_ctrl->id == V4L2_CID_MPEG_MFC_H264_USE_LTR) {
+               value = MFC_READL(MFC_REG_E_H264_NAL_CONTROL);
+               buf_ctrl->old_val2 = (value >> 11) & 0xF;
+               value &= ~(0xF << 11);
+               value |= (buf_ctrl->val & 0xF) << 11;
+               MFC_WRITEL(value, MFC_REG_E_H264_NAL_CONTROL);
+       }
+
+       if (buf_ctrl->id == V4L2_CID_MPEG_MFC51_VIDEO_I_PERIOD_CH) {
+               value = MFC_READL(MFC_REG_E_GOP_CONFIG2);
+               buf_ctrl->old_val |= (value << 16) & 0x3FFF0000;
+               value &= ~(0x3FFF);
+               value |= (buf_ctrl->val >> 16) & 0x3FFF;
+               MFC_WRITEL(value, MFC_REG_E_GOP_CONFIG2);
+       }
+
+       /* PROFILE & LEVEL have to be set up together */
+       if (buf_ctrl->id == V4L2_CID_MPEG_VIDEO_H264_LEVEL) {
+               value = MFC_READL(MFC_REG_E_PICTURE_PROFILE);
+               buf_ctrl->old_val |= (value & 0x000F) << 8;
+               value &= ~(0x000F);
+               value |= p->codec.h264.profile & 0x000F;
+               MFC_WRITEL(value, MFC_REG_E_PICTURE_PROFILE);
+               p->codec.h264.level = buf_ctrl->val;
+       }
+
+       if (buf_ctrl->id == V4L2_CID_MPEG_VIDEO_H264_PROFILE) {
+               value = MFC_READL(MFC_REG_E_PICTURE_PROFILE);
+               buf_ctrl->old_val |= value & 0xFF00;
+               value &= ~(0x00FF << 8);
+               value |= (p->codec.h264.level << 8) & 0xFF00;
+               MFC_WRITEL(value, MFC_REG_E_PICTURE_PROFILE);
+               p->codec.h264.profile = buf_ctrl->val;
+       }
+
+       /* per buffer QP setting change */
+       if (buf_ctrl->id == V4L2_CID_MPEG_MFC_CONFIG_QP)
+               p->config_qp = buf_ctrl->val;
+
+       /* set the ROI buffer DVA */
+       if (buf_ctrl->id == V4L2_CID_MPEG_VIDEO_ROI_CONTROL) {
+               MFC_WRITEL(enc->roi_buf[buf_ctrl->old_val2].daddr,
+                               MFC_REG_E_ROI_BUFFER_ADDR);
+               mfc_debug(3, "[ROI] buffer[%d] addr %#llx, QP val: %#x\n",
+                               buf_ctrl->old_val2,
+                               enc->roi_buf[buf_ctrl->old_val2].daddr,
+                               buf_ctrl->val);
+       }
+}
+
+static int mfc_enc_set_buf_ctrls_val(struct mfc_ctx *ctx, struct list_head *head)
+{
+       struct mfc_buf_ctrl *buf_ctrl;
+       struct mfc_dev *dev = ctx->dev;
+       struct mfc_enc *enc = ctx->enc_priv;
+       unsigned int value = 0;
+       struct mfc_enc_params *p = &enc->params;
+
+       list_for_each_entry(buf_ctrl, head, list) {
+               if (!(buf_ctrl->type & MFC_CTRL_TYPE_SET) || !buf_ctrl->has_new)
+                       continue;
+
+               /* read old vlaue */
+               value = MFC_READL(buf_ctrl->addr);
+
+               /* save old value for recovery */
+               if (buf_ctrl->is_volatile)
+                       buf_ctrl->old_val = (value >> buf_ctrl->shft) & buf_ctrl->mask;
+
+               /* write new value */
+               value &= ~(buf_ctrl->mask << buf_ctrl->shft);
+               value |= ((buf_ctrl->val & buf_ctrl->mask) << buf_ctrl->shft);
+               MFC_WRITEL(value, buf_ctrl->addr);
+
+               /* set change flag bit */
+               if (buf_ctrl->flag_mode == MFC_CTRL_MODE_SFR) {
+                       value = MFC_READL(buf_ctrl->flag_addr);
+                       value |= (1 << buf_ctrl->flag_shft);
+                       MFC_WRITEL(value, buf_ctrl->flag_addr);
+               }
+
+               buf_ctrl->has_new = 0;
+               buf_ctrl->updated = 1;
+
+               __mfc_enc_set_buf_ctrls_exception(ctx, buf_ctrl);
+
+               mfc_debug(6, "[CTRLS] Set buffer control id: 0x%08x, val: %d\n",
+                               buf_ctrl->id, buf_ctrl->val);
+       }
+
+       if (!p->rc_frame && !p->rc_mb && p->dynamic_qp) {
+               value = MFC_READL(MFC_REG_E_FIXED_PICTURE_QP);
+               value &= ~(0xFF000000);
+               value |= (p->config_qp & 0xFF) << 24;
+               MFC_WRITEL(value, MFC_REG_E_FIXED_PICTURE_QP);
+               mfc_debug(6, "[CTRLS] Dynamic QP changed %#x\n",
+                               MFC_READL(MFC_REG_E_FIXED_PICTURE_QP));
+       }
+
+       return 0;
+}
+
+static int mfc_enc_get_buf_ctrls_val(struct mfc_ctx *ctx, struct list_head *head)
+{
+       struct mfc_buf_ctrl *buf_ctrl;
+       struct mfc_dev *dev = ctx->dev;
+       unsigned int value = 0;
+
+       list_for_each_entry(buf_ctrl, head, list) {
+               if (!(buf_ctrl->type & MFC_CTRL_TYPE_GET))
+                       continue;
+
+               if (buf_ctrl->mode == MFC_CTRL_MODE_SFR)
+                       value = MFC_READL(buf_ctrl->addr);
+               else if (buf_ctrl->mode == MFC_CTRL_MODE_CST)
+                       value = call_bop(buf_ctrl, read_cst, ctx, buf_ctrl);
+
+               value = (value >> buf_ctrl->shft) & buf_ctrl->mask;
+
+               buf_ctrl->val = value;
+               buf_ctrl->has_new = 1;
+
+               mfc_debug(6, "[CTRLS] Get buffer control id: 0x%08x, val: %d\n",
+                               buf_ctrl->id, buf_ctrl->val);
+       }
+
+       return 0;
+}
+
+static int mfc_enc_set_buf_ctrls_val_nal_q_enc(struct mfc_ctx *ctx,
+                       struct list_head *head, EncoderInputStr *pInStr)
+{
+       struct mfc_buf_ctrl *buf_ctrl;
+       struct mfc_enc *enc = ctx->enc_priv;
+       struct temporal_layer_info temporal_LC;
+       unsigned int i, param_change;
+       struct mfc_enc_params *p = &enc->params;
+
+       mfc_debug_enter();
+
+       list_for_each_entry(buf_ctrl, head, list) {
+               if (!(buf_ctrl->type & MFC_CTRL_TYPE_SET) || !buf_ctrl->has_new)
+                       continue;
+               param_change = 0;
+               switch (buf_ctrl->id) {
+               case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG:
+                       pInStr->PictureTag &= ~(buf_ctrl->mask << buf_ctrl->shft);
+                       pInStr->PictureTag |=
+                               (buf_ctrl->val & buf_ctrl->mask) << buf_ctrl->shft;
+                       enc->stored_tag = buf_ctrl->val;
+                       break;
+               case V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE:
+                       pInStr->FrameInsertion &= ~(buf_ctrl->mask << buf_ctrl->shft);
+                       pInStr->FrameInsertion |=
+                               (buf_ctrl->val & buf_ctrl->mask) << buf_ctrl->shft;
+                       break;
+               case V4L2_CID_MPEG_MFC51_VIDEO_I_PERIOD_CH:
+                       pInStr->GopConfig &= ~(buf_ctrl->mask << buf_ctrl->shft);
+                       pInStr->GopConfig |=
+                               (buf_ctrl->val & buf_ctrl->mask) << buf_ctrl->shft;
+                       pInStr->GopConfig2 &= ~(0x3FFF);
+                       pInStr->GopConfig2 |= (buf_ctrl->val >> 16) & 0x3FFF;
+                       param_change = 1;
+                       break;
+               case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_RATE_CH:
+                       pInStr->RcFrameRate &= ~(buf_ctrl->mask << buf_ctrl->shft);
+                       pInStr->RcFrameRate |=
+                               (buf_ctrl->val & buf_ctrl->mask) << buf_ctrl->shft;
+                       param_change = 1;
+                       break;
+               case V4L2_CID_MPEG_MFC51_VIDEO_BIT_RATE_CH:
+                       pInStr->RcBitRate &= ~(buf_ctrl->mask << buf_ctrl->shft);
+                       pInStr->RcBitRate |=
+                               (buf_ctrl->val & buf_ctrl->mask) << buf_ctrl->shft;
+                       param_change = 1;
+                       break;
+               case V4L2_CID_MPEG_VIDEO_H264_MAX_QP:
+               case V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP:
+               case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP:
+               case V4L2_CID_MPEG_VIDEO_H263_MAX_QP:
+               case V4L2_CID_MPEG_VIDEO_VP8_MAX_QP:
+               case V4L2_CID_MPEG_VIDEO_VP9_MAX_QP:
+               case V4L2_CID_MPEG_VIDEO_H264_MIN_QP:
+               case V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP:
+               case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP:
+               case V4L2_CID_MPEG_VIDEO_H263_MIN_QP:
+               case V4L2_CID_MPEG_VIDEO_VP8_MIN_QP:
+               case V4L2_CID_MPEG_VIDEO_VP9_MIN_QP:
+                       pInStr->RcQpBound &= ~(buf_ctrl->mask << buf_ctrl->shft);
+                       pInStr->RcQpBound |=
+                               (buf_ctrl->val & buf_ctrl->mask) << buf_ctrl->shft;
+                       param_change = 1;
+                       break;
+               case V4L2_CID_MPEG_VIDEO_H264_MAX_QP_P:
+               case V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP_P:
+               case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP_P:
+               case V4L2_CID_MPEG_VIDEO_H263_MAX_QP_P:
+               case V4L2_CID_MPEG_VIDEO_VP8_MAX_QP_P:
+               case V4L2_CID_MPEG_VIDEO_VP9_MAX_QP_P:
+               case V4L2_CID_MPEG_VIDEO_H264_MIN_QP_P:
+               case V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP_P:
+               case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP_P:
+               case V4L2_CID_MPEG_VIDEO_H263_MIN_QP_P:
+               case V4L2_CID_MPEG_VIDEO_VP8_MIN_QP_P:
+               case V4L2_CID_MPEG_VIDEO_VP9_MIN_QP_P:
+               case V4L2_CID_MPEG_VIDEO_H264_MAX_QP_B:
+               case V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP_B:
+               case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP_B:
+               case V4L2_CID_MPEG_VIDEO_H264_MIN_QP_B:
+               case V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP_B:
+               case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP_B:
+                       pInStr->RcQpBoundPb &= ~(buf_ctrl->mask << buf_ctrl->shft);
+                       pInStr->RcQpBoundPb |=
+                               (buf_ctrl->val & buf_ctrl->mask) << buf_ctrl->shft;
+                       param_change = 1;
+                       break;
+               case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_CH:
+               case V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_CH:
+               case V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_CH:
+               case V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_CH:
+                       memcpy(&temporal_LC,
+                               enc->sh_handle_svc.vaddr, sizeof(struct temporal_layer_info));
+
+                       if (((temporal_LC.temporal_layer_count & 0x7) < 1) ||
+                               ((temporal_LC.temporal_layer_count > 3) && IS_VP8_ENC(ctx)) ||
+                               ((temporal_LC.temporal_layer_count > 3) && IS_VP9_ENC(ctx))) {
+                               /* claer NUM_T_LAYER_CHANGE */
+                               mfc_err_ctx("[NALQ][HIERARCHICAL] layer count(%d) is invalid\n",
+                                               temporal_LC.temporal_layer_count);
+                               return 0;
+                       }
+
+                       if (IS_H264_ENC(ctx))
+                               p->codec.h264.num_hier_layer =
+                                       temporal_LC.temporal_layer_count & 0x7;
+
+                       /* enable RC_BIT_RATE_CHANGE */
+                       if (temporal_LC.temporal_layer_bitrate[0] > 0 || p->hier_bitrate_ctrl)
+                               pInStr->ParamChange |= (1 << 2);
+                       else
+                               pInStr->ParamChange &= ~(1 << 2);
+
+                       /* enalbe NUM_T_LAYER_CHANGE */
+                       if (temporal_LC.temporal_layer_count & 0x7)
+                               pInStr->ParamChange |= (1 << 10);
+                       else
+                               pInStr->ParamChange &= ~(1 << 10);
+                       mfc_debug(3, "[NALQ][HIERARCHICAL] layer count %d\n",
+                                       temporal_LC.temporal_layer_count & 0x7);
+
+                       pInStr->NumTLayer &= ~(0x7);
+                       pInStr->NumTLayer |= (temporal_LC.temporal_layer_count & 0x7);
+                       pInStr->NumTLayer &= ~(0x1 << 8);
+                       pInStr->NumTLayer |= (p->hier_bitrate_ctrl & 0x1) << 8;
+                       for (i = 0; i < (temporal_LC.temporal_layer_count & 0x7); i++) {
+                               mfc_debug(3, "[NALQ][HIERARCHICAL] layer bitrate[%d] %d (FW ctrl: %d)\n",
+                                       i, temporal_LC.temporal_layer_bitrate[i], p->hier_bitrate_ctrl);
+                               pInStr->HierarchicalBitRateLayer[i] =
+                                       temporal_LC.temporal_layer_bitrate[i];
+                       }
+
+                       /* priority change */
+                       if (IS_H264_ENC(ctx)) {
+                               for (i = 0; i < (temporal_LC.temporal_layer_count & 0x7); i++) {
+                                       if (i <= 4)
+                                               pInStr->H264HDSvcExtension0 |=
+                                                       ((p->codec.h264.base_priority & 0x3f) + i) << (6 * i);
+                                       else
+                                               pInStr->H264HDSvcExtension1 |=
+                                                       ((p->codec.h264.base_priority & 0x3f) + i) << (6 * (i - 5));
+                               }
+                               mfc_debug(3, "[NALQ][HIERARCHICAL] EXTENSION0 %#x, EXTENSION1 %#x\n",
+                                               pInStr->H264HDSvcExtension0, pInStr->H264HDSvcExtension1);
+
+                               pInStr->ParamChange |= (1 << 12);
+                       }
+                       break;
+               case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
+                       pInStr->PictureProfile &= ~(buf_ctrl->mask << buf_ctrl->shft);
+                       pInStr->PictureProfile |=
+                               (buf_ctrl->val & buf_ctrl->mask) << buf_ctrl->shft;
+                       pInStr->PictureProfile &= ~(0xf);
+                       pInStr->PictureProfile |= p->codec.h264.profile & 0xf;
+                       p->codec.h264.level = buf_ctrl->val;
+                       param_change = 1;
+                       break;
+               case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
+                       pInStr->PictureProfile &= ~(buf_ctrl->mask << buf_ctrl->shft);
+                       pInStr->PictureProfile |=
+                               (buf_ctrl->val & buf_ctrl->mask) << buf_ctrl->shft;
+                       pInStr->PictureProfile &= ~(0xff << 8);
+                       pInStr->PictureProfile |= (p->codec.h264.level << 8) & 0xff00;
+                       p->codec.h264.profile = buf_ctrl->val;
+                       param_change = 1;
+                       break;
+               case V4L2_CID_MPEG_MFC_H264_MARK_LTR:
+                       pInStr->H264NalControl &= ~(buf_ctrl->mask << buf_ctrl->shft);
+                       pInStr->H264NalControl |=
+                               (buf_ctrl->val & buf_ctrl->mask) << buf_ctrl->shft;
+                       pInStr->H264NalControl &= ~(0x7 << 8);
+                       pInStr->H264NalControl |= (buf_ctrl->val & 0x7) << 8;
+                       break;
+               case V4L2_CID_MPEG_MFC_H264_USE_LTR:
+                       pInStr->H264NalControl &= ~(buf_ctrl->mask << buf_ctrl->shft);
+                       pInStr->H264NalControl |=
+                               (buf_ctrl->val & buf_ctrl->mask) << buf_ctrl->shft;
+                       pInStr->H264NalControl &= ~(0xF << 11);
+                       pInStr->H264NalControl |= (buf_ctrl->val & 0xF) << 11;
+                       break;
+               case V4L2_CID_MPEG_MFC_H264_BASE_PRIORITY:
+                       for (i = 0; i < (p->codec.h264.num_hier_layer & 0x7); i++)
+                               if (i <= 4)
+                                       pInStr->H264HDSvcExtension0 |=
+                                               ((buf_ctrl->val & 0x3f) + i) << (6 * i);
+                               else
+                                       pInStr->H264HDSvcExtension1 |=
+                                               ((buf_ctrl->val & 0x3f) + i) << (6 * (i - 5));
+                       p->codec.h264.base_priority = buf_ctrl->val;
+                       param_change = 1;
+                       break;
+               case V4L2_CID_MPEG_MFC_CONFIG_QP:
+                       pInStr->FixedPictureQp &= ~(buf_ctrl->mask << buf_ctrl->shft);
+                       pInStr->FixedPictureQp |=
+                               (buf_ctrl->val & buf_ctrl->mask) << buf_ctrl->shft;
+                       p->config_qp = buf_ctrl->val;
+                       break;
+               case V4L2_CID_MPEG_VIDEO_ROI_CONTROL:
+                       pInStr->RcRoiCtrl &= ~(buf_ctrl->mask << buf_ctrl->shft);
+                       pInStr->RcRoiCtrl |=
+                               (buf_ctrl->val & buf_ctrl->mask) << buf_ctrl->shft;
+                       pInStr->RoiBufferAddr = enc->roi_buf[buf_ctrl->old_val2].daddr;
+                       mfc_debug(3, "[NALQ][ROI] buffer[%d] addr %#llx, QP val: %#x\n",
+                                       buf_ctrl->old_val2,
+                                       enc->roi_buf[buf_ctrl->old_val2].daddr,
+                                       buf_ctrl->val);
+                       break;
+               case V4L2_CID_MPEG_VIDEO_YSUM:
+                       pInStr->Weight &= ~(buf_ctrl->mask << buf_ctrl->shft);
+                       pInStr->Weight |=
+                               (buf_ctrl->val & buf_ctrl->mask) << buf_ctrl->shft;
+                       break;
+               case V4L2_CID_MPEG_VIDEO_RATIO_OF_INTRA:
+                       pInStr->RcMode &= ~(buf_ctrl->mask << buf_ctrl->shft);
+                       pInStr->RcMode |=
+                               (buf_ctrl->val & buf_ctrl->mask) << buf_ctrl->shft;
+                       param_change = 1;
+                       break;
+               /* If new dynamic controls are added, insert here */
+               default:
+                       mfc_info_ctx("[NALQ] can't find control, id: 0x%x\n",
+                                       buf_ctrl->id);
+               }
+
+               if (param_change)
+                       pInStr->ParamChange |= (1 << buf_ctrl->flag_shft);
+
+               buf_ctrl->has_new = 0;
+               buf_ctrl->updated = 1;
+
+               mfc_debug(6, "[NALQ][CTRLS] Set buffer control id: 0x%08x, val: %d\n",
+                               buf_ctrl->id, buf_ctrl->val);
+       }
+
+       if (!p->rc_frame && !p->rc_mb && p->dynamic_qp) {
+               pInStr->FixedPictureQp &= ~(0xFF000000);
+               pInStr->FixedPictureQp |= (p->config_qp & 0xFF) << 24;
+               mfc_debug(6, "[NALQ][CTRLS] Dynamic QP changed %#x\n",
+                               pInStr->FixedPictureQp);
+       }
+
+       mfc_debug_leave();
+
+       return 0;
+}
+
+static int mfc_enc_get_buf_ctrls_val_nal_q_enc(struct mfc_ctx *ctx,
+                       struct list_head *head, EncoderOutputStr *pOutStr)
+{
+       struct mfc_buf_ctrl *buf_ctrl;
+       struct mfc_enc *enc = ctx->enc_priv;
+       unsigned int value = 0;
+
+       mfc_debug_enter();
+
+       list_for_each_entry(buf_ctrl, head, list) {
+               if (!(buf_ctrl->type & MFC_CTRL_TYPE_GET))
+                       continue;
+               switch (buf_ctrl->id) {
+               case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG:
+                       value = pOutStr->PictureTag;
+                       break;
+               case V4L2_CID_MPEG_MFC51_VIDEO_LUMA_ADDR:
+                       value = pOutStr->EncodedFrameAddr[0];
+                       break;
+               case V4L2_CID_MPEG_MFC51_VIDEO_CHROMA_ADDR:
+                       value = pOutStr->EncodedFrameAddr[1];
+                       break;
+               case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_STATUS:
+                       value = !enc->in_slice;
+                       break;
+               /* If new dynamic controls are added, insert here */
+               default:
+                       mfc_info_ctx("[NALQ] can't find control, id: 0x%x\n",
+                                       buf_ctrl->id);
+               }
+               value = (value >> buf_ctrl->shft) & buf_ctrl->mask;
+
+               buf_ctrl->val = value;
+               buf_ctrl->has_new = 1;
+
+               mfc_debug(6, "[NALQ][CTRLS] Get buffer control id: 0x%08x, val: %d\n",
+                               buf_ctrl->id, buf_ctrl->val);
+       }
+
+       mfc_debug_leave();
+
+       return 0;
+}
+
+static int mfc_enc_recover_buf_ctrls_val(struct mfc_ctx *ctx,
+                                               struct list_head *head)
+{
+       struct mfc_buf_ctrl *buf_ctrl;
+       struct mfc_dev *dev = ctx->dev;
+       unsigned int value = 0;
+
+       list_for_each_entry(buf_ctrl, head, list) {
+               if (!(buf_ctrl->type & MFC_CTRL_TYPE_SET)
+                       || !buf_ctrl->is_volatile
+                       || !buf_ctrl->updated)
+                       continue;
+
+               if (buf_ctrl->mode == MFC_CTRL_MODE_SFR)
+                       value = MFC_READL(buf_ctrl->addr);
+
+               value &= ~(buf_ctrl->mask << buf_ctrl->shft);
+               value |= ((buf_ctrl->old_val & buf_ctrl->mask)
+                                                       << buf_ctrl->shft);
+
+               if (buf_ctrl->mode == MFC_CTRL_MODE_SFR)
+                       MFC_WRITEL(value, buf_ctrl->addr);
+
+               /* clear change flag bit */
+               if (buf_ctrl->flag_mode == MFC_CTRL_MODE_SFR) {
+                       value = MFC_READL(buf_ctrl->flag_addr);
+                       value &= ~(1 << buf_ctrl->flag_shft);
+                       MFC_WRITEL(value, buf_ctrl->flag_addr);
+               }
+
+               mfc_debug(6, "[CTRLS] Recover buffer control id: 0x%08x, old val: %d\n",
+                               buf_ctrl->id, buf_ctrl->old_val);
+
+               if (buf_ctrl->id == V4L2_CID_MPEG_MFC51_VIDEO_I_PERIOD_CH) {
+                       value = MFC_READL(MFC_REG_E_GOP_CONFIG2);
+                       value &= ~(0x3FFF);
+                       value |= (buf_ctrl->old_val >> 16) & 0x3FFF;
+                       MFC_WRITEL(value, MFC_REG_E_GOP_CONFIG2);
+               }
+               if (buf_ctrl->id == V4L2_CID_MPEG_VIDEO_H264_LEVEL) {
+                       value = MFC_READL(MFC_REG_E_PICTURE_PROFILE);
+                       value &= ~(0x000F);
+                       value |= (buf_ctrl->old_val >> 8) & 0x000F;
+                       MFC_WRITEL(value, MFC_REG_E_PICTURE_PROFILE);
+               }
+               if (buf_ctrl->id == V4L2_CID_MPEG_VIDEO_H264_PROFILE) {
+                       value = MFC_READL(MFC_REG_E_PICTURE_PROFILE);
+                       value &= ~(0xFF00);
+                       value |= buf_ctrl->old_val & 0xFF00;
+                       MFC_WRITEL(value, MFC_REG_E_PICTURE_PROFILE);
+               }
+               if (buf_ctrl->id == V4L2_CID_MPEG_MFC_H264_BASE_PRIORITY) {
+                       MFC_WRITEL(buf_ctrl->old_val, MFC_REG_E_H264_HD_SVC_EXTENSION_0);
+                       MFC_WRITEL(buf_ctrl->old_val2, MFC_REG_E_H264_HD_SVC_EXTENSION_1);
+               }
+               if (buf_ctrl->id
+                       == V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_CH ||
+                       buf_ctrl->id
+                       == V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_CH ||
+                       buf_ctrl->id
+                       == V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_CH) {
+                       MFC_WRITEL(buf_ctrl->old_val2, MFC_REG_E_NUM_T_LAYER);
+                       /* clear RC_BIT_RATE_CHANGE */
+                       value = MFC_READL(buf_ctrl->flag_addr);
+                       value &= ~(1 << 2);
+                       MFC_WRITEL(value, buf_ctrl->flag_addr);
+               }
+               if (buf_ctrl->id == V4L2_CID_MPEG_MFC_H264_MARK_LTR) {
+                       value = MFC_READL(MFC_REG_E_H264_NAL_CONTROL);
+                       value &= ~(0x7 << 8);
+                       value |= (buf_ctrl->old_val2 & 0x7) << 8;
+                       MFC_WRITEL(value, MFC_REG_E_H264_NAL_CONTROL);
+               }
+               if (buf_ctrl->id == V4L2_CID_MPEG_MFC_H264_USE_LTR) {
+                       value = MFC_READL(MFC_REG_E_H264_NAL_CONTROL);
+                       value &= ~(0xF << 11);
+                       value |= (buf_ctrl->old_val2 & 0xF) << 11;
+                       MFC_WRITEL(value, MFC_REG_E_H264_NAL_CONTROL);
+               }
+               buf_ctrl->updated = 0;
+       }
+
+       return 0;
+}
+
+static int mfc_enc_recover_buf_ctrls_nal_q(struct mfc_ctx *ctx,
+               struct list_head *head)
+{
+       struct mfc_buf_ctrl *buf_ctrl;
+
+       list_for_each_entry(buf_ctrl, head, list) {
+               if (!(buf_ctrl->type & MFC_CTRL_TYPE_SET)
+                               || !(buf_ctrl->updated))
+                       continue;
+
+               buf_ctrl->has_new = 1;
+               buf_ctrl->updated = 0;
+
+               mfc_debug(6, "[NALQ][CTRLS] Recover buffer control id: 0x%08x, val: %d\n",
+                               buf_ctrl->id, buf_ctrl->val);
+       }
+
+       return 0;
+}
+
+struct mfc_ctrls_ops encoder_ctrls_ops = {
+       .init_ctx_ctrls                 = mfc_enc_init_ctx_ctrls,
+       .cleanup_ctx_ctrls              = mfc_enc_cleanup_ctx_ctrls,
+       .init_buf_ctrls                 = mfc_enc_init_buf_ctrls,
+       .reset_buf_ctrls                = mfc_enc_reset_buf_ctrls,
+       .cleanup_buf_ctrls              = mfc_enc_cleanup_buf_ctrls,
+       .to_buf_ctrls                   = mfc_enc_to_buf_ctrls,
+       .to_ctx_ctrls                   = mfc_enc_to_ctx_ctrls,
+       .set_buf_ctrls_val              = mfc_enc_set_buf_ctrls_val,
+       .get_buf_ctrls_val              = mfc_enc_get_buf_ctrls_val,
+       .recover_buf_ctrls_val          = mfc_enc_recover_buf_ctrls_val,
+       .get_buf_update_val             = mfc_enc_get_buf_update_val,
+       .set_buf_ctrls_val_nal_q_enc    = mfc_enc_set_buf_ctrls_val_nal_q_enc,
+       .get_buf_ctrls_val_nal_q_enc    = mfc_enc_get_buf_ctrls_val_nal_q_enc,
+       .recover_buf_ctrls_nal_q        = mfc_enc_recover_buf_ctrls_nal_q,
+};
diff --git a/drivers/media/platform/exynos/mfc/mfc_enc_ops.c b/drivers/media/platform/exynos/mfc/mfc_enc_ops.c
deleted file mode 100644 (file)
index 824fe53..0000000
+++ /dev/null
@@ -1,1622 +0,0 @@
-/*
- * drivers/media/platform/exynos/mfc/mfc_enc_ops.c
- *
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include "mfc_common.h"
-
-#include "mfc_reg.h"
-
-static int __mfc_enc_ctrl_read_cst(struct mfc_ctx *ctx,
-               struct mfc_buf_ctrl *buf_ctrl)
-{
-       int ret;
-       struct mfc_enc *enc = ctx->enc_priv;
-
-       switch (buf_ctrl->id) {
-       case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_STATUS:
-               ret = !enc->in_slice;
-               break;
-       default:
-               mfc_err_ctx("not support custom per-buffer control\n");
-               ret = -EINVAL;
-               break;
-       }
-
-       return ret;
-}
-
-static struct mfc_ctrl_cfg mfc_ctrl_list[] = {
-       {       /* set frame tag */
-               .type = MFC_CTRL_TYPE_SET,
-               .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,
-               .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,
-               .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,
-               .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 = 0xFFFFFFFF,
-               .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,
-               .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_CST,
-               .addr = 0,
-               .mask = 0xFFFFFFFF,
-               .shft = 0,
-               .flag_mode = MFC_CTRL_MODE_NONE,
-               .flag_addr = 0,
-               .flag_shft = 0,
-               .read_cst = __mfc_enc_ctrl_read_cst,
-               .write_cst = NULL,
-       },
-       {       /* H.264 I frame QP Max change */
-               .type = MFC_CTRL_TYPE_SET,
-               .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,
-               .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,
-               .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,
-               .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,
-               .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,
-               .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,
-               .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,
-               .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,
-               .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,
-               .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,
-               .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,
-               .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,
-               .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,
-               .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,
-               .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,
-               .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,
-               .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,
-               .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,
-               .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,
-               .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,
-               .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,
-               .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,
-               .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,
-               .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,
-               .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,
-               .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,
-               .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,
-               .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,
-               .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,
-               .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,
-               .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,
-               .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,
-               .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,
-               .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,
-               .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,
-               .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,
-               .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,
-               .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,
-               .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,
-               .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,
-               .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,
-               .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_mode = 0,
-               .flag_shft = 0,
-       },
-       {       /* set base layer priority */
-               .type = MFC_CTRL_TYPE_SET,
-               .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,
-       }
-};
-
-#define NUM_CTRL_CFGS ARRAY_SIZE(mfc_ctrl_list)
-
-static int mfc_enc_cleanup_ctx_ctrls(struct mfc_ctx *ctx)
-{
-       struct mfc_ctx_ctrl *ctx_ctrl;
-
-       while (!list_empty(&ctx->ctrls)) {
-               ctx_ctrl = list_entry((&ctx->ctrls)->next,
-                                     struct mfc_ctx_ctrl, list);
-               list_del(&ctx_ctrl->list);
-               kfree(ctx_ctrl);
-       }
-
-       INIT_LIST_HEAD(&ctx->ctrls);
-
-       return 0;
-}
-
-static int mfc_enc_get_buf_update_val(struct mfc_ctx *ctx,
-                       struct list_head *head, unsigned int id, int value)
-{
-       struct mfc_buf_ctrl *buf_ctrl;
-
-       list_for_each_entry(buf_ctrl, head, list) {
-               if (buf_ctrl->id == id) {
-                       buf_ctrl->val = value;
-                       mfc_debug(6, "[CTRLS] Update buffer control id: 0x%08x, val: %d\n",
-                                       buf_ctrl->id, buf_ctrl->val);
-                       break;
-               }
-       }
-
-       return 0;
-}
-
-static int mfc_enc_init_ctx_ctrls(struct mfc_ctx *ctx)
-{
-       unsigned long i;
-       struct mfc_ctx_ctrl *ctx_ctrl;
-
-       INIT_LIST_HEAD(&ctx->ctrls);
-
-       for (i = 0; i < NUM_CTRL_CFGS; i++) {
-               ctx_ctrl = kzalloc(sizeof(struct mfc_ctx_ctrl), GFP_KERNEL);
-               if (ctx_ctrl == NULL) {
-                       mfc_err_dev("Failed to allocate context control "\
-                                       "id: 0x%08x, type: %d\n",
-                                       mfc_ctrl_list[i].id,
-                                       mfc_ctrl_list[i].type);
-
-                       mfc_enc_cleanup_ctx_ctrls(ctx);
-
-                       return -ENOMEM;
-               }
-
-               ctx_ctrl->type = mfc_ctrl_list[i].type;
-               ctx_ctrl->id = mfc_ctrl_list[i].id;
-               ctx_ctrl->has_new = 0;
-               ctx_ctrl->val = 0;
-
-               list_add_tail(&ctx_ctrl->list, &ctx->ctrls);
-       }
-
-       return 0;
-}
-
-static void mfc_enc_reset_buf_ctrls(struct list_head *head)
-{
-       struct mfc_buf_ctrl *buf_ctrl;
-
-       list_for_each_entry(buf_ctrl, head, list) {
-               buf_ctrl->has_new = 0;
-               buf_ctrl->val = 0;
-               buf_ctrl->old_val = 0;
-               buf_ctrl->updated = 0;
-       }
-}
-
-static void __mfc_enc_remove_buf_ctrls(struct list_head *head)
-{
-       struct mfc_buf_ctrl *buf_ctrl;
-
-       while (!list_empty(head)) {
-               buf_ctrl = list_entry(head->next,
-                               struct mfc_buf_ctrl, list);
-               list_del(&buf_ctrl->list);
-               kfree(buf_ctrl);
-       }
-
-       INIT_LIST_HEAD(head);
-}
-
-static int mfc_enc_init_buf_ctrls(struct mfc_ctx *ctx,
-       enum mfc_ctrl_type type, unsigned int index)
-{
-       unsigned long i;
-       struct mfc_buf_ctrl *buf_ctrl;
-       struct list_head *head;
-
-       if (index >= MFC_MAX_BUFFERS) {
-               mfc_err_dev("Per-buffer control index is out of range\n");
-               return -EINVAL;
-       }
-
-       if (type & MFC_CTRL_TYPE_SRC) {
-               if (test_bit(index, &ctx->src_ctrls_avail)) {
-                       mfc_enc_reset_buf_ctrls(&ctx->src_ctrls[index]);
-
-                       return 0;
-               }
-
-               head = &ctx->src_ctrls[index];
-       } else if (type & MFC_CTRL_TYPE_DST) {
-               if (test_bit(index, &ctx->dst_ctrls_avail)) {
-                       mfc_enc_reset_buf_ctrls(&ctx->dst_ctrls[index]);
-
-                       return 0;
-               }
-
-               head = &ctx->dst_ctrls[index];
-       } else {
-               mfc_err_dev("Control type mismatch. type : %d\n", type);
-               return -EINVAL;
-       }
-
-       INIT_LIST_HEAD(head);
-
-       for (i = 0; i < NUM_CTRL_CFGS; i++) {
-               if (!(type & mfc_ctrl_list[i].type))
-                       continue;
-
-               buf_ctrl = kzalloc(sizeof(struct mfc_buf_ctrl), GFP_KERNEL);
-               if (buf_ctrl == NULL) {
-                       mfc_err_dev("Failed to allocate buffer control "\
-                                       "id: 0x%08x, type: %d\n",
-                                       mfc_ctrl_list[i].id,
-                                       mfc_ctrl_list[i].type);
-
-                       __mfc_enc_remove_buf_ctrls(head);
-
-                       return -ENOMEM;
-               }
-
-               buf_ctrl->type = mfc_ctrl_list[i].type;
-               buf_ctrl->id = mfc_ctrl_list[i].id;
-               buf_ctrl->is_volatile = mfc_ctrl_list[i].is_volatile;
-               buf_ctrl->mode = mfc_ctrl_list[i].mode;
-               buf_ctrl->addr = mfc_ctrl_list[i].addr;
-               buf_ctrl->mask = mfc_ctrl_list[i].mask;
-               buf_ctrl->shft = mfc_ctrl_list[i].shft;
-               buf_ctrl->flag_mode = mfc_ctrl_list[i].flag_mode;
-               buf_ctrl->flag_addr = mfc_ctrl_list[i].flag_addr;
-               buf_ctrl->flag_shft = mfc_ctrl_list[i].flag_shft;
-               if (buf_ctrl->mode == MFC_CTRL_MODE_CST) {
-                       buf_ctrl->read_cst = mfc_ctrl_list[i].read_cst;
-                       buf_ctrl->write_cst = mfc_ctrl_list[i].write_cst;
-               }
-
-               list_add_tail(&buf_ctrl->list, head);
-       }
-
-       mfc_enc_reset_buf_ctrls(head);
-
-       if (type & MFC_CTRL_TYPE_SRC)
-               set_bit(index, &ctx->src_ctrls_avail);
-       else
-               set_bit(index, &ctx->dst_ctrls_avail);
-
-       return 0;
-}
-
-static int mfc_enc_cleanup_buf_ctrls(struct mfc_ctx *ctx,
-       enum mfc_ctrl_type type, unsigned int index)
-{
-       struct list_head *head;
-
-       if (index >= MFC_MAX_BUFFERS) {
-               mfc_err_dev("Per-buffer control index is out of range\n");
-               return -EINVAL;
-       }
-
-       if (type & MFC_CTRL_TYPE_SRC) {
-               if (!(test_and_clear_bit(index, &ctx->src_ctrls_avail))) {
-                       return 0;
-               }
-
-               head = &ctx->src_ctrls[index];
-       } else if (type & MFC_CTRL_TYPE_DST) {
-               if (!(test_and_clear_bit(index, &ctx->dst_ctrls_avail))) {
-                       return 0;
-               }
-
-               head = &ctx->dst_ctrls[index];
-       } else {
-               mfc_err_dev("Control type mismatch. type : %d\n", type);
-               return -EINVAL;
-       }
-
-       __mfc_enc_remove_buf_ctrls(head);
-
-       return 0;
-}
-
-static int mfc_enc_to_buf_ctrls(struct mfc_ctx *ctx, struct list_head *head)
-{
-       struct mfc_ctx_ctrl *ctx_ctrl;
-       struct mfc_buf_ctrl *buf_ctrl;
-       struct mfc_enc *enc = ctx->enc_priv;
-       int index = 0;
-       unsigned int reg = 0;
-
-       list_for_each_entry(ctx_ctrl, &ctx->ctrls, list) {
-               if (!(ctx_ctrl->type & MFC_CTRL_TYPE_SET) || !ctx_ctrl->has_new)
-                       continue;
-
-               list_for_each_entry(buf_ctrl, head, list) {
-                       if (!(buf_ctrl->type & MFC_CTRL_TYPE_SET))
-                               continue;
-
-                       if (buf_ctrl->id == ctx_ctrl->id) {
-                               buf_ctrl->has_new = 1;
-                               buf_ctrl->val = ctx_ctrl->val;
-                               if (buf_ctrl->is_volatile)
-                                       buf_ctrl->updated = 0;
-
-                               ctx_ctrl->has_new = 0;
-                               if (buf_ctrl->id == V4L2_CID_MPEG_VIDEO_ROI_CONTROL) {
-                                       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);
-                                               mfc_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_debug(3, "[ROI] buffer[%d] is not enabled\n", index);
-                                       }
-                                       buf_ctrl->val = reg;
-                                       buf_ctrl->old_val2 = index;
-                               }
-                               break;
-                       }
-               }
-       }
-
-       return 0;
-}
-
-static int mfc_enc_to_ctx_ctrls(struct mfc_ctx *ctx, struct list_head *head)
-{
-       struct mfc_ctx_ctrl *ctx_ctrl;
-       struct mfc_buf_ctrl *buf_ctrl;
-
-       list_for_each_entry(buf_ctrl, head, list) {
-               if (!(buf_ctrl->type & MFC_CTRL_TYPE_GET) || !buf_ctrl->has_new)
-                       continue;
-
-               list_for_each_entry(ctx_ctrl, &ctx->ctrls, list) {
-                       if (!(ctx_ctrl->type & MFC_CTRL_TYPE_GET))
-                               continue;
-
-                       if (ctx_ctrl->id == buf_ctrl->id) {
-                               if (ctx_ctrl->has_new)
-                                       mfc_debug(8,
-                                       "Overwrite context control "\
-                                       "value id: 0x%08x, val: %d\n",
-                                               ctx_ctrl->id, ctx_ctrl->val);
-
-                               ctx_ctrl->has_new = 1;
-                               ctx_ctrl->val = buf_ctrl->val;
-
-                               buf_ctrl->has_new = 0;
-                       }
-               }
-       }
-
-       return 0;
-}
-
-static void __mfc_enc_set_buf_ctrls_temporal_svc(struct mfc_ctx *ctx,
-                       struct mfc_buf_ctrl *buf_ctrl)
-{
-       struct mfc_dev *dev = ctx->dev;
-       struct mfc_enc *enc = ctx->enc_priv;
-       unsigned int value = 0, value2 = 0;
-       struct temporal_layer_info temporal_LC;
-       unsigned int i;
-       struct mfc_enc_params *p = &enc->params;
-
-       if (buf_ctrl->id
-               == V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_CH ||
-               buf_ctrl->id
-               == V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_CH ||
-               buf_ctrl->id
-               == V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_CH ||
-               buf_ctrl->id
-               == V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_CH) {
-               memcpy(&temporal_LC,
-                       enc->sh_handle_svc.vaddr, sizeof(struct temporal_layer_info));
-
-               if(((temporal_LC.temporal_layer_count & 0x7) < 1) ||
-                       ((temporal_LC.temporal_layer_count > 3) && IS_VP8_ENC(ctx)) ||
-                       ((temporal_LC.temporal_layer_count > 3) && IS_VP9_ENC(ctx))) {
-                       /* clear NUM_T_LAYER_CHANGE */
-                       value = MFC_READL(buf_ctrl->flag_addr);
-                       value &= ~(1 << 10);
-                       MFC_WRITEL(value, buf_ctrl->flag_addr);
-                       mfc_err_ctx("[HIERARCHICAL] layer count is invalid : %d\n",
-                                       temporal_LC.temporal_layer_count);
-                       return;
-               }
-
-               if (IS_H264_ENC(ctx))
-                       p->codec.h264.num_hier_layer = temporal_LC.temporal_layer_count & 0x7;
-
-               /* enable RC_BIT_RATE_CHANGE */
-               value = MFC_READL(buf_ctrl->flag_addr);
-               if (temporal_LC.temporal_layer_bitrate[0] > 0 || p->hier_bitrate_ctrl)
-                       /* set RC_BIT_RATE_CHANGE */
-                       value |= (1 << 2);
-               else
-                       /* clear RC_BIT_RATE_CHANGE */
-                       value &= ~(1 << 2);
-               MFC_WRITEL(value, buf_ctrl->flag_addr);
-
-               mfc_debug(3, "[HIERARCHICAL] layer count %d, E_PARAM_CHANGE %#x\n",
-                               temporal_LC.temporal_layer_count & 0x7, value);
-
-               value = MFC_READL(MFC_REG_E_NUM_T_LAYER);
-               buf_ctrl->old_val2 = value;
-               value &= ~(0x7);
-               value |= (temporal_LC.temporal_layer_count & 0x7);
-               value &= ~(0x1 << 8);
-               value |= (p->hier_bitrate_ctrl & 0x1) << 8;
-               MFC_WRITEL(value, MFC_REG_E_NUM_T_LAYER);
-               mfc_debug(3, "[HIERARCHICAL] E_NUM_T_LAYER %#x\n", value);
-               for (i = 0; i < (temporal_LC.temporal_layer_count & 0x7); i++) {
-                       mfc_debug(3, "[HIERARCHICAL] layer bitrate[%d] %d (FW ctrl: %d)\n",
-                                       i, temporal_LC.temporal_layer_bitrate[i], p->hier_bitrate_ctrl);
-                       MFC_WRITEL(temporal_LC.temporal_layer_bitrate[i],
-                                       buf_ctrl->addr + i * 4);
-               }
-               /* priority change */
-               if (IS_H264_ENC(ctx)) {
-                       value = 0;
-                       value2 = 0;
-                       for (i = 0; i < (p->codec.h264.num_hier_layer & 0x07); i++) {
-                               if (i <= 4)
-                                       value |= ((p->codec.h264.base_priority & 0x3F) + i)
-                                               << (6 * i);
-                               else
-                                       value2 |= ((p->codec.h264.base_priority & 0x3F) + i)
-                                               << (6 * (i - 5));
-                       }
-                       MFC_WRITEL(value, MFC_REG_E_H264_HD_SVC_EXTENSION_0);
-                       MFC_WRITEL(value2, MFC_REG_E_H264_HD_SVC_EXTENSION_1);
-                       mfc_debug(3, "[HIERARCHICAL] EXTENSION0 %#x, EXTENSION1 %#x\n",
-                                       value, value2);
-
-                       value = MFC_READL(buf_ctrl->flag_addr);
-                       value |= (1 << 12);
-                       MFC_WRITEL(value, buf_ctrl->flag_addr);
-                       mfc_debug(3, "[HIERARCHICAL] E_PARAM_CHANGE %#x\n", value);
-               }
-
-       }
-
-       /* temproral layer priority */
-       if (buf_ctrl->id == V4L2_CID_MPEG_MFC_H264_BASE_PRIORITY) {
-               value = MFC_READL(MFC_REG_E_H264_HD_SVC_EXTENSION_0);
-               buf_ctrl->old_val |= value & 0x3FFFFFC0;
-               value &= ~(0x3FFFFFC0);
-               value2 = MFC_READL(MFC_REG_E_H264_HD_SVC_EXTENSION_1);
-               buf_ctrl->old_val2 = value2 & 0x0FFF;
-               value2 &= ~(0x0FFF);
-               for (i = 0; i < (p->codec.h264.num_hier_layer & 0x07); i++) {
-                       if (i <= 4)
-                               value |= ((buf_ctrl->val & 0x3F) + i) << (6 * i);
-                       else
-                               value2 |= ((buf_ctrl->val & 0x3F) + i) << (6 * (i - 5));
-               }
-               MFC_WRITEL(value, MFC_REG_E_H264_HD_SVC_EXTENSION_0);
-               MFC_WRITEL(value2, MFC_REG_E_H264_HD_SVC_EXTENSION_1);
-               p->codec.h264.base_priority = buf_ctrl->val;
-               mfc_debug(3, "[HIERARCHICAL] EXTENSION0 %#x, EXTENSION1 %#x\n",
-                               value, value2);
-       }
-}
-
-static void __mfc_enc_set_buf_ctrls_exception(struct mfc_ctx *ctx,
-                       struct mfc_buf_ctrl *buf_ctrl)
-{
-       struct mfc_dev *dev = ctx->dev;
-       struct mfc_enc *enc = ctx->enc_priv;
-       struct mfc_enc_params *p = &enc->params;
-       unsigned int value = 0;
-
-       if (buf_ctrl->id == V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG)
-               enc->stored_tag = buf_ctrl->val;
-
-       /* temporal layer setting */
-       __mfc_enc_set_buf_ctrls_temporal_svc(ctx, buf_ctrl);
-
-       if (buf_ctrl->id == V4L2_CID_MPEG_MFC_H264_MARK_LTR) {
-               value = MFC_READL(MFC_REG_E_H264_NAL_CONTROL);
-               buf_ctrl->old_val2 = (value >> 8) & 0x7;
-               value &= ~(0x7 << 8);
-               value |= (buf_ctrl->val & 0x7) << 8;
-               MFC_WRITEL(value, MFC_REG_E_H264_NAL_CONTROL);
-       }
-       if (buf_ctrl->id == V4L2_CID_MPEG_MFC_H264_USE_LTR) {
-               value = MFC_READL(MFC_REG_E_H264_NAL_CONTROL);
-               buf_ctrl->old_val2 = (value >> 11) & 0xF;
-               value &= ~(0xF << 11);
-               value |= (buf_ctrl->val & 0xF) << 11;
-               MFC_WRITEL(value, MFC_REG_E_H264_NAL_CONTROL);
-       }
-
-       if (buf_ctrl->id == V4L2_CID_MPEG_MFC51_VIDEO_I_PERIOD_CH) {
-               value = MFC_READL(MFC_REG_E_GOP_CONFIG2);
-               buf_ctrl->old_val |= (value << 16) & 0x3FFF0000;
-               value &= ~(0x3FFF);
-               value |= (buf_ctrl->val >> 16) & 0x3FFF;
-               MFC_WRITEL(value, MFC_REG_E_GOP_CONFIG2);
-       }
-
-       /* PROFILE & LEVEL have to be set up together */
-       if (buf_ctrl->id == V4L2_CID_MPEG_VIDEO_H264_LEVEL) {
-               value = MFC_READL(MFC_REG_E_PICTURE_PROFILE);
-               buf_ctrl->old_val |= (value & 0x000F) << 8;
-               value &= ~(0x000F);
-               value |= p->codec.h264.profile & 0x000F;
-               MFC_WRITEL(value, MFC_REG_E_PICTURE_PROFILE);
-               p->codec.h264.level = buf_ctrl->val;
-       }
-
-       if (buf_ctrl->id == V4L2_CID_MPEG_VIDEO_H264_PROFILE) {
-               value = MFC_READL(MFC_REG_E_PICTURE_PROFILE);
-               buf_ctrl->old_val |= value & 0xFF00;
-               value &= ~(0x00FF << 8);
-               value |= (p->codec.h264.level << 8) & 0xFF00;
-               MFC_WRITEL(value, MFC_REG_E_PICTURE_PROFILE);
-               p->codec.h264.profile = buf_ctrl->val;
-       }
-
-       /* per buffer QP setting change */
-       if (buf_ctrl->id == V4L2_CID_MPEG_MFC_CONFIG_QP)
-               p->config_qp = buf_ctrl->val;
-
-       /* set the ROI buffer DVA */
-       if (buf_ctrl->id == V4L2_CID_MPEG_VIDEO_ROI_CONTROL) {
-               MFC_WRITEL(enc->roi_buf[buf_ctrl->old_val2].daddr,
-                               MFC_REG_E_ROI_BUFFER_ADDR);
-               mfc_debug(3, "[ROI] buffer[%d] addr %#llx, QP val: %#x\n",
-                               buf_ctrl->old_val2,
-                               enc->roi_buf[buf_ctrl->old_val2].daddr,
-                               buf_ctrl->val);
-       }
-}
-
-static int mfc_enc_set_buf_ctrls_val(struct mfc_ctx *ctx, struct list_head *head)
-{
-       struct mfc_buf_ctrl *buf_ctrl;
-       struct mfc_dev *dev = ctx->dev;
-       struct mfc_enc *enc = ctx->enc_priv;
-       unsigned int value = 0;
-       struct mfc_enc_params *p = &enc->params;
-
-       list_for_each_entry(buf_ctrl, head, list) {
-               if (!(buf_ctrl->type & MFC_CTRL_TYPE_SET) || !buf_ctrl->has_new)
-                       continue;
-
-               /* read old vlaue */
-               value = MFC_READL(buf_ctrl->addr);
-
-               /* save old value for recovery */
-               if (buf_ctrl->is_volatile)
-                       buf_ctrl->old_val = (value >> buf_ctrl->shft) & buf_ctrl->mask;
-
-               /* write new value */
-               value &= ~(buf_ctrl->mask << buf_ctrl->shft);
-               value |= ((buf_ctrl->val & buf_ctrl->mask) << buf_ctrl->shft);
-               MFC_WRITEL(value, buf_ctrl->addr);
-
-               /* set change flag bit */
-               if (buf_ctrl->flag_mode == MFC_CTRL_MODE_SFR) {
-                       value = MFC_READL(buf_ctrl->flag_addr);
-                       value |= (1 << buf_ctrl->flag_shft);
-                       MFC_WRITEL(value, buf_ctrl->flag_addr);
-               }
-
-               buf_ctrl->has_new = 0;
-               buf_ctrl->updated = 1;
-
-               __mfc_enc_set_buf_ctrls_exception(ctx, buf_ctrl);
-
-               mfc_debug(6, "[CTRLS] Set buffer control id: 0x%08x, val: %d\n",
-                               buf_ctrl->id, buf_ctrl->val);
-       }
-
-       if (!p->rc_frame && !p->rc_mb && p->dynamic_qp) {
-               value = MFC_READL(MFC_REG_E_FIXED_PICTURE_QP);
-               value &= ~(0xFF000000);
-               value |= (p->config_qp & 0xFF) << 24;
-               MFC_WRITEL(value, MFC_REG_E_FIXED_PICTURE_QP);
-               mfc_debug(6, "[CTRLS] Dynamic QP changed %#x\n",
-                               MFC_READL(MFC_REG_E_FIXED_PICTURE_QP));
-       }
-
-       return 0;
-}
-
-static int mfc_enc_get_buf_ctrls_val(struct mfc_ctx *ctx, struct list_head *head)
-{
-       struct mfc_buf_ctrl *buf_ctrl;
-       struct mfc_dev *dev = ctx->dev;
-       unsigned int value = 0;
-
-       list_for_each_entry(buf_ctrl, head, list) {
-               if (!(buf_ctrl->type & MFC_CTRL_TYPE_GET))
-                       continue;
-
-               if (buf_ctrl->mode == MFC_CTRL_MODE_SFR)
-                       value = MFC_READL(buf_ctrl->addr);
-               else if (buf_ctrl->mode == MFC_CTRL_MODE_CST)
-                       value = call_bop(buf_ctrl, read_cst, ctx, buf_ctrl);
-
-               value = (value >> buf_ctrl->shft) & buf_ctrl->mask;
-
-               buf_ctrl->val = value;
-               buf_ctrl->has_new = 1;
-
-               mfc_debug(6, "[CTRLS] Get buffer control id: 0x%08x, val: %d\n",
-                               buf_ctrl->id, buf_ctrl->val);
-       }
-
-       return 0;
-}
-
-static int mfc_enc_set_buf_ctrls_val_nal_q_enc(struct mfc_ctx *ctx,
-                       struct list_head *head, EncoderInputStr *pInStr)
-{
-       struct mfc_buf_ctrl *buf_ctrl;
-       struct mfc_enc *enc = ctx->enc_priv;
-       struct temporal_layer_info temporal_LC;
-       unsigned int i, param_change;
-       struct mfc_enc_params *p = &enc->params;
-
-       mfc_debug_enter();
-
-       list_for_each_entry(buf_ctrl, head, list) {
-               if (!(buf_ctrl->type & MFC_CTRL_TYPE_SET) || !buf_ctrl->has_new)
-                       continue;
-               param_change = 0;
-               switch (buf_ctrl->id) {
-               case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG:
-                       pInStr->PictureTag &= ~(buf_ctrl->mask << buf_ctrl->shft);
-                       pInStr->PictureTag |=
-                               (buf_ctrl->val & buf_ctrl->mask) << buf_ctrl->shft;
-                       enc->stored_tag = buf_ctrl->val;
-                       break;
-               case V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE:
-                       pInStr->FrameInsertion &= ~(buf_ctrl->mask << buf_ctrl->shft);
-                       pInStr->FrameInsertion |=
-                               (buf_ctrl->val & buf_ctrl->mask) << buf_ctrl->shft;
-                       break;
-               case V4L2_CID_MPEG_MFC51_VIDEO_I_PERIOD_CH:
-                       pInStr->GopConfig &= ~(buf_ctrl->mask << buf_ctrl->shft);
-                       pInStr->GopConfig |=
-                               (buf_ctrl->val & buf_ctrl->mask) << buf_ctrl->shft;
-                       pInStr->GopConfig2 &= ~(0x3FFF);
-                       pInStr->GopConfig2 |= (buf_ctrl->val >> 16) & 0x3FFF;
-                       param_change = 1;
-                       break;
-               case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_RATE_CH:
-                       pInStr->RcFrameRate &= ~(buf_ctrl->mask << buf_ctrl->shft);
-                       pInStr->RcFrameRate |=
-                               (buf_ctrl->val & buf_ctrl->mask) << buf_ctrl->shft;
-                       param_change = 1;
-                       break;
-               case V4L2_CID_MPEG_MFC51_VIDEO_BIT_RATE_CH:
-                       pInStr->RcBitRate &= ~(buf_ctrl->mask << buf_ctrl->shft);
-                       pInStr->RcBitRate |=
-                               (buf_ctrl->val & buf_ctrl->mask) << buf_ctrl->shft;
-                       param_change = 1;
-                       break;
-               case V4L2_CID_MPEG_VIDEO_H264_MAX_QP:
-               case V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP:
-               case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP:
-               case V4L2_CID_MPEG_VIDEO_H263_MAX_QP:
-               case V4L2_CID_MPEG_VIDEO_VP8_MAX_QP:
-               case V4L2_CID_MPEG_VIDEO_VP9_MAX_QP:
-               case V4L2_CID_MPEG_VIDEO_H264_MIN_QP:
-               case V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP:
-               case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP:
-               case V4L2_CID_MPEG_VIDEO_H263_MIN_QP:
-               case V4L2_CID_MPEG_VIDEO_VP8_MIN_QP:
-               case V4L2_CID_MPEG_VIDEO_VP9_MIN_QP:
-                       pInStr->RcQpBound &= ~(buf_ctrl->mask << buf_ctrl->shft);
-                       pInStr->RcQpBound |=
-                               (buf_ctrl->val & buf_ctrl->mask) << buf_ctrl->shft;
-                       param_change = 1;
-                       break;
-               case V4L2_CID_MPEG_VIDEO_H264_MAX_QP_P:
-               case V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP_P:
-               case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP_P:
-               case V4L2_CID_MPEG_VIDEO_H263_MAX_QP_P:
-               case V4L2_CID_MPEG_VIDEO_VP8_MAX_QP_P:
-               case V4L2_CID_MPEG_VIDEO_VP9_MAX_QP_P:
-               case V4L2_CID_MPEG_VIDEO_H264_MIN_QP_P:
-               case V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP_P:
-               case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP_P:
-               case V4L2_CID_MPEG_VIDEO_H263_MIN_QP_P:
-               case V4L2_CID_MPEG_VIDEO_VP8_MIN_QP_P:
-               case V4L2_CID_MPEG_VIDEO_VP9_MIN_QP_P:
-               case V4L2_CID_MPEG_VIDEO_H264_MAX_QP_B:
-               case V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP_B:
-               case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP_B:
-               case V4L2_CID_MPEG_VIDEO_H264_MIN_QP_B:
-               case V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP_B:
-               case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP_B:
-                       pInStr->RcQpBoundPb &= ~(buf_ctrl->mask << buf_ctrl->shft);
-                       pInStr->RcQpBoundPb |=
-                               (buf_ctrl->val & buf_ctrl->mask) << buf_ctrl->shft;
-                       param_change = 1;
-                       break;
-               case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_CH:
-               case V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_CH:
-               case V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_CH:
-               case V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_CH:
-                       memcpy(&temporal_LC,
-                               enc->sh_handle_svc.vaddr, sizeof(struct temporal_layer_info));
-
-                       if (((temporal_LC.temporal_layer_count & 0x7) < 1) ||
-                               ((temporal_LC.temporal_layer_count > 3) && IS_VP8_ENC(ctx)) ||
-                               ((temporal_LC.temporal_layer_count > 3) && IS_VP9_ENC(ctx))) {
-                               /* claer NUM_T_LAYER_CHANGE */
-                               mfc_err_ctx("[NALQ][HIERARCHICAL] layer count(%d) is invalid\n",
-                                               temporal_LC.temporal_layer_count);
-                               return 0;
-                       }
-
-                       if (IS_H264_ENC(ctx))
-                               p->codec.h264.num_hier_layer =
-                                       temporal_LC.temporal_layer_count & 0x7;
-
-                       /* enable RC_BIT_RATE_CHANGE */
-                       if (temporal_LC.temporal_layer_bitrate[0] > 0 || p->hier_bitrate_ctrl)
-                               pInStr->ParamChange |= (1 << 2);
-                       else
-                               pInStr->ParamChange &= ~(1 << 2);
-
-                       /* enalbe NUM_T_LAYER_CHANGE */
-                       if (temporal_LC.temporal_layer_count & 0x7)
-                               pInStr->ParamChange |= (1 << 10);
-                       else
-                               pInStr->ParamChange &= ~(1 << 10);
-                       mfc_debug(3, "[NALQ][HIERARCHICAL] layer count %d\n",
-                                       temporal_LC.temporal_layer_count & 0x7);
-
-                       pInStr->NumTLayer &= ~(0x7);
-                       pInStr->NumTLayer |= (temporal_LC.temporal_layer_count & 0x7);
-                       pInStr->NumTLayer &= ~(0x1 << 8);
-                       pInStr->NumTLayer |= (p->hier_bitrate_ctrl & 0x1) << 8;
-                       for (i = 0; i < (temporal_LC.temporal_layer_count & 0x7); i++) {
-                               mfc_debug(3, "[NALQ][HIERARCHICAL] layer bitrate[%d] %d (FW ctrl: %d)\n",
-                                       i, temporal_LC.temporal_layer_bitrate[i], p->hier_bitrate_ctrl);
-                               pInStr->HierarchicalBitRateLayer[i] =
-                                       temporal_LC.temporal_layer_bitrate[i];
-                       }
-
-                       /* priority change */
-                       if (IS_H264_ENC(ctx)) {
-                               for (i = 0; i < (temporal_LC.temporal_layer_count & 0x7); i++) {
-                                       if (i <= 4)
-                                               pInStr->H264HDSvcExtension0 |=
-                                                       ((p->codec.h264.base_priority & 0x3f) + i) << (6 * i);
-                                       else
-                                               pInStr->H264HDSvcExtension1 |=
-                                                       ((p->codec.h264.base_priority & 0x3f) + i) << (6 * (i - 5));
-                               }
-                               mfc_debug(3, "[NALQ][HIERARCHICAL] EXTENSION0 %#x, EXTENSION1 %#x\n",
-                                               pInStr->H264HDSvcExtension0, pInStr->H264HDSvcExtension1);
-
-                               pInStr->ParamChange |= (1 << 12);
-                       }
-                       break;
-               case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
-                       pInStr->PictureProfile &= ~(buf_ctrl->mask << buf_ctrl->shft);
-                       pInStr->PictureProfile |=
-                               (buf_ctrl->val & buf_ctrl->mask) << buf_ctrl->shft;
-                       pInStr->PictureProfile &= ~(0xf);
-                       pInStr->PictureProfile |= p->codec.h264.profile & 0xf;
-                       p->codec.h264.level = buf_ctrl->val;
-                       param_change = 1;
-                       break;
-               case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
-                       pInStr->PictureProfile &= ~(buf_ctrl->mask << buf_ctrl->shft);
-                       pInStr->PictureProfile |=
-                               (buf_ctrl->val & buf_ctrl->mask) << buf_ctrl->shft;
-                       pInStr->PictureProfile &= ~(0xff << 8);
-                       pInStr->PictureProfile |= (p->codec.h264.level << 8) & 0xff00;
-                       p->codec.h264.profile = buf_ctrl->val;
-                       param_change = 1;
-                       break;
-               case V4L2_CID_MPEG_MFC_H264_MARK_LTR:
-                       pInStr->H264NalControl &= ~(buf_ctrl->mask << buf_ctrl->shft);
-                       pInStr->H264NalControl |=
-                               (buf_ctrl->val & buf_ctrl->mask) << buf_ctrl->shft;
-                       pInStr->H264NalControl &= ~(0x7 << 8);
-                       pInStr->H264NalControl |= (buf_ctrl->val & 0x7) << 8;
-                       break;
-               case V4L2_CID_MPEG_MFC_H264_USE_LTR:
-                       pInStr->H264NalControl &= ~(buf_ctrl->mask << buf_ctrl->shft);
-                       pInStr->H264NalControl |=
-                               (buf_ctrl->val & buf_ctrl->mask) << buf_ctrl->shft;
-                       pInStr->H264NalControl &= ~(0xF << 11);
-                       pInStr->H264NalControl |= (buf_ctrl->val & 0xF) << 11;
-                       break;
-               case V4L2_CID_MPEG_MFC_H264_BASE_PRIORITY:
-                       for (i = 0; i < (p->codec.h264.num_hier_layer & 0x7); i++)
-                               if (i <= 4)
-                                       pInStr->H264HDSvcExtension0 |=
-                                               ((buf_ctrl->val & 0x3f) + i) << (6 * i);
-                               else
-                                       pInStr->H264HDSvcExtension1 |=
-                                               ((buf_ctrl->val & 0x3f) + i) << (6 * (i - 5));
-                       p->codec.h264.base_priority = buf_ctrl->val;
-                       param_change = 1;
-                       break;
-               case V4L2_CID_MPEG_MFC_CONFIG_QP:
-                       pInStr->FixedPictureQp &= ~(buf_ctrl->mask << buf_ctrl->shft);
-                       pInStr->FixedPictureQp |=
-                               (buf_ctrl->val & buf_ctrl->mask) << buf_ctrl->shft;
-                       p->config_qp = buf_ctrl->val;
-                       break;
-               case V4L2_CID_MPEG_VIDEO_ROI_CONTROL:
-                       pInStr->RcRoiCtrl &= ~(buf_ctrl->mask << buf_ctrl->shft);
-                       pInStr->RcRoiCtrl |=
-                               (buf_ctrl->val & buf_ctrl->mask) << buf_ctrl->shft;
-                       pInStr->RoiBufferAddr = enc->roi_buf[buf_ctrl->old_val2].daddr;
-                       mfc_debug(3, "[NALQ][ROI] buffer[%d] addr %#llx, QP val: %#x\n",
-                                       buf_ctrl->old_val2,
-                                       enc->roi_buf[buf_ctrl->old_val2].daddr,
-                                       buf_ctrl->val);
-                       break;
-               case V4L2_CID_MPEG_VIDEO_YSUM:
-                       pInStr->Weight &= ~(buf_ctrl->mask << buf_ctrl->shft);
-                       pInStr->Weight |=
-                               (buf_ctrl->val & buf_ctrl->mask) << buf_ctrl->shft;
-                       break;
-               case V4L2_CID_MPEG_VIDEO_RATIO_OF_INTRA:
-                       pInStr->RcMode &= ~(buf_ctrl->mask << buf_ctrl->shft);
-                       pInStr->RcMode |=
-                               (buf_ctrl->val & buf_ctrl->mask) << buf_ctrl->shft;
-                       param_change = 1;
-                       break;
-               /* If new dynamic controls are added, insert here */
-               default:
-                       mfc_info_ctx("[NALQ] can't find control, id: 0x%x\n",
-                                       buf_ctrl->id);
-               }
-
-               if (param_change)
-                       pInStr->ParamChange |= (1 << buf_ctrl->flag_shft);
-
-               buf_ctrl->has_new = 0;
-               buf_ctrl->updated = 1;
-
-               mfc_debug(6, "[NALQ][CTRLS] Set buffer control id: 0x%08x, val: %d\n",
-                               buf_ctrl->id, buf_ctrl->val);
-       }
-
-       if (!p->rc_frame && !p->rc_mb && p->dynamic_qp) {
-               pInStr->FixedPictureQp &= ~(0xFF000000);
-               pInStr->FixedPictureQp |= (p->config_qp & 0xFF) << 24;
-               mfc_debug(6, "[NALQ][CTRLS] Dynamic QP changed %#x\n",
-                               pInStr->FixedPictureQp);
-       }
-
-       mfc_debug_leave();
-
-       return 0;
-}
-
-static int mfc_enc_get_buf_ctrls_val_nal_q_enc(struct mfc_ctx *ctx,
-                       struct list_head *head, EncoderOutputStr *pOutStr)
-{
-       struct mfc_buf_ctrl *buf_ctrl;
-       struct mfc_enc *enc = ctx->enc_priv;
-       unsigned int value = 0;
-
-       mfc_debug_enter();
-
-       list_for_each_entry(buf_ctrl, head, list) {
-               if (!(buf_ctrl->type & MFC_CTRL_TYPE_GET))
-                       continue;
-               switch (buf_ctrl->id) {
-               case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG:
-                       value = pOutStr->PictureTag;
-                       break;
-               case V4L2_CID_MPEG_MFC51_VIDEO_LUMA_ADDR:
-                       value = pOutStr->EncodedFrameAddr[0];
-                       break;
-               case V4L2_CID_MPEG_MFC51_VIDEO_CHROMA_ADDR:
-                       value = pOutStr->EncodedFrameAddr[1];
-                       break;
-               case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_STATUS:
-                       value = !enc->in_slice;
-                       break;
-               /* If new dynamic controls are added, insert here */
-               default:
-                       mfc_info_ctx("[NALQ] can't find control, id: 0x%x\n",
-                                       buf_ctrl->id);
-               }
-               value = (value >> buf_ctrl->shft) & buf_ctrl->mask;
-
-               buf_ctrl->val = value;
-               buf_ctrl->has_new = 1;
-
-               mfc_debug(6, "[NALQ][CTRLS] Get buffer control id: 0x%08x, val: %d\n",
-                               buf_ctrl->id, buf_ctrl->val);
-       }
-
-       mfc_debug_leave();
-
-       return 0;
-}
-
-static int mfc_enc_recover_buf_ctrls_val(struct mfc_ctx *ctx,
-                                               struct list_head *head)
-{
-       struct mfc_buf_ctrl *buf_ctrl;
-       struct mfc_dev *dev = ctx->dev;
-       unsigned int value = 0;
-
-       list_for_each_entry(buf_ctrl, head, list) {
-               if (!(buf_ctrl->type & MFC_CTRL_TYPE_SET)
-                       || !buf_ctrl->is_volatile
-                       || !buf_ctrl->updated)
-                       continue;
-
-               if (buf_ctrl->mode == MFC_CTRL_MODE_SFR)
-                       value = MFC_READL(buf_ctrl->addr);
-
-               value &= ~(buf_ctrl->mask << buf_ctrl->shft);
-               value |= ((buf_ctrl->old_val & buf_ctrl->mask)
-                                                       << buf_ctrl->shft);
-
-               if (buf_ctrl->mode == MFC_CTRL_MODE_SFR)
-                       MFC_WRITEL(value, buf_ctrl->addr);
-
-               /* clear change flag bit */
-               if (buf_ctrl->flag_mode == MFC_CTRL_MODE_SFR) {
-                       value = MFC_READL(buf_ctrl->flag_addr);
-                       value &= ~(1 << buf_ctrl->flag_shft);
-                       MFC_WRITEL(value, buf_ctrl->flag_addr);
-               }
-
-               mfc_debug(6, "[CTRLS] Recover buffer control id: 0x%08x, old val: %d\n",
-                               buf_ctrl->id, buf_ctrl->old_val);
-
-               if (buf_ctrl->id == V4L2_CID_MPEG_MFC51_VIDEO_I_PERIOD_CH) {
-                       value = MFC_READL(MFC_REG_E_GOP_CONFIG2);
-                       value &= ~(0x3FFF);
-                       value |= (buf_ctrl->old_val >> 16) & 0x3FFF;
-                       MFC_WRITEL(value, MFC_REG_E_GOP_CONFIG2);
-               }
-               if (buf_ctrl->id == V4L2_CID_MPEG_VIDEO_H264_LEVEL) {
-                       value = MFC_READL(MFC_REG_E_PICTURE_PROFILE);
-                       value &= ~(0x000F);
-                       value |= (buf_ctrl->old_val >> 8) & 0x000F;
-                       MFC_WRITEL(value, MFC_REG_E_PICTURE_PROFILE);
-               }
-               if (buf_ctrl->id == V4L2_CID_MPEG_VIDEO_H264_PROFILE) {
-                       value = MFC_READL(MFC_REG_E_PICTURE_PROFILE);
-                       value &= ~(0xFF00);
-                       value |= buf_ctrl->old_val & 0xFF00;
-                       MFC_WRITEL(value, MFC_REG_E_PICTURE_PROFILE);
-               }
-               if (buf_ctrl->id == V4L2_CID_MPEG_MFC_H264_BASE_PRIORITY) {
-                       MFC_WRITEL(buf_ctrl->old_val, MFC_REG_E_H264_HD_SVC_EXTENSION_0);
-                       MFC_WRITEL(buf_ctrl->old_val2, MFC_REG_E_H264_HD_SVC_EXTENSION_1);
-               }
-               if (buf_ctrl->id
-                       == V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_CH ||
-                       buf_ctrl->id
-                       == V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_CH ||
-                       buf_ctrl->id
-                       == V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_CH) {
-                       MFC_WRITEL(buf_ctrl->old_val2, MFC_REG_E_NUM_T_LAYER);
-                       /* clear RC_BIT_RATE_CHANGE */
-                       value = MFC_READL(buf_ctrl->flag_addr);
-                       value &= ~(1 << 2);
-                       MFC_WRITEL(value, buf_ctrl->flag_addr);
-               }
-               if (buf_ctrl->id == V4L2_CID_MPEG_MFC_H264_MARK_LTR) {
-                       value = MFC_READL(MFC_REG_E_H264_NAL_CONTROL);
-                       value &= ~(0x7 << 8);
-                       value |= (buf_ctrl->old_val2 & 0x7) << 8;
-                       MFC_WRITEL(value, MFC_REG_E_H264_NAL_CONTROL);
-               }
-               if (buf_ctrl->id == V4L2_CID_MPEG_MFC_H264_USE_LTR) {
-                       value = MFC_READL(MFC_REG_E_H264_NAL_CONTROL);
-                       value &= ~(0xF << 11);
-                       value |= (buf_ctrl->old_val2 & 0xF) << 11;
-                       MFC_WRITEL(value, MFC_REG_E_H264_NAL_CONTROL);
-               }
-               buf_ctrl->updated = 0;
-       }
-
-       return 0;
-}
-
-static int mfc_enc_recover_buf_ctrls_nal_q(struct mfc_ctx *ctx,
-               struct list_head *head)
-{
-       struct mfc_buf_ctrl *buf_ctrl;
-
-       list_for_each_entry(buf_ctrl, head, list) {
-               if (!(buf_ctrl->type & MFC_CTRL_TYPE_SET)
-                               || !(buf_ctrl->updated))
-                       continue;
-
-               buf_ctrl->has_new = 1;
-               buf_ctrl->updated = 0;
-
-               mfc_debug(6, "[NALQ][CTRLS] Recover buffer control id: 0x%08x, val: %d\n",
-                               buf_ctrl->id, buf_ctrl->val);
-       }
-
-       return 0;
-}
-
-struct mfc_ctrls_ops encoder_ctrls_ops = {
-       .init_ctx_ctrls                 = mfc_enc_init_ctx_ctrls,
-       .cleanup_ctx_ctrls              = mfc_enc_cleanup_ctx_ctrls,
-       .init_buf_ctrls                 = mfc_enc_init_buf_ctrls,
-       .reset_buf_ctrls                = mfc_enc_reset_buf_ctrls,
-       .cleanup_buf_ctrls              = mfc_enc_cleanup_buf_ctrls,
-       .to_buf_ctrls                   = mfc_enc_to_buf_ctrls,
-       .to_ctx_ctrls                   = mfc_enc_to_ctx_ctrls,
-       .set_buf_ctrls_val              = mfc_enc_set_buf_ctrls_val,
-       .get_buf_ctrls_val              = mfc_enc_get_buf_ctrls_val,
-       .recover_buf_ctrls_val          = mfc_enc_recover_buf_ctrls_val,
-       .get_buf_update_val             = mfc_enc_get_buf_update_val,
-       .set_buf_ctrls_val_nal_q_enc    = mfc_enc_set_buf_ctrls_val_nal_q_enc,
-       .get_buf_ctrls_val_nal_q_enc    = mfc_enc_get_buf_ctrls_val_nal_q_enc,
-       .recover_buf_ctrls_nal_q        = mfc_enc_recover_buf_ctrls_nal_q,
-};
index aaea80deb188310962d12cf8b02c2a02d391fe6a..d037643a5b5307fc9d03efe80490e04a05b45f48 100644 (file)
@@ -12,7 +12,7 @@
 
 #include "mfc_enc_param.h"
 
-#include "mfc_reg.h"
+#include "mfc_reg_api.h"
 
 /* Definition */
 #define FRAME_DELTA_DEFAULT            1
diff --git a/drivers/media/platform/exynos/mfc/mfc_enc_v4l2.c b/drivers/media/platform/exynos/mfc/mfc_enc_v4l2.c
new file mode 100644 (file)
index 0000000..d491a23
--- /dev/null
@@ -0,0 +1,2061 @@
+/*
+ * drivers/media/platform/exynos/mfc/mfc_enc_v4l2.c
+ *
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include "mfc_enc_v4l2.h"
+#include "mfc_enc_internal.h"
+
+#include "mfc_hwlock.h"
+#include "mfc_otf.h"
+#include "mfc_opr.h"
+#include "mfc_sync.h"
+
+#include "mfc_qos.h"
+#include "mfc_queue.h"
+#include "mfc_utils.h"
+#include "mfc_buf.h"
+#include "mfc_mem.h"
+
+static struct mfc_fmt *__mfc_enc_find_format(struct mfc_ctx *ctx,
+               unsigned int pixelformat)
+{
+       struct mfc_dev *dev = ctx->dev;
+       struct mfc_fmt *fmt = NULL;
+       unsigned long i;
+
+       for (i = 0; i < NUM_FORMATS; i++) {
+               if (enc_formats[i].fourcc == pixelformat) {
+                       fmt = (struct mfc_fmt *)&enc_formats[i];
+                       break;
+               }
+       }
+
+       if (!dev->pdata->support_10bit && (fmt->type & MFC_FMT_10BIT)) {
+               mfc_err_ctx("[FRAME] 10bit is not supported\n");
+               fmt = NULL;
+       }
+       if (!dev->pdata->support_422 && (fmt->type & MFC_FMT_422)) {
+               mfc_err_ctx("[FRAME] 422 is not supported\n");
+               fmt = NULL;
+       }
+       if (!dev->pdata->support_rgb && (fmt->type & MFC_FMT_RGB)) {
+               mfc_err_ctx("[FRAME] RGB is not supported\n");
+               fmt = NULL;
+       }
+
+       return fmt;
+}
+
+static struct v4l2_queryctrl *__mfc_enc_get_ctrl(int id)
+{
+       unsigned long i;
+
+       for (i = 0; i < NUM_CTRLS; ++i)
+               if (id == controls[i].id)
+                       return &controls[i];
+       return NULL;
+}
+
+static int __mfc_enc_check_ctrl_val(struct mfc_ctx *ctx, struct v4l2_control *ctrl)
+{
+       struct v4l2_queryctrl *c;
+
+       c = __mfc_enc_get_ctrl(ctrl->id);
+       if (!c) {
+               mfc_err_ctx("[CTRLS] not supported control id (%#x)\n", ctrl->id);
+               return -EINVAL;
+       }
+
+       if (ctrl->id == V4L2_CID_MPEG_VIDEO_GOP_SIZE
+           && ctrl->value > c->maximum) {
+               mfc_info_ctx("GOP_SIZE is changed to max(%d -> %d)\n",
+                                ctrl->value, c->maximum);
+               ctrl->value = c->maximum;
+       }
+
+       if (ctrl->id == V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER) {
+               if ((ctrl->value & ~(1 << 16)) < c->minimum || (ctrl->value & ~(1 << 16)) > c->maximum
+                   || (c->step != 0 && (ctrl->value & ~(1 << 16)) % c->step != 0)) {
+                       mfc_err_ctx("[CTRLS][HIERARCHICAL] Invalid control value for %#x (%#x)\n",
+                                       ctrl->id, ctrl->value);
+                       return -ERANGE;
+               } else {
+                       return 0;
+               }
+       }
+
+       if (ctrl->value < c->minimum || ctrl->value > c->maximum
+           || (c->step != 0 && ctrl->value % c->step != 0)) {
+               mfc_err_ctx("[CTRLS] Invalid control value for %#x (%#x)\n",
+                               ctrl->id, ctrl->value);
+               return -ERANGE;
+       }
+
+       return 0;
+}
+
+static inline int __mfc_enc_h264_profile(struct mfc_ctx *ctx, int profile)
+{
+       int ret = 0;
+
+       switch (profile) {
+       case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
+               ret = MFC_REG_E_PROFILE_H264_MAIN;
+               break;
+       case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
+               ret = MFC_REG_E_PROFILE_H264_HIGH;
+               break;
+       case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
+               ret = MFC_REG_E_PROFILE_H264_BASELINE;
+               break;
+       case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
+               ret = MFC_REG_E_PROFILE_H264_CONSTRAINED_BASELINE;
+               break;
+       case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH:
+               ret = MFC_REG_E_PROFILE_H264_CONSTRAINED_HIGH;
+               break;
+       default:
+               ret = -EINVAL;
+       }
+
+       return ret;
+}
+
+/* Query capabilities of the device */
+static int vidioc_querycap(struct file *file, void *priv,
+                          struct v4l2_capability *cap)
+{
+       strncpy(cap->driver, "MFC", sizeof(cap->driver) - 1);
+       strncpy(cap->card, "encoder", sizeof(cap->card) - 1);
+       cap->bus_info[0] = 0;
+       cap->version = KERNEL_VERSION(1, 0, 0);
+       cap->device_caps = V4L2_CAP_VIDEO_CAPTURE
+                       | V4L2_CAP_VIDEO_OUTPUT
+                       | V4L2_CAP_VIDEO_CAPTURE_MPLANE
+                       | V4L2_CAP_VIDEO_OUTPUT_MPLANE
+                       | V4L2_CAP_STREAMING
+                       | V4L2_CAP_DEVICE_CAPS;
+
+       cap->capabilities = cap->device_caps;
+
+       return 0;
+}
+
+static int __mfc_enc_enum_fmt(struct mfc_dev *dev, struct v4l2_fmtdesc *f,
+               unsigned int type)
+{
+       struct mfc_fmt *fmt;
+       unsigned long i, j = 0;
+
+       for (i = 0; i < NUM_FORMATS; ++i) {
+               if (!(enc_formats[i].type & type))
+                       continue;
+               if (!dev->pdata->support_10bit && (enc_formats[i].type & MFC_FMT_10BIT))
+                       continue;
+               if (!dev->pdata->support_422 && (enc_formats[i].type & MFC_FMT_422))
+                       continue;
+               if (!dev->pdata->support_rgb && (enc_formats[i].type & MFC_FMT_RGB))
+                       continue;
+
+               if (j == f->index) {
+                       fmt = &enc_formats[i];
+                       strlcpy(f->description, fmt->name,
+                               sizeof(f->description));
+                       f->pixelformat = fmt->fourcc;
+
+                       return 0;
+               }
+
+               ++j;
+       }
+
+       return -EINVAL;
+}
+
+static int vidioc_enum_fmt_vid_cap_mplane(struct file *file, void *pirv,
+               struct v4l2_fmtdesc *f)
+{
+       struct mfc_dev *dev = video_drvdata(file);
+
+       return __mfc_enc_enum_fmt(dev, f, MFC_FMT_STREAM);
+}
+
+static int vidioc_enum_fmt_vid_out_mplane(struct file *file, void *prov,
+               struct v4l2_fmtdesc *f)
+{
+       struct mfc_dev *dev = video_drvdata(file);
+
+       return __mfc_enc_enum_fmt(dev, f, MFC_FMT_FRAME);
+}
+
+static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
+{
+       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+       struct mfc_enc *enc = ctx->enc_priv;
+       struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
+       struct mfc_raw_info *raw;
+       int i;
+
+       mfc_debug_enter();
+
+       if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+               mfc_debug(4, "enc dst g_fmt\n");
+               /* This is run on output (encoder dest) */
+               pix_fmt_mp->width = 0;
+               pix_fmt_mp->height = 0;
+               pix_fmt_mp->field = V4L2_FIELD_NONE;
+               pix_fmt_mp->pixelformat = ctx->dst_fmt->fourcc;
+               pix_fmt_mp->num_planes = ctx->dst_fmt->mem_planes;
+
+               pix_fmt_mp->plane_fmt[0].bytesperline = enc->dst_buf_size;
+               pix_fmt_mp->plane_fmt[0].sizeimage = enc->dst_buf_size;
+       } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+               mfc_debug(4, "enc src g_fmt\n");
+               /* This is run on capture (encoder src) */
+               raw = &ctx->raw_buf;
+
+               pix_fmt_mp->width = ctx->img_width;
+               pix_fmt_mp->height = ctx->img_height;
+               pix_fmt_mp->field = V4L2_FIELD_NONE;
+               pix_fmt_mp->pixelformat = ctx->src_fmt->fourcc;
+               pix_fmt_mp->num_planes = ctx->src_fmt->mem_planes;
+               for (i = 0; i < ctx->src_fmt->mem_planes; i++) {
+                       pix_fmt_mp->plane_fmt[i].bytesperline = raw->stride[i];
+                       pix_fmt_mp->plane_fmt[i].sizeimage = raw->plane_size[i];
+               }
+       } else {
+               mfc_err_dev("invalid buf type (%d)\n", f->type);
+               return -EINVAL;
+       }
+
+       mfc_debug_leave();
+
+       return 0;
+}
+
+static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
+{
+       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+       struct mfc_fmt *fmt;
+       struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
+
+       fmt = __mfc_enc_find_format(ctx, pix_fmt_mp->pixelformat);
+       if (!fmt) {
+               mfc_err_dev("Unsupported format for %s\n",
+                               V4L2_TYPE_IS_OUTPUT(f->type) ? "source" : "destination");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static void __mfc_enc_check_format(struct mfc_ctx *ctx)
+{
+       switch (ctx->src_fmt->fourcc) {
+       case V4L2_PIX_FMT_NV16M_S10B:
+       case V4L2_PIX_FMT_NV61M_S10B:
+       case V4L2_PIX_FMT_NV16M_P210:
+       case V4L2_PIX_FMT_NV61M_P210:
+               mfc_debug(2, "[FRAME][10BIT] is 422 and 10bit format\n");
+               ctx->is_10bit = 1;
+               ctx->is_422 = 1;
+               break;
+       case V4L2_PIX_FMT_NV16M:
+       case V4L2_PIX_FMT_NV61M:
+               mfc_debug(2, "[FRAME] is 422 format\n");
+               ctx->is_10bit = 0;
+               ctx->is_422 = 1;
+               break;
+       case V4L2_PIX_FMT_NV12M_S10B:
+       case V4L2_PIX_FMT_NV12M_P010:
+       case V4L2_PIX_FMT_NV21M_S10B:
+       case V4L2_PIX_FMT_NV21M_P010:
+               mfc_debug(2, "[FRAME][10BIT] is 10bit format\n");
+               ctx->is_10bit = 1;
+               ctx->is_422 = 0;
+               break;
+       default:
+               ctx->is_10bit = 0;
+               ctx->is_422 = 0;
+               break;
+       }
+       mfc_debug(2, "[FRAME] 10bit: %d, 422: %d\n", ctx->is_10bit, ctx->is_422);
+}
+
+static int __mfc_enc_check_resolution(struct mfc_ctx *ctx)
+{
+       int max_width = 0, max_height = 0, min_width = 0, min_height = 0, swap_check = 0;
+
+       /* Check max resolution */
+       switch (ctx->codec_mode) {
+       case MFC_REG_CODEC_HEVC_ENC:
+               if (ctx->is_422) {
+                       max_width = 65536;
+                       max_height = 8192;
+                       swap_check = 1;
+               } else {
+                       max_width = 8192;
+                       max_height = 8192;
+               }
+               break;
+       case MFC_REG_CODEC_BPG_ENC:
+               max_width = 65536;
+               max_height = 8192;
+               swap_check = 1;
+               break;
+       case MFC_REG_CODEC_H264_ENC:
+       case MFC_REG_CODEC_VP8_ENC:
+               max_width = 8192;
+               max_height = 8192;
+               break;
+       case MFC_REG_CODEC_VP9_ENC:
+               max_width = 4096;
+               max_height = 8192;
+               break;
+       case MFC_REG_CODEC_MPEG4_ENC:
+               max_width = 2048;
+               max_height = 2048;
+               break;
+       case MFC_REG_CODEC_H263_ENC:
+               max_width = 2048;
+               max_height = 1152;
+               break;
+       default:
+               mfc_err_ctx("Not supported codec(%d)\n", ctx->codec_mode);
+               return -EINVAL;
+       }
+
+       if (swap_check) {
+               if (!((ctx->crop_width < max_width && ctx->crop_height < max_height) ||
+                               (ctx->crop_width < max_height && ctx->crop_height < max_width))) {
+                       mfc_err_ctx("Resolution is too big(%dx%d > %dxi%d or %dx%d\n",
+                                       ctx->crop_width, ctx->crop_height, max_width, max_height,
+                                       max_height, max_width);
+                       return -EINVAL;
+               }
+       } else {
+               if (ctx->crop_width > max_width || ctx->crop_height > max_height) {
+                       mfc_err_ctx("Resolution is too big(%dx%d > %dx%d)\n",
+                                       ctx->crop_width, ctx->crop_height, max_width, max_height);
+                       return -EINVAL;
+               }
+       }
+
+       /* Check min resolution */
+       switch (ctx->codec_mode) {
+       case MFC_REG_CODEC_HEVC_ENC:
+       case MFC_REG_CODEC_BPG_ENC:
+       case MFC_REG_CODEC_VP9_ENC:
+               min_width = 64;
+               min_height = 64;
+               break;
+       case MFC_REG_CODEC_H264_ENC:
+       case MFC_REG_CODEC_VP8_ENC:
+       case MFC_REG_CODEC_MPEG4_ENC:
+       case MFC_REG_CODEC_H263_ENC:
+               min_width = 32;
+               min_height = 32;
+               break;
+       default:
+               mfc_err_ctx("Not supported codec(%d)\n", ctx->codec_mode);
+               return -EINVAL;
+       }
+
+       if (ctx->crop_width < min_width || ctx->crop_height < min_height) {
+               mfc_err_ctx("Resolution is too small(%dx%d < %dx%d)\n",
+                               ctx->crop_width, ctx->crop_height, min_width, min_height);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int vidioc_s_fmt_vid_cap_mplane(struct file *file, void *priv,
+                                                       struct v4l2_format *f)
+{
+       struct mfc_dev *dev = video_drvdata(file);
+       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+       struct mfc_enc *enc = ctx->enc_priv;
+       struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
+       int ret = 0;
+
+       mfc_debug_enter();
+
+       if (ctx->vq_dst.streaming) {
+               mfc_err_ctx("dst queue busy\n");
+               return -EBUSY;
+       }
+
+       ctx->dst_fmt = __mfc_enc_find_format(ctx, pix_fmt_mp->pixelformat);
+       if (!ctx->dst_fmt) {
+               mfc_err_ctx("Unsupported format for destination\n");
+               return -EINVAL;
+       }
+
+       ctx->codec_mode = ctx->dst_fmt->codec_mode;
+       mfc_info_ctx("[STREAM] Enc dst codec(%d) : %s\n",
+                       ctx->codec_mode, ctx->dst_fmt->name);
+
+       if (__mfc_enc_check_resolution(ctx)) {
+               mfc_err_ctx("Unsupported resolution\n");
+               return -EINVAL;
+       }
+
+       if (ctx->otf_handle) {
+               if (ctx->dst_fmt->fourcc != V4L2_PIX_FMT_H264 &&
+                               ctx->dst_fmt->fourcc != V4L2_PIX_FMT_HEVC) {
+                       mfc_err_ctx("[OTF] only H.264 and HEVC is supported\n");
+                       return -EINVAL;
+               }
+               if (mfc_otf_init(ctx)) {
+                       mfc_err_ctx("[OTF] otf_init failed\n");
+                       mfc_otf_destroy(ctx);
+                       return -EINVAL;
+               }
+       }
+
+       enc->dst_buf_size = pix_fmt_mp->plane_fmt[0].sizeimage;
+       pix_fmt_mp->plane_fmt[0].bytesperline = 0;
+
+       ret = mfc_alloc_instance_context(ctx);
+       if (ret) {
+               mfc_err_ctx("Failed to allocate enc instance[%d] buffers\n",
+                               ctx->num);
+               return -ENOMEM;
+       }
+
+       mfc_change_state(ctx, MFCINST_INIT);
+
+       ctx->capture_state = QUEUE_FREE;
+
+       ret = mfc_alloc_enc_roi_buffer(ctx);
+       if (ret) {
+               mfc_err_ctx("[ROI] Failed to allocate ROI buffers\n");
+               mfc_release_instance_context(ctx);
+               return -ENOMEM;
+       }
+
+       MFC_TRACE_CTX_HWLOCK("**ENC s_fmt\n");
+
+       ret = mfc_get_hwlock_ctx(ctx);
+       if (ret < 0) {
+               mfc_err_dev("Failed to get hwlock\n");
+               mfc_release_instance_context(ctx);
+               mfc_release_enc_roi_buffer(ctx);
+               return -EBUSY;
+       }
+
+       mfc_set_bit(ctx->num, &dev->work_bits);
+       ret = mfc_just_run(dev, ctx->num);
+       if (ret) {
+               mfc_err_ctx("Failed to run MFC\n");
+               mfc_release_hwlock_ctx(ctx);
+               mfc_cleanup_work_bit_and_try_run(ctx);
+               mfc_release_instance_context(ctx);
+               mfc_release_enc_roi_buffer(ctx);
+               return -EIO;
+       }
+
+       if (mfc_wait_for_done_ctx(ctx,
+                               MFC_REG_R2H_CMD_OPEN_INSTANCE_RET)) {
+               mfc_err_ctx("time out during open instance\n");
+               mfc_release_hwlock_ctx(ctx);
+               mfc_cleanup_work_bit_and_try_run(ctx);
+               mfc_release_instance_context(ctx);
+               mfc_release_enc_roi_buffer(ctx);
+               return -EIO;
+       }
+       mfc_release_hwlock_ctx(ctx);
+
+       mfc_debug(2, "Got instance number: %d\n", ctx->inst_no);
+
+       if (mfc_enc_ctx_ready(ctx))
+               mfc_set_bit(ctx->num, &dev->work_bits);
+       if (ctx->otf_handle && mfc_otf_ctx_ready(ctx))
+               mfc_set_bit(ctx->num, &dev->work_bits);
+       if (mfc_is_work_to_do(dev))
+               queue_work(dev->butler_wq, &dev->butler_work);
+
+       mfc_debug_leave();
+       return 0;
+}
+
+static int vidioc_s_fmt_vid_out_mplane(struct file *file, void *priv,
+                                                       struct v4l2_format *f)
+{
+       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+       struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
+
+       mfc_debug_enter();
+
+       if (ctx->vq_src.streaming) {
+               mfc_err_ctx("src queue busy\n");
+               return -EBUSY;
+       }
+
+       if (ctx->otf_handle) {
+               mfc_info_ctx("[OTF] skip source s_fmt\n");
+               return 0;
+       }
+
+       ctx->src_fmt = __mfc_enc_find_format(ctx, pix_fmt_mp->pixelformat);
+       if (!ctx->src_fmt) {
+               mfc_err_ctx("Unsupported format for source\n");
+               return -EINVAL;
+       }
+
+       if (ctx->src_fmt->mem_planes != pix_fmt_mp->num_planes) {
+               mfc_err_ctx("[FRAME] enc src plane number is different (%d != %d)\n",
+                               ctx->src_fmt->mem_planes, pix_fmt_mp->num_planes);
+               return -EINVAL;
+       }
+
+       ctx->raw_buf.num_planes = ctx->src_fmt->num_planes;
+       ctx->img_width = pix_fmt_mp->width;
+       ctx->img_height = pix_fmt_mp->height;
+       ctx->buf_stride = pix_fmt_mp->plane_fmt[0].bytesperline;
+
+       __mfc_enc_check_format(ctx);
+
+       if (ctx->state == MFCINST_RUNNING) {
+               mfc_change_state(ctx, MFCINST_GOT_INST);
+               mfc_info_ctx("[DRC] Enc resolution is changed\n");
+       }
+
+       mfc_info_ctx("[FRAME] enc src pixelformat : %s\n", ctx->src_fmt->name);
+       mfc_info_ctx("[FRAME] resolution w: %d, h: %d, stride: %d\n",
+                       pix_fmt_mp->width, pix_fmt_mp->height, ctx->buf_stride);
+
+       /*
+        * It should be keep till buffer size and stride was calculated.
+        * And it can be changed to real encoding size, if user call the s_crop.
+        */
+       ctx->crop_width = ctx->img_width;
+       ctx->crop_height = ctx->img_height;
+       mfc_enc_calc_src_size(ctx);
+
+       ctx->output_state = QUEUE_FREE;
+
+       mfc_debug_leave();
+       return 0;
+}
+
+static int vidioc_g_crop(struct file *file, void *fh, struct v4l2_crop *cr)
+{
+       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+
+       mfc_debug_enter();
+
+       cr->c.left = ctx->crop_left;
+       cr->c.top = ctx->crop_top;
+       cr->c.width = ctx->crop_width;
+       cr->c.height = ctx->crop_height;
+
+       mfc_debug(2, "[FRAME] enc crop w: %d, h: %d, offset l: %d t: %d\n",
+                       ctx->crop_width, ctx->crop_height, ctx->crop_left, ctx->crop_top);
+
+       mfc_debug_leave();
+
+       return 0;
+}
+
+static int vidioc_s_crop(struct file *file, void *priv, const struct v4l2_crop *cr)
+{
+       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+
+       mfc_debug_enter();
+
+       if (cr->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+               mfc_err_ctx("not supported type (It can only in the source)\n");
+               return -EINVAL;
+       }
+
+       if (cr->c.left < 0 || cr->c.top < 0) {
+               mfc_err_ctx("[FRAME] crop position is negative\n");
+               return -EINVAL;
+       }
+
+       if ((cr->c.height > ctx->img_height) || (cr->c.top > ctx->img_height) ||
+                       (cr->c.width > ctx->img_width) || (cr->c.left > ctx->img_width) ||
+                       (cr->c.left <= (ctx->img_width - cr->c.width)) ||
+                       (cr->c.top <= (ctx->img_height - cr->c.height))) {
+               mfc_err_ctx("[FRAME] Out of crop range: (%d,%d,%d,%d) from %dx%d\n",
+                               cr->c.left, cr->c.top, cr->c.width, cr->c.height,
+                               ctx->img_width, ctx->img_height);
+               return -EINVAL;
+       }
+
+       ctx->crop_top = cr->c.top;
+       ctx->crop_left = cr->c.left;
+       ctx->crop_height = cr->c.height;
+       ctx->crop_width = cr->c.width;
+
+       mfc_debug(3, "[FRAME] enc original: %dx%d, crop: %dx%d, offset l: %d t: %d\n",
+                       ctx->img_width, ctx->img_height,
+                       ctx->crop_width, ctx->crop_height,
+                       ctx->crop_left, ctx->crop_top);
+
+       return 0;
+}
+
+static int vidioc_reqbufs(struct file *file, void *priv,
+                                         struct v4l2_requestbuffers *reqbufs)
+{
+       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+       int ret = 0;
+
+       mfc_debug_enter();
+
+       if (reqbufs->memory == V4L2_MEMORY_MMAP) {
+               mfc_err_ctx("Not supported memory type (%d)\n", reqbufs->memory);
+               return -EINVAL;
+       }
+
+       if (ctx->otf_handle) {
+               mfc_info_ctx("[OTF] skip reqbufs\n");
+               return 0;
+       }
+
+       if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+               mfc_debug(4, "enc dst reqbuf(%d)\n", reqbufs->count);
+               if (reqbufs->count == 0) {
+                       ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
+                       ctx->capture_state = QUEUE_FREE;
+                       return ret;
+               }
+
+               if (ctx->capture_state != QUEUE_FREE) {
+                       mfc_err_ctx("invalid capture state: %d\n", ctx->capture_state);
+                       return -EINVAL;
+               }
+
+               ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
+               if (ret) {
+                       mfc_err_ctx("error in vb2_reqbufs() for E(D)\n");
+                       return ret;
+               }
+
+               ctx->capture_state = QUEUE_BUFS_REQUESTED;
+       } else if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+               mfc_debug(4, "enc src reqbuf(%d)\n", reqbufs->count);
+               if (reqbufs->count == 0) {
+                       ret = vb2_reqbufs(&ctx->vq_src, reqbufs);
+                       ctx->output_state = QUEUE_FREE;
+                       return ret;
+               }
+
+               if (ctx->output_state != QUEUE_FREE) {
+                       mfc_err_ctx("invalid output state: %d\n", ctx->output_state);
+                       return -EINVAL;
+               }
+
+               ret = vb2_reqbufs(&ctx->vq_src, reqbufs);
+               if (ret) {
+                       mfc_err_ctx("error in vb2_reqbufs() for E(S)\n");
+                       return ret;
+               }
+
+               ctx->output_state = QUEUE_BUFS_REQUESTED;
+       } else {
+               mfc_err_ctx("invalid buf type (%d)\n", reqbufs->type);
+               return -EINVAL;
+       }
+
+       mfc_debug_leave();
+
+       return ret;
+}
+
+static int vidioc_querybuf(struct file *file, void *priv,
+                                                  struct v4l2_buffer *buf)
+{
+       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+       int ret = 0;
+
+       mfc_debug_enter();
+
+       if (ctx->otf_handle) {
+               mfc_info_ctx("[OTF] skip source querybuf\n");
+               return 0;
+       }
+
+       if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+               mfc_debug(4, "enc dst querybuf, state: %d\n", ctx->state);
+               ret = vb2_querybuf(&ctx->vq_dst, buf);
+               if (ret != 0) {
+                       mfc_err_dev("enc dst: error in vb2_querybuf()\n");
+                       return ret;
+               }
+       } else if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+               mfc_debug(4, "enc src querybuf, state: %d\n", ctx->state);
+               ret = vb2_querybuf(&ctx->vq_src, buf);
+               if (ret != 0) {
+                       mfc_err_dev("enc src: error in vb2_querybuf()\n");
+                       return ret;
+               }
+       } else {
+               mfc_err_dev("invalid buf type (%d)\n", buf->type);
+               return -EINVAL;
+       }
+
+       mfc_debug_leave();
+
+       return ret;
+}
+
+/* Queue a buffer */
+static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
+{
+       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+       int i, ret = -EINVAL;
+
+       mfc_debug_enter();
+
+       if (ctx->otf_handle) {
+               mfc_info_ctx("[OTF] skip qbuf\n");
+               return 0;
+       }
+
+       if (ctx->state == MFCINST_ERROR) {
+               mfc_err_ctx("Call on QBUF after unrecoverable error\n");
+               return -EIO;
+       }
+
+       if (V4L2_TYPE_IS_MULTIPLANAR(buf->type) && !buf->length) {
+               mfc_err_ctx("multiplanar but length is zero\n");
+               return -EIO;
+       }
+
+       if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+               mfc_debug(4, "enc src buf[%d] Q\n", buf->index);
+               for (i = 0; i < ctx->src_fmt->num_planes; i++) {
+                       if (!buf->m.planes[i].bytesused) {
+                               mfc_debug(2, "[FRAME] enc src[%d] size zero, "
+                                               "changed to buf size %d\n",
+                                               i, buf->m.planes[i].length);
+                               buf->m.planes[i].bytesused = buf->m.planes[i].length;
+                       } else {
+                               mfc_debug(2, "[FRAME] enc src[%d] size %d\n",
+                                               i, buf->m.planes[i].bytesused);
+                       }
+               }
+               ret = vb2_qbuf(&ctx->vq_src, buf);
+       } else {
+               mfc_debug(4, "enc dst buf[%d] Q\n", buf->index);
+               ret = vb2_qbuf(&ctx->vq_dst, buf);
+       }
+
+       mfc_debug_leave();
+       return ret;
+}
+
+/* Dequeue a buffer */
+static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
+{
+       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+       int ret;
+
+       mfc_debug_enter();
+
+       if (ctx->otf_handle) {
+               mfc_info_ctx("[OTF] skip dqbuf\n");
+               return 0;
+       }
+
+       if (ctx->state == MFCINST_ERROR) {
+               mfc_err_ctx("Call on DQBUF after unrecoverable error\n");
+               return -EIO;
+       }
+       if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+               mfc_debug(4, "enc src buf[%d] DQ\n", buf->index);
+               ret = vb2_dqbuf(&ctx->vq_src, buf, file->f_flags & O_NONBLOCK);
+       } else {
+               mfc_debug(4, "enc dst buf[%d] DQ\n", buf->index);
+               ret = vb2_dqbuf(&ctx->vq_dst, buf, file->f_flags & O_NONBLOCK);
+       }
+       mfc_debug_leave();
+       return ret;
+}
+
+/* Stream on */
+static int vidioc_streamon(struct file *file, void *priv,
+                          enum v4l2_buf_type type)
+{
+       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+       int ret = -EINVAL;
+
+       mfc_debug_enter();
+
+       if (ctx->otf_handle) {
+               mfc_info_ctx("[OTF] skip streamon\n");
+               return 0;
+       }
+
+       if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+               mfc_debug(4, "enc src streamon\n");
+               ret = vb2_streamon(&ctx->vq_src, type);
+
+               if (!ret) {
+                       mfc_qos_on(ctx);
+               }
+       } else {
+               mfc_debug(4, "enc dst streamon\n");
+               ret = vb2_streamon(&ctx->vq_dst, type);
+       }
+
+       mfc_debug(2, "src: %d, dst: %d, state = %d, dpb_count = %d\n",
+                 mfc_get_queue_count(&ctx->buf_queue_lock, &ctx->src_buf_queue),
+                 mfc_get_queue_count(&ctx->buf_queue_lock, &ctx->dst_buf_queue),
+                 ctx->state, ctx->dpb_count);
+       mfc_debug_leave();
+       return ret;
+}
+
+/* Stream off, which equals to a pause */
+static int vidioc_streamoff(struct file *file, void *priv,
+                           enum v4l2_buf_type type)
+{
+       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+       int ret;
+
+       mfc_debug_enter();
+
+       if (ctx->otf_handle) {
+               mfc_info_ctx("[OTF] skip streamoff\n");
+               return 0;
+       }
+
+       ret = -EINVAL;
+       if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+               mfc_debug(4, "enc src streamoff\n");
+               mfc_qos_reset_last_framerate(ctx);
+
+               ret = vb2_streamoff(&ctx->vq_src, type);
+               if (!ret)
+                       mfc_qos_off(ctx);
+       } else {
+               mfc_debug(4, "enc dst streamoff\n");
+               ret = vb2_streamoff(&ctx->vq_dst, type);
+       }
+
+       mfc_debug_leave();
+
+       return ret;
+}
+
+/* Query a ctrl */
+static int vidioc_queryctrl(struct file *file, void *priv,
+                           struct v4l2_queryctrl *qc)
+{
+       struct v4l2_queryctrl *c;
+
+       c = __mfc_enc_get_ctrl(qc->id);
+       if (!c) {
+               mfc_err_dev("[CTRLS] not supported control id (%#x)\n", qc->id);
+               return -EINVAL;
+       }
+
+       *qc = *c;
+       return 0;
+}
+
+static int __mfc_enc_ext_info(struct mfc_ctx *ctx)
+{
+       struct mfc_dev *dev = ctx->dev;
+       int val = 0;
+
+       val |= ENC_SET_SPARE_SIZE;
+       val |= ENC_SET_TEMP_SVC_CH;
+
+       if (MFC_FEATURE_SUPPORT(dev, dev->pdata->skype))
+               val |= ENC_SET_SKYPE_FLAG;
+
+       val |= ENC_SET_ROI_CONTROL;
+       val |= ENC_SET_QP_BOUND_PB;
+       val |= ENC_SET_FIXED_SLICE;
+       val |= ENC_SET_PVC_MODE;
+       val |= ENC_SET_RATIO_OF_INTRA;
+
+       if (MFC_FEATURE_SUPPORT(dev, dev->pdata->color_aspect_enc))
+               val |= ENC_SET_COLOR_ASPECT;
+
+       val |= ENC_SET_HP_BITRATE_CONTROL;
+
+       if (MFC_FEATURE_SUPPORT(dev, dev->pdata->static_info_enc))
+               val |= ENC_SET_STATIC_INFO;
+
+       mfc_debug(5, "[CTRLS] ext info val: %#x\n", val);
+
+       return val;
+}
+
+static int __mfc_enc_get_ctrl_val(struct mfc_ctx *ctx, struct v4l2_control *ctrl)
+{
+       struct mfc_dev *dev = ctx->dev;
+       struct mfc_enc *enc = ctx->enc_priv;
+       struct mfc_ctx_ctrl *ctx_ctrl;
+       int ret = 0;
+       int found = 0;
+
+       switch (ctrl->id) {
+       case V4L2_CID_CACHEABLE:
+               mfc_debug(5, "it is supported only V4L2_MEMORY_MMAP\n");
+               break;
+       case V4L2_CID_MPEG_MFC51_VIDEO_STREAM_SIZE:
+               ctrl->value = enc->dst_buf_size;
+               break;
+       case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TYPE:
+               ctrl->value = enc->frame_type;
+               break;
+       case V4L2_CID_MPEG_MFC51_VIDEO_CHECK_STATE:
+               ctrl->value = MFCSTATE_PROCESSING;
+               break;
+       case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG:
+       case V4L2_CID_MPEG_MFC51_VIDEO_LUMA_ADDR:
+       case V4L2_CID_MPEG_MFC51_VIDEO_CHROMA_ADDR:
+       case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_STATUS:
+               list_for_each_entry(ctx_ctrl, &ctx->ctrls, list) {
+                       if (!(ctx_ctrl->type & MFC_CTRL_TYPE_GET))
+                               continue;
+
+                       if (ctx_ctrl->id == ctrl->id) {
+                               if (ctx_ctrl->has_new) {
+                                       ctx_ctrl->has_new = 0;
+                                       ctrl->value = ctx_ctrl->val;
+                               } else {
+                                       mfc_debug(5, "[CTRLS] Control value "\
+                                                       "is not up to date: "\
+                                                       "0x%08x\n", ctrl->id);
+                                       return -EINVAL;
+                               }
+
+                               found = 1;
+                               break;
+                       }
+               }
+
+               if (!found) {
+                       mfc_err_ctx("Invalid control: 0x%08x\n", ctrl->id);
+                       return -EINVAL;
+               }
+               break;
+       case V4L2_CID_MPEG_MFC_GET_VERSION_INFO:
+               ctrl->value = dev->pdata->ip_ver;
+               break;
+       case V4L2_CID_MPEG_MFC_GET_DRIVER_INFO:
+               ctrl->value = MFC_DRIVER_INFO;
+               break;
+       case V4L2_CID_MPEG_MFC_GET_EXTRA_BUFFER_SIZE:
+               ctrl->value = MFC_LINEAR_BUF_SIZE;
+               break;
+       case V4L2_CID_MPEG_VIDEO_QOS_RATIO:
+               ctrl->value = ctx->qos_ratio;
+               break;
+       case V4L2_CID_MPEG_MFC_GET_EXT_INFO:
+               ctrl->value = __mfc_enc_ext_info(ctx);
+               break;
+       case V4L2_CID_MPEG_VIDEO_BPG_HEADER_SIZE:
+               ctrl->value = enc->header_size;
+               break;
+       default:
+               mfc_err_ctx("Invalid control: 0x%08x\n", ctrl->id);
+               ret = -EINVAL;
+               break;
+       }
+
+       mfc_debug(5, "[CTRLS] get id: %#x, value: %d\n", ctrl->id, ctrl->value);
+
+       return ret;
+}
+
+static int vidioc_g_ctrl(struct file *file, void *priv,
+                        struct v4l2_control *ctrl)
+{
+       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+       int ret = 0;
+
+       mfc_debug_enter();
+       ret = __mfc_enc_get_ctrl_val(ctx, ctrl);
+       mfc_debug_leave();
+
+       return ret;
+}
+
+static inline int __mfc_enc_h264_level(enum v4l2_mpeg_video_h264_level lvl)
+{
+       static unsigned int t[V4L2_MPEG_VIDEO_H264_LEVEL_5_1 + 1] = {
+               /* V4L2_MPEG_VIDEO_H264_LEVEL_1_0   */ 10,
+               /* V4L2_MPEG_VIDEO_H264_LEVEL_1B    */ 9,
+               /* V4L2_MPEG_VIDEO_H264_LEVEL_1_1   */ 11,
+               /* V4L2_MPEG_VIDEO_H264_LEVEL_1_2   */ 12,
+               /* V4L2_MPEG_VIDEO_H264_LEVEL_1_3   */ 13,
+               /* V4L2_MPEG_VIDEO_H264_LEVEL_2_0   */ 20,
+               /* V4L2_MPEG_VIDEO_H264_LEVEL_2_1   */ 21,
+               /* V4L2_MPEG_VIDEO_H264_LEVEL_2_2   */ 22,
+               /* V4L2_MPEG_VIDEO_H264_LEVEL_3_0   */ 30,
+               /* V4L2_MPEG_VIDEO_H264_LEVEL_3_1   */ 31,
+               /* V4L2_MPEG_VIDEO_H264_LEVEL_3_2   */ 32,
+               /* V4L2_MPEG_VIDEO_H264_LEVEL_4_0   */ 40,
+               /* V4L2_MPEG_VIDEO_H264_LEVEL_4_1   */ 41,
+               /* V4L2_MPEG_VIDEO_H264_LEVEL_4_2   */ 42,
+               /* V4L2_MPEG_VIDEO_H264_LEVEL_5_0   */ 50,
+               /* V4L2_MPEG_VIDEO_H264_LEVEL_5_1   */ 51,
+       };
+       return t[lvl];
+}
+
+static inline int __mfc_enc_mpeg4_level(enum v4l2_mpeg_video_mpeg4_level lvl)
+{
+       static unsigned int t[V4L2_MPEG_VIDEO_MPEG4_LEVEL_6 + 1] = {
+               /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_0             */ 0,
+               /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B, Simple    */ 9,
+               /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_1             */ 1,
+               /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_2             */ 2,
+               /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_3             */ 3,
+               /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_3B, Advanced  */ 7,
+               /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_4             */ 4,
+               /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_5             */ 5,
+               /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_6,  Simple    */ 6,
+       };
+       return t[lvl];
+}
+
+static inline int __mfc_enc_vui_sar_idc(enum v4l2_mpeg_video_h264_vui_sar_idc sar)
+{
+       static unsigned int t[V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED + 1] = {
+               /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_UNSPECIFIED     */ 0,
+               /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_1x1             */ 1,
+               /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_12x11           */ 2,
+               /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_10x11           */ 3,
+               /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_16x11           */ 4,
+               /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_40x33           */ 5,
+               /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_24x11           */ 6,
+               /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_20x11           */ 7,
+               /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_32x11           */ 8,
+               /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_80x33           */ 9,
+               /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_18x11           */ 10,
+               /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_15x11           */ 11,
+               /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_64x33           */ 12,
+               /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_160x99          */ 13,
+               /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_4x3             */ 14,
+               /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_3x2             */ 15,
+               /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_2x1             */ 16,
+               /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED        */ 255,
+       };
+       return t[sar];
+}
+
+static int __mfc_enc_set_param(struct mfc_ctx *ctx, struct v4l2_control *ctrl)
+{
+       struct mfc_enc *enc = ctx->enc_priv;
+       struct mfc_enc_params *p = &enc->params;
+       int ret = 0;
+
+       switch (ctrl->id) {
+       case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
+               p->gop_size = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE:
+               p->slice_mode =
+                       (enum v4l2_mpeg_video_multi_slice_mode)ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB:
+               p->slice_mb = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES:
+               p->slice_bit = ctrl->value * 8;
+               break;
+       case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB_ROW:
+               p->slice_mb_row = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB:
+               p->intra_refresh_mb = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC51_VIDEO_PADDING:
+               p->pad = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC51_VIDEO_PADDING_YUV:
+               p->pad_luma = (ctrl->value >> 16) & 0xff;
+               p->pad_cb = (ctrl->value >> 8) & 0xff;
+               p->pad_cr = (ctrl->value >> 0) & 0xff;
+               break;
+       case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE:
+               p->rc_frame = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_BITRATE:
+               p->rc_bitrate = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF:
+               p->rc_reaction_coeff = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE:
+               enc->force_frame_type = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_VBV_SIZE:
+               p->vbv_buf_size = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_HEADER_MODE:
+               p->seq_hdr_mode =
+                       (enum v4l2_mpeg_video_header_mode)(ctrl->value);
+               break;
+       case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE:
+               p->frame_skip_mode =
+                       (enum v4l2_mpeg_mfc51_video_frame_skip_mode)
+                       (ctrl->value);
+               break;
+       case V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT:
+               p->fixed_target_bit = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_B_FRAMES:
+               p->num_b_frame = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
+               p->codec.h264.profile =
+               __mfc_enc_h264_profile(ctx, (enum v4l2_mpeg_video_h264_profile)(ctrl->value));
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
+               p->codec.h264.level =
+               __mfc_enc_h264_level((enum v4l2_mpeg_video_h264_level)(ctrl->value));
+               break;
+       case V4L2_CID_MPEG_MFC51_VIDEO_H264_INTERLACE:
+               p->codec.h264.interlace = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE:
+               p->codec.h264.loop_filter_mode =
+               (enum v4l2_mpeg_video_h264_loop_filter_mode)(ctrl->value);
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA:
+               p->codec.h264.loop_filter_alpha = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA:
+               p->codec.h264.loop_filter_beta = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
+               p->codec.h264.entropy_mode =
+                       (enum v4l2_mpeg_video_h264_entropy_mode)(ctrl->value);
+               break;
+       case V4L2_CID_MPEG_MFC51_VIDEO_H264_NUM_REF_PIC_FOR_P:
+               p->num_refs_for_p = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM:
+               p->codec.h264._8x8_transform = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE:
+               p->rc_mb = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC51_VIDEO_H264_RC_FRAME_RATE:
+               p->rc_framerate = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP:
+               p->codec.h264.rc_frame_qp = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_MIN_QP:
+               p->codec.h264.rc_min_qp = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_MAX_QP:
+               p->codec.h264.rc_max_qp = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_MIN_QP_P:
+               p->codec.h264.rc_min_qp_p = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_MAX_QP_P:
+               p->codec.h264.rc_max_qp_p = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_MIN_QP_B:
+               p->codec.h264.rc_min_qp_b = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_MAX_QP_B:
+               p->codec.h264.rc_max_qp_b = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_DARK:
+               p->codec.h264.rc_mb_dark = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_SMOOTH:
+               p->codec.h264.rc_mb_smooth = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_STATIC:
+               p->codec.h264.rc_mb_static = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_ACTIVITY:
+               p->codec.h264.rc_mb_activity = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP:
+               p->codec.h264.rc_p_frame_qp = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP:
+               p->codec.h264.rc_b_frame_qp = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE:
+               p->codec.h264.ar_vui = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC:
+               p->codec.h264.ar_vui_idc =
+               __mfc_enc_vui_sar_idc((enum v4l2_mpeg_video_h264_vui_sar_idc)(ctrl->value));
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH:
+               p->codec.h264.ext_sar_width = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT:
+               p->codec.h264.ext_sar_height = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
+               p->codec.h264.open_gop = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD:
+               p->codec.h264.open_gop_size = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING:
+               p->codec.h264.hier_qp_enable = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE:
+               p->codec.h264.hier_qp_type =
+               (enum v4l2_mpeg_video_h264_hierarchical_coding_type)(ctrl->value);
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER:
+               p->codec.h264.num_hier_layer = ctrl->value & 0x7;
+               p->codec.h264.hier_ref_type = (ctrl->value >> 16) & 0x1;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP:
+               p->codec.h264.hier_qp_layer[(ctrl->value >> 16) & 0x7]
+                       = ctrl->value & 0xFF;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT0:
+               p->codec.h264.hier_bit_layer[0] = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT1:
+               p->codec.h264.hier_bit_layer[1] = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT2:
+               p->codec.h264.hier_bit_layer[2] = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT3:
+               p->codec.h264.hier_bit_layer[3] = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT4:
+               p->codec.h264.hier_bit_layer[4] = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT5:
+               p->codec.h264.hier_bit_layer[5] = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT6:
+               p->codec.h264.hier_bit_layer[6] = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING:
+               p->codec.h264.sei_gen_enable = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_CURRENT_FRAME_0:
+               p->codec.h264.sei_fp_curr_frame_0 = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE:
+               p->codec.h264.sei_fp_arrangement_type = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_FMO:
+               p->codec.h264.fmo_enable = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE:
+               switch ((enum v4l2_mpeg_video_h264_fmo_map_type)(ctrl->value)) {
+               case V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_INTERLEAVED_SLICES:
+               case V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_SCATTERED_SLICES:
+               case V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_RASTER_SCAN:
+               case V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_WIPE_SCAN:
+                       p->codec.h264.fmo_slice_map_type = ctrl->value;
+                       break;
+               default:
+                       ret = -EINVAL;
+               }
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_FMO_SLICE_GROUP:
+               p->codec.h264.fmo_slice_num_grp = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH:
+               p->codec.h264.fmo_run_length[(ctrl->value >> 30) & 0x3]
+                       = ctrl->value & 0x3FFFFFFF;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_DIRECTION:
+               p->codec.h264.fmo_sg_dir = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_RATE:
+               p->codec.h264.fmo_sg_rate = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_ASO:
+               p->codec.h264.aso_enable = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_ASO_SLICE_ORDER:
+               p->codec.h264.aso_slice_order[(ctrl->value >> 18) & 0x7]
+                       &= ~(0xFF << (((ctrl->value >> 16) & 0x3) << 3));
+               p->codec.h264.aso_slice_order[(ctrl->value >> 18) & 0x7]
+                       |= (ctrl->value & 0xFF) << \
+                               (((ctrl->value >> 16) & 0x3) << 3);
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_PREPEND_SPSPPS_TO_IDR:
+               p->codec.h264.prepend_sps_pps_to_idr = ctrl->value ? 1 : 0;
+               break;
+       case V4L2_CID_MPEG_MFC_H264_ENABLE_LTR:
+               p->codec.h264.enable_ltr = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC_H264_NUM_OF_LTR:
+               p->codec.h264.num_of_ltr = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC_H264_BASE_PRIORITY:
+               p->codec.h264.base_priority = ctrl->value;
+               p->codec.h264.set_priority = 1;
+               break;
+       case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:
+               switch ((enum v4l2_mpeg_video_mpeg4_profile)(ctrl->value)) {
+               case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE:
+                       p->codec.mpeg4.profile =
+                               MFC_REG_E_PROFILE_MPEG4_SIMPLE;
+                       break;
+               case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE:
+                       p->codec.mpeg4.profile =
+                       MFC_REG_E_PROFILE_MPEG4_ADVANCED_SIMPLE;
+                       break;
+               default:
+                       ret = -EINVAL;
+               }
+               break;
+       case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL:
+               p->codec.mpeg4.level =
+               __mfc_enc_mpeg4_level((enum v4l2_mpeg_video_mpeg4_level)(ctrl->value));
+               break;
+       case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP:
+               p->codec.mpeg4.rc_frame_qp = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP:
+               p->codec.mpeg4.rc_min_qp = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP:
+               p->codec.mpeg4.rc_max_qp = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP_P:
+               p->codec.mpeg4.rc_min_qp_p = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP_P:
+               p->codec.mpeg4.rc_max_qp_p = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP_B:
+               p->codec.mpeg4.rc_min_qp_b = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP_B:
+               p->codec.mpeg4.rc_max_qp_b = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_MPEG4_QPEL:
+               p->codec.mpeg4.quarter_pixel = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP:
+               p->codec.mpeg4.rc_p_frame_qp = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP:
+               p->codec.mpeg4.rc_b_frame_qp = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC51_VIDEO_MPEG4_VOP_TIME_RES:
+               p->codec.mpeg4.vop_time_res = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC51_VIDEO_MPEG4_VOP_FRM_DELTA:
+               p->codec.mpeg4.vop_frm_delta = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC51_VIDEO_H263_RC_FRAME_RATE:
+               p->rc_framerate = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP:
+               p->codec.mpeg4.rc_frame_qp = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H263_MIN_QP:
+               p->codec.mpeg4.rc_min_qp = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H263_MAX_QP:
+               p->codec.mpeg4.rc_max_qp = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H263_MIN_QP_P:
+               p->codec.mpeg4.rc_min_qp_p = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H263_MAX_QP_P:
+               p->codec.mpeg4.rc_max_qp_p = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP:
+               p->codec.mpeg4.rc_p_frame_qp = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC70_VIDEO_VP8_VERSION:
+               p->codec.vp8.vp8_version = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC70_VIDEO_VP8_RC_FRAME_RATE:
+               p->rc_framerate = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_VP8_MIN_QP:
+               p->codec.vp8.rc_min_qp = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_VP8_MAX_QP:
+               p->codec.vp8.rc_max_qp = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_VP8_MIN_QP_P:
+               p->codec.vp8.rc_min_qp_p = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_VP8_MAX_QP_P:
+               p->codec.vp8.rc_max_qp_p = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_VP8_I_FRAME_QP:
+               p->codec.vp8.rc_frame_qp = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_VP8_P_FRAME_QP:
+               p->codec.vp8.rc_p_frame_qp = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC70_VIDEO_VP8_NUM_OF_PARTITIONS:
+               p->codec.vp8.vp8_numberofpartitions = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC70_VIDEO_VP8_FILTER_LEVEL:
+               p->codec.vp8.vp8_filterlevel = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC70_VIDEO_VP8_FILTER_SHARPNESS:
+               p->codec.vp8.vp8_filtersharpness = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC70_VIDEO_VP8_GOLDEN_FRAMESEL:
+               p->codec.vp8.vp8_goldenframesel = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC70_VIDEO_VP8_GF_REFRESH_PERIOD:
+               p->codec.vp8.vp8_gfrefreshperiod = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC70_VIDEO_VP8_HIERARCHY_QP_ENABLE:
+               p->codec.vp8.hier_qp_enable = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC70_VIDEO_VP8_HIERARCHY_QP_LAYER0:
+               p->codec.vp8.hier_qp_layer[(ctrl->value >> 16) & 0x3]
+                       = ctrl->value & 0xFF;
+               break;
+       case V4L2_CID_MPEG_MFC70_VIDEO_VP8_HIERARCHY_QP_LAYER1:
+               p->codec.vp8.hier_qp_layer[(ctrl->value >> 16) & 0x3]
+                       = ctrl->value & 0xFF;
+               break;
+       case V4L2_CID_MPEG_MFC70_VIDEO_VP8_HIERARCHY_QP_LAYER2:
+               p->codec.vp8.hier_qp_layer[(ctrl->value >> 16) & 0x3]
+                       = ctrl->value & 0xFF;
+               break;
+       case V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_BIT0:
+               p->codec.vp8.hier_bit_layer[0] = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_BIT1:
+               p->codec.vp8.hier_bit_layer[1] = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_BIT2:
+               p->codec.vp8.hier_bit_layer[2] = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC70_VIDEO_VP8_REF_NUMBER_FOR_PFRAMES:
+               p->num_refs_for_p = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC70_VIDEO_VP8_DISABLE_INTRA_MD4X4:
+               p->codec.vp8.intra_4x4mode_disable = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC70_VIDEO_VP8_NUM_TEMPORAL_LAYER:
+               p->codec.vp8.num_hier_layer = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_VP9_VERSION:
+               p->codec.vp9.vp9_version = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_VP9_RC_FRAME_RATE:
+               p->rc_framerate = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_VP9_MIN_QP:
+               p->codec.vp9.rc_min_qp = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_VP9_MAX_QP:
+               p->codec.vp9.rc_max_qp = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_VP9_MIN_QP_P:
+               p->codec.vp9.rc_min_qp_p = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_VP9_MAX_QP_P:
+               p->codec.vp9.rc_max_qp_p = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_VP9_I_FRAME_QP:
+               p->codec.vp9.rc_frame_qp = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_VP9_P_FRAME_QP:
+               p->codec.vp9.rc_p_frame_qp = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_VP9_GOLDEN_FRAMESEL:
+               p->codec.vp9.vp9_goldenframesel = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_VP9_GF_REFRESH_PERIOD:
+               p->codec.vp9.vp9_gfrefreshperiod = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_VP9_HIERARCHY_QP_ENABLE:
+               p->codec.vp9.hier_qp_enable = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_QP:
+               p->codec.vp9.hier_qp_layer[(ctrl->value >> 16) & 0x3]
+                       = ctrl->value & 0xFF;
+               break;
+       case V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_BIT0:
+               p->codec.vp9.hier_bit_layer[0] = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_BIT1:
+               p->codec.vp9.hier_bit_layer[1] = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_BIT2:
+               p->codec.vp9.hier_bit_layer[2] = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_VP9_REF_NUMBER_FOR_PFRAMES:
+               p->num_refs_for_p = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER:
+               p->codec.vp9.num_hier_layer = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_VP9_MAX_PARTITION_DEPTH:
+               p->codec.vp9.max_partition_depth = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_VP9_DISABLE_INTRA_PU_SPLIT:
+               p->codec.vp9.intra_pu_split_disable = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_DISABLE_IVF_HEADER:
+               p->ivf_header_disable = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_VP9_PROFILE:
+               p->codec.vp9.profile = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP:
+               p->codec.hevc.rc_frame_qp = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP:
+               p->codec.hevc.rc_p_frame_qp = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP:
+               p->codec.hevc.rc_b_frame_qp = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_RC_FRAME_RATE:
+               p->rc_framerate = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP:
+               p->codec.hevc.rc_min_qp = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP:
+               p->codec.hevc.rc_max_qp = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP_P:
+               p->codec.hevc.rc_min_qp_p = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP_P:
+               p->codec.hevc.rc_max_qp_p = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP_B:
+               p->codec.hevc.rc_min_qp_b = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP_B:
+               p->codec.hevc.rc_max_qp_b = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL:
+               p->codec.hevc.level = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE:
+               p->codec.hevc.profile = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_ADAPTIVE_RC_DARK:
+               p->codec.hevc.rc_lcu_dark = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_ADAPTIVE_RC_SMOOTH:
+               p->codec.hevc.rc_lcu_smooth = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_ADAPTIVE_RC_STATIC:
+               p->codec.hevc.rc_lcu_static = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_ADAPTIVE_RC_ACTIVITY:
+               p->codec.hevc.rc_lcu_activity = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_TIER_FLAG:
+               p->codec.hevc.tier_flag = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_MAX_PARTITION_DEPTH:
+               p->codec.hevc.max_partition_depth = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_REF_NUMBER_FOR_PFRAMES:
+               p->num_refs_for_p = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_REFRESH_TYPE:
+               p->codec.hevc.refreshtype = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_CONST_INTRA_PRED_ENABLE:
+               p->codec.hevc.const_intra_period_enable = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LOSSLESS_CU_ENABLE:
+               p->codec.hevc.lossless_cu_enable = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_WAVEFRONT_ENABLE:
+               p->codec.hevc.wavefront_enable = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LF_DISABLE:
+               p->codec.hevc.loopfilter_disable = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LF_SLICE_BOUNDARY:
+               p->codec.hevc.loopfilter_across = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LTR_ENABLE:
+               p->codec.hevc.enable_ltr = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_QP_ENABLE:
+               p->codec.hevc.hier_qp_enable = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_TYPE:
+               p->codec.hevc.hier_qp_type =
+               (enum v4l2_mpeg_video_hevc_hierarchical_coding_type)(ctrl->value);
+               break;
+       case V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER:
+               p->codec.hevc.num_hier_layer = ctrl->value & 0x7;
+               p->codec.hevc.hier_ref_type = (ctrl->value >> 16) & 0x1;
+               break;
+       case V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_QP:
+               p->codec.hevc.hier_qp_layer[(ctrl->value >> 16) & 0x7]
+                       = ctrl->value & 0xFF;
+               break;
+       case V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT0:
+               p->codec.hevc.hier_bit_layer[0] = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT1:
+               p->codec.hevc.hier_bit_layer[1] = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT2:
+               p->codec.hevc.hier_bit_layer[2] = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT3:
+               p->codec.hevc.hier_bit_layer[3] = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT4:
+               p->codec.hevc.hier_bit_layer[4] = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT5:
+               p->codec.hevc.hier_bit_layer[5] = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT6:
+               p->codec.hevc.hier_bit_layer[6] = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_GENERAL_PB_ENABLE:
+               p->codec.hevc.general_pb_enable = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_TEMPORAL_ID_ENABLE:
+               p->codec.hevc.temporal_id_enable = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_STRONG_SMOTHING_FLAG:
+               p->codec.hevc.strong_intra_smooth = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_DISABLE_INTRA_PU_SPLIT:
+               p->codec.hevc.intra_pu_split_disable = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_DISABLE_TMV_PREDICTION:
+               p->codec.hevc.tmv_prediction_disable = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_MAX_NUM_MERGE_MV_MINUS1:
+               p->codec.hevc.max_num_merge_mv = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_WITHOUT_STARTCODE_ENABLE:
+               p->codec.hevc.encoding_nostartcode_enable = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_REFRESH_PERIOD:
+               p->codec.hevc.refreshperiod = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LF_BETA_OFFSET_DIV2:
+               p->codec.hevc.lf_beta_offset_div2 = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LF_TC_OFFSET_DIV2:
+               p->codec.hevc.lf_tc_offset_div2 = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD:
+               p->codec.hevc.size_of_length_field = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_USER_REF:
+               p->codec.hevc.user_ref = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_STORE_REF:
+               p->codec.hevc.store_ref = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_ROI_ENABLE:
+               p->roi_enable = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC_H264_VUI_RESTRICTION_ENABLE:
+               p->codec.h264.vui_enable = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_HEVC_PREPEND_SPSPPS_TO_IDR:
+               p->codec.hevc.prepend_sps_pps_to_idr = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC_CONFIG_QP_ENABLE:
+               p->dynamic_qp = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC_CONFIG_QP:
+               p->config_qp = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_RC_PVC_ENABLE:
+               /* It is valid for H.264, HEVC, VP8, VP9 */
+               p->rc_pvc = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_TEMPORAL_SHORTTERM_MAX_LAYER:
+               p->num_hier_max_layer = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_SIGN_DATA_HIDING:
+               break;
+       case V4L2_CID_MPEG_VIDEO_WEIGHTED_ENABLE:
+               p->weighted_enable = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_BPG_THUMBNAIL_SIZE:
+               /* It should be included when NAL_START */
+               p->codec.bpg.thumb_size = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_BPG_EXIF_SIZE:
+               /* It should be included when NAL_START */
+               p->codec.bpg.exif_size = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_RATIO_OF_INTRA:
+               p->ratio_intra = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_FULL_RANGE_FLAG:
+               p->check_color_range = 1;
+               p->color_range = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_COLOUR_PRIMARIES:
+               p->colour_primaries = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_TRANSFER_CHARACTERISTICS:
+               p->transfer_characteristics = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_MATRIX_COEFFICIENTS:
+               p->matrix_coefficients = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_HIERARCHICAL_BITRATE_CTRL:
+               p->hier_bitrate_ctrl = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_STATIC_INFO_ENABLE:
+               p->static_info_enable = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_SEI_MAX_PIC_AVERAGE_LIGHT:
+               p->max_pic_average_light = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_SEI_MAX_CONTENT_LIGHT:
+               p->max_content_light = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_SEI_MAX_DISPLAY_LUMINANCE:
+               p->max_display_luminance = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_SEI_MIN_DISPLAY_LUMINANCE:
+               p->min_display_luminance = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_SEI_WHITE_POINT:
+               p->white_point = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_SEI_DISPLAY_PRIMARIES_0:
+               p->display_primaries_0 = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_SEI_DISPLAY_PRIMARIES_1:
+               p->display_primaries_1 = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_SEI_DISPLAY_PRIMARIES_2:
+               p->display_primaries_2 = ctrl->value;
+               break;
+       default:
+               mfc_err_ctx("Invalid control: 0x%08x\n", ctrl->id);
+               ret = -EINVAL;
+       }
+
+       return ret;
+}
+
+static int __mfc_enc_set_ctrl_val(struct mfc_ctx *ctx, struct v4l2_control *ctrl)
+{
+       struct mfc_enc *enc = ctx->enc_priv;
+       struct mfc_enc_params *p = &enc->params;
+       struct mfc_ctx_ctrl *ctx_ctrl;
+       int ret = 0;
+       int found = 0;
+       int index = 0;
+
+       mfc_debug(5, "[CTRLS] id: %#x, value: %d\n", ctrl->id, ctrl->value);
+
+       switch (ctrl->id) {
+       case V4L2_CID_CACHEABLE:
+               mfc_debug(5, "it is supported only V4L2_MEMORY_MMAP\n");
+               break;
+       case V4L2_CID_MPEG_VIDEO_QOS_RATIO:
+               ctx->qos_ratio = ctrl->value;
+               break;
+       case V4L2_CID_MPEG_VIDEO_H264_MAX_QP:
+       case V4L2_CID_MPEG_VIDEO_H263_MAX_QP:
+       case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP:
+       case V4L2_CID_MPEG_VIDEO_VP8_MAX_QP:
+       case V4L2_CID_MPEG_VIDEO_VP9_MAX_QP:
+       case V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP:
+       case V4L2_CID_MPEG_VIDEO_H264_MIN_QP:
+       case V4L2_CID_MPEG_VIDEO_H263_MIN_QP:
+       case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP:
+       case V4L2_CID_MPEG_VIDEO_VP8_MIN_QP:
+       case V4L2_CID_MPEG_VIDEO_VP9_MIN_QP:
+       case V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP:
+       case V4L2_CID_MPEG_VIDEO_H264_MAX_QP_P:
+       case V4L2_CID_MPEG_VIDEO_H263_MAX_QP_P:
+       case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP_P:
+       case V4L2_CID_MPEG_VIDEO_VP8_MAX_QP_P:
+       case V4L2_CID_MPEG_VIDEO_VP9_MAX_QP_P:
+       case V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP_P:
+       case V4L2_CID_MPEG_VIDEO_H264_MIN_QP_P:
+       case V4L2_CID_MPEG_VIDEO_H263_MIN_QP_P:
+       case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP_P:
+       case V4L2_CID_MPEG_VIDEO_VP8_MIN_QP_P:
+       case V4L2_CID_MPEG_VIDEO_VP9_MIN_QP_P:
+       case V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP_P:
+       case V4L2_CID_MPEG_VIDEO_H264_MAX_QP_B:
+       case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP_B:
+       case V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP_B:
+       case V4L2_CID_MPEG_VIDEO_H264_MIN_QP_B:
+       case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP_B:
+       case V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP_B:
+       case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG:
+       case V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE:
+       case V4L2_CID_MPEG_MFC51_VIDEO_I_PERIOD_CH:
+       case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_RATE_CH:
+       case V4L2_CID_MPEG_MFC51_VIDEO_BIT_RATE_CH:
+       case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_CH:
+       case V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_CH:
+       case V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_CH:
+       case V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_CH:
+       case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
+       case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
+       case V4L2_CID_MPEG_MFC_H264_MARK_LTR:
+       case V4L2_CID_MPEG_MFC_H264_USE_LTR:
+       case V4L2_CID_MPEG_MFC_H264_BASE_PRIORITY:
+       case V4L2_CID_MPEG_MFC_CONFIG_QP:
+       case V4L2_CID_MPEG_VIDEO_ROI_CONTROL:
+       case V4L2_CID_MPEG_VIDEO_YSUM:
+       case V4L2_CID_MPEG_VIDEO_RATIO_OF_INTRA:
+               list_for_each_entry(ctx_ctrl, &ctx->ctrls, list) {
+                       if (!(ctx_ctrl->type & MFC_CTRL_TYPE_SET))
+                               continue;
+
+                       if (ctx_ctrl->id == ctrl->id) {
+                               ctx_ctrl->has_new = 1;
+                               ctx_ctrl->val = ctrl->value;
+                               if (ctx_ctrl->id == \
+                                       V4L2_CID_MPEG_MFC51_VIDEO_FRAME_RATE_CH) {
+                                       ctx_ctrl->val &= ~(0xFFFF << 16);
+                                       ctx_ctrl->val |= ctx_ctrl->val << 16;
+                                       ctx_ctrl->val &= ~(0xFFFF);
+                                       ctx_ctrl->val |= p->rc_frame_delta & 0xFFFF;
+                               }
+                               if (((ctx_ctrl->id == \
+                                       V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_CH) ||
+                                       (ctx_ctrl->id == \
+                                       V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_CH) ||
+                                       (ctx_ctrl->id == \
+                                       V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_CH) ||
+                                       (ctx_ctrl->id == \
+                                       V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_CH)) &&
+                                       (enc->sh_handle_svc.fd == -1)) {
+                                               enc->sh_handle_svc.fd = ctrl->value;
+                                               if (mfc_mem_get_user_shared_handle(ctx,
+                                                                       &enc->sh_handle_svc))
+                                                       return -EINVAL;
+                                               else
+                                                       mfc_debug(2, "[MEMINFO][HIERARCHICAL] shared handle fd: %d, vaddr: 0x%p\n",
+                                                                       enc->sh_handle_svc.fd,
+                                                                       enc->sh_handle_svc.vaddr);
+                               }
+                               if (ctx_ctrl->id == V4L2_CID_MPEG_MFC51_VIDEO_I_PERIOD_CH &&
+                                               p->i_frm_ctrl_mode) {
+                                       ctx_ctrl->val = ctx_ctrl->val * (p->num_b_frame + 1);
+                                       if (ctx_ctrl->val >= 0x3FFFFFFF) {
+                                               mfc_info_ctx("I frame interval is bigger than max: %d\n",
+                                                               ctx_ctrl->val);
+                                               ctx_ctrl->val = 0x3FFFFFFF;
+                                       }
+                               }
+                               if (ctx_ctrl->id == V4L2_CID_MPEG_VIDEO_H264_LEVEL)
+                                       ctx_ctrl->val = __mfc_enc_h264_level((enum v4l2_mpeg_video_h264_level)(ctrl->value));
+                               if (ctx_ctrl->id == V4L2_CID_MPEG_VIDEO_H264_PROFILE)
+                                       ctx_ctrl->val = __mfc_enc_h264_profile(ctx, (enum v4l2_mpeg_video_h264_profile)(ctrl->value));
+                               if (ctx_ctrl->id == V4L2_CID_MPEG_VIDEO_ROI_CONTROL) {
+                                       if (enc->sh_handle_roi.fd == -1) {
+                                               enc->sh_handle_roi.fd = ctrl->value;
+                                               if (mfc_mem_get_user_shared_handle(ctx,
+                                                                       &enc->sh_handle_roi))
+                                                       return -EINVAL;
+                                               else
+                                                       mfc_debug(2, "[MEMINFO][ROI] shared handle fd: %d, vaddr: 0x%p\n",
+                                                                       enc->sh_handle_roi.fd,
+                                                                       enc->sh_handle_roi.vaddr);
+                                       }
+                                       index = enc->roi_index;
+                                       memcpy(&enc->roi_info[index],
+                                                       enc->sh_handle_roi.vaddr,
+                                                       sizeof(struct mfc_enc_roi_info));
+                                       if (copy_from_user(enc->roi_buf[index].vaddr,
+                                                       enc->roi_info[index].addr,
+                                                       enc->roi_info[index].size))
+                                               return -EFAULT;
+                               }
+
+                               found = 1;
+                               break;
+                       }
+               }
+
+               if (!found) {
+                       mfc_err_ctx("Invalid control: 0x%08x\n", ctrl->id);
+                       return -EINVAL;
+               }
+               break;
+       default:
+               ret = __mfc_enc_set_param(ctx, ctrl);
+               break;
+       }
+
+       return ret;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *priv,
+                        struct v4l2_control *ctrl)
+{
+       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+       int ret = 0;
+
+       mfc_debug_enter();
+
+       ret = __mfc_enc_check_ctrl_val(ctx, ctrl);
+       if (ret != 0)
+               return ret;
+
+       ret = __mfc_enc_set_ctrl_val(ctx, ctrl);
+
+       mfc_debug_leave();
+
+       return ret;
+}
+
+static int vidioc_g_ext_ctrls(struct file *file, void *priv,
+                             struct v4l2_ext_controls *f)
+{
+       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+       struct v4l2_ext_control *ext_ctrl;
+       struct v4l2_control ctrl;
+       int i;
+       int ret = 0;
+
+       if (f->which != V4L2_CTRL_CLASS_MPEG)
+               return -EINVAL;
+
+       for (i = 0; i < f->count; i++) {
+               ext_ctrl = (f->controls + i);
+
+               ctrl.id = ext_ctrl->id;
+
+               ret = __mfc_enc_get_ctrl_val(ctx, &ctrl);
+               if (ret == 0) {
+                       ext_ctrl->value = ctrl.value;
+               } else {
+                       f->error_idx = i;
+                       break;
+               }
+
+               mfc_debug(5, "[CTRLS][%d] id: %#x, value: %d\n",
+                               i, ext_ctrl->id, ext_ctrl->value);
+       }
+
+       return ret;
+}
+
+static int vidioc_s_ext_ctrls(struct file *file, void *priv,
+                               struct v4l2_ext_controls *f)
+{
+       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+       struct v4l2_ext_control *ext_ctrl;
+       struct v4l2_control ctrl;
+       int i;
+       int ret = 0;
+
+       if (f->which != V4L2_CTRL_CLASS_MPEG)
+               return -EINVAL;
+
+       for (i = 0; i < f->count; i++) {
+               ext_ctrl = (f->controls + i);
+
+               ctrl.id = ext_ctrl->id;
+               ctrl.value = ext_ctrl->value;
+
+               ret = __mfc_enc_check_ctrl_val(ctx, &ctrl);
+               if (ret != 0) {
+                       f->error_idx = i;
+                       break;
+               }
+
+               ret = __mfc_enc_set_param(ctx, &ctrl);
+               if (ret != 0) {
+                       f->error_idx = i;
+                       break;
+               }
+
+               mfc_debug(5, "[CTRLS][%d] id: %#x, value: %d\n",
+                               i, ext_ctrl->id, ext_ctrl->value);
+       }
+
+       return ret;
+}
+
+static int vidioc_try_ext_ctrls(struct file *file, void *priv,
+                               struct v4l2_ext_controls *f)
+{
+       struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+       struct v4l2_ext_control *ext_ctrl;
+       struct v4l2_control ctrl;
+       int i;
+       int ret = 0;
+
+       if (f->which != V4L2_CTRL_CLASS_MPEG)
+               return -EINVAL;
+
+       for (i = 0; i < f->count; i++) {
+               ext_ctrl = (f->controls + i);
+
+               ctrl.id = ext_ctrl->id;
+               ctrl.value = ext_ctrl->value;
+
+               ret = __mfc_enc_check_ctrl_val(ctx, &ctrl);
+               if (ret != 0) {
+                       f->error_idx = i;
+                       break;
+               }
+
+               mfc_debug(2, "[%d] id: 0x%08x, value: %d\n", i, ext_ctrl->id, ext_ctrl->value);
+       }
+
+       return ret;
+}
+
+static const struct v4l2_ioctl_ops mfc_enc_ioctl_ops = {
+       .vidioc_querycap                = vidioc_querycap,
+       .vidioc_enum_fmt_vid_cap_mplane = vidioc_enum_fmt_vid_cap_mplane,
+       .vidioc_enum_fmt_vid_out_mplane = vidioc_enum_fmt_vid_out_mplane,
+       .vidioc_g_fmt_vid_cap_mplane    = vidioc_g_fmt,
+       .vidioc_g_fmt_vid_out_mplane    = vidioc_g_fmt,
+       .vidioc_try_fmt_vid_cap_mplane  = vidioc_try_fmt,
+       .vidioc_try_fmt_vid_out_mplane  = vidioc_try_fmt,
+       .vidioc_s_fmt_vid_cap_mplane    = vidioc_s_fmt_vid_cap_mplane,
+       .vidioc_s_fmt_vid_out_mplane    = vidioc_s_fmt_vid_out_mplane,
+       .vidioc_g_crop                  = vidioc_g_crop,
+       .vidioc_s_crop                  = vidioc_s_crop,
+       .vidioc_reqbufs                 = vidioc_reqbufs,
+       .vidioc_querybuf                = vidioc_querybuf,
+       .vidioc_qbuf                    = vidioc_qbuf,
+       .vidioc_dqbuf                   = vidioc_dqbuf,
+       .vidioc_streamon                = vidioc_streamon,
+       .vidioc_streamoff               = vidioc_streamoff,
+       .vidioc_queryctrl               = vidioc_queryctrl,
+       .vidioc_g_ctrl                  = vidioc_g_ctrl,
+       .vidioc_s_ctrl                  = vidioc_s_ctrl,
+       .vidioc_g_ext_ctrls             = vidioc_g_ext_ctrls,
+       .vidioc_s_ext_ctrls             = vidioc_s_ext_ctrls,
+       .vidioc_try_ext_ctrls           = vidioc_try_ext_ctrls,
+};
+
+const struct v4l2_ioctl_ops *mfc_get_enc_v4l2_ioctl_ops(void)
+{
+       return &mfc_enc_ioctl_ops;
+}
diff --git a/drivers/media/platform/exynos/mfc/mfc_enc_v4l2.h b/drivers/media/platform/exynos/mfc/mfc_enc_v4l2.h
new file mode 100644 (file)
index 0000000..24a24dd
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * drivers/media/platform/exynos/mfc/mfc_enc_v4l2.h
+ *
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __MFC_ENC_V4L2_H
+#define __MFC_ENC_V4L2_H __FILE__
+
+#include "mfc_common.h"
+
+const struct v4l2_ioctl_ops *mfc_get_enc_v4l2_ioctl_ops(void);
+
+#endif /* __MFC_ENC_V4L2_H */
diff --git a/drivers/media/platform/exynos/mfc/mfc_enc_vb2.c b/drivers/media/platform/exynos/mfc/mfc_enc_vb2.c
new file mode 100644 (file)
index 0000000..6d9ef8f
--- /dev/null
@@ -0,0 +1,478 @@
+/*
+ * drivers/media/platform/exynos/mfc/mfc_enc_vb2_ops.c
+ *
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include "mfc_common.h"
+
+#include "mfc_hwlock.h"
+#include "mfc_nal_q.h"
+#include "mfc_opr.h"
+#include "mfc_sync.h"
+
+#include "mfc_qos.h"
+#include "mfc_queue.h"
+#include "mfc_utils.h"
+#include "mfc_buf.h"
+#include "mfc_mem.h"
+
+static int mfc_enc_queue_setup(struct vb2_queue *vq,
+                               unsigned int *buf_count, unsigned int *plane_count,
+                               unsigned int psize[], struct device *alloc_devs[])
+{
+       struct mfc_dev *dev;
+       struct mfc_ctx *ctx = vq->drv_priv;
+       struct mfc_enc *enc = ctx->enc_priv;
+       struct mfc_raw_info *raw;
+       int i;
+
+       mfc_debug_enter();
+
+       dev = ctx->dev;
+       if (!dev) {
+               mfc_err_dev("no mfc device to run\n");
+               return -EINVAL;
+       }
+
+       if (ctx->state != MFCINST_GOT_INST &&
+           vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+               mfc_err_ctx("invalid state: %d\n", ctx->state);
+               return -EINVAL;
+       }
+       if (ctx->state >= MFCINST_FINISHING &&
+           vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+               mfc_err_ctx("invalid state: %d\n", ctx->state);
+               return -EINVAL;
+       }
+
+       if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+               mfc_debug(4, "enc dst\n");
+               if (ctx->dst_fmt)
+                       *plane_count = ctx->dst_fmt->mem_planes;
+               else
+                       *plane_count = MFC_ENC_CAP_PLANE_COUNT;
+
+               if (*buf_count < 1)
+                       *buf_count = 1;
+               if (*buf_count > MFC_MAX_BUFFERS)
+                       *buf_count = MFC_MAX_BUFFERS;
+
+               psize[0] = enc->dst_buf_size;
+               alloc_devs[0] = dev->device;
+       } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+               mfc_debug(4, "enc src\n");
+               raw = &ctx->raw_buf;
+
+               if (ctx->src_fmt)
+                       *plane_count = ctx->src_fmt->mem_planes;
+               else
+                       *plane_count = MFC_ENC_OUT_PLANE_COUNT;
+
+               if (*buf_count < 1)
+                       *buf_count = 1;
+               if (*buf_count > MFC_MAX_BUFFERS)
+                       *buf_count = MFC_MAX_BUFFERS;
+
+               if (*plane_count == 1) {
+                       psize[0] = raw->total_plane_size;
+                       alloc_devs[0] = dev->device;
+               } else {
+                       for (i = 0; i < *plane_count; i++) {
+                               psize[i] = raw->plane_size[i];
+                               alloc_devs[i] = dev->device;
+                       }
+               }
+       } else {
+               mfc_err_ctx("invalid queue type: %d\n", vq->type);
+               return -EINVAL;
+       }
+
+       mfc_debug(2, "buf_count: %d, plane_count: %d, type: %#x\n",
+                       *buf_count, *plane_count, vq->type);
+       for (i = 0; i < *plane_count; i++)
+               mfc_debug(2, "plane[%d] size: %d\n", i, psize[i]);
+
+       mfc_debug_leave();
+
+       return 0;
+}
+
+static void mfc_enc_unlock(struct vb2_queue *q)
+{
+       struct mfc_ctx *ctx = q->drv_priv;
+       struct mfc_dev *dev = ctx->dev;
+
+       mutex_unlock(&dev->mfc_mutex);
+}
+
+static void mfc_enc_lock(struct vb2_queue *q)
+{
+       struct mfc_ctx *ctx = q->drv_priv;
+       struct mfc_dev *dev = ctx->dev;
+
+       mutex_lock(&dev->mfc_mutex);
+}
+
+static int mfc_enc_buf_init(struct vb2_buffer *vb)
+{
+       struct vb2_queue *vq = vb->vb2_queue;
+       struct mfc_ctx *ctx = vq->drv_priv;
+       int ret;
+
+       mfc_debug_enter();
+
+       if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+               ret = mfc_check_vb_with_fmt(ctx->dst_fmt, vb);
+               if (ret < 0)
+                       return ret;
+
+               if (call_cop(ctx, init_buf_ctrls, ctx, MFC_CTRL_TYPE_DST,
+                                       vb->index) < 0)
+                       mfc_err_ctx("failed in init_buf_ctrls\n");
+
+       } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+               ret = mfc_check_vb_with_fmt(ctx->src_fmt, vb);
+               if (ret < 0)
+                       return ret;
+
+               if (call_cop(ctx, init_buf_ctrls, ctx, MFC_CTRL_TYPE_SRC,
+                                       vb->index) < 0)
+                       mfc_err_ctx("failed in init_buf_ctrls\n");
+       } else {
+               mfc_err_ctx("inavlid queue type: %d\n", vq->type);
+               return -EINVAL;
+       }
+
+       mfc_debug_leave();
+
+       return 0;
+}
+
+static int mfc_enc_buf_prepare(struct vb2_buffer *vb)
+{
+       struct vb2_queue *vq = vb->vb2_queue;
+       struct mfc_ctx *ctx = vq->drv_priv;
+       struct mfc_enc *enc = ctx->enc_priv;
+       struct mfc_raw_info *raw;
+       unsigned int index = vb->index;
+       struct mfc_buf *buf = vb_to_mfc_buf(vb);
+       struct dma_buf *bufcon_dmabuf[MFC_MAX_PLANES];
+       int i, mem_get_count = 0;
+       size_t buf_size;
+
+       mfc_debug_enter();
+
+       if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+               buf_size = vb2_plane_size(vb, 0);
+               mfc_debug(2, "[STREAM] vb size: %lu, calc size: %u\n",
+                       buf_size, enc->dst_buf_size);
+
+               if (buf_size < enc->dst_buf_size) {
+                       mfc_err_ctx("[STREAM] size(%d) is smaller than (%d)\n",
+                                       buf_size, enc->dst_buf_size);
+                       return -EINVAL;
+               }
+
+               buf->addr[0][0] = mfc_mem_get_daddr_vb(vb, 0);
+       } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+               raw = &ctx->raw_buf;
+               if (ctx->src_fmt->mem_planes == 1) {
+                       buf_size = vb2_plane_size(vb, 0);
+                       mfc_debug(2, "[FRAME] single plane vb size: %lu, calc size: %d\n",
+                                       buf_size, raw->total_plane_size);
+                       if (buf_size < raw->total_plane_size) {
+                               mfc_err_ctx("[FRAME] single plane size(%d) is smaller than (%d)\n",
+                                               buf_size, raw->total_plane_size);
+                               return -EINVAL;
+                       }
+               } else {
+                       for (i = 0; i < ctx->src_fmt->mem_planes; i++) {
+                               buf_size = vb2_plane_size(vb, i);
+                               mfc_debug(2, "[FRAME] plane[%d] vb size: %lu, calc size: %d\n",
+                                               i, buf_size, raw->plane_size[i]);
+                               if (buf_size < raw->plane_size[i]) {
+                                       mfc_err_ctx("[FRAME] plane[%d] size(%d) is smaller than (%d)\n",
+                                                       i, buf_size, raw->plane_size[i]);
+                                       return -EINVAL;
+                               }
+                       }
+               }
+
+               for (i = 0; i < ctx->src_fmt->mem_planes; i++) {
+                       bufcon_dmabuf[i] = dma_buf_get(vb->planes[i].m.fd);
+                       if (IS_ERR(bufcon_dmabuf[i])) {
+                               mfc_err_ctx("failed to get bufcon dmabuf\n");
+                               goto err_mem_put;
+                       }
+
+                       mem_get_count++;
+                       buf->num_bufs_in_batch = mfc_bufcon_get_buf_count(bufcon_dmabuf[i]);
+                       mfc_debug(3, "[BUFCON] num bufs in batch: %d\n", buf->num_bufs_in_batch);
+                       if (buf->num_bufs_in_batch == 0) {
+                               mfc_err_ctx("[BUFCON] bufs count couldn't be zero\n");
+                               goto err_mem_put;
+                       }
+
+                       if (buf->num_bufs_in_batch < 0)
+                               buf->num_bufs_in_batch = 0;
+
+                       if (!ctx->batch_mode && buf->num_bufs_in_batch > 0) {
+                               ctx->batch_mode = 1;
+                               mfc_debug(2, "[BUFCON] buffer batch mode enable\n");
+                       }
+
+                       if (buf->num_bufs_in_batch > 0) {
+                               if (mfc_bufcon_get_daddr(ctx, buf, bufcon_dmabuf[i], i)) {
+                                       mfc_err_ctx("[BUFCON] failed to get daddr[%d] in buffer container\n", i);
+                                       goto err_mem_put;
+                               }
+
+                               ctx->framerate = buf->num_valid_bufs * ENC_DEFAULT_CAM_CAPTURE_FPS;
+                               mfc_debug(3, "[BUFCON] framerate: %ld\n", ctx->framerate);
+
+                               dma_buf_put(bufcon_dmabuf[i]);
+                       } else {
+                               dma_addr_t start_raw;
+
+                               dma_buf_put(bufcon_dmabuf[i]);
+                               start_raw = mfc_mem_get_daddr_vb(vb, 0);
+                               if (start_raw == 0) {
+                                       mfc_err_ctx("Plane mem not allocated\n");
+                                       return -ENOMEM;
+                               }
+                               if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12N) {
+                                       buf->addr[0][0] = start_raw;
+                                       buf->addr[0][1] = NV12N_CBCR_BASE(start_raw,
+                                                       ctx->img_width,
+                                                       ctx->img_height);
+                               } else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420N) {
+                                       buf->addr[0][0] = start_raw;
+                                       buf->addr[0][1] = YUV420N_CB_BASE(start_raw,
+                                                       ctx->img_width,
+                                                       ctx->img_height);
+                                       buf->addr[0][2] = YUV420N_CR_BASE(start_raw,
+                                                       ctx->img_width,
+                                                       ctx->img_height);
+                               } else {
+                                       buf->addr[0][i] = mfc_mem_get_daddr_vb(vb, i);
+                               }
+                       }
+               }
+
+               if (call_cop(ctx, to_buf_ctrls, ctx, &ctx->src_ctrls[index]) < 0)
+                       mfc_err_ctx("failed in to_buf_ctrls\n");
+       } else {
+               mfc_err_ctx("inavlid queue type: %d\n", vq->type);
+               return -EINVAL;
+       }
+
+       mfc_debug_leave();
+       return 0;
+
+err_mem_put:
+       for (i = 0; i < mem_get_count; i++)
+               dma_buf_put(bufcon_dmabuf[i]);
+
+       return -ENOMEM;
+}
+
+static void mfc_enc_buf_finish(struct vb2_buffer *vb)
+{
+       struct vb2_queue *vq = vb->vb2_queue;
+       struct mfc_ctx *ctx = vq->drv_priv;
+       unsigned int index = vb->index;
+
+
+       if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+               if (call_cop(ctx, to_ctx_ctrls, ctx, &ctx->dst_ctrls[index]) < 0)
+                       mfc_err_ctx("failed in to_ctx_ctrls\n");
+       } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+               if (call_cop(ctx, to_ctx_ctrls, ctx, &ctx->src_ctrls[index]) < 0)
+                       mfc_err_ctx("failed in to_ctx_ctrls\n");
+       }
+}
+
+static void mfc_enc_buf_cleanup(struct vb2_buffer *vb)
+{
+       struct vb2_queue *vq = vb->vb2_queue;
+       struct mfc_ctx *ctx = vq->drv_priv;
+       unsigned int index = vb->index;
+
+       mfc_debug_enter();
+
+       if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+               if (call_cop(ctx, cleanup_buf_ctrls, ctx,
+                                       MFC_CTRL_TYPE_DST, index) < 0)
+                       mfc_err_ctx("failed in cleanup_buf_ctrls\n");
+       } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+               if (call_cop(ctx, cleanup_buf_ctrls, ctx,
+                                       MFC_CTRL_TYPE_SRC, index) < 0)
+                       mfc_err_ctx("failed in cleanup_buf_ctrls\n");
+       } else {
+               mfc_err_ctx("mfc_enc_buf_cleanup: unknown queue type\n");
+       }
+
+       mfc_debug_leave();
+}
+
+static int mfc_enc_start_streaming(struct vb2_queue *q, unsigned int count)
+{
+       struct mfc_ctx *ctx = q->drv_priv;
+       struct mfc_dev *dev = ctx->dev;
+
+       /* If context is ready then dev = work->data;schedule it to run */
+       if (mfc_enc_ctx_ready(ctx)) {
+               mfc_set_bit(ctx->num, &dev->work_bits);
+       }
+
+       mfc_try_run(dev);
+
+       return 0;
+}
+
+static void mfc_enc_stop_streaming(struct vb2_queue *q)
+{
+       struct mfc_ctx *ctx = q->drv_priv;
+       struct mfc_dev *dev = ctx->dev;
+       int index = 0;
+       int aborted = 0;
+       int ret = 0;
+
+       mfc_info_ctx("enc stop_streaming is called, hwlock : %d, type : %d\n",
+                               test_bit(ctx->num, &dev->hwlock.bits), q->type);
+       MFC_TRACE_CTX("** ENC streamoff(type:%d)\n", q->type);
+
+       /* If a H/W operation is in progress, wait for it complete */
+       if (need_to_wait_nal_abort(ctx)) {
+               if (mfc_wait_for_done_ctx(ctx, MFC_REG_R2H_CMD_NAL_ABORT_RET)) {
+                       mfc_err_ctx("time out during nal abort\n");
+                       mfc_cleanup_work_bit_and_try_run(ctx);
+               }
+               aborted = 1;
+       }
+       MFC_TRACE_CTX_HWLOCK("**ENC streamoff(type:%d)\n", q->type);
+       ret = mfc_get_hwlock_ctx(ctx);
+       if (ret < 0) {
+               mfc_err_ctx("Failed to get hwlock\n");
+               return;
+       }
+
+       if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+               mfc_cleanup_enc_dst_queue(ctx);
+
+               while (index < MFC_MAX_BUFFERS) {
+                       index = find_next_bit(&ctx->dst_ctrls_avail,
+                                       MFC_MAX_BUFFERS, index);
+                       if (index < MFC_MAX_BUFFERS)
+                               call_cop(ctx, reset_buf_ctrls, &ctx->dst_ctrls[index]);
+                       index++;
+               }
+       } else if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+               if (ctx->state == MFCINST_RUNNING) {
+                       mfc_change_state(ctx, MFCINST_FINISHING);
+                       mfc_set_bit(ctx->num, &dev->work_bits);
+
+                       while (mfc_get_buf(&ctx->buf_queue_lock, &ctx->dst_buf_queue, MFC_BUF_NO_TOUCH_USED)) {
+                               ret = mfc_just_run(dev, ctx->num);
+                               if (ret) {
+                                       mfc_err_ctx("Failed to run MFC\n");
+                                       break;
+                               }
+                               if (mfc_wait_for_done_ctx(ctx, MFC_REG_R2H_CMD_FRAME_DONE_RET)) {
+                                       mfc_err_ctx("Waiting for LAST_SEQ timed out\n");
+                                       break;
+                               }
+                               if (ctx->state == MFCINST_RUNNING) {
+                                       mfc_debug(2, "all encoded buffers out\n");
+                                       break;
+                               }
+                       }
+               }
+
+               mfc_move_all_bufs(&ctx->buf_queue_lock, &ctx->src_buf_queue,
+                               &ctx->ref_buf_queue, MFC_QUEUE_ADD_BOTTOM);
+               mfc_cleanup_enc_src_queue(ctx);
+
+               while (index < MFC_MAX_BUFFERS) {
+                       index = find_next_bit(&ctx->src_ctrls_avail,
+                                       MFC_MAX_BUFFERS, index);
+                       if (index < MFC_MAX_BUFFERS)
+                               call_cop(ctx, reset_buf_ctrls, &ctx->src_ctrls[index]);
+                       index++;
+               }
+       }
+
+       if (aborted || ctx->state == MFCINST_FINISHING)
+               mfc_change_state(ctx, MFCINST_RUNNING);
+
+       mfc_debug(2, "buffer cleanup is done in stop_streaming, type : %d\n", q->type);
+
+       mfc_clear_bit(ctx->num, &dev->work_bits);
+       mfc_release_hwlock_ctx(ctx);
+
+       if (mfc_is_work_to_do(dev))
+               queue_work(dev->butler_wq, &dev->butler_work);
+}
+
+static void mfc_enc_buf_queue(struct vb2_buffer *vb)
+{
+       struct vb2_queue *vq = vb->vb2_queue;
+       struct mfc_ctx *ctx = vq->drv_priv;
+       struct mfc_dev *dev = ctx->dev;
+       struct mfc_buf *buf = vb_to_mfc_buf(vb);
+       int i;
+
+       mfc_debug_enter();
+
+       buf->next_index = 0;
+       buf->done_index = 0;
+
+       if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+               mfc_debug(2, "[BUFINFO] ctx[%d] add dst index: %d, addr: 0x%08llx\n",
+                               ctx->num, vb->index, buf->addr[0][0]);
+
+               /* Mark destination as available for use by MFC */
+               mfc_add_tail_buf(&ctx->buf_queue_lock, &ctx->dst_buf_queue, buf);
+       } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+               for (i = 0; i < ctx->src_fmt->mem_planes; i++)
+                       mfc_debug(2, "[BUFINFO] ctx[%d] add src index: %d, addr[%d]: 0x%08llx\n",
+                                       ctx->num, vb->index, i, buf->addr[0][i]);
+               mfc_add_tail_buf(&ctx->buf_queue_lock, &ctx->src_buf_queue, buf);
+
+               if (debug_ts == 1)
+                       mfc_info_ctx("[TS] framerate: %ld, timestamp: %lld\n",
+                                       ctx->framerate, buf->vb.vb2_buf.timestamp);
+
+               mfc_qos_update_last_framerate(ctx, buf->vb.vb2_buf.timestamp);
+               mfc_qos_update_framerate(ctx);
+       } else {
+               mfc_err_ctx("unsupported buffer type (%d)\n", vq->type);
+       }
+
+       if (mfc_enc_ctx_ready(ctx)) {
+               mfc_set_bit(ctx->num, &dev->work_bits);
+       }
+       mfc_try_run(dev);
+
+       mfc_debug_leave();
+}
+
+struct vb2_ops mfc_enc_qops = {
+       .queue_setup            = mfc_enc_queue_setup,
+       .wait_prepare           = mfc_enc_unlock,
+       .wait_finish            = mfc_enc_lock,
+       .buf_init               = mfc_enc_buf_init,
+       .buf_prepare            = mfc_enc_buf_prepare,
+       .buf_finish             = mfc_enc_buf_finish,
+       .buf_cleanup            = mfc_enc_buf_cleanup,
+       .start_streaming        = mfc_enc_start_streaming,
+       .stop_streaming         = mfc_enc_stop_streaming,
+       .buf_queue              = mfc_enc_buf_queue,
+};
diff --git a/drivers/media/platform/exynos/mfc/mfc_enc_vb2_ops.c b/drivers/media/platform/exynos/mfc/mfc_enc_vb2_ops.c
deleted file mode 100644 (file)
index 6d9ef8f..0000000
+++ /dev/null
@@ -1,478 +0,0 @@
-/*
- * drivers/media/platform/exynos/mfc/mfc_enc_vb2_ops.c
- *
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include "mfc_common.h"
-
-#include "mfc_hwlock.h"
-#include "mfc_nal_q.h"
-#include "mfc_opr.h"
-#include "mfc_sync.h"
-
-#include "mfc_qos.h"
-#include "mfc_queue.h"
-#include "mfc_utils.h"
-#include "mfc_buf.h"
-#include "mfc_mem.h"
-
-static int mfc_enc_queue_setup(struct vb2_queue *vq,
-                               unsigned int *buf_count, unsigned int *plane_count,
-                               unsigned int psize[], struct device *alloc_devs[])
-{
-       struct mfc_dev *dev;
-       struct mfc_ctx *ctx = vq->drv_priv;
-       struct mfc_enc *enc = ctx->enc_priv;
-       struct mfc_raw_info *raw;
-       int i;
-
-       mfc_debug_enter();
-
-       dev = ctx->dev;
-       if (!dev) {
-               mfc_err_dev("no mfc device to run\n");
-               return -EINVAL;
-       }
-
-       if (ctx->state != MFCINST_GOT_INST &&
-           vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-               mfc_err_ctx("invalid state: %d\n", ctx->state);
-               return -EINVAL;
-       }
-       if (ctx->state >= MFCINST_FINISHING &&
-           vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
-               mfc_err_ctx("invalid state: %d\n", ctx->state);
-               return -EINVAL;
-       }
-
-       if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-               mfc_debug(4, "enc dst\n");
-               if (ctx->dst_fmt)
-                       *plane_count = ctx->dst_fmt->mem_planes;
-               else
-                       *plane_count = MFC_ENC_CAP_PLANE_COUNT;
-
-               if (*buf_count < 1)
-                       *buf_count = 1;
-               if (*buf_count > MFC_MAX_BUFFERS)
-                       *buf_count = MFC_MAX_BUFFERS;
-
-               psize[0] = enc->dst_buf_size;
-               alloc_devs[0] = dev->device;
-       } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
-               mfc_debug(4, "enc src\n");
-               raw = &ctx->raw_buf;
-
-               if (ctx->src_fmt)
-                       *plane_count = ctx->src_fmt->mem_planes;
-               else
-                       *plane_count = MFC_ENC_OUT_PLANE_COUNT;
-
-               if (*buf_count < 1)
-                       *buf_count = 1;
-               if (*buf_count > MFC_MAX_BUFFERS)
-                       *buf_count = MFC_MAX_BUFFERS;
-
-               if (*plane_count == 1) {
-                       psize[0] = raw->total_plane_size;
-                       alloc_devs[0] = dev->device;
-               } else {
-                       for (i = 0; i < *plane_count; i++) {
-                               psize[i] = raw->plane_size[i];
-                               alloc_devs[i] = dev->device;
-                       }
-               }
-       } else {
-               mfc_err_ctx("invalid queue type: %d\n", vq->type);
-               return -EINVAL;
-       }
-
-       mfc_debug(2, "buf_count: %d, plane_count: %d, type: %#x\n",
-                       *buf_count, *plane_count, vq->type);
-       for (i = 0; i < *plane_count; i++)
-               mfc_debug(2, "plane[%d] size: %d\n", i, psize[i]);
-
-       mfc_debug_leave();
-
-       return 0;
-}
-
-static void mfc_enc_unlock(struct vb2_queue *q)
-{
-       struct mfc_ctx *ctx = q->drv_priv;
-       struct mfc_dev *dev = ctx->dev;
-
-       mutex_unlock(&dev->mfc_mutex);
-}
-
-static void mfc_enc_lock(struct vb2_queue *q)
-{
-       struct mfc_ctx *ctx = q->drv_priv;
-       struct mfc_dev *dev = ctx->dev;
-
-       mutex_lock(&dev->mfc_mutex);
-}
-
-static int mfc_enc_buf_init(struct vb2_buffer *vb)
-{
-       struct vb2_queue *vq = vb->vb2_queue;
-       struct mfc_ctx *ctx = vq->drv_priv;
-       int ret;
-
-       mfc_debug_enter();
-
-       if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-               ret = mfc_check_vb_with_fmt(ctx->dst_fmt, vb);
-               if (ret < 0)
-                       return ret;
-
-               if (call_cop(ctx, init_buf_ctrls, ctx, MFC_CTRL_TYPE_DST,
-                                       vb->index) < 0)
-                       mfc_err_ctx("failed in init_buf_ctrls\n");
-
-       } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
-               ret = mfc_check_vb_with_fmt(ctx->src_fmt, vb);
-               if (ret < 0)
-                       return ret;
-
-               if (call_cop(ctx, init_buf_ctrls, ctx, MFC_CTRL_TYPE_SRC,
-                                       vb->index) < 0)
-                       mfc_err_ctx("failed in init_buf_ctrls\n");
-       } else {
-               mfc_err_ctx("inavlid queue type: %d\n", vq->type);
-               return -EINVAL;
-       }
-
-       mfc_debug_leave();
-
-       return 0;
-}
-
-static int mfc_enc_buf_prepare(struct vb2_buffer *vb)
-{
-       struct vb2_queue *vq = vb->vb2_queue;
-       struct mfc_ctx *ctx = vq->drv_priv;
-       struct mfc_enc *enc = ctx->enc_priv;
-       struct mfc_raw_info *raw;
-       unsigned int index = vb->index;
-       struct mfc_buf *buf = vb_to_mfc_buf(vb);
-       struct dma_buf *bufcon_dmabuf[MFC_MAX_PLANES];
-       int i, mem_get_count = 0;
-       size_t buf_size;
-
-       mfc_debug_enter();
-
-       if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-               buf_size = vb2_plane_size(vb, 0);
-               mfc_debug(2, "[STREAM] vb size: %lu, calc size: %u\n",
-                       buf_size, enc->dst_buf_size);
-
-               if (buf_size < enc->dst_buf_size) {
-                       mfc_err_ctx("[STREAM] size(%d) is smaller than (%d)\n",
-                                       buf_size, enc->dst_buf_size);
-                       return -EINVAL;
-               }
-
-               buf->addr[0][0] = mfc_mem_get_daddr_vb(vb, 0);
-       } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
-               raw = &ctx->raw_buf;
-               if (ctx->src_fmt->mem_planes == 1) {
-                       buf_size = vb2_plane_size(vb, 0);
-                       mfc_debug(2, "[FRAME] single plane vb size: %lu, calc size: %d\n",
-                                       buf_size, raw->total_plane_size);
-                       if (buf_size < raw->total_plane_size) {
-                               mfc_err_ctx("[FRAME] single plane size(%d) is smaller than (%d)\n",
-                                               buf_size, raw->total_plane_size);
-                               return -EINVAL;
-                       }
-               } else {
-                       for (i = 0; i < ctx->src_fmt->mem_planes; i++) {
-                               buf_size = vb2_plane_size(vb, i);
-                               mfc_debug(2, "[FRAME] plane[%d] vb size: %lu, calc size: %d\n",
-                                               i, buf_size, raw->plane_size[i]);
-                               if (buf_size < raw->plane_size[i]) {
-                                       mfc_err_ctx("[FRAME] plane[%d] size(%d) is smaller than (%d)\n",
-                                                       i, buf_size, raw->plane_size[i]);
-                                       return -EINVAL;
-                               }
-                       }
-               }
-
-               for (i = 0; i < ctx->src_fmt->mem_planes; i++) {
-                       bufcon_dmabuf[i] = dma_buf_get(vb->planes[i].m.fd);
-                       if (IS_ERR(bufcon_dmabuf[i])) {
-                               mfc_err_ctx("failed to get bufcon dmabuf\n");
-                               goto err_mem_put;
-                       }
-
-                       mem_get_count++;
-                       buf->num_bufs_in_batch = mfc_bufcon_get_buf_count(bufcon_dmabuf[i]);
-                       mfc_debug(3, "[BUFCON] num bufs in batch: %d\n", buf->num_bufs_in_batch);
-                       if (buf->num_bufs_in_batch == 0) {
-                               mfc_err_ctx("[BUFCON] bufs count couldn't be zero\n");
-                               goto err_mem_put;
-                       }
-
-                       if (buf->num_bufs_in_batch < 0)
-                               buf->num_bufs_in_batch = 0;
-
-                       if (!ctx->batch_mode && buf->num_bufs_in_batch > 0) {
-                               ctx->batch_mode = 1;
-                               mfc_debug(2, "[BUFCON] buffer batch mode enable\n");
-                       }
-
-                       if (buf->num_bufs_in_batch > 0) {
-                               if (mfc_bufcon_get_daddr(ctx, buf, bufcon_dmabuf[i], i)) {
-                                       mfc_err_ctx("[BUFCON] failed to get daddr[%d] in buffer container\n", i);
-                                       goto err_mem_put;
-                               }
-
-                               ctx->framerate = buf->num_valid_bufs * ENC_DEFAULT_CAM_CAPTURE_FPS;
-                               mfc_debug(3, "[BUFCON] framerate: %ld\n", ctx->framerate);
-
-                               dma_buf_put(bufcon_dmabuf[i]);
-                       } else {
-                               dma_addr_t start_raw;
-
-                               dma_buf_put(bufcon_dmabuf[i]);
-                               start_raw = mfc_mem_get_daddr_vb(vb, 0);
-                               if (start_raw == 0) {
-                                       mfc_err_ctx("Plane mem not allocated\n");
-                                       return -ENOMEM;
-                               }
-                               if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12N) {
-                                       buf->addr[0][0] = start_raw;
-                                       buf->addr[0][1] = NV12N_CBCR_BASE(start_raw,
-                                                       ctx->img_width,
-                                                       ctx->img_height);
-                               } else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420N) {
-                                       buf->addr[0][0] = start_raw;
-                                       buf->addr[0][1] = YUV420N_CB_BASE(start_raw,
-                                                       ctx->img_width,
-                                                       ctx->img_height);
-                                       buf->addr[0][2] = YUV420N_CR_BASE(start_raw,
-                                                       ctx->img_width,
-                                                       ctx->img_height);
-                               } else {
-                                       buf->addr[0][i] = mfc_mem_get_daddr_vb(vb, i);
-                               }
-                       }
-               }
-
-               if (call_cop(ctx, to_buf_ctrls, ctx, &ctx->src_ctrls[index]) < 0)
-                       mfc_err_ctx("failed in to_buf_ctrls\n");
-       } else {
-               mfc_err_ctx("inavlid queue type: %d\n", vq->type);
-               return -EINVAL;
-       }
-
-       mfc_debug_leave();
-       return 0;
-
-err_mem_put:
-       for (i = 0; i < mem_get_count; i++)
-               dma_buf_put(bufcon_dmabuf[i]);
-
-       return -ENOMEM;
-}
-
-static void mfc_enc_buf_finish(struct vb2_buffer *vb)
-{
-       struct vb2_queue *vq = vb->vb2_queue;
-       struct mfc_ctx *ctx = vq->drv_priv;
-       unsigned int index = vb->index;
-
-
-       if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-               if (call_cop(ctx, to_ctx_ctrls, ctx, &ctx->dst_ctrls[index]) < 0)
-                       mfc_err_ctx("failed in to_ctx_ctrls\n");
-       } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
-               if (call_cop(ctx, to_ctx_ctrls, ctx, &ctx->src_ctrls[index]) < 0)
-                       mfc_err_ctx("failed in to_ctx_ctrls\n");
-       }
-}
-
-static void mfc_enc_buf_cleanup(struct vb2_buffer *vb)
-{
-       struct vb2_queue *vq = vb->vb2_queue;
-       struct mfc_ctx *ctx = vq->drv_priv;
-       unsigned int index = vb->index;
-
-       mfc_debug_enter();
-
-       if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-               if (call_cop(ctx, cleanup_buf_ctrls, ctx,
-                                       MFC_CTRL_TYPE_DST, index) < 0)
-                       mfc_err_ctx("failed in cleanup_buf_ctrls\n");
-       } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
-               if (call_cop(ctx, cleanup_buf_ctrls, ctx,
-                                       MFC_CTRL_TYPE_SRC, index) < 0)
-                       mfc_err_ctx("failed in cleanup_buf_ctrls\n");
-       } else {
-               mfc_err_ctx("mfc_enc_buf_cleanup: unknown queue type\n");
-       }
-
-       mfc_debug_leave();
-}
-
-static int mfc_enc_start_streaming(struct vb2_queue *q, unsigned int count)
-{
-       struct mfc_ctx *ctx = q->drv_priv;
-       struct mfc_dev *dev = ctx->dev;
-
-       /* If context is ready then dev = work->data;schedule it to run */
-       if (mfc_enc_ctx_ready(ctx)) {
-               mfc_set_bit(ctx->num, &dev->work_bits);
-       }
-
-       mfc_try_run(dev);
-
-       return 0;
-}
-
-static void mfc_enc_stop_streaming(struct vb2_queue *q)
-{
-       struct mfc_ctx *ctx = q->drv_priv;
-       struct mfc_dev *dev = ctx->dev;
-       int index = 0;
-       int aborted = 0;
-       int ret = 0;
-
-       mfc_info_ctx("enc stop_streaming is called, hwlock : %d, type : %d\n",
-                               test_bit(ctx->num, &dev->hwlock.bits), q->type);
-       MFC_TRACE_CTX("** ENC streamoff(type:%d)\n", q->type);
-
-       /* If a H/W operation is in progress, wait for it complete */
-       if (need_to_wait_nal_abort(ctx)) {
-               if (mfc_wait_for_done_ctx(ctx, MFC_REG_R2H_CMD_NAL_ABORT_RET)) {
-                       mfc_err_ctx("time out during nal abort\n");
-                       mfc_cleanup_work_bit_and_try_run(ctx);
-               }
-               aborted = 1;
-       }
-       MFC_TRACE_CTX_HWLOCK("**ENC streamoff(type:%d)\n", q->type);
-       ret = mfc_get_hwlock_ctx(ctx);
-       if (ret < 0) {
-               mfc_err_ctx("Failed to get hwlock\n");
-               return;
-       }
-
-       if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-               mfc_cleanup_enc_dst_queue(ctx);
-
-               while (index < MFC_MAX_BUFFERS) {
-                       index = find_next_bit(&ctx->dst_ctrls_avail,
-                                       MFC_MAX_BUFFERS, index);
-                       if (index < MFC_MAX_BUFFERS)
-                               call_cop(ctx, reset_buf_ctrls, &ctx->dst_ctrls[index]);
-                       index++;
-               }
-       } else if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
-               if (ctx->state == MFCINST_RUNNING) {
-                       mfc_change_state(ctx, MFCINST_FINISHING);
-                       mfc_set_bit(ctx->num, &dev->work_bits);
-
-                       while (mfc_get_buf(&ctx->buf_queue_lock, &ctx->dst_buf_queue, MFC_BUF_NO_TOUCH_USED)) {
-                               ret = mfc_just_run(dev, ctx->num);
-                               if (ret) {
-                                       mfc_err_ctx("Failed to run MFC\n");
-                                       break;
-                               }
-                               if (mfc_wait_for_done_ctx(ctx, MFC_REG_R2H_CMD_FRAME_DONE_RET)) {
-                                       mfc_err_ctx("Waiting for LAST_SEQ timed out\n");
-                                       break;
-                               }
-                               if (ctx->state == MFCINST_RUNNING) {
-                                       mfc_debug(2, "all encoded buffers out\n");
-                                       break;
-                               }
-                       }
-               }
-
-               mfc_move_all_bufs(&ctx->buf_queue_lock, &ctx->src_buf_queue,
-                               &ctx->ref_buf_queue, MFC_QUEUE_ADD_BOTTOM);
-               mfc_cleanup_enc_src_queue(ctx);
-
-               while (index < MFC_MAX_BUFFERS) {
-                       index = find_next_bit(&ctx->src_ctrls_avail,
-                                       MFC_MAX_BUFFERS, index);
-                       if (index < MFC_MAX_BUFFERS)
-                               call_cop(ctx, reset_buf_ctrls, &ctx->src_ctrls[index]);
-                       index++;
-               }
-       }
-
-       if (aborted || ctx->state == MFCINST_FINISHING)
-               mfc_change_state(ctx, MFCINST_RUNNING);
-
-       mfc_debug(2, "buffer cleanup is done in stop_streaming, type : %d\n", q->type);
-
-       mfc_clear_bit(ctx->num, &dev->work_bits);
-       mfc_release_hwlock_ctx(ctx);
-
-       if (mfc_is_work_to_do(dev))
-               queue_work(dev->butler_wq, &dev->butler_work);
-}
-
-static void mfc_enc_buf_queue(struct vb2_buffer *vb)
-{
-       struct vb2_queue *vq = vb->vb2_queue;
-       struct mfc_ctx *ctx = vq->drv_priv;
-       struct mfc_dev *dev = ctx->dev;
-       struct mfc_buf *buf = vb_to_mfc_buf(vb);
-       int i;
-
-       mfc_debug_enter();
-
-       buf->next_index = 0;
-       buf->done_index = 0;
-
-       if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-               mfc_debug(2, "[BUFINFO] ctx[%d] add dst index: %d, addr: 0x%08llx\n",
-                               ctx->num, vb->index, buf->addr[0][0]);
-
-               /* Mark destination as available for use by MFC */
-               mfc_add_tail_buf(&ctx->buf_queue_lock, &ctx->dst_buf_queue, buf);
-       } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
-               for (i = 0; i < ctx->src_fmt->mem_planes; i++)
-                       mfc_debug(2, "[BUFINFO] ctx[%d] add src index: %d, addr[%d]: 0x%08llx\n",
-                                       ctx->num, vb->index, i, buf->addr[0][i]);
-               mfc_add_tail_buf(&ctx->buf_queue_lock, &ctx->src_buf_queue, buf);
-
-               if (debug_ts == 1)
-                       mfc_info_ctx("[TS] framerate: %ld, timestamp: %lld\n",
-                                       ctx->framerate, buf->vb.vb2_buf.timestamp);
-
-               mfc_qos_update_last_framerate(ctx, buf->vb.vb2_buf.timestamp);
-               mfc_qos_update_framerate(ctx);
-       } else {
-               mfc_err_ctx("unsupported buffer type (%d)\n", vq->type);
-       }
-
-       if (mfc_enc_ctx_ready(ctx)) {
-               mfc_set_bit(ctx->num, &dev->work_bits);
-       }
-       mfc_try_run(dev);
-
-       mfc_debug_leave();
-}
-
-struct vb2_ops mfc_enc_qops = {
-       .queue_setup            = mfc_enc_queue_setup,
-       .wait_prepare           = mfc_enc_unlock,
-       .wait_finish            = mfc_enc_lock,
-       .buf_init               = mfc_enc_buf_init,
-       .buf_prepare            = mfc_enc_buf_prepare,
-       .buf_finish             = mfc_enc_buf_finish,
-       .buf_cleanup            = mfc_enc_buf_cleanup,
-       .start_streaming        = mfc_enc_start_streaming,
-       .stop_streaming         = mfc_enc_stop_streaming,
-       .buf_queue              = mfc_enc_buf_queue,
-};
diff --git a/drivers/media/platform/exynos/mfc/mfc_hw_reg_api.c b/drivers/media/platform/exynos/mfc/mfc_hw_reg_api.c
new file mode 100644 (file)
index 0000000..4026006
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * drivers/media/platform/exynos/mfc/mfc_cal.c
+ *
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <trace/events/mfc.h>
+
+#include "mfc_hw_reg_api.h"
+#include "mfc_pm.h"
+
+/* Reset the device */
+int mfc_reset_mfc(struct mfc_dev *dev)
+{
+       int i;
+
+       mfc_debug_enter();
+
+       if (!dev) {
+               mfc_err_dev("no mfc device to run\n");
+               return -EINVAL;
+       }
+
+       /* Zero Initialization of MFC registers */
+       MFC_WRITEL(0, MFC_REG_RISC2HOST_CMD);
+       MFC_WRITEL(0, MFC_REG_HOST2RISC_CMD);
+       MFC_WRITEL(0, MFC_REG_FW_VERSION);
+
+       for (i = 0; i < MFC_REG_REG_CLEAR_COUNT; i++)
+               MFC_WRITEL(0, MFC_REG_REG_CLEAR_BEGIN + (i*4));
+
+       MFC_WRITEL(0x1FFF, MFC_REG_MFC_RESET);
+       MFC_WRITEL(0, MFC_REG_MFC_RESET);
+
+       mfc_debug_leave();
+
+       return 0;
+}
+
+void mfc_set_risc_base_addr(struct mfc_dev *dev,
+                                       enum mfc_buf_usage_type buf_type)
+{
+       struct mfc_special_buf *fw_buf;
+
+       fw_buf = &dev->fw_buf;
+
+       if (buf_type == MFCBUF_DRM)
+               fw_buf = &dev->drm_fw_buf;
+
+       MFC_WRITEL(fw_buf->daddr, MFC_REG_RISC_BASE_ADDRESS);
+       mfc_debug(2, "[MEMINFO][F/W] %s Base Address : %#x\n",
+                       buf_type == MFCBUF_DRM ? "DRM" : "NORMAL", fw_buf->daddr);
+       MFC_TRACE_DEV("%s F/W Base Address : %#x\n",
+                       buf_type == MFCBUF_DRM ? "DRM" : "NORMAL", fw_buf->daddr);
+}
+
+void mfc_cmd_host2risc(struct mfc_dev *dev, int cmd)
+{
+       mfc_debug(1, "Issue the command: %d\n", cmd);
+       MFC_TRACE_DEV(">> CMD : %d, (dev:0x%lx, bits:%lx, owned:%d, wl:%d, trans:%d)\n",
+                       cmd, dev->hwlock.dev, dev->hwlock.bits, dev->hwlock.owned_by_irq,
+                       dev->hwlock.wl_count, dev->hwlock.transfer_owner);
+
+       trace_mfc_frame_start(dev->curr_ctx, cmd, 0, 0);
+       /* Reset RISC2HOST command except nal q stop command */
+       if (cmd != MFC_REG_H2R_CMD_STOP_QUEUE)
+               MFC_WRITEL(0x0, MFC_REG_RISC2HOST_CMD);
+
+       /* Start the timeout watchdog */
+       if ((cmd != MFC_REG_H2R_CMD_NAL_QUEUE) && (cmd != MFC_REG_H2R_CMD_STOP_QUEUE))
+               mfc_watchdog_start_tick(dev);
+
+       if (dbg_enable) {
+               /* For FW debugging */
+               mfc_dbg_set_addr(dev);
+               mfc_dbg_enable(dev);
+       }
+
+       /* Issue the command */
+       MFC_WRITEL(cmd, MFC_REG_HOST2RISC_CMD);
+       MFC_WRITEL(0x1, MFC_REG_HOST2RISC_INT);
+}
+
+/* Check whether HW interrupt has occurred or not */
+int mfc_check_risc2host(struct mfc_dev *dev)
+{
+       if (mfc_pm_get_pwr_ref_cnt(dev) && mfc_pm_get_clk_ref_cnt(dev)) {
+               if (MFC_READL(MFC_REG_RISC2HOST_INT))
+                       return MFC_READL(MFC_REG_RISC2HOST_CMD);
+               else
+                       return 0;
+       }
+
+       return 0;
+}
diff --git a/drivers/media/platform/exynos/mfc/mfc_hw_reg_api.h b/drivers/media/platform/exynos/mfc/mfc_hw_reg_api.h
new file mode 100644 (file)
index 0000000..9d1245d
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * drivers/media/platform/exynos/mfc/mfc_hw_reg_api.h
+ *
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __MFC_HW_REG_API_H
+#define __MFC_HW_REG_API_H __FILE__
+
+#include "mfc_reg_api.h"
+
+#include "mfc_common.h"
+
+#include "mfc_utils.h"
+
+#define mfc_get_int_reason()   (MFC_READL(MFC_REG_RISC2HOST_CMD)               \
+                                               & MFC_REG_RISC2HOST_CMD_MASK)
+#define mfc_clear_int_sfr()                            \
+               do {                                                    \
+                       MFC_WRITEL(0, MFC_REG_RISC2HOST_CMD);   \
+                       MFC_WRITEL(0, MFC_REG_RISC2HOST_INT);   \
+               } while (0)
+
+static inline int mfc_stop_bus(struct mfc_dev *dev)
+{
+       unsigned int status;
+       unsigned long timeout;
+
+       /* Reset */
+       MFC_WRITEL(0x1, MFC_REG_MFC_BUS_RESET_CTRL);
+
+       timeout = jiffies + msecs_to_jiffies(MFC_BW_TIMEOUT);
+       /* Check bus status */
+       do {
+               if (time_after(jiffies, timeout)) {
+                       mfc_err_dev("Timeout while resetting MFC.\n");
+                       return -EIO;
+               }
+               status = MFC_READL(MFC_REG_MFC_BUS_RESET_CTRL);
+       } while ((status & 0x2) == 0);
+
+       return 0;
+}
+
+static inline void mfc_start_bus(struct mfc_dev *dev)
+{
+       int val;
+
+       val = MFC_READL(MFC_REG_MFC_BUS_RESET_CTRL);
+       val &= ~(0x1);
+       MFC_WRITEL(val, MFC_REG_MFC_BUS_RESET_CTRL);
+}
+
+static inline void mfc_risc_on(struct mfc_dev *dev)
+{
+       mfc_clean_dev_int_flags(dev);
+
+       MFC_WRITEL(0x1, MFC_REG_RISC_ON);
+       MFC_WRITEL(0x0, MFC_REG_MFC_OFF);
+       mfc_debug(1, "RISC_ON\n");
+       MFC_TRACE_DEV(">> RISC ON\n");
+}
+
+static inline void mfc_risc_off(struct mfc_dev *dev)
+{
+       unsigned int status;
+       unsigned long timeout;
+
+       timeout = jiffies + msecs_to_jiffies(MFC_BW_TIMEOUT);
+       /* Check pending status */
+       do {
+               if (time_after(jiffies, timeout)) {
+                       mfc_err_dev("Timeout while pendng clear\n");
+                       mfc_err_dev("MFC access pending state: %#x\n", status);
+                       mfc_err_dev("MFC access pending R: %#x, W: %#x\n",
+                                       MFC_READL(MFC_REG_MFC_RPEND),
+                                       MFC_READL(MFC_REG_MFC_WPEND));
+                       break;
+               }
+               status = MFC_READL(MFC_REG_MFC_BUS_STATUS);
+       } while (status != 0);
+
+       MFC_WRITEL(0x0, MFC_REG_RISC_ON);
+}
+
+static inline void mfc_mfc_off(struct mfc_dev *dev)
+{
+       mfc_info_dev("MFC h/w state: %d\n",
+                       MFC_READL(MFC_REG_MFC_STATE) & 0x7);
+       MFC_WRITEL(0x1, MFC_REG_MFC_OFF);
+}
+
+static inline void mfc_enable_all_clocks(struct mfc_dev *dev)
+{
+       /* Enable all FW clock gating */
+       MFC_WRITEL(0xFFFFFFFF, MFC_REG_MFC_FW_CLOCK);
+}
+
+int mfc_reset_mfc(struct mfc_dev *dev);
+void mfc_set_risc_base_addr(struct mfc_dev *dev,
+                               enum mfc_buf_usage_type buf_type);
+void mfc_cmd_host2risc(struct mfc_dev *dev, int cmd);
+int mfc_check_risc2host(struct mfc_dev *dev);
+
+#endif /* __MFC_HW_REG_API_H */
index 0821b1834babb38e84fb626611e07d39ff0836dd..f67ba97070c0e386c1cecf1fce634716b0eacf74 100644 (file)
@@ -20,8 +20,8 @@
 #include "mfc_inst.h"
 #include "mfc_pm.h"
 #include "mfc_cmd.h"
-#include "mfc_cal.h"
-#include "mfc_reg.h"
+#include "mfc_reg_api.h"
+#include "mfc_hw_reg_api.h"
 
 #include "mfc_queue.h"
 #include "mfc_utils.h"
index 8e130879aba37c0f766056dc37a0dd72de4396e7..2e37a49f7f3f72288bde4cf43334925b67139a33 100644 (file)
@@ -14,9 +14,9 @@
 
 #include "mfc_cmd.h"
 #include "mfc_enc_param.h"
-#include "mfc_cal.h"
 #include "mfc_perf_measure.h"
-#include "mfc_reg.h"
+#include "mfc_reg_api.h"
+#include "mfc_hw_reg_api.h"
 
 #include "mfc_utils.h"
 
diff --git a/drivers/media/platform/exynos/mfc/mfc_irq.c b/drivers/media/platform/exynos/mfc/mfc_irq.c
deleted file mode 100644 (file)
index 680ce74..0000000
+++ /dev/null
@@ -1,1564 +0,0 @@
-/*
- * drivers/media/platform/exynos/mfc/mfc_irq.c
- *
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include "mfc_irq.h"
-
-#include "mfc_hwlock.h"
-#include "mfc_nal_q.h"
-#include "mfc_otf.h"
-#include "mfc_opr.h"
-#include "mfc_sync.h"
-
-#include "mfc_pm.h"
-#include "mfc_cal.h"
-#include "mfc_perf_measure.h"
-#include "mfc_reg.h"
-#include "mfc_mmcache.h"
-
-#include "mfc_qos.h"
-#include "mfc_queue.h"
-#include "mfc_buf.h"
-#include "mfc_mem.h"
-
-static void __mfc_handle_black_bar_info(struct mfc_dev *dev, struct mfc_ctx *ctx)
-{
-       struct v4l2_rect new_black_bar;
-       int black_bar_info;
-       struct mfc_dec *dec = ctx->dec_priv;
-
-       black_bar_info = mfc_get_black_bar_detection();
-       mfc_debug(3, "[BLACKBAR] type: %#x\n", black_bar_info);
-
-       if (black_bar_info == MFC_REG_DISP_STATUS_BLACK_BAR) {
-               new_black_bar.left = mfc_get_black_bar_pos_x();
-               new_black_bar.top = mfc_get_black_bar_pos_y();
-               new_black_bar.width = mfc_get_black_bar_image_w();
-               new_black_bar.height = mfc_get_black_bar_image_h();
-       } else if (black_bar_info == MFC_REG_DISP_STATUS_BLACK_SCREEN) {
-               new_black_bar.left = -1;
-               new_black_bar.top = -1;
-               new_black_bar.width = ctx->img_width;
-               new_black_bar.height = ctx->img_height;
-       } else if (black_bar_info == MFC_REG_DISP_STATUS_NOT_DETECTED) {
-               new_black_bar.left = 0;
-               new_black_bar.top = 0;
-               new_black_bar.width = ctx->img_width;
-               new_black_bar.height = ctx->img_height;
-       } else {
-               mfc_err_ctx("[BLACKBAR] Not supported type: %#x\n", black_bar_info);
-               dec->black_bar_updated = 0;
-               return;
-       }
-
-       if ((new_black_bar.left == dec->black_bar.left) &&
-                       (new_black_bar.top == dec->black_bar.top) &&
-                       (new_black_bar.width == dec->black_bar.width) &&
-                       (new_black_bar.height == dec->black_bar.height)) {
-               mfc_debug(4, "[BLACKBAR] information was not changed\n");
-               dec->black_bar_updated = 0;
-               return;
-       }
-
-       dec->black_bar = new_black_bar;
-       dec->black_bar_updated = 1;
-}
-
-static unsigned int __mfc_handle_frame_field(struct mfc_ctx *ctx)
-{
-       struct mfc_dev *dev = ctx->dev;
-       unsigned int interlace_type = 0, is_interlace = 0, is_mbaff = 0;
-       unsigned int field;
-
-       if (CODEC_INTERLACED(ctx))
-               is_interlace = mfc_is_interlace_picture();
-
-       if (CODEC_MBAFF(ctx))
-               is_mbaff = mfc_is_mbaff_picture();
-
-       if (is_interlace) {
-               interlace_type = mfc_get_interlace_type();
-               if (interlace_type)
-                       field = V4L2_FIELD_INTERLACED_TB;
-               else
-                       field = V4L2_FIELD_INTERLACED_BT;
-       } else if (is_mbaff) {
-               field = V4L2_FIELD_INTERLACED_TB;
-       } else {
-               field = V4L2_FIELD_NONE;
-       }
-
-       mfc_debug(2, "[INTERLACE] is_interlace: %d (type : %d), is_mbaff: %d, field: 0x%#x\n",
-                       is_interlace, interlace_type, is_mbaff, field);
-
-       return field;
-}
-
-static void __mfc_handle_frame_all_extracted(struct mfc_ctx *ctx)
-{
-       struct mfc_dec *dec = ctx->dec_priv;
-       struct mfc_buf *dst_mb;
-       int index, i, is_first = 1;
-
-       mfc_debug(2, "Decided to finish\n");
-       ctx->sequence++;
-
-       while (1) {
-               dst_mb = mfc_get_del_buf(&ctx->buf_queue_lock, &ctx->dst_buf_queue, MFC_BUF_NO_TOUCH_USED);
-               if (!dst_mb)
-                       break;
-
-               mfc_debug(2, "Cleaning up buffer: %d\n",
-                                         dst_mb->vb.vb2_buf.index);
-
-               index = dst_mb->vb.vb2_buf.index;
-
-               for (i = 0; i < ctx->dst_fmt->mem_planes; i++)
-                       vb2_set_plane_payload(&dst_mb->vb.vb2_buf, i, 0);
-
-               dst_mb->vb.sequence = (ctx->sequence++);
-               dst_mb->vb.field = __mfc_handle_frame_field(ctx);
-               dst_mb->vb.reserved2 = 0;
-
-               clear_bit(dst_mb->vb.vb2_buf.index, &dec->available_dpb);
-
-               if (call_cop(ctx, get_buf_ctrls_val, ctx, &ctx->dst_ctrls[index]) < 0)
-                       mfc_err_ctx("failed in get_buf_ctrls_val\n");
-
-               if (is_first) {
-                       call_cop(ctx, get_buf_update_val, ctx,
-                               &ctx->dst_ctrls[index],
-                               V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG,
-                               dec->stored_tag);
-                       is_first = 0;
-               } else {
-                       call_cop(ctx, get_buf_update_val, ctx,
-                               &ctx->dst_ctrls[index],
-                               V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG,
-                               DEFAULT_TAG);
-                       call_cop(ctx, get_buf_update_val, ctx,
-                               &ctx->dst_ctrls[index],
-                               V4L2_CID_MPEG_VIDEO_H264_SEI_FP_AVAIL,
-                               0);
-               }
-
-               vb2_buffer_done(&dst_mb->vb.vb2_buf, VB2_BUF_STATE_DONE);
-
-               /* decoder dst buffer CFW UNPROT */
-               if (ctx->is_drm)
-                       mfc_raw_unprotect(ctx, dst_mb, index);
-
-               mfc_debug(2, "Cleaned up buffer: %d\n", index);
-       }
-
-       mfc_handle_force_change_status(ctx);
-       mfc_debug(2, "After cleanup\n");
-}
-
-static void __mfc_handle_frame_copy_timestamp(struct mfc_ctx *ctx)
-{
-       struct mfc_dev *dev = ctx->dev;
-       struct mfc_buf *ref_mb, *src_mb;
-       dma_addr_t dec_y_addr;
-
-       dec_y_addr = (dma_addr_t)mfc_get_dec_y_addr();
-
-       /* Get the source buffer */
-       src_mb = mfc_get_buf(&ctx->buf_queue_lock, &ctx->src_buf_queue, MFC_BUF_NO_TOUCH_USED);
-       if (!src_mb) {
-               mfc_err_dev("[TS] no src buffers\n");
-               return;
-       }
-
-       ref_mb = mfc_find_buf(&ctx->buf_queue_lock, &ctx->ref_buf_queue, dec_y_addr);
-       if (ref_mb)
-               ref_mb->vb.vb2_buf.timestamp = src_mb->vb.vb2_buf.timestamp;
-}
-
-static void __mfc_handle_frame_output_move(struct mfc_ctx *ctx,
-               dma_addr_t dspl_y_addr, unsigned int released_flag)
-{
-       struct mfc_dev *dev = ctx->dev;
-       struct mfc_dec *dec = ctx->dec_priv;
-       struct mfc_buf *ref_mb;
-       int index;
-
-       ref_mb = mfc_find_move_buf(&ctx->buf_queue_lock,
-                       &ctx->dst_buf_queue, &ctx->ref_buf_queue, dspl_y_addr, released_flag);
-       if (ref_mb) {
-               index = ref_mb->vb.vb2_buf.index;
-
-               /* Check if this is the buffer we're looking for */
-               mfc_debug(2, "[DPB] Found buf[%d] 0x%08llx, looking for disp addr 0x%08llx\n",
-                               index, ref_mb->addr[0][0], dspl_y_addr);
-
-               if (released_flag & (1 << index)) {
-                       dec->available_dpb &= ~(1 << index);
-                       released_flag &= ~(1 << index);
-                       mfc_debug(2, "[DPB] Corrupted frame(%d), it will be re-used(release)\n",
-                                       mfc_get_warn(mfc_get_int_err()));
-               } else {
-                       dec->err_reuse_flag |= 1 << index;
-                       mfc_debug(2, "[DPB] Corrupted frame(%d), it will be re-used(not released)\n",
-                                       mfc_get_warn(mfc_get_int_err()));
-               }
-               dec->dynamic_used |= released_flag;
-       }
-}
-
-static void __mfc_handle_frame_output_del(struct mfc_ctx *ctx,
-               unsigned int err, unsigned int released_flag)
-{
-       struct mfc_dev *dev = ctx->dev;
-       struct mfc_dec *dec = ctx->dec_priv;
-       struct mfc_raw_info *raw = &ctx->raw_buf;
-       struct mfc_buf *ref_mb;
-       dma_addr_t dspl_y_addr;
-       unsigned int frame_type;
-       unsigned int dst_frame_status;
-       unsigned int is_video_signal_type = 0, is_colour_description = 0;
-       unsigned int is_content_light = 0, is_display_colour = 0;
-       unsigned int i, index;
-
-       if (MFC_FEATURE_SUPPORT(dev, dev->pdata->color_aspect_dec)) {
-               is_video_signal_type = mfc_get_video_signal_type();
-               is_colour_description = mfc_get_colour_description();
-       }
-
-       if (MFC_FEATURE_SUPPORT(dev, dev->pdata->static_info_dec)) {
-               is_content_light = mfc_get_sei_avail_content_light();
-               is_display_colour = mfc_get_sei_avail_mastering_display();
-       }
-
-       if (MFC_FEATURE_SUPPORT(dev, dev->pdata->black_bar) && dec->detect_black_bar)
-               __mfc_handle_black_bar_info(dev, ctx);
-       else
-               dec->black_bar_updated = 0;
-
-       if (dec->immediate_display == 1) {
-               dspl_y_addr = (dma_addr_t)mfc_get_dec_y_addr();
-               frame_type = mfc_get_dec_frame_type();
-       } else {
-               dspl_y_addr = (dma_addr_t)mfc_get_disp_y_addr();
-               frame_type = mfc_get_disp_frame_type();
-       }
-
-       ref_mb = mfc_find_del_buf(&ctx->buf_queue_lock,
-                       &ctx->ref_buf_queue, dspl_y_addr);
-       if (ref_mb) {
-               index = ref_mb->vb.vb2_buf.index;
-               /* Check if this is the buffer we're looking for */
-               mfc_debug(2, "[BUFINFO][DPB] ctx[%d] get dst index: %d, addr[0]: 0x%08llx\n",
-                               ctx->num, index, ref_mb->addr[0][0]);
-
-               ref_mb->vb.sequence = ctx->sequence;
-               ref_mb->vb.field = __mfc_handle_frame_field(ctx);
-
-               /* Set reserved2 bits in order to inform SEI information */
-               ref_mb->vb.reserved2 = 0;
-
-               if (is_content_light) {
-                       ref_mb->vb.reserved2 |= (1 << 0);
-                       mfc_debug(2, "[HDR] content light level parsed\n");
-               }
-
-               if (is_display_colour) {
-                       ref_mb->vb.reserved2 |= (1 << 1);
-                       mfc_debug(2, "[HDR] mastering display colour parsed\n");
-               }
-
-               if (is_video_signal_type) {
-                       ref_mb->vb.reserved2 |= (1 << 4);
-                       mfc_debug(2, "[HDR] video signal type parsed\n");
-                       if (is_colour_description) {
-                               ref_mb->vb.reserved2 |= (1 << 2);
-                               mfc_debug(2, "[HDR] matrix coefficients parsed\n");
-                               ref_mb->vb.reserved2 |= (1 << 3);
-                               mfc_debug(2, "[HDR] colour description parsed\n");
-                       }
-               }
-
-               if (IS_VP9_DEC(ctx) && MFC_FEATURE_SUPPORT(dev, dev->pdata->color_aspect_dec)) {
-                       if (dec->color_space != MFC_REG_D_COLOR_UNKNOWN) {
-                               ref_mb->vb.reserved2 |= (1 << 3);
-                               mfc_debug(2, "[HDR] color space parsed\n");
-                       }
-                       ref_mb->vb.reserved2 |= (1 << 4);
-                       mfc_debug(2, "[HDR] color range parsed\n");
-               }
-
-               if (dec->black_bar_updated) {
-                       ref_mb->vb.reserved2 |= (1 << 5);
-                       mfc_debug(3, "[BLACKBAR] black bar detected\n");
-               }
-
-               if (ctx->src_fmt->mem_planes == 1) {
-                       vb2_set_plane_payload(&ref_mb->vb.vb2_buf, 0,
-                                       raw->total_plane_size);
-                       mfc_debug(5, "single plane payload: %d\n",
-                                       raw->total_plane_size);
-               } else {
-                       for (i = 0; i < ctx->src_fmt->mem_planes; i++) {
-                               vb2_set_plane_payload(&ref_mb->vb.vb2_buf, i,
-                                               raw->plane_size[i]);
-                       }
-               }
-
-               clear_bit(index, &dec->available_dpb);
-
-               ref_mb->vb.flags &= ~(V4L2_BUF_FLAG_KEYFRAME |
-                                       V4L2_BUF_FLAG_PFRAME |
-                                       V4L2_BUF_FLAG_BFRAME |
-                                       V4L2_BUF_FLAG_ERROR);
-
-               switch (frame_type) {
-                       case MFC_REG_DISPLAY_FRAME_I:
-                               ref_mb->vb.flags |= V4L2_BUF_FLAG_KEYFRAME;
-                               break;
-                       case MFC_REG_DISPLAY_FRAME_P:
-                               ref_mb->vb.flags |= V4L2_BUF_FLAG_PFRAME;
-                               break;
-                       case MFC_REG_DISPLAY_FRAME_B:
-                               ref_mb->vb.flags |= V4L2_BUF_FLAG_BFRAME;
-                               break;
-                       default:
-                               break;
-               }
-
-               if (mfc_get_warn(err)) {
-                       mfc_err_ctx("Warning for displayed frame: %d\n",
-                                       mfc_get_warn(err));
-                       ref_mb->vb.flags |= V4L2_BUF_FLAG_ERROR;
-               }
-
-               if (call_cop(ctx, get_buf_ctrls_val, ctx, &ctx->dst_ctrls[index]) < 0)
-                       mfc_err_ctx("failed in get_buf_ctrls_val\n");
-
-               mfc_handle_released_info(ctx, released_flag, index);
-
-               if (dec->immediate_display == 1) {
-                       dst_frame_status = mfc_get_dec_status();
-
-                       call_cop(ctx, get_buf_update_val, ctx,
-                                       &ctx->dst_ctrls[index],
-                                       V4L2_CID_MPEG_MFC51_VIDEO_DISPLAY_STATUS,
-                                       dst_frame_status);
-
-                       call_cop(ctx, get_buf_update_val, ctx,
-                                       &ctx->dst_ctrls[index],
-                                       V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG,
-                                       dec->stored_tag);
-
-                       dec->immediate_display = 0;
-               }
-
-               /* Update frame tag for packed PB */
-               if (CODEC_MULTIFRAME(ctx) && (dec->y_addr_for_pb == dspl_y_addr)) {
-                       call_cop(ctx, get_buf_update_val, ctx,
-                                       &ctx->dst_ctrls[index],
-                                       V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG,
-                                       dec->stored_tag);
-                       dec->y_addr_for_pb = 0;
-               }
-
-               mfc_qos_update_last_framerate(ctx, ref_mb->vb.vb2_buf.timestamp);
-               vb2_buffer_done(&ref_mb->vb.vb2_buf, mfc_get_warn(err) ?
-                               VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
-       }
-}
-
-static void __mfc_handle_frame_new(struct mfc_ctx *ctx, unsigned int err)
-{
-       struct mfc_dec *dec = ctx->dec_priv;
-       struct mfc_dev *dev = ctx->dev;
-       dma_addr_t dspl_y_addr;
-       unsigned int frame_type;
-       int mvc_view_id;
-       unsigned int prev_flag, released_flag = 0;
-
-       frame_type = mfc_get_disp_frame_type();
-       mvc_view_id = mfc_get_mvc_disp_view_id();
-
-       if (IS_H264_MVC_DEC(ctx)) {
-               if (mvc_view_id == 0)
-                       ctx->sequence++;
-       } else {
-               ctx->sequence++;
-       }
-
-       dspl_y_addr = mfc_get_disp_y_addr();
-
-       if (dec->immediate_display == 1) {
-               dspl_y_addr = (dma_addr_t)mfc_get_dec_y_addr();
-               frame_type = mfc_get_dec_frame_type();
-       }
-
-       mfc_debug(2, "[FRAME] frame type: %d\n", frame_type);
-
-       /* If frame is same as previous then skip and do not dequeue */
-       if (frame_type == MFC_REG_DISPLAY_FRAME_NOT_CODED)
-               if (!CODEC_NOT_CODED(ctx))
-                       return;
-
-       prev_flag = dec->dynamic_used;
-       dec->dynamic_used = mfc_get_dec_used_flag();
-       released_flag = prev_flag & (~dec->dynamic_used);
-
-       mfc_debug(2, "[DPB] Used flag: old = %08x, new = %08x, Released buffer = %08x\n",
-                       prev_flag, dec->dynamic_used, released_flag);
-
-       /* decoder dst buffer CFW UNPROT */
-       mfc_unprotect_released_dpb(ctx, released_flag);
-
-       if ((IS_VC1_RCV_DEC(ctx) &&
-               mfc_get_warn(err) == MFC_REG_ERR_SYNC_POINT_NOT_RECEIVED) ||
-               (mfc_get_warn(err) == MFC_REG_ERR_BROKEN_LINK))
-               __mfc_handle_frame_output_move(ctx, dspl_y_addr, released_flag);
-       else
-               __mfc_handle_frame_output_del(ctx, err, released_flag);
-}
-
-static void __mfc_handle_frame_error(struct mfc_ctx *ctx,
-               unsigned int reason, unsigned int err)
-{
-       struct mfc_dec *dec;
-       struct mfc_buf *src_mb;
-       unsigned int index;
-
-       if (ctx->type == MFCINST_ENCODER) {
-               mfc_err_ctx("Encoder Interrupt Error: %d\n", err);
-               return;
-       }
-
-       dec = ctx->dec_priv;
-       if (!dec) {
-               mfc_err_dev("no mfc decoder to run\n");
-               return;
-       }
-
-       mfc_err_ctx("Interrupt Error: %d\n", err);
-
-       /* Get the source buffer */
-       src_mb = mfc_get_del_buf(&ctx->buf_queue_lock, &ctx->src_buf_queue, MFC_BUF_NO_TOUCH_USED);
-
-       if (!src_mb) {
-               mfc_err_dev("no src buffers\n");
-       } else {
-               index = src_mb->vb.vb2_buf.index;
-               if (call_cop(ctx, recover_buf_ctrls_val, ctx, &ctx->src_ctrls[index]) < 0)
-                       mfc_err_ctx("failed in recover_buf_ctrls_val\n");
-
-               mfc_debug(2, "MFC needs next buffer\n");
-               dec->consumed = 0;
-
-               if (call_cop(ctx, get_buf_ctrls_val, ctx, &ctx->src_ctrls[index]) < 0)
-                       mfc_err_ctx("failed in get_buf_ctrls_val\n");
-
-               /* decoder src buffer CFW UNPROT */
-               if (ctx->is_drm)
-                       mfc_stream_unprotect(ctx, src_mb, index);
-
-               vb2_buffer_done(&src_mb->vb.vb2_buf, VB2_BUF_STATE_ERROR);
-       }
-
-       mfc_debug(2, "Assesing whether this context should be run again\n");
-}
-
-static void __mfc_handle_ref_frame(struct mfc_ctx *ctx)
-{
-       struct mfc_dev *dev = ctx->dev;
-       struct mfc_dec *dec = ctx->dec_priv;
-       struct mfc_buf *dst_mb;
-       dma_addr_t dec_addr;
-
-       dec_addr = (dma_addr_t)mfc_get_dec_y_addr();
-
-       /* Try to search decoded address in whole dst queue */
-       dst_mb = mfc_find_move_buf_used(&ctx->buf_queue_lock,
-                       &ctx->ref_buf_queue, &ctx->dst_buf_queue, dec_addr);
-       if (dst_mb) {
-               mfc_debug(2, "[DPB] Found in dst queue = 0x%08llx, buf = 0x%08llx\n",
-                               dec_addr, dst_mb->addr[0][0]);
-
-               if (!(dec->dynamic_set & mfc_get_dec_used_flag()))
-                       dec->dynamic_used |= dec->dynamic_set;
-       } else {
-               mfc_debug(2, "[DPB] Can't find buffer for addr = 0x%08llx\n", dec_addr);
-       }
-}
-
-static void __mfc_handle_reuse_buffer(struct mfc_ctx *ctx)
-{
-       struct mfc_dev *dev = ctx->dev;
-       struct mfc_dec *dec = ctx->dec_priv;
-       unsigned int prev_flag, released_flag = 0;
-       int i;
-
-       prev_flag = dec->dynamic_used;
-       dec->dynamic_used = mfc_get_dec_used_flag();
-       released_flag = prev_flag & (~dec->dynamic_used);
-
-       if (!released_flag)
-               return;
-
-       /* Reuse not referenced buf anymore */
-       for (i = 0; i < MFC_MAX_DPBS; i++)
-               if (released_flag & (1 << i))
-                       if (mfc_move_reuse_buffer(ctx, i))
-                               released_flag &= ~(1 << i);
-
-       /* Not reused buffer should be released when there is a display frame */
-       dec->dec_only_release_flag |= released_flag;
-       for (i = 0; i < MFC_MAX_DPBS; i++)
-               if (released_flag & (1 << i))
-                       clear_bit(i, &dec->available_dpb);
-}
-
-static void __mfc_handle_frame_input(struct mfc_ctx *ctx, unsigned int err)
-{
-       struct mfc_dev *dev = ctx->dev;
-       struct mfc_dec *dec = ctx->dec_priv;
-       struct mfc_buf *src_mb;
-       unsigned int index;
-       int deleted = 0;
-       unsigned long consumed;
-
-       consumed = dec->consumed + mfc_get_consumed_stream();
-
-       if (mfc_get_err(err) == MFC_REG_ERR_NON_PAIRED_FIELD) {
-               /*
-                * For non-paired field, the same buffer need to be
-                * resubmitted and the consumed stream will be 0
-                */
-               mfc_debug(2, "Not paired field. Running again the same buffer\n");
-               return;
-       }
-
-       /* Get the source buffer */
-       src_mb = mfc_get_del_if_consumed(ctx, &ctx->src_buf_queue,
-                       mfc_get_consumed_stream(), STUFF_BYTE, err, &deleted);
-       if (!src_mb) {
-               mfc_err_dev("no src buffers\n");
-               return;
-       }
-
-       index = src_mb->vb.vb2_buf.index;
-       mfc_debug(2, "[BUFINFO] ctx[%d] get src index: %d, addr: 0x%08llx\n",
-                       ctx->num, index, src_mb->addr[0][0]);
-
-       if (!deleted) {
-               /* Run MFC again on the same buffer */
-               mfc_debug(2, "[MULTIFRAME] Running again the same buffer\n");
-
-               if (CODEC_MULTIFRAME(ctx))
-                       dec->y_addr_for_pb = (dma_addr_t)mfc_get_dec_y_addr();
-
-               dec->consumed = consumed;
-               dec->remained_size = src_mb->vb.vb2_buf.planes[0].bytesused
-                                       - dec->consumed;
-               dec->has_multiframe = 1;
-
-               MFC_TRACE_CTX("** consumed:%ld, remained:%ld, addr:0x%08llx\n",
-                       dec->consumed, dec->remained_size, dec->y_addr_for_pb);
-               /* Do not move src buffer to done_list */
-               return;
-       }
-
-       if (call_cop(ctx, recover_buf_ctrls_val, ctx, &ctx->src_ctrls[index]) < 0)
-               mfc_err_ctx("failed in recover_buf_ctrls_val\n");
-
-       dec->consumed = 0;
-       dec->remained_size = 0;
-
-       if (call_cop(ctx, get_buf_ctrls_val, ctx, &ctx->src_ctrls[index]) < 0)
-               mfc_err_ctx("failed in get_buf_ctrls_val\n");
-
-       /* decoder src buffer CFW UNPROT */
-       if (ctx->is_drm)
-               mfc_stream_unprotect(ctx, src_mb, index);
-
-       vb2_buffer_done(&src_mb->vb.vb2_buf, VB2_BUF_STATE_DONE);
-}
-
-/* Handle frame decoding interrupt */
-static void __mfc_handle_frame(struct mfc_ctx *ctx,
-                       unsigned int reason, unsigned int err)
-{
-       struct mfc_dev *dev = ctx->dev;
-       struct mfc_dec *dec = ctx->dec_priv;
-       unsigned int dst_frame_status, sei_avail_frame_pack;
-       unsigned int res_change, need_dpb_change, need_scratch_change;
-
-       dst_frame_status = mfc_get_disp_status();
-       res_change = mfc_get_res_change();
-       need_dpb_change = mfc_get_dpb_change();
-       need_scratch_change = mfc_get_scratch_change();
-       sei_avail_frame_pack = mfc_get_sei_avail_frame_pack();
-
-       if (dec->immediate_display == 1)
-               dst_frame_status = mfc_get_dec_status();
-
-       mfc_debug(2, "[FRAME] frame status: %d\n", dst_frame_status);
-       mfc_debug(2, "[FRAME] display status: %d, type: %d, yaddr: %#x\n",
-                       mfc_get_disp_status(), mfc_get_disp_frame_type(),
-                       mfc_get_disp_y_addr());
-       mfc_debug(2, "[FRAME] decoded status: %d, type: %d, yaddr: %#x\n",
-                       mfc_get_dec_status(), mfc_get_dec_frame_type(),
-                       mfc_get_dec_y_addr());
-
-       mfc_debug(4, "[HDR] SEI available status: 0x%08x\n", mfc_get_sei_avail());
-       mfc_debug(4, "[HDR] SEI content light: 0x%08x\n", mfc_get_sei_content_light());
-       mfc_debug(4, "[HDR] SEI luminance: 0x%08x, 0x%08x white point: 0x%08x\n",
-                       mfc_get_sei_mastering0(), mfc_get_sei_mastering1(),
-                       mfc_get_sei_mastering2());
-       mfc_debug(4, "[HDR] SEI display primaries: 0x%08x, 0x%08x, 0x%08x\n",
-                       mfc_get_sei_mastering3(), mfc_get_sei_mastering4(),
-                       mfc_get_sei_mastering5());
-       mfc_debug(2, "[DPB] Used flag: old = %08x, new = %08x\n",
-                               dec->dynamic_used, mfc_get_dec_used_flag());
-
-       if (ctx->state == MFCINST_RES_CHANGE_INIT)
-               mfc_change_state(ctx, MFCINST_RES_CHANGE_FLUSH);
-
-       if (res_change) {
-               mfc_debug(2, "[DRC] Resolution change set to %d\n", res_change);
-               mfc_change_state(ctx, MFCINST_RES_CHANGE_INIT);
-               ctx->wait_state = WAIT_DECODING;
-               mfc_debug(7, "[DRC] Decoding waiting! : %d\n", ctx->wait_state);
-               return;
-       }
-
-       if (need_dpb_change || need_scratch_change)
-               mfc_debug(2, "[DRC] Interframe resolution change is not supported\n");
-
-       if (mfc_is_queue_count_same(&ctx->buf_queue_lock, &ctx->src_buf_queue, 0) &&
-               mfc_is_queue_count_same(&ctx->buf_queue_lock, &ctx->dst_buf_queue, 0)) {
-               mfc_err_dev("Queue count is zero for src and dst\n");
-               goto leave_handle_frame;
-       }
-
-       if (IS_H264_DEC(ctx) && sei_avail_frame_pack &&
-               dst_frame_status == MFC_REG_DEC_STATUS_DECODING_ONLY) {
-               mfc_debug(2, "Frame packing SEI exists for a frame\n");
-               mfc_debug(2, "Reallocate DPBs and issue init_buffer\n");
-               ctx->is_dpb_realloc = 1;
-               mfc_change_state(ctx, MFCINST_HEAD_PARSED);
-               ctx->capture_state = QUEUE_FREE;
-               ctx->wait_state = WAIT_DECODING;
-               __mfc_handle_frame_all_extracted(ctx);
-               goto leave_handle_frame;
-       }
-
-       /* All frames remaining in the buffer have been extracted  */
-       if (dst_frame_status == MFC_REG_DEC_STATUS_DECODING_EMPTY) {
-               if (ctx->state == MFCINST_RES_CHANGE_FLUSH) {
-                       struct mfc_timestamp *temp_ts = NULL;
-
-                       mfc_debug(2, "[DRC] Last frame received after resolution change\n");
-                       __mfc_handle_frame_all_extracted(ctx);
-                       mfc_change_state(ctx, MFCINST_RES_CHANGE_END);
-                       /* If there is no display frame after resolution change,
-                        * Some released frames can't be unprotected.
-                        * So, check and request unprotection in the end of DRC.
-                        */
-                       mfc_cleanup_assigned_dpb(ctx);
-
-                       /* empty the timestamp queue */
-                       while (!list_empty(&ctx->ts_list)) {
-                               temp_ts = list_entry((&ctx->ts_list)->next,
-                                               struct mfc_timestamp, list);
-                               list_del(&temp_ts->list);
-                       }
-                       ctx->ts_count = 0;
-                       ctx->ts_is_full = 0;
-                       mfc_qos_reset_last_framerate(ctx);
-                       mfc_qos_set_framerate(ctx, DEC_DEFAULT_FPS);
-
-                       goto leave_handle_frame;
-               } else {
-                       __mfc_handle_frame_all_extracted(ctx);
-               }
-       }
-
-       if (mfc_get_num_of_tile() >= 4)
-               dec->num_of_tile_over_4 = 1;
-
-       switch (dst_frame_status) {
-       case MFC_REG_DEC_STATUS_DECODING_DISPLAY:
-               __mfc_handle_ref_frame(ctx);
-               break;
-       case MFC_REG_DEC_STATUS_DECODING_ONLY:
-               __mfc_handle_ref_frame(ctx);
-               /*
-                * Some cases can have many decoding only frames like VP9
-                * alt-ref frame. So need handling release buffer
-                * because of DPB full.
-                */
-               __mfc_handle_reuse_buffer(ctx);
-               break;
-       default:
-               break;
-       }
-
-       if (mfc_dec_status_decoding(dst_frame_status))
-               __mfc_handle_frame_copy_timestamp(ctx);
-
-       /* A frame has been decoded and is in the buffer  */
-       if (mfc_dec_status_display(dst_frame_status))
-               __mfc_handle_frame_new(ctx, err);
-       else
-               mfc_debug(2, "No frame decode\n");
-
-       /* Mark source buffer as complete */
-       if (dst_frame_status != MFC_REG_DEC_STATUS_DISPLAY_ONLY)
-               __mfc_handle_frame_input(ctx, err);
-
-leave_handle_frame:
-       mfc_debug(2, "Assesing whether this context should be run again\n");
-}
-
-static void __mfc_handle_stream_copy_timestamp(struct mfc_ctx *ctx, struct mfc_buf *src_mb)
-{
-       struct mfc_dev *dev;
-       struct mfc_enc *enc = ctx->enc_priv;
-       struct mfc_enc_params *p = &enc->params;
-       struct mfc_buf *dst_mb;
-       u32 interval;
-       u64 start_timestamp;
-       u64 new_timestamp;
-
-       if (!ctx) {
-               mfc_err_dev("[BUFCON][TS] no mfc context to run\n");
-               return;
-       }
-
-       dev = ctx->dev;
-       if (!dev) {
-               mfc_err_dev("[BUFCON][TS] no device to run\n");
-               return;
-       }
-
-       start_timestamp = src_mb->vb.vb2_buf.timestamp;
-       interval = NSEC_PER_SEC / p->rc_framerate;
-       if (debug_ts == 1)
-               mfc_info_ctx("[BUFCON][TS] %dfps, start timestamp: %lld, base interval: %d\n",
-                               p->rc_framerate, start_timestamp, interval);
-
-       new_timestamp = start_timestamp + (interval * src_mb->done_index);
-       if (debug_ts == 1)
-               mfc_info_ctx("[BUFCON][TS] new timestamp: %lld, interval: %d\n",
-                               new_timestamp, interval * src_mb->done_index);
-
-       /* Get the destination buffer */
-       dst_mb = mfc_get_buf(&ctx->buf_queue_lock, &ctx->dst_buf_queue, MFC_BUF_NO_TOUCH_USED);
-       if (dst_mb)
-               dst_mb->vb.vb2_buf.timestamp = new_timestamp;
-}
-
-static void __mfc_handle_stream_input(struct mfc_ctx *ctx)
-{
-       struct mfc_raw_info *raw;
-       struct mfc_buf *ref_mb, *src_mb;
-       dma_addr_t enc_addr[3] = { 0, 0, 0 };
-       int i, found_in_src_queue = 0;
-       unsigned int index;
-
-       raw = &ctx->raw_buf;
-
-       mfc_get_enc_frame_buffer(ctx, &enc_addr[0], raw->num_planes);
-       if (enc_addr[0] == 0) {
-               mfc_debug(3, "no encoded src\n");
-               goto move_buf;
-       }
-       for (i = 0; i < raw->num_planes; i++)
-               mfc_debug(2, "[BUFINFO] ctx[%d] get src addr[%d]: 0x%08llx\n",
-                               ctx->num, i, enc_addr[i]);
-
-       if (IS_BUFFER_BATCH_MODE(ctx)) {
-               src_mb = mfc_find_first_buf(&ctx->buf_queue_lock,
-                               &ctx->src_buf_queue, enc_addr[0]);
-               if (src_mb) {
-                       found_in_src_queue = 1;
-
-                       __mfc_handle_stream_copy_timestamp(ctx, src_mb);
-                       src_mb->done_index++;
-                       mfc_debug(4, "[BUFCON] batch buf done_index: %d\n", src_mb->done_index);
-
-                       index = src_mb->vb.vb2_buf.index;
-
-                       if (call_cop(ctx, recover_buf_ctrls_val, ctx,
-                                               &ctx->src_ctrls[index]) < 0)
-                               mfc_err_ctx("failed in recover_buf_ctrls_val\n");
-
-                       /* single buffer || last image in a buffer container */
-                       if (!src_mb->num_valid_bufs || src_mb->done_index == src_mb->num_valid_bufs) {
-                               src_mb = mfc_find_del_buf(&ctx->buf_queue_lock,
-                                               &ctx->src_buf_queue, enc_addr[0]);
-                               for (i = 0; i < raw->num_planes; i++)
-                                       mfc_bufcon_put_daddr(ctx, src_mb, i);
-                               vb2_buffer_done(&src_mb->vb.vb2_buf, VB2_BUF_STATE_DONE);
-                       }
-
-                       /* encoder src buffer CFW UNPROT */
-                       if (ctx->is_drm)
-                               mfc_raw_unprotect(ctx, src_mb, index);
-               }
-       } else {
-               /* normal single buffer */
-               src_mb = mfc_find_del_buf(&ctx->buf_queue_lock,
-                               &ctx->src_buf_queue, enc_addr[0]);
-               if (src_mb) {
-                       found_in_src_queue = 1;
-                       index = src_mb->vb.vb2_buf.index;
-                       if (call_cop(ctx, recover_buf_ctrls_val, ctx,
-                                               &ctx->src_ctrls[index]) < 0)
-                               mfc_err_ctx("failed in recover_buf_ctrls_val\n");
-
-                       mfc_debug(3, "find src buf in src_queue\n");
-                       vb2_buffer_done(&src_mb->vb.vb2_buf, VB2_BUF_STATE_DONE);
-
-                       /* encoder src buffer CFW UNPROT */
-                       if (ctx->is_drm)
-                               mfc_raw_unprotect(ctx, src_mb, index);
-               } else {
-                       mfc_debug(3, "no src buf in src_queue\n");
-                       ref_mb = mfc_find_del_buf(&ctx->buf_queue_lock,
-                                       &ctx->ref_buf_queue, enc_addr[0]);
-                       if (ref_mb) {
-                               mfc_debug(3, "find src buf in ref_queue\n");
-                               vb2_buffer_done(&ref_mb->vb.vb2_buf, VB2_BUF_STATE_DONE);
-
-                               /* encoder src buffer CFW UNPROT */
-                               if (ctx->is_drm) {
-                                       index = ref_mb->vb.vb2_buf.index;
-                                       mfc_raw_unprotect(ctx, ref_mb, index);
-                               }
-                       } else {
-                               mfc_err_ctx("couldn't find src buffer\n");
-                       }
-               }
-       }
-
-move_buf:
-       /* move enqueued src buffer: src queue -> ref queue */
-       if (!found_in_src_queue && ctx->state != MFCINST_FINISHING) {
-               mfc_move_first_buf_used(&ctx->buf_queue_lock,
-                               &ctx->ref_buf_queue, &ctx->src_buf_queue, MFC_QUEUE_ADD_BOTTOM);
-
-               mfc_debug(2, "enc src_buf_queue(%d) -> ref_buf_queue(%d)\n",
-                               mfc_get_queue_count(&ctx->buf_queue_lock, &ctx->src_buf_queue),
-                               mfc_get_queue_count(&ctx->buf_queue_lock, &ctx->ref_buf_queue));
-       }
-}
-
-static void __mfc_handle_stream_output(struct mfc_ctx *ctx, int slice_type,
-                                       unsigned int strm_size)
-{
-       struct mfc_enc *enc = ctx->enc_priv;
-       struct mfc_buf *dst_mb;
-       unsigned int index;
-
-       if (strm_size == 0) {
-               mfc_debug(3, "no encoded dst (reuse)\n");
-               return;
-       } else if (strm_size < 0) {
-               mfc_err_ctx("invalid stream size: %d\n", strm_size);
-               return;
-       }
-
-       /* at least one more dest. buffers exist always  */
-       dst_mb = mfc_get_del_buf(&ctx->buf_queue_lock,
-                       &ctx->dst_buf_queue, MFC_BUF_NO_TOUCH_USED);
-       if (!dst_mb) {
-               mfc_err_ctx("no dst buffers\n");
-               return;
-       }
-
-       mfc_debug(2, "[BUFINFO] ctx[%d] get dst addr: 0x%08llx\n",
-                       ctx->num, dst_mb->addr[0][0]);
-
-       dst_mb->vb.flags &= ~(V4L2_BUF_FLAG_KEYFRAME |
-                               V4L2_BUF_FLAG_PFRAME |
-                               V4L2_BUF_FLAG_BFRAME);
-       switch (slice_type) {
-       case MFC_REG_E_SLICE_TYPE_I:
-               dst_mb->vb.flags |= V4L2_BUF_FLAG_KEYFRAME;
-               break;
-       case MFC_REG_E_SLICE_TYPE_P:
-               dst_mb->vb.flags |= V4L2_BUF_FLAG_PFRAME;
-               break;
-       case MFC_REG_E_SLICE_TYPE_B:
-               dst_mb->vb.flags |= V4L2_BUF_FLAG_BFRAME;
-               break;
-       default:
-               dst_mb->vb.flags |= V4L2_BUF_FLAG_KEYFRAME;
-               break;
-       }
-       mfc_debug(2, "[STREAM] Slice type flag: %d\n", dst_mb->vb.flags);
-
-       if (IS_BPG_ENC(ctx)) {
-               strm_size += enc->header_size;
-               mfc_debug(2, "bpg total stream size: %d\n", strm_size);
-       }
-       vb2_set_plane_payload(&dst_mb->vb.vb2_buf, 0, strm_size);
-
-       index = dst_mb->vb.vb2_buf.index;
-       if (call_cop(ctx, get_buf_ctrls_val, ctx, &ctx->dst_ctrls[index]) < 0)
-               mfc_err_ctx("failed in get_buf_ctrls_val\n");
-
-       vb2_buffer_done(&dst_mb->vb.vb2_buf, VB2_BUF_STATE_DONE);
-
-       /* encoder dst buffer CFW UNPROT */
-       if (ctx->is_drm)
-               mfc_stream_unprotect(ctx, dst_mb, index);
-}
-
-/* Handle frame encoding interrupt */
-static int __mfc_handle_stream(struct mfc_ctx *ctx)
-{
-       struct mfc_dev *dev = ctx->dev;
-       struct mfc_enc *enc = ctx->enc_priv;
-       int slice_type;
-       unsigned int strm_size;
-       unsigned int pic_count;
-
-       slice_type = mfc_get_enc_slice_type();
-       strm_size = mfc_get_enc_strm_size();
-       pic_count = mfc_get_enc_pic_count();
-
-       mfc_debug(2, "[STREAM] encoded slice type: %d, size: %d, display order: %d\n",
-                       slice_type, strm_size, pic_count);
-
-       /* buffer full handling */
-       if (enc->buf_full) {
-               mfc_change_state(ctx, MFCINST_ABORT_INST);
-               return 0;
-       }
-       if (ctx->state == MFCINST_RUNNING_BUF_FULL)
-               mfc_change_state(ctx, MFCINST_RUNNING);
-
-       /* set encoded frame type */
-       enc->frame_type = slice_type;
-       ctx->sequence++;
-
-       if (enc->in_slice) {
-               if (mfc_is_queue_count_same(&ctx->buf_queue_lock, &ctx->dst_buf_queue, 0)) {
-                       mfc_clear_bit(ctx->num, &dev->work_bits);
-               }
-               return 0;
-       }
-
-       /* handle source buffer */
-       __mfc_handle_stream_input(ctx);
-
-       /* handle destination buffer */
-       __mfc_handle_stream_output(ctx, slice_type, strm_size);
-
-       return 0;
-}
-
-/* Error handling for interrupt */
-static inline void __mfc_handle_error(struct mfc_ctx *ctx,
-       unsigned int reason, unsigned int err)
-{
-       struct mfc_dev *dev = ctx->dev;
-       struct mfc_buf *src_mb;
-       int index;
-
-       mfc_err_ctx("Interrupt Error: display: %d, decoded: %d\n",
-                       mfc_get_warn(err), mfc_get_err(err));
-       err = mfc_get_err(err);
-
-       /* Error recovery is dependent on the state of context */
-       switch (ctx->state) {
-       case MFCINST_RES_CHANGE_END:
-       case MFCINST_GOT_INST:
-               /* This error had to happen while parsing the header */
-               if (!ctx->is_drm) {
-                       unsigned char *stream_vir = NULL;
-                       unsigned int strm_size = 0;
-
-                       src_mb = mfc_get_del_buf(&ctx->buf_queue_lock, &ctx->src_buf_queue, MFC_BUF_NO_TOUCH_USED);
-                       if (src_mb) {
-                               stream_vir = src_mb->vir_addr;
-                               strm_size = src_mb->vb.vb2_buf.planes[0].bytesused;
-                               if (strm_size > 32)
-                                       strm_size = 32;
-
-                               if (stream_vir && strm_size)
-                                       print_hex_dump(KERN_ERR, "No header: ",
-                                                       DUMP_PREFIX_ADDRESS, strm_size, 0,
-                                                       stream_vir, strm_size, false);
-
-                               vb2_buffer_done(&src_mb->vb.vb2_buf, VB2_BUF_STATE_DONE);
-                       }
-               } else {
-                       src_mb = mfc_get_del_buf(&ctx->buf_queue_lock, &ctx->src_buf_queue, MFC_BUF_NO_TOUCH_USED);
-                       if (src_mb) {
-                               index = src_mb->vb.vb2_buf.index;
-                               /* decoder src buffer CFW UNPROT */
-                               mfc_stream_unprotect(ctx, src_mb, index);
-                               vb2_buffer_done(&src_mb->vb.vb2_buf, VB2_BUF_STATE_DONE);
-                       }
-               }
-               break;
-       case MFCINST_INIT:
-               /* This error had to happen while acquireing instance */
-       case MFCINST_RETURN_INST:
-               /* This error had to happen while releasing instance */
-       case MFCINST_DPB_FLUSHING:
-               /* This error had to happen while flushing DPB */
-       case MFCINST_SPECIAL_PARSING:
-       case MFCINST_SPECIAL_PARSING_NAL:
-               /* This error had to happen while special parsing */
-               break;
-       case MFCINST_HEAD_PARSED:
-               /* This error had to happen while setting dst buffers */
-       case MFCINST_RES_CHANGE_INIT:
-       case MFCINST_RES_CHANGE_FLUSH:
-               /* This error has to happen while resolution change */
-       case MFCINST_ABORT_INST:
-               /* This error has to happen while buffer full handling */
-       case MFCINST_FINISHING:
-               /* It is higly probable that an error occured
-                * while decoding a frame */
-               mfc_change_state(ctx, MFCINST_ERROR);
-               /* Mark all dst buffers as having an error */
-               mfc_cleanup_queue(&ctx->buf_queue_lock, &ctx->dst_buf_queue);
-               /* Mark all src buffers as having an error */
-               mfc_cleanup_queue(&ctx->buf_queue_lock, &ctx->src_buf_queue);
-               break;
-       default:
-               mfc_err_ctx("Encountered an error interrupt which had not been handled\n");
-               mfc_err_ctx("ctx->state = %d, ctx->inst_no = %d\n",
-                                               ctx->state, ctx->inst_no);
-               break;
-       }
-
-       mfc_wake_up_dev(dev, reason, err);
-
-       return;
-}
-
-/* Handle header decoder interrupt */
-static int __mfc_handle_seq_dec(struct mfc_ctx *ctx)
-{
-       struct mfc_dev *dev = ctx->dev;
-       struct mfc_dec *dec = ctx->dec_priv;
-       int i, is_interlace, is_mbaff;
-
-       if (ctx->src_fmt->fourcc != V4L2_PIX_FMT_FIMV1) {
-               ctx->img_width = mfc_get_img_width();
-               ctx->img_height = mfc_get_img_height();
-               ctx->crop_width = ctx->img_width;
-               ctx->crop_height = ctx->img_height;
-               mfc_info_ctx("[STREAM] resolution w: %d, h: %d\n", ctx->img_width, ctx->img_height);
-       }
-
-       ctx->dpb_count = mfc_get_dpb_count();
-       ctx->scratch_buf_size = mfc_get_scratch_size();
-       for (i = 0; i < ctx->dst_fmt->num_planes; i++)
-               ctx->min_dpb_size[i] = mfc_get_min_dpb_size(i);
-
-       mfc_dec_store_crop_info(ctx);
-       dec->mv_count = mfc_get_mv_count();
-       if (CODEC_10BIT(ctx) && dev->pdata->support_10bit) {
-               if (mfc_get_luma_bit_depth_minus8() ||
-                       mfc_get_chroma_bit_depth_minus8() ||
-                       mfc_get_profile() == MFC_REG_D_PROFILE_HEVC_MAIN_10) {
-                       ctx->is_10bit = 1;
-                       mfc_info_ctx("[STREAM][10BIT] 10bit contents, profile: %d, depth: %d/%d\n",
-                                       mfc_get_profile(),
-                                       mfc_get_luma_bit_depth_minus8() + 8,
-                                       mfc_get_chroma_bit_depth_minus8() + 8);
-               }
-       }
-       if (CODEC_422FORMAT(ctx) && dev->pdata->support_422) {
-               if (mfc_get_chroma_format() == MFC_REG_D_CHROMA_422) {
-                       ctx->is_422 = 1;
-                       mfc_info_ctx("[STREAM] 422 chroma format\n");
-               }
-       }
-
-       if (ctx->img_width == 0 || ctx->img_height == 0)
-               mfc_change_state(ctx, MFCINST_ERROR);
-       else
-               mfc_change_state(ctx, MFCINST_HEAD_PARSED);
-
-       if (ctx->state == MFCINST_HEAD_PARSED) {
-               is_interlace = mfc_is_interlace_picture();
-               is_mbaff = mfc_is_mbaff_picture();
-               if (is_interlace || is_mbaff)
-                       dec->is_interlaced = 1;
-               mfc_debug(2, "[INTERLACE] interlace: %d, mbaff: %d\n", is_interlace, is_mbaff);
-       }
-
-       if (IS_H264_DEC(ctx) || IS_H264_MVC_DEC(ctx) || IS_HEVC_DEC(ctx)) {
-               struct mfc_buf *src_mb = mfc_get_buf(&ctx->buf_queue_lock, &ctx->src_buf_queue, MFC_BUF_NO_TOUCH_USED);
-               if (src_mb) {
-                       dec->consumed += mfc_get_consumed_stream();
-                       mfc_debug(2, "[STREAM] header total size : %d, consumed : %lu\n",
-                                       src_mb->vb.vb2_buf.planes[0].bytesused, dec->consumed);
-                       if ((dec->consumed > 0) &&
-                                       (src_mb->vb.vb2_buf.planes[0].bytesused > dec->consumed)) {
-                               dec->remained_size = src_mb->vb.vb2_buf.planes[0].bytesused -
-                                       dec->consumed;
-                               mfc_debug(2, "[STREAM] there is remained bytes(%lu) after header parsing\n",
-                                               dec->remained_size);
-                       } else {
-                               dec->consumed = 0;
-                               dec->remained_size = 0;
-                       }
-               }
-       }
-
-       if (IS_VP9_DEC(ctx)) {
-               dec->color_range = mfc_get_color_range();
-               dec->color_space = mfc_get_color_space();
-               mfc_debug(2, "color range: %d, color space: %d, It's valid for VP9\n",
-                               dec->color_range, dec->color_space);
-       }
-
-       return 0;
-}
-
-/* Handle header encoder interrupt */
-static int __mfc_handle_seq_enc(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_buf *dst_mb;
-       int ret;
-
-       enc->header_size = mfc_get_enc_strm_size();
-       mfc_debug(2, "[STREAM] encoded slice type: %d, header size: %d, display order: %d\n",
-                       mfc_get_enc_slice_type(), enc->header_size,
-                       mfc_get_enc_pic_count());
-
-       if (IS_BPG_ENC(ctx)) {
-               dst_mb = mfc_get_buf(&ctx->buf_queue_lock, &ctx->dst_buf_queue, MFC_BUF_NO_TOUCH_USED);
-               if (!dst_mb) {
-                       mfc_err_dev("no dst buffers\n");
-                       return -EAGAIN;
-               }
-
-               dst_mb->vb.vb2_buf.planes[0].data_offset += (enc->header_size +
-                               p->codec.bpg.thumb_size + p->codec.bpg.exif_size);
-               mfc_debug(2, "offset for NAL_START: %d (header: %d + thumb: %d + exif: %d)\n",
-                               dst_mb->vb.vb2_buf.planes[0].data_offset,
-                               enc->header_size,
-                               p->codec.bpg.thumb_size,
-                               p->codec.bpg.exif_size);
-       } else {
-               if ((p->seq_hdr_mode == V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE) ||
-                       (p->seq_hdr_mode == V4L2_MPEG_VIDEO_HEADER_MODE_AT_THE_READY)) {
-                       dst_mb = mfc_get_del_buf(&ctx->buf_queue_lock,
-                                       &ctx->dst_buf_queue, MFC_BUF_NO_TOUCH_USED);
-                       if (!dst_mb) {
-                               mfc_err_dev("no dst buffers\n");
-                               return -EAGAIN;
-                       }
-
-                       vb2_set_plane_payload(&dst_mb->vb.vb2_buf, 0, mfc_get_enc_strm_size());
-                       vb2_buffer_done(&dst_mb->vb.vb2_buf, VB2_BUF_STATE_DONE);
-
-                       /* encoder dst buffer CFW UNPROT */
-                       if (ctx->is_drm) {
-                               int index = dst_mb->vb.vb2_buf.index;
-
-                               mfc_stream_unprotect(ctx, dst_mb, index);
-                       }
-               }
-       }
-
-       ctx->dpb_count = mfc_get_enc_dpb_count();
-       ctx->scratch_buf_size = mfc_get_enc_scratch_size();
-
-       /* If the ROI is enabled at SEQ_START, clear ROI_ENABLE bit */
-       mfc_clear_roi_enable(dev);
-
-       if (!ctx->codec_buffer_allocated) {
-               mfc_debug(2, "[DRC] previous codec buffer is exist\n");
-
-               if (dev->has_mmcache && dev->mmcache.is_on_status)
-                       mfc_invalidate_mmcache(dev);
-
-               mfc_release_codec_buffers(ctx);
-       }
-       ret = mfc_alloc_codec_buffers(ctx);
-       if (ret) {
-               mfc_err_ctx("Failed to allocate encoding buffers\n");
-               return ret;
-       }
-
-       mfc_change_state(ctx, MFCINST_HEAD_PARSED);
-
-       return 0;
-}
-
-static inline int is_err_condition(unsigned int err)
-{
-       if (err == MFC_REG_ERR_NO_AVAILABLE_DPB ||
-               err == MFC_REG_ERR_INSUFFICIENT_DPB_SIZE ||
-               err == MFC_REG_ERR_INSUFFICIENT_NUM_DPB ||
-               err == MFC_REG_ERR_INSUFFICIENT_MV_BUF_SIZE ||
-               err == MFC_REG_ERR_INSUFFICIENT_SCRATCH_BUF_SIZE)
-               return 1;
-
-       return 0;
-}
-
-irqreturn_t mfc_top_half_irq(int irq, void *priv)
-{
-       struct mfc_dev *dev = priv;
-       struct mfc_ctx *ctx;
-       unsigned int err;
-       unsigned int reason;
-
-       ctx = dev->ctx[dev->curr_ctx];
-       if (!ctx) {
-               mfc_err_dev("no mfc context to run\n");
-               return IRQ_WAKE_THREAD;
-       }
-
-       reason = mfc_get_int_reason();
-       err = mfc_get_int_err();
-       mfc_debug(2, "[c:%d] Int reason: %d (err: %d)\n",
-                       dev->curr_ctx, reason, err);
-       MFC_TRACE_CTX("<< INT(top): %d\n", reason);
-
-       mfc_perf_measure_off(dev);
-
-       return IRQ_WAKE_THREAD;
-}
-
-/*
- * Return value description
- *  0: NAL-Q is handled successfully
- *  1: NAL_START command
- * -1: Error
-*/
-static inline int __mfc_nal_q_irq(struct mfc_dev *dev,
-               unsigned int reason, unsigned int err)
-{
-       int ret = -1;
-       unsigned int errcode;
-
-       nal_queue_handle *nal_q_handle = dev->nal_q_handle;
-       EncoderOutputStr *pOutStr;
-
-       switch (reason) {
-       case MFC_REG_R2H_CMD_QUEUE_DONE_RET:
-               pOutStr = mfc_nal_q_dequeue_out_buf(dev,
-                       nal_q_handle->nal_q_out_handle, &errcode);
-               if (pOutStr) {
-                       if (mfc_nal_q_handle_out_buf(dev, pOutStr))
-                               mfc_err_dev("[NALQ] Failed to handle out buf\n");
-               } else {
-                       mfc_err_dev("[NALQ] pOutStr is NULL\n");
-               }
-
-               if (nal_q_handle->nal_q_exception)
-                       mfc_set_bit(nal_q_handle->nal_q_out_handle->nal_q_ctx,
-                                       &dev->work_bits);
-               mfc_clear_int_sfr();
-
-               if (!nal_q_handle->nal_q_exception)
-                       mfc_nal_q_clock_off(dev, nal_q_handle);
-
-               ret = 0;
-               break;
-       case MFC_REG_R2H_CMD_COMPLETE_QUEUE_RET:
-               mfc_watchdog_stop_tick(dev);
-               nal_q_handle->nal_q_state = NAL_Q_STATE_CREATED;
-               MFC_TRACE_DEV("** NAL Q state : %d\n", nal_q_handle->nal_q_state);
-               mfc_debug(2, "[NALQ] return to created state\n");
-               mfc_nal_q_cleanup_queue(dev);
-               mfc_nal_q_cleanup_clock(dev);
-               mfc_clear_int_sfr();
-               mfc_pm_clock_off(dev);
-               mfc_wake_up_dev(dev, reason, err);
-
-               ret = 0;
-               break;
-       default:
-               if (nal_q_handle->nal_q_state == NAL_Q_STATE_STARTED ||
-                       nal_q_handle->nal_q_state == NAL_Q_STATE_STOPPED) {
-                       mfc_err_dev("[NALQ] Should not be here! state: %d, int reason : %d\n",
-                               nal_q_handle->nal_q_state, reason);
-                       mfc_clear_int_sfr();
-
-                       ret = -1;
-               } else {
-                       /* NAL START */
-                       ret = 1;
-               }
-
-               break;
-       }
-
-       if (ret == 0)
-               queue_work(dev->butler_wq, &dev->butler_work);
-
-       return ret;
-}
-
-static inline int __mfc_handle_done_frame(struct mfc_ctx *ctx,
-                               unsigned int reason, unsigned int err)
-{
-       struct mfc_dev *dev = ctx->dev;
-       struct mfc_enc *enc = NULL;
-
-       if (ctx->type == MFCINST_DECODER) {
-               if (ctx->state == MFCINST_SPECIAL_PARSING_NAL) {
-                       mfc_clear_int_sfr();
-                       mfc_pm_clock_off(dev);
-                       mfc_clear_bit(ctx->num, &dev->work_bits);
-                       mfc_change_state(ctx, MFCINST_RUNNING);
-                       mfc_wake_up_ctx(ctx, reason, err);
-                       return 0;
-               }
-               __mfc_handle_frame(ctx, reason, err);
-       } else if (ctx->type == MFCINST_ENCODER) {
-               if (ctx->otf_handle) {
-                       mfc_otf_handle_stream(ctx);
-                       return 1;
-               }
-               enc = ctx->enc_priv;
-               if (reason == MFC_REG_R2H_CMD_SLICE_DONE_RET) {
-                       dev->preempt_ctx = ctx->num;
-                       enc->buf_full = 0;
-                       enc->in_slice = 1;
-               } else if (reason == MFC_REG_R2H_CMD_ENC_BUFFER_FULL_RET) {
-                       mfc_err_ctx("stream buffer size(%d) isn't enough\n",
-                                       mfc_get_enc_strm_size());
-                       dev->preempt_ctx = ctx->num;
-                       enc->buf_full = 1;
-                       enc->in_slice = 0;
-               } else {
-                       enc->buf_full = 0;
-                       enc->in_slice = 0;
-               }
-               __mfc_handle_stream(ctx);
-       }
-
-       return 1;
-}
-
-static inline void __mfc_handle_nal_abort(struct mfc_ctx *ctx)
-{
-       struct mfc_enc *enc = ctx->enc_priv;
-
-       if (ctx->type == MFCINST_ENCODER) {
-               mfc_change_state(ctx, MFCINST_RUNNING_BUF_FULL);
-               enc->buf_full = 0;
-               if (IS_VP8_ENC(ctx))
-                       mfc_err_ctx("stream buffer size isn't enough\n");
-               __mfc_handle_stream(ctx);
-       } else {
-               mfc_change_state(ctx, MFCINST_ABORT);
-       }
-}
-
-static int __mfc_irq_dev(struct mfc_dev *dev, unsigned int reason, unsigned int err)
-{
-       /* Stop the timeout watchdog */
-       if (reason != MFC_REG_R2H_CMD_FW_STATUS_RET)
-               mfc_watchdog_stop_tick(dev);
-
-       switch (reason) {
-       case MFC_REG_R2H_CMD_CACHE_FLUSH_RET:
-       case MFC_REG_R2H_CMD_SYS_INIT_RET:
-       case MFC_REG_R2H_CMD_FW_STATUS_RET:
-       case MFC_REG_R2H_CMD_SLEEP_RET:
-       case MFC_REG_R2H_CMD_WAKEUP_RET:
-               mfc_clear_int_sfr();
-               mfc_wake_up_dev(dev, reason, err);
-               return 0;
-       }
-
-       return 1;
-}
-
-static int __mfc_irq_ctx(struct mfc_ctx *ctx, unsigned int reason, unsigned int err)
-{
-       struct mfc_dev *dev = ctx->dev;
-
-       switch (reason) {
-       case MFC_REG_R2H_CMD_ERR_RET:
-               if (ctx->otf_handle) {
-                       mfc_otf_handle_error(ctx, reason, err);
-                       break;
-               }
-               /* An error has occured */
-               if (ctx->state == MFCINST_RUNNING || ctx->state == MFCINST_ABORT) {
-                       if ((mfc_get_err(err) >= MFC_REG_ERR_WARNINGS_START) &&
-                               (mfc_get_err(err) <= MFC_REG_ERR_WARNINGS_END))
-                               __mfc_handle_frame(ctx, reason, err);
-                       else
-                               __mfc_handle_frame_error(ctx, reason, err);
-               } else {
-                       __mfc_handle_error(ctx, reason, err);
-               }
-               break;
-       case MFC_REG_R2H_CMD_SLICE_DONE_RET:
-       case MFC_REG_R2H_CMD_FIELD_DONE_RET:
-       case MFC_REG_R2H_CMD_FRAME_DONE_RET:
-       case MFC_REG_R2H_CMD_ENC_BUFFER_FULL_RET:
-               return __mfc_handle_done_frame(ctx, reason, err);
-       case MFC_REG_R2H_CMD_COMPLETE_SEQ_RET:
-               if (ctx->type == MFCINST_ENCODER) {
-                       __mfc_handle_stream(ctx);
-                       mfc_change_state(ctx, MFCINST_RUNNING);
-               } else if (ctx->type == MFCINST_DECODER) {
-                       return __mfc_handle_done_frame(ctx, reason, err);
-               }
-               break;
-       case MFC_REG_R2H_CMD_SEQ_DONE_RET:
-               if (ctx->type == MFCINST_ENCODER) {
-                       if (ctx->otf_handle) {
-                               mfc_otf_handle_seq(ctx);
-                               break;
-                       }
-                       __mfc_handle_seq_enc(ctx);
-               } else if (ctx->type == MFCINST_DECODER) {
-                       __mfc_handle_seq_dec(ctx);
-               }
-               break;
-       case MFC_REG_R2H_CMD_OPEN_INSTANCE_RET:
-               ctx->inst_no = mfc_get_inst_no();
-               mfc_change_state(ctx, MFCINST_GOT_INST);
-               break;
-       case MFC_REG_R2H_CMD_CLOSE_INSTANCE_RET:
-               mfc_change_state(ctx, MFCINST_FREE);
-               break;
-       case MFC_REG_R2H_CMD_NAL_ABORT_RET:
-               __mfc_handle_nal_abort(ctx);
-               break;
-       case MFC_REG_R2H_CMD_DPB_FLUSH_RET:
-               mfc_change_state(ctx, MFCINST_ABORT);
-               break;
-       case MFC_REG_R2H_CMD_INIT_BUFFERS_RET:
-               if (err != 0) {
-                       mfc_err_ctx("INIT_BUFFERS_RET error: %d\n", err);
-                       break;
-               }
-
-               mfc_change_state(ctx, MFCINST_RUNNING);
-               if (ctx->type == MFCINST_DECODER) {
-                       if (ctx->wait_state == WAIT_DECODING) {
-                               ctx->wait_state = WAIT_INITBUF_DONE;
-                               mfc_debug(2, "INIT_BUFFER has done, but can't start decoding\n");
-                       }
-                       if (ctx->is_dpb_realloc)
-                               ctx->is_dpb_realloc = 0;
-               }
-               break;
-       default:
-               mfc_err_ctx("Unknown int reason: %d\n", reason);
-       }
-
-       return 1;
-}
-
-/* Interrupt processing */
-irqreturn_t mfc_irq(int irq, void *priv)
-{
-       struct mfc_dev *dev = priv;
-       struct mfc_ctx *ctx;
-       unsigned int reason;
-       unsigned int err;
-       int ret = -1;
-
-       mfc_debug_enter();
-
-       if (!dev) {
-               mfc_err_dev("no mfc device to run\n");
-               goto irq_end;
-       }
-
-       if (mfc_pm_get_pwr_ref_cnt(dev) == 0) {
-               mfc_err_dev("no mfc power on\n");
-               call_dop(dev, dump_and_stop_debug_mode, dev);
-               goto irq_end;
-       }
-
-       /* Get the reason of interrupt and the error code */
-       reason = mfc_get_int_reason();
-       err = mfc_get_int_err();
-       mfc_debug(1, "Int reason: %d (err: %d)\n", reason, err);
-       MFC_TRACE_DEV("<< INT: %d\n", reason);
-
-       dev->preempt_ctx = MFC_NO_INSTANCE_SET;
-
-       if (dbg_enable && (reason != MFC_REG_R2H_CMD_QUEUE_DONE_RET))
-               mfc_dbg_disable(dev);
-
-       if ((sfr_dump & MFC_DUMP_ERR_INT) && (reason == MFC_REG_R2H_CMD_ERR_RET))
-               call_dop(dev, dump_regs, dev);
-
-       if ((sfr_dump & MFC_DUMP_WARN_INT) &&
-                       (err && (reason != MFC_REG_R2H_CMD_ERR_RET)))
-               call_dop(dev, dump_regs, dev);
-
-       if (is_err_condition(err))
-               call_dop(dev, dump_and_stop_debug_mode, dev);
-
-       if (dev->nal_q_handle) {
-               ret = __mfc_nal_q_irq(dev, reason, err);
-               if (ret == 0) {
-                       mfc_debug(2, "[NALQ] command was handled\n");
-                       goto irq_end;
-               } else if (ret == 1){
-                       /* Path through */
-                       mfc_debug(2, "NAL_START command will be handled\n");
-               } else {
-                       mfc_debug(2, "[NALQ] command handling Error\n");
-                       goto irq_end;
-               }
-       }
-
-       ret = __mfc_irq_dev(dev, reason, err);
-       if (!ret)
-               goto irq_end;
-
-       ctx = dev->ctx[dev->curr_ctx];
-       if (!ctx) {
-               mfc_err_dev("no mfc context to run\n");
-               mfc_clear_int_sfr();
-               mfc_pm_clock_off(dev);
-               goto irq_end;
-       }
-
-       ret = __mfc_irq_ctx(ctx, reason, err);
-       if (!ret)
-               goto irq_end;
-
-       /* clean-up interrupt */
-       mfc_clear_int_sfr();
-
-       if ((ctx->state != MFCINST_RES_CHANGE_INIT) && (mfc_ctx_ready(ctx) == 0))
-               mfc_clear_bit(ctx->num, &dev->work_bits);
-
-       if (ctx->otf_handle) {
-               if (mfc_otf_ctx_ready(ctx))
-                       mfc_set_bit(ctx->num, &dev->work_bits);
-               else
-                       mfc_clear_bit(ctx->num, &dev->work_bits);
-       }
-
-       mfc_hwlock_handler_irq(dev, ctx, reason, err);
-
-irq_end:
-       mfc_debug_leave();
-       return IRQ_HANDLED;
-}
diff --git a/drivers/media/platform/exynos/mfc/mfc_irq.h b/drivers/media/platform/exynos/mfc/mfc_irq.h
deleted file mode 100644 (file)
index 872596a..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * drivers/media/platform/exynos/mfc/mfc_irq.h
- *
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef __MFC_IRQ_H
-#define __MFC_IRQ_H __FILE__
-
-#include <linux/interrupt.h>
-
-#include "mfc_common.h"
-
-#include "mfc_utils.h"
-
-irqreturn_t mfc_top_half_irq(int irq, void *priv);
-irqreturn_t mfc_irq(int irq, void *priv);
-
-static inline void mfc_handle_force_change_status(struct mfc_ctx *ctx)
-{
-       if (ctx->state != MFCINST_ABORT && ctx->state != MFCINST_HEAD_PARSED &&
-                       ctx->state != MFCINST_RES_CHANGE_FLUSH)
-               mfc_change_state(ctx, MFCINST_RUNNING);
-}
-
-#endif /* __MFC_IRQ_H */
diff --git a/drivers/media/platform/exynos/mfc/mfc_isr.c b/drivers/media/platform/exynos/mfc/mfc_isr.c
new file mode 100644 (file)
index 0000000..d940839
--- /dev/null
@@ -0,0 +1,1564 @@
+/*
+ * drivers/media/platform/exynos/mfc/mfc_isr.c
+ *
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include "mfc_isr.h"
+
+#include "mfc_hwlock.h"
+#include "mfc_nal_q.h"
+#include "mfc_otf.h"
+#include "mfc_opr.h"
+#include "mfc_sync.h"
+
+#include "mfc_pm.h"
+#include "mfc_perf_measure.h"
+#include "mfc_reg_api.h"
+#include "mfc_hw_reg_api.h"
+#include "mfc_mmcache.h"
+
+#include "mfc_qos.h"
+#include "mfc_queue.h"
+#include "mfc_buf.h"
+#include "mfc_mem.h"
+
+static void __mfc_handle_black_bar_info(struct mfc_dev *dev, struct mfc_ctx *ctx)
+{
+       struct v4l2_rect new_black_bar;
+       int black_bar_info;
+       struct mfc_dec *dec = ctx->dec_priv;
+
+       black_bar_info = mfc_get_black_bar_detection();
+       mfc_debug(3, "[BLACKBAR] type: %#x\n", black_bar_info);
+
+       if (black_bar_info == MFC_REG_DISP_STATUS_BLACK_BAR) {
+               new_black_bar.left = mfc_get_black_bar_pos_x();
+               new_black_bar.top = mfc_get_black_bar_pos_y();
+               new_black_bar.width = mfc_get_black_bar_image_w();
+               new_black_bar.height = mfc_get_black_bar_image_h();
+       } else if (black_bar_info == MFC_REG_DISP_STATUS_BLACK_SCREEN) {
+               new_black_bar.left = -1;
+               new_black_bar.top = -1;
+               new_black_bar.width = ctx->img_width;
+               new_black_bar.height = ctx->img_height;
+       } else if (black_bar_info == MFC_REG_DISP_STATUS_NOT_DETECTED) {
+               new_black_bar.left = 0;
+               new_black_bar.top = 0;
+               new_black_bar.width = ctx->img_width;
+               new_black_bar.height = ctx->img_height;
+       } else {
+               mfc_err_ctx("[BLACKBAR] Not supported type: %#x\n", black_bar_info);
+               dec->black_bar_updated = 0;
+               return;
+       }
+
+       if ((new_black_bar.left == dec->black_bar.left) &&
+                       (new_black_bar.top == dec->black_bar.top) &&
+                       (new_black_bar.width == dec->black_bar.width) &&
+                       (new_black_bar.height == dec->black_bar.height)) {
+               mfc_debug(4, "[BLACKBAR] information was not changed\n");
+               dec->black_bar_updated = 0;
+               return;
+       }
+
+       dec->black_bar = new_black_bar;
+       dec->black_bar_updated = 1;
+}
+
+static unsigned int __mfc_handle_frame_field(struct mfc_ctx *ctx)
+{
+       struct mfc_dev *dev = ctx->dev;
+       unsigned int interlace_type = 0, is_interlace = 0, is_mbaff = 0;
+       unsigned int field;
+
+       if (CODEC_INTERLACED(ctx))
+               is_interlace = mfc_is_interlace_picture();
+
+       if (CODEC_MBAFF(ctx))
+               is_mbaff = mfc_is_mbaff_picture();
+
+       if (is_interlace) {
+               interlace_type = mfc_get_interlace_type();
+               if (interlace_type)
+                       field = V4L2_FIELD_INTERLACED_TB;
+               else
+                       field = V4L2_FIELD_INTERLACED_BT;
+       } else if (is_mbaff) {
+               field = V4L2_FIELD_INTERLACED_TB;
+       } else {
+               field = V4L2_FIELD_NONE;
+       }
+
+       mfc_debug(2, "[INTERLACE] is_interlace: %d (type : %d), is_mbaff: %d, field: 0x%#x\n",
+                       is_interlace, interlace_type, is_mbaff, field);
+
+       return field;
+}
+
+static void __mfc_handle_frame_all_extracted(struct mfc_ctx *ctx)
+{
+       struct mfc_dec *dec = ctx->dec_priv;
+       struct mfc_buf *dst_mb;
+       int index, i, is_first = 1;
+
+       mfc_debug(2, "Decided to finish\n");
+       ctx->sequence++;
+
+       while (1) {
+               dst_mb = mfc_get_del_buf(&ctx->buf_queue_lock, &ctx->dst_buf_queue, MFC_BUF_NO_TOUCH_USED);
+               if (!dst_mb)
+                       break;
+
+               mfc_debug(2, "Cleaning up buffer: %d\n",
+                                         dst_mb->vb.vb2_buf.index);
+
+               index = dst_mb->vb.vb2_buf.index;
+
+               for (i = 0; i < ctx->dst_fmt->mem_planes; i++)
+                       vb2_set_plane_payload(&dst_mb->vb.vb2_buf, i, 0);
+
+               dst_mb->vb.sequence = (ctx->sequence++);
+               dst_mb->vb.field = __mfc_handle_frame_field(ctx);
+               dst_mb->vb.reserved2 = 0;
+
+               clear_bit(dst_mb->vb.vb2_buf.index, &dec->available_dpb);
+
+               if (call_cop(ctx, get_buf_ctrls_val, ctx, &ctx->dst_ctrls[index]) < 0)
+                       mfc_err_ctx("failed in get_buf_ctrls_val\n");
+
+               if (is_first) {
+                       call_cop(ctx, get_buf_update_val, ctx,
+                               &ctx->dst_ctrls[index],
+                               V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG,
+                               dec->stored_tag);
+                       is_first = 0;
+               } else {
+                       call_cop(ctx, get_buf_update_val, ctx,
+                               &ctx->dst_ctrls[index],
+                               V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG,
+                               DEFAULT_TAG);
+                       call_cop(ctx, get_buf_update_val, ctx,
+                               &ctx->dst_ctrls[index],
+                               V4L2_CID_MPEG_VIDEO_H264_SEI_FP_AVAIL,
+                               0);
+               }
+
+               vb2_buffer_done(&dst_mb->vb.vb2_buf, VB2_BUF_STATE_DONE);
+
+               /* decoder dst buffer CFW UNPROT */
+               if (ctx->is_drm)
+                       mfc_raw_unprotect(ctx, dst_mb, index);
+
+               mfc_debug(2, "Cleaned up buffer: %d\n", index);
+       }
+
+       mfc_handle_force_change_status(ctx);
+       mfc_debug(2, "After cleanup\n");
+}
+
+static void __mfc_handle_frame_copy_timestamp(struct mfc_ctx *ctx)
+{
+       struct mfc_dev *dev = ctx->dev;
+       struct mfc_buf *ref_mb, *src_mb;
+       dma_addr_t dec_y_addr;
+
+       dec_y_addr = (dma_addr_t)mfc_get_dec_y_addr();
+
+       /* Get the source buffer */
+       src_mb = mfc_get_buf(&ctx->buf_queue_lock, &ctx->src_buf_queue, MFC_BUF_NO_TOUCH_USED);
+       if (!src_mb) {
+               mfc_err_dev("[TS] no src buffers\n");
+               return;
+       }
+
+       ref_mb = mfc_find_buf(&ctx->buf_queue_lock, &ctx->ref_buf_queue, dec_y_addr);
+       if (ref_mb)
+               ref_mb->vb.vb2_buf.timestamp = src_mb->vb.vb2_buf.timestamp;
+}
+
+static void __mfc_handle_frame_output_move(struct mfc_ctx *ctx,
+               dma_addr_t dspl_y_addr, unsigned int released_flag)
+{
+       struct mfc_dev *dev = ctx->dev;
+       struct mfc_dec *dec = ctx->dec_priv;
+       struct mfc_buf *ref_mb;
+       int index;
+
+       ref_mb = mfc_find_move_buf(&ctx->buf_queue_lock,
+                       &ctx->dst_buf_queue, &ctx->ref_buf_queue, dspl_y_addr, released_flag);
+       if (ref_mb) {
+               index = ref_mb->vb.vb2_buf.index;
+
+               /* Check if this is the buffer we're looking for */
+               mfc_debug(2, "[DPB] Found buf[%d] 0x%08llx, looking for disp addr 0x%08llx\n",
+                               index, ref_mb->addr[0][0], dspl_y_addr);
+
+               if (released_flag & (1 << index)) {
+                       dec->available_dpb &= ~(1 << index);
+                       released_flag &= ~(1 << index);
+                       mfc_debug(2, "[DPB] Corrupted frame(%d), it will be re-used(release)\n",
+                                       mfc_get_warn(mfc_get_int_err()));
+               } else {
+                       dec->err_reuse_flag |= 1 << index;
+                       mfc_debug(2, "[DPB] Corrupted frame(%d), it will be re-used(not released)\n",
+                                       mfc_get_warn(mfc_get_int_err()));
+               }
+               dec->dynamic_used |= released_flag;
+       }
+}
+
+static void __mfc_handle_frame_output_del(struct mfc_ctx *ctx,
+               unsigned int err, unsigned int released_flag)
+{
+       struct mfc_dev *dev = ctx->dev;
+       struct mfc_dec *dec = ctx->dec_priv;
+       struct mfc_raw_info *raw = &ctx->raw_buf;
+       struct mfc_buf *ref_mb;
+       dma_addr_t dspl_y_addr;
+       unsigned int frame_type;
+       unsigned int dst_frame_status;
+       unsigned int is_video_signal_type = 0, is_colour_description = 0;
+       unsigned int is_content_light = 0, is_display_colour = 0;
+       unsigned int i, index;
+
+       if (MFC_FEATURE_SUPPORT(dev, dev->pdata->color_aspect_dec)) {
+               is_video_signal_type = mfc_get_video_signal_type();
+               is_colour_description = mfc_get_colour_description();
+       }
+
+       if (MFC_FEATURE_SUPPORT(dev, dev->pdata->static_info_dec)) {
+               is_content_light = mfc_get_sei_avail_content_light();
+               is_display_colour = mfc_get_sei_avail_mastering_display();
+       }
+
+       if (MFC_FEATURE_SUPPORT(dev, dev->pdata->black_bar) && dec->detect_black_bar)
+               __mfc_handle_black_bar_info(dev, ctx);
+       else
+               dec->black_bar_updated = 0;
+
+       if (dec->immediate_display == 1) {
+               dspl_y_addr = (dma_addr_t)mfc_get_dec_y_addr();
+               frame_type = mfc_get_dec_frame_type();
+       } else {
+               dspl_y_addr = (dma_addr_t)mfc_get_disp_y_addr();
+               frame_type = mfc_get_disp_frame_type();
+       }
+
+       ref_mb = mfc_find_del_buf(&ctx->buf_queue_lock,
+                       &ctx->ref_buf_queue, dspl_y_addr);
+       if (ref_mb) {
+               index = ref_mb->vb.vb2_buf.index;
+               /* Check if this is the buffer we're looking for */
+               mfc_debug(2, "[BUFINFO][DPB] ctx[%d] get dst index: %d, addr[0]: 0x%08llx\n",
+                               ctx->num, index, ref_mb->addr[0][0]);
+
+               ref_mb->vb.sequence = ctx->sequence;
+               ref_mb->vb.field = __mfc_handle_frame_field(ctx);
+
+               /* Set reserved2 bits in order to inform SEI information */
+               ref_mb->vb.reserved2 = 0;
+
+               if (is_content_light) {
+                       ref_mb->vb.reserved2 |= (1 << 0);
+                       mfc_debug(2, "[HDR] content light level parsed\n");
+               }
+
+               if (is_display_colour) {
+                       ref_mb->vb.reserved2 |= (1 << 1);
+                       mfc_debug(2, "[HDR] mastering display colour parsed\n");
+               }
+
+               if (is_video_signal_type) {
+                       ref_mb->vb.reserved2 |= (1 << 4);
+                       mfc_debug(2, "[HDR] video signal type parsed\n");
+                       if (is_colour_description) {
+                               ref_mb->vb.reserved2 |= (1 << 2);
+                               mfc_debug(2, "[HDR] matrix coefficients parsed\n");
+                               ref_mb->vb.reserved2 |= (1 << 3);
+                               mfc_debug(2, "[HDR] colour description parsed\n");
+                       }
+               }
+
+               if (IS_VP9_DEC(ctx) && MFC_FEATURE_SUPPORT(dev, dev->pdata->color_aspect_dec)) {
+                       if (dec->color_space != MFC_REG_D_COLOR_UNKNOWN) {
+                               ref_mb->vb.reserved2 |= (1 << 3);
+                               mfc_debug(2, "[HDR] color space parsed\n");
+                       }
+                       ref_mb->vb.reserved2 |= (1 << 4);
+                       mfc_debug(2, "[HDR] color range parsed\n");
+               }
+
+               if (dec->black_bar_updated) {
+                       ref_mb->vb.reserved2 |= (1 << 5);
+                       mfc_debug(3, "[BLACKBAR] black bar detected\n");
+               }
+
+               if (ctx->src_fmt->mem_planes == 1) {
+                       vb2_set_plane_payload(&ref_mb->vb.vb2_buf, 0,
+                                       raw->total_plane_size);
+                       mfc_debug(5, "single plane payload: %d\n",
+                                       raw->total_plane_size);
+               } else {
+                       for (i = 0; i < ctx->src_fmt->mem_planes; i++) {
+                               vb2_set_plane_payload(&ref_mb->vb.vb2_buf, i,
+                                               raw->plane_size[i]);
+                       }
+               }
+
+               clear_bit(index, &dec->available_dpb);
+
+               ref_mb->vb.flags &= ~(V4L2_BUF_FLAG_KEYFRAME |
+                                       V4L2_BUF_FLAG_PFRAME |
+                                       V4L2_BUF_FLAG_BFRAME |
+                                       V4L2_BUF_FLAG_ERROR);
+
+               switch (frame_type) {
+                       case MFC_REG_DISPLAY_FRAME_I:
+                               ref_mb->vb.flags |= V4L2_BUF_FLAG_KEYFRAME;
+                               break;
+                       case MFC_REG_DISPLAY_FRAME_P:
+                               ref_mb->vb.flags |= V4L2_BUF_FLAG_PFRAME;
+                               break;
+                       case MFC_REG_DISPLAY_FRAME_B:
+                               ref_mb->vb.flags |= V4L2_BUF_FLAG_BFRAME;
+                               break;
+                       default:
+                               break;
+               }
+
+               if (mfc_get_warn(err)) {
+                       mfc_err_ctx("Warning for displayed frame: %d\n",
+                                       mfc_get_warn(err));
+                       ref_mb->vb.flags |= V4L2_BUF_FLAG_ERROR;
+               }
+
+               if (call_cop(ctx, get_buf_ctrls_val, ctx, &ctx->dst_ctrls[index]) < 0)
+                       mfc_err_ctx("failed in get_buf_ctrls_val\n");
+
+               mfc_handle_released_info(ctx, released_flag, index);
+
+               if (dec->immediate_display == 1) {
+                       dst_frame_status = mfc_get_dec_status();
+
+                       call_cop(ctx, get_buf_update_val, ctx,
+                                       &ctx->dst_ctrls[index],
+                                       V4L2_CID_MPEG_MFC51_VIDEO_DISPLAY_STATUS,
+                                       dst_frame_status);
+
+                       call_cop(ctx, get_buf_update_val, ctx,
+                                       &ctx->dst_ctrls[index],
+                                       V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG,
+                                       dec->stored_tag);
+
+                       dec->immediate_display = 0;
+               }
+
+               /* Update frame tag for packed PB */
+               if (CODEC_MULTIFRAME(ctx) && (dec->y_addr_for_pb == dspl_y_addr)) {
+                       call_cop(ctx, get_buf_update_val, ctx,
+                                       &ctx->dst_ctrls[index],
+                                       V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG,
+                                       dec->stored_tag);
+                       dec->y_addr_for_pb = 0;
+               }
+
+               mfc_qos_update_last_framerate(ctx, ref_mb->vb.vb2_buf.timestamp);
+               vb2_buffer_done(&ref_mb->vb.vb2_buf, mfc_get_warn(err) ?
+                               VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
+       }
+}
+
+static void __mfc_handle_frame_new(struct mfc_ctx *ctx, unsigned int err)
+{
+       struct mfc_dec *dec = ctx->dec_priv;
+       struct mfc_dev *dev = ctx->dev;
+       dma_addr_t dspl_y_addr;
+       unsigned int frame_type;
+       int mvc_view_id;
+       unsigned int prev_flag, released_flag = 0;
+
+       frame_type = mfc_get_disp_frame_type();
+       mvc_view_id = mfc_get_mvc_disp_view_id();
+
+       if (IS_H264_MVC_DEC(ctx)) {
+               if (mvc_view_id == 0)
+                       ctx->sequence++;
+       } else {
+               ctx->sequence++;
+       }
+
+       dspl_y_addr = mfc_get_disp_y_addr();
+
+       if (dec->immediate_display == 1) {
+               dspl_y_addr = (dma_addr_t)mfc_get_dec_y_addr();
+               frame_type = mfc_get_dec_frame_type();
+       }
+
+       mfc_debug(2, "[FRAME] frame type: %d\n", frame_type);
+
+       /* If frame is same as previous then skip and do not dequeue */
+       if (frame_type == MFC_REG_DISPLAY_FRAME_NOT_CODED)
+               if (!CODEC_NOT_CODED(ctx))
+                       return;
+
+       prev_flag = dec->dynamic_used;
+       dec->dynamic_used = mfc_get_dec_used_flag();
+       released_flag = prev_flag & (~dec->dynamic_used);
+
+       mfc_debug(2, "[DPB] Used flag: old = %08x, new = %08x, Released buffer = %08x\n",
+                       prev_flag, dec->dynamic_used, released_flag);
+
+       /* decoder dst buffer CFW UNPROT */
+       mfc_unprotect_released_dpb(ctx, released_flag);
+
+       if ((IS_VC1_RCV_DEC(ctx) &&
+               mfc_get_warn(err) == MFC_REG_ERR_SYNC_POINT_NOT_RECEIVED) ||
+               (mfc_get_warn(err) == MFC_REG_ERR_BROKEN_LINK))
+               __mfc_handle_frame_output_move(ctx, dspl_y_addr, released_flag);
+       else
+               __mfc_handle_frame_output_del(ctx, err, released_flag);
+}
+
+static void __mfc_handle_frame_error(struct mfc_ctx *ctx,
+               unsigned int reason, unsigned int err)
+{
+       struct mfc_dec *dec;
+       struct mfc_buf *src_mb;
+       unsigned int index;
+
+       if (ctx->type == MFCINST_ENCODER) {
+               mfc_err_ctx("Encoder Interrupt Error: %d\n", err);
+               return;
+       }
+
+       dec = ctx->dec_priv;
+       if (!dec) {
+               mfc_err_dev("no mfc decoder to run\n");
+               return;
+       }
+
+       mfc_err_ctx("Interrupt Error: %d\n", err);
+
+       /* Get the source buffer */
+       src_mb = mfc_get_del_buf(&ctx->buf_queue_lock, &ctx->src_buf_queue, MFC_BUF_NO_TOUCH_USED);
+
+       if (!src_mb) {
+               mfc_err_dev("no src buffers\n");
+       } else {
+               index = src_mb->vb.vb2_buf.index;
+               if (call_cop(ctx, recover_buf_ctrls_val, ctx, &ctx->src_ctrls[index]) < 0)
+                       mfc_err_ctx("failed in recover_buf_ctrls_val\n");
+
+               mfc_debug(2, "MFC needs next buffer\n");
+               dec->consumed = 0;
+
+               if (call_cop(ctx, get_buf_ctrls_val, ctx, &ctx->src_ctrls[index]) < 0)
+                       mfc_err_ctx("failed in get_buf_ctrls_val\n");
+
+               /* decoder src buffer CFW UNPROT */
+               if (ctx->is_drm)
+                       mfc_stream_unprotect(ctx, src_mb, index);
+
+               vb2_buffer_done(&src_mb->vb.vb2_buf, VB2_BUF_STATE_ERROR);
+       }
+
+       mfc_debug(2, "Assesing whether this context should be run again\n");
+}
+
+static void __mfc_handle_ref_frame(struct mfc_ctx *ctx)
+{
+       struct mfc_dev *dev = ctx->dev;
+       struct mfc_dec *dec = ctx->dec_priv;
+       struct mfc_buf *dst_mb;
+       dma_addr_t dec_addr;
+
+       dec_addr = (dma_addr_t)mfc_get_dec_y_addr();
+
+       /* Try to search decoded address in whole dst queue */
+       dst_mb = mfc_find_move_buf_used(&ctx->buf_queue_lock,
+                       &ctx->ref_buf_queue, &ctx->dst_buf_queue, dec_addr);
+       if (dst_mb) {
+               mfc_debug(2, "[DPB] Found in dst queue = 0x%08llx, buf = 0x%08llx\n",
+                               dec_addr, dst_mb->addr[0][0]);
+
+               if (!(dec->dynamic_set & mfc_get_dec_used_flag()))
+                       dec->dynamic_used |= dec->dynamic_set;
+       } else {
+               mfc_debug(2, "[DPB] Can't find buffer for addr = 0x%08llx\n", dec_addr);
+       }
+}
+
+static void __mfc_handle_reuse_buffer(struct mfc_ctx *ctx)
+{
+       struct mfc_dev *dev = ctx->dev;
+       struct mfc_dec *dec = ctx->dec_priv;
+       unsigned int prev_flag, released_flag = 0;
+       int i;
+
+       prev_flag = dec->dynamic_used;
+       dec->dynamic_used = mfc_get_dec_used_flag();
+       released_flag = prev_flag & (~dec->dynamic_used);
+
+       if (!released_flag)
+               return;
+
+       /* Reuse not referenced buf anymore */
+       for (i = 0; i < MFC_MAX_DPBS; i++)
+               if (released_flag & (1 << i))
+                       if (mfc_move_reuse_buffer(ctx, i))
+                               released_flag &= ~(1 << i);
+
+       /* Not reused buffer should be released when there is a display frame */
+       dec->dec_only_release_flag |= released_flag;
+       for (i = 0; i < MFC_MAX_DPBS; i++)
+               if (released_flag & (1 << i))
+                       clear_bit(i, &dec->available_dpb);
+}
+
+static void __mfc_handle_frame_input(struct mfc_ctx *ctx, unsigned int err)
+{
+       struct mfc_dev *dev = ctx->dev;
+       struct mfc_dec *dec = ctx->dec_priv;
+       struct mfc_buf *src_mb;
+       unsigned int index;
+       int deleted = 0;
+       unsigned long consumed;
+
+       consumed = dec->consumed + mfc_get_consumed_stream();
+
+       if (mfc_get_err(err) == MFC_REG_ERR_NON_PAIRED_FIELD) {
+               /*
+                * For non-paired field, the same buffer need to be
+                * resubmitted and the consumed stream will be 0
+                */
+               mfc_debug(2, "Not paired field. Running again the same buffer\n");
+               return;
+       }
+
+       /* Get the source buffer */
+       src_mb = mfc_get_del_if_consumed(ctx, &ctx->src_buf_queue,
+                       mfc_get_consumed_stream(), STUFF_BYTE, err, &deleted);
+       if (!src_mb) {
+               mfc_err_dev("no src buffers\n");
+               return;
+       }
+
+       index = src_mb->vb.vb2_buf.index;
+       mfc_debug(2, "[BUFINFO] ctx[%d] get src index: %d, addr: 0x%08llx\n",
+                       ctx->num, index, src_mb->addr[0][0]);
+
+       if (!deleted) {
+               /* Run MFC again on the same buffer */
+               mfc_debug(2, "[MULTIFRAME] Running again the same buffer\n");
+
+               if (CODEC_MULTIFRAME(ctx))
+                       dec->y_addr_for_pb = (dma_addr_t)mfc_get_dec_y_addr();
+
+               dec->consumed = consumed;
+               dec->remained_size = src_mb->vb.vb2_buf.planes[0].bytesused
+                                       - dec->consumed;
+               dec->has_multiframe = 1;
+
+               MFC_TRACE_CTX("** consumed:%ld, remained:%ld, addr:0x%08llx\n",
+                       dec->consumed, dec->remained_size, dec->y_addr_for_pb);
+               /* Do not move src buffer to done_list */
+               return;
+       }
+
+       if (call_cop(ctx, recover_buf_ctrls_val, ctx, &ctx->src_ctrls[index]) < 0)
+               mfc_err_ctx("failed in recover_buf_ctrls_val\n");
+
+       dec->consumed = 0;
+       dec->remained_size = 0;
+
+       if (call_cop(ctx, get_buf_ctrls_val, ctx, &ctx->src_ctrls[index]) < 0)
+               mfc_err_ctx("failed in get_buf_ctrls_val\n");
+
+       /* decoder src buffer CFW UNPROT */
+       if (ctx->is_drm)
+               mfc_stream_unprotect(ctx, src_mb, index);
+
+       vb2_buffer_done(&src_mb->vb.vb2_buf, VB2_BUF_STATE_DONE);
+}
+
+/* Handle frame decoding interrupt */
+static void __mfc_handle_frame(struct mfc_ctx *ctx,
+                       unsigned int reason, unsigned int err)
+{
+       struct mfc_dev *dev = ctx->dev;
+       struct mfc_dec *dec = ctx->dec_priv;
+       unsigned int dst_frame_status, sei_avail_frame_pack;
+       unsigned int res_change, need_dpb_change, need_scratch_change;
+
+       dst_frame_status = mfc_get_disp_status();
+       res_change = mfc_get_res_change();
+       need_dpb_change = mfc_get_dpb_change();
+       need_scratch_change = mfc_get_scratch_change();
+       sei_avail_frame_pack = mfc_get_sei_avail_frame_pack();
+
+       if (dec->immediate_display == 1)
+               dst_frame_status = mfc_get_dec_status();
+
+       mfc_debug(2, "[FRAME] frame status: %d\n", dst_frame_status);
+       mfc_debug(2, "[FRAME] display status: %d, type: %d, yaddr: %#x\n",
+                       mfc_get_disp_status(), mfc_get_disp_frame_type(),
+                       mfc_get_disp_y_addr());
+       mfc_debug(2, "[FRAME] decoded status: %d, type: %d, yaddr: %#x\n",
+                       mfc_get_dec_status(), mfc_get_dec_frame_type(),
+                       mfc_get_dec_y_addr());
+
+       mfc_debug(4, "[HDR] SEI available status: 0x%08x\n", mfc_get_sei_avail());
+       mfc_debug(4, "[HDR] SEI content light: 0x%08x\n", mfc_get_sei_content_light());
+       mfc_debug(4, "[HDR] SEI luminance: 0x%08x, 0x%08x white point: 0x%08x\n",
+                       mfc_get_sei_mastering0(), mfc_get_sei_mastering1(),
+                       mfc_get_sei_mastering2());
+       mfc_debug(4, "[HDR] SEI display primaries: 0x%08x, 0x%08x, 0x%08x\n",
+                       mfc_get_sei_mastering3(), mfc_get_sei_mastering4(),
+                       mfc_get_sei_mastering5());
+       mfc_debug(2, "[DPB] Used flag: old = %08x, new = %08x\n",
+                               dec->dynamic_used, mfc_get_dec_used_flag());
+
+       if (ctx->state == MFCINST_RES_CHANGE_INIT)
+               mfc_change_state(ctx, MFCINST_RES_CHANGE_FLUSH);
+
+       if (res_change) {
+               mfc_debug(2, "[DRC] Resolution change set to %d\n", res_change);
+               mfc_change_state(ctx, MFCINST_RES_CHANGE_INIT);
+               ctx->wait_state = WAIT_DECODING;
+               mfc_debug(7, "[DRC] Decoding waiting! : %d\n", ctx->wait_state);
+               return;
+       }
+
+       if (need_dpb_change || need_scratch_change)
+               mfc_debug(2, "[DRC] Interframe resolution change is not supported\n");
+
+       if (mfc_is_queue_count_same(&ctx->buf_queue_lock, &ctx->src_buf_queue, 0) &&
+               mfc_is_queue_count_same(&ctx->buf_queue_lock, &ctx->dst_buf_queue, 0)) {
+               mfc_err_dev("Queue count is zero for src and dst\n");
+               goto leave_handle_frame;
+       }
+
+       if (IS_H264_DEC(ctx) && sei_avail_frame_pack &&
+               dst_frame_status == MFC_REG_DEC_STATUS_DECODING_ONLY) {
+               mfc_debug(2, "Frame packing SEI exists for a frame\n");
+               mfc_debug(2, "Reallocate DPBs and issue init_buffer\n");
+               ctx->is_dpb_realloc = 1;
+               mfc_change_state(ctx, MFCINST_HEAD_PARSED);
+               ctx->capture_state = QUEUE_FREE;
+               ctx->wait_state = WAIT_DECODING;
+               __mfc_handle_frame_all_extracted(ctx);
+               goto leave_handle_frame;
+       }
+
+       /* All frames remaining in the buffer have been extracted  */
+       if (dst_frame_status == MFC_REG_DEC_STATUS_DECODING_EMPTY) {
+               if (ctx->state == MFCINST_RES_CHANGE_FLUSH) {
+                       struct mfc_timestamp *temp_ts = NULL;
+
+                       mfc_debug(2, "[DRC] Last frame received after resolution change\n");
+                       __mfc_handle_frame_all_extracted(ctx);
+                       mfc_change_state(ctx, MFCINST_RES_CHANGE_END);
+                       /* If there is no display frame after resolution change,
+                        * Some released frames can't be unprotected.
+                        * So, check and request unprotection in the end of DRC.
+                        */
+                       mfc_cleanup_assigned_dpb(ctx);
+
+                       /* empty the timestamp queue */
+                       while (!list_empty(&ctx->ts_list)) {
+                               temp_ts = list_entry((&ctx->ts_list)->next,
+                                               struct mfc_timestamp, list);
+                               list_del(&temp_ts->list);
+                       }
+                       ctx->ts_count = 0;
+                       ctx->ts_is_full = 0;
+                       mfc_qos_reset_last_framerate(ctx);
+                       mfc_qos_set_framerate(ctx, DEC_DEFAULT_FPS);
+
+                       goto leave_handle_frame;
+               } else {
+                       __mfc_handle_frame_all_extracted(ctx);
+               }
+       }
+
+       if (mfc_get_num_of_tile() >= 4)
+               dec->num_of_tile_over_4 = 1;
+
+       switch (dst_frame_status) {
+       case MFC_REG_DEC_STATUS_DECODING_DISPLAY:
+               __mfc_handle_ref_frame(ctx);
+               break;
+       case MFC_REG_DEC_STATUS_DECODING_ONLY:
+               __mfc_handle_ref_frame(ctx);
+               /*
+                * Some cases can have many decoding only frames like VP9
+                * alt-ref frame. So need handling release buffer
+                * because of DPB full.
+                */
+               __mfc_handle_reuse_buffer(ctx);
+               break;
+       default:
+               break;
+       }
+
+       if (mfc_dec_status_decoding(dst_frame_status))
+               __mfc_handle_frame_copy_timestamp(ctx);
+
+       /* A frame has been decoded and is in the buffer  */
+       if (mfc_dec_status_display(dst_frame_status))
+               __mfc_handle_frame_new(ctx, err);
+       else
+               mfc_debug(2, "No frame decode\n");
+
+       /* Mark source buffer as complete */
+       if (dst_frame_status != MFC_REG_DEC_STATUS_DISPLAY_ONLY)
+               __mfc_handle_frame_input(ctx, err);
+
+leave_handle_frame:
+       mfc_debug(2, "Assesing whether this context should be run again\n");
+}
+
+static void __mfc_handle_stream_copy_timestamp(struct mfc_ctx *ctx, struct mfc_buf *src_mb)
+{
+       struct mfc_dev *dev;
+       struct mfc_enc *enc = ctx->enc_priv;
+       struct mfc_enc_params *p = &enc->params;
+       struct mfc_buf *dst_mb;
+       u32 interval;
+       u64 start_timestamp;
+       u64 new_timestamp;
+
+       if (!ctx) {
+               mfc_err_dev("[BUFCON][TS] no mfc context to run\n");
+               return;
+       }
+
+       dev = ctx->dev;
+       if (!dev) {
+               mfc_err_dev("[BUFCON][TS] no device to run\n");
+               return;
+       }
+
+       start_timestamp = src_mb->vb.vb2_buf.timestamp;
+       interval = NSEC_PER_SEC / p->rc_framerate;
+       if (debug_ts == 1)
+               mfc_info_ctx("[BUFCON][TS] %dfps, start timestamp: %lld, base interval: %d\n",
+                               p->rc_framerate, start_timestamp, interval);
+
+       new_timestamp = start_timestamp + (interval * src_mb->done_index);
+       if (debug_ts == 1)
+               mfc_info_ctx("[BUFCON][TS] new timestamp: %lld, interval: %d\n",
+                               new_timestamp, interval * src_mb->done_index);
+
+       /* Get the destination buffer */
+       dst_mb = mfc_get_buf(&ctx->buf_queue_lock, &ctx->dst_buf_queue, MFC_BUF_NO_TOUCH_USED);
+       if (dst_mb)
+               dst_mb->vb.vb2_buf.timestamp = new_timestamp;
+}
+
+static void __mfc_handle_stream_input(struct mfc_ctx *ctx)
+{
+       struct mfc_raw_info *raw;
+       struct mfc_buf *ref_mb, *src_mb;
+       dma_addr_t enc_addr[3] = { 0, 0, 0 };
+       int i, found_in_src_queue = 0;
+       unsigned int index;
+
+       raw = &ctx->raw_buf;
+
+       mfc_get_enc_frame_buffer(ctx, &enc_addr[0], raw->num_planes);
+       if (enc_addr[0] == 0) {
+               mfc_debug(3, "no encoded src\n");
+               goto move_buf;
+       }
+       for (i = 0; i < raw->num_planes; i++)
+               mfc_debug(2, "[BUFINFO] ctx[%d] get src addr[%d]: 0x%08llx\n",
+                               ctx->num, i, enc_addr[i]);
+
+       if (IS_BUFFER_BATCH_MODE(ctx)) {
+               src_mb = mfc_find_first_buf(&ctx->buf_queue_lock,
+                               &ctx->src_buf_queue, enc_addr[0]);
+               if (src_mb) {
+                       found_in_src_queue = 1;
+
+                       __mfc_handle_stream_copy_timestamp(ctx, src_mb);
+                       src_mb->done_index++;
+                       mfc_debug(4, "[BUFCON] batch buf done_index: %d\n", src_mb->done_index);
+
+                       index = src_mb->vb.vb2_buf.index;
+
+                       if (call_cop(ctx, recover_buf_ctrls_val, ctx,
+                                               &ctx->src_ctrls[index]) < 0)
+                               mfc_err_ctx("failed in recover_buf_ctrls_val\n");
+
+                       /* single buffer || last image in a buffer container */
+                       if (!src_mb->num_valid_bufs || src_mb->done_index == src_mb->num_valid_bufs) {
+                               src_mb = mfc_find_del_buf(&ctx->buf_queue_lock,
+                                               &ctx->src_buf_queue, enc_addr[0]);
+                               for (i = 0; i < raw->num_planes; i++)
+                                       mfc_bufcon_put_daddr(ctx, src_mb, i);
+                               vb2_buffer_done(&src_mb->vb.vb2_buf, VB2_BUF_STATE_DONE);
+                       }
+
+                       /* encoder src buffer CFW UNPROT */
+                       if (ctx->is_drm)
+                               mfc_raw_unprotect(ctx, src_mb, index);
+               }
+       } else {
+               /* normal single buffer */
+               src_mb = mfc_find_del_buf(&ctx->buf_queue_lock,
+                               &ctx->src_buf_queue, enc_addr[0]);
+               if (src_mb) {
+                       found_in_src_queue = 1;
+                       index = src_mb->vb.vb2_buf.index;
+                       if (call_cop(ctx, recover_buf_ctrls_val, ctx,
+                                               &ctx->src_ctrls[index]) < 0)
+                               mfc_err_ctx("failed in recover_buf_ctrls_val\n");
+
+                       mfc_debug(3, "find src buf in src_queue\n");
+                       vb2_buffer_done(&src_mb->vb.vb2_buf, VB2_BUF_STATE_DONE);
+
+                       /* encoder src buffer CFW UNPROT */
+                       if (ctx->is_drm)
+                               mfc_raw_unprotect(ctx, src_mb, index);
+               } else {
+                       mfc_debug(3, "no src buf in src_queue\n");
+                       ref_mb = mfc_find_del_buf(&ctx->buf_queue_lock,
+                                       &ctx->ref_buf_queue, enc_addr[0]);
+                       if (ref_mb) {
+                               mfc_debug(3, "find src buf in ref_queue\n");
+                               vb2_buffer_done(&ref_mb->vb.vb2_buf, VB2_BUF_STATE_DONE);
+
+                               /* encoder src buffer CFW UNPROT */
+                               if (ctx->is_drm) {
+                                       index = ref_mb->vb.vb2_buf.index;
+                                       mfc_raw_unprotect(ctx, ref_mb, index);
+                               }
+                       } else {
+                               mfc_err_ctx("couldn't find src buffer\n");
+                       }
+               }
+       }
+
+move_buf:
+       /* move enqueued src buffer: src queue -> ref queue */
+       if (!found_in_src_queue && ctx->state != MFCINST_FINISHING) {
+               mfc_move_first_buf_used(&ctx->buf_queue_lock,
+                               &ctx->ref_buf_queue, &ctx->src_buf_queue, MFC_QUEUE_ADD_BOTTOM);
+
+               mfc_debug(2, "enc src_buf_queue(%d) -> ref_buf_queue(%d)\n",
+                               mfc_get_queue_count(&ctx->buf_queue_lock, &ctx->src_buf_queue),
+                               mfc_get_queue_count(&ctx->buf_queue_lock, &ctx->ref_buf_queue));
+       }
+}
+
+static void __mfc_handle_stream_output(struct mfc_ctx *ctx, int slice_type,
+                                       unsigned int strm_size)
+{
+       struct mfc_enc *enc = ctx->enc_priv;
+       struct mfc_buf *dst_mb;
+       unsigned int index;
+
+       if (strm_size == 0) {
+               mfc_debug(3, "no encoded dst (reuse)\n");
+               return;
+       } else if (strm_size < 0) {
+               mfc_err_ctx("invalid stream size: %d\n", strm_size);
+               return;
+       }
+
+       /* at least one more dest. buffers exist always  */
+       dst_mb = mfc_get_del_buf(&ctx->buf_queue_lock,
+                       &ctx->dst_buf_queue, MFC_BUF_NO_TOUCH_USED);
+       if (!dst_mb) {
+               mfc_err_ctx("no dst buffers\n");
+               return;
+       }
+
+       mfc_debug(2, "[BUFINFO] ctx[%d] get dst addr: 0x%08llx\n",
+                       ctx->num, dst_mb->addr[0][0]);
+
+       dst_mb->vb.flags &= ~(V4L2_BUF_FLAG_KEYFRAME |
+                               V4L2_BUF_FLAG_PFRAME |
+                               V4L2_BUF_FLAG_BFRAME);
+       switch (slice_type) {
+       case MFC_REG_E_SLICE_TYPE_I:
+               dst_mb->vb.flags |= V4L2_BUF_FLAG_KEYFRAME;
+               break;
+       case MFC_REG_E_SLICE_TYPE_P:
+               dst_mb->vb.flags |= V4L2_BUF_FLAG_PFRAME;
+               break;
+       case MFC_REG_E_SLICE_TYPE_B:
+               dst_mb->vb.flags |= V4L2_BUF_FLAG_BFRAME;
+               break;
+       default:
+               dst_mb->vb.flags |= V4L2_BUF_FLAG_KEYFRAME;
+               break;
+       }
+       mfc_debug(2, "[STREAM] Slice type flag: %d\n", dst_mb->vb.flags);
+
+       if (IS_BPG_ENC(ctx)) {
+               strm_size += enc->header_size;
+               mfc_debug(2, "bpg total stream size: %d\n", strm_size);
+       }
+       vb2_set_plane_payload(&dst_mb->vb.vb2_buf, 0, strm_size);
+
+       index = dst_mb->vb.vb2_buf.index;
+       if (call_cop(ctx, get_buf_ctrls_val, ctx, &ctx->dst_ctrls[index]) < 0)
+               mfc_err_ctx("failed in get_buf_ctrls_val\n");
+
+       vb2_buffer_done(&dst_mb->vb.vb2_buf, VB2_BUF_STATE_DONE);
+
+       /* encoder dst buffer CFW UNPROT */
+       if (ctx->is_drm)
+               mfc_stream_unprotect(ctx, dst_mb, index);
+}
+
+/* Handle frame encoding interrupt */
+static int __mfc_handle_stream(struct mfc_ctx *ctx)
+{
+       struct mfc_dev *dev = ctx->dev;
+       struct mfc_enc *enc = ctx->enc_priv;
+       int slice_type;
+       unsigned int strm_size;
+       unsigned int pic_count;
+
+       slice_type = mfc_get_enc_slice_type();
+       strm_size = mfc_get_enc_strm_size();
+       pic_count = mfc_get_enc_pic_count();
+
+       mfc_debug(2, "[STREAM] encoded slice type: %d, size: %d, display order: %d\n",
+                       slice_type, strm_size, pic_count);
+
+       /* buffer full handling */
+       if (enc->buf_full) {
+               mfc_change_state(ctx, MFCINST_ABORT_INST);
+               return 0;
+       }
+       if (ctx->state == MFCINST_RUNNING_BUF_FULL)
+               mfc_change_state(ctx, MFCINST_RUNNING);
+
+       /* set encoded frame type */
+       enc->frame_type = slice_type;
+       ctx->sequence++;
+
+       if (enc->in_slice) {
+               if (mfc_is_queue_count_same(&ctx->buf_queue_lock, &ctx->dst_buf_queue, 0)) {
+                       mfc_clear_bit(ctx->num, &dev->work_bits);
+               }
+               return 0;
+       }
+
+       /* handle source buffer */
+       __mfc_handle_stream_input(ctx);
+
+       /* handle destination buffer */
+       __mfc_handle_stream_output(ctx, slice_type, strm_size);
+
+       return 0;
+}
+
+/* Error handling for interrupt */
+static inline void __mfc_handle_error(struct mfc_ctx *ctx,
+       unsigned int reason, unsigned int err)
+{
+       struct mfc_dev *dev = ctx->dev;
+       struct mfc_buf *src_mb;
+       int index;
+
+       mfc_err_ctx("Interrupt Error: display: %d, decoded: %d\n",
+                       mfc_get_warn(err), mfc_get_err(err));
+       err = mfc_get_err(err);
+
+       /* Error recovery is dependent on the state of context */
+       switch (ctx->state) {
+       case MFCINST_RES_CHANGE_END:
+       case MFCINST_GOT_INST:
+               /* This error had to happen while parsing the header */
+               if (!ctx->is_drm) {
+                       unsigned char *stream_vir = NULL;
+                       unsigned int strm_size = 0;
+
+                       src_mb = mfc_get_del_buf(&ctx->buf_queue_lock, &ctx->src_buf_queue, MFC_BUF_NO_TOUCH_USED);
+                       if (src_mb) {
+                               stream_vir = src_mb->vir_addr;
+                               strm_size = src_mb->vb.vb2_buf.planes[0].bytesused;
+                               if (strm_size > 32)
+                                       strm_size = 32;
+
+                               if (stream_vir && strm_size)
+                                       print_hex_dump(KERN_ERR, "No header: ",
+                                                       DUMP_PREFIX_ADDRESS, strm_size, 0,
+                                                       stream_vir, strm_size, false);
+
+                               vb2_buffer_done(&src_mb->vb.vb2_buf, VB2_BUF_STATE_DONE);
+                       }
+               } else {
+                       src_mb = mfc_get_del_buf(&ctx->buf_queue_lock, &ctx->src_buf_queue, MFC_BUF_NO_TOUCH_USED);
+                       if (src_mb) {
+                               index = src_mb->vb.vb2_buf.index;
+                               /* decoder src buffer CFW UNPROT */
+                               mfc_stream_unprotect(ctx, src_mb, index);
+                               vb2_buffer_done(&src_mb->vb.vb2_buf, VB2_BUF_STATE_DONE);
+                       }
+               }
+               break;
+       case MFCINST_INIT:
+               /* This error had to happen while acquireing instance */
+       case MFCINST_RETURN_INST:
+               /* This error had to happen while releasing instance */
+       case MFCINST_DPB_FLUSHING:
+               /* This error had to happen while flushing DPB */
+       case MFCINST_SPECIAL_PARSING:
+       case MFCINST_SPECIAL_PARSING_NAL:
+               /* This error had to happen while special parsing */
+               break;
+       case MFCINST_HEAD_PARSED:
+               /* This error had to happen while setting dst buffers */
+       case MFCINST_RES_CHANGE_INIT:
+       case MFCINST_RES_CHANGE_FLUSH:
+               /* This error has to happen while resolution change */
+       case MFCINST_ABORT_INST:
+               /* This error has to happen while buffer full handling */
+       case MFCINST_FINISHING:
+               /* It is higly probable that an error occured
+                * while decoding a frame */
+               mfc_change_state(ctx, MFCINST_ERROR);
+               /* Mark all dst buffers as having an error */
+               mfc_cleanup_queue(&ctx->buf_queue_lock, &ctx->dst_buf_queue);
+               /* Mark all src buffers as having an error */
+               mfc_cleanup_queue(&ctx->buf_queue_lock, &ctx->src_buf_queue);
+               break;
+       default:
+               mfc_err_ctx("Encountered an error interrupt which had not been handled\n");
+               mfc_err_ctx("ctx->state = %d, ctx->inst_no = %d\n",
+                                               ctx->state, ctx->inst_no);
+               break;
+       }
+
+       mfc_wake_up_dev(dev, reason, err);
+
+       return;
+}
+
+/* Handle header decoder interrupt */
+static int __mfc_handle_seq_dec(struct mfc_ctx *ctx)
+{
+       struct mfc_dev *dev = ctx->dev;
+       struct mfc_dec *dec = ctx->dec_priv;
+       int i, is_interlace, is_mbaff;
+
+       if (ctx->src_fmt->fourcc != V4L2_PIX_FMT_FIMV1) {
+               ctx->img_width = mfc_get_img_width();
+               ctx->img_height = mfc_get_img_height();
+               ctx->crop_width = ctx->img_width;
+               ctx->crop_height = ctx->img_height;
+               mfc_info_ctx("[STREAM] resolution w: %d, h: %d\n", ctx->img_width, ctx->img_height);
+       }
+
+       ctx->dpb_count = mfc_get_dpb_count();
+       ctx->scratch_buf_size = mfc_get_scratch_size();
+       for (i = 0; i < ctx->dst_fmt->num_planes; i++)
+               ctx->min_dpb_size[i] = mfc_get_min_dpb_size(i);
+
+       mfc_dec_store_crop_info(ctx);
+       dec->mv_count = mfc_get_mv_count();
+       if (CODEC_10BIT(ctx) && dev->pdata->support_10bit) {
+               if (mfc_get_luma_bit_depth_minus8() ||
+                       mfc_get_chroma_bit_depth_minus8() ||
+                       mfc_get_profile() == MFC_REG_D_PROFILE_HEVC_MAIN_10) {
+                       ctx->is_10bit = 1;
+                       mfc_info_ctx("[STREAM][10BIT] 10bit contents, profile: %d, depth: %d/%d\n",
+                                       mfc_get_profile(),
+                                       mfc_get_luma_bit_depth_minus8() + 8,
+                                       mfc_get_chroma_bit_depth_minus8() + 8);
+               }
+       }
+       if (CODEC_422FORMAT(ctx) && dev->pdata->support_422) {
+               if (mfc_get_chroma_format() == MFC_REG_D_CHROMA_422) {
+                       ctx->is_422 = 1;
+                       mfc_info_ctx("[STREAM] 422 chroma format\n");
+               }
+       }
+
+       if (ctx->img_width == 0 || ctx->img_height == 0)
+               mfc_change_state(ctx, MFCINST_ERROR);
+       else
+               mfc_change_state(ctx, MFCINST_HEAD_PARSED);
+
+       if (ctx->state == MFCINST_HEAD_PARSED) {
+               is_interlace = mfc_is_interlace_picture();
+               is_mbaff = mfc_is_mbaff_picture();
+               if (is_interlace || is_mbaff)
+                       dec->is_interlaced = 1;
+               mfc_debug(2, "[INTERLACE] interlace: %d, mbaff: %d\n", is_interlace, is_mbaff);
+       }
+
+       if (IS_H264_DEC(ctx) || IS_H264_MVC_DEC(ctx) || IS_HEVC_DEC(ctx)) {
+               struct mfc_buf *src_mb = mfc_get_buf(&ctx->buf_queue_lock, &ctx->src_buf_queue, MFC_BUF_NO_TOUCH_USED);
+               if (src_mb) {
+                       dec->consumed += mfc_get_consumed_stream();
+                       mfc_debug(2, "[STREAM] header total size : %d, consumed : %lu\n",
+                                       src_mb->vb.vb2_buf.planes[0].bytesused, dec->consumed);
+                       if ((dec->consumed > 0) &&
+                                       (src_mb->vb.vb2_buf.planes[0].bytesused > dec->consumed)) {
+                               dec->remained_size = src_mb->vb.vb2_buf.planes[0].bytesused -
+                                       dec->consumed;
+                               mfc_debug(2, "[STREAM] there is remained bytes(%lu) after header parsing\n",
+                                               dec->remained_size);
+                       } else {
+                               dec->consumed = 0;
+                               dec->remained_size = 0;
+                       }
+               }
+       }
+
+       if (IS_VP9_DEC(ctx)) {
+               dec->color_range = mfc_get_color_range();
+               dec->color_space = mfc_get_color_space();
+               mfc_debug(2, "color range: %d, color space: %d, It's valid for VP9\n",
+                               dec->color_range, dec->color_space);
+       }
+
+       return 0;
+}
+
+/* Handle header encoder interrupt */
+static int __mfc_handle_seq_enc(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_buf *dst_mb;
+       int ret;
+
+       enc->header_size = mfc_get_enc_strm_size();
+       mfc_debug(2, "[STREAM] encoded slice type: %d, header size: %d, display order: %d\n",
+                       mfc_get_enc_slice_type(), enc->header_size,
+                       mfc_get_enc_pic_count());
+
+       if (IS_BPG_ENC(ctx)) {
+               dst_mb = mfc_get_buf(&ctx->buf_queue_lock, &ctx->dst_buf_queue, MFC_BUF_NO_TOUCH_USED);
+               if (!dst_mb) {
+                       mfc_err_dev("no dst buffers\n");
+                       return -EAGAIN;
+               }
+
+               dst_mb->vb.vb2_buf.planes[0].data_offset += (enc->header_size +
+                               p->codec.bpg.thumb_size + p->codec.bpg.exif_size);
+               mfc_debug(2, "offset for NAL_START: %d (header: %d + thumb: %d + exif: %d)\n",
+                               dst_mb->vb.vb2_buf.planes[0].data_offset,
+                               enc->header_size,
+                               p->codec.bpg.thumb_size,
+                               p->codec.bpg.exif_size);
+       } else {
+               if ((p->seq_hdr_mode == V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE) ||
+                       (p->seq_hdr_mode == V4L2_MPEG_VIDEO_HEADER_MODE_AT_THE_READY)) {
+                       dst_mb = mfc_get_del_buf(&ctx->buf_queue_lock,
+                                       &ctx->dst_buf_queue, MFC_BUF_NO_TOUCH_USED);
+                       if (!dst_mb) {
+                               mfc_err_dev("no dst buffers\n");
+                               return -EAGAIN;
+                       }
+
+                       vb2_set_plane_payload(&dst_mb->vb.vb2_buf, 0, mfc_get_enc_strm_size());
+                       vb2_buffer_done(&dst_mb->vb.vb2_buf, VB2_BUF_STATE_DONE);
+
+                       /* encoder dst buffer CFW UNPROT */
+                       if (ctx->is_drm) {
+                               int index = dst_mb->vb.vb2_buf.index;
+
+                               mfc_stream_unprotect(ctx, dst_mb, index);
+                       }
+               }
+       }
+
+       ctx->dpb_count = mfc_get_enc_dpb_count();
+       ctx->scratch_buf_size = mfc_get_enc_scratch_size();
+
+       /* If the ROI is enabled at SEQ_START, clear ROI_ENABLE bit */
+       mfc_clear_roi_enable(dev);
+
+       if (!ctx->codec_buffer_allocated) {
+               mfc_debug(2, "[DRC] previous codec buffer is exist\n");
+
+               if (dev->has_mmcache && dev->mmcache.is_on_status)
+                       mfc_invalidate_mmcache(dev);
+
+               mfc_release_codec_buffers(ctx);
+       }
+       ret = mfc_alloc_codec_buffers(ctx);
+       if (ret) {
+               mfc_err_ctx("Failed to allocate encoding buffers\n");
+               return ret;
+       }
+
+       mfc_change_state(ctx, MFCINST_HEAD_PARSED);
+
+       return 0;
+}
+
+static inline int is_err_condition(unsigned int err)
+{
+       if (err == MFC_REG_ERR_NO_AVAILABLE_DPB ||
+               err == MFC_REG_ERR_INSUFFICIENT_DPB_SIZE ||
+               err == MFC_REG_ERR_INSUFFICIENT_NUM_DPB ||
+               err == MFC_REG_ERR_INSUFFICIENT_MV_BUF_SIZE ||
+               err == MFC_REG_ERR_INSUFFICIENT_SCRATCH_BUF_SIZE)
+               return 1;
+
+       return 0;
+}
+
+irqreturn_t mfc_top_half_irq(int irq, void *priv)
+{
+       struct mfc_dev *dev = priv;
+       struct mfc_ctx *ctx;
+       unsigned int err;
+       unsigned int reason;
+
+       ctx = dev->ctx[dev->curr_ctx];
+       if (!ctx) {
+               mfc_err_dev("no mfc context to run\n");
+               return IRQ_WAKE_THREAD;
+       }
+
+       reason = mfc_get_int_reason();
+       err = mfc_get_int_err();
+       mfc_debug(2, "[c:%d] Int reason: %d (err: %d)\n",
+                       dev->curr_ctx, reason, err);
+       MFC_TRACE_CTX("<< INT(top): %d\n", reason);
+
+       mfc_perf_measure_off(dev);
+
+       return IRQ_WAKE_THREAD;
+}
+
+/*
+ * Return value description
+ *  0: NAL-Q is handled successfully
+ *  1: NAL_START command
+ * -1: Error
+*/
+static inline int __mfc_nal_q_irq(struct mfc_dev *dev,
+               unsigned int reason, unsigned int err)
+{
+       int ret = -1;
+       unsigned int errcode;
+
+       nal_queue_handle *nal_q_handle = dev->nal_q_handle;
+       EncoderOutputStr *pOutStr;
+
+       switch (reason) {
+       case MFC_REG_R2H_CMD_QUEUE_DONE_RET:
+               pOutStr = mfc_nal_q_dequeue_out_buf(dev,
+                       nal_q_handle->nal_q_out_handle, &errcode);
+               if (pOutStr) {
+                       if (mfc_nal_q_handle_out_buf(dev, pOutStr))
+                               mfc_err_dev("[NALQ] Failed to handle out buf\n");
+               } else {
+                       mfc_err_dev("[NALQ] pOutStr is NULL\n");
+               }
+
+               if (nal_q_handle->nal_q_exception)
+                       mfc_set_bit(nal_q_handle->nal_q_out_handle->nal_q_ctx,
+                                       &dev->work_bits);
+               mfc_clear_int_sfr();
+
+               if (!nal_q_handle->nal_q_exception)
+                       mfc_nal_q_clock_off(dev, nal_q_handle);
+
+               ret = 0;
+               break;
+       case MFC_REG_R2H_CMD_COMPLETE_QUEUE_RET:
+               mfc_watchdog_stop_tick(dev);
+               nal_q_handle->nal_q_state = NAL_Q_STATE_CREATED;
+               MFC_TRACE_DEV("** NAL Q state : %d\n", nal_q_handle->nal_q_state);
+               mfc_debug(2, "[NALQ] return to created state\n");
+               mfc_nal_q_cleanup_queue(dev);
+               mfc_nal_q_cleanup_clock(dev);
+               mfc_clear_int_sfr();
+               mfc_pm_clock_off(dev);
+               mfc_wake_up_dev(dev, reason, err);
+
+               ret = 0;
+               break;
+       default:
+               if (nal_q_handle->nal_q_state == NAL_Q_STATE_STARTED ||
+                       nal_q_handle->nal_q_state == NAL_Q_STATE_STOPPED) {
+                       mfc_err_dev("[NALQ] Should not be here! state: %d, int reason : %d\n",
+                               nal_q_handle->nal_q_state, reason);
+                       mfc_clear_int_sfr();
+
+                       ret = -1;
+               } else {
+                       /* NAL START */
+                       ret = 1;
+               }
+
+               break;
+       }
+
+       if (ret == 0)
+               queue_work(dev->butler_wq, &dev->butler_work);
+
+       return ret;
+}
+
+static inline int __mfc_handle_done_frame(struct mfc_ctx *ctx,
+                               unsigned int reason, unsigned int err)
+{
+       struct mfc_dev *dev = ctx->dev;
+       struct mfc_enc *enc = NULL;
+
+       if (ctx->type == MFCINST_DECODER) {
+               if (ctx->state == MFCINST_SPECIAL_PARSING_NAL) {
+                       mfc_clear_int_sfr();
+                       mfc_pm_clock_off(dev);
+                       mfc_clear_bit(ctx->num, &dev->work_bits);
+                       mfc_change_state(ctx, MFCINST_RUNNING);
+                       mfc_wake_up_ctx(ctx, reason, err);
+                       return 0;
+               }
+               __mfc_handle_frame(ctx, reason, err);
+       } else if (ctx->type == MFCINST_ENCODER) {
+               if (ctx->otf_handle) {
+                       mfc_otf_handle_stream(ctx);
+                       return 1;
+               }
+               enc = ctx->enc_priv;
+               if (reason == MFC_REG_R2H_CMD_SLICE_DONE_RET) {
+                       dev->preempt_ctx = ctx->num;
+                       enc->buf_full = 0;
+                       enc->in_slice = 1;
+               } else if (reason == MFC_REG_R2H_CMD_ENC_BUFFER_FULL_RET) {
+                       mfc_err_ctx("stream buffer size(%d) isn't enough\n",
+                                       mfc_get_enc_strm_size());
+                       dev->preempt_ctx = ctx->num;
+                       enc->buf_full = 1;
+                       enc->in_slice = 0;
+               } else {
+                       enc->buf_full = 0;
+                       enc->in_slice = 0;
+               }
+               __mfc_handle_stream(ctx);
+       }
+
+       return 1;
+}
+
+static inline void __mfc_handle_nal_abort(struct mfc_ctx *ctx)
+{
+       struct mfc_enc *enc = ctx->enc_priv;
+
+       if (ctx->type == MFCINST_ENCODER) {
+               mfc_change_state(ctx, MFCINST_RUNNING_BUF_FULL);
+               enc->buf_full = 0;
+               if (IS_VP8_ENC(ctx))
+                       mfc_err_ctx("stream buffer size isn't enough\n");
+               __mfc_handle_stream(ctx);
+       } else {
+               mfc_change_state(ctx, MFCINST_ABORT);
+       }
+}
+
+static int __mfc_irq_dev(struct mfc_dev *dev, unsigned int reason, unsigned int err)
+{
+       /* Stop the timeout watchdog */
+       if (reason != MFC_REG_R2H_CMD_FW_STATUS_RET)
+               mfc_watchdog_stop_tick(dev);
+
+       switch (reason) {
+       case MFC_REG_R2H_CMD_CACHE_FLUSH_RET:
+       case MFC_REG_R2H_CMD_SYS_INIT_RET:
+       case MFC_REG_R2H_CMD_FW_STATUS_RET:
+       case MFC_REG_R2H_CMD_SLEEP_RET:
+       case MFC_REG_R2H_CMD_WAKEUP_RET:
+               mfc_clear_int_sfr();
+               mfc_wake_up_dev(dev, reason, err);
+               return 0;
+       }
+
+       return 1;
+}
+
+static int __mfc_irq_ctx(struct mfc_ctx *ctx, unsigned int reason, unsigned int err)
+{
+       struct mfc_dev *dev = ctx->dev;
+
+       switch (reason) {
+       case MFC_REG_R2H_CMD_ERR_RET:
+               if (ctx->otf_handle) {
+                       mfc_otf_handle_error(ctx, reason, err);
+                       break;
+               }
+               /* An error has occured */
+               if (ctx->state == MFCINST_RUNNING || ctx->state == MFCINST_ABORT) {
+                       if ((mfc_get_err(err) >= MFC_REG_ERR_WARNINGS_START) &&
+                               (mfc_get_err(err) <= MFC_REG_ERR_WARNINGS_END))
+                               __mfc_handle_frame(ctx, reason, err);
+                       else
+                               __mfc_handle_frame_error(ctx, reason, err);
+               } else {
+                       __mfc_handle_error(ctx, reason, err);
+               }
+               break;
+       case MFC_REG_R2H_CMD_SLICE_DONE_RET:
+       case MFC_REG_R2H_CMD_FIELD_DONE_RET:
+       case MFC_REG_R2H_CMD_FRAME_DONE_RET:
+       case MFC_REG_R2H_CMD_ENC_BUFFER_FULL_RET:
+               return __mfc_handle_done_frame(ctx, reason, err);
+       case MFC_REG_R2H_CMD_COMPLETE_SEQ_RET:
+               if (ctx->type == MFCINST_ENCODER) {
+                       __mfc_handle_stream(ctx);
+                       mfc_change_state(ctx, MFCINST_RUNNING);
+               } else if (ctx->type == MFCINST_DECODER) {
+                       return __mfc_handle_done_frame(ctx, reason, err);
+               }
+               break;
+       case MFC_REG_R2H_CMD_SEQ_DONE_RET:
+               if (ctx->type == MFCINST_ENCODER) {
+                       if (ctx->otf_handle) {
+                               mfc_otf_handle_seq(ctx);
+                               break;
+                       }
+                       __mfc_handle_seq_enc(ctx);
+               } else if (ctx->type == MFCINST_DECODER) {
+                       __mfc_handle_seq_dec(ctx);
+               }
+               break;
+       case MFC_REG_R2H_CMD_OPEN_INSTANCE_RET:
+               ctx->inst_no = mfc_get_inst_no();
+               mfc_change_state(ctx, MFCINST_GOT_INST);
+               break;
+       case MFC_REG_R2H_CMD_CLOSE_INSTANCE_RET:
+               mfc_change_state(ctx, MFCINST_FREE);
+               break;
+       case MFC_REG_R2H_CMD_NAL_ABORT_RET:
+               __mfc_handle_nal_abort(ctx);
+               break;
+       case MFC_REG_R2H_CMD_DPB_FLUSH_RET:
+               mfc_change_state(ctx, MFCINST_ABORT);
+               break;
+       case MFC_REG_R2H_CMD_INIT_BUFFERS_RET:
+               if (err != 0) {
+                       mfc_err_ctx("INIT_BUFFERS_RET error: %d\n", err);
+                       break;
+               }
+
+               mfc_change_state(ctx, MFCINST_RUNNING);
+               if (ctx->type == MFCINST_DECODER) {
+                       if (ctx->wait_state == WAIT_DECODING) {
+                               ctx->wait_state = WAIT_INITBUF_DONE;
+                               mfc_debug(2, "INIT_BUFFER has done, but can't start decoding\n");
+                       }
+                       if (ctx->is_dpb_realloc)
+                               ctx->is_dpb_realloc = 0;
+               }
+               break;
+       default:
+               mfc_err_ctx("Unknown int reason: %d\n", reason);
+       }
+
+       return 1;
+}
+
+/* Interrupt processing */
+irqreturn_t mfc_irq(int irq, void *priv)
+{
+       struct mfc_dev *dev = priv;
+       struct mfc_ctx *ctx;
+       unsigned int reason;
+       unsigned int err;
+       int ret = -1;
+
+       mfc_debug_enter();
+
+       if (!dev) {
+               mfc_err_dev("no mfc device to run\n");
+               goto irq_end;
+       }
+
+       if (mfc_pm_get_pwr_ref_cnt(dev) == 0) {
+               mfc_err_dev("no mfc power on\n");
+               call_dop(dev, dump_and_stop_debug_mode, dev);
+               goto irq_end;
+       }
+
+       /* Get the reason of interrupt and the error code */
+       reason = mfc_get_int_reason();
+       err = mfc_get_int_err();
+       mfc_debug(1, "Int reason: %d (err: %d)\n", reason, err);
+       MFC_TRACE_DEV("<< INT: %d\n", reason);
+
+       dev->preempt_ctx = MFC_NO_INSTANCE_SET;
+
+       if (dbg_enable && (reason != MFC_REG_R2H_CMD_QUEUE_DONE_RET))
+               mfc_dbg_disable(dev);
+
+       if ((sfr_dump & MFC_DUMP_ERR_INT) && (reason == MFC_REG_R2H_CMD_ERR_RET))
+               call_dop(dev, dump_regs, dev);
+
+       if ((sfr_dump & MFC_DUMP_WARN_INT) &&
+                       (err && (reason != MFC_REG_R2H_CMD_ERR_RET)))
+               call_dop(dev, dump_regs, dev);
+
+       if (is_err_condition(err))
+               call_dop(dev, dump_and_stop_debug_mode, dev);
+
+       if (dev->nal_q_handle) {
+               ret = __mfc_nal_q_irq(dev, reason, err);
+               if (ret == 0) {
+                       mfc_debug(2, "[NALQ] command was handled\n");
+                       goto irq_end;
+               } else if (ret == 1){
+                       /* Path through */
+                       mfc_debug(2, "NAL_START command will be handled\n");
+               } else {
+                       mfc_debug(2, "[NALQ] command handling Error\n");
+                       goto irq_end;
+               }
+       }
+
+       ret = __mfc_irq_dev(dev, reason, err);
+       if (!ret)
+               goto irq_end;
+
+       ctx = dev->ctx[dev->curr_ctx];
+       if (!ctx) {
+               mfc_err_dev("no mfc context to run\n");
+               mfc_clear_int_sfr();
+               mfc_pm_clock_off(dev);
+               goto irq_end;
+       }
+
+       ret = __mfc_irq_ctx(ctx, reason, err);
+       if (!ret)
+               goto irq_end;
+
+       /* clean-up interrupt */
+       mfc_clear_int_sfr();
+
+       if ((ctx->state != MFCINST_RES_CHANGE_INIT) && (mfc_ctx_ready(ctx) == 0))
+               mfc_clear_bit(ctx->num, &dev->work_bits);
+
+       if (ctx->otf_handle) {
+               if (mfc_otf_ctx_ready(ctx))
+                       mfc_set_bit(ctx->num, &dev->work_bits);
+               else
+                       mfc_clear_bit(ctx->num, &dev->work_bits);
+       }
+
+       mfc_hwlock_handler_irq(dev, ctx, reason, err);
+
+irq_end:
+       mfc_debug_leave();
+       return IRQ_HANDLED;
+}
diff --git a/drivers/media/platform/exynos/mfc/mfc_isr.h b/drivers/media/platform/exynos/mfc/mfc_isr.h
new file mode 100644 (file)
index 0000000..e9767e7
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * drivers/media/platform/exynos/mfc/mfc_isr.h
+ *
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __MFC_ISR_H
+#define __MFC_ISR_H __FILE__
+
+#include <linux/interrupt.h>
+
+#include "mfc_common.h"
+
+#include "mfc_utils.h"
+
+irqreturn_t mfc_top_half_irq(int irq, void *priv);
+irqreturn_t mfc_irq(int irq, void *priv);
+
+static inline void mfc_handle_force_change_status(struct mfc_ctx *ctx)
+{
+       if (ctx->state != MFCINST_ABORT && ctx->state != MFCINST_HEAD_PARSED &&
+                       ctx->state != MFCINST_RES_CHANGE_FLUSH)
+               mfc_change_state(ctx, MFCINST_RUNNING);
+}
+
+#endif /* __MFC_ISR_H */
index 3587d8bc27c71448773308a99c28cb522cb98de4..624478d11a45acbed35602ee54878c62d51abf8f 100644 (file)
@@ -12,7 +12,7 @@
 
 #include "mfc_mmcache.h"
 
-#include "mfc_reg.h"
+#include "mfc_reg_api.h"
 
 static const unsigned char mmcache_SFR_0x0010[] = {
        0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
index 870620e1079243371dce7ccafd743a9c19b36f51..ac533e3fdc2f3377a1c5e64fa8b86bdef0b99370 100644 (file)
@@ -15,8 +15,8 @@
 #include "mfc_sync.h"
 
 #include "mfc_pm.h"
-#include "mfc_cal.h"
-#include "mfc_reg.h"
+#include "mfc_reg_api.h"
+#include "mfc_hw_reg_api.h"
 
 #include "mfc_qos.h"
 #include "mfc_queue.h"
index 776e67363375601900a26beb3c95979da6c4161d..34bd0be0ff4e815bc177282831690851276940de 100644 (file)
@@ -13,7 +13,7 @@
 #include "mfc_opr.h"
 
 #include "mfc_inst.h"
-#include "mfc_reg.h"
+#include "mfc_reg_api.h"
 
 #include "mfc_queue.h"
 #include "mfc_utils.h"
index aa95f5133a84f2ad4bd92711665f9b9b02265239..59b04c43adce6485c651808ff2b2891533734607 100644 (file)
@@ -26,7 +26,7 @@
 #include "mfc_inst.h"
 #include "mfc_pm.h"
 #include "mfc_cmd.h"
-#include "mfc_reg.h"
+#include "mfc_reg_api.h"
 
 #include "mfc_qos.h"
 #include "mfc_queue.h"
index 9b74b773ce3e13de5ce1acb84d2f98f3cec51472..dc3a41b99c0eafce562b176c373dab2d785f2ddc 100644 (file)
@@ -15,7 +15,7 @@
 
 #include <linux/clk.h>
 
-#include "mfc_reg.h"
+#include "mfc_reg_api.h"
 
 void mfc_perf_register(struct mfc_dev *dev);
 void __mfc_measure_init(void);
index 0f7bfd26b3124a9957d5f4fa902d028f925ad9e5..efa109dc7583905233ab987bcda3601ee44051d9 100644 (file)
@@ -16,8 +16,8 @@
 
 #include "mfc_pm.h"
 
-#include "mfc_cal.h"
-#include "mfc_reg.h"
+#include "mfc_reg_api.h"
+#include "mfc_hw_reg_api.h"
 
 void mfc_pm_init(struct mfc_dev *dev)
 {
diff --git a/drivers/media/platform/exynos/mfc/mfc_reg.c b/drivers/media/platform/exynos/mfc/mfc_reg.c
deleted file mode 100644 (file)
index 772af91..0000000
+++ /dev/null
@@ -1,547 +0,0 @@
-/*
- * drivers/media/platform/exynos/mfc/mfc_reg.c
- *
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/delay.h>
-
-#include "mfc_reg.h"
-
-void mfc_dbg_enable(struct mfc_dev *dev)
-{
-       mfc_debug(2, "MFC debug info enable\n");
-       MFC_WRITEL(0x1, MFC_REG_DBG_INFO_ENABLE);
-}
-
-void mfc_dbg_disable(struct mfc_dev *dev)
-{
-       mfc_debug(2, "MFC debug info disable\n");
-       MFC_WRITEL(0x0, MFC_REG_DBG_INFO_ENABLE);
-}
-
-void mfc_dbg_set_addr(struct mfc_dev *dev)
-{
-       struct mfc_ctx_buf_size *buf_size = dev->variant->buf_size->ctx_buf;
-
-       memset((void *)dev->dbg_info_buf.vaddr, 0, buf_size->dbg_info_buf);
-
-       MFC_WRITEL(dev->dbg_info_buf.daddr, MFC_REG_DBG_BUFFER_ADDR);
-       MFC_WRITEL(buf_size->dbg_info_buf, MFC_REG_DBG_BUFFER_SIZE);
-}
-
-void mfc_otf_set_frame_addr(struct mfc_ctx *ctx, int num_planes)
-{
-       struct mfc_dev *dev = ctx->dev;
-       struct _otf_handle *handle = ctx->otf_handle;
-       struct _otf_buf_addr *buf_addr = &handle->otf_buf_addr;
-       int index = handle->otf_buf_index;
-       int i;
-
-       for (i = 0; i < num_planes; i++) {
-               mfc_debug(2, "[OTF][FRAME] set frame buffer[%d], 0x%08llx)\n",
-                               i, buf_addr->otf_daddr[index][i]);
-               MFC_WRITEL(buf_addr->otf_daddr[index][i],
-                               MFC_REG_E_SOURCE_FIRST_ADDR + (i * 4));
-       }
-}
-
-void mfc_otf_set_stream_size(struct mfc_ctx *ctx, unsigned int size)
-{
-       struct mfc_dev *dev = ctx->dev;
-       struct _otf_handle *handle = ctx->otf_handle;
-       struct _otf_debug *debug = &handle->otf_debug;
-       struct mfc_special_buf *buf;
-
-       mfc_debug(2, "[OTF] set stream buffer full size, %u\n", size);
-       MFC_WRITEL(size, MFC_REG_E_STREAM_BUFFER_SIZE);
-
-       if (otf_dump && !ctx->is_drm) {
-               buf = &debug->stream_buf[debug->frame_cnt];
-               mfc_debug(2, "[OTF] set stream addr for debugging\n");
-               mfc_debug(2, "[OTF][STREAM] buf[%d] daddr: 0x%08llx\n",
-                               debug->frame_cnt, buf->daddr);
-               MFC_WRITEL(buf->daddr, MFC_REG_E_STREAM_BUFFER_ADDR);
-       }
-}
-
-void mfc_otf_set_hwfc_index(struct mfc_ctx *ctx, int job_id)
-{
-       struct mfc_dev *dev = ctx->dev;
-
-       mfc_debug(2, "[OTF] set hwfc index, %d\n", job_id);
-       HWFC_WRITEL(job_id, HWFC_ENCODING_IDX);
-}
-
-/* Set decoding frame buffer */
-int mfc_set_dec_codec_buffers(struct mfc_ctx *ctx)
-{
-       struct mfc_dev *dev;
-       struct mfc_dec *dec;
-       unsigned int i;
-       size_t frame_size_mv;
-       dma_addr_t buf_addr;
-       int buf_size;
-       int align_gap;
-       struct mfc_raw_info *raw;
-       unsigned int reg = 0;
-
-       if (!ctx) {
-               mfc_err_dev("no mfc context to run\n");
-               return -EINVAL;
-       }
-
-       dev = ctx->dev;
-       if (!dev) {
-               mfc_err_dev("no mfc device to run\n");
-               return -EINVAL;
-       }
-
-       dec = ctx->dec_priv;
-       if (!dec) {
-               mfc_err_dev("no mfc decoder to run\n");
-               return -EINVAL;
-       }
-
-       raw = &ctx->raw_buf;
-       buf_addr = ctx->codec_buf.daddr;
-       buf_size = ctx->codec_buf.size;
-
-       mfc_debug(2, "[MEMINFO] codec buf 0x%llx size: %d\n", buf_addr, buf_size);
-       mfc_debug(2, "Total DPB COUNT: %d, display delay: %d\n",
-                       dec->total_dpb_count, dec->display_delay);
-
-       /* set decoder DPB size, stride */
-       MFC_WRITEL(dec->total_dpb_count, MFC_REG_D_NUM_DPB);
-       for (i = 0; i < raw->num_planes; i++) {
-               mfc_debug(2, "[FRAME] buf[%d] size: %d, stride: %d\n",
-                               i, raw->plane_size[i], raw->stride[i]);
-               MFC_WRITEL(raw->plane_size[i], MFC_REG_D_FIRST_PLANE_DPB_SIZE + (i * 4));
-               MFC_WRITEL(ctx->raw_buf.stride[i],
-                               MFC_REG_D_FIRST_PLANE_DPB_STRIDE_SIZE + (i * 4));
-               if (ctx->is_10bit) {
-                       MFC_WRITEL(raw->stride_2bits[i], MFC_REG_D_FIRST_PLANE_2BIT_DPB_STRIDE_SIZE + (i * 4));
-                       MFC_WRITEL(raw->plane_size_2bits[i], MFC_REG_D_FIRST_PLANE_2BIT_DPB_SIZE + (i * 4));
-                       mfc_debug(2, "[FRAME][10BIT] 2bits buf[%d] size: %d, stride: %d\n",
-                                       i, raw->plane_size_2bits[i], raw->stride_2bits[i]);
-               }
-       }
-
-       /* set codec buffers */
-       MFC_WRITEL(buf_addr, MFC_REG_D_SCRATCH_BUFFER_ADDR);
-       MFC_WRITEL(ctx->scratch_buf_size, MFC_REG_D_SCRATCH_BUFFER_SIZE);
-       buf_addr += ctx->scratch_buf_size;
-       buf_size -= ctx->scratch_buf_size;
-
-       if (IS_H264_DEC(ctx) || IS_H264_MVC_DEC(ctx) || IS_HEVC_DEC(ctx) || IS_BPG_DEC(ctx))
-               MFC_WRITEL(ctx->mv_size, MFC_REG_D_MV_BUFFER_SIZE);
-
-       if (IS_VP9_DEC(ctx)){
-               MFC_WRITEL(buf_addr, MFC_REG_D_STATIC_BUFFER_ADDR);
-               MFC_WRITEL(DEC_STATIC_BUFFER_SIZE, MFC_REG_D_STATIC_BUFFER_SIZE);
-               buf_addr += DEC_STATIC_BUFFER_SIZE;
-               buf_size -= DEC_STATIC_BUFFER_SIZE;
-       }
-
-       if (IS_MPEG4_DEC(ctx) && dec->loop_filter_mpeg4) {
-               mfc_debug(2, "Add DPB for loop filter of MPEG4\n");
-               for (i = 0; i < NUM_MPEG4_LF_BUF; i++) {
-                       MFC_WRITEL(buf_addr, MFC_REG_D_POST_FILTER_LUMA_DPB0 + (4 * i));
-                       buf_addr += ctx->loopfilter_luma_size;
-                       buf_size -= ctx->loopfilter_luma_size;
-
-                       MFC_WRITEL(buf_addr, MFC_REG_D_POST_FILTER_CHROMA_DPB0 + (4 * i));
-                       buf_addr += ctx->loopfilter_chroma_size;
-                       buf_size -= ctx->loopfilter_chroma_size;
-               }
-               reg |= ((dec->loop_filter_mpeg4 & MFC_REG_D_INIT_BUF_OPT_LF_CTRL_MASK)
-                               << MFC_REG_D_INIT_BUF_OPT_LF_CTRL_SHIFT);
-       }
-
-       reg |= (0x1 << MFC_REG_D_INIT_BUF_OPT_DYNAMIC_DPB_SET_SHIFT);
-
-       if (CODEC_NOT_CODED(ctx)) {
-               reg |= (0x1 << MFC_REG_D_INIT_BUF_OPT_COPY_NOT_CODED_SHIFT);
-               mfc_debug(2, "Notcoded frame copy mode start\n");
-       }
-       /* Enable 10bit Dithering */
-       if (ctx->is_10bit) {
-               reg |= (0x1 << MFC_REG_D_INIT_BUF_OPT_DITHERING_EN_SHIFT);
-               /* 64byte align, It is vaid only for VP9 */
-               reg |= (0x1 << MFC_REG_D_INIT_BUF_OPT_STRIDE_SIZE_ALIGN);
-       } else {
-               /* 16byte align, It is vaid only for VP9 */
-               reg &= ~(0x1 << MFC_REG_D_INIT_BUF_OPT_STRIDE_SIZE_ALIGN);
-       }
-
-       MFC_WRITEL(reg, MFC_REG_D_INIT_BUFFER_OPTIONS);
-
-       frame_size_mv = ctx->mv_size;
-       MFC_WRITEL(dec->mv_count, MFC_REG_D_NUM_MV);
-       if (IS_H264_DEC(ctx) || IS_H264_MVC_DEC(ctx) || IS_HEVC_DEC(ctx) || IS_BPG_DEC(ctx)) {
-               for (i = 0; i < dec->mv_count; i++) {
-                       /* To test alignment */
-                       align_gap = buf_addr;
-                       buf_addr = ALIGN(buf_addr, 16);
-                       align_gap = buf_addr - align_gap;
-                       buf_size -= align_gap;
-
-                       MFC_WRITEL(buf_addr, MFC_REG_D_MV_BUFFER0 + i * 4);
-                       buf_addr += frame_size_mv;
-                       buf_size -= frame_size_mv;
-               }
-       }
-
-       mfc_debug(2, "[MEMINFO] codec buf 0x%llx, remained size: %d\n", buf_addr, buf_size);
-       if (buf_size < 0) {
-               mfc_debug(2, "[MEMINFO] Not enough memory has been allocated\n");
-               return -ENOMEM;
-       }
-
-       return 0;
-}
-
-/* Set encoding ref & codec buffer */
-int mfc_set_enc_codec_buffers(struct mfc_ctx *ctx)
-{
-       struct mfc_dev *dev = ctx->dev;
-       struct mfc_enc *enc = ctx->enc_priv;
-       dma_addr_t buf_addr;
-       int buf_size;
-       int i;
-
-       mfc_debug_enter();
-
-       buf_addr = ctx->codec_buf.daddr;
-       buf_size = ctx->codec_buf.size;
-
-       mfc_debug(2, "[MEMINFO] codec buf 0x%llx, size: %d\n", buf_addr, buf_size);
-       mfc_debug(2, "DPB COUNT: %d\n", ctx->dpb_count);
-
-       MFC_WRITEL(buf_addr, MFC_REG_E_SCRATCH_BUFFER_ADDR);
-       MFC_WRITEL(ctx->scratch_buf_size, MFC_REG_E_SCRATCH_BUFFER_SIZE);
-       buf_addr += ctx->scratch_buf_size;
-       buf_size -= ctx->scratch_buf_size;
-
-       /* start address of per buffer is aligned */
-       for (i = 0; i < ctx->dpb_count; i++) {
-               MFC_WRITEL(buf_addr, MFC_REG_E_LUMA_DPB + (4 * i));
-               buf_addr += enc->luma_dpb_size;
-               buf_size -= enc->luma_dpb_size;
-       }
-       for (i = 0; i < ctx->dpb_count; i++) {
-               MFC_WRITEL(buf_addr, MFC_REG_E_CHROMA_DPB + (4 * i));
-               buf_addr += enc->chroma_dpb_size;
-               buf_size -= enc->chroma_dpb_size;
-       }
-       for (i = 0; i < ctx->dpb_count; i++) {
-               MFC_WRITEL(buf_addr, MFC_REG_E_ME_BUFFER + (4 * i));
-               buf_addr += enc->me_buffer_size;
-               buf_size -= enc->me_buffer_size;
-       }
-
-       MFC_WRITEL(buf_addr, MFC_REG_E_TMV_BUFFER0);
-       buf_addr += enc->tmv_buffer_size >> 1;
-       MFC_WRITEL(buf_addr, MFC_REG_E_TMV_BUFFER1);
-       buf_addr += enc->tmv_buffer_size >> 1;
-       buf_size -= enc->tmv_buffer_size;
-
-       mfc_debug(2, "[MEMINFO] codec buf 0x%llx, remained size: %d\n", buf_addr, buf_size);
-       if (buf_size < 0) {
-               mfc_debug(2, "[MEMINFO] Not enough memory has been allocated\n");
-               return -ENOMEM;
-       }
-
-       mfc_debug_leave();
-
-       return 0;
-}
-
-/* Set registers for decoding stream buffer */
-int mfc_set_dec_stream_buffer(struct mfc_ctx *ctx, struct mfc_buf *mfc_buf,
-                 unsigned int start_num_byte, unsigned int strm_size)
-{
-       struct mfc_dev *dev;
-       struct mfc_dec *dec;
-       unsigned int cpb_buf_size;
-       dma_addr_t addr;
-       int index = -1;
-
-       mfc_debug_enter();
-       if (!ctx) {
-               mfc_err_dev("no mfc context to run\n");
-               return -EINVAL;
-       }
-       dev = ctx->dev;
-       if (!dev) {
-               mfc_err_dev("no mfc device to run\n");
-               return -EINVAL;
-       }
-       dec = ctx->dec_priv;
-       if (!dec) {
-               mfc_err_dev("no mfc decoder to run\n");
-               return -EINVAL;
-       }
-
-       cpb_buf_size = ALIGN(dec->src_buf_size, STREAM_BUF_ALIGN);
-
-       if (mfc_buf) {
-               index = mfc_buf->vb.vb2_buf.index;
-               addr = mfc_buf->addr[0][0];
-               if (strm_size > set_strm_size_max(cpb_buf_size)) {
-                       mfc_info_ctx("Decrease strm_size because of %d align: %u -> %u\n",
-                               STREAM_BUF_ALIGN, strm_size, set_strm_size_max(cpb_buf_size));
-                       strm_size = set_strm_size_max(cpb_buf_size);
-                       mfc_buf->vb.vb2_buf.planes[0].bytesused = strm_size;
-               }
-       } else {
-               addr = 0;
-       }
-
-       mfc_debug(2, "[BUFINFO] ctx[%d] set src index: %d, addr: 0x%08llx\n",
-                       ctx->num, index, addr);
-       mfc_debug(2, "[STREAM] strm_size: %#lx(%d), buf_size: %u, offset: %u\n",
-                       strm_size, strm_size, cpb_buf_size, start_num_byte);
-
-       if (strm_size == 0)
-               mfc_info_ctx("stream size is 0\n");
-
-       MFC_WRITEL(strm_size, MFC_REG_D_STREAM_DATA_SIZE);
-       MFC_WRITEL(addr, MFC_REG_D_CPB_BUFFER_ADDR);
-       MFC_WRITEL(cpb_buf_size, MFC_REG_D_CPB_BUFFER_SIZE);
-       MFC_WRITEL(start_num_byte, MFC_REG_D_CPB_BUFFER_OFFSET);
-
-       if (mfc_buf)
-               MFC_TRACE_CTX("Set src[%d] fd: %d, %#llx\n",
-                               index, mfc_buf->vb.vb2_buf.planes[0].m.fd, addr);
-
-       mfc_debug_leave();
-       return 0;
-}
-
-void mfc_set_enc_frame_buffer(struct mfc_ctx *ctx,
-               struct mfc_buf *mfc_buf, int num_planes)
-{
-       struct mfc_dev *dev = ctx->dev;
-       dma_addr_t addr[3] = { 0, 0, 0 };
-       dma_addr_t addr_2bit[2] = { 0, 0 };
-       int index, i;
-
-       if (!mfc_buf) {
-               mfc_debug(3, "enc zero buffer set\n");
-               goto buffer_set;
-       }
-
-       index = mfc_buf->vb.vb2_buf.index;
-       if (mfc_buf->num_valid_bufs > 0) {
-               for (i = 0; i < num_planes; i++) {
-                       addr[i] = mfc_buf->addr[mfc_buf->next_index][i];
-                       mfc_debug(2, "[BUFCON][BUFINFO] ctx[%d] set src index:%d, batch[%d], addr[%d]: 0x%08llx\n",
-                                       ctx->num, index, mfc_buf->next_index, i, addr[i]);
-               }
-               mfc_buf->next_index++;
-       } else {
-               for (i = 0; i < num_planes; i++) {
-                       addr[i] = mfc_buf->addr[0][i];
-                       mfc_debug(2, "[BUFINFO] ctx[%d] set src index:%d, addr[%d]: 0x%08llx\n",
-                                       ctx->num, index, i, addr[i]);
-               }
-       }
-
-buffer_set:
-       for (i = 0; i < num_planes; i++)
-               MFC_WRITEL(addr[i], MFC_REG_E_SOURCE_FIRST_ADDR + (i * 4));
-
-       if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12M_S10B ||
-               ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV21M_S10B) {
-               addr_2bit[0] = addr[0] + NV12N_10B_Y_8B_SIZE(ctx->img_width, ctx->img_height);
-               addr_2bit[1] = addr[1] + NV12N_10B_CBCR_8B_SIZE(ctx->img_width, ctx->img_height);
-
-               for (i = 0; i < num_planes; i++) {
-                       MFC_WRITEL(addr_2bit[i], MFC_REG_E_SOURCE_FIRST_2BIT_ADDR + (i * 4));
-                       mfc_debug(2, "[BUFINFO][10BIT] ctx[%d] set src 2bit addr[%d]: 0x%08llx\n",
-                                       ctx->num, i, addr_2bit[i]);
-               }
-       } else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV16M_S10B ||
-               ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV61M_S10B) {
-               addr_2bit[0] = addr[0] + NV16M_Y_SIZE(ctx->img_width, ctx->img_height);
-               addr_2bit[1] = addr[1] + NV16M_CBCR_SIZE(ctx->img_width, ctx->img_height);
-
-               for (i = 0; i < num_planes; i++) {
-                       MFC_WRITEL(addr_2bit[i], MFC_REG_E_SOURCE_FIRST_2BIT_ADDR + (i * 4));
-                       mfc_debug(2, "[BUFINFO][10BIT] ctx[%d] set src 2bit addr[%d]: 0x%08llx\n",
-                                       ctx->num, i, addr_2bit[i]);
-               }
-       }
-}
-
-/* Set registers for encoding stream buffer */
-int mfc_set_enc_stream_buffer(struct mfc_ctx *ctx,
-               struct mfc_buf *mfc_buf)
-{
-       struct mfc_dev *dev = ctx->dev;
-       dma_addr_t addr;
-       unsigned int size, offset, index;
-
-       index = mfc_buf->vb.vb2_buf.index;
-       addr = mfc_buf->addr[0][0];
-       offset = mfc_buf->vb.vb2_buf.planes[0].data_offset;
-       size = (unsigned int)vb2_plane_size(&mfc_buf->vb.vb2_buf, 0);
-       size = ALIGN(size, 512);
-
-       MFC_WRITEL(addr, MFC_REG_E_STREAM_BUFFER_ADDR); /* 16B align */
-       MFC_WRITEL(size, MFC_REG_E_STREAM_BUFFER_SIZE);
-       MFC_WRITEL(offset, MFC_REG_E_STREAM_BUFFER_OFFSET);
-
-       mfc_debug(2, "[BUFINFO] ctx[%d] set dst index: %d, addr: 0x%08llx\n",
-                       ctx->num, index, addr);
-       mfc_debug(2, "[STREAM] buf_size: %u, offset: %d\n", size, offset);
-
-       return 0;
-}
-
-void mfc_get_enc_frame_buffer(struct mfc_ctx *ctx,
-               dma_addr_t addr[], int num_planes)
-{
-       struct mfc_dev *dev = ctx->dev;
-       unsigned long enc_recon_y_addr, enc_recon_c_addr;
-       int i, addr_offset;
-
-       addr_offset = MFC_REG_E_ENCODED_SOURCE_FIRST_ADDR;
-
-       for (i = 0; i < num_planes; i++)
-               addr[i] = MFC_READL(addr_offset + (i * 4));
-
-       enc_recon_y_addr = MFC_READL(MFC_REG_E_RECON_LUMA_DPB_ADDR);
-       enc_recon_c_addr = MFC_READL(MFC_REG_E_RECON_CHROMA_DPB_ADDR);
-
-       mfc_debug(2, "[MEMINFO] recon y: 0x%08lx c: 0x%08lx\n",
-                       enc_recon_y_addr, enc_recon_c_addr);
-}
-
-void mfc_set_enc_stride(struct mfc_ctx *ctx)
-{
-       struct mfc_dev *dev = ctx->dev;
-       int i;
-
-       for (i = 0; i < ctx->raw_buf.num_planes; i++) {
-               MFC_WRITEL(ctx->raw_buf.stride[i],
-                               MFC_REG_E_SOURCE_FIRST_STRIDE + (i * 4));
-               mfc_debug(2, "[FRAME] enc src plane[%d] stride: %d\n",
-                               i, ctx->raw_buf.stride[i]);
-       }
-}
-
-int mfc_set_dynamic_dpb(struct mfc_ctx *ctx, struct mfc_buf *dst_mb)
-{
-       struct mfc_dev *dev = ctx->dev;
-       struct mfc_dec *dec = ctx->dec_priv;
-       struct mfc_raw_info *raw = &ctx->raw_buf;
-       int dst_index;
-       int i;
-
-       dst_index = dst_mb->vb.vb2_buf.index;
-       set_bit(dst_index, &dec->available_dpb);
-       dec->dynamic_set = 1 << dst_index;
-       mfc_debug(2, "[DPB] ADDING Flag after: 0x%lx\n", dec->available_dpb);
-
-       /* for debugging about black bar detection */
-       if (MFC_FEATURE_SUPPORT(dev, dev->pdata->black_bar) && dec->detect_black_bar) {
-               for (i = 0; i < raw->num_planes; i++) {
-                       dec->frame_vaddr[i][dec->frame_cnt] = vb2_plane_vaddr(&dst_mb->vb.vb2_buf, i);
-                       dec->frame_daddr[i][dec->frame_cnt] = dst_mb->addr[0][i];
-                       dec->frame_size[i][dec->frame_cnt] = raw->plane_size[i];
-                       dec->index[i][dec->frame_cnt] = dst_index;
-                       dec->fd[i][dec->frame_cnt] = dst_mb->vb.vb2_buf.planes[0].m.fd;
-               }
-               dec->frame_cnt++;
-               if (dec->frame_cnt >= 30)
-                       dec->frame_cnt = 0;
-       }
-
-       /* decoder dst buffer CFW PROT */
-       mfc_protect_dpb(ctx, dst_mb);
-
-       for (i = 0; i < raw->num_planes; i++) {
-               MFC_WRITEL(raw->plane_size[i],
-                               MFC_REG_D_FIRST_PLANE_DPB_SIZE + i * 4);
-               MFC_WRITEL(dst_mb->addr[0][i],
-                               MFC_REG_D_FIRST_PLANE_DPB0 + (i * 0x100 + dst_index * 4));
-               if (ctx->is_10bit)
-                       MFC_WRITEL(raw->plane_size_2bits[i],
-                                       MFC_REG_D_FIRST_PLANE_2BIT_DPB_SIZE + (i * 4));
-               mfc_debug(2, "[BUFINFO][DPB] ctx[%d] set dst index: %d, addr[%d]: 0x%08llx\n",
-                               ctx->num, dst_index, i, dst_mb->addr[0][i]);
-       }
-
-       MFC_TRACE_CTX("Set dst[%d] fd: %d, %#llx / avail %#lx used %#x\n",
-                       dst_index, dst_mb->vb.vb2_buf.planes[0].m.fd, dst_mb->addr[0][0],
-                       dec->available_dpb, dec->dynamic_used);
-
-       return 0;
-}
-
-void mfc_set_pixel_format(struct mfc_dev *dev, unsigned int format)
-{
-       unsigned int reg = 0;
-       unsigned int pix_val, mem_type_10bit = 0;
-
-       if (dev->pdata->P010_decoding)
-               mem_type_10bit = 1;
-
-       switch (format) {
-       case V4L2_PIX_FMT_NV12M:
-       case V4L2_PIX_FMT_NV12N:
-       case V4L2_PIX_FMT_NV12MT_16X16:
-       case V4L2_PIX_FMT_NV16M:
-               pix_val = 0;
-               break;
-       case V4L2_PIX_FMT_NV21M:
-       case V4L2_PIX_FMT_NV61M:
-               pix_val = 1;
-               break;
-       case V4L2_PIX_FMT_YVU420M:
-               pix_val = 2;
-               break;
-       case V4L2_PIX_FMT_YUV420M:
-       case V4L2_PIX_FMT_YUV420N:
-               pix_val = 3;
-               break;
-       /* For 10bit direct set */
-       case V4L2_PIX_FMT_NV12N_10B:
-       case V4L2_PIX_FMT_NV12M_S10B:
-       case V4L2_PIX_FMT_NV16M_S10B:
-               mem_type_10bit = 0;
-               pix_val = 0;
-               break;
-       case V4L2_PIX_FMT_NV12M_P010:
-       case V4L2_PIX_FMT_NV16M_P210:
-               mem_type_10bit = 1;
-               pix_val = 0;
-               break;
-       case V4L2_PIX_FMT_NV21M_S10B:
-       case V4L2_PIX_FMT_NV61M_S10B:
-               mem_type_10bit = 0;
-               pix_val = 1;
-               break;
-       case V4L2_PIX_FMT_NV21M_P010:
-       case V4L2_PIX_FMT_NV61M_P210:
-               mem_type_10bit = 1;
-               pix_val = 1;
-               break;
-       default:
-               pix_val = 0;
-               break;
-       }
-       reg |= pix_val;
-       reg |= (mem_type_10bit << 4);
-       MFC_WRITEL(reg, MFC_REG_PIXEL_FORMAT);
-       mfc_debug(2, "[FRAME] pixel format: %d, mem_type_10bit for 10bit: %d (reg: %#x)\n",
-                       pix_val, mem_type_10bit, reg);
-}
diff --git a/drivers/media/platform/exynos/mfc/mfc_reg.h b/drivers/media/platform/exynos/mfc/mfc_reg.h
deleted file mode 100644 (file)
index 757b3d1..0000000
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * drivers/media/platform/exynos/mfc/mfc_reg.h
- *
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef __MFC_REG_H
-#define __MFC_REG_H __FILE__
-
-#include "mfc_common.h"
-
-#include "mfc_utils.h"
-
-#define MFC_READL(offset)              readl(dev->regs_base + (offset))
-#define MFC_WRITEL(data, offset)       writel((data), dev->regs_base + (offset))
-
-#define MFC_MMU0_READL(offset)         readl(dev->sysmmu0_base + (offset))
-#define MFC_MMU1_READL(offset)         readl(dev->sysmmu1_base + (offset))
-
-#define HWFC_WRITEL(data, offset)      writel((data), dev->hwfc_base + (offset))
-
-#define MMCACHE_READL(offset)          readl(dev->mmcache.base + (offset))
-#define MMCACHE_WRITEL(data, offset)   writel((data), dev->mmcache.base + (offset))
-
-/* version */
-#define mfc_get_fimv_info()            ((MFC_READL(MFC_REG_FW_VERSION)         \
-                                               >> MFC_REG_FW_VER_INFO_SHFT)            \
-                                               & MFC_REG_FW_VER_INFO_MASK)
-#define mfc_get_fw_ver_year()  ((MFC_READL(MFC_REG_FW_VERSION)         \
-                                               >> MFC_REG_FW_VER_YEAR_SHFT)            \
-                                               & MFC_REG_FW_VER_YEAR_MASK)
-#define mfc_get_fw_ver_month() ((MFC_READL(MFC_REG_FW_VERSION)         \
-                                               >> MFC_REG_FW_VER_MONTH_SHFT)           \
-                                               & MFC_REG_FW_VER_MONTH_MASK)
-#define mfc_get_fw_ver_date()  ((MFC_READL(MFC_REG_FW_VERSION)         \
-                                               >> MFC_REG_FW_VER_DATE_SHFT)            \
-                                               & MFC_REG_FW_VER_DATE_MASK)
-#define mfc_get_fw_ver_all()   ((MFC_READL(MFC_REG_FW_VERSION)         \
-                                               >> MFC_REG_FW_VER_ALL_SHFT)             \
-                                               & MFC_REG_FW_VER_ALL_MASK)
-#define mfc_get_mfc_version()  ((MFC_READL(MFC_REG_MFC_VERSION)                \
-                                               >> MFC_REG_MFC_VER_SHFT)                \
-                                               & MFC_REG_MFC_VER_MASK)
-
-
-/* decoding & display information */
-#define mfc_get_dec_status()   (MFC_READL(MFC_REG_D_DECODED_STATUS)            \
-                                               & MFC_REG_DEC_STATUS_DECODED_STATUS_MASK)
-#define mfc_get_disp_status()  (MFC_READL(MFC_REG_D_DISPLAY_STATUS)            \
-                                               & MFC_REG_DISP_STATUS_DISPLAY_STATUS_MASK)
-#define mfc_get_res_change()   ((MFC_READL(MFC_REG_D_DISPLAY_STATUS)           \
-                                               >> MFC_REG_DISP_STATUS_RES_CHANGE_SHIFT)        \
-                                               & MFC_REG_DISP_STATUS_RES_CHANGE_MASK)
-#define mfc_get_black_bar_detection()  ((MFC_READL(MFC_REG_D_DISPLAY_STATUS)           \
-                                               >> MFC_REG_DISP_STATUS_BLACK_BAR_DETECT_SHIFT)  \
-                                               & MFC_REG_DISP_STATUS_BLACK_BAR_DETECT_MASK)
-#define mfc_get_dpb_change()   ((MFC_READL(MFC_REG_D_DISPLAY_STATUS)           \
-                                               >> MFC_REG_DISP_STATUS_NEED_DPB_CHANGE_SHIFT)   \
-                                               & MFC_REG_DISP_STATUS_NEED_DPB_CHANGE_MASK)
-#define mfc_get_scratch_change()       ((MFC_READL(MFC_REG_D_DISPLAY_STATUS)           \
-                                               >> MFC_REG_DISP_STATUS_NEED_SCRATCH_CHANGE_SHIFT)       \
-                                               & MFC_REG_DISP_STATUS_NEED_SCRATCH_CHANGE_MASK)
-#define mfc_get_disp_frame_type()      (MFC_READL(MFC_REG_D_DISPLAY_FRAME_TYPE)        \
-                                               & MFC_REG_DISPLAY_FRAME_MASK)
-#define mfc_get_dec_frame_type()       (MFC_READL(MFC_REG_D_DECODED_FRAME_TYPE)        \
-                                               & MFC_REG_DECODED_FRAME_MASK)
-#define mfc_get_interlace_type()       ((MFC_READL(MFC_REG_D_DISPLAY_FRAME_TYPE)       \
-                                               >> MFC_REG_DISPLAY_TEMP_INFO_SHIFT)     \
-                                               & MFC_REG_DISPLAY_TEMP_INFO_MASK)
-#define mfc_is_interlace_picture()     ((MFC_READL(MFC_REG_D_DISPLAY_STATUS)           \
-                                               >> MFC_REG_DISP_STATUS_INTERLACE_SHIFT)\
-                                               & MFC_REG_DISP_STATUS_INTERLACE_MASK)
-#define mfc_is_mbaff_picture() ((MFC_READL(MFC_REG_D_H264_INFO)                \
-                                               >> MFC_REG_D_H264_INFO_MBAFF_FRAME_FLAG_SHIFT)\
-                                               & MFC_REG_D_H264_INFO_MBAFF_FRAME_FLAG_MASK)
-#define mfc_get_img_width()            MFC_READL(MFC_REG_D_DISPLAY_FRAME_WIDTH)
-#define mfc_get_img_height()   MFC_READL(MFC_REG_D_DISPLAY_FRAME_HEIGHT)
-#define mfc_get_disp_y_addr()  MFC_READL(MFC_REG_D_DISPLAY_LUMA_ADDR)
-#define mfc_get_dec_y_addr()   MFC_READL(MFC_REG_D_DECODED_LUMA_ADDR)
-
-
-/* kind of interrupt */
-#define mfc_get_int_err()              MFC_READL(MFC_REG_ERROR_CODE)
-#define mfc_get_err(x)         (((x) >> MFC_REG_ERR_STATUS_SHIFT)              \
-                                               & MFC_REG_ERR_STATUS_MASK)
-#define mfc_get_warn(x)                (((x) >> MFC_REG_WARN_STATUS_SHIFT)             \
-                                               & MFC_REG_WARN_STATUS_MASK)
-
-
-/* additional information */
-#define mfc_get_consumed_stream()              MFC_READL(MFC_REG_D_DECODED_NAL_SIZE)
-#define mfc_get_dpb_count()                    MFC_READL(MFC_REG_D_MIN_NUM_DPB)
-#define mfc_get_min_dpb_size(x)                MFC_READL(MFC_REG_D_MIN_FIRST_PLANE_DPB_SIZE + (x * 4))
-#define mfc_get_scratch_size()         MFC_READL(MFC_REG_D_MIN_SCRATCH_BUFFER_SIZE)
-#define mfc_get_mv_count()                     MFC_READL(MFC_REG_D_MIN_NUM_MV)
-#define mfc_get_inst_no()                      MFC_READL(MFC_REG_RET_INSTANCE_ID)
-#define mfc_get_enc_dpb_count()                MFC_READL(MFC_REG_E_NUM_DPB)
-#define mfc_get_enc_scratch_size()             MFC_READL(MFC_REG_E_MIN_SCRATCH_BUFFER_SIZE)
-#define mfc_get_enc_strm_size()                MFC_READL(MFC_REG_E_STREAM_SIZE)
-#define mfc_get_enc_slice_type()               MFC_READL(MFC_REG_E_SLICE_TYPE)
-#define mfc_get_enc_pic_count()                MFC_READL(MFC_REG_E_PICTURE_COUNT)
-#define mfc_get_sei_avail()                    MFC_READL(MFC_REG_D_SEI_AVAIL)
-#define mfc_get_sei_content_light()            MFC_READL(MFC_REG_D_CONTENT_LIGHT_LEVEL_INFO_SEI)
-#define mfc_get_sei_mastering0()               MFC_READL(MFC_REG_D_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_0)
-#define mfc_get_sei_mastering1()               MFC_READL(MFC_REG_D_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_1)
-#define mfc_get_sei_mastering2()               MFC_READL(MFC_REG_D_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_2)
-#define mfc_get_sei_mastering3()               MFC_READL(MFC_REG_D_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_3)
-#define mfc_get_sei_mastering4()               MFC_READL(MFC_REG_D_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_4)
-#define mfc_get_sei_mastering5()               MFC_READL(MFC_REG_D_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_5)
-#define mfc_get_sei_avail_frame_pack() (MFC_READL(MFC_REG_D_SEI_AVAIL) \
-                                               & MFC_REG_D_SEI_AVAIL_FRAME_PACK_MASK)
-#define mfc_get_sei_avail_content_light()      ((MFC_READL(MFC_REG_D_SEI_AVAIL)        \
-                                               >> MFC_REG_D_SEI_AVAIL_CONTENT_LIGHT_SHIFT)     \
-                                               & MFC_REG_D_SEI_AVAIL_CONTENT_LIGHT_MASK)
-#define mfc_get_sei_avail_mastering_display()  ((MFC_READL(MFC_REG_D_SEI_AVAIL)        \
-                                               >> MFC_REG_D_SEI_AVAIL_MASTERING_DISPLAY_SHIFT) \
-                                               & MFC_REG_D_SEI_AVAIL_MASTERING_DISPLAY_MASK)
-#define mfc_get_video_signal_type()            ((MFC_READL(MFC_REG_D_VIDEO_SIGNAL_TYPE)        \
-                                               >> MFC_REG_D_VIDEO_SIGNAL_TYPE_FLAG_SHIFT)      \
-                                               & MFC_REG_D_VIDEO_SIGNAL_TYPE_FLAG_MASK)
-#define mfc_get_colour_description()   ((MFC_READL(MFC_REG_D_VIDEO_SIGNAL_TYPE)        \
-                                               >> MFC_REG_D_COLOUR_DESCRIPTION_FLAG_SHIFT)     \
-                                               & MFC_REG_D_COLOUR_DESCRIPTION_FLAG_MASK)
-#define mfc_get_black_bar_pos_x()              ((MFC_READL(MFC_REG_D_BLACK_BAR_START_POS)      \
-                                               >> MFC_REG_D_BLACK_BAR_START_X_SHIFT)           \
-                                               & MFC_REG_D_BLACK_BAR_START_X_MASK)
-#define mfc_get_black_bar_pos_y()              ((MFC_READL(MFC_REG_D_BLACK_BAR_START_POS)      \
-                                               >> MFC_REG_D_BLACK_BAR_START_Y_SHIFT)           \
-                                               & MFC_REG_D_BLACK_BAR_START_Y_MASK)
-#define mfc_get_black_bar_image_w()            ((MFC_READL(MFC_REG_D_BLACK_BAR_IMAGE_SIZE)     \
-                                               >> MFC_REG_D_BLACK_BAR_IMAGE_W_SHIFT)   \
-                                               & MFC_REG_D_BLACK_BAR_IMAGE_W_MASK)
-#define mfc_get_black_bar_image_h()            ((MFC_READL(MFC_REG_D_BLACK_BAR_IMAGE_SIZE)     \
-                                               >> MFC_REG_D_BLACK_BAR_IMAGE_H_SHIFT)   \
-                                               & MFC_REG_D_BLACK_BAR_IMAGE_H_MASK)
-#define mfc_get_mvc_disp_view_id()             (MFC_READL(MFC_REG_D_MVC_VIEW_ID)               \
-                                               & MFC_REG_D_MVC_VIEW_ID_DISP_MASK)
-#define mfc_get_profile()                      (MFC_READL(MFC_REG_D_DECODED_PICTURE_PROFILE)   \
-                                               & MFC_REG_D_DECODED_PIC_PROFILE_MASK)
-#define mfc_get_luma_bit_depth_minus8()        ((MFC_READL(MFC_REG_D_DECODED_PICTURE_PROFILE)  \
-                                               >> MFC_REG_D_BIT_DEPTH_LUMA_MINUS8_SHIFT)       \
-                                               & MFC_REG_D_BIT_DEPTH_LUMA_MINUS8_MASK)
-#define mfc_get_chroma_bit_depth_minus8()      ((MFC_READL(MFC_REG_D_DECODED_PICTURE_PROFILE)  \
-                                               >> MFC_REG_D_BIT_DEPTH_CHROMA_MINUS8_SHIFT)     \
-                                               & MFC_REG_D_BIT_DEPTH_CHROMA_MINUS8_MASK)
-#define mfc_get_dec_used_flag()                MFC_READL(MFC_REG_D_USED_DPB_FLAG_LOWER)
-#define mfc_get_enc_nal_done_info()            ((MFC_READL(MFC_REG_E_NAL_DONE_INFO) & (0x3 << 4)) >> 4)
-#define mfc_get_chroma_format()                (MFC_READL(MFC_REG_D_CHROMA_FORMAT)             \
-                                               & MFC_REG_D_CHROMA_FORMAT_MASK)
-#define mfc_get_color_range()          ((MFC_READL(MFC_REG_D_CHROMA_FORMAT)    \
-                                               >> MFC_REG_D_COLOR_RANGE_SHIFT) \
-                                               & MFC_REG_D_COLOR_RANGE_MASK)
-#define mfc_get_color_space()          ((MFC_READL(MFC_REG_D_CHROMA_FORMAT)    \
-                                               >> MFC_REG_D_COLOR_SPACE_SHIFT) \
-                                               & MFC_REG_D_COLOR_SPACE_MASK)
-#define mfc_get_num_of_tile()          ((MFC_READL(MFC_REG_D_DECODED_STATUS)           \
-                                               >> MFC_REG_DEC_STATUS_NUM_OF_TILE_SHIFT)        \
-                                               & MFC_REG_DEC_STATUS_NUM_OF_TILE_MASK)
-
-
-/* nal queue information */
-#define mfc_get_nal_q_input_count()            MFC_READL(MFC_REG_NAL_QUEUE_INPUT_COUNT)
-#define mfc_get_nal_q_output_count()   MFC_READL(MFC_REG_NAL_QUEUE_OUTPUT_COUNT)
-#define mfc_get_nal_q_input_exe_count()        MFC_READL(MFC_REG_NAL_QUEUE_INPUT_EXE_COUNT)
-#define mfc_get_nal_q_info()           MFC_READL(MFC_REG_NAL_QUEUE_INFO)
-#define mfc_get_nal_q_input_addr()             MFC_READL(MFC_REG_NAL_QUEUE_INPUT_ADDR)
-#define mfc_get_nal_q_input_size()             MFC_READL(MFC_REG_NAL_QUEUE_INPUT_SIZE)
-#define mfc_get_nal_q_output_addr()            MFC_READL(MFC_REG_NAL_QUEUE_OUTPUT_ADDR)
-#define mfc_get_nal_q_output_ize()             MFC_READL(MFC_REG_NAL_QUEUE_OUTPUT_SIZE)
-
-static inline void mfc_reset_nal_queue_registers(struct mfc_dev *dev)
-{
-       MFC_WRITEL(0x0, MFC_REG_NAL_QUEUE_INPUT_COUNT);
-       MFC_WRITEL(0x0, MFC_REG_NAL_QUEUE_OUTPUT_COUNT);
-       MFC_WRITEL(0x0, MFC_REG_NAL_QUEUE_INPUT_EXE_COUNT);
-       MFC_WRITEL(0x0, MFC_REG_NAL_QUEUE_INFO);
-}
-
-static inline void mfc_update_nal_queue_input(struct mfc_dev *dev,
-       dma_addr_t addr, unsigned int size)
-{
-       MFC_WRITEL(addr, MFC_REG_NAL_QUEUE_INPUT_ADDR);
-       MFC_WRITEL(size, MFC_REG_NAL_QUEUE_INPUT_SIZE);
-}
-
-static inline void mfc_update_nal_queue_output(struct mfc_dev *dev,
-       dma_addr_t addr, unsigned int size)
-{
-       MFC_WRITEL(addr, MFC_REG_NAL_QUEUE_OUTPUT_ADDR);
-       MFC_WRITEL(size, MFC_REG_NAL_QUEUE_OUTPUT_SIZE);
-}
-
-static inline void mfc_update_nal_queue_input_count(struct mfc_dev *dev,
-       unsigned int input_count)
-{
-       MFC_WRITEL(input_count, MFC_REG_NAL_QUEUE_INPUT_COUNT);
-}
-
-static inline void mfc_dec_store_crop_info(struct mfc_ctx *ctx)
-{
-       struct mfc_dev *dev = ctx->dev;
-       struct mfc_dec *dec = ctx->dec_priv;
-       u32 left, right, top, bottom;
-
-       left = MFC_READL(MFC_REG_D_DISPLAY_CROP_INFO1);
-       right = left >> MFC_REG_D_SHARED_CROP_RIGHT_SHIFT;
-       left = left & MFC_REG_D_SHARED_CROP_LEFT_MASK;
-       top = MFC_READL(MFC_REG_D_DISPLAY_CROP_INFO2);
-       bottom = top >> MFC_REG_D_SHARED_CROP_BOTTOM_SHIFT;
-       top = top & MFC_REG_D_SHARED_CROP_TOP_MASK;
-
-       dec->cr_left = left;
-       dec->cr_right = right;
-       dec->cr_top = top;
-       dec->cr_bot = bottom;
-}
-
-static inline void mfc_clear_enc_res_change(struct mfc_dev *dev)
-{
-       unsigned int reg = 0;
-
-       reg = MFC_READL(MFC_REG_E_PARAM_CHANGE);
-       reg &= ~(0x7 << 6);
-       MFC_WRITEL(reg, MFC_REG_E_PARAM_CHANGE);
-}
-
-static inline void mfc_clear_roi_enable(struct mfc_dev *dev)
-{
-       unsigned int reg = 0;
-
-       reg = MFC_READL(MFC_REG_E_RC_ROI_CTRL);
-       reg &= ~(0x1);
-       MFC_WRITEL(reg, MFC_REG_E_RC_ROI_CTRL);
-}
-
-void mfc_dbg_enable(struct mfc_dev *dev);
-void mfc_dbg_disable(struct mfc_dev *dev);
-void mfc_dbg_set_addr(struct mfc_dev *dev);
-
-void mfc_otf_set_frame_addr(struct mfc_ctx *ctx, int num_planes);
-void mfc_otf_set_stream_size(struct mfc_ctx *ctx, unsigned int size);
-void mfc_otf_set_hwfc_index(struct mfc_ctx *ctx, int job_id);
-
-int mfc_set_dec_codec_buffers(struct mfc_ctx *ctx);
-int mfc_set_enc_codec_buffers(struct mfc_ctx *mfc_ctx);
-
-int mfc_set_dec_stream_buffer(struct mfc_ctx *ctx,
-               struct mfc_buf *mfc_buf,
-               unsigned int start_num_byte,
-               unsigned int buf_size);
-
-void mfc_set_enc_frame_buffer(struct mfc_ctx *ctx,
-               struct mfc_buf *mfc_buf, int num_planes);
-int mfc_set_enc_stream_buffer(struct mfc_ctx *ctx,
-               struct mfc_buf *mfc_buf);
-
-void mfc_get_enc_frame_buffer(struct mfc_ctx *ctx,
-               dma_addr_t addr[], int num_planes);
-void mfc_set_enc_stride(struct mfc_ctx *ctx);
-
-int mfc_set_dynamic_dpb(struct mfc_ctx *ctx, struct mfc_buf *dst_vb);
-
-void mfc_set_pixel_format(struct mfc_dev *dev, unsigned int format);
-
-#endif /* __MFC_REG_H */
diff --git a/drivers/media/platform/exynos/mfc/mfc_reg_api.c b/drivers/media/platform/exynos/mfc/mfc_reg_api.c
new file mode 100644 (file)
index 0000000..469a7fc
--- /dev/null
@@ -0,0 +1,547 @@
+/*
+ * drivers/media/platform/exynos/mfc/mfc_reg.c
+ *
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/delay.h>
+
+#include "mfc_reg_api.h"
+
+void mfc_dbg_enable(struct mfc_dev *dev)
+{
+       mfc_debug(2, "MFC debug info enable\n");
+       MFC_WRITEL(0x1, MFC_REG_DBG_INFO_ENABLE);
+}
+
+void mfc_dbg_disable(struct mfc_dev *dev)
+{
+       mfc_debug(2, "MFC debug info disable\n");
+       MFC_WRITEL(0x0, MFC_REG_DBG_INFO_ENABLE);
+}
+
+void mfc_dbg_set_addr(struct mfc_dev *dev)
+{
+       struct mfc_ctx_buf_size *buf_size = dev->variant->buf_size->ctx_buf;
+
+       memset((void *)dev->dbg_info_buf.vaddr, 0, buf_size->dbg_info_buf);
+
+       MFC_WRITEL(dev->dbg_info_buf.daddr, MFC_REG_DBG_BUFFER_ADDR);
+       MFC_WRITEL(buf_size->dbg_info_buf, MFC_REG_DBG_BUFFER_SIZE);
+}
+
+void mfc_otf_set_frame_addr(struct mfc_ctx *ctx, int num_planes)
+{
+       struct mfc_dev *dev = ctx->dev;
+       struct _otf_handle *handle = ctx->otf_handle;
+       struct _otf_buf_addr *buf_addr = &handle->otf_buf_addr;
+       int index = handle->otf_buf_index;
+       int i;
+
+       for (i = 0; i < num_planes; i++) {
+               mfc_debug(2, "[OTF][FRAME] set frame buffer[%d], 0x%08llx)\n",
+                               i, buf_addr->otf_daddr[index][i]);
+               MFC_WRITEL(buf_addr->otf_daddr[index][i],
+                               MFC_REG_E_SOURCE_FIRST_ADDR + (i * 4));
+       }
+}
+
+void mfc_otf_set_stream_size(struct mfc_ctx *ctx, unsigned int size)
+{
+       struct mfc_dev *dev = ctx->dev;
+       struct _otf_handle *handle = ctx->otf_handle;
+       struct _otf_debug *debug = &handle->otf_debug;
+       struct mfc_special_buf *buf;
+
+       mfc_debug(2, "[OTF] set stream buffer full size, %u\n", size);
+       MFC_WRITEL(size, MFC_REG_E_STREAM_BUFFER_SIZE);
+
+       if (otf_dump && !ctx->is_drm) {
+               buf = &debug->stream_buf[debug->frame_cnt];
+               mfc_debug(2, "[OTF] set stream addr for debugging\n");
+               mfc_debug(2, "[OTF][STREAM] buf[%d] daddr: 0x%08llx\n",
+                               debug->frame_cnt, buf->daddr);
+               MFC_WRITEL(buf->daddr, MFC_REG_E_STREAM_BUFFER_ADDR);
+       }
+}
+
+void mfc_otf_set_hwfc_index(struct mfc_ctx *ctx, int job_id)
+{
+       struct mfc_dev *dev = ctx->dev;
+
+       mfc_debug(2, "[OTF] set hwfc index, %d\n", job_id);
+       HWFC_WRITEL(job_id, HWFC_ENCODING_IDX);
+}
+
+/* Set decoding frame buffer */
+int mfc_set_dec_codec_buffers(struct mfc_ctx *ctx)
+{
+       struct mfc_dev *dev;
+       struct mfc_dec *dec;
+       unsigned int i;
+       size_t frame_size_mv;
+       dma_addr_t buf_addr;
+       int buf_size;
+       int align_gap;
+       struct mfc_raw_info *raw;
+       unsigned int reg = 0;
+
+       if (!ctx) {
+               mfc_err_dev("no mfc context to run\n");
+               return -EINVAL;
+       }
+
+       dev = ctx->dev;
+       if (!dev) {
+               mfc_err_dev("no mfc device to run\n");
+               return -EINVAL;
+       }
+
+       dec = ctx->dec_priv;
+       if (!dec) {
+               mfc_err_dev("no mfc decoder to run\n");
+               return -EINVAL;
+       }
+
+       raw = &ctx->raw_buf;
+       buf_addr = ctx->codec_buf.daddr;
+       buf_size = ctx->codec_buf.size;
+
+       mfc_debug(2, "[MEMINFO] codec buf 0x%llx size: %d\n", buf_addr, buf_size);
+       mfc_debug(2, "Total DPB COUNT: %d, display delay: %d\n",
+                       dec->total_dpb_count, dec->display_delay);
+
+       /* set decoder DPB size, stride */
+       MFC_WRITEL(dec->total_dpb_count, MFC_REG_D_NUM_DPB);
+       for (i = 0; i < raw->num_planes; i++) {
+               mfc_debug(2, "[FRAME] buf[%d] size: %d, stride: %d\n",
+                               i, raw->plane_size[i], raw->stride[i]);
+               MFC_WRITEL(raw->plane_size[i], MFC_REG_D_FIRST_PLANE_DPB_SIZE + (i * 4));
+               MFC_WRITEL(ctx->raw_buf.stride[i],
+                               MFC_REG_D_FIRST_PLANE_DPB_STRIDE_SIZE + (i * 4));
+               if (ctx->is_10bit) {
+                       MFC_WRITEL(raw->stride_2bits[i], MFC_REG_D_FIRST_PLANE_2BIT_DPB_STRIDE_SIZE + (i * 4));
+                       MFC_WRITEL(raw->plane_size_2bits[i], MFC_REG_D_FIRST_PLANE_2BIT_DPB_SIZE + (i * 4));
+                       mfc_debug(2, "[FRAME][10BIT] 2bits buf[%d] size: %d, stride: %d\n",
+                                       i, raw->plane_size_2bits[i], raw->stride_2bits[i]);
+               }
+       }
+
+       /* set codec buffers */
+       MFC_WRITEL(buf_addr, MFC_REG_D_SCRATCH_BUFFER_ADDR);
+       MFC_WRITEL(ctx->scratch_buf_size, MFC_REG_D_SCRATCH_BUFFER_SIZE);
+       buf_addr += ctx->scratch_buf_size;
+       buf_size -= ctx->scratch_buf_size;
+
+       if (IS_H264_DEC(ctx) || IS_H264_MVC_DEC(ctx) || IS_HEVC_DEC(ctx) || IS_BPG_DEC(ctx))
+               MFC_WRITEL(ctx->mv_size, MFC_REG_D_MV_BUFFER_SIZE);
+
+       if (IS_VP9_DEC(ctx)){
+               MFC_WRITEL(buf_addr, MFC_REG_D_STATIC_BUFFER_ADDR);
+               MFC_WRITEL(DEC_STATIC_BUFFER_SIZE, MFC_REG_D_STATIC_BUFFER_SIZE);
+               buf_addr += DEC_STATIC_BUFFER_SIZE;
+               buf_size -= DEC_STATIC_BUFFER_SIZE;
+       }
+
+       if (IS_MPEG4_DEC(ctx) && dec->loop_filter_mpeg4) {
+               mfc_debug(2, "Add DPB for loop filter of MPEG4\n");
+               for (i = 0; i < NUM_MPEG4_LF_BUF; i++) {
+                       MFC_WRITEL(buf_addr, MFC_REG_D_POST_FILTER_LUMA_DPB0 + (4 * i));
+                       buf_addr += ctx->loopfilter_luma_size;
+                       buf_size -= ctx->loopfilter_luma_size;
+
+                       MFC_WRITEL(buf_addr, MFC_REG_D_POST_FILTER_CHROMA_DPB0 + (4 * i));
+                       buf_addr += ctx->loopfilter_chroma_size;
+                       buf_size -= ctx->loopfilter_chroma_size;
+               }
+               reg |= ((dec->loop_filter_mpeg4 & MFC_REG_D_INIT_BUF_OPT_LF_CTRL_MASK)
+                               << MFC_REG_D_INIT_BUF_OPT_LF_CTRL_SHIFT);
+       }
+
+       reg |= (0x1 << MFC_REG_D_INIT_BUF_OPT_DYNAMIC_DPB_SET_SHIFT);
+
+       if (CODEC_NOT_CODED(ctx)) {
+               reg |= (0x1 << MFC_REG_D_INIT_BUF_OPT_COPY_NOT_CODED_SHIFT);
+               mfc_debug(2, "Notcoded frame copy mode start\n");
+       }
+       /* Enable 10bit Dithering */
+       if (ctx->is_10bit) {
+               reg |= (0x1 << MFC_REG_D_INIT_BUF_OPT_DITHERING_EN_SHIFT);
+               /* 64byte align, It is vaid only for VP9 */
+               reg |= (0x1 << MFC_REG_D_INIT_BUF_OPT_STRIDE_SIZE_ALIGN);
+       } else {
+               /* 16byte align, It is vaid only for VP9 */
+               reg &= ~(0x1 << MFC_REG_D_INIT_BUF_OPT_STRIDE_SIZE_ALIGN);
+       }
+
+       MFC_WRITEL(reg, MFC_REG_D_INIT_BUFFER_OPTIONS);
+
+       frame_size_mv = ctx->mv_size;
+       MFC_WRITEL(dec->mv_count, MFC_REG_D_NUM_MV);
+       if (IS_H264_DEC(ctx) || IS_H264_MVC_DEC(ctx) || IS_HEVC_DEC(ctx) || IS_BPG_DEC(ctx)) {
+               for (i = 0; i < dec->mv_count; i++) {
+                       /* To test alignment */
+                       align_gap = buf_addr;
+                       buf_addr = ALIGN(buf_addr, 16);
+                       align_gap = buf_addr - align_gap;
+                       buf_size -= align_gap;
+
+                       MFC_WRITEL(buf_addr, MFC_REG_D_MV_BUFFER0 + i * 4);
+                       buf_addr += frame_size_mv;
+                       buf_size -= frame_size_mv;
+               }
+       }
+
+       mfc_debug(2, "[MEMINFO] codec buf 0x%llx, remained size: %d\n", buf_addr, buf_size);
+       if (buf_size < 0) {
+               mfc_debug(2, "[MEMINFO] Not enough memory has been allocated\n");
+               return -ENOMEM;
+       }
+
+       return 0;
+}
+
+/* Set encoding ref & codec buffer */
+int mfc_set_enc_codec_buffers(struct mfc_ctx *ctx)
+{
+       struct mfc_dev *dev = ctx->dev;
+       struct mfc_enc *enc = ctx->enc_priv;
+       dma_addr_t buf_addr;
+       int buf_size;
+       int i;
+
+       mfc_debug_enter();
+
+       buf_addr = ctx->codec_buf.daddr;
+       buf_size = ctx->codec_buf.size;
+
+       mfc_debug(2, "[MEMINFO] codec buf 0x%llx, size: %d\n", buf_addr, buf_size);
+       mfc_debug(2, "DPB COUNT: %d\n", ctx->dpb_count);
+
+       MFC_WRITEL(buf_addr, MFC_REG_E_SCRATCH_BUFFER_ADDR);
+       MFC_WRITEL(ctx->scratch_buf_size, MFC_REG_E_SCRATCH_BUFFER_SIZE);
+       buf_addr += ctx->scratch_buf_size;
+       buf_size -= ctx->scratch_buf_size;
+
+       /* start address of per buffer is aligned */
+       for (i = 0; i < ctx->dpb_count; i++) {
+               MFC_WRITEL(buf_addr, MFC_REG_E_LUMA_DPB + (4 * i));
+               buf_addr += enc->luma_dpb_size;
+               buf_size -= enc->luma_dpb_size;
+       }
+       for (i = 0; i < ctx->dpb_count; i++) {
+               MFC_WRITEL(buf_addr, MFC_REG_E_CHROMA_DPB + (4 * i));
+               buf_addr += enc->chroma_dpb_size;
+               buf_size -= enc->chroma_dpb_size;
+       }
+       for (i = 0; i < ctx->dpb_count; i++) {
+               MFC_WRITEL(buf_addr, MFC_REG_E_ME_BUFFER + (4 * i));
+               buf_addr += enc->me_buffer_size;
+               buf_size -= enc->me_buffer_size;
+       }
+
+       MFC_WRITEL(buf_addr, MFC_REG_E_TMV_BUFFER0);
+       buf_addr += enc->tmv_buffer_size >> 1;
+       MFC_WRITEL(buf_addr, MFC_REG_E_TMV_BUFFER1);
+       buf_addr += enc->tmv_buffer_size >> 1;
+       buf_size -= enc->tmv_buffer_size;
+
+       mfc_debug(2, "[MEMINFO] codec buf 0x%llx, remained size: %d\n", buf_addr, buf_size);
+       if (buf_size < 0) {
+               mfc_debug(2, "[MEMINFO] Not enough memory has been allocated\n");
+               return -ENOMEM;
+       }
+
+       mfc_debug_leave();
+
+       return 0;
+}
+
+/* Set registers for decoding stream buffer */
+int mfc_set_dec_stream_buffer(struct mfc_ctx *ctx, struct mfc_buf *mfc_buf,
+                 unsigned int start_num_byte, unsigned int strm_size)
+{
+       struct mfc_dev *dev;
+       struct mfc_dec *dec;
+       unsigned int cpb_buf_size;
+       dma_addr_t addr;
+       int index = -1;
+
+       mfc_debug_enter();
+       if (!ctx) {
+               mfc_err_dev("no mfc context to run\n");
+               return -EINVAL;
+       }
+       dev = ctx->dev;
+       if (!dev) {
+               mfc_err_dev("no mfc device to run\n");
+               return -EINVAL;
+       }
+       dec = ctx->dec_priv;
+       if (!dec) {
+               mfc_err_dev("no mfc decoder to run\n");
+               return -EINVAL;
+       }
+
+       cpb_buf_size = ALIGN(dec->src_buf_size, STREAM_BUF_ALIGN);
+
+       if (mfc_buf) {
+               index = mfc_buf->vb.vb2_buf.index;
+               addr = mfc_buf->addr[0][0];
+               if (strm_size > set_strm_size_max(cpb_buf_size)) {
+                       mfc_info_ctx("Decrease strm_size because of %d align: %u -> %u\n",
+                               STREAM_BUF_ALIGN, strm_size, set_strm_size_max(cpb_buf_size));
+                       strm_size = set_strm_size_max(cpb_buf_size);
+                       mfc_buf->vb.vb2_buf.planes[0].bytesused = strm_size;
+               }
+       } else {
+               addr = 0;
+       }
+
+       mfc_debug(2, "[BUFINFO] ctx[%d] set src index: %d, addr: 0x%08llx\n",
+                       ctx->num, index, addr);
+       mfc_debug(2, "[STREAM] strm_size: %#lx(%d), buf_size: %u, offset: %u\n",
+                       strm_size, strm_size, cpb_buf_size, start_num_byte);
+
+       if (strm_size == 0)
+               mfc_info_ctx("stream size is 0\n");
+
+       MFC_WRITEL(strm_size, MFC_REG_D_STREAM_DATA_SIZE);
+       MFC_WRITEL(addr, MFC_REG_D_CPB_BUFFER_ADDR);
+       MFC_WRITEL(cpb_buf_size, MFC_REG_D_CPB_BUFFER_SIZE);
+       MFC_WRITEL(start_num_byte, MFC_REG_D_CPB_BUFFER_OFFSET);
+
+       if (mfc_buf)
+               MFC_TRACE_CTX("Set src[%d] fd: %d, %#llx\n",
+                               index, mfc_buf->vb.vb2_buf.planes[0].m.fd, addr);
+
+       mfc_debug_leave();
+       return 0;
+}
+
+void mfc_set_enc_frame_buffer(struct mfc_ctx *ctx,
+               struct mfc_buf *mfc_buf, int num_planes)
+{
+       struct mfc_dev *dev = ctx->dev;
+       dma_addr_t addr[3] = { 0, 0, 0 };
+       dma_addr_t addr_2bit[2] = { 0, 0 };
+       int index, i;
+
+       if (!mfc_buf) {
+               mfc_debug(3, "enc zero buffer set\n");
+               goto buffer_set;
+       }
+
+       index = mfc_buf->vb.vb2_buf.index;
+       if (mfc_buf->num_valid_bufs > 0) {
+               for (i = 0; i < num_planes; i++) {
+                       addr[i] = mfc_buf->addr[mfc_buf->next_index][i];
+                       mfc_debug(2, "[BUFCON][BUFINFO] ctx[%d] set src index:%d, batch[%d], addr[%d]: 0x%08llx\n",
+                                       ctx->num, index, mfc_buf->next_index, i, addr[i]);
+               }
+               mfc_buf->next_index++;
+       } else {
+               for (i = 0; i < num_planes; i++) {
+                       addr[i] = mfc_buf->addr[0][i];
+                       mfc_debug(2, "[BUFINFO] ctx[%d] set src index:%d, addr[%d]: 0x%08llx\n",
+                                       ctx->num, index, i, addr[i]);
+               }
+       }
+
+buffer_set:
+       for (i = 0; i < num_planes; i++)
+               MFC_WRITEL(addr[i], MFC_REG_E_SOURCE_FIRST_ADDR + (i * 4));
+
+       if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12M_S10B ||
+               ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV21M_S10B) {
+               addr_2bit[0] = addr[0] + NV12N_10B_Y_8B_SIZE(ctx->img_width, ctx->img_height);
+               addr_2bit[1] = addr[1] + NV12N_10B_CBCR_8B_SIZE(ctx->img_width, ctx->img_height);
+
+               for (i = 0; i < num_planes; i++) {
+                       MFC_WRITEL(addr_2bit[i], MFC_REG_E_SOURCE_FIRST_2BIT_ADDR + (i * 4));
+                       mfc_debug(2, "[BUFINFO][10BIT] ctx[%d] set src 2bit addr[%d]: 0x%08llx\n",
+                                       ctx->num, i, addr_2bit[i]);
+               }
+       } else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV16M_S10B ||
+               ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV61M_S10B) {
+               addr_2bit[0] = addr[0] + NV16M_Y_SIZE(ctx->img_width, ctx->img_height);
+               addr_2bit[1] = addr[1] + NV16M_CBCR_SIZE(ctx->img_width, ctx->img_height);
+
+               for (i = 0; i < num_planes; i++) {
+                       MFC_WRITEL(addr_2bit[i], MFC_REG_E_SOURCE_FIRST_2BIT_ADDR + (i * 4));
+                       mfc_debug(2, "[BUFINFO][10BIT] ctx[%d] set src 2bit addr[%d]: 0x%08llx\n",
+                                       ctx->num, i, addr_2bit[i]);
+               }
+       }
+}
+
+/* Set registers for encoding stream buffer */
+int mfc_set_enc_stream_buffer(struct mfc_ctx *ctx,
+               struct mfc_buf *mfc_buf)
+{
+       struct mfc_dev *dev = ctx->dev;
+       dma_addr_t addr;
+       unsigned int size, offset, index;
+
+       index = mfc_buf->vb.vb2_buf.index;
+       addr = mfc_buf->addr[0][0];
+       offset = mfc_buf->vb.vb2_buf.planes[0].data_offset;
+       size = (unsigned int)vb2_plane_size(&mfc_buf->vb.vb2_buf, 0);
+       size = ALIGN(size, 512);
+
+       MFC_WRITEL(addr, MFC_REG_E_STREAM_BUFFER_ADDR); /* 16B align */
+       MFC_WRITEL(size, MFC_REG_E_STREAM_BUFFER_SIZE);
+       MFC_WRITEL(offset, MFC_REG_E_STREAM_BUFFER_OFFSET);
+
+       mfc_debug(2, "[BUFINFO] ctx[%d] set dst index: %d, addr: 0x%08llx\n",
+                       ctx->num, index, addr);
+       mfc_debug(2, "[STREAM] buf_size: %u, offset: %d\n", size, offset);
+
+       return 0;
+}
+
+void mfc_get_enc_frame_buffer(struct mfc_ctx *ctx,
+               dma_addr_t addr[], int num_planes)
+{
+       struct mfc_dev *dev = ctx->dev;
+       unsigned long enc_recon_y_addr, enc_recon_c_addr;
+       int i, addr_offset;
+
+       addr_offset = MFC_REG_E_ENCODED_SOURCE_FIRST_ADDR;
+
+       for (i = 0; i < num_planes; i++)
+               addr[i] = MFC_READL(addr_offset + (i * 4));
+
+       enc_recon_y_addr = MFC_READL(MFC_REG_E_RECON_LUMA_DPB_ADDR);
+       enc_recon_c_addr = MFC_READL(MFC_REG_E_RECON_CHROMA_DPB_ADDR);
+
+       mfc_debug(2, "[MEMINFO] recon y: 0x%08lx c: 0x%08lx\n",
+                       enc_recon_y_addr, enc_recon_c_addr);
+}
+
+void mfc_set_enc_stride(struct mfc_ctx *ctx)
+{
+       struct mfc_dev *dev = ctx->dev;
+       int i;
+
+       for (i = 0; i < ctx->raw_buf.num_planes; i++) {
+               MFC_WRITEL(ctx->raw_buf.stride[i],
+                               MFC_REG_E_SOURCE_FIRST_STRIDE + (i * 4));
+               mfc_debug(2, "[FRAME] enc src plane[%d] stride: %d\n",
+                               i, ctx->raw_buf.stride[i]);
+       }
+}
+
+int mfc_set_dynamic_dpb(struct mfc_ctx *ctx, struct mfc_buf *dst_mb)
+{
+       struct mfc_dev *dev = ctx->dev;
+       struct mfc_dec *dec = ctx->dec_priv;
+       struct mfc_raw_info *raw = &ctx->raw_buf;
+       int dst_index;
+       int i;
+
+       dst_index = dst_mb->vb.vb2_buf.index;
+       set_bit(dst_index, &dec->available_dpb);
+       dec->dynamic_set = 1 << dst_index;
+       mfc_debug(2, "[DPB] ADDING Flag after: 0x%lx\n", dec->available_dpb);
+
+       /* for debugging about black bar detection */
+       if (MFC_FEATURE_SUPPORT(dev, dev->pdata->black_bar) && dec->detect_black_bar) {
+               for (i = 0; i < raw->num_planes; i++) {
+                       dec->frame_vaddr[i][dec->frame_cnt] = vb2_plane_vaddr(&dst_mb->vb.vb2_buf, i);
+                       dec->frame_daddr[i][dec->frame_cnt] = dst_mb->addr[0][i];
+                       dec->frame_size[i][dec->frame_cnt] = raw->plane_size[i];
+                       dec->index[i][dec->frame_cnt] = dst_index;
+                       dec->fd[i][dec->frame_cnt] = dst_mb->vb.vb2_buf.planes[0].m.fd;
+               }
+               dec->frame_cnt++;
+               if (dec->frame_cnt >= 30)
+                       dec->frame_cnt = 0;
+       }
+
+       /* decoder dst buffer CFW PROT */
+       mfc_protect_dpb(ctx, dst_mb);
+
+       for (i = 0; i < raw->num_planes; i++) {
+               MFC_WRITEL(raw->plane_size[i],
+                               MFC_REG_D_FIRST_PLANE_DPB_SIZE + i * 4);
+               MFC_WRITEL(dst_mb->addr[0][i],
+                               MFC_REG_D_FIRST_PLANE_DPB0 + (i * 0x100 + dst_index * 4));
+               if (ctx->is_10bit)
+                       MFC_WRITEL(raw->plane_size_2bits[i],
+                                       MFC_REG_D_FIRST_PLANE_2BIT_DPB_SIZE + (i * 4));
+               mfc_debug(2, "[BUFINFO][DPB] ctx[%d] set dst index: %d, addr[%d]: 0x%08llx\n",
+                               ctx->num, dst_index, i, dst_mb->addr[0][i]);
+       }
+
+       MFC_TRACE_CTX("Set dst[%d] fd: %d, %#llx / avail %#lx used %#x\n",
+                       dst_index, dst_mb->vb.vb2_buf.planes[0].m.fd, dst_mb->addr[0][0],
+                       dec->available_dpb, dec->dynamic_used);
+
+       return 0;
+}
+
+void mfc_set_pixel_format(struct mfc_dev *dev, unsigned int format)
+{
+       unsigned int reg = 0;
+       unsigned int pix_val, mem_type_10bit = 0;
+
+       if (dev->pdata->P010_decoding)
+               mem_type_10bit = 1;
+
+       switch (format) {
+       case V4L2_PIX_FMT_NV12M:
+       case V4L2_PIX_FMT_NV12N:
+       case V4L2_PIX_FMT_NV12MT_16X16:
+       case V4L2_PIX_FMT_NV16M:
+               pix_val = 0;
+               break;
+       case V4L2_PIX_FMT_NV21M:
+       case V4L2_PIX_FMT_NV61M:
+               pix_val = 1;
+               break;
+       case V4L2_PIX_FMT_YVU420M:
+               pix_val = 2;
+               break;
+       case V4L2_PIX_FMT_YUV420M:
+       case V4L2_PIX_FMT_YUV420N:
+               pix_val = 3;
+               break;
+       /* For 10bit direct set */
+       case V4L2_PIX_FMT_NV12N_10B:
+       case V4L2_PIX_FMT_NV12M_S10B:
+       case V4L2_PIX_FMT_NV16M_S10B:
+               mem_type_10bit = 0;
+               pix_val = 0;
+               break;
+       case V4L2_PIX_FMT_NV12M_P010:
+       case V4L2_PIX_FMT_NV16M_P210:
+               mem_type_10bit = 1;
+               pix_val = 0;
+               break;
+       case V4L2_PIX_FMT_NV21M_S10B:
+       case V4L2_PIX_FMT_NV61M_S10B:
+               mem_type_10bit = 0;
+               pix_val = 1;
+               break;
+       case V4L2_PIX_FMT_NV21M_P010:
+       case V4L2_PIX_FMT_NV61M_P210:
+               mem_type_10bit = 1;
+               pix_val = 1;
+               break;
+       default:
+               pix_val = 0;
+               break;
+       }
+       reg |= pix_val;
+       reg |= (mem_type_10bit << 4);
+       MFC_WRITEL(reg, MFC_REG_PIXEL_FORMAT);
+       mfc_debug(2, "[FRAME] pixel format: %d, mem_type_10bit for 10bit: %d (reg: %#x)\n",
+                       pix_val, mem_type_10bit, reg);
+}
diff --git a/drivers/media/platform/exynos/mfc/mfc_reg_api.h b/drivers/media/platform/exynos/mfc/mfc_reg_api.h
new file mode 100644 (file)
index 0000000..4a0110e
--- /dev/null
@@ -0,0 +1,271 @@
+/*
+ * drivers/media/platform/exynos/mfc/mfc_reg_api.h
+ *
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __MFC_REG_API_H
+#define __MFC_REG_API_H __FILE__
+
+#include "mfc_common.h"
+
+#include "mfc_utils.h"
+
+#define MFC_READL(offset)              readl(dev->regs_base + (offset))
+#define MFC_WRITEL(data, offset)       writel((data), dev->regs_base + (offset))
+
+#define MFC_MMU0_READL(offset)         readl(dev->sysmmu0_base + (offset))
+#define MFC_MMU1_READL(offset)         readl(dev->sysmmu1_base + (offset))
+
+#define HWFC_WRITEL(data, offset)      writel((data), dev->hwfc_base + (offset))
+
+#define MMCACHE_READL(offset)          readl(dev->mmcache.base + (offset))
+#define MMCACHE_WRITEL(data, offset)   writel((data), dev->mmcache.base + (offset))
+
+/* version */
+#define mfc_get_fimv_info()            ((MFC_READL(MFC_REG_FW_VERSION)         \
+                                               >> MFC_REG_FW_VER_INFO_SHFT)            \
+                                               & MFC_REG_FW_VER_INFO_MASK)
+#define mfc_get_fw_ver_year()  ((MFC_READL(MFC_REG_FW_VERSION)         \
+                                               >> MFC_REG_FW_VER_YEAR_SHFT)            \
+                                               & MFC_REG_FW_VER_YEAR_MASK)
+#define mfc_get_fw_ver_month() ((MFC_READL(MFC_REG_FW_VERSION)         \
+                                               >> MFC_REG_FW_VER_MONTH_SHFT)           \
+                                               & MFC_REG_FW_VER_MONTH_MASK)
+#define mfc_get_fw_ver_date()  ((MFC_READL(MFC_REG_FW_VERSION)         \
+                                               >> MFC_REG_FW_VER_DATE_SHFT)            \
+                                               & MFC_REG_FW_VER_DATE_MASK)
+#define mfc_get_fw_ver_all()   ((MFC_READL(MFC_REG_FW_VERSION)         \
+                                               >> MFC_REG_FW_VER_ALL_SHFT)             \
+                                               & MFC_REG_FW_VER_ALL_MASK)
+#define mfc_get_mfc_version()  ((MFC_READL(MFC_REG_MFC_VERSION)                \
+                                               >> MFC_REG_MFC_VER_SHFT)                \
+                                               & MFC_REG_MFC_VER_MASK)
+
+
+/* decoding & display information */
+#define mfc_get_dec_status()   (MFC_READL(MFC_REG_D_DECODED_STATUS)            \
+                                               & MFC_REG_DEC_STATUS_DECODED_STATUS_MASK)
+#define mfc_get_disp_status()  (MFC_READL(MFC_REG_D_DISPLAY_STATUS)            \
+                                               & MFC_REG_DISP_STATUS_DISPLAY_STATUS_MASK)
+#define mfc_get_res_change()   ((MFC_READL(MFC_REG_D_DISPLAY_STATUS)           \
+                                               >> MFC_REG_DISP_STATUS_RES_CHANGE_SHIFT)        \
+                                               & MFC_REG_DISP_STATUS_RES_CHANGE_MASK)
+#define mfc_get_black_bar_detection()  ((MFC_READL(MFC_REG_D_DISPLAY_STATUS)           \
+                                               >> MFC_REG_DISP_STATUS_BLACK_BAR_DETECT_SHIFT)  \
+                                               & MFC_REG_DISP_STATUS_BLACK_BAR_DETECT_MASK)
+#define mfc_get_dpb_change()   ((MFC_READL(MFC_REG_D_DISPLAY_STATUS)           \
+                                               >> MFC_REG_DISP_STATUS_NEED_DPB_CHANGE_SHIFT)   \
+                                               & MFC_REG_DISP_STATUS_NEED_DPB_CHANGE_MASK)
+#define mfc_get_scratch_change()       ((MFC_READL(MFC_REG_D_DISPLAY_STATUS)           \
+                                               >> MFC_REG_DISP_STATUS_NEED_SCRATCH_CHANGE_SHIFT)       \
+                                               & MFC_REG_DISP_STATUS_NEED_SCRATCH_CHANGE_MASK)
+#define mfc_get_disp_frame_type()      (MFC_READL(MFC_REG_D_DISPLAY_FRAME_TYPE)        \
+                                               & MFC_REG_DISPLAY_FRAME_MASK)
+#define mfc_get_dec_frame_type()       (MFC_READL(MFC_REG_D_DECODED_FRAME_TYPE)        \
+                                               & MFC_REG_DECODED_FRAME_MASK)
+#define mfc_get_interlace_type()       ((MFC_READL(MFC_REG_D_DISPLAY_FRAME_TYPE)       \
+                                               >> MFC_REG_DISPLAY_TEMP_INFO_SHIFT)     \
+                                               & MFC_REG_DISPLAY_TEMP_INFO_MASK)
+#define mfc_is_interlace_picture()     ((MFC_READL(MFC_REG_D_DISPLAY_STATUS)           \
+                                               >> MFC_REG_DISP_STATUS_INTERLACE_SHIFT)\
+                                               & MFC_REG_DISP_STATUS_INTERLACE_MASK)
+#define mfc_is_mbaff_picture() ((MFC_READL(MFC_REG_D_H264_INFO)                \
+                                               >> MFC_REG_D_H264_INFO_MBAFF_FRAME_FLAG_SHIFT)\
+                                               & MFC_REG_D_H264_INFO_MBAFF_FRAME_FLAG_MASK)
+#define mfc_get_img_width()            MFC_READL(MFC_REG_D_DISPLAY_FRAME_WIDTH)
+#define mfc_get_img_height()   MFC_READL(MFC_REG_D_DISPLAY_FRAME_HEIGHT)
+#define mfc_get_disp_y_addr()  MFC_READL(MFC_REG_D_DISPLAY_LUMA_ADDR)
+#define mfc_get_dec_y_addr()   MFC_READL(MFC_REG_D_DECODED_LUMA_ADDR)
+
+
+/* kind of interrupt */
+#define mfc_get_int_err()              MFC_READL(MFC_REG_ERROR_CODE)
+#define mfc_get_err(x)         (((x) >> MFC_REG_ERR_STATUS_SHIFT)              \
+                                               & MFC_REG_ERR_STATUS_MASK)
+#define mfc_get_warn(x)                (((x) >> MFC_REG_WARN_STATUS_SHIFT)             \
+                                               & MFC_REG_WARN_STATUS_MASK)
+
+
+/* additional information */
+#define mfc_get_consumed_stream()              MFC_READL(MFC_REG_D_DECODED_NAL_SIZE)
+#define mfc_get_dpb_count()                    MFC_READL(MFC_REG_D_MIN_NUM_DPB)
+#define mfc_get_min_dpb_size(x)                MFC_READL(MFC_REG_D_MIN_FIRST_PLANE_DPB_SIZE + (x * 4))
+#define mfc_get_scratch_size()         MFC_READL(MFC_REG_D_MIN_SCRATCH_BUFFER_SIZE)
+#define mfc_get_mv_count()                     MFC_READL(MFC_REG_D_MIN_NUM_MV)
+#define mfc_get_inst_no()                      MFC_READL(MFC_REG_RET_INSTANCE_ID)
+#define mfc_get_enc_dpb_count()                MFC_READL(MFC_REG_E_NUM_DPB)
+#define mfc_get_enc_scratch_size()             MFC_READL(MFC_REG_E_MIN_SCRATCH_BUFFER_SIZE)
+#define mfc_get_enc_strm_size()                MFC_READL(MFC_REG_E_STREAM_SIZE)
+#define mfc_get_enc_slice_type()               MFC_READL(MFC_REG_E_SLICE_TYPE)
+#define mfc_get_enc_pic_count()                MFC_READL(MFC_REG_E_PICTURE_COUNT)
+#define mfc_get_sei_avail()                    MFC_READL(MFC_REG_D_SEI_AVAIL)
+#define mfc_get_sei_content_light()            MFC_READL(MFC_REG_D_CONTENT_LIGHT_LEVEL_INFO_SEI)
+#define mfc_get_sei_mastering0()               MFC_READL(MFC_REG_D_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_0)
+#define mfc_get_sei_mastering1()               MFC_READL(MFC_REG_D_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_1)
+#define mfc_get_sei_mastering2()               MFC_READL(MFC_REG_D_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_2)
+#define mfc_get_sei_mastering3()               MFC_READL(MFC_REG_D_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_3)
+#define mfc_get_sei_mastering4()               MFC_READL(MFC_REG_D_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_4)
+#define mfc_get_sei_mastering5()               MFC_READL(MFC_REG_D_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_5)
+#define mfc_get_sei_avail_frame_pack() (MFC_READL(MFC_REG_D_SEI_AVAIL) \
+                                               & MFC_REG_D_SEI_AVAIL_FRAME_PACK_MASK)
+#define mfc_get_sei_avail_content_light()      ((MFC_READL(MFC_REG_D_SEI_AVAIL)        \
+                                               >> MFC_REG_D_SEI_AVAIL_CONTENT_LIGHT_SHIFT)     \
+                                               & MFC_REG_D_SEI_AVAIL_CONTENT_LIGHT_MASK)
+#define mfc_get_sei_avail_mastering_display()  ((MFC_READL(MFC_REG_D_SEI_AVAIL)        \
+                                               >> MFC_REG_D_SEI_AVAIL_MASTERING_DISPLAY_SHIFT) \
+                                               & MFC_REG_D_SEI_AVAIL_MASTERING_DISPLAY_MASK)
+#define mfc_get_video_signal_type()            ((MFC_READL(MFC_REG_D_VIDEO_SIGNAL_TYPE)        \
+                                               >> MFC_REG_D_VIDEO_SIGNAL_TYPE_FLAG_SHIFT)      \
+                                               & MFC_REG_D_VIDEO_SIGNAL_TYPE_FLAG_MASK)
+#define mfc_get_colour_description()   ((MFC_READL(MFC_REG_D_VIDEO_SIGNAL_TYPE)        \
+                                               >> MFC_REG_D_COLOUR_DESCRIPTION_FLAG_SHIFT)     \
+                                               & MFC_REG_D_COLOUR_DESCRIPTION_FLAG_MASK)
+#define mfc_get_black_bar_pos_x()              ((MFC_READL(MFC_REG_D_BLACK_BAR_START_POS)      \
+                                               >> MFC_REG_D_BLACK_BAR_START_X_SHIFT)           \
+                                               & MFC_REG_D_BLACK_BAR_START_X_MASK)
+#define mfc_get_black_bar_pos_y()              ((MFC_READL(MFC_REG_D_BLACK_BAR_START_POS)      \
+                                               >> MFC_REG_D_BLACK_BAR_START_Y_SHIFT)           \
+                                               & MFC_REG_D_BLACK_BAR_START_Y_MASK)
+#define mfc_get_black_bar_image_w()            ((MFC_READL(MFC_REG_D_BLACK_BAR_IMAGE_SIZE)     \
+                                               >> MFC_REG_D_BLACK_BAR_IMAGE_W_SHIFT)   \
+                                               & MFC_REG_D_BLACK_BAR_IMAGE_W_MASK)
+#define mfc_get_black_bar_image_h()            ((MFC_READL(MFC_REG_D_BLACK_BAR_IMAGE_SIZE)     \
+                                               >> MFC_REG_D_BLACK_BAR_IMAGE_H_SHIFT)   \
+                                               & MFC_REG_D_BLACK_BAR_IMAGE_H_MASK)
+#define mfc_get_mvc_disp_view_id()             (MFC_READL(MFC_REG_D_MVC_VIEW_ID)               \
+                                               & MFC_REG_D_MVC_VIEW_ID_DISP_MASK)
+#define mfc_get_profile()                      (MFC_READL(MFC_REG_D_DECODED_PICTURE_PROFILE)   \
+                                               & MFC_REG_D_DECODED_PIC_PROFILE_MASK)
+#define mfc_get_luma_bit_depth_minus8()        ((MFC_READL(MFC_REG_D_DECODED_PICTURE_PROFILE)  \
+                                               >> MFC_REG_D_BIT_DEPTH_LUMA_MINUS8_SHIFT)       \
+                                               & MFC_REG_D_BIT_DEPTH_LUMA_MINUS8_MASK)
+#define mfc_get_chroma_bit_depth_minus8()      ((MFC_READL(MFC_REG_D_DECODED_PICTURE_PROFILE)  \
+                                               >> MFC_REG_D_BIT_DEPTH_CHROMA_MINUS8_SHIFT)     \
+                                               & MFC_REG_D_BIT_DEPTH_CHROMA_MINUS8_MASK)
+#define mfc_get_dec_used_flag()                MFC_READL(MFC_REG_D_USED_DPB_FLAG_LOWER)
+#define mfc_get_enc_nal_done_info()            ((MFC_READL(MFC_REG_E_NAL_DONE_INFO) & (0x3 << 4)) >> 4)
+#define mfc_get_chroma_format()                (MFC_READL(MFC_REG_D_CHROMA_FORMAT)             \
+                                               & MFC_REG_D_CHROMA_FORMAT_MASK)
+#define mfc_get_color_range()          ((MFC_READL(MFC_REG_D_CHROMA_FORMAT)    \
+                                               >> MFC_REG_D_COLOR_RANGE_SHIFT) \
+                                               & MFC_REG_D_COLOR_RANGE_MASK)
+#define mfc_get_color_space()          ((MFC_READL(MFC_REG_D_CHROMA_FORMAT)    \
+                                               >> MFC_REG_D_COLOR_SPACE_SHIFT) \
+                                               & MFC_REG_D_COLOR_SPACE_MASK)
+#define mfc_get_num_of_tile()          ((MFC_READL(MFC_REG_D_DECODED_STATUS)           \
+                                               >> MFC_REG_DEC_STATUS_NUM_OF_TILE_SHIFT)        \
+                                               & MFC_REG_DEC_STATUS_NUM_OF_TILE_MASK)
+
+
+/* nal queue information */
+#define mfc_get_nal_q_input_count()            MFC_READL(MFC_REG_NAL_QUEUE_INPUT_COUNT)
+#define mfc_get_nal_q_output_count()   MFC_READL(MFC_REG_NAL_QUEUE_OUTPUT_COUNT)
+#define mfc_get_nal_q_input_exe_count()        MFC_READL(MFC_REG_NAL_QUEUE_INPUT_EXE_COUNT)
+#define mfc_get_nal_q_info()           MFC_READL(MFC_REG_NAL_QUEUE_INFO)
+#define mfc_get_nal_q_input_addr()             MFC_READL(MFC_REG_NAL_QUEUE_INPUT_ADDR)
+#define mfc_get_nal_q_input_size()             MFC_READL(MFC_REG_NAL_QUEUE_INPUT_SIZE)
+#define mfc_get_nal_q_output_addr()            MFC_READL(MFC_REG_NAL_QUEUE_OUTPUT_ADDR)
+#define mfc_get_nal_q_output_ize()             MFC_READL(MFC_REG_NAL_QUEUE_OUTPUT_SIZE)
+
+static inline void mfc_reset_nal_queue_registers(struct mfc_dev *dev)
+{
+       MFC_WRITEL(0x0, MFC_REG_NAL_QUEUE_INPUT_COUNT);
+       MFC_WRITEL(0x0, MFC_REG_NAL_QUEUE_OUTPUT_COUNT);
+       MFC_WRITEL(0x0, MFC_REG_NAL_QUEUE_INPUT_EXE_COUNT);
+       MFC_WRITEL(0x0, MFC_REG_NAL_QUEUE_INFO);
+}
+
+static inline void mfc_update_nal_queue_input(struct mfc_dev *dev,
+       dma_addr_t addr, unsigned int size)
+{
+       MFC_WRITEL(addr, MFC_REG_NAL_QUEUE_INPUT_ADDR);
+       MFC_WRITEL(size, MFC_REG_NAL_QUEUE_INPUT_SIZE);
+}
+
+static inline void mfc_update_nal_queue_output(struct mfc_dev *dev,
+       dma_addr_t addr, unsigned int size)
+{
+       MFC_WRITEL(addr, MFC_REG_NAL_QUEUE_OUTPUT_ADDR);
+       MFC_WRITEL(size, MFC_REG_NAL_QUEUE_OUTPUT_SIZE);
+}
+
+static inline void mfc_update_nal_queue_input_count(struct mfc_dev *dev,
+       unsigned int input_count)
+{
+       MFC_WRITEL(input_count, MFC_REG_NAL_QUEUE_INPUT_COUNT);
+}
+
+static inline void mfc_dec_store_crop_info(struct mfc_ctx *ctx)
+{
+       struct mfc_dev *dev = ctx->dev;
+       struct mfc_dec *dec = ctx->dec_priv;
+       u32 left, right, top, bottom;
+
+       left = MFC_READL(MFC_REG_D_DISPLAY_CROP_INFO1);
+       right = left >> MFC_REG_D_SHARED_CROP_RIGHT_SHIFT;
+       left = left & MFC_REG_D_SHARED_CROP_LEFT_MASK;
+       top = MFC_READL(MFC_REG_D_DISPLAY_CROP_INFO2);
+       bottom = top >> MFC_REG_D_SHARED_CROP_BOTTOM_SHIFT;
+       top = top & MFC_REG_D_SHARED_CROP_TOP_MASK;
+
+       dec->cr_left = left;
+       dec->cr_right = right;
+       dec->cr_top = top;
+       dec->cr_bot = bottom;
+}
+
+static inline void mfc_clear_enc_res_change(struct mfc_dev *dev)
+{
+       unsigned int reg = 0;
+
+       reg = MFC_READL(MFC_REG_E_PARAM_CHANGE);
+       reg &= ~(0x7 << 6);
+       MFC_WRITEL(reg, MFC_REG_E_PARAM_CHANGE);
+}
+
+static inline void mfc_clear_roi_enable(struct mfc_dev *dev)
+{
+       unsigned int reg = 0;
+
+       reg = MFC_READL(MFC_REG_E_RC_ROI_CTRL);
+       reg &= ~(0x1);
+       MFC_WRITEL(reg, MFC_REG_E_RC_ROI_CTRL);
+}
+
+void mfc_dbg_enable(struct mfc_dev *dev);
+void mfc_dbg_disable(struct mfc_dev *dev);
+void mfc_dbg_set_addr(struct mfc_dev *dev);
+
+void mfc_otf_set_frame_addr(struct mfc_ctx *ctx, int num_planes);
+void mfc_otf_set_stream_size(struct mfc_ctx *ctx, unsigned int size);
+void mfc_otf_set_hwfc_index(struct mfc_ctx *ctx, int job_id);
+
+int mfc_set_dec_codec_buffers(struct mfc_ctx *ctx);
+int mfc_set_enc_codec_buffers(struct mfc_ctx *mfc_ctx);
+
+int mfc_set_dec_stream_buffer(struct mfc_ctx *ctx,
+               struct mfc_buf *mfc_buf,
+               unsigned int start_num_byte,
+               unsigned int buf_size);
+
+void mfc_set_enc_frame_buffer(struct mfc_ctx *ctx,
+               struct mfc_buf *mfc_buf, int num_planes);
+int mfc_set_enc_stream_buffer(struct mfc_ctx *ctx,
+               struct mfc_buf *mfc_buf);
+
+void mfc_get_enc_frame_buffer(struct mfc_ctx *ctx,
+               dma_addr_t addr[], int num_planes);
+void mfc_set_enc_stride(struct mfc_ctx *ctx);
+
+int mfc_set_dynamic_dpb(struct mfc_ctx *ctx, struct mfc_buf *dst_vb);
+
+void mfc_set_pixel_format(struct mfc_dev *dev, unsigned int format);
+
+#endif /* __MFC_REG_API_H */
diff --git a/drivers/media/platform/exynos/mfc/mfc_regs.h b/drivers/media/platform/exynos/mfc/mfc_regs.h
new file mode 100644 (file)
index 0000000..ee569f4
--- /dev/null
@@ -0,0 +1,743 @@
+/*
+ * drivers/media/platform/exynos/mfc/mfc_regs.h
+ *
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __MFC_REGS_H
+#define __MFC_REGS_H __FILE__
+
+#define MFC_MMU_INTERRUPT_STATUS                               0x0060
+#define MFC_MMU_FAULT_TRANS_INFO                               0x0078
+#define MFC_MMU_FAULT_TRANS_INFO_RW_MASK                       0x100000
+#define MFC_MMU_FAULT_TRANS_INFO_AXID_MASK                     0xFFFF
+
+#define HWFC_ENCODING_IDX                                      0x4
+
+/* Codec Common Registers */
+#define MFC_REG_RISC_ON                                        0x0000
+#define MFC_REG_RISC2HOST_INT                                  0x003C
+#define MFC_REG_HOST2RISC_INT                                  0x0044
+#define MFC_REG_RISC_BASE_ADDRESS                              0x0054
+
+#define MFC_REG_MFC_FW_CLOCK                                   0x1060
+#define MFC_REG_MFC_RESET                                      0x1070
+
+#define MFC_REG_HOST2RISC_CMD                                  0x1100
+#define MFC_REG_RISC2HOST_CMD                                  0x1104
+
+#define MFC_REG_MFC_BUS_STATUS                                 0x7018
+#define MFC_REG_MFC_RPEND                                      0x7028
+#define MFC_REG_MFC_WPEND                                      0x702C
+#define MFC_REG_MFC_BUS_RESET_CTRL                             0x7110
+#define MFC_REG_MFC_OFF                                        0x7120
+#define MFC_REG_MFC_STATE                                      0x7124
+
+#define MFC_REG_FW_VERSION                                     0xF000
+#define MFC_REG_INSTANCE_ID                                    0xF008
+#define MFC_REG_CODEC_TYPE                                     0xF00C
+#define MFC_REG_CONTEXT_MEM_ADDR                               0xF014
+#define MFC_REG_CONTEXT_MEM_SIZE                               0xF018
+#define MFC_REG_SHARED_MEM_ADDR                                0xF01C
+#define MFC_REG_PIXEL_FORMAT                                   0xF020
+
+#define MFC_REG_METADATA_ENABLE                                0xF024
+#define MFC_REG_MFC_VERSION                                    0xF028
+#define MFC_REG_DBG_INFO_ENABLE                                0xF02C
+#define MFC_REG_DBG_BUFFER_ADDR                                0xF030
+#define MFC_REG_DBG_BUFFER_SIZE                                0xF034
+
+#define MFC_REG_CODEC_CONTROL                                  0xF038
+#define MFC_REG_DEC_TIMEOUT_VALUE                              0xF03C
+#define MFC_REG_HED_SHARED_MEM_ADDR                            0xF040
+
+/* NAL QUEUE */
+#define MFC_REG_NAL_QUEUE_INPUT_ADDR                           0xF044
+#define MFC_REG_NAL_QUEUE_INPUT_SIZE                           0xF048
+#define MFC_REG_NAL_QUEUE_OUTPUT_ADDR                          0xF04C
+#define MFC_REG_NAL_QUEUE_OUTPUT_SIZE                          0xF050
+#define MFC_REG_NAL_QUEUE_INPUT_COUNT                          0xF054
+
+#define MFC_REG_RET_INSTANCE_ID                                0xF070
+#define MFC_REG_ERROR_CODE                                     0xF074
+#define MFC_REG_DBG_BUFFER_OUTPUT_SIZE                         0xF078
+#define MFC_REG_METADATA_STATUS                                0xF07C
+
+#define MFC_REG_DBG_INFO_STAGE_COUNTER                         0xF088
+
+/* NAL QUEUE */
+#define MFC_REG_NAL_QUEUE_OUTPUT_COUNT                         0xF08C
+#define MFC_REG_NAL_QUEUE_INPUT_EXE_COUNT                      0xF090
+#define MFC_REG_NAL_QUEUE_INFO                                 0xF094
+
+/* Decoder Registers */
+#define MFC_REG_D_CRC_CTRL                                     0xF0B0
+#define MFC_REG_D_DEC_OPTIONS                                  0xF0B4
+
+#define MFC_REG_D_DISPLAY_DELAY                                0xF0B8
+
+#define MFC_REG_D_SET_FRAME_WIDTH                              0xF0BC
+#define MFC_REG_D_SET_FRAME_HEIGHT                             0xF0C0
+
+#define MFC_REG_D_SEI_ENABLE                                   0xF0C4
+
+#define MFC_REG_D_FORCE_PIXEL_VAL                              0xF0C8
+
+/* Buffer setting registers */
+/* Session return */
+#define MFC_REG_D_MIN_NUM_DPB                                  0xF0F0
+#define MFC_REG_D_MIN_FIRST_PLANE_DPB_SIZE                     0xF0F4
+#define MFC_REG_D_MIN_SECOND_PLANE_DPB_SIZE                    0xF0F8
+#define MFC_REG_D_MIN_THIRD_PLANE_DPB_SIZE                     0xF0FC
+#define MFC_REG_D_MIN_NUM_MV                                   0xF100
+#define MFC_REG_D_MVC_NUM_VIEWS                                0xF104
+#define MFC_REG_D_MIN_SCRATCH_BUFFER_SIZE                      0xF108
+#define MFC_REG_D_MIN_FIRST_PLANE_2BIT_DPB_SIZE                0xF10C
+#define MFC_REG_D_MIN_SECOND_PLANE_2BIT_DPB_SIZE               0xF110
+#define MFC_REG_D_POST_FILTER_LUMA_DPB0                        0xF120
+#define MFC_REG_D_POST_FILTER_LUMA_DPB1                        0xF124
+#define MFC_REG_D_POST_FILTER_CHROMA_DPB0                      0xF128
+#define MFC_REG_D_POST_FILTER_CHROMA_DPB1                      0xF12C
+
+/* Buffers */
+#define MFC_REG_D_NUM_DPB                                      0xF130
+#define MFC_REG_D_NUM_MV                                       0xF134
+#define MFC_REG_D_FIRST_PLANE_DPB_STRIDE_SIZE                  0xF138
+#define MFC_REG_D_SECOND_PLANE_DPB_STRIDE_SIZE                 0xF13C
+#define MFC_REG_D_THIRD_PLANE_DPB_STRIDE_SIZE                  0xF140
+#define MFC_REG_D_FIRST_PLANE_DPB_SIZE                         0xF144
+#define MFC_REG_D_SECOND_PLANE_DPB_SIZE                        0xF148
+#define MFC_REG_D_THIRD_PLANE_DPB_SIZE                         0xF14C
+#define MFC_REG_D_MV_BUFFER_SIZE                               0xF150
+#define MFC_REG_D_INIT_BUFFER_OPTIONS                          0xF154
+#define MFC_REG_D_FIRST_PLANE_DPB0                             0xF160
+#define MFC_REG_D_SECOND_PLANE_DPB0                            0xF260
+#define MFC_REG_D_THIRD_PLANE_DPB0                             0xF360
+#define MFC_REG_D_MV_BUFFER0                                   0xF460
+#define MFC_REG_D_SCRATCH_BUFFER_ADDR                          0xF560
+#define MFC_REG_D_SCRATCH_BUFFER_SIZE                          0xF564
+#define MFC_REG_D_METADATA_BUFFER_ADDR                         0xF568
+#define MFC_REG_D_METADATA_BUFFER_SIZE                         0xF56C
+
+#define MFC_REG_D_STATIC_BUFFER_ADDR                           0xF570
+#define MFC_REG_D_STATIC_BUFFER_SIZE                           0xF574
+#define MFC_REG_D_FIRST_PLANE_2BIT_DPB_SIZE                    0xF578
+#define MFC_REG_D_SECOND_PLANE_2BIT_DPB_SIZE                   0xF57C
+#define MFC_REG_D_FIRST_PLANE_2BIT_DPB_STRIDE_SIZE             0xF580
+#define MFC_REG_D_SECOND_PLANE_2BIT_DPB_STRIDE_SIZE            0xF584
+
+#define MFC_REG_D_NAL_START_OPTIONS                            0xF5AC
+
+/* Nal cmd */
+#define MFC_REG_D_CPB_BUFFER_ADDR                              0xF5B0
+#define MFC_REG_D_CPB_BUFFER_SIZE                              0xF5B4
+#define MFC_REG_D_AVAILABLE_DPB_FLAG_UPPER                     0xF5B8
+#define MFC_REG_D_AVAILABLE_DPB_FLAG_LOWER                     0xF5BC
+#define MFC_REG_D_CPB_BUFFER_OFFSET                            0xF5C0
+#define MFC_REG_D_SLICE_IF_ENABLE                              0xF5C4
+#define MFC_REG_D_PICTURE_TAG                                  0xF5C8
+#define MFC_REG_D_STREAM_DATA_SIZE                             0xF5D0
+#define MFC_REG_D_DYNAMIC_DPB_FLAG_UPPER                       0xF5D4
+#define MFC_REG_D_DYNAMIC_DPB_FLAG_LOWER                       0xF5D8
+
+/* Nal return */
+#define MFC_REG_D_DISPLAY_FRAME_WIDTH                          0xF600
+#define MFC_REG_D_DISPLAY_FRAME_HEIGHT                         0xF604
+#define MFC_REG_D_DISPLAY_STATUS                               0xF608
+#define MFC_REG_D_DISPLAY_FIRST_PLANE_ADDR                     0xF60C
+#define MFC_REG_D_DISPLAY_SECOND_PLANE_ADDR                    0xF610
+#define MFC_REG_D_DISPLAY_THIRD_PLANE_ADDR                     0xF614
+#define MFC_REG_D_DISPLAY_FRAME_TYPE                           0xF618
+#define MFC_REG_D_DISPLAY_CROP_INFO1                           0xF61C
+#define MFC_REG_D_DISPLAY_CROP_INFO2                           0xF620
+#define MFC_REG_D_DISPLAY_PICTURE_PROFILE                      0xF624
+#define MFC_REG_D_DISPLAY_FIRST_PLANE_CRC                      0xF628
+#define MFC_REG_D_DISPLAY_SECOND_PLANE_CRC                     0xF62C
+#define MFC_REG_D_DISPLAY_THIRD_PLANE_CRC                      0xF630
+#define MFC_REG_D_DISPLAY_ASPECT_RATIO                         0xF634
+#define MFC_REG_D_DISPLAY_EXTENDED_AR                          0xF638
+#define MFC_REG_D_DECODED_FRAME_WIDTH                          0xF63C
+#define MFC_REG_D_DECODED_FRAME_HEIGHT                         0xF640
+#define MFC_REG_D_DECODED_STATUS                               0xF644
+#define MFC_REG_D_DECODED_FIRST_PLANE_ADDR                     0xF648
+#define MFC_REG_D_DECODED_SECOND_PLANE_ADDR                    0xF64C
+#define MFC_REG_D_DECODED_THIRD_PLANE_ADDR                     0xF650
+#define MFC_REG_D_DECODED_FRAME_TYPE                           0xF654
+#define MFC_REG_D_DECODED_CROP_INFO1                           0xF658
+#define MFC_REG_D_DECODED_CROP_INFO2                           0xF65C
+#define MFC_REG_D_DECODED_PICTURE_PROFILE                      0xF660
+#define MFC_REG_D_DECODED_NAL_SIZE                             0xF664
+#define MFC_REG_D_DECODED_FIRST_PLANE_CRC                      0xF668
+#define MFC_REG_D_DECODED_SECOND_PLANE_CRC                     0xF66C
+#define MFC_REG_D_DECODED_THIRD_PLANE_CRC                      0xF670
+#define MFC_REG_D_RET_PICTURE_TAG_TOP                          0xF674
+#define MFC_REG_D_RET_PICTURE_TAG_BOT                          0xF678
+#define MFC_REG_D_RET_PICTURE_TIME_TOP                         0xF67C
+#define MFC_REG_D_RET_PICTURE_TIME_BOT                         0xF680
+#define MFC_REG_D_CHROMA_FORMAT                                0xF684
+
+#define MFC_REG_D_VC1_INFO                                     0xF688
+#define MFC_REG_D_MPEG4_INFO                                   0xF68C
+#define MFC_REG_D_H264_INFO                                    0xF690
+#define MFC_REG_D_HEVC_INFO                                    0xF6A0
+#define MFC_REG_D_BPG_INFO                                     0xF6A8
+
+#define MFC_REG_D_METADATA_ADDR_CONCEALED_MB                   0xF6B0
+#define MFC_REG_D_METADATA_SIZE_CONCEALED_MB                   0xF6B4
+#define MFC_REG_D_METADATA_ADDR_VC1_PARAM                      0xF6B8
+#define MFC_REG_D_METADATA_SIZE_VC1_PARAM                      0xF6BC
+#define MFC_REG_D_METADATA_ADDR_SEI_NAL                        0xF6C0
+#define MFC_REG_D_METADATA_SIZE_SEI_NAL                        0xF6C4
+#define MFC_REG_D_METADATA_ADDR_VUI                            0xF6C8
+#define MFC_REG_D_METADATA_SIZE_VUI                            0xF6CC
+#define MFC_REG_D_METADATA_ADDR_MVCVUI                         0xF6D0
+#define MFC_REG_D_METADATA_SIZE_MVCVUI                         0xF6D4
+
+#define MFC_REG_D_MVC_VIEW_ID                                  0xF6D8
+
+#define MFC_REG_D_SEI_AVAIL                                    0xF6DC
+#define MFC_REG_D_FRAME_PACK_ARRGMENT_ID                       0xF6E0
+#define MFC_REG_D_FRAME_PACK_SEI_INFO                          0xF6E4
+#define MFC_REG_D_FRAME_PACK_GRID_POS                          0xF6E8
+
+#define MFC_REG_D_DISPLAY_RECOVERY_SEI_INFO                    0xF6EC
+#define MFC_REG_D_DECODED_RECOVERY_SEI_INFO                    0xF6F0
+
+#define MFC_REG_D_DISPLAY_FIRST_PLANE_2BIT_CRC                 0xF6FC
+#define MFC_REG_D_DISPLAY_SECOND_PLANE_2BIT_CRC                0xF700
+#define MFC_REG_D_DECODED_FIRST_PLANE_2BIT_CRC                 0xF704
+#define MFC_REG_D_DECODED_SECOND_PLANE_2BIT_CRC                0xF708
+
+#define MFC_REG_D_VIDEO_SIGNAL_TYPE                            0xF70C
+#define MFC_REG_D_CONTENT_LIGHT_LEVEL_INFO_SEI                 0xF710
+#define MFC_REG_D_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_0        0xF714
+#define MFC_REG_D_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_1        0xF718
+
+#define MFC_REG_D_USED_DPB_FLAG_UPPER                          0xF720
+#define MFC_REG_D_USED_DPB_FLAG_LOWER                          0xF724
+
+#define MFC_REG_D_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_2        0xF728
+#define MFC_REG_D_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_3        0xF72C
+#define MFC_REG_D_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_4        0xF730
+#define MFC_REG_D_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_5        0xF734
+
+#define MFC_REG_D_BLACK_BAR_START_POS                          0xF738
+#define MFC_REG_D_BLACK_BAR_IMAGE_SIZE                         0xF73C
+
+#define MFC_REG_D_DISPLAY_LUMA_ADDR                            0xF60C
+#define MFC_REG_D_DISPLAY_CHROMA_ADDR                          0xF610
+
+#define MFC_REG_D_DECODED_LUMA_ADDR                            0xF648
+#define MFC_REG_D_DECODED_CHROMA_ADDR                          0xF64C
+
+/* Encoder Registers */
+#define MFC_REG_E_CROPPED_FRAME_WIDTH                          0xF778
+#define MFC_REG_E_CROPPED_FRAME_HEIGHT                         0xF77C
+#define MFC_REG_E_FRAME_CROP_OFFSET                            0xF780
+#define MFC_REG_E_ENC_OPTIONS                                  0xF784
+#define MFC_REG_E_PICTURE_PROFILE                              0xF788
+#define MFC_REG_E_VBV_BUFFER_SIZE                              0xF78C
+#define MFC_REG_E_VBV_INIT_DELAY                               0xF790
+#define MFC_REG_E_FIXED_PICTURE_QP                             0xF794
+#define MFC_REG_E_RC_CONFIG                                    0xF798
+#define MFC_REG_E_RC_QP_BOUND                                  0xF79C
+#define MFC_REG_E_RC_QP_BOUND_PB                               0xF7A0
+#define MFC_REG_E_RC_MODE                                      0xF7A4
+
+#define MFC_REG_E_MB_RC_CONFIG                                 0xF7A8
+#define MFC_REG_E_PADDING_CTRL                                 0xF7AC
+#define MFC_REG_E_AIR_THRESHOLD                                0xF7B0
+
+#define MFC_REG_E_MV_HOR_RANGE                                 0xF7B4
+#define MFC_REG_E_MV_VER_RANGE                                 0xF7B8
+
+#define MFC_REG_E_HIGH_QUALITY_MODE                            0xF7C0
+#define MFC_REG_E_VIDEO_SIGNAL_TYPE                            0xF7C4
+
+#define MFC_REG_E_SAO_WEIGHT0                                  0xF7C8
+#define MFC_REG_E_SAO_WEIGHT1                                  0xF7CC
+
+#define MFC_REG_E_NUM_DPB                                      0xF890
+#define MFC_REG_E_MIN_SCRATCH_BUFFER_SIZE                      0xF894
+
+#define MFC_REG_E_LUMA_DPB                                     0xF8C0
+#define MFC_REG_E_CHROMA_DPB                                   0xF904
+#define MFC_REG_E_ME_BUFFER                                    0xF948
+
+#define MFC_REG_E_SCRATCH_BUFFER_ADDR                          0xF98C
+#define MFC_REG_E_SCRATCH_BUFFER_SIZE                          0xF990
+#define MFC_REG_E_TMV_BUFFER0                                  0xF994
+#define MFC_REG_E_TMV_BUFFER1                                  0xF998
+#define MFC_REG_E_IR_BUFFER_ADDR                               0xF99C
+#define MFC_REG_E_SOURCE_FIRST_2BIT_ADDR                       0xF9D0
+#define MFC_REG_E_SOURCE_SECOND_2BIT_ADDR                      0xF9D4
+#define MFC_REG_E_SOURCE_FIRST_2BIT_STRIDE                     0xF9D8
+#define MFC_REG_E_SOURCE_SECOND_2BIT_STRIDE                    0xF9DC
+#define MFC_REG_E_SOURCE_FIRST_ADDR                            0xF9E0
+#define MFC_REG_E_SOURCE_SECOND_ADDR                           0xF9E4
+#define MFC_REG_E_SOURCE_THIRD_ADDR                            0xF9E8
+#define MFC_REG_E_SOURCE_FIRST_STRIDE                          0xF9EC
+#define MFC_REG_E_SOURCE_SECOND_STRIDE                         0xF9F0
+#define MFC_REG_E_SOURCE_THIRD_STRIDE                          0xF9F4
+#define MFC_REG_E_STREAM_BUFFER_ADDR                           0xF9F8
+#define MFC_REG_E_STREAM_BUFFER_SIZE                           0xF9FC
+#define MFC_REG_E_ROI_BUFFER_ADDR                              0xFA00
+
+#define MFC_REG_E_PARAM_CHANGE                                 0xFA04
+#define MFC_REG_E_IR_SIZE                                      0xFA08
+#define MFC_REG_E_GOP_CONFIG                                   0xFA0C
+#define MFC_REG_E_MSLICE_MODE                                  0xFA10
+#define MFC_REG_E_MSLICE_SIZE_MB                               0xFA14
+#define MFC_REG_E_MSLICE_SIZE_BITS                             0xFA18
+#define MFC_REG_E_FRAME_INSERTION                              0xFA1C
+
+#define MFC_REG_E_RC_FRAME_RATE                                0xFA20
+#define MFC_REG_E_RC_BIT_RATE                                  0xFA24
+#define MFC_REG_E_RC_ROI_CTRL                                  0xFA2C
+#define MFC_REG_E_PICTURE_TAG                                  0xFA30
+#define MFC_REG_E_BIT_COUNT_ENABLE                             0xFA34
+#define MFC_REG_E_MAX_BIT_COUNT                                0xFA38
+#define MFC_REG_E_MIN_BIT_COUNT                                0xFA3C
+
+#define MFC_REG_E_METADATA_BUFFER_ADDR                         0xFA40
+#define MFC_REG_E_METADATA_BUFFER_SIZE                         0xFA44
+
+#define MFC_REG_E_ENCODING_ORDER_TIME_INFO                     0xFA50
+#define MFC_REG_E_ENCODING_ORDER_INFO                          0xFA54
+#define MFC_REG_E_STREAM_BUFFER_OFFSET                         0xFA58
+#define MFC_REG_E_GOP_CONFIG2                                  0xFA5C
+#define MFC_REG_E_WEIGHT_FOR_WEIGHTED_PREDICTION               0xFA60
+
+#define MFC_REG_E_ENCODED_SOURCE_FIRST_ADDR                    0xFA70
+#define MFC_REG_E_ENCODED_SOURCE_SECOND_ADDR                   0xFA74
+#define MFC_REG_E_ENCODED_SOURCE_THIRD_ADDR                    0xFA78
+
+#define MFC_REG_E_STREAM_SIZE                                  0xFA80
+#define MFC_REG_E_SLICE_TYPE                                   0xFA84
+#define MFC_REG_E_PICTURE_COUNT                                0xFA88
+#define MFC_REG_E_RET_PICTURE_TAG                              0xFA8C
+
+#define MFC_REG_E_RECON_LUMA_DPB_ADDR                          0xFA9C
+#define MFC_REG_E_RECON_CHROMA_DPB_ADDR                        0xFAA0
+#define MFC_REG_E_METADATA_ADDR_ENC_SLICE                      0xFAA4
+#define MFC_REG_E_METADATA_SIZE_ENC_SLICE                      0xFAA8
+
+#define MFC_REG_E_NAL_DONE_INFO                                0xFAEC
+
+#define MFC_REG_E_MPEG4_OPTIONS                                0xFB10
+#define MFC_REG_E_MPEG4_HEC_PERIOD                             0xFB14
+
+#define MFC_REG_E_BPG_OPTIONS                                  0xFB1C
+#define MFC_REG_E_BPG_EXT_CTB_QP_CTRL                          0xFB20
+#define MFC_REG_E_BPG_CHROMA_QP_OFFSET                         0xFB24
+#define MFC_REG_E_BPG_EXTENSION_DATA_SIZE                      0xFB28
+
+#define MFC_REG_E_H264_HD_SVC_EXTENSION_0                      0xFB44
+#define MFC_REG_E_H264_HD_SVC_EXTENSION_1                      0xFB48
+#define MFC_REG_E_ASPECT_RATIO                                 0xFB4C
+#define MFC_REG_E_EXTENDED_SAR                                 0xFB50
+
+#define MFC_REG_E_H264_OPTIONS                                 0xFB54
+#define MFC_REG_E_H264_OPTIONS_2                               0xFB58
+#define MFC_REG_E_H264_LF_ALPHA_OFFSET                         0xFB5C
+#define MFC_REG_E_H264_LF_BETA_OFFSET                          0xFB60
+#define MFC_REG_E_H264_REFRESH_PERIOD                          0xFB64
+
+#define MFC_REG_E_H264_FMO_SLICE_GRP_MAP_TYPE                  0xFB68
+#define MFC_REG_E_H264_FMO_NUM_SLICE_GRP_MINUS1                0xFB6C
+#define MFC_REG_E_H264_FMO_SLICE_GRP_CHANGE_DIR                0xFB70
+#define MFC_REG_E_H264_FMO_SLICE_GRP_CHANGE_RATE_MINUS1        0xFB74
+#define MFC_REG_E_H264_FMO_RUN_LENGTH_MINUS1_0                 0xFB78
+#define MFC_REG_E_H264_FMO_RUN_LENGTH_MINUS1_1                 0xFB7C
+#define MFC_REG_E_H264_FMO_RUN_LENGTH_MINUS1_2                 0xFB80
+#define MFC_REG_E_H264_FMO_RUN_LENGTH_MINUS1_3                 0xFB84
+
+#define MFC_REG_E_H264_ASO_SLICE_ORDER_0                       0xFB88
+#define MFC_REG_E_H264_ASO_SLICE_ORDER_1                       0xFB8C
+#define MFC_REG_E_H264_ASO_SLICE_ORDER_2                       0xFB90
+#define MFC_REG_E_H264_ASO_SLICE_ORDER_3                       0xFB94
+#define MFC_REG_E_H264_ASO_SLICE_ORDER_4                       0xFB98
+#define MFC_REG_E_H264_ASO_SLICE_ORDER_5                       0xFB9C
+#define MFC_REG_E_H264_ASO_SLICE_ORDER_6                       0xFBA0
+#define MFC_REG_E_H264_ASO_SLICE_ORDER_7                       0xFBA4
+#define MFC_REG_E_H264_CHROMA_QP_OFFSET                        0xFBA8
+
+#define MFC_REG_E_NUM_T_LAYER                                  0xFBAC
+#define MFC_REG_E_HIERARCHICAL_QP_LAYER0                       0xFBB0
+#define MFC_REG_E_HIERARCHICAL_QP_LAYER1                       0xFBB4
+#define MFC_REG_E_HIERARCHICAL_QP_LAYER2                       0xFBB8
+#define MFC_REG_E_HIERARCHICAL_QP_LAYER3                       0xFBBC
+#define MFC_REG_E_HIERARCHICAL_QP_LAYER4                       0xFBC0
+#define MFC_REG_E_HIERARCHICAL_QP_LAYER5                       0xFBC4
+#define MFC_REG_E_HIERARCHICAL_QP_LAYER6                       0xFBC8
+
+/* For backward compatibility */
+#define MFC_REG_E_H264_FRAME_PACKING_SEI_INFO                  0xFC4C
+
+#define MFC_REG_E_H264_NAL_CONTROL                             0xFD14
+#define MFC_REG_E_HIERARCHICAL_BIT_RATE_LAYER0                 0xFD18
+#define MFC_REG_E_HIERARCHICAL_BIT_RATE_LAYER1                 0xFD1C
+#define MFC_REG_E_HIERARCHICAL_BIT_RATE_LAYER2                 0xFD20
+#define MFC_REG_E_HIERARCHICAL_BIT_RATE_LAYER3                 0xFD24
+#define MFC_REG_E_HIERARCHICAL_BIT_RATE_LAYER4                 0xFD28
+#define MFC_REG_E_HIERARCHICAL_BIT_RATE_LAYER5                 0xFD2C
+#define MFC_REG_E_HIERARCHICAL_BIT_RATE_LAYER6                 0xFD30
+
+#define MFC_REG_E_MVC_FRAME_QP_VIEW1                           0xFD40
+#define MFC_REG_E_MVC_RC_FRAME_RATE_VIEW1                      0xFD44
+#define MFC_REG_E_MVC_RC_BIT_RATE_VIEW1                        0xFD48
+#define MFC_REG_E_MVC_RC_QBOUND_VIEW1                          0xFD4C
+#define MFC_REG_E_MVC_RC_MODE_VIEW1                            0xFD50
+#define MFC_REG_E_MVC_INTER_VIEW_PREDICTION_ON                 0xFD80
+
+#define MFC_REG_E_VP9_OPTION                                   0xFD90
+#define MFC_REG_E_VP9_FILTER_OPTION                            0xFD94
+#define MFC_REG_E_VP9_GOLDEN_FRAME_OPTION                      0xFD98
+#define MFC_REG_E_VP8_OPTION                                   0xFDB0
+#define MFC_REG_E_VP8_FILTER_OPTION                            0xFDB4
+#define MFC_REG_E_VP8_GOLDEN_FRAME_OPTION                      0xFDB8
+
+#define MFC_REG_E_HEVC_OPTIONS_2                               0xFDC4
+
+#define MFC_REG_E_HEVC_OPTIONS                                 0xFDD4
+#define MFC_REG_E_HEVC_REFRESH_PERIOD                          0xFDD8
+#define MFC_REG_E_HEVC_CHROMA_QP_OFFSET                        0xFDDC
+#define MFC_REG_E_HEVC_LF_BETA_OFFSET_DIV2                     0xFDE0
+#define MFC_REG_E_HEVC_LF_TC_OFFSET_DIV2                       0xFDE4
+#define MFC_REG_E_HEVC_NAL_CONTROL                             0xFDE8
+
+#define MFC_REG_E_VP8_NAL_CONTROL                              0xFDF0
+#define MFC_REG_E_VP9_NAL_CONTROL                              0xFDF4
+#define MFC_REG_E_CONTENT_LIGHT_LEVEL_INFO_SEI                 0xFDF8
+#define MFC_REG_E_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_0        0xFDFC
+#define MFC_REG_E_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_1        0xFE00
+#define MFC_REG_E_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_2        0xFE04
+#define MFC_REG_E_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_3        0xFE08
+#define MFC_REG_E_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_4        0xFE0C
+#define MFC_REG_E_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_5        0xFE10
+
+
+#define MFC_REG_REG_CLEAR_BEGIN                        0xf000
+#define MFC_REG_REG_CLEAR_COUNT                        1024
+
+
+/* Bit Definitions */
+/* 0x1100: MFC_REG_HOST2RISC_CMD */
+#define MFC_REG_H2R_CMD_EMPTY                          0
+#define MFC_REG_H2R_CMD_SYS_INIT                       1
+#define MFC_REG_H2R_CMD_OPEN_INSTANCE                  2
+#define MFC_REG_H2R_CMD_SEQ_HEADER                     3
+#define MFC_REG_H2R_CMD_INIT_BUFFERS                   4
+#define MFC_REG_H2R_CMD_NAL_START                      5
+#define MFC_REG_H2R_CMD_CLOSE_INSTANCE                 6
+#define MFC_REG_H2R_CMD_SLEEP                          7
+#define MFC_REG_H2R_CMD_WAKEUP                         8
+#define MFC_REG_H2R_CMD_LAST_FRAME                     9
+#define MFC_REG_H2R_CMD_DPB_FLUSH                      10
+#define MFC_REG_H2R_CMD_NAL_ABORT                      11
+#define MFC_REG_H2R_CMD_CACHE_FLUSH                    12
+#define MFC_REG_H2R_CMD_NAL_QUEUE                      13
+#define MFC_REG_H2R_CMD_STOP_QUEUE                     14
+
+
+/* 0x1104: MFC_REG_RISC2HOST_CMD */
+#define MFC_REG_RISC2HOST_CMD_MASK                     0x1FFFF
+#define MFC_REG_R2H_CMD_EMPTY                          0
+#define MFC_REG_R2H_CMD_SYS_INIT_RET                   1
+#define MFC_REG_R2H_CMD_OPEN_INSTANCE_RET              2
+#define MFC_REG_R2H_CMD_SEQ_DONE_RET                   3
+#define MFC_REG_R2H_CMD_INIT_BUFFERS_RET               4
+#define MFC_REG_R2H_CMD_CLOSE_INSTANCE_RET             6
+#define MFC_REG_R2H_CMD_SLEEP_RET                      7
+#define MFC_REG_R2H_CMD_WAKEUP_RET                     8
+#define MFC_REG_R2H_CMD_COMPLETE_SEQ_RET               9
+#define MFC_REG_R2H_CMD_DPB_FLUSH_RET                  10
+#define MFC_REG_R2H_CMD_NAL_ABORT_RET                  11
+#define MFC_REG_R2H_CMD_FW_STATUS_RET                  12
+#define MFC_REG_R2H_CMD_FRAME_DONE_RET                 13
+#define MFC_REG_R2H_CMD_FIELD_DONE_RET                 14
+#define MFC_REG_R2H_CMD_SLICE_DONE_RET                 15
+#define MFC_REG_R2H_CMD_ENC_BUFFER_FULL_RET            16
+#define MFC_REG_R2H_CMD_QUEUE_DONE_RET                 17
+#define MFC_REG_R2H_CMD_COMPLETE_QUEUE_RET             18
+#define MFC_REG_R2H_CMD_CACHE_FLUSH_RET                20
+#define MFC_REG_R2H_CMD_ERR_RET                        32
+
+
+/* 0xF000: MFC_REG_FW_VERSION */
+#define MFC_REG_FW_VER_INFO_MASK                       0xFF
+#define MFC_REG_FW_VER_INFO_SHFT                       24
+#define MFC_REG_FW_VER_YEAR_MASK                       0xFF
+#define MFC_REG_FW_VER_YEAR_SHFT                       16
+#define MFC_REG_FW_VER_MONTH_MASK                      0xFF
+#define MFC_REG_FW_VER_MONTH_SHFT                      8
+#define MFC_REG_FW_VER_DATE_MASK                       0xFF
+#define MFC_REG_FW_VER_DATE_SHFT                       0
+#define MFC_REG_FW_VER_ALL_MASK                        0xFFFFFF
+#define MFC_REG_FW_VER_ALL_SHFT                        0
+
+
+/* 0xF00C: MFC_REG_CODEC_TYPE */
+#define MFC_FORMATS_NO_CODEC                           -1
+/* Decoder */
+#define MFC_REG_CODEC_H264_DEC                         0
+#define MFC_REG_CODEC_H264_MVC_DEC                     1
+#define MFC_REG_CODEC_MPEG4_DEC                        3
+#define MFC_REG_CODEC_FIMV1_DEC                        4
+#define MFC_REG_CODEC_FIMV2_DEC                        5
+#define MFC_REG_CODEC_FIMV3_DEC                        6
+#define MFC_REG_CODEC_FIMV4_DEC                        7
+#define MFC_REG_CODEC_H263_DEC                         8
+#define MFC_REG_CODEC_VC1_RCV_DEC                      9
+#define MFC_REG_CODEC_VC1_DEC                          10
+#define MFC_REG_CODEC_MPEG2_DEC                        13
+#define MFC_REG_CODEC_VP8_DEC                          14
+#define MFC_REG_CODEC_HEVC_DEC                         17
+#define MFC_REG_CODEC_VP9_DEC                          18
+/* Encoder */
+#define MFC_REG_CODEC_H264_ENC                         20
+#define MFC_REG_CODEC_H264_MVC_ENC                     21
+#define MFC_REG_CODEC_MPEG4_ENC                        23
+#define MFC_REG_CODEC_H263_ENC                         24
+#define MFC_REG_CODEC_VP8_ENC                          25
+#define MFC_REG_CODEC_HEVC_ENC                         26
+#define MFC_REG_CODEC_VP9_ENC                          27
+
+#define MFC_REG_CODEC_BPG_DEC                          32
+#define MFC_REG_CODEC_BPG_ENC                          33
+
+/* 0xF028: MFC_REG_MFC_VERSION */
+#define MFC_REG_MFC_VER_MASK                           0xFFFFFFFF
+#define MFC_REG_MFC_VER_SHFT                           0
+
+
+/* 0xF074: MFC_REG_ERROR_CODE */
+#define MFC_REG_ERR_STATUS_MASK                        0xFFFF
+#define MFC_REG_ERR_STATUS_SHIFT                       0
+#define MFC_REG_WARN_STATUS_MASK                       0xFFFF
+#define MFC_REG_WARN_STATUS_SHIFT                      16
+/* Error number */
+#define MFC_REG_ERR_BUFFER_FULL                        18
+#define MFC_REG_ERR_NO_AVAILABLE_DPB                   33
+#define MFC_REG_ERR_NO_KEY_FRAME                       34
+#define MFC_REG_ERR_VPS_ONLY_ERROR                     42
+#define MFC_REG_ERR_INSUFFICIENT_DPB_SIZE              57
+#define MFC_REG_ERR_INSUFFICIENT_NUM_DPB               58
+#define MFC_REG_ERR_INSUFFICIENT_MV_BUF_SIZE           60
+#define MFC_REG_ERR_NULL_SCRATCH                       61
+#define MFC_REG_ERR_INSUFFICIENT_SCRATCH_BUF_SIZE      62
+
+#define MFC_REG_ERR_UNSUPPORTED_FEATURE                100
+#define MFC_REG_ERR_UNSUPPORTED_RESOLUTION             101
+#define MFC_REG_ERR_HEADER_NOT_FOUND                   102
+#define MFC_REG_ERR_INVAILD_NAL_TYPE                   103
+#define MFC_REG_ERR_SEQUENCE_HEADER                    104
+#define MFC_REG_ERR_MFC_TIMEOUT                        140
+#define MFC_REG_ERR_TS_MUX_TIMEOUT                     141
+#define MFC_REG_ERR_G2D_TIMEOUT                        142
+#define MFC_REG_ERR_FRAME_CONCEAL                      150
+#define MFC_REG_ERR_WARNINGS_START                     160
+#define MFC_REG_ERR_BROKEN_LINK                        161
+#define MFC_REG_ERR_SYNC_POINT_NOT_RECEIVED            190
+#define MFC_REG_ERR_NON_PAIRED_FIELD                   191
+#define MFC_REG_ERR_WARNINGS_END                       222
+
+
+/* 0xF0B4: MFC_REG_D_DEC_OPTIONS */
+#define MFC_REG_D_DEC_OPT_DISPLAY_DELAY_EN_SHIFT       3
+#define MFC_REG_D_DEC_OPT_FMO_ASO_CTRL_MASK            0x1
+#define MFC_REG_D_DEC_OPT_FMO_ASO_CTRL_SHIFT           4
+#define MFC_REG_D_DEC_OPT_IDR_DECODING_MASK            0x1
+#define MFC_REG_D_DEC_OPT_IDR_DECODING_SHIFT           6
+#define MFC_REG_D_DEC_OPT_DISCARD_RCV_HEADER_SHIFT     7
+#define MFC_REG_D_DEC_OPT_CONCEAL_CONTROL_SHIFT        8
+#define MFC_REG_D_DEC_OPT_PARALLEL_DISABLE_SHIFT       11
+#define MFC_REG_D_DEC_OPT_REALLOC_CONTROL_SHIFT        13
+#define MFC_REG_D_DEC_OPT_SPECIAL_PARSING_SHIFT        15
+#define MFC_REG_D_DEC_OPT_THUMBNAIL_DECODING           16
+
+
+/* 0xF0C4: MFC_REG_D_SEI_ENABLE */
+#define MFC_REG_D_SEI_ENABLE_NEED_INIT_BUFFER_SHIFT    1
+#define MFC_REG_D_SEI_ENABLE_RECOVERY_PARSING_SHIFT    2
+#define MFC_REG_D_SEI_ENABLE_CONTENT_LIGHT_SHIFT       4
+#define MFC_REG_D_SEI_ENABLE_MASTERING_DISPLAY_SHIFT   5
+
+
+/* 0xF154: MFC_REG_D_INIT_BUFFER_OPTIONS */
+#define MFC_REG_D_INIT_BUF_OPT_LF_CTRL_MASK            0x3
+#define MFC_REG_D_INIT_BUF_OPT_LF_CTRL_SHIFT           1
+#define MFC_REG_D_INIT_BUF_OPT_DYNAMIC_DPB_SET_SHIFT   3
+#define MFC_REG_D_INIT_BUF_OPT_COPY_NOT_CODED_SHIFT    4
+#define MFC_REG_D_INIT_BUF_OPT_DITHERING_EN_SHIFT      6
+#define MFC_REG_D_INIT_BUF_OPT_STRIDE_SIZE_ALIGN       7
+
+
+/* 0xF5AC: MFC_REG_D_NAL_START_OPTIONS */
+#define MFC_REG_D_NAL_START_OPT_BLACK_BAR_SHIFT        3
+
+
+/* 0xF608: MFC_REG_D_DISPLAY_STATUS */
+#define MFC_REG_DISP_STATUS_DISPLAY_STATUS_MASK        0x7
+#define MFC_REG_DISP_STATUS_INTERLACE_MASK             0x1
+#define MFC_REG_DISP_STATUS_INTERLACE_SHIFT            3
+#define MFC_REG_DISP_STATUS_RES_CHANGE_MASK            0x3
+#define MFC_REG_DISP_STATUS_RES_CHANGE_SHIFT           4
+#define MFC_REG_DISP_STATUS_NEED_DPB_CHANGE_MASK       0x1
+#define MFC_REG_DISP_STATUS_NEED_DPB_CHANGE_SHIFT      9
+#define MFC_REG_DISP_STATUS_NEED_SCRATCH_CHANGE_MASK   0x1
+#define MFC_REG_DISP_STATUS_NEED_SCRATCH_CHANGE_SHIFT  10
+#define MFC_REG_DISP_STATUS_NEED_EMPTY_DPB_MASK        0x1
+#define MFC_REG_DISP_STATUS_NEED_EMPTY_DPB_SHIFT       12
+#define MFC_REG_DISP_STATUS_BLACK_BAR_DETECT_MASK      0x3
+#define MFC_REG_DISP_STATUS_BLACK_BAR_DETECT_SHIFT     13
+#define MFC_REG_DISP_STATUS_NOT_DETECTED               0x0
+#define MFC_REG_DISP_STATUS_BLACK_BAR                  0x1
+#define MFC_REG_DISP_STATUS_BLACK_SCREEN               0x2
+
+
+/* 0xF618: MFC_REG_D_DISPLAY_FRAME_TYPE */
+#define MFC_REG_DISPLAY_FRAME_MASK                     0x7
+#define MFC_REG_DISPLAY_TEMP_INFO_MASK                 0x1
+#define MFC_REG_DISPLAY_TEMP_INFO_SHIFT                7
+#define MFC_REG_DISPLAY_FRAME_NOT_CODED                0
+#define MFC_REG_DISPLAY_FRAME_I                        1
+#define MFC_REG_DISPLAY_FRAME_P                        2
+#define MFC_REG_DISPLAY_FRAME_B                        3
+
+
+/* 0xF61C: MFC_REG_D_DISPLAY_CROP_INFO1 */
+#define MFC_REG_D_SHARED_CROP_LEFT_MASK                0xFFFF
+#define MFC_REG_D_SHARED_CROP_RIGHT_SHIFT              16
+
+
+/* 0xF620: MFC_REG_D_DISPLAY_CROP_INFO2 */
+#define MFC_REG_D_SHARED_CROP_TOP_MASK                 0xFFFF
+#define MFC_REG_D_SHARED_CROP_BOTTOM_SHIFT             16
+
+
+/* 0xF644: MFC_REG_D_DECODED_STATUS */
+#define MFC_REG_DEC_STATUS_DECODED_STATUS_MASK         0x7
+#define MFC_REG_DEC_STATUS_DECODING_ONLY               0
+#define MFC_REG_DEC_STATUS_DECODING_DISPLAY            1
+#define MFC_REG_DEC_STATUS_DISPLAY_ONLY                2
+#define MFC_REG_DEC_STATUS_DECODING_EMPTY              3
+#define MFC_REG_DEC_STATUS_NUM_OF_TILE_MASK            0xF
+#define MFC_REG_DEC_STATUS_NUM_OF_TILE_SHIFT           15
+
+
+/* 0xF654: MFC_REG_D_DECODED_FRAME_TYPE */
+#define MFC_REG_DECODED_FRAME_MASK                     0x7
+#define MFC_REG_DECODED_FRAME_NOT_CODED                0
+#define MFC_REG_DECODED_FRAME_I                        1
+#define MFC_REG_DECODED_FRAME_P                        2
+#define MFC_REG_DECODED_FRAME_B                        3
+
+
+/* 0xF660: MFC_REG_D_DECODED_PICTURE_PROFILE */
+#define MFC_REG_D_DECODED_PIC_PROFILE_MASK             0x1F
+#define MFC_REG_D_BIT_DEPTH_CHROMA_MINUS8_MASK         0x7
+#define MFC_REG_D_BIT_DEPTH_CHROMA_MINUS8_SHIFT        19
+#define MFC_REG_D_BIT_DEPTH_LUMA_MINUS8_MASK           0x7
+#define MFC_REG_D_BIT_DEPTH_LUMA_MINUS8_SHIFT          16
+#define MFC_REG_D_PROFILE_HEVC_MAIN                    1
+#define MFC_REG_D_PROFILE_HEVC_MAIN_10                 2
+#define MFC_REG_D_PROFILE_HEVC_RANGE_EXT               4
+
+
+/* 0xF684: MFC_REG_D_CHROMA_FORMAT */
+#define MFC_REG_D_CHROMA_FORMAT_MASK                   0x3
+#define MFC_REG_D_COLOR_RANGE_MASK                     0x1
+#define MFC_REG_D_COLOR_RANGE_SHIFT                    3
+#define MFC_REG_D_COLOR_SPACE_MASK                     0xF
+#define MFC_REG_D_COLOR_SPACE_SHIFT                    4
+#define MFC_REG_D_COLOR_UNKNOWN                        0
+#define MFC_REG_D_CHROMA_400                           0
+#define MFC_REG_D_CHROMA_420                           1
+#define MFC_REG_D_CHROMA_422                           2
+#define MFC_REG_D_CHROMA_444                           3
+
+
+/* 0xF690: MFC_REG_D_H264_INFO */
+#define MFC_REG_D_H264_INFO_MBAFF_FRAME_FLAG_SHIFT     9
+#define MFC_REG_D_H264_INFO_MBAFF_FRAME_FLAG_MASK      0x1
+
+
+/* 0xF6D8: MFC_REG_D_MVC_VIEW_ID */
+#define MFC_REG_D_MVC_VIEW_ID_DISP_MASK                0xFFFF
+
+
+/* 0xF6DC: MFC_REG_D_SEI_AVAIL */
+#define MFC_REG_D_SEI_AVAIL_FRAME_PACK_MASK            0x1
+#define MFC_REG_D_SEI_AVAIL_CONTENT_LIGHT_MASK         0x1
+#define MFC_REG_D_SEI_AVAIL_CONTENT_LIGHT_SHIFT        1
+#define MFC_REG_D_SEI_AVAIL_MASTERING_DISPLAY_MASK     0x1
+#define MFC_REG_D_SEI_AVAIL_MASTERING_DISPLAY_SHIFT    2
+
+
+/* 0xF70C: MFC_REG_D_VIDEO_SIGNAL_TYPE */
+#define MFC_REG_D_VIDEO_SIGNAL_TYPE_FLAG_MASK          0x1
+#define MFC_REG_D_VIDEO_SIGNAL_TYPE_FLAG_SHIFT         29
+#define MFC_REG_D_COLOUR_DESCRIPTION_FLAG_MASK         0x1
+#define MFC_REG_D_COLOUR_DESCRIPTION_FLAG_SHIFT        24
+
+
+/* 0xF738: MFC_REG_D_BLACK_BAR_START_POS */
+#define MFC_REG_D_BLACK_BAR_START_X_SHIFT              0
+#define MFC_REG_D_BLACK_BAR_START_X_MASK               0xFFFF
+#define MFC_REG_D_BLACK_BAR_START_Y_SHIFT              16
+#define MFC_REG_D_BLACK_BAR_START_Y_MASK               0xFFFF
+
+
+/* 0xF73C: MFC_REG_D_BLACK_BAR_IMAGE_SIZE */
+#define MFC_REG_D_BLACK_BAR_IMAGE_W_SHIFT              0
+#define MFC_REG_D_BLACK_BAR_IMAGE_W_MASK               0xFFFF
+#define MFC_REG_D_BLACK_BAR_IMAGE_H_SHIFT              16
+#define MFC_REG_D_BLACK_BAR_IMAGE_H_MASK               0xFFFF
+
+
+/* 0xF780:  MFC_REG_E_FRAME_CROP_OFFSET */
+#define MFC_REG_E_FRAME_CROP_OFFSET_TOP                16
+#define MFC_REG_E_FRAME_CROP_OFFSET_LEFT               0
+#define MFC_REG_E_FRAME_CROP_OFFSET_MASK               0x3FFF
+
+
+/* 0xF788: MFC_REG_E_PICTURE_PROFILE */
+#define MFC_REG_E_PROFILE_H264_BASELINE                0
+#define MFC_REG_E_PROFILE_H264_MAIN                    1
+#define MFC_REG_E_PROFILE_H264_HIGH                    2
+#define MFC_REG_E_PROFILE_H264_CONSTRAINED_BASELINE    3
+#define MFC_REG_E_PROFILE_H264_CONSTRAINED_HIGH        5
+#define MFC_REG_E_PROFILE_MPEG4_SIMPLE                 0
+#define MFC_REG_E_PROFILE_MPEG4_ADVANCED_SIMPLE        1
+#define MFC_REG_E_PROFILE_HEVC_MAIN_422_10_INTRA       2
+#define MFC_REG_E_PROFILE_HEVC_MAIN_10                 3
+#define MFC_REG_E_PROFILE_HEVC_MAIN_422_10             4
+#define MFC_REG_E_PROFILE_VP9_PROFILE0                 0
+#define MFC_REG_E_PROFILE_VP9_PROFILE1                 1
+#define MFC_REG_E_PROFILE_VP9_PROFILE2                 2
+#define MFC_REG_E_PROFILE_VP9_PROFILE3                 3
+
+
+/* 0xF7A4: MFC_REG_E_RC_MODE */
+#define MFC_REG_E_RC_CBR_FIX                           0
+#define MFC_REG_E_RC_CBR_VAR                           1
+#define MFC_REG_E_RC_VBR                               2
+#define MFC_REG_E_RC_CBR_I_LIMIT                       3
+
+
+/* 0xFA84: MFC_REG_E_SLICE_TYPE */
+#define MFC_REG_E_SLICE_TYPE_NOT_CODED                 0
+#define MFC_REG_E_SLICE_TYPE_I                         1
+#define MFC_REG_E_SLICE_TYPE_P                         2
+#define MFC_REG_E_SLICE_TYPE_B                         3
+#define MFC_REG_E_SLICE_TYPE_SKIPPED                   4
+
+
+#endif /* __MFC_REGS_H */
diff --git a/drivers/media/platform/exynos/mfc/mfc_regs_v10.h b/drivers/media/platform/exynos/mfc/mfc_regs_v10.h
deleted file mode 100644 (file)
index e50d495..0000000
+++ /dev/null
@@ -1,743 +0,0 @@
-/*
- * drivers/media/platform/exynos/mfc/regs-mfc-v10.h
- *
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef __REGS_MFC_V10_H
-#define __REGS_MFC_V10_H __FILE__
-
-#define MFC_MMU_INTERRUPT_STATUS                               0x0060
-#define MFC_MMU_FAULT_TRANS_INFO                               0x0078
-#define MFC_MMU_FAULT_TRANS_INFO_RW_MASK                       0x100000
-#define MFC_MMU_FAULT_TRANS_INFO_AXID_MASK                     0xFFFF
-
-#define HWFC_ENCODING_IDX                                      0x4
-
-/* Codec Common Registers */
-#define MFC_REG_RISC_ON                                        0x0000
-#define MFC_REG_RISC2HOST_INT                                  0x003C
-#define MFC_REG_HOST2RISC_INT                                  0x0044
-#define MFC_REG_RISC_BASE_ADDRESS                              0x0054
-
-#define MFC_REG_MFC_FW_CLOCK                                   0x1060
-#define MFC_REG_MFC_RESET                                      0x1070
-
-#define MFC_REG_HOST2RISC_CMD                                  0x1100
-#define MFC_REG_RISC2HOST_CMD                                  0x1104
-
-#define MFC_REG_MFC_BUS_STATUS                                 0x7018
-#define MFC_REG_MFC_RPEND                                      0x7028
-#define MFC_REG_MFC_WPEND                                      0x702C
-#define MFC_REG_MFC_BUS_RESET_CTRL                             0x7110
-#define MFC_REG_MFC_OFF                                        0x7120
-#define MFC_REG_MFC_STATE                                      0x7124
-
-#define MFC_REG_FW_VERSION                                     0xF000
-#define MFC_REG_INSTANCE_ID                                    0xF008
-#define MFC_REG_CODEC_TYPE                                     0xF00C
-#define MFC_REG_CONTEXT_MEM_ADDR                               0xF014
-#define MFC_REG_CONTEXT_MEM_SIZE                               0xF018
-#define MFC_REG_SHARED_MEM_ADDR                                0xF01C
-#define MFC_REG_PIXEL_FORMAT                                   0xF020
-
-#define MFC_REG_METADATA_ENABLE                                0xF024
-#define MFC_REG_MFC_VERSION                                    0xF028
-#define MFC_REG_DBG_INFO_ENABLE                                0xF02C
-#define MFC_REG_DBG_BUFFER_ADDR                                0xF030
-#define MFC_REG_DBG_BUFFER_SIZE                                0xF034
-
-#define MFC_REG_CODEC_CONTROL                                  0xF038
-#define MFC_REG_DEC_TIMEOUT_VALUE                              0xF03C
-#define MFC_REG_HED_SHARED_MEM_ADDR                            0xF040
-
-/* NAL QUEUE */
-#define MFC_REG_NAL_QUEUE_INPUT_ADDR                           0xF044
-#define MFC_REG_NAL_QUEUE_INPUT_SIZE                           0xF048
-#define MFC_REG_NAL_QUEUE_OUTPUT_ADDR                          0xF04C
-#define MFC_REG_NAL_QUEUE_OUTPUT_SIZE                          0xF050
-#define MFC_REG_NAL_QUEUE_INPUT_COUNT                          0xF054
-
-#define MFC_REG_RET_INSTANCE_ID                                0xF070
-#define MFC_REG_ERROR_CODE                                     0xF074
-#define MFC_REG_DBG_BUFFER_OUTPUT_SIZE                         0xF078
-#define MFC_REG_METADATA_STATUS                                0xF07C
-
-#define MFC_REG_DBG_INFO_STAGE_COUNTER                         0xF088
-
-/* NAL QUEUE */
-#define MFC_REG_NAL_QUEUE_OUTPUT_COUNT                         0xF08C
-#define MFC_REG_NAL_QUEUE_INPUT_EXE_COUNT                      0xF090
-#define MFC_REG_NAL_QUEUE_INFO                                 0xF094
-
-/* Decoder Registers */
-#define MFC_REG_D_CRC_CTRL                                     0xF0B0
-#define MFC_REG_D_DEC_OPTIONS                                  0xF0B4
-
-#define MFC_REG_D_DISPLAY_DELAY                                0xF0B8
-
-#define MFC_REG_D_SET_FRAME_WIDTH                              0xF0BC
-#define MFC_REG_D_SET_FRAME_HEIGHT                             0xF0C0
-
-#define MFC_REG_D_SEI_ENABLE                                   0xF0C4
-
-#define MFC_REG_D_FORCE_PIXEL_VAL                              0xF0C8
-
-/* Buffer setting registers */
-/* Session return */
-#define MFC_REG_D_MIN_NUM_DPB                                  0xF0F0
-#define MFC_REG_D_MIN_FIRST_PLANE_DPB_SIZE                     0xF0F4
-#define MFC_REG_D_MIN_SECOND_PLANE_DPB_SIZE                    0xF0F8
-#define MFC_REG_D_MIN_THIRD_PLANE_DPB_SIZE                     0xF0FC
-#define MFC_REG_D_MIN_NUM_MV                                   0xF100
-#define MFC_REG_D_MVC_NUM_VIEWS                                0xF104
-#define MFC_REG_D_MIN_SCRATCH_BUFFER_SIZE                      0xF108
-#define MFC_REG_D_MIN_FIRST_PLANE_2BIT_DPB_SIZE                0xF10C
-#define MFC_REG_D_MIN_SECOND_PLANE_2BIT_DPB_SIZE               0xF110
-#define MFC_REG_D_POST_FILTER_LUMA_DPB0                        0xF120
-#define MFC_REG_D_POST_FILTER_LUMA_DPB1                        0xF124
-#define MFC_REG_D_POST_FILTER_CHROMA_DPB0                      0xF128
-#define MFC_REG_D_POST_FILTER_CHROMA_DPB1                      0xF12C
-
-/* Buffers */
-#define MFC_REG_D_NUM_DPB                                      0xF130
-#define MFC_REG_D_NUM_MV                                       0xF134
-#define MFC_REG_D_FIRST_PLANE_DPB_STRIDE_SIZE                  0xF138
-#define MFC_REG_D_SECOND_PLANE_DPB_STRIDE_SIZE                 0xF13C
-#define MFC_REG_D_THIRD_PLANE_DPB_STRIDE_SIZE                  0xF140
-#define MFC_REG_D_FIRST_PLANE_DPB_SIZE                         0xF144
-#define MFC_REG_D_SECOND_PLANE_DPB_SIZE                        0xF148
-#define MFC_REG_D_THIRD_PLANE_DPB_SIZE                         0xF14C
-#define MFC_REG_D_MV_BUFFER_SIZE                               0xF150
-#define MFC_REG_D_INIT_BUFFER_OPTIONS                          0xF154
-#define MFC_REG_D_FIRST_PLANE_DPB0                             0xF160
-#define MFC_REG_D_SECOND_PLANE_DPB0                            0xF260
-#define MFC_REG_D_THIRD_PLANE_DPB0                             0xF360
-#define MFC_REG_D_MV_BUFFER0                                   0xF460
-#define MFC_REG_D_SCRATCH_BUFFER_ADDR                          0xF560
-#define MFC_REG_D_SCRATCH_BUFFER_SIZE                          0xF564
-#define MFC_REG_D_METADATA_BUFFER_ADDR                         0xF568
-#define MFC_REG_D_METADATA_BUFFER_SIZE                         0xF56C
-
-#define MFC_REG_D_STATIC_BUFFER_ADDR                           0xF570
-#define MFC_REG_D_STATIC_BUFFER_SIZE                           0xF574
-#define MFC_REG_D_FIRST_PLANE_2BIT_DPB_SIZE                    0xF578
-#define MFC_REG_D_SECOND_PLANE_2BIT_DPB_SIZE                   0xF57C
-#define MFC_REG_D_FIRST_PLANE_2BIT_DPB_STRIDE_SIZE             0xF580
-#define MFC_REG_D_SECOND_PLANE_2BIT_DPB_STRIDE_SIZE            0xF584
-
-#define MFC_REG_D_NAL_START_OPTIONS                            0xF5AC
-
-/* Nal cmd */
-#define MFC_REG_D_CPB_BUFFER_ADDR                              0xF5B0
-#define MFC_REG_D_CPB_BUFFER_SIZE                              0xF5B4
-#define MFC_REG_D_AVAILABLE_DPB_FLAG_UPPER                     0xF5B8
-#define MFC_REG_D_AVAILABLE_DPB_FLAG_LOWER                     0xF5BC
-#define MFC_REG_D_CPB_BUFFER_OFFSET                            0xF5C0
-#define MFC_REG_D_SLICE_IF_ENABLE                              0xF5C4
-#define MFC_REG_D_PICTURE_TAG                                  0xF5C8
-#define MFC_REG_D_STREAM_DATA_SIZE                             0xF5D0
-#define MFC_REG_D_DYNAMIC_DPB_FLAG_UPPER                       0xF5D4
-#define MFC_REG_D_DYNAMIC_DPB_FLAG_LOWER                       0xF5D8
-
-/* Nal return */
-#define MFC_REG_D_DISPLAY_FRAME_WIDTH                          0xF600
-#define MFC_REG_D_DISPLAY_FRAME_HEIGHT                         0xF604
-#define MFC_REG_D_DISPLAY_STATUS                               0xF608
-#define MFC_REG_D_DISPLAY_FIRST_PLANE_ADDR                     0xF60C
-#define MFC_REG_D_DISPLAY_SECOND_PLANE_ADDR                    0xF610
-#define MFC_REG_D_DISPLAY_THIRD_PLANE_ADDR                     0xF614
-#define MFC_REG_D_DISPLAY_FRAME_TYPE                           0xF618
-#define MFC_REG_D_DISPLAY_CROP_INFO1                           0xF61C
-#define MFC_REG_D_DISPLAY_CROP_INFO2                           0xF620
-#define MFC_REG_D_DISPLAY_PICTURE_PROFILE                      0xF624
-#define MFC_REG_D_DISPLAY_FIRST_PLANE_CRC                      0xF628
-#define MFC_REG_D_DISPLAY_SECOND_PLANE_CRC                     0xF62C
-#define MFC_REG_D_DISPLAY_THIRD_PLANE_CRC                      0xF630
-#define MFC_REG_D_DISPLAY_ASPECT_RATIO                         0xF634
-#define MFC_REG_D_DISPLAY_EXTENDED_AR                          0xF638
-#define MFC_REG_D_DECODED_FRAME_WIDTH                          0xF63C
-#define MFC_REG_D_DECODED_FRAME_HEIGHT                         0xF640
-#define MFC_REG_D_DECODED_STATUS                               0xF644
-#define MFC_REG_D_DECODED_FIRST_PLANE_ADDR                     0xF648
-#define MFC_REG_D_DECODED_SECOND_PLANE_ADDR                    0xF64C
-#define MFC_REG_D_DECODED_THIRD_PLANE_ADDR                     0xF650
-#define MFC_REG_D_DECODED_FRAME_TYPE                           0xF654
-#define MFC_REG_D_DECODED_CROP_INFO1                           0xF658
-#define MFC_REG_D_DECODED_CROP_INFO2                           0xF65C
-#define MFC_REG_D_DECODED_PICTURE_PROFILE                      0xF660
-#define MFC_REG_D_DECODED_NAL_SIZE                             0xF664
-#define MFC_REG_D_DECODED_FIRST_PLANE_CRC                      0xF668
-#define MFC_REG_D_DECODED_SECOND_PLANE_CRC                     0xF66C
-#define MFC_REG_D_DECODED_THIRD_PLANE_CRC                      0xF670
-#define MFC_REG_D_RET_PICTURE_TAG_TOP                          0xF674
-#define MFC_REG_D_RET_PICTURE_TAG_BOT                          0xF678
-#define MFC_REG_D_RET_PICTURE_TIME_TOP                         0xF67C
-#define MFC_REG_D_RET_PICTURE_TIME_BOT                         0xF680
-#define MFC_REG_D_CHROMA_FORMAT                                0xF684
-
-#define MFC_REG_D_VC1_INFO                                     0xF688
-#define MFC_REG_D_MPEG4_INFO                                   0xF68C
-#define MFC_REG_D_H264_INFO                                    0xF690
-#define MFC_REG_D_HEVC_INFO                                    0xF6A0
-#define MFC_REG_D_BPG_INFO                                     0xF6A8
-
-#define MFC_REG_D_METADATA_ADDR_CONCEALED_MB                   0xF6B0
-#define MFC_REG_D_METADATA_SIZE_CONCEALED_MB                   0xF6B4
-#define MFC_REG_D_METADATA_ADDR_VC1_PARAM                      0xF6B8
-#define MFC_REG_D_METADATA_SIZE_VC1_PARAM                      0xF6BC
-#define MFC_REG_D_METADATA_ADDR_SEI_NAL                        0xF6C0
-#define MFC_REG_D_METADATA_SIZE_SEI_NAL                        0xF6C4
-#define MFC_REG_D_METADATA_ADDR_VUI                            0xF6C8
-#define MFC_REG_D_METADATA_SIZE_VUI                            0xF6CC
-#define MFC_REG_D_METADATA_ADDR_MVCVUI                         0xF6D0
-#define MFC_REG_D_METADATA_SIZE_MVCVUI                         0xF6D4
-
-#define MFC_REG_D_MVC_VIEW_ID                                  0xF6D8
-
-#define MFC_REG_D_SEI_AVAIL                                    0xF6DC
-#define MFC_REG_D_FRAME_PACK_ARRGMENT_ID                       0xF6E0
-#define MFC_REG_D_FRAME_PACK_SEI_INFO                          0xF6E4
-#define MFC_REG_D_FRAME_PACK_GRID_POS                          0xF6E8
-
-#define MFC_REG_D_DISPLAY_RECOVERY_SEI_INFO                    0xF6EC
-#define MFC_REG_D_DECODED_RECOVERY_SEI_INFO                    0xF6F0
-
-#define MFC_REG_D_DISPLAY_FIRST_PLANE_2BIT_CRC                 0xF6FC
-#define MFC_REG_D_DISPLAY_SECOND_PLANE_2BIT_CRC                0xF700
-#define MFC_REG_D_DECODED_FIRST_PLANE_2BIT_CRC                 0xF704
-#define MFC_REG_D_DECODED_SECOND_PLANE_2BIT_CRC                0xF708
-
-#define MFC_REG_D_VIDEO_SIGNAL_TYPE                            0xF70C
-#define MFC_REG_D_CONTENT_LIGHT_LEVEL_INFO_SEI                 0xF710
-#define MFC_REG_D_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_0        0xF714
-#define MFC_REG_D_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_1        0xF718
-
-#define MFC_REG_D_USED_DPB_FLAG_UPPER                          0xF720
-#define MFC_REG_D_USED_DPB_FLAG_LOWER                          0xF724
-
-#define MFC_REG_D_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_2        0xF728
-#define MFC_REG_D_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_3        0xF72C
-#define MFC_REG_D_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_4        0xF730
-#define MFC_REG_D_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_5        0xF734
-
-#define MFC_REG_D_BLACK_BAR_START_POS                          0xF738
-#define MFC_REG_D_BLACK_BAR_IMAGE_SIZE                         0xF73C
-
-#define MFC_REG_D_DISPLAY_LUMA_ADDR                            0xF60C
-#define MFC_REG_D_DISPLAY_CHROMA_ADDR                          0xF610
-
-#define MFC_REG_D_DECODED_LUMA_ADDR                            0xF648
-#define MFC_REG_D_DECODED_CHROMA_ADDR                          0xF64C
-
-/* Encoder Registers */
-#define MFC_REG_E_CROPPED_FRAME_WIDTH                          0xF778
-#define MFC_REG_E_CROPPED_FRAME_HEIGHT                         0xF77C
-#define MFC_REG_E_FRAME_CROP_OFFSET                            0xF780
-#define MFC_REG_E_ENC_OPTIONS                                  0xF784
-#define MFC_REG_E_PICTURE_PROFILE                              0xF788
-#define MFC_REG_E_VBV_BUFFER_SIZE                              0xF78C
-#define MFC_REG_E_VBV_INIT_DELAY                               0xF790
-#define MFC_REG_E_FIXED_PICTURE_QP                             0xF794
-#define MFC_REG_E_RC_CONFIG                                    0xF798
-#define MFC_REG_E_RC_QP_BOUND                                  0xF79C
-#define MFC_REG_E_RC_QP_BOUND_PB                               0xF7A0
-#define MFC_REG_E_RC_MODE                                      0xF7A4
-
-#define MFC_REG_E_MB_RC_CONFIG                                 0xF7A8
-#define MFC_REG_E_PADDING_CTRL                                 0xF7AC
-#define MFC_REG_E_AIR_THRESHOLD                                0xF7B0
-
-#define MFC_REG_E_MV_HOR_RANGE                                 0xF7B4
-#define MFC_REG_E_MV_VER_RANGE                                 0xF7B8
-
-#define MFC_REG_E_HIGH_QUALITY_MODE                            0xF7C0
-#define MFC_REG_E_VIDEO_SIGNAL_TYPE                            0xF7C4
-
-#define MFC_REG_E_SAO_WEIGHT0                                  0xF7C8
-#define MFC_REG_E_SAO_WEIGHT1                                  0xF7CC
-
-#define MFC_REG_E_NUM_DPB                                      0xF890
-#define MFC_REG_E_MIN_SCRATCH_BUFFER_SIZE                      0xF894
-
-#define MFC_REG_E_LUMA_DPB                                     0xF8C0
-#define MFC_REG_E_CHROMA_DPB                                   0xF904
-#define MFC_REG_E_ME_BUFFER                                    0xF948
-
-#define MFC_REG_E_SCRATCH_BUFFER_ADDR                          0xF98C
-#define MFC_REG_E_SCRATCH_BUFFER_SIZE                          0xF990
-#define MFC_REG_E_TMV_BUFFER0                                  0xF994
-#define MFC_REG_E_TMV_BUFFER1                                  0xF998
-#define MFC_REG_E_IR_BUFFER_ADDR                               0xF99C
-#define MFC_REG_E_SOURCE_FIRST_2BIT_ADDR                       0xF9D0
-#define MFC_REG_E_SOURCE_SECOND_2BIT_ADDR                      0xF9D4
-#define MFC_REG_E_SOURCE_FIRST_2BIT_STRIDE                     0xF9D8
-#define MFC_REG_E_SOURCE_SECOND_2BIT_STRIDE                    0xF9DC
-#define MFC_REG_E_SOURCE_FIRST_ADDR                            0xF9E0
-#define MFC_REG_E_SOURCE_SECOND_ADDR                           0xF9E4
-#define MFC_REG_E_SOURCE_THIRD_ADDR                            0xF9E8
-#define MFC_REG_E_SOURCE_FIRST_STRIDE                          0xF9EC
-#define MFC_REG_E_SOURCE_SECOND_STRIDE                         0xF9F0
-#define MFC_REG_E_SOURCE_THIRD_STRIDE                          0xF9F4
-#define MFC_REG_E_STREAM_BUFFER_ADDR                           0xF9F8
-#define MFC_REG_E_STREAM_BUFFER_SIZE                           0xF9FC
-#define MFC_REG_E_ROI_BUFFER_ADDR                              0xFA00
-
-#define MFC_REG_E_PARAM_CHANGE                                 0xFA04
-#define MFC_REG_E_IR_SIZE                                      0xFA08
-#define MFC_REG_E_GOP_CONFIG                                   0xFA0C
-#define MFC_REG_E_MSLICE_MODE                                  0xFA10
-#define MFC_REG_E_MSLICE_SIZE_MB                               0xFA14
-#define MFC_REG_E_MSLICE_SIZE_BITS                             0xFA18
-#define MFC_REG_E_FRAME_INSERTION                              0xFA1C
-
-#define MFC_REG_E_RC_FRAME_RATE                                0xFA20
-#define MFC_REG_E_RC_BIT_RATE                                  0xFA24
-#define MFC_REG_E_RC_ROI_CTRL                                  0xFA2C
-#define MFC_REG_E_PICTURE_TAG                                  0xFA30
-#define MFC_REG_E_BIT_COUNT_ENABLE                             0xFA34
-#define MFC_REG_E_MAX_BIT_COUNT                                0xFA38
-#define MFC_REG_E_MIN_BIT_COUNT                                0xFA3C
-
-#define MFC_REG_E_METADATA_BUFFER_ADDR                         0xFA40
-#define MFC_REG_E_METADATA_BUFFER_SIZE                         0xFA44
-
-#define MFC_REG_E_ENCODING_ORDER_TIME_INFO                     0xFA50
-#define MFC_REG_E_ENCODING_ORDER_INFO                          0xFA54
-#define MFC_REG_E_STREAM_BUFFER_OFFSET                         0xFA58
-#define MFC_REG_E_GOP_CONFIG2                                  0xFA5C
-#define MFC_REG_E_WEIGHT_FOR_WEIGHTED_PREDICTION               0xFA60
-
-#define MFC_REG_E_ENCODED_SOURCE_FIRST_ADDR                    0xFA70
-#define MFC_REG_E_ENCODED_SOURCE_SECOND_ADDR                   0xFA74
-#define MFC_REG_E_ENCODED_SOURCE_THIRD_ADDR                    0xFA78
-
-#define MFC_REG_E_STREAM_SIZE                                  0xFA80
-#define MFC_REG_E_SLICE_TYPE                                   0xFA84
-#define MFC_REG_E_PICTURE_COUNT                                0xFA88
-#define MFC_REG_E_RET_PICTURE_TAG                              0xFA8C
-
-#define MFC_REG_E_RECON_LUMA_DPB_ADDR                          0xFA9C
-#define MFC_REG_E_RECON_CHROMA_DPB_ADDR                        0xFAA0
-#define MFC_REG_E_METADATA_ADDR_ENC_SLICE                      0xFAA4
-#define MFC_REG_E_METADATA_SIZE_ENC_SLICE                      0xFAA8
-
-#define MFC_REG_E_NAL_DONE_INFO                                0xFAEC
-
-#define MFC_REG_E_MPEG4_OPTIONS                                0xFB10
-#define MFC_REG_E_MPEG4_HEC_PERIOD                             0xFB14
-
-#define MFC_REG_E_BPG_OPTIONS                                  0xFB1C
-#define MFC_REG_E_BPG_EXT_CTB_QP_CTRL                          0xFB20
-#define MFC_REG_E_BPG_CHROMA_QP_OFFSET                         0xFB24
-#define MFC_REG_E_BPG_EXTENSION_DATA_SIZE                      0xFB28
-
-#define MFC_REG_E_H264_HD_SVC_EXTENSION_0                      0xFB44
-#define MFC_REG_E_H264_HD_SVC_EXTENSION_1                      0xFB48
-#define MFC_REG_E_ASPECT_RATIO                                 0xFB4C
-#define MFC_REG_E_EXTENDED_SAR                                 0xFB50
-
-#define MFC_REG_E_H264_OPTIONS                                 0xFB54
-#define MFC_REG_E_H264_OPTIONS_2                               0xFB58
-#define MFC_REG_E_H264_LF_ALPHA_OFFSET                         0xFB5C
-#define MFC_REG_E_H264_LF_BETA_OFFSET                          0xFB60
-#define MFC_REG_E_H264_REFRESH_PERIOD                          0xFB64
-
-#define MFC_REG_E_H264_FMO_SLICE_GRP_MAP_TYPE                  0xFB68
-#define MFC_REG_E_H264_FMO_NUM_SLICE_GRP_MINUS1                0xFB6C
-#define MFC_REG_E_H264_FMO_SLICE_GRP_CHANGE_DIR                0xFB70
-#define MFC_REG_E_H264_FMO_SLICE_GRP_CHANGE_RATE_MINUS1        0xFB74
-#define MFC_REG_E_H264_FMO_RUN_LENGTH_MINUS1_0                 0xFB78
-#define MFC_REG_E_H264_FMO_RUN_LENGTH_MINUS1_1                 0xFB7C
-#define MFC_REG_E_H264_FMO_RUN_LENGTH_MINUS1_2                 0xFB80
-#define MFC_REG_E_H264_FMO_RUN_LENGTH_MINUS1_3                 0xFB84
-
-#define MFC_REG_E_H264_ASO_SLICE_ORDER_0                       0xFB88
-#define MFC_REG_E_H264_ASO_SLICE_ORDER_1                       0xFB8C
-#define MFC_REG_E_H264_ASO_SLICE_ORDER_2                       0xFB90
-#define MFC_REG_E_H264_ASO_SLICE_ORDER_3                       0xFB94
-#define MFC_REG_E_H264_ASO_SLICE_ORDER_4                       0xFB98
-#define MFC_REG_E_H264_ASO_SLICE_ORDER_5                       0xFB9C
-#define MFC_REG_E_H264_ASO_SLICE_ORDER_6                       0xFBA0
-#define MFC_REG_E_H264_ASO_SLICE_ORDER_7                       0xFBA4
-#define MFC_REG_E_H264_CHROMA_QP_OFFSET                        0xFBA8
-
-#define MFC_REG_E_NUM_T_LAYER                                  0xFBAC
-#define MFC_REG_E_HIERARCHICAL_QP_LAYER0                       0xFBB0
-#define MFC_REG_E_HIERARCHICAL_QP_LAYER1                       0xFBB4
-#define MFC_REG_E_HIERARCHICAL_QP_LAYER2                       0xFBB8
-#define MFC_REG_E_HIERARCHICAL_QP_LAYER3                       0xFBBC
-#define MFC_REG_E_HIERARCHICAL_QP_LAYER4                       0xFBC0
-#define MFC_REG_E_HIERARCHICAL_QP_LAYER5                       0xFBC4
-#define MFC_REG_E_HIERARCHICAL_QP_LAYER6                       0xFBC8
-
-/* For backward compatibility */
-#define MFC_REG_E_H264_FRAME_PACKING_SEI_INFO                  0xFC4C
-
-#define MFC_REG_E_H264_NAL_CONTROL                             0xFD14
-#define MFC_REG_E_HIERARCHICAL_BIT_RATE_LAYER0                 0xFD18
-#define MFC_REG_E_HIERARCHICAL_BIT_RATE_LAYER1                 0xFD1C
-#define MFC_REG_E_HIERARCHICAL_BIT_RATE_LAYER2                 0xFD20
-#define MFC_REG_E_HIERARCHICAL_BIT_RATE_LAYER3                 0xFD24
-#define MFC_REG_E_HIERARCHICAL_BIT_RATE_LAYER4                 0xFD28
-#define MFC_REG_E_HIERARCHICAL_BIT_RATE_LAYER5                 0xFD2C
-#define MFC_REG_E_HIERARCHICAL_BIT_RATE_LAYER6                 0xFD30
-
-#define MFC_REG_E_MVC_FRAME_QP_VIEW1                           0xFD40
-#define MFC_REG_E_MVC_RC_FRAME_RATE_VIEW1                      0xFD44
-#define MFC_REG_E_MVC_RC_BIT_RATE_VIEW1                        0xFD48
-#define MFC_REG_E_MVC_RC_QBOUND_VIEW1                          0xFD4C
-#define MFC_REG_E_MVC_RC_MODE_VIEW1                            0xFD50
-#define MFC_REG_E_MVC_INTER_VIEW_PREDICTION_ON                 0xFD80
-
-#define MFC_REG_E_VP9_OPTION                                   0xFD90
-#define MFC_REG_E_VP9_FILTER_OPTION                            0xFD94
-#define MFC_REG_E_VP9_GOLDEN_FRAME_OPTION                      0xFD98
-#define MFC_REG_E_VP8_OPTION                                   0xFDB0
-#define MFC_REG_E_VP8_FILTER_OPTION                            0xFDB4
-#define MFC_REG_E_VP8_GOLDEN_FRAME_OPTION                      0xFDB8
-
-#define MFC_REG_E_HEVC_OPTIONS_2                               0xFDC4
-
-#define MFC_REG_E_HEVC_OPTIONS                                 0xFDD4
-#define MFC_REG_E_HEVC_REFRESH_PERIOD                          0xFDD8
-#define MFC_REG_E_HEVC_CHROMA_QP_OFFSET                        0xFDDC
-#define MFC_REG_E_HEVC_LF_BETA_OFFSET_DIV2                     0xFDE0
-#define MFC_REG_E_HEVC_LF_TC_OFFSET_DIV2                       0xFDE4
-#define MFC_REG_E_HEVC_NAL_CONTROL                             0xFDE8
-
-#define MFC_REG_E_VP8_NAL_CONTROL                              0xFDF0
-#define MFC_REG_E_VP9_NAL_CONTROL                              0xFDF4
-#define MFC_REG_E_CONTENT_LIGHT_LEVEL_INFO_SEI                 0xFDF8
-#define MFC_REG_E_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_0        0xFDFC
-#define MFC_REG_E_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_1        0xFE00
-#define MFC_REG_E_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_2        0xFE04
-#define MFC_REG_E_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_3        0xFE08
-#define MFC_REG_E_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_4        0xFE0C
-#define MFC_REG_E_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_5        0xFE10
-
-
-#define MFC_REG_REG_CLEAR_BEGIN                        0xf000
-#define MFC_REG_REG_CLEAR_COUNT                        1024
-
-
-/* Bit Definitions */
-/* 0x1100: MFC_REG_HOST2RISC_CMD */
-#define MFC_REG_H2R_CMD_EMPTY                          0
-#define MFC_REG_H2R_CMD_SYS_INIT                       1
-#define MFC_REG_H2R_CMD_OPEN_INSTANCE                  2
-#define MFC_REG_H2R_CMD_SEQ_HEADER                     3
-#define MFC_REG_H2R_CMD_INIT_BUFFERS                   4
-#define MFC_REG_H2R_CMD_NAL_START                      5
-#define MFC_REG_H2R_CMD_CLOSE_INSTANCE                 6
-#define MFC_REG_H2R_CMD_SLEEP                          7
-#define MFC_REG_H2R_CMD_WAKEUP                         8
-#define MFC_REG_H2R_CMD_LAST_FRAME                     9
-#define MFC_REG_H2R_CMD_DPB_FLUSH                      10
-#define MFC_REG_H2R_CMD_NAL_ABORT                      11
-#define MFC_REG_H2R_CMD_CACHE_FLUSH                    12
-#define MFC_REG_H2R_CMD_NAL_QUEUE                      13
-#define MFC_REG_H2R_CMD_STOP_QUEUE                     14
-
-
-/* 0x1104: MFC_REG_RISC2HOST_CMD */
-#define MFC_REG_RISC2HOST_CMD_MASK                     0x1FFFF
-#define MFC_REG_R2H_CMD_EMPTY                          0
-#define MFC_REG_R2H_CMD_SYS_INIT_RET                   1
-#define MFC_REG_R2H_CMD_OPEN_INSTANCE_RET              2
-#define MFC_REG_R2H_CMD_SEQ_DONE_RET                   3
-#define MFC_REG_R2H_CMD_INIT_BUFFERS_RET               4
-#define MFC_REG_R2H_CMD_CLOSE_INSTANCE_RET             6
-#define MFC_REG_R2H_CMD_SLEEP_RET                      7
-#define MFC_REG_R2H_CMD_WAKEUP_RET                     8
-#define MFC_REG_R2H_CMD_COMPLETE_SEQ_RET               9
-#define MFC_REG_R2H_CMD_DPB_FLUSH_RET                  10
-#define MFC_REG_R2H_CMD_NAL_ABORT_RET                  11
-#define MFC_REG_R2H_CMD_FW_STATUS_RET                  12
-#define MFC_REG_R2H_CMD_FRAME_DONE_RET                 13
-#define MFC_REG_R2H_CMD_FIELD_DONE_RET                 14
-#define MFC_REG_R2H_CMD_SLICE_DONE_RET                 15
-#define MFC_REG_R2H_CMD_ENC_BUFFER_FULL_RET            16
-#define MFC_REG_R2H_CMD_QUEUE_DONE_RET                 17
-#define MFC_REG_R2H_CMD_COMPLETE_QUEUE_RET             18
-#define MFC_REG_R2H_CMD_CACHE_FLUSH_RET                20
-#define MFC_REG_R2H_CMD_ERR_RET                        32
-
-
-/* 0xF000: MFC_REG_FW_VERSION */
-#define MFC_REG_FW_VER_INFO_MASK                       0xFF
-#define MFC_REG_FW_VER_INFO_SHFT                       24
-#define MFC_REG_FW_VER_YEAR_MASK                       0xFF
-#define MFC_REG_FW_VER_YEAR_SHFT                       16
-#define MFC_REG_FW_VER_MONTH_MASK                      0xFF
-#define MFC_REG_FW_VER_MONTH_SHFT                      8
-#define MFC_REG_FW_VER_DATE_MASK                       0xFF
-#define MFC_REG_FW_VER_DATE_SHFT                       0
-#define MFC_REG_FW_VER_ALL_MASK                        0xFFFFFF
-#define MFC_REG_FW_VER_ALL_SHFT                        0
-
-
-/* 0xF00C: MFC_REG_CODEC_TYPE */
-#define MFC_FORMATS_NO_CODEC                           -1
-/* Decoder */
-#define MFC_REG_CODEC_H264_DEC                         0
-#define MFC_REG_CODEC_H264_MVC_DEC                     1
-#define MFC_REG_CODEC_MPEG4_DEC                        3
-#define MFC_REG_CODEC_FIMV1_DEC                        4
-#define MFC_REG_CODEC_FIMV2_DEC                        5
-#define MFC_REG_CODEC_FIMV3_DEC                        6
-#define MFC_REG_CODEC_FIMV4_DEC                        7
-#define MFC_REG_CODEC_H263_DEC                         8
-#define MFC_REG_CODEC_VC1_RCV_DEC                      9
-#define MFC_REG_CODEC_VC1_DEC                          10
-#define MFC_REG_CODEC_MPEG2_DEC                        13
-#define MFC_REG_CODEC_VP8_DEC                          14
-#define MFC_REG_CODEC_HEVC_DEC                         17
-#define MFC_REG_CODEC_VP9_DEC                          18
-/* Encoder */
-#define MFC_REG_CODEC_H264_ENC                         20
-#define MFC_REG_CODEC_H264_MVC_ENC                     21
-#define MFC_REG_CODEC_MPEG4_ENC                        23
-#define MFC_REG_CODEC_H263_ENC                         24
-#define MFC_REG_CODEC_VP8_ENC                          25
-#define MFC_REG_CODEC_HEVC_ENC                         26
-#define MFC_REG_CODEC_VP9_ENC                          27
-
-#define MFC_REG_CODEC_BPG_DEC                          32
-#define MFC_REG_CODEC_BPG_ENC                          33
-
-/* 0xF028: MFC_REG_MFC_VERSION */
-#define MFC_REG_MFC_VER_MASK                           0xFFFFFFFF
-#define MFC_REG_MFC_VER_SHFT                           0
-
-
-/* 0xF074: MFC_REG_ERROR_CODE */
-#define MFC_REG_ERR_STATUS_MASK                        0xFFFF
-#define MFC_REG_ERR_STATUS_SHIFT                       0
-#define MFC_REG_WARN_STATUS_MASK                       0xFFFF
-#define MFC_REG_WARN_STATUS_SHIFT                      16
-/* Error number */
-#define MFC_REG_ERR_BUFFER_FULL                        18
-#define MFC_REG_ERR_NO_AVAILABLE_DPB                   33
-#define MFC_REG_ERR_NO_KEY_FRAME                       34
-#define MFC_REG_ERR_VPS_ONLY_ERROR                     42
-#define MFC_REG_ERR_INSUFFICIENT_DPB_SIZE              57
-#define MFC_REG_ERR_INSUFFICIENT_NUM_DPB               58
-#define MFC_REG_ERR_INSUFFICIENT_MV_BUF_SIZE           60
-#define MFC_REG_ERR_NULL_SCRATCH                       61
-#define MFC_REG_ERR_INSUFFICIENT_SCRATCH_BUF_SIZE      62
-
-#define MFC_REG_ERR_UNSUPPORTED_FEATURE                100
-#define MFC_REG_ERR_UNSUPPORTED_RESOLUTION             101
-#define MFC_REG_ERR_HEADER_NOT_FOUND                   102
-#define MFC_REG_ERR_INVAILD_NAL_TYPE                   103
-#define MFC_REG_ERR_SEQUENCE_HEADER                    104
-#define MFC_REG_ERR_MFC_TIMEOUT                        140
-#define MFC_REG_ERR_TS_MUX_TIMEOUT                     141
-#define MFC_REG_ERR_G2D_TIMEOUT                        142
-#define MFC_REG_ERR_FRAME_CONCEAL                      150
-#define MFC_REG_ERR_WARNINGS_START                     160
-#define MFC_REG_ERR_BROKEN_LINK                        161
-#define MFC_REG_ERR_SYNC_POINT_NOT_RECEIVED            190
-#define MFC_REG_ERR_NON_PAIRED_FIELD                   191
-#define MFC_REG_ERR_WARNINGS_END                       222
-
-
-/* 0xF0B4: MFC_REG_D_DEC_OPTIONS */
-#define MFC_REG_D_DEC_OPT_DISPLAY_DELAY_EN_SHIFT       3
-#define MFC_REG_D_DEC_OPT_FMO_ASO_CTRL_MASK            0x1
-#define MFC_REG_D_DEC_OPT_FMO_ASO_CTRL_SHIFT           4
-#define MFC_REG_D_DEC_OPT_IDR_DECODING_MASK            0x1
-#define MFC_REG_D_DEC_OPT_IDR_DECODING_SHIFT           6
-#define MFC_REG_D_DEC_OPT_DISCARD_RCV_HEADER_SHIFT     7
-#define MFC_REG_D_DEC_OPT_CONCEAL_CONTROL_SHIFT        8
-#define MFC_REG_D_DEC_OPT_PARALLEL_DISABLE_SHIFT       11
-#define MFC_REG_D_DEC_OPT_REALLOC_CONTROL_SHIFT        13
-#define MFC_REG_D_DEC_OPT_SPECIAL_PARSING_SHIFT        15
-#define MFC_REG_D_DEC_OPT_THUMBNAIL_DECODING           16
-
-
-/* 0xF0C4: MFC_REG_D_SEI_ENABLE */
-#define MFC_REG_D_SEI_ENABLE_NEED_INIT_BUFFER_SHIFT    1
-#define MFC_REG_D_SEI_ENABLE_RECOVERY_PARSING_SHIFT    2
-#define MFC_REG_D_SEI_ENABLE_CONTENT_LIGHT_SHIFT       4
-#define MFC_REG_D_SEI_ENABLE_MASTERING_DISPLAY_SHIFT   5
-
-
-/* 0xF154: MFC_REG_D_INIT_BUFFER_OPTIONS */
-#define MFC_REG_D_INIT_BUF_OPT_LF_CTRL_MASK            0x3
-#define MFC_REG_D_INIT_BUF_OPT_LF_CTRL_SHIFT           1
-#define MFC_REG_D_INIT_BUF_OPT_DYNAMIC_DPB_SET_SHIFT   3
-#define MFC_REG_D_INIT_BUF_OPT_COPY_NOT_CODED_SHIFT    4
-#define MFC_REG_D_INIT_BUF_OPT_DITHERING_EN_SHIFT      6
-#define MFC_REG_D_INIT_BUF_OPT_STRIDE_SIZE_ALIGN       7
-
-
-/* 0xF5AC: MFC_REG_D_NAL_START_OPTIONS */
-#define MFC_REG_D_NAL_START_OPT_BLACK_BAR_SHIFT        3
-
-
-/* 0xF608: MFC_REG_D_DISPLAY_STATUS */
-#define MFC_REG_DISP_STATUS_DISPLAY_STATUS_MASK        0x7
-#define MFC_REG_DISP_STATUS_INTERLACE_MASK             0x1
-#define MFC_REG_DISP_STATUS_INTERLACE_SHIFT            3
-#define MFC_REG_DISP_STATUS_RES_CHANGE_MASK            0x3
-#define MFC_REG_DISP_STATUS_RES_CHANGE_SHIFT           4
-#define MFC_REG_DISP_STATUS_NEED_DPB_CHANGE_MASK       0x1
-#define MFC_REG_DISP_STATUS_NEED_DPB_CHANGE_SHIFT      9
-#define MFC_REG_DISP_STATUS_NEED_SCRATCH_CHANGE_MASK   0x1
-#define MFC_REG_DISP_STATUS_NEED_SCRATCH_CHANGE_SHIFT  10
-#define MFC_REG_DISP_STATUS_NEED_EMPTY_DPB_MASK        0x1
-#define MFC_REG_DISP_STATUS_NEED_EMPTY_DPB_SHIFT       12
-#define MFC_REG_DISP_STATUS_BLACK_BAR_DETECT_MASK      0x3
-#define MFC_REG_DISP_STATUS_BLACK_BAR_DETECT_SHIFT     13
-#define MFC_REG_DISP_STATUS_NOT_DETECTED               0x0
-#define MFC_REG_DISP_STATUS_BLACK_BAR                  0x1
-#define MFC_REG_DISP_STATUS_BLACK_SCREEN               0x2
-
-
-/* 0xF618: MFC_REG_D_DISPLAY_FRAME_TYPE */
-#define MFC_REG_DISPLAY_FRAME_MASK                     0x7
-#define MFC_REG_DISPLAY_TEMP_INFO_MASK                 0x1
-#define MFC_REG_DISPLAY_TEMP_INFO_SHIFT                7
-#define MFC_REG_DISPLAY_FRAME_NOT_CODED                0
-#define MFC_REG_DISPLAY_FRAME_I                        1
-#define MFC_REG_DISPLAY_FRAME_P                        2
-#define MFC_REG_DISPLAY_FRAME_B                        3
-
-
-/* 0xF61C: MFC_REG_D_DISPLAY_CROP_INFO1 */
-#define MFC_REG_D_SHARED_CROP_LEFT_MASK                0xFFFF
-#define MFC_REG_D_SHARED_CROP_RIGHT_SHIFT              16
-
-
-/* 0xF620: MFC_REG_D_DISPLAY_CROP_INFO2 */
-#define MFC_REG_D_SHARED_CROP_TOP_MASK                 0xFFFF
-#define MFC_REG_D_SHARED_CROP_BOTTOM_SHIFT             16
-
-
-/* 0xF644: MFC_REG_D_DECODED_STATUS */
-#define MFC_REG_DEC_STATUS_DECODED_STATUS_MASK         0x7
-#define MFC_REG_DEC_STATUS_DECODING_ONLY               0
-#define MFC_REG_DEC_STATUS_DECODING_DISPLAY            1
-#define MFC_REG_DEC_STATUS_DISPLAY_ONLY                2
-#define MFC_REG_DEC_STATUS_DECODING_EMPTY              3
-#define MFC_REG_DEC_STATUS_NUM_OF_TILE_MASK            0xF
-#define MFC_REG_DEC_STATUS_NUM_OF_TILE_SHIFT           15
-
-
-/* 0xF654: MFC_REG_D_DECODED_FRAME_TYPE */
-#define MFC_REG_DECODED_FRAME_MASK                     0x7
-#define MFC_REG_DECODED_FRAME_NOT_CODED                0
-#define MFC_REG_DECODED_FRAME_I                        1
-#define MFC_REG_DECODED_FRAME_P                        2
-#define MFC_REG_DECODED_FRAME_B                        3
-
-
-/* 0xF660: MFC_REG_D_DECODED_PICTURE_PROFILE */
-#define MFC_REG_D_DECODED_PIC_PROFILE_MASK             0x1F
-#define MFC_REG_D_BIT_DEPTH_CHROMA_MINUS8_MASK         0x7
-#define MFC_REG_D_BIT_DEPTH_CHROMA_MINUS8_SHIFT        19
-#define MFC_REG_D_BIT_DEPTH_LUMA_MINUS8_MASK           0x7
-#define MFC_REG_D_BIT_DEPTH_LUMA_MINUS8_SHIFT          16
-#define MFC_REG_D_PROFILE_HEVC_MAIN                    1
-#define MFC_REG_D_PROFILE_HEVC_MAIN_10                 2
-#define MFC_REG_D_PROFILE_HEVC_RANGE_EXT               4
-
-
-/* 0xF684: MFC_REG_D_CHROMA_FORMAT */
-#define MFC_REG_D_CHROMA_FORMAT_MASK                   0x3
-#define MFC_REG_D_COLOR_RANGE_MASK                     0x1
-#define MFC_REG_D_COLOR_RANGE_SHIFT                    3
-#define MFC_REG_D_COLOR_SPACE_MASK                     0xF
-#define MFC_REG_D_COLOR_SPACE_SHIFT                    4
-#define MFC_REG_D_COLOR_UNKNOWN                        0
-#define MFC_REG_D_CHROMA_400                           0
-#define MFC_REG_D_CHROMA_420                           1
-#define MFC_REG_D_CHROMA_422                           2
-#define MFC_REG_D_CHROMA_444                           3
-
-
-/* 0xF690: MFC_REG_D_H264_INFO */
-#define MFC_REG_D_H264_INFO_MBAFF_FRAME_FLAG_SHIFT     9
-#define MFC_REG_D_H264_INFO_MBAFF_FRAME_FLAG_MASK      0x1
-
-
-/* 0xF6D8: MFC_REG_D_MVC_VIEW_ID */
-#define MFC_REG_D_MVC_VIEW_ID_DISP_MASK                0xFFFF
-
-
-/* 0xF6DC: MFC_REG_D_SEI_AVAIL */
-#define MFC_REG_D_SEI_AVAIL_FRAME_PACK_MASK            0x1
-#define MFC_REG_D_SEI_AVAIL_CONTENT_LIGHT_MASK         0x1
-#define MFC_REG_D_SEI_AVAIL_CONTENT_LIGHT_SHIFT        1
-#define MFC_REG_D_SEI_AVAIL_MASTERING_DISPLAY_MASK     0x1
-#define MFC_REG_D_SEI_AVAIL_MASTERING_DISPLAY_SHIFT    2
-
-
-/* 0xF70C: MFC_REG_D_VIDEO_SIGNAL_TYPE */
-#define MFC_REG_D_VIDEO_SIGNAL_TYPE_FLAG_MASK          0x1
-#define MFC_REG_D_VIDEO_SIGNAL_TYPE_FLAG_SHIFT         29
-#define MFC_REG_D_COLOUR_DESCRIPTION_FLAG_MASK         0x1
-#define MFC_REG_D_COLOUR_DESCRIPTION_FLAG_SHIFT        24
-
-
-/* 0xF738: MFC_REG_D_BLACK_BAR_START_POS */
-#define MFC_REG_D_BLACK_BAR_START_X_SHIFT              0
-#define MFC_REG_D_BLACK_BAR_START_X_MASK               0xFFFF
-#define MFC_REG_D_BLACK_BAR_START_Y_SHIFT              16
-#define MFC_REG_D_BLACK_BAR_START_Y_MASK               0xFFFF
-
-
-/* 0xF73C: MFC_REG_D_BLACK_BAR_IMAGE_SIZE */
-#define MFC_REG_D_BLACK_BAR_IMAGE_W_SHIFT              0
-#define MFC_REG_D_BLACK_BAR_IMAGE_W_MASK               0xFFFF
-#define MFC_REG_D_BLACK_BAR_IMAGE_H_SHIFT              16
-#define MFC_REG_D_BLACK_BAR_IMAGE_H_MASK               0xFFFF
-
-
-/* 0xF780:  MFC_REG_E_FRAME_CROP_OFFSET */
-#define MFC_REG_E_FRAME_CROP_OFFSET_TOP                16
-#define MFC_REG_E_FRAME_CROP_OFFSET_LEFT               0
-#define MFC_REG_E_FRAME_CROP_OFFSET_MASK               0x3FFF
-
-
-/* 0xF788: MFC_REG_E_PICTURE_PROFILE */
-#define MFC_REG_E_PROFILE_H264_BASELINE                0
-#define MFC_REG_E_PROFILE_H264_MAIN                    1
-#define MFC_REG_E_PROFILE_H264_HIGH                    2
-#define MFC_REG_E_PROFILE_H264_CONSTRAINED_BASELINE    3
-#define MFC_REG_E_PROFILE_H264_CONSTRAINED_HIGH        5
-#define MFC_REG_E_PROFILE_MPEG4_SIMPLE                 0
-#define MFC_REG_E_PROFILE_MPEG4_ADVANCED_SIMPLE        1
-#define MFC_REG_E_PROFILE_HEVC_MAIN_422_10_INTRA       2
-#define MFC_REG_E_PROFILE_HEVC_MAIN_10                 3
-#define MFC_REG_E_PROFILE_HEVC_MAIN_422_10             4
-#define MFC_REG_E_PROFILE_VP9_PROFILE0                 0
-#define MFC_REG_E_PROFILE_VP9_PROFILE1                 1
-#define MFC_REG_E_PROFILE_VP9_PROFILE2                 2
-#define MFC_REG_E_PROFILE_VP9_PROFILE3                 3
-
-
-/* 0xF7A4: MFC_REG_E_RC_MODE */
-#define MFC_REG_E_RC_CBR_FIX                           0
-#define MFC_REG_E_RC_CBR_VAR                           1
-#define MFC_REG_E_RC_VBR                               2
-#define MFC_REG_E_RC_CBR_I_LIMIT                       3
-
-
-/* 0xFA84: MFC_REG_E_SLICE_TYPE */
-#define MFC_REG_E_SLICE_TYPE_NOT_CODED                 0
-#define MFC_REG_E_SLICE_TYPE_I                         1
-#define MFC_REG_E_SLICE_TYPE_P                         2
-#define MFC_REG_E_SLICE_TYPE_B                         3
-#define MFC_REG_E_SLICE_TYPE_SKIPPED                   4
-
-
-#endif /* __REGS_MFC_V10_H */
index 0a7669b053b6a9462fcf399b0cb2c3f88c108128..b3a85415e45fd401e09de68d9f66e180d916c7ae 100644 (file)
@@ -12,7 +12,7 @@
 
 #include "mfc_sync.h"
 
-#include "mfc_cal.h"
+#include "mfc_hw_reg_api.h"
 #include "mfc_perf_measure.h"
 
 #include "mfc_queue.h"
index 0a10cfbf4d187225205ed97d46619d0c8c60e2e4..64a3d8e4352885d96806a0e8d23bdcf212d559f1 100644 (file)
@@ -19,8 +19,8 @@
 
 #include "mfc_pm.h"
 #include "mfc_cmd.h"
-#include "mfc_cal.h"
-#include "mfc_reg.h"
+#include "mfc_reg_api.h"
+#include "mfc_hw_reg_api.h"
 
 #include "mfc_queue.h"
 #include "mfc_utils.h"