3 Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>
4 SPDX-License-Identifier: BSD-2-Clause-Patent
8 #include "SdBlockIoPei.h"
11 Read/Write specified SD host controller mmio register.
13 @param[in] Address The address of the mmio register to be read/written.
14 @param[in] Read A boolean to indicate it's read or write operation.
15 @param[in] Count The width of the mmio register in bytes.
16 Must be 1, 2 , 4 or 8 bytes.
17 @param[in, out] Data For read operations, the destination buffer to store
18 the results. For write operations, the source buffer
19 to write data from. The caller is responsible for
20 having ownership of the data buffer and ensuring its
21 size not less than Count bytes.
23 @retval EFI_INVALID_PARAMETER The Address or the Data or the Count is not valid.
24 @retval EFI_SUCCESS The read/write operation succeeds.
25 @retval Others The read/write operation fails.
37 if ((Address
== 0) || (Data
== NULL
)) {
38 return EFI_INVALID_PARAMETER
;
41 if ((Count
!= 1) && (Count
!= 2) && (Count
!= 4) && (Count
!= 8)) {
42 return EFI_INVALID_PARAMETER
;
48 *(UINT8
*)Data
= MmioRead8 (Address
);
50 MmioWrite8 (Address
, *(UINT8
*)Data
);
56 *(UINT16
*)Data
= MmioRead16 (Address
);
58 MmioWrite16 (Address
, *(UINT16
*)Data
);
64 *(UINT32
*)Data
= MmioRead32 (Address
);
66 MmioWrite32 (Address
, *(UINT32
*)Data
);
72 *(UINT64
*)Data
= MmioRead64 (Address
);
74 MmioWrite64 (Address
, *(UINT64
*)Data
);
80 return EFI_INVALID_PARAMETER
;
87 Do OR operation with the value of the specified SD host controller mmio register.
89 @param[in] Address The address of the mmio register to be read/written.
90 @param[in] Count The width of the mmio register in bytes.
91 Must be 1, 2 , 4 or 8 bytes.
92 @param[in] OrData The pointer to the data used to do OR operation.
93 The caller is responsible for having ownership of
94 the data buffer and ensuring its size not less than
97 @retval EFI_INVALID_PARAMETER The Address or the OrData or the Count is not valid.
98 @retval EFI_SUCCESS The OR operation succeeds.
99 @retval Others The OR operation fails.
114 Status
= SdPeimHcRwMmio (Address
, TRUE
, Count
, &Data
);
115 if (EFI_ERROR (Status
)) {
120 Or
= *(UINT8
*)OrData
;
121 } else if (Count
== 2) {
122 Or
= *(UINT16
*)OrData
;
123 } else if (Count
== 4) {
124 Or
= *(UINT32
*)OrData
;
125 } else if (Count
== 8) {
126 Or
= *(UINT64
*)OrData
;
128 return EFI_INVALID_PARAMETER
;
132 Status
= SdPeimHcRwMmio (Address
, FALSE
, Count
, &Data
);
138 Do AND operation with the value of the specified SD host controller mmio register.
140 @param[in] Address The address of the mmio register to be read/written.
141 @param[in] Count The width of the mmio register in bytes.
142 Must be 1, 2 , 4 or 8 bytes.
143 @param[in] AndData The pointer to the data used to do AND operation.
144 The caller is responsible for having ownership of
145 the data buffer and ensuring its size not less than
148 @retval EFI_INVALID_PARAMETER The Address or the AndData or the Count is not valid.
149 @retval EFI_SUCCESS The AND operation succeeds.
150 @retval Others The AND operation fails.
165 Status
= SdPeimHcRwMmio (Address
, TRUE
, Count
, &Data
);
166 if (EFI_ERROR (Status
)) {
171 And
= *(UINT8
*)AndData
;
172 } else if (Count
== 2) {
173 And
= *(UINT16
*)AndData
;
174 } else if (Count
== 4) {
175 And
= *(UINT32
*)AndData
;
176 } else if (Count
== 8) {
177 And
= *(UINT64
*)AndData
;
179 return EFI_INVALID_PARAMETER
;
183 Status
= SdPeimHcRwMmio (Address
, FALSE
, Count
, &Data
);
189 Wait for the value of the specified MMIO register set to the test value.
191 @param[in] Address The address of the mmio register to be checked.
192 @param[in] Count The width of the mmio register in bytes.
193 Must be 1, 2, 4 or 8 bytes.
194 @param[in] MaskValue The mask value of memory.
195 @param[in] TestValue The test value of memory.
197 @retval EFI_NOT_READY The MMIO register hasn't set to the expected value.
198 @retval EFI_SUCCESS The MMIO register has expected value.
199 @retval Others The MMIO operation fails.
204 SdPeimHcCheckMmioSet (
215 // Access PCI MMIO space to see if the value is the tested one.
218 Status
= SdPeimHcRwMmio (Address
, TRUE
, Count
, &Value
);
219 if (EFI_ERROR (Status
)) {
225 if (Value
== TestValue
) {
229 return EFI_NOT_READY
;
233 Wait for the value of the specified MMIO register set to the test value.
235 @param[in] Address The address of the mmio register to wait.
236 @param[in] Count The width of the mmio register in bytes.
237 Must be 1, 2, 4 or 8 bytes.
238 @param[in] MaskValue The mask value of memory.
239 @param[in] TestValue The test value of memory.
240 @param[in] Timeout The time out value for wait memory set, uses 1
241 microsecond as a unit.
243 @retval EFI_TIMEOUT The MMIO register hasn't expected value in timeout
245 @retval EFI_SUCCESS The MMIO register has expected value.
246 @retval Others The MMIO operation fails.
251 SdPeimHcWaitMmioSet (
260 BOOLEAN InfiniteWait
;
265 InfiniteWait
= FALSE
;
268 while (InfiniteWait
|| (Timeout
> 0)) {
269 Status
= SdPeimHcCheckMmioSet (
275 if (Status
!= EFI_NOT_READY
) {
280 // Stall for 1 microsecond.
282 MicroSecondDelay (1);
291 Software reset the specified SD host controller and enable all interrupts.
293 @param[in] Bar The mmio base address of the slot to be accessed.
295 @retval EFI_SUCCESS The software reset executes successfully.
296 @retval Others The software reset fails.
308 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_SW_RST
, FALSE
, sizeof (SwReset
), &SwReset
);
310 if (EFI_ERROR (Status
)) {
311 DEBUG ((DEBUG_ERROR
, "SdPeimHcReset: write full 1 fails: %r\n", Status
));
315 Status
= SdPeimHcWaitMmioSet (
322 if (EFI_ERROR (Status
)) {
323 DEBUG ((DEBUG_INFO
, "SdPeimHcReset: reset done with %r\n", Status
));
328 // Enable all interrupt after reset all.
330 Status
= SdPeimHcEnableInterrupt (Bar
);
336 Set all interrupt status bits in Normal and Error Interrupt Status Enable
339 @param[in] Bar The mmio base address of the slot to be accessed.
341 @retval EFI_SUCCESS The operation executes successfully.
342 @retval Others The operation fails.
346 SdPeimHcEnableInterrupt (
354 // Enable all bits in Error Interrupt Status Enable Register
357 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_ERR_INT_STS_EN
, FALSE
, sizeof (IntStatus
), &IntStatus
);
358 if (EFI_ERROR (Status
)) {
363 // Enable all bits in Normal Interrupt Status Enable Register
366 Status
= SdPeimHcRwMmio (Bar
+ SD_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 SdPeimHcGetCapability (
384 OUT SD_HC_SLOT_CAP
*Capability
390 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_CAP
, TRUE
, sizeof (Cap
), &Cap
);
391 if (EFI_ERROR (Status
)) {
395 CopyMem (Capability
, &Cap
, sizeof (Cap
));
401 Detect whether there is a SD card attached at the specified SD 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 SD card attached.
409 @retval EFI_NO_MEDIA There is not a SD card attached.
410 @retval Others The detection fails.
423 // Check Normal Interrupt Status Register
425 Status
= SdPeimHcRwMmio (Bar
+ SD_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
= SdPeimHcRwMmio (Bar
+ SD_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
= SdPeimHcRwMmio (Bar
+ SD_HC_PRESENT_STATE
, TRUE
, sizeof (PresentState
), &PresentState
);
445 if (EFI_ERROR (Status
)) {
449 if ((PresentState
& BIT16
) != 0) {
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 SD clock.
464 @retval Others Fail to stop SD clock.
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
= SdPeimHcWaitMmioSet (
482 Bar
+ SD_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
= SdPeimHcAndMmio (Bar
+ SD_HC_CLOCK_CTRL
, sizeof (ClockCtrl
), &ClockCtrl
);
502 SD 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 SdPeimHcClockSupply (
520 SD_HC_SLOT_CAP Capability
;
525 UINT16 ControllerVer
;
529 // Calculate a divisor for SD clock frequency
531 Status
= SdPeimHcGetCapability (Bar
, &Capability
);
532 if (EFI_ERROR (Status
)) {
536 ASSERT (Capability
.BaseClkFreq
!= 0);
538 BaseClkFreq
= Capability
.BaseClkFreq
;
540 if (ClockFreq
== 0) {
541 return EFI_INVALID_PARAMETER
;
544 if (ClockFreq
> (BaseClkFreq
* 1000)) {
545 ClockFreq
= BaseClkFreq
* 1000;
549 // Calculate the divisor of base frequency.
552 SettingFreq
= BaseClkFreq
* 1000;
553 while (ClockFreq
< SettingFreq
) {
556 SettingFreq
= (BaseClkFreq
* 1000) / (2 * Divisor
);
557 Remainder
= (BaseClkFreq
* 1000) % (2 * Divisor
);
558 if ((ClockFreq
== SettingFreq
) && (Remainder
== 0)) {
562 if ((ClockFreq
== SettingFreq
) && (Remainder
!= 0)) {
567 DEBUG ((DEBUG_INFO
, "BaseClkFreq %dMHz Divisor %d ClockFreq %dKhz\n", BaseClkFreq
, Divisor
, ClockFreq
));
569 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_CTRL_VER
, TRUE
, sizeof (ControllerVer
), &ControllerVer
);
570 if (EFI_ERROR (Status
)) {
575 // Set SDCLK Frequency Select and Internal Clock Enable fields in Clock Control register.
577 if ((ControllerVer
& 0xFF) == 2) {
578 ASSERT (Divisor
<= 0x3FF);
579 ClockCtrl
= ((Divisor
& 0xFF) << 8) | ((Divisor
& 0x300) >> 2);
580 } else if (((ControllerVer
& 0xFF) == 0) || ((ControllerVer
& 0xFF) == 1)) {
582 // Only the most significant bit can be used as divisor.
584 if (((Divisor
- 1) & Divisor
) != 0) {
585 Divisor
= 1 << (HighBitSet32 (Divisor
) + 1);
588 ASSERT (Divisor
<= 0x80);
589 ClockCtrl
= (Divisor
& 0xFF) << 8;
591 DEBUG ((DEBUG_ERROR
, "Unknown SD Host Controller Spec version [0x%x]!!!\n", ControllerVer
));
592 return EFI_UNSUPPORTED
;
596 // Stop bus clock at first
598 Status
= SdPeimHcStopClock (Bar
);
599 if (EFI_ERROR (Status
)) {
604 // Supply clock frequency with specified divisor
607 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_CLOCK_CTRL
, FALSE
, sizeof (ClockCtrl
), &ClockCtrl
);
608 if (EFI_ERROR (Status
)) {
609 DEBUG ((DEBUG_ERROR
, "Set SDCLK Frequency Select and Internal Clock Enable fields fails\n"));
614 // Wait Internal Clock Stable in the Clock Control register to be 1
616 Status
= SdPeimHcWaitMmioSet (
617 Bar
+ SD_HC_CLOCK_CTRL
,
623 if (EFI_ERROR (Status
)) {
628 // Set SD Clock Enable in the Clock Control register to 1
631 Status
= SdPeimHcOrMmio (Bar
+ SD_HC_CLOCK_CTRL
, sizeof (ClockCtrl
), &ClockCtrl
);
637 SD bus power control.
639 Refer to SD Host Controller Simplified spec 3.0 Section 3.3 for details.
641 @param[in] Bar The mmio base address of the slot to be accessed.
642 @param[in] PowerCtrl The value setting to the power control register.
644 @retval TRUE There is a SD card attached.
645 @retval FALSE There is no a SD card attached.
649 SdPeimHcPowerControl (
659 PowerCtrl
&= (UINT8
) ~BIT0
;
660 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_POWER_CTRL
, FALSE
, sizeof (PowerCtrl
), &PowerCtrl
);
661 if (EFI_ERROR (Status
)) {
666 // Set SD Bus Voltage Select and SD Bus Power fields in Power Control Register
669 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_POWER_CTRL
, FALSE
, sizeof (PowerCtrl
), &PowerCtrl
);
675 Set the SD bus width.
677 Refer to SD Host Controller Simplified spec 3.0 Section 3.4 for details.
679 @param[in] Bar The mmio base address of the slot to be accessed.
680 @param[in] BusWidth The bus width used by the SD device, it must be 1, 4 or 8.
682 @retval EFI_SUCCESS The bus width is set successfully.
683 @retval Others The bus width isn't set successfully.
687 SdPeimHcSetBusWidth (
696 HostCtrl1
= (UINT8
) ~(BIT5
| BIT1
);
697 Status
= SdPeimHcAndMmio (Bar
+ SD_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
698 } else if (BusWidth
== 4) {
699 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_HOST_CTRL1
, TRUE
, sizeof (HostCtrl1
), &HostCtrl1
);
700 if (EFI_ERROR (Status
)) {
705 HostCtrl1
&= (UINT8
) ~BIT5
;
706 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_HOST_CTRL1
, FALSE
, sizeof (HostCtrl1
), &HostCtrl1
);
707 } else if (BusWidth
== 8) {
708 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_HOST_CTRL1
, TRUE
, sizeof (HostCtrl1
), &HostCtrl1
);
709 if (EFI_ERROR (Status
)) {
713 HostCtrl1
&= (UINT8
) ~BIT1
;
715 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_HOST_CTRL1
, FALSE
, sizeof (HostCtrl1
), &HostCtrl1
);
718 return EFI_INVALID_PARAMETER
;
725 Supply SD card with lowest clock frequency at initialization.
727 @param[in] Bar The mmio base address of the slot to be accessed.
729 @retval EFI_SUCCESS The clock is supplied successfully.
730 @retval Others The clock isn't supplied successfully.
734 SdPeimHcInitClockFreq (
739 SD_HC_SLOT_CAP Capability
;
743 // Calculate a divisor for SD clock frequency
745 Status
= SdPeimHcGetCapability (Bar
, &Capability
);
746 if (EFI_ERROR (Status
)) {
750 if (Capability
.BaseClkFreq
== 0) {
752 // Don't support get Base Clock Frequency information via another method
754 return EFI_UNSUPPORTED
;
758 // Supply 400KHz clock frequency at initialization phase.
761 Status
= SdPeimHcClockSupply (Bar
, InitFreq
);
766 Supply SD card with maximum voltage at initialization.
768 Refer to SD Host Controller Simplified spec 3.0 Section 3.3 for details.
770 @param[in] Bar The mmio base address of the slot to be accessed.
772 @retval EFI_SUCCESS The voltage is supplied successfully.
773 @retval Others The voltage isn't supplied successfully.
777 SdPeimHcInitPowerVoltage (
782 SD_HC_SLOT_CAP Capability
;
787 // Get the support voltage of the Host Controller
789 Status
= SdPeimHcGetCapability (Bar
, &Capability
);
790 if (EFI_ERROR (Status
)) {
795 // Calculate supported maximum voltage according to SD Bus Voltage Select
797 if (Capability
.Voltage33
!= 0) {
802 } else if (Capability
.Voltage30
!= 0) {
807 } else if (Capability
.Voltage18
!= 0) {
813 Status
= SdPeimHcOrMmio (Bar
+ SD_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
814 if (EFI_ERROR (Status
)) {
818 MicroSecondDelay (5000);
821 return EFI_DEVICE_ERROR
;
825 // Set SD Bus Voltage Select and SD Bus Power fields in Power Control Register
827 Status
= SdPeimHcPowerControl (Bar
, MaxVoltage
);
833 Initialize the Timeout Control register with most conservative value at initialization.
835 Refer to SD Host Controller Simplified spec 3.0 Section 2.2.15 for details.
837 @param[in] Bar The mmio base address of the slot to be accessed.
839 @retval EFI_SUCCESS The timeout control register is configured successfully.
840 @retval Others The timeout control register isn't configured successfully.
844 SdPeimHcInitTimeoutCtrl (
852 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_TIMEOUT_CTRL
, FALSE
, sizeof (Timeout
), &Timeout
);
858 Initial SD host controller with lowest clock frequency, max power and max timeout value
861 @param[in] Bar The mmio base address of the slot to be accessed.
863 @retval EFI_SUCCESS The host controller is initialized successfully.
864 @retval Others The host controller isn't initialized successfully.
874 Status
= SdPeimHcInitClockFreq (Bar
);
875 if (EFI_ERROR (Status
)) {
879 Status
= SdPeimHcInitPowerVoltage (Bar
);
880 if (EFI_ERROR (Status
)) {
884 Status
= SdPeimHcInitTimeoutCtrl (Bar
);
891 @param[in] Bar The mmio base address of the slot to be accessed.
892 @param[in] On The boolean to turn on/off LED.
894 @retval EFI_SUCCESS The LED is turned on/off successfully.
895 @retval Others The LED isn't turned on/off successfully.
909 Status
= SdPeimHcOrMmio (Bar
+ SD_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
911 HostCtrl1
= (UINT8
) ~BIT0
;
912 Status
= SdPeimHcAndMmio (Bar
+ SD_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
919 Build ADMA descriptor table for transfer.
921 Refer to SD Host Controller Simplified spec 3.0 Section 1.13 for details.
923 @param[in] Trb The pointer to the SD_TRB instance.
925 @retval EFI_SUCCESS The ADMA descriptor table is created successfully.
926 @retval Others The ADMA descriptor table isn't created successfully.
934 EFI_PHYSICAL_ADDRESS Data
;
942 DataLen
= Trb
->DataLen
;
944 // Only support 32bit ADMA Descriptor Table
946 if ((Data
>= 0x100000000ul
) || ((Data
+ DataLen
) > 0x100000000ul
)) {
947 return EFI_INVALID_PARAMETER
;
951 // Address field shall be set on 32-bit boundary (Lower 2-bit is always set to 0)
952 // for 32-bit address descriptor table.
954 if ((Data
& (BIT0
| BIT1
)) != 0) {
955 DEBUG ((DEBUG_INFO
, "The buffer [0x%x] to construct ADMA desc is not aligned to 4 bytes boundary!\n", Data
));
958 Entries
= DivU64x32 ((DataLen
+ ADMA_MAX_DATA_PER_LINE
- 1), ADMA_MAX_DATA_PER_LINE
);
960 Trb
->AdmaDescSize
= (UINTN
)MultU64x32 (Entries
, sizeof (SD_HC_ADMA_DESC_LINE
));
961 Trb
->AdmaDesc
= SdPeimAllocateMem (Trb
->Slot
->Private
->Pool
, Trb
->AdmaDescSize
);
962 if (Trb
->AdmaDesc
== NULL
) {
963 return EFI_OUT_OF_RESOURCES
;
967 Address
= (UINT32
)Data
;
968 for (Index
= 0; Index
< Entries
; Index
++) {
969 if (Remaining
<= ADMA_MAX_DATA_PER_LINE
) {
970 Trb
->AdmaDesc
[Index
].Valid
= 1;
971 Trb
->AdmaDesc
[Index
].Act
= 2;
972 Trb
->AdmaDesc
[Index
].Length
= (UINT16
)Remaining
;
973 Trb
->AdmaDesc
[Index
].Address
= Address
;
976 Trb
->AdmaDesc
[Index
].Valid
= 1;
977 Trb
->AdmaDesc
[Index
].Act
= 2;
978 Trb
->AdmaDesc
[Index
].Length
= 0;
979 Trb
->AdmaDesc
[Index
].Address
= Address
;
982 Remaining
-= ADMA_MAX_DATA_PER_LINE
;
983 Address
+= ADMA_MAX_DATA_PER_LINE
;
987 // Set the last descriptor line as end of descriptor table
989 Trb
->AdmaDesc
[Index
].End
= 1;
994 Create a new TRB for the SD cmd request.
996 @param[in] Slot The slot number of the SD card to send the command to.
997 @param[in] Packet A pointer to the SD command data structure.
999 @return Created Trb or NULL.
1004 IN SD_PEIM_HC_SLOT
*Slot
,
1005 IN SD_COMMAND_PACKET
*Packet
1010 SD_HC_SLOT_CAP Capability
;
1011 EDKII_IOMMU_OPERATION MapOp
;
1015 // Calculate a divisor for SD clock frequency
1017 Status
= SdPeimHcGetCapability (Slot
->SdHcBase
, &Capability
);
1018 if (EFI_ERROR (Status
)) {
1022 Trb
= AllocateZeroPool (sizeof (SD_TRB
));
1028 Trb
->BlockSize
= 0x200;
1029 Trb
->Packet
= Packet
;
1030 Trb
->Timeout
= Packet
->Timeout
;
1032 if ((Packet
->InTransferLength
!= 0) && (Packet
->InDataBuffer
!= NULL
)) {
1033 Trb
->Data
= Packet
->InDataBuffer
;
1034 Trb
->DataLen
= Packet
->InTransferLength
;
1036 } else if ((Packet
->OutTransferLength
!= 0) && (Packet
->OutDataBuffer
!= NULL
)) {
1037 Trb
->Data
= Packet
->OutDataBuffer
;
1038 Trb
->DataLen
= Packet
->OutTransferLength
;
1040 } else if ((Packet
->InTransferLength
== 0) && (Packet
->OutTransferLength
== 0)) {
1047 if ((Trb
->DataLen
!= 0) && (Trb
->DataLen
< Trb
->BlockSize
)) {
1048 Trb
->BlockSize
= (UINT16
)Trb
->DataLen
;
1051 if (Packet
->SdCmdBlk
->CommandIndex
== SD_SEND_TUNING_BLOCK
) {
1052 Trb
->Mode
= SdPioMode
;
1055 MapOp
= EdkiiIoMmuOperationBusMasterWrite
;
1057 MapOp
= EdkiiIoMmuOperationBusMasterRead
;
1060 if (Trb
->DataLen
!= 0) {
1061 MapLength
= Trb
->DataLen
;
1062 Status
= IoMmuMap (MapOp
, Trb
->Data
, &MapLength
, &Trb
->DataPhy
, &Trb
->DataMap
);
1064 if (EFI_ERROR (Status
) || (MapLength
!= Trb
->DataLen
)) {
1065 DEBUG ((DEBUG_ERROR
, "SdPeimCreateTrb: Fail to map data buffer.\n"));
1070 if (Trb
->DataLen
== 0) {
1071 Trb
->Mode
= SdNoData
;
1072 } else if (Capability
.Adma2
!= 0) {
1073 Trb
->Mode
= SdAdmaMode
;
1074 Status
= BuildAdmaDescTable (Trb
);
1075 if (EFI_ERROR (Status
)) {
1078 } else if (Capability
.Sdma
!= 0) {
1079 Trb
->Mode
= SdSdmaMode
;
1081 Trb
->Mode
= SdPioMode
;
1088 SdPeimFreeTrb (Trb
);
1093 Free the resource used by the TRB.
1095 @param[in] Trb The pointer to the SD_TRB instance.
1103 if ((Trb
!= NULL
) && (Trb
->DataMap
!= NULL
)) {
1104 IoMmuUnmap (Trb
->DataMap
);
1107 if ((Trb
!= NULL
) && (Trb
->AdmaDesc
!= NULL
)) {
1108 SdPeimFreeMem (Trb
->Slot
->Private
->Pool
, Trb
->AdmaDesc
, Trb
->AdmaDescSize
);
1119 Check if the env is ready for execute specified TRB.
1121 @param[in] Bar The mmio base address of the slot to be accessed.
1122 @param[in] Trb The pointer to the SD_TRB instance.
1124 @retval EFI_SUCCESS The env is ready for TRB execution.
1125 @retval EFI_NOT_READY The env is not ready for TRB execution.
1126 @retval Others Some erros happen.
1136 SD_COMMAND_PACKET
*Packet
;
1137 UINT32 PresentState
;
1139 Packet
= Trb
->Packet
;
1141 if ((Packet
->SdCmdBlk
->CommandType
== SdCommandTypeAdtc
) ||
1142 (Packet
->SdCmdBlk
->ResponseType
== SdResponseTypeR1b
) ||
1143 (Packet
->SdCmdBlk
->ResponseType
== SdResponseTypeR5b
))
1146 // Wait Command Inhibit (CMD) and Command Inhibit (DAT) in
1147 // the Present State register to be 0
1149 PresentState
= BIT0
| BIT1
;
1152 // Wait Command Inhibit (CMD) in the Present State register
1155 PresentState
= BIT0
;
1158 Status
= SdPeimHcCheckMmioSet (
1159 Bar
+ SD_HC_PRESENT_STATE
,
1160 sizeof (PresentState
),
1169 Wait for the env to be ready for execute specified TRB.
1171 @param[in] Bar The mmio base address of the slot to be accessed.
1172 @param[in] Trb The pointer to the SD_TRB instance.
1174 @retval EFI_SUCCESS The env is ready for TRB execution.
1175 @retval EFI_TIMEOUT The env is not ready for TRB execution in time.
1176 @retval Others Some erros happen.
1186 SD_COMMAND_PACKET
*Packet
;
1188 BOOLEAN InfiniteWait
;
1191 // Wait Command Complete Interrupt Status bit in Normal Interrupt Status Register
1193 Packet
= Trb
->Packet
;
1194 Timeout
= Packet
->Timeout
;
1196 InfiniteWait
= TRUE
;
1198 InfiniteWait
= FALSE
;
1201 while (InfiniteWait
|| (Timeout
> 0)) {
1203 // Check Trb execution result by reading Normal Interrupt Status register.
1205 Status
= SdPeimCheckTrbEnv (Bar
, Trb
);
1206 if (Status
!= EFI_NOT_READY
) {
1211 // Stall for 1 microsecond.
1213 MicroSecondDelay (1);
1222 Execute the specified TRB.
1224 @param[in] Bar The mmio base address of the slot to be accessed.
1225 @param[in] Trb The pointer to the SD_TRB instance.
1227 @retval EFI_SUCCESS The TRB is sent to host controller successfully.
1228 @retval Others Some erros happen when sending this request to the host controller.
1238 SD_COMMAND_PACKET
*Packet
;
1249 Packet
= Trb
->Packet
;
1251 // Clear all bits in Error Interrupt Status Register
1254 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_ERR_INT_STS
, FALSE
, sizeof (IntStatus
), &IntStatus
);
1255 if (EFI_ERROR (Status
)) {
1260 // Clear all bits in Normal Interrupt Status Register
1263 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_NOR_INT_STS
, FALSE
, sizeof (IntStatus
), &IntStatus
);
1264 if (EFI_ERROR (Status
)) {
1269 // Set Host Control 1 register DMA Select field
1271 if (Trb
->Mode
== SdAdmaMode
) {
1273 Status
= SdPeimHcOrMmio (Bar
+ SD_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
1274 if (EFI_ERROR (Status
)) {
1279 SdPeimHcLedOnOff (Bar
, TRUE
);
1281 if (Trb
->Mode
== SdSdmaMode
) {
1282 if ((UINT64
)(UINTN
)Trb
->DataPhy
>= 0x100000000ul
) {
1283 return EFI_INVALID_PARAMETER
;
1286 SdmaAddr
= (UINT32
)(UINTN
)Trb
->DataPhy
;
1287 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_SDMA_ADDR
, FALSE
, sizeof (SdmaAddr
), &SdmaAddr
);
1288 if (EFI_ERROR (Status
)) {
1291 } else if (Trb
->Mode
== SdAdmaMode
) {
1292 AdmaAddr
= (UINT64
)(UINTN
)Trb
->AdmaDesc
;
1293 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_ADMA_SYS_ADDR
, FALSE
, sizeof (AdmaAddr
), &AdmaAddr
);
1294 if (EFI_ERROR (Status
)) {
1299 BlkSize
= Trb
->BlockSize
;
1300 if (Trb
->Mode
== SdSdmaMode
) {
1302 // Set SDMA boundary to be 512K bytes.
1307 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_BLK_SIZE
, FALSE
, sizeof (BlkSize
), &BlkSize
);
1308 if (EFI_ERROR (Status
)) {
1313 if (Trb
->Mode
!= SdNoData
) {
1315 // Calculate Block Count.
1317 BlkCount
= (UINT16
)(Trb
->DataLen
/ Trb
->BlockSize
);
1320 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_BLK_COUNT
, FALSE
, sizeof (BlkCount
), &BlkCount
);
1321 if (EFI_ERROR (Status
)) {
1325 Argument
= Packet
->SdCmdBlk
->CommandArgument
;
1326 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_ARG1
, FALSE
, sizeof (Argument
), &Argument
);
1327 if (EFI_ERROR (Status
)) {
1332 if (Trb
->Mode
!= SdNoData
) {
1333 if (Trb
->Mode
!= SdPioMode
) {
1342 TransMode
|= BIT5
| BIT1
;
1346 // SD memory card needs to use AUTO CMD12 feature.
1353 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_TRANS_MOD
, FALSE
, sizeof (TransMode
), &TransMode
);
1354 if (EFI_ERROR (Status
)) {
1358 Cmd
= (UINT16
)LShiftU64 (Packet
->SdCmdBlk
->CommandIndex
, 8);
1359 if (Packet
->SdCmdBlk
->CommandType
== SdCommandTypeAdtc
) {
1364 // Convert ResponseType to value
1366 if (Packet
->SdCmdBlk
->CommandType
!= SdCommandTypeBc
) {
1367 switch (Packet
->SdCmdBlk
->ResponseType
) {
1368 case SdResponseTypeR1
:
1369 case SdResponseTypeR5
:
1370 case SdResponseTypeR6
:
1371 case SdResponseTypeR7
:
1372 Cmd
|= (BIT1
| BIT3
| BIT4
);
1374 case SdResponseTypeR2
:
1375 Cmd
|= (BIT0
| BIT3
);
1377 case SdResponseTypeR3
:
1378 case SdResponseTypeR4
:
1381 case SdResponseTypeR1b
:
1382 case SdResponseTypeR5b
:
1383 Cmd
|= (BIT0
| BIT1
| BIT3
| BIT4
);
1394 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_COMMAND
, FALSE
, sizeof (Cmd
), &Cmd
);
1399 Check the TRB execution result.
1401 @param[in] Bar The mmio base address of the slot to be accessed.
1402 @param[in] Trb The pointer to the SD_TRB instance.
1404 @retval EFI_SUCCESS The TRB is executed successfully.
1405 @retval EFI_NOT_READY The TRB is not completed for execution.
1406 @retval Others Some erros happen when executing this request.
1410 SdPeimCheckTrbResult (
1416 SD_COMMAND_PACKET
*Packet
;
1425 Packet
= Trb
->Packet
;
1427 // Check Trb execution result by reading Normal Interrupt Status register.
1429 Status
= SdPeimHcRwMmio (
1430 Bar
+ SD_HC_NOR_INT_STS
,
1435 if (EFI_ERROR (Status
)) {
1440 // Check Transfer Complete bit is set or not.
1442 if ((IntStatus
& BIT1
) == BIT1
) {
1443 if ((IntStatus
& BIT15
) == BIT15
) {
1445 // Read Error Interrupt Status register to check if the error is
1446 // Data Timeout Error.
1447 // If yes, treat it as success as Transfer Complete has higher
1448 // priority than Data Timeout Error.
1450 Status
= SdPeimHcRwMmio (
1451 Bar
+ SD_HC_ERR_INT_STS
,
1456 if (!EFI_ERROR (Status
)) {
1457 if ((IntStatus
& BIT4
) == BIT4
) {
1458 Status
= EFI_SUCCESS
;
1460 Status
= EFI_DEVICE_ERROR
;
1469 // Check if there is a error happened during cmd execution.
1470 // If yes, then do error recovery procedure to follow SD Host Controller
1471 // Simplified Spec 3.0 section 3.10.1.
1473 if ((IntStatus
& BIT15
) == BIT15
) {
1474 Status
= SdPeimHcRwMmio (
1475 Bar
+ SD_HC_ERR_INT_STS
,
1480 if (EFI_ERROR (Status
)) {
1484 if ((IntStatus
& 0x0F) != 0) {
1488 if ((IntStatus
& 0xF0) != 0) {
1492 Status
= SdPeimHcRwMmio (
1498 if (EFI_ERROR (Status
)) {
1502 Status
= SdPeimHcWaitMmioSet (
1509 if (EFI_ERROR (Status
)) {
1513 Status
= EFI_DEVICE_ERROR
;
1518 // Check if DMA interrupt is signalled for the SDMA transfer.
1520 if ((Trb
->Mode
== SdSdmaMode
) && ((IntStatus
& BIT3
) == BIT3
)) {
1522 // Clear DMA interrupt bit.
1525 Status
= SdPeimHcRwMmio (
1526 Bar
+ SD_HC_NOR_INT_STS
,
1531 if (EFI_ERROR (Status
)) {
1536 // Update SDMA Address register.
1538 SdmaAddr
= SD_SDMA_ROUND_UP ((UINT32
)(UINTN
)Trb
->DataPhy
, SD_SDMA_BOUNDARY
);
1539 Status
= SdPeimHcRwMmio (
1540 Bar
+ SD_HC_SDMA_ADDR
,
1545 if (EFI_ERROR (Status
)) {
1549 Trb
->DataPhy
= (UINT32
)(UINTN
)SdmaAddr
;
1552 if ((Packet
->SdCmdBlk
->CommandType
!= SdCommandTypeAdtc
) &&
1553 (Packet
->SdCmdBlk
->ResponseType
!= SdResponseTypeR1b
) &&
1554 (Packet
->SdCmdBlk
->ResponseType
!= SdResponseTypeR5b
))
1556 if ((IntStatus
& BIT0
) == BIT0
) {
1557 Status
= EFI_SUCCESS
;
1562 if (Packet
->SdCmdBlk
->CommandIndex
== SD_SEND_TUNING_BLOCK
) {
1564 // When performing tuning procedure (Execute Tuning is set to 1) through PIO mode,
1565 // wait Buffer Read Ready bit of Normal Interrupt Status Register to be 1.
1566 // Refer to SD Host Controller Simplified Specification 3.0 figure 2-29 for details.
1568 if ((IntStatus
& BIT5
) == BIT5
) {
1570 // Clear Buffer Read Ready interrupt at first.
1573 SdPeimHcRwMmio (Bar
+ SD_HC_NOR_INT_STS
, FALSE
, sizeof (IntStatus
), &IntStatus
);
1575 // Read data out from Buffer Port register
1577 for (PioLength
= 0; PioLength
< Trb
->DataLen
; PioLength
+= 4) {
1578 SdPeimHcRwMmio (Bar
+ SD_HC_BUF_DAT_PORT
, TRUE
, 4, (UINT8
*)Trb
->Data
+ PioLength
);
1581 Status
= EFI_SUCCESS
;
1586 Status
= EFI_NOT_READY
;
1589 // Get response data when the cmd is executed successfully.
1591 if (!EFI_ERROR (Status
)) {
1592 if (Packet
->SdCmdBlk
->CommandType
!= SdCommandTypeBc
) {
1593 for (Index
= 0; Index
< 4; Index
++) {
1594 Status
= SdPeimHcRwMmio (
1595 Bar
+ SD_HC_RESPONSE
+ Index
* 4,
1600 if (EFI_ERROR (Status
)) {
1601 SdPeimHcLedOnOff (Bar
, FALSE
);
1606 CopyMem (Packet
->SdStatusBlk
, Response
, sizeof (Response
));
1610 if (Status
!= EFI_NOT_READY
) {
1611 SdPeimHcLedOnOff (Bar
, FALSE
);
1618 Wait for the TRB execution result.
1620 @param[in] Bar The mmio base address of the slot to be accessed.
1621 @param[in] Trb The pointer to the SD_TRB instance.
1623 @retval EFI_SUCCESS The TRB is executed successfully.
1624 @retval Others Some erros happen when executing this request.
1628 SdPeimWaitTrbResult (
1634 SD_COMMAND_PACKET
*Packet
;
1636 BOOLEAN InfiniteWait
;
1638 Packet
= Trb
->Packet
;
1640 // Wait Command Complete Interrupt Status bit in Normal Interrupt Status Register
1642 Timeout
= Packet
->Timeout
;
1644 InfiniteWait
= TRUE
;
1646 InfiniteWait
= FALSE
;
1649 while (InfiniteWait
|| (Timeout
> 0)) {
1651 // Check Trb execution result by reading Normal Interrupt Status register.
1653 Status
= SdPeimCheckTrbResult (Bar
, Trb
);
1654 if (Status
!= EFI_NOT_READY
) {
1659 // Stall for 1 microsecond.
1661 MicroSecondDelay (1);
1670 Sends SD command to an SD card that is attached to the SD controller.
1672 If Packet is successfully sent to the SD card, then EFI_SUCCESS is returned.
1674 If a device error occurs while sending the Packet, then EFI_DEVICE_ERROR is returned.
1676 If Slot is not in a valid range for the SD controller, then EFI_INVALID_PARAMETER
1679 If Packet defines a data command but both InDataBuffer and OutDataBuffer are NULL,
1680 EFI_INVALID_PARAMETER is returned.
1682 @param[in] Slot The slot number of the Sd card to send the command to.
1683 @param[in,out] Packet A pointer to the SD command data structure.
1685 @retval EFI_SUCCESS The SD Command Packet was sent by the host.
1686 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send the SD
1688 @retval EFI_INVALID_PARAMETER Packet, Slot, or the contents of the Packet is invalid.
1689 @retval EFI_INVALID_PARAMETER Packet defines a data command but both InDataBuffer and
1690 OutDataBuffer are NULL.
1691 @retval EFI_NO_MEDIA SD Device not present in the Slot.
1692 @retval EFI_UNSUPPORTED The command described by the SD Command Packet is not
1693 supported by the host controller.
1694 @retval EFI_BAD_BUFFER_SIZE The InTransferLength or OutTransferLength exceeds the
1695 limit supported by SD card ( i.e. if the number of bytes
1696 exceed the Last LBA).
1702 IN SD_PEIM_HC_SLOT
*Slot
,
1703 IN OUT SD_COMMAND_PACKET
*Packet
1709 if (Packet
== NULL
) {
1710 return EFI_INVALID_PARAMETER
;
1713 if ((Packet
->SdCmdBlk
== NULL
) || (Packet
->SdStatusBlk
== NULL
)) {
1714 return EFI_INVALID_PARAMETER
;
1717 if ((Packet
->OutDataBuffer
== NULL
) && (Packet
->OutTransferLength
!= 0)) {
1718 return EFI_INVALID_PARAMETER
;
1721 if ((Packet
->InDataBuffer
== NULL
) && (Packet
->InTransferLength
!= 0)) {
1722 return EFI_INVALID_PARAMETER
;
1725 Trb
= SdPeimCreateTrb (Slot
, Packet
);
1727 return EFI_OUT_OF_RESOURCES
;
1730 Status
= SdPeimWaitTrbEnv (Slot
->SdHcBase
, Trb
);
1731 if (EFI_ERROR (Status
)) {
1735 Status
= SdPeimExecTrb (Slot
->SdHcBase
, Trb
);
1736 if (EFI_ERROR (Status
)) {
1740 Status
= SdPeimWaitTrbResult (Slot
->SdHcBase
, Trb
);
1741 if (EFI_ERROR (Status
)) {
1746 SdPeimFreeTrb (Trb
);
1752 Send command GO_IDLE_STATE to the device to make it go to Idle State.
1754 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
1756 @param[in] Slot The slot number of the SD card to send the command to.
1758 @retval EFI_SUCCESS The SD device is reset correctly.
1759 @retval Others The device reset fails.
1764 IN SD_PEIM_HC_SLOT
*Slot
1767 SD_COMMAND_BLOCK SdCmdBlk
;
1768 SD_STATUS_BLOCK SdStatusBlk
;
1769 SD_COMMAND_PACKET Packet
;
1772 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
1773 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
1774 ZeroMem (&Packet
, sizeof (Packet
));
1776 Packet
.SdCmdBlk
= &SdCmdBlk
;
1777 Packet
.SdStatusBlk
= &SdStatusBlk
;
1778 Packet
.Timeout
= SD_TIMEOUT
;
1780 SdCmdBlk
.CommandIndex
= SD_GO_IDLE_STATE
;
1781 SdCmdBlk
.CommandType
= SdCommandTypeBc
;
1782 SdCmdBlk
.ResponseType
= 0;
1783 SdCmdBlk
.CommandArgument
= 0;
1785 Status
= SdPeimExecCmd (Slot
, &Packet
);
1791 Send command SEND_IF_COND to the device to inquiry the SD Memory Card interface
1794 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
1796 @param[in] Slot The slot number of the SD card to send the command to.
1797 @param[in] SupplyVoltage The supplied voltage by the host.
1798 @param[in] CheckPattern The check pattern to be sent to the device.
1800 @retval EFI_SUCCESS The operation is done correctly.
1801 @retval Others The operation fails.
1805 SdPeimVoltageCheck (
1806 IN SD_PEIM_HC_SLOT
*Slot
,
1807 IN UINT8 SupplyVoltage
,
1808 IN UINT8 CheckPattern
1811 SD_COMMAND_BLOCK SdCmdBlk
;
1812 SD_STATUS_BLOCK SdStatusBlk
;
1813 SD_COMMAND_PACKET Packet
;
1816 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
1817 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
1818 ZeroMem (&Packet
, sizeof (Packet
));
1820 Packet
.SdCmdBlk
= &SdCmdBlk
;
1821 Packet
.SdStatusBlk
= &SdStatusBlk
;
1822 Packet
.Timeout
= SD_TIMEOUT
;
1824 SdCmdBlk
.CommandIndex
= SD_SEND_IF_COND
;
1825 SdCmdBlk
.CommandType
= SdCommandTypeBcr
;
1826 SdCmdBlk
.ResponseType
= SdResponseTypeR7
;
1827 SdCmdBlk
.CommandArgument
= (SupplyVoltage
<< 8) | CheckPattern
;
1829 Status
= SdPeimExecCmd (Slot
, &Packet
);
1830 if (!EFI_ERROR (Status
)) {
1831 if (SdStatusBlk
.Resp0
!= SdCmdBlk
.CommandArgument
) {
1832 return EFI_DEVICE_ERROR
;
1840 Send command SDIO_SEND_OP_COND to the device to see whether it is SDIO device.
1842 Refer to SDIO Simplified Spec 3 Section 3.2 for details.
1844 @param[in] Slot The slot number of the SD card to send the command to.
1845 @param[in] VoltageWindow The supply voltage window.
1846 @param[in] S18r The boolean to show if it should switch to 1.8v.
1848 @retval EFI_SUCCESS The operation is done correctly.
1849 @retval Others The operation fails.
1854 IN SD_PEIM_HC_SLOT
*Slot
,
1855 IN UINT32 VoltageWindow
,
1859 SD_COMMAND_BLOCK SdCmdBlk
;
1860 SD_STATUS_BLOCK SdStatusBlk
;
1861 SD_COMMAND_PACKET Packet
;
1865 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
1866 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
1867 ZeroMem (&Packet
, sizeof (Packet
));
1869 Packet
.SdCmdBlk
= &SdCmdBlk
;
1870 Packet
.SdStatusBlk
= &SdStatusBlk
;
1871 Packet
.Timeout
= SD_TIMEOUT
;
1873 SdCmdBlk
.CommandIndex
= SDIO_SEND_OP_COND
;
1874 SdCmdBlk
.CommandType
= SdCommandTypeBcr
;
1875 SdCmdBlk
.ResponseType
= SdResponseTypeR4
;
1877 Switch
= S18r
? BIT24
: 0;
1879 SdCmdBlk
.CommandArgument
= (VoltageWindow
& 0xFFFFFF) | Switch
;
1881 Status
= SdPeimExecCmd (Slot
, &Packet
);
1887 Send command SD_SEND_OP_COND to the device to see whether it is SDIO device.
1889 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
1891 @param[in] Slot The slot number of the SD card to send the command to.
1892 @param[in] Rca The relative device address of addressed device.
1893 @param[in] VoltageWindow The supply voltage window.
1894 @param[in] S18r The boolean to show if it should switch to 1.8v.
1895 @param[in] Xpc The boolean to show if it should provide 0.36w power control.
1896 @param[in] Hcs The boolean to show if it support host capacity info.
1897 @param[out] Ocr The buffer to store returned OCR register value.
1900 @retval EFI_SUCCESS The operation is done correctly.
1901 @retval Others The operation fails.
1906 IN SD_PEIM_HC_SLOT
*Slot
,
1908 IN UINT32 VoltageWindow
,
1915 SD_COMMAND_BLOCK SdCmdBlk
;
1916 SD_STATUS_BLOCK SdStatusBlk
;
1917 SD_COMMAND_PACKET Packet
;
1921 UINT32 HostCapacity
;
1923 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
1924 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
1925 ZeroMem (&Packet
, sizeof (Packet
));
1927 Packet
.SdCmdBlk
= &SdCmdBlk
;
1928 Packet
.SdStatusBlk
= &SdStatusBlk
;
1929 Packet
.Timeout
= SD_TIMEOUT
;
1931 SdCmdBlk
.CommandIndex
= SD_APP_CMD
;
1932 SdCmdBlk
.CommandType
= SdCommandTypeAc
;
1933 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
1934 SdCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
1936 Status
= SdPeimExecCmd (Slot
, &Packet
);
1937 if (EFI_ERROR (Status
)) {
1941 SdCmdBlk
.CommandIndex
= SD_SEND_OP_COND
;
1942 SdCmdBlk
.CommandType
= SdCommandTypeBcr
;
1943 SdCmdBlk
.ResponseType
= SdResponseTypeR3
;
1945 Switch
= S18r
? BIT24
: 0;
1946 MaxPower
= Xpc
? BIT28
: 0;
1947 HostCapacity
= Hcs
? BIT30
: 0;
1948 SdCmdBlk
.CommandArgument
= (VoltageWindow
& 0xFFFFFF) | Switch
| MaxPower
| HostCapacity
;
1950 Status
= SdPeimExecCmd (Slot
, &Packet
);
1951 if (!EFI_ERROR (Status
)) {
1953 // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12.
1955 *Ocr
= SdStatusBlk
.Resp0
;
1962 Broadcast command ALL_SEND_CID to the bus to ask all the SD devices to send the
1963 data of their CID registers.
1965 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
1967 @param[in] Slot The slot number of the SD card to send the command to.
1969 @retval EFI_SUCCESS The operation is done correctly.
1970 @retval Others The operation fails.
1975 IN SD_PEIM_HC_SLOT
*Slot
1978 SD_COMMAND_BLOCK SdCmdBlk
;
1979 SD_STATUS_BLOCK SdStatusBlk
;
1980 SD_COMMAND_PACKET Packet
;
1983 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
1984 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
1985 ZeroMem (&Packet
, sizeof (Packet
));
1987 Packet
.SdCmdBlk
= &SdCmdBlk
;
1988 Packet
.SdStatusBlk
= &SdStatusBlk
;
1989 Packet
.Timeout
= SD_TIMEOUT
;
1991 SdCmdBlk
.CommandIndex
= SD_ALL_SEND_CID
;
1992 SdCmdBlk
.CommandType
= SdCommandTypeBcr
;
1993 SdCmdBlk
.ResponseType
= SdResponseTypeR2
;
1994 SdCmdBlk
.CommandArgument
= 0;
1996 Status
= SdPeimExecCmd (Slot
, &Packet
);
2002 Send command SET_RELATIVE_ADDR to the SD device to assign a Relative device
2005 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
2007 @param[in] Slot The slot number of the SD card to send the command to.
2008 @param[out] Rca The relative device address to be assigned.
2010 @retval EFI_SUCCESS The operation is done correctly.
2011 @retval Others The operation fails.
2016 IN SD_PEIM_HC_SLOT
*Slot
,
2020 SD_COMMAND_BLOCK SdCmdBlk
;
2021 SD_STATUS_BLOCK SdStatusBlk
;
2022 SD_COMMAND_PACKET Packet
;
2025 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
2026 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
2027 ZeroMem (&Packet
, sizeof (Packet
));
2029 Packet
.SdCmdBlk
= &SdCmdBlk
;
2030 Packet
.SdStatusBlk
= &SdStatusBlk
;
2031 Packet
.Timeout
= SD_TIMEOUT
;
2033 SdCmdBlk
.CommandIndex
= SD_SET_RELATIVE_ADDR
;
2034 SdCmdBlk
.CommandType
= SdCommandTypeBcr
;
2035 SdCmdBlk
.ResponseType
= SdResponseTypeR6
;
2037 Status
= SdPeimExecCmd (Slot
, &Packet
);
2038 if (!EFI_ERROR (Status
)) {
2039 *Rca
= (UINT16
)(SdStatusBlk
.Resp0
>> 16);
2046 Send command SEND_CSD to the SD device to get the data of the CSD register.
2048 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
2050 @param[in] Slot The slot number of the SD card to send the command to.
2051 @param[in] Rca The relative device address of selected device.
2052 @param[out] Csd The buffer to store the content of the CSD register.
2053 Note the caller should ignore the lowest byte of this
2054 buffer as the content of this byte is meaningless even
2055 if the operation succeeds.
2057 @retval EFI_SUCCESS The operation is done correctly.
2058 @retval Others The operation fails.
2063 IN SD_PEIM_HC_SLOT
*Slot
,
2068 SD_COMMAND_BLOCK SdCmdBlk
;
2069 SD_STATUS_BLOCK SdStatusBlk
;
2070 SD_COMMAND_PACKET Packet
;
2073 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
2074 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
2075 ZeroMem (&Packet
, sizeof (Packet
));
2077 Packet
.SdCmdBlk
= &SdCmdBlk
;
2078 Packet
.SdStatusBlk
= &SdStatusBlk
;
2079 Packet
.Timeout
= SD_TIMEOUT
;
2081 SdCmdBlk
.CommandIndex
= SD_SEND_CSD
;
2082 SdCmdBlk
.CommandType
= SdCommandTypeAc
;
2083 SdCmdBlk
.ResponseType
= SdResponseTypeR2
;
2084 SdCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
2086 Status
= SdPeimExecCmd (Slot
, &Packet
);
2087 if (!EFI_ERROR (Status
)) {
2089 // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12.
2091 CopyMem (((UINT8
*)Csd
) + 1, &SdStatusBlk
.Resp0
, sizeof (SD_CSD
) - 1);
2098 Send command SELECT_DESELECT_CARD to the SD device to select/deselect it.
2100 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
2102 @param[in] Slot The slot number of the SD card to send the command to.
2103 @param[in] Rca The relative device address of selected device.
2105 @retval EFI_SUCCESS The operation is done correctly.
2106 @retval Others The operation fails.
2111 IN SD_PEIM_HC_SLOT
*Slot
,
2115 SD_COMMAND_BLOCK SdCmdBlk
;
2116 SD_STATUS_BLOCK SdStatusBlk
;
2117 SD_COMMAND_PACKET Packet
;
2120 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
2121 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
2122 ZeroMem (&Packet
, sizeof (Packet
));
2124 Packet
.SdCmdBlk
= &SdCmdBlk
;
2125 Packet
.SdStatusBlk
= &SdStatusBlk
;
2126 Packet
.Timeout
= SD_TIMEOUT
;
2128 SdCmdBlk
.CommandIndex
= SD_SELECT_DESELECT_CARD
;
2129 SdCmdBlk
.CommandType
= SdCommandTypeAc
;
2130 SdCmdBlk
.ResponseType
= SdResponseTypeR1b
;
2131 SdCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
2133 Status
= SdPeimExecCmd (Slot
, &Packet
);
2139 Send command VOLTAGE_SWITCH to the SD device to switch the voltage of the device.
2141 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
2143 @param[in] Slot The slot number of the SD card to send the command to.
2145 @retval EFI_SUCCESS The operation is done correctly.
2146 @retval Others The operation fails.
2150 SdPeimVoltageSwitch (
2151 IN SD_PEIM_HC_SLOT
*Slot
2154 SD_COMMAND_BLOCK SdCmdBlk
;
2155 SD_STATUS_BLOCK SdStatusBlk
;
2156 SD_COMMAND_PACKET Packet
;
2159 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
2160 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
2161 ZeroMem (&Packet
, sizeof (Packet
));
2163 Packet
.SdCmdBlk
= &SdCmdBlk
;
2164 Packet
.SdStatusBlk
= &SdStatusBlk
;
2165 Packet
.Timeout
= SD_TIMEOUT
;
2167 SdCmdBlk
.CommandIndex
= SD_VOLTAGE_SWITCH
;
2168 SdCmdBlk
.CommandType
= SdCommandTypeAc
;
2169 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2170 SdCmdBlk
.CommandArgument
= 0;
2172 Status
= SdPeimExecCmd (Slot
, &Packet
);
2178 Send command SET_BUS_WIDTH to the SD device to set the bus width.
2180 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
2182 @param[in] Slot The slot number of the SD card to send the command to.
2183 @param[in] Rca The relative device address of addressed device.
2184 @param[in] BusWidth The bus width to be set, it could be 1 or 4.
2186 @retval EFI_SUCCESS The operation is done correctly.
2187 @retval Others The operation fails.
2192 IN SD_PEIM_HC_SLOT
*Slot
,
2197 SD_COMMAND_BLOCK SdCmdBlk
;
2198 SD_STATUS_BLOCK SdStatusBlk
;
2199 SD_COMMAND_PACKET Packet
;
2203 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
2204 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
2205 ZeroMem (&Packet
, sizeof (Packet
));
2207 Packet
.SdCmdBlk
= &SdCmdBlk
;
2208 Packet
.SdStatusBlk
= &SdStatusBlk
;
2209 Packet
.Timeout
= SD_TIMEOUT
;
2211 SdCmdBlk
.CommandIndex
= SD_APP_CMD
;
2212 SdCmdBlk
.CommandType
= SdCommandTypeAc
;
2213 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2214 SdCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
2216 Status
= SdPeimExecCmd (Slot
, &Packet
);
2217 if (EFI_ERROR (Status
)) {
2221 SdCmdBlk
.CommandIndex
= SD_SET_BUS_WIDTH
;
2222 SdCmdBlk
.CommandType
= SdCommandTypeAc
;
2223 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2225 if (BusWidth
== 1) {
2227 } else if (BusWidth
== 4) {
2230 return EFI_INVALID_PARAMETER
;
2233 SdCmdBlk
.CommandArgument
= Value
& 0x3;
2235 Status
= SdPeimExecCmd (Slot
, &Packet
);
2241 Send command SWITCH_FUNC to the SD device to check switchable function or switch card function.
2243 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
2245 @param[in] Slot The slot number of the SD card to send the command to.
2246 @param[in] AccessMode The value for access mode group.
2247 @param[in] CommandSystem The value for command set group.
2248 @param[in] DriveStrength The value for drive length group.
2249 @param[in] PowerLimit The value for power limit group.
2250 @param[in] Mode Switch or check function.
2251 @param[out] SwitchResp The return switch function status.
2253 @retval EFI_SUCCESS The operation is done correctly.
2254 @retval Others The operation fails.
2259 IN SD_PEIM_HC_SLOT
*Slot
,
2260 IN UINT8 AccessMode
,
2261 IN UINT8 CommandSystem
,
2262 IN UINT8 DriveStrength
,
2263 IN UINT8 PowerLimit
,
2265 OUT UINT8
*SwitchResp
2268 SD_COMMAND_BLOCK SdCmdBlk
;
2269 SD_STATUS_BLOCK SdStatusBlk
;
2270 SD_COMMAND_PACKET Packet
;
2274 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
2275 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
2276 ZeroMem (&Packet
, sizeof (Packet
));
2278 Packet
.SdCmdBlk
= &SdCmdBlk
;
2279 Packet
.SdStatusBlk
= &SdStatusBlk
;
2280 Packet
.Timeout
= SD_TIMEOUT
;
2282 SdCmdBlk
.CommandIndex
= SD_SWITCH_FUNC
;
2283 SdCmdBlk
.CommandType
= SdCommandTypeAdtc
;
2284 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2286 ModeValue
= Mode
? BIT31
: 0;
2287 SdCmdBlk
.CommandArgument
= (AccessMode
& 0xF) | ((PowerLimit
& 0xF) << 4) | \
2288 ((DriveStrength
& 0xF) << 8) | ((DriveStrength
& 0xF) << 12) | \
2290 Packet
.InDataBuffer
= SwitchResp
;
2291 Packet
.InTransferLength
= 64;
2293 Status
= SdPeimExecCmd (Slot
, &Packet
);
2299 Send command SEND_STATUS to the addressed SD device to get its status register.
2301 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
2303 @param[in] Slot The slot number of the SD card to send the command to.
2304 @param[in] Rca The relative device address of addressed device.
2305 @param[out] DevStatus The returned device status.
2307 @retval EFI_SUCCESS The operation is done correctly.
2308 @retval Others The operation fails.
2313 IN SD_PEIM_HC_SLOT
*Slot
,
2315 OUT UINT32
*DevStatus
2318 SD_COMMAND_BLOCK SdCmdBlk
;
2319 SD_STATUS_BLOCK SdStatusBlk
;
2320 SD_COMMAND_PACKET Packet
;
2323 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
2324 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
2325 ZeroMem (&Packet
, sizeof (Packet
));
2327 Packet
.SdCmdBlk
= &SdCmdBlk
;
2328 Packet
.SdStatusBlk
= &SdStatusBlk
;
2329 Packet
.Timeout
= SD_TIMEOUT
;
2331 SdCmdBlk
.CommandIndex
= SD_SEND_STATUS
;
2332 SdCmdBlk
.CommandType
= SdCommandTypeAc
;
2333 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2334 SdCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
2336 Status
= SdPeimExecCmd (Slot
, &Packet
);
2337 if (!EFI_ERROR (Status
)) {
2338 *DevStatus
= SdStatusBlk
.Resp0
;
2345 Send command READ_SINGLE_BLOCK/WRITE_SINGLE_BLOCK to the addressed SD device
2346 to read/write the specified number of blocks.
2348 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
2350 @param[in] Slot The slot number of the SD card to send the command to.
2351 @param[in] Lba The logical block address of starting access.
2352 @param[in] BlockSize The block size of specified SD device partition.
2353 @param[in] Buffer The pointer to the transfer buffer.
2354 @param[in] BufferSize The size of transfer buffer.
2355 @param[in] IsRead Boolean to show the operation direction.
2357 @retval EFI_SUCCESS The operation is done correctly.
2358 @retval Others The operation fails.
2362 SdPeimRwSingleBlock (
2363 IN SD_PEIM_HC_SLOT
*Slot
,
2365 IN UINT32 BlockSize
,
2367 IN UINTN BufferSize
,
2371 SD_COMMAND_BLOCK SdCmdBlk
;
2372 SD_STATUS_BLOCK SdStatusBlk
;
2373 SD_COMMAND_PACKET Packet
;
2376 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
2377 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
2378 ZeroMem (&Packet
, sizeof (Packet
));
2380 Packet
.SdCmdBlk
= &SdCmdBlk
;
2381 Packet
.SdStatusBlk
= &SdStatusBlk
;
2383 // Calculate timeout value through the below formula.
2384 // Timeout = (transfer size) / (2MB/s).
2385 // Taking 2MB/s as divisor is because it's the lowest
2386 // transfer speed of class 2.
2388 Packet
.Timeout
= (BufferSize
/ (2 * 1024 * 1024) + 1) * 1000 * 1000;
2391 Packet
.InDataBuffer
= Buffer
;
2392 Packet
.InTransferLength
= (UINT32
)BufferSize
;
2394 SdCmdBlk
.CommandIndex
= SD_READ_SINGLE_BLOCK
;
2395 SdCmdBlk
.CommandType
= SdCommandTypeAdtc
;
2396 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2398 Packet
.OutDataBuffer
= Buffer
;
2399 Packet
.OutTransferLength
= (UINT32
)BufferSize
;
2401 SdCmdBlk
.CommandIndex
= SD_WRITE_SINGLE_BLOCK
;
2402 SdCmdBlk
.CommandType
= SdCommandTypeAdtc
;
2403 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2406 if (Slot
->SectorAddressing
) {
2407 SdCmdBlk
.CommandArgument
= (UINT32
)Lba
;
2409 SdCmdBlk
.CommandArgument
= (UINT32
)MultU64x32 (Lba
, BlockSize
);
2412 Status
= SdPeimExecCmd (Slot
, &Packet
);
2418 Send command READ_MULTIPLE_BLOCK/WRITE_MULTIPLE_BLOCK to the addressed SD device
2419 to read/write the specified number of blocks.
2421 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
2423 @param[in] Slot The slot number of the SD card to send the command to.
2424 @param[in] Lba The logical block address of starting access.
2425 @param[in] BlockSize The block size of specified SD device partition.
2426 @param[in] Buffer The pointer to the transfer buffer.
2427 @param[in] BufferSize The size of transfer buffer.
2428 @param[in] IsRead Boolean to show the operation direction.
2430 @retval EFI_SUCCESS The operation is done correctly.
2431 @retval Others The operation fails.
2435 SdPeimRwMultiBlocks (
2436 IN SD_PEIM_HC_SLOT
*Slot
,
2438 IN UINT32 BlockSize
,
2440 IN UINTN BufferSize
,
2444 SD_COMMAND_BLOCK SdCmdBlk
;
2445 SD_STATUS_BLOCK SdStatusBlk
;
2446 SD_COMMAND_PACKET Packet
;
2449 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
2450 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
2451 ZeroMem (&Packet
, sizeof (Packet
));
2453 Packet
.SdCmdBlk
= &SdCmdBlk
;
2454 Packet
.SdStatusBlk
= &SdStatusBlk
;
2456 // Calculate timeout value through the below formula.
2457 // Timeout = (transfer size) / (2MB/s).
2458 // Taking 2MB/s as divisor is because it's the lowest
2459 // transfer speed of class 2.
2461 Packet
.Timeout
= (BufferSize
/ (2 * 1024 * 1024) + 1) * 1000 * 1000;
2464 Packet
.InDataBuffer
= Buffer
;
2465 Packet
.InTransferLength
= (UINT32
)BufferSize
;
2467 SdCmdBlk
.CommandIndex
= SD_READ_MULTIPLE_BLOCK
;
2468 SdCmdBlk
.CommandType
= SdCommandTypeAdtc
;
2469 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2471 Packet
.OutDataBuffer
= Buffer
;
2472 Packet
.OutTransferLength
= (UINT32
)BufferSize
;
2474 SdCmdBlk
.CommandIndex
= SD_WRITE_MULTIPLE_BLOCK
;
2475 SdCmdBlk
.CommandType
= SdCommandTypeAdtc
;
2476 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2479 if (Slot
->SectorAddressing
) {
2480 SdCmdBlk
.CommandArgument
= (UINT32
)Lba
;
2482 SdCmdBlk
.CommandArgument
= (UINT32
)MultU64x32 (Lba
, BlockSize
);
2485 Status
= SdPeimExecCmd (Slot
, &Packet
);
2491 Send command SEND_TUNING_BLOCK to the SD device for SDR104/SDR50 optimal sampling point
2494 It may be sent up to 40 times until the host finishes the tuning procedure.
2496 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
2498 @param[in] Slot The slot number of the SD card to send the command to.
2500 @retval EFI_SUCCESS The operation is done correctly.
2501 @retval Others The operation fails.
2505 SdPeimSendTuningBlk (
2506 IN SD_PEIM_HC_SLOT
*Slot
2509 SD_COMMAND_BLOCK SdCmdBlk
;
2510 SD_STATUS_BLOCK SdStatusBlk
;
2511 SD_COMMAND_PACKET Packet
;
2513 UINT8 TuningBlock
[64];
2515 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
2516 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
2517 ZeroMem (&Packet
, sizeof (Packet
));
2519 Packet
.SdCmdBlk
= &SdCmdBlk
;
2520 Packet
.SdStatusBlk
= &SdStatusBlk
;
2521 Packet
.Timeout
= SD_TIMEOUT
;
2523 SdCmdBlk
.CommandIndex
= SD_SEND_TUNING_BLOCK
;
2524 SdCmdBlk
.CommandType
= SdCommandTypeAdtc
;
2525 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2526 SdCmdBlk
.CommandArgument
= 0;
2528 Packet
.InDataBuffer
= TuningBlock
;
2529 Packet
.InTransferLength
= sizeof (TuningBlock
);
2531 Status
= SdPeimExecCmd (Slot
, &Packet
);
2537 Tuning the sampling point of SDR104 or SDR50 bus speed mode.
2539 Command SD_SEND_TUNING_BLOCK may be sent up to 40 times until the host finishes the
2542 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and SD Host Controller
2543 Simplified Spec 3.0 Figure 2-29 for details.
2545 @param[in] Slot The slot number of the SD card to send the command to.
2547 @retval EFI_SUCCESS The operation is done correctly.
2548 @retval Others The operation fails.
2553 IN SD_PEIM_HC_SLOT
*Slot
2561 // Notify the host that the sampling clock tuning procedure starts.
2564 Status
= SdPeimHcOrMmio (Slot
->SdHcBase
+ SD_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2565 if (EFI_ERROR (Status
)) {
2570 // Ask the device to send a sequence of tuning blocks till the tuning procedure is done.
2574 Status
= SdPeimSendTuningBlk (Slot
);
2575 if (EFI_ERROR (Status
)) {
2579 Status
= SdPeimHcRwMmio (Slot
->SdHcBase
+ SD_HC_HOST_CTRL2
, TRUE
, sizeof (HostCtrl2
), &HostCtrl2
);
2580 if (EFI_ERROR (Status
)) {
2584 if ((HostCtrl2
& (BIT6
| BIT7
)) == 0) {
2588 if ((HostCtrl2
& (BIT6
| BIT7
)) == BIT7
) {
2591 } while (++Retry
< 40);
2593 DEBUG ((DEBUG_ERROR
, "SdPeimTuningClock: Send tuning block fails at %d times with HostCtrl2 %02x\n", Retry
, HostCtrl2
));
2595 // Abort the tuning procedure and reset the tuning circuit.
2597 HostCtrl2
= (UINT8
) ~(BIT6
| BIT7
);
2598 Status
= SdPeimHcAndMmio (Slot
->SdHcBase
+ SD_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2599 if (EFI_ERROR (Status
)) {
2603 return EFI_DEVICE_ERROR
;
2607 Switch the bus width to specified width.
2609 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and
2610 SD Host Controller Simplified Spec 3.0 section Figure 3-7 for details.
2612 @param[in] Slot The slot number of the SD card to send the command to.
2613 @param[in] Rca The relative device address to be assigned.
2614 @param[in] BusWidth The bus width to be set, it could be 4 or 8.
2616 @retval EFI_SUCCESS The operation is done correctly.
2617 @retval Others The operation fails.
2621 SdPeimSwitchBusWidth (
2622 IN SD_PEIM_HC_SLOT
*Slot
,
2630 Status
= SdPeimSetBusWidth (Slot
, Rca
, BusWidth
);
2631 if (EFI_ERROR (Status
)) {
2635 Status
= SdPeimSendStatus (Slot
, Rca
, &DevStatus
);
2636 if (EFI_ERROR (Status
)) {
2641 // Check the switch operation is really successful or not.
2643 if ((DevStatus
>> 16) != 0) {
2644 return EFI_DEVICE_ERROR
;
2647 Status
= SdPeimHcSetBusWidth (Slot
->SdHcBase
, BusWidth
);
2653 Switch the high speed timing according to request.
2655 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and
2656 SD Host Controller Simplified Spec 3.0 section Figure 2-29 for details.
2658 @param[in] Slot The slot number of the SD card to send the command to.
2659 @param[in] Rca The relative device address to be assigned.
2660 @param[in] S18a The boolean to show if it's a UHS-I SD card.
2662 @retval EFI_SUCCESS The operation is done correctly.
2663 @retval Others The operation fails.
2668 IN SD_PEIM_HC_SLOT
*Slot
,
2674 SD_HC_SLOT_CAP Capability
;
2680 UINT8 SwitchResp
[64];
2682 Status
= SdPeimGetCsd (Slot
, Rca
, &Slot
->Csd
);
2683 if (EFI_ERROR (Status
)) {
2684 DEBUG ((DEBUG_ERROR
, "SdPeimSetBusMode: SdPeimGetCsd fails with %r\n", Status
));
2688 Status
= SdPeimHcGetCapability (Slot
->SdHcBase
, &Capability
);
2689 if (EFI_ERROR (Status
)) {
2693 Status
= SdPeimSelect (Slot
, Rca
);
2694 if (EFI_ERROR (Status
)) {
2695 DEBUG ((DEBUG_ERROR
, "SdPeimSetBusMode: SdPeimSelect fails with %r\n", Status
));
2700 Status
= SdPeimSwitchBusWidth (Slot
, Rca
, BusWidth
);
2701 if (EFI_ERROR (Status
)) {
2702 DEBUG ((DEBUG_ERROR
, "SdPeimSetBusMode: SdPeimSwitchBusWidth fails with %r\n", Status
));
2707 // Get the supported bus speed from SWITCH cmd return data group #1.
2709 ZeroMem (SwitchResp
, sizeof (SwitchResp
));
2710 Status
= SdPeimSwitch (Slot
, 0xF, 0xF, 0xF, 0xF, FALSE
, SwitchResp
);
2711 if (EFI_ERROR (Status
)) {
2716 // Calculate supported bus speed/bus width/clock frequency by host and device capability.
2719 if (S18a
&& (Capability
.Sdr104
!= 0) && ((SwitchResp
[13] & BIT3
) != 0)) {
2722 } else if (S18a
&& (Capability
.Sdr50
!= 0) && ((SwitchResp
[13] & BIT2
) != 0)) {
2725 } else if (S18a
&& (Capability
.Ddr50
!= 0) && ((SwitchResp
[13] & BIT4
) != 0)) {
2728 } else if ((SwitchResp
[13] & BIT1
) != 0) {
2736 DEBUG ((DEBUG_INFO
, "SdPeimSetBusMode: AccessMode %d ClockFreq %d BusWidth %d\n", AccessMode
, ClockFreq
, BusWidth
));
2738 Status
= SdPeimSwitch (Slot
, AccessMode
, 0xF, 0xF, 0xF, TRUE
, SwitchResp
);
2739 if (EFI_ERROR (Status
)) {
2740 DEBUG ((DEBUG_ERROR
, "SdPeimSetBusMode: SdPeimSwitch fails with %r\n", Status
));
2744 if ((SwitchResp
[16] & 0xF) != AccessMode
) {
2745 DEBUG ((DEBUG_ERROR
, "SdPeimSetBusMode: SdPeimSwitch to AccessMode %d ClockFreq %d BusWidth %d fails! The Switch response is 0x%1x\n", AccessMode
, ClockFreq
, BusWidth
, SwitchResp
[16] & 0xF));
2746 return EFI_DEVICE_ERROR
;
2750 // Set to High Speed timing
2752 if (AccessMode
== 1) {
2754 Status
= SdPeimHcOrMmio (Slot
->SdHcBase
+ SD_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
2755 if (EFI_ERROR (Status
)) {
2760 HostCtrl2
= (UINT8
) ~0x7;
2761 Status
= SdPeimHcAndMmio (Slot
->SdHcBase
+ SD_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2762 if (EFI_ERROR (Status
)) {
2766 HostCtrl2
= AccessMode
;
2767 Status
= SdPeimHcOrMmio (Slot
->SdHcBase
+ SD_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2768 if (EFI_ERROR (Status
)) {
2772 Status
= SdPeimHcClockSupply (Slot
->SdHcBase
, ClockFreq
* 1000);
2773 if (EFI_ERROR (Status
)) {
2774 DEBUG ((DEBUG_ERROR
, "SdPeimSetBusMode: SdPeimHcClockSupply %r\n", Status
));
2778 if ((AccessMode
== 3) || ((AccessMode
== 2) && (Capability
.TuningSDR50
!= 0))) {
2779 Status
= SdPeimTuningClock (Slot
);
2780 if (EFI_ERROR (Status
)) {
2781 DEBUG ((DEBUG_ERROR
, "SdPeimSetBusMode: SdPeimTuningClock fails with %r\n", Status
));
2786 DEBUG ((DEBUG_INFO
, "SdPeimSetBusMode: SdPeimSetBusMode %r\n", Status
));
2792 Execute SD device identification procedure.
2794 Refer to SD Physical Layer Simplified Spec 4.1 Section 3.6 for details.
2796 @param[in] Slot The slot number of the SD card to send the command to.
2798 @retval EFI_SUCCESS There is a SD card.
2799 @retval Others There is not a SD card.
2803 SdPeimIdentification (
2804 IN SD_PEIM_HC_SLOT
*Slot
2814 UINT16 ControllerVer
;
2816 UINT32 PresentState
;
2818 SD_HC_SLOT_CAP Capability
;
2822 // 1. Send Cmd0 to the device
2824 Status
= SdPeimReset (Slot
);
2825 if (EFI_ERROR (Status
)) {
2826 DEBUG ((DEBUG_ERROR
, "SdPeimIdentification: Executing Cmd0 fails with %r\n", Status
));
2831 // 2. Send Cmd8 to the device
2833 Status
= SdPeimVoltageCheck (Slot
, 0x1, 0xFF);
2834 if (EFI_ERROR (Status
)) {
2835 DEBUG ((DEBUG_ERROR
, "SdPeimIdentification: Executing Cmd8 fails with %r\n", Status
));
2840 // 3. Send SDIO Cmd5 to the device to the SDIO device OCR register.
2842 Status
= SdioSendOpCond (Slot
, 0, FALSE
);
2843 if (!EFI_ERROR (Status
)) {
2844 DEBUG ((DEBUG_ERROR
, "SdPeimIdentification: Found SDIO device, ignore it as we don't support\n"));
2845 return EFI_DEVICE_ERROR
;
2849 // 4. Send Acmd41 with voltage window 0 to the device
2851 Status
= SdPeimSendOpCond (Slot
, 0, 0, FALSE
, FALSE
, FALSE
, &Ocr
);
2852 if (EFI_ERROR (Status
)) {
2853 DEBUG ((DEBUG_ERROR
, "SdPeimIdentification: Executing SdPeimSendOpCond fails with %r\n", Status
));
2854 return EFI_DEVICE_ERROR
;
2857 Status
= SdPeimHcGetCapability (Slot
->SdHcBase
, &Capability
);
2858 if (EFI_ERROR (Status
)) {
2862 Status
= SdPeimHcRwMmio (Slot
->SdHcBase
+ SD_HC_MAX_CURRENT_CAP
, TRUE
, sizeof (Current
), &Current
);
2863 if (EFI_ERROR (Status
)) {
2867 if (Capability
.Voltage33
!= 0) {
2871 MaxCurrent
= ((UINT32
)Current
& 0xFF) * 4;
2872 } else if (Capability
.Voltage30
!= 0) {
2876 MaxCurrent
= (((UINT32
)Current
>> 8) & 0xFF) * 4;
2877 } else if (Capability
.Voltage18
!= 0) {
2881 MaxCurrent
= (((UINT32
)Current
>> 16) & 0xFF) * 4;
2884 return EFI_DEVICE_ERROR
;
2887 if (MaxCurrent
>= 150) {
2893 Status
= SdPeimHcRwMmio (Slot
->SdHcBase
+ SD_HC_CTRL_VER
, TRUE
, sizeof (ControllerVer
), &ControllerVer
);
2894 if (EFI_ERROR (Status
)) {
2898 if ((ControllerVer
& 0xFF) == 2) {
2900 } else if (((ControllerVer
& 0xFF) == 0) || ((ControllerVer
& 0xFF) == 1)) {
2904 return EFI_UNSUPPORTED
;
2908 // 5. Repeatly send Acmd41 with supply voltage window to the device.
2909 // Note here we only support the cards complied with SD physical
2910 // layer simplified spec version 2.0 and version 3.0 and above.
2915 Status
= SdPeimSendOpCond (Slot
, 0, Ocr
, S18r
, Xpc
, TRUE
, &Ocr
);
2916 if (EFI_ERROR (Status
)) {
2917 DEBUG ((DEBUG_ERROR
, "SdPeimIdentification: SdPeimSendOpCond fails with %r Ocr %x, S18r %x, Xpc %x\n", Status
, Ocr
, S18r
, Xpc
));
2918 return EFI_DEVICE_ERROR
;
2921 if (Retry
++ == 100) {
2922 DEBUG ((DEBUG_ERROR
, "SdPeimIdentification: SdPeimSendOpCond fails too many times\n"));
2923 return EFI_DEVICE_ERROR
;
2926 MicroSecondDelay (10 * 1000);
2927 } while ((Ocr
& BIT31
) == 0);
2930 // 6. If the S18a bit is set and the Host Controller supports 1.8V signaling
2931 // (One of support bits is set to 1: SDR50, SDR104 or DDR50 in the
2932 // Capabilities register), switch its voltage to 1.8V.
2934 if (((Capability
.Sdr50
!= 0) ||
2935 (Capability
.Sdr104
!= 0) ||
2936 (Capability
.Ddr50
!= 0)) &&
2937 ((Ocr
& BIT24
) != 0))
2939 Status
= SdPeimVoltageSwitch (Slot
);
2940 if (EFI_ERROR (Status
)) {
2941 DEBUG ((DEBUG_ERROR
, "SdPeimIdentification: Executing SdPeimVoltageSwitch fails with %r\n", Status
));
2942 Status
= EFI_DEVICE_ERROR
;
2945 Status
= SdPeimHcStopClock (Slot
->SdHcBase
);
2946 if (EFI_ERROR (Status
)) {
2947 Status
= EFI_DEVICE_ERROR
;
2951 SdPeimHcRwMmio (Slot
->SdHcBase
+ SD_HC_PRESENT_STATE
, TRUE
, sizeof (PresentState
), &PresentState
);
2952 if (((PresentState
>> 20) & 0xF) != 0) {
2953 DEBUG ((DEBUG_ERROR
, "SdPeimIdentification: SwitchVoltage fails with PresentState = 0x%x\n", PresentState
));
2954 Status
= EFI_DEVICE_ERROR
;
2959 SdPeimHcOrMmio (Slot
->SdHcBase
+ SD_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2961 MicroSecondDelay (5000);
2963 SdPeimHcRwMmio (Slot
->SdHcBase
+ SD_HC_HOST_CTRL2
, TRUE
, sizeof (HostCtrl2
), &HostCtrl2
);
2964 if ((HostCtrl2
& BIT3
) == 0) {
2965 DEBUG ((DEBUG_ERROR
, "SdPeimIdentification: SwitchVoltage fails with HostCtrl2 = 0x%x\n", HostCtrl2
));
2966 Status
= EFI_DEVICE_ERROR
;
2970 SdPeimHcInitClockFreq (Slot
->SdHcBase
);
2972 MicroSecondDelay (1000);
2974 SdPeimHcRwMmio (Slot
->SdHcBase
+ SD_HC_PRESENT_STATE
, TRUE
, sizeof (PresentState
), &PresentState
);
2975 if (((PresentState
>> 20) & 0xF) != 0xF) {
2976 DEBUG ((DEBUG_ERROR
, "SdPeimIdentification: SwitchVoltage fails with PresentState = 0x%x, It should be 0xF\n", PresentState
));
2977 Status
= EFI_DEVICE_ERROR
;
2982 DEBUG ((DEBUG_INFO
, "SdPeimIdentification: Switch to 1.8v signal voltage success\n"));
2985 Status
= SdPeimAllSendCid (Slot
);
2986 if (EFI_ERROR (Status
)) {
2987 DEBUG ((DEBUG_ERROR
, "SdPeimIdentification: Executing SdPeimAllSendCid fails with %r\n", Status
));
2991 Status
= SdPeimSetRca (Slot
, &Rca
);
2992 if (EFI_ERROR (Status
)) {
2993 DEBUG ((DEBUG_ERROR
, "SdPeimIdentification: Executing SdPeimSetRca fails with %r\n", Status
));
2998 // Enter Data Tranfer Mode.
3000 DEBUG ((DEBUG_INFO
, "Found a SD device at slot [%d]\n", Slot
));
3002 Status
= SdPeimSetBusMode (Slot
, Rca
, ((Ocr
& BIT24
) != 0));
3008 // Set SD Bus Power = 0
3010 PowerCtrl
= (UINT8
) ~BIT0
;
3011 Status
= SdPeimHcAndMmio (Slot
->SdHcBase
+ SD_HC_POWER_CTRL
, sizeof (PowerCtrl
), &PowerCtrl
);
3012 return EFI_DEVICE_ERROR
;