1 /******************************************************************************
3 * Copyright (C) 2013 - 2016 Xilinx, Inc. All rights reserved.
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:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
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.
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
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.
31 ******************************************************************************/
32 /*****************************************************************************/
35 * @file xsdps_options.c
36 * @addtogroup sdps_v3_4
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.
43 * MODIFICATION HISTORY:
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
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
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
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
81 ******************************************************************************/
83 /***************************** Include Files *********************************/
86 #if defined (__aarch64__)
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 *******************************/
97 /***************** Macros (Inline Functions) Definitions *********************/
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);
110 extern u16 TransferMode;
111 /*****************************************************************************/
113 * Update Block size for read/write operations.
115 * @param InstancePtr is a pointer to the instance to be worked on.
116 * @param BlkSize - Block size passed by the user.
120 ******************************************************************************/
121 s32 XSdPs_SetBlkSize(XSdPs *InstancePtr, u16 BlkSize)
126 Xil_AssertNonvoid(InstancePtr != NULL);
127 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
129 PresentStateReg = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
130 XSDPS_PRES_STATE_OFFSET);
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;
140 /* Send block write command */
141 Status = XSdPs_CmdTransfer(InstancePtr, CMD16, BlkSize, 0U);
142 if (Status != XST_SUCCESS) {
143 Status = XST_FAILURE;
147 Status = (s32)XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
150 /* Set block size to the value passed */
151 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress, XSDPS_BLK_SIZE_OFFSET,
152 BlkSize & XSDPS_BLK_SIZE_MASK);
154 Status = XST_SUCCESS;
161 /*****************************************************************************/
164 * API to get bus width support by card.
167 * @param InstancePtr is a pointer to the XSdPs instance.
168 * @param SCR - buffer to store SCR register returned by card.
171 * - XST_SUCCESS if successful.
172 * - XST_FAILURE if fail.
176 ******************************************************************************/
177 s32 XSdPs_Get_BusWidth(XSdPs *InstancePtr, u8 *SCR)
185 Xil_AssertNonvoid(InstancePtr != NULL);
186 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
188 for (LoopCnt = 0; LoopCnt < 8; LoopCnt++) {
192 /* Send block write command */
193 Status = XSdPs_CmdTransfer(InstancePtr, CMD55,
194 InstancePtr->RelCardAddr, 0U);
195 if (Status != XST_SUCCESS) {
196 Status = XST_FAILURE;
200 BlkCnt = XSDPS_SCR_BLKCNT;
201 BlkSize = XSDPS_SCR_BLKSIZE;
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);
208 XSdPs_SetupADMA2DescTbl(InstancePtr, BlkCnt, SCR);
210 TransferMode = XSDPS_TM_DAT_DIR_SEL_MASK | XSDPS_TM_DMA_EN_MASK;
212 if (InstancePtr->Config.IsCacheCoherent == 0) {
213 Xil_DCacheInvalidateRange((INTPTR)SCR, 8);
216 Status = XSdPs_CmdTransfer(InstancePtr, ACMD51, 0U, BlkCnt);
217 if (Status != XST_SUCCESS) {
218 Status = XST_FAILURE;
223 * Check for transfer complete
224 * Polling for response for now
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;
237 } while ((StatusReg & XSDPS_INTR_TC_MASK) == 0U);
239 /* Write to clear bit */
240 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
241 XSDPS_NORM_INTR_STS_OFFSET, XSDPS_INTR_TC_MASK);
243 Status = (s32)XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
246 Status = XST_SUCCESS;
253 /*****************************************************************************/
256 * API to set bus width to 4-bit in card and host
259 * @param InstancePtr is a pointer to the XSdPs instance.
262 * - XST_SUCCESS if successful.
263 * - XST_FAILURE if fail.
267 ******************************************************************************/
268 s32 XSdPs_Change_BusWidth(XSdPs *InstancePtr)
274 Xil_AssertNonvoid(InstancePtr != NULL);
275 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
279 * check for bus width for 3.0 controller and return if
282 if ((InstancePtr->HC_Version == XSDPS_HC_SPEC_V3) &&
283 (InstancePtr->Config.BusWidth < XSDPS_WIDTH_4)) {
284 Status = XST_SUCCESS;
288 if (InstancePtr->CardType == XSDPS_CARD_SD) {
290 Status = XSdPs_CmdTransfer(InstancePtr, CMD55, InstancePtr->RelCardAddr,
292 if (Status != XST_SUCCESS) {
293 Status = XST_FAILURE;
297 InstancePtr->BusWidth = XSDPS_4_BIT_WIDTH;
299 Arg = ((u32)InstancePtr->BusWidth);
301 Status = XSdPs_CmdTransfer(InstancePtr, ACMD6, Arg, 0U);
302 if (Status != XST_SUCCESS) {
303 Status = XST_FAILURE;
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;
314 InstancePtr->BusWidth = XSDPS_4_BIT_WIDTH;
317 if (InstancePtr->BusWidth == XSDPS_8_BIT_WIDTH) {
318 if (InstancePtr->Mode == XSDPS_DDR52_MODE)
319 Arg = XSDPS_MMC_DDR_8_BIT_BUS_ARG;
321 Arg = XSDPS_MMC_8_BIT_BUS_ARG;
323 if (InstancePtr->Mode == XSDPS_DDR52_MODE)
324 Arg = XSDPS_MMC_DDR_4_BIT_BUS_ARG;
326 Arg = XSDPS_MMC_4_BIT_BUS_ARG;
329 Status = XSdPs_CmdTransfer(InstancePtr, CMD6, Arg, 0U);
330 if (Status != XST_SUCCESS) {
331 Status = XST_FAILURE;
335 /* Check for transfer complete */
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;
347 } while((StatusReg & XSDPS_INTR_TC_MASK) == 0U);
349 /* Write to clear bit */
350 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
351 XSDPS_NORM_INTR_STS_OFFSET, XSDPS_INTR_TC_MASK);
354 usleep(XSDPS_MMC_DELAY_FOR_SWITCH);
356 StatusReg = XSdPs_ReadReg8(InstancePtr->Config.BaseAddress,
357 XSDPS_HOST_CTRL1_OFFSET);
359 /* Width setting in controller */
360 if (InstancePtr->BusWidth == XSDPS_8_BIT_WIDTH) {
361 StatusReg |= XSDPS_HC_EXT_BUS_WIDTH;
363 StatusReg |= XSDPS_HC_WIDTH_MASK;
366 XSdPs_WriteReg8(InstancePtr->Config.BaseAddress,
367 XSDPS_HOST_CTRL1_OFFSET,
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);
379 Status = (s32)XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
382 Status = XST_SUCCESS;
389 /*****************************************************************************/
392 * API to get bus speed supported by card.
395 * @param InstancePtr is a pointer to the XSdPs instance.
396 * @param ReadBuff - buffer to store function group support data
400 * - XST_SUCCESS if successful.
401 * - XST_FAILURE if fail.
405 ******************************************************************************/
406 s32 XSdPs_Get_BusSpeed(XSdPs *InstancePtr, u8 *ReadBuff)
415 Xil_AssertNonvoid(InstancePtr != NULL);
416 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
418 for (LoopCnt = 0; LoopCnt < 64; LoopCnt++) {
419 ReadBuff[LoopCnt] = 0U;
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);
428 XSdPs_SetupADMA2DescTbl(InstancePtr, BlkCnt, ReadBuff);
430 TransferMode = XSDPS_TM_DAT_DIR_SEL_MASK | XSDPS_TM_DMA_EN_MASK;
432 Arg = XSDPS_SWITCH_CMD_HS_GET;
434 if (InstancePtr->Config.IsCacheCoherent == 0) {
435 Xil_DCacheInvalidateRange((INTPTR)ReadBuff, 64);
438 Status = XSdPs_CmdTransfer(InstancePtr, CMD6, Arg, 1U);
439 if (Status != XST_SUCCESS) {
440 Status = XST_FAILURE;
445 * Check for transfer complete
446 * Polling for response for now
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;
459 } while ((StatusReg & XSDPS_INTR_TC_MASK) == 0U);
461 /* Write to clear bit */
462 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
463 XSDPS_NORM_INTR_STS_OFFSET, XSDPS_INTR_TC_MASK);
465 Status = (s32)XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
468 Status = XST_SUCCESS;
475 /*****************************************************************************/
478 * API to set high speed in card and host. Changes clock in host accordingly.
481 * @param InstancePtr is a pointer to the XSdPs instance.
484 * - XST_SUCCESS if successful.
485 * - XST_FAILURE if fail.
489 ******************************************************************************/
490 s32 XSdPs_Change_BusSpeed(XSdPs *InstancePtr)
497 u8 ReadBuff[64] = {0U};
499 Xil_AssertNonvoid(InstancePtr != NULL);
500 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
502 if (InstancePtr->CardType == XSDPS_CARD_SD) {
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);
510 XSdPs_SetupADMA2DescTbl(InstancePtr, BlkCnt, ReadBuff);
512 if (InstancePtr->Config.IsCacheCoherent == 0) {
513 Xil_DCacheFlushRange((INTPTR)ReadBuff, 64);
516 TransferMode = XSDPS_TM_DAT_DIR_SEL_MASK | XSDPS_TM_DMA_EN_MASK;
518 Arg = XSDPS_SWITCH_CMD_HS_SET;
520 Status = XSdPs_CmdTransfer(InstancePtr, CMD6, Arg, 1U);
521 if (Status != XST_SUCCESS) {
522 Status = XST_FAILURE;
527 * Check for transfer complete
528 * Polling for response for now
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;
541 } while ((StatusReg & XSDPS_INTR_TC_MASK) == 0U);
543 /* Write to clear bit */
544 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
545 XSDPS_NORM_INTR_STS_OFFSET, XSDPS_INTR_TC_MASK);
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;
555 } else if (InstancePtr->CardType == XSDPS_CARD_MMC) {
556 Arg = XSDPS_MMC_HIGH_SPEED_ARG;
558 Status = XSdPs_CmdTransfer(InstancePtr, CMD6, Arg, 0U);
559 if (Status != XST_SUCCESS) {
560 Status = XST_FAILURE;
565 * Check for transfer complete
568 StatusReg = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
569 XSDPS_NORM_INTR_STS_OFFSET);
570 if ((StatusReg & XSDPS_INTR_ERR_MASK) != 0U) {
572 * Write to clear error bits
574 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
575 XSDPS_ERR_INTR_STS_OFFSET,
576 XSDPS_ERROR_INTR_ALL_MASK);
577 Status = XST_FAILURE;
580 } while ((StatusReg & XSDPS_INTR_TC_MASK) == 0U);
585 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
586 XSDPS_NORM_INTR_STS_OFFSET, XSDPS_INTR_TC_MASK);
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;
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;
603 Arg = XSDPS_MMC_HIGH_SPEED_ARG;
604 InstancePtr->BusSpeed = XSDPS_MMC_HSD_MAX_CLK;
607 Status = XSdPs_CmdTransfer(InstancePtr, CMD6, Arg, 0U);
608 if (Status != XST_SUCCESS) {
609 Status = XST_FAILURE;
614 * Check for transfer complete
617 StatusReg = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
618 XSDPS_NORM_INTR_STS_OFFSET);
619 if ((StatusReg & XSDPS_INTR_ERR_MASK) != 0U) {
621 * Write to clear error bits
623 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
624 XSDPS_ERR_INTR_STS_OFFSET,
625 XSDPS_ERROR_INTR_ALL_MASK);
626 Status = XST_FAILURE;
629 } while ((StatusReg & XSDPS_INTR_TC_MASK) == 0U);
634 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
635 XSDPS_NORM_INTR_STS_OFFSET, XSDPS_INTR_TC_MASK);
637 Status = XSdPs_Change_ClkFreq(InstancePtr, InstancePtr->BusSpeed);
638 if (Status != XST_SUCCESS) {
639 Status = XST_FAILURE;
643 if (InstancePtr->Mode == XSDPS_HS200_MODE) {
644 Status = XSdPs_Execute_Tuning(InstancePtr);
645 if (Status != XST_SUCCESS) {
646 Status = XST_FAILURE;
652 usleep(XSDPS_MMC_DELAY_FOR_SWITCH);
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);
660 Status = (s32)XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
664 Status = XST_SUCCESS;
671 /*****************************************************************************/
674 * API to change clock freq to given value.
677 * @param InstancePtr is a pointer to the XSdPs instance.
678 * @param SelFreq - Clock frequency in Hz.
682 * @note This API will change clock frequency to the value less than
683 * or equal to the given value using the permissible dividors.
685 ******************************************************************************/
686 s32 XSdPs_Change_ClkFreq(XSdPs *InstancePtr, u32 SelFreq)
695 Xil_AssertNonvoid(InstancePtr != NULL);
696 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
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);
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);
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;
720 if (DivCnt > XSDPS_CC_EXT_MAX_DIV_CNT) {
721 /* No valid divisor found for given frequency */
722 Status = XST_FAILURE;
726 /* Calculate divisor */
728 while (DivCnt <= XSDPS_CC_MAX_DIV_CNT) {
729 if (((InstancePtr->Config.InputClockHz) / DivCnt) <= SelFreq) {
730 Divisor = DivCnt / 2U;
733 DivCnt = DivCnt << 1U;
736 if (DivCnt > XSDPS_CC_MAX_DIV_CNT) {
737 /* No valid divisor found for given frequency */
738 Status = XST_FAILURE;
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);
750 ExtDivisor = Divisor >> 8;
751 ExtDivisor <<= XSDPS_CC_EXT_DIV_SHIFT;
752 ExtDivisor &= XSDPS_CC_SDCLK_FREQ_SEL_EXT_MASK;
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,
760 ClockReg = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
761 XSDPS_CLK_CTRL_OFFSET);
762 ClockReg &= (~XSDPS_CC_SDCLK_FREQ_SEL_MASK);
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,
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);;
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);
786 Status = XST_SUCCESS;
793 /*****************************************************************************/
796 * API to send pullup command to card before using DAT line 3(using 4-bit bus)
799 * @param InstancePtr is a pointer to the XSdPs instance.
802 * - XST_SUCCESS if successful.
803 * - XST_FAILURE if fail.
807 ******************************************************************************/
808 s32 XSdPs_Pullup(XSdPs *InstancePtr)
812 Xil_AssertNonvoid(InstancePtr != NULL);
813 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
815 Status = XSdPs_CmdTransfer(InstancePtr, CMD55,
816 InstancePtr->RelCardAddr, 0U);
817 if (Status != XST_SUCCESS) {
818 Status = XST_FAILURE;
822 Status = XSdPs_CmdTransfer(InstancePtr, ACMD42, 0U, 0U);
823 if (Status != XST_SUCCESS) {
824 Status = XST_FAILURE;
828 Status = XST_SUCCESS;
835 /*****************************************************************************/
838 * API to get EXT_CSD register of eMMC.
841 * @param InstancePtr is a pointer to the XSdPs instance.
842 * @param ReadBuff - buffer to store EXT_CSD
845 * - XST_SUCCESS if successful.
846 * - XST_FAILURE if fail.
850 ******************************************************************************/
851 s32 XSdPs_Get_Mmc_ExtCsd(XSdPs *InstancePtr, u8 *ReadBuff)
860 Xil_AssertNonvoid(InstancePtr != NULL);
861 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
863 for (LoopCnt = 0; LoopCnt < 512; LoopCnt++) {
864 ReadBuff[LoopCnt] = 0U;
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);
873 XSdPs_SetupADMA2DescTbl(InstancePtr, BlkCnt, ReadBuff);
875 if (InstancePtr->Config.IsCacheCoherent == 0) {
876 Xil_DCacheInvalidateRange((INTPTR)ReadBuff, 512U);
879 TransferMode = XSDPS_TM_DAT_DIR_SEL_MASK | XSDPS_TM_DMA_EN_MASK;
881 /* Send SEND_EXT_CSD command */
882 Status = XSdPs_CmdTransfer(InstancePtr, CMD8, Arg, 1U);
883 if (Status != XST_SUCCESS) {
884 Status = XST_FAILURE;
889 * Check for transfer complete
890 * Polling for response for now
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;
903 } while ((StatusReg & XSDPS_INTR_TC_MASK) == 0U);
905 /* Write to clear bit */
906 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
907 XSDPS_NORM_INTR_STS_OFFSET, XSDPS_INTR_TC_MASK);
909 Status = (s32)XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
912 Status = XST_SUCCESS;
919 /*****************************************************************************/
922 * API to write EXT_CSD register of eMMC.
925 * @param InstancePtr is a pointer to the XSdPs instance.
926 * @param Arg is the argument to be sent along with the command
929 * - XST_SUCCESS if successful.
930 * - XST_FAILURE if fail.
934 ******************************************************************************/
935 s32 XSdPs_Set_Mmc_ExtCsd(XSdPs *InstancePtr, u32 Arg)
940 Status = XSdPs_CmdTransfer(InstancePtr, CMD6, Arg, 0U);
941 if (Status != XST_SUCCESS) {
942 Status = XST_FAILURE;
947 * Check for transfer complete
950 StatusReg = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
951 XSDPS_NORM_INTR_STS_OFFSET);
952 if ((StatusReg & XSDPS_INTR_ERR_MASK) != 0U) {
954 * Write to clear error bits
956 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
957 XSDPS_ERR_INTR_STS_OFFSET,
958 XSDPS_ERROR_INTR_ALL_MASK);
959 Status = XST_FAILURE;
962 } while ((StatusReg & XSDPS_INTR_TC_MASK) == 0U);
964 /* Write to clear bit */
965 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
966 XSDPS_NORM_INTR_STS_OFFSET, XSDPS_INTR_TC_MASK);
968 Status = (s32)XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
971 Status = XST_SUCCESS;
978 #if defined (ARMR5) || defined (__aarch64__) || defined (ARMA53_32)
979 /*****************************************************************************/
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.
987 * @param InstancePtr is a pointer to the XSdPs instance.
988 * @param ReadBuff contains the response for CMD6
994 ******************************************************************************/
995 void XSdPs_Identify_UhsMode(XSdPs *InstancePtr, u8 *ReadBuff)
998 Xil_AssertVoid(InstancePtr != NULL);
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;
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;
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;
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;
1021 InstancePtr->Mode = XSDPS_UHS_SPEED_MODE_SDR12;
1024 /*****************************************************************************/
1027 * API to UHS-I mode initialization
1030 * @param InstancePtr is a pointer to the XSdPs instance.
1031 * @param Mode UHS-I mode
1034 * - XST_SUCCESS if successful.
1035 * - XST_FAILURE if fail.
1039 ******************************************************************************/
1040 s32 XSdPs_Uhs_ModeInit(XSdPs *InstancePtr, u8 Mode)
1048 u8 ReadBuff[64] = {0U};
1050 Xil_AssertNonvoid(InstancePtr != NULL);
1051 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
1053 /* Drive strength */
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,
1062 XSdPs_SetupADMA2DescTbl(InstancePtr, BlkCnt, ReadBuff);
1064 if (InstancePtr->Config.IsCacheCoherent == 0) {
1065 Xil_DCacheFlushRange((INTPTR)ReadBuff, 64);
1068 TransferMode = XSDPS_TM_DAT_DIR_SEL_MASK | XSDPS_TM_DMA_EN_MASK;
1072 Arg = XSDPS_SWITCH_CMD_SDR12_SET;
1073 InstancePtr->BusSpeed = XSDPS_SD_SDR12_MAX_CLK;
1076 Arg = XSDPS_SWITCH_CMD_SDR25_SET;
1077 InstancePtr->BusSpeed = XSDPS_SD_SDR25_MAX_CLK;
1080 Arg = XSDPS_SWITCH_CMD_SDR50_SET;
1081 InstancePtr->BusSpeed = XSDPS_SD_SDR50_MAX_CLK;
1084 Arg = XSDPS_SWITCH_CMD_SDR104_SET;
1085 InstancePtr->BusSpeed = XSDPS_SD_SDR104_MAX_CLK;
1088 Arg = XSDPS_SWITCH_CMD_DDR50_SET;
1089 InstancePtr->BusSpeed = XSDPS_SD_DDR50_MAX_CLK;
1092 Status = XST_FAILURE;
1097 Status = XSdPs_CmdTransfer(InstancePtr, CMD6, Arg, 1U);
1098 if (Status != XST_SUCCESS) {
1099 Status = XST_FAILURE;
1104 * Check for transfer complete
1105 * Polling for response for now
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;
1117 } while ((StatusReg & XSDPS_INTR_TC_MASK) == 0U);
1119 /* Write to clear bit */
1120 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
1121 XSDPS_NORM_INTR_STS_OFFSET, XSDPS_INTR_TC_MASK);
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);
1131 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
1132 XSDPS_HOST_CTRL2_OFFSET, CtrlReg);
1134 /* Change the clock frequency */
1135 Status = XSdPs_Change_ClkFreq(InstancePtr, InstancePtr->BusSpeed);
1136 if (Status != XST_SUCCESS) {
1137 Status = XST_FAILURE;
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;
1151 Status = XST_SUCCESS;
1158 static s32 XSdPs_Execute_Tuning(XSdPs *InstancePtr)
1165 Xil_AssertNonvoid(InstancePtr != NULL);
1166 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
1168 BlkSize = XSDPS_TUNING_CMD_BLKSIZE;
1169 if(InstancePtr->BusWidth == XSDPS_8_BIT_WIDTH)
1171 BlkSize = BlkSize*2U;
1173 BlkSize &= XSDPS_BLK_SIZE_MASK;
1174 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress, XSDPS_BLK_SIZE_OFFSET,
1177 TransferMode = XSDPS_TM_DAT_DIR_SEL_MASK;
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);
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.
1189 /* Wait for ~60 clock cycles to reset the tap values */
1192 #if defined (ARMR5) || defined (__aarch64__) || defined (ARMA53_32)
1193 /* Issue DLL Reset to load new SDHC tuned tap values */
1194 XSdPs_DllReset(InstancePtr);
1197 for (TuningCount = 0U; TuningCount < MAX_TUNING_COUNT; TuningCount++) {
1199 if (InstancePtr->CardType == XSDPS_CARD_SD) {
1200 Status = XSdPs_CmdTransfer(InstancePtr, CMD19, 0U, 1U);
1202 Status = XSdPs_CmdTransfer(InstancePtr, CMD21, 0U, 1U);
1205 if (Status != XST_SUCCESS) {
1206 Status = XST_FAILURE;
1210 if ((XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
1211 XSDPS_HOST_CTRL2_OFFSET) & XSDPS_HC2_EXEC_TNG_MASK) == 0U) {
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);
1223 if ((XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
1224 XSDPS_HOST_CTRL2_OFFSET) & XSDPS_HC2_SAMP_CLK_SEL_MASK) == 0U) {
1225 Status = XST_FAILURE;
1229 /* Wait for ~12 clock cycles to synchronize the new tap values */
1232 #if defined (ARMR5) || defined (__aarch64__) || defined (ARMA53_32)
1233 /* Issue DLL Reset to load new SDHC tuned tap values */
1234 XSdPs_DllReset(InstancePtr);
1237 Status = XST_SUCCESS;
1239 RETURN_PATH: return Status;
1243 #if defined (ARMR5) || defined (__aarch64__) || defined (ARMA53_32)
1244 /*****************************************************************************/
1247 * API to set Tap Delay for SDR104 and HS200 modes
1250 * @param InstancePtr is a pointer to the XSdPs instance.
1256 ******************************************************************************/
1257 void XSdPs_sdr104_hs200_tapdelay(u32 Bank, u32 DeviceId, u32 CardType)
1262 #ifdef XPAR_PSU_SD_0_DEVICE_ID
1263 if (DeviceId == 0U) {
1264 #if EL1_NONSECURE && defined (__aarch64__)
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);
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);
1275 /* Program the OTAPDLY */
1276 TapDelay = XSdPs_ReadReg(XPS_SYS_CTRL_BASEADDR, SD_OTAPDLY);
1277 TapDelay &= ~SD0_OTAPDLY_SEL_MASK;
1279 TapDelay |= SD0_OTAPDLYSEL_HS200_B2;
1281 TapDelay |= SD0_OTAPDLYSEL_HS200_B0;
1282 XSdPs_WriteReg(XPS_SYS_CTRL_BASEADDR, SD_OTAPDLY, TapDelay);
1287 #if EL1_NONSECURE && defined (__aarch64__)
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);
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);
1298 TapDelay = XSdPs_ReadReg(XPS_SYS_CTRL_BASEADDR, SD_OTAPDLY);
1299 TapDelay &= ~SD1_OTAPDLY_SEL_MASK;
1301 TapDelay |= SD1_OTAPDLYSEL_HS200_B2;
1303 TapDelay |= SD1_OTAPDLYSEL_HS200_B0;
1304 XSdPs_WriteReg(XPS_SYS_CTRL_BASEADDR, SD_OTAPDLY, TapDelay);
1306 #ifdef XPAR_PSU_SD_0_DEVICE_ID
1311 /*****************************************************************************/
1314 * API to set Tap Delay for SDR50 mode
1317 * @param InstancePtr is a pointer to the XSdPs instance.
1323 ******************************************************************************/
1324 void XSdPs_sdr50_tapdelay(u32 Bank, u32 DeviceId, u32 CardType)
1330 #ifdef XPAR_PSU_SD_0_DEVICE_ID
1331 if (DeviceId == 0U) {
1332 #if EL1_NONSECURE && defined (__aarch64__)
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,
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);
1347 #if EL1_NONSECURE && defined (__aarch64__)
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,
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);
1358 #ifdef XPAR_PSU_SD_0_DEVICE_ID
1363 /*****************************************************************************/
1366 * API to set Tap Delay for DDR50 mode
1369 * @param InstancePtr is a pointer to the XSdPs instance.
1375 ******************************************************************************/
1376 void XSdPs_ddr50_tapdelay(u32 Bank, u32 DeviceId, u32 CardType)
1381 #ifdef XPAR_PSU_SD_0_DEVICE_ID
1382 if (DeviceId == 0U) {
1383 #if EL1_NONSECURE && defined (__aarch64__)
1385 Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR + SD_ITAPDLY) |
1386 ((u64)SD0_ITAPCHGWIN << 32), (u64)SD0_ITAPCHGWIN,
1388 Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR + SD_ITAPDLY) |
1389 ((u64)SD0_ITAPDLYENA << 32), (u64)SD0_ITAPDLYENA,
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);
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);
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);
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;
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;
1429 TapDelay |= SD0_OTAPDLYSEL_EMMC_DDR50;
1430 XSdPs_WriteReg(XPS_SYS_CTRL_BASEADDR, SD_OTAPDLY, TapDelay);
1435 #if EL1_NONSECURE && defined (__aarch64__)
1437 Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR + SD_ITAPDLY) |
1438 ((u64)SD1_ITAPCHGWIN << 32), (u64)SD1_ITAPCHGWIN,
1440 Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR + SD_ITAPDLY) |
1441 ((u64)SD1_ITAPDLYENA << 32), (u64)SD1_ITAPDLYENA,
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);
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);
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);
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;
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;
1482 TapDelay |= SD1_OTAPDLYSEL_EMMC_DDR50;
1483 XSdPs_WriteReg(XPS_SYS_CTRL_BASEADDR, SD_OTAPDLY, TapDelay);
1485 #ifdef XPAR_PSU_SD_0_DEVICE_ID
1490 /*****************************************************************************/
1493 * API to set Tap Delay for HSD and SDR25 mode
1496 * @param InstancePtr is a pointer to the XSdPs instance.
1502 ******************************************************************************/
1503 void XSdPs_hsd_sdr25_tapdelay(u32 Bank, u32 DeviceId, u32 CardType)
1508 #ifdef XPAR_PSU_SD_0_DEVICE_ID
1509 if (DeviceId == 0U) {
1510 #if EL1_NONSECURE && defined (__aarch64__)
1512 Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR + SD_ITAPDLY) |
1513 ((u64)SD0_ITAPCHGWIN << 32), (u64)SD0_ITAPCHGWIN,
1515 Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR + SD_ITAPDLY) |
1516 ((u64)SD0_ITAPDLYENA << 32), (u64)SD0_ITAPDLYENA,
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,
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);
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);
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;
1548 TapDelay |= SD0_OTAPDLYSEL_EMMC_HSD;
1549 XSdPs_WriteReg(XPS_SYS_CTRL_BASEADDR, SD_OTAPDLY, TapDelay);
1554 #if EL1_NONSECURE && defined (__aarch64__)
1556 Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR + SD_ITAPDLY) |
1557 ((u64)SD1_ITAPCHGWIN << 32), (u64)SD1_ITAPCHGWIN,
1559 Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR + SD_ITAPDLY) |
1560 ((u64)SD1_ITAPDLYENA << 32), (u64)SD1_ITAPDLYENA,
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,
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);
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);
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;
1592 TapDelay |= SD1_OTAPDLYSEL_EMMC_HSD;
1593 XSdPs_WriteReg(XPS_SYS_CTRL_BASEADDR, SD_OTAPDLY, TapDelay);
1595 #ifdef XPAR_PSU_SD_0_DEVICE_ID
1600 /*****************************************************************************/
1603 * API to set Tap Delay w.r.t speed modes
1606 * @param InstancePtr is a pointer to the XSdPs instance.
1612 ******************************************************************************/
1613 void XSdPs_SetTapDelay(XSdPs *InstancePtr)
1615 u32 DllCtrl, BankNum, DeviceId, CardType;
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__)
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);
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);
1632 InstancePtr->Config_TapDelay(BankNum, DeviceId, CardType);
1633 #if EL1_NONSECURE && defined (__aarch64__)
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);
1639 DllCtrl &= ~SD0_DLL_RST;
1640 XSdPs_WriteReg(XPS_SYS_CTRL_BASEADDR, SD_DLL_CTRL, DllCtrl);
1644 #if EL1_NONSECURE && defined (__aarch64__)
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);
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);
1654 InstancePtr->Config_TapDelay(BankNum, DeviceId, CardType);
1655 #if EL1_NONSECURE && defined (__aarch64__)
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);
1661 DllCtrl &= ~SD1_DLL_RST;
1662 XSdPs_WriteReg(XPS_SYS_CTRL_BASEADDR, SD_DLL_CTRL, DllCtrl);
1664 #ifdef XPAR_PSU_SD_0_DEVICE_ID
1669 /*****************************************************************************/
1672 * API to reset the DLL
1675 * @param InstancePtr is a pointer to the XSdPs instance.
1681 ******************************************************************************/
1682 static void XSdPs_DllReset(XSdPs *InstancePtr)
1684 u32 ClockReg, DllCtrl;
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);
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__)
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);
1702 DllCtrl |= SD0_DLL_RST;
1703 XSdPs_WriteReg(XPS_SYS_CTRL_BASEADDR, SD_DLL_CTRL, DllCtrl);
1706 #if EL1_NONSECURE && defined (__aarch64__)
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);
1712 DllCtrl |= SD1_DLL_RST;
1713 XSdPs_WriteReg(XPS_SYS_CTRL_BASEADDR, SD_DLL_CTRL, DllCtrl);
1717 /* Wait for 2 micro seconds */
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__)
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);
1729 DllCtrl &= ~SD0_DLL_RST;
1730 XSdPs_WriteReg(XPS_SYS_CTRL_BASEADDR, SD_DLL_CTRL, DllCtrl);
1733 #if EL1_NONSECURE && defined (__aarch64__)
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);
1739 DllCtrl &= ~SD1_DLL_RST;
1740 XSdPs_WriteReg(XPS_SYS_CTRL_BASEADDR, SD_DLL_CTRL, DllCtrl);
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);
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);