3169 lines
81 KiB
C
3169 lines
81 KiB
C
/***************************************************************************
|
|
* Filename: sdcard.c
|
|
*
|
|
* Authors:
|
|
*
|
|
* Description:
|
|
* SD card driver
|
|
* SDIO init and supply basic APIs
|
|
*
|
|
* Last Updated:
|
|
*
|
|
* Notes:
|
|
******************************************************************************/
|
|
#include "sdio.h"
|
|
//#include "intc.h" // for INTCConfigure declaration
|
|
//#include "intc_list.h" // for INTC_SRC_USB2CI_OTG definition
|
|
|
|
//#include "bsp_hisr.h"
|
|
|
|
//#include "utilities.h"
|
|
//#include "pmic.h"
|
|
#include "ff.h"
|
|
#include "fat32_utils.h"
|
|
#define fatal_printf uart_printf
|
|
#ifdef MV_USB2_MASS_STORAGE
|
|
#include "mvUsbStorage.h"
|
|
#endif
|
|
//add by yazhouren@asrmicro.com
|
|
#define PLAT_CRANE 1
|
|
#define FAT32_FILE_SYSTEM
|
|
///define for boot33
|
|
extern unsigned char pmic_id;
|
|
OSA_STATUS OSAFlagWait( OSFlagRef Ref, UINT32 mask, UINT32 operation, UINT32 *flags, UINT32 timeout )
|
|
{
|
|
return OS_SUCCESS;
|
|
}
|
|
//#define ASSERT(x) {if((x)==0){uart_printf("%s:%d\r\n", __FILE__, __LINE__);while(1);}}
|
|
int sdcard_fatfs_mount_status_g;
|
|
int sdcard_fat_is_ok(void)
|
|
{
|
|
return sdcard_fatfs_mount_status_g;
|
|
}
|
|
|
|
|
|
#ifdef FAT32_FILE_SYSTEM
|
|
//#include "crossplatformsw.h"
|
|
#endif
|
|
//#include "cgpio.h"
|
|
|
|
//#include "usb_macro.h"
|
|
//#include "platform.h"
|
|
//#include "mvUsbStorage.h"
|
|
#define SDCARD_DEBUG 0
|
|
#define SDCARD_LISR_DBG 0
|
|
|
|
#define SDCARD_INIT_UNDO 0
|
|
#define SDCARD_INIT_SUCCESS 1
|
|
#define SDCARD_INIT_FAILED 2
|
|
|
|
|
|
//0 for invalid card
|
|
// 1 for standard card
|
|
// 2 for high capacity card
|
|
static char card_type = 0;
|
|
static char hs_switch = 0;
|
|
#define CARD_TYPE_INVALID 0
|
|
#define CARD_TYPE_STANDARD 1
|
|
#define CARD_TYPE_HIGH 2
|
|
|
|
//card status
|
|
static char card_status = 1;
|
|
#define CARD_STATUS_INSERT 0
|
|
#define CARD_STATUS_REMOVE 1
|
|
|
|
static char card_mode;
|
|
#define CARD_MODE_INT 0
|
|
#define CARD_MODE_POLL 1
|
|
|
|
__align(4) unsigned char SDStack[2048];
|
|
__align(4) unsigned char SDCard_InsertRemove_Stack[2048];
|
|
|
|
volatile static UINT16 SD_RESPONSE[8]; //response registers
|
|
OSSemaRef SDSysRef = NULL;
|
|
//OSSemaRef SDCMDRef = NULL;
|
|
OSSemaRef SDDATARef = NULL;
|
|
|
|
OSTaskRef SDTaskRef = NULL;
|
|
OSTaskRef SDCard_InsertRemove_TaskRef = NULL;
|
|
OSFlagRef SDFlgRef = NULL;
|
|
OSFlagRef SD_CMDReset_FlgRef = NULL;
|
|
|
|
static OS_HISR SdcardHISR; //HISR control block
|
|
static OS_HISR SdcardInsertHISR;
|
|
static OS_HISR SdcardRemoveHISR;
|
|
|
|
//hisr for command and data transfer
|
|
//static NU_HISR SdCMDHISR;
|
|
static OS_HISR SDDATAHISR;
|
|
|
|
static UINT8 SD_CMD_COMP_status = 0;
|
|
static UINT8 SD_DATA_COMP_status = 0;
|
|
static UINT8 SD_DATA_START_status = 0;
|
|
static UINT8 sdcard_initialized = 0;
|
|
static UINT8 sdcard_reinitialized = 0;
|
|
static UINT8 SD_CMD_BufferReady = 0;
|
|
static UINT16 SD_ERR_INTSTATUS = 0;
|
|
|
|
static UINT32 SD_RCA = 0; //RCA of MMC card
|
|
static UINT32 SDCARD_CTRL_BASE_ADDR = 0;
|
|
static UINT32 SD_BLK_NUM = 0;
|
|
|
|
static UINT8 SD_Read_status = 0;
|
|
static UINT8 SD_Write_status = 0;
|
|
|
|
static UINT8 SD_Trans_Status = 0;
|
|
volatile UINT8 CMD8_timout_cnt = 0;
|
|
static UINT8 SD_Infinite_Err_Flag = 0;
|
|
static UINT8 SD_Decrease_Clk_Flag = 0;
|
|
|
|
static UINT32 gSDRecordTime;
|
|
static int ee_sd_dump_status_g = 1;
|
|
|
|
|
|
OSA_STATUS OSASemaphoreRelease_sdcard(OSASemaRef semaRef)
|
|
{
|
|
if (ee_sd_dump_status_g)
|
|
return OS_SUCCESS;
|
|
else
|
|
//return OSASemaphoreRelease(semaRef);
|
|
return OS_SUCCESS;
|
|
}
|
|
OSA_STATUS OSASemaphoreAcquire_sdcard(OSASemaRef semaRef, UINT32 timeout)
|
|
{
|
|
if (ee_sd_dump_status_g)
|
|
return OS_SUCCESS;
|
|
else
|
|
//return OSASemaphoreAcquire(semaRef, timeout);
|
|
return OS_SUCCESS;
|
|
}
|
|
|
|
//add by yazhouren@asrmicro.com
|
|
#define AIB_MMC1_IO_REG 0xD401e82c
|
|
static void AIB_MMC1_IO_Set_3_3V(void)
|
|
{
|
|
volatile unsigned int val = 0;
|
|
|
|
val = AIB_Secure_Read(AIB_MMC1_IO_REG); //AIB_MMC1_IO_REG
|
|
val &= ~(0x4); //0--> 3.3V enable, 1-->1.8V enable
|
|
AIB_Secure_Write(AIB_MMC1_IO_REG, val);
|
|
}
|
|
|
|
static void AIB_MMC1_IO_Set_1_8V(void)
|
|
{
|
|
volatile unsigned int val = 0;
|
|
|
|
val = AIB_Secure_Read(AIB_MMC1_IO_REG); //AIB_MMC1_IO_REG
|
|
val |= (0x4); //0--> 3.3V enable, 1-->1.8V enable
|
|
AIB_Secure_Write(AIB_MMC1_IO_REG, val);
|
|
}
|
|
|
|
static BOOL PlatformSDCardEnable(void)
|
|
{
|
|
return TRUE;
|
|
}
|
|
static void PMIC_Set_SDIO_1_8V(void)
|
|
{
|
|
if (PMIC_IS_PM812())
|
|
{
|
|
PM812_Ldo_12_set_1_8();
|
|
}
|
|
else if(PMIC_IS_PM813())
|
|
{
|
|
Ningbo_Ldo_9_set_1_8();
|
|
}
|
|
else //802
|
|
{
|
|
Guilin_Ldo_6_set_1_8();
|
|
}
|
|
AIB_MMC1_IO_Set_1_8V();
|
|
}
|
|
|
|
static void PMIC_Set_SDIO_2_8V(void)
|
|
{
|
|
AIB_MMC1_IO_Set_3_3V();
|
|
if (PMIC_IS_PM812())
|
|
{
|
|
PM812_Ldo_12_set_2_8();
|
|
}
|
|
else if(PMIC_IS_PM813())
|
|
{
|
|
Ningbo_Ldo_9_set_2_8();
|
|
}
|
|
else //802
|
|
{
|
|
Guilin_Ldo_6_set_2_8();
|
|
}
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* Function: eeGetSystemAssertFlag
|
|
********************************************************************************
|
|
* Description: Get system assert flag.
|
|
*
|
|
* Parameters:
|
|
*
|
|
* Return value:
|
|
*
|
|
* Notes:
|
|
*******************************************************************************/
|
|
BOOL eeGetSystemAssertFlag(void)
|
|
{
|
|
//return ee_sd_dump_status_g;
|
|
return eeSDDump_status_get();
|
|
}
|
|
|
|
|
|
|
|
/* SDR104 tuning pattern */
|
|
static const UINT8 sd_tuning_pattern[] =
|
|
{
|
|
0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc, 0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef,
|
|
0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb, 0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef,
|
|
0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c, 0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee,
|
|
0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff, 0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde,
|
|
};
|
|
|
|
//extern void USB2MgrDeviceReset(void);
|
|
extern void Create_CurDir(void);
|
|
extern BOOL DumpFileToSDEnable(void);
|
|
//get fat32 file system init status
|
|
//extern UINT8 FSInit_Status_Get(void);
|
|
extern void sdcard_check_free_space(UINT32 MinSize, BOOL DumpBin);
|
|
extern void Fat32_Init(void);
|
|
//extern void FSInit_Status_Init(void);
|
|
extern BOOL eeGetSystemAssertFlag(void);
|
|
|
|
static void SdCard_Wait(UINT32 count)
|
|
{
|
|
UINT32 i = 0;
|
|
for(i=0; i<count; i++)
|
|
{;}
|
|
}
|
|
|
|
static void SdCard_MsWait(UINT32 count)
|
|
{
|
|
UINT32 i = 0;
|
|
UINT32 j = 0;
|
|
for(i=0; i<count; i++)
|
|
{
|
|
for(j=0; j<40000; j++)
|
|
{
|
|
;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static UINT8 sdcard_readb(UINT32 base, UINT32 reg)
|
|
{
|
|
volatile UINT8* ptr8;
|
|
UINT8 tmp;
|
|
ptr8 = (volatile UINT8*)(base + reg);
|
|
tmp = *ptr8;
|
|
return tmp;
|
|
}
|
|
|
|
static void sdcard_writeb(UINT32 base, UINT32 reg, UINT8 data)
|
|
{
|
|
volatile UINT8* ptr8;
|
|
ptr8 = (volatile UINT8*)(base + reg);
|
|
*ptr8 = data;
|
|
}
|
|
|
|
static UINT32 sdcard_readl(UINT32 base, UINT32 reg)
|
|
{
|
|
volatile UINT32* ptr32;
|
|
UINT32 tmp;
|
|
ptr32 = (volatile UINT32*)(base + reg);
|
|
tmp = *ptr32;
|
|
return tmp;
|
|
}
|
|
|
|
static void sdcard_writel(UINT32 base, UINT32 reg, UINT32 data)
|
|
{
|
|
volatile UINT32* ptr32;
|
|
ptr32 = (volatile UINT32*)(base + reg);
|
|
*ptr32 = data;
|
|
}
|
|
|
|
static UINT16 sdcard_readw(UINT32 base, UINT32 reg)
|
|
{
|
|
volatile UINT16* ptr16;
|
|
UINT16 tmp;
|
|
ptr16 = (volatile UINT16*)(base + reg);
|
|
tmp = *ptr16;
|
|
return tmp;
|
|
}
|
|
|
|
static void sdcard_writew(UINT32 base, UINT32 reg, UINT16 data)
|
|
{
|
|
volatile UINT16* ptr16;
|
|
ptr16 = (volatile UINT16*)(base + reg);
|
|
*ptr16 = data;
|
|
}
|
|
|
|
static void SdCard_IRQ_Enable(UINT32 base_addr, UINT16 mask)
|
|
{
|
|
volatile UINT16* ptr16;
|
|
|
|
ptr16 = (UINT16*) (base_addr + SD_NORM_INTR_STS_EBLE_offset);
|
|
*ptr16 |= mask ;
|
|
|
|
ptr16 = (UINT16*) (base_addr + SD_NORM_INTR_STS_INTR_EBLE_offset);
|
|
*ptr16 |= mask ;
|
|
}
|
|
|
|
/**
|
|
* @brief: enable clock
|
|
* @base_addr: base address
|
|
* @clock: dividsion 0--48MHZ; 1--24MHZ; 2--12MHZ; 4--6MHZ;8--3MHZ
|
|
*/
|
|
static void SdCard_Enable_Clock(UINT32 base_addr, UINT32 CLOCK)
|
|
{
|
|
volatile UINT16* ptr16;
|
|
UINT32 tick_count;
|
|
#ifdef PLAT_CRANE
|
|
{
|
|
CLOCK = ((CLOCK&0x300)>>8)|((CLOCK&0xFF)<<2);
|
|
ptr16 = (UINT16*) (base_addr + SD_CLOCK_CTRL_offset);
|
|
if((*ptr16>>6) == (CLOCK&0x3FF))
|
|
{
|
|
// return;
|
|
}
|
|
|
|
/*turn on sd clock and set timeouts*/
|
|
ptr16 = (UINT16*) (base_addr + SD_CLOCK_CTRL_offset);
|
|
*ptr16 = (((CLOCK & 0X3FF)) << 6 | 0x01);
|
|
}
|
|
#else
|
|
if(NezhaChipIS_B0() == 1)
|
|
{
|
|
CLOCK = ((CLOCK&0x300)>>8)|((CLOCK&0xFF)<<2);
|
|
ptr16 = (UINT16*) (base_addr + SD_CLOCK_CTRL_offset);
|
|
if((*ptr16>>6) == (CLOCK&0x3FF))
|
|
{
|
|
// return;
|
|
}
|
|
|
|
/*turn on sd clock and set timeouts*/
|
|
ptr16 = (UINT16*) (base_addr + SD_CLOCK_CTRL_offset);
|
|
*ptr16 = (((CLOCK & 0X3FF)) << 6 | 0x01);
|
|
}
|
|
else
|
|
{
|
|
ptr16 = (UINT16*) (base_addr + SD_CLOCK_CTRL_offset);
|
|
if((*ptr16>>8) == (CLOCK&0xFF))
|
|
{
|
|
// return;
|
|
}
|
|
|
|
/*turn on sd clock and set timeouts*/
|
|
ptr16 = (UINT16*) (base_addr + SD_CLOCK_CTRL_offset);
|
|
*ptr16 = (((CLOCK & 0XFF)) << 8 | 0x01);
|
|
}
|
|
#endif
|
|
|
|
/*Loop wait for sd clock and timeout are set*/
|
|
tick_count = 100;
|
|
while( !(*ptr16 & 0x0002 == 0x2) )
|
|
{
|
|
if(tick_count == 0)
|
|
{
|
|
uart_printf("clock timeout \r\n");
|
|
}
|
|
SdCard_MsWait(1);
|
|
tick_count--;
|
|
}
|
|
|
|
*ptr16 |= 0x0004;
|
|
|
|
ptr16 = (UINT16*) (base_addr + SD_CLOCK_CTRL_offset);
|
|
|
|
//uart_printf("SDCARD:SD_CLOCK_CTRL_offset=%x", *ptr16);
|
|
|
|
}
|
|
|
|
static UINT32 SdCard_SW_ResetData(UINT32 base_addr)
|
|
{
|
|
volatile UINT16* ptr16;
|
|
UINT32 timeout = 10000;
|
|
UINT16 val;
|
|
|
|
#if SDCARD_DEBUG
|
|
uart_printf("SdCard_SW_ResetData\r\n");
|
|
#endif
|
|
|
|
ptr16 = (UINT16*) (base_addr + SD_SW_RESET_CTRL_offset);
|
|
val = *ptr16;
|
|
|
|
val |= SW_RST_DAT;
|
|
|
|
*ptr16 = val;
|
|
|
|
do
|
|
{
|
|
val = *ptr16;
|
|
if (!(val & (SW_RST_DAT)))
|
|
{
|
|
break;
|
|
}
|
|
|
|
} while (timeout--);
|
|
|
|
if (timeout)
|
|
{
|
|
return MMC_ERR_NONE;
|
|
}
|
|
|
|
uart_printf("SdCard_SW_ResetData timeout\r\n");
|
|
return MMC_ERR_CMD_TOUT;
|
|
}
|
|
|
|
static UINT32 SdCard_SW_ResetCmd(UINT32 base_addr)
|
|
{
|
|
volatile UINT16* ptr16;
|
|
UINT32 timeout = 10000;
|
|
UINT16 val;
|
|
|
|
#if SDCARD_DEBUG
|
|
uart_printf("SdCard_SW_ResetCmd\r\n");
|
|
#endif
|
|
|
|
ptr16 = (UINT16*) (base_addr + SD_SW_RESET_CTRL_offset);
|
|
val = *ptr16;
|
|
|
|
val |= SW_RST_CMD;
|
|
|
|
*ptr16 = val;
|
|
|
|
do
|
|
{
|
|
val = *ptr16;
|
|
if (!(val & (SW_RST_CMD)))
|
|
{
|
|
break;
|
|
}
|
|
|
|
} while (timeout--);
|
|
|
|
if (timeout)
|
|
{
|
|
//uart_printf("SdCard_SW_ResetCmd end\r\n");
|
|
return MMC_ERR_NONE;
|
|
}
|
|
|
|
uart_printf("SdCard_SW_ResetCmd timeout\r\n");
|
|
return MMC_ERR_CMD_TOUT;
|
|
}
|
|
|
|
|
|
static UINT32 SdCard_SW_Reset(UINT32 base_addr)
|
|
{
|
|
volatile UINT16* ptr16;
|
|
UINT32 timeout = 1000;
|
|
UINT16 val;
|
|
|
|
#if SDCARD_DEBUG
|
|
uart_printf("Software reset for card\r\n");
|
|
#endif
|
|
|
|
ptr16 = (UINT16*) (base_addr + SD_SW_RESET_CTRL_offset);
|
|
val = *ptr16;
|
|
|
|
val |= SW_RST_CMD | SW_RST_DAT;
|
|
|
|
*ptr16 = val;
|
|
|
|
do
|
|
{
|
|
val = *ptr16;
|
|
if (!(val & (SW_RST_DAT | SW_RST_CMD | SW_RST_ALL)))
|
|
break;
|
|
SdCard_Wait(1000);
|
|
} while (timeout--);
|
|
|
|
if (timeout)
|
|
return MMC_ERR_NONE;
|
|
|
|
#if SDCARD_DEBUG
|
|
uart_printf("Software reset timeout\r\n");
|
|
#endif
|
|
|
|
return MMC_ERR_CMD_TOUT;
|
|
}
|
|
|
|
/**
|
|
* @brief: send cmd without data
|
|
*
|
|
* @cmd: command code
|
|
* @argv: argument
|
|
* @base_addr: base address
|
|
*
|
|
* @return: 0 is success, otherwise is failure
|
|
*/
|
|
static UINT32 SdCard_Cmd_Nodata(UINT16 cmd, UINT32 argv, UINT32 base_addr)
|
|
{
|
|
volatile UINT32* ptr32;
|
|
volatile UINT16* ptr16;
|
|
UINT32 tick_count;
|
|
UINT32 mask;
|
|
int timeout = 0;
|
|
UINT16 isr_sts;
|
|
OSA_STATUS status;
|
|
/*Set wait*/
|
|
SD_CMD_COMP_status = 0;
|
|
|
|
timeout = 1000000;
|
|
mask = SDHCI_CMD_INHIBIT;
|
|
while((sdcard_readl(base_addr, SD_PRESENT_STAT_0_offset))&mask)
|
|
{
|
|
if(timeout == 0)
|
|
{
|
|
uart_printf("Controller never released inhabit bit\r\n");
|
|
return MMC_ERR_CMD_TOUT;
|
|
}
|
|
timeout--;
|
|
}
|
|
|
|
/*put to execute*/
|
|
ptr32 = (UINT32*) (base_addr + SD_ARG_LOW_offset);
|
|
*ptr32 = argv;
|
|
|
|
ptr16 = (UINT16*) (base_addr + SD_CMD_offset);
|
|
*ptr16 = cmd;
|
|
|
|
/*wait for complete*/
|
|
tick_count = 40000;
|
|
|
|
if(sdcard_get_mode() == CARD_MODE_INT)
|
|
{
|
|
while (!SD_CMD_COMP_status)
|
|
{
|
|
//SdCard_Wait(2000);
|
|
SdCard_Wait(500);//change by yazhouren@asrmicro.com
|
|
tick_count--;
|
|
if (tick_count == 0 )
|
|
{
|
|
uart_printf("Wait for command %d time out!\r\n",cmd>>8);
|
|
return MMC_ERR_CMD_TOUT;
|
|
}
|
|
}
|
|
|
|
}
|
|
else if(sdcard_get_mode() == CARD_MODE_POLL)
|
|
{
|
|
isr_sts = sdcard_readw(SDCARD_CTRL_BASE_ADDR, SD_NORM_INTR_STS_offset);
|
|
while (!(isr_sts & CMD_COMP))
|
|
{
|
|
//SdCard_Wait(2000);
|
|
SdCard_Wait(500); //change by hengshanyang, Owner:yazhouren
|
|
tick_count--;
|
|
if(tick_count == 0 )
|
|
{
|
|
uart_printf("Wait for command %d time out!\r\n",cmd>>8);
|
|
return MMC_ERR_CMD_TOUT;
|
|
}
|
|
isr_sts = sdcard_readw(SDCARD_CTRL_BASE_ADDR, SD_NORM_INTR_STS_offset);
|
|
}
|
|
//clear cmd complete interrupt
|
|
sdcard_writew(SDCARD_CTRL_BASE_ADDR, SD_NORM_INTR_STS_offset, CMD_COMP);
|
|
}
|
|
|
|
/*Get [0--7] Response registers*/
|
|
ptr16 = (UINT16*) (base_addr + SD_RESP_0_offset);
|
|
for (tick_count = 0; tick_count < 8; tick_count++)
|
|
{
|
|
SD_RESPONSE[tick_count] = *ptr16;
|
|
ptr16++;
|
|
}
|
|
|
|
return MMC_ERR_NONE;
|
|
}
|
|
|
|
/**
|
|
* @brief: send cmd with data
|
|
*
|
|
* @cmd: command code
|
|
* @argv: argument
|
|
* @base_addr: base address
|
|
*
|
|
* @return: 0 is success, otherwise is failure
|
|
*/
|
|
static UINT32 SdCard_Read_NoDMA(UINT16 cmd, UINT32 argv, UINT16 blk_size, UINT16 blk_cnt, UINT32 buffer)
|
|
{
|
|
volatile UINT32* ptr32;
|
|
volatile UINT16* ptr16;
|
|
UINT32 tick_count,base_addr;
|
|
UINT32 mask;
|
|
int timeout = 0;
|
|
UINT16 isr_sts;
|
|
OSA_STATUS status;
|
|
|
|
base_addr = SDCARD_CTRL_BASE_ADDR;
|
|
/*Set wait*/
|
|
SD_CMD_COMP_status = 0;
|
|
SD_CMD_BufferReady = 0;
|
|
|
|
timeout = 1000000;
|
|
mask = SDHCI_CMD_INHIBIT;
|
|
while((sdcard_readl(base_addr, SD_PRESENT_STAT_0_offset))&mask)
|
|
{
|
|
if(timeout == 0)
|
|
{
|
|
uart_printf("Controller never released inhabit bit\r\n");
|
|
return MMC_ERR_CMD_TOUT;
|
|
}
|
|
timeout--;
|
|
}
|
|
|
|
/*set block size and block count*/
|
|
ptr32 = (UINT32*) (base_addr + SD_BLOCK_SIZE_offset);
|
|
*ptr32 = blk_size | (blk_cnt << 16);
|
|
/*put to execute*/
|
|
ptr32 = (UINT32*) (base_addr + SD_ARG_LOW_offset);
|
|
*ptr32 = argv;
|
|
|
|
sdcard_writel(base_addr, SD_TRANSFER_MODE_offset, (0x10|(cmd<<16)));
|
|
|
|
/*wait for complete*/
|
|
#if 0
|
|
tick_count = 40000;
|
|
|
|
if(sdcard_get_mode() == CARD_MODE_INT)
|
|
{
|
|
while (!SD_CMD_COMP_status)
|
|
{
|
|
SdCard_Wait(2000);
|
|
tick_count--;
|
|
if (tick_count == 0 )
|
|
{
|
|
uart_printf("Wait for command %d time out!\r\n",cmd>>8);
|
|
return MMC_ERR_CMD_TOUT;
|
|
}
|
|
}
|
|
|
|
}
|
|
else if(sdcard_get_mode() == CARD_MODE_POLL)
|
|
{
|
|
isr_sts = sdcard_readw(SDCARD_CTRL_BASE_ADDR, SD_NORM_INTR_STS_offset);
|
|
while (!(isr_sts & CMD_COMP))
|
|
{
|
|
SdCard_Wait(2000);
|
|
tick_count--;
|
|
if(tick_count == 0 )
|
|
{
|
|
uart_printf("Wait for command %d time out!\r\n",cmd>>8);
|
|
return MMC_ERR_CMD_TOUT;
|
|
}
|
|
isr_sts = sdcard_readw(SDCARD_CTRL_BASE_ADDR, SD_NORM_INTR_STS_offset);
|
|
}
|
|
//clear cmd complete interrupt
|
|
sdcard_writew(SDCARD_CTRL_BASE_ADDR, SD_NORM_INTR_STS_offset, CMD_COMP);
|
|
}
|
|
|
|
/*Get [0--7] Response registers*/
|
|
ptr16 = (UINT16*) (base_addr + SD_RESP_0_offset);
|
|
for (tick_count = 0; tick_count < 8; tick_count++)
|
|
{
|
|
SD_RESPONSE[tick_count] = *ptr16;
|
|
ptr16++;
|
|
}
|
|
#endif
|
|
//wait for buffer ready
|
|
tick_count = 80000;
|
|
if(sdcard_get_mode() == CARD_MODE_INT)
|
|
{
|
|
while (!SD_CMD_BufferReady)
|
|
{
|
|
SdCard_Wait(2000);
|
|
tick_count--;
|
|
if (tick_count == 0 )
|
|
{
|
|
uart_printf("Wait for CMD%d Buffer ready time out!\r\n",cmd>>8);
|
|
return MMC_ERR_CMD_TOUT;
|
|
}
|
|
}
|
|
|
|
}
|
|
else if(sdcard_get_mode() == CARD_MODE_POLL)
|
|
{
|
|
isr_sts = sdcard_readw(SDCARD_CTRL_BASE_ADDR, SD_NORM_INTR_STS_offset);
|
|
while (!(isr_sts & RX_RDY))
|
|
{
|
|
SdCard_Wait(2000);
|
|
tick_count--;
|
|
if(tick_count == 0 )
|
|
{
|
|
uart_printf("Wait for CMD%d Buffer ready time out!\r\n",cmd>>8);
|
|
return MMC_ERR_CMD_TOUT;
|
|
}
|
|
isr_sts = sdcard_readw(SDCARD_CTRL_BASE_ADDR, SD_NORM_INTR_STS_offset);
|
|
}
|
|
//clear cmd complete interrupt
|
|
sdcard_writew(SDCARD_CTRL_BASE_ADDR, SD_NORM_INTR_STS_offset, CMD_COMP);
|
|
}
|
|
|
|
UINT16 count;
|
|
count = 0;
|
|
ptr32 = (UINT32 *)buffer;
|
|
while(count < blk_size)
|
|
{
|
|
*ptr32 = sdcard_readl(base_addr, SD_BUF_PORT_0_offset);
|
|
ptr32++;
|
|
count = count+4;
|
|
}
|
|
|
|
return MMC_ERR_NONE;
|
|
}
|
|
int sdcard_clk_on(void)
|
|
{
|
|
volatile UINT32* ptr32;
|
|
|
|
/*Turn on SD host 0 axi clock and pheripherial clock*/
|
|
ptr32 = (UINT32*) (SD0_HOST_PMU_AXI_CLOCK) ;
|
|
#ifdef PLAT_CRANE
|
|
*ptr32 = 0x95b;//change by yazhouren@asrmicro.com
|
|
#else
|
|
*ptr32 = 0x59;
|
|
#endif
|
|
/*Turn on SD host 1 axi clock and pheripherial clock*/
|
|
ptr32 = (UINT32*) (SD1_HOST_PMU_AXI_CLOCK) ;
|
|
#ifdef PLAT_CRANE
|
|
*ptr32 = 0x952;//change by yazhouren@asrmicro.com
|
|
#else
|
|
*ptr32 = 0x52;
|
|
#endif
|
|
|
|
uart_printf("SDCARD:SD1_HOST_PMU_AXI_CLOCK=%x\r\n", *(UINT32*) (SD0_HOST_PMU_AXI_CLOCK));
|
|
return 0;
|
|
}
|
|
|
|
int sdcard_clk_off(UINT32 base)
|
|
{
|
|
volatile UINT32* ptr32;
|
|
UINT16 clk;
|
|
|
|
/*Turn off SD host 1 axi clock and pheripherial clock*/
|
|
ptr32 = (UINT32*) (SD1_HOST_PMU_AXI_CLOCK) ;
|
|
*ptr32 = 0x0;
|
|
clk = sdcard_readw(base, SD_CLOCK_CTRL_offset);
|
|
|
|
//disable sd card clock
|
|
clk = clk & 0xfffb;
|
|
sdcard_writel(base, SD_CLOCK_CTRL_offset, clk);
|
|
|
|
uart_printf("clk off:0x%x", sdcard_readl(base, SD_CLOCK_CTRL_offset));
|
|
}
|
|
|
|
/**
|
|
* @brief This function set voltage.
|
|
*
|
|
* @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
|
|
*/
|
|
static int sdcard_set_power()
|
|
{
|
|
volatile UINT8* ptr8;
|
|
|
|
ptr8 = (UINT8*) (SDCARD_CTRL_BASE_ADDR + SDHCI_POWER_CONTROL);
|
|
if(0x0F == *ptr8)
|
|
{
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
uart_printf("==sdcard set power==\r\n");
|
|
*ptr8 = 0x0E; //3.3v
|
|
*ptr8 |= SDHCI_POWER_ON;
|
|
SdCard_MsWait(20);
|
|
uart_printf("sdcard set power %x\r\n",*((UINT8*) (SDCARD_CTRL_BASE_ADDR + SDHCI_POWER_CONTROL)));
|
|
ptr8 = (UINT8*) (SDCARD_CTRL_BASE_ADDR + SD_HOST_CTRL_offset);
|
|
*ptr8 = 0x00;
|
|
uart_printf("sdcard set ctrl %x\r\n",*((UINT8*) (SDCARD_CTRL_BASE_ADDR + SD_HOST_CTRL_offset)));
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#define UNSTUFF_BITS(resp,start,size) \
|
|
({ \
|
|
const int __size = size; \
|
|
const UINT32 __mask = (__size < 32 ? 1 << __size : 0) - 1; \
|
|
const int __off = 3 - ((start) / 32); \
|
|
const int __shft = (start) & 31; \
|
|
UINT32 __res; \
|
|
\
|
|
__res = resp[__off] >> __shft; \
|
|
if (__size + __shft > 32) \
|
|
__res |= resp[__off-1] << ((32 - __shft) % 32); \
|
|
__res & __mask; \
|
|
})
|
|
|
|
static void SD_GetResponse136(UINT32* resp)
|
|
{
|
|
resp[0] = SD_RESPONSE[5] >> 8 | SD_RESPONSE[6] << 8 | SD_RESPONSE[7] << 24;
|
|
resp[1] = SD_RESPONSE[3] >> 8 | SD_RESPONSE[4] << 8 | SD_RESPONSE[5] << 24;
|
|
resp[2] = SD_RESPONSE[1] >> 8 | SD_RESPONSE[2] << 8 | SD_RESPONSE[3] << 24;
|
|
resp[3] = SD_RESPONSE[0] << 8 | SD_RESPONSE[1] << 24;
|
|
}
|
|
|
|
static UINT32 SD_Decode_CSD(UINT32 base_addr)
|
|
{
|
|
UINT32 c_size,c_size_mult,csd_struct,capacity,read_len;
|
|
UINT32 resp[4];
|
|
|
|
SD_GetResponse136(resp);
|
|
|
|
csd_struct = UNSTUFF_BITS(resp, 126, 2);
|
|
switch(csd_struct){
|
|
case 0:
|
|
c_size = UNSTUFF_BITS(resp,62,12);
|
|
c_size_mult = UNSTUFF_BITS(resp,47,3);
|
|
read_len = UNSTUFF_BITS(resp,80,4);
|
|
capacity = (1+c_size) << (c_size_mult + 2);
|
|
capacity = capacity << read_len;
|
|
|
|
SD_BLK_NUM = capacity/0x200;
|
|
uart_printf("c_size:0x%x,c_size_mult:0x%x,read_len:0x%x",c_size,c_size_mult,read_len);
|
|
uart_printf("standard card, capacity:0x%x.,blk_num:0x%x\n",capacity,SD_BLK_NUM);
|
|
break;
|
|
case 1:
|
|
c_size = UNSTUFF_BITS(resp, 48, 22);
|
|
capacity = (1+c_size) << 10;
|
|
//this should be block number, the actual capacity need to mult with 0x200
|
|
SD_BLK_NUM = capacity;
|
|
uart_printf("high capacity card, capacity:0x%x\n",capacity);
|
|
break;
|
|
default:
|
|
uart_printf("unrecognised CSD structure version:0x%x",csd_struct);
|
|
}
|
|
|
|
return MMC_ERR_NONE;
|
|
}
|
|
|
|
|
|
extern void PMIC_ShutDown_SdLDO(void);
|
|
static int sdcard_cmd_init()
|
|
{
|
|
UINT32 status = 0;
|
|
UINT16 cmd = 0;
|
|
UINT32 argv = 0;
|
|
UINT32 ocr = 0;
|
|
UINT32 count = 0;
|
|
UINT32 base_addr = SD1_HOST_CTRL_ADDR;
|
|
UINT32 res;
|
|
card_type = CARD_TYPE_INVALID;
|
|
/*
|
|
cmd0 set card to idle, cmd8 check the version,
|
|
cmd0 -> cmd8 -> r7 ->cmd5 ->r4 ->cmd3 ->r6 ->cmd7 ->r1b
|
|
*/
|
|
|
|
/*Invoke CMD0 */
|
|
uart_printf("Send CMD0\n");
|
|
//SdCard_MsWait(50);
|
|
status = SdCard_Cmd_Nodata(0x0000, 0x00000000, base_addr);
|
|
if (status != MMC_ERR_NONE)
|
|
{
|
|
uart_printf("Error Invoke CMD0");
|
|
}
|
|
else
|
|
{
|
|
uart_printf("CMD0 Done!\n");
|
|
}
|
|
|
|
/*Invoke CMD8 */
|
|
uart_printf("Send CMD8\n");
|
|
//SdCard_MsWait(50);
|
|
#if 1
|
|
cmd = 0x081a;
|
|
/*set ocr value to the voltage, 0xAA is check pattern*/
|
|
argv = ((MMC_OCR_AVAIL & 0xFF8000) != 0) << 8 | 0xAA;
|
|
status = SdCard_Cmd_Nodata(cmd , argv, base_addr);
|
|
if (status != MMC_ERR_NONE)
|
|
{
|
|
uart_printf("Error Invoke CMD8, version1.0 or No SD inserted!\n");
|
|
return MMC_ERR_CMD_TOUT;//add by yazhouren@asrmicro.com
|
|
}
|
|
else
|
|
{
|
|
UINT8 result = SD_RESPONSE[0]&0xFF;
|
|
if(result != 0xAA)
|
|
{
|
|
uart_printf("cmd8 error\n");
|
|
return MMC_ERR_INVALID;
|
|
}
|
|
|
|
/*cmd8's response is r7, r7 equal resp0 in this program,
|
|
resp0[15:8]=voltage, resp0[7:0]=check pattern*/
|
|
uart_printf("Response CMD8: %x\n", SD_RESPONSE[0]);
|
|
uart_printf("voltage: %x \r\n", SD_RESPONSE[1]);
|
|
uart_printf("CMD8 Done!\n");
|
|
}
|
|
#endif
|
|
CMD8_timout_cnt = 0;
|
|
//send ACMD41
|
|
count = 400;
|
|
//SdCard_MsWait(50);
|
|
do{
|
|
cmd = 0x371a;
|
|
argv = 0x0;
|
|
status = SdCard_Cmd_Nodata(cmd , argv, base_addr);
|
|
|
|
if(status != MMC_ERR_NONE)
|
|
{
|
|
uart_printf("Error Invoke CMD55");
|
|
return MMC_ERR_CMD_TOUT;
|
|
}
|
|
|
|
//send command with HCS=1(BIT30) and S18R=1(BIT24)
|
|
cmd = 0x2902;
|
|
//argv = 0x40ff8000;
|
|
argv = 0x41300000;
|
|
status = SdCard_Cmd_Nodata(cmd,argv,base_addr);
|
|
if(status != MMC_ERR_NONE)
|
|
{
|
|
uart_printf("Error Invoke CMD41\n");
|
|
return MMC_ERR_CMD_TOUT;
|
|
}
|
|
|
|
res = SD_RESPONSE[1];
|
|
|
|
count --;
|
|
//uart_printf("ACMD41 send\n");
|
|
SdCard_MsWait(10);
|
|
}
|
|
while((count > 0) && ((res & 0x8000) == 0x0));
|
|
|
|
//check BIT31
|
|
if((res & 0x8000) == 0)
|
|
{
|
|
uart_printf("sd card init failed!response:0x%x,0x%x\n",SD_RESPONSE[0],SD_RESPONSE[1]);
|
|
|
|
}
|
|
//check BIT30, CCS
|
|
if(res & 0x4000)
|
|
{
|
|
card_type = CARD_TYPE_HIGH;
|
|
uart_printf("high capacity card\n");
|
|
}
|
|
else
|
|
{
|
|
card_type = CARD_TYPE_STANDARD;
|
|
uart_printf("standard card\n");
|
|
}
|
|
|
|
//only enable UHS for Samsung platform
|
|
#if 0 //add by yazhouren@asrmicro.com
|
|
if((PlatformGetProjectType() == NEZHA_SMIFI_V2) || (PlatformGetProjectType() == NEZHA_SMNAND_V2))
|
|
{
|
|
if(res & 0x100)
|
|
{
|
|
hs_switch = 1;
|
|
uart_printf("This card can switch to HS mode");
|
|
}
|
|
}
|
|
#endif
|
|
uart_printf("ACMD41,response:0x%x,0x%x\n",SD_RESPONSE[0],SD_RESPONSE[1]);
|
|
|
|
if(hs_switch == 1)
|
|
{
|
|
//send cmd11
|
|
argv = sdcard_readl(base_addr, SD_PRESENT_STAT_0_offset);
|
|
uart_printf("before send cmd11, present state:0x%x",argv);
|
|
uart_printf("Send CMD11");
|
|
cmd = 0x0b3a;
|
|
argv = 0;
|
|
status = SdCard_Cmd_Nodata(cmd,argv,base_addr);
|
|
if(status != MMC_ERR_CMD_TOUT)
|
|
{
|
|
uart_printf("CMD11 response OK");
|
|
SdCard_MsWait(10);
|
|
argv = sdcard_readl(base_addr, SD_PRESENT_STAT_0_offset);
|
|
uart_printf("before disable clock, present state:0x%x",argv);
|
|
//disable SD clock
|
|
cmd = sdcard_readw(base_addr, SD_CLOCK_CTRL_offset);
|
|
cmd = cmd & 0xFFFB;
|
|
sdcard_writew(base_addr, SD_CLOCK_CTRL_offset, cmd);
|
|
SdCard_MsWait(2);
|
|
|
|
//modify Host control 2, 1.8v signaling enable
|
|
cmd = sdcard_readw(base_addr, 0x3E);
|
|
uart_printf("before change, host control2:0x%x",cmd);
|
|
cmd = cmd | 0x8;
|
|
sdcard_writew(base_addr, 0x3E, cmd);
|
|
|
|
//modify host control 1 register
|
|
cmd = sdcard_readw(base_addr, SD_HOST_CTRL_offset);
|
|
cmd = cmd & 0xff;
|
|
cmd = cmd | 0xb00;
|
|
sdcard_writew(base_addr, SD_HOST_CTRL_offset, cmd);
|
|
uart_printf("host control1:0x%x",cmd);
|
|
|
|
//change the voltage to 1.8v
|
|
PMIC_Set_SDIO_1_8V();
|
|
SdCard_MsWait(10);
|
|
cmd = sdcard_readw(base_addr, 0x3E);
|
|
uart_printf("change voltage, host control2:0x%x",cmd);
|
|
//modify SD FIFO param, enable force clock on
|
|
argv = sdcard_readl(base_addr, 0x104);
|
|
uart_printf("1 SD FIFO param:0x%x",argv);
|
|
|
|
argv = argv | 0x1800;
|
|
sdcard_writel(base_addr, 0x104, argv);
|
|
|
|
|
|
argv = sdcard_readl(base_addr, SD_PRESENT_STAT_0_offset);
|
|
while((argv & 0xf00000) != 0xf00000)
|
|
{
|
|
argv = sdcard_readl(base_addr, SD_PRESENT_STAT_0_offset);
|
|
uart_printf("present state:0x%x",argv);
|
|
}
|
|
uart_printf("Enable Clock,present state:0x%x",argv);
|
|
|
|
SdCard_MsWait(5);
|
|
|
|
//disable clock force sd
|
|
argv = sdcard_readl(base_addr, 0x104);
|
|
uart_printf("2 SD FIFO param:0x%x",argv);
|
|
|
|
argv = argv & 0xFFFFE7FF;
|
|
sdcard_writel(base_addr, 0x104, argv);
|
|
uart_printf("disable force on, SD FIFO param:0x%x", sdcard_readl(base_addr, 0x104));
|
|
|
|
//enable sd clock
|
|
SdCard_Enable_Clock(base_addr,0x300);
|
|
SdCard_MsWait(5);
|
|
|
|
}
|
|
else
|
|
{
|
|
uart_printf("Error Invoke CMD11\n");
|
|
}
|
|
}
|
|
//clear cmd8 timeout count
|
|
CMD8_timout_cnt = 0;
|
|
//SdCard_MsWait(20);
|
|
|
|
uart_printf("Send CMD2\n");
|
|
cmd = 0x0209;
|
|
argv = 0x0;
|
|
status = SdCard_Cmd_Nodata(cmd,argv,base_addr);
|
|
if(status != MMC_ERR_NONE)
|
|
{
|
|
uart_printf("Error Invoke CMD2");
|
|
return MMC_ERR_CMD_TOUT;
|
|
}
|
|
//SdCard_MsWait(50);
|
|
/*Invoke CMD3, cmd3 get the RCA*/
|
|
//uart_printf("Send CMD3");
|
|
cmd = 0x031a;
|
|
argv = 0x0;
|
|
status = SdCard_Cmd_Nodata(cmd,argv, base_addr);
|
|
if (status != MMC_ERR_NONE)
|
|
{
|
|
uart_printf("Error Invoke CMD3");
|
|
return MMC_ERR_CMD_TOUT;
|
|
}
|
|
else
|
|
{
|
|
/*read RCA, cmd3's response is R6, R6[39:24] is RCA, R6[23:8] is card status
|
|
in this program, resp1 is RCA*/
|
|
uart_printf("CMD3 Response: %x, %x\n", SD_RESPONSE[0], SD_RESPONSE[1]);
|
|
SD_RCA = SD_RESPONSE[1] & 0xffff;
|
|
|
|
uart_printf("Card RCA: %x", SD_RCA);
|
|
//uart_printf("CMD3 Done!");
|
|
}
|
|
|
|
//SdCard_MsWait(50);
|
|
//send command 9 to read CSD
|
|
status = SdCard_Cmd_Nodata(0x0901, SD_RCA<<16, base_addr);
|
|
|
|
if (status != MMC_ERR_NONE)
|
|
{
|
|
uart_printf("Error Invoke CMD9\r\n");
|
|
} else {
|
|
uart_printf("CMD9 Done!\r\n");
|
|
}
|
|
|
|
/*decode card CSD*/
|
|
SD_Decode_CSD(base_addr);
|
|
|
|
/*Invoke CMD7, cmd7 is select card, its argument[31:16] is RCA,other bits are stuff*/
|
|
argv = SD_RCA << 16;
|
|
//argv = 0x10000;
|
|
status = SdCard_Cmd_Nodata(0x071b, argv, base_addr);
|
|
if (status != MMC_ERR_NONE)
|
|
{
|
|
uart_printf("Error Invoke CMD7\n");
|
|
return MMC_ERR_CMD_TOUT;
|
|
}
|
|
else
|
|
{
|
|
/*cmd7's response is R1b, R1b is identical to R1 with an optional busy
|
|
signal transmitted on the data line, R1[39:8] is card status, in this program,
|
|
resp0 and resp1 is represent these bits*/
|
|
//uart_printf("CMD7 Response: %x, %x", SD_RESPONSE[0], SD_RESPONSE[1]);
|
|
//uart_printf("CMD7 Done!");
|
|
}
|
|
//SdCard_MsWait(50);
|
|
|
|
//uart_printf("card initialization and identification passed,enter into transfer state!\n");
|
|
return 0;
|
|
}
|
|
|
|
static int sdcard_enable_highspeed(void)
|
|
{
|
|
UINT16 cmd = 0;
|
|
UINT16 value;
|
|
UINT32 base_addr = SD1_HOST_CTRL_ADDR;
|
|
UINT32 status = 0, argv;
|
|
|
|
cmd = 0x063a;
|
|
argv = 0x80fffff1;
|
|
|
|
status = SdCard_Cmd_Nodata(cmd, argv, base_addr);
|
|
|
|
if (status != MMC_ERR_NONE)
|
|
{
|
|
uart_printf("Error Invoke CMD6");
|
|
return MMC_ERR_CMD_TOUT;
|
|
}
|
|
|
|
SdCard_MsWait(100);
|
|
|
|
value = sdcard_readw(base_addr, SD_HOST_CTRL_offset);
|
|
uart_printf("before set highspeed,host control:0x%x\n",value);
|
|
value |= (1<<2);
|
|
sdcard_writew(base_addr, SD_HOST_CTRL_offset, value);
|
|
uart_printf("after set highspeed,host control:0x%x\n",value);
|
|
|
|
uart_printf("sd card set highspeed success!\n");
|
|
return 0;
|
|
}
|
|
|
|
static int sdcard_set_width(UINT32 bus_width)
|
|
{
|
|
UINT32 base_addr = SD1_HOST_CTRL_ADDR;
|
|
UINT16 value;
|
|
UINT16 cmd = 0;
|
|
UINT32 argv = 0;
|
|
UINT32 status = 0;
|
|
|
|
value = sdcard_readw(base_addr, SD_HOST_CTRL_offset);
|
|
uart_printf("original host control:0x%x\n",value);
|
|
value = (value & 0xfffd) | (bus_width<<1);
|
|
uart_printf("modified host control:0x%x\n",value);
|
|
sdcard_writew(base_addr, SD_HOST_CTRL_offset, value);
|
|
SdCard_MsWait(100);
|
|
|
|
cmd = 0x371a;
|
|
argv = SD_RCA << 16;
|
|
|
|
status = SdCard_Cmd_Nodata(cmd, argv, base_addr);
|
|
if (status != MMC_ERR_NONE)
|
|
{
|
|
uart_printf("Error Invoke CMD55");
|
|
return MMC_ERR_CMD_TOUT;
|
|
}
|
|
|
|
cmd = 0x061a;
|
|
argv = bus_width<<1;
|
|
|
|
status = SdCard_Cmd_Nodata(cmd, argv, base_addr);
|
|
if (status != MMC_ERR_NONE)
|
|
{
|
|
uart_printf("Error Invoke ACMD6");
|
|
return MMC_ERR_CMD_TOUT;
|
|
}
|
|
|
|
uart_printf("sd card set buswidth success!\n");
|
|
return 0;
|
|
}
|
|
|
|
static void sdcard_config_pin()
|
|
{
|
|
|
|
volatile unsigned long *r;
|
|
#if 0 //add by yazhouren@asrmicro.com
|
|
PlatformBoardType board_type = NEZHA_MAX_BOARD_TYPE;
|
|
board_type = PlatformGetBoardType();
|
|
switch(board_type)
|
|
{
|
|
case NEZHA_MMIFI_V4_BOARD:
|
|
{
|
|
Sdcard_clear_gpio49_bit(); //added by notion 20140319
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
#endif
|
|
//uart_printf("==pin config start==");
|
|
|
|
sdcard_card_detect_config();
|
|
|
|
#ifdef PLAT_CRANE
|
|
//r = (volatile unsigned long*)(0xD401E2C0); //GPIO70
|
|
//*r = 0x10C0;
|
|
|
|
/*
|
|
r = (volatile unsigned long*)(0xD401E0AC); //card detect
|
|
uart_printf("The default MMC_CD value:0x%x\n",*r);
|
|
*r = 0x10A0;
|
|
uart_printf("The modified MMC_CD value:0x%x\n",*r);
|
|
*/
|
|
r = (volatile unsigned long*)(0xD401E0A8); //clk
|
|
*r = 0x10C0;
|
|
|
|
r = (volatile unsigned long*)(0xD401E0A4); //cmd
|
|
*r = 0x10C0;
|
|
// *r = 0x10C0; //config as gpio17
|
|
|
|
r = (volatile unsigned long*)(0xD401E0A0); //data0
|
|
*r = 0x10C0;
|
|
|
|
r = (volatile unsigned long*)(0xD401E09C); //data1
|
|
*r = 0x10C0;
|
|
|
|
r = (volatile unsigned long*)(0xD401E098); //data2
|
|
*r = 0x10C0;
|
|
|
|
r = (volatile unsigned long*)(0xD401E094); //data3
|
|
*r = 0x10C0;
|
|
|
|
|
|
//config GPIO70 as output
|
|
//r = (volatile unsigned long*)(0xD4019008 + 0x0C);
|
|
//*r |= 0x40;
|
|
|
|
//r = (volatile unsigned long*)(0xD4019008 + 0x18);
|
|
//*r |= 0x40; //GPIO70 to high level
|
|
|
|
#endif
|
|
|
|
//uart_printf("==pin config end==");
|
|
|
|
}
|
|
|
|
static sdcard_card_detect_config()
|
|
{
|
|
volatile unsigned long *r;
|
|
//uart_printf("==card detect pin config==");
|
|
//0xac, function0, card detect
|
|
r = (volatile unsigned long*)(0xD401E0ac); //card detect
|
|
*r = (*r & 0xFFFF0000) | 0xD0C0;
|
|
uart_printf("card detect:0x%x\r\n",*r);
|
|
}
|
|
void sdcard_burstsize_config()
|
|
{
|
|
volatile UINT16* ptr16;
|
|
UINT32 base_addr = SD1_HOST_CTRL_ADDR;
|
|
|
|
/*set sd_clk delay */
|
|
ptr16 = (UINT16*) (base_addr + SD_CLOCK_AND_BURST_SIZE_SETUP_offset);
|
|
*ptr16 = 0x03C5;
|
|
uart_printf("burst set %x", *((UINT16*) (base_addr + SD_CLOCK_AND_BURST_SIZE_SETUP_offset)));
|
|
}
|
|
|
|
/**
|
|
* @brief: This function enable or disable card interrupt.
|
|
*
|
|
* @enable: 1 is enable, 0 is disable
|
|
*/
|
|
void sd_card_int(UNSIGNED_INT enable)
|
|
{
|
|
UINT16 isr;
|
|
|
|
isr = sdcard_readw(SDCARD_CTRL_BASE_ADDR, SD_NORM_INTR_STS_EBLE_offset);
|
|
if(enable)
|
|
isr |= CARD_INT;
|
|
else
|
|
isr &= ~CARD_INT;
|
|
sdcard_writew(SDCARD_CTRL_BASE_ADDR, SD_NORM_INTR_STS_EBLE_offset, isr);
|
|
sdcard_writew(SDCARD_CTRL_BASE_ADDR, SD_NORM_INTR_STS_INTR_EBLE_offset, isr);
|
|
}
|
|
|
|
void sd_dumpregs(UINT32 base)
|
|
{
|
|
UINT16 isr_sts = 0;
|
|
|
|
uart_printf("SD card error: 0x%x", sdcard_readl(base, SD_PRESENT_STAT_0_offset));
|
|
|
|
uart_printf(": ============== REGISTER DUMP ==============\r\n");
|
|
uart_printf(": DMA addr: 0x%08x | Version: 0x%08x\r\n",
|
|
sdcard_readl(base, SD_SYSADDR_LOW_offset),
|
|
sdcard_readw(base, SDHCI_HOST_VERSION));
|
|
uart_printf(": Blk size: 0x%08x | Blk cnt: 0x%x\r\n",
|
|
sdcard_readw(base, SD_BLOCK_SIZE_offset),
|
|
sdcard_readw(base, SD_BLOCK_COUNT_offset));
|
|
uart_printf(": Argument: 0x%08x | Trn mode: 0x%08x\r\n",
|
|
sdcard_readl(base, SD_ARG_LOW_offset),
|
|
sdcard_readw(base, SD_TRANSFER_MODE_offset));
|
|
uart_printf(": Present: 0x%08x | Host ctl: 0x%08x\r\n",
|
|
sdcard_readl(base, SD_PRESENT_STAT_0_offset),
|
|
sdcard_readw(base, SD_HOST_CTRL_offset));
|
|
uart_printf(": Host control2: 0x%08x", sdcard_readw(base,0x3e));
|
|
uart_printf(": Power: 0x%08x | Blk gap: 0x%08x\r\n",
|
|
sdcard_readb(base, SDHCI_POWER_CONTROL),
|
|
sdcard_readw(base, SD_BGAP_CTRL_offset));
|
|
uart_printf(": Wake-up: 0x%08x | Clock: 0x%08x\r\n",
|
|
sdcard_readb(base, SDHCI_WAKE_UP_CONTROL),
|
|
sdcard_readw(base, SD_CLOCK_CTRL_offset));
|
|
uart_printf(": Timeout: 0x%08x | Int stat: 0x%08x\r\n",
|
|
sdcard_readb(base, SD_SW_RESET_CTRL_offset),
|
|
sdcard_readl(base, SD_NORM_INTR_STS_offset));
|
|
uart_printf(": Int enab: 0x%08x | Sig enab: 0x%08x\r\n",
|
|
sdcard_readl(base, SD_NORM_INTR_STS_EBLE_offset),
|
|
sdcard_readl(base, SD_NORM_INTR_STS_INTR_EBLE_offset));
|
|
uart_printf(": AC12 err: 0x%08x | Slot int: 0x%08x\r\n",
|
|
sdcard_readw(base, SDHCI_ACMD12_ERR),
|
|
sdcard_readw(base, SDHCI_SLOT_INT_STATUS));
|
|
uart_printf(": Caps: 0x%08x | Max curr: 0x%08x\r\n",
|
|
sdcard_readl(base, SDHCI_CAPABILITIES),
|
|
sdcard_readl(base, SDHCI_MAX_CURRENT));
|
|
uart_printf(": Command: 0x%08x\r\n",
|
|
sdcard_readw(base, SD_CMD_offset));
|
|
#ifndef PLAT_CRANE
|
|
uart_printf(": Fifo_prm: 0x%08x | Burst set: 0x%08x\r\n",
|
|
sdcard_readw(base, SD_FIFO_PARA_offset),
|
|
sdcard_readw(base, SD_CLOCK_AND_BURST_SIZE_SETUP_offset));
|
|
#endif
|
|
// uart_printf("SPI mode:0x%x\n",sdcard_readw(base, 0xe4));
|
|
uart_printf(": ===========================================\r\n");
|
|
|
|
if(eeGetSystemAssertFlag())
|
|
{
|
|
isr_sts = sdcard_readw(base, SD_NORM_INTR_STS_offset);
|
|
if(isr_sts & ERR_INT )
|
|
{
|
|
/*FSInit_Status_Init();*/
|
|
sdcard_initialized = SDCARD_INIT_UNDO;
|
|
uart_printf("Force fs/SD to be uninitialized!");
|
|
sdcard_writel(SDCARD_CTRL_BASE_ADDR, SD_NORM_INTR_STS_EBLE_offset, 0x0);
|
|
sdcard_writel(SDCARD_CTRL_BASE_ADDR, SD_NORM_INTR_STS_INTR_EBLE_offset, 0x0);
|
|
}
|
|
}
|
|
}
|
|
|
|
#define SD_INSERT_CARD_FLAG_BIT 0x1
|
|
#define SD_REMOVE_CARD_FLAG_BIT 0x2
|
|
|
|
#define SD_RESET_CMD_FLAG_BIT 0x1
|
|
|
|
#ifdef FAT32_FILE_SYSTEM
|
|
FATFS fatfs_fs[2];
|
|
#endif
|
|
void sdcard_reinit(void)
|
|
{
|
|
UINT32 base_addr = SD1_HOST_CTRL_ADDR;
|
|
UINT32 ret;
|
|
sdcard_reinitialized = SDCARD_INIT_UNDO;
|
|
UINT16 value;
|
|
|
|
if(sdcard_initialized == SDCARD_INIT_UNDO)
|
|
{
|
|
uart_printf("SD device haven't init before\n");
|
|
return;
|
|
}
|
|
|
|
PMIC_Set_SDIO_2_8V();
|
|
|
|
sdcard_initialized = SDCARD_INIT_UNDO;
|
|
uart_printf("Insert Card, re-init command\n");
|
|
sdcard_set_power();
|
|
|
|
SdCard_Enable_Clock(base_addr, 0x300);
|
|
SdCard_MsWait(50);
|
|
|
|
sdcard_set_mode(CARD_MODE_INT);
|
|
|
|
/*
|
|
//set buswidth as 1 bit
|
|
value = sdcard_readw(base_addr, SD_HOST_CTRL_offset);
|
|
uart_printf("original host control:0x%x\n",value);
|
|
value = value & 0xfffd ;
|
|
uart_printf("modified host control:0x%x\n",value);
|
|
sdcard_writew(base_addr, SD_HOST_CTRL_offset, value);
|
|
SdCard_MsWait(100);
|
|
*/
|
|
SdCard_SW_Reset(base_addr);
|
|
sd_dumpregs(base_addr);
|
|
|
|
CMD8_timout_cnt = 0;
|
|
|
|
ret = sdcard_cmd_init();
|
|
|
|
if(ret)
|
|
goto RE_INIT_ERR;
|
|
|
|
SdCard_Enable_Clock(base_addr, 0x2);
|
|
sdcard_writeb(base_addr, SD_SW_RESET_CTRL_offset, 0x0E);
|
|
|
|
//0 for 1bit and 1 for 4bit bus width
|
|
ret = sdcard_set_width(1);
|
|
if(ret)
|
|
goto RE_INIT_ERR;
|
|
|
|
UINT32 TX_CFG;
|
|
//keep the hold time for default speed mode
|
|
TX_CFG = sdcard_readl(base_addr, 0x118);
|
|
uart_printf("1 TX_CFG:0x%x",TX_CFG);
|
|
TX_CFG = TX_CFG | 0x40000000;
|
|
sdcard_writel(base_addr, 0x118, TX_CFG);
|
|
uart_printf("2 TX_CFG:0x%x",sdcard_readl(base_addr, 0x118));
|
|
|
|
uart_printf("==sdcard re-init OK==\r\n");
|
|
|
|
sdcard_initialized = SDCARD_INIT_SUCCESS;
|
|
sdcard_reinitialized = SDCARD_INIT_SUCCESS;
|
|
card_status = CARD_STATUS_INSERT;
|
|
|
|
#ifdef FAT32_FILE_SYSTEM
|
|
SD_Infinite_Err_Flag = 0;
|
|
////////Fat32_Init();
|
|
FRESULT res = f_mount(&fatfs_fs[0], DUMP_VOL, 1);
|
|
extern int sdcard_fatfs_mount_status_g;
|
|
if (res == FR_OK) {
|
|
sdcard_fatfs_mount_status_g = 1;
|
|
fatal_printf("SDCARD is mounted sucessfully\n");
|
|
}
|
|
#endif
|
|
return;
|
|
|
|
RE_INIT_ERR:
|
|
uart_printf("==sdcard re-init failed==\r\n");
|
|
sdcard_initialized = SDCARD_INIT_FAILED;
|
|
sdcard_reinitialized = SDCARD_INIT_FAILED;
|
|
return;
|
|
}
|
|
|
|
#if 0
|
|
void SD_ResetCMD_Task()
|
|
{
|
|
OSA_STATUS status;
|
|
UINT32 flag_value,cmd_value;
|
|
UINT32 flag_mask = SD_RESET_CMD_FLAG_BIT;
|
|
SD_Decrease_Clk_Flag = 0;
|
|
while(1)
|
|
{
|
|
//wait for flag
|
|
uart_printf("SD_ResetCMD_Task wait\n");
|
|
status = OSAFlagWait(SD_CMDReset_FlgRef, flag_mask,OSA_FLAG_OR_CLEAR,&flag_value,OSA_SUSPEND);
|
|
ASSERT(status == OS_SUCCESS);
|
|
if(flag_value & SD_RESET_CMD_FLAG_BIT)
|
|
{
|
|
cmd_value = sdcard_readl(SD1_HOST_CTRL_ADDR, SD_TRANSFER_MODE_offset);
|
|
//just for command8
|
|
uart_printf("cmd_value:0x%x, err_status:0x%x\n",cmd_value,SD_ERR_INTSTATUS);
|
|
|
|
if(sdcard_initialized != SDCARD_INIT_SUCCESS)
|
|
CMD8_timout_cnt++;
|
|
else
|
|
SD_Infinite_Err_Flag = 1;
|
|
|
|
if(CMD8_timout_cnt >= 3)
|
|
{
|
|
CMD8_timout_cnt = 0;
|
|
SD_Infinite_Err_Flag = 1;
|
|
}
|
|
else if(SD_Infinite_Err_Flag == 1)
|
|
{
|
|
if(SD_Decrease_Clk_Flag == 0)
|
|
{
|
|
SD_Decrease_Clk_Flag = 1;
|
|
|
|
uart_printf("decrease clk here");
|
|
|
|
SdCard_Enable_Clock(SD1_HOST_CTRL_ADDR, 3);
|
|
SdCard_SW_Reset(SD1_HOST_CTRL_ADDR);
|
|
SD_Infinite_Err_Flag = 0;
|
|
}else
|
|
{
|
|
//sd_dumpregs(SD1_HOST_CTRL_ADDR);
|
|
SdCard_SW_Reset(SD1_HOST_CTRL_ADDR);
|
|
//send command again
|
|
sdcard_writel(SD1_HOST_CTRL_ADDR, SD_TRANSFER_MODE_offset, cmd_value);
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
void SD_CARD_Insert_Remove_Task()
|
|
{
|
|
OSA_STATUS status;
|
|
UINT32 flag_value,cmd_value;
|
|
UINT32 flag_mask = SD_INSERT_CARD_FLAG_BIT | SD_REMOVE_CARD_FLAG_BIT;
|
|
|
|
while(1)
|
|
{
|
|
//wait for flag
|
|
uart_printf("SD_InsertRemove_Task wait\n");
|
|
status = OSAFlagWait(SDFlgRef, flag_mask,OSA_FLAG_OR_CLEAR,&flag_value,OSA_SUSPEND);
|
|
ASSERT(status == OS_SUCCESS);
|
|
|
|
if(flag_value & SD_INSERT_CARD_FLAG_BIT)
|
|
{
|
|
sdcard_reinit();
|
|
|
|
if(sdcard_initialized == SDCARD_INIT_SUCCESS)
|
|
{
|
|
uart_printf("handle insert here!\n");
|
|
card_status = CARD_STATUS_INSERT;
|
|
/*USB2MgrDeviceUnplugPlug_SD();*/ //yazhouren@asrmicro.com
|
|
}
|
|
}
|
|
|
|
if(flag_value & SD_REMOVE_CARD_FLAG_BIT)
|
|
{
|
|
uart_printf("handle remove here!\n");
|
|
card_status = CARD_STATUS_REMOVE;
|
|
/*USB2MgrDeviceUnplugPlug_SD();*/ //yazhouren@asrmicro.com
|
|
}
|
|
}
|
|
}
|
|
|
|
static void sdcard_cmderr_hisr(void)
|
|
{
|
|
//set flag
|
|
OS_STATUS os_status;
|
|
uart_printf("cmderr_hisr\n");
|
|
os_status = OSAFlagSet (SD_CMDReset_FlgRef, SD_RESET_CMD_FLAG_BIT, OSA_FLAG_OR);
|
|
ASSERT(os_status==OS_SUCCESS);
|
|
}
|
|
|
|
static void sdcard_insert_hisr(void)
|
|
{
|
|
//set flag
|
|
OS_STATUS os_status;
|
|
//uart_printf("sdcard_insert_hisr\n");
|
|
os_status = OSAFlagSet (SDFlgRef, SD_INSERT_CARD_FLAG_BIT, OSA_FLAG_OR);
|
|
ASSERT(os_status==OS_SUCCESS);
|
|
}
|
|
|
|
static void sdcard_remove_hisr(void)
|
|
{
|
|
//set flag
|
|
OS_STATUS os_status;
|
|
//uart_printf("sdcard_insert_hisr\n");
|
|
os_status = OSAFlagSet (SDFlgRef, SD_REMOVE_CARD_FLAG_BIT, OSA_FLAG_OR);
|
|
ASSERT(os_status==OS_SUCCESS);
|
|
}
|
|
|
|
static void sdcard_DATA_hisr(void)
|
|
{
|
|
OSA_STATUS status;
|
|
UINT32 count;
|
|
OSASemaphorePoll(SDDATARef, &count);
|
|
|
|
if(count == 0)
|
|
OSASemaphoreRelease_sdcard(SDDATARef);
|
|
// status = OSASemaphoreRelease_sdcard(SDDATARef);
|
|
// ASSERT(status == OS_SUCCESS);
|
|
}
|
|
|
|
static void sdcard_task_init()
|
|
{
|
|
OS_STATUS status;
|
|
status = OSASemaphoreCreate (&SDSysRef, 1, OSA_FIFO);
|
|
ASSERT(status == OS_SUCCESS);
|
|
|
|
// status = OSASemaphoreCreate(&SDCMDRef, 0, OSA_FIFO);
|
|
// ASSERT(status == OS_SUCCESS);
|
|
|
|
status = OSASemaphoreCreate(&SDDATARef, 0, OSA_FIFO);
|
|
ASSERT(status == OS_SUCCESS);
|
|
|
|
status = OSAFlagCreate(&SDFlgRef);
|
|
ASSERT(status == OS_SUCCESS);
|
|
|
|
status = OSAFlagCreate(&SD_CMDReset_FlgRef);
|
|
|
|
//create task for reset command when command timeout happens
|
|
status = OSATaskCreate(&SDTaskRef, SDStack, 2048, 42, "SD_Reset_TASK", SD_ResetCMD_Task, NULL);
|
|
ASSERT(status == OS_SUCCESS);
|
|
|
|
//create task to handle card insert and remove interrupt
|
|
status = OSATaskCreate(&SDCard_InsertRemove_TaskRef, SDCard_InsertRemove_Stack, 2048, 90, "SD_Card_TASK", SD_CARD_Insert_Remove_Task, NULL);
|
|
ASSERT(status == OS_SUCCESS);
|
|
|
|
//create HISR
|
|
OS_Create_HISR(&SdcardHISR, "sdcardhisr", sdcard_cmderr_hisr, HISR_PRIORITY_2);
|
|
|
|
OS_Create_HISR(&SdcardInsertHISR, "sdcardinserthisr", sdcard_insert_hisr,HISR_PRIORITY_2);
|
|
OS_Create_HISR(&SdcardRemoveHISR, "sdcardremovehisr", sdcard_remove_hisr,HISR_PRIORITY_2);
|
|
|
|
// OS_Create_HISR(&SdCMDHISR, "sdcardcmdhisr", sdcard_CMD_hisr,HISR_PRIORITY_2);
|
|
OS_Create_HISR(&SDDATAHISR, "sdcarddatahisr", sdcard_DATA_hisr,HISR_PRIORITY_2);
|
|
}
|
|
#endif
|
|
/**
|
|
* @brief: This function handle LISR.
|
|
*
|
|
*/
|
|
//just for lisr interval debug
|
|
#if SDCARD_LISR_DBG
|
|
static int lisr_start[0x40] = {0};
|
|
static int lisr_end[0x40] = {0};
|
|
static int lisr_loop = 0;
|
|
#endif
|
|
void dump_sd_lisr()
|
|
{
|
|
#if SDCARD_LISR_DBG
|
|
int loop;
|
|
for(loop = 0; loop < 0x40; loop++)
|
|
{
|
|
uart_printf("loop:0x%x,start:0x%x,interval:0x%x\n",loop,lisr_start[loop],(lisr_end[loop] - lisr_start[loop]));
|
|
}
|
|
#endif
|
|
}
|
|
|
|
//extern unsigned long sd_dbg_tick;
|
|
#if 0
|
|
static void sdcard_isr(INTC_InterruptInfo sourceInfo)
|
|
{
|
|
UINT16 isr_sts = 0;
|
|
UINT16 err_sts = 0;
|
|
int cardint = 0,status;
|
|
|
|
#if SDCARD_LISR_DBG
|
|
lisr_start[lisr_loop] = rti_get_current_tick();
|
|
#endif
|
|
if (SDCARD_CTRL_BASE_ADDR == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
isr_sts = sdcard_readw(SDCARD_CTRL_BASE_ADDR, SD_NORM_INTR_STS_offset);
|
|
if (isr_sts == 0 || isr_sts == 0xFFFF)
|
|
{
|
|
#if SDCARD_LISR_DBG
|
|
uart_printf("Err isr sts:%x\r\n", isr_sts);
|
|
#endif
|
|
return;
|
|
}
|
|
|
|
sdcard_writew(SDCARD_CTRL_BASE_ADDR, SD_NORM_INTR_STS_offset, isr_sts);
|
|
|
|
if (isr_sts & CARD_INS)
|
|
{
|
|
uart_printf("CARD Insert interrupt: %x\r\n", isr_sts);
|
|
OS_Activate_HISR(&SdcardInsertHISR);
|
|
|
|
}
|
|
|
|
if(isr_sts & CARD_REM)
|
|
{
|
|
uart_printf("CARD Remove interrupt: %x\r\n", isr_sts);
|
|
OS_Activate_HISR(&SdcardRemoveHISR);
|
|
}
|
|
|
|
if (isr_sts & (CMD_COMP))
|
|
{
|
|
SD_CMD_COMP_status = 1;
|
|
}
|
|
|
|
if (isr_sts & (XFER_COMP))
|
|
{
|
|
SD_DATA_COMP_status = 1;
|
|
//uart_printf("DATA");
|
|
if(SD_DATA_START_status == 1)
|
|
{
|
|
OS_Activate_HISR(&SDDATAHISR);
|
|
SD_DATA_START_status = 0;
|
|
}
|
|
}
|
|
|
|
if(isr_sts & (RX_RDY))
|
|
{
|
|
uart_printf("Buffer ready,isr_sts:0x%x",isr_sts);
|
|
SD_CMD_BufferReady = 1;
|
|
}
|
|
|
|
if (isr_sts & CARD_INT)
|
|
{
|
|
cardint = 1;
|
|
uart_printf("Card interrupt\n");
|
|
/* For debug*/
|
|
sd_card_int(0);
|
|
}
|
|
|
|
if (isr_sts & DMA_INT)
|
|
{
|
|
sdcard_writel(SDCARD_CTRL_BASE_ADDR, SD_SYSADDR_LOW_offset,sdcard_readl(SDCARD_CTRL_BASE_ADDR,SD_SYSADDR_LOW_offset));
|
|
//uart_printf("DMA interrupt\n");
|
|
}
|
|
|
|
if (isr_sts & ERR_INT )
|
|
{
|
|
err_sts = sdcard_readw(SDCARD_CTRL_BASE_ADDR, SD_ERR_INTR_STS_offset);
|
|
sdcard_writew(SDCARD_CTRL_BASE_ADDR, SD_ERR_INTR_STS_offset, err_sts);
|
|
SD_ERR_INTSTATUS = err_sts;
|
|
#if 0
|
|
if(FSInit_Status_Get() != 1)
|
|
uart_printf("isr_sts:0x%x,err_sts:0x%x",isr_sts,err_sts);
|
|
#endif
|
|
if (err_sts & (CMD_TO_ERR | CMD_IDX_ERR | CMD_END_BIT_ERR | CMD_CRC_ERR))
|
|
{
|
|
if (err_sts & CMD_TO_ERR)
|
|
{
|
|
/*if(FSInit_Status_Get() != 1)
|
|
uart_printf("Command timeout error");*/
|
|
status = OS_Activate_HISR(&SdcardHISR);
|
|
}
|
|
if (err_sts & CMD_IDX_ERR)
|
|
{
|
|
SD_Infinite_Err_Flag++;
|
|
//uart_printf("Command index error!\r\n");
|
|
}
|
|
if (err_sts & CMD_END_BIT_ERR)
|
|
{
|
|
SD_Infinite_Err_Flag++;
|
|
//uart_printf("Command end bit error!\r\n");
|
|
}
|
|
if (err_sts & CMD_CRC_ERR)
|
|
{
|
|
SD_Infinite_Err_Flag++;
|
|
//uart_printf("Command CRC error!\r\n");
|
|
}
|
|
}else{
|
|
SD_Infinite_Err_Flag++;
|
|
}
|
|
|
|
if((SD_Infinite_Err_Flag == 1) && (sdcard_initialized == SDCARD_INIT_SUCCESS))
|
|
{
|
|
if(SD_Decrease_Clk_Flag == 0)
|
|
status = OS_Activate_HISR(&SdcardHISR);
|
|
else
|
|
{
|
|
/*if(FSInit_Status_Get() != 1)
|
|
uart_printf("disable interrupt here!");*/
|
|
|
|
OS_Activate_HISR(&SDDATAHISR);
|
|
sdcard_writel(SDCARD_CTRL_BASE_ADDR, SD_NORM_INTR_STS_EBLE_offset, 0x0);
|
|
sdcard_writel(SDCARD_CTRL_BASE_ADDR, SD_NORM_INTR_STS_INTR_EBLE_offset, 0x0);
|
|
}
|
|
}
|
|
}
|
|
|
|
#if SDCARD_DEBUG
|
|
uart_printf("leave sdcard_isr\r\n");
|
|
#endif
|
|
|
|
#if SDCARD_LISR_DBG
|
|
lisr_end[lisr_loop] = rti_get_current_tick();
|
|
lisr_loop++;
|
|
|
|
if(lisr_loop == 0x40)
|
|
lisr_loop = 0;
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
UINT32 sdcard_read_multiblks(UINT32 base, UINT32 buffer, UINT32 loop, UINT32 blk_cnt);
|
|
UINT32 sdcard_write_multiblks(UINT32 base, UINT32 buffer, UINT32 loop, UINT32 blk_cnt);
|
|
UINT32 sdcard_read_singleblk(UINT32 base, UINT32 buffer, UINT32 loop);
|
|
UINT32 sdcard_write_singleblk(UINT32 base, UINT32 buffer, UINT32 loop);
|
|
|
|
|
|
|
|
#define TEST_SIZE 0x2000 //0x400000 //512*1024*8
|
|
|
|
//0 for un-init, 1 for init success, 2 for init failed
|
|
//0 for un-init, 1 for standard, 2 for high capacity
|
|
UINT32 sdcard_get_status(void)
|
|
{
|
|
if(sdcard_initialized == SDCARD_INIT_SUCCESS)
|
|
return 1;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
UINT32 sdcard_get_blknum(void)
|
|
{
|
|
return SD_BLK_NUM;
|
|
}
|
|
|
|
UINT32 sdcard_get_mode(void)
|
|
{
|
|
return card_mode;
|
|
}
|
|
|
|
UINT32 sdcard_set_mode(UINT32 mode)
|
|
{
|
|
card_mode = mode;
|
|
}
|
|
|
|
BOOL sdcard_transmit_status(void)
|
|
{
|
|
if(SD_Trans_Status == 1)
|
|
{
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
static void SdCard_Check_TransStatus(UINT32 base);
|
|
|
|
int eeSDDump_status_get(void)
|
|
{
|
|
return ee_sd_dump_status_g;
|
|
}
|
|
|
|
UINT32 sdcard_ee_dump_folder_index = 0;
|
|
#if 0
|
|
void eeSDDumpMakeDir(void)
|
|
{
|
|
FAT32FILEINFO fileinfo_ptr;
|
|
unsigned int handle;
|
|
int ret = 0;
|
|
UINT32 m_ind;
|
|
char str[128] = "\0";
|
|
static int flag = 0;
|
|
|
|
if (flag != 0)
|
|
return;
|
|
flag = 1;
|
|
|
|
sprintf(str, "%s\\%s*",DUMP_VOL ,DUMP_DIR_PRENAME);
|
|
handle = FAT_findfirst(str, &fileinfo_ptr);
|
|
|
|
if (handle != 0) {
|
|
sdcard_ee_dump_folder_index = m_atoi_dec((char *)fileinfo_ptr.info.m_lpszFullName + m_strlen(DUMP_DIR_PRENAME));
|
|
if(sdcard_ee_dump_folder_index == 0xFFFFFFFF)
|
|
sdcard_ee_dump_folder_index =0;
|
|
while(!ret){
|
|
ret = FAT_findnext(handle, &fileinfo_ptr);
|
|
if (ret == 0) {
|
|
m_ind = m_atoi_dec((char *)fileinfo_ptr.info.m_lpszFullName + m_strlen(DUMP_DIR_PRENAME));
|
|
if(m_ind == 0xFFFFFFFF) continue;
|
|
sdcard_ee_dump_folder_index = MAX(m_ind,sdcard_ee_dump_folder_index);
|
|
}
|
|
}
|
|
FAT_findfileclose(handle);
|
|
}else{
|
|
// TODO: tmp workaround to make an Empty dir here , or findfirst would failed, have to fix further
|
|
//sprintf(str, "%s\\%sN",DUMP_VOL ,DUMP_DIR_PRENAME);
|
|
//FAT_MakeDir(str, NULL);
|
|
}
|
|
|
|
//mkdir
|
|
sprintf(str, "%s\\%s%d",DUMP_VOL ,DUMP_DIR_PRENAME,++sdcard_ee_dump_folder_index);
|
|
FAT_MakeDir(str, NULL);
|
|
uart_printf("eeSDDumpMakeDir end\r\n");
|
|
}
|
|
#endif
|
|
void eeSDDumpPrepare(void)
|
|
{
|
|
#ifdef FAT32_FILE_SYSTEM
|
|
UINT32 isr_sts;
|
|
UINT32 base = SD1_HOST_CTRL_ADDR;
|
|
UINT32 timeout = 40000;
|
|
ee_sd_dump_status_g = 1;
|
|
uart_printf("EE LOG: %s Enter\n", __func__);
|
|
if (sdcard_is_ready())
|
|
{
|
|
//set sd card as polling mode
|
|
sdcard_set_mode(1);
|
|
//set sd card with lower clock
|
|
SdCard_Enable_Clock(base, 3);
|
|
//Enable SD card interrupt
|
|
SdCard_IRQ_Enable(base, 0xF1FF);
|
|
//enable error interrupt
|
|
sdcard_writew(base, SD_ERR_INTR_STS_EBLE_offset, 0x3ff);
|
|
sdcard_writew(base, (SD_ERR_INTR_STS_EBLE_offset + 0x4), 0x3ff);
|
|
|
|
if((SD_Read_status == 1)||(SD_Write_status != 0))
|
|
{
|
|
uart_printf("SD transfer hasn't completed,%d,%d!!!\n",SD_Read_status,SD_Write_status);
|
|
if(SD_Write_status != 1)
|
|
SD_Trans_Status = 1;
|
|
|
|
//wait for data transfer end interrupt
|
|
if(SD_Write_status != 2)
|
|
{
|
|
isr_sts = sdcard_readw(base, SD_NORM_INTR_STS_offset);
|
|
while ( !(isr_sts & XFER_COMP))
|
|
{
|
|
if(isr_sts & DMA_INT)
|
|
{
|
|
sdcard_writew(base, SD_NORM_INTR_STS_offset, DMA_INT);
|
|
sdcard_writel(base, SD_SYSADDR_LOW_offset,sdcard_readl(base,SD_SYSADDR_LOW_offset));
|
|
//uart_printf("DMA interrupt\n");
|
|
timeout = 40000;
|
|
}
|
|
SdCard_Wait(2000);
|
|
timeout--;
|
|
if (timeout == 0 )
|
|
{
|
|
if(isr_sts & ERR_INT )
|
|
{
|
|
isr_sts = sdcard_readw(base, SD_ERR_INTR_STS_offset);
|
|
sdcard_writew(base, SD_ERR_INTR_STS_offset, isr_sts);
|
|
uart_printf("err_sts:0x%x\n",isr_sts);
|
|
SdCard_SW_Reset(base);
|
|
timeout = 40000;
|
|
}else
|
|
{
|
|
uart_printf("POLL mode,Wait for data transfer time out!\n");
|
|
sd_dumpregs(base);
|
|
//modify by qgwang, 20131015
|
|
break;
|
|
}
|
|
}
|
|
isr_sts = sdcard_readw(base, SD_NORM_INTR_STS_offset);
|
|
}
|
|
//clear data complete interrupt
|
|
sdcard_writew(base, SD_NORM_INTR_STS_offset, XFER_COMP);
|
|
}
|
|
|
|
//wait for card states change
|
|
SdCard_Check_TransStatus(base);
|
|
}
|
|
/*
|
|
if(DumpFileToSDEnable())
|
|
{
|
|
if(FAT32_IsFormat() == 1)
|
|
{
|
|
sdcard_check_free_space(0x6400000, TRUE);
|
|
Create_CurDir();
|
|
}
|
|
else
|
|
{
|
|
uart_printf("Non-fat32 file system, don't create current dir!");
|
|
}
|
|
|
|
}
|
|
|
|
diag_comm_create_assert_sdl();
|
|
*/
|
|
|
|
}
|
|
else if(sdcard_is_insert())
|
|
{
|
|
uart_printf("Non-fat32 file system, don't save dump bin!\n");
|
|
}
|
|
|
|
uart_printf("EE LOG: %s Exit\n", __func__);
|
|
#endif
|
|
|
|
}
|
|
|
|
#if 1
|
|
void sdcard_test(UINT32 base)
|
|
{
|
|
UINT32 ret = 1;
|
|
UINT32 start, end;
|
|
int loop = 0;
|
|
unsigned char * buf_src;
|
|
unsigned char * buf_dest;
|
|
buf_src = (unsigned char *)malloc(TEST_SIZE);
|
|
buf_dest = (unsigned char *)malloc(TEST_SIZE);
|
|
int loop_big;
|
|
uart_printf("read/write check here");
|
|
|
|
for(loop_big = 0; loop_big < 0x40; loop_big++)
|
|
{
|
|
memset(buf_src, 0x55+loop_big, TEST_SIZE);
|
|
memset(buf_dest, 0x2, TEST_SIZE);
|
|
|
|
|
|
ret = sdcard_write_singleblk(base, buf_src, loop_big*16);
|
|
ASSERT(ret == 0);
|
|
|
|
// SdCard_MsWait(20);
|
|
|
|
ret = sdcard_read_singleblk(base, buf_dest, loop_big*16);
|
|
ASSERT(ret == 0);
|
|
|
|
ret = memcmp(buf_src, buf_dest, 512);
|
|
if(ret != 0)
|
|
{
|
|
uart_printf("r/w check error:0x%x,loop:%d\n",ret,loop_big);
|
|
return ret;
|
|
}
|
|
|
|
//uart_printf("loop %d, r/w check right!\n",loop_big);
|
|
}
|
|
uart_printf("read/write check here passed!");
|
|
|
|
//return;
|
|
|
|
for(loop_big = 0; loop_big < 0x10; loop_big ++)
|
|
{
|
|
start = (UINT32)buf_src;
|
|
for(loop = 0; loop < 8; loop ++)
|
|
{
|
|
memset((void *)start,((loop+loop_big+10)&0xff),512);
|
|
start = start + 512;
|
|
}
|
|
// memset(buf_src, 0xa5, TEST_SIZE);
|
|
memset(buf_dest, 0x0, TEST_SIZE);
|
|
//uart_printf("src:0x%x,dest:0x%x\n",buf_src,buf_dest);
|
|
|
|
|
|
for(loop = 0; loop < 0x2000; )
|
|
{
|
|
ret = sdcard_write_multiblks(base,(buf_src + loop*512),(loop+0x2000*loop_big),16);
|
|
if(ret)
|
|
return ret;
|
|
loop = loop + 16;
|
|
}
|
|
|
|
for(loop = 0; loop < 0x2000; )
|
|
{
|
|
ret = sdcard_read_multiblks(base,(buf_dest + loop*512),(loop+0x2000*loop_big),16);
|
|
if(ret)
|
|
return ret;
|
|
loop = loop + 16;
|
|
}
|
|
ret = memcmp(buf_src, buf_dest, TEST_SIZE);
|
|
if(ret != 0)
|
|
{
|
|
uart_printf("1 loop 0x%x r/w check error:0x%x\n",loop_big,ret);
|
|
return ret;
|
|
}
|
|
|
|
memset(buf_dest,0x0,512*8);
|
|
ret = sdcard_write_multiblks(base, buf_src, loop_big, 0x8);
|
|
if(ret)
|
|
return ret;
|
|
|
|
ret = sdcard_write_multiblks(base, buf_src, loop_big, 0x8);
|
|
if(ret)
|
|
return ret;
|
|
|
|
ret = sdcard_read_multiblks(base, buf_dest, loop_big, 0x8);
|
|
if(ret)
|
|
return ret;
|
|
|
|
ret = memcmp(buf_src, buf_dest, 512*8);
|
|
if(ret != 0)
|
|
{
|
|
uart_printf("2 loop 0x%x r/w check error:0x%x\n",loop_big,ret);
|
|
return ret;
|
|
}
|
|
|
|
uart_printf("loop 0x%x r/w check right!\n",loop_big);
|
|
}
|
|
|
|
return;
|
|
}
|
|
#endif
|
|
#if 0
|
|
static void sd_isr(INTC_InterruptInfo sourceInfo)
|
|
{
|
|
UINT16 slot_int;
|
|
slot_int = sdcard_readw(SD1_HOST_CTRL_ADDR, SDHCI_SLOT_INT_STATUS);
|
|
|
|
#ifdef PLAT_CRANE
|
|
if((slot_int & 0x1) == 1)
|
|
sdcard_isr(sourceInfo);
|
|
|
|
if((slot_int & 0x2) == 2) {
|
|
//sdio_isr(sourceInfo);
|
|
uart_printf("ERR----------ERR---------------ERR SDIO\n");
|
|
|
|
uart_printf("ERR----------ERR---------------ERR SDIO\n");
|
|
uart_printf("ERR----------ERR---------------ERR SDIO\n");
|
|
uart_printf("ERR----------ERR---------------ERR SDIO\n");
|
|
}
|
|
#else
|
|
if((slot_int & 0x3) == 1)
|
|
sdcard_isr(sourceInfo);
|
|
else if((slot_int & 0x3) == 0)
|
|
sdio_isr(sourceInfo);
|
|
#endif
|
|
}
|
|
#endif
|
|
static void SdCard_Switch_Function(UINT32 base_addr)
|
|
{
|
|
UINT32 status;
|
|
//send CMD6, check function
|
|
UINT16 cmd = 0x63a;
|
|
UINT32 argv = 0xffff;
|
|
UINT8 data_block[64],count;
|
|
uart_printf("Send CMD6");
|
|
|
|
memset(data_block, 0, 64);
|
|
status = SdCard_Read_NoDMA(cmd, argv, 64, 1, data_block);
|
|
|
|
if (status != MMC_ERR_NONE)
|
|
{
|
|
uart_printf("Error Invoke CMD6\r\n");
|
|
} else {
|
|
uart_printf("CMD6 Done!\r\n");
|
|
}
|
|
|
|
for(count = 0; count < 64; )
|
|
{
|
|
uart_printf("data:0x%x,0x%x,0x%x,0x%x",data_block[count],data_block[count+1],data_block[count+2],data_block[count+3]);
|
|
count = count + 4;
|
|
}
|
|
//send CMD6, switch function
|
|
|
|
cmd = 0x63a;
|
|
argv = 0x80000003;
|
|
|
|
status = SdCard_Cmd_Nodata(cmd, argv, base_addr);
|
|
|
|
if (status != MMC_ERR_NONE)
|
|
{
|
|
uart_printf("Error Invoke CMD6\r\n");
|
|
} else {
|
|
uart_printf("CMD6 Done!\r\n");
|
|
//modify Host control 2, SDR25 mode
|
|
cmd = sdcard_readw(base_addr, 0x3E);
|
|
uart_printf("before set SDR mode, host control2:0x%x",cmd);
|
|
cmd = cmd | 0x3;
|
|
sdcard_writew(base_addr, 0x3E, cmd);
|
|
uart_printf("SDR104, host control2:0x%x",cmd);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief: This function tunes the RX windows with the given clock.
|
|
* @return the delay value
|
|
*/
|
|
static void SdCard_Tune_Clock(UINT32 base_addr)
|
|
{
|
|
UINT8 delay, match;
|
|
UINT16 count;
|
|
UINT32 rx_cfg;
|
|
UINT8 data_block[64];
|
|
match = 1;
|
|
|
|
memset(data_block, 0, 64);
|
|
|
|
rx_cfg = sdcard_readl(base_addr, 0x114);
|
|
uart_printf("The default rx_cfg value:0x%x",rx_cfg);
|
|
// count = sdcard_readw(base_addr, 0x3E);
|
|
// uart_printf("before tune, host control2:0x%x",count);
|
|
// count = count | 0x40;
|
|
// sdcard_writew(base_addr, 0x3E, count);
|
|
// uart_printf("Enable execute tune, host control2:0x%x",count);
|
|
SdCard_MsWait(5);
|
|
|
|
for(delay = 0; match == 1; delay++)
|
|
{
|
|
rx_cfg = rx_cfg & 0xffff0000;
|
|
rx_cfg = rx_cfg | (delay<<8) | 0x6;
|
|
uart_printf("The rx_cfg value:0x%x",rx_cfg);
|
|
sdcard_writel(base_addr, 0x114, rx_cfg);
|
|
|
|
SdCard_Read_NoDMA(0x133a, 0, 64, 1, data_block);
|
|
|
|
if(memcmp(data_block, sd_tuning_pattern, 64) != 0)
|
|
{
|
|
match = 0;
|
|
for(count = 0; count < 64; )
|
|
{
|
|
uart_printf("data:0x%x,0x%x,0x%x,0x%x",data_block[count],data_block[count+1],data_block[count+2],data_block[count+3]);
|
|
count = count + 4;
|
|
}
|
|
}
|
|
uart_printf("match:0x%x",match);
|
|
}
|
|
SdCard_MsWait(5);
|
|
|
|
uart_printf("The max delay value:0x%x",delay);
|
|
delay = delay>>2;
|
|
//set the delay value
|
|
rx_cfg = sdcard_readl(base_addr, 0x114);
|
|
rx_cfg = rx_cfg & 0xffff0000;
|
|
rx_cfg = rx_cfg | (delay<<8) | 0x6;
|
|
sdcard_writel(base_addr, 0x114, rx_cfg);
|
|
}
|
|
|
|
/* One GPIO pin is applied to enable external LDO for SDCARD power supply on EVB with PM802. */
|
|
#define GPIO_SDCARD_PWR 75
|
|
|
|
void sdcard_poweron(void)
|
|
{
|
|
if (PMIC_IS_PM812())
|
|
{
|
|
PM812_Ldo_12_set_2_8();
|
|
PM812_Ldo_12_set(TRUE);//SDIO
|
|
PM812_Ldo_13_set_2_8();
|
|
PM812_Ldo_13_set(TRUE);//SDCARD
|
|
}
|
|
else if(PMIC_IS_PM813())
|
|
{
|
|
Ningbo_Ldo_9_set_2_8();
|
|
Ningbo_Ldo_9_set(TRUE);//SDIO
|
|
Ningbo_Ldo_4_set_2_8();
|
|
Ningbo_Ldo_4_set(TRUE);//SDCARD
|
|
}
|
|
#if 0
|
|
else //802
|
|
{
|
|
Guilin_Ldo_6_set_2_8();
|
|
Guilin_Ldo_6_set(TRUE);//SDIO
|
|
|
|
GpioSetDirection(GPIO_SDCARD_PWR, GPIO_OUT_PIN);
|
|
GpioSetLevel(GPIO_SDCARD_PWR, 1); //enable SDCARD power.
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void sdcard_poweroff(void)
|
|
{
|
|
//INTCDisable(INTC_SRC_MMC);
|
|
if (PMIC_IS_PM812())
|
|
{
|
|
PM812_Ldo_12_set(FALSE);//SDIO
|
|
PM812_Ldo_13_set(FALSE);//SDCARD
|
|
}
|
|
else if(PMIC_IS_PM813())
|
|
{
|
|
Ningbo_Ldo_9_set(FALSE);//SDIO
|
|
Ningbo_Ldo_4_set(FALSE);//SDCARD
|
|
}
|
|
#if 0
|
|
else //802
|
|
{
|
|
Guilin_Ldo_6_set(FALSE);//SDIO
|
|
GpioSetLevel(GPIO_SDCARD_PWR, 0); //disable SDCARD power.
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
* @brief: This function initialize SDIO bus driver.
|
|
*
|
|
* @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
|
|
*/
|
|
int sdcard_init(void)
|
|
{
|
|
UINT32 base_addr = SD1_HOST_CTRL_ADDR;
|
|
UINT16 int_sta;
|
|
int ret = 0;
|
|
int fnnum = 0;
|
|
|
|
if(!PlatformSDCardEnable())
|
|
{
|
|
return 0;
|
|
}
|
|
fatal_printf("===sd card init===\r\n");
|
|
//enable sd card vcc yazhouren@asrmicrom.com
|
|
AIB_MMC1_IO_Set_3_3V();
|
|
|
|
sdcard_poweron();
|
|
//return 0;
|
|
|
|
sdcard_initialized = SDCARD_INIT_UNDO;
|
|
SDCARD_CTRL_BASE_ADDR = base_addr;
|
|
|
|
//config i2c and sdio pinmux
|
|
sdcard_config_pin();
|
|
|
|
sdcard_clk_on();
|
|
|
|
SdCard_MsWait(10);
|
|
|
|
//config sdio power
|
|
sdcard_set_power();
|
|
//config sdio clock, modify by qigang
|
|
SdCard_Enable_Clock(base_addr, 0x300);
|
|
//SdCard_Enable_Clock(base_addr, 0);
|
|
|
|
//config burst size
|
|
sdcard_burstsize_config();
|
|
|
|
/*init sdio's irq Int status register*/
|
|
//enable all interrupt, modify by qigang
|
|
SdCard_IRQ_Enable(base_addr, 0xF1FF);
|
|
|
|
sdcard_writew(base_addr, SD_ERR_INTR_STS_EBLE_offset, 0x3ff);
|
|
sdcard_writew(base_addr, (SD_ERR_INTR_STS_EBLE_offset + 0x4), 0x3ff);
|
|
|
|
//sd_dumpregs(SD1_HOST_CTRL_ADDR);
|
|
#if 0
|
|
sdcard_task_init();
|
|
|
|
/*configure source of INT, and set ISR*/
|
|
INTCConfigure(INTC_SRC_MMC, INTC_IRQ, INTC_HIGH_LEVEL);
|
|
INTCBind(INTC_SRC_MMC, sd_isr);
|
|
/*INT source enable*/
|
|
INTCEnable(INTC_SRC_MMC);
|
|
|
|
sdcard_set_mode(CARD_MODE_INT);
|
|
#endif
|
|
sdcard_set_mode(CARD_MODE_POLL);
|
|
SdCard_MsWait(10);
|
|
|
|
SdCard_SW_Reset(base_addr);
|
|
|
|
fatal_printf("===sd card cmd init begin===\r\n");
|
|
//sd_dumpregs(SD1_HOST_CTRL_ADDR);
|
|
#ifdef SDCARD_INSERT_DEC
|
|
UINT16 card_insert = sdcard_readw(base_addr, 0x26);
|
|
if(!(card_insert & 0x5)) {
|
|
fatal_printf("sdcard don't insert:%d!\r\n", card_insert);
|
|
goto SD_Handle_Err;
|
|
}
|
|
#endif
|
|
ret = sdcard_cmd_init();
|
|
if(ret)
|
|
goto SD_Handle_Err;
|
|
|
|
//high speed, not completed yet
|
|
//clear interrupt status
|
|
int_sta = sdcard_readw(base_addr, SD_NORM_INTR_STS_offset);
|
|
if(int_sta)
|
|
{
|
|
uart_printf("before enable highspeed, interrupt status:0x%x\n",int_sta);
|
|
sdcard_writew(base_addr,SD_NORM_INTR_STS_offset,int_sta);
|
|
}
|
|
sdcard_writeb(SD1_HOST_CTRL_ADDR, SD_SW_RESET_CTRL_offset, 0x0E);
|
|
|
|
//0 for 1bit and 1 for 4bit bus width
|
|
ret = sdcard_set_width(1);
|
|
if(ret)
|
|
goto SD_Handle_Err;
|
|
|
|
if(hs_switch == 1)
|
|
{
|
|
// SdCard_MsWait(10);
|
|
SdCard_Switch_Function(base_addr);
|
|
}else
|
|
{
|
|
UINT32 TX_CFG;
|
|
//keep the hold time for default speed mode
|
|
TX_CFG = sdcard_readl(base_addr, 0x118);
|
|
uart_printf("1 TX_CFG:0x%x\n",TX_CFG);
|
|
TX_CFG = TX_CFG | 0x40000000;
|
|
sdcard_writel(base_addr, 0x118, TX_CFG);
|
|
uart_printf("2 TX_CFG:0x%x\n",sdcard_readl(base_addr, 0x118));
|
|
}
|
|
|
|
SdCard_Enable_Clock(base_addr, 0x3);
|
|
|
|
if(hs_switch == 1)
|
|
{
|
|
//SdCard_MsWait(10);
|
|
SdCard_Tune_Clock(base_addr);
|
|
SdCard_MsWait(10);
|
|
}
|
|
|
|
//modify host2 register to stop clock when no data transfer
|
|
int_sta = sdcard_readw(base_addr, 0x3E);
|
|
uart_printf("the default value of host2 is 0x%x\n",int_sta);
|
|
int_sta = int_sta | 0x4000;
|
|
sdcard_writew(base_addr, 0x3E, int_sta);
|
|
|
|
fatal_printf("==sdcard init OK==\r\n");
|
|
|
|
sdcard_initialized = SDCARD_INIT_SUCCESS;
|
|
card_status = CARD_STATUS_INSERT;
|
|
/* Init FAT32 system only when SD card is ready.*/
|
|
#ifdef FAT32_FILE_SYSTEM
|
|
SD_Infinite_Err_Flag = 0;
|
|
////////Fat32_Init();
|
|
eeSDDumpPrepare();
|
|
FRESULT res = f_mount(&fatfs_fs[0], DUMP_VOL, 1);
|
|
extern int sdcard_fatfs_mount_status_g;
|
|
if (res == FR_OK) {
|
|
sdcard_fatfs_mount_status_g = 1;
|
|
fatal_printf("SDCARD is mounted successfully\n");
|
|
}
|
|
else {
|
|
fatal_printf("SDCARD mount err:%d\n", res);
|
|
}
|
|
#endif
|
|
|
|
return ret;
|
|
|
|
SD_Handle_Err:
|
|
fatal_printf("sdcard init error!!!\n");
|
|
|
|
sdcard_poweroff();
|
|
|
|
//only disable SD CLK and LDO for Samsung platform
|
|
//if((PlatformGetProjectType() == NEZHA_SMIFI_V2) || (PlatformGetProjectType() == NEZHA_SMNAND_V2))
|
|
//{
|
|
// sdcard_clk_off(base_addr);
|
|
// PMIC_ShutDown_SdLDO();
|
|
//}
|
|
CMD8_timout_cnt = 0;
|
|
sdcard_initialized = SDCARD_INIT_FAILED;
|
|
|
|
return ret;
|
|
}
|
|
|
|
UINT32 sdcard_read_multiblks(UINT32 base, UINT32 buffer, UINT32 loop, UINT32 blk_cnt)
|
|
{
|
|
UINT32 timeout,mask;
|
|
OSA_STATUS status;
|
|
UINT16 isr_sts;
|
|
gSDRecordTime = /*OSAGetTicks()*/0;
|
|
|
|
#ifdef MV_USB2_MASS_STORAGE
|
|
mvUsbStorageNotifyUsbActive();
|
|
#endif
|
|
|
|
status = OSASemaphoreAcquire_sdcard(SDSysRef, OS_SUSPEND);
|
|
ASSERT(status == OS_SUCCESS);
|
|
SD_Read_status = 1;
|
|
|
|
SD_CMD_COMP_status = 0;
|
|
SD_DATA_COMP_status = 0;
|
|
SD_DATA_START_status = 1;
|
|
CacheInvalidateMemory(buffer, 0x200*blk_cnt);
|
|
//sdio_set_dmaaddr(base, dma_addr);
|
|
sdcard_writel(base, SD_SYSADDR_LOW_offset, buffer);
|
|
|
|
//sdio_set_blkarg(base, SDIO_CMD18_BLKARG);
|
|
sdcard_writel(base, SD_BLOCK_SIZE_offset, 0x7200 | (blk_cnt << 16));
|
|
|
|
timeout = 1000000;
|
|
mask = SDHCI_CMD_INHIBIT;
|
|
while((sdcard_readl(base, SD_PRESENT_STAT_0_offset))&mask)
|
|
{
|
|
if(timeout == 0)
|
|
{
|
|
uart_printf("Controller never released inhabit bit\r\n");
|
|
status = OSASemaphoreRelease_sdcard(SDSysRef);
|
|
ASSERT(status == OS_SUCCESS);
|
|
SD_Read_status = 0;
|
|
return MMC_ERR_CMD_TOUT;
|
|
}
|
|
timeout--;
|
|
}
|
|
//set card read offset
|
|
//sdio_set_argument(base, (loop * SDIO_TRANS_SIZE));
|
|
if(card_type == CARD_TYPE_HIGH)
|
|
sdcard_writel(base, SD_ARG_LOW_offset, loop);
|
|
else if(card_type == CARD_TYPE_STANDARD)
|
|
sdcard_writel(base, SD_ARG_LOW_offset, loop*0x200);
|
|
//sdcard_writel(base, SD_ARG_LOW_offset, loop);
|
|
//send command 18
|
|
sdcard_writel(base, SD_TRANSFER_MODE_offset, 0x123a0037);
|
|
|
|
|
|
/*wait for complete*/
|
|
timeout = 40000;
|
|
if(sdcard_get_mode() == CARD_MODE_INT)
|
|
{
|
|
while (!SD_CMD_COMP_status)
|
|
{
|
|
SdCard_Wait(2000);
|
|
timeout--;
|
|
if(timeout == 0 )
|
|
{
|
|
uart_printf("INT mode,Wait for command18 time out!\r\n");
|
|
uart_printf("INT mode,Wait for command18 time out!\r\n");
|
|
if(SD_Decrease_Clk_Flag == 0)
|
|
{
|
|
sd_dumpregs(base);
|
|
}
|
|
status = OSASemaphoreRelease_sdcard(SDSysRef);
|
|
ASSERT(status == OS_SUCCESS);
|
|
SD_Read_status = 0;
|
|
|
|
return MMC_ERR_CMD_TOUT;
|
|
}
|
|
|
|
if(SD_Infinite_Err_Flag == 1)
|
|
{
|
|
status = OSASemaphoreRelease_sdcard(SDSysRef);
|
|
ASSERT(status == OS_SUCCESS);
|
|
SD_Read_status = 0;
|
|
return MMC_ERR_CMD_TOUT;
|
|
}
|
|
|
|
}
|
|
|
|
}else if(sdcard_get_mode() == CARD_MODE_POLL)
|
|
{
|
|
isr_sts = sdcard_readw(SDCARD_CTRL_BASE_ADDR, SD_NORM_INTR_STS_offset);
|
|
while (!(isr_sts & CMD_COMP))
|
|
{
|
|
SdCard_Wait(2000);
|
|
timeout--;
|
|
if (timeout == 0 )
|
|
{
|
|
fatal_printf("POLL mode,Wait for command18 time out!\r\n");
|
|
uart_printf("blk num:0x%x",blk_cnt);
|
|
sd_dumpregs(base);
|
|
status = OSASemaphoreRelease_sdcard(SDSysRef);
|
|
ASSERT(status == OS_SUCCESS);
|
|
return MMC_ERR_CMD_TOUT;
|
|
}
|
|
isr_sts = sdcard_readw(SDCARD_CTRL_BASE_ADDR, SD_NORM_INTR_STS_offset);
|
|
}
|
|
|
|
//clear cmd complete interrupt
|
|
sdcard_writew(SDCARD_CTRL_BASE_ADDR, SD_NORM_INTR_STS_offset, CMD_COMP);
|
|
}
|
|
|
|
timeout = 40000;
|
|
|
|
if(sdcard_get_mode() == CARD_MODE_INT)
|
|
{
|
|
status = OSASemaphoreAcquire_sdcard(SDDATARef, OS_SUSPEND);
|
|
ASSERT(status == OS_SUCCESS);
|
|
if(SD_DATA_COMP_status != 1)
|
|
{
|
|
status = OSASemaphoreRelease_sdcard(SDSysRef);
|
|
ASSERT(status == OS_SUCCESS);
|
|
return MMC_ERR_DATA_TOUT;
|
|
}
|
|
/*
|
|
while (!SD_DATA_COMP_status)
|
|
{
|
|
SdCard_Wait(2000);
|
|
timeout--;
|
|
if (timeout == 0 )
|
|
{
|
|
uart_printf("INT mode,CMD18,Wait for data transfer time out!\r\n");
|
|
sd_dumpregs(base);
|
|
status = OSASemaphoreRelease_sdcard(SDSysRef);
|
|
ASSERT(status == OS_SUCCESS);
|
|
return MMC_ERR_DATA_TOUT;
|
|
}
|
|
}
|
|
*/
|
|
}else if(sdcard_get_mode() == CARD_MODE_POLL)
|
|
{
|
|
isr_sts = sdcard_readw(SDCARD_CTRL_BASE_ADDR, SD_NORM_INTR_STS_offset);
|
|
while ( !(isr_sts & XFER_COMP))
|
|
{
|
|
if(isr_sts & DMA_INT)
|
|
{
|
|
sdcard_writew(base, SD_NORM_INTR_STS_offset, DMA_INT);
|
|
sdcard_writel(base, SD_SYSADDR_LOW_offset,sdcard_readl(base,SD_SYSADDR_LOW_offset));
|
|
uart_printf("CMD18 DMA interrupt");
|
|
timeout = 40000;
|
|
}
|
|
SdCard_Wait(2000);
|
|
timeout--;
|
|
if (timeout == 0 )
|
|
{
|
|
uart_printf("POLL mode,CMD18, Wait for data transfer time out!\r\n");
|
|
sd_dumpregs(base);
|
|
status = OSASemaphoreRelease_sdcard(SDSysRef);
|
|
ASSERT(status == OS_SUCCESS);
|
|
return MMC_ERR_DATA_TOUT;
|
|
//timeout = 40000;
|
|
}
|
|
isr_sts = sdcard_readw(SDCARD_CTRL_BASE_ADDR, SD_NORM_INTR_STS_offset);
|
|
}
|
|
//clear data complete interrupt
|
|
sdcard_writew(SDCARD_CTRL_BASE_ADDR, SD_NORM_INTR_STS_offset, XFER_COMP);
|
|
}
|
|
|
|
SdCard_SW_Reset(base);
|
|
//SdCard_Wait(200000);
|
|
SD_Read_status = 0;
|
|
status = OSASemaphoreRelease_sdcard(SDSysRef);
|
|
ASSERT(status == OS_SUCCESS);
|
|
|
|
return 0;
|
|
}
|
|
|
|
UINT32 sdcard_read_singleblk(UINT32 base, UINT32 buffer, UINT32 loop)
|
|
{
|
|
UINT32 timeout,mask;
|
|
OSA_STATUS status;
|
|
UINT16 isr_sts;
|
|
gSDRecordTime = /*OSAGetTicks()*/0;
|
|
|
|
#ifdef MV_USB2_MASS_STORAGE
|
|
mvUsbStorageNotifyUsbActive();
|
|
#endif
|
|
status = OSASemaphoreAcquire_sdcard(SDSysRef, OS_SUSPEND);
|
|
ASSERT(status == OS_SUCCESS);
|
|
SD_Read_status = 1;
|
|
|
|
SD_CMD_COMP_status = 0;
|
|
SD_DATA_COMP_status = 0;
|
|
SD_DATA_START_status = 1;
|
|
CacheInvalidateMemory(buffer, 0x200);
|
|
//sdio_set_dmaaddr(base, dma_addr);
|
|
sdcard_writel(base, SD_SYSADDR_LOW_offset, buffer);
|
|
|
|
sdcard_writel(base, SD_BLOCK_SIZE_offset, 0x7200 | (1 << 16));
|
|
timeout = 1000000;
|
|
mask = SDHCI_CMD_INHIBIT;
|
|
while((sdcard_readl(base, SD_PRESENT_STAT_0_offset))&mask)
|
|
{
|
|
if(timeout == 0)
|
|
{
|
|
uart_printf("Controller never released inhabit bit\r\n");
|
|
status = OSASemaphoreRelease_sdcard(SDSysRef);
|
|
ASSERT(status == OS_SUCCESS);
|
|
SD_Read_status = 0;
|
|
return MMC_ERR_CMD_TOUT;
|
|
}
|
|
timeout--;
|
|
}
|
|
//set card read offset
|
|
//sdio_set_argument(base, (loop * SDIO_TRANS_SIZE));
|
|
if(card_type == CARD_TYPE_HIGH)
|
|
sdcard_writel(base, SD_ARG_LOW_offset, loop);
|
|
else if(card_type == CARD_TYPE_STANDARD)
|
|
sdcard_writel(base, SD_ARG_LOW_offset, loop*0x200);
|
|
//sdcard_writel(base, SD_ARG_LOW_offset, loop);
|
|
//send command 17
|
|
sdcard_writel(base, SD_TRANSFER_MODE_offset, 0x113a0011);
|
|
/*wait for complete*/
|
|
timeout = 40000;
|
|
if(sdcard_get_mode() == CARD_MODE_INT)
|
|
{
|
|
while (!SD_CMD_COMP_status)
|
|
{
|
|
SdCard_Wait(2000);
|
|
timeout--;
|
|
if(timeout == 0 )
|
|
{
|
|
uart_printf("INT mode,Wait for command17 time out!\r\n");
|
|
uart_printf("INT mode,Wait for command17 time out!\r\n");
|
|
if(SD_Decrease_Clk_Flag == 0)
|
|
{
|
|
sd_dumpregs(base);
|
|
}
|
|
status = OSASemaphoreRelease_sdcard(SDSysRef);
|
|
ASSERT(status == OS_SUCCESS);
|
|
SD_Read_status = 0;
|
|
|
|
return MMC_ERR_CMD_TOUT;
|
|
}
|
|
|
|
if(SD_Infinite_Err_Flag == 1)
|
|
{
|
|
status = OSASemaphoreRelease_sdcard(SDSysRef);
|
|
ASSERT(status == OS_SUCCESS);
|
|
SD_Read_status = 0;
|
|
return MMC_ERR_CMD_TOUT;
|
|
}
|
|
|
|
}
|
|
|
|
}else if(sdcard_get_mode() == CARD_MODE_POLL)
|
|
{
|
|
isr_sts = sdcard_readw(SDCARD_CTRL_BASE_ADDR, SD_NORM_INTR_STS_offset);
|
|
while (!(isr_sts & CMD_COMP))
|
|
{
|
|
SdCard_Wait(2000);
|
|
timeout--;
|
|
if (timeout == 0 )
|
|
{
|
|
fatal_printf("POLL mode,Wait for command17 time out!\r\n");
|
|
//uart_printf("blk num:0x%x",blk_cnt);
|
|
sd_dumpregs(base);
|
|
status = OSASemaphoreRelease_sdcard(SDSysRef);
|
|
ASSERT(status == OS_SUCCESS);
|
|
return MMC_ERR_CMD_TOUT;
|
|
}
|
|
isr_sts = sdcard_readw(SDCARD_CTRL_BASE_ADDR, SD_NORM_INTR_STS_offset);
|
|
}
|
|
//clear cmd complete interrupt
|
|
sdcard_writew(SDCARD_CTRL_BASE_ADDR, SD_NORM_INTR_STS_offset, CMD_COMP);
|
|
}
|
|
|
|
timeout = 40000;
|
|
|
|
if(sdcard_get_mode() == CARD_MODE_INT)
|
|
{
|
|
status = OSASemaphoreAcquire_sdcard(SDDATARef, OS_SUSPEND);
|
|
ASSERT(status == OS_SUCCESS);
|
|
if(SD_DATA_COMP_status != 1)
|
|
{
|
|
status = OSASemaphoreRelease_sdcard(SDSysRef);
|
|
ASSERT(status == OS_SUCCESS);
|
|
return MMC_ERR_DATA_TOUT;
|
|
}
|
|
|
|
}else if(sdcard_get_mode() == CARD_MODE_POLL)
|
|
{
|
|
isr_sts = sdcard_readw(SDCARD_CTRL_BASE_ADDR, SD_NORM_INTR_STS_offset);
|
|
while ( !(isr_sts & XFER_COMP))
|
|
{
|
|
if(isr_sts & DMA_INT)
|
|
{
|
|
sdcard_writew(base, SD_NORM_INTR_STS_offset, DMA_INT);
|
|
sdcard_writel(base, SD_SYSADDR_LOW_offset,sdcard_readl(base,SD_SYSADDR_LOW_offset));
|
|
uart_printf("CMD17 DMA interrupt");
|
|
timeout = 40000;
|
|
}
|
|
SdCard_Wait(2000);
|
|
timeout--;
|
|
if (timeout == 0 )
|
|
{
|
|
uart_printf("POLL mode,CMD17, Wait for data transfer time out!\r\n");
|
|
sd_dumpregs(base);
|
|
status = OSASemaphoreRelease_sdcard(SDSysRef);
|
|
ASSERT(status == OS_SUCCESS);
|
|
return MMC_ERR_DATA_TOUT;
|
|
//timeout = 40000;
|
|
}
|
|
isr_sts = sdcard_readw(SDCARD_CTRL_BASE_ADDR, SD_NORM_INTR_STS_offset);
|
|
}
|
|
//clear data complete interrupt
|
|
sdcard_writew(SDCARD_CTRL_BASE_ADDR, SD_NORM_INTR_STS_offset, XFER_COMP);
|
|
}
|
|
|
|
SdCard_SW_Reset(base);
|
|
//SdCard_Wait(200000);
|
|
SD_Read_status = 0;
|
|
status = OSASemaphoreRelease_sdcard(SDSysRef);
|
|
ASSERT(status == OS_SUCCESS);
|
|
return 0;
|
|
}
|
|
|
|
static void SdCard_Check_TransStatus(UINT32 base)
|
|
{
|
|
UINT16 cmd;
|
|
UINT32 argv;
|
|
|
|
//response type R1
|
|
cmd = 0x0d1a;
|
|
argv = SD_RCA << 16;
|
|
SdCard_Cmd_Nodata(cmd, argv, base);
|
|
//check card status, transfer and data ready
|
|
while((((SD_RESPONSE[0]>>9) & 0xf) != 4) || ((SD_RESPONSE[0] & 0x100) == 0))
|
|
{
|
|
//uart_printf("Response 0:0x%x",SD_RESPONSE[0]);
|
|
SdCard_Cmd_Nodata(cmd, argv, base);
|
|
|
|
if(SD_Infinite_Err_Flag == 1)
|
|
return;
|
|
}
|
|
}
|
|
|
|
UINT32 sdcard_write_multiblks(UINT32 base, UINT32 buffer, UINT32 loop, UINT32 blk_cnt)
|
|
{
|
|
UINT32 timeout,mask;
|
|
OSA_STATUS status;
|
|
UINT16 isr_sts;
|
|
gSDRecordTime = /*OSAGetTicks()*/0;
|
|
|
|
#ifdef MV_USB2_MASS_STORAGE
|
|
mvUsbStorageNotifyUsbActive();
|
|
#endif
|
|
|
|
status = OSASemaphoreAcquire_sdcard(SDSysRef, OS_SUSPEND);
|
|
ASSERT(status == OS_SUCCESS);
|
|
SD_Write_status = 1;
|
|
|
|
SD_CMD_COMP_status = 0;
|
|
SD_DATA_COMP_status = 0;
|
|
SD_DATA_START_status = 1;
|
|
CacheCleanMemory(buffer, 0x200*blk_cnt);
|
|
|
|
//sdio_set_dmaaddr(base, dma_addr);
|
|
sdcard_writel(base, SD_SYSADDR_LOW_offset, buffer);
|
|
|
|
//sdio_set_blkarg(base, SDIO_CMD18_BLKARG);
|
|
sdcard_writel(base, SD_BLOCK_SIZE_offset, 0x7200 | (blk_cnt << 16));
|
|
|
|
timeout = 1000000;
|
|
mask = SDHCI_CMD_INHIBIT;
|
|
while((sdcard_readl(base, SD_PRESENT_STAT_0_offset))&mask)
|
|
{
|
|
if(timeout == 0)
|
|
{
|
|
uart_printf("Controller never released inhabit bit\r\n");
|
|
status = OSASemaphoreRelease_sdcard(SDSysRef);
|
|
ASSERT(status == OS_SUCCESS);
|
|
SD_Write_status = 0;
|
|
return MMC_ERR_CMD_TOUT;
|
|
}
|
|
timeout--;
|
|
}
|
|
|
|
//set card read offset
|
|
if(card_type == CARD_TYPE_HIGH)
|
|
sdcard_writel(base, SD_ARG_LOW_offset, loop);
|
|
else if(card_type == CARD_TYPE_STANDARD)
|
|
sdcard_writel(base, SD_ARG_LOW_offset, loop*0x200);
|
|
|
|
sdcard_writel(base, SD_TRANSFER_MODE_offset, 0x193a0027);
|
|
|
|
/*wait for complete*/
|
|
timeout = 40000;
|
|
|
|
if(sdcard_get_mode() == CARD_MODE_INT)
|
|
{
|
|
while (!SD_CMD_COMP_status)
|
|
{
|
|
SdCard_Wait(2000);
|
|
timeout--;
|
|
if(timeout == 0 )
|
|
{
|
|
uart_printf("INT mode, Wait for command25 time out!\r\n");
|
|
if(SD_Decrease_Clk_Flag == 0)
|
|
{
|
|
sd_dumpregs(base);
|
|
}
|
|
|
|
status = OSASemaphoreRelease_sdcard(SDSysRef);
|
|
ASSERT(status == OS_SUCCESS);
|
|
SD_Write_status = 0;
|
|
|
|
return MMC_ERR_CMD_TOUT;
|
|
}
|
|
|
|
if(SD_Infinite_Err_Flag == 1)
|
|
{
|
|
status = OSASemaphoreRelease_sdcard(SDSysRef);
|
|
ASSERT(status == OS_SUCCESS);
|
|
SD_Read_status = 0;
|
|
return MMC_ERR_CMD_TOUT;
|
|
}
|
|
}
|
|
|
|
}else if(sdcard_get_mode() == CARD_MODE_POLL)
|
|
{
|
|
isr_sts = sdcard_readw(base, SD_NORM_INTR_STS_offset);
|
|
while (!(isr_sts & CMD_COMP))
|
|
{
|
|
SdCard_Wait(2000);
|
|
timeout--;
|
|
if (timeout == 0 )
|
|
{
|
|
fatal_printf("POLL mode, Wait for command25 time out!\r\n");
|
|
sd_dumpregs(base);
|
|
status = OSASemaphoreRelease_sdcard(SDSysRef);
|
|
ASSERT(status == OS_SUCCESS);
|
|
return MMC_ERR_CMD_TOUT;
|
|
}
|
|
isr_sts = sdcard_readw(base, SD_NORM_INTR_STS_offset);
|
|
}
|
|
|
|
//clear cmd complete interrupt
|
|
sdcard_writew(base, SD_NORM_INTR_STS_offset, CMD_COMP);
|
|
}
|
|
|
|
timeout = 80000;
|
|
if(sdcard_get_mode() == CARD_MODE_INT)
|
|
{
|
|
status = OSASemaphoreAcquire_sdcard(SDDATARef, OS_SUSPEND);
|
|
ASSERT(status == OS_SUCCESS);
|
|
|
|
if(SD_DATA_COMP_status != 1)
|
|
{
|
|
status = OSASemaphoreRelease_sdcard(SDSysRef);
|
|
ASSERT(status == OS_SUCCESS);
|
|
return MMC_ERR_DATA_TOUT;
|
|
}
|
|
/*
|
|
while (!SD_DATA_COMP_status)
|
|
{
|
|
SdCard_Wait(2000);
|
|
timeout--;
|
|
if (timeout == 0 )
|
|
{
|
|
uart_printf("INT mode,CMD25,Wait for data transfer time out!\r\n");
|
|
sd_dumpregs(base);
|
|
status = OSASemaphoreRelease_sdcard(SDSysRef);
|
|
ASSERT(status == OS_SUCCESS);
|
|
return MMC_ERR_DATA_TOUT;
|
|
}
|
|
}
|
|
*/
|
|
}else if(sdcard_get_mode() == CARD_MODE_POLL)
|
|
{
|
|
isr_sts = sdcard_readw(base, SD_NORM_INTR_STS_offset);
|
|
while ( !(isr_sts & XFER_COMP))
|
|
{
|
|
if(isr_sts & DMA_INT)
|
|
{
|
|
sdcard_writew(base, SD_NORM_INTR_STS_offset, DMA_INT);
|
|
sdcard_writel(base, SD_SYSADDR_LOW_offset,sdcard_readl(base,SD_SYSADDR_LOW_offset));
|
|
//uart_printf("CMD25 DMA interrupt");
|
|
timeout = 40000;
|
|
|
|
}
|
|
SdCard_Wait(2000);
|
|
timeout--;
|
|
if (timeout == 0 )
|
|
{
|
|
if(isr_sts & ERR_INT )
|
|
{
|
|
isr_sts = sdcard_readw(base, SD_ERR_INTR_STS_offset);
|
|
sdcard_writew(base, SD_ERR_INTR_STS_offset, isr_sts);
|
|
uart_printf("err_sts:0x%x",isr_sts);
|
|
SdCard_SW_Reset(base);
|
|
timeout = 40000;
|
|
}else
|
|
{
|
|
status = OSASemaphoreRelease_sdcard(SDSysRef);
|
|
ASSERT(status == OS_SUCCESS);
|
|
uart_printf("POLL mode,CMD25,Wait for data transfer time out!");
|
|
sd_dumpregs(base);
|
|
return MMC_ERR_DATA_TOUT;
|
|
}
|
|
}
|
|
isr_sts = sdcard_readw(base, SD_NORM_INTR_STS_offset);
|
|
}
|
|
//clear data complete interrupt
|
|
sdcard_writew(base, SD_NORM_INTR_STS_offset, XFER_COMP);
|
|
}
|
|
|
|
SD_Write_status = 2;
|
|
|
|
SdCard_Check_TransStatus(base);
|
|
//SdCard_Wait(200000);
|
|
SD_Write_status = 0;
|
|
status = OSASemaphoreRelease_sdcard(SDSysRef);
|
|
ASSERT(status == OS_SUCCESS);
|
|
|
|
return MMC_ERR_NONE;
|
|
|
|
}
|
|
|
|
UINT32 sdcard_write_singleblk(UINT32 base, UINT32 buffer, UINT32 loop)
|
|
{
|
|
UINT32 timeout,mask;
|
|
OSA_STATUS status;
|
|
UINT16 isr_sts;
|
|
gSDRecordTime = /*OSAGetTicks()*/0;
|
|
|
|
#ifdef MV_USB2_MASS_STORAGE
|
|
mvUsbStorageNotifyUsbActive();
|
|
#endif
|
|
|
|
status = OSASemaphoreAcquire_sdcard(SDSysRef, OS_SUSPEND);
|
|
ASSERT(status == OS_SUCCESS);
|
|
SD_Write_status = 1;
|
|
|
|
SD_CMD_COMP_status = 0;
|
|
SD_DATA_COMP_status = 0;
|
|
SD_DATA_START_status = 1;
|
|
CacheCleanMemory(buffer, 0x200);
|
|
|
|
//sdio_set_dmaaddr(base, dma_addr);
|
|
sdcard_writel(base, SD_SYSADDR_LOW_offset, buffer);
|
|
|
|
//sdio_set_blkarg(base, SDIO_CMD18_BLKARG);
|
|
sdcard_writel(base, SD_BLOCK_SIZE_offset, 0x7200 | (1 << 16));
|
|
|
|
timeout = 1000000;
|
|
mask = SDHCI_CMD_INHIBIT;
|
|
while((sdcard_readl(base, SD_PRESENT_STAT_0_offset))&mask)
|
|
{
|
|
if(timeout == 0)
|
|
{
|
|
uart_printf("Controller never released inhabit bit\r\n");
|
|
status = OSASemaphoreRelease_sdcard(SDSysRef);
|
|
ASSERT(status == OS_SUCCESS);
|
|
SD_Write_status = 0;
|
|
return MMC_ERR_CMD_TOUT;
|
|
}
|
|
timeout--;
|
|
}
|
|
|
|
//set card read offset
|
|
if(card_type == CARD_TYPE_HIGH)
|
|
sdcard_writel(base, SD_ARG_LOW_offset, loop);
|
|
else if(card_type == CARD_TYPE_STANDARD)
|
|
sdcard_writel(base, SD_ARG_LOW_offset, loop*0x200);
|
|
|
|
//send CMD24
|
|
sdcard_writel(base, SD_TRANSFER_MODE_offset, 0x183a0001);
|
|
|
|
/*wait for complete*/
|
|
timeout = 40000;
|
|
|
|
if(sdcard_get_mode() == CARD_MODE_INT)
|
|
{
|
|
while (!SD_CMD_COMP_status)
|
|
{
|
|
SdCard_Wait(2000);
|
|
timeout--;
|
|
if(timeout == 0 )
|
|
{
|
|
uart_printf("INT mode, Wait for command24 time out!\r\n");
|
|
if(SD_Decrease_Clk_Flag == 0)
|
|
{
|
|
sd_dumpregs(base);
|
|
}
|
|
|
|
status = OSASemaphoreRelease_sdcard(SDSysRef);
|
|
ASSERT(status == OS_SUCCESS);
|
|
SD_Write_status = 0;
|
|
|
|
return MMC_ERR_CMD_TOUT;
|
|
}
|
|
|
|
if(SD_Infinite_Err_Flag == 1)
|
|
{
|
|
status = OSASemaphoreRelease_sdcard(SDSysRef);
|
|
ASSERT(status == OS_SUCCESS);
|
|
SD_Read_status = 0;
|
|
return MMC_ERR_CMD_TOUT;
|
|
}
|
|
}
|
|
|
|
}else if(sdcard_get_mode() == CARD_MODE_POLL)
|
|
{
|
|
isr_sts = sdcard_readw(base, SD_NORM_INTR_STS_offset);
|
|
while (!(isr_sts & CMD_COMP))
|
|
{
|
|
SdCard_Wait(2000);
|
|
timeout--;
|
|
if (timeout == 0 )
|
|
{
|
|
fatal_printf("POLL mode, Wait for command24 time out!\r\n");
|
|
sd_dumpregs(base);
|
|
status = OSASemaphoreRelease_sdcard(SDSysRef);
|
|
ASSERT(status == OS_SUCCESS);
|
|
return MMC_ERR_CMD_TOUT;
|
|
}
|
|
isr_sts = sdcard_readw(base, SD_NORM_INTR_STS_offset);
|
|
}
|
|
|
|
//clear cmd complete interrupt
|
|
sdcard_writew(base, SD_NORM_INTR_STS_offset, CMD_COMP);
|
|
}
|
|
|
|
timeout = 80000;
|
|
if(sdcard_get_mode() == CARD_MODE_INT)
|
|
{
|
|
status = OSASemaphoreAcquire_sdcard(SDDATARef, OS_SUSPEND);
|
|
ASSERT(status == OS_SUCCESS);
|
|
|
|
if(SD_DATA_COMP_status != 1)
|
|
{
|
|
status = OSASemaphoreRelease_sdcard(SDSysRef);
|
|
ASSERT(status == OS_SUCCESS);
|
|
return MMC_ERR_DATA_TOUT;
|
|
}
|
|
}else if(sdcard_get_mode() == CARD_MODE_POLL)
|
|
{
|
|
isr_sts = sdcard_readw(base, SD_NORM_INTR_STS_offset);
|
|
while ( !(isr_sts & XFER_COMP))
|
|
{
|
|
if(isr_sts & DMA_INT)
|
|
{
|
|
sdcard_writew(base, SD_NORM_INTR_STS_offset, DMA_INT);
|
|
sdcard_writel(base, SD_SYSADDR_LOW_offset,sdcard_readl(base,SD_SYSADDR_LOW_offset));
|
|
uart_printf("CMD24 DMA interrupt");
|
|
timeout = 40000;
|
|
|
|
}
|
|
SdCard_Wait(2000);
|
|
timeout--;
|
|
if (timeout == 0 )
|
|
{
|
|
if(isr_sts & ERR_INT )
|
|
{
|
|
isr_sts = sdcard_readw(base, SD_ERR_INTR_STS_offset);
|
|
sdcard_writew(base, SD_ERR_INTR_STS_offset, isr_sts);
|
|
uart_printf("err_sts:0x%x",isr_sts);
|
|
SdCard_SW_Reset(base);
|
|
timeout = 40000;
|
|
}else
|
|
{
|
|
status = OSASemaphoreRelease_sdcard(SDSysRef);
|
|
ASSERT(status == OS_SUCCESS);
|
|
uart_printf("POLL mode,CMD25,Wait for data transfer time out!");
|
|
sd_dumpregs(base);
|
|
return MMC_ERR_DATA_TOUT;
|
|
}
|
|
}
|
|
isr_sts = sdcard_readw(base, SD_NORM_INTR_STS_offset);
|
|
}
|
|
//clear data complete interrupt
|
|
sdcard_writew(base, SD_NORM_INTR_STS_offset, XFER_COMP);
|
|
}
|
|
|
|
SD_Write_status = 2;
|
|
|
|
SdCard_Check_TransStatus(base);
|
|
//SdCard_Wait(200000);
|
|
SD_Write_status = 0;
|
|
status = OSASemaphoreRelease_sdcard(SDSysRef);
|
|
ASSERT(status == OS_SUCCESS);
|
|
|
|
return MMC_ERR_NONE;
|
|
|
|
}
|
|
|
|
UINT32 sdcard_write_mass_storage(UINT32 buffer, UINT32 loop, UINT32 blk_cnt)
|
|
{
|
|
UINT32 ret = 0;
|
|
if((sdcard_initialized != SDCARD_INIT_SUCCESS) || (SD_Infinite_Err_Flag == 1) || (card_status == CARD_STATUS_REMOVE))
|
|
{
|
|
return 0x10;
|
|
}
|
|
//uart_printf("write,loop:0x%x,blk_cnt:0x%x",loop,blk_cnt);
|
|
if(blk_cnt == 1)
|
|
ret = sdcard_write_singleblk(SD1_HOST_CTRL_ADDR, buffer, loop);
|
|
else if(blk_cnt > 1)
|
|
ret = sdcard_write_multiblks(SD1_HOST_CTRL_ADDR, buffer, loop, blk_cnt);
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
UINT32 sdcard_read_mass_storage(UINT32 buffer, UINT32 loop, UINT32 blk_cnt)
|
|
{
|
|
UINT32 ret = 0;
|
|
if((sdcard_initialized != SDCARD_INIT_SUCCESS) || (SD_Infinite_Err_Flag == 1) ||(card_status == CARD_STATUS_REMOVE))
|
|
{
|
|
return 0x10;
|
|
}
|
|
|
|
//uart_printf("read,loop:0x%x,blk_cnt:0x%x",loop,blk_cnt);
|
|
if(blk_cnt == 1)
|
|
ret = sdcard_read_singleblk(SD1_HOST_CTRL_ADDR, buffer, loop);
|
|
else if(blk_cnt > 1)
|
|
ret = sdcard_read_multiblks(SD1_HOST_CTRL_ADDR, buffer, loop, blk_cnt);
|
|
|
|
return ret;
|
|
}
|
|
|
|
UINT8 sdcard_get_errflag(void)
|
|
{
|
|
return SD_Infinite_Err_Flag;
|
|
}
|
|
BOOL sdcard_is_ready(void)
|
|
{
|
|
if(PlatformSDCardEnable()/*&&(FSInit_Status_Get()==1)*/&&(card_status != CARD_STATUS_REMOVE))
|
|
{
|
|
if((SD_Decrease_Clk_Flag != 0) && (sdcard_get_errflag() == 1) &&(!eeGetSystemAssertFlag()))
|
|
return FALSE;
|
|
else
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
BOOL sdcard_is_insert(void)
|
|
{
|
|
if(PlatformSDCardEnable()&&(sdcard_get_status()==1)&&(card_status != CARD_STATUS_REMOVE))
|
|
{
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
/*extern BOOL diagCommSdLogEnable(void);
|
|
BOOL SDWork(void)
|
|
{
|
|
if(TRUE == diagCommSdLogEnable())
|
|
{
|
|
return TRUE;
|
|
}
|
|
else
|
|
return FALSE;
|
|
}*/
|
|
|