1 /******************************************************************************
2 * Copyright (C) 2013 - 2020 Xilinx, Inc. All rights reserved.
3 * SPDX-License-Identifier: MIT
4 ******************************************************************************/
5
6 /*****************************************************************************/
7 /**
8 *
9 * @file xsdps_options.c
10 * @addtogroup sdps_v3_9
11 * @{
12 *
13 * Contains API's for changing the various options in host and card.
14 * See xsdps.h for a detailed description of the device and driver.
15 *
16 * <pre>
17 * MODIFICATION HISTORY:
18 *
19 * Ver Who Date Changes
20 * ----- --- -------- -----------------------------------------------
21 * 1.00a hk/sg 10/17/13 Initial release
22 * 2.1 hk 04/18/14 Increase sleep for eMMC switch command.
23 * Add sleep for microblaze designs. CR# 781117.
24 * 2.3 sk 09/23/14 Use XSdPs_Change_ClkFreq API whenever changing
25 * clock.CR# 816586.
26 * 2.5 sg 07/09/15 Added SD 3.0 features
27 * kvn 07/15/15 Modified the code according to MISRAC-2012.
28 * 2.7 sk 01/08/16 Added workaround for issue in auto tuning mode
29 * of SDR50, SDR104 and HS200.
30 * sk 02/16/16 Corrected the Tuning logic.
31 * sk 03/02/16 Configured the Tap Delay values for eMMC HS200 mode.
32 * 2.8 sk 04/20/16 Added new workaround for auto tuning.
33 * 3.0 sk 07/07/16 Used usleep API for both arm and microblaze.
34 * sk 07/16/16 Added support for UHS modes.
35 * sk 07/16/16 Added Tap delays accordingly to different SD/eMMC
36 * operating modes.
37 * 3.1 mi 09/07/16 Removed compilation warnings with extra compiler flags.
38 * sk 11/07/16 Enable Rst_n bit in ext_csd reg if not enabled.
39 * sk 11/16/16 Issue DLL reset at 31 iteration to load new zero value.
40 * 3.2 sk 02/01/17 Added HSD and DDR mode support for eMMC.
41 * sk 02/01/17 Consider bus width parameter from design for switching
42 * vns 02/09/17 Added ARMA53_32 support for ZynqMP CR#968397
43 * vns 03/13/17 Fixed MISRAC mandatory violation
44 * sk 03/20/17 Add support for EL1 non-secure mode.
45 * 3.3 mn 07/25/17 Removed SD0_OTAPDLYENA and SD1_OTAPDLYENA bits
46 * mn 08/07/17 Properly set OTAPDLY value by clearing previous bit
47 * settings
48 * mn 08/17/17 Added CCI support for A53 and disabled data cache
49 * operations when it is enabled.
50 * mn 08/22/17 Updated for Word Access System support
51 * 3.4 mn 01/22/18 Separated out SDR104 and HS200 clock defines
52 * 3.6 mn 07/06/18 Fix Cppcheck warnings for sdps driver
53 * 3.7 aru 03/12/19 Modified the code according to MISRAC-2012.
54 * mn 03/27/19 Disable calls to dll_reset API for versal SPP Platforms
55 * 3.8 mn 04/12/19 Modified TapDelay code for supporting ZynqMP and Versal
56 * mn 05/21/19 Set correct tap delays for Versal
57 * mn 05/21/19 Disable DLL Reset code for Versal
58 * mn 08/29/19 Add call to Cache Invalidation API in XSdPs_Get_BusWidth
59 * 3.9 mn 03/03/20 Restructured the code for more readability and modularity
60 * mn 03/16/20 Move XSdPs_Select_Card API to User APIs
61 *
62 * </pre>
63 *
64 ******************************************************************************/
65
66 /***************************** Include Files *********************************/
67 #include "xsdps_core.h"
68 /************************** Constant Definitions *****************************/
69 /**************************** Type Definitions *******************************/
70
71 /***************** Macros (Inline Functions) Definitions *********************/
72
73 /************************** Function Prototypes ******************************/
74
75 /*****************************************************************************/
76 /**
77 *
78 * @brief
79 * API to change clock freq to given value.
80 *
81 *
82 * @param InstancePtr is a pointer to the XSdPs instance.
83 * @param SelFreq - Clock frequency in Hz.
84 *
85 * @return None
86 *
87 * @note This API will change clock frequency to the value less than
88 * or equal to the given value using the permissible dividors.
89 *
90 ******************************************************************************/
XSdPs_Change_ClkFreq(XSdPs * InstancePtr,u32 SelFreq)91 s32 XSdPs_Change_ClkFreq(XSdPs *InstancePtr, u32 SelFreq)
92 {
93 s32 Status;
94
95 Xil_AssertNonvoid(InstancePtr != NULL);
96 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
97
98 if (InstancePtr->HC_Version == XSDPS_HC_SPEC_V3) {
99 /* Program the Tap delays */
100 XSdPs_SetTapDelay(InstancePtr);
101 }
102
103 Status = XSdPs_SetClock(InstancePtr, SelFreq);
104 if (Status != XST_SUCCESS) {
105 Status = XST_FAILURE;
106 }
107
108 return Status;
109 }
110
111 /*****************************************************************************/
112 /**
113 * @brief
114 * Update Block size for read/write operations.
115 *
116 * @param InstancePtr is a pointer to the instance to be worked on.
117 * @param BlkSize - Block size passed by the user.
118 *
119 * @return None
120 *
121 ******************************************************************************/
XSdPs_SetBlkSize(XSdPs * InstancePtr,u16 BlkSize)122 s32 XSdPs_SetBlkSize(XSdPs *InstancePtr, u16 BlkSize)
123 {
124 s32 Status;
125
126 Xil_AssertNonvoid(InstancePtr != NULL);
127 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
128
129 Status = XSdPs_CheckBusIdle(InstancePtr, (XSDPS_PSR_INHIBIT_CMD_MASK
130 | XSDPS_PSR_INHIBIT_DAT_MASK
131 | XSDPS_PSR_WR_ACTIVE_MASK
132 | XSDPS_PSR_RD_ACTIVE_MASK));
133 if (Status != XST_SUCCESS) {
134 Status = XST_FAILURE;
135 goto RETURN_PATH ;
136 }
137
138 /* Send block write command */
139 Status = XSdPs_CmdTransfer(InstancePtr, CMD16, BlkSize, 0U);
140 if (Status != XST_SUCCESS) {
141 Status = XST_FAILURE;
142 goto RETURN_PATH;
143 }
144
145 /* Set block size to the value passed */
146 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress, XSDPS_BLK_SIZE_OFFSET,
147 BlkSize & XSDPS_BLK_SIZE_MASK);
148
149 RETURN_PATH:
150 return Status;
151 }
152
153 /*****************************************************************************/
154 /**
155 *
156 * @brief
157 * API to get bus width support by card.
158 *
159 *
160 * @param InstancePtr is a pointer to the XSdPs instance.
161 * @param SCR - buffer to store SCR register returned by card.
162 *
163 * @return
164 * - XST_SUCCESS if successful.
165 * - XST_FAILURE if fail.
166 *
167 * @note None.
168 *
169 ******************************************************************************/
XSdPs_Get_BusWidth(XSdPs * InstancePtr,u8 * ReadBuff)170 s32 XSdPs_Get_BusWidth(XSdPs *InstancePtr, u8 *ReadBuff)
171 {
172 s32 Status;
173 u16 BlkCnt;
174 u16 BlkSize;
175 s32 LoopCnt;
176
177 Xil_AssertNonvoid(InstancePtr != NULL);
178 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
179
180 for (LoopCnt = 0; LoopCnt < 8; LoopCnt++) {
181 ReadBuff[LoopCnt] = 0U;
182 }
183
184 /* Send block write command */
185 Status = XSdPs_CmdTransfer(InstancePtr, CMD55,
186 InstancePtr->RelCardAddr, 0U);
187 if (Status != XST_SUCCESS) {
188 Status = XST_FAILURE;
189 goto RETURN_PATH;
190 }
191
192 BlkCnt = XSDPS_SCR_BLKCNT;
193 BlkSize = XSDPS_SCR_BLKSIZE;
194
195 XSdPs_SetupReadDma(InstancePtr, BlkCnt, BlkSize, ReadBuff);
196
197 Status = XSdPs_CmdTransfer(InstancePtr, ACMD51, 0U, BlkCnt);
198 if (Status != XST_SUCCESS) {
199 Status = XST_FAILURE;
200 goto RETURN_PATH;
201 }
202
203 /* Check for transfer done */
204 Status = XSdps_CheckTransferDone(InstancePtr);
205 if (Status != XST_SUCCESS) {
206 Status = XST_FAILURE;
207 }
208
209 if (InstancePtr->Config.IsCacheCoherent == 0U) {
210 Xil_DCacheInvalidateRange((INTPTR)ReadBuff,
211 (INTPTR)BlkCnt * BlkSize);
212 }
213
214 Status = XST_SUCCESS;
215
216 RETURN_PATH:
217 return Status;
218
219 }
220
221 /*****************************************************************************/
222 /**
223 *
224 * @brief
225 * API to set bus width to 4-bit in card and host
226 *
227 *
228 * @param InstancePtr is a pointer to the XSdPs instance.
229 *
230 * @return
231 * - XST_SUCCESS if successful.
232 * - XST_FAILURE if fail.
233 *
234 * @note None.
235 *
236 ******************************************************************************/
XSdPs_Change_BusWidth(XSdPs * InstancePtr)237 s32 XSdPs_Change_BusWidth(XSdPs *InstancePtr)
238 {
239 s32 Status;
240 u32 StatusReg;
241 u32 Arg;
242
243 Xil_AssertNonvoid(InstancePtr != NULL);
244 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
245
246 /*
247 * check for bus width for 3.0 controller and return if
248 * bus width is <4
249 */
250 if ((InstancePtr->HC_Version == XSDPS_HC_SPEC_V3) &&
251 (InstancePtr->Config.BusWidth < XSDPS_WIDTH_4)) {
252 Status = XST_SUCCESS;
253 goto RETURN_PATH;
254 }
255
256 if (InstancePtr->CardType == XSDPS_CARD_SD) {
257
258 Status = XSdPs_CmdTransfer(InstancePtr, CMD55, InstancePtr->RelCardAddr,
259 0U);
260 if (Status != XST_SUCCESS) {
261 Status = XST_FAILURE;
262 goto RETURN_PATH;
263 }
264
265 Status = XSdPs_CmdTransfer(InstancePtr, ACMD6, (u32)InstancePtr->BusWidth, 0U);
266 if (Status != XST_SUCCESS) {
267 Status = XST_FAILURE;
268 goto RETURN_PATH;
269 }
270 } else {
271 if (InstancePtr->BusWidth == XSDPS_8_BIT_WIDTH) {
272 if (InstancePtr->Mode == XSDPS_DDR52_MODE) {
273 Arg = XSDPS_MMC_DDR_8_BIT_BUS_ARG;
274 } else {
275 Arg = XSDPS_MMC_8_BIT_BUS_ARG;
276 }
277 } else {
278 if (InstancePtr->Mode == XSDPS_DDR52_MODE) {
279 Arg = XSDPS_MMC_DDR_4_BIT_BUS_ARG;
280 } else {
281 Arg = XSDPS_MMC_4_BIT_BUS_ARG;
282 }
283 }
284
285 Status = XSdPs_Set_Mmc_ExtCsd(InstancePtr, Arg);
286 if (Status != XST_SUCCESS) {
287 Status = XST_FAILURE;
288 goto RETURN_PATH;
289 }
290 }
291
292 usleep(XSDPS_MMC_DELAY_FOR_SWITCH);
293
294 StatusReg = XSdPs_ReadReg8(InstancePtr->Config.BaseAddress,
295 XSDPS_HOST_CTRL1_OFFSET);
296
297 /* Width setting in controller */
298 if (InstancePtr->BusWidth == XSDPS_8_BIT_WIDTH) {
299 StatusReg |= XSDPS_HC_EXT_BUS_WIDTH;
300 } else {
301 StatusReg |= XSDPS_HC_WIDTH_MASK;
302 }
303
304 XSdPs_WriteReg8(InstancePtr->Config.BaseAddress,
305 XSDPS_HOST_CTRL1_OFFSET,
306 (u8)StatusReg);
307
308 if (InstancePtr->Mode == XSDPS_DDR52_MODE) {
309 StatusReg = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
310 XSDPS_HOST_CTRL2_OFFSET);
311 StatusReg &= (u32)(~XSDPS_HC2_UHS_MODE_MASK);
312 StatusReg |= InstancePtr->Mode;
313 XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
314 XSDPS_HOST_CTRL2_OFFSET, (u16)StatusReg);
315 }
316
317 Status = XST_SUCCESS;
318
319 RETURN_PATH:
320 return Status;
321
322 }
323
324 /*****************************************************************************/
325 /**
326 *
327 * @brief
328 * API to get bus speed supported by card.
329 *
330 *
331 * @param InstancePtr is a pointer to the XSdPs instance.
332 * @param ReadBuff - buffer to store function group support data
333 * returned by card.
334 *
335 * @return
336 * - XST_SUCCESS if successful.
337 * - XST_FAILURE if fail.
338 *
339 * @note None.
340 *
341 ******************************************************************************/
XSdPs_Get_BusSpeed(XSdPs * InstancePtr,u8 * ReadBuff)342 s32 XSdPs_Get_BusSpeed(XSdPs *InstancePtr, u8 *ReadBuff)
343 {
344 s32 Status;
345 u32 Arg;
346 u16 BlkCnt;
347 u16 BlkSize;
348 s32 LoopCnt;
349
350 Xil_AssertNonvoid(InstancePtr != NULL);
351 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
352
353 for (LoopCnt = 0; LoopCnt < 64; LoopCnt++) {
354 ReadBuff[LoopCnt] = 0U;
355 }
356
357 BlkCnt = XSDPS_SWITCH_CMD_BLKCNT;
358 BlkSize = XSDPS_SWITCH_CMD_BLKSIZE;
359
360 XSdPs_SetupReadDma(InstancePtr, BlkCnt, BlkSize, ReadBuff);
361
362 Arg = XSDPS_SWITCH_CMD_HS_GET;
363
364 Status = XSdPs_CmdTransfer(InstancePtr, CMD6, Arg, 1U);
365 if (Status != XST_SUCCESS) {
366 Status = XST_FAILURE;
367 goto RETURN_PATH;
368 }
369
370 /* Check for transfer done */
371 Status = XSdps_CheckTransferDone(InstancePtr);
372 if (Status != XST_SUCCESS) {
373 Status = XST_FAILURE;
374 }
375
376 if (InstancePtr->Config.IsCacheCoherent == 0U) {
377 Xil_DCacheInvalidateRange((INTPTR)ReadBuff,
378 (INTPTR)BlkCnt * BlkSize);
379 }
380
381 Status = XST_SUCCESS;
382
383 RETURN_PATH:
384 return Status;
385
386 }
387
388 /*****************************************************************************/
389 /**
390 *
391 * @brief
392 * API to get SD card status information.
393 *
394 *
395 * @param InstancePtr is a pointer to the XSdPs instance.
396 * @param SdStatReg - buffer to store status data returned by card.
397 *
398 * @return
399 * - XST_SUCCESS if successful.
400 * - XST_FAILURE if fail.
401 *
402 * @note None.
403 *
404 ******************************************************************************/
XSdPs_Get_Status(XSdPs * InstancePtr,u8 * SdStatReg)405 s32 XSdPs_Get_Status(XSdPs *InstancePtr, u8 *SdStatReg)
406 {
407 s32 Status;
408 u16 BlkCnt;
409 u16 BlkSize;
410
411 Xil_AssertNonvoid(InstancePtr != NULL);
412 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
413
414 /* Send block write command */
415 Status = XSdPs_CmdTransfer(InstancePtr, CMD55,
416 InstancePtr->RelCardAddr, 0U);
417 if (Status != XST_SUCCESS) {
418 Status = XST_FAILURE;
419 goto RETURN_PATH;
420 }
421
422 BlkCnt = XSDPS_SD_STATUS_BLKCNT;
423 BlkSize = XSDPS_SD_STATUS_BLKSIZE;
424
425 XSdPs_SetupReadDma(InstancePtr, BlkCnt, BlkSize, SdStatReg);
426
427 Status = XSdPs_CmdTransfer(InstancePtr, ACMD13, 0U, BlkCnt);
428 if (Status != XST_SUCCESS) {
429 Status = XST_FAILURE;
430 goto RETURN_PATH;
431 }
432
433 /* Check for transfer done */
434 Status = XSdps_CheckTransferDone(InstancePtr);
435 if (Status != XST_SUCCESS) {
436 Status = XST_FAILURE;
437 }
438
439 if (InstancePtr->Config.IsCacheCoherent == 0U) {
440 Xil_DCacheInvalidateRange((INTPTR)SdStatReg,
441 (INTPTR)BlkCnt * BlkSize);
442 }
443
444 Status = XST_SUCCESS;
445
446 RETURN_PATH:
447 return Status;
448 }
449
450 /*****************************************************************************/
451 /**
452 *
453 * @brief
454 * API to set high speed in card and host. Changes clock in host accordingly.
455 *
456 *
457 * @param InstancePtr is a pointer to the XSdPs instance.
458 *
459 * @return
460 * - XST_SUCCESS if successful.
461 * - XST_FAILURE if fail.
462 *
463 * @note None.
464 *
465 ******************************************************************************/
XSdPs_Change_BusSpeed(XSdPs * InstancePtr)466 s32 XSdPs_Change_BusSpeed(XSdPs *InstancePtr)
467 {
468 s32 Status;
469 u32 StatusReg;
470
471 Xil_AssertNonvoid(InstancePtr != NULL);
472 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
473
474 if (InstancePtr->CardType == XSDPS_CARD_SD) {
475 Status = XSdPs_Change_SdBusSpeed(InstancePtr);
476 if (Status != XST_SUCCESS) {
477 Status = XST_FAILURE;
478 goto RETURN_PATH;
479 }
480 } else {
481 Status = XSdPs_Change_MmcBusSpeed(InstancePtr);
482 if (Status != XST_SUCCESS) {
483 Status = XST_FAILURE;
484 goto RETURN_PATH;
485 }
486 }
487
488 Status = XSdPs_Change_ClkFreq(InstancePtr, InstancePtr->BusSpeed);
489 if (Status != XST_SUCCESS) {
490 Status = XST_FAILURE;
491 goto RETURN_PATH;
492 }
493
494 if ((InstancePtr->Mode == XSDPS_HS200_MODE) ||
495 (InstancePtr->Mode == XSDPS_UHS_SPEED_MODE_SDR104) ||
496 (InstancePtr->Mode == XSDPS_UHS_SPEED_MODE_SDR50)) {
497 Status = XSdPs_Execute_Tuning(InstancePtr);
498 if (Status != XST_SUCCESS) {
499 Status = XST_FAILURE;
500 goto RETURN_PATH;
501 }
502 }
503
504 usleep(XSDPS_MMC_DELAY_FOR_SWITCH);
505
506 StatusReg = (u32)XSdPs_ReadReg8(InstancePtr->Config.BaseAddress,
507 XSDPS_HOST_CTRL1_OFFSET);
508 StatusReg |= XSDPS_HC_SPEED_MASK;
509 XSdPs_WriteReg8(InstancePtr->Config.BaseAddress,
510 XSDPS_HOST_CTRL1_OFFSET, (u8)StatusReg);
511
512 Status = XST_SUCCESS;
513
514 RETURN_PATH:
515 return Status;
516
517 }
518
519 /*****************************************************************************/
520 /**
521 *
522 * @brief
523 * API to get EXT_CSD register of eMMC.
524 *
525 *
526 * @param InstancePtr is a pointer to the XSdPs instance.
527 * @param ReadBuff - buffer to store EXT_CSD
528 *
529 * @return
530 * - XST_SUCCESS if successful.
531 * - XST_FAILURE if fail.
532 *
533 * @note None.
534 *
535 ******************************************************************************/
XSdPs_Get_Mmc_ExtCsd(XSdPs * InstancePtr,u8 * ReadBuff)536 s32 XSdPs_Get_Mmc_ExtCsd(XSdPs *InstancePtr, u8 *ReadBuff)
537 {
538 s32 Status;
539 u32 Arg = 0U;
540 u16 BlkCnt;
541 u16 BlkSize;
542 s32 LoopCnt;
543
544 Xil_AssertNonvoid(InstancePtr != NULL);
545 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
546
547 for (LoopCnt = 0; LoopCnt < 512; LoopCnt++) {
548 ReadBuff[LoopCnt] = 0U;
549 }
550
551 BlkCnt = XSDPS_EXT_CSD_CMD_BLKCNT;
552 BlkSize = XSDPS_EXT_CSD_CMD_BLKSIZE;
553
554 XSdPs_SetupReadDma(InstancePtr, BlkCnt, BlkSize, ReadBuff);
555
556 /* Send SEND_EXT_CSD command */
557 Status = XSdPs_CmdTransfer(InstancePtr, CMD8, Arg, 1U);
558 if (Status != XST_SUCCESS) {
559 Status = XST_FAILURE;
560 goto RETURN_PATH;
561 }
562
563 /* Check for transfer done */
564 Status = XSdps_CheckTransferDone(InstancePtr);
565 if (Status != XST_SUCCESS) {
566 Status = XST_FAILURE;
567 }
568
569 if (InstancePtr->Config.IsCacheCoherent == 0U) {
570 Xil_DCacheInvalidateRange((INTPTR)ReadBuff,
571 (INTPTR)BlkCnt * BlkSize);
572 }
573
574 Status = XST_SUCCESS;
575
576 RETURN_PATH:
577 return Status;
578
579 }
580
581 /*****************************************************************************/
582 /**
583 *
584 * @brief
585 * API to write EXT_CSD register of eMMC.
586 *
587 *
588 * @param InstancePtr is a pointer to the XSdPs instance.
589 * @param Arg is the argument to be sent along with the command
590 *
591 * @return
592 * - XST_SUCCESS if successful.
593 * - XST_FAILURE if fail.
594 *
595 * @note None.
596 *
597 ******************************************************************************/
XSdPs_Set_Mmc_ExtCsd(XSdPs * InstancePtr,u32 Arg)598 s32 XSdPs_Set_Mmc_ExtCsd(XSdPs *InstancePtr, u32 Arg)
599 {
600 s32 Status;
601
602 Xil_AssertNonvoid(InstancePtr != NULL);
603 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
604
605 Status = XSdPs_CmdTransfer(InstancePtr, CMD6, Arg, 0U);
606 if (Status != XST_SUCCESS) {
607 Status = XST_FAILURE;
608 goto RETURN_PATH;
609 }
610
611 /* Check for transfer done */
612 Status = XSdps_CheckTransferDone(InstancePtr);
613 if (Status != XST_SUCCESS) {
614 Status = XST_FAILURE;
615 }
616
617 Status = XST_SUCCESS;
618
619 RETURN_PATH:
620 return Status;
621
622 }
623
624 /*****************************************************************************/
625 /**
626 *
627 * @brief
628 * API to send pullup command to card before using DAT line 3(using 4-bit bus)
629 *
630 *
631 * @param InstancePtr is a pointer to the XSdPs instance.
632 *
633 * @return
634 * - XST_SUCCESS if successful.
635 * - XST_FAILURE if fail.
636 *
637 * @note None.
638 *
639 ******************************************************************************/
XSdPs_Pullup(XSdPs * InstancePtr)640 s32 XSdPs_Pullup(XSdPs *InstancePtr)
641 {
642 s32 Status;
643
644 Xil_AssertNonvoid(InstancePtr != NULL);
645 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
646
647 Status = XSdPs_CmdTransfer(InstancePtr, CMD55,
648 InstancePtr->RelCardAddr, 0U);
649 if (Status != XST_SUCCESS) {
650 Status = XST_FAILURE;
651 goto RETURN_PATH;
652 }
653
654 Status = XSdPs_CmdTransfer(InstancePtr, ACMD42, 0U, 0U);
655 if (Status != XST_SUCCESS) {
656 Status = XST_FAILURE;
657 goto RETURN_PATH;
658 }
659
660 Status = XST_SUCCESS;
661
662 RETURN_PATH:
663 return Status;
664
665 }
666
667 /*****************************************************************************/
668 /**
669 *
670 * @brief
671 * Selects card and sets default block size
672 *
673 *
674 * @param InstancePtr is a pointer to the XSdPs instance.
675 *
676 * @return
677 * - XST_SUCCESS if successful.
678 * - XST_FAILURE if fail.
679 * - XSDPS_CT_ERROR if Command Transfer fail.
680 *
681 * @note None.
682 *
683 ******************************************************************************/
XSdPs_Select_Card(XSdPs * InstancePtr)684 s32 XSdPs_Select_Card (XSdPs *InstancePtr)
685 {
686 s32 Status;
687
688 Xil_AssertNonvoid(InstancePtr != NULL);
689 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
690
691 /* Send CMD7 - Select card */
692 Status = XSdPs_CmdTransfer(InstancePtr, CMD7,
693 InstancePtr->RelCardAddr, 0U);
694
695 return Status;
696 }
697
698 /** @} */
699