//<MStar Software>
//******************************************************************************
// MStar Software
// Copyright (c) 2010 - 2012 MStar Semiconductor, Inc. All rights reserved.
// All software, firmware and related documentation herein ("MStar Software") are
// intellectual property of MStar Semiconductor, Inc. ("MStar") and protected by
// law, including, but not limited to, copyright law and international treaties.
// Any use, modification, reproduction, retransmission, or republication of all
// or part of MStar Software is expressly prohibited, unless prior written
// permission has been granted by MStar.
//
// By accessing, browsing and/or using MStar Software, you acknowledge that you
// have read, understood, and agree, to be bound by below terms ("Terms") and to
// comply with all applicable laws and regulations:
//
// 1. MStar shall retain any and all right, ownership and interest to MStar
//    Software and any modification/derivatives thereof.
//    No right, ownership, or interest to MStar Software and any
//    modification/derivatives thereof is transferred to you under Terms.
//
// 2. You understand that MStar Software might include, incorporate or be
//    supplied together with third party`s software and the use of MStar
//    Software may require additional licenses from third parties.
//    Therefore, you hereby agree it is your sole responsibility to separately
//    obtain any and all third party right and license necessary for your use of
//    such third party`s software.
//
// 3. MStar Software and any modification/derivatives thereof shall be deemed as
//    MStar`s confidential information and you agree to keep MStar`s
//    confidential information in strictest confidence and not disclose to any
//    third party.
//
// 4. MStar Software is provided on an "AS IS" basis without warranties of any
//    kind. Any warranties are hereby expressly disclaimed by MStar, including
//    without limitation, any warranties of merchantability, non-infringement of
//    intellectual property rights, fitness for a particular purpose, error free
//    and in conformity with any international standard.  You agree to waive any
//    claim against MStar for any loss, damage, cost or expense that you may
//    incur related to your use of MStar Software.
//    In no event shall MStar be liable for any direct, indirect, incidental or
//    consequential damages, including without limitation, lost of profit or
//    revenues, lost or damage of data, and unauthorized system use.
//    You agree that this Section 4 shall still apply without being affected
//    even if MStar Software has been modified by MStar in accordance with your
//    request or instruction for your use, except otherwise agreed by both
//    parties in writing.
//
// 5. If requested, MStar may from time to time provide technical supports or
//    services in relation with MStar Software to you for your use of
//    MStar Software in conjunction with your or your customer`s product
//    ("Services").
//    You understand and agree that, except otherwise agreed by both parties in
//    writing, Services are provided on an "AS IS" basis and the warranty
//    disclaimer set forth in Section 4 above shall apply.
//
// 6. Nothing contained herein shall be construed as by implication, estoppels
//    or otherwise:
//    (a) conferring any license or right to use MStar name, trademark, service
//        mark, symbol or any other identification;
//    (b) obligating MStar or any of its affiliates to furnish any person,
//        including without limitation, you and your customers, any assistance
//        of any kind whatsoever, or any information; or
//    (c) conferring any license or right under any intellectual property right.
//
// 7. These terms shall be governed by and construed in accordance with the laws
//    of Taiwan, R.O.C., excluding its conflict of law rules.
//    Any and all dispute arising out hereof or related hereto shall be finally
//    settled by arbitration referred to the Chinese Arbitration Association,
//    Taipei in accordance with the ROC Arbitration Law and the Arbitration
//    Rules of the Association by three (3) arbitrators appointed in accordance
//    with the said Rules.
//    The place of arbitration shall be in Taipei, Taiwan and the language shall
//    be English.
//    The arbitration award shall be final and binding to both parties.
//
//******************************************************************************
//<MStar Software>
////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2008-2009 MStar Semiconductor, Inc.
// All rights reserved.
//
// Unless otherwise stipulated in writing, any and all information contained
// herein regardless in any format shall remain the sole proprietary of
// MStar Semiconductor Inc. and be kept in strict confidence
// ("MStar Confidential Information") by the recipient.
// Any unauthorized act including without limitation unauthorized disclosure,
// copying, use, reproduction, sale, distribution, modification, disassembling,
// reverse engineering and compiling of the contents of MStar Confidential
// Information is unlawful and strictly prohibited. MStar hereby reserves the
// rights to any and all damages, losses, costs and expenses resulting therefrom.
//
////////////////////////////////////////////////////////////////////////////////
//==============================================================================
// [mhal_sc.c]
// Date: 20081203
// Descriptions: Add a new layer for HW setting
//==============================================================================
#define  MHAL_PIP_C

#include "MsCommon.h"
#include "mhal_xc_chip_config.h"
#include "utopia.h"
#include "utopia_dapi.h"
#include "drvXC_IOPort.h"
#include "apiXC.h"
#include "apiXC_PCMonitor.h"
#include "xc_hwreg_utility2.h"
#include "hwreg_sc.h"
#include "drv_sc_menuload.h"
#include "mvideo_context.h"
#include "drv_sc_ip.h"
#include "mhal_sc.h"

#include "drv_sc_display.h"
#include "drv_sc_isr.h"
#include "apiXC_Adc.h"
#include "apiXC_ModeParse.h"
#include "apiXC_Auto.h"
#include "drvXC_HDMI_if.h"
#include "mvideo_context.h"
#if (LD_ENABLE==1)
#include "mdrv_ld.h"
#include "mdrv_ldalgo.h"
#endif
#include "mdrv_sc_3d.h"
#include "drvXC_ADC_Internal.h"
#if FRC_INSIDE
#include "mdrv_frc.h"
#include "mhal_frc.h"
#endif
#include "XC_private.h"
#if defined(MSOS_TYPE_LINUX_KERNEL)
#include <linux/string.h>
#else
#include <string.h>
#endif

//==============================================================================
void _Hal_SC_Sub_SetStgenWindow_burst(void *pInstance, MS_WINDOW_TYPE *pstDispWin)
{
#if (FRC_INSIDE && (HW_DESIGN_4K2K_VER == 6))
    XC_INSTANCE_PRIVATE *psXCInstPri = NULL;
    UtopiaInstanceGetPrivate(pInstance, (void**)&psXCInstPri);
    XC_RESOURCE_PRIVATE* pXCResourcePrivate = NULL;
    UtopiaResourceGetPrivate(g_pXCResource[_XC_SELECT_INTERNAL_VARIABLE(psXCInstPri->u32DeviceID)],(void**)(&pXCResourcePrivate));

    //when sc0 sub enable,should set fsc sub de window
    if(IsFSCOrFRCEnable())
    {
        MS_U16 u16BK0F_07 = pstDispWin->x;
        MS_U16 u16BK0F_08 = pstDispWin->width + pstDispWin->x - 1;
        MS_U16 u16BK0F_09 = pstDispWin->y;
        MS_U16 u16BK0F_0A = pstDispWin->height + pstDispWin->y - 1;

        MS_U16 u16DsipHstart = 0;
        MS_U16 u16DsipHend = 0;
        MS_U16 u16DsipVstart = 0;
        MS_U16 u16DsipVend = 0;
        if(MHal_FRC_IsFHDToFSC(pInstance,MAIN_WINDOW))
        {
            u16DsipHstart = SC_R2BYTEMSK( psXCInstPri->u32DeviceID, REG_SC_BK68_03_L, 0x3FFF)+
                (u16BK0F_07 - SC_R2BYTEMSK( psXCInstPri->u32DeviceID, REG_SC_BK10_04_L, 0x3FFF))/2;
            u16DsipHend = u16DsipHstart + (u16BK0F_08 - u16BK0F_07 + 1)/2-1;
            u16DsipVstart = SC_R2BYTEMSK( psXCInstPri->u32DeviceID, REG_SC_BK68_0B_L, 0x1FFF)+
                (u16BK0F_09 - SC_R2BYTEMSK( psXCInstPri->u32DeviceID, REG_SC_BK10_06_L, 0x1FFF))/2;
            u16DsipVend = u16DsipVstart + (u16BK0F_0A - u16BK0F_09 + 1)/2-1;

            MDrv_XC_MLoad_WriteCmd(pInstance, REG_SC_BK68_10_L, u16DsipHstart&~1, 0x3FFF);
            MDrv_XC_MLoad_WriteCmd(pInstance, REG_SC_BK68_11_L, u16DsipHend, 0x3FFF);
            MDrv_XC_MLoad_WriteCmd(pInstance, REG_SC_BK68_12_L, u16DsipVstart, 0x1FFF);
            MDrv_XC_MLoad_WriteCmd(pInstance, REG_SC_BK68_13_L, u16DsipVend, 0x1FFF);
        }
        else
        {
            u16DsipHstart = SC_R2BYTEMSK( psXCInstPri->u32DeviceID, REG_SC_BK68_03_L, 0x3FFF)+
                (u16BK0F_07 - SC_R2BYTEMSK( psXCInstPri->u32DeviceID, REG_SC_BK10_04_L, 0x3FFF));
            u16DsipHend = u16DsipHstart + (u16BK0F_08 - u16BK0F_07 + 1)-1;
            u16DsipVstart = SC_R2BYTEMSK( psXCInstPri->u32DeviceID, REG_SC_BK68_0B_L, 0x1FFF)+
                (u16BK0F_09 - SC_R2BYTEMSK( psXCInstPri->u32DeviceID, REG_SC_BK10_06_L, 0x1FFF));
            u16DsipVend = u16DsipVstart + (u16BK0F_0A - u16BK0F_09 + 1)-1;

            MDrv_XC_MLoad_WriteCmd(pInstance, REG_SC_BK68_10_L, u16DsipHstart&~1, 0x3FFF);
            MDrv_XC_MLoad_WriteCmd(pInstance, REG_SC_BK68_11_L, u16DsipHend, 0x3FFF);
            MDrv_XC_MLoad_WriteCmd(pInstance, REG_SC_BK68_12_L, u16DsipVstart, 0x1FFF);
            MDrv_XC_MLoad_WriteCmd(pInstance, REG_SC_BK68_13_L, u16DsipVend, 0x1FFF);
        }
    }
#endif
}

void _Hal_SC_Sub_SetStgenWindow(void *pInstance, MS_WINDOW_TYPE *pstDispWin)
{
#if (FRC_INSIDE && (HW_DESIGN_4K2K_VER == 6))
    XC_INSTANCE_PRIVATE *psXCInstPri = NULL;
    UtopiaInstanceGetPrivate(pInstance, (void**)&psXCInstPri);
    XC_RESOURCE_PRIVATE* pXCResourcePrivate = NULL;
    UtopiaResourceGetPrivate(g_pXCResource[_XC_SELECT_INTERNAL_VARIABLE(psXCInstPri->u32DeviceID)],(void**)(&pXCResourcePrivate));

    //when sc0 sub enable,should set fsc sub de window
    if(IsFSCOrFRCEnable())
    {
        MS_U16 u16BK0F_07 = pstDispWin->x;
        MS_U16 u16BK0F_08 = pstDispWin->width + pstDispWin->x - 1;
        MS_U16 u16BK0F_09 = pstDispWin->y;
        MS_U16 u16BK0F_0A = pstDispWin->height + pstDispWin->y - 1;

        MS_U16 u16DsipHstart = 0;
        MS_U16 u16DsipHend = 0;
        MS_U16 u16DsipVstart = 0;
        MS_U16 u16DsipVend = 0;
        if(MHal_FRC_IsFHDToFSC(pInstance,MAIN_WINDOW))
        {
            u16DsipHstart = SC_R2BYTEMSK(psXCInstPri->u32DeviceID, REG_SC_BK68_03_L, 0x3FFF)+
                (u16BK0F_07 - SC_R2BYTEMSK( psXCInstPri->u32DeviceID, REG_SC_BK10_04_L, 0x3FFF))/2;
            u16DsipHend = u16DsipHstart + (u16BK0F_08 - u16BK0F_07 + 1)/2-1;
            u16DsipVstart = SC_R2BYTEMSK(psXCInstPri->u32DeviceID, REG_SC_BK68_0B_L, 0x1FFF)+
                (u16BK0F_09 - SC_R2BYTEMSK( psXCInstPri->u32DeviceID, REG_SC_BK10_06_L, 0x1FFF))/2;
            u16DsipVend = u16DsipVstart + (u16BK0F_0A - u16BK0F_09 + 1)/2-1;

            SC_W2BYTE(psXCInstPri->u32DeviceID, REG_SC_BK68_10_L, u16DsipHstart&~1);
            SC_W2BYTE(psXCInstPri->u32DeviceID, REG_SC_BK68_11_L, u16DsipHend);
            SC_W2BYTE(psXCInstPri->u32DeviceID, REG_SC_BK68_12_L, u16DsipVstart);
            SC_W2BYTE(psXCInstPri->u32DeviceID, REG_SC_BK68_13_L, u16DsipVend);
        }
        else
        {
            u16DsipHstart = SC_R2BYTEMSK( psXCInstPri->u32DeviceID, REG_SC_BK68_03_L, 0x3FFF)+
                (u16BK0F_07 - SC_R2BYTEMSK( psXCInstPri->u32DeviceID, REG_SC_BK10_04_L, 0x3FFF));
            u16DsipHend = u16DsipHstart + (u16BK0F_08 - u16BK0F_07 + 1)-1;
            u16DsipVstart = SC_R2BYTEMSK( psXCInstPri->u32DeviceID, REG_SC_BK68_0B_L, 0x1FFF)+
                (u16BK0F_09 - SC_R2BYTEMSK( psXCInstPri->u32DeviceID, REG_SC_BK10_06_L, 0x1FFF));
            u16DsipVend = u16DsipVstart + (u16BK0F_0A - u16BK0F_09 + 1)-1;

            SC_W2BYTE(psXCInstPri->u32DeviceID, REG_SC_BK68_10_L, u16DsipHstart&~1);
            SC_W2BYTE(psXCInstPri->u32DeviceID, REG_SC_BK68_11_L, u16DsipHend);
            SC_W2BYTE(psXCInstPri->u32DeviceID, REG_SC_BK68_12_L, u16DsipVstart);
            SC_W2BYTE(psXCInstPri->u32DeviceID, REG_SC_BK68_13_L, u16DsipVend);
        }
    }
#endif
}

void Hal_SC_Sub_SetDisplayWindow_burst(void *pInstance, MS_WINDOW_TYPE *pstDispWin)
{
    MS_U16 u16extra_req;
    MS_WINDOW_TYPE stDspwin;
    memset(&stDspwin, 0, sizeof(MS_WINDOW_TYPE));

    XC_INSTANCE_PRIVATE *psXCInstPri = NULL;
    UtopiaInstanceGetPrivate(pInstance, (void**)&psXCInstPri);
    _MLOAD_ENTRY(pInstance);

    // When Main is foreground, sub is background, extra must enable.

    u16extra_req = 0x01;
    MS_U16 DispWinEnd = pstDispWin->x + pstDispWin->width-1 ;

    if(Hal_SC_is_extra_req_en(pInstance, NULL, NULL , &pstDispWin->x , &DispWinEnd))
    {
        MDrv_XC_MLoad_WriteCmd(pInstance, REG_SC_BK20_11_L, BIT(15), BIT(15));

        u16extra_req = u16extra_req | 0x8000;
    }

    //this is moved outside this function to mdrv_sc_pip.c
    //MApi_XC_MLoad_WriteCmd(REG_SC_BK20_10_L, (TRUE<<1), BIT(1));

    // HW PIP architeucture
    // Becasue BK3_02[8] and BK20_11[15] can not enable toghter, otherwise garbage will be showed,
    // we need to use BK12_47[0] to instead. And the default value of BK3_02[8] is 1. So, we need
    // to set it to 0 in this function.
    MDrv_XC_MLoad_WriteCmd(pInstance, REG_SC_BK20_11_L, u16extra_req , 0x800F);
    MDrv_XC_MLoad_WriteCmd(pInstance, REG_SC_BK03_02_L, 0, 0x0080);

#if PIP_PATCH_USING_SC1_MAIN_AS_SC0_SUB
    if (psXCInstPri->u32DeviceID == 0)
    {
        //Display window
        MDrv_XC_MLoad_WriteCmd(pInstance, REG_SC_BK0F_07_L, pstDispWin->x,0xFFFF);                             // Display H start
        MDrv_XC_MLoad_WriteCmd(pInstance, REG_SC_BK0F_08_L, pstDispWin->width + pstDispWin->x - 1,0xFFFF);    // Display H end
        MDrv_XC_MLoad_WriteCmd(pInstance, REG_SC_BK0F_09_L, pstDispWin->y,0xFFFF);                             // Display V start
        MDrv_XC_MLoad_WriteCmd(pInstance, REG_SC_BK0F_0A_L, pstDispWin->height + pstDispWin->y - 1,0xFFFF);   // Display V end
        //when sc0 sub enable,should set fsc sub de window
        _Hal_SC_Sub_SetStgenWindow_burst(pInstance, pstDispWin);
    }
    else
    {
        //FIX ME:review follow HW_DESIGN_4K2K_VER = 6 rule
        MS_U16 u16HDEStart = SC_R2BYTE(0, REG_SC_BK10_04_L);
        //Display window
        MDrv_XC_MLoad_WriteCmd(g_pDevice0Instance, REG_SC_BK0F_07_L, pstDispWin->x,0xFFFF);                             // Display H start
        MDrv_XC_MLoad_WriteCmd(g_pDevice0Instance, REG_SC_BK0F_08_L, pstDispWin->width + pstDispWin->x - 1,0xFFFF);    // Display H end
        MDrv_XC_MLoad_WriteCmd(g_pDevice0Instance, REG_SC_BK0F_09_L, pstDispWin->y,0xFFFF);                             // Display V start
        MDrv_XC_MLoad_WriteCmd(g_pDevice0Instance, REG_SC_BK0F_0A_L, pstDispWin->height + pstDispWin->y - 1,0xFFFF);   // Display V end

        //Display window
        MDrv_XC_MLoad_WriteCmd(pInstance, REG_SC_BK10_08_L, u16HDEStart/2,VOP_DISPLAY_HSTART_MASK);//temp solution(+90)
        MDrv_XC_MLoad_WriteCmd(pInstance, REG_SC_BK10_09_L, (u16HDEStart/2+ pstDispWin->width - 1),VOP_DISPLAY_HEND_MASK);
        if (Hal_SC_NeedXCH8Align(pInstance))
        {
            stDspwin.x = u16HDEStart / 2;
            stDspwin.width = pstDispWin->width;
        }

        // Maxim: Copy MDE to FDE for SC1 case
        MDrv_XC_MLoad_WriteCmd(pInstance, REG_SC_BK10_04_L, u16HDEStart/2,VOP_DISPLAY_HSTART_MASK);//temp solution(+90)
        MDrv_XC_MLoad_WriteCmd(pInstance, REG_SC_BK10_05_L, (u16HDEStart/2+ pstDispWin->width - 1),VOP_DISPLAY_HEND_MASK);

        if (SC_R2BYTEMSK(0, REG_SC_BK68_50_L, BIT(3)) == 0)
        {
            MDrv_XC_MLoad_WriteCmd(pInstance, REG_SC_BK10_0A_L, pstDispWin->y - 1,VOP_DISPLAY_VSTART_MASK);
            MDrv_XC_MLoad_WriteCmd(pInstance, REG_SC_BK10_0B_L, pstDispWin->height + pstDispWin->y - 1,VOP_DISPLAY_VEND_MASK);
            if (Hal_SC_NeedXCV8Align(pInstance) || Hal_SC_NeedXCH8Align(pInstance))
            {
                stDspwin.y = pstDispWin->y - 1;
                stDspwin.height = pstDispWin->height;
            }
            // Maxim: Copy MDE to FDE for SC1 case
            MDrv_XC_MLoad_WriteCmd(pInstance, REG_SC_BK10_06_L, pstDispWin->y - 1,VOP_DISPLAY_VSTART_MASK);
            MDrv_XC_MLoad_WriteCmd(pInstance, REG_SC_BK10_07_L, pstDispWin->height + pstDispWin->y - 1,VOP_DISPLAY_VEND_MASK);
        }
        else
        {
            MDrv_XC_MLoad_WriteCmd(pInstance, REG_SC_BK10_0A_L, pstDispWin->y,VOP_DISPLAY_VSTART_MASK);
            MDrv_XC_MLoad_WriteCmd(pInstance, REG_SC_BK10_0B_L, pstDispWin->height + pstDispWin->y - 1,VOP_DISPLAY_VEND_MASK);
            if (Hal_SC_NeedXCV8Align(pInstance) || Hal_SC_NeedXCH8Align(pInstance))
            {
                stDspwin.y = pstDispWin->y;
                stDspwin.height = pstDispWin->height;
            }
            // Maxim: Copy MDE to FDE for SC1 case
            MDrv_XC_MLoad_WriteCmd(pInstance, REG_SC_BK10_06_L, pstDispWin->y,VOP_DISPLAY_VSTART_MASK);
            MDrv_XC_MLoad_WriteCmd(pInstance, REG_SC_BK10_07_L, pstDispWin->height + pstDispWin->y - 1,VOP_DISPLAY_VEND_MASK);
        }
        if (Hal_SC_NeedXCV8Align(pInstance) || Hal_SC_NeedXCH8Align(pInstance))
        {
            Hal_SC_8AlignPatchBy2ndSDE(pInstance, TRUE, &stDspwin);
        }
    }
#else
    //Display window
    MDrv_XC_MLoad_WriteCmd(pInstance, REG_SC_BK0F_07_L, pstDispWin->x, 0xFFFF);                             // Display H start
    MDrv_XC_MLoad_WriteCmd(pInstance, REG_SC_BK0F_08_L, pstDispWin->width + pstDispWin->x - 1, 0xFFFF);    // Display H end
    MDrv_XC_MLoad_WriteCmd(pInstance, REG_SC_BK0F_09_L, pstDispWin->y, 0xFFFF);                             // Display V start
    MDrv_XC_MLoad_WriteCmd(pInstance, REG_SC_BK0F_0A_L, pstDispWin->height + pstDispWin->y - 1, 0xFFFF);   // Display V end
    _Hal_SC_Sub_SetStgenWindow_burst(pInstance, pstDispWin);
#endif
    //HW_SUPPORT_HSV_DEMO_WINDOW
    if (psXCInstPri->u32DeviceID == 0)
    {
        MS_U16 u16tmp = 0;
        u16tmp = pstDispWin->x - SC_R2BYTEMSK( psXCInstPri->u32DeviceID, REG_SC_BK10_04_L, 0x3FFF);
        MDrv_XC_MLoad_WriteCmd_XC_EXT(pInstance, REG_SC_EXT_BK0C_03_L, u16tmp, 0x1FFF);
        u16tmp = pstDispWin->width + pstDispWin->x - 1 - SC_R2BYTEMSK( psXCInstPri->u32DeviceID, REG_SC_BK10_04_L, 0x3FFF);
        MDrv_XC_MLoad_WriteCmd_XC_EXT(pInstance, REG_SC_EXT_BK0C_04_L, u16tmp, 0x1FFF);
        u16tmp = pstDispWin->y - SC_R2BYTEMSK( psXCInstPri->u32DeviceID, REG_SC_BK10_06_L, 0x3FFF);
        MDrv_XC_MLoad_WriteCmd_XC_EXT(pInstance, REG_SC_EXT_BK0C_05_L, u16tmp, 0x1FFF);
        u16tmp = pstDispWin->height + pstDispWin->y - 1 - SC_R2BYTEMSK(psXCInstPri->u32DeviceID, REG_SC_BK10_06_L, 0x1FFF);
        MDrv_XC_MLoad_WriteCmd_XC_EXT(pInstance, REG_SC_EXT_BK0C_06_L, u16tmp, 0x1FFF);
    }

    MDrv_XC_MLoad_Fire(pInstance, TRUE);
    _MLOAD_RETURN(pInstance);
}

void Hal_SC_Sub_SetDisplayWindow(void *pInstance, MS_WINDOW_TYPE *pstDispWin)
{
    //SC_W2BYTEMSK( REG_SC_BK20_10_L, (TRUE<<1), BIT(1));
    MS_WINDOW_TYPE stDspwin;
    memset(&stDspwin, 0, sizeof(MS_WINDOW_TYPE));
    XC_INSTANCE_PRIVATE *psXCInstPri = NULL;
    UtopiaInstanceGetPrivate(pInstance, (void**)&psXCInstPri);
#if PIP_PATCH_USING_SC1_MAIN_AS_SC0_SUB
    //Display window
    SC_W2BYTE(0, REG_SC_BK0F_07_L, pstDispWin->x);                             // Display H start
    SC_W2BYTE(0, REG_SC_BK0F_08_L, pstDispWin->width + pstDispWin->x - 1);    // Display H end
    SC_W2BYTE(0, REG_SC_BK0F_09_L, pstDispWin->y);                             // Display V start
    SC_W2BYTE(0, REG_SC_BK0F_0A_L, pstDispWin->height + pstDispWin->y - 1);   // Display V end
    if (psXCInstPri->u32DeviceID == 1)
    {
        MS_U16 u16HDEStart = SC_R2BYTE(0, REG_SC_BK10_04_L);
        SC_W2BYTE(psXCInstPri->u32DeviceID, REG_SC_BK10_08_L, u16HDEStart/2);//temp solution(+90)
        SC_W2BYTE(psXCInstPri->u32DeviceID, REG_SC_BK10_09_L, (u16HDEStart/2+ pstDispWin->width - 1));
        if (Hal_SC_NeedXCH8Align(pInstance))
        {
            stDspwin.x = u16HDEStart / 2;
            stDspwin.width = pstDispWin->width;
        }

        // Maxim: Copy MDE to FDE for SC1 case
        SC_W2BYTE(psXCInstPri->u32DeviceID, REG_SC_BK10_04_L, u16HDEStart/2);//temp solution(+90)
        SC_W2BYTE(psXCInstPri->u32DeviceID, REG_SC_BK10_05_L, (u16HDEStart/2+ pstDispWin->width - 1));

        if (SC_R2BYTEMSK(0, REG_SC_BK68_50_L, BIT(3)) == 0)
        {
            SC_W2BYTE(psXCInstPri->u32DeviceID, REG_SC_BK10_0A_L, pstDispWin->y - 1);
            SC_W2BYTE(psXCInstPri->u32DeviceID, REG_SC_BK10_0B_L, pstDispWin->height + pstDispWin->y - 1);
            if (Hal_SC_NeedXCV8Align(pInstance) || Hal_SC_NeedXCH8Align(pInstance))
            {
                stDspwin.y = pstDispWin->y - 1;
                stDspwin.height = pstDispWin->height;
            }
            // Maxim: Copy MDE to FDE for SC1 case
            SC_W2BYTE(psXCInstPri->u32DeviceID, REG_SC_BK10_06_L, pstDispWin->y - 1);
            SC_W2BYTE(psXCInstPri->u32DeviceID, REG_SC_BK10_07_L, pstDispWin->height + pstDispWin->y - 1);
        }
        else
        {
            SC_W2BYTE(psXCInstPri->u32DeviceID, REG_SC_BK10_0A_L, pstDispWin->y);
            SC_W2BYTE(psXCInstPri->u32DeviceID, REG_SC_BK10_0B_L, pstDispWin->height + pstDispWin->y - 1);
            if (Hal_SC_NeedXCV8Align(pInstance) || Hal_SC_NeedXCH8Align(pInstance))
            {
                stDspwin.y = pstDispWin->y;
                stDspwin.height = pstDispWin->height;
            }
            // Maxim: Copy MDE to FDE for SC1 case
            SC_W2BYTE(psXCInstPri->u32DeviceID, REG_SC_BK10_06_L, pstDispWin->y);
            SC_W2BYTE(psXCInstPri->u32DeviceID, REG_SC_BK10_07_L, pstDispWin->height + pstDispWin->y - 1);
        }
        if (Hal_SC_NeedXCV8Align(pInstance) || Hal_SC_NeedXCH8Align(pInstance))
        {
            Hal_SC_8AlignPatchBy2ndSDE(pInstance, FALSE, &stDspwin);
        }
    }
    else if(psXCInstPri->u32DeviceID == 0)
    {
        //when sc0 sub enable,should set fsc sub de window
        _Hal_SC_Sub_SetStgenWindow(pInstance, pstDispWin);
    }
#else
    //Display window
    SC_W2BYTE(psXCInstPri->u32DeviceID, REG_SC_BK0F_07_L, pstDispWin->x);                             // Display H start
    SC_W2BYTE(psXCInstPri->u32DeviceID, REG_SC_BK0F_08_L, pstDispWin->width + pstDispWin->x - 1);    // Display H end
    SC_W2BYTE(psXCInstPri->u32DeviceID, REG_SC_BK0F_09_L, pstDispWin->y);                             // Display V start
    SC_W2BYTE(psXCInstPri->u32DeviceID, REG_SC_BK0F_0A_L, pstDispWin->height + pstDispWin->y - 1);   // Display V end
    _Hal_SC_Sub_SetStgenWindow(pInstance, pstDispWin);
#endif
    //HW_SUPPORT_HSV_DEMO_WINDOW
    if (psXCInstPri->u32DeviceID == 0)
    {
        MS_U16 u16tmp = 0;
        u16tmp = pstDispWin->x - SC_R2BYTEMSK( psXCInstPri->u32DeviceID, REG_SC_BK10_04_L, 0x3FFF);
        SC_EXT_W2BYTE(psXCInstPri->u32DeviceID, REG_SC_EXT_BK0C_03_L, u16tmp);
        u16tmp = pstDispWin->width + pstDispWin->x - 1 - SC_R2BYTEMSK( psXCInstPri->u32DeviceID, REG_SC_BK10_04_L, 0x3FFF);
        SC_EXT_W2BYTE(psXCInstPri->u32DeviceID, REG_SC_EXT_BK0C_04_L, u16tmp);
        u16tmp = pstDispWin->y - SC_R2BYTEMSK( psXCInstPri->u32DeviceID, REG_SC_BK10_06_L, 0x3FFF);
        SC_EXT_W2BYTE(psXCInstPri->u32DeviceID, REG_SC_EXT_BK0C_05_L, u16tmp);
        u16tmp = pstDispWin->height + pstDispWin->y - 1 - SC_R2BYTEMSK(psXCInstPri->u32DeviceID, REG_SC_BK10_06_L, 0x1FFF);
        SC_EXT_W2BYTE(psXCInstPri->u32DeviceID, REG_SC_EXT_BK0C_06_L, u16tmp);
    }
}


void Hal_SC_subwindow_disable_burst(void *pInstance)
{
    XC_INSTANCE_PRIVATE *psXCInstPri = NULL;
    UtopiaInstanceGetPrivate(pInstance, (void**)&psXCInstPri);
    _MLOAD_ENTRY(pInstance);
    MDrv_XC_MLoad_WriteCmd(pInstance, REG_SC_BK20_10_L, (FALSE<<1), BIT(1));
#if PIP_PATCH_USING_SC1_MAIN_AS_SC0_SUB
    //FIX ME:temp tgen setting
    MDrv_XC_MLoad_WriteCmd(g_pDevice0Instance, REG_SC_BK68_40_L, 0x00, BIT(4));
#endif
    MDrv_XC_MLoad_WriteCmd(pInstance, REG_SC_BK58_10_L, 0x0, BIT(0));
    MDrv_XC_MLoad_WriteCmd(pInstance, REG_SC_BK20_11_L, 0x0000 , 0x800F);

    MDrv_XC_MLoad_Fire(pInstance, TRUE);
    _MLOAD_RETURN(pInstance);
}

void Hal_SC_subwindow_disable(void *pInstance)
{
    XC_INSTANCE_PRIVATE *psXCInstPri = NULL;
    UtopiaInstanceGetPrivate(pInstance, (void**)&psXCInstPri);
    SC_W2BYTEMSK(psXCInstPri->u32DeviceID, REG_SC_BK20_10_L, (FALSE<<1), BIT(1));
#if PIP_PATCH_USING_SC1_MAIN_AS_SC0_SUB
    //FIX ME:temp tgen setting
    SC_W2BYTEMSK(0, REG_SC_BK68_40_L, 0x00, BIT(4));
#endif
    SC_W2BYTEMSK(psXCInstPri->u32DeviceID, REG_SC_BK58_10_L, 0x0, BIT(0));
    SC_W2BYTEMSK(psXCInstPri->u32DeviceID, REG_SC_BK20_11_L, 0x0000 , 0x800F);
}

MS_BOOL Hal_SC_Is_subwindow_enable(void *pInstance)
{
    XC_INSTANCE_PRIVATE *psXCInstPri = NULL;
    UtopiaInstanceGetPrivate(pInstance, (void**)&psXCInstPri);
    XC_RESOURCE_PRIVATE* pXCResourcePrivate = NULL;
    UtopiaResourceGetPrivate(g_pXCResource[_XC_SELECT_INTERNAL_VARIABLE(psXCInstPri->u32DeviceID)],(void**)(&pXCResourcePrivate));

#if PIP_PATCH_USING_SC1_MAIN_AS_SC0_SUB
    if(!MDrv_XC_GetMWEStatus(pInstance)
        && (E_XC_3D_OUTPUT_MODE_NONE == pXCResourcePrivate->stdrvXC_3D._eOutput3DMode))
    {
        return (SC_R2BYTEMSK(0, REG_SC_BK68_40_L, BIT(4)) == 0)? FALSE:TRUE;
    }
    else
    {
        return (SC_R2BYTEMSK( psXCInstPri->u32DeviceID, REG_SC_BK20_10_L, BIT(1)) == 0)? FALSE:TRUE;
    }
#else
    return (SC_R2BYTEMSK( psXCInstPri->u32DeviceID, REG_SC_BK20_10_L, BIT(1)) == 0)? FALSE:TRUE;
#endif
}


void Hal_SC_set_border_format(void *pInstance, MS_U8 u8Left, MS_U8 u8Right, MS_U8 u8Up, MS_U8 u8Down, MS_U8 u8color, SCALER_WIN eWindow )
{
    XC_INSTANCE_PRIVATE *psXCInstPri = NULL;
    UtopiaInstanceGetPrivate(pInstance, (void**)&psXCInstPri);
    if( eWindow == MAIN_WINDOW && psXCInstPri->u32DeviceID == 0)
    {
        SC_W2BYTEMSK( psXCInstPri->u32DeviceID, REG_SC_BK0F_02_L, ((MS_U16)u8Left<<8), 0xFF00);
        SC_W2BYTEMSK( psXCInstPri->u32DeviceID, REG_SC_BK0F_03_L, ((MS_U16)u8Right<<8), 0xFF00);
        SC_W2BYTEMSK( psXCInstPri->u32DeviceID, REG_SC_BK0F_04_L, ((MS_U16)u8Up<<8), 0xFF00);
        SC_W2BYTEMSK( psXCInstPri->u32DeviceID, REG_SC_BK0F_05_L, ((MS_U16)u8Down<<8), 0xFF00);

        SC_W2BYTEMSK( psXCInstPri->u32DeviceID, REG_SC_BK10_24_L, ((MS_U16)u8color<<8), 0xFF00);
    }
    else
    {
        SC_W2BYTEMSK( 0, REG_SC_BK0F_02_L, (MS_U16)u8Left, 0x00FF);
        SC_W2BYTEMSK( 0, REG_SC_BK0F_03_L, (MS_U16)u8Right, 0x00FF);
        SC_W2BYTEMSK( 0, REG_SC_BK0F_04_L, (MS_U16)u8Up, 0x00FF);
        SC_W2BYTEMSK( 0, REG_SC_BK0F_05_L, (MS_U16)u8Down, 0x00FF);

        SC_W2BYTEMSK( 0, REG_SC_BK0F_17_L, (MS_U16)u8color, 0x00FF);
    }
}

void Hal_SC_border_enable(void *pInstance, MS_BOOL bEnable, SCALER_WIN eWindow )
{
    XC_INSTANCE_PRIVATE *psXCInstPri = NULL;
    UtopiaInstanceGetPrivate(pInstance, (void**)&psXCInstPri);
    if( eWindow == MAIN_WINDOW && psXCInstPri->u32DeviceID == 0)
    {
        SC_W2BYTEMSK( psXCInstPri->u32DeviceID, REG_SC_BK10_19_L, (bEnable<<2), BIT(2));
    }
    else
    {
        SC_W2BYTEMSK( 0, REG_SC_BK0F_01_L, (bEnable<<7), BIT(7));
    }
}

void Hal_SC_set_Zorder_main_first(void *pInstance, MS_BOOL bMainFirst)
{
    XC_INSTANCE_PRIVATE *psXCInstPri = NULL;
    UtopiaInstanceGetPrivate(pInstance, (void**)&psXCInstPri);
    SC_W2BYTEMSK( psXCInstPri->u32DeviceID, REG_SC_BK20_10_L, (bMainFirst << 8), BIT(8) );

    if (bMainFirst)
        SC_W2BYTEMSK( psXCInstPri->u32DeviceID, REG_SC_BK19_14_L, BIT(3) , BIT(3) );
    else
        SC_W2BYTEMSK( psXCInstPri->u32DeviceID, REG_SC_BK19_14_L, 0x00 , BIT(3) );
}

void Hal_SC_set_Zorder_main_first_burst(void *pInstance, MS_BOOL bMainFirst)
{

    _MLOAD_ENTRY(pInstance);

    MDrv_XC_MLoad_WriteCmd( pInstance, REG_SC_BK20_10_L, (bMainFirst << 8), BIT(8) );

    if (bMainFirst)
        MDrv_XC_MLoad_WriteCmd( pInstance, REG_SC_BK19_14_L, BIT(3) , BIT(3) );
    else
        MDrv_XC_MLoad_WriteCmd( pInstance, REG_SC_BK19_14_L, 0x00 , BIT(3) );

    MDrv_XC_MLoad_Fire(pInstance, TRUE);

    _MLOAD_RETURN(pInstance);
}

void Hal_SC_SetPIP_FRC(void *pInstance, MS_BOOL enable, MS_U8 u8IgonreLinesNum)
{
    // Enable FRC for Subwindow
    SC_W2BYTEMSK(0, REG_SC_BK12_45_L, ( enable ? BIT(3):0 ), BIT(3));

    // Set Threadhold
    SC_W2BYTEMSK(0, REG_SC_BK12_45_L, u8IgonreLinesNum, BIT(2)|BIT(1)|BIT(0));
}

void Hal_SC_set_Zextra_y_half_burst(void *pInstance, MS_BOOL bInterlace)
{
    _MLOAD_ENTRY(pInstance);

    if (bInterlace)
        MDrv_XC_MLoad_WriteCmd(pInstance, REG_SC_BK20_11_L, BIT(13), BIT(13));
    else
        MDrv_XC_MLoad_WriteCmd(pInstance, REG_SC_BK20_11_L, 0, BIT(13));

    MDrv_XC_MLoad_Fire(pInstance, TRUE);

    _MLOAD_RETURN(pInstance);
}

void Hal_SC_set_Zextra_y_half(void *pInstance, MS_BOOL bInterlace)
{
    XC_INSTANCE_PRIVATE *psXCInstPri = NULL;
    UtopiaInstanceGetPrivate(pInstance, (void**)&psXCInstPri);
    if (bInterlace)
        SC_W2BYTEMSK(psXCInstPri->u32DeviceID, REG_SC_BK20_11_L, BIT(13), BIT(13));
    else
        SC_W2BYTEMSK(psXCInstPri->u32DeviceID, REG_SC_BK20_11_L, 0, BIT(13));
}

void Hal_SC_enable_extra_request(void *pInstance, MS_BOOL bEnable)
{
    // HW PIP architeucture
    // Becasue BK3_02[7] and BK20_11[15] can not enable toghter, otherwise garbage will be showed,
    // With HW auto no signal, BK3_02[7] will be enabled by HW
    // so, we need to set BK20_11[15] to 0 before no signal, ex. source switch case, need to disable extra request engine
    // Then we need to restore extra request engine after input source is stable

    XC_INSTANCE_PRIVATE *psXCInstPri = NULL;
    UtopiaInstanceGetPrivate(pInstance, (void**)&psXCInstPri);

    if(MDrv_XC_MLoad_GetStatus(pInstance) == E_MLOAD_ENABLED)
    {
        _MLOAD_ENTRY(pInstance);

        if (TRUE == bEnable)
        {
            if(Hal_SC_is_extra_req_en(pInstance, NULL, NULL, NULL, NULL))
            {
                MDrv_XC_MLoad_WriteCmd(pInstance, REG_SC_BK20_11_L, BIT(15), BIT(15));
            }
            else
            {
                MDrv_XC_MLoad_WriteCmd(pInstance, REG_SC_BK20_11_L, 0, BIT(15));
            }
        }
        else
        {
            MDrv_XC_MLoad_WriteCmd(pInstance, REG_SC_BK20_11_L, 0, BIT(15));
        }

        MDrv_XC_MLoad_Fire(pInstance, TRUE);

        _MLOAD_RETURN(pInstance);
    }
    else
    {
        if (TRUE == bEnable)
        {
            if(Hal_SC_is_extra_req_en(pInstance, NULL, NULL, NULL, NULL))
            {
                SC_W2BYTEMSK(psXCInstPri->u32DeviceID, REG_SC_BK20_11_L, BIT(15), BIT(15));
            }
            else
            {
                SC_W2BYTEMSK(psXCInstPri->u32DeviceID, REG_SC_BK20_11_L, 0, BIT(15));
            }
        }
        else
        {
            SC_W2BYTEMSK(psXCInstPri->u32DeviceID, REG_SC_BK20_11_L, 0, BIT(15));
        }
    }
}

void Hal_SC_EnableCLK_for_SUB(void * pInstance, MS_BOOL bEnable)
{
    // !!!!Sub FCLK&&ODCLK can not be closed to avoid menuload timeout

    //MDrv_WriteRegBit(REG_CKG_S2_FCLK,   bEnable, CKG_S2_FCLK_GATED);  // REG_CLKGEN0_57[8], s2_fclk
    //MDrv_WriteRegBit(REG_CKG_S2_ODCLK,  bEnable, CKG_S2_ODCLK_GATED);  // REG_CLKGEN2_63[0], s2_odclk
    MDrv_WriteRegBit(REG_CKG_S2_IDCLK2, !bEnable, CKG_S2_IDCLK2_GATED); // REG_CLKGEN2_65[0], s2_idclk2
}

#undef  MHAL_PIP_C
