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