1 /******************************************************************************
3 * Copyright (C) 2013 - 2015 Xilinx, Inc. All rights reserved.
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
15 * Use of the Software is limited solely to applications:
16 * (a) running on a Xilinx device, or
17 * (b) that interact with a Xilinx device through a bus or interconnect.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
24 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 * Except as contained in this notice, the name of the Xilinx shall not be used
28 * in advertising or otherwise to promote the sale, use or other dealings in
29 * this Software without prior written authorization from Xilinx.
31 ******************************************************************************/
32 /*****************************************************************************/
36 * @addtogroup sdps_v2_5
39 * Contains the interface functions of the XSdPs driver.
40 * See xsdps.h for a detailed description of the device and driver.
43 * MODIFICATION HISTORY:
45 * Ver Who Date Changes
46 * ----- --- -------- -----------------------------------------------
47 * 1.00a hk/sg 10/17/13 Initial release
48 * 2.0 hk 12/13/13 Added check for arm to use sleep.h and its API's
49 * 2.1 hk 04/18/14 Add sleep for microblaze designs. CR# 781117.
50 * 2.2 hk 07/28/14 Make changes to enable use of data cache.
51 * 2.3 sk 09/23/14 Send command for relative card address
52 * when re-initialization is done.CR# 819614.
53 * Use XSdPs_Change_ClkFreq API whenever changing
55 * 2.4 sk 12/04/14 Added support for micro SD without
57 * Checked for DAT Inhibit mask instead of CMD
58 * Inhibit mask in Cmd Transfer API.
59 * Added Support for SD Card v1.0
60 * 2.5 sg 07/09/15 Added SD 3.0 features
61 * kvn 07/15/15 Modified the code according to MISRAC-2012.
62 * 2.6 sk 10/12/15 Added support for SD card v1.0 CR# 840601.
63 * 2.7 sk 11/24/15 Considered the slot type befoe checking CD/WP pins.
64 * sk 12/10/15 Added support for MMC cards.
65 * sk 02/16/16 Corrected the Tuning logic.
66 * sk 03/01/16 Removed Bus Width check for eMMC. CR# 938311.
69 ******************************************************************************/
71 /***************************** Include Files *********************************/
74 * The header sleep.h and API usleep() can only be used with an arm design.
75 * MB_Sleep() is used for microblaze design.
77 #if defined (__arm__) || defined (__aarch64__)
85 #include "microblaze_sleep.h"
89 /************************** Constant Definitions *****************************/
90 #define XSDPS_CMD8_VOL_PATTERN 0x1AAU
91 #define XSDPS_RESPOCR_READY 0x80000000U
92 #define XSDPS_ACMD41_HCS 0x40000000U
93 #define XSDPS_ACMD41_3V3 0x00300000U
94 #define XSDPS_CMD1_HIGH_VOL 0x00FF8000U
95 #define XSDPS_CMD1_DUAL_VOL 0x00FF8010U
96 #define HIGH_SPEED_SUPPORT 0x2U
97 #define WIDTH_4_BIT_SUPPORT 0x4U
98 #define SD_CLK_25_MHZ 25000000U
99 #define SD_CLK_26_MHZ 26000000U
100 #define EXT_CSD_DEVICE_TYPE_BYTE 196U
101 #define EXT_CSD_DEVICE_TYPE_HIGH_SPEED 0x2U
102 #define EXT_CSD_DEVICE_TYPE_DDR_1V8_HIGH_SPEED 0x4U
103 #define EXT_CSD_DEVICE_TYPE_DDR_1V2_HIGH_SPEED 0x8U
104 #define EXT_CSD_DEVICE_TYPE_SDR_1V8_HS200 0x10U
105 #define EXT_CSD_DEVICE_TYPE_SDR_1V2_HS200 0x20U
106 #define CSD_SPEC_VER_3 0x3U
108 /* Note: Remove this once fixed */
111 /**************************** Type Definitions *******************************/
113 /***************** Macros (Inline Functions) Definitions *********************/
115 /************************** Function Prototypes ******************************/
116 u32 XSdPs_FrameCmd(XSdPs *InstancePtr, u32 Cmd);
117 s32 XSdPs_CmdTransfer(XSdPs *InstancePtr, u32 Cmd, u32 Arg, u32 BlkCnt);
118 void XSdPs_SetupADMA2DescTbl(XSdPs *InstancePtr, u32 BlkCnt, const u8 *Buff);
119 extern s32 XSdPs_Uhs_ModeInit(XSdPs *InstancePtr, u8 Mode);
120 static s32 XSdPs_IdentifyCard(XSdPs *InstancePtr);
121 static s32 XSdPs_Switch_Voltage(XSdPs *InstancePtr);
123 /*****************************************************************************/
126 * Initializes a specific XSdPs instance such that the driver is ready to use.
129 * @param InstancePtr is a pointer to the XSdPs instance.
130 * @param ConfigPtr is a reference to a structure containing information
131 * about a specific SD device. This function initializes an
132 * InstancePtr object for a specific device specified by the
133 * contents of Config.
134 * @param EffectiveAddr is the device base address in the virtual memory
135 * address space. The caller is responsible for keeping the address
136 * mapping from EffectiveAddr to the device physical base address
137 * unchanged once this function is invoked. Unexpected errors may
138 * occur if the address mapping changes after this function is
139 * called. If address translation is not used, use
140 * ConfigPtr->Config.BaseAddress for this device.
143 * - XST_SUCCESS if successful.
144 * - XST_DEVICE_IS_STARTED if the device is already started.
145 * It must be stopped to re-initialize.
147 * @note This function initializes the host controller.
148 * Initial clock of 400KHz is set.
149 * Voltage of 3.3V is selected as that is supported by host.
150 * Interrupts status is enabled and signal disabled by default.
151 * Default data direction is card to host and
152 * 32 bit ADMA2 is selected. Defualt Block size is 512 bytes.
154 ******************************************************************************/
155 s32 XSdPs_CfgInitialize(XSdPs *InstancePtr, XSdPs_Config *ConfigPtr,
162 Xil_AssertNonvoid(InstancePtr != NULL);
163 Xil_AssertNonvoid(ConfigPtr != NULL);
165 /* Set some default values. */
166 InstancePtr->Config.BaseAddress = EffectiveAddr;
167 InstancePtr->Config.InputClockHz = ConfigPtr->InputClockHz;
168 InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
169 InstancePtr->Config.CardDetect = ConfigPtr->CardDetect;
170 InstancePtr->Config.WriteProtect = ConfigPtr->WriteProtect;
172 /* Disable bus power */
173 XSdPs_WriteReg8(InstancePtr->Config.BaseAddress,
174 XSDPS_POWER_CTRL_OFFSET, 0U);
176 /* Delay to poweroff card */
177 #if defined (__arm__) || defined (__aarch64__)
183 #ifdef __MICROBLAZE__
189 /* "Software reset for all" is initiated */
190 XSdPs_WriteReg8(InstancePtr->Config.BaseAddress, XSDPS_SW_RST_OFFSET,
191 XSDPS_SWRST_ALL_MASK);
193 /* Proceed with initialization only after reset is complete */
194 ReadReg = XSdPs_ReadReg8(InstancePtr->Config.BaseAddress,
195 XSDPS_SW_RST_OFFSET);
196 while ((ReadReg & XSDPS_SWRST_ALL_MASK) != 0U) {
197 ReadReg = XSdPs_ReadReg8(InstancePtr->Config.BaseAddress,
198 XSDPS_SW_RST_OFFSET);
200 /* Host Controller version is read. */
201 InstancePtr->HC_Version =
202 (u8)(XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
203 XSDPS_HOST_CTRL_VER_OFFSET) & XSDPS_HC_SPEC_VER_MASK);
206 * Read capabilities register and update it in Instance pointer.
207 * It is sufficient to read this once on power on.
209 InstancePtr->Host_Caps = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
212 /* Select voltage and enable bus power. */
213 XSdPs_WriteReg8(InstancePtr->Config.BaseAddress,
214 XSDPS_POWER_CTRL_OFFSET,
215 XSDPS_PC_BUS_VSEL_3V3_MASK | XSDPS_PC_BUS_PWR_MASK);
217 /* Change the clock frequency to 400 KHz */
218 Status = XSdPs_Change_ClkFreq(InstancePtr, XSDPS_CLK_400_KHZ);
219 if (Status != XST_SUCCESS) {
220 Status = XST_FAILURE;
224 if ((InstancePtr->Host_Caps & XSDPS_CAP_VOLT_3V3_MASK) != 0U) {
225 PowerLevel = XSDPS_PC_BUS_VSEL_3V3_MASK;
226 } else if ((InstancePtr->Host_Caps & XSDPS_CAP_VOLT_3V0_MASK) != 0U) {
227 PowerLevel = XSDPS_PC_BUS_VSEL_3V0_MASK;
228 } else if ((InstancePtr->Host_Caps & XSDPS_CAP_VOLT_1V8_MASK) != 0U) {
229 PowerLevel = XSDPS_PC_BUS_VSEL_1V8_MASK;
234 /* Select voltage based on capability and enable bus power. */
235 XSdPs_WriteReg8(InstancePtr->Config.BaseAddress,
236 XSDPS_POWER_CTRL_OFFSET,
237 PowerLevel | XSDPS_PC_BUS_PWR_MASK);
238 /* Enable ADMA2 in 64bit mode. */
239 XSdPs_WriteReg8(InstancePtr->Config.BaseAddress,
240 XSDPS_HOST_CTRL1_OFFSET,
241 XSDPS_HC_DMA_ADMA2_32_MASK);
243 /* Enable all interrupt status except card interrupt initially */
244 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
245 XSDPS_NORM_INTR_STS_EN_OFFSET,
246 XSDPS_NORM_INTR_ALL_MASK & (~XSDPS_INTR_CARD_MASK));
248 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
249 XSDPS_ERR_INTR_STS_EN_OFFSET,
250 XSDPS_ERROR_INTR_ALL_MASK);
252 /* Disable all interrupt signals by default. */
253 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
254 XSDPS_NORM_INTR_SIG_EN_OFFSET, 0x0U);
255 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
256 XSDPS_ERR_INTR_SIG_EN_OFFSET, 0x0U);
259 * Transfer mode register - default value
260 * DMA enabled, block count enabled, data direction card to host(read)
262 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
263 XSDPS_XFER_MODE_OFFSET,
264 XSDPS_TM_DMA_EN_MASK | XSDPS_TM_BLK_CNT_EN_MASK |
265 XSDPS_TM_DAT_DIR_SEL_MASK);
267 /* Set block size to 512 by default */
268 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
269 XSDPS_BLK_SIZE_OFFSET, XSDPS_BLK_SIZE_512_MASK);
271 Status = XST_SUCCESS;
278 /*****************************************************************************/
280 * SD initialization is done in this function
283 * @param InstancePtr is a pointer to the instance to be worked on.
286 * - XST_SUCCESS if initialization was successful
287 * - XST_FAILURE if failure - could be because
288 * a) SD is already initialized
289 * b) There is no card inserted
290 * c) One of the steps (commands) in the
291 initialization cycle failed
293 * @note This function initializes the SD card by following its
294 * initialization and identification state diagram.
295 * CMD0 is sent to reset card.
296 * CMD8 and ACDM41 are sent to identify voltage and
297 * high capacity support
298 * CMD2 and CMD3 are sent to obtain Card ID and
299 * Relative card address respectively.
300 * CMD9 is sent to read the card specific data.
302 ******************************************************************************/
303 s32 XSdPs_SdCardInitialize(XSdPs *InstancePtr)
312 Xil_AssertNonvoid(InstancePtr != NULL);
313 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
315 if ((InstancePtr->HC_Version != XSDPS_HC_SPEC_V3) ||
316 ((InstancePtr->Host_Caps & XSDPS_CAPS_SLOT_TYPE_MASK)
317 != XSDPS_CAPS_EMB_SLOT)) {
318 if(InstancePtr->Config.CardDetect != 0U) {
320 * Check the present state register to make sure
321 * card is inserted and detected by host controller
323 PresentStateReg = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
324 XSDPS_PRES_STATE_OFFSET);
325 if ((PresentStateReg & XSDPS_PSR_CARD_INSRT_MASK) == 0U) {
326 Status = XST_FAILURE;
332 /* CMD0 no response expected */
333 Status = XSdPs_CmdTransfer(InstancePtr, (u32)CMD0, 0U, 0U);
334 if (Status != XST_SUCCESS) {
335 Status = XST_FAILURE;
340 * CMD8; response expected
341 * 0x1AA - Supply Voltage 2.7 - 3.6V and AA is pattern
343 Status = XSdPs_CmdTransfer(InstancePtr, CMD8,
344 XSDPS_CMD8_VOL_PATTERN, 0U);
345 if ((Status != XST_SUCCESS) && (Status != XSDPS_CT_ERROR)) {
346 Status = XST_FAILURE;
350 if (Status == XSDPS_CT_ERROR) {
351 /* "Software reset for all" is initiated */
352 XSdPs_WriteReg8(InstancePtr->Config.BaseAddress, XSDPS_SW_RST_OFFSET,
353 XSDPS_SWRST_CMD_LINE_MASK);
355 /* Proceed with initialization only after reset is complete */
356 ReadReg = XSdPs_ReadReg8(InstancePtr->Config.BaseAddress,
357 XSDPS_SW_RST_OFFSET);
358 while ((ReadReg & XSDPS_SWRST_CMD_LINE_MASK) != 0U) {
359 ReadReg = XSdPs_ReadReg8(InstancePtr->Config.BaseAddress,
360 XSDPS_SW_RST_OFFSET);
364 RespOCR = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
366 if (RespOCR != XSDPS_CMD8_VOL_PATTERN) {
367 InstancePtr->Card_Version = XSDPS_SD_VER_1_0;
370 InstancePtr->Card_Version = XSDPS_SD_VER_2_0;
374 /* Send ACMD41 while card is still busy with power up */
375 while ((RespOCR & XSDPS_RESPOCR_READY) == 0U) {
376 Status = XSdPs_CmdTransfer(InstancePtr, CMD55, 0U, 0U);
377 if (Status != XST_SUCCESS) {
378 Status = XST_FAILURE;
382 Arg = XSDPS_ACMD41_HCS | XSDPS_ACMD41_3V3 | (0x1FFU << 15U);
383 if (InstancePtr->HC_Version == XSDPS_HC_SPEC_V3) {
384 Arg |= XSDPS_OCR_S18;
387 /* 0x40300000 - Host High Capacity support & 3.3V window */
388 Status = XSdPs_CmdTransfer(InstancePtr, ACMD41,
390 if (Status != XST_SUCCESS) {
391 Status = XST_FAILURE;
395 /* Response with card capacity */
396 RespOCR = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
401 /* Update HCS support flag based on card capacity response */
402 if ((RespOCR & XSDPS_ACMD41_HCS) != 0U) {
403 InstancePtr->HCS = 1U;
406 /* There is no support to switch to 1.8V and use UHS mode on 1.0 silicon */
408 if ((RespOCR & XSDPS_OCR_S18) != 0U) {
409 InstancePtr->Switch1v8 = 1U;
410 Status = XSdPs_Switch_Voltage(InstancePtr);
411 if (Status != XST_SUCCESS) {
412 Status = XST_FAILURE;
419 /* CMD2 for Card ID */
420 Status = XSdPs_CmdTransfer(InstancePtr, CMD2, 0U, 0U);
421 if (Status != XST_SUCCESS) {
422 Status = XST_FAILURE;
426 InstancePtr->CardID[0] =
427 XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
429 InstancePtr->CardID[1] =
430 XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
432 InstancePtr->CardID[2] =
433 XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
435 InstancePtr->CardID[3] =
436 XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
439 Status = XSdPs_CmdTransfer(InstancePtr, CMD3, 0U, 0U);
440 if (Status != XST_SUCCESS) {
441 Status = XST_FAILURE;
446 * Relative card address is stored as the upper 16 bits
447 * This is to avoid shifting when sending commands
449 InstancePtr->RelCardAddr =
450 XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
451 XSDPS_RESP0_OFFSET) & 0xFFFF0000U;
452 } while (InstancePtr->RelCardAddr == 0U);
454 Status = XSdPs_CmdTransfer(InstancePtr, CMD9, (InstancePtr->RelCardAddr), 0U);
455 if (Status != XST_SUCCESS) {
456 Status = XST_FAILURE;
461 * Card specific data is read.
462 * Currently not used for any operation.
464 CSD[0] = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
466 CSD[1] = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
468 CSD[2] = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
470 CSD[3] = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
473 Status = XST_SUCCESS;
480 /*****************************************************************************/
483 * Initialize Card with Identification mode sequence
486 * @param InstancePtr is a pointer to the instance to be worked on.
489 * - XST_SUCCESS if initialization was successful
490 * - XST_FAILURE if failure - could be because
491 * a) SD is already initialized
492 * b) There is no card inserted
493 * c) One of the steps (commands) in the
494 * initialization cycle failed
497 ******************************************************************************/
498 s32 XSdPs_CardInitialize(XSdPs *InstancePtr) {
505 #pragma data_alignment = 32
506 static u8 ExtCsd[512];
507 #pragma data_alignment = 4
509 static u8 ExtCsd[512] __attribute__ ((aligned(32)));
512 u8 ReadBuff[64] = { 0U };
515 Xil_AssertNonvoid(InstancePtr != NULL);
516 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
518 /* Default settings */
519 InstancePtr->BusWidth = XSDPS_1_BIT_WIDTH;
520 InstancePtr->CardType = XSDPS_CARD_SD;
521 InstancePtr->Switch1v8 = 0U;
522 InstancePtr->BusSpeed = XSDPS_CLK_400_KHZ;
524 if ((InstancePtr->HC_Version == XSDPS_HC_SPEC_V3) &&
525 ((InstancePtr->Host_Caps & XSDPS_CAPS_SLOT_TYPE_MASK)
526 == XSDPS_CAPS_EMB_SLOT)) {
527 InstancePtr->CardType = XSDPS_CHIP_EMMC;
529 Status = XSdPs_IdentifyCard(InstancePtr);
530 if (Status == XST_FAILURE) {
535 if ((InstancePtr->CardType != XSDPS_CARD_SD) &&
536 (InstancePtr->CardType != XSDPS_CARD_MMC) &&
537 (InstancePtr->CardType != XSDPS_CHIP_EMMC)) {
538 Status = XST_FAILURE;
542 if (InstancePtr->CardType == XSDPS_CARD_SD) {
543 Status = XSdPs_SdCardInitialize(InstancePtr);
544 if (Status != XST_SUCCESS) {
545 Status = XST_FAILURE;
549 /* Change clock to default clock 25MHz */
550 InstancePtr->BusSpeed = SD_CLK_25_MHZ;
551 Status = XSdPs_Change_ClkFreq(InstancePtr, InstancePtr->BusSpeed);
552 if (Status != XST_SUCCESS) {
553 Status = XST_FAILURE;
557 } else if ((InstancePtr->CardType == XSDPS_CARD_MMC)
558 || (InstancePtr->CardType == XSDPS_CHIP_EMMC)) {
559 Status = XSdPs_MmcCardInitialize(InstancePtr);
560 if (Status != XST_SUCCESS) {
561 Status = XST_FAILURE;
564 /* Change clock to default clock 26MHz */
565 InstancePtr->BusSpeed = SD_CLK_26_MHZ;
566 Status = XSdPs_Change_ClkFreq(InstancePtr, InstancePtr->BusSpeed);
567 if (Status != XST_SUCCESS) {
568 Status = XST_FAILURE;
572 Status = XST_FAILURE;
576 Status = XSdPs_Select_Card(InstancePtr);
577 if (Status != XST_SUCCESS) {
578 Status = XST_FAILURE;
582 if (InstancePtr->CardType == XSDPS_CARD_SD) {
583 /* Pull-up disconnected during data transfer */
584 Status = XSdPs_Pullup(InstancePtr);
585 if (Status != XST_SUCCESS) {
586 Status = XST_FAILURE;
590 Status = XSdPs_Get_BusWidth(InstancePtr, SCR);
591 if (Status != XST_SUCCESS) {
592 Status = XST_FAILURE;
596 if ((SCR[1] & WIDTH_4_BIT_SUPPORT) != 0U) {
597 Status = XSdPs_Change_BusWidth(InstancePtr);
598 if (Status != XST_SUCCESS) {
599 Status = XST_FAILURE;
604 if ((InstancePtr->Switch1v8 != 0U) &&
605 (InstancePtr->BusWidth == XSDPS_4_BIT_WIDTH)) {
606 /* Set UHS-I SDR104 mode */
607 Status = XSdPs_Uhs_ModeInit(InstancePtr,
608 XSDPS_UHS_SPEED_MODE_SDR104);
609 if (Status != XST_SUCCESS) {
610 Status = XST_FAILURE;
617 * card supports CMD6 when SD_SPEC field in SCR register
618 * indicates that the Physical Layer Specification Version
619 * is 1.10 or later. So for SD v1.0 cmd6 is not supported.
622 /* Get speed supported by device */
623 Status = XSdPs_Get_BusSpeed(InstancePtr, ReadBuff);
624 if (Status != XST_SUCCESS) {
625 Status = XST_FAILURE;
629 /* Check for high speed support */
630 if ((ReadBuff[13] & HIGH_SPEED_SUPPORT) != 0U) {
631 Status = XSdPs_Change_BusSpeed(InstancePtr);
632 if (Status != XST_SUCCESS) {
633 Status = XST_FAILURE;
640 } else if (((InstancePtr->CardType == XSDPS_CARD_MMC) &&
641 (InstancePtr->Card_Version > CSD_SPEC_VER_3)) &&
642 (InstancePtr->HC_Version == XSDPS_HC_SPEC_V2)) {
644 Status = XSdPs_Change_BusWidth(InstancePtr);
645 if (Status != XST_SUCCESS) {
646 Status = XST_FAILURE;
650 Status = XSdPs_Get_Mmc_ExtCsd(InstancePtr, ExtCsd);
651 if (Status != XST_SUCCESS) {
652 Status = XST_FAILURE;
656 if ((ExtCsd[EXT_CSD_DEVICE_TYPE_BYTE] &
657 EXT_CSD_DEVICE_TYPE_HIGH_SPEED) != 0U) {
658 Status = XSdPs_Change_BusSpeed(InstancePtr);
659 if (Status != XST_SUCCESS) {
660 Status = XST_FAILURE;
664 Status = XSdPs_Get_Mmc_ExtCsd(InstancePtr, ExtCsd);
665 if (Status != XST_SUCCESS) {
666 Status = XST_FAILURE;
670 if (ExtCsd[EXT_CSD_HS_TIMING_BYTE] != EXT_CSD_HS_TIMING_HIGH) {
671 Status = XST_FAILURE;
675 } else if (InstancePtr->CardType == XSDPS_CHIP_EMMC){
676 /* Change bus width to 8-bit */
677 Status = XSdPs_Change_BusWidth(InstancePtr);
678 if (Status != XST_SUCCESS) {
679 Status = XST_FAILURE;
683 /* Get Extended CSD */
684 Status = XSdPs_Get_Mmc_ExtCsd(InstancePtr, ExtCsd);
685 if (Status != XST_SUCCESS) {
686 Status = XST_FAILURE;
690 if ((ExtCsd[EXT_CSD_DEVICE_TYPE_BYTE] &
691 (EXT_CSD_DEVICE_TYPE_SDR_1V8_HS200 |
692 EXT_CSD_DEVICE_TYPE_SDR_1V2_HS200)) != 0U) {
693 Status = XSdPs_Change_BusSpeed(InstancePtr);
694 if (Status != XST_SUCCESS) {
695 Status = XST_FAILURE;
699 Status = XSdPs_Get_Mmc_ExtCsd(InstancePtr, ExtCsd);
700 if (Status != XST_SUCCESS) {
701 Status = XST_FAILURE;
705 if (ExtCsd[EXT_CSD_HS_TIMING_BYTE] != EXT_CSD_HS_TIMING_HS200) {
706 Status = XST_FAILURE;
712 Status = XSdPs_SetBlkSize(InstancePtr, XSDPS_BLK_SIZE_512_MASK);
713 if (Status != XST_SUCCESS) {
714 Status = XST_FAILURE;
722 /*****************************************************************************/
725 * Identify type of card using CMD0 + CMD1 sequence
728 * @param InstancePtr is a pointer to the XSdPs instance.
730 ******************************************************************************/
731 static s32 XSdPs_IdentifyCard(XSdPs *InstancePtr)
737 Xil_AssertNonvoid(InstancePtr != NULL);
738 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
740 /* 74 CLK delay after card is powered up, before the first command. */
741 #if defined (__arm__) || defined (__aarch64__)
743 usleep(XSDPS_INIT_DELAY);
747 #ifdef __MICROBLAZE__
754 /* CMD0 no response expected */
755 Status = XSdPs_CmdTransfer(InstancePtr, CMD0, 0U, 0U);
756 if (Status != XST_SUCCESS) {
757 Status = XST_FAILURE;
761 /* Host High Capacity support & High voltage window */
762 Status = XSdPs_CmdTransfer(InstancePtr, CMD1,
763 XSDPS_ACMD41_HCS | XSDPS_CMD1_HIGH_VOL, 0U);
764 if (Status != XST_SUCCESS) {
765 InstancePtr->CardType = XSDPS_CARD_SD;
767 InstancePtr->CardType = XSDPS_CARD_MMC;
770 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
771 XSDPS_NORM_INTR_STS_OFFSET, XSDPS_NORM_INTR_ALL_MASK);
772 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
773 XSDPS_ERR_INTR_STS_OFFSET, XSDPS_ERROR_INTR_ALL_MASK);
775 /* "Software reset for all" is initiated */
776 XSdPs_WriteReg8(InstancePtr->Config.BaseAddress, XSDPS_SW_RST_OFFSET,
777 XSDPS_SWRST_CMD_LINE_MASK);
779 /* Proceed with initialization only after reset is complete */
780 ReadReg = XSdPs_ReadReg8(InstancePtr->Config.BaseAddress,
781 XSDPS_SW_RST_OFFSET);
782 while ((ReadReg & XSDPS_SWRST_CMD_LINE_MASK) != 0U) {
783 ReadReg = XSdPs_ReadReg8(InstancePtr->Config.BaseAddress,
784 XSDPS_SW_RST_OFFSET);
787 Status = XST_SUCCESS;
793 /*****************************************************************************/
796 * Switches the SD card voltage from 3v3 to 1v8
799 * @param InstancePtr is a pointer to the XSdPs instance.
801 ******************************************************************************/
802 static s32 XSdPs_Switch_Voltage(XSdPs *InstancePtr)
808 /* Send switch voltage command */
809 Status = XSdPs_CmdTransfer(InstancePtr, CMD11, 0U, 0U);
810 if (Status != XST_SUCCESS) {
811 Status = XST_FAILURE;
814 /* Wait for CMD and DATA line to go low */
815 ReadReg = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
816 XSDPS_PRES_STATE_OFFSET);
817 while ((ReadReg & (XSDPS_PSR_CMD_SG_LVL_MASK |
818 XSDPS_PSR_DAT30_SG_LVL_MASK)) != 0U) {
819 ReadReg = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
820 XSDPS_PRES_STATE_OFFSET);
824 CtrlReg = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
825 XSDPS_CLK_CTRL_OFFSET);
826 CtrlReg &= ~(XSDPS_CC_SD_CLK_EN_MASK | XSDPS_CC_INT_CLK_EN_MASK);
827 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress, XSDPS_CLK_CTRL_OFFSET,
830 /* Wait minimum 5mSec */
831 #if defined (__arm__) || defined (__aarch64__)
837 #ifdef __MICROBLAZE__
843 /* Enabling 1.8V in controller */
844 CtrlReg = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
845 XSDPS_HOST_CTRL2_OFFSET);
846 CtrlReg |= XSDPS_HC2_1V8_EN_MASK;
847 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress, XSDPS_HOST_CTRL2_OFFSET,
851 Status = XSdPs_Change_ClkFreq(InstancePtr, XSDPS_CLK_400_KHZ);
852 if (Status != XST_SUCCESS) {
853 Status = XST_FAILURE;
857 /* Wait for CMD and DATA line to go high */
858 ReadReg = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
859 XSDPS_PRES_STATE_OFFSET);
860 while ((ReadReg & (XSDPS_PSR_CMD_SG_LVL_MASK | XSDPS_PSR_DAT30_SG_LVL_MASK))
861 != (XSDPS_PSR_CMD_SG_LVL_MASK | XSDPS_PSR_DAT30_SG_LVL_MASK)) {
862 ReadReg = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
863 XSDPS_PRES_STATE_OFFSET);
870 /*****************************************************************************/
873 * This function does SD command generation.
875 * @param InstancePtr is a pointer to the instance to be worked on.
876 * @param Cmd is the command to be sent.
877 * @param Arg is the argument to be sent along with the command.
878 * This could be address or any other information
879 * @param BlkCnt - Block count passed by the user.
882 * - XST_SUCCESS if initialization was successful
883 * - XST_FAILURE if failure - could be because another transfer
884 * is in progress or command or data inhibit is set
886 ******************************************************************************/
887 s32 XSdPs_CmdTransfer(XSdPs *InstancePtr, u32 Cmd, u32 Arg, u32 BlkCnt)
894 Xil_AssertNonvoid(InstancePtr != NULL);
895 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
898 * Check the command inhibit to make sure no other
899 * command transfer is in progress
901 PresentStateReg = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
902 XSDPS_PRES_STATE_OFFSET);
903 if ((PresentStateReg & XSDPS_PSR_INHIBIT_CMD_MASK) != 0U) {
904 Status = XST_FAILURE;
908 /* Write block count register */
909 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
910 XSDPS_BLK_CNT_OFFSET, (u16)BlkCnt);
912 XSdPs_WriteReg8(InstancePtr->Config.BaseAddress,
913 XSDPS_TIMEOUT_CTRL_OFFSET, 0xEU);
915 /* Write argument register */
916 XSdPs_WriteReg(InstancePtr->Config.BaseAddress,
917 XSDPS_ARGMT_OFFSET, Arg);
919 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
920 XSDPS_NORM_INTR_STS_OFFSET, XSDPS_NORM_INTR_ALL_MASK);
921 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
922 XSDPS_ERR_INTR_STS_OFFSET, XSDPS_ERROR_INTR_ALL_MASK);
923 /* Command register is set to trigger transfer of command */
924 CommandReg = XSdPs_FrameCmd(InstancePtr, Cmd);
927 * Mask to avoid writing to reserved bits 31-30
928 * This is necessary because 0x80000000 is used by this software to
929 * distinguish between ACMD and CMD of same number
931 CommandReg = CommandReg & 0x3FFFU;
934 * Check for data inhibit in case of command using DAT lines.
935 * For Tuning Commands DAT lines check can be ignored.
937 if ((Cmd != CMD21) && (Cmd != CMD19)) {
938 PresentStateReg = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
939 XSDPS_PRES_STATE_OFFSET);
940 if (((PresentStateReg & (XSDPS_PSR_INHIBIT_DAT_MASK |
941 XSDPS_PSR_INHIBIT_DAT_MASK)) != 0U) &&
942 ((CommandReg & XSDPS_DAT_PRESENT_SEL_MASK) != 0U)) {
943 Status = XST_FAILURE;
948 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress, XSDPS_CMD_OFFSET,
951 /* Polling for response for now */
953 StatusReg = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
954 XSDPS_NORM_INTR_STS_OFFSET);
955 if ((Cmd == CMD21) || (Cmd == CMD19)) {
956 if ((XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
957 XSDPS_NORM_INTR_STS_OFFSET) & XSDPS_INTR_BRR_MASK) != 0U){
958 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
959 XSDPS_NORM_INTR_STS_OFFSET, XSDPS_INTR_BRR_MASK);
964 if ((StatusReg & XSDPS_INTR_ERR_MASK) != 0U) {
965 Status = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
966 XSDPS_ERR_INTR_STS_OFFSET);
967 if ((Status & ~XSDPS_INTR_ERR_CT_MASK) == 0) {
968 Status = XSDPS_CT_ERROR;
970 /* Write to clear error bits */
971 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
972 XSDPS_ERR_INTR_STS_OFFSET,
973 XSDPS_ERROR_INTR_ALL_MASK);
976 } while((StatusReg & XSDPS_INTR_CC_MASK) == 0U);
977 /* Write to clear bit */
978 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
979 XSDPS_NORM_INTR_STS_OFFSET,
982 Status = XST_SUCCESS;
989 /*****************************************************************************/
991 * This function frames the Command register for a particular command.
992 * Note that this generates only the command register value i.e.
993 * the upper 16 bits of the transfer mode and command register.
994 * This value is already shifted to be upper 16 bits and can be directly
995 * OR'ed with transfer mode register value.
997 * @param Command to be sent.
999 * @return Command register value complete with response type and
1000 * data, CRC and index related flags.
1002 ******************************************************************************/
1003 u32 XSdPs_FrameCmd(XSdPs *InstancePtr, u32 Cmd)
1011 RetVal |= RESP_NONE;
1023 RetVal |= RESP_NONE;
1029 if (InstancePtr->CardType == XSDPS_CARD_SD) {
1030 RetVal |= RESP_R1 | (u32)XSDPS_DAT_PRESENT_SEL_MASK;
1042 if (InstancePtr->CardType == XSDPS_CARD_SD) {
1045 RetVal |= RESP_R1 | (u32)XSDPS_DAT_PRESENT_SEL_MASK;
1062 RetVal |= RESP_R1 | (u32)XSDPS_DAT_PRESENT_SEL_MASK;
1068 RetVal |= RESP_R1 | (u32)XSDPS_DAT_PRESENT_SEL_MASK;
1076 RetVal |= RESP_R1 | (u32)XSDPS_DAT_PRESENT_SEL_MASK;
1092 /*****************************************************************************/
1094 * This function performs SD read in polled mode.
1096 * @param InstancePtr is a pointer to the instance to be worked on.
1097 * @param Arg is the address passed by the user that is to be sent as
1098 * argument along with the command.
1099 * @param BlkCnt - Block count passed by the user.
1100 * @param Buff - Pointer to the data buffer for a DMA transfer.
1103 * - XST_SUCCESS if initialization was successful
1104 * - XST_FAILURE if failure - could be because another transfer
1105 * is in progress or command or data inhibit is set
1107 ******************************************************************************/
1108 s32 XSdPs_ReadPolled(XSdPs *InstancePtr, u32 Arg, u32 BlkCnt, u8 *Buff)
1111 u32 PresentStateReg;
1114 if ((InstancePtr->HC_Version != XSDPS_HC_SPEC_V3) ||
1115 ((InstancePtr->Host_Caps & XSDPS_CAPS_SLOT_TYPE_MASK)
1116 != XSDPS_CAPS_EMB_SLOT)) {
1117 if(InstancePtr->Config.CardDetect != 0U) {
1118 /* Check status to ensure card is initialized */
1119 PresentStateReg = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
1120 XSDPS_PRES_STATE_OFFSET);
1121 if ((PresentStateReg & XSDPS_PSR_CARD_INSRT_MASK) == 0x0U) {
1122 Status = XST_FAILURE;
1128 /* Set block size to 512 if not already set */
1129 if( XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
1130 XSDPS_BLK_SIZE_OFFSET) != XSDPS_BLK_SIZE_512_MASK ) {
1131 Status = XSdPs_SetBlkSize(InstancePtr,
1132 XSDPS_BLK_SIZE_512_MASK);
1133 if (Status != XST_SUCCESS) {
1134 Status = XST_FAILURE;
1139 XSdPs_SetupADMA2DescTbl(InstancePtr, BlkCnt, Buff);
1141 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
1142 XSDPS_XFER_MODE_OFFSET,
1143 XSDPS_TM_AUTO_CMD12_EN_MASK |
1144 XSDPS_TM_BLK_CNT_EN_MASK | XSDPS_TM_DAT_DIR_SEL_MASK |
1145 XSDPS_TM_DMA_EN_MASK | XSDPS_TM_MUL_SIN_BLK_SEL_MASK);
1147 Xil_DCacheInvalidateRange((INTPTR)Buff, BlkCnt * XSDPS_BLK_SIZE_512_MASK);
1149 /* Send block read command */
1150 Status = XSdPs_CmdTransfer(InstancePtr, CMD18, Arg, BlkCnt);
1151 if (Status != XST_SUCCESS) {
1152 Status = XST_FAILURE;
1156 /* Check for transfer complete */
1158 StatusReg = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
1159 XSDPS_NORM_INTR_STS_OFFSET);
1160 if ((StatusReg & XSDPS_INTR_ERR_MASK) != 0U) {
1161 /* Write to clear error bits */
1162 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
1163 XSDPS_ERR_INTR_STS_OFFSET,
1164 XSDPS_ERROR_INTR_ALL_MASK);
1165 Status = XST_FAILURE;
1168 } while((StatusReg & XSDPS_INTR_TC_MASK) == 0U);
1170 /* Write to clear bit */
1171 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
1172 XSDPS_NORM_INTR_STS_OFFSET, XSDPS_INTR_TC_MASK);
1173 Status = (s32)XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
1174 XSDPS_RESP0_OFFSET);
1176 Status = XST_SUCCESS;
1182 /*****************************************************************************/
1184 * This function performs SD write in polled mode.
1186 * @param InstancePtr is a pointer to the instance to be worked on.
1187 * @param Arg is the address passed by the user that is to be sent as
1188 * argument along with the command.
1189 * @param BlkCnt - Block count passed by the user.
1190 * @param Buff - Pointer to the data buffer for a DMA transfer.
1193 * - XST_SUCCESS if initialization was successful
1194 * - XST_FAILURE if failure - could be because another transfer
1195 * is in progress or command or data inhibit is set
1197 ******************************************************************************/
1198 s32 XSdPs_WritePolled(XSdPs *InstancePtr, u32 Arg, u32 BlkCnt, const u8 *Buff)
1201 u32 PresentStateReg;
1204 if ((InstancePtr->HC_Version != XSDPS_HC_SPEC_V3) ||
1205 ((InstancePtr->Host_Caps & XSDPS_CAPS_SLOT_TYPE_MASK)
1206 != XSDPS_CAPS_EMB_SLOT)) {
1207 if(InstancePtr->Config.CardDetect != 0U) {
1208 /* Check status to ensure card is initialized */
1209 PresentStateReg = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
1210 XSDPS_PRES_STATE_OFFSET);
1211 if ((PresentStateReg & XSDPS_PSR_CARD_INSRT_MASK) == 0x0U) {
1212 Status = XST_FAILURE;
1218 /* Set block size to 512 if not already set */
1219 if( XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
1220 XSDPS_BLK_SIZE_OFFSET) != XSDPS_BLK_SIZE_512_MASK ) {
1221 Status = XSdPs_SetBlkSize(InstancePtr,
1222 XSDPS_BLK_SIZE_512_MASK);
1223 if (Status != XST_SUCCESS) {
1224 Status = XST_FAILURE;
1230 XSdPs_SetupADMA2DescTbl(InstancePtr, BlkCnt, Buff);
1231 Xil_DCacheFlushRange((INTPTR)Buff, BlkCnt * XSDPS_BLK_SIZE_512_MASK);
1233 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
1234 XSDPS_XFER_MODE_OFFSET,
1235 XSDPS_TM_AUTO_CMD12_EN_MASK |
1236 XSDPS_TM_BLK_CNT_EN_MASK |
1237 XSDPS_TM_MUL_SIN_BLK_SEL_MASK | XSDPS_TM_DMA_EN_MASK);
1239 /* Send block write command */
1240 Status = XSdPs_CmdTransfer(InstancePtr, CMD25, Arg, BlkCnt);
1241 if (Status != XST_SUCCESS) {
1242 Status = XST_FAILURE;
1247 * Check for transfer complete
1248 * Polling for response for now
1251 StatusReg = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
1252 XSDPS_NORM_INTR_STS_OFFSET);
1253 if ((StatusReg & XSDPS_INTR_ERR_MASK) != 0U) {
1254 /* Write to clear error bits */
1255 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
1256 XSDPS_ERR_INTR_STS_OFFSET,
1257 XSDPS_ERROR_INTR_ALL_MASK);
1258 Status = XST_FAILURE;
1261 } while((StatusReg & XSDPS_INTR_TC_MASK) == 0U);
1263 /* Write to clear bit */
1264 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
1265 XSDPS_NORM_INTR_STS_OFFSET, XSDPS_INTR_TC_MASK);
1267 Status = XST_SUCCESS;
1273 /*****************************************************************************/
1276 * Selects card and sets default block size
1279 * @param InstancePtr is a pointer to the XSdPs instance.
1282 * - XST_SUCCESS if successful.
1283 * - XST_FAILURE if fail.
1287 ******************************************************************************/
1288 s32 XSdPs_Select_Card (XSdPs *InstancePtr)
1292 /* Send CMD7 - Select card */
1293 Status = XSdPs_CmdTransfer(InstancePtr, CMD7,
1294 InstancePtr->RelCardAddr, 0U);
1295 if (Status != XST_SUCCESS) {
1296 Status = XST_FAILURE;
1305 /*****************************************************************************/
1308 * API to setup ADMA2 descriptor table
1311 * @param InstancePtr is a pointer to the XSdPs instance.
1312 * @param BlkCnt - block count.
1313 * @param Buff pointer to data buffer.
1319 ******************************************************************************/
1320 void XSdPs_SetupADMA2DescTbl(XSdPs *InstancePtr, u32 BlkCnt, const u8 *Buff)
1322 u32 TotalDescLines = 0U;
1326 /* Setup ADMA2 - Write descriptor table and point ADMA SAR to it */
1327 BlkSize = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
1328 XSDPS_BLK_SIZE_OFFSET);
1329 BlkSize = BlkSize & XSDPS_BLK_SIZE_MASK;
1331 if((BlkCnt*BlkSize) < XSDPS_DESC_MAX_LENGTH) {
1333 TotalDescLines = 1U;
1337 TotalDescLines = ((BlkCnt*BlkSize) / XSDPS_DESC_MAX_LENGTH);
1338 if (((BlkCnt * BlkSize) % XSDPS_DESC_MAX_LENGTH) != 0U) {
1339 TotalDescLines += 1U;
1344 for (DescNum = 0U; DescNum < (TotalDescLines-1); DescNum++) {
1345 InstancePtr->Adma2_DescrTbl[DescNum].Address =
1346 (u32)((UINTPTR)Buff + (DescNum*XSDPS_DESC_MAX_LENGTH));
1347 InstancePtr->Adma2_DescrTbl[DescNum].Attribute =
1348 XSDPS_DESC_TRAN | XSDPS_DESC_VALID;
1349 /* This will write '0' to length field which indicates 65536 */
1350 InstancePtr->Adma2_DescrTbl[DescNum].Length =
1351 (u16)XSDPS_DESC_MAX_LENGTH;
1354 InstancePtr->Adma2_DescrTbl[TotalDescLines-1].Address =
1355 (u32)((UINTPTR)Buff + (DescNum*XSDPS_DESC_MAX_LENGTH));
1357 InstancePtr->Adma2_DescrTbl[TotalDescLines-1].Attribute =
1358 XSDPS_DESC_TRAN | XSDPS_DESC_END | XSDPS_DESC_VALID;
1360 InstancePtr->Adma2_DescrTbl[TotalDescLines-1].Length =
1361 (u16)((BlkCnt*BlkSize) - (DescNum*XSDPS_DESC_MAX_LENGTH));
1364 XSdPs_WriteReg(InstancePtr->Config.BaseAddress, XSDPS_ADMA_SAR_OFFSET,
1365 (u32)(UINTPTR)&(InstancePtr->Adma2_DescrTbl[0]));
1367 Xil_DCacheFlushRange((INTPTR)&(InstancePtr->Adma2_DescrTbl[0]),
1368 sizeof(XSdPs_Adma2Descriptor) * 32U);
1372 /*****************************************************************************/
1374 * Mmc initialization is done in this function
1377 * @param InstancePtr is a pointer to the instance to be worked on.
1380 * - XST_SUCCESS if initialization was successful
1381 * - XST_FAILURE if failure - could be because
1382 * a) MMC is already initialized
1383 * b) There is no card inserted
1384 * c) One of the steps (commands) in the initialization
1386 * @note This function initializes the SD card by following its
1387 * initialization and identification state diagram.
1388 * CMD0 is sent to reset card.
1389 * CMD1 sent to identify voltage and high capacity support
1390 * CMD2 and CMD3 are sent to obtain Card ID and
1391 * Relative card address respectively.
1392 * CMD9 is sent to read the card specific data.
1394 ******************************************************************************/
1395 s32 XSdPs_MmcCardInitialize(XSdPs *InstancePtr)
1397 u32 PresentStateReg;
1402 Xil_AssertNonvoid(InstancePtr != NULL);
1403 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
1405 if ((InstancePtr->HC_Version != XSDPS_HC_SPEC_V3) ||
1406 ((InstancePtr->Host_Caps & XSDPS_CAPS_SLOT_TYPE_MASK)
1407 != XSDPS_CAPS_EMB_SLOT)) {
1408 if(InstancePtr->Config.CardDetect != 0U) {
1410 * Check the present state register to make sure
1411 * card is inserted and detected by host controller
1413 PresentStateReg = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
1414 XSDPS_PRES_STATE_OFFSET);
1415 if ((PresentStateReg & XSDPS_PSR_CARD_INSRT_MASK) == 0U) {
1416 Status = XST_FAILURE;
1422 /* CMD0 no response expected */
1423 Status = XSdPs_CmdTransfer(InstancePtr, CMD0, 0U, 0U);
1424 if (Status != XST_SUCCESS) {
1425 Status = XST_FAILURE;
1430 /* Send CMD1 while card is still busy with power up */
1431 while ((RespOCR & XSDPS_RESPOCR_READY) == 0U) {
1433 /* Host High Capacity support & High volage window */
1434 Status = XSdPs_CmdTransfer(InstancePtr, CMD1,
1435 XSDPS_ACMD41_HCS | XSDPS_CMD1_HIGH_VOL, 0U);
1436 if (Status != XST_SUCCESS) {
1437 Status = XST_FAILURE;
1441 /* Response with card capacity */
1442 RespOCR = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
1443 XSDPS_RESP0_OFFSET);
1447 /* Update HCS support flag based on card capacity response */
1448 if ((RespOCR & XSDPS_ACMD41_HCS) != 0U) {
1449 InstancePtr->HCS = 1U;
1452 /* CMD2 for Card ID */
1453 Status = XSdPs_CmdTransfer(InstancePtr, CMD2, 0U, 0U);
1454 if (Status != XST_SUCCESS) {
1455 Status = XST_FAILURE;
1459 InstancePtr->CardID[0] =
1460 XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
1461 XSDPS_RESP0_OFFSET);
1462 InstancePtr->CardID[1] =
1463 XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
1464 XSDPS_RESP1_OFFSET);
1465 InstancePtr->CardID[2] =
1466 XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
1467 XSDPS_RESP2_OFFSET);
1468 InstancePtr->CardID[3] =
1469 XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
1470 XSDPS_RESP3_OFFSET);
1472 /* Set relative card address */
1473 InstancePtr->RelCardAddr = 0x12340000U;
1474 Status = XSdPs_CmdTransfer(InstancePtr, CMD3, (InstancePtr->RelCardAddr), 0U);
1475 if (Status != XST_SUCCESS) {
1476 Status = XST_FAILURE;
1480 Status = XSdPs_CmdTransfer(InstancePtr, CMD9, (InstancePtr->RelCardAddr), 0U);
1481 if (Status != XST_SUCCESS) {
1482 Status = XST_FAILURE;
1487 * Card specific data is read.
1488 * Currently not used for any operation.
1490 CSD[0] = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
1491 XSDPS_RESP0_OFFSET);
1492 CSD[1] = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
1493 XSDPS_RESP1_OFFSET);
1494 CSD[2] = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
1495 XSDPS_RESP2_OFFSET);
1496 CSD[3] = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
1497 XSDPS_RESP3_OFFSET);
1499 InstancePtr->Card_Version = (CSD[3] & CSD_SPEC_VER_MASK) >>18U;
1501 Status = XST_SUCCESS;