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);
321 Send command SELECT_DESELECT_CARD to the SD device to select/deselect it.
323 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
325 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
326 @param[in] Slot The slot number of the SD card to send the command to.
327 @param[in] Rca The relative device address of selected device.
329 @retval EFI_SUCCESS The operation is done correctly.
330 @retval Others The operation fails.
335 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
340 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
341 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
342 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
345 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
346 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
347 ZeroMem (&Packet
, sizeof (Packet
));
349 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
350 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
351 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
353 SdMmcCmdBlk
.CommandIndex
= SD_SELECT_DESELECT_CARD
;
354 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
356 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1b
;
358 SdMmcCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
360 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
366 Send command VOLTAGE_SWITCH to the SD device to switch the voltage of the device.
368 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
370 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
371 @param[in] Slot The slot number of the SD card to send the command to.
373 @retval EFI_SUCCESS The operation is done correctly.
374 @retval Others The operation fails.
378 SdCardVoltageSwitch (
379 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
383 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
384 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
385 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
388 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
389 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
390 ZeroMem (&Packet
, sizeof (Packet
));
392 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
393 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
394 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
396 SdMmcCmdBlk
.CommandIndex
= SD_VOLTAGE_SWITCH
;
397 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
398 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
399 SdMmcCmdBlk
.CommandArgument
= 0;
401 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
407 Send command SET_BUS_WIDTH to the SD device to set the bus width.
409 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
411 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
412 @param[in] Slot The slot number of the SD card to send the command to.
413 @param[in] Rca The relative device address of addressed device.
414 @param[in] BusWidth The bus width to be set, it could be 1 or 4.
416 @retval EFI_SUCCESS The operation is done correctly.
417 @retval Others The operation fails.
422 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
428 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
429 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
430 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
434 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
435 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
436 ZeroMem (&Packet
, sizeof (Packet
));
438 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
439 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
440 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
442 SdMmcCmdBlk
.CommandIndex
= SD_APP_CMD
;
443 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
444 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
445 SdMmcCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
447 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
448 if (EFI_ERROR (Status
)) {
452 SdMmcCmdBlk
.CommandIndex
= SD_SET_BUS_WIDTH
;
453 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
454 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
458 } else if (BusWidth
== 4) {
461 return EFI_INVALID_PARAMETER
;
464 SdMmcCmdBlk
.CommandArgument
= Value
& 0x3;
466 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
471 Send command SWITCH_FUNC to the SD device to check switchable function or switch card function.
473 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
475 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
476 @param[in] Slot The slot number of the SD card to send the command to.
477 @param[in] AccessMode The value for access mode group.
478 @param[in] CommandSystem The value for command set group.
479 @param[in] DriveStrength The value for drive length group.
480 @param[in] PowerLimit The value for power limit group.
481 @param[in] Mode Switch or check function.
482 @param[out] SwitchResp The return switch function status.
484 @retval EFI_SUCCESS The operation is done correctly.
485 @retval Others The operation fails.
490 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
493 IN UINT8 CommandSystem
,
494 IN UINT8 DriveStrength
,
497 OUT UINT8
*SwitchResp
500 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
501 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
502 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
506 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
507 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
508 ZeroMem (&Packet
, sizeof (Packet
));
510 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
511 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
512 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
514 SdMmcCmdBlk
.CommandIndex
= SD_SWITCH_FUNC
;
515 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAdtc
;
516 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
518 ModeValue
= Mode
? BIT31
: 0;
519 SdMmcCmdBlk
.CommandArgument
= (AccessMode
& 0xF) | ((PowerLimit
& 0xF) << 4) | \
520 ((DriveStrength
& 0xF) << 8) | ((DriveStrength
& 0xF) << 12) | \
523 Packet
.InDataBuffer
= SwitchResp
;
524 Packet
.InTransferLength
= 64;
526 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
532 Send command SEND_STATUS to the addressed SD device to get its status register.
534 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
536 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
537 @param[in] Slot The slot number of the SD card to send the command to.
538 @param[in] Rca The relative device address of addressed device.
539 @param[out] DevStatus The returned device status.
541 @retval EFI_SUCCESS The operation is done correctly.
542 @retval Others The operation fails.
547 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
550 OUT UINT32
*DevStatus
553 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
554 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
555 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
558 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
559 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
560 ZeroMem (&Packet
, sizeof (Packet
));
562 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
563 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
564 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
566 SdMmcCmdBlk
.CommandIndex
= SD_SEND_STATUS
;
567 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
568 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
569 SdMmcCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
571 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
572 if (!EFI_ERROR (Status
)) {
573 *DevStatus
= SdMmcStatusBlk
.Resp0
;
580 Send command SEND_TUNING_BLOCK to the SD device for HS200 optimal sampling point
583 It may be sent up to 40 times until the host finishes the tuning procedure.
585 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
587 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
588 @param[in] Slot The slot number of the SD card to send the command to.
590 @retval EFI_SUCCESS The operation is done correctly.
591 @retval Others The operation fails.
595 SdCardSendTuningBlk (
596 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
600 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
601 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
602 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
604 UINT8 TuningBlock
[64];
606 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
607 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
608 ZeroMem (&Packet
, sizeof (Packet
));
610 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
611 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
612 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
614 SdMmcCmdBlk
.CommandIndex
= SD_SEND_TUNING_BLOCK
;
615 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAdtc
;
616 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
617 SdMmcCmdBlk
.CommandArgument
= 0;
619 Packet
.InDataBuffer
= TuningBlock
;
620 Packet
.InTransferLength
= sizeof (TuningBlock
);
622 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
628 Tunning the sampling point of SDR104 or SDR50 bus speed mode.
630 Command SD_SEND_TUNING_BLOCK may be sent up to 40 times until the host finishes the
633 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and
634 SD Host Controller Simplified Spec 3.0 section Figure 3-7 for details.
636 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
637 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
638 @param[in] Slot The slot number of the SD card to send the command to.
640 @retval EFI_SUCCESS The operation is done correctly.
641 @retval Others The operation fails.
646 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
647 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
656 // Notify the host that the sampling clock tuning procedure starts.
659 Status
= SdMmcHcOrMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
660 if (EFI_ERROR (Status
)) {
664 // Ask the device to send a sequence of tuning blocks till the tuning procedure is done.
668 Status
= SdCardSendTuningBlk (PassThru
, Slot
);
669 if (EFI_ERROR (Status
)) {
670 DEBUG ((DEBUG_ERROR
, "SdCardSendTuningBlk: Send tuning block fails with %r\n", Status
));
674 Status
= SdMmcHcRwMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, TRUE
, sizeof (HostCtrl2
), &HostCtrl2
);
675 if (EFI_ERROR (Status
)) {
679 if ((HostCtrl2
& (BIT6
| BIT7
)) == 0) {
682 if ((HostCtrl2
& (BIT6
| BIT7
)) == BIT7
) {
685 } while (++Retry
< 40);
687 DEBUG ((DEBUG_ERROR
, "SdCardTuningClock: Send tuning block fails at %d times with HostCtrl2 %02x\n", Retry
, HostCtrl2
));
689 // Abort the tuning procedure and reset the tuning circuit.
691 HostCtrl2
= (UINT8
)~(BIT6
| BIT7
);
692 Status
= SdMmcHcAndMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
693 if (EFI_ERROR (Status
)) {
696 return EFI_DEVICE_ERROR
;
700 Switch the bus width to specified width.
702 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and
703 SD Host Controller Simplified Spec 3.0 section Figure 3-7 for details.
705 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
706 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
707 @param[in] Slot The slot number of the SD card to send the command to.
708 @param[in] Rca The relative device address to be assigned.
709 @param[in] BusWidth The bus width to be set, it could be 4 or 8.
711 @retval EFI_SUCCESS The operation is done correctly.
712 @retval Others The operation fails.
716 SdCardSwitchBusWidth (
717 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
718 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
727 Status
= SdCardSetBusWidth (PassThru
, Slot
, Rca
, BusWidth
);
728 if (EFI_ERROR (Status
)) {
729 DEBUG ((DEBUG_ERROR
, "SdCardSwitchBusWidth: Switch to bus width %d fails with %r\n", BusWidth
, Status
));
733 Status
= SdCardSendStatus (PassThru
, Slot
, Rca
, &DevStatus
);
734 if (EFI_ERROR (Status
)) {
735 DEBUG ((DEBUG_ERROR
, "SdCardSwitchBusWidth: Send status fails with %r\n", Status
));
739 // Check the switch operation is really successful or not.
741 if ((DevStatus
>> 16) != 0) {
742 DEBUG ((DEBUG_ERROR
, "SdCardSwitchBusWidth: The switch operation fails as DevStatus is 0x%08x\n", DevStatus
));
743 return EFI_DEVICE_ERROR
;
746 Status
= SdMmcHcSetBusWidth (PciIo
, Slot
, BusWidth
);
752 Switch the high speed timing according to request.
754 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and
755 SD Host Controller Simplified Spec 3.0 section Figure 2-29 for details.
757 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
758 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
759 @param[in] Slot The slot number of the SD card to send the command to.
760 @param[in] Rca The relative device address to be assigned.
761 @param[in] S18A The boolean to show if it's a UHS-I SD card.
763 @retval EFI_SUCCESS The operation is done correctly.
764 @retval Others The operation fails.
769 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
770 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
777 SD_MMC_HC_SLOT_CAP
*Capability
;
782 UINT8 SwitchResp
[64];
783 SD_MMC_BUS_MODE Timing
;
784 SD_MMC_HC_PRIVATE_DATA
*Private
;
786 Private
= SD_MMC_HC_PRIVATE_FROM_THIS (PassThru
);
788 Capability
= &Private
->Capability
[Slot
];
790 Status
= SdCardSelect (PassThru
, Slot
, Rca
);
791 if (EFI_ERROR (Status
)) {
797 Status
= SdCardSwitchBusWidth (PciIo
, PassThru
, Slot
, Rca
, BusWidth
);
798 if (EFI_ERROR (Status
)) {
802 // Get the supported bus speed from SWITCH cmd return data group #1.
804 Status
= SdCardSwitch (PassThru
, Slot
, 0xF, 0xF, 0xF, 0xF, FALSE
, SwitchResp
);
805 if (EFI_ERROR (Status
)) {
809 // Calculate supported bus speed/bus width/clock frequency by host and device capability.
812 if (S18A
&& (Capability
->Sdr104
!= 0) && ((SwitchResp
[13] & BIT3
) != 0)) {
815 Timing
= SdMmcUhsSdr104
;
816 } else if (S18A
&& (Capability
->Sdr50
!= 0) && ((SwitchResp
[13] & BIT2
) != 0)) {
819 Timing
= SdMmcUhsSdr50
;
820 } else if (S18A
&& (Capability
->Ddr50
!= 0) && ((SwitchResp
[13] & BIT4
) != 0)) {
823 Timing
= SdMmcUhsDdr50
;
824 } else if ((SwitchResp
[13] & BIT1
) != 0) {
827 Timing
= SdMmcUhsSdr25
;
831 Timing
= SdMmcUhsSdr12
;
834 Status
= SdCardSwitch (PassThru
, Slot
, AccessMode
, 0xF, 0xF, 0xF, TRUE
, SwitchResp
);
835 if (EFI_ERROR (Status
)) {
839 if ((SwitchResp
[16] & 0xF) != AccessMode
) {
840 DEBUG ((DEBUG_ERROR
, "SdCardSetBusMode: Switch to AccessMode %d ClockFreq %d BusWidth %d fails! The Switch response is 0x%1x\n", AccessMode
, ClockFreq
, BusWidth
, SwitchResp
[16] & 0xF));
841 return EFI_DEVICE_ERROR
;
844 DEBUG ((DEBUG_INFO
, "SdCardSetBusMode: Switch to AccessMode %d ClockFreq %d BusWidth %d\n", AccessMode
, ClockFreq
, BusWidth
));
847 // Set to Hight Speed timing
849 if (AccessMode
== 1) {
851 Status
= SdMmcHcOrMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
852 if (EFI_ERROR (Status
)) {
857 Status
= SdMmcHcUhsSignaling (Private
->ControllerHandle
, PciIo
, Slot
, Timing
);
858 if (EFI_ERROR (Status
)) {
862 Status
= SdMmcHcClockSupply (PciIo
, Slot
, ClockFreq
* 1000, Private
->BaseClkFreq
[Slot
], Private
->ControllerVersion
[Slot
]);
863 if (EFI_ERROR (Status
)) {
867 if (mOverride
!= NULL
&& mOverride
->NotifyPhase
!= NULL
) {
868 Status
= mOverride
->NotifyPhase (
869 Private
->ControllerHandle
,
871 EdkiiSdMmcSwitchClockFreqPost
,
874 if (EFI_ERROR (Status
)) {
877 "%a: SD/MMC switch clock freq post notifier callback failed - %r\n",
885 if ((AccessMode
== 3) || ((AccessMode
== 2) && (Capability
->TuningSDR50
!= 0))) {
886 Status
= SdCardTuningClock (PciIo
, PassThru
, Slot
);
887 if (EFI_ERROR (Status
)) {
896 Execute SD device identification procedure.
898 Refer to SD Physical Layer Simplified Spec 4.1 Section 3.6 for details.
900 @param[in] Private A pointer to the SD_MMC_HC_PRIVATE_DATA instance.
901 @param[in] Slot The slot number of the SD card to send the command to.
903 @retval EFI_SUCCESS There is a SD card.
904 @retval Others There is not a SD card.
908 SdCardIdentification (
909 IN SD_MMC_HC_PRIVATE_DATA
*Private
,
914 EFI_PCI_IO_PROTOCOL
*PciIo
;
915 EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
;
921 UINT16 ControllerVer
;
927 PciIo
= Private
->PciIo
;
928 PassThru
= &Private
->PassThru
;
930 // 1. Send Cmd0 to the device
932 Status
= SdCardReset (PassThru
, Slot
);
933 if (EFI_ERROR (Status
)) {
934 DEBUG ((DEBUG_INFO
, "SdCardIdentification: Executing Cmd0 fails with %r\n", Status
));
938 // 2. Send Cmd8 to the device
940 Status
= SdCardVoltageCheck (PassThru
, Slot
, 0x1, 0xFF);
941 if (EFI_ERROR (Status
)) {
942 DEBUG ((DEBUG_INFO
, "SdCardIdentification: Executing Cmd8 fails with %r\n", Status
));
946 // 3. Send SDIO Cmd5 to the device to the SDIO device OCR register.
948 Status
= SdioSendOpCond (PassThru
, Slot
, 0, FALSE
);
949 if (!EFI_ERROR (Status
)) {
950 DEBUG ((DEBUG_INFO
, "SdCardIdentification: Found SDIO device, ignore it as we don't support\n"));
951 return EFI_DEVICE_ERROR
;
954 // 4. Send Acmd41 with voltage window 0 to the device
956 Status
= SdCardSendOpCond (PassThru
, Slot
, 0, 0, FALSE
, FALSE
, FALSE
, &Ocr
);
957 if (EFI_ERROR (Status
)) {
958 DEBUG ((DEBUG_INFO
, "SdCardIdentification: Executing SdCardSendOpCond fails with %r\n", Status
));
959 return EFI_DEVICE_ERROR
;
962 if (Private
->Capability
[Slot
].Voltage33
!= 0) {
966 MaxCurrent
= ((UINT32
)Private
->MaxCurrent
[Slot
] & 0xFF) * 4;
967 } else if (Private
->Capability
[Slot
].Voltage30
!= 0) {
971 MaxCurrent
= (((UINT32
)Private
->MaxCurrent
[Slot
] >> 8) & 0xFF) * 4;
972 } else if (Private
->Capability
[Slot
].Voltage18
!= 0) {
976 MaxCurrent
= (((UINT32
)Private
->MaxCurrent
[Slot
] >> 16) & 0xFF) * 4;
979 return EFI_DEVICE_ERROR
;
982 if (MaxCurrent
>= 150) {
988 Status
= SdMmcHcRwMmio (PciIo
, Slot
, SD_MMC_HC_CTRL_VER
, TRUE
, sizeof (ControllerVer
), &ControllerVer
);
989 if (EFI_ERROR (Status
)) {
993 if (((ControllerVer
& 0xFF) >= SD_MMC_HC_CTRL_VER_300
) &&
994 ((ControllerVer
& 0xFF) <= SD_MMC_HC_CTRL_VER_420
)) {
996 } else if (((ControllerVer
& 0xFF) == SD_MMC_HC_CTRL_VER_100
) || ((ControllerVer
& 0xFF) == SD_MMC_HC_CTRL_VER_200
)) {
1000 return EFI_UNSUPPORTED
;
1003 // 5. Repeatly send Acmd41 with supply voltage window to the device.
1004 // Note here we only support the cards complied with SD physical
1005 // layer simplified spec version 2.0 and version 3.0 and above.
1010 Status
= SdCardSendOpCond (PassThru
, Slot
, 0, Ocr
, S18r
, Xpc
, TRUE
, &Ocr
);
1011 if (EFI_ERROR (Status
)) {
1012 DEBUG ((DEBUG_ERROR
, "SdCardIdentification: SdCardSendOpCond fails with %r Ocr %x, S18r %x, Xpc %x\n", Status
, Ocr
, S18r
, Xpc
));
1013 return EFI_DEVICE_ERROR
;
1016 if (Retry
++ == 100) {
1017 DEBUG ((DEBUG_ERROR
, "SdCardIdentification: SdCardSendOpCond fails too many times\n"));
1018 return EFI_DEVICE_ERROR
;
1020 gBS
->Stall(10 * 1000);
1021 } while ((Ocr
& BIT31
) == 0);
1024 // 6. If the S18A bit is set and the Host Controller supports 1.8V signaling
1025 // (One of support bits is set to 1: SDR50, SDR104 or DDR50 in the
1026 // Capabilities register), switch its voltage to 1.8V.
1028 if ((Private
->Capability
[Slot
].Sdr50
!= 0 ||
1029 Private
->Capability
[Slot
].Sdr104
!= 0 ||
1030 Private
->Capability
[Slot
].Ddr50
!= 0) &&
1031 ((Ocr
& BIT24
) != 0)) {
1032 Status
= SdCardVoltageSwitch (PassThru
, Slot
);
1033 if (EFI_ERROR (Status
)) {
1034 DEBUG ((DEBUG_ERROR
, "SdCardIdentification: Executing SdCardVoltageSwitch fails with %r\n", Status
));
1035 Status
= EFI_DEVICE_ERROR
;
1038 Status
= SdMmcHcStopClock (PciIo
, Slot
);
1039 if (EFI_ERROR (Status
)) {
1040 Status
= EFI_DEVICE_ERROR
;
1044 SdMmcHcRwMmio (PciIo
, Slot
, SD_MMC_HC_PRESENT_STATE
, TRUE
, sizeof (PresentState
), &PresentState
);
1045 if (((PresentState
>> 20) & 0xF) != 0) {
1046 DEBUG ((DEBUG_ERROR
, "SdCardIdentification: SwitchVoltage fails with PresentState = 0x%x\n", PresentState
));
1047 Status
= EFI_DEVICE_ERROR
;
1051 SdMmcHcOrMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
1055 SdMmcHcRwMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, TRUE
, sizeof (HostCtrl2
), &HostCtrl2
);
1056 if ((HostCtrl2
& BIT3
) == 0) {
1057 DEBUG ((DEBUG_ERROR
, "SdCardIdentification: SwitchVoltage fails with HostCtrl2 = 0x%x\n", HostCtrl2
));
1058 Status
= EFI_DEVICE_ERROR
;
1062 SdMmcHcInitClockFreq (PciIo
, Slot
, Private
->BaseClkFreq
[Slot
], Private
->ControllerVersion
[Slot
]);
1066 SdMmcHcRwMmio (PciIo
, Slot
, SD_MMC_HC_PRESENT_STATE
, TRUE
, sizeof (PresentState
), &PresentState
);
1067 if (((PresentState
>> 20) & 0xF) != 0xF) {
1068 DEBUG ((DEBUG_ERROR
, "SdCardIdentification: SwitchVoltage fails with PresentState = 0x%x, It should be 0xF\n", PresentState
));
1069 Status
= EFI_DEVICE_ERROR
;
1073 DEBUG ((DEBUG_INFO
, "SdCardIdentification: Switch to 1.8v signal voltage success\n"));
1076 Status
= SdCardAllSendCid (PassThru
, Slot
);
1077 if (EFI_ERROR (Status
)) {
1078 DEBUG ((DEBUG_ERROR
, "SdCardIdentification: Executing SdCardAllSendCid fails with %r\n", Status
));
1082 Status
= SdCardSetRca (PassThru
, Slot
, &Rca
);
1083 if (EFI_ERROR (Status
)) {
1084 DEBUG ((DEBUG_ERROR
, "SdCardIdentification: Executing SdCardSetRca fails with %r\n", Status
));
1088 // Enter Data Tranfer Mode.
1090 DEBUG ((DEBUG_INFO
, "SdCardIdentification: Found a SD device at slot [%d]\n", Slot
));
1091 Private
->Slot
[Slot
].CardType
= SdCardType
;
1093 Status
= SdCardSetBusMode (PciIo
, PassThru
, Slot
, Rca
, ((Ocr
& BIT24
) != 0));
1099 // Set SD Bus Power = 0
1101 PowerCtrl
= (UINT8
)~BIT0
;
1102 Status
= SdMmcHcAndMmio (PciIo
, Slot
, SD_MMC_HC_POWER_CTRL
, sizeof (PowerCtrl
), &PowerCtrl
);
1103 return EFI_DEVICE_ERROR
;