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

/******************************************************************************
* [File]			msdc_if.h
* [Version]			v1.0
* [Revision Date]	2011-05-04
* [Author]			Shunli Wang, shunli.wang@mediatek.inc, 82896, 2011-05-04
* [Description]
*	MSDC Driver Header File
* [Copyright]
*	Copyright (C) 2011 MediaTek Incorporation. All Rights Reserved.
******************************************************************************/

#ifndef MSDC_IF_H
#define MSDC_IF_H

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

#include "x_lint.h"
#include "x_typedef.h"
#include "x_os.h"
#include "x_assert.h"
#include "x_printf.h"

#define EXT_CSD_CARD_TYPE_HS400_1_8V	(1<<6)	/* Card can run at HS400 1.8V */
#define EXT_CSD_CARD_TYPE_HS400_1_2V	(1<<7)	/* Card can run at HS400 1.2V */

#define EXT_CSD_CARD_TYPE_HS200_1_8V	(1<<4)	/* Card can run at HS400 1.8V */
#define EXT_CSD_CARD_TYPE_HS200_1_2V	(1<<5)	/* Card can run at HS400 1.2V */

#define MSDC_CAPABILITI_HS200  (1 << 0)
#define MSDC_CAPABILITI_HS400  (1 << 1)
#define MSDC_CPU_IDENTIFY_THRESHOLD  (4)//the same PCB in HT, delay cell may change mostly in 3

#define MSDC_DELTA(a, b)   ((a)>(b)? ((a)-(b)) : ((b)-(a)))

//save parameters in boot partition2

typedef struct _autok_info_
{
	UINT32 szMSDCAutoK[18];
	UINT32 u4RunAutokFlag;
	UINT32 u4id1;
	UINT32 u4id2;
	UINT32 u4SpeedMode;
	UINT32 u4CpuDelayCell; //identify CPU
}autok_info;


#ifndef CC_MSDC_SDMMC_TEST
#define CC_MSDC_SDMMC_TEST
#endif

#ifdef CC_MTD_SUPPORT_64_PARTITION
	#define MSDCPART_PARTNUM                (64)
#else
	#define MSDCPART_PARTNUM                (32)
#endif

#define MSDC_PARTID_SHIFT		(48)
/* eMMC density is up to 2TB(41bit is enough) */
#define MSDC_BYTE_OFFSET_MASK	((1ULL << MSDC_PARTID_SHIFT) - 1ULL)

#ifdef CC_PARTITION_WP_SUPPORT
EXTERN void  MSDCPART_WpConfig(UINT32 wp);
#endif
EXTERN VOID  MSDCPART_ShowPartition(VOID);

EXTERN INT32 MSDCPART_Read(UINT64 u8Offset, unsigned long uptrMemPtr, UINT32 u4MemLen);
EXTERN INT32 MSDCPART_Write(UINT64 u8Offset, unsigned long uptrMemPtr, UINT32 u4MemLen);
EXTERN INT32 MSDCPART_Erase(UINT64 u8Offset, UINT32 u4SectNum);

EXTERN INT32 Loader_GetMsdcEraseSize(VOID);
EXTERN INT32 Loader_ReadMsdc(UINT32 u4PartId, UINT32 u4Offset, VOID *pvMemPtr, UINT32 u4MemLen);
EXTERN INT32 Loader_WriteMsdc(UINT32 u4PartId, UINT32 u4Offset, VOID *pvMemPtr, UINT32 u4MemLen);
EXTERN INT32 Loader_ReadMsdc64(UINT32 u4PartId, UINT64 u8Offset, void *pvMemPtr, UINT32 u4MemLen);
EXTERN INT32 Loader_WriteMsdc64(UINT32 u4PartId, UINT64 u8Offset, void *pvMemPtr, UINT32 u4MemLen);
EXTERN INT32 Loader_EraseMsdc(UINT32 u4PartId, UINT32 u4Offset, UINT32 u4MemLen);

// for eeprom replacement
EXTERN INT32 MSDC_EEPROM_Read(UINT32 u4Offset, unsigned long uptrMemPtr, UINT32 u4MemLen);
EXTERN INT32 MSDC_EEPROM_Write(UINT32 u4Offset, unsigned long uptrMemPtr, UINT32 u4MemLen);

#ifdef CC_EEP2EMMC_DUAL_BANK_SUPPORT
EXTERN INT32 MSDC_EEP_Header_Read(UINT32 u4Offset, unsigned long uptrMemPtr, UINT32 u4MemLen);
EXTERN INT32 MSDC_EEP_Header_Write(UINT32 u4Offset, unsigned long uptrMemPtr, UINT32 u4MemLen);
EXTERN INT32 MSDC_EEP_Init_Header_Read(UINT32 u4Offset, unsigned long uptrMemPtr, UINT32 u4MemLen);
EXTERN INT32 MSDC_EEP_Init_Header_Write(UINT32 u4Offset, unsigned long uptrMemPtr, UINT32 u4MemLen);
EXTERN INT32 MSDC_EEP_Init_Data_Read(BOOL fgBankIndex, UINT32 u4Offset, unsigned long uptrMemPtr, UINT32 u4MemLen);
EXTERN INT32 MSDC_EEP_Init_Data_Write(BOOL fgBankIndex, UINT32 u4Offset, unsigned long uptrMemPtr, UINT32 u4MemLen);
#endif

//#ifndef __KERNEL__
#if 1
// For SD use
#define MSDC_SD_NONE                    (0)
#define MSDC_SD_INSERT                  (1)
#define MSDC_SD_UNKNOWN                 (2)

typedef struct
{
    UINT32 Boot_Partition_Sz;

    UINT32 Write_BlkSz;
    UINT32 Erase_GrpSz;
    UINT32 WP_GrpSz;

    UINT64 Dev_Sz;
} MSDC_DevInfo_T;

EXTERN VOID MSDC_HostSet(UINT32 u4Ch);
EXTERN UINT32 MSDC_HostGet(VOID);
EXTERN VOID MSDC_EmmcHostSet(UINT32 u4Ch);
EXTERN VOID  MSDC_ApiLock(HANDLE_T *hhSema);
EXTERN VOID  MSDC_ApiUnLock(HANDLE_T *hhSema);
EXTERN VOID MSDC_PinMux(UINT32 u4Ch);
EXTERN INT32 MsdcCardIdentify(VOID);
EXTERN INT32 MsdcSysInit(VOID);
EXTERN INT32 MsdcSetDataMode(UINT32 fgDataMode);
EXTERN INT32 MsdcSetDataEndMode(UINT32 fgEndMode);
EXTERN INT32 MsdcSetDataBusWidth(UINT32 busWidth);
EXTERN INT32 MsdcSetSpeedMode(UINT32 SpeedMode);
EXTERN INT32 MSDCTest_ExitHS200(VOID);
#if defined(CC_MT5891) || defined(CONFIG_ARCH_MT5891) || defined(CC_MT5882)
EXTERN INT32 MsdcSetHS400SpeedMode(VOID);
EXTERN INT32 MsdcHS400SaveRegs(VOID);
EXTERN INT32 MsdcHS400RestoreRegs(VOID);
EXTERN INT32 MSDCTest_HS400AutoTest(UINT32 *pSrcWrite,  UINT32 *pDestRead);
EXTERN VOID  MSDCDrivingMore(UINT32 CLK, UINT32 CMD, UINT32 DAT);
EXTERN UINT32 MSDCDrivingMoreGet(UINT32 IDX);
EXTERN INT32 Loader_mmc_select_hs200(UINT32 u4bus_width);
EXTERN INT32 Loader_mmc_select_hs400(VOID);
EXTERN INT32 MSDCTest_HS400_SLT_AutoTest(UINT64 u8Offset, UINT32 u4TotalSize);
EXTERN INT32 MSDCTest_Normal_SLT_AutoTest(UINT64 u8Offset, UINT32 u4TotalSize);
INT32 MSDCTest_ExitHS400(VOID);
#endif
EXTERN INT32 MsdcSetDDRMode(UINT32 fgDDRMode);
EXTERN INT32 MsdcSetBusClock(UINT32 busClock);
EXTERN INT32 MsdcSetContinueClock(UINT32 fgContinueClock);
EXTERN INT32 MsdcPrintConfigInfo(VOID);
EXTERN INT32 MsdcGetRegisters(UINT32 fgWhich);
EXTERN INT32 MsdcGetDevInfo(MSDC_DevInfo_T *MsdcDevInfo);
EXTERN INT32 MsdcGetDevSize(UINT64 *Dev_Sz);
EXTERN INT32 MsdcIdentyCard(BOOL fgForceIdentCard);
EXTERN INT32 MsdcReadCard(UINT64 u8Addr, UINT32 *pu4Buf, UINT32 u4Length);
EXTERN INT32 MsdcWriteCard(UINT32 *u4SrcAddr, UINT64 u8ByteOffset, UINT32 u4Len);
EXTERN INT32 MsdcEraseCard(UINT64 u8ByteOffset, UINT64 u8Len, UINT32 u4EraseType);
EXTERN INT32 MsdcWPCard(UINT32 u4WPLevel, UINT32 u4WPType, UINT32 u4fgEn, UINT64 wpAddr);
EXTERN VOID MsdcToggleContClock(VOID);
EXTERN INT32 MsdcIdentReadMMC(UINT32 *pu4Buf, UINT64 u8Addr, UINT32 u4Length);
EXTERN INT32 eMMC2DRAM(UINT64 u8Addr, UINT32 *pSrcOrDes, UINT32 u4Length, UINT32 u4Type);


// For SD use
EXTERN INT32 MSDCDetectSDGPIO(VOID);
EXTERN INT32 MSDCSDSwitchVoltage(INT32 hV);
EXTERN INT32 MSDCSDInit(BOOL fgForce);
EXTERN INT32 MSDCGetSDInsert(BOOL fgForce);
EXTERN INT32 MSDCGetSDDevInfo(MSDC_DevInfo_T *MsdcDevInfo);
EXTERN INT32 SD2DRAM(UINT64 u8Addr, UINT32 *pSrcOrDes, UINT32 u4Length, UINT32 u4Type);

// For loader use
EXTERN INT32 Loader_WriteToBootArea1(VOID *pvMemPtr);
EXTERN INT32 Loader_ReadFromBootArea2(void *pvMemPtr, UINT32 u4MemLen);
EXTERN INT32 Loader_WriteToBootArea2(void *pvMemPtr, UINT32 u4MemLen);

EXTERN INT32 MSDCTest_HS200Tuning(UINT32 target);
EXTERN INT32 MSDCTest_HS200Calibration(UINT32 u4Offset, UINT32 u4Size);
EXTERN INT32 MsdcCapabilitySupport(VOID);

// For sd/mmc test use
#ifdef CC_MSDC_SDMMC_TEST
EXTERN INT32 MSDCTest_Register(VOID);
EXTERN INT32 MSDCTest_Detection(VOID);
EXTERN INT32 MSDCTest_Protection(VOID);
EXTERN INT32 MSDCTest_DataAutoTest(UINT32 *pSrcWrite,  UINT32 *pDestRead);
EXTERN INT32 MSDCTest_DataEndAutoTest(UINT32 *pSrcWrite,  UINT32 *pDestRead);
EXTERN INT32 MSDCTest_BootModeAutoTest(UINT32 *pSrcWrite, UINT32 *pDestRead);
EXTERN INT32 MSDCTest_BootInt(UINT32 *pSrcWrite, UINT32 *pDestRead, UINT32 test_mode);
EXTERN INT32 MSDCTest_AutoTuning(UINT32 target);

#if defined(CC_MT5891) || defined(CONFIG_ARCH_MT5891) || defined(CC_MT5882)
EXTERN VOID MSDCTest_ModeMap(int mode,UINT32 *pSrcWrite,  UINT32 *pDestRead);
EXTERN INT32 MSDCTest_HS400AutoTest(UINT32 *pSrcWrite,  UINT32 *pDestRead);
EXTERN VOID MsdcDumpEMMCTotalRegister(VOID);
EXTERN INT32 MSDCTest_DataOnlyTest(UINT32 *pSrcWrite,	UINT32 *pDestRead);
#endif

#endif

// for sdio test use
#ifdef CC_MSDC_SDIO_TEST
EXTERN INT32 MSDCSDIO_Init(VOID);
EXTERN INT32 MSDCSDIO_GetCIA(UINT32 fgMode);
EXTERN INT32 MSDCSDIO_ParseCIA(VOID);
EXTERN INT32 MSDCSDIO_SetBusWidth(UINT32 buswidth);
EXTERN INT32 MSDCSDIO_SetBlockLen(UINT32 blklen);
EXTERN INT32 MSDCSDIO_ReadTest(UINT32 buff, UINT32 offset, UINT32 len, UINT32 mode);
EXTERN INT32 MSDCSDIO_ReadAutoTest(VOID);
#endif
#endif /* __KERNEL__ */

#endif /* MSDC_IF_H */
