/* 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: brianpc.huang $
 * $Date: 2015/05/29 $
 * $RCSfile: serialflash_hw.h,v $
 * $Revision: #1 $
 *
 *---------------------------------------------------------------------------*/

#ifndef SERIAL_FLASH_HW_H
#define SERIAL_FLASH_HW_H

//#define BD_NOR_ENABLE
//-----------------------------------------------------------------------------
// Include files
//-----------------------------------------------------------------------------

#ifndef CC_NOR_DISABLE

#ifdef BD_NOR_ENABLE
#include "x_hal_ic.h"
#else
#include "x_hal_5381.h"
#endif
#include "x_typedef.h"


//-----------------------------------------------------------------------------
// Type definitions
//-----------------------------------------------------------------------------
#ifdef BD_NOR_ENABLE
#define ENABLE_DUALREAD
#define SFLASH_MEM_BASE         ((UINT32)0xFA000000)//mmu on
#define SFLASH_REG_BASE         ((UINT32)(IO_BASE + 0x11000))
#else
#define SFLASH_MEM_BASE         (IO_VIRT + 0x8000000)
#define SFLASH_REG_BASE         (IO_VIRT + 0x08700)
#define SFLASH_RAM_BASE			((UINT32)0xFB00C000)		//0xfb00c000~0cfb00dfff for 5881
//#define SFLASH_RAM_BASE			((UINT32)0xFB004000)	//0xfb004000~0xfb004fff for 5399
#endif

#define SFLASH_CMD_REG          ((UINT32)0x00)
#define SFLASH_CNT_REG          ((UINT32)0x04)
#define SFLASH_RDSR_REG         ((UINT32)0x08)
#define SFLASH_RDATA_REG        ((UINT32)0x0C)
#ifdef BD_NOR_ENABLE
#define SFLASH_RADR0_REG        ((UINT32)0x10)
#define SFLASH_RADR1_REG        ((UINT32)0x14)
#define SFLASH_RADR2_REG        ((UINT32)0x18)
#define SFLASH_WDATA_REG        ((UINT32)0x1C)
#define SFLASH_PRGDATA0_REG     ((UINT32)0x20)
#define SFLASH_PRGDATA1_REG     ((UINT32)0x24)
#define SFLASH_PRGDATA2_REG     ((UINT32)0x28)
#define SFLASH_PRGDATA3_REG     ((UINT32)0x2C)
#define SFLASH_PRGDATA4_REG     ((UINT32)0x30)
#define SFLASH_PRGDATA5_REG     ((UINT32)0x34)
#define SFLASH_SHREG0_REG       ((UINT32)0x38)
#define SFLASH_SHREG1_REG       ((UINT32)0x3C)
#define SFLASH_SHREG2_REG       ((UINT32)0x40)
#define SFLASH_SHREG3_REG       ((UINT32)0x44)
#define SFLASH_SHREG4_REG       ((UINT32)0x48)
#define SFLASH_SHREG5_REG       ((UINT32)0x4C)
#define SFLASH_SHREG6_REG       ((UINT32)0x50)
#define SFLASH_SHREG7_REG       ((UINT32)0x54)
#define SFLASH_SHREG8_REG       ((UINT32)0x58)
#define SFLASH_SHREG9_REG       ((UINT32)0x5C)
#define SFLASH_FLHCFG_REG      	((UINT32)0x84)
#define SFLASH_PP_DATA_REG      ((UINT32)0x98)
#define SFLASH_PREBUF_STUS_REG  ((UINT32)0x9C)
#define SFLASH_SF_INTRSTUS_REG  ((UINT32)0xA8)
#define SFLASH_SF_INTREN_REG    ((UINT32)0xAC)
#define SFLASH_SF_TIME_REG      ((UINT32)0x94)
#define SFLASH_CHKSUM_CTL_REG   ((UINT32)0xB8)
#define SFLASH_CHECKSUM_REG     ((UINT32)0xBC)
#define SFLASH_CMD2_REG     	((UINT32)0xC0)
#define SFLASH_WRPROT_REG       ((UINT32)0xC4)
#define SFLASH_RADR3_REG        ((UINT32)0xC8)
#define SFLASH_READ_DUAL_REG    ((UINT32)0xCC)
#define SFLASH_DELSEL0_REG    	((UINT32)0xA0)
#define SFLASH_DELSEL1_REG    	((UINT32)0xA4)
#define SFLASH_DELSEL2_REG    	((UINT32)0xD0)
#define SFLASH_DELSEL3_REG    	((UINT32)0xD4)
#define SFLASH_DELSEL4_REG    	((UINT32)0xD8)
#else
#define SFLASH_RADR0_REG        ((UINT32)0x20)
#define SFLASH_RADR1_REG        ((UINT32)0x24)
#define SFLASH_RADR2_REG        ((UINT32)0x28)
#define SFLASH_WDATA_REG        ((UINT32)0x2C)
#define SFLASH_PRGDATA0_REG     ((UINT32)0x30)
#define SFLASH_PRGDATA1_REG     ((UINT32)0x34)
#define SFLASH_PRGDATA2_REG     ((UINT32)0x38)
#define SFLASH_PRGDATA3_REG     ((UINT32)0x3C)
#define SFLASH_PRGDATA4_REG     ((UINT32)0x40)
#define SFLASH_PRGDATA5_REG     ((UINT32)0x44)
#define SFLASH_SHREG0_REG       ((UINT32)0x48)
#define SFLASH_SHREG1_REG       ((UINT32)0x4C)
#define SFLASH_SHREG2_REG       ((UINT32)0x50)
#define SFLASH_SHREG3_REG       ((UINT32)0x54)
#define SFLASH_SHREG4_REG       ((UINT32)0x58)
#define SFLASH_SHREG5_REG       ((UINT32)0x5C)
#define SFLASH_PP_DATA_REG      ((UINT32)0x80)
#define SFLASH_PREBUF_STUS_REG  ((UINT32)0x84)
#define SFLASH_SF_INTRSTUS_REG  ((UINT32)0x88)
#define SFLASH_SF_INTREN_REG    ((UINT32)0x8C)
#define SFLASH_SF_TIME_REG      ((UINT32)0xA4)
#define SFLASH_CHKSUM_CTL_REG   ((UINT32)0xA8)
#define SFLASH_CHECKSUM_REG     ((UINT32)0xAC)
#define SFLASH_CKGEN_REG        ((UINT32)0xB0)
#define SFLASH_SAMPLE_EDGE_REG  ((UINT32)0xB4)
#define SFLASH_DELAY_SELECTION  ((UINT32)0xB8)
#define SFLASH_DUAL_REG         ((UINT32)0xC0)
#define SFLASH_PREFETCH_REG     ((UINT32)0xC4)
#define SFLASH_PRGDATA6_REG     ((UINT32)0xC8)
#define SFLASH_PRGDATA7_REG     ((UINT32)0xCC)
#define SFLASH_PRGDATA_RISC0    ((UINT32)0xD0)
#define SFLASH_PRGDATA_RISC1    ((UINT32)0xD4)
#define SFLASH_SHREG6_REG       ((UINT32)0xD8)
#define SFLASH_SHREG7_REG       ((UINT32)0xDC)
#define SFLASH_SHREG_RISC0      ((UINT32)0xE0)
#define SFLASH_SHREG_RISC1      ((UINT32)0xE4)

#endif
#define SFLASH_CFG1_REG         ((UINT32)0x60)
#define SFLASH_CFG2_REG         ((UINT32)0x64)
#define SFLASH_CFG3_REG         ((UINT32)0x68)
#define SFLASH_STATUS0_REG      ((UINT32)0x70)
#define SFLASH_STATUS1_REG      ((UINT32)0x74)
#define SFLASH_STATUS2_REG      ((UINT32)0x78)
#define SFLASH_STATUS3_REG      ((UINT32)0x7C)

//-----------------------------------------------------------------------------
#define SFLASH_WRBUF_SIZE       128
#ifndef BD_NOR_ENABLE
#define PP_SIZE       			256			//max 255*4
#define PAGE_COUNT       		1
#endif

//-----------------------------------------------------------------------------
#define SFLASHHWNAME_LEN    48

#ifdef REPLACE_EEPROM_WITH_NOR	
typedef struct
{
    UINT8   u1MenuID;
    UINT8   u1DevID1;
    UINT8   u1DevID2;
    UINT8   u1PPType;
    UINT32  u4ChipSize;
    UINT32  u4SecSize;
    UINT32  u4CEraseTimeoutMSec;

    UINT8   u1WRENCmd;
    UINT8   u1WRDICmd;
    UINT8   u1RDSRCmd;
    UINT8   u1WRSRCmd;
    UINT8   u1READCmd;
    UINT8   u1FASTREADCmd;
    UINT8   u1READIDCmd;
    UINT8   u1SECERASECmd;
    UINT8   u1CHIPERASECmd;
    UINT8   u1PAGEPROGRAMCmd;
    UINT8   u1AAIPROGRAMCmd;
    UINT8   u1DualREADCmd;
    UINT8   u1Protection;
	UINT8   u1Protection_Eeprom;
    CHAR    pcFlashStr[SFLASHHWNAME_LEN];
} SFLASHHW_VENDOR_T;
#else
typedef struct
{
    UINT8   u1MenuID;
    UINT8   u1DevID1;
    UINT8   u1DevID2;
    UINT8   u1PPType;
    UINT32  u4ChipSize;
    UINT32  u4SecSize;
    UINT32  u4CEraseTimeoutMSec;

    UINT8   u1WRENCmd;
    UINT8   u1WRDICmd;
    UINT8   u1RDSRCmd;
    UINT8   u1WRSRCmd;
    UINT8   u1READCmd;
    UINT8   u1FASTREADCmd;
    UINT8   u1READIDCmd;
    UINT8   u1SECERASECmd;
    UINT8   u1CHIPERASECmd;
    UINT8   u1PAGEPROGRAMCmd;
    UINT8   u1AAIPROGRAMCmd;
    UINT8   u1DualREADCmd;
    UINT8   u1Protection;
    CHAR    pcFlashStr[SFLASHHWNAME_LEN];
} SFLASHHW_VENDOR_T;
#endif

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

//-----------------------------------------------------------------------------
// Public functions
//-----------------------------------------------------------------------------
EXTERN INT32 SFLASHHW_Init(void);

EXTERN void SFLASHHW_SetIsr(BOOL fgSet);

EXTERN INT32 SFLASHHW_GetID(UINT32 u4Index, UINT8 *pu1MenuID,
                             UINT8 *pu1DevID1, UINT8 *pu1DevID2);
EXTERN void SFLASHHW_GetFlashInfo(SFLASH_INFO_T *prInfo);

EXTERN INT32 SFLASHHW_Read(UINT32 u4Addr, UINT32 u4len, UINT8* pu1buf);

EXTERN INT32 SFLASHHW_WriteSector(UINT32 u4Index, UINT32 u4Addr,
                                  UINT32 u4Len, const UINT8* pu1Buf);

EXTERN INT32 SFLASHHW_EraseSector(UINT32 u1Index, UINT32 u4Addr);

EXTERN INT32 SFLASHHW_EraseChip(UINT32 u4Index);
EXTERN INT32 SFLASHHW_CalCRC(UINT32 u4Addr, UINT32 u4Len, UINT32* pu4CheckSum);

EXTERN void SFLASHHW_SetClk(UINT32 u4Val);
EXTERN UINT32 SFLASHHW_GetClk(void);
EXTERN void SFLASHHW_SetSampleEdge(UINT32 u4Val);
EXTERN UINT32 SFLASHHW_GetSampleEdge(void);

EXTERN INT32 SFLASHHW_ReadFlashStatus(UINT32 u4Index, UINT8 *pu1Val);
EXTERN INT32 SFLASHHW_WriteProtect(UINT32 u4Index, BOOL fgEnable);

EXTERN CHAR* SFLASHHW_GetFlashName(UINT8 u1MenuID, UINT8 u1DevID1, UINT8 u1DevID2);

EXTERN INT32 SFLASHHW_EnableDMA(UINT32 u4SrcAddr, UINT32 u4DestAddr, UINT32 u4Size);

EXTERN UINT32 SFLASHHW_GetFlashSize(UINT8 u1MenuID, UINT8 u1DevID1, UINT8 u1DevID2);

#ifndef BD_NOR_ENABLE
EXTERN INT32 SFLASHHW_ReadProgram(UINT32 u4Addr, UINT32 u4len, UINT8* pu1buf);
EXTERN INT32 SFLASHHW_ReadRISCProgram(UINT32 u4Addr, UINT32 u4len, UINT8* pu1buf);
EXTERN INT32 SFLASHHW_WriteMutilPP(UINT32 u4Index, UINT32 u4Addr, UINT32 u4Len,
                           const UINT8* pu1Buf);
EXTERN INT32 SFLASHHW_WriteProgram(UINT32 u4Index, UINT32 u4Addr,
                                  UINT32 u4Len, const UINT8* pu1Buf);
EXTERN INT32 SFLASHHW_WriteRISCProgram(UINT32 u4Index, UINT32 u4Addr,
                                  UINT32 u4Len, const UINT8* pu1Buf);
EXTERN void SFLASHHW_SetEnableClkDelay(BOOL fgEnable);
EXTERN void SFLASHHW_SetEnableDataDelay(BOOL fgEnable);
EXTERN void SFLASHHW_SetClkDelay(UINT32 u4Val);
EXTERN void SFLASHHW_SetDataDelay(UINT32 u4Val);
EXTERN UINT32 SFLASHHW_GetDataDelay(void);
EXTERN UINT32 SFLASHHW_GetClkDelay(void);
EXTERN void SFLASHHW_SetReadType(UINT32 u4Val);
EXTERN UINT32 SFLASHHW_GetReadType(void);
EXTERN UINT32 SFLASHHW_PinMux(UINT32 u4Val);
#else
EXTERN void SFLASHHW_WriteSfProtect(UINT32 u4Val);
EXTERN UINT32 SFLASHHW_ReadSfProtect(void);
EXTERN void SFLASHHW_WriteReg(UINT32 uAddr, UINT32 u4Val);
EXTERN UINT32 SFLASHHW_ReadReg(UINT32 uAddr);
EXTERN UINT32 SFLASHHW_SwitchChip(UINT32 uAddr);
EXTERN INT32 SFLASHHW_DeInit(void);
EXTERN INT32 _SetFlashEnter4Byte(void);
EXTERN INT32 _SetFlashExit4Byte(void);
EXTERN INT32 _SetFlashEnter4BitRead(void);
EXTERN INT32 _SetFlashExit4BitRead(void);
EXTERN INT32 SFLASHHW_4BitRead(UINT32 u4Addr, UINT32 u4len, UINT8* pu1buf);
EXTERN INT32 SFLASHHW_4Byte4BitRead(UINT32 u4Addr, UINT32 u4len, UINT8* pu1buf);
EXTERN INT32 SFLASHHW_4BWriteSector(UINT32 u4Index, UINT32 u4Addr,
                                  UINT32 u4Len, const UINT8* pu1Buf);
EXTERN INT32 SFLASHHW_4BEraseSector(UINT32 u1Index, UINT32 u4Addr);
#endif
#endif
#endif
