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 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include "SdMmcPciHcDxe.h"
19 Send command GO_IDLE_STATE (CMD0 with argument of 0x00000000) to the device to
20 make it go to Idle State.
22 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
24 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
25 @param[in] Slot The slot number of the SD card to send the command to.
27 @retval EFI_SUCCESS The EMMC device is reset correctly.
28 @retval Others The device reset fails.
33 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
37 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
38 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
39 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
42 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
43 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
44 ZeroMem (&Packet
, sizeof (Packet
));
46 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
47 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
48 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
50 SdMmcCmdBlk
.CommandIndex
= EMMC_GO_IDLE_STATE
;
51 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeBc
;
52 SdMmcCmdBlk
.ResponseType
= 0;
53 SdMmcCmdBlk
.CommandArgument
= 0;
57 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
63 Send command SEND_OP_COND to the EMMC device to get the data of the OCR register.
65 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
67 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
68 @param[in] Slot The slot number of the SD card to send the command to.
69 @param[in, out] Argument On input, the argument of SEND_OP_COND is to send to the device.
70 On output, the argument is the value of OCR register.
72 @retval EFI_SUCCESS The operation is done correctly.
73 @retval Others The operation fails.
78 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
80 IN OUT UINT32
*Argument
83 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
84 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
85 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
88 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
89 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
90 ZeroMem (&Packet
, sizeof (Packet
));
92 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
93 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
94 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
96 SdMmcCmdBlk
.CommandIndex
= EMMC_SEND_OP_COND
;
97 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeBcr
;
98 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR3
;
99 SdMmcCmdBlk
.CommandArgument
= *Argument
;
101 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
102 if (!EFI_ERROR (Status
)) {
104 // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12.
106 *Argument
= SdMmcStatusBlk
.Resp0
;
113 Broadcast command ALL_SEND_CID to the bus to ask all the EMMC devices to send the
114 data of their CID registers.
116 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
118 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
119 @param[in] Slot The slot number of the SD card to send the command to.
121 @retval EFI_SUCCESS The operation is done correctly.
122 @retval Others The operation fails.
127 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
131 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
132 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
133 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
= EMMC_ALL_SEND_CID
;
145 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeBcr
;
146 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR2
;
147 SdMmcCmdBlk
.CommandArgument
= 0;
149 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
155 Send command SET_RELATIVE_ADDR to the EMMC device to assign a Relative device
158 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
160 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
161 @param[in] Slot The slot number of the SD card to send the command to.
162 @param[in] Rca The relative device address to be assigned.
164 @retval EFI_SUCCESS The operation is done correctly.
165 @retval Others The operation fails.
170 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
175 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
176 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
177 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
180 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
181 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
182 ZeroMem (&Packet
, sizeof (Packet
));
184 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
185 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
186 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
188 SdMmcCmdBlk
.CommandIndex
= EMMC_SET_RELATIVE_ADDR
;
189 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
190 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
191 SdMmcCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
193 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
199 Send command SEND_CSD to the EMMC device to get the data of the CSD register.
201 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
203 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
204 @param[in] Slot The slot number of the SD card to send the command to.
205 @param[in] Rca The relative device address of selected device.
206 @param[out] Csd The buffer to store the content of the CSD register.
207 Note the caller should ignore the lowest byte of this
208 buffer as the content of this byte is meaningless even
209 if the operation succeeds.
211 @retval EFI_SUCCESS The operation is done correctly.
212 @retval Others The operation fails.
217 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
223 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
224 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
225 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
228 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
229 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
230 ZeroMem (&Packet
, sizeof (Packet
));
232 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
233 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
234 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
236 SdMmcCmdBlk
.CommandIndex
= EMMC_SEND_CSD
;
237 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
238 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR2
;
239 SdMmcCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
241 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
242 if (!EFI_ERROR (Status
)) {
244 // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12.
246 CopyMem (((UINT8
*)Csd
) + 1, &SdMmcStatusBlk
.Resp0
, sizeof (EMMC_CSD
) - 1);
253 Send command SELECT_DESELECT_CARD to the EMMC device to select/deselect it.
255 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
257 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
258 @param[in] Slot The slot number of the SD card to send the command to.
259 @param[in] Rca The relative device address of selected device.
261 @retval EFI_SUCCESS The operation is done correctly.
262 @retval Others The operation fails.
267 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
272 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
273 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
274 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
277 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
278 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
279 ZeroMem (&Packet
, sizeof (Packet
));
281 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
282 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
283 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
285 SdMmcCmdBlk
.CommandIndex
= EMMC_SELECT_DESELECT_CARD
;
286 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
287 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
288 SdMmcCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
290 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
296 Send command SEND_EXT_CSD to the EMMC device to get the data of the EXT_CSD register.
298 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
300 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
301 @param[in] Slot The slot number of the SD card to send the command to.
302 @param[out] ExtCsd The buffer to store the content of the EXT_CSD register.
304 @retval EFI_SUCCESS The operation is done correctly.
305 @retval Others The operation fails.
310 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
312 OUT EMMC_EXT_CSD
*ExtCsd
315 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
316 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
317 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
320 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
321 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
322 ZeroMem (&Packet
, sizeof (Packet
));
324 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
325 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
326 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
328 SdMmcCmdBlk
.CommandIndex
= EMMC_SEND_EXT_CSD
;
329 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAdtc
;
330 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
331 SdMmcCmdBlk
.CommandArgument
= 0x00000000;
333 Packet
.InDataBuffer
= ExtCsd
;
334 Packet
.InTransferLength
= sizeof (EMMC_EXT_CSD
);
336 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
341 Send command SWITCH to the EMMC device to switch the mode of operation of the
342 selected Device or modifies the EXT_CSD registers.
344 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
346 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
347 @param[in] Slot The slot number of the SD card to send the command to.
348 @param[in] Access The access mode of SWTICH command.
349 @param[in] Index The offset of the field to be access.
350 @param[in] Value The value to be set to the specified field of EXT_CSD register.
351 @param[in] CmdSet The value of CmdSet field of EXT_CSD register.
353 @retval EFI_SUCCESS The operation is done correctly.
354 @retval Others The operation fails.
359 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
367 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
368 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
369 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
372 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
373 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
374 ZeroMem (&Packet
, sizeof (Packet
));
376 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
377 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
378 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
380 SdMmcCmdBlk
.CommandIndex
= EMMC_SWITCH
;
381 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
382 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1b
;
383 SdMmcCmdBlk
.CommandArgument
= (Access
<< 24) | (Index
<< 16) | (Value
<< 8) | CmdSet
;
385 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
391 Send command SEND_STATUS to the addressed EMMC device to get its status register.
393 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
395 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
396 @param[in] Slot The slot number of the SD card to send the command to.
397 @param[in] Rca The relative device address of addressed device.
398 @param[out] DevStatus The returned device status.
400 @retval EFI_SUCCESS The operation is done correctly.
401 @retval Others The operation fails.
406 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
409 OUT UINT32
*DevStatus
412 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
413 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
414 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
417 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
418 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
419 ZeroMem (&Packet
, sizeof (Packet
));
421 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
422 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
423 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
425 SdMmcCmdBlk
.CommandIndex
= EMMC_SEND_STATUS
;
426 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
427 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
428 SdMmcCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
430 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
431 if (!EFI_ERROR (Status
)) {
432 *DevStatus
= SdMmcStatusBlk
.Resp0
;
439 Send command SEND_TUNING_BLOCK to the EMMC device for HS200 optimal sampling point
442 It may be sent up to 40 times until the host finishes the tuning procedure.
444 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 for details.
446 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
447 @param[in] Slot The slot number of the SD card to send the command to.
448 @param[in] BusWidth The bus width to work.
450 @retval EFI_SUCCESS The operation is done correctly.
451 @retval Others The operation fails.
456 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
461 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
462 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
463 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
465 UINT8 TuningBlock
[128];
467 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
468 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
469 ZeroMem (&Packet
, sizeof (Packet
));
471 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
472 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
473 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
475 SdMmcCmdBlk
.CommandIndex
= EMMC_SEND_TUNING_BLOCK
;
476 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAdtc
;
477 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
478 SdMmcCmdBlk
.CommandArgument
= 0;
480 Packet
.InDataBuffer
= TuningBlock
;
482 Packet
.InTransferLength
= sizeof (TuningBlock
);
484 Packet
.InTransferLength
= 64;
487 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
493 Tunning the clock to get HS200 optimal sampling point.
495 Command SEND_TUNING_BLOCK may be sent up to 40 times until the host finishes the
498 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
499 Simplified Spec 3.0 Figure 2-29 for details.
501 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
502 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
503 @param[in] Slot The slot number of the SD card to send the command to.
504 @param[in] BusWidth The bus width to work.
506 @retval EFI_SUCCESS The operation is done correctly.
507 @retval Others The operation fails.
511 EmmcTuningClkForHs200 (
512 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
513 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
523 // Notify the host that the sampling clock tuning procedure starts.
526 Status
= SdMmcHcOrMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
527 if (EFI_ERROR (Status
)) {
531 // Ask the device to send a sequence of tuning blocks till the tuning procedure is done.
535 Status
= EmmcSendTuningBlk (PassThru
, Slot
, BusWidth
);
536 if (EFI_ERROR (Status
)) {
537 DEBUG ((DEBUG_ERROR
, "EmmcTuningClkForHs200: Send tuning block fails with %r\n", Status
));
541 Status
= SdMmcHcRwMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, TRUE
, sizeof (HostCtrl2
), &HostCtrl2
);
542 if (EFI_ERROR (Status
)) {
546 if ((HostCtrl2
& (BIT6
| BIT7
)) == 0) {
550 if ((HostCtrl2
& (BIT6
| BIT7
)) == BIT7
) {
553 } while (++Retry
< 40);
555 DEBUG ((DEBUG_ERROR
, "EmmcTuningClkForHs200: Send tuning block fails at %d times with HostCtrl2 %02x\n", Retry
, HostCtrl2
));
557 // Abort the tuning procedure and reset the tuning circuit.
559 HostCtrl2
= (UINT8
)~(BIT6
| BIT7
);
560 Status
= SdMmcHcAndMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
561 if (EFI_ERROR (Status
)) {
564 return EFI_DEVICE_ERROR
;
568 Switch the bus width to specified width.
570 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.9 and SD Host Controller
571 Simplified Spec 3.0 Figure 3-7 for details.
573 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
574 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
575 @param[in] Slot The slot number of the SD card to send the command to.
576 @param[in] Rca The relative device address to be assigned.
577 @param[in] IsDdr If TRUE, use dual data rate data simpling method. Otherwise
578 use single data rate data simpling method.
579 @param[in] BusWidth The bus width to be set, it could be 4 or 8.
581 @retval EFI_SUCCESS The operation is done correctly.
582 @retval Others The operation fails.
587 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
588 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
603 // Write Byte, the Value field is written into the byte pointed by Index.
606 Index
= OFFSET_OF (EMMC_EXT_CSD
, BusWidth
);
609 } else if (BusWidth
== 8) {
612 return EFI_INVALID_PARAMETER
;
620 Status
= EmmcSwitch (PassThru
, Slot
, Access
, Index
, Value
, CmdSet
);
621 if (EFI_ERROR (Status
)) {
622 DEBUG ((DEBUG_ERROR
, "EmmcSwitchBusWidth: Switch to bus width %d fails with %r\n", BusWidth
, Status
));
626 Status
= EmmcSendStatus (PassThru
, Slot
, Rca
, &DevStatus
);
627 if (EFI_ERROR (Status
)) {
628 DEBUG ((DEBUG_ERROR
, "EmmcSwitchBusWidth: Send status fails with %r\n", Status
));
632 // Check the switch operation is really successful or not.
634 if ((DevStatus
& BIT7
) != 0) {
635 DEBUG ((DEBUG_ERROR
, "EmmcSwitchBusWidth: The switch operation fails as DevStatus is 0x%08x\n", DevStatus
));
636 return EFI_DEVICE_ERROR
;
639 Status
= SdMmcHcSetBusWidth (PciIo
, Slot
, BusWidth
);
645 Switch the bus timing and clock frequency.
647 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6 and SD Host Controller
648 Simplified Spec 3.0 Figure 3-3 for details.
650 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
651 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
652 @param[in] Slot The slot number of the SD card to send the command to.
653 @param[in] Rca The relative device address to be assigned.
654 @param[in] HsTiming The value to be written to HS_TIMING field of EXT_CSD register.
655 @param[in] Timing The bus mode timing indicator.
656 @param[in] ClockFreq The max clock frequency to be set, the unit is MHz.
658 @retval EFI_SUCCESS The operation is done correctly.
659 @retval Others The operation fails.
663 EmmcSwitchBusTiming (
664 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
665 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
669 IN SD_MMC_BUS_MODE Timing
,
679 SD_MMC_HC_PRIVATE_DATA
*Private
;
681 Private
= SD_MMC_HC_PRIVATE_FROM_THIS (PassThru
);
683 // Write Byte, the Value field is written into the byte pointed by Index.
686 Index
= OFFSET_OF (EMMC_EXT_CSD
, HsTiming
);
690 Status
= EmmcSwitch (PassThru
, Slot
, Access
, Index
, Value
, CmdSet
);
691 if (EFI_ERROR (Status
)) {
692 DEBUG ((DEBUG_ERROR
, "EmmcSwitchBusTiming: Switch to hstiming %d fails with %r\n", HsTiming
, Status
));
697 // Convert the clock freq unit from MHz to KHz.
699 Status
= SdMmcHcClockSupply (PciIo
, Slot
, ClockFreq
* 1000, Private
->BaseClkFreq
[Slot
], Private
->ControllerVersion
[Slot
]);
700 if (EFI_ERROR (Status
)) {
704 Status
= EmmcSendStatus (PassThru
, Slot
, Rca
, &DevStatus
);
705 if (EFI_ERROR (Status
)) {
706 DEBUG ((DEBUG_ERROR
, "EmmcSwitchBusTiming: Send status fails with %r\n", Status
));
710 // Check the switch operation is really successful or not.
712 if ((DevStatus
& BIT7
) != 0) {
713 DEBUG ((DEBUG_ERROR
, "EmmcSwitchBusTiming: The switch operation fails as DevStatus is 0x%08x\n", DevStatus
));
714 return EFI_DEVICE_ERROR
;
717 if (mOverride
!= NULL
&& mOverride
->NotifyPhase
!= NULL
) {
718 Status
= mOverride
->NotifyPhase (
719 Private
->ControllerHandle
,
721 EdkiiSdMmcSwitchClockFreqPost
,
724 if (EFI_ERROR (Status
)) {
727 "%a: SD/MMC switch clock freq post notifier callback failed - %r\n",
739 Switch to the High Speed timing according to request.
741 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
742 Simplified Spec 3.0 Figure 2-29 for details.
744 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
745 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
746 @param[in] Slot The slot number of the SD card to send the command to.
747 @param[in] Rca The relative device address to be assigned.
748 @param[in] ClockFreq The max clock frequency to be set.
749 @param[in] IsDdr If TRUE, use dual data rate data simpling method. Otherwise
750 use single data rate data simpling method.
751 @param[in] BusWidth The bus width to be set, it could be 4 or 8.
753 @retval EFI_SUCCESS The operation is done correctly.
754 @retval Others The operation fails.
758 EmmcSwitchToHighSpeed (
759 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
760 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
771 SD_MMC_BUS_MODE Timing
;
772 SD_MMC_HC_PRIVATE_DATA
*Private
;
774 Private
= SD_MMC_HC_PRIVATE_FROM_THIS (PassThru
);
776 Status
= EmmcSwitchBusWidth (PciIo
, PassThru
, Slot
, Rca
, IsDdr
, BusWidth
);
777 if (EFI_ERROR (Status
)) {
781 // Set to Hight Speed timing
784 Status
= SdMmcHcOrMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
785 if (EFI_ERROR (Status
)) {
790 Timing
= SdMmcMmcHsDdr
;
791 } else if (ClockFreq
== 52) {
792 Timing
= SdMmcMmcHsSdr
;
794 Timing
= SdMmcMmcLegacy
;
797 Status
= SdMmcHcUhsSignaling (Private
->ControllerHandle
, PciIo
, Slot
, Timing
);
798 if (EFI_ERROR (Status
)) {
803 Status
= EmmcSwitchBusTiming (PciIo
, PassThru
, Slot
, Rca
, HsTiming
, Timing
, ClockFreq
);
809 Switch to the HS200 timing according to request.
811 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
812 Simplified Spec 3.0 Figure 2-29 for details.
814 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
815 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
816 @param[in] Slot The slot number of the SD card to send the command to.
817 @param[in] Rca The relative device address to be assigned.
818 @param[in] ClockFreq The max clock frequency to be set.
819 @param[in] BusWidth The bus width to be set, it could be 4 or 8.
821 @retval EFI_SUCCESS The operation is done correctly.
822 @retval Others The operation fails.
827 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
828 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
838 SD_MMC_BUS_MODE Timing
;
839 SD_MMC_HC_PRIVATE_DATA
*Private
;
841 Private
= SD_MMC_HC_PRIVATE_FROM_THIS (PassThru
);
843 if ((BusWidth
!= 4) && (BusWidth
!= 8)) {
844 return EFI_INVALID_PARAMETER
;
847 Status
= EmmcSwitchBusWidth (PciIo
, PassThru
, Slot
, Rca
, FALSE
, BusWidth
);
848 if (EFI_ERROR (Status
)) {
852 // Set to HS200/SDR104 timing
855 // Stop bus clock at first
857 Status
= SdMmcHcStopClock (PciIo
, Slot
);
858 if (EFI_ERROR (Status
)) {
862 Timing
= SdMmcMmcHs200
;
864 Status
= SdMmcHcUhsSignaling (Private
->ControllerHandle
, PciIo
, Slot
, Timing
);
865 if (EFI_ERROR (Status
)) {
870 // Wait Internal Clock Stable in the Clock Control register to be 1 before set SD Clock Enable bit
872 Status
= SdMmcHcWaitMmioSet (
875 SD_MMC_HC_CLOCK_CTRL
,
879 SD_MMC_HC_GENERIC_TIMEOUT
881 if (EFI_ERROR (Status
)) {
885 // Set SD Clock Enable in the Clock Control register to 1
888 Status
= SdMmcHcOrMmio (PciIo
, Slot
, SD_MMC_HC_CLOCK_CTRL
, sizeof (ClockCtrl
), &ClockCtrl
);
891 Status
= EmmcSwitchBusTiming (PciIo
, PassThru
, Slot
, Rca
, HsTiming
, Timing
, ClockFreq
);
892 if (EFI_ERROR (Status
)) {
896 Status
= EmmcTuningClkForHs200 (PciIo
, PassThru
, Slot
, BusWidth
);
902 Switch to the HS400 timing according to request.
904 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
905 Simplified Spec 3.0 Figure 2-29 for details.
907 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
908 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
909 @param[in] Slot The slot number of the SD card to send the command to.
910 @param[in] Rca The relative device address to be assigned.
911 @param[in] ClockFreq The max clock frequency to be set.
913 @retval EFI_SUCCESS The operation is done correctly.
914 @retval Others The operation fails.
919 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
920 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
928 SD_MMC_BUS_MODE Timing
;
929 SD_MMC_HC_PRIVATE_DATA
*Private
;
931 Private
= SD_MMC_HC_PRIVATE_FROM_THIS (PassThru
);
933 Status
= EmmcSwitchToHS200 (PciIo
, PassThru
, Slot
, Rca
, ClockFreq
, 8);
934 if (EFI_ERROR (Status
)) {
938 // Set to Hight Speed timing and set the clock frequency to a value less than 52MHz.
941 Status
= EmmcSwitchBusTiming (PciIo
, PassThru
, Slot
, Rca
, HsTiming
, SdMmcMmcHsSdr
, 52);
942 if (EFI_ERROR (Status
)) {
946 // HS400 mode must use 8 data lines.
948 Status
= EmmcSwitchBusWidth (PciIo
, PassThru
, Slot
, Rca
, TRUE
, 8);
949 if (EFI_ERROR (Status
)) {
953 Timing
= SdMmcMmcHs400
;
955 Status
= SdMmcHcUhsSignaling (Private
->ControllerHandle
, PciIo
, Slot
, Timing
);
956 if (EFI_ERROR (Status
)) {
961 Status
= EmmcSwitchBusTiming (PciIo
, PassThru
, Slot
, Rca
, HsTiming
, Timing
, ClockFreq
);
967 Switch the high speed timing according to request.
969 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
970 Simplified Spec 3.0 Figure 2-29 for details.
972 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
973 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
974 @param[in] Slot The slot number of the SD card to send the command to.
975 @param[in] Rca The relative device address to be assigned.
977 @retval EFI_SUCCESS The operation is done correctly.
978 @retval Others The operation fails.
983 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
984 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
996 SD_MMC_HC_PRIVATE_DATA
*Private
;
998 Private
= SD_MMC_HC_PRIVATE_FROM_THIS (PassThru
);
1000 Status
= EmmcGetCsd (PassThru
, Slot
, Rca
, &Csd
);
1001 if (EFI_ERROR (Status
)) {
1002 DEBUG ((DEBUG_ERROR
, "EmmcSetBusMode: GetCsd fails with %r\n", Status
));
1006 Status
= EmmcSelect (PassThru
, Slot
, Rca
);
1007 if (EFI_ERROR (Status
)) {
1008 DEBUG ((DEBUG_ERROR
, "EmmcSetBusMode: Select fails with %r\n", Status
));
1012 ASSERT (Private
->BaseClkFreq
[Slot
] != 0);
1014 // Check if the Host Controller support 8bits bus width.
1016 if (Private
->Capability
[Slot
].BusWidth8
!= 0) {
1022 // Get Deivce_Type from EXT_CSD register.
1024 Status
= EmmcGetExtCsd (PassThru
, Slot
, &ExtCsd
);
1025 if (EFI_ERROR (Status
)) {
1026 DEBUG ((DEBUG_ERROR
, "EmmcSetBusMode: GetExtCsd fails with %r\n", Status
));
1030 // Calculate supported bus speed/bus width/clock frequency.
1035 if (((ExtCsd
.DeviceType
& (BIT4
| BIT5
)) != 0) && (Private
->Capability
[Slot
].Sdr104
!= 0)) {
1039 } else if (((ExtCsd
.DeviceType
& (BIT2
| BIT3
)) != 0) && (Private
->Capability
[Slot
].Ddr50
!= 0)) {
1043 } else if (((ExtCsd
.DeviceType
& BIT1
) != 0) && (Private
->Capability
[Slot
].HighSpeed
!= 0)) {
1047 } else if (((ExtCsd
.DeviceType
& BIT0
) != 0) && (Private
->Capability
[Slot
].HighSpeed
!= 0)) {
1053 // Check if both of the device and the host controller support HS400 DDR mode.
1055 if (((ExtCsd
.DeviceType
& (BIT6
| BIT7
)) != 0) && (Private
->Capability
[Slot
].Hs400
!= 0)) {
1057 // The host controller supports 8bits bus.
1059 ASSERT (BusWidth
== 8);
1065 if ((ClockFreq
== 0) || (HsTiming
== 0)) {
1067 // Continue using default setting.
1072 DEBUG ((DEBUG_INFO
, "EmmcSetBusMode: HsTiming %d ClockFreq %d BusWidth %d Ddr %a\n", HsTiming
, ClockFreq
, BusWidth
, IsDdr
? "TRUE":"FALSE"));
1074 if (HsTiming
== 3) {
1076 // Execute HS400 timing switch procedure
1078 Status
= EmmcSwitchToHS400 (PciIo
, PassThru
, Slot
, Rca
, ClockFreq
);
1079 } else if (HsTiming
== 2) {
1081 // Execute HS200 timing switch procedure
1083 Status
= EmmcSwitchToHS200 (PciIo
, PassThru
, Slot
, Rca
, ClockFreq
, BusWidth
);
1086 // Execute High Speed timing switch procedure
1088 Status
= EmmcSwitchToHighSpeed (PciIo
, PassThru
, Slot
, Rca
, ClockFreq
, IsDdr
, BusWidth
);
1091 DEBUG ((DEBUG_INFO
, "EmmcSetBusMode: Switch to %a %r\n", (HsTiming
== 3) ? "HS400" : ((HsTiming
== 2) ? "HS200" : "HighSpeed"), Status
));
1097 Execute EMMC device identification procedure.
1099 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
1101 @param[in] Private A pointer to the SD_MMC_HC_PRIVATE_DATA instance.
1102 @param[in] Slot The slot number of the SD card to send the command to.
1104 @retval EFI_SUCCESS There is a EMMC card.
1105 @retval Others There is not a EMMC card.
1109 EmmcIdentification (
1110 IN SD_MMC_HC_PRIVATE_DATA
*Private
,
1115 EFI_PCI_IO_PROTOCOL
*PciIo
;
1116 EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
;
1121 PciIo
= Private
->PciIo
;
1122 PassThru
= &Private
->PassThru
;
1124 Status
= EmmcReset (PassThru
, Slot
);
1125 if (EFI_ERROR (Status
)) {
1126 DEBUG ((DEBUG_VERBOSE
, "EmmcIdentification: Executing Cmd0 fails with %r\n", Status
));
1133 Status
= EmmcGetOcr (PassThru
, Slot
, &Ocr
);
1134 if (EFI_ERROR (Status
)) {
1135 DEBUG ((DEBUG_VERBOSE
, "EmmcIdentification: Executing Cmd1 fails with %r\n", Status
));
1140 if (Retry
++ == 100) {
1141 DEBUG ((DEBUG_VERBOSE
, "EmmcIdentification: Executing Cmd1 fails too many times\n"));
1142 return EFI_DEVICE_ERROR
;
1144 gBS
->Stall(10 * 1000);
1145 } while ((Ocr
& BIT31
) == 0);
1147 Status
= EmmcGetAllCid (PassThru
, Slot
);
1148 if (EFI_ERROR (Status
)) {
1149 DEBUG ((DEBUG_VERBOSE
, "EmmcIdentification: Executing Cmd2 fails with %r\n", Status
));
1153 // Slot starts from 0 and valid RCA starts from 1.
1154 // Here we takes a simple formula to calculate the RCA.
1155 // Don't support multiple devices on the slot, that is
1156 // shared bus slot feature.
1159 Status
= EmmcSetRca (PassThru
, Slot
, Rca
);
1160 if (EFI_ERROR (Status
)) {
1161 DEBUG ((DEBUG_ERROR
, "EmmcIdentification: Executing Cmd3 fails with %r\n", Status
));
1165 // Enter Data Tranfer Mode.
1167 DEBUG ((DEBUG_INFO
, "EmmcIdentification: Found a EMMC device at slot [%d], RCA [%d]\n", Slot
, Rca
));
1168 Private
->Slot
[Slot
].CardType
= EmmcCardType
;
1170 Status
= EmmcSetBusMode (PciIo
, PassThru
, Slot
, Rca
);