]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_R5_UltraScale_MPSoC/RTOSDemo_R5_bsp/psu_cortexr5_0/libsrc/sdps_v3_1/src/xsdps.c
xTaskGenericNotify() now sets xYieldPending to pdTRUE even when the 'higher priority...
[freertos] / FreeRTOS / Demo / CORTEX_R5_UltraScale_MPSoC / RTOSDemo_R5_bsp / psu_cortexr5_0 / libsrc / sdps_v3_1 / src / xsdps.c
1 /******************************************************************************
2 *
3 * Copyright (C) 2013 - 2016 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 * 2.8   sk     05/03/16 Standard Speed for SD to 19MHz in ZynqMPSoC. CR#951024
68 * 3.0   sk     06/09/16 Added support for mkfs to calculate sector count.
69 *       sk     07/16/16 Added support for UHS modes.
70 *       sk     07/07/16 Used usleep API for both arm and microblaze.
71 *       sk     07/16/16 Added Tap delays accordingly to different SD/eMMC
72 *                       operating modes.
73 * 3.1   mi     09/07/16 Removed compilation warnings with extra compiler flags.
74 *       sk     10/13/16 Reduced the delay during power cycle to 1ms as per spec
75 *       sk     10/19/16 Used emmc_hwreset pin to reset eMMC.
76 *       sk     11/07/16 Enable Rst_n bit in ext_csd reg if not enabled.
77 * </pre>
78 *
79 ******************************************************************************/
80
81 /***************************** Include Files *********************************/
82 #include "xsdps.h"
83 #include "sleep.h"
84
85 /************************** Constant Definitions *****************************/
86 #define XSDPS_CMD8_VOL_PATTERN  0x1AAU
87 #define XSDPS_RESPOCR_READY     0x80000000U
88 #define XSDPS_ACMD41_HCS        0x40000000U
89 #define XSDPS_ACMD41_3V3        0x00300000U
90 #define XSDPS_CMD1_HIGH_VOL     0x00FF8000U
91 #define XSDPS_CMD1_DUAL_VOL     0x00FF8010U
92 #define HIGH_SPEED_SUPPORT      0x2U
93 #define WIDTH_4_BIT_SUPPORT     0x4U
94 #define SD_CLK_25_MHZ           25000000U
95 #define SD_CLK_19_MHZ           19000000U
96 #define SD_CLK_26_MHZ           26000000U
97 #define EXT_CSD_DEVICE_TYPE_BYTE        196U
98 #define EXT_CSD_SEC_COUNT       212U
99 #define EXT_CSD_DEVICE_TYPE_HIGH_SPEED                  0x2U
100 #define EXT_CSD_DEVICE_TYPE_DDR_1V8_HIGH_SPEED  0x4U
101 #define EXT_CSD_DEVICE_TYPE_DDR_1V2_HIGH_SPEED  0x8U
102 #define EXT_CSD_DEVICE_TYPE_SDR_1V8_HS200               0x10U
103 #define EXT_CSD_DEVICE_TYPE_SDR_1V2_HS200               0x20U
104 #define CSD_SPEC_VER_3          0x3U
105
106 /* Note: Remove this once fixed */
107 #define UHS_BROKEN
108
109 /**************************** Type Definitions *******************************/
110
111 /***************** Macros (Inline Functions) Definitions *********************/
112
113 /************************** Function Prototypes ******************************/
114 u32 XSdPs_FrameCmd(XSdPs *InstancePtr, u32 Cmd);
115 s32 XSdPs_CmdTransfer(XSdPs *InstancePtr, u32 Cmd, u32 Arg, u32 BlkCnt);
116 void XSdPs_SetupADMA2DescTbl(XSdPs *InstancePtr, u32 BlkCnt, const u8 *Buff);
117 extern s32 XSdPs_Uhs_ModeInit(XSdPs *InstancePtr, u8 Mode);
118 static s32 XSdPs_IdentifyCard(XSdPs *InstancePtr);
119 #ifndef UHS_BROKEN
120 static s32 XSdPs_Switch_Voltage(XSdPs *InstancePtr);
121 #endif
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.DeviceId = ConfigPtr->DeviceId;
167         InstancePtr->Config.BaseAddress = EffectiveAddr;
168         InstancePtr->Config.InputClockHz = ConfigPtr->InputClockHz;
169         InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
170         InstancePtr->Config.CardDetect =  ConfigPtr->CardDetect;
171         InstancePtr->Config.WriteProtect =  ConfigPtr->WriteProtect;
172         InstancePtr->Config.BusWidth = ConfigPtr->BusWidth;
173         InstancePtr->Config.BankNumber = ConfigPtr->BankNumber;
174         InstancePtr->Config.HasEMIO = ConfigPtr->HasEMIO;
175         InstancePtr->SectorCount = 0;
176         InstancePtr->Mode = XSDPS_DEFAULT_SPEED_MODE;
177         InstancePtr->Config_TapDelay = NULL;
178
179         /* Disable bus power and issue emmc hw reset */
180         if ((XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
181                         XSDPS_HOST_CTRL_VER_OFFSET) & XSDPS_HC_SPEC_VER_MASK) ==
182                         XSDPS_HC_SPEC_V3)
183                 XSdPs_WriteReg8(InstancePtr->Config.BaseAddress,
184                                 XSDPS_POWER_CTRL_OFFSET, XSDPS_PC_EMMC_HW_RST_MASK);
185         else
186                 XSdPs_WriteReg8(InstancePtr->Config.BaseAddress,
187                                 XSDPS_POWER_CTRL_OFFSET, 0x0);
188
189         /* Delay to poweroff card */
190     (void)usleep(1000U);
191
192         /* "Software reset for all" is initiated */
193         XSdPs_WriteReg8(InstancePtr->Config.BaseAddress, XSDPS_SW_RST_OFFSET,
194                         XSDPS_SWRST_ALL_MASK);
195
196         /* Proceed with initialization only after reset is complete */
197         ReadReg = XSdPs_ReadReg8(InstancePtr->Config.BaseAddress,
198                                 XSDPS_SW_RST_OFFSET);
199         while ((ReadReg & XSDPS_SWRST_ALL_MASK) != 0U) {
200                 ReadReg = XSdPs_ReadReg8(InstancePtr->Config.BaseAddress,
201                                 XSDPS_SW_RST_OFFSET);
202         }
203         /* Host Controller version is read. */
204          InstancePtr->HC_Version =
205                         (u8)(XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
206                         XSDPS_HOST_CTRL_VER_OFFSET) & XSDPS_HC_SPEC_VER_MASK);
207
208         /*
209          * Read capabilities register and update it in Instance pointer.
210          * It is sufficient to read this once on power on.
211          */
212         InstancePtr->Host_Caps = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
213                                                 XSDPS_CAPS_OFFSET);
214
215         /* Select voltage and enable bus power. */
216         if (InstancePtr->HC_Version == XSDPS_HC_SPEC_V3)
217                 XSdPs_WriteReg8(InstancePtr->Config.BaseAddress,
218                                 XSDPS_POWER_CTRL_OFFSET,
219                                 (XSDPS_PC_BUS_VSEL_3V3_MASK | XSDPS_PC_BUS_PWR_MASK) &
220                                 ~XSDPS_PC_EMMC_HW_RST_MASK);
221         else
222                 XSdPs_WriteReg8(InstancePtr->Config.BaseAddress,
223                                 XSDPS_POWER_CTRL_OFFSET,
224                                 XSDPS_PC_BUS_VSEL_3V3_MASK | XSDPS_PC_BUS_PWR_MASK);
225
226         /* Delay before issuing the command after emmc reset */
227         if (InstancePtr->HC_Version == XSDPS_HC_SPEC_V3)
228                 if ((InstancePtr->Host_Caps & XSDPS_CAPS_SLOT_TYPE_MASK) ==
229                                 XSDPS_CAPS_EMB_SLOT)
230                         usleep(200);
231
232         /* Change the clock frequency to 400 KHz */
233         Status = XSdPs_Change_ClkFreq(InstancePtr, XSDPS_CLK_400_KHZ);
234         if (Status != XST_SUCCESS) {
235                 Status = XST_FAILURE;
236                 goto RETURN_PATH ;
237         }
238
239     if ((InstancePtr->Host_Caps & XSDPS_CAP_VOLT_3V3_MASK) != 0U) {
240                 PowerLevel = XSDPS_PC_BUS_VSEL_3V3_MASK;
241         } else if ((InstancePtr->Host_Caps & XSDPS_CAP_VOLT_3V0_MASK) != 0U) {
242                 PowerLevel = XSDPS_PC_BUS_VSEL_3V0_MASK;
243         } else if ((InstancePtr->Host_Caps & XSDPS_CAP_VOLT_1V8_MASK) != 0U) {
244                 PowerLevel = XSDPS_PC_BUS_VSEL_1V8_MASK;
245         } else {
246                 PowerLevel = 0U;
247         }
248
249         /* Select voltage based on capability and enable bus power. */
250         XSdPs_WriteReg8(InstancePtr->Config.BaseAddress,
251                         XSDPS_POWER_CTRL_OFFSET,
252                         PowerLevel | XSDPS_PC_BUS_PWR_MASK);
253         /* Enable ADMA2 in 64bit mode. */
254         XSdPs_WriteReg8(InstancePtr->Config.BaseAddress,
255                         XSDPS_HOST_CTRL1_OFFSET,
256                         XSDPS_HC_DMA_ADMA2_32_MASK);
257
258         /* Enable all interrupt status except card interrupt initially */
259         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
260                         XSDPS_NORM_INTR_STS_EN_OFFSET,
261                         XSDPS_NORM_INTR_ALL_MASK & (~XSDPS_INTR_CARD_MASK));
262
263         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
264                         XSDPS_ERR_INTR_STS_EN_OFFSET,
265                         XSDPS_ERROR_INTR_ALL_MASK);
266
267         /* Disable all interrupt signals by default. */
268         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
269                         XSDPS_NORM_INTR_SIG_EN_OFFSET, 0x0U);
270         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
271                         XSDPS_ERR_INTR_SIG_EN_OFFSET, 0x0U);
272
273         /*
274          * Transfer mode register - default value
275          * DMA enabled, block count enabled, data direction card to host(read)
276          */
277         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
278                         XSDPS_XFER_MODE_OFFSET,
279                         XSDPS_TM_DMA_EN_MASK | XSDPS_TM_BLK_CNT_EN_MASK |
280                         XSDPS_TM_DAT_DIR_SEL_MASK);
281
282         /* Set block size to 512 by default */
283         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
284                         XSDPS_BLK_SIZE_OFFSET, XSDPS_BLK_SIZE_512_MASK);
285
286         Status = XST_SUCCESS;
287
288 RETURN_PATH:
289         return Status;
290
291 }
292
293 /*****************************************************************************/
294 /**
295 * SD initialization is done in this function
296 *
297 *
298 * @param        InstancePtr is a pointer to the instance to be worked on.
299 *
300 * @return
301 *               - XST_SUCCESS if initialization was successful
302 *               - XST_FAILURE if failure - could be because
303 *                       a) SD is already initialized
304 *                       b) There is no card inserted
305 *                       c) One of the steps (commands) in the
306                            initialization cycle failed
307 *
308 * @note         This function initializes the SD card by following its
309 *               initialization and identification state diagram.
310 *               CMD0 is sent to reset card.
311 *               CMD8 and ACDM41 are sent to identify voltage and
312 *               high capacity support
313 *               CMD2 and CMD3 are sent to obtain Card ID and
314 *               Relative card address respectively.
315 *               CMD9 is sent to read the card specific data.
316 *
317 ******************************************************************************/
318 s32 XSdPs_SdCardInitialize(XSdPs *InstancePtr)
319 {
320         u32 PresentStateReg;
321         s32 Status;
322         u32 RespOCR;
323         u32 CSD[4];
324         u32 Arg;
325         u8 ReadReg;
326         u32 BlkLen, DeviceSize, Mult;
327
328         Xil_AssertNonvoid(InstancePtr != NULL);
329         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
330
331         if ((InstancePtr->HC_Version != XSDPS_HC_SPEC_V3) ||
332                                 ((InstancePtr->Host_Caps & XSDPS_CAPS_SLOT_TYPE_MASK)
333                                 != XSDPS_CAPS_EMB_SLOT)) {
334                 if(InstancePtr->Config.CardDetect != 0U) {
335                         /*
336                          * Check the present state register to make sure
337                          * card is inserted and detected by host controller
338                          */
339                         PresentStateReg = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
340                                         XSDPS_PRES_STATE_OFFSET);
341                         if ((PresentStateReg & XSDPS_PSR_CARD_INSRT_MASK) == 0U)        {
342                                 Status = XST_FAILURE;
343                                 goto RETURN_PATH;
344                         }
345                 }
346         }
347
348         /* CMD0 no response expected */
349         Status = XSdPs_CmdTransfer(InstancePtr, (u32)CMD0, 0U, 0U);
350         if (Status != XST_SUCCESS) {
351                 Status = XST_FAILURE;
352                 goto RETURN_PATH;
353         }
354
355         /*
356          * CMD8; response expected
357          * 0x1AA - Supply Voltage 2.7 - 3.6V and AA is pattern
358          */
359         Status = XSdPs_CmdTransfer(InstancePtr, CMD8,
360                         XSDPS_CMD8_VOL_PATTERN, 0U);
361         if ((Status != XST_SUCCESS) && (Status != XSDPS_CT_ERROR)) {
362                 Status = XST_FAILURE;
363                 goto RETURN_PATH;
364         }
365
366         if (Status == XSDPS_CT_ERROR) {
367                  /* "Software reset for all" is initiated */
368                 XSdPs_WriteReg8(InstancePtr->Config.BaseAddress, XSDPS_SW_RST_OFFSET,
369                                 XSDPS_SWRST_CMD_LINE_MASK);
370
371                 /* Proceed with initialization only after reset is complete */
372                 ReadReg = XSdPs_ReadReg8(InstancePtr->Config.BaseAddress,
373                                                 XSDPS_SW_RST_OFFSET);
374                 while ((ReadReg & XSDPS_SWRST_CMD_LINE_MASK) != 0U) {
375                         ReadReg = XSdPs_ReadReg8(InstancePtr->Config.BaseAddress,
376                                                 XSDPS_SW_RST_OFFSET);
377                 }
378         }
379
380         RespOCR = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
381                                                 XSDPS_RESP0_OFFSET);
382         if (RespOCR != XSDPS_CMD8_VOL_PATTERN) {
383                 InstancePtr->Card_Version = XSDPS_SD_VER_1_0;
384         }
385         else {
386                 InstancePtr->Card_Version = XSDPS_SD_VER_2_0;
387         }
388
389         RespOCR = 0U;
390         /* Send ACMD41 while card is still busy with power up */
391         while ((RespOCR & XSDPS_RESPOCR_READY) == 0U) {
392                 Status = XSdPs_CmdTransfer(InstancePtr, CMD55, 0U, 0U);
393                 if (Status != XST_SUCCESS) {
394                         Status = XST_FAILURE;
395                         goto RETURN_PATH;
396                 }
397
398         Arg = XSDPS_ACMD41_HCS | XSDPS_ACMD41_3V3 | (0x1FFU << 15U);
399                 if (InstancePtr->HC_Version == XSDPS_HC_SPEC_V3) {
400                     Arg |= XSDPS_OCR_S18;
401                 }
402
403                 /* 0x40300000 - Host High Capacity support & 3.3V window */
404                 Status = XSdPs_CmdTransfer(InstancePtr, ACMD41,
405                                 Arg, 0U);
406                 if (Status != XST_SUCCESS) {
407                         Status = XST_FAILURE;
408                         goto RETURN_PATH;
409                 }
410
411                 /* Response with card capacity */
412                 RespOCR = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
413                                 XSDPS_RESP0_OFFSET);
414
415         }
416
417         /* Update HCS support flag based on card capacity response */
418         if ((RespOCR & XSDPS_ACMD41_HCS) != 0U) {
419                 InstancePtr->HCS = 1U;
420         }
421
422         /* There is no support to switch to 1.8V and use UHS mode on 1.0 silicon */
423 #ifndef UHS_BROKEN
424     if ((RespOCR & XSDPS_OCR_S18) != 0U) {
425                 InstancePtr->Switch1v8 = 1U;
426                 Status = XSdPs_Switch_Voltage(InstancePtr);
427                 if (Status != XST_SUCCESS) {
428                         Status = XST_FAILURE;
429                         goto RETURN_PATH;
430                 }
431
432         }
433 #endif
434
435         /* CMD2 for Card ID */
436         Status = XSdPs_CmdTransfer(InstancePtr, CMD2, 0U, 0U);
437         if (Status != XST_SUCCESS) {
438                 Status = XST_FAILURE;
439                 goto RETURN_PATH;
440         }
441
442         InstancePtr->CardID[0] =
443                         XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
444                         XSDPS_RESP0_OFFSET);
445         InstancePtr->CardID[1] =
446                         XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
447                         XSDPS_RESP1_OFFSET);
448         InstancePtr->CardID[2] =
449                         XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
450                         XSDPS_RESP2_OFFSET);
451         InstancePtr->CardID[3] =
452                         XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
453                         XSDPS_RESP3_OFFSET);
454         do {
455                 Status = XSdPs_CmdTransfer(InstancePtr, CMD3, 0U, 0U);
456                 if (Status != XST_SUCCESS) {
457                         Status = XST_FAILURE;
458                         goto RETURN_PATH;
459                 }
460
461                 /*
462                  * Relative card address is stored as the upper 16 bits
463                  * This is to avoid shifting when sending commands
464                  */
465                 InstancePtr->RelCardAddr =
466                                 XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
467                                         XSDPS_RESP0_OFFSET) & 0xFFFF0000U;
468         } while (InstancePtr->RelCardAddr == 0U);
469
470         Status = XSdPs_CmdTransfer(InstancePtr, CMD9, (InstancePtr->RelCardAddr), 0U);
471         if (Status != XST_SUCCESS) {
472                 Status = XST_FAILURE;
473                 goto RETURN_PATH;
474         }
475
476         /*
477          * Card specific data is read.
478          * Currently not used for any operation.
479          */
480         CSD[0] = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
481                         XSDPS_RESP0_OFFSET);
482         CSD[1] = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
483                         XSDPS_RESP1_OFFSET);
484         CSD[2] = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
485                         XSDPS_RESP2_OFFSET);
486         CSD[3] = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
487                         XSDPS_RESP3_OFFSET);
488
489         if (((CSD[3] & CSD_STRUCT_MASK) >> 22U) == 0U) {
490                 BlkLen = 1 << ((CSD[2] & READ_BLK_LEN_MASK) >> 8U);
491                 Mult = 1 << (((CSD[1] & C_SIZE_MULT_MASK) >> 7U) + 2U);
492                 DeviceSize = (CSD[1] & C_SIZE_LOWER_MASK) >> 22U;
493                 DeviceSize |= (CSD[2] & C_SIZE_UPPER_MASK) << 10U;
494                 DeviceSize = (DeviceSize + 1U) * Mult;
495                 DeviceSize =  DeviceSize * BlkLen;
496                 InstancePtr->SectorCount = (DeviceSize/XSDPS_BLK_SIZE_512_MASK);
497         } else if (((CSD[3] & CSD_STRUCT_MASK) >> 22U) == 1U) {
498                 InstancePtr->SectorCount = (((CSD[1] & CSD_V2_C_SIZE_MASK) >> 8U) +
499                                                                                 1U) * 1024U;
500         }
501
502         Status = XST_SUCCESS;
503
504 RETURN_PATH:
505         return Status;
506
507 }
508
509 /*****************************************************************************/
510 /**
511 *
512 * Initialize Card with Identification mode sequence
513 *
514 *
515 * @param        InstancePtr is a pointer to the instance to be worked on.
516 *
517 * @return
518 *               - XST_SUCCESS if initialization was successful
519 *               - XST_FAILURE if failure - could be because
520 *                       a) SD is already initialized
521 *                       b) There is no card inserted
522 *                       c) One of the steps (commands) in the
523 *                          initialization cycle failed
524 *
525 *
526 ******************************************************************************/
527 s32 XSdPs_CardInitialize(XSdPs *InstancePtr)
528 {
529 #ifdef __ICCARM__
530 #pragma data_alignment = 32
531 static u8 ExtCsd[512];
532 #pragma data_alignment = 4
533 #else
534 static u8 ExtCsd[512] __attribute__ ((aligned(32)));
535 #endif
536         u8 SCR[8] = { 0U };
537         u8 ReadBuff[64] = { 0U };
538         s32 Status;
539         u32 Arg;
540
541         Xil_AssertNonvoid(InstancePtr != NULL);
542         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
543
544         /* Default settings */
545         InstancePtr->BusWidth = XSDPS_1_BIT_WIDTH;
546         InstancePtr->CardType = XSDPS_CARD_SD;
547         InstancePtr->Switch1v8 = 0U;
548         InstancePtr->BusSpeed = XSDPS_CLK_400_KHZ;
549
550         if ((InstancePtr->HC_Version == XSDPS_HC_SPEC_V3) &&
551                         ((InstancePtr->Host_Caps & XSDPS_CAPS_SLOT_TYPE_MASK)
552                         == XSDPS_CAPS_EMB_SLOT)) {
553                 InstancePtr->CardType = XSDPS_CHIP_EMMC;
554         } else {
555                 Status = XSdPs_IdentifyCard(InstancePtr);
556                 if (Status == XST_FAILURE) {
557                         goto RETURN_PATH;
558                 }
559         }
560
561         if ((InstancePtr->CardType != XSDPS_CARD_SD) &&
562                 (InstancePtr->CardType != XSDPS_CARD_MMC) &&
563                 (InstancePtr->CardType != XSDPS_CHIP_EMMC)) {
564                 Status = XST_FAILURE;
565                 goto RETURN_PATH;
566         }
567
568         if (InstancePtr->CardType == XSDPS_CARD_SD) {
569                 Status = XSdPs_SdCardInitialize(InstancePtr);
570                 if (Status != XST_SUCCESS) {
571                         Status = XST_FAILURE;
572                         goto RETURN_PATH;
573                 }
574
575                 /* Change clock to default clock 25MHz */
576                 /*
577                  * SD default speed mode timing should be closed at 19 MHz.
578                  * The reason for this is SD requires a voltage level shifter.
579                  * This limitation applies to ZynqMPSoC.
580                  */
581                 if (InstancePtr->HC_Version == XSDPS_HC_SPEC_V3)
582                         InstancePtr->BusSpeed = SD_CLK_19_MHZ;
583                 else
584                         InstancePtr->BusSpeed = SD_CLK_25_MHZ;
585                 Status = XSdPs_Change_ClkFreq(InstancePtr, InstancePtr->BusSpeed);
586                 if (Status != XST_SUCCESS) {
587                         Status = XST_FAILURE;
588                         goto RETURN_PATH;
589                 }
590
591         } else if ((InstancePtr->CardType == XSDPS_CARD_MMC)
592                         || (InstancePtr->CardType == XSDPS_CHIP_EMMC)) {
593                 Status = XSdPs_MmcCardInitialize(InstancePtr);
594                 if (Status != XST_SUCCESS) {
595                         Status = XST_FAILURE;
596                         goto RETURN_PATH;
597                 }
598                 /* Change clock to default clock 26MHz */
599                 InstancePtr->BusSpeed = SD_CLK_26_MHZ;
600                 Status = XSdPs_Change_ClkFreq(InstancePtr, InstancePtr->BusSpeed);
601                 if (Status != XST_SUCCESS) {
602                         Status = XST_FAILURE;
603                         goto RETURN_PATH;
604                 }
605         } else {
606                 Status = XST_FAILURE;
607                 goto RETURN_PATH;
608         }
609
610         Status = XSdPs_Select_Card(InstancePtr);
611         if (Status != XST_SUCCESS) {
612                 Status = XST_FAILURE;
613                 goto RETURN_PATH;
614         }
615
616         if (InstancePtr->CardType == XSDPS_CARD_SD) {
617                 /* Pull-up disconnected during data transfer */
618                 Status = XSdPs_Pullup(InstancePtr);
619                 if (Status != XST_SUCCESS) {
620                         Status = XST_FAILURE;
621                         goto RETURN_PATH;
622                 }
623
624                 Status = XSdPs_Get_BusWidth(InstancePtr, SCR);
625                 if (Status != XST_SUCCESS) {
626                         Status = XST_FAILURE;
627                         goto RETURN_PATH;
628                 }
629
630                 if ((SCR[1] & WIDTH_4_BIT_SUPPORT) != 0U) {
631                         Status = XSdPs_Change_BusWidth(InstancePtr);
632                         if (Status != XST_SUCCESS) {
633                                 Status = XST_FAILURE;
634                                 goto RETURN_PATH;
635                         }
636                 }
637
638                 /* Get speed supported by device */
639                 Status = XSdPs_Get_BusSpeed(InstancePtr, ReadBuff);
640                 if (Status != XST_SUCCESS) {
641                         goto RETURN_PATH;
642                 }
643
644 #if defined (ARMR5) || defined (__aarch64__)
645                 if ((InstancePtr->Switch1v8 != 0U) &&
646                                 (InstancePtr->BusWidth == XSDPS_4_BIT_WIDTH)) {
647
648                         /* Identify the UHS mode supported by card */
649                         XSdPs_Identify_UhsMode(InstancePtr, ReadBuff);
650
651                         /* Set UHS-I SDR104 mode */
652                         Status = XSdPs_Uhs_ModeInit(InstancePtr, InstancePtr->Mode);
653                         if (Status != XST_SUCCESS) {
654                                 goto RETURN_PATH;
655                         }
656
657                 } else {
658 #endif
659                         /*
660                          * card supports CMD6 when SD_SPEC field in SCR register
661                          * indicates that the Physical Layer Specification Version
662                          * is 1.10 or later. So for SD v1.0 cmd6 is not supported.
663                          */
664                         if (SCR[0] != 0U) {
665                                 /* Check for high speed support */
666                                 if ((ReadBuff[13] & HIGH_SPEED_SUPPORT) != 0U) {
667                                         InstancePtr->Mode = XSDPS_HIGH_SPEED_MODE;
668 #if defined (ARMR5) || defined (__aarch64__)
669                                         InstancePtr->Config_TapDelay = XSdPs_hsd_sdr25_tapdelay;
670 #endif
671                                         Status = XSdPs_Change_BusSpeed(InstancePtr);
672                                         if (Status != XST_SUCCESS) {
673                                                 Status = XST_FAILURE;
674                                                 goto RETURN_PATH;
675                                         }
676                                 }
677                         }
678 #if defined (ARMR5) || defined (__aarch64__)
679                 }
680 #endif
681
682         } else if (((InstancePtr->CardType == XSDPS_CARD_MMC) &&
683                                 (InstancePtr->Card_Version > CSD_SPEC_VER_3)) &&
684                                 (InstancePtr->HC_Version == XSDPS_HC_SPEC_V2)) {
685
686                 Status = XSdPs_Change_BusWidth(InstancePtr);
687                 if (Status != XST_SUCCESS) {
688                         Status = XST_FAILURE;
689                         goto RETURN_PATH;
690                 }
691
692                 Status = XSdPs_Get_Mmc_ExtCsd(InstancePtr, ExtCsd);
693                 if (Status != XST_SUCCESS) {
694                         Status = XST_FAILURE;
695                         goto RETURN_PATH;
696                 }
697
698                 InstancePtr->SectorCount = *(u32 *)&ExtCsd[EXT_CSD_SEC_COUNT];
699
700                 if ((ExtCsd[EXT_CSD_DEVICE_TYPE_BYTE] &
701                                 EXT_CSD_DEVICE_TYPE_HIGH_SPEED) != 0U) {
702                         InstancePtr->Mode = XSDPS_HIGH_SPEED_MODE;
703                         Status = XSdPs_Change_BusSpeed(InstancePtr);
704                         if (Status != XST_SUCCESS) {
705                                 Status = XST_FAILURE;
706                                 goto RETURN_PATH;
707                         }
708
709                         Status = XSdPs_Get_Mmc_ExtCsd(InstancePtr, ExtCsd);
710                         if (Status != XST_SUCCESS) {
711                                 Status = XST_FAILURE;
712                                 goto RETURN_PATH;
713                         }
714
715                         if (ExtCsd[EXT_CSD_HS_TIMING_BYTE] != EXT_CSD_HS_TIMING_HIGH) {
716                                 Status = XST_FAILURE;
717                                 goto RETURN_PATH;
718                         }
719                 }
720         } else if (InstancePtr->CardType == XSDPS_CHIP_EMMC){
721                 /* Change bus width to 8-bit */
722                 Status = XSdPs_Change_BusWidth(InstancePtr);
723                 if (Status != XST_SUCCESS) {
724                         Status = XST_FAILURE;
725                         goto RETURN_PATH;
726                 }
727
728                 /* Get Extended CSD */
729                 Status = XSdPs_Get_Mmc_ExtCsd(InstancePtr, ExtCsd);
730                 if (Status != XST_SUCCESS) {
731                         Status = XST_FAILURE;
732                         goto RETURN_PATH;
733                 }
734
735                 InstancePtr->SectorCount = *(u32 *)&ExtCsd[EXT_CSD_SEC_COUNT];
736
737                 if ((ExtCsd[EXT_CSD_DEVICE_TYPE_BYTE] &
738                                 (EXT_CSD_DEVICE_TYPE_SDR_1V8_HS200 |
739                                 EXT_CSD_DEVICE_TYPE_SDR_1V2_HS200)) != 0U) {
740                         InstancePtr->Mode = XSDPS_HS200_MODE;
741 #if defined (ARMR5) || defined (__aarch64__)
742                         InstancePtr->Config_TapDelay = XSdPs_sdr104_hs200_tapdelay;
743 #endif
744                         Status = XSdPs_Change_BusSpeed(InstancePtr);
745                         if (Status != XST_SUCCESS) {
746                                 Status = XST_FAILURE;
747                                 goto RETURN_PATH;
748                         }
749
750                         Status = XSdPs_Get_Mmc_ExtCsd(InstancePtr, ExtCsd);
751                         if (Status != XST_SUCCESS) {
752                                 Status = XST_FAILURE;
753                                 goto RETURN_PATH;
754                         }
755
756                         if (ExtCsd[EXT_CSD_HS_TIMING_BYTE] != EXT_CSD_HS_TIMING_HS200) {
757                                 Status = XST_FAILURE;
758                                 goto RETURN_PATH;
759                         }
760                 }
761
762                 /* Enable Rst_n_Fun bit if it is disabled */
763                 if(ExtCsd[EXT_CSD_RST_N_FUN_BYTE] == EXT_CSD_RST_N_FUN_TEMP_DIS) {
764                         Arg = XSDPS_MMC_RST_FUN_EN_ARG;
765                         Status = XSdPs_Set_Mmc_ExtCsd(InstancePtr, Arg);
766                         if (Status != XST_SUCCESS) {
767                                 Status = XST_FAILURE;
768                                 goto RETURN_PATH;
769                         }
770                 }
771         }
772
773         Status = XSdPs_SetBlkSize(InstancePtr, XSDPS_BLK_SIZE_512_MASK);
774         if (Status != XST_SUCCESS) {
775                 Status = XST_FAILURE;
776                 goto RETURN_PATH;
777         }
778
779 RETURN_PATH:
780         return Status;
781 }
782
783 /*****************************************************************************/
784 /**
785 *
786 * Identify type of card using CMD0 + CMD1 sequence
787 *
788 *
789 * @param        InstancePtr is a pointer to the XSdPs instance.
790 *
791 ******************************************************************************/
792 static s32 XSdPs_IdentifyCard(XSdPs *InstancePtr)
793 {
794         s32 Status;
795         u8 ReadReg;
796
797         Xil_AssertNonvoid(InstancePtr != NULL);
798         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
799
800         /* 74 CLK delay after card is powered up, before the first command. */
801         usleep(XSDPS_INIT_DELAY);
802
803         /* CMD0 no response expected */
804         Status = XSdPs_CmdTransfer(InstancePtr, CMD0, 0U, 0U);
805         if (Status != XST_SUCCESS) {
806                 Status = XST_FAILURE;
807                 goto RETURN_PATH;
808         }
809
810         /* Host High Capacity support & High voltage window */
811         Status = XSdPs_CmdTransfer(InstancePtr, CMD1,
812                         XSDPS_ACMD41_HCS | XSDPS_CMD1_HIGH_VOL, 0U);
813         if (Status != XST_SUCCESS) {
814                 InstancePtr->CardType = XSDPS_CARD_SD;
815         } else {
816                 InstancePtr->CardType = XSDPS_CARD_MMC;
817         }
818
819         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
820                         XSDPS_NORM_INTR_STS_OFFSET, XSDPS_NORM_INTR_ALL_MASK);
821         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
822                         XSDPS_ERR_INTR_STS_OFFSET, XSDPS_ERROR_INTR_ALL_MASK);
823
824         /* "Software reset for all" is initiated */
825         XSdPs_WriteReg8(InstancePtr->Config.BaseAddress, XSDPS_SW_RST_OFFSET,
826                         XSDPS_SWRST_CMD_LINE_MASK);
827
828         /* Proceed with initialization only after reset is complete */
829         ReadReg = XSdPs_ReadReg8(InstancePtr->Config.BaseAddress,
830                                         XSDPS_SW_RST_OFFSET);
831         while ((ReadReg & XSDPS_SWRST_CMD_LINE_MASK) != 0U) {
832                 ReadReg = XSdPs_ReadReg8(InstancePtr->Config.BaseAddress,
833                                         XSDPS_SW_RST_OFFSET);
834         }
835
836         Status = XST_SUCCESS;
837
838 RETURN_PATH:
839         return Status;
840 }
841
842 #ifndef UHS_BROKEN
843 /*****************************************************************************/
844 /**
845 *
846 * Switches the SD card voltage from 3v3 to 1v8
847 *
848 *
849 * @param        InstancePtr is a pointer to the XSdPs instance.
850 *
851 ******************************************************************************/
852 static s32 XSdPs_Switch_Voltage(XSdPs *InstancePtr)
853 {
854         s32 Status;
855         u16 CtrlReg;
856         u32 ReadReg;
857
858         /* Send switch voltage command */
859         Status = XSdPs_CmdTransfer(InstancePtr, CMD11, 0U, 0U);
860         if (Status != XST_SUCCESS) {
861                 Status = XST_FAILURE;
862         }
863
864         /* Wait for CMD and DATA line to go low */
865         ReadReg = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
866                                 XSDPS_PRES_STATE_OFFSET);
867         while ((ReadReg & (XSDPS_PSR_CMD_SG_LVL_MASK |
868                                         XSDPS_PSR_DAT30_SG_LVL_MASK)) != 0U) {
869                 ReadReg = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
870                                         XSDPS_PRES_STATE_OFFSET);
871         }
872
873         /* Stop the clock */
874         CtrlReg = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
875                         XSDPS_CLK_CTRL_OFFSET);
876         CtrlReg &= ~(XSDPS_CC_SD_CLK_EN_MASK | XSDPS_CC_INT_CLK_EN_MASK);
877         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress, XSDPS_CLK_CTRL_OFFSET,
878                         CtrlReg);
879
880         /* Wait minimum 5mSec */
881         (void)usleep(5000U);
882
883         /* Enabling 1.8V in controller */
884         CtrlReg = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
885                         XSDPS_HOST_CTRL2_OFFSET);
886         CtrlReg |= XSDPS_HC2_1V8_EN_MASK;
887         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress, XSDPS_HOST_CTRL2_OFFSET,
888                         CtrlReg);
889
890         /* Start clock */
891         Status = XSdPs_Change_ClkFreq(InstancePtr, XSDPS_CLK_400_KHZ);
892         if (Status != XST_SUCCESS) {
893                 Status = XST_FAILURE;
894                 goto RETURN_PATH;
895         }
896
897         /* Wait for CMD and DATA line to go high */
898         ReadReg = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
899                                 XSDPS_PRES_STATE_OFFSET);
900         while ((ReadReg & (XSDPS_PSR_CMD_SG_LVL_MASK | XSDPS_PSR_DAT30_SG_LVL_MASK))
901                         != (XSDPS_PSR_CMD_SG_LVL_MASK | XSDPS_PSR_DAT30_SG_LVL_MASK)) {
902                 ReadReg = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
903                                         XSDPS_PRES_STATE_OFFSET);
904         }
905
906 RETURN_PATH:
907         return Status;
908 }
909 #endif
910
911 /*****************************************************************************/
912 /**
913
914 * This function does SD command generation.
915 *
916 * @param        InstancePtr is a pointer to the instance to be worked on.
917 * @param        Cmd is the command to be sent.
918 * @param        Arg is the argument to be sent along with the command.
919 *               This could be address or any other information
920 * @param        BlkCnt - Block count passed by the user.
921 *
922 * @return
923 *               - XST_SUCCESS if initialization was successful
924 *               - XST_FAILURE if failure - could be because another transfer
925 *                       is in progress or command or data inhibit is set
926 *
927 ******************************************************************************/
928 s32 XSdPs_CmdTransfer(XSdPs *InstancePtr, u32 Cmd, u32 Arg, u32 BlkCnt)
929 {
930         u32 PresentStateReg;
931         u32 CommandReg;
932         u32 StatusReg;
933         s32 Status;
934
935         Xil_AssertNonvoid(InstancePtr != NULL);
936         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
937
938         /*
939          * Check the command inhibit to make sure no other
940          * command transfer is in progress
941          */
942         PresentStateReg = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
943                         XSDPS_PRES_STATE_OFFSET);
944         if ((PresentStateReg & XSDPS_PSR_INHIBIT_CMD_MASK) != 0U) {
945                 Status = XST_FAILURE;
946                 goto RETURN_PATH;
947         }
948
949         /* Write block count register */
950         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
951                         XSDPS_BLK_CNT_OFFSET, (u16)BlkCnt);
952
953         XSdPs_WriteReg8(InstancePtr->Config.BaseAddress,
954                         XSDPS_TIMEOUT_CTRL_OFFSET, 0xEU);
955
956         /* Write argument register */
957         XSdPs_WriteReg(InstancePtr->Config.BaseAddress,
958                         XSDPS_ARGMT_OFFSET, Arg);
959
960         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
961                         XSDPS_NORM_INTR_STS_OFFSET, XSDPS_NORM_INTR_ALL_MASK);
962         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
963                         XSDPS_ERR_INTR_STS_OFFSET, XSDPS_ERROR_INTR_ALL_MASK);
964         /* Command register is set to trigger transfer of command */
965         CommandReg = XSdPs_FrameCmd(InstancePtr, Cmd);
966
967         /*
968          * Mask to avoid writing to reserved bits 31-30
969          * This is necessary because 0x80000000 is used  by this software to
970          * distinguish between ACMD and CMD of same number
971          */
972         CommandReg = CommandReg & 0x3FFFU;
973
974         /*
975          * Check for data inhibit in case of command using DAT lines.
976          * For Tuning Commands DAT lines check can be ignored.
977          */
978         if ((Cmd != CMD21) && (Cmd != CMD19)) {
979                 PresentStateReg = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
980                                 XSDPS_PRES_STATE_OFFSET);
981                 if (((PresentStateReg & (XSDPS_PSR_INHIBIT_DAT_MASK |
982                                                                         XSDPS_PSR_INHIBIT_DAT_MASK)) != 0U) &&
983                                 ((CommandReg & XSDPS_DAT_PRESENT_SEL_MASK) != 0U)) {
984                         Status = XST_FAILURE;
985                         goto RETURN_PATH;
986                 }
987         }
988
989         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress, XSDPS_CMD_OFFSET,
990                         (u16)CommandReg);
991
992         /* Polling for response for now */
993         do {
994                 StatusReg = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
995                                         XSDPS_NORM_INTR_STS_OFFSET);
996                 if ((Cmd == CMD21) || (Cmd == CMD19)) {
997                         if ((XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
998                                         XSDPS_NORM_INTR_STS_OFFSET) & XSDPS_INTR_BRR_MASK) != 0U){
999                                 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
1000                                         XSDPS_NORM_INTR_STS_OFFSET, XSDPS_INTR_BRR_MASK);
1001                                 break;
1002                         }
1003                 }
1004
1005                 if ((StatusReg & XSDPS_INTR_ERR_MASK) != 0U) {
1006                         Status = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
1007                                                                         XSDPS_ERR_INTR_STS_OFFSET);
1008                         if ((Status & ~XSDPS_INTR_ERR_CT_MASK) == 0) {
1009                                 Status = XSDPS_CT_ERROR;
1010                         }
1011                          /* Write to clear error bits */
1012                         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
1013                                         XSDPS_ERR_INTR_STS_OFFSET,
1014                                         XSDPS_ERROR_INTR_ALL_MASK);
1015                         goto RETURN_PATH;
1016                 }
1017         } while((StatusReg & XSDPS_INTR_CC_MASK) == 0U);
1018         /* Write to clear bit */
1019         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
1020                         XSDPS_NORM_INTR_STS_OFFSET,
1021                         XSDPS_INTR_CC_MASK);
1022
1023         Status = XST_SUCCESS;
1024
1025 RETURN_PATH:
1026                 return Status;
1027
1028 }
1029
1030 /*****************************************************************************/
1031 /**
1032 * This function frames the Command register for a particular command.
1033 * Note that this generates only the command register value i.e.
1034 * the upper 16 bits of the transfer mode and command register.
1035 * This value is already shifted to be upper 16 bits and can be directly
1036 * OR'ed with transfer mode register value.
1037 *
1038 * @param        Command to be sent.
1039 *
1040 * @return       Command register value complete with response type and
1041 *               data, CRC and index related flags.
1042 *
1043 ******************************************************************************/
1044 u32 XSdPs_FrameCmd(XSdPs *InstancePtr, u32 Cmd)
1045 {
1046                 u32 RetVal;
1047
1048                 RetVal = Cmd;
1049
1050                 switch(Cmd) {
1051                 case CMD0:
1052                         RetVal |= RESP_NONE;
1053                 break;
1054                 case CMD1:
1055                         RetVal |= RESP_R3;
1056                 break;
1057                 case CMD2:
1058                         RetVal |= RESP_R2;
1059                 break;
1060                 case CMD3:
1061                         RetVal |= RESP_R6;
1062                 break;
1063                 case CMD4:
1064                         RetVal |= RESP_NONE;
1065                         break;
1066                 case CMD5:
1067                         RetVal |= RESP_R1B;
1068                 break;
1069                 case CMD6:
1070                         if (InstancePtr->CardType == XSDPS_CARD_SD) {
1071                                 RetVal |= RESP_R1 | (u32)XSDPS_DAT_PRESENT_SEL_MASK;
1072                         } else {
1073                                 RetVal |= RESP_R1B;
1074                         }
1075                         break;
1076                 case ACMD6:
1077                         RetVal |= RESP_R1;
1078                 break;
1079                 case CMD7:
1080                         RetVal |= RESP_R1;
1081                 break;
1082                 case CMD8:
1083                         if (InstancePtr->CardType == XSDPS_CARD_SD) {
1084                                 RetVal |= RESP_R1;
1085                         } else {
1086                                 RetVal |= RESP_R1 | (u32)XSDPS_DAT_PRESENT_SEL_MASK;
1087                         }
1088                         break;
1089                 case CMD9:
1090                         RetVal |= RESP_R2;
1091                 break;
1092                 case CMD11:
1093                 case CMD10:
1094                 case CMD12:
1095                 case ACMD13:
1096                 case CMD16:
1097                         RetVal |= RESP_R1;
1098                 break;
1099                 case CMD17:
1100                 case CMD18:
1101                 case CMD19:
1102                 case CMD21:
1103                         RetVal |= RESP_R1 | (u32)XSDPS_DAT_PRESENT_SEL_MASK;
1104                 break;
1105                 case CMD23:
1106                 case ACMD23:
1107                 case CMD24:
1108                 case CMD25:
1109                         RetVal |= RESP_R1 | (u32)XSDPS_DAT_PRESENT_SEL_MASK;
1110                 case ACMD41:
1111                         RetVal |= RESP_R3;
1112                 break;
1113                 case ACMD42:
1114                         RetVal |= RESP_R1;
1115                 break;
1116                 case ACMD51:
1117                         RetVal |= RESP_R1 | (u32)XSDPS_DAT_PRESENT_SEL_MASK;
1118                 break;
1119                 case CMD52:
1120                 case CMD55:
1121                         RetVal |= RESP_R1;
1122                 break;
1123                 case CMD58:
1124                 break;
1125                 default :
1126                         RetVal |= Cmd;
1127                 break;
1128                 }
1129
1130                 return RetVal;
1131 }
1132
1133 /*****************************************************************************/
1134 /**
1135 * This function performs SD read in polled mode.
1136 *
1137 * @param        InstancePtr is a pointer to the instance to be worked on.
1138 * @param        Arg is the address passed by the user that is to be sent as
1139 *               argument along with the command.
1140 * @param        BlkCnt - Block count passed by the user.
1141 * @param        Buff - Pointer to the data buffer for a DMA transfer.
1142 *
1143 * @return
1144 *               - XST_SUCCESS if initialization was successful
1145 *               - XST_FAILURE if failure - could be because another transfer
1146 *               is in progress or command or data inhibit is set
1147 *
1148 ******************************************************************************/
1149 s32 XSdPs_ReadPolled(XSdPs *InstancePtr, u32 Arg, u32 BlkCnt, u8 *Buff)
1150 {
1151         s32 Status;
1152         u32 PresentStateReg;
1153         u32 StatusReg;
1154
1155         if ((InstancePtr->HC_Version != XSDPS_HC_SPEC_V3) ||
1156                                 ((InstancePtr->Host_Caps & XSDPS_CAPS_SLOT_TYPE_MASK)
1157                                 != XSDPS_CAPS_EMB_SLOT)) {
1158                 if(InstancePtr->Config.CardDetect != 0U) {
1159                         /* Check status to ensure card is initialized */
1160                         PresentStateReg = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
1161                                         XSDPS_PRES_STATE_OFFSET);
1162                         if ((PresentStateReg & XSDPS_PSR_CARD_INSRT_MASK) == 0x0U) {
1163                                 Status = XST_FAILURE;
1164                                 goto RETURN_PATH;
1165                         }
1166                 }
1167         }
1168
1169         /* Set block size to 512 if not already set */
1170         if( XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
1171                         XSDPS_BLK_SIZE_OFFSET) != XSDPS_BLK_SIZE_512_MASK ) {
1172                 Status = XSdPs_SetBlkSize(InstancePtr,
1173                         XSDPS_BLK_SIZE_512_MASK);
1174                 if (Status != XST_SUCCESS) {
1175                         Status = XST_FAILURE;
1176                         goto RETURN_PATH;
1177                 }
1178         }
1179
1180         XSdPs_SetupADMA2DescTbl(InstancePtr, BlkCnt, Buff);
1181
1182         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
1183                         XSDPS_XFER_MODE_OFFSET,
1184                         XSDPS_TM_AUTO_CMD12_EN_MASK |
1185                         XSDPS_TM_BLK_CNT_EN_MASK | XSDPS_TM_DAT_DIR_SEL_MASK |
1186                         XSDPS_TM_DMA_EN_MASK | XSDPS_TM_MUL_SIN_BLK_SEL_MASK);
1187
1188         Xil_DCacheInvalidateRange((INTPTR)Buff, BlkCnt * XSDPS_BLK_SIZE_512_MASK);
1189
1190         /* Send block read command */
1191         Status = XSdPs_CmdTransfer(InstancePtr, CMD18, Arg, BlkCnt);
1192         if (Status != XST_SUCCESS) {
1193                 Status = XST_FAILURE;
1194                 goto RETURN_PATH;
1195         }
1196
1197         /* Check for transfer complete */
1198         do {
1199                 StatusReg = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
1200                                         XSDPS_NORM_INTR_STS_OFFSET);
1201                 if ((StatusReg & XSDPS_INTR_ERR_MASK) != 0U) {
1202                         /* Write to clear error bits */
1203                         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
1204                                         XSDPS_ERR_INTR_STS_OFFSET,
1205                                         XSDPS_ERROR_INTR_ALL_MASK);
1206                         Status = XST_FAILURE;
1207                         goto RETURN_PATH;
1208                 }
1209         } while((StatusReg & XSDPS_INTR_TC_MASK) == 0U);
1210
1211         /* Write to clear bit */
1212         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
1213                         XSDPS_NORM_INTR_STS_OFFSET, XSDPS_INTR_TC_MASK);
1214         Status = (s32)XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
1215                         XSDPS_RESP0_OFFSET);
1216
1217         Status = XST_SUCCESS;
1218
1219 RETURN_PATH:
1220         return Status;
1221 }
1222
1223 /*****************************************************************************/
1224 /**
1225 * This function performs SD write in polled mode.
1226 *
1227 * @param        InstancePtr is a pointer to the instance to be worked on.
1228 * @param        Arg is the address passed by the user that is to be sent as
1229 *               argument along with the command.
1230 * @param        BlkCnt - Block count passed by the user.
1231 * @param        Buff - Pointer to the data buffer for a DMA transfer.
1232 *
1233 * @return
1234 *               - XST_SUCCESS if initialization was successful
1235 *               - XST_FAILURE if failure - could be because another transfer
1236 *               is in progress or command or data inhibit is set
1237 *
1238 ******************************************************************************/
1239 s32 XSdPs_WritePolled(XSdPs *InstancePtr, u32 Arg, u32 BlkCnt, const u8 *Buff)
1240 {
1241         s32 Status;
1242         u32 PresentStateReg;
1243         u32 StatusReg;
1244
1245         if ((InstancePtr->HC_Version != XSDPS_HC_SPEC_V3) ||
1246                                 ((InstancePtr->Host_Caps & XSDPS_CAPS_SLOT_TYPE_MASK)
1247                                 != XSDPS_CAPS_EMB_SLOT)) {
1248                 if(InstancePtr->Config.CardDetect != 0U) {
1249                         /* Check status to ensure card is initialized */
1250                         PresentStateReg = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
1251                                         XSDPS_PRES_STATE_OFFSET);
1252                         if ((PresentStateReg & XSDPS_PSR_CARD_INSRT_MASK) == 0x0U) {
1253                                 Status = XST_FAILURE;
1254                                 goto RETURN_PATH;
1255                         }
1256                 }
1257         }
1258
1259         /* Set block size to 512 if not already set */
1260         if( XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
1261                         XSDPS_BLK_SIZE_OFFSET) != XSDPS_BLK_SIZE_512_MASK ) {
1262                 Status = XSdPs_SetBlkSize(InstancePtr,
1263                         XSDPS_BLK_SIZE_512_MASK);
1264                 if (Status != XST_SUCCESS) {
1265                         Status = XST_FAILURE;
1266                         goto RETURN_PATH;
1267                 }
1268
1269         }
1270
1271         XSdPs_SetupADMA2DescTbl(InstancePtr, BlkCnt, Buff);
1272         Xil_DCacheFlushRange((INTPTR)Buff, BlkCnt * XSDPS_BLK_SIZE_512_MASK);
1273
1274         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
1275                         XSDPS_XFER_MODE_OFFSET,
1276                         XSDPS_TM_AUTO_CMD12_EN_MASK |
1277                         XSDPS_TM_BLK_CNT_EN_MASK |
1278                         XSDPS_TM_MUL_SIN_BLK_SEL_MASK | XSDPS_TM_DMA_EN_MASK);
1279
1280         /* Send block write command */
1281         Status = XSdPs_CmdTransfer(InstancePtr, CMD25, Arg, BlkCnt);
1282         if (Status != XST_SUCCESS) {
1283                 Status = XST_FAILURE;
1284                 goto RETURN_PATH;
1285         }
1286
1287         /*
1288          * Check for transfer complete
1289          * Polling for response for now
1290          */
1291         do {
1292                 StatusReg = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
1293                                         XSDPS_NORM_INTR_STS_OFFSET);
1294                 if ((StatusReg & XSDPS_INTR_ERR_MASK) != 0U) {
1295                         /* Write to clear error bits */
1296                         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
1297                                         XSDPS_ERR_INTR_STS_OFFSET,
1298                                         XSDPS_ERROR_INTR_ALL_MASK);
1299                         Status = XST_FAILURE;
1300                         goto RETURN_PATH;
1301                 }
1302         } while((StatusReg & XSDPS_INTR_TC_MASK) == 0U);
1303
1304         /* Write to clear bit */
1305         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
1306                         XSDPS_NORM_INTR_STS_OFFSET, XSDPS_INTR_TC_MASK);
1307
1308         Status = XST_SUCCESS;
1309
1310         RETURN_PATH:
1311                 return Status;
1312 }
1313
1314 /*****************************************************************************/
1315 /**
1316 *
1317 * Selects card and sets default block size
1318 *
1319 *
1320 * @param        InstancePtr is a pointer to the XSdPs instance.
1321 *
1322 * @return
1323 *               - XST_SUCCESS if successful.
1324 *               - XST_FAILURE if fail.
1325 *
1326 * @note         None.
1327 *
1328 ******************************************************************************/
1329 s32 XSdPs_Select_Card (XSdPs *InstancePtr)
1330 {
1331         s32 Status = 0;
1332
1333         /* Send CMD7 - Select card */
1334         Status = XSdPs_CmdTransfer(InstancePtr, CMD7,
1335                         InstancePtr->RelCardAddr, 0U);
1336         if (Status != XST_SUCCESS) {
1337                 Status = XST_FAILURE;
1338                 goto RETURN_PATH;
1339         }
1340
1341 RETURN_PATH:
1342                 return Status;
1343
1344 }
1345
1346 /*****************************************************************************/
1347 /**
1348 *
1349 * API to setup ADMA2 descriptor table
1350 *
1351 *
1352 * @param        InstancePtr is a pointer to the XSdPs instance.
1353 * @param        BlkCnt - block count.
1354 * @param        Buff pointer to data buffer.
1355 *
1356 * @return       None
1357 *
1358 * @note         None.
1359 *
1360 ******************************************************************************/
1361 void XSdPs_SetupADMA2DescTbl(XSdPs *InstancePtr, u32 BlkCnt, const u8 *Buff)
1362 {
1363         u32 TotalDescLines = 0U;
1364         u32 DescNum = 0U;
1365         u32 BlkSize = 0U;
1366
1367         /* Setup ADMA2 - Write descriptor table and point ADMA SAR to it */
1368         BlkSize = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
1369                                         XSDPS_BLK_SIZE_OFFSET);
1370         BlkSize = BlkSize & XSDPS_BLK_SIZE_MASK;
1371
1372         if((BlkCnt*BlkSize) < XSDPS_DESC_MAX_LENGTH) {
1373
1374                 TotalDescLines = 1U;
1375
1376         }else {
1377
1378                 TotalDescLines = ((BlkCnt*BlkSize) / XSDPS_DESC_MAX_LENGTH);
1379                 if (((BlkCnt * BlkSize) % XSDPS_DESC_MAX_LENGTH) != 0U) {
1380                         TotalDescLines += 1U;
1381                 }
1382
1383         }
1384
1385         for (DescNum = 0U; DescNum < (TotalDescLines-1); DescNum++) {
1386                 InstancePtr->Adma2_DescrTbl[DescNum].Address =
1387                                 (u32)((UINTPTR)Buff + (DescNum*XSDPS_DESC_MAX_LENGTH));
1388                 InstancePtr->Adma2_DescrTbl[DescNum].Attribute =
1389                                 XSDPS_DESC_TRAN | XSDPS_DESC_VALID;
1390                 /* This will write '0' to length field which indicates 65536 */
1391                 InstancePtr->Adma2_DescrTbl[DescNum].Length =
1392                                 (u16)XSDPS_DESC_MAX_LENGTH;
1393         }
1394
1395         InstancePtr->Adma2_DescrTbl[TotalDescLines-1].Address =
1396                         (u32)((UINTPTR)Buff + (DescNum*XSDPS_DESC_MAX_LENGTH));
1397
1398         InstancePtr->Adma2_DescrTbl[TotalDescLines-1].Attribute =
1399                         XSDPS_DESC_TRAN | XSDPS_DESC_END | XSDPS_DESC_VALID;
1400
1401         InstancePtr->Adma2_DescrTbl[TotalDescLines-1].Length =
1402                         (u16)((BlkCnt*BlkSize) - (DescNum*XSDPS_DESC_MAX_LENGTH));
1403
1404
1405         XSdPs_WriteReg(InstancePtr->Config.BaseAddress, XSDPS_ADMA_SAR_OFFSET,
1406                         (u32)(UINTPTR)&(InstancePtr->Adma2_DescrTbl[0]));
1407
1408         Xil_DCacheFlushRange((INTPTR)&(InstancePtr->Adma2_DescrTbl[0]),
1409                         sizeof(XSdPs_Adma2Descriptor) * 32U);
1410
1411 }
1412
1413 /*****************************************************************************/
1414 /**
1415 * Mmc initialization is done in this function
1416 *
1417 *
1418 * @param        InstancePtr is a pointer to the instance to be worked on.
1419 *
1420 * @return
1421 *               - XST_SUCCESS if initialization was successful
1422 *               - XST_FAILURE if failure - could be because
1423 *                       a) MMC is already initialized
1424 *                       b) There is no card inserted
1425 *                       c) One of the steps (commands) in the initialization
1426 *                          cycle failed
1427 * @note         This function initializes the SD card by following its
1428 *               initialization and identification state diagram.
1429 *               CMD0 is sent to reset card.
1430 *               CMD1 sent to identify voltage and high capacity support
1431 *               CMD2 and CMD3 are sent to obtain Card ID and
1432 *               Relative card address respectively.
1433 *               CMD9 is sent to read the card specific data.
1434 *
1435 ******************************************************************************/
1436 s32 XSdPs_MmcCardInitialize(XSdPs *InstancePtr)
1437 {
1438         u32 PresentStateReg;
1439         s32 Status;
1440         u32 RespOCR;
1441         u32 CSD[4];
1442         u32 BlkLen, DeviceSize, Mult;
1443
1444         Xil_AssertNonvoid(InstancePtr != NULL);
1445         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
1446
1447         if ((InstancePtr->HC_Version != XSDPS_HC_SPEC_V3) ||
1448                                 ((InstancePtr->Host_Caps & XSDPS_CAPS_SLOT_TYPE_MASK)
1449                                 != XSDPS_CAPS_EMB_SLOT)) {
1450                 if(InstancePtr->Config.CardDetect != 0U) {
1451                         /*
1452                          * Check the present state register to make sure
1453                          * card is inserted and detected by host controller
1454                          */
1455                         PresentStateReg = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
1456                                         XSDPS_PRES_STATE_OFFSET);
1457                         if ((PresentStateReg & XSDPS_PSR_CARD_INSRT_MASK) == 0U)        {
1458                                 Status = XST_FAILURE;
1459                                 goto RETURN_PATH;
1460                         }
1461                 }
1462         }
1463
1464         /* CMD0 no response expected */
1465         Status = XSdPs_CmdTransfer(InstancePtr, CMD0, 0U, 0U);
1466         if (Status != XST_SUCCESS) {
1467                 Status = XST_FAILURE;
1468                 goto RETURN_PATH;
1469         }
1470
1471         RespOCR = 0U;
1472         /* Send CMD1 while card is still busy with power up */
1473         while ((RespOCR & XSDPS_RESPOCR_READY) == 0U) {
1474
1475                 /* Host High Capacity support & High volage window */
1476                 Status = XSdPs_CmdTransfer(InstancePtr, CMD1,
1477                                 XSDPS_ACMD41_HCS | XSDPS_CMD1_HIGH_VOL, 0U);
1478                 if (Status != XST_SUCCESS) {
1479                         Status = XST_FAILURE;
1480                         goto RETURN_PATH;
1481                 }
1482
1483                 /* Response with card capacity */
1484                 RespOCR = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
1485                                 XSDPS_RESP0_OFFSET);
1486
1487         }
1488
1489         /* Update HCS support flag based on card capacity response */
1490         if ((RespOCR & XSDPS_ACMD41_HCS) != 0U) {
1491                 InstancePtr->HCS = 1U;
1492         }
1493
1494         /* CMD2 for Card ID */
1495         Status = XSdPs_CmdTransfer(InstancePtr, CMD2, 0U, 0U);
1496         if (Status != XST_SUCCESS) {
1497                 Status = XST_FAILURE;
1498                 goto RETURN_PATH;
1499         }
1500
1501         InstancePtr->CardID[0] =
1502                         XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
1503                         XSDPS_RESP0_OFFSET);
1504         InstancePtr->CardID[1] =
1505                         XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
1506                         XSDPS_RESP1_OFFSET);
1507         InstancePtr->CardID[2] =
1508                         XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
1509                         XSDPS_RESP2_OFFSET);
1510         InstancePtr->CardID[3] =
1511                         XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
1512                         XSDPS_RESP3_OFFSET);
1513
1514         /* Set relative card address */
1515         InstancePtr->RelCardAddr = 0x12340000U;
1516         Status = XSdPs_CmdTransfer(InstancePtr, CMD3, (InstancePtr->RelCardAddr), 0U);
1517         if (Status != XST_SUCCESS) {
1518                 Status = XST_FAILURE;
1519                 goto RETURN_PATH;
1520         }
1521
1522         Status = XSdPs_CmdTransfer(InstancePtr, CMD9, (InstancePtr->RelCardAddr), 0U);
1523         if (Status != XST_SUCCESS) {
1524                 Status = XST_FAILURE;
1525                 goto RETURN_PATH;
1526         }
1527
1528         /*
1529          * Card specific data is read.
1530          * Currently not used for any operation.
1531          */
1532         CSD[0] = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
1533                         XSDPS_RESP0_OFFSET);
1534         CSD[1] = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
1535                         XSDPS_RESP1_OFFSET);
1536         CSD[2] = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
1537                         XSDPS_RESP2_OFFSET);
1538         CSD[3] = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
1539                         XSDPS_RESP3_OFFSET);
1540
1541         InstancePtr->Card_Version =  (CSD[3] & CSD_SPEC_VER_MASK) >>18U;
1542
1543         /* Calculating the memory capacity */
1544         BlkLen = 1 << ((CSD[2] & READ_BLK_LEN_MASK) >> 8U);
1545         Mult = 1 << (((CSD[1] & C_SIZE_MULT_MASK) >> 7U) + 2U);
1546         DeviceSize = (CSD[1] & C_SIZE_LOWER_MASK) >> 22U;
1547         DeviceSize |= (CSD[2] & C_SIZE_UPPER_MASK) << 10U;
1548         DeviceSize = (DeviceSize + 1U) * Mult;
1549         DeviceSize =  DeviceSize * BlkLen;
1550
1551         InstancePtr->SectorCount = (DeviceSize/XSDPS_BLK_SIZE_512_MASK);
1552
1553         Status = XST_SUCCESS;
1554
1555 RETURN_PATH:
1556         return Status;
1557
1558 }
1559 /** @} */