2 This file provides some helper functions which are specific for SD card device.
4 Copyright (c) 2015, 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);
322 Send command SEND_CSD to the SD device to get the data of the CSD register.
324 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
326 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
327 @param[in] Slot The slot number of the SD card to send the command to.
328 @param[in] Rca The relative device address of selected device.
329 @param[out] Csd The buffer to store the content of the CSD register.
330 Note the caller should ignore the lowest byte of this
331 buffer as the content of this byte is meaningless even
332 if the operation succeeds.
334 @retval EFI_SUCCESS The operation is done correctly.
335 @retval Others The operation fails.
340 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_SEND_CSD
;
360 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
361 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR2
;
362 SdMmcCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
364 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
365 if (!EFI_ERROR (Status
)) {
367 // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12.
369 CopyMem (((UINT8
*)Csd
) + 1, &SdMmcStatusBlk
.Resp0
, sizeof (SD_CSD
) - 1);
376 Send command SEND_CSD to the SD device to get the data of the CSD register.
378 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
380 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
381 @param[in] Slot The slot number of the SD card to send the command to.
382 @param[in] Rca The relative device address of selected device.
383 @param[out] Scr The buffer to store the content of the SCR register.
385 @retval EFI_SUCCESS The operation is done correctly.
386 @retval Others The operation fails.
391 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
397 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
398 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
399 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
402 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
403 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
404 ZeroMem (&Packet
, sizeof (Packet
));
406 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
407 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
408 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
410 SdMmcCmdBlk
.CommandIndex
= SD_APP_CMD
;
411 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
412 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
413 SdMmcCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
415 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
416 if (EFI_ERROR (Status
)) {
420 SdMmcCmdBlk
.CommandIndex
= SD_SEND_SCR
;
421 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAdtc
;
422 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
424 Packet
.InDataBuffer
= Scr
;
425 Packet
.InTransferLength
= sizeof (SD_SCR
);
427 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
433 Send command SELECT_DESELECT_CARD to the SD device to select/deselect it.
435 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
437 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
438 @param[in] Slot The slot number of the SD card to send the command to.
439 @param[in] Rca The relative device address of selected device.
441 @retval EFI_SUCCESS The operation is done correctly.
442 @retval Others The operation fails.
447 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
452 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
453 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
454 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
457 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
458 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
459 ZeroMem (&Packet
, sizeof (Packet
));
461 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
462 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
463 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
465 SdMmcCmdBlk
.CommandIndex
= SD_SELECT_DESELECT_CARD
;
466 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
467 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1b
;
468 SdMmcCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
470 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
476 Send command VOLTAGE_SWITCH to the SD device to switch the voltage of the device.
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.
483 @retval EFI_SUCCESS The operation is done correctly.
484 @retval Others The operation fails.
488 SdCardVoltageSwitch (
489 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
493 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
494 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
495 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
498 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
499 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
500 ZeroMem (&Packet
, sizeof (Packet
));
502 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
503 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
504 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
506 SdMmcCmdBlk
.CommandIndex
= SD_VOLTAGE_SWITCH
;
507 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
508 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
509 SdMmcCmdBlk
.CommandArgument
= 0;
511 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
517 Send command SET_BUS_WIDTH to the SD device to set the bus width.
519 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
521 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
522 @param[in] Slot The slot number of the SD card to send the command to.
523 @param[in] Rca The relative device address of addressed device.
524 @param[in] BusWidth The bus width to be set, it could be 1 or 4.
526 @retval EFI_SUCCESS The operation is done correctly.
527 @retval Others The operation fails.
532 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
538 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
539 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
540 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
544 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
545 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
546 ZeroMem (&Packet
, sizeof (Packet
));
548 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
549 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
550 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
552 SdMmcCmdBlk
.CommandIndex
= SD_APP_CMD
;
553 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
554 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
555 SdMmcCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
557 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
558 if (EFI_ERROR (Status
)) {
562 SdMmcCmdBlk
.CommandIndex
= SD_SET_BUS_WIDTH
;
563 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
564 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
568 } else if (BusWidth
== 4) {
571 return EFI_INVALID_PARAMETER
;
574 SdMmcCmdBlk
.CommandArgument
= Value
& 0x3;
576 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
581 Send command SWITCH_FUNC to the SD device to check switchable function or switch card function.
583 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
585 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
586 @param[in] Slot The slot number of the SD card to send the command to.
587 @param[in] AccessMode The value for access mode group.
588 @param[in] CommandSystem The value for command set group.
589 @param[in] DriveStrength The value for drive length group.
590 @param[in] PowerLimit The value for power limit group.
591 @param[in] Mode Switch or check function.
593 @retval EFI_SUCCESS The operation is done correctly.
594 @retval Others The operation fails.
599 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
602 IN UINT8 CommandSystem
,
603 IN UINT8 DriveStrength
,
608 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
609 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
610 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
615 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
616 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
617 ZeroMem (&Packet
, sizeof (Packet
));
619 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
620 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
621 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
623 SdMmcCmdBlk
.CommandIndex
= SD_SWITCH_FUNC
;
624 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAdtc
;
625 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
627 ModeValue
= Mode
? BIT31
: 0;
628 SdMmcCmdBlk
.CommandArgument
= (AccessMode
& 0xF) | ((PowerLimit
& 0xF) << 4) | \
629 ((DriveStrength
& 0xF) << 8) | ((DriveStrength
& 0xF) << 12) | \
632 Packet
.InDataBuffer
= Data
;
633 Packet
.InTransferLength
= sizeof (Data
);
635 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
641 Send command SEND_STATUS to the addressed SD device to get its status register.
643 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
645 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
646 @param[in] Slot The slot number of the SD card to send the command to.
647 @param[in] Rca The relative device address of addressed device.
648 @param[out] DevStatus The returned device status.
650 @retval EFI_SUCCESS The operation is done correctly.
651 @retval Others The operation fails.
656 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
659 OUT UINT32
*DevStatus
662 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
663 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
664 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
667 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
668 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
669 ZeroMem (&Packet
, sizeof (Packet
));
671 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
672 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
673 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
675 SdMmcCmdBlk
.CommandIndex
= SD_SEND_STATUS
;
676 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
677 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
678 SdMmcCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
680 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
681 if (!EFI_ERROR (Status
)) {
682 *DevStatus
= SdMmcStatusBlk
.Resp0
;
689 Send command SEND_TUNING_BLOCK to the SD device for HS200 optimal sampling point
692 It may be sent up to 40 times until the host finishes the tuning procedure.
694 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
696 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
697 @param[in] Slot The slot number of the SD card to send the command to.
699 @retval EFI_SUCCESS The operation is done correctly.
700 @retval Others The operation fails.
704 SdCardSendTuningBlk (
705 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
709 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
710 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
711 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
713 UINT8 TuningBlock
[64];
715 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
716 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
717 ZeroMem (&Packet
, sizeof (Packet
));
719 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
720 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
721 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
723 SdMmcCmdBlk
.CommandIndex
= SD_SEND_TUNING_BLOCK
;
724 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAdtc
;
725 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
726 SdMmcCmdBlk
.CommandArgument
= 0;
728 Packet
.InDataBuffer
= TuningBlock
;
729 Packet
.InTransferLength
= sizeof (TuningBlock
);
731 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
737 Tunning the sampling point of SDR104 or SDR50 bus speed mode.
739 Command SD_SEND_TUNING_BLOCK may be sent up to 40 times until the host finishes the
742 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and
743 SD Host Controller Simplified Spec 3.0 section Figure 3-7 for details.
745 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
746 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
747 @param[in] Slot The slot number of the SD card to send the command to.
749 @retval EFI_SUCCESS The operation is done correctly.
750 @retval Others The operation fails.
755 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
756 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
765 // Notify the host that the sampling clock tuning procedure starts.
768 Status
= SdMmcHcOrMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
769 if (EFI_ERROR (Status
)) {
773 // Ask the device to send a sequence of tuning blocks till the tuning procedure is done.
777 Status
= SdCardSendTuningBlk (PassThru
, Slot
);
778 if (EFI_ERROR (Status
)) {
779 DEBUG ((EFI_D_ERROR
, "SdCardSendTuningBlk: Send tuning block fails with %r\n", Status
));
783 Status
= SdMmcHcRwMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, TRUE
, sizeof (HostCtrl2
), &HostCtrl2
);
784 if (EFI_ERROR (Status
)) {
788 if ((HostCtrl2
& (BIT6
| BIT7
)) == BIT7
) {
791 } while (++Retry
< 40);
794 Status
= EFI_TIMEOUT
;
795 DEBUG ((EFI_D_ERROR
, "SdCardTuningClock: Send tuning block exceeds 40 times\n"));
802 Switch the bus width to specified width.
804 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and
805 SD Host Controller Simplified Spec 3.0 section Figure 3-7 for details.
807 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
808 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
809 @param[in] Slot The slot number of the SD card to send the command to.
810 @param[in] Rca The relative device address to be assigned.
811 @param[in] BusWidth The bus width to be set, it could be 4 or 8.
813 @retval EFI_SUCCESS The operation is done correctly.
814 @retval Others The operation fails.
818 SdCardSwitchBusWidth (
819 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
820 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
829 Status
= SdCardSetBusWidth (PassThru
, Slot
, Rca
, BusWidth
);
830 if (EFI_ERROR (Status
)) {
831 DEBUG ((EFI_D_ERROR
, "SdCardSwitchBusWidth: Switch to bus width %d fails with %r\n", BusWidth
, Status
));
835 Status
= SdCardSendStatus (PassThru
, Slot
, Rca
, &DevStatus
);
836 if (EFI_ERROR (Status
)) {
837 DEBUG ((EFI_D_ERROR
, "SdCardSwitchBusWidth: Send status fails with %r\n", Status
));
841 // Check the switch operation is really successful or not.
843 if ((DevStatus
>> 16) != 0) {
844 DEBUG ((EFI_D_ERROR
, "SdCardSwitchBusWidth: The switch operation fails as DevStatus is 0x%08x\n", DevStatus
));
845 return EFI_DEVICE_ERROR
;
848 Status
= SdMmcHcSetBusWidth (PciIo
, Slot
, BusWidth
);
854 Switch the high speed timing according to request.
856 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and
857 SD Host Controller Simplified Spec 3.0 section Figure 2-29 for details.
859 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
860 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
861 @param[in] Slot The slot number of the SD card to send the command to.
862 @param[in] Rca The relative device address to be assigned.
863 @param[in] S18A The boolean to show if it's a UHS-I SD card.
865 @retval EFI_SUCCESS The operation is done correctly.
866 @retval Others The operation fails.
871 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
872 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
879 SD_MMC_HC_SLOT_CAP
*Capability
;
885 SD_MMC_HC_PRIVATE_DATA
*Private
;
887 Private
= SD_MMC_HC_PRIVATE_FROM_THIS (PassThru
);
889 Capability
= &Private
->Capability
[Slot
];
891 Status
= SdCardSelect (PassThru
, Slot
, Rca
);
892 if (EFI_ERROR (Status
)) {
898 Status
= SdCardSwitchBusWidth (PciIo
, PassThru
, Slot
, Rca
, BusWidth
);
899 if (EFI_ERROR (Status
)) {
904 // Calculate supported bus speed/bus width/clock frequency.
907 if (S18A
&& (Capability
->Sdr104
!= 0)) {
910 } else if (S18A
&& (Capability
->Sdr50
!= 0)) {
913 } else if (S18A
&& (Capability
->Ddr50
!= 0)) {
921 DEBUG ((EFI_D_INFO
, "SdCardSetBusMode: AccessMode %d ClockFreq %d BusWidth %d\n", AccessMode
, ClockFreq
, BusWidth
));
923 Status
= SdCardSwitch (PassThru
, Slot
, AccessMode
, 0, 0, 0, TRUE
);
924 if (EFI_ERROR (Status
)) {
929 // Set to Hight Speed timing
931 if (AccessMode
== 1) {
933 Status
= SdMmcHcOrMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
934 if (EFI_ERROR (Status
)) {
939 HostCtrl2
= (UINT8
)~0x7;
940 Status
= SdMmcHcAndMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
941 if (EFI_ERROR (Status
)) {
944 HostCtrl2
= AccessMode
;
945 Status
= SdMmcHcOrMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
946 if (EFI_ERROR (Status
)) {
950 Status
= SdMmcHcClockSupply (PciIo
, Slot
, ClockFreq
* 1000, *Capability
);
951 if (EFI_ERROR (Status
)) {
955 if ((AccessMode
== 3) || ((AccessMode
== 2) && (Capability
->TuningSDR50
!= 0))) {
956 Status
= SdCardTuningClock (PciIo
, PassThru
, Slot
);
957 if (EFI_ERROR (Status
)) {
966 Execute SD device identification procedure.
968 Refer to SD Physical Layer Simplified Spec 4.1 Section 3.6 for details.
970 @param[in] Private A pointer to the SD_MMC_HC_PRIVATE_DATA instance.
971 @param[in] Slot The slot number of the SD card to send the command to.
973 @retval EFI_SUCCESS There is a SD card.
974 @retval Others There is not a SD card.
978 SdCardIdentification (
979 IN SD_MMC_HC_PRIVATE_DATA
*Private
,
984 EFI_PCI_IO_PROTOCOL
*PciIo
;
985 EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
;
991 UINT16 ControllerVer
;
996 PciIo
= Private
->PciIo
;
997 PassThru
= &Private
->PassThru
;
999 // 1. Send Cmd0 to the device
1001 Status
= SdCardReset (PassThru
, Slot
);
1002 if (EFI_ERROR (Status
)) {
1003 DEBUG ((EFI_D_INFO
, "SdCardIdentification: Executing Cmd0 fails with %r\n", Status
));
1007 // 2. Send Cmd8 to the device
1009 Status
= SdCardVoltageCheck (PassThru
, Slot
, 0x1, 0xFF);
1010 if (EFI_ERROR (Status
)) {
1011 DEBUG ((EFI_D_INFO
, "SdCardIdentification: Executing Cmd8 fails with %r\n", Status
));
1015 // 3. Send SDIO Cmd5 to the device to the SDIO device OCR register.
1017 Status
= SdioSendOpCond (PassThru
, Slot
, 0, FALSE
);
1018 if (!EFI_ERROR (Status
)) {
1019 DEBUG ((EFI_D_INFO
, "SdCardIdentification: Found SDIO device, ignore it as we don't support\n"));
1020 return EFI_DEVICE_ERROR
;
1023 // 4. Send Acmd41 with voltage window 0 to the device
1025 Status
= SdCardSendOpCond (PassThru
, Slot
, 0, 0, FALSE
, FALSE
, FALSE
, &Ocr
);
1026 if (EFI_ERROR (Status
)) {
1027 DEBUG ((EFI_D_INFO
, "SdCardIdentification: Executing SdCardSendOpCond fails with %r\n", Status
));
1028 return EFI_DEVICE_ERROR
;
1031 if (Private
->Capability
[Slot
].Voltage33
!= 0) {
1035 MaxCurrent
= ((UINT32
)Private
->MaxCurrent
[Slot
] & 0xFF) * 4;
1036 } else if (Private
->Capability
[Slot
].Voltage30
!= 0) {
1040 MaxCurrent
= (((UINT32
)Private
->MaxCurrent
[Slot
] >> 8) & 0xFF) * 4;
1041 } else if (Private
->Capability
[Slot
].Voltage18
!= 0) {
1045 MaxCurrent
= (((UINT32
)Private
->MaxCurrent
[Slot
] >> 16) & 0xFF) * 4;
1048 return EFI_DEVICE_ERROR
;
1051 if (MaxCurrent
>= 150) {
1057 Status
= SdMmcHcRwMmio (PciIo
, Slot
, SD_MMC_HC_CTRL_VER
, TRUE
, sizeof (ControllerVer
), &ControllerVer
);
1058 if (EFI_ERROR (Status
)) {
1062 if ((ControllerVer
& 0xFF) == 2) {
1064 } else if (((ControllerVer
& 0xFF) == 0) || ((ControllerVer
& 0xFF) == 1)) {
1068 return EFI_UNSUPPORTED
;
1071 // 5. Repeatly send Acmd41 with supply voltage window to the device.
1072 // Note here we only support the cards complied with SD physical
1073 // layer simplified spec version 2.0 and version 3.0 and above.
1076 Status
= SdCardSendOpCond (PassThru
, Slot
, 0, Ocr
, S18r
, Xpc
, TRUE
, &Ocr
);
1077 if (EFI_ERROR (Status
)) {
1078 DEBUG ((EFI_D_ERROR
, "SdCardIdentification: SdCardSendOpCond fails with %r Ocr %x, S18r %x, Xpc %x\n", Status
, Ocr
, S18r
, Xpc
));
1079 return EFI_DEVICE_ERROR
;
1081 } while ((Ocr
& BIT31
) == 0);
1084 // 6. If the S18A bit is set and the Host Controller supports 1.8V signaling
1085 // (One of support bits is set to 1: SDR50, SDR104 or DDR50 in the
1086 // Capabilities register), switch its voltage to 1.8V.
1088 if ((Private
->Capability
[Slot
].Sdr50
!= 0 ||
1089 Private
->Capability
[Slot
].Sdr104
!= 0 ||
1090 Private
->Capability
[Slot
].Ddr50
!= 0) &&
1091 ((Ocr
& BIT24
) != 0)) {
1092 Status
= SdCardVoltageSwitch (PassThru
, Slot
);
1093 if (EFI_ERROR (Status
)) {
1094 DEBUG ((EFI_D_ERROR
, "SdCardIdentification: Executing SdCardVoltageSwitch fails with %r\n", Status
));
1095 Status
= EFI_DEVICE_ERROR
;
1098 Status
= SdMmcHcStopClock (PciIo
, Slot
);
1099 if (EFI_ERROR (Status
)) {
1100 Status
= EFI_DEVICE_ERROR
;
1104 SdMmcHcRwMmio (PciIo
, Slot
, SD_MMC_HC_PRESENT_STATE
, TRUE
, sizeof (PresentState
), &PresentState
);
1105 if (((PresentState
>> 20) & 0xF) != 0) {
1106 DEBUG ((EFI_D_ERROR
, "SdCardIdentification: SwitchVoltage fails with PresentState = 0x%x\n", PresentState
));
1107 Status
= EFI_DEVICE_ERROR
;
1111 SdMmcHcOrMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
1115 SdMmcHcRwMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, TRUE
, sizeof (HostCtrl2
), &HostCtrl2
);
1116 if ((HostCtrl2
& BIT3
) == 0) {
1117 DEBUG ((EFI_D_ERROR
, "SdCardIdentification: SwitchVoltage fails with HostCtrl2 = 0x%x\n", HostCtrl2
));
1118 Status
= EFI_DEVICE_ERROR
;
1122 SdMmcHcInitClockFreq (PciIo
, Slot
, Private
->Capability
[Slot
]);
1126 SdMmcHcRwMmio (PciIo
, Slot
, SD_MMC_HC_PRESENT_STATE
, TRUE
, sizeof (PresentState
), &PresentState
);
1127 if (((PresentState
>> 20) & 0xF) != 0xF) {
1128 DEBUG ((EFI_D_ERROR
, "SdCardIdentification: SwitchVoltage fails with PresentState = 0x%x, It should be 0xF\n", PresentState
));
1129 Status
= EFI_DEVICE_ERROR
;
1133 DEBUG ((EFI_D_INFO
, "SdCardIdentification: Switch to 1.8v signal voltage success\n"));
1136 Status
= SdCardAllSendCid (PassThru
, Slot
);
1137 if (EFI_ERROR (Status
)) {
1138 DEBUG ((EFI_D_ERROR
, "SdCardIdentification: Executing SdCardAllSendCid fails with %r\n", Status
));
1142 Status
= SdCardSetRca (PassThru
, Slot
, &Rca
);
1143 if (EFI_ERROR (Status
)) {
1144 DEBUG ((EFI_D_ERROR
, "SdCardIdentification: Executing SdCardSetRca fails with %r\n", Status
));
1148 // Enter Data Tranfer Mode.
1150 DEBUG ((EFI_D_INFO
, "SdCardIdentification: Found a SD device at slot [%d]\n", Slot
));
1151 Private
->Slot
[Slot
].CardType
= SdCardType
;
1153 Status
= SdCardSetBusMode (PciIo
, PassThru
, Slot
, Rca
, ((Ocr
& BIT24
) != 0));
1159 // Set SD Bus Power = 0
1161 PowerCtrl
= (UINT8
)~BIT0
;
1162 Status
= SdMmcHcAndMmio (PciIo
, Slot
, SD_MMC_HC_POWER_CTRL
, sizeof (PowerCtrl
), &PowerCtrl
);
1163 return EFI_DEVICE_ERROR
;