/**
 * @file hv_cal_OsdFrame.c
 * @brief Osd Cal Frame interface file.
 * @details This file provides the following functions: \n
 *          (1) Osd CAL layer initialization functions \n
 *
 * @author HiView SoC Software Team
 * @version 1.0.0
 * @date 2022-08-31
 * @copyright Copyright(c),2022-8, Hiview Software. All rights reserved.
 * @par History:
 * <table>
 * <tr><th>Author         <th>Date        <th>Change Description
 * <tr><td>OSD Group      <td>2022-08-31   <td>create
 * </table>
*/

#include "hv_drv_Osd.h"
#include "hv_cal_Osd.h"

UINT32 Hv_Cal_OsdFrame_PixelFormatConvert(OsdPixelFormat enSrcFormat, OsdPixelFormat enDstFormat, UINT32 uiColor)
{
    UCHAR8 ucR = 0;
    UCHAR8 ucG = 0;
    UCHAR8 ucB = 0;
    UCHAR8 ucA = 0;
    UINT32 uiRes = 0;

    switch (enSrcFormat)
    {
        case OSD_PIXEL_FORMAT_RGBA8888:
        case OSD_PIXEL_FORMAT_RGB888:
        {
            ucA = (uiColor >> 24) & 0xff;
            ucB = (uiColor >> 16) & 0xff;
            ucG = (uiColor >> 8) & 0xff;
            ucR = uiColor & 0xff;
            break;
        }
        case OSD_PIXEL_FORMAT_RGBA4444:
        {
            ucR = (((USHORT16)uiColor >> 0) & 0x0f) << 4;
            ucG = (((USHORT16)uiColor >> 4) & 0x0f) << 4;
            ucB = (((USHORT16)uiColor >> 8) & 0x0f) << 4;
            break;
        }
        case OSD_PIXEL_FORMAT_RGB565:
        {
            ucB = (((USHORT16)uiColor >> 11) & 0x1F) << 3;
            ucG = (((USHORT16)uiColor >> 5) & 0x3F) << 2;
            ucR = (((USHORT16)uiColor >> 0) & 0x1F) << 3;
            break;
        }
        default:
        {
            break;
        }
    }

    switch (enDstFormat)
    {
        case OSD_PIXEL_FORMAT_RGBA8888:
        case OSD_PIXEL_FORMAT_RGB888:
        {
            uiRes = (ucA << 24) | (ucB << 16) | (ucG << 8) | ucR;
            break;
        }
        case OSD_PIXEL_FORMAT_RGBA4444:
        {
            uiRes = ((ucA >> 4) << 12) | ((ucB >> 4) << 8)
                    | ((ucG >> 4) << 4) | (ucR >> 4);
            break;
        }
        case OSD_PIXEL_FORMAT_RGB565:
        {
            uiRes = (((USHORT16)(ucB >> 3)) << 11) | (((USHORT16)(ucG >> 2)) << 5)
                    | ((USHORT16)(ucR >> 3));
            break;
        }
        default:
        {
            break;
        }
    }

    return uiRes;
}

/*sh06_top*/
static VOID Hv_Cal_OsdFrame_DispOsdRst(BOOL bEnable)
{
    HV_W32_FIELD(SYS_SH06_TOP_08, reg_disp_osd_rst_n, bEnable);
}

/**
 * 0: disable
 * 1: disable
 * 2: 2
 * 3: 3
 * 4: 4
 * 5: 5
 *
 * .
 * .
 * .
 *
 * 15: 15
 */
VOID Hv_Cal_OsdFrame_VsDivNum(UCHAR8 ucDivNum)
{
    HV_W32_FIELD(DISP_TOP_DPU_LDG_SYNC_14, reg_osd_vs_div_num, ucDivNum);
}

VOID Hv_Cal_OsdFrame_WdmaHeight(USHORT16 usHeight)
{
    HV_W32_FIELD(DISP_TOP_DPU_LDG_SYNC_14, reg_osd_wdma_height, usHeight);
}

VOID Hv_Cal_OsdFrame_SwTriggerEnable(BOOL bEnable)
{
    HV_W32_FIELD(DISP_TOP_DPU_LDG_SYNC_18, reg_osd_sw_trig_en, bEnable);
    HV_W32_FIELD(DISP_TOP_DPU_LDG_SYNC_18, reg_osd_sw_trig, bEnable);
}

/*kosd top*/
VOID Hv_Cal_OsdFrame_Sw0ApbReset(BOOL bEnable)
{
    HV_W32_FIELD(DISP_TOP_SUB_OSD_TOP_6C, reg_kosd_sw0_apb_reset, bEnable);
}

VOID Hv_Cal_OsdFrame_Sw1ApbReset(BOOL bEnable)
{
    HV_W32_FIELD(DISP_TOP_SUB_OSD_TOP_6C, reg_kosd_sw1_apb_reset, bEnable);
}

VOID Hv_Cal_OsdFrame_SetSync(VOID)
{
    OSD_DRV_LOG_DEBUG("Set Sync\n");
    HV_W32_FIELD(DISP_TOP_KOSD_TOP_00, reg_en, 1);
}

BOOL Hv_Cal_OsdFrame_CheckSync(VOID)
{
    HV_R32_DECL_VAR();

    return HV_R32_FIELD(DISP_TOP_KOSD_TOP_00, reg_en) == 0;
}

VOID Hv_Cal_OsdFrame_WaitSync(VOID)
{
    OSD_DRV_LOG_DEBUG("Wait Sync...\n");
#ifdef OSD_TEST_ASYNC_REGEN
    Hv_Vos_TaskYield();
#else
    while (!Hv_Cal_OsdFrame_CheckSync())
    {
        Hv_Cal_Osd_TimeDelayMs(1);
    }
    Hv_Cal_OsdInnerDMA_ClearStart();
#endif
    OSD_DRV_LOG_DEBUG("Sync done!!\n");
}

VOID Hv_Cal_OsdFrame_SetAndWaitSync(VOID)
{
    Hv_Cal_OsdFrame_SetSync();
    Hv_Cal_OsdFrame_WaitSync();
}

VOID Hv_Cal_OsdFrame_SetUniversalAlphaEnable(OsdDataPath enPath, BOOL bEnable)
{
    switch (enPath)
    {
        case OSD_DATAPATH_GRAPHIC:
        {
            HV_W32_FIELD(DISP_TOP_KOSD_TOP_3C, regs_force_alpha_en, bEnable);
            break;
        }
        case OSD_DATAPATH_DDRREAD:
        {
            //HV_W32_FIELD(DISP_TOP_SUB_OSD_TOP_B8, regs_rdma_force_alpha_en, bEnable);
            break;
        }
        case OSD_DATAPATH_HSBLEND:
        {
            HV_W32_FIELD(DISP_TOP_SUB_OSD_TOP_70, reg_osd_alpha_force_en, bEnable);
            break;
        }
        default:
        {
            break;
        }
    }
}

VOID Hv_Cal_OsdFrame_SetUniversalAlphaValue(OsdDataPath enPath, UCHAR8 ucValue)
{
    switch (enPath)
    {
        case OSD_DATAPATH_GRAPHIC:
        {
            HV_W32_FIELD(DISP_TOP_KOSD_TOP_34, regs_bmp_alpha, ucValue);
            break;
        }
        case OSD_DATAPATH_DDRREAD:
        {
            /* RGB565 or RGB888 */
#if (HV_OSD_CONFIG_DDR_FORMAT == 2 || HV_OSD_CONFIG_DDR_FORMAT == 5)
            HV_W32_FIELD(DISP_TOP_SUB_OSD_TOP_B0, regs_rdma_alpha, ucValue);
#endif
            break;
        }
        case OSD_DATAPATH_HSBLEND:
        {
            HV_W32_FIELD(DISP_TOP_SUB_OSD_TOP_70, reg_osd_alpha_force_value, ucValue);
            break;
        }
        default:
        {
            break;
        }
    }
}

VOID Hv_Cal_OsdFrame_SetUniversalAlphaMode(OsdDataPath enPath, OsdAlphaForceMode enMode)
{
    switch (enPath)
    {
        case OSD_DATAPATH_GRAPHIC:
        {
            HV_W32_FIELD(DISP_TOP_KOSD_TOP_3C, regs_force_alpha_mode, enMode);
            break;
        }
        case OSD_DATAPATH_DDRREAD:
        {
            HV_W32_FIELD(DISP_TOP_SUB_OSD_TOP_B8, regs_rdma_force_alpha_mode, enMode);
            break;
        }
        default:
        {
            break;
        }
    }
}

VOID Hv_Cal_OsdFrame_SetUniversalColorEnable(OsdDataPath enPath, BOOL bEnable)
{
    switch (enPath)
    {
        case OSD_DATAPATH_GRAPHIC:
        {
            HV_W32_FIELD(DISP_TOP_KOSD_TOP_3C, regs_force_color_en, bEnable);
            break;
        }
        case OSD_DATAPATH_DDRREAD:
        {
            HV_W32_FIELD(DISP_TOP_SUB_OSD_TOP_B8, regs_rdma_force_color_en, bEnable);
            break;
        }
        default:
        {
            break;
        }
    }
}

VOID Hv_Cal_OsdFrame_SetUniversalColor(OsdDataPath enPath, UINT32 uiColor)
{
    switch (enPath)
    {
        case OSD_DATAPATH_GRAPHIC:
        {
            HV_W32_FIELD(DISP_TOP_KOSD_TOP_34, regs_bmp_r, OSD_R(uiColor));
            HV_W32_FIELD(DISP_TOP_KOSD_TOP_34, regs_bmp_g, OSD_G(uiColor));
            HV_W32_FIELD(DISP_TOP_KOSD_TOP_34, regs_bmp_b, OSD_B(uiColor));
            break;
        }
        case OSD_DATAPATH_DDRREAD:
        {
            HV_W32_FIELD(DISP_TOP_SUB_OSD_TOP_B0, regs_rdma_r, OSD_R(uiColor));
            HV_W32_FIELD(DISP_TOP_SUB_OSD_TOP_B0, regs_rdma_g, OSD_G(uiColor));
            HV_W32_FIELD(DISP_TOP_SUB_OSD_TOP_B0, regs_rdma_b, OSD_B(uiColor));
            break;
        }
        default:
        {
            break;
        }
    }
}

VOID Hv_Cal_OsdFrame_Init(VOID)
{
    Hv_Cal_OsdFrame_DispOsdRst(1);
}
