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
);
56 *(UINT16
*)Data
= MmioRead16 (Address
);
58 MmioWrite16 (Address
, *(UINT16
*)Data
);
64 *(UINT32
*)Data
= MmioRead32 (Address
);
66 MmioWrite32 (Address
, *(UINT32
*)Data
);
72 *(UINT64
*)Data
= MmioRead64 (Address
);
74 MmioWrite64 (Address
, *(UINT64
*)Data
);
80 return EFI_INVALID_PARAMETER
;
87 Do OR operation with the value of the specified EMMC host controller mmio register.
89 @param[in] Address The address of the mmio register to be read/written.
90 @param[in] Count The width of the mmio register in bytes.
91 Must be 1, 2 , 4 or 8 bytes.
92 @param[in] OrData The pointer to the data used to do OR operation.
93 The caller is responsible for having ownership of
94 the data buffer and ensuring its size not less than
97 @retval EFI_INVALID_PARAMETER The Address or the OrData or the Count is not valid.
98 @retval EFI_SUCCESS The OR operation succeeds.
99 @retval Others The OR operation fails.
114 Status
= EmmcPeimHcRwMmio (Address
, TRUE
, Count
, &Data
);
115 if (EFI_ERROR (Status
)) {
120 Or
= *(UINT8
*)OrData
;
121 } else if (Count
== 2) {
122 Or
= *(UINT16
*)OrData
;
123 } else if (Count
== 4) {
124 Or
= *(UINT32
*)OrData
;
125 } else if (Count
== 8) {
126 Or
= *(UINT64
*)OrData
;
128 return EFI_INVALID_PARAMETER
;
132 Status
= EmmcPeimHcRwMmio (Address
, FALSE
, Count
, &Data
);
138 Do AND operation with the value of the specified EMMC host controller mmio register.
140 @param[in] Address The address of the mmio register to be read/written.
141 @param[in] Count The width of the mmio register in bytes.
142 Must be 1, 2 , 4 or 8 bytes.
143 @param[in] AndData The pointer to the data used to do AND operation.
144 The caller is responsible for having ownership of
145 the data buffer and ensuring its size not less than
148 @retval EFI_INVALID_PARAMETER The Address or the AndData or the Count is not valid.
149 @retval EFI_SUCCESS The AND operation succeeds.
150 @retval Others The AND operation fails.
165 Status
= EmmcPeimHcRwMmio (Address
, TRUE
, Count
, &Data
);
166 if (EFI_ERROR (Status
)) {
171 And
= *(UINT8
*)AndData
;
172 } else if (Count
== 2) {
173 And
= *(UINT16
*)AndData
;
174 } else if (Count
== 4) {
175 And
= *(UINT32
*)AndData
;
176 } else if (Count
== 8) {
177 And
= *(UINT64
*)AndData
;
179 return EFI_INVALID_PARAMETER
;
183 Status
= EmmcPeimHcRwMmio (Address
, FALSE
, Count
, &Data
);
189 Wait for the value of the specified MMIO register set to the test value.
191 @param[in] Address The address of the mmio register to be checked.
192 @param[in] Count The width of the mmio register in bytes.
193 Must be 1, 2, 4 or 8 bytes.
194 @param[in] MaskValue The mask value of memory.
195 @param[in] TestValue The test value of memory.
197 @retval EFI_NOT_READY The MMIO register hasn't set to the expected value.
198 @retval EFI_SUCCESS The MMIO register has expected value.
199 @retval Others The MMIO operation fails.
204 EmmcPeimHcCheckMmioSet (
215 // Access PCI MMIO space to see if the value is the tested one.
218 Status
= EmmcPeimHcRwMmio (Address
, TRUE
, Count
, &Value
);
219 if (EFI_ERROR (Status
)) {
225 if (Value
== TestValue
) {
229 return EFI_NOT_READY
;
233 Wait for the value of the specified MMIO register set to the test value.
235 @param[in] Address The address of the mmio register to wait.
236 @param[in] Count The width of the mmio register in bytes.
237 Must be 1, 2, 4 or 8 bytes.
238 @param[in] MaskValue The mask value of memory.
239 @param[in] TestValue The test value of memory.
240 @param[in] Timeout The time out value for wait memory set, uses 1
241 microsecond as a unit.
243 @retval EFI_TIMEOUT The MMIO register hasn't expected value in timeout
245 @retval EFI_SUCCESS The MMIO register has expected value.
246 @retval Others The MMIO operation fails.
251 EmmcPeimHcWaitMmioSet (
260 BOOLEAN InfiniteWait
;
265 InfiniteWait
= FALSE
;
268 while (InfiniteWait
|| (Timeout
> 0)) {
269 Status
= EmmcPeimHcCheckMmioSet (
275 if (Status
!= EFI_NOT_READY
) {
280 // Stall for 1 microsecond.
282 MicroSecondDelay (1);
291 Software reset the specified EMMC host controller and enable all interrupts.
293 @param[in] Bar The mmio base address of the slot to be accessed.
295 @retval EFI_SUCCESS The software reset executes successfully.
296 @retval Others The software reset fails.
308 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_SW_RST
, FALSE
, sizeof (SwReset
), &SwReset
);
310 if (EFI_ERROR (Status
)) {
311 DEBUG ((DEBUG_ERROR
, "EmmcPeimHcReset: write full 1 fails: %r\n", Status
));
315 Status
= EmmcPeimHcWaitMmioSet (
316 Bar
+ EMMC_HC_SW_RST
,
322 if (EFI_ERROR (Status
)) {
323 DEBUG ((DEBUG_INFO
, "EmmcPeimHcReset: reset done with %r\n", Status
));
328 // Enable all interrupt after reset all.
330 Status
= EmmcPeimHcEnableInterrupt (Bar
);
336 Set all interrupt status bits in Normal and Error Interrupt Status Enable
339 @param[in] Bar The mmio base address of the slot to be accessed.
341 @retval EFI_SUCCESS The operation executes successfully.
342 @retval Others The operation fails.
346 EmmcPeimHcEnableInterrupt (
354 // Enable all bits in Error Interrupt Status Enable Register
357 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_ERR_INT_STS_EN
, FALSE
, sizeof (IntStatus
), &IntStatus
);
358 if (EFI_ERROR (Status
)) {
363 // Enable all bits in Normal Interrupt Status Enable Register
366 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_NOR_INT_STS_EN
, FALSE
, sizeof (IntStatus
), &IntStatus
);
372 Get the capability data from the specified slot.
374 @param[in] Bar The mmio base address of the slot to be accessed.
375 @param[out] Capability The buffer to store the capability data.
377 @retval EFI_SUCCESS The operation executes successfully.
378 @retval Others The operation fails.
382 EmmcPeimHcGetCapability (
384 OUT EMMC_HC_SLOT_CAP
*Capability
390 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_CAP
, TRUE
, sizeof (Cap
), &Cap
);
391 if (EFI_ERROR (Status
)) {
395 CopyMem (Capability
, &Cap
, sizeof (Cap
));
401 Detect whether there is a EMMC card attached at the specified EMMC host controller
404 Refer to SD Host Controller Simplified spec 3.0 Section 3.1 for details.
406 @param[in] Bar The mmio base address of the slot to be accessed.
408 @retval EFI_SUCCESS There is a EMMC card attached.
409 @retval EFI_NO_MEDIA There is not a EMMC card attached.
410 @retval Others The detection fails.
414 EmmcPeimHcCardDetect (
423 // Check Normal Interrupt Status Register
425 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_NOR_INT_STS
, TRUE
, sizeof (Data
), &Data
);
426 if (EFI_ERROR (Status
)) {
430 if ((Data
& (BIT6
| BIT7
)) != 0) {
432 // Clear BIT6 and BIT7 by writing 1 to these two bits if set.
435 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_NOR_INT_STS
, FALSE
, sizeof (Data
), &Data
);
436 if (EFI_ERROR (Status
)) {
442 // Check Present State Register to see if there is a card presented.
444 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_PRESENT_STATE
, TRUE
, sizeof (PresentState
), &PresentState
);
445 if (EFI_ERROR (Status
)) {
449 if ((PresentState
& BIT16
) != 0) {
457 Stop EMMC card clock.
459 Refer to SD Host Controller Simplified spec 3.0 Section 3.2.2 for details.
461 @param[in] Bar The mmio base address of the slot to be accessed.
463 @retval EFI_SUCCESS Succeed to stop EMMC clock.
464 @retval Others Fail to stop EMMC clock.
468 EmmcPeimHcStopClock (
477 // Ensure no SD transactions are occurring on the SD Bus by
478 // waiting for Command Inhibit (DAT) and Command Inhibit (CMD)
479 // in the Present State register to be 0.
481 Status
= EmmcPeimHcWaitMmioSet (
482 Bar
+ EMMC_HC_PRESENT_STATE
,
483 sizeof (PresentState
),
488 if (EFI_ERROR (Status
)) {
493 // Set SD Clock Enable in the Clock Control register to 0
495 ClockCtrl
= (UINT16
) ~BIT2
;
496 Status
= EmmcPeimHcAndMmio (Bar
+ EMMC_HC_CLOCK_CTRL
, sizeof (ClockCtrl
), &ClockCtrl
);
502 EMMC card clock supply.
504 Refer to SD Host Controller Simplified spec 3.0 Section 3.2.1 for details.
506 @param[in] Bar The mmio base address of the slot to be accessed.
507 @param[in] ClockFreq The max clock frequency to be set. The unit is KHz.
509 @retval EFI_SUCCESS The clock is supplied successfully.
510 @retval Others The clock isn't supplied successfully.
514 EmmcPeimHcClockSupply (
520 EMMC_HC_SLOT_CAP Capability
;
525 UINT16 ControllerVer
;
529 // Calculate a divisor for SD clock frequency
531 Status
= EmmcPeimHcGetCapability (Bar
, &Capability
);
532 if (EFI_ERROR (Status
)) {
536 ASSERT (Capability
.BaseClkFreq
!= 0);
538 BaseClkFreq
= Capability
.BaseClkFreq
;
540 if (ClockFreq
== 0) {
541 return EFI_INVALID_PARAMETER
;
544 if (ClockFreq
> (BaseClkFreq
* 1000)) {
545 ClockFreq
= BaseClkFreq
* 1000;
549 // Calculate the divisor of base frequency.
552 SettingFreq
= BaseClkFreq
* 1000;
553 while (ClockFreq
< SettingFreq
) {
556 SettingFreq
= (BaseClkFreq
* 1000) / (2 * Divisor
);
557 Remainder
= (BaseClkFreq
* 1000) % (2 * Divisor
);
558 if ((ClockFreq
== SettingFreq
) && (Remainder
== 0)) {
562 if ((ClockFreq
== SettingFreq
) && (Remainder
!= 0)) {
567 DEBUG ((DEBUG_INFO
, "BaseClkFreq %dMHz Divisor %d ClockFreq %dKhz\n", BaseClkFreq
, Divisor
, ClockFreq
));
569 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_CTRL_VER
, TRUE
, sizeof (ControllerVer
), &ControllerVer
);
570 if (EFI_ERROR (Status
)) {
575 // Set SDCLK Frequency Select and Internal Clock Enable fields in Clock Control register.
577 if ((ControllerVer
& 0xFF) == 2) {
578 ASSERT (Divisor
<= 0x3FF);
579 ClockCtrl
= ((Divisor
& 0xFF) << 8) | ((Divisor
& 0x300) >> 2);
580 } else if (((ControllerVer
& 0xFF) == 0) || ((ControllerVer
& 0xFF) == 1)) {
582 // Only the most significant bit can be used as divisor.
584 if (((Divisor
- 1) & Divisor
) != 0) {
585 Divisor
= 1 << (HighBitSet32 (Divisor
) + 1);
588 ASSERT (Divisor
<= 0x80);
589 ClockCtrl
= (Divisor
& 0xFF) << 8;
591 DEBUG ((DEBUG_ERROR
, "Unknown SD Host Controller Spec version [0x%x]!!!\n", ControllerVer
));
592 return EFI_UNSUPPORTED
;
596 // Stop bus clock at first
598 Status
= EmmcPeimHcStopClock (Bar
);
599 if (EFI_ERROR (Status
)) {
604 // Supply clock frequency with specified divisor
607 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_CLOCK_CTRL
, FALSE
, sizeof (ClockCtrl
), &ClockCtrl
);
608 if (EFI_ERROR (Status
)) {
609 DEBUG ((DEBUG_ERROR
, "Set SDCLK Frequency Select and Internal Clock Enable fields fails\n"));
614 // Wait Internal Clock Stable in the Clock Control register to be 1
616 Status
= EmmcPeimHcWaitMmioSet (
617 Bar
+ EMMC_HC_CLOCK_CTRL
,
623 if (EFI_ERROR (Status
)) {
628 // Set SD Clock Enable in the Clock Control register to 1
631 Status
= EmmcPeimHcOrMmio (Bar
+ EMMC_HC_CLOCK_CTRL
, sizeof (ClockCtrl
), &ClockCtrl
);
637 EMMC bus power control.
639 Refer to SD Host Controller Simplified spec 3.0 Section 3.3 for details.
641 @param[in] Bar The mmio base address of the slot to be accessed.
642 @param[in] PowerCtrl The value setting to the power control register.
644 @retval TRUE There is a EMMC card attached.
645 @retval FALSE There is no a EMMC card attached.
649 EmmcPeimHcPowerControl (
659 PowerCtrl
&= (UINT8
) ~BIT0
;
660 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_POWER_CTRL
, FALSE
, sizeof (PowerCtrl
), &PowerCtrl
);
661 if (EFI_ERROR (Status
)) {
666 // Set SD Bus Voltage Select and SD Bus Power fields in Power Control Register
669 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_POWER_CTRL
, FALSE
, sizeof (PowerCtrl
), &PowerCtrl
);
675 Set the EMMC bus width.
677 Refer to SD Host Controller Simplified spec 3.0 Section 3.4 for details.
679 @param[in] Bar The mmio base address of the slot to be accessed.
680 @param[in] BusWidth The bus width used by the EMMC device, it must be 1, 4 or 8.
682 @retval EFI_SUCCESS The bus width is set successfully.
683 @retval Others The bus width isn't set successfully.
687 EmmcPeimHcSetBusWidth (
696 HostCtrl1
= (UINT8
) ~(BIT5
| BIT1
);
697 Status
= EmmcPeimHcAndMmio (Bar
+ EMMC_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
698 } else if (BusWidth
== 4) {
699 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_HOST_CTRL1
, TRUE
, sizeof (HostCtrl1
), &HostCtrl1
);
700 if (EFI_ERROR (Status
)) {
705 HostCtrl1
&= (UINT8
) ~BIT5
;
706 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_HOST_CTRL1
, FALSE
, sizeof (HostCtrl1
), &HostCtrl1
);
707 } else if (BusWidth
== 8) {
708 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_HOST_CTRL1
, TRUE
, sizeof (HostCtrl1
), &HostCtrl1
);
709 if (EFI_ERROR (Status
)) {
713 HostCtrl1
&= (UINT8
) ~BIT1
;
715 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_HOST_CTRL1
, FALSE
, sizeof (HostCtrl1
), &HostCtrl1
);
718 return EFI_INVALID_PARAMETER
;
725 Supply EMMC card with lowest clock frequency at initialization.
727 @param[in] Bar The mmio base address of the slot to be accessed.
729 @retval EFI_SUCCESS The clock is supplied successfully.
730 @retval Others The clock isn't supplied successfully.
734 EmmcPeimHcInitClockFreq (
739 EMMC_HC_SLOT_CAP Capability
;
743 // Calculate a divisor for SD clock frequency
745 Status
= EmmcPeimHcGetCapability (Bar
, &Capability
);
746 if (EFI_ERROR (Status
)) {
750 if (Capability
.BaseClkFreq
== 0) {
752 // Don't support get Base Clock Frequency information via another method
754 return EFI_UNSUPPORTED
;
758 // Supply 400KHz clock frequency at initialization phase.
761 Status
= EmmcPeimHcClockSupply (Bar
, InitFreq
);
766 Supply EMMC card with maximum voltage at initialization.
768 Refer to SD Host Controller Simplified spec 3.0 Section 3.3 for details.
770 @param[in] Bar The mmio base address of the slot to be accessed.
772 @retval EFI_SUCCESS The voltage is supplied successfully.
773 @retval Others The voltage isn't supplied successfully.
777 EmmcPeimHcInitPowerVoltage (
782 EMMC_HC_SLOT_CAP Capability
;
787 // Get the support voltage of the Host Controller
789 Status
= EmmcPeimHcGetCapability (Bar
, &Capability
);
790 if (EFI_ERROR (Status
)) {
795 // Calculate supported maximum voltage according to SD Bus Voltage Select
797 if (Capability
.Voltage33
!= 0) {
802 } else if (Capability
.Voltage30
!= 0) {
807 } else if (Capability
.Voltage18
!= 0) {
813 Status
= EmmcPeimHcOrMmio (Bar
+ EMMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
814 if (EFI_ERROR (Status
)) {
818 MicroSecondDelay (5000);
821 return EFI_DEVICE_ERROR
;
825 // Set SD Bus Voltage Select and SD Bus Power fields in Power Control Register
827 Status
= EmmcPeimHcPowerControl (Bar
, MaxVoltage
);
833 Initialize the Timeout Control register with most conservative value at initialization.
835 Refer to SD Host Controller Simplified spec 3.0 Section 2.2.15 for details.
837 @param[in] Bar The mmio base address of the slot to be accessed.
839 @retval EFI_SUCCESS The timeout control register is configured successfully.
840 @retval Others The timeout control register isn't configured successfully.
844 EmmcPeimHcInitTimeoutCtrl (
852 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_TIMEOUT_CTRL
, FALSE
, sizeof (Timeout
), &Timeout
);
858 Initial EMMC host controller with lowest clock frequency, max power and max timeout value
861 @param[in] Bar The mmio base address of the slot to be accessed.
863 @retval EFI_SUCCESS The host controller is initialized successfully.
864 @retval Others The host controller isn't initialized successfully.
874 Status
= EmmcPeimHcInitClockFreq (Bar
);
875 if (EFI_ERROR (Status
)) {
879 Status
= EmmcPeimHcInitPowerVoltage (Bar
);
880 if (EFI_ERROR (Status
)) {
884 Status
= EmmcPeimHcInitTimeoutCtrl (Bar
);
891 @param[in] Bar The mmio base address of the slot to be accessed.
892 @param[in] On The boolean to turn on/off LED.
894 @retval EFI_SUCCESS The LED is turned on/off successfully.
895 @retval Others The LED isn't turned on/off successfully.
909 Status
= EmmcPeimHcOrMmio (Bar
+ EMMC_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
911 HostCtrl1
= (UINT8
) ~BIT0
;
912 Status
= EmmcPeimHcAndMmio (Bar
+ EMMC_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
919 Build ADMA descriptor table for transfer.
921 Refer to SD Host Controller Simplified spec 3.0 Section 1.13 for details.
923 @param[in] Trb The pointer to the EMMC_TRB instance.
925 @retval EFI_SUCCESS The ADMA descriptor table is created successfully.
926 @retval Others The ADMA descriptor table isn't created successfully.
934 EFI_PHYSICAL_ADDRESS Data
;
942 DataLen
= Trb
->DataLen
;
944 // Only support 32bit ADMA Descriptor Table
946 if ((Data
>= 0x100000000ul
) || ((Data
+ DataLen
) > 0x100000000ul
)) {
947 return EFI_INVALID_PARAMETER
;
951 // Address field shall be set on 32-bit boundary (Lower 2-bit is always set to 0)
952 // for 32-bit address descriptor table.
954 if ((Data
& (BIT0
| BIT1
)) != 0) {
955 DEBUG ((DEBUG_INFO
, "The buffer [0x%x] to construct ADMA desc is not aligned to 4 bytes boundary!\n", Data
));
958 Entries
= DivU64x32 ((DataLen
+ ADMA_MAX_DATA_PER_LINE
- 1), ADMA_MAX_DATA_PER_LINE
);
960 Trb
->AdmaDescSize
= (UINTN
)MultU64x32 (Entries
, sizeof (EMMC_HC_ADMA_DESC_LINE
));
961 Trb
->AdmaDesc
= EmmcPeimAllocateMem (Trb
->Slot
->Private
->Pool
, Trb
->AdmaDescSize
);
962 if (Trb
->AdmaDesc
== NULL
) {
963 return EFI_OUT_OF_RESOURCES
;
967 Address
= (UINT32
)Data
;
968 for (Index
= 0; Index
< Entries
; Index
++) {
969 if (Remaining
<= ADMA_MAX_DATA_PER_LINE
) {
970 Trb
->AdmaDesc
[Index
].Valid
= 1;
971 Trb
->AdmaDesc
[Index
].Act
= 2;
972 Trb
->AdmaDesc
[Index
].Length
= (UINT16
)Remaining
;
973 Trb
->AdmaDesc
[Index
].Address
= Address
;
976 Trb
->AdmaDesc
[Index
].Valid
= 1;
977 Trb
->AdmaDesc
[Index
].Act
= 2;
978 Trb
->AdmaDesc
[Index
].Length
= 0;
979 Trb
->AdmaDesc
[Index
].Address
= Address
;
982 Remaining
-= ADMA_MAX_DATA_PER_LINE
;
983 Address
+= ADMA_MAX_DATA_PER_LINE
;
987 // Set the last descriptor line as end of descriptor table
989 Trb
->AdmaDesc
[Index
].End
= 1;
994 Create a new TRB for the EMMC cmd request.
996 @param[in] Slot The slot number of the EMMC card to send the command to.
997 @param[in] Packet A pointer to the SD command data structure.
999 @return Created Trb or NULL.
1004 IN EMMC_PEIM_HC_SLOT
*Slot
,
1005 IN EMMC_COMMAND_PACKET
*Packet
1010 EMMC_HC_SLOT_CAP Capability
;
1011 EDKII_IOMMU_OPERATION MapOp
;
1015 // Calculate a divisor for SD clock frequency
1017 Status
= EmmcPeimHcGetCapability (Slot
->EmmcHcBase
, &Capability
);
1018 if (EFI_ERROR (Status
)) {
1022 Trb
= AllocateZeroPool (sizeof (EMMC_TRB
));
1028 Trb
->BlockSize
= 0x200;
1029 Trb
->Packet
= Packet
;
1030 Trb
->Timeout
= Packet
->Timeout
;
1032 if ((Packet
->InTransferLength
!= 0) && (Packet
->InDataBuffer
!= NULL
)) {
1033 Trb
->Data
= Packet
->InDataBuffer
;
1034 Trb
->DataLen
= Packet
->InTransferLength
;
1036 } else if ((Packet
->OutTransferLength
!= 0) && (Packet
->OutDataBuffer
!= NULL
)) {
1037 Trb
->Data
= Packet
->OutDataBuffer
;
1038 Trb
->DataLen
= Packet
->OutTransferLength
;
1040 } else if ((Packet
->InTransferLength
== 0) && (Packet
->OutTransferLength
== 0)) {
1047 if ((Trb
->DataLen
!= 0) && (Trb
->DataLen
< Trb
->BlockSize
)) {
1048 Trb
->BlockSize
= (UINT16
)Trb
->DataLen
;
1051 if (Packet
->EmmcCmdBlk
->CommandIndex
== EMMC_SEND_TUNING_BLOCK
) {
1052 Trb
->Mode
= EmmcPioMode
;
1055 MapOp
= EdkiiIoMmuOperationBusMasterWrite
;
1057 MapOp
= EdkiiIoMmuOperationBusMasterRead
;
1060 if (Trb
->DataLen
!= 0) {
1061 MapLength
= Trb
->DataLen
;
1062 Status
= IoMmuMap (MapOp
, Trb
->Data
, &MapLength
, &Trb
->DataPhy
, &Trb
->DataMap
);
1064 if (EFI_ERROR (Status
) || (MapLength
!= Trb
->DataLen
)) {
1065 DEBUG ((DEBUG_ERROR
, "EmmcPeimCreateTrb: Fail to map data buffer.\n"));
1070 if (Trb
->DataLen
== 0) {
1071 Trb
->Mode
= EmmcNoData
;
1072 } else if (Capability
.Adma2
!= 0) {
1073 Trb
->Mode
= EmmcAdmaMode
;
1074 Status
= BuildAdmaDescTable (Trb
);
1075 if (EFI_ERROR (Status
)) {
1078 } else if (Capability
.Sdma
!= 0) {
1079 Trb
->Mode
= EmmcSdmaMode
;
1081 Trb
->Mode
= EmmcPioMode
;
1088 EmmcPeimFreeTrb (Trb
);
1093 Free the resource used by the TRB.
1095 @param[in] Trb The pointer to the EMMC_TRB instance.
1103 if ((Trb
!= NULL
) && (Trb
->DataMap
!= NULL
)) {
1104 IoMmuUnmap (Trb
->DataMap
);
1107 if ((Trb
!= NULL
) && (Trb
->AdmaDesc
!= NULL
)) {
1108 EmmcPeimFreeMem (Trb
->Slot
->Private
->Pool
, Trb
->AdmaDesc
, Trb
->AdmaDescSize
);
1119 Check if the env is ready for execute specified TRB.
1121 @param[in] Bar The mmio base address of the slot to be accessed.
1122 @param[in] Trb The pointer to the EMMC_TRB instance.
1124 @retval EFI_SUCCESS The env is ready for TRB execution.
1125 @retval EFI_NOT_READY The env is not ready for TRB execution.
1126 @retval Others Some erros happen.
1130 EmmcPeimCheckTrbEnv (
1136 EMMC_COMMAND_PACKET
*Packet
;
1137 UINT32 PresentState
;
1139 Packet
= Trb
->Packet
;
1141 if ((Packet
->EmmcCmdBlk
->CommandType
== EmmcCommandTypeAdtc
) ||
1142 (Packet
->EmmcCmdBlk
->ResponseType
== EmmcResponceTypeR1b
) ||
1143 (Packet
->EmmcCmdBlk
->ResponseType
== EmmcResponceTypeR5b
))
1146 // Wait Command Inhibit (CMD) and Command Inhibit (DAT) in
1147 // the Present State register to be 0
1149 PresentState
= BIT0
| BIT1
;
1152 // Wait Command Inhibit (CMD) in the Present State register
1155 PresentState
= BIT0
;
1158 Status
= EmmcPeimHcCheckMmioSet (
1159 Bar
+ EMMC_HC_PRESENT_STATE
,
1160 sizeof (PresentState
),
1169 Wait for the env to be ready for execute specified TRB.
1171 @param[in] Bar The mmio base address of the slot to be accessed.
1172 @param[in] Trb The pointer to the EMMC_TRB instance.
1174 @retval EFI_SUCCESS The env is ready for TRB execution.
1175 @retval EFI_TIMEOUT The env is not ready for TRB execution in time.
1176 @retval Others Some erros happen.
1180 EmmcPeimWaitTrbEnv (
1186 EMMC_COMMAND_PACKET
*Packet
;
1188 BOOLEAN InfiniteWait
;
1191 // Wait Command Complete Interrupt Status bit in Normal Interrupt Status Register
1193 Packet
= Trb
->Packet
;
1194 Timeout
= Packet
->Timeout
;
1196 InfiniteWait
= TRUE
;
1198 InfiniteWait
= FALSE
;
1201 while (InfiniteWait
|| (Timeout
> 0)) {
1203 // Check Trb execution result by reading Normal Interrupt Status register.
1205 Status
= EmmcPeimCheckTrbEnv (Bar
, Trb
);
1206 if (Status
!= EFI_NOT_READY
) {
1211 // Stall for 1 microsecond.
1213 MicroSecondDelay (1);
1222 Execute the specified TRB.
1224 @param[in] Bar The mmio base address of the slot to be accessed.
1225 @param[in] Trb The pointer to the EMMC_TRB instance.
1227 @retval EFI_SUCCESS The TRB is sent to host controller successfully.
1228 @retval Others Some erros happen when sending this request to the host controller.
1238 EMMC_COMMAND_PACKET
*Packet
;
1249 Packet
= Trb
->Packet
;
1251 // Clear all bits in Error Interrupt Status Register
1254 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_ERR_INT_STS
, FALSE
, sizeof (IntStatus
), &IntStatus
);
1255 if (EFI_ERROR (Status
)) {
1260 // Clear all bits in Normal Interrupt Status Register
1263 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_NOR_INT_STS
, FALSE
, sizeof (IntStatus
), &IntStatus
);
1264 if (EFI_ERROR (Status
)) {
1269 // Set Host Control 1 register DMA Select field
1271 if (Trb
->Mode
== EmmcAdmaMode
) {
1273 Status
= EmmcPeimHcOrMmio (Bar
+ EMMC_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
1274 if (EFI_ERROR (Status
)) {
1279 EmmcPeimHcLedOnOff (Bar
, TRUE
);
1281 if (Trb
->Mode
== EmmcSdmaMode
) {
1282 if ((UINT64
)(UINTN
)Trb
->DataPhy
>= 0x100000000ul
) {
1283 return EFI_INVALID_PARAMETER
;
1286 SdmaAddr
= (UINT32
)(UINTN
)Trb
->DataPhy
;
1287 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_SDMA_ADDR
, FALSE
, sizeof (SdmaAddr
), &SdmaAddr
);
1288 if (EFI_ERROR (Status
)) {
1291 } else if (Trb
->Mode
== EmmcAdmaMode
) {
1292 AdmaAddr
= (UINT64
)(UINTN
)Trb
->AdmaDesc
;
1293 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_ADMA_SYS_ADDR
, FALSE
, sizeof (AdmaAddr
), &AdmaAddr
);
1294 if (EFI_ERROR (Status
)) {
1299 BlkSize
= Trb
->BlockSize
;
1300 if (Trb
->Mode
== EmmcSdmaMode
) {
1302 // Set SDMA boundary to be 512K bytes.
1307 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_BLK_SIZE
, FALSE
, sizeof (BlkSize
), &BlkSize
);
1308 if (EFI_ERROR (Status
)) {
1313 if (Trb
->Mode
!= EmmcNoData
) {
1315 // Calculate Block Count.
1317 BlkCount
= (UINT16
)(Trb
->DataLen
/ Trb
->BlockSize
);
1320 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_BLK_COUNT
, FALSE
, sizeof (BlkCount
), &BlkCount
);
1321 if (EFI_ERROR (Status
)) {
1325 Argument
= Packet
->EmmcCmdBlk
->CommandArgument
;
1326 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_ARG1
, FALSE
, sizeof (Argument
), &Argument
);
1327 if (EFI_ERROR (Status
)) {
1332 if (Trb
->Mode
!= EmmcNoData
) {
1333 if (Trb
->Mode
!= EmmcPioMode
) {
1342 TransMode
|= BIT5
| BIT1
;
1346 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_TRANS_MOD
, FALSE
, sizeof (TransMode
), &TransMode
);
1347 if (EFI_ERROR (Status
)) {
1351 Cmd
= (UINT16
)LShiftU64 (Packet
->EmmcCmdBlk
->CommandIndex
, 8);
1352 if (Packet
->EmmcCmdBlk
->CommandType
== EmmcCommandTypeAdtc
) {
1357 // Convert ResponseType to value
1359 if (Packet
->EmmcCmdBlk
->CommandType
!= EmmcCommandTypeBc
) {
1360 switch (Packet
->EmmcCmdBlk
->ResponseType
) {
1361 case EmmcResponceTypeR1
:
1362 case EmmcResponceTypeR5
:
1363 case EmmcResponceTypeR6
:
1364 case EmmcResponceTypeR7
:
1365 Cmd
|= (BIT1
| BIT3
| BIT4
);
1367 case EmmcResponceTypeR2
:
1368 Cmd
|= (BIT0
| BIT3
);
1370 case EmmcResponceTypeR3
:
1371 case EmmcResponceTypeR4
:
1374 case EmmcResponceTypeR1b
:
1375 case EmmcResponceTypeR5b
:
1376 Cmd
|= (BIT0
| BIT1
| BIT3
| BIT4
);
1387 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_COMMAND
, FALSE
, sizeof (Cmd
), &Cmd
);
1392 Check the TRB execution result.
1394 @param[in] Bar The mmio base address of the slot to be accessed.
1395 @param[in] Trb The pointer to the EMMC_TRB instance.
1397 @retval EFI_SUCCESS The TRB is executed successfully.
1398 @retval EFI_NOT_READY The TRB is not completed for execution.
1399 @retval Others Some erros happen when executing this request.
1403 EmmcPeimCheckTrbResult (
1409 EMMC_COMMAND_PACKET
*Packet
;
1418 Packet
= Trb
->Packet
;
1420 // Check Trb execution result by reading Normal Interrupt Status register.
1422 Status
= EmmcPeimHcRwMmio (
1423 Bar
+ EMMC_HC_NOR_INT_STS
,
1428 if (EFI_ERROR (Status
)) {
1433 // Check Transfer Complete bit is set or not.
1435 if ((IntStatus
& BIT1
) == BIT1
) {
1436 if ((IntStatus
& BIT15
) == BIT15
) {
1438 // Read Error Interrupt Status register to check if the error is
1439 // Data Timeout Error.
1440 // If yes, treat it as success as Transfer Complete has higher
1441 // priority than Data Timeout Error.
1443 Status
= EmmcPeimHcRwMmio (
1444 Bar
+ EMMC_HC_ERR_INT_STS
,
1449 if (!EFI_ERROR (Status
)) {
1450 if ((IntStatus
& BIT4
) == BIT4
) {
1451 Status
= EFI_SUCCESS
;
1453 Status
= EFI_DEVICE_ERROR
;
1462 // Check if there is a error happened during cmd execution.
1463 // If yes, then do error recovery procedure to follow SD Host Controller
1464 // Simplified Spec 3.0 section 3.10.1.
1466 if ((IntStatus
& BIT15
) == BIT15
) {
1467 Status
= EmmcPeimHcRwMmio (
1468 Bar
+ EMMC_HC_ERR_INT_STS
,
1473 if (EFI_ERROR (Status
)) {
1477 if ((IntStatus
& 0x0F) != 0) {
1481 if ((IntStatus
& 0xF0) != 0) {
1485 Status
= EmmcPeimHcRwMmio (
1486 Bar
+ EMMC_HC_SW_RST
,
1491 if (EFI_ERROR (Status
)) {
1495 Status
= EmmcPeimHcWaitMmioSet (
1496 Bar
+ EMMC_HC_SW_RST
,
1502 if (EFI_ERROR (Status
)) {
1506 Status
= EFI_DEVICE_ERROR
;
1511 // Check if DMA interrupt is signalled for the SDMA transfer.
1513 if ((Trb
->Mode
== EmmcSdmaMode
) && ((IntStatus
& BIT3
) == BIT3
)) {
1515 // Clear DMA interrupt bit.
1518 Status
= EmmcPeimHcRwMmio (
1519 Bar
+ EMMC_HC_NOR_INT_STS
,
1524 if (EFI_ERROR (Status
)) {
1529 // Update SDMA Address register.
1531 SdmaAddr
= EMMC_SDMA_ROUND_UP ((UINT32
)(UINTN
)Trb
->DataPhy
, EMMC_SDMA_BOUNDARY
);
1532 Status
= EmmcPeimHcRwMmio (
1533 Bar
+ EMMC_HC_SDMA_ADDR
,
1538 if (EFI_ERROR (Status
)) {
1542 Trb
->DataPhy
= (UINT32
)(UINTN
)SdmaAddr
;
1545 if ((Packet
->EmmcCmdBlk
->CommandType
!= EmmcCommandTypeAdtc
) &&
1546 (Packet
->EmmcCmdBlk
->ResponseType
!= EmmcResponceTypeR1b
) &&
1547 (Packet
->EmmcCmdBlk
->ResponseType
!= EmmcResponceTypeR5b
))
1549 if ((IntStatus
& BIT0
) == BIT0
) {
1550 Status
= EFI_SUCCESS
;
1555 if (Packet
->EmmcCmdBlk
->CommandIndex
== EMMC_SEND_TUNING_BLOCK
) {
1557 // When performing tuning procedure (Execute Tuning is set to 1) through PIO mode,
1558 // wait Buffer Read Ready bit of Normal Interrupt Status Register to be 1.
1559 // Refer to SD Host Controller Simplified Specification 3.0 figure 2-29 for details.
1561 if ((IntStatus
& BIT5
) == BIT5
) {
1563 // Clear Buffer Read Ready interrupt at first.
1566 EmmcPeimHcRwMmio (Bar
+ EMMC_HC_NOR_INT_STS
, FALSE
, sizeof (IntStatus
), &IntStatus
);
1568 // Read data out from Buffer Port register
1570 for (PioLength
= 0; PioLength
< Trb
->DataLen
; PioLength
+= 4) {
1571 EmmcPeimHcRwMmio (Bar
+ EMMC_HC_BUF_DAT_PORT
, TRUE
, 4, (UINT8
*)Trb
->Data
+ PioLength
);
1574 Status
= EFI_SUCCESS
;
1579 Status
= EFI_NOT_READY
;
1582 // Get response data when the cmd is executed successfully.
1584 if (!EFI_ERROR (Status
)) {
1585 if (Packet
->EmmcCmdBlk
->CommandType
!= EmmcCommandTypeBc
) {
1586 for (Index
= 0; Index
< 4; Index
++) {
1587 Status
= EmmcPeimHcRwMmio (
1588 Bar
+ EMMC_HC_RESPONSE
+ Index
* 4,
1593 if (EFI_ERROR (Status
)) {
1594 EmmcPeimHcLedOnOff (Bar
, FALSE
);
1599 CopyMem (Packet
->EmmcStatusBlk
, Response
, sizeof (Response
));
1603 if (Status
!= EFI_NOT_READY
) {
1604 EmmcPeimHcLedOnOff (Bar
, FALSE
);
1611 Wait for the TRB execution result.
1613 @param[in] Bar The mmio base address of the slot to be accessed.
1614 @param[in] Trb The pointer to the EMMC_TRB instance.
1616 @retval EFI_SUCCESS The TRB is executed successfully.
1617 @retval Others Some erros happen when executing this request.
1621 EmmcPeimWaitTrbResult (
1627 EMMC_COMMAND_PACKET
*Packet
;
1629 BOOLEAN InfiniteWait
;
1631 Packet
= Trb
->Packet
;
1633 // Wait Command Complete Interrupt Status bit in Normal Interrupt Status Register
1635 Timeout
= Packet
->Timeout
;
1637 InfiniteWait
= TRUE
;
1639 InfiniteWait
= FALSE
;
1642 while (InfiniteWait
|| (Timeout
> 0)) {
1644 // Check Trb execution result by reading Normal Interrupt Status register.
1646 Status
= EmmcPeimCheckTrbResult (Bar
, Trb
);
1647 if (Status
!= EFI_NOT_READY
) {
1652 // Stall for 1 microsecond.
1654 MicroSecondDelay (1);
1663 Sends EMMC command to an EMMC card that is attached to the EMMC controller.
1665 If Packet is successfully sent to the EMMC card, then EFI_SUCCESS is returned.
1667 If a device error occurs while sending the Packet, then EFI_DEVICE_ERROR is returned.
1669 If Slot is not in a valid range for the EMMC controller, then EFI_INVALID_PARAMETER
1672 If Packet defines a data command but both InDataBuffer and OutDataBuffer are NULL,
1673 EFI_INVALID_PARAMETER is returned.
1675 @param[in] Slot The slot number of the Emmc card to send the command to.
1676 @param[in,out] Packet A pointer to the EMMC command data structure.
1678 @retval EFI_SUCCESS The EMMC Command Packet was sent by the host.
1679 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send the SD
1681 @retval EFI_INVALID_PARAMETER Packet, Slot, or the contents of the Packet is invalid.
1682 @retval EFI_INVALID_PARAMETER Packet defines a data command but both InDataBuffer and
1683 OutDataBuffer are NULL.
1684 @retval EFI_NO_MEDIA SD Device not present in the Slot.
1685 @retval EFI_UNSUPPORTED The command described by the EMMC Command Packet is not
1686 supported by the host controller.
1687 @retval EFI_BAD_BUFFER_SIZE The InTransferLength or OutTransferLength exceeds the
1688 limit supported by EMMC card ( i.e. if the number of bytes
1689 exceed the Last LBA).
1695 IN EMMC_PEIM_HC_SLOT
*Slot
,
1696 IN OUT EMMC_COMMAND_PACKET
*Packet
1702 if (Packet
== NULL
) {
1703 return EFI_INVALID_PARAMETER
;
1706 if ((Packet
->EmmcCmdBlk
== NULL
) || (Packet
->EmmcStatusBlk
== NULL
)) {
1707 return EFI_INVALID_PARAMETER
;
1710 if ((Packet
->OutDataBuffer
== NULL
) && (Packet
->OutTransferLength
!= 0)) {
1711 return EFI_INVALID_PARAMETER
;
1714 if ((Packet
->InDataBuffer
== NULL
) && (Packet
->InTransferLength
!= 0)) {
1715 return EFI_INVALID_PARAMETER
;
1718 Trb
= EmmcPeimCreateTrb (Slot
, Packet
);
1720 return EFI_OUT_OF_RESOURCES
;
1723 Status
= EmmcPeimWaitTrbEnv (Slot
->EmmcHcBase
, Trb
);
1724 if (EFI_ERROR (Status
)) {
1728 Status
= EmmcPeimExecTrb (Slot
->EmmcHcBase
, Trb
);
1729 if (EFI_ERROR (Status
)) {
1733 Status
= EmmcPeimWaitTrbResult (Slot
->EmmcHcBase
, Trb
);
1734 if (EFI_ERROR (Status
)) {
1739 EmmcPeimFreeTrb (Trb
);
1745 Send command GO_IDLE_STATE (CMD0 with argument of 0x00000000) to the device to
1746 make it go to Idle State.
1748 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
1750 @param[in] Slot The slot number of the Emmc card to send the command to.
1752 @retval EFI_SUCCESS The EMMC device is reset correctly.
1753 @retval Others The device reset fails.
1758 IN EMMC_PEIM_HC_SLOT
*Slot
1761 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
1762 EMMC_STATUS_BLOCK EmmcStatusBlk
;
1763 EMMC_COMMAND_PACKET Packet
;
1766 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
1767 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
1768 ZeroMem (&Packet
, sizeof (Packet
));
1770 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
1771 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
1772 Packet
.Timeout
= EMMC_TIMEOUT
;
1774 EmmcCmdBlk
.CommandIndex
= EMMC_GO_IDLE_STATE
;
1775 EmmcCmdBlk
.CommandType
= EmmcCommandTypeBc
;
1776 EmmcCmdBlk
.ResponseType
= 0;
1777 EmmcCmdBlk
.CommandArgument
= 0;
1779 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
1785 Send command SEND_OP_COND to the EMMC device to get the data of the OCR register.
1787 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
1789 @param[in] Slot The slot number of the Emmc card to send the command to.
1790 @param[in, out] Argument On input, the argument of SEND_OP_COND is to send to the device.
1791 On output, the argument is the value of OCR register.
1793 @retval EFI_SUCCESS The operation is done correctly.
1794 @retval Others The operation fails.
1799 IN EMMC_PEIM_HC_SLOT
*Slot
,
1800 IN OUT UINT32
*Argument
1803 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
1804 EMMC_STATUS_BLOCK EmmcStatusBlk
;
1805 EMMC_COMMAND_PACKET Packet
;
1808 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
1809 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
1810 ZeroMem (&Packet
, sizeof (Packet
));
1812 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
1813 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
1814 Packet
.Timeout
= EMMC_TIMEOUT
;
1816 EmmcCmdBlk
.CommandIndex
= EMMC_SEND_OP_COND
;
1817 EmmcCmdBlk
.CommandType
= EmmcCommandTypeBcr
;
1818 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR3
;
1819 EmmcCmdBlk
.CommandArgument
= *Argument
;
1821 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
1822 if (!EFI_ERROR (Status
)) {
1824 // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12.
1826 *Argument
= EmmcStatusBlk
.Resp0
;
1833 Broadcast command ALL_SEND_CID to the bus to ask all the EMMC devices to send the
1834 data of their CID registers.
1836 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
1838 @param[in] Slot The slot number of the Emmc card to send the command to.
1840 @retval EFI_SUCCESS The operation is done correctly.
1841 @retval Others The operation fails.
1846 IN EMMC_PEIM_HC_SLOT
*Slot
1849 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
1850 EMMC_STATUS_BLOCK EmmcStatusBlk
;
1851 EMMC_COMMAND_PACKET Packet
;
1854 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
1855 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
1856 ZeroMem (&Packet
, sizeof (Packet
));
1858 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
1859 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
1860 Packet
.Timeout
= EMMC_TIMEOUT
;
1862 EmmcCmdBlk
.CommandIndex
= EMMC_ALL_SEND_CID
;
1863 EmmcCmdBlk
.CommandType
= EmmcCommandTypeBcr
;
1864 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR2
;
1865 EmmcCmdBlk
.CommandArgument
= 0;
1867 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
1873 Send command SET_RELATIVE_ADDR to the EMMC device to assign a Relative device
1876 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
1878 @param[in] Slot The slot number of the Emmc card to send the command to.
1879 @param[in] Rca The relative device address to be assigned.
1881 @retval EFI_SUCCESS The operation is done correctly.
1882 @retval Others The operation fails.
1887 IN EMMC_PEIM_HC_SLOT
*Slot
,
1891 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
1892 EMMC_STATUS_BLOCK EmmcStatusBlk
;
1893 EMMC_COMMAND_PACKET Packet
;
1896 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
1897 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
1898 ZeroMem (&Packet
, sizeof (Packet
));
1900 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
1901 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
1902 Packet
.Timeout
= EMMC_TIMEOUT
;
1904 EmmcCmdBlk
.CommandIndex
= EMMC_SET_RELATIVE_ADDR
;
1905 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAc
;
1906 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR1
;
1907 EmmcCmdBlk
.CommandArgument
= Rca
<< 16;
1909 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
1915 Send command SEND_CSD to the EMMC device to get the data of the CSD register.
1917 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
1919 @param[in] Slot The slot number of the Emmc card to send the command to.
1920 @param[in] Rca The relative device address of selected device.
1921 @param[out] Csd The buffer to store the content of the CSD register.
1922 Note the caller should ignore the lowest byte of this
1923 buffer as the content of this byte is meaningless even
1924 if the operation succeeds.
1926 @retval EFI_SUCCESS The operation is done correctly.
1927 @retval Others The operation fails.
1932 IN EMMC_PEIM_HC_SLOT
*Slot
,
1937 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
1938 EMMC_STATUS_BLOCK EmmcStatusBlk
;
1939 EMMC_COMMAND_PACKET Packet
;
1942 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
1943 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
1944 ZeroMem (&Packet
, sizeof (Packet
));
1946 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
1947 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
1948 Packet
.Timeout
= EMMC_TIMEOUT
;
1950 EmmcCmdBlk
.CommandIndex
= EMMC_SEND_CSD
;
1951 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAc
;
1952 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR2
;
1953 EmmcCmdBlk
.CommandArgument
= Rca
<< 16;
1955 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
1956 if (!EFI_ERROR (Status
)) {
1958 // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12.
1960 CopyMem (((UINT8
*)Csd
) + 1, &EmmcStatusBlk
.Resp0
, sizeof (EMMC_CSD
) - 1);
1967 Send command SELECT_DESELECT_CARD to the EMMC device to select/deselect it.
1969 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
1971 @param[in] Slot The slot number of the Emmc card to send the command to.
1972 @param[in] Rca The relative device address of selected device.
1974 @retval EFI_SUCCESS The operation is done correctly.
1975 @retval Others The operation fails.
1980 IN EMMC_PEIM_HC_SLOT
*Slot
,
1984 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
1985 EMMC_STATUS_BLOCK EmmcStatusBlk
;
1986 EMMC_COMMAND_PACKET Packet
;
1989 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
1990 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
1991 ZeroMem (&Packet
, sizeof (Packet
));
1993 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
1994 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
1995 Packet
.Timeout
= EMMC_TIMEOUT
;
1997 EmmcCmdBlk
.CommandIndex
= EMMC_SELECT_DESELECT_CARD
;
1998 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAc
;
1999 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR1
;
2000 EmmcCmdBlk
.CommandArgument
= Rca
<< 16;
2002 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
2008 Send command SEND_EXT_CSD to the EMMC device to get the data of the EXT_CSD register.
2010 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
2012 @param[in] Slot The slot number of the Emmc card to send the command to.
2013 @param[out] ExtCsd The buffer to store the content of the EXT_CSD register.
2015 @retval EFI_SUCCESS The operation is done correctly.
2016 @retval Others The operation fails.
2021 IN EMMC_PEIM_HC_SLOT
*Slot
,
2022 OUT EMMC_EXT_CSD
*ExtCsd
2025 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
2026 EMMC_STATUS_BLOCK EmmcStatusBlk
;
2027 EMMC_COMMAND_PACKET Packet
;
2030 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
2031 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
2032 ZeroMem (&Packet
, sizeof (Packet
));
2034 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
2035 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
2036 Packet
.Timeout
= EMMC_TIMEOUT
;
2038 EmmcCmdBlk
.CommandIndex
= EMMC_SEND_EXT_CSD
;
2039 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAdtc
;
2040 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR1
;
2041 EmmcCmdBlk
.CommandArgument
= 0x00000000;
2043 Packet
.InDataBuffer
= ExtCsd
;
2044 Packet
.InTransferLength
= sizeof (EMMC_EXT_CSD
);
2046 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
2051 Send command SWITCH to the EMMC device to switch the mode of operation of the
2052 selected Device or modifies the EXT_CSD registers.
2054 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
2056 @param[in] Slot The slot number of the Emmc card to send the command to.
2057 @param[in] Access The access mode of SWITCH command.
2058 @param[in] Index The offset of the field to be access.
2059 @param[in] Value The value to be set to the specified field of EXT_CSD register.
2060 @param[in] CmdSet The value of CmdSet field of EXT_CSD register.
2062 @retval EFI_SUCCESS The operation is done correctly.
2063 @retval Others The operation fails.
2068 IN EMMC_PEIM_HC_SLOT
*Slot
,
2075 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
2076 EMMC_STATUS_BLOCK EmmcStatusBlk
;
2077 EMMC_COMMAND_PACKET Packet
;
2080 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
2081 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
2082 ZeroMem (&Packet
, sizeof (Packet
));
2084 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
2085 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
2086 Packet
.Timeout
= EMMC_TIMEOUT
;
2088 EmmcCmdBlk
.CommandIndex
= EMMC_SWITCH
;
2089 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAc
;
2090 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR1b
;
2091 EmmcCmdBlk
.CommandArgument
= (Access
<< 24) | (Index
<< 16) | (Value
<< 8) | CmdSet
;
2093 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
2099 Send command SEND_STATUS to the addressed EMMC device to get its status register.
2101 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
2103 @param[in] Slot The slot number of the Emmc card to send the command to.
2104 @param[in] Rca The relative device address of addressed device.
2105 @param[out] DevStatus The returned device status.
2107 @retval EFI_SUCCESS The operation is done correctly.
2108 @retval Others The operation fails.
2112 EmmcPeimSendStatus (
2113 IN EMMC_PEIM_HC_SLOT
*Slot
,
2115 OUT UINT32
*DevStatus
2118 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
2119 EMMC_STATUS_BLOCK EmmcStatusBlk
;
2120 EMMC_COMMAND_PACKET Packet
;
2123 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
2124 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
2125 ZeroMem (&Packet
, sizeof (Packet
));
2127 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
2128 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
2129 Packet
.Timeout
= EMMC_TIMEOUT
;
2131 EmmcCmdBlk
.CommandIndex
= EMMC_SEND_STATUS
;
2132 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAc
;
2133 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR1
;
2134 EmmcCmdBlk
.CommandArgument
= Rca
<< 16;
2136 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
2137 if (!EFI_ERROR (Status
)) {
2138 *DevStatus
= EmmcStatusBlk
.Resp0
;
2145 Send command SET_BLOCK_COUNT to the addressed EMMC device to set the number of
2146 blocks for the following block read/write cmd.
2148 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
2150 @param[in] Slot The slot number of the Emmc card to send the command to.
2151 @param[in] BlockCount The number of the logical block to access.
2153 @retval EFI_SUCCESS The operation is done correctly.
2154 @retval Others The operation fails.
2158 EmmcPeimSetBlkCount (
2159 IN EMMC_PEIM_HC_SLOT
*Slot
,
2160 IN UINT16 BlockCount
2163 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
2164 EMMC_STATUS_BLOCK EmmcStatusBlk
;
2165 EMMC_COMMAND_PACKET Packet
;
2168 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
2169 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
2170 ZeroMem (&Packet
, sizeof (Packet
));
2172 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
2173 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
2174 Packet
.Timeout
= EMMC_TIMEOUT
;
2176 EmmcCmdBlk
.CommandIndex
= EMMC_SET_BLOCK_COUNT
;
2177 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAc
;
2178 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR1
;
2179 EmmcCmdBlk
.CommandArgument
= BlockCount
;
2181 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
2187 Send command READ_MULTIPLE_BLOCK/WRITE_MULTIPLE_BLOCK to the addressed EMMC device
2188 to read/write the specified number of blocks.
2190 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
2192 @param[in] Slot The slot number of the Emmc card to send the command to.
2193 @param[in] Lba The logical block address of starting access.
2194 @param[in] BlockSize The block size of specified EMMC device partition.
2195 @param[in] Buffer The pointer to the transfer buffer.
2196 @param[in] BufferSize The size of transfer buffer.
2197 @param[in] IsRead Boolean to show the operation direction.
2199 @retval EFI_SUCCESS The operation is done correctly.
2200 @retval Others The operation fails.
2204 EmmcPeimRwMultiBlocks (
2205 IN EMMC_PEIM_HC_SLOT
*Slot
,
2207 IN UINT32 BlockSize
,
2209 IN UINTN BufferSize
,
2213 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
2214 EMMC_STATUS_BLOCK EmmcStatusBlk
;
2215 EMMC_COMMAND_PACKET Packet
;
2218 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
2219 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
2220 ZeroMem (&Packet
, sizeof (Packet
));
2222 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
2223 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
2225 // Calculate timeout value through the below formula.
2226 // Timeout = (transfer size) / (2MB/s).
2227 // Taking 2MB/s as divisor is because it's nearest to the eMMC lowest
2228 // transfer speed (2.4MB/s).
2229 // Refer to eMMC 5.0 spec section 6.9.1 for details.
2231 Packet
.Timeout
= (BufferSize
/ (2 * 1024 * 1024) + 1) * 1000 * 1000;
2234 Packet
.InDataBuffer
= Buffer
;
2235 Packet
.InTransferLength
= (UINT32
)BufferSize
;
2237 EmmcCmdBlk
.CommandIndex
= EMMC_READ_MULTIPLE_BLOCK
;
2238 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAdtc
;
2239 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR1
;
2241 Packet
.OutDataBuffer
= Buffer
;
2242 Packet
.OutTransferLength
= (UINT32
)BufferSize
;
2244 EmmcCmdBlk
.CommandIndex
= EMMC_WRITE_MULTIPLE_BLOCK
;
2245 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAdtc
;
2246 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR1
;
2249 if (Slot
->SectorAddressing
) {
2250 EmmcCmdBlk
.CommandArgument
= (UINT32
)Lba
;
2252 EmmcCmdBlk
.CommandArgument
= (UINT32
)MultU64x32 (Lba
, BlockSize
);
2255 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
2261 Send command SEND_TUNING_BLOCK to the EMMC device for HS200 optimal sampling point
2264 It may be sent up to 40 times until the host finishes the tuning procedure.
2266 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 for details.
2268 @param[in] Slot The slot number of the Emmc card to send the command to.
2269 @param[in] BusWidth The bus width to work.
2271 @retval EFI_SUCCESS The operation is done correctly.
2272 @retval Others The operation fails.
2276 EmmcPeimSendTuningBlk (
2277 IN EMMC_PEIM_HC_SLOT
*Slot
,
2281 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
2282 EMMC_STATUS_BLOCK EmmcStatusBlk
;
2283 EMMC_COMMAND_PACKET Packet
;
2285 UINT8 TuningBlock
[128];
2287 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
2288 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
2289 ZeroMem (&Packet
, sizeof (Packet
));
2291 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
2292 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
2293 Packet
.Timeout
= EMMC_TIMEOUT
;
2295 EmmcCmdBlk
.CommandIndex
= EMMC_SEND_TUNING_BLOCK
;
2296 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAdtc
;
2297 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR1
;
2298 EmmcCmdBlk
.CommandArgument
= 0;
2300 Packet
.InDataBuffer
= TuningBlock
;
2301 if (BusWidth
== 8) {
2302 Packet
.InTransferLength
= sizeof (TuningBlock
);
2304 Packet
.InTransferLength
= 64;
2307 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
2313 Tuning the clock to get HS200 optimal sampling point.
2315 Command SEND_TUNING_BLOCK may be sent up to 40 times until the host finishes the
2318 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
2319 Simplified Spec 3.0 section Figure 2-29 for details.
2321 @param[in] Slot The slot number of the Emmc card to send the command to.
2322 @param[in] BusWidth The bus width to work.
2324 @retval EFI_SUCCESS The operation is done correctly.
2325 @retval Others The operation fails.
2329 EmmcPeimTuningClkForHs200 (
2330 IN EMMC_PEIM_HC_SLOT
*Slot
,
2339 // Notify the host that the sampling clock tuning procedure starts.
2342 Status
= EmmcPeimHcOrMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2343 if (EFI_ERROR (Status
)) {
2348 // Ask the device to send a sequence of tuning blocks till the tuning procedure is done.
2352 Status
= EmmcPeimSendTuningBlk (Slot
, BusWidth
);
2353 if (EFI_ERROR (Status
)) {
2357 Status
= EmmcPeimHcRwMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL2
, TRUE
, sizeof (HostCtrl2
), &HostCtrl2
);
2358 if (EFI_ERROR (Status
)) {
2362 if ((HostCtrl2
& (BIT6
| BIT7
)) == 0) {
2366 if ((HostCtrl2
& (BIT6
| BIT7
)) == BIT7
) {
2369 } while (++Retry
< 40);
2371 DEBUG ((DEBUG_ERROR
, "EmmcPeimTuningClkForHs200: Send tuning block fails at %d times with HostCtrl2 %02x\n", Retry
, HostCtrl2
));
2373 // Abort the tuning procedure and reset the tuning circuit.
2375 HostCtrl2
= (UINT8
) ~(BIT6
| BIT7
);
2376 Status
= EmmcPeimHcAndMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2377 if (EFI_ERROR (Status
)) {
2381 return EFI_DEVICE_ERROR
;
2385 Switch the bus width to specified width.
2387 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.9 and SD Host Controller
2388 Simplified Spec 3.0 section Figure 3-7 for details.
2390 @param[in] Slot The slot number of the Emmc card to send the command to.
2391 @param[in] Rca The relative device address to be assigned.
2392 @param[in] IsDdr If TRUE, use dual data rate data simpling method. Otherwise
2393 use single data rate data simpling method.
2394 @param[in] BusWidth The bus width to be set, it could be 4 or 8.
2396 @retval EFI_SUCCESS The operation is done correctly.
2397 @retval Others The operation fails.
2401 EmmcPeimSwitchBusWidth (
2402 IN EMMC_PEIM_HC_SLOT
*Slot
,
2416 // Write Byte, the Value field is written into the byte pointed by Index.
2419 Index
= OFFSET_OF (EMMC_EXT_CSD
, BusWidth
);
2420 if (BusWidth
== 4) {
2422 } else if (BusWidth
== 8) {
2425 return EFI_INVALID_PARAMETER
;
2433 Status
= EmmcPeimSwitch (Slot
, Access
, Index
, Value
, CmdSet
);
2434 if (EFI_ERROR (Status
)) {
2438 Status
= EmmcPeimSendStatus (Slot
, Rca
, &DevStatus
);
2439 if (EFI_ERROR (Status
)) {
2444 // Check the switch operation is really successful or not.
2446 if ((DevStatus
& BIT7
) != 0) {
2447 return EFI_DEVICE_ERROR
;
2450 Status
= EmmcPeimHcSetBusWidth (Slot
->EmmcHcBase
, BusWidth
);
2456 Switch the clock frequency to the specified value.
2458 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6 and SD Host Controller
2459 Simplified Spec 3.0 section Figure 3-3 for details.
2461 @param[in] Slot The slot number of the Emmc card to send the command to.
2462 @param[in] Rca The relative device address to be assigned.
2463 @param[in] HsTiming The value to be written to HS_TIMING field of EXT_CSD register.
2464 @param[in] ClockFreq The max clock frequency to be set, the unit is MHz.
2466 @retval EFI_SUCCESS The operation is done correctly.
2467 @retval Others The operation fails.
2471 EmmcPeimSwitchClockFreq (
2472 IN EMMC_PEIM_HC_SLOT
*Slot
,
2486 // Write Byte, the Value field is written into the byte pointed by Index.
2489 Index
= OFFSET_OF (EMMC_EXT_CSD
, HsTiming
);
2493 Status
= EmmcPeimSwitch (Slot
, Access
, Index
, Value
, CmdSet
);
2494 if (EFI_ERROR (Status
)) {
2498 Status
= EmmcPeimSendStatus (Slot
, Rca
, &DevStatus
);
2499 if (EFI_ERROR (Status
)) {
2504 // Check the switch operation is really successful or not.
2506 if ((DevStatus
& BIT7
) != 0) {
2507 return EFI_DEVICE_ERROR
;
2511 // Convert the clock freq unit from MHz to KHz.
2513 Status
= EmmcPeimHcClockSupply (Slot
->EmmcHcBase
, ClockFreq
* 1000);
2519 Switch to the High Speed timing according to request.
2521 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
2522 Simplified Spec 3.0 section Figure 2-29 for details.
2524 @param[in] Slot The slot number of the Emmc card to send the command to.
2525 @param[in] Rca The relative device address to be assigned.
2526 @param[in] ClockFreq The max clock frequency to be set.
2527 @param[in] IsDdr If TRUE, use dual data rate data simpling method. Otherwise
2528 use single data rate data simpling method.
2529 @param[in] BusWidth The bus width to be set, it could be 4 or 8.
2531 @retval EFI_SUCCESS The operation is done correctly.
2532 @retval Others The operation fails.
2536 EmmcPeimSwitchToHighSpeed (
2537 IN EMMC_PEIM_HC_SLOT
*Slot
,
2539 IN UINT32 ClockFreq
,
2549 Status
= EmmcPeimSwitchBusWidth (Slot
, Rca
, IsDdr
, BusWidth
);
2550 if (EFI_ERROR (Status
)) {
2555 // Set to High Speed timing
2558 Status
= EmmcPeimHcOrMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
2559 if (EFI_ERROR (Status
)) {
2563 HostCtrl2
= (UINT8
) ~0x7;
2564 Status
= EmmcPeimHcAndMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2565 if (EFI_ERROR (Status
)) {
2571 } else if (ClockFreq
== 52) {
2577 Status
= EmmcPeimHcOrMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2578 if (EFI_ERROR (Status
)) {
2583 Status
= EmmcPeimSwitchClockFreq (Slot
, Rca
, HsTiming
, ClockFreq
);
2589 Switch to the HS200 timing according to request.
2591 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
2592 Simplified Spec 3.0 section Figure 2-29 for details.
2594 @param[in] Slot The slot number of the Emmc card to send the command to.
2595 @param[in] Rca The relative device address to be assigned.
2596 @param[in] ClockFreq The max clock frequency to be set.
2597 @param[in] BusWidth The bus width to be set, it could be 4 or 8.
2599 @retval EFI_SUCCESS The operation is done correctly.
2600 @retval Others The operation fails.
2604 EmmcPeimSwitchToHS200 (
2605 IN EMMC_PEIM_HC_SLOT
*Slot
,
2607 IN UINT32 ClockFreq
,
2616 if ((BusWidth
!= 4) && (BusWidth
!= 8)) {
2617 return EFI_INVALID_PARAMETER
;
2620 Status
= EmmcPeimSwitchBusWidth (Slot
, Rca
, FALSE
, BusWidth
);
2621 if (EFI_ERROR (Status
)) {
2626 // Set to HS200/SDR104 timing
2629 // Stop bus clock at first
2631 Status
= EmmcPeimHcStopClock (Slot
->EmmcHcBase
);
2632 if (EFI_ERROR (Status
)) {
2636 HostCtrl2
= (UINT8
) ~0x7;
2637 Status
= EmmcPeimHcAndMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2638 if (EFI_ERROR (Status
)) {
2642 HostCtrl2
= BIT0
| BIT1
;
2643 Status
= EmmcPeimHcOrMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2644 if (EFI_ERROR (Status
)) {
2649 // Wait Internal Clock Stable in the Clock Control register to be 1 before set SD Clock Enable bit
2651 Status
= EmmcPeimHcWaitMmioSet (
2652 Slot
->EmmcHcBase
+ EMMC_HC_CLOCK_CTRL
,
2658 if (EFI_ERROR (Status
)) {
2663 // Set SD Clock Enable in the Clock Control register to 1
2666 Status
= EmmcPeimHcOrMmio (Slot
->EmmcHcBase
+ EMMC_HC_CLOCK_CTRL
, sizeof (ClockCtrl
), &ClockCtrl
);
2669 Status
= EmmcPeimSwitchClockFreq (Slot
, Rca
, HsTiming
, ClockFreq
);
2670 if (EFI_ERROR (Status
)) {
2674 Status
= EmmcPeimTuningClkForHs200 (Slot
, BusWidth
);
2680 Switch to the HS400 timing according to request.
2682 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
2683 Simplified Spec 3.0 section Figure 2-29 for details.
2685 @param[in] Slot The slot number of the Emmc card to send the command to.
2686 @param[in] Rca The relative device address to be assigned.
2687 @param[in] ClockFreq The max clock frequency to be set.
2689 @retval EFI_SUCCESS The operation is done correctly.
2690 @retval Others The operation fails.
2694 EmmcPeimSwitchToHS400 (
2695 IN EMMC_PEIM_HC_SLOT
*Slot
,
2704 Status
= EmmcPeimSwitchToHS200 (Slot
, Rca
, ClockFreq
, 8);
2705 if (EFI_ERROR (Status
)) {
2710 // Set to High Speed timing and set the clock frequency to a value less than 52MHz.
2713 Status
= EmmcPeimSwitchClockFreq (Slot
, Rca
, HsTiming
, 52);
2714 if (EFI_ERROR (Status
)) {
2719 // HS400 mode must use 8 data lines.
2721 Status
= EmmcPeimSwitchBusWidth (Slot
, Rca
, TRUE
, 8);
2722 if (EFI_ERROR (Status
)) {
2727 // Set to HS400 timing
2729 HostCtrl2
= (UINT8
) ~0x7;
2730 Status
= EmmcPeimHcAndMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2731 if (EFI_ERROR (Status
)) {
2735 HostCtrl2
= BIT0
| BIT2
;
2736 Status
= EmmcPeimHcOrMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2737 if (EFI_ERROR (Status
)) {
2742 Status
= EmmcPeimSwitchClockFreq (Slot
, Rca
, HsTiming
, ClockFreq
);
2748 Switch the high speed timing according to request.
2750 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
2751 Simplified Spec 3.0 section Figure 2-29 for details.
2753 @param[in] Slot The slot number of the Emmc card to send the command to.
2754 @param[in] Rca The relative device address to be assigned.
2756 @retval EFI_SUCCESS The operation is done correctly.
2757 @retval Others The operation fails.
2761 EmmcPeimSetBusMode (
2762 IN EMMC_PEIM_HC_SLOT
*Slot
,
2767 EMMC_HC_SLOT_CAP Capability
;
2773 Status
= EmmcPeimGetCsd (Slot
, Rca
, &Slot
->Csd
);
2774 if (EFI_ERROR (Status
)) {
2775 DEBUG ((DEBUG_ERROR
, "EmmcPeimSetBusMode: EmmcPeimGetCsd fails with %r\n", Status
));
2779 if ((Slot
->Csd
.CSizeLow
| Slot
->Csd
.CSizeHigh
<< 2) == 0xFFF) {
2780 Slot
->SectorAddressing
= TRUE
;
2782 Slot
->SectorAddressing
= FALSE
;
2785 Status
= EmmcPeimSelect (Slot
, Rca
);
2786 if (EFI_ERROR (Status
)) {
2787 DEBUG ((DEBUG_ERROR
, "EmmcPeimSetBusMode: EmmcPeimSelect fails with %r\n", Status
));
2791 Status
= EmmcPeimHcGetCapability (Slot
->EmmcHcBase
, &Capability
);
2792 if (EFI_ERROR (Status
)) {
2793 DEBUG ((DEBUG_ERROR
, "EmmcPeimSetBusMode: EmmcPeimHcGetCapability fails with %r\n", Status
));
2797 ASSERT (Capability
.BaseClkFreq
!= 0);
2799 // Check if the Host Controller support 8bits bus width.
2801 if (Capability
.BusWidth8
!= 0) {
2808 // Get Device_Type from EXT_CSD register.
2810 Status
= EmmcPeimGetExtCsd (Slot
, &Slot
->ExtCsd
);
2811 if (EFI_ERROR (Status
)) {
2812 DEBUG ((DEBUG_ERROR
, "EmmcPeimSetBusMode: EmmcPeimGetExtCsd fails with %r\n", Status
));
2817 // Calculate supported bus speed/bus width/clock frequency.
2822 if (((Slot
->ExtCsd
.DeviceType
& (BIT4
| BIT5
)) != 0) && (Capability
.Sdr104
!= 0)) {
2826 } else if (((Slot
->ExtCsd
.DeviceType
& (BIT2
| BIT3
)) != 0) && (Capability
.Ddr50
!= 0)) {
2830 } else if (((Slot
->ExtCsd
.DeviceType
& BIT1
) != 0) && (Capability
.HighSpeed
!= 0)) {
2834 } else if (((Slot
->ExtCsd
.DeviceType
& BIT0
) != 0) && (Capability
.HighSpeed
!= 0)) {
2841 // Check if both of the device and the host controller support HS400 DDR mode.
2843 if (((Slot
->ExtCsd
.DeviceType
& (BIT6
| BIT7
)) != 0) && (Capability
.Hs400
!= 0)) {
2845 // The host controller supports 8bits bus.
2847 ASSERT (BusWidth
== 8);
2853 if ((ClockFreq
== 0) || (HsTiming
== 0)) {
2855 // Continue using default setting.
2860 DEBUG ((DEBUG_INFO
, "HsTiming %d ClockFreq %d BusWidth %d Ddr %a\n", HsTiming
, ClockFreq
, BusWidth
, IsDdr
? "TRUE" : "FALSE"));
2862 if (HsTiming
== 3) {
2864 // Execute HS400 timing switch procedure
2866 Status
= EmmcPeimSwitchToHS400 (Slot
, Rca
, ClockFreq
);
2867 } else if (HsTiming
== 2) {
2869 // Execute HS200 timing switch procedure
2871 Status
= EmmcPeimSwitchToHS200 (Slot
, Rca
, ClockFreq
, BusWidth
);
2874 // Execute High Speed timing switch procedure
2876 Status
= EmmcPeimSwitchToHighSpeed (Slot
, Rca
, ClockFreq
, IsDdr
, BusWidth
);
2883 Execute EMMC device identification procedure.
2885 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
2887 @param[in] Slot The slot number of the Emmc card to send the command to.
2889 @retval EFI_SUCCESS There is a EMMC card.
2890 @retval Others There is not a EMMC card.
2894 EmmcPeimIdentification (
2895 IN EMMC_PEIM_HC_SLOT
*Slot
2903 Status
= EmmcPeimReset (Slot
);
2904 if (EFI_ERROR (Status
)) {
2905 DEBUG ((DEBUG_ERROR
, "EmmcPeimIdentification: EmmcPeimReset fails with %r\n", Status
));
2912 Status
= EmmcPeimGetOcr (Slot
, &Ocr
);
2913 if (EFI_ERROR (Status
)) {
2914 DEBUG ((DEBUG_ERROR
, "EmmcPeimIdentification: EmmcPeimGetOcr fails with %r\n", Status
));
2918 if (Retry
++ == 100) {
2919 DEBUG ((DEBUG_ERROR
, "EmmcPeimIdentification: EmmcPeimGetOcr fails too many times\n"));
2920 return EFI_DEVICE_ERROR
;
2923 MicroSecondDelay (10 * 1000);
2924 } while ((Ocr
& BIT31
) == 0);
2926 Status
= EmmcPeimGetAllCid (Slot
);
2927 if (EFI_ERROR (Status
)) {
2928 DEBUG ((DEBUG_ERROR
, "EmmcPeimIdentification: EmmcPeimGetAllCid fails with %r\n", Status
));
2933 // Don't support multiple devices on the slot, that is
2934 // shared bus slot feature.
2937 Status
= EmmcPeimSetRca (Slot
, Rca
);
2938 if (EFI_ERROR (Status
)) {
2939 DEBUG ((DEBUG_ERROR
, "EmmcPeimIdentification: EmmcPeimSetRca fails with %r\n", Status
));
2944 // Enter Data Tranfer Mode.
2946 DEBUG ((DEBUG_INFO
, "Found a EMMC device at slot [%d], RCA [%d]\n", Slot
, Rca
));
2948 Status
= EmmcPeimSetBusMode (Slot
, Rca
);