/**
 * @file hv_mw_Video_Interrupt.c
 * @brief  dpu interrupt middleware source file
 * @details This file provides the following functions: \n
 *          (1) dpu interrupt handle \n
 *          (2) interrupt init handle \n
 *          (3) 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_vos_Comm.h"
#include "hv_comm_Assert.h"
#include "hv_comm_Define.h"

#include "hv_mw_Video_Interrupt.h"
#include "hv_mw_InputPortManager.h"
#include "hv_mw_Channel_Manager.h"
#include "hv_mw_SystemManager.h"
#include "hv_mw_PanelManager.h"

#include "hv_drv_DpuCommon.h"
#include "hv_drv_DpuMainMute.h"
#include "hv_cal_DpuMainScaler.h"
#ifdef CONFIG_USER_DOUBLE_CHANNEL_ON
#include "hv_drv_DpuSubMute.h"
#endif

#include "hv_drv_Mprt.h"
#include "hv_chip_Irq.h"
#include "hv_cal_PLL.h"
#include "hv_drv_Ktx.h"

static DisplayInterrupt s_stDisplayInterrupt;
DisplayInterrupt* Hv_Mw_Video_GetDisplayInterrupt(VOID)
{
    return &s_stDisplayInterrupt;
}

VOID Hv_Mw_Video_ClearDisplayInterrupt(VOID)
{
    DisplayInterrupt* pstDisplayInterrupt = Hv_Mw_Video_GetDisplayInterrupt();
    HV_MEMSET(pstDisplayInterrupt, 0, sizeof(DisplayInterrupt));
    return;
}
static HV_VOS_ISR_RESULT_E Hv_Mw_Mute_ISRHandler(UINT32 irqNum, void *arg)
{
    Hv_Vos_WClrMiscInt(irqNum - HV_CHIP_IRQ_BASE);

    DisplayInterruptType enInterruptType = DisplayInterruptType_Mute0;
    HV_VOS_QUEUE_S* xSystembQueue = Hv_Mw_System_GetSystemQueue();
    HV_ASSERT_VALID_PTR_RET_NO_LOG(xSystembQueue, HV_VOS_ISR_HANDLED);
    
    if(irqNum == HV_CHIP_IRQ_SH12_0)
    {
        enInterruptType = DisplayInterruptType_Mute0;
        SystemEvent stSystemEvent = {0};
        stSystemEvent.ucChannelType = CHANNEL_TYPE_MAIN;
        stSystemEvent.enEventType = SYSTEM_REV_EVENT_TYPE_CHANNEL;
        /* CHECK MUTE STATUS 0 : Normal 1: Abnormal*/
        if(0 == Hv_Drv_DpuScaler_GetMainMuteIntReason())
        {            
            stSystemEvent.usEventId = CHANNEL_EVENT_ID_MUTE_STATE_NORMAL;
        }
        else
        {
            /*主通道异常时关闭背光，副通道不关背光*/
#if (HV_CONFIG_ON == HV_PROJECT_CONFIG_CHANNEL_SEAMLESS_SWITCH)
            Hv_Cal_DpuScaler_ToggleMainFrcReadIndex();
#endif
            Hv_Mw_Channel_MuteOn(CHANNEL_TYPE_MAIN);
            Hv_Cal_DpuScaler_SetMuteNoDeTh(1200000);
            stSystemEvent.usEventId = CHANNEL_EVENT_ID_MUTE_STATE_ABNORMAL;
        }
        stSystemEvent.uiValue = 0;
        Hv_Vos_QueueSendFromISR(xSystembQueue, (void *)&stSystemEvent);
    }

#ifdef CONFIG_USER_DOUBLE_CHANNEL_ON
    if(irqNum == HV_CHIP_IRQ_SH12_1)
    {
        enInterruptType = DisplayInterruptType_Mute1;
        SystemEvent stSystemEvent = {0};
        stSystemEvent.ucChannelType = CHANNEL_TYPE_SUB;
        stSystemEvent.enEventType = SYSTEM_REV_EVENT_TYPE_CHANNEL;
        /* CHECK MUTE STATUS 0 : Normal 1: Abnormal*/
        if(0 == Hv_Drv_DpuScaler_GetSubMuteIntReason())
        {
            stSystemEvent.usEventId = CHANNEL_EVENT_ID_MUTE_STATE_NORMAL;
        }
        else
        {
            Hv_Mw_Channel_MuteOn(CHANNEL_TYPE_SUB);
            Hv_Cal_DpuScaler_SetMuteSubNoDeTh(1200000);
            stSystemEvent.usEventId = CHANNEL_EVENT_ID_MUTE_STATE_ABNORMAL;
        }
        stSystemEvent.uiValue = 0;
        Hv_Vos_QueueSendFromISR(xSystembQueue, (void *)&stSystemEvent);
    }
    
#endif
    
    /*中断统计*/
    s_stDisplayInterrupt.uiInterruptCount++;
    s_stDisplayInterrupt.enInterruptType = enInterruptType;

    return HV_VOS_ISR_HANDLED;
}

VOID Hv_Mw_Mute_Interrupt_Enable(ChannelType enChannelType)
{
    if(CHANNEL_TYPE_MAIN == enChannelType)
    {
        Hv_Vos_WClrMiscInt(HV_CHIP_IRQ_SH12_0 - HV_CHIP_IRQ_BASE);
        Hv_Cal_DpuScaler_SetMuteSh12MuteInt(HV_ENABLE);
        Hv_Vos_UnmaskIrq(HV_CHIP_IRQ_SH12_0);
    }
#ifdef CONFIG_USER_DOUBLE_CHANNEL_ON
    else
    {
        Hv_Vos_WClrMiscInt(HV_CHIP_IRQ_SH12_1 - HV_CHIP_IRQ_BASE);
        Hv_Cal_DpuScaler_SetMuteSubSh12MuteInt(HV_ENABLE);
        Hv_Vos_UnmaskIrq(HV_CHIP_IRQ_SH12_1);
    }
#endif
    return;
}

VOID Hv_Mw_Mute_Interrupt_Disable(ChannelType enChannelType)
{
    if(CHANNEL_TYPE_MAIN == enChannelType)
    {
        Hv_Vos_WClrMiscInt(HV_CHIP_IRQ_SH12_0 - HV_CHIP_IRQ_BASE);
        Hv_Cal_DpuScaler_SetMuteSh12MuteInt(HV_DISABLE);
        Hv_Vos_MaskIrq(HV_CHIP_IRQ_SH12_0);
    }
#ifdef CONFIG_USER_DOUBLE_CHANNEL_ON
    else
    {
        Hv_Vos_WClrMiscInt(HV_CHIP_IRQ_SH12_1 - HV_CHIP_IRQ_BASE);
        Hv_Cal_DpuScaler_SetMuteSubSh12MuteInt(HV_DISABLE);
        Hv_Vos_MaskIrq(HV_CHIP_IRQ_SH12_1);
    }
#endif
    return;
}

Status Hv_Mw_Mute_Interrupt_Init(VOID)
{
    Hv_Vos_ConfigIrq(HV_CHIP_IRQ_SH12_0, HV_TRUE, 0);
    Hv_Vos_AttachIsr(HV_CHIP_IRQ_SH12_0, Hv_Mw_Mute_ISRHandler, NULL);
    Hv_Mw_Mute_Interrupt_Disable(CHANNEL_TYPE_MAIN);
#ifdef CONFIG_USER_DOUBLE_CHANNEL_ON
    Hv_Vos_ConfigIrq(HV_CHIP_IRQ_SH12_1, HV_TRUE, 0);
    Hv_Vos_AttachIsr(HV_CHIP_IRQ_SH12_1, Hv_Mw_Mute_ISRHandler, NULL);
    Hv_Mw_Mute_Interrupt_Disable(CHANNEL_TYPE_SUB);
#endif
    return HV_SUCCESS;
}

static HV_VOS_ISR_RESULT_E Hv_Mw_DpuScaler_DpuIRQHandler(UINT32 irqNum, void *arg)
{
    const ChannelManager* pstChannelManager = Hv_Mw_Channel_GetManager();
    const VideoConfigParams* pstVideoConfigParams = &pstChannelManager->astChannelData[0].stVideoConfigParams;
    /*清中断！*/
    Hv_Vos_WClrMiscInt(irqNum - HV_CHIP_IRQ_BASE);

    s_stDisplayInterrupt.uiInterruptCount++;
    s_stDisplayInterrupt.enInterruptType = DisplayInterruptType_Dpu;
    Hv_Drv_DpuScaler_DpuIntProc(&s_stDisplayInterrupt.stDpuInterrupt, pstVideoConfigParams, pstChannelManager->astChannelData[CHANNEL_TYPE_MAIN].pfPQCallback);

    return HV_VOS_ISR_HANDLED;
}

static HV_VOS_ISR_RESULT_E Hv_Mw_DpuScaler_DtcIRQHandler(UINT32 irqNum, void *arg)
{
    /*清中断！*/
    Hv_Vos_WClrMiscInt(irqNum - HV_CHIP_IRQ_BASE);

    s_stDisplayInterrupt.uiInterruptCount++;
    s_stDisplayInterrupt.enInterruptType = DisplayInterruptType_Dtc;
    Hv_Drv_DpuScaler_DtcIntProc(&s_stDisplayInterrupt.stDtcInterrupt);
    return HV_VOS_ISR_HANDLED;
}

static HV_VOS_ISR_RESULT_E Hv_Mw_DpuScaler_VsyncISR(UINT32 irqNum, void *arg)
{

    const ChannelManager* pstChannelManager = Hv_Mw_Channel_GetManager();
    const VideoConfigParams* pstVideoConfigParams = &pstChannelManager->astChannelData[0].stVideoConfigParams;
    /*清中断！*/
    Hv_Vos_WClrMiscInt(irqNum - HV_CHIP_IRQ_BASE);
    //Hv_Vos_MaskIrq(irqNum);

    HsIpInterruptDefine* pstIpInterrupt = NULL;
    DisplayInterruptType enType = 0;
    if (HV_CHIP_IRQ_HS_IP0 == irqNum)
    {
        enType = DisplayInterruptType_HsIp0;
        pstIpInterrupt = &s_stDisplayInterrupt.stHsIp0;
    }
    else if (HV_CHIP_IRQ_HS_IP1 == irqNum)
    {
        enType = DisplayInterruptType_HsIp1;
        pstIpInterrupt = &s_stDisplayInterrupt.stHsIp1;
    }
    else if (HV_CHIP_IRQ_HS_DISP == irqNum)
    {
        enType = DisplayInterruptType_HsDisplay;
        pstIpInterrupt = &s_stDisplayInterrupt.stHsDisplay;
    }
    /*中断统计*/
    s_stDisplayInterrupt.uiInterruptCount++;
    s_stDisplayInterrupt.enInterruptType = enType;

    /*中断处理*/
    Hv_Drv_DpuScaler_VsyncHandler(pstIpInterrupt, enType,pstVideoConfigParams, pstChannelManager->astChannelData[CHANNEL_TYPE_MAIN].pfPQCallback);
    return HV_VOS_ISR_HANDLED;
}

Status Hv_Mw_Dpu_Interrupt_Init(VOID)
{
    Hv_Vos_ConfigIrq(HV_CHIP_IRQ_DPU, HV_TRUE, 0);
    Hv_Vos_AttachIsr(HV_CHIP_IRQ_DPU, Hv_Mw_DpuScaler_DpuIRQHandler, NULL);
    Hv_Vos_UnmaskIrq(HV_CHIP_IRQ_DPU);
    
    Hv_Vos_ConfigIrq(HV_CHIP_IRQ_DTC_UNDER, HV_TRUE, 0);
    Hv_Vos_AttachIsr(HV_CHIP_IRQ_DTC_UNDER, Hv_Mw_DpuScaler_DtcIRQHandler, NULL);
    Hv_Vos_UnmaskIrq(HV_CHIP_IRQ_DTC_UNDER);

    Hv_Vos_ConfigIrq(HV_CHIP_IRQ_HS_IP0, HV_TRUE, 0);
    Hv_Vos_AttachIsr(HV_CHIP_IRQ_HS_IP0, Hv_Mw_DpuScaler_VsyncISR, NULL);
    Hv_Vos_UnmaskIrq(HV_CHIP_IRQ_HS_IP0);

    Hv_Vos_ConfigIrq(HV_CHIP_IRQ_HS_IP1, HV_TRUE, 0);
    Hv_Vos_AttachIsr(HV_CHIP_IRQ_HS_IP1, Hv_Mw_DpuScaler_VsyncISR, NULL);
    Hv_Vos_UnmaskIrq(HV_CHIP_IRQ_HS_IP1);

    Hv_Vos_ConfigIrq(HV_CHIP_IRQ_HS_DISP, HV_TRUE, 0);
    Hv_Vos_AttachIsr(HV_CHIP_IRQ_HS_DISP, Hv_Mw_DpuScaler_VsyncISR, NULL);
    Hv_Vos_UnmaskIrq(HV_CHIP_IRQ_HS_DISP);

    return HV_SUCCESS;
}

