Re: [PATCH v2 2/2] [media] s5p-mfc: update MFC v4l2 driver to support MFC6.x

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

On Fri, Jul 6, 2012 at 11:00 PM, Arun Kumar K <arun.kk@xxxxxxxxxxx> wrote:
> From: Jeongtae Park <jtp.park@xxxxxxxxxxx>
>
> Multi Format Codec 6.x is a hardware video coding acceleration
> module fount in new Exynos5 SoC series.
> It is capable of handling a range of video codecs and this driver
> provides a V4L2 interface for video decoding and encoding.
>
> Signed-off-by: Jeongtae Park <jtp.park@xxxxxxxxxxx>
> Singed-off-by: Janghyuck Kim <janghyuck.kim@xxxxxxxxxxx>
> Singed-off-by: Jaeryul Oh <jaeryul.oh@xxxxxxxxxxx>
> Signed-off-by: Naveen Krishna Chatradhi <ch.naveen@xxxxxxxxxxx>
> Signed-off-by: Arun Kumar K <arun.kk@xxxxxxxxxxx>
> Cc: Marek Szyprowski <m.szyprowski@xxxxxxxxxxx>
> Cc: Kamil Debski <k.debski@xxxxxxxxxxx>
> ---
>  drivers/media/video/Kconfig                  |   16 +-
>  drivers/media/video/s5p-mfc/Makefile         |    7 +-
>  drivers/media/video/s5p-mfc/regs-mfc-v6.h    |  676 ++++++++++
>  drivers/media/video/s5p-mfc/regs-mfc.h       |   29 +
>  drivers/media/video/s5p-mfc/s5p_mfc.c        |  163 ++-
>  drivers/media/video/s5p-mfc/s5p_mfc_cmd.c    |    6 +-
>  drivers/media/video/s5p-mfc/s5p_mfc_cmd.h    |    3 +
>  drivers/media/video/s5p-mfc/s5p_mfc_cmd_v6.c |   96 ++
>  drivers/media/video/s5p-mfc/s5p_mfc_common.h |  123 ++-
>  drivers/media/video/s5p-mfc/s5p_mfc_ctrl.c   |  160 ++-
>  drivers/media/video/s5p-mfc/s5p_mfc_ctrl.h   |    1 +
>  drivers/media/video/s5p-mfc/s5p_mfc_dec.c    |  210 +++-
>  drivers/media/video/s5p-mfc/s5p_mfc_dec.h    |    1 +
>  drivers/media/video/s5p-mfc/s5p_mfc_enc.c    |  191 ++--
>  drivers/media/video/s5p-mfc/s5p_mfc_enc.h    |    1 +
>  drivers/media/video/s5p-mfc/s5p_mfc_intr.c   |    1 -
>  drivers/media/video/s5p-mfc/s5p_mfc_opr.c    |  278 +++--
>  drivers/media/video/s5p-mfc/s5p_mfc_opr.h    |   25 +-
>  drivers/media/video/s5p-mfc/s5p_mfc_opr_v6.c | 1697 ++++++++++++++++++++++++++
>  drivers/media/video/s5p-mfc/s5p_mfc_opr_v6.h |  140 +++
>  drivers/media/video/s5p-mfc/s5p_mfc_pm.c     |    6 +-
>  drivers/media/video/s5p-mfc/s5p_mfc_shm.c    |   28 +-
>  drivers/media/video/s5p-mfc/s5p_mfc_shm.h    |   13 +-
>  drivers/media/video/v4l2-ctrls.c             |    1 -
>  24 files changed, 3476 insertions(+), 396 deletions(-)

Doesn't it too big for one patch? Can you split it into several patches?

>  create mode 100644 drivers/media/video/s5p-mfc/regs-mfc-v6.h
>  create mode 100644 drivers/media/video/s5p-mfc/s5p_mfc_cmd_v6.c
>  create mode 100644 drivers/media/video/s5p-mfc/s5p_mfc_opr_v6.c
>  create mode 100644 drivers/media/video/s5p-mfc/s5p_mfc_opr_v6.h
>
> diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
> index 99937c9..0d7fe77 100644
> --- a/drivers/media/video/Kconfig
> +++ b/drivers/media/video/Kconfig
> @@ -1198,13 +1198,27 @@ config VIDEO_SAMSUNG_S5P_JPEG
>           This is a v4l2 driver for Samsung S5P and EXYNOS4 JPEG codec
>
>  config VIDEO_SAMSUNG_S5P_MFC
> +       bool
> +
> +config VIDEO_SAMSUNG_S5P_MFC_V5
>         tristate "Samsung S5P MFC 5.1 Video Codec"
> -       depends on VIDEO_DEV && VIDEO_V4L2 && PLAT_S5P
> +       depends on VIDEO_DEV && VIDEO_V4L2 && ARCH_EXYNOS4
> +       select VIDEO_SAMSUNG_S5P_MFC
>         select VIDEOBUF2_DMA_CONTIG
>         default n
>         help
>             MFC 5.1 driver for V4L2.
>
> +config VIDEO_SAMSUNG_S5P_MFC_V6

Yes, I know it's exynos5 series features. however, it's not good idea
to add new config.
It already handled platform device with proper name.
e.g., s5p-mfc-v5, s5p-mfc-v6 and handle it with platform data.

> +       tristate "Samsung S5P MFC 6.x Video Codec"
> +       depends on VIDEO_DEV && VIDEO_V4L2 && ARCH_EXYNOS5
> +       select VIDEO_SAMSUNG_S5P_MFC
> +       select VIDEOBUF2_DMA_CONTIG
> +       select DMA_SHARED_BUFFER
> +       default n
> +       help
> +           MFC 6.x driver for V4L2.
> +
>  config VIDEO_MX2_EMMAPRP
>         tristate "MX2 eMMa-PrP support"
>         depends on VIDEO_DEV && VIDEO_V4L2 && SOC_IMX27
> diff --git a/drivers/media/video/s5p-mfc/Makefile b/drivers/media/video/s5p-mfc/Makefile
> index d066340..0308d74 100644
> --- a/drivers/media/video/s5p-mfc/Makefile
> +++ b/drivers/media/video/s5p-mfc/Makefile
> @@ -1,5 +1,6 @@
>  obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MFC) := s5p-mfc.o
> -s5p-mfc-y += s5p_mfc.o s5p_mfc_intr.o s5p_mfc_opr.o
> +s5p-mfc-y += s5p_mfc.o s5p_mfc_intr.o
>  s5p-mfc-y += s5p_mfc_dec.o s5p_mfc_enc.o
> -s5p-mfc-y += s5p_mfc_ctrl.o s5p_mfc_cmd.o
> -s5p-mfc-y += s5p_mfc_pm.o s5p_mfc_shm.o
> +s5p-mfc-y += s5p_mfc_ctrl.o s5p_mfc_pm.o
> +obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MFC_V5) += s5p_mfc_opr.o s5p_mfc_cmd.o s5p_mfc_shm.o
> +obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MFC_V6) += s5p_mfc_opr_v6.o s5p_mfc_cmd_v6.o
> diff --git a/drivers/media/video/s5p-mfc/regs-mfc-v6.h b/drivers/media/video/s5p-mfc/regs-mfc-v6.h
> new file mode 100644
> index 0000000..f22a159
> --- /dev/null
> +++ b/drivers/media/video/s5p-mfc/regs-mfc-v6.h
> @@ -0,0 +1,676 @@
> +/*
> + * Register definition file for Samsung MFC V6.x Interface (FIMV) driver
> + *
> + * Copyright (c) 2012 Samsung Electronics
> + *             http://www.samsung.com/
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#ifndef _REGS_FIMV_V6_H
> +#define _REGS_FIMV_V6_H
> +
> +#define S5P_FIMV_REG_SIZE      (S5P_FIMV_END_ADDR - S5P_FIMV_START_ADDR)
> +#define S5P_FIMV_REG_COUNT     ((S5P_FIMV_END_ADDR - S5P_FIMV_START_ADDR) / 4)
> +
> +/* Number of bits that the buffer address should be shifted for particular
> + * MFC buffers.  */
> +#define S5P_FIMV_MEM_OFFSET            0
> +
> +#define S5P_FIMV_START_ADDR            0x0000
> +#define S5P_FIMV_END_ADDR              0xfd80
> +
> +#define S5P_FIMV_REG_CLEAR_BEGIN       0xf000
> +#define S5P_FIMV_REG_CLEAR_COUNT       1024
> +
> +/* Codec Common Registers */
> +#define S5P_FIMV_RISC_ON                       0x0000
> +#define S5P_FIMV_RISC2HOST_INT                 0x003C
> +#define S5P_FIMV_HOST2RISC_INT                 0x0044
> +#define S5P_FIMV_RISC_BASE_ADDRESS             0x0054
> +
> +#define S5P_FIMV_MFC_RESET                     0x1070
> +
> +#define S5P_FIMV_HOST2RISC_CMD                 0x1100
> +#define S5P_FIMV_H2R_CMD_EMPTY                 0
> +#define S5P_FIMV_H2R_CMD_SYS_INIT              1
> +#define S5P_FIMV_H2R_CMD_OPEN_INSTANCE         2
> +#define S5P_FIMV_CH_SEQ_HEADER                 3
> +#define S5P_FIMV_CH_INIT_BUFS                  4
> +#define S5P_FIMV_CH_FRAME_START                        5
> +#define S5P_FIMV_H2R_CMD_CLOSE_INSTANCE                6
> +#define S5P_FIMV_H2R_CMD_SLEEP                 7
> +#define S5P_FIMV_H2R_CMD_WAKEUP                        8
> +#define S5P_FIMV_CH_LAST_FRAME                 9
> +#define S5P_FIMV_H2R_CMD_FLUSH                 10
> +/* RMVME: REALLOC used? */
> +#define S5P_FIMV_CH_FRAME_START_REALLOC                5
> +
> +#define S5P_FIMV_RISC2HOST_CMD                 0x1104
> +#define S5P_FIMV_R2H_CMD_EMPTY                 0
> +#define S5P_FIMV_R2H_CMD_SYS_INIT_RET          1
> +#define S5P_FIMV_R2H_CMD_OPEN_INSTANCE_RET     2
> +#define S5P_FIMV_R2H_CMD_SEQ_DONE_RET          3
> +#define S5P_FIMV_R2H_CMD_INIT_BUFFERS_RET      4
> +
> +#define S5P_FIMV_R2H_CMD_CLOSE_INSTANCE_RET    6
> +#define S5P_FIMV_R2H_CMD_SLEEP_RET             7
> +#define S5P_FIMV_R2H_CMD_WAKEUP_RET            8
> +#define S5P_FIMV_R2H_CMD_COMPLETE_SEQ_RET      9
> +#define S5P_FIMV_R2H_CMD_DPB_FLUSH_RET         10
> +#define S5P_FIMV_R2H_CMD_NAL_ABORT_RET         11
> +#define S5P_FIMV_R2H_CMD_FW_STATUS_RET         12
> +#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_FUL_RET    16
> +#define S5P_FIMV_R2H_CMD_ERR_RET               32
> +
> +#define S5P_FIMV_FW_VERSION                    0xF000
> +
> +#define S5P_FIMV_INSTANCE_ID                   0xF008
> +#define S5P_FIMV_CODEC_TYPE                    0xF00C
> +#define S5P_FIMV_CONTEXT_MEM_ADDR              0xF014
> +#define S5P_FIMV_CONTEXT_MEM_SIZE              0xF018
> +#define S5P_FIMV_PIXEL_FORMAT                  0xF020
> +
> +#define S5P_FIMV_METADATA_ENABLE               0xF024
> +#define S5P_FIMV_DBG_BUFFER_ADDR               0xF030
> +#define S5P_FIMV_DBG_BUFFER_SIZE               0xF034
> +#define S5P_FIMV_RET_INSTANCE_ID               0xF070
> +
> +#define S5P_FIMV_ERROR_CODE                    0xF074
> +#define S5P_FIMV_ERR_WARNINGS_START            160
> +#define S5P_FIMV_ERR_DEC_MASK                  0xFFFF
> +#define S5P_FIMV_ERR_DEC_SHIFT                 0
> +#define S5P_FIMV_ERR_DSPL_MASK                 0xFFFF0000
> +#define S5P_FIMV_ERR_DSPL_SHIFT                        16
> +
> +#define S5P_FIMV_DBG_BUFFER_OUTPUT_SIZE                0xF078
> +#define S5P_FIMV_METADATA_STATUS               0xF07C
> +#define S5P_FIMV_METADATA_ADDR_MB_INFO         0xF080
> +#define S5P_FIMV_METADATA_SIZE_MB_INFO         0xF084
> +
> +/* Decoder Registers */
> +#define S5P_FIMV_D_CRC_CTRL                    0xF0B0
> +#define S5P_FIMV_D_DEC_OPTIONS                 0xF0B4
> +#define S5P_FIMV_D_OPT_FMO_ASO_CTRL_MASK       4
> +#define S5P_FIMV_D_OPT_DDELAY_EN_SHIFT         3
> +#define S5P_FIMV_D_OPT_LF_CTRL_SHIFT           1
> +#define S5P_FIMV_D_OPT_LF_CTRL_MASK            0x3
> +#define S5P_FIMV_D_OPT_TILE_MODE_SHIFT         0
> +
> +#define S5P_FIMV_D_DISPLAY_DELAY               0xF0B8
> +
> +#define S5P_FIMV_D_SET_FRAME_WIDTH             0xF0BC
> +#define S5P_FIMV_D_SET_FRAME_HEIGHT            0xF0C0
> +
> +#define S5P_FIMV_D_SEI_ENABLE                  0xF0C4
> +
> +/* Buffer setting registers */
> +#define S5P_FIMV_D_MIN_NUM_DPB                 0xF0F0
> +#define S5P_FIMV_D_MIN_LUMA_DPB_SIZE           0xF0F4
> +#define S5P_FIMV_D_MIN_CHROMA_DPB_SIZE         0xF0F8
> +#define S5P_FIMV_D_MVC_NUM_VIEWS               0xF0FC
> +#define S5P_FIMV_D_NUM_DPB                     0xF130
> +#define S5P_FIMV_D_LUMA_DPB_SIZE               0xF134
> +#define S5P_FIMV_D_CHROMA_DPB_SIZE             0xF138
> +#define S5P_FIMV_D_MV_BUFFER_SIZE              0xF13C
> +
> +#define S5P_FIMV_D_LUMA_DPB                    0xF140
> +#define S5P_FIMV_D_CHROMA_DPB                  0xF240
> +#define S5P_FIMV_D_MV_BUFFER                   0xF340
> +
> +#define S5P_FIMV_D_SCRATCH_BUFFER_ADDR         0xF440
> +#define S5P_FIMV_D_SCRATCH_BUFFER_SIZE         0xF444
> +#define S5P_FIMV_D_METADATA_BUFFER_ADDR                0xF448
> +#define S5P_FIMV_D_METADATA_BUFFER_SIZE                0xF44C
> +#define S5P_FIMV_D_CPB_BUFFER_ADDR             0xF4B0
> +#define S5P_FIMV_D_CPB_BUFFER_SIZE             0xF4B4
> +
> +#define S5P_FIMV_D_AVAILABLE_DPB_FLAG_UPPER    0xF4B8
> +#define S5P_FIMV_D_AVAILABLE_DPB_FLAG_LOWER    0xF4BC
> +#define S5P_FIMV_D_CPB_BUFFER_OFFSET           0xF4C0
> +#define S5P_FIMV_D_SLICE_IF_ENABLE             0xF4C4
> +#define S5P_FIMV_D_PICTURE_TAG                 0xF4C8
> +#define S5P_FIMV_D_STREAM_DATA_SIZE            0xF4D0
> +
> +/* Display information register */
> +#define S5P_FIMV_D_DISPLAY_FRAME_WIDTH         0xF500
> +#define S5P_FIMV_D_DISPLAY_FRAME_HEIGHT                0xF504
> +
> +/* Display status */
> +#define S5P_FIMV_D_DISPLAY_STATUS              0xF508
> +#define S5P_FIMV_DEC_STATUS_DECODING_ONLY              0
> +#define S5P_FIMV_DEC_STATUS_DECODING_DISPLAY           1
> +#define S5P_FIMV_DEC_STATUS_DISPLAY_ONLY               2
> +#define S5P_FIMV_DEC_STATUS_DECODING_EMPTY             3
> +#define S5P_FIMV_DEC_STATUS_DECODING_STATUS_MASK       7
> +#define S5P_FIMV_DEC_STATUS_PROGRESSIVE                        (0<<3)
> +#define S5P_FIMV_DEC_STATUS_INTERLACE                  (1<<3)
> +#define S5P_FIMV_DEC_STATUS_INTERLACE_MASK             (1<<3)
> +#define S5P_FIMV_DEC_STATUS_RESOLUTION_MASK            (3<<4)
> +#define S5P_FIMV_DEC_STATUS_RESOLUTION_INC             (1<<4)
> +#define S5P_FIMV_DEC_STATUS_RESOLUTION_DEC             (2<<4)
> +#define S5P_FIMV_DEC_STATUS_RESOLUTION_SHIFT           4
> +#define S5P_FIMV_DEC_STATUS_CRC_GENERATED              (1<<5)
> +#define S5P_FIMV_DEC_STATUS_CRC_NOT_GENERATED          (0<<5)
> +#define S5P_FIMV_DEC_STATUS_CRC_MASK                   (1<<5)
> +
> +#define S5P_FIMV_D_DISPLAY_LUMA_ADDR           0xF50C
> +#define S5P_FIMV_D_DISPLAY_CHROMA_ADDR         0xF510
> +
> +#define S5P_FIMV_D_DISPLAY_FRAME_TYPE          0xF514
> +#define S5P_FIMV_DECODE_FRAME_SKIPPED          0
> +#define S5P_FIMV_DECODE_FRAME_I_FRAME          1
> +#define S5P_FIMV_DECODE_FRAME_P_FRAME          2
> +#define S5P_FIMV_DECODE_FRAME_B_FRAME          3
> +#define S5P_FIMV_DECODE_FRAME_OTHER_FRAME      4
> +#define S5P_FIMV_SHARED_CROP_INFO_H            0x0020
> +#define S5P_FIMV_SHARED_CROP_LEFT_MASK         0xFFFF
> +#define S5P_FIMV_SHARED_CROP_LEFT_SHIFT                0
> +#define S5P_FIMV_SHARED_CROP_RIGHT_MASK                0xFFFF0000
> +#define S5P_FIMV_SHARED_CROP_RIGHT_SHIFT       16
> +#define S5P_FIMV_SHARED_CROP_INFO_V            0x0024
> +#define S5P_FIMV_SHARED_CROP_TOP_MASK          0xFFFF
> +#define S5P_FIMV_SHARED_CROP_TOP_SHIFT         0
> +#define S5P_FIMV_SHARED_CROP_BOTTOM_MASK       0xFFFF0000
> +#define S5P_FIMV_SHARED_CROP_BOTTOM_SHIFT      16
> +
> +#define S5P_FIMV_D_DISPLAY_CROP_INFO1          0xF518
> +#define S5P_FIMV_D_DISPLAY_CROP_INFO2          0xF51C
> +#define S5P_FIMV_D_DISPLAY_PICTURE_PROFILE     0xF520
> +#define S5P_FIMV_D_DISPLAY_LUMA_CRC_TOP                0xF524
> +#define S5P_FIMV_D_DISPLAY_CHROMA_CRC_TOP      0xF528
> +#define S5P_FIMV_D_DISPLAY_LUMA_CRC_BOT                0xF52C
> +#define S5P_FIMV_D_DISPLAY_CHROMA_CRC_BOT      0xF530
> +#define S5P_FIMV_D_DISPLAY_ASPECT_RATIO                0xF534
> +#define S5P_FIMV_D_DISPLAY_EXTENDED_AR         0xF538
> +
> +/* Decoded picture information register */
> +#define S5P_FIMV_D_DECODED_FRAME_WIDTH         0xF53C
> +#define S5P_FIMV_D_DECODED_FRAME_HEIGHT                0xF540
> +#define S5P_FIMV_D_DECODED_STATUS              0xF544
> +#define S5P_FIMV_DEC_CRC_GEN_MASK              0x1
> +#define S5P_FIMV_DEC_CRC_GEN_SHIFT             6
> +
> +#define S5P_FIMV_D_DECODED_LUMA_ADDR           0xF548
> +#define S5P_FIMV_D_DECODED_CHROMA_ADDR         0xF54C
> +
> +#define S5P_FIMV_D_DECODED_FRAME_TYPE          0xF550
> +#define S5P_FIMV_DECODE_FRAME_MASK             7
> +
> +#define S5P_FIMV_D_DECODED_CROP_INFO1          0xF554
> +#define S5P_FIMV_D_DECODED_CROP_INFO2          0xF558
> +#define S5P_FIMV_D_DECODED_PICTURE_PROFILE     0xF55C
> +#define S5P_FIMV_D_DECODED_NAL_SIZE            0xF560
> +#define S5P_FIMV_D_DECODED_LUMA_CRC_TOP                0xF564
> +#define S5P_FIMV_D_DECODED_CHROMA_CRC_TOP      0xF568
> +#define S5P_FIMV_D_DECODED_LUMA_CRC_BOT                0xF56C
> +#define S5P_FIMV_D_DECODED_CHROMA_CRC_BOT      0xF570
> +
> +/* Returned value register for specific setting */
> +#define S5P_FIMV_D_RET_PICTURE_TAG_TOP         0xF574
> +#define S5P_FIMV_D_RET_PICTURE_TAG_BOT         0xF578
> +#define S5P_FIMV_D_RET_PICTURE_TIME_TOP                0xF57C
> +#define S5P_FIMV_D_RET_PICTURE_TIME_BOT                0xF580
> +#define S5P_FIMV_D_CHROMA_FORMAT               0xF588
> +#define S5P_FIMV_D_MPEG4_INFO                  0xF58C
> +#define S5P_FIMV_D_H264_INFO                   0xF590
> +
> +#define S5P_FIMV_D_METADATA_ADDR_CONCEALED_MB  0xF594
> +#define S5P_FIMV_D_METADATA_SIZE_CONCEALED_MB  0xF598
> +#define S5P_FIMV_D_METADATA_ADDR_VC1_PARAM     0xF59C
> +#define S5P_FIMV_D_METADATA_SIZE_VC1_PARAM     0xF5A0
> +#define S5P_FIMV_D_METADATA_ADDR_SEI_NAL       0xF5A4
> +#define S5P_FIMV_D_METADATA_SIZE_SEI_NAL       0xF5A8
> +#define S5P_FIMV_D_METADATA_ADDR_VUI           0xF5AC
> +#define S5P_FIMV_D_METADATA_SIZE_VUI           0xF5B0
> +
> +#define S5P_FIMV_D_MVC_VIEW_ID                 0xF5B4
> +
> +/* SEI related information */
> +#define S5P_FIMV_D_FRAME_PACK_SEI_AVAIL                0xF5F0
> +#define S5P_FIMV_D_FRAME_PACK_ARRGMENT_ID      0xF5F4
> +#define S5P_FIMV_D_FRAME_PACK_SEI_INFO         0xF5F8
> +#define S5P_FIMV_D_FRAME_PACK_GRID_POS         0xF5FC
> +
> +/* Encoder Registers */
> +#define S5P_FIMV_E_FRAME_WIDTH                 0xF770
> +#define S5P_FIMV_E_FRAME_HEIGHT                        0xF774
> +#define S5P_FIMV_E_CROPPED_FRAME_WIDTH         0xF778
> +#define S5P_FIMV_E_CROPPED_FRAME_HEIGHT                0xF77C
> +#define S5P_FIMV_E_FRAME_CROP_OFFSET           0xF780
> +#define S5P_FIMV_E_ENC_OPTIONS                 0xF784
> +#define S5P_FIMV_E_PICTURE_PROFILE             0xF788
> +#define S5P_FIMV_ENC_PROFILE_H264_MAIN                 0
> +#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_MPEG4_SIMPLE              0
> +#define S5P_FIMV_ENC_PROFILE_MPEG4_ADVANCED_SIMPLE     1
> +#define S5P_FIMV_E_FIXED_PICTURE_QP            0xF790
> +
> +#define S5P_FIMV_E_RC_CONFIG                   0xF794
> +#define S5P_FIMV_E_RC_QP_BOUND                 0xF798
> +#define S5P_FIMV_E_RC_RPARAM                   0xF79C
> +#define S5P_FIMV_E_MB_RC_CONFIG                        0xF7A0
> +#define S5P_FIMV_E_PADDING_CTRL                        0xF7A4
> +#define S5P_FIMV_E_MV_HOR_RANGE                        0xF7AC
> +#define S5P_FIMV_E_MV_VER_RANGE                        0xF7B0
> +
> +#define S5P_FIMV_E_VBV_BUFFER_SIZE             0xF84C
> +#define S5P_FIMV_E_VBV_INIT_DELAY              0xF850
> +#define S5P_FIMV_E_NUM_DPB                     0xF890
> +#define S5P_FIMV_E_LUMA_DPB                    0xF8C0
> +#define S5P_FIMV_E_CHROMA_DPB                  0xF904
> +#define S5P_FIMV_E_ME_BUFFER                   0xF948
> +
> +#define S5P_FIMV_E_SCRATCH_BUFFER_ADDR         0xF98C
> +#define S5P_FIMV_E_SCRATCH_BUFFER_SIZE         0xF990
> +#define S5P_FIMV_E_TMV_BUFFER0                 0xF994
> +#define S5P_FIMV_E_TMV_BUFFER1                 0xF998
> +#define S5P_FIMV_E_SOURCE_LUMA_ADDR            0xF9F0
> +#define S5P_FIMV_E_SOURCE_CHROMA_ADDR          0xF9F4
> +#define S5P_FIMV_E_STREAM_BUFFER_ADDR          0xF9F8
> +#define S5P_FIMV_E_STREAM_BUFFER_SIZE          0xF9FC
> +#define S5P_FIMV_E_ROI_BUFFER_ADDR             0xFA00
> +
> +#define S5P_FIMV_E_PARAM_CHANGE                        0xFA04
> +#define S5P_FIMV_E_IR_SIZE                     0xFA08
> +#define S5P_FIMV_E_GOP_CONFIG                  0xFA0C
> +#define S5P_FIMV_E_MSLICE_MODE                 0xFA10
> +#define S5P_FIMV_E_MSLICE_SIZE_MB              0xFA14
> +#define S5P_FIMV_E_MSLICE_SIZE_BITS            0xFA18
> +#define S5P_FIMV_E_FRAME_INSERTION             0xFA1C
> +
> +#define S5P_FIMV_E_RC_FRAME_RATE               0xFA20
> +#define S5P_FIMV_E_RC_BIT_RATE                 0xFA24
> +#define S5P_FIMV_E_RC_QP_OFFSET                        0xFA28
> +#define S5P_FIMV_E_RC_ROI_CTRL                 0xFA2C
> +#define S5P_FIMV_E_PICTURE_TAG                 0xFA30
> +#define S5P_FIMV_E_BIT_COUNT_ENABLE            0xFA34
> +#define S5P_FIMV_E_MAX_BIT_COUNT               0xFA38
> +#define S5P_FIMV_E_MIN_BIT_COUNT               0xFA3C
> +
> +#define S5P_FIMV_E_METADATA_BUFFER_ADDR                0xFA40
> +#define S5P_FIMV_E_METADATA_BUFFER_SIZE                0xFA44
> +#define S5P_FIMV_E_STREAM_SIZE                 0xFA80
> +#define S5P_FIMV_E_SLICE_TYPE                  0xFA84
> +#define S5P_FIMV_ENC_SI_SLICE_TYPE_NON_CODED   0
> +#define S5P_FIMV_ENC_SI_SLICE_TYPE_I           1
> +#define S5P_FIMV_ENC_SI_SLICE_TYPE_P           2
> +#define S5P_FIMV_ENC_SI_SLICE_TYPE_B           3
> +#define S5P_FIMV_ENC_SI_SLICE_TYPE_SKIPPED     4
> +#define S5P_FIMV_ENC_SI_SLICE_TYPE_OTHERS      5
> +#define S5P_FIMV_E_PICTURE_COUNT               0xFA88
> +#define S5P_FIMV_E_RET_PICTURE_TAG             0xFA8C
> +#define S5P_FIMV_E_STREAM_BUFFER_WRITE_POINTER 0xFA90
> +
> +#define S5P_FIMV_E_ENCODED_SOURCE_LUMA_ADDR    0xFA94
> +#define S5P_FIMV_E_ENCODED_SOURCE_CHROMA_ADDR  0xFA98
> +#define S5P_FIMV_E_RECON_LUMA_DPB_ADDR         0xFA9C
> +#define S5P_FIMV_E_RECON_CHROMA_DPB_ADDR       0xFAA0
> +#define S5P_FIMV_E_METADATA_ADDR_ENC_SLICE     0xFAA4
> +#define S5P_FIMV_E_METADATA_SIZE_ENC_SLICE     0xFAA8
> +
> +#define S5P_FIMV_E_MPEG4_OPTIONS               0xFB10
> +#define S5P_FIMV_E_MPEG4_HEC_PERIOD            0xFB14
> +#define S5P_FIMV_E_ASPECT_RATIO                        0xFB50
> +#define S5P_FIMV_E_EXTENDED_SAR                        0xFB54
> +
> +#define S5P_FIMV_E_H264_OPTIONS                        0xFB58
> +#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
> +
> +#define S5P_FIMV_E_H264_FMO_SLICE_GRP_MAP_TYPE                 0xFB68
> +#define S5P_FIMV_E_H264_FMO_NUM_SLICE_GRP_MINUS1               0xFB6C
> +#define S5P_FIMV_E_H264_FMO_SLICE_GRP_CHANGE_DIR               0xFB70
> +#define S5P_FIMV_E_H264_FMO_SLICE_GRP_CHANGE_RATE_MINUS1       0xFB74
> +#define S5P_FIMV_E_H264_FMO_RUN_LENGTH_MINUS1_0        0xFB78
> +#define S5P_FIMV_E_H264_FMO_RUN_LENGTH_MINUS1_1        0xFB7C
> +#define S5P_FIMV_E_H264_FMO_RUN_LENGTH_MINUS1_2        0xFB80
> +#define S5P_FIMV_E_H264_FMO_RUN_LENGTH_MINUS1_3        0xFB84
> +
> +#define S5P_FIMV_E_H264_ASO_SLICE_ORDER_0      0xFB88
> +#define S5P_FIMV_E_H264_ASO_SLICE_ORDER_1      0xFB8C
> +#define S5P_FIMV_E_H264_ASO_SLICE_ORDER_2      0xFB90
> +#define S5P_FIMV_E_H264_ASO_SLICE_ORDER_3      0xFB94
> +#define S5P_FIMV_E_H264_ASO_SLICE_ORDER_4      0xFB98
> +#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_H264_NUM_T_LAYER            0xFBAC
> +
> +#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER0 0xFBB0
> +#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER1 0xFBB4
> +#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER2 0xFBB8
> +#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER3 0xFBBC
> +#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER4 0xFBC0
> +#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER5 0xFBC4
> +#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER6 0xFBC8
> +
> +#define S5P_FIMV_E_H264_FRAME_PACKING_SEI_INFO 0xFC4C
> +#define S5P_FIMV_ENC_FP_ARRANGEMENT_TYPE_SIDE_BY_SIDE  0
> +#define S5P_FIMV_ENC_FP_ARRANGEMENT_TYPE_TOP_BOTTOM    1
> +#define S5P_FIMV_ENC_FP_ARRANGEMENT_TYPE_TEMPORAL      2
> +
> +#define S5P_FIMV_E_MVC_FRAME_QP_VIEW1          0xFD40
> +#define S5P_FIMV_E_MVC_RC_FRAME_RATE_VIEW1     0xFD44
> +#define S5P_FIMV_E_MVC_RC_BIT_RATE_VIEW1       0xFD48
> +#define S5P_FIMV_E_MVC_RC_QBOUND_VIEW1         0xFD4C
> +#define S5P_FIMV_E_MVC_RC_RPARA_VIEW1          0xFD50
> +#define S5P_FIMV_E_MVC_INTER_VIEW_PREDICTION_ON        0xFD80
> +
> +/* Codec numbers  */
> +#define S5P_FIMV_CODEC_NONE            -1
> +
> +
> +#define S5P_FIMV_CODEC_H264_DEC        0
> +#define S5P_FIMV_CODEC_H264_MVC_DEC    1
> +
> +#define S5P_FIMV_CODEC_MPEG4_DEC       3
> +#define S5P_FIMV_CODEC_FIMV1_DEC       4
> +#define S5P_FIMV_CODEC_FIMV2_DEC       5
> +#define S5P_FIMV_CODEC_FIMV3_DEC       6
> +#define S5P_FIMV_CODEC_FIMV4_DEC       7
> +#define S5P_FIMV_CODEC_H263_DEC        8
> +#define S5P_FIMV_CODEC_VC1RCV_DEC      9
> +#define S5P_FIMV_CODEC_VC1_DEC         10
> +/* FIXME: Add 11~12 */
> +#define S5P_FIMV_CODEC_MPEG2_DEC       13
> +#define S5P_FIMV_CODEC_VP8_DEC         14
> +/* FIXME: Add 15~16 */
> +#define S5P_FIMV_CODEC_H264_ENC        20
> +#define S5P_FIMV_CODEC_H264_MVC_ENC    21
> +
> +#define S5P_FIMV_CODEC_MPEG4_ENC       23
> +#define S5P_FIMV_CODEC_H263_ENC        24
> +/***   Definitions for MFCv5 compatibility ***/
> +#define S5P_FIMV_SI_DISPLAY_Y_ADR              S5P_FIMV_D_DISPLAY_LUMA_ADDR
> +#define S5P_FIMV_SI_DISPLAY_C_ADR              S5P_FIMV_D_DISPLAY_CHROMA_ADDR
> +
> +#define S5P_FIMV_CRC_LUMA0                     S5P_FIMV_D_DECODED_LUMA_CRC_TOP
> +#define S5P_FIMV_CRC_CHROMA0                   S5P_FIMV_D_DECODED_CHROMA_CRC_TOP
> +#define S5P_FIMV_CRC_LUMA1                     S5P_FIMV_D_DECODED_LUMA_CRC_BOT
> +#define S5P_FIMV_CRC_CHROMA1                   S5P_FIMV_D_DECODED_CHROMA_CRC_BOT
> +#define S5P_FIMV_CRC_DISP_LUMA0                        S5P_FIMV_D_DISPLAY_LUMA_CRC_TOP
> +#define S5P_FIMV_CRC_DISP_CHROMA0              S5P_FIMV_D_DISPLAY_CHROMA_CRC_TOP
> +
> +#define S5P_FIMV_SI_DECODED_STATUS             S5P_FIMV_D_DECODED_STATUS
> +#define S5P_FIMV_SI_DISPLAY_STATUS             S5P_FIMV_D_DISPLAY_STATUS
> +#define S5P_FIMV_SHARED_SET_FRAME_TAG          S5P_FIMV_D_PICTURE_TAG
> +#define S5P_FIMV_SHARED_GET_FRAME_TAG_TOP      S5P_FIMV_D_RET_PICTURE_TAG_TOP
> +#define S5P_FIMV_CRC_DISP_STATUS               S5P_FIMV_D_DISPLAY_STATUS
> +
> +/* SEI related information */
> +#define S5P_FIMV_FRAME_PACK_SEI_AVAIL          S5P_FIMV_D_FRAME_PACK_SEI_AVAIL
> +#define S5P_FIMV_FRAME_PACK_ARRGMENT_ID                S5P_FIMV_D_FRAME_PACK_ARRGMENT_ID
> +#define S5P_FIMV_FRAME_PACK_SEI_INFO           S5P_FIMV_D_FRAME_PACK_SEI_INFO
> +#define S5P_FIMV_FRAME_PACK_GRID_POS           S5P_FIMV_D_FRAME_PACK_GRID_POS
> +
> +#define S5P_FIMV_SHARED_SET_E_FRAME_TAG                S5P_FIMV_E_PICTURE_TAG
> +#define S5P_FIMV_SHARED_GET_E_FRAME_TAG                S5P_FIMV_E_RET_PICTURE_TAG
> +#define S5P_FIMV_ENCODED_LUMA_ADDR             S5P_FIMV_E_ENCODED_SOURCE_LUMA_ADDR
> +#define S5P_FIMV_ENCODED_CHROMA_ADDR           S5P_FIMV_E_ENCODED_SOURCE_CHROMA_ADDR
> +#define        S5P_FIMV_FRAME_INSERTION                S5P_FIMV_E_FRAME_INSERTION
> +
> +#define S5P_FIMV_PARAM_CHANGE_FLAG             S5P_FIMV_E_PARAM_CHANGE /* flag */
> +#define S5P_FIMV_NEW_I_PERIOD                  S5P_FIMV_E_GOP_CONFIG
> +#define S5P_FIMV_NEW_RC_FRAME_RATE             S5P_FIMV_E_RC_FRAME_RATE
> +#define S5P_FIMV_NEW_RC_BIT_RATE               S5P_FIMV_E_RC_BIT_RATE
> +/*** End of MFCv5 compatibility definitions ***/
> +
> +/***      old definitions     ***/
> +#define S5P_FIMV_SW_RESET              0x0000
> +#define S5P_FIMV_RISC_HOST_INT         0x0008
> +
> +/* Command from HOST to RISC */
> +#define S5P_FIMV_HOST2RISC_ARG1                0x0034
> +#define S5P_FIMV_HOST2RISC_ARG2                0x0038
> +#define S5P_FIMV_HOST2RISC_ARG3                0x003c
> +#define S5P_FIMV_HOST2RISC_ARG4                0x0040
> +
> +/* Command from RISC to HOST */
> +#define S5P_FIMV_RISC2HOST_CMD_MASK    0x1FFFF
> +#define S5P_FIMV_RISC2HOST_ARG1                0x0048
> +#define S5P_FIMV_RISC2HOST_ARG2                0x004c
> +#define S5P_FIMV_RISC2HOST_ARG3                0x0050
> +#define S5P_FIMV_RISC2HOST_ARG4                0x0054
> +
> +#define S5P_FIMV_SYS_MEM_SZ            0x005c
> +#define S5P_FIMV_FW_STATUS             0x0080
> +
> +/* Memory controller register */
> +#define S5P_FIMV_MC_DRAMBASE_ADR_A     0x0508
> +#define S5P_FIMV_MC_DRAMBASE_ADR_B     0x050c
> +#define S5P_FIMV_MC_STATUS             0x0510
> +
> +/* Common register */
> +#define S5P_FIMV_COMMON_BASE_A         0x0600
> +#define S5P_FIMV_COMMON_BASE_B         0x0700
> +
> +/* Decoder */
> +#define S5P_FIMV_DEC_CHROMA_ADR                (S5P_FIMV_COMMON_BASE_A)
> +#define S5P_FIMV_DEC_LUMA_ADR          (S5P_FIMV_COMMON_BASE_B)
> +
> +/* H.264 decoding */
> +#define S5P_FIMV_H264_VERT_NB_MV_ADR   (S5P_FIMV_COMMON_BASE_A + 0x8c) /* vertical neighbor motion vector */
> +#define S5P_FIMV_H264_NB_IP_ADR                (S5P_FIMV_COMMON_BASE_A + 0x90) /* neighbor pixels for intra pred */
> +#define S5P_FIMV_H264_MV_ADR           (S5P_FIMV_COMMON_BASE_B + 0x80) /* H264 motion vector */
> +
> +/* MPEG4 decoding */
> +#define S5P_FIMV_MPEG4_NB_DCAC_ADR     (S5P_FIMV_COMMON_BASE_A + 0x8c) /* neighbor AC/DC coeff. */
> +#define S5P_FIMV_MPEG4_UP_NB_MV_ADR    (S5P_FIMV_COMMON_BASE_A + 0x90) /* upper neighbor motion vector */
> +#define S5P_FIMV_MPEG4_SA_MV_ADR       (S5P_FIMV_COMMON_BASE_A + 0x94) /* subseq. anchor motion vector */
> +#define S5P_FIMV_MPEG4_OT_LINE_ADR     (S5P_FIMV_COMMON_BASE_A + 0x98) /* overlap transform line */
> +#define S5P_FIMV_MPEG4_SP_ADR          (S5P_FIMV_COMMON_BASE_A + 0xa8) /* syntax parser */
> +
> +/* H.263 decoding */
> +#define S5P_FIMV_H263_NB_DCAC_ADR      (S5P_FIMV_COMMON_BASE_A + 0x8c)
> +#define S5P_FIMV_H263_UP_NB_MV_ADR     (S5P_FIMV_COMMON_BASE_A + 0x90)
> +#define S5P_FIMV_H263_SA_MV_ADR                (S5P_FIMV_COMMON_BASE_A + 0x94)
> +#define S5P_FIMV_H263_OT_LINE_ADR      (S5P_FIMV_COMMON_BASE_A + 0x98)
> +
> +/* VC-1 decoding */
> +#define S5P_FIMV_VC1_NB_DCAC_ADR       (S5P_FIMV_COMMON_BASE_A + 0x8c)
> +#define S5P_FIMV_VC1_UP_NB_MV_ADR      (S5P_FIMV_COMMON_BASE_A + 0x90)
> +#define S5P_FIMV_VC1_SA_MV_ADR         (S5P_FIMV_COMMON_BASE_A + 0x94)
> +#define S5P_FIMV_VC1_OT_LINE_ADR       (S5P_FIMV_COMMON_BASE_A + 0x98)
> +#define S5P_FIMV_VC1_BITPLANE3_ADR     (S5P_FIMV_COMMON_BASE_A + 0x9c) /* bitplane3 */
> +#define S5P_FIMV_VC1_BITPLANE2_ADR     (S5P_FIMV_COMMON_BASE_A + 0xa0) /* bitplane2 */
> +#define S5P_FIMV_VC1_BITPLANE1_ADR     (S5P_FIMV_COMMON_BASE_A + 0xa4) /* bitplane1 */
> +
> +/* Encoder */
> +#define S5P_FIMV_ENC_REF0_LUMA_ADR     (S5P_FIMV_COMMON_BASE_A + 0x1c) /* reconstructed luma */
> +#define S5P_FIMV_ENC_REF1_LUMA_ADR     (S5P_FIMV_COMMON_BASE_A + 0x20)
> +#define S5P_FIMV_ENC_REF0_CHROMA_ADR   (S5P_FIMV_COMMON_BASE_B)        /* reconstructed chroma */
> +#define S5P_FIMV_ENC_REF1_CHROMA_ADR   (S5P_FIMV_COMMON_BASE_B + 0x04)
> +#define S5P_FIMV_ENC_REF2_LUMA_ADR     (S5P_FIMV_COMMON_BASE_B + 0x10)
> +#define S5P_FIMV_ENC_REF2_CHROMA_ADR   (S5P_FIMV_COMMON_BASE_B + 0x08)
> +#define S5P_FIMV_ENC_REF3_LUMA_ADR     (S5P_FIMV_COMMON_BASE_B + 0x14)
> +#define S5P_FIMV_ENC_REF3_CHROMA_ADR   (S5P_FIMV_COMMON_BASE_B + 0x0c)
> +
> +/* H.264 encoding */
> +#define S5P_FIMV_H264_UP_MV_ADR                (S5P_FIMV_COMMON_BASE_A)        /* upper motion vector */
> +#define S5P_FIMV_H264_NBOR_INFO_ADR    (S5P_FIMV_COMMON_BASE_A + 0x04) /* entropy engine's neighbor info. */
> +#define S5P_FIMV_H264_UP_INTRA_MD_ADR  (S5P_FIMV_COMMON_BASE_A + 0x08) /* upper intra MD */
> +#define S5P_FIMV_H264_COZERO_FLAG_ADR  (S5P_FIMV_COMMON_BASE_A + 0x10) /* direct cozero flag */
> +#define S5P_FIMV_H264_UP_INTRA_PRED_ADR        (S5P_FIMV_COMMON_BASE_B + 0x40) /* upper intra PRED */
> +
> +/* H.263 encoding */
> +#define S5P_FIMV_H263_UP_MV_ADR                (S5P_FIMV_COMMON_BASE_A)        /* upper motion vector */
> +#define S5P_FIMV_H263_ACDC_COEF_ADR    (S5P_FIMV_COMMON_BASE_A + 0x04) /* upper Q coeff. */
> +
> +/* MPEG4 encoding */
> +#define S5P_FIMV_MPEG4_UP_MV_ADR       (S5P_FIMV_COMMON_BASE_A)        /* upper motion vector */
> +#define S5P_FIMV_MPEG4_ACDC_COEF_ADR   (S5P_FIMV_COMMON_BASE_A + 0x04) /* upper Q coeff. */
> +#define S5P_FIMV_MPEG4_COZERO_FLAG_ADR (S5P_FIMV_COMMON_BASE_A + 0x10) /* direct cozero flag */
> +
> +#define S5P_FIMV_ENC_REF_B_LUMA_ADR     0x062c /* ref B Luma addr */
> +#define S5P_FIMV_ENC_REF_B_CHROMA_ADR   0x0630 /* ref B Chroma addr */
> +
> +#define S5P_FIMV_ENC_CUR_LUMA_ADR      0x0718 /* current Luma addr */
> +#define S5P_FIMV_ENC_CUR_CHROMA_ADR    0x071C /* current Chroma addr */
> +
> +/* Codec common register */
> +#define S5P_FIMV_ENC_HSIZE_PX          0x0818 /* frame width at encoder */
> +#define S5P_FIMV_ENC_VSIZE_PX          0x081c /* frame height at encoder */
> +#define S5P_FIMV_ENC_PROFILE           0x0830 /* profile register */
> +#define S5P_FIMV_ENC_PIC_STRUCT                0x083c /* picture field/frame flag */
> +#define S5P_FIMV_ENC_LF_CTRL           0x0848 /* loop filter control */
> +#define S5P_FIMV_ENC_ALPHA_OFF         0x084c /* loop filter alpha offset */
> +#define S5P_FIMV_ENC_BETA_OFF          0x0850 /* loop filter beta offset */
> +#define S5P_FIMV_MR_BUSIF_CTRL         0x0854 /* hidden, bus interface ctrl */
> +#define S5P_FIMV_ENC_PXL_CACHE_CTRL    0x0a00 /* pixel cache control */
> +
> +/* Channel & stream interface register */
> +#define S5P_FIMV_SI_RTN_CHID           0x2000 /* Return CH instance ID register */
> +#define S5P_FIMV_SI_CH0_INST_ID                0x2040 /* codec instance ID */
> +#define S5P_FIMV_SI_CH1_INST_ID                0x2080 /* codec instance ID */
> +/* Decoder */
> +#define S5P_FIMV_SI_VRESOL             0x2004 /* vertical resolution of decoder */
> +#define S5P_FIMV_SI_HRESOL             0x2008 /* horizontal resolution of decoder */
> +#define S5P_FIMV_SI_BUF_NUMBER         0x200c /* number of frames in the decoded pic */
> +#define S5P_FIMV_SI_CONSUMED_BYTES     0x2018 /* Consumed number of bytes to decode
> +                                                               a frame */
> +#define S5P_FIMV_SI_FRAME_TYPE         0x2020 /* frame type such as skip/I/P/B */
> +
> +#define S5P_FIMV_SI_CH0_SB_ST_ADR      0x2044 /* start addr of stream buf */
> +#define S5P_FIMV_SI_CH0_SB_FRM_SIZE    0x2048 /* size of stream buf */
> +#define S5P_FIMV_SI_CH0_DESC_ADR       0x204c /* addr of descriptor buf */
> +#define S5P_FIMV_SI_CH0_CPB_SIZE       0x2058 /* max size of coded pic. buf */
> +#define S5P_FIMV_SI_CH0_DESC_SIZE      0x205c /* max size of descriptor buf */
> +
> +#define S5P_FIMV_SI_CH1_SB_ST_ADR      0x2084 /* start addr of stream buf */
> +#define S5P_FIMV_SI_CH1_SB_FRM_SIZE    0x2088 /* size of stream buf */
> +#define S5P_FIMV_SI_CH1_DESC_ADR       0x208c /* addr of descriptor buf */
> +#define S5P_FIMV_SI_CH1_CPB_SIZE       0x2098 /* max size of coded pic. buf */
> +#define S5P_FIMV_SI_CH1_DESC_SIZE      0x209c /* max size of descriptor buf */
> +
> +#define S5P_FIMV_SI_FIMV1_HRESOL       0x2054 /* horizontal resolution */
> +#define S5P_FIMV_SI_FIMV1_VRESOL       0x2050 /* vertical resolution */
> +
> +/* Decode frame address */
> +#define S5P_FIMV_DECODE_Y_ADR                  0x2024
> +#define S5P_FIMV_DECODE_C_ADR                  0x2028
> +
> +/* Decoded frame type */
> +#define S5P_FIMV_DECODE_FRAME_TYPE             0x2020
> +
> +/* Sizes of buffers required for decoding */
> +#define S5P_FIMV_DEC_NB_IP_SIZE                        (32 * 1024)
> +#define S5P_FIMV_DEC_VERT_NB_MV_SIZE           (16 * 1024)
> +#define S5P_FIMV_DEC_NB_DCAC_SIZE              (16 * 1024)
> +#define S5P_FIMV_DEC_UPNB_MV_SIZE              (68 * 1024)
> +#define S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE                (136 * 1024)
> +#define S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE     (32 * 1024)
> +#define S5P_FIMV_DEC_VC1_BITPLANE_SIZE         (2 * 1024)
> +#define S5P_FIMV_DEC_STX_PARSER_SIZE           (68 * 1024)
> +
> +#define S5P_FIMV_NV12M_HALIGN                  16
> +#define S5P_FIMV_NV12MT_HALIGN                 16
> +#define S5P_FIMV_NV12MT_VALIGN                 16
> +
> +/* Sizes of buffers required for encoding */
> +#define S5P_FIMV_ENC_UPMV_SIZE                 (0x10000)
> +#define S5P_FIMV_ENC_COLFLG_SIZE               (0x10000)
> +#define S5P_FIMV_ENC_INTRAMD_SIZE              (0x10000)
> +#define S5P_FIMV_ENC_INTRAPRED_SIZE            (0x4000)
> +#define S5P_FIMV_ENC_NBORINFO_SIZE             (0x10000)
> +#define S5P_FIMV_ENC_ACDCCOEF_SIZE             (0x10000)
> +
> +/* Encoder */
> +#define S5P_FIMV_ENC_SI_STRM_SIZE      0x2004 /* stream size */
> +#define S5P_FIMV_ENC_SI_PIC_CNT                0x2008 /* picture count */
> +#define S5P_FIMV_ENC_SI_WRITE_PTR      0x200c /* write pointer */
> +#define S5P_FIMV_ENC_SI_SLICE_TYPE     0x2010 /* slice type(I/P/B/IDR) */
> +
> +#define S5P_FIMV_ENCODED_Y_ADDR         0x2014 /* the addr of the encoded luma pic */
> +#define S5P_FIMV_ENCODED_C_ADDR         0x2018 /* the addr of the encoded chroma pic */
> +
> +#define S5P_FIMV_ENC_SI_CH0_SB_ADR     0x2044 /* addr of stream buf */
> +#define S5P_FIMV_ENC_SI_CH0_SB_SIZE    0x204c /* size of stream buf */
> +#define S5P_FIMV_ENC_SI_CH0_CUR_Y_ADR  0x2050 /* current Luma addr */
> +#define S5P_FIMV_ENC_SI_CH0_CUR_C_ADR  0x2054 /* current Chroma addr */
> +#define S5P_FIMV_ENC_SI_CH0_FRAME_INS  0x2058 /* frame insertion */
> +
> +#define S5P_FIMV_ENC_SI_CH1_SB_ADR     0x2084 /* addr of stream buf */
> +#define S5P_FIMV_ENC_SI_CH1_SB_SIZE    0x208c /* size of stream buf */
> +#define S5P_FIMV_ENC_SI_CH1_CUR_Y_ADR  0x2090 /* current Luma addr */
> +#define S5P_FIMV_ENC_SI_CH1_CUR_C_ADR  0x2094 /* current Chroma addr */
> +#define S5P_FIMV_ENC_SI_CH1_FRAME_INS  0x2098 /* frame insertion */
> +
> +#define S5P_FIMV_ENC_PIC_TYPE_CTRL     0xc504 /* pic type level control */
> +#define S5P_FIMV_ENC_B_RECON_WRITE_ON  0xc508 /* B frame recon write ctrl */
> +#define S5P_FIMV_ENC_MSLICE_CTRL       0xc50c /* multi slice control */
> +#define S5P_FIMV_ENC_MSLICE_MB         0xc510 /* MB number in the one slice */
> +#define S5P_FIMV_ENC_MSLICE_BIT                0xc514 /* bit count for one slice */
> +#define S5P_FIMV_ENC_CIR_CTRL          0xc518 /* number of intra refresh MB */
> +#define S5P_FIMV_ENC_MAP_FOR_CUR       0xc51c /* linear or 64x32 tiled mode */
> +#define S5P_FIMV_ENC_PADDING_CTRL      0xc520 /* padding control */
> +
> +#define S5P_FIMV_ENC_RC_CONFIG         0xc5a0 /* RC config */
> +#define S5P_FIMV_ENC_RC_BIT_RATE       0xc5a8 /* bit rate */
> +#define S5P_FIMV_ENC_RC_QBOUND         0xc5ac /* max/min QP */
> +#define S5P_FIMV_ENC_RC_RPARA          0xc5b0 /* rate control reaction coeff */
> +#define S5P_FIMV_ENC_RC_MB_CTRL                0xc5b4 /* MB adaptive scaling */
> +
> +/* Encoder for H264 only */
> +#define S5P_FIMV_ENC_H264_ENTRP_MODE   0xd004 /* CAVLC or CABAC */
> +#define S5P_FIMV_ENC_H264_ALPHA_OFF    0xd008 /* loop filter alpha offset */
> +#define S5P_FIMV_ENC_H264_BETA_OFF     0xd00c /* loop filter beta offset */
> +#define S5P_FIMV_ENC_H264_NUM_OF_REF   0xd010 /* number of reference for P/B */
> +#define S5P_FIMV_ENC_H264_TRANS_FLAG   0xd034 /* 8x8 transform flag in PPS & high profile */
> +
> +#define S5P_FIMV_ENC_RC_FRAME_RATE     0xd0d0 /* frame rate */
> +
> +/* Encoder for MPEG4 only */
> +#define S5P_FIMV_ENC_MPEG4_QUART_PXL   0xe008 /* qpel interpolation ctrl */
> +
> +/* Additional */
> +#define S5P_FIMV_SI_CH0_DPB_CONF_CTRL   0x2068 /* DPB Config Control Register */
> +#define S5P_FIMV_DPB_COUNT_MASK                0xffff
> +
> +#define S5P_FIMV_SI_CH0_RELEASE_BUF     0x2060 /* DPB release buffer register */
> +#define S5P_FIMV_SI_CH0_HOST_WR_ADR    0x2064 /* address of shared memory */
> +
> +/* Channel Control Register */
> +#define S5P_FIMV_CH_FRAME_START_REALLOC        5
> +
> +#define S5P_FIMV_CH_MASK               7
> +#define S5P_FIMV_CH_SHIFT              16
> +
> +/* Host to RISC command */
> +#define S5P_FIMV_R2H_CMD_RSV_RET               3
> +#define S5P_FIMV_R2H_CMD_ENC_COMPLETE_RET      7
> +#define S5P_FIMV_R2H_CMD_FLUSH_RET             12
> +#define S5P_FIMV_R2H_CMD_EDFU_INIT_RET         16
> +
> +/* Shared memory registers' offsets */
> +
> +/* An offset of the start position in the stream when
> + * the start position is not aligned */
> +#define S5P_FIMV_SHARED_GET_FRAME_TAG_BOT      0x000C
> +#define S5P_FIMV_SHARED_START_BYTE_NUM         0x0018
> +#define S5P_FIMV_SHARED_RC_VOP_TIMING          0x0030
> +#define S5P_FIMV_SHARED_LUMA_DPB_SIZE          0x0064
> +#define S5P_FIMV_SHARED_CHROMA_DPB_SIZE                0x0068
> +#define S5P_FIMV_SHARED_MV_SIZE                        0x006C
> +#define S5P_FIMV_SHARED_PIC_TIME_TOP           0x0010
> +#define S5P_FIMV_SHARED_PIC_TIME_BOTTOM                0x0014
> +#define S5P_FIMV_SHARED_EXT_ENC_CONTROL                0x0028
> +#define S5P_FIMV_SHARED_P_B_FRAME_QP           0x0070
> +#define S5P_FIMV_SHARED_ASPECT_RATIO_IDC       0x0074
> +#define S5P_FIMV_SHARED_EXTENDED_SAR           0x0078
> +#define S5P_FIMV_SHARED_H264_I_PERIOD          0x009C
> +#define S5P_FIMV_SHARED_RC_CONTROL_CONFIG      0x00A0
> +
> +/* End of old definitions */
> +
> +#endif /* _REGS_FIMV_V6_H */
> diff --git a/drivers/media/video/s5p-mfc/regs-mfc.h b/drivers/media/video/s5p-mfc/regs-mfc.h
> index a19bece..d2dfb06 100644
> --- a/drivers/media/video/s5p-mfc/regs-mfc.h
> +++ b/drivers/media/video/s5p-mfc/regs-mfc.h
> @@ -144,6 +144,7 @@
>  #define S5P_FIMV_ENC_PROFILE_H264_MAIN                 0
>  #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_MPEG4_SIMPLE              0
>  #define S5P_FIMV_ENC_PROFILE_MPEG4_ADVANCED_SIMPLE     1
>  #define S5P_FIMV_ENC_PIC_STRUCT                0x083c /* picture field/frame flag */
> @@ -213,6 +214,7 @@
>  #define S5P_FIMV_DEC_STATUS_RESOLUTION_MASK            (3<<4)
>  #define S5P_FIMV_DEC_STATUS_RESOLUTION_INC             (1<<4)
>  #define S5P_FIMV_DEC_STATUS_RESOLUTION_DEC             (2<<4)
> +#define S5P_FIMV_DEC_STATUS_RESOLUTION_SHIFT           4
>
>  /* Decode frame address */
>  #define S5P_FIMV_DECODE_Y_ADR                  0x2024
> @@ -377,6 +379,16 @@
>  #define S5P_FIMV_R2H_CMD_EDFU_INIT_RET         16
>  #define S5P_FIMV_R2H_CMD_ERR_RET               32
>
> +/* Dummy definition for MFCv6 compatibilty */
> +#define S5P_FIMV_CODEC_H264_MVC_DEC            -1
> +#define S5P_FIMV_R2H_CMD_FIELD_DONE_RET                -1
> +#define S5P_FIMV_MFC_RESET                     -1
> +#define S5P_FIMV_RISC_ON                       -1
> +#define S5P_FIMV_RISC_BASE_ADDRESS             -1
> +#define S5P_FIMV_CODEC_VP8_DEC                 -1
> +#define S5P_FIMV_REG_CLEAR_BEGIN               0
> +#define S5P_FIMV_REG_CLEAR_COUNT               0
> +
>  /* Error handling defines */
>  #define S5P_FIMV_ERR_WARNINGS_START            145
>  #define S5P_FIMV_ERR_DEC_MASK                  0xFFFF
> @@ -414,5 +426,22 @@
>  #define S5P_FIMV_SHARED_EXTENDED_SAR           0x0078
>  #define S5P_FIMV_SHARED_H264_I_PERIOD          0x009C
>  #define S5P_FIMV_SHARED_RC_CONTROL_CONFIG      0x00A0
> +#define S5P_FIMV_SHARED_DISP_FRAME_TYPE_SHIFT  2
> +
> +#define S5P_FIMV_SHARED_FRAME_PACK_SEI_AVAIL    0x16C
> +#define S5P_FIMV_SHARED_FRAME_PACK_ARRGMENT_ID  0x170
> +#define S5P_FIMV_SHARED_FRAME_PACK_SEI_INFO     0x174
> +#define S5P_FIMV_SHARED_FRAME_PACK_GRID_POS     0x178
> +
> +/* SEI related information */
> +#define S5P_FIMV_FRAME_PACK_SEI_AVAIL           S5P_FIMV_SHARED_FRAME_PACK_SEI_AVAIL
> +#define S5P_FIMV_FRAME_PACK_ARRGMENT_ID         S5P_FIMV_SHARED_FRAME_PACK_ARRGMENT_ID
> +#define S5P_FIMV_FRAME_PACK_SEI_INFO            S5P_FIMV_SHARED_FRAME_PACK_SEI_INFO
> +#define S5P_FIMV_FRAME_PACK_GRID_POS            S5P_FIMV_SHARED_FRAME_PACK_GRID_POS
> +
> +#define S5P_FIMV_SHARED_SET_E_FRAME_TAG                S5P_FIMV_SHARED_SET_FRAME_TAG
> +#define S5P_FIMV_SHARED_GET_E_FRAME_TAG                S5P_FIMV_SHARED_GET_FRAME_TAG_TOP
> +#define S5P_FIMV_ENCODED_LUMA_ADDR             S5P_FIMV_ENCODED_Y_ADDR
> +#define S5P_FIMV_ENCODED_CHROMA_ADDR           S5P_FIMV_ENCODED_C_ADDR
>
>  #endif /* _REGS_FIMV_H */
> diff --git a/drivers/media/video/s5p-mfc/s5p_mfc.c b/drivers/media/video/s5p-mfc/s5p_mfc.c
> index 9bb68e7..bec94bc 100644
> --- a/drivers/media/video/s5p-mfc/s5p_mfc.c
> +++ b/drivers/media/video/s5p-mfc/s5p_mfc.c
> @@ -21,15 +21,13 @@
>  #include <linux/videodev2.h>
>  #include <linux/workqueue.h>
>  #include <media/videobuf2-core.h>
> -#include "regs-mfc.h"
> +#include "s5p_mfc_common.h"
>  #include "s5p_mfc_ctrl.h"
>  #include "s5p_mfc_debug.h"
>  #include "s5p_mfc_dec.h"
>  #include "s5p_mfc_enc.h"
>  #include "s5p_mfc_intr.h"
> -#include "s5p_mfc_opr.h"
>  #include "s5p_mfc_pm.h"
> -#include "s5p_mfc_shm.h"
>
>  #define S5P_MFC_NAME           "s5p-mfc"
>  #define S5P_MFC_DEC_NAME       "s5p-mfc-dec"
> @@ -155,13 +153,6 @@ static enum s5p_mfc_node_type s5p_mfc_get_node_type(struct file *file)
>         return MFCNODE_INVALID;
>  }
>
> -static void s5p_mfc_clear_int_flags(struct s5p_mfc_dev *dev)
> -{
> -       mfc_write(dev, 0, S5P_FIMV_RISC_HOST_INT);
> -       mfc_write(dev, 0, S5P_FIMV_RISC2HOST_CMD);
> -       mfc_write(dev, 0xffff, S5P_FIMV_SI_RTN_CHID);
> -}
> -
>  static void s5p_mfc_handle_frame_all_extracted(struct s5p_mfc_ctx *ctx)
>  {
>         struct s5p_mfc_buf *dst_buf;
> @@ -179,8 +170,8 @@ static void s5p_mfc_handle_frame_all_extracted(struct s5p_mfc_ctx *ctx)
>                 ctx->dst_queue_cnt--;
>                 dst_buf->b->v4l2_buf.sequence = (ctx->sequence++);
>
> -               if (s5p_mfc_read_shm(ctx, PIC_TIME_TOP) ==
> -                       s5p_mfc_read_shm(ctx, PIC_TIME_BOT))
> +               if (s5p_mfc_read_info(ctx, PIC_TIME_TOP) ==
> +                       s5p_mfc_read_info(ctx, PIC_TIME_BOT))
>                         dst_buf->b->v4l2_buf.field = V4L2_FIELD_NONE;
>                 else
>                         dst_buf->b->v4l2_buf.field = V4L2_FIELD_INTERLACED;
> @@ -195,7 +186,7 @@ static void s5p_mfc_handle_frame_copy_time(struct s5p_mfc_ctx *ctx)
>         struct s5p_mfc_dev *dev = ctx->dev;
>         struct s5p_mfc_buf  *dst_buf, *src_buf;
>         size_t dec_y_addr = s5p_mfc_get_dec_y_adr();
> -       unsigned int frame_type = s5p_mfc_get_frame_type();
> +       unsigned int frame_type = s5p_mfc_get_dec_frame_type();
>
>         /* Copy timestamp / timecode from decoded src to dst and set
>            appropraite flags */
> @@ -232,7 +223,7 @@ static void s5p_mfc_handle_frame_new(struct s5p_mfc_ctx *ctx, unsigned int err)
>         struct s5p_mfc_dev *dev = ctx->dev;
>         struct s5p_mfc_buf  *dst_buf;
>         size_t dspl_y_addr = s5p_mfc_get_dspl_y_adr();
> -       unsigned int frame_type = s5p_mfc_get_frame_type();
> +       unsigned int frame_type = s5p_mfc_get_dec_frame_type();
>         unsigned int index;
>
>         /* If frame is same as previous then skip and do not dequeue */
> @@ -251,8 +242,8 @@ static void s5p_mfc_handle_frame_new(struct s5p_mfc_ctx *ctx, unsigned int err)
>                         list_del(&dst_buf->list);
>                         ctx->dst_queue_cnt--;
>                         dst_buf->b->v4l2_buf.sequence = ctx->sequence;
> -                       if (s5p_mfc_read_shm(ctx, PIC_TIME_TOP) ==
> -                               s5p_mfc_read_shm(ctx, PIC_TIME_BOT))
> +                       if (s5p_mfc_read_info(ctx, PIC_TIME_TOP) ==
> +                               s5p_mfc_read_info(ctx, PIC_TIME_BOT))
>                                 dst_buf->b->v4l2_buf.field = V4L2_FIELD_NONE;
>                         else
>                                 dst_buf->b->v4l2_buf.field =
> @@ -285,12 +276,13 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx,
>
>         dst_frame_status = s5p_mfc_get_dspl_status()
>                                 & S5P_FIMV_DEC_STATUS_DECODING_STATUS_MASK;
> -       res_change = s5p_mfc_get_dspl_status()
> -                               & S5P_FIMV_DEC_STATUS_RESOLUTION_MASK;
> +       res_change = (s5p_mfc_get_dspl_status()
> +                               & S5P_FIMV_DEC_STATUS_RESOLUTION_MASK)
> +                               >> S5P_FIMV_DEC_STATUS_RESOLUTION_SHIFT;
>         mfc_debug(2, "Frame Status: %x\n", dst_frame_status);
>         if (ctx->state == MFCINST_RES_CHANGE_INIT)
>                 ctx->state = MFCINST_RES_CHANGE_FLUSH;
> -       if (res_change) {
> +       if (res_change && res_change != 3) {
>                 ctx->state = MFCINST_RES_CHANGE_INIT;
>                 s5p_mfc_clear_int_flags(dev);
>                 wake_up_ctx(ctx, reason, err);
> @@ -333,7 +325,8 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx,
>                                                                 list);
>                 ctx->consumed_stream += s5p_mfc_get_consumed_stream();
>                 if (ctx->codec_mode != S5P_FIMV_CODEC_H264_DEC &&
> -                       s5p_mfc_get_frame_type() == S5P_FIMV_DECODE_FRAME_P_FRAME
> +                       s5p_mfc_get_dec_frame_type() ==
> +                                       S5P_FIMV_DECODE_FRAME_P_FRAME
>                                         && ctx->consumed_stream + STUFF_BYTE <
>                                         src_buf->b->v4l2_planes[0].bytesused) {
>                         /* Run MFC again on the same buffer */
> @@ -427,7 +420,6 @@ static void s5p_mfc_handle_seq_done(struct s5p_mfc_ctx *ctx,
>                                  unsigned int reason, unsigned int err)
>  {
>         struct s5p_mfc_dev *dev;
> -       unsigned int guard_width, guard_height;
>
>         if (ctx == NULL)
>                 return;
> @@ -439,45 +431,28 @@ static void s5p_mfc_handle_seq_done(struct s5p_mfc_ctx *ctx,
>                 ctx->img_width = s5p_mfc_get_img_width();
>                 ctx->img_height = s5p_mfc_get_img_height();
>
> -               ctx->buf_width = ALIGN(ctx->img_width,
> -                                               S5P_FIMV_NV12MT_HALIGN);
> -               ctx->buf_height = ALIGN(ctx->img_height,
> -                                               S5P_FIMV_NV12MT_VALIGN);
> -               mfc_debug(2, "SEQ Done: Movie dimensions %dx%d, "
> -                       "buffer dimensions: %dx%d\n", ctx->img_width,
> -                               ctx->img_height, ctx->buf_width,
> -                                               ctx->buf_height);
> -               if (ctx->codec_mode == S5P_FIMV_CODEC_H264_DEC) {
> -                       ctx->luma_size = ALIGN(ctx->buf_width *
> -                               ctx->buf_height, S5P_FIMV_DEC_BUF_ALIGN);
> -                       ctx->chroma_size = ALIGN(ctx->buf_width *
> -                                        ALIGN((ctx->img_height >> 1),
> -                                              S5P_FIMV_NV12MT_VALIGN),
> -                                              S5P_FIMV_DEC_BUF_ALIGN);
> -                       ctx->mv_size = ALIGN(ctx->buf_width *
> -                                       ALIGN((ctx->buf_height >> 2),
> -                                       S5P_FIMV_NV12MT_VALIGN),
> -                                       S5P_FIMV_DEC_BUF_ALIGN);
> -               } else {
> -                       guard_width = ALIGN(ctx->img_width + 24,
> -                                       S5P_FIMV_NV12MT_HALIGN);
> -                       guard_height = ALIGN(ctx->img_height + 16,
> -                                               S5P_FIMV_NV12MT_VALIGN);
> -                       ctx->luma_size = ALIGN(guard_width *
> -                               guard_height, S5P_FIMV_DEC_BUF_ALIGN);
> -                       guard_width = ALIGN(ctx->img_width + 16,
> -                                               S5P_FIMV_NV12MT_HALIGN);
> -                       guard_height = ALIGN((ctx->img_height >> 1) + 4,
> -                                               S5P_FIMV_NV12MT_VALIGN);
> -                       ctx->chroma_size = ALIGN(guard_width *
> -                               guard_height, S5P_FIMV_DEC_BUF_ALIGN);
> -                       ctx->mv_size = 0;
> -               }
> +               s5p_mfc_dec_calc_dpb_size(ctx);
> +
>                 ctx->dpb_count = s5p_mfc_get_dpb_count();
>                 if (ctx->img_width == 0 || ctx->img_height == 0)
>                         ctx->state = MFCINST_ERROR;
>                 else
>                         ctx->state = MFCINST_HEAD_PARSED;
> +
> +               if ((ctx->codec_mode == S5P_FIMV_CODEC_H264_DEC ||
> +                       ctx->codec_mode == S5P_FIMV_CODEC_H264_MVC_DEC) &&
> +                               !list_empty(&ctx->src_queue)) {
> +                       struct s5p_mfc_buf *src_buf;
> +                       src_buf = list_entry(ctx->src_queue.next,
> +                                       struct s5p_mfc_buf, list);
> +                       mfc_debug(2, "Check consumed size of header. ");
> +                       mfc_debug(2, "source : %d, consumed : %d\n",
> +                                       s5p_mfc_get_consumed_stream(),
> +                                       src_buf->b->v4l2_planes[0].bytesused);
> +                       if (s5p_mfc_get_consumed_stream() <
> +                                       src_buf->b->v4l2_planes[0].bytesused)
> +                               ctx->remained = 1;
> +               }
>         }
>         s5p_mfc_clear_int_flags(dev);
>         clear_work_bit(ctx);
> @@ -508,7 +483,7 @@ static void s5p_mfc_handle_init_buffers(struct s5p_mfc_ctx *ctx,
>         spin_unlock(&dev->condlock);
>         if (err == 0) {
>                 ctx->state = MFCINST_RUNNING;
> -               if (!ctx->dpb_flush_flag) {
> +               if (!ctx->dpb_flush_flag && !ctx->remained) {
>                         spin_lock_irqsave(&dev->irqlock, flags);
>                         if (!list_empty(&ctx->src_queue)) {
>                                 src_buf = list_entry(ctx->src_queue.next,
> @@ -567,6 +542,7 @@ static irqreturn_t s5p_mfc_irq(int irq, void *priv)
>                 break;
>
>         case S5P_FIMV_R2H_CMD_SLICE_DONE_RET:
> +       case S5P_FIMV_R2H_CMD_FIELD_DONE_RET:
>         case S5P_FIMV_R2H_CMD_FRAME_DONE_RET:
>                 if (ctx->c_ops->post_frame_start) {
>                         if (ctx->c_ops->post_frame_start(ctx))
> @@ -679,6 +655,7 @@ static int s5p_mfc_open(struct file *file)
>         if (s5p_mfc_get_node_type(file) == MFCNODE_DECODER) {
>                 ctx->type = MFCINST_DECODER;
>                 ctx->c_ops = get_dec_codec_ops();
> +               s5p_mfc_dec_init(ctx);
>                 /* Setup ctrl handler */
>                 ret = s5p_mfc_dec_ctrls_setup(ctx);
>                 if (ret) {
> @@ -691,6 +668,7 @@ static int s5p_mfc_open(struct file *file)
>                 /* only for encoder */
>                 INIT_LIST_HEAD(&ctx->ref_queue);
>                 ctx->ref_queue_cnt = 0;
> +               s5p_mfc_enc_init(ctx);
>                 /* Setup ctrl handler */
>                 ret = s5p_mfc_enc_ctrls_setup(ctx);
>                 if (ret) {
> @@ -842,6 +820,7 @@ static int s5p_mfc_release(struct file *file)
>                 mfc_debug(2, "Last instance - release firmware\n");
>                 /* reset <-> F/W release */
>                 s5p_mfc_reset(dev);
> +               s5p_mfc_deinit_hw(dev);
>                 s5p_mfc_release_firmware(dev);
>                 del_timer_sync(&dev->watchdog_timer);
>                 if (s5p_mfc_power_off() < 0)
> @@ -1086,6 +1065,9 @@ static int s5p_mfc_probe(struct platform_device *pdev)
>         dev->watchdog_timer.data = (unsigned long)dev;
>         dev->watchdog_timer.function = s5p_mfc_watchdog;
>
> +       dev->variant = (struct s5p_mfc_variant *)
> +               platform_get_device_id(pdev)->driver_data;
> +
>         pr_debug("%s--\n", __func__);
>         return 0;
>
> @@ -1205,9 +1187,74 @@ static const struct dev_pm_ops s5p_mfc_pm_ops = {
>                            NULL)
>  };
>
> +struct s5p_mfc_buf_size_v5 mfc_buf_size_v5 = {
> +       .h264_ctx       = 0x96000,
> +       .non_h264_ctx   = 0x2800,
> +       .dsc            = 0x20000,
> +       .shm            = 0x1000,
> +};
> +
> +struct s5p_mfc_buf_size buf_size_v5 = {
> +       .fw     = 0x60000,
> +       .cpb    = 0x400000,     /*   4MB */
> +       .priv   = &mfc_buf_size_v5,
> +};
> +
> +struct s5p_mfc_buf_align mfc_buf_align_v5 = {
> +       .base = 17,
> +};
> +
> +static struct s5p_mfc_variant mfc_drvdata_v5 = {
> +       .version        = 0x51,
> +       .port_num       = 2,
> +       .buf_size       = &buf_size_v5,
> +       .buf_align      = &mfc_buf_align_v5,
> +};
> +
> +struct s5p_mfc_buf_size_v6 mfc_buf_size_v6 = {
> +       .dev_ctx        = 0x7000,       /*  28KB */
> +       .h264_dec_ctx   = 0x200000,     /* 1.6MB */
> +       .other_dec_ctx  = 0x5000,       /*  20KB */
> +       .h264_enc_ctx   = 0x19000,      /* 100KB */
> +       .other_enc_ctx  = 0x3000,       /*  12KB */
> +};
> +
> +struct s5p_mfc_buf_size buf_size_v6 = {
> +       .fw     = 0x100000,     /*   1MB */
> +       .cpb    = 0x300000,     /*   3MB */
> +       .priv   = &mfc_buf_size_v6,
> +};
> +
> +struct s5p_mfc_buf_align mfc_buf_align_v6 = {
> +       .base = 0,
> +};
> +
> +static struct s5p_mfc_variant mfc_drvdata_v6 = {
> +       .version        = 0x61,
> +       .port_num       = 1,
> +       .buf_size       = &buf_size_v6,
> +       .buf_align      = &mfc_buf_align_v6,
> +};
> +
> +static struct platform_device_id mfc_driver_ids[] = {
> +       {
> +               .name = "s5p-mfc",
> +               .driver_data = (unsigned long)&mfc_drvdata_v5,
> +       }, {
> +               .name = "s5p-mfc-v5",
> +               .driver_data = (unsigned long)&mfc_drvdata_v5,
> +       }, {
> +               .name = "s5p-mfc-v6",
> +               .driver_data = (unsigned long)&mfc_drvdata_v6,
> +       },
> +       {},
> +};
> +MODULE_DEVICE_TABLE(platform, mfc_driver_ids);
> +
>  static struct platform_driver s5p_mfc_driver = {
> -       .probe  = s5p_mfc_probe,
> -       .remove = __devexit_p(s5p_mfc_remove),
> +       .probe          = s5p_mfc_probe,
> +       .remove         = __devexit_p(s5p_mfc_remove),
> +       .id_table       = mfc_driver_ids,
>         .driver = {
>                 .name   = S5P_MFC_NAME,
>                 .owner  = THIS_MODULE,
> diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_cmd.c b/drivers/media/video/s5p-mfc/s5p_mfc_cmd.c
> index f0665ed..e3c64db 100644
> --- a/drivers/media/video/s5p-mfc/s5p_mfc_cmd.c
> +++ b/drivers/media/video/s5p-mfc/s5p_mfc_cmd.c
> @@ -16,8 +16,8 @@
>  #include "s5p_mfc_debug.h"
>
>  /* This function is used to send a command to the MFC */
> -static int s5p_mfc_cmd_host2risc(struct s5p_mfc_dev *dev, int cmd,
> -                                               struct s5p_mfc_cmd_args *args)
> +int s5p_mfc_cmd_host2risc(struct s5p_mfc_dev *dev, int cmd,
> +                               struct s5p_mfc_cmd_args *args)
>  {
>         int cur_cmd;
>         unsigned long timeout;
> @@ -81,7 +81,7 @@ int s5p_mfc_open_inst_cmd(struct s5p_mfc_ctx *ctx)
>         memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args));
>         h2r_args.arg[0] = ctx->codec_mode;
>         h2r_args.arg[1] = 0; /* no crc & no pixelcache */
> -       h2r_args.arg[2] = ctx->ctx_ofs;
> +       h2r_args.arg[2] = ctx->ctx.ofs;
>         h2r_args.arg[3] = ctx->ctx_size;
>         ret = s5p_mfc_cmd_host2risc(dev, S5P_FIMV_H2R_CMD_OPEN_INSTANCE,
>                                                                 &h2r_args);
> diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_cmd.h b/drivers/media/video/s5p-mfc/s5p_mfc_cmd.h
> index 5ceebfe..5c9e662 100644
> --- a/drivers/media/video/s5p-mfc/s5p_mfc_cmd.h
> +++ b/drivers/media/video/s5p-mfc/s5p_mfc_cmd.h
> @@ -21,6 +21,9 @@ struct s5p_mfc_cmd_args {
>         unsigned int    arg[MAX_H2R_ARG];
>  };
>
> +int s5p_mfc_cmd_host2risc(struct s5p_mfc_dev *dev, int cmd,
> +       struct s5p_mfc_cmd_args *args);
> +
>  int s5p_mfc_sys_init_cmd(struct s5p_mfc_dev *dev);
>  int s5p_mfc_sleep_cmd(struct s5p_mfc_dev *dev);
>  int s5p_mfc_wakeup_cmd(struct s5p_mfc_dev *dev);
> diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_cmd_v6.c b/drivers/media/video/s5p-mfc/s5p_mfc_cmd_v6.c
> new file mode 100644
> index 0000000..6a631e0
> --- /dev/null
> +++ b/drivers/media/video/s5p-mfc/s5p_mfc_cmd_v6.c
> @@ -0,0 +1,96 @@
> +/*
> + * linux/drivers/media/video/s5p-mfc/s5p_mfc_cmd_v6.c
> + *
> + * Copyright (c) 2012 Samsung Electronics Co., Ltd.
> + *             http://www.samsung.com/
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + */
> +
> +#include "s5p_mfc_common.h"
> +
> +#include "s5p_mfc_cmd.h"
> +#include "s5p_mfc_debug.h"
> +#include "s5p_mfc_intr.h"
> +
> +int s5p_mfc_cmd_host2risc(struct s5p_mfc_dev *dev, int cmd,
> +                               struct s5p_mfc_cmd_args *args)
> +{
> +       mfc_debug(2, "Issue the command: %d\n", cmd);
> +
> +       /* Reset RISC2HOST command */
> +       mfc_write(dev, 0x0, S5P_FIMV_RISC2HOST_CMD);
> +
> +       /* Issue the command */
> +       mfc_write(dev, cmd, S5P_FIMV_HOST2RISC_CMD);
> +       mfc_write(dev, 0x1, S5P_FIMV_HOST2RISC_INT);
> +
> +       return 0;
> +}
> +
> +int s5p_mfc_sys_init_cmd(struct s5p_mfc_dev *dev)
> +{
> +       struct s5p_mfc_cmd_args h2r_args;
> +       struct s5p_mfc_buf_size_v6 *buf_size = dev->variant->buf_size->priv;
> +
> +       s5p_mfc_alloc_dev_context_buffer(dev);
> +       mfc_write(dev, dev->ctx_buf.dma, S5P_FIMV_CONTEXT_MEM_ADDR);
> +       mfc_write(dev, buf_size->dev_ctx, S5P_FIMV_CONTEXT_MEM_SIZE);
> +       return s5p_mfc_cmd_host2risc(dev, S5P_FIMV_H2R_CMD_SYS_INIT, &h2r_args);
> +}
> +
> +int s5p_mfc_sleep_cmd(struct s5p_mfc_dev *dev)
> +{
> +       struct s5p_mfc_cmd_args h2r_args;
> +
> +       memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args));
> +       return s5p_mfc_cmd_host2risc(dev, S5P_FIMV_H2R_CMD_SLEEP, &h2r_args);
> +}
> +
> +int s5p_mfc_wakeup_cmd(struct s5p_mfc_dev *dev)
> +{
> +       struct s5p_mfc_cmd_args h2r_args;
> +
> +       memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args));
> +       return s5p_mfc_cmd_host2risc(dev, S5P_FIMV_H2R_CMD_WAKEUP, &h2r_args);
> +}
> +
> +/* Open a new instance and get its number */
> +int s5p_mfc_open_inst_cmd(struct s5p_mfc_ctx *ctx)
> +{
> +       struct s5p_mfc_dev *dev = ctx->dev;
> +       struct s5p_mfc_cmd_args h2r_args;
> +
> +       mfc_debug(2, "Requested codec mode: %d\n", ctx->codec_mode);
> +       dev->curr_ctx = ctx->num;
> +       mfc_write(dev, ctx->codec_mode, S5P_FIMV_CODEC_TYPE);
> +       mfc_write(dev, ctx->ctx.dma, S5P_FIMV_CONTEXT_MEM_ADDR);
> +       mfc_write(dev, ctx->ctx_size, S5P_FIMV_CONTEXT_MEM_SIZE);
> +       mfc_write(dev, 0, S5P_FIMV_D_CRC_CTRL); /* no crc */
> +
> +       return s5p_mfc_cmd_host2risc(dev, S5P_FIMV_H2R_CMD_OPEN_INSTANCE,
> +                                       &h2r_args);
> +}
> +
> +/* Close instance */
> +int s5p_mfc_close_inst_cmd(struct s5p_mfc_ctx *ctx)
> +{
> +       struct s5p_mfc_dev *dev = ctx->dev;
> +       struct s5p_mfc_cmd_args h2r_args;
> +       int ret = 0;
> +
> +       dev->curr_ctx = ctx->num;
> +       if (ctx->state != MFCINST_FREE) {
> +               mfc_write(dev, ctx->inst_no, S5P_FIMV_INSTANCE_ID);
> +               ret = s5p_mfc_cmd_host2risc(dev,
> +                                       S5P_FIMV_H2R_CMD_CLOSE_INSTANCE,
> +                                       &h2r_args);
> +       } else {
> +               ret = -EINVAL;
> +       }
> +
> +       return ret;
> +}
> diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_common.h b/drivers/media/video/s5p-mfc/s5p_mfc_common.h
> index bd5706a..8c646f4 100644
> --- a/drivers/media/video/s5p-mfc/s5p_mfc_common.h
> +++ b/drivers/media/video/s5p-mfc/s5p_mfc_common.h
> @@ -16,7 +16,6 @@
>  #ifndef S5P_MFC_COMMON_H_
>  #define S5P_MFC_COMMON_H_
>
> -#include "regs-mfc.h"
>  #include <linux/platform_device.h>
>  #include <linux/videodev2.h>
>  #include <media/v4l2-ctrls.h>
> @@ -34,10 +33,6 @@
>  #define MFC_OFFSET_SHIFT       11
>
>  #define FIRMWARE_ALIGN         0x20000         /* 128KB */
> -#define MFC_H264_CTX_BUF_SIZE  0x96000         /* 600KB per H264 instance */
> -#define MFC_CTX_BUF_SIZE       0x2800          /* 10KB per instance */
> -#define DESC_BUF_SIZE          0x20000         /* 128KB for DESC buffer */
> -#define SHARED_BUF_SIZE                0x2000          /* 8KB for shared buffer */
>
>  #define DEF_CPB_SIZE           0x40000         /* 512KB */
>
> @@ -174,6 +169,54 @@ struct s5p_mfc_pm {
>         struct device   *device;
>  };
>
> +struct s5p_mfc_buf_size_v5 {
> +       unsigned int h264_ctx;
> +       unsigned int non_h264_ctx;
> +       unsigned int dsc;
> +       unsigned int shm;
> +};
> +
> +struct s5p_mfc_buf_size_v6 {
> +       unsigned int dev_ctx;
> +       unsigned int h264_dec_ctx;
> +       unsigned int other_dec_ctx;
> +       unsigned int h264_enc_ctx;
> +       unsigned int other_enc_ctx;
> +};
> +
> +struct s5p_mfc_buf_size {
> +       unsigned int fw;
> +       unsigned int cpb;
> +       void *priv;
> +};
> +
> +struct s5p_mfc_buf_align {
> +       unsigned int base;
> +};
> +
> +struct s5p_mfc_variant {
> +       unsigned int version;
> +       unsigned int port_num;
> +       struct s5p_mfc_buf_size *buf_size;
> +       struct s5p_mfc_buf_align *buf_align;
> +};
> +
> +/**
> + * struct s5p_mfc_priv_buf - represents internal used buffer
> + * @alloc:             allocation-specific context for each buffer
> + *                     (videobuf2 allocator)
> + * @ofs:               offset of each buffer, will be used for MFC
> + * @virt:              kernel virtual address, only valid when the
> + *                     buffer accessed by driver
> + * @dma:               DMA address, only valid when kernel DMA API used
> + */
> +struct s5p_mfc_priv_buf {
> +       void            *alloc;
> +       unsigned long   ofs;
> +       void            *virt;
> +       dma_addr_t      dma;
> +};
> +
>  /**
>   * struct s5p_mfc_dev - The struct containing driver internal parameters.
>   *
> @@ -209,6 +252,7 @@ struct s5p_mfc_pm {
>   * @watchdog_work:     worker for the watchdog
>   * @alloc_ctx:         videobuf2 allocator contexts for two memory banks
>   * @enter_suspend:     flag set when entering suspend
> + * @ctx_buf:           common context memory (MFCv6)
>   *
>   */
>  struct s5p_mfc_dev {
> @@ -223,6 +267,7 @@ struct s5p_mfc_dev {
>         struct v4l2_ctrl_handler dec_ctrl_handler;
>         struct v4l2_ctrl_handler enc_ctrl_handler;
>         struct s5p_mfc_pm       pm;
> +       struct s5p_mfc_variant  *variant;
>         int num_inst;
>         spinlock_t irqlock;     /* lock when operating on videobuf2 queues */
>         spinlock_t condlock;    /* lock when changing/checking if a context is
> @@ -245,6 +290,8 @@ struct s5p_mfc_dev {
>         struct work_struct watchdog_work;
>         void *alloc_ctx[2];
>         unsigned long enter_suspend;
> +
> +       struct s5p_mfc_priv_buf ctx_buf;
>  };
>
>  /**
> @@ -278,6 +325,23 @@ struct s5p_mfc_h264_enc_params {
>         enum v4l2_mpeg_video_h264_level level_v4l2;
>         int level;
>         u16 cpb_size;
> +       int interlace;
> +       u8 hier_qp;
> +       u8 hier_qp_type;
> +       u8 hier_qp_layer;
> +       u8 hier_qp_layer_qp[7];
> +       u8 sei_frame_packing;
> +       u8 sei_fp_curr_frame_0;
> +       u8 sei_fp_arrangement_type;
> +
> +       u8 fmo;
> +       u8 fmo_map_type;
> +       u8 fmo_slice_grp;
> +       u8 fmo_chg_dir;
> +       u32 fmo_chg_rate;
> +       u32 fmo_run_len[4];
> +       u8 aso;
> +       u32 aso_slice_order[8];
>  };
>
>  /**
> @@ -288,8 +352,6 @@ struct s5p_mfc_mpeg4_enc_params {
>         enum v4l2_mpeg_video_mpeg4_profile profile;
>         int quarter_pixel;
>         /* Common for MPEG4, H263 */
> -       u16 vop_time_res;
> -       u16 vop_frm_delta;
>         u8 rc_frame_qp;
>         u8 rc_min_qp;
>         u8 rc_max_qp;
> @@ -316,9 +378,11 @@ struct s5p_mfc_enc_params {
>         u8 pad_cb;
>         u8 pad_cr;
>         int rc_frame;
> +       int rc_mb;
>         u32 rc_bitrate;
>         u16 rc_reaction_coeff;
>         u16 vbv_size;
> +       u32 vbv_delay;
>
>         enum v4l2_mpeg_video_header_mode seq_hdr_mode;
>         enum v4l2_mpeg_mfc51_video_frame_skip_mode frame_skip_mode;
> @@ -327,7 +391,6 @@ struct s5p_mfc_enc_params {
>         u8 num_b_frame;
>         u32 rc_framerate_num;
>         u32 rc_framerate_denom;
> -       int interlace;
>
>         union {
>                 struct s5p_mfc_h264_enc_params h264;
> @@ -470,6 +533,7 @@ struct s5p_mfc_ctx {
>         unsigned long consumed_stream;
>
>         unsigned int dpb_flush_flag;
> +       unsigned int remained;
>
>         /* Buffers */
>         void *bank1_buf;
> @@ -499,37 +563,42 @@ struct s5p_mfc_ctx {
>         int display_delay;
>         int display_delay_enable;
>         int after_packed_pb;
> +       int sei_fp_parse;
>
>         int dpb_count;
>         int total_dpb_count;
>
>         /* Buffers */
> -       void *ctx_buf;
> -       size_t ctx_phys;
> -       size_t ctx_ofs;
> -       size_t ctx_size;
> -
> -       void *desc_buf;
> -       size_t desc_phys;
> -
> -
> -       void *shm_alloc;
> -       void *shm;
> -       size_t shm_ofs;
> +       unsigned int ctx_size;
> +       struct s5p_mfc_priv_buf ctx;
> +       struct s5p_mfc_priv_buf dsc;
> +       struct s5p_mfc_priv_buf shm;
>
>         struct s5p_mfc_enc_params enc_params;
>
>         size_t enc_dst_buf_size;
> +       size_t luma_dpb_size;
> +       size_t chroma_dpb_size;
> +       size_t me_buffer_size;
> +       size_t tmv_buffer_size;
>
>         enum v4l2_mpeg_mfc51_video_force_frame_type force_frame_type;
>
>         struct list_head ref_queue;
>         unsigned int ref_queue_cnt;
>
> +       enum v4l2_mpeg_video_multi_slice_mode slice_mode;
> +       union {
> +               unsigned int mb;
> +               unsigned int bits;
> +       } slice_size;
> +
>         struct s5p_mfc_codec_ops *c_ops;
>
>         struct v4l2_ctrl *ctrls[MFC_MAX_CTRLS];
>         struct v4l2_ctrl_handler ctrl_handler;
> +       unsigned int frame_tag;
> +       size_t scratch_buf_size;
>  };
>
>  /*
> @@ -567,4 +636,18 @@ struct mfc_control {
>  #define ctrl_to_ctx(__ctrl) \
>         container_of((__ctrl)->handler, struct s5p_mfc_ctx, ctrl_handler)
>
> +#define HAS_PORTNUM(dev)       (dev ? (dev->variant ? \
> +                               (dev->variant->port_num ? 1 : 0) : 0) : 0)
> +#define IS_TWOPORT(dev)                (dev->variant->port_num == 2 ? 1 : 0)
> +#define IS_MFCV6(dev)          (dev->variant->version >= 0x60 ? 1 : 0)
> +
> +#if defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC_V5)
> +#include "regs-mfc.h"
> +#include "s5p_mfc_opr.h"
> +#include "s5p_mfc_shm.h"
> +#elif defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC_V6)
> +#include "regs-mfc-v6.h"
> +#include "s5p_mfc_opr_v6.h"
> +#endif
> +
>  #endif /* S5P_MFC_COMMON_H_ */
> diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_ctrl.c b/drivers/media/video/s5p-mfc/s5p_mfc_ctrl.c
> index 08a5cfe..65ff15d 100644
> --- a/drivers/media/video/s5p-mfc/s5p_mfc_ctrl.c
> +++ b/drivers/media/video/s5p-mfc/s5p_mfc_ctrl.c
> @@ -15,7 +15,6 @@
>  #include <linux/firmware.h>
>  #include <linux/jiffies.h>
>  #include <linux/sched.h>
> -#include "regs-mfc.h"
>  #include "s5p_mfc_cmd.h"
>  #include "s5p_mfc_common.h"
>  #include "s5p_mfc_debug.h"
> @@ -38,12 +37,12 @@ int s5p_mfc_alloc_and_load_firmware(struct s5p_mfc_dev *dev)
>          * into kernel. */
>         mfc_debug_enter();
>         err = request_firmware((const struct firmware **)&fw_blob,
> -                                    "s5p-mfc.fw", dev->v4l2_dev.dev);
> +                                    "mfc_fw.bin", dev->v4l2_dev.dev);
>         if (err != 0) {
>                 mfc_err("Firmware is not present in the /lib/firmware directory nor compiled in kernel\n");
>                 return -EINVAL;
>         }
> -       dev->fw_size = ALIGN(fw_blob->size, FIRMWARE_ALIGN);
> +       dev->fw_size = dev->variant->buf_size->fw;
>         if (s5p_mfc_bitproc_buf) {
>                 mfc_err("Attempting to allocate firmware when it seems that it is already loaded\n");
>                 release_firmware(fw_blob);
> @@ -77,28 +76,33 @@ int s5p_mfc_alloc_and_load_firmware(struct s5p_mfc_dev *dev)
>                 return -EIO;
>         }
>         dev->bank1 = s5p_mfc_bitproc_phys;
> -       b_base = vb2_dma_contig_memops.alloc(
> -               dev->alloc_ctx[MFC_BANK2_ALLOC_CTX], 1 << MFC_BANK2_ALIGN_ORDER);
> -       if (IS_ERR(b_base)) {
> -               vb2_dma_contig_memops.put(s5p_mfc_bitproc_buf);
> -               s5p_mfc_bitproc_phys = 0;
> -               s5p_mfc_bitproc_buf = NULL;
> -               mfc_err("Allocating bank2 base failed\n");
> -       release_firmware(fw_blob);
> -               return -ENOMEM;
> -       }
> -       bank2_base_phys = s5p_mfc_mem_cookie(
> -               dev->alloc_ctx[MFC_BANK2_ALLOC_CTX], b_base);
> -       vb2_dma_contig_memops.put(b_base);
> -       if (bank2_base_phys & ((1 << MFC_BASE_ALIGN_ORDER) - 1)) {
> -               mfc_err("The base memory for bank 2 is not aligned to 128KB\n");
> -               vb2_dma_contig_memops.put(s5p_mfc_bitproc_buf);
> -               s5p_mfc_bitproc_phys = 0;
> -               s5p_mfc_bitproc_buf = NULL;
> -               release_firmware(fw_blob);
> -               return -EIO;
> +       if (HAS_PORTNUM(dev) && IS_TWOPORT(dev)) {
> +               b_base = vb2_dma_contig_memops.alloc(
> +                       dev->alloc_ctx[MFC_BANK2_ALLOC_CTX],
> +                       1 << MFC_BANK2_ALIGN_ORDER);
> +               if (IS_ERR(b_base)) {
> +                       vb2_dma_contig_memops.put(s5p_mfc_bitproc_buf);
> +                       s5p_mfc_bitproc_phys = 0;
> +                       s5p_mfc_bitproc_buf = 0;
> +                       mfc_err("Allocating bank2 base failed\n");
> +                       release_firmware(fw_blob);
> +                       return -ENOMEM;
> +               }
> +               bank2_base_phys = s5p_mfc_mem_cookie(
> +                       dev->alloc_ctx[MFC_BANK2_ALLOC_CTX], b_base);
> +               vb2_dma_contig_memops.put(b_base);
> +               if (bank2_base_phys & ((1 << MFC_BASE_ALIGN_ORDER) - 1)) {
> +                       mfc_err("The base memory for bank 2 is not aligned to 128KB\n");
> +                       vb2_dma_contig_memops.put(s5p_mfc_bitproc_buf);
> +                       s5p_mfc_bitproc_phys = 0;
> +                       s5p_mfc_bitproc_buf = 0;
> +                       release_firmware(fw_blob);
> +                       return -EIO;
> +               }
> +               dev->bank2 = bank2_base_phys;
> +       } else {
> +               dev->bank2 = dev->bank1;
>         }
> -       dev->bank2 = bank2_base_phys;
>         memcpy(s5p_mfc_bitproc_virt, fw_blob->data, fw_blob->size);
>         wmb();
>         release_firmware(fw_blob);
> @@ -116,7 +120,7 @@ int s5p_mfc_reload_firmware(struct s5p_mfc_dev *dev)
>          * into kernel. */
>         mfc_debug_enter();
>         err = request_firmware((const struct firmware **)&fw_blob,
> -                                    "s5p-mfc.fw", dev->v4l2_dev.dev);
> +                                    "mfc_fw.bin", dev->v4l2_dev.dev);
>         if (err != 0) {
>                 mfc_err("Firmware is not present in the /lib/firmware directory nor compiled in kernel\n");
>                 return -EINVAL;
> @@ -157,46 +161,81 @@ int s5p_mfc_reset(struct s5p_mfc_dev *dev)
>  {
>         unsigned int mc_status;
>         unsigned long timeout;
> +       int i;
>
>         mfc_debug_enter();
> -       /* Stop procedure */
> -       /*  reset RISC */
> -       mfc_write(dev, 0x3f6, S5P_FIMV_SW_RESET);
> -       /*  All reset except for MC */
> -       mfc_write(dev, 0x3e2, S5P_FIMV_SW_RESET);
> -       mdelay(10);
> -
> -       timeout = jiffies + msecs_to_jiffies(MFC_BW_TIMEOUT);
> -       /* Check MC status */
> -       do {
> -               if (time_after(jiffies, timeout)) {
> -                       mfc_err("Timeout while resetting MFC\n");
> -                       return -EIO;
> -               }
>
> -               mc_status = mfc_read(dev, S5P_FIMV_MC_STATUS);
> +       if (IS_MFCV6(dev)) {
> +               /* Reset IP */
> +               /*  except RISC, reset */
> +               mfc_write(dev, 0xFEE, S5P_FIMV_MFC_RESET);
> +               /*  reset release */
> +               mfc_write(dev, 0x0, S5P_FIMV_MFC_RESET);
>
> -       } while (mc_status & 0x3);
> +               /* Zero Initialization of MFC registers */
> +               mfc_write(dev, 0, S5P_FIMV_RISC2HOST_CMD);
> +               mfc_write(dev, 0, S5P_FIMV_HOST2RISC_CMD);
> +               mfc_write(dev, 0, S5P_FIMV_FW_VERSION);
> +
> +               for (i = 0; i < S5P_FIMV_REG_CLEAR_COUNT; i++)
> +                       mfc_write(dev, 0, S5P_FIMV_REG_CLEAR_BEGIN + (i*4));
> +
> +               /* Reset */
> +               mfc_write(dev, 0, S5P_FIMV_RISC_ON);
> +               mfc_write(dev, 0x1FFF, S5P_FIMV_MFC_RESET);
> +               mfc_write(dev, 0, S5P_FIMV_MFC_RESET);
> +       } else {
> +               /* Stop procedure */
> +               /*  reset RISC */
> +               mfc_write(dev, 0x3f6, S5P_FIMV_SW_RESET);
> +               /*  All reset except for MC */
> +               mfc_write(dev, 0x3e2, S5P_FIMV_SW_RESET);
> +               mdelay(10);
> +
> +               timeout = jiffies + msecs_to_jiffies(MFC_BW_TIMEOUT);
> +               /* Check MC status */
> +               do {
> +                       if (time_after(jiffies, timeout)) {
> +                               mfc_err("Timeout while resetting MFC\n");
> +                               return -EIO;
> +                       }
> +
> +                       mc_status = mfc_read(dev, S5P_FIMV_MC_STATUS);
> +
> +               } while (mc_status & 0x3);
> +
> +               mfc_write(dev, 0x0, S5P_FIMV_SW_RESET);
> +               mfc_write(dev, 0x3fe, S5P_FIMV_SW_RESET);
> +       }
>
> -       mfc_write(dev, 0x0, S5P_FIMV_SW_RESET);
> -       mfc_write(dev, 0x3fe, S5P_FIMV_SW_RESET);
>         mfc_debug_leave();
>         return 0;
>  }
>
>  static inline void s5p_mfc_init_memctrl(struct s5p_mfc_dev *dev)
>  {
> -       mfc_write(dev, dev->bank1, S5P_FIMV_MC_DRAMBASE_ADR_A);
> -       mfc_write(dev, dev->bank2, S5P_FIMV_MC_DRAMBASE_ADR_B);
> -       mfc_debug(2, "Bank1: %08x, Bank2: %08x\n", dev->bank1, dev->bank2);
> +       if (IS_MFCV6(dev)) {
> +               mfc_write(dev, dev->bank1, S5P_FIMV_RISC_BASE_ADDRESS);
> +               mfc_debug(2, "Base Address : %08x\n", dev->bank1);
> +       } else {
> +               mfc_write(dev, dev->bank1, S5P_FIMV_MC_DRAMBASE_ADR_A);
> +               mfc_write(dev, dev->bank2, S5P_FIMV_MC_DRAMBASE_ADR_B);
> +               mfc_debug(2, "Bank1: %08x, Bank2: %08x\n",
> +                               dev->bank1, dev->bank2);
> +       }
>  }
>
>  static inline void s5p_mfc_clear_cmds(struct s5p_mfc_dev *dev)
>  {
> -       mfc_write(dev, 0xffffffff, S5P_FIMV_SI_CH0_INST_ID);
> -       mfc_write(dev, 0xffffffff, S5P_FIMV_SI_CH1_INST_ID);
> -       mfc_write(dev, 0, S5P_FIMV_RISC2HOST_CMD);
> -       mfc_write(dev, 0, S5P_FIMV_HOST2RISC_CMD);
> +       if (IS_MFCV6(dev)) {
> +               /* Zero initialization should be done before RESET.
> +                * Nothing to do here. */
> +       } else {
> +               mfc_write(dev, 0xffffffff, S5P_FIMV_SI_CH0_INST_ID);
> +               mfc_write(dev, 0xffffffff, S5P_FIMV_SI_CH1_INST_ID);
> +               mfc_write(dev, 0, S5P_FIMV_RISC2HOST_CMD);
> +               mfc_write(dev, 0, S5P_FIMV_HOST2RISC_CMD);
> +       }
>  }
>
>  /* Initialize hardware */
> @@ -224,7 +263,10 @@ int s5p_mfc_init_hw(struct s5p_mfc_dev *dev)
>         s5p_mfc_clear_cmds(dev);
>         /* 3. Release reset signal to the RISC */
>         s5p_mfc_clean_dev_int_flags(dev);
> -       mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET);
> +       if (IS_MFCV6(dev))
> +               mfc_write(dev, 0x1, S5P_FIMV_RISC_ON);
> +       else
> +               mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET);
>         mfc_debug(2, "Will now wait for completion of firmware transfer\n");
>         if (s5p_mfc_wait_for_done_dev(dev, S5P_FIMV_R2H_CMD_FW_STATUS_RET)) {
>                 mfc_err("Failed to load firmware\n");
> @@ -267,6 +309,17 @@ int s5p_mfc_init_hw(struct s5p_mfc_dev *dev)
>  }
>
>
> +/* Deinitialize hardware */
> +void s5p_mfc_deinit_hw(struct s5p_mfc_dev *dev)
> +{
> +       s5p_mfc_clock_on();
> +
> +       s5p_mfc_reset(dev);
> +       s5p_mfc_release_dev_context_buffer(dev);
> +
> +       s5p_mfc_clock_off();
> +}
> +
>  int s5p_mfc_sleep(struct s5p_mfc_dev *dev)
>  {
>         int ret;
> @@ -322,7 +375,10 @@ int s5p_mfc_wakeup(struct s5p_mfc_dev *dev)
>                 return ret;
>         }
>         /* 4. Release reset signal to the RISC */
> -       mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET);
> +       if (IS_MFCV6(dev))
> +               mfc_write(dev, 0x1, S5P_FIMV_RISC_ON);
> +       else
> +               mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET);
>         mfc_debug(2, "Ok, now will write a command to wakeup the system\n");
>         if (s5p_mfc_wait_for_done_dev(dev, S5P_FIMV_R2H_CMD_WAKEUP_RET)) {
>                 mfc_err("Failed to load firmware\n");
> diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_ctrl.h b/drivers/media/video/s5p-mfc/s5p_mfc_ctrl.h
> index 61dc23b..b72c8c6 100644
> --- a/drivers/media/video/s5p-mfc/s5p_mfc_ctrl.h
> +++ b/drivers/media/video/s5p-mfc/s5p_mfc_ctrl.h
> @@ -20,6 +20,7 @@ int s5p_mfc_alloc_and_load_firmware(struct s5p_mfc_dev *dev);
>  int s5p_mfc_reload_firmware(struct s5p_mfc_dev *dev);
>
>  int s5p_mfc_init_hw(struct s5p_mfc_dev *dev);
> +void s5p_mfc_deinit_hw(struct s5p_mfc_dev *dev);
>
>  int s5p_mfc_sleep(struct s5p_mfc_dev *dev);
>  int s5p_mfc_wakeup(struct s5p_mfc_dev *dev);
> diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_dec.c b/drivers/media/video/s5p-mfc/s5p_mfc_dec.c
> index 4dd32fc..d4c6cf2 100644
> --- a/drivers/media/video/s5p-mfc/s5p_mfc_dec.c
> +++ b/drivers/media/video/s5p-mfc/s5p_mfc_dec.c
> @@ -23,85 +23,113 @@
>  #include <linux/workqueue.h>
>  #include <media/v4l2-ctrls.h>
>  #include <media/videobuf2-core.h>
> -#include "regs-mfc.h"
>  #include "s5p_mfc_common.h"
>  #include "s5p_mfc_debug.h"
>  #include "s5p_mfc_dec.h"
>  #include "s5p_mfc_intr.h"
> -#include "s5p_mfc_opr.h"
>  #include "s5p_mfc_pm.h"
> -#include "s5p_mfc_shm.h"
> +
> +#define DEF_SRC_FMT    4
> +#define DEF_DST_FMT    0
>
>  static struct s5p_mfc_fmt formats[] = {
>         {
> +               .name           = "4:2:0 2 Planes 16x16 Tiles",
> +               .fourcc         = V4L2_PIX_FMT_NV12MT_16X16,
> +               .codec_mode     = S5P_FIMV_CODEC_NONE,
> +               .type           = MFC_FMT_RAW,
> +               .num_planes     = 2,
> +       },
> +       {
>                 .name           = "4:2:0 2 Planes 64x32 Tiles",
>                 .fourcc         = V4L2_PIX_FMT_NV12MT,
>                 .codec_mode     = S5P_FIMV_CODEC_NONE,
>                 .type           = MFC_FMT_RAW,
>                 .num_planes     = 2,
> -        },
> +       },
> +       {
> +               .name           = "4:2:0 2 Planes Y/CbCr",
> +               .fourcc         = V4L2_PIX_FMT_NV12M,
> +               .codec_mode     = S5P_FIMV_CODEC_NONE,
> +               .type           = MFC_FMT_RAW,
> +               .num_planes     = 2,
> +       },
> +       {
> +               .name           = "4:2:0 2 Planes Y/CrCb",
> +               .fourcc         = V4L2_PIX_FMT_NV21M,
> +               .codec_mode     = S5P_FIMV_CODEC_NONE,
> +               .type           = MFC_FMT_RAW,
> +               .num_planes     = 2,
> +       },
>         {
> -               .name = "4:2:0 2 Planes",
> -               .fourcc = V4L2_PIX_FMT_NV12M,
> -               .codec_mode = S5P_FIMV_CODEC_NONE,
> -               .type = MFC_FMT_RAW,
> -               .num_planes = 2,
> +               .name           = "H264 Encoded Stream",
> +               .fourcc         = V4L2_PIX_FMT_H264,
> +               .codec_mode     = S5P_FIMV_CODEC_H264_DEC,
> +               .type           = MFC_FMT_DEC,
> +               .num_planes     = 1,
>         },
>         {
> -               .name = "H264 Encoded Stream",
> -               .fourcc = V4L2_PIX_FMT_H264,
> -               .codec_mode = S5P_FIMV_CODEC_H264_DEC,
> -               .type = MFC_FMT_DEC,
> -               .num_planes = 1,
> +               .name           = "H264/MVC Encoded Stream",
> +               .fourcc         = V4L2_PIX_FMT_H264_MVC,
> +               .codec_mode     = S5P_FIMV_CODEC_H264_MVC_DEC,
> +               .type           = MFC_FMT_DEC,
> +               .num_planes     = 1,
>         },
>         {
> -               .name = "H263 Encoded Stream",
> -               .fourcc = V4L2_PIX_FMT_H263,
> -               .codec_mode = S5P_FIMV_CODEC_H263_DEC,
> -               .type = MFC_FMT_DEC,
> -               .num_planes = 1,
> +               .name           = "H263 Encoded Stream",
> +               .fourcc         = V4L2_PIX_FMT_H263,
> +               .codec_mode     = S5P_FIMV_CODEC_H263_DEC,
> +               .type           = MFC_FMT_DEC,
> +               .num_planes     = 1,
>         },
>         {
> -               .name = "MPEG1 Encoded Stream",
> -               .fourcc = V4L2_PIX_FMT_MPEG1,
> -               .codec_mode = S5P_FIMV_CODEC_MPEG2_DEC,
> -               .type = MFC_FMT_DEC,
> -               .num_planes = 1,
> +               .name           = "MPEG1 Encoded Stream",
> +               .fourcc         = V4L2_PIX_FMT_MPEG1,
> +               .codec_mode     = S5P_FIMV_CODEC_MPEG2_DEC,
> +               .type           = MFC_FMT_DEC,
> +               .num_planes     = 1,
>         },
>         {
> -               .name = "MPEG2 Encoded Stream",
> -               .fourcc = V4L2_PIX_FMT_MPEG2,
> -               .codec_mode = S5P_FIMV_CODEC_MPEG2_DEC,
> -               .type = MFC_FMT_DEC,
> -               .num_planes = 1,
> +               .name           = "MPEG2 Encoded Stream",
> +               .fourcc         = V4L2_PIX_FMT_MPEG2,
> +               .codec_mode     = S5P_FIMV_CODEC_MPEG2_DEC,
> +               .type           = MFC_FMT_DEC,
> +               .num_planes     = 1,
>         },
>         {
> -               .name = "MPEG4 Encoded Stream",
> -               .fourcc = V4L2_PIX_FMT_MPEG4,
> -               .codec_mode = S5P_FIMV_CODEC_MPEG4_DEC,
> -               .type = MFC_FMT_DEC,
> -               .num_planes = 1,
> +               .name           = "MPEG4 Encoded Stream",
> +               .fourcc         = V4L2_PIX_FMT_MPEG4,
> +               .codec_mode     = S5P_FIMV_CODEC_MPEG4_DEC,
> +               .type           = MFC_FMT_DEC,
> +               .num_planes     = 1,
>         },
>         {
> -               .name = "XviD Encoded Stream",
> -               .fourcc = V4L2_PIX_FMT_XVID,
> -               .codec_mode = S5P_FIMV_CODEC_MPEG4_DEC,
> -               .type = MFC_FMT_DEC,
> -               .num_planes = 1,
> +               .name           = "XviD Encoded Stream",
> +               .fourcc         = V4L2_PIX_FMT_XVID,
> +               .codec_mode     = S5P_FIMV_CODEC_MPEG4_DEC,
> +               .type           = MFC_FMT_DEC,
> +               .num_planes     = 1,
>         },
>         {
> -               .name = "VC1 Encoded Stream",
> -               .fourcc = V4L2_PIX_FMT_VC1_ANNEX_G,
> -               .codec_mode = S5P_FIMV_CODEC_VC1_DEC,
> -               .type = MFC_FMT_DEC,
> -               .num_planes = 1,
> +               .name           = "VC1 Encoded Stream",
> +               .fourcc         = V4L2_PIX_FMT_VC1_ANNEX_G,
> +               .codec_mode     = S5P_FIMV_CODEC_VC1_DEC,
> +               .type           = MFC_FMT_DEC,
> +               .num_planes     = 1,
>         },
>         {
> -               .name = "VC1 RCV Encoded Stream",
> -               .fourcc = V4L2_PIX_FMT_VC1_ANNEX_L,
> -               .codec_mode = S5P_FIMV_CODEC_VC1RCV_DEC,
> -               .type = MFC_FMT_DEC,
> -               .num_planes = 1,
> +               .name           = "VC1 RCV Encoded Stream",
> +               .fourcc         = V4L2_PIX_FMT_VC1_ANNEX_L,
> +               .codec_mode     = S5P_FIMV_CODEC_VC1RCV_DEC,
> +               .type           = MFC_FMT_DEC,
> +               .num_planes     = 1,
> +       },
> +       {
> +               .name           = "VC8 Encoded Stream",
> +               .fourcc         = V4L2_PIX_FMT_VP8,
> +               .codec_mode     = S5P_FIMV_CODEC_VP8_DEC,
> +               .type           = MFC_FMT_DEC,
> +               .num_planes     = 1,
>         },
>  };
>
> @@ -336,21 +364,35 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
>  /* Try format */
>  static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
>  {
> +       struct s5p_mfc_dev *dev = video_drvdata(file);
>         struct s5p_mfc_fmt *fmt;
>
> -       if (f->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
> -               mfc_err("This node supports decoding only\n");
> -               return -EINVAL;
> -       }
> -       fmt = find_format(f, MFC_FMT_DEC);
> -       if (!fmt) {
> -               mfc_err("Unsupported format\n");
> -               return -EINVAL;
> -       }
> -       if (fmt->type != MFC_FMT_DEC) {
> -               mfc_err("\n");
> -               return -EINVAL;
> +       mfc_debug(2, "Type is %d\n", f->type);
> +       if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
> +               fmt = find_format(f, MFC_FMT_DEC);
> +               if (!fmt) {
> +                       mfc_err("Unsupported format for source.\n");
> +                       return -EINVAL;
> +               }
> +               if (!IS_MFCV6(dev) && (fmt->fourcc == V4L2_PIX_FMT_VP8)) {
> +                       mfc_err("Not supported format.\n");
> +                       return -EINVAL;
> +               }
> +       } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
> +               fmt = find_format(f, MFC_FMT_RAW);
> +               if (!fmt) {
> +                       mfc_err("Unsupported format for destination.\n");
> +                       return -EINVAL;
> +               }
> +               if (IS_MFCV6(dev) && (fmt->fourcc == V4L2_PIX_FMT_NV12MT)) {
> +                       mfc_err("Not supported format.\n");
> +                       return -EINVAL;
> +               } else if (fmt->fourcc != V4L2_PIX_FMT_NV12MT) {
> +                       mfc_err("Not supported format.\n");
> +                       return -EINVAL;
> +               }
>         }
> +
>         return 0;
>  }
>
> @@ -373,6 +415,26 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
>                 ret = -EBUSY;
>                 goto out;
>         }
> +       if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
> +               fmt = find_format(f, MFC_FMT_RAW);
> +               if (!fmt) {
> +                       mfc_err("Unsupported format for source.\n");
> +                       return -EINVAL;
> +               }
> +               if (!IS_MFCV6(dev) && (fmt->fourcc != V4L2_PIX_FMT_NV12MT)) {
> +                       mfc_err("Not supported format.\n");
> +                       return -EINVAL;
> +               } else if (IS_MFCV6(dev) && (fmt->fourcc == V4L2_PIX_FMT_NV12MT)) {
> +                       mfc_err("Not supported format.\n");
> +                       return -EINVAL;
> +               }
> +               ctx->dst_fmt = fmt;
> +               mfc_debug_leave();
> +               return ret;
> +       } else if (f->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
> +               mfc_err("Wrong type error for S_FMT : %d", f->type);
> +               return -EINVAL;
> +       }
>         fmt = find_format(f, MFC_FMT_DEC);
>         if (!fmt || fmt->codec_mode == S5P_FIMV_CODEC_NONE) {
>                 mfc_err("Unknown codec\n");
> @@ -385,6 +447,10 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
>                 ret = -EINVAL;
>                 goto out;
>         }
> +       if (!IS_MFCV6(dev) && (fmt->fourcc == V4L2_PIX_FMT_VP8)) {
> +               mfc_err("Not supported format.\n");
> +               return -EINVAL;
> +       }
>         ctx->src_fmt = fmt;
>         ctx->codec_mode = fmt->codec_mode;
>         mfc_debug(2, "The codec number is: %d\n", ctx->codec_mode);
> @@ -498,7 +564,7 @@ static int vidioc_reqbufs(struct file *file, void *priv,
>                 }
>                 s5p_mfc_try_run(dev);
>                 s5p_mfc_wait_for_done_ctx(ctx,
> -                                        S5P_FIMV_R2H_CMD_INIT_BUFFERS_RET, 0);
> +                                       S5P_FIMV_R2H_CMD_INIT_BUFFERS_RET, 0);
>         }
>         return ret;
>  }
> @@ -696,10 +762,10 @@ static int vidioc_g_crop(struct file *file, void *priv,
>                         return -EINVAL;
>                 }
>         if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_H264) {
> -               left = s5p_mfc_read_shm(ctx, CROP_INFO_H);
> +               left = s5p_mfc_read_info(ctx, CROP_INFO_H);
>                 right = left >> S5P_FIMV_SHARED_CROP_RIGHT_SHIFT;
>                 left = left & S5P_FIMV_SHARED_CROP_LEFT_MASK;
> -               top = s5p_mfc_read_shm(ctx, CROP_INFO_V);
> +               top = s5p_mfc_read_info(ctx, CROP_INFO_V);
>                 bottom = top >> S5P_FIMV_SHARED_CROP_BOTTOM_SHIFT;
>                 top = top & S5P_FIMV_SHARED_CROP_TOP_MASK;
>                 cr->c.left = left;
> @@ -750,6 +816,7 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq,
>                         void *allocators[])
>  {
>         struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);
> +       struct s5p_mfc_dev *dev = ctx->dev;
>
>         /* Video output for decoding (source)
>          * this can be set after getting an instance */
> @@ -785,7 +852,13 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq,
>             vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
>                 psize[0] = ctx->luma_size;
>                 psize[1] = ctx->chroma_size;
> -               allocators[0] = ctx->dev->alloc_ctx[MFC_BANK2_ALLOC_CTX];
> +
> +               if (IS_MFCV6(dev))
> +                       allocators[0] =
> +                               ctx->dev->alloc_ctx[MFC_BANK1_ALLOC_CTX];
> +               else
> +                       allocators[0] =
> +                               ctx->dev->alloc_ctx[MFC_BANK2_ALLOC_CTX];
>                 allocators[1] = ctx->dev->alloc_ctx[MFC_BANK1_ALLOC_CTX];
>         } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
>                    ctx->state == MFCINST_INIT) {
> @@ -1035,3 +1108,10 @@ void s5p_mfc_dec_ctrls_delete(struct s5p_mfc_ctx *ctx)
>                 ctx->ctrls[i] = NULL;
>  }
>
> +void s5p_mfc_dec_init(struct s5p_mfc_ctx *ctx)
> +{
> +       ctx->src_fmt = &formats[DEF_SRC_FMT];
> +       ctx->dst_fmt = &formats[DEF_DST_FMT];
> +       mfc_debug(2, "Default src_fmt is %x, dest_fmt is %x\n",
> +                       (unsigned int)ctx->src_fmt, (unsigned int)ctx->dst_fmt);
> +}
> diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_dec.h b/drivers/media/video/s5p-mfc/s5p_mfc_dec.h
> index fb8b215..c53baf8 100644
> --- a/drivers/media/video/s5p-mfc/s5p_mfc_dec.h
> +++ b/drivers/media/video/s5p-mfc/s5p_mfc_dec.h
> @@ -19,5 +19,6 @@ const struct v4l2_ioctl_ops *get_dec_v4l2_ioctl_ops(void);
>  struct s5p_mfc_fmt *get_dec_def_fmt(bool src);
>  int s5p_mfc_dec_ctrls_setup(struct s5p_mfc_ctx *ctx);
>  void s5p_mfc_dec_ctrls_delete(struct s5p_mfc_ctx *ctx);
> +void s5p_mfc_dec_init(struct s5p_mfc_ctx *ctx);
>
>  #endif /* S5P_MFC_DEC_H_ */
> diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c b/drivers/media/video/s5p-mfc/s5p_mfc_enc.c
> index 03d8334..645a8ef 100644
> --- a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c
> +++ b/drivers/media/video/s5p-mfc/s5p_mfc_enc.c
> @@ -24,48 +24,63 @@
>  #include <linux/workqueue.h>
>  #include <media/v4l2-ctrls.h>
>  #include <media/videobuf2-core.h>
> -#include "regs-mfc.h"
>  #include "s5p_mfc_common.h"
>  #include "s5p_mfc_debug.h"
>  #include "s5p_mfc_enc.h"
>  #include "s5p_mfc_intr.h"
> -#include "s5p_mfc_opr.h"
> +
> +#define DEF_SRC_FMT    2
> +#define DEF_DST_FMT    4
>
>  static struct s5p_mfc_fmt formats[] = {
>         {
> -               .name = "4:2:0 2 Planes 64x32 Tiles",
> -               .fourcc = V4L2_PIX_FMT_NV12MT,
> -               .codec_mode = S5P_FIMV_CODEC_NONE,
> -               .type = MFC_FMT_RAW,
> -               .num_planes = 2,
> +               .name           = "4:2:0 2 Planes 16x16 Tiles",
> +               .fourcc         = V4L2_PIX_FMT_NV12MT_16X16,
> +               .codec_mode     = S5P_FIMV_CODEC_NONE,
> +               .type           = MFC_FMT_RAW,
> +               .num_planes     = 2,
> +       },
> +       {
> +               .name           = "4:2:0 2 Planes 64x32 Tiles",
> +               .fourcc         = V4L2_PIX_FMT_NV12MT,
> +               .codec_mode     = S5P_FIMV_CODEC_NONE,
> +               .type           = MFC_FMT_RAW,
> +               .num_planes     = 2,
> +       },
> +       {
> +               .name           = "4:2:0 2 Planes Y/CbCr",
> +               .fourcc         = V4L2_PIX_FMT_NV12M,
> +               .codec_mode     = S5P_FIMV_CODEC_NONE,
> +               .type           = MFC_FMT_RAW,
> +               .num_planes     = 2,
>         },
>         {
> -               .name = "4:2:0 2 Planes",
> -               .fourcc = V4L2_PIX_FMT_NV12M,
> -               .codec_mode = S5P_FIMV_CODEC_NONE,
> -               .type = MFC_FMT_RAW,
> -               .num_planes = 2,
> +               .name           = "4:2:0 2 Planes Y/CrCb",
> +               .fourcc         = V4L2_PIX_FMT_NV21M,
> +               .codec_mode     = S5P_FIMV_CODEC_NONE,
> +               .type           = MFC_FMT_RAW,
> +               .num_planes     = 2,
>         },
>         {
> -               .name = "H264 Encoded Stream",
> -               .fourcc = V4L2_PIX_FMT_H264,
> -               .codec_mode = S5P_FIMV_CODEC_H264_ENC,
> -               .type = MFC_FMT_ENC,
> -               .num_planes = 1,
> +               .name           = "H264 Encoded Stream",
> +               .fourcc         = V4L2_PIX_FMT_H264,
> +               .codec_mode     = S5P_FIMV_CODEC_H264_ENC,
> +               .type           = MFC_FMT_ENC,
> +               .num_planes     = 1,
>         },
>         {
> -               .name = "MPEG4 Encoded Stream",
> -               .fourcc = V4L2_PIX_FMT_MPEG4,
> -               .codec_mode = S5P_FIMV_CODEC_MPEG4_ENC,
> -               .type = MFC_FMT_ENC,
> -               .num_planes = 1,
> +               .name           = "MPEG4 Encoded Stream",
> +               .fourcc         = V4L2_PIX_FMT_MPEG4,
> +               .codec_mode     = S5P_FIMV_CODEC_MPEG4_ENC,
> +               .type           = MFC_FMT_ENC,
> +               .num_planes     = 1,
>         },
>         {
> -               .name = "H263 Encoded Stream",
> -               .fourcc = V4L2_PIX_FMT_H263,
> -               .codec_mode = S5P_FIMV_CODEC_H263_ENC,
> -               .type = MFC_FMT_ENC,
> -               .num_planes = 1,
> +               .name           = "H263 Encoded Stream",
> +               .fourcc         = V4L2_PIX_FMT_H263,
> +               .codec_mode     = S5P_FIMV_CODEC_H263_ENC,
> +               .type           = MFC_FMT_ENC,
> +               .num_planes     = 1,
>         },
>  };
>
> @@ -641,13 +656,22 @@ static int enc_post_seq_start(struct s5p_mfc_ctx *ctx)
>                 vb2_buffer_done(dst_mb->b, VB2_BUF_STATE_DONE);
>                 spin_unlock_irqrestore(&dev->irqlock, flags);
>         }
> -       ctx->state = MFCINST_RUNNING;
> -       if (s5p_mfc_ctx_ready(ctx)) {
> -               spin_lock_irqsave(&dev->condlock, flags);
> -               set_bit(ctx->num, &dev->ctx_work_bits);
> -               spin_unlock_irqrestore(&dev->condlock, flags);
> +
> +       if (IS_MFCV6(dev)) {
> +               ctx->state = MFCINST_HEAD_PARSED; /* for INIT_BUFFER cmd */
> +       } else {
> +               ctx->state = MFCINST_RUNNING;
> +               if (s5p_mfc_ctx_ready(ctx)) {
> +                       spin_lock_irqsave(&dev->condlock, flags);
> +                       set_bit(ctx->num, &dev->ctx_work_bits);
> +                       spin_unlock_irqrestore(&dev->condlock, flags);
> +               }
> +               s5p_mfc_try_run(dev);
>         }
> -       s5p_mfc_try_run(dev);
> +
> +       if (IS_MFCV6(dev))
> +               ctx->dpb_count = s5p_mfc_get_enc_dpb_count();
> +
>         return 0;
>  }
>
> @@ -961,6 +985,17 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
>                         mfc_err("failed to set output format\n");
>                         return -EINVAL;
>                 }
> +
> +               if (!IS_MFCV6(dev) &&
> +                               (fmt->fourcc == V4L2_PIX_FMT_NV12MT_16X16)) {
> +                       mfc_err("Not supported format.\n");
> +                       return -EINVAL;
> +               } else if (IS_MFCV6(dev) &&
> +                               (fmt->fourcc == V4L2_PIX_FMT_NV12MT)) {
> +                       mfc_err("Not supported format.\n");
> +                       return -EINVAL;
> +               }
> +
>                 if (fmt->num_planes != pix_fmt_mp->num_planes) {
>                         mfc_err("failed to set output format\n");
>                         ret = -EINVAL;
> @@ -973,45 +1008,13 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
>                 mfc_debug(2, "fmt - w: %d, h: %d, ctx - w: %d, h: %d\n",
>                         pix_fmt_mp->width, pix_fmt_mp->height,
>                         ctx->img_width, ctx->img_height);
> -               if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12M) {
> -                       ctx->buf_width = ALIGN(ctx->img_width,
> -                                                       S5P_FIMV_NV12M_HALIGN);
> -                       ctx->luma_size = ALIGN(ctx->img_width,
> -                               S5P_FIMV_NV12M_HALIGN) * ALIGN(ctx->img_height,
> -                               S5P_FIMV_NV12M_LVALIGN);
> -                       ctx->chroma_size = ALIGN(ctx->img_width,
> -                               S5P_FIMV_NV12M_HALIGN) * ALIGN((ctx->img_height
> -                               >> 1), S5P_FIMV_NV12M_CVALIGN);
> -
> -                       ctx->luma_size = ALIGN(ctx->luma_size,
> -                                                       S5P_FIMV_NV12M_SALIGN);
> -                       ctx->chroma_size = ALIGN(ctx->chroma_size,
> -                                                       S5P_FIMV_NV12M_SALIGN);
> -
> -                       pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size;
> -                       pix_fmt_mp->plane_fmt[0].bytesperline = ctx->buf_width;
> -                       pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
> -                       pix_fmt_mp->plane_fmt[1].bytesperline = ctx->buf_width;
> -
> -               } else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12MT) {
> -                       ctx->buf_width = ALIGN(ctx->img_width,
> -                                                       S5P_FIMV_NV12MT_HALIGN);
> -                       ctx->luma_size = ALIGN(ctx->img_width,
> -                               S5P_FIMV_NV12MT_HALIGN) * ALIGN(ctx->img_height,
> -                               S5P_FIMV_NV12MT_VALIGN);
> -                       ctx->chroma_size = ALIGN(ctx->img_width,
> -                               S5P_FIMV_NV12MT_HALIGN) * ALIGN((ctx->img_height
> -                               >> 1), S5P_FIMV_NV12MT_VALIGN);
> -                       ctx->luma_size = ALIGN(ctx->luma_size,
> -                                                       S5P_FIMV_NV12MT_SALIGN);
> -                       ctx->chroma_size = ALIGN(ctx->chroma_size,
> -                                                       S5P_FIMV_NV12MT_SALIGN);
> -
> -                       pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size;
> -                       pix_fmt_mp->plane_fmt[0].bytesperline = ctx->buf_width;
> -                       pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
> -                       pix_fmt_mp->plane_fmt[1].bytesperline = ctx->buf_width;
> -               }
> +
> +               s5p_mfc_enc_calc_src_size(ctx);
> +               pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size;
> +               pix_fmt_mp->plane_fmt[0].bytesperline = ctx->buf_width;
> +               pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
> +               pix_fmt_mp->plane_fmt[1].bytesperline = ctx->buf_width;
> +
>                 ctx->src_bufs_cnt = 0;
>                 ctx->output_state = QUEUE_FREE;
>         } else {
> @@ -1026,6 +1029,7 @@ out:
>  static int vidioc_reqbufs(struct file *file, void *priv,
>                                           struct v4l2_requestbuffers *reqbufs)
>  {
> +       struct s5p_mfc_dev *dev = video_drvdata(file);
>         struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
>         int ret = 0;
>
> @@ -1045,12 +1049,15 @@ static int vidioc_reqbufs(struct file *file, void *priv,
>                         return ret;
>                 }
>                 ctx->capture_state = QUEUE_BUFS_REQUESTED;
> -               ret = s5p_mfc_alloc_codec_buffers(ctx);
> -               if (ret) {
> -                       mfc_err("Failed to allocate encoding buffers\n");
> -                       reqbufs->count = 0;
> -                       ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
> -                       return -ENOMEM;
> +
> +               if (!IS_MFCV6(dev)) {
> +                       ret = s5p_mfc_alloc_codec_buffers(ctx);
> +                       if (ret) {
> +                               mfc_err("Failed to allocate encoding buffers\n");
> +                               reqbufs->count = 0;
> +                               ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
> +                               return -ENOMEM;
> +                       }
>                 }
>         } else if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
>                 if (ctx->output_state != QUEUE_FREE) {
> @@ -1297,6 +1304,13 @@ static int s5p_mfc_enc_s_ctrl(struct v4l2_ctrl *ctrl)
>                         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;
>                 }
> @@ -1516,6 +1530,7 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq,
>                         unsigned int psize[], void *allocators[])
>  {
>         struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);
> +       struct s5p_mfc_dev *dev = ctx->dev;
>
>         if (ctx->state != MFCINST_GOT_INST) {
>                 mfc_err("inavlid state: %d\n", ctx->state);
> @@ -1544,8 +1559,17 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq,
>                         *buf_count = MFC_MAX_BUFFERS;
>                 psize[0] = ctx->luma_size;
>                 psize[1] = ctx->chroma_size;
> -               allocators[0] = ctx->dev->alloc_ctx[MFC_BANK2_ALLOC_CTX];
> -               allocators[1] = ctx->dev->alloc_ctx[MFC_BANK2_ALLOC_CTX];
> +               if (IS_MFCV6(dev)) {
> +                       allocators[0] =
> +                               ctx->dev->alloc_ctx[MFC_BANK1_ALLOC_CTX];
> +                       allocators[1] =
> +                               ctx->dev->alloc_ctx[MFC_BANK1_ALLOC_CTX];
> +               } else {
> +                       allocators[0] =
> +                               ctx->dev->alloc_ctx[MFC_BANK2_ALLOC_CTX];
> +                       allocators[1] =
> +                               ctx->dev->alloc_ctx[MFC_BANK2_ALLOC_CTX];
> +               }
>         } else {
>                 mfc_err("inavlid queue type: %d\n", vq->type);
>                 return -EINVAL;
> @@ -1826,3 +1850,10 @@ void s5p_mfc_enc_ctrls_delete(struct s5p_mfc_ctx *ctx)
>         for (i = 0; i < NUM_CTRLS; i++)
>                 ctx->ctrls[i] = NULL;
>  }
> +
> +void s5p_mfc_enc_init(struct s5p_mfc_ctx *ctx)
> +{
> +       ctx->src_fmt = &formats[DEF_SRC_FMT];
> +       ctx->dst_fmt = &formats[DEF_DST_FMT];
> +}
> +
> diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_enc.h b/drivers/media/video/s5p-mfc/s5p_mfc_enc.h
> index 405bdd3..413f22f 100644
> --- a/drivers/media/video/s5p-mfc/s5p_mfc_enc.h
> +++ b/drivers/media/video/s5p-mfc/s5p_mfc_enc.h
> @@ -19,5 +19,6 @@ const struct v4l2_ioctl_ops *get_enc_v4l2_ioctl_ops(void);
>  struct s5p_mfc_fmt *get_enc_def_fmt(bool src);
>  int s5p_mfc_enc_ctrls_setup(struct s5p_mfc_ctx *ctx);
>  void s5p_mfc_enc_ctrls_delete(struct s5p_mfc_ctx *ctx);
> +void s5p_mfc_enc_init(struct s5p_mfc_ctx *ctx);
>
>  #endif /* S5P_MFC_ENC_H_  */
> diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_intr.c b/drivers/media/video/s5p-mfc/s5p_mfc_intr.c
> index 8f2f8bf..dfdc558 100644
> --- a/drivers/media/video/s5p-mfc/s5p_mfc_intr.c
> +++ b/drivers/media/video/s5p-mfc/s5p_mfc_intr.c
> @@ -17,7 +17,6 @@
>  #include <linux/io.h>
>  #include <linux/sched.h>
>  #include <linux/wait.h>
> -#include "regs-mfc.h"
>  #include "s5p_mfc_common.h"
>  #include "s5p_mfc_debug.h"
>  #include "s5p_mfc_intr.h"
> diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_opr.c b/drivers/media/video/s5p-mfc/s5p_mfc_opr.c
> index e6217cb..1fd9c92 100644
> --- a/drivers/media/video/s5p-mfc/s5p_mfc_opr.c
> +++ b/drivers/media/video/s5p-mfc/s5p_mfc_opr.c
> @@ -12,15 +12,12 @@
>   * published by the Free Software Foundation.
>   */
>
> -#include "regs-mfc.h"
> -#include "s5p_mfc_cmd.h"
>  #include "s5p_mfc_common.h"
> +#include "s5p_mfc_cmd.h"
>  #include "s5p_mfc_ctrl.h"
>  #include "s5p_mfc_debug.h"
>  #include "s5p_mfc_intr.h"
> -#include "s5p_mfc_opr.h"
>  #include "s5p_mfc_pm.h"
> -#include "s5p_mfc_shm.h"
>  #include <asm/cacheflush.h>
>  #include <linux/delay.h>
>  #include <linux/dma-mapping.h>
> @@ -37,39 +34,31 @@
>  /* Allocate temporary buffers for decoding */
>  int s5p_mfc_alloc_dec_temp_buffers(struct s5p_mfc_ctx *ctx)
>  {
> -       void *desc_virt;
>         struct s5p_mfc_dev *dev = ctx->dev;
> +       struct s5p_mfc_buf_size_v5 *buf_size = dev->variant->buf_size->priv;
>
> -       ctx->desc_buf = vb2_dma_contig_memops.alloc(
> -                       dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], DESC_BUF_SIZE);
> -       if (IS_ERR_VALUE((int)ctx->desc_buf)) {
> -               ctx->desc_buf = NULL;
> +       ctx->dsc.alloc = vb2_dma_contig_memops.alloc(
> +                       dev->alloc_ctx[MFC_BANK1_ALLOC_CTX],
> +                       buf_size->dsc);
> +       if (IS_ERR_VALUE((int)ctx->dsc.alloc)) {
> +               ctx->dsc.alloc = NULL;
>                 mfc_err("Allocating DESC buffer failed\n");
>                 return -ENOMEM;
>         }
> -       ctx->desc_phys = s5p_mfc_mem_cookie(
> -                       dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->desc_buf);
> -       BUG_ON(ctx->desc_phys & ((1 << MFC_BANK1_ALIGN_ORDER) - 1));
> -       desc_virt = vb2_dma_contig_memops.vaddr(ctx->desc_buf);
> -       if (desc_virt == NULL) {
> -               vb2_dma_contig_memops.put(ctx->desc_buf);
> -               ctx->desc_phys = 0;
> -               ctx->desc_buf = NULL;
> -               mfc_err("Remapping DESC buffer failed\n");
> -               return -ENOMEM;
> -       }
> -       memset(desc_virt, 0, DESC_BUF_SIZE);
> -       wmb();
> +       ctx->dsc.dma = s5p_mfc_mem_cookie(
> +                       dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->dsc.alloc);
> +       BUG_ON(ctx->dsc.dma & ((1 << MFC_BANK1_ALIGN_ORDER) - 1));
> +
>         return 0;
>  }
>
>  /* Release temporary buffers for decoding */
>  void s5p_mfc_release_dec_desc_buffer(struct s5p_mfc_ctx *ctx)
>  {
> -       if (ctx->desc_phys) {
> -               vb2_dma_contig_memops.put(ctx->desc_buf);
> -               ctx->desc_phys = 0;
> -               ctx->desc_buf = NULL;
> +       if (ctx->dsc.dma) {
> +               vb2_dma_contig_memops.put(ctx->dsc.alloc);
> +               ctx->dsc.alloc = NULL;
> +               ctx->dsc.dma = 0;
>         }
>  }
>
> @@ -231,41 +220,43 @@ void s5p_mfc_release_codec_buffers(struct s5p_mfc_ctx *ctx)
>  /* Allocate memory for instance data buffer */
>  int s5p_mfc_alloc_instance_buffer(struct s5p_mfc_ctx *ctx)
>  {
> -       void *context_virt;
>         struct s5p_mfc_dev *dev = ctx->dev;
> +       struct s5p_mfc_buf_size_v5 *buf_size = dev->variant->buf_size->priv;
>
>         if (ctx->codec_mode == S5P_FIMV_CODEC_H264_DEC ||
>                 ctx->codec_mode == S5P_FIMV_CODEC_H264_ENC)
> -               ctx->ctx_size = MFC_H264_CTX_BUF_SIZE;
> +               ctx->ctx_size = buf_size->h264_ctx;
>         else
> -               ctx->ctx_size = MFC_CTX_BUF_SIZE;
> -       ctx->ctx_buf = vb2_dma_contig_memops.alloc(
> +               ctx->ctx_size = buf_size->non_h264_ctx;
> +       ctx->ctx.alloc = vb2_dma_contig_memops.alloc(
>                 dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->ctx_size);
> -       if (IS_ERR(ctx->ctx_buf)) {
> +       if (IS_ERR(ctx->ctx.alloc)) {
>                 mfc_err("Allocating context buffer failed\n");
> -               ctx->ctx_phys = 0;
> -               ctx->ctx_buf = NULL;
> +               ctx->ctx.alloc = NULL;
>                 return -ENOMEM;
>         }
> -       ctx->ctx_phys = s5p_mfc_mem_cookie(
> -               dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->ctx_buf);
> -       BUG_ON(ctx->ctx_phys & ((1 << MFC_BANK1_ALIGN_ORDER) - 1));
> -       ctx->ctx_ofs = OFFSETA(ctx->ctx_phys);
> -       context_virt = vb2_dma_contig_memops.vaddr(ctx->ctx_buf);
> -       if (context_virt == NULL) {
> +       ctx->ctx.dma = s5p_mfc_mem_cookie(
> +               dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->ctx.alloc);
> +       BUG_ON(ctx->ctx.dma & ((1 << MFC_BANK1_ALIGN_ORDER) - 1));
> +       ctx->ctx.ofs = OFFSETA(ctx->ctx.dma);
> +       ctx->ctx.virt = vb2_dma_contig_memops.vaddr(ctx->ctx.alloc);
> +       if (!ctx->ctx.virt) {
>                 mfc_err("Remapping instance buffer failed\n");
> -               vb2_dma_contig_memops.put(ctx->ctx_buf);
> -               ctx->ctx_phys = 0;
> -               ctx->ctx_buf = NULL;
> +               vb2_dma_contig_memops.put(ctx->ctx.alloc);
> +               ctx->ctx.alloc = NULL;
> +               ctx->ctx.ofs = 0;
> +               ctx->ctx.dma = 0;
>                 return -ENOMEM;
>         }
>         /* Zero content of the allocated memory */
> -       memset(context_virt, 0, ctx->ctx_size);
> +       memset(ctx->ctx.virt, 0, ctx->ctx_size);
>         wmb();
>         if (s5p_mfc_init_shm(ctx) < 0) {
> -               vb2_dma_contig_memops.put(ctx->ctx_buf);
> -               ctx->ctx_phys = 0;
> -               ctx->ctx_buf = NULL;
> +               vb2_dma_contig_memops.put(ctx->ctx.alloc);
> +               ctx->ctx.alloc = NULL;
> +               ctx->ctx.ofs = 0;
> +               ctx->ctx.virt = NULL;
> +               ctx->ctx.dma = 0;
>                 return -ENOMEM;
>         }
>         return 0;
> @@ -274,15 +265,100 @@ int s5p_mfc_alloc_instance_buffer(struct s5p_mfc_ctx *ctx)
>  /* Release instance buffer */
>  void s5p_mfc_release_instance_buffer(struct s5p_mfc_ctx *ctx)
>  {
> -       if (ctx->ctx_buf) {
> -               vb2_dma_contig_memops.put(ctx->ctx_buf);
> -               ctx->ctx_phys = 0;
> -               ctx->ctx_buf = NULL;
> +       if (ctx->ctx.alloc) {
> +               vb2_dma_contig_memops.put(ctx->ctx.alloc);
> +               ctx->ctx.alloc = NULL;
> +               ctx->ctx.ofs = 0;
> +               ctx->ctx.virt = NULL;
> +               ctx->ctx.dma = 0;
>         }
> -       if (ctx->shm_alloc) {
> -               vb2_dma_contig_memops.put(ctx->shm_alloc);
> -               ctx->shm_alloc = NULL;
> -               ctx->shm = NULL;
> +       if (ctx->shm.alloc) {
> +               vb2_dma_contig_memops.put(ctx->shm.alloc);
> +               ctx->shm.alloc = NULL;
> +               ctx->shm.ofs = 0;
> +               ctx->shm.virt = NULL;
> +       }
> +}
> +
> +int s5p_mfc_alloc_dev_context_buffer(struct s5p_mfc_dev *dev)
> +{
> +       /* NOP */
> +
> +       return 0;
> +}
> +
> +void s5p_mfc_release_dev_context_buffer(struct s5p_mfc_dev *dev)
> +{
> +       /* NOP */
> +}
> +
> +void s5p_mfc_dec_calc_dpb_size(struct s5p_mfc_ctx *ctx)
> +{
> +       unsigned int guard_width, guard_height;
> +
> +       ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN);
> +       ctx->buf_height = ALIGN(ctx->img_height, S5P_FIMV_NV12MT_VALIGN);
> +       mfc_debug(2,
> +               "SEQ Done: Movie dimensions %dx%d, buffer dimensions: %dx%d\n",
> +               ctx->img_width, ctx->img_height, ctx->buf_width,
> +               ctx->buf_height);
> +
> +       if (ctx->codec_mode == S5P_FIMV_CODEC_H264_DEC) {
> +               ctx->luma_size = ALIGN(ctx->buf_width * ctx->buf_height,
> +                               S5P_FIMV_DEC_BUF_ALIGN);
> +               ctx->chroma_size = ALIGN(ctx->buf_width *
> +                               ALIGN((ctx->img_height >> 1),
> +                                       S5P_FIMV_NV12MT_VALIGN),
> +                               S5P_FIMV_DEC_BUF_ALIGN);
> +               ctx->mv_size = ALIGN(ctx->buf_width *
> +                               ALIGN((ctx->buf_height >> 2),
> +                                       S5P_FIMV_NV12MT_VALIGN),
> +                               S5P_FIMV_DEC_BUF_ALIGN);
> +       } else {
> +               guard_width =
> +                       ALIGN(ctx->img_width + 24, S5P_FIMV_NV12MT_HALIGN);
> +               guard_height =
> +                       ALIGN(ctx->img_height + 16, S5P_FIMV_NV12MT_VALIGN);
> +               ctx->luma_size = ALIGN(guard_width * guard_height,
> +                               S5P_FIMV_DEC_BUF_ALIGN);
> +
> +               guard_width =
> +                       ALIGN(ctx->img_width + 16, S5P_FIMV_NV12MT_HALIGN);
> +               guard_height =
> +                       ALIGN((ctx->img_height >> 1) + 4,
> +                                       S5P_FIMV_NV12MT_VALIGN);
> +               ctx->chroma_size = ALIGN(guard_width * guard_height,
> +                               S5P_FIMV_DEC_BUF_ALIGN);
> +
> +               ctx->mv_size = 0;
> +       }
> +}
> +
> +void s5p_mfc_enc_calc_src_size(struct s5p_mfc_ctx *ctx)
> +{
> +       if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12M) {
> +               ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12M_HALIGN);
> +
> +               ctx->luma_size = ALIGN(ctx->img_width, S5P_FIMV_NV12M_HALIGN)
> +                       * ALIGN(ctx->img_height, S5P_FIMV_NV12M_LVALIGN);
> +               ctx->chroma_size = ALIGN(ctx->img_width, S5P_FIMV_NV12M_HALIGN)
> +                       * ALIGN((ctx->img_height >> 1), S5P_FIMV_NV12M_CVALIGN);
> +
> +               ctx->luma_size = ALIGN(ctx->luma_size, S5P_FIMV_NV12M_SALIGN);
> +               ctx->chroma_size =
> +                       ALIGN(ctx->chroma_size, S5P_FIMV_NV12M_SALIGN);
> +       } else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12MT) {
> +               ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN);
> +
> +               ctx->luma_size = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN)
> +                       * ALIGN(ctx->img_height, S5P_FIMV_NV12MT_VALIGN);
> +               ctx->chroma_size =
> +                       ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN)
> +                       * ALIGN((ctx->img_height >> 1), S5P_FIMV_NV12MT_VALIGN);
> +
> +               ctx->luma_size = ALIGN(ctx->luma_size, S5P_FIMV_NV12MT_SALIGN);
> +               ctx->chroma_size =
> +                       ALIGN(ctx->chroma_size, S5P_FIMV_NV12MT_SALIGN);
>         }
>  }
>
> @@ -290,16 +366,17 @@ void s5p_mfc_release_instance_buffer(struct s5p_mfc_ctx *ctx)
>  void s5p_mfc_set_dec_desc_buffer(struct s5p_mfc_ctx *ctx)
>  {
>         struct s5p_mfc_dev *dev = ctx->dev;
> +       struct s5p_mfc_buf_size_v5 *buf_size = dev->variant->buf_size->priv;
>
> -       mfc_write(dev, OFFSETA(ctx->desc_phys), S5P_FIMV_SI_CH0_DESC_ADR);
> -       mfc_write(dev, DESC_BUF_SIZE, S5P_FIMV_SI_CH0_DESC_SIZE);
> +       mfc_write(dev, OFFSETA(ctx->dsc.dma), S5P_FIMV_SI_CH0_DESC_ADR);
> +       mfc_write(dev, buf_size->dsc, S5P_FIMV_SI_CH0_DESC_SIZE);
>  }
>
>  /* Set registers for shared buffer */
>  static void s5p_mfc_set_shared_buffer(struct s5p_mfc_ctx *ctx)
>  {
>         struct s5p_mfc_dev *dev = ctx->dev;
> -       mfc_write(dev, ctx->shm_ofs, S5P_FIMV_SI_CH0_HOST_WR_ADR);
> +       mfc_write(dev, ctx->shm.ofs, S5P_FIMV_SI_CH0_HOST_WR_ADR);
>  }
>
>  /* Set registers for decoding stream buffer */
> @@ -311,7 +388,7 @@ int s5p_mfc_set_dec_stream_buffer(struct s5p_mfc_ctx *ctx, int buf_addr,
>         mfc_write(dev, OFFSETA(buf_addr), S5P_FIMV_SI_CH0_SB_ST_ADR);
>         mfc_write(dev, ctx->dec_src_buf_size, S5P_FIMV_SI_CH0_CPB_SIZE);
>         mfc_write(dev, buf_size, S5P_FIMV_SI_CH0_SB_FRM_SIZE);
> -       s5p_mfc_write_shm(ctx, start_num_byte, START_BYTE_NUM);
> +       s5p_mfc_write_info(ctx, start_num_byte, START_BYTE_NUM);
>         return 0;
>  }
>
> @@ -438,10 +515,10 @@ int s5p_mfc_set_dec_frame_buffer(struct s5p_mfc_ctx *ctx)
>                 mfc_debug(2, "Not enough memory has been allocated\n");
>                 return -ENOMEM;
>         }
> -       s5p_mfc_write_shm(ctx, frame_size, ALLOC_LUMA_DPB_SIZE);
> -       s5p_mfc_write_shm(ctx, frame_size_ch, ALLOC_CHROMA_DPB_SIZE);
> +       s5p_mfc_write_info(ctx, frame_size, ALLOC_LUMA_DPB_SIZE);
> +       s5p_mfc_write_info(ctx, frame_size_ch, ALLOC_CHROMA_DPB_SIZE);
>         if (ctx->codec_mode == S5P_FIMV_CODEC_H264_DEC)
> -               s5p_mfc_write_shm(ctx, frame_size_mv, ALLOC_MV_SIZE);
> +               s5p_mfc_write_info(ctx, frame_size_mv, ALLOC_MV_SIZE);
>         mfc_write(dev, ((S5P_FIMV_CH_INIT_BUFS & S5P_FIMV_CH_MASK)
>                                         << S5P_FIMV_CH_SHIFT) | (ctx->inst_no),
>                                                 S5P_FIMV_SI_CH0_INST_ID);
> @@ -685,16 +762,16 @@ static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx)
>         /* reaction coefficient */
>         if (p->rc_frame)
>                 mfc_write(dev, p->rc_reaction_coeff, S5P_FIMV_ENC_RC_RPARA);
> -       shm = s5p_mfc_read_shm(ctx, EXT_ENC_CONTROL);
> +       shm = s5p_mfc_read_info(ctx, EXT_ENC_CONTROL);
>         /* seq header ctrl */
>         shm &= ~(0x1 << 3);
>         shm |= (p->seq_hdr_mode << 3);
>         /* frame skip mode */
>         shm &= ~(0x3 << 1);
>         shm |= (p->frame_skip_mode << 1);
> -       s5p_mfc_write_shm(ctx, shm, EXT_ENC_CONTROL);
> +       s5p_mfc_write_info(ctx, shm, EXT_ENC_CONTROL);
>         /* fixed target bit */
> -       s5p_mfc_write_shm(ctx, p->fixed_target_bit, RC_CONTROL_CONFIG);
> +       s5p_mfc_write_info(ctx, p->fixed_target_bit, RC_CONTROL_CONFIG);
>         return 0;
>  }
>
> @@ -723,9 +800,9 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)
>         reg |= p_264->profile;
>         mfc_write(dev, reg, S5P_FIMV_ENC_PROFILE);
>         /* interlace  */
> -       mfc_write(dev, p->interlace, S5P_FIMV_ENC_PIC_STRUCT);
> +       mfc_write(dev, p_264->interlace, S5P_FIMV_ENC_PIC_STRUCT);
>         /* height */
> -       if (p->interlace)
> +       if (p_264->interlace)
>                 mfc_write(dev, ctx->img_height >> 1, S5P_FIMV_ENC_VSIZE_PX);
>         /* loopfilter ctrl */
>         mfc_write(dev, p_264->loop_filter_mode, S5P_FIMV_ENC_LF_CTRL);
> @@ -767,7 +844,7 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)
>         reg = mfc_read(dev, S5P_FIMV_ENC_RC_CONFIG);
>         /* macroblock level rate control */
>         reg &= ~(0x1 << 8);
> -       reg |= (p_264->rc_mb << 8);
> +       reg |= (p->rc_mb << 8);
>         /* frame QP */
>         reg &= ~(0x3F);
>         reg |= p_264->rc_frame_qp;
> @@ -788,7 +865,7 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)
>         reg |= p_264->rc_min_qp;
>         mfc_write(dev, reg, S5P_FIMV_ENC_RC_QBOUND);
>         /* macroblock adaptive scaling features */
> -       if (p_264->rc_mb) {
> +       if (p->rc_mb) {
>                 reg = mfc_read(dev, S5P_FIMV_ENC_RC_MB_CTRL);
>                 /* dark region */
>                 reg &= ~(0x1 << 3);
> @@ -804,37 +881,36 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)
>                 reg |= p_264->rc_mb_activity;
>                 mfc_write(dev, reg, S5P_FIMV_ENC_RC_MB_CTRL);
>         }
> -       if (!p->rc_frame &&
> -           !p_264->rc_mb) {
> -               shm = s5p_mfc_read_shm(ctx, P_B_FRAME_QP);
> +       if (!p->rc_frame && !p->rc_mb) {
> +               shm = s5p_mfc_read_info(ctx, P_B_FRAME_QP);
>                 shm &= ~(0xFFF);
>                 shm |= ((p_264->rc_b_frame_qp & 0x3F) << 6);
>                 shm |= (p_264->rc_p_frame_qp & 0x3F);
> -               s5p_mfc_write_shm(ctx, shm, P_B_FRAME_QP);
> +               s5p_mfc_write_info(ctx, shm, P_B_FRAME_QP);
>         }
>         /* extended encoder ctrl */
> -       shm = s5p_mfc_read_shm(ctx, EXT_ENC_CONTROL);
> +       shm = s5p_mfc_read_info(ctx, EXT_ENC_CONTROL);
>         /* AR VUI control */
>         shm &= ~(0x1 << 15);
>         shm |= (p_264->vui_sar << 1);
> -       s5p_mfc_write_shm(ctx, shm, EXT_ENC_CONTROL);
> +       s5p_mfc_write_info(ctx, shm, EXT_ENC_CONTROL);
>         if (p_264->vui_sar) {
>                 /* aspect ration IDC */
> -               shm = s5p_mfc_read_shm(ctx, SAMPLE_ASPECT_RATIO_IDC);
> +               shm = s5p_mfc_read_info(ctx, SAMPLE_ASPECT_RATIO_IDC);
>                 shm &= ~(0xFF);
>                 shm |= p_264->vui_sar_idc;
> -               s5p_mfc_write_shm(ctx, shm, SAMPLE_ASPECT_RATIO_IDC);
> +               s5p_mfc_write_info(ctx, shm, SAMPLE_ASPECT_RATIO_IDC);
>                 if (p_264->vui_sar_idc == 0xFF) {
>                         /* sample  AR info */
> -                       shm = s5p_mfc_read_shm(ctx, EXTENDED_SAR);
> +                       shm = s5p_mfc_read_info(ctx, EXTENDED_SAR);
>                         shm &= ~(0xFFFFFFFF);
>                         shm |= p_264->vui_ext_sar_width << 16;
>                         shm |= p_264->vui_ext_sar_height;
> -                       s5p_mfc_write_shm(ctx, shm, EXTENDED_SAR);
> +                       s5p_mfc_write_info(ctx, shm, EXTENDED_SAR);
>                 }
>         }
>         /* intra picture period for H.264 */
> -       shm = s5p_mfc_read_shm(ctx, H264_I_PERIOD);
> +       shm = s5p_mfc_read_info(ctx, H264_I_PERIOD);
>         /* control */
>         shm &= ~(0x1 << 16);
>         shm |= (p_264->open_gop << 16);
> @@ -843,16 +919,16 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)
>                 shm &= ~(0xFFFF);
>                 shm |= p_264->open_gop_size;
>         }
> -       s5p_mfc_write_shm(ctx, shm, H264_I_PERIOD);
> +       s5p_mfc_write_info(ctx, shm, H264_I_PERIOD);
>         /* extended encoder ctrl */
> -       shm = s5p_mfc_read_shm(ctx, EXT_ENC_CONTROL);
> +       shm = s5p_mfc_read_info(ctx, EXT_ENC_CONTROL);
>         /* vbv buffer size */
>         if (p->frame_skip_mode ==
>                         V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) {
>                 shm &= ~(0xFFFF << 16);
>                 shm |= (p_264->cpb_size << 16);
>         }
> -       s5p_mfc_write_shm(ctx, shm, EXT_ENC_CONTROL);
> +       s5p_mfc_write_info(ctx, shm, EXT_ENC_CONTROL);
>         return 0;
>  }
>
> @@ -885,11 +961,11 @@ static int s5p_mfc_set_enc_params_mpeg4(struct s5p_mfc_ctx *ctx)
>         mfc_write(dev, p_mpeg4->quarter_pixel, S5P_FIMV_ENC_MPEG4_QUART_PXL);
>         /* qp */
>         if (!p->rc_frame) {
> -               shm = s5p_mfc_read_shm(ctx, P_B_FRAME_QP);
> +               shm = s5p_mfc_read_info(ctx, P_B_FRAME_QP);
>                 shm &= ~(0xFFF);
>                 shm |= ((p_mpeg4->rc_b_frame_qp & 0x3F) << 6);
>                 shm |= (p_mpeg4->rc_p_frame_qp & 0x3F);
> -               s5p_mfc_write_shm(ctx, shm, P_B_FRAME_QP);
> +               s5p_mfc_write_info(ctx, shm, P_B_FRAME_QP);
>         }
>         /* frame rate */
>         if (p->rc_frame) {
> @@ -898,12 +974,12 @@ static int s5p_mfc_set_enc_params_mpeg4(struct s5p_mfc_ctx *ctx)
>                                                 p->rc_framerate_denom;
>                         mfc_write(dev, framerate,
>                                 S5P_FIMV_ENC_RC_FRAME_RATE);
> -                       shm = s5p_mfc_read_shm(ctx, RC_VOP_TIMING);
> +                       shm = s5p_mfc_read_info(ctx, RC_VOP_TIMING);
>                         shm &= ~(0xFFFFFFFF);
>                         shm |= (1 << 31);
>                         shm |= ((p->rc_framerate_num & 0x7FFF) << 16);
>                         shm |= (p->rc_framerate_denom & 0xFFFF);
> -                       s5p_mfc_write_shm(ctx, shm, RC_VOP_TIMING);
> +                       s5p_mfc_write_info(ctx, shm, RC_VOP_TIMING);
>                 }
>         } else {
>                 mfc_write(dev, 0, S5P_FIMV_ENC_RC_FRAME_RATE);
> @@ -924,14 +1000,14 @@ static int s5p_mfc_set_enc_params_mpeg4(struct s5p_mfc_ctx *ctx)
>         reg |= p_mpeg4->rc_min_qp;
>         mfc_write(dev, reg, S5P_FIMV_ENC_RC_QBOUND);
>         /* extended encoder ctrl */
> -       shm = s5p_mfc_read_shm(ctx, EXT_ENC_CONTROL);
> +       shm = s5p_mfc_read_info(ctx, EXT_ENC_CONTROL);
>         /* vbv buffer size */
>         if (p->frame_skip_mode ==
>                         V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) {
>                 shm &= ~(0xFFFF << 16);
>                 shm |= (p->vbv_size << 16);
>         }
> -       s5p_mfc_write_shm(ctx, shm, EXT_ENC_CONTROL);
> +       s5p_mfc_write_info(ctx, shm, EXT_ENC_CONTROL);
>         return 0;
>  }
>
> @@ -946,10 +1022,10 @@ static int s5p_mfc_set_enc_params_h263(struct s5p_mfc_ctx *ctx)
>         s5p_mfc_set_enc_params(ctx);
>         /* qp */
>         if (!p->rc_frame) {
> -               shm = s5p_mfc_read_shm(ctx, P_B_FRAME_QP);
> +               shm = s5p_mfc_read_info(ctx, P_B_FRAME_QP);
>                 shm &= ~(0xFFF);
>                 shm |= (p_h263->rc_p_frame_qp & 0x3F);
> -               s5p_mfc_write_shm(ctx, shm, P_B_FRAME_QP);
> +               s5p_mfc_write_info(ctx, shm, P_B_FRAME_QP);
>         }
>         /* frame rate */
>         if (p->rc_frame && p->rc_framerate_denom)
> @@ -973,14 +1049,14 @@ static int s5p_mfc_set_enc_params_h263(struct s5p_mfc_ctx *ctx)
>         reg |= p_h263->rc_min_qp;
>         mfc_write(dev, reg, S5P_FIMV_ENC_RC_QBOUND);
>         /* extended encoder ctrl */
> -       shm = s5p_mfc_read_shm(ctx, EXT_ENC_CONTROL);
> +       shm = s5p_mfc_read_info(ctx, EXT_ENC_CONTROL);
>         /* vbv buffer size */
>         if (p->frame_skip_mode ==
>                         V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) {
>                 shm &= ~(0xFFFF << 16);
>                 shm |= (p->vbv_size << 16);
>         }
> -       s5p_mfc_write_shm(ctx, shm, EXT_ENC_CONTROL);
> +       s5p_mfc_write_info(ctx, shm, EXT_ENC_CONTROL);
>         return 0;
>  }
>
> @@ -1395,3 +1471,21 @@ void s5p_mfc_cleanup_queue(struct list_head *lh, struct vb2_queue *vq)
>         }
>  }
>
> +void s5p_mfc_clear_int_flags(struct s5p_mfc_dev *dev)
> +{
> +       mfc_write(dev, 0, S5P_FIMV_RISC_HOST_INT);
> +       mfc_write(dev, 0, S5P_FIMV_RISC2HOST_CMD);
> +       mfc_write(dev, 0xffff, S5P_FIMV_SI_RTN_CHID);
> +}
> +
> +void s5p_mfc_write_info(struct s5p_mfc_ctx *ctx, unsigned int data,
> +                       unsigned int ofs)
> +{
> +       s5p_mfc_write_shm(ctx, data, ofs);
> +}
> +
> +unsigned int s5p_mfc_read_info(struct s5p_mfc_ctx *ctx,
> +                               unsigned int ofs)
> +{
> +       return s5p_mfc_read_shm(ctx, ofs);
> +}
> diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_opr.h b/drivers/media/video/s5p-mfc/s5p_mfc_opr.h
> index 5932d1c..6b49a7c 100644
> --- a/drivers/media/video/s5p-mfc/s5p_mfc_opr.h
> +++ b/drivers/media/video/s5p-mfc/s5p_mfc_opr.h
> @@ -50,8 +50,20 @@ void s5p_mfc_release_codec_buffers(struct s5p_mfc_ctx *ctx);
>  int s5p_mfc_alloc_instance_buffer(struct s5p_mfc_ctx *ctx);
>  void s5p_mfc_release_instance_buffer(struct s5p_mfc_ctx *ctx);
>
> +int s5p_mfc_alloc_dev_context_buffer(struct s5p_mfc_dev *dev);
> +void s5p_mfc_release_dev_context_buffer(struct s5p_mfc_dev *dev);
> +
> +void s5p_mfc_dec_calc_dpb_size(struct s5p_mfc_ctx *ctx);
> +void s5p_mfc_enc_calc_src_size(struct s5p_mfc_ctx *ctx);
> +
>  void s5p_mfc_try_run(struct s5p_mfc_dev *dev);
>  void s5p_mfc_cleanup_queue(struct list_head *lh, struct vb2_queue *vq);
> +void s5p_mfc_clear_int_flags(struct s5p_mfc_dev *dev);
> +
> +void s5p_mfc_write_info(struct s5p_mfc_ctx *ctx, unsigned int data,
> +               unsigned int ofs);
> +unsigned int s5p_mfc_read_info(struct s5p_mfc_ctx *ctx,
> +               unsigned int ofs);
>
>  #define s5p_mfc_get_dspl_y_adr()       (readl(dev->regs_base + \
>                                         S5P_FIMV_SI_DISPLAY_Y_ADR) << \
> @@ -63,9 +75,13 @@ void s5p_mfc_cleanup_queue(struct list_head *lh, struct vb2_queue *vq);
>                                                 S5P_FIMV_SI_DISPLAY_STATUS)
>  #define s5p_mfc_get_dec_status()       readl(dev->regs_base + \
>                                                 S5P_FIMV_SI_DECODE_STATUS)
> -#define s5p_mfc_get_frame_type()       (readl(dev->regs_base + \
> +#define s5p_mfc_get_dec_frame_type()   (readl(dev->regs_base + \
>                                                 S5P_FIMV_DECODE_FRAME_TYPE) \
>                                         & S5P_FIMV_DECODE_FRAME_MASK)
> +#define s5p_mfc_get_disp_frame_type()  ((s5p_mfc_read_shm(ctx, \
> +                                               DISP_PIC_FRAME_TYPE) \
> +                                               >> S5P_FIMV_SHARED_DISP_FRAME_TYPE_SHIFT) \
> +                                       & S5P_FIMV_DECODE_FRAME_MASK)
>  #define s5p_mfc_get_consumed_stream()  readl(dev->regs_base + \
>                                                 S5P_FIMV_SI_CONSUMED_BYTES)
>  #define s5p_mfc_get_int_reason()       (readl(dev->regs_base + \
> @@ -89,5 +105,12 @@ void s5p_mfc_cleanup_queue(struct list_head *lh, struct vb2_queue *vq);
>                                                 S5P_FIMV_ENC_SI_STRM_SIZE)
>  #define s5p_mfc_get_enc_slice_type()   readl(dev->regs_base + \
>                                                 S5P_FIMV_ENC_SI_SLICE_TYPE)
> +#define s5p_mfc_get_enc_dpb_count()    -1
> +#define s5p_mfc_get_enc_pic_count()    readl(dev->regs_base + \
> +                                               S5P_FIMV_ENC_SI_PIC_CNT)
> +#define s5p_mfc_get_sei_avail_status() s5p_mfc_read_shm(ctx, \
> +                                               FRAME_PACK_SEI_AVAIL)
> +#define s5p_mfc_get_mvc_num_views()    -1
> +#define s5p_mfc_get_mvc_view_id()      -1
>
>  #endif /* S5P_MFC_OPR_H_ */
> diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/video/s5p-mfc/s5p_mfc_opr_v6.c
> new file mode 100644
> index 0000000..8e68ecc
> --- /dev/null
> +++ b/drivers/media/video/s5p-mfc/s5p_mfc_opr_v6.c
> @@ -0,0 +1,1697 @@
> +/*
> + * drivers/media/video/s5p-mfc/s5p_mfc_opr_v6.c
> + *
> + * Samsung MFC (Multi Function Codec - FIMV) driver
> + * This file contains hw related functions.
> + *
> + * Copyright (c) 2012 Samsung Electronics
> + *             http://www.samsung.com/
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#undef DEBUG
> +
> +#include <linux/delay.h>
> +#include <linux/mm.h>
> +#include <linux/io.h>
> +#include <linux/jiffies.h>
> +#include <linux/firmware.h>
> +#include <linux/err.h>
> +#include <linux/sched.h>
> +#include <linux/dma-mapping.h>
> +
> +#include <asm/cacheflush.h>
> +
> +#include "s5p_mfc_common.h"
> +#include "s5p_mfc_cmd.h"
> +#include "s5p_mfc_intr.h"
> +#include "s5p_mfc_pm.h"
> +#include "s5p_mfc_debug.h"
> +
> +/* #define S5P_MFC_DEBUG_REGWRITE  */
> +#ifdef S5P_MFC_DEBUG_REGWRITE
> +#undef writel
> +#define writel(v, r)                                                   \
> +       do {                                                            \
> +               pr_err("MFCWRITE(%p): %08x\n", r, (unsigned int)v);     \
> +       __raw_writel(v, r);                                             \
> +       } while (0)
> +#endif /* S5P_MFC_DEBUG_REGWRITE */
> +
> +#define READL(offset)          readl(dev->regs_base + (offset))
> +#define WRITEL(data, offset)   writel((data), dev->regs_base + (offset))
> +#define OFFSETA(x)             (((x) - dev->port_a) >> S5P_FIMV_MEM_OFFSET)
> +#define OFFSETB(x)             (((x) - dev->port_b) >> S5P_FIMV_MEM_OFFSET)
> +
> +/* Allocate temporary buffers for decoding */
> +int s5p_mfc_alloc_dec_temp_buffers(struct s5p_mfc_ctx *ctx)
> +{
> +       /* NOP */
> +
> +       return 0;
> +}
> +
> +/* Release temproary buffers for decoding */
> +void s5p_mfc_release_dec_desc_buffer(struct s5p_mfc_ctx *ctx)
> +{
> +       /* NOP */
> +}
> +
> +/* Allocate codec buffers */
> +int s5p_mfc_alloc_codec_buffers(struct s5p_mfc_ctx *ctx)
> +{
> +       struct s5p_mfc_dev *dev = ctx->dev;
> +       unsigned int mb_width, mb_height;
> +
> +       mb_width = mb_width(ctx->img_width);
> +       mb_height = mb_height(ctx->img_height);
> +
> +       if (ctx->type == MFCINST_DECODER) {
> +               mfc_debug(2, "Luma size:%d Chroma size:%d MV size:%d\n",
> +                         ctx->luma_size, ctx->chroma_size, ctx->mv_size);
> +               mfc_debug(2, "Totals bufs: %d\n", ctx->total_dpb_count);
> +       } else if (ctx->type == MFCINST_ENCODER) {
> +               ctx->tmv_buffer_size = 2 * ALIGN((mb_width + 1) *
> +                               (mb_height + 1) * 8, 16);
> +               ctx->luma_dpb_size = ALIGN((mb_width * mb_height) * 256, 256);
> +               ctx->chroma_dpb_size = ALIGN((mb_width * mb_height) * 128, 256);
> +               ctx->me_buffer_size = ALIGN(((((ctx->img_width+63)/64) * 16) *
> +                       (((ctx->img_height+63)/64) * 16)) +
> +                        ((((mb_width*mb_height)+31)/32) * 16), 256);
> +
> +               mfc_debug(2, "recon luma size: %d chroma size: %d\n",
> +                         ctx->luma_dpb_size, ctx->chroma_dpb_size);
> +       } else {
> +               return -EINVAL;
> +       }
> +
> +       /* Codecs have different memory requirements */
> +       switch (ctx->codec_mode) {
> +       case S5P_FIMV_CODEC_H264_DEC:
> +       case S5P_FIMV_CODEC_H264_MVC_DEC:
> +               ctx->scratch_buf_size = (mb_width * 128) + 65536;
> +               ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, 256);
> +               ctx->bank1_size =
> +                       ctx->scratch_buf_size +
> +                       (ctx->total_dpb_count * ctx->mv_size);
> +               break;
> +       case S5P_FIMV_CODEC_MPEG4_DEC:
> +               /* mb_width * (mb_height * 64 + 144) + 8192 * mb_height +
> +                * 41088 */
> +               ctx->scratch_buf_size = mb_width * (mb_height * 64 + 144) +
> +                       ((2048 + 15)/16 * mb_height * 64) +
> +                       ((2048 + 15)/16 * 256 + 8320);
> +               ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, 256);
> +               ctx->bank1_size = ctx->scratch_buf_size;
> +               break;
> +       case S5P_FIMV_CODEC_VC1RCV_DEC:
> +       case S5P_FIMV_CODEC_VC1_DEC:
> +               ctx->scratch_buf_size = 2096 * (mb_width + mb_height + 1);
> +               ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, 256);
> +               ctx->bank1_size = ctx->scratch_buf_size;
> +               break;
> +       case S5P_FIMV_CODEC_MPEG2_DEC:
> +               ctx->bank1_size = 0;
> +               ctx->bank2_size = 0;
> +               break;
> +       case S5P_FIMV_CODEC_H263_DEC:
> +               ctx->scratch_buf_size = mb_width * 400;
> +               ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, 256);
> +               ctx->bank1_size = ctx->scratch_buf_size;
> +               break;
> +       case S5P_FIMV_CODEC_VP8_DEC:
> +               ctx->scratch_buf_size = mb_width * 32 + mb_height * 128 + 34816;
> +               ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, 256);
> +               ctx->bank1_size = ctx->scratch_buf_size;
> +               break;
> +       case S5P_FIMV_CODEC_H264_ENC:
> +               ctx->scratch_buf_size = (mb_width * 64) +
> +                       ((mb_width + 1) * 16) + (4096 * 16);
> +               ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, 256);
> +               ctx->bank1_size =
> +                       ctx->scratch_buf_size + ctx->tmv_buffer_size +
> +                       (ctx->dpb_count * (ctx->luma_dpb_size +
> +                       ctx->chroma_dpb_size + ctx->me_buffer_size));
> +               ctx->bank2_size = 0;
> +               break;
> +       case S5P_FIMV_CODEC_MPEG4_ENC:
> +       case S5P_FIMV_CODEC_H263_ENC:
> +               ctx->scratch_buf_size = (mb_width * 16) + ((mb_width + 1) * 16);
> +               ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, 256);
> +               ctx->bank1_size =
> +                       ctx->scratch_buf_size + ctx->tmv_buffer_size +
> +                       (ctx->dpb_count * (ctx->luma_dpb_size +
> +                       ctx->chroma_dpb_size + ctx->me_buffer_size));
> +               ctx->bank2_size = 0;
> +               break;
> +       default:
> +               break;
> +       }
> +
> +       /* Allocate only if memory from bank 1 is necessary */
> +       if (ctx->bank1_size > 0) {
> +               ctx->bank1_buf = vb2_dma_contig_memops.alloc(
> +               dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->bank1_size);
> +               if (IS_ERR(ctx->bank1_buf)) {
> +                       ctx->bank1_buf = 0;
> +                       pr_err("Buf alloc for decoding failed (port A)\n");
> +                       return -ENOMEM;
> +               }
> +               ctx->bank1_phys = s5p_mfc_mem_cookie(
> +                       dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->bank1_buf);
> +               BUG_ON(ctx->bank1_phys & ((1 << MFC_BANK1_ALIGN_ORDER) - 1));
> +       }
> +
> +       return 0;
> +}
> +
> +/* Release buffers allocated for codec */
> +void s5p_mfc_release_codec_buffers(struct s5p_mfc_ctx *ctx)
> +{
> +       if (ctx->bank1_buf) {
> +               vb2_dma_contig_memops.put(ctx->bank1_buf);
> +               ctx->bank1_buf = 0;
> +               ctx->bank1_phys = 0;
> +               ctx->bank1_size = 0;
> +       }
> +}
> +
> +/* Allocate memory for instance data buffer */
> +int s5p_mfc_alloc_instance_buffer(struct s5p_mfc_ctx *ctx)
> +{
> +       struct s5p_mfc_dev *dev = ctx->dev;
> +       struct s5p_mfc_buf_size_v6 *buf_size = dev->variant->buf_size->priv;
> +
> +       mfc_debug_enter();
> +
> +       switch (ctx->codec_mode) {
> +       case S5P_FIMV_CODEC_H264_DEC:
> +       case S5P_FIMV_CODEC_H264_MVC_DEC:
> +               ctx->ctx_size = buf_size->h264_dec_ctx;
> +               break;
> +       case S5P_FIMV_CODEC_MPEG4_DEC:
> +       case S5P_FIMV_CODEC_H263_DEC:
> +       case S5P_FIMV_CODEC_VC1RCV_DEC:
> +       case S5P_FIMV_CODEC_VC1_DEC:
> +       case S5P_FIMV_CODEC_MPEG2_DEC:
> +       case S5P_FIMV_CODEC_VP8_DEC:
> +               ctx->ctx_size = buf_size->other_dec_ctx;
> +               break;
> +       case S5P_FIMV_CODEC_H264_ENC:
> +               ctx->ctx_size = buf_size->h264_enc_ctx;
> +               break;
> +       case S5P_FIMV_CODEC_MPEG4_ENC:
> +       case S5P_FIMV_CODEC_H263_ENC:
> +               ctx->ctx_size = buf_size->other_enc_ctx;
> +               break;
> +       default:
> +               ctx->ctx_size = 0;
> +               mfc_err("Codec type(%d) should be checked!\n", ctx->codec_mode);
> +               break;
> +       }
> +
> +       ctx->ctx.alloc = vb2_dma_contig_memops.alloc(
> +               dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->ctx_size);
> +       if (IS_ERR(ctx->ctx.alloc)) {
> +               mfc_err("Allocating context buffer failed.\n");
> +               return PTR_ERR(ctx->ctx.alloc);
> +       }
> +
> +       ctx->ctx.dma = s5p_mfc_mem_cookie(
> +               dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->ctx.alloc);
> +
> +       ctx->ctx.virt = vb2_dma_contig_memops.vaddr(ctx->ctx.alloc);
> +       if (!ctx->ctx.virt) {
> +               vb2_dma_contig_memops.put(ctx->ctx.alloc);
> +               ctx->ctx.alloc = NULL;
> +               ctx->ctx.dma = 0;
> +               ctx->ctx.virt = NULL;
> +
> +               mfc_err("Remapping context buffer failed.\n");
> +               return -ENOMEM;
> +       }
> +
> +       memset(ctx->ctx.virt, 0, ctx->ctx_size);
> +       wmb();
> +
> +       mfc_debug_leave();
> +
> +       return 0;
> +}
> +
> +/* Release instance buffer */
> +void s5p_mfc_release_instance_buffer(struct s5p_mfc_ctx *ctx)
> +{
> +       mfc_debug_enter();
> +
> +       if (ctx->ctx.alloc) {
> +               vb2_dma_contig_memops.put(ctx->ctx.alloc);
> +               ctx->ctx.alloc = NULL;
> +               ctx->ctx.dma = 0;
> +               ctx->ctx.virt = NULL;
> +       }
> +
> +       mfc_debug_leave();
> +}
> +
> +/* Allocate context buffers for SYS_INIT */
> +int s5p_mfc_alloc_dev_context_buffer(struct s5p_mfc_dev *dev)
> +{
> +       struct s5p_mfc_buf_size_v6 *buf_size = dev->variant->buf_size->priv;
> +
> +       mfc_debug_enter();
> +
> +       dev->ctx_buf.alloc = vb2_dma_contig_memops.alloc(
> +                       dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], buf_size->dev_ctx);
> +       if (IS_ERR(dev->ctx_buf.alloc)) {
> +               mfc_err("Allocating DESC buffer failed.\n");
> +               return PTR_ERR(dev->ctx_buf.alloc);
> +       }
> +
> +       dev->ctx_buf.dma = s5p_mfc_mem_cookie(
> +                       dev->alloc_ctx[MFC_BANK1_ALLOC_CTX],
> +                       dev->ctx_buf.alloc);
> +
> +       dev->ctx_buf.virt = vb2_dma_contig_memops.vaddr(dev->ctx_buf.alloc);
> +       if (!dev->ctx_buf.virt) {
> +               vb2_dma_contig_memops.put(dev->ctx_buf.alloc);
> +               dev->ctx_buf.alloc = NULL;
> +               dev->ctx_buf.dma = 0;
> +
> +               mfc_err("Remapping DESC buffer failed.\n");
> +               return -ENOMEM;
> +       }
> +
> +       memset(dev->ctx_buf.virt, 0, buf_size->dev_ctx);
> +       wmb();
> +
> +       mfc_debug_leave();
> +
> +       return 0;
> +}
> +
> +/* Release context buffers for SYS_INIT */
> +void s5p_mfc_release_dev_context_buffer(struct s5p_mfc_dev *dev)
> +{
> +       if (dev->ctx_buf.alloc) {
> +               vb2_dma_contig_memops.put(dev->ctx_buf.alloc);
> +               dev->ctx_buf.alloc = NULL;
> +               dev->ctx_buf.dma = 0;
> +               dev->ctx_buf.virt = NULL;
> +       }
> +}
> +
> +static int calc_plane(int width, int height)
> +{
> +       int mbX, mbY;
> +
> +       mbX = (width + 15)/16;
> +       mbY = (height + 15)/16;
> +
> +       if (width * height < 2048 * 1024)
> +               mbY = (mbY + 1) / 2 * 2;
> +
> +       return (mbX * 16) * (mbY * 16);
> +}
> +
> +void s5p_mfc_dec_calc_dpb_size(struct s5p_mfc_ctx *ctx)
> +{
> +       ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN);
> +       ctx->buf_height = ALIGN(ctx->img_height, S5P_FIMV_NV12MT_VALIGN);
> +       mfc_debug(2, "SEQ Done: Movie dimensions %dx%d,\n"
> +                       "buffer dimensions: %dx%d\n", ctx->img_width,
> +                       ctx->img_height, ctx->buf_width, ctx->buf_height);
> +
> +       ctx->luma_size = calc_plane(ctx->img_width, ctx->img_height);
> +       ctx->chroma_size = calc_plane(ctx->img_width, (ctx->img_height >> 1));
> +       if (ctx->codec_mode == S5P_FIMV_CODEC_H264_DEC ||
> +                       ctx->codec_mode == S5P_FIMV_CODEC_H264_MVC_DEC) {
> +               ctx->mv_size = s5p_mfc_dec_mv_size(ctx->img_width,
> +                               ctx->img_height);
> +               ctx->mv_size = ALIGN(ctx->mv_size, 16);
> +       } else {
> +               ctx->mv_size = 0;
> +       }
> +}
> +
> +void s5p_mfc_enc_calc_src_size(struct s5p_mfc_ctx *ctx)
> +{
> +       unsigned int mb_width, mb_height;
> +
> +       mb_width = mb_width(ctx->img_width);
> +       mb_height = mb_height(ctx->img_height);
> +
> +       ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12M_HALIGN);
> +       ctx->luma_size = ALIGN((mb_width * mb_height) * 256, 256);
> +       ctx->chroma_size = ALIGN((mb_width * mb_height) * 128, 256);
> +}
> +
> +/* Set registers for decoding stream buffer */
> +int s5p_mfc_set_dec_stream_buffer(struct s5p_mfc_ctx *ctx, int buf_addr,
> +                 unsigned int start_num_byte, unsigned int strm_size)
> +{
> +       struct s5p_mfc_dev *dev = ctx->dev;
> +       struct s5p_mfc_buf_size *buf_size = dev->variant->buf_size;
> +
> +       mfc_debug_enter();
> +       mfc_debug(2, "inst_no: %d, buf_addr: 0x%08x,\n"
> +               "buf_size: 0x%08x (%d)\n",
> +               ctx->inst_no, buf_addr, strm_size, strm_size);
> +       WRITEL(strm_size, S5P_FIMV_D_STREAM_DATA_SIZE);
> +       WRITEL(buf_addr, S5P_FIMV_D_CPB_BUFFER_ADDR);
> +       WRITEL(buf_size->cpb, S5P_FIMV_D_CPB_BUFFER_SIZE);
> +       WRITEL(start_num_byte, S5P_FIMV_D_CPB_BUFFER_OFFSET);
> +
> +       mfc_debug_leave();
> +       return 0;
> +}
> +
> +/* Set decoding frame buffer */
> +int s5p_mfc_set_dec_frame_buffer(struct s5p_mfc_ctx *ctx)
> +{
> +       unsigned int frame_size, i;
> +       unsigned int frame_size_ch, frame_size_mv;
> +       struct s5p_mfc_dev *dev = ctx->dev;
> +       size_t buf_addr1;
> +       int buf_size1;
> +       int align_gap;
> +
> +       buf_addr1 = ctx->bank1_phys;
> +       buf_size1 = ctx->bank1_size;
> +
> +       mfc_debug(2, "Buf1: %p (%d)\n", (void *)buf_addr1, buf_size1);
> +       mfc_debug(2, "Total DPB COUNT: %d\n", ctx->total_dpb_count);
> +       mfc_debug(2, "Setting display delay to %d\n", ctx->display_delay);
> +
> +       WRITEL(ctx->total_dpb_count, S5P_FIMV_D_NUM_DPB);
> +       WRITEL(ctx->luma_size, S5P_FIMV_D_LUMA_DPB_SIZE);
> +       WRITEL(ctx->chroma_size, S5P_FIMV_D_CHROMA_DPB_SIZE);
> +
> +       WRITEL(buf_addr1, S5P_FIMV_D_SCRATCH_BUFFER_ADDR);
> +       WRITEL(ctx->scratch_buf_size, S5P_FIMV_D_SCRATCH_BUFFER_SIZE);
> +       buf_addr1 += ctx->scratch_buf_size;
> +       buf_size1 -= ctx->scratch_buf_size;
> +
> +       if (ctx->codec_mode == S5P_FIMV_CODEC_H264_DEC ||
> +                       ctx->codec_mode == S5P_FIMV_CODEC_H264_MVC_DEC)
> +               WRITEL(ctx->mv_size, S5P_FIMV_D_MV_BUFFER_SIZE);
> +
> +       frame_size = ctx->luma_size;
> +       frame_size_ch = ctx->chroma_size;
> +       frame_size_mv = ctx->mv_size;
> +       mfc_debug(2, "Frame size: %d ch: %d mv: %d\n",
> +                       frame_size, frame_size_ch, frame_size_mv);
> +
> +       for (i = 0; i < ctx->total_dpb_count; i++) {
> +               /* Bank2 */
> +               mfc_debug(2, "Luma %d: %x\n", i,
> +                                       ctx->dst_bufs[i].cookie.raw.luma);
> +               WRITEL(ctx->dst_bufs[i].cookie.raw.luma,
> +                               S5P_FIMV_D_LUMA_DPB + i * 4);
> +               mfc_debug(2, "\tChroma %d: %x\n", i,
> +                                       ctx->dst_bufs[i].cookie.raw.chroma);
> +               WRITEL(ctx->dst_bufs[i].cookie.raw.chroma,
> +                               S5P_FIMV_D_CHROMA_DPB + i * 4);
> +
> +               if (ctx->codec_mode == S5P_FIMV_CODEC_H264_DEC ||
> +                               ctx->codec_mode ==
> +                               S5P_FIMV_CODEC_H264_MVC_DEC) {
> +                       /* To test alignment */
> +                       align_gap = buf_addr1;
> +                       buf_addr1 = ALIGN(buf_addr1, 16);
> +                       align_gap = buf_addr1 - align_gap;
> +                       buf_size1 -= align_gap;
> +
> +                       mfc_debug(2, "\tBuf1: %x, size: %d\n",
> +                                       buf_addr1, buf_size1);
> +                       WRITEL(buf_addr1, S5P_FIMV_D_MV_BUFFER + i * 4);
> +                       buf_addr1 += frame_size_mv;
> +                       buf_size1 -= frame_size_mv;
> +               }
> +       }
> +
> +       mfc_debug(2, "Buf1: %u, buf_size1: %d (frames %d)\n",
> +                       buf_addr1, buf_size1, ctx->total_dpb_count);
> +       if (buf_size1 < 0) {
> +               mfc_debug(2, "Not enough memory has been allocated.\n");
> +               return -ENOMEM;
> +       }
> +
> +       WRITEL(ctx->inst_no, S5P_FIMV_INSTANCE_ID);
> +       s5p_mfc_cmd_host2risc(dev, S5P_FIMV_CH_INIT_BUFS, NULL);
> +
> +       mfc_debug(2, "After setting buffers.\n");
> +       return 0;
> +}
> +
> +/* Set registers for encoding stream buffer */
> +int s5p_mfc_set_enc_stream_buffer(struct s5p_mfc_ctx *ctx,
> +               unsigned long addr, unsigned int size)
> +{
> +       struct s5p_mfc_dev *dev = ctx->dev;
> +
> +       WRITEL(addr, S5P_FIMV_E_STREAM_BUFFER_ADDR); /* 16B align */
> +       WRITEL(size, S5P_FIMV_E_STREAM_BUFFER_SIZE);
> +
> +       mfc_debug(2, "stream buf addr: 0x%08lx, size: 0x%d",
> +               addr, size);
> +
> +       return 0;
> +}
> +
> +void s5p_mfc_set_enc_frame_buffer(struct s5p_mfc_ctx *ctx,
> +               unsigned long y_addr, unsigned long c_addr)
> +{
> +       struct s5p_mfc_dev *dev = ctx->dev;
> +
> +       WRITEL(y_addr, S5P_FIMV_E_SOURCE_LUMA_ADDR); /* 256B align */
> +       WRITEL(c_addr, S5P_FIMV_E_SOURCE_CHROMA_ADDR);
> +
> +       mfc_debug(2, "enc src y buf addr: 0x%08lx", y_addr);
> +       mfc_debug(2, "enc src c buf addr: 0x%08lx", c_addr);
> +}
> +
> +void s5p_mfc_get_enc_frame_buffer(struct s5p_mfc_ctx *ctx,
> +               unsigned long *y_addr, unsigned long *c_addr)
> +{
> +       struct s5p_mfc_dev *dev = ctx->dev;
> +       unsigned long enc_recon_y_addr, enc_recon_c_addr;
> +
> +       *y_addr = READL(S5P_FIMV_E_ENCODED_SOURCE_LUMA_ADDR);
> +       *c_addr = READL(S5P_FIMV_E_ENCODED_SOURCE_CHROMA_ADDR);
> +
> +       enc_recon_y_addr = READL(S5P_FIMV_E_RECON_LUMA_DPB_ADDR);
> +       enc_recon_c_addr = READL(S5P_FIMV_E_RECON_CHROMA_DPB_ADDR);
> +
> +       mfc_debug(2, "recon y addr: 0x%08lx", enc_recon_y_addr);
> +       mfc_debug(2, "recon c addr: 0x%08lx", enc_recon_c_addr);
> +}
> +
> +/* Set encoding ref & codec buffer */
> +int s5p_mfc_set_enc_ref_buffer(struct s5p_mfc_ctx *ctx)
> +{
> +       struct s5p_mfc_dev *dev = ctx->dev;
> +       size_t buf_addr1, buf_size1;
> +       int i;
> +
> +       mfc_debug_enter();
> +
> +       buf_addr1 = ctx->bank1_phys;
> +       buf_size1 = ctx->bank1_size;
> +
> +       mfc_debug(2, "Buf1: %p (%d)\n", (void *)buf_addr1, buf_size1);
> +
> +       for (i = 0; i < ctx->dpb_count; i++) {
> +               WRITEL(buf_addr1, S5P_FIMV_E_LUMA_DPB + (4 * i));
> +               buf_addr1 += ctx->luma_dpb_size;
> +               WRITEL(buf_addr1, S5P_FIMV_E_CHROMA_DPB + (4 * i));
> +               buf_addr1 += ctx->chroma_dpb_size;
> +               WRITEL(buf_addr1, S5P_FIMV_E_ME_BUFFER + (4 * i));
> +               buf_addr1 += ctx->me_buffer_size;
> +               buf_size1 -= (ctx->luma_dpb_size + ctx->chroma_dpb_size +
> +                       ctx->me_buffer_size);
> +       }
> +
> +       WRITEL(buf_addr1, S5P_FIMV_E_SCRATCH_BUFFER_ADDR);
> +       WRITEL(ctx->scratch_buf_size, S5P_FIMV_E_SCRATCH_BUFFER_SIZE);
> +       buf_addr1 += ctx->scratch_buf_size;
> +       buf_size1 -= ctx->scratch_buf_size;
> +
> +       WRITEL(buf_addr1, S5P_FIMV_E_TMV_BUFFER0);
> +       buf_addr1 += ctx->tmv_buffer_size >> 1;
> +       WRITEL(buf_addr1, S5P_FIMV_E_TMV_BUFFER1);
> +       buf_addr1 += ctx->tmv_buffer_size >> 1;
> +       buf_size1 -= ctx->tmv_buffer_size;
> +
> +       mfc_debug(2, "Buf1: %u, buf_size1: %d (ref frames %d)\n",
> +                       buf_addr1, buf_size1, ctx->dpb_count);
> +       if (buf_size1 < 0) {
> +               mfc_debug(2, "Not enough memory has been allocated.\n");
> +               return -ENOMEM;
> +       }
> +
> +       WRITEL(ctx->inst_no, S5P_FIMV_INSTANCE_ID);
> +       s5p_mfc_cmd_host2risc(dev, S5P_FIMV_CH_INIT_BUFS, NULL);
> +
> +       mfc_debug_leave();
> +
> +       return 0;
> +}
> +
> +static int s5p_mfc_set_slice_mode(struct s5p_mfc_ctx *ctx)
> +{
> +       struct s5p_mfc_dev *dev = ctx->dev;
> +
> +       /* multi-slice control */
> +       /* multi-slice MB number or bit size */
> +       WRITEL(ctx->slice_mode, S5P_FIMV_E_MSLICE_MODE);
> +       if (ctx->slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB) {
> +               WRITEL(ctx->slice_size.mb, S5P_FIMV_E_MSLICE_SIZE_MB);
> +       } else if (ctx->slice_mode ==
> +                       V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES) {
> +               WRITEL(ctx->slice_size.bits, S5P_FIMV_E_MSLICE_SIZE_BITS);
> +       } else {
> +               WRITEL(0x0, S5P_FIMV_E_MSLICE_SIZE_MB);
> +               WRITEL(0x0, S5P_FIMV_E_MSLICE_SIZE_BITS);
> +       }
> +
> +       return 0;
> +}
> +
> +static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx)
> +{
> +       struct s5p_mfc_dev *dev = ctx->dev;
> +       struct s5p_mfc_enc_params *p = &ctx->enc_params;
> +       unsigned int reg = 0;
> +
> +       mfc_debug_enter();
> +
> +       /* width */
> +       WRITEL(ctx->img_width, S5P_FIMV_E_FRAME_WIDTH); /* 16 align */
> +       /* height */
> +       WRITEL(ctx->img_height, S5P_FIMV_E_FRAME_HEIGHT); /* 16 align */
> +
> +       /* cropped width */
> +       WRITEL(ctx->img_width, S5P_FIMV_E_CROPPED_FRAME_WIDTH);
> +       /* cropped height */
> +       WRITEL(ctx->img_height, S5P_FIMV_E_CROPPED_FRAME_HEIGHT);
> +       /* cropped offset */
> +       WRITEL(0x0, S5P_FIMV_E_FRAME_CROP_OFFSET);
> +
> +       /* pictype : IDR period */
> +       reg = 0;
> +       reg |= p->gop_size & 0xFFFF;
> +       WRITEL(reg, S5P_FIMV_E_GOP_CONFIG);
> +
> +       /* multi-slice control */
> +       /* multi-slice MB number or bit size */
> +       ctx->slice_mode = p->slice_mode;
> +       reg = 0;
> +       if (p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB) {
> +               reg |= (0x1 << 3);
> +               WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS);
> +               ctx->slice_size.mb = p->slice_mb;
> +       } else if (p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES) {
> +               reg |= (0x1 << 3);
> +               WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS);
> +               ctx->slice_size.bits = p->slice_bit;
> +       } else {
> +               reg &= ~(0x1 << 3);
> +               WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS);
> +       }
> +
> +       s5p_mfc_set_slice_mode(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
> +               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_NV12M) {
> +               /* 0: Linear, 1: 2D tiled*/
> +               reg = READL(S5P_FIMV_E_ENC_OPTIONS);
> +               reg &= ~(0x1 << 7);
> +               WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS);
> +               /* 0: NV12(CbCr), 1: NV21(CrCb) */
> +               WRITEL(0x0, S5P_FIMV_PIXEL_FORMAT);
> +       } else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV21M) {
> +               /* 0: Linear, 1: 2D tiled*/
> +               reg = READL(S5P_FIMV_E_ENC_OPTIONS);
> +               reg &= ~(0x1 << 7);
> +               WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS);
> +               /* 0: NV12(CbCr), 1: NV21(CrCb) */
> +               WRITEL(0x1, S5P_FIMV_PIXEL_FORMAT);
> +       } else 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);
> +               /* 0: NV12(CbCr), 1: NV21(CrCb) */
> +               WRITEL(0x0, 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) {
> +               reg = 0;
> +               /** enable */
> +               reg |= (1 << 31);
> +               /** cr value */
> +               reg |= ((p->pad_cr & 0xFF) << 16);
> +               /** cb value */
> +               reg |= ((p->pad_cb & 0xFF) << 8);
> +               /** y value */
> +               reg |= p->pad_luma & 0xFF;
> +               WRITEL(reg, S5P_FIMV_E_PADDING_CTRL);
> +       }
> +
> +       /* rate control config. */
> +       reg = 0;
> +       /* frame-level rate control */
> +       reg |= ((p->rc_frame & 0x1) << 9);
> +       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);
> +
> +       /* reaction coefficient */
> +       if (p->rc_frame) {
> +               if (p->rc_reaction_coeff < TIGHT_CBR_MAX) /* tight CBR */
> +                       WRITEL(1, S5P_FIMV_E_RC_RPARAM);
> +               else                                      /* loose CBR */
> +                       WRITEL(2, S5P_FIMV_E_RC_RPARAM);
> +       }
> +
> +       /* seq header ctrl */
> +       reg = READL(S5P_FIMV_E_ENC_OPTIONS);
> +       reg &= ~(0x1 << 2);
> +       reg |= ((p->seq_hdr_mode & 0x1) << 2);
> +
> +       /* frame skip mode */
> +       reg &= ~(0x3);
> +       reg |= (p->frame_skip_mode & 0x3);
> +       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] */
> +       reg = 0;
> +       reg &= ~(0x3FFF);
> +       reg = 256;
> +       WRITEL(reg, S5P_FIMV_E_MV_HOR_RANGE);
> +
> +       reg = 0;
> +       reg &= ~(0x3FFF);
> +       reg = 256;
> +       WRITEL(reg, S5P_FIMV_E_MV_VER_RANGE);
> +
> +       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_RC_ROI_CTRL);
> +       WRITEL(0x0, S5P_FIMV_E_PICTURE_TAG);
> +
> +       WRITEL(0x0, S5P_FIMV_E_BIT_COUNT_ENABLE);
> +       WRITEL(0x0, S5P_FIMV_E_MAX_BIT_COUNT);
> +       WRITEL(0x0, S5P_FIMV_E_MIN_BIT_COUNT);
> +
> +       WRITEL(0x0, S5P_FIMV_E_METADATA_BUFFER_ADDR);
> +       WRITEL(0x0, S5P_FIMV_E_METADATA_BUFFER_SIZE);
> +
> +       mfc_debug_leave();
> +
> +       return 0;
> +}
> +
> +static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)
> +{
> +       struct s5p_mfc_dev *dev = ctx->dev;
> +       struct s5p_mfc_enc_params *p = &ctx->enc_params;
> +       struct s5p_mfc_h264_enc_params *p_h264 = &p->codec.h264;
> +       unsigned int reg = 0;
> +       int i;
> +
> +       mfc_debug_enter();
> +
> +       s5p_mfc_set_enc_params(ctx);
> +
> +       /* pictype : number of B */
> +       reg = READL(S5P_FIMV_E_GOP_CONFIG);
> +       reg &= ~(0x3 << 16);
> +       reg |= ((p->num_b_frame & 0x3) << 16);
> +       WRITEL(reg, S5P_FIMV_E_GOP_CONFIG);
> +
> +       /* profile & level */
> +       reg = 0;
> +       /** level */
> +       reg |= ((p_h264->level & 0xFF) << 8);
> +       /** profile - 0 ~ 3 */
> +       reg |= p_h264->profile & 0x3F;
> +       WRITEL(reg, S5P_FIMV_E_PICTURE_PROFILE);
> +
> +       /* rate control config. */
> +       reg = READL(S5P_FIMV_E_RC_CONFIG);
> +       /** macroblock level rate control */
> +       reg &= ~(0x1 << 8);
> +       reg |= ((p->rc_mb & 0x1) << 8);
> +       WRITEL(reg, S5P_FIMV_E_RC_CONFIG);
> +       /** frame QP */
> +       reg &= ~(0x3F);
> +       reg |= p_h264->rc_frame_qp & 0x3F;
> +       WRITEL(reg, S5P_FIMV_E_RC_CONFIG);
> +
> +       /* max & min value of QP */
> +       reg = 0;
> +       /** max QP */
> +       reg |= ((p_h264->rc_max_qp & 0x3F) << 8);
> +       /** min QP */
> +       reg |= p_h264->rc_min_qp & 0x3F;
> +       WRITEL(reg, S5P_FIMV_E_RC_QP_BOUND);
> +
> +       /* other QPs */
> +       WRITEL(0x0, S5P_FIMV_E_FIXED_PICTURE_QP);
> +       if (!p->rc_frame && !p->rc_mb) {
> +               reg = 0;
> +               reg |= ((p_h264->rc_b_frame_qp & 0x3F) << 16);
> +               reg |= ((p_h264->rc_p_frame_qp & 0x3F) << 8);
> +               reg |= p_h264->rc_frame_qp & 0x3F;
> +               WRITEL(reg, S5P_FIMV_E_FIXED_PICTURE_QP);
> +       }
> +
> +       /* frame rate */
> +       if (p->rc_frame && p->rc_framerate_num && p->rc_framerate_denom) {
> +               reg = 0;
> +               reg |= ((p->rc_framerate_num & 0xFFFF) << 16);
> +               reg |= p->rc_framerate_denom & 0xFFFF;
> +               WRITEL(reg, S5P_FIMV_E_RC_FRAME_RATE);
> +       }
> +
> +       /* vbv buffer size */
> +       if (p->frame_skip_mode ==
> +                       V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) {
> +               WRITEL(p_h264->cpb_size & 0xFFFF, S5P_FIMV_E_VBV_BUFFER_SIZE);
> +
> +               if (p->rc_frame)
> +                       WRITEL(p->vbv_delay, S5P_FIMV_E_VBV_INIT_DELAY);
> +       }
> +
> +       /* interlace */
> +       reg = 0;
> +       reg |= ((p_h264->interlace & 0x1) << 3);
> +       WRITEL(reg, S5P_FIMV_E_H264_OPTIONS);
> +
> +       /* height */
> +       if (p_h264->interlace) {
> +               WRITEL(ctx->img_height >> 1,
> +                               S5P_FIMV_E_FRAME_HEIGHT); /* 32 align */
> +               /* cropped height */
> +               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_h264->loop_filter_mode & 0x3) << 1);
> +       WRITEL(reg, S5P_FIMV_E_H264_OPTIONS);
> +
> +       /* loopfilter alpha offset */
> +       if (p_h264->loop_filter_alpha < 0) {
> +               reg = 0x10;
> +               reg |= (0xFF - p_h264->loop_filter_alpha) + 1;
> +       } else {
> +               reg = 0x00;
> +               reg |= (p_h264->loop_filter_alpha & 0xF);
> +       }
> +       WRITEL(reg, S5P_FIMV_E_H264_LF_ALPHA_OFFSET);
> +
> +       /* loopfilter beta offset */
> +       if (p_h264->loop_filter_beta < 0) {
> +               reg = 0x10;
> +               reg |= (0xFF - p_h264->loop_filter_beta) + 1;
> +       } else {
> +               reg = 0x00;
> +               reg |= (p_h264->loop_filter_beta & 0xF);
> +       }
> +       WRITEL(reg, S5P_FIMV_E_H264_LF_BETA_OFFSET);
> +
> +       /* entropy coding mode */
> +       reg = READL(S5P_FIMV_E_H264_OPTIONS);
> +       reg &= ~(0x1);
> +       reg |= p_h264->entropy_mode & 0x1;
> +       WRITEL(reg, S5P_FIMV_E_H264_OPTIONS);
> +
> +       /* number of ref. picture */
> +       reg = READL(S5P_FIMV_E_H264_OPTIONS);
> +       reg &= ~(0x1 << 7);
> +       reg |= (((p_h264->num_ref_pic_4p - 1) & 0x1) << 7);
> +       WRITEL(reg, S5P_FIMV_E_H264_OPTIONS);
> +
> +       /* 8x8 transform enable */
> +       reg = READL(S5P_FIMV_E_H264_OPTIONS);
> +       reg &= ~(0x3 << 12);
> +       reg |= ((p_h264->_8x8_transform & 0x3) << 12);
> +       WRITEL(reg, S5P_FIMV_E_H264_OPTIONS);
> +
> +       /* macroblock adaptive scaling features */
> +       WRITEL(0x0, S5P_FIMV_E_MB_RC_CONFIG);
> +       if (p->rc_mb) {
> +               reg = 0;
> +               /** dark region */
> +               reg |= ((p_h264->rc_mb_dark & 0x1) << 3);
> +               /** smooth region */
> +               reg |= ((p_h264->rc_mb_smooth & 0x1) << 2);
> +               /** static region */
> +               reg |= ((p_h264->rc_mb_static & 0x1) << 1);
> +               /** high activity region */
> +               reg |= p_h264->rc_mb_activity & 0x1;
> +               WRITEL(reg, S5P_FIMV_E_MB_RC_CONFIG);
> +       }
> +
> +       /* aspect ratio VUI */
> +       reg = READL(S5P_FIMV_E_H264_OPTIONS);
> +       reg &= ~(0x1 << 5);
> +       reg |= ((p_h264->vui_sar & 0x1) << 5);
> +       WRITEL(reg, S5P_FIMV_E_H264_OPTIONS);
> +
> +       WRITEL(0x0, S5P_FIMV_E_ASPECT_RATIO);
> +       WRITEL(0x0, S5P_FIMV_E_EXTENDED_SAR);
> +       if (p_h264->vui_sar) {
> +               /* aspect ration IDC */
> +               reg = 0;
> +               reg |= p_h264->vui_sar_idc & 0xFF;
> +               WRITEL(reg, S5P_FIMV_E_ASPECT_RATIO);
> +               if (p_h264->vui_sar_idc == 0xFF) {
> +                       /* extended SAR */
> +                       reg = 0;
> +                       reg |= (p_h264->vui_ext_sar_width & 0xFFFF) << 16;
> +                       reg |= p_h264->vui_ext_sar_height & 0xFFFF;
> +                       WRITEL(reg, S5P_FIMV_E_EXTENDED_SAR);
> +               }
> +       }
> +
> +       /* intra picture period for H.264 open GOP */
> +       /* control */
> +       reg = READL(S5P_FIMV_E_H264_OPTIONS);
> +       reg &= ~(0x1 << 4);
> +       reg |= ((p_h264->open_gop & 0x1) << 4);
> +       WRITEL(reg, S5P_FIMV_E_H264_OPTIONS);
> +       /* value */
> +       WRITEL(0x0, S5P_FIMV_E_H264_I_PERIOD);
> +       if (p_h264->open_gop) {
> +               reg = 0;
> +               reg |= p_h264->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 */
> +       reg = READL(S5P_FIMV_E_H264_OPTIONS);
> +       reg &= ~(0x1 << 6);
> +       reg |= ((p_h264->aso & 0x1) << 6);
> +       WRITEL(reg, S5P_FIMV_E_H264_OPTIONS);
> +
> +       /* hier qp enable */
> +       reg = READL(S5P_FIMV_E_H264_OPTIONS);
> +       reg &= ~(0x1 << 8);
> +       reg |= ((p_h264->open_gop & 0x1) << 8);
> +       WRITEL(reg, S5P_FIMV_E_H264_OPTIONS);
> +       reg = 0;
> +       if (p_h264->hier_qp && p_h264->hier_qp_layer) {
> +               reg |= (p_h264->hier_qp_type & 0x1) << 0x3;
> +               reg |= p_h264->hier_qp_layer & 0x7;
> +               WRITEL(reg, S5P_FIMV_E_H264_NUM_T_LAYER);
> +               /* QP value for each layer */
> +               for (i = 0; i < (p_h264->hier_qp_layer & 0x7); i++)
> +                       WRITEL(p_h264->hier_qp_layer_qp[i],
> +                               S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER0 + i * 4);
> +       }
> +       /* number of coding layer should be zero when hierarchical is disable */
> +       WRITEL(reg, S5P_FIMV_E_H264_NUM_T_LAYER);
> +
> +       /* frame packing SEI generation */
> +       reg = READL(S5P_FIMV_E_H264_OPTIONS);
> +       reg &= ~(0x1 << 25);
> +       reg |= ((p_h264->sei_frame_packing & 0x1) << 25);
> +       WRITEL(reg, S5P_FIMV_E_H264_OPTIONS);
> +       if (p_h264->sei_frame_packing) {
> +               reg = 0;
> +               /** current frame0 flag */
> +               reg |= ((p_h264->sei_fp_curr_frame_0 & 0x1) << 2);
> +               /** arrangement type */
> +               reg |= p_h264->sei_fp_arrangement_type & 0x3;
> +               WRITEL(reg, S5P_FIMV_E_H264_FRAME_PACKING_SEI_INFO);
> +       }
> +
> +       if (p_h264->fmo) {
> +               switch (p_h264->fmo_map_type) {
> +               case V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_INTERLEAVED_SLICES:
> +                       if (p_h264->fmo_slice_grp > 4)
> +                               p_h264->fmo_slice_grp = 4;
> +                       for (i = 0; i < (p_h264->fmo_slice_grp & 0xF); i++)
> +                               WRITEL(p_h264->fmo_run_len[i] - 1,
> +                               S5P_FIMV_E_H264_FMO_RUN_LENGTH_MINUS1_0 +
> +                               i * 4);
> +                       break;
> +               case V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_SCATTERED_SLICES:
> +                       if (p_h264->fmo_slice_grp > 4)
> +                               p_h264->fmo_slice_grp = 4;
> +                       break;
> +               case V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_RASTER_SCAN:
> +               case V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_WIPE_SCAN:
> +                       if (p_h264->fmo_slice_grp > 2)
> +                               p_h264->fmo_slice_grp = 2;
> +                       WRITEL(p_h264->fmo_chg_dir & 0x1,
> +                               S5P_FIMV_E_H264_FMO_SLICE_GRP_CHANGE_DIR);
> +                       /* the valid range is 0 ~ number of macroblocks -1 */
> +                       WRITEL(p_h264->fmo_chg_rate,
> +                               S5P_FIMV_E_H264_FMO_SLICE_GRP_CHANGE_RATE_MINUS1);
> +                       break;
> +               default:
> +                       mfc_err("Unsupported map type for FMO: %d\n",
> +                                       p_h264->fmo_map_type);
> +                       p_h264->fmo_map_type = 0;
> +                       p_h264->fmo_slice_grp = 1;
> +                       break;
> +               }
> +
> +               WRITEL(p_h264->fmo_map_type,
> +                               S5P_FIMV_E_H264_FMO_SLICE_GRP_MAP_TYPE);
> +               WRITEL(p_h264->fmo_slice_grp - 1,
> +                               S5P_FIMV_E_H264_FMO_NUM_SLICE_GRP_MINUS1);
> +       } else {
> +               WRITEL(0, S5P_FIMV_E_H264_FMO_NUM_SLICE_GRP_MINUS1);
> +       }
> +
> +       mfc_debug_leave();
> +
> +       return 0;
> +}
> +
> +static int s5p_mfc_set_enc_params_mpeg4(struct s5p_mfc_ctx *ctx)
> +{
> +       struct s5p_mfc_dev *dev = ctx->dev;
> +       struct s5p_mfc_enc_params *p = &ctx->enc_params;
> +       struct s5p_mfc_mpeg4_enc_params *p_mpeg4 = &p->codec.mpeg4;
> +       unsigned int reg = 0;
> +
> +       mfc_debug_enter();
> +
> +       s5p_mfc_set_enc_params(ctx);
> +
> +       /* pictype : number of B */
> +       reg = READL(S5P_FIMV_E_GOP_CONFIG);
> +       reg &= ~(0x3 << 16);
> +       reg |= ((p->num_b_frame & 0x3) << 16);
> +       WRITEL(reg, S5P_FIMV_E_GOP_CONFIG);
> +
> +       /* profile & level */
> +       reg = 0;
> +       /** level */
> +       reg |= ((p_mpeg4->level & 0xFF) << 8);
> +       /** profile - 0 ~ 1 */
> +       reg |= p_mpeg4->profile & 0x3F;
> +       WRITEL(reg, S5P_FIMV_E_PICTURE_PROFILE);
> +
> +       /* rate control config. */
> +       reg = READL(S5P_FIMV_E_RC_CONFIG);
> +       /** macroblock level rate control */
> +       reg &= ~(0x1 << 8);
> +       reg |= ((p->rc_mb & 0x1) << 8);
> +       WRITEL(reg, S5P_FIMV_E_RC_CONFIG);
> +       /** frame QP */
> +       reg &= ~(0x3F);
> +       reg |= p_mpeg4->rc_frame_qp & 0x3F;
> +       WRITEL(reg, S5P_FIMV_E_RC_CONFIG);
> +
> +       /* max & min value of QP */
> +       reg = 0;
> +       /** max QP */
> +       reg |= ((p_mpeg4->rc_max_qp & 0x3F) << 8);
> +       /** min QP */
> +       reg |= p_mpeg4->rc_min_qp & 0x3F;
> +       WRITEL(reg, S5P_FIMV_E_RC_QP_BOUND);
> +
> +       /* other QPs */
> +       WRITEL(0x0, S5P_FIMV_E_FIXED_PICTURE_QP);
> +       if (!p->rc_frame && !p->rc_mb) {
> +               reg = 0;
> +               reg |= ((p_mpeg4->rc_b_frame_qp & 0x3F) << 16);
> +               reg |= ((p_mpeg4->rc_p_frame_qp & 0x3F) << 8);
> +               reg |= p_mpeg4->rc_frame_qp & 0x3F;
> +               WRITEL(reg, S5P_FIMV_E_FIXED_PICTURE_QP);
> +       }
> +
> +       /* frame rate */
> +       if (p->rc_frame && p->rc_framerate_num && p->rc_framerate_denom) {
> +               reg = 0;
> +               reg |= ((p->rc_framerate_num & 0xFFFF) << 16);
> +               reg |= p->rc_framerate_denom & 0xFFFF;
> +               WRITEL(reg, S5P_FIMV_E_RC_FRAME_RATE);
> +       }
> +
> +       /* vbv buffer size */
> +       if (p->frame_skip_mode ==
> +                       V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) {
> +               WRITEL(p->vbv_size & 0xFFFF, S5P_FIMV_E_VBV_BUFFER_SIZE);
> +
> +               if (p->rc_frame)
> +                       WRITEL(p->vbv_delay, S5P_FIMV_E_VBV_INIT_DELAY);
> +       }
> +
> +       /* Disable HEC */
> +       WRITEL(0x0, S5P_FIMV_E_MPEG4_OPTIONS);
> +       WRITEL(0x0, S5P_FIMV_E_MPEG4_HEC_PERIOD);
> +
> +       mfc_debug_leave();
> +
> +       return 0;
> +}
> +
> +static int s5p_mfc_set_enc_params_h263(struct s5p_mfc_ctx *ctx)
> +{
> +       struct s5p_mfc_dev *dev = ctx->dev;
> +       struct s5p_mfc_enc_params *p = &ctx->enc_params;
> +       struct s5p_mfc_mpeg4_enc_params *p_h263 = &p->codec.mpeg4;
> +       unsigned int reg = 0;
> +
> +       mfc_debug_enter();
> +
> +       s5p_mfc_set_enc_params(ctx);
> +
> +       /* profile & level */
> +       reg = 0;
> +       /** profile */
> +       reg |= (0x1 << 4);
> +       WRITEL(reg, S5P_FIMV_E_PICTURE_PROFILE);
> +
> +       /* rate control config. */
> +       reg = READL(S5P_FIMV_E_RC_CONFIG);
> +       /** macroblock level rate control */
> +       reg &= ~(0x1 << 8);
> +       reg |= ((p->rc_mb & 0x1) << 8);
> +       WRITEL(reg, S5P_FIMV_E_RC_CONFIG);
> +       /** frame QP */
> +       reg &= ~(0x3F);
> +       reg |= p_h263->rc_frame_qp & 0x3F;
> +       WRITEL(reg, S5P_FIMV_E_RC_CONFIG);
> +
> +       /* max & min value of QP */
> +       reg = 0;
> +       /** max QP */
> +       reg |= ((p_h263->rc_max_qp & 0x3F) << 8);
> +       /** min QP */
> +       reg |= p_h263->rc_min_qp & 0x3F;
> +       WRITEL(reg, S5P_FIMV_E_RC_QP_BOUND);
> +
> +       /* other QPs */
> +       WRITEL(0x0, S5P_FIMV_E_FIXED_PICTURE_QP);
> +       if (!p->rc_frame && !p->rc_mb) {
> +               reg = 0;
> +               reg |= ((p_h263->rc_b_frame_qp & 0x3F) << 16);
> +               reg |= ((p_h263->rc_p_frame_qp & 0x3F) << 8);
> +               reg |= p_h263->rc_frame_qp & 0x3F;
> +               WRITEL(reg, S5P_FIMV_E_FIXED_PICTURE_QP);
> +       }
> +
> +       /* frame rate */
> +       if (p->rc_frame && p->rc_framerate_num && p->rc_framerate_denom) {
> +               reg = 0;
> +               reg |= ((p->rc_framerate_num & 0xFFFF) << 16);
> +               reg |= p->rc_framerate_denom & 0xFFFF;
> +               WRITEL(reg, S5P_FIMV_E_RC_FRAME_RATE);
> +       }
> +
> +       /* vbv buffer size */
> +       if (p->frame_skip_mode ==
> +                       V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) {
> +               WRITEL(p->vbv_size & 0xFFFF, S5P_FIMV_E_VBV_BUFFER_SIZE);
> +
> +               if (p->rc_frame)
> +                       WRITEL(p->vbv_delay, S5P_FIMV_E_VBV_INIT_DELAY);
> +       }
> +
> +       mfc_debug_leave();
> +
> +       return 0;
> +}
> +
> +/* Initialize decoding */
> +int s5p_mfc_init_decode(struct s5p_mfc_ctx *ctx)
> +{
> +       struct s5p_mfc_dev *dev = ctx->dev;
> +       unsigned int reg = 0;
> +       int fmo_aso_ctrl = 0;
> +
> +       mfc_debug_enter();
> +       mfc_debug(2, "InstNo: %d/%d\n", ctx->inst_no, S5P_FIMV_CH_SEQ_HEADER);
> +       mfc_debug(2, "BUFs: %08x %08x %08x\n",
> +                 READL(S5P_FIMV_D_CPB_BUFFER_ADDR),
> +                 READL(S5P_FIMV_D_CPB_BUFFER_ADDR),
> +                 READL(S5P_FIMV_D_CPB_BUFFER_ADDR));
> +
> +       /* FMO_ASO_CTRL - 0: Enable, 1: Disable */
> +       reg |= (fmo_aso_ctrl << S5P_FIMV_D_OPT_FMO_ASO_CTRL_MASK);
> +
> +       /* When user sets desplay_delay to 0,
> +        * It works as "display_delay enable" and delay set to 0.
> +        * If user wants display_delay disable, It should be
> +        * set to negative value. */
> +       if (ctx->display_delay >= 0) {
> +               reg |= (0x1 << S5P_FIMV_D_OPT_DDELAY_EN_SHIFT);
> +               WRITEL(ctx->display_delay, S5P_FIMV_D_DISPLAY_DELAY);
> +       }
> +       /* Setup loop filter, for decoding this is only valid for MPEG4 */
> +       if (ctx->codec_mode == S5P_FIMV_CODEC_MPEG4_DEC) {
> +               mfc_debug(2, "Set loop filter to: %d\n",
> +                               ctx->loop_filter_mpeg4);
> +               reg |= (ctx->loop_filter_mpeg4 <<
> +                               S5P_FIMV_D_OPT_LF_CTRL_SHIFT);
> +       }
> +       if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_NV12MT_16X16)
> +               reg |= (0x1 << S5P_FIMV_D_OPT_TILE_MODE_SHIFT);
> +
> +       WRITEL(reg, S5P_FIMV_D_DEC_OPTIONS);
> +
> +       /* 0: NV12(CbCr), 1: NV21(CrCb) */
> +       if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_NV21M)
> +               WRITEL(0x1, S5P_FIMV_PIXEL_FORMAT);
> +       else
> +               WRITEL(0x0, S5P_FIMV_PIXEL_FORMAT);
> +
> +       /* sei parse */
> +       WRITEL(ctx->sei_fp_parse & 0x1, S5P_FIMV_D_SEI_ENABLE);
> +
> +       WRITEL(ctx->inst_no, S5P_FIMV_INSTANCE_ID);
> +       s5p_mfc_cmd_host2risc(dev, S5P_FIMV_CH_SEQ_HEADER, NULL);
> +
> +       mfc_debug_leave();
> +       return 0;
> +}
> +
> +static inline void s5p_mfc_set_flush(struct s5p_mfc_ctx *ctx, int flush)
> +{
> +       struct s5p_mfc_dev *dev = ctx->dev;
> +       unsigned int dpb;
> +       if (flush)
> +               dpb = READL(S5P_FIMV_SI_CH0_DPB_CONF_CTRL) | (1 << 14);
> +       else
> +               dpb = READL(S5P_FIMV_SI_CH0_DPB_CONF_CTRL) & ~(1 << 14);
> +       WRITEL(dpb, S5P_FIMV_SI_CH0_DPB_CONF_CTRL);
> +}
> +
> +/* Decode a single frame */
> +int s5p_mfc_decode_one_frame(struct s5p_mfc_ctx *ctx, int last_frame)
> +{
> +       struct s5p_mfc_dev *dev = ctx->dev;
> +
> +       WRITEL(0xffffffff, S5P_FIMV_D_AVAILABLE_DPB_FLAG_LOWER);
> +       WRITEL(0xffffffff, S5P_FIMV_D_AVAILABLE_DPB_FLAG_UPPER);
> +       WRITEL(ctx->slice_interface & 0x1, S5P_FIMV_D_SLICE_IF_ENABLE);
> +
> +       WRITEL(ctx->inst_no, S5P_FIMV_INSTANCE_ID);
> +       /* Issue different commands to instance basing on whether it
> +        * is the last frame or not. */
> +       switch (last_frame) {
> +       case 0:
> +               s5p_mfc_cmd_host2risc(dev, S5P_FIMV_CH_FRAME_START, NULL);
> +               break;
> +       case 1:
> +               s5p_mfc_cmd_host2risc(dev, S5P_FIMV_CH_LAST_FRAME, NULL);
> +               break;
> +       }
> +
> +       mfc_debug(2, "Decoding a usual frame.\n");
> +       return 0;
> +}
> +
> +int s5p_mfc_init_encode(struct s5p_mfc_ctx *ctx)
> +{
> +       struct s5p_mfc_dev *dev = ctx->dev;
> +
> +       if (ctx->codec_mode == S5P_FIMV_CODEC_H264_ENC)
> +               s5p_mfc_set_enc_params_h264(ctx);
> +       else if (ctx->codec_mode == S5P_FIMV_CODEC_MPEG4_ENC)
> +               s5p_mfc_set_enc_params_mpeg4(ctx);
> +       else if (ctx->codec_mode == S5P_FIMV_CODEC_H263_ENC)
> +               s5p_mfc_set_enc_params_h263(ctx);
> +       else {
> +               mfc_err("Unknown codec for encoding (%x).\n",
> +                       ctx->codec_mode);
> +               return -EINVAL;
> +       }
> +
> +       WRITEL(ctx->inst_no, S5P_FIMV_INSTANCE_ID);
> +       s5p_mfc_cmd_host2risc(dev, S5P_FIMV_CH_SEQ_HEADER, NULL);
> +
> +       return 0;
> +}
> +
> +int s5p_mfc_h264_set_aso_slice_order(struct s5p_mfc_ctx *ctx)
> +{
> +       struct s5p_mfc_dev *dev = ctx->dev;
> +       struct s5p_mfc_enc_params *p = &ctx->enc_params;
> +       struct s5p_mfc_h264_enc_params *p_h264 = &p->codec.h264;
> +       int i;
> +
> +       if (p_h264->aso) {
> +               for (i = 0; i < 8; i++)
> +                       WRITEL(p_h264->aso_slice_order[i],
> +                               S5P_FIMV_E_H264_ASO_SLICE_ORDER_0 + i * 4);
> +       }
> +       return 0;
> +}
> +
> +/* Encode a single frame */
> +int s5p_mfc_encode_one_frame(struct s5p_mfc_ctx *ctx)
> +{
> +       struct s5p_mfc_dev *dev = ctx->dev;
> +
> +       mfc_debug(2, "++\n");
> +
> +       /* memory structure cur. frame */
> +
> +       if (ctx->codec_mode == S5P_FIMV_CODEC_H264_ENC)
> +               s5p_mfc_h264_set_aso_slice_order(ctx);
> +
> +       s5p_mfc_set_slice_mode(ctx);
> +
> +       WRITEL(ctx->inst_no, S5P_FIMV_INSTANCE_ID);
> +       s5p_mfc_cmd_host2risc(dev, S5P_FIMV_CH_FRAME_START, NULL);
> +
> +       mfc_debug(2, "--\n");
> +
> +       return 0;
> +}
> +
> +static inline int s5p_mfc_get_new_ctx(struct s5p_mfc_dev *dev)
> +{
> +       unsigned long flags;
> +       int new_ctx;
> +       int cnt;
> +
> +       spin_lock_irqsave(&dev->condlock, flags);
> +       mfc_debug(2, "Previos context: %d (bits %08lx)\n", dev->curr_ctx,
> +                                                       dev->ctx_work_bits);
> +       new_ctx = (dev->curr_ctx + 1) % MFC_NUM_CONTEXTS;
> +       cnt = 0;
> +       while (!test_bit(new_ctx, &dev->ctx_work_bits)) {
> +               new_ctx = (new_ctx + 1) % MFC_NUM_CONTEXTS;
> +               cnt++;
> +               if (cnt > MFC_NUM_CONTEXTS) {
> +                       /* No contexts to run */
> +                       spin_unlock_irqrestore(&dev->condlock, flags);
> +                       return -EAGAIN;
> +               }
> +       }
> +       spin_unlock_irqrestore(&dev->condlock, flags);
> +       return new_ctx;
> +}
> +
> +static inline void s5p_mfc_run_dec_last_frames(struct s5p_mfc_ctx *ctx)
> +{
> +       struct s5p_mfc_dev *dev = ctx->dev;
> +       struct s5p_mfc_buf *temp_vb;
> +       unsigned long flags;
> +
> +       spin_lock_irqsave(&dev->irqlock, flags);
> +
> +       /* Frames are being decoded */
> +       if (list_empty(&ctx->src_queue)) {
> +               mfc_debug(2, "No src buffers.\n");
> +               spin_unlock_irqrestore(&dev->irqlock, flags);
> +               return;
> +       }
> +       /* Get the next source buffer */
> +       temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
> +       temp_vb->used = 1;
> +       s5p_mfc_set_dec_stream_buffer(ctx,
> +                       vb2_dma_contig_plane_dma_addr(temp_vb->b, 0), 0, 0);
> +       spin_unlock_irqrestore(&dev->irqlock, flags);
> +
> +       dev->curr_ctx = ctx->num;
> +       s5p_mfc_clean_ctx_int_flags(ctx);
> +       s5p_mfc_decode_one_frame(ctx, 1);
> +}
> +
> +static inline int s5p_mfc_run_dec_frame(struct s5p_mfc_ctx *ctx)
> +{
> +       struct s5p_mfc_dev *dev = ctx->dev;
> +       struct s5p_mfc_buf *temp_vb;
> +       unsigned long flags;
> +       int last_frame = 0;
> +       unsigned int index;
> +
> +       spin_lock_irqsave(&dev->irqlock, flags);
> +
> +       /* Frames are being decoded */
> +       if (list_empty(&ctx->src_queue)) {
> +               mfc_debug(2, "No src buffers.\n");
> +               spin_unlock_irqrestore(&dev->irqlock, flags);
> +               return -EAGAIN;
> +       }
> +       /* Get the next source buffer */
> +       temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
> +       temp_vb->used = 1;
> +       s5p_mfc_set_dec_stream_buffer(ctx,
> +               vb2_dma_contig_plane_dma_addr(temp_vb->b, 0), 0,
> +                       temp_vb->b->v4l2_planes[0].bytesused);
> +       spin_unlock_irqrestore(&dev->irqlock, flags);
> +
> +       index = temp_vb->b->v4l2_buf.index;
> +
> +       dev->curr_ctx = ctx->num;
> +       s5p_mfc_clean_ctx_int_flags(ctx);
> +       if (temp_vb->b->v4l2_planes[0].bytesused == 0) {
> +               last_frame = 1;
> +               mfc_debug(2, "Setting ctx->state to FINISHING\n");
> +               ctx->state = MFCINST_FINISHING;
> +       }
> +       s5p_mfc_decode_one_frame(ctx, last_frame);
> +
> +       return 0;
> +}
> +
> +static inline int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
> +{
> +       struct s5p_mfc_dev *dev = ctx->dev;
> +       unsigned long flags;
> +       struct s5p_mfc_buf *dst_mb;
> +       struct s5p_mfc_buf *src_mb;
> +       unsigned long src_y_addr, src_c_addr, dst_addr;
> +       /*
> +       unsigned int src_y_size, src_c_size;
> +       */
> +       unsigned int dst_size;
> +       unsigned int index;
> +
> +       spin_lock_irqsave(&dev->irqlock, flags);
> +
> +       if (list_empty(&ctx->src_queue)) {
> +               mfc_debug(2, "no src buffers.\n");
> +               spin_unlock_irqrestore(&dev->irqlock, flags);
> +               return -EAGAIN;
> +       }
> +
> +       if (list_empty(&ctx->dst_queue)) {
> +               mfc_debug(2, "no dst buffers.\n");
> +               spin_unlock_irqrestore(&dev->irqlock, flags);
> +               return -EAGAIN;
> +       }
> +
> +       src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
> +       src_mb->used = 1;
> +       src_y_addr = vb2_dma_contig_plane_dma_addr(src_mb->b, 0);
> +       src_c_addr = vb2_dma_contig_plane_dma_addr(src_mb->b, 1);
> +
> +       mfc_debug(2, "enc src y addr: 0x%08lx", src_y_addr);
> +       mfc_debug(2, "enc src c addr: 0x%08lx", src_c_addr);
> +
> +       s5p_mfc_set_enc_frame_buffer(ctx, src_y_addr, src_c_addr);
> +
> +       dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);
> +       dst_mb->used = 1;
> +       dst_addr = vb2_dma_contig_plane_dma_addr(dst_mb->b, 0);
> +       dst_size = vb2_plane_size(dst_mb->b, 0);
> +
> +       s5p_mfc_set_enc_stream_buffer(ctx, dst_addr, dst_size);
> +
> +       spin_unlock_irqrestore(&dev->irqlock, flags);
> +
> +       index = src_mb->b->v4l2_buf.index;
> +
> +       dev->curr_ctx = ctx->num;
> +       s5p_mfc_clean_ctx_int_flags(ctx);
> +       s5p_mfc_encode_one_frame(ctx);
> +
> +       return 0;
> +}
> +
> +static inline void s5p_mfc_run_init_dec(struct s5p_mfc_ctx *ctx)
> +{
> +       struct s5p_mfc_dev *dev = ctx->dev;
> +       unsigned long flags;
> +       struct s5p_mfc_buf *temp_vb;
> +
> +       /* Initializing decoding - parsing header */
> +       spin_lock_irqsave(&dev->irqlock, flags);
> +       mfc_debug(2, "Preparing to init decoding.\n");
> +       temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
> +       mfc_debug(2, "Header size: %d\n", temp_vb->b->v4l2_planes[0].bytesused);
> +       s5p_mfc_set_dec_stream_buffer(ctx,
> +               vb2_dma_contig_plane_dma_addr(temp_vb->b, 0), 0,
> +                       temp_vb->b->v4l2_planes[0].bytesused);
> +       spin_unlock_irqrestore(&dev->irqlock, flags);
> +       dev->curr_ctx = ctx->num;
> +       s5p_mfc_clean_ctx_int_flags(ctx);
> +       s5p_mfc_init_decode(ctx);
> +}
> +
> +static inline void s5p_mfc_run_init_enc(struct s5p_mfc_ctx *ctx)
> +{
> +       struct s5p_mfc_dev *dev = ctx->dev;
> +       unsigned long flags;
> +       struct s5p_mfc_buf *dst_mb;
> +       unsigned long dst_addr;
> +       unsigned int dst_size;
> +
> +       spin_lock_irqsave(&dev->irqlock, flags);
> +
> +       dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);
> +       dst_addr = vb2_dma_contig_plane_dma_addr(dst_mb->b, 0);
> +       dst_size = vb2_plane_size(dst_mb->b, 0);
> +       s5p_mfc_set_enc_stream_buffer(ctx, dst_addr, dst_size);
> +       spin_unlock_irqrestore(&dev->irqlock, flags);
> +       dev->curr_ctx = ctx->num;
> +       s5p_mfc_clean_ctx_int_flags(ctx);
> +       s5p_mfc_init_encode(ctx);
> +}
> +
> +static inline int s5p_mfc_run_init_dec_buffers(struct s5p_mfc_ctx *ctx)
> +{
> +       struct s5p_mfc_dev *dev = ctx->dev;
> +       int ret;
> +       /* Header was parsed now start processing
> +        * First set the output frame buffers
> +        * s5p_mfc_alloc_dec_buffers(ctx); */
> +
> +       if (ctx->capture_state != QUEUE_BUFS_MMAPED) {
> +               mfc_err("It seems that not all destionation buffers were\n"
> +                       "mmaped.MFC requires that all destination are mmaped\n"
> +                       "before starting processing.\n");
> +               return -EAGAIN;
> +       }
> +
> +       dev->curr_ctx = ctx->num;
> +       s5p_mfc_clean_ctx_int_flags(ctx);
> +       ret = s5p_mfc_set_dec_frame_buffer(ctx);
> +       if (ret) {
> +               mfc_err("Failed to alloc frame mem.\n");
> +               ctx->state = MFCINST_ERROR;
> +       }
> +       return ret;
> +}
> +
> +static inline int s5p_mfc_run_init_enc_buffers(struct s5p_mfc_ctx *ctx)
> +{
> +       struct s5p_mfc_dev *dev = ctx->dev;
> +       int ret;
> +
> +       ret = s5p_mfc_alloc_codec_buffers(ctx);
> +       if (ret) {
> +               mfc_err("Failed to allocate encoding buffers.\n");
> +               return -ENOMEM;
> +       }
> +
> +       /* Header was generated now starting processing
> +        * First set the reference frame buffers
> +        */
> +       if (ctx->capture_state != QUEUE_BUFS_REQUESTED) {
> +               mfc_err("It seems that destionation buffers were not\n"
> +                       "requested.MFC requires that header should be generated\n"
> +                       "before allocating codec buffer.\n");
> +               return -EAGAIN;
> +       }
> +
> +       dev->curr_ctx = ctx->num;
> +       s5p_mfc_clean_ctx_int_flags(ctx);
> +       ret = s5p_mfc_set_enc_ref_buffer(ctx);
> +       if (ret) {
> +               mfc_err("Failed to alloc frame mem.\n");
> +               ctx->state = MFCINST_ERROR;
> +       }
> +       return ret;
> +}
> +
> +/* Try running an operation on hardware */
> +void s5p_mfc_try_run(struct s5p_mfc_dev *dev)
> +{
> +       struct s5p_mfc_ctx *ctx;
> +       int new_ctx;
> +       unsigned int ret = 0;
> +
> +       mfc_debug(1, "Try run dev: %p\n", dev);
> +
> +       /* Check whether hardware is not running */
> +       if (test_and_set_bit(0, &dev->hw_lock) != 0) {
> +               /* This is perfectly ok, the scheduled ctx should wait */
> +               mfc_debug(1, "Couldn't lock HW.\n");
> +               return;
> +       }
> +
> +       /* Choose the context to run */
> +       new_ctx = s5p_mfc_get_new_ctx(dev);
> +       if (new_ctx < 0) {
> +               /* No contexts to run */
> +               if (test_and_clear_bit(0, &dev->hw_lock) == 0) {
> +                       mfc_err("Failed to unlock hardware.\n");
> +                       return;
> +               }
> +
> +               mfc_debug(1, "No ctx is scheduled to be run.\n");
> +               return;
> +       }
> +
> +       mfc_debug(1, "New context: %d\n", new_ctx);
> +       ctx = dev->ctx[new_ctx];
> +       mfc_debug(1, "Seting new context to %p\n", ctx);
> +       /* Got context to run in ctx */
> +       mfc_debug(1, "ctx->dst_queue_cnt=%d ctx->dpb_count=%d ctx->src_queue_cnt=%d\n",
> +               ctx->dst_queue_cnt, ctx->dpb_count, ctx->src_queue_cnt);
> +       mfc_debug(1, "ctx->state=%d\n", ctx->state);
> +       /* Last frame has already been sent to MFC
> +        * Now obtaining frames from MFC buffer */
> +
> +       s5p_mfc_clock_on();
> +       if (ctx->type == MFCINST_DECODER) {
> +               switch (ctx->state) {
> +               case MFCINST_FINISHING:
> +                       s5p_mfc_run_dec_last_frames(ctx);
> +                       break;
> +               case MFCINST_RUNNING:
> +                       ret = s5p_mfc_run_dec_frame(ctx);
> +                       break;
> +               case MFCINST_INIT:
> +                       s5p_mfc_clean_ctx_int_flags(ctx);
> +                       ret = s5p_mfc_open_inst_cmd(ctx);
> +                       break;
> +               case MFCINST_RETURN_INST:
> +                       s5p_mfc_clean_ctx_int_flags(ctx);
> +                       ret = s5p_mfc_close_inst_cmd(ctx);
> +                       break;
> +               case MFCINST_GOT_INST:
> +                       s5p_mfc_run_init_dec(ctx);
> +                       break;
> +               case MFCINST_HEAD_PARSED:
> +                       ret = s5p_mfc_run_init_dec_buffers(ctx);
> +                       break;
> +               case MFCINST_RES_CHANGE_INIT:
> +                       s5p_mfc_run_dec_last_frames(ctx);
> +                       break;
> +               case MFCINST_RES_CHANGE_FLUSH:
> +                       s5p_mfc_run_dec_last_frames(ctx);
> +                       break;
> +               case MFCINST_RES_CHANGE_END:
> +                       mfc_debug(2, "Finished remaining frames after resolution change.\n");
> +                       ctx->capture_state = QUEUE_FREE;
> +                       mfc_debug(2, "Will re-init the codec`.\n");
> +                       s5p_mfc_run_init_dec(ctx);
> +                       break;
> +               default:
> +                       ret = -EAGAIN;
> +               }
> +       } else if (ctx->type == MFCINST_ENCODER) {
> +               switch (ctx->state) {
> +               case MFCINST_FINISHING:
> +               case MFCINST_RUNNING:
> +                       ret = s5p_mfc_run_enc_frame(ctx);
> +                       break;
> +               case MFCINST_INIT:
> +                       ret = s5p_mfc_open_inst_cmd(ctx);
> +                       break;
> +               case MFCINST_RETURN_INST:
> +                       ret = s5p_mfc_close_inst_cmd(ctx);
> +                       break;
> +               case MFCINST_GOT_INST:
> +                       s5p_mfc_run_init_enc(ctx);
> +                       break;
> +               case MFCINST_HEAD_PARSED: /* Only for MFC6.x */
> +                       ret = s5p_mfc_run_init_enc_buffers(ctx);
> +                       break;
> +               default:
> +                       ret = -EAGAIN;
> +               }
> +       } else {
> +               mfc_err("invalid context type: %d\n", ctx->type);
> +               ret = -EAGAIN;
> +       }
> +
> +       if (ret) {
> +               /* Free hardware lock */
> +               if (test_and_clear_bit(0, &dev->hw_lock) == 0)
> +                       mfc_err("Failed to unlock hardware.\n");
> +
> +               /* This is in deed imporant, as no operation has been
> +                * scheduled, reduce the clock count as no one will
> +                * ever do this, because no interrupt related to this try_run
> +                * will ever come from hardware. */
> +               s5p_mfc_clock_off();
> +       }
> +}
> +
> +
> +void s5p_mfc_cleanup_queue(struct list_head *lh, struct vb2_queue *vq)
> +{
> +       struct s5p_mfc_buf *b;
> +       int i;
> +
> +       while (!list_empty(lh)) {
> +               b = list_entry(lh->next, struct s5p_mfc_buf, list);
> +               for (i = 0; i < b->b->num_planes; i++)
> +                       vb2_set_plane_payload(b->b, i, 0);
> +               vb2_buffer_done(b->b, VB2_BUF_STATE_ERROR);
> +               list_del(&b->list);
> +       }
> +}
> +
> +void s5p_mfc_clear_int_flags(struct s5p_mfc_dev *dev)
> +{
> +       mfc_write(dev, 0, S5P_FIMV_RISC2HOST_CMD);
> +       mfc_write(dev, 0, S5P_FIMV_RISC2HOST_INT);
> +}
> +
> +void s5p_mfc_write_info(struct s5p_mfc_ctx *ctx, unsigned int data,
> +               unsigned int ofs)
> +{
> +       struct s5p_mfc_dev *dev = ctx->dev;
> +
> +       s5p_mfc_clock_on();
> +       WRITEL(data, ofs);
> +       s5p_mfc_clock_off();
> +}
> +
> +unsigned int s5p_mfc_read_info(struct s5p_mfc_ctx *ctx, unsigned int ofs)
> +{
> +       struct s5p_mfc_dev *dev = ctx->dev;
> +       int ret;
> +
> +       s5p_mfc_clock_on();
> +       ret = READL(ofs);
> +       s5p_mfc_clock_off();
> +
> +       return ret;
> +}
> diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_opr_v6.h b/drivers/media/video/s5p-mfc/s5p_mfc_opr_v6.h
> new file mode 100644
> index 0000000..93ce2d8
> --- /dev/null
> +++ b/drivers/media/video/s5p-mfc/s5p_mfc_opr_v6.h
> @@ -0,0 +1,140 @@
> +/*
> + * drivers/media/video/s5p-mfc/s5p_mfc_opr_v6.h
> + *
> + * Header file for Samsung MFC (Multi Function Codec - FIMV) driver
> + * Contains declarations of hw related functions.
> + *
> + * Copyright (c) 2012 Samsung Electronics
> + *             http://www.samsung.com/
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#ifndef S5P_MFC_OPR_V6_H_
> +#define S5P_MFC_OPR_V6_H_
> +
> +#include "s5p_mfc_common.h"
> +
> +#define MFC_CTRL_MODE_CUSTOM   MFC_CTRL_MODE_SFR
> +
> +int s5p_mfc_init_decode(struct s5p_mfc_ctx *ctx);
> +int s5p_mfc_init_encode(struct s5p_mfc_ctx *mfc_ctx);
> +
> +int s5p_mfc_set_dec_frame_buffer(struct s5p_mfc_ctx *ctx);
> +int s5p_mfc_set_dec_stream_buffer(struct s5p_mfc_ctx *ctx, int buf_addr,
> +                                                 unsigned int start_num_byte,
> +                                                 unsigned int buf_size);
> +
> +void s5p_mfc_set_enc_frame_buffer(struct s5p_mfc_ctx *ctx,
> +               unsigned long y_addr, unsigned long c_addr);
> +int s5p_mfc_set_enc_stream_buffer(struct s5p_mfc_ctx *ctx,
> +               unsigned long addr, unsigned int size);
> +void s5p_mfc_get_enc_frame_buffer(struct s5p_mfc_ctx *ctx,
> +               unsigned long *y_addr, unsigned long *c_addr);
> +int s5p_mfc_set_enc_ref_buffer(struct s5p_mfc_ctx *mfc_ctx);
> +
> +int s5p_mfc_decode_one_frame(struct s5p_mfc_ctx *ctx, int last_frame);
> +int s5p_mfc_encode_one_frame(struct s5p_mfc_ctx *mfc_ctx);
> +
> +/* Memory allocation */
> +int s5p_mfc_alloc_dec_temp_buffers(struct s5p_mfc_ctx *ctx);
> +void s5p_mfc_set_dec_desc_buffer(struct s5p_mfc_ctx *ctx);
> +void s5p_mfc_release_dec_desc_buffer(struct s5p_mfc_ctx *ctx);
> +
> +int s5p_mfc_alloc_codec_buffers(struct s5p_mfc_ctx *ctx);
> +void s5p_mfc_release_codec_buffers(struct s5p_mfc_ctx *ctx);
> +
> +int s5p_mfc_alloc_instance_buffer(struct s5p_mfc_ctx *ctx);
> +void s5p_mfc_release_instance_buffer(struct s5p_mfc_ctx *ctx);
> +int s5p_mfc_alloc_dev_context_buffer(struct s5p_mfc_dev *dev);
> +void s5p_mfc_release_dev_context_buffer(struct s5p_mfc_dev *dev);
> +
> +void s5p_mfc_dec_calc_dpb_size(struct s5p_mfc_ctx *ctx);
> +void s5p_mfc_enc_calc_src_size(struct s5p_mfc_ctx *ctx);
> +
> +#define s5p_mfc_get_dspl_y_adr()       (readl(dev->regs_base + \
> +                                       S5P_FIMV_SI_DISPLAY_Y_ADR))
> +#define s5p_mfc_get_dec_y_adr()                (readl(dev->regs_base + \
> +                                       S5P_FIMV_D_DISPLAY_LUMA_ADDR))
> +#define s5p_mfc_get_dspl_status()      readl(dev->regs_base + \
> +                                               S5P_FIMV_D_DISPLAY_STATUS)
> +#define s5p_mfc_get_decoded_status()   readl(dev->regs_base + \
> +                                               S5P_FIMV_D_DECODED_STATUS)
> +#define s5p_mfc_get_dec_frame_type()   (readl(dev->regs_base + \
> +                                               S5P_FIMV_D_DECODED_FRAME_TYPE) \
> +                                               & S5P_FIMV_DECODE_FRAME_MASK)
> +#define s5p_mfc_get_disp_frame_type()  (readl(ctx->dev->regs_base + \
> +                                               S5P_FIMV_D_DISPLAY_FRAME_TYPE) \
> +                                               & S5P_FIMV_DECODE_FRAME_MASK)
> +#define s5p_mfc_get_consumed_stream()  readl(dev->regs_base + \
> +                                               S5P_FIMV_D_DECODED_NAL_SIZE)
> +#define s5p_mfc_get_int_reason()       (readl(dev->regs_base + \
> +                                       S5P_FIMV_RISC2HOST_CMD) & \
> +                                       S5P_FIMV_RISC2HOST_CMD_MASK)
> +#define s5p_mfc_get_int_err()          readl(dev->regs_base + \
> +                                               S5P_FIMV_ERROR_CODE)
> +#define s5p_mfc_err_dec(x)             (((x) & S5P_FIMV_ERR_DEC_MASK) >> \
> +                                               S5P_FIMV_ERR_DEC_SHIFT)
> +#define s5p_mfc_err_dspl(x)            (((x) & S5P_FIMV_ERR_DSPL_MASK) >> \
> +                                               S5P_FIMV_ERR_DSPL_SHIFT)
> +#define s5p_mfc_get_img_width()                readl(dev->regs_base + \
> +                                               S5P_FIMV_D_DISPLAY_FRAME_WIDTH)
> +#define s5p_mfc_get_img_height()       readl(dev->regs_base + \
> +                                               S5P_FIMV_D_DISPLAY_FRAME_HEIGHT)
> +#define s5p_mfc_get_dpb_count()                readl(dev->regs_base + \
> +                                               S5P_FIMV_D_MIN_NUM_DPB)
> +#define s5p_mfc_get_inst_no()          readl(dev->regs_base + \
> +                                               S5P_FIMV_RET_INSTANCE_ID)
> +#define s5p_mfc_get_enc_dpb_count()    readl(dev->regs_base + \
> +                                               S5P_FIMV_E_NUM_DPB)
> +#define s5p_mfc_get_enc_strm_size()    readl(dev->regs_base + \
> +                                               S5P_FIMV_E_STREAM_SIZE)
> +#define s5p_mfc_get_enc_slice_type()   readl(dev->regs_base + \
> +                                               S5P_FIMV_E_SLICE_TYPE)
> +#define s5p_mfc_get_enc_pic_count()    readl(dev->regs_base + \
> +                                               S5P_FIMV_E_PICTURE_COUNT)
> +#define s5p_mfc_get_sei_avail_status() readl(dev->regs_base + \
> +                                               S5P_FIMV_D_FRAME_PACK_SEI_AVAIL)
> +#define s5p_mfc_get_mvc_num_views()    readl(dev->regs_base + \
> +                                               S5P_FIMV_D_MVC_NUM_VIEWS)
> +#define s5p_mfc_get_mvc_view_id()      readl(dev->regs_base + \
> +                                               S5P_FIMV_D_MVC_VIEW_ID)
> +
> +#define mb_width(x_size)               ((x_size + 15) / 16)
> +#define mb_height(y_size)              ((y_size + 15) / 16)
> +#define s5p_mfc_dec_mv_size(x, y)      (mb_width(x) * \
> +                                       (((mb_height(y)+1)/2)*2) * 64 + 128)
> +
> +/* Definition */
> +#define ENC_MULTI_SLICE_MB_MAX         ((1 << 30) - 1)
> +#define ENC_MULTI_SLICE_BIT_MIN                2800
> +#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_H264_H263          1
> +#define TIGHT_CBR_MAX                  10
> +
> +/* Definitions for shared memory compatibility */
> +#define PIC_TIME_TOP           S5P_FIMV_D_RET_PICTURE_TAG_TOP
> +#define PIC_TIME_BOT           S5P_FIMV_D_RET_PICTURE_TAG_BOT
> +#define CROP_INFO_H            S5P_FIMV_D_DISPLAY_CROP_INFO1
> +#define CROP_INFO_V            S5P_FIMV_D_DISPLAY_CROP_INFO2
> +
> +void s5p_mfc_try_run(struct s5p_mfc_dev *dev);
> +
> +void s5p_mfc_cleanup_queue(struct list_head *lh, struct vb2_queue *vq);
> +void s5p_mfc_clear_int_flags(struct s5p_mfc_dev *dev);
> +
> +void s5p_mfc_write_info(struct s5p_mfc_ctx *ctx, unsigned int data,
> +               unsigned int ofs);
> +unsigned int s5p_mfc_read_info(struct s5p_mfc_ctx *ctx, unsigned int ofs);
> +
> +#endif /* S5P_MFC_OPR_V6_H_ */
> diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_pm.c b/drivers/media/video/s5p-mfc/s5p_mfc_pm.c
> index 738a607..4fa0b54 100644
> --- a/drivers/media/video/s5p-mfc/s5p_mfc_pm.c
> +++ b/drivers/media/video/s5p-mfc/s5p_mfc_pm.c
> @@ -20,7 +20,11 @@
>  #include "s5p_mfc_debug.h"
>  #include "s5p_mfc_pm.h"
>
> -#define MFC_CLKNAME            "sclk_mfc"
> +#if defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC_V5)
> +#define MFC_CLKNAME            "sclk_mfc"
> +#elif defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC_V6)
> +#define MFC_CLKNAME            "aclk_333"
I think it can handle clkname without new config.

Thank you,
Kyungmin Park
> +#endif
>  #define MFC_GATE_CLK_NAME      "mfc"
>
>  #define CLK_DEBUG
> diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_shm.c b/drivers/media/video/s5p-mfc/s5p_mfc_shm.c
> index 91fdbac..9ee269d 100644
> --- a/drivers/media/video/s5p-mfc/s5p_mfc_shm.c
> +++ b/drivers/media/video/s5p-mfc/s5p_mfc_shm.c
> @@ -21,26 +21,28 @@ int s5p_mfc_init_shm(struct s5p_mfc_ctx *ctx)
>  {
>         struct s5p_mfc_dev *dev = ctx->dev;
>         void *shm_alloc_ctx = dev->alloc_ctx[MFC_BANK1_ALLOC_CTX];
> +       struct s5p_mfc_buf_size_v5 *buf_size = dev->variant->buf_size->priv;
>
> -       ctx->shm_alloc = vb2_dma_contig_memops.alloc(shm_alloc_ctx,
> -                                                       SHARED_BUF_SIZE);
> -       if (IS_ERR(ctx->shm_alloc)) {
> +       ctx->shm.alloc = vb2_dma_contig_memops.alloc(shm_alloc_ctx,
> +                                                       buf_size->shm);
> +       if (IS_ERR(ctx->shm.alloc)) {
>                 mfc_err("failed to allocate shared memory\n");
> -               return PTR_ERR(ctx->shm_alloc);
> +               return PTR_ERR(ctx->shm.alloc);
>         }
> -       /* shm_ofs only keeps the offset from base (port a) */
> -       ctx->shm_ofs = s5p_mfc_mem_cookie(shm_alloc_ctx, ctx->shm_alloc)
> +       /* shared memory offset only keeps the offset from base (port a) */
> +       ctx->shm.ofs = s5p_mfc_mem_cookie(shm_alloc_ctx, ctx->shm.alloc)
>                                                                 - dev->bank1;
> -       BUG_ON(ctx->shm_ofs & ((1 << MFC_BANK1_ALIGN_ORDER) - 1));
> -       ctx->shm = vb2_dma_contig_memops.vaddr(ctx->shm_alloc);
> -       if (!ctx->shm) {
> -               vb2_dma_contig_memops.put(ctx->shm_alloc);
> -               ctx->shm_ofs = 0;
> -               ctx->shm_alloc = NULL;
> +       BUG_ON(ctx->shm.ofs & ((1 << MFC_BANK1_ALIGN_ORDER) - 1));
> +
> +       ctx->shm.virt = vb2_dma_contig_memops.vaddr(ctx->shm.alloc);
> +       if (!ctx->shm.virt) {
> +               vb2_dma_contig_memops.put(ctx->shm.alloc);
> +               ctx->shm.alloc = NULL;
> +               ctx->shm.ofs = 0;
>                 mfc_err("failed to virt addr of shared memory\n");
>                 return -ENOMEM;
>         }
> -       memset((void *)ctx->shm, 0, SHARED_BUF_SIZE);
> +       memset((void *)ctx->shm.virt, 0, buf_size->shm);
>         wmb();
>         return 0;
>  }
> diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_shm.h b/drivers/media/video/s5p-mfc/s5p_mfc_shm.h
> index cf962a4..8400ab0 100644
> --- a/drivers/media/video/s5p-mfc/s5p_mfc_shm.h
> +++ b/drivers/media/video/s5p-mfc/s5p_mfc_shm.h
> @@ -71,20 +71,23 @@ enum MFC_SHM_OFS {
>         DBG_HISTORY_INPUT1      = 0xD4, /* C */
>         DBG_HISTORY_OUTPUT      = 0xD8, /* C */
>         HIERARCHICAL_P_QP       = 0xE0, /* E, H.264 */
> +       FRAME_PACK_SEI_ENABLE   = 0x168, /* C */
> +       FRAME_PACK_SEI_AVAIL    = 0x16c, /* D */
> +       FRAME_PACK_SEI_INFO     = 0x17c, /* E */
>  };
>
>  int s5p_mfc_init_shm(struct s5p_mfc_ctx *ctx);
>
> -#define s5p_mfc_write_shm(ctx, x, ofs)         \
> -       do {                                    \
> -               writel(x, (ctx->shm + ofs));    \
> -               wmb();                          \
> +#define s5p_mfc_write_shm(ctx, x, ofs)                 \
> +       do {                                            \
> +               writel(x, (ctx->shm.virt + ofs));       \
> +               wmb();                                  \
>         } while (0)
>
>  static inline u32 s5p_mfc_read_shm(struct s5p_mfc_ctx *ctx, unsigned int ofs)
>  {
>         rmb();
> -       return readl(ctx->shm + ofs);
> +       return readl(ctx->shm.virt + ofs);
>  }
>
>  #endif /* S5P_MFC_SHM_H_ */
> diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c
> index 9abd9ab..61d6583 100644
> --- a/drivers/media/video/v4l2-ctrls.c
> +++ b/drivers/media/video/v4l2-ctrls.c
> @@ -502,7 +502,6 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
>                 return mpeg4_profile;
>         case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
>                 return jpeg_chroma_subsampling;
> -
>         default:
>                 return NULL;
>         }
> --
> 1.7.0.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-media" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux