in portable/Zynq/xsdps.c [588:882]
s32 XSdPs_CardInitialize( XSdPs * InstancePtr )
{
#ifdef __ICCARM__
#pragma data_alignment = 32
static u8 ExtCsd[ 512 ];
#pragma data_alignment = 4
#else
static u8 ExtCsd[ 512 ] __attribute__( ( aligned( 32 ) ) );
#endif
u8 SCR[ 8 ] = { 0U };
u8 ReadBuff[ 64 ] = { 0U };
s32 Status;
Xil_AssertNonvoid( InstancePtr != NULL );
Xil_AssertNonvoid( InstancePtr->IsReady == XIL_COMPONENT_IS_READY );
/* Default settings */
InstancePtr->BusWidth = XSDPS_1_BIT_WIDTH;
InstancePtr->CardType = XSDPS_CARD_SD;
InstancePtr->Switch1v8 = 0U;
InstancePtr->BusSpeed = XSDPS_CLK_400_KHZ;
if( ( InstancePtr->HC_Version == XSDPS_HC_SPEC_V3 ) &&
( ( InstancePtr->Host_Caps & XSDPS_CAPS_SLOT_TYPE_MASK )
== XSDPS_CAPS_EMB_SLOT ) )
{
InstancePtr->CardType = XSDPS_CHIP_EMMC;
}
else
{
Status = XSdPs_IdentifyCard( InstancePtr );
if( Status == XST_FAILURE )
{
goto RETURN_PATH;
}
}
if( ( InstancePtr->CardType != XSDPS_CARD_SD ) &&
( InstancePtr->CardType != XSDPS_CARD_MMC ) &&
( InstancePtr->CardType != XSDPS_CHIP_EMMC ) )
{
Status = XST_FAILURE;
goto RETURN_PATH;
}
if( InstancePtr->CardType == XSDPS_CARD_SD )
{
Status = XSdPs_SdCardInitialize( InstancePtr );
if( Status != XST_SUCCESS )
{
Status = XST_FAILURE;
goto RETURN_PATH;
}
/* Change clock to default clock 25MHz */
InstancePtr->BusSpeed = SD_CLK_25_MHZ;
Status = XSdPs_Change_ClkFreq( InstancePtr, InstancePtr->BusSpeed );
if( Status != XST_SUCCESS )
{
Status = XST_FAILURE;
goto RETURN_PATH;
}
}
else if( ( InstancePtr->CardType == XSDPS_CARD_MMC ) ||
( InstancePtr->CardType == XSDPS_CHIP_EMMC ) )
{
Status = XSdPs_MmcCardInitialize( InstancePtr );
if( Status != XST_SUCCESS )
{
Status = XST_FAILURE;
goto RETURN_PATH;
}
/* Change clock to default clock 26MHz */
InstancePtr->BusSpeed = SD_CLK_26_MHZ;
Status = XSdPs_Change_ClkFreq( InstancePtr, InstancePtr->BusSpeed );
if( Status != XST_SUCCESS )
{
Status = XST_FAILURE;
goto RETURN_PATH;
}
}
else
{
Status = XST_FAILURE;
goto RETURN_PATH;
}
Status = XSdPs_Select_Card( InstancePtr );
if( Status != XST_SUCCESS )
{
Status = XST_FAILURE;
goto RETURN_PATH;
}
if( InstancePtr->CardType == XSDPS_CARD_SD )
{
/* Pull-up disconnected during data transfer */
Status = XSdPs_Pullup( InstancePtr );
if( Status != XST_SUCCESS )
{
Status = XST_FAILURE;
goto RETURN_PATH;
}
Status = XSdPs_Get_BusWidth( InstancePtr, SCR );
if( Status != XST_SUCCESS )
{
Status = XST_FAILURE;
goto RETURN_PATH;
}
if( ( SCR[ 1 ] & WIDTH_4_BIT_SUPPORT ) != 0U )
{
Status = XSdPs_Change_BusWidth( InstancePtr );
if( Status != XST_SUCCESS )
{
Status = XST_FAILURE;
goto RETURN_PATH;
}
}
if( ( InstancePtr->Switch1v8 != 0U ) &&
( InstancePtr->BusWidth == XSDPS_4_BIT_WIDTH ) )
{
/* Set UHS-I SDR104 mode */
Status = XSdPs_Uhs_ModeInit( InstancePtr,
XSDPS_UHS_SPEED_MODE_SDR104 );
if( Status != XST_SUCCESS )
{
Status = XST_FAILURE;
goto RETURN_PATH;
}
}
else
{
/*
* card supports CMD6 when SD_SPEC field in SCR register
* indicates that the Physical Layer Specification Version
* is 1.10 or later. So for SD v1.0 cmd6 is not supported.
*/
if( SCR[ 0 ] != 0U )
{
/* Get speed supported by device */
Status = XSdPs_Get_BusSpeed( InstancePtr, ReadBuff );
if( Status != XST_SUCCESS )
{
Status = XST_FAILURE;
FF_PRINTF( "SD-card seems OK but 4-bits doesn't work. Dirty contacts ?\n" );
FF_PRINTF( "Or: SD-card has version v1.0 which does not support cmd6 ?\n" );
goto RETURN_PATH;
}
/* Check for high speed support */
if( ( ReadBuff[ 13 ] & HIGH_SPEED_SUPPORT ) != 0U )
{
Status = XSdPs_Change_BusSpeed( InstancePtr );
if( Status != XST_SUCCESS )
{
Status = XST_FAILURE;
goto RETURN_PATH;
}
}
}
}
}
else if( ( InstancePtr->CardType == XSDPS_CARD_MMC ) &&
( InstancePtr->HC_Version == XSDPS_HC_SPEC_V2 ) )
{
Status = XSdPs_Change_BusWidth( InstancePtr );
if( Status != XST_SUCCESS )
{
Status = XST_FAILURE;
goto RETURN_PATH;
}
Status = XSdPs_Get_Mmc_ExtCsd( InstancePtr, ExtCsd );
if( Status != XST_SUCCESS )
{
Status = XST_FAILURE;
goto RETURN_PATH;
}
if( ExtCsd[ EXT_CSD_BUS_WIDTH_BYTE ] != EXT_CSD_BUS_WIDTH_4_BIT )
{
Status = XST_FAILURE;
goto RETURN_PATH;
}
if( ( ExtCsd[ EXT_CSD_DEVICE_TYPE_BYTE ] &
EXT_CSD_DEVICE_TYPE_HIGH_SPEED ) != 0U )
{
Status = XSdPs_Change_BusSpeed( InstancePtr );
if( Status != XST_SUCCESS )
{
Status = XST_FAILURE;
goto RETURN_PATH;
}
Status = XSdPs_Get_Mmc_ExtCsd( InstancePtr, ExtCsd );
if( Status != XST_SUCCESS )
{
Status = XST_FAILURE;
goto RETURN_PATH;
}
if( ExtCsd[ EXT_CSD_HS_TIMING_BYTE ] != EXT_CSD_HS_TIMING_HIGH )
{
Status = XST_FAILURE;
goto RETURN_PATH;
}
}
}
else if( InstancePtr->CardType == XSDPS_CHIP_EMMC )
{
/* Change bus width to 8-bit */
Status = XSdPs_Change_BusWidth( InstancePtr );
if( Status != XST_SUCCESS )
{
Status = XST_FAILURE;
goto RETURN_PATH;
}
/* Get Extended CSD */
Status = XSdPs_Get_Mmc_ExtCsd( InstancePtr, ExtCsd );
if( Status != XST_SUCCESS )
{
Status = XST_FAILURE;
goto RETURN_PATH;
}
/* Check for 8-bit support */
if( ExtCsd[ EXT_CSD_BUS_WIDTH_BYTE ] != EXT_CSD_BUS_WIDTH_8_BIT )
{
Status = XST_FAILURE;
goto RETURN_PATH;
}
if( ( ExtCsd[ EXT_CSD_DEVICE_TYPE_BYTE ] &
( EXT_CSD_DEVICE_TYPE_SDR_1V8_HS200 |
EXT_CSD_DEVICE_TYPE_SDR_1V2_HS200 ) ) != 0U )
{
Status = XSdPs_Change_BusSpeed( InstancePtr );
if( Status != XST_SUCCESS )
{
Status = XST_FAILURE;
goto RETURN_PATH;
}
Status = XSdPs_Get_Mmc_ExtCsd( InstancePtr, ExtCsd );
if( Status != XST_SUCCESS )
{
Status = XST_FAILURE;
goto RETURN_PATH;
}
if( ExtCsd[ EXT_CSD_HS_TIMING_BYTE ] != EXT_CSD_HS_TIMING_HS200 )
{
Status = XST_FAILURE;
goto RETURN_PATH;
}
}
}
Status = XSdPs_SetBlkSize( InstancePtr, XSDPS_BLK_SIZE_512_MASK );
if( Status != XST_SUCCESS )
{
Status = XST_FAILURE;
goto RETURN_PATH;
}
RETURN_PATH:
return Status;
}