/**
 * @file hv_mw_Video_TimingCheck.c
 * @brief  dpu TimingCheck middleware source file
 * @details This file provides the following functions: \n
 *          (1) dpu TimingCheck handle \n
 *          (2) Feed functions \n
 *
 * @author HiView SoC Software Team
 * @version 1.0.0
 * @date 2022-08-25
 * @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-25   <td>init
 * </table>
*/

#include "hv_mw_Video_TimingCheck.h"
#include "hv_chip_Clk.h"
#include "hv_comm_Assert.h"
#include "hv_mw_InputPortManager.h"
#include "hv_mw_PanelManager.h"
#include "hv_comm_MemParser.h"
#include "hv_drv_DpuCommon.h"
#include "hv_cal_DpuMainScaler.h"
#include "hv_cal_DpuCprConfig.h"
#include "hv_mw_Video.h"

static VOID SetChannelVideoConfigParams(ChannelData* pstChannelData)
{
    const ChannelManager* pstChannelManager =  Hv_Mw_Channel_GetManager();
    pstChannelData->stVideoConfigParams.enAspectRatio = pstChannelManager->astChannelData[CHANNEL_TYPE_MAIN].pfPQCallback(PQCALLBACK_RATIOMAPPING, &(pstChannelData->stVideoConfigParams));
    pstChannelData->stVideoConfigParams.bInterlacedMode    = pstChannelData->stRxVideoTiming.bInterlacedMode;
    pstChannelData->stVideoConfigParams.uiInputFrameRate   = pstChannelData->stRxVideoTiming.usFrameRate;
    pstChannelData->stVideoConfigParams.uiInputVideoWidth  = pstChannelData->stRxVideoTiming.usHActive;
    pstChannelData->stVideoConfigParams.uiInputVideoHight  = pstChannelData->stRxVideoTiming.usVActive;
    pstChannelData->stVideoConfigParams.uiInputVideoHtotal = pstChannelData->stRxVideoTiming.usHTotal;
    pstChannelData->stVideoConfigParams.uiInputVideoVtotal = pstChannelData->stRxVideoTiming.usVTotal;
    pstChannelData->stVideoConfigParams.enPxpMode          = pstChannelManager->stChannelFlashConfig.enFlashPxPMode;
    return;
}

Status Hv_Mw_Video_TimingCheck(LinkPortIndex stPortIndex,ChannelData* pstChannelData)
{
    HV_ASSERT_VALID_PTR(pstChannelData);
    #if 0
    const InputPortManager* pstInputPortManager = Hv_Mw_InputPort_GetManagerPtr();
    if(HV_FAILURE ==  pstInputPortManager->pfGetPortErrorCode(stPortIndex))
    {
        pstInputPortManager->pfReset(stPortIndex);
        HV_LOG_INFO(HDMI, "The Error Code of RX %u exceeds the threshold", stPortIndex);
        return ERROR_RX_AUTOEQ_ABNORMAL;
    }
    #endif
    if ((0 == pstChannelData->stRxVideoTiming.usHTotal)
     || (0 == pstChannelData->stRxVideoTiming.usHActive)
     || (0 == pstChannelData->stRxVideoTiming.usVTotal)
     || (0 == pstChannelData->stRxVideoTiming.usVActive)
     || (0 == pstChannelData->stRxVideoTiming.usFrameRate))
    {
        return ERROR_RX_TIMING_UNSUPPORT;
    }

    MainCprDrrAddr stMainCprDrrAddr = {0};
    SetChannelVideoConfigParams(pstChannelData);
    if ((CHANNEL_TYPE_MAIN == pstChannelData->enChannelType)
    && (HV_FALSE == Hv_Mw_Video_CheckUseFrameSync(pstChannelData->stVideoConfigParams.bVflipEnable, &pstChannelData->stRxVideoTiming, &pstChannelData->stVideoConfigParams)))
    {
        if (HV_FALSE == Hv_Cal_DpuScaler_MainCprDdrAddr(&pstChannelData->stVideoConfigParams, &stMainCprDrrAddr))
        {
            return ERROR_RX_TIMING_UNSUPPORT;
        }
    }

    if (ColorDepthType_16Bit == pstChannelData->stVideoConfigParams.stColor.eClrDepth)
    {
        return ERROR_RX_TIMING_COLOR_DEPTH_NOT_SUPPORT;
    }
    /*2200*1125*297HZ = 735,075 khz*/
    if ((0 == pstChannelData->stRxVideoTiming.uiFreqKHz) || (pstChannelData->stRxVideoTiming.uiFreqKHz > HV_CHIP_CLK_DATAPATH_MAX))
    {
        return ERROR_RX_TIMING_FREQ_OUT_OF_RANGE;
    }
    
    return HV_SUCCESS;
}