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