/**
 * @file hv_drv_DpuSubScaler.c
 * @brief dpu driver source code.
 * @details This file provides the following functions: \n
 *          (1) Initialization and reset functions \n
 *
 * @author HiView SoC Software Team
 * @version 1.0.0
 * @date 2022-08-23
 * @copyright Copyright(c),2022-8, Hiview Software. All rights reserved.
 * @par History:
 * <table>
 * <tr><th>Author                        <th>Date         <th>Change Description
 * <tr><td>HiView SoC Software Team      <td>2022-08-23   <td>init
 * </table>
*/

#include "hv_comm_MemoryConfig.h"
#include "hv_vos_Comm.h"
#include "PanelConfig.h"

#include "hv_comm_Assert.h"
#include "hv_comm_Utilities.h"
#include "hv_comm_DataBase.h"
#include "hv_comm_MemParser.h"
#include "hv_drv_DpuCommon.h"
#include "hv_drv_DpuSubScaler.h"
#include "hv_drv_DpuSubMute.h"
#include "hv_drv_DynamicColorWin.h"
#include "hv_cal_DpuSubScaler.h"
#include "hv_cal_DpuMainScaler.h"
#include "hv_cal_DynamicColorWin.h"

#include "hv_drv_PQ.h"

typedef struct _SubChWinSize
{
    USHORT16 usSubChHsize;
    USHORT16 usSubChVsize;
    USHORT16 usSubChHpos;
    USHORT16 usSubChVpos;
}SubChWinSize;

VOID Hv_Drv_DpuScaler_CalcSubWindowOutPut(VideoConfigParams* pstVideoConfigParams) 
{   
    HV_ASSERT_VALID_PTR_VOID(pstVideoConfigParams);
    if (PXP_MODE_PIP_ENABLE == pstVideoConfigParams->enPxpMode)
    {
        if (HV_FALSE != HV_COMMON_DATABASE_GET(UserData, bMagnifyGlassSw))/*放大镜根据放大比例设置窗口大小*/
        {
            USHORT16 usMgHsize = HV_COMMON_DATABASE_GET(UserData, usMagnifyGlassHsize);
            USHORT16 usMgVsize = HV_COMMON_DATABASE_GET(UserData, usMagnifyGlassVsize);
            pstVideoConfigParams->uiOutputVideoWidth = usMgHsize;
            pstVideoConfigParams->uiOutputVideoHight = usMgVsize;
            pstVideoConfigParams->uiOutputVideoHtotal = usMgHsize + (pstVideoConfigParams->usVideoPanelHtotalType - pstVideoConfigParams->usVideoPanelHactive) * usMgHsize / pstVideoConfigParams->usVideoPanelHactive;
            pstVideoConfigParams->uiOutputVideoVtotal = usMgVsize + (pstVideoConfigParams->usVideoPanelVtotalType - pstVideoConfigParams->usVideoPanelVactive) * usMgVsize / pstVideoConfigParams->usVideoPanelVactive;
        }
#if (HV_CONFIG_ON == HV_PROJECT_CONFIG_DPU_BRIGHT_FRAME)
        else if (HV_FALSE != HV_COMMON_DATABASE_GET(UserData, bBrightFrameEn))
        {
            USHORT16 usBfHsize = HV_COMMON_DATABASE_GET(UserData, usMagnifyGlassHsize);
            USHORT16 usBfVsize = HV_COMMON_DATABASE_GET(UserData, usMagnifyGlassVsize);
            pstVideoConfigParams->uiOutputVideoWidth = usBfHsize;
            pstVideoConfigParams->uiOutputVideoHight = usBfVsize;
            pstVideoConfigParams->uiOutputVideoHtotal = usBfVsize + (pstVideoConfigParams->usVideoPanelHtotalType - pstVideoConfigParams->usVideoPanelHactive) * usBfHsize / pstVideoConfigParams->usVideoPanelHactive;
            pstVideoConfigParams->uiOutputVideoVtotal = usBfVsize + (pstVideoConfigParams->usVideoPanelVtotalType - pstVideoConfigParams->usVideoPanelVactive) * usBfVsize / pstVideoConfigParams->usVideoPanelVactive;
        }
#endif
        else
        {
            USHORT16 usPipWindowHSize = 0;
            USHORT16 usPipWindowVSize = 0;
            if (PIP_SIZE_SMALL == HV_COMMON_DATABASE_GET(UserData, ucPipSize))
            {
                usPipWindowHSize =  HV_COMMON_DATABASE_GET(UserData, usPipSmallWindowHSize);
                usPipWindowVSize =  HV_COMMON_DATABASE_GET(UserData, usPipSmallWindowVSize);
            }
            else if (PIP_SIZE_MIDDLE == HV_COMMON_DATABASE_GET(UserData, ucPipSize))
            {
                usPipWindowHSize =  HV_COMMON_DATABASE_GET(UserData, usPipMiddleWindowHSize);
                usPipWindowVSize =  HV_COMMON_DATABASE_GET(UserData, usPipMiddleWindowVSize);
            }
            else
            {
                usPipWindowHSize =  HV_COMMON_DATABASE_GET(UserData, usPipBigWindowHSize);
                usPipWindowVSize =  HV_COMMON_DATABASE_GET(UserData, usPipBigWindowVSize);
            }

            pstVideoConfigParams->uiOutputVideoWidth = usPipWindowHSize;
            pstVideoConfigParams->uiOutputVideoHight = usPipWindowVSize;
            pstVideoConfigParams->uiOutputVideoHtotal = usPipWindowHSize + (pstVideoConfigParams->usVideoPanelHtotalType - pstVideoConfigParams->usVideoPanelHactive) * usPipWindowHSize / pstVideoConfigParams->usVideoPanelHactive;
            pstVideoConfigParams->uiOutputVideoVtotal = usPipWindowVSize + (pstVideoConfigParams->usVideoPanelVtotalType - pstVideoConfigParams->usVideoPanelVactive) * usPipWindowVSize / pstVideoConfigParams->usVideoPanelVactive;
        }
    }
    else /*PBP H方向只能占用屏幕一半*/
    {
        pstVideoConfigParams->uiOutputVideoWidth = Hv_Drv_DpuScaler_GetPbpSubWindowHSize();
        pstVideoConfigParams->uiOutputVideoHight = pstVideoConfigParams->usVideoPanelVactive;
        pstVideoConfigParams->uiOutputVideoHtotal = Hv_Drv_DpuScaler_GetPbpSubWindowHSize() + (pstVideoConfigParams->usVideoPanelHtotalType - pstVideoConfigParams->usVideoPanelHactive) * Hv_Drv_DpuScaler_GetPbpSubWindowHSize() / pstVideoConfigParams->usVideoPanelHactive;
        pstVideoConfigParams->uiOutputVideoVtotal = pstVideoConfigParams->usVideoPanelVactive + (pstVideoConfigParams->usVideoPanelVtotalType - pstVideoConfigParams->usVideoPanelHactive) * pstVideoConfigParams->usVideoPanelVactive / pstVideoConfigParams->usVideoPanelVactive;
    }
    return;
}


static VOID GetSubChannelSizePositon(PxpMode enPxpMode,  SubChWinSize* pstSubChWinSize, USHORT16 usPanelHactive, USHORT16 usPanelVactive)
{
    if (PXP_MODE_PIP_ENABLE == enPxpMode)
    {
        if (HV_FALSE != HV_COMMON_DATABASE_GET(UserData, bMagnifyGlassSw))
        {
            pstSubChWinSize->usSubChHsize = HV_COMMON_DATABASE_GET(UserData, usMagnifyGlassHsize);
            pstSubChWinSize->usSubChVsize = HV_COMMON_DATABASE_GET(UserData, usMagnifyGlassVsize);
            pstSubChWinSize->usSubChHpos = HV_COMMON_DATABASE_GET(UserData, usMagnifyGlassPositionH);
            pstSubChWinSize->usSubChVpos = HV_COMMON_DATABASE_GET(UserData, usMagnifyGlassPositionV);            
        }
#if (HV_CONFIG_ON == HV_PROJECT_CONFIG_DPU_BRIGHT_FRAME)
        else if (HV_FALSE != HV_COMMON_DATABASE_GET(UserData, bBrightFrameEn))
        {
            Hv_Drv_DpuScaler_CalcBrightFrameSize(usPanelHactive, usPanelVactive);
            pstSubChWinSize->usSubChHsize = HV_COMMON_DATABASE_GET(UserData, usBrightFrameHsize);
            pstSubChWinSize->usSubChVsize = HV_COMMON_DATABASE_GET(UserData, usBrightFrameVsize);
            pstSubChWinSize->usSubChHpos = HV_COMMON_DATABASE_GET(UserData, usBrightFramePosH);
            pstSubChWinSize->usSubChVpos = HV_COMMON_DATABASE_GET(UserData, usBrightFramePosV);
        }
#endif
        else  /*PIP模式*/
        {
            if (PIP_SIZE_SMALL == HV_COMMON_DATABASE_GET(UserData, ucPipSize))
            {
                pstSubChWinSize->usSubChHsize =  HV_COMMON_DATABASE_GET(UserData, usPipSmallWindowHSize);
                pstSubChWinSize->usSubChVsize =  HV_COMMON_DATABASE_GET(UserData, usPipSmallWindowVSize);
            }
            else if (PIP_SIZE_MIDDLE == HV_COMMON_DATABASE_GET(UserData, ucPipSize))
            {
                pstSubChWinSize->usSubChHsize =  HV_COMMON_DATABASE_GET(UserData, usPipMiddleWindowHSize);
                pstSubChWinSize->usSubChVsize =  HV_COMMON_DATABASE_GET(UserData, usPipMiddleWindowVSize);
            }
            else
            {
                pstSubChWinSize->usSubChHsize =  HV_COMMON_DATABASE_GET(UserData, usPipBigWindowHSize);
                pstSubChWinSize->usSubChVsize =  HV_COMMON_DATABASE_GET(UserData, usPipBigWindowVSize);
            }
            UCHAR8 ucPipPosition = HV_COMMON_DATABASE_GET(UserData, ucPipPosition); /*0:左上 1：左下 2:右上 3:右下*/
            switch (ucPipPosition)
            {
                case 0:
                {
                    pstSubChWinSize->usSubChHpos = 0;
                    pstSubChWinSize->usSubChVpos = 0;
                    break;
                }
                case 1:
                {
                    pstSubChWinSize->usSubChHpos = 0;
                    pstSubChWinSize->usSubChVpos = usPanelVactive - pstSubChWinSize->usSubChVsize;
                    break;
                }
                case 2:
                {
                    pstSubChWinSize->usSubChHpos = usPanelHactive - pstSubChWinSize->usSubChHsize;
                    pstSubChWinSize->usSubChVpos = 0;
                    break;
                }
                case 3:
                {
                    pstSubChWinSize->usSubChHpos = usPanelHactive - pstSubChWinSize->usSubChHsize;
                    pstSubChWinSize->usSubChVpos = usPanelVactive - pstSubChWinSize->usSubChVsize;
                    break;
                }
                default:
                {
                    break;
                }
            }
        }
    }
    else /*PBP H方向只能占用屏幕一半*/
    {
        pstSubChWinSize->usSubChHsize = Hv_Drv_DpuScaler_GetPbpSubWindowHSize();
        pstSubChWinSize->usSubChVsize = usPanelVactive;
        pstSubChWinSize->usSubChHpos = usPanelHactive - pstSubChWinSize->usSubChHsize;
        pstSubChWinSize->usSubChVpos = 0;
    }
    return;
}

VOID Hv_Drv_DpuScaler_SubWindowConfig(USHORT16 usPanelHactive, USHORT16 usPanelVactive)
{
    PxpMode enPxpMode = PXP_MODE_CLOSE;
    DpuWindowParam stSubChannelWindowParam = {0};
    SubChWinSize stSubChWinSize = {0};

    SubWindowBorderCfg stBorderCfg = HV_COMMON_DATABASE_GET(SystemData, stSubWindowBorderCfg);
    stSubChannelWindowParam.bBorderEn = stBorderCfg.ucPxpBorderEnable;
    stSubChannelWindowParam.ucBorderWidth = stBorderCfg.ucSubWindowBorderWidth;
    stSubChannelWindowParam.ucBborderColor = ((UINT32)stBorderCfg.ucSubWindowBorderColorR << 16) | ((UINT32)stBorderCfg.ucSubWindowBorderColorG << 8) | stBorderCfg.ucSubWindowBorderColorB;

    if (HV_FALSE != HV_COMMON_DATABASE_GET(UserData, bMagnifyGlassSw))
    {
        enPxpMode = PXP_MODE_PIP_ENABLE;
    }
#if (HV_CONFIG_ON == HV_PROJECT_CONFIG_DPU_BRIGHT_FRAME)
    else if (HV_FALSE != HV_COMMON_DATABASE_GET(UserData, bBrightFrameEn))
    {
        enPxpMode = PXP_MODE_PIP_ENABLE;
    }
#endif
    else
    {
        enPxpMode = HV_COMMON_DATABASE_GET(UserData, ucPxPMode);
    }
    GetSubChannelSizePositon(enPxpMode, &stSubChWinSize, usPanelHactive, usPanelVactive);

    if (PXP_MODE_CLOSE != enPxpMode) /*PIP or pbp*/
    {
        if (HV_FALSE != HV_COMMON_DATABASE_GET(UserData, bMagnifyGlassSw))    /*bMagnifyGlassSw还表示放大比例*/
        {
            stSubChannelWindowParam.usDtcChHsta = stSubChWinSize.usSubChHpos - (stSubChWinSize.usSubChHsize / 2);
            stSubChannelWindowParam.usDtcChHend = stSubChWinSize.usSubChHpos + (stSubChWinSize.usSubChHsize / 2) - 1;
            stSubChannelWindowParam.usDtcChVsta = stSubChWinSize.usSubChVpos - (stSubChWinSize.usSubChVsize / 2);
            stSubChannelWindowParam.usDtcChVend = stSubChWinSize.usSubChVpos + (stSubChWinSize.usSubChVsize / 2) - 1;
            stSubChannelWindowParam.usBorderHstart = stSubChWinSize.usSubChHpos - (stSubChWinSize.usSubChHsize / 2);
            stSubChannelWindowParam.usBorderVstart = stSubChWinSize.usSubChVpos - (stSubChWinSize.usSubChVsize / 2);
            stSubChannelWindowParam.usBorderLength = stSubChWinSize.usSubChHsize;
            stSubChannelWindowParam.usBorderHeight = stSubChWinSize.usSubChVsize;
            stSubChannelWindowParam.bBorderEn = 0;
            Hv_Drv_DpuScaler_LdgSubBorderEn(stSubChannelWindowParam.bBorderEn);
        }
#if (HV_CONFIG_ON == HV_PROJECT_CONFIG_DPU_BRIGHT_FRAME)
        else if (HV_FALSE != HV_COMMON_DATABASE_GET(UserData, bBrightFrameEn))
        {
            stSubChannelWindowParam.usDtcChHsta = stSubChWinSize.usSubChHpos - (stSubChWinSize.usSubChHsize / 2);
            stSubChannelWindowParam.usDtcChHend = stSubChWinSize.usSubChHpos + (stSubChWinSize.usSubChHsize / 2) - 1;
            stSubChannelWindowParam.usDtcChVsta = stSubChWinSize.usSubChVpos - (stSubChWinSize.usSubChVsize / 2);
            stSubChannelWindowParam.usDtcChVend = stSubChWinSize.usSubChVpos + (stSubChWinSize.usSubChVsize / 2) - 1;
            stSubChannelWindowParam.usBorderHstart = stSubChWinSize.usSubChHpos - (stSubChWinSize.usSubChHsize / 2);
            stSubChannelWindowParam.usBorderVstart = stSubChWinSize.usSubChVpos - (stSubChWinSize.usSubChVsize / 2);
            stSubChannelWindowParam.usBorderLength = stSubChWinSize.usSubChHsize;
            stSubChannelWindowParam.usBorderHeight = stSubChWinSize.usSubChVsize;
            stSubChannelWindowParam.bBorderEn = 0;
            Hv_Drv_DpuScaler_LdgSubBorderEn(stSubChannelWindowParam.bBorderEn);
            
        }
#endif
        else/*非放大镜模式的PIP/PBP*/
        {
            stSubChannelWindowParam.usDtcChHsta = stSubChWinSize.usSubChHpos;
            stSubChannelWindowParam.usDtcChHend = stSubChWinSize.usSubChHpos + stSubChWinSize.usSubChHsize - 1;
            stSubChannelWindowParam.usDtcChVsta = stSubChWinSize.usSubChVpos;
            stSubChannelWindowParam.usDtcChVend = stSubChWinSize.usSubChVpos + stSubChWinSize.usSubChVsize - 1;
            if (PXP_MODE_PIP_ENABLE == enPxpMode)
            {
                stSubChannelWindowParam.usBorderHstart = stSubChWinSize.usSubChHpos;
                stSubChannelWindowParam.usBorderVstart = stSubChWinSize.usSubChVpos;
                stSubChannelWindowParam.usBorderLength = stSubChWinSize.usSubChHsize;
                stSubChannelWindowParam.usBorderHeight = stSubChWinSize.usSubChVsize;
            }
            else
            {
                /*PBP模式仅有中间一条线 H方向边框的宽度 = ucSubWindowBorderWidth*/
                stSubChannelWindowParam.usBorderHstart = stSubChWinSize.usSubChHpos;
                stSubChannelWindowParam.usBorderVstart = stSubChWinSize.usSubChVpos;
                stSubChannelWindowParam.usBorderLength = stBorderCfg.ucSubWindowBorderWidth;
                stSubChannelWindowParam.usBorderHeight = stSubChWinSize.usSubChVsize;
            }
        }
    }
    Hv_Cal_DpuScaler_SetSubWindowConifg(&stSubChannelWindowParam);

    return;
}

static VOID CapVgsfSubC02Config(const VideoConfigParams* pstVideoConfigParams)
{
    HV_ASSERT_VALID_PTR_VOID(pstVideoConfigParams);
    if (ColorFormatType_YCbCr420 == pstVideoConfigParams->stColor.eClrFormat)
    {
        Hv_Cal_DpuScaler_CapVgsfSubC02ClkEn(1);
        Hv_Cal_DpuScaler_CapVgsfSubC02Enable(1);
        Hv_Cal_DpuScaler_CapVgsfSubC02DeEnable(1);
    }
    else
    {
        Hv_Cal_DpuScaler_CapVgsfSubC02ClkEn(0);
        Hv_Cal_DpuScaler_CapVgsfSubC02Enable(0);
        Hv_Cal_DpuScaler_CapVgsfSubC02DeEnable(0);
    }
    return;
}

static VOID CapVgsfSubC24Config(const VideoConfigParams* pstVideoConfigParams)
{
    HV_ASSERT_VALID_PTR_VOID(pstVideoConfigParams);
    if (ColorFormatType_YCbCr420 == pstVideoConfigParams->stColor.eClrFormat
        || ColorFormatType_YCbCr422 == pstVideoConfigParams->stColor.eClrFormat)
    {
        Hv_Cal_DpuScaler_CapVgsfSubC24ClkEn(1);
    }
    else
    {
        Hv_Cal_DpuScaler_CapVgsfSubC24ClkEn(0);
    }
    return;
}


static VOID CapVgsfSubC42Config(const VideoConfigParams* pstVideoConfigParams)
{
    HV_ASSERT_VALID_PTR_VOID(pstVideoConfigParams);    
    /*hdr 打开时会转化到RGB在CSC2转化为YUV444,此时只需要判决DDR中的颜色格式不是YUV444就需要开启C42*/
    if ((ColorFormatType_YCbCr422 == pstVideoConfigParams->stFrameBufferCfg.enFBColorFormat)
        || (ColorFormatType_YCbCr420 == pstVideoConfigParams->stFrameBufferCfg.enFBColorFormat))
    {
        Hv_Cal_DpuScaler_CapVgsfSubC42FuncClkEn(1);
        Hv_Cal_DpuScaler_CapVgsfSubC42On(1);
    }
    else
    {
        Hv_Cal_DpuScaler_CapVgsfSubC42FuncClkEn(0);
        Hv_Cal_DpuScaler_CapVgsfSubC42On(0);
    }

    return;
}

static VOID CapVgsfSubC20Config(const VideoConfigParams* pstVideoConfigParams)
{
    HV_ASSERT_VALID_PTR_VOID(pstVideoConfigParams);
    /*hdr 打开时会转化到RGB在CSC2转化为YUV444,此时只需要判决DDR中的颜色格式不是YUV420就需要开启C20*/
    if (ColorFormatType_YCbCr420 == pstVideoConfigParams->stFrameBufferCfg.enFBColorFormat)
    {
        Hv_Cal_DpuScaler_CapVgsfSubC20FuncClkEn(1);
        Hv_Cal_DpuScaler_CapVgsfSubC20Enable(1);
        /* 输入为YUV420，且进行Vflip时，需要更换CbCr顺序，否则会出现红色蓝色反转现象 */
        if ((ColorFormatType_YCbCr420 ==pstVideoConfigParams->stColor.eClrFormat)
            &&(HV_ENABLE == pstVideoConfigParams->bVflipEnable))
        {
            Hv_Cal_DpuScaler_CapVgsfSubC20CbCrPosAdjEnable(1);
        }
        else
        {
            Hv_Cal_DpuScaler_CapVgsfSubC20CbCrPosAdjEnable(0);
        }
    }
    else
    {
        Hv_Cal_DpuScaler_CapVgsfSubC20FuncClkEn(0);
        Hv_Cal_DpuScaler_CapVgsfSubC20Enable(0);
    }

    return;
}

static VOID CapVgsfSubCSC2Config(const VideoConfigParams* pstVideoConfigParams)
{
    HV_ASSERT_VALID_PTR_VOID(pstVideoConfigParams);
    /*6是RGB转YUV 7是YUV转RGB,过DDR使用YUV数据所以开CSC2*/
    if (Hv_Cal_DpuScaler_GetCapVgsfSubCsc1FunctionOn()
        || (ColorFormatType_RGB == pstVideoConfigParams->stColor.eClrFormat))
    {
        /*cap vgsf csc2 setting start*/
        Hv_Cal_DpuScaler_CapVgsfSubCsc2ClkEn(1);
        Hv_Cal_DpuScaler_CapVgsfSubCsc2ConvertOn(1);
        Hv_Cal_DpuScaler_CapVgsfSubCsc2ConvertMode(6);
        /*cap vgsf csc2 setting end*/
    }
    else
    {
        Hv_Cal_DpuScaler_CapVgsfSubCsc2ClkEn(0);
        Hv_Cal_DpuScaler_CapVgsfSubCsc2ConvertOn(0);
        Hv_Cal_DpuScaler_CapVgsfSubCsc2ConvertMode(0);
    }
    return;
}

extern VOID Hv_Cal_DpuScaler_CapVgsfSubCaOutMaskOn(UINT32 uiValue, UINT32 uiVgas);
VOID Hv_Drv_DpuScaler_UpdataSubCapOutMask(const VideoConfigParams* pstVideoConfigParams)
{
    /*cap vgsf mask setting*/
    UINT32 uiVgas = 0;
    DpuCapCutParam stDpuCapCutParam = {0};
    if (HV_TRUE == pstVideoConfigParams->bMainFakeSwitch)
    {
        Hv_Drv_DpuScaler_CalcCapCutParam(pstVideoConfigParams, &stDpuCapCutParam);
        Hv_Cal_DpuScaler_SetCapVgsfSubCutParam(&stDpuCapCutParam);
#if (HV_CONFIG_ON == HV_PROJECT_CONFIG_DPU_BRIGHT_FRAME)
        if (HV_FALSE != HV_COMMON_DATABASE_GET(UserData, bBrightFrameEn))
        {
            Hv_Drv_DpuScaler_CalcDcwCapCutParam(pstVideoConfigParams, &stDpuCapCutParam);
            Hv_Cal_DpuScaler_SetCapVgsfSubCutParam(&stDpuCapCutParam);
            uiVgas = HV_COMMON_DATABASE_GET(UserData, bBrightFrameEn);
        }
#endif
        Hv_Cal_DpuScaler_CapVgsfSubCaOutMaskOn(1, uiVgas);
    }
    else
    {
        Hv_Cal_DpuScaler_SetCapVgsfSubCutParam(&stDpuCapCutParam);
        Hv_Cal_DpuScaler_CapVgsfSubCaOutMaskOn(0, uiVgas);
    }
    return;
}

Status Hv_Drv_DpuScaler_CapVgsfSettingsSub(const VideoConfigParams* pstVideoConfigParams)
{
    HV_ASSERT_VALID_PTR(pstVideoConfigParams);


    Hv_Cal_DpuScaler_CapVgsfSubInOutSize(pstVideoConfigParams);

    Hv_Drv_DpuScaler_UpdataSubCapOutMask(pstVideoConfigParams);

    CapVgsfSubC02Config(pstVideoConfigParams);
    CapVgsfSubC24Config(pstVideoConfigParams);
    Hv_Cal_DpuScaler_CapVgsfSubCsc1Config(pstVideoConfigParams);
    CapVgsfSubC42Config(pstVideoConfigParams);
    CapVgsfSubC20Config(pstVideoConfigParams);
    CapVgsfSubCSC2Config(pstVideoConfigParams);

    /*C20 size 是scaler down之后的和ddr的size保持一致,scaler down之后的de enable默认关掉所以不关注htotal配置，scalerdown之前打开deenable 关注htotal*/

    /*1是开启scaler down，3是scaler down bypass。*/
    if (HV_TRUE == pstVideoConfigParams->bHorizontalNeedScaler)
    {
        Hv_Cal_DpuScaler_CapVgsfSubCaVgMsfYhMode(1);
    }
    else
    {
        Hv_Cal_DpuScaler_CapVgsfSubCaVgMsfYhMode(3);
    }

    if (HV_TRUE == pstVideoConfigParams->bVerticalNeedScaler)
    {
        Hv_Cal_DpuScaler_CapVgsfSubCaVgMsfYvMode(1);
    }
    else
    {
        Hv_Cal_DpuScaler_CapVgsfSubCaVgMsfYvMode(3);
    }

    UINT32 uiHsfInSize = pstVideoConfigParams->uiInputVideoWidth;
    Hv_Cal_DpuScaler_CapVgsfSubCaVgHsfInSize(uiHsfInSize);

    HV_ASSERT_TRUE(pstVideoConfigParams->uiInputVideoWidth > 0);
    UINT32 uiHsfOutSize = pstVideoConfigParams->uiDdrOrWtrVideoWidth;
    Hv_Cal_DpuScaler_CapVgsfSubCaVgVsfInSize(pstVideoConfigParams->uiInputVideoHight);
    if (pstVideoConfigParams->bMainFakeSwitch)
    {
        Hv_Cal_DpuScaler_CapVgsfSubCaVghfilbase(8192);
        Hv_Cal_DpuScaler_CapVgsfSubCaVgVfilbase(8192);

        Hv_Cal_DpuScaler_CapVgsfSubCaVgVsfOutSize(pstVideoConfigParams->uiInputVideoHight);
        Hv_Cal_DpuScaler_CapVgsfSubCaVgHsfOutSize(uiHsfInSize);
#if (HV_CONFIG_ON == HV_PROJECT_CONFIG_DPU_BRIGHT_FRAME)
        if (HV_FALSE != HV_COMMON_DATABASE_GET(UserData, bBrightFrameEn))
        {
            /*如果inp timing需要scl down，先down到panel size*/
            Hv_Cal_DpuScaler_DcwCapScalerDownParam(pstVideoConfigParams);
        }
#endif
    }
    else
    {
        HV_ASSERT_TRUE(uiHsfOutSize > 0);
        /*8192* in_size/out_size*/
        Hv_Cal_DpuScaler_CapVgsfSubCaVghfilbase(8192 * uiHsfInSize / uiHsfOutSize);
        HV_ASSERT_TRUE(pstVideoConfigParams->uiDdrOrWtrVideoHight > 0);
        /*8192* in_size/out_size*/
        Hv_Cal_DpuScaler_CapVgsfSubCaVgVfilbase((UINT32)8192 * pstVideoConfigParams->uiInputVideoHight / pstVideoConfigParams->uiDdrOrWtrVideoHight);

        Hv_Cal_DpuScaler_CapVgsfSubCaVgVsfOutSize(pstVideoConfigParams->uiDdrOrWtrVideoHight);
        Hv_Cal_DpuScaler_CapVgsfSubCaVgHsfOutSize(uiHsfOutSize);
    }

    return HV_SUCCESS;
}

static VOID DpcSrpSubFrameBufferColorConfig(const VideoConfigParams* pstVideoConfigParams)
{
    HV_ASSERT_VALID_PTR_VOID(pstVideoConfigParams);
    if (ColorFormatType_YCbCr422 == pstVideoConfigParams->stFrameBufferCfg.enFBColorFormat)
    {
        Hv_Cal_DpuScaler_DpcSrpSubDataMode(1);
    }
    else if (ColorFormatType_YCbCr420 == pstVideoConfigParams->stFrameBufferCfg.enFBColorFormat)
    {
        Hv_Cal_DpuScaler_DpcSrpSubDataMode(2);
    }
    else/*YUV444 and RGB444*/
    {
        Hv_Cal_DpuScaler_DpcSrpSubDataMode(0);
    }

    if (ColorDepthType_12Bit == pstVideoConfigParams->stFrameBufferCfg.enFBColorDepth)
    {
        Hv_Cal_DpuScaler_DpcSrpSubDataWidth(3);
    }
    else if (ColorDepthType_10Bit == pstVideoConfigParams->stFrameBufferCfg.enFBColorDepth)
    {
        Hv_Cal_DpuScaler_DpcSrpSubDataWidth(2);
    }
    else
    {
        Hv_Cal_DpuScaler_DpcSrpSubDataWidth(1);
    }

    return;
}

Status Hv_Drv_DpuScaler_DpcSrpSubSettings(const VideoConfigParams* pstVideoConfigParams)
{
    HV_ASSERT_VALID_PTR(pstVideoConfigParams);
    Hv_Cal_DpuScaler_DpcSrpSubUpHbp(4);
    Hv_Cal_DpuScaler_DpcSrpSubUpLastMode(0);

    DpcSrpSubFrameBufferColorConfig(pstVideoConfigParams);

    /*Subpath 0:ddr data*/
    Hv_Cal_DpuScaler_DpcSrpSubFrcFrameSyncSel(0);
    return HV_SUCCESS;
}

Status Hv_Drv_DpuScaler_DpcCapSubSettings(const VideoConfigParams* pstVideoConfigParams)
{
    HV_ASSERT_VALID_PTR(pstVideoConfigParams);
    /*data mode 0:444 1:422 2:420*/
    if (ColorFormatType_YCbCr422 == pstVideoConfigParams->stFrameBufferCfg.enFBColorFormat)
    {
        Hv_Cal_DpuScaler_DpcCapSubVmDataMode(1);
    }
    else if (ColorFormatType_YCbCr420 == pstVideoConfigParams->stFrameBufferCfg.enFBColorFormat)
    {
        Hv_Cal_DpuScaler_DpcCapSubVmDataMode(2);
    }
    else/*YUV444 and RGB444*/
    {
        Hv_Cal_DpuScaler_DpcCapSubVmDataMode(0);
    }
    
    if (ColorDepthType_12Bit == pstVideoConfigParams->stFrameBufferCfg.enFBColorDepth)
    {
        Hv_Cal_DpuScaler_DpcCapSubVmDataBitWidth(12);
    }
    else if (ColorDepthType_10Bit == pstVideoConfigParams->stFrameBufferCfg.enFBColorDepth)
    {
        Hv_Cal_DpuScaler_DpcCapSubVmDataBitWidth(10);
    }
    else/*ColorDepthType_8Bit abd ColorDepthType_6Bit*/
    {
        Hv_Cal_DpuScaler_DpcCapSubVmDataBitWidth(8);
    }

    /*Sub仅支持pack/unpack模式过ddr*/
    Hv_Cal_DpuScaler_DpcCapSubEncPackWork(2);

    return HV_SUCCESS;
}

VOID Hv_Drv_DpuScaler_SubVdmReadAddrSwap(VOID)
{
    UINT32 uiReadAddrA = Hv_Cal_DpuScaler_GetSubVdmReadAddr0();
    UINT32 uiReadAddrB = Hv_Cal_DpuScaler_GetSubVdmReadAddr1();
    Hv_Cal_DpuScaler_SetSubVdmReadAddr0(uiReadAddrB);
    Hv_Cal_DpuScaler_SetSubVdmReadAddr1(uiReadAddrA);
    return;
}

VOID Hv_Drv_DpuScaler_SubVdmWriteAddrSwap(VOID)
{
    UINT32 uiReadAddrA = Hv_Cal_DpuScaler_GetSubVdmReadAddr0();
    UINT32 uiReadAddrB = Hv_Cal_DpuScaler_GetSubVdmReadAddr1();
    Hv_Cal_DpuScaler_SetSubVdmWirteAddr0(uiReadAddrB);
    Hv_Cal_DpuScaler_SetSubVdmWirteAddr1(uiReadAddrA);
    return;
}

Status Hv_Drv_DpuScaler_SrpTopSubSettings(const VideoConfigParams* pstVideoConfigParams)
{
    HV_ASSERT_VALID_PTR(pstVideoConfigParams);
    /*hflp*/
    Hv_Cal_DpuScaler_SrpTopSubScHflip(pstVideoConfigParams->bHflipEnable);
    /*sub*/
    UINT32 uiSrpInWidth = pstVideoConfigParams->uiDdrOrWtrVideoWidth;
    UINT32 uiSrpInHeight = pstVideoConfigParams->uiDdrOrWtrVideoHight;
    UINT32 uiwidthOut  = pstVideoConfigParams->uiOutputVideoWidth;
    UINT32 uiHeightOut = pstVideoConfigParams->uiOutputVideoHight;
    if (pstVideoConfigParams->bMainFakeSwitch)
    {
        /*usMainFakeHsize, usSubFakeHsize代表的是最终大小，*/
        uiwidthOut  = pstVideoConfigParams->usMainFakeHsize;
        uiHeightOut = pstVideoConfigParams->usMainFakeVsize;
    }

    Hv_Cal_DpuScaler_SrpTopSubSrPassthrough(0);
    Hv_Cal_DpuScaler_SrpTopSubSrSpatOn(0);
    Hv_Cal_DpuScaler_SrpTopSubSrSpatMode(2);
    Hv_Cal_DpuScaler_SrpTopSubSrSpatWith(uiSrpInWidth);

    Hv_Cal_DpuScaler_SrpTopSubC02Config(pstVideoConfigParams);

    Hv_Cal_DpuScaler_SrpTopSubSrC24Config(pstVideoConfigParams);

    Hv_Cal_DpuScaler_SrpTopSubSrCbScfOn(1);
    Hv_Cal_DpuScaler_SrpTopSubScThrouSw(0);

    if(uiSrpInHeight == uiHeightOut)
    {
        Hv_Cal_DpuScaler_SrpTopSubScCvmode(2);
        Hv_Cal_DpuScaler_SrpTopSubScYvmode(2);
    }
    else
    {
        Hv_Cal_DpuScaler_SrpTopSubScCvmode(1);
        Hv_Cal_DpuScaler_SrpTopSubScYvmode(1);
    }

    if(uiSrpInWidth == uiwidthOut)
    {
        Hv_Cal_DpuScaler_SrpTopSubScChmode(2);
        Hv_Cal_DpuScaler_SrpTopSubScYhmode(2);
    }
    else
    {
        Hv_Cal_DpuScaler_SrpTopSubScChmode(1);
        Hv_Cal_DpuScaler_SrpTopSubScYhmode(1);
    }
    if ((uiSrpInWidth == uiwidthOut) && (uiSrpInHeight == uiHeightOut))
    {
        Hv_Cal_DpuScaler_SrpTopSubScUpClkEn(0);
    }
    else
    {
        Hv_Cal_DpuScaler_SrpTopSubScUpClkEn(1);
    }

    HV_ASSERT_TRUE(uiwidthOut > 0);
    HV_ASSERT_TRUE(uiHeightOut > 0);
    Hv_Cal_DpuScaler_SrpTopSubScHfilbase(8192 * uiSrpInWidth / uiwidthOut);
    Hv_Cal_DpuScaler_SrpTopSubScVfilbase(8192 *  uiSrpInHeight / uiHeightOut);

    Hv_Cal_DpuScaler_SrpTopSubSrScfTableId(9);
    /*srp数据要求必须是YUV444，LDG数据一定是RGB固定开CSC1*/
    /*Haocaiyan modified, CSC convert off*/
    Hv_Cal_DpuScaler_SrpTopSubSrCs1ConvertOn(0);
    Hv_Cal_DpuScaler_SrpTopSubSrCs1ConvertMode(7);

    
    return HV_SUCCESS;
}

Status Hv_Drv_DpuScaler_SubLdgTopSubSettings(const VideoConfigParams* pstVideoConfigParams)
{
    HV_ASSERT_VALID_PTR(pstVideoConfigParams);
    Hv_Cal_DpuScaler_SubLdgTopSubCscEn(1);
    return HV_SUCCESS;
}

Status Hv_Drv_DpuScaler_SetSubPathInterlaceMode(const VideoConfigParams* pstVideoConfigParams, UCHAR8 ucFieldPolar)
{
    HV_ASSERT_VALID_PTR(pstVideoConfigParams);
    UINT32 uiHeightScf = pstVideoConfigParams->uiDdrOrWtrVideoHight;
    UINT32 uiHeightOut = pstVideoConfigParams->uiOutputVideoHight;
    UINT32 uiVfilbase = 8192 *  uiHeightScf / uiHeightOut;
    if (HV_TRUE == pstVideoConfigParams->bInterlacedMode)
    {
        Hv_Cal_DpuScaler_ScSubPvosPs0(0x1000000-uiVfilbase);
        Hv_Cal_DpuScaler_ScSubPvosPs1(uiVfilbase);

        Hv_Cal_DpuScaler_ScSubFeildSel(1);
        Hv_Cal_DpuScaler_ScSubFeildPolar(0);
    }
    else
    {
        Hv_Cal_DpuScaler_ScSubPvosPs0(0);
        Hv_Cal_DpuScaler_ScSubPvosPs1(0);

        Hv_Cal_DpuScaler_ScSubFeildSel(0);
        Hv_Cal_DpuScaler_ScSubFeildPolar(0);
    }
    return HV_SUCCESS;
}


static Status Hv_Drv_DpuScaler_SubHdrSetType(HDREOTF etype)
{
    switch(etype)
    {
        case SDR_TYPE:
        {
            Hv_Cal_DpuScaler_CapVgsfSubHdrGmiEnable(0);
            Hv_Cal_DpuScaler_CapVgsfSubHdrOotfEnable(0);
            Hv_Cal_DpuScaler_CapVgsfSubHdrGmdEnable(0);
            break;
        }
        case HDR10_TYPE:
        {
            Hv_Cal_DpuScaler_CapVgsfSubHdrGmiEnable(1);
            Hv_Cal_DpuScaler_CapVgsfSubHdrOotfEnable(0);
            Hv_Cal_DpuScaler_CapVgsfSubHdrGmdEnable(1);
            break;
        }
        case HLG_TYPE:
        {
            Hv_Cal_DpuScaler_CapVgsfSubHdrGmiEnable(1);
            Hv_Cal_DpuScaler_CapVgsfSubHdrOotfEnable(1);
            Hv_Cal_DpuScaler_CapVgsfSubHdrGmdEnable(1);
            break;
        }
        default:
        {
            Hv_Cal_DpuScaler_CapVgsfSubHdrGmiEnable(0);
            Hv_Cal_DpuScaler_CapVgsfSubHdrOotfEnable(0);
            Hv_Cal_DpuScaler_CapVgsfSubHdrGmdEnable(0);
            break;
        }
    }
    return HV_SUCCESS;
}



Status Hv_Drv_DpuScaler_SubHdrEnable(UINT32 uiValue)
{
    if(uiValue == 0)
    {
        Hv_Cal_DpuScaler_CapVgsfSubHdrPassthrough(1);
    }
    else
    {
        Hv_Cal_DpuScaler_CapVgsfSubHdrPassthrough(0);
    }
    return HV_SUCCESS;
}

Status Hv_Drv_DpuScaler_SubHdrDmEnable(UINT32 uiValue)
{
    if(uiValue == 0)
    {
        Hv_Cal_DpuScaler_CapVgsfSubHdrLutGmiEn(0);
    }
    else
    {
        Hv_Cal_DpuScaler_CapVgsfSubHdrLutGmiEn(1);
    }
    return HV_SUCCESS;
}

Status Hv_Drv_DpuScaler_SubHdrProcessSOP(const HDRParam* pstHdrParam)
{
    HV_ASSERT_VALID_PTR(pstHdrParam);
    /*Silicon*/
    //check if source HDR is On
    if((HDR10_TYPE == pstHdrParam->xType)||(HLG_TYPE == pstHdrParam->xType))
    {
        UINT32 uiAllZero = 1;

        Hv_Drv_PQ_SetHdrMode(CHANNEL_TYPE_SUB, pstHdrParam->xType, (HDRParam*)pstHdrParam);
    }
    else//HDR to SDR
    {
        Hv_Drv_PQ_SetHdrMode(CHANNEL_TYPE_SUB, SDR_TYPE, (HDRParam*)pstHdrParam);
    }

    return HV_SUCCESS;
}

Status Hv_Drv_DpuScaler_CapVgsfSubHdrSetting(const VideoConfigParams* pstVideoConfigParams)
{
    HV_ASSERT_VALID_PTR(pstVideoConfigParams);
    /*为了支持HDR效果OSD菜单动态修改，即修改HDR效果时动态修改个别寄存器即可，在配置链路时固定配置HDR寄存器*/

    Hv_Cal_DpuScaler_CapVgsfSubHdrGmiEnable(0);
    Hv_Cal_DpuScaler_CapVgsfSubHdrOotfEnable(0);
    Hv_Cal_DpuScaler_CapVgsfSubHdrGmdEnable(0);
    Hv_Cal_DpuScaler_CapVgsfSubHdrPassthrough(0);
    Hv_Cal_DpuScaler_CapVgsfSubHdrLutGmiEn(1);
    Hv_Cal_DpuScaler_CapVgsfSubHdrLutOotfEn(1);/*TODO Use only GMI for Now*/
    Hv_Cal_DpuScaler_CapVgsfSubHdrLutGmdEn(1);/*TODO Use only GMI for Now*/
    Hv_Cal_DpuScaler_DpuVdmTblRdSubEnable(1);

    Hv_Cal_DpuScaler_DpuVdmTblRdSubTblTblEnable(0x70);//TODO 0x70 == 01110000 = enable 4 5 6
    /* sub cap sync setting before HDR dma enable */
    if(0 != pstVideoConfigParams->bHdrSwitch)
    {
        Hv_Drv_DpuScaler_SubHdrProcessSOP(&pstVideoConfigParams->stHdrParam);
    }
    else
    {
        Hv_Drv_DpuScaler_SubHdrEnable(0);
    }

    return HV_SUCCESS;
}

VOID Hv_Drv_DpuScaler_SubChannelClose(VOID)
{
    /*close throught ddr DMA*/
    Hv_Cal_DpuScaler_DpuRvdm01LineRdEnable(0);
    Hv_Cal_DpuScaler_DpuWvdm01WrEnable(0);
    if(Hv_Cal_DpuScaler_GetCapVgsfSubCsc1FunctionOn())
    {
        HV_W32_FIELD(DISP_TOP_DPU_CA_VGSF_01_30, reg_01_ca_vg_cs1_convert_func_clk_en, 0);
        HV_W32_FIELD(DISP_TOP_DPU_CA_VGSF_01_30, reg_01_ca_vg_csc1_en, 0);
    }
    return;
}

Status Hv_Drv_DpuScaler_SubRatio(const VideoConfigParams* pstVideoConfigParams)
{
    HV_ASSERT_VALID_PTR(pstVideoConfigParams);
    INT32 uiPosa = 0;
    INT32 uiPosc = 0;

    UINT32 uiVtmp = 0;
    UINT32 uiHtmp = 0;

    UINT32 uiOutW = pstVideoConfigParams->uiOutputVideoWidth;
    UINT32 uiOutH =  pstVideoConfigParams->uiOutputVideoHight;

    UINT32 uiRealHeight = 0;

    UINT32 uiValid = 0;
    USHORT16 usPbpSubH = 0;
    usPbpSubH = Hv_Drv_DpuScaler_GetPbpSubWindowHSize();
    RatioParam atRatioArr[OUTPUTRATIO_MAX] = 
    {
        {pstVideoConfigParams->usVideoPanelHactive, pstVideoConfigParams->usVideoPanelVactive},{16,9}, {4,3},{21,9},{5,3},{1,1},{16,10},{5,4},{pstVideoConfigParams->usVideoPanelHactive, pstVideoConfigParams->usVideoPanelVactive}
    };

    if(pstVideoConfigParams->enPxpMode == PXP_MODE_PIP_ENABLE)//do nothing when pip, scaler already configed by dpu
    {
        return 0;
    }

    if(pstVideoConfigParams->enPxpMode == PXP_MODE_PBP_ENABLE)
    {
        atRatioArr[0].usRatioW = usPbpSubH;
    }
    /*sub*/
    UINT32 uiSrpInWidth = pstVideoConfigParams->uiDdrOrWtrVideoWidth;
    UINT32 uiSrpInHeight = pstVideoConfigParams->uiDdrOrWtrVideoHight;
    UINT32 uiwidthOut  = pstVideoConfigParams->uiOutputVideoWidth;
    UINT32 uiHeightOut = pstVideoConfigParams->uiOutputVideoHight;
    if (pstVideoConfigParams->bMainFakeSwitch)
    {
        /*usMgHsize, usMgVsize代表的是最终大小，*/
        uiwidthOut  = pstVideoConfigParams->usMainFakeHsize;
        uiHeightOut = pstVideoConfigParams->usMainFakeVsize;
    }

    HV_LOG_INFO(VIDEO, "SSSUB==Hv_Drv_DpuScalerSclRatio 1:1 %u %u %u %u %u %u===", pstVideoConfigParams->uiInputVideoWidth,pstVideoConfigParams->uiInputVideoHight,pstVideoConfigParams->uiDdrOrWtrVideoWidth, pstVideoConfigParams->uiDdrOrWtrVideoHight, uiOutW, uiOutH);
    HV_ASSERT_TRUE(pstVideoConfigParams->uiInputVideoWidth > 0);
    HV_ASSERT_TRUE(pstVideoConfigParams->uiInputVideoHight > 0);
    HV_ASSERT_TRUE(pstVideoConfigParams->uiDdrOrWtrVideoWidth > 0);
    HV_ASSERT_TRUE(pstVideoConfigParams->uiDdrOrWtrVideoHight > 0);
    HV_ASSERT_TRUE(pstVideoConfigParams->uiOutputVideoWidth > 0);
    HV_ASSERT_TRUE(pstVideoConfigParams->uiOutputVideoHight > 0);

    if(pstVideoConfigParams->enAspectRatio != OUTPUTRATIO_1TO1)
    {
        if(pstVideoConfigParams->enPxpMode == PXP_MODE_CLOSE)
        {
            if(pstVideoConfigParams->uiOutputVideoHight * atRatioArr[pstVideoConfigParams->enAspectRatio].usRatioW > atRatioArr[pstVideoConfigParams->enAspectRatio].usRatioH* pstVideoConfigParams->uiOutputVideoWidth)
            {
                uiOutW = pstVideoConfigParams->uiOutputVideoWidth;
            }
            else
            {
                uiOutW = pstVideoConfigParams->uiOutputVideoHight * atRatioArr[pstVideoConfigParams->enAspectRatio].usRatioW / atRatioArr[pstVideoConfigParams->enAspectRatio].usRatioH;
            }

        }
        else if(pstVideoConfigParams->enPxpMode == PXP_MODE_PBP_ENABLE)
        {
        //    uiOutW = 2*pstVideoConfigParams->uiOutputVideoHight * atRatioArr[pstVideoConfigParams->enAspectRatio].usRatioW /(atRatioArr[pstVideoConfigParams->enAspectRatio].usRatioH << 1);
            if(pstVideoConfigParams->uiInputVideoWidth* pstVideoConfigParams->usVideoPanelVactive > pstVideoConfigParams->uiInputVideoHight* usPbpSubH)
            {
                uiOutW =  usPbpSubH;
                HV_LOG_DEBUG(PQ, "fill h %d", uiOutW);
            }
            else//fill v
            {
                uiOutW = pstVideoConfigParams->uiInputVideoWidth*(pstVideoConfigParams->usVideoPanelVactive)/pstVideoConfigParams->uiInputVideoHight;
                HV_LOG_DEBUG(PQ, "fill v %d", uiOutW);
            };

            HV_LOG_DEBUG(PQ, "SSSSSUB uiOutW %d", uiOutW);
        }
        else
        {
            return HV_SUCCESS;
        }
        //get real Height if interlace
        if(pstVideoConfigParams->bInterlacedMode)
        {
            uiRealHeight  = pstVideoConfigParams->uiDdrOrWtrVideoHight<< 1;
        }
        else
        {
            uiRealHeight  = pstVideoConfigParams->uiDdrOrWtrVideoHight;
        }
 
        if(pstVideoConfigParams->enAspectRatio != OUTPUTRATIO_AUTO)
        {
            if(pstVideoConfigParams->enPxpMode == PXP_MODE_PBP_ENABLE)
            {
                atRatioArr[pstVideoConfigParams->enAspectRatio].usRatioW *= 1000;
                atRatioArr[pstVideoConfigParams->enAspectRatio].usRatioH *= 1000;
                atRatioArr[pstVideoConfigParams->enAspectRatio].usRatioW = atRatioArr[pstVideoConfigParams->enAspectRatio].usRatioW*usPbpSubH/(pstVideoConfigParams->usVideoPanelVactive/2);
            }
            if(pstVideoConfigParams->uiOutputVideoHight * atRatioArr[pstVideoConfigParams->enAspectRatio].usRatioW > atRatioArr[pstVideoConfigParams->enAspectRatio].usRatioH* pstVideoConfigParams->uiOutputVideoWidth)
            {
                uiOutH = pstVideoConfigParams->uiOutputVideoWidth*atRatioArr[pstVideoConfigParams->enAspectRatio].usRatioH/atRatioArr[pstVideoConfigParams->enAspectRatio].usRatioW;
            }
            else
            {
                uiOutH = pstVideoConfigParams->uiOutputVideoHight;
            }

        }
        else/*Auto mode, calculate out H*/
        {
            if(pstVideoConfigParams->uiInputVideoWidth * pstVideoConfigParams->uiOutputVideoHight >= uiRealHeight *pstVideoConfigParams->uiOutputVideoWidth)
            {
                //HV_LOG_DEBUG(DEFAULT, "%d %d %d", uiOutW, uiRealHeight, pstVideoConfigParams->uiInputVideoWidth);
                if(pstVideoConfigParams->bInterlacedMode)
                {
                    uiOutH = uiOutW * uiRealHeight/pstVideoConfigParams->uiDdrOrWtrVideoWidth;
                }
                else
                {
                    uiOutH = uiOutW * pstVideoConfigParams->uiInputVideoHight/pstVideoConfigParams->uiInputVideoWidth;
                }
                if((pstVideoConfigParams->enPxpMode == PXP_MODE_PBP_ENABLE)&& (uiOutH > pstVideoConfigParams->usVideoPanelVactive))
                {
                    uiOutH = (pstVideoConfigParams->usVideoPanelVactive*usPbpSubH)/uiOutW;
                }
                HV_LOG_DEBUG(PQ, "SSSSUB %d %d", uiOutH, uiOutW);
            }
            else
            {
                uiOutH = pstVideoConfigParams->uiOutputVideoHight;     
                uiOutW = pstVideoConfigParams->uiOutputVideoHight*pstVideoConfigParams->uiDdrOrWtrVideoWidth/uiRealHeight;
                HV_LOG_DEBUG(PQ, "1SSSSUB %d %d", uiOutH, uiOutW);
            }
        }

       //changed output Timing
        uiHtmp = (pstVideoConfigParams->uiDdrOrWtrVideoWidth << 13) / uiOutW;
        uiPosa = (uiHtmp * (pstVideoConfigParams->uiOutputVideoWidth - uiOutW)) >> 1;
        uiPosa = (1 << 25) - uiPosa;

        Hv_Cal_DpuScaler_ScSubPhosPsA0(uiPosa);
        Hv_Cal_DpuScaler_ScSubPhosPsB0(0);

        Hv_Cal_DpuScaler_SrpTopSubScHfilbase((pstVideoConfigParams->uiDdrOrWtrVideoWidth << 13) / uiOutW);
        if(pstVideoConfigParams->bInterlacedMode)
        {
            Hv_Cal_DpuScaler_SrpTopSubScVfilbase(((uiRealHeight << 13) / uiOutH)/2);
            uiVtmp = ((uiRealHeight << 13) / uiOutH)/2; 
        }
        else
        {
            HV_LOG_DEBUG(PQ, "VFILL ui %d %d", uiRealHeight, uiOutH);
            Hv_Cal_DpuScaler_SrpTopSubScVfilbase((uiRealHeight << 13) / uiOutH);
            uiVtmp = ((uiRealHeight << 13) / uiOutH); 
        }

        //donot use realheight here
        INT32 iPosc = ((pstVideoConfigParams->uiDdrOrWtrVideoHight<< 13) - (uiVtmp * pstVideoConfigParams->uiOutputVideoHight))>>1;
        if(iPosc < 0)
            iPosc += 1<<24;

        Hv_Cal_DpuScaler_ScSubPvosPs0(iPosc);
        Hv_Cal_DpuScaler_ScSubPvosPs1(0);
        if(pstVideoConfigParams->bInterlacedMode)
        {
            Hv_Cal_DpuScaler_ScSubPvosPs1(iPosc);
        }

    }
    else//1to1 mode
    {
        if(pstVideoConfigParams->bInterlacedMode)
        {
            uiRealHeight  = pstVideoConfigParams->uiInputVideoHight << 1;
        }
        else
        {
            uiRealHeight  = pstVideoConfigParams->uiInputVideoHight;
        }

        {

            if(pstVideoConfigParams->bInterlacedMode)
            {
                uiValid = uiOutH * pstVideoConfigParams->uiDdrOrWtrVideoWidth / (pstVideoConfigParams->uiDdrOrWtrVideoHight << 1);
                uiHtmp =  pstVideoConfigParams->uiDdrOrWtrVideoWidth << 13 / uiValid;
                uiVtmp =  pstVideoConfigParams->uiDdrOrWtrVideoHight << 14 / uiOutH;

                uiHtmp = 8192;
                uiVtmp = 4096;
            }
            else
            {
                uiValid = uiOutH * pstVideoConfigParams->uiDdrOrWtrVideoWidth / pstVideoConfigParams->uiDdrOrWtrVideoHight;
                uiHtmp = pstVideoConfigParams->uiDdrOrWtrVideoWidth << 13 / uiValid;
                uiVtmp = pstVideoConfigParams->uiDdrOrWtrVideoHight << 13 / uiOutH;

                uiHtmp = 8192;
                uiVtmp = 8192;
            }

            uiOutW = pstVideoConfigParams->uiOutputVideoWidth;
            uiOutH = pstVideoConfigParams->uiOutputVideoHight;
            uiValid = pstVideoConfigParams->uiDdrOrWtrVideoWidth;////uiOutH*rs.w/rs.h;


            uiPosa = (uiHtmp * (uiValid-uiOutW)) >> 1;
            if(uiPosa < 0)
                uiPosa = (1 << 25) + uiPosa;


            INT32 iTmp = 0;
            iTmp = (pstVideoConfigParams->uiDdrOrWtrVideoHight <<13) - (uiVtmp * uiOutH);
            INT32 iPosc = iTmp >> 1;
            if(iPosc < 0)
                iPosc += 1<<24;

            if(pstVideoConfigParams->bInterlacedMode)
            {
                Hv_Cal_DpuScaler_SrpTopSubScVfilbase(uiVtmp);
                Hv_Cal_DpuScaler_ScSubPvosPs1(0x1000000 - (uiVtmp ));
            }
            else
            {
                Hv_Cal_DpuScaler_SrpTopSubScVfilbase(uiVtmp);
            }
            Hv_Cal_DpuScaler_ScSubPvosPs0(iPosc);
            Hv_Cal_DpuScaler_ScSubPhosPsA0(uiPosa);
            Hv_Cal_DpuScaler_SrpTopSubScHfilbase(8192);
            //Hv_Cal_DpuScaler_SrpTopSubScVfilbase(8192);
        }

        Hv_Cal_DpuScaler_ScSubOrfCrlev(80);
        Hv_Cal_DpuScaler_ScSubOrfCblev(80);
        Hv_Cal_DpuScaler_ScSubOrfYlev(0);

    }
    return HV_SUCCESS;
}

Status Hv_Drv_DpuScaler_LDGSubInsertBlackCableDetect(VOID)
{
    return Hv_Cal_DpuScaler_LDGSubInsertBlackCableDetect();
}


static Status SubLdgTopCommonSettings(const VideoConfigParams* pstVideoConfigParams)
{
    Hv_Cal_DpuScaler_SubLdgTopByPass(0);
    Hv_Cal_DpuScaler_SubLdgTopBorderMode(0);
    return HV_SUCCESS;
}

Status Hv_Drv_DpuSubScaler_Config(const VideoConfigParams* pstVideoConfigParams)
{
    HV_ASSERT_VALID_PTR(pstVideoConfigParams);
    Hv_Drv_DpuScaler_CapVgsfSubHdrSetting(pstVideoConfigParams);
#ifdef HV_SCALER_DEBUG_VERSION
    Hv_Cal_DpuScaler_CapVgsfPattSettingsSub(pstVideoConfigParams);
#endif
    HV_ASSERT_SUCCESS(Hv_Drv_DpuScaler_CapVgsfSettingsSub(pstVideoConfigParams));
    Hv_Drv_DpuScaler_FrameBufferConfig01(pstVideoConfigParams);
    HV_ASSERT_SUCCESS(Hv_Drv_DpuScaler_DpcCapSubSettings(pstVideoConfigParams));
    HV_ASSERT_SUCCESS(Hv_Drv_DpuScaler_DpcSrpSubSettings(pstVideoConfigParams));
    HV_ASSERT_SUCCESS(Hv_Drv_DpuScaler_DpuVdm01Settings(pstVideoConfigParams));
    HV_ASSERT_SUCCESS(Hv_Drv_DpuScaler_SrpTopSubSettings(pstVideoConfigParams));
    HV_ASSERT_SUCCESS(Hv_Drv_DpuScaler_SubLdgTopSubSettings(pstVideoConfigParams));
    Hv_Drv_DpuScaler_SetSubPathInterlaceMode(pstVideoConfigParams, 0);
    Hv_Drv_DpuScaler_SubRatio(pstVideoConfigParams);

    HV_ASSERT_SUCCESS(SubLdgTopCommonSettings(pstVideoConfigParams));
    return HV_SUCCESS;
}

VOID Hv_Drv_DpuScaler_LdgSubBorderEn(BOOL bEn)
{
    SubWindowBorderCfg stBorderCfg = HV_COMMON_DATABASE_GET(SystemData, stSubWindowBorderCfg);
    BOOL bBorderEn = stBorderCfg.ucPxpBorderEnable;
    Hv_Cal_DpuScaler_LdgSubBorderEn(bEn&bBorderEn);
    return;
}

VOID Hv_Drv_DpuScaler_InitFrcModeSub(BOOL bStart)
{
    Hv_Cal_DpuScaler_SetSubFrcIndex(bStart);
    return;
}

VOID Hv_Drv_DpuScaler_SubLdgTopSubBlendEn(BOOL bEn)
{
    Hv_Cal_DpuScaler_SubLdgTopSubBlendEn(bEn);
    return;
}

VOID Hv_Drv_DpuScaler_DtcSubWindowEn(BOOL bEn)
{
    Hv_Cal_DpuScaler_DtcSubWindowEn(bEn);
    return;
}

VOID Hv_Drv_DpuScaler_SetSubSeamlessApplyInEn(BOOL bEn)
{
    Hv_Cal_DpuScaler_SetSubSeamlessApplyInEn(bEn);
    return;
}

VOID Hv_Drv_DpuScaler_SetSubPathClkEn(BOOL bEn)
{
    Hv_Cal_DpuScaler_DpcSrpSubUnpackClkEn(bEn);
    Hv_Cal_DpuScaler_DpuDtcSubRx2ClkEn(bEn);
    Hv_Cal_DpuScaler_SetSubMuteClkEn(bEn);
    if (0 == bEn)
    {
        Hv_Cal_DpuScaler_SrpTopSubScUpClkEn(bEn);
    }
    return;
}

USHORT16 Hv_Drv_DpuScaler_GetPbpMainWindowHSize(USHORT16 usPanelHactive)
{
    return (USHORT16)(usPanelHactive - HV_COMMON_DATABASE_GET(UserData, usPbpWindowHSize));
}
USHORT16 Hv_Drv_DpuScaler_GetPbpMainWindowHTotal(USHORT16 usPanelHactive, USHORT16 usPanelHtotal)
{
    USHORT16 usPbpMainWindowHSize = Hv_Drv_DpuScaler_GetPbpMainWindowHSize(usPanelHactive);
    return (USHORT16)((UINT32)usPanelHtotal * usPbpMainWindowHSize / usPanelHactive);
}

USHORT16 Hv_Drv_DpuScaler_GetPbpSubWindowHSize(VOID)
{
    return (USHORT16)HV_COMMON_DATABASE_GET(UserData, usPbpWindowHSize);
}
