1 /******************************************************************************
3 * Copyright (C) 2013 - 2014 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_1
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.
53 ******************************************************************************/
55 /***************************** Include Files *********************************/
58 * The header sleep.h and API usleep() can only be used with an arm design.
59 * MB_Sleep() is used for microblaze design.
69 #include "microblaze_sleep.h"
73 /************************** Constant Definitions *****************************/
74 #define XSDPS_CMD8_VOL_PATTERN 0x1AA
75 #define XSDPS_RESPOCR_READY 0x80000000
76 #define XSDPS_ACMD41_HCS 0x40000000
77 #define XSDPS_ACMD41_3V3 0x00300000
78 #define XSDPS_CMD1_HIGH_VOL 0x00FF8000
79 #define XSDPS_CMD1_DUAL_VOL 0x00FF8010
81 /**************************** Type Definitions *******************************/
83 /***************** Macros (Inline Functions) Definitions *********************/
85 #define XSDPS_INIT_DELAY 2000
87 /************************** Function Prototypes ******************************/
88 u32 XSdPs_FrameCmd(u32 Cmd);
89 int XSdPs_CmdTransfer(XSdPs *InstancePtr, u32 Cmd, u32 Arg, u32 BlkCnt);
90 void XSdPs_SetupADMA2DescTbl(XSdPs *InstancePtr, u32 BlkCnt, const u8 *Buff);
92 /*****************************************************************************/
95 * Initializes a specific XSdPs instance such that the driver is ready to use.
98 * @param InstancePtr is a pointer to the XSdPs instance.
99 * @param ConfigPtr is a reference to a structure containing information
100 * about a specific SD device. This function initializes an
101 * InstancePtr object for a specific device specified by the
102 * contents of Config.
103 * @param EffectiveAddr is the device base address in the virtual memory
104 * address space. The caller is responsible for keeping the address
105 * mapping from EffectiveAddr to the device physical base address
106 * unchanged once this function is invoked. Unexpected errors may
107 * occur if the address mapping changes after this function is
108 * called. If address translation is not used, use
109 * ConfigPtr->Config.BaseAddress for this device.
112 * - XST_SUCCESS if successful.
113 * - XST_DEVICE_IS_STARTED if the device is already started.
114 * It must be stopped to re-initialize.
116 * @note This function initializes the host controller.
117 * Initial clock of 400KHz is set.
118 * Voltage of 3.3V is selected as that is supported by host.
119 * Interrupts status is enabled and signal disabled by default.
120 * Default data direction is card to host and
121 * 32 bit ADMA2 is selected. Defualt Block size is 512 bytes.
123 ******************************************************************************/
124 int XSdPs_CfgInitialize(XSdPs *InstancePtr, XSdPs_Config *ConfigPtr,
129 Xil_AssertNonvoid(InstancePtr != NULL);
130 Xil_AssertNonvoid(ConfigPtr != NULL);
133 * Set some default values.
135 InstancePtr->Config.BaseAddress = EffectiveAddr;
136 InstancePtr->Config.InputClockHz = ConfigPtr->InputClockHz;
137 InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
140 * "Software reset for all" is initiated
142 XSdPs_WriteReg8(InstancePtr->Config.BaseAddress, XSDPS_SW_RST_OFFSET,
143 XSDPS_SWRST_ALL_MASK);
146 * Proceed with initialization only after reset is complete
148 while (XSdPs_ReadReg8(InstancePtr->Config.BaseAddress,
149 XSDPS_SW_RST_OFFSET) & XSDPS_SWRST_ALL_MASK);
152 * Read capabilities register and update it in Instance pointer.
153 * It is sufficient to read this once on power on.
155 InstancePtr->Host_Caps = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
159 * SD clock frequency divider 128
160 * Enable the internal clock
162 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
163 XSDPS_CLK_CTRL_OFFSET,
164 XSDPS_CC_SDCLK_FREQ_D128_MASK | XSDPS_CC_INT_CLK_EN_MASK);
167 * Wait for internal clock to stabilize
169 while ((XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
170 XSDPS_CLK_CTRL_OFFSET) & XSDPS_CC_INT_CLK_STABLE_MASK) == 0);
175 ClockReg = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
176 XSDPS_CLK_CTRL_OFFSET);
177 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
178 XSDPS_CLK_CTRL_OFFSET, ClockReg | XSDPS_CC_SD_CLK_EN_MASK);
181 * Select voltage and enable bus power.
183 XSdPs_WriteReg8(InstancePtr->Config.BaseAddress,
184 XSDPS_POWER_CTRL_OFFSET,
185 XSDPS_PC_BUS_VSEL_3V3_MASK | XSDPS_PC_BUS_PWR_MASK);
187 XSdPs_WriteReg8(InstancePtr->Config.BaseAddress,
188 XSDPS_HOST_CTRL1_OFFSET,
189 XSDPS_HC_DMA_ADMA2_32_MASK);
192 * Enable all interrupt status except card interrupt initially
194 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
195 XSDPS_NORM_INTR_STS_EN_OFFSET,
196 XSDPS_NORM_INTR_ALL_MASK & (~XSDPS_INTR_CARD_MASK));
198 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
199 XSDPS_ERR_INTR_STS_EN_OFFSET,
200 XSDPS_ERROR_INTR_ALL_MASK);
203 * Disable all interrupt signals by default.
205 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
206 XSDPS_NORM_INTR_SIG_EN_OFFSET, 0x0);
207 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
208 XSDPS_ERR_INTR_SIG_EN_OFFSET, 0x0);
211 * Transfer mode register - default value
212 * DMA enabled, block count enabled, data direction card to host(read)
214 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
215 XSDPS_XFER_MODE_OFFSET,
216 XSDPS_TM_DMA_EN_MASK | XSDPS_TM_BLK_CNT_EN_MASK |
217 XSDPS_TM_DAT_DIR_SEL_MASK);
220 * Set block size to 512 by default
222 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
223 XSDPS_BLK_SIZE_OFFSET, XSDPS_BLK_SIZE_512_MASK);
228 /*****************************************************************************/
230 * SD initialization is done in this function
233 * @param InstancePtr is a pointer to the instance to be worked on.
236 * - XST_SUCCESS if initialization was successful
237 * - XST_FAILURE if failure - could be because
238 * a) SD is already initialized
239 * b) There is no card inserted
240 * c) One of the steps (commands) in the
241 initialization cycle failed
243 * @note This function initializes the SD card by following its
244 * initialization and identification state diagram.
245 * CMD0 is sent to reset card.
246 * CMD8 and ACDM41 are sent to identify voltage and
247 * high capacity support
248 * CMD2 and CMD3 are sent to obtain Card ID and
249 * Relative card address respectively.
250 * CMD9 is sent to read the card specific data.
252 ******************************************************************************/
253 int XSdPs_SdCardInitialize(XSdPs *InstancePtr)
260 Xil_AssertNonvoid(InstancePtr != NULL);
261 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
264 * Check the present state register to make sure
265 * card is inserted and detected by host controller
267 PresentStateReg = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
268 XSDPS_PRES_STATE_OFFSET);
269 if ((PresentStateReg & XSDPS_PSR_CARD_INSRT_MASK) == 0) {
270 Status = XST_FAILURE;
275 * 74 CLK delay after card is powered up, before the first command.
280 usleep(XSDPS_INIT_DELAY);
284 #ifdef __MICROBLAZE__
292 * CMD0 no response expected
294 Status = XSdPs_CmdTransfer(InstancePtr, CMD0, 0, 0);
295 if (Status != XST_SUCCESS) {
296 Status = XST_FAILURE;
301 * CMD8; response expected
302 * 0x1AA - Supply Voltage 2.7 - 3.6V and AA is pattern
304 Status = XSdPs_CmdTransfer(InstancePtr, CMD8,
305 XSDPS_CMD8_VOL_PATTERN, 0);
306 if (Status != XST_SUCCESS) {
307 Status = XST_FAILURE;
311 RespOCR = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
313 if (RespOCR != XSDPS_CMD8_VOL_PATTERN) {
314 Status = XST_FAILURE;
320 * Send ACMD41 while card is still busy with power up
322 while ((RespOCR & XSDPS_RESPOCR_READY) == 0) {
323 Status = XSdPs_CmdTransfer(InstancePtr, CMD55, 0, 0);
324 if (Status != XST_SUCCESS) {
325 Status = XST_FAILURE;
330 * 0x40300000 - Host High Capacity support & 3.3V window
332 Status = XSdPs_CmdTransfer(InstancePtr, ACMD41,
333 (XSDPS_ACMD41_HCS | XSDPS_ACMD41_3V3), 0);
334 if (Status != XST_SUCCESS) {
335 Status = XST_FAILURE;
340 * Response with card capacity
342 RespOCR = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
348 * Update HCS support flag based on card capacity response
350 if (RespOCR & XSDPS_ACMD41_HCS)
351 InstancePtr->HCS = 1;
356 Status = XSdPs_CmdTransfer(InstancePtr, CMD2, 0, 0);
357 if (Status != XST_SUCCESS) {
358 Status = XST_FAILURE;
362 InstancePtr->CardID[0] =
363 XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
365 InstancePtr->CardID[1] =
366 XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
368 InstancePtr->CardID[2] =
369 XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
371 InstancePtr->CardID[3] =
372 XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
375 while (InstancePtr->RelCardAddr == 0) {
376 Status = XSdPs_CmdTransfer(InstancePtr, CMD3, 0, 0);
377 if (Status != XST_SUCCESS) {
378 Status = XST_FAILURE;
383 * Relative card address is stored as the upper 16 bits
384 * This is to avoid shifting when sending commands
386 InstancePtr->RelCardAddr =
387 XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
388 XSDPS_RESP0_OFFSET) & 0xFFFF0000;
391 Status = XSdPs_CmdTransfer(InstancePtr, CMD9, (InstancePtr->RelCardAddr), 0);
392 if (Status != XST_SUCCESS) {
393 Status = XST_FAILURE;
398 * Card specific data is read.
399 * Currently not used for any operation.
401 CSD[0] = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
403 CSD[1] = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
405 CSD[2] = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
407 CSD[3] = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
410 Status = XST_SUCCESS;
417 /*****************************************************************************/
419 * This function does SD command generation.
421 * @param InstancePtr is a pointer to the instance to be worked on.
422 * @param Cmd is the command to be sent.
423 * @param Arg is the argument to be sent along with the command.
424 * This could be address or any other information
425 * @param BlkCnt - Block count passed by the user.
428 * - XST_SUCCESS if initialization was successful
429 * - XST_FAILURE if failure - could be because another transfer
430 * is in progress or command or data inhibit is set
432 ******************************************************************************/
433 int XSdPs_CmdTransfer(XSdPs *InstancePtr, u32 Cmd, u32 Arg, u32 BlkCnt)
440 Xil_AssertNonvoid(InstancePtr != NULL);
441 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
444 * Check the command inhibit to make sure no other
445 * command transfer is in progress
447 PresentStateReg = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
448 XSDPS_PRES_STATE_OFFSET);
449 if (PresentStateReg & XSDPS_PSR_INHIBIT_CMD_MASK) {
450 Status = XST_FAILURE;
455 * Write block count register
457 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
458 XSDPS_BLK_CNT_OFFSET, BlkCnt);
460 XSdPs_WriteReg8(InstancePtr->Config.BaseAddress,
461 XSDPS_TIMEOUT_CTRL_OFFSET, 0xE);
464 * Write argument register
466 XSdPs_WriteReg(InstancePtr->Config.BaseAddress,
467 XSDPS_ARGMT_OFFSET, Arg);
469 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
470 XSDPS_NORM_INTR_STS_OFFSET, XSDPS_NORM_INTR_ALL_MASK);
471 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
472 XSDPS_ERR_INTR_STS_OFFSET, XSDPS_ERROR_INTR_ALL_MASK);
474 * Command register is set to trigger transfer of command
476 CommandReg = XSdPs_FrameCmd(Cmd);
479 * Mask to avoid writing to reserved bits 31-30
480 * This is necessary because 0x80000000 is used by this software to
481 * distinguish between ACMD and CMD of same number
483 CommandReg = CommandReg & 0x3FFF;
486 * Check for data inhibit in case of command using DAT lines
488 PresentStateReg = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
489 XSDPS_PRES_STATE_OFFSET);
490 if ((PresentStateReg & XSDPS_PSR_INHIBIT_CMD_MASK) &&
491 (CommandReg & XSDPS_DAT_PRESENT_SEL_MASK)) {
492 Status = XST_FAILURE;
496 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress, XSDPS_CMD_OFFSET,
500 * Polling for response for now
503 StatusReg = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
504 XSDPS_NORM_INTR_STS_OFFSET);
506 if (StatusReg & XSDPS_INTR_ERR_MASK) {
509 * Write to clear error bits
511 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
512 XSDPS_ERR_INTR_STS_OFFSET,
513 XSDPS_ERROR_INTR_ALL_MASK);
514 Status = XST_FAILURE;
517 } while((StatusReg & XSDPS_INTR_CC_MASK) == 0);
521 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
522 XSDPS_NORM_INTR_STS_OFFSET,
525 Status = XST_SUCCESS;
532 /*****************************************************************************/
534 * This function frames the Command register for a particular command.
535 * Note that this generates only the command register value i.e.
536 * the upper 16 bits of the transfer mode and command register.
537 * This value is already shifted to be upper 16 bits and can be directly
538 * OR'ed with transfer mode register value.
540 * @param Command to be sent.
542 * @return Command register value complete with response type and
543 * data, CRC and index related flags.
545 ******************************************************************************/
546 u32 XSdPs_FrameCmd(u32 Cmd)
574 RetVal |= RESP_R1 | XSDPS_DAT_PRESENT_SEL_MASK;
595 RetVal |= RESP_R1 | XSDPS_DAT_PRESENT_SEL_MASK;
610 RetVal |= RESP_R1 | XSDPS_DAT_PRESENT_SEL_MASK;
616 RetVal |= RESP_R1 | XSDPS_DAT_PRESENT_SEL_MASK;
624 RetVal |= RESP_R1 | XSDPS_DAT_PRESENT_SEL_MASK;
637 /*****************************************************************************/
639 * This function performs SD read in polled mode.
641 * @param InstancePtr is a pointer to the instance to be worked on.
642 * @param Arg is the address passed by the user that is to be sent as
643 * argument along with the command.
644 * @param BlkCnt - Block count passed by the user.
645 * @param Buff - Pointer to the data buffer for a DMA transfer.
648 * - XST_SUCCESS if initialization was successful
649 * - XST_FAILURE if failure - could be because another transfer
650 * is in progress or command or data inhibit is set
652 ******************************************************************************/
653 int XSdPs_ReadPolled(XSdPs *InstancePtr, u32 Arg, u32 BlkCnt, u8 *Buff)
660 * Check status to ensure card is initialized
662 PresentStateReg = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
663 XSDPS_PRES_STATE_OFFSET);
664 if ((PresentStateReg & XSDPS_PSR_CARD_INSRT_MASK) == 0x0) {
665 Status = XST_FAILURE;
670 * Set block size to 512 if not already set
672 if( XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
673 XSDPS_BLK_SIZE_OFFSET) != XSDPS_BLK_SIZE_512_MASK ) {
674 Status = XSdPs_SetBlkSize(InstancePtr,
675 XSDPS_BLK_SIZE_512_MASK);
676 if (Status != XST_SUCCESS) {
677 Status = XST_FAILURE;
682 XSdPs_SetupADMA2DescTbl(InstancePtr, BlkCnt, Buff);
684 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
685 XSDPS_XFER_MODE_OFFSET,
686 XSDPS_TM_AUTO_CMD12_EN_MASK |
687 XSDPS_TM_BLK_CNT_EN_MASK | XSDPS_TM_DAT_DIR_SEL_MASK |
688 XSDPS_TM_DMA_EN_MASK | XSDPS_TM_MUL_SIN_BLK_SEL_MASK);
691 * Send block read command
693 Status = XSdPs_CmdTransfer(InstancePtr, CMD18, Arg, BlkCnt);
694 if (Status != XST_SUCCESS) {
695 Status = XST_FAILURE;
700 * Check for transfer complete
703 StatusReg = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
704 XSDPS_NORM_INTR_STS_OFFSET);
705 if (StatusReg & XSDPS_INTR_ERR_MASK) {
707 * Write to clear error bits
709 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
710 XSDPS_ERR_INTR_STS_OFFSET,
711 XSDPS_ERROR_INTR_ALL_MASK);
712 Status = XST_FAILURE;
715 } while((StatusReg & XSDPS_INTR_TC_MASK) == 0);
720 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
721 XSDPS_NORM_INTR_STS_OFFSET, XSDPS_INTR_TC_MASK);
722 Status = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
725 Status = XST_SUCCESS;
731 /*****************************************************************************/
733 * This function performs SD write in polled mode.
735 * @param InstancePtr is a pointer to the instance to be worked on.
736 * @param Arg is the address passed by the user that is to be sent as
737 * argument along with the command.
738 * @param BlkCnt - Block count passed by the user.
739 * @param Buff - Pointer to the data buffer for a DMA transfer.
742 * - XST_SUCCESS if initialization was successful
743 * - XST_FAILURE if failure - could be because another transfer
744 * is in progress or command or data inhibit is set
746 ******************************************************************************/
747 int XSdPs_WritePolled(XSdPs *InstancePtr, u32 Arg, u32 BlkCnt, const u8 *Buff)
754 * Check status to ensure card is initialized
756 PresentStateReg = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
757 XSDPS_PRES_STATE_OFFSET);
758 if ((PresentStateReg & XSDPS_PSR_CARD_INSRT_MASK) == 0x0) {
759 Status = XST_FAILURE;
764 * Set block size to 512 if not already set
766 if( XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
767 XSDPS_BLK_SIZE_OFFSET) != XSDPS_BLK_SIZE_512_MASK ) {
768 Status = XSdPs_SetBlkSize(InstancePtr,
769 XSDPS_BLK_SIZE_512_MASK);
770 if (Status != XST_SUCCESS) {
771 Status = XST_FAILURE;
777 XSdPs_SetupADMA2DescTbl(InstancePtr, BlkCnt, Buff);
779 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
780 XSDPS_XFER_MODE_OFFSET,
781 XSDPS_TM_AUTO_CMD12_EN_MASK |
782 XSDPS_TM_BLK_CNT_EN_MASK |
783 XSDPS_TM_MUL_SIN_BLK_SEL_MASK | XSDPS_TM_DMA_EN_MASK);
786 * Send block write command
788 Status = XSdPs_CmdTransfer(InstancePtr, CMD25, Arg, BlkCnt);
789 if (Status != XST_SUCCESS) {
790 Status = XST_FAILURE;
795 * Check for transfer complete
796 * Polling for response for now
799 StatusReg = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
800 XSDPS_NORM_INTR_STS_OFFSET);
801 if (StatusReg & XSDPS_INTR_ERR_MASK) {
803 * Write to clear error bits
805 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
806 XSDPS_ERR_INTR_STS_OFFSET,
807 XSDPS_ERROR_INTR_ALL_MASK);
808 Status = XST_FAILURE;
811 } while((StatusReg & XSDPS_INTR_TC_MASK) == 0);
816 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
817 XSDPS_NORM_INTR_STS_OFFSET, XSDPS_INTR_TC_MASK);
819 Status = XST_SUCCESS;
825 /*****************************************************************************/
828 * Selects card and sets default block size
831 * @param InstancePtr is a pointer to the XSdPs instance.
834 * - XST_SUCCESS if successful.
835 * - XST_FAILURE if fail.
839 ******************************************************************************/
840 int XSdPs_Select_Card (XSdPs *InstancePtr)
845 * Send CMD7 - Select card
847 Status = XSdPs_CmdTransfer(InstancePtr, CMD7,
848 InstancePtr->RelCardAddr, 0);
849 if (Status != XST_SUCCESS) {
850 Status = XST_FAILURE;
854 Status = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
858 * Set default block size
860 Status = XSdPs_SetBlkSize(InstancePtr, XSDPS_BLK_SIZE_512_MASK);
861 if (Status != XST_SUCCESS) {
862 Status = XST_FAILURE;
866 Status = XST_SUCCESS;
873 /*****************************************************************************/
876 * API to setup ADMA2 descriptor table
879 * @param InstancePtr is a pointer to the XSdPs instance.
880 * @param BlkCnt - block count.
881 * @param Buff pointer to data buffer.
887 ******************************************************************************/
888 void XSdPs_SetupADMA2DescTbl(XSdPs *InstancePtr, u32 BlkCnt, const u8 *Buff)
890 u32 TotalDescLines = 0;
895 * Setup ADMA2 - Write descriptor table and point ADMA SAR to it
897 BlkSize = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
898 XSDPS_BLK_SIZE_OFFSET);
899 BlkSize = BlkSize & XSDPS_BLK_SIZE_MASK;
901 if((BlkCnt*BlkSize) < XSDPS_DESC_MAX_LENGTH) {
907 TotalDescLines = ((BlkCnt*BlkSize) / XSDPS_DESC_MAX_LENGTH);
908 if ((BlkCnt * BlkSize) % XSDPS_DESC_MAX_LENGTH)
913 for (DescNum = 0; DescNum < (TotalDescLines-1); DescNum++) {
914 InstancePtr->Adma2_DescrTbl[DescNum].Address =
915 (u32)(Buff + (DescNum*XSDPS_DESC_MAX_LENGTH));
916 InstancePtr->Adma2_DescrTbl[DescNum].Attribute =
917 XSDPS_DESC_TRAN | XSDPS_DESC_VALID;
919 * This will write '0' to length field which indicates 65536
921 InstancePtr->Adma2_DescrTbl[DescNum].Length =
922 (u16)XSDPS_DESC_MAX_LENGTH;
925 InstancePtr->Adma2_DescrTbl[TotalDescLines-1].Address =
926 (u32)(Buff + (DescNum*XSDPS_DESC_MAX_LENGTH));
928 InstancePtr->Adma2_DescrTbl[TotalDescLines-1].Attribute =
929 XSDPS_DESC_TRAN | XSDPS_DESC_END | XSDPS_DESC_VALID;
931 InstancePtr->Adma2_DescrTbl[TotalDescLines-1].Length =
932 (BlkCnt*BlkSize) - (DescNum*XSDPS_DESC_MAX_LENGTH);
935 XSdPs_WriteReg(InstancePtr->Config.BaseAddress, XSDPS_ADMA_SAR_OFFSET,
936 (u32)&(InstancePtr->Adma2_DescrTbl[0]));
940 /*****************************************************************************/
942 * Mmc initialization is done in this function
945 * @param InstancePtr is a pointer to the instance to be worked on.
948 * - XST_SUCCESS if initialization was successful
949 * - XST_FAILURE if failure - could be because
950 * a) MMC is already initialized
951 * b) There is no card inserted
952 * c) One of the steps (commands) in the initialization
954 * @note This function initializes the SD card by following its
955 * initialization and identification state diagram.
956 * CMD0 is sent to reset card.
957 * CMD1 sent to identify voltage and high capacity support
958 * CMD2 and CMD3 are sent to obtain Card ID and
959 * Relative card address respectively.
960 * CMD9 is sent to read the card specific data.
962 ******************************************************************************/
963 int XSdPs_MmcCardInitialize(XSdPs *InstancePtr)
970 Xil_AssertNonvoid(InstancePtr != NULL);
971 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
974 * Check the present state register to make sure
975 * card is inserted and detected by host controller
977 PresentStateReg = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
978 XSDPS_PRES_STATE_OFFSET);
979 if ((PresentStateReg & XSDPS_PSR_CARD_INSRT_MASK) == 0) {
980 Status = XST_FAILURE;
985 * 74 CLK delay after card is powered up, before the first command.
990 usleep(XSDPS_INIT_DELAY);
994 #ifdef __MICROBLAZE__
1002 * CMD0 no response expected
1004 Status = XSdPs_CmdTransfer(InstancePtr, CMD0, 0, 0);
1005 if (Status != XST_SUCCESS) {
1006 Status = XST_FAILURE;
1012 * Send CMD1 while card is still busy with power up
1014 while ((RespOCR & XSDPS_RESPOCR_READY) == 0) {
1017 * Host High Capacity support & High volage window
1019 Status = XSdPs_CmdTransfer(InstancePtr, CMD1,
1020 XSDPS_ACMD41_HCS | XSDPS_CMD1_HIGH_VOL, 0);
1021 if (Status != XST_SUCCESS) {
1022 Status = XST_FAILURE;
1027 * Response with card capacity
1029 RespOCR = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
1030 XSDPS_RESP0_OFFSET);
1035 * Update HCS support flag based on card capacity response
1037 if (RespOCR & XSDPS_ACMD41_HCS)
1038 InstancePtr->HCS = 1;
1043 Status = XSdPs_CmdTransfer(InstancePtr, CMD2, 0, 0);
1044 if (Status != XST_SUCCESS) {
1045 Status = XST_FAILURE;
1049 InstancePtr->CardID[0] =
1050 XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
1051 XSDPS_RESP0_OFFSET);
1052 InstancePtr->CardID[1] =
1053 XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
1054 XSDPS_RESP1_OFFSET);
1055 InstancePtr->CardID[2] =
1056 XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
1057 XSDPS_RESP2_OFFSET);
1058 InstancePtr->CardID[3] =
1059 XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
1060 XSDPS_RESP3_OFFSET);
1062 Status = XSdPs_CmdTransfer(InstancePtr, CMD3, 0, 0);
1063 if (Status != XST_SUCCESS) {
1064 Status = XST_FAILURE;
1069 * Relative card address is stored as the upper 16 bits
1070 * This is to avoid shifting when sending commands
1072 InstancePtr->RelCardAddr =
1073 XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
1074 XSDPS_RESP0_OFFSET) & 0xFFFF0000;
1076 Status = XSdPs_CmdTransfer(InstancePtr, CMD9, (InstancePtr->RelCardAddr), 0);
1077 if (Status != XST_SUCCESS) {
1078 Status = XST_FAILURE;
1083 * Card specific data is read.
1084 * Currently not used for any operation.
1086 CSD[0] = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
1087 XSDPS_RESP0_OFFSET);
1088 CSD[1] = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
1089 XSDPS_RESP1_OFFSET);
1090 CSD[2] = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
1091 XSDPS_RESP2_OFFSET);
1092 CSD[3] = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
1093 XSDPS_RESP3_OFFSET);
1095 Status = XST_SUCCESS;