From e9eb0f878b6c2173654d6d7780fd1babc427ccea Mon Sep 17 00:00:00 2001
From: "elel@3wh.net" <elel@3wh.net>
Date: Thu, 27 Dec 2018 14:37:10 +0000
Subject: [PATCH 5/5] Use Samsung MFC from A810

---
 drivers/media/platform/exynos/mfc/Kconfig     |    0
 drivers/media/platform/exynos/mfc/Makefile    |    0
 .../media/platform/exynos/mfc/regs-mfc-v5.h   |    3 +
 .../media/platform/exynos/mfc/regs-mfc-v6.h   |   34 +-
 .../media/platform/exynos/mfc/regs-mfc-v8.h   |   32 +-
 .../media/platform/exynos/mfc/regs-mfc-v9.h   |   42 +-
 drivers/media/platform/exynos/mfc/s5p_mfc.c   |  509 +++--
 .../media/platform/exynos/mfc/s5p_mfc_cmd.h   |    0
 .../platform/exynos/mfc/s5p_mfc_cmd_v5.c      |    0
 .../platform/exynos/mfc/s5p_mfc_cmd_v6.c      |    0
 .../platform/exynos/mfc/s5p_mfc_common.h      |  145 +-
 .../media/platform/exynos/mfc/s5p_mfc_ctrl.c  |   42 +-
 .../media/platform/exynos/mfc/s5p_mfc_ctrl.h  |    0
 .../media/platform/exynos/mfc/s5p_mfc_debug.h |    7 -
 .../media/platform/exynos/mfc/s5p_mfc_dec.c   |  170 +-
 .../media/platform/exynos/mfc/s5p_mfc_dec.h   |    2 +-
 .../media/platform/exynos/mfc/s5p_mfc_enc.c   | 1764 +++++++++++++----
 .../media/platform/exynos/mfc/s5p_mfc_enc.h   |    2 +-
 .../media/platform/exynos/mfc/s5p_mfc_inst.c  |    0
 .../media/platform/exynos/mfc/s5p_mfc_inst.h  |    0
 .../media/platform/exynos/mfc/s5p_mfc_intr.c  |    0
 .../media/platform/exynos/mfc/s5p_mfc_intr.h  |    0
 .../media/platform/exynos/mfc/s5p_mfc_mem.c   |    0
 .../media/platform/exynos/mfc/s5p_mfc_mem.h   |    0
 .../platform/exynos/mfc/s5p_mfc_opr_v5.c      |    4 +-
 .../platform/exynos/mfc/s5p_mfc_opr_v5.h      |    1 +
 .../platform/exynos/mfc/s5p_mfc_opr_v6.c      | 1154 ++++++-----
 .../platform/exynos/mfc/s5p_mfc_opr_v6.h      |    1 +
 .../platform/exynos/mfc/s5p_mfc_opr_v8.h      |    1 +
 .../platform/exynos/mfc/s5p_mfc_opr_v9.h      |   25 -
 .../media/platform/exynos/mfc/s5p_mfc_pm.c    |    0
 .../media/platform/exynos/mfc/s5p_mfc_pm.h    |    0
 .../media/platform/exynos/mfc/s5p_mfc_qos.c   |   15 +-
 .../media/platform/exynos/mfc/s5p_mfc_reg.c   |    0
 .../media/platform/exynos/mfc/s5p_mfc_reg.h   |    0
 .../media/platform/exynos/mfc/s5p_mfc_shm.c   |    0
 .../media/platform/exynos/mfc/s5p_mfc_shm.h   |    0
 include/uapi/linux/v4l2-controls.h            |    6 +-
 include/uapi/linux/videodev2_exynos_media.h   |  128 +-
 39 files changed, 2820 insertions(+), 1267 deletions(-)
 mode change 100644 => 100755 drivers/media/platform/exynos/mfc/Kconfig
 mode change 100644 => 100755 drivers/media/platform/exynos/mfc/Makefile
 mode change 100644 => 100755 drivers/media/platform/exynos/mfc/regs-mfc-v5.h
 mode change 100644 => 100755 drivers/media/platform/exynos/mfc/regs-mfc-v6.h
 mode change 100644 => 100755 drivers/media/platform/exynos/mfc/regs-mfc-v8.h
 mode change 100644 => 100755 drivers/media/platform/exynos/mfc/regs-mfc-v9.h
 mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc.c
 mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_cmd.h
 mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_cmd_v5.c
 mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_cmd_v6.c
 mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_common.h
 mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_ctrl.c
 mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_ctrl.h
 mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_debug.h
 mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_dec.c
 mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_dec.h
 mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_enc.c
 mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_enc.h
 mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_inst.c
 mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_inst.h
 mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_intr.c
 mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_intr.h
 mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_mem.c
 mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_mem.h
 mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_opr_v5.c
 mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_opr_v5.h
 mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_opr_v6.c
 mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_opr_v6.h
 mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_opr_v8.h
 mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_opr_v9.h
 mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_pm.c
 mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_pm.h
 mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_qos.c
 mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_reg.c
 mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_reg.h
 mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_shm.c
 mode change 100644 => 100755 drivers/media/platform/exynos/mfc/s5p_mfc_shm.h
 mode change 100644 => 100755 include/uapi/linux/v4l2-controls.h
 mode change 100644 => 100755 include/uapi/linux/videodev2_exynos_media.h

diff --git a/drivers/media/platform/exynos/mfc/Kconfig b/drivers/media/platform/exynos/mfc/Kconfig
old mode 100644
new mode 100755
diff --git a/drivers/media/platform/exynos/mfc/Makefile b/drivers/media/platform/exynos/mfc/Makefile
old mode 100644
new mode 100755
diff --git a/drivers/media/platform/exynos/mfc/regs-mfc-v5.h b/drivers/media/platform/exynos/mfc/regs-mfc-v5.h
old mode 100644
new mode 100755
index d7a16b816b88..1e63a2f79548
--- a/drivers/media/platform/exynos/mfc/regs-mfc-v5.h
+++ b/drivers/media/platform/exynos/mfc/regs-mfc-v5.h
@@ -128,6 +128,7 @@
 #define S5P_FIMV_ENC_PROFILE_H264_HIGH                 1
 #define S5P_FIMV_ENC_PROFILE_H264_BASELINE             2
 #define S5P_FIMV_ENC_PROFILE_H264_CONSTRAINED_BASELINE 3
+#define S5P_FIMV_ENC_PROFILE_H264_CONSTRAINED_HIGH     5
 #define S5P_FIMV_ENC_PROFILE_MPEG4_SIMPLE              0
 #define S5P_FIMV_ENC_PROFILE_MPEG4_ADVANCED_SIMPLE     1
 #define S5P_FIMV_ENC_PIC_STRUCT		0x083c /* picture field/frame flag */
@@ -398,6 +399,8 @@ static inline unsigned int r2h_bits(int cmd)
 #define S5P_FIMV_MFC_VERSION			0
 #define S5P_FIMV_ERR_FRAME_CONCEAL		-1
 #define S5P_FIMV_R2H_CMD_DPB_FLUSH_RET		-2
+#define S5P_FIMV_E_H264_HD_SVC_EXTENSION_0	-1
+#define S5P_FIMV_E_H264_HD_SVC_EXTENSION_1	-1
 
 /* for compatibility */
 #define S5P_FIMV_E_GOP_CONFIG2		-1
diff --git a/drivers/media/platform/exynos/mfc/regs-mfc-v6.h b/drivers/media/platform/exynos/mfc/regs-mfc-v6.h
old mode 100644
new mode 100755
index bce2f1571dc2..15f83e965b76
--- a/drivers/media/platform/exynos/mfc/regs-mfc-v6.h
+++ b/drivers/media/platform/exynos/mfc/regs-mfc-v6.h
@@ -140,6 +140,8 @@ static inline unsigned int r2h_bits(int cmd)
 #define S5P_FIMV_RET_INSTANCE_ID		0xF070
 
 #define S5P_FIMV_ERROR_CODE			0xF074
+#define S5P_FIMV_ERR_HEADER_NOT_FOUND		102
+#define S5P_FIMV_ERR_SYNC_POINT_NOT_RECEIVED	190
 #define S5P_FIMV_ERR_WARNINGS_START		160
 #define S5P_FIMV_ERR_WARNINGS_END		222
 #define S5P_FIMV_ERR_DEC_MASK			0xFFFF
@@ -173,6 +175,7 @@ static inline unsigned int r2h_bits(int cmd)
 
 #define S5P_FIMV_D_SEI_ENABLE			0xF0C4
 #define S5P_FIMV_D_SEI_NEED_INIT_BUFFER_SHIFT	1
+#define S5P_FIMV_D_SEI_RECOVERY_PARSING_ENABLE	2
 
 /* Buffer setting registers */
 #define S5P_FIMV_D_MIN_NUM_DPB			0xF0F0
@@ -337,6 +340,7 @@ static inline unsigned int r2h_bits(int cmd)
 #define S5P_FIMV_ENC_PROFILE_H264_MAIN                 1
 #define S5P_FIMV_ENC_PROFILE_H264_HIGH                 2
 #define S5P_FIMV_ENC_PROFILE_H264_CONSTRAINED_BASELINE 3
+#define S5P_FIMV_ENC_PROFILE_H264_CONSTRAINED_HIGH     5
 #define S5P_FIMV_ENC_PROFILE_MPEG4_SIMPLE              0
 #define S5P_FIMV_ENC_PROFILE_MPEG4_ADVANCED_SIMPLE     1
 #define S5P_FIMV_E_FIXED_PICTURE_QP		0xF790
@@ -405,12 +409,15 @@ static inline unsigned int r2h_bits(int cmd)
 
 #define S5P_FIMV_E_MPEG4_OPTIONS		0xFB10
 #define S5P_FIMV_E_MPEG4_HEC_PERIOD		0xFB14
+
+#define S5P_FIMV_E_H264_HD_SVC_EXTENSION_0	0xFB44
+#define S5P_FIMV_E_H264_HD_SVC_EXTENSION_1	0xFB48
+#define S5P_FIMV_E_H264_OPTIONS_2		0xFB4C
 #define S5P_FIMV_E_ASPECT_RATIO			0xFB50
 #define S5P_FIMV_E_EXTENDED_SAR			0xFB54
 
 #define S5P_FIMV_E_IDR_H264_IDR			0
 #define S5P_FIMV_E_H264_OPTIONS			0xFB58
-#define S5P_FIMV_E_H264_OPTIONS_2		0xFB4C
 #define S5P_FIMV_E_H264_LF_ALPHA_OFFSET		0xFB5C
 #define S5P_FIMV_E_H264_LF_BETA_OFFSET		0xFB60
 #define S5P_FIMV_E_H264_I_PERIOD		0xFB64
@@ -432,13 +439,10 @@ static inline unsigned int r2h_bits(int cmd)
 #define S5P_FIMV_E_H264_ASO_SLICE_ORDER_5	0xFB9C
 #define S5P_FIMV_E_H264_ASO_SLICE_ORDER_6	0xFBA0
 #define S5P_FIMV_E_H264_ASO_SLICE_ORDER_7	0xFBA4
+#define S5P_FIMV_E_H264_CHROMA_QP_OFFSET	0xFBA8
 
 #define S5P_FIMV_E_NUM_T_LAYER			0xFBAC
 
-/* For backward compatibility */
-#define S5P_FIMV_E_H264_CHROMA_QP_OFFSET	0xFBA8
-#define S5P_FIMV_E_H264_NUM_T_LAYER		S5P_FIMV_E_NUM_T_LAYER
-
 #define S5P_FIMV_E_HIERARCHICAL_QP_LAYER0	0xFBB0
 #define S5P_FIMV_E_HIERARCHICAL_QP_LAYER1	0xFBB4
 #define S5P_FIMV_E_HIERARCHICAL_QP_LAYER2	0xFBB8
@@ -448,23 +452,8 @@ static inline unsigned int r2h_bits(int cmd)
 #define S5P_FIMV_E_HIERARCHICAL_QP_LAYER6	0xFBC8
 
 /* For backward compatibility */
-#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER0	S5P_FIMV_E_HIERARCHICAL_QP_LAYER0
-#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER1	S5P_FIMV_E_HIERARCHICAL_QP_LAYER1
-#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER2	S5P_FIMV_E_HIERARCHICAL_QP_LAYER2
-#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER3	S5P_FIMV_E_HIERARCHICAL_QP_LAYER3
-#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER4	S5P_FIMV_E_HIERARCHICAL_QP_LAYER4
-#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER5	S5P_FIMV_E_HIERARCHICAL_QP_LAYER5
-#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER6	S5P_FIMV_E_HIERARCHICAL_QP_LAYER6
-
 #define S5P_FIMV_E_H264_FRAME_PACKING_SEI_INFO	0xFC4C
 
-#define S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER0	S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER0
-#define S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER1	S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER1
-#define S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER2	S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER2
-#define S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER3	S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER3
-#define S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER4	S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER4
-#define S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER5	S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER5
-#define S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER6	S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER6
 #define S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER0	0xFD18
 #define S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER1	0xFD1C
 #define S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER2	0xFD20
@@ -828,11 +817,6 @@ static inline unsigned int r2h_bits(int cmd)
 #define S5P_FIMV_E_VP8_OPTION			0xFDB0
 #define S5P_FIMV_E_VP8_FILTER_OPTIONS		0xFDB4
 #define S5P_FIMV_E_VP8_GOLDEN_FRAME_OPTION	0xFDB8
-/* For backward compatibility */
-#define S5P_FIMV_E_VP8_NUM_T_LAYER		S5P_FIMV_E_NUM_T_LAYER
-#define S5P_FIMV_E_VP8_HIERARCHICAL_QP_LAYER0	S5P_FIMV_E_HIERARCHICAL_QP_LAYER0
-#define S5P_FIMV_E_VP8_HIERARCHICAL_QP_LAYER1	S5P_FIMV_E_HIERARCHICAL_QP_LAYER1
-#define S5P_FIMV_E_VP8_HIERARCHICAL_QP_LAYER2	S5P_FIMV_E_HIERARCHICAL_QP_LAYER2
 /* for compatibility */
 #define S5P_FIMV_E_HEVC_OPTIONS			-1
 #define S5P_FIMV_E_HEVC_REFRESH_PERIOD		-1
diff --git a/drivers/media/platform/exynos/mfc/regs-mfc-v8.h b/drivers/media/platform/exynos/mfc/regs-mfc-v8.h
old mode 100644
new mode 100755
index 53c38ba1f1ca..195df530aa8e
--- a/drivers/media/platform/exynos/mfc/regs-mfc-v8.h
+++ b/drivers/media/platform/exynos/mfc/regs-mfc-v8.h
@@ -144,6 +144,8 @@ static inline unsigned int r2h_bits(int cmd)
 #define S5P_FIMV_RET_INSTANCE_ID		0xF070
 #define S5P_FIMV_ERROR_CODE			0xF074
 
+#define S5P_FIMV_ERR_HEADER_NOT_FOUND		102
+#define S5P_FIMV_ERR_SYNC_POINT_NOT_RECEIVED	190
 #define S5P_FIMV_ERR_WARNINGS_START		160
 #define S5P_FIMV_ERR_WARNINGS_END		222
 #define S5P_FIMV_ERR_DEC_MASK			0xFFFF
@@ -178,6 +180,7 @@ static inline unsigned int r2h_bits(int cmd)
 
 #define S5P_FIMV_D_SEI_ENABLE			0xF0C4
 #define S5P_FIMV_D_SEI_NEED_INIT_BUFFER_SHIFT	1
+#define S5P_FIMV_D_SEI_RECOVERY_PARSING_ENABLE	2
 
 /* Buffer setting registers */
 /* Session return */
@@ -372,6 +375,7 @@ static inline unsigned int r2h_bits(int cmd)
 #define S5P_FIMV_ENC_PROFILE_H264_MAIN                 1
 #define S5P_FIMV_ENC_PROFILE_H264_HIGH                 2
 #define S5P_FIMV_ENC_PROFILE_H264_CONSTRAINED_BASELINE 3
+#define S5P_FIMV_ENC_PROFILE_H264_CONSTRAINED_HIGH     5
 #define S5P_FIMV_ENC_PROFILE_MPEG4_SIMPLE              0
 #define S5P_FIMV_ENC_PROFILE_MPEG4_ADVANCED_SIMPLE     1
 #define S5P_FIMV_E_FIXED_PICTURE_QP		0xF794
@@ -453,6 +457,9 @@ static inline unsigned int r2h_bits(int cmd)
 
 #define S5P_FIMV_E_MPEG4_OPTIONS		0xFB10
 #define S5P_FIMV_E_MPEG4_HEC_PERIOD		0xFB14
+
+#define S5P_FIMV_E_H264_HD_SVC_EXTENSION_0	0xFB44
+#define S5P_FIMV_E_H264_HD_SVC_EXTENSION_1	0xFB48
 #define S5P_FIMV_E_ASPECT_RATIO			0xFB4C
 #define S5P_FIMV_E_EXTENDED_SAR			0xFB50
 
@@ -480,13 +487,10 @@ static inline unsigned int r2h_bits(int cmd)
 #define S5P_FIMV_E_H264_ASO_SLICE_ORDER_5	0xFB9C
 #define S5P_FIMV_E_H264_ASO_SLICE_ORDER_6	0xFBA0
 #define S5P_FIMV_E_H264_ASO_SLICE_ORDER_7	0xFBA4
+#define S5P_FIMV_E_H264_CHROMA_QP_OFFSET	0xFBA8
 
 #define S5P_FIMV_E_NUM_T_LAYER			0xFBAC
 
-/* For backward compatibility */
-#define S5P_FIMV_E_H264_CHROMA_QP_OFFSET	0xFBA8
-#define S5P_FIMV_E_H264_NUM_T_LAYER		S5P_FIMV_E_NUM_T_LAYER
-
 #define S5P_FIMV_E_HIERARCHICAL_QP_LAYER0	0xFBB0
 #define S5P_FIMV_E_HIERARCHICAL_QP_LAYER1	0xFBB4
 #define S5P_FIMV_E_HIERARCHICAL_QP_LAYER2	0xFBB8
@@ -496,23 +500,8 @@ static inline unsigned int r2h_bits(int cmd)
 #define S5P_FIMV_E_HIERARCHICAL_QP_LAYER6	0xFBC8
 
 /* For backward compatibility */
-#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER0	S5P_FIMV_E_HIERARCHICAL_QP_LAYER0
-#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER1	S5P_FIMV_E_HIERARCHICAL_QP_LAYER1
-#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER2	S5P_FIMV_E_HIERARCHICAL_QP_LAYER2
-#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER3	S5P_FIMV_E_HIERARCHICAL_QP_LAYER3
-#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER4	S5P_FIMV_E_HIERARCHICAL_QP_LAYER4
-#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER5	S5P_FIMV_E_HIERARCHICAL_QP_LAYER5
-#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER6	S5P_FIMV_E_HIERARCHICAL_QP_LAYER6
-
 #define S5P_FIMV_E_H264_FRAME_PACKING_SEI_INFO	0xFC4C
 
-#define S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER0	S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER0
-#define S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER1	S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER1
-#define S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER2	S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER2
-#define S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER3	S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER3
-#define S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER4	S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER4
-#define S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER5	S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER5
-#define S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER6	S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER6
 #define S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER0	0xFD18
 #define S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER1	0xFD1C
 #define S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER2	0xFD20
@@ -531,11 +520,6 @@ static inline unsigned int r2h_bits(int cmd)
 #define S5P_FIMV_E_VP8_OPTION			0xFDB0
 #define S5P_FIMV_E_VP8_FILTER_OPTIONS		0xFDB4
 #define S5P_FIMV_E_VP8_GOLDEN_FRAME_OPTION	0xFDB8
-/* For backward compatibility */
-#define S5P_FIMV_E_VP8_NUM_T_LAYER		S5P_FIMV_E_NUM_T_LAYER
-#define S5P_FIMV_E_VP8_HIERARCHICAL_QP_LAYER0	S5P_FIMV_E_HIERARCHICAL_QP_LAYER0
-#define S5P_FIMV_E_VP8_HIERARCHICAL_QP_LAYER1	S5P_FIMV_E_HIERARCHICAL_QP_LAYER1
-#define S5P_FIMV_E_VP8_HIERARCHICAL_QP_LAYER2	S5P_FIMV_E_HIERARCHICAL_QP_LAYER2
 /* for compatibility */
 #define S5P_FIMV_E_HEVC_OPTIONS			-1
 #define S5P_FIMV_E_HEVC_REFRESH_PERIOD		-1
diff --git a/drivers/media/platform/exynos/mfc/regs-mfc-v9.h b/drivers/media/platform/exynos/mfc/regs-mfc-v9.h
old mode 100644
new mode 100755
index 5dab5fc9a45e..dbfb8933e42d
--- a/drivers/media/platform/exynos/mfc/regs-mfc-v9.h
+++ b/drivers/media/platform/exynos/mfc/regs-mfc-v9.h
@@ -75,6 +75,7 @@
 #define S5P_FIMV_R2H_CMD_FRAME_DONE_RET		13
 #define S5P_FIMV_R2H_CMD_FIELD_DONE_RET		14
 #define S5P_FIMV_R2H_CMD_SLICE_DONE_RET		15
+#define S5P_FIMV_R2H_CMD_ENC_BUFFER_FULL_RET	16
 #define S5P_FIMV_R2H_CMD_CACHE_FLUSH_RET	20
 #define S5P_FIMV_R2H_CMD_ERR_RET		32
 
@@ -100,7 +101,8 @@ static inline unsigned int h2r_to_r2h_bits(int cmd)
 	case S5P_FIMV_CH_FRAME_START:
 		mask |= (R2H_BIT(S5P_FIMV_R2H_CMD_FRAME_DONE_RET) |
 			 R2H_BIT(S5P_FIMV_R2H_CMD_FIELD_DONE_RET) |
-			 R2H_BIT(S5P_FIMV_R2H_CMD_SLICE_DONE_RET));
+			 R2H_BIT(S5P_FIMV_R2H_CMD_SLICE_DONE_RET) |
+			 R2H_BIT(S5P_FIMV_R2H_CMD_ENC_BUFFER_FULL_RET));
 		break;
 	case S5P_FIMV_CH_LAST_FRAME:
 		mask |= R2H_BIT(S5P_FIMV_R2H_CMD_FRAME_DONE_RET);
@@ -118,7 +120,8 @@ static inline unsigned int r2h_bits(int cmd)
 		mask |= (R2H_BIT(S5P_FIMV_R2H_CMD_FIELD_DONE_RET) |
 			 R2H_BIT(S5P_FIMV_R2H_CMD_COMPLETE_SEQ_RET) |
 			 R2H_BIT(S5P_FIMV_R2H_CMD_SLICE_DONE_RET) |
-			 R2H_BIT(S5P_FIMV_R2H_CMD_INIT_BUFFERS_RET));
+			 R2H_BIT(S5P_FIMV_R2H_CMD_INIT_BUFFERS_RET) |
+			 R2H_BIT(S5P_FIMV_R2H_CMD_ENC_BUFFER_FULL_RET));
 	/* FIXME: Temporal mask for S3D SEI processing */
 	else if (cmd == S5P_FIMV_R2H_CMD_INIT_BUFFERS_RET)
 		mask |= (R2H_BIT(S5P_FIMV_R2H_CMD_FIELD_DONE_RET) |
@@ -150,6 +153,9 @@ static inline unsigned int r2h_bits(int cmd)
 #define S5P_FIMV_RET_INSTANCE_ID		0xF070
 #define S5P_FIMV_ERROR_CODE			0xF074
 
+#define S5P_FIMV_ERR_HEADER_NOT_FOUND		102
+#define S5P_FIMV_ERR_SYNC_POINT_NOT_RECEIVED	190
+#define S5P_FIMV_ERR_NON_PAIRED_FIELD		191
 #define S5P_FIMV_ERR_WARNINGS_START		160
 #define S5P_FIMV_ERR_WARNINGS_END		222
 #define S5P_FIMV_ERR_DEC_MASK			0xFFFF
@@ -176,6 +182,7 @@ static inline unsigned int r2h_bits(int cmd)
 #define S5P_FIMV_D_OPT_TILE_MODE_SHIFT		0
 #define S5P_FIMV_D_OPT_DYNAMIC_DPB_SET_SHIFT	3
 #define S5P_FIMV_D_OPT_NOT_CODED_SET_SHIFT	4
+#define S5P_FIMV_D_OPT_SPECIAL_PARSING_SHIFT	15
 
 #define S5P_FIMV_D_DISPLAY_DELAY		0xF0B8
 
@@ -184,6 +191,7 @@ static inline unsigned int r2h_bits(int cmd)
 
 #define S5P_FIMV_D_SEI_ENABLE			0xF0C4
 #define S5P_FIMV_D_SEI_NEED_INIT_BUFFER_SHIFT	1
+#define S5P_FIMV_D_SEI_RECOVERY_PARSING_ENABLE	2
 
 /* Buffer setting registers */
 /* Session return */
@@ -367,6 +375,7 @@ static inline unsigned int r2h_bits(int cmd)
 #define S5P_FIMV_ENC_PROFILE_H264_MAIN                 1
 #define S5P_FIMV_ENC_PROFILE_H264_HIGH                 2
 #define S5P_FIMV_ENC_PROFILE_H264_CONSTRAINED_BASELINE 3
+#define S5P_FIMV_ENC_PROFILE_H264_CONSTRAINED_HIGH     5
 #define S5P_FIMV_ENC_PROFILE_MPEG4_SIMPLE              0
 #define S5P_FIMV_ENC_PROFILE_MPEG4_ADVANCED_SIMPLE     1
 #define S5P_FIMV_E_FIXED_PICTURE_QP		0xF794
@@ -457,6 +466,9 @@ static inline unsigned int r2h_bits(int cmd)
 
 #define S5P_FIMV_E_MPEG4_OPTIONS		0xFB10
 #define S5P_FIMV_E_MPEG4_HEC_PERIOD		0xFB14
+
+#define S5P_FIMV_E_H264_HD_SVC_EXTENSION_0	0xFB44
+#define S5P_FIMV_E_H264_HD_SVC_EXTENSION_1	0xFB48
 #define S5P_FIMV_E_ASPECT_RATIO			0xFB4C
 #define S5P_FIMV_E_EXTENDED_SAR			0xFB50
 
@@ -485,13 +497,10 @@ static inline unsigned int r2h_bits(int cmd)
 #define S5P_FIMV_E_H264_ASO_SLICE_ORDER_5	0xFB9C
 #define S5P_FIMV_E_H264_ASO_SLICE_ORDER_6	0xFBA0
 #define S5P_FIMV_E_H264_ASO_SLICE_ORDER_7	0xFBA4
+#define S5P_FIMV_E_H264_CHROMA_QP_OFFSET	0xFBA8
 
 #define S5P_FIMV_E_NUM_T_LAYER			0xFBAC
 
-/* For backward compatibility */
-#define S5P_FIMV_E_H264_CHROMA_QP_OFFSET	0xFBA8
-#define S5P_FIMV_E_H264_NUM_T_LAYER		S5P_FIMV_E_NUM_T_LAYER
-
 #define S5P_FIMV_E_HIERARCHICAL_QP_LAYER0	0xFBB0
 #define S5P_FIMV_E_HIERARCHICAL_QP_LAYER1	0xFBB4
 #define S5P_FIMV_E_HIERARCHICAL_QP_LAYER2	0xFBB8
@@ -501,24 +510,9 @@ static inline unsigned int r2h_bits(int cmd)
 #define S5P_FIMV_E_HIERARCHICAL_QP_LAYER6	0xFBC8
 
 /* For backward compatibility */
-#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER0	S5P_FIMV_E_HIERARCHICAL_QP_LAYER0
-#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER1	S5P_FIMV_E_HIERARCHICAL_QP_LAYER1
-#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER2	S5P_FIMV_E_HIERARCHICAL_QP_LAYER2
-#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER3	S5P_FIMV_E_HIERARCHICAL_QP_LAYER3
-#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER4	S5P_FIMV_E_HIERARCHICAL_QP_LAYER4
-#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER5	S5P_FIMV_E_HIERARCHICAL_QP_LAYER5
-#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER6	S5P_FIMV_E_HIERARCHICAL_QP_LAYER6
-
 #define S5P_FIMV_E_H264_FRAME_PACKING_SEI_INFO	0xFC4C
 
 #define S5P_FIMV_E_H264_NAL_CONTROL		0xFD14
-#define S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER0	S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER0
-#define S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER1	S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER1
-#define S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER2	S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER2
-#define S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER3	S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER3
-#define S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER4	S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER4
-#define S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER5	S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER5
-#define S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER6	S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER6
 #define S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER0	0xFD18
 #define S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER1	0xFD1C
 #define S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER2	0xFD20
@@ -538,12 +532,6 @@ static inline unsigned int r2h_bits(int cmd)
 #define S5P_FIMV_E_VP8_FILTER_OPTIONS		0xFDB4
 #define S5P_FIMV_E_VP8_GOLDEN_FRAME_OPTION	0xFDB8
 
-/* For backward compatibility */
-#define S5P_FIMV_E_VP8_NUM_T_LAYER		S5P_FIMV_E_NUM_T_LAYER
-#define S5P_FIMV_E_VP8_HIERARCHICAL_QP_LAYER0	S5P_FIMV_E_HIERARCHICAL_QP_LAYER0
-#define S5P_FIMV_E_VP8_HIERARCHICAL_QP_LAYER1	S5P_FIMV_E_HIERARCHICAL_QP_LAYER1
-#define S5P_FIMV_E_VP8_HIERARCHICAL_QP_LAYER2	S5P_FIMV_E_HIERARCHICAL_QP_LAYER2
-
 #define S5P_FIMV_E_HEVC_OPTIONS			0xFDD4
 #define S5P_FIMV_E_HEVC_REFRESH_PERIOD		0xFDD8
 #define S5P_FIMV_E_HEVC_CHROMA_QP_OFFSET	0xFDDC
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc.c b/drivers/media/platform/exynos/mfc/s5p_mfc.c
old mode 100644
new mode 100755
index 5b07d11ec5b7..3ff3d4c7d0a3
--- a/drivers/media/platform/exynos/mfc/s5p_mfc.c
+++ b/drivers/media/platform/exynos/mfc/s5p_mfc.c
@@ -160,20 +160,21 @@ int exynos_mfc_sysmmu_fault_handler(struct iommu_domain *iodmn, struct device *d
 /*
  * A framerate table determines framerate by the interval(us) of each frame.
  * Framerate is not accurate, just rough value to seperate overload section.
- * Base line of each section are selected from 25fps(40000us), 45fps(22222us)
- * and 100fps(10000us).
+ * Base line of each section are selected from 40fps(25000us), 80fps(12500us),
+ * 145fps(6940us) and 205fps(4860us).
  *
- * interval(us) | 0           10000         22222         40000           |
- * framerate    |     120fps    |    60fps    |    30fps    |    25fps    |
+ * interval(us) | 0         4860          6940          12500         25000          |
+ * framerate    |    240fps   |    180fps   |    120fps   |    60fps    |    30fps   |
  */
 
 #define COL_FRAME_RATE		0
 #define COL_FRAME_INTERVAL	1
 static unsigned long framerate_table[][2] = {
-	{ 25000, 40000 },
-	{ 30000, 22222 },
-	{ 60000, 10000 },
-	{ 120000, 0 },
+	{ 30000, 25000 },
+	{ 60000, 12500 },
+	{ 120000, 6940 },
+	{ 180000, 4860 },
+	{ 240000, 0 },
 };
 
 static inline unsigned long timeval_diff(struct timeval *to,
@@ -280,6 +281,7 @@ int get_framerate_by_timestamp(struct s5p_mfc_ctx *ctx, struct v4l2_buffer *buf)
 
 	if (list_empty(&ctx->ts_list)) {
 		dec_add_timestamp(ctx, buf, &ctx->ts_list);
+		return get_framerate_by_interval(0);
 	} else {
 		found = 0;
 		list_for_each_entry_reverse(temp_ts, &ctx->ts_list, list) {
@@ -324,6 +326,12 @@ int get_framerate_by_timestamp(struct s5p_mfc_ctx *ctx, struct v4l2_buffer *buf)
 				min_interval, max_framerate);
 	}
 
+	if (!ctx->ts_is_full) {
+		if (debug_ts == 1)
+			mfc_info_ctx("ts doesn't full, keep %d fps\n", ctx->framerate);
+		return ctx->framerate;
+	}
+
 	return max_framerate;
 }
 
@@ -557,10 +565,8 @@ static int s5p_mfc_check_hw_state(struct s5p_mfc_dev *dev)
 	clk_state = mfc_check_clock_state(dev);
 	mfc_disp_dev_state(dev);
 
-	if (!pwr_state || !clk_state)
-		mfc_err("power or clock state is unstable\n");
-
-	s5p_mfc_dump_regs(dev);
+	if (pwr_state && clk_state)
+		s5p_mfc_dump_regs(dev);
 
 	return 0;
 }
@@ -725,7 +731,7 @@ static void s5p_mfc_handle_frame_all_extracted(struct s5p_mfc_ctx *ctx)
 	struct s5p_mfc_dev *dev;
 	struct s5p_mfc_buf *dst_buf;
 	int index, is_first = 1;
-	unsigned int interlace_type, is_interlace = 0;
+	unsigned int interlace_type = 0, is_interlace = 0;
 
 	if (!ctx) {
 		mfc_err("no mfc context to run\n");
@@ -809,7 +815,9 @@ static void mfc_check_ref_frame(struct s5p_mfc_ctx *ctx,
 {
 	struct s5p_mfc_dec *dec = ctx->dec_priv;
 	struct s5p_mfc_buf *ref_buf, *tmp_buf;
+	struct list_head *dst_list;
 	int index;
+	int found = 0;
 
 	list_for_each_entry_safe(ref_buf, tmp_buf, ref_list, list) {
 		index = ref_buf->vb.v4l2_buf.index;
@@ -825,9 +833,26 @@ static void mfc_check_ref_frame(struct s5p_mfc_ctx *ctx,
 			clear_bit(index, &dec->dpb_status);
 			mfc_debug(2, "Move buffer[%d], fd[%d] to dst queue\n",
 					index, dec->assigned_fd[index]);
+			found = 1;
 			break;
 		}
 	}
+
+	if (is_h264(ctx) && !found) {
+		dst_list = &ctx->dst_queue;
+		list_for_each_entry_safe(ref_buf, tmp_buf, dst_list, list) {
+			index = ref_buf->vb.v4l2_buf.index;
+			if (index == ref_index && ref_buf->already) {
+				dec->assigned_fd[index] =
+					ref_buf->vb.v4l2_planes[0].m.fd;
+				clear_bit(index, &dec->dpb_status);
+				mfc_debug(2, "re-assigned buffer[%d], fd[%d] for H264\n",
+						index, dec->assigned_fd[index]);
+				found = 1;
+				break;
+			}
+		}
+	}
 }
 
 /* Process the released reference information */
@@ -844,11 +869,17 @@ static void mfc_handle_released_info(struct s5p_mfc_ctx *ctx,
 	if (released_flag) {
 		for (t = 0; t < MFC_MAX_DPBS; t++) {
 			if (released_flag & (1 << t)) {
-				mfc_debug(2, "Release FD[%d] = %03d !! ",
-						t, dec->assigned_fd[t]);
-				refBuf->dpb[ncount].fd[0] = dec->assigned_fd[t];
+				if (dec->err_sync_flag & (1 << t)) {
+					mfc_debug(2, "Released, but reuse. FD[%d] = %03d\n",
+							t, dec->assigned_fd[t]);
+					dec->err_sync_flag &= ~(1 << t);
+				} else {
+					mfc_debug(2, "Release FD[%d] = %03d\n",
+							t, dec->assigned_fd[t]);
+					refBuf->dpb[ncount].fd[0] = dec->assigned_fd[t];
+					ncount++;
+				}
 				dec->assigned_fd[t] = MFC_INFO_INIT_FD;
-				ncount++;
 				mfc_check_ref_frame(ctx, dst_queue_addr, t);
 			}
 		}
@@ -906,7 +937,7 @@ static void s5p_mfc_handle_frame_new(struct s5p_mfc_ctx *ctx, unsigned int err)
 	dma_addr_t dspl_y_addr;
 	unsigned int index;
 	unsigned int frame_type;
-	unsigned int interlace_type, is_interlace = 0;
+	unsigned int interlace_type = 0, is_interlace = 0;
 	int mvc_view_id;
 	unsigned int dst_frame_status, last_frame_status;
 	struct list_head *dst_queue_addr;
@@ -994,6 +1025,24 @@ static void s5p_mfc_handle_frame_new(struct s5p_mfc_ctx *ctx, unsigned int err)
 		if (s5p_mfc_mem_plane_addr(ctx, &dst_buf->vb, 0)
 							== dspl_y_addr) {
 			index = dst_buf->vb.v4l2_buf.index;
+			if (ctx->codec_mode == S5P_FIMV_CODEC_VC1RCV_DEC &&
+				s5p_mfc_err_dspl(err) == S5P_FIMV_ERR_SYNC_POINT_NOT_RECEIVED) {
+				if (released_flag & (1 << index)) {
+					list_del(&dst_buf->list);
+					dec->ref_queue_cnt--;
+					list_add_tail(&dst_buf->list, &ctx->dst_queue);
+					ctx->dst_queue_cnt++;
+					dec->dpb_status &= ~(1 << index);
+					released_flag &= ~(1 << index);
+					mfc_debug(2, "SYNC_POINT_NOT_RECEIVED, released.\n");
+				} else {
+					dec->err_sync_flag |= 1 << index;
+					mfc_debug(2, "SYNC_POINT_NOT_RECEIVED, used.\n");
+				}
+				dec->dynamic_used |= released_flag;
+				break;
+			}
+
 			list_del(&dst_buf->list);
 
 			if (dec->is_dynamic_dpb)
@@ -1024,7 +1073,8 @@ static void s5p_mfc_handle_frame_new(struct s5p_mfc_ctx *ctx, unsigned int err)
 			dst_buf->vb.v4l2_buf.flags &=
 					~(V4L2_BUF_FLAG_KEYFRAME |
 					V4L2_BUF_FLAG_PFRAME |
-					V4L2_BUF_FLAG_BFRAME);
+					V4L2_BUF_FLAG_BFRAME |
+					V4L2_BUF_FLAG_ERROR);
 
 			switch (frame_type) {
 			case S5P_FIMV_DISPLAY_FRAME_I:
@@ -1043,9 +1093,12 @@ static void s5p_mfc_handle_frame_new(struct s5p_mfc_ctx *ctx, unsigned int err)
 				break;
 			}
 
-			if (s5p_mfc_err_dspl(err))
+			if (s5p_mfc_err_dspl(err)) {
 				mfc_err_ctx("Warning for displayed frame: %d\n",
 							s5p_mfc_err_dspl(err));
+				dst_buf->vb.v4l2_buf.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");
@@ -1142,19 +1195,6 @@ static void s5p_mfc_handle_frame_new(struct s5p_mfc_ctx *ctx, unsigned int err)
 	}
 }
 
-static int s5p_mfc_find_start_code(unsigned char *src_mem, unsigned int remainSize)
-{
-	unsigned int index = 0;
-
-	for (index = 0; index < remainSize - 3; index++) {
-		if ((src_mem[index] == 0x00) && (src_mem[index+1] == 0x00) &&
-				(src_mem[index+2] == 0x01))
-			return index;
-	}
-
-	return -1;
-}
-
 static void s5p_mfc_handle_frame_error(struct s5p_mfc_ctx *ctx,
 		unsigned int reason, unsigned int err)
 {
@@ -1306,6 +1346,52 @@ static void s5p_mfc_handle_ref_frame(struct s5p_mfc_ctx *ctx)
 	}
 }
 
+static void s5p_mfc_move_reuse_buffer(struct s5p_mfc_ctx *ctx, int release_index)
+{
+	struct s5p_mfc_dec *dec = ctx->dec_priv;
+	struct s5p_mfc_buf *ref_mb, *tmp_mb;
+	int index;
+
+	list_for_each_entry_safe(ref_mb, tmp_mb, &dec->ref_queue, list) {
+		index = ref_mb->vb.v4l2_buf.index;
+		if (index == release_index) {
+			ref_mb->used = 0;
+
+			list_del(&ref_mb->list);
+			dec->ref_queue_cnt--;
+
+			list_add_tail(&ref_mb->list, &ctx->dst_queue);
+			ctx->dst_queue_cnt++;
+
+			clear_bit(index, &dec->dpb_status);
+			mfc_debug(2, "buffer[%d] is moved to dst queue for reuse\n", index);
+		}
+	}
+}
+
+static void s5p_mfc_handle_reuse_buffer(struct s5p_mfc_ctx *ctx)
+{
+	struct s5p_mfc_dev *dev = ctx->dev;
+	struct s5p_mfc_dec *dec = ctx->dec_priv;
+	unsigned int prev_flag, released_flag = 0;
+	int i;
+
+	if (!dec->is_dynamic_dpb)
+		return;
+
+	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))
+			s5p_mfc_move_reuse_buffer(ctx, i);
+}
+
 /* Handle frame decoding interrupt */
 static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx,
 					unsigned int reason, unsigned int err)
@@ -1399,9 +1485,23 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx,
 	/* All frames remaining in the buffer have been extracted  */
 	if (dst_frame_status == S5P_FIMV_DEC_STATUS_DECODING_EMPTY) {
 		if (ctx->state == MFCINST_RES_CHANGE_FLUSH) {
+			struct mfc_timestamp *temp_ts = NULL;
+
 			mfc_debug(2, "Last frame received after resolution change.\n");
 			s5p_mfc_handle_frame_all_extracted(ctx);
 			ctx->state = MFCINST_RES_CHANGE_END;
+
+			/* 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;
+			ctx->last_framerate = 0;
+			ctx->framerate = DEC_MAX_FPS;
+
 			goto leave_handle_frame;
 		} else {
 			s5p_mfc_handle_frame_all_extracted(ctx);
@@ -1410,12 +1510,18 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx,
 
 	if (dec->is_dynamic_dpb) {
 		switch (dst_frame_status) {
-		case S5P_FIMV_DEC_STATUS_DECODING_ONLY:
-			dec->dynamic_used |= mfc_get_dec_used_flag();
-			/* Fall through */
 		case S5P_FIMV_DEC_STATUS_DECODING_DISPLAY:
 			s5p_mfc_handle_ref_frame(ctx);
 			break;
+		case S5P_FIMV_DEC_STATUS_DECODING_ONLY:
+			s5p_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.
+			 */
+			s5p_mfc_handle_reuse_buffer(ctx);
+			break;
 		default:
 			break;
 		}
@@ -1444,52 +1550,23 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx,
 		dec->consumed += s5p_mfc_get_consumed_stream();
 		remained = (unsigned int)(src_buf->vb.v4l2_planes[0].bytesused - dec->consumed);
 
-		if ((prev_offset == 0) && dec->is_packedpb && remained > STUFF_BYTE &&
-			dec->consumed < src_buf->vb.v4l2_planes[0].bytesused &&
-			s5p_mfc_get_dec_frame_type() ==
-						S5P_FIMV_DECODED_FRAME_P) {
-			unsigned char *stream_vir;
-			int offset = 0;
-
+		if ((dec->consumed > 0) && (remained > STUFF_BYTE) && (err == 0) &&
+				(src_buf->vb.v4l2_planes[0].bytesused > dec->consumed)) {
 			/* Run MFC again on the same buffer */
 			mfc_debug(2, "Running again the same buffer.\n");
 
-			if (IS_MFCv7X(dev) && dec->is_dual_dpb)
-				dec->y_addr_for_pb = mfc_get_dec_first_addr();
-			else
+			if (dec->is_packedpb)
 				dec->y_addr_for_pb = (dma_addr_t)MFC_GET_ADR(DEC_DECODED_Y);
 
-			spin_unlock_irqrestore(&dev->irqlock, flags);
-			stream_vir = vb2_plane_vaddr(&src_buf->vb, 0);
-			s5p_mfc_mem_inv_vb(&src_buf->vb, 1);
-			spin_lock_irqsave(&dev->irqlock, flags);
-
-			if (ctx->codec_mode != S5P_FIMV_CODEC_VP9_DEC) {
-				offset = s5p_mfc_find_start_code(
-						stream_vir + dec->consumed, remained);
-			}
-
-			if (offset > STUFF_BYTE)
-				dec->consumed += offset;
-
-#if 0
-			s5p_mfc_set_dec_stream_buffer(ctx,
-				src_buf->planes.stream, dec->consumed,
-				src_buf->vb.v4l2_planes[0].bytesused -
-							dec->consumed);
-			dev->curr_ctx = ctx->num;
-			dev->curr_ctx_drm = ctx->is_drm;
-			s5p_mfc_clean_ctx_int_flags(ctx);
-			s5p_mfc_clear_int_flags();
-			wake_up_ctx(ctx, reason, err);
-			spin_unlock_irqrestore(&dev->irqlock, flags);
-			s5p_mfc_decode_one_frame(ctx, 0);
-			return;
-#else
 			dec->remained_size = src_buf->vb.v4l2_planes[0].bytesused -
 							dec->consumed;
 			/* Do not move src buffer to done_list */
-#endif
+		} else if (s5p_mfc_err_dec(err) == S5P_FIMV_ERR_NON_PAIRED_FIELD) {
+			/*
+			 * For non-paired field, the same buffer need to be
+			 * resumitted and the consumed stream will be 0
+			 */
+			mfc_debug(2, "Not paired field. Running again the same buffer.\n");
 		} else {
 			index = src_buf->vb.v4l2_buf.index;
 			if (call_cop(ctx, recover_buf_ctrls_val, ctx, &ctx->src_ctrls[index]) < 0)
@@ -1548,32 +1625,50 @@ static inline void s5p_mfc_handle_error(struct s5p_mfc_ctx *ctx,
 
 	mfc_err_ctx("Interrupt Error: %d\n", err);
 	s5p_mfc_clear_int_flags();
-	wake_up_dev(dev, reason, err);
 
 	/* Error recovery is dependent on the state of context */
 	switch (ctx->state) {
-	case MFCINST_INIT:
-		/* This error had to happen while acquireing instance */
+	case MFCINST_RES_CHANGE_END:
 	case MFCINST_GOT_INST:
-		/* This error had to happen while parsing vps only */
+		/* This error had to happen while parsing the header */
 		if (err == S5P_FIMV_VPS_ONLY_ERROR) {
 			ctx->state = MFCINST_VPS_PARSED_ONLY;
 			if (!list_empty(&ctx->src_queue)) {
-				src_buf = list_entry(ctx->src_queue.next, struct s5p_mfc_buf,
-						list);
+				src_buf = list_entry(ctx->src_queue.next,
+						struct s5p_mfc_buf, list);
 				list_del(&src_buf->list);
 				ctx->src_queue_cnt--;
 				vb2_buffer_done(&src_buf->vb, VB2_BUF_STATE_DONE);
 			}
+		} else if (!ctx->is_drm) {
+			unsigned char *stream_vir = NULL;
+			unsigned int strm_size = 0;
+			spin_lock_irqsave(&dev->irqlock, flags);
+			if (!list_empty(&ctx->src_queue)) {
+				src_buf = list_entry(ctx->src_queue.next,
+						struct s5p_mfc_buf, list);
+				stream_vir = src_buf->vir_addr;
+				strm_size = src_buf->vb.v4l2_planes[0].bytesused;
+				if (strm_size > 32)
+					strm_size = 32;
+			}
+			spin_unlock_irqrestore(&dev->irqlock, flags);
+			if (stream_vir && strm_size)
+				print_hex_dump(KERN_ERR, "No header: ",
+						DUMP_PREFIX_ADDRESS, strm_size, 4,
+						stream_vir, strm_size, false);
 		}
-	case MFCINST_RES_CHANGE_END:
-		/* This error had to happen while parsing the header */
+	case MFCINST_INIT:
+		/* This error had to happen while acquireing instance */
 	case MFCINST_HEAD_PARSED:
 		/* This error had to happen while setting dst buffers */
 	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 */
 		clear_work_bit(ctx);
 		if (clear_hw_bit(ctx) == 0)
 			BUG();
@@ -1611,9 +1706,31 @@ static inline void s5p_mfc_handle_error(struct s5p_mfc_ctx *ctx,
 
 		break;
 	}
+	wake_up_dev(dev, reason, err);
+
 	return;
 }
 
+static irqreturn_t s5p_mfc_top_half_irq(int irq, void *priv)
+{
+	struct s5p_mfc_dev *dev = priv;
+	struct s5p_mfc_ctx *ctx;
+	unsigned int err;
+	unsigned int reason;
+
+	ctx = dev->ctx[dev->curr_ctx];
+	if (!ctx)
+		mfc_err("no mfc context to run\n");
+
+	reason = s5p_mfc_get_int_reason();
+	err = s5p_mfc_get_int_err();
+	mfc_debug(2, "[c:%d] Int reason: %d (err: %d)\n",
+			dev->curr_ctx, reason, err);
+	MFC_TRACE_DEV("<< Int reason(top): %d\n", reason);
+
+	return IRQ_WAKE_THREAD;
+}
+
 /* Interrupt processing */
 static irqreturn_t s5p_mfc_irq(int irq, void *priv)
 {
@@ -1625,6 +1742,7 @@ static irqreturn_t s5p_mfc_irq(int irq, void *priv)
 	unsigned int reason;
 	unsigned int err;
 	unsigned long flags;
+	unsigned int reg = 0;
 
 	mfc_debug_enter();
 
@@ -1696,19 +1814,87 @@ static irqreturn_t s5p_mfc_irq(int irq, void *priv)
 	case S5P_FIMV_R2H_CMD_FIELD_DONE_RET:
 	case S5P_FIMV_R2H_CMD_FRAME_DONE_RET:
 	case S5P_FIMV_R2H_CMD_COMPLETE_SEQ_RET:
+	case S5P_FIMV_R2H_CMD_ENC_BUFFER_FULL_RET:
 		if (ctx->type == MFCINST_DECODER) {
+			if (ctx->state == MFCINST_SPECIAL_PARSING_NAL) {
+				s5p_mfc_clear_int_flags();
+				spin_lock_irq(&dev->condlock);
+				clear_bit(ctx->num, &dev->ctx_work_bits);
+				spin_unlock_irq(&dev->condlock);
+				ctx->state =  MFCINST_RUNNING;
+				if (clear_hw_bit(ctx) == 0)
+					BUG();
+				s5p_mfc_clock_off(dev);
+				wake_up_ctx(ctx, reason, err);
+				goto done;
+			}
 			s5p_mfc_handle_frame(ctx, reason, err);
 		} else if (ctx->type == MFCINST_ENCODER) {
 			if (reason == S5P_FIMV_R2H_CMD_SLICE_DONE_RET) {
 				dev->preempt_ctx = ctx->num;
+				enc->buf_full = 0;
 				enc->in_slice = 1;
+			} else if (reason == S5P_FIMV_R2H_CMD_ENC_BUFFER_FULL_RET) {
+				mfc_err_ctx("stream buffer size(%d) isn't enough\n",
+						s5p_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;
 			}
 
 			if (ctx->c_ops->post_frame_start) {
-				if (ctx->c_ops->post_frame_start(ctx))
-					mfc_err_ctx("post_frame_start() failed\n");
+				if (ctx->enc_res_change || ctx->enc_res_change_state) {
+					/* Right after the first NAL_START finished with the new resolution,
+					 * We need to reset the fields
+					 */
+					if (ctx->enc_res_change) {
+						reg = s5p_mfc_read_reg(dev, S5P_FIMV_E_PARAM_CHANGE);
+						reg &= ~(0x7 << 6); /* clear resolution change bits */
+						s5p_mfc_write_reg(dev, reg, S5P_FIMV_E_PARAM_CHANGE);
+
+						ctx->enc_res_change_state = ctx->enc_res_change;
+						ctx->enc_res_change = 0;
+					}
+
+					if (ctx->enc_res_change_state == 1) { /* resolution swap */
+						ctx->enc_res_change_state = 0;
+					} else if (ctx->enc_res_change_state == 2) { /* resolution change */
+						reg = s5p_mfc_read_reg(dev, S5P_FIMV_E_NAL_DONE_INFO);
+						reg = (reg & (0x3 << 4)) >> 4;
+
+						mfc_debug(2, "Encoding Resolution Status : %d\n", reg);
+
+						if (reg == 1) { /* Resolution Change for B-frame */
+							/* Encode with previous resolution */
+							/* NOTHING TO-DO */
+						} else if (reg == 2) { /* Resolution Change for B-frame */
+							s5p_mfc_release_codec_buffers(ctx);
+							ctx->state = MFCINST_HEAD_PARSED; /* for INIT_BUFFER cmd */
+
+							ctx->enc_res_change_state = 0;
+							ctx->min_scratch_buf_size = s5p_mfc_read_reg(dev, S5P_FIMV_E_MIN_SCRATCH_BUFFER_SIZE);
+							mfc_debug(2, "S5P_FIMV_E_MIN_SCRATCH_BUFFER_SIZE = 0x%x\n",
+								(unsigned int)ctx->min_scratch_buf_size);
+						} else if (reg == 3) { /* Resolution Change for only P-frame */
+							s5p_mfc_release_codec_buffers(ctx);
+							ctx->state = MFCINST_HEAD_PARSED; /* for INIT_BUFFER cmd */
+
+							ctx->enc_res_change_state = 0;
+							ctx->min_scratch_buf_size = s5p_mfc_read_reg(dev, S5P_FIMV_E_MIN_SCRATCH_BUFFER_SIZE);
+							ctx->enc_res_change_re_input = 1;
+							mfc_debug(2, "S5P_FIMV_E_MIN_SCRATCH_BUFFER_SIZE = 0x%x\n",
+								(unsigned int)ctx->min_scratch_buf_size);
+						}
+					}
+					if (ctx->c_ops->post_frame_start(ctx))
+						mfc_err_ctx("post_frame_start() failed\n");
+				} else {
+					if (ctx->c_ops->post_frame_start(ctx))
+						mfc_err_ctx("post_frame_start() failed\n");
+				}
 
 				s5p_mfc_clear_int_flags();
 				if (clear_hw_bit(ctx) == 0)
@@ -1797,8 +1983,18 @@ static irqreturn_t s5p_mfc_irq(int irq, void *priv)
 		goto irq_cleanup_hw;
 		break;
 	case S5P_FIMV_R2H_CMD_NAL_ABORT_RET:
-		ctx->state = MFCINST_ABORT;
-		clear_work_bit(ctx);
+		if (ctx->type == MFCINST_ENCODER) {
+			ctx->state = MFCINST_RUNNING_BUF_FULL;
+			enc->buf_full = 0;
+			if (ctx->codec_mode == S5P_FIMV_CODEC_VP8_ENC)
+				mfc_err_ctx("stream buffer size isn't enough\n");
+			if (ctx->c_ops->post_frame_start)
+				if (ctx->c_ops->post_frame_start(ctx))
+					mfc_err_ctx("post_frame_start() failed\n");
+		} else {
+			ctx->state = MFCINST_ABORT;
+			clear_work_bit(ctx);
+		}
 		if (clear_hw_bit(ctx) == 0)
 			BUG();
 		goto irq_cleanup_hw;
@@ -2197,8 +2393,8 @@ static int s5p_mfc_open(struct file *file)
 		}
 	}
 
-	mfc_info_ctx("MFC open completed [%d:%d] dev = %p, ctx = %p\n",
-			dev->num_drm_inst, dev->num_inst, dev, ctx);
+	mfc_info_ctx("MFC open completed [%d:%d] dev = %p, ctx = %p, version = %d\n",
+			dev->num_drm_inst, dev->num_inst, dev, ctx, MFC_DRIVER_INFO);
 	mutex_unlock(&dev->mfc_mutex);
 	return ret;
 
@@ -2270,19 +2466,14 @@ err_no_device:
 	return ret;
 }
 
-#define need_to_wait_frame_start(ctx)		\
-	(((ctx->state == MFCINST_FINISHING) ||	\
-	  (ctx->state == MFCINST_RUNNING)) &&	\
-	 test_bit(ctx->num, &ctx->dev->hw_lock))
 /* Release MFC context */
 static int s5p_mfc_release(struct file *file)
 {
 	struct s5p_mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
 	struct s5p_mfc_dev *dev = NULL;
 	struct s5p_mfc_enc *enc = NULL;
-#ifdef CONFIG_EXYNOS_CONTENT_PATH_PROTECTION
 	int ret = 0;
-#endif
+
 	dev = ctx->dev;
 	if (!dev) {
 		mfc_err("no mfc device to run\n");
@@ -2294,22 +2485,33 @@ static int s5p_mfc_release(struct file *file)
 	mfc_info_ctx("MFC driver release is called [%d:%d], is_drm(%d)\n",
 			dev->num_drm_inst, dev->num_inst, ctx->is_drm);
 
-	if (need_to_wait_frame_start(ctx)) {
-		ctx->state = MFCINST_ABORT;
+	spin_lock_irq(&dev->condlock);
+	set_bit(ctx->num, &dev->ctx_stop_bits);
+	clear_bit(ctx->num, &dev->ctx_work_bits);
+	spin_unlock_irq(&dev->condlock);
+
+	/* If a H/W operation is in progress, wait for it complete */
+	if (need_to_wait_nal_abort(ctx)) {
 		if (s5p_mfc_wait_for_done_ctx(ctx,
-				S5P_FIMV_R2H_CMD_FRAME_DONE_RET))
+				S5P_FIMV_R2H_CMD_NAL_ABORT_RET))
 			s5p_mfc_cleanup_timeout(ctx);
+	} else if (test_bit(ctx->num, &dev->hw_lock)) {
+		ret = wait_event_timeout(ctx->queue,
+				(test_bit(ctx->num, &dev->hw_lock) == 0),
+				msecs_to_jiffies(MFC_INT_TIMEOUT));
+		if (ret == 0)
+			mfc_err_ctx("wait for event failed\n");
 	}
 
 	if (ctx->type == MFCINST_ENCODER) {
 		enc = ctx->enc_priv;
 		if (!enc) {
 			mfc_err_ctx("no mfc encoder to run\n");
-			mutex_unlock(&dev->mfc_mutex);
-			return -EINVAL;
+			ret = -EINVAL;
+			goto err_release;
 		}
 
-		if (enc->in_slice) {
+		if (enc->in_slice || enc->buf_full) {
 			ctx->state = MFCINST_ABORT_INST;
 			spin_lock_irq(&dev->condlock);
 			set_bit(ctx->num, &dev->ctx_work_bits);
@@ -2320,6 +2522,7 @@ static int s5p_mfc_release(struct file *file)
 				s5p_mfc_cleanup_timeout(ctx);
 
 			enc->in_slice = 0;
+			enc->buf_full = 0;
 		}
 	}
 
@@ -2362,77 +2565,36 @@ static int s5p_mfc_release(struct file *file)
 	if (!atomic_read(&dev->watchdog_run) &&
 		(ctx->inst_no != MFC_NO_INSTANCE_SET)) {
 		/* Wait for hw_lock == 0 for this context */
-		wait_event_timeout(ctx->queue,
-				(test_bit(ctx->num, &dev->hw_lock) == 0),
+		ret = wait_event_timeout(ctx->queue,
+				(dev->hw_lock == 0),
 				msecs_to_jiffies(MFC_INT_SHORT_TIMEOUT));
+		if (ret == 0) {
+			mfc_err_ctx("Waiting for hardware to finish timed out\n");
+			ret = -EBUSY;
+			goto err_release;
+		}
 
+		s5p_mfc_clean_ctx_int_flags(ctx);
 		ctx->state = MFCINST_RETURN_INST;
 		spin_lock_irq(&dev->condlock);
 		set_bit(ctx->num, &dev->ctx_work_bits);
 		spin_unlock_irq(&dev->condlock);
 
 		/* To issue the command 'CLOSE_INSTANCE' */
-		s5p_mfc_clean_ctx_int_flags(ctx);
 		s5p_mfc_try_run(dev);
 
 		/* Wait until instance is returned or timeout occured */
 		if (s5p_mfc_wait_for_done_ctx(ctx,
-				S5P_FIMV_R2H_CMD_CLOSE_INSTANCE_RET)) {
-			dev->curr_ctx_drm = ctx->is_drm;
-			set_bit(ctx->num, &dev->hw_lock);
-			s5p_mfc_clock_on(dev);
-			s5p_mfc_close_inst(ctx);
+				S5P_FIMV_R2H_CMD_CLOSE_INSTANCE_RET) == 1) {
+			mfc_err_ctx("It was expired to wait for a CLOSE_INSTANCE\n");
 			if (s5p_mfc_wait_for_done_ctx(ctx,
-				S5P_FIMV_R2H_CMD_CLOSE_INSTANCE_RET)) {
-				mfc_err_ctx("Abnormal h/w state.\n");
-
-				/* cleanup for the next open */
-				if (dev->curr_ctx == ctx->num)
-					clear_bit(ctx->num, &dev->hw_lock);
-				if (ctx->is_drm)
-					dev->num_drm_inst--;
-				dev->num_inst--;
-
-				mfc_info_dev("Failed to release MFC inst[%d:%d]\n",
-						dev->num_drm_inst, dev->num_inst);
-
-#ifdef CONFIG_EXYNOS_CONTENT_PATH_PROTECTION
-				if (ctx->is_drm && dev->num_drm_inst == 0) {
-					ret = s5p_mfc_secmem_isolate_and_protect(0);
-					if (ret)
-						mfc_err("Failed to unprotect secure memory\n");
-				}
-#endif
-				if (dev->num_inst == 0) {
-					s5p_mfc_deinit_hw(dev);
-					del_timer_sync(&dev->watchdog_timer);
-
-					flush_workqueue(dev->sched_wq);
-
-					s5p_mfc_clock_off(dev);
-					mfc_debug(2, "power off\n");
-					s5p_mfc_power_off(dev);
-
-					s5p_mfc_release_dev_context_buffer(dev);
-					dev->drm_fw_status = 0;
-
-#ifdef CONFIG_EXYNOS_CONTENT_PATH_PROTECTION
-					if (dev->is_support_smc) {
-						s5p_mfc_release_sec_pgtable(dev);
-						dev->is_support_smc = 0;
-					}
-#endif
-				} else {
-					s5p_mfc_clock_off(dev);
-				}
-
-
-				mutex_unlock(&dev->mfc_mutex);
-
-				return -EIO;
+					S5P_FIMV_R2H_CMD_CLOSE_INSTANCE_RET)) {
+				mfc_err_ctx("It was once more expired. stop H/W\n");
+				s5p_mfc_check_hw_state(dev);
+				/* Stop */
+				BUG();
 			}
 		}
-
 		ctx->inst_no = MFC_NO_INSTANCE_SET;
 	}
 	/* hardware locking scheme */
@@ -2490,6 +2652,11 @@ static int s5p_mfc_release(struct file *file)
 		enc_cleanup_user_shared_handle(ctx);
 		kfree(ctx->enc_priv);
 	}
+
+	spin_lock_irq(&dev->condlock);
+	clear_bit(ctx->num, &dev->ctx_stop_bits);
+	spin_unlock_irq(&dev->condlock);
+
 	dev->ctx[ctx->num] = 0;
 	kfree(ctx);
 
@@ -2499,6 +2666,15 @@ static int s5p_mfc_release(struct file *file)
 	mutex_unlock(&dev->mfc_mutex);
 
 	return 0;
+
+err_release:
+	spin_lock_irq(&dev->condlock);
+	clear_bit(ctx->num, &dev->ctx_stop_bits);
+	spin_unlock_irq(&dev->condlock);
+
+	mutex_unlock(&dev->mfc_mutex);
+
+	return ret;
 }
 
 /* Poll */
@@ -2788,8 +2964,8 @@ static int s5p_mfc_probe(struct platform_device *pdev)
 		goto err_res_irq;
 	}
 	dev->irq = res->start;
-	ret = request_threaded_irq(dev->irq, NULL, s5p_mfc_irq, IRQF_ONESHOT, pdev->name,
-									dev);
+	ret = request_threaded_irq(dev->irq, s5p_mfc_top_half_irq, s5p_mfc_irq,
+			IRQF_ONESHOT, pdev->name, dev);
 	if (ret != 0) {
 		dev_err(&pdev->dev, "failed to install irq (%d)\n", ret);
 		goto err_req_irq;
@@ -3164,8 +3340,6 @@ static int s5p_mfc_suspend(struct device *dev)
 {
 	struct s5p_mfc_dev *m_dev = platform_get_drvdata(to_platform_device(dev));
 	int ret;
-	int i = 0;
-	struct s5p_mfc_ctx *ctx = NULL;
 
 	if (!m_dev) {
 		mfc_err("no mfc device to run\n");
@@ -3175,20 +3349,6 @@ static int s5p_mfc_suspend(struct device *dev)
 	if (m_dev->num_inst == 0)
 		return 0;
 
-	ctx = m_dev->ctx[m_dev->curr_ctx];
-	if (!ctx) {//may be, we got the instance just after release
-		for(i = 0; i < MFC_NUM_CONTEXTS; i++)
-		{
-			ctx = m_dev->ctx[i];
-			if(ctx)
-			{
-				mfc_info_ctx("MFC Find a not null ctx, and the curr_ctx changed to %d\n",i);
-				m_dev->curr_ctx = i;
-				break;
-			}
-		}
-	}
-
 	ret = s5p_mfc_sleep(m_dev);
 
 	return ret;
@@ -3365,6 +3525,7 @@ static struct platform_driver s5p_mfc_driver = {
 		.owner	= THIS_MODULE,
 		.pm	= &s5p_mfc_pm_ops,
 		.of_match_table = exynos_mfc_match,
+		.suppress_bind_attrs = true,
 	},
 };
 
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_cmd.h b/drivers/media/platform/exynos/mfc/s5p_mfc_cmd.h
old mode 100644
new mode 100755
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_cmd_v5.c b/drivers/media/platform/exynos/mfc/s5p_mfc_cmd_v5.c
old mode 100644
new mode 100755
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_cmd_v6.c b/drivers/media/platform/exynos/mfc/s5p_mfc_cmd_v6.c
old mode 100644
new mode 100755
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_common.h b/drivers/media/platform/exynos/mfc/s5p_mfc_common.h
old mode 100644
new mode 100755
index 38797515a390..78ebff85a12d
--- a/drivers/media/platform/exynos/mfc/s5p_mfc_common.h
+++ b/drivers/media/platform/exynos/mfc/s5p_mfc_common.h
@@ -37,6 +37,8 @@
 #include <linux/pm_qos.h>
 #endif
 
+#define MFC_DRIVER_INFO		180315
+
 #define MFC_MAX_BUFFERS		32
 #define MFC_MAX_REF_BUFS	2
 #define MFC_FRAME_PLANES	2
@@ -47,15 +49,15 @@
 #define MFC_NUM_CONTEXTS	32
 #define MFC_MAX_DRM_CTX		2
 /* Interrupt timeout */
-#define MFC_INT_TIMEOUT		2000
+#define MFC_INT_TIMEOUT		15000
 /* Interrupt short timeout */
-#define MFC_INT_SHORT_TIMEOUT	800
+#define MFC_INT_SHORT_TIMEOUT	3000
 /* Busy wait timeout */
 #define MFC_BW_TIMEOUT		500
 /* Watchdog interval */
 #define MFC_WATCHDOG_INTERVAL   1000
 /* After how many executions watchdog should assume lock up */
-#define MFC_WATCHDOG_CNT        5
+#define MFC_WATCHDOG_CNT        15
 
 #define MFC_NO_INSTANCE_SET	-1
 
@@ -71,6 +73,7 @@
 #define MFC_BASE_MASK		((1 << 17) - 1)
 
 #define FLAG_LAST_FRAME		0x80000000
+#define FLAG_CSD		0x20000000
 #define MFC_MAX_INTERVAL	(2 * USEC_PER_SEC)
 
 /* Maximum number of temporal layers */
@@ -125,7 +128,7 @@ enum s5p_mfc_inst_state {
 	MFCINST_INIT = 100,
 	MFCINST_GOT_INST,
 	MFCINST_HEAD_PARSED,
-	MFCINST_BUFS_SET,
+	MFCINST_RUNNING_BUF_FULL,
 	MFCINST_RUNNING,
 	MFCINST_FINISHING,
 	MFCINST_FINISHED,
@@ -139,6 +142,8 @@ enum s5p_mfc_inst_state {
 	MFCINST_ABORT_INST,
 	MFCINST_DPB_FLUSHING,
 	MFCINST_VPS_PARSED_ONLY,
+	MFCINST_SPECIAL_PARSING,
+	MFCINST_SPECIAL_PARSING_NAL,
 };
 
 /**
@@ -182,15 +187,6 @@ enum mfc_buf_usage_type {
 	MFCBUF_DRM,
 };
 
-enum mfc_buf_process_type {
-	MFCBUFPROC_DEFAULT 		= 0x0,
-	MFCBUFPROC_COPY 		= (1 << 0),
-	MFCBUFPROC_SHARE 		= (1 << 1),
-	MFCBUFPROC_META 		= (1 << 2),
-	MFCBUFPROC_ANBSHARE		= (1 << 3),
-	MFCBUFPROC_ANBSHARE_NV12L	= (1 << 4),
-};
-
 struct s5p_mfc_ctx;
 struct s5p_mfc_extra_buf;
 struct s5p_mfc_dev;
@@ -237,6 +233,7 @@ struct s5p_mfc_buf {
 	int used;
 	int already;
 	int consumed;
+	unsigned char *vir_addr;
 };
 
 #define vb_to_mfc_buf(x)	\
@@ -363,6 +360,7 @@ struct s5p_mfc_dev {
 	int curr_ctx;
 	int preempt_ctx;
 	unsigned long ctx_work_bits;
+	unsigned long ctx_stop_bits;
 
 	atomic_t watchdog_cnt;
 	atomic_t watchdog_run;
@@ -434,6 +432,10 @@ struct s5p_mfc_h264_enc_params {
 	u8 rc_frame_qp;
 	u8 rc_min_qp;
 	u8 rc_max_qp;
+	u8 rc_min_qp_p;
+	u8 rc_max_qp_p;
+	u8 rc_min_qp_b;
+	u8 rc_max_qp_b;
 	u8 rc_mb_dark;
 	u8 rc_mb_smooth;
 	u8 rc_mb_static;
@@ -446,11 +448,12 @@ struct s5p_mfc_h264_enc_params {
 	u16 ext_sar_height;
 	u8 open_gop;
 	u16 open_gop_size;
-	u8 hier_qp;
+	u8 hier_qp_enable;
 	enum v4l2_mpeg_video_h264_hierarchical_coding_type hier_qp_type;
-	u8 hier_qp_layer;
-	u8 hier_qp_layer_qp[7];
-	u32 hier_qp_layer_bit[7];
+	u8 num_hier_layer;
+	u8 hier_ref_type;
+	u8 hier_qp_layer[7];
+	u32 hier_bit_layer[7];
 	u8 sei_gen_enable;
 	u8 sei_fp_curr_frame_0;
 	enum v4l2_mpeg_video_h264_sei_fp_arrangement_type sei_fp_arrangement_type;
@@ -464,6 +467,11 @@ struct s5p_mfc_h264_enc_params {
 	u32 aso_slice_order[8];
 
 	u32 prepend_sps_pps_to_idr;
+	u8 enable_ltr;
+	u8 num_of_ltr;
+	u32 set_priority;
+	u32 base_priority;
+	u32 vui_enable;
 };
 
 /**
@@ -482,6 +490,10 @@ struct s5p_mfc_mpeg4_enc_params {
 	u8 rc_frame_qp;
 	u8 rc_min_qp;
 	u8 rc_max_qp;
+	u8 rc_min_qp_p;
+	u8 rc_max_qp_p;
+	u8 rc_min_qp_b;
+	u8 rc_max_qp_b;
 	u8 rc_p_frame_qp;
 };
 
@@ -494,19 +506,21 @@ struct s5p_mfc_vp8_enc_params {
 	u8 vp8_version;
 	u8 rc_min_qp;
 	u8 rc_max_qp;
+	u8 rc_min_qp_p;
+	u8 rc_max_qp_p;
 	u8 rc_frame_qp;
 	u8 rc_p_frame_qp;
 	u8 vp8_numberofpartitions;
 	u8 vp8_filterlevel;
 	u8 vp8_filtersharpness;
 	u8 vp8_goldenframesel;
-	u8 vp8_gfrefreshperiod;
-	u8 hierarchy_qp_enable;
-	u8 hier_qp_layer_qp[3];
-	u32 hier_qp_layer_bit[3];
+	u16 vp8_gfrefreshperiod;
+	u8 hier_qp_enable;
+	u8 hier_qp_layer[3];
+	u32 hier_bit_layer[3];
 	u8 num_refs_for_p;
 	u8 intra_4x4mode_disable;
-	u8 num_temporal_layer;
+	u8 num_hier_layer;
 };
 
 /**
@@ -519,6 +533,10 @@ struct s5p_mfc_hevc_enc_params {
 	u32 rc_framerate;
 	u8 rc_min_qp;
 	u8 rc_max_qp;
+	u8 rc_min_qp_p;
+	u8 rc_max_qp_p;
+	u8 rc_min_qp_b;
+	u8 rc_max_qp_b;
 	u8 rc_lcu_dark;
 	u8 rc_lcu_smooth;
 	u8 rc_lcu_static;
@@ -529,11 +547,9 @@ struct s5p_mfc_hevc_enc_params {
 	u8 max_partition_depth;
 	u8 num_refs_for_p;
 	u8 refreshtype;
-	u8 refreshperiod;
-	s8 croma_qp_offset_cr;
-	s8 croma_qp_offset_cb;
-	s8 lf_beta_offset_div2;
-	s8 lf_tc_offset_div2;
+	u16 refreshperiod;
+	s32 lf_beta_offset_div2;
+	s32 lf_tc_offset_div2;
 	u8 loopfilter_disable;
 	u8 loopfilter_across;
 	u8 nal_control_length_filed;
@@ -542,12 +558,13 @@ struct s5p_mfc_hevc_enc_params {
 	u8 const_intra_period_enable;
 	u8 lossless_cu_enable;
 	u8 wavefront_enable;
-	u8 longterm_ref_enable;
-	u8 hier_qp;
-	u8 hier_qp_type;
-	u8 hier_qp_layer;
-	u8 hier_qp_layer_qp;
-	u8 hier_qp_layer_bit;
+	u8 enable_ltr;
+	u8 hier_qp_enable;
+	enum v4l2_mpeg_video_hevc_hierarchical_coding_type hier_qp_type;
+	u8 hier_ref_type;
+	u8 num_hier_layer;
+	u8 hier_qp_layer[7];
+	u32 hier_bit_layer[7];
 	u8 sign_data_hiding;
 	u8 general_pb_enable;
 	u8 temporal_id_enable;
@@ -560,6 +577,7 @@ struct s5p_mfc_hevc_enc_params {
 	u8 size_of_length_field;
 	u8 user_ref;
 	u8 store_ref;
+	u8 prepend_sps_pps_to_idr;
 };
 
 /**
@@ -571,9 +589,10 @@ struct s5p_mfc_enc_params {
 
 	u32 gop_size;
 	enum v4l2_mpeg_video_multi_slice_mode slice_mode;
-	u16 slice_mb;
+	u32 slice_mb;
 	u32 slice_bit;
-	u16 intra_refresh_mb;
+	u32 slice_mb_row;
+	u32 intra_refresh_mb;
 	u8 pad;
 	u8 pad_luma;
 	u8 pad_cb;
@@ -581,6 +600,8 @@ struct s5p_mfc_enc_params {
 	u8 rc_frame;
 	u32 rc_bitrate;
 	u16 rc_reaction_coeff;
+	u32 config_qp;
+	u32 dynamic_qp;
 	u8 frame_tag;
 
 	u8 num_b_frame;		/* H.264/MPEG4 */
@@ -589,6 +610,7 @@ struct s5p_mfc_enc_params {
 	enum v4l2_mpeg_video_header_mode seq_hdr_mode;
 	enum v4l2_mpeg_mfc51_video_frame_skip_mode frame_skip_mode;
 	u8 fixed_target_bit;
+	u8 num_hier_max_layer;
 
 	u16 rc_frame_delta;	/* MFC6.1 Only */
 
@@ -652,6 +674,7 @@ struct s5p_mfc_buf_ctrl {
 	int has_new;
 	int val;
 	unsigned int old_val;		/* only for MFC_CTRL_TYPE_SET */
+	unsigned int old_val2;		/* only for MFC_CTRL_TYPE_SET */
 	unsigned int is_volatile;	/* only for MFC_CTRL_TYPE_SET */
 	unsigned int updated;
 	unsigned int mode;
@@ -740,7 +763,7 @@ struct s5p_mfc_raw_info {
 	int plane_size[3];
 };
 
-#define MFC_TIME_INDEX		8
+#define MFC_TIME_INDEX		15
 struct mfc_timestamp {
 	struct list_head list;
 	struct timeval timestamp;
@@ -805,6 +828,8 @@ struct s5p_mfc_dec {
 	struct mfc_user_shared_handle sh_handle;
 
 	int dynamic_ref_filled;
+
+	unsigned int err_sync_flag;
 };
 
 struct s5p_mfc_enc {
@@ -831,6 +856,7 @@ struct s5p_mfc_enc {
 		unsigned int bits;
 	} slice_size;
 	unsigned int in_slice;
+	unsigned int buf_full;
 
 	int stored_tag;
 	struct mfc_user_shared_handle sh_handle;
@@ -872,6 +898,15 @@ struct s5p_mfc_ctx {
 	int dpb_count;
 	int buf_stride;
 
+	int old_img_width;
+	int old_img_height;
+
+	unsigned int enc_drc_flag;
+	int enc_res_change;
+	int enc_res_change_state;
+	int enc_res_change_re_input;
+	size_t min_scratch_buf_size;
+
 	struct s5p_mfc_raw_info raw_buf;
 	int mv_size;
 
@@ -879,10 +914,12 @@ struct s5p_mfc_ctx {
 	void *port_a_buf;
 	size_t port_a_phys;
 	size_t port_a_size;
+	void *port_a_virt;
 
 	void *port_b_buf;
 	size_t port_b_phys;
 	size_t port_b_size;
+	void *port_b_virt;
 
 	enum s5p_mfc_queue_state capture_state;
 	enum s5p_mfc_queue_state output_state;
@@ -926,16 +963,15 @@ struct s5p_mfc_ctx {
 	struct list_head qos_list;
 #endif
 	int qos_ratio;
+	int qos_changed;
 	int framerate;
 	int last_framerate;
 	int avg_framerate;
 	int frame_count;
 	struct timeval last_timestamp;
-	int qp_min_change;
-	int qp_max_change;
 
 	int is_max_fps;
-	int buf_process_type;
+	int use_extra_qos;
 
 	struct mfc_timestamp ts_array[MFC_TIME_INDEX];
 	struct list_head ts_list;
@@ -1054,8 +1090,6 @@ static inline unsigned int mfc_version(struct s5p_mfc_dev *dev)
 					(dev->fw.date >= 0x121005)) ||	\
 					(IS_MFCv5X(dev) &&		\
 					(dev->fw.date >= 0x120823)))
-#define FW_HAS_VUI_PARAMS(dev)		(IS_MFCV6(dev) &&		\
-					(dev->fw.date >= 0x121214))
 #define FW_HAS_ADV_RC_MODE(dev)		(IS_MFCV6(dev) &&		\
 					(dev->fw.date >= 0x130329))
 #define FW_HAS_I_LIMIT_RC_MODE(dev)	((IS_MFCv7X(dev) &&		\
@@ -1080,12 +1114,19 @@ static inline unsigned int mfc_version(struct s5p_mfc_dev *dev)
 
 #define FW_NEED_SHARED_MEMORY(dev)	(IS_MFCv5X(dev) || IS_MFCv6X(dev) ||	\
 					IS_MFCv7X(dev) || IS_MFCv78(dev))
+#if 0		/* Do not use last frame info */
 #define FW_HAS_LAST_DISP_INFO(dev)	(IS_MFCv9X(dev) &&			\
-					(dev->fw.date >= 0x141205))
+ 					(dev->fw.date >= 0x141205))
+#else
+#define FW_HAS_LAST_DISP_INFO(dev)	0
+#endif
 #define FW_HAS_GOP2(dev)		(IS_MFCv9X(dev) &&			\
 					(dev->fw.date >= 0x150316))
 #define FW_HAS_E_MIN_SCRATCH_BUF(dev)	IS_MFCv9X(dev)
 
+#define FW_SUPPORT_SKYPE(dev)		IS_MFCv9X(dev) &&		\
+					(dev->fw.date >= 0x150603)
+
 #define HW_LOCK_CLEAR_MASK		(0xFFFFFFFF)
 
 #define is_h264(ctx)		((ctx->codec_mode == S5P_FIMV_CODEC_H264_DEC) ||\
@@ -1102,15 +1143,30 @@ static inline unsigned int mfc_version(struct s5p_mfc_dev *dev)
 #define interlaced_cond(ctx)	is_mpeg4vc1(ctx) || is_mpeg2(ctx) || is_h264(ctx)
 #define on_res_change(ctx)	((ctx)->state >= MFCINST_RES_CHANGE_INIT &&	\
 				 (ctx)->state <= MFCINST_RES_CHANGE_END)
+#define need_to_wait_frame_start(ctx)		\
+	(((ctx->state == MFCINST_FINISHING) ||	\
+	  (ctx->state == MFCINST_RUNNING)) &&	\
+	 test_bit(ctx->num, &ctx->dev->hw_lock))
+#define need_to_wait_nal_abort(ctx)		 \
+	(ctx->state == MFCINST_ABORT_INST)
+#define need_to_special_parsing(ctx)		\
+	((ctx->state == MFCINST_GOT_INST) ||	\
+	 (ctx->state == MFCINST_HEAD_PARSED))
+#define need_to_special_parsing_nal(ctx)	\
+	((ctx->state == MFCINST_RUNNING) ||	\
+	 (ctx->state == MFCINST_ABORT))
 
 /* Extra information for Decoder */
 #define	DEC_SET_DUAL_DPB		(1 << 0)
 #define	DEC_SET_DYNAMIC_DPB		(1 << 1)
 #define	DEC_SET_LAST_FRAME_INFO		(1 << 2)
+#define	DEC_SET_SKYPE_FLAG		(1 << 3)
 /* Extra information for Encoder */
 #define	ENC_SET_RGB_INPUT		(1 << 0)
 #define	ENC_SET_SPARE_SIZE		(1 << 1)
 #define	ENC_SET_TEMP_SVC_CH		(1 << 2)
+#define	ENC_SET_SKYPE_FLAG		(1 << 3)
+#define	ENC_SET_QP_BOUND_PB		(1 << 5)
 
 #define MFC_QOS_FLAG_NODATA		0xFFFFFFFF
 
@@ -1129,8 +1185,11 @@ static inline int clear_hw_bit(struct s5p_mfc_ctx *ctx)
 	struct s5p_mfc_dev *dev = ctx->dev;
 	int ret = -1;
 
-	if (!atomic_read(&dev->watchdog_run))
+	if (!atomic_read(&dev->watchdog_run)) {
 		ret = test_and_clear_bit(ctx->num, &dev->hw_lock);
+		/* Reset the timeout watchdog */
+		atomic_set(&dev->watchdog_cnt, 0);
+	}
 
 	return ret;
 }
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_ctrl.c b/drivers/media/platform/exynos/mfc/s5p_mfc_ctrl.c
old mode 100644
new mode 100755
index 53677ca4248d..e3bf79c1e8b5
--- a/drivers/media/platform/exynos/mfc/s5p_mfc_ctrl.c
+++ b/drivers/media/platform/exynos/mfc/s5p_mfc_ctrl.c
@@ -512,7 +512,8 @@ int s5p_mfc_sleep(struct s5p_mfc_dev *dev)
 {
 	struct s5p_mfc_ctx *ctx;
 	int ret;
-	int old_state;
+	int old_state, i;
+	int need_cache_flush = 0;
 
 	mfc_debug_enter();
 
@@ -523,8 +524,25 @@ int s5p_mfc_sleep(struct s5p_mfc_dev *dev)
 
 	ctx = dev->ctx[dev->curr_ctx];
 	if (!ctx) {
-		mfc_err("no mfc context to run\n");
-		return -EINVAL;
+		for (i = 0; i < MFC_NUM_CONTEXTS; i++) {
+			if (dev->ctx[i]) {
+				ctx = dev->ctx[i];
+				break;
+			}
+		}
+		if (!ctx) {
+			mfc_err("no mfc context to run\n");
+			return -EINVAL;
+		} else {
+			mfc_info_dev("ctx is changed %d -> %d\n",
+					dev->curr_ctx, ctx->num);
+			dev->curr_ctx = ctx->num;
+			if (dev->curr_ctx_drm != ctx->is_drm) {
+				need_cache_flush = 1;
+				mfc_info_dev("DRM attribute is changed %d->%d\n",
+						dev->curr_ctx_drm, ctx->is_drm);
+			}
+		}
 	}
 	old_state = ctx->state;
 	ctx->state = MFCINST_ABORT;
@@ -545,6 +563,22 @@ int s5p_mfc_sleep(struct s5p_mfc_dev *dev)
 	ctx->state = old_state;
 	s5p_mfc_clock_on(dev);
 	s5p_mfc_clean_dev_int_flags(dev);
+
+	if (need_cache_flush) {
+		s5p_mfc_cmd_host2risc(dev, S5P_FIMV_CH_CACHE_FLUSH, NULL);
+		if (s5p_mfc_wait_for_done_dev(dev, S5P_FIMV_R2H_CMD_CACHE_FLUSH_RET)) {
+			mfc_err_ctx("Failed to flush cache\n");
+			ret = -EINVAL;
+			goto err_mfc_sleep;
+		}
+
+		s5p_mfc_init_memctrl(dev, (ctx->is_drm ? MFCBUF_DRM : MFCBUF_NORMAL));
+		s5p_mfc_clock_off(dev);
+
+		dev->curr_ctx_drm = ctx->is_drm;
+		s5p_mfc_clock_on(dev);
+	}
+
 	ret = s5p_mfc_sleep_cmd(dev);
 	if (ret) {
 		mfc_err_dev("Failed to send command to MFC - timeout.\n");
@@ -584,7 +618,7 @@ int s5p_mfc_wakeup(struct s5p_mfc_dev *dev)
 		mfc_err("no mfc device to run\n");
 		return -EINVAL;
 	}
-	mfc_info_dev("curr_ctx_drm:%d\n", dev->curr_ctx_drm);
+	mfc_info_dev("curr_ctx_drm:%d\n", dev->curr_ctx_drm);	
 	dev->wakeup_status = 1;
 	/* Set clock source again after wake up */
 	s5p_mfc_set_clock_parent(dev);
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_ctrl.h b/drivers/media/platform/exynos/mfc/s5p_mfc_ctrl.h
old mode 100644
new mode 100755
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_debug.h b/drivers/media/platform/exynos/mfc/s5p_mfc_debug.h
old mode 100644
new mode 100755
index c41996e6f8ea..fbc065cbc7b9
--- a/drivers/media/platform/exynos/mfc/s5p_mfc_debug.h
+++ b/drivers/media/platform/exynos/mfc/s5p_mfc_debug.h
@@ -67,11 +67,4 @@ extern int debug;
 			__func__, __LINE__, ##args);		\
 	} while (0)
 
-#define mfc_dbg_ctx(fmt, args...)				\
-	do {							\
-		printk(KERN_DEBUG "[d:%d, c:%d] %s:%d: " fmt,	\
-			ctx->dev->id, ctx->num,			\
-			__func__, __LINE__, ##args);		\
-	} while (0)
-
 #endif /* S5P_MFC_DEBUG_H_ */
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_dec.c b/drivers/media/platform/exynos/mfc/s5p_mfc_dec.c
old mode 100644
new mode 100755
index db53120b7531..c9ea937bdfcd
--- a/drivers/media/platform/exynos/mfc/s5p_mfc_dec.c
+++ b/drivers/media/platform/exynos/mfc/s5p_mfc_dec.c
@@ -392,7 +392,7 @@ static struct v4l2_queryctrl controls[] = {
 		.id = V4L2_CID_MPEG_VIDEO_QOS_RATIO,
 		.type = V4L2_CTRL_TYPE_INTEGER,
 		.name = "QoS ratio value",
-		.minimum = 20,
+		.minimum = 0,
 		.maximum = 1000,
 		.step = 10,
 		.default_value = 100,
@@ -424,15 +424,6 @@ static struct v4l2_queryctrl controls[] = {
 		.step = 1,
 		.default_value = 0,
 	},
-	{
-		.id = V4L2_CID_MPEG_MFC_SET_BUF_PROCESS_TYPE,
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.name = "Set buffer process type",
-		.minimum = INT_MIN,
-		.maximum = INT_MAX,
-		.step = 1,
-		.default_value = 0,
-	},
 };
 
 #define NUM_CTRLS ARRAY_SIZE(controls)
@@ -631,12 +622,21 @@ static struct s5p_mfc_ctrl_cfg mfc_ctrl_list[] = {
 /* Check whether a context should be run on hardware */
 int s5p_mfc_dec_ctx_ready(struct s5p_mfc_ctx *ctx)
 {
+	struct s5p_mfc_dev *dev = ctx->dev;
 	struct s5p_mfc_dec *dec = ctx->dec_priv;
 	mfc_debug(2, "src=%d, dst=%d, ref=%d, state=%d capstat=%d\n",
 		  ctx->src_queue_cnt, ctx->dst_queue_cnt, dec->ref_queue_cnt,
 		  ctx->state, ctx->capture_state);
 	mfc_debug(2, "wait_state = %d\n", ctx->wait_state);
 
+	/* Skip ready check temprally */
+	spin_lock_irq(&dev->condlock);
+	if (test_bit(ctx->num, &dev->ctx_stop_bits)) {
+		spin_unlock_irq(&dev->condlock);
+		return 0;
+	}
+	spin_unlock_irq(&dev->condlock);
+
 	/* Context is to parse header */
 	if (ctx->src_queue_cnt >= 1 && ctx->state == MFCINST_GOT_INST)
 		return 1;
@@ -1453,7 +1453,6 @@ static int vidioc_s_fmt_vid_out_mplane(struct file *file, void *priv,
 		spin_lock_irq(&dev->condlock);
 		set_bit(ctx->num, &dev->ctx_work_bits);
 		spin_unlock_irq(&dev->condlock);
-		s5p_mfc_clean_ctx_int_flags(ctx);
 		s5p_mfc_try_run(dev);
 		/* Wait until instance is returned or timeout occured */
 		if (s5p_mfc_wait_for_done_ctx(ctx,
@@ -1514,7 +1513,6 @@ static int vidioc_s_fmt_vid_out_mplane(struct file *file, void *priv,
 	spin_lock_irq(&dev->condlock);
 	set_bit(ctx->num, &dev->ctx_work_bits);
 	spin_unlock_irq(&dev->condlock);
-	s5p_mfc_clean_ctx_int_flags(ctx);
 	s5p_mfc_try_run(dev);
 	if (s5p_mfc_wait_for_done_ctx(ctx,
 			S5P_FIMV_R2H_CMD_OPEN_INSTANCE_RET)) {
@@ -1729,6 +1727,11 @@ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
 		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) {
 		if (buf->m.planes[0].bytesused > ctx->vq_src.plane_sizes[0]) {
 			mfc_err_ctx("data size (%d) must be less than "
@@ -1751,9 +1754,10 @@ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
 				sizeof(struct timeval));
 		}
 		if (ctx->last_framerate != 0 &&
-				ctx->last_framerate != ctx->framerate) {
-			mfc_debug(2, "fps changed: %d -> %d\n",
-					ctx->framerate, ctx->last_framerate);
+				((ctx->last_framerate != ctx->framerate) || ctx->qos_changed)) {
+			mfc_debug(2, "fps changed: %d -> %d (%s)\n",
+					ctx->framerate, ctx->last_framerate,
+					ctx->use_extra_qos ? "extra" : "normal");
 			ctx->framerate = ctx->last_framerate;
 			s5p_mfc_qos_on(ctx);
 		}
@@ -1788,7 +1792,13 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
 		ret = vb2_dqbuf(&ctx->vq_src, buf, file->f_flags & O_NONBLOCK);
 	} else {
 		ret = vb2_dqbuf(&ctx->vq_dst, buf, file->f_flags & O_NONBLOCK);
+
 		/* Memcpy from dec->ref_info to shared memory */
+		if (buf->index >= MFC_MAX_DPBS) {
+			mfc_err_ctx("buffer index[%d] range over\n", buf->index);
+			return -EINVAL;
+		}
+
 		srcBuf = &dec->ref_info[buf->index];
 		for (ncount = 0; ncount < MFC_MAX_DPBS; ncount++) {
 			if (srcBuf->dpb[ncount].fd[0] == MFC_INFO_INIT_FD)
@@ -1854,7 +1864,7 @@ static int vidioc_streamoff(struct file *file, void *priv,
 	} else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
 		ret = vb2_streamoff(&ctx->vq_dst, type);
 		if (!ret) {
-			if (!(ctx->buf_process_type & MFCBUFPROC_COPY))
+			if (!ctx->use_extra_qos)
 				s5p_mfc_qos_off(ctx);
 		}
 	} else {
@@ -1891,6 +1901,8 @@ static int dec_ext_info(struct s5p_mfc_ctx *ctx)
 		val |= DEC_SET_DYNAMIC_DPB;
 	if (FW_HAS_LAST_DISP_INFO(dev))
 		val |= DEC_SET_LAST_FRAME_INFO;
+	if (FW_SUPPORT_SKYPE(dev))
+		val |= DEC_SET_SKYPE_FLAG;
 
 	return val;
 }
@@ -2001,6 +2013,9 @@ static int get_ctrl_val(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl)
 	case V4L2_CID_MPEG_MFC_GET_EXT_INFO:
 		ctrl->value = dec_ext_info(ctx);
 		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))
@@ -2177,8 +2192,16 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
 	case V4L2_CID_MPEG_VIDEO_QOS_RATIO:
 		if (ctrl->value > 150)
 			ctrl->value = 1000;
-		mfc_info_ctx("set %d qos_ratio.\n", ctrl->value);
+		if (ctrl->value == 0) {
+			ctrl->value = 100;
+			ctx->use_extra_qos = 1;
+			mfc_info_ctx("QOS_RATIO is 0, use extra qos!\n");
+		} else {
+			ctx->use_extra_qos = 0;
+			mfc_info_ctx("QOS_RATIO is %d, use normal qos!\n", ctrl->value);
+		}
 		ctx->qos_ratio = ctrl->value;
+		ctx->qos_changed = 1;
 		break;
 	case V4L2_CID_MPEG_MFC_SET_DYNAMIC_DPB_MODE:
 		if (FW_HAS_DYNAMIC_DPB(dev))
@@ -2193,9 +2216,6 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
 			return -EINVAL;
 		}
 		break;
-	case V4L2_CID_MPEG_MFC_SET_BUF_PROCESS_TYPE:
-		ctx->buf_process_type = ctrl->value;
-		break;
 	default:
 		list_for_each_entry(ctx_ctrl, &ctx->ctrls, list) {
 			if (!(ctx_ctrl->type & MFC_CTRL_TYPE_SET))
@@ -2736,8 +2756,8 @@ static int s5p_mfc_stop_streaming(struct vb2_queue *q)
 	struct s5p_mfc_ctx *ctx = q->drv_priv;
 	struct s5p_mfc_dec *dec;
 	struct s5p_mfc_dev *dev;
-	int aborted = 0;
 	int index = 0;
+	int ret = 0;
 	int prev_state;
 
 	if (!ctx) {
@@ -2755,15 +2775,22 @@ static int s5p_mfc_stop_streaming(struct vb2_queue *q)
 		return -EINVAL;
 	}
 
-	if (need_to_wait_frame_start(ctx)) {
-		ctx->state = MFCINST_ABORT;
-		if (s5p_mfc_wait_for_done_ctx(ctx,
-				S5P_FIMV_R2H_CMD_FRAME_DONE_RET))
-			s5p_mfc_cleanup_timeout(ctx);
-		if (on_res_change(ctx))
-			mfc_debug(2, "stop on res change(state:%d)\n", ctx->state);
-		else
-			aborted = 1;
+	mfc_info_ctx("dec stop_streaming is called, hw_lock : %d, type : %d\n",
+				test_bit(ctx->num, &dev->hw_lock), q->type);
+	MFC_TRACE_CTX("** DEC streamoff(type:%d)\n", q->type);
+
+	spin_lock_irq(&dev->condlock);
+	set_bit(ctx->num, &dev->ctx_stop_bits);
+	clear_bit(ctx->num, &dev->ctx_work_bits);
+	spin_unlock_irq(&dev->condlock);
+
+	/* If a H/W operation is in progress, wait for it complete */
+	if (test_bit(ctx->num, &dev->hw_lock)) {
+		ret = wait_event_timeout(ctx->queue,
+				(test_bit(ctx->num, &dev->hw_lock) == 0),
+				msecs_to_jiffies(MFC_INT_TIMEOUT));
+		if (ret == 0)
+			mfc_err_ctx("wait for event failed\n");
 	}
 
 	spin_lock_irqsave(&dev->irqlock, flags);
@@ -2773,6 +2800,7 @@ static int s5p_mfc_stop_streaming(struct vb2_queue *q)
 			cleanup_assigned_fd(ctx);
 			cleanup_ref_queue(ctx);
 			dec->dynamic_used = 0;
+			dec->err_sync_flag = 0;
 		}
 
 		s5p_mfc_cleanup_queue(&ctx->dst_queue, &ctx->vq_dst);
@@ -2801,7 +2829,44 @@ static int s5p_mfc_stop_streaming(struct vb2_queue *q)
 			mfc_debug(2, "Decoding can be started now\n");
 		}
 	} else if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
-		s5p_mfc_cleanup_queue(&ctx->src_queue, &ctx->vq_src);
+		while (!list_empty(&ctx->src_queue)) {
+			struct s5p_mfc_buf *src_buf;
+			int csd, condition = 0;
+
+			src_buf = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
+			csd = src_buf->vb.v4l2_buf.reserved2 & FLAG_CSD ? 1 : 0;
+
+			if (csd) {
+				spin_unlock_irqrestore(&dev->irqlock, flags);
+				s5p_mfc_clean_ctx_int_flags(ctx);
+				if (need_to_special_parsing(ctx)) {
+					ctx->state = MFCINST_SPECIAL_PARSING;
+					condition = S5P_FIMV_R2H_CMD_SEQ_DONE_RET;
+					mfc_info_ctx("try to special parsing! (before NAL_START)\n");
+				} else if (need_to_special_parsing_nal(ctx)) {
+					ctx->state = MFCINST_SPECIAL_PARSING_NAL;
+					condition = S5P_FIMV_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) {
+					spin_lock_irq(&dev->condlock);
+					set_bit(ctx->num, &dev->ctx_work_bits);
+					spin_unlock_irq(&dev->condlock);
+					s5p_mfc_try_run(dev);
+					if (s5p_mfc_wait_for_done_ctx(ctx, condition)) {
+						mfc_err_ctx("special parsing time out\n");
+						s5p_mfc_cleanup_timeout(ctx);
+					}
+				}
+				spin_lock_irqsave(&dev->irqlock, flags);
+			}
+			vb2_set_plane_payload(&src_buf->vb, 0, 0);
+			vb2_buffer_done(&src_buf->vb, VB2_BUF_STATE_ERROR);
+			list_del(&src_buf->list);
+		}
+
 		INIT_LIST_HEAD(&ctx->src_queue);
 		ctx->src_queue_cnt = 0;
 
@@ -2814,13 +2879,30 @@ static int s5p_mfc_stop_streaming(struct vb2_queue *q)
 		}
 	}
 
-	if (aborted)
+	if (ctx->state == MFCINST_FINISHING)
 		ctx->state = MFCINST_RUNNING;
 
 	spin_unlock_irqrestore(&dev->irqlock, flags);
 
 	if (IS_MFCV6(dev) && q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
 			need_to_dpb_flush(ctx)) {
+		int ret = 0;
+
+		/* If a H/W operation is in progress, wait for it complete */
+		if (dev->hw_lock) {
+			struct s5p_mfc_ctx *wait_ctx;
+
+			index = find_first_bit(&dev->hw_lock, MFC_NUM_CONTEXTS);
+			wait_ctx = dev->ctx[index];
+			ret = wait_event_interruptible_timeout(wait_ctx->queue,
+					(dev->hw_lock == 0),
+					msecs_to_jiffies(MFC_INT_TIMEOUT));
+			if (ret == 0) {
+				mfc_err_dev("Waiting for hardware to finish timed out\n");
+				return -EIO;
+			}
+		}
+
 		prev_state = ctx->state;
 		ctx->state = MFCINST_DPB_FLUSHING;
 		spin_lock_irq(&dev->condlock);
@@ -2833,6 +2915,23 @@ static int s5p_mfc_stop_streaming(struct vb2_queue *q)
 			s5p_mfc_cleanup_timeout(ctx);
 		ctx->state = prev_state;
 	}
+
+	spin_lock_irq(&dev->condlock);
+	clear_bit(ctx->num, &dev->ctx_stop_bits);
+	spin_unlock_irq(&dev->condlock);
+
+	mfc_debug(2, "buffer cleanup & flush is done in stop_streaming, type : %d\n", q->type);
+
+	if (s5p_mfc_dec_ctx_ready(ctx)) {
+		spin_lock_irq(&dev->condlock);
+		set_bit(ctx->num, &dev->ctx_work_bits);
+		spin_unlock_irq(&dev->condlock);
+	}
+	spin_lock_irq(&dev->condlock);
+	if (dev->ctx_work_bits)
+		queue_work(dev->sched_wq, &dev->sched_work);
+	spin_unlock_irq(&dev->condlock);
+
 	return 0;
 }
 
@@ -2868,6 +2967,7 @@ static void s5p_mfc_buf_queue(struct vb2_buffer *vb)
 	int remove_flag = 0;
 	int index;
 	int skip_add = 0;
+	unsigned char *stream_vir = NULL;
 
 	mfc_debug_enter();
 	if (!ctx) {
@@ -2892,9 +2992,14 @@ static void s5p_mfc_buf_queue(struct vb2_buffer *vb)
 		mfc_debug(2, "Adding to src: %p (0x%08lx, 0x%08lx)\n", vb,
 			(unsigned long)s5p_mfc_mem_plane_addr(ctx, vb, 0),
 			(unsigned long)buf->planes.stream);
+		if (ctx->state < MFCINST_HEAD_PARSED && !ctx->is_drm) {
+			stream_vir = vb2_plane_vaddr(vb, 0);
+			s5p_mfc_mem_inv_vb(vb, 1);
+		}
 		spin_lock_irqsave(&dev->irqlock, flags);
 		list_add_tail(&buf->list, &ctx->src_queue);
 		ctx->src_queue_cnt++;
+		buf->vir_addr = stream_vir;
 		spin_unlock_irqrestore(&dev->irqlock, flags);
 	} else if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
 		buf->used = 0;
@@ -3052,6 +3157,7 @@ int s5p_mfc_init_dec_ctx(struct s5p_mfc_ctx *ctx)
 	dec->is_dts_mode = 0;
 	dec->is_dual_dpb = 0;
 	dec->tiled_buf_cnt = 0;
+	dec->err_sync_flag = 0;
 
 	dec->is_dynamic_dpb = 0;
 	dec->dynamic_used = 0;
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_dec.h b/drivers/media/platform/exynos/mfc/s5p_mfc_dec.h
old mode 100644
new mode 100755
index 584b2a4117fb..14b436624e92
--- a/drivers/media/platform/exynos/mfc/s5p_mfc_dec.h
+++ b/drivers/media/platform/exynos/mfc/s5p_mfc_dec.h
@@ -15,7 +15,7 @@
 
 #define MAX_FRAME_SIZE		(2*1024*1024)
 #define DEFAULT_TAG		(0xE05)
-#define DEC_MAX_FPS		(60000)
+#define DEC_MAX_FPS     (240000)
 
 const struct v4l2_ioctl_ops *get_dec_v4l2_ioctl_ops(void);
 int s5p_mfc_init_dec_ctx(struct s5p_mfc_ctx *ctx);
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_enc.c b/drivers/media/platform/exynos/mfc/s5p_mfc_enc.c
old mode 100644
new mode 100755
index 72172a419903..145c32b74284
--- a/drivers/media/platform/exynos/mfc/s5p_mfc_enc.c
+++ b/drivers/media/platform/exynos/mfc/s5p_mfc_enc.c
@@ -198,7 +198,7 @@ static struct v4l2_queryctrl controls[] = {
 		.type = V4L2_CTRL_TYPE_INTEGER,
 		.name = "The slice partitioning method",
 		.minimum = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE,
-		.maximum = V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES,
+		.maximum = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB_ROW,
 		.step = 1,
 		.default_value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE,
 	},
@@ -207,7 +207,7 @@ static struct v4l2_queryctrl controls[] = {
 		.type = V4L2_CTRL_TYPE_INTEGER,
 		.name = "The number of MB in a slice",
 		.minimum = 1,
-		.maximum = ENC_MULTI_SLICE_MB_MAX,
+		.maximum = INT_MAX,
 		.step = 1,
 		.default_value = 1,
 	},
@@ -215,17 +215,26 @@ static struct v4l2_queryctrl controls[] = {
 		.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES,
 		.type = V4L2_CTRL_TYPE_INTEGER,
 		.name = "The maximum bits per slices",
-		.minimum = ENC_MULTI_SLICE_BYTE_MIN,
-		.maximum = (1 << 30) - 1,
+		.minimum = 350,
+		.maximum = INT_MAX / 8,
+		.step = 1,
+		.default_value = 350,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB_ROW,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "The number of MB row in a slice",
+		.minimum = 1,
+		.maximum = INT_MAX / 256,
 		.step = 1,
-		.default_value = ENC_MULTI_SLICE_BYTE_MIN,
+		.default_value = 1,
 	},
 	{
 		.id = V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB,
 		.type = V4L2_CTRL_TYPE_INTEGER,
 		.name = "The number of intra refresh MBs",
 		.minimum = 0,
-		.maximum = ENC_INTRA_REFRESH_MB_MAX,
+		.maximum = (1 << 18) - 1,
 		.step = 1,
 		.default_value = 0,
 	},
@@ -243,7 +252,7 @@ static struct v4l2_queryctrl controls[] = {
 		.type = V4L2_CTRL_TYPE_INTEGER,
 		.name = "Padding Color YUV Value",
 		.minimum = 0,
-		.maximum = (1 << 25) - 1,
+		.maximum = (1 << 24) - 1,
 		.step = 1,
 		.default_value = 0,
 	},
@@ -261,7 +270,7 @@ static struct v4l2_queryctrl controls[] = {
 		.type = V4L2_CTRL_TYPE_INTEGER,
 		.name = "Target bit rate rate-control",
 		.minimum = 1,
-		.maximum = (1 << 30) - 1,
+		.maximum = INT_MAX,
 		.step = 1,
 		.default_value = 1,
 	},
@@ -279,7 +288,7 @@ static struct v4l2_queryctrl controls[] = {
 		.type = V4L2_CTRL_TYPE_INTEGER,
 		.name = "Encoded stream size",
 		.minimum = 0,
-		.maximum = (1 << 30) - 1,
+		.maximum = INT_MAX,
 		.step = 1,
 		.default_value = 0,
 		.flags = V4L2_CTRL_FLAG_READ_ONLY,
@@ -289,7 +298,7 @@ static struct v4l2_queryctrl controls[] = {
 		.type = V4L2_CTRL_TYPE_INTEGER,
 		.name = "Encoded frame count",
 		.minimum = 0,
-		.maximum = (1 << 30) - 1,
+		.maximum = INT_MAX,
 		.step = 1,
 		.default_value = 0,
 		.flags = V4L2_CTRL_FLAG_READ_ONLY,
@@ -319,7 +328,7 @@ static struct v4l2_queryctrl controls[] = {
 		.type = V4L2_CTRL_TYPE_INTEGER,
 		.name = "VBV buffer size (1Kbits)",
 		.minimum = 0,
-		.maximum = ENC_VBV_BUF_SIZE_MAX,
+		.maximum = (1 << 16) - 1,
 		.step = 1,
 		.default_value = 0,
 	},
@@ -373,7 +382,7 @@ static struct v4l2_queryctrl controls[] = {
 		.type = V4L2_CTRL_TYPE_INTEGER,
 		.name = "H264 profile",
 		.minimum = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
-		.maximum = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
+		.maximum = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH,
 		.step = 1,
 		.default_value = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
 	},
@@ -408,8 +417,8 @@ static struct v4l2_queryctrl controls[] = {
 		.id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA,
 		.type = V4L2_CTRL_TYPE_INTEGER,
 		.name = "H264 loop filter alpha offset",
-		.minimum = ENC_H264_LOOP_FILTER_AB_MIN,
-		.maximum = ENC_H264_LOOP_FILTER_AB_MAX,
+		.minimum = -12,
+		.maximum = 12,
 		.step = 1,
 		.default_value = 0,
 	},
@@ -417,8 +426,8 @@ static struct v4l2_queryctrl controls[] = {
 		.id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA,
 		.type = V4L2_CTRL_TYPE_INTEGER,
 		.name = "H264 loop filter beta offset",
-		.minimum = ENC_H264_LOOP_FILTER_AB_MIN,
-		.maximum = ENC_H264_LOOP_FILTER_AB_MAX,
+		.minimum = -12,
+		.maximum = 12,
 		.step = 1,
 		.default_value = 0,
 	},
@@ -463,7 +472,7 @@ static struct v4l2_queryctrl controls[] = {
 		.type = V4L2_CTRL_TYPE_INTEGER,
 		.name = "H264 Frame rate",
 		.minimum = 1,
-		.maximum = ENC_H264_RC_FRAME_RATE_MAX,
+		.maximum = (1 << 16) - 1,
 		.step = 1,
 		.default_value = 1,
 	},
@@ -476,25 +485,6 @@ static struct v4l2_queryctrl controls[] = {
 		.step = 1,
 		.default_value = 0,
 	},
-	{
-		.id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP,
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.name = "H264 Minimum QP value",
-		.minimum = 0,
-		.maximum = 51,
-		.step = 1,
-		.default_value = 0,
-	},
-	{
-		/* MAX_QP must be greater than or equal to MIN_QP */
-		.id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP,
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.name = "H264 Maximum QP value",
-		.minimum = 0,
-		.maximum = 51,
-		.step = 1,
-		.default_value = 0,
-	},
 	{
 		.id = V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_DARK,
 		.type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -619,7 +609,7 @@ static struct v4l2_queryctrl controls[] = {
 		.minimum = V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_B,
 		.maximum = V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P,
 		.step = 1,
-		.default_value = V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_B,
+		.default_value = V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P,
 	},
 	{
 		.id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER,
@@ -775,24 +765,6 @@ static struct v4l2_queryctrl controls[] = {
 		.step = 1,
 		.default_value = 1,
 	},
-	{
-		.id = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP,
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.name = "MPEG4 Minimum QP value",
-		.minimum = 1,
-		.maximum = 31,
-		.step = 1,
-		.default_value = 1,
-	},
-	{
-		.id = V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP,
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.name = "MPEG4 Maximum QP value",
-		.minimum = 1,
-		.maximum = 31,
-		.step = 1,
-		.default_value = 1,
-	},
 	{	/* MFC5.x Only */
 		.id = V4L2_CID_MPEG_VIDEO_MPEG4_QPEL,
 		.type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -825,7 +797,7 @@ static struct v4l2_queryctrl controls[] = {
 		.type = V4L2_CTRL_TYPE_INTEGER,
 		.name = "MPEG4 vop time resolution",
 		.minimum = 0,
-		.maximum = ENC_MPEG4_VOP_TIME_RES_MAX,
+		.maximum = (1 << 16) - 1,
 		.step = 1,
 		.default_value = 0,
 	},
@@ -843,7 +815,7 @@ static struct v4l2_queryctrl controls[] = {
 		.type = V4L2_CTRL_TYPE_INTEGER,
 		.name = "H263 Frame rate",
 		.minimum = 1,
-		.maximum = ENC_H263_RC_FRAME_RATE_MAX,
+		.maximum = (1 << 8) - 1,
 		.step = 1,
 		.default_value = 1,
 	},
@@ -856,24 +828,6 @@ static struct v4l2_queryctrl controls[] = {
 		.step = 1,
 		.default_value = 1,
 	},
-	{
-		.id = V4L2_CID_MPEG_VIDEO_H263_MIN_QP,
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.name = "H263 Minimum QP value",
-		.minimum = 1,
-		.maximum = 31,
-		.step = 1,
-		.default_value = 1,
-	},
-	{
-		.id = V4L2_CID_MPEG_VIDEO_H263_MAX_QP,
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.name = "H263 Maximum QP value",
-		.minimum = 1,
-		.maximum = 31,
-		.step = 1,
-		.default_value = 1,
-	},
 	{
 		.id = V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP,
 		.type = V4L2_CTRL_TYPE_INTEGER,
@@ -905,8 +859,8 @@ static struct v4l2_queryctrl controls[] = {
 		.id = V4L2_CID_MPEG_VIDEO_QOS_RATIO,
 		.type = V4L2_CTRL_TYPE_INTEGER,
 		.name = "QoS ratio value",
-		.minimum = 20,
-		.maximum = 200,
+		.minimum = 0,
+		.maximum = 1000,
 		.step = 10,
 		.default_value = 100,
 	},
@@ -937,30 +891,12 @@ static struct v4l2_queryctrl controls[] = {
 		.step = 1,
 		.default_value = 0,
 	},
-	{
-		.id = V4L2_CID_MPEG_VIDEO_VP8_MAX_QP,
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.name = "VP8 Frame QP MAX value",
-		.minimum = 0,
-		.maximum = 127,
-		.step = 1,
-		.default_value = 0,
-	},
-	{
-		.id = V4L2_CID_MPEG_VIDEO_VP8_MIN_QP,
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.name = "VP8 Frame QP MIN value",
-		.minimum = 0,
-		.maximum = 127,
-		.step = 1,
-		.default_value = 0,
-	},
 	{
 		.id = V4L2_CID_MPEG_MFC70_VIDEO_VP8_RC_FRAME_RATE,
 		.type = V4L2_CTRL_TYPE_INTEGER,
 		.name = "VP8 Frame rate",
 		.minimum = 1,
-		.maximum = ENC_H264_RC_FRAME_RATE_MAX,
+		.maximum = (1 << 16) - 1,
 		.step = 1,
 		.default_value = 0,
 	},
@@ -1005,7 +941,7 @@ static struct v4l2_queryctrl controls[] = {
 		.type = V4L2_CTRL_TYPE_INTEGER,
 		.name = "VP8 indication of golden frame",
 		.minimum = 0,
-		.maximum = ((1 << 16) - 1),
+		.maximum = (1 << 16) - 1,
 		.step = 1,
 		.default_value = 0,
 	},
@@ -1099,26 +1035,6 @@ static struct v4l2_queryctrl controls[] = {
 		.step = 1,
 		.default_value = 0,
 	},
-
-	{
-		.id = V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP,
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.name = "HEVC Minimum QP value",
-		.minimum = 0,
-		.maximum = 51,
-		.step = 1,
-		.default_value = 0,
-	},
-	{
-		/* MAX_QP must be greater than or equal to MIN_QP */
-		.id = V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP,
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.name = "HEVC Maximum QP value",
-		.minimum = 0,
-		.maximum = 51,
-		.step = 1,
-		.default_value = 0,
-	},
 	{
 		.id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_ADAPTIVE_RC_DARK,
 		.type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -1187,7 +1103,7 @@ static struct v4l2_queryctrl controls[] = {
 		.type = V4L2_CTRL_TYPE_INTEGER,
 		.name = "HEVC Frame rate",
 		.minimum = 1,
-		.maximum = ENC_HEVC_RC_FRAME_RATE_MAX,
+		.maximum = (1 << 16) - 1,
 		.step = 1,
 		.default_value = 0,
 	},
@@ -1285,8 +1201,8 @@ static struct v4l2_queryctrl controls[] = {
 		.id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_TYPE,
 		.type = V4L2_CTRL_TYPE_BOOLEAN,
 		.name = "Hierarchical Coding Type",
-		.minimum = 0,
-		.maximum = 1,
+		.minimum = V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B,
+		.maximum = V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P,
 		.step = 1,
 		.default_value = 0, /* need to check defualt value */
 	},
@@ -1309,13 +1225,76 @@ static struct v4l2_queryctrl controls[] = {
 		.default_value = 0, /* need to check defualt value */
 	},
 	{
-		.id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT,
+		.id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT0,
 		.type = V4L2_CTRL_TYPE_INTEGER,
-		.name = "Hierarchical Coding Layer BIT",
+		.name = "Hierarchical Coding Layer BIT0",
 		.minimum = INT_MIN,
 		.maximum = INT_MAX,
 		.step = 1,
-		.default_value = 0, /* need to check defualt value */
+		.default_value = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT1,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "Hierarchical Coding Layer BIT1",
+		.minimum = INT_MIN,
+		.maximum = INT_MAX,
+		.step = 1,
+		.default_value = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT2,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "Hierarchical Coding Layer BIT2",
+		.minimum = INT_MIN,
+		.maximum = INT_MAX,
+		.step = 1,
+		.default_value = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT3,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "Hierarchical Coding Layer BIT3",
+		.minimum = INT_MIN,
+		.maximum = INT_MAX,
+		.step = 1,
+		.default_value = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT4,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "Hierarchical Coding Layer BIT4",
+		.minimum = INT_MIN,
+		.maximum = INT_MAX,
+		.step = 1,
+		.default_value = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT5,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "Hierarchical Coding Layer BIT5",
+		.minimum = INT_MIN,
+		.maximum = INT_MAX,
+		.step = 1,
+		.default_value = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT6,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "Hierarchical Coding Layer BIT6",
+		.minimum = INT_MIN,
+		.maximum = INT_MAX,
+		.step = 1,
+		.default_value = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_CH,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "Hierarchical Coding Layer Change",
+		.minimum = INT_MIN,
+		.maximum = INT_MAX,
+		.step = 1,
+		.default_value = 0,
 	},
 	{
 		.id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_SIGN_DATA_HIDING,
@@ -1394,25 +1373,7 @@ static struct v4l2_queryctrl controls[] = {
 		.type = V4L2_CTRL_TYPE_INTEGER,
 		.name = "HEVC Number of reference picture",
 		.minimum = 0,
-		.maximum = 10, /* need to check maximum size */
-		.step = 1,
-		.default_value = 0, /* need to check defualt value */
-	},
-	{
-		.id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_QP_INDEX_CR,
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.name = "Chroma QP index offset Cr",
-		.minimum = ENC_HEVC_QP_INDEX_MIN,
-		.maximum = ENC_HEVC_QP_INDEX_MAX,
-		.step = 1,
-		.default_value = 0, /* need to check defualt value */
-	},
-	{
-		.id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_QP_INDEX_CB,
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.name = "Chroma QP index offset Cb",
-		.minimum = ENC_HEVC_QP_INDEX_MIN,
-		.maximum = ENC_HEVC_QP_INDEX_MAX,
+		.maximum = (1 << 16) - 1,
 		.step = 1,
 		.default_value = 0, /* need to check defualt value */
 	},
@@ -1420,8 +1381,8 @@ static struct v4l2_queryctrl controls[] = {
 		.id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LF_BETA_OFFSET_DIV2,
 		.type = V4L2_CTRL_TYPE_INTEGER,
 		.name = "HEVC loop filter beta offset",
-		.minimum = ENC_HEVC_LOOP_FILTER_MIN,
-		.maximum = ENC_HEVC_LOOP_FILTER_MAX,
+		.minimum = -6,
+		.maximum = 6,
 		.step = 1,
 		.default_value = 0, /* need to check defualt value */
 	},
@@ -1429,8 +1390,8 @@ static struct v4l2_queryctrl controls[] = {
 		.id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LF_TC_OFFSET_DIV2,
 		.type = V4L2_CTRL_TYPE_INTEGER,
 		.name = "HEVC loop filter tc offset",
-		.minimum = ENC_HEVC_LOOP_FILTER_MIN,
-		.maximum = ENC_HEVC_LOOP_FILTER_MAX,
+		.minimum = -6,
+		.maximum = 6,
 		.step = 1,
 		.default_value = 0, /* need to check defualt value */
 	},
@@ -1596,90 +1557,422 @@ static struct v4l2_queryctrl controls[] = {
 		.step = 1,
 		.default_value = 0,
 	},
-};
-
-#define NUM_CTRLS ARRAY_SIZE(controls)
-
-static struct v4l2_queryctrl *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 check_ctrl_val(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl)
-{
-	struct s5p_mfc_dev *dev = ctx->dev;
-	struct v4l2_queryctrl *c;
-
-	c = get_ctrl(ctrl->id);
-	if (!c)
-		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->value < c->minimum || ctrl->value > c->maximum
-	    || (c->step != 0 && ctrl->value % c->step != 0)) {
-		v4l2_err(&dev->v4l2_dev, "Invalid control value\n");
-		return -ERANGE;
-	}
-	if (!FW_HAS_ENC_SPSPPS_CTRL(dev) && ctrl->id ==	\
-			V4L2_CID_MPEG_VIDEO_H264_PREPEND_SPSPPS_TO_IDR) {
-		mfc_err_ctx("Not support feature(0x%x) for F/W\n", ctrl->id);
-		return -ERANGE;
-	}
-
-	return 0;
-}
-
-static int enc_ctrl_read_cst(struct s5p_mfc_ctx *ctx,
-		struct s5p_mfc_buf_ctrl *buf_ctrl)
-{
-	int ret;
-	struct s5p_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 s5p_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_CUSTOM,
-		.addr = S5P_FIMV_SHARED_SET_E_FRAME_TAG,
-		.mask = 0xFFFFFFFF,
-		.shft = 0,
-		.flag_mode = MFC_CTRL_MODE_NONE,
-		.flag_addr = 0,
-		.flag_shft = 0,
+	{
+		.id = V4L2_CID_MPEG_MFC_H264_ENABLE_LTR,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "Enable LTR",
+		.minimum = 0,
+		.maximum = 1,
+		.step = 1,
+		.default_value = 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_CUSTOM,
-		.addr = S5P_FIMV_SHARED_GET_E_FRAME_TAG,
-		.mask = 0xFFFFFFFF,
-		.shft = 0,
-		.flag_mode = MFC_CTRL_MODE_NONE,
+	{
+		.id = V4L2_CID_MPEG_MFC_H264_NUM_OF_LTR,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "Number of LTR",
+		.minimum = 0,
+		.maximum = 4,
+		.step = 1,
+		.default_value = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_MFC_H264_MARK_LTR,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "Set the frame as a LTRP",
+		.minimum = 0,
+		.maximum = 4,
+		.step = 1,
+		.default_value = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_MFC_H264_USE_LTR,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "Specify a LTRP for encoding",
+		.minimum = 0,
+		.maximum = 0xF,
+		.step = 1,
+		.default_value = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_MFC_H264_BASE_PRIORITY,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "Hierarchical Base Layer Priority",
+		.minimum = 0,
+		.maximum = (1 << 6) - 1 - 6,
+		.step = 1,
+		.default_value = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_MFC_CONFIG_QP,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "QP control per each frame",
+		.minimum = 0,
+		.maximum = (1 << 7) - 1,
+		.step = 1,
+		.default_value = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_MFC_H264_VUI_RESTRICTION_ENABLE,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "H264 vui generation enable",
+		.minimum = 0,
+		.maximum = 1,
+		.step = 1,
+		.default_value = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_HEVC_PREPEND_SPSPPS_TO_IDR,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "Prepend SPS/PPS to every IDR",
+		.minimum = 0,
+		.maximum = 1,
+		.step = 1,
+		.default_value = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_MFC_CONFIG_QP_ENABLE,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "set dynamic qp control",
+		.minimum = 0,
+		.maximum = 1,
+		.step = 1,
+		.default_value = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "H264 Min QP value for I frame",
+		.minimum = 0,
+		.maximum = 51,
+		.step = 1,
+		.default_value = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "H264 Max QP value for I frame",
+		.minimum = 0,
+		.maximum = 51,
+		.step = 1,
+		.default_value = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "HEVC Min QP value for I frame",
+		.minimum = 0,
+		.maximum = 51,
+		.step = 1,
+		.default_value = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "HEVC Max QP value for I frame",
+		.minimum = 0,
+		.maximum = 51,
+		.step = 1,
+		.default_value = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "MPEG4 Min QP value for I frame",
+		.minimum = 1,
+		.maximum = 31,
+		.step = 1,
+		.default_value = 1,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "MPEG4 Max QP value for I frame",
+		.minimum = 1,
+		.maximum = 31,
+		.step = 1,
+		.default_value = 1,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_H263_MIN_QP,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "H263 Min QP value for I frame",
+		.minimum = 1,
+		.maximum = 31,
+		.step = 1,
+		.default_value = 1,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_H263_MAX_QP,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "H263 Max QP value for I frame",
+		.minimum = 1,
+		.maximum = 31,
+		.step = 1,
+		.default_value = 1,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_VP8_MIN_QP,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "VP8 Min QP value for I frame",
+		.minimum = 0,
+		.maximum = 127,
+		.step = 1,
+		.default_value = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_VP8_MAX_QP,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "VP8 Max QP value for I frame",
+		.minimum = 0,
+		.maximum = 127,
+		.step = 1,
+		.default_value = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP_P,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "H264 Min QP value for P frame",
+		.minimum = 0,
+		.maximum = 51,
+		.step = 1,
+		.default_value = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP_P,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "H264 Max QP value for P frame",
+		.minimum = 0,
+		.maximum = 51,
+		.step = 1,
+		.default_value = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP_P,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "HEVC Min QP value for P frame",
+		.minimum = 0,
+		.maximum = 51,
+		.step = 1,
+		.default_value = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP_P,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "HEVC Max QP value for P frame",
+		.minimum = 0,
+		.maximum = 51,
+		.step = 1,
+		.default_value = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP_P,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "MPEG4 Min QP value for P frame",
+		.minimum = 1,
+		.maximum = 31,
+		.step = 1,
+		.default_value = 1,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP_P,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "MPEG4 Max QP value for P frame",
+		.minimum = 1,
+		.maximum = 31,
+		.step = 1,
+		.default_value = 1,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_H263_MIN_QP_P,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "H263 Min QP value for P frame",
+		.minimum = 1,
+		.maximum = 31,
+		.step = 1,
+		.default_value = 1,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_H263_MAX_QP_P,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "H263 Max QP value for P frame",
+		.minimum = 1,
+		.maximum = 31,
+		.step = 1,
+		.default_value = 1,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_VP8_MIN_QP_P,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "VP8 Min QP value for P frame",
+		.minimum = 0,
+		.maximum = 127,
+		.step = 1,
+		.default_value = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_VP8_MAX_QP_P,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "VP8 Max QP value for P frame",
+		.minimum = 0,
+		.maximum = 127,
+		.step = 1,
+		.default_value = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP_B,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "H264 Min QP value for B frame",
+		.minimum = 0,
+		.maximum = 51,
+		.step = 1,
+		.default_value = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP_B,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "H264 Max QP value for B frame",
+		.minimum = 0,
+		.maximum = 51,
+		.step = 1,
+		.default_value = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP_B,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "HEVC Min QP value for B frame",
+		.minimum = 0,
+		.maximum = 51,
+		.step = 1,
+		.default_value = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP_B,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "HEVC Max QP value for B frame",
+		.minimum = 0,
+		.maximum = 51,
+		.step = 1,
+		.default_value = 0,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP_B,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "MPEG4 Min QP value for B frame",
+		.minimum = 1,
+		.maximum = 31,
+		.step = 1,
+		.default_value = 1,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP_B,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "MPEG4 Max QP value for B frame",
+		.minimum = 1,
+		.maximum = 31,
+		.step = 1,
+		.default_value = 1,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_TEMPORAL_SHORTTERM_MAX_LAYER,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "Hierarchical Coding max layer",
+		.minimum = 0,
+		.maximum = 3,
+		.step = 1,
+		.default_value = 0,
+	},
+};
+
+#define NUM_CTRLS ARRAY_SIZE(controls)
+
+static struct v4l2_queryctrl *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 check_ctrl_val(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl)
+{
+	struct s5p_mfc_dev *dev = ctx->dev;
+	struct v4l2_queryctrl *c;
+
+	c = get_ctrl(ctrl->id);
+	if (!c)
+		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)) {
+			v4l2_err(&dev->v4l2_dev, "Invalid control value\n");
+			return -ERANGE;
+		} else {
+			return 0;
+		}
+	}
+	if (ctrl->value < c->minimum || ctrl->value > c->maximum
+	    || (c->step != 0 && ctrl->value % c->step != 0)) {
+		v4l2_err(&dev->v4l2_dev, "Invalid control value\n");
+		return -ERANGE;
+	}
+	if (!FW_HAS_ENC_SPSPPS_CTRL(dev) && ctrl->id ==	\
+			V4L2_CID_MPEG_VIDEO_H264_PREPEND_SPSPPS_TO_IDR) {
+		mfc_err_ctx("Not support feature(0x%x) for F/W\n", ctrl->id);
+		return -ERANGE;
+	}
+
+	return 0;
+}
+
+static int enc_ctrl_read_cst(struct s5p_mfc_ctx *ctx,
+		struct s5p_mfc_buf_ctrl *buf_ctrl)
+{
+	int ret;
+	struct s5p_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 s5p_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_CUSTOM,
+		.addr = S5P_FIMV_SHARED_SET_E_FRAME_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_CUSTOM,
+		.addr = S5P_FIMV_SHARED_GET_E_FRAME_TAG,
+		.mask = 0xFFFFFFFF,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_NONE,
 		.flag_addr = 0,
 		.flag_shft = 0,
 	},
@@ -1769,149 +2062,426 @@ static struct s5p_mfc_ctrl_cfg mfc_ctrl_list[] = {
 		.read_cst = enc_ctrl_read_cst,
 		.write_cst = NULL,
 	},
-	{	/* H.264 QP Max change */
+	{	/* 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_CUSTOM,
+		.addr = S5P_FIMV_NEW_RC_QP_BOUND,
+		.mask = 0x7F,
+		.shft = 8,
+		.flag_mode = MFC_CTRL_MODE_CUSTOM,
+		.flag_addr = S5P_FIMV_PARAM_CHANGE_FLAG,
+		.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_CUSTOM,
+		.addr = S5P_FIMV_NEW_RC_QP_BOUND,
+		.mask = 0x7F,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_CUSTOM,
+		.flag_addr = S5P_FIMV_PARAM_CHANGE_FLAG,
+		.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_CUSTOM,
+		.addr = S5P_FIMV_NEW_RC_QP_BOUND,
+		.mask = 0x7F,
+		.shft = 8,
+		.flag_mode = MFC_CTRL_MODE_CUSTOM,
+		.flag_addr = S5P_FIMV_PARAM_CHANGE_FLAG,
+		.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_CUSTOM,
+		.addr = S5P_FIMV_NEW_RC_QP_BOUND,
+		.mask = 0x7F,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_CUSTOM,
+		.flag_addr = S5P_FIMV_PARAM_CHANGE_FLAG,
+		.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_CUSTOM,
+		.addr = S5P_FIMV_NEW_RC_QP_BOUND,
+		.mask = 0x7F,
+		.shft = 8,
+		.flag_mode = MFC_CTRL_MODE_CUSTOM,
+		.flag_addr = S5P_FIMV_PARAM_CHANGE_FLAG,
+		.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_CUSTOM,
+		.addr = S5P_FIMV_NEW_RC_QP_BOUND,
+		.mask = 0x7F,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_CUSTOM,
+		.flag_addr = S5P_FIMV_PARAM_CHANGE_FLAG,
+		.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_CUSTOM,
+		.addr = S5P_FIMV_NEW_RC_QP_BOUND,
+		.mask = 0x7F,
+		.shft = 8,
+		.flag_mode = MFC_CTRL_MODE_CUSTOM,
+		.flag_addr = S5P_FIMV_PARAM_CHANGE_FLAG,
+		.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_CUSTOM,
+		.addr = S5P_FIMV_NEW_RC_QP_BOUND,
+		.mask = 0x7F,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_CUSTOM,
+		.flag_addr = S5P_FIMV_PARAM_CHANGE_FLAG,
+		.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_CUSTOM,
+		.addr = S5P_FIMV_NEW_RC_QP_BOUND,
+		.mask = 0x7F,
+		.shft = 8,
+		.flag_mode = MFC_CTRL_MODE_CUSTOM,
+		.flag_addr = S5P_FIMV_PARAM_CHANGE_FLAG,
+		.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_CUSTOM,
+		.addr = S5P_FIMV_NEW_RC_QP_BOUND,
+		.mask = 0x7F,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_CUSTOM,
+		.flag_addr = S5P_FIMV_PARAM_CHANGE_FLAG,
+		.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 = S5P_FIMV_E_RC_QP_BOUND_PB,
+		.mask = 0x7F,
+		.shft = 8,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = S5P_FIMV_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 = S5P_FIMV_E_RC_QP_BOUND_PB,
+		.mask = 0x7F,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = S5P_FIMV_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 = S5P_FIMV_E_RC_QP_BOUND_PB,
+		.mask = 0x7F,
+		.shft = 8,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = S5P_FIMV_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 = S5P_FIMV_E_RC_QP_BOUND_PB,
+		.mask = 0x7F,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = S5P_FIMV_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 = S5P_FIMV_E_RC_QP_BOUND_PB,
+		.mask = 0x7F,
+		.shft = 8,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = S5P_FIMV_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 = S5P_FIMV_E_RC_QP_BOUND_PB,
+		.mask = 0x7F,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = S5P_FIMV_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 = S5P_FIMV_E_RC_QP_BOUND_PB,
+		.mask = 0x7F,
+		.shft = 8,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = S5P_FIMV_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 = S5P_FIMV_E_RC_QP_BOUND_PB,
+		.mask = 0x7F,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = S5P_FIMV_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 = S5P_FIMV_E_RC_QP_BOUND_PB,
+		.mask = 0x7F,
+		.shft = 8,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = S5P_FIMV_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 = S5P_FIMV_E_RC_QP_BOUND_PB,
+		.mask = 0x7F,
+		.shft = 0,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = S5P_FIMV_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 = S5P_FIMV_E_RC_QP_BOUND_PB,
+		.mask = 0x7F,
+		.shft = 24,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = S5P_FIMV_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 = S5P_FIMV_E_RC_QP_BOUND_PB,
+		.mask = 0x7F,
+		.shft = 16,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = S5P_FIMV_E_PARAM_CHANGE,
+		.flag_shft = 4,
+	},
+	{	/* MPEG4 B frame QP Max change */
 		.type = MFC_CTRL_TYPE_SET,
-		.id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP,
+		.id = V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP_B,
 		.is_volatile = 1,
-		.mode = MFC_CTRL_MODE_CUSTOM,
-		.addr = S5P_FIMV_NEW_RC_QP_BOUND,
-		.mask = 0xFFFFFFFF,
-		.shft = 0,
-		.flag_mode = MFC_CTRL_MODE_CUSTOM,
-		.flag_addr = S5P_FIMV_PARAM_CHANGE_FLAG,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = S5P_FIMV_E_RC_QP_BOUND_PB,
+		.mask = 0x7F,
+		.shft = 24,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = S5P_FIMV_E_PARAM_CHANGE,
 		.flag_shft = 4,
 	},
-	{	/* H.264 QP Min change */
+	{	/* MPEG4 B frame QP Min change */
 		.type = MFC_CTRL_TYPE_SET,
-		.id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP,
+		.id = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP_B,
 		.is_volatile = 1,
-		.mode = MFC_CTRL_MODE_CUSTOM,
-		.addr = S5P_FIMV_NEW_RC_QP_BOUND,
-		.mask = 0xFFFFFFFF,
-		.shft = 0,
-		.flag_mode = MFC_CTRL_MODE_CUSTOM,
-		.flag_addr = S5P_FIMV_PARAM_CHANGE_FLAG,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = S5P_FIMV_E_RC_QP_BOUND_PB,
+		.mask = 0x7F,
+		.shft = 16,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = S5P_FIMV_E_PARAM_CHANGE,
 		.flag_shft = 4,
 	},
-	{	/* H.263 QP Max change */
+	{	/* HEVC B frame QP Max change */
 		.type = MFC_CTRL_TYPE_SET,
-		.id = V4L2_CID_MPEG_VIDEO_H263_MAX_QP,
+		.id = V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP_B,
 		.is_volatile = 1,
-		.mode = MFC_CTRL_MODE_CUSTOM,
-		.addr = S5P_FIMV_NEW_RC_QP_BOUND,
-		.mask = 0xFFFFFFFF,
-		.shft = 0,
-		.flag_mode = MFC_CTRL_MODE_CUSTOM,
-		.flag_addr = S5P_FIMV_PARAM_CHANGE_FLAG,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = S5P_FIMV_E_RC_QP_BOUND_PB,
+		.mask = 0x7F,
+		.shft = 24,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = S5P_FIMV_E_PARAM_CHANGE,
 		.flag_shft = 4,
 	},
-	{	/* H.263 QP Min change */
+	{	/* HEVC B frame QP Min change */
 		.type = MFC_CTRL_TYPE_SET,
-		.id = V4L2_CID_MPEG_VIDEO_H263_MIN_QP,
+		.id = V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP_B,
 		.is_volatile = 1,
-		.mode = MFC_CTRL_MODE_CUSTOM,
-		.addr = S5P_FIMV_NEW_RC_QP_BOUND,
-		.mask = 0xFFFFFFFF,
-		.shft = 0,
-		.flag_mode = MFC_CTRL_MODE_CUSTOM,
-		.flag_addr = S5P_FIMV_PARAM_CHANGE_FLAG,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = S5P_FIMV_E_RC_QP_BOUND_PB,
+		.mask = 0x7F,
+		.shft = 16,
+		.flag_mode = MFC_CTRL_MODE_SFR,
+		.flag_addr = S5P_FIMV_E_PARAM_CHANGE,
 		.flag_shft = 4,
 	},
-	{	/* MPEG4 QP Max change */
+
+	{	/* H.264 Dynamic Temporal Layer & bitrate change */
 		.type = MFC_CTRL_TYPE_SET,
-		.id = V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP,
+		.id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_CH,
 		.is_volatile = 1,
 		.mode = MFC_CTRL_MODE_CUSTOM,
-		.addr = S5P_FIMV_NEW_RC_QP_BOUND,
+		.addr = S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER0,
 		.mask = 0xFFFFFFFF,
 		.shft = 0,
 		.flag_mode = MFC_CTRL_MODE_CUSTOM,
 		.flag_addr = S5P_FIMV_PARAM_CHANGE_FLAG,
-		.flag_shft = 4,
+		.flag_shft = 10,
 	},
-	{	/* MPEG4 QP Min change */
+	{	/* HEVC Dynamic Temporal Layer & bitrate change */
 		.type = MFC_CTRL_TYPE_SET,
-		.id = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP,
+		.id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_CH,
 		.is_volatile = 1,
 		.mode = MFC_CTRL_MODE_CUSTOM,
-		.addr = S5P_FIMV_NEW_RC_QP_BOUND,
+		.addr = S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER0,
 		.mask = 0xFFFFFFFF,
 		.shft = 0,
 		.flag_mode = MFC_CTRL_MODE_CUSTOM,
 		.flag_addr = S5P_FIMV_PARAM_CHANGE_FLAG,
-		.flag_shft = 4,
+		.flag_shft = 10,
 	},
-	{	/* VP8 QP Max change */
+	{	/* VP8 Dynamic Temporal Layer change */
 		.type = MFC_CTRL_TYPE_SET,
-		.id = V4L2_CID_MPEG_VIDEO_VP8_MAX_QP,
+		.id = V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_CH,
 		.is_volatile = 1,
 		.mode = MFC_CTRL_MODE_CUSTOM,
-		.addr = S5P_FIMV_NEW_RC_QP_BOUND,
+		.addr = S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER0,
 		.mask = 0xFFFFFFFF,
 		.shft = 0,
 		.flag_mode = MFC_CTRL_MODE_CUSTOM,
 		.flag_addr = S5P_FIMV_PARAM_CHANGE_FLAG,
-		.flag_shft = 4,
+		.flag_shft = 10,
 	},
-	{	/* VP8 QP Min change */
+	{	/* set level */
 		.type = MFC_CTRL_TYPE_SET,
-		.id = V4L2_CID_MPEG_VIDEO_VP8_MIN_QP,
+		.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL,
 		.is_volatile = 1,
 		.mode = MFC_CTRL_MODE_CUSTOM,
-		.addr = S5P_FIMV_NEW_RC_QP_BOUND,
-		.mask = 0xFFFFFFFF,
-		.shft = 0,
-		.flag_mode = MFC_CTRL_MODE_CUSTOM,
+		.addr = S5P_FIMV_E_PICTURE_PROFILE,
+		.mask = 0x000000FF,
+		.shft = 8,
+		.flag_mode = MFC_CTRL_MODE_SFR,
 		.flag_addr = S5P_FIMV_PARAM_CHANGE_FLAG,
-		.flag_shft = 4,
+		.flag_shft = 5,
 	},
-	{	/* H.264 Dynamic Temporal Layer change */
+	{	/* set profile */
 		.type = MFC_CTRL_TYPE_SET,
-		.id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_CH,
+		.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE,
 		.is_volatile = 1,
 		.mode = MFC_CTRL_MODE_CUSTOM,
-		.addr = S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER0,
-		.mask = 0xFFFFFFFF,
+		.addr = S5P_FIMV_E_PICTURE_PROFILE,
+		.mask = 0x0000000F,
 		.shft = 0,
-		.flag_mode = MFC_CTRL_MODE_CUSTOM,
+		.flag_mode = MFC_CTRL_MODE_SFR,
 		.flag_addr = S5P_FIMV_PARAM_CHANGE_FLAG,
-		.flag_shft = 10,
+		.flag_shft = 5,
 	},
-	{	/* HEVC QP Max change */
+	{	/* set store LTR */
 		.type = MFC_CTRL_TYPE_SET,
-		.id = V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP,
+		.id = V4L2_CID_MPEG_MFC_H264_MARK_LTR,
 		.is_volatile = 1,
-		.mode = MFC_CTRL_MODE_CUSTOM,
-		.addr = S5P_FIMV_NEW_RC_QP_BOUND,
-		.mask = 0xFFFFFFFF,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = S5P_FIMV_E_H264_NAL_CONTROL,
+		.mask = 0x00000003,
 		.shft = 0,
-		.flag_mode = MFC_CTRL_MODE_CUSTOM,
-		.flag_addr = S5P_FIMV_PARAM_CHANGE_FLAG,
-		.flag_shft = 4,
+		.flag_mode = MFC_CTRL_MODE_NONE,
+		.flag_addr = 0,
+		.flag_shft = 0,
 	},
-	{	/* HEVC QP Min change */
+	{	/* set use LTR */
 		.type = MFC_CTRL_TYPE_SET,
-		.id = V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP,
+		.id = V4L2_CID_MPEG_MFC_H264_USE_LTR,
 		.is_volatile = 1,
-		.mode = MFC_CTRL_MODE_CUSTOM,
-		.addr = S5P_FIMV_NEW_RC_QP_BOUND,
-		.mask = 0xFFFFFFFF,
-		.shft = 0,
-		.flag_mode = MFC_CTRL_MODE_CUSTOM,
-		.flag_addr = S5P_FIMV_PARAM_CHANGE_FLAG,
-		.flag_shft = 4,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = S5P_FIMV_E_H264_NAL_CONTROL,
+		.mask = 0x00000003,
+		.shft = 2,
+		.flag_mode = MFC_CTRL_MODE_NONE,
+		.flag_addr = 0,
+		.flag_shft = 0,
 	},
-	{	/* VP8 Dynamic Temporal Layer change */
+	{	/* set base layer priority */
 		.type = MFC_CTRL_TYPE_SET,
-		.id = V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_CH,
+		.id = V4L2_CID_MPEG_MFC_H264_BASE_PRIORITY,
 		.is_volatile = 1,
-		.mode = MFC_CTRL_MODE_CUSTOM,
-		.addr = S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER0,
-		.mask = 0xFFFFFFFF,
+		.mode = MFC_CTRL_MODE_SFR,
+		.addr = S5P_FIMV_E_H264_HD_SVC_EXTENSION_0,
+		.mask = 0x0000003F,
 		.shft = 0,
-		.flag_mode = MFC_CTRL_MODE_CUSTOM,
+		.flag_mode = MFC_CTRL_MODE_SFR,
 		.flag_addr = S5P_FIMV_PARAM_CHANGE_FLAG,
-		.flag_shft = 10,
+		.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 = S5P_FIMV_E_FIXED_PICTURE_QP,
+		.mask = 0x0000007F,
+		.shft = 24,
+		.flag_mode = MFC_CTRL_MODE_NONE,
+		.flag_addr = 0,
+		.flag_shft = 0,
 	},
 };
 
@@ -1919,12 +2489,21 @@ static struct s5p_mfc_ctrl_cfg mfc_ctrl_list[] = {
 
 int s5p_mfc_enc_ctx_ready(struct s5p_mfc_ctx *ctx)
 {
+	struct s5p_mfc_dev *dev = ctx->dev;
 	struct s5p_mfc_enc *enc = ctx->enc_priv;
 	struct s5p_mfc_enc_params *p = &enc->params;
 
 	mfc_debug(2, "src=%d, dst=%d, state=%d\n",
 		  ctx->src_queue_cnt, ctx->dst_queue_cnt, ctx->state);
 
+	/* Skip ready check temporally */
+	spin_lock_irq(&dev->condlock);
+	if (test_bit(ctx->num, &dev->ctx_stop_bits)) {
+		spin_unlock_irq(&dev->condlock);
+		return 0;
+	}
+	spin_unlock_irq(&dev->condlock);
+
 	/* context is ready to make header */
 	if (ctx->state == MFCINST_GOT_INST && ctx->dst_queue_cnt >= 1) {
 		if (p->seq_hdr_mode == \
@@ -1946,6 +2525,10 @@ int s5p_mfc_enc_ctx_ready(struct s5p_mfc_ctx *ctx)
 	if (ctx->state == MFCINST_RUNNING_NO_OUTPUT &&
 		ctx->src_queue_cnt >= 1 && ctx->dst_queue_cnt >= 1)
 		return 1;
+	/* context is ready to encode a frame for NAL_ABORT command */
+	if (ctx->state == MFCINST_ABORT_INST &&
+		ctx->src_queue_cnt >= 1 && ctx->dst_queue_cnt >= 1)
+		return 1;
 	/* context is ready to encode remain frames */
 	if (ctx->state == MFCINST_FINISHING &&
 		ctx->src_queue_cnt >= 1 && ctx->dst_queue_cnt >= 1)
@@ -1956,6 +2539,40 @@ int s5p_mfc_enc_ctx_ready(struct s5p_mfc_ctx *ctx)
 	return 0;
 }
 
+static inline int h264_profile(struct s5p_mfc_ctx *ctx, enum v4l2_mpeg_video_h264_profile profile)
+{
+	struct s5p_mfc_dev *dev = ctx->dev;
+	int ret = 0;
+
+	switch (profile) {
+	case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
+		ret = S5P_FIMV_ENC_PROFILE_H264_MAIN;
+		break;
+	case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
+		ret = S5P_FIMV_ENC_PROFILE_H264_HIGH;
+		break;
+	case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
+		ret =S5P_FIMV_ENC_PROFILE_H264_BASELINE;
+		break;
+	case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
+		if (IS_MFCV6(dev))
+			ret = S5P_FIMV_ENC_PROFILE_H264_CONSTRAINED_BASELINE;
+		else
+			ret = -EINVAL;
+		break;
+	case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH:
+		if (IS_MFCV6(dev))
+			ret = S5P_FIMV_ENC_PROFILE_H264_CONSTRAINED_HIGH;
+		else
+			ret = -EINVAL;
+		break;
+	default:
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
 static int enc_cleanup_ctx_ctrls(struct s5p_mfc_ctx *ctx)
 {
 	struct s5p_mfc_ctx_ctrl *ctx_ctrl;
@@ -2265,9 +2882,10 @@ static int enc_set_buf_ctrls_val(struct s5p_mfc_ctx *ctx, struct list_head *head
 	struct s5p_mfc_buf_ctrl *buf_ctrl;
 	struct s5p_mfc_dev *dev = ctx->dev;
 	struct s5p_mfc_enc *enc = ctx->enc_priv;
-	unsigned int value = 0;
+	unsigned int value = 0, value2 = 0;
 	struct temporal_layer_info temporal_LC;
 	unsigned int i;
+	struct s5p_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)
@@ -2312,44 +2930,91 @@ static int enc_set_buf_ctrls_val(struct s5p_mfc_ctx *ctx, struct list_head *head
 		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) {
+			== V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_CH ||
+			buf_ctrl->id
+			== V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_CH) {
 			memcpy(&temporal_LC,
 				enc->sh_handle.virt, sizeof(struct temporal_layer_info));
 
-			if((temporal_LC.temporal_layer_count < 1) ||
-				((temporal_LC.temporal_layer_count > 7) &&
-				(ctx->codec_mode == S5P_FIMV_CODEC_H264_ENC)) ||
+			if(((temporal_LC.temporal_layer_count & 0x7) < 1) ||
 				((temporal_LC.temporal_layer_count > 3) &&
 				(ctx->codec_mode == S5P_FIMV_CODEC_VP8_ENC))) {
+				/* claer NUM_T_LAYER_CHANGE */
 				value = s5p_mfc_read_reg(dev, buf_ctrl->flag_addr);
 				value &= ~(1 << 10);
 				s5p_mfc_write_reg(dev, value, buf_ctrl->flag_addr);
-				mfc_err_ctx("temporal layer count is invalid : %d\n"
-					, temporal_LC.temporal_layer_count);
+				mfc_err_ctx("Temporal SVC: layer count is invalid : %d\n",
+					temporal_LC.temporal_layer_count);
 				goto invalid_layer_count;
 			}
 
-			value = s5p_mfc_read_reg(dev, buf_ctrl->flag_addr);
+			if (ctx->codec_mode == S5P_FIMV_CODEC_H264_ENC)
+				p->codec.h264.num_hier_layer = temporal_LC.temporal_layer_count & 0x7;
+
 			/* enable RC_BIT_RATE_CHANGE */
-			value |= (1 << 2);
+			value = s5p_mfc_read_reg(dev, buf_ctrl->flag_addr);
+			if (temporal_LC.temporal_layer_bitrate[0] > 0)
+				/* set RC_BIT_RATE_CHANGE */
+				value |= (1 << 2);
+			else
+				/* claer RC_BIT_RATE_CHANGE */
+				value &= ~(1 << 2);
 			s5p_mfc_write_reg(dev, value, buf_ctrl->flag_addr);
 
-			mfc_debug(2, "temporal layer count : %d\n", temporal_LC.temporal_layer_count);
-			if(ctx->codec_mode == S5P_FIMV_CODEC_H264_ENC)
-				s5p_mfc_write_reg(dev,
-					temporal_LC.temporal_layer_count, S5P_FIMV_E_H264_NUM_T_LAYER);
-			else if(ctx->codec_mode == S5P_FIMV_CODEC_VP8_ENC)
-				s5p_mfc_write_reg(dev,
-					temporal_LC.temporal_layer_count, S5P_FIMV_E_VP8_NUM_T_LAYER);
-			for(i = 0; i < temporal_LC.temporal_layer_count; i++) {
-				mfc_debug(2, "temporal layer bitrate[%d] : %d\n",
+			mfc_debug(3, "Temporal SVC: layer count %d, E_PARAM_CHANGE %#x\n",
+					temporal_LC.temporal_layer_count & 0x7, value);
+
+			value = s5p_mfc_read_reg(dev, S5P_FIMV_E_NUM_T_LAYER);
+			buf_ctrl->old_val2 = value;
+			value &= ~(0x7);
+			value |= (temporal_LC.temporal_layer_count & 0x7);
+			s5p_mfc_write_reg(dev, value, S5P_FIMV_E_NUM_T_LAYER);
+			mfc_debug(3, "Temporal SVC: E_NUM_T_LAYER %#x\n", value);
+			for(i = 0; i < (temporal_LC.temporal_layer_count & 0x7); i++) {
+				mfc_debug(3, "Temporal SVC: layer bitrate[%d] %d\n",
 					i, temporal_LC.temporal_layer_bitrate[i]);
 				s5p_mfc_write_reg(dev,
 					temporal_LC.temporal_layer_bitrate[i], buf_ctrl->addr + i * 4);
 			}
+
+			/* priority change */
+			if (ctx->codec_mode == S5P_FIMV_CODEC_H264_ENC) {
+				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));
+		}
+				s5p_mfc_write_reg(dev, value, S5P_FIMV_E_H264_HD_SVC_EXTENSION_0);
+				s5p_mfc_write_reg(dev, value2, S5P_FIMV_E_H264_HD_SVC_EXTENSION_1);
+				mfc_debug(3, "Temporal SVC: EXTENSION0 %#x, EXTENSION1 %#x\n",
+						value, value2);
+
+				value = s5p_mfc_read_reg(dev, buf_ctrl->flag_addr);
+				value |= (1 << 12);
+				s5p_mfc_write_reg(dev, value, buf_ctrl->flag_addr);
+				mfc_debug(3, "Temporal SVC: E_PARAM_CHANGE %#x\n", value);
+			}
 		}
+
+		if (buf_ctrl->id == V4L2_CID_MPEG_MFC_H264_MARK_LTR) {
+			value = s5p_mfc_read_reg(dev, S5P_FIMV_E_H264_NAL_CONTROL);
+			buf_ctrl->old_val2 = (value >> 8) & 0x7;
+			value &= ~(0x7 << 8);
+			value |= (buf_ctrl->val & 0x7) << 8;
+			s5p_mfc_write_reg(dev, value, S5P_FIMV_E_H264_NAL_CONTROL);
+		}
+		if (buf_ctrl->id == V4L2_CID_MPEG_MFC_H264_USE_LTR) {
+			value = s5p_mfc_read_reg(dev, S5P_FIMV_E_H264_NAL_CONTROL);
+			buf_ctrl->old_val2 = (value >> 11) & 0xF;
+			value &= ~(0xF << 11);
+			value |= (buf_ctrl->val & 0xF) << 11;
+			s5p_mfc_write_reg(dev, value, S5P_FIMV_E_H264_NAL_CONTROL);
+		}
+
 		if ((buf_ctrl->id == V4L2_CID_MPEG_MFC51_VIDEO_I_PERIOD_CH) && FW_HAS_GOP2(dev)) {
-			value = 0;
 			value = s5p_mfc_read_reg(dev, S5P_FIMV_E_GOP_CONFIG2);
 			buf_ctrl->old_val |= (value << 16) & 0x3FFF0000;
 			value &= ~(0x3FFF);
@@ -2357,12 +3022,61 @@ static int enc_set_buf_ctrls_val(struct s5p_mfc_ctx *ctx, struct list_head *head
 			s5p_mfc_write_reg(dev, value, S5P_FIMV_E_GOP_CONFIG2);
 		}
 
+		/* PROFILE & LEVEL have to be set up together */
+		if (buf_ctrl->id == V4L2_CID_MPEG_VIDEO_H264_LEVEL) {
+			value = s5p_mfc_read_reg(dev, S5P_FIMV_E_PICTURE_PROFILE);
+			buf_ctrl->old_val |= (value & 0x000F) << 8;
+			value &= ~(0x000F);
+			value |= p->codec.h264.profile & 0x000F;
+			s5p_mfc_write_reg(dev, value, S5P_FIMV_E_PICTURE_PROFILE);
+			p->codec.h264.level = buf_ctrl->val;
+		}
+		if (buf_ctrl->id == V4L2_CID_MPEG_VIDEO_H264_PROFILE) {
+			value = s5p_mfc_read_reg(dev, S5P_FIMV_E_PICTURE_PROFILE);
+			buf_ctrl->old_val |= value & 0xFF00;
+			value &= ~(0x00FF << 8);
+			value |= (p->codec.h264.level << 8) & 0xFF00;
+			s5p_mfc_write_reg(dev, value, S5P_FIMV_E_PICTURE_PROFILE);
+			p->codec.h264.profile = buf_ctrl->val;
+		}
+
+		/* temproral layer priority */
+		if (buf_ctrl->id == V4L2_CID_MPEG_MFC_H264_BASE_PRIORITY) {
+			value = s5p_mfc_read_reg(dev, S5P_FIMV_E_H264_HD_SVC_EXTENSION_0);
+			buf_ctrl->old_val |= value & 0x3FFFFFC0;
+			value &= ~(0x3FFFFFC0);
+			value2 = s5p_mfc_read_reg(dev, S5P_FIMV_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));
+			}
+			s5p_mfc_write_reg(dev, value, S5P_FIMV_E_H264_HD_SVC_EXTENSION_0);
+			s5p_mfc_write_reg(dev, value2, S5P_FIMV_E_H264_HD_SVC_EXTENSION_1);
+			p->codec.h264.base_priority = buf_ctrl->val;
+			mfc_debug(3, "Temporal SVC: EXTENSION0 %#x, EXTENSION1 %#x\n",
+					value, value2);
+		}
+		/* per buffer QP setting change */
+		if (buf_ctrl->id == V4L2_CID_MPEG_MFC_CONFIG_QP)
+			p->config_qp = buf_ctrl->val;
+
 invalid_layer_count:
 		mfc_debug(8, "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 = s5p_mfc_read_reg(dev, S5P_FIMV_E_FIXED_PICTURE_QP);
+		value &= ~(0xFF000000);
+		value |= (p->config_qp & 0xFF) << 24;
+		s5p_mfc_write_reg(dev, value, S5P_FIMV_E_FIXED_PICTURE_QP);
+	}
+
 	return 0;
 }
 
@@ -2438,12 +3152,51 @@ static int enc_recover_buf_ctrls_val(struct s5p_mfc_ctx *ctx,
 				"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 && FW_HAS_GOP2(dev)) {
-			value = 0;
 			value = s5p_mfc_read_reg(dev, S5P_FIMV_E_GOP_CONFIG2);
 			value &= ~(0x3FFF);
 			value |= (buf_ctrl->old_val >> 16) & 0x3FFF;
 			s5p_mfc_write_reg(dev, value, S5P_FIMV_E_GOP_CONFIG2);
 		}
+		if (buf_ctrl->id == V4L2_CID_MPEG_VIDEO_H264_LEVEL) {
+			value = s5p_mfc_read_reg(dev, S5P_FIMV_E_PICTURE_PROFILE);
+			value &= ~(0x000F);
+			value |= (buf_ctrl->old_val >> 8) & 0x000F;
+			s5p_mfc_write_reg(dev, value, S5P_FIMV_E_PICTURE_PROFILE);
+		}
+		if (buf_ctrl->id == V4L2_CID_MPEG_VIDEO_H264_PROFILE) {
+			value = s5p_mfc_read_reg(dev, S5P_FIMV_E_PICTURE_PROFILE);
+			value &= ~(0xFF00);
+			value |= buf_ctrl->old_val & 0xFF00;
+			s5p_mfc_write_reg(dev, value, S5P_FIMV_E_PICTURE_PROFILE);
+		}
+		if (buf_ctrl->id == V4L2_CID_MPEG_MFC_H264_BASE_PRIORITY) {
+			s5p_mfc_write_reg(dev, buf_ctrl->old_val, S5P_FIMV_E_H264_HD_SVC_EXTENSION_0);
+			s5p_mfc_write_reg(dev, buf_ctrl->old_val2, S5P_FIMV_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) {
+			s5p_mfc_write_reg(dev, buf_ctrl->old_val2, S5P_FIMV_E_NUM_T_LAYER);
+			/* clear RC_BIT_RATE_CHANGE */
+			value = s5p_mfc_read_reg(dev, buf_ctrl->flag_addr);
+			value &= ~(1 << 2);
+			s5p_mfc_write_reg(dev, value, buf_ctrl->flag_addr);
+			}
+		if (buf_ctrl->id == V4L2_CID_MPEG_MFC_H264_MARK_LTR) {
+			value = s5p_mfc_read_reg(dev, S5P_FIMV_E_H264_NAL_CONTROL);
+			value &= ~(0x7 << 8);
+			value |= (buf_ctrl->old_val2 & 0x7) << 8;
+			s5p_mfc_write_reg(dev, value, S5P_FIMV_E_H264_NAL_CONTROL);
+		}
+		if (buf_ctrl->id == V4L2_CID_MPEG_MFC_H264_USE_LTR) {
+			value = s5p_mfc_read_reg(dev, S5P_FIMV_E_H264_NAL_CONTROL);
+			value &= ~(0xF << 11);
+			value |= (buf_ctrl->old_val2 & 0xF) << 11;
+			s5p_mfc_write_reg(dev, value, S5P_FIMV_E_H264_NAL_CONTROL);
+		}
 	}
 
 	return 0;
@@ -2597,9 +3350,14 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
 	strm_size = s5p_mfc_get_enc_strm_size();
 	pic_count = s5p_mfc_get_enc_pic_count();
 
-	mfc_debug(2, "encoded slice type: %d", slice_type);
-	mfc_debug(2, "encoded stream size: %d", strm_size);
-	mfc_debug(2, "display order: %d", pic_count);
+	mfc_debug(2, "encoded slice type: %d\n", slice_type);
+	mfc_debug(2, "encoded stream size: %d\n", strm_size);
+	mfc_debug(2, "display order: %d\n", pic_count);
+
+	if (enc->buf_full) {
+		ctx->state = MFCINST_ABORT_INST;
+		return 0;
+	}
 
 	/* set encoded frame type */
 	enc->frame_type = slice_type;
@@ -2608,7 +3366,8 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
 	spin_lock_irqsave(&dev->irqlock, flags);
 
 	ctx->sequence++;
-	if (strm_size > 0 || ctx->state == MFCINST_FINISHING) {
+	if (strm_size > 0 || ctx->state == MFCINST_FINISHING
+			  || ctx->state == MFCINST_RUNNING_BUF_FULL) {
 		/* at least one more dest. buffers exist always  */
 		mb_entry = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);
 
@@ -2666,9 +3425,10 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
 		return 0;
 	}
 
-	if (slice_type >= 0 &&
+	if (!ctx->enc_res_change_re_input && slice_type >= 0 &&
 			ctx->state != MFCINST_FINISHING) {
-		if (ctx->state == MFCINST_RUNNING_NO_OUTPUT)
+		if (ctx->state == MFCINST_RUNNING_NO_OUTPUT ||
+			ctx->state == MFCINST_RUNNING_BUF_FULL)
 			ctx->state = MFCINST_RUNNING;
 
 		s5p_mfc_get_enc_frame_buffer(ctx, &enc_addr[0], raw->num_planes);
@@ -2725,9 +3485,13 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
 		vb2_buffer_done(&mb_entry->vb, VB2_BUF_STATE_DONE);
 	}
 
+	if (ctx->enc_res_change_re_input)
+		ctx->enc_res_change_re_input = 0;
+
 	if ((ctx->src_queue_cnt > 0) &&
 		((ctx->state == MFCINST_RUNNING) ||
-		 (ctx->state == MFCINST_RUNNING_NO_OUTPUT))) {
+		 (ctx->state == MFCINST_RUNNING_NO_OUTPUT) ||
+		 (ctx->state == MFCINST_RUNNING_BUF_FULL))) {
 		mb_entry = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
 
 		if (mb_entry->used) {
@@ -2946,10 +3710,18 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
 	if (ret)
 		return ret;
 
-	if (ctx->vq_src.streaming || ctx->vq_dst.streaming) {
-		v4l2_err(&dev->v4l2_dev, "%s queue busy\n", __func__);
-		ret = -EBUSY;
-		goto out;
+	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+		if (ctx->vq_dst.streaming) {
+			v4l2_err(&dev->v4l2_dev, "%s dst queue busy\n", __func__);
+			ret = -EBUSY;
+			goto out;
+		}
+	} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+		if (ctx->vq_src.streaming) {
+			v4l2_err(&dev->v4l2_dev, "%s src queue busy\n", __func__);
+			ret = -EBUSY;
+			goto out;
+		}
 	}
 
 	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
@@ -3014,6 +3786,12 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
 		ctx->img_height = pix_fmt_mp->height;
 		ctx->buf_stride = pix_fmt_mp->plane_fmt[0].bytesperline;
 
+		if ((ctx->state == MFCINST_RUNNING)
+			&& (((ctx->old_img_width != 0) && (ctx->old_img_width != ctx->img_width))
+				|| ((ctx->old_img_height != 0) && (ctx->old_img_height != ctx->img_height)))) {
+			ctx->enc_drc_flag = 1;
+		}
+
 		mfc_info_ctx("Enc input pixelformat : %s\n", ctx->src_fmt->name);
 		mfc_info_ctx("fmt - w: %d, h: %d, stride: %d\n",
 			pix_fmt_mp->width, pix_fmt_mp->height, ctx->buf_stride);
@@ -3184,11 +3962,18 @@ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
 	int ret = -EINVAL;
 
 	mfc_debug_enter();
+
 	mfc_debug(2, "Enqueued buf: %d (type = %d)\n", buf->index, buf->type);
 	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) {
 		ret = vb2_qbuf(&ctx->vq_src, buf);
 		if (!ret) {
@@ -3236,9 +4021,10 @@ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
 calc_again:
 #endif
 			if (ctx->last_framerate != 0 &&
-				ctx->last_framerate != ctx->framerate) {
-				mfc_debug(2, "fps changed: %d -> %d\n",
-					ctx->framerate, ctx->last_framerate);
+				((ctx->last_framerate != ctx->framerate) || ctx->qos_changed)) {
+				mfc_debug(2, "fps changed: %d -> %d (%s)\n",
+					ctx->framerate, ctx->last_framerate,
+					ctx->use_extra_qos ? "extra" : "normal");
 				ctx->framerate = ctx->last_framerate;
 				s5p_mfc_qos_on(ctx);
 			}
@@ -3313,6 +4099,13 @@ static int vidioc_streamoff(struct file *file, void *priv,
 	if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
 		ctx->last_framerate = 0;
 		memset(&ctx->last_timestamp, 0, sizeof(struct timeval));
+
+		ctx->old_img_width = ctx->img_width;
+		ctx->old_img_height = ctx->img_height;
+
+		mfc_debug(2, "vidioc_streamoff ctx->old_img_width = %d\n", ctx->old_img_width);
+		mfc_debug(2, "vidioc_streamoff ctx->old_img_height = %d\n", ctx->old_img_height);
+
 		ret = vb2_streamoff(&ctx->vq_src, type);
 		if (!ret)
 			s5p_mfc_qos_off(ctx);
@@ -3351,6 +4144,11 @@ static int enc_ext_info(struct s5p_mfc_ctx *ctx)
 	if (FW_HAS_TEMPORAL_SVC_CH(dev))
 		val |= ENC_SET_TEMP_SVC_CH;
 
+	if (FW_SUPPORT_SKYPE(dev))
+		val |= ENC_SET_SKYPE_FLAG;
+
+	val |= ENC_SET_QP_BOUND_PB;
+
 	return val;
 }
 
@@ -3414,6 +4212,9 @@ static int get_ctrl_val(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl)
 	case V4L2_CID_MPEG_MFC_GET_VERSION_INFO:
 		ctrl->value = mfc_version(dev);
 		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(mfc_version(dev));
 		break;
@@ -3530,6 +4331,9 @@ static int set_enc_param(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl)
 	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;
@@ -3572,29 +4376,8 @@ static int set_enc_param(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl)
 		p->num_b_frame = ctrl->value;
 		break;
 	case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
-		switch ((enum v4l2_mpeg_video_h264_profile)(ctrl->value)) {
-		case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
-			p->codec.h264.profile =
-				S5P_FIMV_ENC_PROFILE_H264_MAIN;
-			break;
-		case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
-			p->codec.h264.profile =
-				S5P_FIMV_ENC_PROFILE_H264_HIGH;
-			break;
-		case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
-			p->codec.h264.profile =
-				S5P_FIMV_ENC_PROFILE_H264_BASELINE;
-			break;
-		case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
-			if (IS_MFCV6(dev))
-				p->codec.h264.profile =
-				S5P_FIMV_ENC_PROFILE_H264_CONSTRAINED_BASELINE;
-			else
-				ret = -EINVAL;
-			break;
-		default:
-			ret = -EINVAL;
-		}
+		p->codec.h264.profile =
+		h264_profile(ctx, (enum v4l2_mpeg_video_h264_profile)(ctrl->value));
 		break;
 	case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
 		p->codec.h264.level =
@@ -3638,6 +4421,18 @@ static int set_enc_param(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl)
 	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;
@@ -3676,39 +4471,40 @@ static int set_enc_param(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl)
 		p->codec.h264.open_gop_size = ctrl->value;
 		break;
 	case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING:
-		p->codec.h264.hier_qp = ctrl->value;
+		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.hier_qp_layer = ctrl->value;
+		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_qp[(ctrl->value >> 16) & 0x7]
+		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_qp_layer_bit[0] = ctrl->value;
+		p->codec.h264.hier_bit_layer[0] = ctrl->value;
 		break;
 	case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT1:
-		p->codec.h264.hier_qp_layer_bit[1] = ctrl->value;
+		p->codec.h264.hier_bit_layer[1] = ctrl->value;
 		break;
 	case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT2:
-		p->codec.h264.hier_qp_layer_bit[2] = ctrl->value;
+		p->codec.h264.hier_bit_layer[2] = ctrl->value;
 		break;
 	case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT3:
-		p->codec.h264.hier_qp_layer_bit[3] = ctrl->value;
+		p->codec.h264.hier_bit_layer[3] = ctrl->value;
 		break;
 	case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT4:
-		p->codec.h264.hier_qp_layer_bit[4] = ctrl->value;
+		p->codec.h264.hier_bit_layer[4] = ctrl->value;
 		break;
 	case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT5:
-		p->codec.h264.hier_qp_layer_bit[5] = ctrl->value;
+		p->codec.h264.hier_bit_layer[5] = ctrl->value;
 		break;
 	case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT6:
-		p->codec.h264.hier_qp_layer_bit[6] = ctrl->value;
+		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;
@@ -3760,6 +4556,16 @@ static int set_enc_param(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl)
 	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:
@@ -3787,6 +4593,18 @@ static int set_enc_param(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl)
 	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;
@@ -3814,6 +4632,12 @@ static int set_enc_param(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl)
 	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;
@@ -3829,6 +4653,12 @@ static int set_enc_param(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl)
 	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;
@@ -3851,28 +4681,28 @@ static int set_enc_param(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl)
 		p->codec.vp8.vp8_gfrefreshperiod = ctrl->value;
 		break;
 	case V4L2_CID_MPEG_MFC70_VIDEO_VP8_HIERARCHY_QP_ENABLE:
-		p->codec.vp8.hierarchy_qp_enable = ctrl->value;
+		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_qp[(ctrl->value >> 16) & 0x3]
+		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_qp[(ctrl->value >> 16) & 0x3]
+		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_qp[(ctrl->value >> 16) & 0x3]
+		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_qp_layer_bit[0] = ctrl->value;
+		p->codec.vp8.hier_bit_layer[0] = ctrl->value;
 		break;
 	case V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_BIT1:
-		p->codec.vp8.hier_qp_layer_bit[1] = ctrl->value;
+		p->codec.vp8.hier_bit_layer[1] = ctrl->value;
 		break;
 	case V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_BIT2:
-		p->codec.vp8.hier_qp_layer_bit[2] = ctrl->value;
+		p->codec.vp8.hier_bit_layer[2] = ctrl->value;
 		break;
 	case V4L2_CID_MPEG_MFC70_VIDEO_VP8_REF_NUMBER_FOR_PFRAMES:
 		p->codec.vp8.num_refs_for_p = ctrl->value;
@@ -3881,7 +4711,7 @@ static int set_enc_param(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl)
 		p->codec.vp8.intra_4x4mode_disable = ctrl->value;
 		break;
 	case V4L2_CID_MPEG_MFC70_VIDEO_VP8_NUM_TEMPORAL_LAYER:
-		p->codec.vp8.num_temporal_layer = ctrl->value;
+		p->codec.vp8.num_hier_layer = ctrl->value;
 		break;
 	case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP:
 		p->codec.hevc.rc_frame_qp = ctrl->value;
@@ -3901,6 +4731,18 @@ static int set_enc_param(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl)
 	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;
@@ -3943,25 +4785,46 @@ static int set_enc_param(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl)
 		p->codec.hevc.loopfilter_disable = ctrl->value;
 		break;
 	case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LF_SLICE_BOUNDARY:
-		p->codec.hevc.loopfilter_disable = ctrl->value;
+		p->codec.hevc.loopfilter_across = ctrl->value;
 		break;
 	case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LTR_ENABLE:
-		p->codec.hevc.longterm_ref_enable = ctrl->value;
+		p->codec.hevc.enable_ltr = ctrl->value;
 		break;
 	case V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_QP_ENABLE:
-		p->codec.hevc.hier_qp = ctrl->value;
+		p->codec.hevc.hier_qp_enable = ctrl->value;
 		break;
 	case V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_TYPE:
-		p->codec.hevc.hier_qp_type = ctrl->value;
+		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.hier_qp_layer = ctrl->value;
+		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_qp = ctrl->value & 0xFF;
+		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_BIT:
-		p->codec.hevc.hier_qp_layer_bit = ctrl->value & 0xFF;
+	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_SIGN_DATA_HIDING:
 		p->codec.hevc.sign_data_hiding = ctrl->value;
@@ -3990,12 +4853,6 @@ static int set_enc_param(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl)
 	case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_REFRESH_PERIOD:
 		p->codec.hevc.refreshperiod = ctrl->value;
 		break;
-	case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_QP_INDEX_CR:
-		p->codec.hevc.croma_qp_offset_cr = ctrl->value;
-		break;
-	case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_QP_INDEX_CB:
-		p->codec.hevc.croma_qp_offset_cb = ctrl->value;
-		break;
 	case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LF_BETA_OFFSET_DIV2:
 		p->codec.hevc.lf_beta_offset_div2 = ctrl->value;
 		break;
@@ -4011,6 +4868,21 @@ static int set_enc_param(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl)
 	case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_STORE_REF:
 		p->codec.hevc.store_ref = 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_TEMPORAL_SHORTTERM_MAX_LAYER:
+		p->num_hier_max_layer = ctrl->value;
+		break;
 	default:
 		v4l2_err(&dev->v4l2_dev, "Invalid control\n");
 		ret = -EINVAL;
@@ -4090,23 +4962,45 @@ static int set_ctrl_val(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl)
 			ctx->cacheable = 0;
 		break;
 	case V4L2_CID_MPEG_VIDEO_QOS_RATIO:
+		if (ctrl->value > 150)
+			ctrl->value = 1000;
+		if (ctrl->value == 0) {
+			ctrl->value = 100;
+			ctx->use_extra_qos = 1;
+			mfc_info_ctx("QOS_RATIO is 0, use extra qos!\n");
+		} else {
+			ctx->use_extra_qos = 0;
+			mfc_info_ctx("QOS_RATIO is %d, use extra qos!\n", ctrl->value);
+		}
 		ctx->qos_ratio = ctrl->value;
+		ctx->qos_changed = 1;
 		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_HEVC_MAX_QP:
-		ctx->qp_max_change = ctrl->value;
-		break;
 	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_HEVC_MIN_QP:
-		ctx->qp_min_change = ctrl->value;
-		ctrl->value = ((ctx->qp_max_change << 8)
-			| (ctx->qp_min_change));
+	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_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_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:
@@ -4114,6 +5008,13 @@ static int set_ctrl_val(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl)
 	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_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:
 		list_for_each_entry(ctx_ctrl, &ctx->ctrls, list) {
 			if (!(ctx_ctrl->type & MFC_CTRL_TYPE_SET))
 				continue;
@@ -4128,7 +5029,9 @@ static int set_ctrl_val(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl)
 				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)) &&
+					V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_CH) ||
+					(ctx_ctrl->id == \
+					V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_CH)) &&
 					(enc->sh_handle.fd == -1)) {
 						enc->sh_handle.fd = ctrl->value;
 						if (process_user_shared_handle_enc(ctx)) {
@@ -4136,6 +5039,10 @@ static int set_ctrl_val(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl)
 							return -EINVAL;
 						}
 				}
+				if (ctx_ctrl->id == V4L2_CID_MPEG_VIDEO_H264_LEVEL)
+					ctx_ctrl->val = h264_level((enum v4l2_mpeg_video_h264_level)(ctrl->value));
+				if (ctx_ctrl->id == V4L2_CID_MPEG_VIDEO_H264_PROFILE)
+					ctx_ctrl->val = h264_profile(ctx, (enum v4l2_mpeg_video_h264_profile)(ctrl->value));
 				found = 1;
 				break;
 			}
@@ -4582,10 +5489,6 @@ static int s5p_mfc_start_streaming(struct vb2_queue *q, unsigned int count)
 	return 0;
 }
 
-#define need_to_wait_frame_start(ctx)		\
-	(((ctx->state == MFCINST_FINISHING) ||	\
-	  (ctx->state == MFCINST_RUNNING)) &&	\
-	 test_bit(ctx->num, &ctx->dev->hw_lock))
 static int s5p_mfc_stop_streaming(struct vb2_queue *q)
 {
 	unsigned long flags;
@@ -4594,16 +5497,32 @@ static int s5p_mfc_stop_streaming(struct vb2_queue *q)
 	struct s5p_mfc_enc *enc = ctx->enc_priv;
 	int index = 0;
 	int aborted = 0;
+	int ret = 0;
+
+	mfc_info_ctx("enc stop_streaming is called, hw_lock : %d, type : %d\n",
+				test_bit(ctx->num, &dev->hw_lock), q->type);
+	MFC_TRACE_CTX("** ENC streamoff(type:%d)\n", q->type);
 
-	if (need_to_wait_frame_start(ctx)) {
-		ctx->state = MFCINST_ABORT;
+	spin_lock_irq(&dev->condlock);
+	set_bit(ctx->num, &dev->ctx_stop_bits);
+	clear_bit(ctx->num, &dev->ctx_work_bits);
+	spin_unlock_irq(&dev->condlock);
+
+	/* If a H/W operation is in progress, wait for it complete */
+	 if (need_to_wait_nal_abort(ctx)) {
 		if (s5p_mfc_wait_for_done_ctx(ctx,
-				S5P_FIMV_R2H_CMD_FRAME_DONE_RET))
+				S5P_FIMV_R2H_CMD_NAL_ABORT_RET))
 			s5p_mfc_cleanup_timeout(ctx);
 		aborted = 1;
+	} else if (test_bit(ctx->num, &dev->hw_lock)) {
+		ret = wait_event_timeout(ctx->queue,
+				(test_bit(ctx->num, &dev->hw_lock) == 0),
+				msecs_to_jiffies(MFC_INT_TIMEOUT));
+		if (ret == 0)
+			mfc_err_ctx("wait for event failed\n");
 	}
 
-	if (enc->in_slice) {
+	if (enc->in_slice || enc->buf_full) {
 		ctx->state = MFCINST_ABORT_INST;
 		spin_lock_irq(&dev->condlock);
 		set_bit(ctx->num, &dev->ctx_work_bits);
@@ -4614,6 +5533,7 @@ static int s5p_mfc_stop_streaming(struct vb2_queue *q)
 			s5p_mfc_cleanup_timeout(ctx);
 
 		enc->in_slice = 0;
+		enc->buf_full = 0;
 		aborted = 1;
 	}
 
@@ -4649,9 +5569,25 @@ static int s5p_mfc_stop_streaming(struct vb2_queue *q)
 
 	spin_unlock_irqrestore(&dev->irqlock, flags);
 
-	if (aborted)
+	if (aborted || ctx->state == MFCINST_FINISHING)
 		ctx->state = MFCINST_RUNNING;
 
+	spin_lock_irq(&dev->condlock);
+	clear_bit(ctx->num, &dev->ctx_stop_bits);
+	spin_unlock_irq(&dev->condlock);
+
+	mfc_debug(2, "buffer cleanup is done in stop_streaming, type : %d\n", q->type);
+
+	if (s5p_mfc_enc_ctx_ready(ctx)) {
+		spin_lock_irq(&dev->condlock);
+		set_bit(ctx->num, &dev->ctx_work_bits);
+		spin_unlock_irq(&dev->condlock);
+	}
+	spin_lock_irq(&dev->condlock);
+	if (dev->ctx_work_bits)
+		queue_work(dev->sched_wq, &dev->sched_work);
+	spin_unlock_irq(&dev->condlock);
+
 	return 0;
 }
 
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_enc.h b/drivers/media/platform/exynos/mfc/s5p_mfc_enc.h
old mode 100644
new mode 100755
index 541a61de1158..9fb31c764da3
--- a/drivers/media/platform/exynos/mfc/s5p_mfc_enc.h
+++ b/drivers/media/platform/exynos/mfc/s5p_mfc_enc.h
@@ -16,7 +16,7 @@
 #define MFC_ENC_AVG_FPS_MODE
 
 #define ENC_HIGH_FPS	(70000)
-#define ENC_MAX_FPS	(120000)
+#define ENC_MAX_FPS	(240000)
 #define ENC_AVG_FRAMES	(10)
 
 const struct v4l2_ioctl_ops *get_enc_v4l2_ioctl_ops(void);
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_inst.c b/drivers/media/platform/exynos/mfc/s5p_mfc_inst.c
old mode 100644
new mode 100755
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_inst.h b/drivers/media/platform/exynos/mfc/s5p_mfc_inst.h
old mode 100644
new mode 100755
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_intr.c b/drivers/media/platform/exynos/mfc/s5p_mfc_intr.c
old mode 100644
new mode 100755
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_intr.h b/drivers/media/platform/exynos/mfc/s5p_mfc_intr.h
old mode 100644
new mode 100755
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_mem.c b/drivers/media/platform/exynos/mfc/s5p_mfc_mem.c
old mode 100644
new mode 100755
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_mem.h b/drivers/media/platform/exynos/mfc/s5p_mfc_mem.h
old mode 100644
new mode 100755
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v5.c b/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v5.c
old mode 100644
new mode 100755
index 1a3cf0b99e5d..fadfa7edd5b5
--- a/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v5.c
+++ b/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v5.c
@@ -881,10 +881,10 @@ static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx)
 
 	/* multi-slice control */
 	/* multi-slice MB number or bit size */
-	if (p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB) {
+	if (p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB) {
 		WRITEL(((0x0 << 1) | 0x1), S5P_FIMV_ENC_MSLICE_CTRL);
 		WRITEL(p->slice_mb, S5P_FIMV_ENC_MSLICE_MB);
-	} else if (p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES) {
+	} else if (p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES) {
 		WRITEL(((0x1 << 1) | 0x1), S5P_FIMV_ENC_MSLICE_CTRL);
 		WRITEL(p->slice_bit, S5P_FIMV_ENC_MSLICE_BIT);
 	} else {
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v5.h b/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v5.h
old mode 100644
new mode 100755
index 8ad06de595f2..e851e179e17c
--- a/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v5.h
+++ b/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v5.h
@@ -144,6 +144,7 @@ void s5p_mfc_enc_calc_src_size(struct s5p_mfc_ctx *ctx);
 #define ENC_MULTI_SLICE_MB_MAX		((1 << 16) - 1)
 #define ENC_MULTI_SLICE_BIT_MIN		1900
 #define ENC_MULTI_SLICE_BYTE_MIN	238
+#define ENC_MULTI_SLICE_MB_ROW_MAX	100
 #define ENC_INTRA_REFRESH_MB_MAX	((1 << 16) - 1)
 #define ENC_VBV_BUF_SIZE_MAX		((1 << 16) - 1)
 #define ENC_H264_LOOP_FILTER_AB_MIN	-6
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v6.c
old mode 100644
new mode 100755
index 04ced6aa052f..c9b11c116d65
--- a/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v6.c
+++ b/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v6.c
@@ -333,6 +333,9 @@ int s5p_mfc_alloc_codec_buffers(struct s5p_mfc_ctx *ctx)
 			(ctx->dpb_count * (enc->luma_dpb_size +
 			enc->chroma_dpb_size + enc->me_buffer_size));
 		ctx->port_b_size = 0;
+
+		ctx->scratch_buf_size = max(ctx->scratch_buf_size, ctx->min_scratch_buf_size);
+		ctx->min_scratch_buf_size = 0;
 		break;
 	case S5P_FIMV_CODEC_MPEG4_ENC:
 	case S5P_FIMV_CODEC_H263_ENC:
@@ -399,6 +402,15 @@ int s5p_mfc_alloc_codec_buffers(struct s5p_mfc_ctx *ctx)
 			return -ENOMEM;
 		}
 		ctx->port_a_phys = s5p_mfc_mem_daddr_priv(ctx->port_a_buf);
+		ctx->port_a_virt = s5p_mfc_mem_vaddr_priv(ctx->port_a_buf);
+		if (!ctx->port_a_virt) {
+			s5p_mfc_mem_free_priv(ctx->port_a_buf);
+			ctx->port_a_buf = NULL;
+			ctx->port_a_phys = 0;
+
+			mfc_err_ctx("Get vaddr for codec buffer failed.\n");
+			return -ENOMEM;
+		}
 	}
 
 	mfc_debug_leave();
@@ -982,7 +994,7 @@ int s5p_mfc_set_dec_stream_buffer(struct s5p_mfc_ctx *ctx, dma_addr_t buf_addr,
 	if (cpb_buf_size < strm_size + 4)
 		mfc_info_ctx("cpb_buf_size(%zu) < strm_size(0x%08x) + 4 bytes\n",
 				cpb_buf_size, strm_size);
-	if (ctx->state == MFCINST_GOT_INST && strm_size == 0)
+	if (strm_size == 0)
 		mfc_info_ctx("stream size is 0\n");
 
 	WRITEL(strm_size, S5P_FIMV_D_STREAM_DATA_SIZE);
@@ -1283,6 +1295,8 @@ int s5p_mfc_set_enc_stream_buffer(struct s5p_mfc_ctx *ctx,
 {
 	struct s5p_mfc_dev *dev = ctx->dev;
 
+	size = ALIGN(size, 512);
+
 	WRITEL(addr, S5P_FIMV_E_STREAM_BUFFER_ADDR); /* 16B align */
 	WRITEL(size, S5P_FIMV_E_STREAM_BUFFER_SIZE);
 
@@ -1390,16 +1404,18 @@ static int s5p_mfc_set_slice_mode(struct s5p_mfc_ctx *ctx)
 	struct s5p_mfc_enc *enc = ctx->enc_priv;
 
 	/* multi-slice control */
-	if (enc->slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES)
+	if (enc->slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES)
 		WRITEL((enc->slice_mode + 0x4), S5P_FIMV_E_MSLICE_MODE);
+	else if (enc->slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB_ROW)
+		WRITEL((enc->slice_mode - 0x2), S5P_FIMV_E_MSLICE_MODE);
 	else
 		WRITEL(enc->slice_mode, S5P_FIMV_E_MSLICE_MODE);
 
 	/* multi-slice MB number or bit size */
-	if (enc->slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB) {
+	if (enc->slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB || \
+			enc->slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB_ROW) {
 		WRITEL(enc->slice_size.mb, S5P_FIMV_E_MSLICE_SIZE_MB);
-	} else if (enc->slice_mode == \
-			V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES) {
+	} else if (enc->slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES) {
 		WRITEL(enc->slice_size.bits, S5P_FIMV_E_MSLICE_SIZE_BITS);
 	} else {
 		WRITEL(0x0, S5P_FIMV_E_MSLICE_SIZE_MB);
@@ -1410,6 +1426,77 @@ static int s5p_mfc_set_slice_mode(struct s5p_mfc_ctx *ctx)
 
 }
 
+void s5p_mfc_set_default_params(struct s5p_mfc_ctx *ctx)
+{
+	struct s5p_mfc_dev *dev = ctx->dev;
+
+	/* Default setting for quality */
+	/* Common Registers */
+	WRITEL(0x0, S5P_FIMV_E_ENC_OPTIONS);
+	WRITEL(0x0, S5P_FIMV_E_FIXED_PICTURE_QP);
+	WRITEL(0x80, S5P_FIMV_E_MV_HOR_RANGE);
+	WRITEL(0x80, S5P_FIMV_E_MV_VER_RANGE);
+	WRITEL(0x0, S5P_FIMV_E_IR_SIZE);
+	WRITEL(0x0, S5P_FIMV_E_AIR_THRESHOLD);
+	WRITEL(0x1E, S5P_FIMV_E_GOP_CONFIG); /* I frame period: 30 */
+	WRITEL(0x0, S5P_FIMV_E_GOP_CONFIG2);
+	WRITEL(0x0, S5P_FIMV_E_MSLICE_MODE);
+
+	/* Hierarchical Coding */
+	WRITEL(0x8, S5P_FIMV_E_NUM_T_LAYER);
+
+	/* Rate Control */
+	WRITEL(0x4000, S5P_FIMV_E_RC_CONFIG);
+	WRITEL(0x0, S5P_FIMV_E_RC_QP_BOUND);
+	WRITEL(0x0, S5P_FIMV_E_RC_QP_BOUND_PB);
+	WRITEL(0x2, S5P_FIMV_E_RC_MODE);
+	WRITEL(0xF, S5P_FIMV_E_MB_RC_CONFIG);
+	WRITEL(0x1E0001, S5P_FIMV_E_RC_FRAME_RATE); /* framerate: 30 fps */
+	WRITEL(0xF4240, S5P_FIMV_E_RC_BIT_RATE); /* bitrate: 1000000 */
+	WRITEL(0x3FD00, S5P_FIMV_E_RC_ROI_CTRL);
+	WRITEL(0x0, S5P_FIMV_E_VBV_BUFFER_SIZE);
+	WRITEL(0x0, S5P_FIMV_E_VBV_INIT_DELAY);
+	WRITEL(0x0, S5P_FIMV_E_BIT_COUNT_ENABLE);
+	WRITEL(0x2710, S5P_FIMV_E_MAX_BIT_COUNT); /* max bit count: 10000 */
+	WRITEL(0x3E8, S5P_FIMV_E_MIN_BIT_COUNT); /* min bit count: 1000 */
+
+	/* HEVC */
+	WRITEL(0x50F215, S5P_FIMV_E_HEVC_OPTIONS);
+	WRITEL(0x1E, S5P_FIMV_E_HEVC_REFRESH_PERIOD);
+	WRITEL(0x0, S5P_FIMV_E_HEVC_CHROMA_QP_OFFSET);
+	WRITEL(0x0, S5P_FIMV_E_HEVC_LF_BETA_OFFSET_DIV2);
+	WRITEL(0x0, S5P_FIMV_E_HEVC_LF_TC_OFFSET_DIV2);
+
+	/* H.264 */
+	WRITEL(0x3011, S5P_FIMV_E_H264_OPTIONS);
+	WRITEL(0x0, S5P_FIMV_E_H264_OPTIONS_2);
+	WRITEL(0x0, S5P_FIMV_E_H264_LF_ALPHA_OFFSET);
+	WRITEL(0x0, S5P_FIMV_E_H264_LF_BETA_OFFSET);
+	WRITEL(0x0, S5P_FIMV_E_H264_I_PERIOD);
+	WRITEL(0x0, S5P_FIMV_E_H264_CHROMA_QP_OFFSET);
+
+	/* VP8 */
+	WRITEL(0x0, S5P_FIMV_E_VP8_OPTION);
+	WRITEL(0x0, S5P_FIMV_E_VP8_GOLDEN_FRAME_OPTION);
+
+	/* MVC */
+	WRITEL(0x1D, S5P_FIMV_E_MVC_FRAME_QP_VIEW1); /* QP: 29 */
+	WRITEL(0xF4240, S5P_FIMV_E_MVC_RC_BIT_RATE_VIEW1); /* bitrate: 1000000 */
+	WRITEL(0x33003300, S5P_FIMV_E_MVC_RC_QBOUND_VIEW1); /* max I, P QP: 51 */
+	WRITEL(0x2, S5P_FIMV_E_MVC_RC_MODE_VIEW1);
+	WRITEL(0x1, S5P_FIMV_E_MVC_INTER_VIEW_PREDICTION_ON);
+
+	/* Additional initialization: NAL start only */
+	WRITEL(0x0, S5P_FIMV_E_FRAME_INSERTION);
+	WRITEL(0x0, S5P_FIMV_E_ROI_BUFFER_ADDR);
+	WRITEL(0x0, S5P_FIMV_E_PARAM_CHANGE);
+	WRITEL(0x0, S5P_FIMV_E_PICTURE_TAG);
+	WRITEL(0x0, S5P_FIMV_E_METADATA_BUFFER_ADDR);
+	WRITEL(0x0, S5P_FIMV_E_METADATA_BUFFER_SIZE);
+
+	return;
+}
+
 static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx)
 {
 	struct s5p_mfc_dev *dev = ctx->dev;
@@ -1419,6 +1506,8 @@ static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx)
 
 	mfc_debug_enter();
 
+	s5p_mfc_set_default_params(ctx);
+
 	/* width */
 	WRITEL(ctx->img_width, S5P_FIMV_E_FRAME_WIDTH); /* 16 align */
 	/* height */
@@ -1432,12 +1521,14 @@ static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx)
 	WRITEL(0x0, S5P_FIMV_E_FRAME_CROP_OFFSET);
 
 	/* pictype : IDR period */
-	reg = 0;
+	reg = READL(S5P_FIMV_E_GOP_CONFIG);
+	reg &= ~(0xFFFF);
 	reg |= p->gop_size & 0xFFFF;
 	WRITEL(reg, S5P_FIMV_E_GOP_CONFIG);
 
 	if(FW_HAS_GOP2(dev)) {
-		reg = 0;
+		reg = READL(S5P_FIMV_E_GOP_CONFIG2);
+		reg &= ~(0x3FFF);
 		reg |= (p->gop_size >> 16) & 0x3FFF;
 		WRITEL(reg, S5P_FIMV_E_GOP_CONFIG2);
 	}
@@ -1446,12 +1537,12 @@ static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx)
 	/* multi-slice MB number or bit size */
 	enc->slice_mode = p->slice_mode;
 
-	WRITEL(0, S5P_FIMV_E_ENC_OPTIONS);
-
-	if (p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB) {
+	if (p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB) {
 		enc->slice_size.mb = p->slice_mb;
-	} else if (p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES) {
+	} else if (p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES) {
 		enc->slice_size.bits = p->slice_bit;
+	} else if (p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB_ROW) {
+		enc->slice_size.mb = p->slice_mb_row * ((ctx->img_width + 15) / 16);
 	} else {
 		enc->slice_size.mb = 0;
 		enc->slice_size.bits = 0;
@@ -1461,31 +1552,22 @@ static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx)
 
 	/* cyclic intra refresh */
 	WRITEL(p->intra_refresh_mb, S5P_FIMV_E_IR_SIZE);
+
 	reg = READL(S5P_FIMV_E_ENC_OPTIONS);
-	if (p->intra_refresh_mb == 0)
-		reg &= ~(0x1 << 4);
-	else
+	/* frame skip mode */
+	reg &= ~(0x3);
+	reg |= (p->frame_skip_mode & 0x3);
+	/* seq header ctrl */
+	reg &= ~(0x1 << 2);
+	reg |= ((p->seq_hdr_mode & 0x1) << 2);
+	/* cyclic intra refresh */
+	reg &= ~(0x1 << 4);
+	if (p->intra_refresh_mb)
 		reg |= (0x1 << 4);
-	WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS);
-
 	/* 'NON_REFERENCE_STORE_ENABLE' for debugging */
-	reg = READL(S5P_FIMV_E_ENC_OPTIONS);
 	reg &= ~(0x1 << 9);
 	WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS);
 
-	/* memory structure cur. frame */
-	if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12MT_16X16) {
-		/* 0: Linear, 1: 2D tiled*/
-		reg = READL(S5P_FIMV_E_ENC_OPTIONS);
-		reg |= (0x1 << 7);
-		WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS);
-	} else {
-		/* 0: Linear, 1: 2D tiled*/
-		reg = READL(S5P_FIMV_E_ENC_OPTIONS);
-		reg &= ~(0x1 << 7);
-		WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS);
-	}
-
 	switch (ctx->src_fmt->fourcc) {
 	case V4L2_PIX_FMT_NV12M:
 	case V4L2_PIX_FMT_NV12MT_16X16:
@@ -1521,12 +1603,6 @@ static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx)
 	}
 	WRITEL(pix_val, S5P_FIMV_PIXEL_FORMAT);
 
-	/* memory structure recon. frame */
-	/* 0: Linear, 1: 2D tiled */
-	reg = READL(S5P_FIMV_E_ENC_OPTIONS);
-	reg |= (0x1 << 8);
-	WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS);
-
 	/* padding control & value */
 	WRITEL(0x0, S5P_FIMV_E_PADDING_CTRL);
 	if (p->pad) {
@@ -1546,18 +1622,20 @@ static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx)
 	}
 
 	/* rate control config. */
-	reg = 0;
-	/** frame-level rate control */
+	reg = READL(S5P_FIMV_E_RC_CONFIG);
+	/* macroblock level rate control */
+	reg &= ~(0x1 << 8);
+	reg |= ((p->rc_mb & 0x1) << 8);
+	/* framelevel rate control */
 	reg &= ~(0x1 << 9);
-	reg |= (p->rc_frame << 9);
+	reg |= ((p->rc_frame & 0x1) << 9);
+	/* 'DROP_CONTROL_ENABLE', disable */
+	reg &= ~(0x1 << 10);
 	WRITEL(reg, S5P_FIMV_E_RC_CONFIG);
 
 	/* bit rate */
-	if (p->rc_frame)
-		WRITEL(p->rc_bitrate,
-			S5P_FIMV_E_RC_BIT_RATE);
-	else
-		WRITEL(1, S5P_FIMV_E_RC_BIT_RATE);
+	if (p->rc_bitrate)
+		WRITEL(p->rc_bitrate, S5P_FIMV_E_RC_BIT_RATE);
 
 	if (p->rc_frame) {
 		if (FW_HAS_ADV_RC_MODE(dev)) {
@@ -1580,48 +1658,12 @@ static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx)
 
 	/* extended encoder ctrl */
 	/** vbv buffer size */
-	if (p->frame_skip_mode == V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT)
-		WRITEL(p->vbv_buf_size, S5P_FIMV_E_VBV_BUFFER_SIZE);
-
-	/** seq header ctrl */
-	reg = READL(S5P_FIMV_E_ENC_OPTIONS);
-	reg &= ~(0x1 << 2);
-	reg |= (p->seq_hdr_mode << 2);
-	/** frame skip mode */
-	reg &= ~(0x3);
-	reg |= (p->frame_skip_mode);
-	WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS);
-
-	/* 'DROP_CONTROL_ENABLE', disable */
-	reg = READL(S5P_FIMV_E_RC_CONFIG);
-	reg &= ~(0x1 << 10);
-	WRITEL(reg, S5P_FIMV_E_RC_CONFIG);
-
-	/* setting for MV range [16, 256] */
-	if (mfc_version(dev) == 0x61)
-		reg = ENC_V61_MV_RANGE;
-	else if (mfc_version(dev) == 0x78)
-		reg = ENC_V78_MV_RANGE;
-	else
-		reg = ENC_V65_MV_RANGE;
-	WRITEL(reg, S5P_FIMV_E_MV_HOR_RANGE);
-	WRITEL(reg, S5P_FIMV_E_MV_VER_RANGE);
-
-	WRITEL(0x0, S5P_FIMV_E_VBV_INIT_DELAY); /* SEQ_start Only */
-
-	/* initialize for '0' only setting */
-	WRITEL(0x0, S5P_FIMV_E_FRAME_INSERTION); /* NAL_start Only */
-	WRITEL(0x0, S5P_FIMV_E_ROI_BUFFER_ADDR); /* NAL_start Only */
-	WRITEL(0x0, S5P_FIMV_E_PARAM_CHANGE); /* NAL_start Only */
-	WRITEL(0x0, S5P_FIMV_E_RC_ROI_CTRL); /* NAL_start Only */
-	WRITEL(0x0, S5P_FIMV_E_PICTURE_TAG); /* NAL_start Only */
-
-	WRITEL(0x0, S5P_FIMV_E_BIT_COUNT_ENABLE); /* NAL_start Only */
-	WRITEL(0x0, S5P_FIMV_E_MAX_BIT_COUNT); /* NAL_start Only */
-	WRITEL(0x0, S5P_FIMV_E_MIN_BIT_COUNT); /* NAL_start Only */
-
-	WRITEL(0x0, S5P_FIMV_E_METADATA_BUFFER_ADDR); /* NAL_start Only */
-	WRITEL(0x0, S5P_FIMV_E_METADATA_BUFFER_SIZE); /* NAL_start Only */
+	if (p->frame_skip_mode == V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) {
+		reg = READL(S5P_FIMV_E_VBV_BUFFER_SIZE);
+		reg &= ~(0xFF);
+		reg |= p->vbv_buf_size & 0xFF;
+		WRITEL(reg, S5P_FIMV_E_VBV_BUFFER_SIZE);
+	}
 
 	mfc_debug_leave();
 
@@ -1634,7 +1676,7 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)
 	struct s5p_mfc_enc *enc = ctx->enc_priv;
 	struct s5p_mfc_enc_params *p = &enc->params;
 	struct s5p_mfc_h264_enc_params *p_264 = &p->codec.h264;
-	unsigned int reg = 0;
+	unsigned int reg = 0, reg2 = 0;
 	int i;
 
 	mfc_debug_enter();
@@ -1682,10 +1724,52 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)
 	reg |= p_264->profile;
 	WRITEL(reg, S5P_FIMV_E_PICTURE_PROFILE);
 
+	reg = READL(S5P_FIMV_E_H264_OPTIONS);
+	/* entropy coding mode */
+	reg &= ~(0x1);
+	reg |= (p_264->entropy_mode & 0x1);
+	/* loop filter ctrl */
+	reg &= ~(0x3 << 1);
+	reg |= ((p_264->loop_filter_mode & 0x3) << 1);
 	/* interlace */
-	reg = 0;
 	reg &= ~(0x1 << 3);
-	reg |= (p_264->interlace << 3);
+	reg |= ((p_264->interlace & 0x1) << 3);
+	/* intra picture period for H.264 open GOP
+	 * from 9.0 Version changed register meaning
+	 */
+	reg &= ~(0x1 << 4);
+	p_264->open_gop ^= S5P_FIMV_E_IDR_H264_IDR;
+	reg |= ((p_264->open_gop & 0x1) << 4);
+	/* extended encoder ctrl */
+	reg &= ~(0x1 << 5);
+	reg |= ((p_264->ar_vui & 0x1) << 5);
+	/* ASO enable */
+	reg &= ~(0x1 << 6);
+	reg |= ((p_264->aso_enable & 0x1) << 6);
+	/* number of ref. picture */
+	reg &= ~(0x1 << 7);
+	reg |= (((p_264->num_ref_pic_4p - 1) & 0x1) << 7);
+	/* Temporal SVC - hier qp enable */
+	reg &= ~(0x1 << 8);
+	reg |= ((p_264->hier_qp_enable & 0x1) << 8);
+	/* 8x8 transform enable */
+	reg &= ~(0x1 << 12);
+	reg &= ~(0x1 << 13);
+	reg |= ((p_264->_8x8_transform & 0x1) << 12);
+	reg |= ((p_264->_8x8_transform & 0x1) << 13);
+	/* 'CONSTRAINED_INTRA_PRED_ENABLE' is disable */
+	reg &= ~(0x1 << 14);
+	/*
+	 * CONSTRAINT_SET0_FLAG: all constraints specified in
+	 * Baseline Profile
+	 */
+	reg |= (0x1 << 26);
+	/* sps pps control */
+	reg &= ~(0x1 << 29);
+	reg |= ((p_264->prepend_sps_pps_to_idr & 0x1) << 29);
+	/* VUI parameter disable */
+	reg &= ~(0x1 << 30);
+	reg |= ((p_264->vui_enable & 0x1) << 30);
 	WRITEL(reg, S5P_FIMV_E_H264_OPTIONS);
 
 	/** height */
@@ -1695,134 +1779,90 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)
 		WRITEL(ctx->img_height >> 1, S5P_FIMV_E_CROPPED_FRAME_HEIGHT);
 	}
 
-	/* loop filter ctrl */
-	reg = READL(S5P_FIMV_E_H264_OPTIONS);
-	reg &= ~(0x3 << 1);
-	reg |= (p_264->loop_filter_mode << 1);
-	WRITEL(reg, S5P_FIMV_E_H264_OPTIONS);
-
 	/* loopfilter alpha offset */
-	if (p_264->loop_filter_alpha < 0) {
-		reg = 0x10;
-		reg |= (0xFF - p_264->loop_filter_alpha) + 1;
-	} else {
-		reg = 0x00;
-		reg |= (p_264->loop_filter_alpha & 0xF);
-	}
+	reg = READL(S5P_FIMV_E_H264_LF_ALPHA_OFFSET);
+	reg &= ~(0x1F);
+	reg |= (p_264->loop_filter_alpha & 0x1F);
 	WRITEL(reg, S5P_FIMV_E_H264_LF_ALPHA_OFFSET);
 
 	/* loopfilter beta offset */
-	if (p_264->loop_filter_beta < 0) {
-		reg = 0x10;
-		reg |= (0xFF - p_264->loop_filter_beta) + 1;
-	} else {
-		reg = 0x00;
-		reg |= (p_264->loop_filter_beta & 0xF);
-	}
+	reg = READL(S5P_FIMV_E_H264_LF_BETA_OFFSET);
+	reg &= ~(0x1F);
+	reg |= (p_264->loop_filter_beta & 0x1F);
 	WRITEL(reg, S5P_FIMV_E_H264_LF_BETA_OFFSET);
 
-	/* entropy coding mode */
-	reg = READL(S5P_FIMV_E_H264_OPTIONS);
-	reg &= ~(0x1);
-	reg |= (p_264->entropy_mode);
-	WRITEL(reg, S5P_FIMV_E_H264_OPTIONS);
-
-	/* number of ref. picture */
-	reg = READL(S5P_FIMV_E_H264_OPTIONS);
-	reg &= ~(0x1 << 7);
-	if (!IS_MFCv78(dev))
-		reg |= ((p_264->num_ref_pic_4p-1) << 7);
-	WRITEL(reg, S5P_FIMV_E_H264_OPTIONS);
-
-	/* 8x8 transform enable */
-	reg = READL(S5P_FIMV_E_H264_OPTIONS);
-	reg &= ~(0x3 << 12);
-	reg |= (p_264->_8x8_transform << 12);
-	WRITEL(reg, S5P_FIMV_E_H264_OPTIONS);
-
 	/* rate control config. */
 	reg = READL(S5P_FIMV_E_RC_CONFIG);
-	/** macroblock level rate control */
-	reg &= ~(0x1 << 8);
-	reg |= (p->rc_mb << 8);
-	WRITEL(reg, S5P_FIMV_E_RC_CONFIG);
 	/** frame QP */
-	reg &= ~(0x3F);
-	reg |= p_264->rc_frame_qp;
+	reg &= ~(0x7F);
+	reg |= (p_264->rc_frame_qp & 0x7F);
+	if (!p->rc_frame && !p->rc_mb && p->dynamic_qp)
+		reg |= (0x1 << 11);
 	WRITEL(reg, S5P_FIMV_E_RC_CONFIG);
 
 	/* frame rate */
 	/* Fix value for H.264, H.263 in the driver */
 	p->rc_frame_delta = FRAME_DELTA_DEFAULT;
 	if (p->rc_frame) {
-		reg = 0;
-		reg &= ~(0xffff << 16);
-		reg |= ((p_264->rc_framerate * p->rc_frame_delta) << 16);
-		reg &= ~(0xffff);
-		reg |= p->rc_frame_delta;
+		reg = READL(S5P_FIMV_E_RC_FRAME_RATE);
+		reg &= ~(0xFFFF << 16);
+		reg |= (p_264->rc_framerate * p->rc_frame_delta) << 16;
+		reg &= ~(0xFFFF);
+		reg |= p->rc_frame_delta & 0xFFFF;
 		WRITEL(reg, S5P_FIMV_E_RC_FRAME_RATE);
 	}
-
-	/* max & min value of QP */
-	reg = 0;
-	/** max QP */
-	reg &= ~(0x3F << 8);
-	reg |= (p_264->rc_max_qp << 8);
-	/** min QP */
-	reg &= ~(0x3F);
-	reg |= p_264->rc_min_qp;
+	/* max & min value of QP for I frame */
+	reg = READL(S5P_FIMV_E_RC_QP_BOUND);
+	/** max I frame QP */
+	reg &= ~(0x7F << 8);
+	reg |= ((p_264->rc_max_qp & 0x7F) << 8);
+	/** min I frame QP */
+	reg &= ~(0x7F);
+	reg |= (p_264->rc_min_qp & 0x7F);
 	WRITEL(reg, S5P_FIMV_E_RC_QP_BOUND);
 
-	/* macroblock adaptive scaling features */
-	WRITEL(0x0, S5P_FIMV_E_MB_RC_CONFIG);
-	if (p->rc_mb) {
-		reg = 0;
-		/** dark region */
-		reg &= ~(0x1 << 3);
-		reg |= (p_264->rc_mb_dark << 3);
-		/** smooth region */
-		reg &= ~(0x1 << 2);
-		reg |= (p_264->rc_mb_smooth << 2);
-		/** static region */
-		reg &= ~(0x1 << 1);
-		reg |= (p_264->rc_mb_static << 1);
-		/** high activity region */
-		reg &= ~(0x1);
-		reg |= p_264->rc_mb_activity;
-		WRITEL(reg, S5P_FIMV_E_MB_RC_CONFIG);
-	}
-
-	WRITEL(0x0, S5P_FIMV_E_FIXED_PICTURE_QP);
-	if (!p->rc_frame && !p->rc_mb) {
-		reg = 0;
-		reg &= ~(0x3f << 16);
-		reg |= (p_264->rc_b_frame_qp << 16);
-		reg &= ~(0x3f << 8);
-		reg |= (p_264->rc_p_frame_qp << 8);
-		reg &= ~(0x3f);
-		reg |= p_264->rc_frame_qp;
-		WRITEL(reg, S5P_FIMV_E_FIXED_PICTURE_QP);
-	}
-
-	/* sps pps control */
-	reg = READL(S5P_FIMV_E_H264_OPTIONS);
-	reg &= ~(0x1 << 29);
-	reg |= (p_264->prepend_sps_pps_to_idr << 29);
-	WRITEL(reg, S5P_FIMV_E_H264_OPTIONS);
+	/* max & min value of QP for P/B frame */
+	reg = READL(S5P_FIMV_E_RC_QP_BOUND_PB);
+	/** max B frame QP */
+	reg &= ~(0x7F << 24);
+	reg |= ((p_264->rc_max_qp_b & 0x7F) << 24);
+	/** min B frame QP */
+	reg &= ~(0x7F << 16);
+	reg |= ((p_264->rc_min_qp_b & 0x7F) << 16);
+	/** max P frame QP */
+	reg &= ~(0x7F << 8);
+	reg |= ((p_264->rc_max_qp_p & 0x7F) << 8);
+	/** min P frame QP */
+	reg &= ~(0x7F);
+	reg |= p_264->rc_min_qp_p & 0x7F;
+	WRITEL(reg, S5P_FIMV_E_RC_QP_BOUND_PB);
 
-	/*
-	 * CONSTRAINT_SET0_FLAG: all constraints specified in
-	 * Baseline Profile
-	 */
-	reg = READL(S5P_FIMV_E_H264_OPTIONS);
-	reg |= (0x1 << 26);
-	WRITEL(reg, S5P_FIMV_E_H264_OPTIONS);
+	/* macroblock adaptive scaling features */
+	reg = READL(S5P_FIMV_E_MB_RC_CONFIG);
+	/* dark region */
+	reg &= ~(0x1 << 3);
+	reg |= ((p_264->rc_mb_dark & 0x1) << 3);
+	/* smooth region */
+	reg &= ~(0x1 << 2);
+	reg |= ((p_264->rc_mb_smooth & 0x1) << 2);
+	/* static region */
+	reg &= ~(0x1 << 1);
+	reg |= ((p_264->rc_mb_static & 0x1) << 1);
+	/* high activity region */
+	reg &= ~(0x1);
+	reg |= (p_264->rc_mb_activity & 0x1);
+	WRITEL(reg, S5P_FIMV_E_MB_RC_CONFIG);
 
-	/* extended encoder ctrl */
-	reg = READL(S5P_FIMV_E_H264_OPTIONS);
-	reg &= ~(0x1 << 5);
-	reg |= (p_264->ar_vui << 5);
-	WRITEL(reg, S5P_FIMV_E_H264_OPTIONS);
+	reg = READL(S5P_FIMV_E_FIXED_PICTURE_QP);
+	reg &= ~(0x7F << 24);
+	reg |= ((p->config_qp & 0x7F) << 24);
+	reg &= ~(0x7F << 16);
+	reg |= ((p_264->rc_b_frame_qp & 0x7F) << 16);
+	reg &= ~(0x7F << 8);
+	reg |= ((p_264->rc_p_frame_qp & 0x7F) << 8);
+	reg &= ~(0x7F);
+	reg |= (p_264->rc_frame_qp & 0x7F);
+	WRITEL(reg, S5P_FIMV_E_FIXED_PICTURE_QP);
 
 	WRITEL(0x0, S5P_FIMV_E_ASPECT_RATIO);
 	WRITEL(0x0, S5P_FIMV_E_EXTENDED_SAR);
@@ -1841,87 +1881,72 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)
 			WRITEL(reg, S5P_FIMV_E_EXTENDED_SAR);
 		}
 	}
-
-	/* intra picture period for H.264 open GOP */
-	/** control */
-	reg = READL(S5P_FIMV_E_H264_OPTIONS);
-	/* from 9.0 Version changed register meaning*/
-	reg &= ~(0x1 << 4);
-	p_264->open_gop ^= S5P_FIMV_E_IDR_H264_IDR;
-	reg |= (p_264->open_gop << 4);
-	WRITEL(reg, S5P_FIMV_E_H264_OPTIONS);
-	/** value */
-	WRITEL(0x0, S5P_FIMV_E_H264_I_PERIOD);
+	/* intra picture period for H.264 open GOP, value */
 	if (p_264->open_gop) {
-		reg = 0;
-		reg &= ~(0xffff);
-		reg |= p_264->open_gop_size;
+		reg = READL(S5P_FIMV_E_H264_I_PERIOD);
+		reg &= ~(0xFFFF);
+		reg |= (p_264->open_gop_size & 0xFFFF);
 		WRITEL(reg, S5P_FIMV_E_H264_I_PERIOD);
 	}
 
-	/* 'WEIGHTED_BI_PREDICTION' for B is disable */
-	reg = READL(S5P_FIMV_E_H264_OPTIONS);
-	reg &= ~(0x3 << 9);
-	WRITEL(reg, S5P_FIMV_E_H264_OPTIONS);
-
-	/* 'CONSTRAINED_INTRA_PRED_ENABLE' is disable */
-	reg = READL(S5P_FIMV_E_H264_OPTIONS);
-	reg &= ~(0x1 << 14);
-	WRITEL(reg, S5P_FIMV_E_H264_OPTIONS);
-
-	/* ASO enable */
-	reg = READL(S5P_FIMV_E_H264_OPTIONS);
-	if (p_264->aso_enable)
-		reg |= (0x1 << 6);
-	else
-		reg &= ~(0x1 << 6);
-	WRITEL(reg, S5P_FIMV_E_H264_OPTIONS);
+	reg = READL(S5P_FIMV_E_H264_OPTIONS_2);
+	/* pic_order_cnt_type = 0 for backward compatibilities */
+	if (FW_HAS_POC_TYPE_CTRL(dev))
+		reg &= ~(0x3);
+	/* Enable LTR */
+	reg &= ~(0x1 << 2);
+	if ((p_264->enable_ltr & 0x1) || (p_264->num_of_ltr > 0))
+		reg |= (0x1 << 2);
+	/* Number of LTR */
+	reg &= ~(0x3 << 7);
+	if (p_264->num_of_ltr > 2)
+		reg |= (((p_264->num_of_ltr - 2) & 0x3) << 7);
+	WRITEL(reg, S5P_FIMV_E_H264_OPTIONS_2);
 
-	/* VUI parameter disable */
-	if (FW_HAS_VUI_PARAMS(dev)) {
-		reg = READL(S5P_FIMV_E_H264_OPTIONS);
-		reg &= ~(0x1 << 30);
-		WRITEL(reg, S5P_FIMV_E_H264_OPTIONS);
+	/* Temporal SVC - qp type, layer number */
+	reg = READL(S5P_FIMV_E_NUM_T_LAYER);
+	reg &= ~(0x1 << 3);
+	reg |= (p_264->hier_qp_type & 0x1) << 3;
+	reg &= ~(0x7);
+	reg |= p_264->num_hier_layer & 0x7;
+	reg &= ~(0x7 << 4);
+	if (p_264->hier_ref_type) {
+		reg |= 0x1 << 7;
+		reg |= (p->num_hier_max_layer & 0x7) << 4;
+	} else {
+		reg |= 0x7 << 4;
 	}
+	WRITEL(reg, S5P_FIMV_E_NUM_T_LAYER);
+	mfc_debug(3, "Temporal SVC: hier_qp_enable %d, enable_ltr %d, "
+		"num_hier_layer %d, max_layer %d, hier_ref_type %d, NUM_T_LAYER 0x%x\n",
+		p_264->hier_qp_enable, p_264->enable_ltr, p_264->num_hier_layer,
+		p->num_hier_max_layer, p_264->hier_ref_type, reg);
 
-	/* pic_order_cnt_type = 0 for backward compatibilities */
-	if (FW_HAS_POC_TYPE_CTRL(dev)) {
-		reg = READL(S5P_FIMV_E_H264_OPTIONS_2);
-		reg &= ~(0x3 << 0);
-		reg |= (0x0 << 0); /* TODO: add new CID for this */
-		WRITEL(reg, S5P_FIMV_E_H264_OPTIONS_2);
+	/* QP & Bitrate for each layer */
+	for (i = 0; i < 7; i++) {
+		WRITEL(p_264->hier_qp_layer[i],
+				S5P_FIMV_E_HIERARCHICAL_QP_LAYER0 + i * 4);
+		WRITEL(p_264->hier_bit_layer[i],
+				S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER0 + i * 4);
+		mfc_debug(3, "Temporal SVC: layer[%d] QP: %#x, bitrate: %#x\n",
+					i, p_264->hier_qp_layer[i],
+					p_264->hier_bit_layer[i]);
 	}
 
-#if defined(CONFIG_SOC_EXYNOS5422) || defined(CONFIG_SOC_EXYNOS5433)
-	reg = READL(S5P_FIMV_E_H264_OPTIONS_2);
-	reg |= (0x1 << 3); /* Enable ECO MODE */
-	WRITEL(reg, S5P_FIMV_E_H264_OPTIONS_2);
-#endif
-
-	/* hier qp enable */
-	reg = READL(S5P_FIMV_E_H264_OPTIONS);
-	reg &= ~(0x1 << 8);
-	reg |= ((p_264->hier_qp & 0x1) << 8);
-	WRITEL(reg, S5P_FIMV_E_H264_OPTIONS);
-	reg = 0;
-	if (p_264->hier_qp_layer) {
-		reg |= 0x7 << 0x4;
-		reg |= (p_264->hier_qp_type & 0x1) << 0x3;
-		reg |= p_264->hier_qp_layer & 0x7;
-		WRITEL(reg, S5P_FIMV_E_H264_NUM_T_LAYER);
-		/* QP value for each layer */
-		if (p_264->hier_qp) {
-			for (i = 0; i < (p_264->hier_qp_layer & 0x7); i++)
-			WRITEL(p_264->hier_qp_layer_qp[i],
-					S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER0 + i * 4);
-		} else {
-			for (i = 0; i < (p_264->hier_qp_layer & 0x7); i++)
-			WRITEL(p_264->hier_qp_layer_bit[i],
-					S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER0 + i * 4);
+	if (p_264->set_priority) {
+		reg = 0;
+		reg2 = 0;
+		for (i = 0; i < (p_264->num_hier_layer & 0x7); i++) {
+			if (i <= 4)
+				reg |= ((p_264->base_priority & 0x3F) + i) << (6 * i);
+			else
+				reg2 |= ((p_264->base_priority & 0x3F) + i) << (6 * (i - 5));
 		}
+		WRITEL(reg, S5P_FIMV_E_H264_HD_SVC_EXTENSION_0);
+		WRITEL(reg2, S5P_FIMV_E_H264_HD_SVC_EXTENSION_1);
+		mfc_debug(3, "Temporal SVC: priority EXTENSION0: %#x, EXTENSION1: %#x\n",
+							reg, reg2);
 	}
-	/* number of coding layer should be zero when hierarchical is disable */
-	WRITEL(reg, S5P_FIMV_E_H264_NUM_T_LAYER);
 
 	/* set frame pack sei generation */
 	if (p_264->sei_gen_enable) {
@@ -2015,26 +2040,25 @@ static int s5p_mfc_set_enc_params_mpeg4(struct s5p_mfc_ctx *ctx)
 	/* WRITEL(p_mpeg4->quarter_pixel, S5P_FIMV_ENC_MPEG4_QUART_PXL); */
 
 	/* qp */
-	WRITEL(0x0, S5P_FIMV_E_FIXED_PICTURE_QP);
-	if (!p->rc_frame && !p->rc_mb) {
-		reg = 0;
-		reg &= ~(0x3f << 16);
-		reg |= (p_mpeg4->rc_b_frame_qp << 16);
-		reg &= ~(0x3f << 8);
-		reg |= (p_mpeg4->rc_p_frame_qp << 8);
-		reg &= ~(0x3f);
-		reg |= p_mpeg4->rc_frame_qp;
-		WRITEL(reg, S5P_FIMV_E_FIXED_PICTURE_QP);
-	}
+	reg = READL(S5P_FIMV_E_FIXED_PICTURE_QP);
+	reg &= ~(0x7F << 24);
+	reg |= ((p->config_qp & 0x7F) << 24);
+	reg &= ~(0x7F << 16);
+	reg |= ((p_mpeg4->rc_b_frame_qp & 0x7F) << 16);
+	reg &= ~(0x7F << 8);
+	reg |= ((p_mpeg4->rc_p_frame_qp & 0x7F) << 8);
+	reg &= ~(0x7F);
+	reg |= (p_mpeg4->rc_frame_qp & 0x7F);
+	WRITEL(reg, S5P_FIMV_E_FIXED_PICTURE_QP);
 
 	/* frame rate */
 	if (p->rc_frame) {
 		p->rc_frame_delta = p_mpeg4->vop_frm_delta;
-		reg = 0;
-		reg &= ~(0xffff << 16);
+		reg = READL(S5P_FIMV_E_RC_FRAME_RATE);
+		reg &= ~(0xFFFF << 16);
 		reg |= (p_mpeg4->vop_time_res << 16);
-		reg &= ~(0xffff);
-		reg |= p_mpeg4->vop_frm_delta;
+		reg &= ~(0xFFFF);
+		reg |= (p_mpeg4->vop_frm_delta & 0xFFFF);
 		WRITEL(reg, S5P_FIMV_E_RC_FRAME_RATE);
 	} else {
 		p->rc_frame_delta = FRAME_DELTA_DEFAULT;
@@ -2042,25 +2066,37 @@ static int s5p_mfc_set_enc_params_mpeg4(struct s5p_mfc_ctx *ctx)
 
 	/* rate control config. */
 	reg = READL(S5P_FIMV_E_RC_CONFIG);
-	/** macroblock level rate control */
-	reg &= ~(0x1 << 8);
-	reg |= (p->rc_mb << 8);
-	WRITEL(reg, S5P_FIMV_E_RC_CONFIG);
 	/** frame QP */
-	reg &= ~(0x3F);
-	reg |= p_mpeg4->rc_frame_qp;
+	reg &= ~(0x7F);
+	reg |= (p_mpeg4->rc_frame_qp & 0x7F);
 	WRITEL(reg, S5P_FIMV_E_RC_CONFIG);
 
-	/* max & min value of QP */
-	reg = 0;
-	/** max QP */
-	reg &= ~(0x3F << 8);
-	reg |= (p_mpeg4->rc_max_qp << 8);
-	/** min QP */
-	reg &= ~(0x3F);
-	reg |= p_mpeg4->rc_min_qp;
+	/* max & min value of QP for I frame */
+	reg = READL(S5P_FIMV_E_RC_QP_BOUND);
+	/** max I frame QP */
+	reg &= ~(0x7F << 8);
+	reg |= ((p_mpeg4->rc_max_qp & 0x7F) << 8);
+	/** min I frame QP */
+	reg &= ~(0x7F);
+	reg |= (p_mpeg4->rc_min_qp & 0x7F);
 	WRITEL(reg, S5P_FIMV_E_RC_QP_BOUND);
 
+	/* max & min value of QP for P/B frame */
+	reg = READL(S5P_FIMV_E_RC_QP_BOUND_PB);
+	/** max B frame QP */
+	reg &= ~(0x7F << 24);
+	reg |= ((p_mpeg4->rc_max_qp_b & 0x7F) << 24);
+	/** min B frame QP */
+	reg &= ~(0x7F << 16);
+	reg |= ((p_mpeg4->rc_min_qp_b & 0x7F) << 16);
+	/** max P frame QP */
+	reg &= ~(0x7F << 8);
+	reg |= ((p_mpeg4->rc_max_qp_p & 0x7F) << 8);
+	/** min P frame QP */
+	reg &= ~(0x7F);
+	reg |= p_mpeg4->rc_min_qp_p & 0x7F;
+	WRITEL(reg, S5P_FIMV_E_RC_QP_BOUND_PB);
+
 	/* initialize for '0' only setting*/
 	WRITEL(0x0, S5P_FIMV_E_MPEG4_OPTIONS); /* SEQ_start only */
 	WRITEL(0x0, S5P_FIMV_E_MPEG4_HEC_PERIOD); /* SEQ_start only */
@@ -2089,49 +2125,54 @@ static int s5p_mfc_set_enc_params_h263(struct s5p_mfc_ctx *ctx)
 	WRITEL(reg, S5P_FIMV_E_PICTURE_PROFILE);
 
 	/* qp */
-	WRITEL(0x0, S5P_FIMV_E_FIXED_PICTURE_QP);
-	if (!p->rc_frame && !p->rc_mb) {
-		reg = 0;
-		reg &= ~(0x3f << 8);
-		reg |= (p_mpeg4->rc_p_frame_qp << 8);
-		reg &= ~(0x3f);
-		reg |= p_mpeg4->rc_frame_qp;
-		WRITEL(reg, S5P_FIMV_E_FIXED_PICTURE_QP);
-	}
+	reg = READL(S5P_FIMV_E_FIXED_PICTURE_QP);
+	reg &= ~(0x7F << 24);
+	reg |= ((p->config_qp & 0x7F) << 24);
+	reg &= ~(0x7F << 8);
+	reg |= ((p_mpeg4->rc_p_frame_qp & 0x7F) << 8);
+	reg &= ~(0x7F);
+	reg |= (p_mpeg4->rc_frame_qp & 0x7F);
+	WRITEL(reg, S5P_FIMV_E_FIXED_PICTURE_QP);
 
 	/* frame rate */
 	/* Fix value for H.264, H.263 in the driver */
 	p->rc_frame_delta = FRAME_DELTA_DEFAULT;
 	if (p->rc_frame) {
-		reg = 0;
-		reg &= ~(0xffff << 16);
+		reg = READL(S5P_FIMV_E_RC_FRAME_RATE);
+		reg &= ~(0xFFFF << 16);
 		reg |= ((p_mpeg4->rc_framerate * p->rc_frame_delta) << 16);
-		reg &= ~(0xffff);
-		reg |= p->rc_frame_delta;
+		reg &= ~(0xFFFF);
+		reg |= (p->rc_frame_delta & 0xFFFF);
 		WRITEL(reg, S5P_FIMV_E_RC_FRAME_RATE);
 	}
 
 	/* rate control config. */
 	reg = READL(S5P_FIMV_E_RC_CONFIG);
-	/** macroblock level rate control */
-	reg &= ~(0x1 << 8);
-	reg |= (p->rc_mb << 8);
-	WRITEL(reg, S5P_FIMV_E_RC_CONFIG);
 	/** frame QP */
-	reg &= ~(0x3F);
-	reg |= p_mpeg4->rc_frame_qp;
+	reg &= ~(0x7F);
+	reg |= (p_mpeg4->rc_frame_qp & 0x7F);
 	WRITEL(reg, S5P_FIMV_E_RC_CONFIG);
 
-	/* max & min value of QP */
-	reg = 0;
-	/** max QP */
-	reg &= ~(0x3F << 8);
-	reg |= (p_mpeg4->rc_max_qp << 8);
-	/** min QP */
-	reg &= ~(0x3F);
-	reg |= p_mpeg4->rc_min_qp;
+	/* max & min value of QP for I frame */
+	reg = READL(S5P_FIMV_E_RC_QP_BOUND);
+	/** max I frame QP */
+	reg &= ~(0x7F << 8);
+	reg |= ((p_mpeg4->rc_max_qp & 0x7F) << 8);
+	/** min I frame QP */
+	reg &= ~(0x7F);
+	reg |= (p_mpeg4->rc_min_qp & 0x7F);
 	WRITEL(reg, S5P_FIMV_E_RC_QP_BOUND);
 
+	/* max & min value of QP for P/B frame */
+	reg = READL(S5P_FIMV_E_RC_QP_BOUND_PB);
+	/** max P frame QP */
+	reg &= ~(0x7F << 8);
+	reg |= ((p_mpeg4->rc_max_qp_p & 0x7F) << 8);
+	/** min P frame QP */
+	reg &= ~(0x7F);
+	reg |= p_mpeg4->rc_min_qp_p & 0x7F;
+	WRITEL(reg, S5P_FIMV_E_RC_QP_BOUND_PB);
+
 	mfc_debug_leave();
 
 	return 0;
@@ -2155,42 +2196,47 @@ static int s5p_mfc_set_enc_params_vp8(struct s5p_mfc_ctx *ctx)
 	reg |= (p_vp8->vp8_version) ;
 	WRITEL(reg, S5P_FIMV_E_PICTURE_PROFILE);
 
-	reg = 0;
+	reg = READL(S5P_FIMV_E_VP8_OPTION);
+	reg &= ~(0x1);
+	reg |= (p_vp8->num_refs_for_p - 1) & 0x1;
+	reg &= ~(0xF << 3);
+	reg |= (p_vp8->vp8_numberofpartitions & 0xF) << 3;
+	reg &= ~(0x1 << 10);
+	reg |= (p_vp8->intra_4x4mode_disable & 0x1) << 10;
+	/* Temporal SVC - hier qp enable */
+	reg &= ~(0x1 << 11);
+	reg |= (p_vp8->hier_qp_enable & 0x1) << 11;
 	/* Disable IVF header */
 	reg |= (0x1 << 12);
-	reg |= (p_vp8->intra_4x4mode_disable & 0x1) << 10;
-	reg |= (p_vp8->vp8_numberofpartitions & 0xF) << 3;
-	reg |= (p_vp8->num_refs_for_p - 1) & 0x1;
 	WRITEL(reg, S5P_FIMV_E_VP8_OPTION);
 
-	reg = 0;
+	reg = READL(S5P_FIMV_E_VP8_GOLDEN_FRAME_OPTION);
+	reg &= ~(0x1);
 	reg |= (p_vp8->vp8_goldenframesel & 0x1);
-	reg |= (p_vp8->vp8_gfrefreshperiod & 0xffff) << 1;
+	reg &= ~(0xFFFF << 1);
+	reg |= (p_vp8->vp8_gfrefreshperiod & 0xFFFF) << 1;
 	WRITEL(reg, S5P_FIMV_E_VP8_GOLDEN_FRAME_OPTION);
 
-	/* hier qp enable */
-	reg = READL(S5P_FIMV_E_VP8_OPTION);
-	reg &= ~(0x1 << 11);
-	reg |= ((p_vp8->hierarchy_qp_enable & 0x1) << 11);
-	WRITEL(reg, S5P_FIMV_E_VP8_OPTION);
-	reg = 0;
-	if (p_vp8->num_temporal_layer) {
-		reg |= p_vp8->num_temporal_layer & 0x3;
-		WRITEL(reg, S5P_FIMV_E_VP8_NUM_T_LAYER);
-		/* QP value for each layer */
-		if (p_vp8->hierarchy_qp_enable) {
-			for (i = 0; i < (p_vp8->num_temporal_layer & 0x3); i++)
-			WRITEL(p_vp8->hier_qp_layer_qp[i],
-					S5P_FIMV_E_VP8_HIERARCHICAL_QP_LAYER0 + i * 4);
-		} else {
-			for (i = 0; i < (p_vp8->num_temporal_layer & 0x3); i++)
-			WRITEL(p_vp8->hier_qp_layer_bit[i],
-					S5P_FIMV_E_H264_HIERARCHICAL_BIT_RATE_LAYER0 + i * 4);
-		}
+	/* Temporal SVC - layer number */
+	reg = READL(S5P_FIMV_E_NUM_T_LAYER);
+	reg &= ~(0x7);
+	reg |= p_vp8->num_hier_layer & 0x3;
+	reg &= ~(0x7 << 4);
+	reg |= 0x3 << 4;
+	WRITEL(reg, S5P_FIMV_E_NUM_T_LAYER);
+	mfc_debug(3, "Temporal SVC: hier_qp_enable %d, num_hier_layer %d, NUM_T_LAYER 0x%x\n",
+			p_vp8->hier_qp_enable, p_vp8->num_hier_layer, reg);
+
+	/* QP & Bitrate for each layer */
+	for (i = 0; i < 3; i++) {
+		WRITEL(p_vp8->hier_qp_layer[i],
+				S5P_FIMV_E_HIERARCHICAL_QP_LAYER0 + i * 4);
+		WRITEL(p_vp8->hier_bit_layer[i],
+				S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER0 + i * 4);
+		mfc_debug(3, "Temporal SVC: layer[%d] QP: %#x, bitrate: %#x\n",
+					i, p_vp8->hier_qp_layer[i],
+					p_vp8->hier_bit_layer[i]);
 	}
-	/* number of coding layer should be zero when hierarchical is disable */
-	reg |= p_vp8->num_temporal_layer;
-	WRITEL(reg, S5P_FIMV_E_VP8_NUM_T_LAYER);
 
 	reg = 0;
 	reg |= (p_vp8->vp8_filtersharpness & 0x7);
@@ -2198,51 +2244,52 @@ static int s5p_mfc_set_enc_params_vp8(struct s5p_mfc_ctx *ctx)
 	WRITEL(reg , S5P_FIMV_E_VP8_FILTER_OPTIONS);
 
 	/* qp */
-	WRITEL(0x0, S5P_FIMV_E_FIXED_PICTURE_QP);
-	if (!p->rc_frame && !p->rc_mb) {
-		reg = 0;
-		reg &= ~(0x3f << 8);
-		reg |= (p_vp8->rc_p_frame_qp << 8);
-		reg &= ~(0x3f);
-		reg |= p_vp8->rc_frame_qp;
-		WRITEL(reg, S5P_FIMV_E_FIXED_PICTURE_QP);
-	}
+	reg = READL(S5P_FIMV_E_FIXED_PICTURE_QP);
+	reg &= ~(0x7F << 24);
+	reg |= ((p->config_qp & 0x7F) << 24);
+	reg &= ~(0x7F << 8);
+	reg |= ((p_vp8->rc_p_frame_qp & 0x7F) << 8);
+	reg &= ~(0x7F);
+	reg |= (p_vp8->rc_frame_qp & 0x7F);
+	WRITEL(reg, S5P_FIMV_E_FIXED_PICTURE_QP);
 
 	/* frame rate */
 	p->rc_frame_delta = FRAME_DELTA_DEFAULT;
-
 	if (p->rc_frame) {
-		reg = 0;
-		reg &= ~(0xffff << 16);
+		reg = READL(S5P_FIMV_E_RC_FRAME_RATE);
+		reg &= ~(0xFFFF << 16);
 		reg |= ((p_vp8->rc_framerate * p->rc_frame_delta) << 16);
-		reg &= ~(0xffff);
-		reg |= p->rc_frame_delta;
+		reg &= ~(0xFFFF);
+		reg |= (p->rc_frame_delta & 0xFFFF);
 		WRITEL(reg, S5P_FIMV_E_RC_FRAME_RATE);
 	}
 
 	/* rate control config. */
 	reg = READL(S5P_FIMV_E_RC_CONFIG);
-	/** macroblock level rate control */
-	reg &= ~(0x1 << 8);
-	reg |= (p->rc_mb << 8);
 	/** frame QP */
-	reg &= ~(0x3F);
-	reg |= p_vp8->rc_frame_qp;
+	reg &= ~(0x7F);
+	reg |= (p_vp8->rc_frame_qp & 0x7F);
 	WRITEL(reg, S5P_FIMV_E_RC_CONFIG);
 
-	/* max & min value of QP */
-	reg = 0;
-	/** max QP */
-	reg &= ~(0x3F << 8);
-	reg |= (p_vp8->rc_max_qp << 8);
-	/** min QP */
-	reg &= ~(0x3F);
-	reg |= p_vp8->rc_min_qp;
+	/* max & min value of QP for I frame */
+	reg = READL(S5P_FIMV_E_RC_QP_BOUND);
+	/** max I frame QP */
+	reg &= ~(0x7F << 8);
+	reg |= ((p_vp8->rc_max_qp & 0x7F) << 8);
+	/** min I frame QP */
+	reg &= ~(0x7F);
+	reg |= (p_vp8->rc_min_qp & 0x7F);
 	WRITEL(reg, S5P_FIMV_E_RC_QP_BOUND);
 
-	/* Disable all macroblock adaptive scaling features */
-	reg = 0xF;
-	WRITEL(reg, S5P_FIMV_E_MB_RC_CONFIG);
+	/* max & min value of QP for P/B frame */
+	reg = READL(S5P_FIMV_E_RC_QP_BOUND_PB);
+	/** max P frame QP */
+	reg &= ~(0x7F << 8);
+	reg |= ((p_vp8->rc_max_qp_p & 0x7F) << 8);
+	/** min P frame QP */
+	reg &= ~(0x7F);
+	reg |= p_vp8->rc_min_qp_p & 0x7F;
+	WRITEL(reg, S5P_FIMV_E_RC_QP_BOUND_PB);
 
 	mfc_debug_leave();
 
@@ -2286,129 +2333,165 @@ static int s5p_mfc_set_enc_params_hevc(struct s5p_mfc_ctx *ctx)
 	WRITEL(reg, S5P_FIMV_E_PICTURE_PROFILE);
 
 	/* max partition depth */
-	reg = 0;
+	reg = READL(S5P_FIMV_E_HEVC_OPTIONS);
+	reg &= ~(0x3);
 	reg |= (p_hevc->max_partition_depth & 0x1);
-	reg |= (p_hevc->num_refs_for_p-1) << 2;
-	reg |= (2 << 3); /* always set IDR encoding */
+	reg &= ~(0x1 << 2);
+	reg |= (p_hevc->num_refs_for_p - 1) << 2;
+	reg &= ~(0x1 << 5);
 	reg |= (p_hevc->const_intra_period_enable & 0x1) << 5;
+	reg &= ~(0x1 << 6);
 	reg |= (p_hevc->lossless_cu_enable & 0x1) << 6;
+	reg &= ~(0x1 << 7);
 	reg |= (p_hevc->wavefront_enable & 0x1) << 7;
+	reg &= ~(0x1 << 8);
 	reg |= (p_hevc->loopfilter_disable & 0x1) << 8;
-	reg |= (p_hevc->longterm_ref_enable & 0x1) << 10;
-	reg |= (p_hevc->hier_qp & 0x1) << 11;
+	reg &= ~(0x1 << 9);
+	reg |= (p_hevc->loopfilter_across & 0x1) << 9;
+	reg &= ~(0x1 << 10);
+	reg |= (p_hevc->enable_ltr & 0x1) << 10;
+	reg &= ~(0x1 << 11);
+	reg |= (p_hevc->hier_qp_enable & 0x1) << 11;
+	reg &= ~(0x1 << 12);
 	reg |= (p_hevc->sign_data_hiding & 0x1) << 12;
+	reg &= ~(0x1 << 13);
 	reg |= (p_hevc->general_pb_enable & 0x1) << 13;
+	reg &= ~(0x1 << 14);
 	reg |= (p_hevc->temporal_id_enable & 0x1) << 14;
+	reg &= ~(0x1 << 15);
 	reg |= (p_hevc->strong_intra_smooth & 0x1) << 15;
+	reg &= ~(0x1 << 16);
 	reg |= (p_hevc->intra_pu_split_disable & 0x1) << 16;
+	reg &= ~(0x1 << 17);
 	reg |= (p_hevc->tmv_prediction_disable & 0x1) << 17;
+	reg &= ~(0x7 << 18);
 	reg |= (p_hevc->max_num_merge_mv & 0x7) << 18;
-	/* reg |= (1 << 21); always eco mode disable */
+	reg &= ~(0x1 << 22);
 	reg |= (p_hevc->encoding_nostartcode_enable & 0x1) << 22;
+	reg &= ~(0x1 << 26);
+	reg |= (p_hevc->prepend_sps_pps_to_idr & 0x1) << 26;
 	WRITEL(reg, S5P_FIMV_E_HEVC_OPTIONS);
 	/* refresh period */
-	if (p_hevc->refreshtype) {
-		reg = 0;
-		reg |= (p_hevc->refreshperiod & 0x1);
-		WRITEL(reg, S5P_FIMV_E_HEVC_REFRESH_PERIOD);
-	}
+	reg = READL(S5P_FIMV_E_HEVC_REFRESH_PERIOD);
+	reg &= ~(0xFFFF);
+	reg |= (p_hevc->refreshperiod & 0xFFFF);
+	WRITEL(reg, S5P_FIMV_E_HEVC_REFRESH_PERIOD);
 	/* loop filter setting */
-	reg |= (p_hevc->loopfilter_disable & 0x01) << 8;
 	if (!p_hevc->loopfilter_disable) {
-		reg = 0;
-		reg |= (p_hevc->lf_beta_offset_div2 & 0x1);
-		WRITEL(reg, S5P_FIMV_E_HEVC_LF_BETA_OFFSET_DIV2);
-		reg = 0;
-		reg |= (p_hevc->lf_tc_offset_div2 & 0x1);
-		WRITEL(reg, S5P_FIMV_E_HEVC_LF_TC_OFFSET_DIV2);
-		reg = READL(S5P_FIMV_E_HEVC_OPTIONS);
-		reg &= ~(0x1 << 9);
-		reg |= (p_hevc->loopfilter_across & 0x1) << 9;
+		WRITEL(p_hevc->lf_beta_offset_div2, S5P_FIMV_E_HEVC_LF_BETA_OFFSET_DIV2);
+		WRITEL(p_hevc->lf_tc_offset_div2, S5P_FIMV_E_HEVC_LF_TC_OFFSET_DIV2);
 	}
 	/* long term reference */
-	if (p_hevc->longterm_ref_enable) {
+	if (p_hevc->enable_ltr) {
 		reg = 0;
 		reg |= (p_hevc->store_ref & 0x3);
 		reg &= ~(0x3 << 2);
 		reg |= (p_hevc->user_ref & 0x3) << 2;
 		WRITEL(reg, S5P_FIMV_E_HEVC_NAL_CONTROL);
 	}
-	/* hier qp enable */
-	if (p_hevc->hier_qp && p_hevc->hier_qp_layer) {
-		reg |= (p_hevc->hier_qp_type & 0x1) << 0x3;
-		reg |= p_hevc->hier_qp_layer & 0x7;
-	/* number of coding layer should be zero when hierarchical is disable */
-		WRITEL(reg, S5P_FIMV_E_NUM_T_LAYER);
-		/* QP value for each layer */
-		for (i = 0; i < (p_hevc->hier_qp_layer & 0x7); i++)
-			WRITEL(p_hevc->hier_qp_layer_qp,
-				S5P_FIMV_E_HIERARCHICAL_QP_LAYER0 + i * 4);
-			WRITEL(p_hevc->hier_qp_layer_bit,
-				S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER0 + i * 4);
+
+	/* Temporal SVC - qp type, layer number */
+	reg = READL(S5P_FIMV_E_NUM_T_LAYER);
+	reg &= ~(0x1 << 3);
+	reg |= (p_hevc->hier_qp_type & 0x1) << 3;
+	reg &= ~(0x7);
+	reg |= p_hevc->num_hier_layer & 0x7;
+	reg &= ~(0x7 << 4);
+	if (p_hevc->hier_ref_type) {
+		reg |= 0x1 << 7;
+		reg |= (p->num_hier_max_layer & 0x7) << 4;
+	} else {
+		reg |= 0x7 << 4;
+	}
+	WRITEL(reg, S5P_FIMV_E_NUM_T_LAYER);
+	mfc_debug(2, "Temporal SVC: hier_qp_enable %d, enable_ltr %d, "
+		"num_hier_layer %d, max_layer %d, hier_ref_type %d, NUM_T_LAYER 0x%x\n",
+		p_hevc->hier_qp_enable, p_hevc->enable_ltr, p_hevc->num_hier_layer,
+		p->num_hier_max_layer, p_hevc->hier_ref_type, reg);
+
+	/* QP & Bitrate for each layer */
+	for (i = 0; i < 7; i++) {
+		WRITEL(p_hevc->hier_qp_layer[i],
+			S5P_FIMV_E_HIERARCHICAL_QP_LAYER0 + i * 4);
+		WRITEL(p_hevc->hier_bit_layer[i],
+			S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER0 + i * 4);
+		mfc_debug(3, "Temporal SVC: layer[%d] QP: %#x, bitrate: %#x\n",
+					i, p_hevc->hier_qp_layer[i],
+					p_hevc->hier_bit_layer[i]);
 	}
+
 	/* rate control config. */
 	reg = READL(S5P_FIMV_E_RC_CONFIG);
-	/** macroblock level rate control */
-	reg &= ~(0x1 << 8);
-	reg |= (p->rc_mb << 8);
-	WRITEL(reg, S5P_FIMV_E_RC_CONFIG);
 	/** frame QP */
-	reg &= ~(0x3F);
-	reg |= p_hevc->rc_frame_qp;
+	reg &= ~(0x7F);
+	reg |= (p_hevc->rc_frame_qp & 0x7F);
 	WRITEL(reg, S5P_FIMV_E_RC_CONFIG);
 
 	/* frame rate */
-
 	p->rc_frame_delta = FRAME_DELTA_DEFAULT;
 	if (p->rc_frame) {
-		reg = 0;
-		reg &= ~(0xffff << 16);
+		reg = READL(S5P_FIMV_E_RC_FRAME_RATE);
+		reg &= ~(0xFFFF << 16);
 		reg |= ((p_hevc->rc_framerate * p->rc_frame_delta) << 16);
-		reg &= ~(0xffff);
-		reg |= p->rc_frame_delta;
+		reg &= ~(0xFFFF);
+		reg |= (p->rc_frame_delta & 0xFFFF);
 		WRITEL(reg, S5P_FIMV_E_RC_FRAME_RATE);
 	}
 
-	/* max & min value of QP */
-	reg = 0;
-	/** max QP */
-	reg &= ~(0x3F << 8);
-	reg |= (p_hevc->rc_max_qp << 8);
-	/** min QP */
-	reg &= ~(0x3F);
-	reg |= p_hevc->rc_min_qp;
+	/* max & min value of QP for I frame */
+	reg = READL(S5P_FIMV_E_RC_QP_BOUND);
+	/** max I frame QP */
+	reg &= ~(0x7F << 8);
+	reg |= ((p_hevc->rc_max_qp & 0x7F) << 8);
+	/** min I frame QP */
+	reg &= ~(0x7F);
+	reg |= (p_hevc->rc_min_qp & 0x7F);
 	WRITEL(reg, S5P_FIMV_E_RC_QP_BOUND);
 
+	/* max & min value of QP for P/B frame */
+	reg = READL(S5P_FIMV_E_RC_QP_BOUND_PB);
+	/** max B frame QP */
+	reg &= ~(0x7F << 24);
+	reg |= ((p_hevc->rc_max_qp_b & 0x7F) << 24);
+	/** min B frame QP */
+	reg &= ~(0x7F << 16);
+	reg |= ((p_hevc->rc_min_qp_b & 0x7F) << 16);
+	/** max P frame QP */
+	reg &= ~(0x7F << 8);
+	reg |= ((p_hevc->rc_max_qp_p & 0x7F) << 8);
+	/** min P frame QP */
+	reg &= ~(0x7F);
+	reg |= p_hevc->rc_min_qp_p & 0x7F;
+	WRITEL(reg, S5P_FIMV_E_RC_QP_BOUND_PB);
+
 	/* macroblock adaptive scaling features */
-	WRITEL(0x0, S5P_FIMV_E_MB_RC_CONFIG);
-	if (p->rc_mb) {
-		reg = 0;
-		/** dark region */
-		reg &= ~(0x1 << 3);
-		reg |= (p_hevc->rc_lcu_dark << 3);
-		/** smooth region */
-		reg &= ~(0x1 << 2);
-		reg |= (p_hevc->rc_lcu_smooth << 2);
-		/** static region */
-		reg &= ~(0x1 << 1);
-		reg |= (p_hevc->rc_lcu_static << 1);
-		/** high activity region */
-		reg &= ~(0x1);
-		reg |= p_hevc->rc_lcu_activity;
-		WRITEL(reg, S5P_FIMV_E_MB_RC_CONFIG);
-	}
-	WRITEL(0x0, S5P_FIMV_E_FIXED_PICTURE_QP);
-	if (!p->rc_frame && !p->rc_mb) {
-		reg = 0;
-		reg &= ~(0x3f << 16);
-		reg |= (p_hevc->rc_b_frame_qp << 16);
-		reg &= ~(0x3f << 8);
-		reg |= (p_hevc->rc_p_frame_qp << 8);
-		reg &= ~(0x3f);
-		reg |= p_hevc->rc_frame_qp;
-		WRITEL(reg, S5P_FIMV_E_FIXED_PICTURE_QP);
-	}
-		mfc_debug_leave();
+	reg = READL(S5P_FIMV_E_MB_RC_CONFIG);
+	/* dark region */
+	reg &= ~(0x1 << 3);
+	reg |= ((p_hevc->rc_lcu_dark & 0x1) << 3);
+	/* smooth region */
+	reg &= ~(0x1 << 2);
+	reg |= ((p_hevc->rc_lcu_smooth & 0x1) << 2);
+	/* static region */
+	reg &= ~(0x1 << 1);
+	reg |= ((p_hevc->rc_lcu_static & 0x1) << 1);
+	/* high activity region */
+	reg &= ~(0x1);
+	reg |= (p_hevc->rc_lcu_activity & 0x1);
+	WRITEL(reg, S5P_FIMV_E_MB_RC_CONFIG);
+
+	reg = READL(S5P_FIMV_E_FIXED_PICTURE_QP);
+	reg &= ~(0x7F << 24);
+	reg |= ((p->config_qp & 0x7F) << 24);
+	reg &= ~(0x7F << 16);
+	reg |= ((p_hevc->rc_b_frame_qp & 0x7F) << 16);
+	reg &= ~(0x7F << 8);
+	reg |= ((p_hevc->rc_p_frame_qp & 0x7F) << 8);
+	reg &= ~(0x7F);
+	reg |= (p_hevc->rc_frame_qp & 0x7F);
+	WRITEL(reg, S5P_FIMV_E_FIXED_PICTURE_QP);
+
+	mfc_debug_leave();
 
 	return 0;
 }
@@ -2471,6 +2554,9 @@ static int s5p_mfc_init_decode(struct s5p_mfc_ctx *ctx)
 	if (dec->is_dual_dpb)
 		reg |= (0x1 << S5P_FIMV_D_OPT_DISPLAY_LINEAR_EN);
 
+	/* Parsing all including PPS */
+	reg |= (0x1 << S5P_FIMV_D_OPT_SPECIAL_PARSING_SHIFT);
+
 	WRITEL(reg, S5P_FIMV_D_DEC_OPTIONS);
 
 	if (ctx->codec_mode == S5P_FIMV_CODEC_FIMV1_DEC) {
@@ -2515,6 +2601,10 @@ static int s5p_mfc_init_decode(struct s5p_mfc_ctx *ctx)
 	/* Enable realloc interface if SEI is enabled */
 	if (dec->sei_parse && FW_HAS_SEI_S3D_REALLOC(dev))
 		reg |= (0x1 << S5P_FIMV_D_SEI_NEED_INIT_BUFFER_SHIFT);
+
+	/* Enable recovery SEI parsing */
+	reg |= (0x1 << S5P_FIMV_D_SEI_RECOVERY_PARSING_ENABLE);
+
 	WRITEL(reg, S5P_FIMV_D_SEI_ENABLE);
 
 	WRITEL(ctx->inst_no, S5P_FIMV_INSTANCE_ID);
@@ -2632,6 +2722,109 @@ static int s5p_mfc_h264_set_aso_slice_order(struct s5p_mfc_ctx *ctx)
 	return 0;
 }
 
+static inline void s5p_mfc_set_stride_enc(struct s5p_mfc_ctx *ctx)
+{
+	struct s5p_mfc_dev *dev = ctx->dev;
+	int i;
+
+	if (IS_MFCv7X(dev) || IS_MFCV8(dev)) {
+		for (i = 0; i < ctx->raw_buf.num_planes; i++) {
+			WRITEL(ctx->raw_buf.stride[i],
+				S5P_FIMV_E_SOURCE_FIRST_STRIDE + (i * 4));
+			mfc_debug(2, "enc src[%d] stride: 0x%08lx",
+				i, (unsigned long)ctx->raw_buf.stride[i]);
+		}
+	}
+}
+
+/*
+	When the resolution is changed,
+	s5p_mfc_start_change_resol_enc() should be called right before NAL_START.
+	return value
+	0: no resolution change
+	1: resolution swap
+	2: resolution change
+*/
+int s5p_mfc_start_change_resol_enc(struct s5p_mfc_ctx *ctx)
+{
+	struct s5p_mfc_dev *dev = ctx->dev;
+	struct s5p_mfc_enc *enc = ctx->enc_priv;
+	struct s5p_mfc_enc_params *p = &enc->params;
+	unsigned int reg = 0;
+	int old_img_width;
+	int old_img_height;
+	int new_img_width;
+	int new_img_height;
+	int ret = 0;
+
+	if ((ctx->img_width == 0) || (ctx->img_height == 0)) {
+		mfc_err("new_img_width = %d, new_img_height = %d\n",
+			ctx->img_width, ctx->img_height);
+		return 0;
+	}
+
+	old_img_width = ctx->old_img_width;
+	old_img_height = ctx->old_img_height;
+
+	new_img_width = ctx->img_width;
+	new_img_height = ctx->img_height;
+
+	if ((old_img_width == new_img_width) && (old_img_height == new_img_height)) {
+		mfc_err("Resolution is not changed. new_img_width = %d, new_img_height = %d\n",
+			new_img_width, new_img_height);
+		return 0;
+	}
+
+	mfc_info_ctx("Resolution Change : (%d x %d) -> (%d x %d)\n",
+		old_img_width, old_img_height, new_img_width, new_img_height);
+
+	if (ctx->img_width) {
+		ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12M_HALIGN);
+	}
+
+	if ((old_img_width == new_img_height) && (old_img_height == new_img_width)) {
+		reg = READL(S5P_FIMV_E_PARAM_CHANGE);
+		reg &= ~(0x1 << 6);
+		reg |= (0x1 << 6); /* resolution swap */
+		WRITEL(reg, S5P_FIMV_E_PARAM_CHANGE);
+		ret = 1;
+	} else {
+		reg = READL(S5P_FIMV_E_PARAM_CHANGE);
+		reg &= ~(0x3 << 7);
+		/* For now, FW does not care S5P_FIMV_E_PARAM_CHANGE is 1 or 2.
+		 * It cares S5P_FIMV_E_PARAM_CHANGE is NOT zero.
+		 */
+		if ((old_img_width*old_img_height) < (new_img_width*new_img_height)) {
+			reg |= (0x1 << 7); /* resolution increased */
+			mfc_info_ctx("Resolution Increased\n");
+		} else {
+			reg |= (0x2 << 7); /* resolution decreased */
+			mfc_info_ctx("Resolution Decreased\n");
+		}
+		WRITEL(reg, S5P_FIMV_E_PARAM_CHANGE);
+
+		/** set cropped width */
+		WRITEL(ctx->img_width, S5P_FIMV_E_CROPPED_FRAME_WIDTH);
+		/** set cropped height */
+		WRITEL(ctx->img_height, S5P_FIMV_E_CROPPED_FRAME_HEIGHT);
+
+		/* bit rate */
+		if (p->rc_frame)
+			WRITEL(p->rc_bitrate, S5P_FIMV_E_RC_BIT_RATE);
+		else
+			WRITEL(1000000, S5P_FIMV_E_RC_BIT_RATE);
+		ret = 2;
+	}
+
+	/** set new stride */
+	s5p_mfc_set_stride_enc(ctx);
+
+	/** set cropped offset */
+	WRITEL(0x0, S5P_FIMV_E_FRAME_CROP_OFFSET);
+
+	return ret;
+}
+
 /* Encode a single frame */
 int s5p_mfc_encode_one_frame(struct s5p_mfc_ctx *ctx, int last_frame)
 {
@@ -2644,6 +2837,11 @@ int s5p_mfc_encode_one_frame(struct s5p_mfc_ctx *ctx, int last_frame)
 
 	s5p_mfc_set_slice_mode(ctx);
 
+	if (ctx->enc_drc_flag) {
+		ctx->enc_res_change = s5p_mfc_start_change_resol_enc(ctx);
+		ctx->enc_drc_flag = 0;
+	}
+
 	WRITEL(ctx->inst_no, S5P_FIMV_INSTANCE_ID);
 	/* Issue different commands to instance basing on whether it
 	 * is the last frame or not. */
@@ -2768,8 +2966,13 @@ static inline int s5p_mfc_run_dec_last_frames(struct s5p_mfc_ctx *ctx)
 		temp_vb = list_entry(ctx->src_queue.next,
 					struct s5p_mfc_buf, list);
 		temp_vb->used = 1;
-		s5p_mfc_set_dec_stream_buffer(ctx,
-			s5p_mfc_mem_plane_addr(ctx, &temp_vb->vb, 0), 0, 0);
+		if (dec->consumed)
+			s5p_mfc_set_dec_stream_buffer(ctx,
+				s5p_mfc_mem_plane_addr(ctx, &temp_vb->vb, 0),
+				dec->consumed, dec->remained_size);
+		else
+			s5p_mfc_set_dec_stream_buffer(ctx,
+				s5p_mfc_mem_plane_addr(ctx, &temp_vb->vb, 0), 0, 0);
 	}
 
 	if (dec->is_dynamic_dpb) {
@@ -3130,21 +3333,6 @@ static inline int s5p_mfc_run_init_dec(struct s5p_mfc_ctx *ctx)
 	return 0;
 }
 
-static inline void s5p_mfc_set_stride_enc(struct s5p_mfc_ctx *ctx)
-{
-	struct s5p_mfc_dev *dev = ctx->dev;
-	int i;
-
-	if (IS_MFCv7X(dev) || IS_MFCV8(dev)) {
-		for (i = 0; i < ctx->raw_buf.num_planes; i++) {
-			WRITEL(ctx->raw_buf.stride[i],
-				S5P_FIMV_E_SOURCE_FIRST_STRIDE + (i * 4));
-			mfc_debug(2, "enc src[%d] stride: 0x%08lx",
-				i, (unsigned long)ctx->raw_buf.stride[i]);
-		}
-	}
-}
-
 static inline int s5p_mfc_run_init_enc(struct s5p_mfc_ctx *ctx)
 {
 	struct s5p_mfc_dev *dev = ctx->dev;
@@ -3156,6 +3344,12 @@ static inline int s5p_mfc_run_init_enc(struct s5p_mfc_ctx *ctx)
 
 	spin_lock_irqsave(&dev->irqlock, flags);
 
+	if (list_empty(&ctx->dst_queue)) {
+		mfc_debug(2, "no dst buffers.\n");
+		spin_unlock_irqrestore(&dev->irqlock, flags);
+		return -EAGAIN;
+	}
+
 	dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);
 	dst_addr = s5p_mfc_mem_plane_addr(ctx, &dst_mb->vb, 0);
 	dst_size = (unsigned int)vb2_plane_size(&dst_mb->vb, 0);
@@ -3386,6 +3580,7 @@ void s5p_mfc_try_run(struct s5p_mfc_dev *dev)
 			ret = s5p_mfc_run_dec_last_frames(ctx);
 			break;
 		case MFCINST_RUNNING:
+		case MFCINST_SPECIAL_PARSING_NAL:
 			ret = s5p_mfc_run_dec_frame(ctx);
 			break;
 		case MFCINST_INIT:
@@ -3395,6 +3590,7 @@ void s5p_mfc_try_run(struct s5p_mfc_dev *dev)
 			ret = s5p_mfc_close_inst(ctx);
 			break;
 		case MFCINST_GOT_INST:
+		case MFCINST_SPECIAL_PARSING:
 			ret = s5p_mfc_run_init_dec(ctx);
 			break;
 		case MFCINST_HEAD_PARSED:
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v6.h b/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v6.h
old mode 100644
new mode 100755
index b20f72fe2647..6a94096d89e4
--- a/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v6.h
+++ b/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v6.h
@@ -152,6 +152,7 @@ void s5p_mfc_enc_calc_src_size(struct s5p_mfc_ctx *ctx);
 #define ENC_MULTI_SLICE_MB_MAX		((1 << 30) - 1)
 #define ENC_MULTI_SLICE_BIT_MIN		2800
 #define ENC_MULTI_SLICE_BYTE_MIN	350
+#define ENC_MULTI_SLICE_MB_ROW_MAX	255
 #define ENC_INTRA_REFRESH_MB_MAX	((1 << 18) - 1)
 #define ENC_VBV_BUF_SIZE_MAX		((1 << 30) - 1)
 #define ENC_H264_LOOP_FILTER_AB_MIN	-12
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v8.h b/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v8.h
old mode 100644
new mode 100755
index ac0ac5b78663..1933c1bbef58
--- a/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v8.h
+++ b/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v8.h
@@ -151,6 +151,7 @@ void s5p_mfc_enc_calc_src_size(struct s5p_mfc_ctx *ctx);
 #define ENC_MULTI_SLICE_MB_MAX		((1 << 30) - 1)
 #define ENC_MULTI_SLICE_BIT_MIN		2800
 #define ENC_MULTI_SLICE_BYTE_MIN	350
+#define ENC_MULTI_SLICE_MB_ROW_MAX	255
 #define ENC_INTRA_REFRESH_MB_MAX	((1 << 18) - 1)
 #define ENC_VBV_BUF_SIZE_MAX		((1 << 30) - 1)
 #define ENC_H264_LOOP_FILTER_AB_MIN	-12
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v9.h b/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v9.h
old mode 100644
new mode 100755
index 7644451748d1..9c47ba8fcc3c
--- a/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v9.h
+++ b/drivers/media/platform/exynos/mfc/s5p_mfc_opr_v9.h
@@ -148,28 +148,9 @@ void s5p_mfc_enc_calc_src_size(struct s5p_mfc_ctx *ctx);
 	} while (0)
 
 /* Definition */
-#define ENC_MULTI_SLICE_MB_MAX		((1 << 30) - 1)
-#define ENC_MULTI_SLICE_BIT_MIN		2800
-#define ENC_MULTI_SLICE_BYTE_MIN	350
-#define ENC_INTRA_REFRESH_MB_MAX	((1 << 18) - 1)
-#define ENC_VBV_BUF_SIZE_MAX		((1 << 30) - 1)
-#define ENC_H264_LOOP_FILTER_AB_MIN	-12
-#define ENC_H264_LOOP_FILTER_AB_MAX	12
-#define ENC_H264_RC_FRAME_RATE_MAX	((1 << 16) - 1)
-#define ENC_H263_RC_FRAME_RATE_MAX	((1 << 16) - 1)
-#define ENC_H264_PROFILE_MAX		3
-#define ENC_H264_LEVEL_MAX		42
-#define ENC_MPEG4_VOP_TIME_RES_MAX	((1 << 16) - 1)
 #define FRAME_DELTA_DEFAULT		1
 #define TIGHT_CBR_MAX			10
 #define I_LIMIT_CBR_MAX			5
-#define ENC_HEVC_RC_FRAME_RATE_MAX	((1 << 16) - 1)
-#define ENC_HEVC_QP_INDEX_MIN	-12
-#define ENC_HEVC_QP_INDEX_MAX	12
-#define ENC_HEVC_LOOP_FILTER_MIN	-12
-#define ENC_HEVC_LOOP_FILTER_MAX	12
-#define ENC_HEVC_RC_FRAME_RATE_MAX	((1 << 16) - 1)
-#define ENC_HEVC_LEVEL_MAX		62
 
 /* Definitions for shared memory compatibility */
 #define PIC_TIME_TOP		S5P_FIMV_D_RET_PICTURE_TAG_TOP
@@ -233,12 +214,6 @@ void s5p_mfc_enc_calc_src_size(struct s5p_mfc_ctx *ctx);
 #define ENC_HEVC_ME_SIZE(x, y)				\
 			((((x * 32 / 8 + 63) / 64 * 64) * ((y * 8) + 64)) + (x * y * 32))
 
-/* MV range is [16,256] for v6.1, [16,128] for v6.5 */
-#define ENC_V61_MV_RANGE		256
-#define ENC_V65_MV_RANGE		128
-/* MV range is [16,32] for v7.8 */
-#define ENC_V78_MV_RANGE		32
-
 #define NUM_MPEG4_LF_BUF		2
 
 /* Scratch buffer size for MFC v8.0 */
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_pm.c b/drivers/media/platform/exynos/mfc/s5p_mfc_pm.c
old mode 100644
new mode 100755
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_pm.h b/drivers/media/platform/exynos/mfc/s5p_mfc_pm.h
old mode 100644
new mode 100755
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_qos.c b/drivers/media/platform/exynos/mfc/s5p_mfc_qos.c
old mode 100644
new mode 100755
index cce9e2f0d831..7ad9a83a7e8e
--- a/drivers/media/platform/exynos/mfc/s5p_mfc_qos.c
+++ b/drivers/media/platform/exynos/mfc/s5p_mfc_qos.c
@@ -36,7 +36,9 @@ static void mfc_qos_operate(struct s5p_mfc_ctx *ctx, int opr_type, int idx)
 	struct s5p_mfc_platdata *pdata = dev->pdata;
 	struct s5p_mfc_qos *qos_table = pdata->qos_table;
 
-	if (ctx->buf_process_type & MFCBUFPROC_COPY) {
+	if (ctx->qos_changed)
+		ctx->qos_changed = 0;
+	if (ctx->use_extra_qos) {
 		if (pdata->qos_extra[idx].thrd_mb != MFC_QOS_FLAG_NODATA) {
 			qos_table = pdata->qos_extra;
 #ifdef CONFIG_ARM_EXYNOS_MP_CPUFREQ
@@ -85,7 +87,7 @@ static void mfc_qos_operate(struct s5p_mfc_ctx *ctx, int opr_type, int idx)
 				qos_table[idx].freq_kfc);
 #endif
 		atomic_set(&dev->qos_req_cur, idx + 1);
-		mfc_dbg_ctx("QoS request: %d\n", idx + 1);
+		mfc_info_ctx("QoS request: %d\n", idx + 1);
 		break;
 	case MFC_QOS_UPDATE:
 		if (dev->curr_rate < qos_table[idx].freq_mfc) {
@@ -131,7 +133,7 @@ static void mfc_qos_operate(struct s5p_mfc_ctx *ctx, int opr_type, int idx)
 				qos_table[idx].freq_kfc);
 #endif
 		atomic_set(&dev->qos_req_cur, idx + 1);
-		mfc_dbg_ctx("QoS update: %d\n", idx + 1);
+		mfc_info_ctx("QoS update: %d\n", idx + 1);
 		break;
 	case MFC_QOS_REMOVE:
 		MFC_TRACE_CTX("++ QOS remove(prev mfc:%d)\n",
@@ -154,7 +156,7 @@ static void mfc_qos_operate(struct s5p_mfc_ctx *ctx, int opr_type, int idx)
 		pm_qos_remove_request(&dev->qos_req_cluster0);
 #endif
 		atomic_set(&dev->qos_req_cur, 0);
-		mfc_dbg_ctx("QoS remove\n");
+		mfc_info_ctx("QoS remove\n");
 		break;
 	default:
 		mfc_err_ctx("Unknown request for opr [%d]\n", opr_type);
@@ -173,7 +175,7 @@ static void mfc_qos_print(struct s5p_mfc_ctx *ctx,
 			qos_table[index].freq_cpu);
 #endif
 #ifdef CONFIG_ARM_EXYNOS_MP_CPUFREQ
-	mfc_dbg_ctx("\tint: %d(%d), mif: %d, cpu: %d, kfc: %d\n",
+	mfc_info_ctx("\tint: %d(%d), mif: %d, cpu: %d, kfc: %d\n",
 			qos_table[index].freq_int,
 			qos_table[index].freq_mfc,
 			qos_table[index].freq_mif,
@@ -211,6 +213,9 @@ static void mfc_qos_add_or_update(struct s5p_mfc_ctx *ctx, int total_mb)
 			} else if (atomic_read(&dev->qos_req_cur) != (i + 1)) {
 				mfc_qos_print(ctx, qos_table, i);
 				mfc_qos_operate(ctx, MFC_QOS_UPDATE, i);
+			} else if (atomic_read(&dev->qos_req_cur) == (i + 1) &&
+					ctx->qos_changed) {
+				mfc_qos_operate(ctx, MFC_QOS_UPDATE, i);
 			}
 			break;
 		}
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_reg.c b/drivers/media/platform/exynos/mfc/s5p_mfc_reg.c
old mode 100644
new mode 100755
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_reg.h b/drivers/media/platform/exynos/mfc/s5p_mfc_reg.h
old mode 100644
new mode 100755
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_shm.c b/drivers/media/platform/exynos/mfc/s5p_mfc_shm.c
old mode 100644
new mode 100755
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_shm.h b/drivers/media/platform/exynos/mfc/s5p_mfc_shm.h
old mode 100644
new mode 100755
diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
old mode 100644
new mode 100755
index 69bd5bb0d5af..90c6ccfd97d6
--- a/include/uapi/linux/v4l2-controls.h
+++ b/include/uapi/linux/v4l2-controls.h
@@ -358,8 +358,9 @@ enum v4l2_mpeg_video_header_mode {
 #define V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE		(V4L2_CID_MPEG_BASE+221)
 enum v4l2_mpeg_video_multi_slice_mode {
 	V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE		= 0,
-	V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB		= 1,
-	V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES	= 2,
+	V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB		= 1,
+	V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES	= 2,
+	V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB_ROW	= 3,
 };
 #define V4L2_CID_MPEG_VIDEO_VBV_SIZE			(V4L2_CID_MPEG_BASE+222)
 #define V4L2_CID_MPEG_VIDEO_DEC_PTS			(V4L2_CID_MPEG_BASE+223)
@@ -431,6 +432,7 @@ enum v4l2_mpeg_video_h264_profile {
 	V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH_INTRA	= 14,
 	V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH		= 15,
 	V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH		= 16,
+	V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH		= 17,
 };
 #define V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT	(V4L2_CID_MPEG_BASE+364)
 #define V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH	(V4L2_CID_MPEG_BASE+365)
diff --git a/include/uapi/linux/videodev2_exynos_media.h b/include/uapi/linux/videodev2_exynos_media.h
old mode 100644
new mode 100755
index abb64fdc078f..21927206676a
--- a/include/uapi/linux/videodev2_exynos_media.h
+++ b/include/uapi/linux/videodev2_exynos_media.h
@@ -322,6 +322,26 @@ enum v4l2_mpeg_mfc51_video_frame_type {
 					(V4L2_CID_MPEG_MFC_BASE + 97)
 #define V4L2_CID_MPEG_MFC_SET_BUF_PROCESS_TYPE			\
 					(V4L2_CID_MPEG_MFC_BASE + 98)
+#define V4L2_CID_MPEG_MFC_GET_10BIT_INFO			\
+					(V4L2_CID_MPEG_MFC_BASE + 99)
+#define V4L2_CID_MPEG_MFC_H264_ENABLE_LTR		\
+					(V4L2_CID_MPEG_MFC_BASE + 100)
+#define V4L2_CID_MPEG_MFC_H264_MARK_LTR			\
+					(V4L2_CID_MPEG_MFC_BASE + 101)
+#define V4L2_CID_MPEG_MFC_H264_USE_LTR			\
+					(V4L2_CID_MPEG_MFC_BASE + 102)
+#define V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB_ROW	\
+					(V4L2_CID_MPEG_MFC_BASE + 103)
+#define V4L2_CID_MPEG_MFC_H264_BASE_PRIORITY		\
+					(V4L2_CID_MPEG_MFC_BASE + 104)
+#define V4L2_CID_MPEG_MFC_CONFIG_QP			\
+					(V4L2_CID_MPEG_MFC_BASE + 105)
+#define V4L2_CID_MPEG_MFC_H264_VUI_RESTRICTION_ENABLE	\
+					(V4L2_CID_MPEG_MFC_BASE + 106)
+#define V4L2_CID_MPEG_MFC_GET_DRIVER_INFO			\
+					(V4L2_CID_MPEG_MFC_BASE + 107)
+#define V4L2_CID_MPEG_MFC_CONFIG_QP_ENABLE		\
+					(V4L2_CID_MPEG_MFC_BASE + 108)
 
 /* CIDs for HEVC encoding. Number gaps are for compatibility */
 
@@ -339,12 +359,14 @@ enum v4l2_mpeg_mfc51_video_frame_type {
 					(V4L2_CID_MPEG_MFC_BASE + 115)
 #define V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_TYPE       \
 					(V4L2_CID_MPEG_MFC_BASE + 116)
+enum v4l2_mpeg_video_hevc_hierarchical_coding_type {
+	V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B	= 0,
+	V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P	= 1,
+};
 #define V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER      \
 					(V4L2_CID_MPEG_MFC_BASE + 117)
 #define V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_QP   \
 					(V4L2_CID_MPEG_MFC_BASE + 118)
-#define V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT  \
-					(V4L2_CID_MPEG_MFC_BASE + 119)
 #define V4L2_CID_MPEG_VIDEO_HEVC_PROFILE			\
 					(V4L2_CID_MPEG_MFC_BASE + 120)
 #define V4L2_CID_MPEG_VIDEO_HEVC_LEVEL				\
@@ -411,4 +433,106 @@ enum v4l2_mpeg_mfc51_video_frame_type {
 					(V4L2_CID_MPEG_MFC_BASE + 151)
 #define V4L2_CID_MPEG_MFC90_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD	\
 					(V4L2_CID_MPEG_MFC_BASE + 152)
+#define V4L2_CID_MPEG_VIDEO_HEVC_PREPEND_SPSPPS_TO_IDR	\
+					(V4L2_CID_MPEG_MFC_BASE + 153)
+#define V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_CH	\
+					(V4L2_CID_MPEG_MFC_BASE + 154)
+#define V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT0 \
+					(V4L2_CID_MPEG_MFC_BASE + 155)
+#define V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT1 \
+					(V4L2_CID_MPEG_MFC_BASE + 156)
+#define V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT2 \
+					(V4L2_CID_MPEG_MFC_BASE + 157)
+#define V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT3 \
+					(V4L2_CID_MPEG_MFC_BASE + 158)
+#define V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT4 \
+					(V4L2_CID_MPEG_MFC_BASE + 159)
+#define V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT5 \
+					(V4L2_CID_MPEG_MFC_BASE + 160)
+#define V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT6 \
+					(V4L2_CID_MPEG_MFC_BASE + 161)
+#define V4L2_CID_MPEG_VIDEO_VP9_VERSION				\
+					(V4L2_CID_MPEG_MFC_BASE + 163)
+#define V4L2_CID_MPEG_VIDEO_VP9_RC_FRAME_RATE			\
+					(V4L2_CID_MPEG_MFC_BASE + 164)
+#define V4L2_CID_MPEG_VIDEO_VP9_MIN_QP				\
+					(V4L2_CID_MPEG_MFC_BASE + 165)
+#define V4L2_CID_MPEG_VIDEO_VP9_MAX_QP				\
+					(V4L2_CID_MPEG_MFC_BASE + 166)
+#define V4L2_CID_MPEG_VIDEO_VP9_I_FRAME_QP			\
+					(V4L2_CID_MPEG_MFC_BASE + 167)
+#define V4L2_CID_MPEG_VIDEO_VP9_P_FRAME_QP			\
+					(V4L2_CID_MPEG_MFC_BASE + 168)
+#define V4L2_CID_MPEG_VIDEO_VP9_GOLDEN_FRAMESEL			\
+					(V4L2_CID_MPEG_MFC_BASE + 169)
+#define V4L2_CID_MPEG_VIDEO_VP9_GF_REFRESH_PERIOD		\
+					(V4L2_CID_MPEG_MFC_BASE + 170)
+#define V4L2_CID_MPEG_VIDEO_VP9_HIERARCHY_QP_ENABLE		\
+					(V4L2_CID_MPEG_MFC_BASE + 171)
+#define V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_QP	\
+					(V4L2_CID_MPEG_MFC_BASE + 172)
+#define V4L2_CID_MPEG_VIDEO_VP9_REF_NUMBER_FOR_PFRAMES		\
+					(V4L2_CID_MPEG_MFC_BASE + 173)
+#define V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER	\
+					(V4L2_CID_MPEG_MFC_BASE + 174)
+#define V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_CH \
+					(V4L2_CID_MPEG_MFC_BASE + 175)
+#define V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_BIT0	\
+					(V4L2_CID_MPEG_MFC_BASE + 176)
+#define V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_BIT1	\
+					(V4L2_CID_MPEG_MFC_BASE + 177)
+#define V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_BIT2	\
+					(V4L2_CID_MPEG_MFC_BASE + 178)
+#define V4L2_CID_MPEG_VIDEO_VP9_MAX_PARTITION_DEPTH		\
+					(V4L2_CID_MPEG_MFC_BASE + 179)
+#define V4L2_CID_MPEG_VIDEO_VP9_DISABLE_INTRA_PU_SPLIT		\
+					(V4L2_CID_MPEG_MFC_BASE + 180)
+#define V4L2_CID_MPEG_VIDEO_DISABLE_IVF_HEADER			\
+					(V4L2_CID_MPEG_MFC_BASE + 181)
+
+/* CIDs for new common interface */
+#define V4L2_CID_MPEG_VIDEO_TEMPORAL_SHORTTERM_MAX_LAYER	\
+					(V4L2_CID_MPEG_MFC_BASE + 193)
+#define V4L2_CID_MPEG_VIDEO_BLACK_BAR_DETECT			\
+					(V4L2_CID_MPEG_MFC_BASE + 194)
+#define V4L2_CID_MPEG_MFC_H264_NUM_OF_LTR			\
+					(V4L2_CID_MPEG_MFC_BASE + 195)
+
+/* QP BOUND interface */
+#define V4L2_CID_MPEG_VIDEO_H264_MAX_QP_P			\
+					(V4L2_CID_MPEG_MFC_BASE + 201)
+#define V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP_P			\
+					(V4L2_CID_MPEG_MFC_BASE + 202)
+#define V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP_P			\
+					(V4L2_CID_MPEG_MFC_BASE + 203)
+#define V4L2_CID_MPEG_VIDEO_H263_MAX_QP_P			\
+					(V4L2_CID_MPEG_MFC_BASE + 204)
+#define V4L2_CID_MPEG_VIDEO_VP8_MAX_QP_P			\
+					(V4L2_CID_MPEG_MFC_BASE + 205)
+#define V4L2_CID_MPEG_VIDEO_VP9_MAX_QP_P			\
+					(V4L2_CID_MPEG_MFC_BASE + 206)
+#define V4L2_CID_MPEG_VIDEO_H264_MIN_QP_P			\
+					(V4L2_CID_MPEG_MFC_BASE + 207)
+#define V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP_P			\
+					(V4L2_CID_MPEG_MFC_BASE + 208)
+#define V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP_P			\
+					(V4L2_CID_MPEG_MFC_BASE + 209)
+#define V4L2_CID_MPEG_VIDEO_H263_MIN_QP_P			\
+					(V4L2_CID_MPEG_MFC_BASE + 210)
+#define V4L2_CID_MPEG_VIDEO_VP8_MIN_QP_P			\
+					(V4L2_CID_MPEG_MFC_BASE + 211)
+#define V4L2_CID_MPEG_VIDEO_VP9_MIN_QP_P			\
+					(V4L2_CID_MPEG_MFC_BASE + 212)
+#define V4L2_CID_MPEG_VIDEO_H264_MAX_QP_B			\
+					(V4L2_CID_MPEG_MFC_BASE + 213)
+#define V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP_B			\
+					(V4L2_CID_MPEG_MFC_BASE + 214)
+#define V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP_B			\
+					(V4L2_CID_MPEG_MFC_BASE + 215)
+#define V4L2_CID_MPEG_VIDEO_H264_MIN_QP_B			\
+					(V4L2_CID_MPEG_MFC_BASE + 216)
+#define V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP_B			\
+					(V4L2_CID_MPEG_MFC_BASE + 217)
+#define V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP_B			\
+					(V4L2_CID_MPEG_MFC_BASE + 218)
 #endif /* __LINUX_VIDEODEV2_EXYNOS_MEDIA_H */
-- 
2.20.1

