2 This file provides some helper functions which are specific for SD card device.
4 Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
5 Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include "SdMmcPciHcDxe.h"
13 Send command GO_IDLE_STATE to the device to make it go to Idle State.
15 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
17 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
18 @param[in] Slot The slot number of the SD card to send the command to.
20 @retval EFI_SUCCESS The SD device is reset correctly.
21 @retval Others The device reset fails.
26 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
30 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
31 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
32 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
35 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
36 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
37 ZeroMem (&Packet
, sizeof (Packet
));
39 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
40 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
41 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
43 SdMmcCmdBlk
.CommandIndex
= SD_GO_IDLE_STATE
;
44 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeBc
;
46 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
52 Send command SEND_IF_COND to the device to inquiry the SD Memory Card interface
55 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
57 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
58 @param[in] Slot The slot number of the SD card to send the command to.
59 @param[in] SupplyVoltage The supplied voltage by the host.
60 @param[in] CheckPattern The check pattern to be sent to the device.
62 @retval EFI_SUCCESS The operation is done correctly.
63 @retval Others The operation fails.
68 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
70 IN UINT8 SupplyVoltage
,
74 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
75 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
76 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
79 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
80 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
81 ZeroMem (&Packet
, sizeof (Packet
));
83 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
84 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
85 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
87 SdMmcCmdBlk
.CommandIndex
= SD_SEND_IF_COND
;
88 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeBcr
;
89 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR7
;
90 SdMmcCmdBlk
.CommandArgument
= (SupplyVoltage
<< 8) | CheckPattern
;
92 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
94 if (!EFI_ERROR (Status
)) {
95 if (SdMmcStatusBlk
.Resp0
!= SdMmcCmdBlk
.CommandArgument
) {
96 return EFI_DEVICE_ERROR
;
104 Send command SDIO_SEND_OP_COND to the device to see whether it is SDIO device.
106 Refer to SDIO Simplified Spec 3 Section 3.2 for details.
108 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
109 @param[in] Slot The slot number of the SD card to send the command to.
110 @param[in] VoltageWindow The supply voltage window.
111 @param[in] S18R The boolean to show if it should switch to 1.8v.
113 @retval EFI_SUCCESS The operation is done correctly.
114 @retval Others The operation fails.
119 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
121 IN UINT32 VoltageWindow
,
125 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
126 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
127 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
131 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
132 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
133 ZeroMem (&Packet
, sizeof (Packet
));
135 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
136 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
137 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
139 SdMmcCmdBlk
.CommandIndex
= SDIO_SEND_OP_COND
;
140 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeBcr
;
141 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR4
;
143 Switch
= S18R
? BIT24
: 0;
145 SdMmcCmdBlk
.CommandArgument
= (VoltageWindow
& 0xFFFFFF) | Switch
;
147 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
153 Send command SD_SEND_OP_COND to the device to see whether it is SDIO device.
155 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
157 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
158 @param[in] Slot The slot number of the SD card to send the command to.
159 @param[in] Rca The relative device address of addressed device.
160 @param[in] VoltageWindow The supply voltage window.
161 @param[in] S18R The boolean to show if it should switch to 1.8v.
162 @param[in] Xpc The boolean to show if it should provide 0.36w power control.
163 @param[in] Hcs The boolean to show if it support host capacity info.
164 @param[out] Ocr The buffer to store returned OCR register value.
166 @retval EFI_SUCCESS The operation is done correctly.
167 @retval Others The operation fails.
172 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
175 IN UINT32 VoltageWindow
,
182 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
183 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
184 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
190 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
191 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
192 ZeroMem (&Packet
, sizeof (Packet
));
194 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
195 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
196 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
198 SdMmcCmdBlk
.CommandIndex
= SD_APP_CMD
;
199 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
200 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
201 SdMmcCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
203 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
204 if (EFI_ERROR (Status
)) {
208 SdMmcCmdBlk
.CommandIndex
= SD_SEND_OP_COND
;
209 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeBcr
;
210 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR3
;
212 Switch
= S18R
? BIT24
: 0;
213 MaxPower
= Xpc
? BIT28
: 0;
214 HostCapacity
= Hcs
? BIT30
: 0;
216 SdMmcCmdBlk
.CommandArgument
= (VoltageWindow
& 0xFFFFFF) | Switch
| MaxPower
| HostCapacity
;
218 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
219 if (!EFI_ERROR (Status
)) {
221 // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12.
223 *Ocr
= SdMmcStatusBlk
.Resp0
;
230 Broadcast command ALL_SEND_CID to the bus to ask all the SD devices to send the
231 data of their CID registers.
233 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
235 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
236 @param[in] Slot The slot number of the SD card to send the command to.
238 @retval EFI_SUCCESS The operation is done correctly.
239 @retval Others The operation fails.
244 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
248 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
249 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
250 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
253 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
254 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
255 ZeroMem (&Packet
, sizeof (Packet
));
257 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
258 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
259 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
261 SdMmcCmdBlk
.CommandIndex
= SD_ALL_SEND_CID
;
262 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeBcr
;
263 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR2
;
265 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
271 Send command SET_RELATIVE_ADDR to the SD device to assign a Relative device
274 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
276 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
277 @param[in] Slot The slot number of the SD card to send the command to.
278 @param[out] Rca The relative device address to assign.
280 @retval EFI_SUCCESS The operation is done correctly.
281 @retval Others The operation fails.
286 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
291 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
292 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
293 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
296 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
297 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
298 ZeroMem (&Packet
, sizeof (Packet
));
300 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
301 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
302 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
304 SdMmcCmdBlk
.CommandIndex
= SD_SET_RELATIVE_ADDR
;
305 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeBcr
;
306 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR6
;
308 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
309 if (!EFI_ERROR (Status
)) {
310 *Rca
= (UINT16
)(SdMmcStatusBlk
.Resp0
>> 16);
317 Send command SELECT_DESELECT_CARD to the SD device to select/deselect it.
319 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
321 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
322 @param[in] Slot The slot number of the SD card to send the command to.
323 @param[in] Rca The relative device address of selected device.
325 @retval EFI_SUCCESS The operation is done correctly.
326 @retval Others The operation fails.
331 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
336 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
337 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
338 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
341 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
342 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
343 ZeroMem (&Packet
, sizeof (Packet
));
345 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
346 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
347 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
349 SdMmcCmdBlk
.CommandIndex
= SD_SELECT_DESELECT_CARD
;
350 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
352 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1b
;
355 SdMmcCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
357 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
363 Send command VOLTAGE_SWITCH to the SD device to switch the voltage of the device.
365 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
367 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
368 @param[in] Slot The slot number of the SD card to send the command to.
370 @retval EFI_SUCCESS The operation is done correctly.
371 @retval Others The operation fails.
375 SdCardVoltageSwitch (
376 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
380 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
381 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
382 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
385 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
386 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
387 ZeroMem (&Packet
, sizeof (Packet
));
389 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
390 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
391 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
393 SdMmcCmdBlk
.CommandIndex
= SD_VOLTAGE_SWITCH
;
394 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
395 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
396 SdMmcCmdBlk
.CommandArgument
= 0;
398 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
404 Send command SET_BUS_WIDTH to the SD device to set the bus width.
406 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
408 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
409 @param[in] Slot The slot number of the SD card to send the command to.
410 @param[in] Rca The relative device address of addressed device.
411 @param[in] BusWidth The bus width to be set, it could be 1 or 4.
413 @retval EFI_SUCCESS The operation is done correctly.
414 @retval Others The operation fails.
419 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
425 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
426 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
427 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
431 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
432 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
433 ZeroMem (&Packet
, sizeof (Packet
));
435 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
436 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
437 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
439 SdMmcCmdBlk
.CommandIndex
= SD_APP_CMD
;
440 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
441 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
442 SdMmcCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
444 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
445 if (EFI_ERROR (Status
)) {
449 SdMmcCmdBlk
.CommandIndex
= SD_SET_BUS_WIDTH
;
450 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
451 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
455 } else if (BusWidth
== 4) {
458 return EFI_INVALID_PARAMETER
;
461 SdMmcCmdBlk
.CommandArgument
= Value
& 0x3;
463 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
468 Send command SWITCH_FUNC to the SD device to check switchable function or switch card function.
470 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
472 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
473 @param[in] Slot The slot number of the SD card to send the command to.
474 @param[in] BusTiming Target bus timing based on which access group value will be set.
475 @param[in] CommandSystem The value for command set group.
476 @param[in] DriverStrength The value for driver strength group.
477 @param[in] PowerLimit The value for power limit group.
478 @param[in] Mode Switch or check function.
479 @param[out] SwitchResp The return switch function status.
481 @retval EFI_SUCCESS The operation is done correctly.
482 @retval Others The operation fails.
487 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
489 IN SD_MMC_BUS_MODE BusTiming
,
490 IN UINT8 CommandSystem
,
491 IN SD_DRIVER_STRENGTH_TYPE DriverStrength
,
494 OUT UINT8
*SwitchResp
497 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
498 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
499 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
504 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
505 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
506 ZeroMem (&Packet
, sizeof (Packet
));
508 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
509 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
510 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
512 SdMmcCmdBlk
.CommandIndex
= SD_SWITCH_FUNC
;
513 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAdtc
;
514 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
516 ModeValue
= Mode
? BIT31
: 0;
540 SdMmcCmdBlk
.CommandArgument
= (AccessMode
& 0xF) | ((CommandSystem
& 0xF) << 4) | \
541 ((DriverStrength
& 0xF) << 8) | ((PowerLimit
& 0xF) << 12) | \
544 Packet
.InDataBuffer
= SwitchResp
;
545 Packet
.InTransferLength
= 64;
547 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
548 if (EFI_ERROR (Status
)) {
553 if ((((AccessMode
& 0xF) != 0xF) && ((SwitchResp
[16] & 0xF) != AccessMode
)) ||
554 (((CommandSystem
& 0xF) != 0xF) && (((SwitchResp
[16] >> 4) & 0xF) != CommandSystem
)) ||
555 (((DriverStrength
& 0xF) != 0xF) && ((SwitchResp
[15] & 0xF) != DriverStrength
)) ||
556 (((PowerLimit
& 0xF) != 0xF) && (((SwitchResp
[15] >> 4) & 0xF) != PowerLimit
)))
558 return EFI_DEVICE_ERROR
;
566 Send command SEND_STATUS to the addressed SD device to get its status register.
568 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
570 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
571 @param[in] Slot The slot number of the SD card to send the command to.
572 @param[in] Rca The relative device address of addressed device.
573 @param[out] DevStatus The returned device status.
575 @retval EFI_SUCCESS The operation is done correctly.
576 @retval Others The operation fails.
581 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
584 OUT UINT32
*DevStatus
587 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
588 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
589 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
592 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
593 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
594 ZeroMem (&Packet
, sizeof (Packet
));
596 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
597 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
598 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
600 SdMmcCmdBlk
.CommandIndex
= SD_SEND_STATUS
;
601 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
602 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
603 SdMmcCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
605 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
606 if (!EFI_ERROR (Status
)) {
607 *DevStatus
= SdMmcStatusBlk
.Resp0
;
614 Send command SEND_TUNING_BLOCK to the SD device for HS200 optimal sampling point
617 It may be sent up to 40 times until the host finishes the tuning procedure.
619 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
621 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
622 @param[in] Slot The slot number of the SD card to send the command to.
624 @retval EFI_SUCCESS The operation is done correctly.
625 @retval Others The operation fails.
629 SdCardSendTuningBlk (
630 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
634 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
635 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
636 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
638 UINT8 TuningBlock
[64];
640 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
641 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
642 ZeroMem (&Packet
, sizeof (Packet
));
644 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
645 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
646 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
648 SdMmcCmdBlk
.CommandIndex
= SD_SEND_TUNING_BLOCK
;
649 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAdtc
;
650 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
651 SdMmcCmdBlk
.CommandArgument
= 0;
653 Packet
.InDataBuffer
= TuningBlock
;
654 Packet
.InTransferLength
= sizeof (TuningBlock
);
656 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
662 Tunning the sampling point of SDR104 or SDR50 bus speed mode.
664 Command SD_SEND_TUNING_BLOCK may be sent up to 40 times until the host finishes the
667 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and
668 SD Host Controller Simplified Spec 3.0 section Figure 3-7 for details.
670 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
671 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
672 @param[in] Slot The slot number of the SD card to send the command to.
674 @retval EFI_SUCCESS The operation is done correctly.
675 @retval Others The operation fails.
680 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
681 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
690 // Notify the host that the sampling clock tuning procedure starts.
693 Status
= SdMmcHcOrMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
694 if (EFI_ERROR (Status
)) {
699 // Ask the device to send a sequence of tuning blocks till the tuning procedure is done.
703 Status
= SdCardSendTuningBlk (PassThru
, Slot
);
704 if (EFI_ERROR (Status
)) {
705 DEBUG ((DEBUG_ERROR
, "SdCardSendTuningBlk: Send tuning block fails with %r\n", Status
));
709 Status
= SdMmcHcRwMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, TRUE
, sizeof (HostCtrl2
), &HostCtrl2
);
710 if (EFI_ERROR (Status
)) {
714 if ((HostCtrl2
& (BIT6
| BIT7
)) == 0) {
718 if ((HostCtrl2
& (BIT6
| BIT7
)) == BIT7
) {
721 } while (++Retry
< 40);
723 DEBUG ((DEBUG_ERROR
, "SdCardTuningClock: Send tuning block fails at %d times with HostCtrl2 %02x\n", Retry
, HostCtrl2
));
725 // Abort the tuning procedure and reset the tuning circuit.
727 HostCtrl2
= (UINT8
) ~(BIT6
| BIT7
);
728 Status
= SdMmcHcAndMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
729 if (EFI_ERROR (Status
)) {
733 return EFI_DEVICE_ERROR
;
737 Switch the bus width to specified width.
739 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and
740 SD Host Controller Simplified Spec 3.0 section Figure 3-7 for details.
742 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
743 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
744 @param[in] Slot The slot number of the SD card to send the command to.
745 @param[in] Rca The relative device address to be assigned.
746 @param[in] BusWidth The bus width to be set, it could be 4 or 8.
748 @retval EFI_SUCCESS The operation is done correctly.
749 @retval Others The operation fails.
753 SdCardSwitchBusWidth (
754 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
755 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
764 Status
= SdCardSetBusWidth (PassThru
, Slot
, Rca
, BusWidth
);
765 if (EFI_ERROR (Status
)) {
766 DEBUG ((DEBUG_ERROR
, "SdCardSwitchBusWidth: Switch to bus width %d fails with %r\n", BusWidth
, Status
));
770 Status
= SdCardSendStatus (PassThru
, Slot
, Rca
, &DevStatus
);
771 if (EFI_ERROR (Status
)) {
772 DEBUG ((DEBUG_ERROR
, "SdCardSwitchBusWidth: Send status fails with %r\n", Status
));
777 // Check the switch operation is really successful or not.
779 if ((DevStatus
>> 16) != 0) {
780 DEBUG ((DEBUG_ERROR
, "SdCardSwitchBusWidth: The switch operation fails as DevStatus is 0x%08x\n", DevStatus
));
781 return EFI_DEVICE_ERROR
;
784 Status
= SdMmcHcSetBusWidth (PciIo
, Slot
, BusWidth
);
790 Check if passed BusTiming is supported in both controller and card.
792 @param[in] Private Pointer to controller private data
793 @param[in] SlotIndex Index of the slot in the controller
794 @param[in] CardSupportedBusTimings Bitmask indicating which bus timings are supported by card
795 @param[in] IsInUhsI Flag indicating if link is in UHS-I
797 @retval TRUE Both card and controller support given BusTiming
798 @retval FALSE Card or controller doesn't support given BusTiming
801 SdIsBusTimingSupported (
802 IN SD_MMC_HC_PRIVATE_DATA
*Private
,
804 IN UINT8 CardSupportedBusTimings
,
806 IN SD_MMC_BUS_MODE BusTiming
809 SD_MMC_HC_SLOT_CAP
*Capability
;
811 Capability
= &Private
->Capability
[SlotIndex
];
816 if ((Capability
->Sdr104
!= 0) && ((CardSupportedBusTimings
& BIT3
) != 0)) {
822 if ((Capability
->Ddr50
!= 0) && ((CardSupportedBusTimings
& BIT4
) != 0)) {
828 if ((Capability
->Sdr50
!= 0) && ((CardSupportedBusTimings
& BIT2
) != 0)) {
834 if ((CardSupportedBusTimings
& BIT1
) != 0) {
840 if ((CardSupportedBusTimings
& BIT0
) != 0) {
851 if ((Capability
->HighSpeed
!= 0) && ((CardSupportedBusTimings
& BIT1
) != 0)) {
857 if ((CardSupportedBusTimings
& BIT0
) != 0) {
871 Get the target bus timing to set on the link. This function
872 will try to select highest bus timing supported by card, controller
875 @param[in] Private Pointer to controller private data
876 @param[in] SlotIndex Index of the slot in the controller
877 @param[in] CardSupportedBusTimings Bitmask indicating which bus timings are supported by card
878 @param[in] IsInUhsI Flag indicating if link is in UHS-I
880 @return Bus timing value that should be set on link
883 SdGetTargetBusTiming (
884 IN SD_MMC_HC_PRIVATE_DATA
*Private
,
886 IN UINT8 CardSupportedBusTimings
,
890 SD_MMC_BUS_MODE BusTiming
;
893 BusTiming
= SdMmcUhsSdr104
;
895 BusTiming
= SdMmcSdHs
;
898 while (BusTiming
> SdMmcSdDs
) {
899 if (SdIsBusTimingSupported (Private
, SlotIndex
, CardSupportedBusTimings
, IsInUhsI
, BusTiming
)) {
910 Get the target bus width to be set on the bus.
912 @param[in] Private Pointer to controller private data
913 @param[in] SlotIndex Index of the slot in the controller
914 @param[in] BusTiming Bus timing set on the bus
916 @return Bus width to be set on the bus
919 SdGetTargetBusWidth (
920 IN SD_MMC_HC_PRIVATE_DATA
*Private
,
922 IN SD_MMC_BUS_MODE BusTiming
926 UINT8 PreferredBusWidth
;
928 PreferredBusWidth
= Private
->Slot
[SlotIndex
].OperatingParameters
.BusWidth
;
930 if ((BusTiming
== SdMmcSdDs
) || (BusTiming
== SdMmcSdHs
)) {
931 if ((PreferredBusWidth
!= EDKII_SD_MMC_BUS_WIDTH_IGNORE
) &&
932 ((PreferredBusWidth
== 1) || (PreferredBusWidth
== 4)))
934 BusWidth
= PreferredBusWidth
;
940 // UHS-I modes support only 4-bit width.
941 // Switch to 4-bit has been done before calling this function anyway so
942 // this is purely informational.
951 Get the target clock frequency to be set on the bus.
953 @param[in] Private Pointer to controller private data
954 @param[in] SlotIndex Index of the slot in the controller
955 @param[in] BusTiming Bus timing to be set on the bus
957 @return Value of the clock frequency to be set on bus in MHz
960 SdGetTargetBusClockFreq (
961 IN SD_MMC_HC_PRIVATE_DATA
*Private
,
963 IN SD_MMC_BUS_MODE BusTiming
966 UINT32 PreferredClockFreq
;
969 PreferredClockFreq
= Private
->Slot
[SlotIndex
].OperatingParameters
.ClockFreq
;
989 if ((PreferredClockFreq
!= EDKII_SD_MMC_CLOCK_FREQ_IGNORE
) && (PreferredClockFreq
< MaxClockFreq
)) {
990 return PreferredClockFreq
;
997 Get the driver strength to be set on bus.
999 @param[in] Private Pointer to controller private data
1000 @param[in] SlotIndex Index of the slot in the controller
1001 @param[in] CardSupportedDriverStrengths Bitmask indicating which driver strengths are supported on the card
1002 @param[in] BusTiming Bus timing set on the bus
1004 @return Value of the driver strength to be set on the bus
1006 EDKII_SD_MMC_DRIVER_STRENGTH
1007 SdGetTargetDriverStrength (
1008 IN SD_MMC_HC_PRIVATE_DATA
*Private
,
1010 IN UINT8 CardSupportedDriverStrengths
,
1011 IN SD_MMC_BUS_MODE BusTiming
1014 EDKII_SD_MMC_DRIVER_STRENGTH PreferredDriverStrength
;
1015 EDKII_SD_MMC_DRIVER_STRENGTH DriverStrength
;
1017 if ((BusTiming
== SdMmcSdDs
) || (BusTiming
== SdMmcSdHs
)) {
1018 DriverStrength
.Sd
= SdDriverStrengthIgnore
;
1019 return DriverStrength
;
1022 PreferredDriverStrength
= Private
->Slot
[SlotIndex
].OperatingParameters
.DriverStrength
;
1023 DriverStrength
.Sd
= SdDriverStrengthTypeB
;
1025 if ((PreferredDriverStrength
.Sd
!= EDKII_SD_MMC_DRIVER_STRENGTH_IGNORE
) &&
1026 (CardSupportedDriverStrengths
& (BIT0
<< PreferredDriverStrength
.Sd
)))
1028 if (((PreferredDriverStrength
.Sd
== SdDriverStrengthTypeA
) &&
1029 (Private
->Capability
[SlotIndex
].DriverTypeA
!= 0)) ||
1030 ((PreferredDriverStrength
.Sd
== SdDriverStrengthTypeC
) &&
1031 (Private
->Capability
[SlotIndex
].DriverTypeC
!= 0)) ||
1032 ((PreferredDriverStrength
.Sd
== SdDriverStrengthTypeD
) &&
1033 (Private
->Capability
[SlotIndex
].DriverTypeD
!= 0)))
1035 DriverStrength
.Sd
= PreferredDriverStrength
.Sd
;
1039 return DriverStrength
;
1043 Get the target settings for the bus mode.
1045 @param[in] Private Pointer to controller private data
1046 @param[in] SlotIndex Index of the slot in the controller
1047 @param[in] SwitchQueryResp Pointer to switch query response
1048 @param[in] IsInUhsI Flag indicating if link is in UHS-I mode
1049 @param[out] BusMode Target configuration of the bus
1052 SdGetTargetBusMode (
1053 IN SD_MMC_HC_PRIVATE_DATA
*Private
,
1055 IN UINT8
*SwitchQueryResp
,
1056 IN BOOLEAN IsInUhsI
,
1057 OUT SD_MMC_BUS_SETTINGS
*BusMode
1060 BusMode
->BusTiming
= SdGetTargetBusTiming (Private
, SlotIndex
, SwitchQueryResp
[13], IsInUhsI
);
1061 BusMode
->BusWidth
= SdGetTargetBusWidth (Private
, SlotIndex
, BusMode
->BusTiming
);
1062 BusMode
->ClockFreq
= SdGetTargetBusClockFreq (Private
, SlotIndex
, BusMode
->BusTiming
);
1063 BusMode
->DriverStrength
= SdGetTargetDriverStrength (Private
, SlotIndex
, SwitchQueryResp
[9], BusMode
->BusTiming
);
1067 Switch the high speed timing according to request.
1069 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and
1070 SD Host Controller Simplified Spec 3.0 section Figure 2-29 for details.
1072 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
1073 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
1074 @param[in] Slot The slot number of the SD card to send the command to.
1075 @param[in] Rca The relative device address to be assigned.
1076 @param[in] S18A The boolean to show if it's a UHS-I SD card.
1078 @retval EFI_SUCCESS The operation is done correctly.
1079 @retval Others The operation fails.
1084 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1085 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
1092 SD_MMC_HC_SLOT_CAP
*Capability
;
1094 UINT8 SwitchResp
[64];
1095 SD_MMC_HC_PRIVATE_DATA
*Private
;
1096 SD_MMC_BUS_SETTINGS BusMode
;
1098 Private
= SD_MMC_HC_PRIVATE_FROM_THIS (PassThru
);
1100 Capability
= &Private
->Capability
[Slot
];
1102 Status
= SdCardSelect (PassThru
, Slot
, Rca
);
1103 if (EFI_ERROR (Status
)) {
1109 // For UHS-I speed modes 4-bit data bus is requiered so we
1110 // switch here irrespective of platform preference.
1112 Status
= SdCardSwitchBusWidth (PciIo
, PassThru
, Slot
, Rca
, 4);
1113 if (EFI_ERROR (Status
)) {
1119 // Get the supported bus speed from SWITCH cmd return data group #1.
1121 Status
= SdCardSwitch (PassThru
, Slot
, 0xFF, 0xF, SdDriverStrengthIgnore
, 0xF, FALSE
, SwitchResp
);
1122 if (EFI_ERROR (Status
)) {
1126 SdGetTargetBusMode (Private
, Slot
, SwitchResp
, S18A
, &BusMode
);
1130 "SdCardSetBusMode: Target bus mode: bus timing = %d, bus width = %d, clock freq[MHz] = %d, driver strength = %d\n",
1134 BusMode
.DriverStrength
.Sd
1138 Status
= SdCardSwitchBusWidth (PciIo
, PassThru
, Slot
, Rca
, BusMode
.BusWidth
);
1139 if (EFI_ERROR (Status
)) {
1144 Status
= SdCardSwitch (PassThru
, Slot
, BusMode
.BusTiming
, 0xF, BusMode
.DriverStrength
.Sd
, 0xF, TRUE
, SwitchResp
);
1145 if (EFI_ERROR (Status
)) {
1149 Status
= SdMmcSetDriverStrength (Private
->PciIo
, Slot
, BusMode
.DriverStrength
.Sd
);
1150 if (EFI_ERROR (Status
)) {
1155 // Set to High Speed timing
1157 if (BusMode
.BusTiming
== SdMmcSdHs
) {
1159 Status
= SdMmcHcOrMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
1160 if (EFI_ERROR (Status
)) {
1165 Status
= SdMmcHcUhsSignaling (Private
->ControllerHandle
, PciIo
, Slot
, BusMode
.BusTiming
);
1166 if (EFI_ERROR (Status
)) {
1170 Status
= SdMmcHcClockSupply (Private
, Slot
, BusMode
.BusTiming
, FALSE
, BusMode
.ClockFreq
* 1000);
1171 if (EFI_ERROR (Status
)) {
1175 if ((BusMode
.BusTiming
== SdMmcUhsSdr104
) || ((BusMode
.BusTiming
== SdMmcUhsSdr50
) && (Capability
->TuningSDR50
!= 0))) {
1176 Status
= SdCardTuningClock (PciIo
, PassThru
, Slot
);
1177 if (EFI_ERROR (Status
)) {
1186 Execute SD device identification procedure.
1188 Refer to SD Physical Layer Simplified Spec 4.1 Section 3.6 for details.
1190 @param[in] Private A pointer to the SD_MMC_HC_PRIVATE_DATA instance.
1191 @param[in] Slot The slot number of the SD card to send the command to.
1193 @retval EFI_SUCCESS There is a SD card.
1194 @retval Others There is not a SD card.
1198 SdCardIdentification (
1199 IN SD_MMC_HC_PRIVATE_DATA
*Private
,
1204 EFI_PCI_IO_PROTOCOL
*PciIo
;
1205 EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
;
1211 UINT16 ControllerVer
;
1213 UINT32 PresentState
;
1217 PciIo
= Private
->PciIo
;
1218 PassThru
= &Private
->PassThru
;
1220 // 1. Send Cmd0 to the device
1222 Status
= SdCardReset (PassThru
, Slot
);
1223 if (EFI_ERROR (Status
)) {
1224 DEBUG ((DEBUG_INFO
, "SdCardIdentification: Executing Cmd0 fails with %r\n", Status
));
1229 // 2. Send Cmd8 to the device
1231 Status
= SdCardVoltageCheck (PassThru
, Slot
, 0x1, 0xFF);
1232 if (EFI_ERROR (Status
)) {
1233 DEBUG ((DEBUG_INFO
, "SdCardIdentification: Executing Cmd8 fails with %r\n", Status
));
1238 // 3. Send SDIO Cmd5 to the device to the SDIO device OCR register.
1240 Status
= SdioSendOpCond (PassThru
, Slot
, 0, FALSE
);
1241 if (!EFI_ERROR (Status
)) {
1242 DEBUG ((DEBUG_INFO
, "SdCardIdentification: Found SDIO device, ignore it as we don't support\n"));
1243 return EFI_DEVICE_ERROR
;
1247 // 4. Send Acmd41 with voltage window 0 to the device
1249 Status
= SdCardSendOpCond (PassThru
, Slot
, 0, 0, FALSE
, FALSE
, FALSE
, &Ocr
);
1250 if (EFI_ERROR (Status
)) {
1251 DEBUG ((DEBUG_INFO
, "SdCardIdentification: Executing SdCardSendOpCond fails with %r\n", Status
));
1252 return EFI_DEVICE_ERROR
;
1255 if (Private
->Capability
[Slot
].Voltage33
!= 0) {
1259 MaxCurrent
= ((UINT32
)Private
->MaxCurrent
[Slot
] & 0xFF) * 4;
1260 } else if (Private
->Capability
[Slot
].Voltage30
!= 0) {
1264 MaxCurrent
= (((UINT32
)Private
->MaxCurrent
[Slot
] >> 8) & 0xFF) * 4;
1265 } else if (Private
->Capability
[Slot
].Voltage18
!= 0) {
1269 MaxCurrent
= (((UINT32
)Private
->MaxCurrent
[Slot
] >> 16) & 0xFF) * 4;
1272 return EFI_DEVICE_ERROR
;
1275 if (MaxCurrent
>= 150) {
1281 Status
= SdMmcHcRwMmio (PciIo
, Slot
, SD_MMC_HC_CTRL_VER
, TRUE
, sizeof (ControllerVer
), &ControllerVer
);
1282 if (EFI_ERROR (Status
)) {
1286 if (((ControllerVer
& 0xFF) >= SD_MMC_HC_CTRL_VER_300
) &&
1287 ((ControllerVer
& 0xFF) <= SD_MMC_HC_CTRL_VER_420
))
1290 } else if (((ControllerVer
& 0xFF) == SD_MMC_HC_CTRL_VER_100
) || ((ControllerVer
& 0xFF) == SD_MMC_HC_CTRL_VER_200
)) {
1294 return EFI_UNSUPPORTED
;
1298 // 5. Repeatly send Acmd41 with supply voltage window to the device.
1299 // Note here we only support the cards complied with SD physical
1300 // layer simplified spec version 2.0 and version 3.0 and above.
1305 Status
= SdCardSendOpCond (PassThru
, Slot
, 0, Ocr
, S18r
, Xpc
, TRUE
, &Ocr
);
1306 if (EFI_ERROR (Status
)) {
1307 DEBUG ((DEBUG_ERROR
, "SdCardIdentification: SdCardSendOpCond fails with %r Ocr %x, S18r %x, Xpc %x\n", Status
, Ocr
, S18r
, Xpc
));
1308 return EFI_DEVICE_ERROR
;
1311 if (Retry
++ == 100) {
1312 DEBUG ((DEBUG_ERROR
, "SdCardIdentification: SdCardSendOpCond fails too many times\n"));
1313 return EFI_DEVICE_ERROR
;
1316 gBS
->Stall (10 * 1000);
1317 } while ((Ocr
& BIT31
) == 0);
1320 // 6. If the S18A bit is set and the Host Controller supports 1.8V signaling
1321 // (One of support bits is set to 1: SDR50, SDR104 or DDR50 in the
1322 // Capabilities register), switch its voltage to 1.8V.
1324 if (((Private
->Capability
[Slot
].Sdr50
!= 0) ||
1325 (Private
->Capability
[Slot
].Sdr104
!= 0) ||
1326 (Private
->Capability
[Slot
].Ddr50
!= 0)) &&
1327 ((Ocr
& BIT24
) != 0))
1329 Status
= SdCardVoltageSwitch (PassThru
, Slot
);
1330 if (EFI_ERROR (Status
)) {
1331 DEBUG ((DEBUG_ERROR
, "SdCardIdentification: Executing SdCardVoltageSwitch fails with %r\n", Status
));
1332 Status
= EFI_DEVICE_ERROR
;
1335 Status
= SdMmcHcStopClock (PciIo
, Slot
);
1336 if (EFI_ERROR (Status
)) {
1337 Status
= EFI_DEVICE_ERROR
;
1341 SdMmcHcRwMmio (PciIo
, Slot
, SD_MMC_HC_PRESENT_STATE
, TRUE
, sizeof (PresentState
), &PresentState
);
1342 if (((PresentState
>> 20) & 0xF) != 0) {
1343 DEBUG ((DEBUG_ERROR
, "SdCardIdentification: SwitchVoltage fails with PresentState = 0x%x\n", PresentState
));
1344 Status
= EFI_DEVICE_ERROR
;
1349 SdMmcHcOrMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
1353 SdMmcHcRwMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, TRUE
, sizeof (HostCtrl2
), &HostCtrl2
);
1354 if ((HostCtrl2
& BIT3
) == 0) {
1355 DEBUG ((DEBUG_ERROR
, "SdCardIdentification: SwitchVoltage fails with HostCtrl2 = 0x%x\n", HostCtrl2
));
1356 Status
= EFI_DEVICE_ERROR
;
1360 Status
= SdMmcHcStartSdClock (PciIo
, Slot
);
1361 if (EFI_ERROR (Status
)) {
1367 SdMmcHcRwMmio (PciIo
, Slot
, SD_MMC_HC_PRESENT_STATE
, TRUE
, sizeof (PresentState
), &PresentState
);
1368 if (((PresentState
>> 20) & 0xF) != 0xF) {
1369 DEBUG ((DEBUG_ERROR
, "SdCardIdentification: SwitchVoltage fails with PresentState = 0x%x, It should be 0xF\n", PresentState
));
1370 Status
= EFI_DEVICE_ERROR
;
1375 DEBUG ((DEBUG_INFO
, "SdCardIdentification: Switch to 1.8v signal voltage success\n"));
1378 Status
= SdCardAllSendCid (PassThru
, Slot
);
1379 if (EFI_ERROR (Status
)) {
1380 DEBUG ((DEBUG_ERROR
, "SdCardIdentification: Executing SdCardAllSendCid fails with %r\n", Status
));
1384 Status
= SdCardSetRca (PassThru
, Slot
, &Rca
);
1385 if (EFI_ERROR (Status
)) {
1386 DEBUG ((DEBUG_ERROR
, "SdCardIdentification: Executing SdCardSetRca fails with %r\n", Status
));
1391 // Enter Data Tranfer Mode.
1393 DEBUG ((DEBUG_INFO
, "SdCardIdentification: Found a SD device at slot [%d]\n", Slot
));
1394 Private
->Slot
[Slot
].CardType
= SdCardType
;
1396 Status
= SdCardSetBusMode (PciIo
, PassThru
, Slot
, Rca
, ((Ocr
& BIT24
) != 0));
1402 // Set SD Bus Power = 0
1404 PowerCtrl
= (UINT8
) ~BIT0
;
1405 Status
= SdMmcHcAndMmio (PciIo
, Slot
, SD_MMC_HC_POWER_CTRL
, sizeof (PowerCtrl
), &PowerCtrl
);
1406 return EFI_DEVICE_ERROR
;