]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_R5_UltraScale_MPSoC/RTOSDemo_R5_bsp/psu_cortexr5_0/libsrc/sdps_v2_7/src/xsdps.c
Update some more standard demos for use on 64-bit architectures.
[freertos] / FreeRTOS / Demo / CORTEX_R5_UltraScale_MPSoC / RTOSDemo_R5_bsp / psu_cortexr5_0 / libsrc / sdps_v2_7 / src / xsdps.c
1 /******************************************************************************
2 *
3 * Copyright (C) 2013 - 2015 Xilinx, Inc.  All rights reserved.
4 *
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:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
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.
18 *
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
25 * SOFTWARE.
26 *
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.
30 *
31 ******************************************************************************/
32 /*****************************************************************************/
33 /**
34 *
35 * @file xsdps.c
36 * @addtogroup sdps_v2_5
37 * @{
38 *
39 * Contains the interface functions of the XSdPs driver.
40 * See xsdps.h for a detailed description of the device and driver.
41 *
42 * <pre>
43 * MODIFICATION HISTORY:
44 *
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
54 *                                               clock.CR# 816586.
55 * 2.4   sk         12/04/14 Added support for micro SD without
56 *                                               WP/CD. CR# 810655.
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.
67 * </pre>
68 *
69 ******************************************************************************/
70
71 /***************************** Include Files *********************************/
72 #include "xsdps.h"
73 /*
74  * The header sleep.h and API usleep() can only be used with an arm design.
75  * MB_Sleep() is used for microblaze design.
76  */
77 #if defined (__arm__) || defined (__aarch64__)
78
79 #include "sleep.h"
80
81 #endif
82
83 #ifdef __MICROBLAZE__
84
85 #include "microblaze_sleep.h"
86
87 #endif
88
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
107
108 /* Note: Remove this once fixed */
109 #define UHS_BROKEN
110
111 /**************************** Type Definitions *******************************/
112
113 /***************** Macros (Inline Functions) Definitions *********************/
114
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);
122
123 /*****************************************************************************/
124 /**
125 *
126 * Initializes a specific XSdPs instance such that the driver is ready to use.
127 *
128 *
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.
141 *
142 * @return
143 *               - XST_SUCCESS if successful.
144 *               - XST_DEVICE_IS_STARTED if the device is already started.
145 *               It must be stopped to re-initialize.
146 *
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.
153 *
154 ******************************************************************************/
155 s32 XSdPs_CfgInitialize(XSdPs *InstancePtr, XSdPs_Config *ConfigPtr,
156                                 u32 EffectiveAddr)
157 {
158         s32 Status;
159         u8 PowerLevel;
160         u8 ReadReg;
161
162         Xil_AssertNonvoid(InstancePtr != NULL);
163         Xil_AssertNonvoid(ConfigPtr != NULL);
164
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;
171
172         /* Disable bus power */
173         XSdPs_WriteReg8(InstancePtr->Config.BaseAddress,
174                         XSDPS_POWER_CTRL_OFFSET, 0U);
175
176         /* Delay to poweroff card */
177 #if defined (__arm__) || defined (__aarch64__)
178
179     (void)sleep(1U);
180
181 #endif
182
183 #ifdef __MICROBLAZE__
184
185     MB_Sleep(1000U);
186
187 #endif
188
189         /* "Software reset for all" is initiated */
190         XSdPs_WriteReg8(InstancePtr->Config.BaseAddress, XSDPS_SW_RST_OFFSET,
191                         XSDPS_SWRST_ALL_MASK);
192
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);
199         }
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);
204
205         /*
206          * Read capabilities register and update it in Instance pointer.
207          * It is sufficient to read this once on power on.
208          */
209         InstancePtr->Host_Caps = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
210                                                 XSDPS_CAPS_OFFSET);
211
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);
216
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;
221                 goto RETURN_PATH ;
222         }
223
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;
230         } else {
231                 PowerLevel = 0U;
232         }
233
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);
242
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));
247
248         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
249                         XSDPS_ERR_INTR_STS_EN_OFFSET,
250                         XSDPS_ERROR_INTR_ALL_MASK);
251
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);
257
258         /*
259          * Transfer mode register - default value
260          * DMA enabled, block count enabled, data direction card to host(read)
261          */
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);
266
267         /* Set block size to 512 by default */
268         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
269                         XSDPS_BLK_SIZE_OFFSET, XSDPS_BLK_SIZE_512_MASK);
270
271         Status = XST_SUCCESS;
272
273 RETURN_PATH:
274         return Status;
275
276 }
277
278 /*****************************************************************************/
279 /**
280 * SD initialization is done in this function
281 *
282 *
283 * @param        InstancePtr is a pointer to the instance to be worked on.
284 *
285 * @return
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
292 *
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.
301 *
302 ******************************************************************************/
303 s32 XSdPs_SdCardInitialize(XSdPs *InstancePtr)
304 {
305         u32 PresentStateReg;
306         s32 Status;
307         u32 RespOCR;
308         u32 CSD[4];
309         u32 Arg;
310         u8 ReadReg;
311
312         Xil_AssertNonvoid(InstancePtr != NULL);
313         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
314
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) {
319                         /*
320                          * Check the present state register to make sure
321                          * card is inserted and detected by host controller
322                          */
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;
327                                 goto RETURN_PATH;
328                         }
329                 }
330         }
331
332         /* CMD0 no response expected */
333         Status = XSdPs_CmdTransfer(InstancePtr, (u32)CMD0, 0U, 0U);
334         if (Status != XST_SUCCESS) {
335                 Status = XST_FAILURE;
336                 goto RETURN_PATH;
337         }
338
339         /*
340          * CMD8; response expected
341          * 0x1AA - Supply Voltage 2.7 - 3.6V and AA is pattern
342          */
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;
347                 goto RETURN_PATH;
348         }
349
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);
354
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);
361                 }
362         }
363
364         RespOCR = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
365                                                 XSDPS_RESP0_OFFSET);
366         if (RespOCR != XSDPS_CMD8_VOL_PATTERN) {
367                 InstancePtr->Card_Version = XSDPS_SD_VER_1_0;
368         }
369         else {
370                 InstancePtr->Card_Version = XSDPS_SD_VER_2_0;
371         }
372
373         RespOCR = 0U;
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;
379                         goto RETURN_PATH;
380                 }
381
382         Arg = XSDPS_ACMD41_HCS | XSDPS_ACMD41_3V3 | (0x1FFU << 15U);
383                 if (InstancePtr->HC_Version == XSDPS_HC_SPEC_V3) {
384                     Arg |= XSDPS_OCR_S18;
385                 }
386
387                 /* 0x40300000 - Host High Capacity support & 3.3V window */
388                 Status = XSdPs_CmdTransfer(InstancePtr, ACMD41,
389                                 Arg, 0U);
390                 if (Status != XST_SUCCESS) {
391                         Status = XST_FAILURE;
392                         goto RETURN_PATH;
393                 }
394
395                 /* Response with card capacity */
396                 RespOCR = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
397                                 XSDPS_RESP0_OFFSET);
398
399         }
400
401         /* Update HCS support flag based on card capacity response */
402         if ((RespOCR & XSDPS_ACMD41_HCS) != 0U) {
403                 InstancePtr->HCS = 1U;
404         }
405
406         /* There is no support to switch to 1.8V and use UHS mode on 1.0 silicon */
407 #ifndef UHS_BROKEN
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;
413                         goto RETURN_PATH;
414                 }
415
416         }
417 #endif
418
419         /* CMD2 for Card ID */
420         Status = XSdPs_CmdTransfer(InstancePtr, CMD2, 0U, 0U);
421         if (Status != XST_SUCCESS) {
422                 Status = XST_FAILURE;
423                 goto RETURN_PATH;
424         }
425
426         InstancePtr->CardID[0] =
427                         XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
428                         XSDPS_RESP0_OFFSET);
429         InstancePtr->CardID[1] =
430                         XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
431                         XSDPS_RESP1_OFFSET);
432         InstancePtr->CardID[2] =
433                         XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
434                         XSDPS_RESP2_OFFSET);
435         InstancePtr->CardID[3] =
436                         XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
437                         XSDPS_RESP3_OFFSET);
438         do {
439                 Status = XSdPs_CmdTransfer(InstancePtr, CMD3, 0U, 0U);
440                 if (Status != XST_SUCCESS) {
441                         Status = XST_FAILURE;
442                         goto RETURN_PATH;
443                 }
444
445                 /*
446                  * Relative card address is stored as the upper 16 bits
447                  * This is to avoid shifting when sending commands
448                  */
449                 InstancePtr->RelCardAddr =
450                                 XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
451                                         XSDPS_RESP0_OFFSET) & 0xFFFF0000U;
452         } while (InstancePtr->RelCardAddr == 0U);
453
454         Status = XSdPs_CmdTransfer(InstancePtr, CMD9, (InstancePtr->RelCardAddr), 0U);
455         if (Status != XST_SUCCESS) {
456                 Status = XST_FAILURE;
457                 goto RETURN_PATH;
458         }
459
460         /*
461          * Card specific data is read.
462          * Currently not used for any operation.
463          */
464         CSD[0] = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
465                         XSDPS_RESP0_OFFSET);
466         CSD[1] = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
467                         XSDPS_RESP1_OFFSET);
468         CSD[2] = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
469                         XSDPS_RESP2_OFFSET);
470         CSD[3] = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
471                         XSDPS_RESP3_OFFSET);
472
473         Status = XST_SUCCESS;
474
475 RETURN_PATH:
476         return Status;
477
478 }
479
480 /*****************************************************************************/
481 /**
482 *
483 * Initialize Card with Identification mode sequence
484 *
485 *
486 * @param        InstancePtr is a pointer to the instance to be worked on.
487 *
488 * @return
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
495 *
496 *
497 ******************************************************************************/
498 s32 XSdPs_CardInitialize(XSdPs *InstancePtr) {
499         u8 Tmp;
500         u32 Cnt;
501         u32 PresentStateReg;
502         u32 CtrlReg;
503         u32 CSD[4];
504 #ifdef __ICCARM__
505 #pragma data_alignment = 32
506 static u8 ExtCsd[512];
507 #pragma data_alignment = 4
508 #else
509 static u8 ExtCsd[512] __attribute__ ((aligned(32)));
510 #endif
511         u8 SCR[8] = { 0U };
512         u8 ReadBuff[64] = { 0U };
513         s32 Status;
514
515         Xil_AssertNonvoid(InstancePtr != NULL);
516         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
517
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;
523
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;
528         } else {
529                 Status = XSdPs_IdentifyCard(InstancePtr);
530                 if (Status == XST_FAILURE) {
531                         goto RETURN_PATH;
532                 }
533         }
534
535         if ((InstancePtr->CardType != XSDPS_CARD_SD) &&
536                 (InstancePtr->CardType != XSDPS_CARD_MMC) &&
537                 (InstancePtr->CardType != XSDPS_CHIP_EMMC)) {
538                 Status = XST_FAILURE;
539                 goto RETURN_PATH;
540         }
541
542         if (InstancePtr->CardType == XSDPS_CARD_SD) {
543                 Status = XSdPs_SdCardInitialize(InstancePtr);
544                 if (Status != XST_SUCCESS) {
545                         Status = XST_FAILURE;
546                         goto RETURN_PATH;
547                 }
548
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;
554                         goto RETURN_PATH;
555                 }
556
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;
562                         goto RETURN_PATH;
563                 }
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;
569                         goto RETURN_PATH;
570                 }
571         } else {
572                 Status = XST_FAILURE;
573                 goto RETURN_PATH;
574         }
575
576         Status = XSdPs_Select_Card(InstancePtr);
577         if (Status != XST_SUCCESS) {
578                 Status = XST_FAILURE;
579                 goto RETURN_PATH;
580         }
581
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;
587                         goto RETURN_PATH;
588                 }
589
590                 Status = XSdPs_Get_BusWidth(InstancePtr, SCR);
591                 if (Status != XST_SUCCESS) {
592                         Status = XST_FAILURE;
593                         goto RETURN_PATH;
594                 }
595
596                 if ((SCR[1] & WIDTH_4_BIT_SUPPORT) != 0U) {
597                         Status = XSdPs_Change_BusWidth(InstancePtr);
598                         if (Status != XST_SUCCESS) {
599                                 Status = XST_FAILURE;
600                                 goto RETURN_PATH;
601                         }
602                 }
603
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;
611                                 goto RETURN_PATH;
612                         }
613
614                 } else {
615
616                         /*
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.
620                          */
621                         if (SCR[0] != 0U) {
622                                 /* Get speed supported by device */
623                                 Status = XSdPs_Get_BusSpeed(InstancePtr, ReadBuff);
624                                 if (Status != XST_SUCCESS) {
625                                         Status = XST_FAILURE;
626                                         goto RETURN_PATH;
627                                 }
628
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;
634                                                 goto RETURN_PATH;
635                                         }
636                                 }
637                         }
638                 }
639
640         } else if (((InstancePtr->CardType == XSDPS_CARD_MMC) &&
641                                 (InstancePtr->Card_Version > CSD_SPEC_VER_3)) &&
642                                 (InstancePtr->HC_Version == XSDPS_HC_SPEC_V2)) {
643
644                 Status = XSdPs_Change_BusWidth(InstancePtr);
645                 if (Status != XST_SUCCESS) {
646                         Status = XST_FAILURE;
647                         goto RETURN_PATH;
648                 }
649
650                 Status = XSdPs_Get_Mmc_ExtCsd(InstancePtr, ExtCsd);
651                 if (Status != XST_SUCCESS) {
652                         Status = XST_FAILURE;
653                         goto RETURN_PATH;
654                 }
655
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;
661                                 goto RETURN_PATH;
662                         }
663
664                         Status = XSdPs_Get_Mmc_ExtCsd(InstancePtr, ExtCsd);
665                         if (Status != XST_SUCCESS) {
666                                 Status = XST_FAILURE;
667                                 goto RETURN_PATH;
668                         }
669
670                         if (ExtCsd[EXT_CSD_HS_TIMING_BYTE] != EXT_CSD_HS_TIMING_HIGH) {
671                                 Status = XST_FAILURE;
672                                 goto RETURN_PATH;
673                         }
674                 }
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;
680                         goto RETURN_PATH;
681                 }
682
683                 /* Get Extended CSD */
684                 Status = XSdPs_Get_Mmc_ExtCsd(InstancePtr, ExtCsd);
685                 if (Status != XST_SUCCESS) {
686                         Status = XST_FAILURE;
687                         goto RETURN_PATH;
688                 }
689
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;
696                                 goto RETURN_PATH;
697                         }
698
699                         Status = XSdPs_Get_Mmc_ExtCsd(InstancePtr, ExtCsd);
700                         if (Status != XST_SUCCESS) {
701                                 Status = XST_FAILURE;
702                                 goto RETURN_PATH;
703                         }
704
705                         if (ExtCsd[EXT_CSD_HS_TIMING_BYTE] != EXT_CSD_HS_TIMING_HS200) {
706                                 Status = XST_FAILURE;
707                                 goto RETURN_PATH;
708                         }
709                 }
710         }
711
712         Status = XSdPs_SetBlkSize(InstancePtr, XSDPS_BLK_SIZE_512_MASK);
713         if (Status != XST_SUCCESS) {
714                 Status = XST_FAILURE;
715                 goto RETURN_PATH;
716         }
717
718 RETURN_PATH:
719         return Status;
720 }
721
722 /*****************************************************************************/
723 /**
724 *
725 * Identify type of card using CMD0 + CMD1 sequence
726 *
727 *
728 * @param        InstancePtr is a pointer to the XSdPs instance.
729 *
730 ******************************************************************************/
731 static s32 XSdPs_IdentifyCard(XSdPs *InstancePtr)
732 {
733         s32 Status;
734         u32 OperCondReg;
735         u8 ReadReg;
736
737         Xil_AssertNonvoid(InstancePtr != NULL);
738         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
739
740         /* 74 CLK delay after card is powered up, before the first command. */
741 #if defined (__arm__) || defined (__aarch64__)
742
743         usleep(XSDPS_INIT_DELAY);
744
745 #endif
746
747 #ifdef __MICROBLAZE__
748
749         /* 2 msec delay */
750         MB_Sleep(2);
751
752 #endif
753
754         /* CMD0 no response expected */
755         Status = XSdPs_CmdTransfer(InstancePtr, CMD0, 0U, 0U);
756         if (Status != XST_SUCCESS) {
757                 Status = XST_FAILURE;
758                 goto RETURN_PATH;
759         }
760
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;
766         } else {
767                 InstancePtr->CardType = XSDPS_CARD_MMC;
768         }
769
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);
774
775         /* "Software reset for all" is initiated */
776         XSdPs_WriteReg8(InstancePtr->Config.BaseAddress, XSDPS_SW_RST_OFFSET,
777                         XSDPS_SWRST_CMD_LINE_MASK);
778
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);
785         }
786
787         Status = XST_SUCCESS;
788
789 RETURN_PATH:
790         return Status;
791 }
792
793 /*****************************************************************************/
794 /**
795 *
796 * Switches the SD card voltage from 3v3 to 1v8
797 *
798 *
799 * @param        InstancePtr is a pointer to the XSdPs instance.
800 *
801 ******************************************************************************/
802 static s32 XSdPs_Switch_Voltage(XSdPs *InstancePtr)
803 {
804         s32 Status;
805         u16 CtrlReg;
806         u32 ReadReg;
807
808         /* Send switch voltage command */
809         Status = XSdPs_CmdTransfer(InstancePtr, CMD11, 0U, 0U);
810         if (Status != XST_SUCCESS) {
811                 Status = XST_FAILURE;
812         }
813
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);
821         }
822
823         /* Stop the clock */
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,
828                         CtrlReg);
829
830         /* Wait minimum 5mSec */
831 #if defined (__arm__) || defined (__aarch64__)
832
833         (void)usleep(5000U);
834
835 #endif
836
837 #ifdef __MICROBLAZE__
838
839         MB_Sleep(5U);
840
841 #endif
842
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,
848                         CtrlReg);
849
850         /* Start clock */
851         Status = XSdPs_Change_ClkFreq(InstancePtr, XSDPS_CLK_400_KHZ);
852         if (Status != XST_SUCCESS) {
853                 Status = XST_FAILURE;
854                 goto RETURN_PATH;
855         }
856
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);
864         }
865
866 RETURN_PATH:
867         return Status;
868 }
869
870 /*****************************************************************************/
871 /**
872
873 * This function does SD command generation.
874 *
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.
880 *
881 * @return
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
885 *
886 ******************************************************************************/
887 s32 XSdPs_CmdTransfer(XSdPs *InstancePtr, u32 Cmd, u32 Arg, u32 BlkCnt)
888 {
889         u32 PresentStateReg;
890         u32 CommandReg;
891         u32 StatusReg;
892         s32 Status;
893
894         Xil_AssertNonvoid(InstancePtr != NULL);
895         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
896
897         /*
898          * Check the command inhibit to make sure no other
899          * command transfer is in progress
900          */
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;
905                 goto RETURN_PATH;
906         }
907
908         /* Write block count register */
909         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
910                         XSDPS_BLK_CNT_OFFSET, (u16)BlkCnt);
911
912         XSdPs_WriteReg8(InstancePtr->Config.BaseAddress,
913                         XSDPS_TIMEOUT_CTRL_OFFSET, 0xEU);
914
915         /* Write argument register */
916         XSdPs_WriteReg(InstancePtr->Config.BaseAddress,
917                         XSDPS_ARGMT_OFFSET, Arg);
918
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);
925
926         /*
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
930          */
931         CommandReg = CommandReg & 0x3FFFU;
932
933         /*
934          * Check for data inhibit in case of command using DAT lines.
935          * For Tuning Commands DAT lines check can be ignored.
936          */
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;
944                         goto RETURN_PATH;
945                 }
946         }
947
948         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress, XSDPS_CMD_OFFSET,
949                         (u16)CommandReg);
950
951         /* Polling for response for now */
952         do {
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);
960                                 break;
961                         }
962                 }
963
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;
969                         }
970                          /* Write to clear error bits */
971                         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
972                                         XSDPS_ERR_INTR_STS_OFFSET,
973                                         XSDPS_ERROR_INTR_ALL_MASK);
974                         goto RETURN_PATH;
975                 }
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,
980                         XSDPS_INTR_CC_MASK);
981
982         Status = XST_SUCCESS;
983
984 RETURN_PATH:
985                 return Status;
986
987 }
988
989 /*****************************************************************************/
990 /**
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.
996 *
997 * @param        Command to be sent.
998 *
999 * @return       Command register value complete with response type and
1000 *               data, CRC and index related flags.
1001 *
1002 ******************************************************************************/
1003 u32 XSdPs_FrameCmd(XSdPs *InstancePtr, u32 Cmd)
1004 {
1005                 u32 RetVal;
1006
1007                 RetVal = Cmd;
1008
1009                 switch(Cmd) {
1010                 case CMD0:
1011                         RetVal |= RESP_NONE;
1012                 break;
1013                 case CMD1:
1014                         RetVal |= RESP_R3;
1015                 break;
1016                 case CMD2:
1017                         RetVal |= RESP_R2;
1018                 break;
1019                 case CMD3:
1020                         RetVal |= RESP_R6;
1021                 break;
1022                 case CMD4:
1023                         RetVal |= RESP_NONE;
1024                         break;
1025                 case CMD5:
1026                         RetVal |= RESP_R1B;
1027                 break;
1028                 case CMD6:
1029                         if (InstancePtr->CardType == XSDPS_CARD_SD) {
1030                                 RetVal |= RESP_R1 | (u32)XSDPS_DAT_PRESENT_SEL_MASK;
1031                         } else {
1032                                 RetVal |= RESP_R1B;
1033                         }
1034                         break;
1035                 case ACMD6:
1036                         RetVal |= RESP_R1;
1037                 break;
1038                 case CMD7:
1039                         RetVal |= RESP_R1;
1040                 break;
1041                 case CMD8:
1042                         if (InstancePtr->CardType == XSDPS_CARD_SD) {
1043                                 RetVal |= RESP_R1;
1044                         } else {
1045                                 RetVal |= RESP_R1 | (u32)XSDPS_DAT_PRESENT_SEL_MASK;
1046                         }
1047                         break;
1048                 case CMD9:
1049                         RetVal |= RESP_R2;
1050                 break;
1051                 case CMD11:
1052                 case CMD10:
1053                 case CMD12:
1054                 case ACMD13:
1055                 case CMD16:
1056                         RetVal |= RESP_R1;
1057                 break;
1058                 case CMD17:
1059                 case CMD18:
1060                 case CMD19:
1061                 case CMD21:
1062                         RetVal |= RESP_R1 | (u32)XSDPS_DAT_PRESENT_SEL_MASK;
1063                 break;
1064                 case CMD23:
1065                 case ACMD23:
1066                 case CMD24:
1067                 case CMD25:
1068                         RetVal |= RESP_R1 | (u32)XSDPS_DAT_PRESENT_SEL_MASK;
1069                 case ACMD41:
1070                         RetVal |= RESP_R3;
1071                 break;
1072                 case ACMD42:
1073                         RetVal |= RESP_R1;
1074                 break;
1075                 case ACMD51:
1076                         RetVal |= RESP_R1 | (u32)XSDPS_DAT_PRESENT_SEL_MASK;
1077                 break;
1078                 case CMD52:
1079                 case CMD55:
1080                         RetVal |= RESP_R1;
1081                 break;
1082                 case CMD58:
1083                 break;
1084                 default :
1085                         RetVal |= Cmd;
1086                 break;
1087                 }
1088
1089                 return RetVal;
1090 }
1091
1092 /*****************************************************************************/
1093 /**
1094 * This function performs SD read in polled mode.
1095 *
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.
1101 *
1102 * @return
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
1106 *
1107 ******************************************************************************/
1108 s32 XSdPs_ReadPolled(XSdPs *InstancePtr, u32 Arg, u32 BlkCnt, u8 *Buff)
1109 {
1110         s32 Status;
1111         u32 PresentStateReg;
1112         u32 StatusReg;
1113
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;
1123                                 goto RETURN_PATH;
1124                         }
1125                 }
1126         }
1127
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;
1135                         goto RETURN_PATH;
1136                 }
1137         }
1138
1139         XSdPs_SetupADMA2DescTbl(InstancePtr, BlkCnt, Buff);
1140
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);
1146
1147         Xil_DCacheInvalidateRange((INTPTR)Buff, BlkCnt * XSDPS_BLK_SIZE_512_MASK);
1148
1149         /* Send block read command */
1150         Status = XSdPs_CmdTransfer(InstancePtr, CMD18, Arg, BlkCnt);
1151         if (Status != XST_SUCCESS) {
1152                 Status = XST_FAILURE;
1153                 goto RETURN_PATH;
1154         }
1155
1156         /* Check for transfer complete */
1157         do {
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;
1166                         goto RETURN_PATH;
1167                 }
1168         } while((StatusReg & XSDPS_INTR_TC_MASK) == 0U);
1169
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);
1175
1176         Status = XST_SUCCESS;
1177
1178 RETURN_PATH:
1179         return Status;
1180 }
1181
1182 /*****************************************************************************/
1183 /**
1184 * This function performs SD write in polled mode.
1185 *
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.
1191 *
1192 * @return
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
1196 *
1197 ******************************************************************************/
1198 s32 XSdPs_WritePolled(XSdPs *InstancePtr, u32 Arg, u32 BlkCnt, const u8 *Buff)
1199 {
1200         s32 Status;
1201         u32 PresentStateReg;
1202         u32 StatusReg;
1203
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;
1213                                 goto RETURN_PATH;
1214                         }
1215                 }
1216         }
1217
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;
1225                         goto RETURN_PATH;
1226                 }
1227
1228         }
1229
1230         XSdPs_SetupADMA2DescTbl(InstancePtr, BlkCnt, Buff);
1231         Xil_DCacheFlushRange((INTPTR)Buff, BlkCnt * XSDPS_BLK_SIZE_512_MASK);
1232
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);
1238
1239         /* Send block write command */
1240         Status = XSdPs_CmdTransfer(InstancePtr, CMD25, Arg, BlkCnt);
1241         if (Status != XST_SUCCESS) {
1242                 Status = XST_FAILURE;
1243                 goto RETURN_PATH;
1244         }
1245
1246         /*
1247          * Check for transfer complete
1248          * Polling for response for now
1249          */
1250         do {
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;
1259                         goto RETURN_PATH;
1260                 }
1261         } while((StatusReg & XSDPS_INTR_TC_MASK) == 0U);
1262
1263         /* Write to clear bit */
1264         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
1265                         XSDPS_NORM_INTR_STS_OFFSET, XSDPS_INTR_TC_MASK);
1266
1267         Status = XST_SUCCESS;
1268
1269         RETURN_PATH:
1270                 return Status;
1271 }
1272
1273 /*****************************************************************************/
1274 /**
1275 *
1276 * Selects card and sets default block size
1277 *
1278 *
1279 * @param        InstancePtr is a pointer to the XSdPs instance.
1280 *
1281 * @return
1282 *               - XST_SUCCESS if successful.
1283 *               - XST_FAILURE if fail.
1284 *
1285 * @note         None.
1286 *
1287 ******************************************************************************/
1288 s32 XSdPs_Select_Card (XSdPs *InstancePtr)
1289 {
1290         s32 Status = 0;
1291
1292         /* Send CMD7 - Select card */
1293         Status = XSdPs_CmdTransfer(InstancePtr, CMD7,
1294                         InstancePtr->RelCardAddr, 0U);
1295         if (Status != XST_SUCCESS) {
1296                 Status = XST_FAILURE;
1297                 goto RETURN_PATH;
1298         }
1299
1300 RETURN_PATH:
1301                 return Status;
1302
1303 }
1304
1305 /*****************************************************************************/
1306 /**
1307 *
1308 * API to setup ADMA2 descriptor table
1309 *
1310 *
1311 * @param        InstancePtr is a pointer to the XSdPs instance.
1312 * @param        BlkCnt - block count.
1313 * @param        Buff pointer to data buffer.
1314 *
1315 * @return       None
1316 *
1317 * @note         None.
1318 *
1319 ******************************************************************************/
1320 void XSdPs_SetupADMA2DescTbl(XSdPs *InstancePtr, u32 BlkCnt, const u8 *Buff)
1321 {
1322         u32 TotalDescLines = 0U;
1323         u32 DescNum = 0U;
1324         u32 BlkSize = 0U;
1325
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;
1330
1331         if((BlkCnt*BlkSize) < XSDPS_DESC_MAX_LENGTH) {
1332
1333                 TotalDescLines = 1U;
1334
1335         }else {
1336
1337                 TotalDescLines = ((BlkCnt*BlkSize) / XSDPS_DESC_MAX_LENGTH);
1338                 if (((BlkCnt * BlkSize) % XSDPS_DESC_MAX_LENGTH) != 0U) {
1339                         TotalDescLines += 1U;
1340                 }
1341
1342         }
1343
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;
1352         }
1353
1354         InstancePtr->Adma2_DescrTbl[TotalDescLines-1].Address =
1355                         (u32)((UINTPTR)Buff + (DescNum*XSDPS_DESC_MAX_LENGTH));
1356
1357         InstancePtr->Adma2_DescrTbl[TotalDescLines-1].Attribute =
1358                         XSDPS_DESC_TRAN | XSDPS_DESC_END | XSDPS_DESC_VALID;
1359
1360         InstancePtr->Adma2_DescrTbl[TotalDescLines-1].Length =
1361                         (u16)((BlkCnt*BlkSize) - (DescNum*XSDPS_DESC_MAX_LENGTH));
1362
1363
1364         XSdPs_WriteReg(InstancePtr->Config.BaseAddress, XSDPS_ADMA_SAR_OFFSET,
1365                         (u32)(UINTPTR)&(InstancePtr->Adma2_DescrTbl[0]));
1366
1367         Xil_DCacheFlushRange((INTPTR)&(InstancePtr->Adma2_DescrTbl[0]),
1368                         sizeof(XSdPs_Adma2Descriptor) * 32U);
1369
1370 }
1371
1372 /*****************************************************************************/
1373 /**
1374 * Mmc initialization is done in this function
1375 *
1376 *
1377 * @param        InstancePtr is a pointer to the instance to be worked on.
1378 *
1379 * @return
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
1385 *                          cycle failed
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.
1393 *
1394 ******************************************************************************/
1395 s32 XSdPs_MmcCardInitialize(XSdPs *InstancePtr)
1396 {
1397         u32 PresentStateReg;
1398         s32 Status;
1399         u32 RespOCR;
1400         u32 CSD[4];
1401
1402         Xil_AssertNonvoid(InstancePtr != NULL);
1403         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
1404
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) {
1409                         /*
1410                          * Check the present state register to make sure
1411                          * card is inserted and detected by host controller
1412                          */
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;
1417                                 goto RETURN_PATH;
1418                         }
1419                 }
1420         }
1421
1422         /* CMD0 no response expected */
1423         Status = XSdPs_CmdTransfer(InstancePtr, CMD0, 0U, 0U);
1424         if (Status != XST_SUCCESS) {
1425                 Status = XST_FAILURE;
1426                 goto RETURN_PATH;
1427         }
1428
1429         RespOCR = 0U;
1430         /* Send CMD1 while card is still busy with power up */
1431         while ((RespOCR & XSDPS_RESPOCR_READY) == 0U) {
1432
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;
1438                         goto RETURN_PATH;
1439                 }
1440
1441                 /* Response with card capacity */
1442                 RespOCR = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
1443                                 XSDPS_RESP0_OFFSET);
1444
1445         }
1446
1447         /* Update HCS support flag based on card capacity response */
1448         if ((RespOCR & XSDPS_ACMD41_HCS) != 0U) {
1449                 InstancePtr->HCS = 1U;
1450         }
1451
1452         /* CMD2 for Card ID */
1453         Status = XSdPs_CmdTransfer(InstancePtr, CMD2, 0U, 0U);
1454         if (Status != XST_SUCCESS) {
1455                 Status = XST_FAILURE;
1456                 goto RETURN_PATH;
1457         }
1458
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);
1471
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;
1477                 goto RETURN_PATH;
1478         }
1479
1480         Status = XSdPs_CmdTransfer(InstancePtr, CMD9, (InstancePtr->RelCardAddr), 0U);
1481         if (Status != XST_SUCCESS) {
1482                 Status = XST_FAILURE;
1483                 goto RETURN_PATH;
1484         }
1485
1486         /*
1487          * Card specific data is read.
1488          * Currently not used for any operation.
1489          */
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);
1498
1499         InstancePtr->Card_Version =  (CSD[3] & CSD_SPEC_VER_MASK) >>18U;
1500
1501         Status = XST_SUCCESS;
1502
1503 RETURN_PATH:
1504         return Status;
1505
1506 }
1507 /** @} */