3 Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>
4 SPDX-License-Identifier: BSD-2-Clause-Patent
8 #include "EmmcBlockIoPei.h"
11 Read/Write specified EMMC host controller mmio register.
13 @param[in] Address The address of the mmio register to be read/written.
14 @param[in] Read A boolean to indicate it's read or write operation.
15 @param[in] Count The width of the mmio register in bytes.
16 Must be 1, 2 , 4 or 8 bytes.
17 @param[in, out] Data For read operations, the destination buffer to store
18 the results. For write operations, the source buffer
19 to write data from. The caller is responsible for
20 having ownership of the data buffer and ensuring its
21 size not less than Count bytes.
23 @retval EFI_INVALID_PARAMETER The Address or the Data or the Count is not valid.
24 @retval EFI_SUCCESS The read/write operation succeeds.
25 @retval Others The read/write operation fails.
37 if ((Address
== 0) || (Data
== NULL
)) {
38 return EFI_INVALID_PARAMETER
;
41 if ((Count
!= 1) && (Count
!= 2) && (Count
!= 4) && (Count
!= 8)) {
42 return EFI_INVALID_PARAMETER
;
48 *(UINT8
*)Data
= MmioRead8 (Address
);
50 MmioWrite8 (Address
, *(UINT8
*)Data
);
55 *(UINT16
*)Data
= MmioRead16 (Address
);
57 MmioWrite16 (Address
, *(UINT16
*)Data
);
62 *(UINT32
*)Data
= MmioRead32 (Address
);
64 MmioWrite32 (Address
, *(UINT32
*)Data
);
69 *(UINT64
*)Data
= MmioRead64 (Address
);
71 MmioWrite64 (Address
, *(UINT64
*)Data
);
76 return EFI_INVALID_PARAMETER
;
83 Do OR operation with the value of the specified EMMC host controller mmio register.
85 @param[in] Address The address of the mmio register to be read/written.
86 @param[in] Count The width of the mmio register in bytes.
87 Must be 1, 2 , 4 or 8 bytes.
88 @param[in] OrData The pointer to the data used to do OR operation.
89 The caller is responsible for having ownership of
90 the data buffer and ensuring its size not less than
93 @retval EFI_INVALID_PARAMETER The Address or the OrData or the Count is not valid.
94 @retval EFI_SUCCESS The OR operation succeeds.
95 @retval Others The OR operation fails.
110 Status
= EmmcPeimHcRwMmio (Address
, TRUE
, Count
, &Data
);
111 if (EFI_ERROR (Status
)) {
116 Or
= *(UINT8
*) OrData
;
117 } else if (Count
== 2) {
118 Or
= *(UINT16
*) OrData
;
119 } else if (Count
== 4) {
120 Or
= *(UINT32
*) OrData
;
121 } else if (Count
== 8) {
122 Or
= *(UINT64
*) OrData
;
124 return EFI_INVALID_PARAMETER
;
128 Status
= EmmcPeimHcRwMmio (Address
, FALSE
, Count
, &Data
);
134 Do AND operation with the value of the specified EMMC host controller mmio register.
136 @param[in] Address The address of the mmio register to be read/written.
137 @param[in] Count The width of the mmio register in bytes.
138 Must be 1, 2 , 4 or 8 bytes.
139 @param[in] AndData The pointer to the data used to do AND operation.
140 The caller is responsible for having ownership of
141 the data buffer and ensuring its size not less than
144 @retval EFI_INVALID_PARAMETER The Address or the AndData or the Count is not valid.
145 @retval EFI_SUCCESS The AND operation succeeds.
146 @retval Others The AND operation fails.
161 Status
= EmmcPeimHcRwMmio (Address
, TRUE
, Count
, &Data
);
162 if (EFI_ERROR (Status
)) {
167 And
= *(UINT8
*) AndData
;
168 } else if (Count
== 2) {
169 And
= *(UINT16
*) AndData
;
170 } else if (Count
== 4) {
171 And
= *(UINT32
*) AndData
;
172 } else if (Count
== 8) {
173 And
= *(UINT64
*) AndData
;
175 return EFI_INVALID_PARAMETER
;
179 Status
= EmmcPeimHcRwMmio (Address
, FALSE
, Count
, &Data
);
185 Wait for the value of the specified MMIO register set to the test value.
187 @param[in] Address The address of the mmio register to be checked.
188 @param[in] Count The width of the mmio register in bytes.
189 Must be 1, 2, 4 or 8 bytes.
190 @param[in] MaskValue The mask value of memory.
191 @param[in] TestValue The test value of memory.
193 @retval EFI_NOT_READY The MMIO register hasn't set to the expected value.
194 @retval EFI_SUCCESS The MMIO register has expected value.
195 @retval Others The MMIO operation fails.
200 EmmcPeimHcCheckMmioSet (
211 // Access PCI MMIO space to see if the value is the tested one.
214 Status
= EmmcPeimHcRwMmio (Address
, TRUE
, Count
, &Value
);
215 if (EFI_ERROR (Status
)) {
221 if (Value
== TestValue
) {
225 return EFI_NOT_READY
;
229 Wait for the value of the specified MMIO register set to the test value.
231 @param[in] Address The address of the mmio register to wait.
232 @param[in] Count The width of the mmio register in bytes.
233 Must be 1, 2, 4 or 8 bytes.
234 @param[in] MaskValue The mask value of memory.
235 @param[in] TestValue The test value of memory.
236 @param[in] Timeout The time out value for wait memory set, uses 1
237 microsecond as a unit.
239 @retval EFI_TIMEOUT The MMIO register hasn't expected value in timeout
241 @retval EFI_SUCCESS The MMIO register has expected value.
242 @retval Others The MMIO operation fails.
247 EmmcPeimHcWaitMmioSet (
256 BOOLEAN InfiniteWait
;
261 InfiniteWait
= FALSE
;
264 while (InfiniteWait
|| (Timeout
> 0)) {
265 Status
= EmmcPeimHcCheckMmioSet (
271 if (Status
!= EFI_NOT_READY
) {
276 // Stall for 1 microsecond.
278 MicroSecondDelay (1);
287 Software reset the specified EMMC host controller and enable all interrupts.
289 @param[in] Bar The mmio base address of the slot to be accessed.
291 @retval EFI_SUCCESS The software reset executes successfully.
292 @retval Others The software reset fails.
304 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_SW_RST
, FALSE
, sizeof (SwReset
), &SwReset
);
306 if (EFI_ERROR (Status
)) {
307 DEBUG ((EFI_D_ERROR
, "EmmcPeimHcReset: write full 1 fails: %r\n", Status
));
311 Status
= EmmcPeimHcWaitMmioSet (
312 Bar
+ EMMC_HC_SW_RST
,
318 if (EFI_ERROR (Status
)) {
319 DEBUG ((EFI_D_INFO
, "EmmcPeimHcReset: reset done with %r\n", Status
));
323 // Enable all interrupt after reset all.
325 Status
= EmmcPeimHcEnableInterrupt (Bar
);
331 Set all interrupt status bits in Normal and Error Interrupt Status Enable
334 @param[in] Bar The mmio base address of the slot to be accessed.
336 @retval EFI_SUCCESS The operation executes successfully.
337 @retval Others The operation fails.
341 EmmcPeimHcEnableInterrupt (
349 // Enable all bits in Error Interrupt Status Enable Register
352 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_ERR_INT_STS_EN
, FALSE
, sizeof (IntStatus
), &IntStatus
);
353 if (EFI_ERROR (Status
)) {
357 // Enable all bits in Normal Interrupt Status Enable Register
360 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_NOR_INT_STS_EN
, FALSE
, sizeof (IntStatus
), &IntStatus
);
366 Get the capability data from the specified slot.
368 @param[in] Bar The mmio base address of the slot to be accessed.
369 @param[out] Capability The buffer to store the capability data.
371 @retval EFI_SUCCESS The operation executes successfully.
372 @retval Others The operation fails.
376 EmmcPeimHcGetCapability (
378 OUT EMMC_HC_SLOT_CAP
*Capability
384 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_CAP
, TRUE
, sizeof (Cap
), &Cap
);
385 if (EFI_ERROR (Status
)) {
389 CopyMem (Capability
, &Cap
, sizeof (Cap
));
395 Detect whether there is a EMMC card attached at the specified EMMC host controller
398 Refer to SD Host Controller Simplified spec 3.0 Section 3.1 for details.
400 @param[in] Bar The mmio base address of the slot to be accessed.
402 @retval EFI_SUCCESS There is a EMMC card attached.
403 @retval EFI_NO_MEDIA There is not a EMMC card attached.
404 @retval Others The detection fails.
408 EmmcPeimHcCardDetect (
417 // Check Normal Interrupt Status Register
419 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_NOR_INT_STS
, TRUE
, sizeof (Data
), &Data
);
420 if (EFI_ERROR (Status
)) {
424 if ((Data
& (BIT6
| BIT7
)) != 0) {
426 // Clear BIT6 and BIT7 by writing 1 to these two bits if set.
429 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_NOR_INT_STS
, FALSE
, sizeof (Data
), &Data
);
430 if (EFI_ERROR (Status
)) {
436 // Check Present State Register to see if there is a card presented.
438 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_PRESENT_STATE
, TRUE
, sizeof (PresentState
), &PresentState
);
439 if (EFI_ERROR (Status
)) {
443 if ((PresentState
& BIT16
) != 0) {
451 Stop EMMC card clock.
453 Refer to SD Host Controller Simplified spec 3.0 Section 3.2.2 for details.
455 @param[in] Bar The mmio base address of the slot to be accessed.
457 @retval EFI_SUCCESS Succeed to stop EMMC clock.
458 @retval Others Fail to stop EMMC clock.
462 EmmcPeimHcStopClock (
471 // Ensure no SD transactions are occurring on the SD Bus by
472 // waiting for Command Inhibit (DAT) and Command Inhibit (CMD)
473 // in the Present State register to be 0.
475 Status
= EmmcPeimHcWaitMmioSet (
476 Bar
+ EMMC_HC_PRESENT_STATE
,
477 sizeof (PresentState
),
482 if (EFI_ERROR (Status
)) {
487 // Set SD Clock Enable in the Clock Control register to 0
489 ClockCtrl
= (UINT16
)~BIT2
;
490 Status
= EmmcPeimHcAndMmio (Bar
+ EMMC_HC_CLOCK_CTRL
, sizeof (ClockCtrl
), &ClockCtrl
);
496 EMMC card clock supply.
498 Refer to SD Host Controller Simplified spec 3.0 Section 3.2.1 for details.
500 @param[in] Bar The mmio base address of the slot to be accessed.
501 @param[in] ClockFreq The max clock frequency to be set. The unit is KHz.
503 @retval EFI_SUCCESS The clock is supplied successfully.
504 @retval Others The clock isn't supplied successfully.
508 EmmcPeimHcClockSupply (
514 EMMC_HC_SLOT_CAP Capability
;
519 UINT16 ControllerVer
;
523 // Calculate a divisor for SD clock frequency
525 Status
= EmmcPeimHcGetCapability (Bar
, &Capability
);
526 if (EFI_ERROR (Status
)) {
529 ASSERT (Capability
.BaseClkFreq
!= 0);
531 BaseClkFreq
= Capability
.BaseClkFreq
;
533 if (ClockFreq
== 0) {
534 return EFI_INVALID_PARAMETER
;
537 if (ClockFreq
> (BaseClkFreq
* 1000)) {
538 ClockFreq
= BaseClkFreq
* 1000;
542 // Calculate the divisor of base frequency.
545 SettingFreq
= BaseClkFreq
* 1000;
546 while (ClockFreq
< SettingFreq
) {
549 SettingFreq
= (BaseClkFreq
* 1000) / (2 * Divisor
);
550 Remainder
= (BaseClkFreq
* 1000) % (2 * Divisor
);
551 if ((ClockFreq
== SettingFreq
) && (Remainder
== 0)) {
554 if ((ClockFreq
== SettingFreq
) && (Remainder
!= 0)) {
559 DEBUG ((EFI_D_INFO
, "BaseClkFreq %dMHz Divisor %d ClockFreq %dKhz\n", BaseClkFreq
, Divisor
, ClockFreq
));
561 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_CTRL_VER
, TRUE
, sizeof (ControllerVer
), &ControllerVer
);
562 if (EFI_ERROR (Status
)) {
566 // Set SDCLK Frequency Select and Internal Clock Enable fields in Clock Control register.
568 if ((ControllerVer
& 0xFF) == 2) {
569 ASSERT (Divisor
<= 0x3FF);
570 ClockCtrl
= ((Divisor
& 0xFF) << 8) | ((Divisor
& 0x300) >> 2);
571 } else if (((ControllerVer
& 0xFF) == 0) || ((ControllerVer
& 0xFF) == 1)) {
573 // Only the most significant bit can be used as divisor.
575 if (((Divisor
- 1) & Divisor
) != 0) {
576 Divisor
= 1 << (HighBitSet32 (Divisor
) + 1);
578 ASSERT (Divisor
<= 0x80);
579 ClockCtrl
= (Divisor
& 0xFF) << 8;
581 DEBUG ((EFI_D_ERROR
, "Unknown SD Host Controller Spec version [0x%x]!!!\n", ControllerVer
));
582 return EFI_UNSUPPORTED
;
586 // Stop bus clock at first
588 Status
= EmmcPeimHcStopClock (Bar
);
589 if (EFI_ERROR (Status
)) {
594 // Supply clock frequency with specified divisor
597 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_CLOCK_CTRL
, FALSE
, sizeof (ClockCtrl
), &ClockCtrl
);
598 if (EFI_ERROR (Status
)) {
599 DEBUG ((EFI_D_ERROR
, "Set SDCLK Frequency Select and Internal Clock Enable fields fails\n"));
604 // Wait Internal Clock Stable in the Clock Control register to be 1
606 Status
= EmmcPeimHcWaitMmioSet (
607 Bar
+ EMMC_HC_CLOCK_CTRL
,
613 if (EFI_ERROR (Status
)) {
618 // Set SD Clock Enable in the Clock Control register to 1
621 Status
= EmmcPeimHcOrMmio (Bar
+ EMMC_HC_CLOCK_CTRL
, sizeof (ClockCtrl
), &ClockCtrl
);
627 EMMC bus power control.
629 Refer to SD Host Controller Simplified spec 3.0 Section 3.3 for details.
631 @param[in] Bar The mmio base address of the slot to be accessed.
632 @param[in] PowerCtrl The value setting to the power control register.
634 @retval TRUE There is a EMMC card attached.
635 @retval FALSE There is no a EMMC card attached.
639 EmmcPeimHcPowerControl (
649 PowerCtrl
&= (UINT8
)~BIT0
;
650 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_POWER_CTRL
, FALSE
, sizeof (PowerCtrl
), &PowerCtrl
);
651 if (EFI_ERROR (Status
)) {
656 // Set SD Bus Voltage Select and SD Bus Power fields in Power Control Register
659 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_POWER_CTRL
, FALSE
, sizeof (PowerCtrl
), &PowerCtrl
);
665 Set the EMMC bus width.
667 Refer to SD Host Controller Simplified spec 3.0 Section 3.4 for details.
669 @param[in] Bar The mmio base address of the slot to be accessed.
670 @param[in] BusWidth The bus width used by the EMMC device, it must be 1, 4 or 8.
672 @retval EFI_SUCCESS The bus width is set successfully.
673 @retval Others The bus width isn't set successfully.
677 EmmcPeimHcSetBusWidth (
686 HostCtrl1
= (UINT8
)~(BIT5
| BIT1
);
687 Status
= EmmcPeimHcAndMmio (Bar
+ EMMC_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
688 } else if (BusWidth
== 4) {
689 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_HOST_CTRL1
, TRUE
, sizeof (HostCtrl1
), &HostCtrl1
);
690 if (EFI_ERROR (Status
)) {
694 HostCtrl1
&= (UINT8
)~BIT5
;
695 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_HOST_CTRL1
, FALSE
, sizeof (HostCtrl1
), &HostCtrl1
);
696 } else if (BusWidth
== 8) {
697 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_HOST_CTRL1
, TRUE
, sizeof (HostCtrl1
), &HostCtrl1
);
698 if (EFI_ERROR (Status
)) {
701 HostCtrl1
&= (UINT8
)~BIT1
;
703 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_HOST_CTRL1
, FALSE
, sizeof (HostCtrl1
), &HostCtrl1
);
706 return EFI_INVALID_PARAMETER
;
713 Supply EMMC card with lowest clock frequency at initialization.
715 @param[in] Bar The mmio base address of the slot to be accessed.
717 @retval EFI_SUCCESS The clock is supplied successfully.
718 @retval Others The clock isn't supplied successfully.
722 EmmcPeimHcInitClockFreq (
727 EMMC_HC_SLOT_CAP Capability
;
731 // Calculate a divisor for SD clock frequency
733 Status
= EmmcPeimHcGetCapability (Bar
, &Capability
);
734 if (EFI_ERROR (Status
)) {
738 if (Capability
.BaseClkFreq
== 0) {
740 // Don't support get Base Clock Frequency information via another method
742 return EFI_UNSUPPORTED
;
745 // Supply 400KHz clock frequency at initialization phase.
748 Status
= EmmcPeimHcClockSupply (Bar
, InitFreq
);
753 Supply EMMC card with maximum voltage at initialization.
755 Refer to SD Host Controller Simplified spec 3.0 Section 3.3 for details.
757 @param[in] Bar The mmio base address of the slot to be accessed.
759 @retval EFI_SUCCESS The voltage is supplied successfully.
760 @retval Others The voltage isn't supplied successfully.
764 EmmcPeimHcInitPowerVoltage (
769 EMMC_HC_SLOT_CAP Capability
;
774 // Get the support voltage of the Host Controller
776 Status
= EmmcPeimHcGetCapability (Bar
, &Capability
);
777 if (EFI_ERROR (Status
)) {
781 // Calculate supported maximum voltage according to SD Bus Voltage Select
783 if (Capability
.Voltage33
!= 0) {
788 } else if (Capability
.Voltage30
!= 0) {
793 } else if (Capability
.Voltage18
!= 0) {
799 Status
= EmmcPeimHcOrMmio (Bar
+ EMMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
800 if (EFI_ERROR (Status
)) {
803 MicroSecondDelay (5000);
806 return EFI_DEVICE_ERROR
;
810 // Set SD Bus Voltage Select and SD Bus Power fields in Power Control Register
812 Status
= EmmcPeimHcPowerControl (Bar
, MaxVoltage
);
818 Initialize the Timeout Control register with most conservative value at initialization.
820 Refer to SD Host Controller Simplified spec 3.0 Section 2.2.15 for details.
822 @param[in] Bar The mmio base address of the slot to be accessed.
824 @retval EFI_SUCCESS The timeout control register is configured successfully.
825 @retval Others The timeout control register isn't configured successfully.
829 EmmcPeimHcInitTimeoutCtrl (
837 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_TIMEOUT_CTRL
, FALSE
, sizeof (Timeout
), &Timeout
);
843 Initial EMMC host controller with lowest clock frequency, max power and max timeout value
846 @param[in] Bar The mmio base address of the slot to be accessed.
848 @retval EFI_SUCCESS The host controller is initialized successfully.
849 @retval Others The host controller isn't initialized successfully.
859 Status
= EmmcPeimHcInitClockFreq (Bar
);
860 if (EFI_ERROR (Status
)) {
864 Status
= EmmcPeimHcInitPowerVoltage (Bar
);
865 if (EFI_ERROR (Status
)) {
869 Status
= EmmcPeimHcInitTimeoutCtrl (Bar
);
876 @param[in] Bar The mmio base address of the slot to be accessed.
877 @param[in] On The boolean to turn on/off LED.
879 @retval EFI_SUCCESS The LED is turned on/off successfully.
880 @retval Others The LED isn't turned on/off successfully.
894 Status
= EmmcPeimHcOrMmio (Bar
+ EMMC_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
896 HostCtrl1
= (UINT8
)~BIT0
;
897 Status
= EmmcPeimHcAndMmio (Bar
+ EMMC_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
904 Build ADMA descriptor table for transfer.
906 Refer to SD Host Controller Simplified spec 3.0 Section 1.13 for details.
908 @param[in] Trb The pointer to the EMMC_TRB instance.
910 @retval EFI_SUCCESS The ADMA descriptor table is created successfully.
911 @retval Others The ADMA descriptor table isn't created successfully.
919 EFI_PHYSICAL_ADDRESS Data
;
927 DataLen
= Trb
->DataLen
;
929 // Only support 32bit ADMA Descriptor Table
931 if ((Data
>= 0x100000000ul
) || ((Data
+ DataLen
) > 0x100000000ul
)) {
932 return EFI_INVALID_PARAMETER
;
935 // Address field shall be set on 32-bit boundary (Lower 2-bit is always set to 0)
936 // for 32-bit address descriptor table.
938 if ((Data
& (BIT0
| BIT1
)) != 0) {
939 DEBUG ((EFI_D_INFO
, "The buffer [0x%x] to construct ADMA desc is not aligned to 4 bytes boundary!\n", Data
));
942 Entries
= DivU64x32 ((DataLen
+ ADMA_MAX_DATA_PER_LINE
- 1), ADMA_MAX_DATA_PER_LINE
);
944 Trb
->AdmaDescSize
= (UINTN
)MultU64x32 (Entries
, sizeof (EMMC_HC_ADMA_DESC_LINE
));
945 Trb
->AdmaDesc
= EmmcPeimAllocateMem (Trb
->Slot
->Private
->Pool
, Trb
->AdmaDescSize
);
946 if (Trb
->AdmaDesc
== NULL
) {
947 return EFI_OUT_OF_RESOURCES
;
951 Address
= (UINT32
)Data
;
952 for (Index
= 0; Index
< Entries
; Index
++) {
953 if (Remaining
<= ADMA_MAX_DATA_PER_LINE
) {
954 Trb
->AdmaDesc
[Index
].Valid
= 1;
955 Trb
->AdmaDesc
[Index
].Act
= 2;
956 Trb
->AdmaDesc
[Index
].Length
= (UINT16
)Remaining
;
957 Trb
->AdmaDesc
[Index
].Address
= Address
;
960 Trb
->AdmaDesc
[Index
].Valid
= 1;
961 Trb
->AdmaDesc
[Index
].Act
= 2;
962 Trb
->AdmaDesc
[Index
].Length
= 0;
963 Trb
->AdmaDesc
[Index
].Address
= Address
;
966 Remaining
-= ADMA_MAX_DATA_PER_LINE
;
967 Address
+= ADMA_MAX_DATA_PER_LINE
;
971 // Set the last descriptor line as end of descriptor table
973 Trb
->AdmaDesc
[Index
].End
= 1;
978 Create a new TRB for the EMMC cmd request.
980 @param[in] Slot The slot number of the EMMC card to send the command to.
981 @param[in] Packet A pointer to the SD command data structure.
983 @return Created Trb or NULL.
988 IN EMMC_PEIM_HC_SLOT
*Slot
,
989 IN EMMC_COMMAND_PACKET
*Packet
994 EMMC_HC_SLOT_CAP Capability
;
995 EDKII_IOMMU_OPERATION MapOp
;
999 // Calculate a divisor for SD clock frequency
1001 Status
= EmmcPeimHcGetCapability (Slot
->EmmcHcBase
, &Capability
);
1002 if (EFI_ERROR (Status
)) {
1006 Trb
= AllocateZeroPool (sizeof (EMMC_TRB
));
1012 Trb
->BlockSize
= 0x200;
1013 Trb
->Packet
= Packet
;
1014 Trb
->Timeout
= Packet
->Timeout
;
1016 if ((Packet
->InTransferLength
!= 0) && (Packet
->InDataBuffer
!= NULL
)) {
1017 Trb
->Data
= Packet
->InDataBuffer
;
1018 Trb
->DataLen
= Packet
->InTransferLength
;
1020 } else if ((Packet
->OutTransferLength
!= 0) && (Packet
->OutDataBuffer
!= NULL
)) {
1021 Trb
->Data
= Packet
->OutDataBuffer
;
1022 Trb
->DataLen
= Packet
->OutTransferLength
;
1024 } else if ((Packet
->InTransferLength
== 0) && (Packet
->OutTransferLength
== 0)) {
1031 if ((Trb
->DataLen
!= 0) && (Trb
->DataLen
< Trb
->BlockSize
)) {
1032 Trb
->BlockSize
= (UINT16
)Trb
->DataLen
;
1035 if (Packet
->EmmcCmdBlk
->CommandIndex
== EMMC_SEND_TUNING_BLOCK
) {
1036 Trb
->Mode
= EmmcPioMode
;
1039 MapOp
= EdkiiIoMmuOperationBusMasterWrite
;
1041 MapOp
= EdkiiIoMmuOperationBusMasterRead
;
1044 if (Trb
->DataLen
!= 0) {
1045 MapLength
= Trb
->DataLen
;
1046 Status
= IoMmuMap (MapOp
, Trb
->Data
, &MapLength
, &Trb
->DataPhy
, &Trb
->DataMap
);
1048 if (EFI_ERROR (Status
) || (MapLength
!= Trb
->DataLen
)) {
1049 DEBUG ((DEBUG_ERROR
, "EmmcPeimCreateTrb: Fail to map data buffer.\n"));
1054 if (Trb
->DataLen
== 0) {
1055 Trb
->Mode
= EmmcNoData
;
1056 } else if (Capability
.Adma2
!= 0) {
1057 Trb
->Mode
= EmmcAdmaMode
;
1058 Status
= BuildAdmaDescTable (Trb
);
1059 if (EFI_ERROR (Status
)) {
1062 } else if (Capability
.Sdma
!= 0) {
1063 Trb
->Mode
= EmmcSdmaMode
;
1065 Trb
->Mode
= EmmcPioMode
;
1071 EmmcPeimFreeTrb (Trb
);
1076 Free the resource used by the TRB.
1078 @param[in] Trb The pointer to the EMMC_TRB instance.
1086 if ((Trb
!= NULL
) && (Trb
->DataMap
!= NULL
)) {
1087 IoMmuUnmap (Trb
->DataMap
);
1090 if ((Trb
!= NULL
) && (Trb
->AdmaDesc
!= NULL
)) {
1091 EmmcPeimFreeMem (Trb
->Slot
->Private
->Pool
, Trb
->AdmaDesc
, Trb
->AdmaDescSize
);
1101 Check if the env is ready for execute specified TRB.
1103 @param[in] Bar The mmio base address of the slot to be accessed.
1104 @param[in] Trb The pointer to the EMMC_TRB instance.
1106 @retval EFI_SUCCESS The env is ready for TRB execution.
1107 @retval EFI_NOT_READY The env is not ready for TRB execution.
1108 @retval Others Some erros happen.
1112 EmmcPeimCheckTrbEnv (
1118 EMMC_COMMAND_PACKET
*Packet
;
1119 UINT32 PresentState
;
1121 Packet
= Trb
->Packet
;
1123 if ((Packet
->EmmcCmdBlk
->CommandType
== EmmcCommandTypeAdtc
) ||
1124 (Packet
->EmmcCmdBlk
->ResponseType
== EmmcResponceTypeR1b
) ||
1125 (Packet
->EmmcCmdBlk
->ResponseType
== EmmcResponceTypeR5b
)) {
1127 // Wait Command Inhibit (CMD) and Command Inhibit (DAT) in
1128 // the Present State register to be 0
1130 PresentState
= BIT0
| BIT1
;
1133 // Wait Command Inhibit (CMD) in the Present State register
1136 PresentState
= BIT0
;
1139 Status
= EmmcPeimHcCheckMmioSet (
1140 Bar
+ EMMC_HC_PRESENT_STATE
,
1141 sizeof (PresentState
),
1150 Wait for the env to be ready for execute specified TRB.
1152 @param[in] Bar The mmio base address of the slot to be accessed.
1153 @param[in] Trb The pointer to the EMMC_TRB instance.
1155 @retval EFI_SUCCESS The env is ready for TRB execution.
1156 @retval EFI_TIMEOUT The env is not ready for TRB execution in time.
1157 @retval Others Some erros happen.
1161 EmmcPeimWaitTrbEnv (
1167 EMMC_COMMAND_PACKET
*Packet
;
1169 BOOLEAN InfiniteWait
;
1172 // Wait Command Complete Interrupt Status bit in Normal Interrupt Status Register
1174 Packet
= Trb
->Packet
;
1175 Timeout
= Packet
->Timeout
;
1177 InfiniteWait
= TRUE
;
1179 InfiniteWait
= FALSE
;
1182 while (InfiniteWait
|| (Timeout
> 0)) {
1184 // Check Trb execution result by reading Normal Interrupt Status register.
1186 Status
= EmmcPeimCheckTrbEnv (Bar
, Trb
);
1187 if (Status
!= EFI_NOT_READY
) {
1191 // Stall for 1 microsecond.
1193 MicroSecondDelay (1);
1202 Execute the specified TRB.
1204 @param[in] Bar The mmio base address of the slot to be accessed.
1205 @param[in] Trb The pointer to the EMMC_TRB instance.
1207 @retval EFI_SUCCESS The TRB is sent to host controller successfully.
1208 @retval Others Some erros happen when sending this request to the host controller.
1218 EMMC_COMMAND_PACKET
*Packet
;
1229 Packet
= Trb
->Packet
;
1231 // Clear all bits in Error Interrupt Status Register
1234 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_ERR_INT_STS
, FALSE
, sizeof (IntStatus
), &IntStatus
);
1235 if (EFI_ERROR (Status
)) {
1239 // Clear all bits in Normal Interrupt Status Register
1242 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_NOR_INT_STS
, FALSE
, sizeof (IntStatus
), &IntStatus
);
1243 if (EFI_ERROR (Status
)) {
1247 // Set Host Control 1 register DMA Select field
1249 if (Trb
->Mode
== EmmcAdmaMode
) {
1251 Status
= EmmcPeimHcOrMmio (Bar
+ EMMC_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
1252 if (EFI_ERROR (Status
)) {
1257 EmmcPeimHcLedOnOff (Bar
, TRUE
);
1259 if (Trb
->Mode
== EmmcSdmaMode
) {
1260 if ((UINT64
)(UINTN
)Trb
->DataPhy
>= 0x100000000ul
) {
1261 return EFI_INVALID_PARAMETER
;
1264 SdmaAddr
= (UINT32
)(UINTN
)Trb
->DataPhy
;
1265 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_SDMA_ADDR
, FALSE
, sizeof (SdmaAddr
), &SdmaAddr
);
1266 if (EFI_ERROR (Status
)) {
1269 } else if (Trb
->Mode
== EmmcAdmaMode
) {
1270 AdmaAddr
= (UINT64
)(UINTN
)Trb
->AdmaDesc
;
1271 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_ADMA_SYS_ADDR
, FALSE
, sizeof (AdmaAddr
), &AdmaAddr
);
1272 if (EFI_ERROR (Status
)) {
1277 BlkSize
= Trb
->BlockSize
;
1278 if (Trb
->Mode
== EmmcSdmaMode
) {
1280 // Set SDMA boundary to be 512K bytes.
1285 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_BLK_SIZE
, FALSE
, sizeof (BlkSize
), &BlkSize
);
1286 if (EFI_ERROR (Status
)) {
1291 if (Trb
->Mode
!= EmmcNoData
) {
1293 // Calcuate Block Count.
1295 BlkCount
= (UINT16
)(Trb
->DataLen
/ Trb
->BlockSize
);
1298 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_BLK_COUNT
, FALSE
, sizeof (BlkCount
), &BlkCount
);
1299 if (EFI_ERROR (Status
)) {
1303 Argument
= Packet
->EmmcCmdBlk
->CommandArgument
;
1304 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_ARG1
, FALSE
, sizeof (Argument
), &Argument
);
1305 if (EFI_ERROR (Status
)) {
1310 if (Trb
->Mode
!= EmmcNoData
) {
1311 if (Trb
->Mode
!= EmmcPioMode
) {
1318 TransMode
|= BIT5
| BIT1
;
1322 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_TRANS_MOD
, FALSE
, sizeof (TransMode
), &TransMode
);
1323 if (EFI_ERROR (Status
)) {
1327 Cmd
= (UINT16
)LShiftU64(Packet
->EmmcCmdBlk
->CommandIndex
, 8);
1328 if (Packet
->EmmcCmdBlk
->CommandType
== EmmcCommandTypeAdtc
) {
1332 // Convert ResponseType to value
1334 if (Packet
->EmmcCmdBlk
->CommandType
!= EmmcCommandTypeBc
) {
1335 switch (Packet
->EmmcCmdBlk
->ResponseType
) {
1336 case EmmcResponceTypeR1
:
1337 case EmmcResponceTypeR5
:
1338 case EmmcResponceTypeR6
:
1339 case EmmcResponceTypeR7
:
1340 Cmd
|= (BIT1
| BIT3
| BIT4
);
1342 case EmmcResponceTypeR2
:
1343 Cmd
|= (BIT0
| BIT3
);
1345 case EmmcResponceTypeR3
:
1346 case EmmcResponceTypeR4
:
1349 case EmmcResponceTypeR1b
:
1350 case EmmcResponceTypeR5b
:
1351 Cmd
|= (BIT0
| BIT1
| BIT3
| BIT4
);
1361 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_COMMAND
, FALSE
, sizeof (Cmd
), &Cmd
);
1366 Check the TRB execution result.
1368 @param[in] Bar The mmio base address of the slot to be accessed.
1369 @param[in] Trb The pointer to the EMMC_TRB instance.
1371 @retval EFI_SUCCESS The TRB is executed successfully.
1372 @retval EFI_NOT_READY The TRB is not completed for execution.
1373 @retval Others Some erros happen when executing this request.
1377 EmmcPeimCheckTrbResult (
1383 EMMC_COMMAND_PACKET
*Packet
;
1392 Packet
= Trb
->Packet
;
1394 // Check Trb execution result by reading Normal Interrupt Status register.
1396 Status
= EmmcPeimHcRwMmio (
1397 Bar
+ EMMC_HC_NOR_INT_STS
,
1402 if (EFI_ERROR (Status
)) {
1406 // Check Transfer Complete bit is set or not.
1408 if ((IntStatus
& BIT1
) == BIT1
) {
1409 if ((IntStatus
& BIT15
) == BIT15
) {
1411 // Read Error Interrupt Status register to check if the error is
1412 // Data Timeout Error.
1413 // If yes, treat it as success as Transfer Complete has higher
1414 // priority than Data Timeout Error.
1416 Status
= EmmcPeimHcRwMmio (
1417 Bar
+ EMMC_HC_ERR_INT_STS
,
1422 if (!EFI_ERROR (Status
)) {
1423 if ((IntStatus
& BIT4
) == BIT4
) {
1424 Status
= EFI_SUCCESS
;
1426 Status
= EFI_DEVICE_ERROR
;
1434 // Check if there is a error happened during cmd execution.
1435 // If yes, then do error recovery procedure to follow SD Host Controller
1436 // Simplified Spec 3.0 section 3.10.1.
1438 if ((IntStatus
& BIT15
) == BIT15
) {
1439 Status
= EmmcPeimHcRwMmio (
1440 Bar
+ EMMC_HC_ERR_INT_STS
,
1445 if (EFI_ERROR (Status
)) {
1449 if ((IntStatus
& 0x0F) != 0) {
1452 if ((IntStatus
& 0xF0) != 0) {
1456 Status
= EmmcPeimHcRwMmio (
1457 Bar
+ EMMC_HC_SW_RST
,
1462 if (EFI_ERROR (Status
)) {
1465 Status
= EmmcPeimHcWaitMmioSet (
1466 Bar
+ EMMC_HC_SW_RST
,
1472 if (EFI_ERROR (Status
)) {
1476 Status
= EFI_DEVICE_ERROR
;
1480 // Check if DMA interrupt is signalled for the SDMA transfer.
1482 if ((Trb
->Mode
== EmmcSdmaMode
) && ((IntStatus
& BIT3
) == BIT3
)) {
1484 // Clear DMA interrupt bit.
1487 Status
= EmmcPeimHcRwMmio (
1488 Bar
+ EMMC_HC_NOR_INT_STS
,
1493 if (EFI_ERROR (Status
)) {
1497 // Update SDMA Address register.
1499 SdmaAddr
= EMMC_SDMA_ROUND_UP ((UINT32
)(UINTN
)Trb
->DataPhy
, EMMC_SDMA_BOUNDARY
);
1500 Status
= EmmcPeimHcRwMmio (
1501 Bar
+ EMMC_HC_SDMA_ADDR
,
1506 if (EFI_ERROR (Status
)) {
1509 Trb
->DataPhy
= (UINT32
)(UINTN
)SdmaAddr
;
1512 if ((Packet
->EmmcCmdBlk
->CommandType
!= EmmcCommandTypeAdtc
) &&
1513 (Packet
->EmmcCmdBlk
->ResponseType
!= EmmcResponceTypeR1b
) &&
1514 (Packet
->EmmcCmdBlk
->ResponseType
!= EmmcResponceTypeR5b
)) {
1515 if ((IntStatus
& BIT0
) == BIT0
) {
1516 Status
= EFI_SUCCESS
;
1521 if (Packet
->EmmcCmdBlk
->CommandIndex
== EMMC_SEND_TUNING_BLOCK
) {
1523 // When performing tuning procedure (Execute Tuning is set to 1) through PIO mode,
1524 // wait Buffer Read Ready bit of Normal Interrupt Status Register to be 1.
1525 // Refer to SD Host Controller Simplified Specification 3.0 figure 2-29 for details.
1527 if ((IntStatus
& BIT5
) == BIT5
) {
1529 // Clear Buffer Read Ready interrupt at first.
1532 EmmcPeimHcRwMmio (Bar
+ EMMC_HC_NOR_INT_STS
, FALSE
, sizeof (IntStatus
), &IntStatus
);
1534 // Read data out from Buffer Port register
1536 for (PioLength
= 0; PioLength
< Trb
->DataLen
; PioLength
+= 4) {
1537 EmmcPeimHcRwMmio (Bar
+ EMMC_HC_BUF_DAT_PORT
, TRUE
, 4, (UINT8
*)Trb
->Data
+ PioLength
);
1539 Status
= EFI_SUCCESS
;
1544 Status
= EFI_NOT_READY
;
1547 // Get response data when the cmd is executed successfully.
1549 if (!EFI_ERROR (Status
)) {
1550 if (Packet
->EmmcCmdBlk
->CommandType
!= EmmcCommandTypeBc
) {
1551 for (Index
= 0; Index
< 4; Index
++) {
1552 Status
= EmmcPeimHcRwMmio (
1553 Bar
+ EMMC_HC_RESPONSE
+ Index
* 4,
1558 if (EFI_ERROR (Status
)) {
1559 EmmcPeimHcLedOnOff (Bar
, FALSE
);
1563 CopyMem (Packet
->EmmcStatusBlk
, Response
, sizeof (Response
));
1567 if (Status
!= EFI_NOT_READY
) {
1568 EmmcPeimHcLedOnOff (Bar
, FALSE
);
1575 Wait for the TRB execution result.
1577 @param[in] Bar The mmio base address of the slot to be accessed.
1578 @param[in] Trb The pointer to the EMMC_TRB instance.
1580 @retval EFI_SUCCESS The TRB is executed successfully.
1581 @retval Others Some erros happen when executing this request.
1585 EmmcPeimWaitTrbResult (
1591 EMMC_COMMAND_PACKET
*Packet
;
1593 BOOLEAN InfiniteWait
;
1595 Packet
= Trb
->Packet
;
1597 // Wait Command Complete Interrupt Status bit in Normal Interrupt Status Register
1599 Timeout
= Packet
->Timeout
;
1601 InfiniteWait
= TRUE
;
1603 InfiniteWait
= FALSE
;
1606 while (InfiniteWait
|| (Timeout
> 0)) {
1608 // Check Trb execution result by reading Normal Interrupt Status register.
1610 Status
= EmmcPeimCheckTrbResult (Bar
, Trb
);
1611 if (Status
!= EFI_NOT_READY
) {
1615 // Stall for 1 microsecond.
1617 MicroSecondDelay (1);
1626 Sends EMMC command to an EMMC card that is attached to the EMMC controller.
1628 If Packet is successfully sent to the EMMC card, then EFI_SUCCESS is returned.
1630 If a device error occurs while sending the Packet, then EFI_DEVICE_ERROR is returned.
1632 If Slot is not in a valid range for the EMMC controller, then EFI_INVALID_PARAMETER
1635 If Packet defines a data command but both InDataBuffer and OutDataBuffer are NULL,
1636 EFI_INVALID_PARAMETER is returned.
1638 @param[in] Slot The slot number of the Emmc card to send the command to.
1639 @param[in,out] Packet A pointer to the EMMC command data structure.
1641 @retval EFI_SUCCESS The EMMC Command Packet was sent by the host.
1642 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send the SD
1644 @retval EFI_INVALID_PARAMETER Packet, Slot, or the contents of the Packet is invalid.
1645 @retval EFI_INVALID_PARAMETER Packet defines a data command but both InDataBuffer and
1646 OutDataBuffer are NULL.
1647 @retval EFI_NO_MEDIA SD Device not present in the Slot.
1648 @retval EFI_UNSUPPORTED The command described by the EMMC Command Packet is not
1649 supported by the host controller.
1650 @retval EFI_BAD_BUFFER_SIZE The InTransferLength or OutTransferLength exceeds the
1651 limit supported by EMMC card ( i.e. if the number of bytes
1652 exceed the Last LBA).
1658 IN EMMC_PEIM_HC_SLOT
*Slot
,
1659 IN OUT EMMC_COMMAND_PACKET
*Packet
1665 if (Packet
== NULL
) {
1666 return EFI_INVALID_PARAMETER
;
1669 if ((Packet
->EmmcCmdBlk
== NULL
) || (Packet
->EmmcStatusBlk
== NULL
)) {
1670 return EFI_INVALID_PARAMETER
;
1673 if ((Packet
->OutDataBuffer
== NULL
) && (Packet
->OutTransferLength
!= 0)) {
1674 return EFI_INVALID_PARAMETER
;
1677 if ((Packet
->InDataBuffer
== NULL
) && (Packet
->InTransferLength
!= 0)) {
1678 return EFI_INVALID_PARAMETER
;
1681 Trb
= EmmcPeimCreateTrb (Slot
, Packet
);
1683 return EFI_OUT_OF_RESOURCES
;
1686 Status
= EmmcPeimWaitTrbEnv (Slot
->EmmcHcBase
, Trb
);
1687 if (EFI_ERROR (Status
)) {
1691 Status
= EmmcPeimExecTrb (Slot
->EmmcHcBase
, Trb
);
1692 if (EFI_ERROR (Status
)) {
1696 Status
= EmmcPeimWaitTrbResult (Slot
->EmmcHcBase
, Trb
);
1697 if (EFI_ERROR (Status
)) {
1702 EmmcPeimFreeTrb (Trb
);
1708 Send command GO_IDLE_STATE (CMD0 with argument of 0x00000000) to the device to
1709 make it go to Idle State.
1711 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
1713 @param[in] Slot The slot number of the Emmc card to send the command to.
1715 @retval EFI_SUCCESS The EMMC device is reset correctly.
1716 @retval Others The device reset fails.
1721 IN EMMC_PEIM_HC_SLOT
*Slot
1724 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
1725 EMMC_STATUS_BLOCK EmmcStatusBlk
;
1726 EMMC_COMMAND_PACKET Packet
;
1729 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
1730 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
1731 ZeroMem (&Packet
, sizeof (Packet
));
1733 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
1734 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
1735 Packet
.Timeout
= EMMC_TIMEOUT
;
1737 EmmcCmdBlk
.CommandIndex
= EMMC_GO_IDLE_STATE
;
1738 EmmcCmdBlk
.CommandType
= EmmcCommandTypeBc
;
1739 EmmcCmdBlk
.ResponseType
= 0;
1740 EmmcCmdBlk
.CommandArgument
= 0;
1742 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
1748 Send command SEND_OP_COND to the EMMC device to get the data of the OCR register.
1750 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
1752 @param[in] Slot The slot number of the Emmc card to send the command to.
1753 @param[in, out] Argument On input, the argument of SEND_OP_COND is to send to the device.
1754 On output, the argument is the value of OCR register.
1756 @retval EFI_SUCCESS The operation is done correctly.
1757 @retval Others The operation fails.
1762 IN EMMC_PEIM_HC_SLOT
*Slot
,
1763 IN OUT UINT32
*Argument
1766 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
1767 EMMC_STATUS_BLOCK EmmcStatusBlk
;
1768 EMMC_COMMAND_PACKET Packet
;
1771 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
1772 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
1773 ZeroMem (&Packet
, sizeof (Packet
));
1775 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
1776 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
1777 Packet
.Timeout
= EMMC_TIMEOUT
;
1779 EmmcCmdBlk
.CommandIndex
= EMMC_SEND_OP_COND
;
1780 EmmcCmdBlk
.CommandType
= EmmcCommandTypeBcr
;
1781 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR3
;
1782 EmmcCmdBlk
.CommandArgument
= *Argument
;
1784 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
1785 if (!EFI_ERROR (Status
)) {
1787 // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12.
1789 *Argument
= EmmcStatusBlk
.Resp0
;
1796 Broadcast command ALL_SEND_CID to the bus to ask all the EMMC devices to send the
1797 data of their CID registers.
1799 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
1801 @param[in] Slot The slot number of the Emmc card to send the command to.
1803 @retval EFI_SUCCESS The operation is done correctly.
1804 @retval Others The operation fails.
1809 IN EMMC_PEIM_HC_SLOT
*Slot
1812 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
1813 EMMC_STATUS_BLOCK EmmcStatusBlk
;
1814 EMMC_COMMAND_PACKET Packet
;
1817 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
1818 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
1819 ZeroMem (&Packet
, sizeof (Packet
));
1821 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
1822 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
1823 Packet
.Timeout
= EMMC_TIMEOUT
;
1825 EmmcCmdBlk
.CommandIndex
= EMMC_ALL_SEND_CID
;
1826 EmmcCmdBlk
.CommandType
= EmmcCommandTypeBcr
;
1827 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR2
;
1828 EmmcCmdBlk
.CommandArgument
= 0;
1830 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
1836 Send command SET_RELATIVE_ADDR to the EMMC device to assign a Relative device
1839 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
1841 @param[in] Slot The slot number of the Emmc card to send the command to.
1842 @param[in] Rca The relative device address to be assigned.
1844 @retval EFI_SUCCESS The operation is done correctly.
1845 @retval Others The operation fails.
1850 IN EMMC_PEIM_HC_SLOT
*Slot
,
1854 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
1855 EMMC_STATUS_BLOCK EmmcStatusBlk
;
1856 EMMC_COMMAND_PACKET Packet
;
1859 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
1860 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
1861 ZeroMem (&Packet
, sizeof (Packet
));
1863 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
1864 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
1865 Packet
.Timeout
= EMMC_TIMEOUT
;
1867 EmmcCmdBlk
.CommandIndex
= EMMC_SET_RELATIVE_ADDR
;
1868 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAc
;
1869 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR1
;
1870 EmmcCmdBlk
.CommandArgument
= Rca
<< 16;
1872 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
1878 Send command SEND_CSD to the EMMC device to get the data of the CSD register.
1880 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
1882 @param[in] Slot The slot number of the Emmc card to send the command to.
1883 @param[in] Rca The relative device address of selected device.
1884 @param[out] Csd The buffer to store the content of the CSD register.
1885 Note the caller should ignore the lowest byte of this
1886 buffer as the content of this byte is meaningless even
1887 if the operation succeeds.
1889 @retval EFI_SUCCESS The operation is done correctly.
1890 @retval Others The operation fails.
1895 IN EMMC_PEIM_HC_SLOT
*Slot
,
1900 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
1901 EMMC_STATUS_BLOCK EmmcStatusBlk
;
1902 EMMC_COMMAND_PACKET Packet
;
1905 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
1906 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
1907 ZeroMem (&Packet
, sizeof (Packet
));
1909 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
1910 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
1911 Packet
.Timeout
= EMMC_TIMEOUT
;
1913 EmmcCmdBlk
.CommandIndex
= EMMC_SEND_CSD
;
1914 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAc
;
1915 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR2
;
1916 EmmcCmdBlk
.CommandArgument
= Rca
<< 16;
1918 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
1919 if (!EFI_ERROR (Status
)) {
1921 // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12.
1923 CopyMem (((UINT8
*)Csd
) + 1, &EmmcStatusBlk
.Resp0
, sizeof (EMMC_CSD
) - 1);
1930 Send command SELECT_DESELECT_CARD to the EMMC device to select/deselect it.
1932 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
1934 @param[in] Slot The slot number of the Emmc card to send the command to.
1935 @param[in] Rca The relative device address of selected device.
1937 @retval EFI_SUCCESS The operation is done correctly.
1938 @retval Others The operation fails.
1943 IN EMMC_PEIM_HC_SLOT
*Slot
,
1947 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
1948 EMMC_STATUS_BLOCK EmmcStatusBlk
;
1949 EMMC_COMMAND_PACKET Packet
;
1952 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
1953 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
1954 ZeroMem (&Packet
, sizeof (Packet
));
1956 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
1957 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
1958 Packet
.Timeout
= EMMC_TIMEOUT
;
1960 EmmcCmdBlk
.CommandIndex
= EMMC_SELECT_DESELECT_CARD
;
1961 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAc
;
1962 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR1
;
1963 EmmcCmdBlk
.CommandArgument
= Rca
<< 16;
1965 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
1971 Send command SEND_EXT_CSD to the EMMC device to get the data of the EXT_CSD register.
1973 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
1975 @param[in] Slot The slot number of the Emmc card to send the command to.
1976 @param[out] ExtCsd The buffer to store the content of the EXT_CSD register.
1978 @retval EFI_SUCCESS The operation is done correctly.
1979 @retval Others The operation fails.
1984 IN EMMC_PEIM_HC_SLOT
*Slot
,
1985 OUT EMMC_EXT_CSD
*ExtCsd
1988 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
1989 EMMC_STATUS_BLOCK EmmcStatusBlk
;
1990 EMMC_COMMAND_PACKET Packet
;
1993 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
1994 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
1995 ZeroMem (&Packet
, sizeof (Packet
));
1997 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
1998 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
1999 Packet
.Timeout
= EMMC_TIMEOUT
;
2001 EmmcCmdBlk
.CommandIndex
= EMMC_SEND_EXT_CSD
;
2002 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAdtc
;
2003 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR1
;
2004 EmmcCmdBlk
.CommandArgument
= 0x00000000;
2006 Packet
.InDataBuffer
= ExtCsd
;
2007 Packet
.InTransferLength
= sizeof (EMMC_EXT_CSD
);
2009 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
2014 Send command SWITCH to the EMMC device to switch the mode of operation of the
2015 selected Device or modifies the EXT_CSD registers.
2017 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
2019 @param[in] Slot The slot number of the Emmc card to send the command to.
2020 @param[in] Access The access mode of SWTICH command.
2021 @param[in] Index The offset of the field to be access.
2022 @param[in] Value The value to be set to the specified field of EXT_CSD register.
2023 @param[in] CmdSet The value of CmdSet field of EXT_CSD register.
2025 @retval EFI_SUCCESS The operation is done correctly.
2026 @retval Others The operation fails.
2031 IN EMMC_PEIM_HC_SLOT
*Slot
,
2038 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
2039 EMMC_STATUS_BLOCK EmmcStatusBlk
;
2040 EMMC_COMMAND_PACKET Packet
;
2043 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
2044 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
2045 ZeroMem (&Packet
, sizeof (Packet
));
2047 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
2048 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
2049 Packet
.Timeout
= EMMC_TIMEOUT
;
2051 EmmcCmdBlk
.CommandIndex
= EMMC_SWITCH
;
2052 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAc
;
2053 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR1b
;
2054 EmmcCmdBlk
.CommandArgument
= (Access
<< 24) | (Index
<< 16) | (Value
<< 8) | CmdSet
;
2056 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
2062 Send command SEND_STATUS to the addressed EMMC device to get its status register.
2064 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
2066 @param[in] Slot The slot number of the Emmc card to send the command to.
2067 @param[in] Rca The relative device address of addressed device.
2068 @param[out] DevStatus The returned device status.
2070 @retval EFI_SUCCESS The operation is done correctly.
2071 @retval Others The operation fails.
2075 EmmcPeimSendStatus (
2076 IN EMMC_PEIM_HC_SLOT
*Slot
,
2078 OUT UINT32
*DevStatus
2081 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
2082 EMMC_STATUS_BLOCK EmmcStatusBlk
;
2083 EMMC_COMMAND_PACKET Packet
;
2086 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
2087 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
2088 ZeroMem (&Packet
, sizeof (Packet
));
2090 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
2091 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
2092 Packet
.Timeout
= EMMC_TIMEOUT
;
2094 EmmcCmdBlk
.CommandIndex
= EMMC_SEND_STATUS
;
2095 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAc
;
2096 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR1
;
2097 EmmcCmdBlk
.CommandArgument
= Rca
<< 16;
2099 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
2100 if (!EFI_ERROR (Status
)) {
2101 *DevStatus
= EmmcStatusBlk
.Resp0
;
2108 Send command SET_BLOCK_COUNT to the addressed EMMC device to set the number of
2109 blocks for the following block read/write cmd.
2111 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
2113 @param[in] Slot The slot number of the Emmc card to send the command to.
2114 @param[in] BlockCount The number of the logical block to access.
2116 @retval EFI_SUCCESS The operation is done correctly.
2117 @retval Others The operation fails.
2121 EmmcPeimSetBlkCount (
2122 IN EMMC_PEIM_HC_SLOT
*Slot
,
2123 IN UINT16 BlockCount
2126 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
2127 EMMC_STATUS_BLOCK EmmcStatusBlk
;
2128 EMMC_COMMAND_PACKET Packet
;
2131 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
2132 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
2133 ZeroMem (&Packet
, sizeof (Packet
));
2135 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
2136 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
2137 Packet
.Timeout
= EMMC_TIMEOUT
;
2139 EmmcCmdBlk
.CommandIndex
= EMMC_SET_BLOCK_COUNT
;
2140 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAc
;
2141 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR1
;
2142 EmmcCmdBlk
.CommandArgument
= BlockCount
;
2144 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
2150 Send command READ_MULTIPLE_BLOCK/WRITE_MULTIPLE_BLOCK to the addressed EMMC device
2151 to read/write the specified number of blocks.
2153 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
2155 @param[in] Slot The slot number of the Emmc card to send the command to.
2156 @param[in] Lba The logical block address of starting access.
2157 @param[in] BlockSize The block size of specified EMMC device partition.
2158 @param[in] Buffer The pointer to the transfer buffer.
2159 @param[in] BufferSize The size of transfer buffer.
2160 @param[in] IsRead Boolean to show the operation direction.
2162 @retval EFI_SUCCESS The operation is done correctly.
2163 @retval Others The operation fails.
2167 EmmcPeimRwMultiBlocks (
2168 IN EMMC_PEIM_HC_SLOT
*Slot
,
2170 IN UINT32 BlockSize
,
2172 IN UINTN BufferSize
,
2176 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
2177 EMMC_STATUS_BLOCK EmmcStatusBlk
;
2178 EMMC_COMMAND_PACKET Packet
;
2181 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
2182 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
2183 ZeroMem (&Packet
, sizeof (Packet
));
2185 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
2186 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
2188 // Calculate timeout value through the below formula.
2189 // Timeout = (transfer size) / (2MB/s).
2190 // Taking 2MB/s as divisor is because it's nearest to the eMMC lowest
2191 // transfer speed (2.4MB/s).
2192 // Refer to eMMC 5.0 spec section 6.9.1 for details.
2194 Packet
.Timeout
= (BufferSize
/ (2 * 1024 * 1024) + 1) * 1000 * 1000;;
2197 Packet
.InDataBuffer
= Buffer
;
2198 Packet
.InTransferLength
= (UINT32
)BufferSize
;
2200 EmmcCmdBlk
.CommandIndex
= EMMC_READ_MULTIPLE_BLOCK
;
2201 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAdtc
;
2202 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR1
;
2204 Packet
.OutDataBuffer
= Buffer
;
2205 Packet
.OutTransferLength
= (UINT32
)BufferSize
;
2207 EmmcCmdBlk
.CommandIndex
= EMMC_WRITE_MULTIPLE_BLOCK
;
2208 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAdtc
;
2209 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR1
;
2212 if (Slot
->SectorAddressing
) {
2213 EmmcCmdBlk
.CommandArgument
= (UINT32
)Lba
;
2215 EmmcCmdBlk
.CommandArgument
= (UINT32
)MultU64x32 (Lba
, BlockSize
);
2218 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
2224 Send command SEND_TUNING_BLOCK to the EMMC device for HS200 optimal sampling point
2227 It may be sent up to 40 times until the host finishes the tuning procedure.
2229 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 for details.
2231 @param[in] Slot The slot number of the Emmc card to send the command to.
2232 @param[in] BusWidth The bus width to work.
2234 @retval EFI_SUCCESS The operation is done correctly.
2235 @retval Others The operation fails.
2239 EmmcPeimSendTuningBlk (
2240 IN EMMC_PEIM_HC_SLOT
*Slot
,
2244 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
2245 EMMC_STATUS_BLOCK EmmcStatusBlk
;
2246 EMMC_COMMAND_PACKET Packet
;
2248 UINT8 TuningBlock
[128];
2250 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
2251 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
2252 ZeroMem (&Packet
, sizeof (Packet
));
2254 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
2255 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
2256 Packet
.Timeout
= EMMC_TIMEOUT
;
2258 EmmcCmdBlk
.CommandIndex
= EMMC_SEND_TUNING_BLOCK
;
2259 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAdtc
;
2260 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR1
;
2261 EmmcCmdBlk
.CommandArgument
= 0;
2263 Packet
.InDataBuffer
= TuningBlock
;
2264 if (BusWidth
== 8) {
2265 Packet
.InTransferLength
= sizeof (TuningBlock
);
2267 Packet
.InTransferLength
= 64;
2270 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
2276 Tunning the clock to get HS200 optimal sampling point.
2278 Command SEND_TUNING_BLOCK may be sent up to 40 times until the host finishes the
2281 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
2282 Simplified Spec 3.0 section Figure 2-29 for details.
2284 @param[in] Slot The slot number of the Emmc card to send the command to.
2285 @param[in] BusWidth The bus width to work.
2287 @retval EFI_SUCCESS The operation is done correctly.
2288 @retval Others The operation fails.
2292 EmmcPeimTuningClkForHs200 (
2293 IN EMMC_PEIM_HC_SLOT
*Slot
,
2302 // Notify the host that the sampling clock tuning procedure starts.
2305 Status
= EmmcPeimHcOrMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2306 if (EFI_ERROR (Status
)) {
2310 // Ask the device to send a sequence of tuning blocks till the tuning procedure is done.
2314 Status
= EmmcPeimSendTuningBlk (Slot
, BusWidth
);
2315 if (EFI_ERROR (Status
)) {
2319 Status
= EmmcPeimHcRwMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL2
, TRUE
, sizeof (HostCtrl2
), &HostCtrl2
);
2320 if (EFI_ERROR (Status
)) {
2324 if ((HostCtrl2
& (BIT6
| BIT7
)) == 0) {
2328 if ((HostCtrl2
& (BIT6
| BIT7
)) == BIT7
) {
2331 } while (++Retry
< 40);
2333 DEBUG ((EFI_D_ERROR
, "EmmcPeimTuningClkForHs200: Send tuning block fails at %d times with HostCtrl2 %02x\n", Retry
, HostCtrl2
));
2335 // Abort the tuning procedure and reset the tuning circuit.
2337 HostCtrl2
= (UINT8
)~(BIT6
| BIT7
);
2338 Status
= EmmcPeimHcAndMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2339 if (EFI_ERROR (Status
)) {
2342 return EFI_DEVICE_ERROR
;
2346 Switch the bus width to specified width.
2348 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.9 and SD Host Controller
2349 Simplified Spec 3.0 section Figure 3-7 for details.
2351 @param[in] Slot The slot number of the Emmc card to send the command to.
2352 @param[in] Rca The relative device address to be assigned.
2353 @param[in] IsDdr If TRUE, use dual data rate data simpling method. Otherwise
2354 use single data rate data simpling method.
2355 @param[in] BusWidth The bus width to be set, it could be 4 or 8.
2357 @retval EFI_SUCCESS The operation is done correctly.
2358 @retval Others The operation fails.
2362 EmmcPeimSwitchBusWidth (
2363 IN EMMC_PEIM_HC_SLOT
*Slot
,
2377 // Write Byte, the Value field is written into the byte pointed by Index.
2380 Index
= OFFSET_OF (EMMC_EXT_CSD
, BusWidth
);
2381 if (BusWidth
== 4) {
2383 } else if (BusWidth
== 8) {
2386 return EFI_INVALID_PARAMETER
;
2394 Status
= EmmcPeimSwitch (Slot
, Access
, Index
, Value
, CmdSet
);
2395 if (EFI_ERROR (Status
)) {
2399 Status
= EmmcPeimSendStatus (Slot
, Rca
, &DevStatus
);
2400 if (EFI_ERROR (Status
)) {
2404 // Check the switch operation is really successful or not.
2406 if ((DevStatus
& BIT7
) != 0) {
2407 return EFI_DEVICE_ERROR
;
2410 Status
= EmmcPeimHcSetBusWidth (Slot
->EmmcHcBase
, BusWidth
);
2416 Switch the clock frequency to the specified value.
2418 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6 and SD Host Controller
2419 Simplified Spec 3.0 section Figure 3-3 for details.
2421 @param[in] Slot The slot number of the Emmc card to send the command to.
2422 @param[in] Rca The relative device address to be assigned.
2423 @param[in] HsTiming The value to be written to HS_TIMING field of EXT_CSD register.
2424 @param[in] ClockFreq The max clock frequency to be set, the unit is MHz.
2426 @retval EFI_SUCCESS The operation is done correctly.
2427 @retval Others The operation fails.
2431 EmmcPeimSwitchClockFreq (
2432 IN EMMC_PEIM_HC_SLOT
*Slot
,
2446 // Write Byte, the Value field is written into the byte pointed by Index.
2449 Index
= OFFSET_OF (EMMC_EXT_CSD
, HsTiming
);
2453 Status
= EmmcPeimSwitch (Slot
, Access
, Index
, Value
, CmdSet
);
2454 if (EFI_ERROR (Status
)) {
2458 Status
= EmmcPeimSendStatus (Slot
, Rca
, &DevStatus
);
2459 if (EFI_ERROR (Status
)) {
2463 // Check the switch operation is really successful or not.
2465 if ((DevStatus
& BIT7
) != 0) {
2466 return EFI_DEVICE_ERROR
;
2469 // Convert the clock freq unit from MHz to KHz.
2471 Status
= EmmcPeimHcClockSupply (Slot
->EmmcHcBase
, ClockFreq
* 1000);
2477 Switch to the High Speed timing according to request.
2479 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
2480 Simplified Spec 3.0 section Figure 2-29 for details.
2482 @param[in] Slot The slot number of the Emmc card to send the command to.
2483 @param[in] Rca The relative device address to be assigned.
2484 @param[in] ClockFreq The max clock frequency to be set.
2485 @param[in] IsDdr If TRUE, use dual data rate data simpling method. Otherwise
2486 use single data rate data simpling method.
2487 @param[in] BusWidth The bus width to be set, it could be 4 or 8.
2489 @retval EFI_SUCCESS The operation is done correctly.
2490 @retval Others The operation fails.
2494 EmmcPeimSwitchToHighSpeed (
2495 IN EMMC_PEIM_HC_SLOT
*Slot
,
2497 IN UINT32 ClockFreq
,
2507 Status
= EmmcPeimSwitchBusWidth (Slot
, Rca
, IsDdr
, BusWidth
);
2508 if (EFI_ERROR (Status
)) {
2512 // Set to Hight Speed timing
2515 Status
= EmmcPeimHcOrMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
2516 if (EFI_ERROR (Status
)) {
2520 HostCtrl2
= (UINT8
)~0x7;
2521 Status
= EmmcPeimHcAndMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2522 if (EFI_ERROR (Status
)) {
2527 } else if (ClockFreq
== 52) {
2532 Status
= EmmcPeimHcOrMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2533 if (EFI_ERROR (Status
)) {
2538 Status
= EmmcPeimSwitchClockFreq (Slot
, Rca
, HsTiming
, ClockFreq
);
2544 Switch to the HS200 timing according to request.
2546 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
2547 Simplified Spec 3.0 section Figure 2-29 for details.
2549 @param[in] Slot The slot number of the Emmc card to send the command to.
2550 @param[in] Rca The relative device address to be assigned.
2551 @param[in] ClockFreq The max clock frequency to be set.
2552 @param[in] BusWidth The bus width to be set, it could be 4 or 8.
2554 @retval EFI_SUCCESS The operation is done correctly.
2555 @retval Others The operation fails.
2559 EmmcPeimSwitchToHS200 (
2560 IN EMMC_PEIM_HC_SLOT
*Slot
,
2562 IN UINT32 ClockFreq
,
2571 if ((BusWidth
!= 4) && (BusWidth
!= 8)) {
2572 return EFI_INVALID_PARAMETER
;
2575 Status
= EmmcPeimSwitchBusWidth (Slot
, Rca
, FALSE
, BusWidth
);
2576 if (EFI_ERROR (Status
)) {
2580 // Set to HS200/SDR104 timing
2583 // Stop bus clock at first
2585 Status
= EmmcPeimHcStopClock (Slot
->EmmcHcBase
);
2586 if (EFI_ERROR (Status
)) {
2590 HostCtrl2
= (UINT8
)~0x7;
2591 Status
= EmmcPeimHcAndMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2592 if (EFI_ERROR (Status
)) {
2595 HostCtrl2
= BIT0
| BIT1
;
2596 Status
= EmmcPeimHcOrMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2597 if (EFI_ERROR (Status
)) {
2602 // Wait Internal Clock Stable in the Clock Control register to be 1 before set SD Clock Enable bit
2604 Status
= EmmcPeimHcWaitMmioSet (
2605 Slot
->EmmcHcBase
+ EMMC_HC_CLOCK_CTRL
,
2611 if (EFI_ERROR (Status
)) {
2615 // Set SD Clock Enable in the Clock Control register to 1
2618 Status
= EmmcPeimHcOrMmio (Slot
->EmmcHcBase
+ EMMC_HC_CLOCK_CTRL
, sizeof (ClockCtrl
), &ClockCtrl
);
2621 Status
= EmmcPeimSwitchClockFreq (Slot
, Rca
, HsTiming
, ClockFreq
);
2622 if (EFI_ERROR (Status
)) {
2626 Status
= EmmcPeimTuningClkForHs200 (Slot
, BusWidth
);
2632 Switch to the HS400 timing according to request.
2634 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
2635 Simplified Spec 3.0 section Figure 2-29 for details.
2637 @param[in] Slot The slot number of the Emmc card to send the command to.
2638 @param[in] Rca The relative device address to be assigned.
2639 @param[in] ClockFreq The max clock frequency to be set.
2641 @retval EFI_SUCCESS The operation is done correctly.
2642 @retval Others The operation fails.
2646 EmmcPeimSwitchToHS400 (
2647 IN EMMC_PEIM_HC_SLOT
*Slot
,
2656 Status
= EmmcPeimSwitchToHS200 (Slot
, Rca
, ClockFreq
, 8);
2657 if (EFI_ERROR (Status
)) {
2661 // Set to Hight Speed timing and set the clock frequency to a value less than 52MHz.
2664 Status
= EmmcPeimSwitchClockFreq (Slot
, Rca
, HsTiming
, 52);
2665 if (EFI_ERROR (Status
)) {
2669 // HS400 mode must use 8 data lines.
2671 Status
= EmmcPeimSwitchBusWidth (Slot
, Rca
, TRUE
, 8);
2672 if (EFI_ERROR (Status
)) {
2676 // Set to HS400 timing
2678 HostCtrl2
= (UINT8
)~0x7;
2679 Status
= EmmcPeimHcAndMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2680 if (EFI_ERROR (Status
)) {
2683 HostCtrl2
= BIT0
| BIT2
;
2684 Status
= EmmcPeimHcOrMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2685 if (EFI_ERROR (Status
)) {
2690 Status
= EmmcPeimSwitchClockFreq (Slot
, Rca
, HsTiming
, ClockFreq
);
2696 Switch the high speed timing according to request.
2698 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
2699 Simplified Spec 3.0 section Figure 2-29 for details.
2701 @param[in] Slot The slot number of the Emmc card to send the command to.
2702 @param[in] Rca The relative device address to be assigned.
2704 @retval EFI_SUCCESS The operation is done correctly.
2705 @retval Others The operation fails.
2709 EmmcPeimSetBusMode (
2710 IN EMMC_PEIM_HC_SLOT
*Slot
,
2715 EMMC_HC_SLOT_CAP Capability
;
2721 Status
= EmmcPeimGetCsd (Slot
, Rca
, &Slot
->Csd
);
2722 if (EFI_ERROR (Status
)) {
2723 DEBUG ((EFI_D_ERROR
, "EmmcPeimSetBusMode: EmmcPeimGetCsd fails with %r\n", Status
));
2727 if ((Slot
->Csd
.CSizeLow
| Slot
->Csd
.CSizeHigh
<< 2) == 0xFFF) {
2728 Slot
->SectorAddressing
= TRUE
;
2730 Slot
->SectorAddressing
= FALSE
;
2733 Status
= EmmcPeimSelect (Slot
, Rca
);
2734 if (EFI_ERROR (Status
)) {
2735 DEBUG ((EFI_D_ERROR
, "EmmcPeimSetBusMode: EmmcPeimSelect fails with %r\n", Status
));
2739 Status
= EmmcPeimHcGetCapability (Slot
->EmmcHcBase
, &Capability
);
2740 if (EFI_ERROR (Status
)) {
2741 DEBUG ((EFI_D_ERROR
, "EmmcPeimSetBusMode: EmmcPeimHcGetCapability fails with %r\n", Status
));
2745 ASSERT (Capability
.BaseClkFreq
!= 0);
2747 // Check if the Host Controller support 8bits bus width.
2749 if (Capability
.BusWidth8
!= 0) {
2755 // Get Deivce_Type from EXT_CSD register.
2757 Status
= EmmcPeimGetExtCsd (Slot
, &Slot
->ExtCsd
);
2758 if (EFI_ERROR (Status
)) {
2759 DEBUG ((EFI_D_ERROR
, "EmmcPeimSetBusMode: EmmcPeimGetExtCsd fails with %r\n", Status
));
2763 // Calculate supported bus speed/bus width/clock frequency.
2768 if (((Slot
->ExtCsd
.DeviceType
& (BIT4
| BIT5
)) != 0) && (Capability
.Sdr104
!= 0)) {
2772 } else if (((Slot
->ExtCsd
.DeviceType
& (BIT2
| BIT3
)) != 0) && (Capability
.Ddr50
!= 0)) {
2776 } else if (((Slot
->ExtCsd
.DeviceType
& BIT1
) != 0) && (Capability
.HighSpeed
!= 0)) {
2780 } else if (((Slot
->ExtCsd
.DeviceType
& BIT0
) != 0) && (Capability
.HighSpeed
!= 0)) {
2786 // Check if both of the device and the host controller support HS400 DDR mode.
2788 if (((Slot
->ExtCsd
.DeviceType
& (BIT6
| BIT7
)) != 0) && (Capability
.Hs400
!= 0)) {
2790 // The host controller supports 8bits bus.
2792 ASSERT (BusWidth
== 8);
2798 if ((ClockFreq
== 0) || (HsTiming
== 0)) {
2800 // Continue using default setting.
2805 DEBUG ((EFI_D_INFO
, "HsTiming %d ClockFreq %d BusWidth %d Ddr %a\n", HsTiming
, ClockFreq
, BusWidth
, IsDdr
? "TRUE":"FALSE"));
2807 if (HsTiming
== 3) {
2809 // Execute HS400 timing switch procedure
2811 Status
= EmmcPeimSwitchToHS400 (Slot
, Rca
, ClockFreq
);
2812 } else if (HsTiming
== 2) {
2814 // Execute HS200 timing switch procedure
2816 Status
= EmmcPeimSwitchToHS200 (Slot
, Rca
, ClockFreq
, BusWidth
);
2819 // Execute High Speed timing switch procedure
2821 Status
= EmmcPeimSwitchToHighSpeed (Slot
, Rca
, ClockFreq
, IsDdr
, BusWidth
);
2828 Execute EMMC device identification procedure.
2830 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
2832 @param[in] Slot The slot number of the Emmc card to send the command to.
2834 @retval EFI_SUCCESS There is a EMMC card.
2835 @retval Others There is not a EMMC card.
2839 EmmcPeimIdentification (
2840 IN EMMC_PEIM_HC_SLOT
*Slot
2848 Status
= EmmcPeimReset (Slot
);
2849 if (EFI_ERROR (Status
)) {
2850 DEBUG ((EFI_D_ERROR
, "EmmcPeimIdentification: EmmcPeimReset fails with %r\n", Status
));
2857 Status
= EmmcPeimGetOcr (Slot
, &Ocr
);
2858 if (EFI_ERROR (Status
)) {
2859 DEBUG ((EFI_D_ERROR
, "EmmcPeimIdentification: EmmcPeimGetOcr fails with %r\n", Status
));
2863 if (Retry
++ == 100) {
2864 DEBUG ((EFI_D_ERROR
, "EmmcPeimIdentification: EmmcPeimGetOcr fails too many times\n"));
2865 return EFI_DEVICE_ERROR
;
2867 MicroSecondDelay (10 * 1000);
2868 } while ((Ocr
& BIT31
) == 0);
2870 Status
= EmmcPeimGetAllCid (Slot
);
2871 if (EFI_ERROR (Status
)) {
2872 DEBUG ((EFI_D_ERROR
, "EmmcPeimIdentification: EmmcPeimGetAllCid fails with %r\n", Status
));
2876 // Don't support multiple devices on the slot, that is
2877 // shared bus slot feature.
2880 Status
= EmmcPeimSetRca (Slot
, Rca
);
2881 if (EFI_ERROR (Status
)) {
2882 DEBUG ((EFI_D_ERROR
, "EmmcPeimIdentification: EmmcPeimSetRca fails with %r\n", Status
));
2886 // Enter Data Tranfer Mode.
2888 DEBUG ((EFI_D_INFO
, "Found a EMMC device at slot [%d], RCA [%d]\n", Slot
, Rca
));
2890 Status
= EmmcPeimSetBusMode (Slot
, Rca
);