3 Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php.
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14 #include "EmmcBlockIoPei.h"
17 Read/Write specified EMMC host controller mmio register.
19 @param[in] Address The address of the mmio register to be read/written.
20 @param[in] Read A boolean to indicate it's read or write operation.
21 @param[in] Count The width of the mmio register in bytes.
22 Must be 1, 2 , 4 or 8 bytes.
23 @param[in, out] Data For read operations, the destination buffer to store
24 the results. For write operations, the source buffer
25 to write data from. The caller is responsible for
26 having ownership of the data buffer and ensuring its
27 size not less than Count bytes.
29 @retval EFI_INVALID_PARAMETER The Address or the Data or the Count is not valid.
30 @retval EFI_SUCCESS The read/write operation succeeds.
31 @retval Others The read/write operation fails.
43 if ((Address
== 0) || (Data
== NULL
)) {
44 return EFI_INVALID_PARAMETER
;
47 if ((Count
!= 1) && (Count
!= 2) && (Count
!= 4) && (Count
!= 8)) {
48 return EFI_INVALID_PARAMETER
;
54 *(UINT8
*)Data
= MmioRead8 (Address
);
56 MmioWrite8 (Address
, *(UINT8
*)Data
);
61 *(UINT16
*)Data
= MmioRead16 (Address
);
63 MmioWrite16 (Address
, *(UINT16
*)Data
);
68 *(UINT32
*)Data
= MmioRead32 (Address
);
70 MmioWrite32 (Address
, *(UINT32
*)Data
);
75 *(UINT64
*)Data
= MmioRead64 (Address
);
77 MmioWrite64 (Address
, *(UINT64
*)Data
);
82 return EFI_INVALID_PARAMETER
;
89 Do OR operation with the value of the specified EMMC host controller mmio register.
91 @param[in] Address The address of the mmio register to be read/written.
92 @param[in] Count The width of the mmio register in bytes.
93 Must be 1, 2 , 4 or 8 bytes.
94 @param[in] OrData The pointer to the data used to do OR operation.
95 The caller is responsible for having ownership of
96 the data buffer and ensuring its size not less than
99 @retval EFI_INVALID_PARAMETER The Address or the OrData or the Count is not valid.
100 @retval EFI_SUCCESS The OR operation succeeds.
101 @retval Others The OR operation fails.
116 Status
= EmmcPeimHcRwMmio (Address
, TRUE
, Count
, &Data
);
117 if (EFI_ERROR (Status
)) {
122 Or
= *(UINT8
*) OrData
;
123 } else if (Count
== 2) {
124 Or
= *(UINT16
*) OrData
;
125 } else if (Count
== 4) {
126 Or
= *(UINT32
*) OrData
;
127 } else if (Count
== 8) {
128 Or
= *(UINT64
*) OrData
;
130 return EFI_INVALID_PARAMETER
;
134 Status
= EmmcPeimHcRwMmio (Address
, FALSE
, Count
, &Data
);
140 Do AND operation with the value of the specified EMMC host controller mmio register.
142 @param[in] Address The address of the mmio register to be read/written.
143 @param[in] Count The width of the mmio register in bytes.
144 Must be 1, 2 , 4 or 8 bytes.
145 @param[in] AndData The pointer to the data used to do AND operation.
146 The caller is responsible for having ownership of
147 the data buffer and ensuring its size not less than
150 @retval EFI_INVALID_PARAMETER The Address or the AndData or the Count is not valid.
151 @retval EFI_SUCCESS The AND operation succeeds.
152 @retval Others The AND operation fails.
167 Status
= EmmcPeimHcRwMmio (Address
, TRUE
, Count
, &Data
);
168 if (EFI_ERROR (Status
)) {
173 And
= *(UINT8
*) AndData
;
174 } else if (Count
== 2) {
175 And
= *(UINT16
*) AndData
;
176 } else if (Count
== 4) {
177 And
= *(UINT32
*) AndData
;
178 } else if (Count
== 8) {
179 And
= *(UINT64
*) AndData
;
181 return EFI_INVALID_PARAMETER
;
185 Status
= EmmcPeimHcRwMmio (Address
, FALSE
, Count
, &Data
);
191 Wait for the value of the specified MMIO register set to the test value.
193 @param[in] Address The address of the mmio register to be checked.
194 @param[in] Count The width of the mmio register in bytes.
195 Must be 1, 2, 4 or 8 bytes.
196 @param[in] MaskValue The mask value of memory.
197 @param[in] TestValue The test value of memory.
199 @retval EFI_NOT_READY The MMIO register hasn't set to the expected value.
200 @retval EFI_SUCCESS The MMIO register has expected value.
201 @retval Others The MMIO operation fails.
206 EmmcPeimHcCheckMmioSet (
217 // Access PCI MMIO space to see if the value is the tested one.
220 Status
= EmmcPeimHcRwMmio (Address
, TRUE
, Count
, &Value
);
221 if (EFI_ERROR (Status
)) {
227 if (Value
== TestValue
) {
231 return EFI_NOT_READY
;
235 Wait for the value of the specified MMIO register set to the test value.
237 @param[in] Address The address of the mmio register to wait.
238 @param[in] Count The width of the mmio register in bytes.
239 Must be 1, 2, 4 or 8 bytes.
240 @param[in] MaskValue The mask value of memory.
241 @param[in] TestValue The test value of memory.
242 @param[in] Timeout The time out value for wait memory set, uses 1
243 microsecond as a unit.
245 @retval EFI_TIMEOUT The MMIO register hasn't expected value in timeout
247 @retval EFI_SUCCESS The MMIO register has expected value.
248 @retval Others The MMIO operation fails.
253 EmmcPeimHcWaitMmioSet (
262 BOOLEAN InfiniteWait
;
267 InfiniteWait
= FALSE
;
270 while (InfiniteWait
|| (Timeout
> 0)) {
271 Status
= EmmcPeimHcCheckMmioSet (
277 if (Status
!= EFI_NOT_READY
) {
282 // Stall for 1 microsecond.
284 MicroSecondDelay (1);
293 Software reset the specified EMMC host controller and enable all interrupts.
295 @param[in] Bar The mmio base address of the slot to be accessed.
297 @retval EFI_SUCCESS The software reset executes successfully.
298 @retval Others The software reset fails.
310 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_SW_RST
, FALSE
, sizeof (SwReset
), &SwReset
);
312 if (EFI_ERROR (Status
)) {
313 DEBUG ((EFI_D_ERROR
, "EmmcPeimHcReset: write full 1 fails: %r\n", Status
));
317 Status
= EmmcPeimHcWaitMmioSet (
318 Bar
+ EMMC_HC_SW_RST
,
324 if (EFI_ERROR (Status
)) {
325 DEBUG ((EFI_D_INFO
, "EmmcPeimHcReset: reset done with %r\n", Status
));
329 // Enable all interrupt after reset all.
331 Status
= EmmcPeimHcEnableInterrupt (Bar
);
337 Set all interrupt status bits in Normal and Error Interrupt Status Enable
340 @param[in] Bar The mmio base address of the slot to be accessed.
342 @retval EFI_SUCCESS The operation executes successfully.
343 @retval Others The operation fails.
347 EmmcPeimHcEnableInterrupt (
355 // Enable all bits in Error Interrupt Status Enable Register
358 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_ERR_INT_STS_EN
, FALSE
, sizeof (IntStatus
), &IntStatus
);
359 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
)) {
535 ASSERT (Capability
.BaseClkFreq
!= 0);
537 BaseClkFreq
= Capability
.BaseClkFreq
;
538 if ((ClockFreq
> (BaseClkFreq
* 1000)) || (ClockFreq
== 0)) {
539 return EFI_INVALID_PARAMETER
;
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
;
926 Data
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)Trb
->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
;
997 // Calculate a divisor for SD clock frequency
999 Status
= EmmcPeimHcGetCapability (Slot
->EmmcHcBase
, &Capability
);
1000 if (EFI_ERROR (Status
)) {
1004 Trb
= EmmcPeimAllocateMem (Slot
->Private
->Pool
, sizeof (EMMC_TRB
));
1010 Trb
->BlockSize
= 0x200;
1011 Trb
->Packet
= Packet
;
1012 Trb
->Timeout
= Packet
->Timeout
;
1014 if ((Packet
->InTransferLength
!= 0) && (Packet
->InDataBuffer
!= NULL
)) {
1015 Trb
->Data
= Packet
->InDataBuffer
;
1016 Trb
->DataLen
= Packet
->InTransferLength
;
1018 } else if ((Packet
->OutTransferLength
!= 0) && (Packet
->OutDataBuffer
!= NULL
)) {
1019 Trb
->Data
= Packet
->OutDataBuffer
;
1020 Trb
->DataLen
= Packet
->OutTransferLength
;
1022 } else if ((Packet
->InTransferLength
== 0) && (Packet
->OutTransferLength
== 0)) {
1029 if ((Trb
->DataLen
% Trb
->BlockSize
) != 0) {
1030 if (Trb
->DataLen
< Trb
->BlockSize
) {
1031 Trb
->BlockSize
= (UINT16
)Trb
->DataLen
;
1035 if (Trb
->DataLen
== 0) {
1036 Trb
->Mode
= EmmcNoData
;
1037 } else if (Capability
.Adma2
!= 0) {
1038 Trb
->Mode
= EmmcAdmaMode
;
1039 Status
= BuildAdmaDescTable (Trb
);
1040 if (EFI_ERROR (Status
)) {
1043 } else if (Capability
.Sdma
!= 0) {
1044 Trb
->Mode
= EmmcSdmaMode
;
1046 Trb
->Mode
= EmmcPioMode
;
1052 EmmcPeimFreeTrb (Trb
);
1057 Free the resource used by the TRB.
1059 @param[in] Trb The pointer to the EMMC_TRB instance.
1067 if ((Trb
!= NULL
) && (Trb
->AdmaDesc
!= NULL
)) {
1068 EmmcPeimFreeMem (Trb
->Slot
->Private
->Pool
, Trb
->AdmaDesc
, Trb
->AdmaDescSize
);
1072 EmmcPeimFreeMem (Trb
->Slot
->Private
->Pool
, Trb
, sizeof (EMMC_TRB
));
1078 Check if the env is ready for execute specified TRB.
1080 @param[in] Bar The mmio base address of the slot to be accessed.
1081 @param[in] Trb The pointer to the EMMC_TRB instance.
1083 @retval EFI_SUCCESS The env is ready for TRB execution.
1084 @retval EFI_NOT_READY The env is not ready for TRB execution.
1085 @retval Others Some erros happen.
1089 EmmcPeimCheckTrbEnv (
1095 EMMC_COMMAND_PACKET
*Packet
;
1096 UINT32 PresentState
;
1098 Packet
= Trb
->Packet
;
1100 if ((Packet
->EmmcCmdBlk
->CommandType
== EmmcCommandTypeAdtc
) ||
1101 (Packet
->EmmcCmdBlk
->ResponseType
== EmmcResponceTypeR1b
) ||
1102 (Packet
->EmmcCmdBlk
->ResponseType
== EmmcResponceTypeR5b
)) {
1104 // Wait Command Inhibit (CMD) and Command Inhibit (DAT) in
1105 // the Present State register to be 0
1107 PresentState
= BIT0
| BIT1
;
1108 if (Packet
->EmmcCmdBlk
->CommandIndex
== EMMC_SEND_TUNING_BLOCK
) {
1109 PresentState
= BIT0
;
1113 // Wait Command Inhibit (CMD) in the Present State register
1116 PresentState
= BIT0
;
1119 Status
= EmmcPeimHcCheckMmioSet (
1120 Bar
+ EMMC_HC_PRESENT_STATE
,
1121 sizeof (PresentState
),
1130 Wait for the env to be ready for execute specified TRB.
1132 @param[in] Bar The mmio base address of the slot to be accessed.
1133 @param[in] Trb The pointer to the EMMC_TRB instance.
1135 @retval EFI_SUCCESS The env is ready for TRB execution.
1136 @retval EFI_TIMEOUT The env is not ready for TRB execution in time.
1137 @retval Others Some erros happen.
1141 EmmcPeimWaitTrbEnv (
1147 EMMC_COMMAND_PACKET
*Packet
;
1149 BOOLEAN InfiniteWait
;
1152 // Wait Command Complete Interrupt Status bit in Normal Interrupt Status Register
1154 Packet
= Trb
->Packet
;
1155 Timeout
= Packet
->Timeout
;
1157 InfiniteWait
= TRUE
;
1159 InfiniteWait
= FALSE
;
1162 while (InfiniteWait
|| (Timeout
> 0)) {
1164 // Check Trb execution result by reading Normal Interrupt Status register.
1166 Status
= EmmcPeimCheckTrbEnv (Bar
, Trb
);
1167 if (Status
!= EFI_NOT_READY
) {
1171 // Stall for 1 microsecond.
1173 MicroSecondDelay (1);
1182 Execute the specified TRB.
1184 @param[in] Bar The mmio base address of the slot to be accessed.
1185 @param[in] Trb The pointer to the EMMC_TRB instance.
1187 @retval EFI_SUCCESS The TRB is sent to host controller successfully.
1188 @retval Others Some erros happen when sending this request to the host controller.
1198 EMMC_COMMAND_PACKET
*Packet
;
1209 Packet
= Trb
->Packet
;
1211 // Clear all bits in Error Interrupt Status Register
1214 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_ERR_INT_STS
, FALSE
, sizeof (IntStatus
), &IntStatus
);
1215 if (EFI_ERROR (Status
)) {
1219 // Clear all bits in Normal Interrupt Status Register
1222 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_NOR_INT_STS
, FALSE
, sizeof (IntStatus
), &IntStatus
);
1223 if (EFI_ERROR (Status
)) {
1227 // Set Host Control 1 register DMA Select field
1229 if (Trb
->Mode
== EmmcAdmaMode
) {
1231 Status
= EmmcPeimHcOrMmio (Bar
+ EMMC_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
1232 if (EFI_ERROR (Status
)) {
1237 EmmcPeimHcLedOnOff (Bar
, TRUE
);
1239 if (Trb
->Mode
== EmmcSdmaMode
) {
1240 if ((UINT64
)(UINTN
)Trb
->Data
>= 0x100000000ul
) {
1241 return EFI_INVALID_PARAMETER
;
1244 SdmaAddr
= (UINT32
)(UINTN
)Trb
->Data
;
1245 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_SDMA_ADDR
, FALSE
, sizeof (SdmaAddr
), &SdmaAddr
);
1246 if (EFI_ERROR (Status
)) {
1249 } else if (Trb
->Mode
== EmmcAdmaMode
) {
1250 AdmaAddr
= (UINT64
)(UINTN
)Trb
->AdmaDesc
;
1251 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_ADMA_SYS_ADDR
, FALSE
, sizeof (AdmaAddr
), &AdmaAddr
);
1252 if (EFI_ERROR (Status
)) {
1257 BlkSize
= Trb
->BlockSize
;
1258 if (Trb
->Mode
== EmmcSdmaMode
) {
1260 // Set SDMA boundary to be 512K bytes.
1265 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_BLK_SIZE
, FALSE
, sizeof (BlkSize
), &BlkSize
);
1266 if (EFI_ERROR (Status
)) {
1270 BlkCount
= (UINT16
)(Trb
->DataLen
/ Trb
->BlockSize
);
1271 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_BLK_COUNT
, FALSE
, sizeof (BlkCount
), &BlkCount
);
1272 if (EFI_ERROR (Status
)) {
1276 Argument
= Packet
->EmmcCmdBlk
->CommandArgument
;
1277 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_ARG1
, FALSE
, sizeof (Argument
), &Argument
);
1278 if (EFI_ERROR (Status
)) {
1283 if (Trb
->Mode
!= EmmcNoData
) {
1284 if (Trb
->Mode
!= EmmcPioMode
) {
1290 if (BlkCount
!= 0) {
1291 TransMode
|= BIT5
| BIT1
;
1295 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_TRANS_MOD
, FALSE
, sizeof (TransMode
), &TransMode
);
1296 if (EFI_ERROR (Status
)) {
1300 Cmd
= (UINT16
)LShiftU64(Packet
->EmmcCmdBlk
->CommandIndex
, 8);
1301 if (Packet
->EmmcCmdBlk
->CommandType
== EmmcCommandTypeAdtc
) {
1305 // Convert ResponseType to value
1307 if (Packet
->EmmcCmdBlk
->CommandType
!= EmmcCommandTypeBc
) {
1308 switch (Packet
->EmmcCmdBlk
->ResponseType
) {
1309 case EmmcResponceTypeR1
:
1310 case EmmcResponceTypeR5
:
1311 case EmmcResponceTypeR6
:
1312 case EmmcResponceTypeR7
:
1313 Cmd
|= (BIT1
| BIT3
| BIT4
);
1315 case EmmcResponceTypeR2
:
1316 Cmd
|= (BIT0
| BIT3
);
1318 case EmmcResponceTypeR3
:
1319 case EmmcResponceTypeR4
:
1322 case EmmcResponceTypeR1b
:
1323 case EmmcResponceTypeR5b
:
1324 Cmd
|= (BIT0
| BIT1
| BIT3
| BIT4
);
1334 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_COMMAND
, FALSE
, sizeof (Cmd
), &Cmd
);
1339 Check the TRB execution result.
1341 @param[in] Bar The mmio base address of the slot to be accessed.
1342 @param[in] Trb The pointer to the EMMC_TRB instance.
1344 @retval EFI_SUCCESS The TRB is executed successfully.
1345 @retval EFI_NOT_READY The TRB is not completed for execution.
1346 @retval Others Some erros happen when executing this request.
1350 EmmcPeimCheckTrbResult (
1356 EMMC_COMMAND_PACKET
*Packet
;
1364 Packet
= Trb
->Packet
;
1366 // Check Trb execution result by reading Normal Interrupt Status register.
1368 Status
= EmmcPeimHcRwMmio (
1369 Bar
+ EMMC_HC_NOR_INT_STS
,
1374 if (EFI_ERROR (Status
)) {
1378 // Check Transfer Complete bit is set or not.
1380 if ((IntStatus
& BIT1
) == BIT1
) {
1381 if ((IntStatus
& BIT15
) == BIT15
) {
1383 // Read Error Interrupt Status register to check if the error is
1384 // Data Timeout Error.
1385 // If yes, treat it as success as Transfer Complete has higher
1386 // priority than Data Timeout Error.
1388 Status
= EmmcPeimHcRwMmio (
1389 Bar
+ EMMC_HC_ERR_INT_STS
,
1394 if (!EFI_ERROR (Status
)) {
1395 if ((IntStatus
& BIT4
) == BIT4
) {
1396 Status
= EFI_SUCCESS
;
1398 Status
= EFI_DEVICE_ERROR
;
1406 // Check if there is a error happened during cmd execution.
1407 // If yes, then do error recovery procedure to follow SD Host Controller
1408 // Simplified Spec 3.0 section 3.10.1.
1410 if ((IntStatus
& BIT15
) == BIT15
) {
1411 Status
= EmmcPeimHcRwMmio (
1412 Bar
+ EMMC_HC_ERR_INT_STS
,
1417 if (EFI_ERROR (Status
)) {
1421 if ((IntStatus
& 0x0F) != 0) {
1424 if ((IntStatus
& 0xF0) != 0) {
1428 Status
= EmmcPeimHcRwMmio (
1429 Bar
+ EMMC_HC_SW_RST
,
1434 if (EFI_ERROR (Status
)) {
1437 Status
= EmmcPeimHcWaitMmioSet (
1438 Bar
+ EMMC_HC_SW_RST
,
1444 if (EFI_ERROR (Status
)) {
1448 Status
= EFI_DEVICE_ERROR
;
1452 // Check if DMA interrupt is signalled for the SDMA transfer.
1454 if ((Trb
->Mode
== EmmcSdmaMode
) && ((IntStatus
& BIT3
) == BIT3
)) {
1456 // Clear DMA interrupt bit.
1459 Status
= EmmcPeimHcRwMmio (
1460 Bar
+ EMMC_HC_NOR_INT_STS
,
1465 if (EFI_ERROR (Status
)) {
1469 // Update SDMA Address register.
1471 SdmaAddr
= EMMC_SDMA_ROUND_UP ((UINT32
)(UINTN
)Trb
->Data
, EMMC_SDMA_BOUNDARY
);
1472 Status
= EmmcPeimHcRwMmio (
1473 Bar
+ EMMC_HC_SDMA_ADDR
,
1478 if (EFI_ERROR (Status
)) {
1481 Trb
->Data
= (VOID
*)(UINTN
)SdmaAddr
;
1484 if ((Packet
->EmmcCmdBlk
->CommandType
!= EmmcCommandTypeAdtc
) &&
1485 (Packet
->EmmcCmdBlk
->ResponseType
!= EmmcResponceTypeR1b
) &&
1486 (Packet
->EmmcCmdBlk
->ResponseType
!= EmmcResponceTypeR5b
)) {
1487 if ((IntStatus
& BIT0
) == BIT0
) {
1488 Status
= EFI_SUCCESS
;
1493 if (Packet
->EmmcCmdBlk
->CommandIndex
== EMMC_SEND_TUNING_BLOCK
) {
1494 Status
= EFI_SUCCESS
;
1498 Status
= EFI_NOT_READY
;
1501 // Get response data when the cmd is executed successfully.
1503 if (!EFI_ERROR (Status
)) {
1504 if (Packet
->EmmcCmdBlk
->CommandType
!= EmmcCommandTypeBc
) {
1505 for (Index
= 0; Index
< 4; Index
++) {
1506 Status
= EmmcPeimHcRwMmio (
1507 Bar
+ EMMC_HC_RESPONSE
+ Index
* 4,
1512 if (EFI_ERROR (Status
)) {
1513 EmmcPeimHcLedOnOff (Bar
, FALSE
);
1517 CopyMem (Packet
->EmmcStatusBlk
, Response
, sizeof (Response
));
1521 if (Status
!= EFI_NOT_READY
) {
1522 EmmcPeimHcLedOnOff (Bar
, FALSE
);
1529 Wait for the TRB execution result.
1531 @param[in] Bar The mmio base address of the slot to be accessed.
1532 @param[in] Trb The pointer to the EMMC_TRB instance.
1534 @retval EFI_SUCCESS The TRB is executed successfully.
1535 @retval Others Some erros happen when executing this request.
1539 EmmcPeimWaitTrbResult (
1545 EMMC_COMMAND_PACKET
*Packet
;
1547 BOOLEAN InfiniteWait
;
1549 Packet
= Trb
->Packet
;
1551 // Wait Command Complete Interrupt Status bit in Normal Interrupt Status Register
1553 Timeout
= Packet
->Timeout
;
1555 InfiniteWait
= TRUE
;
1557 InfiniteWait
= FALSE
;
1560 while (InfiniteWait
|| (Timeout
> 0)) {
1562 // Check Trb execution result by reading Normal Interrupt Status register.
1564 Status
= EmmcPeimCheckTrbResult (Bar
, Trb
);
1565 if (Status
!= EFI_NOT_READY
) {
1569 // Stall for 1 microsecond.
1571 MicroSecondDelay (1);
1580 Sends EMMC command to an EMMC card that is attached to the EMMC controller.
1582 If Packet is successfully sent to the EMMC card, then EFI_SUCCESS is returned.
1584 If a device error occurs while sending the Packet, then EFI_DEVICE_ERROR is returned.
1586 If Slot is not in a valid range for the EMMC controller, then EFI_INVALID_PARAMETER
1589 If Packet defines a data command but both InDataBuffer and OutDataBuffer are NULL,
1590 EFI_INVALID_PARAMETER is returned.
1592 @param[in] Slot The slot number of the Emmc card to send the command to.
1593 @param[in,out] Packet A pointer to the EMMC command data structure.
1595 @retval EFI_SUCCESS The EMMC Command Packet was sent by the host.
1596 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send the SD
1598 @retval EFI_INVALID_PARAMETER Packet, Slot, or the contents of the Packet is invalid.
1599 @retval EFI_INVALID_PARAMETER Packet defines a data command but both InDataBuffer and
1600 OutDataBuffer are NULL.
1601 @retval EFI_NO_MEDIA SD Device not present in the Slot.
1602 @retval EFI_UNSUPPORTED The command described by the EMMC Command Packet is not
1603 supported by the host controller.
1604 @retval EFI_BAD_BUFFER_SIZE The InTransferLength or OutTransferLength exceeds the
1605 limit supported by EMMC card ( i.e. if the number of bytes
1606 exceed the Last LBA).
1612 IN EMMC_PEIM_HC_SLOT
*Slot
,
1613 IN OUT EMMC_COMMAND_PACKET
*Packet
1619 if (Packet
== NULL
) {
1620 return EFI_INVALID_PARAMETER
;
1623 if ((Packet
->EmmcCmdBlk
== NULL
) || (Packet
->EmmcStatusBlk
== NULL
)) {
1624 return EFI_INVALID_PARAMETER
;
1627 if ((Packet
->OutDataBuffer
== NULL
) && (Packet
->OutTransferLength
!= 0)) {
1628 return EFI_INVALID_PARAMETER
;
1631 if ((Packet
->InDataBuffer
== NULL
) && (Packet
->InTransferLength
!= 0)) {
1632 return EFI_INVALID_PARAMETER
;
1635 Trb
= EmmcPeimCreateTrb (Slot
, Packet
);
1637 return EFI_OUT_OF_RESOURCES
;
1640 Status
= EmmcPeimWaitTrbEnv (Slot
->EmmcHcBase
, Trb
);
1641 if (EFI_ERROR (Status
)) {
1645 Status
= EmmcPeimExecTrb (Slot
->EmmcHcBase
, Trb
);
1646 if (EFI_ERROR (Status
)) {
1650 Status
= EmmcPeimWaitTrbResult (Slot
->EmmcHcBase
, Trb
);
1651 if (EFI_ERROR (Status
)) {
1656 EmmcPeimFreeTrb (Trb
);
1662 Send command GO_IDLE_STATE (CMD0 with argument of 0x00000000) to the device to
1663 make it go to Idle State.
1665 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
1667 @param[in] Slot The slot number of the Emmc card to send the command to.
1669 @retval EFI_SUCCESS The EMMC device is reset correctly.
1670 @retval Others The device reset fails.
1675 IN EMMC_PEIM_HC_SLOT
*Slot
1678 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
1679 EMMC_STATUS_BLOCK EmmcStatusBlk
;
1680 EMMC_COMMAND_PACKET Packet
;
1683 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
1684 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
1685 ZeroMem (&Packet
, sizeof (Packet
));
1687 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
1688 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
1689 Packet
.Timeout
= EMMC_TIMEOUT
;
1691 EmmcCmdBlk
.CommandIndex
= EMMC_GO_IDLE_STATE
;
1692 EmmcCmdBlk
.CommandType
= EmmcCommandTypeBc
;
1693 EmmcCmdBlk
.ResponseType
= 0;
1694 EmmcCmdBlk
.CommandArgument
= 0;
1696 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
1702 Send command SEND_OP_COND to the EMMC device to get the data of the OCR register.
1704 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
1706 @param[in] Slot The slot number of the Emmc card to send the command to.
1707 @param[in, out] Argument On input, the argument of SEND_OP_COND is to send to the device.
1708 On output, the argument is the value of OCR register.
1710 @retval EFI_SUCCESS The operation is done correctly.
1711 @retval Others The operation fails.
1716 IN EMMC_PEIM_HC_SLOT
*Slot
,
1717 IN OUT UINT32
*Argument
1720 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
1721 EMMC_STATUS_BLOCK EmmcStatusBlk
;
1722 EMMC_COMMAND_PACKET Packet
;
1725 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
1726 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
1727 ZeroMem (&Packet
, sizeof (Packet
));
1729 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
1730 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
1731 Packet
.Timeout
= EMMC_TIMEOUT
;
1733 EmmcCmdBlk
.CommandIndex
= EMMC_SEND_OP_COND
;
1734 EmmcCmdBlk
.CommandType
= EmmcCommandTypeBcr
;
1735 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR3
;
1736 EmmcCmdBlk
.CommandArgument
= *Argument
;
1738 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
1739 if (!EFI_ERROR (Status
)) {
1741 // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12.
1743 *Argument
= EmmcStatusBlk
.Resp0
;
1750 Broadcast command ALL_SEND_CID to the bus to ask all the EMMC devices to send the
1751 data of their CID registers.
1753 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
1755 @param[in] Slot The slot number of the Emmc card to send the command to.
1757 @retval EFI_SUCCESS The operation is done correctly.
1758 @retval Others The operation fails.
1763 IN EMMC_PEIM_HC_SLOT
*Slot
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_ALL_SEND_CID
;
1780 EmmcCmdBlk
.CommandType
= EmmcCommandTypeBcr
;
1781 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR2
;
1782 EmmcCmdBlk
.CommandArgument
= 0;
1784 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
1790 Send command SET_RELATIVE_ADDR to the EMMC device to assign a Relative device
1793 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
1795 @param[in] Slot The slot number of the Emmc card to send the command to.
1796 @param[in] Rca The relative device address to be assigned.
1798 @retval EFI_SUCCESS The operation is done correctly.
1799 @retval Others The operation fails.
1804 IN EMMC_PEIM_HC_SLOT
*Slot
,
1808 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
1809 EMMC_STATUS_BLOCK EmmcStatusBlk
;
1810 EMMC_COMMAND_PACKET Packet
;
1813 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
1814 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
1815 ZeroMem (&Packet
, sizeof (Packet
));
1817 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
1818 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
1819 Packet
.Timeout
= EMMC_TIMEOUT
;
1821 EmmcCmdBlk
.CommandIndex
= EMMC_SET_RELATIVE_ADDR
;
1822 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAc
;
1823 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR1
;
1824 EmmcCmdBlk
.CommandArgument
= Rca
<< 16;
1826 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
1832 Send command SEND_CSD to the EMMC device to get the data of the CSD register.
1834 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
1836 @param[in] Slot The slot number of the Emmc card to send the command to.
1837 @param[in] Rca The relative device address of selected device.
1838 @param[out] Csd The buffer to store the content of the CSD register.
1839 Note the caller should ignore the lowest byte of this
1840 buffer as the content of this byte is meaningless even
1841 if the operation succeeds.
1843 @retval EFI_SUCCESS The operation is done correctly.
1844 @retval Others The operation fails.
1849 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_SEND_CSD
;
1868 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAc
;
1869 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR2
;
1870 EmmcCmdBlk
.CommandArgument
= Rca
<< 16;
1872 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
1873 if (!EFI_ERROR (Status
)) {
1875 // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12.
1877 CopyMem (((UINT8
*)Csd
) + 1, &EmmcStatusBlk
.Resp0
, sizeof (EMMC_CSD
) - 1);
1884 Send command SELECT_DESELECT_CARD to the EMMC device to select/deselect it.
1886 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
1888 @param[in] Slot The slot number of the Emmc card to send the command to.
1889 @param[in] Rca The relative device address of selected device.
1891 @retval EFI_SUCCESS The operation is done correctly.
1892 @retval Others The operation fails.
1897 IN EMMC_PEIM_HC_SLOT
*Slot
,
1901 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
1902 EMMC_STATUS_BLOCK EmmcStatusBlk
;
1903 EMMC_COMMAND_PACKET Packet
;
1906 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
1907 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
1908 ZeroMem (&Packet
, sizeof (Packet
));
1910 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
1911 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
1912 Packet
.Timeout
= EMMC_TIMEOUT
;
1914 EmmcCmdBlk
.CommandIndex
= EMMC_SELECT_DESELECT_CARD
;
1915 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAc
;
1916 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR1
;
1917 EmmcCmdBlk
.CommandArgument
= Rca
<< 16;
1919 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
1925 Send command SEND_EXT_CSD to the EMMC device to get the data of the EXT_CSD register.
1927 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
1929 @param[in] Slot The slot number of the Emmc card to send the command to.
1930 @param[out] ExtCsd The buffer to store the content of the EXT_CSD register.
1932 @retval EFI_SUCCESS The operation is done correctly.
1933 @retval Others The operation fails.
1938 IN EMMC_PEIM_HC_SLOT
*Slot
,
1939 OUT EMMC_EXT_CSD
*ExtCsd
1942 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
1943 EMMC_STATUS_BLOCK EmmcStatusBlk
;
1944 EMMC_COMMAND_PACKET Packet
;
1947 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
1948 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
1949 ZeroMem (&Packet
, sizeof (Packet
));
1951 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
1952 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
1953 Packet
.Timeout
= EMMC_TIMEOUT
;
1955 EmmcCmdBlk
.CommandIndex
= EMMC_SEND_EXT_CSD
;
1956 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAdtc
;
1957 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR1
;
1958 EmmcCmdBlk
.CommandArgument
= 0x00000000;
1960 Packet
.InDataBuffer
= ExtCsd
;
1961 Packet
.InTransferLength
= sizeof (EMMC_EXT_CSD
);
1963 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
1968 Send command SWITCH to the EMMC device to switch the mode of operation of the
1969 selected Device or modifies the EXT_CSD registers.
1971 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
1973 @param[in] Slot The slot number of the Emmc card to send the command to.
1974 @param[in] Access The access mode of SWTICH command.
1975 @param[in] Index The offset of the field to be access.
1976 @param[in] Value The value to be set to the specified field of EXT_CSD register.
1977 @param[in] CmdSet The value of CmdSet field of EXT_CSD register.
1979 @retval EFI_SUCCESS The operation is done correctly.
1980 @retval Others The operation fails.
1985 IN EMMC_PEIM_HC_SLOT
*Slot
,
1992 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
1993 EMMC_STATUS_BLOCK EmmcStatusBlk
;
1994 EMMC_COMMAND_PACKET Packet
;
1997 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
1998 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
1999 ZeroMem (&Packet
, sizeof (Packet
));
2001 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
2002 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
2003 Packet
.Timeout
= EMMC_TIMEOUT
;
2005 EmmcCmdBlk
.CommandIndex
= EMMC_SWITCH
;
2006 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAc
;
2007 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR1b
;
2008 EmmcCmdBlk
.CommandArgument
= (Access
<< 24) | (Index
<< 16) | (Value
<< 8) | CmdSet
;
2010 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
2016 Send command SEND_STATUS to the addressed EMMC device to get its status register.
2018 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
2020 @param[in] Slot The slot number of the Emmc card to send the command to.
2021 @param[in] Rca The relative device address of addressed device.
2022 @param[out] DevStatus The returned device status.
2024 @retval EFI_SUCCESS The operation is done correctly.
2025 @retval Others The operation fails.
2029 EmmcPeimSendStatus (
2030 IN EMMC_PEIM_HC_SLOT
*Slot
,
2032 OUT UINT32
*DevStatus
2035 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
2036 EMMC_STATUS_BLOCK EmmcStatusBlk
;
2037 EMMC_COMMAND_PACKET Packet
;
2040 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
2041 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
2042 ZeroMem (&Packet
, sizeof (Packet
));
2044 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
2045 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
2046 Packet
.Timeout
= EMMC_TIMEOUT
;
2048 EmmcCmdBlk
.CommandIndex
= EMMC_SEND_STATUS
;
2049 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAc
;
2050 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR1
;
2051 EmmcCmdBlk
.CommandArgument
= Rca
<< 16;
2053 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
2054 if (!EFI_ERROR (Status
)) {
2055 *DevStatus
= EmmcStatusBlk
.Resp0
;
2062 Send command SET_BLOCK_COUNT to the addressed EMMC device to set the number of
2063 blocks for the following block read/write cmd.
2065 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
2067 @param[in] Slot The slot number of the Emmc card to send the command to.
2068 @param[in] BlockCount The number of the logical block to access.
2070 @retval EFI_SUCCESS The operation is done correctly.
2071 @retval Others The operation fails.
2075 EmmcPeimSetBlkCount (
2076 IN EMMC_PEIM_HC_SLOT
*Slot
,
2077 IN UINT16 BlockCount
2080 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
2081 EMMC_STATUS_BLOCK EmmcStatusBlk
;
2082 EMMC_COMMAND_PACKET Packet
;
2085 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
2086 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
2087 ZeroMem (&Packet
, sizeof (Packet
));
2089 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
2090 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
2091 Packet
.Timeout
= EMMC_TIMEOUT
;
2093 EmmcCmdBlk
.CommandIndex
= EMMC_SET_BLOCK_COUNT
;
2094 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAc
;
2095 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR1
;
2096 EmmcCmdBlk
.CommandArgument
= BlockCount
;
2098 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
2104 Send command READ_MULTIPLE_BLOCK/WRITE_MULTIPLE_BLOCK to the addressed EMMC device
2105 to read/write the specified number of blocks.
2107 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
2109 @param[in] Slot The slot number of the Emmc card to send the command to.
2110 @param[in] Lba The logical block address of starting access.
2111 @param[in] BlockSize The block size of specified EMMC device partition.
2112 @param[in] Buffer The pointer to the transfer buffer.
2113 @param[in] BufferSize The size of transfer buffer.
2114 @param[in] IsRead Boolean to show the operation direction.
2116 @retval EFI_SUCCESS The operation is done correctly.
2117 @retval Others The operation fails.
2121 EmmcPeimRwMultiBlocks (
2122 IN EMMC_PEIM_HC_SLOT
*Slot
,
2124 IN UINT32 BlockSize
,
2126 IN UINTN BufferSize
,
2130 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
2131 EMMC_STATUS_BLOCK EmmcStatusBlk
;
2132 EMMC_COMMAND_PACKET Packet
;
2135 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
2136 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
2137 ZeroMem (&Packet
, sizeof (Packet
));
2139 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
2140 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
2142 // Calculate timeout value through the below formula.
2143 // Timeout = (transfer size) / (2MB/s).
2144 // Taking 2MB/s as divisor is because it's nearest to the eMMC lowest
2145 // transfer speed (2.4MB/s).
2146 // Refer to eMMC 5.0 spec section 6.9.1 for details.
2148 Packet
.Timeout
= (BufferSize
/ (2 * 1024 * 1024) + 1) * 1000 * 1000;;
2151 Packet
.InDataBuffer
= Buffer
;
2152 Packet
.InTransferLength
= (UINT32
)BufferSize
;
2154 EmmcCmdBlk
.CommandIndex
= EMMC_READ_MULTIPLE_BLOCK
;
2155 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAdtc
;
2156 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR1
;
2158 Packet
.OutDataBuffer
= Buffer
;
2159 Packet
.OutTransferLength
= (UINT32
)BufferSize
;
2161 EmmcCmdBlk
.CommandIndex
= EMMC_WRITE_MULTIPLE_BLOCK
;
2162 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAdtc
;
2163 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR1
;
2166 if (Slot
->SectorAddressing
) {
2167 EmmcCmdBlk
.CommandArgument
= (UINT32
)Lba
;
2169 EmmcCmdBlk
.CommandArgument
= (UINT32
)MultU64x32 (Lba
, BlockSize
);
2172 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
2178 Send command SEND_TUNING_BLOCK to the EMMC device for HS200 optimal sampling point
2181 It may be sent up to 40 times until the host finishes the tuning procedure.
2183 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 for details.
2185 @param[in] Slot The slot number of the Emmc card to send the command to.
2186 @param[in] BusWidth The bus width to work.
2188 @retval EFI_SUCCESS The operation is done correctly.
2189 @retval Others The operation fails.
2193 EmmcPeimSendTuningBlk (
2194 IN EMMC_PEIM_HC_SLOT
*Slot
,
2198 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
2199 EMMC_STATUS_BLOCK EmmcStatusBlk
;
2200 EMMC_COMMAND_PACKET Packet
;
2202 UINT8 TuningBlock
[128];
2204 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
2205 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
2206 ZeroMem (&Packet
, sizeof (Packet
));
2208 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
2209 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
2210 Packet
.Timeout
= EMMC_TIMEOUT
;
2212 EmmcCmdBlk
.CommandIndex
= EMMC_SEND_TUNING_BLOCK
;
2213 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAdtc
;
2214 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR1
;
2215 EmmcCmdBlk
.CommandArgument
= 0;
2217 Packet
.InDataBuffer
= TuningBlock
;
2218 if (BusWidth
== 8) {
2219 Packet
.InTransferLength
= sizeof (TuningBlock
);
2221 Packet
.InTransferLength
= 64;
2224 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
2230 Tunning the clock to get HS200 optimal sampling point.
2232 Command SEND_TUNING_BLOCK may be sent up to 40 times until the host finishes the
2235 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
2236 Simplified Spec 3.0 section Figure 2-29 for details.
2238 @param[in] Slot The slot number of the Emmc card to send the command to.
2239 @param[in] BusWidth The bus width to work.
2241 @retval EFI_SUCCESS The operation is done correctly.
2242 @retval Others The operation fails.
2246 EmmcPeimTuningClkForHs200 (
2247 IN EMMC_PEIM_HC_SLOT
*Slot
,
2256 // Notify the host that the sampling clock tuning procedure starts.
2259 Status
= EmmcPeimHcOrMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2260 if (EFI_ERROR (Status
)) {
2264 // Ask the device to send a sequence of tuning blocks till the tuning procedure is done.
2268 Status
= EmmcPeimSendTuningBlk (Slot
, BusWidth
);
2269 if (EFI_ERROR (Status
)) {
2273 Status
= EmmcPeimHcRwMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL2
, TRUE
, sizeof (HostCtrl2
), &HostCtrl2
);
2274 if (EFI_ERROR (Status
)) {
2278 if ((HostCtrl2
& (BIT6
| BIT7
)) == BIT7
) {
2281 } while (++Retry
< 40);
2284 Status
= EFI_TIMEOUT
;
2290 Switch the bus width to specified width.
2292 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.9 and SD Host Controller
2293 Simplified Spec 3.0 section Figure 3-7 for details.
2295 @param[in] Slot The slot number of the Emmc card to send the command to.
2296 @param[in] Rca The relative device address to be assigned.
2297 @param[in] IsDdr If TRUE, use dual data rate data simpling method. Otherwise
2298 use single data rate data simpling method.
2299 @param[in] BusWidth The bus width to be set, it could be 4 or 8.
2301 @retval EFI_SUCCESS The operation is done correctly.
2302 @retval Others The operation fails.
2306 EmmcPeimSwitchBusWidth (
2307 IN EMMC_PEIM_HC_SLOT
*Slot
,
2321 // Write Byte, the Value field is written into the byte pointed by Index.
2324 Index
= OFFSET_OF (EMMC_EXT_CSD
, BusWidth
);
2325 if (BusWidth
== 4) {
2327 } else if (BusWidth
== 8) {
2330 return EFI_INVALID_PARAMETER
;
2338 Status
= EmmcPeimSwitch (Slot
, Access
, Index
, Value
, CmdSet
);
2339 if (EFI_ERROR (Status
)) {
2343 Status
= EmmcPeimSendStatus (Slot
, Rca
, &DevStatus
);
2344 if (EFI_ERROR (Status
)) {
2348 // Check the switch operation is really successful or not.
2350 if ((DevStatus
& BIT7
) != 0) {
2351 return EFI_DEVICE_ERROR
;
2354 Status
= EmmcPeimHcSetBusWidth (Slot
->EmmcHcBase
, BusWidth
);
2360 Switch the clock frequency to the specified value.
2362 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6 and SD Host Controller
2363 Simplified Spec 3.0 section Figure 3-3 for details.
2365 @param[in] Slot The slot number of the Emmc card to send the command to.
2366 @param[in] Rca The relative device address to be assigned.
2367 @param[in] HsTiming The value to be written to HS_TIMING field of EXT_CSD register.
2368 @param[in] ClockFreq The max clock frequency to be set, the unit is MHz.
2370 @retval EFI_SUCCESS The operation is done correctly.
2371 @retval Others The operation fails.
2375 EmmcPeimSwitchClockFreq (
2376 IN EMMC_PEIM_HC_SLOT
*Slot
,
2390 // Write Byte, the Value field is written into the byte pointed by Index.
2393 Index
= OFFSET_OF (EMMC_EXT_CSD
, HsTiming
);
2397 Status
= EmmcPeimSwitch (Slot
, Access
, Index
, Value
, CmdSet
);
2398 if (EFI_ERROR (Status
)) {
2402 Status
= EmmcPeimSendStatus (Slot
, Rca
, &DevStatus
);
2403 if (EFI_ERROR (Status
)) {
2407 // Check the switch operation is really successful or not.
2409 if ((DevStatus
& BIT7
) != 0) {
2410 return EFI_DEVICE_ERROR
;
2413 // Convert the clock freq unit from MHz to KHz.
2415 Status
= EmmcPeimHcClockSupply (Slot
->EmmcHcBase
, ClockFreq
* 1000);
2421 Switch to the High Speed timing according to request.
2423 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
2424 Simplified Spec 3.0 section Figure 2-29 for details.
2426 @param[in] Slot The slot number of the Emmc card to send the command to.
2427 @param[in] Rca The relative device address to be assigned.
2428 @param[in] ClockFreq The max clock frequency to be set.
2429 @param[in] IsDdr If TRUE, use dual data rate data simpling method. Otherwise
2430 use single data rate data simpling method.
2431 @param[in] BusWidth The bus width to be set, it could be 4 or 8.
2433 @retval EFI_SUCCESS The operation is done correctly.
2434 @retval Others The operation fails.
2438 EmmcPeimSwitchToHighSpeed (
2439 IN EMMC_PEIM_HC_SLOT
*Slot
,
2441 IN UINT32 ClockFreq
,
2451 Status
= EmmcPeimSwitchBusWidth (Slot
, Rca
, IsDdr
, BusWidth
);
2452 if (EFI_ERROR (Status
)) {
2456 // Set to Hight Speed timing
2459 Status
= EmmcPeimHcOrMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
2460 if (EFI_ERROR (Status
)) {
2464 HostCtrl2
= (UINT8
)~0x7;
2465 Status
= EmmcPeimHcAndMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2466 if (EFI_ERROR (Status
)) {
2471 } else if (ClockFreq
== 52) {
2476 Status
= EmmcPeimHcOrMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2477 if (EFI_ERROR (Status
)) {
2482 Status
= EmmcPeimSwitchClockFreq (Slot
, Rca
, HsTiming
, ClockFreq
);
2483 if (EFI_ERROR (Status
)) {
2491 Switch to the HS200 timing according to request.
2493 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
2494 Simplified Spec 3.0 section Figure 2-29 for details.
2496 @param[in] Slot The slot number of the Emmc card to send the command to.
2497 @param[in] Rca The relative device address to be assigned.
2498 @param[in] ClockFreq The max clock frequency to be set.
2499 @param[in] BusWidth The bus width to be set, it could be 4 or 8.
2501 @retval EFI_SUCCESS The operation is done correctly.
2502 @retval Others The operation fails.
2506 EmmcPeimSwitchToHS200 (
2507 IN EMMC_PEIM_HC_SLOT
*Slot
,
2509 IN UINT32 ClockFreq
,
2518 if ((BusWidth
!= 4) && (BusWidth
!= 8)) {
2519 return EFI_INVALID_PARAMETER
;
2522 Status
= EmmcPeimSwitchBusWidth (Slot
, Rca
, FALSE
, BusWidth
);
2523 if (EFI_ERROR (Status
)) {
2527 // Set to HS200/SDR104 timing
2530 // Stop bus clock at first
2532 Status
= EmmcPeimHcStopClock (Slot
->EmmcHcBase
);
2533 if (EFI_ERROR (Status
)) {
2537 HostCtrl2
= (UINT8
)~0x7;
2538 Status
= EmmcPeimHcAndMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2539 if (EFI_ERROR (Status
)) {
2542 HostCtrl2
= BIT0
| BIT1
;
2543 Status
= EmmcPeimHcOrMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2544 if (EFI_ERROR (Status
)) {
2549 // Wait Internal Clock Stable in the Clock Control register to be 1 before set SD Clock Enable bit
2551 Status
= EmmcPeimHcWaitMmioSet (
2552 Slot
->EmmcHcBase
+ EMMC_HC_CLOCK_CTRL
,
2558 if (EFI_ERROR (Status
)) {
2562 // Set SD Clock Enable in the Clock Control register to 1
2565 Status
= EmmcPeimHcOrMmio (Slot
->EmmcHcBase
+ EMMC_HC_CLOCK_CTRL
, sizeof (ClockCtrl
), &ClockCtrl
);
2568 Status
= EmmcPeimSwitchClockFreq (Slot
, Rca
, HsTiming
, ClockFreq
);
2569 if (EFI_ERROR (Status
)) {
2573 Status
= EmmcPeimTuningClkForHs200 (Slot
, BusWidth
);
2579 Switch to the HS400 timing according to request.
2581 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
2582 Simplified Spec 3.0 section Figure 2-29 for details.
2584 @param[in] Slot The slot number of the Emmc card to send the command to.
2585 @param[in] Rca The relative device address to be assigned.
2586 @param[in] ClockFreq The max clock frequency to be set.
2588 @retval EFI_SUCCESS The operation is done correctly.
2589 @retval Others The operation fails.
2593 EmmcPeimSwitchToHS400 (
2594 IN EMMC_PEIM_HC_SLOT
*Slot
,
2603 Status
= EmmcPeimSwitchToHS200 (Slot
, Rca
, ClockFreq
, 8);
2604 if (EFI_ERROR (Status
)) {
2608 // Set to Hight Speed timing and set the clock frequency to a value less than 52MHz.
2611 Status
= EmmcPeimSwitchClockFreq (Slot
, Rca
, HsTiming
, 52);
2612 if (EFI_ERROR (Status
)) {
2616 // HS400 mode must use 8 data lines.
2618 Status
= EmmcPeimSwitchBusWidth (Slot
, Rca
, TRUE
, 8);
2619 if (EFI_ERROR (Status
)) {
2623 // Set to HS400 timing
2625 HostCtrl2
= (UINT8
)~0x7;
2626 Status
= EmmcPeimHcAndMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2627 if (EFI_ERROR (Status
)) {
2630 HostCtrl2
= BIT0
| BIT2
;
2631 Status
= EmmcPeimHcOrMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2632 if (EFI_ERROR (Status
)) {
2637 Status
= EmmcPeimSwitchClockFreq (Slot
, Rca
, HsTiming
, ClockFreq
);
2643 Switch the high speed timing according to request.
2645 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
2646 Simplified Spec 3.0 section Figure 2-29 for details.
2648 @param[in] Slot The slot number of the Emmc card to send the command to.
2649 @param[in] Rca The relative device address to be assigned.
2651 @retval EFI_SUCCESS The operation is done correctly.
2652 @retval Others The operation fails.
2656 EmmcPeimSetBusMode (
2657 IN EMMC_PEIM_HC_SLOT
*Slot
,
2662 EMMC_HC_SLOT_CAP Capability
;
2668 Status
= EmmcPeimGetCsd (Slot
, Rca
, &Slot
->Csd
);
2669 if (EFI_ERROR (Status
)) {
2670 DEBUG ((EFI_D_ERROR
, "EmmcPeimSetBusMode: EmmcPeimGetCsd fails with %r\n", Status
));
2674 if ((Slot
->Csd
.CSizeLow
| Slot
->Csd
.CSizeHigh
<< 2) == 0xFFF) {
2675 Slot
->SectorAddressing
= TRUE
;
2677 Slot
->SectorAddressing
= FALSE
;
2680 Status
= EmmcPeimSelect (Slot
, Rca
);
2681 if (EFI_ERROR (Status
)) {
2682 DEBUG ((EFI_D_ERROR
, "EmmcPeimSetBusMode: EmmcPeimSelect fails with %r\n", Status
));
2686 Status
= EmmcPeimHcGetCapability (Slot
->EmmcHcBase
, &Capability
);
2687 if (EFI_ERROR (Status
)) {
2688 DEBUG ((EFI_D_ERROR
, "EmmcPeimSetBusMode: EmmcPeimHcGetCapability fails with %r\n", Status
));
2692 ASSERT (Capability
.BaseClkFreq
!= 0);
2694 // Check if the Host Controller support 8bits bus width.
2696 if (Capability
.BusWidth8
!= 0) {
2702 // Get Deivce_Type from EXT_CSD register.
2704 Status
= EmmcPeimGetExtCsd (Slot
, &Slot
->ExtCsd
);
2705 if (EFI_ERROR (Status
)) {
2706 DEBUG ((EFI_D_ERROR
, "EmmcPeimSetBusMode: EmmcPeimGetExtCsd fails with %r\n", Status
));
2710 // Calculate supported bus speed/bus width/clock frequency.
2715 if (((Slot
->ExtCsd
.DeviceType
& (BIT4
| BIT5
)) != 0) && (Capability
.Sdr104
!= 0)) {
2719 } else if (((Slot
->ExtCsd
.DeviceType
& (BIT2
| BIT3
)) != 0) && (Capability
.Ddr50
!= 0)) {
2723 } else if (((Slot
->ExtCsd
.DeviceType
& BIT1
) != 0) && (Capability
.HighSpeed
!= 0)) {
2727 } else if (((Slot
->ExtCsd
.DeviceType
& BIT0
) != 0) && (Capability
.HighSpeed
!= 0)) {
2733 // Check if both of the device and the host controller support HS400 DDR mode.
2735 if (((Slot
->ExtCsd
.DeviceType
& (BIT6
| BIT7
)) != 0) && (Capability
.Hs400
!= 0)) {
2737 // The host controller supports 8bits bus.
2739 ASSERT (BusWidth
== 8);
2745 if ((ClockFreq
== 0) || (HsTiming
== 0)) {
2747 // Continue using default setting.
2752 DEBUG ((EFI_D_INFO
, "HsTiming %d ClockFreq %d BusWidth %d Ddr %a\n", HsTiming
, ClockFreq
, BusWidth
, IsDdr
? "TRUE":"FALSE"));
2754 if (HsTiming
== 3) {
2756 // Execute HS400 timing switch procedure
2758 Status
= EmmcPeimSwitchToHS400 (Slot
, Rca
, ClockFreq
);
2759 } else if (HsTiming
== 2) {
2761 // Execute HS200 timing switch procedure
2763 Status
= EmmcPeimSwitchToHS200 (Slot
, Rca
, ClockFreq
, BusWidth
);
2766 // Execute High Speed timing switch procedure
2768 Status
= EmmcPeimSwitchToHighSpeed (Slot
, Rca
, ClockFreq
, BusWidth
, IsDdr
);
2775 Execute EMMC device identification procedure.
2777 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
2779 @param[in] Slot The slot number of the Emmc card to send the command to.
2781 @retval EFI_SUCCESS There is a EMMC card.
2782 @retval Others There is not a EMMC card.
2786 EmmcPeimIdentification (
2787 IN EMMC_PEIM_HC_SLOT
*Slot
2794 Status
= EmmcPeimReset (Slot
);
2795 if (EFI_ERROR (Status
)) {
2796 DEBUG ((EFI_D_ERROR
, "EmmcPeimIdentification: EmmcPeimReset fails with %r\n", Status
));
2802 Status
= EmmcPeimGetOcr (Slot
, &Ocr
);
2803 if (EFI_ERROR (Status
)) {
2804 DEBUG ((EFI_D_ERROR
, "EmmcPeimIdentification: EmmcPeimGetOcr fails with %r\n", Status
));
2807 } while ((Ocr
& BIT31
) == 0);
2809 Status
= EmmcPeimGetAllCid (Slot
);
2810 if (EFI_ERROR (Status
)) {
2811 DEBUG ((EFI_D_ERROR
, "EmmcPeimIdentification: EmmcPeimGetAllCid fails with %r\n", Status
));
2815 // Don't support multiple devices on the slot, that is
2816 // shared bus slot feature.
2819 Status
= EmmcPeimSetRca (Slot
, Rca
);
2820 if (EFI_ERROR (Status
)) {
2821 DEBUG ((EFI_D_ERROR
, "EmmcPeimIdentification: EmmcPeimSetRca fails with %r\n", Status
));
2825 // Enter Data Tranfer Mode.
2827 DEBUG ((EFI_D_INFO
, "Found a EMMC device at slot [%d], RCA [%d]\n", Slot
, Rca
));
2829 Status
= EmmcPeimSetBusMode (Slot
, Rca
);