]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo_bsp/ps7_cortexa9_0/libsrc/sdps_v3_4/src/xsdps_options.c
Update Zynq, MPSoc Cortex-A53 and MPSoc Cortex-R5 demo projects to build with the...
[freertos] / FreeRTOS / Demo / CORTEX_A9_Zynq_ZC702 / RTOSDemo_bsp / ps7_cortexa9_0 / libsrc / sdps_v3_4 / src / xsdps_options.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_options.c
36 * @addtogroup sdps_v3_4
37 * @{
38 *
39 * Contains API's for changing the various options in host and card.
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.1   hk     04/18/14 Increase sleep for eMMC switch command.
49 *                       Add sleep for microblaze designs. CR# 781117.
50 * 2.3   sk     09/23/14 Use XSdPs_Change_ClkFreq API whenever changing
51 *                                               clock.CR# 816586.
52 * 2.5   sg         07/09/15 Added SD 3.0 features
53 *       kvn    07/15/15 Modified the code according to MISRAC-2012.
54 * 2.7   sk     01/08/16 Added workaround for issue in auto tuning mode
55 *                       of SDR50, SDR104 and HS200.
56 *       sk     02/16/16 Corrected the Tuning logic.
57 *       sk     03/02/16 Configured the Tap Delay values for eMMC HS200 mode.
58 * 2.8   sk     04/20/16 Added new workaround for auto tuning.
59 * 3.0   sk     07/07/16 Used usleep API for both arm and microblaze.
60 *       sk     07/16/16 Added support for UHS modes.
61 *       sk     07/16/16 Added Tap delays accordingly to different SD/eMMC
62 *                       operating modes.
63 * 3.1   mi     09/07/16 Removed compilation warnings with extra compiler flags.
64 *       sk     11/07/16 Enable Rst_n bit in ext_csd reg if not enabled.
65 *       sk     11/16/16 Issue DLL reset at 31 iteration to load new zero value.
66 * 3.2   sk     02/01/17 Added HSD and DDR mode support for eMMC.
67 *       sk     02/01/17 Consider bus width parameter from design for switching
68 *       vns    02/09/17 Added ARMA53_32 support for ZynqMP CR#968397
69 *       vns    03/13/17 Fixed MISRAC mandatory violation
70 *       sk     03/20/17 Add support for EL1 non-secure mode.
71 * 3.3   mn     07/25/17 Removed SD0_OTAPDLYENA and SD1_OTAPDLYENA bits
72 *       mn     08/07/17 Properly set OTAPDLY value by clearing previous bit
73 *                       settings
74 *       mn     08/17/17 Added CCI support for A53 and disabled data cache
75 *                       operations when it is enabled.
76 *       mn     08/22/17 Updated for Word Access System support
77 * 3.4   mn     01/22/18 Separated out SDR104 and HS200 clock defines
78 *
79 * </pre>
80 *
81 ******************************************************************************/
82
83 /***************************** Include Files *********************************/
84 #include "xsdps.h"
85 #include "sleep.h"
86 #if defined (__aarch64__)
87 #include "xil_smc.h"
88 #endif
89 /************************** Constant Definitions *****************************/
90 #define UHS_SDR12_SUPPORT       0x1U
91 #define UHS_SDR25_SUPPORT       0x2U
92 #define UHS_SDR50_SUPPORT       0x4U
93 #define UHS_SDR104_SUPPORT      0x8U
94 #define UHS_DDR50_SUPPORT       0x10U
95 /**************************** Type Definitions *******************************/
96
97 /***************** Macros (Inline Functions) Definitions *********************/
98
99 /************************** Function Prototypes ******************************/
100 s32 XSdPs_CmdTransfer(XSdPs *InstancePtr, u32 Cmd, u32 Arg, u32 BlkCnt);
101 void XSdPs_SetupADMA2DescTbl(XSdPs *InstancePtr, u32 BlkCnt, const u8 *Buff);
102 static s32 XSdPs_Execute_Tuning(XSdPs *InstancePtr);
103 #if defined (ARMR5) || defined (__aarch64__) || defined (ARMA53_32)
104 s32 XSdPs_Uhs_ModeInit(XSdPs *InstancePtr, u8 Mode);
105 static void XSdPs_sdr50_tapdelay(u32 Bank, u32 DeviceId, u32 CardType);
106 void XSdPs_SetTapDelay(XSdPs *InstancePtr);
107 static void XSdPs_DllReset(XSdPs *InstancePtr);
108 #endif
109
110 extern u16 TransferMode;
111 /*****************************************************************************/
112 /**
113 * Update Block size for read/write operations.
114 *
115 * @param        InstancePtr is a pointer to the instance to be worked on.
116 * @param        BlkSize - Block size passed by the user.
117 *
118 * @return       None
119 *
120 ******************************************************************************/
121 s32 XSdPs_SetBlkSize(XSdPs *InstancePtr, u16 BlkSize)
122 {
123         s32 Status;
124         u32 PresentStateReg;
125
126         Xil_AssertNonvoid(InstancePtr != NULL);
127         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
128
129         PresentStateReg = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
130                         XSDPS_PRES_STATE_OFFSET);
131
132         if ((PresentStateReg & ((u32)XSDPS_PSR_INHIBIT_CMD_MASK |
133                         (u32)XSDPS_PSR_INHIBIT_DAT_MASK |
134                         (u32)XSDPS_PSR_WR_ACTIVE_MASK | (u32)XSDPS_PSR_RD_ACTIVE_MASK)) != 0U) {
135                 Status = XST_FAILURE;
136                 goto RETURN_PATH;
137         }
138
139
140         /* Send block write command */
141         Status = XSdPs_CmdTransfer(InstancePtr, CMD16, BlkSize, 0U);
142         if (Status != XST_SUCCESS) {
143                 Status = XST_FAILURE;
144                 goto RETURN_PATH;
145         }
146
147         Status = (s32)XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
148                         XSDPS_RESP0_OFFSET);
149
150         /* Set block size to the value passed */
151         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress, XSDPS_BLK_SIZE_OFFSET,
152                          BlkSize & XSDPS_BLK_SIZE_MASK);
153
154         Status = XST_SUCCESS;
155
156         RETURN_PATH:
157                 return Status;
158
159 }
160
161 /*****************************************************************************/
162 /**
163 *
164 * API to get bus width support by card.
165 *
166 *
167 * @param        InstancePtr is a pointer to the XSdPs instance.
168 * @param        SCR - buffer to store SCR register returned by card.
169 *
170 * @return
171 *               - XST_SUCCESS if successful.
172 *               - XST_FAILURE if fail.
173 *
174 * @note         None.
175 *
176 ******************************************************************************/
177 s32 XSdPs_Get_BusWidth(XSdPs *InstancePtr, u8 *SCR)
178 {
179         s32 Status;
180         u32 StatusReg;
181         u16 BlkCnt;
182         u16 BlkSize;
183         s32 LoopCnt;
184
185         Xil_AssertNonvoid(InstancePtr != NULL);
186         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
187
188         for (LoopCnt = 0; LoopCnt < 8; LoopCnt++) {
189                 SCR[LoopCnt] = 0U;
190         }
191
192         /* Send block write command */
193         Status = XSdPs_CmdTransfer(InstancePtr, CMD55,
194                         InstancePtr->RelCardAddr, 0U);
195         if (Status != XST_SUCCESS) {
196                 Status = XST_FAILURE;
197                 goto RETURN_PATH;
198         }
199
200         BlkCnt = XSDPS_SCR_BLKCNT;
201         BlkSize = XSDPS_SCR_BLKSIZE;
202
203         /* Set block size to the value passed */
204         BlkSize &= XSDPS_BLK_SIZE_MASK;
205         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
206                         XSDPS_BLK_SIZE_OFFSET, BlkSize);
207
208         XSdPs_SetupADMA2DescTbl(InstancePtr, BlkCnt, SCR);
209
210         TransferMode =  XSDPS_TM_DAT_DIR_SEL_MASK | XSDPS_TM_DMA_EN_MASK;
211
212         if (InstancePtr->Config.IsCacheCoherent == 0) {
213                 Xil_DCacheInvalidateRange((INTPTR)SCR, 8);
214         }
215
216         Status = XSdPs_CmdTransfer(InstancePtr, ACMD51, 0U, BlkCnt);
217         if (Status != XST_SUCCESS) {
218                 Status = XST_FAILURE;
219                 goto RETURN_PATH;
220         }
221
222         /*
223          * Check for transfer complete
224          * Polling for response for now
225          */
226         do {
227                 StatusReg = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
228                                         XSDPS_NORM_INTR_STS_OFFSET);
229                 if ((StatusReg & XSDPS_INTR_ERR_MASK) != 0U) {
230                         /* Write to clear error bits */
231                         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
232                                         XSDPS_ERR_INTR_STS_OFFSET,
233                                         XSDPS_ERROR_INTR_ALL_MASK);
234                         Status = XST_FAILURE;
235                         goto RETURN_PATH;
236                 }
237         } while ((StatusReg & XSDPS_INTR_TC_MASK) == 0U);
238
239         /* Write to clear bit */
240         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
241                         XSDPS_NORM_INTR_STS_OFFSET, XSDPS_INTR_TC_MASK);
242
243         Status = (s32)XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
244                         XSDPS_RESP0_OFFSET);
245
246         Status = XST_SUCCESS;
247
248         RETURN_PATH:
249                 return Status;
250
251 }
252
253 /*****************************************************************************/
254 /**
255 *
256 * API to set bus width to 4-bit in card and host
257 *
258 *
259 * @param        InstancePtr is a pointer to the XSdPs instance.
260 *
261 * @return
262 *               - XST_SUCCESS if successful.
263 *               - XST_FAILURE if fail.
264 *
265 * @note         None.
266 *
267 ******************************************************************************/
268 s32 XSdPs_Change_BusWidth(XSdPs *InstancePtr)
269 {
270         s32 Status;
271         u32 StatusReg;
272         u32 Arg;
273
274         Xil_AssertNonvoid(InstancePtr != NULL);
275         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
276
277
278         /*
279          * check for bus width for 3.0 controller and return if
280          * bus width is <4
281          */
282         if ((InstancePtr->HC_Version == XSDPS_HC_SPEC_V3) &&
283                         (InstancePtr->Config.BusWidth < XSDPS_WIDTH_4)) {
284                 Status = XST_SUCCESS;
285                 goto RETURN_PATH;
286         }
287
288         if (InstancePtr->CardType == XSDPS_CARD_SD) {
289
290                 Status = XSdPs_CmdTransfer(InstancePtr, CMD55, InstancePtr->RelCardAddr,
291                                 0U);
292                 if (Status != XST_SUCCESS) {
293                         Status = XST_FAILURE;
294                         goto RETURN_PATH;
295                 }
296
297                 InstancePtr->BusWidth = XSDPS_4_BIT_WIDTH;
298
299                 Arg = ((u32)InstancePtr->BusWidth);
300
301                 Status = XSdPs_CmdTransfer(InstancePtr, ACMD6, Arg, 0U);
302                 if (Status != XST_SUCCESS) {
303                         Status = XST_FAILURE;
304                         goto RETURN_PATH;
305                 }
306         } else {
307
308                 if ((InstancePtr->HC_Version == XSDPS_HC_SPEC_V3)
309                                 && (InstancePtr->CardType == XSDPS_CHIP_EMMC) &&
310                                 (InstancePtr->Config.BusWidth == XSDPS_WIDTH_8)) {
311                         /* in case of eMMC data width 8-bit */
312                         InstancePtr->BusWidth = XSDPS_8_BIT_WIDTH;
313                 } else {
314                         InstancePtr->BusWidth = XSDPS_4_BIT_WIDTH;
315                 }
316
317                 if (InstancePtr->BusWidth == XSDPS_8_BIT_WIDTH) {
318                         if (InstancePtr->Mode == XSDPS_DDR52_MODE)
319                                 Arg = XSDPS_MMC_DDR_8_BIT_BUS_ARG;
320                         else
321                                 Arg = XSDPS_MMC_8_BIT_BUS_ARG;
322                 } else {
323                         if (InstancePtr->Mode == XSDPS_DDR52_MODE)
324                                 Arg = XSDPS_MMC_DDR_4_BIT_BUS_ARG;
325                         else
326                                 Arg = XSDPS_MMC_4_BIT_BUS_ARG;
327                 }
328
329                 Status = XSdPs_CmdTransfer(InstancePtr, CMD6, Arg, 0U);
330                 if (Status != XST_SUCCESS) {
331                         Status = XST_FAILURE;
332                         goto RETURN_PATH;
333                 }
334
335                 /* Check for transfer complete */
336                 do {
337                         StatusReg = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
338                                                 XSDPS_NORM_INTR_STS_OFFSET);
339                         if ((StatusReg & XSDPS_INTR_ERR_MASK) != 0U) {
340                                 /* Write to clear error bits */
341                                 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
342                                                 XSDPS_ERR_INTR_STS_OFFSET,
343                                                 XSDPS_ERROR_INTR_ALL_MASK);
344                                 Status = XST_FAILURE;
345                                 goto RETURN_PATH;
346                         }
347                 } while((StatusReg & XSDPS_INTR_TC_MASK) == 0U);
348
349                 /* Write to clear bit */
350                 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
351                                 XSDPS_NORM_INTR_STS_OFFSET, XSDPS_INTR_TC_MASK);
352         }
353
354         usleep(XSDPS_MMC_DELAY_FOR_SWITCH);
355
356         StatusReg = XSdPs_ReadReg8(InstancePtr->Config.BaseAddress,
357                                         XSDPS_HOST_CTRL1_OFFSET);
358
359         /* Width setting in controller */
360         if (InstancePtr->BusWidth == XSDPS_8_BIT_WIDTH) {
361                 StatusReg |= XSDPS_HC_EXT_BUS_WIDTH;
362         } else {
363                 StatusReg |= XSDPS_HC_WIDTH_MASK;
364         }
365
366         XSdPs_WriteReg8(InstancePtr->Config.BaseAddress,
367                         XSDPS_HOST_CTRL1_OFFSET,
368                         (u8)StatusReg);
369
370         if (InstancePtr->Mode == XSDPS_DDR52_MODE) {
371                 StatusReg = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
372                                         XSDPS_HOST_CTRL2_OFFSET);
373                 StatusReg &= (u16)(~XSDPS_HC2_UHS_MODE_MASK);
374                 StatusReg |= InstancePtr->Mode;
375                 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
376                                 XSDPS_HOST_CTRL2_OFFSET, StatusReg);
377         }
378
379         Status = (s32)XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
380                         XSDPS_RESP0_OFFSET);
381
382         Status = XST_SUCCESS;
383
384         RETURN_PATH:
385                 return Status;
386
387 }
388
389 /*****************************************************************************/
390 /**
391 *
392 * API to get bus speed supported by card.
393 *
394 *
395 * @param        InstancePtr is a pointer to the XSdPs instance.
396 * @param        ReadBuff - buffer to store function group support data
397 *               returned by card.
398 *
399 * @return
400 *               - XST_SUCCESS if successful.
401 *               - XST_FAILURE if fail.
402 *
403 * @note         None.
404 *
405 ******************************************************************************/
406 s32 XSdPs_Get_BusSpeed(XSdPs *InstancePtr, u8 *ReadBuff)
407 {
408         s32 Status;
409         u32 StatusReg;
410         u32 Arg;
411         u16 BlkCnt;
412         u16 BlkSize;
413         s32 LoopCnt;
414
415         Xil_AssertNonvoid(InstancePtr != NULL);
416         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
417
418         for (LoopCnt = 0; LoopCnt < 64; LoopCnt++) {
419                 ReadBuff[LoopCnt] = 0U;
420         }
421
422         BlkCnt = XSDPS_SWITCH_CMD_BLKCNT;
423         BlkSize = XSDPS_SWITCH_CMD_BLKSIZE;
424         BlkSize &= XSDPS_BLK_SIZE_MASK;
425         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
426                         XSDPS_BLK_SIZE_OFFSET, BlkSize);
427
428         XSdPs_SetupADMA2DescTbl(InstancePtr, BlkCnt, ReadBuff);
429
430         TransferMode =  XSDPS_TM_DAT_DIR_SEL_MASK | XSDPS_TM_DMA_EN_MASK;
431
432         Arg = XSDPS_SWITCH_CMD_HS_GET;
433
434         if (InstancePtr->Config.IsCacheCoherent == 0) {
435                 Xil_DCacheInvalidateRange((INTPTR)ReadBuff, 64);
436         }
437
438         Status = XSdPs_CmdTransfer(InstancePtr, CMD6, Arg, 1U);
439         if (Status != XST_SUCCESS) {
440                 Status = XST_FAILURE;
441                 goto RETURN_PATH;
442         }
443
444         /*
445          * Check for transfer complete
446          * Polling for response for now
447          */
448         do {
449                 StatusReg = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
450                                         XSDPS_NORM_INTR_STS_OFFSET);
451                 if ((StatusReg & XSDPS_INTR_ERR_MASK) != 0U) {
452                         /* Write to clear error bits */
453                         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
454                                         XSDPS_ERR_INTR_STS_OFFSET,
455                                         XSDPS_ERROR_INTR_ALL_MASK);
456                         Status = XST_FAILURE;
457                         goto RETURN_PATH;
458                 }
459         } while ((StatusReg & XSDPS_INTR_TC_MASK) == 0U);
460
461         /* Write to clear bit */
462         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
463                         XSDPS_NORM_INTR_STS_OFFSET, XSDPS_INTR_TC_MASK);
464
465         Status = (s32)XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
466                         XSDPS_RESP0_OFFSET);
467
468         Status = XST_SUCCESS;
469
470         RETURN_PATH:
471                 return Status;
472
473 }
474
475 /*****************************************************************************/
476 /**
477 *
478 * API to set high speed in card and host. Changes clock in host accordingly.
479 *
480 *
481 * @param        InstancePtr is a pointer to the XSdPs instance.
482 *
483 * @return
484 *               - XST_SUCCESS if successful.
485 *               - XST_FAILURE if fail.
486 *
487 * @note         None.
488 *
489 ******************************************************************************/
490 s32 XSdPs_Change_BusSpeed(XSdPs *InstancePtr)
491 {
492         s32 Status;
493         u32 StatusReg;
494         u32 Arg;
495         u16 BlkCnt;
496         u16 BlkSize;
497         u8 ReadBuff[64] = {0U};
498
499         Xil_AssertNonvoid(InstancePtr != NULL);
500         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
501
502         if (InstancePtr->CardType == XSDPS_CARD_SD) {
503
504                 BlkCnt = XSDPS_SWITCH_CMD_BLKCNT;
505                 BlkSize = XSDPS_SWITCH_CMD_BLKSIZE;
506                 BlkSize &= XSDPS_BLK_SIZE_MASK;
507                 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
508                                 XSDPS_BLK_SIZE_OFFSET, BlkSize);
509
510                 XSdPs_SetupADMA2DescTbl(InstancePtr, BlkCnt, ReadBuff);
511
512                 if (InstancePtr->Config.IsCacheCoherent == 0) {
513                         Xil_DCacheFlushRange((INTPTR)ReadBuff, 64);
514                 }
515
516                 TransferMode =  XSDPS_TM_DAT_DIR_SEL_MASK | XSDPS_TM_DMA_EN_MASK;
517
518                 Arg = XSDPS_SWITCH_CMD_HS_SET;
519
520                 Status = XSdPs_CmdTransfer(InstancePtr, CMD6, Arg, 1U);
521                 if (Status != XST_SUCCESS) {
522                         Status = XST_FAILURE;
523                         goto RETURN_PATH;
524                 }
525
526                 /*
527                  * Check for transfer complete
528                  * Polling for response for now
529                  */
530                 do {
531                         StatusReg = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
532                                                 XSDPS_NORM_INTR_STS_OFFSET);
533                         if ((StatusReg & XSDPS_INTR_ERR_MASK) != 0U) {
534                                 /* Write to clear error bits */
535                                 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
536                                                 XSDPS_ERR_INTR_STS_OFFSET,
537                                                 XSDPS_ERROR_INTR_ALL_MASK);
538                                 Status = XST_FAILURE;
539                                 goto RETURN_PATH;
540                         }
541                 } while ((StatusReg & XSDPS_INTR_TC_MASK) == 0U);
542
543                 /* Write to clear bit */
544                 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
545                                 XSDPS_NORM_INTR_STS_OFFSET, XSDPS_INTR_TC_MASK);
546
547                 /* Change the clock frequency to 50 MHz */
548                 InstancePtr->BusSpeed = XSDPS_CLK_50_MHZ;
549                 Status = XSdPs_Change_ClkFreq(InstancePtr, InstancePtr->BusSpeed);
550                 if (Status != XST_SUCCESS) {
551                                 Status = XST_FAILURE;
552                                 goto RETURN_PATH;
553                 }
554
555         } else if (InstancePtr->CardType == XSDPS_CARD_MMC) {
556                 Arg = XSDPS_MMC_HIGH_SPEED_ARG;
557
558                 Status = XSdPs_CmdTransfer(InstancePtr, CMD6, Arg, 0U);
559                 if (Status != XST_SUCCESS) {
560                         Status = XST_FAILURE;
561                         goto RETURN_PATH;
562                 }
563
564                 /*
565                  * Check for transfer complete
566                  */
567                 do {
568                         StatusReg = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
569                                                 XSDPS_NORM_INTR_STS_OFFSET);
570                         if ((StatusReg & XSDPS_INTR_ERR_MASK) != 0U) {
571                                 /*
572                                  * Write to clear error bits
573                                  */
574                                 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
575                                                 XSDPS_ERR_INTR_STS_OFFSET,
576                                                 XSDPS_ERROR_INTR_ALL_MASK);
577                                 Status = XST_FAILURE;
578                                 goto RETURN_PATH;
579                         }
580                 } while ((StatusReg & XSDPS_INTR_TC_MASK) == 0U);
581
582                 /*
583                  * Write to clear bit
584                  */
585                 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
586                                 XSDPS_NORM_INTR_STS_OFFSET, XSDPS_INTR_TC_MASK);
587
588                 /* Change the clock frequency to 52 MHz */
589                 InstancePtr->BusSpeed = XSDPS_CLK_52_MHZ;
590                 Status = XSdPs_Change_ClkFreq(InstancePtr, XSDPS_CLK_52_MHZ);
591                 if (Status != XST_SUCCESS) {
592                         Status = XST_FAILURE;
593                         goto RETURN_PATH;
594                 }
595         } else {
596                 if (InstancePtr->Mode == XSDPS_HS200_MODE) {
597                         Arg = XSDPS_MMC_HS200_ARG;
598                         InstancePtr->BusSpeed = XSDPS_MMC_HS200_MAX_CLK;
599                 } else if (InstancePtr->Mode == XSDPS_DDR52_MODE) {
600                         Arg = XSDPS_MMC_HIGH_SPEED_ARG;
601                         InstancePtr->BusSpeed = XSDPS_MMC_DDR_MAX_CLK;
602                 } else {
603                         Arg = XSDPS_MMC_HIGH_SPEED_ARG;
604                         InstancePtr->BusSpeed = XSDPS_MMC_HSD_MAX_CLK;
605                 }
606
607                 Status = XSdPs_CmdTransfer(InstancePtr, CMD6, Arg, 0U);
608                 if (Status != XST_SUCCESS) {
609                         Status = XST_FAILURE;
610                         goto RETURN_PATH;
611                 }
612
613                 /*
614                  * Check for transfer complete
615                  */
616                 do {
617                         StatusReg = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
618                                                 XSDPS_NORM_INTR_STS_OFFSET);
619                         if ((StatusReg & XSDPS_INTR_ERR_MASK) != 0U) {
620                                 /*
621                                  * Write to clear error bits
622                                  */
623                                 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
624                                                 XSDPS_ERR_INTR_STS_OFFSET,
625                                                 XSDPS_ERROR_INTR_ALL_MASK);
626                                 Status = XST_FAILURE;
627                                 goto RETURN_PATH;
628                         }
629                 } while ((StatusReg & XSDPS_INTR_TC_MASK) == 0U);
630
631                 /*
632                  * Write to clear bit
633                  */
634                 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
635                                 XSDPS_NORM_INTR_STS_OFFSET, XSDPS_INTR_TC_MASK);
636
637                 Status = XSdPs_Change_ClkFreq(InstancePtr, InstancePtr->BusSpeed);
638                 if (Status != XST_SUCCESS) {
639                         Status = XST_FAILURE;
640                         goto RETURN_PATH;
641                 }
642
643                 if (InstancePtr->Mode == XSDPS_HS200_MODE) {
644                         Status = XSdPs_Execute_Tuning(InstancePtr);
645                         if (Status != XST_SUCCESS) {
646                                 Status = XST_FAILURE;
647                                 goto RETURN_PATH;
648                         }
649                 }
650         }
651
652         usleep(XSDPS_MMC_DELAY_FOR_SWITCH);
653
654         StatusReg = (s32)XSdPs_ReadReg8(InstancePtr->Config.BaseAddress,
655                                         XSDPS_HOST_CTRL1_OFFSET);
656         StatusReg |= XSDPS_HC_SPEED_MASK;
657         XSdPs_WriteReg8(InstancePtr->Config.BaseAddress,
658                         XSDPS_HOST_CTRL1_OFFSET, (u8)StatusReg);
659
660         Status = (s32)XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
661                         XSDPS_RESP0_OFFSET);
662
663
664         Status = XST_SUCCESS;
665
666         RETURN_PATH:
667                 return Status;
668
669 }
670
671 /*****************************************************************************/
672 /**
673 *
674 * API to change clock freq to given value.
675 *
676 *
677 * @param        InstancePtr is a pointer to the XSdPs instance.
678 * @param        SelFreq - Clock frequency in Hz.
679 *
680 * @return       None
681 *
682 * @note         This API will change clock frequency to the value less than
683 *               or equal to the given value using the permissible dividors.
684 *
685 ******************************************************************************/
686 s32 XSdPs_Change_ClkFreq(XSdPs *InstancePtr, u32 SelFreq)
687 {
688         u16 ClockReg;
689         u16 DivCnt;
690         u16 Divisor = 0U;
691         u16 ExtDivisor;
692         s32 Status;
693         u16 ReadReg;
694
695         Xil_AssertNonvoid(InstancePtr != NULL);
696         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
697
698         /* Disable clock */
699         ClockReg = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
700                         XSDPS_CLK_CTRL_OFFSET);
701         ClockReg &= ~(XSDPS_CC_SD_CLK_EN_MASK | XSDPS_CC_INT_CLK_EN_MASK);
702         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
703                         XSDPS_CLK_CTRL_OFFSET, ClockReg);
704
705         if (InstancePtr->HC_Version == XSDPS_HC_SPEC_V3) {
706 #if defined (ARMR5) || defined (__aarch64__) || defined (ARMA53_32)
707         if ((InstancePtr->Mode != XSDPS_DEFAULT_SPEED_MODE) &&
708                         (InstancePtr->Mode != XSDPS_UHS_SPEED_MODE_SDR12))
709                 /* Program the Tap delays */
710                 XSdPs_SetTapDelay(InstancePtr);
711 #endif
712                 /* Calculate divisor */
713                 for (DivCnt = 0x1U; DivCnt <= XSDPS_CC_EXT_MAX_DIV_CNT;DivCnt++) {
714                         if (((InstancePtr->Config.InputClockHz) / DivCnt) <= SelFreq) {
715                                 Divisor = DivCnt >> 1;
716                                 break;
717                         }
718                 }
719
720                 if (DivCnt > XSDPS_CC_EXT_MAX_DIV_CNT) {
721                         /* No valid divisor found for given frequency */
722                         Status = XST_FAILURE;
723                         goto RETURN_PATH;
724                 }
725         } else {
726                 /* Calculate divisor */
727                 DivCnt = 0x1U;
728                 while (DivCnt <= XSDPS_CC_MAX_DIV_CNT) {
729                         if (((InstancePtr->Config.InputClockHz) / DivCnt) <= SelFreq) {
730                                 Divisor = DivCnt / 2U;
731                                 break;
732                         }
733                         DivCnt = DivCnt << 1U;
734                 }
735
736                 if (DivCnt > XSDPS_CC_MAX_DIV_CNT) {
737                         /* No valid divisor found for given frequency */
738                         Status = XST_FAILURE;
739                         goto RETURN_PATH;
740                 }
741         }
742
743         /* Set clock divisor */
744         if (InstancePtr->HC_Version == XSDPS_HC_SPEC_V3) {
745                 ClockReg = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
746                                 XSDPS_CLK_CTRL_OFFSET);
747                 ClockReg &= ~(XSDPS_CC_SDCLK_FREQ_SEL_MASK |
748                 XSDPS_CC_SDCLK_FREQ_SEL_EXT_MASK);
749
750                 ExtDivisor = Divisor >> 8;
751                 ExtDivisor <<= XSDPS_CC_EXT_DIV_SHIFT;
752                 ExtDivisor &= XSDPS_CC_SDCLK_FREQ_SEL_EXT_MASK;
753
754                 Divisor <<= XSDPS_CC_DIV_SHIFT;
755                 Divisor &= XSDPS_CC_SDCLK_FREQ_SEL_MASK;
756                 ClockReg |= Divisor | ExtDivisor | (u16)XSDPS_CC_INT_CLK_EN_MASK;
757                 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress, XSDPS_CLK_CTRL_OFFSET,
758                                 ClockReg);
759         } else {
760                 ClockReg = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
761                                 XSDPS_CLK_CTRL_OFFSET);
762                 ClockReg &= (~XSDPS_CC_SDCLK_FREQ_SEL_MASK);
763
764                 Divisor <<= XSDPS_CC_DIV_SHIFT;
765                 Divisor &= XSDPS_CC_SDCLK_FREQ_SEL_MASK;
766                 ClockReg |= Divisor | (u16)XSDPS_CC_INT_CLK_EN_MASK;
767                 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress, XSDPS_CLK_CTRL_OFFSET,
768                                 ClockReg);
769         }
770
771         /* Wait for internal clock to stabilize */
772         ReadReg = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
773                                 XSDPS_CLK_CTRL_OFFSET);
774         while((ReadReg & XSDPS_CC_INT_CLK_STABLE_MASK) == 0U) {
775                 ReadReg = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
776                                         XSDPS_CLK_CTRL_OFFSET);;
777         }
778
779         /* Enable SD clock */
780         ClockReg = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
781                         XSDPS_CLK_CTRL_OFFSET);
782         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
783                         XSDPS_CLK_CTRL_OFFSET,
784                         ClockReg | XSDPS_CC_SD_CLK_EN_MASK);
785
786         Status = XST_SUCCESS;
787
788 RETURN_PATH:
789                 return Status;
790
791 }
792
793 /*****************************************************************************/
794 /**
795 *
796 * API to send pullup command to card before using DAT line 3(using 4-bit bus)
797 *
798 *
799 * @param        InstancePtr is a pointer to the XSdPs instance.
800 *
801 * @return
802 *               - XST_SUCCESS if successful.
803 *               - XST_FAILURE if fail.
804 *
805 * @note         None.
806 *
807 ******************************************************************************/
808 s32 XSdPs_Pullup(XSdPs *InstancePtr)
809 {
810         s32 Status;
811
812         Xil_AssertNonvoid(InstancePtr != NULL);
813         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
814
815         Status = XSdPs_CmdTransfer(InstancePtr, CMD55,
816                         InstancePtr->RelCardAddr, 0U);
817         if (Status != XST_SUCCESS) {
818                 Status = XST_FAILURE;
819                 goto RETURN_PATH;
820         }
821
822         Status = XSdPs_CmdTransfer(InstancePtr, ACMD42, 0U, 0U);
823         if (Status != XST_SUCCESS) {
824                 Status = XST_FAILURE;
825                 goto RETURN_PATH;
826         }
827
828         Status = XST_SUCCESS;
829
830         RETURN_PATH:
831                 return Status;
832
833 }
834
835 /*****************************************************************************/
836 /**
837 *
838 * API to get EXT_CSD register of eMMC.
839 *
840 *
841 * @param        InstancePtr is a pointer to the XSdPs instance.
842 * @param        ReadBuff - buffer to store EXT_CSD
843 *
844 * @return
845 *               - XST_SUCCESS if successful.
846 *               - XST_FAILURE if fail.
847 *
848 * @note         None.
849 *
850 ******************************************************************************/
851 s32 XSdPs_Get_Mmc_ExtCsd(XSdPs *InstancePtr, u8 *ReadBuff)
852 {
853         s32 Status;
854         u32 StatusReg;
855         u32 Arg = 0U;
856         u16 BlkCnt;
857         u16 BlkSize;
858         s32 LoopCnt;
859
860         Xil_AssertNonvoid(InstancePtr != NULL);
861         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
862
863         for (LoopCnt = 0; LoopCnt < 512; LoopCnt++) {
864                 ReadBuff[LoopCnt] = 0U;
865         }
866
867         BlkCnt = XSDPS_EXT_CSD_CMD_BLKCNT;
868         BlkSize = XSDPS_EXT_CSD_CMD_BLKSIZE;
869         BlkSize &= XSDPS_BLK_SIZE_MASK;
870         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
871                         XSDPS_BLK_SIZE_OFFSET, BlkSize);
872
873         XSdPs_SetupADMA2DescTbl(InstancePtr, BlkCnt, ReadBuff);
874
875         if (InstancePtr->Config.IsCacheCoherent == 0) {
876                 Xil_DCacheInvalidateRange((INTPTR)ReadBuff, 512U);
877         }
878
879         TransferMode =  XSDPS_TM_DAT_DIR_SEL_MASK | XSDPS_TM_DMA_EN_MASK;
880
881         /* Send SEND_EXT_CSD command */
882         Status = XSdPs_CmdTransfer(InstancePtr, CMD8, Arg, 1U);
883         if (Status != XST_SUCCESS) {
884                 Status = XST_FAILURE;
885                 goto RETURN_PATH;
886         }
887
888         /*
889          * Check for transfer complete
890          * Polling for response for now
891          */
892         do {
893                 StatusReg = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
894                                         XSDPS_NORM_INTR_STS_OFFSET);
895                 if ((StatusReg & XSDPS_INTR_ERR_MASK) != 0U) {
896                         /* Write to clear error bits */
897                         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
898                                         XSDPS_ERR_INTR_STS_OFFSET,
899                                         XSDPS_ERROR_INTR_ALL_MASK);
900                         Status = XST_FAILURE;
901                         goto RETURN_PATH;
902                 }
903         } while ((StatusReg & XSDPS_INTR_TC_MASK) == 0U);
904
905         /* Write to clear bit */
906         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
907                         XSDPS_NORM_INTR_STS_OFFSET, XSDPS_INTR_TC_MASK);
908
909         Status = (s32)XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
910                         XSDPS_RESP0_OFFSET);
911
912         Status = XST_SUCCESS;
913
914         RETURN_PATH:
915                 return Status;
916
917 }
918
919 /*****************************************************************************/
920 /**
921 *
922 * API to write EXT_CSD register of eMMC.
923 *
924 *
925 * @param        InstancePtr is a pointer to the XSdPs instance.
926 * @param        Arg is the argument to be sent along with the command
927 *
928 * @return
929 *               - XST_SUCCESS if successful.
930 *               - XST_FAILURE if fail.
931 *
932 * @note         None.
933 *
934 ******************************************************************************/
935 s32 XSdPs_Set_Mmc_ExtCsd(XSdPs *InstancePtr, u32 Arg)
936 {
937         s32 Status;
938         u32 StatusReg;
939
940         Status = XSdPs_CmdTransfer(InstancePtr, CMD6, Arg, 0U);
941         if (Status != XST_SUCCESS) {
942                 Status = XST_FAILURE;
943                 goto RETURN_PATH;
944         }
945
946         /*
947          * Check for transfer complete
948          */
949         do {
950                 StatusReg = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
951                                         XSDPS_NORM_INTR_STS_OFFSET);
952                 if ((StatusReg & XSDPS_INTR_ERR_MASK) != 0U) {
953                         /*
954                          * Write to clear error bits
955                          */
956                         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
957                                         XSDPS_ERR_INTR_STS_OFFSET,
958                                         XSDPS_ERROR_INTR_ALL_MASK);
959                         Status = XST_FAILURE;
960                         goto RETURN_PATH;
961                 }
962         } while ((StatusReg & XSDPS_INTR_TC_MASK) == 0U);
963
964         /* Write to clear bit */
965         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
966                         XSDPS_NORM_INTR_STS_OFFSET, XSDPS_INTR_TC_MASK);
967
968         Status = (s32)XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
969                         XSDPS_RESP0_OFFSET);
970
971         Status = XST_SUCCESS;
972
973         RETURN_PATH:
974                 return Status;
975
976 }
977
978 #if defined (ARMR5) || defined (__aarch64__) || defined (ARMA53_32)
979 /*****************************************************************************/
980 /**
981 *
982 * API to Identify the supported UHS mode. This API will assign the
983 * corresponding tap delay API to the Config_TapDelay pointer based on the
984 * supported bus speed.
985 *
986 *
987 * @param        InstancePtr is a pointer to the XSdPs instance.
988 * @param        ReadBuff contains the response for CMD6
989 *
990 * @return       None.
991 *
992 * @note         None.
993 *
994 ******************************************************************************/
995 void XSdPs_Identify_UhsMode(XSdPs *InstancePtr, u8 *ReadBuff)
996 {
997
998         Xil_AssertVoid(InstancePtr != NULL);
999
1000         if (((ReadBuff[13] & UHS_SDR104_SUPPORT) != 0U) &&
1001                 (InstancePtr->Config.InputClockHz >= XSDPS_SD_INPUT_MAX_CLK)) {
1002                 InstancePtr->Mode = XSDPS_UHS_SPEED_MODE_SDR104;
1003                 InstancePtr->Config_TapDelay = XSdPs_sdr104_hs200_tapdelay;
1004         }
1005         else if (((ReadBuff[13] & UHS_SDR50_SUPPORT) != 0U) &&
1006                 (InstancePtr->Config.InputClockHz >= XSDPS_SD_SDR50_MAX_CLK)) {
1007                 InstancePtr->Mode = XSDPS_UHS_SPEED_MODE_SDR50;
1008                 InstancePtr->Config_TapDelay = XSdPs_sdr50_tapdelay;
1009         }
1010         else if (((ReadBuff[13] & UHS_DDR50_SUPPORT) != 0U) &&
1011                 (InstancePtr->Config.InputClockHz >= XSDPS_SD_DDR50_MAX_CLK)) {
1012                 InstancePtr->Mode = XSDPS_UHS_SPEED_MODE_DDR50;
1013                 InstancePtr->Config_TapDelay = XSdPs_ddr50_tapdelay;
1014         }
1015         else if (((ReadBuff[13] & UHS_SDR25_SUPPORT) != 0U) &&
1016                 (InstancePtr->Config.InputClockHz >= XSDPS_SD_SDR25_MAX_CLK)) {
1017                 InstancePtr->Mode = XSDPS_UHS_SPEED_MODE_SDR25;
1018                 InstancePtr->Config_TapDelay = XSdPs_hsd_sdr25_tapdelay;
1019         }
1020         else
1021                 InstancePtr->Mode = XSDPS_UHS_SPEED_MODE_SDR12;
1022 }
1023
1024 /*****************************************************************************/
1025 /**
1026 *
1027 * API to UHS-I mode initialization
1028 *
1029 *
1030 * @param        InstancePtr is a pointer to the XSdPs instance.
1031 * @param        Mode UHS-I mode
1032 *
1033 * @return
1034 *               - XST_SUCCESS if successful.
1035 *               - XST_FAILURE if fail.
1036 *
1037 * @note         None.
1038 *
1039 ******************************************************************************/
1040 s32 XSdPs_Uhs_ModeInit(XSdPs *InstancePtr, u8 Mode)
1041 {
1042         s32 Status;
1043         u16 StatusReg;
1044         u16 CtrlReg;
1045         u32 Arg;
1046         u16 BlkCnt;
1047         u16 BlkSize;
1048         u8 ReadBuff[64] = {0U};
1049
1050         Xil_AssertNonvoid(InstancePtr != NULL);
1051         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
1052
1053         /* Drive strength */
1054
1055         /* Bus speed mode selection */
1056         BlkCnt = XSDPS_SWITCH_CMD_BLKCNT;
1057         BlkSize = XSDPS_SWITCH_CMD_BLKSIZE;
1058         BlkSize &= XSDPS_BLK_SIZE_MASK;
1059         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress, XSDPS_BLK_SIZE_OFFSET,
1060                         BlkSize);
1061
1062         XSdPs_SetupADMA2DescTbl(InstancePtr, BlkCnt, ReadBuff);
1063
1064         if (InstancePtr->Config.IsCacheCoherent == 0) {
1065                 Xil_DCacheFlushRange((INTPTR)ReadBuff, 64);
1066         }
1067
1068         TransferMode =  XSDPS_TM_DAT_DIR_SEL_MASK | XSDPS_TM_DMA_EN_MASK;
1069
1070         switch (Mode) {
1071         case 0U:
1072                 Arg = XSDPS_SWITCH_CMD_SDR12_SET;
1073                 InstancePtr->BusSpeed = XSDPS_SD_SDR12_MAX_CLK;
1074                 break;
1075         case 1U:
1076                 Arg = XSDPS_SWITCH_CMD_SDR25_SET;
1077                 InstancePtr->BusSpeed = XSDPS_SD_SDR25_MAX_CLK;
1078                 break;
1079         case 2U:
1080                 Arg = XSDPS_SWITCH_CMD_SDR50_SET;
1081                 InstancePtr->BusSpeed = XSDPS_SD_SDR50_MAX_CLK;
1082                 break;
1083         case 3U:
1084                 Arg = XSDPS_SWITCH_CMD_SDR104_SET;
1085                 InstancePtr->BusSpeed = XSDPS_SD_SDR104_MAX_CLK;
1086                 break;
1087         case 4U:
1088                 Arg = XSDPS_SWITCH_CMD_DDR50_SET;
1089                 InstancePtr->BusSpeed = XSDPS_SD_DDR50_MAX_CLK;
1090                 break;
1091         default:
1092                 Status = XST_FAILURE;
1093                 goto RETURN_PATH;
1094                 break;
1095         }
1096
1097         Status = XSdPs_CmdTransfer(InstancePtr, CMD6, Arg, 1U);
1098         if (Status != XST_SUCCESS) {
1099                 Status = XST_FAILURE;
1100                 goto RETURN_PATH;
1101         }
1102
1103         /*
1104          * Check for transfer complete
1105          * Polling for response for now
1106          */
1107         do {
1108                 StatusReg = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
1109                                 XSDPS_NORM_INTR_STS_OFFSET);
1110                 if ((StatusReg & XSDPS_INTR_ERR_MASK) != 0U) {
1111                         /* Write to clear error bits */
1112                         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
1113                                         XSDPS_ERR_INTR_STS_OFFSET, XSDPS_ERROR_INTR_ALL_MASK);
1114                         Status = XST_FAILURE;
1115                         goto RETURN_PATH;
1116                 }
1117         } while ((StatusReg & XSDPS_INTR_TC_MASK) == 0U);
1118
1119         /* Write to clear bit */
1120         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
1121                         XSDPS_NORM_INTR_STS_OFFSET, XSDPS_INTR_TC_MASK);
1122
1123
1124         /* Current limit */
1125
1126         /* Set UHS mode in controller */
1127         CtrlReg = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
1128                         XSDPS_HOST_CTRL2_OFFSET);
1129         CtrlReg &= (u16)(~XSDPS_HC2_UHS_MODE_MASK);
1130         CtrlReg |= Mode;
1131         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
1132                         XSDPS_HOST_CTRL2_OFFSET, CtrlReg);
1133
1134         /* Change the clock frequency */
1135         Status = XSdPs_Change_ClkFreq(InstancePtr, InstancePtr->BusSpeed);
1136         if (Status != XST_SUCCESS) {
1137                         Status = XST_FAILURE;
1138                         goto RETURN_PATH;
1139         }
1140
1141         if((Mode == XSDPS_UHS_SPEED_MODE_SDR104) ||
1142                         (Mode == XSDPS_UHS_SPEED_MODE_SDR50)) {
1143                 /* Send tuning pattern */
1144                 Status = XSdPs_Execute_Tuning(InstancePtr);
1145                 if (Status != XST_SUCCESS) {
1146                                 Status = XST_FAILURE;
1147                                 goto RETURN_PATH;
1148                 }
1149         }
1150
1151         Status = XST_SUCCESS;
1152
1153         RETURN_PATH:
1154                 return Status;
1155 }
1156 #endif
1157
1158 static s32 XSdPs_Execute_Tuning(XSdPs *InstancePtr)
1159 {
1160         s32 Status;
1161         u16 BlkSize;
1162         u16 CtrlReg;
1163         u8 TuningCount;
1164
1165         Xil_AssertNonvoid(InstancePtr != NULL);
1166         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
1167
1168         BlkSize = XSDPS_TUNING_CMD_BLKSIZE;
1169         if(InstancePtr->BusWidth == XSDPS_8_BIT_WIDTH)
1170         {
1171                 BlkSize = BlkSize*2U;
1172         }
1173         BlkSize &= XSDPS_BLK_SIZE_MASK;
1174         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress, XSDPS_BLK_SIZE_OFFSET,
1175                         BlkSize);
1176
1177         TransferMode =  XSDPS_TM_DAT_DIR_SEL_MASK;
1178
1179         CtrlReg = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
1180                                 XSDPS_HOST_CTRL2_OFFSET);
1181         CtrlReg |= XSDPS_HC2_EXEC_TNG_MASK;
1182         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
1183                                 XSDPS_HOST_CTRL2_OFFSET, CtrlReg);
1184
1185         /*
1186          * workaround which can work for 1.0/2.0 silicon for auto tuning.
1187          * This can be revisited for 3.0 silicon if necessary.
1188          */
1189         /* Wait for ~60 clock cycles to reset the tap values */
1190         (void)usleep(1U);
1191
1192 #if defined (ARMR5) || defined (__aarch64__) || defined (ARMA53_32)
1193         /* Issue DLL Reset to load new SDHC tuned tap values */
1194         XSdPs_DllReset(InstancePtr);
1195 #endif
1196
1197         for (TuningCount = 0U; TuningCount < MAX_TUNING_COUNT; TuningCount++) {
1198
1199                 if (InstancePtr->CardType == XSDPS_CARD_SD) {
1200                         Status = XSdPs_CmdTransfer(InstancePtr, CMD19, 0U, 1U);
1201                 } else {
1202                         Status = XSdPs_CmdTransfer(InstancePtr, CMD21, 0U, 1U);
1203                 }
1204
1205                 if (Status != XST_SUCCESS) {
1206                         Status = XST_FAILURE;
1207                         goto RETURN_PATH;
1208                 }
1209
1210                 if ((XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
1211                                 XSDPS_HOST_CTRL2_OFFSET) & XSDPS_HC2_EXEC_TNG_MASK) == 0U) {
1212                         break;
1213                 }
1214
1215                 if (TuningCount == 31) {
1216 #if defined (ARMR5) || defined (__aarch64__) || defined (ARMA53_32)
1217                         /* Issue DLL Reset to load new SDHC tuned tap values */
1218                         XSdPs_DllReset(InstancePtr);
1219 #endif
1220                 }
1221         }
1222
1223         if ((XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
1224                         XSDPS_HOST_CTRL2_OFFSET) & XSDPS_HC2_SAMP_CLK_SEL_MASK) == 0U) {
1225                 Status = XST_FAILURE;
1226                 goto RETURN_PATH;
1227         }
1228
1229         /* Wait for ~12 clock cycles to synchronize the new tap values */
1230         (void)usleep(1U);
1231
1232 #if defined (ARMR5) || defined (__aarch64__) || defined (ARMA53_32)
1233         /* Issue DLL Reset to load new SDHC tuned tap values */
1234         XSdPs_DllReset(InstancePtr);
1235 #endif
1236
1237         Status = XST_SUCCESS;
1238
1239         RETURN_PATH: return Status;
1240
1241 }
1242
1243 #if defined (ARMR5) || defined (__aarch64__) || defined (ARMA53_32)
1244 /*****************************************************************************/
1245 /**
1246 *
1247 * API to set Tap Delay for SDR104 and HS200 modes
1248 *
1249 *
1250 * @param        InstancePtr is a pointer to the XSdPs instance.
1251 *
1252 * @return       None
1253 *
1254 * @note         None.
1255 *
1256 ******************************************************************************/
1257 void XSdPs_sdr104_hs200_tapdelay(u32 Bank, u32 DeviceId, u32 CardType)
1258 {
1259         u32 TapDelay;
1260         (void) CardType;
1261
1262 #ifdef XPAR_PSU_SD_0_DEVICE_ID
1263         if (DeviceId == 0U) {
1264 #if EL1_NONSECURE && defined (__aarch64__)
1265                 (void)TapDelay;
1266                 if (Bank == 2)
1267                         Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR +
1268                                         SD_OTAPDLY) | ((u64)SD0_OTAPDLY_SEL_MASK << 32),
1269                                         (u64)SD0_OTAPDLYSEL_HS200_B2, 0, 0, 0, 0, 0);
1270                 else
1271                         Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR +
1272                                         SD_OTAPDLY) | ((u64)SD0_OTAPDLY_SEL_MASK << 32),
1273                                         (u64)SD0_OTAPDLYSEL_HS200_B0, 0, 0, 0, 0, 0);
1274 #else
1275                 /* Program the OTAPDLY */
1276                 TapDelay = XSdPs_ReadReg(XPS_SYS_CTRL_BASEADDR, SD_OTAPDLY);
1277                 TapDelay &= ~SD0_OTAPDLY_SEL_MASK;
1278                 if (Bank == 2)
1279                         TapDelay |= SD0_OTAPDLYSEL_HS200_B2;
1280                 else
1281                         TapDelay |= SD0_OTAPDLYSEL_HS200_B0;
1282                 XSdPs_WriteReg(XPS_SYS_CTRL_BASEADDR, SD_OTAPDLY, TapDelay);
1283 #endif
1284         } else {
1285 #endif
1286                 (void) DeviceId;
1287 #if EL1_NONSECURE && defined (__aarch64__)
1288                 (void)TapDelay;
1289                 if (Bank == 2)
1290                         Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR +
1291                                         SD_OTAPDLY) | ((u64)SD1_OTAPDLY_SEL_MASK << 32),
1292                                         (u64)SD1_OTAPDLYSEL_HS200_B2, 0, 0, 0, 0, 0);
1293                 else
1294                         Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR +
1295                                         SD_OTAPDLY) | ((u64)SD1_OTAPDLY_SEL_MASK << 32),
1296                                         (u64)SD1_OTAPDLYSEL_HS200_B0, 0, 0, 0, 0, 0);
1297 #else
1298                 TapDelay = XSdPs_ReadReg(XPS_SYS_CTRL_BASEADDR, SD_OTAPDLY);
1299                 TapDelay &= ~SD1_OTAPDLY_SEL_MASK;
1300                 if (Bank == 2)
1301                         TapDelay |= SD1_OTAPDLYSEL_HS200_B2;
1302                 else
1303                         TapDelay |= SD1_OTAPDLYSEL_HS200_B0;
1304                 XSdPs_WriteReg(XPS_SYS_CTRL_BASEADDR, SD_OTAPDLY, TapDelay);
1305 #endif
1306 #ifdef XPAR_PSU_SD_0_DEVICE_ID
1307         }
1308 #endif
1309 }
1310
1311 /*****************************************************************************/
1312 /**
1313 *
1314 * API to set Tap Delay for SDR50 mode
1315 *
1316 *
1317 * @param        InstancePtr is a pointer to the XSdPs instance.
1318 *
1319 * @return       None
1320 *
1321 * @note         None.
1322 *
1323 ******************************************************************************/
1324 void XSdPs_sdr50_tapdelay(u32 Bank, u32 DeviceId, u32 CardType)
1325 {
1326         u32 TapDelay;
1327         (void) Bank;
1328         (void) CardType;
1329
1330 #ifdef XPAR_PSU_SD_0_DEVICE_ID
1331         if (DeviceId == 0U) {
1332 #if EL1_NONSECURE && defined (__aarch64__)
1333                 (void)TapDelay;
1334                 Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR + SD_OTAPDLY) |
1335                                 ((u64)SD0_OTAPDLY_SEL_MASK << 32), (u64)SD0_OTAPDLYSEL_SD50,
1336                                 0, 0, 0, 0, 0);
1337 #else
1338                 /* Program the OTAPDLY */
1339                 TapDelay = XSdPs_ReadReg(XPS_SYS_CTRL_BASEADDR, SD_OTAPDLY);
1340                 TapDelay &= ~SD0_OTAPDLY_SEL_MASK;
1341                 TapDelay |= SD0_OTAPDLYSEL_SD50;
1342                 XSdPs_WriteReg(XPS_SYS_CTRL_BASEADDR, SD_OTAPDLY, TapDelay);
1343 #endif
1344         } else {
1345 #endif
1346                 (void) DeviceId;
1347 #if EL1_NONSECURE && defined (__aarch64__)
1348                 (void)TapDelay;
1349                 Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR + SD_OTAPDLY) |
1350                                 ((u64)SD1_OTAPDLY_SEL_MASK << 32), (u64)SD1_OTAPDLYSEL_SD50,
1351                                 0, 0, 0, 0, 0);
1352 #else
1353                 TapDelay = XSdPs_ReadReg(XPS_SYS_CTRL_BASEADDR, SD_OTAPDLY);
1354                 TapDelay &= ~SD1_OTAPDLY_SEL_MASK;
1355                 TapDelay |= SD1_OTAPDLYSEL_SD50;
1356                 XSdPs_WriteReg(XPS_SYS_CTRL_BASEADDR, SD_OTAPDLY, TapDelay);
1357 #endif
1358 #ifdef XPAR_PSU_SD_0_DEVICE_ID
1359         }
1360 #endif
1361 }
1362
1363 /*****************************************************************************/
1364 /**
1365 *
1366 * API to set Tap Delay for DDR50 mode
1367 *
1368 *
1369 * @param        InstancePtr is a pointer to the XSdPs instance.
1370 *
1371 * @return       None
1372 *
1373 * @note         None.
1374 *
1375 ******************************************************************************/
1376 void XSdPs_ddr50_tapdelay(u32 Bank, u32 DeviceId, u32 CardType)
1377 {
1378         u32 TapDelay;
1379         (void) Bank;
1380
1381 #ifdef XPAR_PSU_SD_0_DEVICE_ID
1382         if (DeviceId == 0U) {
1383 #if EL1_NONSECURE && defined (__aarch64__)
1384                 (void)TapDelay;
1385                 Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR + SD_ITAPDLY) |
1386                                 ((u64)SD0_ITAPCHGWIN << 32), (u64)SD0_ITAPCHGWIN,
1387                                 0, 0, 0, 0, 0);
1388                 Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR + SD_ITAPDLY) |
1389                                 ((u64)SD0_ITAPDLYENA << 32), (u64)SD0_ITAPDLYENA,
1390                                 0, 0, 0, 0, 0);
1391                 if (CardType== XSDPS_CARD_SD)
1392                         Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR +
1393                                         SD_ITAPDLY) | ((u64)SD0_ITAPDLY_SEL_MASK << 32),
1394                                         (u64)SD0_ITAPDLYSEL_SD_DDR50, 0, 0, 0, 0, 0);
1395                 else
1396                         Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR +
1397                                         SD_ITAPDLY) | ((u64)SD0_ITAPDLY_SEL_MASK << 32),
1398                                         (u64)SD0_ITAPDLYSEL_EMMC_DDR50, 0, 0, 0, 0, 0);
1399                 Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR + SD_ITAPDLY) |
1400                                 ((u64)SD0_ITAPCHGWIN << 32), (u64)0x0, 0, 0, 0, 0, 0);
1401                 if (CardType == XSDPS_CARD_SD)
1402                         Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR +
1403                                         SD_OTAPDLY) | ((u64)SD0_OTAPDLY_SEL_MASK << 32),
1404                                         (u64)SD0_OTAPDLYSEL_SD_DDR50, 0, 0, 0, 0, 0);
1405                 else
1406                         Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR +
1407                                         SD_OTAPDLY) | ((u64)SD0_OTAPDLY_SEL_MASK << 32),
1408                                         (u64)SD0_OTAPDLYSEL_EMMC_DDR50, 0, 0, 0, 0, 0);
1409 #else
1410                 TapDelay = XSdPs_ReadReg(XPS_SYS_CTRL_BASEADDR, SD_ITAPDLY);
1411                 TapDelay |= SD0_ITAPCHGWIN;
1412                 XSdPs_WriteReg(XPS_SYS_CTRL_BASEADDR, SD_ITAPDLY, TapDelay);
1413                 /* Program the ITAPDLY */
1414                 TapDelay |= SD0_ITAPDLYENA;
1415                 XSdPs_WriteReg(XPS_SYS_CTRL_BASEADDR, SD_ITAPDLY, TapDelay);
1416                 if (CardType== XSDPS_CARD_SD)
1417                         TapDelay |= SD0_ITAPDLYSEL_SD_DDR50;
1418                 else
1419                         TapDelay |= SD0_ITAPDLYSEL_EMMC_DDR50;
1420                 XSdPs_WriteReg(XPS_SYS_CTRL_BASEADDR, SD_ITAPDLY, TapDelay);
1421                 TapDelay &= ~SD0_ITAPCHGWIN;
1422                 XSdPs_WriteReg(XPS_SYS_CTRL_BASEADDR, SD_ITAPDLY, TapDelay);
1423                 /* Program the OTAPDLY */
1424                 TapDelay = XSdPs_ReadReg(XPS_SYS_CTRL_BASEADDR, SD_OTAPDLY);
1425                 TapDelay &= ~SD0_OTAPDLY_SEL_MASK;
1426                 if (CardType == XSDPS_CARD_SD)
1427                         TapDelay |= SD0_OTAPDLYSEL_SD_DDR50;
1428                 else
1429                         TapDelay |= SD0_OTAPDLYSEL_EMMC_DDR50;
1430                 XSdPs_WriteReg(XPS_SYS_CTRL_BASEADDR, SD_OTAPDLY, TapDelay);
1431 #endif
1432         } else {
1433 #endif
1434                 (void) DeviceId;
1435 #if EL1_NONSECURE && defined (__aarch64__)
1436                 (void)TapDelay;
1437                 Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR + SD_ITAPDLY) |
1438                                 ((u64)SD1_ITAPCHGWIN << 32), (u64)SD1_ITAPCHGWIN,
1439                                 0, 0, 0, 0, 0);
1440                 Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR + SD_ITAPDLY) |
1441                                 ((u64)SD1_ITAPDLYENA << 32), (u64)SD1_ITAPDLYENA,
1442                                 0, 0, 0, 0, 0);
1443                 if (CardType== XSDPS_CARD_SD)
1444                         Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR +
1445                                         SD_ITAPDLY) | ((u64)SD1_ITAPDLY_SEL_MASK << 32),
1446                                         (u64)SD1_ITAPDLYSEL_SD_DDR50, 0, 0, 0, 0, 0);
1447                 else
1448                         Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR +
1449                                         SD_ITAPDLY) | ((u64)SD1_ITAPDLY_SEL_MASK << 32),
1450                                         (u64)SD1_ITAPDLYSEL_EMMC_DDR50, 0, 0, 0, 0, 0);
1451                 Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR +
1452                                 SD_ITAPDLY) | ((u64)SD1_ITAPCHGWIN << 32),
1453                                 (u64)0x0, 0, 0, 0, 0, 0);
1454                 if (CardType == XSDPS_CARD_SD)
1455                         Xil_Smc(MMIO_WRITE_SMC_FID,(u64)(XPS_SYS_CTRL_BASEADDR +
1456                                         SD_OTAPDLY) | ((u64)SD1_OTAPDLY_SEL_MASK << 32),
1457                                         (u64)SD1_OTAPDLYSEL_SD_DDR50, 0, 0, 0, 0, 0);
1458                 else
1459                         Xil_Smc(MMIO_WRITE_SMC_FID,(u64)(XPS_SYS_CTRL_BASEADDR +
1460                                         SD_OTAPDLY) | ((u64)SD1_OTAPDLY_SEL_MASK << 32),
1461                                         (u64)SD1_OTAPDLYSEL_EMMC_DDR50, 0, 0, 0, 0, 0);
1462 #else
1463                 TapDelay = XSdPs_ReadReg(XPS_SYS_CTRL_BASEADDR, SD_ITAPDLY);
1464                 TapDelay |= SD1_ITAPCHGWIN;
1465                 XSdPs_WriteReg(XPS_SYS_CTRL_BASEADDR, SD_ITAPDLY, TapDelay);
1466                 /* Program the ITAPDLY */
1467                 TapDelay |= SD1_ITAPDLYENA;
1468                 XSdPs_WriteReg(XPS_SYS_CTRL_BASEADDR, SD_ITAPDLY, TapDelay);
1469                 if (CardType == XSDPS_CARD_SD)
1470                         TapDelay |= SD1_ITAPDLYSEL_SD_DDR50;
1471                 else
1472                         TapDelay |= SD1_ITAPDLYSEL_EMMC_DDR50;
1473                 XSdPs_WriteReg(XPS_SYS_CTRL_BASEADDR, SD_ITAPDLY, TapDelay);
1474                 TapDelay &= ~SD1_ITAPCHGWIN;
1475                 XSdPs_WriteReg(XPS_SYS_CTRL_BASEADDR, SD_ITAPDLY, TapDelay);
1476                 /* Program the OTAPDLY */
1477                 TapDelay = XSdPs_ReadReg(XPS_SYS_CTRL_BASEADDR, SD_OTAPDLY);
1478                 TapDelay &= ~SD1_OTAPDLY_SEL_MASK;
1479                 if (CardType == XSDPS_CARD_SD)
1480                         TapDelay |= SD1_OTAPDLYSEL_SD_DDR50;
1481                 else
1482                         TapDelay |= SD1_OTAPDLYSEL_EMMC_DDR50;
1483                 XSdPs_WriteReg(XPS_SYS_CTRL_BASEADDR, SD_OTAPDLY, TapDelay);
1484 #endif
1485 #ifdef XPAR_PSU_SD_0_DEVICE_ID
1486         }
1487 #endif
1488 }
1489
1490 /*****************************************************************************/
1491 /**
1492 *
1493 * API to set Tap Delay for HSD and SDR25 mode
1494 *
1495 *
1496 * @param        InstancePtr is a pointer to the XSdPs instance.
1497 *
1498 * @return       None
1499 *
1500 * @note         None.
1501 *
1502 ******************************************************************************/
1503 void XSdPs_hsd_sdr25_tapdelay(u32 Bank, u32 DeviceId, u32 CardType)
1504 {
1505         u32 TapDelay;
1506         (void) Bank;
1507
1508 #ifdef XPAR_PSU_SD_0_DEVICE_ID
1509         if (DeviceId == 0U) {
1510 #if EL1_NONSECURE && defined (__aarch64__)
1511                 (void)TapDelay;
1512                 Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR + SD_ITAPDLY) |
1513                                 ((u64)SD0_ITAPCHGWIN << 32), (u64)SD0_ITAPCHGWIN,
1514                                 0, 0, 0, 0, 0);
1515                 Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR + SD_ITAPDLY) |
1516                                 ((u64)SD0_ITAPDLYENA << 32), (u64)SD0_ITAPDLYENA,
1517                                 0, 0, 0, 0, 0);
1518                 Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR + SD_ITAPDLY) |
1519                                 ((u64)SD0_ITAPDLY_SEL_MASK << 32), (u64)SD0_ITAPDLYSEL_HSD,
1520                                 0, 0, 0, 0, 0);
1521                 Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR + SD_ITAPDLY) |
1522                                 ((u64)SD0_ITAPCHGWIN << 32), (u64)0x0, 0, 0, 0, 0, 0);
1523                 if (CardType == XSDPS_CARD_SD)
1524                         Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR +
1525                                         SD_OTAPDLY) | ((u64)SD0_OTAPDLY_SEL_MASK << 32),
1526                                         (u64)SD0_OTAPDLYSEL_SD_HSD, 0, 0, 0, 0, 0);
1527                 else
1528                         Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR +
1529                                         SD_OTAPDLY) | ((u64)SD0_OTAPDLY_SEL_MASK << 32),
1530                                         (u64)SD0_OTAPDLYSEL_EMMC_HSD, 0, 0, 0, 0, 0);
1531 #else
1532                 TapDelay = XSdPs_ReadReg(XPS_SYS_CTRL_BASEADDR, SD_ITAPDLY);
1533                 TapDelay |= SD0_ITAPCHGWIN;
1534                 XSdPs_WriteReg(XPS_SYS_CTRL_BASEADDR, SD_ITAPDLY, TapDelay);
1535                 /* Program the ITAPDLY */
1536                 TapDelay |= SD0_ITAPDLYENA;
1537                 XSdPs_WriteReg(XPS_SYS_CTRL_BASEADDR, SD_ITAPDLY, TapDelay);
1538                 TapDelay |= SD0_ITAPDLYSEL_HSD;
1539                 XSdPs_WriteReg(XPS_SYS_CTRL_BASEADDR, SD_ITAPDLY, TapDelay);
1540                 TapDelay &= ~SD0_ITAPCHGWIN;
1541                 XSdPs_WriteReg(XPS_SYS_CTRL_BASEADDR, SD_ITAPDLY, TapDelay);
1542                 /* Program the OTAPDLY */
1543                 TapDelay = XSdPs_ReadReg(XPS_SYS_CTRL_BASEADDR, SD_OTAPDLY);
1544                 TapDelay &= ~SD0_OTAPDLY_SEL_MASK;
1545                 if (CardType == XSDPS_CARD_SD)
1546                         TapDelay |= SD0_OTAPDLYSEL_SD_HSD;
1547                 else
1548                         TapDelay |= SD0_OTAPDLYSEL_EMMC_HSD;
1549                 XSdPs_WriteReg(XPS_SYS_CTRL_BASEADDR, SD_OTAPDLY, TapDelay);
1550 #endif
1551         } else {
1552 #endif
1553                 (void) DeviceId;
1554 #if EL1_NONSECURE && defined (__aarch64__)
1555                 (void)TapDelay;
1556                 Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR + SD_ITAPDLY) |
1557                                 ((u64)SD1_ITAPCHGWIN << 32), (u64)SD1_ITAPCHGWIN,
1558                                 0, 0, 0, 0, 0);
1559                 Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR + SD_ITAPDLY) |
1560                                 ((u64)SD1_ITAPDLYENA << 32), (u64)SD1_ITAPDLYENA,
1561                                 0, 0, 0, 0, 0);
1562                 Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR + SD_ITAPDLY) |
1563                                 ((u64)SD1_ITAPDLY_SEL_MASK << 32), (u64)SD1_ITAPDLYSEL_HSD,
1564                                 0, 0, 0, 0, 0);
1565                 Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR + SD_ITAPDLY) |
1566                                 ((u64)SD1_ITAPCHGWIN << 32), (u64)0x0, 0, 0, 0, 0, 0);
1567                 if (CardType == XSDPS_CARD_SD)
1568                         Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR +
1569                                         SD_OTAPDLY) | ((u64)SD1_OTAPDLY_SEL_MASK << 32),
1570                                         (u64)SD1_OTAPDLYSEL_SD_HSD, 0, 0, 0, 0, 0);
1571                 else
1572                         Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR +
1573                                         SD_OTAPDLY) | ((u64)SD1_OTAPDLY_SEL_MASK << 32),
1574                                         (u64)SD1_OTAPDLYSEL_EMMC_HSD, 0, 0, 0, 0, 0);
1575 #else
1576                 TapDelay = XSdPs_ReadReg(XPS_SYS_CTRL_BASEADDR, SD_ITAPDLY);
1577                 TapDelay |= SD1_ITAPCHGWIN;
1578                 XSdPs_WriteReg(XPS_SYS_CTRL_BASEADDR, SD_ITAPDLY, TapDelay);
1579                 /* Program the ITAPDLY */
1580                 TapDelay |= SD1_ITAPDLYENA;
1581                 XSdPs_WriteReg(XPS_SYS_CTRL_BASEADDR, SD_ITAPDLY, TapDelay);
1582                 TapDelay |= SD1_ITAPDLYSEL_HSD;
1583                 XSdPs_WriteReg(XPS_SYS_CTRL_BASEADDR, SD_ITAPDLY, TapDelay);
1584                 TapDelay &= ~SD1_ITAPCHGWIN;
1585                 XSdPs_WriteReg(XPS_SYS_CTRL_BASEADDR, SD_ITAPDLY, TapDelay);
1586                 /* Program the OTAPDLY */
1587                 TapDelay = XSdPs_ReadReg(XPS_SYS_CTRL_BASEADDR, SD_OTAPDLY);
1588                 TapDelay &= ~SD1_OTAPDLY_SEL_MASK;
1589                 if (CardType == XSDPS_CARD_SD)
1590                         TapDelay |= SD1_OTAPDLYSEL_SD_HSD;
1591                 else
1592                         TapDelay |= SD1_OTAPDLYSEL_EMMC_HSD;
1593                 XSdPs_WriteReg(XPS_SYS_CTRL_BASEADDR, SD_OTAPDLY, TapDelay);
1594 #endif
1595 #ifdef XPAR_PSU_SD_0_DEVICE_ID
1596         }
1597 #endif
1598 }
1599
1600 /*****************************************************************************/
1601 /**
1602 *
1603 * API to set Tap Delay w.r.t speed modes
1604 *
1605 *
1606 * @param        InstancePtr is a pointer to the XSdPs instance.
1607 *
1608 * @return       None
1609 *
1610 * @note         None.
1611 *
1612 ******************************************************************************/
1613 void XSdPs_SetTapDelay(XSdPs *InstancePtr)
1614 {
1615         u32 DllCtrl, BankNum, DeviceId, CardType;
1616
1617         BankNum = InstancePtr->Config.BankNumber;
1618         DeviceId = InstancePtr->Config.DeviceId ;
1619         CardType = InstancePtr->CardType ;
1620 #ifdef XPAR_PSU_SD_0_DEVICE_ID
1621         if (DeviceId == 0U) {
1622 #if EL1_NONSECURE && defined (__aarch64__)
1623                 (void)DllCtrl;
1624                 Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR +
1625                                 SD_DLL_CTRL) | ((u64)SD0_DLL_RST << 32),
1626                                 (u64)SD0_DLL_RST, 0, 0, 0, 0, 0);
1627 #else
1628                 DllCtrl = XSdPs_ReadReg(XPS_SYS_CTRL_BASEADDR, SD_DLL_CTRL);
1629                 DllCtrl |= SD0_DLL_RST;
1630                 XSdPs_WriteReg(XPS_SYS_CTRL_BASEADDR, SD_DLL_CTRL, DllCtrl);
1631 #endif
1632                 InstancePtr->Config_TapDelay(BankNum, DeviceId, CardType);
1633 #if EL1_NONSECURE && defined (__aarch64__)
1634                 (void)DllCtrl;
1635                 Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR +
1636                                 SD_DLL_CTRL) | ((u64)SD0_DLL_RST << 32),
1637                                 (u64)0x0, 0, 0, 0, 0, 0);
1638 #else
1639                 DllCtrl &= ~SD0_DLL_RST;
1640                 XSdPs_WriteReg(XPS_SYS_CTRL_BASEADDR, SD_DLL_CTRL, DllCtrl);
1641 #endif
1642         } else {
1643 #endif
1644 #if EL1_NONSECURE && defined (__aarch64__)
1645                 (void)DllCtrl;
1646                 Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR +
1647                                 SD_DLL_CTRL) | ((u64)SD1_DLL_RST << 32),
1648                                 (u64)SD1_DLL_RST, 0, 0, 0, 0, 0);
1649 #else
1650                 DllCtrl = XSdPs_ReadReg(XPS_SYS_CTRL_BASEADDR, SD_DLL_CTRL);
1651                 DllCtrl |= SD1_DLL_RST;
1652                 XSdPs_WriteReg(XPS_SYS_CTRL_BASEADDR, SD_DLL_CTRL, DllCtrl);
1653 #endif
1654                 InstancePtr->Config_TapDelay(BankNum, DeviceId, CardType);
1655 #if EL1_NONSECURE && defined (__aarch64__)
1656                 (void)DllCtrl;
1657                 Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR +
1658                                 SD_DLL_CTRL) | ((u64)SD1_DLL_RST << 32),
1659                                 (u64)0x0, 0, 0, 0, 0, 0);
1660 #else
1661                 DllCtrl &= ~SD1_DLL_RST;
1662                 XSdPs_WriteReg(XPS_SYS_CTRL_BASEADDR, SD_DLL_CTRL, DllCtrl);
1663 #endif
1664 #ifdef XPAR_PSU_SD_0_DEVICE_ID
1665         }
1666 #endif
1667 }
1668
1669 /*****************************************************************************/
1670 /**
1671 *
1672 * API to reset the DLL
1673 *
1674 *
1675 * @param        InstancePtr is a pointer to the XSdPs instance.
1676 *
1677 * @return       None
1678 *
1679 * @note         None.
1680 *
1681 ******************************************************************************/
1682 static void XSdPs_DllReset(XSdPs *InstancePtr)
1683 {
1684         u32 ClockReg, DllCtrl;
1685
1686         /* Disable clock */
1687         ClockReg = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
1688                         XSDPS_CLK_CTRL_OFFSET);
1689         ClockReg &= ~XSDPS_CC_SD_CLK_EN_MASK;
1690         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
1691                         XSDPS_CLK_CTRL_OFFSET, ClockReg);
1692
1693         /* Issue DLL Reset to load zero tap values */
1694         DllCtrl = XSdPs_ReadReg(XPS_SYS_CTRL_BASEADDR, SD_DLL_CTRL);
1695         if (InstancePtr->Config.DeviceId == 0U) {
1696 #if EL1_NONSECURE && defined (__aarch64__)
1697                 (void)DllCtrl;
1698                 Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR +
1699                                 SD_DLL_CTRL) | ((u64)SD0_DLL_RST << 32),
1700                                 (u64)SD0_DLL_RST, 0, 0, 0, 0, 0);
1701 #else
1702                 DllCtrl |= SD0_DLL_RST;
1703                 XSdPs_WriteReg(XPS_SYS_CTRL_BASEADDR, SD_DLL_CTRL, DllCtrl);
1704 #endif
1705         } else {
1706 #if EL1_NONSECURE && defined (__aarch64__)
1707                 (void)DllCtrl;
1708                 Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR +
1709                                 SD_DLL_CTRL) | ((u64)SD1_DLL_RST << 32),
1710                                 (u64)SD1_DLL_RST, 0, 0, 0, 0, 0);
1711 #else
1712                 DllCtrl |= SD1_DLL_RST;
1713                 XSdPs_WriteReg(XPS_SYS_CTRL_BASEADDR, SD_DLL_CTRL, DllCtrl);
1714 #endif
1715         }
1716
1717         /* Wait for 2 micro seconds */
1718         (void)usleep(2U);
1719
1720         /* Release the DLL out of reset */
1721         DllCtrl = XSdPs_ReadReg(XPS_SYS_CTRL_BASEADDR, SD_DLL_CTRL);
1722         if (InstancePtr->Config.DeviceId == 0U) {
1723 #if EL1_NONSECURE && defined (__aarch64__)
1724                 (void)DllCtrl;
1725                 Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR +
1726                                 SD_DLL_CTRL) | ((u64)SD0_DLL_RST << 32),
1727                                 (u64)0x0, 0, 0, 0, 0, 0);
1728 #else
1729                 DllCtrl &= ~SD0_DLL_RST;
1730                 XSdPs_WriteReg(XPS_SYS_CTRL_BASEADDR, SD_DLL_CTRL, DllCtrl);
1731 #endif
1732         } else {
1733 #if EL1_NONSECURE && defined (__aarch64__)
1734                 (void)DllCtrl;
1735                 Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR +
1736                                 SD_DLL_CTRL) | ((u64)SD1_DLL_RST << 32),
1737                                 (u64)0x0, 0, 0, 0, 0, 0);
1738 #else
1739                 DllCtrl &= ~SD1_DLL_RST;
1740                 XSdPs_WriteReg(XPS_SYS_CTRL_BASEADDR, SD_DLL_CTRL, DllCtrl);
1741 #endif
1742         }
1743
1744         /* Wait for internal clock to stabilize */
1745         ClockReg = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
1746                                 XSDPS_CLK_CTRL_OFFSET);
1747         while((ClockReg & XSDPS_CC_INT_CLK_STABLE_MASK) == 0U) {
1748                 ClockReg = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
1749                                         XSDPS_CLK_CTRL_OFFSET);
1750         }
1751
1752         /* Enable SD clock */
1753         ClockReg = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
1754                         XSDPS_CLK_CTRL_OFFSET);
1755         XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
1756                         XSDPS_CLK_CTRL_OFFSET,
1757                         ClockReg | XSDPS_CC_SD_CLK_EN_MASK);
1758 }
1759 #endif
1760 /** @} */