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
;
539 if (ClockFreq
== 0) {
540 return EFI_INVALID_PARAMETER
;
543 if (ClockFreq
> (BaseClkFreq
* 1000)) {
544 ClockFreq
= BaseClkFreq
* 1000;
548 // Calculate the divisor of base frequency.
551 SettingFreq
= BaseClkFreq
* 1000;
552 while (ClockFreq
< SettingFreq
) {
555 SettingFreq
= (BaseClkFreq
* 1000) / (2 * Divisor
);
556 Remainder
= (BaseClkFreq
* 1000) % (2 * Divisor
);
557 if ((ClockFreq
== SettingFreq
) && (Remainder
== 0)) {
560 if ((ClockFreq
== SettingFreq
) && (Remainder
!= 0)) {
565 DEBUG ((EFI_D_INFO
, "BaseClkFreq %dMHz Divisor %d ClockFreq %dKhz\n", BaseClkFreq
, Divisor
, ClockFreq
));
567 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_CTRL_VER
, TRUE
, sizeof (ControllerVer
), &ControllerVer
);
568 if (EFI_ERROR (Status
)) {
572 // Set SDCLK Frequency Select and Internal Clock Enable fields in Clock Control register.
574 if ((ControllerVer
& 0xFF) == 2) {
575 ASSERT (Divisor
<= 0x3FF);
576 ClockCtrl
= ((Divisor
& 0xFF) << 8) | ((Divisor
& 0x300) >> 2);
577 } else if (((ControllerVer
& 0xFF) == 0) || ((ControllerVer
& 0xFF) == 1)) {
579 // Only the most significant bit can be used as divisor.
581 if (((Divisor
- 1) & Divisor
) != 0) {
582 Divisor
= 1 << (HighBitSet32 (Divisor
) + 1);
584 ASSERT (Divisor
<= 0x80);
585 ClockCtrl
= (Divisor
& 0xFF) << 8;
587 DEBUG ((EFI_D_ERROR
, "Unknown SD Host Controller Spec version [0x%x]!!!\n", ControllerVer
));
588 return EFI_UNSUPPORTED
;
592 // Stop bus clock at first
594 Status
= EmmcPeimHcStopClock (Bar
);
595 if (EFI_ERROR (Status
)) {
600 // Supply clock frequency with specified divisor
603 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_CLOCK_CTRL
, FALSE
, sizeof (ClockCtrl
), &ClockCtrl
);
604 if (EFI_ERROR (Status
)) {
605 DEBUG ((EFI_D_ERROR
, "Set SDCLK Frequency Select and Internal Clock Enable fields fails\n"));
610 // Wait Internal Clock Stable in the Clock Control register to be 1
612 Status
= EmmcPeimHcWaitMmioSet (
613 Bar
+ EMMC_HC_CLOCK_CTRL
,
619 if (EFI_ERROR (Status
)) {
624 // Set SD Clock Enable in the Clock Control register to 1
627 Status
= EmmcPeimHcOrMmio (Bar
+ EMMC_HC_CLOCK_CTRL
, sizeof (ClockCtrl
), &ClockCtrl
);
633 EMMC bus power control.
635 Refer to SD Host Controller Simplified spec 3.0 Section 3.3 for details.
637 @param[in] Bar The mmio base address of the slot to be accessed.
638 @param[in] PowerCtrl The value setting to the power control register.
640 @retval TRUE There is a EMMC card attached.
641 @retval FALSE There is no a EMMC card attached.
645 EmmcPeimHcPowerControl (
655 PowerCtrl
&= (UINT8
)~BIT0
;
656 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_POWER_CTRL
, FALSE
, sizeof (PowerCtrl
), &PowerCtrl
);
657 if (EFI_ERROR (Status
)) {
662 // Set SD Bus Voltage Select and SD Bus Power fields in Power Control Register
665 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_POWER_CTRL
, FALSE
, sizeof (PowerCtrl
), &PowerCtrl
);
671 Set the EMMC bus width.
673 Refer to SD Host Controller Simplified spec 3.0 Section 3.4 for details.
675 @param[in] Bar The mmio base address of the slot to be accessed.
676 @param[in] BusWidth The bus width used by the EMMC device, it must be 1, 4 or 8.
678 @retval EFI_SUCCESS The bus width is set successfully.
679 @retval Others The bus width isn't set successfully.
683 EmmcPeimHcSetBusWidth (
692 HostCtrl1
= (UINT8
)~(BIT5
| BIT1
);
693 Status
= EmmcPeimHcAndMmio (Bar
+ EMMC_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
694 } else if (BusWidth
== 4) {
695 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_HOST_CTRL1
, TRUE
, sizeof (HostCtrl1
), &HostCtrl1
);
696 if (EFI_ERROR (Status
)) {
700 HostCtrl1
&= (UINT8
)~BIT5
;
701 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_HOST_CTRL1
, FALSE
, sizeof (HostCtrl1
), &HostCtrl1
);
702 } else if (BusWidth
== 8) {
703 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_HOST_CTRL1
, TRUE
, sizeof (HostCtrl1
), &HostCtrl1
);
704 if (EFI_ERROR (Status
)) {
707 HostCtrl1
&= (UINT8
)~BIT1
;
709 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_HOST_CTRL1
, FALSE
, sizeof (HostCtrl1
), &HostCtrl1
);
712 return EFI_INVALID_PARAMETER
;
719 Supply EMMC card with lowest clock frequency at initialization.
721 @param[in] Bar The mmio base address of the slot to be accessed.
723 @retval EFI_SUCCESS The clock is supplied successfully.
724 @retval Others The clock isn't supplied successfully.
728 EmmcPeimHcInitClockFreq (
733 EMMC_HC_SLOT_CAP Capability
;
737 // Calculate a divisor for SD clock frequency
739 Status
= EmmcPeimHcGetCapability (Bar
, &Capability
);
740 if (EFI_ERROR (Status
)) {
744 if (Capability
.BaseClkFreq
== 0) {
746 // Don't support get Base Clock Frequency information via another method
748 return EFI_UNSUPPORTED
;
751 // Supply 400KHz clock frequency at initialization phase.
754 Status
= EmmcPeimHcClockSupply (Bar
, InitFreq
);
759 Supply EMMC card with maximum voltage at initialization.
761 Refer to SD Host Controller Simplified spec 3.0 Section 3.3 for details.
763 @param[in] Bar The mmio base address of the slot to be accessed.
765 @retval EFI_SUCCESS The voltage is supplied successfully.
766 @retval Others The voltage isn't supplied successfully.
770 EmmcPeimHcInitPowerVoltage (
775 EMMC_HC_SLOT_CAP Capability
;
780 // Get the support voltage of the Host Controller
782 Status
= EmmcPeimHcGetCapability (Bar
, &Capability
);
783 if (EFI_ERROR (Status
)) {
787 // Calculate supported maximum voltage according to SD Bus Voltage Select
789 if (Capability
.Voltage33
!= 0) {
794 } else if (Capability
.Voltage30
!= 0) {
799 } else if (Capability
.Voltage18
!= 0) {
805 Status
= EmmcPeimHcOrMmio (Bar
+ EMMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
806 if (EFI_ERROR (Status
)) {
809 MicroSecondDelay (5000);
812 return EFI_DEVICE_ERROR
;
816 // Set SD Bus Voltage Select and SD Bus Power fields in Power Control Register
818 Status
= EmmcPeimHcPowerControl (Bar
, MaxVoltage
);
824 Initialize the Timeout Control register with most conservative value at initialization.
826 Refer to SD Host Controller Simplified spec 3.0 Section 2.2.15 for details.
828 @param[in] Bar The mmio base address of the slot to be accessed.
830 @retval EFI_SUCCESS The timeout control register is configured successfully.
831 @retval Others The timeout control register isn't configured successfully.
835 EmmcPeimHcInitTimeoutCtrl (
843 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_TIMEOUT_CTRL
, FALSE
, sizeof (Timeout
), &Timeout
);
849 Initial EMMC host controller with lowest clock frequency, max power and max timeout value
852 @param[in] Bar The mmio base address of the slot to be accessed.
854 @retval EFI_SUCCESS The host controller is initialized successfully.
855 @retval Others The host controller isn't initialized successfully.
865 Status
= EmmcPeimHcInitClockFreq (Bar
);
866 if (EFI_ERROR (Status
)) {
870 Status
= EmmcPeimHcInitPowerVoltage (Bar
);
871 if (EFI_ERROR (Status
)) {
875 Status
= EmmcPeimHcInitTimeoutCtrl (Bar
);
882 @param[in] Bar The mmio base address of the slot to be accessed.
883 @param[in] On The boolean to turn on/off LED.
885 @retval EFI_SUCCESS The LED is turned on/off successfully.
886 @retval Others The LED isn't turned on/off successfully.
900 Status
= EmmcPeimHcOrMmio (Bar
+ EMMC_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
902 HostCtrl1
= (UINT8
)~BIT0
;
903 Status
= EmmcPeimHcAndMmio (Bar
+ EMMC_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
910 Build ADMA descriptor table for transfer.
912 Refer to SD Host Controller Simplified spec 3.0 Section 1.13 for details.
914 @param[in] Trb The pointer to the EMMC_TRB instance.
916 @retval EFI_SUCCESS The ADMA descriptor table is created successfully.
917 @retval Others The ADMA descriptor table isn't created successfully.
925 EFI_PHYSICAL_ADDRESS Data
;
932 Data
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)Trb
->Data
;
933 DataLen
= Trb
->DataLen
;
935 // Only support 32bit ADMA Descriptor Table
937 if ((Data
>= 0x100000000ul
) || ((Data
+ DataLen
) > 0x100000000ul
)) {
938 return EFI_INVALID_PARAMETER
;
941 // Address field shall be set on 32-bit boundary (Lower 2-bit is always set to 0)
942 // for 32-bit address descriptor table.
944 if ((Data
& (BIT0
| BIT1
)) != 0) {
945 DEBUG ((EFI_D_INFO
, "The buffer [0x%x] to construct ADMA desc is not aligned to 4 bytes boundary!\n", Data
));
948 Entries
= DivU64x32 ((DataLen
+ ADMA_MAX_DATA_PER_LINE
- 1), ADMA_MAX_DATA_PER_LINE
);
950 Trb
->AdmaDescSize
= (UINTN
)MultU64x32 (Entries
, sizeof (EMMC_HC_ADMA_DESC_LINE
));
951 Trb
->AdmaDesc
= EmmcPeimAllocateMem (Trb
->Slot
->Private
->Pool
, Trb
->AdmaDescSize
);
952 if (Trb
->AdmaDesc
== NULL
) {
953 return EFI_OUT_OF_RESOURCES
;
957 Address
= (UINT32
)Data
;
958 for (Index
= 0; Index
< Entries
; Index
++) {
959 if (Remaining
<= ADMA_MAX_DATA_PER_LINE
) {
960 Trb
->AdmaDesc
[Index
].Valid
= 1;
961 Trb
->AdmaDesc
[Index
].Act
= 2;
962 Trb
->AdmaDesc
[Index
].Length
= (UINT16
)Remaining
;
963 Trb
->AdmaDesc
[Index
].Address
= Address
;
966 Trb
->AdmaDesc
[Index
].Valid
= 1;
967 Trb
->AdmaDesc
[Index
].Act
= 2;
968 Trb
->AdmaDesc
[Index
].Length
= 0;
969 Trb
->AdmaDesc
[Index
].Address
= Address
;
972 Remaining
-= ADMA_MAX_DATA_PER_LINE
;
973 Address
+= ADMA_MAX_DATA_PER_LINE
;
977 // Set the last descriptor line as end of descriptor table
979 Trb
->AdmaDesc
[Index
].End
= 1;
984 Create a new TRB for the EMMC cmd request.
986 @param[in] Slot The slot number of the EMMC card to send the command to.
987 @param[in] Packet A pointer to the SD command data structure.
989 @return Created Trb or NULL.
994 IN EMMC_PEIM_HC_SLOT
*Slot
,
995 IN EMMC_COMMAND_PACKET
*Packet
1000 EMMC_HC_SLOT_CAP Capability
;
1003 // Calculate a divisor for SD clock frequency
1005 Status
= EmmcPeimHcGetCapability (Slot
->EmmcHcBase
, &Capability
);
1006 if (EFI_ERROR (Status
)) {
1010 Trb
= EmmcPeimAllocateMem (Slot
->Private
->Pool
, sizeof (EMMC_TRB
));
1016 Trb
->BlockSize
= 0x200;
1017 Trb
->Packet
= Packet
;
1018 Trb
->Timeout
= Packet
->Timeout
;
1020 if ((Packet
->InTransferLength
!= 0) && (Packet
->InDataBuffer
!= NULL
)) {
1021 Trb
->Data
= Packet
->InDataBuffer
;
1022 Trb
->DataLen
= Packet
->InTransferLength
;
1024 } else if ((Packet
->OutTransferLength
!= 0) && (Packet
->OutDataBuffer
!= NULL
)) {
1025 Trb
->Data
= Packet
->OutDataBuffer
;
1026 Trb
->DataLen
= Packet
->OutTransferLength
;
1028 } else if ((Packet
->InTransferLength
== 0) && (Packet
->OutTransferLength
== 0)) {
1035 if (Trb
->DataLen
< Trb
->BlockSize
) {
1036 Trb
->BlockSize
= (UINT16
)Trb
->DataLen
;
1039 if (Packet
->EmmcCmdBlk
->CommandIndex
== EMMC_SEND_TUNING_BLOCK
) {
1040 Trb
->Mode
= EmmcPioMode
;
1042 if (Trb
->DataLen
== 0) {
1043 Trb
->Mode
= EmmcNoData
;
1044 } else if (Capability
.Adma2
!= 0) {
1045 Trb
->Mode
= EmmcAdmaMode
;
1046 Status
= BuildAdmaDescTable (Trb
);
1047 if (EFI_ERROR (Status
)) {
1050 } else if (Capability
.Sdma
!= 0) {
1051 Trb
->Mode
= EmmcSdmaMode
;
1053 Trb
->Mode
= EmmcPioMode
;
1059 EmmcPeimFreeTrb (Trb
);
1064 Free the resource used by the TRB.
1066 @param[in] Trb The pointer to the EMMC_TRB instance.
1074 if ((Trb
!= NULL
) && (Trb
->AdmaDesc
!= NULL
)) {
1075 EmmcPeimFreeMem (Trb
->Slot
->Private
->Pool
, Trb
->AdmaDesc
, Trb
->AdmaDescSize
);
1079 EmmcPeimFreeMem (Trb
->Slot
->Private
->Pool
, Trb
, sizeof (EMMC_TRB
));
1085 Check if the env is ready for execute specified TRB.
1087 @param[in] Bar The mmio base address of the slot to be accessed.
1088 @param[in] Trb The pointer to the EMMC_TRB instance.
1090 @retval EFI_SUCCESS The env is ready for TRB execution.
1091 @retval EFI_NOT_READY The env is not ready for TRB execution.
1092 @retval Others Some erros happen.
1096 EmmcPeimCheckTrbEnv (
1102 EMMC_COMMAND_PACKET
*Packet
;
1103 UINT32 PresentState
;
1105 Packet
= Trb
->Packet
;
1107 if ((Packet
->EmmcCmdBlk
->CommandType
== EmmcCommandTypeAdtc
) ||
1108 (Packet
->EmmcCmdBlk
->ResponseType
== EmmcResponceTypeR1b
) ||
1109 (Packet
->EmmcCmdBlk
->ResponseType
== EmmcResponceTypeR5b
)) {
1111 // Wait Command Inhibit (CMD) and Command Inhibit (DAT) in
1112 // the Present State register to be 0
1114 PresentState
= BIT0
| BIT1
;
1117 // Wait Command Inhibit (CMD) in the Present State register
1120 PresentState
= BIT0
;
1123 Status
= EmmcPeimHcCheckMmioSet (
1124 Bar
+ EMMC_HC_PRESENT_STATE
,
1125 sizeof (PresentState
),
1134 Wait for the env to be ready for execute specified TRB.
1136 @param[in] Bar The mmio base address of the slot to be accessed.
1137 @param[in] Trb The pointer to the EMMC_TRB instance.
1139 @retval EFI_SUCCESS The env is ready for TRB execution.
1140 @retval EFI_TIMEOUT The env is not ready for TRB execution in time.
1141 @retval Others Some erros happen.
1145 EmmcPeimWaitTrbEnv (
1151 EMMC_COMMAND_PACKET
*Packet
;
1153 BOOLEAN InfiniteWait
;
1156 // Wait Command Complete Interrupt Status bit in Normal Interrupt Status Register
1158 Packet
= Trb
->Packet
;
1159 Timeout
= Packet
->Timeout
;
1161 InfiniteWait
= TRUE
;
1163 InfiniteWait
= FALSE
;
1166 while (InfiniteWait
|| (Timeout
> 0)) {
1168 // Check Trb execution result by reading Normal Interrupt Status register.
1170 Status
= EmmcPeimCheckTrbEnv (Bar
, Trb
);
1171 if (Status
!= EFI_NOT_READY
) {
1175 // Stall for 1 microsecond.
1177 MicroSecondDelay (1);
1186 Execute the specified TRB.
1188 @param[in] Bar The mmio base address of the slot to be accessed.
1189 @param[in] Trb The pointer to the EMMC_TRB instance.
1191 @retval EFI_SUCCESS The TRB is sent to host controller successfully.
1192 @retval Others Some erros happen when sending this request to the host controller.
1202 EMMC_COMMAND_PACKET
*Packet
;
1213 Packet
= Trb
->Packet
;
1215 // Clear all bits in Error Interrupt Status Register
1218 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_ERR_INT_STS
, FALSE
, sizeof (IntStatus
), &IntStatus
);
1219 if (EFI_ERROR (Status
)) {
1223 // Clear all bits in Normal Interrupt Status Register
1226 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_NOR_INT_STS
, FALSE
, sizeof (IntStatus
), &IntStatus
);
1227 if (EFI_ERROR (Status
)) {
1231 // Set Host Control 1 register DMA Select field
1233 if (Trb
->Mode
== EmmcAdmaMode
) {
1235 Status
= EmmcPeimHcOrMmio (Bar
+ EMMC_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
1236 if (EFI_ERROR (Status
)) {
1241 EmmcPeimHcLedOnOff (Bar
, TRUE
);
1243 if (Trb
->Mode
== EmmcSdmaMode
) {
1244 if ((UINT64
)(UINTN
)Trb
->Data
>= 0x100000000ul
) {
1245 return EFI_INVALID_PARAMETER
;
1248 SdmaAddr
= (UINT32
)(UINTN
)Trb
->Data
;
1249 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_SDMA_ADDR
, FALSE
, sizeof (SdmaAddr
), &SdmaAddr
);
1250 if (EFI_ERROR (Status
)) {
1253 } else if (Trb
->Mode
== EmmcAdmaMode
) {
1254 AdmaAddr
= (UINT64
)(UINTN
)Trb
->AdmaDesc
;
1255 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_ADMA_SYS_ADDR
, FALSE
, sizeof (AdmaAddr
), &AdmaAddr
);
1256 if (EFI_ERROR (Status
)) {
1261 BlkSize
= Trb
->BlockSize
;
1262 if (Trb
->Mode
== EmmcSdmaMode
) {
1264 // Set SDMA boundary to be 512K bytes.
1269 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_BLK_SIZE
, FALSE
, sizeof (BlkSize
), &BlkSize
);
1270 if (EFI_ERROR (Status
)) {
1275 if (Trb
->Mode
!= EmmcNoData
) {
1277 // Calcuate Block Count.
1279 BlkCount
= (UINT16
)(Trb
->DataLen
/ Trb
->BlockSize
);
1282 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_BLK_COUNT
, FALSE
, sizeof (BlkCount
), &BlkCount
);
1283 if (EFI_ERROR (Status
)) {
1287 Argument
= Packet
->EmmcCmdBlk
->CommandArgument
;
1288 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_ARG1
, FALSE
, sizeof (Argument
), &Argument
);
1289 if (EFI_ERROR (Status
)) {
1294 if (Trb
->Mode
!= EmmcNoData
) {
1295 if (Trb
->Mode
!= EmmcPioMode
) {
1302 TransMode
|= BIT5
| BIT1
;
1306 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_TRANS_MOD
, FALSE
, sizeof (TransMode
), &TransMode
);
1307 if (EFI_ERROR (Status
)) {
1311 Cmd
= (UINT16
)LShiftU64(Packet
->EmmcCmdBlk
->CommandIndex
, 8);
1312 if (Packet
->EmmcCmdBlk
->CommandType
== EmmcCommandTypeAdtc
) {
1316 // Convert ResponseType to value
1318 if (Packet
->EmmcCmdBlk
->CommandType
!= EmmcCommandTypeBc
) {
1319 switch (Packet
->EmmcCmdBlk
->ResponseType
) {
1320 case EmmcResponceTypeR1
:
1321 case EmmcResponceTypeR5
:
1322 case EmmcResponceTypeR6
:
1323 case EmmcResponceTypeR7
:
1324 Cmd
|= (BIT1
| BIT3
| BIT4
);
1326 case EmmcResponceTypeR2
:
1327 Cmd
|= (BIT0
| BIT3
);
1329 case EmmcResponceTypeR3
:
1330 case EmmcResponceTypeR4
:
1333 case EmmcResponceTypeR1b
:
1334 case EmmcResponceTypeR5b
:
1335 Cmd
|= (BIT0
| BIT1
| BIT3
| BIT4
);
1345 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_COMMAND
, FALSE
, sizeof (Cmd
), &Cmd
);
1350 Check the TRB execution result.
1352 @param[in] Bar The mmio base address of the slot to be accessed.
1353 @param[in] Trb The pointer to the EMMC_TRB instance.
1355 @retval EFI_SUCCESS The TRB is executed successfully.
1356 @retval EFI_NOT_READY The TRB is not completed for execution.
1357 @retval Others Some erros happen when executing this request.
1361 EmmcPeimCheckTrbResult (
1367 EMMC_COMMAND_PACKET
*Packet
;
1376 Packet
= Trb
->Packet
;
1378 // Check Trb execution result by reading Normal Interrupt Status register.
1380 Status
= EmmcPeimHcRwMmio (
1381 Bar
+ EMMC_HC_NOR_INT_STS
,
1386 if (EFI_ERROR (Status
)) {
1390 // Check Transfer Complete bit is set or not.
1392 if ((IntStatus
& BIT1
) == BIT1
) {
1393 if ((IntStatus
& BIT15
) == BIT15
) {
1395 // Read Error Interrupt Status register to check if the error is
1396 // Data Timeout Error.
1397 // If yes, treat it as success as Transfer Complete has higher
1398 // priority than Data Timeout Error.
1400 Status
= EmmcPeimHcRwMmio (
1401 Bar
+ EMMC_HC_ERR_INT_STS
,
1406 if (!EFI_ERROR (Status
)) {
1407 if ((IntStatus
& BIT4
) == BIT4
) {
1408 Status
= EFI_SUCCESS
;
1410 Status
= EFI_DEVICE_ERROR
;
1418 // Check if there is a error happened during cmd execution.
1419 // If yes, then do error recovery procedure to follow SD Host Controller
1420 // Simplified Spec 3.0 section 3.10.1.
1422 if ((IntStatus
& BIT15
) == BIT15
) {
1423 Status
= EmmcPeimHcRwMmio (
1424 Bar
+ EMMC_HC_ERR_INT_STS
,
1429 if (EFI_ERROR (Status
)) {
1433 if ((IntStatus
& 0x0F) != 0) {
1436 if ((IntStatus
& 0xF0) != 0) {
1440 Status
= EmmcPeimHcRwMmio (
1441 Bar
+ EMMC_HC_SW_RST
,
1446 if (EFI_ERROR (Status
)) {
1449 Status
= EmmcPeimHcWaitMmioSet (
1450 Bar
+ EMMC_HC_SW_RST
,
1456 if (EFI_ERROR (Status
)) {
1460 Status
= EFI_DEVICE_ERROR
;
1464 // Check if DMA interrupt is signalled for the SDMA transfer.
1466 if ((Trb
->Mode
== EmmcSdmaMode
) && ((IntStatus
& BIT3
) == BIT3
)) {
1468 // Clear DMA interrupt bit.
1471 Status
= EmmcPeimHcRwMmio (
1472 Bar
+ EMMC_HC_NOR_INT_STS
,
1477 if (EFI_ERROR (Status
)) {
1481 // Update SDMA Address register.
1483 SdmaAddr
= EMMC_SDMA_ROUND_UP ((UINT32
)(UINTN
)Trb
->Data
, EMMC_SDMA_BOUNDARY
);
1484 Status
= EmmcPeimHcRwMmio (
1485 Bar
+ EMMC_HC_SDMA_ADDR
,
1490 if (EFI_ERROR (Status
)) {
1493 Trb
->Data
= (VOID
*)(UINTN
)SdmaAddr
;
1496 if ((Packet
->EmmcCmdBlk
->CommandType
!= EmmcCommandTypeAdtc
) &&
1497 (Packet
->EmmcCmdBlk
->ResponseType
!= EmmcResponceTypeR1b
) &&
1498 (Packet
->EmmcCmdBlk
->ResponseType
!= EmmcResponceTypeR5b
)) {
1499 if ((IntStatus
& BIT0
) == BIT0
) {
1500 Status
= EFI_SUCCESS
;
1505 if (Packet
->EmmcCmdBlk
->CommandIndex
== EMMC_SEND_TUNING_BLOCK
) {
1507 // When performing tuning procedure (Execute Tuning is set to 1) through PIO mode,
1508 // wait Buffer Read Ready bit of Normal Interrupt Status Register to be 1.
1509 // Refer to SD Host Controller Simplified Specification 3.0 figure 2-29 for details.
1511 if ((IntStatus
& BIT5
) == BIT5
) {
1513 // Clear Buffer Read Ready interrupt at first.
1516 EmmcPeimHcRwMmio (Bar
+ EMMC_HC_NOR_INT_STS
, FALSE
, sizeof (IntStatus
), &IntStatus
);
1518 // Read data out from Buffer Port register
1520 for (PioLength
= 0; PioLength
< Trb
->DataLen
; PioLength
+= 4) {
1521 EmmcPeimHcRwMmio (Bar
+ EMMC_HC_BUF_DAT_PORT
, TRUE
, 4, (UINT8
*)Trb
->Data
+ PioLength
);
1523 Status
= EFI_SUCCESS
;
1528 Status
= EFI_NOT_READY
;
1531 // Get response data when the cmd is executed successfully.
1533 if (!EFI_ERROR (Status
)) {
1534 if (Packet
->EmmcCmdBlk
->CommandType
!= EmmcCommandTypeBc
) {
1535 for (Index
= 0; Index
< 4; Index
++) {
1536 Status
= EmmcPeimHcRwMmio (
1537 Bar
+ EMMC_HC_RESPONSE
+ Index
* 4,
1542 if (EFI_ERROR (Status
)) {
1543 EmmcPeimHcLedOnOff (Bar
, FALSE
);
1547 CopyMem (Packet
->EmmcStatusBlk
, Response
, sizeof (Response
));
1551 if (Status
!= EFI_NOT_READY
) {
1552 EmmcPeimHcLedOnOff (Bar
, FALSE
);
1559 Wait for the TRB execution result.
1561 @param[in] Bar The mmio base address of the slot to be accessed.
1562 @param[in] Trb The pointer to the EMMC_TRB instance.
1564 @retval EFI_SUCCESS The TRB is executed successfully.
1565 @retval Others Some erros happen when executing this request.
1569 EmmcPeimWaitTrbResult (
1575 EMMC_COMMAND_PACKET
*Packet
;
1577 BOOLEAN InfiniteWait
;
1579 Packet
= Trb
->Packet
;
1581 // Wait Command Complete Interrupt Status bit in Normal Interrupt Status Register
1583 Timeout
= Packet
->Timeout
;
1585 InfiniteWait
= TRUE
;
1587 InfiniteWait
= FALSE
;
1590 while (InfiniteWait
|| (Timeout
> 0)) {
1592 // Check Trb execution result by reading Normal Interrupt Status register.
1594 Status
= EmmcPeimCheckTrbResult (Bar
, Trb
);
1595 if (Status
!= EFI_NOT_READY
) {
1599 // Stall for 1 microsecond.
1601 MicroSecondDelay (1);
1610 Sends EMMC command to an EMMC card that is attached to the EMMC controller.
1612 If Packet is successfully sent to the EMMC card, then EFI_SUCCESS is returned.
1614 If a device error occurs while sending the Packet, then EFI_DEVICE_ERROR is returned.
1616 If Slot is not in a valid range for the EMMC controller, then EFI_INVALID_PARAMETER
1619 If Packet defines a data command but both InDataBuffer and OutDataBuffer are NULL,
1620 EFI_INVALID_PARAMETER is returned.
1622 @param[in] Slot The slot number of the Emmc card to send the command to.
1623 @param[in,out] Packet A pointer to the EMMC command data structure.
1625 @retval EFI_SUCCESS The EMMC Command Packet was sent by the host.
1626 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send the SD
1628 @retval EFI_INVALID_PARAMETER Packet, Slot, or the contents of the Packet is invalid.
1629 @retval EFI_INVALID_PARAMETER Packet defines a data command but both InDataBuffer and
1630 OutDataBuffer are NULL.
1631 @retval EFI_NO_MEDIA SD Device not present in the Slot.
1632 @retval EFI_UNSUPPORTED The command described by the EMMC Command Packet is not
1633 supported by the host controller.
1634 @retval EFI_BAD_BUFFER_SIZE The InTransferLength or OutTransferLength exceeds the
1635 limit supported by EMMC card ( i.e. if the number of bytes
1636 exceed the Last LBA).
1642 IN EMMC_PEIM_HC_SLOT
*Slot
,
1643 IN OUT EMMC_COMMAND_PACKET
*Packet
1649 if (Packet
== NULL
) {
1650 return EFI_INVALID_PARAMETER
;
1653 if ((Packet
->EmmcCmdBlk
== NULL
) || (Packet
->EmmcStatusBlk
== NULL
)) {
1654 return EFI_INVALID_PARAMETER
;
1657 if ((Packet
->OutDataBuffer
== NULL
) && (Packet
->OutTransferLength
!= 0)) {
1658 return EFI_INVALID_PARAMETER
;
1661 if ((Packet
->InDataBuffer
== NULL
) && (Packet
->InTransferLength
!= 0)) {
1662 return EFI_INVALID_PARAMETER
;
1665 Trb
= EmmcPeimCreateTrb (Slot
, Packet
);
1667 return EFI_OUT_OF_RESOURCES
;
1670 Status
= EmmcPeimWaitTrbEnv (Slot
->EmmcHcBase
, Trb
);
1671 if (EFI_ERROR (Status
)) {
1675 Status
= EmmcPeimExecTrb (Slot
->EmmcHcBase
, Trb
);
1676 if (EFI_ERROR (Status
)) {
1680 Status
= EmmcPeimWaitTrbResult (Slot
->EmmcHcBase
, Trb
);
1681 if (EFI_ERROR (Status
)) {
1686 EmmcPeimFreeTrb (Trb
);
1692 Send command GO_IDLE_STATE (CMD0 with argument of 0x00000000) to the device to
1693 make it go to Idle State.
1695 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
1697 @param[in] Slot The slot number of the Emmc card to send the command to.
1699 @retval EFI_SUCCESS The EMMC device is reset correctly.
1700 @retval Others The device reset fails.
1705 IN EMMC_PEIM_HC_SLOT
*Slot
1708 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
1709 EMMC_STATUS_BLOCK EmmcStatusBlk
;
1710 EMMC_COMMAND_PACKET Packet
;
1713 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
1714 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
1715 ZeroMem (&Packet
, sizeof (Packet
));
1717 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
1718 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
1719 Packet
.Timeout
= EMMC_TIMEOUT
;
1721 EmmcCmdBlk
.CommandIndex
= EMMC_GO_IDLE_STATE
;
1722 EmmcCmdBlk
.CommandType
= EmmcCommandTypeBc
;
1723 EmmcCmdBlk
.ResponseType
= 0;
1724 EmmcCmdBlk
.CommandArgument
= 0;
1726 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
1732 Send command SEND_OP_COND to the EMMC device to get the data of the OCR register.
1734 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
1736 @param[in] Slot The slot number of the Emmc card to send the command to.
1737 @param[in, out] Argument On input, the argument of SEND_OP_COND is to send to the device.
1738 On output, the argument is the value of OCR register.
1740 @retval EFI_SUCCESS The operation is done correctly.
1741 @retval Others The operation fails.
1746 IN EMMC_PEIM_HC_SLOT
*Slot
,
1747 IN OUT UINT32
*Argument
1750 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
1751 EMMC_STATUS_BLOCK EmmcStatusBlk
;
1752 EMMC_COMMAND_PACKET Packet
;
1755 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
1756 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
1757 ZeroMem (&Packet
, sizeof (Packet
));
1759 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
1760 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
1761 Packet
.Timeout
= EMMC_TIMEOUT
;
1763 EmmcCmdBlk
.CommandIndex
= EMMC_SEND_OP_COND
;
1764 EmmcCmdBlk
.CommandType
= EmmcCommandTypeBcr
;
1765 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR3
;
1766 EmmcCmdBlk
.CommandArgument
= *Argument
;
1768 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
1769 if (!EFI_ERROR (Status
)) {
1771 // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12.
1773 *Argument
= EmmcStatusBlk
.Resp0
;
1780 Broadcast command ALL_SEND_CID to the bus to ask all the EMMC devices to send the
1781 data of their CID registers.
1783 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
1785 @param[in] Slot The slot number of the Emmc card to send the command to.
1787 @retval EFI_SUCCESS The operation is done correctly.
1788 @retval Others The operation fails.
1793 IN EMMC_PEIM_HC_SLOT
*Slot
1796 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
1797 EMMC_STATUS_BLOCK EmmcStatusBlk
;
1798 EMMC_COMMAND_PACKET Packet
;
1801 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
1802 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
1803 ZeroMem (&Packet
, sizeof (Packet
));
1805 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
1806 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
1807 Packet
.Timeout
= EMMC_TIMEOUT
;
1809 EmmcCmdBlk
.CommandIndex
= EMMC_ALL_SEND_CID
;
1810 EmmcCmdBlk
.CommandType
= EmmcCommandTypeBcr
;
1811 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR2
;
1812 EmmcCmdBlk
.CommandArgument
= 0;
1814 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
1820 Send command SET_RELATIVE_ADDR to the EMMC device to assign a Relative device
1823 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
1825 @param[in] Slot The slot number of the Emmc card to send the command to.
1826 @param[in] Rca The relative device address to be assigned.
1828 @retval EFI_SUCCESS The operation is done correctly.
1829 @retval Others The operation fails.
1834 IN EMMC_PEIM_HC_SLOT
*Slot
,
1838 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
1839 EMMC_STATUS_BLOCK EmmcStatusBlk
;
1840 EMMC_COMMAND_PACKET Packet
;
1843 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
1844 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
1845 ZeroMem (&Packet
, sizeof (Packet
));
1847 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
1848 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
1849 Packet
.Timeout
= EMMC_TIMEOUT
;
1851 EmmcCmdBlk
.CommandIndex
= EMMC_SET_RELATIVE_ADDR
;
1852 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAc
;
1853 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR1
;
1854 EmmcCmdBlk
.CommandArgument
= Rca
<< 16;
1856 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
1862 Send command SEND_CSD to the EMMC device to get the data of the CSD register.
1864 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
1866 @param[in] Slot The slot number of the Emmc card to send the command to.
1867 @param[in] Rca The relative device address of selected device.
1868 @param[out] Csd The buffer to store the content of the CSD register.
1869 Note the caller should ignore the lowest byte of this
1870 buffer as the content of this byte is meaningless even
1871 if the operation succeeds.
1873 @retval EFI_SUCCESS The operation is done correctly.
1874 @retval Others The operation fails.
1879 IN EMMC_PEIM_HC_SLOT
*Slot
,
1884 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
1885 EMMC_STATUS_BLOCK EmmcStatusBlk
;
1886 EMMC_COMMAND_PACKET Packet
;
1889 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
1890 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
1891 ZeroMem (&Packet
, sizeof (Packet
));
1893 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
1894 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
1895 Packet
.Timeout
= EMMC_TIMEOUT
;
1897 EmmcCmdBlk
.CommandIndex
= EMMC_SEND_CSD
;
1898 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAc
;
1899 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR2
;
1900 EmmcCmdBlk
.CommandArgument
= Rca
<< 16;
1902 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
1903 if (!EFI_ERROR (Status
)) {
1905 // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12.
1907 CopyMem (((UINT8
*)Csd
) + 1, &EmmcStatusBlk
.Resp0
, sizeof (EMMC_CSD
) - 1);
1914 Send command SELECT_DESELECT_CARD to the EMMC device to select/deselect it.
1916 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
1918 @param[in] Slot The slot number of the Emmc card to send the command to.
1919 @param[in] Rca The relative device address of selected device.
1921 @retval EFI_SUCCESS The operation is done correctly.
1922 @retval Others The operation fails.
1927 IN EMMC_PEIM_HC_SLOT
*Slot
,
1931 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
1932 EMMC_STATUS_BLOCK EmmcStatusBlk
;
1933 EMMC_COMMAND_PACKET Packet
;
1936 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
1937 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
1938 ZeroMem (&Packet
, sizeof (Packet
));
1940 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
1941 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
1942 Packet
.Timeout
= EMMC_TIMEOUT
;
1944 EmmcCmdBlk
.CommandIndex
= EMMC_SELECT_DESELECT_CARD
;
1945 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAc
;
1946 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR1
;
1947 EmmcCmdBlk
.CommandArgument
= Rca
<< 16;
1949 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
1955 Send command SEND_EXT_CSD to the EMMC device to get the data of the EXT_CSD register.
1957 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
1959 @param[in] Slot The slot number of the Emmc card to send the command to.
1960 @param[out] ExtCsd The buffer to store the content of the EXT_CSD register.
1962 @retval EFI_SUCCESS The operation is done correctly.
1963 @retval Others The operation fails.
1968 IN EMMC_PEIM_HC_SLOT
*Slot
,
1969 OUT EMMC_EXT_CSD
*ExtCsd
1972 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
1973 EMMC_STATUS_BLOCK EmmcStatusBlk
;
1974 EMMC_COMMAND_PACKET Packet
;
1977 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
1978 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
1979 ZeroMem (&Packet
, sizeof (Packet
));
1981 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
1982 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
1983 Packet
.Timeout
= EMMC_TIMEOUT
;
1985 EmmcCmdBlk
.CommandIndex
= EMMC_SEND_EXT_CSD
;
1986 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAdtc
;
1987 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR1
;
1988 EmmcCmdBlk
.CommandArgument
= 0x00000000;
1990 Packet
.InDataBuffer
= ExtCsd
;
1991 Packet
.InTransferLength
= sizeof (EMMC_EXT_CSD
);
1993 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
1998 Send command SWITCH to the EMMC device to switch the mode of operation of the
1999 selected Device or modifies the EXT_CSD registers.
2001 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
2003 @param[in] Slot The slot number of the Emmc card to send the command to.
2004 @param[in] Access The access mode of SWTICH command.
2005 @param[in] Index The offset of the field to be access.
2006 @param[in] Value The value to be set to the specified field of EXT_CSD register.
2007 @param[in] CmdSet The value of CmdSet field of EXT_CSD register.
2009 @retval EFI_SUCCESS The operation is done correctly.
2010 @retval Others The operation fails.
2015 IN EMMC_PEIM_HC_SLOT
*Slot
,
2022 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
2023 EMMC_STATUS_BLOCK EmmcStatusBlk
;
2024 EMMC_COMMAND_PACKET Packet
;
2027 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
2028 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
2029 ZeroMem (&Packet
, sizeof (Packet
));
2031 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
2032 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
2033 Packet
.Timeout
= EMMC_TIMEOUT
;
2035 EmmcCmdBlk
.CommandIndex
= EMMC_SWITCH
;
2036 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAc
;
2037 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR1b
;
2038 EmmcCmdBlk
.CommandArgument
= (Access
<< 24) | (Index
<< 16) | (Value
<< 8) | CmdSet
;
2040 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
2046 Send command SEND_STATUS to the addressed EMMC device to get its status register.
2048 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
2050 @param[in] Slot The slot number of the Emmc card to send the command to.
2051 @param[in] Rca The relative device address of addressed device.
2052 @param[out] DevStatus The returned device status.
2054 @retval EFI_SUCCESS The operation is done correctly.
2055 @retval Others The operation fails.
2059 EmmcPeimSendStatus (
2060 IN EMMC_PEIM_HC_SLOT
*Slot
,
2062 OUT UINT32
*DevStatus
2065 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
2066 EMMC_STATUS_BLOCK EmmcStatusBlk
;
2067 EMMC_COMMAND_PACKET Packet
;
2070 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
2071 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
2072 ZeroMem (&Packet
, sizeof (Packet
));
2074 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
2075 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
2076 Packet
.Timeout
= EMMC_TIMEOUT
;
2078 EmmcCmdBlk
.CommandIndex
= EMMC_SEND_STATUS
;
2079 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAc
;
2080 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR1
;
2081 EmmcCmdBlk
.CommandArgument
= Rca
<< 16;
2083 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
2084 if (!EFI_ERROR (Status
)) {
2085 *DevStatus
= EmmcStatusBlk
.Resp0
;
2092 Send command SET_BLOCK_COUNT to the addressed EMMC device to set the number of
2093 blocks for the following block read/write cmd.
2095 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
2097 @param[in] Slot The slot number of the Emmc card to send the command to.
2098 @param[in] BlockCount The number of the logical block to access.
2100 @retval EFI_SUCCESS The operation is done correctly.
2101 @retval Others The operation fails.
2105 EmmcPeimSetBlkCount (
2106 IN EMMC_PEIM_HC_SLOT
*Slot
,
2107 IN UINT16 BlockCount
2110 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
2111 EMMC_STATUS_BLOCK EmmcStatusBlk
;
2112 EMMC_COMMAND_PACKET Packet
;
2115 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
2116 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
2117 ZeroMem (&Packet
, sizeof (Packet
));
2119 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
2120 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
2121 Packet
.Timeout
= EMMC_TIMEOUT
;
2123 EmmcCmdBlk
.CommandIndex
= EMMC_SET_BLOCK_COUNT
;
2124 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAc
;
2125 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR1
;
2126 EmmcCmdBlk
.CommandArgument
= BlockCount
;
2128 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
2134 Send command READ_MULTIPLE_BLOCK/WRITE_MULTIPLE_BLOCK to the addressed EMMC device
2135 to read/write the specified number of blocks.
2137 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
2139 @param[in] Slot The slot number of the Emmc card to send the command to.
2140 @param[in] Lba The logical block address of starting access.
2141 @param[in] BlockSize The block size of specified EMMC device partition.
2142 @param[in] Buffer The pointer to the transfer buffer.
2143 @param[in] BufferSize The size of transfer buffer.
2144 @param[in] IsRead Boolean to show the operation direction.
2146 @retval EFI_SUCCESS The operation is done correctly.
2147 @retval Others The operation fails.
2151 EmmcPeimRwMultiBlocks (
2152 IN EMMC_PEIM_HC_SLOT
*Slot
,
2154 IN UINT32 BlockSize
,
2156 IN UINTN BufferSize
,
2160 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
2161 EMMC_STATUS_BLOCK EmmcStatusBlk
;
2162 EMMC_COMMAND_PACKET Packet
;
2165 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
2166 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
2167 ZeroMem (&Packet
, sizeof (Packet
));
2169 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
2170 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
2172 // Calculate timeout value through the below formula.
2173 // Timeout = (transfer size) / (2MB/s).
2174 // Taking 2MB/s as divisor is because it's nearest to the eMMC lowest
2175 // transfer speed (2.4MB/s).
2176 // Refer to eMMC 5.0 spec section 6.9.1 for details.
2178 Packet
.Timeout
= (BufferSize
/ (2 * 1024 * 1024) + 1) * 1000 * 1000;;
2181 Packet
.InDataBuffer
= Buffer
;
2182 Packet
.InTransferLength
= (UINT32
)BufferSize
;
2184 EmmcCmdBlk
.CommandIndex
= EMMC_READ_MULTIPLE_BLOCK
;
2185 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAdtc
;
2186 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR1
;
2188 Packet
.OutDataBuffer
= Buffer
;
2189 Packet
.OutTransferLength
= (UINT32
)BufferSize
;
2191 EmmcCmdBlk
.CommandIndex
= EMMC_WRITE_MULTIPLE_BLOCK
;
2192 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAdtc
;
2193 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR1
;
2196 if (Slot
->SectorAddressing
) {
2197 EmmcCmdBlk
.CommandArgument
= (UINT32
)Lba
;
2199 EmmcCmdBlk
.CommandArgument
= (UINT32
)MultU64x32 (Lba
, BlockSize
);
2202 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
2208 Send command SEND_TUNING_BLOCK to the EMMC device for HS200 optimal sampling point
2211 It may be sent up to 40 times until the host finishes the tuning procedure.
2213 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 for details.
2215 @param[in] Slot The slot number of the Emmc card to send the command to.
2216 @param[in] BusWidth The bus width to work.
2218 @retval EFI_SUCCESS The operation is done correctly.
2219 @retval Others The operation fails.
2223 EmmcPeimSendTuningBlk (
2224 IN EMMC_PEIM_HC_SLOT
*Slot
,
2228 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
2229 EMMC_STATUS_BLOCK EmmcStatusBlk
;
2230 EMMC_COMMAND_PACKET Packet
;
2232 UINT8 TuningBlock
[128];
2234 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
2235 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
2236 ZeroMem (&Packet
, sizeof (Packet
));
2238 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
2239 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
2240 Packet
.Timeout
= EMMC_TIMEOUT
;
2242 EmmcCmdBlk
.CommandIndex
= EMMC_SEND_TUNING_BLOCK
;
2243 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAdtc
;
2244 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR1
;
2245 EmmcCmdBlk
.CommandArgument
= 0;
2247 Packet
.InDataBuffer
= TuningBlock
;
2248 if (BusWidth
== 8) {
2249 Packet
.InTransferLength
= sizeof (TuningBlock
);
2251 Packet
.InTransferLength
= 64;
2254 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
2260 Tunning the clock to get HS200 optimal sampling point.
2262 Command SEND_TUNING_BLOCK may be sent up to 40 times until the host finishes the
2265 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
2266 Simplified Spec 3.0 section Figure 2-29 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 EmmcPeimTuningClkForHs200 (
2277 IN EMMC_PEIM_HC_SLOT
*Slot
,
2286 // Notify the host that the sampling clock tuning procedure starts.
2289 Status
= EmmcPeimHcOrMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2290 if (EFI_ERROR (Status
)) {
2294 // Ask the device to send a sequence of tuning blocks till the tuning procedure is done.
2298 Status
= EmmcPeimSendTuningBlk (Slot
, BusWidth
);
2299 if (EFI_ERROR (Status
)) {
2303 Status
= EmmcPeimHcRwMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL2
, TRUE
, sizeof (HostCtrl2
), &HostCtrl2
);
2304 if (EFI_ERROR (Status
)) {
2308 if ((HostCtrl2
& (BIT6
| BIT7
)) == 0) {
2312 if ((HostCtrl2
& (BIT6
| BIT7
)) == BIT7
) {
2315 } while (++Retry
< 40);
2317 DEBUG ((EFI_D_ERROR
, "EmmcPeimTuningClkForHs200: Send tuning block fails at %d times with HostCtrl2 %02x\n", Retry
, HostCtrl2
));
2319 // Abort the tuning procedure and reset the tuning circuit.
2321 HostCtrl2
= (UINT8
)~(BIT6
| BIT7
);
2322 Status
= EmmcPeimHcAndMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2323 if (EFI_ERROR (Status
)) {
2326 return EFI_DEVICE_ERROR
;
2330 Switch the bus width to specified width.
2332 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.9 and SD Host Controller
2333 Simplified Spec 3.0 section Figure 3-7 for details.
2335 @param[in] Slot The slot number of the Emmc card to send the command to.
2336 @param[in] Rca The relative device address to be assigned.
2337 @param[in] IsDdr If TRUE, use dual data rate data simpling method. Otherwise
2338 use single data rate data simpling method.
2339 @param[in] BusWidth The bus width to be set, it could be 4 or 8.
2341 @retval EFI_SUCCESS The operation is done correctly.
2342 @retval Others The operation fails.
2346 EmmcPeimSwitchBusWidth (
2347 IN EMMC_PEIM_HC_SLOT
*Slot
,
2361 // Write Byte, the Value field is written into the byte pointed by Index.
2364 Index
= OFFSET_OF (EMMC_EXT_CSD
, BusWidth
);
2365 if (BusWidth
== 4) {
2367 } else if (BusWidth
== 8) {
2370 return EFI_INVALID_PARAMETER
;
2378 Status
= EmmcPeimSwitch (Slot
, Access
, Index
, Value
, CmdSet
);
2379 if (EFI_ERROR (Status
)) {
2383 Status
= EmmcPeimSendStatus (Slot
, Rca
, &DevStatus
);
2384 if (EFI_ERROR (Status
)) {
2388 // Check the switch operation is really successful or not.
2390 if ((DevStatus
& BIT7
) != 0) {
2391 return EFI_DEVICE_ERROR
;
2394 Status
= EmmcPeimHcSetBusWidth (Slot
->EmmcHcBase
, BusWidth
);
2400 Switch the clock frequency to the specified value.
2402 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6 and SD Host Controller
2403 Simplified Spec 3.0 section Figure 3-3 for details.
2405 @param[in] Slot The slot number of the Emmc card to send the command to.
2406 @param[in] Rca The relative device address to be assigned.
2407 @param[in] HsTiming The value to be written to HS_TIMING field of EXT_CSD register.
2408 @param[in] ClockFreq The max clock frequency to be set, the unit is MHz.
2410 @retval EFI_SUCCESS The operation is done correctly.
2411 @retval Others The operation fails.
2415 EmmcPeimSwitchClockFreq (
2416 IN EMMC_PEIM_HC_SLOT
*Slot
,
2430 // Write Byte, the Value field is written into the byte pointed by Index.
2433 Index
= OFFSET_OF (EMMC_EXT_CSD
, HsTiming
);
2437 Status
= EmmcPeimSwitch (Slot
, Access
, Index
, Value
, CmdSet
);
2438 if (EFI_ERROR (Status
)) {
2442 Status
= EmmcPeimSendStatus (Slot
, Rca
, &DevStatus
);
2443 if (EFI_ERROR (Status
)) {
2447 // Check the switch operation is really successful or not.
2449 if ((DevStatus
& BIT7
) != 0) {
2450 return EFI_DEVICE_ERROR
;
2453 // Convert the clock freq unit from MHz to KHz.
2455 Status
= EmmcPeimHcClockSupply (Slot
->EmmcHcBase
, ClockFreq
* 1000);
2461 Switch to the High Speed timing according to request.
2463 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
2464 Simplified Spec 3.0 section Figure 2-29 for details.
2466 @param[in] Slot The slot number of the Emmc card to send the command to.
2467 @param[in] Rca The relative device address to be assigned.
2468 @param[in] ClockFreq The max clock frequency to be set.
2469 @param[in] IsDdr If TRUE, use dual data rate data simpling method. Otherwise
2470 use single data rate data simpling method.
2471 @param[in] BusWidth The bus width to be set, it could be 4 or 8.
2473 @retval EFI_SUCCESS The operation is done correctly.
2474 @retval Others The operation fails.
2478 EmmcPeimSwitchToHighSpeed (
2479 IN EMMC_PEIM_HC_SLOT
*Slot
,
2481 IN UINT32 ClockFreq
,
2491 Status
= EmmcPeimSwitchBusWidth (Slot
, Rca
, IsDdr
, BusWidth
);
2492 if (EFI_ERROR (Status
)) {
2496 // Set to Hight Speed timing
2499 Status
= EmmcPeimHcOrMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
2500 if (EFI_ERROR (Status
)) {
2504 HostCtrl2
= (UINT8
)~0x7;
2505 Status
= EmmcPeimHcAndMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2506 if (EFI_ERROR (Status
)) {
2511 } else if (ClockFreq
== 52) {
2516 Status
= EmmcPeimHcOrMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2517 if (EFI_ERROR (Status
)) {
2522 Status
= EmmcPeimSwitchClockFreq (Slot
, Rca
, HsTiming
, ClockFreq
);
2523 if (EFI_ERROR (Status
)) {
2531 Switch to the HS200 timing according to request.
2533 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
2534 Simplified Spec 3.0 section Figure 2-29 for details.
2536 @param[in] Slot The slot number of the Emmc card to send the command to.
2537 @param[in] Rca The relative device address to be assigned.
2538 @param[in] ClockFreq The max clock frequency to be set.
2539 @param[in] BusWidth The bus width to be set, it could be 4 or 8.
2541 @retval EFI_SUCCESS The operation is done correctly.
2542 @retval Others The operation fails.
2546 EmmcPeimSwitchToHS200 (
2547 IN EMMC_PEIM_HC_SLOT
*Slot
,
2549 IN UINT32 ClockFreq
,
2558 if ((BusWidth
!= 4) && (BusWidth
!= 8)) {
2559 return EFI_INVALID_PARAMETER
;
2562 Status
= EmmcPeimSwitchBusWidth (Slot
, Rca
, FALSE
, BusWidth
);
2563 if (EFI_ERROR (Status
)) {
2567 // Set to HS200/SDR104 timing
2570 // Stop bus clock at first
2572 Status
= EmmcPeimHcStopClock (Slot
->EmmcHcBase
);
2573 if (EFI_ERROR (Status
)) {
2577 HostCtrl2
= (UINT8
)~0x7;
2578 Status
= EmmcPeimHcAndMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2579 if (EFI_ERROR (Status
)) {
2582 HostCtrl2
= BIT0
| BIT1
;
2583 Status
= EmmcPeimHcOrMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2584 if (EFI_ERROR (Status
)) {
2589 // Wait Internal Clock Stable in the Clock Control register to be 1 before set SD Clock Enable bit
2591 Status
= EmmcPeimHcWaitMmioSet (
2592 Slot
->EmmcHcBase
+ EMMC_HC_CLOCK_CTRL
,
2598 if (EFI_ERROR (Status
)) {
2602 // Set SD Clock Enable in the Clock Control register to 1
2605 Status
= EmmcPeimHcOrMmio (Slot
->EmmcHcBase
+ EMMC_HC_CLOCK_CTRL
, sizeof (ClockCtrl
), &ClockCtrl
);
2608 Status
= EmmcPeimSwitchClockFreq (Slot
, Rca
, HsTiming
, ClockFreq
);
2609 if (EFI_ERROR (Status
)) {
2613 Status
= EmmcPeimTuningClkForHs200 (Slot
, BusWidth
);
2619 Switch to the HS400 timing according to request.
2621 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
2622 Simplified Spec 3.0 section Figure 2-29 for details.
2624 @param[in] Slot The slot number of the Emmc card to send the command to.
2625 @param[in] Rca The relative device address to be assigned.
2626 @param[in] ClockFreq The max clock frequency to be set.
2628 @retval EFI_SUCCESS The operation is done correctly.
2629 @retval Others The operation fails.
2633 EmmcPeimSwitchToHS400 (
2634 IN EMMC_PEIM_HC_SLOT
*Slot
,
2643 Status
= EmmcPeimSwitchToHS200 (Slot
, Rca
, ClockFreq
, 8);
2644 if (EFI_ERROR (Status
)) {
2648 // Set to Hight Speed timing and set the clock frequency to a value less than 52MHz.
2651 Status
= EmmcPeimSwitchClockFreq (Slot
, Rca
, HsTiming
, 52);
2652 if (EFI_ERROR (Status
)) {
2656 // HS400 mode must use 8 data lines.
2658 Status
= EmmcPeimSwitchBusWidth (Slot
, Rca
, TRUE
, 8);
2659 if (EFI_ERROR (Status
)) {
2663 // Set to HS400 timing
2665 HostCtrl2
= (UINT8
)~0x7;
2666 Status
= EmmcPeimHcAndMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2667 if (EFI_ERROR (Status
)) {
2670 HostCtrl2
= BIT0
| BIT2
;
2671 Status
= EmmcPeimHcOrMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2672 if (EFI_ERROR (Status
)) {
2677 Status
= EmmcPeimSwitchClockFreq (Slot
, Rca
, HsTiming
, ClockFreq
);
2683 Switch the high speed timing according to request.
2685 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
2686 Simplified Spec 3.0 section Figure 2-29 for details.
2688 @param[in] Slot The slot number of the Emmc card to send the command to.
2689 @param[in] Rca The relative device address to be assigned.
2691 @retval EFI_SUCCESS The operation is done correctly.
2692 @retval Others The operation fails.
2696 EmmcPeimSetBusMode (
2697 IN EMMC_PEIM_HC_SLOT
*Slot
,
2702 EMMC_HC_SLOT_CAP Capability
;
2708 Status
= EmmcPeimGetCsd (Slot
, Rca
, &Slot
->Csd
);
2709 if (EFI_ERROR (Status
)) {
2710 DEBUG ((EFI_D_ERROR
, "EmmcPeimSetBusMode: EmmcPeimGetCsd fails with %r\n", Status
));
2714 if ((Slot
->Csd
.CSizeLow
| Slot
->Csd
.CSizeHigh
<< 2) == 0xFFF) {
2715 Slot
->SectorAddressing
= TRUE
;
2717 Slot
->SectorAddressing
= FALSE
;
2720 Status
= EmmcPeimSelect (Slot
, Rca
);
2721 if (EFI_ERROR (Status
)) {
2722 DEBUG ((EFI_D_ERROR
, "EmmcPeimSetBusMode: EmmcPeimSelect fails with %r\n", Status
));
2726 Status
= EmmcPeimHcGetCapability (Slot
->EmmcHcBase
, &Capability
);
2727 if (EFI_ERROR (Status
)) {
2728 DEBUG ((EFI_D_ERROR
, "EmmcPeimSetBusMode: EmmcPeimHcGetCapability fails with %r\n", Status
));
2732 ASSERT (Capability
.BaseClkFreq
!= 0);
2734 // Check if the Host Controller support 8bits bus width.
2736 if (Capability
.BusWidth8
!= 0) {
2742 // Get Deivce_Type from EXT_CSD register.
2744 Status
= EmmcPeimGetExtCsd (Slot
, &Slot
->ExtCsd
);
2745 if (EFI_ERROR (Status
)) {
2746 DEBUG ((EFI_D_ERROR
, "EmmcPeimSetBusMode: EmmcPeimGetExtCsd fails with %r\n", Status
));
2750 // Calculate supported bus speed/bus width/clock frequency.
2755 if (((Slot
->ExtCsd
.DeviceType
& (BIT4
| BIT5
)) != 0) && (Capability
.Sdr104
!= 0)) {
2759 } else if (((Slot
->ExtCsd
.DeviceType
& (BIT2
| BIT3
)) != 0) && (Capability
.Ddr50
!= 0)) {
2763 } else if (((Slot
->ExtCsd
.DeviceType
& BIT1
) != 0) && (Capability
.HighSpeed
!= 0)) {
2767 } else if (((Slot
->ExtCsd
.DeviceType
& BIT0
) != 0) && (Capability
.HighSpeed
!= 0)) {
2773 // Check if both of the device and the host controller support HS400 DDR mode.
2775 if (((Slot
->ExtCsd
.DeviceType
& (BIT6
| BIT7
)) != 0) && (Capability
.Hs400
!= 0)) {
2777 // The host controller supports 8bits bus.
2779 ASSERT (BusWidth
== 8);
2785 if ((ClockFreq
== 0) || (HsTiming
== 0)) {
2787 // Continue using default setting.
2792 DEBUG ((EFI_D_INFO
, "HsTiming %d ClockFreq %d BusWidth %d Ddr %a\n", HsTiming
, ClockFreq
, BusWidth
, IsDdr
? "TRUE":"FALSE"));
2794 if (HsTiming
== 3) {
2796 // Execute HS400 timing switch procedure
2798 Status
= EmmcPeimSwitchToHS400 (Slot
, Rca
, ClockFreq
);
2799 } else if (HsTiming
== 2) {
2801 // Execute HS200 timing switch procedure
2803 Status
= EmmcPeimSwitchToHS200 (Slot
, Rca
, ClockFreq
, BusWidth
);
2806 // Execute High Speed timing switch procedure
2808 Status
= EmmcPeimSwitchToHighSpeed (Slot
, Rca
, ClockFreq
, BusWidth
, IsDdr
);
2815 Execute EMMC device identification procedure.
2817 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
2819 @param[in] Slot The slot number of the Emmc card to send the command to.
2821 @retval EFI_SUCCESS There is a EMMC card.
2822 @retval Others There is not a EMMC card.
2826 EmmcPeimIdentification (
2827 IN EMMC_PEIM_HC_SLOT
*Slot
2834 Status
= EmmcPeimReset (Slot
);
2835 if (EFI_ERROR (Status
)) {
2836 DEBUG ((EFI_D_ERROR
, "EmmcPeimIdentification: EmmcPeimReset fails with %r\n", Status
));
2842 Status
= EmmcPeimGetOcr (Slot
, &Ocr
);
2843 if (EFI_ERROR (Status
)) {
2844 DEBUG ((EFI_D_ERROR
, "EmmcPeimIdentification: EmmcPeimGetOcr fails with %r\n", Status
));
2847 } while ((Ocr
& BIT31
) == 0);
2849 Status
= EmmcPeimGetAllCid (Slot
);
2850 if (EFI_ERROR (Status
)) {
2851 DEBUG ((EFI_D_ERROR
, "EmmcPeimIdentification: EmmcPeimGetAllCid fails with %r\n", Status
));
2855 // Don't support multiple devices on the slot, that is
2856 // shared bus slot feature.
2859 Status
= EmmcPeimSetRca (Slot
, Rca
);
2860 if (EFI_ERROR (Status
)) {
2861 DEBUG ((EFI_D_ERROR
, "EmmcPeimIdentification: EmmcPeimSetRca fails with %r\n", Status
));
2865 // Enter Data Tranfer Mode.
2867 DEBUG ((EFI_D_INFO
, "Found a EMMC device at slot [%d], RCA [%d]\n", Slot
, Rca
));
2869 Status
= EmmcPeimSetBusMode (Slot
, Rca
);