/* 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: fvr.h,v $
 * $Revision$
 *
 *---------------------------------------------------------------------------*/

/** @file fvr.h
 *  FVR driver - FVR header
 */

#ifndef _FVR_H
#define _FVR_H

#include "dmx.h"
#include "fvr_if.h"
#include "x_hal_5381.h"
#include "tlv_fvr_if.h"
//-----------------------------------------------------------------------------
// Constant definitions
//-----------------------------------------------------------------------------

//
// Base addresses
//
#define FVR_GBL_SIZE                        (16)   // 64 bytes

#if defined(CC_MT5895)
#define FVR_GBL_COMMON_SIZE                 (27)   // [Capy]108 bytes
#elif defined(CC_MT5891) || defined(CC_MT5886) || defined(CC_MT5893)
#define FVR_GBL_COMMON_SIZE                 (20)   // 80 bytes
#else //MT5890, MT5882, MT5883
#define FVR_GBL_COMMON_SIZE                 (31)   // 124 bytes
#endif

#define FVR_CI14_GBL_SIZE                   (16)  //64bytes for per one ,ci+1.4

#if defined(CC_MT5890)
#define FVR_PID_SIZE                        (9)    // 36 bype Record PID data structure,total 128share
#elif defined(CC_MT5891) || defined(CC_MT5886) ||( defined(CC_MT5893) && defined(CC_MT5893_ES1))
#define FVR_PID_SIZE                        (8)    // 32 bype Record PID data structure,total 128share
#elif defined(CC_MT5895)
#define FVR_PID_SIZE                        (20) //capy
#elif defined(CC_MT5893)
#define FVR_PID_SIZE                        (IS_IC_5893_ES1()?(8):(15))   // 60 bype Record PID data structure,total 128share
#else  //MT5882 and MT5883
#define FVR_PID_SIZE                        (7)    // 28 bype Record PID data structure,total 128share
#endif

#define FVR_PID_TABLE_BASE                  (DEMUX0_BASE + 0xE00) //0x17E00

#if defined(CC_MT5890)
#define FVR_GBL_PID_BASE                    (DEMUX7_BASE + 0x1F4) //0x541f4
#define FVR_GBL_PID_BASE1                   (DEMUX7_BASE + 0x234) //0x54234
#define FVR_GBL_PID_BASE2                   (DEMUX7_BASE + 0x274) //0x54274
#define FVR_GBL_PID_BASE3                   (DEMUX7_BASE + 0x2B4) //0x542B4
#define FVR_GBL_CI14_PID_BASE               (DEMUX7_BASE + 0x2F4) //0x542F4

#define FVR_GBL_COMMON_REGION               (DEMUX7_BASE + 0x334) //0x54334

#define FVR_PER_PID_OFFSET                  (0x2D00)
#define FVR_PER_PID_BASE                    (DEMUX2_BASE + FVR_PER_PID_OFFSET) //0xf001bd00

#define FVR_KEY_BASE                        (DEMUX9_BASE + 0xC80) //0xf006AC80

#elif defined(CC_MT5891) || defined(CC_MT5886)
#define FVR_GBL_PID_BASE                    (DEMUX7_BASE + 0x7F4) //0x547f4
#define FVR_GBL_PID_BASE1                   (DEMUX7_BASE + 0x834) //0x54834
#define FVR_GBL_PID_BASE2                   (DEMUX7_BASE + 0x874) //0x54874
#define FVR_GBL_PID_BASE3                   (DEMUX7_BASE + 0x8B4) //0x548B4
#define FVR_GBL_CI14_PID_BASE               (DEMUX7_BASE + 0x8F4) //0x548F4

#define FVR_GBL_COMMON_REGION               (DEMUX7_BASE + 0x934) //0x54934

#define FVR_PER_PID_OFFSET                  (0x3600)
#define FVR_PER_PID_BASE                    (DEMUX2_BASE + FVR_PER_PID_OFFSET) //0xf001c600
#define FVR_PER_PID_BASE2                   (DEMUX7_BASE) //0xf0054000
#define FVR_BASE_PID_NUM                    (80)
#define FVR_BASE2_PID_NUM                   (48)
#define FVR_KEY_BASE                        (DEMUX9_BASE + 0xC80) //0xf006AC80

#elif defined(CC_MT5895)

#define FVR_GBL_PID_BASE                    (DEMUX11_BASE + 0x210) //0x571f4 [Capy]
#define FVR_GBL_PID_BASE1                   (DEMUX11_BASE + 0x27C) //0x57234
#define FVR_GBL_PID_BASE2                   (DEMUX11_BASE + 0x2E8) //0x57274
#define FVR_GBL_PID_BASE3                   (DEMUX11_BASE + 0x354) //0x572B4
#define FVR_GBL_CI14_PID_BASE               (DEMUX11_BASE + 0x3C0) //0x572F4
#define FVR_GBL_COMMON_REGION               (DEMUX11_BASE + 0x42C) //0x57334

#define FVR_PER_PID_OFFSET                  0x4604
#define FVR_PER_PID_BASE                    (DEMUX16_BASE + FVR_PER_PID_OFFSET)
#define FVR_BASE_PID_NUM                    128
#define FVR_KEY_BASE                        DEMUX9_BASE + 0xC80

#elif defined(CC_MT5893)
#define FVR_GBL_PID_BASE                    (IS_IC_5893_ES1()?(DEMUX7_BASE + 0x7F4):(DEMUX11_BASE + 0x1F4)) //0x571f4
#define FVR_GBL_PID_BASE1                   (IS_IC_5893_ES1()?(DEMUX7_BASE + 0x834):(DEMUX11_BASE + 0x234)) //0x57234
#define FVR_GBL_PID_BASE2                   (IS_IC_5893_ES1()?(DEMUX7_BASE + 0x874):(DEMUX11_BASE + 0x274)) //0x57274
#define FVR_GBL_PID_BASE3                   (IS_IC_5893_ES1()?(DEMUX7_BASE + 0x8B4):(DEMUX11_BASE + 0x2B4)) //0x572B4
#define FVR_GBL_CI14_PID_BASE               (IS_IC_5893_ES1()?(DEMUX7_BASE + 0x8F4):(DEMUX11_BASE + 0x2F4)) //0x572F4
#define FVR_GBL_COMMON_REGION               (IS_IC_5893_ES1()?(DEMUX7_BASE + 0x934):(DEMUX11_BASE + 0x334)) //0x57334

#define FVR_PER_PID_OFFSET                  (IS_IC_5893_ES1()?(0x3600):(0x4604))
#define FVR_PER_PID_BASE                    (IS_IC_5893_ES1()?(DEMUX2_BASE + FVR_PER_PID_OFFSET):(DEMUX16_BASE + FVR_PER_PID_OFFSET)) //0xf005A604
#define FVR_BASE_PID_NUM                    (IS_IC_5893_ES1()?(80):(128))
#define FVR_KEY_BASE                        (IS_IC_5893_ES1()?(DEMUX11_BASE + 0xC80):(DEMUX9_BASE + 0xC80)) //0xf006AC80

////////////////////////////////5893 E1 define/////////////////////////////////////////////////
#define FVR_PER_PID_BASE2                   (DEMUX7_BASE) //0xf0054000
#define FVR_BASE2_PID_NUM                   (48)
/////////////////////////////////////////////////////////////////////////////////////////////

#else  //MT5882 and MT5883

#define FVR_GBL_PID_BASE                    (DEMUX7_BASE + 0xA4)  //0x540A4
#define FVR_GBL_PID_BASE1                   (DEMUX7_BASE + 0xE4)  //0x540E4
#define FVR_GBL_PID_BASE2                   (DEMUX7_BASE + 0x124) //0x54124
#define FVR_GBL_PID_BASE3                   (DEMUX7_BASE + 0x164) //0x54164
#define FVR_GBL_CI14_PID_BASE               (DEMUX7_BASE + 0x1A4) //0x541A4

#define FVR_GBL_COMMON_REGION               (DEMUX7_BASE + 0x1E4) //0x541E4

#define FVR_PER_PID_OFFSET                  (0x1E00)
#define FVR_PER_PID_BASE                    (DEMUX2_BASE + FVR_PER_PID_OFFSET) //0x1AE00

#define FVR_KEY_BASE                        (DEMUX7_BASE + 0xD24) //0x54D24
#endif

#if defined(CC_MT5893)

#define FVR_SIT_BUFFER_OFFSET             (IS_IC_5893_ES1()?(0x4C08):(0x7608)) //0x57608
#define FVR_SIT_BUFFER_OFFSET1            (IS_IC_5893_ES1()?(0x4CBC):(0x76BC)) //0x576BC
#define FVR_SIT_BUFFER_OFFSET2            (IS_IC_5893_ES1()?(0x4D70):(0x7770)) //0x57770
#define FVR_SIT_BUFFER_OFFSET3            (IS_IC_5893_ES1()?(0x4E24):(0x7824)) //0x57824

#define FVR_SIT_BUFFER_BASE               (IS_IC_5893_ES1()?(DEMUX7_BASE + 0xC08):(DEMUX11_BASE + 0x608)) //0x57608
#define FVR_SIT_BUFFER_BASE1              (IS_IC_5893_ES1()?(DEMUX7_BASE + 0xCBC):(DEMUX11_BASE + 0x6BC)) //0x576BC
#define FVR_SIT_BUFFER_BASE2              (IS_IC_5893_ES1()?(DEMUX7_BASE + 0xD70):(DEMUX11_BASE + 0x770)) //0x57770
#define FVR_SIT_BUFFER_BASE3              (IS_IC_5893_ES1()?(DEMUX7_BASE + 0xE24):(DEMUX11_BASE + 0x824)) //0x57824

#elif defined(CC_MT5895)
#define FVR_SIT_BUFFER_OFFSET             (0x773C)
#define FVR_SIT_BUFFER_OFFSET1            (0x77FC)
#define FVR_SIT_BUFFER_OFFSET2            (0x78BC)
#define FVR_SIT_BUFFER_OFFSET3            (0x797C)

#define FVR_SIT_BUFFER_BASE               (DEMUX11_BASE + 0x73C)
#define FVR_SIT_BUFFER_BASE1              (DEMUX11_BASE + 0x7FC)
#define FVR_SIT_BUFFER_BASE2              (DEMUX11_BASE + 0x8BC)
#define FVR_SIT_BUFFER_BASE3              (DEMUX11_BASE + 0x97C)

#else /* Not MT5893 IC */

#if defined(CC_MT5891) || defined(CC_MT5886)

#define FVR_SIT_BUFFER_OFFSET               (0x4C08)
#define FVR_SIT_BUFFER_OFFSET1              (0x4CBC)
#define FVR_SIT_BUFFER_OFFSET2              (0x4D70)
#define FVR_SIT_BUFFER_OFFSET3              (0x4E24)

#else //MT5882 and MT5883

#define FVR_SIT_BUFFER_OFFSET               (0x4A34)
#define FVR_SIT_BUFFER_OFFSET1              (0x4AE8)
#define FVR_SIT_BUFFER_OFFSET2              (0x4B9C)
#define FVR_SIT_BUFFER_OFFSET3              (0x4C50)

#endif

#define FVR_SIT_BUFFER_BASE                 (DEMUX7_BASE + FVR_SIT_BUFFER_OFFSET - 0x4000)
#define FVR_SIT_BUFFER_BASE1                (DEMUX7_BASE + FVR_SIT_BUFFER_OFFSET1 - 0x4000)
#define FVR_SIT_BUFFER_BASE2                (DEMUX7_BASE + FVR_SIT_BUFFER_OFFSET2 - 0x4000)
#define FVR_SIT_BUFFER_BASE3                (DEMUX7_BASE + FVR_SIT_BUFFER_OFFSET3 - 0x4000)

#endif

#if defined(CC_MT5890) || defined(CC_MT5891) || defined(CC_MT5886) || defined(CC_MT5893)
#define FVR_CLOCK                           (432000000) //oryx/gazelle  demux clock
#elif defined(CC_MT5895)
#define FVR_CLOCK                           (648000000) //capy  demux clock
#else  //MT5882 and MT5883
#define FVR_CLOCK                           (324000000) //capri demux clock
#endif

//
// Interrupt
//
#define FVR_INT_ERR_MASK                   0xFFFF
#define FVR_INT_ERR_REC_DBM                (1 << 0)
#define FVR_INT_ERR_uP                     (1 << 2)

#define FVR_INT_STATUS_MASK                0xFFFF0000
#define FVR_INT_STATUS_REC_DBM             (1 << 16)
#define FVR_INT_STATUS_uP                  (1 << 18)

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

#define FVR_SIT_BASE_W(base, word)        ((volatile UINT32*)(UPTR)(OFFSET_64BIT + (base)))[(word)]

#define FVR_SIT_ARY_W(idx, word)         \
            FVR_SIT_BASE_W((idx==0) ? FVR_SIT_BUFFER_BASE : \
            (idx==1) ? FVR_SIT_BUFFER_BASE1 : \
            (idx==2) ? FVR_SIT_BUFFER_BASE2 : \
            FVR_SIT_BUFFER_BASE3 , word)

///
/// FVR PID data structure access commands
///
#define FVR_GBL_BASE_W(base, word)          ((volatile UINT32*)(UPTR)(OFFSET_64BIT + (base)))[(word)]
#define FVR_GBL_BASE_S(base, word)          ((UINT32)(base) + 4 * word )

#define FVR_GBL_ARY_W(idx, word)         \
            FVR_GBL_BASE_W((idx==0) ? FVR_GBL_PID_BASE : \
            (idx==1) ? FVR_GBL_PID_BASE1 : \
            (idx==2) ? FVR_GBL_PID_BASE2 : \
            (idx==3) ? FVR_GBL_PID_BASE3 : \
            FVR_GBL_CI14_PID_BASE, word)


#define FVR_GBL_ARY_S(idx, word)         \
            FVR_GBL_BASE_S((idx==0) ? FVR_GBL_PID_BASE : \
            (idx==1) ? FVR_GBL_PID_BASE1 : \
            (idx==2) ? FVR_GBL_PID_BASE2 : \
            (idx==3) ? FVR_GBL_PID_BASE3 : \
            FVR_GBL_CI14_PID_BASE, word)



#define FVR_GBL_ARY(idx)         \
            ((idx==0) ? FVR_GBL_PID_BASE : \
            (idx==1) ? FVR_GBL_PID_BASE1 : \
            (idx==2) ? FVR_GBL_PID_BASE2 : \
            (idx==3) ? FVR_GBL_PID_BASE3 : \
            FVR_GBL_CI14_PID_BASE)

//////////////////////////////////////////////////////////////////////
#define FVR_GBL_BASE_W_ADDR(base, word)          ((volatile UINT32*)(UPTR)((base) + (4*word)))

#define FVR_GBL_ARY_W_ADDR(idx, word)         \
            FVR_GBL_BASE_W_ADDR((idx==0) ? FVR_GBL_PID_BASE : \
            (idx==1) ? FVR_GBL_PID_BASE1 : \
            (idx==2) ? FVR_GBL_PID_BASE2 : \
            (idx==3) ? FVR_GBL_PID_BASE3 : \
            FVR_GBL_CI14_PID_BASE, word)

/////////////////////////////////////////////////////////////////////

/*the following two item used for ciplus1.4*/
#define FVR_GBL_CI14_REPLACE_BYTE_CONTROL    FVR_GBL_BASE_W(FVR_GBL_CI14_PID_BASE,9)
#define FVR_GBL_CI14_TS_SYNCBYTE_SETTING     FVR_GBL_BASE_W(FVR_GBL_CI14_PID_BASE,10)

#define FVR_GBL_TIMEINFO                     FVR_GBL_BASE_W(FVR_GBL_COMMON_REGION, 0)
#define FVR_GBL_TIMEINFO_UPDATE              FVR_GBL_BASE_W(FVR_GBL_COMMON_REGION, 1)
#define FVR_GBL_SERIALNUM_ADDR               FVR_GBL_BASE_W(FVR_GBL_COMMON_REGION, 2)

#define FVR_GBL_DMEMENDADDR_TS0              FVR_GBL_BASE_W(FVR_GBL_COMMON_REGION, 3)
#define FVR_GBL_PKTCOUNTER_TS0               FVR_GBL_BASE_W(FVR_GBL_COMMON_REGION, 4)

#define FVR_GBL_DMEMENDADDR_TS1              FVR_GBL_BASE_W(FVR_GBL_COMMON_REGION, 5)
#define FVR_GBL_PKTCOUNTER_TS1               FVR_GBL_BASE_W(FVR_GBL_COMMON_REGION, 6)

#define FVR_GBL_DMEMENDADDR_TS2              FVR_GBL_BASE_W(FVR_GBL_COMMON_REGION, 7)
#define FVR_GBL_PKTCOUNTER_TS2               FVR_GBL_BASE_W(FVR_GBL_COMMON_REGION, 8)

#define FVR_GBL_DMEMENDADDR_TS3              FVR_GBL_BASE_W(FVR_GBL_COMMON_REGION, 9)
#define FVR_GBL_PKTCOUNTER_TS3               FVR_GBL_BASE_W(FVR_GBL_COMMON_REGION, 10)

#define FVR_GBL_DMEMENDADDR_CI14              FVR_GBL_BASE_W(FVR_GBL_COMMON_REGION, 11)
#define FVR_GBL_PKTCOUNTER_CI14               FVR_GBL_BASE_W(FVR_GBL_COMMON_REGION, 12)

#if defined(CC_MT5891) || defined(CC_MT5886) ||( defined(CC_MT5893) && defined(CC_MT5893_ES1))
#define FVR_PID_DATA_LEN                       (8)  // 32Byte pid data structure
#define FVR_PER_PID_W(base, word)           ((volatile UINT32*)(UPTR)(OFFSET_64BIT + (base)))[(word)]

#define FVR_PER_PID_S(pidx)                 ((pidx<FVR_BASE_PID_NUM) ? (FVR_PER_PID_BASE + FVR_PID_SIZE * 4 * (pidx)) : \
                                                                       (FVR_PER_PID_BASE2 + FVR_PID_SIZE * 4 * ((pidx) - FVR_BASE_PID_NUM)))

#define FVR_PER_PID_S_W(pidx, word)         FVR_PER_PID_W((pidx<FVR_BASE_PID_NUM) ? FVR_PER_PID_BASE : \
                                                FVR_PER_PID_BASE2, (FVR_PID_SIZE * ((pidx<FVR_BASE_PID_NUM)? pidx : (pidx - FVR_BASE_PID_NUM))) + (word))
//////////////////////////////////////////////////////////////////////

#define FVR_PER_PID_W_ADDR(base, word)           ((volatile UINT32*)(UPTR)((base) + (word)))

#define FVR_PER_PID_S_W_AADR(pidx, word)         FVR_PER_PID_W_ADDR((pidx<FVR_BASE_PID_NUM) ? FVR_PER_PID_BASE : \
                                                        FVR_PER_PID_BASE2, ((FVR_PID_SIZE *4 ) * ((pidx<FVR_BASE_PID_NUM)? pidx : (pidx - FVR_BASE_PID_NUM))) + (4*word))

////////////
/////////////////////////////////////////////////////////////////////

#elif defined(CC_MT5893)
#define FVR_PID_DATA_LEN                    (IS_IC_5893_ES1()?(8):(15))  // 60 Byte pid data structure

#define FVR_PER_PID_W(base, word)           ((volatile UINT32*)(UPTR)(OFFSET_64BIT + (base)))[(word)]

#define FVR_PER_PID_S(pidx)  				(IS_IC_5893_ES1()? \
                                            ((pidx<FVR_BASE_PID_NUM) ? (FVR_PER_PID_BASE + FVR_PID_SIZE * 4 * (pidx)) : \
                                            (FVR_PER_PID_BASE2 + FVR_PID_SIZE * 4 * ((pidx) - FVR_BASE_PID_NUM))):\
                                            (FVR_PER_PID_BASE + FVR_PID_SIZE *4* (pidx)))

#define FVR_PER_PID_S_W(pidx, word)         FVR_PER_PID_W((IS_IC_5893_ES1()?((pidx<FVR_BASE_PID_NUM) ? FVR_PER_PID_BASE : \
                                                           FVR_PER_PID_BASE2):(FVR_PER_PID_BASE)), \
                                                           (IS_IC_5893_ES1()?((FVR_PID_SIZE * ((pidx<FVR_BASE_PID_NUM)? pidx : (pidx - FVR_BASE_PID_NUM))) + (word)):\
                                                           ((FVR_PID_SIZE * pidx) + (word))))

//////////////////////////////////////////////////////////////////////
#define FVR_PER_PID_W_ADDR(base, word)           ((volatile UINT32*)(UPTR)((base) + (word)))

#define FVR_PER_PID_S_W_AADR(pidx,word)   FVR_PER_PID_W_ADDR((IS_IC_5893_ES1()?\
                                                              ((pidx<FVR_BASE_PID_NUM) ? FVR_PER_PID_BASE : \
                                                        FVR_PER_PID_BASE2):(FVR_PER_PID_BASE)),\
                                                        (IS_IC_5893_ES1()?(((FVR_PID_SIZE *4 ) * ((pidx<FVR_BASE_PID_NUM)? pidx : (pidx - FVR_BASE_PID_NUM))) + (4*word)):\
                                                         (((FVR_PID_SIZE *4) * (pidx)) + (4*word))))

#elif defined(CC_MT5863) || defined(CC_MT5865)
#define FVR_PID_DATA_LEN                       (7)  // 28 Byte pid data structure
#define FVR_PER_PID_W(word)                 ((volatile UINT32*)(UPTR)(FVR_PER_PID_BASE + OFFSET_64BIT))[(word)]

#define FVR_PER_PID_S(pidx)               (FVR_PER_PID_BASE + FVR_PID_SIZE * 4 * (pidx))

#define FVR_PER_PID_S_W(pidx, word)         FVR_PER_PID_W((FVR_PID_SIZE * (pidx)) + (word))

#elif defined(CC_MT5895)
#define FVR_PID_DATA_LEN                    15  // 60 Byte pid data structure

#define FVR_PER_PID_W(base, word)           ((volatile UINT32*)(UPTR)(OFFSET_64BIT + (base)))[(word)]

#define FVR_PER_PID_S(pidx)                 (FVR_PER_PID_BASE + FVR_PID_SIZE * 4 * (pidx))

#define FVR_PER_PID_S_W(pidx, word)          FVR_PER_PID_W(FVR_PER_PID_S(pidx), word)

#define FVR_PER_PID_W_ADDR(base, word)       ((volatile UINT32*)(UPTR)(base) + (word))

#define FVR_PER_PID_S_W_AADR(pidx, word)     FVR_PER_PID_W_ADDR(FVR_PER_PID_S(pidx), word)

#else // MT5890, MT5882,  MT5883
#define FVR_PID_DATA_LEN                       (7)  // 28 Byte pid data structure
#define FVR_PER_PID_W(word)                 ((volatile UINT32*)(UPTR)(FVR_PER_PID_BASE))[(word)]

#define FVR_PER_PID_S(pidx)               (FVR_PER_PID_BASE + FVR_PID_SIZE * 4 * (pidx))

#define FVR_PER_PID_S_W(pidx, word)         FVR_PER_PID_W((FVR_PID_SIZE * (pidx)) + (word))
//////////////////////////////////////////////////////////////////////
#define FVR_PER_PID_S_W_AADR(pidx,word)           ((volatile UINT32*)(UPTR)(FVR_PER_PID_BASE + ((FVR_PID_SIZE *4) * (pidx)) + (4*word)))
/////////////////////////////////////////////////////////////////////

#endif

/// PID index table access command
#define FVR_PID_INDEX_TABLE(pidx)           ((volatile UINT32*)(UPTR)(OFFSET_64BIT + FVR_PID_TABLE_BASE))[(pidx)]
#define FVR_PID_INDEX_TABLE_ADDR(pidx)      ((volatile UINT32*)(UPTR)(FVR_PID_TABLE_BASE + (4*pidx)))

#define FVR_KEY_EVEN_KEY(idx, word)         ((volatile UINT32*)(UPTR)(OFFSET_64BIT + FVR_KEY_BASE + (idx * 96)))[(word)]
#define FVR_KEY_ODD_KEY(idx, word)          ((volatile UINT32*)(UPTR)(OFFSET_64BIT + FVR_KEY_BASE + ((idx * 96) + 48)))[(word)]
#define FVR_KEY_EVEN_IV(idx, word)          ((volatile UINT32*)(UPTR)(OFFSET_64BIT + FVR_KEY_BASE + ((idx * 96) + 32)))[(word)]
#define FVR_KEY_ODD_IV(idx, word)           ((volatile UINT32*)(UPTR)(OFFSET_64BIT + FVR_KEY_BASE + ((idx * 96) + 80)))[(word)]

#define TLV_FVR_IV_BASE                     (DEMUX9_BASE + 0xF28) //0x6AF28
#define TLV_FVR_AES_IV(idx, word)          ((volatile UINT32*)(UPTR)(OFFSET_64BIT + TLV_FVR_IV_BASE + (idx * 16)))[(word)]

#if defined(CC_MT5895)
#define TLV_FVR_SCRAMBLE_PRE_BYTES_IV_BASE      (DEMUX11_BASE + 0xB74) //REC0 0x57B74 12word, REC1 0x57BA4 12word. REC3 0x57BD4
#define TLV_FVR_SCRAMBLE_PRE_BYTES_IV_BASE_LEN   (36) //36 word
#define TLV_FVR_SCRAMBLE_PRE_BYTES              (DEMUX11_BASE + 0xC04)
#define TLV_FVR_SCRAMBLE_PRE_BYTES_LEN          (12)  //4*3 word
#else
#define TLV_FVR_SCRAMBLE_PRE_BYTES_IV_BASE      (DEMUX11_BASE + 0x9A8) //REC0 0x579a8 12word, REC1 0x579D8 12word.
#define TLV_FVR_SCRAMBLE_PRE_BYTES_IV_BASE_LEN  (24) //24 word
#define TLV_FVR_SCRAMBLE_PRE_BYTES              (DEMUX11_BASE + 0xA08)
#define TLV_FVR_SCRAMBLE_PRE_BYTES_LEN          (8)  //4*2 word
#endif

#define TLV_PRE_BYPE(word) ((volatile UINT32*)(UPTR)(OFFSET_64BIT + TLV_FVR_SCRAMBLE_PRE_BYTES_IV_BASE ))[(word)]
#define TLV_FVR_IV_BYPE(word) ((volatile UINT32*)(UPTR)(OFFSET_64BIT + TLV_FVR_IV_BASE))[(word)]


///////////////////////////////////////////////////////////////////
#define FVR_ENC_KEY_INDEX_MAX               (4)
#define FVR_ENC_KEY_LEN                     (24) // 24word  96Byte  : enc key len
#define FVR_ENC_KEY_DATA(idx, word)         ((volatile UINT32*)(UPTR)(OFFSET_64BIT + FVR_KEY_BASE + (idx * 96)))[(word)]
#define FVR_ENC_KEY_DATA_ADDR(idx, word)    ((volatile UINT32*)(UPTR)(FVR_KEY_BASE + (idx * 96) + (4 * word)))
//////////////////////////////////////////////////////////////////
#define DATASIZE(rp, wp, size)      \
    (((rp) <= (wp)) ? ((wp) - (rp)) : (((wp) + (size)) - (rp)))

//-----------------------------------------------------------------------------
// Type def
//-----------------------------------------------------------------------------
typedef struct
{
    UPTR u4BufStart;
    UPTR u4BufEnd;
    UPTR u4Rp;
    UPTR u4Wp;
    UINT16 u2CurPktCount;
    UINT16 u2TargetPktCount;
    UINT32 u4LongPktCount;
    UPTR u4PktRp;

    BOOL fgAllocateBuffer;
    USIZE u4BufSize;

    BOOL fgSetAlign;
    UINT32 u4BufAlign;

    PFN_FVR_GBL_NOTIFY pfnNotifyFunc;
    void* pvNotifyTag;

    UINT32 u4TimeToNotify;

    UPTR u4PicWorkingBuf;
	/*add new item for ciplus1.4 */
	UINT32 u4SyncPattern; /*ts3 bit[31:24], ts2 bit[23:16], ts1 bit[15:8], ts0bit[7:0]*/
	UINT8  u1CiTsidx; /*for ci input ts index settings*/
	UINT8  u1SyncMask; /*use bit[3:0] */
	BOOL   fgTimeStamp;  /*  for every global regtion,ucode set this to HW  TRUE: enable,FALSE:disable*/
	BOOL   fgRemuxDirection; /* if the 34thByte (HW enable:1),then ucode config HW CP7_0,data inflow cp7, not remux buffer */
    UINT64 u8BufRingCounter;
} FVR_GBL_STRUCT_T;

typedef struct
{
    BOOL fgEnable;
    UINT8 u1TsIndex;
	UINT8 u1LocalTsIndex;
    UINT16 u2Pid;

    BOOL fgPktSwap;
	UINT16 u2SwapLen;
    PFN_FVR_PID_PKTSWAP pfnSwapNotify;
    void *pvSwapNotifyTag;
    BOOL fgPktSwapOnce;

    BOOL fgPicSearch;
    UINT8 u1PicSearchMask;
    PFN_FVR_PID_PICSEARCH pfnPicSearchNotify;
    PFN_TLV_FVR_PID_PICSEARCH pfnTlvPicSearchNotify;
    void *pvPicSearchNotifyTag;

    BOOL fgScramble;
    BOOL fgCBCMode;

    FVR_KEY_TYPE_T eKeyType;    // Record encryption key type
    UINT8 u1KeyIdx;             // Record encryption key index
    UINT32 u4KeyLen;            // Record encryption key length

    BOOL fgDetectScramble;
    PFN_FVR_PID_DETECTSCRAMBLE pfnDetectScrambleNotify;
    PFN_FVR_PID_DETECTSCRAMBLE pfnDetectRawScrambleNotify;

    BOOL fgFreeze;
    DMX_SOURCE_T eSource;     // Logical channel: DTV0, DTV1
    DMX_PID_TYPE_T ePidType;

    //----------------------------------
    // Below is for section filter
    BOOL fgDoSFilter;
    BOOL fgAllocateBuffer;      // Allocate buffer or not
    UPTR u4BufStart;          // Buffer start
    UPTR u4BufEnd;            // Buffer end
    USIZE u4BufLen;            // Buffer length
    UPTR u4Rp;                // Read pointer
    UPTR u4SectionRp;         // Section read pointer
    UPTR u4Wp;                // Write pointer
    UINT32 u1SerialNumber;
    PFN_DMX_NOTIFY pfnNotify;   // Demux callback function
    void* pvNotifyTag;          // Tag value of callback function
    void *pvInstanceTag;

#ifdef CC_DMX_MULTIPLE_SECTION
    //UINT32 u4SecMask;
    UINT32 au4SecMask[SEC_CNT];
    UINT8  u1SecCount;
    UINT8  u1SecIdx;            // If u1SecIdx means first secion filter index
#endif  // CC_DMX_MULTIPLE_SECTION
    //----------------------------------

    BOOL  fgDesc;               // Decrypt TS (CI+, multi-2)
    UINT8 u1DescKeyidx;         // Decrypt TS (CI+, multi-2)
    DMX_DESC_MODE_T eDescMode;  // Descramble mode

    BOOL fgOddKey;
	UINT8 u1PtsTableIdx;
	UPTR u4MptBufStart;
	UPTR u4MptBufEnd;
	USIZE u4MptBufSize;
	UPTR u4MptRp;
	UPTR u4MptWp;

    UINT8 u1PhyIpIdx;
    UINT8 u1VirIpIdx;
} FVR_PID_STRUCT_T;

typedef enum
{
    FVR_MSG_PKTCOUNT,
    FVR_MSG_PKTSWAP,
    FVR_MSG_PICSEARCH,
    FVR_MSG_TIMERPKT,
    FVR_MSG_SITCOMPLETE,
    FVR_MSG_MPTINT,
} FVR_MSG_TYPE_T;

typedef struct {
    FVR_MSG_TYPE_T eMsgType;    ///< Message type
    union {
        FVR_SIT_PKTREPLACE_INFO_T rSitInfo;
        FVR_PID_PICNOTIFY_INFO_T rPicInfo;
        FVR_GBL_TIMENOTIFY_INFO_T rTimeInfo;
        TLV_FVR_NOTIFY_INFO_T rTlvInfo;
    } uMsgData;
} FVR_MSG_T;



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

EXTERN void _FVR_ApiLock(void);
EXTERN void _FVR_ApiUnlock(void);

//
// fvr_init.c
//
EXTERN BOOL _FVR_Init(void);
EXTERN BOOL _FVR_InitPidStruct(void);

EXTERN BOOL _FVR_Start(UINT8 u1Idx);
EXTERN BOOL _FVR_Stop(UINT8 u1Idx);
EXTERN BOOL _FVR_IsRecording(UINT8 u1Idx);
EXTERN BOOL _FVR_RecordingStateUpdate(UINT8 u1Idx, BOOL fgRecording, BOOL fgTlvRecoding);

EXTERN BOOL _FVR_GetResidual(UINT8 u1Idx, UPTR *pu4Addr, USIZE *pu4Size, UINT32 *pu4Index);
EXTERN void _FVR_SetScrambleScheme(BOOL fgOrg);

//
// fvr_swap.c
//
EXTERN BOOL _FVR_SwapInit(void);
EXTERN BOOL _FVR_SwapSetPattern(UINT8 u1Pidx, UINT8* pu1Pattern, UINT16 u2Len);
EXTERN BOOL _FVR_SwapSetNullPattern(UINT8 u1Pidx);
EXTERN BOOL _FVR_SwapFreePattern(UINT8 u1Pidx);
EXTERN BOOL _FVR_DoSwap(UINT8 u1Pidx, UPTR u4Addr);
EXTERN BOOL _FVR_DoExchangeKey(UINT8 u1Idx);
EXTERN BOOL _FVR_DoPacketSwapOnce(UINT8 u1Pidx);


//
// fvr_isr.c
//
EXTERN BOOL _FVR_InitIsr(void);
EXTERN BOOL _FVR_DispatchuPInterrupt(UINT32 u4Status, UINT32 u4Status2);
EXTERN void _FVR_uPErrorInt(UINT8 u1Idx);

//
// fvr_api.c
//
#ifdef CC_DEFINE_DMX_LOCK
extern CRIT_STATE_T _rGFvrLock;
#define _FVR_Lock() do { _rGFvrLock = x_crit_start(); } while (0)
#define _FVR_Unlock() do {  x_crit_end(_rGFvrLock); } while (0)
#else /* CC_DEFINE_DMX_LOCK */
EXTERN void _FVR_Lock(void);
EXTERN void _FVR_Unlock(void);
#endif /* CC_DEFINE_DMX_LOCK */

EXTERN void _FVR_InitAPI(void);

EXTERN BOOL _FVR_SetGBL(UINT8 u1Idx, UINT32 u4Flags, const FVR_GBL_T* prGBL);
EXTERN BOOL _FVR_GetGBL(UINT8 u1Idx, UINT32 u4Flags, FVR_GBL_T *prGBL);
EXTERN BOOL _FVR_FreeGBL(UINT8 u1Idx);
EXTERN FVR_GBL_STRUCT_T* _FVR_GetGBLStruct(UINT8 u1Idx);
EXTERN BOOL _FVR_DropScrambledPacket(UINT8 u1Idx, BOOL fgEnalbe);

EXTERN BOOL _FVR_TogglePidKey(void);
EXTERN void _FVR_SetIsToggleKey(UINT8 u1Idx);
EXTERN BOOL _FVR_GetIsToggleKey(UINT8 u1Idx);

EXTERN BOOL _FVR_SetPid(UINT8 u1Pidx, UINT32 u4Flags, const FVR_PID_T* prPid);
EXTERN BOOL _FVR_GetPid(UINT8 u1Pidx, UINT32 u4Flags, FVR_PID_T *prPid);
EXTERN FVR_PID_STRUCT_T* _FVR_GetPidStruct(UINT8 u1Pidx);
EXTERN BOOL _FVR_FreePid(UINT8 u1Pidx);
EXTERN BOOL _FVR_FlushPidBuffer(UINT8 u1Idx);

EXTERN void _FVR_SetTimestamp(UINT32 u4Flags, const FVR_TIMESTAMP_T* prTimeStamp);
EXTERN void _FVR_GetTimestamp(UINT32 u4Flags, FVR_TIMESTAMP_T* prTimeStamp);

EXTERN BOOL _FVR_FlushBuffer(UINT8 u1Idx);
EXTERN BOOL _FVR_GetBuffer(UINT8 u1Idx, UPTR u4Addr, USIZE u4Size, UINT8 *pu1Buf, UPTR *pu4RetAddr);
EXTERN BOOL _FVR_UnlockBuffer(UINT8 u1Idx, UPTR u4Addr, USIZE u4Size);
EXTERN BOOL _FVR_FreeBuffer(UINT8 u1Idx);

EXTERN void _FVR_QueryStatus(UINT8 u1Idx, FVR_QUERY_INFO_T *prInfo);
EXTERN void _FVR_SetIsOverflow(UINT8 u1Idx, BOOL fgOverflow);

EXTERN void _FVR_SetByPass(UINT8 u1TsIndex, UINT32 u4Val, BOOL fgEnable);

EXTERN BOOL _FVR_SetVideoTypeByPidx(UINT8 u1Pidx, FVR_VIDEO_TYPE_T eVideoType);
EXTERN FVR_VIDEO_TYPE_T _FVR_GetVideoTypeByPidx(UINT8 u1Pidx);

EXTERN BOOL _FVR_SetAesIV(UINT32 *pu4IV);
EXTERN BOOL _FVR_SetAesKey(UINT8 u1KeyIdx, BOOL fgEven, UINT8 *pu1Key);
EXTERN BOOL _FVR_SetAesEvenOddIV(UINT8 u1Idx, BOOL fgEven, UINT32 *pu4IV);
EXTERN BOOL _FVR_SetCryptoKey(UINT8 u1KeyIdx, BOOL fgEven, FVR_CRYPTO_KEY_TYPE_T eKeyType,
                                const UINT8 *pu1Key, UINT32 u4KeyLen);

EXTERN BOOL _FVR_IsPidEnabled(UINT8 u1Pidx);

EXTERN BOOL _FVR_PSI_UnlockBuffer(UINT8 u1Pidx, UINT8 u1SerialNumber, USIZE u4Size, UPTR u4FrameAddr);
EXTERN BOOL _FVR_PSI_FlushBuffer(UINT8 u1Pidx);
EXTERN BOOL _FVR_PSI_GetBuffer(UINT8 u1Pidx, UINT8 u1SerialNumber, UPTR u4FrameAddr,
                               USIZE u4SkipSize, USIZE u4CopySize, UCHAR* pu1Dest);

EXTERN BOOL _FVR_UpdateWritePointer(UINT8 u1Idx, UPTR u4Wp);
EXTERN BOOL _FVR_GetIsTSEnabled(UINT8 u1TsIdx);

EXTERN BOOL _FVR_SendTimerPktEvent(FVR_GBL_TIMENOTIFY_INFO_T *prTimeInfo);
EXTERN BOOL _FVR_SendPictureEvent(FVR_PID_PICNOTIFY_INFO_T *prPicInfo);
EXTERN BOOL _FVR_SendSitCompleteEvent(FVR_SIT_PKTREPLACE_INFO_T *prSitInfo);

EXTERN BOOL _FVR_ReplaceDITPacket(UINT8 u1Pidx, UINT32 u4PktIdx);

EXTERN UINT32 _FVR_SitQueryInsertedPacketCount(UINT8 u1TsIdx);
EXTERN BOOL _FVR_SitReplacePacket(UINT8 u1TsIdx, UINT8 u1SitPktCnt, BOOL fgComplete);
EXTERN BOOL _FVR_SitSetPattern(UINT8 u1TsIdx, UINT16 u2Pid, const UINT8 *pu1Data, UINT16 u2Len);
EXTERN BOOL _FVR_SitFreePattern(UINT8 u1TsIdx);
EXTERN BOOL _FVR_SitInsertPattern(UINT8 u1TsIdx, BOOL fgSyncCmd);
EXTERN BOOL _FVR_SitInsertPatternByTimer(UINT8 u1TsIdx, UINT32 u4MsDelay);
EXTERN BOOL _FVR_SitStopTimer(UINT8 u1TsIdx);
EXTERN BOOL _FVR_SitInit(void);

EXTERN BOOL _FVR_StartInsertDIT(UINT8 u1Pidx, UINT32 u4PcrDiffMs);
EXTERN BOOL _FVR_StopInsertDIT(UINT8 u1Pidx);

EXTERN FVR_SCRAMBLE_STATE_T _FVR_GetScrambleState(UINT8 u1Pidx);
EXTERN FVR_SCRAMBLE_STATE_T _FVR_GetRawScrambleState(UINT8 u1Pidx);

EXTERN UINT8 _FVR_GetRecordIdx(UINT8 u1Pidx);


EXTERN VOID _TLV_FVRPicSearchInt(UINT8 u1Pidx, UINT8 u1Pattern, UINT32 u4SeqNum, UINT32 u4PacketAddr);
EXTERN VOID _TLV_FVRPacketCountInt(UINT8 u1Pidx, UINT32 u4PacketAddr);
EXTERN VOID _TLV_FVRPacketSwapInt(UINT8 u1Pidx, UINT32 u4StartAddr);

EXTERN BOOL _TLV_SwapSetMptPattern(UINT8 u1Pidx, UINT8* pu1Pattern, UINT16 u2Len);
EXTERN BOOL _TLV_FVR_SwapSetPattern(UINT8 u1Pidx, UINT8* pu1Pattern, UINT16 u2Len);
EXTERN BOOL _TLV_FVR_SwapFreePattern(UINT8 u1Pidx);

EXTERN BOOL _TLV_FVR_SendPacketSwapEvent(UINT8 u1Pidx, UPTR u4Addr, UINT64 u8BufRingCounter);
EXTERN BOOL _TLV_FVR_SwapInit(void);


#endif  // _FVR_H

