//<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>

//-------------------------------------------------------------------------------------------------
//  Include Files
//-------------------------------------------------------------------------------------------------
#include "MsCommon.h"
#include "MsTypes.h"
#include "drvMIU.h"
#include "drvMIU_private.h"
#include "regMIU.h"
#include "halMIU.h"
#include "halCHIP.h"
#include "utopia_dapi.h"
#include "utopia.h"

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


//-------------------------------------------------------------------------------------------------
//  Local Defines
//-------------------------------------------------------------------------------------------------
#define HAL_MIU_SSC_DBG(x)          //x

#define KHz                         (1000UL)
#define MHz                         (1000000UL)
#define MPPL                        (432)
#define MPLL_T                      (2.31)
#define DDR_FACTOR                  (524288)
#define DDFSPAN_FACTOR              (131072)
#define IDNUM_KERNELPROTECT         (12)

//-------------------------------------------------------------------------------------------------
//  Local Structures
//-------------------------------------------------------------------------------------------------
const MS_U32 clientTbl[MIU_MAX_DEVICE][MIU_CLIENT_MAX_NUMBER] =
{
    { MIU_CLIENT }
};

MS_U32 clientId_KernelProtect[IDNUM_KERNELPROTECT] =
{
    MIU_KERNEL_PROTECT_WHITE_LIST
};
//-------------------------------------------------------------------------------------------------
//  Global Variables
//-------------------------------------------------------------------------------------------------
static MS_U32 u32CPUClient[] =
{
    MIU_BW_CPU_HW_CLIENT
};
static MS_U32 u32GPUClient[] =
{
    MIU_BW_GPU_HW_CLIENT
};
static MS_U32 u32XCClient[] =
{
    MIU_BW_XC_HW_CLIENT
};
static MS_U32 u32MVOPClient[] =
{
    MIU_BW_MVOP_HW_CLIENT
};
static MS_U32 u32MEMCClient[] =
{
    MIU_BW_MEMC_HW_CLIENT
};
static MS_U32 u32GOPClient[] =
{
    MIU_BW_GOP_HW_CLIENT
};
static MS_U32 u32ODClient[] =
{
    MIU_BW_OD_HW_CLIENT
};
static MS_U32 u32HDRClient[] =
{
    MIU_BW_HDR_HW_CLIENT
};
static MS_U32 u32AUDIOClient[] =
{
    MIU_BW_AUDIO_HW_CLIENT
};
static MS_U32 u32AUDIOENClient[] =
{
    MIU_BW_AUDIOEN_HW_CLIENT
};
static MS_U32 u32AUDIODEClient[] =
{
    MIU_BW_AUDIODE_HW_CLIENT
};
static MS_U32 u32VDECClient[] =
{
    MIU_BW_VDEC_HW_CLIENT
};
static MS_U32 u32GEClient[] =
{
    MIU_BW_GE_HW_CLIENT
};
static MS_U32 u32VDECR2Client[] =
{
    MIU_BW_VDECR2_HW_CLIENT
};
static MS_U32 u32DIPClient[] =
{
    MIU_BW_DIP_HW_CLIENT
};
static MS_U32 u32VEClient[] =
{
    MIU_BW_VE_HW_CLIENT
};
static MS_U32 u32MFDECClient[] =
{
    MIU_BW_MFDEC_HW_CLIENT
};
static MS_U32 u32DISPLAYClient[] =
{
    MIU_BW_DISPLAY_HW_CLIENT
};
static MS_U32 u32BISTClient[] =
{
    MIU_BW_BIST_HW_CLIENT
};
//-------------------------------------------------------------------------------------------------
//  Local Variables
//-------------------------------------------------------------------------------------------------
static MS_VIRT _gMIU_MapBase = 0x1F200000;      //default set to MIPS platfrom
static MS_VIRT _gPM_MapBase = 0x1F000000;       //default set to MIPS platfrom
static MS_VIRT _gEXT_MapBase = 0xBf600000;

// UTOPIA remove so dummy code
#ifndef CONFIG_UTOPIAXP_REMOVE_IMPL
static MS_U32 u32CurrentUpdateFrequencyValue;
static MS_U32 u32BWMonitorInitCount = 0;

MS_BOOL IDEnables[MIU_MAX_DEVICE][MIU_MAX_PROTECT_BLOCK][MIU_MAX_PROTECT_ID] =
        {
            {{0}, {0}, {0}, {0}}
        }; //ID enable for protect block 0~3

MS_U32 IDs[MIU_MAX_DEVICE][MIU_MAX_PROTECT_ID_GROUP][MIU_MAX_PROTECT_ID] = {{{0}, {0}}}; //IDs for protection

MS_U32 ProtectGroupSelect[MIU_MAX_DEVICE][MIU_MAX_PROTECT_BLOCK] = {{0}};

//IDs for bandwidth monitor
static MS_U32 MonitorId[MIU_MAX_DEVICE][MIU_MAX_BW_MONITOR_GROUP_NUMBER][MIU_MAX_BW_MONITOR_GP_CLIENT_NUMBER];
#endif

//-------------------------------------------------------------------------------------------------
//  Debug Functions
//-------------------------------------------------------------------------------------------------

//-------------------------------------------------------------------------------------------------
//  Local Functions
//-------------------------------------------------------------------------------------------------

//-------------------------------------------------------------------------------------------------
// Type and Structure Declaration
//-------------------------------------------------------------------------------------------------

//-------------------------------------------------------------------------------------------------
//  Global Functions
//-------------------------------------------------------------------------------------------------
void HAL_MIU_SetIOMapBase(MS_VIRT virtBase)
{
    _gMIU_MapBase = virtBase;
    MIU_DEBUG_INFO(u32MIUDbgLevel, "MIU _gMIU_MapBase= %lx\n", _gMIU_MapBase);
}

void HAL_MIU_SetPMIOMapBase(MS_VIRT virtBase)
{
    _gPM_MapBase = virtBase;
    MIU_DEBUG_INFO(u32MIUDbgLevel, "MIU _gPM_MapBase= %lx\n", _gPM_MapBase);
}

void HAL_MIU_SetExtIOMapBase(MS_VIRT virtBase)
{
    _gEXT_MapBase = virtBase;
    MIU_DEBUG_INFO(u32MIUDbgLevel, "MIU _gEXT_MapBase= %lx\n", _gEXT_MapBase);
}

MS_S16 HAL_MIU_GetClientInfo(MS_U8 u8MiuDev, eMIUClientID eClientID)
{
    if (u8MiuDev >= MIU_MAX_DEVICE)
    {
        MIU_DEBUG_INFO(u32MIUDbgLevel, "Wrong MIU device:%u\n", u8MiuDev);
        return (-1);
    }

    if(eClientID == MIU_CLIENT_DUMMY)
    {
        MIU_DEBUG_INFO(u32MIUDbgLevel, "Not support client ID:%u!\n", eClientID);
        return (-1);
    }

    if(eClientID != MIU_CLIENT_NONE && clientTbl[u8MiuDev][eClientID] == 0x0)
        return (-1);

    return clientTbl[u8MiuDev][eClientID];
}

////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function  \b Name: HAL_MIU_ReadByte
/// @brief \b Function  \b Description: read 1 Byte data
/// @param <IN>         \b u32RegAddr: register address
/// @param <OUT>        \b None :
/// @param <RET>        \b MS_U8
/// @param <GLOBAL>     \b None :
////////////////////////////////////////////////////////////////////////////////
MS_U8 HAL_MIU_ReadByte(MS_U32 u32RegAddr)
{
    return ((volatile MS_U8*)(_gMIU_MapBase))[(u32RegAddr << 1) - (u32RegAddr & 1)];
}

MS_U8 HAL_MIU_ExtReadByte(MS_U32 u32RegAddr)
{
    return ((volatile MS_U8*)(_gEXT_MapBase))[(u32RegAddr << 1) - (u32RegAddr & 1)];
}


////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function  \b Name: HAL_MIU_PM_ReadByte
/// @brief \b Function  \b Description: read 1 Byte data
/// @param <IN>         \b u32RegAddr: register address
/// @param <OUT>        \b None :
/// @param <RET>        \b MS_U8
/// @param <GLOBAL>     \b None :
////////////////////////////////////////////////////////////////////////////////
MS_U8 HAL_MIU_PM_ReadByte(MS_U32 u32RegAddr)
{
    return ((volatile MS_U8*)(_gPM_MapBase))[(u32RegAddr << 1) - (u32RegAddr & 1)];
}

////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function  \b Name: HAL_MIU_Read4Byte
/// @brief \b Function  \b Description: read 2 Byte data
/// @param <IN>         \b u32RegAddr: register address
/// @param <OUT>        \b None :
/// @param <RET>        \b MS_U16
/// @param <GLOBAL>     \b None :
////////////////////////////////////////////////////////////////////////////////
MS_U16 HAL_MIU_Read2Byte(MS_U32 u32RegAddr)
{
    return ((volatile MS_U16*)(_gMIU_MapBase))[u32RegAddr];
}

MS_U16 HAL_MIU_ExtRead2Byte(MS_U32 u32RegAddr)
{
    return ((volatile MS_U16*)(_gEXT_MapBase))[u32RegAddr];
}

////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function  \b Name: HAL_MIU_Read4Byte
/// @brief \b Function  \b Description: read 4 Byte data
/// @param <IN>         \b u32RegAddr: register address
/// @param <OUT>        \b None :
/// @param <RET>        \b MS_U32
/// @param <GLOBAL>     \b None :
////////////////////////////////////////////////////////////////////////////////
MS_U32 HAL_MIU_Read4Byte(MS_U32 u32RegAddr)
{
    return (HAL_MIU_Read2Byte(u32RegAddr) | HAL_MIU_Read2Byte(u32RegAddr+2) << 16);
}

MS_U32 HAL_MIU_ExtRead4Byte(MS_U32 u32RegAddr)
{
    return (HAL_MIU_ExtRead2Byte(u32RegAddr) | HAL_MIU_ExtRead2Byte(u32RegAddr+2) << 16);
}

////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function  \b Name: HAL_MIU_WriteByte
/// @brief \b Function  \b Description: write 1 Byte data
/// @param <IN>         \b u32RegAddr: register address
/// @param <IN>         \b u8Val : 1 byte data
/// @param <OUT>        \b None :
/// @param <RET>        \b TRUE: Ok FALSE: Fail
/// @param <GLOBAL>     \b None :
////////////////////////////////////////////////////////////////////////////////
MS_BOOL HAL_MIU_WriteByte(MS_U32 u32RegAddr, MS_U8 u8Val)
{
    if (!u32RegAddr)
    {
        MIU_DEBUG_ERR(u32MIUDbgLevel, "WriteByte reg error!\n");
        return FALSE;
    }

    ((volatile MS_U8*)(_gMIU_MapBase))[(u32RegAddr << 1) - (u32RegAddr & 1)] = u8Val;
    return TRUE;
}

MS_BOOL HAL_MIU_ExtWriteByte(MS_U32 u32RegAddr, MS_U8 u8Val)
{
    ((volatile MS_U8*)(_gEXT_MapBase))[(u32RegAddr << 1) - (u32RegAddr & 1)] = u8Val;
    return TRUE;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function  \b Name: HAL_MIU_Write2Byte
/// @brief \b Function  \b Description: write 2 Byte data
/// @param <IN>         \b u32RegAddr: register address
/// @param <IN>         \b u16Val : 2 byte data
/// @param <OUT>        \b None :
/// @param <RET>        \b TRUE: Ok FALSE: Fail
/// @param <GLOBAL>     \b None :
////////////////////////////////////////////////////////////////////////////////
MS_BOOL HAL_MIU_Write2Byte(MS_U32 u32RegAddr, MS_U16 u16Val)
{
    if (!u32RegAddr)
    {
        MIU_DEBUG_ERR(u32MIUDbgLevel, "Write2Byte reg error!\n");
        return FALSE;
    }

    ((volatile MS_U16*)(_gMIU_MapBase))[u32RegAddr] = u16Val;
    return TRUE;
}

MS_BOOL HAL_MIU_ExtWrite2Byte(MS_U32 u32RegAddr, MS_U16 u16Val)
{
    ((volatile MS_U16*)(_gEXT_MapBase))[u32RegAddr] = u16Val;
    return TRUE;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function  \b Name: HAL_BDMA_Write4Byte
/// @brief \b Function  \b Description: write 4 Byte data
/// @param <IN>         \b u32RegAddr: register address
/// @param <IN>         \b u32Val : 4 byte data
/// @param <OUT>        \b None :
/// @param <RET>        \b TRUE: Ok FALSE: Fail
/// @param <GLOBAL>     \b None :
////////////////////////////////////////////////////////////////////////////////
MS_BOOL HAL_MIU_Write4Byte(MS_U32 u32RegAddr, MS_U32 u32Val)
{
    if (!u32RegAddr)
    {
        MIU_DEBUG_ERR(u32MIUDbgLevel, "Write4Byte reg error!\n");
        return FALSE;
    }

    HAL_MIU_Write2Byte(u32RegAddr, u32Val & 0x0000FFFF);
    HAL_MIU_Write2Byte(u32RegAddr+2, u32Val >> 16);
    return TRUE;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function  \b Name: HAL_BDMA_ExtWrite4Byte
/// @brief \b Function  \b Description: write 4 Byte data
/// @param <IN>         \b u32RegAddr: register address
/// @param <IN>         \b u32Val : 4 byte data
/// @param <OUT>        \b None :
/// @param <RET>        \b TRUE: Ok FALSE: Fail
/// @param <GLOBAL>     \b None :
////////////////////////////////////////////////////////////////////////////////
MS_BOOL HAL_MIU_ExtWrite4Byte(MS_U32 u32RegAddr, MS_U32 u32Val)
{
    if (!u32RegAddr)
    {
        MIU_DEBUG_ERR(u32MIUDbgLevel, "ExtWrite4Byte reg error!\n");
        return FALSE;
    }

    HAL_MIU_ExtWrite2Byte(u32RegAddr, u32Val & 0x0000FFFF);
    HAL_MIU_ExtWrite2Byte(u32RegAddr+2, u32Val >> 16);
    return TRUE;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function  \b Name: HAL_BDMA_WriteByte
/// @brief \b Function  \b Description: write 1 Byte data
/// @param <IN>         \b u32RegAddr: register address
/// @param <IN>         \b u8Val : 1 byte data
/// @param <OUT>        \b None :
/// @param <RET>        \b TRUE: Ok FALSE: Fail
/// @param <GLOBAL>     \b None :
////////////////////////////////////////////////////////////////////////////////
MS_BOOL HAL_MIU_WriteRegBit(MS_U32 u32RegAddr, MS_U8 u8Mask, MS_BOOL bEnable)
{
    MS_U8 u8Val;
    if (!u32RegAddr)
    {
        MIU_DEBUG_ERR(u32MIUDbgLevel, "WriteRegBit reg error!\n");
        return FALSE;
    }

    u8Val = HAL_MIU_ReadByte(u32RegAddr);
    u8Val = (bEnable) ? (u8Val | u8Mask) : (u8Val & ~u8Mask);
    HAL_MIU_WriteByte(u32RegAddr, u8Val);
    return TRUE;
}

MS_BOOL HAL_MIU_ExtWriteRegBit(MS_U32 u32RegAddr, MS_U8 u8Mask, MS_BOOL bEnable)
{
    MS_U8 u8Val;
    if (!u32RegAddr)
    {
        MIU_DEBUG_ERR(u32MIUDbgLevel, "ExtWriteRegBit reg error!\n");
        return FALSE;
    }

    u8Val = HAL_MIU_ExtReadByte(u32RegAddr);
    u8Val = (bEnable) ? (u8Val | u8Mask) : (u8Val & ~u8Mask);
    HAL_MIU_ExtWriteByte(u32RegAddr, u8Val);
    return TRUE;
}

void HAL_MIU_Write2BytesBit(MS_U32 u32RegOffset, MS_BOOL bEnable, MS_U16 u16Mask)
{
    MS_U16 val = HAL_MIU_Read2Byte(u32RegOffset);
    val = (bEnable) ? (val | u16Mask) : (val & ~u16Mask);
    HAL_MIU_Write2Byte(u32RegOffset, val);
}

void HAL_MIU_ExtWrite2BytesBit(MS_U32 u32RegOffset, MS_BOOL bEnable, MS_U16 u16Mask)
{
    MS_U16 val = HAL_MIU_ExtRead2Byte(u32RegOffset);
    val = (bEnable) ? (val | u16Mask) : (val & ~u16Mask);
    HAL_MIU_ExtWrite2Byte(u32RegOffset, val);
}

// UTOPIA remove so dummy code
#ifndef CONFIG_UTOPIAXP_REMOVE_IMPL
void HAL_MIU_SetProtectID(MS_U32 u32Reg, MS_U8 u8MiuDev, MS_U32 u32ClientID)
{
    MS_S16 sVal = HAL_MIU_GetClientInfo(u8MiuDev, (eMIUClientID)u32ClientID);

    if (0 > sVal)
        sVal = 0;

    HAL_MIU_ExtWriteByte(u32Reg, sVal & 0xFF);
}

MS_BOOL HAL_MIU_SelIDGroup(MS_U8 u8MiuSel, MS_U8 u8Blockx, MS_U32 *pu32ProtectId)
{
    MS_BOOL bprotectgroup;
    MS_U32 u32ID;
    MS_U32 u32IdGroup;
    MS_U32 u32IdIndex;
    MS_U32 u32index;
    MS_U8 u8isfound0, u8isfound1;

    if(u8MiuSel >= MIU_MAX_DEVICE)
    {
        MIU_DEBUG_INFO(u32MIUDbgLevel, "Not support MIU%u!\n", u8MiuSel );
        return false;
    }

    //Select which protect group
    for(u32IdGroup = 0; u32IdGroup < MIU_MAX_PROTECT_ID_GROUP; u32IdGroup++)
    {
        bprotectgroup = TRUE;
        for(u32IdIndex = 0; u32IdIndex < MIU_MAX_PROTECT_ID; u32IdIndex++)
        {
            u32ID = pu32ProtectId[u32IdIndex];

            if(u32ID == 0)
                continue;

            u8isfound0 = FALSE;
            //check if repeat
            for(u32index = 0; u32index < MIU_MAX_PROTECT_ID; u32index++)
            {
                if(HAL_MIU_GetClientInfo(u8MiuSel,(eMIUClientID)IDs[u8MiuSel][u32IdGroup][u32index]) == HAL_MIU_GetClientInfo(u8MiuSel,(eMIUClientID)u32ID))
                {
                    u8isfound0 = TRUE;
                    break;
                }
            }
            //check if protect list overflow
            if(u8isfound0 != TRUE)
            {
                u8isfound1 = FALSE;
                for(u32index = 0; u32index < MIU_MAX_PROTECT_ID; u32index++)
                {
                    if(IDs[u8MiuSel][u32IdGroup][u32index] == 0)
                    {
                        u8isfound1 = TRUE;
                        break;
                    }
                }
                //ID overflow
                if(u8isfound1 == FALSE)
                {
                    //this protect group can not protect all protect id
                    bprotectgroup = FALSE;
                    break;
                }
            }
        }
        if(bprotectgroup)
        {
            ProtectGroupSelect[u8MiuSel][u8Blockx] = u32IdGroup;
            return true;
        }
    }
    MIU_DEBUG_INFO(u32MIUDbgLevel, "No protect ID group can use.\n" );
    return false;
}

MS_BOOL HAL_MIU_SetGroupID2(MS_U8 u8MiuSel, MS_U8 u8Blockx, MS_U32 *pu32ProtectId, MS_U32 u32RegAddrID, MS_U32 u32RegAddrIDenable, MS_U32 u32SelIdGroup)
{
    MS_U32 u32index0, u32index1;
    MS_U32 u32ID;
    MS_U8 u8isfound0, u8isfound1;
    MS_U16 u16idenable;

    //reset IDenables for protect u8Blockx
    for(u32index0 = 0; u32index0 < MIU_MAX_PROTECT_ID; u32index0++)
    {
        IDEnables[u8MiuSel][u8Blockx][u32index0] = 0;
    }

    for(u32index0 = 0; u32index0 < MIU_MAX_PROTECT_ID; u32index0++)
    {
        u32ID = pu32ProtectId[u32index0];

        //Unused ID
        if(u32ID == 0 || HAL_MIU_GetClientInfo(u8MiuSel, (eMIUClientID)u32ID) <= 0)
           continue;

        u8isfound0 = FALSE;

        for(u32index1 = 0; u32index1 < MIU_MAX_PROTECT_ID; u32index1++)
        {
            if(HAL_MIU_GetClientInfo(u8MiuSel,(eMIUClientID)IDs[u8MiuSel][u32SelIdGroup][u32index1]) == HAL_MIU_GetClientInfo(u8MiuSel,(eMIUClientID)u32ID))
            {
                //ID reused former setting
                IDEnables[u8MiuSel][u8Blockx][u32index1] = 1;
                u8isfound0 = TRUE;
                break;
            }
        }


        //Need to create new ID in IDs
        if(u8isfound0 != TRUE)
        {
            u8isfound1 = FALSE;

            for(u32index1 = 0; u32index1 < MIU_MAX_PROTECT_ID; u32index1++)
            {
                if(IDs[u8MiuSel][u32SelIdGroup][u32index1] == 0)
                {
                    IDs[u8MiuSel][u32SelIdGroup][u32index1] = u32ID;
                    IDEnables[u8MiuSel][u8Blockx][u32index1] = 1;
                    u8isfound1 = TRUE;
                    break;
                }
            }

            //ID overflow
            if(u8isfound1 == FALSE)
                return FALSE;
        }
    }

    u16idenable = 0;

    for(u32index0 = 0; u32index0 < MIU_MAX_PROTECT_ID; u32index0++)
    {
        if(IDEnables[u8MiuSel][u8Blockx][u32index0] == 1)
            u16idenable |= (1<<u32index0);
    }

    HAL_MIU_ExtWrite2Byte(u32RegAddrIDenable, u16idenable);

    for(u32index0 = 0; u32index0 < MIU_MAX_PROTECT_ID; u32index0++)
    {
         HAL_MIU_SetProtectID(u32RegAddrID + u32index0, u8MiuSel, IDs[u8MiuSel][u32SelIdGroup][u32index0]);
    }

    return TRUE;
}

MS_BOOL HAL_MIU_ResetGroupID(MS_U8 u8MiuSel, MS_U8 u8Blockx, MS_U32 *pu32ProtectId, MS_U32 u32RegAddrID, MS_U32 u32RegAddrIDenable)
{
    MS_U32 u32index0, u32index1;
    MS_U8 u8isIDNoUse;
    MS_U16 u16idenable;
    MS_U32 u32IdGroup;

    if (u8MiuSel >= MIU_MAX_DEVICE)
        return FALSE;

    //get id group of block
    u32IdGroup = ProtectGroupSelect[u8MiuSel][u8Blockx];

    //reset IDenables for protect u8Blockx
    for(u32index0 = 0; u32index0 < MIU_MAX_PROTECT_ID; u32index0++)
    {
        IDEnables[u8MiuSel][u8Blockx][u32index0] = 0;
    }

    u16idenable = 0x0;

    HAL_MIU_ExtWrite2Byte(u32RegAddrIDenable, u16idenable);

    for(u32index0 = 0; u32index0 < MIU_MAX_PROTECT_ID; u32index0++)
    {
        u8isIDNoUse  = FALSE;

        for(u32index1 = 0; u32index1 < MIU_MAX_PROTECT_BLOCK; u32index1++)
        {
            if(ProtectGroupSelect[u8MiuSel][u32index1] == u32IdGroup)
            {
                if(IDEnables[u8MiuSel][u32index1][u32index0] == 1)
                {
                    //protect ID is still be used
                    u8isIDNoUse  = FALSE;
                    break;
                }
                u8isIDNoUse  = TRUE;
            }
        }

        if(u8isIDNoUse == TRUE)
            IDs[u8MiuSel][u32IdGroup][u32index0] = 0;
    }

    for(u32index0 = 0; u32index0 < MIU_MAX_PROTECT_ID; u32index0++)
    {
         HAL_MIU_SetProtectID(u32RegAddrID + u32index0, u8MiuSel, IDs[u8MiuSel][u32IdGroup][u32index0]);
    }

    return TRUE;
}
#endif

////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function \b Name: HAL_MIU_GetDefaultClientID_KernelProtect()
/// @brief \b Function \b Description:  Get default client id array pointer for protect kernel
/// @param <RET>           \b     : The pointer of Array of client IDs
////////////////////////////////////////////////////////////////////////////////
MS_U8* HAL_MIU_GetDefaultClientID_KernelProtect()
{
     if(IDNUM_KERNELPROTECT > 0)
         return  (MS_U8 *)&clientId_KernelProtect[0];

     return NULL;
}

// UTOPIA remove so dummy code
#ifndef CONFIG_UTOPIAXP_REMOVE_IMPL
////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function    \b Name: HAL_MIU_ProtectAlign()
/// @brief \b Function    \b Description:  Get the page shift for MIU protect
/// @param <*u32PageShift>\b IN: Page shift
/// @param <RET>          \b OUT: None
////////////////////////////////////////////////////////////////////////////////
MS_U32 HAL_MIU_ProtectAlign(void)
{
    MS_U32 u32PageShift;

    u32PageShift = MIU_PAGE_SHIFT;
    return u32PageShift;
}

static MS_U64 HAL_MIU_UMAOffset(MS_U32 u32MiuSel)
{
    switch (u32MiuSel)
    {
        case 0:
        {
            return 0;
        }
        case 1:
        {
            MS_U16 regVal = HAL_MIU_Read2Byte(REG_MIU_SIZE_CONFIG);
            MS_U32 miu_size_config = (regVal>>8)&0xF;

            switch(miu_size_config)
            {
                case 0x9:
                    return 256* 0x100000ULL; //256MB
                case 0xA:
                    return 512* 0x100000ULL; //512MB
                case 0xB:
                    return 1024* 0x100000ULL; //1GB
                case 0xC:
                    return 2048* 0x100000ULL; //2GB
                case 0xD:
                    return 4096* 0x100000ULL; //4GB
                default:
                    MIU_DEBUG_INFO(u32MIUDbgLevel, "Incorrect MIU size config value\n" );
            }
            return 0;
        }
        default:
        {
            MIU_DEBUG_INFO(u32MIUDbgLevel, "Not support MIU%lu!\n", (unsigned long)u32MiuSel);
        }
    }

    return 0;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function \b Name: HAL_MIU_Dram_Size()
/// @brief \b Function \b Description: Set up Dram size for MIU protect
/// @param MiuID        \b IN     : MIU ID
/// @param DramSize     \b IN     : Specified Dram size for MIU protect
/// @param <OUT>           \b None    :
/// @param <RET>           \b None    :
/// @param <GLOBAL>        \b None    :
////////////////////////////////////////////////////////////////////////////////
MS_BOOL HAL_MIU_Dram_Size(MS_U8 MiuID, MS_U8 DramSize)
{
    MS_U32 u32RegAddr;
    MS_U32 u32RegAddrBound;
    MS_U32 u32RegAddrProtect;

    if(E_MIU_0 == (MIU_ID)MiuID)
    {
        u32RegAddr = MIU_PROTECT_DDR_SIZE;
        u32RegAddrBound = MIU_PROTECT_DDR_BOUND;
        u32RegAddrProtect = MIU_PROTECT_BASE;

        switch (DramSize)
        {
            case E_MIU_DDR_32MB:
                HAL_MIU_WriteByte(u32RegAddr, MIU_PROTECT_DDR_32MB);
                HAL_MIU_ExtWrite4Byte(u32RegAddrBound, MIU_PROTECT_DDR_32MB_BOUND);
                break;
            case E_MIU_DDR_64MB:
                HAL_MIU_WriteByte(u32RegAddr, MIU_PROTECT_DDR_64MB);
                HAL_MIU_ExtWrite4Byte(u32RegAddrBound, MIU_PROTECT_DDR_64MB_BOUND);
                break;
            case E_MIU_DDR_128MB:
                HAL_MIU_WriteByte(u32RegAddr, MIU_PROTECT_DDR_128MB);
                HAL_MIU_ExtWrite4Byte(u32RegAddrBound, MIU_PROTECT_DDR_128MB_BOUND);
                break;
            case E_MIU_DDR_256MB:
                HAL_MIU_WriteByte(u32RegAddr, MIU_PROTECT_DDR_256MB);
                HAL_MIU_ExtWrite4Byte(u32RegAddrBound, MIU_PROTECT_DDR_256MB_BOUND);
                break;
            case E_MIU_DDR_384MB:
                HAL_MIU_WriteByte(u32RegAddr, MIU_PROTECT_DDR_512MB);
                HAL_MIU_ExtWrite4Byte(u32RegAddrBound, MIU_PROTECT_DDR_384MB_BOUND);
                break;
            case E_MIU_DDR_512MB:
                HAL_MIU_WriteByte(u32RegAddr, MIU_PROTECT_DDR_512MB);
                HAL_MIU_ExtWrite4Byte(u32RegAddrBound, MIU_PROTECT_DDR_512MB_BOUND);
                break;
            case E_MIU_DDR_768MB:
                HAL_MIU_WriteByte(u32RegAddr, MIU_PROTECT_DDR_1024MB);
                HAL_MIU_ExtWrite4Byte(u32RegAddrBound, MIU_PROTECT_DDR_768MB_BOUND);
                break;
            case E_MIU_DDR_1024MB:
                HAL_MIU_WriteByte(u32RegAddr, MIU_PROTECT_DDR_1024MB);
                HAL_MIU_ExtWrite4Byte(u32RegAddrBound, MIU_PROTECT_DDR_1024MB_BOUND);
                break;
            case E_MIU_DDR_1280MB:
                HAL_MIU_WriteByte(u32RegAddr, MIU_PROTECT_DDR_2048MB);
                HAL_MIU_ExtWrite4Byte(u32RegAddrBound, MIU_PROTECT_DDR_1280MB_BOUND);
                break;
            case E_MIU_DDR_1536MB:
                HAL_MIU_WriteByte(u32RegAddr, MIU_PROTECT_DDR_2048MB);
                HAL_MIU_ExtWrite4Byte(u32RegAddrBound, MIU_PROTECT_DDR_1536MB_BOUND);
                break;
            case E_MIU_DDR_1792MB:
                HAL_MIU_WriteByte(u32RegAddr, MIU_PROTECT_DDR_2048MB);
                HAL_MIU_ExtWrite4Byte(u32RegAddrBound, MIU_PROTECT_DDR_1792MB_BOUND);
                break;
            case E_MIU_DDR_2048MB:
                HAL_MIU_WriteByte(u32RegAddr, MIU_PROTECT_DDR_2048MB);
                HAL_MIU_ExtWrite4Byte(u32RegAddrBound, MIU_PROTECT_DDR_2048MB_BOUND);
                break;
            case E_MIU_DDR_2304MB:
                HAL_MIU_WriteByte(u32RegAddr, MIU_PROTECT_DDR_4096MB);
                HAL_MIU_ExtWrite4Byte(u32RegAddrBound, MIU_PROTECT_DDR_2304MB_BOUND);
                break;
            case E_MIU_DDR_2560MB:
                HAL_MIU_WriteByte(u32RegAddr, MIU_PROTECT_DDR_4096MB);
                HAL_MIU_ExtWrite4Byte(u32RegAddrBound, MIU_PROTECT_DDR_2560MB_BOUND);
                break;
            case E_MIU_DDR_2816MB:
                HAL_MIU_WriteByte(u32RegAddr, MIU_PROTECT_DDR_4096MB);
                HAL_MIU_ExtWrite4Byte(u32RegAddrBound, MIU_PROTECT_DDR_2816MB_BOUND);
                break;
            case E_MIU_DDR_3072MB:
                HAL_MIU_WriteByte(u32RegAddr, MIU_PROTECT_DDR_4096MB);
                HAL_MIU_ExtWrite4Byte(u32RegAddrBound, MIU_PROTECT_DDR_3072MB_BOUND);
                break;
            case E_MIU_DDR_3328MB:
                HAL_MIU_WriteByte(u32RegAddr, MIU_PROTECT_DDR_4096MB);
                HAL_MIU_ExtWrite4Byte(u32RegAddrBound, MIU_PROTECT_DDR_3328MB_BOUND);
                break;
            case E_MIU_DDR_3584MB:
                HAL_MIU_WriteByte(u32RegAddr, MIU_PROTECT_DDR_4096MB);
                HAL_MIU_ExtWrite4Byte(u32RegAddrBound, MIU_PROTECT_DDR_3584MB_BOUND);
                break;
            case E_MIU_DDR_3840MB:
                HAL_MIU_WriteByte(u32RegAddr, MIU_PROTECT_DDR_4096MB);
                HAL_MIU_ExtWrite4Byte(u32RegAddrBound, MIU_PROTECT_DDR_3840MB_BOUND);
                break;
            case E_MIU_DDR_4096MB:
                HAL_MIU_WriteByte(u32RegAddr, MIU_PROTECT_DDR_4096MB);
                HAL_MIU_ExtWrite4Byte(u32RegAddrBound, MIU_PROTECT_DDR_4096MB_BOUND);
                break;
            case E_MIU_DDR_8192MB:
                HAL_MIU_WriteByte(u32RegAddr, MIU_PROTECT_DDR_8192MB);
                break;
            default:
                return false;
        }
        //out of area protect enable
        if(DramSize != E_MIU_DDR_8192MB)
        {
            //Write Over Bound Protect
            HAL_MIU_ExtWrite2BytesBit(u32RegAddrProtect, TRUE, BIT12);
            //Read Over Bound Protect
            HAL_MIU_ExtWrite2BytesBit(u32RegAddrProtect+0x2, TRUE, BIT12);
        }
    }
    else
    {
        MIU_DEBUG_INFO(u32MIUDbgLevel, "Not support MIU%u!\n", MiuID);
        return FALSE;
    }

    return true;
}
#endif

////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function \b Name: HAL_MIU_Dram_ReadSize()
/// @brief \b Function \b Description: Set up Dram size for MIU protect
/// @param MiuID        \b IN     : MIU ID
/// @param DramSize     \b IN     : Specified Dram size for MIU protect
/// @param <OUT>           \b None    :
/// @param <RET>           \b None    :
/// @param <GLOBAL>        \b None    :
////////////////////////////////////////////////////////////////////////////////
MS_BOOL HAL_MIU_Dram_ReadSize(MS_U8 MiuID, MIU_DDR_SIZE *pDramSize)
{
    MS_U32 u32RegAddr;
    MS_U8  DramSize;

    if (MiuID >= MIU_MAX_DEVICE)
        return FALSE;

    u32RegAddr = MIU_PROTECT_DDR_SIZE;
    DramSize = HAL_MIU_ReadByte(u32RegAddr);
    DramSize &= 0xF0;
    switch (DramSize)
    {
        case MIU_PROTECT_DDR_32MB:
            *pDramSize = E_MIU_DDR_32MB;
            break;
        case MIU_PROTECT_DDR_64MB:
            *pDramSize = E_MIU_DDR_64MB;
            break;
        case MIU_PROTECT_DDR_128MB:
            *pDramSize = E_MIU_DDR_128MB;
            break;
        case MIU_PROTECT_DDR_256MB:
            *pDramSize = E_MIU_DDR_256MB;
            break;
        case MIU_PROTECT_DDR_512MB:
            *pDramSize = E_MIU_DDR_512MB;
            break;
        case MIU_PROTECT_DDR_1024MB:
            *pDramSize = E_MIU_DDR_1024MB;
            break;
        case MIU_PROTECT_DDR_2048MB:
            *pDramSize = E_MIU_DDR_2048MB;
            break;
        case MIU_PROTECT_DDR_4096MB:
            *pDramSize = E_MIU_DDR_4096MB;
            break;
        case MIU_PROTECT_DDR_8192MB:
            *pDramSize = E_MIU_DDR_8192MB;
            break;
        default:
            return FALSE;
    }
    return TRUE;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function \b Name: MDrv_MIU_GetClinetNumber()
/// @brief \b Function \b Description:  Get the number of clients for specific MIU block
/// @param DramSize     \b IN     : MIU Block to protect (0 ~ 3)
/// @param <OUT>           \b None    :
/// @param <RET>           \b None    :
/// @param <GLOBAL>        \b None    :
////////////////////////////////////////////////////////////////////////////////
MS_U8 HAL_MIU_ClinetNumber(MS_U8 u8Blockx)
{
    MS_U8 u8ClientNumber;

    switch (u8Blockx)
    {
        case E_MIU_BLOCK_0:
            u8ClientNumber = MIU_BLOCK0_CLIENT_NUMBER;
            break;
        case E_MIU_BLOCK_1:
            u8ClientNumber = MIU_BLOCK1_CLIENT_NUMBER;
            break;
        case E_MIU_BLOCK_2:
            u8ClientNumber = MIU_BLOCK2_CLIENT_NUMBER;
            break;
        case E_MIU_BLOCK_3:
            u8ClientNumber = MIU_BLOCK3_CLIENT_NUMBER;
            break;
        case E_MIU_BLOCK_4:
            u8ClientNumber = MIU_BLOCK4_CLIENT_NUMBER;
            break;
        case E_MIU_BLOCK_5:
            u8ClientNumber = MIU_BLOCK5_CLIENT_NUMBER;
            break;
        case E_MIU_BLOCK_6:
            u8ClientNumber = MIU_BLOCK6_CLIENT_NUMBER;
            break;
        case E_MIU_BLOCK_7:
            u8ClientNumber = MIU_BLOCK7_CLIENT_NUMBER;
            break;
        default:
            u8ClientNumber = 0;
    }

    return u8ClientNumber;
}

// UTOPIA remove so dummy code
#ifndef CONFIG_UTOPIAXP_REMOVE_IMPL
////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function \b Name: HAL_MIU_Protect()
/// @brief \b Function \b Description:  Enable/Disable MIU Protection mode
/// @param u8Blockx        \b IN     : MIU Block to protect (0 ~ 4)
/// @param *pu8ProtectId   \b IN     : Allow specified client IDs to write
/// @param u32Start        \b IN     : Starting address
/// @param u32End          \b IN     : End address
/// @param bSetFlag        \b IN     : Disable or Enable MIU protection
///                                      - -Disable(0)
///                                      - -Enable(1)
/// @param <OUT>           \b None    :
/// @param <RET>           \b None    :
/// @param <GLOBAL>        \b None    :
////////////////////////////////////////////////////////////////////////////////
MS_BOOL HAL_MIU_Protect(
                          MS_U8    u8Blockx,
                          MS_U8    *pu8ProtectId,
                          MS_PHY   phy64Start,
                          MS_PHY   phy64End,
                          MS_BOOL  bSetFlag
                         )
{
    MIU_DEBUG_DBG(u32MIUDbgLevel, "Not Support. Auto use MDrv_MIU_ProtectEx for MIU protect\n");
    MS_U8 u8ProtectIdNum;
    MS_U32 pu32ProtectId[MIU_MAX_PROTECT_ID];
    for(u8ProtectIdNum = 0; u8ProtectIdNum < MIU_MAX_PROTECT_ID; u8ProtectIdNum++)
    {
        pu32ProtectId[u8ProtectIdNum] = (MS_U32)pu8ProtectId[u8ProtectIdNum];
    }
    return HAL_MIU_ProtectEx(u8Blockx, pu32ProtectId, phy64Start, phy64End, bSetFlag);
}

////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function \b Name: HAL_MIU_ProtectEx()
/// @brief \b Function \b Description:  Enable/Disable MIU Protection mode
/// @param u8Blockx        \b IN     : MIU Block to protect (0 ~ 4)
/// @param *pu8ProtectId   \b IN     : Allow specified client IDs to write
/// @param u32Start        \b IN     : Starting address
/// @param u32End          \b IN     : End address
/// @param bSetFlag        \b IN     : Disable or Enable MIU protection
///                                      - -Disable(0)
///                                      - -Enable(1)
/// @param <OUT>           \b None    :
/// @param <RET>           \b None    :
/// @param <GLOBAL>        \b None    :
////////////////////////////////////////////////////////////////////////////////
MS_BOOL HAL_MIU_ProtectEx(
                          MS_U8    u8Blockx,
                          MS_U32   *pu32ProtectId,
                          MS_PHY   phy64Start,
                          MS_PHY   phy64End,
                          MS_BOOL  bSetFlag
                         )
{
    MS_U32 u32RegAddr;
    MS_U32 u32RegAddrStar;
    MS_U32 u32RegAddrIDenable;
    MS_U32 u32MiuProtectEn;
    MS_U32 u32MiuProtectGroupSel;
    MS_PHY phy64StartOffset;
    MS_PHY phy64EndOffset;
    MS_U32 u32Data;
    MS_U8  u8Data;
    MS_U8  u8MiuSel;
    MS_U32 u32SelIdGroup = 0;

    // Get MIU selection and offset
    _phy_to_miu_offset(u8MiuSel, phy64EndOffset, phy64End - 1); // minus 1 to avoid end address boundary issue
    _phy_to_miu_offset(u8MiuSel, phy64StartOffset, phy64Start);

    phy64Start = phy64StartOffset;
    phy64End = phy64EndOffset + 1; // plus 1 back to get correct end offset

    // For UMA offset
    phy64Start += HAL_MIU_UMAOffset(u8MiuSel);
    phy64End += HAL_MIU_UMAOffset(u8MiuSel);

    // Incorrect Block ID
    if(u8Blockx >= E_MIU_BLOCK_NUM)
    {
        MIU_DEBUG_INFO(u32MIUDbgLevel, "Out of the number of protect device\n");
        return false;
    }
    else if(((phy64Start & ((1 << MIU_PAGE_SHIFT) -1)) != 0) || ((phy64End & ((1 << MIU_PAGE_SHIFT) -1)) != 0))
    {
        MIU_DEBUG_INFO(u32MIUDbgLevel, "Protected address should be aligned to 8KB\n");
        return false;
    }
    else if(phy64Start >= phy64End)
    {
        MIU_DEBUG_INFO(u32MIUDbgLevel, "Start address is equal to or more than end address\n");
        return false;
    }

    //select ID Group
    if(!HAL_MIU_SelIDGroup(u8MiuSel, u8Blockx, pu32ProtectId))
    {
        return false;
    }
    u32SelIdGroup = ProtectGroupSelect[u8MiuSel][u8Blockx];

    //write_enable
    u8Data = 1 << u8Blockx;
    if(u8MiuSel == E_CHIP_MIU_0)
    {
        if(u32SelIdGroup == 0)
            u32RegAddr = MIU_PROTECT0_ID0;
        else
            u32RegAddr = MIU_PROTECT0_GROUP1_ID0;

        u32MiuProtectEn = MIU_PROTECT_EN;
        u32MiuProtectGroupSel = MIU_PROTECT_GROUP_SEL;

        switch (u8Blockx)
        {
            case E_MIU_BLOCK_0:
                u32RegAddrStar = MIU_PROTECT0_START;
                u32RegAddrIDenable = MIU_PROTECT0_ID_ENABLE;
                break;
            case E_MIU_BLOCK_1:
                u32RegAddrStar = MIU_PROTECT1_START;
                u32RegAddrIDenable = MIU_PROTECT1_ID_ENABLE;
                break;
            case E_MIU_BLOCK_2:
                u32RegAddrStar = MIU_PROTECT2_START;
                u32RegAddrIDenable = MIU_PROTECT2_ID_ENABLE;
                break;
            case E_MIU_BLOCK_3:
                u32RegAddrStar = MIU_PROTECT3_START;
                u32RegAddrIDenable = MIU_PROTECT3_ID_ENABLE;
                break;
            case E_MIU_BLOCK_4:
                u32RegAddrStar = MIU_PROTECT4_START;
                u32RegAddrIDenable = MIU_PROTECT4_ID_ENABLE;
                break;
            case E_MIU_BLOCK_5:
                u32RegAddrStar = MIU_PROTECT5_START;
                u32RegAddrIDenable = MIU_PROTECT5_ID_ENABLE;
                break;
            case E_MIU_BLOCK_6:
                u32RegAddrStar = MIU_PROTECT6_START;
                u32RegAddrIDenable = MIU_PROTECT6_ID_ENABLE;
                break;
            case E_MIU_BLOCK_7:
                u32RegAddrStar = MIU_PROTECT7_START;
                u32RegAddrIDenable = MIU_PROTECT7_ID_ENABLE;
                break;
            default:
                return false;
        }
    }
    else if(u8MiuSel == E_CHIP_MIU_1)
    {
        if(u32SelIdGroup == 0)
            u32RegAddr = MIU1_PROTECT0_ID0;
        else
            u32RegAddr = MIU1_PROTECT0_GROUP1_ID0;

        u32MiuProtectEn = MIU1_PROTECT_EN;
        u32MiuProtectGroupSel = MIU1_PROTECT_GROUP_SEL;

        switch (u8Blockx)
        {
            case E_MIU_BLOCK_0:
                u32RegAddrStar = MIU1_PROTECT0_START;
                u32RegAddrIDenable = MIU1_PROTECT0_ID_ENABLE;
                break;
            case E_MIU_BLOCK_1:
                u32RegAddrStar = MIU1_PROTECT1_START;
                u32RegAddrIDenable = MIU1_PROTECT1_ID_ENABLE;
                break;
            case E_MIU_BLOCK_2:
                u32RegAddrStar = MIU1_PROTECT2_START;
                u32RegAddrIDenable = MIU1_PROTECT2_ID_ENABLE;
                break;
            case E_MIU_BLOCK_3:
                u32RegAddrStar = MIU1_PROTECT3_START;
                u32RegAddrIDenable = MIU1_PROTECT3_ID_ENABLE;
                break;
            case E_MIU_BLOCK_4:
                u32RegAddrStar = MIU1_PROTECT4_START;
                u32RegAddrIDenable = MIU1_PROTECT4_ID_ENABLE;
                break;
            case E_MIU_BLOCK_5:
                u32RegAddrStar = MIU1_PROTECT5_START;
                u32RegAddrIDenable = MIU1_PROTECT5_ID_ENABLE;
                break;
            case E_MIU_BLOCK_6:
                u32RegAddrStar = MIU1_PROTECT6_START;
                u32RegAddrIDenable = MIU1_PROTECT6_ID_ENABLE;
                break;
            case E_MIU_BLOCK_7:
                u32RegAddrStar = MIU1_PROTECT7_START;
                u32RegAddrIDenable = MIU1_PROTECT7_ID_ENABLE;
                break;
            default:
                return false;
        }
     }
    else
    {
        MIU_DEBUG_INFO(u32MIUDbgLevel, "Not support MIU%u!\n",u8MiuSel );
        return FALSE;
    }

    // Disable MIU protect
    HAL_MIU_ExtWriteRegBit(u32MiuProtectEn,u8Data,DISABLE);

    if ( bSetFlag )
    {
        // Set Protect IDs
        if(HAL_MIU_SetGroupID2(u8MiuSel, u8Blockx, pu32ProtectId, u32RegAddr, u32RegAddrIDenable, u32SelIdGroup) == FALSE)
        {
            return FALSE;
        }

        // Start Address
        u32Data = ((MS_U32)(phy64Start >> MIU_PAGE_SHIFT)) & 0x000FFFFF;   //8k/unit //20bits
        HAL_MIU_ExtWrite2Byte(u32RegAddrStar , u32Data);
        HAL_MIU_ExtWriteByte(u32RegAddrStar + 2, u32Data>>16);

        // End Address
        u32Data = ((MS_U32)((phy64End >> MIU_PAGE_SHIFT)-1)) & 0x000FFFFF;   //8k/unit;
        HAL_MIU_ExtWrite2Byte(u32RegAddrStar + 4, u32Data);
        HAL_MIU_ExtWriteByte(u32RegAddrStar + 6, u32Data>>16);

        // Enable MIU protect
        HAL_MIU_ExtWriteRegBit(u32MiuProtectEn, u8Data, ENABLE);

        // Select MIU protect group
        HAL_MIU_ExtWriteRegBit(u32MiuProtectGroupSel, u8Data, ProtectGroupSelect[u8MiuSel][u8Blockx]);
    }
    else
    {
        // Reset Protect IDs
        HAL_MIU_ResetGroupID(u8MiuSel, u8Blockx, NULL, u32RegAddr, u32RegAddrIDenable);
    }

    // clear log
    HAL_MIU_ExtWrite2BytesBit(u32MiuProtectEn + REG_MIU_PROTECT_STATUS, TRUE, REG_MIU_PROTECT_LOG_CLR);
    HAL_MIU_ExtWrite2BytesBit(u32MiuProtectEn + REG_MIU_PROTECT_STATUS, FALSE, REG_MIU_PROTECT_LOG_CLR);

    return TRUE;
}

#define GET_HIT_BLOCK(regval)       BITS_RANGE_VAL(regval, REG_MIU_PROTECT_HIT_NO)
#define GET_HIT_CLIENT(regval)      BITS_RANGE_VAL(regval, REG_MIU_PROTECT_HIT_ID)

MS_BOOL HAL_MIU_GetProtectInfo(MS_U8 u8MiuDev, MIU_PortectInfo *pInfo)
{
    MS_U16 ret = 0;
    MS_U16 loaddr = 0;
    MS_U16 hiaddr = 0;
    MS_U16 block;
    MS_U32 u32Address = 0;
    MS_U32 u32Reg ;

    if(u8MiuDev == E_MIU_0)
    {
        u32Reg = MIU_PROTECT_BASE;
    }
    else
    {
        MIU_DEBUG_INFO(u32MIUDbgLevel, "Not support MIU%u!\n",u8MiuDev );
        return FALSE;
    }

    if (!pInfo)
        return FALSE;

    ret = HAL_MIU_ExtRead2Byte(u32Reg+REG_MIU_PROTECT_STATUS);
    block = HAL_MIU_ExtRead2Byte(u32Reg+REG_MIU_PROTECT_BLOCK);
    loaddr = HAL_MIU_ExtRead2Byte(u32Reg+REG_MIU_PROTECT_LOADDR);
    hiaddr = HAL_MIU_ExtRead2Byte(u32Reg+REG_MIU_PROTECT_HIADDR);

    pInfo->bHit = false;

    if (REG_MIU_PROTECT_HIT_FALG & ret)
    {
        pInfo->bHit = TRUE;

        pInfo->u8Block = (MS_U8)GET_HIT_BLOCK(block);
        pInfo->u8Group = (MS_U8)(GET_HIT_CLIENT(ret) >> 4);
        pInfo->u8ClientID = (MS_U8)(GET_HIT_CLIENT(ret) & 0x0F);
        u32Address = (MS_U32)((hiaddr << 16) | loaddr) ;
        u32Address = u32Address * MIU_PROTECT_ADDRESS_UNIT;

        MIU_DEBUG_ERR(u32MIUDbgLevel, "MIU%u Block:%u Group:%u ClientID:%u Hitted_Address:0x%x<->0x%x\n", u8MiuDev,
        pInfo->u8Block, pInfo->u8Group, pInfo->u8ClientID, (unsigned int)u32Address, (unsigned int)(u32Address + MIU_PROTECT_ADDRESS_UNIT - 1));

        //clear log
        HAL_MIU_ExtWrite2BytesBit(u32Reg+REG_MIU_PROTECT_STATUS, TRUE, REG_MIU_PROTECT_LOG_CLR);
        HAL_MIU_ExtWrite2BytesBit(u32Reg+REG_MIU_PROTECT_STATUS, FALSE, REG_MIU_PROTECT_LOG_CLR);
    }

    return TRUE;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function \b Name: HAL_MIU_SetSsc()
/// @brief \b Function \b Description: MDrv_MIU_SetSsc, @Step & Span
/// @param u16Fmodulation   \b IN : 20KHz ~ 40KHz (Input Value = 20 ~ 40)
/// @param u16FDeviation    \b IN  : under 0.1% ~ 2% (Input Value = 1 ~ 20)
/// @param bEnable          \b IN    :
/// @param None             \b OUT  :
/// @param None             \b RET  :
/// @param None             \b GLOBAL :
////////////////////////////////////////////////////////////////////////////////
MS_BOOL HAL_MIU_SetSsc(MS_U8 u8MiuDev, MS_U16 u16Fmodulation, MS_U16 u16FDeviation, MS_BOOL bEnable)
{
    MS_U32 uDDFSET, uDDR_MHz, uDDFStep, uRegBase = MIU_ATOP_BASE;
    MS_U16 u16DDFSpan;
    MS_U16 u16Input_DIV_First,u16Input_DIV_Second,u16Loop_DIV_First,u16Loop_DIV_Second;
    MS_U8  u8Temp,i;

    //Pre check the input
    if(u8MiuDev == E_MIU_0)
    {
        uRegBase = MIU_ATOP_BASE;
    }
    else if(u8MiuDev == E_MIU_1)
    {
        uRegBase = MIU1_ATOP_BASE;
    }
    else
    {
        MIU_DEBUG_INFO(u32MIUDbgLevel, "Not support MIU%u!\n",u8MiuDev );
        return FALSE;
    }

    MIU_DEBUG_DBG(u32MIUDbgLevel, "MMIO base:%lx uRegBase:%lx\n", (unsigned long)_gMIU_MapBase, (unsigned long)uRegBase);

    //<0>.Disable SSC bit at the beginnig, and checkout bEnable flag
    HAL_MIU_WriteByte(uRegBase+MIU_SSC_EN,(HAL_MIU_ReadByte(uRegBase+MIU_SSC_EN)&(~0xC0))|0x80);
    if(bEnable == FALSE)
        return true;

    if ((u16Fmodulation<20)||(u16Fmodulation>100))
    {
        MIU_DEBUG_INFO(u32MIUDbgLevel, "SSC u16Fmodulation Error...(20KHz - 100KHz)\n" );
        return 0;
    }

    if ((u16FDeviation<1)||(u16FDeviation>20))
    {
        MIU_DEBUG_INFO(u32MIUDbgLevel, "SSC u16FDeviation Error...(0.1%% - 2%% ==> 1 ~20)\n");
        return 0;
    }

    MIU_DEBUG_DBG(u32MIUDbgLevel, "---> u16Fmodulation = %d u16FDeviation = %d \n",(int)u16Fmodulation,(int)u16FDeviation);

    MsOS_DelayTask(MIU_SSC_DelayTIME_MILLISEC);

    //<1>.Caculate DDFM = (Loop_DIV_First * Loop_DIV_Second)/(Input_DIV_First * Input_DIV_Second);
    //Prepare Input_DIV_First
    u8Temp = ((MS_U16)(HAL_MIU_Read2Byte(uRegBase+MIU_DDRPLL_DIV_FIRST)&0x3));       //Bit 9,8 (0x110D36)
    u16Input_DIV_First = 0x01;
    for (i=0;i<u8Temp;i++)
        u16Input_DIV_First = u16Input_DIV_First << 1;
    //Prepare Input_DIV_Second
    u16Input_DIV_Second = 0;// no mapping in Einstein(HAL_MIU_ReadByte(uRegBase+MIU_PLL_INPUT_DIV_2ND));     //Bit 0~7 (0x101222)
    if (u16Input_DIV_Second == 0)
        u16Input_DIV_Second = 1;
    //Prepare Loop_DIV_First
    u8Temp = ((HAL_MIU_ReadByte(uRegBase+MIU_DDRPLL_DIV_FIRST)&0xC)>>2);         //Bit 11,10 (0x110D36)
    u16Loop_DIV_First = 0x01;
     for (i=0;i<u8Temp;i++)
        u16Loop_DIV_First = u16Loop_DIV_First << 1;

    //Prepare Loop_DIV_Second
    u16Loop_DIV_Second = (HAL_MIU_ReadByte(uRegBase+MIU_PLL_LOOP_DIV_2ND))&0x1F;      //Bit 0~4 (0x101223)
    if (u16Loop_DIV_Second == 0)
        u16Loop_DIV_Second = 1;

    //<2>.From DDFSET register to get DDRPLL
    uDDFSET = HAL_MIU_Read4Byte(uRegBase+MIU_DDFSET) & 0x00ffffff;
    //DDRPLL = MPPL * DDR_FACTOR * Loop_First * Loop_Second / DDFSET * Input_First * Input_Second
    MIU_DEBUG_DBG(u32MIUDbgLevel, "---> Loop_First:%u Loop_Second:%u\n", u16Loop_DIV_First, u16Loop_DIV_Second);
    MIU_DEBUG_DBG(u32MIUDbgLevel, "---> Input_first:%u Input_second:%u\n", u16Input_DIV_First, u16Input_DIV_Second);
    uDDR_MHz = (MPPL * DDR_FACTOR * u16Loop_DIV_First * u16Loop_DIV_Second)/ (uDDFSET*u16Input_DIV_First*u16Input_DIV_Second);
    MIU_DEBUG_DBG(u32MIUDbgLevel, "---> uDDFSET = 0x%lx\n",(unsigned long)uDDFSET);
    MIU_DEBUG_DBG(u32MIUDbgLevel, "---> DDR_MHZ = 0x%lx (%d MHz)\n",(unsigned long)uDDR_MHz,(int)uDDR_MHz);

    //<3>.Caculate DDFSPAN = (MPLL * DDFSPAN_FACTOR * MHz) / (DDFSET * Fmodulation * KHz)
    u16DDFSpan = (MS_U32)((DDFSPAN_FACTOR * MPPL/u16Fmodulation)* 1000/uDDFSET);
    MIU_DEBUG_DBG(u32MIUDbgLevel, "---> DDFSPAN = 0x%x (%d)\n",u16DDFSpan,(int)u16DDFSpan);
    if (u16DDFSpan > 0x3FFF)
    {
        u16DDFSpan = 0x3FFF;
        MIU_DEBUG_DBG(u32MIUDbgLevel, "??? DDFSPAN overflow > 0x3FFF, Fource set to 0x03FF\n");
    }

    //Write to Register
    HAL_MIU_Write2Byte(uRegBase+MIU_DDFSPAN,u16DDFSpan);
    //<4>.Caculate DDFSTEP = (FDeviation*DDFSET/10)/(DDFSPAN*100)
    uDDFStep = (MS_U32)((u16FDeviation * (uDDFSET/10))/(u16DDFSpan*100));
    MIU_DEBUG_DBG(u32MIUDbgLevel, "---> DDFSTEP = 0x%lx (%lu)\n", (unsigned long)uDDFStep, (unsigned long)uDDFStep);
    //Write to Register
    uDDFStep &= (0x03FF);
    HAL_MIU_Write2Byte(uRegBase+MIU_DDFSTEP,(HAL_MIU_Read2Byte(uRegBase+MIU_DDFSTEP) & (~0x03FF))|uDDFStep);

    //<5>.Set ENABLE
    HAL_MIU_WriteByte(uRegBase+MIU_SSC_EN,(HAL_MIU_ReadByte(uRegBase+MIU_SSC_EN)|0xC0));

    return 1;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function \b Name: HAL_MIU_MaskReq()
/// @brief \b Function \b Description: Mask MIU request
/// @param u8Miu  IN        \b  : miu0 or miu1
/// @param eClientID IN     \b  : client ID
/// @param None   OUT       \b  :
/// @param None   RET       \b  :
/// @param None   GLOBAL    \b  :
////////////////////////////////////////////////////////////////////////////////
void HAL_MIU_MaskReq(MS_U8 u8Miu, eMIUClientID eClientID)
{
    MS_U8  u8Val;
    MS_U32 u32Reg;
    MS_S16 sVal;

    sVal = HAL_MIU_GetClientInfo(u8Miu, eClientID);
    if (sVal < 0)
    {
        MIU_DEBUG_INFO(u32MIUDbgLevel, "Not support client ID:%u!\n", eClientID);
        return;
    }
    else
    {
        u8Val = MIU_GET_CLIENT_GROUP(sVal);
        if(u8Val < MIU_MAX_GROUP)
        {
            u32Reg = REG_MIU_RQX_MASK(u8Val);
            u32Reg += MIU_BLOCK_ARBITER_GP1;  //base on group1
        }
        else
        {
            MIU_DEBUG_INFO(u32MIUDbgLevel, "Group:%d exceed MIU_MAX_GROUP!", u8Val);
            return;
        }
        HAL_MIU_ExtWrite2BytesBit(u32Reg, TRUE, BIT(MIU_GET_CLIENT_POS(sVal)));
    }
}

////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function \b Name: HAL_MIU_UnMaskReq()
/// @brief \b Function \b Description: Mask MIU request
/// @param u8Miu  IN        \b  : miu0 or miu1
/// @param eClientID IN      \b  : client ID
/// @param None   OUT       \b  :
/// @param None   RET       \b  :
/// @param None   GLOBAL    \b  :
////////////////////////////////////////////////////////////////////////////////
void HAL_MIU_UnMaskReq(MS_U8 u8Miu, eMIUClientID eClientID)
{
    MS_S16 sVal;
    MS_U8  u8Val;
    MS_U32 u32Reg;

    sVal = HAL_MIU_GetClientInfo(u8Miu, eClientID);
    if (sVal < 0)
    {
        MIU_DEBUG_INFO(u32MIUDbgLevel, "Not support client ID:%u!\n", eClientID);
        return;
    }
    else
    {
        u8Val = MIU_GET_CLIENT_GROUP(sVal);

        if(u8Val < MIU_MAX_GROUP)
        {
            u32Reg = REG_MIU_RQX_MASK(u8Val);
            u32Reg += MIU_BLOCK_ARBITER_GP1;  //base on group1
        }
        else
        {
            MIU_DEBUG_INFO(u32MIUDbgLevel, "Group:%d exceed MIU_MAX_GROUP!", u8Val);
            return;
        }

        HAL_MIU_ExtWrite2BytesBit(u32Reg, FALSE, BIT(MIU_GET_CLIENT_POS(sVal)));
    }
}

////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function \b Name: HAL_MIU_SelMIU()
/// @brief \b Function \b Description: MIU selection
/// @param u8MiuDev    IN   \b  : miu device
/// @param u16ClientID IN   \b  : client ID
/// @param None   OUT       \b  :
/// @param None   RET       \b  :
/// @param None   GLOBAL    \b  :
////////////////////////////////////////////////////////////////////////////////
MS_BOOL HAL_MIU_SelMIU(eMIU_SelType eType, eMIUClientID eClientID)
{
    MIU_DEBUG_INFO(u32MIUDbgLevel, "Not support MIU selection!\n");
    return TRUE;

}

////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function \b Name: MDrv_MIU_Mask_Req_OPM_R()
/// @brief \b Function \b Description: Set OPM MIU mask
/// @param u8Mask IN        \b  : miu mask
/// @param u8Miu  IN        \b  : miu0 or miu1
/// @param None   OUT       \b  :
/// @param None   RET       \b  :
/// @param None   GLOBAL    \b  :
////////////////////////////////////////////////////////////////////////////////
void HAL_MIU_Mask_Req_OPM_R(MS_U8 u8Mask, MS_U8 u8Miu)
{
    _FUNC_NOT_USED();
}


////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function \b Name: HAL_MIU_Mask_Req_DNRB_R()
/// @brief \b Function \b Description: Set OPM MIU mask
/// @param u8Mask IN        \b  : miu mask
/// @param u8Miu  IN        \b  : miu0 or miu1
/// @param None   OUT       \b  :
/// @param None   RET       \b  :
/// @param None   GLOBAL    \b  :
////////////////////////////////////////////////////////////////////////////////
void HAL_MIU_Mask_Req_DNRB_R(MS_U8 u8Mask, MS_U8 u8Miu)
{
    _FUNC_NOT_USED();
}


////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function \b Name: HAL_MIU_Mask_Req_DNRB_W()
/// @brief \b Function \b Description: Set OPM MIU mask
/// @param u8Mask IN        \b  : miu mask
/// @param u8Miu  IN        \b  : miu0 or miu1
/// @param None   OUT       \b  :
/// @param None   RET       \b  :
/// @param None   GLOBAL    \b  :
////////////////////////////////////////////////////////////////////////////////
void HAL_MIU_Mask_Req_DNRB_W(MS_U8 u8Mask, MS_U8 u8Miu)
{
    _FUNC_NOT_USED();
}


////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function \b Name: HAL_MIU_Mask_Req_DNRB_RW()
/// @brief \b Function \b Description: Set OPM MIU mask
/// @param u8Mask IN        \b  : miu mask
/// @param u8Miu  IN        \b  : miu0 or miu1
/// @param None   OUT       \b  :
/// @param None   RET       \b  :
/// @param None   GLOBAL    \b  :
////////////////////////////////////////////////////////////////////////////////
void HAL_MIU_Mask_Req_DNRB_RW(MS_U8 u8Mask, MS_U8 u8Miu)
{
    _FUNC_NOT_USED();
}


////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function \b Name: HAL_MIU_Mask_Req_SC_RW()
/// @brief \b Function \b Description: Set OPM MIU mask
/// @param u8Mask IN        \b  : miu mask
/// @param u8Miu  IN        \b  : miu0 or miu1
/// @param None   OUT       \b  :
/// @param None   RET       \b  :
/// @param None   GLOBAL    \b  :
////////////////////////////////////////////////////////////////////////////////
void HAL_MIU_Mask_Req_SC_RW(MS_U8 u8Mask, MS_U8 u8Miu)
{
    _FUNC_NOT_USED();
}


////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function \b Name: HAL_MIU_Mask_Req_MVOP_R()
/// @brief \b Function \b Description: Set OPM MIU mask
/// @param u8Mask IN        \b  : miu mask
/// @param u8Miu  IN        \b  : miu0 or miu1
/// @param None   OUT       \b  :
/// @param None   RET       \b  :
/// @param None   GLOBAL    \b  :
////////////////////////////////////////////////////////////////////////////////
void HAL_MIU_Mask_Req_MVOP_R(MS_U8 u8Mask, MS_U8 u8Miu)
{
    _FUNC_NOT_USED();
}

////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function \b Name: HAL_MIU_Mask_Req_MVD_R()
/// @brief \b Function \b Description: Set OPM MIU mask
/// @param u8Mask IN        \b  : miu mask
/// @param u8Miu  IN        \b  : miu0 or miu1
/// @param None   OUT       \b  :
/// @param None   RET       \b  :
/// @param None   GLOBAL    \b  :
////////////////////////////////////////////////////////////////////////////////
void HAL_MIU_Mask_Req_MVD_R(MS_U8 u8Mask, MS_U8 u8Miu)
{
    _FUNC_NOT_USED();
}

////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function \b Name: HAL_MIU_Mask_Req_MVD_W()
/// @brief \b Function \b Description: Set OPM MIU mask
/// @param u8Mask IN        \b  : miu mask
/// @param u8Miu  IN        \b  : miu0 or miu1
/// @param None   OUT       \b  :
/// @param None   RET       \b  :
/// @param None   GLOBAL    \b  :
////////////////////////////////////////////////////////////////////////////////
void HAL_MIU_Mask_Req_MVD_W(MS_U8 u8Mask, MS_U8 u8Miu)
{
    _FUNC_NOT_USED();
}


////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function \b Name: HAL_MIU_Mask_Req_MVD_RW()
/// @brief \b Function \b Description: Set OPM MIU mask
/// @param u8Mask IN        \b  : miu mask
/// @param u8Miu  IN        \b  : miu0 or miu1
/// @param None   OUT       \b  :
/// @param None   RET       \b  :
/// @param None   GLOBAL    \b  :
////////////////////////////////////////////////////////////////////////////////
void HAL_MIU_Mask_Req_MVD_RW(MS_U8 u8Mask, MS_U8 u8Miu)
{
    _FUNC_NOT_USED();
}


////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function \b Name: HAL_MIU_Mask_Req_AUDIO_RW()
/// @brief \b Function \b Description: Set OPM MIU mask
/// @param u8Mask IN        \b  : miu mask
/// @param u8Miu  IN        \b  : miu0 or miu1
/// @param None   OUT       \b  :
/// @param None   RET       \b  :
/// @param None   GLOBAL    \b  :
////////////////////////////////////////////////////////////////////////////////
void HAL_MIU_Mask_Req_AUDIO_RW(MS_U8 u8Mask, MS_U8 u8Miu)
{
    _FUNC_NOT_USED();
}

////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function \b Name: HAL_MIU_GET_MUX()
/// @brief \b Function \b Description:
/// @param None IN        \b  :
/// @param None IN        \b  :
/// @param None OUT       \b  :
/// @param None RET       \b  :
/// @param None GLOBAL    \b  :
////////////////////////////////////////////////////////////////////////////////
MS_U16 HAL_MIU_GET_MUX(void)
{
    return 0x0000;
}
#endif

////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function \b Name: HAL_MIU_SwitchMIU()
/// @brief \b Function \b Description:
/// @param u8MiuID        \b IN     : select MIU0 or MIU1
/// @param None \b RET:
////////////////////////////////////////////////////////////////////////////////
void HAL_MIU_VOP_SwitchMIU(MS_U8 u8MiuID)
{
    _FUNC_NOT_USED();
}

////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function \b Name: HAL_MIU_IsI64Mode()
/// @brief \b Function \b Description:
/// @param None \b RET: 0: not support, 64 or 128 bits
////////////////////////////////////////////////////////////////////////////////
MS_U16 HAL_MIU_IsI64Mode(void)
{
    _FUNC_NOT_USED();
    return 0x0000;
}

// UTOPIA remove so dummy code
#ifndef CONFIG_UTOPIAXP_REMOVE_IMPL
////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function \b Name: HAL_MIU_IsInitMiu1()
/// @brief \b Function \b Description:
/// @param None \b RET:
////////////////////////////////////////////////////////////////////////////////
MS_BOOL HAL_MIU_IsInitMiu1(void)
{
    MS_BOOL bRet;
    bRet = (HAL_MIU_Read2Byte(MIU1_REG_BASE) & REG_MIU_INIT_DONE) ? TRUE : FALSE;
    MIU_DEBUG_INFO(u32MIUDbgLevel, "Is support MIU1:%d!\n",bRet);
    return bRet;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function  \b Name: HAL_MIU_SetGroupPriority()
/// @brief \b Function  \b Description:  This function for set each group priority
/// @param u8MiuDev     \b IN   : select MIU0 or MIU1
/// @param sPriority    \b IN   : gropu priority
/// @param None \b RET:   0: Fail 1: Ok
////////////////////////////////////////////////////////////////////////////////
MS_BOOL HAL_MIU_SetGroupPriority(MS_U8 u8MiuDev, MIU_GroupPriority sPriority)
{
    MIU_DEBUG_INFO(u32MIUDbgLevel, "Not support MIU Set Group priority!\n");
    return TRUE;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function  \b Name: HAL_MIU_SetGroupPriority()
/// @brief \b Function  \b Description:  This function for set each group priority
/// @param u8MiuDev     \b IN   : select MIU0 or MIU1
/// @param eClientID    \b IN   : client ID
/// @param bMask        \b IN   : TRUE: Mask high priority FALSE: Unmask hih priority
/// @param None \b RET:   0: Fail 1: Ok
////////////////////////////////////////////////////////////////////////////////
MS_BOOL HAL_MIU_SetHPriorityMask(MS_U8 u8MiuDev, eMIUClientID eClientID, MS_BOOL bMask)
{
    MS_U8  u8Val;
    MS_U32 u32Reg;
    MS_S16 sVal;

    sVal = HAL_MIU_GetClientInfo(u8MiuDev, eClientID);
    if (sVal < 0)
    {
        MIU_DEBUG_INFO(u32MIUDbgLevel, "Not support client ID:%u!\n", eClientID);
        return FALSE;
    }
    else
    {
        u8Val = MIU_GET_CLIENT_GROUP(sVal);

        if(u8Val < MIU_MAX_GROUP)
        {
            u32Reg = REG_MIU_RQX_HPMASK(u8Val);
            u32Reg += MIU_BLOCK_ARBITER_GP1;
        }
        else
        {
            MIU_DEBUG_INFO(u32MIUDbgLevel, "Group:%d exceed MIU_MAX_GROUP!", u8Val);
            return FALSE;
        }
        HAL_MIU_ExtWrite2BytesBit(u32Reg, bMask, BIT(MIU_GET_CLIENT_POS(sVal)));
    }
    return TRUE;
}

MS_BOOL HAL_MIU_GetAutoPhaseResult(MS_U32 *miu0, MS_U32 *miu1)
{
    static MS_U32 u32Miu0 = 0, u32Miu1 = 0;

    *miu0 = u32Miu0;
    *miu1 = u32Miu1;

    return FALSE;
}
#endif

MS_BOOL HAL_MIU_EnableScramble(MS_BOOL bEnable)
{
    return FALSE; // not implemented yet
}

MS_BOOL HAL_MIU_IsScrambleEnabled(void)
{
    return FALSE; // not implemented yet
}

// UTOPIA remove so dummy code
#ifndef CONFIG_UTOPIAXP_REMOVE_IMPL
////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function  \b Name: HAL_MIU_SetLoadingRequest
/// @brief \b Function  \b Description: Set loading request
/// @param u8MiuDev     \b IN   : select MIU0 or MIU1
/// @return             \b 0: Fail 1: OK
////////////////////////////////////////////////////////////////////////////////
MS_BOOL HAL_MIU_SetLoadingRequest(MS_U8 u8MiuDev)
{
    MS_U32 u32RegAddr;

    if (u8MiuDev == 1)
    {
        u32RegAddr = MIU1_BW_REQUEST;
    }
    else
    {
        u32RegAddr = MIU_BW_REQUEST;
    }

    HAL_MIU_Write2Byte(u32RegAddr, 0x0050);
    HAL_MIU_Write2Byte(u32RegAddr, 0x0051);

    return TRUE;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function  \b Name: HAL_MIU_GetLoadingRequest
/// @brief \b Function  \b Description: Get loading request
/// @param u8MiuDev     \b IN   : select MIU0 or MIU1
/// @param *u32Loading  \b IN   : percentage of MIU loading
/// @return             \b 0: Fail 1: OK
////////////////////////////////////////////////////////////////////////////////
MS_BOOL HAL_MIU_GetLoadingRequest(MS_U8 u8MiuDev, MS_U32 *u32Loading)
{
    MS_U16 u16Reg;
    MS_U32 u32RegAddr;

    if (u8MiuDev == 1)
    {
        u32RegAddr = MIU1_BW_RESULT;
    }
    else
    {
        u32RegAddr = MIU_BW_RESULT;
    }

    u16Reg = HAL_MIU_Read2Byte(u32RegAddr);
    *u32Loading =(MS_U32)(u16Reg * 100 / 0x400);

    MIU_DEBUG_INFO(u32MIUDbgLevel, "MIU%d loading: %d%%\n", u8MiuDev, (int)(*u32Loading));

    return TRUE;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function  \b Name: HAL_MIU_ParseOccupiedResource
/// @brief \b Function  \b Description: Parse occupied resource to software structure
/// @return             \b 0: Fail 1: OK
////////////////////////////////////////////////////////////////////////////////
MS_BOOL HAL_MIU_ParseOccupiedResource(void)
{
    MS_U8  u8MiuSel;
    MS_U8  u8Blockx;
    MS_U8  u8ClientID;
    MS_U16 u16idenable;
    MS_U32 u32index;
    MS_U32 u32index2;
    MS_U32 u32RegAddr;
    MS_U32 u32RegAddrG1;
    MS_U32 u32RegAddrIDenable;

    for(u8MiuSel = E_MIU_0; u8MiuSel < MIU_MAX_DEVICE; u8MiuSel++)
    {
        for(u8Blockx = E_MIU_BLOCK_0; u8Blockx < E_MIU_BLOCK_NUM; u8Blockx++)
        {
            if(u8MiuSel == E_MIU_0)
            {
                u32RegAddr = MIU_PROTECT0_ID0;
                u32RegAddrG1 = MIU_PROTECT0_GROUP1_ID0;

                switch (u8Blockx)
                {
                    case E_MIU_BLOCK_0:
                        u32RegAddrIDenable = MIU_PROTECT0_ID_ENABLE;
                        break;
                    case E_MIU_BLOCK_1:
                        u32RegAddrIDenable = MIU_PROTECT1_ID_ENABLE;
                        break;
                    case E_MIU_BLOCK_2:
                        u32RegAddrIDenable = MIU_PROTECT2_ID_ENABLE;
                        break;
                    case E_MIU_BLOCK_3:
                        u32RegAddrIDenable = MIU_PROTECT3_ID_ENABLE;
                        break;
                    case E_MIU_BLOCK_4:
                        u32RegAddrIDenable = MIU_PROTECT4_ID_ENABLE;
                        break;
                    case E_MIU_BLOCK_5:
                        u32RegAddrIDenable = MIU_PROTECT5_ID_ENABLE;
                        break;
                    case E_MIU_BLOCK_6:
                        u32RegAddrIDenable = MIU_PROTECT6_ID_ENABLE;
                        break;
                    case E_MIU_BLOCK_7:
                        u32RegAddrIDenable = MIU_PROTECT7_ID_ENABLE;
                        break;
                    default:
                        return false;
                }
            }
            else
            {
                MIU_DEBUG_INFO(u32MIUDbgLevel, "Not support MIU%u!\n", u8MiuSel );
                return FALSE;
            }

            u16idenable = HAL_MIU_ExtRead2Byte(u32RegAddrIDenable);
            for(u32index = 0; u32index < MIU_MAX_PROTECT_ID; u32index++)
            {
                IDEnables[u8MiuSel][u8Blockx][u32index] = ((u16idenable >> u32index) & 0x1)? 1: 0;
            }
        }//for(u8Blockx = E_MIU_BLOCK_0; u8Blockx < E_MIU_BLOCK_NUM; u8Blockx++)

        for(u32index = 0; u32index < MIU_MAX_PROTECT_ID; u32index++)
        {
            u8ClientID = HAL_MIU_ExtReadByte(u32RegAddr + u32index);
            for(u32index2 = 0; u32index2 < MIU_CLIENT_MAX_NUMBER; u32index2++)
            {
                if( clientTbl[u8MiuSel][u32index2] == u8ClientID )
                {
                    IDs[u8MiuSel][0][u32index] = u32index2;
                    break;
                }
            }
            u8ClientID = HAL_MIU_ExtReadByte(u32RegAddrG1 + u32index);
            for(u32index2 = 0; u32index2 < MIU_CLIENT_MAX_NUMBER; u32index2++)
            {
                if( clientTbl[u8MiuSel][u32index2] == u8ClientID )
                {
                    IDs[u8MiuSel][1][u32index] = u32index2;
                    break;
                }
            }
        }
    }//for(u8MiuSel = E_MIU_0; u8MiuSel < E_MIU_NUM; u8MiuSel++)

    if(u32BWMonitorInitCount == 0)
    {
        u32BWMonitorInitCount++;
        for(u32index = 0; u32index < MIU_MAX_DEVICE; ++u32index)
        {
           HAL_MIU_Reset_All_BW_Monitor(u32index);
        }
    }

    return TRUE;
}


void HAL_MIU_PrintMIUProtectArea(MS_U8 u8Blockx,MS_U8 miu_dev)
{

    MS_U32 val_32;
    MS_U32 u32RegAddrStar;

    if( miu_dev == E_MIU_0 )
    {
        switch (u8Blockx)
        {
            case 0:
                u32RegAddrStar = MIU_PROTECT0_START;
                break;
            case 1:
                u32RegAddrStar = MIU_PROTECT1_START;
                break;
            case 2:
                u32RegAddrStar = MIU_PROTECT2_START;
                break;
            case 3:
                u32RegAddrStar = MIU_PROTECT3_START;
                break;
            case 4:
                u32RegAddrStar = MIU_PROTECT4_START;
                break;
            case 5:
                u32RegAddrStar = MIU_PROTECT5_START;
                break;
            case 6:
                u32RegAddrStar = MIU_PROTECT6_START;
                break;
            case 7:
                u32RegAddrStar = MIU_PROTECT7_START;
                break;
            default:
                MIU_DEBUG_INFO(u32MIUDbgLevel, "error miu protect block number\n");
                return;
        }
    }
    else if( miu_dev == E_MIU_1 )
    {
        switch (u8Blockx)
        {
            case 0:
                u32RegAddrStar = MIU1_PROTECT0_START;
                break;
            case 1:
                u32RegAddrStar = MIU1_PROTECT1_START;
                break;
            case 2:
                u32RegAddrStar = MIU1_PROTECT2_START;
                break;
            case 3:
                u32RegAddrStar = MIU1_PROTECT3_START;
                break;
            case 4:
                u32RegAddrStar = MIU1_PROTECT4_START;
                break;
            case 5:
                u32RegAddrStar = MIU1_PROTECT5_START;
                break;
            case 6:
                u32RegAddrStar = MIU1_PROTECT6_START;
                break;
            case 7:
                u32RegAddrStar = MIU1_PROTECT7_START;
                break;
            default:
                MIU_DEBUG_INFO(u32MIUDbgLevel, "error miu protect block number\n");
                return ;
        }
    }
    else
    {
        MIU_DEBUG_INFO(u32MIUDbgLevel, "Not support MIU%u!\n", miu_dev);
        return;
    }
    //protect start address
    val_32 = HAL_MIU_ExtRead4Byte(u32RegAddrStar)& 0x000FFFFF;
    MIU_DEBUG_PRI(u32MIUDbgLevel, "miu%d protect%d startaddr is 0x%tX\n", miu_dev, u8Blockx, (ptrdiff_t)val_32);

    //protect end address
    val_32 = HAL_MIU_ExtRead4Byte(u32RegAddrStar+0x4)& 0x000FFFFF;
    MIU_DEBUG_PRI(u32MIUDbgLevel, "miu%d protect%d endaddr   is 0x%x\n", miu_dev, u8Blockx, (unsigned int)val_32);
}

void HAL_MIU_PrintMIUProtectInfo(void)
{
    MS_U32 u32MiuProtectEn;
    MS_U32 u32MiuProtectIdEn;

    MS_U16 val_16;

    u32MiuProtectEn = MIU_PROTECT_EN;

    u32MiuProtectIdEn= MIU_PROTECT0_ID_ENABLE;
    val_16 = HAL_MIU_ExtReadByte(u32MiuProtectEn);

    if ( (val_16 & 0xff) != 0 )
    {
        MIU_DEBUG_PRI(u32MIUDbgLevel, "miu0 protect is enabled\n");

        //protect_ID_enable information
        val_16 =HAL_MIU_ExtRead2Byte(u32MiuProtectIdEn);
        if ( val_16 != 0 )
        {
            MIU_DEBUG_PRI(u32MIUDbgLevel, "miu0 protect0_ID_enable is 0x%x\n",val_16);
            HAL_MIU_PrintMIUProtectArea(0,0);
        }

        u32MiuProtectIdEn= MIU_PROTECT1_ID_ENABLE;
        val_16 =HAL_MIU_ExtRead2Byte(u32MiuProtectIdEn);
        if ( val_16 != 0 )
        {
            MIU_DEBUG_PRI(u32MIUDbgLevel, "miu0 protect1_ID_enable is 0x%x\n",val_16);
            HAL_MIU_PrintMIUProtectArea(1,0);
        }

        u32MiuProtectIdEn= MIU_PROTECT2_ID_ENABLE;
        val_16 =HAL_MIU_ExtRead2Byte(u32MiuProtectIdEn);
        if ( val_16 != 0 )
        {
            MIU_DEBUG_PRI(u32MIUDbgLevel, "miu0 protect2_ID_enable is 0x%x\n",val_16);
            HAL_MIU_PrintMIUProtectArea(2,0);
        }

        u32MiuProtectIdEn= MIU_PROTECT3_ID_ENABLE;
        val_16 =HAL_MIU_ExtRead2Byte(u32MiuProtectIdEn);
        if ( val_16 != 0 )
        {
            MIU_DEBUG_PRI(u32MIUDbgLevel, "miu0 protect3_ID_enable is 0x%x\n",val_16);
            HAL_MIU_PrintMIUProtectArea(3,0);
        }

        u32MiuProtectIdEn= MIU_PROTECT4_ID_ENABLE;
        val_16 =HAL_MIU_ExtRead2Byte(u32MiuProtectIdEn);
        if ( val_16 != 0 )
        {
            MIU_DEBUG_PRI(u32MIUDbgLevel, "miu0 protect3_ID_enable is 0x%x\n",val_16);
            HAL_MIU_PrintMIUProtectArea(4,0);
        }

        u32MiuProtectIdEn= MIU_PROTECT5_ID_ENABLE;
        val_16 =HAL_MIU_ExtRead2Byte(u32MiuProtectIdEn);
        if ( val_16 != 0 )
        {
            MIU_DEBUG_PRI(u32MIUDbgLevel, "miu0 protect3_ID_enable is 0x%x\n",val_16);
            HAL_MIU_PrintMIUProtectArea(5,0);
        }

        u32MiuProtectIdEn= MIU_PROTECT6_ID_ENABLE;
        val_16 =HAL_MIU_ExtRead2Byte(u32MiuProtectIdEn);
        if ( val_16 != 0 )
        {
            MIU_DEBUG_PRI(u32MIUDbgLevel, "miu0 protect3_ID_enable is 0x%x\n",val_16);
            HAL_MIU_PrintMIUProtectArea(6,0);
        }

        u32MiuProtectIdEn= MIU_PROTECT7_ID_ENABLE;
        val_16 =HAL_MIU_ExtRead2Byte(u32MiuProtectIdEn);
        if ( val_16 != 0 )
        {
            MIU_DEBUG_PRI(u32MIUDbgLevel, "miu0 protect3_ID_enable is 0x%x\n",val_16);
            HAL_MIU_PrintMIUProtectArea(7,0);
        }
    }
    else
    {
        MIU_DEBUG_PRI(u32MIUDbgLevel, "miu0 protect is not enabled\n");
    }

    u32MiuProtectEn=MIU1_PROTECT_EN;
    val_16 = HAL_MIU_ExtReadByte(u32MiuProtectEn);

    if ( (val_16 & 0xff) != 0x0 )
    {
        MIU_DEBUG_PRI(u32MIUDbgLevel, "miu1 protect is enabled\n");

        //protect_ID_enable information
        u32MiuProtectIdEn= MIU1_PROTECT0_ID_ENABLE;
        val_16 =HAL_MIU_ExtRead2Byte(u32MiuProtectIdEn);
        if ( val_16 != 0 )
        {
            MIU_DEBUG_PRI(u32MIUDbgLevel, "miu1 protect0_ID_enable is 0x%x\n",val_16);
            HAL_MIU_PrintMIUProtectArea(0,1);
        }

        u32MiuProtectIdEn= MIU1_PROTECT1_ID_ENABLE;
        val_16 =HAL_MIU_ExtRead2Byte(u32MiuProtectIdEn);
        if ( val_16 != 0 )
        {
            MIU_DEBUG_PRI(u32MIUDbgLevel, "miu1 protect1_ID_enable is 0x%x\n",val_16);
            HAL_MIU_PrintMIUProtectArea(1,1);
        }

        u32MiuProtectIdEn= MIU1_PROTECT2_ID_ENABLE;
        val_16 =HAL_MIU_ExtRead2Byte(u32MiuProtectIdEn);
        if ( val_16 != 0 )
        {
            MIU_DEBUG_PRI(u32MIUDbgLevel, "miu1 protect2_ID_enable is 0x%x\n",val_16);
            HAL_MIU_PrintMIUProtectArea(2,1);
        }

        u32MiuProtectIdEn= MIU1_PROTECT3_ID_ENABLE;
        val_16 =HAL_MIU_ExtRead2Byte(u32MiuProtectIdEn);
        if ( val_16 != 0 )
        {
            MIU_DEBUG_PRI(u32MIUDbgLevel, "miu1 protect3_ID_enable is 0x%x\n",val_16);
            HAL_MIU_PrintMIUProtectArea(3,1);
        }

        u32MiuProtectIdEn= MIU1_PROTECT4_ID_ENABLE;
        val_16 =HAL_MIU_ExtRead2Byte(u32MiuProtectIdEn);
        if ( val_16 != 0 )
        {
            MIU_DEBUG_PRI(u32MIUDbgLevel, "miu1 protect3_ID_enable is 0x%x\n",val_16);
            HAL_MIU_PrintMIUProtectArea(4,1);
        }

        u32MiuProtectIdEn= MIU1_PROTECT5_ID_ENABLE;
        val_16 =HAL_MIU_ExtRead2Byte(u32MiuProtectIdEn);
        if ( val_16 != 0 )
        {
            MIU_DEBUG_PRI(u32MIUDbgLevel, "miu1 protect3_ID_enable is 0x%x\n",val_16);
            HAL_MIU_PrintMIUProtectArea(5,1);
        }

        u32MiuProtectIdEn= MIU1_PROTECT6_ID_ENABLE;
        val_16 =HAL_MIU_ExtRead2Byte(u32MiuProtectIdEn);
        if ( val_16 != 0 )
        {
            MIU_DEBUG_PRI(u32MIUDbgLevel, "miu1 protect3_ID_enable is 0x%x\n",val_16);
            HAL_MIU_PrintMIUProtectArea(6,1);
        }

        u32MiuProtectIdEn= MIU1_PROTECT7_ID_ENABLE;
        val_16 =HAL_MIU_ExtRead2Byte(u32MiuProtectIdEn);
        if ( val_16 != 0 )
        {
            MIU_DEBUG_PRI(u32MIUDbgLevel, "miu1 protect3_ID_enable is 0x%x\n",val_16);
            HAL_MIU_PrintMIUProtectArea(7,1);
        }
    }
    else
    {
        MIU_DEBUG_PRI(u32MIUDbgLevel, "miu1 protect is not enabled\n");

    }

}
#endif

////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function  \b Name: HAL_MIU_GetClientWidth
/// @brief \b Function  \b Description: Get MIU client bus width
/// @param u8MiuDev     \b IN   : select MIU0 or MIU1
/// @param eClientID    \b IN   : client ID
/// @param pClientWidth \b IN   : client bus width
/// @return             \b 0 : Fail  1: OK
////////////////////////////////////////////////////////////////////////////////
MS_BOOL HAL_MIU_GetClientWidth(MS_U8 u8MiuDevi, eMIUClientID eClientID, eMIU_ClientWidth *pClientWidth)
{
    MIU_DEBUG_INFO(u32MIUDbgLevel, "Not support !\n");
    return TRUE;
}

// UTOPIA remove so dummy code
#ifndef CONFIG_UTOPIAXP_REMOVE_IMPL
MS_BOOL HAL_MIU_GetDramType(MS_U32 eMiu, MIU_DDR_TYPE* pType)
{
    MS_U32 u32Reg;

    if (eMiu >= MIU_MAX_DEVICE)
        return FALSE;

    switch (eMiu)
    {
        case 0:
            u32Reg = REG_MIU_DDR_STATUS;
            break;
        default:
            return FALSE;
    }

    if (HAL_MIU_Read2Byte(u32Reg)& REG_MIU_DDR4)
    {
        *pType = E_MIU_DDR4;
    }
    else
    {
        *pType = E_MIU_DDR3;
    }

    return TRUE;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function  \b Name: HAL_MIU_Write_BW_Monitor_Id
/// @brief \b Function  \b Description: Write BW monitor ID into reg
/// @param u8MiuDev     \b IN   : select MIU0 or MIU1
/// @param u8writeId    \b IN   : Write index(0~63)
/// @param u8writeValue \b IN   : client IP ID
/// @param bGroupENABLE  \b IN   : ENABLE or DISABLE the client' group
/// @return             \b 0 : Fail  1: OK
////////////////////////////////////////////////////////////////////////////////
static MS_BOOL HAL_MIU_Write_BW_Monitor_Id(MS_U8 u8MiuDev, MS_U32 u32writeId, MS_U32 u32writeValue, MS_BOOL bGroupENABLE)
{
    MS_U32 u32WRegID;
    MS_U32 u32WRegValue;
    MS_U32 u32WRegEnable;

    switch(u8MiuDev)
    {
        case E_MIU_0:
            u32WRegID = MIU_BW_MONITOR_WRI_ID;
            u32WRegValue = MIU_BW_MONITOR_WRI_EN;
            u32WRegEnable = MIU_BW_MONITOR_READ;
            break;

        default:
            return FALSE;
    }

    //fill in write id
    HAL_MIU_WriteByte(u32WRegID, u32writeId);

    //fill in write client id value
    HAL_MIU_WriteByte(u32WRegValue, u32writeValue);

    //fill in client id enable
    HAL_MIU_WriteRegBit(u32WRegEnable,BIT0,bGroupENABLE);

    //toggle write bit
    HAL_MIU_WriteRegBit(u32WRegID,BIT7,ENABLE);
    HAL_MIU_WriteRegBit(u32WRegID,BIT7,DISABLE);

    return TRUE;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function  \b Name: HAL_MIU_Set_BW_Monitor
/// @brief \b Function  \b Description: Set Bandwidth monitor client ID
/// @param u8MiuDev     \b IN   : select MIU0 or MIU1
/// @param pBWInfo      \b IN   : bandwidth information
/// @return             \b 0 : Fail  1: OK
////////////////////////////////////////////////////////////////////////////////
MS_BOOL HAL_MIU_Set_BW_Monitor(MS_U8 u8MiuDev, MIU_BandwidthMonitorInfo *pBWInfo)
{
    MS_U8 u8Index1, u8Index2;
    MS_U8 u8tmpCount;
    MS_U32 u32writeId;
    MS_U32 u32getMonId = E_MONITOR_INIT;
    MS_S32 s32MPLLTShift;
    MS_U64 u64UpdateFreq;

    if( u8MiuDev != E_MIU_CHANNEL_ALL && u8MiuDev != E_MIU_CHANNEL_0 && u8MiuDev != E_MIU_CHANNEL_1 )
    {
        MIU_DEBUG_INFO(u32MIUDbgLevel, "Not support MIU Channel%u!\n", u8MiuDev);
        return FALSE;
    }

    //Set Freeze bit enable
    HAL_MIU_WriteRegBit(MIU_BW_MONITOR_READ, BIT3, ENABLE);

    //Mask Channel bit
    HAL_MIU_WriteRegBit(MIU_BW_MONITOR_READ, (BIT4|BIT5), DISABLE);
    if( u8MiuDev == E_MIU_CHANNEL_0 )
    {
        HAL_MIU_WriteRegBit(MIU_BW_MONITOR_READ, BIT5, ENABLE);
    }
    else if( u8MiuDev == E_MIU_CHANNEL_1 )
    {
        HAL_MIU_WriteRegBit(MIU_BW_MONITOR_READ, BIT4, ENABLE);
    }

    //only one MIU setting in UMA MODE
    u8MiuDev = E_MIU_0;

    ///find monitor ID
    if(pBWInfo->u32MonitorIndex == E_MONITOR_INIT)
    {
        ///init : find empty monitor
        for(u8Index1 = 0; u8Index1 < MIU_MAX_BW_MONITOR_GROUP_NUMBER; ++u8Index1)
        {
            u8tmpCount = 0;
            for(u8Index2 = 0; u8Index2 < MIU_MAX_BW_MONITOR_GP_CLIENT_NUMBER; ++u8Index2)
            {
                if(MonitorId[u8MiuDev][u8Index1][u8Index2] == MIU_BW_MON_NON_ID)
                {
                    u8tmpCount++;
                }
            }
            if(u8tmpCount == MIU_MAX_BW_MONITOR_GP_CLIENT_NUMBER)
            {
                u32getMonId = u8Index1;
                pBWInfo->u32MonitorIndex = u32getMonId;
                break;
            }
        }
        //can not find empty monitor
        if(u32getMonId == E_MONITOR_INIT)
        {
            MIU_DEBUG_INFO(u32MIUDbgLevel, "No empty monitor!\n");
            return FALSE;
        }
    }

    if(pBWInfo->u32MonitorIndex >= MIU_MAX_BW_MONITOR_GROUP_NUMBER)
    {
        MIU_DEBUG_INFO(u32MIUDbgLevel, "Not support monitor index%u!\n", (int)pBWInfo->u32MonitorIndex);
        return FALSE;
    }
    else
    {
        //appoint monitor
        u32getMonId = pBWInfo->u32MonitorIndex;
    }

    ///reset monitor
    HAL_MIU_Del_BW_Monitor(u8MiuDev, pBWInfo);

    ///set BW Time counter
    if(pBWInfo->stSamplingFrequency.u32UpdateFrequencyValue > 0 )
    {
        u32CurrentUpdateFrequencyValue = pBWInfo->stSamplingFrequency.u32UpdateFrequencyValue;
    }
    else
    {
        switch(pBWInfo->stSamplingFrequency.eSamplingSection)
        {
            case E_MONITOR_FREQUENCY_1:
                u32CurrentUpdateFrequencyValue = MIU_BW_MON_FREQUENCY_1_MS;
                break;
            case E_MONITOR_FREQUENCY_2:
                u32CurrentUpdateFrequencyValue = MIU_BW_MON_FREQUENCY_2_MS;
                break;
            case E_MONITOR_FREQUENCY_3:
                u32CurrentUpdateFrequencyValue = MIU_BW_MON_FREQUENCY_3_MS;
                break;
            case E_MONITOR_FREQUENCY_4:
                u32CurrentUpdateFrequencyValue = MIU_BW_MON_FREQUENCY_4_MS;
                break;
            case E_MONITOR_FREQUENCY_5:
                u32CurrentUpdateFrequencyValue = MIU_BW_MON_FREQUENCY_5_MS;
                break;
            case E_MONITOR_FREQUENCY_6:
                u32CurrentUpdateFrequencyValue = MIU_BW_MON_FREQUENCY_6_MS;
                break;
            case E_MONITOR_FREQUENCY_7:
                u32CurrentUpdateFrequencyValue = MIU_BW_MON_FREQUENCY_7_MS;
                break;
            case E_MONITOR_FREQUENCY_8:
                u32CurrentUpdateFrequencyValue = MIU_BW_MON_FREQUENCY_8_MS;
                break;
            case E_MONITOR_FREQUENCY_9:
                u32CurrentUpdateFrequencyValue = MIU_BW_MON_FREQUENCY_9_MS;
                break;
            default:
                MIU_DEBUG_INFO(u32MIUDbgLevel, "Not support bandwidth time counter %u!\n", (int)pBWInfo->stSamplingFrequency.eSamplingSection);
                return FALSE;
        }
    }

    // mpll clk cycle = 2.3148 ns(432MHz)
    // mpll period = (update_freq(ms) * 1000000) / ( 4 * 1024 * mpll_clk_cycle)
    s32MPLLTShift = MPLL_T * 4096;    //shift 12bits
    u64UpdateFreq = ((MS_U64)u32CurrentUpdateFrequencyValue * 1000000)/s32MPLLTShift;
    HAL_MIU_Write2Byte(MIU_BW_MONITOR_MPLL_PERIOD, (MS_U16)u64UpdateFreq );

    ///set IDs
    if(!pBWInfo->bMonitorAllMIU)
    {
        for(u8Index1 = 0; u8Index1 < MIU_MAX_BW_MONITOR_GP_CLIENT_NUMBER; ++u8Index1)
        {
            MS_S32 sVal;

            switch((eMIUClientID)pBWInfo->u32MonitorId[u8Index1])
            {
                case MIU_CLIENT_MONITOR_GROUP0:
                    MonitorId[u8MiuDev][u32getMonId][u8Index1] = 0x1;
                    u32writeId = u32getMonId * MIU_MAX_BW_MONITOR_GP_CLIENT_NUMBER + u8Index1;
                    HAL_MIU_Write_BW_Monitor_Id(u8MiuDev, u32writeId, 0x1, TRUE);
                    continue;

                case MIU_CLIENT_MONITOR_GROUP1:
                    MonitorId[u8MiuDev][u32getMonId][u8Index1] = 0x10;
                    u32writeId = u32getMonId * MIU_MAX_BW_MONITOR_GP_CLIENT_NUMBER + u8Index1;
                    HAL_MIU_Write_BW_Monitor_Id(u8MiuDev, u32writeId, 0x10, TRUE);
                    continue;

                case MIU_CLIENT_MONITOR_GROUP2:
                    MonitorId[u8MiuDev][u32getMonId][u8Index1] = 0x20;
                    u32writeId = u32getMonId * MIU_MAX_BW_MONITOR_GP_CLIENT_NUMBER + u8Index1;
                    HAL_MIU_Write_BW_Monitor_Id(u8MiuDev, u32writeId, 0x20, TRUE);
                    continue;

                case MIU_CLIENT_MONITOR_GROUP3:
                    MonitorId[u8MiuDev][u32getMonId][u8Index1] = 0x30;
                    u32writeId = u32getMonId * MIU_MAX_BW_MONITOR_GP_CLIENT_NUMBER + u8Index1;
                    HAL_MIU_Write_BW_Monitor_Id(u8MiuDev, u32writeId, 0x30, TRUE);
                    continue;

                case MIU_CLIENT_MONITOR_GROUP4:
                    MonitorId[u8MiuDev][u32getMonId][u8Index1] = 0x40;
                    u32writeId = u32getMonId * MIU_MAX_BW_MONITOR_GP_CLIENT_NUMBER + u8Index1;
                    HAL_MIU_Write_BW_Monitor_Id(u8MiuDev, u32writeId, 0x40, TRUE);
                    continue;

                case MIU_CLIENT_MONITOR_GROUP5:
                    MonitorId[u8MiuDev][u32getMonId][u8Index1] = 0x50;
                    u32writeId = u32getMonId * MIU_MAX_BW_MONITOR_GP_CLIENT_NUMBER + u8Index1;
                    HAL_MIU_Write_BW_Monitor_Id(u8MiuDev, u32writeId, 0x50, TRUE);
                    continue;

                case MIU_CLIENT_MONITOR_GROUP6:
                    MonitorId[u8MiuDev][u32getMonId][u8Index1] = 0x60;
                    u32writeId = u32getMonId * MIU_MAX_BW_MONITOR_GP_CLIENT_NUMBER + u8Index1;
                    HAL_MIU_Write_BW_Monitor_Id(u8MiuDev, u32writeId, 0x60, TRUE);
                    continue;

                case MIU_CLIENT_MONITOR_GROUP7:
                    MonitorId[u8MiuDev][u32getMonId][u8Index1] = 0x70;
                    u32writeId = u32getMonId * MIU_MAX_BW_MONITOR_GP_CLIENT_NUMBER + u8Index1;
                    HAL_MIU_Write_BW_Monitor_Id(u8MiuDev, u32writeId, 0x70, TRUE);
                    continue;

                case MIU_CLIENT_MONITOR_GROUP8:
                    MonitorId[u8MiuDev][u32getMonId][u8Index1] = 0x80;
                    u32writeId = u32getMonId * MIU_MAX_BW_MONITOR_GP_CLIENT_NUMBER + u8Index1;
                    HAL_MIU_Write_BW_Monitor_Id(u8MiuDev, u32writeId, 0x80, TRUE);
                    continue;

                default:
                    break;
            }

            if( (eMIUClientID)pBWInfo->u32MonitorId[u8Index1] == MIU_CLIENT_DUMMY)
            {
                sVal = MIU_BW_MON_NON_ID;
            }
            else
            {
                sVal = HAL_MIU_GetClientInfo(u8MiuDev, (eMIUClientID)pBWInfo->u32MonitorId[u8Index1]);
                if(sVal <= 0)
                {
                    continue;
                }
            }

            MonitorId[u8MiuDev][u32getMonId][u8Index1] = sVal;

            MS_U32 u32writeId = u32getMonId * MIU_MAX_BW_MONITOR_GP_CLIENT_NUMBER + u8Index1;
            HAL_MIU_Write_BW_Monitor_Id(u8MiuDev, u32writeId, sVal, FALSE);
        }
    }
    else
    {
        u8Index1 = 0;
        MonitorId[u8MiuDev][u32getMonId][u8Index1] = MIU_CLIENT_NONE;

        u32writeId = u32getMonId * MIU_MAX_BW_MONITOR_GP_CLIENT_NUMBER + u8Index1;
        HAL_MIU_Write_BW_Monitor_Id(u8MiuDev, u32writeId, MIU_CLIENT_NONE, FALSE);
    }

    //Set Area Enable bit
    if(pBWInfo->bMonitorAreaEn == TRUE)
    {
        HAL_MIU_WriteRegBit(MIU_BW_MONITOR_READ, BIT6, ENABLE);
    }
    else
    {
        HAL_MIU_WriteRegBit(MIU_BW_MONITOR_READ, BIT6, DISABLE);
    }

    //Set Freeze bit disable
    HAL_MIU_WriteRegBit(MIU_BW_MONITOR_READ, BIT3, DISABLE);

    return TRUE;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function  \b Name: HAL_MIU_Del_BW_Monitor
/// @brief \b Function  \b Description: Delete Bandwidth monitor client ID
/// @param u8MiuDev     \b IN   : select MIU0 or MIU1
/// @param pBWInfo      \b IN   : bandwidth information
/// @return             \b 0 : Fail  1: OK
////////////////////////////////////////////////////////////////////////////////

MS_BOOL HAL_MIU_Del_BW_Monitor(MS_U8 u8MiuDev, MIU_BandwidthMonitorInfo *pBWInfo)
{
    MS_U8 u8Index1 = 0;
    MS_U32 u32writeId;
    MS_U32 u32getMonId;

    //only one MIU setting in UMA MODE
    u8MiuDev = E_MIU_0;

    if(pBWInfo->u32MonitorIndex >= MIU_MAX_BW_MONITOR_GP_CLIENT_NUMBER)
    {
        MIU_DEBUG_INFO(u32MIUDbgLevel, "Not support monitor index%u!\n", (int)pBWInfo->u32MonitorIndex);
        return FALSE;
    }
    else
    {
        u32getMonId = pBWInfo->u32MonitorIndex;
    }

    for(u8Index1 = 0; u8Index1 < MIU_MAX_BW_MONITOR_GP_CLIENT_NUMBER; ++u8Index1)
    {
        MonitorId[u8MiuDev][u32getMonId][u8Index1] = MIU_BW_MON_NON_ID;

        u32writeId = u32getMonId * MIU_MAX_BW_MONITOR_GP_CLIENT_NUMBER + u8Index1;
        HAL_MIU_Write_BW_Monitor_Id(u8MiuDev, u32writeId, MIU_BW_MON_NON_ID, DISABLE);
    }

    return TRUE;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function  \b Name: HAL_MIU_Query_BW_Monitor
/// @brief \b Function  \b Description: Query Bandwidth monitor client ID
/// @param u8MiuDev     \b IN   : select MIU0 or MIU1
/// @param pBWInfo      \b IN   : bandwidth information
/// @return             \b 0 : Fail  1: OK
////////////////////////////////////////////////////////////////////////////////

MS_BOOL HAL_MIU_Query_BW_Monitor(MS_U8 u8MiuDev, MIU_BandwidthMonitorInfo *pBWInfo)
{
    MS_U8 u8Index1 = 0;
    MS_U32 u32getMonId;

    //only one MIU setting in UMA MODE
    u8MiuDev = E_MIU_0;

    if(pBWInfo->u32MonitorIndex >= MIU_MAX_BW_MONITOR_GROUP_NUMBER)
    {
        MIU_DEBUG_INFO(u32MIUDbgLevel, "Not support monitor index%u!\n", (int)pBWInfo->u32MonitorIndex);
        return FALSE;
    }
    else
    {
        u32getMonId = pBWInfo->u32MonitorIndex;
    }

    ///get current bandwidth update frequency
    pBWInfo->stSamplingFrequency.u32UpdateFrequencyValue = u32CurrentUpdateFrequencyValue;
    switch(u32CurrentUpdateFrequencyValue)
    {
        case MIU_BW_MON_FREQUENCY_1_MS:
            pBWInfo->stSamplingFrequency.eSamplingSection = E_MONITOR_FREQUENCY_1;
            break;
        case MIU_BW_MON_FREQUENCY_2_MS:
            pBWInfo->stSamplingFrequency.eSamplingSection = E_MONITOR_FREQUENCY_2;
            break;
        case MIU_BW_MON_FREQUENCY_3_MS:
            pBWInfo->stSamplingFrequency.eSamplingSection = E_MONITOR_FREQUENCY_3;
            break;
        case MIU_BW_MON_FREQUENCY_4_MS:
            pBWInfo->stSamplingFrequency.eSamplingSection = E_MONITOR_FREQUENCY_4;
            break;
        case MIU_BW_MON_FREQUENCY_5_MS:
            pBWInfo->stSamplingFrequency.eSamplingSection = E_MONITOR_FREQUENCY_5;
            break;
        case MIU_BW_MON_FREQUENCY_6_MS:
            pBWInfo->stSamplingFrequency.eSamplingSection = E_MONITOR_FREQUENCY_6;
            break;
        case MIU_BW_MON_FREQUENCY_7_MS:
            pBWInfo->stSamplingFrequency.eSamplingSection = E_MONITOR_FREQUENCY_7;
            break;
        case MIU_BW_MON_FREQUENCY_8_MS:
            pBWInfo->stSamplingFrequency.eSamplingSection = E_MONITOR_FREQUENCY_8;
            break;
        case MIU_BW_MON_FREQUENCY_9_MS:
            pBWInfo->stSamplingFrequency.eSamplingSection = E_MONITOR_FREQUENCY_9;
            break;
        default:
            pBWInfo->stSamplingFrequency.eSamplingSection = E_MONITOR_FREQUENCY_1;
            break;
    }

    //get Client IDs
    for(u8Index1 = 0; u8Index1 < MIU_MAX_BW_MONITOR_GP_CLIENT_NUMBER; ++u8Index1)
    {
        if(u8Index1 == E_MONITOR_INDEX_0 && MonitorId[u8MiuDev][u32getMonId][u8Index1] == E_MONITOR_INDEX_0)
        {
            pBWInfo->bMonitorAllMIU = TRUE;
        }
        pBWInfo->u32MonitorId[u8Index1] = MonitorId[u8MiuDev][u32getMonId][u8Index1];
    }

    return TRUE;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function  \b Name: HAL_MIU_Get_BW
/// @brief \b Function  \b Description: Get Bandwidth monitor value
//// @param u8MiuDev     \b IN   : select MIU0 or MIU1
/// @param pBWInfo      \b IN   : bandwidth information
/// @return             \b 0 : Fail  1: OK
////////////////////////////////////////////////////////////////////////////////
MS_BOOL HAL_MIU_Get_BW(MS_U8 u8MiuDev, MIU_BandwidthMonitorInfo *pBWInfo)
{
    MS_U32 u32getMonId;
    MS_U32 u32RRegValue;

    MS_U64 u64OcpyReport;
    MS_U64 u64MaxOcpyReport;
    MS_U64 u64BWReport;
    MS_U64 u64MaxBWReport;
    MS_U64 u64MIUCLKTime;

    if(!MIU_BW_MONITOR)
    {
        MIU_DEBUG_INFO(u32MIUDbgLevel, "This chip not support MIU BANDWIDTH MONITOR HARDWARE!!!\n");
    }

    //only one MIU setting in UMA MODE

    if(pBWInfo->u32MonitorIndex >= MIU_MAX_BW_MONITOR_GROUP_NUMBER)
    {
        MIU_DEBUG_INFO(u32MIUDbgLevel, "Not support monitor index%u!\n", (int)pBWInfo->u32MonitorIndex);
        return FALSE;
    }
    else
    {
        u32getMonId = pBWInfo->u32MonitorIndex;
    }

    //Read value RIU
    u32RRegValue =  MIU_BW_MONITOR0 + (u32getMonId * 2);

    //Set Freeze bit
    HAL_MIU_WriteRegBit(MIU_BW_MONITOR_READ, BIT3, ENABLE);

    //Read BW data
    // occupy cycle
    HAL_MIU_WriteRegBit(MIU_BW_MONITOR_SEL, (BIT4|BIT5|BIT6|BIT7), DISABLE);
    u64OcpyReport = HAL_MIU_Read2Byte(u32RRegValue);
    HAL_MIU_WriteRegBit(MIU_BW_MONITOR_SEL, (BIT4|BIT5|BIT6|BIT7), DISABLE);
    HAL_MIU_WriteRegBit(MIU_BW_MONITOR_SEL, (BIT4), ENABLE);
    u64OcpyReport = u64OcpyReport + (MS_U64)( HAL_MIU_Read2Byte(u32RRegValue) << 16 );
    // max occupy cycle
    HAL_MIU_WriteRegBit(MIU_BW_MONITOR_SEL, (BIT4|BIT5|BIT6|BIT7), DISABLE);
    HAL_MIU_WriteRegBit(MIU_BW_MONITOR_SEL, (BIT5), ENABLE);
    u64MaxOcpyReport = HAL_MIU_Read2Byte(u32RRegValue);
    HAL_MIU_WriteRegBit(MIU_BW_MONITOR_SEL, (BIT4|BIT5|BIT6|BIT7), DISABLE);
    HAL_MIU_WriteRegBit(MIU_BW_MONITOR_SEL, (BIT4|BIT5), ENABLE);
    u64MaxOcpyReport = u64MaxOcpyReport + (MS_U64)( HAL_MIU_Read2Byte(u32RRegValue) << 16 );
    // bw cycle
    HAL_MIU_WriteRegBit(MIU_BW_MONITOR_SEL, (BIT4|BIT5|BIT6|BIT7), DISABLE);
    HAL_MIU_WriteRegBit(MIU_BW_MONITOR_SEL, (BIT6), ENABLE);
    u64BWReport = HAL_MIU_Read2Byte(u32RRegValue);
    HAL_MIU_WriteRegBit(MIU_BW_MONITOR_SEL, (BIT4|BIT5|BIT6|BIT7), DISABLE);
    HAL_MIU_WriteRegBit(MIU_BW_MONITOR_SEL, (BIT4|BIT6), ENABLE);
    u64BWReport = u64BWReport + (MS_U64)( HAL_MIU_Read2Byte(u32RRegValue) << 16 );
    // max bw cycle
    HAL_MIU_WriteRegBit(MIU_BW_MONITOR_SEL, (BIT4|BIT5|BIT6|BIT7), DISABLE);
    HAL_MIU_WriteRegBit(MIU_BW_MONITOR_SEL, (BIT5|BIT6), ENABLE);
    u64MaxBWReport = HAL_MIU_Read2Byte(u32RRegValue);
    HAL_MIU_WriteRegBit(MIU_BW_MONITOR_SEL, (BIT4|BIT5|BIT6|BIT7), DISABLE);
    HAL_MIU_WriteRegBit(MIU_BW_MONITOR_SEL, (BIT4|BIT5|BIT6), ENABLE);
    u64MaxBWReport = u64MaxBWReport + (MS_U64)( HAL_MIU_Read2Byte(u32RRegValue) << 16 );

    // max bw cycle
    HAL_MIU_WriteRegBit(MIU_BW_MONITOR_SEL, (BIT4|BIT5|BIT6|BIT7), DISABLE);
    HAL_MIU_WriteRegBit(MIU_BW_MONITOR_SEL, (BIT4|BIT6|BIT7), ENABLE);
    u64MIUCLKTime = HAL_MIU_Read2Byte(u32RRegValue);
    HAL_MIU_WriteRegBit(MIU_BW_MONITOR_SEL, (BIT4|BIT5|BIT6|BIT7), DISABLE);
    HAL_MIU_WriteRegBit(MIU_BW_MONITOR_SEL, (BIT5|BIT6|BIT7), ENABLE);
    u64MIUCLKTime = u64MIUCLKTime + (MS_U64)( HAL_MIU_Read2Byte(u32RRegValue) << 16 );

    pBWInfo->stCurrentBandwidth.u32ReportImmediateOccupancy = (MS_U32)u64OcpyReport;
    pBWInfo->stCurrentBandwidth.u32ReportMaxOccupancy = (MS_U32)u64MaxOcpyReport;
    pBWInfo->stCurrentBandwidth.u32ReportImmediateBW = (MS_U32)u64BWReport;
    pBWInfo->stCurrentBandwidth.u32ReportMaxBW = (MS_U32)u64MaxBWReport;

    //return value basis point = 0.01%
    if(u64OcpyReport == 0)
        pBWInfo->stCurrentBandwidth.u32ReportImmediateEfficiency = 0;
    else
        pBWInfo->stCurrentBandwidth.u32ReportImmediateEfficiency = (MS_U32)( (u64BWReport*10000) / u64OcpyReport );

    if(u64MaxOcpyReport == 0)
        pBWInfo->stCurrentBandwidth.u32ReportMinEfficiency = 0;
    else
        pBWInfo->stCurrentBandwidth.u32ReportMinEfficiency = (MS_U32)( (u64BWReport*10000) / u64MaxOcpyReport);

    if(u64MIUCLKTime == 0)
    {
        pBWInfo->stCurrentBandwidth.u32ReportImmediateUtilization = 0;
        pBWInfo->stCurrentBandwidth.u32ReportMaxUtilization = 0;
    }
    else
    {
        pBWInfo->stCurrentBandwidth.u32ReportImmediateUtilization = (MS_U32)( (u64BWReport*10000) / u64MIUCLKTime );
        pBWInfo->stCurrentBandwidth.u32ReportMaxUtilization = (MS_U32)( (u64MaxBWReport*10000) / u64MIUCLKTime );
    }
    if(pBWInfo->stCurrentBandwidth.u32ReportImmediateEfficiency == 0)
    {
        pBWInfo->stCurrentBandwidth.u32ReportImmediateUsage = 0;
        pBWInfo->stCurrentBandwidth.u32ReportMaxUsage = 0;
    }
    else
    {
        pBWInfo->stCurrentBandwidth.u32ReportImmediateUsage = (MS_U32)((pBWInfo->stCurrentBandwidth.u32ReportImmediateUtilization * 10000 )  / pBWInfo->stCurrentBandwidth.u32ReportImmediateEfficiency);
        pBWInfo->stCurrentBandwidth.u32ReportMaxUsage = (MS_U32)((pBWInfo->stCurrentBandwidth.u32ReportMaxUtilization * 10000 )  / pBWInfo->stCurrentBandwidth.u32ReportImmediateEfficiency);
    }

    //Set Freeze bit
    HAL_MIU_WriteRegBit(MIU_BW_MONITOR_READ, BIT3, DISABLE);

    return TRUE;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function  \b Name: HAL_MIU_Get_BW_All
/// @brief \b Function  \b Description: Get All Bandwidth monitor value
//// @param u8MiuDev     \b IN   : select MIU0 or MIU1
/// @param pBWInfo      \b IN   : bandwidth information
/// @return             \b 0 : Fail  1: OK
////////////////////////////////////////////////////////////////////////////////

MS_BOOL HAL_MIU_Get_BW_All(MS_U8 u8MiuDev, MIU_BandwidthMonitorInfo *pBWInfo)
{
    MS_U32 u32CountGetMonId;
    MS_U32 u32getMonId;
    MS_U32 u32RRegValue;

    MS_U64 u64OcpyReport;
    MS_U64 u64MaxOcpyReport;
    MS_U64 u64BWReport;
    MS_U64 u64MaxBWReport;
    MS_U64 u64MIUCLKTime;

    if(!MIU_BW_MONITOR)
    {
        MIU_DEBUG_INFO(u32MIUDbgLevel, "This chip not support MIU BANDWIDTH MONITOR HARDWARE!!!\n");
    }

    //only one MIU setting in UMA MODE

    //Set Freeze bit
    HAL_MIU_WriteRegBit(MIU_BW_MONITOR_READ, BIT3, ENABLE);

    for(u32CountGetMonId = 0; u32CountGetMonId < E_MONITOR_INDEX_MAX; u32CountGetMonId++)
    {
        pBWInfo[u32CountGetMonId].u32MonitorIndex = E_MONITOR_NONE;
    }

    for(u32CountGetMonId = 0; u32CountGetMonId < MIU_MAX_BW_MONITOR_GROUP_NUMBER; u32CountGetMonId++)
    {
        pBWInfo[u32CountGetMonId].u32MonitorIndex = u32CountGetMonId;
        u32getMonId = u32CountGetMonId;
        //Read value RIU
        u32RRegValue =  MIU_BW_MONITOR0 + (u32getMonId * 2);

        //Read BW data
        // occupy cycle
        HAL_MIU_WriteRegBit(MIU_BW_MONITOR_SEL, (BIT4|BIT5|BIT6|BIT7), DISABLE);
        u64OcpyReport = HAL_MIU_Read2Byte(u32RRegValue);
        HAL_MIU_WriteRegBit(MIU_BW_MONITOR_SEL, (BIT4|BIT5|BIT6|BIT7), DISABLE);
        HAL_MIU_WriteRegBit(MIU_BW_MONITOR_SEL, (BIT4), ENABLE);
        u64OcpyReport = u64OcpyReport + (MS_U64)( HAL_MIU_Read2Byte(u32RRegValue) << 16 );
        // max occupy cycle
        HAL_MIU_WriteRegBit(MIU_BW_MONITOR_SEL, (BIT4|BIT5|BIT6|BIT7), DISABLE);
        HAL_MIU_WriteRegBit(MIU_BW_MONITOR_SEL, (BIT5), ENABLE);
        u64MaxOcpyReport = HAL_MIU_Read2Byte(u32RRegValue);
        HAL_MIU_WriteRegBit(MIU_BW_MONITOR_SEL, (BIT4|BIT5|BIT6|BIT7), DISABLE);
        HAL_MIU_WriteRegBit(MIU_BW_MONITOR_SEL, (BIT4|BIT5), ENABLE);
        u64MaxOcpyReport = u64MaxOcpyReport + (MS_U64)( HAL_MIU_Read2Byte(u32RRegValue) << 16 );
        // bw cycle
        HAL_MIU_WriteRegBit(MIU_BW_MONITOR_SEL, (BIT4|BIT5|BIT6|BIT7), DISABLE);
        HAL_MIU_WriteRegBit(MIU_BW_MONITOR_SEL, (BIT6), ENABLE);
        u64BWReport = HAL_MIU_Read2Byte(u32RRegValue);
        HAL_MIU_WriteRegBit(MIU_BW_MONITOR_SEL, (BIT4|BIT5|BIT6|BIT7), DISABLE);
        HAL_MIU_WriteRegBit(MIU_BW_MONITOR_SEL, (BIT4|BIT6), ENABLE);
        u64BWReport = u64BWReport + (MS_U64)( HAL_MIU_Read2Byte(u32RRegValue) << 16 );
        // max bw cycle
        HAL_MIU_WriteRegBit(MIU_BW_MONITOR_SEL, (BIT4|BIT5|BIT6|BIT7), DISABLE);
        HAL_MIU_WriteRegBit(MIU_BW_MONITOR_SEL, (BIT5|BIT6), ENABLE);
        u64MaxBWReport = HAL_MIU_Read2Byte(u32RRegValue);
        HAL_MIU_WriteRegBit(MIU_BW_MONITOR_SEL, (BIT4|BIT5|BIT6|BIT7), DISABLE);
        HAL_MIU_WriteRegBit(MIU_BW_MONITOR_SEL, (BIT4|BIT5|BIT6), ENABLE);
        u64MaxBWReport = u64MaxBWReport + (MS_U64)( HAL_MIU_Read2Byte(u32RRegValue) << 16 );

        // max bw cycle
        HAL_MIU_WriteRegBit(MIU_BW_MONITOR_SEL, (BIT4|BIT5|BIT6|BIT7), DISABLE);
        HAL_MIU_WriteRegBit(MIU_BW_MONITOR_SEL, (BIT4|BIT6|BIT7), ENABLE);
        u64MIUCLKTime = HAL_MIU_Read2Byte(u32RRegValue);
        HAL_MIU_WriteRegBit(MIU_BW_MONITOR_SEL, (BIT4|BIT5|BIT6|BIT7), DISABLE);
        HAL_MIU_WriteRegBit(MIU_BW_MONITOR_SEL, (BIT5|BIT6|BIT7), ENABLE);
        u64MIUCLKTime = u64MIUCLKTime + (MS_U64)( HAL_MIU_Read2Byte(u32RRegValue) << 16 );

        pBWInfo[u32CountGetMonId].stCurrentBandwidth.u32ReportImmediateOccupancy = (MS_U32)u64OcpyReport;
        pBWInfo[u32CountGetMonId].stCurrentBandwidth.u32ReportMaxOccupancy = (MS_U32)u64MaxOcpyReport;
        pBWInfo[u32CountGetMonId].stCurrentBandwidth.u32ReportImmediateBW = (MS_U32)u64BWReport;
        pBWInfo[u32CountGetMonId].stCurrentBandwidth.u32ReportMaxBW = (MS_U32)u64MaxBWReport;

        //return value basis point = 0.01%
        if(u64OcpyReport == 0)
            pBWInfo[u32CountGetMonId].stCurrentBandwidth.u32ReportImmediateEfficiency = 0;
        else
            pBWInfo[u32CountGetMonId].stCurrentBandwidth.u32ReportImmediateEfficiency = (MS_U32)( (u64BWReport*10000) / u64OcpyReport );

        if(u64MaxOcpyReport == 0)
            pBWInfo[u32CountGetMonId].stCurrentBandwidth.u32ReportMinEfficiency = 0;
        else
            pBWInfo[u32CountGetMonId].stCurrentBandwidth.u32ReportMinEfficiency = (MS_U32)( (u64BWReport*10000) / u64MaxOcpyReport);

        if(u64MIUCLKTime == 0)
        {
            pBWInfo[u32CountGetMonId].stCurrentBandwidth.u32ReportImmediateUtilization = 0;
            pBWInfo[u32CountGetMonId].stCurrentBandwidth.u32ReportMaxUtilization = 0;
        }
        else
        {
            pBWInfo[u32CountGetMonId].stCurrentBandwidth.u32ReportImmediateUtilization = (MS_U32)( (u64BWReport*10000) / u64MIUCLKTime );
            pBWInfo[u32CountGetMonId].stCurrentBandwidth.u32ReportMaxUtilization = (MS_U32)( (u64MaxBWReport*10000) / u64MIUCLKTime );
        }
        if(pBWInfo[u32CountGetMonId].stCurrentBandwidth.u32ReportImmediateEfficiency == 0)
        {
            pBWInfo[u32CountGetMonId].stCurrentBandwidth.u32ReportImmediateUsage = 0;
            pBWInfo[u32CountGetMonId].stCurrentBandwidth.u32ReportMaxUsage = 0;
        }
        else
        {
            pBWInfo[u32CountGetMonId].stCurrentBandwidth.u32ReportImmediateUsage = (MS_U32)((pBWInfo[u32CountGetMonId].stCurrentBandwidth.u32ReportImmediateUtilization * 10000 )  / pBWInfo[u32CountGetMonId].stCurrentBandwidth.u32ReportImmediateEfficiency);
            pBWInfo[u32CountGetMonId].stCurrentBandwidth.u32ReportMaxUsage = (MS_U32)((pBWInfo[u32CountGetMonId].stCurrentBandwidth.u32ReportMaxUtilization * 10000 )  / pBWInfo[u32CountGetMonId].stCurrentBandwidth.u32ReportImmediateEfficiency);
        }
    }

    //Set Freeze bit
    HAL_MIU_WriteRegBit(MIU_BW_MONITOR_READ, BIT3, DISABLE);

    return TRUE;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief \b Function  \b Name: HAL_MIU_Reset_All_BW_Monitor
/// @brief \b Function  \b Description: Reset Bandwidth monitor information to default
/// @param u8MiuDev     \b IN   : select MIU0 or MIU1
/// @return             \b 0 : Fail  1: OK
////////////////////////////////////////////////////////////////////////////////
MS_BOOL HAL_MIU_Reset_All_BW_Monitor(MS_U8 u8MiuDev)
{
    MS_U32 u32MonId;
    MS_U32 u32MonGroupId;

    //only one MIU setting in UMA MODE
    u8MiuDev = E_MIU_0;

    HAL_MIU_Write2Byte(MIU_BW_MONITOR_SEL,0x0000);
    HAL_MIU_Write2Byte(MIU_BW_MONITOR_WRI_EN,0x0000);
    HAL_MIU_WriteRegBit(MIU_BW_MONITOR_SEL, BIT0, ENABLE);
    HAL_MIU_WriteRegBit(MIU_BW_MONITOR_SEL, BIT0, DISABLE);

    for(u32MonGroupId = 0; u32MonGroupId < MIU_MAX_BW_MONITOR_GROUP_NUMBER; ++u32MonGroupId)
    {
        for(u32MonId = 0; u32MonId < MIU_MAX_BW_MONITOR_GP_CLIENT_NUMBER; ++u32MonId)
        {
            MonitorId[u8MiuDev][u32MonGroupId][u32MonId] = MIU_BW_MON_NON_ID;
        }
    }
    return TRUE;
}

MS_BOOL HAL_MIU_Start_BW_Monitor(MS_U8 u8MiuDev)
{
    //only one MIU setting in UMA MODE

    HAL_MIU_WriteRegBit(MIU_BW_MONITOR_SEL, BIT0, ENABLE);

    return TRUE;
}

MS_BOOL HAL_MIU_ConfigHWAttr(MS_U8 u8MiuDev, eMIU_ATTR_TYPE eAttrType, MS_U16 *u16Value, MS_U16 u16Length)
{
    if(u8MiuDev >= MIU_MAX_DEVICE)
    {
        MIU_DEBUG_INFO(u32MIUDbgLevel, "Not support MIU%u!\n", u8MiuDev);
        return FALSE;
    }

    switch(eAttrType)
    {
        //MIU Select
        case MIU_AttrType_Select:
        {
            MIU_DEBUG_INFO(u32MIUDbgLevel, "Not support MIU selection!\n");
            break;
        }
        //MIU Group Priority
        case MIU_AttrType_GroupPriority:
        {
            MIU_DEBUG_INFO(u32MIUDbgLevel, "Not support Set Group Priority!\n");
            break;
        }
        //MIU Dram Size
        case MIU_AttrType_DramSize:
        {
            if(u16Length > 1)
            {
                MIU_DEBUG_INFO(u32MIUDbgLevel, "Length:%d exceed!", u16Length);
                return FALSE;
            }
            else
            {
                switch((u16Value[0] << 4))
                {
                    case MIU_PROTECT_DDR_32MB:
                        HAL_MIU_Dram_Size(u8MiuDev, E_MIU_DDR_32MB);
                        break;
                    case MIU_PROTECT_DDR_64MB:
                        HAL_MIU_Dram_Size(u8MiuDev, E_MIU_DDR_64MB);
                        break;
                    case MIU_PROTECT_DDR_128MB:
                        HAL_MIU_Dram_Size(u8MiuDev, E_MIU_DDR_128MB);
                        break;
                    case MIU_PROTECT_DDR_256MB:
                        HAL_MIU_Dram_Size(u8MiuDev, E_MIU_DDR_256MB);
                        break;
                    case MIU_PROTECT_DDR_512MB:
                        HAL_MIU_Dram_Size(u8MiuDev, E_MIU_DDR_512MB);
                        break;
                    case MIU_PROTECT_DDR_1024MB:
                        HAL_MIU_Dram_Size(u8MiuDev, E_MIU_DDR_1024MB);
                        break;
                    case MIU_PROTECT_DDR_2048MB:
                        HAL_MIU_Dram_Size(u8MiuDev, E_MIU_DDR_2048MB);
                        break;
                    case MIU_PROTECT_DDR_4096MB:
                        HAL_MIU_Dram_Size(u8MiuDev, E_MIU_DDR_4096MB);
                        break;
                    case MIU_PROTECT_DDR_8192MB:
                        HAL_MIU_Dram_Size(u8MiuDev, E_MIU_DDR_8192MB);
                        break;
                    default:
                        MIU_DEBUG_INFO(u32MIUDbgLevel, "No Dram Enum:%d!", u16Value[0]);
                        break;
                }
            }
            break;
        }
        default:
        {
            MIU_DEBUG_INFO(u32MIUDbgLevel, "Not support eAttrType%u!\n", eAttrType);
            return FALSE;
        }

    }
    return TRUE;
}

MS_BOOL HAL_MIU_SetClientLoading(MIU_ID eMIU, eMIUClientID eClientID)
{
    MS_S16 s16Val;
    MS_U16 u16Val;
    MS_U32 u32RegAddr;
    MS_U32 u32RegAddrStatus;

    s16Val = HAL_MIU_GetClientInfo(eMIU, eClientID);
    if (s16Val < 0)
    {
        MIU_DEBUG_INFO(u32MIUDbgLevel, "Not support client ID:%u!\n", eClientID);
        return FALSE;
    }

    if(eMIU == E_MIU_1)
    {
        u32RegAddr = MIU1_BW_REQUEST;
        u32RegAddrStatus = MIU1_BW_STATUS;
    }
    else
    {
        u32RegAddr = MIU_BW_REQUEST;
        u32RegAddrStatus = MIU_BW_STATUS;
    }

    HAL_MIU_Write2Byte(u32RegAddrStatus, 0x0);
    u16Val = (MS_U16)((s16Val)<<8)|0x40;
    HAL_MIU_Write2Byte(u32RegAddr, u16Val);
    HAL_MIU_Write2Byte(u32RegAddr, u16Val|BIT(0));

    return TRUE;
}

MS_BOOL HAL_MIU_GetClientLoading(MIU_ID eMIU, MS_U32 *pu32Loading)
{
    MS_U32 u32RegAddr;

    if (eMIU > E_MIU_1)
    {
        MIU_DEBUG_INFO(u32MIUDbgLevel, "Not support MIU%u!\n", eMIU);
        return FALSE;
    }
    else
    {
        if(eMIU == E_MIU_1)
            u32RegAddr = MIU1_BW_RESULT;
        else
            u32RegAddr = MIU_BW_RESULT;
    }
    *pu32Loading = (MS_U32)HAL_MIU_Read2Byte(u32RegAddr) & 0xFFFFUL;
    return TRUE;
}

MS_BOOL HAL_MIU_SetClientEfficiency(MIU_ID eMIU, eMIUClientID eClientID)
{
    MS_S16 s16Val;
    MS_U16 u16Val;
    MS_U32 u32RegAddr;
    MS_U32 u32RegAddrStatus;

    s16Val = HAL_MIU_GetClientInfo(eMIU, eClientID);
    if (s16Val < 0)
    {
        MIU_DEBUG_INFO(u32MIUDbgLevel, "Not support client ID:%u!\n", eClientID);
        return FALSE;
    }

    if(eMIU == E_MIU_1)
    {
        u32RegAddr = MIU1_BW_REQUEST;
        u32RegAddrStatus = MIU1_BW_STATUS;
    }
    else
    {
        u32RegAddr = MIU_BW_REQUEST;
        u32RegAddrStatus = MIU_BW_STATUS;
    }

    HAL_MIU_Write2Byte(u32RegAddrStatus, 0x0);
    u16Val = (MS_U16)((s16Val)<<8)|0x34;
    HAL_MIU_Write2Byte(u32RegAddr, u16Val);
    HAL_MIU_Write2Byte(u32RegAddr, u16Val|BIT(0));

    return TRUE;
}

MS_BOOL HAL_MIU_GetClientEfficiency(MIU_ID eMIU, MS_U32 *pu32Efficiency)
{
    MS_U32 u32RegAddr;

    if (eMIU > E_MIU_1)
    {
        MIU_DEBUG_INFO(u32MIUDbgLevel, "Not support MIU%u!\n", eMIU);
        return FALSE;
    }
    else
    {
        if(eMIU == E_MIU_1)
            u32RegAddr = MIU1_BW_RESULT;
        else
            u32RegAddr = MIU_BW_RESULT;
    }
    *pu32Efficiency = (MS_U32)HAL_MIU_Read2Byte(u32RegAddr) & 0xFFFFUL;
    return TRUE;
}

MS_BOOL HAL_MIU_SetBWValue(MS_U32 u32ClientID, MIU_BW_TYPE eBWInfoType)
{
    MS_U32 u32MIU0RegAddr = MIU_BW_REQUEST;
    MS_U32 u32MIU0RegAddrStatus = MIU_BW_STATUS;
    MS_U32 u32MIU1RegAddr = MIU1_BW_REQUEST;
    MS_U32 u32MIU1RegAddrStatus = MIU1_BW_STATUS;
    MS_U16 u16Val;

    if (u32ClientID > 0xFF)
    {
        MIU_DEBUG_INFO(u32MIUDbgLevel, "Not support client ID:%lu!\n", (unsigned long)u32ClientID);
        return FALSE;
    }

    HAL_MIU_Write2Byte(u32MIU0RegAddrStatus, 0x0);
    HAL_MIU_Write2Byte(u32MIU1RegAddrStatus, 0x0);

    switch(eBWInfoType)
    {
        case E_BW_TYPE_IMMED_EFFI:
            u16Val = (MS_U16)(u32ClientID<<8)|0x34;
            break;

        case E_BW_TYPE_MIN_EFFI:
            u16Val = (MS_U16)(u32ClientID<<8)|0x30;
            break;

        case E_BW_TYPE_IMMED_UTIL:
            u16Val = (MS_U16)(u32ClientID<<8)|0x40;
            break;

        case E_BW_TYPE_MAX_UTIL:
            u16Val = (MS_U16)(u32ClientID<<8)|0x50;
            break;
        default:
            MIU_DEBUG_INFO(u32MIUDbgLevel, "Not support BWInfoType:%d!\n", (int)eBWInfoType);
            return FALSE;
    }

    HAL_MIU_Write2Byte(u32MIU0RegAddr, u16Val);
    HAL_MIU_Write2Byte(u32MIU1RegAddr, u16Val);
    HAL_MIU_Write2Byte(u32MIU0RegAddr, u16Val|BIT(0));
    HAL_MIU_Write2Byte(u32MIU1RegAddr, u16Val|BIT(0));

    return TRUE;
}

MS_BOOL HAL_MIU_GetBWValue(MS_U32 u32ClientID, MIU_BW_TYPE eBWInfoType, MIU_UMA_Mode *eUMAMode, MIU_BWValue *BWValue)
{
    MS_U32 u32MIU0RegAddr = MIU_BW_REQUEST;
    MS_U32 u32MIU0RegAddrResult = MIU_BW_RESULT;
    MS_U32 u32MIU1RegAddr = MIU1_BW_REQUEST;
    MS_U32 u32MIU1RegAddrResult = MIU1_BW_RESULT;
    MS_U32 u32MIU0BWValue, u32MIU1BWValue;

    MS_U8 u8MIU0ClientIDNow, u8MIU1ClientIDNow;
    MS_U8 eMIU0BWInfoTypeNow, eMIU1BWInfoTypeNow;

    if (u32ClientID > 0xFF)
    {
        MIU_DEBUG_INFO(u32MIUDbgLevel, "Not support client ID:%lu!\n", (unsigned long)u32ClientID);
        return FALSE;
    }

    u8MIU0ClientIDNow = (HAL_MIU_Read2Byte(u32MIU0RegAddr)&0xFF00)>>8;
    u8MIU1ClientIDNow = (HAL_MIU_Read2Byte(u32MIU1RegAddr)&0xFF00)>>8;
    if(u32ClientID != u8MIU0ClientIDNow || u32ClientID != u8MIU1ClientIDNow)
    {
        MIU_DEBUG_INFO(u32MIUDbgLevel, "Wrong u32ClientID, please SetBWValue again\n");
        return FALSE;
    }

    eMIU0BWInfoTypeNow = HAL_MIU_ReadByte(u32MIU0RegAddr);
    eMIU1BWInfoTypeNow = HAL_MIU_ReadByte(u32MIU1RegAddr);

    switch(eBWInfoType)
    {
        case E_BW_TYPE_IMMED_EFFI:
        {
            if(eMIU0BWInfoTypeNow != 0x35 || eMIU1BWInfoTypeNow != 0x35)
            {
                MIU_DEBUG_INFO(u32MIUDbgLevel, "Wrong eBWInfoType, please SetBWValue again\n");
                return FALSE;
            }
            break;
        }
        case E_BW_TYPE_MIN_EFFI:
        {
            if(eMIU0BWInfoTypeNow != 0x31 || eMIU1BWInfoTypeNow != 0x31)
            {
                MIU_DEBUG_INFO(u32MIUDbgLevel, "Wrong eBWInfoType, please SetBWValue again\n");
                return FALSE;
            }
            break;
        }
        case E_BW_TYPE_IMMED_UTIL:
        {
            if(eMIU0BWInfoTypeNow != 0x41 || eMIU1BWInfoTypeNow != 0x41)
            {
                MIU_DEBUG_INFO(u32MIUDbgLevel, "Wrong eBWInfoType, please SetBWValue again\n");
                return FALSE;
            }
            break;
        }
        case E_BW_TYPE_MAX_UTIL:
        {
            if(eMIU0BWInfoTypeNow != 0x51 || eMIU1BWInfoTypeNow != 0x51)
            {
                MIU_DEBUG_INFO(u32MIUDbgLevel, "Wrong eBWInfoType, please SetBWValue again\n");
                return FALSE;
            }
            break;
        }
        default:
            MIU_DEBUG_INFO(u32MIUDbgLevel, "Not support BWInfoType:%d!\n", eBWInfoType);
            return FALSE;
    }

    if(eBWInfoType == E_BW_TYPE_IMMED_EFFI || eBWInfoType == E_BW_TYPE_MIN_EFFI)
    {
        BWValue->u32MIU0BWValue = 1000;
        BWValue->u32MIU1BWValue = 1000;
        BWValue->u32MIU2BWValue = 1000;
        BWValue->u32UMATotal = 1000;
        BWValue->u32UMATail = 1000;
    }
    else
    {
        BWValue->u32MIU0BWValue = 0;
        BWValue->u32MIU1BWValue = 0;
        BWValue->u32MIU2BWValue = 0;
        BWValue->u32UMATotal = 0;
        BWValue->u32UMATail = 0;
    }

    u32MIU0BWValue = (((MS_U32)HAL_MIU_Read2Byte(u32MIU0RegAddrResult) & 0xFFFFUL) * 1000 ) / 1023;
    u32MIU1BWValue = (((MS_U32)HAL_MIU_Read2Byte(u32MIU1RegAddrResult) & 0xFFFFUL) * 1000 ) / 1023;

    BWValue->u32MIU0BWValue = u32MIU0BWValue;
    BWValue->u32MIU1BWValue = u32MIU1BWValue;

    if( (HAL_MIU_ReadByte(REG_MIU_UMA_MODE)&0x40) == 0x0 )
    {
        BWValue->u32UMATotal = (eBWInfoType == E_BW_TYPE_IMMED_EFFI || eBWInfoType == E_BW_TYPE_MIN_EFFI)?((u32MIU0BWValue + u32MIU1BWValue)/2):(u32MIU0BWValue + u32MIU1BWValue);
        if( (HAL_MIU_ReadByte(REG_MIU_ASYM_UMA_MODE)&0xF) == 0x0 )
        {
            *eUMAMode = E_MIU_SYMUMA;
        }
        else
        {
            *eUMAMode = E_MIU_ASYMUMA;
            if( (HAL_MIU_ReadByte(REG_MIU_ASYM_UMA_MODE)&0xF) >= 0x9 )
            {
                if(eBWInfoType == E_BW_TYPE_IMMED_EFFI || eBWInfoType == E_BW_TYPE_MIN_EFFI)
                {
                    BWValue->u32UMATail = u32MIU1BWValue;
                }
                else
                {
                    if( (u32MIU0BWValue > 0) && (u32MIU1BWValue > 0) && (u32MIU1BWValue > u32MIU0BWValue) && ( (u32MIU1BWValue - u32MIU0BWValue) > ( (u32MIU0BWValue/10)*3 ) ) )
                    {
                        BWValue->u32UMATail = u32MIU1BWValue - u32MIU0BWValue;
                    }
                }
            }
            else
            {
                if(eBWInfoType == E_BW_TYPE_IMMED_EFFI || eBWInfoType == E_BW_TYPE_MIN_EFFI)
                {
                    BWValue->u32UMATail = u32MIU0BWValue;
                }
                else
                {
                    if( (u32MIU0BWValue > 0) && (u32MIU1BWValue > 0) && (u32MIU0BWValue > u32MIU1BWValue) && ( (u32MIU0BWValue - u32MIU1BWValue) > ( (u32MIU0BWValue/10)*3 ) ) )
                    {
                        BWValue->u32UMATail = u32MIU0BWValue - u32MIU1BWValue;
                    }
                }
            }
        }
    }
    else
    {
        *eUMAMode = E_MIU_NONUMA;
    }

    return TRUE;
}
#endif

MS_U32 HAL_MIU_GetModuleClient(MIU_ID eMiu, MIU_IP_Module eMiuModule, MS_U32 **u32ModuleClient)
{
    if (eMiu >= MIU_MAX_DEVICE)
    {
        MIU_DEBUG_INFO(u32MIUDbgLevel, "Not support MIU%u!\n", eMiu );
        return 0;
    }
    switch(eMiuModule)
    {
        case E_MIU_MODULE_CPU:
        {
            if(u32CPUClient[0] == NULL)
            {
                return 0;
            }
            else
            {
                *u32ModuleClient = &u32CPUClient[0];
                return (sizeof(u32CPUClient)/sizeof(MS_U32));
            }
        }
        case E_MIU_MODULE_GPU:
        {
            if(u32GPUClient[0] == NULL)
            {
                return 0;
            }
            else
            {
                *u32ModuleClient = &u32GPUClient[0];
                return (sizeof(u32GPUClient)/sizeof(MS_U32));
            }
        }
        case E_MIU_MODULE_XC:
        {
            if(u32XCClient[0] == NULL)
            {
                return 0;
            }
            else
            {
                *u32ModuleClient = &u32XCClient[0];
                return (sizeof(u32XCClient)/sizeof(MS_U32));
            }
        }
        case E_MIU_MODULE_MVOP:
        {
            if(u32MVOPClient[0] == NULL)
            {
                return 0;
            }
            else
            {
                *u32ModuleClient = &u32MVOPClient[0];
                return (sizeof(u32MVOPClient)/sizeof(MS_U32));
            }
        }
        case E_MIU_MODULE_MEMC:
        {
            if(u32MEMCClient[0] == NULL)
            {
                return 0;
            }
            else
            {
                *u32ModuleClient = &u32MEMCClient[0];
                return (sizeof(u32MEMCClient)/sizeof(MS_U32));
            }
        }
        case E_MIU_MODULE_GOP:
        {
            if(u32GOPClient[0] == NULL)
            {
                return 0;
            }
            else
            {
                *u32ModuleClient = &u32GOPClient[0];
                return (sizeof(u32GOPClient)/sizeof(MS_U32));
            }
        }
        case E_MIU_MODULE_OD:
        {
            if(u32ODClient[0] == NULL)
            {
                return 0;
            }
            else
            {
                *u32ModuleClient = &u32ODClient[0];
                return (sizeof(u32ODClient)/sizeof(MS_U32));
            }
        }
        case E_MIU_MODULE_HDR:
        {
            if(u32HDRClient[0] == NULL)
            {
                return 0;
            }
            else
            {
                *u32ModuleClient = &u32HDRClient[0];
                return (sizeof(u32HDRClient)/sizeof(MS_U32));
            }
        }
        case E_MIU_MODULE_AUDIO:
        {
            if(u32AUDIOClient[0] == NULL)
            {
                return 0;
            }
            else
            {
                *u32ModuleClient = &u32AUDIOClient[0];
                return (sizeof(u32AUDIOClient)/sizeof(MS_U32));
            }
        }
        case E_MIU_MODULE_VDEC:
        {
            if(u32VDECClient[0] == NULL)
            {
                return 0;
            }
            else
            {
                *u32ModuleClient = &u32VDECClient[0];
                return (sizeof(u32VDECClient)/sizeof(MS_U32));
            }
        }
        case E_MIU_MODULE_GE:
        {
            if(u32GEClient[0] == NULL)
            {
                return 0;
            }
            else
            {
                *u32ModuleClient = &u32GEClient[0];
                return (sizeof(u32GEClient)/sizeof(MS_U32));
            }
        }
        case E_MIU_MODULE_VDEC_R2:
        {
            if(u32VDECR2Client[0] == NULL)
            {
                return 0;
            }
            else
            {
                *u32ModuleClient = &u32VDECR2Client[0];
                return (sizeof(u32VDECR2Client)/sizeof(MS_U32));
            }
        }
        case E_MIU_MODULE_DIP:
        {
            if(u32DIPClient[0] == NULL)
            {
                return 0;
            }
            else
            {
                *u32ModuleClient = &u32DIPClient[0];
                return (sizeof(u32DIPClient)/sizeof(MS_U32));
            }
        }
        case E_MIU_MODULE_VE:
        {
            if(u32VEClient[0] == NULL)
            {
                return 0;
            }
            else
            {
                *u32ModuleClient = &u32VEClient[0];
                return (sizeof(u32VEClient)/sizeof(MS_U32));
            }
        }
        case E_MIU_MODULE_MFDEC:
        {
            if(u32MFDECClient[0] == NULL)
            {
                return 0;
            }
            else
            {
                *u32ModuleClient = &u32MFDECClient[0];
                return (sizeof(u32MFDECClient)/sizeof(MS_U32));
            }
        }
        case E_MIU_MODULE_BIST:
        {
            if(u32BISTClient[0] == NULL)
            {
                return 0;
            }
            else
            {
                *u32ModuleClient = &u32BISTClient[0];
                return (sizeof(u32BISTClient)/sizeof(MS_U32));
            }
        }
        case E_MIU_MODULE_AUDIO_EN:
        {
            if(u32AUDIOENClient[0] == NULL)
            {
                return 0;
            }
            else
            {
                *u32ModuleClient = &u32AUDIOENClient[0];
                return (sizeof(u32AUDIOENClient)/sizeof(MS_U32));
            }
        }
        case E_MIU_MODULE_AUDIO_DE:
        {
            if(u32AUDIODEClient[0] == NULL)
            {
                return 0;
            }
            else
            {
                *u32ModuleClient = &u32AUDIODEClient[0];
                return (sizeof(u32AUDIODEClient)/sizeof(MS_U32));
            }
        }
        case E_MIU_MODULE_DISPLAY:
        {
            if(u32DISPLAYClient[0] == NULL)
            {
                return 0;
            }
            else
            {
                *u32ModuleClient = &u32DISPLAYClient[0];
                return (sizeof(u32DISPLAYClient)/sizeof(MS_U32));
            }
        }
        default:
        {
            MIU_DEBUG_INFO(u32MIUDbgLevel, "Wrong Module enum%d!\n", eMiuModule );
            return 0;
        }
    }
}

// UTOPIA remove so dummy code
#ifndef CONFIG_UTOPIAXP_REMOVE_IMPL
MS_BOOL HAL_MIU_GetMIUInfo(MIU_ID eMiu, MIU_Info* stMIUInfo)
{
    MS_U32  u32MIUBUSAddr;
    MS_U32  u32MIUChannelAddr;
    MS_U32  u32MIUDataRatioAddr;
    MS_U32  u32MIUDramFreqAddr;
    MS_U32  u32MIUDDRErrCheckAddr;
    MS_U8   u8MIUBUS;
    MS_U8   u8MIUDataRatio;
    MS_U32  u32MIUDramFreq;

    if (eMiu >= MIU_MAX_CHANNEL)
    {
        MIU_DEBUG_INFO(u32MIUDbgLevel, "Not support MIU%u!\n", eMiu );
        return FALSE;
    }
    else if( eMiu == E_MIU_0 )
    {
        u32MIUBUSAddr = REG_MIU_DRAM_BUS;
        u32MIUChannelAddr = REG_MIU_DRAM_CHANNEL;
        u32MIUDataRatioAddr = REG_MIU_DATA_RATIO;
        u32MIUDramFreqAddr = REG_MIU_DRAM_FREQ;
        u32MIUDDRErrCheckAddr = MIU_ATOP_BASE + MIU_DDR_PHASE_ERR_CHECK;
    }
    else if( eMiu == E_MIU_1 )
    {
        u32MIUBUSAddr = REG_MIU1_DRAM_BUS;
        u32MIUChannelAddr = REG_MIU_DRAM_CHANNEL;
        u32MIUDataRatioAddr = REG_MIU1_DATA_RATIO;
        u32MIUDramFreqAddr = REG_MIU1_DRAM_FREQ;
        u32MIUDDRErrCheckAddr = MIU1_ATOP_BASE + MIU_DDR_PHASE_ERR_CHECK;
    }

    stMIUInfo->u32MIUDDRPhaseErrorCheck = HAL_MIU_Read2Byte(u32MIUDDRErrCheckAddr);
    stMIUInfo->u32MIUDramBus = 0;
    stMIUInfo->u32MIUDramFreq = 0;
    stMIUInfo->u32MIUDramDataRatio = 0;
    if( (HAL_MIU_ReadByte(u32MIUChannelAddr) & 0xF) == 0 && eMiu == E_MIU_1)
        return TRUE;

    //Get Dram Bus
    u8MIUBUS = HAL_MIU_ReadByte(u32MIUBUSAddr) & 0x03;
    if( u8MIUBUS == MIU_DRAM_BUS_16 )
    {
        stMIUInfo->u32MIUDramBus = 16;
    }
    else if( u8MIUBUS == MIU_DRAM_BUS_32 )
    {
        stMIUInfo->u32MIUDramBus = 32;
    }
    else if( u8MIUBUS == MIU_DRAM_BUS_64 )
    {
        stMIUInfo->u32MIUDramBus = 64;
    }

    u8MIUDataRatio = HAL_MIU_ReadByte(u32MIUDataRatioAddr) & 0x03;
    if( u8MIUDataRatio == MIU_DRAM_DATA_RATIO_1X )
    {
        stMIUInfo->u32MIUDramDataRatio = 1;
    }
    else if( u8MIUDataRatio == MIU_DRAM_DATA_RATIO_2X )
    {
        stMIUInfo->u32MIUDramDataRatio = 2;
    }
    else if( u8MIUDataRatio == MIU_DRAM_DATA_RATIO_4X )
    {
        stMIUInfo->u32MIUDramDataRatio = 4;
    }
    else if( u8MIUDataRatio == MIU_DRAM_DATA_RATIO_8X )
    {
        stMIUInfo->u32MIUDramDataRatio = 8;
    }

    u32MIUDramFreq = HAL_MIU_ReadByte(u32MIUDramFreqAddr) & 0xFF;
    if( u32MIUDramFreq >= 0x33 )
    {
        stMIUInfo->u32MIUDramFreq = 1066;
    }
    else if ( u32MIUDramFreq >= 0x2A && u32MIUDramFreq < 0x33)
    {
        stMIUInfo->u32MIUDramFreq = 1200;
    }
    else if ( u32MIUDramFreq >= 0x29 && u32MIUDramFreq < 0x2A)
    {
        stMIUInfo->u32MIUDramFreq = 1333;
    }
    else if ( u32MIUDramFreq >= 0x22 && u32MIUDramFreq < 0x29)
    {
        stMIUInfo->u32MIUDramFreq = 1600;
    }
    else if ( u32MIUDramFreq >= 0x1D && u32MIUDramFreq < 0x22)
    {
        stMIUInfo->u32MIUDramFreq = 1866;
    }
    else if ( u32MIUDramFreq >= 0x19 && u32MIUDramFreq < 0x1D)
    {
        stMIUInfo->u32MIUDramFreq = 2133;
    }
    else if ( u32MIUDramFreq >= 0x17 && u32MIUDramFreq < 0x19)
    {
        stMIUInfo->u32MIUDramFreq = 2400;
    }
    else if ( u32MIUDramFreq >= 0x14 && u32MIUDramFreq < 0x17)
    {
        stMIUInfo->u32MIUDramFreq = 2666;
    }
    else if ( u32MIUDramFreq >= 0x11 && u32MIUDramFreq < 0x14)
    {
        stMIUInfo->u32MIUDramFreq = 3200;
    }

    return TRUE;
}

MS_BOOL HAL_MIU_SetCPUHPriority(MIU_HPri_Scope eScope, MS_U64 u64Start, MS_U64 u64End, MS_BOOL bEnable)
{
    MS_U32 u32StartAddr;
    MS_U32 u32StartHAddr;
    MS_U32 u32EndAddr;
    MS_U32 u32EndHAddr;
    MS_U32 u32StartAlign;
    MS_U32 u32EndAlign;

    switch(eScope)
    {
        case E_MIU_SCOPE_0:
            u32StartAddr = REG_MIU_CPU_SCOPE_0_START;
            u32StartHAddr = REG_MIU_CPU_SCOPE_0_START_H;
            u32EndAddr = REG_MIU_CPU_SCOPE_0_END;
            u32EndHAddr = REG_MIU_CPU_SCOPE_0_END_H;
            break;
        case E_MIU_SCOPE_1:
            u32StartAddr = REG_MIU_CPU_SCOPE_1_START;
            u32StartHAddr = REG_MIU_CPU_SCOPE_1_START_H;
            u32EndAddr = REG_MIU_CPU_SCOPE_1_END;
            u32EndHAddr = REG_MIU_CPU_SCOPE_1_END_H;
            break;
        case E_MIU_SCOPE_2:
            u32StartAddr = REG_MIU_CPU_SCOPE_2_START;
            u32StartHAddr = REG_MIU_CPU_SCOPE_2_START_H;
            u32EndAddr = REG_MIU_CPU_SCOPE_2_END;
            u32EndHAddr = REG_MIU_CPU_SCOPE_2_END_H;
            break;
        default:
            MIU_DEBUG_INFO(u32MIUDbgLevel, "Not support Scope%u!\n", eScope );
            return FALSE;
    }

    if(bEnable == TRUE)
    {
        if( ((HAL_MIU_ReadByte(REG_MIU_CPU_HIGHWAY_ENABLE)>>(eScope+1))&0x1) != 0 )
        {
            MIU_DEBUG_INFO(u32MIUDbgLevel, "Scope%u is enable now, please disable first\n", eScope );
            return FALSE;
        }
    }

    //Disable high way
    HAL_MIU_WriteRegBit(REG_MIU_CPU_HIGHWAY_ENABLE, BIT0, DISABLE);
    //Disable scope
    HAL_MIU_WriteRegBit(REG_MIU_CPU_HIGHWAY_ENABLE, (1<<(eScope+1)), DISABLE);
    HAL_MIU_Write2Byte(u32StartAddr,(MS_U16)0x0);
    HAL_MIU_WriteByte(u32StartHAddr,(MS_U8)0x0);
    HAL_MIU_Write2Byte(u32EndAddr,(MS_U16)0x0);
    HAL_MIU_WriteByte(u32EndHAddr,(MS_U8)0x0);

    if(bEnable == TRUE)
    {
        //set high way priority
        HAL_MIU_WriteRegBit(REG_MIU_CPU_HIGHWAY_TYPE, BIT0|BIT1|BIT2|BIT3, DISABLE);
        //set scope address

        if(((u64Start & ((1 << MIU_CPU_HPRI_PAGE_SHIFT) -1)) != 0) || ((u64End & ((1 << MIU_CPU_HPRI_PAGE_SHIFT) -1)) != 0))
        {
            MIU_DEBUG_INFO(u32MIUDbgLevel, "Address should be aligned to 4KB\n");
            return FALSE;
        }
        else if(u64Start > 0x1FFFFF000 || u64End > 0x1FFFFF000)
        {
            MIU_DEBUG_INFO(u32MIUDbgLevel, "Address should not larger than 0x1FFFFF000\n");
            return FALSE;
        }
        else if(u64Start >= u64End)
        {
            MIU_DEBUG_INFO(u32MIUDbgLevel, "Start address should not >= end address\n");
            return FALSE;
        }

        u32StartAlign = ((MS_U32)(u64Start >> MIU_CPU_HPRI_PAGE_SHIFT)) & 0x1FFFFF;
        u32EndAlign = ((MS_U32)(u64End >> MIU_CPU_HPRI_PAGE_SHIFT)) & 0x1FFFFF;

        HAL_MIU_Write2Byte(u32StartAddr,(MS_U16)(u32StartAlign&0xFFFF));
        HAL_MIU_WriteByte(u32StartHAddr,(MS_U8)((u32StartAlign&0x1F0000)>>16));
        HAL_MIU_Write2Byte(u32EndAddr,(MS_U16)(u32EndAlign&0xFFFF));
        HAL_MIU_WriteByte(u32EndHAddr,(MS_U8)((u32EndAlign&0x1F0000)>>16));
        //Enable scope
        HAL_MIU_WriteRegBit(REG_MIU_CPU_HIGHWAY_ENABLE, (1<<(eScope+1)), ENABLE);
    }

    //Enable high way
    HAL_MIU_WriteRegBit(REG_MIU_CPU_HIGHWAY_ENABLE, BIT0, ENABLE);

    return TRUE;
}
#endif

MS_BOOL HAL_MIU_GetSWClientInfo(MIU_ID eMIU, MS_U64 *pu64HWClientID, MS_U32 u32HWClientIDNumber)
{
    MS_U32 u32index;
    MS_U64 idx;

    if (eMIU >= MIU_MAX_DEVICE)
    {
        MIU_DEBUG_INFO(u32MIUDbgLevel, "Wrong MIU device:%u!\n", eMIU);
        return FALSE;
    }
    for(idx = 0; idx < u32HWClientIDNumber; idx++)
    {
        if(*(pu64HWClientID+idx)>= MIU_MAX_TBL_CLIENT)
            *(pu64HWClientID + idx) = 0x0;
        else
        {
            for(u32index = 0; u32index < MIU_CLIENT_MAX_NUMBER; u32index++)
            {
                if( clientTbl[eMIU][u32index] == *(pu64HWClientID+idx) )
                {
                    *(pu64HWClientID + idx) = u32index;
                    break;
                }
            }
            if( u32index == MIU_CLIENT_MAX_NUMBER )
            {
                MIU_DEBUG_INFO(u32MIUDbgLevel, "Wrong MIU Client ID:0x%llX!\n", *(pu64HWClientID+idx));
                return FALSE;
            }
        }
    }
    return TRUE;
}

#ifdef CONFIG_UTOPIA_PROC_DBG_SUPPORT
//MS_U32 HAL_MIU_GetParaByChip(EN_MIU_GETPARABYCHIP eGetParaByChip, GetParaByChipHandle *pMIUPara)
//{
//    MS_U32 index;
//
//    switch(eGetParaByChip)
//    {
//        case MIU_GETPARABYCHIP_MIU_SELECT:
//            if(pMIUPara->eMIU == E_MIU_0)
//                MIU_DEBUG_PRI(u32MIUDbgLevel, "pMIUPara->eMIU == E_MIU_0\n");
//            return 0x0;
//        default:
//            return 0x0;
//    }
//}
MS_BOOL HAL_MIU_GetSelectInfo(MS_U32 u32IdGroup, MS_U32 *pu32SelectInfo)
{
    //
    // 2. Set the base address of MIU Select
    //
    MIU_DEBUG_INFO(u32MIUDbgLevel, "Not support MIU selection!\n");
    return FALSE;
}

MS_BOOL HAL_MIU_GetMaskInfo(MIU_ID eMIU, MS_U32 u32IdGroup, MS_U32 *pu32MaskInfo)
{
    MS_U32 u32Reg;

    if(0<u32IdGroup && u32IdGroup<MIU_MAX_GROUP)
    {
        u32Reg = REG_MIU_RQX_MASK(u32IdGroup);
        u32Reg += MIU_BLOCK_ARBITER_GP1;  //base on group1
    }
    else
        return FALSE;

    *pu32MaskInfo = HAL_MIU_ExtRead2Byte(u32Reg);
    return TRUE;
}

MS_BOOL HAL_MIU_MDBGetProtectInfo(MIU_ID eMIU, MIU_ProtectInfoHandle *pProtectInfo)
{
    MS_U32 index;
    MS_U32 index1;
    MS_U32 u32MiuProtectEn;
    MS_U32 u32Reg;
    MS_U32 u32RegAddrStar;
    MS_U32 u32RegAddrClientID;
    MS_U32 u32RegAddrClientEn;
    MS_U16 u16ClientEn;
    MS_U32 u32RegAddrGroupSel;
    MS_U8 u8GroupSel;
    MS_U16 u16ret;

    switch(eMIU)
    {
        case E_MIU_0:
            //IDs[E_MIU_0][];
            u32RegAddrClientID = MIU_PROTECT0_ID0;
            u32RegAddrClientEn = MIU_PROTECT0_ID_ENABLE;
            u32RegAddrGroupSel = MIU_PROTECT_GROUP_SEL;
            u32MiuProtectEn=MIU_PROTECT_EN;
            u32Reg = MIU_PROTECT_BASE;
            u32RegAddrStar = MIU_PROTECT0_START;
            break;
        default:
            return FALSE;
    }
    for( index = 0; index < MIU_MAX_PROTECT_ID_GROUP; index++)
    {
        for(index1 = 0; index1 < MIU_MAX_PROTECT_ID; index1++)
        {
            pProtectInfo->WhiteList[index * MIU_MAX_PROTECT_ID + index1] = (MS_U32)HAL_MIU_ExtReadByte(u32RegAddrClientID + (index * MIU_MAX_PROTECT_ID + index1));
        }
    }
    for(index = 0; index < MIU_MAX_PROTECT_BLOCK; index++)
    {
        u16ClientEn = HAL_MIU_ExtRead2Byte(MIU_PROTECT0_ID_ENABLE + (index * 2));
        for(index1 = 0; index1 < MIU_MAX_PROTECT_ID; index1++)
        {
            pProtectInfo->WhiteListEnable[index][index1] = (MS_BOOL)((u16ClientEn & (1<<index1))>>index1);
        }
    }
    u8GroupSel = HAL_MIU_ExtReadByte(u32RegAddrGroupSel);
    for(index = 0; index < MIU_MAX_PROTECT_BLOCK; index++)
    {
        pProtectInfo->ProtectBlockGroup[index] = (MS_U8)((u8GroupSel & (1<<index)) >> index);
    }
    for(index1 = 0; index1 < MIU_MAX_PROTECT_BLOCK; index1++)
    {
        // Start Address
        pProtectInfo->ProtectAddrStart[index1] = (MS_PHY)HAL_MIU_ExtRead4Byte(u32RegAddrStar+index1*8);
        // End Address
        pProtectInfo->ProtectAddrEnd[index1] = (MS_PHY)HAL_MIU_ExtRead4Byte((u32RegAddrStar + 4)+index1*8);
        // Enable MIU protect
    }
    pProtectInfo->ProtectAttribute = HAL_MIU_ExtRead2Byte(u32MiuProtectEn);

    u16ret = HAL_MIU_ExtRead2Byte(u32Reg + REG_MIU_PROTECT_BLOCK);
    pProtectInfo->HitPortectInfo.u8Block = (MS_U8)(u16ret & 0x0F);
    u16ret = HAL_MIU_ExtRead2Byte(u32Reg + REG_MIU_PROTECT_STATUS);
    pProtectInfo->HitPortectInfo.u8Group = (MS_U8)(u16ret >> 12);
    pProtectInfo->HitPortectInfo.u8ClientID = (MS_U8)((u16ret >> 8) & 0x0F);
    if (REG_MIU_PROTECT_HIT_FALG & u16ret)
        pProtectInfo->HitPortectInfo.bHit = TRUE;
    else
        pProtectInfo->HitPortectInfo.bHit = FALSE;

    return TRUE;
}

MS_BOOL HAL_MIU_MDBGetDramClock(MIU_ID eMIU, MS_U32 *pu32DramClock)
{
    MS_U32 u32RegAddrPLL;

    switch(eMIU)
    {
        case E_MIU_0:
            u32RegAddrPLL = MIU_ATOP_BASE + MIU_PLLCTRL;
            break;
        case E_MIU_1:
            u32RegAddrPLL = MIU1_ATOP_BASE + MIU_PLLCTRL;
            break;
        default:
            MIU_DEBUG_INFO(u32MIUDbgLevel, "Wrong MIU device:%u!\n", eMIU);
            return FALSE;
    }
    *pu32DramClock = HAL_MIU_Read4Byte(u32RegAddrPLL) & 0x00FFFFFF; //24bits
    return TRUE;
}

MS_BOOL HAL_MIU_GetChipInfo(MIU_ChipInfoHandle *pChipInfo)
{
    pChipInfo->ArbStruct_Version = 0x2;
    pChipInfo->Protect_Version = 0x2;
    pChipInfo->HWSupport_MIUSelect = 0x0;
    pChipInfo->SWSupport_MIUProtectEx = 0x1;
    pChipInfo->BW_Version = 0x3;
    pChipInfo->DRAMSize_Version = 0x1;
    return TRUE;
}

MS_BOOL HAL_MIU_SetFlowControl(MIU_ID eMIU, MIU_FlowControl *pFlowControl, MS_BOOL bEnable)
{
    return TRUE;
}

MS_BOOL HAL_MIU_SetMemberLimit(MIU_ID eMIU, MIU_MemberLimit *pMemberLimit, MS_BOOL bEnable)
{
    return TRUE;
}

MS_U64 HAL_MIU_MDBGetDramSize(MIU_ID eMIU)
{
    MS_U64 u64Ret = 0;
    MS_U32 u32RegAddrDramSize = MIU_PROTECT_DDR_BOUND;
    if(eMIU < MIU_MAX_DEVICE)
    {
        u64Ret = (MS_U64)((HAL_MIU_ExtRead4Byte(u32RegAddrDramSize)+1)<<MIU_PAGE_SHIFT);
    }
    return u64Ret;
}

#endif
