in portable/Zynq.2019.3/xsdps.c [733:1205]
s32 XSdPs_CardInitialize( XSdPs * InstancePtr )
{
#ifdef __ICCARM__
#pragma data_alignment = 32
static u8 ExtCsd[ 512 ];
#pragma data_alignment = 32
static u8 SCR[ 8 ] = { 0U };
#else
static u8 ExtCsd[ 512 ] __attribute__( ( aligned( 32 ) ) );
static u8 SCR[ 8 ] __attribute__( ( aligned( 32 ) ) ) = { 0U };
#endif
u8 ReadBuff[ 64 ] = { 0U };
s32 Status;
u32 Arg;
Xil_AssertNonvoid( InstancePtr != NULL );
Xil_AssertNonvoid( InstancePtr->IsReady == XIL_COMPONENT_IS_READY );
FF_PRINTF( "XSdPs_CardInitialize\n" );
/* 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 */
/*
* SD default speed mode timing should be closed at 19 MHz.
* The reason for this is SD requires a voltage level shifter.
* This limitation applies to ZynqMPSoC.
*/
if( InstancePtr->HC_Version == XSDPS_HC_SPEC_V3 )
{
InstancePtr->BusSpeed = SD_CLK_19_MHZ;
}
else
{
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;
}
}
/* Get speed supported by device */
Status = XSdPs_Get_BusSpeed( InstancePtr, ReadBuff );
if( Status != XST_SUCCESS )
{
goto RETURN_PATH;
}
if( ( ( SCR[ 2 ] & SCR_SPEC_VER_3 ) != 0U ) &&
( ReadBuff[ 13 ] >= UHS_SDR50_SUPPORT ) &&
( InstancePtr->Config.BusWidth == XSDPS_WIDTH_8 ) &&
#if defined( ARMR5 ) || ( __aarch64__ ) || ( ARMA53_32 ) || ( PSU_PMU )
( XGetPSVersion_Info() > ( u32 ) XPS_VERSION_1 ) &&
#endif
( InstancePtr->Switch1v8 == 0U ) )
{
u16 CtrlReg, ClockReg;
/* Stop the clock */
CtrlReg = XSdPs_ReadReg16( InstancePtr->Config.BaseAddress,
XSDPS_CLK_CTRL_OFFSET );
CtrlReg &= ~( XSDPS_CC_SD_CLK_EN_MASK | XSDPS_CC_INT_CLK_EN_MASK );
XSdPs_WriteReg16( InstancePtr->Config.BaseAddress, XSDPS_CLK_CTRL_OFFSET,
CtrlReg );
/* Enabling 1.8V in controller */
CtrlReg = XSdPs_ReadReg16( InstancePtr->Config.BaseAddress,
XSDPS_HOST_CTRL2_OFFSET );
CtrlReg |= XSDPS_HC2_1V8_EN_MASK;
XSdPs_WriteReg16( InstancePtr->Config.BaseAddress, XSDPS_HOST_CTRL2_OFFSET,
CtrlReg );
/* Wait minimum 5mSec */
( void ) usleep( 5000U );
/* Check for 1.8V signal enable bit is cleared by Host */
CtrlReg = XSdPs_ReadReg16( InstancePtr->Config.BaseAddress,
XSDPS_HOST_CTRL2_OFFSET );
if( ( CtrlReg & XSDPS_HC2_1V8_EN_MASK ) == 0U )
{
Status = XST_FAILURE;
goto RETURN_PATH;
}
/* Wait for internal clock to stabilize */
ClockReg = XSdPs_ReadReg16( InstancePtr->Config.BaseAddress,
XSDPS_CLK_CTRL_OFFSET );
XSdPs_WriteReg16( InstancePtr->Config.BaseAddress,
XSDPS_CLK_CTRL_OFFSET,
ClockReg | XSDPS_CC_INT_CLK_EN_MASK );
ClockReg = XSdPs_ReadReg16( InstancePtr->Config.BaseAddress,
XSDPS_CLK_CTRL_OFFSET );
while( ( ClockReg & XSDPS_CC_INT_CLK_STABLE_MASK ) == 0U )
{
ClockReg = XSdPs_ReadReg16( InstancePtr->Config.BaseAddress,
XSDPS_CLK_CTRL_OFFSET );
}
/* Enable SD clock */
ClockReg = XSdPs_ReadReg16( InstancePtr->Config.BaseAddress,
XSDPS_CLK_CTRL_OFFSET );
XSdPs_WriteReg16( InstancePtr->Config.BaseAddress,
XSDPS_CLK_CTRL_OFFSET,
ClockReg | XSDPS_CC_SD_CLK_EN_MASK );
/* Wait for 1mSec */
( void ) usleep( 1000U );
InstancePtr->Switch1v8 = 1U;
}
#if defined( ARMR5 ) || defined( __aarch64__ ) || defined( ARMA53_32 ) || defined( __MICROBLAZE__ )
if( InstancePtr->Switch1v8 != 0U )
{
/* Identify the UHS mode supported by card */
XSdPs_Identify_UhsMode( InstancePtr, ReadBuff );
/* Set UHS-I SDR104 mode */
Status = XSdPs_Uhs_ModeInit( InstancePtr, ( u8 ) InstancePtr->Mode );
if( Status != XST_SUCCESS )
{
goto RETURN_PATH;
}
}
else
{
#endif /* if defined( ARMR5 ) || defined( __aarch64__ ) || defined( ARMA53_32 ) || defined( __MICROBLAZE__ ) */
/*
* 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 )
{
/* Check for high speed support */
if( ( ( ReadBuff[ 13 ] & HIGH_SPEED_SUPPORT ) != 0U ) &&
( InstancePtr->BusWidth >= XSDPS_4_BIT_WIDTH ) )
{
InstancePtr->Mode = XSDPS_HIGH_SPEED_MODE;
#if defined( ARMR5 ) || defined( __aarch64__ ) || defined( ARMA53_32 ) || defined( __MICROBLAZE__ )
InstancePtr->OTapDelay = SD_OTAPDLYSEL_SD_HSD;
InstancePtr->ITapDelay = SD_ITAPDLYSEL_HSD;
#endif
Status = XSdPs_Change_BusSpeed( InstancePtr );
if( Status != XST_SUCCESS )
{
Status = XST_FAILURE;
goto RETURN_PATH;
}
}
}
#if defined( ARMR5 ) || defined( __aarch64__ ) || defined( ARMA53_32 ) || defined( __MICROBLAZE__ )
}
#endif
}
else if( ( ( InstancePtr->CardType == XSDPS_CARD_MMC ) &&
( InstancePtr->Card_Version > CSD_SPEC_VER_3 ) ) &&
( 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;
}
InstancePtr->SectorCount = ( ( u32 ) ExtCsd[ EXT_CSD_SEC_COUNT_BYTE4 ] ) << 24;
InstancePtr->SectorCount |= ( u32 ) ExtCsd[ EXT_CSD_SEC_COUNT_BYTE3 ] << 16;
InstancePtr->SectorCount |= ( u32 ) ExtCsd[ EXT_CSD_SEC_COUNT_BYTE2 ] << 8;
InstancePtr->SectorCount |= ( u32 ) ExtCsd[ EXT_CSD_SEC_COUNT_BYTE1 ];
if( ( ( ExtCsd[ EXT_CSD_DEVICE_TYPE_BYTE ] &
EXT_CSD_DEVICE_TYPE_HIGH_SPEED ) != 0U ) &&
( InstancePtr->BusWidth >= XSDPS_4_BIT_WIDTH ) )
{
InstancePtr->Mode = XSDPS_HIGH_SPEED_MODE;
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;
}
InstancePtr->SectorCount = ( ( u32 ) ExtCsd[ EXT_CSD_SEC_COUNT_BYTE4 ] ) << 24;
InstancePtr->SectorCount |= ( u32 ) ExtCsd[ EXT_CSD_SEC_COUNT_BYTE3 ] << 16;
InstancePtr->SectorCount |= ( u32 ) ExtCsd[ EXT_CSD_SEC_COUNT_BYTE2 ] << 8;
InstancePtr->SectorCount |= ( u32 ) ExtCsd[ EXT_CSD_SEC_COUNT_BYTE1 ];
/* Check for card supported speed */
if( ( ( ExtCsd[ EXT_CSD_DEVICE_TYPE_BYTE ] &
( EXT_CSD_DEVICE_TYPE_SDR_1V8_HS200 |
EXT_CSD_DEVICE_TYPE_SDR_1V2_HS200 ) ) != 0U ) &&
( InstancePtr->BusWidth >= XSDPS_4_BIT_WIDTH ) )
{
InstancePtr->Mode = XSDPS_HS200_MODE;
#if defined( ARMR5 ) || defined( __aarch64__ ) || defined( ARMA53_32 ) || defined( __MICROBLAZE__ )
if( InstancePtr->Config.BankNumber == 2U )
{
InstancePtr->OTapDelay = SD_OTAPDLYSEL_HS200_B2;
}
else
{
InstancePtr->OTapDelay = SD_OTAPDLYSEL_HS200_B0;
}
#endif
}
else if( ( ( ExtCsd[ EXT_CSD_DEVICE_TYPE_BYTE ] &
( EXT_CSD_DEVICE_TYPE_DDR_1V8_HIGH_SPEED |
EXT_CSD_DEVICE_TYPE_DDR_1V2_HIGH_SPEED ) ) != 0U ) &&
( InstancePtr->BusWidth >= XSDPS_4_BIT_WIDTH ) )
{
InstancePtr->Mode = XSDPS_DDR52_MODE;
#if defined( ARMR5 ) || defined( __aarch64__ ) || defined( ARMA53_32 ) || defined( __MICROBLAZE__ )
InstancePtr->OTapDelay = SD_ITAPDLYSEL_EMMC_DDR50;
InstancePtr->ITapDelay = SD_ITAPDLYSEL_EMMC_DDR50;
#endif
}
else if( ( ( ExtCsd[ EXT_CSD_DEVICE_TYPE_BYTE ] &
EXT_CSD_DEVICE_TYPE_HIGH_SPEED ) != 0U ) &&
( InstancePtr->BusWidth >= XSDPS_4_BIT_WIDTH ) )
{
InstancePtr->Mode = XSDPS_HIGH_SPEED_MODE;
#if defined( ARMR5 ) || defined( __aarch64__ ) || defined( ARMA53_32 ) || defined( __MICROBLAZE__ )
InstancePtr->OTapDelay = SD_OTAPDLYSEL_EMMC_HSD;
InstancePtr->ITapDelay = SD_ITAPDLYSEL_HSD;
#endif
}
else
{
InstancePtr->Mode = XSDPS_DEFAULT_SPEED_MODE;
}
if( InstancePtr->Mode != XSDPS_DEFAULT_SPEED_MODE )
{
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( InstancePtr->Mode == XSDPS_HS200_MODE )
{
if( ExtCsd[ EXT_CSD_HS_TIMING_BYTE ] != EXT_CSD_HS_TIMING_HS200 )
{
Status = XST_FAILURE;
goto RETURN_PATH;
}
}
if( ( InstancePtr->Mode == XSDPS_HIGH_SPEED_MODE ) ||
( InstancePtr->Mode == XSDPS_DDR52_MODE ) )
{
if( ExtCsd[ EXT_CSD_HS_TIMING_BYTE ] != EXT_CSD_HS_TIMING_HIGH )
{
Status = XST_FAILURE;
goto RETURN_PATH;
}
if( InstancePtr->Mode == XSDPS_DDR52_MODE )
{
Status = XSdPs_Change_BusWidth( InstancePtr );
if( Status != XST_SUCCESS )
{
Status = XST_FAILURE;
goto RETURN_PATH;
}
}
}
}
/* Enable Rst_n_Fun bit if it is disabled */
if( ExtCsd[ EXT_CSD_RST_N_FUN_BYTE ] == EXT_CSD_RST_N_FUN_TEMP_DIS )
{
Arg = XSDPS_MMC_RST_FUN_EN_ARG;
Status = XSdPs_Set_Mmc_ExtCsd( InstancePtr, Arg );
if( Status != XST_SUCCESS )
{
Status = XST_FAILURE;
goto RETURN_PATH;
}
}
}
else
{
Status = XST_FAILURE;
goto RETURN_PATH;
}
if( ( InstancePtr->Mode != XSDPS_DDR52_MODE ) ||
( InstancePtr->CardType == XSDPS_CARD_SD ) )
{
Status = XSdPs_SetBlkSize( InstancePtr, XSDPS_BLK_SIZE_512_MASK );
if( Status != XST_SUCCESS )
{
Status = XST_FAILURE;
goto RETURN_PATH;
}
}
RETURN_PATH:
return Status;
}