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 clock frequency to the specified value.
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 EmmcSwitchClockFreq (
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
, "EmmcSwitchClockFreq: Switch to hstiming %d fails with %r\n", HsTiming
, Status
));
696 Status
= EmmcSendStatus (PassThru
, Slot
, Rca
, &DevStatus
);
697 if (EFI_ERROR (Status
)) {
698 DEBUG ((DEBUG_ERROR
, "EmmcSwitchClockFreq: Send status fails with %r\n", Status
));
702 // Check the switch operation is really successful or not.
704 if ((DevStatus
& BIT7
) != 0) {
705 DEBUG ((DEBUG_ERROR
, "EmmcSwitchClockFreq: The switch operation fails as DevStatus is 0x%08x\n", DevStatus
));
706 return EFI_DEVICE_ERROR
;
709 // Convert the clock freq unit from MHz to KHz.
711 Status
= SdMmcHcClockSupply (PciIo
, Slot
, ClockFreq
* 1000, Private
->BaseClkFreq
[Slot
], Private
->ControllerVersion
[Slot
]);
712 if (EFI_ERROR (Status
)) {
716 if (mOverride
!= NULL
&& mOverride
->NotifyPhase
!= NULL
) {
717 Status
= mOverride
->NotifyPhase (
718 Private
->ControllerHandle
,
720 EdkiiSdMmcSwitchClockFreqPost
,
723 if (EFI_ERROR (Status
)) {
726 "%a: SD/MMC switch clock freq post notifier callback failed - %r\n",
738 Switch to the High Speed timing according to request.
740 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
741 Simplified Spec 3.0 Figure 2-29 for details.
743 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
744 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
745 @param[in] Slot The slot number of the SD card to send the command to.
746 @param[in] Rca The relative device address to be assigned.
747 @param[in] ClockFreq The max clock frequency to be set.
748 @param[in] IsDdr If TRUE, use dual data rate data simpling method. Otherwise
749 use single data rate data simpling method.
750 @param[in] BusWidth The bus width to be set, it could be 4 or 8.
752 @retval EFI_SUCCESS The operation is done correctly.
753 @retval Others The operation fails.
757 EmmcSwitchToHighSpeed (
758 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
759 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
770 SD_MMC_BUS_MODE Timing
;
771 SD_MMC_HC_PRIVATE_DATA
*Private
;
773 Private
= SD_MMC_HC_PRIVATE_FROM_THIS (PassThru
);
775 Status
= EmmcSwitchBusWidth (PciIo
, PassThru
, Slot
, Rca
, IsDdr
, BusWidth
);
776 if (EFI_ERROR (Status
)) {
780 // Set to Hight Speed timing
783 Status
= SdMmcHcOrMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
784 if (EFI_ERROR (Status
)) {
789 Timing
= SdMmcMmcHsDdr
;
790 } else if (ClockFreq
== 52) {
791 Timing
= SdMmcMmcHsSdr
;
793 Timing
= SdMmcMmcLegacy
;
796 Status
= SdMmcHcUhsSignaling (Private
->ControllerHandle
, PciIo
, Slot
, Timing
);
797 if (EFI_ERROR (Status
)) {
802 Status
= EmmcSwitchClockFreq (PciIo
, PassThru
, Slot
, Rca
, HsTiming
, Timing
, ClockFreq
);
808 Switch to the HS200 timing according to request.
810 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
811 Simplified Spec 3.0 Figure 2-29 for details.
813 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
814 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
815 @param[in] Slot The slot number of the SD card to send the command to.
816 @param[in] Rca The relative device address to be assigned.
817 @param[in] ClockFreq The max clock frequency to be set.
818 @param[in] BusWidth The bus width to be set, it could be 4 or 8.
820 @retval EFI_SUCCESS The operation is done correctly.
821 @retval Others The operation fails.
826 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
827 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
837 SD_MMC_BUS_MODE Timing
;
838 SD_MMC_HC_PRIVATE_DATA
*Private
;
840 Private
= SD_MMC_HC_PRIVATE_FROM_THIS (PassThru
);
842 if ((BusWidth
!= 4) && (BusWidth
!= 8)) {
843 return EFI_INVALID_PARAMETER
;
846 Status
= EmmcSwitchBusWidth (PciIo
, PassThru
, Slot
, Rca
, FALSE
, BusWidth
);
847 if (EFI_ERROR (Status
)) {
851 // Set to HS200/SDR104 timing
854 // Stop bus clock at first
856 Status
= SdMmcHcStopClock (PciIo
, Slot
);
857 if (EFI_ERROR (Status
)) {
861 Timing
= SdMmcMmcHs200
;
863 Status
= SdMmcHcUhsSignaling (Private
->ControllerHandle
, PciIo
, Slot
, Timing
);
864 if (EFI_ERROR (Status
)) {
869 // Wait Internal Clock Stable in the Clock Control register to be 1 before set SD Clock Enable bit
871 Status
= SdMmcHcWaitMmioSet (
874 SD_MMC_HC_CLOCK_CTRL
,
878 SD_MMC_HC_GENERIC_TIMEOUT
880 if (EFI_ERROR (Status
)) {
884 // Set SD Clock Enable in the Clock Control register to 1
887 Status
= SdMmcHcOrMmio (PciIo
, Slot
, SD_MMC_HC_CLOCK_CTRL
, sizeof (ClockCtrl
), &ClockCtrl
);
890 Status
= EmmcSwitchClockFreq (PciIo
, PassThru
, Slot
, Rca
, HsTiming
, Timing
, ClockFreq
);
891 if (EFI_ERROR (Status
)) {
895 Status
= EmmcTuningClkForHs200 (PciIo
, PassThru
, Slot
, BusWidth
);
901 Switch to the HS400 timing according to request.
903 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
904 Simplified Spec 3.0 Figure 2-29 for details.
906 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
907 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
908 @param[in] Slot The slot number of the SD card to send the command to.
909 @param[in] Rca The relative device address to be assigned.
910 @param[in] ClockFreq The max clock frequency to be set.
912 @retval EFI_SUCCESS The operation is done correctly.
913 @retval Others The operation fails.
918 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
919 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
927 SD_MMC_BUS_MODE Timing
;
928 SD_MMC_HC_PRIVATE_DATA
*Private
;
930 Private
= SD_MMC_HC_PRIVATE_FROM_THIS (PassThru
);
932 Status
= EmmcSwitchToHS200 (PciIo
, PassThru
, Slot
, Rca
, ClockFreq
, 8);
933 if (EFI_ERROR (Status
)) {
937 // Set to Hight Speed timing and set the clock frequency to a value less than 52MHz.
940 Status
= EmmcSwitchClockFreq (PciIo
, PassThru
, Slot
, Rca
, HsTiming
, SdMmcMmcHsSdr
, 52);
941 if (EFI_ERROR (Status
)) {
945 // HS400 mode must use 8 data lines.
947 Status
= EmmcSwitchBusWidth (PciIo
, PassThru
, Slot
, Rca
, TRUE
, 8);
948 if (EFI_ERROR (Status
)) {
952 Timing
= SdMmcMmcHs400
;
954 Status
= SdMmcHcUhsSignaling (Private
->ControllerHandle
, PciIo
, Slot
, Timing
);
955 if (EFI_ERROR (Status
)) {
960 Status
= EmmcSwitchClockFreq (PciIo
, PassThru
, Slot
, Rca
, HsTiming
, Timing
, ClockFreq
);
966 Switch the high speed timing according to request.
968 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
969 Simplified Spec 3.0 Figure 2-29 for details.
971 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
972 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
973 @param[in] Slot The slot number of the SD card to send the command to.
974 @param[in] Rca The relative device address to be assigned.
976 @retval EFI_SUCCESS The operation is done correctly.
977 @retval Others The operation fails.
982 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
983 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
995 SD_MMC_HC_PRIVATE_DATA
*Private
;
997 Private
= SD_MMC_HC_PRIVATE_FROM_THIS (PassThru
);
999 Status
= EmmcGetCsd (PassThru
, Slot
, Rca
, &Csd
);
1000 if (EFI_ERROR (Status
)) {
1001 DEBUG ((DEBUG_ERROR
, "EmmcSetBusMode: GetCsd fails with %r\n", Status
));
1005 Status
= EmmcSelect (PassThru
, Slot
, Rca
);
1006 if (EFI_ERROR (Status
)) {
1007 DEBUG ((DEBUG_ERROR
, "EmmcSetBusMode: Select fails with %r\n", Status
));
1011 ASSERT (Private
->BaseClkFreq
[Slot
] != 0);
1013 // Check if the Host Controller support 8bits bus width.
1015 if (Private
->Capability
[Slot
].BusWidth8
!= 0) {
1021 // Get Deivce_Type from EXT_CSD register.
1023 Status
= EmmcGetExtCsd (PassThru
, Slot
, &ExtCsd
);
1024 if (EFI_ERROR (Status
)) {
1025 DEBUG ((DEBUG_ERROR
, "EmmcSetBusMode: GetExtCsd fails with %r\n", Status
));
1029 // Calculate supported bus speed/bus width/clock frequency.
1034 if (((ExtCsd
.DeviceType
& (BIT4
| BIT5
)) != 0) && (Private
->Capability
[Slot
].Sdr104
!= 0)) {
1038 } else if (((ExtCsd
.DeviceType
& (BIT2
| BIT3
)) != 0) && (Private
->Capability
[Slot
].Ddr50
!= 0)) {
1042 } else if (((ExtCsd
.DeviceType
& BIT1
) != 0) && (Private
->Capability
[Slot
].HighSpeed
!= 0)) {
1046 } else if (((ExtCsd
.DeviceType
& BIT0
) != 0) && (Private
->Capability
[Slot
].HighSpeed
!= 0)) {
1052 // Check if both of the device and the host controller support HS400 DDR mode.
1054 if (((ExtCsd
.DeviceType
& (BIT6
| BIT7
)) != 0) && (Private
->Capability
[Slot
].Hs400
!= 0)) {
1056 // The host controller supports 8bits bus.
1058 ASSERT (BusWidth
== 8);
1064 if ((ClockFreq
== 0) || (HsTiming
== 0)) {
1066 // Continue using default setting.
1071 DEBUG ((DEBUG_INFO
, "EmmcSetBusMode: HsTiming %d ClockFreq %d BusWidth %d Ddr %a\n", HsTiming
, ClockFreq
, BusWidth
, IsDdr
? "TRUE":"FALSE"));
1073 if (HsTiming
== 3) {
1075 // Execute HS400 timing switch procedure
1077 Status
= EmmcSwitchToHS400 (PciIo
, PassThru
, Slot
, Rca
, ClockFreq
);
1078 } else if (HsTiming
== 2) {
1080 // Execute HS200 timing switch procedure
1082 Status
= EmmcSwitchToHS200 (PciIo
, PassThru
, Slot
, Rca
, ClockFreq
, BusWidth
);
1085 // Execute High Speed timing switch procedure
1087 Status
= EmmcSwitchToHighSpeed (PciIo
, PassThru
, Slot
, Rca
, ClockFreq
, IsDdr
, BusWidth
);
1090 DEBUG ((DEBUG_INFO
, "EmmcSetBusMode: Switch to %a %r\n", (HsTiming
== 3) ? "HS400" : ((HsTiming
== 2) ? "HS200" : "HighSpeed"), Status
));
1096 Execute EMMC device identification procedure.
1098 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
1100 @param[in] Private A pointer to the SD_MMC_HC_PRIVATE_DATA instance.
1101 @param[in] Slot The slot number of the SD card to send the command to.
1103 @retval EFI_SUCCESS There is a EMMC card.
1104 @retval Others There is not a EMMC card.
1108 EmmcIdentification (
1109 IN SD_MMC_HC_PRIVATE_DATA
*Private
,
1114 EFI_PCI_IO_PROTOCOL
*PciIo
;
1115 EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
;
1120 PciIo
= Private
->PciIo
;
1121 PassThru
= &Private
->PassThru
;
1123 Status
= EmmcReset (PassThru
, Slot
);
1124 if (EFI_ERROR (Status
)) {
1125 DEBUG ((DEBUG_VERBOSE
, "EmmcIdentification: Executing Cmd0 fails with %r\n", Status
));
1132 Status
= EmmcGetOcr (PassThru
, Slot
, &Ocr
);
1133 if (EFI_ERROR (Status
)) {
1134 DEBUG ((DEBUG_VERBOSE
, "EmmcIdentification: Executing Cmd1 fails with %r\n", Status
));
1139 if (Retry
++ == 100) {
1140 DEBUG ((DEBUG_VERBOSE
, "EmmcIdentification: Executing Cmd1 fails too many times\n"));
1141 return EFI_DEVICE_ERROR
;
1143 gBS
->Stall(10 * 1000);
1144 } while ((Ocr
& BIT31
) == 0);
1146 Status
= EmmcGetAllCid (PassThru
, Slot
);
1147 if (EFI_ERROR (Status
)) {
1148 DEBUG ((DEBUG_VERBOSE
, "EmmcIdentification: Executing Cmd2 fails with %r\n", Status
));
1152 // Slot starts from 0 and valid RCA starts from 1.
1153 // Here we takes a simple formula to calculate the RCA.
1154 // Don't support multiple devices on the slot, that is
1155 // shared bus slot feature.
1158 Status
= EmmcSetRca (PassThru
, Slot
, Rca
);
1159 if (EFI_ERROR (Status
)) {
1160 DEBUG ((DEBUG_ERROR
, "EmmcIdentification: Executing Cmd3 fails with %r\n", Status
));
1164 // Enter Data Tranfer Mode.
1166 DEBUG ((DEBUG_INFO
, "EmmcIdentification: Found a EMMC device at slot [%d], RCA [%d]\n", Slot
, Rca
));
1167 Private
->Slot
[Slot
].CardType
= EmmcCardType
;
1169 Status
= EmmcSetBusMode (PciIo
, PassThru
, Slot
, Rca
);