From: Nagaraju Siddineni <[email protected]>

- Enable HEVC, AV1, VP8/9, MPEG‑4 (incl. MVC, VC‑1 RCV) .
- Extend DPB/buffer structures for AV1 and high‑resolution/multiframe
  streams.
- Add codec‑specific QoS weight parameters (10‑bit, 4:2:2, B‑frames)
  and update DT bandwidth entries.
- Enhance format tables with colour‑range/space and HDR parsing for VP9.
- Detect display‑resolution changes and multiframe flags for VP9/AV1.
- Introduce utility helpers (CRC, aspect‑ratio, colour primaries)
  and minor safety fixes.

Signed-off-by: Nagaraju Siddineni <[email protected]>
Signed-off-by: Himanshu Dewangan <[email protected]>
---
 .../samsung/exynos-mfc/base/mfc_buf.c         |  70 +++++++++
 .../samsung/exynos-mfc/base/mfc_common.h      |  42 ++++-
 .../samsung/exynos-mfc/base/mfc_data_struct.h |  20 +++
 .../samsung/exynos-mfc/base/mfc_format.h      | 136 ++++++++++++++++
 .../samsung/exynos-mfc/base/mfc_qos.c         |  58 +++++++
 .../samsung/exynos-mfc/base/mfc_queue.c       |   5 +
 .../samsung/exynos-mfc/base/mfc_utils.c       |   8 +-
 .../media/platform/samsung/exynos-mfc/mfc.c   |  53 +++++++
 .../platform/samsung/exynos-mfc/mfc_core.c    |   2 +
 .../samsung/exynos-mfc/mfc_core_buf_ctrl.c    |   9 ++
 .../samsung/exynos-mfc/mfc_core_cmd.c         |  11 ++
 .../samsung/exynos-mfc/mfc_core_isr.c         | 147 ++++++++++++++++--
 .../samsung/exynos-mfc/mfc_core_reg_api.c     |  46 +++++-
 .../samsung/exynos-mfc/mfc_core_reg_api.h     |  75 ++++++++-
 .../samsung/exynos-mfc/mfc_core_run.c         |   4 +
 .../platform/samsung/exynos-mfc/mfc_dec_vb2.c |   1 +
 16 files changed, 665 insertions(+), 22 deletions(-)

diff --git a/drivers/media/platform/samsung/exynos-mfc/base/mfc_buf.c 
b/drivers/media/platform/samsung/exynos-mfc/base/mfc_buf.c
index bd1baf34e0b0..84f97ca230bb 100644
--- a/drivers/media/platform/samsung/exynos-mfc/base/mfc_buf.c
+++ b/drivers/media/platform/samsung/exynos-mfc/base/mfc_buf.c
@@ -116,8 +116,25 @@ int mfc_alloc_instance_context(struct mfc_core_ctx 
*core_ctx)
        switch (ctx->codec_mode) {
        case MFC_REG_CODEC_H264_DEC:
        case MFC_REG_CODEC_H264_MVC_DEC:
+       case MFC_REG_CODEC_HEVC_DEC:
                core_ctx->instance_ctx_buf.size = buf_size->h264_dec_ctx;
                break;
+       case MFC_REG_CODEC_MPEG4_DEC:
+       case MFC_REG_CODEC_H263_DEC:
+       case MFC_REG_CODEC_VC1_RCV_DEC:
+       case MFC_REG_CODEC_VC1_DEC:
+       case MFC_REG_CODEC_MPEG2_DEC:
+       case MFC_REG_CODEC_VP8_DEC:
+       case MFC_REG_CODEC_VP9_DEC:
+       case MFC_REG_CODEC_FIMV1_DEC:
+       case MFC_REG_CODEC_FIMV2_DEC:
+       case MFC_REG_CODEC_FIMV3_DEC:
+       case MFC_REG_CODEC_FIMV4_DEC:
+               core_ctx->instance_ctx_buf.size = buf_size->other_dec_ctx;
+               break;
+       case MFC_REG_CODEC_AV1_DEC:
+               core_ctx->instance_ctx_buf.size = buf_size->av1_dec_ctx;
+               break;
        default:
                core_ctx->instance_ctx_buf.size = 0;
                mfc_err("Codec type(%d) should be checked!\n", ctx->codec_mode);
@@ -155,6 +172,59 @@ static void __mfc_dec_calc_codec_buffer_size(struct 
mfc_core_ctx *core_ctx)
        /* Codecs have different memory requirements */
        switch (ctx->codec_mode) {
        case MFC_REG_CODEC_H264_DEC:
+       case MFC_REG_CODEC_H264_MVC_DEC:
+               ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, SZ_256);
+               core_ctx->codec_buf.size = ctx->scratch_buf_size;
+               ctx->mv_buf.size = dec->mv_count * ctx->mv_size;
+               break;
+       case MFC_REG_CODEC_MPEG4_DEC:
+       case MFC_REG_CODEC_FIMV1_DEC:
+       case MFC_REG_CODEC_FIMV2_DEC:
+       case MFC_REG_CODEC_FIMV3_DEC:
+       case MFC_REG_CODEC_FIMV4_DEC:
+               ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, SZ_256);
+               if (dec->loop_filter_mpeg4) {
+                       ctx->loopfilter_luma_size = 
ALIGN(ctx->raw_buf.plane_size[0], SZ_256);
+                       ctx->loopfilter_chroma_size = 
ALIGN(ctx->raw_buf.plane_size[1] +
+                                                       
ctx->raw_buf.plane_size[2], SZ_256);
+                       core_ctx->codec_buf.size = ctx->scratch_buf_size +
+                               (NUM_MPEG4_LF_BUF * (ctx->loopfilter_luma_size +
+                                                    
ctx->loopfilter_chroma_size));
+               } else {
+                       core_ctx->codec_buf.size = ctx->scratch_buf_size;
+               }
+               break;
+       case MFC_REG_CODEC_VC1_RCV_DEC:
+       case MFC_REG_CODEC_VC1_DEC:
+               ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, SZ_256);
+               core_ctx->codec_buf.size = ctx->scratch_buf_size;
+               break;
+       case MFC_REG_CODEC_MPEG2_DEC:
+               ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, SZ_256);
+               core_ctx->codec_buf.size = ctx->scratch_buf_size;
+               break;
+       case MFC_REG_CODEC_H263_DEC:
+               ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, SZ_256);
+               core_ctx->codec_buf.size = ctx->scratch_buf_size;
+               break;
+       case MFC_REG_CODEC_VP8_DEC:
+               ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, SZ_256);
+               core_ctx->codec_buf.size = ctx->scratch_buf_size;
+               break;
+       case MFC_REG_CODEC_VP9_DEC:
+               ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, SZ_256);
+               core_ctx->codec_buf.size =
+                       ctx->scratch_buf_size +
+                       DEC_STATIC_BUFFER_SIZE;
+               break;
+       case MFC_REG_CODEC_AV1_DEC:
+               ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, SZ_256);
+               core_ctx->codec_buf.size =
+                       ctx->scratch_buf_size +
+                       DEC_AV1_STATIC_BUFFER_SIZE(ctx->img_width, 
ctx->img_height);
+               ctx->mv_buf.size = dec->mv_count * ctx->mv_size;
+               break;
+       case MFC_REG_CODEC_HEVC_DEC:
                ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, SZ_256);
                core_ctx->codec_buf.size = ctx->scratch_buf_size;
                ctx->mv_buf.size = dec->mv_count * ctx->mv_size;
diff --git a/drivers/media/platform/samsung/exynos-mfc/base/mfc_common.h 
b/drivers/media/platform/samsung/exynos-mfc/base/mfc_common.h
index de22c28d1625..5392c8566e42 100644
--- a/drivers/media/platform/samsung/exynos-mfc/base/mfc_common.h
+++ b/drivers/media/platform/samsung/exynos-mfc/base/mfc_common.h
@@ -153,7 +153,47 @@
 
 /* Decoder codec mode check */
 #define IS_H264_DEC(ctx)       ((ctx)->codec_mode == MFC_REG_CODEC_H264_DEC)
+#define IS_H264_MVC_DEC(ctx)   ((ctx)->codec_mode == 
MFC_REG_CODEC_H264_MVC_DEC)
+#define IS_MPEG4_DEC(ctx)      ((ctx)->codec_mode == MFC_REG_CODEC_MPEG4_DEC)
+#define IS_FIMV1_DEC(ctx)      ((ctx)->codec_mode == MFC_REG_CODEC_FIMV1_DEC)
+#define IS_FIMV2_DEC(ctx)      ((ctx)->codec_mode == MFC_REG_CODEC_FIMV2_DEC)
+#define IS_FIMV3_DEC(ctx)      ((ctx)->codec_mode == MFC_REG_CODEC_FIMV3_DEC)
+#define IS_FIMV4_DEC(ctx)      ((ctx)->codec_mode == MFC_REG_CODEC_FIMV4_DEC)
+#define IS_VC1_DEC(ctx)                ((ctx)->codec_mode == 
MFC_REG_CODEC_VC1_DEC)
+#define IS_VC1_RCV_DEC(ctx)    ((ctx)->codec_mode == MFC_REG_CODEC_VC1_RCV_DEC)
+#define IS_MPEG2_DEC(ctx)      ((ctx)->codec_mode == MFC_REG_CODEC_MPEG2_DEC)
+#define IS_HEVC_DEC(ctx)       ((ctx)->codec_mode == MFC_REG_CODEC_HEVC_DEC)
+#define IS_VP8_DEC(ctx)                ((ctx)->codec_mode == 
MFC_REG_CODEC_VP8_DEC)
+#define IS_VP9_DEC(ctx)                ((ctx)->codec_mode == 
MFC_REG_CODEC_VP9_DEC)
+#define IS_AV1_DEC(ctx)                ((ctx)->codec_mode == 
MFC_REG_CODEC_AV1_DEC)
+#define IS_MV_HEVC_DEC(ctx, profile)                                           
        \
+       ((ctx)->codec_mode == MFC_REG_CODEC_HEVC_DEC &&                         
        \
+        (profile) == MFC_REG_D_PROFILE_MULTIVIEW_HEVC_MAIN)
+
+#define CODEC_NOT_CODED(ctx)   ({                                              
        \
+       typeof(ctx) _ctx = (ctx);                                               
        \
+       (IS_MPEG4_DEC(_ctx) || IS_VC1_DEC(_ctx) || IS_VC1_RCV_DEC(_ctx) ||      
        \
+        IS_VP9_DEC(_ctx));                                                     
        \
+})
+#define CODEC_INTERLACED(ctx)  ({                                              
        \
+       typeof(ctx) _ctx = (ctx);                                               
        \
+       (IS_H264_DEC(_ctx) || IS_H264_MVC_DEC(_ctx) || IS_MPEG2_DEC(_ctx) ||    
        \
+        IS_MPEG4_DEC(_ctx) || IS_VC1_DEC(_ctx) || IS_VC1_RCV_DEC(_ctx));       
        \
+})
+#define CODEC_MBAFF(ctx)       ({                                              
        \
+       typeof(ctx) _ctx = (ctx);                                               
        \
+       (IS_H264_DEC(_ctx) || IS_H264_MVC_DEC(_ctx));                           
        \
+})
+#define CODEC_MULTIFRAME(ctx)  ({                                              
        \
+       typeof(ctx) _ctx = (ctx);                                               
        \
+       (IS_MPEG4_DEC(_ctx) ||  IS_VP9_DEC(_ctx) || IS_FIMV2_DEC(_ctx) ||       
        \
+        IS_FIMV3_DEC(_ctx) ||  IS_FIMV4_DEC(_ctx) || IS_AV1_DEC(_ctx));        
        \
+})
 
+#define CODEC_422FORMAT(ctx)   ({                                              
        \
+       typeof(ctx) _ctx = (ctx);                                               
        \
+       (IS_HEVC_DEC(_ctx) || IS_VP9_DEC(_ctx));                        \
+})
 #define ON_RES_CHANGE(ctx)     ({                                              
        \
        typeof(ctx) _ctx = (ctx);                                               
        \
        ((_ctx->state >= MFCINST_RES_CHANGE_INIT) &&                            
        \
@@ -177,7 +217,7 @@
 })
 #define CODEC_HAS_IDR(ctx)     ({                                              
        \
        typeof(ctx) _ctx = (ctx);                                               
        \
-       (IS_H264_DEC(_ctx));            \
+       (IS_H264_DEC(_ctx) || IS_H264_MVC_DEC(_ctx) || IS_HEVC_DEC(_ctx));      
        \
 })
 
 /*
diff --git a/drivers/media/platform/samsung/exynos-mfc/base/mfc_data_struct.h 
b/drivers/media/platform/samsung/exynos-mfc/base/mfc_data_struct.h
index 34b4b13b4f01..6b93fe3ab138 100644
--- a/drivers/media/platform/samsung/exynos-mfc/base/mfc_data_struct.h
+++ b/drivers/media/platform/samsung/exynos-mfc/base/mfc_data_struct.h
@@ -503,6 +503,8 @@ struct mfc_fw {
 struct mfc_ctx_buf_size {
        size_t dev_ctx;
        size_t h264_dec_ctx;
+       size_t av1_dec_ctx;
+       size_t other_dec_ctx;
        size_t dbg_info_buf;
 };
 
@@ -710,6 +712,14 @@ struct mfc_bw_data {
 
 struct mfc_bw_info {
        struct mfc_bw_data bw_dec_h264;
+       struct mfc_bw_data bw_dec_hevc;
+       struct mfc_bw_data bw_dec_hevc_10bit;
+       struct mfc_bw_data bw_dec_vp8;
+       struct mfc_bw_data bw_dec_vp9;
+       struct mfc_bw_data bw_dec_vp9_10bit;
+       struct mfc_bw_data bw_dec_av1;
+       struct mfc_bw_data bw_dec_av1_10bit;
+       struct mfc_bw_data bw_dec_mpeg4;
 };
 
 /*
@@ -723,6 +733,7 @@ struct mfc_qos {
        unsigned int freq_int;
        unsigned int freq_mif;
        unsigned int mo_value;
+       unsigned int mo_10bit_value;
        unsigned int time_fw;
        unsigned int bts_scen_idx;
        const char *name;
@@ -747,8 +758,17 @@ struct mfc_qos_ctrl {
 
 struct mfc_qos_weight {
        unsigned int weight_h264_hevc;
+       unsigned int weight_vp8_vp9;
+       unsigned int weight_av1;
+       unsigned int weight_other_codec;
        unsigned int weight_3plane;
+       unsigned int weight_10bit;
+       unsigned int weight_422;
+       unsigned int weight_bframe;
+       unsigned int weight_num_of_ref;
+       unsigned int weight_gpb;
        unsigned int weight_num_of_tile;
+       unsigned int weight_super64_bframe;
        unsigned int weight_mbaff;
 };
 
diff --git a/drivers/media/platform/samsung/exynos-mfc/base/mfc_format.h 
b/drivers/media/platform/samsung/exynos-mfc/base/mfc_format.h
index 3307c2eeaebb..0d48f2373e8d 100644
--- a/drivers/media/platform/samsung/exynos-mfc/base/mfc_format.h
+++ b/drivers/media/platform/samsung/exynos-mfc/base/mfc_format.h
@@ -127,6 +127,142 @@ static struct mfc_fmt mfc_formats[] = {
                .num_planes = 1,
                .mem_planes = 1,
        },
+       {
+               .name = "DEC H264/MVC",
+               .fourcc = V4L2_PIX_FMT_H264_MVC,
+               .codec_mode = MFC_REG_CODEC_H264_MVC_DEC,
+               .type = MFC_FMT_STREAM | MFC_FMT_DEC,
+               .num_planes = 1,
+               .mem_planes = 1,
+       },
+       {
+               .name = "DEC H263",
+               .fourcc = V4L2_PIX_FMT_H263,
+               .codec_mode = MFC_REG_CODEC_H263_DEC,
+               .type = MFC_FMT_STREAM | MFC_FMT_DEC,
+               .num_planes = 1,
+               .mem_planes = 1,
+       },
+       {
+               .name = "DEC MPEG1",
+               .fourcc = V4L2_PIX_FMT_MPEG1,
+               .codec_mode = MFC_REG_CODEC_MPEG2_DEC,
+               .type = MFC_FMT_STREAM | MFC_FMT_DEC,
+               .num_planes = 1,
+               .mem_planes = 1,
+       },
+       {
+               .name = "DEC MPEG2",
+               .fourcc = V4L2_PIX_FMT_MPEG2,
+               .codec_mode = MFC_REG_CODEC_MPEG2_DEC,
+               .type = MFC_FMT_STREAM | MFC_FMT_DEC,
+               .num_planes = 1,
+               .mem_planes = 1,
+       },
+       {
+               .name = "DEC MPEG4",
+               .fourcc = V4L2_PIX_FMT_MPEG4,
+               .codec_mode = MFC_REG_CODEC_MPEG4_DEC,
+               .type = MFC_FMT_STREAM | MFC_FMT_DEC,
+               .num_planes = 1,
+               .mem_planes = 1,
+       },
+       {
+               .name = "DEC FIMV",
+               .fourcc = V4L2_PIX_FMT_FIMV,
+               .codec_mode = MFC_REG_CODEC_MPEG4_DEC,
+               .type = MFC_FMT_STREAM | MFC_FMT_DEC,
+               .num_planes = 1,
+               .mem_planes = 1,
+       },
+       {
+               .name = "DEC FIMV1",
+               .fourcc = V4L2_PIX_FMT_FIMV1,
+               .codec_mode = MFC_REG_CODEC_FIMV1_DEC,
+               .type = MFC_FMT_STREAM | MFC_FMT_DEC,
+               .num_planes = 1,
+               .mem_planes = 1,
+       },
+       {
+               .name = "DEC FIMV2",
+               .fourcc = V4L2_PIX_FMT_FIMV2,
+               .codec_mode = MFC_REG_CODEC_FIMV2_DEC,
+               .type = MFC_FMT_STREAM | MFC_FMT_DEC,
+               .num_planes = 1,
+               .mem_planes = 1,
+       },
+       {
+               .name = "DEC FIMV3",
+               .fourcc = V4L2_PIX_FMT_FIMV3,
+               .codec_mode = MFC_REG_CODEC_FIMV3_DEC,
+               .type = MFC_FMT_STREAM | MFC_FMT_DEC,
+               .num_planes = 1,
+               .mem_planes = 1,
+       },
+       {
+               .name = "DEC FIMV4",
+               .fourcc = V4L2_PIX_FMT_FIMV4,
+               .codec_mode = MFC_REG_CODEC_FIMV4_DEC,
+               .type = MFC_FMT_STREAM | MFC_FMT_DEC,
+               .num_planes = 1,
+               .mem_planes = 1,
+       },
+       {
+               .name = "DEC XviD",
+               .fourcc = V4L2_PIX_FMT_XVID,
+               .codec_mode = MFC_REG_CODEC_MPEG4_DEC,
+               .type = MFC_FMT_STREAM | MFC_FMT_DEC,
+               .num_planes = 1,
+               .mem_planes = 1,
+       },
+       {
+               .name = "DEC VC1",
+               .fourcc = V4L2_PIX_FMT_VC1_ANNEX_G,
+               .codec_mode = MFC_REG_CODEC_VC1_DEC,
+               .type = MFC_FMT_STREAM | MFC_FMT_DEC,
+               .num_planes = 1,
+               .mem_planes = 1,
+       },
+       {
+               .name = "DEC VC1 RCV",
+               .fourcc = V4L2_PIX_FMT_VC1_ANNEX_L,
+               .codec_mode = MFC_REG_CODEC_VC1_RCV_DEC,
+               .type = MFC_FMT_STREAM | MFC_FMT_DEC,
+               .num_planes = 1,
+               .mem_planes = 1,
+       },
+       {
+               .name = "DEC VP8",
+               .fourcc = V4L2_PIX_FMT_VP8,
+               .codec_mode = MFC_REG_CODEC_VP8_DEC,
+               .type = MFC_FMT_STREAM | MFC_FMT_DEC,
+               .num_planes = 1,
+               .mem_planes = 1,
+       },
+       {
+               .name = "DEC VP9",
+               .fourcc = V4L2_PIX_FMT_VP9,
+               .codec_mode = MFC_REG_CODEC_VP9_DEC,
+               .type = MFC_FMT_STREAM | MFC_FMT_DEC,
+               .num_planes = 1,
+               .mem_planes = 1,
+       },
+       {
+               .name = "DEC AV1",
+               .fourcc = V4L2_PIX_FMT_AV1,
+               .codec_mode = MFC_REG_CODEC_AV1_DEC,
+               .type = MFC_FMT_STREAM | MFC_FMT_DEC,
+               .num_planes = 1,
+               .mem_planes = 1,
+       },
+       {
+               .name = "DEC HEVC",
+               .fourcc = V4L2_PIX_FMT_HEVC,
+               .codec_mode = MFC_REG_CODEC_HEVC_DEC,
+               .type = MFC_FMT_STREAM | MFC_FMT_DEC,
+               .num_planes = 1,
+               .mem_planes = 1,
+       },
 };
 
 #endif /* __MFC_FORMAT_H */
diff --git a/drivers/media/platform/samsung/exynos-mfc/base/mfc_qos.c 
b/drivers/media/platform/samsung/exynos-mfc/base/mfc_qos.c
index f6548543f07c..9922c2396b94 100644
--- a/drivers/media/platform/samsung/exynos-mfc/base/mfc_qos.c
+++ b/drivers/media/platform/samsung/exynos-mfc/base/mfc_qos.c
@@ -38,6 +38,7 @@ static inline unsigned long __mfc_qos_add_weight(struct 
mfc_ctx *ctx, unsigned l
 
        switch (ctx->codec_mode) {
        case MFC_REG_CODEC_H264_DEC:
+       case MFC_REG_CODEC_H264_MVC_DEC:
                weight = (weight * 100) / qos_weight->weight_h264_hevc;
                mfc_ctx_debug(3, "[QoS] h264, hevc codec, weight: %d\n", weight 
/ 10);
                if (num_planes == 3) {
@@ -45,6 +46,63 @@ static inline unsigned long __mfc_qos_add_weight(struct 
mfc_ctx *ctx, unsigned l
                        mfc_ctx_debug(3, "[QoS] 3 plane, weight: %d\n", weight 
/ 10);
                }
                break;
+
+       case MFC_REG_CODEC_VP8_DEC:
+               weight = (weight * 100) / qos_weight->weight_vp8_vp9;
+               mfc_ctx_debug(3, "[QoS] vp8, vp9 codec, weight: %d\n", weight / 
10);
+               if (num_planes == 3) {
+                       weight = (weight * 100) / qos_weight->weight_3plane;
+                       mfc_ctx_debug(3, "[QoS] 3 plane, weight: %d\n", weight 
/ 10);
+               }
+               break;
+
+       case MFC_REG_CODEC_HEVC_DEC:
+               weight = (weight * 100) / qos_weight->weight_h264_hevc;
+               mfc_ctx_debug(3, "[QoS] h264, hevc codec, weight: %d\n", weight 
/ 10);
+               if (num_planes == 3) {
+                       weight = (weight * 100) / qos_weight->weight_3plane;
+                       mfc_ctx_debug(3, "[QoS] 3 plane, weight: %d\n", weight 
/ 10);
+               } else {
+                       if (ctx->is_422) {
+                               weight = (weight * 100) / 
qos_weight->weight_422;
+                               mfc_ctx_debug(3, "[QoS] 422foramt, weight: 
%d\n", weight / 10);
+                       }
+               }
+               break;
+
+       case MFC_REG_CODEC_AV1_DEC:
+               weight = (weight * 100) / qos_weight->weight_av1;
+               mfc_ctx_debug(3, "[QoS] av1 codec, weight: %d\n", weight / 10);
+               break;
+
+       case MFC_REG_CODEC_VP9_DEC:
+               weight = (weight * 100) / qos_weight->weight_vp8_vp9;
+               mfc_ctx_debug(3, "[QoS] vp8, vp9 codec, weight: %d\n", weight / 
10);
+
+               if (num_planes == 3) {
+                       weight = (weight * 100) / qos_weight->weight_3plane;
+                       mfc_ctx_debug(3, "[QoS] 3 plane, weight: %d\n", weight 
/ 10);
+               } else {
+                       if (ctx->is_422) {
+                               weight = (weight * 100) / 
qos_weight->weight_422;
+                               mfc_ctx_debug(3, "[QoS] 422foramt, weight: 
%d\n", weight / 10);
+                       }
+               }
+               break;
+
+       case MFC_REG_CODEC_MPEG4_DEC:
+       case MFC_REG_CODEC_FIMV1_DEC:
+       case MFC_REG_CODEC_FIMV2_DEC:
+       case MFC_REG_CODEC_FIMV3_DEC:
+       case MFC_REG_CODEC_FIMV4_DEC:
+       case MFC_REG_CODEC_H263_DEC:
+       case MFC_REG_CODEC_VC1_RCV_DEC:
+       case MFC_REG_CODEC_VC1_DEC:
+       case MFC_REG_CODEC_MPEG2_DEC:
+               weight = (weight * 100) / qos_weight->weight_other_codec;
+               mfc_ctx_debug(3, "[QoS] other codec, weight: %d\n", weight / 
10);
+               break;
+
        default:
                mfc_ctx_err("[QoS] wrong codec_mode (%d), no weight\n", 
ctx->codec_mode);
        }
diff --git a/drivers/media/platform/samsung/exynos-mfc/base/mfc_queue.c 
b/drivers/media/platform/samsung/exynos-mfc/base/mfc_queue.c
index f56e800c55f0..6dc9bc7a1873 100644
--- a/drivers/media/platform/samsung/exynos-mfc/base/mfc_queue.c
+++ b/drivers/media/platform/samsung/exynos-mfc/base/mfc_queue.c
@@ -154,6 +154,11 @@ struct mfc_buf *mfc_get_del_if_consumed(struct mfc_ctx 
*ctx,
                            consumed, strm_size);
        }
 
+       if (remained && IS_MULTI_MODE(ctx) && !CODEC_MULTIFRAME(ctx)) {
+               mfc_ctx_info("[2CORE][MULTIFRAME] multicore mode couldn't 
handle multiframe\n");
+               remained = 0;
+       }
+
        if (consumed > 0 && remained > min_bytes &&
            IS_NO_ERROR(error) && !exceed) {
                /* do not delete from queue */
diff --git a/drivers/media/platform/samsung/exynos-mfc/base/mfc_utils.c 
b/drivers/media/platform/samsung/exynos-mfc/base/mfc_utils.c
index b0698b2bb0c0..83cdae3dee57 100644
--- a/drivers/media/platform/samsung/exynos-mfc/base/mfc_utils.c
+++ b/drivers/media/platform/samsung/exynos-mfc/base/mfc_utils.c
@@ -187,9 +187,15 @@ void mfc_dec_calc_dpb_size(struct mfc_ctx *ctx, struct 
mfc_raw_info *raw, struct
        }
        mfc_ctx_debug(2, "[FRAME] total plane size: %d\n", 
raw->total_plane_size);
 
-       if (IS_H264_DEC(ctx)) {
+       if (IS_H264_DEC(ctx) || IS_H264_MVC_DEC(ctx)) {
                ctx->mv_size = DEC_MV_SIZE_MB(ctx->img_width, ctx->img_height);
                ctx->mv_size = ALIGN(ctx->mv_size, 32);
+       } else if (IS_HEVC_DEC(ctx)) {
+               ctx->mv_size = DEC_HEVC_MV_SIZE(ctx->img_width, 
ctx->img_height);
+               ctx->mv_size = ALIGN(ctx->mv_size, 32);
+       } else if (IS_AV1_DEC(ctx)) {
+               ctx->mv_size = DEC_AV1_MV_SIZE(ctx->img_width, ctx->img_height);
+               ctx->mv_size = ALIGN(ctx->mv_size, 32);
        } else {
                ctx->mv_size = 0;
        }
diff --git a/drivers/media/platform/samsung/exynos-mfc/mfc.c 
b/drivers/media/platform/samsung/exynos-mfc/mfc.c
index fb9a7317e812..293a353c49fa 100644
--- a/drivers/media/platform/samsung/exynos-mfc/mfc.c
+++ b/drivers/media/platform/samsung/exynos-mfc/mfc.c
@@ -646,18 +646,69 @@ static int __mfc_parse_dt(struct device_node *np, struct 
mfc_dev *mfc)
        of_property_read_u32_array
                (np, "bw_dec_h264",
                &pdata->mfc_bw_info.bw_dec_h264.peak, 3);
+       of_property_read_u32_array
+               (np, "bw_dec_hevc",
+               &pdata->mfc_bw_info.bw_dec_hevc.peak, 3);
+       of_property_read_u32_array
+               (np, "bw_dec_hevc_10bit",
+               &pdata->mfc_bw_info.bw_dec_hevc_10bit.peak, 3);
+       of_property_read_u32_array
+               (np, "bw_dec_vp8",
+               &pdata->mfc_bw_info.bw_dec_vp8.peak, 3);
+       of_property_read_u32_array
+               (np, "bw_dec_vp9",
+               &pdata->mfc_bw_info.bw_dec_vp9.peak, 3);
+       of_property_read_u32_array
+               (np, "bw_dec_vp9_10bit",
+               &pdata->mfc_bw_info.bw_dec_vp9_10bit.peak, 3);
+       of_property_read_u32_array
+               (np, "bw_dec_av1",
+               &pdata->mfc_bw_info.bw_dec_av1.peak, 3);
+       of_property_read_u32_array
+               (np, "bw_dec_av1_10bit",
+               &pdata->mfc_bw_info.bw_dec_av1_10bit.peak, 3);
+       of_property_read_u32_array
+               (np, "bw_dec_mpeg4",
+               &pdata->mfc_bw_info.bw_dec_mpeg4.peak, 3);
 
        /* QoS weight */
        of_property_read_u32(np, "dynamic_weight", &pdata->dynamic_weight);
        of_property_read_u32
                        (np, "qos_weight_h264_hevc",
                        &pdata->qos_weight.weight_h264_hevc);
+       of_property_read_u32
+                       (np, "qos_weight_vp8_vp9",
+                       &pdata->qos_weight.weight_vp8_vp9);
+       of_property_read_u32
+                       (np, "qos_weight_av1",
+                       &pdata->qos_weight.weight_av1);
+       of_property_read_u32
+                       (np, "qos_weight_other_codec",
+                       &pdata->qos_weight.weight_other_codec);
        of_property_read_u32
                        (np, "qos_weight_3plane",
                        &pdata->qos_weight.weight_3plane);
+       of_property_read_u32
+                       (np, "qos_weight_10bit",
+                       &pdata->qos_weight.weight_10bit);
+       of_property_read_u32
+                       (np, "qos_weight_422",
+                       &pdata->qos_weight.weight_422);
+       of_property_read_u32
+                       (np, "qos_weight_bframe",
+                       &pdata->qos_weight.weight_bframe);
+       of_property_read_u32
+                       (np, "qos_weight_num_of_ref",
+                       &pdata->qos_weight.weight_num_of_ref);
+       of_property_read_u32
+                       (np, "qos_weight_gpb",
+                       &pdata->qos_weight.weight_gpb);
        of_property_read_u32
                        (np, "qos_weight_num_of_tile",
                        &pdata->qos_weight.weight_num_of_tile);
+       of_property_read_u32
+                       (np, "qos_weight_super64_bframe",
+                       &pdata->qos_weight.weight_super64_bframe);
        of_property_read_u32
                        (np, "qos_weight_mbaff",
                        &pdata->qos_weight.weight_mbaff);
@@ -1075,6 +1126,8 @@ static const struct dev_pm_ops mfc_pm_ops = {
 struct mfc_ctx_buf_size mfc_ctx_buf_size = {
        .dev_ctx        = PAGE_ALIGN(0x7800),   /*  30KB */
        .h264_dec_ctx   = PAGE_ALIGN(0x200000), /* 1.6MB */
+       .av1_dec_ctx    = PAGE_ALIGN(0x19000),  /* 100KB */
+       .other_dec_ctx  = PAGE_ALIGN(0xF000),   /*  60KB */
        .dbg_info_buf   = PAGE_ALIGN(0x1000),   /* 4KB for DEBUG INFO */
 };
 
diff --git a/drivers/media/platform/samsung/exynos-mfc/mfc_core.c 
b/drivers/media/platform/samsung/exynos-mfc/mfc_core.c
index af6fd088fad3..aad3273ce2ba 100644
--- a/drivers/media/platform/samsung/exynos-mfc/mfc_core.c
+++ b/drivers/media/platform/samsung/exynos-mfc/mfc_core.c
@@ -77,6 +77,8 @@ static int __mfc_core_parse_mfc_qos_platdata(struct 
device_node *np,
        of_property_read_u32(np_qos, "freq_int", &qosdata->freq_int);
        of_property_read_u32(np_qos, "freq_mif", &qosdata->freq_mif);
        of_property_read_u32(np_qos, "mo_value", &qosdata->mo_value);
+       of_property_read_u32(np_qos, "mo_10bit_value",
+                            &qosdata->mo_10bit_value);
        of_property_read_u32(np_qos, "time_fw", &qosdata->time_fw);
 
        of_property_read_string(np_qos, "bts_scen", &qosdata->name);
diff --git a/drivers/media/platform/samsung/exynos-mfc/mfc_core_buf_ctrl.c 
b/drivers/media/platform/samsung/exynos-mfc/mfc_core_buf_ctrl.c
index 56dc3e734d02..38f09d6ef2dd 100644
--- a/drivers/media/platform/samsung/exynos-mfc/mfc_core_buf_ctrl.c
+++ b/drivers/media/platform/samsung/exynos-mfc/mfc_core_buf_ctrl.c
@@ -63,6 +63,7 @@ static int mfc_core_get_buf_ctrls(struct mfc_core *core,
                                  struct mfc_ctx *ctx, struct list_head *head)
 {
        struct mfc_buf_ctrl *buf_ctrl;
+       struct mfc_dec *dec = ctx->dec_priv;
        unsigned int value = 0;
 
        list_for_each_entry(buf_ctrl, head, list) {
@@ -77,6 +78,14 @@ static int mfc_core_get_buf_ctrls(struct mfc_core *core,
                buf_ctrl->val = value;
                buf_ctrl->has_new = 1;
 
+               if (IS_VP9_DEC(ctx) && dec) {
+                       if (buf_ctrl->id == V4L2_CID_MPEG_VIDEO_FULL_RANGE_FLAG)
+                               buf_ctrl->val = dec->color_range;
+                       else if (buf_ctrl->id ==
+                                V4L2_CID_MPEG_VIDEO_COLOUR_PRIMARIES)
+                               buf_ctrl->val = dec->color_space;
+               }
+
                if (buf_ctrl->id == V4L2_CID_MPEG_VIDEO_FRAME_ERROR_TYPE)
                        buf_ctrl->val = mfc_get_frame_error_type(ctx, value);
 
diff --git a/drivers/media/platform/samsung/exynos-mfc/mfc_core_cmd.c 
b/drivers/media/platform/samsung/exynos-mfc/mfc_core_cmd.c
index fe7946bb49e7..aaf216741575 100644
--- a/drivers/media/platform/samsung/exynos-mfc/mfc_core_cmd.c
+++ b/drivers/media/platform/samsung/exynos-mfc/mfc_core_cmd.c
@@ -230,6 +230,10 @@ void mfc_core_cmd_dec_seq_header(struct mfc_core *core, 
struct mfc_ctx *ctx)
        reg |= ((dec->idr_decoding & MFC_REG_D_DEC_OPT_IDR_DECODING_MASK)
                << MFC_REG_D_DEC_OPT_IDR_DECODING_SHIFT);
 
+       /* VC1 RCV: Discard to parse additional header as default */
+       if (IS_VC1_RCV_DEC(ctx))
+               reg |= BIT(MFC_REG_D_DEC_OPT_DISCARD_RCV_HEADER_SHIFT);
+
        /* conceal control to specific color */
        reg |= (0x4 << MFC_REG_D_DEC_OPT_CONCEAL_CONTROL_SHIFT);
 
@@ -248,6 +252,13 @@ void mfc_core_cmd_dec_seq_header(struct mfc_core *core, 
struct mfc_ctx *ctx)
 
        MFC_CORE_WRITEL(MFC_CONCEAL_COLOR, MFC_REG_D_FORCE_PIXEL_VAL);
 
+       if (IS_FIMV1_DEC(ctx)) {
+               mfc_debug(2, "Setting FIMV1 resolution to %dx%d\n",
+                         ctx->img_width, ctx->img_height);
+               MFC_CORE_WRITEL(ctx->img_width, MFC_REG_D_SET_FRAME_WIDTH);
+               MFC_CORE_WRITEL(ctx->img_height, MFC_REG_D_SET_FRAME_HEIGHT);
+       }
+
        mfc_core_set_pixel_format(core, ctx, ctx->dst_fmt->fourcc);
 
        reg = 0;
diff --git a/drivers/media/platform/samsung/exynos-mfc/mfc_core_isr.c 
b/drivers/media/platform/samsung/exynos-mfc/mfc_core_isr.c
index 94cc3c4dfdc5..aa2c0b618c19 100644
--- a/drivers/media/platform/samsung/exynos-mfc/mfc_core_isr.c
+++ b/drivers/media/platform/samsung/exynos-mfc/mfc_core_isr.c
@@ -126,10 +126,11 @@ static unsigned int __mfc_handle_frame_field(struct 
mfc_core *core,
        unsigned int interlace_type = 0, is_interlace = 0;
        unsigned int field;
 
-       if (IS_H264_DEC(ctx)) {
-               dec->is_mbaff = mfc_core_is_mbaff_picture();
+       if (CODEC_INTERLACED(ctx))
                is_interlace = mfc_core_is_interlace_picture();
-       }
+
+       if (CODEC_MBAFF(ctx))
+               dec->is_mbaff = mfc_core_is_mbaff_picture();
 
        if (is_interlace) {
                interlace_type = mfc_core_get_interlace_type();
@@ -482,6 +483,27 @@ static struct mfc_buf 
*__mfc_handle_frame_output_del(struct mfc_core *core,
                        }
                }
 
+               if (IS_VP9_DEC(ctx) &&
+                   MFC_FEATURE_SUPPORT(dev, dev->pdata->color_aspect_dec)) {
+                       if (dec->color_space != MFC_REG_D_COLOR_UNKNOWN) {
+                               mfc_set_mb_flag(dst_mb,
+                                               MFC_FLAG_HDR_COLOUR_DESC);
+                               mfc_ctx_debug(2, "[HDR] color space parsed\n");
+                       }
+                       mfc_set_mb_flag(dst_mb, MFC_FLAG_HDR_VIDEO_SIGNAL_TYPE);
+                       mfc_ctx_debug(2, "[HDR] color range parsed\n");
+               }
+
+               if ((IS_VP9_DEC(ctx) && mfc_core_get_disp_res_change()) ||
+                   (IS_AV1_DEC(ctx) && mfc_core_get_disp_res_change_av1())) {
+                       mfc_ctx_info("[FRAME][DRC] display resolution 
changed\n");
+                       mutex_lock(&ctx->drc_wait_mutex);
+                       ctx->wait_state = WAIT_G_FMT;
+                       mfc_core_get_img_size(core, ctx, MFC_GET_RESOL_SIZE);
+                       mfc_set_mb_flag(dst_mb, MFC_FLAG_DISP_RES_CHANGE);
+                       mutex_unlock(&ctx->drc_wait_mutex);
+               }
+
                if (dec->black_bar_updated) {
                        mfc_set_mb_flag(dst_mb, MFC_FLAG_BLACKBAR_DETECT);
                        mfc_ctx_debug(3, "[BLACKBAR] black bar detected\n");
@@ -498,6 +520,11 @@ static struct mfc_buf 
*__mfc_handle_frame_output_del(struct mfc_core *core,
                        mfc_ctx_debug(2, "[FRAME] Last display frame\n");
                }
 
+               if ((IS_VP9_DEC(ctx) || IS_AV1_DEC(ctx)) && 
dec->has_multiframe) {
+                       mfc_set_mb_flag(dst_mb, MFC_FLAG_MULTIFRAME);
+                       mfc_ctx_debug(2, "[MULTIFRAME] multiframe detected\n");
+               }
+
                if (ctx->dst_fmt->mem_planes == 1) {
                        vb2_set_plane_payload(&dst_mb->vb.vb2_buf, 0,
                                              raw->total_plane_size);
@@ -542,6 +569,8 @@ static struct mfc_buf *__mfc_handle_frame_output_del(struct 
mfc_core *core,
 
                mutex_unlock(&dec->dpb_mutex);
        } else {
+               if (IS_AV1_DEC(ctx) && mfc_core_get_multiple_show_frame())
+                       dec->is_multiple_show = 1;
                mfc_print_dpb_queue_with_lock(core->core_ctx[ctx->num], dec);
        }
 
@@ -708,11 +737,18 @@ static struct mfc_buf *__mfc_handle_frame_output(struct 
mfc_core *core,
 {
        struct mfc_dec *dec = ctx->dec_priv;
        unsigned int frame_type;
+       int mvc_view_id;
 
        frame_type = mfc_core_get_disp_frame_type();
+       mvc_view_id = mfc_core_get_mvc_disp_view_id();
 
-       if (!ctx->multi_view_enable || ctx->select_view_irq == MFC_VIEW_ID_SUB)
-               ctx->sequence++;
+       if (IS_H264_MVC_DEC(ctx)) {
+               if (mvc_view_id == 0)
+                       ctx->sequence++;
+       } else {
+               if (!ctx->multi_view_enable || ctx->select_view_irq == 
MFC_VIEW_ID_SUB)
+                       ctx->sequence++;
+       }
 
        if (dec->immediate_display == 1)
                frame_type = mfc_core_get_dec_frame_type();
@@ -721,7 +757,8 @@ static struct mfc_buf *__mfc_handle_frame_output(struct 
mfc_core *core,
 
        /* If frame is same as previous then skip and do not dequeue */
        if (frame_type == MFC_REG_DISPLAY_FRAME_NOT_CODED)
-               return NULL;
+               if (!CODEC_NOT_CODED(ctx))
+                       return NULL;
 
        /* Dequeued display buffer for user */
        return __mfc_handle_frame_output_del(core, ctx, err);
@@ -894,6 +931,7 @@ static void __mfc_handle_frame_input(struct mfc_core *core,
                                     struct mfc_ctx *ctx,
                                     unsigned int err)
 {
+       struct mfc_dev *dev = ctx->dev;
        struct mfc_core_ctx *core_ctx = core->core_ctx[ctx->num];
        struct mfc_dec *dec = ctx->dec_priv;
        struct mfc_buf *src_mb;
@@ -945,6 +983,54 @@ static void __mfc_handle_frame_input(struct mfc_core *core,
 
        mfc_clear_mb_flag(src_mb);
 
+       if ((IS_VP9_DEC(ctx) || IS_AV1_DEC(ctx)) && dec->has_multiframe &&
+           mfc_core_get_disp_status() == MFC_REG_DEC_STATUS_DECODING_ONLY) {
+               mfc_set_mb_flag(src_mb, MFC_FLAG_CONSUMED_ONLY);
+               mfc_debug(2, "[STREAM][MULTIFRAME] last frame is decoding 
only\n");
+       }
+
+       /*
+        * VP8 decoder has decoding only frame,
+        * it will be used for reference frame only not displayed.
+        * So, driver inform to user this input has no destination.
+        */
+       if (((IS_VP8_DEC(ctx) || IS_VP9_DEC(ctx)) &&
+            mfc_core_get_disp_status() == MFC_REG_DEC_STATUS_DECODING_ONLY) ||
+           mfc_core_get_int_reason() == MFC_REG_R2H_CMD_FIELD_DONE_RET) {
+               mfc_set_mb_flag(src_mb, MFC_FLAG_CONSUMED_ONLY);
+               mfc_debug(2, "[STREAM] %s decoding only stream has no buffer to 
DQ\n",
+                         ctx->src_fmt->name);
+       }
+
+       /*
+        * Because AV1 has a no show frame, there are two cases that
+        * driver should inform to user this input has no destination buffer.
+        * 1) If it's decoding only and it's not showable frame,
+        *   it will be used for reference frame only not displayed.
+        * 2) If the buffer that has already DQ to display comes to new display,
+        *   it is multiple show frame.
+        */
+       if (IS_AV1_DEC(ctx)) {
+               if ((mfc_core_get_disp_status() == 
MFC_REG_DEC_STATUS_DECODING_ONLY) &&
+                   !mfc_core_get_showable_frame()) {
+                       mfc_set_mb_flag(src_mb, MFC_FLAG_CONSUMED_ONLY);
+                       mfc_debug(2, "[STREAM] AV1 no showable frame has no 
buffer to DQ\n");
+               }
+               if (dec->is_multiple_show) {
+                       mfc_set_mb_flag(src_mb, MFC_FLAG_CONSUMED_ONLY);
+                       dec->is_multiple_show = 0;
+                       mfc_info("[STREAM] AV1 multiple show frame has no 
buffer to DQ\n");
+               }
+       }
+
+       /* If pic_output_flag is 0 in HEVC, it is no destination buffer */
+       if (IS_HEVC_DEC(ctx) &&
+           MFC_FEATURE_SUPPORT(dev, dev->pdata->hevc_pic_output_flag) &&
+           !mfc_core_get_hevc_pic_output_flag()) {
+               mfc_set_mb_flag(src_mb, MFC_FLAG_CONSUMED_ONLY);
+               mfc_debug(2, "[STREAM] HEVC pic_output_flag off has no buffer 
to DQ\n");
+       }
+
        if (mfc_core_get_disp_status() == MFC_REG_DEC_STATUS_DECODING_ONLY &&
            mfc_core_get_dec_y_addr() == 0) {
                mfc_set_mb_flag(src_mb, MFC_FLAG_CONSUMED_ONLY);
@@ -955,6 +1041,8 @@ static void __mfc_handle_frame_input(struct mfc_core *core,
                mfc_err("failed in core_get_buf_ctrls\n");
 
        dec->consumed = 0;
+       if (IS_VP9_DEC(ctx) || IS_AV1_DEC(ctx))
+               dec->has_multiframe = 0;
 
        if (ctx->multi_view_enable && ctx->select_view == 0)
                mfc_set_mb_flag(src_mb, MFC_FLAG_CONSUMED_ONLY);
@@ -978,7 +1066,7 @@ static void __mfc_handle_frame(struct mfc_core *core,
        unsigned int res_change, need_dpb_change, need_scratch_change;
        struct mfc_buf *mfc_buf = NULL;
        bool qos_update = false;
-       int index;
+       int index, profile;
 
        dst_frame_status = mfc_core_get_disp_status();
        res_change = mfc_core_get_res_change();
@@ -1048,6 +1136,15 @@ static void __mfc_handle_frame(struct mfc_core *core,
                        index = mfc_buf->vb.vb2_buf.index;
                        call_bop(ctx, core_restore_buf_ctrls, ctx, 
&ctx->src_ctrls[index]);
                }
+
+               /* It could because of sub-view header (MV-HEVC) */
+               if (!ctx->multi_view_enable) {
+                       profile = mfc_core_get_profile();
+                       if (IS_MV_HEVC_DEC(ctx, profile)) {
+                               mfc_debug(2, "Ready to enable, possibly a 
sub-view header.\n");
+                               ctx->ready_to_be_multi_view_enable = 1;
+                       }
+               }
                return;
        }
 
@@ -1110,7 +1207,7 @@ static void __mfc_handle_frame(struct mfc_core *core,
        }
 
        /* Detection for QoS weight */
-       if (!dec->num_of_tile_over_4 &&
+       if (!dec->num_of_tile_over_4 && !IS_HEVC_DEC(ctx) &&
            mfc_core_get_num_of_tile() >= 4) {
                dec->num_of_tile_over_4 = 1;
                qos_update = true;
@@ -1185,7 +1282,7 @@ static int __mfc_handle_seq_dec(struct mfc_core *core, 
struct mfc_ctx *ctx)
        struct mfc_core_ctx *core_ctx = core->core_ctx[ctx->num];
        struct mfc_dec *dec = ctx->dec_priv;
        struct mfc_buf *src_mb;
-       int i, is_interlace;
+       int i, is_interlace, profile;
        unsigned int strm_size, consumed;
 
        if (ctx->src_fmt->fourcc != V4L2_PIX_FMT_FIMV1) {
@@ -1196,13 +1293,34 @@ static int __mfc_handle_seq_dec(struct mfc_core *core, 
struct mfc_ctx *ctx)
                mfc_info("[STREAM] resolution w: %d, h: %d\n", ctx->img_width, 
ctx->img_height);
        }
 
-       ctx->dpb_count = mfc_core_get_dpb_count();
+       if (IS_AV1_DEC(ctx) || (IS_VP9_DEC(ctx) && UNDER_4K_RES(ctx)))
+               ctx->dpb_count = mfc_core_get_dpb_count() + 7 - MFC_EXTRA_DPB;
+       else
+               ctx->dpb_count = mfc_core_get_dpb_count();
        mfc_ctx_debug(2, "dpb_count: %d\n", ctx->dpb_count);
 
        ctx->scratch_buf_size = mfc_core_get_scratch_size();
 
        mfc_core_dec_get_crop_info(core, ctx);
        dec->mv_count = mfc_core_get_mv_count();
+       profile = mfc_core_get_profile();
+
+       if (CODEC_422FORMAT(ctx) && dev->pdata->support_422) {
+               if (mfc_core_get_chroma_format() == MFC_REG_D_CHROMA_422) {
+                       ctx->is_422 = 1;
+                       mfc_info("[STREAM] 422 chroma format\n");
+               }
+       }
+
+       if (IS_MV_HEVC_DEC(ctx, profile)) {
+               if (ctx->ready_to_be_multi_view_enable) {
+                       mfc_debug(2, "It will be enabled later, pending 
DPB_FLUSH.\n");
+               } else {
+                       mfc_debug(2, "[MV-HEVC] enabled\n");
+                       ctx->multi_view_enable = 1;
+                       ctx->select_view = MFC_VIEW_ID_MAIN;
+               }
+       }
 
        if (ctx->img_width == 0 || ctx->img_height == 0) {
                mfc_err("[STREAM] wrong resolution w: %d, h: %d\n",
@@ -1243,7 +1361,7 @@ static int __mfc_handle_seq_dec(struct mfc_core *core, 
struct mfc_ctx *ctx)
                strm_size = mfc_dec_get_strm_size(ctx, src_mb);
                mfc_debug(2, "[STREAM] header size, %d, %#x, consumed, %d, 
%#x\n",
                          strm_size, strm_size, consumed, consumed);
-               if ((IS_H264_DEC(ctx)) &&
+               if ((IS_H264_DEC(ctx) || IS_H264_MVC_DEC(ctx) || 
IS_HEVC_DEC(ctx)) &&
                    (consumed > 0 && strm_size > consumed)) {
                        dec->consumed += consumed;
                        mfc_debug(2, "[STREAM] there is remained bytes(%d) 
after header parsing\n",
@@ -1257,6 +1375,13 @@ static int __mfc_handle_seq_dec(struct mfc_core *core, 
struct mfc_ctx *ctx)
        mfc_debug(2, "[FRAME] display delay for first frame %d\n",
                  dec->frame_display_delay);
 
+       if (IS_VP9_DEC(ctx)) {
+               dec->color_range = mfc_core_get_color_range();
+               dec->color_space = mfc_core_get_color_space();
+               mfc_debug(2, "color range: %d, color space: %d, It's valid for 
VP9\n",
+                         dec->color_range, dec->color_space);
+       }
+
        mfc_change_state(core_ctx, MFCINST_HEAD_PARSED);
 
        return 0;
diff --git a/drivers/media/platform/samsung/exynos-mfc/mfc_core_reg_api.c 
b/drivers/media/platform/samsung/exynos-mfc/mfc_core_reg_api.c
index 6950b8451c3d..0cc5d1d9433e 100644
--- a/drivers/media/platform/samsung/exynos-mfc/mfc_core_reg_api.c
+++ b/drivers/media/platform/samsung/exynos-mfc/mfc_core_reg_api.c
@@ -52,7 +52,8 @@ unsigned int mfc_get_frame_error_type(struct mfc_ctx *ctx, 
unsigned int err)
                return MFC_ERR_FRAME_NO_ERR;
        }
 
-       if (mfc_get_warn(err) == MFC_REG_ERR_BROKEN_LINK) {
+       if ((IS_VC1_RCV_DEC(ctx) && (mfc_get_warn(err) == 
MFC_REG_ERR_SYNC_POINT_NOT_RECEIVED)) ||
+           (mfc_get_warn(err) == MFC_REG_ERR_BROKEN_LINK)) {
                mfc_ctx_debug(2, "[FRAME] Broken frame error (%d)\n", 
mfc_get_warn(err));
                return MFC_ERR_FRAME_BROKEN;
        } else if (mfc_get_warn(err) == MFC_REG_ERR_SYNC_POINT_NOT_RECEIVED) {
@@ -104,6 +105,7 @@ int mfc_core_set_dec_codec_buffers(struct mfc_core_ctx 
*core_ctx)
        int buf_size;
        int align_gap;
        unsigned int reg = 0;
+       unsigned int av1_static_buf_size = 0;
 
        buf_addr = core_ctx->codec_buf.daddr;
        buf_size = core_ctx->codec_buf.size;
@@ -124,14 +126,50 @@ int mfc_core_set_dec_codec_buffers(struct mfc_core_ctx 
*core_ctx)
        buf_addr += ctx->scratch_buf_size;
        buf_size -= ctx->scratch_buf_size;
 
-       if (IS_H264_DEC(ctx))
+       if (IS_H264_DEC(ctx) || IS_H264_MVC_DEC(ctx) || IS_HEVC_DEC(ctx) || 
IS_AV1_DEC(ctx))
                MFC_CORE_WRITEL(ctx->mv_size, MFC_REG_D_MV_BUFFER_SIZE);
 
+       if (IS_VP9_DEC(ctx)) {
+               MFC_CORE_DMA_WRITEL(buf_addr, MFC_REG_D_STATIC_BUFFER_ADDR);
+               MFC_CORE_WRITEL(DEC_STATIC_BUFFER_SIZE, 
MFC_REG_D_STATIC_BUFFER_SIZE);
+               buf_addr += DEC_STATIC_BUFFER_SIZE;
+               buf_size -= DEC_STATIC_BUFFER_SIZE;
+       } else if (IS_AV1_DEC(ctx)) {
+               av1_static_buf_size = 
DEC_AV1_STATIC_BUFFER_SIZE(ctx->img_width, ctx->img_height);
+               MFC_CORE_DMA_WRITEL(buf_addr, MFC_REG_D_STATIC_BUFFER_ADDR);
+               MFC_CORE_WRITEL(av1_static_buf_size, 
MFC_REG_D_STATIC_BUFFER_SIZE);
+               buf_addr += av1_static_buf_size;
+               buf_size -= av1_static_buf_size;
+       }
+
+       if (IS_MPEG4_DEC(ctx) && dec->loop_filter_mpeg4) {
+               mfc_debug(2, "Add DPB for loop filter of MPEG4\n");
+               for (i = 0; i < NUM_MPEG4_LF_BUF; i++) {
+                       MFC_CORE_DMA_WRITEL(buf_addr, 
MFC_REG_D_POST_FILTER_LUMA_DPB0 + (4 * i));
+                       buf_addr += ctx->loopfilter_luma_size;
+                       buf_size -= ctx->loopfilter_luma_size;
+
+                       MFC_CORE_DMA_WRITEL(buf_addr, 
MFC_REG_D_POST_FILTER_CHROMA_DPB0 + (4 * i));
+                       buf_addr += ctx->loopfilter_chroma_size;
+                       buf_size -= ctx->loopfilter_chroma_size;
+               }
+               reg |= ((dec->loop_filter_mpeg4 & 
MFC_REG_D_INIT_BUF_OPT_LF_CTRL_MASK)
+                               << MFC_REG_D_INIT_BUF_OPT_LF_CTRL_SHIFT);
+       }
+
        reg |= (dec->is_dynamic_dpb << 
MFC_REG_D_INIT_BUF_OPT_DYNAMIC_DPB_SET_SHIFT);
 
+       if (CODEC_NOT_CODED(ctx)) {
+               reg |= BIT(MFC_REG_D_INIT_BUF_OPT_COPY_NOT_CODED_SHIFT);
+               mfc_debug(2, "Notcoded frame copy mode start\n");
+       }
+
        /* 16byte align, It is valid only for VP9 */
        reg &= ~BIT(MFC_REG_D_INIT_BUF_OPT_STRIDE_SIZE_ALIGN);
-
+       if (IS_VP9_DEC(ctx) && MFC_FEATURE_SUPPORT(dev, 
dev->pdata->vp9_stride_align)) {
+               reg &= ~(0x3 << MFC_REG_D_INIT_BUF_OPT_STRIDE_SIZE_ALIGN);
+               reg |= (0x2 << MFC_REG_D_INIT_BUF_OPT_STRIDE_SIZE_ALIGN);
+       }
        reg &= ~BIT(MFC_REG_D_INIT_BUF_OPT_TWO_MODE_ENABLE_SHIFT);
        if (IS_MULTI_MODE(ctx)) {
                reg |= BIT(MFC_REG_D_INIT_BUF_OPT_TWO_MODE_ENABLE_SHIFT);
@@ -158,7 +196,7 @@ int mfc_core_set_dec_codec_buffers(struct mfc_core_ctx 
*core_ctx)
 
        frame_size_mv = ctx->mv_size;
        MFC_CORE_WRITEL(dec->mv_count, MFC_REG_D_NUM_MV);
-       if (IS_H264_DEC(ctx)) {
+       if (IS_H264_DEC(ctx) || IS_H264_MVC_DEC(ctx) || IS_HEVC_DEC(ctx) || 
IS_AV1_DEC(ctx)) {
                if (ctx->mv_buffer_allocated && buf_size &&
                    buf_size > ctx->mv_buf.dma_buf->size) {
                        mfc_info("[MEMINFO] Not enough MV buf size %d alloc 
size %zu\n",
diff --git a/drivers/media/platform/samsung/exynos-mfc/mfc_core_reg_api.h 
b/drivers/media/platform/samsung/exynos-mfc/mfc_core_reg_api.h
index e7c28b2f2b5d..08f74bd56f3f 100644
--- a/drivers/media/platform/samsung/exynos-mfc/mfc_core_reg_api.h
+++ b/drivers/media/platform/samsung/exynos-mfc/mfc_core_reg_api.h
@@ -89,12 +89,15 @@
                                                >> 
MFC_REG_D_H264_INFO_MBAFF_FRAME_FLAG_SHIFT)\
                                                & 
MFC_REG_D_H264_INFO_MBAFF_FRAME_FLAG_MASK)
 
+#define mfc_core_get_aspect_ratio()    
MFC_CORE_READL(MFC_REG_D_DISPLAY_ASPECT_RATIO)
 #define mfc_core_get_img_width()               
MFC_CORE_READL(MFC_REG_D_DISPLAY_FRAME_WIDTH)
 #define mfc_core_get_img_height()      
MFC_CORE_READL(MFC_REG_D_DISPLAY_FRAME_HEIGHT)
 #define mfc_core_get_disp_y_addr()     
MFC_CORE_DMA_READL(MFC_REG_D_DISPLAY_LUMA_ADDR)
 #define mfc_core_get_dec_y_addr()      
MFC_CORE_DMA_READL(MFC_REG_D_DECODED_LUMA_ADDR)
 #define mfc_core_get_crc_luma()                
MFC_CORE_READL(MFC_REG_D_DISPLAY_FIRST_PLANE_CRC)
 #define mfc_core_get_crc_chroma()      
MFC_CORE_READL(MFC_REG_D_DISPLAY_SECOND_PLANE_CRC)
+#define mfc_core_get_crc_luma_2bit()   
MFC_CORE_READL(MFC_REG_D_DISPLAY_FIRST_PLANE_2BIT_CRC)
+#define mfc_core_get_crc_chroma_2bit() 
MFC_CORE_READL(MFC_REG_D_DISPLAY_SECOND_PLANE_2BIT_CRC)
 
 /* kind of interrupt */
 #define mfc_core_get_int_err()         MFC_CORE_READL(MFC_REG_ERROR_CODE)
@@ -104,10 +107,13 @@
 #define mfc_core_get_dpb_count()               
MFC_CORE_READL(MFC_REG_D_MIN_NUM_DPB)
 #define mfc_core_get_min_dpb_size(x)           \
        MFC_CORE_READL(MFC_REG_D_MIN_FIRST_PLANE_DPB_SIZE + ((x) * 4))
+#define mfc_core_get_min_dpb_size_2bit(x)      \
+       MFC_CORE_READL(MFC_REG_D_MIN_FIRST_PLANE_2BIT_DPB_SIZE + ((x) * 4))
 #define mfc_core_get_scratch_size()            
MFC_CORE_READL(MFC_REG_D_MIN_SCRATCH_BUFFER_SIZE)
 #define mfc_core_get_stride_size(x)            \
        MFC_CORE_READL(MFC_REG_D_FIRST_PLANE_DPB_STRIDE_SIZE + ((x) * 4))
-
+#define mfc_core_get_stride_size_2bit(x)       \
+       MFC_CORE_READL(MFC_REG_D_FIRST_PLANE_2BIT_DPB_STRIDE_SIZE + ((x) * 4))
 #define mfc_core_get_mv_count()                        
MFC_CORE_READL(MFC_REG_D_MIN_NUM_MV)
 #define mfc_core_get_inst_no()                 
MFC_CORE_READL(MFC_REG_RET_INSTANCE_ID)
 #define mfc_core_get_sei_avail()               
MFC_CORE_READL(MFC_REG_D_SEI_AVAIL)
@@ -133,14 +139,27 @@
 #define mfc_core_get_sei_avail_mastering_display()     
((MFC_CORE_READL(MFC_REG_D_SEI_AVAIL)   \
                                                >> 
MFC_REG_D_SEI_AVAIL_MASTERING_DISPLAY_SHIFT) \
                                                & 
MFC_REG_D_SEI_AVAIL_MASTERING_DISPLAY_MASK)
-
+#define mfc_core_get_sei_avail_st_2094_40()            
((MFC_CORE_READL(MFC_REG_D_SEI_AVAIL)   \
+                                               >> 
MFC_REG_D_SEI_AVAIL_ST_2094_40_SHIFT)        \
+                                               & 
MFC_REG_D_SEI_AVAIL_ST_2094_40_MASK)
+#define mfc_core_get_sei_nal_meta_status()     
((MFC_CORE_READL(MFC_REG_METADATA_STATUS)       \
+                                               >> 
MFC_REG_SEI_NAL_STATUS_SHIFT)                \
+                                               & MFC_REG_SEI_NAL_STATUS_MASK)
 #define mfc_core_get_video_signal_type()       
((MFC_CORE_READL(MFC_REG_D_VIDEO_SIGNAL_TYPE)   \
                                                >> 
MFC_REG_D_VIDEO_SIGNAL_TYPE_FLAG_SHIFT)      \
                                                & 
MFC_REG_D_VIDEO_SIGNAL_TYPE_FLAG_MASK)
 #define mfc_core_get_colour_description()      
((MFC_CORE_READL(MFC_REG_D_VIDEO_SIGNAL_TYPE)   \
                                                >> 
MFC_REG_D_COLOUR_DESCRIPTION_FLAG_SHIFT)     \
                                                & 
MFC_REG_D_COLOUR_DESCRIPTION_FLAG_MASK)
-
+#define mfc_core_get_primaries()               
((MFC_CORE_READL(MFC_REG_D_VIDEO_SIGNAL_TYPE)   \
+                                               >> 
MFC_REG_D_COLOUR_PRIMARIES_SHIFT)            \
+                                               & 
MFC_REG_D_COLOUR_PRIMARIES_MASK)
+#define mfc_core_get_transfer()                        
((MFC_CORE_READL(MFC_REG_D_VIDEO_SIGNAL_TYPE)   \
+                                               >> 
MFC_REG_D_TRANSFER_CHARACTERISTICS_SHIFT)    \
+                                               & 
MFC_REG_D_TRANSFER_CHARACTERISTICS_MASK)
+#define mfc_core_get_matrix_coeff()            
((MFC_CORE_READL(MFC_REG_D_VIDEO_SIGNAL_TYPE)   \
+                                               >> 
MFC_REG_D_MATRIX_COEFFICIENTS_SHIFT)         \
+                                               & 
MFC_REG_D_MATRIX_COEFFICIENTS_MASK)
 #define mfc_core_get_black_bar_pos_x()         
((MFC_CORE_READL(MFC_REG_D_BLACK_BAR_START_POS) \
                                                >> 
MFC_REG_D_BLACK_BAR_START_X_SHIFT)           \
                                                & 
MFC_REG_D_BLACK_BAR_START_X_MASK)
@@ -160,12 +179,25 @@
                                                & 
MFC_REG_D_MVC_VIEW_ID_DEC_MASK)
 #define mfc_core_get_mvc_view_id_disp_order()  
(MFC_CORE_READL(MFC_REG_D_MVC_VIEW_ID)          \
                                                & 
MFC_REG_D_MVC_VIEW_ID_DISP_MASK)
+#define mfc_core_get_mvc_left_view_id()                
((MFC_CORE_READL(MFC_REG_D_MVC_VIEW_ID)         \
+                                               >> 
MFC_REG_D_MVC_LEFT_VIEW_ID_SHIFT)    \
+                                               & 
MFC_REG_D_MVC_LEFT_VIEW_ID_MASK)
 #define mfc_core_get_mvc_right_view_id()       
((MFC_CORE_READL(MFC_REG_D_MVC_VIEW_ID)         \
                                                >> 
MFC_REG_D_MVC_RIGHT_VIEW_ID_SHIFT)   \
                                                & 
MFC_REG_D_MVC_RIGHT_VIEW_ID_MASK)
 #define mfc_core_get_profile()         
(MFC_CORE_READL(MFC_REG_D_DECODED_PICTURE_PROFILE)      \
                                        & MFC_REG_D_DECODED_PIC_PROFILE_MASK)
-
+#define mfc_core_get_level()           
((MFC_CORE_READL(MFC_REG_D_DECODED_PICTURE_PROFILE)     \
+                                               >> MFC_REG_D_PIC_LEVEL_SHIFT)   
\
+                                               & MFC_REG_D_PIC_LEVEL_MASK)
+#define mfc_core_get_luma_bit_depth_minus8()   ((MFC_CORE_READL        \
+                                               
(MFC_REG_D_DECODED_PICTURE_PROFILE)     \
+                                               >> 
MFC_REG_D_BIT_DEPTH_LUMA_MINUS8_SHIFT)       \
+                                               & 
MFC_REG_D_BIT_DEPTH_LUMA_MINUS8_MASK)
+#define mfc_core_get_chroma_bit_depth_minus8() ((MFC_CORE_READL        \
+                                               
(MFC_REG_D_DECODED_PICTURE_PROFILE)     \
+                                               >> 
MFC_REG_D_BIT_DEPTH_CHROMA_MINUS8_SHIFT)     \
+                                               & 
MFC_REG_D_BIT_DEPTH_CHROMA_MINUS8_MASK)
 #define mfc_core_get_display_delay()                           \
        ((MFC_CORE_READL(MFC_REG_D_DECODED_PICTURE_PROFILE)     \
        >> MFC_REG_D_DISPLAY_DELAY_SHIFT)               \
@@ -177,10 +209,34 @@
 #define mfc_core_get_dec_used_flag()           (((unsigned 
long)(MFC_CORE_READL                \
                                                
(MFC_REG_D_USED_DPB_FLAG_UPPER)) << 32) |       \
                                                
MFC_CORE_READL(MFC_REG_D_USED_DPB_FLAG_LOWER))
-
+#define mfc_core_get_chroma_format()           
(MFC_CORE_READL(MFC_REG_D_CHROMA_FORMAT)        \
+                                               & MFC_REG_D_CHROMA_FORMAT_MASK)
+#define mfc_core_get_color_range()             
((MFC_CORE_READL(MFC_REG_D_CHROMA_FORMAT)       \
+                                               >> MFC_REG_D_COLOR_RANGE_SHIFT) 
\
+                                               & MFC_REG_D_COLOR_RANGE_MASK)
+#define mfc_core_get_color_space()             
((MFC_CORE_READL(MFC_REG_D_CHROMA_FORMAT)       \
+                                               >> MFC_REG_D_COLOR_SPACE_SHIFT) 
\
+                                               & MFC_REG_D_COLOR_SPACE_MASK)
 #define mfc_core_get_num_of_tile()             
((MFC_CORE_READL(MFC_REG_D_DECODED_STATUS)      \
                                                >> 
MFC_REG_DEC_STATUS_NUM_OF_TILE_SHIFT)        \
                                                & 
MFC_REG_DEC_STATUS_NUM_OF_TILE_MASK)
+#define mfc_core_get_lcu_size()                        
(MFC_CORE_READL(MFC_REG_D_HEVC_INFO)            \
+                                               & 
MFC_REG_D_HEVC_INFO_LCU_SIZE_MASK)
+#define mfc_core_get_disp_res_change()         
((MFC_CORE_READL(MFC_REG_D_VP9_INFO)    \
+                                               >> 
MFC_REG_D_VP9_INFO_DISP_RES_SHIFT)   \
+                                               & 
MFC_REG_D_VP9_INFO_DISP_RES_MASK)
+#define mfc_core_get_disp_res_change_av1()     
((MFC_CORE_READL(MFC_REG_D_AV1_INFO)    \
+                                               >> 
MFC_REG_D_AV1_INFO_DISP_RES_SHIFT)   \
+                                               & 
MFC_REG_D_AV1_INFO_DISP_RES_MASK)
+#define mfc_core_get_showable_frame()          
((MFC_CORE_READL(MFC_REG_D_AV1_INFO)            \
+                                               >> 
MFC_REG_D_AV1_INFO_SHOWABLE_FRAME_SHIFT)     \
+                                               & 
MFC_REG_D_AV1_INFO_SHOWABLE_FRAME_MASK)
+#define mfc_core_get_multiple_show_frame()     
((MFC_CORE_READL(MFC_REG_D_AV1_INFO)            \
+                                               >> 
MFC_REG_D_AV1_INFO_MULTIPLE_SHOW_SHIFT)      \
+                                               & 
MFC_REG_D_AV1_INFO_MULTIPLE_SHOW_MASK)
+#define mfc_core_get_hevc_pic_output_flag()    
((MFC_CORE_READL(MFC_REG_D_HEVC_INFO)           \
+                                               >> 
MFC_REG_D_HEVC_INFO_PIC_OUTPUT_FLAG_SHIFT)   \
+                                               & 
MFC_REG_D_HEVC_INFO_PIC_OUTPUT_FLAG_MASK)
 
 static inline void mfc_core_dec_get_crop_info(struct mfc_core *core,
                                              struct mfc_ctx *ctx)
@@ -201,6 +257,15 @@ static inline void mfc_core_dec_get_crop_info(struct 
mfc_core *core,
        dec->cr_bot = bottom;
 }
 
+static inline void mfc_core_clear_roi_enable(struct mfc_core *core)
+{
+       unsigned int reg = 0;
+
+       reg = MFC_CORE_READL(MFC_REG_E_RC_ROI_CTRL);
+       reg &= ~(0x1);
+       MFC_CORE_WRITEL(reg, MFC_REG_E_RC_ROI_CTRL);
+}
+
 static inline void mfc_core_update_tag(struct mfc_core *core, struct mfc_ctx 
*ctx,
                                       int tag)
 {
diff --git a/drivers/media/platform/samsung/exynos-mfc/mfc_core_run.c 
b/drivers/media/platform/samsung/exynos-mfc/mfc_core_run.c
index 118108f910e2..127d19c4d1cb 100644
--- a/drivers/media/platform/samsung/exynos-mfc/mfc_core_run.c
+++ b/drivers/media/platform/samsung/exynos-mfc/mfc_core_run.c
@@ -369,6 +369,10 @@ int mfc_core_run_dec_frame(struct mfc_core *core, struct 
mfc_ctx *ctx)
        last_frame = __mfc_check_last_frame(core_ctx, src_mb);
        ret = mfc_core_cmd_dec_one_frame(core, ctx, last_frame, src_index);
 
+       if (dec->consumed && IS_MULTI_MODE(ctx) && !CODEC_MULTIFRAME(ctx)) {
+               mfc_debug(2, "[STREAM][2CORE] clear consumed for next core\n");
+               dec->consumed = 0;
+       }
        return ret;
 }
 
diff --git a/drivers/media/platform/samsung/exynos-mfc/mfc_dec_vb2.c 
b/drivers/media/platform/samsung/exynos-mfc/mfc_dec_vb2.c
index 3097a6c0bf14..626c8db5f93b 100644
--- a/drivers/media/platform/samsung/exynos-mfc/mfc_dec_vb2.c
+++ b/drivers/media/platform/samsung/exynos-mfc/mfc_dec_vb2.c
@@ -9,6 +9,7 @@
  * Himanshu Dewangan, <[email protected]>
  */
 
+#include "mfc_dec_v4l2.h"
 #include "mfc_dec_vb2.h"
 
 #include "mfc_rm.h"
-- 
2.34.1

Reply via email to