/**
 * @file hv_drv_OsdMemory.h
 * @brief Osd driver layer memory interface.
 * @verbatim
 * ==============================================================================
 *                        ##### How to use this driver #####
 * ==============================================================================
 * (+) Use Hv_Drv_OsdIndex_TransferIndex(...) to transfer index change to OSD SRAM.
 * @endverbatim
 *
 * @author HiView SoC Software Team
 * @version 0.0.1
 * @date 2022-08-22
 */

#ifndef _HV_DRV_OSDMEMORY_H
#define _HV_DRV_OSDMEMORY_H

#if (HV_PROJECT_CONFIG_OSD_DDRPATH == HV_CONFIG_ON)

#define OSD_BUFFER_SIZE (Hv_Board_Memory_CalculateOsdBlendSize() / 2)
#define OSD_DRAW_BUFFER0_START HV_MEMORY_CONFIG_OSD_BLEND_DDR_START
#define OSD_DRAW_BUFFER1_START (OSD_DRAW_BUFFER0_START + OSD_BUFFER_SIZE)

#endif

/*
 * Allocation of osd ddr address space (1M)
 *
 * !!! change of this map must sync with hv_chip_Memory.h
 *
 * ------------------------     <- HV_MEMORY_CONFIG_OSD_DDR_START
 *  Middle ware structures      <- 64KB reserved. first 16KB used for jpg decompress
 * ------------------------
 *  Driver data structures      <- 32KB
 * ------------------------
 *  Palette data                <- 8KB
 * ------------------------
 *  Index data                  <- 16KB
 * ------------------------
 *  Resource data               <- 64KB
 * ------------------------     <- HV_MEMORY_CONFIG_OSD_DMA_DDR_START
 *  Logo data
 * ------------------------     <- 1M end
 */
#define OSD_MIDDLEWARE_DDR_START HV_MEMORY_CONFIG_OSD_DDR_START
#define OSD_MIDDLEWARE_DDR_SIZE (64 * 1024)

#define OSD_TJPG_POOL_START HV_MEMORY_CONFIG_OSD_DDR_START
#define OSD_TJPG_POOL_SIZE (16 * 1024)

#define OSD_DRIVER_DDR_START (OSD_MIDDLEWARE_DDR_START + OSD_MIDDLEWARE_DDR_SIZE)
#define OSD_DRIVER_DDR_SIZE (32 * 1024)
#define OSD_DRIVER_DDR_END (OSD_DRIVER_DDR_START + OSD_DRIVER_DDR_SIZE)

#define OSD_PALETTE_DDR_START (OSD_DRIVER_DDR_END)
#define OSD_PALETTE_DDR_SIZE (8 * 1024)

#define OSD_INDEX_DDR_START (OSD_PALETTE_DDR_START + OSD_PALETTE_DDR_SIZE)
#define OSD_INDEX_DDR_SIZE (16 * 1024)

#define OSD_RESOURCE_DDR_START (OSD_INDEX_DDR_START + OSD_INDEX_DDR_SIZE)
#define OSD_RESOURCE_DDR_SIZE (64 * 1024)
#define OSD_RESOURCE_DDR_ADDR(offset) ((VOID*)(OSD_RESOURCE_DDR_START + (offset)))

#define OSD_LOGO_DDR_START (HV_MEMORY_CONFIG_OSD_LOGO_DDR_START)


extern UINT32 g_uiOsdDriverDDRPos;
extern UINT32 g_uiOsdDriverDDRPosReserved;
#define OSD_DRIVER_ALLOC_STATIC(type, count) (                              \
        {                                                                   \
            UINT32 __tmp = ALIGN(g_uiOsdDriverDDRPos, 4);                   \
            USHORT16 __size_need = (count) * (sizeof(type));                \
            if ((__tmp + __size_need) >= OSD_DRIVER_DDR_END)                \
            {                                                               \
                OSD_DRV_LOG_ERROR("Osd fatal error: not enough space");     \
            }                                                               \
            g_uiOsdDriverDDRPos = __tmp + __size_need;                      \
            __tmp;                                                          \
        })

#define OSD_DRIVER_FREE_STATIC(size)                                        \
        {                                                                   \
            g_uiOsdDriverDDRPos -= (size);                                  \
        }

#define OSD_DRIVER_MEMORY_PRESERVE()                                        \
        g_uiOsdDriverDDRPosReserved = g_uiOsdDriverDDRPos

#define OSD_DRIVER_MEMORY_RESTORE()                                         \
        g_uiOsdDriverDDRPos = g_uiOsdDriverDDRPosReserved

#define OSD_DRIVER_LOG_STATIC_MEMORY_USAGE()                                \
        OSD_DRV_LOG_DEBUG("Osd driver static memory usage: 0x%x",           \
                g_uiOsdDriverDDRPos - OSD_DRIVER_DDR_START)

/**
 * @brief set DDR change Area
 * @param[in/out] pstChange current change info
 * @param[in] enType change type OSD_SRAM_CHANGE_NONE: area clean
 *                               OSD_SRAM_CHANGE_PARTIAL: partial area dirty
 *                               OSD_SRAM_CHANGE_FULL: whole area dirty
 * @param[in] uiChangeStart start position of this change
 * @param[in] uiChangeEnd end position of this change
 * @return VOID without return
 */

VOID Hv_Drv_OsdMemory_SetSRAMChange(OsdSRAMChange *pstChange, OsdSRAMChangeType enType,
                                UINT32 uiChangeStart, UINT32 uiChangeEnd);
/**
 * @brief reset DDR Memory allocate start pos
 * @param[in] None
 * @return VOID without return
 */
VOID Hv_Drv_OsdMemory_Init(VOID);

#endif
