2 This file provides some helper functions which are specific for EMMC device.
4 Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
5 Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include "SdMmcPciHcDxe.h"
13 Send command GO_IDLE_STATE (CMD0 with argument of 0x00000000) to the device to
14 make it go to Idle State.
16 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
18 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
19 @param[in] Slot The slot number of the SD card to send the command to.
21 @retval EFI_SUCCESS The EMMC device is reset correctly.
22 @retval Others The device reset fails.
27 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
31 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
32 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
33 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
36 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
37 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
38 ZeroMem (&Packet
, sizeof (Packet
));
40 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
41 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
42 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
44 SdMmcCmdBlk
.CommandIndex
= EMMC_GO_IDLE_STATE
;
45 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeBc
;
46 SdMmcCmdBlk
.ResponseType
= 0;
47 SdMmcCmdBlk
.CommandArgument
= 0;
51 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
57 Send command SEND_OP_COND to the EMMC device to get the data of the OCR register.
59 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
61 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
62 @param[in] Slot The slot number of the SD card to send the command to.
63 @param[in, out] Argument On input, the argument of SEND_OP_COND is to send to the device.
64 On output, the argument is the value of OCR register.
66 @retval EFI_SUCCESS The operation is done correctly.
67 @retval Others The operation fails.
72 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
74 IN OUT UINT32
*Argument
77 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
78 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
79 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
82 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
83 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
84 ZeroMem (&Packet
, sizeof (Packet
));
86 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
87 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
88 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
90 SdMmcCmdBlk
.CommandIndex
= EMMC_SEND_OP_COND
;
91 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeBcr
;
92 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR3
;
93 SdMmcCmdBlk
.CommandArgument
= *Argument
;
95 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
96 if (!EFI_ERROR (Status
)) {
98 // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12.
100 *Argument
= SdMmcStatusBlk
.Resp0
;
107 Broadcast command ALL_SEND_CID to the bus to ask all the EMMC devices to send the
108 data of their CID registers.
110 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
112 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
113 @param[in] Slot The slot number of the SD card to send the command to.
115 @retval EFI_SUCCESS The operation is done correctly.
116 @retval Others The operation fails.
121 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
125 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
126 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
127 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
130 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
131 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
132 ZeroMem (&Packet
, sizeof (Packet
));
134 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
135 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
136 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
138 SdMmcCmdBlk
.CommandIndex
= EMMC_ALL_SEND_CID
;
139 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeBcr
;
140 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR2
;
141 SdMmcCmdBlk
.CommandArgument
= 0;
143 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
149 Send command SET_RELATIVE_ADDR to the EMMC device to assign a Relative device
152 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
154 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
155 @param[in] Slot The slot number of the SD card to send the command to.
156 @param[in] Rca The relative device address to be assigned.
158 @retval EFI_SUCCESS The operation is done correctly.
159 @retval Others The operation fails.
164 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
169 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
170 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
171 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
174 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
175 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
176 ZeroMem (&Packet
, sizeof (Packet
));
178 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
179 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
180 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
182 SdMmcCmdBlk
.CommandIndex
= EMMC_SET_RELATIVE_ADDR
;
183 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
184 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
185 SdMmcCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
187 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
193 Send command SEND_CSD to the EMMC device to get the data of the CSD register.
195 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
197 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
198 @param[in] Slot The slot number of the SD card to send the command to.
199 @param[in] Rca The relative device address of selected device.
200 @param[out] Csd The buffer to store the content of the CSD register.
201 Note the caller should ignore the lowest byte of this
202 buffer as the content of this byte is meaningless even
203 if the operation succeeds.
205 @retval EFI_SUCCESS The operation is done correctly.
206 @retval Others The operation fails.
211 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
217 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
218 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
219 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
222 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
223 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
224 ZeroMem (&Packet
, sizeof (Packet
));
226 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
227 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
228 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
230 SdMmcCmdBlk
.CommandIndex
= EMMC_SEND_CSD
;
231 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
232 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR2
;
233 SdMmcCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
235 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
236 if (!EFI_ERROR (Status
)) {
238 // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12.
240 CopyMem (((UINT8
*)Csd
) + 1, &SdMmcStatusBlk
.Resp0
, sizeof (EMMC_CSD
) - 1);
247 Send command SELECT_DESELECT_CARD to the EMMC device to select/deselect it.
249 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
251 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
252 @param[in] Slot The slot number of the SD card to send the command to.
253 @param[in] Rca The relative device address of selected device.
255 @retval EFI_SUCCESS The operation is done correctly.
256 @retval Others The operation fails.
261 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
266 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
267 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
268 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
271 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
272 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
273 ZeroMem (&Packet
, sizeof (Packet
));
275 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
276 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
277 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
279 SdMmcCmdBlk
.CommandIndex
= EMMC_SELECT_DESELECT_CARD
;
280 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
281 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
282 SdMmcCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
284 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
290 Send command SEND_EXT_CSD to the EMMC device to get the data of the EXT_CSD register.
292 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
294 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
295 @param[in] Slot The slot number of the SD card to send the command to.
296 @param[out] ExtCsd The buffer to store the content of the EXT_CSD register.
298 @retval EFI_SUCCESS The operation is done correctly.
299 @retval Others The operation fails.
304 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
306 OUT EMMC_EXT_CSD
*ExtCsd
309 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
310 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
311 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
314 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
315 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
316 ZeroMem (&Packet
, sizeof (Packet
));
318 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
319 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
320 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
322 SdMmcCmdBlk
.CommandIndex
= EMMC_SEND_EXT_CSD
;
323 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAdtc
;
324 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
325 SdMmcCmdBlk
.CommandArgument
= 0x00000000;
327 Packet
.InDataBuffer
= ExtCsd
;
328 Packet
.InTransferLength
= sizeof (EMMC_EXT_CSD
);
330 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
335 Send command SWITCH to the EMMC device to switch the mode of operation of the
336 selected Device or modifies the EXT_CSD registers.
338 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
340 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
341 @param[in] Slot The slot number of the SD card to send the command to.
342 @param[in] Access The access mode of SWTICH command.
343 @param[in] Index The offset of the field to be access.
344 @param[in] Value The value to be set to the specified field of EXT_CSD register.
345 @param[in] CmdSet The value of CmdSet field of EXT_CSD register.
347 @retval EFI_SUCCESS The operation is done correctly.
348 @retval Others The operation fails.
353 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
361 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
362 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
363 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
366 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
367 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
368 ZeroMem (&Packet
, sizeof (Packet
));
370 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
371 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
372 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
374 SdMmcCmdBlk
.CommandIndex
= EMMC_SWITCH
;
375 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
376 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1b
;
377 SdMmcCmdBlk
.CommandArgument
= (Access
<< 24) | (Index
<< 16) | (Value
<< 8) | CmdSet
;
379 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
385 Send command SEND_STATUS to the addressed EMMC device to get its status register.
387 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
389 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
390 @param[in] Slot The slot number of the SD card to send the command to.
391 @param[in] Rca The relative device address of addressed device.
392 @param[out] DevStatus The returned device status.
394 @retval EFI_SUCCESS The operation is done correctly.
395 @retval Others The operation fails.
400 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
403 OUT UINT32
*DevStatus
406 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
407 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
408 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
411 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
412 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
413 ZeroMem (&Packet
, sizeof (Packet
));
415 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
416 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
417 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
419 SdMmcCmdBlk
.CommandIndex
= EMMC_SEND_STATUS
;
420 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
421 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
422 SdMmcCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
424 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
425 if (!EFI_ERROR (Status
)) {
426 *DevStatus
= SdMmcStatusBlk
.Resp0
;
433 Send command SEND_TUNING_BLOCK to the EMMC device for HS200 optimal sampling point
436 It may be sent up to 40 times until the host finishes the tuning procedure.
438 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 for details.
440 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
441 @param[in] Slot The slot number of the SD card to send the command to.
442 @param[in] BusWidth The bus width to work.
444 @retval EFI_SUCCESS The operation is done correctly.
445 @retval Others The operation fails.
450 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
455 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
456 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
457 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
459 UINT8 TuningBlock
[128];
461 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
462 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
463 ZeroMem (&Packet
, sizeof (Packet
));
465 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
466 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
467 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
469 SdMmcCmdBlk
.CommandIndex
= EMMC_SEND_TUNING_BLOCK
;
470 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAdtc
;
471 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
472 SdMmcCmdBlk
.CommandArgument
= 0;
474 Packet
.InDataBuffer
= TuningBlock
;
476 Packet
.InTransferLength
= sizeof (TuningBlock
);
478 Packet
.InTransferLength
= 64;
481 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
487 Tunning the clock to get HS200 optimal sampling point.
489 Command SEND_TUNING_BLOCK may be sent up to 40 times until the host finishes the
492 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
493 Simplified Spec 3.0 Figure 2-29 for details.
495 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
496 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
497 @param[in] Slot The slot number of the SD card to send the command to.
498 @param[in] BusWidth The bus width to work.
500 @retval EFI_SUCCESS The operation is done correctly.
501 @retval Others The operation fails.
505 EmmcTuningClkForHs200 (
506 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
507 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
517 // Notify the host that the sampling clock tuning procedure starts.
520 Status
= SdMmcHcOrMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
521 if (EFI_ERROR (Status
)) {
525 // Ask the device to send a sequence of tuning blocks till the tuning procedure is done.
529 Status
= EmmcSendTuningBlk (PassThru
, Slot
, BusWidth
);
530 if (EFI_ERROR (Status
)) {
531 DEBUG ((DEBUG_ERROR
, "EmmcTuningClkForHs200: Send tuning block fails with %r\n", Status
));
535 Status
= SdMmcHcRwMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, TRUE
, sizeof (HostCtrl2
), &HostCtrl2
);
536 if (EFI_ERROR (Status
)) {
540 if ((HostCtrl2
& (BIT6
| BIT7
)) == 0) {
544 if ((HostCtrl2
& (BIT6
| BIT7
)) == BIT7
) {
547 } while (++Retry
< 40);
549 DEBUG ((DEBUG_ERROR
, "EmmcTuningClkForHs200: Send tuning block fails at %d times with HostCtrl2 %02x\n", Retry
, HostCtrl2
));
551 // Abort the tuning procedure and reset the tuning circuit.
553 HostCtrl2
= (UINT8
)~(BIT6
| BIT7
);
554 Status
= SdMmcHcAndMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
555 if (EFI_ERROR (Status
)) {
558 return EFI_DEVICE_ERROR
;
562 Switch the bus width to specified width.
564 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.9 and SD Host Controller
565 Simplified Spec 3.0 Figure 3-7 for details.
567 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
568 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
569 @param[in] Slot The slot number of the SD card to send the command to.
570 @param[in] Rca The relative device address to be assigned.
571 @param[in] IsDdr If TRUE, use dual data rate data simpling method. Otherwise
572 use single data rate data simpling method.
573 @param[in] BusWidth The bus width to be set, it could be 4 or 8.
575 @retval EFI_SUCCESS The operation is done correctly.
576 @retval Others The operation fails.
581 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
582 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
597 // Write Byte, the Value field is written into the byte pointed by Index.
600 Index
= OFFSET_OF (EMMC_EXT_CSD
, BusWidth
);
603 } else if (BusWidth
== 8) {
606 return EFI_INVALID_PARAMETER
;
614 Status
= EmmcSwitch (PassThru
, Slot
, Access
, Index
, Value
, CmdSet
);
615 if (EFI_ERROR (Status
)) {
616 DEBUG ((DEBUG_ERROR
, "EmmcSwitchBusWidth: Switch to bus width %d fails with %r\n", BusWidth
, Status
));
620 Status
= EmmcSendStatus (PassThru
, Slot
, Rca
, &DevStatus
);
621 if (EFI_ERROR (Status
)) {
622 DEBUG ((DEBUG_ERROR
, "EmmcSwitchBusWidth: Send status fails with %r\n", Status
));
626 // Check the switch operation is really successful or not.
628 if ((DevStatus
& BIT7
) != 0) {
629 DEBUG ((DEBUG_ERROR
, "EmmcSwitchBusWidth: The switch operation fails as DevStatus is 0x%08x\n", DevStatus
));
630 return EFI_DEVICE_ERROR
;
633 Status
= SdMmcHcSetBusWidth (PciIo
, Slot
, BusWidth
);
639 Switch the bus timing and clock frequency.
641 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6 and SD Host Controller
642 Simplified Spec 3.0 Figure 3-3 for details.
644 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
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 to be assigned.
648 @param[in] DriverStrength Driver strength to set for speed modes that support it.
649 @param[in] BusTiming The bus mode timing indicator.
650 @param[in] ClockFreq The max clock frequency to be set, the unit is MHz.
652 @retval EFI_SUCCESS The operation is done correctly.
653 @retval Others The operation fails.
657 EmmcSwitchBusTiming (
658 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
659 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
662 IN EDKII_SD_MMC_DRIVER_STRENGTH DriverStrength
,
663 IN SD_MMC_BUS_MODE BusTiming
,
673 SD_MMC_HC_PRIVATE_DATA
*Private
;
675 Private
= SD_MMC_HC_PRIVATE_FROM_THIS (PassThru
);
677 // Write Byte, the Value field is written into the byte pointed by Index.
680 Index
= OFFSET_OF (EMMC_EXT_CSD
, HsTiming
);
684 Value
= (UINT8
)((DriverStrength
.Emmc
<< 4) | 3);
687 Value
= (UINT8
)((DriverStrength
.Emmc
<< 4) | 2);
697 DEBUG ((DEBUG_ERROR
, "EmmcSwitchBusTiming: Unsupported BusTiming(%d\n)", BusTiming
));
698 return EFI_INVALID_PARAMETER
;
701 Status
= EmmcSwitch (PassThru
, Slot
, Access
, Index
, Value
, CmdSet
);
702 if (EFI_ERROR (Status
)) {
703 DEBUG ((DEBUG_ERROR
, "EmmcSwitchBusTiming: Switch to bus timing %d fails with %r\n", BusTiming
, Status
));
708 // Convert the clock freq unit from MHz to KHz.
710 Status
= SdMmcHcClockSupply (PciIo
, Slot
, ClockFreq
* 1000, Private
->BaseClkFreq
[Slot
], Private
->ControllerVersion
[Slot
]);
711 if (EFI_ERROR (Status
)) {
715 Status
= EmmcSendStatus (PassThru
, Slot
, Rca
, &DevStatus
);
716 if (EFI_ERROR (Status
)) {
717 DEBUG ((DEBUG_ERROR
, "EmmcSwitchBusTiming: Send status fails with %r\n", Status
));
721 // Check the switch operation is really successful or not.
723 if ((DevStatus
& BIT7
) != 0) {
724 DEBUG ((DEBUG_ERROR
, "EmmcSwitchBusTiming: The switch operation fails as DevStatus is 0x%08x\n", DevStatus
));
725 return EFI_DEVICE_ERROR
;
728 if (mOverride
!= NULL
&& mOverride
->NotifyPhase
!= NULL
) {
729 Status
= mOverride
->NotifyPhase (
730 Private
->ControllerHandle
,
732 EdkiiSdMmcSwitchClockFreqPost
,
735 if (EFI_ERROR (Status
)) {
738 "%a: SD/MMC switch clock freq post notifier callback failed - %r\n",
750 Switch to the High Speed timing according to request.
752 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
753 Simplified Spec 3.0 Figure 2-29 for details.
755 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
756 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
757 @param[in] Slot The slot number of the SD card to send the command to.
758 @param[in] Rca The relative device address to be assigned.
759 @param[in] BusMode Pointer to SD_MMC_BUS_SETTINGS structure containing bus settings.
761 @retval EFI_SUCCESS The operation is done correctly.
762 @retval Others The operation fails.
766 EmmcSwitchToHighSpeed (
767 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
768 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
771 IN SD_MMC_BUS_SETTINGS
*BusMode
776 SD_MMC_HC_PRIVATE_DATA
*Private
;
779 Private
= SD_MMC_HC_PRIVATE_FROM_THIS (PassThru
);
781 if ((BusMode
->BusTiming
!= SdMmcMmcHsSdr
&& BusMode
->BusTiming
!= SdMmcMmcHsDdr
) ||
782 BusMode
->ClockFreq
> 52) {
783 return EFI_INVALID_PARAMETER
;
786 if (BusMode
->BusTiming
== SdMmcMmcHsDdr
) {
792 Status
= EmmcSwitchBusWidth (PciIo
, PassThru
, Slot
, Rca
, IsDdr
, BusMode
->BusWidth
);
793 if (EFI_ERROR (Status
)) {
798 // Set to High Speed timing
801 Status
= SdMmcHcOrMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
802 if (EFI_ERROR (Status
)) {
806 Status
= SdMmcHcUhsSignaling (Private
->ControllerHandle
, PciIo
, Slot
, BusMode
->BusTiming
);
807 if (EFI_ERROR (Status
)) {
811 return EmmcSwitchBusTiming (PciIo
, PassThru
, Slot
, Rca
, BusMode
->DriverStrength
, BusMode
->BusTiming
, BusMode
->ClockFreq
);
815 Switch to the HS200 timing. This function assumes that eMMC bus is still in legacy mode.
817 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
818 Simplified Spec 3.0 Figure 2-29 for details.
820 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
821 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
822 @param[in] Slot The slot number of the SD card to send the command to.
823 @param[in] Rca The relative device address to be assigned.
824 @param[in] BusMode Pointer to SD_MMC_BUS_SETTINGS structure containing bus settings.
826 @retval EFI_SUCCESS The operation is done correctly.
827 @retval Others The operation fails.
832 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
833 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
836 IN SD_MMC_BUS_SETTINGS
*BusMode
841 SD_MMC_HC_PRIVATE_DATA
*Private
;
843 Private
= SD_MMC_HC_PRIVATE_FROM_THIS (PassThru
);
845 if (BusMode
->BusTiming
!= SdMmcMmcHs200
||
846 (BusMode
->BusWidth
!= 4 && BusMode
->BusWidth
!= 8)) {
847 return EFI_INVALID_PARAMETER
;
850 Status
= EmmcSwitchBusWidth (PciIo
, PassThru
, Slot
, Rca
, FALSE
, BusMode
->BusWidth
);
851 if (EFI_ERROR (Status
)) {
855 // Stop bus clock at first
857 Status
= SdMmcHcStopClock (PciIo
, Slot
);
858 if (EFI_ERROR (Status
)) {
862 Status
= SdMmcHcUhsSignaling (Private
->ControllerHandle
, PciIo
, Slot
, BusMode
->BusTiming
);
863 if (EFI_ERROR (Status
)) {
868 // Wait Internal Clock Stable in the Clock Control register to be 1 before set SD Clock Enable bit
870 Status
= SdMmcHcWaitMmioSet (
873 SD_MMC_HC_CLOCK_CTRL
,
877 SD_MMC_HC_GENERIC_TIMEOUT
879 if (EFI_ERROR (Status
)) {
883 // Set SD Clock Enable in the Clock Control register to 1
886 Status
= SdMmcHcOrMmio (PciIo
, Slot
, SD_MMC_HC_CLOCK_CTRL
, sizeof (ClockCtrl
), &ClockCtrl
);
888 Status
= EmmcSwitchBusTiming (PciIo
, PassThru
, Slot
, Rca
, BusMode
->DriverStrength
, BusMode
->BusTiming
, BusMode
->ClockFreq
);
889 if (EFI_ERROR (Status
)) {
893 Status
= EmmcTuningClkForHs200 (PciIo
, PassThru
, Slot
, BusMode
->BusWidth
);
899 Switch to the HS400 timing. This function assumes that eMMC bus is still in legacy mode.
901 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
902 Simplified Spec 3.0 Figure 2-29 for details.
904 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
905 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
906 @param[in] Slot The slot number of the SD card to send the command to.
907 @param[in] Rca The relative device address to be assigned.
908 @param[in] BusMode Pointer to SD_MMC_BUS_SETTINGS structure containing bus settings.
910 @retval EFI_SUCCESS The operation is done correctly.
911 @retval Others The operation fails.
916 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
917 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
920 IN SD_MMC_BUS_SETTINGS
*BusMode
924 SD_MMC_HC_PRIVATE_DATA
*Private
;
925 SD_MMC_BUS_SETTINGS Hs200BusMode
;
928 if (BusMode
->BusTiming
!= SdMmcMmcHs400
||
929 BusMode
->BusWidth
!= 8) {
930 return EFI_INVALID_PARAMETER
;
933 Private
= SD_MMC_HC_PRIVATE_FROM_THIS (PassThru
);
934 Hs200BusMode
.BusTiming
= SdMmcMmcHs200
;
935 Hs200BusMode
.BusWidth
= BusMode
->BusWidth
;
936 Hs200BusMode
.ClockFreq
= BusMode
->ClockFreq
;
937 Hs200BusMode
.DriverStrength
= BusMode
->DriverStrength
;
939 Status
= EmmcSwitchToHS200 (PciIo
, PassThru
, Slot
, Rca
, &Hs200BusMode
);
940 if (EFI_ERROR (Status
)) {
945 // Set to High Speed timing and set the clock frequency to a value less than or equal to 52MHz.
946 // This step is necessary to be able to switch Bus into 8 bit DDR mode which is unsupported in HS200.
948 Status
= SdMmcHcUhsSignaling (Private
->ControllerHandle
, PciIo
, Slot
, SdMmcMmcHsSdr
);
949 if (EFI_ERROR (Status
)) {
953 HsFreq
= BusMode
->ClockFreq
< 52 ? BusMode
->ClockFreq
: 52;
954 Status
= EmmcSwitchBusTiming (PciIo
, PassThru
, Slot
, Rca
, BusMode
->DriverStrength
, SdMmcMmcHsSdr
, HsFreq
);
955 if (EFI_ERROR (Status
)) {
959 Status
= EmmcSwitchBusWidth (PciIo
, PassThru
, Slot
, Rca
, TRUE
, BusMode
->BusWidth
);
960 if (EFI_ERROR (Status
)) {
964 Status
= SdMmcHcUhsSignaling (Private
->ControllerHandle
, PciIo
, Slot
, BusMode
->BusTiming
);
965 if (EFI_ERROR (Status
)) {
969 return EmmcSwitchBusTiming (PciIo
, PassThru
, Slot
, Rca
, BusMode
->DriverStrength
, BusMode
->BusTiming
, BusMode
->ClockFreq
);
973 Check if passed BusTiming is supported in both controller and card.
975 @param[in] Private Pointer to controller private data
976 @param[in] SlotIndex Index of the slot in the controller
977 @param[in] ExtCsd Pointer to the card's extended CSD
978 @param[in] BusTiming Bus timing to check
980 @retval TRUE Both card and controller support given BusTiming
981 @retval FALSE Card or controller doesn't support given BusTiming
984 EmmcIsBusTimingSupported (
985 IN SD_MMC_HC_PRIVATE_DATA
*Private
,
987 IN EMMC_EXT_CSD
*ExtCsd
,
988 IN SD_MMC_BUS_MODE BusTiming
992 SD_MMC_HC_SLOT_CAP
*Capabilities
;
994 Capabilities
= &Private
->Capability
[SlotIndex
];
999 if ((((ExtCsd
->DeviceType
& (BIT6
| BIT7
)) != 0) && (Capabilities
->Hs400
!= 0)) && Capabilities
->BusWidth8
!= 0) {
1004 if ((((ExtCsd
->DeviceType
& (BIT4
| BIT5
)) != 0) && (Capabilities
->Sdr104
!= 0))) {
1009 if ((((ExtCsd
->DeviceType
& (BIT2
| BIT3
)) != 0) && (Capabilities
->Ddr50
!= 0))) {
1014 if ((((ExtCsd
->DeviceType
& BIT1
) != 0) && (Capabilities
->HighSpeed
!= 0))) {
1018 case SdMmcMmcLegacy
:
1019 if ((ExtCsd
->DeviceType
& BIT0
) != 0) {
1031 Get the target bus timing to set on the link. This function
1032 will try to select highest bus timing supported by card, controller
1035 @param[in] Private Pointer to controller private data
1036 @param[in] SlotIndex Index of the slot in the controller
1037 @param[in] ExtCsd Pointer to the card's extended CSD
1039 @return Bus timing value that should be set on link
1042 EmmcGetTargetBusTiming (
1043 IN SD_MMC_HC_PRIVATE_DATA
*Private
,
1045 IN EMMC_EXT_CSD
*ExtCsd
1048 SD_MMC_BUS_MODE BusTiming
;
1051 // We start with highest bus timing that this driver currently supports and
1052 // return as soon as we find supported timing.
1054 BusTiming
= SdMmcMmcHs400
;
1055 while (BusTiming
> SdMmcMmcLegacy
) {
1056 if (EmmcIsBusTimingSupported (Private
, SlotIndex
, ExtCsd
, BusTiming
)) {
1066 Check if the passed bus width is supported by controller and card.
1068 @param[in] Private Pointer to controller private data
1069 @param[in] SlotIndex Index of the slot in the controller
1070 @param[in] BusTiming Bus timing set on the link
1071 @param[in] BusWidth Bus width to check
1073 @retval TRUE Passed bus width is supported in current bus configuration
1074 @retval FALSE Passed bus width is not supported in current bus configuration
1077 EmmcIsBusWidthSupported (
1078 IN SD_MMC_HC_PRIVATE_DATA
*Private
,
1080 IN SD_MMC_BUS_MODE BusTiming
,
1084 if (BusWidth
== 8 && Private
->Capability
[SlotIndex
].BusWidth8
!= 0) {
1086 } else if (BusWidth
== 4 && BusTiming
!= SdMmcMmcHs400
) {
1088 } else if (BusWidth
== 1 && (BusTiming
== SdMmcMmcHsSdr
|| BusTiming
== SdMmcMmcLegacy
)) {
1096 Get the target bus width to be set on the bus.
1098 @param[in] Private Pointer to controller private data
1099 @param[in] SlotIndex Index of the slot in the controller
1100 @param[in] ExtCsd Pointer to card's extended CSD
1101 @param[in] BusTiming Bus timing set on the bus
1103 @return Bus width to be set on the bus
1106 EmmcGetTargetBusWidth (
1107 IN SD_MMC_HC_PRIVATE_DATA
*Private
,
1109 IN EMMC_EXT_CSD
*ExtCsd
,
1110 IN SD_MMC_BUS_MODE BusTiming
1114 UINT8 PreferredBusWidth
;
1116 PreferredBusWidth
= Private
->Slot
[SlotIndex
].OperatingParameters
.BusWidth
;
1118 if (PreferredBusWidth
!= EDKII_SD_MMC_BUS_WIDTH_IGNORE
&&
1119 EmmcIsBusWidthSupported (Private
, SlotIndex
, BusTiming
, PreferredBusWidth
)) {
1120 BusWidth
= PreferredBusWidth
;
1121 } else if (EmmcIsBusWidthSupported (Private
, SlotIndex
, BusTiming
, 8)) {
1123 } else if (EmmcIsBusWidthSupported (Private
, SlotIndex
, BusTiming
, 4)) {
1133 Get the target clock frequency to be set on the bus.
1135 @param[in] Private Pointer to controller private data
1136 @param[in] SlotIndex Index of the slot in the controller
1137 @param[in] ExtCsd Pointer to card's extended CSD
1138 @param[in] BusTiming Bus timing to be set on the bus
1140 @return Value of the clock frequency to be set on bus in MHz
1143 EmmcGetTargetClockFreq (
1144 IN SD_MMC_HC_PRIVATE_DATA
*Private
,
1146 IN EMMC_EXT_CSD
*ExtCsd
,
1147 IN SD_MMC_BUS_MODE BusTiming
1150 UINT32 PreferredClockFreq
;
1151 UINT32 MaxClockFreq
;
1153 PreferredClockFreq
= Private
->Slot
[SlotIndex
].OperatingParameters
.ClockFreq
;
1155 switch (BusTiming
) {
1169 if (PreferredClockFreq
!= EDKII_SD_MMC_CLOCK_FREQ_IGNORE
&& PreferredClockFreq
< MaxClockFreq
) {
1170 return PreferredClockFreq
;
1172 return MaxClockFreq
;
1177 Get the driver strength to be set on bus.
1179 @param[in] Private Pointer to controller private data
1180 @param[in] SlotIndex Index of the slot in the controller
1181 @param[in] ExtCsd Pointer to card's extended CSD
1182 @param[in] BusTiming Bus timing set on the bus
1184 @return Value of the driver strength to be set on the bus
1186 EDKII_SD_MMC_DRIVER_STRENGTH
1187 EmmcGetTargetDriverStrength (
1188 IN SD_MMC_HC_PRIVATE_DATA
*Private
,
1190 IN EMMC_EXT_CSD
*ExtCsd
,
1191 IN SD_MMC_BUS_MODE BusTiming
1194 EDKII_SD_MMC_DRIVER_STRENGTH PreferredDriverStrength
;
1195 EDKII_SD_MMC_DRIVER_STRENGTH DriverStrength
;
1197 PreferredDriverStrength
= Private
->Slot
[SlotIndex
].OperatingParameters
.DriverStrength
;
1198 DriverStrength
.Emmc
= EmmcDriverStrengthType0
;
1200 if (PreferredDriverStrength
.Emmc
!= EDKII_SD_MMC_DRIVER_STRENGTH_IGNORE
&&
1201 (ExtCsd
->DriverStrength
& (BIT0
<< PreferredDriverStrength
.Emmc
))) {
1202 DriverStrength
.Emmc
= PreferredDriverStrength
.Emmc
;
1205 return DriverStrength
;
1209 Get the target settings for the bus mode.
1211 @param[in] Private Pointer to controller private data
1212 @param[in] SlotIndex Index of the slot in the controller
1213 @param[in] ExtCsd Pointer to card's extended CSD
1214 @param[out] BusMode Target configuration of the bus
1217 EmmcGetTargetBusMode (
1218 IN SD_MMC_HC_PRIVATE_DATA
*Private
,
1220 IN EMMC_EXT_CSD
*ExtCsd
,
1221 OUT SD_MMC_BUS_SETTINGS
*BusMode
1224 BusMode
->BusTiming
= EmmcGetTargetBusTiming (Private
, SlotIndex
, ExtCsd
);
1225 BusMode
->BusWidth
= EmmcGetTargetBusWidth (Private
, SlotIndex
, ExtCsd
, BusMode
->BusTiming
);
1226 BusMode
->ClockFreq
= EmmcGetTargetClockFreq (Private
, SlotIndex
, ExtCsd
, BusMode
->BusTiming
);
1227 BusMode
->DriverStrength
= EmmcGetTargetDriverStrength (Private
, SlotIndex
, ExtCsd
, BusMode
->BusTiming
);
1231 Switch the high speed timing according to request.
1233 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
1234 Simplified Spec 3.0 Figure 2-29 for details.
1236 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
1237 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
1238 @param[in] Slot The slot number of the SD card to send the command to.
1239 @param[in] Rca The relative device address to be assigned.
1241 @retval EFI_SUCCESS The operation is done correctly.
1242 @retval Others The operation fails.
1247 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1248 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
1255 EMMC_EXT_CSD ExtCsd
;
1256 SD_MMC_BUS_SETTINGS BusMode
;
1257 SD_MMC_HC_PRIVATE_DATA
*Private
;
1259 Private
= SD_MMC_HC_PRIVATE_FROM_THIS (PassThru
);
1261 Status
= EmmcGetCsd (PassThru
, Slot
, Rca
, &Csd
);
1262 if (EFI_ERROR (Status
)) {
1263 DEBUG ((DEBUG_ERROR
, "EmmcSetBusMode: GetCsd fails with %r\n", Status
));
1267 Status
= EmmcSelect (PassThru
, Slot
, Rca
);
1268 if (EFI_ERROR (Status
)) {
1269 DEBUG ((DEBUG_ERROR
, "EmmcSetBusMode: Select fails with %r\n", Status
));
1273 ASSERT (Private
->BaseClkFreq
[Slot
] != 0);
1276 // Get Device_Type from EXT_CSD register.
1278 Status
= EmmcGetExtCsd (PassThru
, Slot
, &ExtCsd
);
1279 if (EFI_ERROR (Status
)) {
1280 DEBUG ((DEBUG_ERROR
, "EmmcSetBusMode: GetExtCsd fails with %r\n", Status
));
1284 EmmcGetTargetBusMode (Private
, Slot
, &ExtCsd
, &BusMode
);
1286 DEBUG ((DEBUG_INFO
, "EmmcSetBusMode: Target bus mode: timing = %d, width = %d, clock freq = %d, driver strength = %d\n",
1287 BusMode
.BusTiming
, BusMode
.BusWidth
, BusMode
.ClockFreq
, BusMode
.DriverStrength
.Emmc
));
1289 if (BusMode
.BusTiming
== SdMmcMmcHs400
) {
1290 Status
= EmmcSwitchToHS400 (PciIo
, PassThru
, Slot
, Rca
, &BusMode
);
1291 } else if (BusMode
.BusTiming
== SdMmcMmcHs200
) {
1292 Status
= EmmcSwitchToHS200 (PciIo
, PassThru
, Slot
, Rca
, &BusMode
);
1294 Status
= EmmcSwitchToHighSpeed (PciIo
, PassThru
, Slot
, Rca
, &BusMode
);
1297 DEBUG ((DEBUG_INFO
, "EmmcSetBusMode: Switch to %a %r\n", (BusMode
.BusTiming
== SdMmcMmcHs400
) ? "HS400" : ((BusMode
.BusTiming
== SdMmcMmcHs200
) ? "HS200" : "HighSpeed"), Status
));
1303 Execute EMMC device identification procedure.
1305 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
1307 @param[in] Private A pointer to the SD_MMC_HC_PRIVATE_DATA instance.
1308 @param[in] Slot The slot number of the SD card to send the command to.
1310 @retval EFI_SUCCESS There is a EMMC card.
1311 @retval Others There is not a EMMC card.
1315 EmmcIdentification (
1316 IN SD_MMC_HC_PRIVATE_DATA
*Private
,
1321 EFI_PCI_IO_PROTOCOL
*PciIo
;
1322 EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
;
1327 PciIo
= Private
->PciIo
;
1328 PassThru
= &Private
->PassThru
;
1330 Status
= EmmcReset (PassThru
, Slot
);
1331 if (EFI_ERROR (Status
)) {
1332 DEBUG ((DEBUG_VERBOSE
, "EmmcIdentification: Executing Cmd0 fails with %r\n", Status
));
1339 Status
= EmmcGetOcr (PassThru
, Slot
, &Ocr
);
1340 if (EFI_ERROR (Status
)) {
1341 DEBUG ((DEBUG_VERBOSE
, "EmmcIdentification: Executing Cmd1 fails with %r\n", Status
));
1346 if (Retry
++ == 100) {
1347 DEBUG ((DEBUG_VERBOSE
, "EmmcIdentification: Executing Cmd1 fails too many times\n"));
1348 return EFI_DEVICE_ERROR
;
1350 gBS
->Stall(10 * 1000);
1351 } while ((Ocr
& BIT31
) == 0);
1353 Status
= EmmcGetAllCid (PassThru
, Slot
);
1354 if (EFI_ERROR (Status
)) {
1355 DEBUG ((DEBUG_VERBOSE
, "EmmcIdentification: Executing Cmd2 fails with %r\n", Status
));
1359 // Slot starts from 0 and valid RCA starts from 1.
1360 // Here we takes a simple formula to calculate the RCA.
1361 // Don't support multiple devices on the slot, that is
1362 // shared bus slot feature.
1365 Status
= EmmcSetRca (PassThru
, Slot
, Rca
);
1366 if (EFI_ERROR (Status
)) {
1367 DEBUG ((DEBUG_ERROR
, "EmmcIdentification: Executing Cmd3 fails with %r\n", Status
));
1371 // Enter Data Tranfer Mode.
1373 DEBUG ((DEBUG_INFO
, "EmmcIdentification: Found a EMMC device at slot [%d], RCA [%d]\n", Slot
, Rca
));
1374 Private
->Slot
[Slot
].CardType
= EmmcCardType
;
1376 Status
= EmmcSetBusMode (PciIo
, PassThru
, Slot
, Rca
);