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 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include "SdMmcPciHcDxe.h"
19 Send command GO_IDLE_STATE to the device to make it go to Idle State.
21 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
23 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
24 @param[in] Slot The slot number of the SD card to send the command to.
26 @retval EFI_SUCCESS The SD device is reset correctly.
27 @retval Others The device reset fails.
32 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
36 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
37 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
38 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
41 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
42 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
43 ZeroMem (&Packet
, sizeof (Packet
));
45 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
46 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
47 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
49 SdMmcCmdBlk
.CommandIndex
= SD_GO_IDLE_STATE
;
50 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeBc
;
52 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
58 Send command SEND_IF_COND to the device to inquiry the SD Memory Card interface
61 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
63 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
64 @param[in] Slot The slot number of the SD card to send the command to.
65 @param[in] SupplyVoltage The supplied voltage by the host.
66 @param[in] CheckPattern The check pattern to be sent to the device.
68 @retval EFI_SUCCESS The operation is done correctly.
69 @retval Others The operation fails.
74 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
76 IN UINT8 SupplyVoltage
,
80 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
81 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
82 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
85 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
86 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
87 ZeroMem (&Packet
, sizeof (Packet
));
89 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
90 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
91 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
93 SdMmcCmdBlk
.CommandIndex
= SD_SEND_IF_COND
;
94 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeBcr
;
95 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR7
;
96 SdMmcCmdBlk
.CommandArgument
= (SupplyVoltage
<< 8) | CheckPattern
;
98 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
100 if (!EFI_ERROR (Status
)) {
101 if (SdMmcStatusBlk
.Resp0
!= SdMmcCmdBlk
.CommandArgument
) {
102 return EFI_DEVICE_ERROR
;
110 Send command SDIO_SEND_OP_COND to the device to see whether it is SDIO device.
112 Refer to SDIO Simplified Spec 3 Section 3.2 for details.
114 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
115 @param[in] Slot The slot number of the SD card to send the command to.
116 @param[in] VoltageWindow The supply voltage window.
117 @param[in] S18R The boolean to show if it should switch to 1.8v.
119 @retval EFI_SUCCESS The operation is done correctly.
120 @retval Others The operation fails.
125 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
127 IN UINT32 VoltageWindow
,
131 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
132 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
133 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
137 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
138 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
139 ZeroMem (&Packet
, sizeof (Packet
));
141 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
142 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
143 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
145 SdMmcCmdBlk
.CommandIndex
= SDIO_SEND_OP_COND
;
146 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeBcr
;
147 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR4
;
149 Switch
= S18R
? BIT24
: 0;
151 SdMmcCmdBlk
.CommandArgument
= (VoltageWindow
& 0xFFFFFF) | Switch
;
153 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
159 Send command SD_SEND_OP_COND to the device to see whether it is SDIO device.
161 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
163 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
164 @param[in] Slot The slot number of the SD card to send the command to.
165 @param[in] Rca The relative device address of addressed device.
166 @param[in] VoltageWindow The supply voltage window.
167 @param[in] S18R The boolean to show if it should switch to 1.8v.
168 @param[in] Xpc The boolean to show if it should provide 0.36w power control.
169 @param[in] Hcs The boolean to show if it support host capacity info.
170 @param[out] Ocr The buffer to store returned OCR register value.
172 @retval EFI_SUCCESS The operation is done correctly.
173 @retval Others The operation fails.
178 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
181 IN UINT32 VoltageWindow
,
188 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
189 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
190 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
196 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
197 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
198 ZeroMem (&Packet
, sizeof (Packet
));
200 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
201 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
202 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
204 SdMmcCmdBlk
.CommandIndex
= SD_APP_CMD
;
205 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
206 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
207 SdMmcCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
209 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
210 if (EFI_ERROR (Status
)) {
214 SdMmcCmdBlk
.CommandIndex
= SD_SEND_OP_COND
;
215 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeBcr
;
216 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR3
;
218 Switch
= S18R
? BIT24
: 0;
219 MaxPower
= Xpc
? BIT28
: 0;
220 HostCapacity
= Hcs
? BIT30
: 0;
222 SdMmcCmdBlk
.CommandArgument
= (VoltageWindow
& 0xFFFFFF) | Switch
| MaxPower
| HostCapacity
;
224 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
225 if (!EFI_ERROR (Status
)) {
227 // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12.
229 *Ocr
= SdMmcStatusBlk
.Resp0
;
236 Broadcast command ALL_SEND_CID to the bus to ask all the SD devices to send the
237 data of their CID registers.
239 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
241 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
242 @param[in] Slot The slot number of the SD card to send the command to.
244 @retval EFI_SUCCESS The operation is done correctly.
245 @retval Others The operation fails.
250 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
254 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
255 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
256 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
259 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
260 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
261 ZeroMem (&Packet
, sizeof (Packet
));
263 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
264 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
265 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
267 SdMmcCmdBlk
.CommandIndex
= SD_ALL_SEND_CID
;
268 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeBcr
;
269 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR2
;
271 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
277 Send command SET_RELATIVE_ADDR to the SD device to assign a Relative device
280 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
282 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
283 @param[in] Slot The slot number of the SD card to send the command to.
284 @param[out] Rca The relative device address to assign.
286 @retval EFI_SUCCESS The operation is done correctly.
287 @retval Others The operation fails.
292 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
297 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
298 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
299 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
302 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
303 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
304 ZeroMem (&Packet
, sizeof (Packet
));
306 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
307 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
308 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
310 SdMmcCmdBlk
.CommandIndex
= SD_SET_RELATIVE_ADDR
;
311 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeBcr
;
312 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR6
;
314 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
315 if (!EFI_ERROR (Status
)) {
316 *Rca
= (UINT16
)(SdMmcStatusBlk
.Resp0
>> 16);
327 Send command SELECT_DESELECT_CARD to the SD device to select/deselect it.
329 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
331 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
332 @param[in] Slot The slot number of the SD card to send the command to.
333 @param[in] Rca The relative device address of selected device.
335 @retval EFI_SUCCESS The operation is done correctly.
336 @retval Others The operation fails.
341 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
346 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
347 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
348 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
351 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
352 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
353 ZeroMem (&Packet
, sizeof (Packet
));
355 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
356 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
357 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
359 SdMmcCmdBlk
.CommandIndex
= SD_SELECT_DESELECT_CARD
;
360 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
362 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1b
;
364 SdMmcCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
366 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
372 Send command VOLTAGE_SWITCH to the SD device to switch the voltage of the device.
374 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
376 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
377 @param[in] Slot The slot number of the SD card to send the command to.
379 @retval EFI_SUCCESS The operation is done correctly.
380 @retval Others The operation fails.
384 SdCardVoltageSwitch (
385 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
389 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
390 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
391 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
394 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
395 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
396 ZeroMem (&Packet
, sizeof (Packet
));
398 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
399 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
400 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
402 SdMmcCmdBlk
.CommandIndex
= SD_VOLTAGE_SWITCH
;
403 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
404 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
405 SdMmcCmdBlk
.CommandArgument
= 0;
407 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
413 Send command SET_BUS_WIDTH to the SD device to set the bus width.
415 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
417 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
418 @param[in] Slot The slot number of the SD card to send the command to.
419 @param[in] Rca The relative device address of addressed device.
420 @param[in] BusWidth The bus width to be set, it could be 1 or 4.
422 @retval EFI_SUCCESS The operation is done correctly.
423 @retval Others The operation fails.
428 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
434 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
435 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
436 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
440 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
441 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
442 ZeroMem (&Packet
, sizeof (Packet
));
444 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
445 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
446 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
448 SdMmcCmdBlk
.CommandIndex
= SD_APP_CMD
;
449 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
450 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
451 SdMmcCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
453 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
454 if (EFI_ERROR (Status
)) {
458 SdMmcCmdBlk
.CommandIndex
= SD_SET_BUS_WIDTH
;
459 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
460 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
464 } else if (BusWidth
== 4) {
467 return EFI_INVALID_PARAMETER
;
470 SdMmcCmdBlk
.CommandArgument
= Value
& 0x3;
472 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
477 Send command SWITCH_FUNC to the SD device to check switchable function or switch card function.
479 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
481 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
482 @param[in] Slot The slot number of the SD card to send the command to.
483 @param[in] AccessMode The value for access mode group.
484 @param[in] CommandSystem The value for command set group.
485 @param[in] DriveStrength The value for drive length group.
486 @param[in] PowerLimit The value for power limit group.
487 @param[in] Mode Switch or check function.
488 @param[out] SwitchResp The return switch function status.
490 @retval EFI_SUCCESS The operation is done correctly.
491 @retval Others The operation fails.
496 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
499 IN UINT8 CommandSystem
,
500 IN UINT8 DriveStrength
,
503 OUT UINT8
*SwitchResp
506 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
507 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
508 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
512 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
513 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
514 ZeroMem (&Packet
, sizeof (Packet
));
516 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
517 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
518 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
520 SdMmcCmdBlk
.CommandIndex
= SD_SWITCH_FUNC
;
521 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAdtc
;
522 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
524 ModeValue
= Mode
? BIT31
: 0;
525 SdMmcCmdBlk
.CommandArgument
= (AccessMode
& 0xF) | ((PowerLimit
& 0xF) << 4) | \
526 ((DriveStrength
& 0xF) << 8) | ((DriveStrength
& 0xF) << 12) | \
529 Packet
.InDataBuffer
= SwitchResp
;
530 Packet
.InTransferLength
= 64;
532 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
538 Send command SEND_STATUS to the addressed SD device to get its status register.
540 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
542 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
543 @param[in] Slot The slot number of the SD card to send the command to.
544 @param[in] Rca The relative device address of addressed device.
545 @param[out] DevStatus The returned device status.
547 @retval EFI_SUCCESS The operation is done correctly.
548 @retval Others The operation fails.
553 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
556 OUT UINT32
*DevStatus
559 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
560 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
561 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
564 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
565 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
566 ZeroMem (&Packet
, sizeof (Packet
));
568 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
569 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
570 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
572 SdMmcCmdBlk
.CommandIndex
= SD_SEND_STATUS
;
573 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
574 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
575 SdMmcCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
577 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
578 if (!EFI_ERROR (Status
)) {
579 *DevStatus
= SdMmcStatusBlk
.Resp0
;
586 Send command SEND_TUNING_BLOCK to the SD device for HS200 optimal sampling point
589 It may be sent up to 40 times until the host finishes the tuning procedure.
591 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
593 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
594 @param[in] Slot The slot number of the SD card to send the command to.
596 @retval EFI_SUCCESS The operation is done correctly.
597 @retval Others The operation fails.
601 SdCardSendTuningBlk (
602 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
606 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
607 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
608 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
610 UINT8 TuningBlock
[64];
612 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
613 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
614 ZeroMem (&Packet
, sizeof (Packet
));
616 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
617 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
618 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
620 SdMmcCmdBlk
.CommandIndex
= SD_SEND_TUNING_BLOCK
;
621 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAdtc
;
622 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
623 SdMmcCmdBlk
.CommandArgument
= 0;
625 Packet
.InDataBuffer
= TuningBlock
;
626 Packet
.InTransferLength
= sizeof (TuningBlock
);
628 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
634 Tunning the sampling point of SDR104 or SDR50 bus speed mode.
636 Command SD_SEND_TUNING_BLOCK may be sent up to 40 times until the host finishes the
639 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and
640 SD Host Controller Simplified Spec 3.0 section Figure 3-7 for details.
642 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
643 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
644 @param[in] Slot The slot number of the SD card to send the command to.
646 @retval EFI_SUCCESS The operation is done correctly.
647 @retval Others The operation fails.
652 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
653 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
662 // Notify the host that the sampling clock tuning procedure starts.
665 Status
= SdMmcHcOrMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
666 if (EFI_ERROR (Status
)) {
670 // Ask the device to send a sequence of tuning blocks till the tuning procedure is done.
674 Status
= SdCardSendTuningBlk (PassThru
, Slot
);
675 if (EFI_ERROR (Status
)) {
676 DEBUG ((DEBUG_ERROR
, "SdCardSendTuningBlk: Send tuning block fails with %r\n", Status
));
680 Status
= SdMmcHcRwMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, TRUE
, sizeof (HostCtrl2
), &HostCtrl2
);
681 if (EFI_ERROR (Status
)) {
685 if ((HostCtrl2
& (BIT6
| BIT7
)) == 0) {
688 if ((HostCtrl2
& (BIT6
| BIT7
)) == BIT7
) {
691 } while (++Retry
< 40);
693 DEBUG ((DEBUG_ERROR
, "SdCardTuningClock: Send tuning block fails at %d times with HostCtrl2 %02x\n", Retry
, HostCtrl2
));
695 // Abort the tuning procedure and reset the tuning circuit.
697 HostCtrl2
= (UINT8
)~(BIT6
| BIT7
);
698 Status
= SdMmcHcAndMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
699 if (EFI_ERROR (Status
)) {
702 return EFI_DEVICE_ERROR
;
706 Switch the bus width to specified width.
708 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and
709 SD Host Controller Simplified Spec 3.0 section Figure 3-7 for details.
711 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
712 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
713 @param[in] Slot The slot number of the SD card to send the command to.
714 @param[in] Rca The relative device address to be assigned.
715 @param[in] BusWidth The bus width to be set, it could be 4 or 8.
717 @retval EFI_SUCCESS The operation is done correctly.
718 @retval Others The operation fails.
722 SdCardSwitchBusWidth (
723 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
724 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
733 Status
= SdCardSetBusWidth (PassThru
, Slot
, Rca
, BusWidth
);
734 if (EFI_ERROR (Status
)) {
735 DEBUG ((DEBUG_ERROR
, "SdCardSwitchBusWidth: Switch to bus width %d fails with %r\n", BusWidth
, Status
));
739 Status
= SdCardSendStatus (PassThru
, Slot
, Rca
, &DevStatus
);
740 if (EFI_ERROR (Status
)) {
741 DEBUG ((DEBUG_ERROR
, "SdCardSwitchBusWidth: Send status fails with %r\n", Status
));
745 // Check the switch operation is really successful or not.
747 if ((DevStatus
>> 16) != 0) {
748 DEBUG ((DEBUG_ERROR
, "SdCardSwitchBusWidth: The switch operation fails as DevStatus is 0x%08x\n", DevStatus
));
749 return EFI_DEVICE_ERROR
;
752 Status
= SdMmcHcSetBusWidth (PciIo
, Slot
, BusWidth
);
758 Switch the high speed timing according to request.
760 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and
761 SD Host Controller Simplified Spec 3.0 section Figure 2-29 for details.
763 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
764 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
765 @param[in] Slot The slot number of the SD card to send the command to.
766 @param[in] Rca The relative device address to be assigned.
767 @param[in] S18A The boolean to show if it's a UHS-I SD card.
769 @retval EFI_SUCCESS The operation is done correctly.
770 @retval Others The operation fails.
775 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
776 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
783 SD_MMC_HC_SLOT_CAP
*Capability
;
788 UINT8 SwitchResp
[64];
789 SD_MMC_BUS_MODE Timing
;
790 SD_MMC_HC_PRIVATE_DATA
*Private
;
792 Private
= SD_MMC_HC_PRIVATE_FROM_THIS (PassThru
);
794 Capability
= &Private
->Capability
[Slot
];
796 Status
= SdCardSelect (PassThru
, Slot
, Rca
);
797 if (EFI_ERROR (Status
)) {
803 Status
= SdCardSwitchBusWidth (PciIo
, PassThru
, Slot
, Rca
, BusWidth
);
804 if (EFI_ERROR (Status
)) {
808 // Get the supported bus speed from SWITCH cmd return data group #1.
810 Status
= SdCardSwitch (PassThru
, Slot
, 0xF, 0xF, 0xF, 0xF, FALSE
, SwitchResp
);
811 if (EFI_ERROR (Status
)) {
815 // Calculate supported bus speed/bus width/clock frequency by host and device capability.
818 if (S18A
&& (Capability
->Sdr104
!= 0) && ((SwitchResp
[13] & BIT3
) != 0)) {
821 Timing
= SdMmcUhsSdr104
;
822 } else if (S18A
&& (Capability
->Sdr50
!= 0) && ((SwitchResp
[13] & BIT2
) != 0)) {
825 Timing
= SdMmcUhsSdr50
;
826 } else if (S18A
&& (Capability
->Ddr50
!= 0) && ((SwitchResp
[13] & BIT4
) != 0)) {
829 Timing
= SdMmcUhsDdr50
;
830 } else if ((SwitchResp
[13] & BIT1
) != 0) {
833 Timing
= SdMmcUhsSdr25
;
837 Timing
= SdMmcUhsSdr12
;
840 Status
= SdCardSwitch (PassThru
, Slot
, AccessMode
, 0xF, 0xF, 0xF, TRUE
, SwitchResp
);
841 if (EFI_ERROR (Status
)) {
845 if ((SwitchResp
[16] & 0xF) != AccessMode
) {
846 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));
847 return EFI_DEVICE_ERROR
;
850 DEBUG ((DEBUG_INFO
, "SdCardSetBusMode: Switch to AccessMode %d ClockFreq %d BusWidth %d\n", AccessMode
, ClockFreq
, BusWidth
));
853 // Set to Hight Speed timing
855 if (AccessMode
== 1) {
857 Status
= SdMmcHcOrMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
858 if (EFI_ERROR (Status
)) {
863 Status
= SdMmcHcUhsSignaling (Private
->ControllerHandle
, PciIo
, Slot
, Timing
);
864 if (EFI_ERROR (Status
)) {
868 Status
= SdMmcHcClockSupply (PciIo
, Slot
, ClockFreq
* 1000, Private
->BaseClkFreq
[Slot
], Private
->ControllerVersion
[Slot
]);
869 if (EFI_ERROR (Status
)) {
873 if (mOverride
!= NULL
&& mOverride
->NotifyPhase
!= NULL
) {
874 Status
= mOverride
->NotifyPhase (
875 Private
->ControllerHandle
,
877 EdkiiSdMmcSwitchClockFreqPost
,
880 if (EFI_ERROR (Status
)) {
883 "%a: SD/MMC switch clock freq post notifier callback failed - %r\n",
891 if ((AccessMode
== 3) || ((AccessMode
== 2) && (Capability
->TuningSDR50
!= 0))) {
892 Status
= SdCardTuningClock (PciIo
, PassThru
, Slot
);
893 if (EFI_ERROR (Status
)) {
902 Execute SD device identification procedure.
904 Refer to SD Physical Layer Simplified Spec 4.1 Section 3.6 for details.
906 @param[in] Private A pointer to the SD_MMC_HC_PRIVATE_DATA instance.
907 @param[in] Slot The slot number of the SD card to send the command to.
909 @retval EFI_SUCCESS There is a SD card.
910 @retval Others There is not a SD card.
914 SdCardIdentification (
915 IN SD_MMC_HC_PRIVATE_DATA
*Private
,
920 EFI_PCI_IO_PROTOCOL
*PciIo
;
921 EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
;
927 UINT16 ControllerVer
;
933 PciIo
= Private
->PciIo
;
934 PassThru
= &Private
->PassThru
;
936 // 1. Send Cmd0 to the device
938 Status
= SdCardReset (PassThru
, Slot
);
939 if (EFI_ERROR (Status
)) {
940 DEBUG ((DEBUG_INFO
, "SdCardIdentification: Executing Cmd0 fails with %r\n", Status
));
944 // 2. Send Cmd8 to the device
946 Status
= SdCardVoltageCheck (PassThru
, Slot
, 0x1, 0xFF);
947 if (EFI_ERROR (Status
)) {
948 DEBUG ((DEBUG_INFO
, "SdCardIdentification: Executing Cmd8 fails with %r\n", Status
));
952 // 3. Send SDIO Cmd5 to the device to the SDIO device OCR register.
954 Status
= SdioSendOpCond (PassThru
, Slot
, 0, FALSE
);
955 if (!EFI_ERROR (Status
)) {
956 DEBUG ((DEBUG_INFO
, "SdCardIdentification: Found SDIO device, ignore it as we don't support\n"));
957 return EFI_DEVICE_ERROR
;
960 // 4. Send Acmd41 with voltage window 0 to the device
962 Status
= SdCardSendOpCond (PassThru
, Slot
, 0, 0, FALSE
, FALSE
, FALSE
, &Ocr
);
963 if (EFI_ERROR (Status
)) {
964 DEBUG ((DEBUG_INFO
, "SdCardIdentification: Executing SdCardSendOpCond fails with %r\n", Status
));
965 return EFI_DEVICE_ERROR
;
968 if (Private
->Capability
[Slot
].Voltage33
!= 0) {
972 MaxCurrent
= ((UINT32
)Private
->MaxCurrent
[Slot
] & 0xFF) * 4;
973 } else if (Private
->Capability
[Slot
].Voltage30
!= 0) {
977 MaxCurrent
= (((UINT32
)Private
->MaxCurrent
[Slot
] >> 8) & 0xFF) * 4;
978 } else if (Private
->Capability
[Slot
].Voltage18
!= 0) {
982 MaxCurrent
= (((UINT32
)Private
->MaxCurrent
[Slot
] >> 16) & 0xFF) * 4;
985 return EFI_DEVICE_ERROR
;
988 if (MaxCurrent
>= 150) {
994 Status
= SdMmcHcRwMmio (PciIo
, Slot
, SD_MMC_HC_CTRL_VER
, TRUE
, sizeof (ControllerVer
), &ControllerVer
);
995 if (EFI_ERROR (Status
)) {
999 if (((ControllerVer
& 0xFF) >= SD_MMC_HC_CTRL_VER_300
) &&
1000 ((ControllerVer
& 0xFF) <= SD_MMC_HC_CTRL_VER_420
)) {
1002 } else if (((ControllerVer
& 0xFF) == SD_MMC_HC_CTRL_VER_100
) || ((ControllerVer
& 0xFF) == SD_MMC_HC_CTRL_VER_200
)) {
1006 return EFI_UNSUPPORTED
;
1009 // 5. Repeatly send Acmd41 with supply voltage window to the device.
1010 // Note here we only support the cards complied with SD physical
1011 // layer simplified spec version 2.0 and version 3.0 and above.
1016 Status
= SdCardSendOpCond (PassThru
, Slot
, 0, Ocr
, S18r
, Xpc
, TRUE
, &Ocr
);
1017 if (EFI_ERROR (Status
)) {
1018 DEBUG ((DEBUG_ERROR
, "SdCardIdentification: SdCardSendOpCond fails with %r Ocr %x, S18r %x, Xpc %x\n", Status
, Ocr
, S18r
, Xpc
));
1019 return EFI_DEVICE_ERROR
;
1022 if (Retry
++ == 100) {
1023 DEBUG ((DEBUG_ERROR
, "SdCardIdentification: SdCardSendOpCond fails too many times\n"));
1024 return EFI_DEVICE_ERROR
;
1026 gBS
->Stall(10 * 1000);
1027 } while ((Ocr
& BIT31
) == 0);
1030 // 6. If the S18A bit is set and the Host Controller supports 1.8V signaling
1031 // (One of support bits is set to 1: SDR50, SDR104 or DDR50 in the
1032 // Capabilities register), switch its voltage to 1.8V.
1034 if ((Private
->Capability
[Slot
].Sdr50
!= 0 ||
1035 Private
->Capability
[Slot
].Sdr104
!= 0 ||
1036 Private
->Capability
[Slot
].Ddr50
!= 0) &&
1037 ((Ocr
& BIT24
) != 0)) {
1038 Status
= SdCardVoltageSwitch (PassThru
, Slot
);
1039 if (EFI_ERROR (Status
)) {
1040 DEBUG ((DEBUG_ERROR
, "SdCardIdentification: Executing SdCardVoltageSwitch fails with %r\n", Status
));
1041 Status
= EFI_DEVICE_ERROR
;
1044 Status
= SdMmcHcStopClock (PciIo
, Slot
);
1045 if (EFI_ERROR (Status
)) {
1046 Status
= EFI_DEVICE_ERROR
;
1050 SdMmcHcRwMmio (PciIo
, Slot
, SD_MMC_HC_PRESENT_STATE
, TRUE
, sizeof (PresentState
), &PresentState
);
1051 if (((PresentState
>> 20) & 0xF) != 0) {
1052 DEBUG ((DEBUG_ERROR
, "SdCardIdentification: SwitchVoltage fails with PresentState = 0x%x\n", PresentState
));
1053 Status
= EFI_DEVICE_ERROR
;
1057 SdMmcHcOrMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
1061 SdMmcHcRwMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, TRUE
, sizeof (HostCtrl2
), &HostCtrl2
);
1062 if ((HostCtrl2
& BIT3
) == 0) {
1063 DEBUG ((DEBUG_ERROR
, "SdCardIdentification: SwitchVoltage fails with HostCtrl2 = 0x%x\n", HostCtrl2
));
1064 Status
= EFI_DEVICE_ERROR
;
1068 SdMmcHcInitClockFreq (PciIo
, Slot
, Private
->BaseClkFreq
[Slot
], Private
->ControllerVersion
[Slot
]);
1072 SdMmcHcRwMmio (PciIo
, Slot
, SD_MMC_HC_PRESENT_STATE
, TRUE
, sizeof (PresentState
), &PresentState
);
1073 if (((PresentState
>> 20) & 0xF) != 0xF) {
1074 DEBUG ((DEBUG_ERROR
, "SdCardIdentification: SwitchVoltage fails with PresentState = 0x%x, It should be 0xF\n", PresentState
));
1075 Status
= EFI_DEVICE_ERROR
;
1079 DEBUG ((DEBUG_INFO
, "SdCardIdentification: Switch to 1.8v signal voltage success\n"));
1082 Status
= SdCardAllSendCid (PassThru
, Slot
);
1083 if (EFI_ERROR (Status
)) {
1084 DEBUG ((DEBUG_ERROR
, "SdCardIdentification: Executing SdCardAllSendCid fails with %r\n", Status
));
1088 Status
= SdCardSetRca (PassThru
, Slot
, &Rca
);
1089 if (EFI_ERROR (Status
)) {
1090 DEBUG ((DEBUG_ERROR
, "SdCardIdentification: Executing SdCardSetRca fails with %r\n", Status
));
1094 // Enter Data Tranfer Mode.
1096 DEBUG ((DEBUG_INFO
, "SdCardIdentification: Found a SD device at slot [%d]\n", Slot
));
1097 Private
->Slot
[Slot
].CardType
= SdCardType
;
1099 Status
= SdCardSetBusMode (PciIo
, PassThru
, Slot
, Rca
, ((Ocr
& BIT24
) != 0));
1105 // Set SD Bus Power = 0
1107 PowerCtrl
= (UINT8
)~BIT0
;
1108 Status
= SdMmcHcAndMmio (PciIo
, Slot
, SD_MMC_HC_POWER_CTRL
, sizeof (PowerCtrl
), &PowerCtrl
);
1109 return EFI_DEVICE_ERROR
;