2 This file provides some helper functions which are specific for SD card device.
4 Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "SdMmcPciHcDxe.h"
18 Send command GO_IDLE_STATE to the device to make it go to Idle State.
20 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
22 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
23 @param[in] Slot The slot number of the SD card to send the command to.
25 @retval EFI_SUCCESS The SD device is reset correctly.
26 @retval Others The device reset fails.
31 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
35 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
36 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
37 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
40 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
41 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
42 ZeroMem (&Packet
, sizeof (Packet
));
44 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
45 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
46 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
48 SdMmcCmdBlk
.CommandIndex
= SD_GO_IDLE_STATE
;
49 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeBc
;
51 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
57 Send command SEND_IF_COND to the device to inquiry the SD Memory Card interface
60 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
62 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
63 @param[in] Slot The slot number of the SD card to send the command to.
64 @param[in] SupplyVoltage The supplied voltage by the host.
65 @param[in] CheckPattern The check pattern to be sent to the device.
67 @retval EFI_SUCCESS The operation is done correctly.
68 @retval Others The operation fails.
73 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
75 IN UINT8 SupplyVoltage
,
79 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
80 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
81 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
84 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
85 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
86 ZeroMem (&Packet
, sizeof (Packet
));
88 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
89 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
90 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
92 SdMmcCmdBlk
.CommandIndex
= SD_SEND_IF_COND
;
93 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeBcr
;
94 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR7
;
95 SdMmcCmdBlk
.CommandArgument
= (SupplyVoltage
<< 8) | CheckPattern
;
97 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
99 if (!EFI_ERROR (Status
)) {
100 if (SdMmcStatusBlk
.Resp0
!= SdMmcCmdBlk
.CommandArgument
) {
101 return EFI_DEVICE_ERROR
;
109 Send command SDIO_SEND_OP_COND to the device to see whether it is SDIO device.
111 Refer to SDIO Simplified Spec 3 Section 3.2 for details.
113 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
114 @param[in] Slot The slot number of the SD card to send the command to.
115 @param[in] VoltageWindow The supply voltage window.
116 @param[in] S18R The boolean to show if it should switch to 1.8v.
118 @retval EFI_SUCCESS The operation is done correctly.
119 @retval Others The operation fails.
124 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
126 IN UINT32 VoltageWindow
,
130 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
131 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
132 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
136 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
137 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
138 ZeroMem (&Packet
, sizeof (Packet
));
140 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
141 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
142 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
144 SdMmcCmdBlk
.CommandIndex
= SDIO_SEND_OP_COND
;
145 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeBcr
;
146 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR4
;
148 Switch
= S18R
? BIT24
: 0;
150 SdMmcCmdBlk
.CommandArgument
= (VoltageWindow
& 0xFFFFFF) | Switch
;
152 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
158 Send command SD_SEND_OP_COND to the device to see whether it is SDIO device.
160 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
162 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
163 @param[in] Slot The slot number of the SD card to send the command to.
164 @param[in] Rca The relative device address of addressed device.
165 @param[in] VoltageWindow The supply voltage window.
166 @param[in] S18R The boolean to show if it should switch to 1.8v.
167 @param[in] Xpc The boolean to show if it should provide 0.36w power control.
168 @param[in] Hcs The boolean to show if it support host capacity info.
169 @param[out] Ocr The buffer to store returned OCR register value.
171 @retval EFI_SUCCESS The operation is done correctly.
172 @retval Others The operation fails.
177 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
180 IN UINT32 VoltageWindow
,
187 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
188 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
189 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
195 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
196 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
197 ZeroMem (&Packet
, sizeof (Packet
));
199 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
200 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
201 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
203 SdMmcCmdBlk
.CommandIndex
= SD_APP_CMD
;
204 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
205 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
206 SdMmcCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
208 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
209 if (EFI_ERROR (Status
)) {
213 SdMmcCmdBlk
.CommandIndex
= SD_SEND_OP_COND
;
214 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeBcr
;
215 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR3
;
217 Switch
= S18R
? BIT24
: 0;
218 MaxPower
= Xpc
? BIT28
: 0;
219 HostCapacity
= Hcs
? BIT30
: 0;
221 SdMmcCmdBlk
.CommandArgument
= (VoltageWindow
& 0xFFFFFF) | Switch
| MaxPower
| HostCapacity
;
223 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
224 if (!EFI_ERROR (Status
)) {
226 // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12.
228 *Ocr
= SdMmcStatusBlk
.Resp0
;
235 Broadcast command ALL_SEND_CID to the bus to ask all the SD devices to send the
236 data of their CID registers.
238 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
240 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
241 @param[in] Slot The slot number of the SD card to send the command to.
243 @retval EFI_SUCCESS The operation is done correctly.
244 @retval Others The operation fails.
249 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
253 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
254 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
255 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
258 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
259 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
260 ZeroMem (&Packet
, sizeof (Packet
));
262 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
263 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
264 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
266 SdMmcCmdBlk
.CommandIndex
= SD_ALL_SEND_CID
;
267 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeBcr
;
268 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR2
;
270 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
276 Send command SET_RELATIVE_ADDR to the SD device to assign a Relative device
279 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
281 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
282 @param[in] Slot The slot number of the SD card to send the command to.
283 @param[out] Rca The relative device address to assign.
285 @retval EFI_SUCCESS The operation is done correctly.
286 @retval Others The operation fails.
291 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
296 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
297 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
298 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
301 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
302 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
303 ZeroMem (&Packet
, sizeof (Packet
));
305 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
306 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
307 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
309 SdMmcCmdBlk
.CommandIndex
= SD_SET_RELATIVE_ADDR
;
310 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeBcr
;
311 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR6
;
313 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
314 if (!EFI_ERROR (Status
)) {
315 *Rca
= (UINT16
)(SdMmcStatusBlk
.Resp0
>> 16);
326 Send command SELECT_DESELECT_CARD to the SD device to select/deselect it.
328 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
330 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
331 @param[in] Slot The slot number of the SD card to send the command to.
332 @param[in] Rca The relative device address of selected device.
334 @retval EFI_SUCCESS The operation is done correctly.
335 @retval Others The operation fails.
340 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
345 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
346 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
347 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
350 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
351 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
352 ZeroMem (&Packet
, sizeof (Packet
));
354 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
355 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
356 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
358 SdMmcCmdBlk
.CommandIndex
= SD_SELECT_DESELECT_CARD
;
359 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
361 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1b
;
363 SdMmcCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
365 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
371 Send command VOLTAGE_SWITCH to the SD device to switch the voltage of the device.
373 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
375 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
376 @param[in] Slot The slot number of the SD card to send the command to.
378 @retval EFI_SUCCESS The operation is done correctly.
379 @retval Others The operation fails.
383 SdCardVoltageSwitch (
384 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
388 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
389 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
390 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
393 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
394 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
395 ZeroMem (&Packet
, sizeof (Packet
));
397 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
398 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
399 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
401 SdMmcCmdBlk
.CommandIndex
= SD_VOLTAGE_SWITCH
;
402 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
403 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
404 SdMmcCmdBlk
.CommandArgument
= 0;
406 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
412 Send command SET_BUS_WIDTH to the SD device to set the bus width.
414 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
416 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
417 @param[in] Slot The slot number of the SD card to send the command to.
418 @param[in] Rca The relative device address of addressed device.
419 @param[in] BusWidth The bus width to be set, it could be 1 or 4.
421 @retval EFI_SUCCESS The operation is done correctly.
422 @retval Others The operation fails.
427 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
433 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
434 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
435 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
439 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
440 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
441 ZeroMem (&Packet
, sizeof (Packet
));
443 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
444 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
445 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
447 SdMmcCmdBlk
.CommandIndex
= SD_APP_CMD
;
448 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
449 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
450 SdMmcCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
452 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
453 if (EFI_ERROR (Status
)) {
457 SdMmcCmdBlk
.CommandIndex
= SD_SET_BUS_WIDTH
;
458 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
459 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
463 } else if (BusWidth
== 4) {
466 return EFI_INVALID_PARAMETER
;
469 SdMmcCmdBlk
.CommandArgument
= Value
& 0x3;
471 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
476 Send command SWITCH_FUNC to the SD device to check switchable function or switch card function.
478 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
480 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
481 @param[in] Slot The slot number of the SD card to send the command to.
482 @param[in] AccessMode The value for access mode group.
483 @param[in] CommandSystem The value for command set group.
484 @param[in] DriveStrength The value for drive length group.
485 @param[in] PowerLimit The value for power limit group.
486 @param[in] Mode Switch or check function.
487 @param[out] SwitchResp The return switch function status.
489 @retval EFI_SUCCESS The operation is done correctly.
490 @retval Others The operation fails.
495 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
498 IN UINT8 CommandSystem
,
499 IN UINT8 DriveStrength
,
502 OUT UINT8
*SwitchResp
505 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
506 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
507 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
511 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
512 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
513 ZeroMem (&Packet
, sizeof (Packet
));
515 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
516 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
517 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
519 SdMmcCmdBlk
.CommandIndex
= SD_SWITCH_FUNC
;
520 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAdtc
;
521 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
523 ModeValue
= Mode
? BIT31
: 0;
524 SdMmcCmdBlk
.CommandArgument
= (AccessMode
& 0xF) | ((PowerLimit
& 0xF) << 4) | \
525 ((DriveStrength
& 0xF) << 8) | ((DriveStrength
& 0xF) << 12) | \
528 Packet
.InDataBuffer
= SwitchResp
;
529 Packet
.InTransferLength
= 64;
531 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
537 Send command SEND_STATUS to the addressed SD device to get its status register.
539 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
541 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
542 @param[in] Slot The slot number of the SD card to send the command to.
543 @param[in] Rca The relative device address of addressed device.
544 @param[out] DevStatus The returned device status.
546 @retval EFI_SUCCESS The operation is done correctly.
547 @retval Others The operation fails.
552 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
555 OUT UINT32
*DevStatus
558 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
559 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
560 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
563 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
564 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
565 ZeroMem (&Packet
, sizeof (Packet
));
567 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
568 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
569 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
571 SdMmcCmdBlk
.CommandIndex
= SD_SEND_STATUS
;
572 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
573 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
574 SdMmcCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
576 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
577 if (!EFI_ERROR (Status
)) {
578 *DevStatus
= SdMmcStatusBlk
.Resp0
;
585 Send command SEND_TUNING_BLOCK to the SD device for HS200 optimal sampling point
588 It may be sent up to 40 times until the host finishes the tuning procedure.
590 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
592 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
593 @param[in] Slot The slot number of the SD card to send the command to.
595 @retval EFI_SUCCESS The operation is done correctly.
596 @retval Others The operation fails.
600 SdCardSendTuningBlk (
601 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
605 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
606 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
607 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
609 UINT8 TuningBlock
[64];
611 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
612 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
613 ZeroMem (&Packet
, sizeof (Packet
));
615 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
616 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
617 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
619 SdMmcCmdBlk
.CommandIndex
= SD_SEND_TUNING_BLOCK
;
620 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAdtc
;
621 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
622 SdMmcCmdBlk
.CommandArgument
= 0;
624 Packet
.InDataBuffer
= TuningBlock
;
625 Packet
.InTransferLength
= sizeof (TuningBlock
);
627 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
633 Tunning the sampling point of SDR104 or SDR50 bus speed mode.
635 Command SD_SEND_TUNING_BLOCK may be sent up to 40 times until the host finishes the
638 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and
639 SD Host Controller Simplified Spec 3.0 section Figure 3-7 for details.
641 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
642 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
643 @param[in] Slot The slot number of the SD card to send the command to.
645 @retval EFI_SUCCESS The operation is done correctly.
646 @retval Others The operation fails.
651 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
652 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
661 // Notify the host that the sampling clock tuning procedure starts.
664 Status
= SdMmcHcOrMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
665 if (EFI_ERROR (Status
)) {
669 // Ask the device to send a sequence of tuning blocks till the tuning procedure is done.
673 Status
= SdCardSendTuningBlk (PassThru
, Slot
);
674 if (EFI_ERROR (Status
)) {
675 DEBUG ((DEBUG_ERROR
, "SdCardSendTuningBlk: Send tuning block fails with %r\n", Status
));
679 Status
= SdMmcHcRwMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, TRUE
, sizeof (HostCtrl2
), &HostCtrl2
);
680 if (EFI_ERROR (Status
)) {
684 if ((HostCtrl2
& (BIT6
| BIT7
)) == 0) {
687 if ((HostCtrl2
& (BIT6
| BIT7
)) == BIT7
) {
690 } while (++Retry
< 40);
692 DEBUG ((DEBUG_ERROR
, "SdCardTuningClock: Send tuning block fails at %d times with HostCtrl2 %02x\n", Retry
, HostCtrl2
));
694 // Abort the tuning procedure and reset the tuning circuit.
696 HostCtrl2
= (UINT8
)~(BIT6
| BIT7
);
697 Status
= SdMmcHcAndMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
698 if (EFI_ERROR (Status
)) {
701 return EFI_DEVICE_ERROR
;
705 Switch the bus width to specified width.
707 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and
708 SD Host Controller Simplified Spec 3.0 section Figure 3-7 for details.
710 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
711 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
712 @param[in] Slot The slot number of the SD card to send the command to.
713 @param[in] Rca The relative device address to be assigned.
714 @param[in] BusWidth The bus width to be set, it could be 4 or 8.
716 @retval EFI_SUCCESS The operation is done correctly.
717 @retval Others The operation fails.
721 SdCardSwitchBusWidth (
722 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
723 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
732 Status
= SdCardSetBusWidth (PassThru
, Slot
, Rca
, BusWidth
);
733 if (EFI_ERROR (Status
)) {
734 DEBUG ((DEBUG_ERROR
, "SdCardSwitchBusWidth: Switch to bus width %d fails with %r\n", BusWidth
, Status
));
738 Status
= SdCardSendStatus (PassThru
, Slot
, Rca
, &DevStatus
);
739 if (EFI_ERROR (Status
)) {
740 DEBUG ((DEBUG_ERROR
, "SdCardSwitchBusWidth: Send status fails with %r\n", Status
));
744 // Check the switch operation is really successful or not.
746 if ((DevStatus
>> 16) != 0) {
747 DEBUG ((DEBUG_ERROR
, "SdCardSwitchBusWidth: The switch operation fails as DevStatus is 0x%08x\n", DevStatus
));
748 return EFI_DEVICE_ERROR
;
751 Status
= SdMmcHcSetBusWidth (PciIo
, Slot
, BusWidth
);
757 Switch the high speed timing according to request.
759 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and
760 SD Host Controller Simplified Spec 3.0 section Figure 2-29 for details.
762 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
763 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
764 @param[in] Slot The slot number of the SD card to send the command to.
765 @param[in] Rca The relative device address to be assigned.
766 @param[in] S18A The boolean to show if it's a UHS-I SD card.
768 @retval EFI_SUCCESS The operation is done correctly.
769 @retval Others The operation fails.
774 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
775 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
782 SD_MMC_HC_SLOT_CAP
*Capability
;
788 UINT8 SwitchResp
[64];
789 SD_MMC_HC_PRIVATE_DATA
*Private
;
791 Private
= SD_MMC_HC_PRIVATE_FROM_THIS (PassThru
);
793 Capability
= &Private
->Capability
[Slot
];
795 Status
= SdCardSelect (PassThru
, Slot
, Rca
);
796 if (EFI_ERROR (Status
)) {
802 Status
= SdCardSwitchBusWidth (PciIo
, PassThru
, Slot
, Rca
, BusWidth
);
803 if (EFI_ERROR (Status
)) {
807 // Get the supported bus speed from SWITCH cmd return data group #1.
809 Status
= SdCardSwitch (PassThru
, Slot
, 0xF, 0xF, 0xF, 0xF, FALSE
, SwitchResp
);
810 if (EFI_ERROR (Status
)) {
814 // Calculate supported bus speed/bus width/clock frequency by host and device capability.
817 if (S18A
&& (Capability
->Sdr104
!= 0) && ((SwitchResp
[13] & BIT3
) != 0)) {
820 } else if (S18A
&& (Capability
->Sdr50
!= 0) && ((SwitchResp
[13] & BIT2
) != 0)) {
823 } else if (S18A
&& (Capability
->Ddr50
!= 0) && ((SwitchResp
[13] & BIT4
) != 0)) {
826 } else if ((SwitchResp
[13] & BIT1
) != 0) {
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 HostCtrl2
= (UINT8
)~0x7;
858 Status
= SdMmcHcAndMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
859 if (EFI_ERROR (Status
)) {
862 HostCtrl2
= AccessMode
;
863 Status
= SdMmcHcOrMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
864 if (EFI_ERROR (Status
)) {
868 Status
= SdMmcHcClockSupply (PciIo
, Slot
, ClockFreq
* 1000, *Capability
);
869 if (EFI_ERROR (Status
)) {
873 if ((AccessMode
== 3) || ((AccessMode
== 2) && (Capability
->TuningSDR50
!= 0))) {
874 Status
= SdCardTuningClock (PciIo
, PassThru
, Slot
);
875 if (EFI_ERROR (Status
)) {
884 Execute SD device identification procedure.
886 Refer to SD Physical Layer Simplified Spec 4.1 Section 3.6 for details.
888 @param[in] Private A pointer to the SD_MMC_HC_PRIVATE_DATA instance.
889 @param[in] Slot The slot number of the SD card to send the command to.
891 @retval EFI_SUCCESS There is a SD card.
892 @retval Others There is not a SD card.
896 SdCardIdentification (
897 IN SD_MMC_HC_PRIVATE_DATA
*Private
,
902 EFI_PCI_IO_PROTOCOL
*PciIo
;
903 EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
;
909 UINT16 ControllerVer
;
915 PciIo
= Private
->PciIo
;
916 PassThru
= &Private
->PassThru
;
918 // 1. Send Cmd0 to the device
920 Status
= SdCardReset (PassThru
, Slot
);
921 if (EFI_ERROR (Status
)) {
922 DEBUG ((DEBUG_INFO
, "SdCardIdentification: Executing Cmd0 fails with %r\n", Status
));
926 // 2. Send Cmd8 to the device
928 Status
= SdCardVoltageCheck (PassThru
, Slot
, 0x1, 0xFF);
929 if (EFI_ERROR (Status
)) {
930 DEBUG ((DEBUG_INFO
, "SdCardIdentification: Executing Cmd8 fails with %r\n", Status
));
934 // 3. Send SDIO Cmd5 to the device to the SDIO device OCR register.
936 Status
= SdioSendOpCond (PassThru
, Slot
, 0, FALSE
);
937 if (!EFI_ERROR (Status
)) {
938 DEBUG ((DEBUG_INFO
, "SdCardIdentification: Found SDIO device, ignore it as we don't support\n"));
939 return EFI_DEVICE_ERROR
;
942 // 4. Send Acmd41 with voltage window 0 to the device
944 Status
= SdCardSendOpCond (PassThru
, Slot
, 0, 0, FALSE
, FALSE
, FALSE
, &Ocr
);
945 if (EFI_ERROR (Status
)) {
946 DEBUG ((DEBUG_INFO
, "SdCardIdentification: Executing SdCardSendOpCond fails with %r\n", Status
));
947 return EFI_DEVICE_ERROR
;
950 if (Private
->Capability
[Slot
].Voltage33
!= 0) {
954 MaxCurrent
= ((UINT32
)Private
->MaxCurrent
[Slot
] & 0xFF) * 4;
955 } else if (Private
->Capability
[Slot
].Voltage30
!= 0) {
959 MaxCurrent
= (((UINT32
)Private
->MaxCurrent
[Slot
] >> 8) & 0xFF) * 4;
960 } else if (Private
->Capability
[Slot
].Voltage18
!= 0) {
964 MaxCurrent
= (((UINT32
)Private
->MaxCurrent
[Slot
] >> 16) & 0xFF) * 4;
967 return EFI_DEVICE_ERROR
;
970 if (MaxCurrent
>= 150) {
976 Status
= SdMmcHcRwMmio (PciIo
, Slot
, SD_MMC_HC_CTRL_VER
, TRUE
, sizeof (ControllerVer
), &ControllerVer
);
977 if (EFI_ERROR (Status
)) {
981 if ((ControllerVer
& 0xFF) == 2) {
983 } else if (((ControllerVer
& 0xFF) == 0) || ((ControllerVer
& 0xFF) == 1)) {
987 return EFI_UNSUPPORTED
;
990 // 5. Repeatly send Acmd41 with supply voltage window to the device.
991 // Note here we only support the cards complied with SD physical
992 // layer simplified spec version 2.0 and version 3.0 and above.
997 Status
= SdCardSendOpCond (PassThru
, Slot
, 0, Ocr
, S18r
, Xpc
, TRUE
, &Ocr
);
998 if (EFI_ERROR (Status
)) {
999 DEBUG ((DEBUG_ERROR
, "SdCardIdentification: SdCardSendOpCond fails with %r Ocr %x, S18r %x, Xpc %x\n", Status
, Ocr
, S18r
, Xpc
));
1000 return EFI_DEVICE_ERROR
;
1003 if (Retry
++ == 100) {
1004 DEBUG ((DEBUG_ERROR
, "SdCardIdentification: SdCardSendOpCond fails too many times\n"));
1005 return EFI_DEVICE_ERROR
;
1007 gBS
->Stall(10 * 1000);
1008 } while ((Ocr
& BIT31
) == 0);
1011 // 6. If the S18A bit is set and the Host Controller supports 1.8V signaling
1012 // (One of support bits is set to 1: SDR50, SDR104 or DDR50 in the
1013 // Capabilities register), switch its voltage to 1.8V.
1015 if ((Private
->Capability
[Slot
].Sdr50
!= 0 ||
1016 Private
->Capability
[Slot
].Sdr104
!= 0 ||
1017 Private
->Capability
[Slot
].Ddr50
!= 0) &&
1018 ((Ocr
& BIT24
) != 0)) {
1019 Status
= SdCardVoltageSwitch (PassThru
, Slot
);
1020 if (EFI_ERROR (Status
)) {
1021 DEBUG ((DEBUG_ERROR
, "SdCardIdentification: Executing SdCardVoltageSwitch fails with %r\n", Status
));
1022 Status
= EFI_DEVICE_ERROR
;
1025 Status
= SdMmcHcStopClock (PciIo
, Slot
);
1026 if (EFI_ERROR (Status
)) {
1027 Status
= EFI_DEVICE_ERROR
;
1031 SdMmcHcRwMmio (PciIo
, Slot
, SD_MMC_HC_PRESENT_STATE
, TRUE
, sizeof (PresentState
), &PresentState
);
1032 if (((PresentState
>> 20) & 0xF) != 0) {
1033 DEBUG ((DEBUG_ERROR
, "SdCardIdentification: SwitchVoltage fails with PresentState = 0x%x\n", PresentState
));
1034 Status
= EFI_DEVICE_ERROR
;
1038 SdMmcHcOrMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
1042 SdMmcHcRwMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, TRUE
, sizeof (HostCtrl2
), &HostCtrl2
);
1043 if ((HostCtrl2
& BIT3
) == 0) {
1044 DEBUG ((DEBUG_ERROR
, "SdCardIdentification: SwitchVoltage fails with HostCtrl2 = 0x%x\n", HostCtrl2
));
1045 Status
= EFI_DEVICE_ERROR
;
1049 SdMmcHcInitClockFreq (PciIo
, Slot
, Private
->Capability
[Slot
]);
1053 SdMmcHcRwMmio (PciIo
, Slot
, SD_MMC_HC_PRESENT_STATE
, TRUE
, sizeof (PresentState
), &PresentState
);
1054 if (((PresentState
>> 20) & 0xF) != 0xF) {
1055 DEBUG ((DEBUG_ERROR
, "SdCardIdentification: SwitchVoltage fails with PresentState = 0x%x, It should be 0xF\n", PresentState
));
1056 Status
= EFI_DEVICE_ERROR
;
1060 DEBUG ((DEBUG_INFO
, "SdCardIdentification: Switch to 1.8v signal voltage success\n"));
1063 Status
= SdCardAllSendCid (PassThru
, Slot
);
1064 if (EFI_ERROR (Status
)) {
1065 DEBUG ((DEBUG_ERROR
, "SdCardIdentification: Executing SdCardAllSendCid fails with %r\n", Status
));
1069 Status
= SdCardSetRca (PassThru
, Slot
, &Rca
);
1070 if (EFI_ERROR (Status
)) {
1071 DEBUG ((DEBUG_ERROR
, "SdCardIdentification: Executing SdCardSetRca fails with %r\n", Status
));
1075 // Enter Data Tranfer Mode.
1077 DEBUG ((DEBUG_INFO
, "SdCardIdentification: Found a SD device at slot [%d]\n", Slot
));
1078 Private
->Slot
[Slot
].CardType
= SdCardType
;
1080 Status
= SdCardSetBusMode (PciIo
, PassThru
, Slot
, Rca
, ((Ocr
& BIT24
) != 0));
1086 // Set SD Bus Power = 0
1088 PowerCtrl
= (UINT8
)~BIT0
;
1089 Status
= SdMmcHcAndMmio (PciIo
, Slot
, SD_MMC_HC_POWER_CTRL
, sizeof (PowerCtrl
), &PowerCtrl
);
1090 return EFI_DEVICE_ERROR
;