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
;
354 SdMmcCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
356 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
362 Send command VOLTAGE_SWITCH to the SD device to switch the voltage of the device.
364 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
366 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
367 @param[in] Slot The slot number of the SD card to send the command to.
369 @retval EFI_SUCCESS The operation is done correctly.
370 @retval Others The operation fails.
374 SdCardVoltageSwitch (
375 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
379 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
380 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
381 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
384 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
385 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
386 ZeroMem (&Packet
, sizeof (Packet
));
388 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
389 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
390 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
392 SdMmcCmdBlk
.CommandIndex
= SD_VOLTAGE_SWITCH
;
393 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
394 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
395 SdMmcCmdBlk
.CommandArgument
= 0;
397 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
403 Send command SET_BUS_WIDTH to the SD device to set the bus width.
405 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
407 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
408 @param[in] Slot The slot number of the SD card to send the command to.
409 @param[in] Rca The relative device address of addressed device.
410 @param[in] BusWidth The bus width to be set, it could be 1 or 4.
412 @retval EFI_SUCCESS The operation is done correctly.
413 @retval Others The operation fails.
418 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
424 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
425 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
426 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
430 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
431 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
432 ZeroMem (&Packet
, sizeof (Packet
));
434 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
435 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
436 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
438 SdMmcCmdBlk
.CommandIndex
= SD_APP_CMD
;
439 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
440 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
441 SdMmcCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
443 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
444 if (EFI_ERROR (Status
)) {
448 SdMmcCmdBlk
.CommandIndex
= SD_SET_BUS_WIDTH
;
449 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
450 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
454 } else if (BusWidth
== 4) {
457 return EFI_INVALID_PARAMETER
;
460 SdMmcCmdBlk
.CommandArgument
= Value
& 0x3;
462 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
467 Send command SWITCH_FUNC to the SD device to check switchable function or switch card function.
469 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
471 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
472 @param[in] Slot The slot number of the SD card to send the command to.
473 @param[in] BusTiming Target bus timing based on which access group value will be set.
474 @param[in] CommandSystem The value for command set group.
475 @param[in] DriverStrength The value for driver strength group.
476 @param[in] PowerLimit The value for power limit group.
477 @param[in] Mode Switch or check function.
478 @param[out] SwitchResp The return switch function status.
480 @retval EFI_SUCCESS The operation is done correctly.
481 @retval Others The operation fails.
486 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
488 IN SD_MMC_BUS_MODE BusTiming
,
489 IN UINT8 CommandSystem
,
490 IN SD_DRIVER_STRENGTH_TYPE DriverStrength
,
493 OUT UINT8
*SwitchResp
496 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
497 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
498 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
503 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
504 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
505 ZeroMem (&Packet
, sizeof (Packet
));
507 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
508 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
509 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
511 SdMmcCmdBlk
.CommandIndex
= SD_SWITCH_FUNC
;
512 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAdtc
;
513 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
515 ModeValue
= Mode
? BIT31
: 0;
539 SdMmcCmdBlk
.CommandArgument
= (AccessMode
& 0xF) | ((CommandSystem
& 0xF) << 4) | \
540 ((DriverStrength
& 0xF) << 8) | ((PowerLimit
& 0xF) << 12) | \
543 Packet
.InDataBuffer
= SwitchResp
;
544 Packet
.InTransferLength
= 64;
546 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
547 if (EFI_ERROR (Status
)) {
552 if ((((AccessMode
& 0xF) != 0xF) && ((SwitchResp
[16] & 0xF) != AccessMode
)) ||
553 (((CommandSystem
& 0xF) != 0xF) && (((SwitchResp
[16] >> 4) & 0xF) != CommandSystem
)) ||
554 (((DriverStrength
& 0xF) != 0xF) && ((SwitchResp
[15] & 0xF) != DriverStrength
)) ||
555 (((PowerLimit
& 0xF) != 0xF) && (((SwitchResp
[15] >> 4) & 0xF) != PowerLimit
))) {
556 return EFI_DEVICE_ERROR
;
564 Send command SEND_STATUS to the addressed SD device to get its status register.
566 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
568 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
569 @param[in] Slot The slot number of the SD card to send the command to.
570 @param[in] Rca The relative device address of addressed device.
571 @param[out] DevStatus The returned device status.
573 @retval EFI_SUCCESS The operation is done correctly.
574 @retval Others The operation fails.
579 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
582 OUT UINT32
*DevStatus
585 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
586 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
587 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
590 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
591 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
592 ZeroMem (&Packet
, sizeof (Packet
));
594 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
595 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
596 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
598 SdMmcCmdBlk
.CommandIndex
= SD_SEND_STATUS
;
599 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
600 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
601 SdMmcCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
603 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
604 if (!EFI_ERROR (Status
)) {
605 *DevStatus
= SdMmcStatusBlk
.Resp0
;
612 Send command SEND_TUNING_BLOCK to the SD device for HS200 optimal sampling point
615 It may be sent up to 40 times until the host finishes the tuning procedure.
617 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
619 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
620 @param[in] Slot The slot number of the SD card to send the command to.
622 @retval EFI_SUCCESS The operation is done correctly.
623 @retval Others The operation fails.
627 SdCardSendTuningBlk (
628 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
632 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
633 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
634 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
636 UINT8 TuningBlock
[64];
638 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
639 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
640 ZeroMem (&Packet
, sizeof (Packet
));
642 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
643 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
644 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
646 SdMmcCmdBlk
.CommandIndex
= SD_SEND_TUNING_BLOCK
;
647 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAdtc
;
648 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
649 SdMmcCmdBlk
.CommandArgument
= 0;
651 Packet
.InDataBuffer
= TuningBlock
;
652 Packet
.InTransferLength
= sizeof (TuningBlock
);
654 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
660 Tunning the sampling point of SDR104 or SDR50 bus speed mode.
662 Command SD_SEND_TUNING_BLOCK may be sent up to 40 times until the host finishes the
665 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and
666 SD Host Controller Simplified Spec 3.0 section Figure 3-7 for details.
668 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
669 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
670 @param[in] Slot The slot number of the SD card to send the command to.
672 @retval EFI_SUCCESS The operation is done correctly.
673 @retval Others The operation fails.
678 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
679 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
688 // Notify the host that the sampling clock tuning procedure starts.
691 Status
= SdMmcHcOrMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
692 if (EFI_ERROR (Status
)) {
696 // Ask the device to send a sequence of tuning blocks till the tuning procedure is done.
700 Status
= SdCardSendTuningBlk (PassThru
, Slot
);
701 if (EFI_ERROR (Status
)) {
702 DEBUG ((DEBUG_ERROR
, "SdCardSendTuningBlk: Send tuning block fails with %r\n", Status
));
706 Status
= SdMmcHcRwMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, TRUE
, sizeof (HostCtrl2
), &HostCtrl2
);
707 if (EFI_ERROR (Status
)) {
711 if ((HostCtrl2
& (BIT6
| BIT7
)) == 0) {
714 if ((HostCtrl2
& (BIT6
| BIT7
)) == BIT7
) {
717 } while (++Retry
< 40);
719 DEBUG ((DEBUG_ERROR
, "SdCardTuningClock: Send tuning block fails at %d times with HostCtrl2 %02x\n", Retry
, HostCtrl2
));
721 // Abort the tuning procedure and reset the tuning circuit.
723 HostCtrl2
= (UINT8
)~(BIT6
| BIT7
);
724 Status
= SdMmcHcAndMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
725 if (EFI_ERROR (Status
)) {
728 return EFI_DEVICE_ERROR
;
732 Switch the bus width to specified width.
734 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and
735 SD Host Controller Simplified Spec 3.0 section Figure 3-7 for details.
737 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
738 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
739 @param[in] Slot The slot number of the SD card to send the command to.
740 @param[in] Rca The relative device address to be assigned.
741 @param[in] BusWidth The bus width to be set, it could be 4 or 8.
743 @retval EFI_SUCCESS The operation is done correctly.
744 @retval Others The operation fails.
748 SdCardSwitchBusWidth (
749 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
750 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
759 Status
= SdCardSetBusWidth (PassThru
, Slot
, Rca
, BusWidth
);
760 if (EFI_ERROR (Status
)) {
761 DEBUG ((DEBUG_ERROR
, "SdCardSwitchBusWidth: Switch to bus width %d fails with %r\n", BusWidth
, Status
));
765 Status
= SdCardSendStatus (PassThru
, Slot
, Rca
, &DevStatus
);
766 if (EFI_ERROR (Status
)) {
767 DEBUG ((DEBUG_ERROR
, "SdCardSwitchBusWidth: Send status fails with %r\n", Status
));
771 // Check the switch operation is really successful or not.
773 if ((DevStatus
>> 16) != 0) {
774 DEBUG ((DEBUG_ERROR
, "SdCardSwitchBusWidth: The switch operation fails as DevStatus is 0x%08x\n", DevStatus
));
775 return EFI_DEVICE_ERROR
;
778 Status
= SdMmcHcSetBusWidth (PciIo
, Slot
, BusWidth
);
784 Check if passed BusTiming is supported in both controller and card.
786 @param[in] Private Pointer to controller private data
787 @param[in] SlotIndex Index of the slot in the controller
788 @param[in] CardSupportedBusTimings Bitmask indicating which bus timings are supported by card
789 @param[in] IsInUhsI Flag indicating if link is in UHS-I
791 @retval TRUE Both card and controller support given BusTiming
792 @retval FALSE Card or controller doesn't support given BusTiming
795 SdIsBusTimingSupported (
796 IN SD_MMC_HC_PRIVATE_DATA
*Private
,
798 IN UINT8 CardSupportedBusTimings
,
800 IN SD_MMC_BUS_MODE BusTiming
803 SD_MMC_HC_SLOT_CAP
*Capability
;
805 Capability
= &Private
->Capability
[SlotIndex
];
810 if ((Capability
->Sdr104
!= 0) && ((CardSupportedBusTimings
& BIT3
) != 0)) {
815 if ((Capability
->Ddr50
!= 0) && ((CardSupportedBusTimings
& BIT4
) != 0)) {
820 if ((Capability
->Sdr50
!= 0) && ((CardSupportedBusTimings
& BIT2
) != 0)) {
825 if ((CardSupportedBusTimings
& BIT1
) != 0) {
830 if ((CardSupportedBusTimings
& BIT0
) != 0) {
840 if ((Capability
->HighSpeed
!= 0) && (CardSupportedBusTimings
& BIT1
) != 0) {
845 if ((CardSupportedBusTimings
& BIT0
) != 0) {
858 Get the target bus timing to set on the link. This function
859 will try to select highest bus timing supported by card, controller
862 @param[in] Private Pointer to controller private data
863 @param[in] SlotIndex Index of the slot in the controller
864 @param[in] CardSupportedBusTimings Bitmask indicating which bus timings are supported by card
865 @param[in] IsInUhsI Flag indicating if link is in UHS-I
867 @return Bus timing value that should be set on link
870 SdGetTargetBusTiming (
871 IN SD_MMC_HC_PRIVATE_DATA
*Private
,
873 IN UINT8 CardSupportedBusTimings
,
877 SD_MMC_BUS_MODE BusTiming
;
880 BusTiming
= SdMmcUhsSdr104
;
882 BusTiming
= SdMmcSdHs
;
885 while (BusTiming
> SdMmcSdDs
) {
886 if (SdIsBusTimingSupported (Private
, SlotIndex
, CardSupportedBusTimings
, IsInUhsI
, BusTiming
)) {
896 Get the target bus width to be set on the bus.
898 @param[in] Private Pointer to controller private data
899 @param[in] SlotIndex Index of the slot in the controller
900 @param[in] BusTiming Bus timing set on the bus
902 @return Bus width to be set on the bus
905 SdGetTargetBusWidth (
906 IN SD_MMC_HC_PRIVATE_DATA
*Private
,
908 IN SD_MMC_BUS_MODE BusTiming
912 UINT8 PreferredBusWidth
;
914 PreferredBusWidth
= Private
->Slot
[SlotIndex
].OperatingParameters
.BusWidth
;
916 if (BusTiming
== SdMmcSdDs
|| BusTiming
== SdMmcSdHs
) {
917 if (PreferredBusWidth
!= EDKII_SD_MMC_BUS_WIDTH_IGNORE
&&
918 (PreferredBusWidth
== 1 || PreferredBusWidth
== 4)) {
919 BusWidth
= PreferredBusWidth
;
925 // UHS-I modes support only 4-bit width.
926 // Switch to 4-bit has been done before calling this function anyway so
927 // this is purely informational.
936 Get the target clock frequency to be set on the bus.
938 @param[in] Private Pointer to controller private data
939 @param[in] SlotIndex Index of the slot in the controller
940 @param[in] BusTiming Bus timing to be set on the bus
942 @return Value of the clock frequency to be set on bus in MHz
945 SdGetTargetBusClockFreq (
946 IN SD_MMC_HC_PRIVATE_DATA
*Private
,
948 IN SD_MMC_BUS_MODE BusTiming
951 UINT32 PreferredClockFreq
;
954 PreferredClockFreq
= Private
->Slot
[SlotIndex
].OperatingParameters
.ClockFreq
;
974 if (PreferredClockFreq
!= EDKII_SD_MMC_CLOCK_FREQ_IGNORE
&& PreferredClockFreq
< MaxClockFreq
) {
975 return PreferredClockFreq
;
982 Get the driver strength to be set on bus.
984 @param[in] Private Pointer to controller private data
985 @param[in] SlotIndex Index of the slot in the controller
986 @param[in] CardSupportedDriverStrengths Bitmask indicating which driver strengths are supported on the card
987 @param[in] BusTiming Bus timing set on the bus
989 @return Value of the driver strength to be set on the bus
991 EDKII_SD_MMC_DRIVER_STRENGTH
992 SdGetTargetDriverStrength (
993 IN SD_MMC_HC_PRIVATE_DATA
*Private
,
995 IN UINT8 CardSupportedDriverStrengths
,
996 IN SD_MMC_BUS_MODE BusTiming
999 EDKII_SD_MMC_DRIVER_STRENGTH PreferredDriverStrength
;
1000 EDKII_SD_MMC_DRIVER_STRENGTH DriverStrength
;
1002 if (BusTiming
== SdMmcSdDs
|| BusTiming
== SdMmcSdHs
) {
1003 DriverStrength
.Sd
= SdDriverStrengthIgnore
;
1004 return DriverStrength
;
1007 PreferredDriverStrength
= Private
->Slot
[SlotIndex
].OperatingParameters
.DriverStrength
;
1008 DriverStrength
.Sd
= SdDriverStrengthTypeB
;
1010 if (PreferredDriverStrength
.Sd
!= EDKII_SD_MMC_DRIVER_STRENGTH_IGNORE
&&
1011 (CardSupportedDriverStrengths
& (BIT0
<< PreferredDriverStrength
.Sd
))) {
1013 if ((PreferredDriverStrength
.Sd
== SdDriverStrengthTypeA
&&
1014 (Private
->Capability
[SlotIndex
].DriverTypeA
!= 0)) ||
1015 (PreferredDriverStrength
.Sd
== SdDriverStrengthTypeC
&&
1016 (Private
->Capability
[SlotIndex
].DriverTypeC
!= 0)) ||
1017 (PreferredDriverStrength
.Sd
== SdDriverStrengthTypeD
&&
1018 (Private
->Capability
[SlotIndex
].DriverTypeD
!= 0))) {
1019 DriverStrength
.Sd
= PreferredDriverStrength
.Sd
;
1023 return DriverStrength
;
1027 Get the target settings for the bus mode.
1029 @param[in] Private Pointer to controller private data
1030 @param[in] SlotIndex Index of the slot in the controller
1031 @param[in] SwitchQueryResp Pointer to switch query response
1032 @param[in] IsInUhsI Flag indicating if link is in UHS-I mode
1033 @param[out] BusMode Target configuration of the bus
1036 SdGetTargetBusMode (
1037 IN SD_MMC_HC_PRIVATE_DATA
*Private
,
1039 IN UINT8
*SwitchQueryResp
,
1040 IN BOOLEAN IsInUhsI
,
1041 OUT SD_MMC_BUS_SETTINGS
*BusMode
1044 BusMode
->BusTiming
= SdGetTargetBusTiming (Private
, SlotIndex
, SwitchQueryResp
[13], IsInUhsI
);
1045 BusMode
->BusWidth
= SdGetTargetBusWidth (Private
, SlotIndex
, BusMode
->BusTiming
);
1046 BusMode
->ClockFreq
= SdGetTargetBusClockFreq (Private
, SlotIndex
, BusMode
->BusTiming
);
1047 BusMode
->DriverStrength
= SdGetTargetDriverStrength (Private
, SlotIndex
, SwitchQueryResp
[9], BusMode
->BusTiming
);
1051 Switch the high speed timing according to request.
1053 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and
1054 SD Host Controller Simplified Spec 3.0 section Figure 2-29 for details.
1056 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
1057 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
1058 @param[in] Slot The slot number of the SD card to send the command to.
1059 @param[in] Rca The relative device address to be assigned.
1060 @param[in] S18A The boolean to show if it's a UHS-I SD card.
1062 @retval EFI_SUCCESS The operation is done correctly.
1063 @retval Others The operation fails.
1068 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1069 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
1076 SD_MMC_HC_SLOT_CAP
*Capability
;
1078 UINT8 SwitchResp
[64];
1079 SD_MMC_HC_PRIVATE_DATA
*Private
;
1080 SD_MMC_BUS_SETTINGS BusMode
;
1082 Private
= SD_MMC_HC_PRIVATE_FROM_THIS (PassThru
);
1084 Capability
= &Private
->Capability
[Slot
];
1086 Status
= SdCardSelect (PassThru
, Slot
, Rca
);
1087 if (EFI_ERROR (Status
)) {
1093 // For UHS-I speed modes 4-bit data bus is requiered so we
1094 // switch here irrespective of platform preference.
1096 Status
= SdCardSwitchBusWidth (PciIo
, PassThru
, Slot
, Rca
, 4);
1097 if (EFI_ERROR (Status
)) {
1103 // Get the supported bus speed from SWITCH cmd return data group #1.
1105 Status
= SdCardSwitch (PassThru
, Slot
, 0xFF, 0xF, SdDriverStrengthIgnore
, 0xF, FALSE
, SwitchResp
);
1106 if (EFI_ERROR (Status
)) {
1110 SdGetTargetBusMode (Private
, Slot
, SwitchResp
, S18A
, &BusMode
);
1112 DEBUG ((DEBUG_INFO
, "SdCardSetBusMode: Target bus mode: bus timing = %d, bus width = %d, clock freq[MHz] = %d, driver strength = %d\n",
1113 BusMode
.BusTiming
, BusMode
.BusWidth
, BusMode
.ClockFreq
, BusMode
.DriverStrength
.Sd
));
1116 Status
= SdCardSwitchBusWidth (PciIo
, PassThru
, Slot
, Rca
, BusMode
.BusWidth
);
1117 if (EFI_ERROR (Status
)) {
1122 Status
= SdCardSwitch (PassThru
, Slot
, BusMode
.BusTiming
, 0xF, BusMode
.DriverStrength
.Sd
, 0xF, TRUE
, SwitchResp
);
1123 if (EFI_ERROR (Status
)) {
1127 Status
= SdMmcSetDriverStrength (Private
->PciIo
, Slot
, BusMode
.DriverStrength
.Sd
);
1128 if (EFI_ERROR (Status
)) {
1133 // Set to High Speed timing
1135 if (BusMode
.BusTiming
== SdMmcSdHs
) {
1137 Status
= SdMmcHcOrMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
1138 if (EFI_ERROR (Status
)) {
1143 Status
= SdMmcHcUhsSignaling (Private
->ControllerHandle
, PciIo
, Slot
, BusMode
.BusTiming
);
1144 if (EFI_ERROR (Status
)) {
1148 Status
= SdMmcHcClockSupply (Private
, Slot
, BusMode
.BusTiming
, FALSE
, BusMode
.ClockFreq
* 1000);
1149 if (EFI_ERROR (Status
)) {
1153 if ((BusMode
.BusTiming
== SdMmcUhsSdr104
) || ((BusMode
.BusTiming
== SdMmcUhsSdr50
) && (Capability
->TuningSDR50
!= 0))) {
1154 Status
= SdCardTuningClock (PciIo
, PassThru
, Slot
);
1155 if (EFI_ERROR (Status
)) {
1164 Execute SD device identification procedure.
1166 Refer to SD Physical Layer Simplified Spec 4.1 Section 3.6 for details.
1168 @param[in] Private A pointer to the SD_MMC_HC_PRIVATE_DATA instance.
1169 @param[in] Slot The slot number of the SD card to send the command to.
1171 @retval EFI_SUCCESS There is a SD card.
1172 @retval Others There is not a SD card.
1176 SdCardIdentification (
1177 IN SD_MMC_HC_PRIVATE_DATA
*Private
,
1182 EFI_PCI_IO_PROTOCOL
*PciIo
;
1183 EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
;
1189 UINT16 ControllerVer
;
1191 UINT32 PresentState
;
1195 PciIo
= Private
->PciIo
;
1196 PassThru
= &Private
->PassThru
;
1198 // 1. Send Cmd0 to the device
1200 Status
= SdCardReset (PassThru
, Slot
);
1201 if (EFI_ERROR (Status
)) {
1202 DEBUG ((DEBUG_INFO
, "SdCardIdentification: Executing Cmd0 fails with %r\n", Status
));
1206 // 2. Send Cmd8 to the device
1208 Status
= SdCardVoltageCheck (PassThru
, Slot
, 0x1, 0xFF);
1209 if (EFI_ERROR (Status
)) {
1210 DEBUG ((DEBUG_INFO
, "SdCardIdentification: Executing Cmd8 fails with %r\n", Status
));
1214 // 3. Send SDIO Cmd5 to the device to the SDIO device OCR register.
1216 Status
= SdioSendOpCond (PassThru
, Slot
, 0, FALSE
);
1217 if (!EFI_ERROR (Status
)) {
1218 DEBUG ((DEBUG_INFO
, "SdCardIdentification: Found SDIO device, ignore it as we don't support\n"));
1219 return EFI_DEVICE_ERROR
;
1222 // 4. Send Acmd41 with voltage window 0 to the device
1224 Status
= SdCardSendOpCond (PassThru
, Slot
, 0, 0, FALSE
, FALSE
, FALSE
, &Ocr
);
1225 if (EFI_ERROR (Status
)) {
1226 DEBUG ((DEBUG_INFO
, "SdCardIdentification: Executing SdCardSendOpCond fails with %r\n", Status
));
1227 return EFI_DEVICE_ERROR
;
1230 if (Private
->Capability
[Slot
].Voltage33
!= 0) {
1234 MaxCurrent
= ((UINT32
)Private
->MaxCurrent
[Slot
] & 0xFF) * 4;
1235 } else if (Private
->Capability
[Slot
].Voltage30
!= 0) {
1239 MaxCurrent
= (((UINT32
)Private
->MaxCurrent
[Slot
] >> 8) & 0xFF) * 4;
1240 } else if (Private
->Capability
[Slot
].Voltage18
!= 0) {
1244 MaxCurrent
= (((UINT32
)Private
->MaxCurrent
[Slot
] >> 16) & 0xFF) * 4;
1247 return EFI_DEVICE_ERROR
;
1250 if (MaxCurrent
>= 150) {
1256 Status
= SdMmcHcRwMmio (PciIo
, Slot
, SD_MMC_HC_CTRL_VER
, TRUE
, sizeof (ControllerVer
), &ControllerVer
);
1257 if (EFI_ERROR (Status
)) {
1261 if (((ControllerVer
& 0xFF) >= SD_MMC_HC_CTRL_VER_300
) &&
1262 ((ControllerVer
& 0xFF) <= SD_MMC_HC_CTRL_VER_420
)) {
1264 } else if (((ControllerVer
& 0xFF) == SD_MMC_HC_CTRL_VER_100
) || ((ControllerVer
& 0xFF) == SD_MMC_HC_CTRL_VER_200
)) {
1268 return EFI_UNSUPPORTED
;
1271 // 5. Repeatly send Acmd41 with supply voltage window to the device.
1272 // Note here we only support the cards complied with SD physical
1273 // layer simplified spec version 2.0 and version 3.0 and above.
1278 Status
= SdCardSendOpCond (PassThru
, Slot
, 0, Ocr
, S18r
, Xpc
, TRUE
, &Ocr
);
1279 if (EFI_ERROR (Status
)) {
1280 DEBUG ((DEBUG_ERROR
, "SdCardIdentification: SdCardSendOpCond fails with %r Ocr %x, S18r %x, Xpc %x\n", Status
, Ocr
, S18r
, Xpc
));
1281 return EFI_DEVICE_ERROR
;
1284 if (Retry
++ == 100) {
1285 DEBUG ((DEBUG_ERROR
, "SdCardIdentification: SdCardSendOpCond fails too many times\n"));
1286 return EFI_DEVICE_ERROR
;
1288 gBS
->Stall(10 * 1000);
1289 } while ((Ocr
& BIT31
) == 0);
1292 // 6. If the S18A bit is set and the Host Controller supports 1.8V signaling
1293 // (One of support bits is set to 1: SDR50, SDR104 or DDR50 in the
1294 // Capabilities register), switch its voltage to 1.8V.
1296 if ((Private
->Capability
[Slot
].Sdr50
!= 0 ||
1297 Private
->Capability
[Slot
].Sdr104
!= 0 ||
1298 Private
->Capability
[Slot
].Ddr50
!= 0) &&
1299 ((Ocr
& BIT24
) != 0)) {
1300 Status
= SdCardVoltageSwitch (PassThru
, Slot
);
1301 if (EFI_ERROR (Status
)) {
1302 DEBUG ((DEBUG_ERROR
, "SdCardIdentification: Executing SdCardVoltageSwitch fails with %r\n", Status
));
1303 Status
= EFI_DEVICE_ERROR
;
1306 Status
= SdMmcHcStopClock (PciIo
, Slot
);
1307 if (EFI_ERROR (Status
)) {
1308 Status
= EFI_DEVICE_ERROR
;
1312 SdMmcHcRwMmio (PciIo
, Slot
, SD_MMC_HC_PRESENT_STATE
, TRUE
, sizeof (PresentState
), &PresentState
);
1313 if (((PresentState
>> 20) & 0xF) != 0) {
1314 DEBUG ((DEBUG_ERROR
, "SdCardIdentification: SwitchVoltage fails with PresentState = 0x%x\n", PresentState
));
1315 Status
= EFI_DEVICE_ERROR
;
1319 SdMmcHcOrMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
1323 SdMmcHcRwMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, TRUE
, sizeof (HostCtrl2
), &HostCtrl2
);
1324 if ((HostCtrl2
& BIT3
) == 0) {
1325 DEBUG ((DEBUG_ERROR
, "SdCardIdentification: SwitchVoltage fails with HostCtrl2 = 0x%x\n", HostCtrl2
));
1326 Status
= EFI_DEVICE_ERROR
;
1331 // Restart the clock with first time parameters.
1332 // NOTE: it is not required to actually restart the clock
1333 // and go through internal clock setup again. Some time
1334 // could be saved if we simply started the SD clock.
1336 SdMmcHcClockSupply (Private
, Slot
, 0, TRUE
, 400);
1340 SdMmcHcRwMmio (PciIo
, Slot
, SD_MMC_HC_PRESENT_STATE
, TRUE
, sizeof (PresentState
), &PresentState
);
1341 if (((PresentState
>> 20) & 0xF) != 0xF) {
1342 DEBUG ((DEBUG_ERROR
, "SdCardIdentification: SwitchVoltage fails with PresentState = 0x%x, It should be 0xF\n", PresentState
));
1343 Status
= EFI_DEVICE_ERROR
;
1347 DEBUG ((DEBUG_INFO
, "SdCardIdentification: Switch to 1.8v signal voltage success\n"));
1350 Status
= SdCardAllSendCid (PassThru
, Slot
);
1351 if (EFI_ERROR (Status
)) {
1352 DEBUG ((DEBUG_ERROR
, "SdCardIdentification: Executing SdCardAllSendCid fails with %r\n", Status
));
1356 Status
= SdCardSetRca (PassThru
, Slot
, &Rca
);
1357 if (EFI_ERROR (Status
)) {
1358 DEBUG ((DEBUG_ERROR
, "SdCardIdentification: Executing SdCardSetRca fails with %r\n", Status
));
1362 // Enter Data Tranfer Mode.
1364 DEBUG ((DEBUG_INFO
, "SdCardIdentification: Found a SD device at slot [%d]\n", Slot
));
1365 Private
->Slot
[Slot
].CardType
= SdCardType
;
1367 Status
= SdCardSetBusMode (PciIo
, PassThru
, Slot
, Rca
, ((Ocr
& BIT24
) != 0));
1373 // Set SD Bus Power = 0
1375 PowerCtrl
= (UINT8
)~BIT0
;
1376 Status
= SdMmcHcAndMmio (PciIo
, Slot
, SD_MMC_HC_POWER_CTRL
, sizeof (PowerCtrl
), &PowerCtrl
);
1377 return EFI_DEVICE_ERROR
;