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

/*-----------------------------------------------------------------------------
 *
 * $Author$
 * $Date$
 * $RCSfile: osd_plane_hw.c,v $
 * $Revision$
 *
 *---------------------------------------------------------------------------*/

/** @file osd_plane_hw.c
 *  This header file includes function definitions of OSD plane hardware.
 */

//-----------------------------------------------------------------------------
// Include files
//-----------------------------------------------------------------------------

#include "osd_drvif.h"
#include "osd_hw.h"
#include "osd_debug.h"

extern UINT32 _fgOsdEnabelUpdate;


//-----------------------------------------------------------------------------
// Macro definitions
//-----------------------------------------------------------------------------


/*lint -save -e960 */
#if defined(CC_MT5893) || defined(CC_MT5895)

#define OSD_PLA_SETGET_TMPL(NAME, FIELD) \
    INT32 _OSD_PLA_Set##NAME(UINT32 u4Plane, UINT32 u4Value) \
    { \
        OSD_VERIFY_PLANE(u4Plane); \
        _rOsdPlaneReg[u4Plane].rField.FIELD = u4Value; \
        if (OSD_CHECK_LEFT_PLANE(u4Plane)) \
        { \
            _rOsdPlaneReg[OSD_GET_RIGHT_PLANE(u4Plane)].rField.FIELD = u4Value; \
        } \
        return (INT32)OSD_RET_OK; \
    } \
    INT32 _OSD_PLA_Get##NAME(UINT32 u4Plane, UINT32 *pu4Value) \
    { \
        OSD_VERIFY_PLANE(u4Plane); \
        if(pu4Value == NULL) \
        { \
            return -(INT32)OSD_RET_INV_ARG; \
        } \
        *pu4Value = _rOsdPlaneReg[u4Plane].rField.FIELD; \
        return (INT32)OSD_RET_OK; \
    } \

#else

#define OSD_PLA_SETGET_TMPL(NAME, FIELD) \
    INT32 _OSD_PLA_Set##NAME(UINT32 u4Plane, UINT32 u4Value) \
    { \
        OSD_VERIFY_PLANE(u4Plane); \
        _rOsdPlaneReg[u4Plane].rField.FIELD = u4Value; \
        return (INT32)OSD_RET_OK; \
    } \
    INT32 _OSD_PLA_Get##NAME(UINT32 u4Plane, UINT32 *pu4Value) \
    { \
        OSD_VERIFY_PLANE(u4Plane); \
        if(pu4Value == NULL) \
        { \
            return -(INT32)OSD_RET_INV_ARG; \
        } \
        *pu4Value = _rOsdPlaneReg[u4Plane].rField.FIELD; \
        return (INT32)OSD_RET_OK; \
    } \

#endif

/* above line is intendedly left blanc */
/*lint -restore */

/*lint -save -e960 */
#if defined(CC_MT5863) && defined(__KERNEL__) && !defined(CC_UBOOT)

#define OSD_PLA_SETGET_ADDRESS_TMPL(NAME, FIELD) \
    INT32 _OSD_PLA_Set##NAME(UINT32 u4Plane, UPTR upValue) \
    { \
        OSD_VERIFY_PLANE(u4Plane); \
        _rOsdPlaneReg[u4Plane].rField.FIELD##High = (UINT32)((UINT64)upValue >> 36) & 0x7; \
        _rOsdPlaneReg[u4Plane].rField.FIELD = ((UINT32)((((UINT64)upValue >> 32) & 0xf) << 28)) | ((UINT32)upValue >> 4); \
        return (INT32)OSD_RET_OK; \
    } \
    INT32 _OSD_PLA_Get##NAME(UINT32 u4Plane, UPTR *pupValue) \
    { \
        BOOL fgEnable = FALSE; \
        OSD_VERIFY_PLANE(u4Plane); \
        if(pupValue == NULL) \
        { \
            return -(INT32)OSD_RET_INV_ARG; \
        } \
        OSD_MMU_GetEnable(u4Plane, &fgEnable); \
        if (fgEnable) \
            *pupValue = (UPTR)(VIRTUAL_ADDRESS_BASE | (((UINT64)(_rOsdPlaneReg[u4Plane].rField.FIELD##High) << 36) \
                        | ((UINT64)(_rOsdPlaneReg[u4Plane].rField.FIELD) << 4))); \
        else \
            *pupValue = (UPTR)(((UINT64)(_rOsdPlaneReg[u4Plane].rField.FIELD##High) << 36) \
                        | ((UINT64)(_rOsdPlaneReg[u4Plane].rField.FIELD) << 4)); \
        return (INT32)OSD_RET_OK; \
    } \

#else

#define OSD_PLA_SETGET_ADDRESS_TMPL(NAME, FIELD) \
    INT32 _OSD_PLA_Set##NAME(UINT32 u4Plane, UPTR upValue) \
    { \
        OSD_VERIFY_PLANE(u4Plane); \
        _rOsdPlaneReg[u4Plane].rField.FIELD = upValue >> 4; \
        return (INT32)OSD_RET_OK; \
    } \
    INT32 _OSD_PLA_Get##NAME(UINT32 u4Plane, UPTR *pupValue) \
    { \
        OSD_VERIFY_PLANE(u4Plane); \
        if(pupValue == NULL) \
        { \
            return -(INT32)OSD_RET_INV_ARG; \
        } \
        *pupValue = (UPTR)((UINT32)_rOsdPlaneReg[u4Plane].rField.FIELD << 4); \
        return (INT32)OSD_RET_OK; \
    } \

#endif

#if defined(CC_MT5863) && defined(__KERNEL__) && !defined(CC_UBOOT)

#define OSD_PLA_GET_HW_ADDRESS_TMPL(NAME, FIELD) \
    INT32 _OSD_PLA_Get_Hw_##NAME(UINT32 u4Plane, volatile UPTR *pupValue) \
    { \
        BOOL fgEnable = FALSE; \
        OSD_VERIFY_PLANE(u4Plane); \
        if(pupValue == NULL) \
        { \
            return -(INT32)OSD_RET_INV_ARG; \
        } \
        OSD_MMU_GetEnable(u4Plane, &fgEnable); \
        if (fgEnable) \
            *pupValue = (UPTR)(VIRTUAL_ADDRESS_BASE | (((UINT64)(_prHwOsdPlaneReg[u4Plane]->rField.FIELD##High) << 36) \
                        | ((UINT64)(_prHwOsdPlaneReg[u4Plane]->rField.FIELD) << 4))); \
        else \
            *pupValue = (UPTR)(((UINT64)(_prHwOsdPlaneReg[u4Plane]->rField.FIELD##High) << 36) \
                        | ((UINT64)(_prHwOsdPlaneReg[u4Plane]->rField.FIELD) << 4)); \
        return (INT32)OSD_RET_OK; \
    } \

#else

#define OSD_PLA_GET_HW_ADDRESS_TMPL(NAME, FIELD) \
    INT32 _OSD_PLA_Get_Hw_##NAME(UINT32 u4Plane, volatile UPTR *pupValue) \
    { \
        OSD_VERIFY_PLANE(u4Plane); \
        if(pupValue == NULL) \
        { \
            return -(INT32)OSD_RET_INV_ARG; \
        } \
        *pupValue = (UPTR)((UINT32)_prHwOsdPlaneReg[u4Plane]->rField.FIELD << 4); \
        return (INT32)OSD_RET_OK; \
    } \

#endif


/* above line is intendedly left blanc */
/*lint -restore */

//-----------------------------------------------------------------------------
// Static variables
//-----------------------------------------------------------------------------

static OSD_PLA_UNION_T _rOsdPlaneReg[OSD_PLANE_MAX_NUM];
#if defined(CC_DYNAMIC_IO_ADDRESS)
#ifdef __KERNEL__
#if !defined(CC_UBOOT) && !defined(CC_MTK_LOADER)
#undef IO_VIRT
#define IO_VIRT IO_VIRT_FIX
#endif
#endif
#endif

#if defined(CC_MT5891) || defined(CC_MT5886) || defined(CC_MT5863) || defined(CC_MT5893) || defined(CC_MT5895)
static volatile OSD_PLA_UNION_T *_prHwOsdPlaneReg[OSD_PLANE_MAX_NUM] = {NULL};
#else
static volatile OSD_PLA_UNION_T *_prHwOsdPlaneReg[] =
{
    (OSD_PLA_UNION_T *) OSD_PLA1_REG,
    (OSD_PLA_UNION_T *) OSD_PLA2_REG,
    (OSD_PLA_UNION_T *) OSD_PLA3_REG,
    (OSD_PLA_UNION_T *) OSD_PLA4_REG,
    (OSD_PLA_UNION_T *) OSD_PLA5_REG,
};
#endif
#if defined(CC_DYNAMIC_IO_ADDRESS)
#ifdef __KERNEL__
#if !defined(CC_UBOOT) && !defined(CC_MTK_LOADER)
#undef IO_VIRT
#define IO_VIRT IO_VIRT_DYN
#endif
#endif
#endif

//-----------------------------------------------------------------------------
// Inter-file functions
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
/** Brief
 *  @param
 *  @return
 */
//-----------------------------------------------------------------------------
#if defined(CC_MT5891) || defined(CC_MT5886) || defined(CC_MT5863) || defined(CC_MT5893) || defined(CC_MT5895)
void _OSD_PLA_InitHwReg(void)
{
    UINT32 i = 0;
#if defined(CC_MT5895)
    for (; i < 3; i++)
    {
        _prHwOsdPlaneReg[i] = (OSD_PLA_UNION_T *)(OSD_PLA1_REG + i * 0x100 + OFFSET_64BIT_SRE);
    }
    _prHwOsdPlaneReg[3] = (OSD_PLA_UNION_T *)(OSD_PLA4_REG + OFFSET_64BIT_SRE);
    _prHwOsdPlaneReg[4] = (OSD_PLA_UNION_T *)(OSD_PLA5_REG + OFFSET_64BIT_SRE);
    for (i = 0; i < 3; i++)
    {
        _prHwOsdPlaneReg[i+5] = (OSD_PLA_UNION_T *)(OSD_RT_PLA1_REG + i * 0x100 + OFFSET_64BIT_SRE);
    }
    _prHwOsdPlaneReg[8] = (OSD_PLA_UNION_T *)(OSD_RT_PLA5_REG + OFFSET_64BIT_SRE);
#else
    for (; i < 3; i++)
    {
        _prHwOsdPlaneReg[i] = (OSD_PLA_UNION_T *)(OSD_PLA1_REG + i * 0x100 + OFFSET_64BIT);
    }
    _prHwOsdPlaneReg[3] = (OSD_PLA_UNION_T *)(OSD_PLA4_REG + OFFSET_64BIT);
    _prHwOsdPlaneReg[4] = (OSD_PLA_UNION_T *)(OSD_PLA5_REG + OFFSET_64BIT);
#if defined(CC_MT5893) || defined(CC_MT5895)
    for (i = 0; i < 3; i++)
    {
        _prHwOsdPlaneReg[i+5] = (OSD_PLA_UNION_T *)(OSD_RT_PLA1_REG + i * 0x100 + OFFSET_64BIT);
    }
    _prHwOsdPlaneReg[8] = (OSD_PLA_UNION_T *)(OSD_RT_PLA5_REG + OFFSET_64BIT);
#endif
#endif
}
#endif

//-----------------------------------------------------------------------------
// Inter-file functions
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
/** Brief
 *  @param
 *  @return
 */
//-----------------------------------------------------------------------------
INT32 _OSD_PLA_ResetCacheRegs(UINT32 u4Plane)
{
    UINT32 u4Idx = 0;
    UINT32 u4RtPlane = OSD_INTERNAL_MAX_PLANE;
    OSD_VERIFY_PLANE(u4Plane);

    /* get a copy of reset value from hw */
    for (; u4Idx < OSD_PLA_REG_NUM; u4Idx++)
    {
        _rOsdPlaneReg[u4Plane].au4Reg[u4Idx]
            = _prHwOsdPlaneReg[u4Plane]->au4Reg[u4Idx];
        
        if (OSD_CHECK_LEFT_PLANE(u4Plane))
        {
            u4RtPlane = OSD_GET_RIGHT_PLANE(u4Plane);
            _rOsdPlaneReg[u4RtPlane].au4Reg[u4Idx]
                = _prHwOsdPlaneReg[u4RtPlane]->au4Reg[u4Idx];
        }
#ifdef GFX_SPEED_OPTION_1

        if (u4Idx == 3 && u4Plane == 1)
        {
            _rOsdPlaneReg[u4Plane].au4Reg[u4Idx] |= 0x2000000;
        }

#endif
    }

    return (INT32) OSD_RET_OK;
}

//-----------------------------------------------------------------------------
/** Brief
 *  @param
 *  @return
 */
//-----------------------------------------------------------------------------
INT32 _OSD_PLA_UpdateHwReg(UINT32 u4Plane)
{
    UINT32 u4Idx = 0;
#if defined(CC_MT5893) || defined(CC_MT5895)
    UINT32 u4RtPlane = OSD_PLANE_MAX_NUM;
#endif
    OSD_VERIFY_PLANE(u4Plane);

    if (!_fgOsdEnabelUpdate)
    {
        return (INT32) OSD_RET_OK;
    }

    for (; u4Idx < OSD_PLA_REG_NUM; u4Idx++)
    {
        _prHwOsdPlaneReg[u4Plane]->au4Reg[u4Idx]
            = _rOsdPlaneReg[u4Plane].au4Reg[u4Idx];
    }

#if defined(CC_MT5893) || defined(CC_MT5895)
    if (u4Plane == OSD_PLANE_1 || u4Plane == OSD_PLANE_2 || u4Plane == OSD_PLANE_3)
    {
        u4RtPlane = u4Plane + 5;
    }
    else if(u4Plane == OSD_PLANE_5)
    {
        u4RtPlane = OSD_RT_PLANE_5;
    }

    if (u4RtPlane < OSD_PLANE_MAX_NUM && OSD_IsOstg2Display())
    {
        for (u4Idx = 0; u4Idx < OSD_PLA_REG_NUM; u4Idx++)
        {
            _rOsdPlaneReg[u4RtPlane].au4Reg[u4Idx] = _rOsdPlaneReg[u4Plane].au4Reg[u4Idx];
            _prHwOsdPlaneReg[u4RtPlane]->au4Reg[u4Idx] = _rOsdPlaneReg[u4Plane].au4Reg[u4Idx];
        }
    }
    if (u4RtPlane < OSD_PLANE_MAX_NUM && OSD_IsDualOstgDisplay())
    {
        for (u4Idx = 0; u4Idx < OSD_PLA_REG_NUM; u4Idx++)
        {
            _prHwOsdPlaneReg[u4RtPlane]->au4Reg[u4Idx] = _rOsdPlaneReg[u4RtPlane].au4Reg[u4Idx];
        }
    }
#endif

    _OSD_UpdateReg();
    return (INT32) OSD_RET_OK;
}

#if defined(CC_MT5863) && defined(__KERNEL__) && !defined(CC_UBOOT)
INT32 _OSD_PLA_Get_Hw_RealBmpAddr(UINT32 u4Plane, UPTR *pupValue)
{
    BOOL fgEnable = FALSE;
    OSD_VERIFY_PLANE(u4Plane);
    if (pupValue == NULL)
    {
        return 0x0;
    }
    OSD_MMU_GetEnable(u4Plane, &fgEnable);
    if(fgEnable)
        *pupValue = (UPTR)(VIRTUAL_ADDRESS_BASE | (((UINT64)(_prHwOsdPlaneReg[u4Plane]->rField.t_rgn.u4DataAddrHigh) << 32)
                    | (_prHwOsdPlaneReg[u4Plane]->rField.t_rgn.u4DataAddr << 4)));
    else
        *pupValue = (UPTR)(((UINT64)(_prHwOsdPlaneReg[u4Plane]->rField.t_rgn.u4DataAddrHigh) << 32)
                    | (_prHwOsdPlaneReg[u4Plane]->rField.t_rgn.u4DataAddr << 4));
    return OSD_RET_OK;
}
#else
INT32 _OSD_PLA_Get_Hw_RealBmpAddr(UINT32 u4Plane, UPTR *pupValue)
{
    OSD_VERIFY_PLANE(u4Plane);
    if (pupValue == NULL)
    {
        return 0x0;
    }

    *pupValue = (UPTR)(_prHwOsdPlaneReg[u4Plane]->rField.t_rgn.u4DataAddr << 4);
    return OSD_RET_OK;
}
#endif

INT32 _OSD_PLA_Get_Hw_RealClipH(UINT32 u4Plane, UINT32 *pu4Value)
{
    OSD_VERIFY_PLANE(u4Plane);
    if (pu4Value == NULL)
    {
        return 0x0;
    }

    *pu4Value = (_prHwOsdPlaneReg[u4Plane]->rField.t_rgn.u4HClip);
    return OSD_RET_OK;
}

//-----------------------------------------------------------------------------
/** dump osd debug info
 *  @param  u4Plane osd plane
 *  @retval OSD_RET_OK success
 */
//-----------------------------------------------------------------------------
INT32 OSD_PLA_Dump(UINT32 u4Plane)
{
    OSD_PLA_UNION_T *prOsdPlaneReg = NULL;
    UINT32 u4Region, u4List;
    UINT32 u4Count = 0;
    OSD_VERIFY_PLANE(u4Plane);
    prOsdPlaneReg = (OSD_PLA_UNION_T *)_prHwOsdPlaneReg[u4Plane];

    if (!prOsdPlaneReg)
    {
        return (INT32) OSD_RET_OK;
    }

    LOG(0,"\n");
    LOG(0,"OSD PLANE[ %d ]\n", u4Plane + 1);
    LOG(0,"    Enable   =%-2d FirstRegion=0x%-8x HStart  =%-4d VStart=%-4d\n",
           prOsdPlaneReg->rField.fgEn,
           prOsdPlaneReg->rField.u4HeaderAddr << 4,
           OSD_PLA_GetHStart(u4Plane),
           OSD_PLA_GetVStart(u4Plane));

    if (!prOsdPlaneReg->rField.u4HeaderAddr)
    {
        return (INT32) OSD_RET_OK;
    }

    LOG(0,"    3DShutter=%-2d RightRegion=0x%-8x FastMute=%-4d Fading=%-4d\n",
           prOsdPlaneReg->rField.fgShutter,
           prOsdPlaneReg->rField.u4RightHeaderAddr << 4,
           prOsdPlaneReg->rField.fgFastMute,
           prOsdPlaneReg->rField.u4Fading);

    // dump scaler
#if defined(CC_MT5893) || defined(CC_MT5895)
    if (prOsdPlaneReg->rField.fgEn && (u4Plane <= (UINT32)OSD_PLANE_3 || (u4Plane >= (UINT32)OSD_RT_PLANE_1 && u4Plane <= (UINT32)OSD_RT_PLANE_3)))
#else
    if (prOsdPlaneReg->rField.fgEn && (u4Plane <= (UINT32)OSD_PLANE_3))
#endif
    {
        IGNORE_RET(OSD_SC_Dump(OSD_PLANE_TO_SCALER(u4Plane)));
    }
#if defined(CC_MT5893) || defined(CC_MT5895)
    if (OSD_IsDualOstgDisplay() && (u4Plane < OSD_EXTERNAL_MAX_PLANE))
    {
        if (u4Plane == OSD_PLANE_5)
        {
            prOsdPlaneReg = (OSD_PLA_UNION_T *)_prHwOsdPlaneReg[OSD_RT_PLANE_5];
        }
        else
        {
            prOsdPlaneReg = (OSD_PLA_UNION_T *)_prHwOsdPlaneReg[u4Plane + OSD_RT_PLANE_1];
        }

        if (NULL == prOsdPlaneReg)
        {
            return (INT32)OSD_RET_OK;
        }

        LOG(1,"+RIGHT PLANE[ %d ]\n", u4Plane + 1);
        LOG(1,"    Enable   =%-2d FirstRegion=0x%-8x HStart  =%-4d VStart=%-4d\n",
               prOsdPlaneReg->rField.fgEn,
               prOsdPlaneReg->rField.u4HeaderAddr << 4,
               OSD_PLA_GetHStart(u4Plane),
               OSD_PLA_GetVStart(u4Plane));
        if (!prOsdPlaneReg->rField.u4HeaderAddr)
        {
            LOG(0, "    Right header is null\n");
        }
    }
#endif
#if defined(__KERNEL__) && !defined(CC_UBOOT) && !defined(CONFIG_TV_DRV_VFY)
    LOG(0,"    BufferMode[%d](0:unknown 1:frontonly 2:backvideo 4:backsys 8:triple 16:windows)\n",
           fb_osd_get_buffer_mode(u4Plane));
#endif
    // dump region
    if (prOsdPlaneReg->rField.u4HeaderAddr != 0)
    {
        u4List = OSD_PLA_GetFirstRegionList(u4Plane);
        IGNORE_RET(OSD_RGN_LIST_GetCount(u4List, (INT32 *)&u4Count));
        IGNORE_RET(OSD_RGN_LIST_GetHead(u4List, (INT32 *)&u4Region));
        LOG(0,"REGION List[ %d ]\n", u4List);

        while (u4Count--)
        {
            UINT32 u4Next;
            IGNORE_RET(OSD_RGN_Dump(u4Region));
            IGNORE_RET(OSD_RGN_Get(u4Region, (INT32)OSD_RGN_NEXT, &u4Next));
            u4Region = u4Next;
        }

        if (prOsdPlaneReg->rField.u4RightHeaderAddr)
        {
            _OSD_RGN_GetRegionId((prOsdPlaneReg->rField.u4RightHeaderAddr << 4), &u4Region);
            LOG(0,"3D Shutter Right Region[ %d ]:\n", u4Region);
            IGNORE_RET(OSD_RGN_Dump(u4Region));
        }
#if defined(CC_MT5893) || defined(CC_MT5895)
        if (OSD_IsDualOstgDisplay())
        {
            u4List = OSD_PLA_GetCurrentInternalRgnList(u4Plane);
            IGNORE_RET(OSD_RGN_LIST_GetCount(u4List, (INT32 *)&u4Count));
            IGNORE_RET(OSD_RGN_LIST_GetHead(u4List, (INT32 *)&u4Region));
            LOG(0,"Internal Region List[%d]\n", u4List);

            while (u4Count--)
            {
                UINT32 u4Next;
                IGNORE_RET(OSD_RGN_Dump(u4Region));
                IGNORE_RET(OSD_RGN_Get(u4Region, (INT32)OSD_RGN_NEXT, &u4Next));
                u4Region = u4Next;
            }
        }
#endif
    }

    LOG(0,"\n");
    return (INT32) OSD_RET_OK;
}

OSD_PLA_SETGET_TMPL(Enable, fgEn)
OSD_PLA_SETGET_TMPL(FakeHdr, fgFakeHdr)
OSD_PLA_SETGET_TMPL(PrngEn, fgPrngEn)
OSD_PLA_SETGET_TMPL(PrngMode, fgPrngMode)
OSD_PLA_SETGET_TMPL(AEdgeDetEn, fgAEdgeDetEn)
OSD_PLA_SETGET_TMPL(CLKeySel, fgCLKeySel)
OSD_PLA_SETGET_TMPL(MatixEnable, fgEnableMatrix)

OSD_PLA_SETGET_TMPL(HFilter, fgHFilter)
OSD_PLA_SETGET_TMPL(Blending, u4Blending)
OSD_PLA_SETGET_TMPL(Fading, u4Fading)
OSD_PLA_SETGET_TMPL(LSB10Bit, fgLSBAlpha)
OSD_PLA_SETGET_TMPL(ContReqLmt, u4ContReqLmt)
OSD_PLA_SETGET_TMPL(FifoSize, u4FifoSize)
OSD_PLA_SETGET_TMPL(VacTh, u4VacTh)
OSD_PLA_SETGET_TMPL(PauseCnt, u4PauseCnt)
OSD_PLA_SETGET_TMPL(ContReqLmt0, u4ContReqLmt0)
OSD_PLA_SETGET_TMPL(BurstDis, fgBurstDis)
OSD_PLA_SETGET_TMPL(Shutter, fgShutter)
OSD_PLA_SETGET_ADDRESS_TMPL(HeaderAddr, u4HeaderAddr)
OSD_PLA_SETGET_ADDRESS_TMPL(RightHeaderAddr, u4RightHeaderAddr)
OSD_PLA_GET_HW_ADDRESS_TMPL(RealHeaderAddr, u4RealHeaderAddr)
OSD_PLA_SETGET_TMPL(FastMute, fgFastMute)
OSD_PLA_SETGET_TMPL(NewFastMute, fgEnNewFastMute)
OSD_PLA_SETGET_TMPL(EnHdrIrq, fgEnHdrIrq)
OSD_PLA_SETGET_TMPL(ClrHdrIrq, fgClrHdrIrq)
OSD_PLA_SETGET_TMPL(HdrIrqStatus, fgHdrIrqStatus)
OSD_PLA_SETGET_TMPL(PremulEn, fgPremulEn)
OSD_PLA_SETGET_TMPL(EnHwRstDec, fgEnHwRstDec)
OSD_PLA_SETGET_TMPL(FSMProtDis, fgFSMProtDis)

