2 This file provides some helper functions which are specific for EMMC device.
4 Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "SdMmcPciHcDxe.h"
18 Send command GO_IDLE_STATE (CMD0 with argument of 0x00000000) to the device to
19 make it go to Idle State.
21 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
23 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
24 @param[in] Slot The slot number of the SD card to send the command to.
26 @retval EFI_SUCCESS The EMMC device is reset correctly.
27 @retval Others The device reset fails.
32 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
36 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
37 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
38 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
41 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
42 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
43 ZeroMem (&Packet
, sizeof (Packet
));
45 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
46 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
47 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
49 SdMmcCmdBlk
.CommandIndex
= EMMC_GO_IDLE_STATE
;
50 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeBc
;
51 SdMmcCmdBlk
.ResponseType
= 0;
52 SdMmcCmdBlk
.CommandArgument
= 0;
56 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
62 Send command SEND_OP_COND to the EMMC device to get the data of the OCR register.
64 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
66 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
67 @param[in] Slot The slot number of the SD card to send the command to.
68 @param[in, out] Argument On input, the argument of SEND_OP_COND is to send to the device.
69 On output, the argument is the value of OCR register.
71 @retval EFI_SUCCESS The operation is done correctly.
72 @retval Others The operation fails.
77 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
79 IN OUT UINT32
*Argument
82 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
83 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
84 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
87 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
88 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
89 ZeroMem (&Packet
, sizeof (Packet
));
91 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
92 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
93 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
95 SdMmcCmdBlk
.CommandIndex
= EMMC_SEND_OP_COND
;
96 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeBcr
;
97 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR3
;
98 SdMmcCmdBlk
.CommandArgument
= *Argument
;
100 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
101 if (!EFI_ERROR (Status
)) {
103 // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12.
105 *Argument
= SdMmcStatusBlk
.Resp0
;
112 Broadcast command ALL_SEND_CID to the bus to ask all the EMMC devices to send the
113 data of their CID registers.
115 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
117 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
118 @param[in] Slot The slot number of the SD card to send the command to.
120 @retval EFI_SUCCESS The operation is done correctly.
121 @retval Others The operation fails.
126 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
130 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
131 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
132 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
135 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
136 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
137 ZeroMem (&Packet
, sizeof (Packet
));
139 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
140 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
141 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
143 SdMmcCmdBlk
.CommandIndex
= EMMC_ALL_SEND_CID
;
144 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeBcr
;
145 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR2
;
146 SdMmcCmdBlk
.CommandArgument
= 0;
148 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
154 Send command SET_RELATIVE_ADDR to the EMMC device to assign a Relative device
157 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
159 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
160 @param[in] Slot The slot number of the SD card to send the command to.
161 @param[in] Rca The relative device address to be assigned.
163 @retval EFI_SUCCESS The operation is done correctly.
164 @retval Others The operation fails.
169 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
174 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
175 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
176 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
179 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
180 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
181 ZeroMem (&Packet
, sizeof (Packet
));
183 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
184 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
185 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
187 SdMmcCmdBlk
.CommandIndex
= EMMC_SET_RELATIVE_ADDR
;
188 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
189 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
190 SdMmcCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
192 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
198 Send command SEND_CSD to the EMMC device to get the data of the CSD register.
200 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
202 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
203 @param[in] Slot The slot number of the SD card to send the command to.
204 @param[in] Rca The relative device address of selected device.
205 @param[out] Csd The buffer to store the content of the CSD register.
206 Note the caller should ignore the lowest byte of this
207 buffer as the content of this byte is meaningless even
208 if the operation succeeds.
210 @retval EFI_SUCCESS The operation is done correctly.
211 @retval Others The operation fails.
216 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
222 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
223 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
224 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
227 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
228 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
229 ZeroMem (&Packet
, sizeof (Packet
));
231 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
232 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
233 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
235 SdMmcCmdBlk
.CommandIndex
= EMMC_SEND_CSD
;
236 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
237 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR2
;
238 SdMmcCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
240 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
241 if (!EFI_ERROR (Status
)) {
243 // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12.
245 CopyMem (((UINT8
*)Csd
) + 1, &SdMmcStatusBlk
.Resp0
, sizeof (EMMC_CSD
) - 1);
252 Send command SELECT_DESELECT_CARD to the EMMC device to select/deselect it.
254 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
256 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
257 @param[in] Slot The slot number of the SD card to send the command to.
258 @param[in] Rca The relative device address of selected device.
260 @retval EFI_SUCCESS The operation is done correctly.
261 @retval Others The operation fails.
266 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
271 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
272 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
273 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
276 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
277 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
278 ZeroMem (&Packet
, sizeof (Packet
));
280 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
281 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
282 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
284 SdMmcCmdBlk
.CommandIndex
= EMMC_SELECT_DESELECT_CARD
;
285 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
286 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
287 SdMmcCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
289 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
295 Send command SEND_EXT_CSD to the EMMC device to get the data of the EXT_CSD register.
297 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
299 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
300 @param[in] Slot The slot number of the SD card to send the command to.
301 @param[out] ExtCsd The buffer to store the content of the EXT_CSD register.
303 @retval EFI_SUCCESS The operation is done correctly.
304 @retval Others The operation fails.
309 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
311 OUT EMMC_EXT_CSD
*ExtCsd
314 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
315 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
316 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
319 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
320 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
321 ZeroMem (&Packet
, sizeof (Packet
));
323 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
324 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
325 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
327 SdMmcCmdBlk
.CommandIndex
= EMMC_SEND_EXT_CSD
;
328 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAdtc
;
329 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
330 SdMmcCmdBlk
.CommandArgument
= 0x00000000;
332 Packet
.InDataBuffer
= ExtCsd
;
333 Packet
.InTransferLength
= sizeof (EMMC_EXT_CSD
);
335 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
340 Send command SWITCH to the EMMC device to switch the mode of operation of the
341 selected Device or modifies the EXT_CSD registers.
343 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
345 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
346 @param[in] Slot The slot number of the SD card to send the command to.
347 @param[in] Access The access mode of SWTICH command.
348 @param[in] Index The offset of the field to be access.
349 @param[in] Value The value to be set to the specified field of EXT_CSD register.
350 @param[in] CmdSet The value of CmdSet field of EXT_CSD register.
352 @retval EFI_SUCCESS The operation is done correctly.
353 @retval Others The operation fails.
358 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
366 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
367 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
368 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
371 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
372 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
373 ZeroMem (&Packet
, sizeof (Packet
));
375 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
376 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
377 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
379 SdMmcCmdBlk
.CommandIndex
= EMMC_SWITCH
;
380 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
381 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1b
;
382 SdMmcCmdBlk
.CommandArgument
= (Access
<< 24) | (Index
<< 16) | (Value
<< 8) | CmdSet
;
384 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
390 Send command SEND_STATUS to the addressed EMMC device to get its status register.
392 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
394 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
395 @param[in] Slot The slot number of the SD card to send the command to.
396 @param[in] Rca The relative device address of addressed device.
397 @param[out] DevStatus The returned device status.
399 @retval EFI_SUCCESS The operation is done correctly.
400 @retval Others The operation fails.
405 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
408 OUT UINT32
*DevStatus
411 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
412 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
413 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
416 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
417 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
418 ZeroMem (&Packet
, sizeof (Packet
));
420 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
421 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
422 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
424 SdMmcCmdBlk
.CommandIndex
= EMMC_SEND_STATUS
;
425 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
426 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
427 SdMmcCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
429 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
430 if (!EFI_ERROR (Status
)) {
431 *DevStatus
= SdMmcStatusBlk
.Resp0
;
438 Send command SEND_TUNING_BLOCK to the EMMC device for HS200 optimal sampling point
441 It may be sent up to 40 times until the host finishes the tuning procedure.
443 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 for details.
445 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
446 @param[in] Slot The slot number of the SD card to send the command to.
447 @param[in] BusWidth The bus width to work.
449 @retval EFI_SUCCESS The operation is done correctly.
450 @retval Others The operation fails.
455 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
460 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
461 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
462 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
464 UINT8 TuningBlock
[128];
466 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
467 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
468 ZeroMem (&Packet
, sizeof (Packet
));
470 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
471 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
472 Packet
.Timeout
= SD_MMC_HC_GENERIC_TIMEOUT
;
474 SdMmcCmdBlk
.CommandIndex
= EMMC_SEND_TUNING_BLOCK
;
475 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAdtc
;
476 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
477 SdMmcCmdBlk
.CommandArgument
= 0;
479 Packet
.InDataBuffer
= TuningBlock
;
481 Packet
.InTransferLength
= sizeof (TuningBlock
);
483 Packet
.InTransferLength
= 64;
486 Status
= SdMmcPassThruPassThru (PassThru
, Slot
, &Packet
, NULL
);
492 Tunning the clock to get HS200 optimal sampling point.
494 Command SEND_TUNING_BLOCK may be sent up to 40 times until the host finishes the
497 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
498 Simplified Spec 3.0 Figure 2-29 for details.
500 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
501 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
502 @param[in] Slot The slot number of the SD card to send the command to.
503 @param[in] BusWidth The bus width to work.
505 @retval EFI_SUCCESS The operation is done correctly.
506 @retval Others The operation fails.
510 EmmcTuningClkForHs200 (
511 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
512 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
522 // Notify the host that the sampling clock tuning procedure starts.
525 Status
= SdMmcHcOrMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
526 if (EFI_ERROR (Status
)) {
530 // Ask the device to send a sequence of tuning blocks till the tuning procedure is done.
534 Status
= EmmcSendTuningBlk (PassThru
, Slot
, BusWidth
);
535 if (EFI_ERROR (Status
)) {
536 DEBUG ((DEBUG_ERROR
, "EmmcTuningClkForHs200: Send tuning block fails with %r\n", Status
));
540 Status
= SdMmcHcRwMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, TRUE
, sizeof (HostCtrl2
), &HostCtrl2
);
541 if (EFI_ERROR (Status
)) {
545 if ((HostCtrl2
& (BIT6
| BIT7
)) == 0) {
549 if ((HostCtrl2
& (BIT6
| BIT7
)) == BIT7
) {
552 } while (++Retry
< 40);
554 DEBUG ((DEBUG_ERROR
, "EmmcTuningClkForHs200: Send tuning block fails at %d times with HostCtrl2 %02x\n", Retry
, HostCtrl2
));
556 // Abort the tuning procedure and reset the tuning circuit.
558 HostCtrl2
= (UINT8
)~(BIT6
| BIT7
);
559 Status
= SdMmcHcAndMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
560 if (EFI_ERROR (Status
)) {
563 return EFI_DEVICE_ERROR
;
567 Switch the bus width to specified width.
569 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.9 and SD Host Controller
570 Simplified Spec 3.0 Figure 3-7 for details.
572 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
573 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
574 @param[in] Slot The slot number of the SD card to send the command to.
575 @param[in] Rca The relative device address to be assigned.
576 @param[in] IsDdr If TRUE, use dual data rate data simpling method. Otherwise
577 use single data rate data simpling method.
578 @param[in] BusWidth The bus width to be set, it could be 4 or 8.
580 @retval EFI_SUCCESS The operation is done correctly.
581 @retval Others The operation fails.
586 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
587 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
602 // Write Byte, the Value field is written into the byte pointed by Index.
605 Index
= OFFSET_OF (EMMC_EXT_CSD
, BusWidth
);
608 } else if (BusWidth
== 8) {
611 return EFI_INVALID_PARAMETER
;
619 Status
= EmmcSwitch (PassThru
, Slot
, Access
, Index
, Value
, CmdSet
);
620 if (EFI_ERROR (Status
)) {
621 DEBUG ((DEBUG_ERROR
, "EmmcSwitchBusWidth: Switch to bus width %d fails with %r\n", BusWidth
, Status
));
625 Status
= EmmcSendStatus (PassThru
, Slot
, Rca
, &DevStatus
);
626 if (EFI_ERROR (Status
)) {
627 DEBUG ((DEBUG_ERROR
, "EmmcSwitchBusWidth: Send status fails with %r\n", Status
));
631 // Check the switch operation is really successful or not.
633 if ((DevStatus
& BIT7
) != 0) {
634 DEBUG ((DEBUG_ERROR
, "EmmcSwitchBusWidth: The switch operation fails as DevStatus is 0x%08x\n", DevStatus
));
635 return EFI_DEVICE_ERROR
;
638 Status
= SdMmcHcSetBusWidth (PciIo
, Slot
, BusWidth
);
644 Switch the clock frequency to the specified value.
646 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6 and SD Host Controller
647 Simplified Spec 3.0 Figure 3-3 for details.
649 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
650 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
651 @param[in] Slot The slot number of the SD card to send the command to.
652 @param[in] Rca The relative device address to be assigned.
653 @param[in] HsTiming The value to be written to HS_TIMING field of EXT_CSD register.
654 @param[in] ClockFreq The max clock frequency to be set, the unit is MHz.
656 @retval EFI_SUCCESS The operation is done correctly.
657 @retval Others The operation fails.
661 EmmcSwitchClockFreq (
662 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
663 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
676 SD_MMC_HC_PRIVATE_DATA
*Private
;
678 Private
= SD_MMC_HC_PRIVATE_FROM_THIS (PassThru
);
680 // Write Byte, the Value field is written into the byte pointed by Index.
683 Index
= OFFSET_OF (EMMC_EXT_CSD
, HsTiming
);
687 Status
= EmmcSwitch (PassThru
, Slot
, Access
, Index
, Value
, CmdSet
);
688 if (EFI_ERROR (Status
)) {
689 DEBUG ((DEBUG_ERROR
, "EmmcSwitchClockFreq: Switch to hstiming %d fails with %r\n", HsTiming
, Status
));
693 Status
= EmmcSendStatus (PassThru
, Slot
, Rca
, &DevStatus
);
694 if (EFI_ERROR (Status
)) {
695 DEBUG ((DEBUG_ERROR
, "EmmcSwitchClockFreq: Send status fails with %r\n", Status
));
699 // Check the switch operation is really successful or not.
701 if ((DevStatus
& BIT7
) != 0) {
702 DEBUG ((DEBUG_ERROR
, "EmmcSwitchClockFreq: The switch operation fails as DevStatus is 0x%08x\n", DevStatus
));
703 return EFI_DEVICE_ERROR
;
706 // Convert the clock freq unit from MHz to KHz.
708 Status
= SdMmcHcClockSupply (PciIo
, Slot
, ClockFreq
* 1000, Private
->Capability
[Slot
]);
714 Switch to the High Speed timing according to request.
716 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
717 Simplified Spec 3.0 Figure 2-29 for details.
719 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
720 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
721 @param[in] Slot The slot number of the SD card to send the command to.
722 @param[in] Rca The relative device address to be assigned.
723 @param[in] ClockFreq The max clock frequency to be set.
724 @param[in] IsDdr If TRUE, use dual data rate data simpling method. Otherwise
725 use single data rate data simpling method.
726 @param[in] BusWidth The bus width to be set, it could be 4 or 8.
728 @retval EFI_SUCCESS The operation is done correctly.
729 @retval Others The operation fails.
733 EmmcSwitchToHighSpeed (
734 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
735 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
748 Status
= EmmcSwitchBusWidth (PciIo
, PassThru
, Slot
, Rca
, IsDdr
, BusWidth
);
749 if (EFI_ERROR (Status
)) {
753 // Set to Hight Speed timing
756 Status
= SdMmcHcOrMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
757 if (EFI_ERROR (Status
)) {
762 // Clean UHS Mode Select field of Host Control 2 reigster before update
764 HostCtrl2
= (UINT8
)~0x7;
765 Status
= SdMmcHcAndMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
766 if (EFI_ERROR (Status
)) {
770 // Set UHS Mode Select field of Host Control 2 reigster to SDR12/25/50
774 } else if (ClockFreq
== 52) {
779 Status
= SdMmcHcOrMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
780 if (EFI_ERROR (Status
)) {
785 Status
= EmmcSwitchClockFreq (PciIo
, PassThru
, Slot
, Rca
, HsTiming
, ClockFreq
);
791 Switch to the HS200 timing according to request.
793 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
794 Simplified Spec 3.0 Figure 2-29 for details.
796 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
797 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
798 @param[in] Slot The slot number of the SD card to send the command to.
799 @param[in] Rca The relative device address to be assigned.
800 @param[in] ClockFreq The max clock frequency to be set.
801 @param[in] BusWidth The bus width to be set, it could be 4 or 8.
803 @retval EFI_SUCCESS The operation is done correctly.
804 @retval Others The operation fails.
809 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
810 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
822 if ((BusWidth
!= 4) && (BusWidth
!= 8)) {
823 return EFI_INVALID_PARAMETER
;
826 Status
= EmmcSwitchBusWidth (PciIo
, PassThru
, Slot
, Rca
, FALSE
, BusWidth
);
827 if (EFI_ERROR (Status
)) {
831 // Set to HS200/SDR104 timing
834 // Stop bus clock at first
836 Status
= SdMmcHcStopClock (PciIo
, Slot
);
837 if (EFI_ERROR (Status
)) {
841 // Clean UHS Mode Select field of Host Control 2 reigster before update
843 HostCtrl2
= (UINT8
)~0x7;
844 Status
= SdMmcHcAndMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
845 if (EFI_ERROR (Status
)) {
849 // Set UHS Mode Select field of Host Control 2 reigster to SDR104
851 HostCtrl2
= BIT0
| BIT1
;
852 Status
= SdMmcHcOrMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
853 if (EFI_ERROR (Status
)) {
857 // Wait Internal Clock Stable in the Clock Control register to be 1 before set SD Clock Enable bit
859 Status
= SdMmcHcWaitMmioSet (
862 SD_MMC_HC_CLOCK_CTRL
,
866 SD_MMC_HC_GENERIC_TIMEOUT
868 if (EFI_ERROR (Status
)) {
872 // Set SD Clock Enable in the Clock Control register to 1
875 Status
= SdMmcHcOrMmio (PciIo
, Slot
, SD_MMC_HC_CLOCK_CTRL
, sizeof (ClockCtrl
), &ClockCtrl
);
878 Status
= EmmcSwitchClockFreq (PciIo
, PassThru
, Slot
, Rca
, HsTiming
, ClockFreq
);
879 if (EFI_ERROR (Status
)) {
883 Status
= EmmcTuningClkForHs200 (PciIo
, PassThru
, Slot
, BusWidth
);
889 Switch to the HS400 timing according to request.
891 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
892 Simplified Spec 3.0 Figure 2-29 for details.
894 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
895 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
896 @param[in] Slot The slot number of the SD card to send the command to.
897 @param[in] Rca The relative device address to be assigned.
898 @param[in] ClockFreq The max clock frequency to be set.
900 @retval EFI_SUCCESS The operation is done correctly.
901 @retval Others The operation fails.
906 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
907 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
917 Status
= EmmcSwitchToHS200 (PciIo
, PassThru
, Slot
, Rca
, ClockFreq
, 8);
918 if (EFI_ERROR (Status
)) {
922 // Set to Hight Speed timing and set the clock frequency to a value less than 52MHz.
925 Status
= EmmcSwitchClockFreq (PciIo
, PassThru
, Slot
, Rca
, HsTiming
, 52);
926 if (EFI_ERROR (Status
)) {
930 // HS400 mode must use 8 data lines.
932 Status
= EmmcSwitchBusWidth (PciIo
, PassThru
, Slot
, Rca
, TRUE
, 8);
933 if (EFI_ERROR (Status
)) {
937 // Clean UHS Mode Select field of Host Control 2 reigster before update
939 HostCtrl2
= (UINT8
)~0x7;
940 Status
= SdMmcHcAndMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
941 if (EFI_ERROR (Status
)) {
945 // Set UHS Mode Select field of Host Control 2 reigster to HS400
947 HostCtrl2
= BIT0
| BIT2
;
948 Status
= SdMmcHcOrMmio (PciIo
, Slot
, SD_MMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
949 if (EFI_ERROR (Status
)) {
954 Status
= EmmcSwitchClockFreq (PciIo
, PassThru
, Slot
, Rca
, HsTiming
, ClockFreq
);
960 Switch the high speed timing according to request.
962 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
963 Simplified Spec 3.0 Figure 2-29 for details.
965 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
966 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
967 @param[in] Slot The slot number of the SD card to send the command to.
968 @param[in] Rca The relative device address to be assigned.
970 @retval EFI_SUCCESS The operation is done correctly.
971 @retval Others The operation fails.
976 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
977 IN EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
,
989 SD_MMC_HC_PRIVATE_DATA
*Private
;
991 Private
= SD_MMC_HC_PRIVATE_FROM_THIS (PassThru
);
993 Status
= EmmcGetCsd (PassThru
, Slot
, Rca
, &Csd
);
994 if (EFI_ERROR (Status
)) {
995 DEBUG ((DEBUG_ERROR
, "EmmcSetBusMode: GetCsd fails with %r\n", Status
));
999 Status
= EmmcSelect (PassThru
, Slot
, Rca
);
1000 if (EFI_ERROR (Status
)) {
1001 DEBUG ((DEBUG_ERROR
, "EmmcSetBusMode: Select fails with %r\n", Status
));
1005 ASSERT (Private
->Capability
[Slot
].BaseClkFreq
!= 0);
1007 // Check if the Host Controller support 8bits bus width.
1009 if (Private
->Capability
[Slot
].BusWidth8
!= 0) {
1015 // Get Deivce_Type from EXT_CSD register.
1017 Status
= EmmcGetExtCsd (PassThru
, Slot
, &ExtCsd
);
1018 if (EFI_ERROR (Status
)) {
1019 DEBUG ((DEBUG_ERROR
, "EmmcSetBusMode: GetExtCsd fails with %r\n", Status
));
1023 // Calculate supported bus speed/bus width/clock frequency.
1028 if (((ExtCsd
.DeviceType
& (BIT4
| BIT5
)) != 0) && (Private
->Capability
[Slot
].Sdr104
!= 0)) {
1032 } else if (((ExtCsd
.DeviceType
& (BIT2
| BIT3
)) != 0) && (Private
->Capability
[Slot
].Ddr50
!= 0)) {
1036 } else if (((ExtCsd
.DeviceType
& BIT1
) != 0) && (Private
->Capability
[Slot
].HighSpeed
!= 0)) {
1040 } else if (((ExtCsd
.DeviceType
& BIT0
) != 0) && (Private
->Capability
[Slot
].HighSpeed
!= 0)) {
1046 // Check if both of the device and the host controller support HS400 DDR mode.
1048 if (((ExtCsd
.DeviceType
& (BIT6
| BIT7
)) != 0) && (Private
->Capability
[Slot
].Hs400
!= 0)) {
1050 // The host controller supports 8bits bus.
1052 ASSERT (BusWidth
== 8);
1058 if ((ClockFreq
== 0) || (HsTiming
== 0)) {
1060 // Continue using default setting.
1065 DEBUG ((DEBUG_INFO
, "EmmcSetBusMode: HsTiming %d ClockFreq %d BusWidth %d Ddr %a\n", HsTiming
, ClockFreq
, BusWidth
, IsDdr
? "TRUE":"FALSE"));
1067 if (HsTiming
== 3) {
1069 // Execute HS400 timing switch procedure
1071 Status
= EmmcSwitchToHS400 (PciIo
, PassThru
, Slot
, Rca
, ClockFreq
);
1072 } else if (HsTiming
== 2) {
1074 // Execute HS200 timing switch procedure
1076 Status
= EmmcSwitchToHS200 (PciIo
, PassThru
, Slot
, Rca
, ClockFreq
, BusWidth
);
1079 // Execute High Speed timing switch procedure
1081 Status
= EmmcSwitchToHighSpeed (PciIo
, PassThru
, Slot
, Rca
, ClockFreq
, IsDdr
, BusWidth
);
1084 DEBUG ((DEBUG_INFO
, "EmmcSetBusMode: Switch to %a %r\n", (HsTiming
== 3) ? "HS400" : ((HsTiming
== 2) ? "HS200" : "HighSpeed"), Status
));
1090 Execute EMMC device identification procedure.
1092 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
1094 @param[in] Private A pointer to the SD_MMC_HC_PRIVATE_DATA instance.
1095 @param[in] Slot The slot number of the SD card to send the command to.
1097 @retval EFI_SUCCESS There is a EMMC card.
1098 @retval Others There is not a EMMC card.
1102 EmmcIdentification (
1103 IN SD_MMC_HC_PRIVATE_DATA
*Private
,
1108 EFI_PCI_IO_PROTOCOL
*PciIo
;
1109 EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
;
1114 PciIo
= Private
->PciIo
;
1115 PassThru
= &Private
->PassThru
;
1117 Status
= EmmcReset (PassThru
, Slot
);
1118 if (EFI_ERROR (Status
)) {
1119 DEBUG ((DEBUG_VERBOSE
, "EmmcIdentification: Executing Cmd0 fails with %r\n", Status
));
1126 Status
= EmmcGetOcr (PassThru
, Slot
, &Ocr
);
1127 if (EFI_ERROR (Status
)) {
1128 DEBUG ((DEBUG_VERBOSE
, "EmmcIdentification: Executing Cmd1 fails with %r\n", Status
));
1133 if (Retry
++ == 100) {
1134 DEBUG ((DEBUG_VERBOSE
, "EmmcIdentification: Executing Cmd1 fails too many times\n"));
1135 return EFI_DEVICE_ERROR
;
1137 gBS
->Stall(10 * 1000);
1138 } while ((Ocr
& BIT31
) == 0);
1140 Status
= EmmcGetAllCid (PassThru
, Slot
);
1141 if (EFI_ERROR (Status
)) {
1142 DEBUG ((DEBUG_VERBOSE
, "EmmcIdentification: Executing Cmd2 fails with %r\n", Status
));
1146 // Slot starts from 0 and valid RCA starts from 1.
1147 // Here we takes a simple formula to calculate the RCA.
1148 // Don't support multiple devices on the slot, that is
1149 // shared bus slot feature.
1152 Status
= EmmcSetRca (PassThru
, Slot
, Rca
);
1153 if (EFI_ERROR (Status
)) {
1154 DEBUG ((DEBUG_ERROR
, "EmmcIdentification: Executing Cmd3 fails with %r\n", Status
));
1158 // Enter Data Tranfer Mode.
1160 DEBUG ((DEBUG_INFO
, "EmmcIdentification: Found a EMMC device at slot [%d], RCA [%d]\n", Slot
, Rca
));
1161 Private
->Slot
[Slot
].CardType
= EmmcCardType
;
1163 Status
= EmmcSetBusMode (PciIo
, PassThru
, Slot
, Rca
);