//<MStar Software>
//******************************************************************************
// MStar Software
// Copyright (c) 2010 - 2012 MStar Semiconductor, Inc. All rights reserved.
// All software, firmware and related documentation herein ("MStar Software") are
// intellectual property of MStar Semiconductor, Inc. ("MStar") and protected by
// law, including, but not limited to, copyright law and international treaties.
// Any use, modification, reproduction, retransmission, or republication of all
// or part of MStar Software is expressly prohibited, unless prior written
// permission has been granted by MStar.
//
// By accessing, browsing and/or using MStar Software, you acknowledge that you
// have read, understood, and agree, to be bound by below terms ("Terms") and to
// comply with all applicable laws and regulations:
//
// 1. MStar shall retain any and all right, ownership and interest to MStar
//    Software and any modification/derivatives thereof.
//    No right, ownership, or interest to MStar Software and any
//    modification/derivatives thereof is transferred to you under Terms.
//
// 2. You understand that MStar Software might include, incorporate or be
//    supplied together with third party`s software and the use of MStar
//    Software may require additional licenses from third parties.
//    Therefore, you hereby agree it is your sole responsibility to separately
//    obtain any and all third party right and license necessary for your use of
//    such third party`s software.
//
// 3. MStar Software and any modification/derivatives thereof shall be deemed as
//    MStar`s confidential information and you agree to keep MStar`s
//    confidential information in strictest confidence and not disclose to any
//    third party.
//
// 4. MStar Software is provided on an "AS IS" basis without warranties of any
//    kind. Any warranties are hereby expressly disclaimed by MStar, including
//    without limitation, any warranties of merchantability, non-infringement of
//    intellectual property rights, fitness for a particular purpose, error free
//    and in conformity with any international standard.  You agree to waive any
//    claim against MStar for any loss, damage, cost or expense that you may
//    incur related to your use of MStar Software.
//    In no event shall MStar be liable for any direct, indirect, incidental or
//    consequential damages, including without limitation, lost of profit or
//    revenues, lost or damage of data, and unauthorized system use.
//    You agree that this Section 4 shall still apply without being affected
//    even if MStar Software has been modified by MStar in accordance with your
//    request or instruction for your use, except otherwise agreed by both
//    parties in writing.
//
// 5. If requested, MStar may from time to time provide technical supports or
//    services in relation with MStar Software to you for your use of
//    MStar Software in conjunction with your or your customer`s product
//    ("Services").
//    You understand and agree that, except otherwise agreed by both parties in
//    writing, Services are provided on an "AS IS" basis and the warranty
//    disclaimer set forth in Section 4 above shall apply.
//
// 6. Nothing contained herein shall be construed as by implication, estoppels
//    or otherwise:
//    (a) conferring any license or right to use MStar name, trademark, service
//        mark, symbol or any other identification;
//    (b) obligating MStar or any of its affiliates to furnish any person,
//        including without limitation, you and your customers, any assistance
//        of any kind whatsoever, or any information; or
//    (c) conferring any license or right under any intellectual property right.
//
// 7. These terms shall be governed by and construed in accordance with the laws
//    of Taiwan, R.O.C., excluding its conflict of law rules.
//    Any and all dispute arising out hereof or related hereto shall be finally
//    settled by arbitration referred to the Chinese Arbitration Association,
//    Taipei in accordance with the ROC Arbitration Law and the Arbitration
//    Rules of the Association by three (3) arbitrators appointed in accordance
//    with the said Rules.
//    The place of arbitration shall be in Taipei, Taiwan and the language shall
//    be English.
//    The arbitration award shall be final and binding to both parties.
//
//******************************************************************************
//<MStar Software>
////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2008-2009 MStar Semiconductor, Inc.
// All rights reserved.
//
// Unless otherwise stipulated in writing, any and all information contained
// herein regardless in any format shall remain the sole proprietary of
// MStar Semiconductor Inc. and be kept in strict confidence
// ("MStar Confidential Information") by the recipient.
// Any unauthorized act including without limitation unauthorized disclosure,
// copying, use, reproduction, sale, distribution, modification, disassembling,
// reverse engineering and compiling of the contents of MStar Confidential
// Information is unlawful and strictly prohibited. MStar hereby reserves the
// rights to any and all damages, losses, costs and expenses resulting therefrom.
//
////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////////////////////////
///
/// file    drvSYS.c
/// @brief  System Driver Interface
/// @author MStar Semiconductor Inc.
///////////////////////////////////////////////////////////////////////////////////////////////////


//-------------------------------------------------------------------------------------------------
//  Include Files
//-------------------------------------------------------------------------------------------------
#if defined (MSOS_TYPE_LINUX)
#include <errno.h>
#include <pthread.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#endif

#ifndef MSOS_TYPE_LINUX_KERNEL
#include <string.h>
#endif

#include "MsCommon.h"
#include "MsVersion.h"
#include "regCHIP.h"
#include "halCHIP.h"
#include "drvSYS.h"
#include "drvMMIO.h"
#include "halSYS.h"
#include "utopia_dapi.h"
#include "drvSYS_priv.h"
#include "utopia.h"
#include "label.h"
#include "drvMIU.h"
#include "drvMBX.h"
#include "apiMBX.h"
#include "drvBDMA.h"
#include "drvSEM.h"
#include "ULog.h"
#include "drvOPTEE_priv.h"
#include "drvIPAUTH.h"

//-------------------------------------------------------------------------------------------------
//  Driver Compiler Options
//-------------------------------------------------------------------------------------------------

//-------------------------------------------------------------------------------------------------
//  Local Defines
//-------------------------------------------------------------------------------------------------
#define TAG_SYS                     "SYS"

//-------------------------------------------------------------------------------------------------
//  Local Structurs
//-------------------------------------------------------------------------------------------------

//-------------------------------------------------------------------------------------------------
//  Global Variables
//-------------------------------------------------------------------------------------------------
MS_U8                               _u8SysDbgLevel = E_SYS_DBGLV_ERR_ONLY;

//-------------------------------------------------------------------------------------------------
//  Local Variables
//-------------------------------------------------------------------------------------------------
static MS_BOOL                      _bSysInit = FALSE;
static MS_BOOL                      _bGlobalInit = FALSE;
static MS_S32                       _s32GlobalMutexId = -1;

static void                         *pInstantSys = NULL;
static void                         *pAttributeSys = NULL;

//-------------------------------------------------------------------------------------------------
//  Debug Functions
//-------------------------------------------------------------------------------------------------
#define SYS_DBG_FUNC()              if (_u8SysDbgLevel >= E_SYS_DBGLV_ALL) \
                                        {MS_DEBUG_MSG(ULOGD(TAG_SYS, "\t====   %s   ====\n", __FUNCTION__));}
#define SYS_DBG_INFO(x, args...)    if (_u8SysDbgLevel >= E_SYS_DBGLV_INFO ) \
                                        {MS_DEBUG_MSG(ULOGI(TAG_SYS, x, ##args));}
#define SYS_DBG_ERR(x, args...)     if (_u8SysDbgLevel >= E_SYS_DBGLV_ERR_ONLY) \
                                        {MS_DEBUG_MSG(ULOGE(TAG_SYS, x, ##args));}

//-------------------------------------------------------------------------------------------------
//  Local Functions
//-------------------------------------------------------------------------------------------------
void __attribute__((weak)) HAL_SYS_SetExtRIUBase(MS_VIRT virtBase)
{
    return;
}

//-------------------------------------------------------------------------------------------------
//  Global Functions
//-------------------------------------------------------------------------------------------------

//-------------------------------------------------------------------------------------------------
// SYS Init
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
/// System initialzation
/// @return TRUE(Success), FALSE(Failure)
//-------------------------------------------------------------------------------------------------
MS_BOOL MDrv_SYS_Init(void)
{
    MS_VIRT virtAddr = 0;
    MS_PHY phySize = 0;

    /* Check init. */
    if (_bSysInit == TRUE)
    {
        SYS_DBG_INFO("[%s][%d] Already inited.\n", __FUNCTION__, __LINE__);
        return TRUE;
    }

    /* Init function. */
    if (UtopiaOpen(MODULE_SYS, &pInstantSys, 0, pAttributeSys) != UTOPIA_STATUS_SUCCESS)
    {
        SYS_DBG_ERR("[%s][%d] Open SYS fail.\n", __FUNCTION__, __LINE__);
        return FALSE;
    }

    /* Init sys base. */
    if (MDrv_MMIO_GetBASE(&virtAddr, &phySize, MS_MODULE_PM) == FALSE)
    {
        SYS_DBG_ERR("[%s][%d] Get IOMAP Base fail.\n", __FUNCTION__, __LINE__);
        return FALSE;
    }
    SYS_Init(virtAddr);

    if (MDrv_MMIO_GetBASE(&virtAddr, &phySize, MS_MODULE_EXTRIU) == TRUE)
    {
        HAL_SYS_SetExtRIUBase(virtAddr);
    }

    /* Init for efuse usage. */
    if (MDrv_MMIO_GetBASE(&virtAddr, &phySize, MS_MODULE_EFUSE) == TRUE)
    {
        HAL_SYS_SetEfuseIOMapBase(virtAddr);
    }
    /* Init for OTP. */
    if (MDrv_MMIO_GetBASE(&virtAddr, &phySize, MS_MODULE_OTP2) == TRUE)
    {
        HAL_SYS_SetOtpIOMapBase(virtAddr);
    }

    /* Init done. */
    _bSysInit = TRUE;

    return TRUE;
}

MS_BOOL MDrv_SYS_GlobalInit(void)
{
    MS_BOOL bRet = TRUE;

    /* First init. */
    if (MsOS_Init() == FALSE)
    {
        return FALSE;
    }

    /* Create mutex. */
    if ((_s32GlobalMutexId == -1) &&
        ((_s32GlobalMutexId = MsOS_CreateMutex(E_MSOS_FIFO, "MDrv_SYS_GlobalInit", MSOS_PROCESS_PRIVATE)) < 0))
    {
        return FALSE;
    }

    MsOS_ObtainMutex(_s32GlobalMutexId, MSOS_WAIT_FOREVER);
    /* Check init. */
    if (_bGlobalInit == TRUE)
    {
        SYS_DBG_INFO("[%s][%d] Already inited.\n", __FUNCTION__, __LINE__);
        goto MDrv_SYS_GlobalInit_End;
    }

    /* Init. */
    if (!MDrv_MMIO_Init()   || !MsOS_MPool_Init()  ||
        !MDrv_SEM_Init()    || !MDrv_MIU_Init()    ||
        !MDrv_SYS_Init())
    {
        bRet = FALSE;
        goto MDrv_SYS_GlobalInit_End;
    }

#if defined(ANDROID)
    MApi_MBX_Init(E_MBX_CPU_MIPS, E_MBX_ROLE_HK, 5000);
    MApi_MBX_Enable(TRUE);
#endif

    /* Init done. */
    _bGlobalInit = TRUE;

MDrv_SYS_GlobalInit_End:
    MsOS_ReleaseMutex(_s32GlobalMutexId);
    return bRet;
}

//-------------------------------------------------------------------------------------------------
// DEBUG
//-------------------------------------------------------------------------------------------------
MS_BOOL MDrv_SYS_DisableDebugPort(void)
{
    return HAL_SYS_DisableDebugPort();
}

MS_BOOL MDrv_SYS_EnableDebugPort(void)
{
    return HAL_SYS_EnableDebugPort();
}

//-------------------------------------------------------------------------------------------------
/// @brief \b Function  \b Name: MDrv_SYS_SetDbgLevel
/// @brief \b Function  \b Description: Set debug level for debug message
/// @param eLevel       \b IN: E_SYS_DBGLV_NONE/E_SYS_DBGLV_ERR_ONLY/E_SYS_DBGLV_INFO/E_SYS_DBGLV_ALL
/// @return             \b SYS_Result
//-------------------------------------------------------------------------------------------------
void MDrv_SYS_SetDbgLevel(SYS_DbgLv eLevel)
{
    _u8SysDbgLevel = eLevel;
}

//-------------------------------------------------------------------------------------------------
//  INFO
//-------------------------------------------------------------------------------------------------

//-------------------------------------------------------------------------------------------------
// CHIP TYPE
//-------------------------------------------------------------------------------------------------

//-------------------------------------------------------------------------------------------------
// RESET
//-------------------------------------------------------------------------------------------------

//-------------------------------------------------------------------------------------------------
// TEE INFO
//-------------------------------------------------------------------------------------------------

//-------------------------------------------------------------------------------------------------
// TEEC
//-------------------------------------------------------------------------------------------------

//-------------------------------------------------------------------------------------------------
// PAD MUTEX TABLE
//-------------------------------------------------------------------------------------------------
MS_BOOL MDrv_SYS_SetPadMux(SYS_PAD_MUX_SET ePadMuxType,SYS_PAD_SEL ePadSel)
{
    MS_BOOL ret = FALSE;
    if((ePadMuxType >= E_PAD_SET_MAX) || (ePadSel >= E_PAD_SEL_MAX))
        return ret;
    ret = HAL_SYS_SetPadMux(ePadMuxType,ePadSel);
    return ret;
}

MS_BOOL MDrv_SYS_PadMuxTableSuspend(void)
{
    return HAL_SYS_PadMuxTableSuspend();
}

MS_BOOL MDrv_SYS_PadMuxTableResume(void)
{
    return HAL_SYS_PadMuxTableResume();
}

//-------------------------------------------------------------------------------------------------
// WDT
//-------------------------------------------------------------------------------------------------

//-------------------------------------------------------------------------------------------------
// TS CLOCK
//-------------------------------------------------------------------------------------------------
MS_BOOL MDrv_SYS_SetTSOutClockPhase(MS_U16 u16Val)
{
    return HAL_SYS_SetTSOutClockPhase(u16Val);
}

MS_BOOL MDrv_SYS_SetTSClockPhase(SYS_PAD_MUX_SET ePadMuxType, MS_U16 u16Val)
{
    return HAL_SYS_SetTSClockPhase(ePadMuxType, u16Val);
}

//-------------------------------------------------------------------------------------------------
// DOLBY
//-------------------------------------------------------------------------------------------------

//-------------------------------------------------------------------------------------------------
// BRICK TERMINATOR
//-------------------------------------------------------------------------------------------------

//-------------------------------------------------------------------------------------------------
// EFUSE
//-------------------------------------------------------------------------------------------------

//-------------------------------------------------------------------------------------------------
// OTHER
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
/// Set RFAGC and TAGC PAD MUX
/// @return None
//-------------------------------------------------------------------------------------------------
void  MDrv_SYS_SetAGCPadMux(SYS_AGC_PAD_SET eAgcPadMux)
{
    HAL_SYS_SetAGCPadMux(eAgcPadMux);
}

MS_BOOL MDrv_SYS_SetPCMCardDetectMode(SYS_PCM_CD_MODE ePCMCDMode)
{
    MS_BOOL ret = FALSE;

    if(ePCMCDMode >= E_PCM_CD_MAX)
        return ret;
    ret = HAL_SYS_SetPCMCardDetectMode(ePCMCDMode);
    return ret;
}

MS_BOOL MDrv_SYS_PackMode(void)
{
#ifdef CONFIG_UTOPIA_FRAMEWORK_KERNEL_DRIVER_STRUCT_PACKED
    return TRUE;
#else
    return FALSE;
#endif
}

/* From /mstar2/drv/system/mdrv_system_io.c */
extern int _mod_sys_get_dts_value(char* node, char* key, char* value, unsigned int size);
//-------------------------------------------------------------------------------------------------
/// Query device key-value via DTS.
/// @ingroup G_SYS_COMMON
/// @param pu8Node      \b IN: Deviece node
/// @param pu8Key       \b IN: Key word
/// @param pu8Value     \b OUT: Result
/// @param u32BufferSize \b IN: Buffer length
/// @return >= 0 : Success
/// @return <  0 : Fail
//-------------------------------------------------------------------------------------------------
MS_S32 MDrv_Sys_GetDTSValue(MS_U8* pu8Node, MS_U8* pu8Key, MS_U8* pu8Value, MS_U32 u32BufferSize)
{
#if defined(MSOS_TYPE_LINUX_KERNEL)
    return _mod_sys_get_dts_value((char *)pu8Node, (char *)pu8Key, (char *)pu8Value, u32BufferSize);
#else
    return -1;
#endif
}
