/* SPDX-License-Identifier: LGPL-2.1-only OR BSD-3-Clause */
/******************************************************************************
 *
 * This file is provided under a dual license.  When you use or
 * distribute this software, you may choose to be licensed under
 * version 2.1 of the GNU Lesser General Public License
 * ("LGPLv2.1 License") or BSD License.
 *
 * LGPLv2.1 License
 *
 * Copyright(C) 2019 MediaTek Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2.1 of the GNU Lesser General Public
 * License as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html for more
 * details.
 *
 * BSD LICENSE
 *
 * Copyright(C) 2019 MediaTek Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name of the copyright holder nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *****************************************************************************/

/*-----------------------------------------------------------------------------
 *
 * Description:
 *
 *---------------------------------------------------------------------------*/

#ifndef X_HAL_5381_H
#define X_HAL_5381_H

#include "x_typedef.h"
#include "x_hal_io.h"
#include "x_hal_reg.h"

//===========================================================================
// Constant definitions

#define MEMORY_ALIGNMENT            8

//===========================================================================
// Macros for register read
#define IO_READ8(base, offset)      HAL_READ8((base) + (offset))
#define IO_READ16(base, offset)     HAL_READ16((base) + (offset))
#define IO_READ32(base, offset)     HAL_READ32((base) + (offset))
#define IO_READ32MSK(base, offset, msk) \
            ((UINT32)HAL_READ32((base) + (offset)) & (UINT32)(msk))
#define IO_READ32MSK_BOOL(base, offset, msk) \
            ((IO_READ32MSK((base), (offset), (msk)) > 0)?TRUE:FALSE)

//===========================================================================
// Macros for register write
#define _dsb()  \
        do {    \
            __asm__ __volatile__ ("dsb sy" : : : "memory"); \
        } while (0)

#define IO_WRITE8(base, offset, value)  do { HAL_WRITE8((base) + (offset), (value)); _dsb(); } while(0)
#define IO_WRITE16(base, offset, value) do { HAL_WRITE16((base) + (offset), (value)); _dsb(); } while(0)
#define IO_WRITE32(base, offset, value) do { HAL_WRITE32((base) + (offset), (value)); _dsb(); } while(0)

#define IO_WRITE32MSK(base, offset, value, msk) \
            IO_WRITE32((base), (offset), \
            (IO_READ32((base), (offset)) & ~(msk)) | ((value) & (msk)))

#define IO_WRITE32_CLEAR(base, offset, set_bit) \
            IO_WRITE32((base), (offset), \
            (IO_READ32((base), (offset)) & ~(1U << set_bit)))

#define IO_WRITE32_SET(base, offset, set_bit) \
            IO_WRITE32((base), (offset), \
            (IO_READ32((base), (offset)) | (1U << set_bit)))

//===========================================================================
// Macros for register read/write access

#define IO_REG8(base, offset)       HAL_REG8((base) + (offset))
#define IO_REG16(base, offset)      HAL_REG16((base) + (offset))
#define IO_REG32(base, offset)      HAL_REG32((base) + (offset))

#define IO_ADDR(base)               (IO_VIRT + base)

//===========================================================================
// Macros for address translation

#ifndef __KERNEL__
#if defined(CC_MT5396) || defined(CC_MT5368) || defined(CC_MT5398)||defined(CC_MT5399) ||defined(CC_MT5880)||defined(CC_MT5881)
#define CACHE(addr)                                   ((addr) & 0x7fffffff)
#define NONCACHE(addr)                                (CACHE(addr) | 0x80000000)
#elif defined(CC_MT5395) || defined(CC_MT5365)
#define CACHE(addr)                                   ((addr) & 0x3fffffff)
#define NONCACHE(addr)                                (CACHE(addr) | 0x40000000)
#elif defined(CC_MT5890) || defined(CC_MT5891)
#define CACHE(addr)                                   (addr < 0xA0000000)?addr:(addr - 0xA0000000)
#define NONCACHE(addr)                                (addr >= 0xA0000000)?addr:(addr + 0xA0000000)
#else
#define CACHE(addr)                                   ((addr) & 0x0fffffff)
#if defined(CC_MT5363)
#define NONCACHE(addr)                            (CACHE(addr) | 0x60000000)
#else
#define NONCACHE(addr)                            (CACHE(addr) | 0x30000000)
#endif
#endif
#endif // __KERNEL__

#ifdef __KERNEL__
#ifdef CC_UBOOT
#define PHYSICAL(addr)              (addr)
#define VIRTUAL(addr)               (addr)
#else
extern UPTR VIRTUAL(UPTR);
extern UPTR PHYSICAL(UPTR);
#endif
#else
#define PHYSICAL(addr)              (addr)
#define VIRTUAL(addr)               (addr)
#endif



//===========================================================================
// Type definitions

#define IC_VER_FPGA         0x00000000U         // FPGA

#define IS_IC_5389()        ((BSP_GetIcVersion() & 0xffff0000U)==0x53890000U)
#define IS_IC_5368()        ((BSP_GetIcVersion() & 0xffff0000U)==0x53680000U)
#define IS_IC_5396()        ((BSP_GetIcVersion() & 0xffff0000U)==0x53960000U)
#define IS_IC_5398()        ((BSP_GetIcVersion() & 0xffff0000U)==0x53980000U)
#define IS_IC_5399()        ((BSP_GetIcVersion() & 0xffff0000U)==0x53990000U)
#define IS_IC_5395()        ((BSP_GetIcVersion() & 0xffff0000U)==0x53950000U)
#define IS_IC_5365()        ((BSP_GetIcVersion() & 0xffff0000U)==0x53650000U)
#define IS_IC_5363()        ((BSP_GetIcVersion() & 0xffff0000U)==0x53630000U)
#define IS_IC_5387()        ((BSP_GetIcVersion() & 0xffff0000U)==0x53870000U)
#define IS_IC_5880()        ((BSP_GetIcVersion() & 0xffff0000U)==0x58800000U)
#define IS_IC_5860()        ((BSP_GetIcVersion() & 0xffff0000U)==0x58600000U)
#define IS_IC_5861()        ((BSP_GetIcVersion() & 0xffff0000U)==0x58610000U)
#define IS_IC_5890()        ((BSP_GetIcVersion() & 0xffff0000U)==0x58900000U)
#define IS_IC_5891()        ((BSP_GetIcVersion() & 0xffff0000U)==0x58910000U)
#define IS_IC_5893()        ((BSP_GetIcVersion() & 0xffff0000U)==0x58930000U)
#define IS_IC_5887()        ((BSP_GetIcVersion() & 0xffff0000U)==0x58870000U)
#define IS_IC_5895()        ((BSP_GetIcVersion() & 0xffff0000U)==0x58950000U)

#define IC_VER_5363_AA      0x53630000         // 5363 AA
#define IC_VER_5363_AB      0x53630001         // 5363 AB

#define IC_VER_5387_AA      0x53870000         // 5387 AA
#define IC_VER_5387_AB      0x53870001         // 5387 AB

#define IC_VER_5365_AA      0x53650000         // 5365 AA
#define IC_VER_5365_AB      0x53650001         // 5365 AB
#define IC_VER_5365_AC      0x53650002         // 5365 AC

#define IC_VER_5395_AA      0x53950000         // 5395 AA
#define IC_VER_5395_AB      0x53950001         // 5395 AB
#define IC_VER_5395_AC      0x53950002         // 5395 AC

#define IC_VER_5389_AA      0x53890000         // 5389 AA
#define IC_VER_5389_AB      0x53890001         // 5389 AB
#define IC_VER_5389_AC      0x53890002         // 5389 AC

#define IC_VER_5368_AA      0x53680000         // 5368 AA
#define IC_VER_5368_AB      0x53680001         // 5368 AB
#define IC_VER_5368_AC      0x53680002         // 5368 AC

#define IC_VER_5396_AA      0x53960000         // 5396 AA
#define IC_VER_5396_AB      0x53960001         // 5396 AB
#define IC_VER_5396_AC      0x53960002         // 5396 AC

#define IC_VER_5398_AA      0x53980000         // 5398 AA
#define IC_VER_5398_AB      0x53980001         // 5398 AB
#define IC_VER_5398_AC      0x53980002         // 5398 AC

#define IC_VER_5399_AA      0x53990001         // 5399 AA
#define IC_VER_5399_AB      0x53990002         // 5399 AB
#define IC_VER_5399_AC      0x53990003         // 5399 AC

#define IC_VER_5890_AA      0x58900001         // 5890 AA
#define IC_VER_5890_AB      0x58900002         // 5890 AB
#define IC_VER_5890_AC      0x58900003         // 5890 AC
#define IC_VER_5890_AD      0x58900004         // 5890 AD

#define IC_VER_5891_AA      0x58910001         // 5891 AA
#define IC_VER_5891_AB      0x58910002         // 5891 AB
#define IC_VER_5891_AC      0x58910003         // 5891 AC
#define IC_VER_5891_AD      0x58910004         // 5891 AD

#define IC_VER_5861_AA      0x58610001         // 5861 AA
#define IC_VER_5861_AB      0x58610002         // 5861 AB
#define IC_VER_5861_AC      0x58610003         // 5861 AC
#define IC_VER_5861_AD      0x58610004         // 5861 AD

#define IC_VER_5360_AA      0x62360AA0U         // 5360 AA
#define IC_VER_5360_AB      0x62360AB0U         // 5360 AB
#define IC_VER_5360_AC      0x62360AC0U         // 5360 AC
#define IC_VER_5360_AD      0x62360AD0U         // 5360 AD
#define IC_VER_5360_AE      0x62360AE0U         // 5360 AE
#define IC_VER_5360_AF      0x62360AF0U         // 5360 AF
#define IC_VER_5360_BA      0x62360BA0U         // 5360 BA
#define IC_VER_5360_BB      0x62360BB0U         // 5360 BB
#define IC_VER_5360_BC      0x62360BC0U         // 5360 BC
#define IC_VER_5360_BD      0x62360BD0U         // 5360 BD
#define IC_VER_5360_CA      0x62360CA0U         // 5360 CA
#define IC_VER_5360_CB      0x62360CB0U         // 5360 CB
#define IC_VER_5360_CC      0x62360CC0U         // 5360 CC

#define IC_VER_5391_AA      0x62391AA0U         // 5391 AA
#define IC_VER_5391_AB      0x62391AB0U         // 5391 AB
#define IC_VER_5391_AC      0x62391AC0U         // 5391 AC
#define IC_VER_5391_AD      0x62391AD0U         // 5391 AD
#define IC_VER_5391_AE      0x62391AE0U         // 5391 AE
#define IC_VER_5391_AF      0x62391AF0U         // 5391 AF
#define IC_VER_5391_BA      0x62391BA0U         // 5391 BA
#define IC_VER_5391_BB      0x62391BB0U         // 5391 BB
#define IC_VER_5391_BC      0x62391BC0U         // 5391 BC
#define IC_VER_5391_CA      0x62391CA0U         // 5391 CA
#define IC_VER_5391_CB      0x62391CB0U         // 5391 CB
#define IC_VER_5391_CC      0x62391CC0U         // 5391 CC

#define IC_VER_5392B_AA     0x53930000U         // 5392B - 2008.09.05
#define IC_VER_5392B        0x53930000U         // 5392B - 2008.09.05
#define IC_VER_5392B_E1     0x53930001U         // 5392B 1st ECO - 2008.10.22
#define IC_VER_5392B_E2     0x53930002U         // 5392B 2nd ECO
#define IC_VER_5392B_E3     0x53930003U         // 5392B 3rd ECO
#define IC_VER_5392B_E4     0x53930004U         // 5392B 4th ECO
#define IC_VER_5392B_E5     0x53930005U         // 5392B 5th ECO
#define IC_VER_5392B_E6     0x53930006U         // 5392B 6th ECO
#define IC_VER_5392B_E7     0x53930007U         // 5392B 7th ECO

#define IC_VER_5880_AA      0x58800000         // 5880 AA
#define IC_VER_5880_AB      0x58800001         // 5880 AB
#define IC_VER_5880_AC      0x58800002         // 5880 AC

#define IC_VER_5860_AA      0x58600000         // 5880 AA
#define IC_VER_5860_AB      0x58600001         // 5880 AB
#define IC_VER_5860_AC      0x58600002         // 5880 AC

#define IC_VER_5886_AA      0x58860001         // 5886 AA
#define IC_VER_5886_AB      0x58860002         // 5886 AB
#define IC_VER_5886_AC      0x58860003         // 5886 AC

#define IC_VER_5893_AA      0x58930001         // 5893 AA
#define IC_VER_5893_AB      0x58930002         // 5893 AB
#define IC_VER_5893_AC      0x58930003         // 5893 AC
#define IC_VER_5893_AD      0x58930004         // 5893 AD
#define IC_VER_5887_AA      0x58870001         // 5887 AA
#define IC_VER_5887_AB      0x58870002         // 5887 AB
#define IC_VER_5887_AC      0x58870003         // 5887 AC
#define IC_VER_5887_AD      0x58870004         // 5887 AD

#define IC_VER_5895_AA      0x58950001         // 5895 AA
#define IC_VER_5895_AB      0x58950002         // 5895 AB
#define IC_VER_5895_AC      0x58950003         // 5895 AC
#define IC_VER_5895_AD      0x58950004         // 5895 AD

#define IC_VER_UNKNOWN      0xffffffffU         // Unknown version

#define IS_IC_5399_ES1()    ((BSP_GetIcVersion() == IC_VER_5399_AA))
#define IS_IC_5399_ES2()    ((BSP_GetIcVersion() == IC_VER_5399_AB))

#define IS_IC_5890_ES1()    ((BSP_GetIcVersion() == IC_VER_5890_AA))
#define IS_IC_5890_MPS1()   ((BSP_GetIcVersion() == IC_VER_5890_AB))
#define IS_IC_5890_ES3()    ((BSP_GetIcVersion() == IC_VER_5890_AC))
#define IS_IC_5890_ES4()    ((BSP_GetIcVersion() == IC_VER_5890_AD))

#define IS_IC_5891_ES1()    ((BSP_GetIcVersion() == IC_VER_5891_AA))
#define IS_IC_5891_ES2()    ((BSP_GetIcVersion() == IC_VER_5891_AB))
#define IS_IC_5891_ES3()    ((BSP_GetIcVersion() == IC_VER_5891_AC))
#define IS_IC_5891_ES4()    ((BSP_GetIcVersion() == IC_VER_5891_AD))

//For DRAM PCB Config
#define IS_IC_5891_BI()     (IS_DRAM_CHANNELC_SUPPORT() == 1)
#define IS_IC_5891_SM()     (IS_DRAM_CHANNELC_SUPPORT() == 0)
#define IS_IC_5891_SM_M1()  (TCMGET_DRAM_PCB_CFG() == DRAM_PCB_5891_SM_M1 )
#define IS_IC_5891_SM_M2()  (TCMGET_DRAM_PCB_CFG() == DRAM_PCB_5891_SM_M2 )

#define IS_IC_5861_ES1()    ((BSP_GetIcVersion() == IC_VER_5861_AA))
#define IS_IC_5861_ES2()    ((BSP_GetIcVersion() == IC_VER_5861_AB))

#define IS_IC_5886_ES1()    ((BSP_GetIcVersion() == IC_VER_5886_AA))
#define IS_IC_5886_ES2()    ((BSP_GetIcVersion() == IC_VER_5886_AB))


#define IS_IC_5893_ES1()    ((BSP_GetIcVersion() == IC_VER_5893_AA))
#define IS_IC_5893_ES2()    ((BSP_GetIcVersion() == IC_VER_5893_AB))
#define IS_IC_5893_ES3()    ((BSP_GetIcVersion() == IC_VER_5893_AC))
#define IS_IC_5893_ES4()    ((BSP_GetIcVersion() == IC_VER_5893_AD))

#define IS_IC_5887_ES1()    ((BSP_GetIcVersion() == IC_VER_5887_AA))
#define IS_IC_5887_ES2()    ((BSP_GetIcVersion() == IC_VER_5887_AB))
#define IS_IC_5887_ES3()    ((BSP_GetIcVersion() == IC_VER_5887_AC))
#define IS_IC_5887_ES4()    ((BSP_GetIcVersion() == IC_VER_5887_AD))
#define IS_IC_5887_L()        (IS_IC_5887() &&  SUPPORT_SYSTEM(SYSTEM_IC_PACKAGE_LARGE))

#define IS_IC_5895_ES1()    ((BSP_GetIcVersion() == IC_VER_5895_AA))
#define IS_IC_5895_ES2()    ((BSP_GetIcVersion() == IC_VER_5895_AB))
#define IS_IC_5895_ES3()    ((BSP_GetIcVersion() == IC_VER_5895_AC))
#define IS_IC_5895_ES4()    ((BSP_GetIcVersion() == IC_VER_5895_AD))

typedef UINT32 IC_VERSION_T;

//===========================================================================
// Exported functions

EXTERN void* BSP_AllocateReserved(UINT32 u4Size);
EXTERN void* BSP_AllocateReservedAlign(UINT32 u4Size, UINT32 u4Align);
EXTERN void BSP_FreeReserved(void* p);
EXTERN void* BSP_MapReservedMem(void *pv_Phys, UINT32 z_Size);
#ifdef CC_FBM_MAPPING_ONE_BY_ONE
void BSP_UnMapReservedMem(void *pv_Virt);
#endif

#ifdef CONFIG_TV_DRV_VFY
EXTERN UPTR BSP_AllocVfyReserveMemory(UINT32 u4Ch, UINT32 u4Size, UINT32 u4Align);
EXTERN void BSP_FreeVfyReserveMemory(UPTR pv_Virt);
#endif
EXTERN BOOL BSP_IsFPGA(void);
EXTERN UINT32 BSP_GetSystemClock(void);
EXTERN void BSP_HaltSystem(void);
EXTERN UPTR BSP_AllocDmaMemory(UPTR u4Size);
EXTERN BOOL BSP_FreeDmaMemory(UPTR uAddr);
EXTERN UPTR BSP_AllocAlignedDmaMemory(UPTR u4Size, UPTR u4Align);
EXTERN BOOL BSP_FreeAlignedDmaMemory(UPTR uAddr);
EXTERN IC_VERSION_T BSP_GetIcVersion(void);
EXTERN UINT32 BSP_IsSystemAcOn(void);
EXTERN UINT32 BSP_GetFbmMemAddr(void);
EXTERN UINT32 BSP_QuerySetAbortRebootFlag(UINT32 *pu4Flag);
EXTERN UINT32 BSP_GetChBMemSize(void);
EXTERN UINT32 BSP_GetChCMemSize(void);

EXTERN UINT32 BSP_GetMemSize(void);
EXTERN UINT32 BSP_GetPanelTableOffset(void);
EXTERN UINT32 BSP_GetPQDataOffset(void);
EXTERN UINT32 BSP_GetPQSmartPicOffset(void);
EXTERN UINT32 BSP_GetAQDataOffset(void);

#ifdef __MODEL_slt__
EXTERN void _DymanicMapChannelBFBM_Pools(void);
#endif

/// Dump system task state.
EXTERN void BspDumpSystemTasksState(void);

#endif  // X_HAL_5381_H
