/*------------------------------------------------------------------------------
* MediaTek Inc. (C) 2020. All rights reserved.
*
* Copyright Statement:
*
* This software/firmware and related documentation ("MediaTek Software") are
* protected under relevant copyright laws. The information contained herein is
* confidential and proprietary to MediaTek Inc. and/or its licensors. Without
* the prior written permission of MediaTek inc. and/or its licensors, any
* reproduction, modification, use or disclosure of MediaTek Software, and
* information contained herein, in whole or in part, shall be strictly
* prohibited.
*
* BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
* ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL
* WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH
* RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
* INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES
* TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
* RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
* OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK
* SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE
* RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
* STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S
* ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE
* RELEASED HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE
* MEDIATEK SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
* CHARGE PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
*
* The following software/firmware and/or related documentation ("MediaTek
* Software") have been modified by MediaTek Inc. All revisions are subject to
* any receiver's applicable license agreements with MediaTek Inc.
*----------------------------------------------------------------------------*/

//-------------------------------------------------------------------------------------------------
//  Include Files
//-------------------------------------------------------------------------------------------------
// Common Definition
#include "MsCommon.h"
#ifndef MSOS_TYPE_LINUX_KERNEL
#include <string.h>
#endif
#include "MsTypes.h"
#include "MsIRQ.h"
#include "MsOS.h"
#include "drvMVOP.h"
#include "drvMIU.h"
#include "drvSYS.h"

// Internal Definition
#include "regMVOP.h"
#include "halMVOP.h"

#ifndef ANDROID
#define MVOP_PRINTF printf
#else
#include <sys/mman.h>
#include <cutils/ashmem.h>
#include <cutils/log.h>

#define MVOP_PRINTF ALOGD
#endif

// Common
#ifdef MSOS_TYPE_LINUX_KERNEL
#include <asm/div64.h>
#else
#define do_div(x,y) ((x)/=(y))
#define do_mod(x,y) ((x)%=(y))
#endif
//-------------------------------------------------------------------------------------------------
//  Driver Compiler Options
//-------------------------------------------------------------------------------------------------

//-------------------------------------------------------------------------------------------------
//  Local Defines
//-------------------------------------------------------------------------------------------------
#define MPLL_CLOCK_216              (216000000ULL)
#define MPLL_CLOCK_432              (432000000ULL)

#define BIT0    BIT(0)
#define BIT1    BIT(1)
#define BIT2    BIT(2)
#define BIT3    BIT(3)
#define BIT4    BIT(4)
#define BIT5    BIT(5)
#define BIT6    BIT(6)
#define BIT7    BIT(7)
#define BIT8    BIT(8)
#define BIT9    BIT(9)
#define BIT10   BIT(10)
#define BIT11   BIT(11)
#define BIT12   BIT(12)
#define BIT13   BIT(13)
#define BIT14   BIT(14)
#define BIT15   BIT(15)

#define ALIGN_UPTO_32(x)            ((((x) + 31) >> 5) << 5)
#define ALIGN_UPTO_16(x)            ((((x) + 15) >> 4) << 4)
#define ALIGN_UPTO_4(x)             ((((x) + 3) >> 2) << 2)
#define ALIGN_UPTO_2(x)             ((((x) + 1) >> 1) << 1)
#define ALIGN_DOWNTO_4(x)           (((x) >> 2) << 2)
#define ALIGN_DOWNTO_2(x)           (((x) >> 1) << 1)

#define MVOP_VBlank                 45
#define MVOP_HBlank_SD              200
#define MVOP_HBlank_HD              300

#define uHD_Width                   3840
#define uHD_Height                  2160

#define fHD_Width                   1920
#define fHD_Height                  1080

#define MaxHTT                      8190
#define MaxVTT                      8190

#define MAX_HCROP                   4096

#define HighByteMask                0xff00
#define LowByteMask                 0x00ff
#define SizeMask                    0x1fff

#define VSYNC_LINE_DOLBY            0x770
#define VSYNC_LINE_IMODE            0x1E
#define VSYNC_DELAY_BY_VB_END       0x100

#define MVOP_SYNC_CLOCK_BASE        86400000

#if MFDEC_HCROP_ALIGN
#define MFDEC_HCROP_ALIGN_0_START   2050
#define MFDEC_HCROP_ALIGN_0_END     2080
#define MFDEC_HCROP_ALIGN_1_START   2562
#define MFDEC_HCROP_ALIGN_1_END     2592
#define MFDEC_HCROP_ALIGN_2_START   3074
#define MFDEC_HCROP_ALIGN_2_END     3104
#define MFDEC_HCROP_ALIGN_3_START   3586
#define MFDEC_HCROP_ALIGN_3_END     3616
#endif

// SCPLL
#define SCPLL_SET_VAL               524288
#define SCPLL_WEIGHT                8
#define SCPLL_TEST_VAL              0x3
#define SCPLL_IN_DIV0_VAL           0x0
#define SCPLL_LOOP_DIV0_VAL         0x1
#define SCPLL_LOOP_DIV1_VAL         0x4
#define SCPLL_OUT_DIV_VAL           0x4
#define SCPLL_ICP_ICTRL_VAL         0x20

#if 0
static MS_U32 u32RiuBaseAdd = 0;
static MS_BOOL bMirrorModeVer = 0;
static MS_BOOL bMirrorModeHor = 0;
static MS_BOOL bMirrorMode = 0;
static MS_BOOL bSubMirrorModeVer = 0;
static MS_BOOL bSubMirrorModeHor = 0;
static MS_BOOL bSubMirrorMode = 0;
static MS_BOOL bEnableFreerunMode = FALSE;
static MS_BOOL bSubEnableFreerunMode = FALSE;
static MS_BOOL b3DLRMode = 0;  /// 3D L/R dual buffer mode
static MS_BOOL bSub3DLRMode = 0;
static MS_BOOL b3DLRAltOutput = FALSE;    /// 3D L/R line alternative output
static MS_BOOL bNewVSyncMode = FALSE;
static MVOP_RptFldMode eRepeatField = E_MVOP_RPTFLD_NONE;      /// mvop output repeating fields for single field input.
static MVOP_RptFldMode eSubRepeatField = E_MVOP_RPTFLD_NONE;   /// mvop output repeating fields for single field input.
static MVOP_RgbFormat eRgbFmt = E_MVOP_RGB_NONE;
static MVOP_RgbFormat eSubRgbFmt = E_MVOP_RGB_NONE;
#endif

typedef struct
{
    MS_BOOL bMirrorModeVer;
    MS_BOOL bMirrorModeHor;
    MS_BOOL bMirrorMode;
    MS_BOOL b3DLRMode;                  /// 3D L/R dual buffer mode
    MS_BOOL b3DLRAltOutput;             /// 3D L/R line alternative output
    MS_BOOL b3DLRAltSBSOutput;          /// 3D L/R side by side output
    MS_BOOL bNewVSyncMode;
    MVOP_RptFldMode eRepeatField;       /// mvop output repeating fields for single field input.
    MVOP_RgbFormat eRgbFmt;             /// eRgbFmt is cleared in HAL_MVOP_SetRgbFormat(Not in HAL_MVOP_ResetReg).
    MS_BOOL bIsInit;
    MS_BOOL bRptPreVsync;
    MS_BOOL bIs422;
    MS_BOOL bIsH265;
    MS_BOOL bIsHS;
    MS_U16  u16CropXStart;
    MS_U16  u16CropYStart;
    MS_U16  u16CropXSize;
    MS_U16  u16CropYSize;
    MS_BOOL bIs2p;
    MS_BOOL bIsEnable;
    MS_U16  u16VsyncLines;
    MVOP_OutputImodeType eInterlaceType;
    MS_BOOL bIsXcTrig;
    MS_BOOL bIsSinDV;
    MS_U16  u16ECONum;
    MS_BOOL bDramRdContd;
    MS_BOOL bForceP;
    MS_BOOL bIsEnLSB;
    MS_U32  u32DC0FrmCnt;
    MS_BOOL bIsDMSMCU;
    MS_U16  u16Reg20;
#if MFDEC_DB_PATCH
    MS_BOOL bMfdecEn;
#endif
    MVOP_TileFormat eTileFormat;
    MS_U16  u16MSBPitch;
#if GOP_BACKPORCH_PATCH
    MS_BOOL bIsUnComp;
#endif
    MS_U16  u16CurVCnt;
    MVOP_MFDECRotate eRotate;
    MVOP_FREQUENCY eClock;
    MS_BOOL bHSD;
    MS_U16  u16HSDOutput;
    MS_BOOL bDS_EN;
    MS_BOOL bOneField;
    MS_BOOL bAV1_FG;
#if MVOP_SUPPORT_SUB
    MS_BOOL bSubMirrorModeVer;
    MS_BOOL bSubMirrorModeHor;
    MS_BOOL bSubMirrorMode;
    MS_BOOL bSub3DLRMode;
    MS_BOOL bSubNewVSyncMode;
    MVOP_RptFldMode eSubRepeatField;    /// mvop output repeating fields for single field input.
    MVOP_RgbFormat eSubRgbFmt;
    MS_BOOL bSubIsInit;
    MS_BOOL bSubRptPreVsync;
    MS_BOOL bSubIs422;
    MS_BOOL bSubIsH265;
    MS_BOOL bSub3DLRAltOutput;          /// 3D L/R line alternative output
    MS_BOOL bSub3DLRAltSBSOutput;
    MS_BOOL bSubIsHS;
    MS_U16  u16SubCropXStart;
    MS_U16  u16SubCropYStart;
    MS_U16  u16SubCropXSize;
    MS_U16  u16SubCropYSize;
    MS_BOOL bSubIs2p;
    MS_BOOL bSubIsEnable;
    MS_U16  u16SubVsyncLines;
    MVOP_OutputImodeType eSubInterlaceType;
    MS_BOOL bSubIsXcTrig;
    MS_BOOL bSubDramRdContd;
    MS_BOOL bSubForceP;
    MS_BOOL bSubIsEnLSB;
    MS_BOOL bSubIsSinDV;
    MS_U32  u32DC1FrmCnt;
    MS_BOOL bSubIsDMSMCU;
    MS_U16  u16SubReg20;
    MVOP_TileFormat eSubTileFormat;
    MS_U16  u16SubMSBPitch;
#if GOP_BACKPORCH_PATCH
    MS_BOOL bSubIsUnComp;
#endif
    MS_U16  u16SubCurVCnt;
    MVOP_MFDECRotate eSubRotate;
    MVOP_FREQUENCY eSubClock;
    MS_BOOL bSubDS_EN;
    MS_BOOL bSubOneField;
    MS_BOOL bSubAV1_FG;
#endif
} MVOP_CTX_HAL;

static MVOP_CTX_HAL* g_pHalMVOPCtx = NULL;
static MS_VIRT u32RiuBaseAdd = 0;

#ifndef MSOS_TYPE_LINUX
MVOP_CTX_HAL g_stmvopHalCtx;
#endif
#if defined(SUPPORT_X_MODEL_FEATURE)
MVOP_CTX_HAL g_stmvopHalCtx;
#endif
#define RIU_MAP u32RiuBaseAdd           //obtained in init

#define RIU8    ((unsigned char  volatile *) RIU_MAP)
#define RIU16    ((MS_U16  volatile *) RIU_MAP)
#define MST_MACRO_START     do {
#define MST_MACRO_END       } while (0)

#define HAL_WriteByte( u32Reg, u8Val )                                                  \
    MST_MACRO_START                                                                     \
    if ( __builtin_constant_p( u32Reg ) )                                               \
    {                                                                                   \
        RIU8[((u32Reg) * 2) - ((u32Reg) & 1)] = u8Val;                                  \
    }                                                                                   \
    else                                                                                \
    {                                                                                   \
        RIU8[(u32Reg << 1) - (u32Reg & 1)] = u8Val;                                     \
    }                                                                                   \
    MST_MACRO_END

#define HAL_ReadByte( u32Reg )                                                          \
    (__builtin_constant_p( u32Reg ) ?                                                   \
    (((u32Reg) & 0x01) ? RIU8[(u32Reg) * 2 - 1] : RIU8[(u32Reg) * 2]) :                 \
    (RIU8[(u32Reg << 1) - (u32Reg & 1)]))

#define HAL_Read2Byte( u32Reg )                                                         \
    (RIU16[u32Reg])

#define HAL_ReadRegBit( u32Reg, u8Mask )                                                \
    (RIU8[(u32Reg) * 2 - ((u32Reg) & 1)] & (u8Mask))

#define HAL_WriteRegBit( u32Reg, bEnable, u8Mask )                                      \
    MST_MACRO_START                                                                     \
    MS_U32 u32Reg8 = ((u32Reg) * 2) - ((u32Reg) & 1);                                   \
    RIU8[u32Reg8] = (bEnable) ? (RIU8[u32Reg8] |  (u8Mask)) :                           \
                    (RIU8[u32Reg8] & ~(u8Mask));                                        \
    MST_MACRO_END

#define HAL_WriteByteMask( u32Reg, u8Val, u8Msk )                                       \
    MST_MACRO_START                                                                     \
    MS_U32 u32Reg8 = ((u32Reg) * 2) - ((u32Reg) & 1);                                   \
    RIU8[u32Reg8] = (RIU8[u32Reg8] & ~(u8Msk)) | ((u8Val) & (u8Msk));                   \
    MST_MACRO_END

#define HAL_Write2Byte(u32Reg, u16Val)                                                  \
    RIU16[u32Reg] = u16Val;

#define HAL_Write2ByteMask( u32Reg, u16Val, u16Msk )                                    \
    MST_MACRO_START                                                                     \
    RIU16[u32Reg] = (RIU16[u32Reg] & ~(u16Msk)) | ((u16Val) & (u16Msk));                \
    MST_MACRO_END

#define SUB_REG(x)         (x - MVOP_REG_BASE + MVOP_SUB_REG_BASE)

#define DEV_REG(x,y) ({                                                                 \
    MS_U32 u32Reg = 0;                                                                  \
    if (y == E_MVOP_DEV_0){                                                             \
        u32Reg = x;}                                                                    \
    else if (y == E_MVOP_DEV_1 && MVOP_SUPPORT_SUB){                                    \
        u32Reg = (x - MVOP_REG_BASE + MVOP_SUB_REG_BASE);}                              \
    else{                                                                               \
        u32Reg = x;}                                                                    \
    u32Reg;                                                                             \
    })                                                                       \

#define _FUNC_NOT_USED()        do {} while ( 0 )
#ifndef UNUSED
#define UNUSED(x) (void)(x)
#endif

#define LOWBYTE(u16)            ((MS_U8)(u16))
#define HIGHBYTE(u16)           ((MS_U8)((u16) >> 8))

#define VOP_ON_MIU1                     ((HAL_ReadByte(0x12F9) & BIT2) == BIT2)
#define _MaskMiuReq_MVOP_R( m )         HAL_WriteRegBit(0x12C7, m, BIT2)
#define _MaskMiu1Req_MVOP_R( m )        HAL_WriteRegBit(0x06C7, m, BIT2)

#define HAL_MIU_SetReqMask( miu_clients, mask ) \
    do { \
        if (VOP_ON_MIU1 == 0) \
            _MaskMiuReq_##miu_clients( mask ); \
        else \
            _MaskMiu1Req_##miu_clients( mask ); \
    } while (0)

#define SUBVOP_ON_MIU1                  ((HAL_ReadByte(0x12F9) & BIT2) == BIT2)
#define _MaskMiuReq_SUBMVOP_R( m )      HAL_WriteRegBit(0x12C7, m, BIT2)
#define _MaskMiu1Req_SUBMVOP_R( m )     HAL_WriteRegBit(0x06C7, m, BIT2)

#define HAL_MIU_SubSetReqMask( miu_clients, mask ) \
    do { \
        if (SUBVOP_ON_MIU1 == 0) \
            _MaskMiuReq_##miu_clients( mask ); \
        else \
            _MaskMiu1Req_##miu_clients( mask ); \
    } while (0)

#define MVOP_DBG_ENABLE 0
#if MVOP_DBG_ENABLE
#define MVOP_DBG(fmt, args...)       MVOP_PRINTF(fmt, ##args)
#else
#define MVOP_DBG(fmt, args...)       {}
#endif

typedef enum
{
    E_MVOP_INIT_OK            = 0,
    E_MVOP_INIT_FAIL          = 1,
    E_MVOP_INIT_ALREADY_EXIST = 2
} MVOP_HalInitCtxResults;
//-------------------------------------------------------------------------------------------------
//  Local Structures
//-------------------------------------------------------------------------------------------------


//-------------------------------------------------------------------------------------------------
//  Global Variables
//-------------------------------------------------------------------------------------------------

#define Y_INFO 0
#define UV_INFO 1
//-------------------------------------------------------------------------------------------------
//  Local Variables
//-------------------------------------------------------------------------------------------------


//-------------------------------------------------------------------------------------------------
//  Debug Functions
//-------------------------------------------------------------------------------------------------


//-------------------------------------------------------------------------------------------------
//  Local Functions
//-------------------------------------------------------------------------------------------------


//-------------------------------------------------------------------------------------------------
//  Global Functions
//-------------------------------------------------------------------------------------------------

void _HAL_MVOP_InitVarCtx(void)
{
    g_pHalMVOPCtx->bMirrorModeVer = 0;
    g_pHalMVOPCtx->bMirrorModeHor = 0;
    g_pHalMVOPCtx->bMirrorMode = 0;
    g_pHalMVOPCtx->b3DLRMode = 0;                           /// 3D L/R dual buffer mode
    g_pHalMVOPCtx->b3DLRAltOutput = FALSE;                  /// 3D L/R line alternative output
    g_pHalMVOPCtx->b3DLRAltSBSOutput = FALSE;
    g_pHalMVOPCtx->bNewVSyncMode = FALSE;
    g_pHalMVOPCtx->eRepeatField = E_MVOP_RPTFLD_NONE;       /// mvop output repeating fields for single field input.
    g_pHalMVOPCtx->eRgbFmt = E_MVOP_RGB_NONE;
    g_pHalMVOPCtx->bIsInit = 0;
    g_pHalMVOPCtx->bRptPreVsync = 0;
    g_pHalMVOPCtx->bIs422 = 0;
    g_pHalMVOPCtx->bIsH265 = 0;
    g_pHalMVOPCtx->bIsHS = FALSE;
    g_pHalMVOPCtx->u16CropXStart = 0;
    g_pHalMVOPCtx->u16CropYStart = 0;
    g_pHalMVOPCtx->u16CropXSize = 0;
    g_pHalMVOPCtx->u16CropYSize = 0;
    g_pHalMVOPCtx->bIs2p = FALSE;
    g_pHalMVOPCtx->bIsEnable = 0;
    g_pHalMVOPCtx->u16VsyncLines = 0;
    g_pHalMVOPCtx->eInterlaceType = E_MVOP_PRO;
    g_pHalMVOPCtx->bIsXcTrig = FALSE;
    g_pHalMVOPCtx->bIsSinDV = 0;
    g_pHalMVOPCtx->u16ECONum = 0;
    g_pHalMVOPCtx->bForceP = 0;
    g_pHalMVOPCtx->bIsEnLSB = 0;
    g_pHalMVOPCtx->bIsDMSMCU = TRUE;
    g_pHalMVOPCtx->bDramRdContd = FALSE;
    g_pHalMVOPCtx->u16Reg20 = 0;
#if MFDEC_DB_PATCH
    g_pHalMVOPCtx->bMfdecEn = FALSE;
#endif
    g_pHalMVOPCtx->eTileFormat = E_MVOP_TILE_NONE;
    g_pHalMVOPCtx->u16MSBPitch = 0;
#if GOP_BACKPORCH_PATCH
    g_pHalMVOPCtx->bIsUnComp = 0;
#endif
    g_pHalMVOPCtx->u16CurVCnt = 0;
    g_pHalMVOPCtx->eClock = E_MVOP_SYNCMODE;
    g_pHalMVOPCtx->bHSD = FALSE;
    g_pHalMVOPCtx->u16HSDOutput = 0;
    g_pHalMVOPCtx->bDS_EN = FALSE;
    g_pHalMVOPCtx->bAV1_FG = FALSE;
}

void _HAL_MVOP_SubInitVarCtx(void)
{
#if MVOP_SUPPORT_SUB
    g_pHalMVOPCtx->bSubMirrorModeVer = 0;
    g_pHalMVOPCtx->bSubMirrorModeHor = 0;
    g_pHalMVOPCtx->bSubMirrorMode = 0;
    g_pHalMVOPCtx->bSub3DLRMode = 0;
    g_pHalMVOPCtx->bSubNewVSyncMode = FALSE;
    g_pHalMVOPCtx->eSubRepeatField = E_MVOP_RPTFLD_NONE;    /// mvop output repeating fields for single field input.
    g_pHalMVOPCtx->eSubRgbFmt = E_MVOP_RGB_NONE;
    g_pHalMVOPCtx->bSubIsInit = 0;
    g_pHalMVOPCtx->bSubRptPreVsync = 0;
    g_pHalMVOPCtx->bSubIs422 = 0;
    g_pHalMVOPCtx->bSubIsH265 = 0;
    g_pHalMVOPCtx->bSub3DLRAltOutput = FALSE;               /// 3D L/R line alternative output
    g_pHalMVOPCtx->bSub3DLRAltSBSOutput = FALSE;
    g_pHalMVOPCtx->bSubIsHS = FALSE;
    g_pHalMVOPCtx->u16SubCropXStart = 0;
    g_pHalMVOPCtx->u16SubCropYStart = 0;
    g_pHalMVOPCtx->u16SubCropXSize = 0;
    g_pHalMVOPCtx->u16SubCropYSize = 0;
    g_pHalMVOPCtx->bSubIs2p = FALSE;
    g_pHalMVOPCtx->bSubIsEnable = 0;
    g_pHalMVOPCtx->u16SubVsyncLines = 0;
    g_pHalMVOPCtx->eSubInterlaceType = E_MVOP_PRO;
    g_pHalMVOPCtx->bSubIsXcTrig = FALSE;
    g_pHalMVOPCtx->bSubForceP = 0;
    g_pHalMVOPCtx->bSubIsEnLSB = 0;
    g_pHalMVOPCtx->bSubIsDMSMCU = TRUE;
    g_pHalMVOPCtx->bSubDramRdContd = FALSE;
    g_pHalMVOPCtx->u16SubReg20 = 0;
    g_pHalMVOPCtx->eSubTileFormat = E_MVOP_TILE_NONE;
    g_pHalMVOPCtx->u16SubMSBPitch = 0;
#if GOP_BACKPORCH_PATCH
    g_pHalMVOPCtx->bSubIsUnComp = 0;
#endif
    g_pHalMVOPCtx->u16SubCurVCnt = 0;
    g_pHalMVOPCtx->eSubClock = E_MVOP_SYNCMODE;
    g_pHalMVOPCtx->bSubDS_EN = FALSE;
    g_pHalMVOPCtx->bSubAV1_FG = FALSE;
#endif
}

MVOP_HalInitCtxResults _HAL_MVOP_InitContext(MS_BOOL* pbFirstDrvInstant)
{
    MS_BOOL bNeedInitShared = FALSE;

    //check first init by MsOS_SHM_GetId / MSOS_SHM_QUERY
#if 0
    if (g_pHalMVOPCtx)
    {
        // The context instance has been created already
        // before somewhere sometime in the same process.
        *pbFirstDrvInstant = bNeedInitShared;
        //return E_MVOP_INIT_FAIL;
        return E_MVOP_INIT_OK;
    }
#endif

#if defined(MSOS_TYPE_LINUX) || defined(MSOS_TYPE_LINUX_KERNEL)
#if !defined(SUPPORT_X_MODEL_FEATURE)
    MS_U32 u32ShmId;
    MS_VIRT u32Addr;
    MS_U32 u32BufSize;

    //MsOS_SHM_Init(); init in msos_init
    if (FALSE == MsOS_SHM_GetId((MS_U8*)"Linux MVOP HAL driver", sizeof(MVOP_CTX_HAL), &u32ShmId, &u32Addr, &u32BufSize, MSOS_SHM_QUERY))
    {
        if (FALSE == MsOS_SHM_GetId((MS_U8*)"Linux MVOP HAL driver", sizeof(MVOP_CTX_HAL), &u32ShmId, &u32Addr, &u32BufSize, MSOS_SHM_CREATE))
        {
            MVOP_DBG(MVOP_PRINTF("MVOP: SHM allocation failed!\n");)
            return E_MVOP_INIT_FAIL;
        }
        MVOP_DBG(MVOP_PRINTF("MVOP: [%s][%d] This is first initial 0x%08lx\n", __FUNCTION__, __LINE__, u32Addr);)
        memset((MS_U8*)u32Addr, 0, sizeof(MVOP_CTX_HAL));
        bNeedInitShared = TRUE;
        g_pHalMVOPCtx = (MVOP_CTX_HAL*)u32Addr;
        _HAL_MVOP_InitVarCtx();
#if MVOP_SUPPORT_SUB
        _HAL_MVOP_SubInitVarCtx();
#endif
    }
    else
    {
        g_pHalMVOPCtx = (MVOP_CTX_HAL*)u32Addr;
        bNeedInitShared = FALSE;
        *pbFirstDrvInstant = bNeedInitShared;

        return E_MVOP_INIT_ALREADY_EXIST;
    }
#else
    g_pHalMVOPCtx = &g_stmvopHalCtx;
    bNeedInitShared = TRUE;
#endif
#else
    g_pHalMVOPCtx = &g_stmvopHalCtx;
    bNeedInitShared = TRUE;
#endif
    *pbFirstDrvInstant = bNeedInitShared;

    if (bNeedInitShared)
    {
        memset(g_pHalMVOPCtx, 0, sizeof(*g_pHalMVOPCtx));
    }

    return E_MVOP_INIT_OK;
}

void _HAL_MVOP_MaskMIU(MVOP_DevID eID, MS_BOOL bEnMask)
{
    MS_BOOL bIsMCUMode = 0;

    switch (eID)
    {
        case E_MVOP_DEV_0:
            HAL_WriteRegBit(VOP_MIU_IF, bEnMask, VOP_MIU_REQ_DIS);
            if (bEnMask)
            {
                HAL_WriteByteMask(VOP_REG_MASK, VOP_LSB_REQ_MASK, VOP_LSB_REQ_MASK);
            }
            else
            {
                bIsMCUMode = (HAL_ReadRegBit(VOP_MPG_JPG_SWITCH, BIT0 | BIT1) == BIT1);
                if (g_pHalMVOPCtx->bIsEnLSB && bIsMCUMode)
                    HAL_WriteByteMask(VOP_REG_MASK, 0, VOP_LSB_REQ_MASK);
                else
                    HAL_WriteByteMask(VOP_REG_MASK, VOP_LSB_REQ_MASK, VOP_LSB_REQ_MASK);
            }
            break;
        case E_MVOP_DEV_1:
#if MVOP_SUPPORT_SUB
            HAL_WriteRegBit(SUB_REG(VOP_MIU_IF), bEnMask, VOP_MIU_REQ_DIS);
            if (bEnMask)
            {
                HAL_WriteByteMask(SUB_REG(VOP_REG_MASK), VOP_LSB_REQ_MASK, VOP_LSB_REQ_MASK);
            }
            else
            {
                bIsMCUMode = (HAL_ReadRegBit(SUB_REG(VOP_MPG_JPG_SWITCH), BIT0 | BIT1) == BIT1);
                if (g_pHalMVOPCtx->bSubIsEnLSB && bIsMCUMode)
                    HAL_WriteByteMask(SUB_REG(VOP_REG_MASK), 0, VOP_LSB_REQ_MASK);
                else
                    HAL_WriteByteMask(SUB_REG(VOP_REG_MASK), VOP_LSB_REQ_MASK, VOP_LSB_REQ_MASK);
            }
#endif
            break;
        default:
            break;
    }
    return;
}

void HAL_MVOP_RegSetBase(MS_VIRT u32Base)
{
    u32RiuBaseAdd = u32Base;
}

void HAL_MVOP_InitMirrorMode(MVOP_DevID eDevID, MS_BOOL bEnable)
{
    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            //set bit[3:7] to support mirror mode
            HAL_WriteRegBit(VOP_MIRROR_CFG, bEnable, VOP_MIRROR_CFG_ENABLE);
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            //set bit[3:7] to support mirror mode
            HAL_WriteRegBit(SUB_REG(VOP_MIRROR_CFG), bEnable, VOP_MIRROR_CFG_ENABLE);
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
}

void HAL_MVOP_SetVerticalMirrorMode(MVOP_DevID eDevID, MS_BOOL bEnable)
{
    if (NULL == g_pHalMVOPCtx)
    {
        MVOP_DBG(MVOP_PRINTF("%s g_pHalMVOPCtx is NULL pointer\n", __FUNCTION__);)
        return;
    }

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            if (VOP_MIRROR_CFG_ENABLE != HAL_ReadRegBit(VOP_MIRROR_CFG, VOP_MIRROR_CFG_ENABLE))
            {
                // MVOP_PRINTF("Setup mirror mode\n");
                HAL_MVOP_InitMirrorMode(E_MVOP_DEV_0, TRUE);
            }
            HAL_WriteRegBit(VOP_MIRROR_CFG, bEnable, VOP_MIRROR_CFG_VEN);
            g_pHalMVOPCtx->bMirrorModeVer = bEnable;
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            if (VOP_MIRROR_CFG_ENABLE != HAL_ReadRegBit(SUB_REG(VOP_MIRROR_CFG), VOP_MIRROR_CFG_ENABLE))
            {
                // MVOP_PRINTF("Setup mirror mode\n");
                HAL_MVOP_InitMirrorMode(E_MVOP_DEV_1, TRUE);
            }
            HAL_WriteRegBit(SUB_REG(VOP_MIRROR_CFG), bEnable, VOP_MIRROR_CFG_VEN);
            g_pHalMVOPCtx->bSubMirrorModeVer = bEnable;
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID = %u\n",
                __FUNCTION__, eDevID);
            break;
        }
    }
}

void HAL_MVOP_SetHorizontallMirrorMode(MVOP_DevID eDevID, MS_BOOL bEnable)
{
    if (NULL == g_pHalMVOPCtx)
    {
        MVOP_DBG(MVOP_PRINTF("%s g_pHalMVOPCtx is NULL pointer\n",
                             __FUNCTION__);)
        return;
    }

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            if (VOP_MIRROR_CFG_ENABLE != HAL_ReadRegBit(VOP_MIRROR_CFG,
                                                        VOP_MIRROR_CFG_ENABLE))
            {
                /* MVOP_PRINTF("Setup mirror mode\n"); */
                HAL_MVOP_InitMirrorMode(E_MVOP_DEV_0, TRUE);
            }
            HAL_WriteRegBit(VOP_MIRROR_CFG, bEnable, VOP_MIRROR_CFG_HEN);
            g_pHalMVOPCtx->bMirrorModeHor = bEnable;
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            if (VOP_MIRROR_CFG_ENABLE != HAL_ReadRegBit(SUB_REG(VOP_MIRROR_CFG),
                                                        VOP_MIRROR_CFG_ENABLE))
            {
                /* MVOP_PRINTF("Setup mirror mode\n"); */
                HAL_MVOP_InitMirrorMode(E_MVOP_DEV_1, TRUE);
            }
            HAL_WriteRegBit(SUB_REG(VOP_MIRROR_CFG), bEnable,
                            VOP_MIRROR_CFG_HEN);
            g_pHalMVOPCtx->bSubMirrorModeHor = bEnable;
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID = %u\n", __FUNCTION__,
                        eDevID);
            break;
        }
    }
}

void HAL_MVOP_Init(MVOP_DevID eDevID)
{
    MVOP_HalInitCtxResults eRet;
    MS_BOOL pbFirstDrvInstant;

    eRet = _HAL_MVOP_InitContext(&pbFirstDrvInstant);

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            if (eRet == E_MVOP_INIT_FAIL)
            {
                MVOP_DBG(MVOP_PRINTF("[%s] MVOP Context Init failed!\n", __FUNCTION__);)
                return;
            }
            else if (eRet == E_MVOP_INIT_ALREADY_EXIST)
            {
                if (g_pHalMVOPCtx->bIsInit)
                {
                    MVOP_DBG(MVOP_PRINTF("[%s] Main MVOP Context has Initialized!\n", __FUNCTION__);)
                    return;
                }
            }
            HAL_MVOP_InitMirrorMode(E_MVOP_DEV_0, TRUE);
            //Enable dynamic clock gating
            //Note: cannot enable VOP_GCLK_VCLK_ON, or hsync cannot be sent out.
            HAL_WriteByteMask(VOP_GCLK, VOP_GCLK_MIU_ON, VOP_GCLK_MIU_ON | VOP_GCLK_VCLK_ON);
            g_pHalMVOPCtx->bIsInit = 1;
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            if (eRet == E_MVOP_INIT_FAIL)
            {
                MVOP_DBG(MVOP_PRINTF("[%s] MVOP Context Init failed!\n", __FUNCTION__);)
                return;
            }
            else if (eRet == E_MVOP_INIT_ALREADY_EXIST)
            {
                if (g_pHalMVOPCtx->bSubIsInit)
                {
                    MVOP_DBG(MVOP_PRINTF("[%s] Sub MVOP Context has Initialized!\n", __FUNCTION__);)
                    return;
                }
            }
            HAL_MVOP_InitMirrorMode(E_MVOP_DEV_1, TRUE);
            //Enable dynamic clock gating
            //Note: cannot enable VOP_GCLK_VCLK_ON, or hsync cannot be sent out.
            HAL_WriteByteMask(SUB_REG(VOP_GCLK), VOP_GCLK_MIU_ON, VOP_GCLK_MIU_ON | VOP_GCLK_VCLK_ON);
            g_pHalMVOPCtx->bSubIsInit = 1;
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
}

void HAL_MVOP_SetFieldInverse(MVOP_DevID eDevID, MS_BOOL b2MVD, MS_BOOL b2IP)
{
    // Set fld inv & ofld_inv
    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            //inverse the field to MVD
            HAL_WriteRegBit(VOP_CTRL1, b2MVD, VOP_FLD_INV);
            //inverse the field to IP
            HAL_WriteRegBit(VOP_CTRL1, b2IP, VOP_OFLD_INV);
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            //inverse the field to MVD
            HAL_WriteRegBit(SUB_REG(VOP_CTRL1), b2MVD, VOP_FLD_INV);
            //inverse the field to IP
            HAL_WriteRegBit(SUB_REG(VOP_CTRL1), b2IP, VOP_OFLD_INV);
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
}

void HAL_MVOP_CheckFieldInverse(MVOP_DevID eDevID)
{
    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            MS_BOOL bMVD = (VOP_FLD_INV == HAL_ReadRegBit(VOP_CTRL1, VOP_FLD_INV));
            MS_BOOL bIP = (VOP_OFLD_INV == HAL_ReadRegBit(VOP_CTRL1, VOP_OFLD_INV));
            //MVOP_PRINTF("[MVOP] test mvd = %d, ip = %d, mir = %d, bypas = %d\n",bMVD,bIP,(g_pHalMVOPCtx->bMirrorModeVer),
            //(VOP_REG_FIELD_BYPASS == HAL_ReadRegBit(VOP_REG_DUMMY, VOP_REG_FIELD_BYPASS)));

            if ((g_pHalMVOPCtx->bMirrorModeVer) && (VOP_REG_FIELD_BYPASS ==
                HAL_ReadRegBit(VOP_REG_DUMMY, VOP_REG_FIELD_BYPASS)))
            {
                HAL_MVOP_SetFieldInverse(E_MVOP_DEV_0, bMVD, !bIP);
            }
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            MS_BOOL bMVD = (VOP_FLD_INV == HAL_ReadRegBit(SUB_REG(VOP_CTRL1), VOP_FLD_INV));
            MS_BOOL bIP = (VOP_OFLD_INV == HAL_ReadRegBit(SUB_REG(VOP_CTRL1), VOP_OFLD_INV));

            if ((g_pHalMVOPCtx->bSubMirrorModeVer) && (VOP_REG_FIELD_BYPASS ==
                HAL_ReadRegBit(SUB_REG(VOP_REG_DUMMY), VOP_REG_FIELD_BYPASS)))
            {
                HAL_MVOP_SetFieldInverse(E_MVOP_DEV_1, bMVD, !bIP);
            }
            break;
        }
#endif
    default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
}

void HAL_MVOP_SetChromaWeighting(MVOP_DevID eDevID, MS_BOOL bEnable)
{
    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            HAL_WriteRegBit(VOP_REG_WEIGHT_CTRL, bEnable, BIT1);
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            HAL_WriteRegBit(SUB_REG(VOP_REG_WEIGHT_CTRL), bEnable, BIT1);
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
}

//load new value into active registers 0x20-0x26
void HAL_MVOP_LoadReg(MVOP_DevID eDevID)
{
    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            HAL_WriteRegBit(VOP_REG_WR, 1, BIT0);
            HAL_WriteRegBit(VOP_REG_WR, 0, BIT0);
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            HAL_WriteRegBit(SUB_REG(VOP_REG_WR), 1, BIT0);
            HAL_WriteRegBit(SUB_REG(VOP_REG_WR), 0, BIT0);
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
}

void HAL_MVOP_ForceWriteReg(MVOP_DevID eDevID)
{
    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            HAL_WriteRegBit(VOP_REG_WR, 1, BIT4);
            HAL_WriteRegBit(VOP_REG_WR, 0, BIT4);
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            HAL_WriteRegBit(SUB_REG(VOP_REG_WR), 1, BIT4);
            HAL_WriteRegBit(SUB_REG(VOP_REG_WR), 0, BIT4);
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
}

void HAL_MVOP_SetMIUReqMask(MVOP_DevID eDevID, MS_BOOL bEnable)
{
    UNUSED(eDevID);
    UNUSED(bEnable);
    //using _HAL_MVOP_MaskMIU to mask
    return;
}

void HAL_MVOP_Rst(MVOP_DevID eDevID)
{
    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            HAL_WriteRegBit(VOP_CTRL0, 0, VOP_DC_EN);
            HAL_WriteRegBit(VOP_CTRL0, 1, VOP_DC_EN);
            g_pHalMVOPCtx->bIsEnable = 1;
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            HAL_WriteRegBit(SUB_REG(VOP_CTRL0), 0, VOP_DC_EN);
            HAL_WriteRegBit(SUB_REG(VOP_CTRL0), 1, VOP_DC_EN);
            g_pHalMVOPCtx->bSubIsEnable = 1;
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
}

void HAL_MVOP_Enable(MVOP_DevID eDevID, MS_BOOL bEnable)
{
    MS_U8 regval;

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            regval = HAL_ReadByte(VOP_CTRL0);
            if (bEnable)
            {
                regval |= VOP_DC_EN;
            }
            else
            {
                regval &= ~VOP_DC_EN;
                HAL_Write2Byte(VOP_BF_VS_MVD, 0x200);
                HAL_Write2Byte(VOP_TF_VS_MVD, 0x200);
            }
            g_pHalMVOPCtx->bIsEnable = bEnable;
            HAL_WriteByte(VOP_CTRL0, regval);
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            regval = HAL_ReadByte(SUB_REG(VOP_CTRL0));
            if (bEnable)
            {
                regval |= VOP_DC_EN;
            }
            else
            {
                regval &= ~VOP_DC_EN;
                HAL_Write2Byte(SUB_REG(VOP_BF_VS_MVD), 0x200);
                HAL_Write2Byte(SUB_REG(VOP_TF_VS_MVD), 0x200);
            }
            g_pHalMVOPCtx->bSubIsEnable = bEnable;
            HAL_WriteByte(SUB_REG(VOP_CTRL0), regval);
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
}

MS_BOOL HAL_MVOP_GetEnableState(MVOP_DevID eDevID)
{
    return (HAL_ReadRegBit(DEV_REG(VOP_CTRL0, eDevID), VOP_DC_EN));
}

MVOP_FREQUENCY HAL_MVOP_GetMaxFreerunClk(MVOP_DevID eDevID)
{
    MVOP_FREQUENCY eRet = E_MVOP_FREQ_NOT_SUPPORT;

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            eRet = E_MVOP_160MHZ;
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            eRet = E_MVOP_160MHZ;
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
    return eRet;
}

void HAL_MVOP_SetFrequency(MVOP_DevID eDevID, MVOP_FREQUENCY enFrequency)
{
    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            /* clear */
            HAL_WriteByteMask(REG_CKG_DC0, 0, CKG_DC0_MASK);

            switch (enFrequency)
            {
                case E_MVOP_SYNCMODE:
                {
                    HAL_WriteByteMask(REG_CKG_DC0,
                                      CKG_DC0_SYNCHRONOUS,
                                      CKG_DC0_MASK);
                    break;
                }
                case E_MVOP_FREERUNMODE:
                {
                    HAL_WriteByteMask(REG_CKG_DC0,
                                      CKG_DC0_FREERUN,
                                      CKG_DC0_MASK);
                    break;
                }
                case E_MVOP_HARDWAREMODE:
                {
                    HAL_WriteByteMask(REG_CKG_DC0,
                                      CKG_DC0_690MHZ,
                                      CKG_DC0_MASK);
                    break;
                }
                case E_MVOP_160MHZ:
                {
                    HAL_WriteByteMask(REG_CKG_DC0,
                                      CKG_DC0_160MHZ,
                                      CKG_DC0_MASK);
                    break;
                }
                case E_MVOP_144MHZ:
                {
                    HAL_WriteByteMask(REG_CKG_DC0,
                                      CKG_DC0_144MHZ,
                                      CKG_DC0_MASK);
                    break;
                }
                case E_MVOP_320MHZ:
                {
                    HAL_WriteByteMask(REG_CKG_DC0,
                                      CKG_DC0_320MHZ,
                                      CKG_DC0_MASK);
                    break;
                }
                case E_MVOP_690MHZ:
                {
                    HAL_WriteByteMask(REG_CKG_DC0,
                                      CKG_DC0_690MHZ,
                                      CKG_DC0_MASK);
                    break;
                }
                default:
                {
                    HAL_WriteByteMask(REG_CKG_DC0,
                                      CKG_DC0_SYNCHRONOUS,
                                      CKG_DC0_MASK);
                    MVOP_PRINTF("[%s] MVOP not support frequency\n",
                                __FUNCTION__);
                    break;
                }
            }
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            /* clear */
            HAL_WriteByteMask(REG_CKG_SUB_DC0, 0, CKG_SUB_DC0_MASK);

            switch (enFrequency)
            {
                case E_MVOP_SYNCMODE:
                {
                    HAL_WriteByteMask(REG_CKG_SUB_DC0,
                                      CKG_SUB_DC0_SYNCHRONOUS,
                                      CKG_SUB_DC0_MASK);
                    break;
                }
                case E_MVOP_FREERUNMODE:
                {
                    HAL_WriteByteMask(REG_CKG_SUB_DC0,
                                      CKG_SUB_DC0_FREERUN,
                                      CKG_SUB_DC0_MASK);
                    break;
                }
                case E_MVOP_160MHZ:
                {
                    HAL_WriteByteMask(REG_CKG_SUB_DC0,
                                      CKG_SUB_DC0_160MHZ,
                                      CKG_SUB_DC0_MASK);
                    break;
                }
                case E_MVOP_144MHZ:
                {
                    HAL_WriteByteMask(REG_CKG_SUB_DC0,
                                      CKG_SUB_DC0_144MHZ,
                                      CKG_SUB_DC0_MASK);
                    break;
                }
                case E_MVOP_320MHZ:
                {
                    HAL_WriteByteMask(REG_CKG_SUB_DC0,
                                      CKG_SUB_DC0_320MHZ,
                                      CKG_SUB_DC0_MASK);
                    break;
                }
                default:
                {
                    HAL_WriteByteMask(REG_CKG_SUB_DC0,
                                      CKG_SUB_DC0_SYNCHRONOUS,
                                      CKG_SUB_DC0_MASK);
                    MVOP_PRINTF("[%s] MVOP not support frequency\n",
                                __FUNCTION__);
                    break;
                }
            }
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
}

MVOP_FREQUENCY HAL_MVOP_GetMaximumClk(MVOP_DevID eDevID)
{
    MVOP_FREQUENCY eRet = E_MVOP_FREQ_NOT_SUPPORT;

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            // M7332/M7632/M7642 Get hardware clock by reading 0x110b
            eRet = E_MVOP_HARDWAREMODE;
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            // M7332/M7632/M7642 Sub MVOP max support 320MHZ
            eRet = E_MVOP_320MHZ;
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
    return eRet;
}

MVOP_FREQUENCY HAL_MVOP_GetCurrentClk(MVOP_DevID eDevID)
{
    MS_U8 u8DC0Clk;
    MVOP_FREQUENCY eRet = E_MVOP_FREQ_NOT_SUPPORT;

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            u8DC0Clk = HAL_ReadByte(REG_CKG_DC0) & CKG_DC0_MASK;
            switch (u8DC0Clk)
            {
                case CKG_DC0_SYNCHRONOUS:
                {
                    eRet = E_MVOP_SYNCMODE;
                    break;
                }
                case CKG_DC0_FREERUN:
                {
                    eRet = E_MVOP_FREERUNMODE;
                    break;
                }
                case CKG_DC0_144MHZ:
                {
                    eRet = E_MVOP_144MHZ;
                    break;
                }
                case CKG_DC0_160MHZ:
                {   eRet = E_MVOP_160MHZ;
                    break;
                }
                case CKG_DC0_320MHZ:
                {
                    eRet = E_MVOP_320MHZ;
                    break;
                }
                case CKG_DC0_690MHZ:
                {
                    // M7332/M7632/M7642 Get hardware clock by reading 0x110b
                    eRet = E_MVOP_HARDWAREMODE;
                    break;
                }
                default:
                {
                    break;
                }
            }
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            u8DC0Clk = HAL_ReadByte(REG_CKG_SUB_DC0) & CKG_SUB_DC0_MASK;
            switch (u8DC0Clk)
            {
                case CKG_SUB_DC0_SYNCHRONOUS:
                {
                    eRet = E_MVOP_SYNCMODE;
                    break;
                }
                case CKG_SUB_DC0_FREERUN:
                {
                    eRet = E_MVOP_FREERUNMODE;
                    break;
                }
                case CKG_SUB_DC0_144MHZ:
                {
                    eRet = E_MVOP_144MHZ;
                    break;
                }
                case CKG_SUB_DC0_160MHZ:
                {
                    eRet = E_MVOP_160MHZ;
                    break;
                }
                case CKG_SUB_DC0_320MHZ:
                {
                    eRet = E_MVOP_320MHZ;
                    break;
                }
                case CKG_DC0_690MHZ:
                {
                    eRet = E_MVOP_690MHZ;
                    break;
                }
                default:
                {
                    break;
                }
            }
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
    return eRet;
}

void HAL_MVOP_SetOutputInterlace(MVOP_DevID eDevID, MS_BOOL bEnable)
{
    MS_U8 regval;

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            regval = HAL_ReadByte(VOP_CTRL0);
#if MFDEC_ROTATE_INTERLACE
            if ((TRUE == bEnable)
                && !((E_MVOP_INT_TB_SEP_FRAME == g_pHalMVOPCtx->eInterlaceType)
                && (E_MVOP_MF_ROTATE_90 == g_pHalMVOPCtx->eRotate
                    || E_MVOP_MF_ROTATE_270 == g_pHalMVOPCtx->eRotate)))
#else
            if (TRUE == bEnable)
#endif
            {
                regval |= 0x80;
            }
            else
            {
                regval &= ~0x80;
            }
            if (TRUE == g_pHalMVOPCtx->bForceP)
            {
                HAL_MVOP_ForceWriteReg(E_MVOP_DEV_0);
                HAL_WriteRegBit(VOP_MIRROR_CFG, 0, VOP_FIELD_FROM_ADDR);
                /* reg_fld_md from riu set 0 / from wb set 1. */
                HAL_WriteRegBit(VOP_REG_DUMMY_5D_H, 0, VOP_FLD_WB);
            }
            HAL_WriteByte(VOP_CTRL0, regval);
            HAL_MVOP_LoadReg(E_MVOP_DEV_0);
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            regval = HAL_ReadByte(SUB_REG(VOP_CTRL0));
            if (TRUE == bEnable)
            {
                regval |= 0x80;
            }
            else
            {
                regval &= ~0x80;
            }
            if (TRUE == g_pHalMVOPCtx->bSubForceP)
            {
                HAL_MVOP_ForceWriteReg(E_MVOP_DEV_1);
                HAL_WriteRegBit(SUB_REG(VOP_MIRROR_CFG), 0,
                                VOP_FIELD_FROM_ADDR);
                /* reg_fld_md from riu set 0 / from wb set 1. */
                HAL_WriteRegBit(SUB_REG(VOP_REG_DUMMY_5D_H), 0, VOP_FLD_WB);
            }
            HAL_WriteByte(SUB_REG(VOP_CTRL0), regval);
            HAL_MVOP_LoadReg(E_MVOP_DEV_1);
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID = %u\n", __FUNCTION__,
                        eDevID);
            break;
        }
    }
}

void HAL_MVOP_SetPattern(MVOP_DevID eDevID, MVOP_Pattern enMVOPPattern)
{
    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            HAL_WriteByteMask(VOP_TST_IMG, enMVOPPattern, BIT2 | BIT1 | BIT0);
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            HAL_WriteByteMask(SUB_REG(VOP_TST_IMG), enMVOPPattern, BIT2 | BIT1 | BIT0);
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
}

MS_BOOL HAL_MVOP_SetTileFormat(MVOP_DevID eDevID, MVOP_TileFormat eTileFormat)
{
    MS_BOOL bRet = TRUE;

    if (g_pHalMVOPCtx == NULL)
    {
        MVOP_DBG(MVOP_PRINTF("%s g_pHalMVOPCtx is NULL pointer\n", __FUNCTION__);)
        bRet = FALSE;
        return bRet;
    }

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            g_pHalMVOPCtx->eTileFormat = eTileFormat;

            switch (eTileFormat)
            {
                case E_MVOP_TILE_8x32:
                {
                    HAL_WriteRegBit(VOP_REG_WR, 0, BIT1);
                    HAL_WriteRegBit(VOP_INPUT_SWITCH0, 0, EVD_ENABLE);
                    HAL_WriteRegBit(VOP_INPUT_SWITCH0, 0, VOP_TILE_32x32);
                    HAL_WriteRegBit(VOP_INPUT_SWITCH0, 0, VOP_DE_COMP_EN);
                    HAL_WriteRegBit(VOP_INPUT_SWITCH0, 0, VOP_DE_COMP_MD);
                    break;
                }
                case E_MVOP_TILE_16x32:
                {
                    HAL_WriteRegBit(VOP_REG_WR, 1, BIT1);
                    HAL_WriteRegBit(VOP_INPUT_SWITCH0, 0, EVD_ENABLE);
                    HAL_WriteRegBit(VOP_INPUT_SWITCH0, 0, VOP_TILE_32x32);
                    HAL_WriteRegBit(VOP_INPUT_SWITCH0, 0, VOP_DE_COMP_EN);
                    HAL_WriteRegBit(VOP_INPUT_SWITCH0, 0, VOP_DE_COMP_MD);
                    break;
                }
                case E_MVOP_TILE_32x16:
                {
                    HAL_WriteRegBit(VOP_REG_WR, 0, BIT1);
                    HAL_WriteRegBit(VOP_INPUT_SWITCH0, 1, EVD_ENABLE);
                    HAL_WriteRegBit(VOP_INPUT_SWITCH0, 0, VOP_TILE_32x32);
                    HAL_WriteRegBit(VOP_INPUT_SWITCH0, 0, VOP_DE_COMP_EN);
                    HAL_WriteRegBit(VOP_INPUT_SWITCH0, 0, VOP_DE_COMP_MD);
                    break;
                }
                case E_MVOP_TILE_32x32:
                {
                    HAL_WriteRegBit(VOP_REG_WR, 0, BIT1);
                    HAL_WriteRegBit(VOP_INPUT_SWITCH0, 0, EVD_ENABLE);
                    HAL_WriteRegBit(VOP_INPUT_SWITCH0, 1, VOP_TILE_32x32);
                    HAL_WriteRegBit(VOP_INPUT_SWITCH0, 0, VOP_DE_COMP_EN);
                    HAL_WriteRegBit(VOP_INPUT_SWITCH0, 0, VOP_DE_COMP_MD);
                    break;
                }
                case E_MVOP_TILE_COMP_32x16_82PACK:
                {
                    HAL_WriteRegBit(VOP_REG_WR, 0, BIT1);
                    HAL_WriteRegBit(VOP_INPUT_SWITCH0, 1, EVD_ENABLE);
                    HAL_WriteRegBit(VOP_INPUT_SWITCH0, 0, VOP_TILE_32x32);
                    HAL_WriteRegBit(VOP_INPUT_SWITCH0, 0, VOP_DE_COMP_EN);
                    HAL_WriteRegBit(VOP_INPUT_SWITCH0, 0, VOP_DE_COMP_MD);
                    break;
                }
                case E_MVOP_TILE_COMP_4x2:
                {
                    HAL_WriteRegBit(VOP_INPUT_SWITCH0, 0, EVD_ENABLE);
                    HAL_WriteRegBit(VOP_INPUT_SWITCH0, 0, VOP_TILE_32x32);
                    HAL_WriteRegBit(VOP_INPUT_SWITCH0, 1, VOP_DE_COMP_EN);
                    HAL_WriteRegBit(VOP_INPUT_SWITCH0, 1, VOP_DE_COMP_MD);
                    break;
                }
                default:
                {
                    HAL_WriteRegBit(VOP_INPUT_SWITCH0, 0, EVD_ENABLE);
                    HAL_WriteRegBit(VOP_INPUT_SWITCH0, 0, VOP_TILE_32x32);
                    HAL_WriteRegBit(VOP_INPUT_SWITCH0, 0, VOP_DE_COMP_EN);
                    HAL_WriteRegBit(VOP_INPUT_SWITCH0, 0, VOP_DE_COMP_MD);
                    bRet = FALSE;
                    break;
                }
            }
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            g_pHalMVOPCtx->eSubTileFormat = eTileFormat;

            switch (eTileFormat)
            {
                case E_MVOP_TILE_8x32:
                {
                    HAL_WriteRegBit(SUB_REG(VOP_REG_WR), 0, BIT1);
                    HAL_WriteRegBit(SUB_REG(VOP_INPUT_SWITCH0), 0, EVD_ENABLE);
                    HAL_WriteRegBit(SUB_REG(VOP_INPUT_SWITCH0), 0, VOP_TILE_32x32);
                    HAL_WriteRegBit(SUB_REG(VOP_INPUT_SWITCH0), 0, VOP_DE_COMP_EN);
                    HAL_WriteRegBit(SUB_REG(VOP_INPUT_SWITCH0), 0, VOP_DE_COMP_MD);
                    break;
                }
                case E_MVOP_TILE_16x32:
                {
                    HAL_WriteRegBit(SUB_REG(VOP_REG_WR), 1, BIT1);
                    HAL_WriteRegBit(SUB_REG(VOP_INPUT_SWITCH0), 0, EVD_ENABLE);
                    HAL_WriteRegBit(SUB_REG(VOP_INPUT_SWITCH0), 0, VOP_TILE_32x32);
                    HAL_WriteRegBit(SUB_REG(VOP_INPUT_SWITCH0), 0, VOP_DE_COMP_EN);
                    HAL_WriteRegBit(SUB_REG(VOP_INPUT_SWITCH0), 0, VOP_DE_COMP_MD);
                    break;
                }
                case E_MVOP_TILE_32x16:
                {
                    HAL_WriteRegBit(SUB_REG(VOP_REG_WR), 0, BIT1);
                    HAL_WriteRegBit(SUB_REG(VOP_INPUT_SWITCH0), 1, EVD_ENABLE);
                    HAL_WriteRegBit(SUB_REG(VOP_INPUT_SWITCH0), 0, VOP_TILE_32x32);
                    HAL_WriteRegBit(SUB_REG(VOP_INPUT_SWITCH0), 0, VOP_DE_COMP_EN);
                    HAL_WriteRegBit(SUB_REG(VOP_INPUT_SWITCH0), 0, VOP_DE_COMP_MD);
                    break;
                }
                case E_MVOP_TILE_32x32:
                {
                    HAL_WriteRegBit(SUB_REG(VOP_REG_WR), 0, BIT1);
                    HAL_WriteRegBit(SUB_REG(VOP_INPUT_SWITCH0), 0, EVD_ENABLE);
                    HAL_WriteRegBit(SUB_REG(VOP_INPUT_SWITCH0), 1, VOP_TILE_32x32);
                    HAL_WriteRegBit(SUB_REG(VOP_INPUT_SWITCH0), 0, VOP_DE_COMP_EN);
                    HAL_WriteRegBit(SUB_REG(VOP_INPUT_SWITCH0), 0, VOP_DE_COMP_MD);
                    break;
                }
                case E_MVOP_TILE_COMP_32x16_82PACK:
                {
                    HAL_WriteRegBit(SUB_REG(VOP_REG_WR), 0, BIT1);
                    HAL_WriteRegBit(SUB_REG(VOP_INPUT_SWITCH0), 1, EVD_ENABLE);
                    HAL_WriteRegBit(SUB_REG(VOP_INPUT_SWITCH0), 0, VOP_TILE_32x32);
                    HAL_WriteRegBit(SUB_REG(VOP_INPUT_SWITCH0), 0, VOP_DE_COMP_EN);
                    HAL_WriteRegBit(SUB_REG(VOP_INPUT_SWITCH0), 0, VOP_DE_COMP_MD);
                    break;
                }
                case E_MVOP_TILE_COMP_4x2:
                {
                    HAL_WriteRegBit(SUB_REG(VOP_INPUT_SWITCH0), 0, EVD_ENABLE);
                    HAL_WriteRegBit(SUB_REG(VOP_INPUT_SWITCH0), 0, VOP_TILE_32x32);
                    HAL_WriteRegBit(SUB_REG(VOP_INPUT_SWITCH0), 1, VOP_DE_COMP_EN);
                    HAL_WriteRegBit(SUB_REG(VOP_INPUT_SWITCH0), 1, VOP_DE_COMP_MD);
                    break;
                }
                default:
                {
                    HAL_WriteRegBit(SUB_REG(VOP_INPUT_SWITCH0), 0, EVD_ENABLE);
                    HAL_WriteRegBit(SUB_REG(VOP_INPUT_SWITCH0), 0, VOP_TILE_32x32);
                    HAL_WriteRegBit(SUB_REG(VOP_INPUT_SWITCH0), 0, VOP_DE_COMP_EN);
                    HAL_WriteRegBit(SUB_REG(VOP_INPUT_SWITCH0), 0, VOP_DE_COMP_MD);
                    bRet = FALSE;
                    break;
                }
            }
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            bRet = FALSE;
            break;
        }
    }
    return bRet;
}

MS_BOOL HAL_MVOP_GetSupportRgbFormat(MVOP_RgbFormat eRgbFmt)
{
    if ((eRgbFmt == E_MVOP_RGB_565) || (eRgbFmt == E_MVOP_RGB_888))
    {
        return TRUE;
    }
    return FALSE;
}

MS_BOOL HAL_MVOP_SetRgbFormat(MVOP_DevID eDevID, MVOP_RgbFormat eRgbFmt)
{
    MS_BOOL bRet = FALSE;

    if (g_pHalMVOPCtx == NULL)
    {
        MVOP_DBG(MVOP_PRINTF("%s g_pHalMVOPCtx is NULL pointer\n", __FUNCTION__);)
        return bRet;
    }

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            switch (eRgbFmt)
            {
                case E_MVOP_RGB_NONE:
                {
                    HAL_WriteByteMask(VOP_RGB_FMT, 0, VOP_RGB_FMT_SEL);
                    g_pHalMVOPCtx->eRgbFmt = eRgbFmt;
                    bRet = TRUE;
                    break;
                }
                case E_MVOP_RGB_565:
                {
                    HAL_WriteByteMask(VOP_RGB_FMT, VOP_RGB_FMT_565, VOP_RGB_FMT_SEL);
                    g_pHalMVOPCtx->eRgbFmt = eRgbFmt;
                    bRet = TRUE;
                    break;
                }
                case E_MVOP_RGB_888:
                {
                    HAL_WriteByteMask(VOP_RGB_FMT, VOP_RGB_FMT_888, VOP_RGB_FMT_SEL);
                    g_pHalMVOPCtx->eRgbFmt = eRgbFmt;
                    bRet = TRUE;
                    break;
                }
                default:
                {
                    MVOP_PRINTF("[%s] MVOP not support color format\n", __FUNCTION__);
                    break;
                }
                MVOP_DBG(MVOP_PRINTF("[MVOP][DBG] %s rgb = 0x%x\n", __FUNCTION__, g_pHalMVOPCtx->eRgbFmt);)
            }
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            switch (eRgbFmt)
            {
                case E_MVOP_RGB_NONE:
                {
                    HAL_WriteByteMask(SUB_REG(VOP_RGB_FMT), 0, VOP_RGB_FMT_SEL);
                    g_pHalMVOPCtx->eSubRgbFmt = eRgbFmt;
                    bRet = TRUE;
                    break;
                }
                case E_MVOP_RGB_565:
                {
                    HAL_WriteByteMask(SUB_REG(VOP_RGB_FMT), VOP_RGB_FMT_565, VOP_RGB_FMT_SEL);
                    g_pHalMVOPCtx->eSubRgbFmt = eRgbFmt;
                    bRet = TRUE;
                    break;
                }
                case E_MVOP_RGB_888:
                {
                    HAL_WriteByteMask(SUB_REG(VOP_RGB_FMT), VOP_RGB_FMT_888, VOP_RGB_FMT_SEL);
                    g_pHalMVOPCtx->eSubRgbFmt = eRgbFmt;
                    bRet = TRUE;
                    break;
                }
                default:
                {
                    MVOP_PRINTF("[%s] MVOP not support color format\n", __FUNCTION__);
                    break;
                }
                MVOP_DBG(MVOP_PRINTF("[MVOP][DBG] %s rgb = 0x%x\n", __FUNCTION__, g_pHalMVOPCtx->eSubRgbFmt);)
            }
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
    return bRet;
}

void HAL_MVOP_SetBlackBG(MVOP_DevID eDevID)
{
    MS_U8 regval;

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            //set MVOP test pattern to black
            HAL_WriteByte((VOP_TST_IMG + 1), 0x10);
            HAL_WriteByte(VOP_U_PAT, 0x80);
            HAL_WriteByte((VOP_U_PAT   + 1), 0x80);

            regval = HAL_ReadByte(VOP_TST_IMG);
            HAL_WriteByte(VOP_TST_IMG, 0x02);
            HAL_WriteByte(VOP_TST_IMG, 0x00);
            HAL_WriteByte(VOP_TST_IMG, regval);
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            //set MVOP test pattern to black
            HAL_WriteByte(SUB_REG(VOP_TST_IMG + 1), 0x10);
            HAL_WriteByte(SUB_REG(VOP_U_PAT), 0x80);
            HAL_WriteByte(SUB_REG(VOP_U_PAT   + 1), 0x80);

            regval = HAL_ReadByte(SUB_REG(VOP_TST_IMG));
            HAL_WriteByte(SUB_REG(VOP_TST_IMG), 0x02);
            HAL_WriteByte(SUB_REG(VOP_TST_IMG), 0x00);
            HAL_WriteByte(SUB_REG(VOP_TST_IMG), regval);
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
}

void HAL_MVOP_SetCropWindow(MVOP_DevID eDevID, MVOP_InputCfg* pparam)
{
#if 1
    UNUSED(eDevID);
    UNUSED(pparam);
#else /* enable it when test code is ready */
    MS_U32 x;
    MS_U32 y;
    MS_U32 u32offset;

    if (FALSE == pparam)
    {
        return;
    }
    /* set MVOP test pattern to black */
    HAL_MVOP_SetBlackBG(eDevID);
#if 0
    if ((MVOP_H264 == pparam->enVideoType)
        && (fHD_Width == pparam->u16StripSize))
    {
        pparam->u16StripSize = 1952;
    }
#endif
    if ((MVOP_MPG == pparam->enVideoType)
        || (MVOP_MPEG4 == pparam->enVideoType))
    {
        /* 8 bytes align */
        pparam->u16CropX = (pparam->u16CropX >> 3) << 3;
        /* 64 bytes align */
        pparam->u16CropY = (pparam->u16CropY >> 6) << 6;
    }
    else if ((MVOP_H264 == pparam->enVideoType)
             || (MVOP_RM == pparam->enVideoType))
    {
        /* 16 bytes align */
        pparam->u16CropX = (pparam->u16CropX >> 4) << 4;
        /* 64 bytes align */
        pparam->u16CropY = (pparam->u16CropY >> 6) << 6;
    }
    else
    {
        MS_ASSERT(0);
    }

    x = (MS_U32)pparam->u16CropX;
    y = (MS_U32)pparam->u16CropY;

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            /* y offset */
            u32offset = ((y * pparam->u16StripSize + (x << 5)) >> 3);
            HAL_WriteByte((VOP_JPG_YSTR0_L), (MS_U8)(u32offset));
            HAL_WriteByte((VOP_JPG_YSTR0_L + 1), (MS_U8)(u32offset >> 8));
            HAL_WriteByte((VOP_JPG_YSTR0_H), (MS_U8)(u32offset >> 16));
            HAL_WriteByte((VOP_JPG_YSTR0_H + 1),
                          (MS_U8)((u32offset >> 24) & VOP_YUV_STR_HIBITS));

            /* uv offset */
            u32offset = ((y >> 1) * pparam->u16StripSize + (x << 5)) >> 3;
            HAL_WriteByte((VOP_JPG_UVSTR0_L), (MS_U8)(u32offset));
            HAL_WriteByte((VOP_JPG_UVSTR0_L + 1), (MS_U8)(u32offset >> 8));
            HAL_WriteByte((VOP_JPG_UVSTR0_H), (MS_U8)(u32offset >> 16));
            HAL_WriteByte((VOP_JPG_UVSTR0_H + 1),
                          (MS_U8)((u32offset >> 24) & VOP_YUV_STR_HIBITS));

            pparam->u16CropWidth = (pparam->u16CropWidth >> 3) << 3;

            /* HSize, VSize */
            HAL_WriteByte((VOP_JPG_HSIZE), LOWBYTE(pparam->u16CropWidth));
            HAL_WriteByte((VOP_JPG_HSIZE + 1), HIGHBYTE(pparam->u16CropWidth));
            HAL_WriteByte((VOP_JPG_VSIZE), LOWBYTE(pparam->u16CropHeight));
            HAL_WriteByte((VOP_JPG_VSIZE + 1), HIGHBYTE(pparam->u16CropHeight));

            HAL_WriteByteMask(VOP_MPG_JPG_SWITCH, BIT0, BIT1 | BIT0);

            /* clear extend strip len bit by default */
            HAL_WriteRegBit(VOP_REG_STRIP_ALIGN, 0, BIT0);
            if ((MVOP_MPG == pparam->enVideoType)
                || (MVOP_MPEG4 == pparam->enVideoType))
            {
                /* Disable H264 or RM Input */
                HAL_WriteRegBit(VOP_INPUT_SWITCH1, 0, BIT2 | BIT3);
                /* 8*32 tile format */
                HAL_WriteRegBit(VOP_REG_WR, 0, BIT1);
            }
            else if ((MVOP_H264 == pparam->enVideoType)
                     || (MVOP_RM == pparam->enVideoType))
            {
                /* 16*32 tile format */
                HAL_WriteRegBit(VOP_REG_WR, 1, BIT1);
                /* SVD mode enable */
                HAL_WriteByteMask(VOP_INPUT_SWITCH1, BIT3, BIT2 | BIT3);
                /* set mvop to 64bit interface */
                HAL_WriteByteMask(VOP_MIU_IF, VOP_MIU_128BIT,
                                  VOP_MIU_128BIT | VOP_MIU_128B_I64);
            }
            HAL_MVOP_LoadReg(E_MVOP_DEV_0);
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            /* y offset */
            u32offset = ((y * pparam->u16StripSize + (x << 5)) >> 3);
            HAL_WriteByte(SUB_REG(VOP_JPG_YSTR0_L), (MS_U8)(u32offset));
            HAL_WriteByte(SUB_REG(VOP_JPG_YSTR0_L + 1),
                          (MS_U8)(u32offset >> 8));
            HAL_WriteByte(SUB_REG(VOP_JPG_YSTR0_H), (MS_U8)(u32offset >> 16));
            HAL_WriteByte(SUB_REG(VOP_JPG_YSTR0_H + 1),
                          (MS_U8)((u32offset >> 24) & VOP_YUV_STR_HIBITS));

            /* uv offset */
            u32offset = ((y >> 1) * pparam->u16StripSize + (x << 5)) >> 3;
            HAL_WriteByte(SUB_REG(VOP_JPG_UVSTR0_L), (MS_U8)(u32offset));
            HAL_WriteByte(SUB_REG(VOP_JPG_UVSTR0_L + 1),
                          (MS_U8)(u32offset >> 8));
            HAL_WriteByte(SUB_REG(VOP_JPG_UVSTR0_H), (MS_U8)(u32offset >> 16));
            HAL_WriteByte(SUB_REG(VOP_JPG_UVSTR0_H + 1),
                          (MS_U8)((u32offset >> 24) & VOP_YUV_STR_HIBITS));

            pparam->u16CropWidth = (pparam->u16CropWidth >> 3) << 3;

            /* HSize, VSize */
            HAL_WriteByte(SUB_REG(VOP_JPG_HSIZE),
                          LOWBYTE(pparam->u16CropWidth));
            HAL_WriteByte(SUB_REG(VOP_JPG_HSIZE + 1),
                          HIGHBYTE(pparam->u16CropWidth));
            HAL_WriteByte(SUB_REG(VOP_JPG_VSIZE),
                          LOWBYTE(pparam->u16CropHeight));
            HAL_WriteByte(SUB_REG(VOP_JPG_VSIZE + 1),
                          HIGHBYTE(pparam->u16CropHeight));

            HAL_WriteByteMask(SUB_REG(VOP_MPG_JPG_SWITCH), BIT0, BIT1 | BIT0);

            /* clear extend strip len bit by default */
            HAL_WriteRegBit(SUB_REG(VOP_REG_STRIP_ALIGN), 0, BIT0);
            if ((MVOP_MPG == pparam->enVideoType)
                || (MVOP_MPEG4 == pparam->enVideoType))
            {
                /* Disable H264 or RM Input */
                HAL_WriteRegBit(SUB_REG(VOP_INPUT_SWITCH), 0, BIT2 | BIT3);
                /* 8*32 tile format */
                HAL_WriteRegBit(SUB_REG(VOP_REG_WR), 0, BIT1);
            }
            else if ((MVOP_H264 == pparam->enVideoType)
                     || (MVOP_RM == pparam->enVideoType))
            {
                /* 16*32 tile format */
                HAL_WriteRegBit(SUB_REG(VOP_REG_WR), 1, BIT1);
                /* SVD mode enable */
                HAL_WriteByteMask(SUB_REG(VOP_INPUT_SWITCH), BIT3, BIT2 | BIT3);
                /* set mvop to 128bit_i128 interface */
                HAL_WriteByteMask(SUB_REG(VOP_MIU_IF), VOP_MIU_128BIT,
                                  VOP_MIU_128BIT | VOP_MIU_128B_I64);
            }
            HAL_MVOP_LoadReg(E_MVOP_DEV_1);
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__,
                        eDevID);
            break;
        }
    }
#endif
}

void HAL_MVOP_SetRepeatField(MVOP_DevID eDevID, MVOP_RptFldMode eMode)
{
    if (g_pHalMVOPCtx == NULL)
    {
        MVOP_DBG(MVOP_PRINTF("%s g_pHalMVOPCtx is NULL pointer\n", __FUNCTION__);)
        return;
    }

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            g_pHalMVOPCtx->eRepeatField = eMode;
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            g_pHalMVOPCtx->eSubRepeatField = eMode;
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
}

void HAL_MVOP_SetInputMode(MVOP_DevID eDevID, VOPINPUTMODE mode,
                           MVOP_InputCfg* pparam)
{
    MS_U16 regval;
    MS_U16 u16strip;
    MS_U16 u16strip_lsb;

    if (NULL == g_pHalMVOPCtx)
    {
        MVOP_DBG(MVOP_PRINTF("%s g_pHalMVOPCtx is NULL pointer\n",
                             __FUNCTION__);)
        return;
    }

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            /* regval = 0; */
            /* for bk pattern */
            /* regval = HAL_ReadByte(VOP_MPG_JPG_SWITCH); */
            regval = g_pHalMVOPCtx->u16Reg20;
            regval |= (mode & 0x3);

            switch (mode)
            {
                case VOPINPUT_HARDWIRE:
                {
                    g_pHalMVOPCtx->bIsDMSMCU = TRUE;
                    mode = VOPINPUT_MCUCTRL;
                    regval |= (mode & 0x3);
                    HAL_WriteByte(VOP_MPG_JPG_SWITCH, regval);
                    g_pHalMVOPCtx->u16Reg20 = (g_pHalMVOPCtx->u16Reg20
                                               & (HighByteMask))
                                               | ((regval) & (LowByteMask));

                    MVOP_DBG("[%s][MVOP] driver switch to mcu mode.\n",
                             __FUNCTION__);

                    HAL_WriteByte(VOP_INFO_FROM_CODEC_L, 0x00);
                    HAL_WriteByte(VOP_INFO_FROM_CODEC_H, 0x00);
                    HAL_WriteRegBit(VOP_REG_MFDEC_2_L, 0, VOP_MF_FROM_WB);
                    HAL_WriteRegBit(VOP_INPUT_SWITCH0, 0, VOP_R2_WISHBONE);
                    HAL_WriteRegBit(VOP_REG_DUMMY, 0, VOP_32x32_WB);
                    break;
                }
                case VOPINPUT_HARDWIRECLIP:
                {
                    g_pHalMVOPCtx->bIsDMSMCU = FALSE;
                    HAL_WriteByte(VOP_MPG_JPG_SWITCH, regval);
                    g_pHalMVOPCtx->u16Reg20 = (g_pHalMVOPCtx->u16Reg20
                                               & (HighByteMask))
                                               | ((regval) & (LowByteMask));

                    /* HSize, VSize */
                    HAL_WriteByte(VOP_JPG_HSIZE, LOWBYTE(pparam->u16HSize));
                    HAL_WriteByte((VOP_JPG_HSIZE + 1),
                                  HIGHBYTE(pparam->u16HSize));
                    HAL_WriteByte(VOP_JPG_VSIZE, LOWBYTE(pparam->u16VSize));
                    HAL_WriteByte((VOP_JPG_VSIZE + 1),
                                  HIGHBYTE(pparam->u16VSize));
                    break;
                }
                case VOPINPUT_MCUCTRL:
                {
                    /*
                    * SN M7322 Photo source do not control by DMS
                    * disable from wb
                    */
                    HAL_WriteByte(VOP_INFO_FROM_CODEC_L, 0x00);
                    HAL_WriteByte(VOP_INFO_FROM_CODEC_H, 0x00);
                    HAL_WriteRegBit(VOP_REG_MFDEC_2_L, 0, VOP_MF_FROM_WB);
                    HAL_WriteRegBit(VOP_INPUT_SWITCH0, 0, VOP_R2_WISHBONE);
                    HAL_WriteRegBit(VOP_REG_DUMMY, 0, VOP_32x32_WB);

                    g_pHalMVOPCtx->bMirrorMode = (g_pHalMVOPCtx->bMirrorModeVer
                                                  || g_pHalMVOPCtx->bMirrorModeHor);

                    if (TRUE == pparam->bProgressive)
                    {
                        regval |= 0x4;
                    }
                    else
                    {
                        if (FALSE == g_pHalMVOPCtx->bIsDMSMCU)
                        {
                            regval &= ~0x4;
                            /* reg_dc_md=b'11 for interlace input */
                            regval |= 0x1;
                            if (E_MVOP_RPTFLD_NONE == g_pHalMVOPCtx->eRepeatField)
                            {
                                MVOP_DBG("%s normal NOT repeat field %x\n",
                                         __FUNCTION__,
                                         g_pHalMVOPCtx->eRepeatField);
                                /*
                                * To support mcu mode interlace
                                * need to set h'3B[9]=1, h'11[12]=0,
                                * and Y1/UV1 address equal to Y0/UV0 address.
                                */
                                HAL_WriteRegBit(VOP_MIRROR_CFG_HI, 1,
                                                VOP_REF_SELF_FLD);
                                HAL_MVOP_SetFieldInverse(E_MVOP_DEV_0, ENABLE,
                                                         DISABLE);
                            }
                        }
                        else
                        {
                            regval |= 0x4;
                        }
                    }

                    if (TRUE == pparam->bYUV422)
                    {
                        regval |= 0x10;
                    }
                    else
                    {
                        regval &= ~0x10;
                    }

                    if (TRUE == pparam->b422pack)
                    {
                        regval |= 0x80;
                    }

                    if (TRUE == pparam->bDramRdContd)
                    {
                        regval |= 0x20;
                        g_pHalMVOPCtx->bDramRdContd = TRUE;
                    }
                    else
                    {
                        regval &= ~0x20;
                        g_pHalMVOPCtx->bDramRdContd = FALSE;
                    }

                    /*
                    * for backward compatable to saturn
                    * [3] UV-7bit mode don't care
                    * [5] dram_rd_md =0
                    * [6] Fld don't care
                    * [7] 422pack don'care
                    */
                    HAL_WriteByte(VOP_MPG_JPG_SWITCH, regval);
                    HAL_MVOP_ForceWriteReg(E_MVOP_DEV_0);
                    g_pHalMVOPCtx->u16Reg20 = (g_pHalMVOPCtx->u16Reg20
                                               & (HighByteMask))
                                               | ((regval) & (LowByteMask));

                    g_pHalMVOPCtx->bIs422 = pparam->bYUV422;
                    if ((TRUE == g_pHalMVOPCtx->bIs422)
                        || (E_MVOP_RGB_NONE != g_pHalMVOPCtx->eRgbFmt))
                    {
                        HAL_WriteRegBit(VOP_REG_DUMMY, FALSE, VOP_420_BW_SAVE);
                        HAL_WriteRegBit(VOP_REG_BW_SAVE, FALSE,
                                        VOP_420_BW_SAVE_EX);
                    }

                    if (0 == pparam->u16StripSize)
                    {
                        if (TRUE == pparam->bSD)
                        {
                            u16strip = 720;
                            u16strip_lsb = 720;
                        }
                        else
                        {
                            u16strip = 1920;
                            u16strip_lsb = 1920;
                        }
                    }
                    else
                    {
                        u16strip = pparam->u16StripSize;
                        g_pHalMVOPCtx->u16MSBPitch = pparam->u16StripSize;
                        u16strip_lsb = pparam->u16StripSize;
                    }

                    /* set dc_strip[7:0] */
                    if (FALSE == pparam->bDramRdContd)
                    {
                        /* need align for monaco */
                        u16strip = (u16strip + 31) / 32 * 32;
                        u16strip = u16strip / 8;
                        u16strip_lsb = (u16strip_lsb + 127) / 128;
                        u16strip_lsb *= 4;
                    }
                    else
                    {
                        if ((TRUE == pparam->b422pack)
                            || (E_MVOP_RGB_NONE != g_pHalMVOPCtx->eRgbFmt))
                        {
                            if (E_MVOP_RGB_888 == g_pHalMVOPCtx->eRgbFmt)
                            {
                                /* 4bytes/pixel (yuv422:2bytes/pixel) */
                                u16strip *= 2;
                            }

                            /*
                            * VOP_REG_STRIP_ALIGN and Mirror mode are mutually
                            * exclusive, after M10(support mirror),
                            * VOP_DC_STRIP_H replace VOP_REG_STRIP_ALIGN,
                            * which supported maximun Hsize is 8188
                            */
#if 0
                            /* [071016 Andy] support YUV422 pack mode */
                            if ((u16strip < 1024)
                                || (TRUE == g_pHalMVOPCtx->bMirrorMode))
                            {
                                u16strip = u16strip / 4;
                                /* do not extend strip len */
                                HAL_WriteRegBit(VOP_REG_STRIP_ALIGN, 0, BIT0);
                            }
                            else
                            {
                                u16strip = u16strip / 8;
                                /* extend strip len to 2048 */
                                HAL_WriteRegBit(VOP_REG_STRIP_ALIGN, 1, BIT0);
                            }
#endif
                            u16strip = u16strip / 4;
                            HAL_WriteRegBit(VOP_REG_STRIP_ALIGN, 0, BIT0);
                        }
                        else
                        {
                            u16strip = u16strip / 8;
                        }
                    }

                    if (u16strip >= 256)
                    {
                        HAL_WriteByte(VOP_DC_STRIP_H, (u16strip >> 8));
                        /* reg_dc_strip_h[2:0] = reg_dc_strip[10:8] */
                    }
                    else
                    {
                        HAL_WriteByteMask(VOP_DC_STRIP_H, 0,
                                          BIT0 | BIT1 | BIT2);
                    }

                    regval = u16strip;
                    HAL_WriteByte(VOP_DC_STRIP, regval);
                    g_pHalMVOPCtx->u16Reg20 = (g_pHalMVOPCtx->u16Reg20
                                               & (LowByteMask))
                                               | ((regval << 8)
                                                  & (HighByteMask));

                    /* LSB strip */
                    HAL_WriteByte(VOP_DC_STRIP_LSB, LOWBYTE(u16strip_lsb));
                    HAL_WriteByteMask(VOP_REG_8BIT_TR_LSC,
                                      HIGHBYTE(u16strip_lsb),
                                      VOP_DC_STRIP_LSB_H);

                    HAL_MVOP_SetYUVBaseAdd(E_MVOP_DEV_0, pparam->u32YOffset,
                                           pparam->u32UVOffset,
                                           pparam->bProgressive,
                                           pparam->b422pack);

                    if (E_MVOP_RPTFLD_NONE != g_pHalMVOPCtx->eRepeatField)
                    {
                        MVOP_DBG("%s reset eRepeatField=%x ==>", __FUNCTION__,
                                 g_pHalMVOPCtx->eRepeatField);
                        /*
                        * To output the same field for single field input,
                        * do NOT set h'3B[9]=1 and h'11[12]=0
                        */

                        /* reset the flag to repeat field */
                        g_pHalMVOPCtx->eRepeatField = E_MVOP_RPTFLD_NONE;
                        MVOP_DBG(" %x\n", g_pHalMVOPCtx->eRepeatField);
                    }

                    /* HSize */
                    MS_U16 u16HSize = ALIGN_UPTO_16(pparam->u16HSize);
                    if (u16HSize != pparam->u16HSize)
                    {
                        MVOP_DBG(MVOP_PRINTF("\n\n Change HSize %d to %d\n",
                                             pparam->u16HSize, u16HSize);)
                    }
                    HAL_WriteByte(VOP_JPG_HSIZE, LOWBYTE(u16HSize));
                    HAL_WriteByte((VOP_JPG_HSIZE + 1), HIGHBYTE(u16HSize));

                    /* VSize */
                    MS_U16 u16VSize = pparam->u16VSize;
                    if (TRUE == g_pHalMVOPCtx->bMirrorModeVer)
                    {
                        u16VSize = ALIGN_UPTO_4(pparam->u16VSize);
                        MVOP_DBG(MVOP_PRINTF("\n\n Change VSize %d to %d\n",
                                             pparam->u16VSize, u16VSize);)
                    }
                    HAL_WriteByte(VOP_JPG_VSIZE, LOWBYTE(u16VSize));
                    HAL_WriteByte((VOP_JPG_VSIZE + 1), HIGHBYTE(u16VSize));

                    /* Film grain */
                    if (MVOP_AV1_FG == pparam->enVideoType)
                    {
                        g_pHalMVOPCtx->bAV1_FG = TRUE;
                        /*
                        * Outlook subject: MVOP av1 patch
                        * SW patch for hsk + small size,
                        * actual size is captured by ip2.
                        */
                        if (TRUE == MDrv_SYS_Query(E_SYS_QUERY_MVOP_MODE_SUPPORTED))
                        {
                            HAL_WriteRegBit(VOP_REG_DUMMY_5D_L, FALSE,
                                            VOP_MODE_SUPPORTED);
                        }
                    }
                    break;
                }
                default:
                {
                    MVOP_PRINTF("[%s] Not support input mode = %u\n",
                                __FUNCTION__, mode);
                    break;
                }
            }
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            /* regval = 0; */
            regval = g_pHalMVOPCtx->u16SubReg20;
            regval |= (mode & 0x3);

            switch (mode)
            {
                case VOPINPUT_HARDWIRE:
                {
                    g_pHalMVOPCtx->bSubIsDMSMCU = TRUE;
                    mode = VOPINPUT_MCUCTRL;
                    regval |= (mode & 0x3);
                    HAL_WriteByte(SUB_REG(VOP_MPG_JPG_SWITCH), regval);
                    g_pHalMVOPCtx->u16SubReg20 = regval;
                    MVOP_DBG("[%s][MVOP] driver switch to mcu mode.\n",
                             __FUNCTION__);
                    HAL_WriteByte(SUB_REG(VOP_INFO_FROM_CODEC_L), 0x00);
                    HAL_WriteByte(SUB_REG(VOP_INFO_FROM_CODEC_H), 0x00);
                    HAL_WriteRegBit(SUB_REG(VOP_REG_MFDEC_2_L), 0,
                                    VOP_MF_FROM_WB);
                    HAL_WriteRegBit(SUB_REG(VOP_INPUT_SWITCH0), 0,
                                    VOP_R2_WISHBONE);
                    HAL_WriteRegBit(SUB_REG(VOP_REG_DUMMY), 0, VOP_32x32_WB);
                    break;
                }
                case VOPINPUT_HARDWIRECLIP:
                {
                    g_pHalMVOPCtx->bSubIsDMSMCU = FALSE;
                    HAL_WriteByte(SUB_REG(VOP_MPG_JPG_SWITCH), regval);
                    g_pHalMVOPCtx->u16SubReg20 = regval;

                    /* HSize, VSize */
                    HAL_WriteByte(SUB_REG(VOP_JPG_HSIZE),
                                  LOWBYTE(pparam->u16HSize));
                    HAL_WriteByte(SUB_REG(VOP_JPG_HSIZE + 1),
                                  HIGHBYTE(pparam->u16HSize));
                    HAL_WriteByte(SUB_REG(VOP_JPG_VSIZE),
                                  LOWBYTE(pparam->u16VSize));
                    HAL_WriteByte(SUB_REG(VOP_JPG_VSIZE + 1),
                                  HIGHBYTE(pparam->u16VSize));
                    break;
                }
                case VOPINPUT_MCUCTRL:
                {
                    /* M7221 Photo source do not control by DMS */
                    HAL_WriteByte(SUB_REG(VOP_INFO_FROM_CODEC_L), 0x00);
                    HAL_WriteByte(SUB_REG(VOP_INFO_FROM_CODEC_H), 0x00);
                    /* disable from wb */
                    HAL_WriteRegBit(SUB_REG(VOP_REG_MFDEC_2_L), 0,
                                    VOP_MF_FROM_WB);
                    HAL_WriteRegBit(SUB_REG(VOP_INPUT_SWITCH0), 0,
                                    VOP_R2_WISHBONE);
                    HAL_WriteRegBit(SUB_REG(VOP_REG_DUMMY), 0, VOP_32x32_WB);

                    g_pHalMVOPCtx->bSubMirrorMode = (g_pHalMVOPCtx->bSubMirrorModeVer
                                                     || g_pHalMVOPCtx->bSubMirrorModeHor);

                    if (TRUE == pparam->bProgressive)
                    {
                        regval |= 0x4;
                    }
                    else
                    {
                        if (FALSE == g_pHalMVOPCtx->bSubIsDMSMCU)
                        {
                            regval &= ~0x4;
                            /* reg_dc_md=b'11 for interlace input */
                            regval |= 0x1;
                            if (E_MVOP_RPTFLD_NONE == g_pHalMVOPCtx->eSubRepeatField)
                            {
                                MVOP_DBG("%s normal NOT repeat field %x\n",
                                         __FUNCTION__,
                                         g_pHalMVOPCtx->eSubRepeatField);
                                /*
                                * To support mcu mode interlace,
                                * need to set h'3B[9]=1, h'11[12]=0,
                                * and Y1/UV1 address equal to Y0/UV0 address.
                                */
                                HAL_WriteRegBit(SUB_REG(VOP_MIRROR_CFG_HI), 1,
                                                VOP_REF_SELF_FLD);
                                HAL_MVOP_SetFieldInverse(E_MVOP_DEV_1, ENABLE,
                                                         DISABLE);
                            }
                        }
                        else
                        {
                            regval |= 0x4;
                        }
                    }

                    if (TRUE == pparam->bYUV422)
                    {
                        regval |= 0x10;
                    }
                    else
                    {
                        regval &= ~0x10;
                    }

                    if (TRUE == pparam->b422pack)
                    {
                        regval |= 0x80;
                    }

                    if (TRUE == pparam->bDramRdContd)
                    {
                        regval |= 0x20;
                        g_pHalMVOPCtx->bSubDramRdContd = TRUE;
                    }
                    else
                    {
                        regval &= ~0x20;
                        g_pHalMVOPCtx->bSubDramRdContd = FALSE;
                    }

                    /*
                    * for backward compatable to saturn
                    * [3] UV-7bit mode don't care
                    * [5] dram_rd_md =0
                    * [6] Fld don't care
                    * [7] 422pack don'care
                    */
                    HAL_WriteByte(SUB_REG(VOP_MPG_JPG_SWITCH), regval);
                    g_pHalMVOPCtx->u16SubReg20 = regval;
                    g_pHalMVOPCtx->bSubIs422 = pparam->bYUV422;
                    if ((TRUE == g_pHalMVOPCtx->bSubIs422)
                        || (E_MVOP_RGB_NONE != g_pHalMVOPCtx->eSubRgbFmt))
                    {
                        HAL_WriteRegBit(SUB_REG(VOP_REG_DUMMY), FALSE,
                                        VOP_420_BW_SAVE);
                        HAL_WriteRegBit(SUB_REG(VOP_REG_BW_SAVE), FALSE,
                                        VOP_420_BW_SAVE_EX);
                    }

                    if (0 == pparam->u16StripSize)
                    {
                        if (TRUE == pparam->bSD)
                        {
                            u16strip = 720;
                            u16strip_lsb = 720;
                        }
                        else
                        {
                            u16strip = 1920;
                            u16strip_lsb = 1920;
                        }
                    }
                    else
                    {
                        u16strip = pparam->u16StripSize;
                        g_pHalMVOPCtx->u16SubMSBPitch = pparam->u16StripSize;
                        u16strip_lsb = pparam->u16StripSize;
                    }

                    /* set dc_strip[7:0] */
                    if (FALSE == pparam->bDramRdContd)
                    {
                        /* need align for monaco */
                        u16strip = (u16strip + 31) / 32 * 32;
                        u16strip = u16strip / 8;
                        u16strip_lsb = (u16strip_lsb + 127) / 128;
                        u16strip_lsb *= 4;
                    }
                    else
                    {
                        if (TRUE == pparam->b422pack)
                        {
                            if (E_MVOP_RGB_888 == g_pHalMVOPCtx->eSubRgbFmt)
                            {
                                u16strip *= 2;
                            }

                            if ((u16strip < 1024)
                                || (TRUE == g_pHalMVOPCtx->bSubMirrorMode))
                            {
                                u16strip = u16strip / 4;
                                /* do not extend strip len */
                                HAL_WriteRegBit(SUB_REG(VOP_REG_STRIP_ALIGN),
                                                0, BIT0);
                            }
                            else
                            {
                                u16strip = u16strip / 8;
                                /* extend strip len to 2048 */
                                HAL_WriteRegBit(SUB_REG(VOP_REG_STRIP_ALIGN),
                                                1, BIT0);
                            }
                        }
                        else
                        {
                            u16strip = u16strip / 8;
                        }
                    }

                    if (u16strip >= 256)
                    {
                        HAL_WriteByte(SUB_REG(VOP_DC_STRIP_H), (u16strip >> 8));
                        /* reg_dc_strip_h[2:0] = reg_dc_strip[10:8] */
                    }
                    else
                    {
                        HAL_WriteByteMask(SUB_REG(VOP_DC_STRIP_H), 0,
                                          BIT0 | BIT1 | BIT2);
                    }

                    regval = u16strip;
                    HAL_WriteByte(SUB_REG(VOP_DC_STRIP), regval);

                    /* LSB strip */
                    HAL_WriteByte(SUB_REG(VOP_DC_STRIP_LSB),
                                  LOWBYTE(u16strip_lsb));
                    HAL_WriteByteMask(SUB_REG(VOP_REG_8BIT_TR_LSC),
                                      HIGHBYTE(u16strip_lsb),
                                      VOP_DC_STRIP_LSB_H);

                    HAL_MVOP_SetYUVBaseAdd(E_MVOP_DEV_1, pparam->u32YOffset,
                                           pparam->u32UVOffset,
                                           pparam->bProgressive,
                                           pparam->b422pack);

                    if (E_MVOP_RPTFLD_NONE != g_pHalMVOPCtx->eSubRepeatField)
                    {
                        MVOP_DBG("%s reset eRepeatField=%x ==>",
                                 __FUNCTION__, g_pHalMVOPCtx->eSubRepeatField);
                        /*
                        * To output the same field for single field input,
                        * do NOT set h'3B[9]=1 and h'11[12]=0
                        */

                        /* reset the flag to repeat field */
                        g_pHalMVOPCtx->eSubRepeatField = E_MVOP_RPTFLD_NONE;
                        MVOP_DBG(" %x\n", g_pHalMVOPCtx->eSubRepeatField);
                    }

                    /* HSize */
                    MS_U16 u16HSize = ALIGN_UPTO_16(pparam->u16HSize);
                    if (u16HSize != pparam->u16HSize)
                    {
                        MVOP_DBG(MVOP_PRINTF("\n\n Change HSize %d to %d\n",
                                             pparam->u16HSize, u16HSize);)
                    }
                    HAL_WriteByte(SUB_REG(VOP_JPG_HSIZE), LOWBYTE(u16HSize));
                    HAL_WriteByte(SUB_REG(VOP_JPG_HSIZE + 1),
                                  HIGHBYTE(u16HSize));

                    /* VSize */
                    MS_U16 u16VSize = pparam->u16VSize;
                    if (TRUE == g_pHalMVOPCtx->bSubMirrorModeVer)
                    {
                        u16VSize = ALIGN_UPTO_4(pparam->u16VSize);
                        MVOP_DBG(MVOP_PRINTF("\n\n Change VSize %d to %d\n",
                                             pparam->u16VSize, u16VSize);)
                    }
                    HAL_WriteByte(SUB_REG(VOP_JPG_VSIZE), LOWBYTE(u16VSize));
                    HAL_WriteByte(SUB_REG(VOP_JPG_VSIZE + 1),
                                  HIGHBYTE(u16VSize));
                    break;
                }
                default:
                {
                    MVOP_PRINTF("[%s] Not support input mode = %u\n",
                                __FUNCTION__, mode);
                    break;
                }
            }
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID = %u\n", __FUNCTION__,
                        eDevID);
            break;
        }
    }
    HAL_MVOP_LoadReg(eDevID);
    HAL_MVOP_ForceWriteReg(eDevID);
}

void HAL_MVOP_EnableUVShift(MVOP_DevID eDevID, MS_BOOL bEnable)
{
    MS_U8 regval;

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            regval = HAL_ReadByte(VOP_MPG_JPG_SWITCH);
            if (((regval & BIT4) == BIT4) && ((regval & 0x3) == 0x2))
            {
                // 422 with MCU control mode
                if (bEnable)
                {
                    MS_ASSERT(0);
                }
            }
            // output 420 and interlace
            //[IP - Sheet] : Main Page --- 420CUP
            //[Project] :  Titania2
            //[Description]:   Chroma artifacts when 420to422 is applied duplicate method.
            //[Root cause]: Apply 420to422 average algorithm to all DTV input cases.
            //The average algorithm must cooperate with MVOP.
            HAL_WriteByteMask(VOP_UV_SHIFT, (bEnable) ? 1 : 0, 0x3);
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            regval = HAL_ReadByte(SUB_REG(VOP_MPG_JPG_SWITCH));
            if (((regval & BIT4) == BIT4) && ((regval & 0x3) == 0x2))
            {   // 422 with MCU control mode
                if (bEnable)
                {
                    MS_ASSERT(0);
                }
            }
            // output 420 and interlace
            //[IP - Sheet] : Main Page --- 420CUP
            //[Project] :  Titania2
            //[Description]:   Chroma artifacts when 420to422 is applied duplicate method.
            //[Root cause]: Apply 420to422 average algorithm to all DTV input cases.
            //The average algorithm must cooperate with MVOP.
            HAL_WriteByteMask(SUB_REG(VOP_UV_SHIFT), (bEnable) ? 1 : 0, 0x3);
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
}

void HAL_MVOP_Set2PMode(MVOP_DevID eDevID, MS_BOOL bEnable)
{
    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            g_pHalMVOPCtx->bIs2p = bEnable;
            HAL_WriteRegBit(VOP_REG_4K2K_2P, bEnable, VOP_4K2K_2P);
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            g_pHalMVOPCtx->bSubIs2p = bEnable;
            HAL_WriteRegBit(SUB_REG(VOP_REG_4K2K_2P), bEnable, VOP_4K2K_2P);
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
}

void HAL_MVOP_SetVSyncMode(MVOP_DevID eDevID, MS_U8 u8Mode)
{
    if (g_pHalMVOPCtx == NULL)
    {
        MVOP_DBG(MVOP_PRINTF("%s g_pHalMVOPCtx is NULL pointer\n", __FUNCTION__);)
        return;
    }

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            g_pHalMVOPCtx->bNewVSyncMode = (1 == u8Mode) ? TRUE : FALSE;
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            g_pHalMVOPCtx->bSubNewVSyncMode = (1 == u8Mode) ? TRUE : FALSE;
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
}

void HAL_MVOP_SetOutputTiming(MVOP_DevID eDevID, MVOP_Timing* ptiming)
{
    //MS_U8 regval;

    if (g_pHalMVOPCtx == NULL)
    {
        MVOP_DBG(MVOP_PRINTF("%s g_pHalMVOPCtx is NULL pointer\n", __FUNCTION__);)
        return;
    }

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            HAL_WriteByte(VOP_FRAME_VCOUNT, LOWBYTE(ptiming->u16V_TotalCount));
            HAL_WriteByte((VOP_FRAME_VCOUNT + 1), HIGHBYTE(ptiming->u16V_TotalCount));
            HAL_WriteByte(VOP_FRAME_HCOUNT, LOWBYTE(ptiming->u16H_TotalCount));
            HAL_WriteByte((VOP_FRAME_HCOUNT + 1), HIGHBYTE(ptiming->u16H_TotalCount));

#if SUPPORT_INT_VSIZE_EX
            HAL_WriteByte((VOP_VB0_STR), LOWBYTE(ptiming->u16VBlank0_Start + 1));
            HAL_WriteByte((VOP_VB0_STR  + 1), HIGHBYTE(ptiming->u16VBlank0_Start + 1));
            HAL_WriteByte((VOP_VB1_STR), LOWBYTE(ptiming->u16VBlank1_Start + 1));
            HAL_WriteByte((VOP_VB1_STR  + 1), HIGHBYTE(ptiming->u16VBlank1_Start + 1));
#else
            HAL_WriteByte((VOP_VB0_STR), LOWBYTE(ptiming->u16VBlank0_Start));
            HAL_WriteByte((VOP_VB0_STR  + 1), HIGHBYTE(ptiming->u16VBlank0_Start));
            HAL_WriteByte((VOP_VB1_STR), LOWBYTE(ptiming->u16VBlank1_Start));
            HAL_WriteByte((VOP_VB1_STR  + 1), HIGHBYTE(ptiming->u16VBlank1_Start));
#endif

            HAL_WriteByte((VOP_VB0_END), LOWBYTE(ptiming->u16VBlank0_End));
            HAL_WriteByte((VOP_VB0_END  + 1), HIGHBYTE(ptiming->u16VBlank0_End));
            HAL_WriteByte((VOP_VB1_END), LOWBYTE(ptiming->u16VBlank1_End));
            HAL_WriteByte((VOP_VB1_END  + 1), HIGHBYTE(ptiming->u16VBlank1_End));
            HAL_WriteByte((VOP_TF_STR), LOWBYTE(ptiming->u16TopField_Start));
            HAL_WriteByte((VOP_TF_STR   + 1), HIGHBYTE(ptiming->u16TopField_Start));
            HAL_WriteByte((VOP_BF_STR), LOWBYTE(ptiming->u16BottomField_Start));
            HAL_WriteByte((VOP_BF_STR   + 1), HIGHBYTE(ptiming->u16BottomField_Start));
            HAL_WriteByte((VOP_HACT_STR), LOWBYTE(ptiming->u16HActive_Start));
            HAL_WriteByte((VOP_HACT_STR + 1), HIGHBYTE(ptiming->u16HActive_Start));

            HAL_WriteByte((VOP_TF_VS), LOWBYTE(ptiming->u16TopField_VS));
            HAL_WriteByte((VOP_TF_VS   + 1), HIGHBYTE(ptiming->u16TopField_VS));
            // sw patch for xc framelock issue
            if ((ptiming->bInterlace == 1) && (g_pHalMVOPCtx->bIsHS))
            {
                HAL_WriteByte((VOP_BF_VS), LOWBYTE(ptiming->u16BottomField_VS + 1));
                HAL_WriteByte((VOP_BF_VS   + 1), HIGHBYTE(ptiming->u16BottomField_VS + 1));
            }
            else
            {
                HAL_WriteByte((VOP_BF_VS), LOWBYTE(ptiming->u16BottomField_VS));
                HAL_WriteByte((VOP_BF_VS   + 1), HIGHBYTE(ptiming->u16BottomField_VS));
            }

#if GOP_BACKPORCH_PATCH
            if (ptiming->bInterlace == 1)
            {
                // vsync forwarding, MI get video delay before sethandshakemode
                g_pHalMVOPCtx->u16CurVCnt = ptiming->u16V_TotalCount - VSYNC_LINE_DOLBY;
            }
            else
            {
                // vsync forwarding, MI get video delay before sethandshakemode
                g_pHalMVOPCtx->u16CurVCnt = ptiming->u16VBlank0_End + VSYNC_DELAY_BY_VB_END;
            }
#else
            // default dms use dc_start vsync.
            g_pHalMVOPCtx->u16CurVCnt = HAL_Read2Byte(VOP_EXT_DB_START_OFF);
#endif

            // mcu mode + hsk mode, no needs to force vsync forwarding
            if (g_pHalMVOPCtx->bIsSinDV)
            {
                g_pHalMVOPCtx->bNewVSyncMode = TRUE;
                g_pHalMVOPCtx->u16VsyncLines = VSYNC_LINE_DOLBY;
            }
#if GOP_BACKPORCH_PATCH
            if ((ptiming->bInterlace == 1) && (g_pHalMVOPCtx->bIsHS))
            {
                g_pHalMVOPCtx->bNewVSyncMode = TRUE;
                g_pHalMVOPCtx->u16VsyncLines = VSYNC_LINE_IMODE;
            }
#endif
            if (g_pHalMVOPCtx->bNewVSyncMode)
            {
#define NEW_VSYNC_MODE_ADVANCE_LINECNT 30
                MS_U16 u16BottomField_VS2MVD;
                MS_U16 u16TopField_VS2MVD;
                MVOP_DBG(MVOP_PRINTF("MVOP use new vync mode, forwarding %d lines\n", NEW_VSYNC_MODE_ADVANCE_LINECNT);)

                if (g_pHalMVOPCtx->u16VsyncLines == 0)
                    u16BottomField_VS2MVD = ptiming->u16BottomField_VS - NEW_VSYNC_MODE_ADVANCE_LINECNT;
                else
                    u16BottomField_VS2MVD = ptiming->u16BottomField_VS - g_pHalMVOPCtx->u16VsyncLines;

                MVOP_DBG(MVOP_PRINTF("BottomField VS ori=0x%x, new=0x%x\n", ptiming->u16BottomField_VS, u16BottomField_VS2MVD);)
                HAL_WriteByte((VOP_BF_VS_MVD), LOWBYTE(u16BottomField_VS2MVD));
                HAL_WriteByte((VOP_BF_VS_MVD + 1), HIGHBYTE(u16BottomField_VS2MVD));

                if (g_pHalMVOPCtx->u16VsyncLines == 0)
                    u16TopField_VS2MVD = ptiming->u16V_TotalCount - NEW_VSYNC_MODE_ADVANCE_LINECNT;
                else
                    u16TopField_VS2MVD = ptiming->u16V_TotalCount - g_pHalMVOPCtx->u16VsyncLines;

                MVOP_DBG(MVOP_PRINTF("TopField VS Vtt=0x%x, new=0x%x\n", ptiming->u16V_TotalCount, u16TopField_VS2MVD);)
                HAL_WriteByte((VOP_TF_VS_MVD), LOWBYTE(u16TopField_VS2MVD));
                HAL_WriteByte((VOP_TF_VS_MVD + 1), HIGHBYTE(u16TopField_VS2MVD));

#if SUPPORT_FILED_DB // t/b signal 30 lines forwarding
                HAL_WriteRegBit(VOP_MIRROR_CFG_HI, 0, VOP_DC2MVD_FLD_SEL);
                HAL_WriteRegBit(VOP_REG_BW_THD_H, 1, REG_MVD_FLD_SEL);

                HAL_WriteByte((VOP_TF_STR_MVD), LOWBYTE(u16TopField_VS2MVD));
                HAL_WriteByte((VOP_TF_STR_MVD + 1), HIGHBYTE(u16TopField_VS2MVD));
                HAL_WriteByte((VOP_BF_STR_MVD), LOWBYTE(u16BottomField_VS2MVD));
                HAL_WriteByte((VOP_BF_STR_MVD + 1), HIGHBYTE(u16BottomField_VS2MVD));
#endif

                HAL_WriteRegBit(VOP_GCLK, 0, VOP_GCLK_MIU_ON);
                // Use new vsync
                HAL_WriteRegBit(VOP_CTRL1, 1, VOP_MVD_VS_MD);
                // restore to original mode
                g_pHalMVOPCtx->bNewVSyncMode = FALSE;
            }
            else
            {
                MS_U16 u16BottomField_VS2MVD = 0x200;
                HAL_WriteByte((VOP_BF_VS_MVD), LOWBYTE(u16BottomField_VS2MVD));
                HAL_WriteByte((VOP_BF_VS_MVD + 1), HIGHBYTE(u16BottomField_VS2MVD));

                MS_U16 u16TopField_VS2MVD = 0x200;
                HAL_WriteByte((VOP_TF_VS_MVD), LOWBYTE(u16TopField_VS2MVD));
                HAL_WriteByte((VOP_TF_VS_MVD + 1), HIGHBYTE(u16TopField_VS2MVD));
                HAL_WriteRegBit(VOP_CTRL1, 0, VOP_MVD_VS_MD);
            }

            // + S3, set default IMG_HSTR, IMG_VSTR0, IMG_VSTR1
#ifdef _SUPPORT_IMG_OFFSET_
            HAL_WriteByte((VOP_IMG_HSTR), LOWBYTE(ptiming->u16HImg_Start));
            HAL_WriteByte((VOP_IMG_HSTR + 1), HIGHBYTE(ptiming->u16HImg_Start));
            HAL_WriteByte((VOP_IMG_VSTR0), LOWBYTE(ptiming->u16VImg_Start0));
            HAL_WriteByte((VOP_IMG_VSTR0 + 1), HIGHBYTE(ptiming->u16VImg_Start0));
            HAL_WriteByte((VOP_IMG_VSTR1), LOWBYTE(ptiming->u16VImg_Start1));
            HAL_WriteByte((VOP_IMG_VSTR1 + 1), HIGHBYTE(ptiming->u16VImg_Start1));
#else
            HAL_WriteByte((VOP_IMG_HSTR), LOWBYTE(ptiming->u16HActive_Start));
            HAL_WriteByte((VOP_IMG_HSTR + 1), HIGHBYTE(ptiming->u16HActive_Start));
            HAL_WriteByte((VOP_IMG_VSTR0), LOWBYTE(ptiming->u16VBlank0_End));
            HAL_WriteByte((VOP_IMG_VSTR0 + 1), HIGHBYTE(ptiming->u16VBlank0_End));
            HAL_WriteByte((VOP_IMG_VSTR1), LOWBYTE(ptiming->u16VBlank1_End));
            HAL_WriteByte((VOP_IMG_VSTR1 + 1), HIGHBYTE(ptiming->u16VBlank1_End));
#endif
            // set MVOP test pattern to black
            HAL_MVOP_SetBlackBG(E_MVOP_DEV_0);
            // set mvop src to test pattern
            HAL_MVOP_SetPattern(E_MVOP_DEV_0, MVOP_PATTERN_FRAMECOLOR);
            // make changed registers take effect
            HAL_MVOP_LoadReg(E_MVOP_DEV_0);
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_0);

            HAL_MVOP_SetMIUReqMask(E_MVOP_DEV_0, TRUE);
            // reset mvop to avoid timing change cause mvop hang-up
            HAL_MVOP_Rst(E_MVOP_DEV_0);
            HAL_MVOP_SetMIUReqMask(E_MVOP_DEV_0, FALSE);

            if (FALSE == g_pHalMVOPCtx->bIsDMSMCU)
            {
                // non-dms remove pattern
                HAL_MVOP_SetPattern(E_MVOP_DEV_0, MVOP_PATTERN_NORMAL);
            }
            if (ptiming->bHDuplicate)
            {
                HAL_Write2Byte(VOP_JPG_HSIZE, (ptiming->u16Width >> 1));
                HAL_Write2Byte(VOP_JPG_VSIZE, ptiming->u16Height);
            }
            else if (g_pHalMVOPCtx->b3DLRMode)
            {
                if (g_pHalMVOPCtx->b3DLRAltSBSOutput)
                {
                    HAL_Write2Byte(VOP_JPG_HSIZE, (ptiming->u16Width) >> 1);
                    HAL_Write2Byte(VOP_JPG_VSIZE, ptiming->u16Height);
                }
                else
                {
                    HAL_Write2Byte(VOP_JPG_HSIZE, ptiming->u16Width);
                    HAL_Write2Byte(VOP_JPG_VSIZE, (ptiming->u16Height) >> 1);
                }
            }
            else
            {
                HAL_Write2Byte(VOP_JPG_HSIZE, ptiming->u16Width);
                HAL_Write2Byte(VOP_JPG_VSIZE, ptiming->u16Height);
            }

            HAL_MVOP_LoadReg(E_MVOP_DEV_0);
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_0);
            // H pixel duplicate
            HAL_WriteRegBit(VOP_CTRL0, ptiming->bHDuplicate, BIT2);
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            HAL_WriteByte(SUB_REG(VOP_FRAME_VCOUNT), LOWBYTE(ptiming->u16V_TotalCount));
            HAL_WriteByte(SUB_REG(VOP_FRAME_VCOUNT + 1), HIGHBYTE(ptiming->u16V_TotalCount));
            HAL_WriteByte(SUB_REG(VOP_FRAME_HCOUNT), LOWBYTE(ptiming->u16H_TotalCount));
            HAL_WriteByte(SUB_REG(VOP_FRAME_HCOUNT + 1), HIGHBYTE(ptiming->u16H_TotalCount));

            HAL_WriteByte(SUB_REG(VOP_VB0_STR), LOWBYTE(ptiming->u16VBlank0_Start));
            HAL_WriteByte(SUB_REG(VOP_VB0_STR  + 1), HIGHBYTE(ptiming->u16VBlank0_Start));
            HAL_WriteByte(SUB_REG(VOP_VB0_END), LOWBYTE(ptiming->u16VBlank0_End));
            HAL_WriteByte(SUB_REG(VOP_VB0_END  + 1), HIGHBYTE(ptiming->u16VBlank0_End));
            HAL_WriteByte(SUB_REG(VOP_VB1_STR), LOWBYTE(ptiming->u16VBlank1_Start));
            HAL_WriteByte(SUB_REG(VOP_VB1_STR  + 1), HIGHBYTE(ptiming->u16VBlank1_Start));
            HAL_WriteByte(SUB_REG(VOP_VB1_END), LOWBYTE(ptiming->u16VBlank1_End));
            HAL_WriteByte(SUB_REG(VOP_VB1_END  + 1), HIGHBYTE(ptiming->u16VBlank1_End));
            HAL_WriteByte(SUB_REG(VOP_TF_STR), LOWBYTE(ptiming->u16TopField_Start));
            HAL_WriteByte(SUB_REG(VOP_TF_STR   + 1), HIGHBYTE(ptiming->u16TopField_Start));
            HAL_WriteByte(SUB_REG(VOP_BF_STR), LOWBYTE(ptiming->u16BottomField_Start));
            HAL_WriteByte(SUB_REG(VOP_BF_STR   + 1), HIGHBYTE(ptiming->u16BottomField_Start));
            HAL_WriteByte(SUB_REG(VOP_HACT_STR), LOWBYTE(ptiming->u16HActive_Start));
            HAL_WriteByte(SUB_REG(VOP_HACT_STR + 1), HIGHBYTE(ptiming->u16HActive_Start));

            HAL_WriteByte(SUB_REG(VOP_TF_VS), LOWBYTE(ptiming->u16TopField_VS));
            HAL_WriteByte(SUB_REG(VOP_TF_VS   + 1), HIGHBYTE(ptiming->u16TopField_VS));
            // sw patch for xc framelock issue
            if ((ptiming->bInterlace == 1) && (g_pHalMVOPCtx->bIsHS))
            {
                HAL_WriteByte(SUB_REG(VOP_BF_VS), LOWBYTE(ptiming->u16BottomField_VS + 1));
                HAL_WriteByte(SUB_REG(VOP_BF_VS   + 1), HIGHBYTE(ptiming->u16BottomField_VS + 1));
            }
            else
            {
                HAL_WriteByte(SUB_REG(VOP_BF_VS), LOWBYTE(ptiming->u16BottomField_VS));
                HAL_WriteByte(SUB_REG(VOP_BF_VS   + 1), HIGHBYTE(ptiming->u16BottomField_VS));
            }

#if GOP_BACKPORCH_PATCH
            if (ptiming->bInterlace == 1)
            {
                // vsync forwarding, MI get video delay before sethandshakemode
                g_pHalMVOPCtx->u16SubCurVCnt = ptiming->u16V_TotalCount - VSYNC_LINE_DOLBY;
            }
            else
            {
                // vsync forwarding, MI get video delay before sethandshakemode
                g_pHalMVOPCtx->u16SubCurVCnt = ptiming->u16VBlank0_End + VSYNC_DELAY_BY_VB_END;
            }
#else
            // default dms use dc_start vsync.
            g_pHalMVOPCtx->u16SubCurVCnt = HAL_Read2Byte(SUB_REG(VOP_EXT_DB_START_OFF));
#endif

            // mcu mode + hsk mode, no needs to force vsync forwarding
            if (g_pHalMVOPCtx->bSubIsSinDV)
            {
                g_pHalMVOPCtx->bSubNewVSyncMode = TRUE;
                g_pHalMVOPCtx->u16SubVsyncLines = VSYNC_LINE_DOLBY;
            }
#if GOP_BACKPORCH_PATCH
            if ((ptiming->bInterlace == 1) && (g_pHalMVOPCtx->bSubIsHS))
            {
                g_pHalMVOPCtx->bSubNewVSyncMode = TRUE;
                g_pHalMVOPCtx->u16SubVsyncLines = VSYNC_LINE_IMODE;
            }
#endif
            if (g_pHalMVOPCtx->bSubNewVSyncMode)
            {
#define SUB_NEW_VSYNC_MODE_ADVANCE_LINECNT 30
                MS_U16 u16BottomField_VS2MVD;
                MS_U16 u16TopField_VS2MVD;
                MVOP_DBG(MVOP_PRINTF("MVOP use new vync mode, forwarding %d lines\n", SUB_NEW_VSYNC_MODE_ADVANCE_LINECNT);)

                if (g_pHalMVOPCtx->u16SubVsyncLines == 0)
                    u16BottomField_VS2MVD = ptiming->u16BottomField_VS - SUB_NEW_VSYNC_MODE_ADVANCE_LINECNT;
                else
                    u16BottomField_VS2MVD = ptiming->u16BottomField_VS - g_pHalMVOPCtx->u16SubVsyncLines;
                MVOP_DBG(MVOP_PRINTF("BottomField VS ori=0x%x, new=0x%x\n", ptiming->u16BottomField_VS, u16BottomField_VS2MVD);)
                HAL_WriteByte(SUB_REG(VOP_BF_VS_MVD), LOWBYTE(u16BottomField_VS2MVD));
                HAL_WriteByte(SUB_REG((VOP_BF_VS_MVD + 1)), HIGHBYTE(u16BottomField_VS2MVD));

                if (g_pHalMVOPCtx->u16SubVsyncLines == 0)
                    u16TopField_VS2MVD = ptiming->u16V_TotalCount - SUB_NEW_VSYNC_MODE_ADVANCE_LINECNT;
                else
                    u16TopField_VS2MVD = ptiming->u16V_TotalCount - g_pHalMVOPCtx->u16SubVsyncLines;
                MVOP_DBG(MVOP_PRINTF("TopField VS Vtt=0x%x, new=0x%x\n", ptiming->u16V_TotalCount, u16TopField_VS2MVD);)
                HAL_WriteByte(SUB_REG(VOP_TF_VS_MVD), LOWBYTE(u16TopField_VS2MVD));
                HAL_WriteByte(SUB_REG((VOP_TF_VS_MVD + 1)), HIGHBYTE(u16TopField_VS2MVD));

#if SUPPORT_FILED_DB // t/b signal 30 lines forwarding
                HAL_WriteRegBit(SUB_REG(VOP_MIRROR_CFG_HI), 0, VOP_DC2MVD_FLD_SEL);
                HAL_WriteRegBit(SUB_REG(VOP_REG_BW_THD_H), 1, REG_MVD_FLD_SEL);

                HAL_WriteByte(SUB_REG(VOP_TF_STR_MVD), LOWBYTE(u16TopField_VS2MVD));
                HAL_WriteByte(SUB_REG(VOP_TF_STR_MVD + 1), HIGHBYTE(u16TopField_VS2MVD));
                HAL_WriteByte(SUB_REG(VOP_BF_STR_MVD), LOWBYTE(u16BottomField_VS2MVD));
                HAL_WriteByte(SUB_REG(VOP_BF_STR_MVD + 1), HIGHBYTE(u16BottomField_VS2MVD));
#endif

                HAL_WriteRegBit(SUB_REG(VOP_GCLK), 0, VOP_GCLK_MIU_ON);
                // Use new vsync
                HAL_WriteRegBit(SUB_REG(VOP_CTRL1), 1, VOP_MVD_VS_MD);
                // restore to original mode
                g_pHalMVOPCtx->bSubNewVSyncMode = FALSE;
            }


            // + S3, set default IMG_HSTR, IMG_VSTR0, IMG_VSTR1
#ifdef _SUPPORT_IMG_OFFSET_
            HAL_WriteByte(SUB_REG(VOP_IMG_HSTR), LOWBYTE(ptiming->u16HImg_Start));
            HAL_WriteByte(SUB_REG(VOP_IMG_HSTR + 1), HIGHBYTE(ptiming->u16HImg_Start));
            HAL_WriteByte(SUB_REG(VOP_IMG_VSTR0), LOWBYTE(ptiming->u16VImg_Start0));
            HAL_WriteByte(SUB_REG(VOP_IMG_VSTR0 + 1), HIGHBYTE(ptiming->u16VImg_Start0));
            HAL_WriteByte(SUB_REG(VOP_IMG_VSTR1), LOWBYTE(ptiming->u16VImg_Start1));
            HAL_WriteByte(SUB_REG(VOP_IMG_VSTR1 + 1), HIGHBYTE(ptiming->u16VImg_Start1));
#else
            HAL_WriteByte(SUB_REG(VOP_IMG_HSTR), LOWBYTE(ptiming->u16HActive_Start));
            HAL_WriteByte(SUB_REG(VOP_IMG_HSTR + 1), HIGHBYTE(ptiming->u16HActive_Start));
            HAL_WriteByte(SUB_REG(VOP_IMG_VSTR0), LOWBYTE(ptiming->u16VBlank0_End));
            HAL_WriteByte(SUB_REG(VOP_IMG_VSTR0 + 1), HIGHBYTE(ptiming->u16VBlank0_End));
            HAL_WriteByte(SUB_REG(VOP_IMG_VSTR1), LOWBYTE(ptiming->u16VBlank1_End));
            HAL_WriteByte(SUB_REG(VOP_IMG_VSTR1 + 1), HIGHBYTE(ptiming->u16VBlank1_End));
#endif
            // set MVOP test pattern to black
            HAL_MVOP_SetBlackBG(E_MVOP_DEV_1);
            // set mvop src to test pattern
            HAL_MVOP_SetPattern(E_MVOP_DEV_1, MVOP_PATTERN_FRAMECOLOR);
            // make changed registers take effect
            HAL_MVOP_LoadReg(E_MVOP_DEV_1);
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_1);

            HAL_MVOP_SetMIUReqMask(E_MVOP_DEV_1, TRUE);
            // reset mvop to avoid timing change cause mvop hang-up
            HAL_MVOP_Rst(E_MVOP_DEV_1);
            HAL_MVOP_SetMIUReqMask(E_MVOP_DEV_1, FALSE);

            if (FALSE == g_pHalMVOPCtx->bSubIsDMSMCU)
            {
                // non-dms remove pattern
                HAL_MVOP_SetPattern(E_MVOP_DEV_1, MVOP_PATTERN_NORMAL);
            }
            if (ptiming->bHDuplicate)
            {
                HAL_Write2Byte(SUB_REG(VOP_JPG_HSIZE), (ptiming->u16Width >> 1));
            }
            else
            {
                HAL_Write2Byte(SUB_REG(VOP_JPG_HSIZE), ptiming->u16Width);
            }

            HAL_Write2Byte(SUB_REG(VOP_JPG_VSIZE), ptiming->u16Height);
            HAL_MVOP_LoadReg(E_MVOP_DEV_1);
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_1);
            // H pixel duplicate
            HAL_WriteRegBit(SUB_REG(VOP_CTRL0), ptiming->bHDuplicate, BIT2);
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
#if 0
    MVOP_DBG(MVOP_PRINTF("\nMVOP SetOutputTiming\n");)
    MVOP_DBG(MVOP_PRINTF(" VTot=%u,\t", ptiming->u16V_TotalCount);)
    MVOP_DBG(MVOP_PRINTF(" HTot=%u,\t", ptiming->u16H_TotalCount);)
    MVOP_DBG(MVOP_PRINTF(" I/P=%u\n", ptiming->bInterlace);)
    MVOP_DBG(MVOP_PRINTF(" W=%u,\t", ptiming->u16Width);)
    MVOP_DBG(MVOP_PRINTF(" H=%u,\t", ptiming->u16Height);)
    MVOP_DBG(MVOP_PRINTF(" FRate=%u,\t", ptiming->u8Framerate);)
    MVOP_DBG(MVOP_PRINTF(" HFreq=%u\n", ptiming->u16H_Freq);)
    MVOP_DBG(MVOP_PRINTF(" Num=0x%x,\t", ptiming->u16Num);)
    MVOP_DBG(MVOP_PRINTF(" Den=0x%x,\t", ptiming->u16Den);)
    MVOP_DBG(MVOP_PRINTF(" u16ExpFRate=%u #\n\n", ptiming->u16ExpFrameRate);)
#endif
}

void HAL_MVOP_SetDCClk(MVOP_DevID eDevID, MS_U8 clkNum, MS_BOOL bEnable)
{
    MS_ASSERT((clkNum == 0) || (clkNum == 1));

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            if (clkNum == 0)
            {
                HAL_WriteRegBit(REG_CKG_DC0, FALSE, CKG_DC0_GATED); //only 7221, For DIP share 0x1014 bank, do not disable.
            }
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            if (clkNum == 0)
            {
                HAL_WriteRegBit(REG_CKG_SUB_DC0, FALSE, CKG_SUB_DC0_GATED);
            }
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
}

void HAL_MVOP_SetDCSRAMClk(MVOP_DevID eDevID, MS_U8 clkNum, MS_BOOL bEnable)
{
    MS_ASSERT((clkNum == 0) || (clkNum == 1));

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            if (clkNum == 0)
            {
                HAL_WriteRegBit(REG_CKG_DC_SRAM, !bEnable, CKG_DC0_SRAM_GATED);
                HAL_WriteRegBit(REG_CKG_DC_SRAM, !bEnable, CKG_DC0_SRAM1_GATED);
                // 000: clk_miu / 001: clk_fbdec(DIP)
                HAL_WriteByteMask(REG_CKG_DC_SRAM, 0, CKG_DC0_SRAM_MASK);
                HAL_WriteByteMask(REG_CKG_DC_SRAM, 0, CKG_DC0_SRAM1_MASK);
            }
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            if (clkNum == 0)
            {
                HAL_WriteRegBit(REG_CKG_DC_SRAM, !bEnable, CKG_DC0_SRAM_GATED);
                HAL_WriteRegBit(REG_CKG_DC_SRAM, !bEnable, CKG_DC0_SRAM1_GATED);
                // 000: clk_miu / 001: clk_fbdec(DIP)
                HAL_WriteByteMask(REG_CKG_DC_SRAM, 0, CKG_DC0_SRAM_MASK);
                HAL_WriteByteMask(REG_CKG_DC_SRAM, 0, CKG_DC0_SRAM1_MASK);
            }
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
}

void HAL_MVOP_SetFBDecClk(MVOP_DevID eID, MS_BOOL bEnable)
{
    if (g_pHalMVOPCtx == NULL)
    {
        MVOP_DBG(MVOP_PRINTF("%s g_pHalMVOPCtx is NULL pointer\n", __FUNCTION__);)
        return;
    }
    if (bEnable == FALSE)
    {
        //Assign Huffman table need to enable FBDec Clk, can not disable in mvop.
#if 0
        if (((eID == E_MVOP_DEV_0) && (g_pHalMVOPCtx->bSubIsInit == FALSE))
                || ((eID == E_MVOP_DEV_1) && (g_pHalMVOPCtx->bIsInit == FALSE))) //main and sub both disable
        {
            HAL_WriteRegBit(REG_CKG_FBDEC, 1, CKG_FBDEC_GATED);
        }
#endif
    }
    else
    {
        HAL_WriteRegBit(REG_MFD_BASIC_H, 0, MFD_CLK_GATED);
    }
    //M7632/M7642/M7332 mfdec use miu clock
    HAL_WriteRegBit(REG_MFD_XPU_SEL, 0, MVOP_CPU_SWITCH); //tmp for M7221: switch to mvop
}

void HAL_MVOP_SetSynClk(MVOP_DevID eDevID, MVOP_Timing* ptiming)
{
    if (g_pHalMVOPCtx == NULL)
    {
        MVOP_DBG(MVOP_PRINTF("%s g_pHalMVOPCtx is NULL pointer\n", __FUNCTION__);)
        return;
    }

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            switch (g_pHalMVOPCtx->eClock)
            {
                case E_MVOP_FREERUNMODE:
                {
                    MS_U64 u64mpll_clock = MPLL_CLOCK_216 << 27 ; //mvop hw bug, tsp default use 216MHz mpll clock @ maserati
                    if (HAL_ReadRegBit(REG_CLK_SYN_STC, BIT0) == BIT0) //check stc1 clock use 432 or 216
                    {
                        u64mpll_clock = MPLL_CLOCK_432 << 27 ;
                    }
                    MS_U64 u64exp_clock = ((MS_U64)ptiming->u16H_TotalCount * (MS_U64)ptiming->u16V_TotalCount * (MS_U64)ptiming->u16ExpFrameRate);
                    do_div(u64exp_clock, 1000);
                    do_div(u64mpll_clock, u64exp_clock);
                    MS_U32 u32FreerunClk = (MS_U32)u64mpll_clock;
                    HAL_MVOP_SetFrequency(E_MVOP_DEV_0, E_MVOP_FREERUNMODE);
                    HAL_WriteByte(REG_DC0_FREERUN_CW_L, LOWBYTE((MS_U16)u32FreerunClk));
                    HAL_WriteByte((REG_DC0_FREERUN_CW_L + 1), HIGHBYTE((MS_U16)u32FreerunClk));
                    HAL_WriteByte(REG_DC0_FREERUN_CW_H, LOWBYTE((MS_U16)(u32FreerunClk >> 16)));
                    HAL_WriteByte((REG_DC0_FREERUN_CW_H + 1), HIGHBYTE((MS_U16)(u32FreerunClk >> 16)));
                    HAL_WriteRegBit(REG_UPDATE_DC0_CW, 1, UPDATE_DC0_FREERUN_CW);
                    HAL_WriteRegBit(REG_UPDATE_DC0_CW, 0, UPDATE_DC0_FREERUN_CW);
                    break;
                }
                case E_MVOP_HARDWAREMODE:
                {
                    HAL_MVOP_SetFrequency(E_MVOP_DEV_0, E_MVOP_690MHZ);
                    break;
                }
                case E_MVOP_144MHZ:
                {
                    break;
                }
                case E_MVOP_160MHZ:
                {
                    if (ptiming->u16ExpFrameRate == 0)
                    {
                        MVOP_DBG(MVOP_PRINTF("%s ptiming->u16ExpFrameRate == 0\n", __FUNCTION__);)
                        return;
                    }

                    //Set DC1 Timing
                    MS_U32 u32FrameRate = (MS_U32)ptiming->u16ExpFrameRate;
                    MS_U32 u32VSize = 1024;
                    MS_U32 u32HSize = ((MVOP_SYNC_CLOCK_BASE / u32FrameRate) * 1000) / u32VSize;

                    if (u32HSize > 4096)
                    {
                        MVOP_PRINTF("[Warning] xc support u32HSize > 4096 after CL 712830\n");
                    }

                    HAL_MVOP_SetFrequency(E_MVOP_DEV_0, E_MVOP_160MHZ);
                    break;
                }
                case E_MVOP_320MHZ:
                {
                    HAL_MVOP_SetFrequency(E_MVOP_DEV_0, E_MVOP_320MHZ);
                    break;
                }
                case E_MVOP_690MHZ:
                {
                    HAL_MVOP_SetFrequency(E_MVOP_DEV_0, E_MVOP_690MHZ);
                    break;
                }
                default:
                {
                    HAL_MVOP_SetFrequency(E_MVOP_DEV_0, E_MVOP_SYNCMODE);
                    HAL_WriteByte(REG_DC0_NUM, LOWBYTE(ptiming->u16Num));
                    HAL_WriteByte((REG_DC0_NUM + 1), HIGHBYTE(ptiming->u16Num));
                    HAL_WriteByte(REG_DC0_DEN, LOWBYTE(ptiming->u16Den));
                    HAL_WriteByte((REG_DC0_DEN + 1), HIGHBYTE(ptiming->u16Den));
                    HAL_WriteRegBit(REG_UPDATE_DC0_CW, 1, UPDATE_DC0_SYNC_CW);
                    HAL_WriteRegBit(REG_UPDATE_DC0_CW, 0, UPDATE_DC0_SYNC_CW);
                    break;
                }
            }
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            if (TRUE == g_pHalMVOPCtx->bIsSinDV)
            {
                g_pHalMVOPCtx->eSubClock = g_pHalMVOPCtx->eClock;
            }
            switch (g_pHalMVOPCtx->eSubClock)
            {
                case E_MVOP_FREERUNMODE:
                {
                    //mvop hw bug, tsp default use 216MHz mpll clock @ maserati
                    MS_U64 u64mpll_clock = MPLL_CLOCK_216 << 27 ;
                    //check stc1 clock use 432 or 216
                    if (HAL_ReadRegBit(REG_CLK_SYN_STC, BIT4) == BIT4)
                    {
                        u64mpll_clock = MPLL_CLOCK_432 << 27 ;
                    }
                    MS_U64 u64exp_clock = (((MS_U64)ptiming->u16H_TotalCount * (MS_U64)ptiming->u16V_TotalCount * (MS_U64)ptiming->u16ExpFrameRate) / 1000);
                    do_div(u64exp_clock, 1000);
                    do_div(u64mpll_clock, u64exp_clock);
                    MS_U32 u32FreerunClk = (MS_U32)u64mpll_clock;
                    HAL_MVOP_SetFrequency(E_MVOP_DEV_1, E_MVOP_FREERUNMODE);
                    HAL_WriteByte(REG_DC1_FREERUN_CW_L, LOWBYTE((MS_U16)u32FreerunClk));
                    HAL_WriteByte((REG_DC1_FREERUN_CW_L + 1), HIGHBYTE((MS_U16)u32FreerunClk));
                    HAL_WriteByte(REG_DC1_FREERUN_CW_H, LOWBYTE((MS_U16)(u32FreerunClk >> 16)));
                    HAL_WriteByte((REG_DC1_FREERUN_CW_H + 1), HIGHBYTE((MS_U16)(u32FreerunClk >> 16)));
                    HAL_WriteRegBit(REG_UPDATE_DC1_CW, 1, UPDATE_DC1_FREERUN_CW);
                    HAL_WriteRegBit(REG_UPDATE_DC1_CW, 0, UPDATE_DC1_FREERUN_CW);
                    break;
                }
                case E_MVOP_144MHZ:
                {
                    break;
                }
                case E_MVOP_160MHZ:
                {
                    if (ptiming->u16ExpFrameRate == 0)
                    {
                        MVOP_DBG(MVOP_PRINTF("%s ptiming->u16ExpFrameRate == 0\n", __FUNCTION__);)
                        return;
                    }

                    //Set DC1 Timing
                    MS_U32 u32FrameRate = (MS_U32)ptiming->u16ExpFrameRate;
                    MS_U32 u32VSize = 1024;
                    MS_U32 u32HSize = ((MVOP_SYNC_CLOCK_BASE / u32FrameRate) * 1000) / u32VSize;

                    if (u32HSize > 4096)
                    {
                        MVOP_PRINTF("[Warning] xc support u32HSize > 4096 after CL 712830\n");
                    }

                    HAL_MVOP_SetFrequency(E_MVOP_DEV_1, E_MVOP_160MHZ);
                    break;
                }
                case E_MVOP_320MHZ:
                {
                    HAL_MVOP_SetFrequency(E_MVOP_DEV_1, E_MVOP_320MHZ);
                    break;
                }
                default:
                {
                    HAL_MVOP_SetFrequency(E_MVOP_DEV_1, E_MVOP_SYNCMODE);
                    HAL_WriteByte(REG_DC1_NUM, LOWBYTE(ptiming->u16Num));
                    HAL_WriteByte((REG_DC1_NUM + 1), HIGHBYTE(ptiming->u16Num));
                    HAL_WriteByte(REG_DC1_DEN, LOWBYTE(ptiming->u16Den));
                    HAL_WriteByte((REG_DC1_DEN + 1), HIGHBYTE(ptiming->u16Den));
                    HAL_WriteRegBit(REG_UPDATE_DC1_CW, 1, UPDATE_DC1_SYNC_CW);
                    HAL_WriteRegBit(REG_UPDATE_DC1_CW, 0, UPDATE_DC1_SYNC_CW);
                    break;
                }
            }
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
}

void HAL_MVOP_SetMonoMode(MVOP_DevID eDevID, MS_BOOL bEnable)
{
    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            if (bEnable)
            {
#if 0
                //0x28[9] reg_h264_purey not work in monet, use vc1 range map replace
                HAL_WriteByte(VOP_U_PAT, 0x80);
                HAL_WriteByte((VOP_U_PAT + 1), 0x80);
                // Mono mode enable
                HAL_WriteRegBit(VOP_INPUT_SWITCH1, 1, BIT1);
#endif
                HAL_WriteByteMask(VOP_RAMAP_CHROMA, 0x0, VOP_RAMAP_CHROMA_VAL);
                // VOP_RAMAP_CHROMA_VAL double buffer
                HAL_MVOP_LoadReg(E_MVOP_DEV_0);
                HAL_MVOP_ForceWriteReg(E_MVOP_DEV_0);
                HAL_WriteRegBit(VOP_RAMAP_CHROMA, 1, VOP_RAMAP_CHROMA_EN);

                // 0x1014[38][5] only works with WB
                // HAL_WriteRegBit(VOP_INFO_FROM_CODEC_L, 0, VOP_INFO_FROM_CODEC_RANGE_MAP);
            }
            else
            {
#if 0
                //Mono mode disable
                HAL_WriteRegBit(VOP_INPUT_SWITCH1, 0, BIT1);
#endif
                HAL_WriteByteMask(VOP_RAMAP_CHROMA, 0x8, VOP_RAMAP_CHROMA_VAL);
                // VOP_RAMAP_CHROMA_VAL double buffer
                HAL_MVOP_LoadReg(E_MVOP_DEV_0);
                HAL_MVOP_ForceWriteReg(E_MVOP_DEV_0);
                HAL_WriteRegBit(VOP_RAMAP_CHROMA, 0, VOP_RAMAP_CHROMA_EN);

                // 0x1014[38][5] only works with WB
                // HAL_WriteRegBit(VOP_INFO_FROM_CODEC_L, 1, VOP_INFO_FROM_CODEC_RANGE_MAP);
            }
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            if (bEnable)
            {
#if 0
                //0x28[9] reg_h264_purey not work in monet, use vc1 range map replace
                HAL_WriteByte(SUB_REG(VOP_U_PAT), 0x80);
                HAL_WriteByte(SUB_REG(VOP_U_PAT + 1), 0x80);
                // Mono mode enable
                HAL_WriteRegBit(SUB_REG(VOP_INPUT_SWITCH1), 1, BIT1);
#endif
                HAL_WriteByteMask(SUB_REG(VOP_RAMAP_CHROMA), 0x0, VOP_RAMAP_CHROMA_VAL);
                HAL_MVOP_LoadReg(E_MVOP_DEV_1);
                // VOP_RAMAP_CHROMA_VAL double buffer
                HAL_MVOP_ForceWriteReg(E_MVOP_DEV_1);
                HAL_WriteRegBit(SUB_REG(VOP_RAMAP_CHROMA), 1, VOP_RAMAP_CHROMA_EN);

                // 0x1013[38][5] only works with WB
                // HAL_WriteRegBit(SUB_REG(VOP_INFO_FROM_CODEC_L), 0, VOP_INFO_FROM_CODEC_RANGE_MAP);
            }
            else
            {
#if 0
                //Mono mode disable
                HAL_WriteRegBit(SUB_REG(VOP_INPUT_SWITCH1), 0, BIT1);
#endif
                HAL_WriteByteMask(SUB_REG(VOP_RAMAP_CHROMA), 0x8, VOP_RAMAP_CHROMA_VAL);
                HAL_MVOP_LoadReg(E_MVOP_DEV_1);
                // VOP_RAMAP_CHROMA_VAL double buffer
                HAL_MVOP_ForceWriteReg(E_MVOP_DEV_1);
                HAL_WriteRegBit(SUB_REG(VOP_RAMAP_CHROMA), 0, VOP_RAMAP_CHROMA_EN);

                // 0x1013[38][5] only works with WB
                // HAL_WriteRegBit(SUB_REG(VOP_INFO_FROM_CODEC_L), 1, VOP_INFO_FROM_CODEC_RANGE_MAP);
            }
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
}

/******************************************************************************/
/// Set MVOP for H264  Hardwire Mode
/******************************************************************************/
void HAL_MVOP_SetH264HardwireMode(MVOP_DevID eDevID)
{
    UNUSED(eDevID);
    MVOP_PRINTF("\n[%s] MVOP driver switch to MCU mode\n", __FUNCTION__);
}

/******************************************************************************/
/// Set MVOP for H264 Dolby Vision Hardwire Mode
/******************************************************************************/
void HAL_MVOP_SetH264HardwireMode_DV(MVOP_DevID eDevID)
{
    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            HAL_MVOP_EnableHDRSetting(E_MVOP_DEV_0, ENABLE);
            HAL_MVOP_SetSingleDV(E_MVOP_DEV_0, ENABLE);
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            MVOP_PRINTF("\n[%s] MVOP driver switch to MCU mode\n", __FUNCTION__);
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID = %u\n", __FUNCTION__,
                        eDevID);
            break;
        }
    }
}

/******************************************************************************/
/// Set MVOP for RM  Hardwire Mode
/******************************************************************************/
void HAL_MVOP_SetRMHardwireMode(MVOP_DevID eDevID)
{
    UNUSED(eDevID);
    MVOP_PRINTF("\n[%s] MVOP driver switch to MCU mode\n", __FUNCTION__);
}

/******************************************************************************/
/// Set MVOP for JPEG Hardwire Mode
/******************************************************************************/
void HAL_MVOP_SetJpegHardwireMode(MVOP_DevID eDevID)
{
    UNUSED(eDevID);
    MVOP_PRINTF("\n[%s] MVOP driver switch to MCU mode\n", __FUNCTION__);
}

/******************************************************************************/
/// Set MVOP for EVD Hardwire Mode
/******************************************************************************/
void HAL_MVOP_SetEVDHardwireMode(MVOP_DevID eDevID)
{
    MVOP_PRINTF("\n[%s] MVOP driver switch to MCU mode\n", __FUNCTION__);

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            g_pHalMVOPCtx->bIsH265 = TRUE;
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            g_pHalMVOPCtx->bSubIsH265 = TRUE;
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
}

/******************************************************************************/
/// Set MVOP for EVD TCH Vision Hardwire Mode
/******************************************************************************/
void HAL_MVOP_SetEVDHardwireMode_DV(void)
{
    HAL_MVOP_EnableHDRSetting(E_MVOP_DEV_0, ENABLE);
    HAL_MVOP_SetSingleDV(E_MVOP_DEV_1, ENABLE);
    g_pHalMVOPCtx->bIsH265 = TRUE;
}

/******************************************************************************/
/// Set MVOP for EVD TCH Vision Hardwire Mode
/******************************************************************************/
void HAL_MVOP_SetEVDHardwireMode_TCH(MVOP_DevID eDevID)
{
    MVOP_PRINTF("\n[%s] MVOP driver switch to MCU mode\n", __FUNCTION__);

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            g_pHalMVOPCtx->bIsH265 = TRUE;
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            g_pHalMVOPCtx->bSubIsH265 = TRUE;
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID = %u\n", __FUNCTION__,
                        eDevID);
            break;
        }
    }
}

/******************************************************************************/
/// Set MVOP for VP9 Hardwire Mode
/// vp9 hw change in Manhathan: tile mode 16x32
/******************************************************************************/
void HAL_MVOP_SetVP9HardwireMode(MVOP_DevID eDevID)
{
    UNUSED(eDevID);
    MVOP_PRINTF("\n[%s] MVOP driver switch to MCU mode\n", __FUNCTION__);
}

/******************************************************************************/
/// Set MVOP for AVS2 Hardwire Mode
/******************************************************************************/
void HAL_MVOP_SetAVS2HardwireMode(MVOP_DevID eDevID)
{
    UNUSED(eDevID);
    MVOP_PRINTF("\n[%s] MVOP driver switch to MCU mode\n", __FUNCTION__);
}

/******************************************************************************/
/// Set MVOP for EVD MCU Mode
/******************************************************************************/
void HAL_MVOP_SetEVDFeature(MVOP_DevID eID, MVOP_EVDFeature* stEVDInput)
{
    switch (eID)
    {
        case E_MVOP_DEV_0:

            HAL_WriteRegBit(VOP_INPUT_SWITCH0, stEVDInput->bEnableEVD, EVD_ENABLE);// 32x32 enable

            switch (stEVDInput->eEVDBit[Y_INFO])
            {
                case E_MVOP_EVD_8BIT:
                    HAL_WriteRegBit(VOP_EVD_10B_EN, 0, VOP_EVD_10B_Y_EN);
                    break;
                case E_MVOP_EVD_10BIT:
                    HAL_WriteRegBit(VOP_EVD_10B_EN, 1, VOP_EVD_10B_Y_EN);
                    break;
                default:
                    break;
            }

            switch (stEVDInput->eEVDBit[UV_INFO])
            {
                case E_MVOP_EVD_8BIT:
                    HAL_WriteRegBit(VOP_EVD_10B_EN, 0, VOP_EVD_10B_UV_EN);
                    break;
                case E_MVOP_EVD_10BIT:
                    HAL_WriteRegBit(VOP_EVD_10B_EN, 1, VOP_EVD_10B_UV_EN);
                    break;
                default:
                    break;
            }

            //LSB BW Discard MASK
            if (stEVDInput->eEVDBit[Y_INFO] || stEVDInput->eEVDBit[UV_INFO])
            {
                HAL_WriteByteMask(VOP_REG_MASK, 0, VOP_LSB_REQ_MASK);
                HAL_WriteRegBit(VOP_UV_SHIFT, 0, VOP_GCLK_MIU_ON);
                MVOP_DBG(MVOP_PRINTF("[Debug] 10 bits display\n"););
                // 10 bits enable MUST enable 3d[15] in M7622
                HAL_WriteRegBit(VOP_REG_DUMMY, TRUE, VOP_420_BW_SAVE);
            }
            else
            {
                //HAL_WriteByteMask(VOP_REG_MASK, BIT1, VOP_LSB_REQ_MASK);
                MVOP_DBG(MVOP_PRINTF("[Debug] 10 bits bw riu control default enable\n"););
            }

            // Write trigger
            HAL_MVOP_LoadReg(E_MVOP_DEV_0);
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_0);
            break;
        case E_MVOP_DEV_1:
#if MVOP_SUPPORT_SUB

            HAL_WriteRegBit(SUB_REG(VOP_INPUT_SWITCH0), stEVDInput->bEnableEVD, EVD_ENABLE);// 32x32 enable

            switch (stEVDInput->eEVDBit[Y_INFO])
            {
                case E_MVOP_EVD_8BIT:
                    HAL_WriteRegBit(SUB_REG(VOP_EVD_10B_EN), 0, VOP_EVD_10B_Y_EN);
                    break;
                case E_MVOP_EVD_10BIT:
                    HAL_WriteRegBit(SUB_REG(VOP_EVD_10B_EN), 1, VOP_EVD_10B_Y_EN);
                    break;
                default:
                    break;
            }

            switch (stEVDInput->eEVDBit[UV_INFO])
            {
                case E_MVOP_EVD_8BIT:
                    HAL_WriteRegBit(SUB_REG(VOP_EVD_10B_EN), 0, VOP_EVD_10B_UV_EN);
                    break;
                case E_MVOP_EVD_10BIT:
                    HAL_WriteRegBit(SUB_REG(VOP_EVD_10B_EN), 1, VOP_EVD_10B_UV_EN);
                    break;
                default:
                    break;
            }

            //LSB BW Discard MASK
            if (stEVDInput->eEVDBit[Y_INFO] || stEVDInput->eEVDBit[UV_INFO])
            {
                HAL_WriteByteMask(SUB_REG(VOP_REG_MASK), 0, VOP_LSB_REQ_MASK);
                HAL_WriteRegBit(SUB_REG(VOP_UV_SHIFT), 0, VOP_GCLK_MIU_ON);
                MVOP_DBG(MVOP_PRINTF("[Debug] 10 bits display\n"););
                // 10 bits enable MUST enable 3d[15] in M7622
                HAL_WriteRegBit(SUB_REG(VOP_REG_DUMMY), TRUE, VOP_420_BW_SAVE);
            }
            else
            {
                //HAL_WriteByteMask(SUB_REG(VOP_REG_MASK), BIT1, VOP_LSB_REQ_MASK);
                MVOP_DBG(MVOP_PRINTF("[Debug] 10 bits bw riu control default enable\n"););
            }
            // Write trigger
            HAL_MVOP_LoadReg(E_MVOP_DEV_1);
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_1);
#endif
            break;
        default:
            break;
    }

}

///Enable 3D L/R dual buffer mode
MS_BOOL HAL_MVOP_Enable3DLR(MVOP_DevID eDevID, MS_BOOL bEnable)
{
    MS_BOOL bRet = FALSE;

    if (g_pHalMVOPCtx == NULL)
    {
        MVOP_DBG(MVOP_PRINTF("%s g_pHalMVOPCtx is NULL pointer\n", __FUNCTION__);)
        return bRet;
    }

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            HAL_WriteRegBit(VOP_MULTI_WIN_CFG0, bEnable, VOP_LR_BUF_MODE);
            g_pHalMVOPCtx->b3DLRMode = bEnable;
            if (bEnable)
            {
                //only for monaco: do not wait for data ready.
                HAL_WriteByteMask(VOP_NOT_WAIT_READ_DATA, 2, VOP_NOT_WAIT_RDLAT);
                HAL_WriteRegBit(VOP_REG_BW_SAVE, 0, VOP_420_BW_SAVE_EX);
            }
            else
            {
                HAL_WriteByteMask(VOP_NOT_WAIT_READ_DATA, 0, VOP_NOT_WAIT_RDLAT);
            }
            bRet = TRUE;
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            HAL_WriteRegBit(SUB_REG(VOP_MULTI_WIN_CFG0), bEnable, VOP_LR_BUF_MODE);
            g_pHalMVOPCtx->bSub3DLRMode = bEnable;
            if (bEnable)
            {
                //only for monaco: do not wait for data ready.
                HAL_WriteByteMask(SUB_REG(VOP_NOT_WAIT_READ_DATA), 2, VOP_NOT_WAIT_RDLAT);
                HAL_WriteRegBit(SUB_REG(VOP_REG_BW_SAVE), 0, VOP_420_BW_SAVE_EX);
            }
            else
            {
                HAL_WriteByteMask(SUB_REG(VOP_NOT_WAIT_READ_DATA), 0, VOP_NOT_WAIT_RDLAT);
            }
            bRet = TRUE;
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
    return bRet;
}

///Get if 3D L/R mode is enabled
MS_BOOL HAL_MVOP_Get3DLRMode(MVOP_DevID eDevID)
{
    MS_BOOL bRet = FALSE;

    if (g_pHalMVOPCtx == NULL)
    {
        MVOP_DBG(MVOP_PRINTF("%s g_pHalMVOPCtx is NULL pointer\n", __FUNCTION__);)
        return bRet;
    }

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            bRet = g_pHalMVOPCtx->b3DLRMode;
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            bRet = g_pHalMVOPCtx->bSub3DLRMode;
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
    return bRet;
}

MS_BOOL HAL_MVOP_GetTimingInfoFromRegisters(MVOP_DevID eDevID, MVOP_TimingInfo_FromRegisters* pMvopTimingInfo)
{
    MS_BOOL bRet = FALSE;

    if (NULL == pMvopTimingInfo)
    {
        MVOP_PRINTF("HAL_MVOP_GetTimingInfoFromRegisters():pMvopTimingInfo is NULL\n");
        return bRet;
    }

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            if (HAL_MVOP_GetEnableState(E_MVOP_DEV_0) == FALSE)
            {
                MVOP_PRINTF("MVOP is not enabled!\n");
                pMvopTimingInfo->bEnabled = FALSE;
                break;
            }
            pMvopTimingInfo->bEnabled = TRUE;
            pMvopTimingInfo->u16H_TotalCount = (HAL_ReadByte((VOP_FRAME_HCOUNT + 1)) << 8) | (HAL_ReadByte((VOP_FRAME_HCOUNT)));
            pMvopTimingInfo->u16V_TotalCount = (HAL_ReadByte((VOP_FRAME_VCOUNT + 1)) << 8) | (HAL_ReadByte((VOP_FRAME_VCOUNT)));
            pMvopTimingInfo->u16VBlank0_Start = (HAL_ReadByte((VOP_VB0_STR + 1)) << 8) | (HAL_ReadByte((VOP_VB0_STR)));
            pMvopTimingInfo->u16VBlank0_End = (HAL_ReadByte((VOP_VB0_END + 1)) << 8) | (HAL_ReadByte((VOP_VB0_END)));
            pMvopTimingInfo->u16VBlank1_Start = (HAL_ReadByte((VOP_VB1_STR + 1)) << 8) | (HAL_ReadByte((VOP_VB1_STR)));
            pMvopTimingInfo->u16VBlank1_End = (HAL_ReadByte((VOP_VB1_END + 1)) << 8) | (HAL_ReadByte((VOP_VB1_END)));
            pMvopTimingInfo->u16TopField_Start = (HAL_ReadByte((VOP_TF_STR + 1)) << 8) | (HAL_ReadByte((VOP_TF_STR)));
            pMvopTimingInfo->u16BottomField_Start = (HAL_ReadByte((VOP_BF_STR + 1)) << 8) | (HAL_ReadByte((VOP_BF_STR)));
            pMvopTimingInfo->u16HActive_Start = (HAL_ReadByte((VOP_HACT_STR + 1)) << 8) | (HAL_ReadByte((VOP_HACT_STR)));
            pMvopTimingInfo->u16TopField_VS = (HAL_ReadByte((VOP_TF_VS + 1)) << 8) | (HAL_ReadByte((VOP_TF_VS)));
            pMvopTimingInfo->u16BottomField_VS = (HAL_ReadByte((VOP_BF_VS + 1)) << 8) | (HAL_ReadByte((VOP_BF_VS)));
            pMvopTimingInfo->bInterlace = (HAL_ReadRegBit(VOP_CTRL0, BIT7) == BIT7);
            bRet = TRUE;
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            if (HAL_MVOP_GetEnableState(E_MVOP_DEV_1) == FALSE)
            {
                MVOP_PRINTF("MVOP is not enabled!\n");
                pMvopTimingInfo->bEnabled = FALSE;
                break;
            }
            pMvopTimingInfo->bEnabled = TRUE;
            pMvopTimingInfo->u16H_TotalCount = (HAL_ReadByte(SUB_REG(VOP_FRAME_HCOUNT + 1) << 8)) | (HAL_ReadByte(SUB_REG(VOP_FRAME_HCOUNT)));
            pMvopTimingInfo->u16V_TotalCount = (HAL_ReadByte(SUB_REG(VOP_FRAME_VCOUNT + 1) << 8)) | (HAL_ReadByte(SUB_REG(VOP_FRAME_VCOUNT)));
            pMvopTimingInfo->u16VBlank0_Start = (HAL_ReadByte(SUB_REG(VOP_VB0_STR + 1) << 8)) | (HAL_ReadByte(SUB_REG(VOP_VB0_STR)));
            pMvopTimingInfo->u16VBlank0_End = (HAL_ReadByte(SUB_REG(VOP_VB0_END + 1) << 8)) | (HAL_ReadByte(SUB_REG(VOP_VB0_END)));
            pMvopTimingInfo->u16VBlank1_Start = (HAL_ReadByte(SUB_REG(VOP_VB1_STR + 1) << 8)) | (HAL_ReadByte(SUB_REG(VOP_VB1_STR)));
            pMvopTimingInfo->u16VBlank1_End = (HAL_ReadByte(SUB_REG(VOP_VB1_END + 1) << 8)) | (HAL_ReadByte(SUB_REG(VOP_VB1_END)));
            pMvopTimingInfo->u16TopField_Start = (HAL_ReadByte(SUB_REG(VOP_TF_STR + 1) << 8)) | (HAL_ReadByte(SUB_REG(VOP_TF_STR)));
            pMvopTimingInfo->u16BottomField_Start = (HAL_ReadByte(SUB_REG(VOP_BF_STR + 1) << 8)) | (HAL_ReadByte(SUB_REG(VOP_BF_STR)));
            pMvopTimingInfo->u16HActive_Start = (HAL_ReadByte(SUB_REG(VOP_HACT_STR + 1) << 8)) | (HAL_ReadByte(SUB_REG(VOP_HACT_STR)));
            pMvopTimingInfo->u16TopField_VS = (HAL_ReadByte(SUB_REG(VOP_TF_VS + 1) << 8)) | (HAL_ReadByte(SUB_REG(VOP_TF_VS)));
            pMvopTimingInfo->u16BottomField_VS = (HAL_ReadByte(SUB_REG(VOP_BF_VS + 1) << 8)) | (HAL_ReadByte(SUB_REG(VOP_BF_VS)));
            pMvopTimingInfo->bInterlace = (HAL_ReadRegBit(SUB_REG(VOP_CTRL0), BIT7) == BIT7);
            bRet = TRUE;
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
    return bRet;
}

void HAL_MVOP_SetYUVBaseAdd(MVOP_DevID eDevID, MS_PHY u32YOffset,
                            MS_PHY u32UVOffset, MS_BOOL bProgressive,
                            MS_BOOL b422pack)
{
    MS_PHY u64tmp = 0;

    if (NULL == g_pHalMVOPCtx)
    {
        MVOP_DBG(MVOP_PRINTF("%s g_pHalMVOPCtx is NULL pointer\n",
                             __FUNCTION__);)
        return;
    }

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            /* Y offset */
            u64tmp = u32YOffset >> 3;
            if (FALSE == bProgressive)
            {
                /* Refine Y offset for interlace repeat bottom field */
                if (E_MVOP_RPTFLD_BOT == g_pHalMVOPCtx->eRepeatField)
                {
                    MVOP_DBG("%d eRepeatField(%x) is bottom!\n", __LINE__,
                             g_pHalMVOPCtx->eRepeatField);
                    u64tmp += 2;
                }
                else
                {
                    MVOP_DBG("%d eRepeatField(%x) is TOP or NONE.\n", __LINE__,
                             g_pHalMVOPCtx->eRepeatField);
                }
            }
            HAL_WriteByte(VOP_JPG_YSTR0_L, u64tmp & 0xff);
            HAL_WriteByte((VOP_JPG_YSTR0_L + 1), (u64tmp >> 8) & 0xff);
            HAL_WriteByte((VOP_JPG_YSTR0_L + 2), (u64tmp >> 16) & 0xff);
            HAL_WriteByte((VOP_JPG_YSTR0_L + 3),
                          (u64tmp >> 24) & VOP_YUV_STR_HIBITS);

            if (FALSE == bProgressive)
            {
                /* Y offset of bottom field if interlace */
                HAL_WriteByte(VOP_JPG_YSTR1_L, u64tmp & 0xff);
                HAL_WriteByte((VOP_JPG_YSTR1_L + 1), (u64tmp >> 8) & 0xff);
                HAL_WriteByte((VOP_JPG_YSTR1_L + 2), (u64tmp >> 16) & 0xff);
                HAL_WriteByte((VOP_JPG_YSTR1_L + 3),
                              (u64tmp >> 24) & VOP_YUV_STR_HIBITS);
            }

            if (TRUE == b422pack)
            {
                /* add 16 for 128bit; add 8 for 64bit */
                u32UVOffset = u32YOffset + 16;
            }
            /* UV offset */
            u64tmp = u32UVOffset >> 3;
            if (FALSE == bProgressive)
            {
                /* Refine UV offset for interlace repeat bottom field */
                if (E_MVOP_RPTFLD_BOT == g_pHalMVOPCtx->eRepeatField)
                {
                    MVOP_DBG("%d eRepeatField(%x) is bottom!\n", __LINE__,
                             g_pHalMVOPCtx->eRepeatField);
                    u64tmp += 2;
                }
                else
                {
                    MVOP_DBG("%d eRepeatField(%x) is TOP/NONE.\n", __LINE__,
                             g_pHalMVOPCtx->eRepeatField);
                }
            }
            HAL_WriteByte(VOP_JPG_UVSTR0_L, u64tmp & 0xff);
            HAL_WriteByte((VOP_JPG_UVSTR0_L + 1), (u64tmp >> 8) & 0xff);
            HAL_WriteByte((VOP_JPG_UVSTR0_L + 2), (u64tmp >> 16) & 0xff);
            HAL_WriteByte((VOP_JPG_UVSTR0_L + 3),
                          (u64tmp >> 24) & VOP_YUV_STR_HIBITS);

            if (FALSE == bProgressive)
            {
                /* UV offset of bottom field if interlace */
                HAL_WriteByte(VOP_JPG_UVSTR1_L, u64tmp & 0xff);
                HAL_WriteByte((VOP_JPG_UVSTR1_L + 1), (u64tmp >> 8) & 0xff);
                HAL_WriteByte((VOP_JPG_UVSTR1_L + 2), (u64tmp >> 16) & 0xff);
                HAL_WriteByte((VOP_JPG_UVSTR1_L + 3),
                              (u64tmp >> 24) & VOP_YUV_STR_HIBITS);
            }
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            /* Y offset */
            u64tmp = u32YOffset >> 3;
            if (FALSE == bProgressive)
            {
                /* Refine Y offset for interlace repeat bottom field */
                if (E_MVOP_RPTFLD_BOT == g_pHalMVOPCtx->eSubRepeatField)
                {
                    MVOP_DBG("%d eRepeatField(%x) is bottom!\n", __LINE__,
                             g_pHalMVOPCtx->eSubRepeatField);
                    u64tmp += 2;
                }
                else
                {
                    MVOP_DBG("%d eRepeatField(%x) is TOP or NONE.\n", __LINE__,
                             g_pHalMVOPCtx->eSubRepeatField);
                }
            }
            HAL_WriteByte(SUB_REG(VOP_JPG_YSTR0_L), u64tmp & 0xff);
            HAL_WriteByte(SUB_REG(VOP_JPG_YSTR0_L + 1), (u64tmp >> 8) & 0xff);
            HAL_WriteByte(SUB_REG(VOP_JPG_YSTR0_L + 2), (u64tmp >> 16) & 0xff);
            HAL_WriteByte(SUB_REG(VOP_JPG_YSTR0_L + 3),
                          (u64tmp >> 24) & VOP_YUV_STR_HIBITS);

            if (FALSE == bProgressive)
            {
                /* Y offset of bottom field if interlace */
                HAL_WriteByte(SUB_REG(VOP_JPG_YSTR1_L), u64tmp & 0xff);
                HAL_WriteByte(SUB_REG(VOP_JPG_YSTR1_L + 1),
                              (u64tmp >> 8) & 0xff);
                HAL_WriteByte(SUB_REG(VOP_JPG_YSTR1_L + 2),
                              (u64tmp >> 16) & 0xff);
                HAL_WriteByte(SUB_REG(VOP_JPG_YSTR1_L + 3),
                              (u64tmp >> 24) & VOP_YUV_STR_HIBITS);
            }

            if (TRUE == b422pack)
            {
                /* 128-bit */
                if (HAL_ReadRegBit(SUB_REG(VOP_MIU_IF), VOP_MIU_128B_I64) != VOP_MIU_128B_I64)
                {
                    /* add 16 for 128bit; add 8 for 64bit */
                    u32UVOffset = u32YOffset + 16;
                }
                /* 64-bit */
                else
                {
                    /* add 16 for 128bit; add 8 for 64bit */
                    u32UVOffset = u32YOffset + 8;
                }
            }
            /* UV offset */
            u64tmp = u32UVOffset >> 3;
            if (FALSE == bProgressive)
            {
                /* Refine UV offset for interlace repeat bottom field */
                if (E_MVOP_RPTFLD_BOT == g_pHalMVOPCtx->eSubRepeatField)
                {
                    MVOP_DBG("%d eRepeatField(%x) is bottom!\n", __LINE__,
                             g_pHalMVOPCtx->eSubRepeatField);
                    u64tmp += 2;
                }
                else
                {
                    MVOP_DBG("%d eRepeatField(%x) is TOP/NONE.\n", __LINE__,
                             g_pHalMVOPCtx->eSubRepeatField);
                }
            }
            HAL_WriteByte(SUB_REG(VOP_JPG_UVSTR0_L), u64tmp & 0xff);
            HAL_WriteByte(SUB_REG(VOP_JPG_UVSTR0_L + 1), (u64tmp >> 8) & 0xff);
            HAL_WriteByte(SUB_REG(VOP_JPG_UVSTR0_L + 2), (u64tmp >> 16) & 0xff);
            HAL_WriteByte(SUB_REG(VOP_JPG_UVSTR0_L + 3),
                          (u64tmp >> 24) & VOP_YUV_STR_HIBITS);

            if (FALSE == bProgressive)
            {
                /* UV offset of bottom field if interlace */
                HAL_WriteByte(SUB_REG(VOP_JPG_UVSTR1_L), u64tmp & 0xff);
                HAL_WriteByte(SUB_REG(VOP_JPG_UVSTR1_L + 1),
                              (u64tmp >> 8) & 0xff);
                HAL_WriteByte(SUB_REG(VOP_JPG_UVSTR1_L + 2),
                              (u64tmp >> 16) & 0xff);
                HAL_WriteByte(SUB_REG(VOP_JPG_UVSTR1_L + 3),
                              (u64tmp >> 24) & VOP_YUV_STR_HIBITS);
            }
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID = %u\n", __FUNCTION__,
                        eDevID);
            break;
        }
    }
}

MS_BOOL HAL_MVOP_SetYUVBaseAddMultiView(MVOP_DevID eID, MVOP_BaseAddInput* stBaseAddInfo)
{
    MS_PHY u64tmpY = 0;
    MS_PHY u64tmpUV = 0;

    if (stBaseAddInfo == NULL)
    {
        MVOP_DBG(MVOP_PRINTF("%s stBaseAddInfo is NULL pointer\n", __FUNCTION__);)
        return FALSE;
    }
    // Y offset
    u64tmpY = (stBaseAddInfo->u32YOffset) >> 3;
    // UV offset
    u64tmpUV = (stBaseAddInfo->u32UVOffset) >> 3;

    switch (stBaseAddInfo->eView)
    {
        case E_MVOP_MAIN_VIEW:
            // Y offset
            HAL_WriteByte(VOP_JPG_YSTR0_L, u64tmpY & 0xff);
            HAL_WriteByte((VOP_JPG_YSTR0_L + 1), (u64tmpY >> 8) & 0xff);
            HAL_WriteByte((VOP_JPG_YSTR0_L + 2), (u64tmpY >> 16) & 0xff);
            HAL_WriteByte((VOP_JPG_YSTR0_L + 3), (u64tmpY >> 24) & VOP_YUV_STR_HIBITS);

            // UV offset
            HAL_WriteByte(VOP_JPG_UVSTR0_L, u64tmpUV & 0xff);
            HAL_WriteByte((VOP_JPG_UVSTR0_L + 1), (u64tmpUV >> 8) & 0xff);
            HAL_WriteByte((VOP_JPG_UVSTR0_L + 2), (u64tmpUV >> 16) & 0xff);
            HAL_WriteByte((VOP_JPG_UVSTR0_L + 3), (u64tmpUV >> 24) & VOP_YUV_STR_HIBITS);
            break;
        case E_MVOP_2ND_VIEW:
            // Y offset
            HAL_WriteByte(VOP_JPG_YSTR1_L, u64tmpY & 0xff);
            HAL_WriteByte((VOP_JPG_YSTR1_L + 1), (u64tmpY >> 8) & 0xff);
            HAL_WriteByte((VOP_JPG_YSTR1_L + 2), (u64tmpY >> 16) & 0xff);
            HAL_WriteByte((VOP_JPG_YSTR1_L + 3), (u64tmpY >> 24) & VOP_YUV_STR_HIBITS);

            //UV offset
            HAL_WriteByte(VOP_JPG_UVSTR1_L, u64tmpUV & 0xff);
            HAL_WriteByte((VOP_JPG_UVSTR1_L + 1), (u64tmpUV >> 8) & 0xff);
            HAL_WriteByte((VOP_JPG_UVSTR1_L + 2), (u64tmpUV >> 16) & 0xff);
            HAL_WriteByte((VOP_JPG_UVSTR1_L + 3), (u64tmpUV >> 24) & VOP_YUV_STR_HIBITS);
            break;
        default:
            break;
    }
    return TRUE;
}

MS_PHY HAL_MVOP_GetYBaseAdd(MVOP_DevID eDevID)
{
    MS_PHY u64YOffset = 0;

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            u64YOffset = HAL_ReadByte(VOP_JPG_YSTR0_L) & 0xff;
            u64YOffset |= ((HAL_ReadByte((VOP_JPG_YSTR0_L + 1)) << 8) & 0xff00);
            u64YOffset |= ((HAL_ReadByte((VOP_JPG_YSTR0_L + 2)) << 16) & 0xff0000);
            u64YOffset |= ((HAL_ReadByte((VOP_JPG_YSTR0_L + 3)) & VOP_YUV_STR_HIBITS) << 24);
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            u64YOffset = HAL_ReadByte(SUB_REG(VOP_JPG_YSTR0_L)) & 0xff;
            u64YOffset |= ((HAL_ReadByte(SUB_REG(VOP_JPG_YSTR0_L + 1)) << 8) & 0xff00);
            u64YOffset |= ((HAL_ReadByte(SUB_REG(VOP_JPG_YSTR0_L + 2)) << 16) & 0xff0000);
            u64YOffset |= ((HAL_ReadByte(SUB_REG(VOP_JPG_YSTR0_L + 3)) & VOP_YUV_STR_HIBITS) << 24);
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
    return u64YOffset;
}

MS_PHY HAL_MVOP_GetUVBaseAdd(MVOP_DevID eDevID)
{
    MS_PHY u64UVOffset = 0;

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            u64UVOffset = HAL_ReadByte(VOP_JPG_UVSTR0_L) & 0xff;
            u64UVOffset |= ((HAL_ReadByte((VOP_JPG_UVSTR0_L + 1)) << 8) & 0xff00);
            u64UVOffset |= ((HAL_ReadByte((VOP_JPG_UVSTR0_L + 2)) << 16) & 0xff0000);
            u64UVOffset |= ((HAL_ReadByte((VOP_JPG_UVSTR0_L + 3)) & VOP_YUV_STR_HIBITS) << 24);
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            u64UVOffset = HAL_ReadByte(SUB_REG(VOP_JPG_UVSTR0_L)) & 0xff;
            u64UVOffset |= ((HAL_ReadByte(SUB_REG(VOP_JPG_UVSTR0_L + 1)) << 8) & 0xff00);
            u64UVOffset |= ((HAL_ReadByte(SUB_REG(VOP_JPG_UVSTR0_L + 2)) << 16) & 0xff0000);
            u64UVOffset |= ((HAL_ReadByte(SUB_REG(VOP_JPG_UVSTR0_L + 3)) & VOP_YUV_STR_HIBITS) << 24);
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
    return u64UVOffset;
}

MS_PHY HAL_MVOP_GetYBaseAddMultiView(MVOP_3DView eView)
{
    MS_PHY u64YOffset = 0;
    switch (eView)
    {
        case E_MVOP_MAIN_VIEW:
            u64YOffset = HAL_ReadByte(VOP_JPG_YSTR0_L) & 0xff;
            u64YOffset |= ((HAL_ReadByte((VOP_JPG_YSTR0_L + 1)) << 8) & 0xff00);
            u64YOffset |= ((HAL_ReadByte((VOP_JPG_YSTR0_L + 2)) << 16) & 0xff0000);
            u64YOffset |= ((HAL_ReadByte((VOP_JPG_YSTR0_L + 3)) & VOP_YUV_STR_HIBITS) << 24);
            break;
        case E_MVOP_2ND_VIEW:
            u64YOffset = HAL_ReadByte(VOP_JPG_YSTR1_L) & 0xff;
            u64YOffset |= ((HAL_ReadByte((VOP_JPG_YSTR1_L + 1)) << 8) & 0xff00);
            u64YOffset |= ((HAL_ReadByte((VOP_JPG_YSTR1_L + 2)) << 16) & 0xff0000);
            u64YOffset |= ((HAL_ReadByte((VOP_JPG_YSTR1_L + 3)) << 24) & 0xff000000);
            break;
        default:
            u64YOffset = 0;
            break;
    }
    return u64YOffset;
}

MS_PHY HAL_MVOP_GetUVBaseAddMultiView(MVOP_3DView eView)
{
    MS_PHY u64UVOffset = 0;
    switch (eView)
    {
        case E_MVOP_MAIN_VIEW:
            u64UVOffset = HAL_ReadByte(VOP_JPG_UVSTR0_L) & 0xff;
            u64UVOffset |= ((HAL_ReadByte((VOP_JPG_UVSTR0_L + 1)) << 8) & 0xff00);
            u64UVOffset |= ((HAL_ReadByte((VOP_JPG_UVSTR0_L + 2)) << 16) & 0xff0000);
            u64UVOffset |= ((HAL_ReadByte((VOP_JPG_UVSTR0_L + 3)) & VOP_YUV_STR_HIBITS) << 24);
            break;
        case E_MVOP_2ND_VIEW:
            u64UVOffset = HAL_ReadByte(VOP_JPG_UVSTR1_L) & 0xff;
            u64UVOffset |= ((HAL_ReadByte((VOP_JPG_UVSTR1_L + 1)) << 8) & 0xff00);
            u64UVOffset |= ((HAL_ReadByte((VOP_JPG_UVSTR1_L + 2)) << 16) & 0xff0000);
            u64UVOffset |= ((HAL_ReadByte((VOP_JPG_UVSTR1_L + 3)) << 24) & 0xff000000);
            break;
        default:
            u64UVOffset = 0;
            break;
    }
    return u64UVOffset;
}

MS_BOOL HAL_MVOP_Set3DLRAltOutput_VHalfScaling(MVOP_DevID eDevID, MS_BOOL bEnable)
{
    MS_BOOL bRet = FALSE;
    // enable dual buffer
    MS_BOOL bEnDualBuff = bEnable ? ENABLE : DISABLE;
    // buffer controlled by HK instead of FW
    // MS_BOOL bEnSWDualBuff = bEnable ? DISABLE : ENABLE;
    // do not mask LSB
    MS_BOOL bEnMirrMaskBase = bEnable ? DISABLE : ENABLE;
    // hardware calculate field jump base address
    MS_BOOL bEnHwFldBase = bEnable ? DISABLE : ENABLE;

    if (g_pHalMVOPCtx == NULL)
    {
        MVOP_DBG(MVOP_PRINTF("%s g_pHalMVOPCtx is NULL pointer\n", __FUNCTION__);)
        return bRet;
    }

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            // Set 0x27[2] = 1 (enable SW dual buffer mode)
            HAL_WriteRegBit(VOP_REG_WR, bEnDualBuff, VOP_BUF_DUAL);
            // Set 0x38[8] = 0 (use SW dual buffer mode)
            // M7221 default disable VOP_INFO_FROM_CODEC_L/VOP_INFO_FROM_CODEC_H
            // HAL_WriteRegBit(VOP_INFO_FROM_CODEC_H, bEnSWDualBuff, VOP_INFO_FROM_CODEC_DUAL_BUFF);
            // Set 0x3b[7] = 0 (use MVD/HVD firmware send base)
            HAL_WriteRegBit(VOP_MIRROR_CFG, bEnMirrMaskBase, VOP_MASK_BASE_LSB);
            // Set 0x3b[5] = 0 (hardware calculate field jump base address)
            HAL_WriteRegBit(VOP_MIRROR_CFG, bEnHwFldBase, VOP_HW_FLD_BASE);
            g_pHalMVOPCtx->b3DLRAltOutput = bEnable;
            bRet = TRUE;
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            // Set 0x27[2] = 1 (enable SW dual buffer mode)
            HAL_WriteRegBit(SUB_REG(VOP_REG_WR), bEnDualBuff, VOP_BUF_DUAL);
            // Set 0x38[8] = 0 (use SW dual buffer mode)
            // M7221 default disable VOP_INFO_FROM_CODEC_L/VOP_INFO_FROM_CODEC_H
            // HAL_WriteRegBit(SUB_REG(VOP_INFO_FROM_CODEC_H), bEnSWDualBuff, VOP_INFO_FROM_CODEC_DUAL_BUFF);
            // Set 0x3b[7] = 0 (use MVD/HVD firmware send base)
            HAL_WriteRegBit(SUB_REG(VOP_MIRROR_CFG), bEnMirrMaskBase, VOP_MASK_BASE_LSB);
            // Set 0x3b[5] = 0 (hardware calculate field jump base address)
            HAL_WriteRegBit(SUB_REG(VOP_MIRROR_CFG), bEnHwFldBase, VOP_HW_FLD_BASE);
            g_pHalMVOPCtx->bSub3DLRAltOutput = bEnable;
            bRet = TRUE;
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
    return bRet;
}

MS_BOOL HAL_MVOP_Set3DLRAltOutput(MVOP_DevID eDevID, MS_BOOL bEnable)
{
    MS_BOOL bRet = FALSE;

    if (g_pHalMVOPCtx == NULL)
    {
        MVOP_DBG(MVOP_PRINTF("%s g_pHalMVOPCtx is NULL pointer\n", __FUNCTION__);)
        return bRet;
    }

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            /*
            * Set 0x3C[2] = 1 (enable 3D L/R dual buffer line alternative output)
            * It works when 0x3C[0] = 1
            */
            HAL_WriteRegBit(VOP_MULTI_WIN_CFG0, bEnable, VOP_LR_LA_OUT);
            /* BW saving not support: LA/SBS */
            HAL_WriteRegBit(VOP_REG_DUMMY, 0, VOP_420_BW_SAVE);
            HAL_WriteRegBit(VOP_REG_BW_SAVE, 0, VOP_420_BW_SAVE_EX);
            HAL_MVOP_LoadReg(E_MVOP_DEV_0);
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_0);
            g_pHalMVOPCtx->b3DLRAltOutput = bEnable;
            bRet = TRUE;
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            /*
            * Set 0x3C[2] = 1 (enable 3D L/R dual buffer line alternative output)
            * It works when 0x3C[0] = 1
            */
            HAL_WriteRegBit(SUB_REG(VOP_MULTI_WIN_CFG0), bEnable, VOP_LR_LA_OUT);
            /* BW saving not support: LA/SBS */
            HAL_WriteRegBit(SUB_REG(VOP_REG_DUMMY), 0, VOP_420_BW_SAVE);
            HAL_WriteRegBit(SUB_REG(VOP_REG_BW_SAVE), 0, VOP_420_BW_SAVE_EX);
            HAL_MVOP_LoadReg(E_MVOP_DEV_1);
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_1);
            g_pHalMVOPCtx->bSub3DLRAltOutput = bEnable;
            bRet = TRUE;
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
    return bRet;
}

MS_BOOL HAL_MVOP_Set3DLRAltSBSOutput(MVOP_DevID eDevID, MS_BOOL bEnable)
{
    MS_BOOL bRet = FALSE;

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            HAL_WriteRegBit(VOP_MULTI_WIN_CFG0, bEnable, VOP_LR_BUF_MODE);
            HAL_WriteRegBit(VOP_MULTI_WIN_CFG0, bEnable, VOP_LR_LA_OUT);
            HAL_WriteRegBit(VOP_MULTI_WIN_CFG0, bEnable, VOP_LR_LA2SBS_OUT);
            g_pHalMVOPCtx->b3DLRAltSBSOutput = bEnable;
            bRet = TRUE;
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            HAL_WriteRegBit(SUB_REG(VOP_MULTI_WIN_CFG0), bEnable, VOP_LR_BUF_MODE);
            HAL_WriteRegBit(SUB_REG(VOP_MULTI_WIN_CFG0), bEnable, VOP_LR_LA_OUT);
            HAL_WriteRegBit(SUB_REG(VOP_MULTI_WIN_CFG0), bEnable, VOP_LR_LA2SBS_OUT);
            g_pHalMVOPCtx->bSub3DLRAltSBSOutput = bEnable;
            bRet = TRUE;
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
    return bRet;
}

MS_BOOL HAL_MVOP_Get3DLRAltOutput(MVOP_DevID eDevID)
{
    MS_BOOL bRet = FALSE;

    if (g_pHalMVOPCtx == NULL)
    {
        MVOP_DBG(MVOP_PRINTF("%s g_pHalMVOPCtx is NULL pointer\n", __FUNCTION__);)
        return bRet;
    }

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            bRet = g_pHalMVOPCtx->b3DLRAltOutput;
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            bRet = g_pHalMVOPCtx->bSub3DLRAltOutput;
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
    return bRet;
}

MS_BOOL HAL_MVOP_Get3DLRAltSBSOutput(MVOP_DevID eDevID)
{
    MS_BOOL bRet = FALSE;

    if (g_pHalMVOPCtx == NULL)
    {
        MVOP_DBG(MVOP_PRINTF("%s g_pHalMVOPCtx is NULL pointer\n", __FUNCTION__);)
        return bRet;
    }

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            bRet = g_pHalMVOPCtx->b3DLRAltSBSOutput;
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            bRet = g_pHalMVOPCtx->bSub3DLRAltSBSOutput;
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
    return bRet;
}

EN_MVOP_Output_3D_TYPE HAL_MVOP_GetOutput3DType(MVOP_DevID eDevID)
{
    EN_MVOP_Output_3D_TYPE en3DType = E_MVOP_OUTPUT_3D_NONE;

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            if (g_pHalMVOPCtx->b3DLRMode)
            {
                if (g_pHalMVOPCtx->b3DLRAltSBSOutput)
                {
                    en3DType = E_MVOP_OUTPUT_3D_SBS;
                }
                else
                {
                    en3DType = E_MVOP_OUTPUT_3D_TB;
                }
            }
            else if (g_pHalMVOPCtx->b3DLRAltOutput)
            {
                en3DType = E_MVOP_OUTPUT_3D_LA;
            }
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            if (g_pHalMVOPCtx->bSub3DLRMode)
            {
                if (g_pHalMVOPCtx->bSub3DLRAltSBSOutput)
                {
                    en3DType = E_MVOP_OUTPUT_3D_SBS;
                }
                else
                {
                    en3DType = E_MVOP_OUTPUT_3D_TB;
                }
            }
            else if (g_pHalMVOPCtx->bSub3DLRAltOutput)
            {
                en3DType = E_MVOP_OUTPUT_3D_LA;
            }
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
    return en3DType;
}

MS_BOOL HAL_MVOP_Set3DLR2ndCfg(MS_BOOL bEnable)
{
    //Set 0x3c[7] as 1 to enable
    HAL_WriteRegBit(VOP_MULTI_WIN_CFG0, bEnable, VOP_LR_DIFF_SIZE);
    return TRUE;
}

MS_BOOL HAL_MVOP_Get3DLR2ndCfg(void)
{
    MS_BOOL bEnable = FALSE;
    if (VOP_LR_DIFF_SIZE == (VOP_LR_DIFF_SIZE & HAL_ReadRegBit(VOP_MULTI_WIN_CFG0, VOP_LR_DIFF_SIZE)))
    {
        bEnable = TRUE;
    }
    return bEnable;
}

MVOP_DrvMirror HAL_MVOP_GetMirrorMode(MVOP_DevID eID)
{
    MVOP_DrvMirror enMirror = E_VOPMIRROR_NONE;
    if (g_pHalMVOPCtx == NULL)
    {
        MVOP_DBG(MVOP_PRINTF("%s g_pHalMVOPCtx is NULL pointer\n", __FUNCTION__);)
        return enMirror;
    }
    switch (eID)
    {
        case E_MVOP_DEV_0:
            if (g_pHalMVOPCtx->bMirrorModeVer && g_pHalMVOPCtx->bMirrorModeHor)
            {
                enMirror = E_VOPMIRROR_HVBOTH;
            }
            else if (g_pHalMVOPCtx->bMirrorModeHor)
            {
                enMirror = E_VOPMIRROR_HORIZONTALL;
            }
            else if (g_pHalMVOPCtx->bMirrorModeVer)
            {
                enMirror = E_VOPMIRROR_VERTICAL;
            }
            break;
        case E_MVOP_DEV_1:
#if MVOP_SUPPORT_SUB
            if (g_pHalMVOPCtx->bSubMirrorModeVer && g_pHalMVOPCtx-> bSubMirrorModeHor)
            {
                enMirror = E_VOPMIRROR_HVBOTH;
            }
            else if (g_pHalMVOPCtx->bSubMirrorModeHor)
            {
                enMirror = E_VOPMIRROR_HORIZONTALL;
            }
            else if (g_pHalMVOPCtx->bSubMirrorModeVer)
            {
                enMirror = E_VOPMIRROR_VERTICAL;
            }
#endif
            break;
        default:
            break;
    }
    return enMirror;
}

MS_BOOL HAL_MVOP_SetVerDup(MVOP_DevID eDevID, MS_BOOL bEnable)
{
#if 0
    MS_BOOL bRet = FALSE;

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            // V line duplicate
            HAL_WriteRegBit(VOP_CTRL0, bEnable, BIT3);
            bRet = TRUE;
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            // V line duplicate
            HAL_WriteRegBit(SUB_REG(VOP_CTRL0), bEnable, BIT3);
            bRet = TRUE;
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
    return bRet;
#else
    UNUSED(eDevID);
    if (TRUE == bEnable)
    {
        MVOP_PRINTF("Not support v-duplicate in this chip\n");
    }
    return FALSE;
#endif
}

MS_BOOL HAL_MVOP_GetVerDup(void)
{
    return (HAL_ReadRegBit(VOP_CTRL0, BIT3) == BIT3);
}

MS_BOOL HAL_MVOP_SetVerx4Dup(MS_BOOL bEnable)
{
    if (TRUE == bEnable)
    {
        MVOP_PRINTF("Not support v-duplicate in this chip\n");
    }
    // HAL_WriteRegBit(VOP_CTRL0, bEnable, BIT3);// x4 duplicate should raise V line duplicate first
    // HAL_WriteRegBit(VOP_RGB_FMT, bEnable, BIT3);// V line x4 duplicate
    return FALSE;
}

MS_BOOL HAL_MVOP_SetHorDup(MVOP_DevID eDevID, MS_BOOL bEnable)
{
    MS_BOOL bRet = TRUE;

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            // V line duplicate
            HAL_WriteRegBit(VOP_CTRL0, bEnable, BIT2);
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            // V line duplicate
            HAL_WriteRegBit(SUB_REG(VOP_CTRL0), bEnable, BIT2);
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            bRet = FALSE;
            break;
        }
    }
    return bRet;
}

MS_BOOL HAL_MVOP_SetHorx4Dup(MS_BOOL bEnable)
{
    HAL_WriteRegBit(VOP_CTRL0, bEnable, BIT2);// x4 duplicate should raise H pixel duplicate first
    HAL_WriteRegBit(VOP_RGB_FMT, bEnable, BIT2);// H line x4 duplicate
    return TRUE;
}

MS_BOOL HAL_MVOP_GetVerx4Dup(void)
{
    return ((HAL_ReadRegBit(VOP_RGB_FMT, BIT3) & HAL_ReadRegBit(VOP_CTRL0, BIT3)) == BIT3);
}

MS_BOOL HAL_MVOP_GetHorx4Dup(void)
{
    return ((HAL_ReadRegBit(VOP_RGB_FMT, BIT2) & HAL_ReadRegBit(VOP_CTRL0, BIT2)) == BIT2);
}

MS_U16 HAL_MVOP_GetTopVStart(MVOP_DevID eID)
{
    MS_U16 u16TopVStart = 0;
    switch (eID)
    {
        case E_MVOP_DEV_0:
            u16TopVStart = HAL_Read2Byte(VOP_IMG_VSTR0) & SizeMask;
            break;
        case E_MVOP_DEV_1:
#if MVOP_SUPPORT_SUB
            u16TopVStart = HAL_Read2Byte(SUB_REG(VOP_IMG_VSTR0)) & SizeMask;
#endif
            break;
        default:
            break;
    }
    return u16TopVStart;
}

MS_U16 HAL_MVOP_GetBottomVStart(MVOP_DevID eID)
{
    MS_U16 u16BotVStart = 0;
    switch (eID)
    {
        case E_MVOP_DEV_0:
            u16BotVStart = HAL_Read2Byte(VOP_IMG_VSTR1) & SizeMask;
            break;
        case E_MVOP_DEV_1:
#if MVOP_SUPPORT_SUB
            u16BotVStart = HAL_Read2Byte(SUB_REG(VOP_IMG_VSTR1)) & SizeMask;
#endif
            break;
        default:
            break;
    }
    return u16BotVStart;
}

MS_U16 HAL_MVOP_GetVCount(MVOP_DevID eID)
{
    MS_U16 u16VCount = 0;
    switch (eID)
    {
        case E_MVOP_DEV_0:
            u16VCount = HAL_Read2Byte(VOP_DEBUG_2A) & SizeMask;
            break;
        case E_MVOP_DEV_1:
#if MVOP_SUPPORT_SUB
            u16VCount = HAL_Read2Byte(SUB_REG(VOP_DEBUG_2A)) & SizeMask;
#endif
            break;
        default:
            break;
    }
    return u16VCount;
}

MS_BOOL HAL_MVOP_SetVC1RangeMap(MVOP_DevID eID, MVOP_VC1RangeMapInfo* stVC1RangeMapInfo)
{
    MS_U32 u8Luma = 0;
    MS_U32 u8Chroma = 0;

    if (stVC1RangeMapInfo == NULL)
    {
        MVOP_DBG(MVOP_PRINTF("%s stBaseAddInfo is NULL pointer\n", __FUNCTION__);)
        return FALSE;
    }

    // Luma value
    u8Luma = stVC1RangeMapInfo->u8LumaValue;
    // Chroma value
    u8Chroma = stVC1RangeMapInfo->u8ChromaValue;

    switch (eID)
    {
        case E_MVOP_DEV_0:
            //set VC1 Luma value
            if (stVC1RangeMapInfo->bIsEnableLuma)
            {
                HAL_WriteRegBit(VOP_RAMAP_LUMA, 1, BIT7);
                HAL_WriteByteMask(VOP_RAMAP_LUMA, u8Luma, VOP_RAMAP_LUMA_VAL);
            }
            else //disable
            {
                HAL_WriteRegBit(VOP_RAMAP_LUMA, 0, BIT7);
            }

            //set VC1 Chroma value
            if (stVC1RangeMapInfo->bIsEnableChroma)
            {
                HAL_WriteRegBit(VOP_RAMAP_CHROMA, 1, BIT7);
                HAL_WriteByteMask(VOP_RAMAP_CHROMA, u8Chroma, VOP_RAMAP_CHROMA_VAL);
            }
            else
            {
                HAL_WriteRegBit(VOP_RAMAP_CHROMA, 0, BIT7);
            }
            break;
        case E_MVOP_DEV_1:
#if MVOP_SUPPORT_SUB
            //set VC1 Luma value
            if (stVC1RangeMapInfo->bIsEnableLuma)
            {
                HAL_WriteRegBit(SUB_REG(VOP_RAMAP_LUMA), 1, BIT7);
                HAL_WriteByteMask(SUB_REG(VOP_RAMAP_LUMA), u8Luma, VOP_RAMAP_LUMA_VAL);
            }
            else //disable
            {
                HAL_WriteRegBit(SUB_REG(VOP_RAMAP_LUMA), 0, BIT7);
            }

            //set VC1 Chroma value
            if (stVC1RangeMapInfo->bIsEnableChroma)
            {
                HAL_WriteRegBit(SUB_REG(VOP_RAMAP_CHROMA), 1, BIT7);
                HAL_WriteByteMask(SUB_REG(VOP_RAMAP_CHROMA), u8Chroma, VOP_RAMAP_CHROMA_VAL);
            }
            else
            {
                HAL_WriteRegBit(SUB_REG(VOP_RAMAP_CHROMA), 0, BIT7);
            }
#endif
            break;
        default:
            break;
    }
    return TRUE;
}

MS_U16 g_u16SetStartX = 0;
MS_U16 g_u16SetStartY = 0;
MS_BOOL g_bIsY4Align = 0;

void HAL_MVOP_SetStartX(MVOP_DevID eID, MS_U16 u16XPos)
{
    if (g_pHalMVOPCtx == NULL)
    {
        MVOP_DBG(MVOP_PRINTF("%s g_pHalMVOPCtx is NULL pointer\n", __FUNCTION__);)
        return;
    }

    switch (eID)
    {
        case E_MVOP_DEV_0:
            u16XPos = ALIGN_DOWNTO_2(u16XPos);
            if (g_pHalMVOPCtx->bAV1_FG)
            {
                u16XPos |= BIT15;
            }
            HAL_Write2Byte(VOP_REG_CROP_HSTART, u16XPos);
            g_pHalMVOPCtx->u16CropXStart = u16XPos;
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_0);
            break;
        case E_MVOP_DEV_1:
#if MVOP_SUPPORT_SUB
            u16XPos = ALIGN_DOWNTO_2(u16XPos);
            // sub mvop not support fg
            HAL_WriteByte(SUB_REG(VOP_REG_CROP_HSTART), u16XPos & 0xff);
            HAL_WriteByte(SUB_REG((VOP_REG_CROP_HSTART + 1)), ((u16XPos) >> (8)) & (0x1f));
            g_pHalMVOPCtx->u16SubCropXStart = u16XPos;
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_1);
#endif
            break;
        default:
            break;
    }
}


void HAL_MVOP_SetStartY(MVOP_DevID eID, MS_U16 u16YPos, MS_BOOL bIsInterlace)
{
    if (g_pHalMVOPCtx == NULL)
    {
        MVOP_DBG(MVOP_PRINTF("%s g_pHalMVOPCtx is NULL pointer\n", __FUNCTION__);)
        return;
    }
    switch (eID)
    {
        case E_MVOP_DEV_0:
            g_pHalMVOPCtx->u16CropYStart = u16YPos;
            HAL_WriteByte(VOP_REG_CROP_VSTART, u16YPos & 0xff);
            HAL_WriteByte((VOP_REG_CROP_VSTART + 1), ((u16YPos) >> (8)) & (0x1f));
            HAL_WriteByteMask((VOP_REG_CROP_VSTART + 1), VOP_CROP_FIX_ODD | VOP_VCROP_EN | VOP_CROP_DB_BUF, VOP_CROP_FIX_ODD | VOP_VCROP_EN | VOP_CROP_DB_BUF);
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_0);
            break;
        case E_MVOP_DEV_1:
#if MVOP_SUPPORT_SUB
            g_pHalMVOPCtx->u16SubCropYStart = u16YPos;
            HAL_WriteByte(SUB_REG(VOP_REG_CROP_VSTART), u16YPos);
            HAL_WriteByte(SUB_REG(VOP_REG_CROP_VSTART + 1), ((u16YPos) >> (8)) & (0x1f));
            HAL_WriteByteMask(SUB_REG(VOP_REG_CROP_VSTART + 1), VOP_CROP_FIX_ODD | VOP_VCROP_EN | VOP_CROP_DB_BUF, VOP_CROP_FIX_ODD | VOP_VCROP_EN | VOP_CROP_DB_BUF);
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_1);
#endif
            break;
        default:
            break;
    }
}

void HAL_MVOP_SetPicWidthMinus(MVOP_DevID eID, MS_U16 u16XSizes, MS_U16 u16Width)
{
    MS_U16 u16Hsize = 0;
    MS_BOOL bisMfdecEnable = 0;
#if MFDEC_HCROP_ALIGN
    MS_BOOL bisMfdecCompressed = 0;
    MS_U16 u16XShift = 0;
#endif
#if MFDEC_HSIZE_LIMIT_PATCH
    EN_MVOP_Output_3D_TYPE en3DType = E_MVOP_OUTPUT_3D_NONE;
#endif

    if (g_pHalMVOPCtx == NULL)
    {
        MVOP_DBG(MVOP_PRINTF("%s g_pHalMVOPCtx is NULL pointer\n", __FUNCTION__);)
        return;
    }

    switch (eID)
    {
        case E_MVOP_DEV_0:
            u16Hsize = HAL_Read2Byte(VOP_JPG_HSIZE);
            u16XSizes = ALIGN_UPTO_2(u16XSizes);
#if GOP_BACKPORCH_PATCH
            //if dms use new vsync, dms can remove sw patch for cpu performance
            if (!g_pHalMVOPCtx->bIsUnComp)
            {
                //in conpress mode crop can not larger than original size.
                u16XSizes = (u16XSizes > u16Hsize) ? u16Hsize : u16XSizes;
            }
#endif
#if MFDEC_HSIZE_LIMIT_PATCH
            en3DType = HAL_MVOP_GetOutput3DType(E_MVOP_DEV_0);
            bisMfdecEnable = (HAL_ReadRegBit(VOP_REG_MFDEC_0_L, VOP_MFDEC_EN) == VOP_MFDEC_EN);
            if ((FALSE == bisMfdecEnable)
                && (u16XSizes > FHD_SRAM_SIZE)
                && (E_MVOP_OUTPUT_3D_NONE == en3DType)
                && (FALSE == g_pHalMVOPCtx->bIs422)
                && (E_MVOP_RGB_NONE == g_pHalMVOPCtx->eRgbFmt)
                && (FALSE == g_pHalMVOPCtx->bDramRdContd))
            {
                HAL_WriteRegBit(VOP_REG_MFDEC_0_L, TRUE, VOP_MFDEC_EN);
                HAL_WriteByteMask(VOP_REG_MFDEC_2_L, (TRUE << 4), VOP_UNCOMP_MODE);
            }
#endif
            /*
            * Outlook subject: MVOP av1 patch
            * SW patch for hsk + small size, actual size is captured by ip2.
            */
            if ((FALSE == MDrv_SYS_Query(E_SYS_QUERY_MVOP_MODE_SUPPORTED))
                && (TRUE == g_pHalMVOPCtx->bAV1_FG)
                && (TRUE == g_pHalMVOPCtx->bDS_EN)
                && (0 != u16XSizes))
            {
                u16XSizes += IP2_PATCH_HOFFSET;
            }
#if MFDEC_HCROP_ALIGN
            bisMfdecEnable = (HAL_ReadRegBit(VOP_REG_MFDEC_0_L, VOP_MFDEC_EN) == VOP_MFDEC_EN);
            bisMfdecCompressed = (HAL_ReadRegBit(VOP_REG_MFDEC_2_L, VOP_UNCOMP_MODE) == 0);
            u16XShift = u16XSizes + (g_pHalMVOPCtx->u16CropXStart % 32);
            if ((TRUE == bisMfdecEnable) && (TRUE == bisMfdecCompressed) && (u16XShift > FHD_SRAM_SIZE)
                    && ((u16XShift >= MFDEC_HCROP_ALIGN_0_START && u16XShift <= MFDEC_HCROP_ALIGN_0_END)
                        || (u16XShift >= MFDEC_HCROP_ALIGN_1_START && u16XShift <= MFDEC_HCROP_ALIGN_1_END)
                        || (u16XShift >= MFDEC_HCROP_ALIGN_2_START && u16XShift <= MFDEC_HCROP_ALIGN_2_END)
                        || (u16XShift >= MFDEC_HCROP_ALIGN_3_START && u16XShift <= MFDEC_HCROP_ALIGN_3_END)))
            {
                u16XSizes = ALIGN_UPTO_32(u16XShift) + 2;
            }
#endif
            // avoid hcrop size larger than hw limit
            u16XSizes = MIN(u16XSizes, MAX_HCROP);
            HAL_WriteByte(VOP_REG_CROP_HSIZE, u16XSizes & 0xff);
            HAL_WriteByte((VOP_REG_CROP_HSIZE + 1), ((u16XSizes) >> (8)) & (0x1f));
            g_pHalMVOPCtx->u16CropXSize = u16XSizes;
            if ((g_pHalMVOPCtx->bHSD) && (u16Hsize > u16XSizes))
            {
                HAL_MVOP_SetHSDIndex(E_MVOP_DEV_0, g_pHalMVOPCtx->bHSD, u16XSizes, g_pHalMVOPCtx->u16HSDOutput);
            }
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_0);
            break;
        case E_MVOP_DEV_1:
#if MVOP_SUPPORT_SUB
            u16Hsize = HAL_Read2Byte(SUB_REG(VOP_JPG_HSIZE));
            u16XSizes = ALIGN_UPTO_2(u16XSizes);
#if GOP_BACKPORCH_PATCH
            if (!g_pHalMVOPCtx->bSubIsUnComp)
            {
                //in conpress mode crop can not larger than original size.
                u16XSizes = (u16XSizes > u16Hsize) ? u16Hsize : u16XSizes;
            }
#endif
            if (u16XSizes > FHD_SRAM_SIZE)
            {
                MVOP_PRINTF("[Error] %s: Sub MVOP width should less than 2048\n", __FUNCTION__);
            }
            HAL_WriteByte(SUB_REG(VOP_REG_CROP_HSIZE), u16XSizes & 0xff);
            HAL_WriteByte(SUB_REG((VOP_REG_CROP_HSIZE + 1)), ((u16XSizes) >> (8)) & (0x1f));
            g_pHalMVOPCtx->u16SubCropXSize = u16XSizes;
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_1);
#endif
            break;
        default:
            break;
    }
    UNUSED(bisMfdecEnable);
    UNUSED(en3DType);
}

void HAL_MVOP_SetPicHeightMinus(MVOP_DevID eID, MS_U16 u16YSizes, MS_U16 u16Height)
{
    MS_U16 u16Vsize = 0;

    if (g_pHalMVOPCtx == NULL)
    {
        MVOP_DBG(MVOP_PRINTF("%s g_pHalMVOPCtx is NULL pointer\n", __FUNCTION__);)
        return;
    }

    switch (eID)
    {
        case E_MVOP_DEV_0:
            u16Vsize = HAL_Read2Byte(VOP_JPG_VSIZE);
#if 0 //dms mvc set one view size, m7322 default dms control.
            //en3DType = HAL_MVOP_GetOutput3DType(E_MVOP_DEV_0);
            MVOP_DBG(MVOP_PRINTF("[MVOP][DBG] 3D FORMAT = %d\n", en3DType);)
            if ((en3DType == E_MVOP_OUTPUT_3D_TB) || (en3DType == E_MVOP_OUTPUT_3D_LA) || (g_pHalMVOPCtx->eInterlaceType == E_MVOP_INT_TB_SEP_FRAME))
            {
                u16YSizes = u16YSizes >> 1;
            }
#endif
            if (g_pHalMVOPCtx->eInterlaceType == E_MVOP_INT_TB_SEP_FRAME)
            {
                u16YSizes = u16YSizes >> 1;
            }
            //use up align, crop by xc capture(M7332/M7632/M7642 can capture in hsk)avoid missing data.
            if (g_pHalMVOPCtx->eInterlaceType > E_MVOP_PRO)
            {
                u16YSizes = ALIGN_UPTO_4(u16YSizes);
            }
            else
            {
                u16YSizes = ALIGN_UPTO_2(u16YSizes);
            }
#if GOP_BACKPORCH_PATCH
            //if dms use new vsync, dms can remove sw patch for cpu performance
            if (!g_pHalMVOPCtx->bIsUnComp)
            {
                //in conpress mode crop can not larger than original size.
                u16YSizes = (u16YSizes > u16Vsize) ? u16Vsize : u16YSizes;
            }
#endif
            HAL_WriteByte(VOP_REG_CROP_VSIZE, (u16YSizes) & 0xff);
            HAL_WriteByte((VOP_REG_CROP_VSIZE + 1), ((u16YSizes) >> (8)) & (0x1f));
            g_pHalMVOPCtx->u16CropYSize = u16YSizes;
            if ((0 == g_pHalMVOPCtx->u16CropXSize) || (0 == g_pHalMVOPCtx->u16CropYSize))
            {
                //M7622 if crop = 0, 0x41[14] = 0 for 10 bits mirror.
                HAL_WriteByteMask((VOP_REG_CROP_VSTART + 1), 0, VOP_VCROP_EN);
            }
            else
            {
                HAL_WriteByteMask((VOP_REG_CROP_VSTART + 1), VOP_VCROP_EN, VOP_VCROP_EN);
            }
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_0);
            break;
        case E_MVOP_DEV_1:
#if MVOP_SUPPORT_SUB
            u16Vsize = HAL_Read2Byte(SUB_REG(VOP_JPG_VSIZE));
#if 0 //dms mvc set one view size
            //en3DType = HAL_MVOP_GetOutput3DType(E_MVOP_DEV_1);
            MVOP_DBG(MVOP_PRINTF("[MVOP][DBG] 3D FORMAT = %d\n", en3DType);)
            if ((en3DType == E_MVOP_OUTPUT_3D_TB) || (en3DType == E_MVOP_OUTPUT_3D_LA) || (g_pHalMVOPCtx->eSubInterlaceType == E_MVOP_INT_TB_SEP_FRAME))
            {
                u16YSizes = u16YSizes >> 1;
            }
#endif
            if (g_pHalMVOPCtx->eSubInterlaceType == E_MVOP_INT_TB_SEP_FRAME)
            {
                u16YSizes = u16YSizes >> 1;
            }
            if (g_pHalMVOPCtx->eSubInterlaceType > E_MVOP_PRO)
            {
                u16YSizes = ALIGN_DOWNTO_4(u16YSizes);
            }
            else
            {
                u16YSizes = ALIGN_DOWNTO_2(u16YSizes);
            }
#if GOP_BACKPORCH_PATCH
            if (!g_pHalMVOPCtx->bSubIsUnComp)
            {
                //in conpress mode crop can not larger than original size.
                u16YSizes = (u16YSizes > u16Vsize) ? u16Vsize : u16YSizes;
            }
#endif
            HAL_WriteByte(SUB_REG(VOP_REG_CROP_VSIZE), (u16YSizes) & 0xff);
            HAL_WriteByte(SUB_REG((VOP_REG_CROP_VSIZE + 1)), ((u16YSizes) >> (8)) & (0x1f));
            g_pHalMVOPCtx->u16SubCropYSize = u16YSizes;
            if ((0 == g_pHalMVOPCtx->u16SubCropXSize) || (0 == g_pHalMVOPCtx->u16SubCropYSize))
            {
                HAL_WriteByteMask(SUB_REG(VOP_REG_CROP_VSTART + 1), 0, VOP_VCROP_EN);
            }
            else
            {
                HAL_WriteByteMask(SUB_REG(VOP_REG_CROP_VSTART + 1), VOP_VCROP_EN, VOP_VCROP_EN);
            }
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_1);
#endif
            break;
        default:
            break;
    }
}

/******************************************************************************/
/// Set MVOP Saving BW Mode
/// @ Napoli this command should be set after MDrv_MVOP_SetOutputCfg
/******************************************************************************/
MS_BOOL HAL_MVOP_Set420BWSaveMode(MVOP_DevID eDevID, MS_BOOL bEnable)
{
    MS_BOOL bRet = FALSE;
    MS_BOOL bValue = FALSE;

    if (NULL == g_pHalMVOPCtx)
    {
        MVOP_DBG(MVOP_PRINTF("%s g_pHalMVOPCtx is NULL pointer\n",
                             __FUNCTION__);)
        return bRet;
    }

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            /* HW limtation: 3DLA/3DSBS/422 */
            bValue = ((TRUE == g_pHalMVOPCtx->b3DLRAltSBSOutput)
                || (TRUE == g_pHalMVOPCtx->b3DLRAltOutput)
                /*|| g_pHalMVOPCtx->b3DLRMode */
                || (TRUE == g_pHalMVOPCtx->bIs422));

            if (TRUE == bValue)
            {
                MVOP_DBG(MVOP_PRINTF("%s Hit the limitation of saving bw, "
                                     "disable BW Saving mode\n", __FUNCTION__);)
                HAL_WriteRegBit(VOP_REG_DUMMY, 0, VOP_420_BW_SAVE);
                HAL_WriteRegBit(VOP_REG_BW_SAVE, 0, VOP_420_BW_SAVE_EX);
            }
            else
            {
                HAL_WriteRegBit(VOP_REG_DUMMY, bEnable, VOP_420_BW_SAVE);
                if (FALSE == g_pHalMVOPCtx->b3DLRMode)
                {
                    HAL_WriteRegBit(VOP_REG_BW_SAVE, bEnable,
                                    VOP_420_BW_SAVE_EX);
                }
                else
                {
                    HAL_WriteRegBit(VOP_REG_BW_SAVE, 0, VOP_420_BW_SAVE_EX);
                }
                bRet = TRUE;
            }
            HAL_MVOP_LoadReg(E_MVOP_DEV_0);
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_0);
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            /* HW limtation: 3DLA/3DSBS/422 */
            bValue = ((TRUE == g_pHalMVOPCtx->bSub3DLRAltSBSOutput)
                || (TRUE == g_pHalMVOPCtx->bSub3DLRAltOutput)
                /*|| g_pHalMVOPCtx->bSub3DLRMode*/
                || (TRUE == g_pHalMVOPCtx->bSubIs422));

            if (TRUE == bValue)
            {
                MVOP_DBG(MVOP_PRINTF("%s Hit the limitation of saving bw, "
                                     "disable BW Saving mode\n", __FUNCTION__);)
                HAL_WriteRegBit(SUB_REG(VOP_REG_DUMMY), 0, VOP_420_BW_SAVE);
                HAL_WriteRegBit(SUB_REG(VOP_REG_BW_SAVE), 0,
                                VOP_420_BW_SAVE_EX);
            }
            else
            {
                HAL_WriteRegBit(SUB_REG(VOP_REG_DUMMY), bEnable,
                                VOP_420_BW_SAVE);
                if (FALSE == g_pHalMVOPCtx->bSub3DLRMode)
                {
                    HAL_WriteRegBit(SUB_REG(VOP_REG_BW_SAVE), bEnable,
                                    VOP_420_BW_SAVE_EX);
                }
                else
                {
                    HAL_WriteRegBit(SUB_REG(VOP_REG_BW_SAVE), 0,
                                    VOP_420_BW_SAVE_EX);
                }
                bRet = TRUE;
            }
            HAL_MVOP_LoadReg(E_MVOP_DEV_1);
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_1);
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID = %u\n", __FUNCTION__,
                        eDevID);
            break;
        }
    }
    return bRet;
}

MS_BOOL HAL_MVOP_SetEVDYUVBaseAdd(MVOP_DevID eDevID, MVOP_EVDBaseAddInput* stEVDBaseAddInfo, MS_BOOL bMFEnable)
{
    MS_BOOL bRet = FALSE;
    MS_PHY u64tmp = 0;
#if IOMMU_MFDEC_CTRL
    MS_U8 u8LumaOffset = 0;
    MS_U8 u8ChromaOffset = 0;
#endif

    if (g_pHalMVOPCtx == NULL)
    {
        MVOP_DBG(MVOP_PRINTF("%s g_pHalMVOPCtx is NULL pointer\n", __FUNCTION__);)
        return bRet;
    }

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            if (!g_pHalMVOPCtx->bForceP)
            {
                if (g_pHalMVOPCtx->u32DC0FrmCnt < 0xffffffff)
                {
                    g_pHalMVOPCtx->u32DC0FrmCnt++;
                }
            }
            //----------------------------------------------------
            // Set MSB YUV Address
            //----------------------------------------------------
            u64tmp = stEVDBaseAddInfo->u32MSBYOffset >> 3;

            if (!stEVDBaseAddInfo->bProgressive)
            {
                //Refine Y offset for interlace repeat bottom field
                if (E_MVOP_RPTFLD_BOT == g_pHalMVOPCtx->eRepeatField)
                {
                    MVOP_DBG("%d eRepeatField(%x) is bottom!\n", __LINE__, g_pHalMVOPCtx->eRepeatField);
                    u64tmp += 2;
                }
                else
                {
                    MVOP_DBG("%d eRepeatField(%x) is TOP or NONE.\n", __LINE__, g_pHalMVOPCtx->eRepeatField);
                }
            }
            HAL_WriteByte(VOP_JPG_YSTR0_L, u64tmp & 0xff);
            HAL_WriteByte((VOP_JPG_YSTR0_L + 1), (u64tmp >> 8) & 0xff);
            HAL_WriteByte((VOP_JPG_YSTR0_H), (u64tmp >> 16) & 0xff);
            HAL_WriteByte((VOP_JPG_YSTR0_H + 1), (u64tmp >> 24) & VOP_YUV_STR_HIBITS);
#if IOMMU_MFDEC_CTRL
            if ((MS_U64)stEVDBaseAddInfo->u32MSBYOffset > ADDRESS_4GB)
            {
                u8LumaOffset = (MS_U8)(stEVDBaseAddInfo->u32MSBYOffset >> 30);
                HAL_WriteByteMask(REG_MVOP_DMA_REQ_LEN_L, u8LumaOffset, MVOP_LUMA_OFFSET);
            }
#endif

            if (stEVDBaseAddInfo->b422Pack)
            {
                stEVDBaseAddInfo->u32MSBUVOffset = stEVDBaseAddInfo->u32MSBYOffset + 16; //add 16 for 128bit; add 8 for 64bit
            }
            u64tmp = stEVDBaseAddInfo->u32MSBUVOffset >> 3;
            if (!stEVDBaseAddInfo->bProgressive)
            {
                //Refine UV offset for interlace repeat bottom field
                if (E_MVOP_RPTFLD_BOT == g_pHalMVOPCtx->eRepeatField)
                {
                    MVOP_DBG("%d eRepeatField(%x) is bottom!\n", __LINE__, g_pHalMVOPCtx->eRepeatField);
                    u64tmp += 2;
                }
                else
                {
                    MVOP_DBG("%d eRepeatField(%x) is TOP/NONE.\n", __LINE__, g_pHalMVOPCtx->eRepeatField);
                }
            }
            HAL_WriteByte(VOP_JPG_UVSTR0_L, u64tmp & 0xff);
            HAL_WriteByte((VOP_JPG_UVSTR0_L + 1), (u64tmp >> 8) & 0xff);
            HAL_WriteByte((VOP_JPG_UVSTR0_H), (u64tmp >> 16) & 0xff);
            HAL_WriteByte((VOP_JPG_UVSTR0_H + 1), (u64tmp >> 24) & VOP_YUV_STR_HIBITS);
#if IOMMU_MFDEC_CTRL
            if ((MS_U64)stEVDBaseAddInfo->u32MSBUVOffset > ADDRESS_4GB)
            {
                u8ChromaOffset = (MS_U8)(stEVDBaseAddInfo->u32MSBUVOffset >> 30);
                HAL_WriteByteMask(REG_MVOP_DMA_REQ_LEN_L, (u8ChromaOffset << 4), MVOP_CHROMA_OFFSET);
            }
#endif
            //----------------------------------------------------
            // Set LSB YUV Address
            //----------------------------------------------------
            g_pHalMVOPCtx->bIsEnLSB = stEVDBaseAddInfo->bEnLSB;
            if (stEVDBaseAddInfo->bEnLSB)
            {
                //Enable LSB
                HAL_WriteRegBit(VOP_REG_MASK, 0, VOP_LSB_REQ_MASK);
                if ((FALSE == bMFEnable) && (g_pHalMVOPCtx->eTileFormat != E_MVOP_TILE_COMP_4x2))
                {
                    HAL_WriteRegBit(VOP_REG_DUMMY, TRUE, VOP_420_BW_SAVE);
                    HAL_WriteRegBit(VOP_INPUT_SWITCH0, TRUE, VOP_NEW_EVD_EN);
                }
                //new 10 bits mode
                stEVDBaseAddInfo->u32LSBYOffset = stEVDBaseAddInfo->u32MSBYOffset;
                stEVDBaseAddInfo->u32LSBUVOffset = stEVDBaseAddInfo->u32MSBUVOffset;

                u64tmp = stEVDBaseAddInfo->u32LSBYOffset >> 3;
                if (!stEVDBaseAddInfo->bProgressive)
                {
                    //Refine Y offset for interlace repeat bottom field
                    if (E_MVOP_RPTFLD_BOT == g_pHalMVOPCtx->eRepeatField)
                    {
                        MVOP_DBG("%d eRepeatField(%x) is bottom!\n", __LINE__, g_pHalMVOPCtx->eRepeatField);
                        u64tmp += 2;
                    }
                    else
                    {
                        MVOP_DBG("%d eRepeatField(%x) is TOP or NONE.\n", __LINE__, g_pHalMVOPCtx->eRepeatField);
                    }
                }
                HAL_WriteByte(VOP_LSB_YSTR0_L, u64tmp & 0xff);
                HAL_WriteByte((VOP_LSB_YSTR0_L + 1), (u64tmp >> 8) & 0xff);
                HAL_WriteByte((VOP_LSB_YSTR0_H), (u64tmp >> 16) & 0xff);
                HAL_WriteByte((VOP_LSB_YSTR0_H + 1), (u64tmp >> 24) & VOP_YUV_STR_HIBITS);
                if (stEVDBaseAddInfo->b422Pack)
                {
                    stEVDBaseAddInfo->u32LSBUVOffset = stEVDBaseAddInfo->u32LSBYOffset + 16; //add 16 for 128bit; add 8 for 64bit
                }

                u64tmp = stEVDBaseAddInfo->u32LSBUVOffset >> 3;
                if (!stEVDBaseAddInfo->bProgressive)
                {
                    //Refine UV offset for interlace repeat bottom field
                    if (E_MVOP_RPTFLD_BOT == g_pHalMVOPCtx->eRepeatField)
                    {
                        MVOP_DBG("%d eRepeatField(%x) is bottom!\n", __LINE__, g_pHalMVOPCtx->eRepeatField);
                        u64tmp += 2;
                    }
                    else
                    {
                        MVOP_DBG("%d eRepeatField(%x) is TOP/NONE.\n", __LINE__, g_pHalMVOPCtx->eRepeatField);
                    }
                }
                HAL_WriteByte(VOP_LSB_UVSTR0_L, u64tmp & 0xff);
                HAL_WriteByte((VOP_LSB_UVSTR0_L + 1), (u64tmp >> 8) & 0xff);
                HAL_WriteByte((VOP_LSB_UVSTR0_H), (u64tmp >> 16) & 0xff);
                HAL_WriteByte((VOP_LSB_UVSTR0_H + 1), (u64tmp >> 24) & VOP_YUV_STR_HIBITS);

            }
            else
            {
                //Disable LSB: for miu select
                HAL_WriteByteMask(VOP_REG_MASK, 0X3, VOP_LSB_REQ_MASK);
                HAL_WriteRegBit(VOP_INPUT_SWITCH0, FALSE, VOP_NEW_EVD_EN);
            }

            // If g_pHalMVOPCtx->eTileFormat has not been setup yet
            // VOP_EVD_10B_EN will be fired again at SetStreamInfo
            if (g_pHalMVOPCtx->bIsEnLSB || (g_pHalMVOPCtx->eTileFormat == E_MVOP_TILE_COMP_4x2))
            {
                HAL_WriteRegBit(VOP_EVD_10B_EN, 1, VOP_EVD_10B_Y_EN);
                HAL_WriteRegBit(VOP_EVD_10B_EN, 1, VOP_EVD_10B_UV_EN);
            }
            else
            {
                HAL_WriteRegBit(VOP_EVD_10B_EN, 0, VOP_EVD_10B_Y_EN);
                HAL_WriteRegBit(VOP_EVD_10B_EN, 0, VOP_EVD_10B_UV_EN);
            }
            bRet = TRUE;
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            //----------------------------------------------------
            // Set MSB YUV Address
            //----------------------------------------------------
            if (!g_pHalMVOPCtx->bSubForceP)
            {
                if (g_pHalMVOPCtx->u32DC1FrmCnt < 0xffffffff)
                {
                    g_pHalMVOPCtx->u32DC1FrmCnt++;
                }
            }
            // Y offset
            u64tmp = stEVDBaseAddInfo->u32MSBYOffset >> 3;

            if (!stEVDBaseAddInfo->bProgressive)
            {
                //Refine Y offset for interlace repeat bottom field
                if (E_MVOP_RPTFLD_BOT == g_pHalMVOPCtx->eRepeatField)
                {
                    MVOP_DBG("%d eRepeatField(%x) is bottom!\n", __LINE__, g_pHalMVOPCtx->eRepeatField);
                    u64tmp += 2;
                }
                else
                {
                    MVOP_DBG("%d eRepeatField(%x) is TOP or NONE.\n", __LINE__, g_pHalMVOPCtx->eRepeatField);
                }
            }
            HAL_WriteByte(SUB_REG(VOP_JPG_YSTR0_L), u64tmp & 0xff);
            HAL_WriteByte(SUB_REG(VOP_JPG_YSTR0_L + 1), (u64tmp >> 8) & 0xff);
            HAL_WriteByte(SUB_REG(VOP_JPG_YSTR0_H), (u64tmp >> 16) & 0xff);
            HAL_WriteByte(SUB_REG(VOP_JPG_YSTR0_H + 1), (u64tmp >> 24) & VOP_YUV_STR_HIBITS);

            if (stEVDBaseAddInfo->b422Pack)
            {
                stEVDBaseAddInfo->u32MSBUVOffset = stEVDBaseAddInfo->u32MSBYOffset + 16; //add 16 for 128bit; add 8 for 64bit
            }
            // UV offset
            u64tmp = stEVDBaseAddInfo->u32MSBUVOffset >> 3;
            if (!stEVDBaseAddInfo->bProgressive)
            {
                //Refine UV offset for interlace repeat bottom field
                if (E_MVOP_RPTFLD_BOT == g_pHalMVOPCtx->eRepeatField)
                {
                    MVOP_DBG("%d eRepeatField(%x) is bottom!\n", __LINE__, g_pHalMVOPCtx->eRepeatField);
                    u64tmp += 2;
                }
                else
                {
                    MVOP_DBG("%d eRepeatField(%x) is TOP/NONE.\n", __LINE__, g_pHalMVOPCtx->eRepeatField);
                }
            }
            HAL_WriteByte(SUB_REG(VOP_JPG_UVSTR0_L), u64tmp & 0xff);
            HAL_WriteByte(SUB_REG(VOP_JPG_UVSTR0_L + 1), (u64tmp >> 8) & 0xff);
            HAL_WriteByte(SUB_REG(VOP_JPG_UVSTR0_H), (u64tmp >> 16) & 0xff);
            HAL_WriteByte(SUB_REG(VOP_JPG_UVSTR0_H + 1), (u64tmp >> 24) & VOP_YUV_STR_HIBITS);
            //----------------------------------------------------
            // Set MSB YUV Address
            //----------------------------------------------------
            g_pHalMVOPCtx->bSubIsEnLSB = stEVDBaseAddInfo->bEnLSB;
            if (stEVDBaseAddInfo->bEnLSB)
            {
                //Enable LSB
                HAL_WriteRegBit(SUB_REG(VOP_REG_MASK), 0, VOP_LSB_REQ_MASK);
                if ((FALSE == bMFEnable) && (g_pHalMVOPCtx->eSubTileFormat != E_MVOP_TILE_COMP_4x2))
                {
                    HAL_WriteRegBit(SUB_REG(VOP_REG_DUMMY), TRUE, VOP_420_BW_SAVE);
                    HAL_WriteRegBit(SUB_REG(VOP_INPUT_SWITCH0), TRUE, VOP_NEW_EVD_EN);
                }
                //new 10 bits mode
                stEVDBaseAddInfo->u32LSBYOffset = stEVDBaseAddInfo->u32MSBYOffset;
                stEVDBaseAddInfo->u32LSBUVOffset = stEVDBaseAddInfo->u32MSBUVOffset;

                // Y offset
                u64tmp = stEVDBaseAddInfo->u32LSBYOffset >> 3;
                if (!stEVDBaseAddInfo->bProgressive)
                {
                    //Refine Y offset for interlace repeat bottom field
                    if (E_MVOP_RPTFLD_BOT == g_pHalMVOPCtx->eRepeatField)
                    {
                        MVOP_DBG("%d eRepeatField(%x) is bottom!\n", __LINE__, g_pHalMVOPCtx->eRepeatField);
                        u64tmp += 2;
                    }
                    else
                    {
                        MVOP_DBG("%d eRepeatField(%x) is TOP or NONE.\n", __LINE__, g_pHalMVOPCtx->eRepeatField);
                    }
                }
                HAL_WriteByte(SUB_REG(VOP_LSB_YSTR0_L), u64tmp & 0xff);
                HAL_WriteByte(SUB_REG(VOP_LSB_YSTR0_L + 1), (u64tmp >> 8) & 0xff);
                HAL_WriteByte(SUB_REG(VOP_LSB_YSTR0_H), (u64tmp >> 16) & 0xff);
                HAL_WriteByte(SUB_REG(VOP_LSB_YSTR0_H + 1), (u64tmp >> 24) & VOP_YUV_STR_HIBITS);

                if (stEVDBaseAddInfo->b422Pack)
                {
                    stEVDBaseAddInfo->u32LSBUVOffset = stEVDBaseAddInfo->u32LSBYOffset + 16; //add 16 for 128bit; add 8 for 64bit
                }
                // UV offset
                u64tmp = stEVDBaseAddInfo->u32LSBUVOffset >> 3;
                if (!stEVDBaseAddInfo->bProgressive)
                {
                    //Refine UV offset for interlace repeat bottom field
                    if (E_MVOP_RPTFLD_BOT == g_pHalMVOPCtx->eRepeatField)
                    {
                        MVOP_DBG("%d eRepeatField(%x) is bottom!\n", __LINE__, g_pHalMVOPCtx->eRepeatField);
                        u64tmp += 2;
                    }
                    else
                    {
                        MVOP_DBG("%d eRepeatField(%x) is TOP/NONE.\n", __LINE__, g_pHalMVOPCtx->eRepeatField);
                    }
                }
                HAL_WriteByte(SUB_REG(VOP_LSB_UVSTR0_L), u64tmp & 0xff);
                HAL_WriteByte(SUB_REG(VOP_LSB_UVSTR0_L + 1), (u64tmp >> 8) & 0xff);
                HAL_WriteByte(SUB_REG(VOP_LSB_UVSTR0_H), (u64tmp >> 16) & 0xff);
                HAL_WriteByte(SUB_REG(VOP_LSB_UVSTR0_H + 1), (u64tmp >> 24) & VOP_YUV_STR_HIBITS);
            }
            else
            {
                //Disable LSB: for miu select
                HAL_WriteRegBit(SUB_REG(VOP_REG_MASK), 1, VOP_LSB_REQ_MASK);
                HAL_WriteRegBit(SUB_REG(VOP_INPUT_SWITCH0), 0, VOP_NEW_EVD_EN);
            }

            // If g_pHalMVOPCtx->eSubTileFormat has not been setup yet
            // VOP_EVD_10B_EN will be fired at SetStreamInfo
            if (g_pHalMVOPCtx->bSubIsEnLSB || (g_pHalMVOPCtx->eSubTileFormat == E_MVOP_TILE_COMP_4x2))
            {
                HAL_WriteRegBit(SUB_REG(VOP_EVD_10B_EN), 1, VOP_EVD_10B_Y_EN);
                HAL_WriteRegBit(SUB_REG(VOP_EVD_10B_EN), 1, VOP_EVD_10B_UV_EN);
            }
            else
            {
                HAL_WriteRegBit(SUB_REG(VOP_EVD_10B_EN), 0, VOP_EVD_10B_Y_EN);
                HAL_WriteRegBit(SUB_REG(VOP_EVD_10B_EN), 0, VOP_EVD_10B_UV_EN);
            }
            bRet = TRUE;
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
    HAL_MVOP_ForceWriteReg(eDevID);
    return bRet;
}

/******************************************************************************/
/// Set MVOP repeat previous frame IF VDEC can not finish vsync.
/// this command should be set disable as call VDEC Exit.
/******************************************************************************/
void HAL_MVOP_SetRptPreVsyncFrame(MVOP_DevID eID, MS_BOOL bEnable)
{
    switch (eID)
    {
        case E_MVOP_DEV_0:
        {
            g_pHalMVOPCtx->bRptPreVsync = bEnable;
            HAL_WriteRegBit(VOP_MIRROR_CFG_HI, bEnable, BIT3);
            break;
        }
        case E_MVOP_DEV_1:
        {
#if MVOP_SUPPORT_SUB
            g_pHalMVOPCtx->bSubRptPreVsync = bEnable;
            HAL_WriteRegBit(SUB_REG(VOP_MIRROR_CFG_HI), bEnable, BIT3);
#endif
            break;
        }
        default:
            MVOP_PRINTF("[Warning] MVOP_DevID not support!\n");
            break;
    }
}

void HAL_MVOP_PowerStateSuspend(void)
{
    g_pHalMVOPCtx->bIsInit = 0;
#if MVOP_SUPPORT_SUB
    g_pHalMVOPCtx->bSubIsInit = 0;
#endif
}

MVOP_HSMode HAL_MVOP_GetHandShakeMode(MVOP_DevID eID)
{
    MVOP_HSMode eRet = E_MVOP_HS_NOT_SUPPORT;

    switch (eID)
    {
        case E_MVOP_DEV_0:
        {
            if (HAL_ReadRegBit(VOP_REG_HS_OUTPUT, VOP_HS_MODE))
            {
                eRet = E_MVOP_HS_ENABLE;
            }
            else
            {
                eRet = E_MVOP_HS_DISABLE;
            }
            break;
        }
        case E_MVOP_DEV_1:
        {
#if MVOP_SUPPORT_SUB
            if (HAL_ReadRegBit(SUB_REG(VOP_REG_HS_OUTPUT), VOP_HS_MODE))
            {
                eRet = E_MVOP_HS_ENABLE;
            }
            else
            {
                eRet = E_MVOP_HS_DISABLE;
            }
#endif
            break;
        }
        default:
            eRet = E_MVOP_HS_INVALID_PARAM;
            break;
    }
    return eRet;
}

MS_BOOL HAL_MVOP_CheckSTCCW(MVOP_DevID eDevID)
{
    MS_BOOL bRet = TRUE;
    MS_U16 u16STC_CW_L = 0;
    MS_U16 u16STC_CW_H = 0;
    MS_BOOL u16STC_CW_SEL = 0;
    MS_BOOL u16TSP_CLK_EN = 0;

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            u16STC_CW_L = HAL_Read2Byte(REG_STC0_CW_L) & 0xffff;
            u16STC_CW_H = HAL_Read2Byte(REG_STC0_CW_H) & 0xffff;
            u16STC_CW_SEL = (HAL_ReadRegBit(REG_STC_CW_SLE_L, BIT1) == BIT1);
            u16TSP_CLK_EN = !(HAL_ReadRegBit(REG_TSP_CLK, BIT0) == BIT0);
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            u16STC_CW_L = HAL_Read2Byte(REG_STC1_CW_L) & 0xffff;
            u16STC_CW_H = HAL_Read2Byte(REG_STC1_CW_H) & 0xffff;
            u16STC_CW_SEL = (HAL_ReadRegBit(REG_STC_CW_SLE_H, BIT1) == BIT1);
            u16TSP_CLK_EN = !(HAL_ReadRegBit(REG_TSP_CLK, BIT0) == BIT0);
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            bRet = FALSE;
            break;
        }
    }

    if ((((u16STC_CW_L || u16STC_CW_H) == 0) && (u16STC_CW_SEL == 0)) || ((u16STC_CW_SEL == 1) && (u16TSP_CLK_EN == 0)))
    {
        bRet = FALSE;
    }
    return bRet;
}

#define MIU1_REG_BASE       0x0600
MS_BOOL HAL_MVOP_GetIsMiuIPControl(HALMVOPMIUCLIENTINFO stInfo)
{
    MS_U32 u32RegMiu = 0;
    MS_U16 u16Mask = 0;
    MS_BOOL bRet = FALSE;

    u32RegMiu = MIU1_REG_BASE + (0xF0 + (stInfo.u8Gp * 2));
    if (stInfo.u8BitPos < 8)
    {
        u16Mask = 1 << stInfo.u8BitPos;
    }
    else
    {
        u16Mask = 1 << (stInfo.u8BitPos - 8);
        u32RegMiu += 1;
    }
    MVOP_DBG(MVOP_PRINTF("[%s] u32RegMiu = 0x%lx, u16Mask = 0x%x\n", __FUNCTION__, u32RegMiu, u16Mask);)
    if (HAL_ReadRegBit(u32RegMiu, u16Mask))
    {
        bRet = TRUE;
    }

    return bRet;
}

void HAL_MVOP_SelMIU(MVOP_DevID eDevID, HALMVOPMIUSEL eMiuMSB0, HALMVOPMIUSEL eMiuMSB1, HALMVOPMIUSEL eMiuLSB0, HALMVOPMIUSEL eMiuLSB1)
{
    MS_U8 u8MSBVlue = 0;
    MS_U8 u8LSBVlue = 0;
#if 0
    //Only 7221, Murphy default set y:miu0 uv:miu1, for iommu setting
    eMiuMSB0 = E_MVOP_SEL_MIU0;
    eMiuMSB1 = E_MVOP_SEL_MIU1;
    eMiuLSB0 = E_MVOP_SEL_MIU0;
    eMiuMSB1 = E_MVOP_SEL_MIU1;
#else
    if (eMiuMSB0 != eMiuMSB1)
        HAL_WriteRegBit(VOP_MIU_SEL, TRUE, BIT0);
    else
        HAL_WriteRegBit(VOP_MIU_SEL, FALSE, BIT0);

    if (eMiuLSB0 != eMiuLSB1)
        HAL_WriteRegBit(VOP_MIU_SEL, TRUE, BIT1);
    else
        HAL_WriteRegBit(VOP_MIU_SEL, FALSE, BIT1);
#endif

    u8MSBVlue |= (eMiuMSB0 << 4);
    u8MSBVlue |= (eMiuMSB1 << 6);

    u8LSBVlue |= (eMiuLSB0 << 4);
    u8LSBVlue |= (eMiuLSB1 << 6);

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            // MSB
            HAL_WriteByteMask(VOP_MIU_SEL, u8MSBVlue, VOP_MSB_BUF0_MIU_SEL | VOP_MSB_BUF1_MIU_SEL);
            // LSB
            HAL_WriteByteMask(VOP_MIU_SEL_LSB, u8LSBVlue, VOP_LSB_BUF0_MIU_SEL | VOP_LSB_BUF1_MIU_SEL);
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_0);
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            // MSB
            HAL_WriteByteMask(SUB_REG(VOP_MIU_SEL), u8MSBVlue, VOP_MSB_BUF0_MIU_SEL | VOP_MSB_BUF1_MIU_SEL);
            // LSB
            HAL_WriteByteMask(SUB_REG(VOP_MIU_SEL_LSB), u8LSBVlue, VOP_LSB_BUF0_MIU_SEL | VOP_LSB_BUF1_MIU_SEL);
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_1);
            break;
        }
#endif
        default:
            break;
    }
}

EN_MVOP_MIU_SEL HAL_MVOP_GetIsOnlyMiuIPControl(void)
{
    return E_HW_CTL_MIU;
}

void HAL_MVOP_GetMaxFramerate(MVOP_DevID eDevID, MVOP_GetMaxFps* stStreamInfo)
{
    MS_U64 u64MaxClk = 0;
    MS_U16 u16HsizeTiming = 0;
    MS_U16 u16VsizeTiming = 0;

    if (NULL == stStreamInfo)
    {
        MVOP_PRINTF("[%s] Input parameter is NULL!\n", __FUNCTION__);
        return;
    }

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
#endif
            {
                if (TRUE == HAL_MVOP_IsSupport2PMode(eDevID))
                {
                    u16HsizeTiming = stStreamInfo->u16HSize >> 1;
                }
                else
                {
                    u16HsizeTiming = stStreamInfo->u16HSize;
                    u16HsizeTiming = ALIGN_UPTO_2(u16HsizeTiming);
                }
                if (stStreamInfo->b3DSBS)
                {
                    u16HsizeTiming *= 2;
                }
                if (stStreamInfo->u16HSize > 720)
                {
                    u16HsizeTiming +=  MVOP_HBlank_HD;
                }
                else
                {
                    u16HsizeTiming +=  MVOP_HBlank_SD;
                }

                u64MaxClk = HAL_MVOP_GetHardwareClock(eDevID, HAL_MVOP_GetMaximumClk(eDevID));
                if (stStreamInfo->b3DTB)
                {
                    u16VsizeTiming = stStreamInfo->u16VSize * 2 + MVOP_VBlank;
                }
                else
                {
                    u16VsizeTiming = stStreamInfo->u16VSize + MVOP_VBlank;
                }
                do_div(u64MaxClk, u16HsizeTiming);
                do_div(u64MaxClk, u16VsizeTiming);
                stStreamInfo->u32Framerate = (MS_U32)u64MaxClk * 1000;
            }
            break;
        default:
            break;
    }

}

void HAL_MVOP_ResetReg(MVOP_DevID eDevID)
{
    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
#if ENABLE_3D_LR_MODE
            HAL_MVOP_Enable3DLR(E_MVOP_DEV_0, DISABLE);
#endif
#if SUPPORT_3DLR_ALT_SBS
            HAL_MVOP_Set3DLRAltOutput(E_MVOP_DEV_0, DISABLE);
            HAL_MVOP_Set3DLRAltSBSOutput(E_MVOP_DEV_0, DISABLE);
#endif

            /*****************************************************/
            // Reset MVOP setting
            HAL_WriteByte(VOP_TST_IMG, 0x40);
            if (g_pHalMVOPCtx->bIsDMSMCU)
            {
                HAL_MVOP_SetPattern(E_MVOP_DEV_0, MVOP_PATTERN_FRAMECOLOR); //set bk test pattern for dms
            }
            HAL_MVOP_Set3DLRAltOutput_VHalfScaling(E_MVOP_DEV_0, DISABLE); //reset to default: disable 3D L/R alternative output.
            HAL_MVOP_Set3DLR2ndCfg(DISABLE);    //reset to default: disable 3D L/R 2nd pitch.
            HAL_WriteRegBit(VOP_CTRL1, 0, VOP_MVD_VS_MD); //default use original vsync
            // Only for Monaco: Enable deciding bot by top address + 2
            HAL_WriteRegBit(VOP_MIRROR_CFG, 0, VOP_FIELD_FROM_ADDR);
            // Reset Mono mode
            HAL_MVOP_SetMonoMode(E_MVOP_DEV_0, FALSE);

            //set MVOP test pattern to black
            HAL_MVOP_SetBlackBG(E_MVOP_DEV_0);

            // clear extend strip len bit by default
            HAL_WriteRegBit(VOP_REG_STRIP_ALIGN, 0, BIT0);

            // set mvop to 128bit_i128 interface
            HAL_WriteByteMask(VOP_MIU_IF, VOP_MIU_128BIT, VOP_MIU_128BIT | VOP_MIU_128B_I64);

            // Disable H264 or RM Input
            HAL_WriteRegBit(VOP_INPUT_SWITCH1, 0, BIT2 | BIT3);
            // Clear 422 Flag
            g_pHalMVOPCtx->bIs422 = 0;
            // Clear evd Flag for interlace mode setting
            g_pHalMVOPCtx->bIsH265 = 0;
            HAL_WriteRegBit(VOP_INT_TYPE, 0, VOP_EVD_INT_SEP);
            //8*32 tile format
            HAL_WriteRegBit(VOP_REG_WR, 0, BIT1);
            HAL_WriteRegBit(VOP_MIRROR_CFG_HI, 0, VOP_REF_SELF_FLD);
            // ip inverse for: field timing and remove filed bypass.
            HAL_MVOP_SetFieldInverse(E_MVOP_DEV_0, ENABLE, DISABLE);
            HAL_WriteByteMask(VOP_INPUT_SWITCH0, 0, EVD_ENABLE | VOP_TILE_32x32 | VOP_NEW_EVD_EN | VOP_DE_COMP_EN | VOP_DE_COMP_MD);
            // EVD 10 bits disable
            //HAL_WriteByteMask(VOP_REG_MASK, BIT1, VOP_LSB_REQ_MASK);
            HAL_WriteRegBit(VOP_EVD_10B_EN, 0, VOP_EVD_10B_Y_EN);
            HAL_WriteRegBit(VOP_EVD_10B_EN, 0, VOP_EVD_10B_UV_EN);
            // Enable 420 BW Saving mode
            HAL_MVOP_Set420BWSaveMode(E_MVOP_DEV_0, TRUE);
            // Disable New Vsync Mode
            g_pHalMVOPCtx->bNewVSyncMode = FALSE;
            HAL_WriteByteMask(VOP_MPG_JPG_SWITCH, VOP_PRO_SEQ, VOP_PRO_SEQ); //for bk pattern
            // Default enable 2p mode
            HAL_MVOP_Set2PMode(E_MVOP_DEV_0, TRUE);
            // Default enable frame sync
            HAL_MVOP_SetFrameSync(E_MVOP_DEV_0, TRUE);
            // Setting MF burst len
            HAL_WriteByteMask(VOP_REG_MFDEC_0_L, 0x70, VOP_MF1_BURST | VOP_MF0_BURST | VOP_MFDEC_EN);
            // Only for monaco: Disable mfdec setting from wb
            HAL_WriteRegBit(VOP_REG_MFDEC_2_L, 0, VOP_MF_FROM_WB);
            // MIU select from WB
            HAL_WriteRegBit(VOP_UV_SHIFT, 0, VOP_GCLK_MIU_ON);// yc seperate can not enable(1: saving power)

            //Disable DV vision
            HAL_MVOP_Enable2DCTimingSync(DISABLE);
            HAL_MVOP_EnableHDRSetting(E_MVOP_DEV_0, DISABLE);
            HAL_MVOP_SetSingleDV(E_MVOP_DEV_0, DISABLE);
            // Disable 10 bits from codec
            HAL_MVOP_SetHandShakeMode(E_MVOP_DEV_0, DISABLE, 25);
            HAL_MVOP_SetStartX(E_MVOP_DEV_0, 0);
            HAL_MVOP_SetStartY(E_MVOP_DEV_0, 0, 0);
            HAL_MVOP_SetPicWidthMinus(E_MVOP_DEV_0, 0, 0);
            HAL_MVOP_SetPicHeightMinus(E_MVOP_DEV_0, 0, 0);
            //HAL_WriteRegBit(VOP_REG_MRQ, 1, VOP_MRQ_EN); //Manhathan only: merge mvop0/1 miu client
            HAL_SetSCFEMIUIPSel(NULL);
            g_pHalMVOPCtx->eRepeatField = E_MVOP_RPTFLD_NONE;
            HAL_WriteRegBit(VOP_REG_DUMMY, 0, VOP_32x32_WB);
            HAL_MVOP_LoadReg(E_MVOP_DEV_0);
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_0);
            g_pHalMVOPCtx->eInterlaceType = E_MVOP_PRO;
            HAL_WriteRegBit(VOP_REG_4K2K_2P, 0, VOP_TRIG_REFER_VB_END);
#if SUPPORT_FILED_DB // t/b signal 30 lines forwarding
            HAL_WriteRegBit(VOP_MIRROR_CFG_HI, 1, VOP_DC2MVD_FLD_SEL);
            HAL_WriteRegBit(VOP_REG_BW_THD_H, 0, REG_MVD_FLD_SEL);

            HAL_WriteByte((VOP_TF_STR_MVD), 0);
            HAL_WriteByte((VOP_TF_STR_MVD + 1), 0);
            HAL_WriteByte((VOP_BF_STR_MVD), 0);
            HAL_WriteByte((VOP_BF_STR_MVD + 1), 0);
#endif
            HAL_WriteRegBit(VOP_REG_DUMMY_5D_L, 0, XC_RESET_HCOUNT); //disable hw patch for kano gop, only enable at xc gen  timing+de mode
            // M7332/M7632/M7642 mvop fetch data + bw saving have to set 0x14 = 0x2208/0x15 = 0x000a for enlarging burst.
            HAL_Write2Byte(VOP_DMA0, 0x2208);
            HAL_WriteByteMask(VOP_BURST, 0xa, VOP_BURST_DIV | VOP_BURST_BY_WF | VOP_BURST_EXT_MSB | VOP_BURST_MERG_SEL);
            //set for miu 16+16 in hsk mode
            HAL_WriteByte(VOP_LSB_DMA0, 0x10);
            HAL_WriteByte(VOP_LSB_DMA1, 0x07);
            //reset mono mode
            HAL_WriteByte(VOP_RAMAP_CHROMA, 0x08);
            HAL_WriteByte(VOP_INFO_FROM_CODEC_L, 0x00);
            HAL_WriteByte(VOP_INFO_FROM_CODEC_H, 0x00);
#if SUPPORT_DDR4_REMAP
            if (!g_pHalMVOPCtx->bIs422)
            {
                HAL_WriteByteMask(VOP_REG_DDR4_REMAP, 0xE0, VOP_MSB_REMAP | VOP_LSB_REMAP | VOP_CHANNEL3_ENABLE);
#if DDR4_CH_BALANCE_PATCH
                HAL_WriteRegBit(REG_MFD_AV1, TRUE, MVOP_DDR4_REMAP_CH_BALANCE);
#endif
            }
#endif
#if SUPPORT_BACK_DRI_FWD
            HAL_WriteRegBit(VOP_REG_SINGLE_3D_H, 0, VOP_MVD_ADV_VS_MD);
#endif
            HAL_MVOP_SetOutputInterlace(E_MVOP_DEV_0, FALSE);
            //mfdec
            HAL_WriteRegBit(VOP_REG_MFDEC_0_L, FALSE, VOP_MFDEC_EN);
            //fd mask.BOB
            HAL_WriteRegBit(VOP_SW_FDMASK, FALSE, VOP_FDMASK);
            HAL_WriteRegBit(VOP_REG_YC422_EN_H, FALSE, VOP_FD_MASK_FROM_VDEC); //fd_mask double buffer
            HAL_WriteRegBit(VOP_SW_FDMASK, FALSE, VOP_FORCE_BOB);
            HAL_MVOP_LoadReg(E_MVOP_DEV_0);
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_0);
            HAL_WriteByte(VOP_DC_STRIP_H, 0);
            HAL_WriteByte(VOP_DS_IDX, 0xff);
            HAL_MVOP_SetHorDup(E_MVOP_DEV_0, FALSE);
            HAL_MVOP_LoadReg(E_MVOP_DEV_0);
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_0);
            HAL_MVOP_SetVerDup(E_MVOP_DEV_0, FALSE);
            HAL_WriteByteMask(VOP_MPG_JPG_SWITCH, 0x0, VOP_DC_MODE_MASK | VOP_422_IMG | VOP_422_PACK | VOP_DRAM_RD_MODE);
            HAL_MVOP_EnableTCHSetting(E_MVOP_DEV_0, FALSE);
            g_pHalMVOPCtx->bIsEnLSB = 0;
            g_pHalMVOPCtx->u32DC0FrmCnt = 0;
            //mvop mcm set 0xf0 maskes mclk too slow to finish sending data to xc.
            HAL_WriteByteMask(VOP_BURST_DELAY, 0x10, VOP_DELAY_CYCLE);
            //ave peak
            HAL_WriteRegBit(VOP_INPUT_SWITCH0, TRUE, VOP_REDUCE_PEAK);
#if MFDEC_DB_PATCH
            g_pHalMVOPCtx->bMfdecEn = FALSE;
#endif
            g_pHalMVOPCtx->bDramRdContd = FALSE;

            g_pHalMVOPCtx->bForceP = FALSE;
            HAL_WriteRegBit(VOP_REG_DUMMY, 0, VOP_REG_FIELD_BYPASS);
            HAL_WriteRegBit(VOP_TST_IMG, FALSE, VOP_SC_VS_INV);
            HAL_MVOP_LoadReg(E_MVOP_DEV_0);
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_0);
            g_pHalMVOPCtx->u16Reg20 = HAL_ReadByte(VOP_MPG_JPG_SWITCH);
            g_pHalMVOPCtx->eTileFormat = E_MVOP_TILE_NONE;
            g_pHalMVOPCtx->u16MSBPitch = 0;
#if GOP_BACKPORCH_PATCH
            g_pHalMVOPCtx->bIsUnComp = 0;
#endif
            g_pHalMVOPCtx->u16CurVCnt = 0;
#if IOMMU_MFDEC_CTRL
            HAL_WriteByteMask(REG_MVOP_BASIC_MODE_H, MVOP_MFDEC_RIU1_MODE, MVOP_MFDEC_RIU_MODE | MVOP_MFDEC_RIU1_MODE);
#endif
            g_pHalMVOPCtx->bHSD = FALSE;
            g_pHalMVOPCtx->u16HSDOutput = 0;
            HAL_WriteRegBit(VOP_EXT_HSD_SEL, FALSE, HSD_BYPASS_EN);

            // VOP_8BIT_TR_LSC needs to be enabled/disabled with VDEC
            HAL_WriteRegBit(VOP_REG_8BIT_TR_LSC, TRUE, VOP_8BIT_TR_LSC);
            //HSD + dither may cause y = 0xff overflow, default disable dither.
            HAL_WriteByteMask(VOP_EXT_HSD_SEL, 0, HSD_HSD_DTH_EN | HSD_HOUT_PRO | HSD_BYPASS_EN);

            // Default disable film grain related settings
            HAL_WriteByteMask(VOP_EXT_FILM_GRAIN, (FILM_GRAIN_FORCE_WRITE | FILM_GRAIN_FORCE_ACK),
                              (FILM_GRAIN_FORCE_WRITE | FILM_GRAIN_FORCE_ACK));
            HAL_WriteByteMask(VOP_EXT_FILM_GRAIN_H, (FG_Y_BYPASS_EN | FG_CB_BYPASS_EN | FG_CR_BYPASS_EN),
                              (FG_Y_BYPASS_EN | FG_CB_BYPASS_EN | FG_CR_BYPASS_EN));

            // Default enable frame reset in M7332/M7632/M7642
            HAL_MVOP_SetFrameReset(eDevID, TRUE);

            // reset mfdec flush timeout bound
            HAL_Write2ByteMask(REG_MFD_LCACHE_TO, MFD_FLUSH_TIMEOUT_DEFAULT, MFD_TO_LB | MFD_TO_UB);
            HAL_Write2ByteMask(REG_MFD_CCACHE_TO, MFD_FLUSH_TIMEOUT_DEFAULT, MFD_TO_LB | MFD_TO_UB);
            HAL_Write2ByteMask(REG_MFD_OFSCACHE_TO, MFD_FLUSH_TIMEOUT_DEFAULT, MFD_TO_LB | MFD_TO_UB);

            // Reset FineTune value
            HAL_MVOP_SetFineTune(eDevID, 0);
            // enable pattern double buffer
            HAL_WriteRegBit(VOP_REG_DUMMY_5D_L, 0, VOP_PATTERN_DB);

            // Reset bOneField
            g_pHalMVOPCtx->bOneField = FALSE;
            g_pHalMVOPCtx->bAV1_FG = FALSE;

            /*
            * Outlook subject: MVOP av1 patch
            * SW patch for hsk + small size, actual size is captured by ip2.
            */
            HAL_WriteRegBit(VOP_REG_DUMMY_5D_L, TRUE, VOP_MODE_SUPPORTED);
            // 8bit mode need to be enabled for 4x2 tile, normal case can be enable.
            HAL_WriteRegBit(VOP_REG_8BIT_TR_LSC, TRUE, VOP_8BIT_MODE_EN);
#if HAL_MFDEC_MODULE_CNT
            // need to reset mfdec after vr360, only reset in main
            HAL_WriteRegBit(REG_MFD_BASIC_L, TRUE, MFD_HW_RST);
            HAL_WriteRegBit(REG_MFD_BASIC_L, FALSE, MFD_HW_RST);
#endif
            /*****************************************************/
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
#if ENABLE_3D_LR_MODE
            HAL_MVOP_Enable3DLR(E_MVOP_DEV_1, DISABLE);
#endif
#if SUPPORT_3DLR_ALT_SBS
            HAL_MVOP_Set3DLRAltOutput(E_MVOP_DEV_1, DISABLE);
            HAL_MVOP_Set3DLRAltSBSOutput(E_MVOP_DEV_1, DISABLE);
#endif
            HAL_MVOP_SubEnableMVDInterface(FALSE);

            /*****************************************************/
            // Reset MVOP setting
            //Reset share mem
            _HAL_MVOP_SubInitVarCtx();
            HAL_WriteByte(SUB_REG(VOP_TST_IMG), 0x40);
            if (g_pHalMVOPCtx->bSubIsDMSMCU)
            {
                HAL_MVOP_SetPattern(E_MVOP_DEV_1, MVOP_PATTERN_FRAMECOLOR); //set bk test pattern for dms
            }
            HAL_WriteRegBit(SUB_REG(VOP_CTRL1), 0, VOP_MVD_VS_MD); //default use original vsync
            // Only for Monaco: Enable deciding bot by top address + 2
            HAL_WriteRegBit(SUB_REG(VOP_MIRROR_CFG), 0, VOP_FIELD_FROM_ADDR);
            // Reset Mono mode
            HAL_MVOP_SetMonoMode(E_MVOP_DEV_1, FALSE);

            //set MVOP test pattern to black
            HAL_MVOP_SetBlackBG(E_MVOP_DEV_1);

            // clear extend strip len bit by default
            HAL_WriteRegBit(SUB_REG(VOP_REG_STRIP_ALIGN), 0, BIT0);

            // set mvop to 128bit_i128 interface
            HAL_WriteByteMask(SUB_REG(VOP_MIU_IF), VOP_MIU_128BIT, VOP_MIU_128BIT | VOP_MIU_128B_I64);

            // Disable H264 or RM Input
            HAL_WriteRegBit(SUB_REG(VOP_INPUT_SWITCH1), 0, BIT2 | BIT3);
            // Clear 422 Flag
            g_pHalMVOPCtx->bSubIs422 = 0;
            // Clear evd Flag for interlace mode setting
            g_pHalMVOPCtx->bSubIsH265 = 0;
            HAL_WriteRegBit(SUB_REG(VOP_INT_TYPE), 0, VOP_EVD_INT_SEP);
            //8*32 tile format
            HAL_WriteRegBit(SUB_REG(VOP_REG_WR), 0, BIT1);
            HAL_WriteRegBit(SUB_REG(VOP_MIRROR_CFG_HI), 0, VOP_REF_SELF_FLD);
            // ip inverse for: field timing and remove filed bypass.
            HAL_MVOP_SetFieldInverse(E_MVOP_DEV_1, ENABLE, DISABLE);
            // EVD 10 bits
            //HAL_WriteByteMask(SUB_REG(VOP_REG_MASK), BIT1, VOP_LSB_REQ_MASK);
            HAL_WriteRegBit(SUB_REG(VOP_EVD_10B_EN), 0, VOP_EVD_10B_Y_EN);
            HAL_WriteRegBit(SUB_REG(VOP_EVD_10B_EN), 0, VOP_EVD_10B_UV_EN);
            // Enable 420 BW Saving mode
            HAL_MVOP_Set420BWSaveMode(E_MVOP_DEV_1, TRUE);
            // VP9 MODE disable
            HAL_WriteByteMask(SUB_REG(VOP_MPG_JPG_SWITCH), VOP_PRO_SEQ, VOP_PRO_SEQ); //for bk pattern
            // Default disable 2p mode
            HAL_MVOP_Set2PMode(E_MVOP_DEV_1, FALSE);
            // Default enable frame sync
            HAL_MVOP_SetFrameSync(E_MVOP_DEV_1, TRUE);
            // Disable New Vsync Mode
            g_pHalMVOPCtx->bSubNewVSyncMode = FALSE;

            // Setting MF burst len
            HAL_WriteByteMask(SUB_REG(VOP_REG_MFDEC_0_L), 0x70, VOP_MF1_BURST | VOP_MF0_BURST | VOP_MFDEC_EN);
            // Only for monaco: Disable mfdec setting from wb
            HAL_WriteRegBit(SUB_REG(VOP_REG_MFDEC_2_L), 0, VOP_MF_FROM_WB);

            HAL_WriteRegBit(SUB_REG(VOP_UV_SHIFT), 0, VOP_GCLK_MIU_ON);// yc seperate can not enable(1: saving power)

            // MUJI default not support 10 bits display
            // Disable 10 bits from codec
            HAL_WriteByte(SUB_REG(VOP_INFO_FROM_CODEC_L), 0x00);
            HAL_WriteByte(SUB_REG(VOP_INFO_FROM_CODEC_H), 0x00);
            HAL_MVOP_Enable2DCTimingSync(DISABLE);
            HAL_MVOP_EnableHDRSetting(E_MVOP_DEV_1, DISABLE);
            HAL_MVOP_SetSingleDV(E_MVOP_DEV_1, DISABLE);
            HAL_MVOP_SetHandShakeMode(E_MVOP_DEV_1, DISABLE, 25);
            HAL_MVOP_SetStartX(E_MVOP_DEV_1, 0);
            HAL_MVOP_SetStartY(E_MVOP_DEV_1, 0, 0);
            HAL_MVOP_SetPicWidthMinus(E_MVOP_DEV_1, 0, 0);
            HAL_MVOP_SetPicHeightMinus(E_MVOP_DEV_1, 0, 0);
            //HAL_WriteRegBit(SUB_REG(VOP_REG_MRQ), 1, VOP_MRQ_EN); //Manhathan only: merge mvop0/1 miu client
            HAL_SetSCFEMIUIPSel(NULL);
            g_pHalMVOPCtx->eSubRepeatField = E_MVOP_RPTFLD_NONE;
            HAL_WriteRegBit(SUB_REG(VOP_REG_DUMMY), 0, VOP_32x32_WB);
            HAL_MVOP_LoadReg(E_MVOP_DEV_1);
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_1);
            g_pHalMVOPCtx->eSubInterlaceType = E_MVOP_PRO;
#if SUPPORT_FILED_DB // t/b signal 30 lines forwarding
            HAL_WriteRegBit(SUB_REG(VOP_MIRROR_CFG_HI), 1, VOP_DC2MVD_FLD_SEL);
            HAL_WriteRegBit(SUB_REG(VOP_REG_BW_THD_H), 0, REG_MVD_FLD_SEL);

            HAL_WriteByte(SUB_REG(VOP_TF_STR_MVD), 0);
            HAL_WriteByte(SUB_REG(VOP_TF_STR_MVD + 1), 0);
            HAL_WriteByte(SUB_REG(VOP_BF_STR_MVD), 0);
            HAL_WriteByte(SUB_REG(VOP_BF_STR_MVD + 1), 0);
#endif
            HAL_WriteRegBit(SUB_REG(VOP_REG_DUMMY_5D_L), 0, XC_RESET_HCOUNT); //disable hw patch for kano gop, only enable at xc gen  timing+de mode
            // M7332/M7632/M7642 mvop fetch data + bw saving have to set 0x14 = 0x2208/0x15 = 0x000a for enlarging burst.
            HAL_Write2Byte(SUB_REG(VOP_DMA0), 0x2208);
            HAL_WriteByteMask(SUB_REG(VOP_BURST), 0xa, VOP_BURST_DIV | VOP_BURST_BY_WF | VOP_BURST_EXT_MSB | VOP_BURST_MERG_SEL);
            //set for miu 16+16 in hsk mode
            HAL_WriteByte(SUB_REG(VOP_LSB_DMA0), 0x10);
            HAL_WriteByte(SUB_REG(VOP_LSB_DMA1), 0x07);
            //reset mono mode
            HAL_WriteByte(SUB_REG(VOP_RAMAP_CHROMA), 0x08);

            // Disable 10 bits from codec
            HAL_WriteRegBit(SUB_REG(VOP_INFO_FROM_CODEC_H), 0, VOP_INFO_FROM_CODEC_10BIT);
#if SUPPORT_DDR4_REMAP
            if (!g_pHalMVOPCtx->bSubIs422)
            {
                HAL_WriteByteMask(SUB_REG(VOP_REG_DDR4_REMAP), 0xE0, VOP_MSB_REMAP | VOP_LSB_REMAP | VOP_CHANNEL3_ENABLE);
            }
#endif
#if SUPPORT_BACK_DRI_FWD
            HAL_WriteRegBit(SUB_REG(VOP_REG_SINGLE_3D_H), 0, VOP_MVD_ADV_VS_MD);
#endif
            HAL_WriteByteMask(SUB_REG(VOP_INPUT_SWITCH0), 0, EVD_ENABLE | VOP_TILE_32x32 | VOP_NEW_EVD_EN | VOP_DE_COMP_EN | VOP_DE_COMP_MD);
            HAL_MVOP_SetOutputInterlace(E_MVOP_DEV_1, FALSE);
            //fd mask.BOB
            HAL_WriteRegBit(SUB_REG(VOP_SW_FDMASK), FALSE, VOP_FDMASK);
            HAL_WriteRegBit(SUB_REG(VOP_REG_YC422_EN_H), FALSE, VOP_FD_MASK_FROM_VDEC); //fd_mask double buffer
            HAL_WriteRegBit(SUB_REG(VOP_SW_FDMASK), FALSE, VOP_FORCE_BOB);
            //mfdec
            HAL_WriteRegBit(SUB_REG(VOP_REG_MFDEC_0_L), FALSE, VOP_MFDEC_EN);
            HAL_MVOP_LoadReg(E_MVOP_DEV_1);
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_1);
            HAL_WriteByte(SUB_REG(VOP_DC_STRIP_H), 0);
            HAL_WriteByte(SUB_REG(VOP_DS_IDX), 0xff);
            HAL_MVOP_SetHorDup(E_MVOP_DEV_1, FALSE);
            HAL_MVOP_LoadReg(E_MVOP_DEV_1);
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_1);
            HAL_MVOP_SetVerDup(E_MVOP_DEV_1, FALSE);
            HAL_WriteByteMask(SUB_REG(VOP_MPG_JPG_SWITCH), 0x0, VOP_DC_MODE_MASK | VOP_422_IMG | VOP_422_PACK | VOP_DRAM_RD_MODE);
            HAL_MVOP_EnableTCHSetting(E_MVOP_DEV_1, FALSE);
            g_pHalMVOPCtx->bSubIsEnLSB = 0;
            g_pHalMVOPCtx->u32DC1FrmCnt = 0;
            //mvop mcm set 0xf0 maskes mclk too slow to finish sending data to xc.
            HAL_WriteByteMask(SUB_REG(VOP_BURST_DELAY), 0x10, VOP_DELAY_CYCLE);
            //ave peak
            HAL_WriteRegBit(SUB_REG(VOP_INPUT_SWITCH0), TRUE, VOP_REDUCE_PEAK);
            g_pHalMVOPCtx->bSubForceP = FALSE;
            HAL_WriteRegBit(SUB_REG(VOP_REG_DUMMY), 0, VOP_REG_FIELD_BYPASS);
            g_pHalMVOPCtx->bSubDramRdContd = FALSE;
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_1);
            HAL_MVOP_LoadReg(E_MVOP_DEV_1);
            g_pHalMVOPCtx->u16SubReg20 = HAL_ReadByte(SUB_REG(VOP_MPG_JPG_SWITCH));
            g_pHalMVOPCtx->eSubTileFormat = E_MVOP_TILE_NONE;
            g_pHalMVOPCtx->u16SubMSBPitch = 0;
#if GOP_BACKPORCH_PATCH
            g_pHalMVOPCtx->bIsUnComp = 0;
#endif
            g_pHalMVOPCtx->u16SubCurVCnt = 0;

            // VOP_8BIT_TR_LSC needs to be enabled/disabled with VDEC
            HAL_WriteRegBit(SUB_REG(VOP_REG_8BIT_TR_LSC), TRUE, VOP_8BIT_TR_LSC);

            // Default enable frame reset in M7332/M7632/M7642
            HAL_MVOP_SetFrameReset(eDevID, TRUE);
            // enable pattern double buffer
            HAL_WriteRegBit(SUB_REG(VOP_REG_DUMMY_5D_L), 0, VOP_PATTERN_DB);

            // Reset bOneField
            g_pHalMVOPCtx->bSubOneField = FALSE;
            g_pHalMVOPCtx->bSubAV1_FG = FALSE;

#if MAIN_SUB_MVOP_DIFF
            // Reset Average Mode
            HAL_MVOP_SetAverageMode(E_MVOP_DEV_1, FALSE);
#endif
            // 8bit mode need to be enabled for 4x2 tile, normal case can be enable.
            HAL_WriteRegBit(SUB_REG(VOP_REG_8BIT_TR_LSC), TRUE, VOP_8BIT_MODE_EN);
            /*****************************************************/
            break;
        }
#endif
        default:
            MVOP_PRINTF("[%s] Input Device ID is Error!\n", __FUNCTION__);
            break;
    }
}

/******************************************************************************/
/// Set MVOP Handshake Mode, XC should be synchronous with MVOP.
/// this command should be before mvop enable.(before 1st frame)
/******************************************************************************/
void HAL_MVOP_SetHandShakeMode(MVOP_DevID eID, MS_BOOL bEnable, MS_U8 u8Framerate)
{
    MS_U8 regval = 0;
#if GOP_BACKPORCH_PATCH
    MS_BOOL bVsyncForw = FALSE;
#endif

    switch (eID)
    {
        case E_MVOP_DEV_0:
        {
            if ((bEnable != g_pHalMVOPCtx->bIsHS) && !(g_pHalMVOPCtx->bIsSinDV)) //prevent switch VOP_CTRL0 (mvop enable), for MHEG5 verify
            {
                _HAL_MVOP_MaskMIU(eID, TRUE);
                regval = HAL_ReadByte(VOP_CTRL0);
                HAL_WriteRegBit(VOP_CTRL0, 0, VOP_DC_EN);
                g_pHalMVOPCtx->bIsHS = bEnable;
                HAL_WriteRegBit(VOP_REG_HS_OUTPUT, bEnable, VOP_HS_MODE);
                HAL_WriteRegBit(VOP_MIRROR_CFG_HI, bEnable, VOP_HK_MASK); //bk background
#if GOP_BACKPORCH_PATCH
                if (g_pHalMVOPCtx->bIsXcTrig)
                {
                    HAL_WriteRegBit(VOP_REG_4K2K_2P, FALSE, VOP_TRIG_REFER_VB_END);
                }
                else
                {
                    HAL_WriteRegBit(VOP_REG_4K2K_2P, bEnable, VOP_TRIG_REFER_VB_END);

                    bVsyncForw = (HAL_ReadRegBit(VOP_CTRL1, VOP_MVD_VS_MD) == BIT6) ? 1 : 0;
                    if (bEnable && (!bVsyncForw))
                    {
                        MS_U16 u16Vtt = 0;
                        MS_U16 u16TopForw = 0;
                        MS_U16 u16BotForw = 0;
                        MS_U16 u16VblankEnd0 = 0;
                        MS_U16 u16VblankEnd1 = 0;

                        u16Vtt = HAL_Read2Byte(VOP_FRAME_VCOUNT) & SizeMask;
                        u16VblankEnd0 = HAL_Read2Byte(VOP_VB0_END) & SizeMask;
                        u16VblankEnd1 = HAL_Read2Byte(VOP_VB1_END) & SizeMask;

                        if (g_pHalMVOPCtx->eInterlaceType == E_MVOP_PRO)
                        {
                            if (u16Vtt >= uHD_Height) //in ds case
                            {
                                u16TopForw = u16VblankEnd0 + VSYNC_DELAY_BY_VB_END;
                                u16BotForw = u16VblankEnd1 + VSYNC_DELAY_BY_VB_END;
                                HAL_Write2Byte(VOP_TF_VS_MVD, u16TopForw);
                                HAL_Write2Byte(VOP_BF_VS_MVD, u16BotForw);
                                HAL_WriteRegBit(VOP_CTRL1, 1, VOP_MVD_VS_MD);
                            }
                        }
                        else
                        {
                            if (u16Vtt >= fHD_Height) //in ds case
                            {
                                u16TopForw = u16VblankEnd0 + VSYNC_LINE_IMODE;
                                u16BotForw = u16VblankEnd1 + VSYNC_LINE_IMODE;
                                HAL_Write2Byte(VOP_TF_VS_MVD, u16TopForw);
                                HAL_Write2Byte(VOP_BF_VS_MVD, u16BotForw);
                                HAL_WriteRegBit(VOP_CTRL1, 1, VOP_MVD_VS_MD);
                            }
                        }
                    }
                }
#endif
                if (!g_pHalMVOPCtx->bIs2p)
                    HAL_MVOP_Set2PMode(E_MVOP_DEV_0, bEnable);

                if (bEnable)
                {
                    // hsk mode can not enable with frame rst, may cause by pass fd_mask failed.mantis: 1403894
                    // HAL_MVOP_SetFrameReset(E_MVOP_DEV_0, DISABLE);
                    // sw patch for xc frame lock: mantis 1472988
                    if ((HAL_ReadByte(VOP_CTRL0) & 0x80) == 0x80) //interlace
                    {
                        MS_U16 u16VOP_BF_VS = 0;
                        u16VOP_BF_VS = HAL_Read2Byte(VOP_BF_VS) & SizeMask;
                        u16VOP_BF_VS = u16VOP_BF_VS + 1; //patch from cc.yang
                        HAL_Write2Byte(VOP_BF_VS, u16VOP_BF_VS);
                    }
                    // M7332/M7632/M7642: MVOP hw patch for small size h-crop
                    HAL_WriteByteMask(VOP_REG_DDR4_REMAP, VOP_BLANK_CNT, VOP_BLANK_CNT);
                }
                else
                {
                    HAL_WriteByteMask(VOP_REG_DDR4_REMAP, 0x4, VOP_BLANK_CNT);
                    HAL_WriteByte(VOP_REG_BLK_VCNT_L, 0x14); //hw default 0x14
                    HAL_WriteByteMask(VOP_REG_BLK_VCNT_H, 0x00, BIT0);
                }
                HAL_WriteByte(VOP_CTRL0, regval);
                _HAL_MVOP_MaskMIU(eID, FALSE);
                HAL_MVOP_LoadReg(E_MVOP_DEV_0);
                HAL_MVOP_ForceWriteReg(E_MVOP_DEV_0);
            }
            break;
        }
        case E_MVOP_DEV_1:
        {
#if MVOP_SUPPORT_SUB
            if ((bEnable != g_pHalMVOPCtx->bSubIsHS) && !(g_pHalMVOPCtx->bIsSinDV)) //prevent switch VOP_CTRL0 (mvop enable), for MHEG5 verify
            {
                _HAL_MVOP_MaskMIU(eID, TRUE);
                regval = HAL_ReadByte(SUB_REG(VOP_CTRL0));
                HAL_WriteRegBit(SUB_REG(VOP_CTRL0), 0, VOP_DC_EN);
                g_pHalMVOPCtx->bSubIsHS = bEnable;
                HAL_WriteRegBit(SUB_REG(VOP_REG_HS_OUTPUT), bEnable, VOP_HS_MODE);
                HAL_WriteRegBit(SUB_REG(VOP_MIRROR_CFG_HI), bEnable, VOP_HK_MASK); //bk background
                if (g_pHalMVOPCtx->bSubIsXcTrig)
                {
                    HAL_WriteRegBit(SUB_REG(VOP_REG_4K2K_2P), FALSE, VOP_TRIG_REFER_VB_END);
                }
                else
                {
                    HAL_WriteRegBit(SUB_REG(VOP_REG_4K2K_2P), bEnable, VOP_TRIG_REFER_VB_END);
                }
#if GOP_BACKPORCH_PATCH
                if (g_pHalMVOPCtx->bSubIsXcTrig)
                {
                    HAL_WriteRegBit(SUB_REG(VOP_REG_4K2K_2P), FALSE, VOP_TRIG_REFER_VB_END);
                }
                else
                {
                    HAL_WriteRegBit(SUB_REG(VOP_REG_4K2K_2P), bEnable, VOP_TRIG_REFER_VB_END);

                    bVsyncForw = (HAL_ReadRegBit(SUB_REG(VOP_CTRL1), VOP_MVD_VS_MD) == BIT6) ? 1 : 0;
                    if (bEnable && (!bVsyncForw))
                    {
                        MS_U16 u16Vtt = 0;
                        MS_U16 u16TopForw = 0;
                        MS_U16 u16BotForw = 0;
                        MS_U16 u16VblankEnd0 = 0;
                        MS_U16 u16VblankEnd1 = 0;

                        u16Vtt = HAL_Read2Byte(SUB_REG(VOP_FRAME_VCOUNT)) & SizeMask;
                        u16VblankEnd0 = HAL_Read2Byte(SUB_REG(VOP_VB0_END)) & SizeMask;
                        u16VblankEnd1 = HAL_Read2Byte(SUB_REG(VOP_VB1_END)) & SizeMask;

                        if (g_pHalMVOPCtx->eSubInterlaceType == E_MVOP_PRO)
                        {
                            if (u16Vtt >= uHD_Height) //in ds case
                            {
                                u16TopForw = u16VblankEnd0 + VSYNC_DELAY_BY_VB_END;
                                u16BotForw = u16VblankEnd1 + VSYNC_DELAY_BY_VB_END;
                                HAL_Write2Byte(SUB_REG(VOP_TF_VS_MVD), u16TopForw);
                                HAL_Write2Byte(SUB_REG(VOP_BF_VS_MVD), u16BotForw);
                                HAL_WriteRegBit(SUB_REG(VOP_CTRL1), 1, VOP_MVD_VS_MD);
                            }
                        }
                        else
                        {
                            if (u16Vtt >= fHD_Height) //in ds case
                            {
                                u16TopForw = u16VblankEnd0 + VSYNC_LINE_IMODE;
                                u16BotForw = u16VblankEnd1 + VSYNC_LINE_IMODE;
                                HAL_Write2Byte(SUB_REG(VOP_TF_VS_MVD), u16TopForw);
                                HAL_Write2Byte(SUB_REG(VOP_BF_VS_MVD), u16BotForw);
                                HAL_WriteRegBit(SUB_REG(VOP_CTRL1), 1, VOP_MVD_VS_MD);
                            }
                        }
                    }
                }
#endif
                if (!g_pHalMVOPCtx->bSubIs2p)
                    HAL_MVOP_Set2PMode(E_MVOP_DEV_1, bEnable);

                if (bEnable)
                {
                    // hsk mode can not enable with frame rst, may cause by pass fd_mask failed.mantis: 1403894
                    // HAL_MVOP_SetFrameReset(E_MVOP_DEV_1, DISABLE);
                    // sw patch for xc frame lock: mantis 1472988
                    if ((HAL_ReadByte(SUB_REG(VOP_CTRL0)) & 0x80) == 0x80) //interlace
                    {
                        MS_U16 u16VOP_BF_VS = 0;
                        u16VOP_BF_VS = HAL_Read2Byte(SUB_REG(VOP_BF_VS)) & SizeMask;
                        u16VOP_BF_VS = u16VOP_BF_VS + 1; //patch from cc.yang
                        HAL_Write2Byte(SUB_REG(VOP_BF_VS), u16VOP_BF_VS);
                    }
                    // M7332/M7632/M7642: MVOP hw patch for small size h-crop
                    HAL_WriteByteMask(SUB_REG(VOP_REG_DDR4_REMAP), VOP_BLANK_CNT, VOP_BLANK_CNT);
                }
                HAL_WriteByte(SUB_REG(VOP_CTRL0), regval);
                _HAL_MVOP_MaskMIU(eID, FALSE);
                HAL_MVOP_LoadReg(E_MVOP_DEV_1);
                HAL_MVOP_ForceWriteReg(E_MVOP_DEV_1);
            }
#endif
            break;
        }
        default:
            MVOP_PRINTF("[Warning] MVOP_DevID not support!\n");
            break;
    }
}

void HAL_MVOP_SetCropforXC(MVOP_DevID eID, MVOP_XCGetCrop* stXCCrop, MS_U16 u16Width, MS_U16 u16Height)
{
    MVOP_DBG(MVOP_PRINTF("%s [crop info] xst: 0x%x yst: 0x%x xsize: 0x%x ysize: 0x%x Width: 0x%x Height: 0x%x\n", __FUNCTION__,
                         stXCCrop->u16XStart, stXCCrop-> > u16YStart, stXCCrop-> > u16XSize, stXCCrop->u16YSize, u16Width, u16Height);)

    EN_MVOP_Output_3D_TYPE en3DType = E_MVOP_OUTPUT_3D_NONE;

    switch (eID)
    {
        case E_MVOP_DEV_0:
        {
            if (!g_pHalMVOPCtx->bIsXcTrig)
            {
                if (g_pHalMVOPCtx->b3DLRMode)
                {
                    if (g_pHalMVOPCtx->b3DLRAltSBSOutput)
                    {
                        u16Width = u16Width << 1;
                    }
                    else
                    {
                        u16Height = u16Height << 1;
                    }
                }

                if ((stXCCrop->u16XStart + stXCCrop->u16XSize) > u16Width)
                {
                    MVOP_PRINTF("[Warning] crop x size or start out of boundary.");
                    return;
                }

                if ((stXCCrop->u16YStart + stXCCrop->u16YSize) > u16Height)
                {
                    MVOP_PRINTF("[Warning] crop y size or start out of boundary.");
                    return;
                }
            }
            en3DType = HAL_MVOP_GetOutput3DType(E_MVOP_DEV_0);
            MVOP_DBG(MVOP_PRINTF("%s 3D FORMAT = %d\n", __FUNCTION__, en3DType);)
            stXCCrop->u16XStart = ALIGN_UPTO_2(stXCCrop->u16XStart);
            if (en3DType == E_MVOP_OUTPUT_3D_SBS)
            {
                stXCCrop->u16XSize = stXCCrop->u16XSize >> 1;
            }
            stXCCrop->u16XSize = ALIGN_UPTO_2(stXCCrop->u16XSize);
            g_pHalMVOPCtx->u16CropXStart = stXCCrop->u16XStart;
            g_pHalMVOPCtx->u16CropXSize = stXCCrop->u16XSize;

#if 0 //sw patch, for monet/manhattan: maserati fix
            if ((stXCCrop->u16YSize <= 512) && (stXCCrop->u16YStart == 0) && (g_pHalMVOPCtx->bMirrorModeVer == TRUE))
            {
                MVOP_PRINTF("[MVOP][Dbg] crop + mirror patch\n");
                stXCCrop->u16YStart = 1;
                stXCCrop->u16YStart = stXCCrop->u16YStart | 0x2000;

                g_pHalMVOPCtx->u16CropYSize = stXCCrop->u16YSize;
                if (g_pHalMVOPCtx->bIsH265 == FALSE)
                {
                    stXCCrop->u16YSize -= 1;
                }
            }
            else
#endif
                g_pHalMVOPCtx->u16CropYStart = stXCCrop->u16YStart;
            stXCCrop->u16YStart |= 0x6000;
            if ((en3DType == E_MVOP_OUTPUT_3D_TB) || (en3DType == E_MVOP_OUTPUT_3D_LA))
            {
                stXCCrop->u16YSize = stXCCrop->u16YSize >> 1;
            }
            g_pHalMVOPCtx->u16CropYSize = stXCCrop->u16YSize;
            break;
        }
        case E_MVOP_DEV_1:
        {
#if MVOP_SUPPORT_SUB
            if (!g_pHalMVOPCtx->bSubIsXcTrig)
            {
                if (g_pHalMVOPCtx->b3DLRMode)
                {
                    if (g_pHalMVOPCtx->b3DLRAltSBSOutput)
                    {
                        u16Width = u16Width << 1;
                    }
                    else
                    {
                        u16Height = u16Height << 1;
                    }
                }

                if ((stXCCrop->u16XStart + stXCCrop->u16XSize) > u16Width)
                {
                    MVOP_PRINTF("[Warning] crop x size or start out of boundary.");
                    return;
                }

                if ((stXCCrop->u16YStart + stXCCrop->u16YSize) > u16Height)
                {
                    MVOP_PRINTF("[Warning] crop y size or start out of boundary.");
                    return;
                }
            }
            stXCCrop->u16XStart = ALIGN_UPTO_2(stXCCrop->u16XStart);
            en3DType = HAL_MVOP_GetOutput3DType(E_MVOP_DEV_1);
            MVOP_DBG(MVOP_PRINTF("%s 3D FORMAT = %d\n", __FUNCTION__, en3DType);)
            stXCCrop->u16XStart = ALIGN_UPTO_2(stXCCrop->u16XStart);
            if (en3DType == E_MVOP_OUTPUT_3D_SBS)
            {
                stXCCrop->u16XSize = stXCCrop->u16XSize >> 1;
            }
            stXCCrop->u16XSize = ALIGN_UPTO_2(stXCCrop->u16XSize);
            g_pHalMVOPCtx->u16SubCropXStart = stXCCrop->u16XStart;
            g_pHalMVOPCtx->u16SubCropXSize = stXCCrop->u16XSize;

#if 0 //sw patch, for monet/manhattan: maserati fix
            if ((stXCCrop->u16YSize <= 512) && (stXCCrop->u16YStart == 0) && (g_pHalMVOPCtx->bSubMirrorModeVer == TRUE))
            {
                MVOP_PRINTF("[MVOP][Dbg] crop + mirror patch\n");
                stXCCrop->u16YStart = 1;
                stXCCrop->u16YStart = stXCCrop->u16YStart | 0x2000;

                g_pHalMVOPCtx->u16SubCropYSize = stXCCrop->u16YSize;
                if (g_pHalMVOPCtx->bSubIsH265 == FALSE)
                {
                    stXCCrop->u16YSize -= 1;
                }
            }
            else
#endif
                g_pHalMVOPCtx->u16SubCropYStart = stXCCrop->u16YStart;
            stXCCrop->u16YStart |= 0x6000;
            if ((en3DType == E_MVOP_OUTPUT_3D_TB) || (en3DType == E_MVOP_OUTPUT_3D_LA))
            {
                stXCCrop->u16YSize = stXCCrop->u16YSize >> 1;
            }
            g_pHalMVOPCtx->u16SubCropYSize = stXCCrop->u16YSize;
#endif
            break;
        }
        default:
            MVOP_PRINTF("[Warning] MVOP_DevID not support!\n");
            break;
    }
    MVOP_DBG(MVOP_PRINTF("[Debug][Crop to XC] xsize = %d, ysize = %d, xstart = %d, ystart=%d\n", stXCCrop->u16XSize, stXCCrop->u16YSize, stXCCrop->u16XStart, stXCCrop->u16YStart);)
    return;
}


MS_BOOL HAL_MVOP_SupportFRCOutputFPS(MVOP_DevID eID)
{
    MS_BOOL bRet = FALSE;
    switch (eID)
    {
        case E_MVOP_DEV_0:
            bRet = TRUE;
            break;
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
            bRet = TRUE;
            break;
#endif
        default:
            break;
    }
    return bRet;
}

MS_BOOL HAL_MVOP_GetIsCurrentHSK(MVOP_DevID eID)
{
    MS_BOOL bRet = FALSE;
    switch (eID)
    {
        case E_MVOP_DEV_0:
            bRet = g_pHalMVOPCtx->bIsHS;
            break;
        case E_MVOP_DEV_1:
#if MVOP_SUPPORT_SUB
            bRet = g_pHalMVOPCtx->bSubIsHS;
#endif
            break;
        default:
            bRet = E_MVOP_HS_INVALID_PARAM;
            break;
    }
    return bRet;
}

void HAL_SetSCFEMIUIPSel(MVOP_SCIPSel* stIPSel)
{
    UNUSED(stIPSel);
    //MVOP/DIP/DISP_MFDEC only support hw select.
    return;
}

void HAL_MVOP_ResetMVOPSetting(MVOP_DevID eDevID)
{

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
            HAL_WriteRegBit(VOP_REG_MFDEC_2_L, 0, VOP_MF_FROM_WB);
            break;
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
            HAL_WriteRegBit(SUB_REG(VOP_REG_MFDEC_2_L), 0, VOP_MF_FROM_WB);
            break;
#endif
        default:
            break;
    }
    return;
}

MS_U16 HAL_MVOP_ReadBank(MVOP_DevID eID, MS_U16 u16Length)
{
    MS_U16 u16Reg = 0;
    if (eID == E_MVOP_DEV_0)
    {
        HAL_WriteRegBit(VOP_REG_WR, 1, BIT4);
        u16Reg = HAL_Read2Byte(MVOP_REG_BASE + (u16Length << 1));
        HAL_WriteRegBit(VOP_REG_WR, 0, BIT4);
    }
#ifdef MVOP_SUPPORT_SUB
    else if (eID == E_MVOP_DEV_1)
    {
        HAL_WriteRegBit(SUB_REG(VOP_REG_WR), 1, BIT4);
        u16Reg = HAL_Read2Byte(SUB_REG(MVOP_REG_BASE + (u16Length << 1)));
        HAL_WriteRegBit(SUB_REG(VOP_REG_WR), 0, BIT4);
    }
#endif
    return u16Reg;
}

void HAL_MVOP_WriteBank(MVOP_DevID eID, MS_U16 u16Length, MS_U16 u16Data)
{
    if (eID == E_MVOP_DEV_0)
    {
        HAL_Write2Byte(MVOP_REG_BASE + (u16Length << 1), u16Data);
    }
#ifdef MVOP_SUPPORT_SUB
    else if (eID == E_MVOP_DEV_1)
    {
        HAL_Write2Byte(SUB_REG(MVOP_REG_BASE + (u16Length << 1)), u16Data);
    }
#endif
}

MS_U16 HAL_MVOP_ReadClkBank(MS_U16 u16Length)
{
    MS_U16 u16Reg = 0;

    if (u16Length < 3) // stc cw
    {
        u16Reg = HAL_Read2Byte(REG_STC_CW_SLE_L + (u16Length << 1));

    }
    else if (u16Length < 7) // dc clk
    {
        u16Length -= 3;
        u16Reg = HAL_Read2Byte(REG_CKG_DC0 + (u16Length << 1)); // main/sub sram
    }
    else // freerun/sync clk
    {
        u16Length -= 7;
        u16Reg = HAL_Read2Byte(REG_UPDATE_DC0_CW + (u16Length << 1));
    }

    //printk("[read][%x] u16Reg = 0x%x\n",u16Length,u16Reg);
    return u16Reg;
}

void HAL_MVOP_WriteClkBank(MS_U16 u16Length, MS_U16 u16Data)
{

    //printk("[write][%x] u16Reg = 0x%x\n",u16Length,u16Data);

    if (u16Length < 3) // stc cw
    {
        HAL_Write2Byte(REG_STC_CW_SLE_L + (u16Length << 1), u16Data);
    }
    else if (u16Length < 7) // dc clk
    {
        u16Length -= 3;
        HAL_Write2Byte(REG_CKG_DC0 + (u16Length << 1), u16Data);
    }
    else // freerun/sync clk
    {
        u16Length -= 7;
        HAL_Write2Byte(REG_UPDATE_DC0_CW + (u16Length << 1), u16Data);
    }
    HAL_WriteRegBit(REG_UPDATE_DC0_CW, TRUE, UPDATE_DC0_SYNC_CW);
    HAL_WriteRegBit(REG_UPDATE_DC0_CW, FALSE, UPDATE_DC0_SYNC_CW);

}

void HAL_MVOP_SetInterlaceType(MVOP_DevID eDevID, MS_U8 u8Interlace)
{
    MVOP_DBG(MVOP_PRINTF("%s u8Interlace = %d\n", __FUNCTION__, u8Interlace);)

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
            // set by frame in vsd mode
            g_pHalMVOPCtx->eInterlaceType = (MVOP_OutputImodeType)u8Interlace;
            if (g_pHalMVOPCtx->eInterlaceType == E_MVOP_INT_TB_SEP_FRAME)
            {
                HAL_WriteRegBit(VOP_INT_TYPE, 1, VOP_EVD_INT_SEP);
                HAL_WriteRegBit(VOP_MIRROR_CFG, 0, VOP_FIELD_FROM_ADDR);
            }
            else if (g_pHalMVOPCtx->eInterlaceType == E_MVOP_INT_TB_ONE_FRAME)
            {
                HAL_WriteRegBit(VOP_INT_TYPE, 0, VOP_EVD_INT_SEP);
            }
            HAL_MVOP_LoadReg(E_MVOP_DEV_0);
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_0);
            break;
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
            g_pHalMVOPCtx->eSubInterlaceType = (MVOP_OutputImodeType)u8Interlace;
            if (g_pHalMVOPCtx->eSubInterlaceType == E_MVOP_INT_TB_SEP_FRAME)
            {
                HAL_WriteRegBit(SUB_REG(VOP_INT_TYPE), 1, VOP_EVD_INT_SEP);
                HAL_WriteRegBit(SUB_REG(VOP_MIRROR_CFG), 0, VOP_FIELD_FROM_ADDR);
            }
            else if (g_pHalMVOPCtx->eSubInterlaceType == E_MVOP_INT_TB_ONE_FRAME)
            {
                HAL_WriteRegBit(SUB_REG(VOP_INT_TYPE), 0, VOP_EVD_INT_SEP);
            }
            HAL_MVOP_LoadReg(E_MVOP_DEV_1);
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_1);
            break;
#endif
        default:
            MVOP_PRINTF("[Warning][%s] MVOP_DevID not support\n", __FUNCTION__);
            break;
    }
}

MS_BOOL HAL_MVOP_GetIsCurrentXCGenTiming(MVOP_DevID eID)
{
    MS_BOOL bRet = FALSE;
    switch (eID)
    {
        case E_MVOP_DEV_0:
            bRet = g_pHalMVOPCtx->bIsXcTrig;
            break;
        case E_MVOP_DEV_1:
#if MVOP_SUPPORT_SUB
            bRet = g_pHalMVOPCtx->bSubIsXcTrig;
#endif
            break;
        default:
            bRet = E_MVOP_HS_INVALID_PARAM;
            break;
    }
    return bRet;
}

MS_BOOL HAL_MVOP_GetIsMVOPSupportBLKBackground(MVOP_DevID eID)
{
    MS_BOOL bRet = FALSE;
    switch (eID)
    {
        case E_MVOP_DEV_0:
            bRet = TRUE;
            break;
        case E_MVOP_DEV_1:
#if MVOP_SUPPORT_SUB
            bRet = TRUE;
#endif
            break;
        default:
            bRet = E_MVOP_HS_INVALID_PARAM;
            break;
    }
    return bRet;
}

void HAL_MVOP_SetSramPower(MVOP_DevID eID, MS_BOOL bEnable)
{
    switch (eID)
    {
        case E_MVOP_DEV_0:
#if MVOP_SUPPORT_SUB
            if ((bEnable == FALSE) && (g_pHalMVOPCtx->bSubIsEnable == FALSE)) //check sub disable -> mfdec sram disable
            {
                HAL_WriteRegBit(VOP_DC_STRIP_H, 1, MFDEC_SRAM_SD_MASK);
                HAL_WriteRegBit(VOP_DC_STRIP_H, 1, VOP_SRAM_SD_MASK);
            }
            else
            {
                HAL_WriteRegBit(VOP_DC_STRIP_H, 0, MFDEC_SRAM_SD_MASK);
                HAL_WriteRegBit(VOP_DC_STRIP_H, 0, VOP_SRAM_SD_MASK);
            }
#else
            HAL_WriteRegBit(VOP_DC_STRIP_H, !bEnable, VOP_SRAM_SD_MASK);
#endif
            break;
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
            if ((bEnable == FALSE) && (g_pHalMVOPCtx->bIsEnable == FALSE))
            {
                HAL_WriteRegBit(VOP_DC_STRIP_H, 1, MFDEC_SRAM_SD_MASK);
                HAL_WriteRegBit(VOP_DC_STRIP_H, 1, VOP_SRAM_SD_MASK);
                HAL_WriteRegBit(SUB_REG(VOP_DC_STRIP_H), 1, VOP_SRAM_SD_MASK);
            }
            else
            {
                HAL_WriteRegBit(VOP_DC_STRIP_H, 0, MFDEC_SRAM_SD_MASK);
                HAL_WriteRegBit(VOP_DC_STRIP_H, 0, VOP_SRAM_SD_MASK); //main need to enable, if sub enable.
                HAL_WriteRegBit(SUB_REG(VOP_DC_STRIP_H), 0, VOP_SRAM_SD_MASK);
            }
            break;
#endif
        default:
            break;
    }
    return;
}

/******************************************************************************/
/// Set MVOP Handshake Mode, XC should be synchronous with MVOP.
/// this command should be before mvop enable.(before 1st frame)
/******************************************************************************/
void HAL_MVOP_SetTimingFromXC(MVOP_DevID eID, MS_BOOL bEnable)
{
    MVOP_DBG(MVOP_PRINTF("[MVOP] %s = %d\n", __FUNCTION__, bEnable);)

    MVOP_FREQUENCY eFreq;

    switch (eID)
    {
        case E_MVOP_DEV_0:
        {
            g_pHalMVOPCtx->bIsXcTrig = bEnable;

            if (TRUE == bEnable)
            {
                HAL_WriteByteMask(VOP_REG_HS_OUTPUT,
                                  0x06,
                                  (VOP_TRIG_FROM_XC | VOP_VSUNC_FROM_XC));
                /* disable inverse the field to IP - not in kano */
                // HAL_WriteRegBit(VOP_CTRL1, 0, BIT4);
                eFreq = HAL_MVOP_GetMaximumClk(E_MVOP_DEV_0);
                HAL_MVOP_SetClock(E_MVOP_DEV_0, eFreq);
                HAL_MVOP_SetFrequency(E_MVOP_DEV_0, eFreq);
                /* set mfdec flush timeout bound */
                HAL_Write2ByteMask(REG_MFD_LCACHE_TO,
                                   MFD_FLUSH_TIMEOUT_BOUND,
                                   (MFD_TO_LB | MFD_TO_UB));
                HAL_Write2ByteMask(REG_MFD_CCACHE_TO,
                                   MFD_FLUSH_TIMEOUT_BOUND,
                                   (MFD_TO_UB | MFD_TO_UB));
                HAL_Write2ByteMask(REG_MFD_OFSCACHE_TO,
                                   MFD_FLUSH_TIMEOUT_BOUND,
                                   (MFD_TO_LB | MFD_TO_UB));

                HAL_WriteRegBit(VOP_REG_4K2K_2P, FALSE, VOP_TRIG_REFER_VB_END);
                /* extending vsync long pulse for ip sampling correctly. */
                HAL_WriteRegBit(VOP_LSB_DMA1, TRUE, VOP_VS_EXT_EN);
            }
            else
            {
                HAL_WriteByteMask(VOP_REG_HS_OUTPUT,
                                  0x00,
                                  (VOP_TRIG_FROM_XC | VOP_VSUNC_FROM_XC));
                HAL_WriteRegBit(VOP_LSB_DMA1, FALSE, VOP_VS_EXT_EN);
            }
            HAL_MVOP_LoadReg(E_MVOP_DEV_0);
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_0);
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            g_pHalMVOPCtx->bSubIsXcTrig = bEnable;

            if (TRUE == bEnable)
            {
                HAL_WriteByteMask(SUB_REG(VOP_REG_HS_OUTPUT),
                                  0x06,
                                  (VOP_TRIG_FROM_XC | VOP_VSUNC_FROM_XC));
                eFreq = HAL_MVOP_GetMaximumClk(E_MVOP_DEV_1);
                HAL_MVOP_SetClock(E_MVOP_DEV_1, eFreq);
                HAL_MVOP_SetFrequency(E_MVOP_DEV_1, eFreq);
                HAL_WriteRegBit(SUB_REG(VOP_REG_4K2K_2P),
                                FALSE,
                                VOP_TRIG_REFER_VB_END);
                HAL_WriteRegBit(SUB_REG(VOP_LSB_DMA1),
                                TRUE,
                                VOP_VS_EXT_EN);
            }
            else
            {
                HAL_WriteByteMask(SUB_REG(VOP_REG_HS_OUTPUT),
                                  0x00,
                                  (VOP_TRIG_FROM_XC | VOP_VSUNC_FROM_XC));
                HAL_WriteRegBit(SUB_REG(VOP_LSB_DMA1),
                                FALSE,
                                VOP_VS_EXT_EN);
            }
            HAL_MVOP_LoadReg(E_MVOP_DEV_1);
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_1);
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[Warning] MVOP_DevID not support!\n");
            break;
        }
    }
}

void HAL_MVOP_Enable2DCTimingSync(MS_BOOL bEnable)
{
    UNUSED(bEnable);
    return;
}

void HAL_MVOP_EnableHDRSetting(MVOP_DevID eDevID, MS_BOOL bEnable)
{
    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            // mvop output 444 now, including dolby
            HAL_WriteRegBit(VOP_REG_YC422_EN_H, FALSE, BIT0);
            if (g_pHalMVOPCtx->bIsXcTrig)
            {
                HAL_WriteRegBit(VOP_REG_4K2K_2P, FALSE, VOP_TRIG_REFER_VB_END);
            }
            else
            {
                HAL_WriteRegBit(VOP_REG_4K2K_2P, bEnable, VOP_TRIG_REFER_VB_END);
            }
            HAL_MVOP_SetSingleDV(E_MVOP_DEV_0, bEnable);
            if (bEnable)
            {
                //enable hsk mode
                HAL_WriteRegBit(VOP_REG_HS_OUTPUT, TRUE, VOP_HS_MODE);
                HAL_WriteRegBit(VOP_MIRROR_CFG_HI, TRUE, VOP_HK_MASK); //bk background
                g_pHalMVOPCtx->bIsHS = TRUE;
                //enable 2p
                HAL_MVOP_Set2PMode(E_MVOP_DEV_0, TRUE);
                HAL_WriteByteMask(VOP_REG_WR_H, 0xF0, VOP_BURST_DELAY_MSB);
                HAL_WriteByte(VOP_REG_BLK_VCNT_L, 0xFF);
                HAL_WriteByteMask(VOP_REG_BLK_VCNT_H, 0x01, BIT0);
                //setting 0x708 dolby stream, 0x13023f only 0x8.
                HAL_WriteByte(VOP_LSB_DMA0, 0x10);
                HAL_WriteByte(VOP_LSB_DMA1, 0x07);
                //vsync inverse
                HAL_WriteRegBit(VOP_TST_IMG, TRUE, VOP_SC_VS_INV);
            }
            else
            {
                HAL_WriteByteMask(VOP_REG_WR_H, 0x00, VOP_BURST_DELAY_MSB);
                HAL_WriteByte(VOP_REG_BLK_VCNT_L, 0x14); //hw default 0x14
                HAL_WriteByteMask(VOP_REG_BLK_VCNT_H, 0x00, BIT0);
                HAL_WriteByte(VOP_LSB_DMA0, 0x08);
                HAL_WriteByte(VOP_LSB_DMA1, 0x07);
                HAL_WriteRegBit(VOP_TST_IMG, FALSE, VOP_SC_VS_INV);
            }
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            // mvop output 444 now, including dolby
            HAL_WriteRegBit(SUB_REG(VOP_REG_YC422_EN_H), FALSE, BIT0);
            if (g_pHalMVOPCtx->bSubIsXcTrig)
            {
                HAL_WriteRegBit(SUB_REG(VOP_REG_4K2K_2P), FALSE, VOP_TRIG_REFER_VB_END);
            }
            else
            {
                HAL_WriteRegBit(SUB_REG(VOP_REG_4K2K_2P), bEnable, VOP_TRIG_REFER_VB_END);
            }
            HAL_MVOP_SetSingleDV(E_MVOP_DEV_1, bEnable);
            if (bEnable)
            {
                HAL_WriteRegBit(SUB_REG(VOP_REG_HS_OUTPUT), TRUE, VOP_HS_MODE);
                HAL_WriteRegBit(SUB_REG(VOP_MIRROR_CFG_HI), TRUE, VOP_HK_MASK); //bk background
                g_pHalMVOPCtx->bSubIsHS = TRUE;
                HAL_MVOP_Set2PMode(E_MVOP_DEV_1, TRUE);
                HAL_WriteByteMask(SUB_REG(VOP_REG_WR_H), 0xF0, VOP_BURST_DELAY);
            }
            else
            {
                HAL_WriteByteMask(SUB_REG(VOP_REG_WR_H), 0x00, VOP_BURST_DELAY);
            }
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
}

void HAL_MVOP_SetByTiming(MVOP_DevID eID, MVOP_VidStat* pstVideoStatus)
{
    MVOP_DBG(MVOP_PRINTF("[MVOP][DBG] HAL_MVOP_SetByTiming\n");)
    switch (eID)
    {
        case E_MVOP_DEV_0:
            MVOP_DBG(MVOP_PRINTF("[MVOP][DBG] no setting\n");)
            break;
        case E_MVOP_DEV_1:
#if MVOP_SUPPORT_SUB
            MVOP_DBG(MVOP_PRINTF("[MVOP][DBG] no setting\n");)
#endif
            break;
        default:
            MVOP_PRINTF("[MVOP][ERR] error input DevID\n");
            break;
    }
}

MS_BOOL HAL_MVOP_IsSupport2PMode(MVOP_DevID eDevID)
{
    UNUSED(eDevID);
    return TRUE;
}

MS_BOOL HAL_MVOP_AutoTimingHDS(MVOP_DevID eID)
{
    MS_BOOL bRet = FALSE;

    switch (eID)
    {
        case E_MVOP_DEV_0:
            bRet = FALSE;
            break;
        case E_MVOP_DEV_1:
#if MVOP_SUPPORT_SUB
            bRet = FALSE;
#endif
            break;
        default:
            bRet = E_MVOP_HS_INVALID_PARAM;
            break;
    }
    return bRet;

}

void HAL_MVOP_Exit(MVOP_DevID eID)
{
    if (NULL == g_pHalMVOPCtx)
    {
        MVOP_DBG(MVOP_PRINTF("%s g_pHalMVOPCtx is NULL pointer\n", __FUNCTION__);)
        return;
    }

    HAL_MVOP_ResetReg(eID);

    switch (eID)
    {
        case E_MVOP_DEV_0:
            g_pHalMVOPCtx->bIsInit = 0;
            g_pHalMVOPCtx->u32DC0FrmCnt = 0;
            HAL_WriteRegBit(VOP_REG_MFDEC_0_L, FALSE, VOP_MFDEC_EN);
#if IOMMU_MFDEC_CTRL
            HAL_WriteByteMask(REG_MVOP_BASIC_MODE_H, MVOP_MFDEC_RIU_MODE, MVOP_MFDEC_RIU_MODE | MVOP_MFDEC_RIU1_MODE);
#endif
            break;
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
            g_pHalMVOPCtx->bSubIsInit = 0;
            g_pHalMVOPCtx->u32DC1FrmCnt = 0;
            HAL_WriteRegBit(SUB_REG(VOP_REG_MFDEC_0_L), FALSE, VOP_MFDEC_EN);
            break;
#endif
        default:
            break;
    }

    return;
}

void HAL_MVOP_SetMiuSaveArea(MVOP_DevID eID, MVOP_MIUReadPrct stMiuSave)
{
    UNUSED(eID);
    UNUSED(stMiuSave);
    MVOP_PRINTF("[Warning][%s] not support\n", __FUNCTION__);
    return;
}

void HAL_MVOP_SetbyInputTiming(MVOP_DevID eID, MVOP_VidStat* pstVideoStatus)
{
    UNUSED(eID);
    UNUSED(pstVideoStatus);
    MVOP_PRINTF("[Warning][%s] not support\n", __FUNCTION__);
    return;
}

void HAL_MVOP_UVSwapEnable(MVOP_DevID eID, MS_BOOL bEnable)
{
    switch (eID)
    {
        case E_MVOP_DEV_0:
            HAL_WriteRegBit(VOP_TST_IMG, bEnable, VOP_UV_SWAP);
            break;
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
            HAL_WriteRegBit(SUB_REG(VOP_TST_IMG), bEnable, VOP_UV_SWAP);
            break;
#endif
        default:
            break;
    }
    return;
}

MS_BOOL HAL_MVOP_SetMFDECRotate(MVOP_DevID eID, MVOP_MFDECRotate eRotate)
{
#if SUPPORT_MFDEC_ROTATE
    MS_BOOL bRet = TRUE;

    if (NULL == g_pHalMVOPCtx)
    {
        MVOP_DBG(MVOP_PRINTF("%s g_pHalMVOPCtx is NULL pointer\n", __FUNCTION__);)
        bRet = FALSE;
        return bRet;
    }

    switch (eID)
    {
        case E_MVOP_DEV_0:
        {
            g_pHalMVOPCtx->eRotate = eRotate;

            if (VOP_MIRROR_CFG_ENABLE != HAL_ReadRegBit(VOP_MIRROR_CFG,
                                                        VOP_MIRROR_CFG_ENABLE))
            {
                HAL_MVOP_InitMirrorMode(E_MVOP_DEV_0, TRUE);
            }

            /* H/V mirror will switch when rotate is enabled */
            switch (eRotate)
            {
                case E_MVOP_MF_ROTATE_NONE:
                {
                    if (TRUE == g_pHalMVOPCtx->bMirrorModeVer)
                    {
                        HAL_WriteRegBit(VOP_MIRROR_CFG,
                                        TRUE,
                                        VOP_MIRROR_CFG_VEN);
                    }
                    else
                    {
                        HAL_WriteRegBit(VOP_MIRROR_CFG,
                                        FALSE,
                                        VOP_MIRROR_CFG_VEN);
                    }

                    if (TRUE == g_pHalMVOPCtx->bMirrorModeHor)
                    {
                        HAL_WriteRegBit(VOP_MIRROR_CFG,
                                        TRUE,
                                        VOP_MIRROR_CFG_HEN);
                    }
                    else
                    {
                        HAL_WriteRegBit(VOP_MIRROR_CFG,
                                        FALSE,
                                        VOP_MIRROR_CFG_HEN);
                    }

                    HAL_WriteRegBit(VOP_REG_MFDEC_2_L,
                                    FALSE,
                                    VOP_ROTATE_EN);

                    HAL_WriteRegBit(VOP_MPG_JPG_SWITCH,
                                    FALSE,
                                    VOP_422_LINEAR_JMP);
                    g_pHalMVOPCtx->u16Reg20 &= ~VOP_422_LINEAR_JMP;
                    break;
                }
                case E_MVOP_MF_ROTATE_90:
                {
                    if (TRUE == g_pHalMVOPCtx->bMirrorModeVer)
                    {
                        HAL_WriteRegBit(VOP_MIRROR_CFG,
                                        FALSE,
                                        VOP_MIRROR_CFG_VEN);
                    }
                    else
                    {
                        HAL_WriteRegBit(VOP_MIRROR_CFG,
                                        TRUE,
                                        VOP_MIRROR_CFG_VEN);
                    }

                    if (TRUE == g_pHalMVOPCtx->bMirrorModeHor)
                    {
                        HAL_WriteRegBit(VOP_MIRROR_CFG,
                                        TRUE,
                                        VOP_MIRROR_CFG_HEN);
                    }
                    else
                    {
                        HAL_WriteRegBit(VOP_MIRROR_CFG,
                                        FALSE,
                                        VOP_MIRROR_CFG_HEN);
                    }

                    HAL_WriteRegBit(VOP_REG_MFDEC_2_L,
                                    TRUE,
                                    VOP_ROTATE_EN);

                    if (TRUE == g_pHalMVOPCtx->bIs422)
                    {
                        HAL_WriteRegBit(VOP_MPG_JPG_SWITCH,
                                        TRUE,
                                        VOP_422_LINEAR_JMP);
                        g_pHalMVOPCtx->u16Reg20 |= VOP_422_LINEAR_JMP;
                    }
                    break;
                }
                case E_MVOP_MF_ROTATE_180:
                {
                    if (TRUE == g_pHalMVOPCtx->bMirrorModeVer)
                    {
                        HAL_WriteRegBit(VOP_MIRROR_CFG, FALSE,
                                        VOP_MIRROR_CFG_VEN);
                    }
                    else
                    {
                        HAL_WriteRegBit(VOP_MIRROR_CFG,
                                        TRUE,
                                        VOP_MIRROR_CFG_VEN);
                    }

                    if (TRUE == g_pHalMVOPCtx->bMirrorModeHor)
                    {
                        HAL_WriteRegBit(VOP_MIRROR_CFG,
                                        FALSE,
                                        VOP_MIRROR_CFG_HEN);
                    }
                    else
                    {
                        HAL_WriteRegBit(VOP_MIRROR_CFG,
                                        TRUE,
                                        VOP_MIRROR_CFG_HEN);
                    }

                    HAL_WriteRegBit(VOP_REG_MFDEC_2_L,
                                    FALSE,
                                    VOP_ROTATE_EN);

                    HAL_WriteRegBit(VOP_MPG_JPG_SWITCH,
                                    FALSE,
                                    VOP_422_LINEAR_JMP);
                    g_pHalMVOPCtx->u16Reg20 &= ~VOP_422_LINEAR_JMP;
                    break;
                }
                case E_MVOP_MF_ROTATE_270:
                {
                    if (TRUE == g_pHalMVOPCtx->bMirrorModeVer)
                    {
                        HAL_WriteRegBit(VOP_MIRROR_CFG,
                                        TRUE,
                                        VOP_MIRROR_CFG_VEN);
                    }
                    else
                    {
                        HAL_WriteRegBit(VOP_MIRROR_CFG,
                                        FALSE,
                                        VOP_MIRROR_CFG_VEN);
                    }

                    if (TRUE == g_pHalMVOPCtx->bMirrorModeHor)
                    {
                        HAL_WriteRegBit(VOP_MIRROR_CFG,
                                        FALSE,
                                        VOP_MIRROR_CFG_HEN);
                    }
                    else
                    {
                        HAL_WriteRegBit(VOP_MIRROR_CFG,
                                        TRUE,
                                        VOP_MIRROR_CFG_HEN);
                    }

                    HAL_WriteRegBit(VOP_REG_MFDEC_2_L,
                                    TRUE,
                                    VOP_ROTATE_EN);

                    if (TRUE == g_pHalMVOPCtx->bIs422)
                    {
                        HAL_WriteRegBit(VOP_MPG_JPG_SWITCH,
                                        TRUE,
                                        VOP_422_LINEAR_JMP);
                        g_pHalMVOPCtx->u16Reg20 |= VOP_422_LINEAR_JMP;
                    }
                    break;
                }
                default:
                {
                    MVOP_PRINTF("[%s] Not support rotate type: %u\n",
                                __FUNCTION__,
                                eRotate);
                    bRet = FALSE;
                    break;
                }
            }
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_0);
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            g_pHalMVOPCtx->eSubRotate = eRotate;

            if (VOP_MIRROR_CFG_ENABLE != HAL_ReadRegBit(SUB_REG(VOP_MIRROR_CFG),
                                                        VOP_MIRROR_CFG_ENABLE))
            {
                HAL_MVOP_InitMirrorMode(E_MVOP_DEV_1, TRUE);
            }

            /* H/V mirror will switch when rotate is enabled */
            switch (eRotate)
            {
                case E_MVOP_MF_ROTATE_NONE:
                {
                    if (TRUE == g_pHalMVOPCtx->bSubMirrorModeVer)
                    {
                        HAL_WriteRegBit(SUB_REG(VOP_MIRROR_CFG),
                                        TRUE,
                                        VOP_MIRROR_CFG_VEN);
                    }
                    else
                    {
                        HAL_WriteRegBit(SUB_REG(VOP_MIRROR_CFG),
                                        FALSE,
                                        VOP_MIRROR_CFG_VEN);
                    }

                    if (TRUE == g_pHalMVOPCtx->bSubMirrorModeHor)
                    {
                        HAL_WriteRegBit(SUB_REG(VOP_MIRROR_CFG),
                                        TRUE,
                                        VOP_MIRROR_CFG_HEN);
                    }
                    else
                    {
                        HAL_WriteRegBit(SUB_REG(VOP_MIRROR_CFG),
                                        FALSE,
                                        VOP_MIRROR_CFG_HEN);
                    }

                    HAL_WriteRegBit(SUB_REG(VOP_REG_MFDEC_2_L),
                                    FALSE,
                                    VOP_ROTATE_EN);

                    HAL_WriteRegBit(SUB_REG(VOP_MPG_JPG_SWITCH),
                                    FALSE,
                                    VOP_422_LINEAR_JMP);
                    g_pHalMVOPCtx->u16SubReg20 &= ~VOP_422_LINEAR_JMP;
                    break;
                }
                case E_MVOP_MF_ROTATE_90:
                {
                    if (TRUE == g_pHalMVOPCtx->bSubMirrorModeVer)
                    {
                        HAL_WriteRegBit(SUB_REG(VOP_MIRROR_CFG),
                                        FALSE,
                                        VOP_MIRROR_CFG_VEN);
                    }
                    else
                    {
                        HAL_WriteRegBit(SUB_REG(VOP_MIRROR_CFG),
                                        TRUE,
                                        VOP_MIRROR_CFG_VEN);
                    }

                    if (TRUE == g_pHalMVOPCtx->bSubMirrorModeHor)
                    {
                        HAL_WriteRegBit(SUB_REG(VOP_MIRROR_CFG),
                                        TRUE,
                                        VOP_MIRROR_CFG_HEN);
                    }
                    else
                    {
                        HAL_WriteRegBit(SUB_REG(VOP_MIRROR_CFG),
                                        FALSE,
                                        VOP_MIRROR_CFG_HEN);
                    }

                    HAL_WriteRegBit(SUB_REG(VOP_REG_MFDEC_2_L),
                                    TRUE,
                                    VOP_ROTATE_EN);

                    if (TRUE == g_pHalMVOPCtx->bSubIs422)
                    {
                        HAL_WriteRegBit(SUB_REG(VOP_MPG_JPG_SWITCH),
                                        TRUE,
                                        VOP_422_LINEAR_JMP);
                        g_pHalMVOPCtx->u16SubReg20 |= VOP_422_LINEAR_JMP;
                    }
                    break;
                }
                case E_MVOP_MF_ROTATE_180:
                {
                    if (TRUE == g_pHalMVOPCtx->bSubMirrorModeVer)
                    {
                        HAL_WriteRegBit(SUB_REG(VOP_MIRROR_CFG),
                                        FALSE,
                                        VOP_MIRROR_CFG_VEN);
                    }
                    else
                    {
                        HAL_WriteRegBit(SUB_REG(VOP_MIRROR_CFG),
                                        TRUE,
                                        VOP_MIRROR_CFG_VEN);
                    }

                    if (TRUE == g_pHalMVOPCtx->bSubMirrorModeHor)
                    {
                        HAL_WriteRegBit(SUB_REG(VOP_MIRROR_CFG),
                                        FALSE,
                                        VOP_MIRROR_CFG_HEN);
                    }
                    else
                    {
                        HAL_WriteRegBit(SUB_REG(VOP_MIRROR_CFG),
                                        TRUE,
                                        VOP_MIRROR_CFG_HEN);
                    }

                    HAL_WriteRegBit(SUB_REG(VOP_REG_MFDEC_2_L),
                                    FALSE,
                                    VOP_ROTATE_EN);

                    HAL_WriteRegBit(SUB_REG(VOP_MPG_JPG_SWITCH),
                                    FALSE,
                                    VOP_422_LINEAR_JMP);
                    g_pHalMVOPCtx->u16SubReg20 &= ~VOP_422_LINEAR_JMP;
                    break;
                }
                case E_MVOP_MF_ROTATE_270:
                {
                    if (TRUE == g_pHalMVOPCtx->bSubMirrorModeVer)
                    {
                        HAL_WriteRegBit(SUB_REG(VOP_MIRROR_CFG),
                                        TRUE,
                                        VOP_MIRROR_CFG_VEN);
                    }
                    else
                    {
                        HAL_WriteRegBit(SUB_REG(VOP_MIRROR_CFG),
                                        FALSE,
                                        VOP_MIRROR_CFG_VEN);
                    }

                    if (TRUE == g_pHalMVOPCtx->bSubMirrorModeHor)
                    {
                        HAL_WriteRegBit(SUB_REG(VOP_MIRROR_CFG),
                                        FALSE,
                                        VOP_MIRROR_CFG_HEN);
                    }
                    else
                    {
                        HAL_WriteRegBit(SUB_REG(VOP_MIRROR_CFG),
                                        TRUE,
                                        VOP_MIRROR_CFG_HEN);
                    }

                    HAL_WriteRegBit(SUB_REG(VOP_REG_MFDEC_2_L),
                                    TRUE,
                                    VOP_ROTATE_EN);

                    if (TRUE == g_pHalMVOPCtx->bSubIs422)
                    {
                        HAL_WriteRegBit(SUB_REG(VOP_MPG_JPG_SWITCH),
                                        TRUE,
                                        VOP_422_LINEAR_JMP);
                        g_pHalMVOPCtx->u16SubReg20 |= VOP_422_LINEAR_JMP;
                    }
                    bRet = TRUE;
                    break;
                }
                default:
                {
                    MVOP_PRINTF("[%s] Not support rotate type: %u\n",
                                __FUNCTION__,
                                eRotate);
                    bRet = FALSE;
                    break;
                }
            }
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_1);
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID: %u\n",
                        __FUNCTION__,
                        eID);
            bRet = FALSE;
            break;
        }
    }
    return bRet;
#else
    UNUSED(eID);
    UNUSED(eRotate);
    MVOP_PRINTF("[%s] Not support rotate on this chip\n", __FUNCTION__);
    return FALSE;
#endif
}

void HAL_MVOP_EnableFODtoWB(MVOP_DevID eID, MS_BOOL bEnable)
{
    UNUSED(eID);
    UNUSED(bEnable);
    return;
}

void HAL_MVOP_SetECONumber(MS_U16 u16ChipRev, MS_U16 u16ChipVer)
{
    if (g_pHalMVOPCtx == NULL)
    {
        MVOP_DBG(MVOP_PRINTF("%s g_pHalMVOPCtx is NULL pointer\n", __FUNCTION__);)
        return;
    }
    g_pHalMVOPCtx->u16ECONum = u16ChipRev;
    UNUSED(u16ChipVer);
}

void HAL_MVOP_MDBRegInputCfg(MVOP_DevID eID, MVOP_InputSel _eInputSel, MVOP_RegInputMdb* stRegInput)
{
    if (MVOP_INPUT_UNKNOWN == _eInputSel)
    {
        return;
    }
    else if ((MVOP_INPUT_DRAM == _eInputSel) || (MVOP_INPUT_DMS_DRAM == _eInputSel) || (MVOP_INPUT_DMS_DRAM_HDR_DV == _eInputSel))
    {
        switch (eID)
        {
            case E_MVOP_DEV_0:
            {
                stRegInput->u32RegYoffset = HAL_Read2Byte(VOP_JPG_YSTR0_L);
                stRegInput->u32RegYoffset |= ((HAL_ReadByte(VOP_JPG_YSTR0_H) << 16) & 0x7fff0000);
                stRegInput->u32RegYoffset = stRegInput->u32RegYoffset << 3; //address 8 byte align
                stRegInput->u32RegUVoffset = HAL_Read2Byte(VOP_JPG_UVSTR0_L);
                stRegInput->u32RegUVoffset |= ((HAL_ReadByte(VOP_JPG_UVSTR0_H) << 16) & 0x7fff0000);
                stRegInput->u32RegUVoffset = stRegInput->u32RegUVoffset << 3;
                stRegInput->u16RegHsize = HAL_Read2Byte(VOP_JPG_HSIZE);
                stRegInput->u16RegVsize = HAL_Read2Byte(VOP_JPG_VSIZE);
                stRegInput->u16RegStrip = HAL_ReadByte(VOP_DC_STRIP);
                stRegInput->bReg422 = (HAL_ReadRegBit(VOP_MPG_JPG_SWITCH, VOP_422_IMG) == VOP_422_IMG);
                stRegInput->bRegPMode = (HAL_ReadRegBit(VOP_MPG_JPG_SWITCH, VOP_PRO_SEQ) == VOP_PRO_SEQ);
                stRegInput->bRegDramContd = (HAL_ReadRegBit(VOP_MPG_JPG_SWITCH, VOP_DRAM_RD_MODE) == VOP_DRAM_RD_MODE);
                stRegInput->bRegField = (HAL_ReadRegBit(VOP_MPG_JPG_SWITCH, VOP_FIELD) == VOP_FIELD);
                stRegInput->bReg422Pack = (HAL_ReadRegBit(VOP_MPG_JPG_SWITCH, VOP_422_PACK) == VOP_422_PACK);
                stRegInput->u8RegDSIndex = HAL_ReadByte(VOP_DS_IDX);
                stRegInput->bRegFDMask = (HAL_ReadRegBit(VOP_SW_FDMASK, VOP_FDMASK) == VOP_FDMASK);
                stRegInput->bRegMfdecEn = (HAL_ReadRegBit(VOP_REG_MFDEC_0_L, VOP_MFDEC_EN) == VOP_MFDEC_EN);
                stRegInput->u32RegBitenAdd = HAL_Read2Byte(VOP_REG_MFDEC_BITADDR_L);
                stRegInput->u32RegBitenAdd |= (HAL_ReadByte((VOP_REG_MFDEC_BITADDR_H)) << 16); //BIT0-31
                stRegInput->u32RegBitenAdd = stRegInput->u32RegBitenAdd << 3;
                stRegInput->bUncompress = (HAL_ReadRegBit(VOP_REG_MFDEC_2_L, VOP_UNCOMP_MODE) == 0) ? 0 : 1;
                break;
            }
#if MVOP_SUPPORT_SUB
            case E_MVOP_DEV_1:
            {
                stRegInput->u32RegYoffset = HAL_Read2Byte(SUB_REG(VOP_JPG_YSTR0_L));
                stRegInput->u32RegYoffset |= ((HAL_ReadByte(SUB_REG(VOP_JPG_YSTR0_H)) << 16) & 0x7fff0000);
                stRegInput->u32RegYoffset = stRegInput->u32RegYoffset << 3; //address 8 byte align
                stRegInput->u32RegUVoffset = HAL_Read2Byte(SUB_REG(VOP_JPG_UVSTR0_L));
                stRegInput->u32RegUVoffset |= ((HAL_ReadByte(SUB_REG(VOP_JPG_UVSTR0_H)) << 16) & 0x7fff0000);
                stRegInput->u32RegUVoffset = stRegInput->u32RegUVoffset << 3;
                stRegInput->u16RegHsize = HAL_Read2Byte(SUB_REG(VOP_JPG_HSIZE));
                stRegInput->u16RegVsize = HAL_Read2Byte(SUB_REG(VOP_JPG_VSIZE));
                stRegInput->u16RegStrip = HAL_ReadByte(SUB_REG(VOP_DC_STRIP));
                stRegInput->bReg422 = (HAL_ReadRegBit(SUB_REG(VOP_MPG_JPG_SWITCH), VOP_422_IMG) == VOP_422_IMG);
                stRegInput->bRegPMode = (HAL_ReadRegBit(SUB_REG(VOP_MPG_JPG_SWITCH), VOP_PRO_SEQ) == VOP_PRO_SEQ);
                stRegInput->bRegDramContd = (HAL_ReadRegBit(SUB_REG(VOP_MPG_JPG_SWITCH), VOP_DRAM_RD_MODE) == VOP_DRAM_RD_MODE);
                stRegInput->bRegField = (HAL_ReadRegBit(SUB_REG(VOP_MPG_JPG_SWITCH), VOP_FIELD) == VOP_FIELD);
                stRegInput->bReg422Pack = (HAL_ReadRegBit(SUB_REG(VOP_MPG_JPG_SWITCH), VOP_422_PACK) == VOP_422_PACK);
                stRegInput->u8RegDSIndex = HAL_ReadByte(SUB_REG(VOP_DS_IDX));
                stRegInput->bRegFDMask = (HAL_ReadRegBit(SUB_REG(VOP_SW_FDMASK), VOP_FDMASK) == VOP_FDMASK);
                stRegInput->bRegMfdecEn = (HAL_ReadRegBit(SUB_REG(VOP_REG_MFDEC_0_L), VOP_MFDEC_EN) == VOP_MFDEC_EN);
                stRegInput->u32RegBitenAdd = HAL_Read2Byte(SUB_REG(VOP_REG_MFDEC_BITADDR_L));
                stRegInput->u32RegBitenAdd |= (HAL_ReadByte(SUB_REG(VOP_REG_MFDEC_BITADDR_H)) << 16); //BIT0-31
                stRegInput->u32RegBitenAdd = stRegInput->u32RegBitenAdd << 3;
                stRegInput->bUncompress = (HAL_ReadRegBit(SUB_REG(VOP_REG_MFDEC_2_L), VOP_UNCOMP_MODE) == 0) ? 0 : 1;
                break;
            }
#endif
            default:
                break;
        }
    }
    else //mvop hardwire mode
    {
        switch (eID)
        {
            case E_MVOP_DEV_0:
            {
                //reg_riu_debug_sel = 1
                HAL_WriteByteMask(VOP_DEBUG_2F_H, VOP_DBG_SEL1, VOP_RIU_DEBUG_SEL);
                stRegInput->u32RegYoffset = HAL_Read2Byte(VOP_DEBUG_2A);
                stRegInput->u32RegYoffset |= ((HAL_ReadByte((VOP_DEBUG_2B)) << 16) & 0x7fff0000);
                stRegInput->u32RegYoffset = stRegInput->u32RegYoffset << 3; //address 8 byte align
                stRegInput->u32RegUVoffset = HAL_Read2Byte(VOP_DEBUG_2C);
                stRegInput->u32RegUVoffset |= ((HAL_ReadByte((VOP_DEBUG_2D)) << 16) & 0x7fff0000);
                stRegInput->u32RegUVoffset = stRegInput->u32RegUVoffset << 3;
                stRegInput->u16RegHsize = HAL_Read2Byte(VOP_DEBUG_2E);
                stRegInput->u16RegVsize = (HAL_Read2Byte(VOP_DEBUG_2F_L) & 0x1ff);
                //reg_riu_debug_sel = 2
                HAL_WriteByteMask(VOP_DEBUG_2F_H, VOP_DBG_SEL2, VOP_RIU_DEBUG_SEL);
                stRegInput->u16RegStrip = HAL_Read2Byte(VOP_DEBUG_2E) & 0x7ff; //bit 0-9
                stRegInput->bReg422 = (HAL_ReadRegBit(VOP_MPG_JPG_SWITCH, VOP_422_PACK) == VOP_422_PACK); //cannot get from wb
                stRegInput->bRegPMode = (HAL_ReadRegBit((VOP_DEBUG_2E + 1), BIT3) == BIT3);
                stRegInput->bRegDramContd = (HAL_ReadRegBit(VOP_MPG_JPG_SWITCH, VOP_DRAM_RD_MODE) == VOP_DRAM_RD_MODE);//cannot get from wb
                stRegInput->bRegField = (HAL_ReadRegBit((VOP_DEBUG_2E + 1), BIT4) == BIT4);
                stRegInput->bReg422Pack = (HAL_ReadRegBit(VOP_MPG_JPG_SWITCH, VOP_422_PACK) == VOP_422_PACK);//cannot get from wb
                stRegInput->u8RegDSIndex = HAL_ReadByte(VOP_DEBUG_2F_L);
                stRegInput->bRegFDMask = (HAL_ReadRegBit((VOP_DEBUG_2E + 1), BIT5) == BIT5);
                //reg_riu_debug_sel = 6
                HAL_WriteByteMask(VOP_DEBUG_2F_H, VOP_DBG_SEL6, VOP_RIU_DEBUG_SEL);
                stRegInput->bRegMfdecEn = (HAL_ReadRegBit(VOP_DEBUG_2C, BIT2) == BIT2);
                stRegInput->u32RegBitenAdd = HAL_Read2Byte(VOP_DEBUG_2D);
                stRegInput->u32RegBitenAdd |= (HAL_ReadByte((VOP_DEBUG_2E)) << 16); //BIT0-31
                stRegInput->u32RegBitenAdd = stRegInput->u32RegBitenAdd << 3;
                HAL_WriteByteMask(VOP_DEBUG_2F_H, VOP_DBG_SEL0, VOP_RIU_DEBUG_SEL); //RESET
                stRegInput->bUncompress = (HAL_ReadRegBit(VOP_REG_MFDEC_2_L, VOP_UNCOMP_MODE) == 0) ? 0 : 1;
                break;
            }
#if MVOP_SUPPORT_SUB
            case E_MVOP_DEV_1:
            {
                //reg_riu_debug_sel = 1
                HAL_WriteByteMask(SUB_REG(VOP_DEBUG_2F_H), VOP_DBG_SEL1, VOP_RIU_DEBUG_SEL);
                stRegInput->u32RegYoffset = HAL_Read2Byte(SUB_REG(VOP_DEBUG_2A));
                stRegInput->u32RegYoffset |= ((HAL_ReadByte(SUB_REG(VOP_DEBUG_2B)) << 16) & 0x7fff0000);
                stRegInput->u32RegYoffset = stRegInput->u32RegYoffset << 3; //address 8 byte align
                stRegInput->u32RegUVoffset = HAL_Read2Byte(SUB_REG(VOP_DEBUG_2C));
                stRegInput->u32RegUVoffset |= ((HAL_ReadByte(SUB_REG(VOP_DEBUG_2D)) << 16) & 0x7fff0000);
                stRegInput->u32RegUVoffset = stRegInput->u32RegUVoffset << 3;
                stRegInput->u16RegHsize = HAL_Read2Byte(SUB_REG(VOP_DEBUG_2E));
                stRegInput->u16RegVsize = (HAL_Read2Byte(SUB_REG(VOP_DEBUG_2F_L)) & 0x1ff);
                //reg_riu_debug_sel = 2
                HAL_WriteByteMask(SUB_REG(VOP_DEBUG_2F_H), VOP_DBG_SEL2, VOP_RIU_DEBUG_SEL);
                stRegInput->u16RegStrip = HAL_Read2Byte(SUB_REG(VOP_DEBUG_2E)) & 0x7ff; //bit 0-9
                stRegInput->bReg422 = (HAL_ReadRegBit(SUB_REG(VOP_MPG_JPG_SWITCH), VOP_422_PACK) == VOP_422_PACK); //cannot get from wb
                stRegInput->bRegPMode = (HAL_ReadRegBit(SUB_REG(VOP_DEBUG_2E + 1), BIT3) == BIT3);
                stRegInput->bRegDramContd = (HAL_ReadRegBit(SUB_REG(VOP_MPG_JPG_SWITCH), VOP_DRAM_RD_MODE) == VOP_DRAM_RD_MODE);//cannot get from wb
                stRegInput->bRegField = (HAL_ReadRegBit(SUB_REG(VOP_DEBUG_2E + 1), BIT4) == BIT4);
                stRegInput->bReg422Pack = (HAL_ReadRegBit(SUB_REG(VOP_MPG_JPG_SWITCH), VOP_422_PACK) == VOP_422_PACK);//cannot get from wb
                stRegInput->u8RegDSIndex = HAL_ReadByte(SUB_REG(VOP_DEBUG_2F_L));
                stRegInput->bRegFDMask = (HAL_ReadRegBit(SUB_REG(VOP_DEBUG_2E + 1), BIT5) == BIT5);
                //reg_riu_debug_sel = 6
                HAL_WriteByteMask(SUB_REG(VOP_DEBUG_2F_H), VOP_DBG_SEL6, VOP_RIU_DEBUG_SEL);
                stRegInput->bRegMfdecEn = (HAL_ReadRegBit(SUB_REG(VOP_DEBUG_2C), BIT2) == BIT2);
                stRegInput->u32RegBitenAdd = HAL_Read2Byte(SUB_REG(VOP_DEBUG_2D));
                stRegInput->u32RegBitenAdd |= (HAL_ReadByte(SUB_REG(VOP_DEBUG_2E)) << 16); //BIT0-31
                stRegInput->u32RegBitenAdd = stRegInput->u32RegBitenAdd << 3;
                HAL_WriteByteMask(SUB_REG(VOP_DEBUG_2F_H), VOP_DBG_SEL0, VOP_RIU_DEBUG_SEL); //RESET
                stRegInput->bUncompress = (HAL_ReadRegBit(SUB_REG(VOP_REG_MFDEC_2_L), VOP_UNCOMP_MODE) == 0) ? 0 : 1;
                break;
            }
#endif
            default:
                break;
        }
    }
}

void HAL_MVOP_MDBRegOutputCfg(MVOP_DevID eID, MVOP_RegOutputMdb* stRegOutput)
{
    MS_U16 u16Vblk;
    MS_U16 u16Hblk;
    MS_U16 u16Num;
    MS_U16 u16Den;
    MS_U64 u64Clock;
    MS_U64 u64FrameSize;

    switch (eID)
    {
        case E_MVOP_DEV_0:
        {
            stRegOutput->u32RegVtt = HAL_Read2Byte(VOP_FRAME_VCOUNT);
            stRegOutput->u32RegHtt = HAL_Read2Byte(VOP_FRAME_HCOUNT);
            stRegOutput->u16RegVImgst = HAL_Read2Byte(VOP_IMG_VSTR0);
            stRegOutput->u16RegHImgst = HAL_Read2Byte(VOP_IMG_HSTR);
            stRegOutput->bRegInterlace = (HAL_ReadRegBit(VOP_CTRL0, BIT7) == BIT7);
            stRegOutput->enRegCLOCK = HAL_MVOP_GetCurrentClk(E_MVOP_DEV_0);

            if (E_MVOP_SYNCMODE == stRegOutput->enRegCLOCK)
            {
                u16Num = HAL_Read2Byte(REG_DC0_NUM);
                u16Den = HAL_Read2Byte(REG_DC0_DEN);
                stRegOutput->u32SyncClockVal = (u16Den == 0) ? 0 : (MS_U32)((MVOP_SYNC_CLOCK_BASE / u16Den) * u16Num);
                u64Clock = stRegOutput->u32SyncClockVal;
            }
            else
            {
                u64Clock = HAL_MVOP_GetHardwareClock(eID, stRegOutput->enRegCLOCK);
            }

            u64FrameSize = (MS_U64)stRegOutput->u32RegVtt * stRegOutput->u32RegHtt;
            if (u64FrameSize == 0)
            {
                stRegOutput->u8RegFPS = 0;
                stRegOutput->u16RegExpFPS = 0;
            }
            else
            {
                stRegOutput->u8RegFPS = u64Clock / u64FrameSize;
                stRegOutput->u16RegExpFPS = u64Clock * 1000 / u64FrameSize;
            }

            u16Vblk = (HAL_Read2Byte(VOP_VB0_END) - HAL_Read2Byte(VOP_VB0_STR)) + (HAL_Read2Byte(VOP_VB1_END) - HAL_Read2Byte(VOP_VB1_STR));
            u16Hblk = HAL_Read2Byte(VOP_IMG_HSTR);
            stRegOutput->u16RegWidth = stRegOutput->u32RegHtt - u16Hblk;
            stRegOutput->u16RegHeight = stRegOutput->u32RegVtt - u16Vblk;
            stRegOutput->bRegHDup = (HAL_ReadRegBit(VOP_CTRL0, VOP_HDUP) == VOP_HDUP);
            stRegOutput->bReg2P = (HAL_ReadRegBit(VOP_REG_4K2K_2P, VOP_4K2K_2P) == VOP_4K2K_2P);
            stRegOutput->u16RegVsForward = (HAL_ReadRegBit(VOP_CTRL1, VOP_MVD_VS_MD) == VOP_MVD_VS_MD) ? (HAL_Read2Byte(VOP_FRAME_VCOUNT) - HAL_Read2Byte(VOP_TF_VS_MVD)) : 0;
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            stRegOutput->u32RegVtt = HAL_Read2Byte(SUB_REG(VOP_FRAME_VCOUNT));
            stRegOutput->u32RegHtt = HAL_Read2Byte(SUB_REG(VOP_FRAME_HCOUNT));
            stRegOutput->u16RegVImgst = HAL_Read2Byte(SUB_REG(VOP_IMG_VSTR0));
            stRegOutput->u16RegHImgst = HAL_Read2Byte(SUB_REG(VOP_IMG_HSTR));
            stRegOutput->bRegInterlace = (HAL_ReadRegBit(SUB_REG(VOP_CTRL0), BIT7) == BIT7);
            stRegOutput->enRegCLOCK = HAL_MVOP_GetCurrentClk(E_MVOP_DEV_1);

            if (E_MVOP_SYNCMODE == stRegOutput->enRegCLOCK)
            {
                u16Num = HAL_Read2Byte(REG_DC1_NUM);
                u16Den = HAL_Read2Byte(REG_DC1_DEN);
                stRegOutput->u32SyncClockVal = (u16Den == 0) ? 0 : (MS_U32)((MVOP_SYNC_CLOCK_BASE / u16Den) * u16Num);
                u64Clock = stRegOutput->u32SyncClockVal;
            }
            else
            {
                u64Clock = stRegOutput->enRegCLOCK;
            }

            u64FrameSize = (MS_U64)stRegOutput->u32RegVtt * stRegOutput->u32RegHtt;
            if (u64FrameSize == 0)
            {
                stRegOutput->u8RegFPS = 0;
                stRegOutput->u16RegExpFPS = 0;
            }
            else
            {
                stRegOutput->u8RegFPS = u64Clock / u64FrameSize;
                stRegOutput->u16RegExpFPS = u64Clock * 1000 / u64FrameSize;
            }

            u16Vblk = (HAL_Read2Byte(SUB_REG(VOP_VB0_END)) - HAL_Read2Byte(SUB_REG(VOP_VB0_STR)))
                      + (HAL_Read2Byte(SUB_REG(VOP_VB1_END)) - HAL_Read2Byte(SUB_REG(VOP_VB1_STR)));
            u16Hblk = HAL_Read2Byte(SUB_REG(VOP_IMG_HSTR));
            stRegOutput->u16RegWidth = stRegOutput->u32RegHtt - u16Hblk;
            stRegOutput->u16RegHeight = stRegOutput->u32RegVtt - u16Vblk;
            stRegOutput->bRegHDup = (HAL_ReadRegBit(SUB_REG(VOP_CTRL0), VOP_HDUP) == VOP_HDUP);
            stRegOutput->bReg2P = (HAL_ReadRegBit(SUB_REG(VOP_REG_4K2K_2P), VOP_4K2K_2P) == VOP_4K2K_2P);
            stRegOutput->u16RegVsForward = (HAL_ReadRegBit(SUB_REG(VOP_CTRL1), VOP_MVD_VS_MD) == VOP_MVD_VS_MD) ? (HAL_Read2Byte(SUB_REG(VOP_FRAME_VCOUNT)) - HAL_Read2Byte(SUB_REG(VOP_TF_VS_MVD))) : 0;
            break;
        }
#endif
        default:
            break;
    }
}

void HAL_MVOP_MDBRegFeature(MVOP_DevID eID, MVOP_FeatureMdb* pstFeature)
{
    MS_U64 u64Clock;
    MS_U32 u32Vtt;
    MS_U32 u32Htt;
    MS_U64 u64FrameSize;
    MS_BOOL bisMfdecEnable;
    MS_U8 u8Mirror = 0;

    switch (eID)
    {
        case E_MVOP_DEV_0:
        {
            u8Mirror = HAL_ReadRegBit(VOP_MIRROR_CFG, VOP_MIRROR_CFG_HEN) \
                       + (HAL_ReadRegBit(VOP_MIRROR_CFG, VOP_MIRROR_CFG_VEN) == VOP_MIRROR_CFG_VEN);
            pstFeature->enMirror = (u8Mirror == 0) ? E_VOPMIRROR_NONE : (MVOP_DrvMirror)u8Mirror;
            if (HAL_ReadRegBit(VOP_MULTI_WIN_CFG0, VOP_LR_BUF_MODE) == VOP_LR_BUF_MODE)
            {
                if (HAL_ReadRegBit(VOP_MULTI_WIN_CFG0, VOP_LR_LA_OUT) == VOP_LR_LA_OUT)
                {
                    if (HAL_ReadRegBit(VOP_MULTI_WIN_CFG0, VOP_LR_LA2SBS_OUT) == VOP_LR_LA2SBS_OUT)
                        pstFeature->en3D = E_MVOP_OUTPUT_3D_SBS;
                    else
                        pstFeature->en3D = E_MVOP_OUTPUT_3D_LA;
                }
                else
                {
                    pstFeature->en3D = E_MVOP_OUTPUT_3D_TB;
                }
            }
            else
            {
                pstFeature->en3D = E_MVOP_OUTPUT_3D_NONE;
            }
            pstFeature->bHSK = (HAL_ReadRegBit(VOP_REG_HS_OUTPUT, VOP_HS_MODE) == VOP_HS_MODE);
            pstFeature->bXCGenTiming = (0 == (HAL_ReadByte(VOP_REG_HS_OUTPUT) & 0x06)) ? 0 : 1;
            pstFeature->stCropSt.u16Xpos = HAL_Read2Byte(VOP_REG_CROP_HSTART) & SizeMask;
            pstFeature->stCropSt.u16Ypos = HAL_Read2Byte(VOP_REG_CROP_VSTART) & SizeMask;
            pstFeature->stCropSize.u16Width = HAL_Read2Byte(VOP_REG_CROP_HSIZE) & SizeMask;
            pstFeature->stCropSize.u16Height = HAL_Read2Byte(VOP_REG_CROP_VSIZE) & SizeMask;
            pstFeature->bOneField = 0; //not support one field in tv chip.
            pstFeature->b2P = (HAL_ReadRegBit(VOP_REG_4K2K_2P, VOP_4K2K_2P) == VOP_4K2K_2P);
            u64Clock = HAL_MVOP_GetHardwareClock(eID, HAL_MVOP_GetCurrentClk(E_MVOP_DEV_0));
            u32Vtt = HAL_Read2Byte(VOP_FRAME_VCOUNT);
            u32Htt = HAL_Read2Byte(VOP_FRAME_HCOUNT);
            u64FrameSize = (MS_U64)u32Vtt * u32Htt;
            pstFeature->u32Framerate = (u64FrameSize == 0) ? 0 : (u64Clock / u64FrameSize);
            pstFeature->b422YUVOutput = (HAL_ReadRegBit(VOP_REG_YC422_EN_H, VOP_422_OUT_EN) == VOP_422_OUT_EN);
            pstFeature->u8DMAThreshold = HAL_ReadByte(VOP_DMA0) & VOP_DMA_THD;
            pstFeature->u8DMABurstLen = HAL_ReadByte(VOP_DMA1) & VOP_BURST_EXT;
            bisMfdecEnable = (HAL_ReadRegBit(VOP_REG_MFDEC_0_L, VOP_MFDEC_EN) == VOP_MFDEC_EN);
            pstFeature->u8MFDECBurstLen = bisMfdecEnable ? ((HAL_ReadByte(VOP_REG_MFDEC_0_L) & (VOP_MF0_BURST | VOP_MF1_BURST)) >> 4) : 0;
            pstFeature->bIsEnLSB = g_pHalMVOPCtx->bIsEnLSB;
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            u8Mirror = HAL_ReadRegBit(SUB_REG(VOP_MIRROR_CFG), VOP_MIRROR_CFG_HEN) \
                       + (HAL_ReadRegBit(SUB_REG(VOP_MIRROR_CFG), VOP_MIRROR_CFG_VEN) == VOP_MIRROR_CFG_VEN);
            pstFeature->enMirror = (u8Mirror == 0) ? E_VOPMIRROR_NONE : (MVOP_DrvMirror)u8Mirror;
            if (HAL_ReadRegBit(SUB_REG(VOP_MULTI_WIN_CFG0), VOP_LR_BUF_MODE) == VOP_LR_BUF_MODE)
            {
                if (HAL_ReadRegBit(SUB_REG(VOP_MULTI_WIN_CFG0), VOP_LR_LA_OUT) == VOP_LR_LA_OUT)
                {
                    if (HAL_ReadRegBit(SUB_REG(VOP_MULTI_WIN_CFG0), VOP_LR_LA2SBS_OUT) == VOP_LR_LA2SBS_OUT)
                        pstFeature->en3D = E_MVOP_OUTPUT_3D_SBS;
                    else
                        pstFeature->en3D = E_MVOP_OUTPUT_3D_LA;
                }
                else
                {
                    pstFeature->en3D = E_MVOP_OUTPUT_3D_TB;
                }
            }
            else
            {
                pstFeature->en3D = E_MVOP_OUTPUT_3D_NONE;
            }
            pstFeature->bHSK = (HAL_ReadRegBit(SUB_REG(VOP_REG_HS_OUTPUT), VOP_HS_MODE) == VOP_HS_MODE);
            pstFeature->bXCGenTiming = (0 == (HAL_ReadByte(SUB_REG(VOP_REG_HS_OUTPUT)) & 0x06)) ? 0 : 1;
            pstFeature->stCropSt.u16Xpos = HAL_Read2Byte(SUB_REG(VOP_REG_CROP_HSTART)) & SizeMask;
            pstFeature->stCropSt.u16Ypos = HAL_Read2Byte(SUB_REG(VOP_REG_CROP_VSTART)) & SizeMask;
            pstFeature->stCropSize.u16Width = HAL_Read2Byte(SUB_REG(VOP_REG_CROP_HSIZE)) & SizeMask;
            pstFeature->stCropSize.u16Height = HAL_Read2Byte(SUB_REG(VOP_REG_CROP_VSIZE)) & SizeMask;
            pstFeature->bOneField = 0; //not support one field in tv chip.
            pstFeature->b2P = (HAL_ReadRegBit(SUB_REG(VOP_REG_4K2K_2P), VOP_4K2K_2P) == VOP_4K2K_2P);
            u64Clock = HAL_MVOP_GetHardwareClock(eID, HAL_MVOP_GetCurrentClk(E_MVOP_DEV_1));
            u32Vtt = HAL_Read2Byte(SUB_REG(VOP_FRAME_VCOUNT));
            u32Htt = HAL_Read2Byte(SUB_REG(VOP_FRAME_HCOUNT));
            u64FrameSize = (MS_U64)u32Vtt * u32Htt;
            pstFeature->u32Framerate = (u64FrameSize == 0) ? 0 : (u64Clock / u64FrameSize);
            pstFeature->b422YUVOutput = (HAL_ReadRegBit(SUB_REG(VOP_REG_YC422_EN_H), VOP_422_OUT_EN) == VOP_422_OUT_EN);
            pstFeature->u8DMAThreshold = HAL_ReadByte(SUB_REG(VOP_DMA0)) & VOP_DMA_THD;
            pstFeature->u8DMABurstLen = HAL_ReadByte(SUB_REG(VOP_DMA1)) & VOP_BURST_EXT;
            bisMfdecEnable = (HAL_ReadRegBit(SUB_REG(VOP_REG_MFDEC_0_L), VOP_MFDEC_EN) == VOP_MFDEC_EN);
            pstFeature->u8MFDECBurstLen = bisMfdecEnable ? ((HAL_ReadByte(SUB_REG(VOP_REG_MFDEC_0_L)) & (VOP_MF0_BURST | VOP_MF1_BURST)) >> 4) : 0;
            pstFeature->bIsEnLSB = g_pHalMVOPCtx->bSubIsEnLSB;
            break;
        }
#endif
        default:
            break;
    }
}

MS_BOOL HAL_MVOP_Get2PMode(MVOP_DevID eDevID)
{
    MS_BOOL bRet = FALSE;
    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            bRet = g_pHalMVOPCtx->bIs2p;
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            bRet = g_pHalMVOPCtx->bSubIs2p;
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
    return bRet;
}

void HAL_MVOP_GetCropInfo(MVOP_DevID eID, MVOP_SetCropPos* stCropStart, MVOP_SetImageWH* stCropSize)
{
    switch (eID)
    {
        case E_MVOP_DEV_0:
            stCropStart->u16Xpos = g_pHalMVOPCtx->u16CropXStart;
            stCropStart->u16Ypos = g_pHalMVOPCtx->u16CropYStart;
            stCropSize->u16Width = g_pHalMVOPCtx->u16CropXSize;
            stCropSize->u16Height = g_pHalMVOPCtx->u16CropYSize;
            break;
        case E_MVOP_DEV_1:
#if MVOP_SUPPORT_SUB
            stCropStart->u16Xpos = g_pHalMVOPCtx->u16SubCropXStart;
            stCropStart->u16Ypos = g_pHalMVOPCtx->u16SubCropYStart;
            stCropSize->u16Width = g_pHalMVOPCtx->u16SubCropXSize;
            stCropSize->u16Height = g_pHalMVOPCtx->u16SubCropYSize;
#endif
            break;
        default:
            break;
    }
}

MS_BOOL HAL_MVOP_GetDCClkIsOn(MVOP_DevID eID)
{
    MS_BOOL bIsDisable = FALSE;

    bIsDisable = (CKG_DC0_GATED == HAL_ReadRegBit(REG_CKG_DC0, CKG_DC0_GATED));
    return !(bIsDisable);
}

void HAL_MVOP_MDBSetVsyncFwdLine(MS_U64* pu64ReqHdl, MVOP_DevID eID, MS_U32 u32VsyncLines)
{
    MS_U16 u16VTT = 0;
    MS_U16 u16BotVS = 0;

    if (g_pHalMVOPCtx == NULL)
    {
        MVOP_DBG(MVOP_PRINTF("%s g_pHalMVOPCtx is NULL pointer\n", __FUNCTION__);)
        return;
    }

    switch (eID)
    {
        case E_MVOP_DEV_0:
        {
            if (TRUE == HAL_MVOP_GetDCClkIsOn(E_MVOP_DEV_0))
            {
                HAL_MVOP_Enable(E_MVOP_DEV_0, FALSE);
                u16VTT = HAL_Read2Byte(VOP_FRAME_VCOUNT);

                /* i mode */
                if (VOP_FLD_MD == HAL_ReadRegBit(VOP_CTRL0, VOP_FLD_MD))
                {
                    u16BotVS = HAL_Read2Byte(VOP_BF_VS);
                    HAL_Write2Byte(VOP_BF_VS_MVD, (u16BotVS - u32VsyncLines));
                }
                HAL_Write2Byte(VOP_TF_VS_MVD, (u16VTT - u32VsyncLines));
                HAL_WriteRegBit(VOP_CTRL1, ENABLE, VOP_MVD_VS_MD);
                HAL_MVOP_LoadReg(E_MVOP_DEV_0);
                HAL_MVOP_ForceWriteReg(E_MVOP_DEV_0);
                HAL_MVOP_Enable(E_MVOP_DEV_0, TRUE);
            }
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            if (TRUE == HAL_MVOP_GetDCClkIsOn(E_MVOP_DEV_1))
            {
                HAL_MVOP_Enable(E_MVOP_DEV_1, FALSE);
                u16VTT = HAL_Read2Byte(SUB_REG(VOP_FRAME_VCOUNT));

                if (VOP_FLD_MD == HAL_ReadRegBit(SUB_REG(VOP_CTRL0), VOP_FLD_MD)) //i mode
                {
                    u16BotVS = HAL_Read2Byte(SUB_REG(VOP_BF_VS));
                    HAL_Write2Byte(SUB_REG(VOP_BF_VS_MVD), (u16BotVS - u32VsyncLines));
                }
                HAL_Write2Byte(SUB_REG(VOP_TF_VS_MVD), (u16VTT - u32VsyncLines));
                HAL_WriteRegBit(SUB_REG(VOP_CTRL1), ENABLE, VOP_MVD_VS_MD);
                HAL_MVOP_LoadReg(E_MVOP_DEV_1);
                HAL_MVOP_ForceWriteReg(E_MVOP_DEV_1);
                HAL_MVOP_Enable(E_MVOP_DEV_1, TRUE);
            }
            break;
        }
#endif
        default:
            break;
    }
}

void HAL_MVOP_SetMFDECInfo(MVOP_DevID eID, HALMVOPMFDECINFO* pMFDECInfo, MS_BOOL bOutputIMode)
{
    MS_PHY u64tmp = 0;
    MS_U16 u16Hsize = 0;
    MS_U16 u16Vsize = 0;
    MS_U16 u16CropH = 0;
    MS_U16 u16CropV = 0;
#if IOMMU_MFDEC_CTRL
    MS_U8 u8BitlenOffset = 0;
#endif
    EN_MVOP_Output_3D_TYPE en3DType = E_MVOP_OUTPUT_3D_NONE;
    switch (eID)
    {
        case E_MVOP_DEV_0:
        {
            u16Hsize = HAL_Read2Byte(VOP_JPG_HSIZE);
            u16Vsize = HAL_Read2Byte(VOP_JPG_VSIZE);
            u16CropH = HAL_Read2Byte(VOP_REG_CROP_HSIZE);
            u16CropV = HAL_Read2Byte(VOP_REG_CROP_VSIZE);
            en3DType = HAL_MVOP_GetOutput3DType(E_MVOP_DEV_0);
#if MFDEC_DB_PATCH
            /* Not support mfdec enable */
            if ((FALSE == pMFDECInfo->bMFDEC_EN)
                /*&& (FALSE == bOutputIMode)*/
                && (E_MVOP_OUTPUT_3D_NONE == en3DType)
                && (FALSE == g_pHalMVOPCtx->bIs422)
                && (E_MVOP_RGB_NONE == g_pHalMVOPCtx->eRgbFmt)
                && (FALSE == g_pHalMVOPCtx->bDramRdContd))
            {
                /*
                * Other tile format not support mfdec + uncompress mode
                * Enable Mfdec for all resolution of 4x2
                */
                if ((E_MVOP_TILE_16x32 == g_pHalMVOPCtx->eTileFormat)
                    || (E_MVOP_TILE_32x16 == g_pHalMVOPCtx->eTileFormat)
                    || (E_MVOP_TILE_COMP_32x16_82PACK == g_pHalMVOPCtx->eTileFormat)
                    || (E_MVOP_TILE_COMP_4x2 == g_pHalMVOPCtx->eTileFormat
                        /* && u16Hsize > fHD_Width */))
                {

                    pMFDECInfo->bMFDEC_EN = TRUE;
                    pMFDECInfo->u32UNCOMPRESS_MODE = TRUE;
                }
            }
#endif

#if MVOP_10B_H128_PATCH
            if ((u16Hsize % 128)
                && (FALSE == pMFDECInfo->bMFDEC_EN)
                && (g_pHalMVOPCtx->bIsEnLSB)
                && (FALSE == g_pHalMVOPCtx->bDramRdContd))
            {
                pMFDECInfo->bMFDEC_EN = TRUE;
                pMFDECInfo->u32UNCOMPRESS_MODE = TRUE;
            }
#endif
#if MFDEC_HSIZE_LIMIT_PATCH
            if ((u16Hsize > FHD_SRAM_SIZE)
                && (FALSE == pMFDECInfo->bMFDEC_EN)
                && (E_MVOP_OUTPUT_3D_NONE == en3DType)
                && (FALSE == g_pHalMVOPCtx->bIs422)
                && (E_MVOP_RGB_NONE == g_pHalMVOPCtx->eRgbFmt)
                && (FALSE == g_pHalMVOPCtx->bDramRdContd))
            {
                pMFDECInfo->bMFDEC_EN = TRUE;
                pMFDECInfo->u32UNCOMPRESS_MODE = TRUE;
            }
#endif
#if SUPPORT_MFDEC_ROTATE
            /* Mfdec need to be enabled for MfdecRotate */
            if ((E_MVOP_MF_ROTATE_90 == g_pHalMVOPCtx->eRotate)
                || (E_MVOP_MF_ROTATE_270 == g_pHalMVOPCtx->eRotate))
            {
                if (FALSE == pMFDECInfo->bMFDEC_EN)
                {
                    pMFDECInfo->bMFDEC_EN = TRUE;
                    pMFDECInfo->u32UNCOMPRESS_MODE = TRUE;
                }
            }
#endif

            if (TRUE == pMFDECInfo->bMFDEC_EN)
            {
                HAL_WriteRegBit(VOP_REG_MFDEC_0_L, TRUE, VOP_MFDEC_EN); // enable mfdec
                if (pMFDECInfo->u8MFDEC_ID >= HAL_MFDEC_MODULE_CNT)
                {
                    MVOP_PRINTF("[MVOP][ERR] not support mfdec id: %d\n", pMFDECInfo->u8MFDEC_ID);
                }
                else
                {
                    HAL_WriteRegBit(VOP_REG_MFDEC_0_L, pMFDECInfo->u8MFDEC_ID, VOP_MFDEC_SEL); //select 0/1 mfdec
                }
                u64tmp = pMFDECInfo->u32BITLEN_FB_ADDR >> 3;
                HAL_WriteByteMask(VOP_REG_MFDEC_2_L, ((MS_U64)pMFDECInfo->u32UNCOMPRESS_MODE << 4), VOP_UNCOMP_MODE);
                HAL_Write2Byte(VOP_REG_MFDEC_BITADDR_L, u64tmp & 0xffff);
                HAL_Write2Byte(VOP_REG_MFDEC_BITADDR_H, (u64tmp >> 16) & 0x7ff);
                HAL_WriteByteMask(VOP_REG_MFDEC_2_L, (pMFDECInfo->u8BITLEN_FB_MIU << 2), VOP_BIT_MIU_SEL);
                HAL_WriteByte(VOP_REG_MFDEC_BIT_PITCH, pMFDECInfo->u32BITLEN_FB_PITCH);
                HAL_WriteRegBit(VOP_REG_MFDEC_5E, pMFDECInfo->bBITLEN_SHT_8, VOP_BITLEN_SHT);
#if IOMMU_MFDEC_CTRL
                if ((MS_U64)pMFDECInfo->u32BITLEN_FB_ADDR > ADDRESS_4GB)
                {
                    u8BitlenOffset = (MS_U8)(pMFDECInfo->u32BITLEN_FB_ADDR >> 30);
                    HAL_WriteByteMask(REG_MVOP_DMA_REQ_LEN_H, u8BitlenOffset, MVOP_BITLEN_OFFSET);
                }
#endif
                if (TRUE == pMFDECInfo->u32UNCOMPRESS_MODE)
                {
                    // Reset AV1 settings for Mfdec
                    HAL_WriteRegBit(REG_MFD_AV1, FALSE, MVOP_AV1_MODE);
                    HAL_WriteRegBit(REG_MFD_AV1, FALSE, MVOP_ALLOW_INTRABC);
                }
                else
                {
                    HAL_WriteRegBit(VOP_INPUT_SWITCH0, FALSE, VOP_NEW_EVD_EN);
                    //compress mode can not change data size for miu hit
                    if (u16Hsize < u16CropH)
                    {
                        HAL_Write2Byte(VOP_REG_CROP_HSIZE, u16Hsize);
                        g_pHalMVOPCtx->u16CropXSize = u16Hsize;
                    }

                    if (u16Vsize < u16CropV)
                    {
                        HAL_Write2Byte(VOP_REG_CROP_VSIZE, u16Vsize);
                        g_pHalMVOPCtx->u16CropYSize = u16Vsize;
                    }

                    // AV1 settings for Mfdec
                    HAL_WriteRegBit(REG_MFD_AV1, pMFDECInfo->bAV1Mode, MVOP_AV1_MODE);
                    HAL_WriteRegBit(REG_MFD_AV1, pMFDECInfo->bAllowIntrabc, MVOP_ALLOW_INTRABC);
                }
            }
            else
            {
                // Disable mfdec
                HAL_WriteRegBit(VOP_REG_MFDEC_0_L, FALSE, VOP_MFDEC_EN);

                // Reset AV1 settings for Mfdec
                HAL_WriteRegBit(REG_MFD_AV1, FALSE, MVOP_AV1_MODE);
                HAL_WriteRegBit(REG_MFD_AV1, FALSE, MVOP_ALLOW_INTRABC);
            }
#if GOP_BACKPORCH_PATCH
            g_pHalMVOPCtx->bIsUnComp = pMFDECInfo->u32UNCOMPRESS_MODE;
#endif
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_0);
        }
        break;
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            u16Hsize = HAL_Read2Byte(SUB_REG(VOP_JPG_HSIZE));
            u16Vsize = HAL_Read2Byte(SUB_REG(VOP_JPG_VSIZE));
            u16CropH = HAL_Read2Byte(SUB_REG(VOP_REG_CROP_HSIZE));
            u16CropV = HAL_Read2Byte(SUB_REG(VOP_REG_CROP_VSIZE));
#if MVOP_10B_H128_PATCH
            u16Hsize = HAL_Read2Byte(SUB_REG(VOP_JPG_HSIZE));
            if ((u16Hsize % 128)
                && (FALSE == pMFDECInfo->bMFDEC_EN)
                && (g_pHalMVOPCtx->bSubIsEnLSB)
                && (FALSE == g_pHalMVOPCtx->bSubDramRdContd))
            {
                pMFDECInfo->bMFDEC_EN = TRUE;
                pMFDECInfo->u32UNCOMPRESS_MODE = TRUE;
            }
#endif
#if SUPPORT_MFDEC_ROTATE
            /* Mfdec need to be enabled for MfdecRotate */
            if ((E_MVOP_MF_ROTATE_90 == g_pHalMVOPCtx->eSubRotate)
                || (E_MVOP_MF_ROTATE_270 == g_pHalMVOPCtx->eSubRotate))
            {
                if (FALSE == pMFDECInfo->bMFDEC_EN)
                {
                    pMFDECInfo->bMFDEC_EN = TRUE;
                    pMFDECInfo->u32UNCOMPRESS_MODE = TRUE;
                }
            }
#endif

            if (TRUE == pMFDECInfo->bMFDEC_EN)
            {
                HAL_WriteRegBit(SUB_REG(VOP_REG_MFDEC_0_L), TRUE, VOP_MFDEC_EN); // enable mfdec
                if (pMFDECInfo->u8MFDEC_ID >= HAL_MFDEC_MODULE_CNT)
                {
                    MVOP_PRINTF("[MVOP][ERR] not support mfdec id: %d\n", pMFDECInfo->u8MFDEC_ID);
                }
                else
                {
                    HAL_WriteRegBit(SUB_REG(VOP_REG_MFDEC_0_L), pMFDECInfo->u8MFDEC_ID, VOP_MFDEC_SEL); //select 0/1 mfdec
                }
                u64tmp = pMFDECInfo->u32BITLEN_FB_ADDR >> 3;
                HAL_WriteByteMask(SUB_REG(VOP_REG_MFDEC_2_L), ((MS_U64)pMFDECInfo->u32UNCOMPRESS_MODE << 4), VOP_UNCOMP_MODE);
                HAL_Write2Byte(SUB_REG(VOP_REG_MFDEC_BITADDR_L), u64tmp & 0xffff);
                HAL_Write2Byte(SUB_REG(VOP_REG_MFDEC_BITADDR_H), (u64tmp >> 16) & 0x7ff);
                HAL_WriteByteMask(SUB_REG(VOP_REG_MFDEC_2_L), (pMFDECInfo->u8BITLEN_FB_MIU << 2), VOP_BIT_MIU_SEL);
                HAL_WriteByte(SUB_REG(VOP_REG_MFDEC_BIT_PITCH), pMFDECInfo->u32BITLEN_FB_PITCH);
                HAL_WriteRegBit(SUB_REG(VOP_REG_MFDEC_5E), pMFDECInfo->bBITLEN_SHT_8, VOP_BITLEN_SHT);
                if (FALSE == pMFDECInfo->u32UNCOMPRESS_MODE)
                {
                    HAL_WriteRegBit(SUB_REG(VOP_INPUT_SWITCH0), FALSE, VOP_NEW_EVD_EN);
                    //compress mode can not change data size for miu hit
                    if (u16Hsize < u16CropH)
                    {
                        HAL_Write2Byte(SUB_REG(VOP_REG_CROP_HSIZE), u16Hsize);
                        g_pHalMVOPCtx->u16SubCropXSize = u16Hsize;
                    }

                    if (u16Vsize < u16CropV)
                    {
                        HAL_Write2Byte(SUB_REG(VOP_REG_CROP_VSIZE), u16Vsize);
                        g_pHalMVOPCtx->u16SubCropYSize = u16Vsize;
                    }
                }
            }
            else
            {
                HAL_WriteRegBit(SUB_REG(VOP_REG_MFDEC_0_L), FALSE, VOP_MFDEC_EN); // enable mfdec
            }
#if GOP_BACKPORCH_PATCH
            g_pHalMVOPCtx->bSubIsUnComp = pMFDECInfo->u32UNCOMPRESS_MODE;
#endif
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_1);
        }
        break;
#endif
        default:
            break;
    }
    return;
}

void HAL_MVOP_SetFrameInterlace(MVOP_DevID eID, HALMVOPInterlace* pIModeInfo)
{
    MS_U16 regval;
    switch (eID)
    {
        case E_MVOP_DEV_0:
        {
            HAL_MVOP_SetInterlaceType(eID, (MS_U8)pIModeInfo->eIModeType);
            HAL_MVOP_SetOutputInterlace(E_MVOP_DEV_0, pIModeInfo->bOutputIMode);
            if (pIModeInfo->bOutputIMode)
            {
                HAL_WriteRegBit(VOP_SW_FDMASK, pIModeInfo->u8FDMask, VOP_FDMASK);
                //HAL_WriteRegBit(VOP_MPG_JPG_SWITCH, pIModeInfo->u8BotFlag, VOP_FIELD);
                HAL_WriteRegBit(VOP_SW_FDMASK, pIModeInfo->u8FDMask, VOP_FORCE_BOB);
                //regval = HAL_ReadByte(VOP_MPG_JPG_SWITCH);
                regval = g_pHalMVOPCtx->u16Reg20;
                if (pIModeInfo->u8BotFlag)
                {
                    regval |= VOP_FIELD;
                }
                else
                {
                    regval &= ~VOP_FIELD;
                }
                if (g_pHalMVOPCtx->u32DC0FrmCnt < 2)
                {
                    regval |= VOP_PRO_SEQ;
                }
                else
                {
                    regval &= ~VOP_PRO_SEQ;
                }
                //HAL_WriteByte(VOP_MPG_JPG_SWITCH, regval);
                g_pHalMVOPCtx->u16Reg20 = (g_pHalMVOPCtx->u16Reg20 & ~(LowByteMask)) | ((regval) & (LowByteMask));
                HAL_Write2Byte(VOP_MPG_JPG_SWITCH, g_pHalMVOPCtx->u16Reg20);
            }
            else
            {
                HAL_WriteRegBit(VOP_SW_FDMASK, 0, VOP_FDMASK);
                //HAL_WriteRegBit(VOP_MPG_JPG_SWITCH, 0, VOP_FIELD);
                HAL_WriteRegBit(VOP_SW_FDMASK, 0, VOP_FORCE_BOB);
                //regval = HAL_ReadByte(VOP_MPG_JPG_SWITCH);
                regval = g_pHalMVOPCtx->u16Reg20;
                if ((TRUE == pIModeInfo->u8BotFlag) && (TRUE == g_pHalMVOPCtx->bForceP))
                {
                    regval |= VOP_FIELD;
                }
                else
                {
                    regval &= ~VOP_FIELD;
                }
                regval |= VOP_PRO_SEQ;
                //HAL_WriteByte(VOP_MPG_JPG_SWITCH, regval);
                g_pHalMVOPCtx->u16Reg20 = (g_pHalMVOPCtx->u16Reg20 & ~(LowByteMask)) | ((regval) & (LowByteMask));
                HAL_Write2Byte(VOP_MPG_JPG_SWITCH, g_pHalMVOPCtx->u16Reg20);
            }
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_0);
        }
        break;
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            HAL_MVOP_SetInterlaceType(eID, (MS_U8)pIModeInfo->eIModeType);
            HAL_MVOP_SetOutputInterlace(E_MVOP_DEV_1, pIModeInfo->bOutputIMode);
            if (pIModeInfo->bOutputIMode)
            {
                HAL_WriteRegBit(SUB_REG(VOP_SW_FDMASK), pIModeInfo->u8FDMask, VOP_FDMASK);
                //HAL_WriteRegBit(SUB_REG(VOP_MPG_JPG_SWITCH), pIModeInfo->u8BotFlag, VOP_FIELD);
                HAL_WriteRegBit(SUB_REG(VOP_SW_FDMASK), pIModeInfo->u8FDMask, VOP_FORCE_BOB);
                //regval = HAL_ReadByte(SUB_REG(VOP_MPG_JPG_SWITCH));
                regval = g_pHalMVOPCtx->u16SubReg20;
                if (pIModeInfo->u8BotFlag)
                {
                    regval |= VOP_FIELD;
                }
                else
                {
                    regval &= ~VOP_FIELD;
                }
                if (g_pHalMVOPCtx->u32DC1FrmCnt < 2)
                {
                    regval |= VOP_PRO_SEQ;
                }
                else
                {
                    regval &= ~VOP_PRO_SEQ;
                }
                //HAL_WriteByte(SUB_REG(VOP_MPG_JPG_SWITCH), regval);
                g_pHalMVOPCtx->u16SubReg20 = (g_pHalMVOPCtx->u16SubReg20 & ~(LowByteMask)) | ((regval) & (LowByteMask));
                HAL_Write2Byte(SUB_REG(VOP_MPG_JPG_SWITCH), g_pHalMVOPCtx->u16SubReg20);
            }
            else
            {
                HAL_WriteRegBit(SUB_REG(VOP_SW_FDMASK), 0, VOP_FDMASK);
                //HAL_WriteRegBit(SUB_REG(VOP_MPG_JPG_SWITCH), 0, VOP_FIELD);
                HAL_WriteRegBit(SUB_REG(VOP_SW_FDMASK), 0, VOP_FORCE_BOB);
                //regval = HAL_ReadByte(SUB_REG(VOP_MPG_JPG_SWITCH));
                regval = g_pHalMVOPCtx->u16SubReg20;
                if ((TRUE == pIModeInfo->u8BotFlag) && (TRUE == g_pHalMVOPCtx->bSubForceP))
                {
                    regval |= VOP_FIELD;
                }
                else
                {
                    regval &= ~VOP_FIELD;
                }
                regval |= VOP_PRO_SEQ;
                //HAL_WriteByte(SUB_REG(VOP_MPG_JPG_SWITCH), regval);
                g_pHalMVOPCtx->u16SubReg20 = (g_pHalMVOPCtx->u16SubReg20 & ~(LowByteMask)) | ((regval) & (LowByteMask));
                HAL_Write2Byte(SUB_REG(VOP_MPG_JPG_SWITCH), g_pHalMVOPCtx->u16SubReg20);
            }
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_1);
        }
        break;
#endif
        default:
            break;
    }
    return;
}

void HAL_MVOP_SetDISPSize(MVOP_DevID eID, HALMVOPDISPSize* pDispSize)
{
    MS_U16 u16strip;
    //MS_U16 u16strip_lsb;  new 10 bits remove
    MS_U16 regval;
#if MVOP_10B_H128_PATCH
    MS_U16 REG54_L = 0;
#endif
#if MFDEC_HSIZE_LIMIT_PATCH
    MS_BOOL bisMfdecEnable = 0;
    EN_MVOP_Output_3D_TYPE en3DType = E_MVOP_OUTPUT_3D_NONE;
#endif

    switch (eID)
    {
        case E_MVOP_DEV_0:
        {
#if MVOP_10B_H128_PATCH
            REG54_L = HAL_ReadByte(VOP_REG_MFDEC_0_L);
            if (g_pHalMVOPCtx->bIsEnLSB && ((REG54_L & 0x01) == 0) && (pDispSize->u16Width % 128))
            {
                HAL_WriteRegBit(VOP_REG_MFDEC_0_L, TRUE, VOP_MFDEC_EN); // enable mfdec
                HAL_WriteByteMask(VOP_REG_MFDEC_2_L, (TRUE << 4), VOP_UNCOMP_MODE);
            }
#endif
#if MFDEC_HSIZE_LIMIT_PATCH
            en3DType = HAL_MVOP_GetOutput3DType(E_MVOP_DEV_0);
            bisMfdecEnable = (HAL_ReadRegBit(VOP_REG_MFDEC_0_L, VOP_MFDEC_EN) == VOP_MFDEC_EN);
            if ((bisMfdecEnable == FALSE)
                && (pDispSize->u16Width > FHD_SRAM_SIZE)
                && (E_MVOP_OUTPUT_3D_NONE == en3DType)
                && (FALSE == g_pHalMVOPCtx->bIs422)
                && (E_MVOP_RGB_NONE == g_pHalMVOPCtx->eRgbFmt)
                && (FALSE == g_pHalMVOPCtx->bDramRdContd))
            {
                HAL_WriteRegBit(VOP_REG_MFDEC_0_L, TRUE, VOP_MFDEC_EN);
                HAL_WriteByteMask(VOP_REG_MFDEC_2_L, (TRUE << 4), VOP_UNCOMP_MODE);
            }
#endif
            /*
            * Outlook subject: MVOP av1 patch
            * SW patch for hsk + small size, actual size is captured by ip2.
            */
            if ((FALSE == MDrv_SYS_Query(E_SYS_QUERY_MVOP_MODE_SUPPORTED))
                && (TRUE == g_pHalMVOPCtx->bAV1_FG)
                && (TRUE == g_pHalMVOPCtx->bDS_EN)
                && (0 != pDispSize->u16Width))
            {
                pDispSize->u16Width += IP2_PATCH_HOFFSET;
            }
            HAL_Write2Byte(VOP_JPG_HSIZE, pDispSize->u16Width);
            if (g_pHalMVOPCtx->eInterlaceType == E_MVOP_INT_TB_SEP_FRAME)
            {
                HAL_Write2Byte(VOP_JPG_VSIZE, pDispSize->u16Height >> 1);
            }
            else
            {
                HAL_Write2Byte(VOP_JPG_VSIZE, pDispSize->u16Height);
            }
            u16strip = pDispSize->u16Pitch[0];
            g_pHalMVOPCtx->u16MSBPitch = pDispSize->u16Pitch[0];

            if (g_pHalMVOPCtx->bDramRdContd == 0)
            {
                u16strip = ((u16strip + 31) >> 5) * 32; //need align for monaco
                u16strip = u16strip >> 3;
            }
            else
            {
                if (g_pHalMVOPCtx->bIs422 || (g_pHalMVOPCtx->eTileFormat == E_MVOP_TILE_COMP_4x2)
                        || (g_pHalMVOPCtx->eRgbFmt != E_MVOP_RGB_NONE))
                {
                    if (E_MVOP_RGB_888 == g_pHalMVOPCtx->eRgbFmt)
                    {
                        u16strip *= 2; //4bytes/pixel (yuv422:2bytes/pixel)
                    }

                    u16strip = u16strip >> 2;
                    HAL_WriteRegBit(VOP_REG_STRIP_ALIGN, 0, BIT0);
                }
                else
                {
                    u16strip = u16strip >> 3;
                }
            }

            if (u16strip >= 256)
            {
                HAL_WriteByte(VOP_DC_STRIP_H, (u16strip >> 8));
                //reg_dc_strip_h[2:0] = reg_dc_strip[10:8]
            }
            else
            {
                HAL_WriteByteMask(VOP_DC_STRIP_H, 0, VOP_STRIP_H_MASK);
            }

            regval = u16strip;

            HAL_WriteByte(VOP_DC_STRIP, regval);
            HAL_WriteByte(VOP_DC_STRIP_LSB, LOWBYTE(u16strip));
            HAL_WriteByteMask(VOP_REG_8BIT_TR_LSC, HIGHBYTE(u16strip), VOP_DC_STRIP_LSB_H);
            //HAL_WriteByte(VOP_DC_STRIP, regval);
            g_pHalMVOPCtx->u16Reg20 = (g_pHalMVOPCtx->u16Reg20 & ~(HighByteMask)) | ((regval << 8) & (HighByteMask));
            HAL_Write2Byte(VOP_MPG_JPG_SWITCH, g_pHalMVOPCtx->u16Reg20);

            HAL_WriteByte(VOP_DS_IDX, pDispSize->U8DSIndex);
            HAL_WriteRegBit(VOP_SW_FDMASK, 1, VOP_FORCE_DS);
            HAL_MVOP_SetHorDup(E_MVOP_DEV_0, pDispSize->bHDup);
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_0);
            HAL_MVOP_SetVerDup(E_MVOP_DEV_0, pDispSize->bVDup);
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_0);
        }
        break;
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
#if MVOP_10B_H128_PATCH
            REG54_L = HAL_ReadByte(SUB_REG(VOP_REG_MFDEC_0_L));
            if (g_pHalMVOPCtx->bSubIsEnLSB && ((REG54_L & 0x01) == 0) && (pDispSize->u16Width % 128))
            {
                HAL_WriteRegBit(SUB_REG(VOP_REG_MFDEC_0_L), TRUE, VOP_MFDEC_EN); // enable mfdec
                HAL_WriteByteMask(SUB_REG(VOP_REG_MFDEC_2_L), (TRUE << 4), VOP_UNCOMP_MODE);
            }
#endif
            if (pDispSize->u16Width > FHD_SRAM_SIZE)
            {
#if MAIN_SUB_MVOP_DIFF
                /* There is only 2k1k sram with bw saving enabled */
                HAL_MVOP_Set420BWSaveMode(E_MVOP_DEV_1, FALSE);
                /* Enable average mode with 2P for DIP */
                if (TRUE == g_pHalMVOPCtx->bSubIs2p)
                {
                    HAL_MVOP_SetAverageMode(E_MVOP_DEV_1, TRUE);
                }
#else
                MVOP_PRINTF("[Error] %s: Sub MVOP width should less than 2048\n",
                            __FUNCTION__);
#endif
            }

            HAL_Write2Byte(SUB_REG(VOP_JPG_HSIZE), pDispSize->u16Width);
            if (g_pHalMVOPCtx->eSubInterlaceType == E_MVOP_INT_TB_SEP_FRAME)
            {
                HAL_Write2Byte(SUB_REG(VOP_JPG_VSIZE), pDispSize->u16Height >> 1);
            }
            else
            {
                HAL_Write2Byte(SUB_REG(VOP_JPG_VSIZE), pDispSize->u16Height);
            }
            u16strip = pDispSize->u16Pitch[0];
            g_pHalMVOPCtx->u16SubMSBPitch = pDispSize->u16Pitch[0];

            if (g_pHalMVOPCtx->bSubDramRdContd == 0)
            {
                u16strip = ((u16strip + 31) >> 5) * 32; //need align for monaco
                u16strip = u16strip >> 3;
            }
            else
            {
                if (g_pHalMVOPCtx->bSubIs422 || (g_pHalMVOPCtx->eSubTileFormat == E_MVOP_TILE_COMP_4x2))
                {
                    if (E_MVOP_RGB_888 == g_pHalMVOPCtx->eSubRgbFmt)
                    {
                        u16strip *= 2; //4bytes/pixel (yuv422:2bytes/pixel)
                    }

                    u16strip = u16strip >> 2;
                    HAL_WriteRegBit(SUB_REG(VOP_REG_STRIP_ALIGN), 0, BIT0);
                }
                else
                {
                    u16strip = u16strip >> 3;
                }
            }

            if (u16strip >= 256)
            {
                HAL_WriteByte(SUB_REG(VOP_DC_STRIP_H), (u16strip >> 8));
                //reg_dc_strip_h[2:0] = reg_dc_strip[10:8]
            }
            else
            {
                HAL_WriteByteMask(SUB_REG(VOP_DC_STRIP_H), 0, VOP_STRIP_H_MASK);
            }

            regval = u16strip;

            HAL_WriteByte(SUB_REG(VOP_DC_STRIP), regval);
            HAL_WriteByte(SUB_REG(VOP_DC_STRIP_LSB), LOWBYTE(u16strip));
            HAL_WriteByteMask(SUB_REG(VOP_REG_8BIT_TR_LSC), HIGHBYTE(u16strip), VOP_DC_STRIP_LSB_H);
            //HAL_WriteByte(SUB_REG(VOP_DC_STRIP), regval);
            g_pHalMVOPCtx->u16SubReg20 = (g_pHalMVOPCtx->u16SubReg20 & ~(HighByteMask)) | ((regval << 8) & (HighByteMask));
            HAL_Write2Byte(SUB_REG(VOP_MPG_JPG_SWITCH), g_pHalMVOPCtx->u16SubReg20);

            HAL_WriteByte(SUB_REG(VOP_DS_IDX), pDispSize->U8DSIndex);
            HAL_WriteRegBit(SUB_REG(VOP_SW_FDMASK), 1, VOP_FORCE_DS);
            HAL_MVOP_SetHorDup(E_MVOP_DEV_1, pDispSize->bHDup);
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_1);
            HAL_MVOP_SetVerDup(E_MVOP_DEV_1, pDispSize->bVDup);
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_1);
        }
        break;
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
    return;
}

void HAL_MVOP_SetDISPDVSize(MVOP_DevID eID, HALMVOPDISPDualDVSize* pDispSize)
{
#if MVOP_SUPPORT_SUB
    MS_U16 u16strip;
    // MS_U16 u16strip_lsb;  new 10 bits remove
    MS_U16 regval;

    switch (eID)
    {
        case E_MVOP_DEV_0:
        {
            if (pDispSize->u16Width_EL > FHD_SRAM_SIZE)
            {
#if MAIN_SUB_MVOP_DIFF
                // There is no mfdec for sub mvop, need to disable bw saving for resolution > 2k1k
                HAL_MVOP_Set420BWSaveMode(E_MVOP_DEV_1, FALSE);
                // Enable average mode with 2P for DIP
                if (TRUE == g_pHalMVOPCtx->bSubIs2p)
                {
                    HAL_MVOP_SetAverageMode(E_MVOP_DEV_1, TRUE);
                }
#else
                MVOP_PRINTF("[Error] %s: Sub MVOP width should less than 2048\n", __FUNCTION__);
#endif
            }
            HAL_Write2Byte(SUB_REG(VOP_JPG_HSIZE), pDispSize->u16Width_EL);
            HAL_Write2Byte(SUB_REG(VOP_JPG_VSIZE), pDispSize->u16Height_EL);
            u16strip = pDispSize->u16Pitch_EL[0];

            u16strip = ((u16strip + 31) >> 5) * 32; //need align for monaco
            u16strip = u16strip >> 3;

            if (u16strip >= 256)
            {
                HAL_WriteByte(SUB_REG(VOP_DC_STRIP_H), (u16strip >> 8));
                //reg_dc_strip_h[2:0] = reg_dc_strip[10:8]
            }
            else
            {
                HAL_WriteByteMask(SUB_REG(VOP_DC_STRIP_H), 0, VOP_STRIP_H_MASK);
            }

            regval = u16strip;

            HAL_WriteByte(SUB_REG(VOP_DC_STRIP), regval);
            HAL_WriteByte(SUB_REG(VOP_DC_STRIP_LSB), LOWBYTE(u16strip));
            HAL_WriteByteMask(SUB_REG(VOP_REG_8BIT_TR_LSC), HIGHBYTE(u16strip), VOP_DC_STRIP_LSB_H);
            //HAL_WriteByte(SUB_REG(VOP_DC_STRIP), regval);
            g_pHalMVOPCtx->u16SubReg20 = (g_pHalMVOPCtx->u16SubReg20 & ~(HighByteMask)) | ((regval << 8) & (HighByteMask));
            HAL_Write2Byte(SUB_REG(VOP_MPG_JPG_SWITCH), g_pHalMVOPCtx->u16SubReg20);
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_1);
            break;
        }
        case E_MVOP_DEV_1:
        {
#if MFDEC_HSIZE_LIMIT_PATCH
            MS_BOOL bisMfdecEnable = 0;
            EN_MVOP_Output_3D_TYPE en3DType = E_MVOP_OUTPUT_3D_NONE;
            en3DType = HAL_MVOP_GetOutput3DType(E_MVOP_DEV_0);
            bisMfdecEnable = (HAL_ReadRegBit(VOP_REG_MFDEC_0_L, VOP_MFDEC_EN) == VOP_MFDEC_EN);
            if ((bisMfdecEnable == FALSE)
                && (pDispSize->u16Width_EL > FHD_SRAM_SIZE)
                && (en3DType == E_MVOP_OUTPUT_3D_NONE)
                && (FALSE == g_pHalMVOPCtx->bIs422)
                && (g_pHalMVOPCtx->eRgbFmt == E_MVOP_RGB_NONE)
                && (FALSE == g_pHalMVOPCtx->bDramRdContd))
            {
                HAL_WriteRegBit(VOP_REG_MFDEC_0_L, TRUE, VOP_MFDEC_EN);
                HAL_WriteByteMask(VOP_REG_MFDEC_2_L, (TRUE << 4), VOP_UNCOMP_MODE);
            }
#endif
            HAL_Write2Byte(VOP_JPG_HSIZE, pDispSize->u16Width_EL);
            HAL_Write2Byte(VOP_JPG_VSIZE, pDispSize->u16Height_EL);
            u16strip = pDispSize->u16Pitch_EL[0];

            u16strip = ((u16strip + 31) >> 5) * 32; //need align for monaco
            u16strip = u16strip >> 3;

            if (u16strip >= 256)
            {
                HAL_WriteByte(VOP_DC_STRIP_H, (u16strip >> 8));
                //reg_dc_strip_h[2:0] = reg_dc_strip[10:8]
            }
            else
            {
                HAL_WriteByteMask(VOP_DC_STRIP_H, 0, VOP_STRIP_H_MASK);
            }

            regval = u16strip;

            HAL_WriteByte(VOP_DC_STRIP, regval);
            HAL_WriteByte(VOP_DC_STRIP_LSB, LOWBYTE(u16strip));
            HAL_WriteByteMask(VOP_REG_8BIT_TR_LSC, HIGHBYTE(u16strip), VOP_DC_STRIP_LSB_H);
            //HAL_WriteByte(VOP_DC_STRIP, regval);
            g_pHalMVOPCtx->u16Reg20 = (g_pHalMVOPCtx->u16Reg20 & ~(HighByteMask)) | ((regval << 8) & (HighByteMask));
            HAL_Write2Byte(VOP_MPG_JPG_SWITCH, g_pHalMVOPCtx->u16Reg20);
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_0);
            break;
        }
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
#else
    MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
#endif
    return;
}

void HAL_MVOP_SetStreamInfo(MVOP_DevID eID, HALMVOStreamINFO* pStreamInfo)
{
    MS_U16 regval;
    MS_U16 u16Pitch;
    MS_U16 REG54_L = 0;

    switch (eID)
    {
        case E_MVOP_DEV_0:
        {
            REG54_L = HAL_ReadByte(VOP_REG_MFDEC_0_L);
            HAL_MVOP_SetTileFormat(E_MVOP_DEV_0, pStreamInfo->eTileFormat);

            g_pHalMVOPCtx->bDS_EN = pStreamInfo->bDS_EN;

            /*
            * If g_pHalMVOPCtx->bIsEnLSB has not been setup yet
            * VOP_EVD_10B_EN will be fired again at HAL_MVOP_SetEVDYUVBaseAdd
            */
            if ((TRUE == g_pHalMVOPCtx->bIsEnLSB)
                || (E_MVOP_TILE_COMP_4x2 == g_pHalMVOPCtx->eTileFormat))
            {
                HAL_WriteRegBit(VOP_EVD_10B_EN, 1, VOP_EVD_10B_Y_EN);
                HAL_WriteRegBit(VOP_EVD_10B_EN, 1, VOP_EVD_10B_UV_EN);
            }
            else
            {
                HAL_WriteRegBit(VOP_EVD_10B_EN, 0, VOP_EVD_10B_Y_EN);
                HAL_WriteRegBit(VOP_EVD_10B_EN, 0, VOP_EVD_10B_UV_EN);
            }
#if MFDEC_DB_PATCH
            /* patch for murphy hw bug: line buffer not support double buffer */
            EN_MVOP_Output_3D_TYPE en3DType = E_MVOP_OUTPUT_3D_NONE;
            MS_BOOL bOutputI = FALSE;

            en3DType = HAL_MVOP_GetOutput3DType(E_MVOP_DEV_0);
            bOutputI = (HAL_ReadRegBit(VOP_CTRL0, VOP_FLD_MD) == VOP_FLD_MD);

            /* Not support mfdec enable */
            if (((REG54_L & 0x01) == 0)
                /*&& (FALSE == bOutputI)*/
                && (E_MVOP_OUTPUT_3D_NONE == en3DType)
                && (FALSE == pStreamInfo->bIs422Mode)
                && (E_MVOP_RGB_NONE == g_pHalMVOPCtx->eRgbFmt)
                && (FALSE == pStreamInfo->bIsDRAMCont))
            {
                /* Other tileformat not support mfdec+uncompress mode */
                if ((E_MVOP_TILE_16x32 == pStreamInfo->eTileFormat)
                    || (E_MVOP_TILE_32x16 == pStreamInfo->eTileFormat)
                    || (E_MVOP_TILE_COMP_32x16_82PACK == g_pHalMVOPCtx->eTileFormat)
                    || (E_MVOP_TILE_COMP_4x2 == g_pHalMVOPCtx->eTileFormat
                        /* && u16Hsize > fHD_Width */))
                {
                    HAL_WriteRegBit(VOP_REG_MFDEC_0_L, TRUE, VOP_MFDEC_EN);
                    HAL_WriteRegBit(VOP_REG_MFDEC_2_L, TRUE, VOP_UNCOMP_MODE);
                }
            }
#endif
            //regval = HAL_ReadByte(VOP_MPG_JPG_SWITCH);
            regval = g_pHalMVOPCtx->u16Reg20;
            if (pStreamInfo->bIs422Mode)
                regval |= 0x90;
            else
                regval &= ~0x90;

            if (pStreamInfo->bIsDRAMCont)
                regval |= 0x20;
            else
                regval &= ~0x20;

            if (pStreamInfo->eTileFormat == E_MVOP_TILE_COMP_8x1)
            {
                MVOP_PRINTF("[Error] %s: Not support E_MVOP_TILE_COMP_8x1\n", __FUNCTION__);
            }

            if (pStreamInfo->eTileFormat == E_MVOP_TILE_COMP_4x2)
            {
                u16Pitch = g_pHalMVOPCtx->u16MSBPitch >> 2;
                //HAL_WriteByte(VOP_DC_STRIP, u16Pitch);
                g_pHalMVOPCtx->u16Reg20 = (g_pHalMVOPCtx->u16Reg20 & ~(HighByteMask)) | ((u16Pitch << 8) & (HighByteMask));
                if (u16Pitch >= 256)
                {
                    HAL_WriteByte(VOP_DC_STRIP_H, (u16Pitch >> 8));
                    //reg_dc_strip_h[2:0] = reg_dc_strip[10:8]
                }
                else
                {
                    HAL_WriteByteMask(VOP_DC_STRIP_H, 0, VOP_STRIP_H_MASK);
                }

                regval |= 0x20;
                g_pHalMVOPCtx->bDramRdContd = TRUE;
                HAL_WriteRegBit(VOP_INPUT_SWITCH0, FALSE, VOP_NEW_EVD_EN);
            }
            else
            {
                if ((FALSE == pStreamInfo->bIs422Mode) && (g_pHalMVOPCtx->eRgbFmt == E_MVOP_RGB_NONE))
                {
                    u16Pitch = g_pHalMVOPCtx->u16MSBPitch >> 3;
                    g_pHalMVOPCtx->u16Reg20 = (g_pHalMVOPCtx->u16Reg20 & ~(HighByteMask)) | ((u16Pitch << 8) & (HighByteMask));
                }
                g_pHalMVOPCtx->bDramRdContd = pStreamInfo->bIsDRAMCont;
                if (g_pHalMVOPCtx->bIsEnLSB && ((REG54_L & 0x01) == 0))
                {
                    HAL_WriteRegBit(VOP_INPUT_SWITCH0, TRUE, VOP_NEW_EVD_EN);
                }
            }
            g_pHalMVOPCtx->u16Reg20 = (g_pHalMVOPCtx->u16Reg20 & ~(LowByteMask)) | ((regval) & (LowByteMask));
            HAL_Write2Byte(VOP_MPG_JPG_SWITCH, g_pHalMVOPCtx->u16Reg20);
            g_pHalMVOPCtx->bIs422 = pStreamInfo->bIs422Mode;

            if (pStreamInfo->bIs422Mode) //for m7221 patch for inputcfg
            {
                HAL_WriteByteMask(VOP_REG_DDR4_REMAP, 0x00, VOP_MSB_REMAP | VOP_LSB_REMAP | VOP_CHANNEL3_ENABLE);
#if DDR4_CH_BALANCE_PATCH
                HAL_WriteRegBit(REG_MFD_AV1, FALSE, MVOP_DDR4_REMAP_CH_BALANCE);
#endif
                HAL_WriteRegBit(VOP_REG_DUMMY, 0, VOP_420_BW_SAVE);
                HAL_WriteRegBit(VOP_REG_BW_SAVE, 0, VOP_420_BW_SAVE_EX);
            }
            else if (pStreamInfo->bDDR4_REMAP)
            {
                HAL_WriteByteMask(VOP_REG_DDR4_REMAP, 0xE0, VOP_MSB_REMAP | VOP_LSB_REMAP | VOP_CHANNEL3_ENABLE);
#if DDR4_CH_BALANCE_PATCH
                HAL_WriteRegBit(REG_MFD_AV1, TRUE, MVOP_DDR4_REMAP_CH_BALANCE);
#endif
            }
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_0);
        }
        break;
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            REG54_L = HAL_ReadByte(SUB_REG(VOP_REG_MFDEC_0_L));
            HAL_MVOP_SetTileFormat(E_MVOP_DEV_1, pStreamInfo->eTileFormat);

            g_pHalMVOPCtx->bSubDS_EN = pStreamInfo->bDS_EN;

            // If g_pHalMVOPCtx->bSubIsEnLSB has not been setup yet
            // VOP_EVD_10B_EN will be fired again at HAL_MVOP_SubSetEVDYUVBaseAdd
            if (g_pHalMVOPCtx->bSubIsEnLSB || (g_pHalMVOPCtx->eSubTileFormat == E_MVOP_TILE_COMP_4x2))
            {
                HAL_WriteRegBit(SUB_REG(VOP_EVD_10B_EN), 1, VOP_EVD_10B_Y_EN);
                HAL_WriteRegBit(SUB_REG(VOP_EVD_10B_EN), 1, VOP_EVD_10B_UV_EN);
            }
            else
            {
                HAL_WriteRegBit(SUB_REG(VOP_EVD_10B_EN), 0, VOP_EVD_10B_Y_EN);
                HAL_WriteRegBit(SUB_REG(VOP_EVD_10B_EN), 0, VOP_EVD_10B_UV_EN);
            }

            //regval = HAL_ReadByte(SUB_REG(VOP_MPG_JPG_SWITCH));
            regval = g_pHalMVOPCtx->u16SubReg20;
            if (pStreamInfo->bIs422Mode)
                regval |= 0x90;
            else
                regval &= ~0x90;

            if (pStreamInfo->bIsDRAMCont)
                regval |= 0x20;
            else
                regval &= ~0x20;

            if (pStreamInfo->eTileFormat == E_MVOP_TILE_COMP_8x1)
            {
                MVOP_PRINTF("[Error] %s: Not support E_MVOP_TILE_COMP_8x1\n", __FUNCTION__);
            }
            else if (pStreamInfo->eTileFormat == E_MVOP_TILE_COMP_4x2)
            {
                u16Pitch = g_pHalMVOPCtx->u16SubMSBPitch >> 2;
                //HAL_WriteByte(SUB_REG(VOP_DC_STRIP), u16Pitch);
                g_pHalMVOPCtx->u16SubReg20 = (g_pHalMVOPCtx->u16SubReg20 & ~(HighByteMask)) | ((u16Pitch << 8) & (HighByteMask));
                if (u16Pitch >= 256)
                {
                    HAL_WriteByte(SUB_REG(VOP_DC_STRIP_H), (u16Pitch >> 8));
                    //reg_dc_strip_h[2:0] = reg_dc_strip[10:8]
                }
                else
                {
                    HAL_WriteByteMask(SUB_REG(VOP_DC_STRIP_H), 0, VOP_STRIP_H_MASK);
                }
                regval |= 0x20;
                g_pHalMVOPCtx->bSubDramRdContd = TRUE;
                HAL_WriteRegBit(SUB_REG(VOP_INPUT_SWITCH0), FALSE, VOP_NEW_EVD_EN);
            }
            else
            {
                g_pHalMVOPCtx->bSubDramRdContd = pStreamInfo->bIsDRAMCont;
                if (g_pHalMVOPCtx->bSubIsEnLSB && ((REG54_L & 0x01) == 0))
                {
                    HAL_WriteRegBit(SUB_REG(VOP_INPUT_SWITCH0), TRUE, VOP_NEW_EVD_EN);
                }
            }

            //HAL_WriteByte(SUB_REG(VOP_MPG_JPG_SWITCH), regval);
            g_pHalMVOPCtx->u16SubReg20 = (g_pHalMVOPCtx->u16SubReg20 & ~(LowByteMask)) | ((regval) & (LowByteMask));
            HAL_Write2Byte(SUB_REG(VOP_MPG_JPG_SWITCH), g_pHalMVOPCtx->u16SubReg20);
            g_pHalMVOPCtx->bSubIs422 = pStreamInfo->bIs422Mode;
            if (pStreamInfo->bIs422Mode) //for m7221 patch for inputcfg
            {
                HAL_WriteByteMask(SUB_REG(VOP_REG_DDR4_REMAP), 0x00, VOP_MSB_REMAP | VOP_LSB_REMAP | VOP_CHANNEL3_ENABLE);
                HAL_WriteRegBit(SUB_REG(VOP_REG_DUMMY), 0, VOP_420_BW_SAVE);
                HAL_WriteRegBit(SUB_REG(VOP_REG_BW_SAVE), 0, VOP_420_BW_SAVE_EX);
            }
            else if (pStreamInfo->bDDR4_REMAP)
            {
                HAL_WriteByteMask(SUB_REG(VOP_REG_DDR4_REMAP), 0xE0, VOP_MSB_REMAP | VOP_LSB_REMAP | VOP_CHANNEL3_ENABLE);
            }
            HAL_MVOP_ForceWriteReg(E_MVOP_DEV_1);
        }
        break;
#endif
        default:
            break;
    }
    return;
}

void HAL_MVOP_EnableTCHSetting(MVOP_DevID eID, MS_BOOL bEnable)
{
    UNUSED(eID);
    UNUSED(bEnable);
    return;
}

MS_BOOL HAL_MVOP_GetIsBotField(MVOP_DevID eID)
{
    MS_BOOL bRet = FALSE;
    switch (eID)
    {
        case E_MVOP_DEV_0:
// remove sw toggle field from m7322, m7332/m7632/m7642 hw will toggle in p timing.
// patch:I_GEN_FIELD_TIMING + one field need to use hw 0x2c[13]
#if 0
            if (g_pHalMVOPCtx->bForceP)
            {
                bRet = ((g_pHalMVOPCtx->u32DC0FrmCnt) % 2);
            }
            else
#endif
            {
                bRet = (HAL_ReadRegBit(VOP_DEBUG_2C_H, VOP_DC2MVD_FLD_FLAG) == VOP_DC2MVD_FLD_FLAG);
            }
            MVOP_DBG(MVOP_PRINTF("[%s] = 0x%x\n", __FUNCTION__, (MS_U8)HAL_ReadRegBit(VOP_DEBUG_2C_H, VOP_DC2MVD_FLD_FLAG));)
            break;
        case E_MVOP_DEV_1:
#if MVOP_SUPPORT_SUB
// remove sw toggle field from m7322, m7332/m7632/m7642 hw will toggle in p timing.
// patch:I_GEN_FIELD_TIMING + one field need to use hw 0x2c[13]
#if 0
            if (g_pHalMVOPCtx->bSubForceP)
            {
                bRet = ((g_pHalMVOPCtx->u32DC1FrmCnt) % 2);
            }
            else
#endif
            {
                bRet = (HAL_ReadRegBit(SUB_REG(VOP_DEBUG_2C_H), VOP_DC2MVD_FLD_FLAG) == VOP_DC2MVD_FLD_FLAG);
            }
#endif
            break;
        default:
            bRet = E_MVOP_HS_INVALID_PARAM;
            break;
    }
    return bRet;
}

void HAL_MVOP_SetForcePMode(MVOP_DevID eID, MS_BOOL bEnable)
{
    switch (eID)
    {
        case E_MVOP_DEV_0:
        {
            g_pHalMVOPCtx->bForceP = bEnable;
        }
        break;
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            g_pHalMVOPCtx->bSubForceP = bEnable;
        }
        break;
#endif
        default:
            break;
    }
}

void HAL_MVOP_SetBankSwitch(MS_BOOL bEnable)
{
    UNUSED(bEnable);
}

void HAL_MVOP_SetSingleDV(MVOP_DevID eID, MS_BOOL bEnable)
{
    switch (eID)
    {
        case E_MVOP_DEV_0:
        {
            g_pHalMVOPCtx->bIsSinDV = bEnable;
        }
        break;
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            g_pHalMVOPCtx->bSubIsSinDV = bEnable;
        }
        break;
#endif
        default:
            break;
    }
    return;
}

MS_BOOL HAL_MVOP_GetHVTTforDynamicFPS(MVOP_DevID eID, MVOP_Timing* pMVOPTiming, MVOP_DYNAMIC_FPS* pTiming)
{
    MS_BOOL bRet = FALSE;
    MS_U64 u64TmpCLK = 0;
    MS_BOOL bInterlace = FALSE;
    MS_U32 u32Vb = 0;
    MS_U32 u32Hb = 0;
    MS_U64 u64TmpHTT = 0;

    //tmp mask
    //MVOP_DBG(MVOP_PRINTF("[MVOP] HAL_MVOP_GetHVTTforDynamicFPS input h = 0x%x, input y = 0x%x, input fps = 0x%x\n",pTiming->u16HorSize,pTiming->u16VerSize,pTiming->u16FrameRate);)

    switch (eID)
    {
        case E_MVOP_DEV_0:
        {
            u64TmpCLK = HAL_MVOP_GetCurrentClk(E_MVOP_DEV_0);
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            u64TmpCLK = HAL_MVOP_GetCurrentClk(E_MVOP_DEV_1);
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            bRet = FALSE;
            break;
        }
    }

    if (((MS_U64)(pTiming->u16HorSize >> 1) * pTiming->u16VerSize * pTiming->u16FrameRate) < (u64TmpCLK * 1000))
    {
        bInterlace = pMVOPTiming->bInterlace;
        u32Hb = pMVOPTiming->u16HActive_Start;
#if defined (__aarch64__)
        MVOP_DBG(MVOP_PRINTF("[MVOP] original HTT = 0x%x, original VTT = 0x%x, u64TmpCLK = %d\n", pMVOPTiming->u16H_TotalCount, pMVOPTiming->u16V_TotalCount, u64TmpCLK);)
#else
        MVOP_DBG(MVOP_PRINTF("[MVOP] original HTT = 0x%x, original VTT = 0x%x, u64TmpCLK = %d\n", pMVOPTiming->u16H_TotalCount, pMVOPTiming->u16V_TotalCount, (int)u64TmpCLK);)
#endif
        if (bInterlace)
        {
            u32Vb = (pMVOPTiming->u16VBlank0_End - pMVOPTiming->u16VBlank0_Start) + (pMVOPTiming->u16VBlank1_End - pMVOPTiming->u16VBlank1_Start);
        }
        else
        {
            u32Vb = pMVOPTiming->u16VBlank0_End - pMVOPTiming->u16VBlank0_Start;
        }
        MVOP_DBG(MVOP_PRINTF("[MVOP] u32Hb = 0x%x, u32Vb = 0x%x\n", u32Hb, u32Vb);)
        pTiming->u16VTotal = pTiming->u16VerSize + u32Vb;
        if ((((MS_U64)pTiming->u16VTotal * pTiming->u16FrameRate) > (u64TmpCLK * 1000)) || (0 == pTiming->u16FrameRate) || (0 == pTiming->u16VTotal))
        {
#if defined (__aarch64__)
            MVOP_PRINTF("[MVOP][Warning] out of hw limitation: input h = 0x%x, input y = 0x%x, CLK = %llu\n", pTiming->u16HorSize, pTiming->u16VerSize, u64TmpCLK);
#else
            MVOP_PRINTF("[MVOP][Warning] out of hw limitation: input h = 0x%x, input y = 0x%x, CLK = %d\n", pTiming->u16HorSize, pTiming->u16VerSize, (int)u64TmpCLK);
#endif
            return bRet;
        }
        u64TmpHTT = ((u64TmpCLK * 1000) / pTiming->u16VTotal) / pTiming->u16FrameRate;

        if (u64TmpHTT >= MaxHTT)
        {
            pTiming->u16HTotal = MaxHTT;
            pTiming->u16VTotal = ((u64TmpCLK * 1000) / pTiming->u16HTotal) / pTiming->u16FrameRate;
            if (pTiming->u16VTotal > MaxVTT)
            {
                bRet = FALSE;
                //tmp mask
                //MVOP_PRINTF("[MVOP][Warning] out of hw limitation: u16HTotal = 0x%x, u16VTotal = 0x%x, FPS = %d\n",pTiming->u16HTotal,pTiming->u16VTotal,pTiming->u16FrameRate);
            }
            else
            {
                bRet = TRUE;
                //tmp mask
                //MVOP_DBG(MVOP_PRINTF("[MVOP]  u16HTotal = 0x%x, u16VTotal = 0x%x, FPS = %d\n",pTiming->u16HTotal,pTiming->u16VTotal,pTiming->u16FrameRate);)

            }
        }
        else
        {
            pTiming->u16HTotal = (MS_U16)u64TmpHTT;
            bRet = TRUE;
            //tmp mask
            //MVOP_PRINTF("[MVOP]  u16HTotal = 0x%x, u16VTotal = 0x%x, FPS = %d\n",pTiming->u16HTotal,pTiming->u16VTotal,pTiming->u16FrameRate);

        }
    }
    else
    {
        MVOP_DBG(MVOP_PRINTF("[MVOP] HTT or VTT smaller than new resolution, clock may not support, can not support dynamic fps\n");)
        bRet = FALSE;
    }

    if (bRet == FALSE)
    {
        pTiming->u16HTotal = pMVOPTiming->u16H_TotalCount;
        pTiming->u16VTotal = pMVOPTiming->u16V_TotalCount;
    }

    UNUSED(u32Hb);
    return bRet;
}

MVOP_Pattern HAL_MVOP_GetPattern(MVOP_DevID eID)
{
    MVOP_Pattern enMVOPPat = MVOP_PATTERN_NORMAL;
    switch (eID)
    {
        case E_MVOP_DEV_0:
        {
            enMVOPPat = (MVOP_Pattern)(HAL_ReadByte(VOP_TST_IMG) & VOP_PATTERN_MASK);
        }
        break;
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            enMVOPPat = (MVOP_Pattern)(HAL_ReadByte(SUB_REG(VOP_TST_IMG)) & VOP_PATTERN_MASK);
        }
        break;
#endif
        default:
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
    }
    return enMVOPPat;
}

void HAL_MVOP_EnableDMSMode(MVOP_DevID eID, MS_BOOL bEnable)
{
    switch (eID)
    {
        case E_MVOP_DEV_0:
        {
            g_pHalMVOPCtx->bIsDMSMCU = bEnable;
        }
        break;
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            g_pHalMVOPCtx->bSubIsDMSMCU = bEnable;
        }
        break;
#endif
        default:
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
    }
    return;
}

MS_U32 HAL_MVOP_GetVideoDelay(MVOP_DevID eID, MS_U32 u32FPS)
{
    MS_U32 u32DelayTime = 0;

#if AUDIO_VIDEO_DELAY_PATCH
    if (u32FPS > 0)
    {
        u32DelayTime = ((((1000000 * 10) / u32FPS) + 5) / 10);
    }
    else
    {
        MVOP_PRINTF("[Warning][%s] framerate = 0\n",__FUNCTION__);
        u32DelayTime = 0;
    }
#else
    MS_U16 u16VTT = 0;
    MS_U16 u16VBlanking = 0;
    MS_U16 u16FireVCNT = 0;
    MS_BOOL bMCUMode = TRUE;
    MS_U16 u16CurrentVCNT = 0;
    MS_U16 u16DelayVCnt = 0;
    MS_U32 u32FrameTime = (1000000 * 10) / u32FPS;
    MS_U32 u32FieldTime = u32FrameTime >> 1;
    MS_BOOL bFieldType;

    switch (eID)
    {
        case E_MVOP_DEV_0:
        {
            u16VTT = HAL_Read2Byte(VOP_FRAME_VCOUNT);
            u16VBlanking = HAL_Read2Byte(VOP_VB0_END) - HAL_Read2Byte(VOP_VB0_STR);
            u16FireVCNT = HAL_Read2Byte(VOP_EXT_DB_START_OFF);
            bMCUMode = (HAL_ReadRegBit(VOP_MPG_JPG_SWITCH, VOP_DC_MODE_MASK) == BIT1);

            //dms + xc gen timing, mvop fps = panel timing.
            u16CurrentVCNT = g_pHalMVOPCtx->u16CurVCnt;
            bFieldType = g_pHalMVOPCtx->eInterlaceType;
        }
        break;
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            u16VTT = HAL_Read2Byte(SUB_REG(VOP_FRAME_VCOUNT));
            u16VBlanking = HAL_Read2Byte(SUB_REG(VOP_VB0_END)) - HAL_Read2Byte(SUB_REG(VOP_VB0_STR));
            u16FireVCNT = HAL_Read2Byte(SUB_REG(VOP_EXT_DB_START_OFF));
            bMCUMode = (HAL_ReadRegBit(SUB_REG(VOP_MPG_JPG_SWITCH), VOP_DC_MODE_MASK) == BIT1);

            //dms + xc gen timing, mvop fps = panel timing.
            u16CurrentVCNT = g_pHalMVOPCtx->u16SubCurVCnt;
            bFieldType = g_pHalMVOPCtx->eSubInterlaceType;
        }
        break;
#endif
        default:
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
    }

    if ((u32FPS == 0) || (u16VTT == 0) || (u16VTT < u16CurrentVCNT))
    {
        return 0;
    }

    if (bMCUMode)
    {
        u16DelayVCnt = (u16CurrentVCNT > u16FireVCNT) ? (u16CurrentVCNT - u16FireVCNT) : ((u16VTT - u16FireVCNT)
            + u16CurrentVCNT);

        //1000000 * 10 = 1000 ms * 1000(for fps) *10(for rounding)
        u32DelayTime = (u32FrameTime * u16DelayVCnt) / u16VTT;
        u32DelayTime = (u32DelayTime + 5) / 10; //for rounding
        //interlace return field delay
        //current v count is bot field
        if (bFieldType > E_MVOP_PRO)
        {
            u32DelayTime = ((u32DelayTime >> 1) + 5) / 10;
        }
        else
        {
            u32DelayTime = (u32DelayTime + 5) / 10; //for rounding
        }
    }
    else
    {
        //1000000 * 10 = 1000 ms * 1000(for fps) *10(for rounding)
        u32DelayTime = (u32FrameTime * u16VBlanking) / u16VTT;
        u32DelayTime = (u32DelayTime + 5) / 10; //for rounding
    }
#endif

    return u32DelayTime;
}

MS_U16 HAL_MVOP_GetHStart(MVOP_Timing* pTiming)
{
    return pTiming->u16HActive_Start / 2 - 5;
}

MS_U16 HAL_MVOP_GetVStart(MVOP_Timing* pTiming)
{
    MS_U16 u16Vst = 0;
    u16Vst = pTiming->u16VBlank0_End - pTiming->u16TopField_VS;

    if ((pTiming->bInterlace == 1) || (g_pHalMVOPCtx->bForceP == TRUE))
    {
        u16Vst *= 2;
        u16Vst -= 19;
    }
    else
    {
        u16Vst -= 6;
    }

    return u16Vst;
}

void HAL_MVOP_SetFrameSync(MVOP_DevID eDevID, MS_BOOL bEnable)
{
    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            HAL_WriteRegBit(VOP_CTRL0, bEnable, VOP_FSYNC_EN);
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            HAL_WriteRegBit(SUB_REG(VOP_CTRL0), bEnable, VOP_FSYNC_EN);
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
}

MS_BOOL HAL_MVOP_IsForce1PTiming(MVOP_DevID eDevID)
{
    MS_BOOL bRet = FALSE;

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            // M7332/M7632/M7642: main mvop default enable 2p mode but with 1p timing
            bRet = TRUE;
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            // M7332/M7632/M7642: no force 1p timing for sub mvop
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
    return bRet;
}

MS_BOOL HAL_MVOP_SetDMSInterrupt(MVOP_DevID eID, MVOP_IntType eIntType)
{
    MS_U8 u8Mask = 0;
    MS_BOOL bRet = TRUE;

    if ((eIntType == E_MVOP_INT_NONE) || (eIntType == E_MVOP_INT_3A_NONE_EX))
    {
        HAL_WriteByteMask(DEV_REG(VOP_REG_3A, eID), VOP_INT3A_ALL, VOP_INT3A_ALL);
        HAL_WriteByteMask(DEV_REG(VOP_INT_MASK, eID), VOP_INT_ALL, VOP_INT_ALL);
        if ((eID == E_MVOP_DEV_0) && (g_pHalMVOPCtx->bForceP))
        {
            if (g_pHalMVOPCtx->u32DC0FrmCnt < 0xffffffff)
            {
                g_pHalMVOPCtx->u32DC0FrmCnt ++;
            }
            else
            {
                g_pHalMVOPCtx->u32DC0FrmCnt = 0;
            }
        }
#if MVOP_SUPPORT_SUB
        else if ((eID == E_MVOP_DEV_1) && (g_pHalMVOPCtx->bSubForceP))
        {
            if (g_pHalMVOPCtx->u32DC1FrmCnt < 0xffffffff)
            {
                g_pHalMVOPCtx->u32DC1FrmCnt ++;
            }
            else
            {
                g_pHalMVOPCtx->u32DC1FrmCnt = 0;
            }
        }
#endif
        return bRet;
    }

    switch (eIntType & HighByteMask)
    {
        case E_MVOP_INT_NONE:
        {
            u8Mask = HAL_ReadByte(DEV_REG(VOP_INT_MASK, eID));
            break;
        }
        case E_MVOP_INT_3A_NONE_EX:
        {
            u8Mask = HAL_ReadByte(DEV_REG(VOP_REG_3A, eID));
            break;
        }
        default:
        {
            MVOP_PRINTF("[%s] MVOP not suuport Int Type 0x%x\n", __FUNCTION__, eIntType);
            bRet = FALSE;
            break;
        }
    }

    switch (eIntType)
    {
        case E_MVOP_INT_BUFF_UF:
        {
            u8Mask &= ~VOP_INT_BUFF_UF;
            break;
        }
        case E_MVOP_INT_BUFF_OF:
        {
            u8Mask &= ~VOP_INT_BUFF_OF;
            break;
        }
        case E_MVOP_INT_VSYNC:
        {
            u8Mask &= ~VOP_INT_VSYNC;
            break;
        }
        case E_MVOP_INT_HSYNC:
        {
            u8Mask &= ~VOP_INT_HSYNC;
            break;
        }
        case E_MVOP_INT_RDY:
        {
            u8Mask &= ~VOP_INT_RDY;
            break;
        }
        case E_MVOP_INT_FDCHNG:
        {
            u8Mask &= ~VOP_INT_FDCHNG;
            break;
        }
        case E_MVOP_INT_MVDVS:
        {
            u8Mask &= ~VOP_INT_MVDVS;
            break;
        }
        case E_MVOP_INT_VSIZE_EX:
        {
            u8Mask &= ~VOP_REG_IN_VSIZE_INT_MASK;
            break;
        }
        case E_MVOP_INT_DC_START:
        {
            u8Mask &= ~VOP_REG_DC_START_INT_MASK;
            break;
        }
        default:
        {
            MVOP_DBG(MVOP_PRINTF("[%s] Unknown MVOP_IntType\n", __FUNCTION__);)
            bRet = FALSE;
            break;
        }
    }

    switch (eIntType & HighByteMask)
    {
        case E_MVOP_INT_NONE:
        {
            HAL_WriteByteMask(DEV_REG(VOP_INT_MASK, eID), u8Mask, VOP_INT_ALL);
            break;
        }
        case E_MVOP_INT_3A_NONE_EX:
        {
            HAL_WriteByteMask(DEV_REG(VOP_REG_3A, eID), u8Mask, VOP_INT3A_ALL);
            break;
        }
        default:
        {
            MVOP_PRINTF("[%s] MVOP not suuport Int Type 0x%x\n", __FUNCTION__, eIntType);
            bRet = FALSE;
            break;
        }
    }

    return bRet;
}

MS_BOOL HAL_MVOP_GetDMSInterrupt(MVOP_DevID eID, MVOP_DMSIntStatus* pDMSIntStatus)
{
    MS_BOOL bRet = TRUE;

    if (eID == E_MVOP_DEV_0)
    {
        pDMSIntStatus->u8IntReg0x1F = HAL_ReadByte((VOP_INT_MASK + 1)) & VOP_INT_ALL;
        pDMSIntStatus->u8IntReg0x3A = HAL_ReadByte((VOP_REG_3A + 1)) & VOP_INT3A_ALL;
    }
#if MVOP_SUPPORT_SUB
    else if (eID == E_MVOP_DEV_1)
    {
        pDMSIntStatus->u8IntReg0x1F = HAL_ReadByte(SUB_REG((VOP_INT_MASK + 1))) & VOP_INT_ALL;
        pDMSIntStatus->u8IntReg0x3A = HAL_ReadByte(SUB_REG((VOP_REG_3A + 1))) & VOP_INT3A_ALL;
    }
#endif
    else
    {
        bRet = FALSE;
    }
    return bRet;
}

MS_BOOL HAL_MVOP_SetTimeStamp(MVOP_DevID eDevID, MS_U64 u64Timestamp, MS_BOOL bForceTimeStamp)
{
    MS_BOOL bRet = FALSE;

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            HAL_Write2Byte((VOP_EXT_64B_TIME_STAMP), (u64Timestamp) & 0xffff);
            HAL_Write2Byte((VOP_EXT_64B_TIME_STAMP + 2), (u64Timestamp >> 16) & 0xffff);
            HAL_Write2Byte((VOP_EXT_64B_TIME_STAMP + 4), (u64Timestamp >> 32) & 0xffff);
            HAL_Write2Byte((VOP_EXT_64B_TIME_STAMP + 6), (u64Timestamp >> 48) & 0xffff);
            HAL_WriteRegBit(VOP_EXT_FORCE_TIME_STAMP, bForceTimeStamp, FORCE_TIME_STAMP);
            bRet = TRUE;
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            HAL_Write2Byte(SUB_REG(VOP_EXT_64B_TIME_STAMP), (u64Timestamp) & 0xffff);
            HAL_Write2Byte(SUB_REG(VOP_EXT_64B_TIME_STAMP + 2), (u64Timestamp >> 16) & 0xffff);
            HAL_Write2Byte(SUB_REG(VOP_EXT_64B_TIME_STAMP + 4), (u64Timestamp >> 32) & 0xffff);
            HAL_Write2Byte(SUB_REG(VOP_EXT_64B_TIME_STAMP + 6), (u64Timestamp >> 48) & 0xffff);
            HAL_WriteRegBit(SUB_REG(VOP_EXT_FORCE_TIME_STAMP), bForceTimeStamp, FORCE_TIME_STAMP);
            bRet = TRUE;
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
    return bRet;
}

MS_U16 HAL_MVOP_GetFireVCount(MVOP_DevID eID)
{
    MS_U16 u16VCount = 0;
    MS_BOOL bIsBot = HAL_MVOP_GetIsBotField(eID);

    switch (eID)
    {
        case E_MVOP_DEV_0:
        {
            if (g_pHalMVOPCtx->bIsHS)
            {
                if (HAL_ReadRegBit(VOP_REG_4K2K_2P, VOP_TRIG_REFER_VB_END) == VOP_TRIG_REFER_VB_END)
                {
                    if (bIsBot)
                    {
                        u16VCount = HAL_Read2Byte(VOP_VB1_END);
                    }
                    else
                    {
                        u16VCount = HAL_Read2Byte(VOP_VB0_END);
                    }
                }
                else
                {
                    if (bIsBot)
                    {
                        u16VCount = HAL_Read2Byte(VOP_BF_VS);
                    }
                    else
                    {
                        u16VCount = HAL_Read2Byte(VOP_TF_VS);
                    }
                }
            }
            else // DE mode
            {
                if (bIsBot)
                {
                    u16VCount = HAL_Read2Byte(VOP_VB1_END);
                }
                else
                {
                    u16VCount = HAL_Read2Byte(VOP_VB0_END);
                }
            }
            break;
        }
        case E_MVOP_DEV_1:
        {
#if MVOP_SUPPORT_SUB
            if (g_pHalMVOPCtx->bSubIsHS)
            {
                if (HAL_ReadRegBit(SUB_REG(VOP_REG_4K2K_2P), VOP_TRIG_REFER_VB_END) == VOP_TRIG_REFER_VB_END)
                {
                    if (bIsBot)
                    {
                        u16VCount = HAL_Read2Byte(SUB_REG(VOP_VB1_END));
                    }
                    else
                    {
                        u16VCount = HAL_Read2Byte(SUB_REG(VOP_VB0_END));
                    }
                }
                else
                {
                    if (bIsBot)
                    {
                        u16VCount = HAL_Read2Byte(SUB_REG(VOP_BF_VS));
                    }
                    else
                    {
                        u16VCount = HAL_Read2Byte(SUB_REG(VOP_TF_VS));
                    }

                }
            }
            else // DE mode
            {
                if (bIsBot)
                {
                    u16VCount = HAL_Read2Byte(SUB_REG(VOP_VB1_END));
                }
                else
                {
                    u16VCount = HAL_Read2Byte(SUB_REG(VOP_VB0_END));
                }
            }
            break;
#endif
        }
        default:
            break;
    }
    return u16VCount;
}

MS_BOOL HAL_MVOP_GetIsFireOnTime(MVOP_DevID eID, MVOP_DMSFireOnTime* pFireTime, MS_U32 u32FPS)
{
    MS_U32 u32FireVCount = HAL_MVOP_GetFireVCount(eID);
    MS_U16 u16Vtotal = 0;
    MS_U32 u32NeedVcnt = 0;
    MS_U64 u64NeedTime = pFireTime->u32NeedTime;

    if (u32FPS == 0)
    {
        return FALSE;
    }

    pFireTime->u32Vcount = HAL_MVOP_GetVCount(eID);

    switch (eID)
    {
        case E_MVOP_DEV_0:
        {
            u16Vtotal = HAL_Read2Byte(VOP_FRAME_VCOUNT);
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            u16Vtotal = HAL_Read2Byte(SUB_REG(VOP_FRAME_VCOUNT));
            break;
        }
#endif
        default:
            break;
    }

    u32NeedVcnt = (MS_U32)(u64NeedTime * u32FPS * u16Vtotal) / 1000000000;
    if (pFireTime->u32Vcount > u32FireVCount)
    {
        if (((u32NeedVcnt + pFireTime->u32Vcount) > u16Vtotal) && ((u32NeedVcnt + pFireTime->u32Vcount - u16Vtotal) > u32FireVCount))
        {
            pFireTime->bIsOnTime = FALSE;
        }
        else
        {
            pFireTime->bIsOnTime = TRUE;
        }
    }
    else
    {
        pFireTime->bIsOnTime = ((u32NeedVcnt + pFireTime->u32Vcount) < u32FireVCount) ? TRUE : FALSE;
    }
    return TRUE;
}

MVOP_RgbFormat HAL_MVOP_GetRGBFormat(MVOP_DevID eID)
{
    MVOP_RgbFormat eRGB = E_MVOP_RGB_NONE;

    switch (eID)
    {
        case E_MVOP_DEV_0:
        {
            eRGB = g_pHalMVOPCtx->eRgbFmt;
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            eRGB = g_pHalMVOPCtx->eSubRgbFmt;
            break;
        }
#endif
        default:
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
    }

    return eRGB;
}

MS_BOOL HAL_MVOP_SetFrameReset(MVOP_DevID eDevID, MS_BOOL bEnable)
{
    MS_BOOL bRet = TRUE;

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            HAL_WriteRegBit(VOP_REG_YC422_EN_H, bEnable, VOP_FRAME_RST);
            // M7332/M7632/M7642 VOP_FRAME_RST and VOP_FRAME_RST2 have to set the same value.
            HAL_WriteRegBit(VOP_REG_HS_OUTPUT, bEnable, VOP_FRAME_RST2);
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            HAL_WriteRegBit(SUB_REG(VOP_REG_YC422_EN_H), bEnable, VOP_FRAME_RST);
            // M7332/M7632/M7642 VOP_FRAME_RST and VOP_FRAME_RST2 have to set the same value.
            HAL_WriteRegBit(SUB_REG(VOP_REG_HS_OUTPUT), bEnable, VOP_FRAME_RST2);
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            bRet = FALSE;
            break;
        }
    }
    return bRet;
}

MS_BOOL HAL_MVOP_SetClock(MVOP_DevID eDevID, MVOP_FREQUENCY eFrequency)
{
    MS_BOOL bRet = FALSE;

    if (g_pHalMVOPCtx == NULL)
    {
        MVOP_DBG(MVOP_PRINTF("%s g_pHalMVOPCtx is NULL pointer\n", __FUNCTION__);)
        return bRet;
    }

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            g_pHalMVOPCtx->eClock = eFrequency;
            bRet = TRUE;
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            g_pHalMVOPCtx->eSubClock = eFrequency;
            bRet = TRUE;
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
    return bRet;
}

MVOP_FREQUENCY HAL_MVOP_GetClock(MVOP_DevID eDevID)
{
    MVOP_FREQUENCY eRet = E_MVOP_FREQ_NOT_SUPPORT;

    if (g_pHalMVOPCtx == NULL)
    {
        MVOP_DBG(MVOP_PRINTF("%s g_pHalMVOPCtx is NULL pointer\n", __FUNCTION__);)
        return eRet;
    }

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            eRet = g_pHalMVOPCtx->eClock;
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            eRet = g_pHalMVOPCtx->eSubClock;
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
    return eRet;
}

MS_BOOL HAL_MVOP_SetHSDIndex(MVOP_DevID eDevID, MS_BOOL bEnable, MS_U16 u16SourceWdh, MS_U16 u16OutputWdh)
{
    MS_U32 u32Index = 0;
    MS_BOOL bRet = TRUE;

    if ((u16SourceWdh > u16OutputWdh) && (bEnable))
    {
        u32Index = ((MS_U32)((((MS_U64)(u16OutputWdh)) * 0x200000ul) / (u16SourceWdh) + 1) / 2);
        u32Index &= 0x7fffff; //23 bits
        g_pHalMVOPCtx->u16HSDOutput = u16OutputWdh;
    }
    else
    {
        if (bEnable)
        {
            MVOP_PRINTF("[%s] source size = %d is smaller/equal than/to output size = %d\n",
                        __FUNCTION__, u16SourceWdh, u16OutputWdh);
            MVOP_PRINTF("[%s] force disable HSD\n", __FUNCTION__);
            bRet = FALSE;
        }
        HAL_WriteRegBit(VOP_EXT_HSD_SEL, FALSE, HSD_ENABLE);
        g_pHalMVOPCtx->bHSD = FALSE;
        g_pHalMVOPCtx->u16HSDOutput = 0;

        return bRet;
    }

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            HAL_WriteRegBit(VOP_EXT_HSD_SEL, TRUE, HSD_ENABLE);
            g_pHalMVOPCtx->bHSD = TRUE;
            HAL_Write2Byte(VOP_EXT_HFACIN_L, u32Index);
            HAL_WriteByteMask(VOP_EXT_HFACIN_H, (u32Index >> 16), HFACIN_HB_MASK);
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            MVOP_PRINTF("[%s] HSD do not support sub mvop\n", __FUNCTION__);
            bRet = FALSE;
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            bRet = FALSE;
            break;
        }
    }

    return bRet;
}

MS_BOOL HAL_MVOP_GetHSDCap(MVOP_DevID eDevID)
{
    MS_BOOL bRet = FALSE;

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            bRet = TRUE;
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            MVOP_PRINTF("[%s] HSD do not support sub mvop\n", __FUNCTION__);
            bRet = FALSE;
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            bRet = FALSE;
            break;
        }
    }
    return bRet;
}

MS_BOOL HAL_MVOP_GetIsDMSMode(MVOP_DevID eID)
{
    switch (eID)
    {
        case E_MVOP_DEV_0:
        {
            return g_pHalMVOPCtx->bIsDMSMCU;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            return g_pHalMVOPCtx->bSubIsDMSMCU;
        }
#endif
        default:
            return FALSE;
    }
}

void HAL_MVOP_GetDataSize(MVOP_DevID eID, MVOP_SetImageWH* stDataSize)
{
    MS_BOOL bIsMCUMode;
    switch (eID)
    {
        case E_MVOP_DEV_0:
            bIsMCUMode = (HAL_ReadRegBit(VOP_MPG_JPG_SWITCH, BIT1) == BIT1) ? TRUE : FALSE;
            if (bIsMCUMode)
            {
                if ((g_pHalMVOPCtx->u16CropXSize == 0) || (g_pHalMVOPCtx->u16CropYSize == 0))
                {
                    stDataSize->u16Width = HAL_Read2Byte(VOP_JPG_HSIZE);
                    stDataSize->u16Height = HAL_Read2Byte(VOP_JPG_VSIZE);
                }
                else
                {
                    /*HDR needs to know mvop actual size(after alignment),
                    but if use register value,
                    double buffer may cause get value delay*/
                    stDataSize->u16Width = g_pHalMVOPCtx->u16CropXSize;
                    stDataSize->u16Height = g_pHalMVOPCtx->u16CropYSize;
                }
            }
            else
            {
                HAL_WriteByteMask(VOP_DEBUG_2F_H, BIT5, VOP_RIU_DEBUG_SEL);
                stDataSize->u16Width = HAL_Read2Byte(VOP_DEBUG_2E)&SizeMask;
                stDataSize->u16Height = HAL_Read2Byte(VOP_DEBUG_2F_L)&SizeMask;
                HAL_WriteByteMask(VOP_DEBUG_2F_H, 0, VOP_RIU_DEBUG_SEL);
            }
            break;
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
            bIsMCUMode = (HAL_ReadRegBit(SUB_REG(VOP_MPG_JPG_SWITCH), BIT1) == BIT1) ? TRUE : FALSE;
            if (bIsMCUMode)
            {
                if ((g_pHalMVOPCtx->u16SubCropXSize == 0) || (g_pHalMVOPCtx->u16SubCropYSize == 0))
                {
                    stDataSize->u16Width = HAL_Read2Byte(SUB_REG(VOP_JPG_HSIZE));;
                    stDataSize->u16Height = HAL_Read2Byte(SUB_REG(VOP_JPG_VSIZE));;
                }
                else
                {
                    /*HDR needs to know mvop actual size(after alignment),
                    but if use register value,
                    double buffer may cause get value delay*/
                    stDataSize->u16Width = g_pHalMVOPCtx->u16SubCropXSize;
                    stDataSize->u16Height = g_pHalMVOPCtx->u16SubCropYSize;
                }
            }
            else
            {
                HAL_WriteByteMask(SUB_REG(VOP_DEBUG_2F_H), BIT5, VOP_RIU_DEBUG_SEL);
                stDataSize->u16Width = HAL_Read2Byte(SUB_REG(VOP_DEBUG_2E))&SizeMask;
                stDataSize->u16Height = HAL_Read2Byte(SUB_REG(VOP_DEBUG_2F_L))&SizeMask;
                HAL_WriteByteMask(VOP_DEBUG_2F_H, 0, VOP_RIU_DEBUG_SEL);
            }
            break;
#endif
        default:
            MVOP_PRINTF("Attention! %s Not support eID=%u yet\n", __FUNCTION__, eID);
            break;
    }
}

MS_U64 HAL_MVOP_GetHardwareClock(MVOP_DevID eDevID, MVOP_FREQUENCY eClock)
{
    MS_U64 u64HardwareClock = 0;

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            switch (eClock)
            {
                case E_MVOP_HARDWAREMODE:
                {
                    MS_U32 u32ScpllSet = 0;
                    u32ScpllSet |= HAL_ReadByte(REG_SCPLL_SET_H);
                    u32ScpllSet <<= 16;
                    u32ScpllSet |= HAL_Read2Byte(REG_SCPLL_SET_L);
                    u64HardwareClock = MPLL_CLOCK_432 * SCPLL_SET_VAL * SCPLL_WEIGHT / u32ScpllSet;

                    // Check whether SCPLL_DEFAULT_WEIGHT == 8
                    if ((HAL_Read2Byte(REG_SCPLL_TEST) != SCPLL_TEST_VAL)
                            && (HAL_ReadRegBit(REG_SCPLL_DIV_CTRL0_L, SCPLL_IN_DIV0) != SCPLL_IN_DIV0_VAL)
                            && (HAL_ReadRegBit(REG_SCPLL_DIV_CTRL0_H, SCPLL_LOOP_DIV0) != SCPLL_LOOP_DIV0_VAL)
                            && (HAL_ReadByte(REG_SCPLL_DIV_CTRL1_L) != SCPLL_LOOP_DIV1_VAL)
                            && (HAL_ReadRegBit(REG_SCPLL_DIV_CTRL1_H, SCPLL_OUT_DIV) != SCPLL_OUT_DIV_VAL)
                            && (HAL_ReadRegBit(REG_SCPLL_TEST_EN, SCPLL_ICP_ICTRL) != SCPLL_ICP_ICTRL_VAL))
                    {
                        MVOP_PRINTF("[%s] SCPLL_WEIGHT != 8\n", __FUNCTION__);
                    }
                    break;
                }
                case E_MVOP_FREQ_NOT_SUPPORT:
                {
                    break;
                }
                default:
                {
                    u64HardwareClock = eClock;
                    break;
                }
            }
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            u64HardwareClock = eClock;
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
    return u64HardwareClock;
}

MS_BOOL HAL_MVOP_SetFineTune(MVOP_DevID eDevID, MS_U16 u16FineTuneCount)
{
    MS_BOOL bRet = FALSE;

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            // Disable FineTune and clear the val
            if (0 == u16FineTuneCount)
            {
                HAL_Write2Byte(VOP_EXT_FINE_TUNE_L, 0);
            }
            else
            {
                HAL_WriteByte(VOP_EXT_FINE_TUNE_L, LOWBYTE(u16FineTuneCount));
                HAL_WriteByteMask(VOP_EXT_FINE_TUNE_H, HIGHBYTE(u16FineTuneCount), FINE_TUNE_HCOUNT_H);
                HAL_WriteRegBit(VOP_EXT_FINE_TUNE_H, TRUE, FINE_TUNE_EN);
            }
            bRet = TRUE;
            break;
        }
#if MVOP_SUPPORT_SUB
        // Sub MVOP not support FineTune feature
        case E_MVOP_DEV_1:
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
    return bRet;
}

MS_BOOL HAL_MVOP_GetOptimizedBlank(MVOP_DevID eDevID, MVOP_VidStat* pVidStat, MVOP_Blank* pBlank)
{
#if OPTIMIZED_BLANK
    MS_BOOL bRet = TRUE;

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
#endif
        {
            switch (pVidStat->u16VerSize)
            {
                case VSIZE_UHD:
                {
                    switch (pVidStat->u16FrameRate)
                    {
                        case FRAMERATE_60000:
                        case FRAMERATE_30000:
                        {
                            pBlank->u16VBlankFront = OPTIMIZED_VBLANK_UHD_FRONT_60000;
                            break;
                        }
                        case FRAMERATE_59940:
                        case FRAMERATE_29970:
                        {
                            pBlank->u16VBlankFront = OPTIMIZED_VBLANK_UHD_FRONT_59940;
                            break;
                        }
                        case FRAMERATE_50000:
                        case FRAMERATE_25000:
                        {
                            pBlank->u16VBlankFront = OPTIMIZED_VBLANK_UHD_FRONT_50000;
                            break;
                        }
                        case FRAMERATE_48000:
                        case FRAMERATE_24000:
                        {
                            pBlank->u16VBlankFront = OPTIMIZED_VBLANK_UHD_FRONT_48000;
                            break;
                        }
                        case FRAMERATE_23976:
                        {
                            pBlank->u16VBlankFront = OPTIMIZED_VBLANK_UHD_FRONT_23976;
                            break;
                        }
                        default:
                        {
                            bRet = FALSE;
                            break;
                        }
                    }
                    break;
                }
                case VSIZE_FHD0:
                {
                    switch (pVidStat->u16FrameRate)
                    {
                        case FRAMERATE_60000:
                        {
                            pBlank->u16VBlankFront = OPTIMIZED_VBLANK_FHD0_FRONT_60000;
                            break;
                        }
                        case FRAMERATE_59940:
                        {
                            pBlank->u16VBlankFront = OPTIMIZED_VBLANK_FHD0_FRONT_59940;
                            break;
                        }
                        case FRAMERATE_50000:
                        {
                            pBlank->u16VBlankFront = OPTIMIZED_VBLANK_FHD0_FRONT_50000;
                            pBlank->u16VBlankBack = OPTIMIZED_VBLANK_FHD0_BACK_50000;
                            break;
                        }
                        case FRAMERATE_48000:
                        {
                            pBlank->u16VBlankFront = OPTIMIZED_VBLANK_FHD0_FRONT_48000;
                            break;
                        }
                        case FRAMERATE_23976:
                        {
                            pBlank->u16HBlankHD = OPTIMIZED_HBLANK_FHD_23976;
                            break;
                        }
                        default:
                        {
                            bRet = FALSE;
                            break;
                        }
                    }
                    break;
                }
                case VSIZE_FHD1:
                {
                    switch (pVidStat->u16FrameRate)
                    {
                        case FRAMERATE_60000:
                        {
                            pBlank->u16VBlankFront = OPTIMIZED_VBLANK_FHD1_FRONT_60000;
                            break;
                        }
                        case FRAMERATE_59940:
                        {
                            pBlank->u16VBlankFront = OPTIMIZED_VBLANK_FHD1_FRONT_59940;
                            break;
                        }
                        case FRAMERATE_50000:
                        {
                            pBlank->u16VBlankFront = OPTIMIZED_VBLANK_FHD1_FRONT_50000;
                            pBlank->u16VBlankBack = OPTIMIZED_VBLANK_FHD1_BACK_50000;
                            break;
                        }
                        case FRAMERATE_48000:
                        {
                            pBlank->u16VBlankFront = OPTIMIZED_VBLANK_FHD1_FRONT_48000;
                            break;
                        }
                        case FRAMERATE_23976:
                        {
                            pBlank->u16VBlankFront = OPTIMIZED_VBLANK_FHD1_FRONT_23976;
                            pBlank->u16HBlankHD = OPTIMIZED_HBLANK_FHD_23976;
                            break;
                        }
                        default:
                        {
                            bRet = FALSE;
                            break;
                        }
                    }
                    break;
                }
                default:
                {
                    bRet = FALSE;
                    break;
                }
            }
            break;
        }
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            bRet = FALSE;
            break;
        }
    }
    return bRet;
#else
    UNUSED(eDevID);
    UNUSED(pVidStat);
    UNUSED(pBlank);
    return FALSE;
#endif
}

MS_BOOL HAL_MVOP_SupportPatDB(void)
{
    return TRUE;
}

MS_BOOL HAL_MVOP_SetOneField(MVOP_DevID eDevID, MS_BOOL bEnable)
{
    MS_BOOL bRet = FALSE;

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            g_pHalMVOPCtx->bOneField = bEnable;
            if (TRUE == bEnable)
            {
                HAL_WriteRegBit(VOP_REG_DUMMY, FALSE, VOP_REG_FIELD_BYPASS);
            }
            bRet = TRUE;
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            g_pHalMVOPCtx->bSubOneField = bEnable;
            if (TRUE == bEnable)
            {
                HAL_WriteRegBit(SUB_REG(VOP_REG_DUMMY), FALSE, VOP_REG_FIELD_BYPASS);
            }
            bRet = TRUE;
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
    return bRet;
}

MS_BOOL HAL_MVOP_SetFDMask(MVOP_DevID eDevID, MS_BOOL bEnable)
{
    MS_BOOL bRet = FALSE;

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            HAL_WriteRegBit(VOP_SW_FDMASK, bEnable, VOP_FDMASK);
            HAL_WriteRegBit(VOP_SW_FDMASK, bEnable, VOP_FORCE_BOB);
            bRet = TRUE;
            break;
        }
        case E_MVOP_DEV_1:
        {
            HAL_WriteRegBit(SUB_REG(VOP_SW_FDMASK), bEnable, VOP_FDMASK);
            HAL_WriteRegBit(SUB_REG(VOP_SW_FDMASK), bEnable, VOP_FORCE_BOB);
            bRet = TRUE;
            break;
        }
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
    return bRet;
}

MS_BOOL HAL_MVOP_SetAverageMode(MVOP_DevID eDevID, MS_BOOL bEnable)
{
    MS_BOOL bRet = FALSE;

    switch (eDevID)
    {
        case E_MVOP_DEV_0:
        {
            HAL_WriteRegBit(VOP_REG_4K2K_2P, bEnable, VOP_HSD_EN);
            bRet = TRUE;
            break;
        }
#if MVOP_SUPPORT_SUB
        case E_MVOP_DEV_1:
        {
            HAL_WriteRegBit(SUB_REG(VOP_REG_4K2K_2P), bEnable, VOP_HSD_EN);
            bRet = TRUE;
            break;
        }
#endif
        default:
        {
            MVOP_PRINTF("[%s] MVOP not support Device ID\n", __FUNCTION__);
            break;
        }
    }
    return bRet;
}

MS_BOOL HAL_MVOPGetDSRegVal(MVOP_DevID eDevID, MVOP_DSGetValue* pDSVal)
{
    return FALSE;
}
///////////////////////   Sub MVOP   ////////////////////////
#if MVOP_SUPPORT_SUB
void HAL_MVOP_SubRegSetBase(MS_VIRT u32Base)
{
    u32RiuBaseAdd = u32Base;
}

void HAL_MVOP_SubEnableMVDInterface(MS_BOOL bEnable)
{
    MVOP_PRINTF("\n[%s] MVOP driver switch to MCU mode\n", __FUNCTION__);
}

#endif

MS_BOOL HAL_MVOP_IntEnableMask(MVOP_DevID eID, MS_U8 eIntType)
{
    UNUSED(eID);
    UNUSED(eIntType);
    return FALSE;
}

MS_U8 HAL_MVOP_IntGetStatus(MVOP_DevID eID)
{
    UNUSED(eID);
    return 0;
}
