3 Copyright (c) 2015 - 2017, 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
;
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
;
1001 EDKII_IOMMU_OPERATION MapOp
;
1005 // Calculate a divisor for SD clock frequency
1007 Status
= EmmcPeimHcGetCapability (Slot
->EmmcHcBase
, &Capability
);
1008 if (EFI_ERROR (Status
)) {
1012 Trb
= AllocateZeroPool (sizeof (EMMC_TRB
));
1018 Trb
->BlockSize
= 0x200;
1019 Trb
->Packet
= Packet
;
1020 Trb
->Timeout
= Packet
->Timeout
;
1022 if ((Packet
->InTransferLength
!= 0) && (Packet
->InDataBuffer
!= NULL
)) {
1023 Trb
->Data
= Packet
->InDataBuffer
;
1024 Trb
->DataLen
= Packet
->InTransferLength
;
1026 } else if ((Packet
->OutTransferLength
!= 0) && (Packet
->OutDataBuffer
!= NULL
)) {
1027 Trb
->Data
= Packet
->OutDataBuffer
;
1028 Trb
->DataLen
= Packet
->OutTransferLength
;
1030 } else if ((Packet
->InTransferLength
== 0) && (Packet
->OutTransferLength
== 0)) {
1037 if ((Trb
->DataLen
!= 0) && (Trb
->DataLen
< Trb
->BlockSize
)) {
1038 Trb
->BlockSize
= (UINT16
)Trb
->DataLen
;
1041 if (Packet
->EmmcCmdBlk
->CommandIndex
== EMMC_SEND_TUNING_BLOCK
) {
1042 Trb
->Mode
= EmmcPioMode
;
1045 MapOp
= EdkiiIoMmuOperationBusMasterWrite
;
1047 MapOp
= EdkiiIoMmuOperationBusMasterRead
;
1050 if (Trb
->DataLen
!= 0) {
1051 MapLength
= Trb
->DataLen
;
1052 Status
= IoMmuMap (MapOp
, Trb
->Data
, &MapLength
, &Trb
->DataPhy
, &Trb
->DataMap
);
1054 if (EFI_ERROR (Status
) || (MapLength
!= Trb
->DataLen
)) {
1055 DEBUG ((DEBUG_ERROR
, "EmmcPeimCreateTrb: Fail to map data buffer.\n"));
1060 if (Trb
->DataLen
== 0) {
1061 Trb
->Mode
= EmmcNoData
;
1062 } else if (Capability
.Adma2
!= 0) {
1063 Trb
->Mode
= EmmcAdmaMode
;
1064 Status
= BuildAdmaDescTable (Trb
);
1065 if (EFI_ERROR (Status
)) {
1068 } else if (Capability
.Sdma
!= 0) {
1069 Trb
->Mode
= EmmcSdmaMode
;
1071 Trb
->Mode
= EmmcPioMode
;
1077 EmmcPeimFreeTrb (Trb
);
1082 Free the resource used by the TRB.
1084 @param[in] Trb The pointer to the EMMC_TRB instance.
1092 if ((Trb
!= NULL
) && (Trb
->DataMap
!= NULL
)) {
1093 IoMmuUnmap (Trb
->DataMap
);
1096 if ((Trb
!= NULL
) && (Trb
->AdmaDesc
!= NULL
)) {
1097 EmmcPeimFreeMem (Trb
->Slot
->Private
->Pool
, Trb
->AdmaDesc
, Trb
->AdmaDescSize
);
1107 Check if the env is ready for execute specified TRB.
1109 @param[in] Bar The mmio base address of the slot to be accessed.
1110 @param[in] Trb The pointer to the EMMC_TRB instance.
1112 @retval EFI_SUCCESS The env is ready for TRB execution.
1113 @retval EFI_NOT_READY The env is not ready for TRB execution.
1114 @retval Others Some erros happen.
1118 EmmcPeimCheckTrbEnv (
1124 EMMC_COMMAND_PACKET
*Packet
;
1125 UINT32 PresentState
;
1127 Packet
= Trb
->Packet
;
1129 if ((Packet
->EmmcCmdBlk
->CommandType
== EmmcCommandTypeAdtc
) ||
1130 (Packet
->EmmcCmdBlk
->ResponseType
== EmmcResponceTypeR1b
) ||
1131 (Packet
->EmmcCmdBlk
->ResponseType
== EmmcResponceTypeR5b
)) {
1133 // Wait Command Inhibit (CMD) and Command Inhibit (DAT) in
1134 // the Present State register to be 0
1136 PresentState
= BIT0
| BIT1
;
1139 // Wait Command Inhibit (CMD) in the Present State register
1142 PresentState
= BIT0
;
1145 Status
= EmmcPeimHcCheckMmioSet (
1146 Bar
+ EMMC_HC_PRESENT_STATE
,
1147 sizeof (PresentState
),
1156 Wait for the env to be ready for execute specified TRB.
1158 @param[in] Bar The mmio base address of the slot to be accessed.
1159 @param[in] Trb The pointer to the EMMC_TRB instance.
1161 @retval EFI_SUCCESS The env is ready for TRB execution.
1162 @retval EFI_TIMEOUT The env is not ready for TRB execution in time.
1163 @retval Others Some erros happen.
1167 EmmcPeimWaitTrbEnv (
1173 EMMC_COMMAND_PACKET
*Packet
;
1175 BOOLEAN InfiniteWait
;
1178 // Wait Command Complete Interrupt Status bit in Normal Interrupt Status Register
1180 Packet
= Trb
->Packet
;
1181 Timeout
= Packet
->Timeout
;
1183 InfiniteWait
= TRUE
;
1185 InfiniteWait
= FALSE
;
1188 while (InfiniteWait
|| (Timeout
> 0)) {
1190 // Check Trb execution result by reading Normal Interrupt Status register.
1192 Status
= EmmcPeimCheckTrbEnv (Bar
, Trb
);
1193 if (Status
!= EFI_NOT_READY
) {
1197 // Stall for 1 microsecond.
1199 MicroSecondDelay (1);
1208 Execute the specified TRB.
1210 @param[in] Bar The mmio base address of the slot to be accessed.
1211 @param[in] Trb The pointer to the EMMC_TRB instance.
1213 @retval EFI_SUCCESS The TRB is sent to host controller successfully.
1214 @retval Others Some erros happen when sending this request to the host controller.
1224 EMMC_COMMAND_PACKET
*Packet
;
1235 Packet
= Trb
->Packet
;
1237 // Clear all bits in Error Interrupt Status Register
1240 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_ERR_INT_STS
, FALSE
, sizeof (IntStatus
), &IntStatus
);
1241 if (EFI_ERROR (Status
)) {
1245 // Clear all bits in Normal Interrupt Status Register
1248 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_NOR_INT_STS
, FALSE
, sizeof (IntStatus
), &IntStatus
);
1249 if (EFI_ERROR (Status
)) {
1253 // Set Host Control 1 register DMA Select field
1255 if (Trb
->Mode
== EmmcAdmaMode
) {
1257 Status
= EmmcPeimHcOrMmio (Bar
+ EMMC_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
1258 if (EFI_ERROR (Status
)) {
1263 EmmcPeimHcLedOnOff (Bar
, TRUE
);
1265 if (Trb
->Mode
== EmmcSdmaMode
) {
1266 if ((UINT64
)(UINTN
)Trb
->DataPhy
>= 0x100000000ul
) {
1267 return EFI_INVALID_PARAMETER
;
1270 SdmaAddr
= (UINT32
)(UINTN
)Trb
->DataPhy
;
1271 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_SDMA_ADDR
, FALSE
, sizeof (SdmaAddr
), &SdmaAddr
);
1272 if (EFI_ERROR (Status
)) {
1275 } else if (Trb
->Mode
== EmmcAdmaMode
) {
1276 AdmaAddr
= (UINT64
)(UINTN
)Trb
->AdmaDesc
;
1277 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_ADMA_SYS_ADDR
, FALSE
, sizeof (AdmaAddr
), &AdmaAddr
);
1278 if (EFI_ERROR (Status
)) {
1283 BlkSize
= Trb
->BlockSize
;
1284 if (Trb
->Mode
== EmmcSdmaMode
) {
1286 // Set SDMA boundary to be 512K bytes.
1291 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_BLK_SIZE
, FALSE
, sizeof (BlkSize
), &BlkSize
);
1292 if (EFI_ERROR (Status
)) {
1297 if (Trb
->Mode
!= EmmcNoData
) {
1299 // Calcuate Block Count.
1301 BlkCount
= (UINT16
)(Trb
->DataLen
/ Trb
->BlockSize
);
1304 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_BLK_COUNT
, FALSE
, sizeof (BlkCount
), &BlkCount
);
1305 if (EFI_ERROR (Status
)) {
1309 Argument
= Packet
->EmmcCmdBlk
->CommandArgument
;
1310 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_ARG1
, FALSE
, sizeof (Argument
), &Argument
);
1311 if (EFI_ERROR (Status
)) {
1316 if (Trb
->Mode
!= EmmcNoData
) {
1317 if (Trb
->Mode
!= EmmcPioMode
) {
1324 TransMode
|= BIT5
| BIT1
;
1328 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_TRANS_MOD
, FALSE
, sizeof (TransMode
), &TransMode
);
1329 if (EFI_ERROR (Status
)) {
1333 Cmd
= (UINT16
)LShiftU64(Packet
->EmmcCmdBlk
->CommandIndex
, 8);
1334 if (Packet
->EmmcCmdBlk
->CommandType
== EmmcCommandTypeAdtc
) {
1338 // Convert ResponseType to value
1340 if (Packet
->EmmcCmdBlk
->CommandType
!= EmmcCommandTypeBc
) {
1341 switch (Packet
->EmmcCmdBlk
->ResponseType
) {
1342 case EmmcResponceTypeR1
:
1343 case EmmcResponceTypeR5
:
1344 case EmmcResponceTypeR6
:
1345 case EmmcResponceTypeR7
:
1346 Cmd
|= (BIT1
| BIT3
| BIT4
);
1348 case EmmcResponceTypeR2
:
1349 Cmd
|= (BIT0
| BIT3
);
1351 case EmmcResponceTypeR3
:
1352 case EmmcResponceTypeR4
:
1355 case EmmcResponceTypeR1b
:
1356 case EmmcResponceTypeR5b
:
1357 Cmd
|= (BIT0
| BIT1
| BIT3
| BIT4
);
1367 Status
= EmmcPeimHcRwMmio (Bar
+ EMMC_HC_COMMAND
, FALSE
, sizeof (Cmd
), &Cmd
);
1372 Check the TRB execution result.
1374 @param[in] Bar The mmio base address of the slot to be accessed.
1375 @param[in] Trb The pointer to the EMMC_TRB instance.
1377 @retval EFI_SUCCESS The TRB is executed successfully.
1378 @retval EFI_NOT_READY The TRB is not completed for execution.
1379 @retval Others Some erros happen when executing this request.
1383 EmmcPeimCheckTrbResult (
1389 EMMC_COMMAND_PACKET
*Packet
;
1398 Packet
= Trb
->Packet
;
1400 // Check Trb execution result by reading Normal Interrupt Status register.
1402 Status
= EmmcPeimHcRwMmio (
1403 Bar
+ EMMC_HC_NOR_INT_STS
,
1408 if (EFI_ERROR (Status
)) {
1412 // Check Transfer Complete bit is set or not.
1414 if ((IntStatus
& BIT1
) == BIT1
) {
1415 if ((IntStatus
& BIT15
) == BIT15
) {
1417 // Read Error Interrupt Status register to check if the error is
1418 // Data Timeout Error.
1419 // If yes, treat it as success as Transfer Complete has higher
1420 // priority than Data Timeout Error.
1422 Status
= EmmcPeimHcRwMmio (
1423 Bar
+ EMMC_HC_ERR_INT_STS
,
1428 if (!EFI_ERROR (Status
)) {
1429 if ((IntStatus
& BIT4
) == BIT4
) {
1430 Status
= EFI_SUCCESS
;
1432 Status
= EFI_DEVICE_ERROR
;
1440 // Check if there is a error happened during cmd execution.
1441 // If yes, then do error recovery procedure to follow SD Host Controller
1442 // Simplified Spec 3.0 section 3.10.1.
1444 if ((IntStatus
& BIT15
) == BIT15
) {
1445 Status
= EmmcPeimHcRwMmio (
1446 Bar
+ EMMC_HC_ERR_INT_STS
,
1451 if (EFI_ERROR (Status
)) {
1455 if ((IntStatus
& 0x0F) != 0) {
1458 if ((IntStatus
& 0xF0) != 0) {
1462 Status
= EmmcPeimHcRwMmio (
1463 Bar
+ EMMC_HC_SW_RST
,
1468 if (EFI_ERROR (Status
)) {
1471 Status
= EmmcPeimHcWaitMmioSet (
1472 Bar
+ EMMC_HC_SW_RST
,
1478 if (EFI_ERROR (Status
)) {
1482 Status
= EFI_DEVICE_ERROR
;
1486 // Check if DMA interrupt is signalled for the SDMA transfer.
1488 if ((Trb
->Mode
== EmmcSdmaMode
) && ((IntStatus
& BIT3
) == BIT3
)) {
1490 // Clear DMA interrupt bit.
1493 Status
= EmmcPeimHcRwMmio (
1494 Bar
+ EMMC_HC_NOR_INT_STS
,
1499 if (EFI_ERROR (Status
)) {
1503 // Update SDMA Address register.
1505 SdmaAddr
= EMMC_SDMA_ROUND_UP ((UINT32
)(UINTN
)Trb
->DataPhy
, EMMC_SDMA_BOUNDARY
);
1506 Status
= EmmcPeimHcRwMmio (
1507 Bar
+ EMMC_HC_SDMA_ADDR
,
1512 if (EFI_ERROR (Status
)) {
1515 Trb
->DataPhy
= (UINT32
)(UINTN
)SdmaAddr
;
1518 if ((Packet
->EmmcCmdBlk
->CommandType
!= EmmcCommandTypeAdtc
) &&
1519 (Packet
->EmmcCmdBlk
->ResponseType
!= EmmcResponceTypeR1b
) &&
1520 (Packet
->EmmcCmdBlk
->ResponseType
!= EmmcResponceTypeR5b
)) {
1521 if ((IntStatus
& BIT0
) == BIT0
) {
1522 Status
= EFI_SUCCESS
;
1527 if (Packet
->EmmcCmdBlk
->CommandIndex
== EMMC_SEND_TUNING_BLOCK
) {
1529 // When performing tuning procedure (Execute Tuning is set to 1) through PIO mode,
1530 // wait Buffer Read Ready bit of Normal Interrupt Status Register to be 1.
1531 // Refer to SD Host Controller Simplified Specification 3.0 figure 2-29 for details.
1533 if ((IntStatus
& BIT5
) == BIT5
) {
1535 // Clear Buffer Read Ready interrupt at first.
1538 EmmcPeimHcRwMmio (Bar
+ EMMC_HC_NOR_INT_STS
, FALSE
, sizeof (IntStatus
), &IntStatus
);
1540 // Read data out from Buffer Port register
1542 for (PioLength
= 0; PioLength
< Trb
->DataLen
; PioLength
+= 4) {
1543 EmmcPeimHcRwMmio (Bar
+ EMMC_HC_BUF_DAT_PORT
, TRUE
, 4, (UINT8
*)Trb
->Data
+ PioLength
);
1545 Status
= EFI_SUCCESS
;
1550 Status
= EFI_NOT_READY
;
1553 // Get response data when the cmd is executed successfully.
1555 if (!EFI_ERROR (Status
)) {
1556 if (Packet
->EmmcCmdBlk
->CommandType
!= EmmcCommandTypeBc
) {
1557 for (Index
= 0; Index
< 4; Index
++) {
1558 Status
= EmmcPeimHcRwMmio (
1559 Bar
+ EMMC_HC_RESPONSE
+ Index
* 4,
1564 if (EFI_ERROR (Status
)) {
1565 EmmcPeimHcLedOnOff (Bar
, FALSE
);
1569 CopyMem (Packet
->EmmcStatusBlk
, Response
, sizeof (Response
));
1573 if (Status
!= EFI_NOT_READY
) {
1574 EmmcPeimHcLedOnOff (Bar
, FALSE
);
1581 Wait for the TRB execution result.
1583 @param[in] Bar The mmio base address of the slot to be accessed.
1584 @param[in] Trb The pointer to the EMMC_TRB instance.
1586 @retval EFI_SUCCESS The TRB is executed successfully.
1587 @retval Others Some erros happen when executing this request.
1591 EmmcPeimWaitTrbResult (
1597 EMMC_COMMAND_PACKET
*Packet
;
1599 BOOLEAN InfiniteWait
;
1601 Packet
= Trb
->Packet
;
1603 // Wait Command Complete Interrupt Status bit in Normal Interrupt Status Register
1605 Timeout
= Packet
->Timeout
;
1607 InfiniteWait
= TRUE
;
1609 InfiniteWait
= FALSE
;
1612 while (InfiniteWait
|| (Timeout
> 0)) {
1614 // Check Trb execution result by reading Normal Interrupt Status register.
1616 Status
= EmmcPeimCheckTrbResult (Bar
, Trb
);
1617 if (Status
!= EFI_NOT_READY
) {
1621 // Stall for 1 microsecond.
1623 MicroSecondDelay (1);
1632 Sends EMMC command to an EMMC card that is attached to the EMMC controller.
1634 If Packet is successfully sent to the EMMC card, then EFI_SUCCESS is returned.
1636 If a device error occurs while sending the Packet, then EFI_DEVICE_ERROR is returned.
1638 If Slot is not in a valid range for the EMMC controller, then EFI_INVALID_PARAMETER
1641 If Packet defines a data command but both InDataBuffer and OutDataBuffer are NULL,
1642 EFI_INVALID_PARAMETER is returned.
1644 @param[in] Slot The slot number of the Emmc card to send the command to.
1645 @param[in,out] Packet A pointer to the EMMC command data structure.
1647 @retval EFI_SUCCESS The EMMC Command Packet was sent by the host.
1648 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send the SD
1650 @retval EFI_INVALID_PARAMETER Packet, Slot, or the contents of the Packet is invalid.
1651 @retval EFI_INVALID_PARAMETER Packet defines a data command but both InDataBuffer and
1652 OutDataBuffer are NULL.
1653 @retval EFI_NO_MEDIA SD Device not present in the Slot.
1654 @retval EFI_UNSUPPORTED The command described by the EMMC Command Packet is not
1655 supported by the host controller.
1656 @retval EFI_BAD_BUFFER_SIZE The InTransferLength or OutTransferLength exceeds the
1657 limit supported by EMMC card ( i.e. if the number of bytes
1658 exceed the Last LBA).
1664 IN EMMC_PEIM_HC_SLOT
*Slot
,
1665 IN OUT EMMC_COMMAND_PACKET
*Packet
1671 if (Packet
== NULL
) {
1672 return EFI_INVALID_PARAMETER
;
1675 if ((Packet
->EmmcCmdBlk
== NULL
) || (Packet
->EmmcStatusBlk
== NULL
)) {
1676 return EFI_INVALID_PARAMETER
;
1679 if ((Packet
->OutDataBuffer
== NULL
) && (Packet
->OutTransferLength
!= 0)) {
1680 return EFI_INVALID_PARAMETER
;
1683 if ((Packet
->InDataBuffer
== NULL
) && (Packet
->InTransferLength
!= 0)) {
1684 return EFI_INVALID_PARAMETER
;
1687 Trb
= EmmcPeimCreateTrb (Slot
, Packet
);
1689 return EFI_OUT_OF_RESOURCES
;
1692 Status
= EmmcPeimWaitTrbEnv (Slot
->EmmcHcBase
, Trb
);
1693 if (EFI_ERROR (Status
)) {
1697 Status
= EmmcPeimExecTrb (Slot
->EmmcHcBase
, Trb
);
1698 if (EFI_ERROR (Status
)) {
1702 Status
= EmmcPeimWaitTrbResult (Slot
->EmmcHcBase
, Trb
);
1703 if (EFI_ERROR (Status
)) {
1708 EmmcPeimFreeTrb (Trb
);
1714 Send command GO_IDLE_STATE (CMD0 with argument of 0x00000000) to the device to
1715 make it go to Idle State.
1717 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
1719 @param[in] Slot The slot number of the Emmc card to send the command to.
1721 @retval EFI_SUCCESS The EMMC device is reset correctly.
1722 @retval Others The device reset fails.
1727 IN EMMC_PEIM_HC_SLOT
*Slot
1730 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
1731 EMMC_STATUS_BLOCK EmmcStatusBlk
;
1732 EMMC_COMMAND_PACKET Packet
;
1735 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
1736 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
1737 ZeroMem (&Packet
, sizeof (Packet
));
1739 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
1740 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
1741 Packet
.Timeout
= EMMC_TIMEOUT
;
1743 EmmcCmdBlk
.CommandIndex
= EMMC_GO_IDLE_STATE
;
1744 EmmcCmdBlk
.CommandType
= EmmcCommandTypeBc
;
1745 EmmcCmdBlk
.ResponseType
= 0;
1746 EmmcCmdBlk
.CommandArgument
= 0;
1748 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
1754 Send command SEND_OP_COND to the EMMC device to get the data of the OCR register.
1756 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
1758 @param[in] Slot The slot number of the Emmc card to send the command to.
1759 @param[in, out] Argument On input, the argument of SEND_OP_COND is to send to the device.
1760 On output, the argument is the value of OCR register.
1762 @retval EFI_SUCCESS The operation is done correctly.
1763 @retval Others The operation fails.
1768 IN EMMC_PEIM_HC_SLOT
*Slot
,
1769 IN OUT UINT32
*Argument
1772 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
1773 EMMC_STATUS_BLOCK EmmcStatusBlk
;
1774 EMMC_COMMAND_PACKET Packet
;
1777 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
1778 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
1779 ZeroMem (&Packet
, sizeof (Packet
));
1781 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
1782 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
1783 Packet
.Timeout
= EMMC_TIMEOUT
;
1785 EmmcCmdBlk
.CommandIndex
= EMMC_SEND_OP_COND
;
1786 EmmcCmdBlk
.CommandType
= EmmcCommandTypeBcr
;
1787 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR3
;
1788 EmmcCmdBlk
.CommandArgument
= *Argument
;
1790 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
1791 if (!EFI_ERROR (Status
)) {
1793 // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12.
1795 *Argument
= EmmcStatusBlk
.Resp0
;
1802 Broadcast command ALL_SEND_CID to the bus to ask all the EMMC devices to send the
1803 data of their CID registers.
1805 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
1807 @param[in] Slot The slot number of the Emmc card to send the command to.
1809 @retval EFI_SUCCESS The operation is done correctly.
1810 @retval Others The operation fails.
1815 IN EMMC_PEIM_HC_SLOT
*Slot
1818 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
1819 EMMC_STATUS_BLOCK EmmcStatusBlk
;
1820 EMMC_COMMAND_PACKET Packet
;
1823 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
1824 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
1825 ZeroMem (&Packet
, sizeof (Packet
));
1827 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
1828 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
1829 Packet
.Timeout
= EMMC_TIMEOUT
;
1831 EmmcCmdBlk
.CommandIndex
= EMMC_ALL_SEND_CID
;
1832 EmmcCmdBlk
.CommandType
= EmmcCommandTypeBcr
;
1833 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR2
;
1834 EmmcCmdBlk
.CommandArgument
= 0;
1836 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
1842 Send command SET_RELATIVE_ADDR to the EMMC device to assign a Relative device
1845 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
1847 @param[in] Slot The slot number of the Emmc card to send the command to.
1848 @param[in] Rca The relative device address to be assigned.
1850 @retval EFI_SUCCESS The operation is done correctly.
1851 @retval Others The operation fails.
1856 IN EMMC_PEIM_HC_SLOT
*Slot
,
1860 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
1861 EMMC_STATUS_BLOCK EmmcStatusBlk
;
1862 EMMC_COMMAND_PACKET Packet
;
1865 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
1866 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
1867 ZeroMem (&Packet
, sizeof (Packet
));
1869 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
1870 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
1871 Packet
.Timeout
= EMMC_TIMEOUT
;
1873 EmmcCmdBlk
.CommandIndex
= EMMC_SET_RELATIVE_ADDR
;
1874 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAc
;
1875 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR1
;
1876 EmmcCmdBlk
.CommandArgument
= Rca
<< 16;
1878 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
1884 Send command SEND_CSD to the EMMC device to get the data of the CSD register.
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.
1890 @param[out] Csd The buffer to store the content of the CSD register.
1891 Note the caller should ignore the lowest byte of this
1892 buffer as the content of this byte is meaningless even
1893 if the operation succeeds.
1895 @retval EFI_SUCCESS The operation is done correctly.
1896 @retval Others The operation fails.
1901 IN EMMC_PEIM_HC_SLOT
*Slot
,
1906 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
1907 EMMC_STATUS_BLOCK EmmcStatusBlk
;
1908 EMMC_COMMAND_PACKET Packet
;
1911 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
1912 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
1913 ZeroMem (&Packet
, sizeof (Packet
));
1915 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
1916 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
1917 Packet
.Timeout
= EMMC_TIMEOUT
;
1919 EmmcCmdBlk
.CommandIndex
= EMMC_SEND_CSD
;
1920 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAc
;
1921 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR2
;
1922 EmmcCmdBlk
.CommandArgument
= Rca
<< 16;
1924 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
1925 if (!EFI_ERROR (Status
)) {
1927 // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12.
1929 CopyMem (((UINT8
*)Csd
) + 1, &EmmcStatusBlk
.Resp0
, sizeof (EMMC_CSD
) - 1);
1936 Send command SELECT_DESELECT_CARD to the EMMC device to select/deselect it.
1938 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
1940 @param[in] Slot The slot number of the Emmc card to send the command to.
1941 @param[in] Rca The relative device address of selected device.
1943 @retval EFI_SUCCESS The operation is done correctly.
1944 @retval Others The operation fails.
1949 IN EMMC_PEIM_HC_SLOT
*Slot
,
1953 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
1954 EMMC_STATUS_BLOCK EmmcStatusBlk
;
1955 EMMC_COMMAND_PACKET Packet
;
1958 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
1959 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
1960 ZeroMem (&Packet
, sizeof (Packet
));
1962 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
1963 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
1964 Packet
.Timeout
= EMMC_TIMEOUT
;
1966 EmmcCmdBlk
.CommandIndex
= EMMC_SELECT_DESELECT_CARD
;
1967 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAc
;
1968 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR1
;
1969 EmmcCmdBlk
.CommandArgument
= Rca
<< 16;
1971 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
1977 Send command SEND_EXT_CSD to the EMMC device to get the data of the EXT_CSD register.
1979 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
1981 @param[in] Slot The slot number of the Emmc card to send the command to.
1982 @param[out] ExtCsd The buffer to store the content of the EXT_CSD register.
1984 @retval EFI_SUCCESS The operation is done correctly.
1985 @retval Others The operation fails.
1990 IN EMMC_PEIM_HC_SLOT
*Slot
,
1991 OUT EMMC_EXT_CSD
*ExtCsd
1994 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
1995 EMMC_STATUS_BLOCK EmmcStatusBlk
;
1996 EMMC_COMMAND_PACKET Packet
;
1999 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
2000 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
2001 ZeroMem (&Packet
, sizeof (Packet
));
2003 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
2004 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
2005 Packet
.Timeout
= EMMC_TIMEOUT
;
2007 EmmcCmdBlk
.CommandIndex
= EMMC_SEND_EXT_CSD
;
2008 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAdtc
;
2009 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR1
;
2010 EmmcCmdBlk
.CommandArgument
= 0x00000000;
2012 Packet
.InDataBuffer
= ExtCsd
;
2013 Packet
.InTransferLength
= sizeof (EMMC_EXT_CSD
);
2015 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
2020 Send command SWITCH to the EMMC device to switch the mode of operation of the
2021 selected Device or modifies the EXT_CSD registers.
2023 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
2025 @param[in] Slot The slot number of the Emmc card to send the command to.
2026 @param[in] Access The access mode of SWTICH command.
2027 @param[in] Index The offset of the field to be access.
2028 @param[in] Value The value to be set to the specified field of EXT_CSD register.
2029 @param[in] CmdSet The value of CmdSet field of EXT_CSD register.
2031 @retval EFI_SUCCESS The operation is done correctly.
2032 @retval Others The operation fails.
2037 IN EMMC_PEIM_HC_SLOT
*Slot
,
2044 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
2045 EMMC_STATUS_BLOCK EmmcStatusBlk
;
2046 EMMC_COMMAND_PACKET Packet
;
2049 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
2050 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
2051 ZeroMem (&Packet
, sizeof (Packet
));
2053 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
2054 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
2055 Packet
.Timeout
= EMMC_TIMEOUT
;
2057 EmmcCmdBlk
.CommandIndex
= EMMC_SWITCH
;
2058 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAc
;
2059 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR1b
;
2060 EmmcCmdBlk
.CommandArgument
= (Access
<< 24) | (Index
<< 16) | (Value
<< 8) | CmdSet
;
2062 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
2068 Send command SEND_STATUS to the addressed EMMC device to get its status register.
2070 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
2072 @param[in] Slot The slot number of the Emmc card to send the command to.
2073 @param[in] Rca The relative device address of addressed device.
2074 @param[out] DevStatus The returned device status.
2076 @retval EFI_SUCCESS The operation is done correctly.
2077 @retval Others The operation fails.
2081 EmmcPeimSendStatus (
2082 IN EMMC_PEIM_HC_SLOT
*Slot
,
2084 OUT UINT32
*DevStatus
2087 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
2088 EMMC_STATUS_BLOCK EmmcStatusBlk
;
2089 EMMC_COMMAND_PACKET Packet
;
2092 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
2093 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
2094 ZeroMem (&Packet
, sizeof (Packet
));
2096 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
2097 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
2098 Packet
.Timeout
= EMMC_TIMEOUT
;
2100 EmmcCmdBlk
.CommandIndex
= EMMC_SEND_STATUS
;
2101 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAc
;
2102 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR1
;
2103 EmmcCmdBlk
.CommandArgument
= Rca
<< 16;
2105 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
2106 if (!EFI_ERROR (Status
)) {
2107 *DevStatus
= EmmcStatusBlk
.Resp0
;
2114 Send command SET_BLOCK_COUNT to the addressed EMMC device to set the number of
2115 blocks for the following block read/write cmd.
2117 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
2119 @param[in] Slot The slot number of the Emmc card to send the command to.
2120 @param[in] BlockCount The number of the logical block to access.
2122 @retval EFI_SUCCESS The operation is done correctly.
2123 @retval Others The operation fails.
2127 EmmcPeimSetBlkCount (
2128 IN EMMC_PEIM_HC_SLOT
*Slot
,
2129 IN UINT16 BlockCount
2132 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
2133 EMMC_STATUS_BLOCK EmmcStatusBlk
;
2134 EMMC_COMMAND_PACKET Packet
;
2137 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
2138 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
2139 ZeroMem (&Packet
, sizeof (Packet
));
2141 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
2142 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
2143 Packet
.Timeout
= EMMC_TIMEOUT
;
2145 EmmcCmdBlk
.CommandIndex
= EMMC_SET_BLOCK_COUNT
;
2146 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAc
;
2147 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR1
;
2148 EmmcCmdBlk
.CommandArgument
= BlockCount
;
2150 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
2156 Send command READ_MULTIPLE_BLOCK/WRITE_MULTIPLE_BLOCK to the addressed EMMC device
2157 to read/write the specified number of blocks.
2159 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
2161 @param[in] Slot The slot number of the Emmc card to send the command to.
2162 @param[in] Lba The logical block address of starting access.
2163 @param[in] BlockSize The block size of specified EMMC device partition.
2164 @param[in] Buffer The pointer to the transfer buffer.
2165 @param[in] BufferSize The size of transfer buffer.
2166 @param[in] IsRead Boolean to show the operation direction.
2168 @retval EFI_SUCCESS The operation is done correctly.
2169 @retval Others The operation fails.
2173 EmmcPeimRwMultiBlocks (
2174 IN EMMC_PEIM_HC_SLOT
*Slot
,
2176 IN UINT32 BlockSize
,
2178 IN UINTN BufferSize
,
2182 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
2183 EMMC_STATUS_BLOCK EmmcStatusBlk
;
2184 EMMC_COMMAND_PACKET Packet
;
2187 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
2188 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
2189 ZeroMem (&Packet
, sizeof (Packet
));
2191 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
2192 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
2194 // Calculate timeout value through the below formula.
2195 // Timeout = (transfer size) / (2MB/s).
2196 // Taking 2MB/s as divisor is because it's nearest to the eMMC lowest
2197 // transfer speed (2.4MB/s).
2198 // Refer to eMMC 5.0 spec section 6.9.1 for details.
2200 Packet
.Timeout
= (BufferSize
/ (2 * 1024 * 1024) + 1) * 1000 * 1000;;
2203 Packet
.InDataBuffer
= Buffer
;
2204 Packet
.InTransferLength
= (UINT32
)BufferSize
;
2206 EmmcCmdBlk
.CommandIndex
= EMMC_READ_MULTIPLE_BLOCK
;
2207 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAdtc
;
2208 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR1
;
2210 Packet
.OutDataBuffer
= Buffer
;
2211 Packet
.OutTransferLength
= (UINT32
)BufferSize
;
2213 EmmcCmdBlk
.CommandIndex
= EMMC_WRITE_MULTIPLE_BLOCK
;
2214 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAdtc
;
2215 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR1
;
2218 if (Slot
->SectorAddressing
) {
2219 EmmcCmdBlk
.CommandArgument
= (UINT32
)Lba
;
2221 EmmcCmdBlk
.CommandArgument
= (UINT32
)MultU64x32 (Lba
, BlockSize
);
2224 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
2230 Send command SEND_TUNING_BLOCK to the EMMC device for HS200 optimal sampling point
2233 It may be sent up to 40 times until the host finishes the tuning procedure.
2235 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 for details.
2237 @param[in] Slot The slot number of the Emmc card to send the command to.
2238 @param[in] BusWidth The bus width to work.
2240 @retval EFI_SUCCESS The operation is done correctly.
2241 @retval Others The operation fails.
2245 EmmcPeimSendTuningBlk (
2246 IN EMMC_PEIM_HC_SLOT
*Slot
,
2250 EMMC_COMMAND_BLOCK EmmcCmdBlk
;
2251 EMMC_STATUS_BLOCK EmmcStatusBlk
;
2252 EMMC_COMMAND_PACKET Packet
;
2254 UINT8 TuningBlock
[128];
2256 ZeroMem (&EmmcCmdBlk
, sizeof (EmmcCmdBlk
));
2257 ZeroMem (&EmmcStatusBlk
, sizeof (EmmcStatusBlk
));
2258 ZeroMem (&Packet
, sizeof (Packet
));
2260 Packet
.EmmcCmdBlk
= &EmmcCmdBlk
;
2261 Packet
.EmmcStatusBlk
= &EmmcStatusBlk
;
2262 Packet
.Timeout
= EMMC_TIMEOUT
;
2264 EmmcCmdBlk
.CommandIndex
= EMMC_SEND_TUNING_BLOCK
;
2265 EmmcCmdBlk
.CommandType
= EmmcCommandTypeAdtc
;
2266 EmmcCmdBlk
.ResponseType
= EmmcResponceTypeR1
;
2267 EmmcCmdBlk
.CommandArgument
= 0;
2269 Packet
.InDataBuffer
= TuningBlock
;
2270 if (BusWidth
== 8) {
2271 Packet
.InTransferLength
= sizeof (TuningBlock
);
2273 Packet
.InTransferLength
= 64;
2276 Status
= EmmcPeimExecCmd (Slot
, &Packet
);
2282 Tunning the clock to get HS200 optimal sampling point.
2284 Command SEND_TUNING_BLOCK may be sent up to 40 times until the host finishes the
2287 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
2288 Simplified Spec 3.0 section Figure 2-29 for details.
2290 @param[in] Slot The slot number of the Emmc card to send the command to.
2291 @param[in] BusWidth The bus width to work.
2293 @retval EFI_SUCCESS The operation is done correctly.
2294 @retval Others The operation fails.
2298 EmmcPeimTuningClkForHs200 (
2299 IN EMMC_PEIM_HC_SLOT
*Slot
,
2308 // Notify the host that the sampling clock tuning procedure starts.
2311 Status
= EmmcPeimHcOrMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2312 if (EFI_ERROR (Status
)) {
2316 // Ask the device to send a sequence of tuning blocks till the tuning procedure is done.
2320 Status
= EmmcPeimSendTuningBlk (Slot
, BusWidth
);
2321 if (EFI_ERROR (Status
)) {
2325 Status
= EmmcPeimHcRwMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL2
, TRUE
, sizeof (HostCtrl2
), &HostCtrl2
);
2326 if (EFI_ERROR (Status
)) {
2330 if ((HostCtrl2
& (BIT6
| BIT7
)) == 0) {
2334 if ((HostCtrl2
& (BIT6
| BIT7
)) == BIT7
) {
2337 } while (++Retry
< 40);
2339 DEBUG ((EFI_D_ERROR
, "EmmcPeimTuningClkForHs200: Send tuning block fails at %d times with HostCtrl2 %02x\n", Retry
, HostCtrl2
));
2341 // Abort the tuning procedure and reset the tuning circuit.
2343 HostCtrl2
= (UINT8
)~(BIT6
| BIT7
);
2344 Status
= EmmcPeimHcAndMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2345 if (EFI_ERROR (Status
)) {
2348 return EFI_DEVICE_ERROR
;
2352 Switch the bus width to specified width.
2354 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.9 and SD Host Controller
2355 Simplified Spec 3.0 section Figure 3-7 for details.
2357 @param[in] Slot The slot number of the Emmc card to send the command to.
2358 @param[in] Rca The relative device address to be assigned.
2359 @param[in] IsDdr If TRUE, use dual data rate data simpling method. Otherwise
2360 use single data rate data simpling method.
2361 @param[in] BusWidth The bus width to be set, it could be 4 or 8.
2363 @retval EFI_SUCCESS The operation is done correctly.
2364 @retval Others The operation fails.
2368 EmmcPeimSwitchBusWidth (
2369 IN EMMC_PEIM_HC_SLOT
*Slot
,
2383 // Write Byte, the Value field is written into the byte pointed by Index.
2386 Index
= OFFSET_OF (EMMC_EXT_CSD
, BusWidth
);
2387 if (BusWidth
== 4) {
2389 } else if (BusWidth
== 8) {
2392 return EFI_INVALID_PARAMETER
;
2400 Status
= EmmcPeimSwitch (Slot
, Access
, Index
, Value
, CmdSet
);
2401 if (EFI_ERROR (Status
)) {
2405 Status
= EmmcPeimSendStatus (Slot
, Rca
, &DevStatus
);
2406 if (EFI_ERROR (Status
)) {
2410 // Check the switch operation is really successful or not.
2412 if ((DevStatus
& BIT7
) != 0) {
2413 return EFI_DEVICE_ERROR
;
2416 Status
= EmmcPeimHcSetBusWidth (Slot
->EmmcHcBase
, BusWidth
);
2422 Switch the clock frequency to the specified value.
2424 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6 and SD Host Controller
2425 Simplified Spec 3.0 section Figure 3-3 for details.
2427 @param[in] Slot The slot number of the Emmc card to send the command to.
2428 @param[in] Rca The relative device address to be assigned.
2429 @param[in] HsTiming The value to be written to HS_TIMING field of EXT_CSD register.
2430 @param[in] ClockFreq The max clock frequency to be set, the unit is MHz.
2432 @retval EFI_SUCCESS The operation is done correctly.
2433 @retval Others The operation fails.
2437 EmmcPeimSwitchClockFreq (
2438 IN EMMC_PEIM_HC_SLOT
*Slot
,
2452 // Write Byte, the Value field is written into the byte pointed by Index.
2455 Index
= OFFSET_OF (EMMC_EXT_CSD
, HsTiming
);
2459 Status
= EmmcPeimSwitch (Slot
, Access
, Index
, Value
, CmdSet
);
2460 if (EFI_ERROR (Status
)) {
2464 Status
= EmmcPeimSendStatus (Slot
, Rca
, &DevStatus
);
2465 if (EFI_ERROR (Status
)) {
2469 // Check the switch operation is really successful or not.
2471 if ((DevStatus
& BIT7
) != 0) {
2472 return EFI_DEVICE_ERROR
;
2475 // Convert the clock freq unit from MHz to KHz.
2477 Status
= EmmcPeimHcClockSupply (Slot
->EmmcHcBase
, ClockFreq
* 1000);
2483 Switch to the High Speed timing according to request.
2485 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
2486 Simplified Spec 3.0 section Figure 2-29 for details.
2488 @param[in] Slot The slot number of the Emmc card to send the command to.
2489 @param[in] Rca The relative device address to be assigned.
2490 @param[in] ClockFreq The max clock frequency to be set.
2491 @param[in] IsDdr If TRUE, use dual data rate data simpling method. Otherwise
2492 use single data rate data simpling method.
2493 @param[in] BusWidth The bus width to be set, it could be 4 or 8.
2495 @retval EFI_SUCCESS The operation is done correctly.
2496 @retval Others The operation fails.
2500 EmmcPeimSwitchToHighSpeed (
2501 IN EMMC_PEIM_HC_SLOT
*Slot
,
2503 IN UINT32 ClockFreq
,
2513 Status
= EmmcPeimSwitchBusWidth (Slot
, Rca
, IsDdr
, BusWidth
);
2514 if (EFI_ERROR (Status
)) {
2518 // Set to Hight Speed timing
2521 Status
= EmmcPeimHcOrMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
2522 if (EFI_ERROR (Status
)) {
2526 HostCtrl2
= (UINT8
)~0x7;
2527 Status
= EmmcPeimHcAndMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2528 if (EFI_ERROR (Status
)) {
2533 } else if (ClockFreq
== 52) {
2538 Status
= EmmcPeimHcOrMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2539 if (EFI_ERROR (Status
)) {
2544 Status
= EmmcPeimSwitchClockFreq (Slot
, Rca
, HsTiming
, ClockFreq
);
2550 Switch to the HS200 timing according to request.
2552 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
2553 Simplified Spec 3.0 section Figure 2-29 for details.
2555 @param[in] Slot The slot number of the Emmc card to send the command to.
2556 @param[in] Rca The relative device address to be assigned.
2557 @param[in] ClockFreq The max clock frequency to be set.
2558 @param[in] BusWidth The bus width to be set, it could be 4 or 8.
2560 @retval EFI_SUCCESS The operation is done correctly.
2561 @retval Others The operation fails.
2565 EmmcPeimSwitchToHS200 (
2566 IN EMMC_PEIM_HC_SLOT
*Slot
,
2568 IN UINT32 ClockFreq
,
2577 if ((BusWidth
!= 4) && (BusWidth
!= 8)) {
2578 return EFI_INVALID_PARAMETER
;
2581 Status
= EmmcPeimSwitchBusWidth (Slot
, Rca
, FALSE
, BusWidth
);
2582 if (EFI_ERROR (Status
)) {
2586 // Set to HS200/SDR104 timing
2589 // Stop bus clock at first
2591 Status
= EmmcPeimHcStopClock (Slot
->EmmcHcBase
);
2592 if (EFI_ERROR (Status
)) {
2596 HostCtrl2
= (UINT8
)~0x7;
2597 Status
= EmmcPeimHcAndMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2598 if (EFI_ERROR (Status
)) {
2601 HostCtrl2
= BIT0
| BIT1
;
2602 Status
= EmmcPeimHcOrMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2603 if (EFI_ERROR (Status
)) {
2608 // Wait Internal Clock Stable in the Clock Control register to be 1 before set SD Clock Enable bit
2610 Status
= EmmcPeimHcWaitMmioSet (
2611 Slot
->EmmcHcBase
+ EMMC_HC_CLOCK_CTRL
,
2617 if (EFI_ERROR (Status
)) {
2621 // Set SD Clock Enable in the Clock Control register to 1
2624 Status
= EmmcPeimHcOrMmio (Slot
->EmmcHcBase
+ EMMC_HC_CLOCK_CTRL
, sizeof (ClockCtrl
), &ClockCtrl
);
2627 Status
= EmmcPeimSwitchClockFreq (Slot
, Rca
, HsTiming
, ClockFreq
);
2628 if (EFI_ERROR (Status
)) {
2632 Status
= EmmcPeimTuningClkForHs200 (Slot
, BusWidth
);
2638 Switch to the HS400 timing according to request.
2640 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
2641 Simplified Spec 3.0 section Figure 2-29 for details.
2643 @param[in] Slot The slot number of the Emmc card to send the command to.
2644 @param[in] Rca The relative device address to be assigned.
2645 @param[in] ClockFreq The max clock frequency to be set.
2647 @retval EFI_SUCCESS The operation is done correctly.
2648 @retval Others The operation fails.
2652 EmmcPeimSwitchToHS400 (
2653 IN EMMC_PEIM_HC_SLOT
*Slot
,
2662 Status
= EmmcPeimSwitchToHS200 (Slot
, Rca
, ClockFreq
, 8);
2663 if (EFI_ERROR (Status
)) {
2667 // Set to Hight Speed timing and set the clock frequency to a value less than 52MHz.
2670 Status
= EmmcPeimSwitchClockFreq (Slot
, Rca
, HsTiming
, 52);
2671 if (EFI_ERROR (Status
)) {
2675 // HS400 mode must use 8 data lines.
2677 Status
= EmmcPeimSwitchBusWidth (Slot
, Rca
, TRUE
, 8);
2678 if (EFI_ERROR (Status
)) {
2682 // Set to HS400 timing
2684 HostCtrl2
= (UINT8
)~0x7;
2685 Status
= EmmcPeimHcAndMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2686 if (EFI_ERROR (Status
)) {
2689 HostCtrl2
= BIT0
| BIT2
;
2690 Status
= EmmcPeimHcOrMmio (Slot
->EmmcHcBase
+ EMMC_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2691 if (EFI_ERROR (Status
)) {
2696 Status
= EmmcPeimSwitchClockFreq (Slot
, Rca
, HsTiming
, ClockFreq
);
2702 Switch the high speed timing according to request.
2704 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
2705 Simplified Spec 3.0 section Figure 2-29 for details.
2707 @param[in] Slot The slot number of the Emmc card to send the command to.
2708 @param[in] Rca The relative device address to be assigned.
2710 @retval EFI_SUCCESS The operation is done correctly.
2711 @retval Others The operation fails.
2715 EmmcPeimSetBusMode (
2716 IN EMMC_PEIM_HC_SLOT
*Slot
,
2721 EMMC_HC_SLOT_CAP Capability
;
2727 Status
= EmmcPeimGetCsd (Slot
, Rca
, &Slot
->Csd
);
2728 if (EFI_ERROR (Status
)) {
2729 DEBUG ((EFI_D_ERROR
, "EmmcPeimSetBusMode: EmmcPeimGetCsd fails with %r\n", Status
));
2733 if ((Slot
->Csd
.CSizeLow
| Slot
->Csd
.CSizeHigh
<< 2) == 0xFFF) {
2734 Slot
->SectorAddressing
= TRUE
;
2736 Slot
->SectorAddressing
= FALSE
;
2739 Status
= EmmcPeimSelect (Slot
, Rca
);
2740 if (EFI_ERROR (Status
)) {
2741 DEBUG ((EFI_D_ERROR
, "EmmcPeimSetBusMode: EmmcPeimSelect fails with %r\n", Status
));
2745 Status
= EmmcPeimHcGetCapability (Slot
->EmmcHcBase
, &Capability
);
2746 if (EFI_ERROR (Status
)) {
2747 DEBUG ((EFI_D_ERROR
, "EmmcPeimSetBusMode: EmmcPeimHcGetCapability fails with %r\n", Status
));
2751 ASSERT (Capability
.BaseClkFreq
!= 0);
2753 // Check if the Host Controller support 8bits bus width.
2755 if (Capability
.BusWidth8
!= 0) {
2761 // Get Deivce_Type from EXT_CSD register.
2763 Status
= EmmcPeimGetExtCsd (Slot
, &Slot
->ExtCsd
);
2764 if (EFI_ERROR (Status
)) {
2765 DEBUG ((EFI_D_ERROR
, "EmmcPeimSetBusMode: EmmcPeimGetExtCsd fails with %r\n", Status
));
2769 // Calculate supported bus speed/bus width/clock frequency.
2774 if (((Slot
->ExtCsd
.DeviceType
& (BIT4
| BIT5
)) != 0) && (Capability
.Sdr104
!= 0)) {
2778 } else if (((Slot
->ExtCsd
.DeviceType
& (BIT2
| BIT3
)) != 0) && (Capability
.Ddr50
!= 0)) {
2782 } else if (((Slot
->ExtCsd
.DeviceType
& BIT1
) != 0) && (Capability
.HighSpeed
!= 0)) {
2786 } else if (((Slot
->ExtCsd
.DeviceType
& BIT0
) != 0) && (Capability
.HighSpeed
!= 0)) {
2792 // Check if both of the device and the host controller support HS400 DDR mode.
2794 if (((Slot
->ExtCsd
.DeviceType
& (BIT6
| BIT7
)) != 0) && (Capability
.Hs400
!= 0)) {
2796 // The host controller supports 8bits bus.
2798 ASSERT (BusWidth
== 8);
2804 if ((ClockFreq
== 0) || (HsTiming
== 0)) {
2806 // Continue using default setting.
2811 DEBUG ((EFI_D_INFO
, "HsTiming %d ClockFreq %d BusWidth %d Ddr %a\n", HsTiming
, ClockFreq
, BusWidth
, IsDdr
? "TRUE":"FALSE"));
2813 if (HsTiming
== 3) {
2815 // Execute HS400 timing switch procedure
2817 Status
= EmmcPeimSwitchToHS400 (Slot
, Rca
, ClockFreq
);
2818 } else if (HsTiming
== 2) {
2820 // Execute HS200 timing switch procedure
2822 Status
= EmmcPeimSwitchToHS200 (Slot
, Rca
, ClockFreq
, BusWidth
);
2825 // Execute High Speed timing switch procedure
2827 Status
= EmmcPeimSwitchToHighSpeed (Slot
, Rca
, ClockFreq
, IsDdr
, BusWidth
);
2834 Execute EMMC device identification procedure.
2836 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
2838 @param[in] Slot The slot number of the Emmc card to send the command to.
2840 @retval EFI_SUCCESS There is a EMMC card.
2841 @retval Others There is not a EMMC card.
2845 EmmcPeimIdentification (
2846 IN EMMC_PEIM_HC_SLOT
*Slot
2854 Status
= EmmcPeimReset (Slot
);
2855 if (EFI_ERROR (Status
)) {
2856 DEBUG ((EFI_D_ERROR
, "EmmcPeimIdentification: EmmcPeimReset fails with %r\n", Status
));
2863 Status
= EmmcPeimGetOcr (Slot
, &Ocr
);
2864 if (EFI_ERROR (Status
)) {
2865 DEBUG ((EFI_D_ERROR
, "EmmcPeimIdentification: EmmcPeimGetOcr fails with %r\n", Status
));
2869 if (Retry
++ == 100) {
2870 DEBUG ((EFI_D_ERROR
, "EmmcPeimIdentification: EmmcPeimGetOcr fails too many times\n"));
2871 return EFI_DEVICE_ERROR
;
2873 MicroSecondDelay (10 * 1000);
2874 } while ((Ocr
& BIT31
) == 0);
2876 Status
= EmmcPeimGetAllCid (Slot
);
2877 if (EFI_ERROR (Status
)) {
2878 DEBUG ((EFI_D_ERROR
, "EmmcPeimIdentification: EmmcPeimGetAllCid fails with %r\n", Status
));
2882 // Don't support multiple devices on the slot, that is
2883 // shared bus slot feature.
2886 Status
= EmmcPeimSetRca (Slot
, Rca
);
2887 if (EFI_ERROR (Status
)) {
2888 DEBUG ((EFI_D_ERROR
, "EmmcPeimIdentification: EmmcPeimSetRca fails with %r\n", Status
));
2892 // Enter Data Tranfer Mode.
2894 DEBUG ((EFI_D_INFO
, "Found a EMMC device at slot [%d], RCA [%d]\n", Slot
, Rca
));
2896 Status
= EmmcPeimSetBusMode (Slot
, Rca
);