/*----------------------------------------------------------------------------*
 * No Warranty                                                                *
 * Except as may be otherwise agreed to in writing, no warranties of any      *
 * kind, whether express or implied, are given by MTK with respect to any MTK *
 * Deliverables or any use thereof, and MTK Deliverables are provided on an   *
 * "AS IS" basis.  MTK hereby expressly disclaims all such warranties,        *
 * including any implied warranties of merchantability, non-infringement and  *
 * fitness for a particular purpose and any warranties arising out of course  *
 * of performance, course of dealing or usage of trade.  Parties further      *
 * acknowledge that Company may, either presently and/or in the future,       *
 * instruct MTK to assist it in the development and the implementation, in    *
 * accordance with Company's designs, of certain softwares relating to        *
 * Company's product(s) (the "Services").  Except as may be otherwise agreed  *
 * to in writing, no warranties of any kind, whether express or implied, are  *
 * given by MTK with respect to the Services provided, and the Services are   *
 * provided on an "AS IS" basis.  Company further acknowledges that the       *
 * Services may contain errors, that testing is important and Company is      *
 * solely responsible for fully testing the Services and/or derivatives       *
 * thereof before they are used, sublicensed or distributed.  Should there be *
 * any third party action brought against MTK, arising out of or relating to  *
 * the Services, Company agree to fully indemnify and hold MTK harmless.      *
 * If the parties mutually agree to enter into or continue a business         *
 * relationship or other arrangement, the terms and conditions set forth      *
 * hereunder shall remain effective and, unless explicitly stated otherwise,  *
 * shall prevail in the event of a conflict in the terms in any agreements    *
 * entered into between the parties.                                          *
 *---------------------------------------------------------------------------*/
/******************************************************************************
* [File]			msdc_drv.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_DRV_H_
#define _MSDC_DRV_H_

#include "msdc_host_hw.h"
#include "msdc_slave_hw.h"
#include "x_dram.h"

#if defined(CC_MT5891) || defined(CONFIG_ARCH_MT5891)// || defined(CC_MT5882)
#define MSDC_NEW_FIFO_PATH  1
#else
#define MSDC_NEW_FIFO_PATH  0
#endif
#define MSDC_ENCRYPT_WRITE_BUF_SUPPORT  1
#define R1_CURRENT_STATE(x)	((x & 0x00001E00) >> 9)	/* sx, b (4 bits) */
#define R1_STATE_IDLE	0
#define R1_STATE_READY	1
#define R1_STATE_IDENT	2
#define R1_STATE_STBY	3
#define R1_STATE_TRAN	4
#define R1_STATE_DATA	5
#define R1_STATE_RCV	6
#define R1_STATE_PRG	7
#define R1_STATE_DIS	8

#define MAX_CKGEN_TUNE_TIME  10
//---------------------------------------------------------------------------
// Configurations
//---------------------------------------------------------------------------
#if defined(CC_MT5396) || defined(CONFIG_ARCH_MT5396) || \
    defined(CC_MT5368) || defined(CONFIG_ARCH_MT5368) || \
    defined(CC_MT5389) || defined(CONFIG_ARCH_MT5389)
#define MSDC_CLK_TARGET   54, 48, 43, 40, 36, 30, 27, 24, 18, 13, 0
#define MSDC_CLK_SRC_VAL  2, 3, 4, 8, 5, 7, 0, 9, 6, 1, 0
#define MSDC_CLK_MODE_VAL 1, 1, 1, 0, 1, 0, 2, 0, 0, 0
#define MSDC_CLK_DIV_VAL  0, 0, 0, 0, 0, 1, 0, 2, 0, 16
#define MSDC_CLK_DRV_VAL  60, 60, 57, 25, 23, 16, 16, 7, 7, 0
#define MSDC_CLK_SAMP_VAL 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x0, 0x0, 0x0, 0x0
#define MSDC_CLK_IDX_MAX  11
#define MSDC_CLK_S_REG1   0xF000D2F8
#define MSDC_CLK_S_REG0   0xF000D264
#define MSDC_CLK_H_REG1   0xF000D2F8
#define MSDC_CLK_H_REG0   0xF000D264
#define MSDC_CLK_GATE_BIT (0x1<<7)
#define MSDC_CLK_SEL_MASK (0x0F<<0)
#define MSDC_HIGH_CLK_IDX 1
#define MSDC_NORM_CLK_IDX 7
#define MSDC_INIT_CLK_IDX 10

#elif defined(CC_MT5880) || defined(CONFIG_ARCH_MT5880) || \
      defined(CC_MT5860) || defined(CONFIG_ARCH_MT5860) || \
      defined(CC_MT5881) || defined(CONFIG_ARCH_MT5881) || \
      defined(CC_MT5398) || defined(CONFIG_ARCH_MT5398)
#define MSDC_CLK_TARGET   54, 48, 43, 40, 36, 30, 27, 24, 18, 13, 0
#define MSDC_CLK_SRC_VAL  1, 2, 8, 6, 9, 5, 3, 7, 10, 4, 0
#define MSDC_CLK_MODE_VAL 1, 1, 1, 0, 1, 0, 2, 0, 0, 0
#define MSDC_CLK_DIV_VAL  0, 0, 0, 0, 0, 1, 0, 2, 0, 16
#define MSDC_CLK_DRV_VAL  60, 60, 57, 25, 23, 16, 16, 7, 7, 0
#define MSDC_CLK_SAMP_VAL 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x0, 0x0, 0x0, 0x0
#define MSDC_CLK_IDX_MAX  11
#define MSDC_CLK_S_REG1   0xF000D380
#define MSDC_CLK_S_REG0   0xF000D32C
#define MSDC_CLK_H_REG1   0xF000D384
#define MSDC_CLK_H_REG0   0xF000D3A0
#define MSDC_CLK_GATE_BIT (0x1<<7)
#define MSDC_CLK_SEL_MASK (0x0F<<0)
#define MSDC_HIGH_CLK_IDX 1
#define MSDC_NORM_CLK_IDX 7
#define MSDC_INIT_CLK_IDX 10

#elif defined(CC_MT5891) || defined(CONFIG_ARCH_MT5891)
#define MSDC_CLK_TARGET   400, 200, 144, 120, 100, 80, 50, 50, 25, 12, 0

//Use original clock source for HS200
//#define MSDC_CLK_SRC_VAL   3,  2,   5,   6,  11,  9,  8,  11, 11,  0, 0
//#define MSDC_CLK_MODE_VAL  3,   1,   1,   1,   0,  1,  1,  2,   0,  0, 0
//#define MSDC_CLK_DIV_VAL   0,   0,   0,   0,   0,  0,  0,  0,   2,  0, 16

//Use DMXPLL for HS200
#if 1 // use one clock source-DMUXPLL
#define MSDC_CLK_SRC_VAL   3,   3,   3,   3,   3,  3,  3,  3,   3,  3, 0
#define MSDC_CLK_MODE_VAL  3,   0,   0,   0,   0,  0,  0,  2,   0,  0, 0
#define MSDC_CLK_DIV_VAL   0,   0,   1,   1,   1,  2,  2,  2,   4,  8, 16
#else
//test
#define MSDC_CLK_SRC_VAL   3,   3,   5,   6,  11,  9,  8,  11, 11,  0, 0
#define MSDC_CLK_MODE_VAL  3,   0,   1,   1,   0,  1,  1,  2,   0,  0, 0
#define MSDC_CLK_DIV_VAL   0,   0,   0,   0,   0,  0,  0,  0,   2,  0, 16
#endif

#define MSDC_CLK_DRV_VAL   1,   1,   1,   1,   1 , 1,  1,  1,   1,  1, 0
#define MSDC_CLK_SAMP_VAL  0x6,0x6, 0x6, 0x6, 0x6,0x6,0x6,0x6,0x0,0x0,0x0, 0x0
#define MSDC_CLK_IDX_MAX  11
#define MSDC_CLK_S_REG1   0xF000D380
#define MSDC_CLK_S_REG0   0xF000D32C
#define MSDC_CLK_H_REG1   0xF000D384
#define MSDC_CLK_H_REG0   0xF000D3A0
#define MSDC_DMULPLL_GATE_BIT (0x1<<31)
#define MSDC_CLK_GATE_BIT (0x1<<7)
#define MSDC_CLK_SEL_MASK (0x0F<<0)
#define MSDC_HIGH_CLK_IDX 7
#define MSDC_NORM_CLK_IDX 8
#define MSDC_INIT_CLK_IDX 10

#elif  defined(CC_MT5890) || defined(CONFIG_ARCH_MT5890)|| \
       defined(CC_MT5861) || defined(CONFIG_ARCH_MT5861)
 #define MSDC_CLK_TARGET   200, 144, 120, 100, 80, 50, 50, 25, 12, 0
#define MSDC_CLK_SRC_VAL   11,   5,   6,  11,  9,  8, 11, 11,  0, 0
#define MSDC_CLK_MODE_VAL   1,   1,   1,   0,  1,  1,  2,  0,  0, 0
#define MSDC_CLK_DIV_VAL    0,   0,   0,   0,  0,  0,  0,  2,  0, 16
#define MSDC_CLK_DRV_VAL    1,   1,   1,   1 , 1,  1,  1,  1,  1, 0
#define MSDC_CLK_SAMP_VAL 0x6, 0x6, 0x6, 0x6,0x6,0x6,0x6,0x0,0x0,0x0, 0x0
#define MSDC_CLK_IDX_MAX  10
#define MSDC_CLK_S_REG1   0xF000D380
#define MSDC_CLK_S_REG0   0xF000D32C
#define MSDC_CLK_H_REG1   0xF000D384
#define MSDC_CLK_H_REG0   0xF000D3A0
#define MSDC_CLK_GATE_BIT (0x1<<7)
#define MSDC_CLK_SEL_MASK (0x0F<<0)
#define MSDC_HIGH_CLK_IDX 6
#define MSDC_NORM_CLK_IDX 7
#define MSDC_INIT_CLK_IDX 9


#elif defined(CC_MT5399) || defined(CONFIG_ARCH_MT5399)|| \
       defined(CC_MT5882) || defined(CONFIG_ARCH_MT5882)
#define MSDC_CLK_TARGET   200, 192, 162, 144, 120, 	100, 	80, 	50, 	50, 	25, 	12, 	 0
#define MSDC_CLK_SRC_VAL   11, 	12,   4,    5, 	6,  11, 	 9, 	 8, 	11, 	11, 	 0, 	 0
#define MSDC_CLK_MODE_VAL   1, 	 1,   1,    1, 	1,   0, 	 1, 	 1, 	 2, 	 0, 	 0, 	 0
#define MSDC_CLK_DIV_VAL    0, 	 0,   0,    0, 	0,   0, 	 0, 	 0, 	 0, 	 2, 	 0, 	16
#define MSDC_CLK_DRV_VAL   60, 	60,  60,    60, 60,  25,    23, 	23, 	16, 	 7, 	 7, 	 0
#define MSDC_CLK_SAMP_VAL 0x6, 0x6, 0x6,    0x6,0x6, 0x6,   0x6,    0x6,   0x6, 	0x0, 	0x0,    0x0, 0x0
#define MSDC_CLK_IDX_MAX  12
#define MSDC_CLK_S_REG1   0xF000D380
#define MSDC_CLK_S_REG0   0xF000D32C
#define MSDC_CLK_H_REG1   0xF000D384
#define MSDC_CLK_H_REG0   0xF000D3A0
#define MSDC_CLK_GATE_BIT (0x1<<7)
#define MSDC_CLK_SEL_MASK (0x0F<<0)
#define MSDC_HIGH_CLK_IDX 8
#define MSDC_NORM_CLK_IDX 9
#define MSDC_INIT_CLK_IDX 11

#elif	  defined(CC_MT5883) || defined(CONFIG_ARCH_MT5883)
#define MSDC_CLK_TARGET   200, 144, 120, 	100, 	80, 	50, 	50, 	25, 	12, 	 0
#define MSDC_CLK_SRC_VAL    4, 	 5, 	6,  11, 	 9, 	 8, 	11, 	11, 	 0, 	 0
#define MSDC_CLK_MODE_VAL   1, 	 1, 	1,   0, 	 1, 	 1, 	 2, 	 0, 	 0, 	 0
#define MSDC_CLK_DIV_VAL    0, 	 0, 	0,   0, 	 0, 	 0, 	 0, 	 2, 	 0, 	16
#define MSDC_CLK_DRV_VAL   48, 	60,   60,  25, 23, 	23, 	16, 	 7, 	 7, 	 0
#define MSDC_CLK_SAMP_VAL 0x6, 0x6,  0x6, 0x6, 0x6,  0x6,   0x6, 	0x0, 	0x0, 0x0, 0x0
#define MSDC_CLK_IDX_MAX  10
#define MSDC_CLK_S_REG1   0xF000D32C
#define MSDC_CLK_S_REG0   0xF000D32C
#define MSDC_CLK_H_REG1   0xF000D384
#define MSDC_CLK_H_REG0   0xF000D3A0
#define MSDC_CLK_GATE_BIT (0x1<<7)
#define MSDC_CLK_SEL_MASK (0x0F<<0)
#define MSDC_HIGH_CLK_IDX 6
#define MSDC_NORM_CLK_IDX 7
#define MSDC_INIT_CLK_IDX 9

#endif


#define CMD0_RESET_LIMIT            (3)
#define MMC_CMD1_RETRY_LIMIT        (1500)
#define SDHC_BLK_SIZE               (512)
#define SDHC_BLK_SIZE_ORDER         (9)
#define MMC_DEF_RCA                 0x0001
#define SD_DEF_RCA                  0x0000

// GPIO63
#if defined(CC_MT5882) || defined(CONFIG_ARCH_MT5882) || defined(CC_MT5883) || defined(CONFIG_ARCH_MT5883)
#define MSDC_SD_VOLTAGE_PIN     43
#elif defined(CC_MT5891) || defined(CONFIG_ARCH_MT5891)
#define MSDC_SD_VOLTAGE_PIN     45
#else
#define MSDC_SD_VOLTAGE_PIN     63
#endif
#define MSDC_SD_DETECT_PIN      76

//---------------------------------------------------------------------------
// Basic definitions
//---------------------------------------------------------------------------

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

#define MSDC_RST_TIMEOUT_LIMIT_COUNT                        5
#define MSDC_CLK_TIMEOUT_LIMIT_COUNT                        10
#define MSDC_FIFOCLR_TIMEOUT_LIMIT_COUNT                    5

#define MSDC_WAIT_SDC_BUS_TIMEOUT_LIMIT_COUNT               400
#define MSDC_WAIT_CMD_TIMEOUT_LIMIT_COUNT                   200
#define MSDC_WAIT_DATA_TIMEOUT_LIMIT_COUNT                  5000
#define MSDC_WAIT_DATA_COMPLETE_TIMEOUT_LIMIT_COUNT         1000000    //should use 1000 ?

#define MSDC_WAIT_BTSTS_1_TIMEOUT_LIMIT_COUNT               20
#define MSDC_WAIT_BTSTS_0_TIMEOUT_LIMIT_COUNT               1000
#define MSDC_WAIT_EMMC_ACK_TIMEOUT_LIMIT_COUNT              60
#define MSDC_WAIT_EMMC_DATA_TIMEOUT_LIMIT_COUNT             1100

#define EMMC_READ_CARD_FAIL                                 1
#define EMMC_MSDC_INIT_FAIL                                 2
#define EMMC_IDENT_CARD_FAIL                                3
#define EMMC_SUCCESS                                        0

//---------------------------------------------------------------------------
// MSDC error retry limitation
//---------------------------------------------------------------------------

#define MSDC_LOAD_MMC_IMAGE_RETRY_LIMIT               10
#define MSDC_SYS_INIT_RETRY_LIMIT                      3
#define MSDC_IDENTIFY_CARD_RETRY_LIMIT                10
#define MSDC_READ_CARD_RETRY_LIMIT                     6
#define MSDC_READ_BOOTLDR_DATA_RETRY_LIMIT             8

//---------------------------------------------------------------------------
// Type definitions
//---------------------------------------------------------------------------
static inline unsigned int uffs(unsigned int x)
{
	unsigned int r = 1;

	if (!x)
		return 0;
	if (!(x & 0xffff)) {
		x >>= 16;
		r += 16;
	}
	if (!(x & 0xff)) {
		x >>= 8;
		r += 8;
	}
	if (!(x & 0xf)) {
		x >>= 4;
		r += 4;
	}
	if (!(x & 3)) {
		x >>= 2;
		r += 2;
	}
	if (!(x & 1)) {
		x >>= 1;
		r += 1;
	}
	return r;
}


#define MSDC_WRITE32(addr, value)      (*(volatile unsigned int *)(addr)) = (value)
#define MSDC_READ32(addr)              (*(volatile unsigned int *)(addr))

#define MSDC_SETBIT(addr, dBit)        MSDC_WRITE32(addr, MSDC_READ32(addr) | (dBit))
#define MSDC_CLRBIT(addr, dBit)        MSDC_WRITE32(addr, MSDC_READ32(addr) & (~(dBit)))

#define MSDC_BITVAL(addr, dBit)        ((MSDC_READ32(addr)>>dBit)&0x1)

#define MSDC_SET_FIELD(reg,field,val) \
    do {    \
        volatile unsigned int tv = MSDC_READ32(reg);    \
        tv &= ~(field); \
        tv |= ((val) << (uffs((unsigned int)field) - 1)); \
        MSDC_WRITE32(reg,tv); \
    } while(0)

#define MSDC_GET_FIELD(reg,field,val) \
    do {    \
        volatile unsigned int tv = MSDC_READ32(reg);    \
        val = ((tv & (field)) >> (uffs((unsigned int)field) - 1)); \
    } while(0)


#define ArraySize(a)              (sizeof(a)/sizeof(a[0]))
#define MAX_NUM(a, b)             ((a)>(b)?(a):(b))
#define MIN_NUM(a, b)             ((a)>(b)?(b):(a))

#define RESPONSE_NO			          (0)
#define RESPONSE_R1			          (1)
#define RESPONSE_R2			          (2)
#define RESPONSE_R3			          (3)
#define RESPONSE_R4			          (4)
#define RESPONSE_R5			          (5)
#define RESPONSE_R6			          (6)
#define RESPONSE_R7			          (7)
#define RESPONSE_R1B		          (8)

#define MSDC_SUCCESS                  (int)(0)
#define MSDC_FAILED                   (int)(-1)

#define CMD_ERR_SUCCESS               (MSDC_SUCCESS)
#define CMD_ERR_FAILED                (MSDC_FAILED)

#define CMD_ERR_NO_RESP               (0x01 << 0)
#define CMD_ERR_RESP_CRCERR           (0x01 << 1)
#define CMD_ERR_WAIT_CMD_TO           (0x01 << 2)

#define CMD_ERR_DATTO                 (0x01 << 3)//not used in loader
#define CMD_ERR_DATA_CRCERR           (0x01 << 4)
#define CMD_ERR_WAIT_DATATO           (0x01 << 5)
#define CMD_ERR_DATA_FAILED           (0x01 << 6)

#define ERR_CMD_FAILED                (0x01 << 1)
#define ERR_DAT_FAILED                (0x01 << 4)

//---------------------------------------------------------------------------
// Log system declaration
//---------------------------------------------------------------------------

#define MSG_LVL_OFF						(0)
#define MSG_LVL_FATAL					(1)
#define MSG_LVL_ERR						(2)
#define MSG_LVL_WARN					(3)
#define MSG_LVL_TITLE					(4)
#define MSG_LVL_INFO					(5)
#define MSG_LVL_CMD						(6)
#define MSG_LVL_DBG						(7)
#define MSG_LVL_TRACE					(8)

#ifdef CC_UBOOT
#define MSDC_PRINT printf
#else
#define MSDC_PRINT Printf
#endif

#ifndef CC_HS200_CALIBRATION_SUPPORT   // tyler.zhang mark it for calibration
#define MSG_LVL_DISPLAY       (4)
#else
#define MSG_LVL_DISPLAY       (0)
#endif
#define MSDC_LOG_TAG "[MSDC] "
#define MSDC_LOG(level, formatStr...) \
	do { \
		if (level <= MSG_LVL_DISPLAY) \
			MSDC_PRINT(MSDC_LOG_TAG formatStr); \
	} while(0)

//---------------------------------------------------------------------------
// Struct declaration
//---------------------------------------------------------------------------
typedef struct _hs400_saved_regs_
{
	UINT32 u4old_latch_ck;
	UINT32 u4old_rd_smpl;
	UINT32 u4old_dat_r_r_dly;
	UINT32 u4old_dat_dlyline_sel;
	UINT32 u4old_dat0_line1_dly;
	UINT32 u4old_dat1_line1_dly;
	UINT32 u4old_dat2_line1_dly;
	UINT32 u4old_dat3_line1_dly;
	UINT32 u4old_dat4_line1_dly;
	UINT32 u4old_dat5_line1_dly;
	UINT32 u4old_dat6_line1_dly;
	UINT32 u4old_dat7_line1_dly;
	UINT32 u4old_dat0_line2_dly;
	UINT32 u4old_dat1_line2_dly;
	UINT32 u4old_dat2_line2_dly;
	UINT32 u4old_dat3_line2_dly;
	UINT32 u4old_dat4_line2_dly;
	UINT32 u4old_dat5_line2_dly;
	UINT32 u4old_dat6_line2_dly;
	UINT32 u4old_dat7_line2_dly;
	UINT32 u4old_rd_smpl_sel;
	UINT32 u4old_rd_d0_smpl;
	UINT32 u4old_w_d_smpl;
	UINT32 u4old_w_d_smpl_sel;
	UINT32 u4old_pad_dat_wr_rx_dly;
	UINT32 u4old_pad_dat1_rx_dly3_mux_sel;
	UINT32 u4old_pad_dat3_rx_dly3_mux_sel;
	UINT32 u4old_pad_dat5_rx_dly3_mux_sel;
	UINT32 u4old_pad_dat7_rx_dly3_mux_sel;
	UINT32 u4old_pad_dat1_rx_dly3;
	UINT32 u4old_pad_dat3_rx_dly3;
	UINT32 u4old_pad_dat5_rx_dly3;
	UINT32 u4old_pad_dat7_rx_dly3;
	UINT32 u4old_w_dat_crc_ta;

}hs400_saved_regs;

typedef struct __sd_cmd_t__
{
    UINT8 idx;
    UINT32 arg;
    UINT32 resp[4];		// Maximum Length Reserved
    UINT32 autoStopResp;
    UINT32 dataMode;
    UINT32 buffLen;
    UINT32 flags;
    VOID *pBuff;				// Point to data buffer in PIO and basic DMA mode
} sd_cmd_t;

typedef struct __msdc_env_s__
{
    UINT8 fgHost;
    UINT8 cid[16];
    UINT8 rca[2];
    UINT8 csd[16];
    UINT8 ocr[4];
    UINT8 ext_csd_rsv[25];

} msdc_env_t;

typedef struct __msdc_autok_s__
{
	//Add for Autok parameters transfer from loader to uboot
	UINT32 SpeedMode;
	UINT32 K_IOCON;
	UINT32 K_PAD_TUNE0;
	UINT32 K_PAD_TUNE1;
	UINT32 K_PATCH_BIT0;
	UINT32 K_PATCH_BIT1;
	UINT32 K_PATCH_BIT2;
	UINT32 K_EMMC50_CFG0;

	UINT32 K_DAT_RD_DLY0;
	UINT32 K_DAT_RD_DLY1;
	UINT32 K_DAT_RD_DLY2;
	UINT32 K_DAT_RD_DLY3;

	UINT32 K_EMMC50_PAD_DS_TUNE;
	UINT32 K_EMMC50_PAD_CMD_TUNE;
	UINT32 K_EMMC50_PAD_DAT01_TUNE;
	UINT32 K_EMMC50_PAD_DAT23_TUNE;
	UINT32 K_EMMC50_PAD_DAT45_TUNE;
	UINT32 K_EMMC50_PAD_DAT67_TUNE;


} msdc_autok_t;


typedef struct __sdhost_s__
{
    UINT32 fgValid;

#define HOST_CAP_MMC_SUPPORT             (0x1<<0)
#define HOST_CAP_SD_SUPPORT              (0x1<<1)
#define HOST_CAP_SDIO_SUPPORT            (0x1<<2)
#define HOST_CAP_LOW_VOLTAGE_18V_SUPPORT (0x1<<3)
    UINT32 hostCap;

#define MSDC_DATA_PRE_DEF_MASK      (0x1<<0)
#define MSDC_DATA_END_AUTO_MASK     (0x1<<1)
#define MSDC_DATA_DDR_MODE_MASK     (0x1<<2)
    UINT32 hostAttr;

    UINT32 busWidth;
    UINT32 blkLen;

#define SPEED_MODE_DS               (0x0)
#define SPEED_MODE_HS               (0x1)
#define SPEED_MODE_HS200            (0x2)
#define SPEED_MODE_SDR50            (0x2)
#define SPEED_MODE_SDR104           (0x3)
#define SPEED_MODE_DDR50            (0x4)
#define SPEED_MODE_HS400            (0x5)

    UINT32 speedMode;

    // Select polling mode or interrupt mode
    UINT32 polling;

    // Host Data Mode
    UINT32 dataMode;

    // Host Bus Clock
    UINT32 maxClock;
    UINT32 curClock;

    // DMA Burst Size
    UINT32 dmaBstSize;
    // Configurable Maximum Basic DMA Len
    UINT32 maxBasicDmaLen;

    // Accumulated interrupt vector
    volatile UINT32 accuVect;

    // EXT_CSD
    UINT8 EXT_CSD[512];
    BOOL fgUpdateExtCsd;

	// Card identification flag
	BOOL fgCardIdent;

	#if defined(CC_MT5891) || defined(CONFIG_ARCH_MT5891)|| defined(CC_MT5882)
	//Saved regs val
	hs400_saved_regs stSavedRegs;
    #endif

	BOOL  fgRunAutoK;

} sdhost_t;

#if defined(CC_MT5399) || defined(CONFIG_ARCH_MT5399)|| \
    defined(CC_MT5890) || defined(CONFIG_ARCH_MT5890)|| \
    defined(CC_MT5891) || defined(CONFIG_ARCH_MT5891)|| \
    defined(CC_MT5882) || defined(CONFIG_ARCH_MT5882)|| \
    defined(CC_MT5861) || defined(CONFIG_ARCH_MT5861)|| \
    defined(CC_MT5883) || defined(CONFIG_ARCH_MT5883)|| \
    defined(CC_MT5891) || defined(CONFIG_ARCH_MT5891)
typedef struct
{
    UINT8 acName[32];
    UINT32 u4ID1;
    UINT32 u4ID2;
    UINT32 DS26Sample;
	UINT32 DS26Delay;
    UINT32 HS52Sample;
    UINT32 HS52Delay;
    UINT32 DDR52Sample;
    UINT32 DDR52Delay;
    UINT32 HS200Sample;
    UINT32 HS200Delay;
} EMMC_FLASH_DEV_T;
#else
typedef struct
{
    char acName[32];
    UINT32 u4ID1;
    UINT32 u4ID2;
    UINT32 u4Sample;
} EMMC_FLASH_DEV_T;
#endif


//Power Class
#define EXT_CSD_PWR_CL_52_360		202	/* RO */
#define EXT_CSD_PWR_CL_200_360		237	/* RO */
#define EXT_CSD_PWR_CL_DDR_52_360	239	/* RO */


//---------------------------------------------------------------------------
// export function declaration
//---------------------------------------------------------------------------

#ifndef CC_UBOOT
EXTERN INT32 MsdcInit (VOID);
EXTERN INT32 MsdcSDPowerSwitch(INT32 i4V);
EXTERN VOID MsdcInitHostConfig(VOID);
EXTERN VOID MsdcContinueClock (UINT32 i4ContinueClock);
EXTERN INT32 MsdcSetClkFreq (UINT32 clkFreq);
EXTERN INT32 MsdcFindHynixName (void);
EXTERN INT32 MsdcSetBusWidth (UINT32 busWidth);
EXTERN INT32 MsdcEnHSMode(UINT32 fgHSMode);
EXTERN INT32 MsdcEnDDRMode(UINT32 fgDDRMode);
EXTERN INT32 MsdcCardRescan (VOID);
EXTERN INT32 MsdcMemRead (UINT64 addr, VOID *pBuff, UINT32 buffLen);
EXTERN INT32 MsdcMemWrite(UINT64 addr, VOID *pBuff, UINT32 buffLen);
EXTERN INT32 MsdcMemErase(UINT64 startAddr, UINT64 endAddr, UINT32 eraseType);
EXTERN INT32 MsdcWPSeg(UINT64 wpAddr, UINT32 u4fgEn);
EXTERN INT32 MsdcHandleCSD(UINT32 fgHandle);
EXTERN INT32 MsdcGetEXTCSD(VOID);
EXTERN UINT8 MsdcGetEXTCSD_BootPartition(UINT32 index);
EXTERN INT32 MsdcSetEXTCSD(UINT32 index, UINT8 value);
EXTERN INT32 MsdcGetStatus(VOID *pBuff);
EXTERN INT32 MsdcGetWPStatus(UINT64 wpAddr, UINT32 *pWP, UINT64 *pWPType);
EXTERN INT32 MsdcGetSCR(VOID);
EXTERN INT32 MsdcGetSSR(VOID *pBuff);
EXTERN void MsdcFindDevName(UINT32 *pCID);
EXTERN INT32 MsdcSendCmd (sd_cmd_t *pCmd);
EXTERN INT32 MsdcReqCmdStart(sd_cmd_t *pCmd);
EXTERN INT32 MsdcRequest(sd_cmd_t *pCmd);
EXTERN INT32 cmd0_go_idle_state(UINT32 arg);
EXTERN INT32 cmd3_send_relative_addr(VOID);
EXTERN INT32 cmd7_select_card (UINT32 sel);
EXTERN INT32 cmd11_sd_voltage_switch(VOID);
EXTERN INT32 cmd19_sd_send_tuning_pattern(VOID);
EXTERN INT32 cmd21_mmc_send_tuning_block(VOID *pBuff, UINT32 buffLen);
EXTERN INT32 cmd12_stop_transmission(VOID);
EXTERN INT32 cmd13_send_status(VOID *pBuff);
EXTERN INT32 cmd17_read_single_block(UINT64 addr, VOID *pBuff, UINT32 buffLen);
EXTERN INT32 cmd24_write_single_block(UINT64 addr, VOID *pBuff, UINT32 buffLen);
EXTERN VOID MsdcFifoPathSelAndInit(VOID);

#if defined(CC_MT5399) || defined(CONFIG_ARCH_MT5399)|| \
    defined(CC_MT5890) || defined(CONFIG_ARCH_MT5890)|| \
    defined(CC_MT5882) || defined(CONFIG_ARCH_MT5882)|| \
    defined(CC_MT5883) || defined(CONFIG_ARCH_MT5883)|| \
    defined(CC_MT5891) || defined(CONFIG_ARCH_MT5891)
EXTERN INT32 MsdcHostVoltageSwitch(VOID);
#endif

#endif

#endif // #ifndef _MSDC_DRV_H_
