/**
 * @file hv_drv_ktx.c
 * @brief ktx module driver
 * @details This module provide interfaces for Hiview-Madia-Ware.
 * @author HiView SoC Software Team
 * @version 0.0.1
 * @date 20220903
 * @copyright Copyright(c),2022-9, Hiview Software. All rights reserved.
 * @par History:
 * <table>
 * <tr><th>Author                         <th>Date             <th>Details
 * <tr><td>HiView SoC Software Team   <td>20220903       <td>Create and first Version.
 * </table>
 **/

#include "hv_drv_Ktx.h"
#include "hv_cal_Ktx.h"
#include "hv_comm_Log.h"
#include "PanelConfig.h"
#include "hv_comm_Assert.h"
#include "hv_vos_Comm.h"
#include "hv_drv_PLL.h"
#include "hv_drv_Gpio.h"
#include "hv_drv_Mprt.h"

#define KTX_DE_PRE_DUMMY_MODE       (0)
#define KTX_DE_POST_DUMMY_MODE      (0)
#define KTX_DE_PRE_DUMMY_NUM        (0)
#define KTX_DE_POST_DUMMY_NUM       (0)
#define TX_LINEBUF_NUM              (5)           /* 获取芯片设计的LineBuf */
#define TX_OUT_DATA_MODE            (0)            /* 获取芯片设计的KTX内部处理位宽0: 10bits; 1: 8bits; 2: 6bits */

#define TX_PLL_MIN_VCO              (800000)       /* khz, 800MHZ */
#define TX_PLL_MAX_VCO              (3000000)      /* khz, 3GHZ */

#define TX_PLL_REF_MIN              (12500)        /* khz, 12.5MHz */
#define TX_PLL_REF_MAX              (100000)       /* khz, 100MHz */

static HvDrvKtxOutParam stKtxOutParam;

Status Hv_Drv_Ktx_Init(HvDrvKtxInParam *pstKtxInParam, const PanelParam *pstPanelParam)
{
    HV_LOG_DEBUG(PANEL, "********** Hv_Drv_Ktx_Init **********");
    HvDrvKtxDesign stKtxDesign;
    HV_MEMSET(&stKtxOutParam, 0, sizeof(stKtxOutParam));
    HV_MEMSET(&stKtxDesign, 0, sizeof(HvDrvKtxDesign));
    // UINT32 hs_filter = 0;

    /* 1.init design parameter from ktx cal layer */
    stKtxDesign.usPPC = TX_PPC;
    stKtxDesign.uiTxPllMaxVco = TX_PLL_MAX_VCO;
    stKtxDesign.uiTxPllMinVco = TX_PLL_MIN_VCO;
    stKtxDesign.uiTxPllMaxRef = TX_PLL_REF_MAX;
    stKtxDesign.uiTxPllMinRef = TX_PLL_REF_MIN;
    stKtxDesign.usTxLineBufNum = TX_LINEBUF_NUM;
    stKtxDesign.ucTxOutDataMode = TX_OUT_DATA_MODE;

    /* 2.gen ktx post cfg */
    HV_ASSERT_SUCCESS(KtxPostTopCfgGen(pstKtxInParam, &stKtxDesign, &stKtxOutParam.stHvDrvKtxPostCfgParam));

    /* 3.gen ktx tx pll cfg */
    if (pstKtxInParam->eHvDrvKtxPhy == KTX_PHY_EDP)
    {
        HV_ASSERT_SUCCESS(Hv_Drv_EdpTx_PllCalculator(pstKtxInParam, &stKtxOutParam.stHvDrvKtxPllCfgParam));
    }
    else if (pstKtxInParam->eHvDrvKtxPhy == KTX_PHY_VBO)
    {
        //HV_ASSERT_SUCCESS(Hv_Drv_VboTx_PllCalculator(pstKtxInParam, &stKtxDesign, &stKtxOutParam.stHvDrvKtxPllCfgParam));
        HV_ASSERT_SUCCESS(Hv_Drv_VboTx_TaibaiPllCalculator(pstKtxInParam, pstKtxInParam->uiKtxInPixClkFreq, &stKtxOutParam.stHvDrvKtxPllCfgParam));
    }
    //Hv_Drv_KTX_SetKTXSelfClock(pstKtxInParam, &stKtxOutParam.stHvDrvKtxPllCfgParam);

    /* 4.gen ktx pif cfg */
    HV_ASSERT_SUCCESS(KtxPifCfgGen(pstKtxInParam, &stKtxDesign, &stKtxOutParam.stHvDrvKtxPostCfgParam, &stKtxOutParam.stHvDrvKtxPifCfgParam));

    /* 5.write to registers */
    Hv_Cal_Ktx_BasicInit(pstPanelParam);
    Hv_Cal_Ktx_SetPostTopParam(&stKtxOutParam.stHvDrvKtxPostCfgParam);
    Hv_Cal_Ktx_SetPllParam(0, &stKtxOutParam.stHvDrvKtxPllCfgParam);
    Hv_Cal_Ktx_SetPifParam(&stKtxOutParam.stHvDrvKtxPifCfgParam);
    Hv_Cal_Ktx_ComboTxPhyMuxSel(0, pstPanelParam);      /*phy0*/
    Hv_Cal_Ktx_ComboTxPhyMuxSel(1, pstPanelParam);      /*phy1*/
    Hv_Cal_Ktx_ComboTxPhyMuxSel(2, pstPanelParam);      /*phy2*/

    return HV_SUCCESS;
}

static Status KtxPostTopCfgGen(HvDrvKtxInParam *pstKtxInParam, HvDrvKtxDesign *pstKtxDesign, HvKtxPostTopCfgParam *pstKtxPostCfgParam)
{
    UINT32 uiHact = 0;
    UINT32 uiAddrShift = 0;

    /* Config Parameter */
    pstKtxPostCfgParam->ucOutDataMode = pstKtxDesign->ucTxOutDataMode;

    uiHact = pstKtxInParam->usKtxInHact / pstKtxDesign->usPPC + pstKtxInParam->usKtxInFlipEnable * (pstKtxInParam->usKtxInPortNum * pstKtxInParam->usKtxInPairNum);

    if (pstKtxInParam->usKtxInPortNum >= 32)        /*最大支持32lane*/
    {
        pstKtxPostCfgParam->ucPortNum = 31;
    }
    else
    {
        pstKtxPostCfgParam->ucPortNum = pstKtxInParam->usKtxInPortNum;
    }

    if (pstKtxInParam->usKtxInPairNum >= 32)
    {
        pstKtxPostCfgParam->ucPairNum = 31;
    }
    else
    {
        pstKtxPostCfgParam->ucPairNum = pstKtxInParam->usKtxInPairNum;
    }

    if (pstKtxInParam->usKtxInSourceNum == 2)           /*根据source num判断对应功能是否需求开启*/
    {
        pstKtxPostCfgParam->ucDoublescanEn = 1;
    }
    else
    {
        pstKtxPostCfgParam->ucDoublescanEn = 0;
    }

    if (pstKtxInParam->usKtxInUsePreDe == 1)
    {
        pstKtxPostCfgParam->ucDegenUseInPreDe = 1;
    }
    else
    {
        pstKtxPostCfgParam->ucDegenUseInPreDe = 0;
    }

    if (pstKtxInParam->usKtxInGateNum == 3)
    {
        pstKtxPostCfgParam->ucDualgateEn = 0;
        pstKtxPostCfgParam->ucTrigateEn = 1;
        pstKtxPostCfgParam->ucDegenUse1stLine = 0;
    }
    else if (pstKtxInParam->usKtxInGateNum == 2)
    {
        pstKtxPostCfgParam->ucDualgateEn = 1;
        pstKtxPostCfgParam->ucTrigateEn = 0;
        pstKtxPostCfgParam->ucDegenUse1stLine = 0;
    }
    else
    {
        pstKtxPostCfgParam->ucDualgateEn = 0;
        pstKtxPostCfgParam->ucTrigateEn = 0;
        pstKtxPostCfgParam->ucDegenUse1stLine = 1;
    }

    pstKtxPostCfgParam->ucDePreNum = (pstKtxInParam->usKtxInUsePreDe * pstKtxInParam->usKtxInPreDeBeforeKtx + pstKtxDesign->usTxLineBufNum - 1) \
                                    * pstKtxInParam->usKtxInGateNum / pstKtxInParam->usKtxInSourceNum - 2;

    if (pstKtxInParam->usKtxInSourceNum > 1)
    {
        pstKtxPostCfgParam->ucDeOutDly = (pstKtxInParam->usKtxInPortNum * pstKtxInParam->usKtxInPairNum) * 2 + 3 + 11;
    }
    else
    {
        pstKtxPostCfgParam->ucDeOutDly = (pstKtxInParam->usKtxInPortNum * pstKtxInParam->usKtxInPairNum) * 1 + 1 + 11;
    }

    pstKtxPostCfgParam->ucMppHBackPorch = (pstKtxInParam->eHvDrvKtxPhy == KTX_PHY_VBO || pstKtxInParam->eHvDrvKtxPhy == KTX_PHY_EDP) ? 10 : 1;
    pstKtxPostCfgParam->ucDePreDummyMode = KTX_DE_PRE_DUMMY_MODE;
    pstKtxPostCfgParam->ucDePostDummyMode = KTX_DE_POST_DUMMY_MODE;
    pstKtxPostCfgParam->ucDePreDummyNum = KTX_DE_PRE_DUMMY_NUM;
    pstKtxPostCfgParam->usDePostDummyNum = KTX_DE_POST_DUMMY_NUM;
    pstKtxPostCfgParam->ucRamEnable = (1 << pstKtxDesign->usTxLineBufNum) - 1;
    pstKtxPostCfgParam->usMppHAct = uiHact / (pstKtxInParam->usKtxInGateNum * pstKtxInParam->usKtxInSourceNum);
    pstKtxPostCfgParam->usMppVAct = (pstKtxInParam->usKtxInVact * pstKtxInParam->usKtxInGateNum) / pstKtxInParam->usKtxInSourceNum;

    pstKtxPostCfgParam->usWram1stStartAddr = 0;
    pstKtxPostCfgParam->usWram2ndStartAddr = (uiHact / pstKtxInParam->usKtxInGateNum) * 1;
    pstKtxPostCfgParam->usWram3rdStartAddr = (uiHact / pstKtxInParam->usKtxInGateNum) * 2;

    if (pstKtxInParam->usKtxInSourceNum == 1)
    {
        pstKtxPostCfgParam->ucDsMapEn = 0;
    }
    else
    {
        pstKtxPostCfgParam->ucDsMapEn = 1;
    }

    if (pstKtxInParam->usKtxInReverseScan == 1)
    {
        pstKtxPostCfgParam->uiLnPixelSwap = 0xffff;
    }
    else
    {
        pstKtxPostCfgParam->uiLnPixelSwap = 0;
    }

    if (pstKtxInParam->usKtxInUsePreDe == 1)
    {
        pstKtxPostCfgParam->usInVAct = pstKtxInParam->usKtxInVact + pstKtxInParam->usKtxInPreDeBeforeKtx;
    }
    else
    {
        pstKtxPostCfgParam->usInVAct = pstKtxInParam->usKtxInVact;
    }

    for (UINT32 uiIndex = 0; uiIndex < (pstKtxInParam->usKtxInPortNum * pstKtxInParam->usKtxInPairNum); uiIndex++)
    {
        // addr_index_lane[uiIndex] = uiIndex/in_pair_num + in_reverse_scan;
        // pstKtxPostCfgParam->usRRamAddrShift[uiIndex] = (uiIndex/pstKtxInParam->usKtxInPairNum + pstKtxInParam->usKtxInReverseScan) * (pstKtxInParam->usKtxInHact/pstKtxInParam->tx_in_ppc/pstKtxInParam->usKtxInGateNum/pstKtxInParam->usKtxInPortNum) - pstKtxInParam->usKtxInReverseScan + pstKtxInParam->usKtxInFlipEnable*pstKtxInParam->usKtxInReverseScan;
        uiAddrShift = (uiIndex / pstKtxInParam->usKtxInPairNum + pstKtxInParam->usKtxInReverseScan) * (pstKtxInParam->usKtxInHact / pstKtxDesign->usPPC / pstKtxInParam->usKtxInGateNum / pstKtxInParam->usKtxInPortNum);
        uiAddrShift = (UINT32)uiAddrShift - (UINT32)(pstKtxInParam->usKtxInReverseScan + pstKtxInParam->usKtxInFlipEnable * pstKtxInParam->usKtxInReverseScan);
        pstKtxPostCfgParam->usRRamAddrShift[uiIndex] = uiAddrShift;
        pstKtxPostCfgParam->ucLaneIndex[uiIndex] = uiIndex;
        HV_LOG_DEBUG(PANEL, "pstKtxPostCfgParam->ucLaneIndex[%u] = %u",pstKtxPostCfgParam->ucLaneIndex[uiIndex], uiIndex);
        pstKtxPostCfgParam->ucRamReverse[uiIndex] = pstKtxInParam->usKtxInReverseScan;
    }
#ifdef HV_SCALER_DEBUG_VERSION
    HV_LOG_DEBUG(PANEL, "********** KTX_CFG pstKtxPostCfgParam->ucPortNum:%d", pstKtxPostCfgParam->ucPortNum);
    HV_LOG_DEBUG(PANEL, "********** KTX_CFG pstKtxPostCfgParam->ucPairNum:%d", pstKtxPostCfgParam->ucPairNum);
    HV_LOG_DEBUG(PANEL, "********** KTX_CFG pstKtxPostCfgParam->ucDoublescanEn:%d", pstKtxPostCfgParam->ucDoublescanEn);
    HV_LOG_DEBUG(PANEL, "********** KTX_CFG pstKtxPostCfgParam->ucDegenUseInPreDe:%d", pstKtxPostCfgParam->ucDegenUseInPreDe);
    HV_LOG_DEBUG(PANEL, "********** KTX_CFG pstKtxPostCfgParam->ucDualgateEn:%d", pstKtxPostCfgParam->ucDualgateEn);
    HV_LOG_DEBUG(PANEL, "********** KTX_CFG pstKtxPostCfgParam->ucTrigateEn:%d", pstKtxPostCfgParam->ucTrigateEn);
    HV_LOG_DEBUG(PANEL, "********** KTX_CFG pstKtxPostCfgParam->ucDegenUse1stLine:%d", pstKtxPostCfgParam->ucDegenUse1stLine);
    HV_LOG_DEBUG(PANEL, "********** KTX_CFG pstKtxPostCfgParam->ucDePreNum:%d", pstKtxPostCfgParam->ucDePreNum);
    HV_LOG_DEBUG(PANEL, "********** KTX_CFG pstKtxPostCfgParam->ucDeOutDly:%d", pstKtxPostCfgParam->ucDeOutDly);
    HV_LOG_DEBUG(PANEL, "********** KTX_CFG pstKtxPostCfgParam->ucMppHBackPorch:%d", pstKtxPostCfgParam->ucMppHBackPorch);
    HV_LOG_DEBUG(PANEL, "********** KTX_CFG pstKtxPostCfgParam->ucDePreDummyMode:%d", pstKtxPostCfgParam->ucDePreDummyMode);
    HV_LOG_DEBUG(PANEL, "********** KTX_CFG pstKtxPostCfgParam->ucDePostDummyMode:%d", pstKtxPostCfgParam->ucDePostDummyMode);
    HV_LOG_DEBUG(PANEL, "********** KTX_CFG pstKtxPostCfgParam->ucDePreDummyNum:%d", pstKtxPostCfgParam->ucDePreDummyNum);
    HV_LOG_DEBUG(PANEL, "********** KTX_CFG pstKtxPostCfgParam->usDePostDummyNum:%d", pstKtxPostCfgParam->usDePostDummyNum);
    HV_LOG_DEBUG(PANEL, "********** KTX_CFG pstKtxPostCfgParam->ucRamEnable:%d", pstKtxPostCfgParam->ucRamEnable);
    HV_LOG_DEBUG(PANEL, "********** KTX_CFG pstKtxPostCfgParam->usMppHAct:%d", pstKtxPostCfgParam->usMppHAct);
    HV_LOG_DEBUG(PANEL, "********** KTX_CFG pstKtxPostCfgParam->usMppVAct:%d", pstKtxPostCfgParam->usMppVAct);
    HV_LOG_DEBUG(PANEL, "********** KTX_CFG pstKtxPostCfgParam->usWram1stStartAddr:%d", pstKtxPostCfgParam->usWram1stStartAddr);
    HV_LOG_DEBUG(PANEL, "********** KTX_CFG pstKtxPostCfgParam->usWram2ndStartAddr:%d", pstKtxPostCfgParam->usWram2ndStartAddr);
    HV_LOG_DEBUG(PANEL, "********** KTX_CFG pstKtxPostCfgParam->usWram3rdStartAddr:%d", pstKtxPostCfgParam->usWram3rdStartAddr);
    HV_LOG_DEBUG(PANEL, "********** KTX_CFG pstKtxPostCfgParam->ucDsMapEn:%d", pstKtxPostCfgParam->ucDsMapEn);
    HV_LOG_DEBUG(PANEL, "********** KTX_CFG pstKtxPostCfgParam->uiLnPixelSwap:%d", pstKtxPostCfgParam->uiLnPixelSwap);
    HV_LOG_DEBUG(PANEL, "********** KTX_CFG pstKtxPostCfgParam->usInVAct:%d", pstKtxPostCfgParam->usInVAct);
    HV_LOG_DEBUG(PANEL, "********** KTX_CFG pstKtxPostCfgParam->ucOutDataMode:%d", pstKtxPostCfgParam->ucOutDataMode);
    HV_LOG_DEBUG(PANEL, "********** KTX_CFG pstKtxPostCfgParam->usHsFilter:%d", pstKtxPostCfgParam->usHsFilter);
#endif
    return HV_SUCCESS;
}

static Status KtxPifCfgGen(
    HvDrvKtxInParam *pstKtxInParam,
    HvDrvKtxDesign *pstKtxDesign,
    HvKtxPostTopCfgParam *pstKtxPostCfgParam,
    HvKtxPIFCfgParam *pstKtxPifCfgParam)
{
    USHORT16 usPacketLenPif = 0;
    USHORT16 usPacketVldPif = 0;
    USHORT16 usTotalLane = pstKtxInParam->usKtxInPortNum * pstKtxInParam->usKtxInPairNum;
    UINT32 uiPixPerLanePif = ((pstKtxInParam->usKtxInHact / pstKtxInParam->usKtxInGateNum) * pstKtxInParam->usKtxInSourceNum) / usTotalLane + pstKtxInParam->usKtxInFlipEnable;
    UINT32 usPifClkRatio = 0;
    UINT64 ullCalStaVal = 0;
    UINT64 ullP2pHsFilter = 0;

    pstKtxPifCfgParam->ucTxgrp00PifTxW2rDly = 13;
    //pstKtxPifCfgParam->ucPifInAfifoSizeMode = (usTotalLane>12) ? 0 : ((usTotalLane>6) ? 2 : 3);
    pstKtxPifCfgParam->ucPifInAfifoSizeMode = (usTotalLane > 4) ? 0 : 3;
    /* vbotx not has min htotal limitation */
    pstKtxPifCfgParam->usTxMinHTotal = 0;
    if (pstKtxInParam->eHvDrvKtxPhy == KTX_PHY_EDP)
    {
        usPacketLenPif = 20;
        usPacketVldPif = 20;
        pstKtxPifCfgParam->ucTxgrp00PifTxW2rDly = 7;
        pstKtxPostCfgParam->usHsFilter = 16;
        pstKtxPifCfgParam->ucPifInAfifoSizeMode = 0;

        HV_ASSERT_TRUE(pstKtxInParam->uiKtxInPixClkFreq > 0);
        usPifClkRatio = ((pstKtxInParam->uiKtxInDptxFreq * 100) / usPacketLenPif) / (pstKtxInParam->uiKtxInPixClkFreq / usTotalLane);
        HV_ASSERT_TRUE(usPifClkRatio > 0);
        HV_LOG_DEBUG(PANEL, "usPifClkRatio is %d !!!", usPifClkRatio);
        if (usPifClkRatio < 1)
        {
            HV_LOG_ERROR(PANEL, "ERROR : edptx pifclk<pixclk/ppc !!!");
            return HV_FAILURE;
        }

        HV_LOG_DEBUG(PANEL, "pstKtxInParam->usKtxInColorDepth is %d !!!", pstKtxInParam->usKtxInColorDepth);
        HV_LOG_DEBUG(PANEL, "pstKtxPostCfgParam->ucMppHBackPorch is %d !!!", pstKtxPostCfgParam->ucMppHBackPorch);
        HV_LOG_DEBUG(PANEL, "pstKtxPostCfgParam->ucDeOutDly is %d !!!", pstKtxPostCfgParam->ucDeOutDly);
        //pstKtxInParam->usKtxInCalSta = ((32 / 16 * 100 / usPifClkRatio * 3 * pstKtxInParam->usKtxInColorDepth) * (usPifClkRatio - 100) / usPifClkRatio + pstKtxPostCfgParam->ucMppHBackPorch + pstKtxPostCfgParam->ucDeOutDly + 2) * usPifClkRatio / 100 + 8;
        ullCalStaVal = ((200 / usPifClkRatio) * 3) * pstKtxInParam->usKtxInColorDepth;
        ullCalStaVal *= (usPifClkRatio-100) / usPifClkRatio;
        ullCalStaVal += pstKtxPostCfgParam->ucMppHBackPorch + pstKtxPostCfgParam->ucDeOutDly + 2;
        ullCalStaVal = ullCalStaVal * usPifClkRatio / 100;
        ullCalStaVal += 8;
        pstKtxInParam->usKtxInCalSta = (USHORT16)ullCalStaVal;
    }
    else if (pstKtxInParam->eHvDrvKtxPhy == KTX_PHY_VBO)
    {
        pstKtxPostCfgParam->usHsFilter = 0;
        if (pstKtxInParam->usKtxInColorDepth == 6)
        {
            usPacketLenPif = 10;
            usPacketVldPif = 6;
        }
        else if (pstKtxInParam->usKtxInColorDepth == 8)
        {
            usPacketLenPif = 10;
            usPacketVldPif = 8;
        }
        else if (pstKtxInParam->usKtxInColorDepth == 10)
        {
            usPacketLenPif = 10;
            usPacketVldPif = 6;
        }
        else if (pstKtxInParam->usKtxInColorDepth == 12)
        {
            usPacketLenPif = 10;
            usPacketVldPif = 7;
        }
        else
        {
            HV_LOG_DEBUG(PANEL, "ERROR : VBO bit mode not support !!!");
            return HV_FAILURE;
        }
        pstKtxInParam->usKtxInCalSta = ((8 * usTotalLane) / pstKtxDesign->usPPC + pstKtxPostCfgParam->ucMppHBackPorch + pstKtxPostCfgParam->ucDeOutDly + 2) * \
                                    ((pstKtxDesign->usPPC * 3) * pstKtxInParam->usKtxInColorDepth) / usTotalLane / usPacketVldPif - 3;
        HV_LOG_DEBUG(PANEL, "KtxPifCfgGen  pstKtxInParam->usKtxInCalSta: %d ", pstKtxInParam->usKtxInCalSta);
    }
    else
    {
        /* ceds/epi/chpi/cmpi */
        /* hs_filter */
        ullP2pHsFilter = (pstKtxInParam->uiKtxInPixClkFreq / pstKtxDesign->usPPC) * (pstKtxPifCfgParam->usPifTg0PacketDhDenEnd + 6);
        pstKtxPostCfgParam->usHsFilter = (USHORT16) ullP2pHsFilter / (pstKtxInParam->uiKtxInRefClkFreq / stKtxOutParam.stHvDrvKtxPllCfgParam.ucTxPllPreDiv * \
                                        stKtxOutParam.stHvDrvKtxPllCfgParam.usTxPllFbdivInt / stKtxOutParam.stHvDrvKtxPllCfgParam.usTxPllPostDiv0 / \
                                        stKtxOutParam.stHvDrvKtxPllCfgParam.ucTxPllPifDiv);
        pstKtxPifCfgParam->usTxMinHTotal = ((pstKtxPifCfgParam->usPifTg0PacketDhDenEnd + 6) * usTotalLane) * usPacketVldPif / (3 * pstKtxInParam->usKtxInColorDepth);

    }
    if (pstKtxInParam->usKtxInMinSta > pstKtxInParam->usKtxInCalSta)
    {
        pstKtxPifCfgParam->usPifTg0PacketDhDenSta = pstKtxInParam->usKtxInMinSta;
    }
    else
    {
        pstKtxPifCfgParam->usPifTg0PacketDhDenSta = pstKtxInParam->usKtxInCalSta;
    }
    pstKtxPifCfgParam->usPifTg0PacketDhDenEnd = (pstKtxInParam->eHvDrvKtxPhy == 7) ? 0x7fff : (uiPixPerLanePif * 3 * pstKtxInParam->usKtxInColorDepth) / usPacketVldPif + pstKtxPifCfgParam->usPifTg0PacketDhDenSta;
    pstKtxPifCfgParam->usPifTg0PacketDvDenSta = pstKtxPostCfgParam->ucDePreNum + 1;
    pstKtxPifCfgParam->usPifTg0PacketDvDenEnd = pstKtxPifCfgParam->usPifTg0PacketDvDenSta + (pstKtxInParam->usKtxInVact * pstKtxInParam->usKtxInGateNum) / pstKtxInParam->usKtxInSourceNum;

    pstKtxPifCfgParam->ucTxgrp00PifConvMode = usPacketLenPif;
    pstKtxPifCfgParam->ucTxgrp0PhyModeSel = pstKtxInParam->eHvDrvKtxPhy;
    pstKtxPifCfgParam->uiPifTg0PktDoubleBufferTimer = 0;
    pstKtxPifCfgParam->ucTxgrp00DclkDivNum = 2;

    pstKtxPifCfgParam->uiPtgHsDly = roundup_div((pstKtxPifCfgParam->usTxMinHTotal / pstKtxInParam->usKtxInGateNum) * 3 * pstKtxInParam->usKtxInColorDepth, usTotalLane * usPacketVldPif * 2 * 16);

    return HV_SUCCESS;
}

VOID HV_Drv_Ktx_PllEnable(BOOL bEn)
{
    HV_LOG_DEBUG(PANEL, "********** HV_Drv_Ktx_PllEnable **********");
    Hv_Cal_Ktx_PllEn(bEn);
    Hv_Drv_Ktx_PifStart(bEn);
    Hv_Cal_Ktx_TxPhyRdClkEn(bEn);
    Hv_Cal_Ktx_PifPreClkEn(bEn);
    Hv_Cal_Ktx_PifLaneClkEn(bEn);

    Hv_Vos_Delayus(10);
    if (Hv_Cal_Ktx_GetKtxPifAfifoFlag() || Hv_Cal_Ktx_GetKtxPostFifoFlag())
    {
        Hv_Cal_Ktx_PifRst(HV_FALSE);
        Hv_Cal_Ktx_TxMacRst(HV_FALSE);
        Hv_Cal_Ktx_KtxPostFifoFlagClear();
        Hv_Cal_Ktx_KtxPifAfifoFlagClear();
        Hv_Vos_Delayus(10);
        Hv_Cal_Ktx_PifRst(HV_TRUE);
        Hv_Cal_Ktx_TxMacRst(HV_TRUE);
    }
    return;
}

VOID Hv_Drv_Ktx_ComboTxPhyEnable(BOOL bEn, TxPanelParam *pstTxPanelParam)
{
    if (pstTxPanelParam->bTxPhy0MuxEn == HV_TRUE)
    {
        HV_Cal_Ktx_ComboTxPhyEn(0, bEn);
    }
    if (pstTxPanelParam->bTxPhy1MuxEn == HV_TRUE)
    {
        HV_Cal_Ktx_ComboTxPhyEn(1, bEn);
    }
    if (pstTxPanelParam->bTxPhy2MuxEn == HV_TRUE)
    {
        HV_Cal_Ktx_ComboTxPhyEn(2, bEn);
    }

    if (bEn == HV_TRUE)
    {
        Hv_Vos_Delayus(10);
        if (Hv_Cal_Ktx_GetTxPhyAfifoFlag())
        {
            Hv_Cal_Ktx_PifStart(HV_FALSE);
            Hv_Cal_Ktx_TxPhyAfifoFlagClear();
            Hv_Vos_Delayus(10);
            Hv_Cal_Ktx_PifStart(HV_TRUE);
        }
    }

    return;
}

VOID Hv_Drv_Ktx_PifStart(BOOL bStart)
{
    Hv_Cal_Ktx_PifStart(bStart);
    return;
}

VOID Hv_Drv_Ktx_TxMacRst(BOOL bStart)
{
    Hv_Cal_Ktx_TxMacRst(bStart);
    return;
}

VOID Hv_Drv_Ktx_PifRst(BOOL bStart)
{
    Hv_Cal_Ktx_PifRst(bStart);
    return;
}

BOOL Hv_Drv_Ktx_GetTxPhyAfifoFlag(VOID)
{
    return Hv_Cal_Ktx_GetTxPhyAfifoFlag();
}

VOID Hv_Drv_Ktx_TxPhyAfifoFlagClear(VOID)
{
    Hv_Cal_Ktx_TxPhyAfifoFlagClear();
    return;
}


VOID Hv_Drv_Ktx_SetBacklightPower(BOOL ucEn)
{
#if (HV_PROJECT_CONFIG_FULL_LOCALDIMMING == HV_CONFIG_OFF)
    Hv_Drv_MPRT_SetOutHighFreqPwmEnable(ucEn);
    //HV_LOG_INFO(HDMI, "##backlight %u",ucEn);
#else
    #ifdef HV_BOARD_CONFIG_GPIO_PANEL_LDC_BLEN
    Hv_Drv_Gpio_SetPinLevel(HV_BOARD_CONFIG_GPIO_PANEL_LDC_BLEN, ucEn ? GPIO_LEVEL_HIGH : GPIO_LEVEL_LOW);
    #endif
    
    #ifdef HV_BOARD_CONFIG_GPIO_PANEL_LDC_BLEN1
    Hv_Drv_Gpio_SetPinLevel(HV_BOARD_CONFIG_GPIO_PANEL_LDC_BLEN1, ucEn ? GPIO_LEVEL_HIGH : GPIO_LEVEL_LOW);
    #endif

    #ifdef HV_BOARD_CONFIG_GPIO_PANEL_LDC_BLEN_REVERT
    Hv_Drv_Gpio_SetPinLevel(HV_BOARD_CONFIG_GPIO_PANEL_LDC_BLEN_REVERT, ucEn ? GPIO_LEVEL_LOW : GPIO_LEVEL_HIGH);
    #endif
#endif
    return;
}

BOOL Hv_Drv_Ktx_GetBacklightPower(VOID)
{
    return Hv_Drv_MPRT_GetOutHighFreqPwmEnable();
}

Status Hv_Drv_Ktx_SetKtxPatt(UCHAR8 ucKtxPattSwitch, UCHAR8 ucPatternMode)
{
    HV_ASSERT_SUCCESS(Hv_Cal_Ktx_SetKtxPatt(ucKtxPattSwitch, ucPatternMode));
    return HV_SUCCESS;
}

VOID Hv_Drv_Ktx_PanelVideoPower(BOOL bEn)
{
    /*给屏数据12V供电的GPIO控制（非背光）*/ 
    Hv_Drv_Gpio_SetDirection(HV_BOARD_CONFIG_GPIO_PANEL_EN, GPIO_DIR_OUTPUT);
    Hv_Drv_Gpio_SetPinLevel(HV_BOARD_CONFIG_GPIO_PANEL_EN, bEn ? GPIO_LEVEL_HIGH : GPIO_LEVEL_LOW);
 #ifdef HV_BOARD_CONFIG_GPIO_10V_EN
    Hv_Drv_Gpio_SetDirection(HV_BOARD_CONFIG_GPIO_10V_EN, GPIO_DIR_OUTPUT);
    Hv_Drv_Gpio_SetPinLevel(HV_BOARD_CONFIG_GPIO_10V_EN, bEn ? GPIO_LEVEL_HIGH : GPIO_LEVEL_LOW);
 #endif
}

VOID Hv_Drv_Ktx_SetTxPostCursroParam(UINT32 uiHpost, UINT32 uiVpost,UINT32 uiR, UINT32 uiG, UINT32 uiB)
{
    Hv_Cal_Ktx_SetTxPostCursroParam(uiHpost, uiVpost, uiR, uiG, uiB);
    return;
}

VOID Hv_Drv_Ktx_SetPanelState(USHORT16 usState)
{
    Hv_Cal_Ktx_SetPanelState(usState);
    return;
}

VOID Hv_Drv_Ktx_SetPowerState(USHORT16 usState)
{
    Hv_Cal_Ktx_SetPowerState(usState);
    return;
}

VOID Hv_Drv_Ktx_SetPowerOnReason(USHORT16 usState)
{
    Hv_Cal_Ktx_SetPowerOnReason(usState);
    return;
}

VOID Hv_Drv_Ktx_SetLdcVcc(UCHAR8 ucEn)
{
#ifdef HV_BOARD_CONFIG_GPIO_PANEL_LDC_VCCON
    Hv_Drv_Gpio_SetPinLevel(HV_BOARD_CONFIG_GPIO_PANEL_LDC_VCCON, ucEn ? GPIO_LEVEL_HIGH : GPIO_LEVEL_LOW);
#endif
    return;
}

VOID Hv_Drv_Ktx_SetLdcVin(UCHAR8 ucEn)
{
#ifdef HV_BOARD_CONFIG_GPIO_PANEL_LDC_VINEN
    Hv_Drv_Gpio_SetPinLevel(HV_BOARD_CONFIG_GPIO_PANEL_LDC_VINEN, ucEn ? GPIO_LEVEL_HIGH : GPIO_LEVEL_LOW);
#endif
#ifdef HV_BOARD_CONFIG_GPIO_PANEL_LDC_VINEN_REVERT
    Hv_Drv_Gpio_SetPinLevel(HV_BOARD_CONFIG_GPIO_PANEL_LDC_VINEN_REVERT, ucEn ? GPIO_LEVEL_LOW : GPIO_LEVEL_HIGH);
#endif
    return;
}

VOID Hv_Drv_Ktx_SetLdcEn(UCHAR8 ucEn)
{
#ifdef HV_BOARD_CONFIG_GPIO_PANEL_LDC_LDEN
    Hv_Drv_Gpio_SetPinLevel(HV_BOARD_CONFIG_GPIO_PANEL_LDC_LDEN, ucEn ? GPIO_LEVEL_HIGH : GPIO_LEVEL_LOW);
#endif
    return;
}