3 Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php.
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14 #include "SdBlockIoPei.h"
17 Read/Write specified SD 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 SD 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
= SdPeimHcRwMmio (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
= SdPeimHcRwMmio (Address
, FALSE
, Count
, &Data
);
140 Do AND operation with the value of the specified SD 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
= SdPeimHcRwMmio (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
= SdPeimHcRwMmio (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 SdPeimHcCheckMmioSet (
217 // Access PCI MMIO space to see if the value is the tested one.
220 Status
= SdPeimHcRwMmio (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 SdPeimHcWaitMmioSet (
262 BOOLEAN InfiniteWait
;
267 InfiniteWait
= FALSE
;
270 while (InfiniteWait
|| (Timeout
> 0)) {
271 Status
= SdPeimHcCheckMmioSet (
277 if (Status
!= EFI_NOT_READY
) {
282 // Stall for 1 microsecond.
284 MicroSecondDelay (1);
293 Software reset the specified SD 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
= SdPeimHcRwMmio (Bar
+ SD_HC_SW_RST
, FALSE
, sizeof (SwReset
), &SwReset
);
312 if (EFI_ERROR (Status
)) {
313 DEBUG ((EFI_D_ERROR
, "SdPeimHcReset: write full 1 fails: %r\n", Status
));
317 Status
= SdPeimHcWaitMmioSet (
324 if (EFI_ERROR (Status
)) {
325 DEBUG ((EFI_D_INFO
, "SdPeimHcReset: reset done with %r\n", Status
));
329 // Enable all interrupt after reset all.
331 Status
= SdPeimHcEnableInterrupt (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 SdPeimHcEnableInterrupt (
355 // Enable all bits in Error Interrupt Status Enable Register
358 Status
= SdPeimHcRwMmio (Bar
+ SD_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
= 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
)) {
535 ASSERT (Capability
.BaseClkFreq
!= 0);
537 BaseClkFreq
= Capability
.BaseClkFreq
;
538 if ((ClockFreq
> (BaseClkFreq
* 1000)) || (ClockFreq
== 0)) {
539 return EFI_INVALID_PARAMETER
;
542 // Calculate the divisor of base frequency.
545 SettingFreq
= BaseClkFreq
* 1000;
546 while (ClockFreq
< SettingFreq
) {
549 SettingFreq
= (BaseClkFreq
* 1000) / (2 * Divisor
);
550 Remainder
= (BaseClkFreq
* 1000) % (2 * Divisor
);
551 if ((ClockFreq
== SettingFreq
) && (Remainder
== 0)) {
554 if ((ClockFreq
== SettingFreq
) && (Remainder
!= 0)) {
559 DEBUG ((EFI_D_INFO
, "BaseClkFreq %dMHz Divisor %d ClockFreq %dKhz\n", BaseClkFreq
, Divisor
, ClockFreq
));
561 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_CTRL_VER
, TRUE
, sizeof (ControllerVer
), &ControllerVer
);
562 if (EFI_ERROR (Status
)) {
566 // Set SDCLK Frequency Select and Internal Clock Enable fields in Clock Control register.
568 if ((ControllerVer
& 0xFF) == 2) {
569 ASSERT (Divisor
<= 0x3FF);
570 ClockCtrl
= ((Divisor
& 0xFF) << 8) | ((Divisor
& 0x300) >> 2);
571 } else if (((ControllerVer
& 0xFF) == 0) || ((ControllerVer
& 0xFF) == 1)) {
573 // Only the most significant bit can be used as divisor.
575 if (((Divisor
- 1) & Divisor
) != 0) {
576 Divisor
= 1 << (HighBitSet32 (Divisor
) + 1);
578 ASSERT (Divisor
<= 0x80);
579 ClockCtrl
= (Divisor
& 0xFF) << 8;
581 DEBUG ((EFI_D_ERROR
, "Unknown SD Host Controller Spec version [0x%x]!!!\n", ControllerVer
));
582 return EFI_UNSUPPORTED
;
586 // Stop bus clock at first
588 Status
= SdPeimHcStopClock (Bar
);
589 if (EFI_ERROR (Status
)) {
594 // Supply clock frequency with specified divisor
597 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_CLOCK_CTRL
, FALSE
, sizeof (ClockCtrl
), &ClockCtrl
);
598 if (EFI_ERROR (Status
)) {
599 DEBUG ((EFI_D_ERROR
, "Set SDCLK Frequency Select and Internal Clock Enable fields fails\n"));
604 // Wait Internal Clock Stable in the Clock Control register to be 1
606 Status
= SdPeimHcWaitMmioSet (
607 Bar
+ SD_HC_CLOCK_CTRL
,
613 if (EFI_ERROR (Status
)) {
618 // Set SD Clock Enable in the Clock Control register to 1
621 Status
= SdPeimHcOrMmio (Bar
+ SD_HC_CLOCK_CTRL
, sizeof (ClockCtrl
), &ClockCtrl
);
627 SD bus power control.
629 Refer to SD Host Controller Simplified spec 3.0 Section 3.3 for details.
631 @param[in] Bar The mmio base address of the slot to be accessed.
632 @param[in] PowerCtrl The value setting to the power control register.
634 @retval TRUE There is a SD card attached.
635 @retval FALSE There is no a SD card attached.
639 SdPeimHcPowerControl (
649 PowerCtrl
&= (UINT8
)~BIT0
;
650 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_POWER_CTRL
, FALSE
, sizeof (PowerCtrl
), &PowerCtrl
);
651 if (EFI_ERROR (Status
)) {
656 // Set SD Bus Voltage Select and SD Bus Power fields in Power Control Register
659 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_POWER_CTRL
, FALSE
, sizeof (PowerCtrl
), &PowerCtrl
);
665 Set the SD bus width.
667 Refer to SD Host Controller Simplified spec 3.0 Section 3.4 for details.
669 @param[in] Bar The mmio base address of the slot to be accessed.
670 @param[in] BusWidth The bus width used by the SD device, it must be 1, 4 or 8.
672 @retval EFI_SUCCESS The bus width is set successfully.
673 @retval Others The bus width isn't set successfully.
677 SdPeimHcSetBusWidth (
686 HostCtrl1
= (UINT8
)~(BIT5
| BIT1
);
687 Status
= SdPeimHcAndMmio (Bar
+ SD_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
688 } else if (BusWidth
== 4) {
689 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_HOST_CTRL1
, TRUE
, sizeof (HostCtrl1
), &HostCtrl1
);
690 if (EFI_ERROR (Status
)) {
694 HostCtrl1
&= (UINT8
)~BIT5
;
695 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_HOST_CTRL1
, FALSE
, sizeof (HostCtrl1
), &HostCtrl1
);
696 } else if (BusWidth
== 8) {
697 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_HOST_CTRL1
, TRUE
, sizeof (HostCtrl1
), &HostCtrl1
);
698 if (EFI_ERROR (Status
)) {
701 HostCtrl1
&= (UINT8
)~BIT1
;
703 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_HOST_CTRL1
, FALSE
, sizeof (HostCtrl1
), &HostCtrl1
);
706 return EFI_INVALID_PARAMETER
;
713 Supply SD card with lowest clock frequency at initialization.
715 @param[in] Bar The mmio base address of the slot to be accessed.
717 @retval EFI_SUCCESS The clock is supplied successfully.
718 @retval Others The clock isn't supplied successfully.
722 SdPeimHcInitClockFreq (
727 SD_HC_SLOT_CAP Capability
;
731 // Calculate a divisor for SD clock frequency
733 Status
= SdPeimHcGetCapability (Bar
, &Capability
);
734 if (EFI_ERROR (Status
)) {
738 if (Capability
.BaseClkFreq
== 0) {
740 // Don't support get Base Clock Frequency information via another method
742 return EFI_UNSUPPORTED
;
745 // Supply 400KHz clock frequency at initialization phase.
748 Status
= SdPeimHcClockSupply (Bar
, InitFreq
);
753 Supply SD card with maximum voltage at initialization.
755 Refer to SD Host Controller Simplified spec 3.0 Section 3.3 for details.
757 @param[in] Bar The mmio base address of the slot to be accessed.
759 @retval EFI_SUCCESS The voltage is supplied successfully.
760 @retval Others The voltage isn't supplied successfully.
764 SdPeimHcInitPowerVoltage (
769 SD_HC_SLOT_CAP Capability
;
774 // Get the support voltage of the Host Controller
776 Status
= SdPeimHcGetCapability (Bar
, &Capability
);
777 if (EFI_ERROR (Status
)) {
781 // Calculate supported maximum voltage according to SD Bus Voltage Select
783 if (Capability
.Voltage33
!= 0) {
788 } else if (Capability
.Voltage30
!= 0) {
793 } else if (Capability
.Voltage18
!= 0) {
799 Status
= SdPeimHcOrMmio (Bar
+ SD_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
800 if (EFI_ERROR (Status
)) {
803 MicroSecondDelay (5000);
806 return EFI_DEVICE_ERROR
;
810 // Set SD Bus Voltage Select and SD Bus Power fields in Power Control Register
812 Status
= SdPeimHcPowerControl (Bar
, MaxVoltage
);
818 Initialize the Timeout Control register with most conservative value at initialization.
820 Refer to SD Host Controller Simplified spec 3.0 Section 2.2.15 for details.
822 @param[in] Bar The mmio base address of the slot to be accessed.
824 @retval EFI_SUCCESS The timeout control register is configured successfully.
825 @retval Others The timeout control register isn't configured successfully.
829 SdPeimHcInitTimeoutCtrl (
837 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_TIMEOUT_CTRL
, FALSE
, sizeof (Timeout
), &Timeout
);
843 Initial SD host controller with lowest clock frequency, max power and max timeout value
846 @param[in] Bar The mmio base address of the slot to be accessed.
848 @retval EFI_SUCCESS The host controller is initialized successfully.
849 @retval Others The host controller isn't initialized successfully.
859 Status
= SdPeimHcInitClockFreq (Bar
);
860 if (EFI_ERROR (Status
)) {
864 Status
= SdPeimHcInitPowerVoltage (Bar
);
865 if (EFI_ERROR (Status
)) {
869 Status
= SdPeimHcInitTimeoutCtrl (Bar
);
876 @param[in] Bar The mmio base address of the slot to be accessed.
877 @param[in] On The boolean to turn on/off LED.
879 @retval EFI_SUCCESS The LED is turned on/off successfully.
880 @retval Others The LED isn't turned on/off successfully.
894 Status
= SdPeimHcOrMmio (Bar
+ SD_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
896 HostCtrl1
= (UINT8
)~BIT0
;
897 Status
= SdPeimHcAndMmio (Bar
+ SD_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
904 Build ADMA descriptor table for transfer.
906 Refer to SD Host Controller Simplified spec 3.0 Section 1.13 for details.
908 @param[in] Trb The pointer to the SD_TRB instance.
910 @retval EFI_SUCCESS The ADMA descriptor table is created successfully.
911 @retval Others The ADMA descriptor table isn't created successfully.
919 EFI_PHYSICAL_ADDRESS Data
;
926 Data
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)Trb
->Data
;
927 DataLen
= Trb
->DataLen
;
929 // Only support 32bit ADMA Descriptor Table
931 if ((Data
>= 0x100000000ul
) || ((Data
+ DataLen
) > 0x100000000ul
)) {
932 return EFI_INVALID_PARAMETER
;
935 // Address field shall be set on 32-bit boundary (Lower 2-bit is always set to 0)
936 // for 32-bit address descriptor table.
938 if ((Data
& (BIT0
| BIT1
)) != 0) {
939 DEBUG ((EFI_D_INFO
, "The buffer [0x%x] to construct ADMA desc is not aligned to 4 bytes boundary!\n", Data
));
942 Entries
= DivU64x32 ((DataLen
+ ADMA_MAX_DATA_PER_LINE
- 1), ADMA_MAX_DATA_PER_LINE
);
944 Trb
->AdmaDescSize
= (UINTN
)MultU64x32 (Entries
, sizeof (SD_HC_ADMA_DESC_LINE
));
945 Trb
->AdmaDesc
= SdPeimAllocateMem (Trb
->Slot
->Private
->Pool
, Trb
->AdmaDescSize
);
946 if (Trb
->AdmaDesc
== NULL
) {
947 return EFI_OUT_OF_RESOURCES
;
951 Address
= (UINT32
)Data
;
952 for (Index
= 0; Index
< Entries
; Index
++) {
953 if (Remaining
<= ADMA_MAX_DATA_PER_LINE
) {
954 Trb
->AdmaDesc
[Index
].Valid
= 1;
955 Trb
->AdmaDesc
[Index
].Act
= 2;
956 Trb
->AdmaDesc
[Index
].Length
= (UINT16
)Remaining
;
957 Trb
->AdmaDesc
[Index
].Address
= Address
;
960 Trb
->AdmaDesc
[Index
].Valid
= 1;
961 Trb
->AdmaDesc
[Index
].Act
= 2;
962 Trb
->AdmaDesc
[Index
].Length
= 0;
963 Trb
->AdmaDesc
[Index
].Address
= Address
;
966 Remaining
-= ADMA_MAX_DATA_PER_LINE
;
967 Address
+= ADMA_MAX_DATA_PER_LINE
;
971 // Set the last descriptor line as end of descriptor table
973 Trb
->AdmaDesc
[Index
].End
= 1;
978 Create a new TRB for the SD cmd request.
980 @param[in] Slot The slot number of the SD card to send the command to.
981 @param[in] Packet A pointer to the SD command data structure.
983 @return Created Trb or NULL.
988 IN SD_PEIM_HC_SLOT
*Slot
,
989 IN SD_COMMAND_PACKET
*Packet
994 SD_HC_SLOT_CAP Capability
;
997 // Calculate a divisor for SD clock frequency
999 Status
= SdPeimHcGetCapability (Slot
->SdHcBase
, &Capability
);
1000 if (EFI_ERROR (Status
)) {
1004 Trb
= SdPeimAllocateMem (Slot
->Private
->Pool
, sizeof (SD_TRB
));
1010 Trb
->BlockSize
= 0x200;
1011 Trb
->Packet
= Packet
;
1012 Trb
->Timeout
= Packet
->Timeout
;
1014 if ((Packet
->InTransferLength
!= 0) && (Packet
->InDataBuffer
!= NULL
)) {
1015 Trb
->Data
= Packet
->InDataBuffer
;
1016 Trb
->DataLen
= Packet
->InTransferLength
;
1018 } else if ((Packet
->OutTransferLength
!= 0) && (Packet
->OutDataBuffer
!= NULL
)) {
1019 Trb
->Data
= Packet
->OutDataBuffer
;
1020 Trb
->DataLen
= Packet
->OutTransferLength
;
1022 } else if ((Packet
->InTransferLength
== 0) && (Packet
->OutTransferLength
== 0)) {
1029 if ((Trb
->DataLen
% Trb
->BlockSize
) != 0) {
1030 if (Trb
->DataLen
< Trb
->BlockSize
) {
1031 Trb
->BlockSize
= (UINT16
)Trb
->DataLen
;
1035 if (Trb
->DataLen
== 0) {
1036 Trb
->Mode
= SdNoData
;
1037 } else if (Capability
.Adma2
!= 0) {
1038 Trb
->Mode
= SdAdmaMode
;
1039 Status
= BuildAdmaDescTable (Trb
);
1040 if (EFI_ERROR (Status
)) {
1043 } else if (Capability
.Sdma
!= 0) {
1044 Trb
->Mode
= SdSdmaMode
;
1046 Trb
->Mode
= SdPioMode
;
1052 SdPeimFreeTrb (Trb
);
1057 Free the resource used by the TRB.
1059 @param[in] Trb The pointer to the SD_TRB instance.
1067 if ((Trb
!= NULL
) && (Trb
->AdmaDesc
!= NULL
)) {
1068 SdPeimFreeMem (Trb
->Slot
->Private
->Pool
, Trb
->AdmaDesc
, Trb
->AdmaDescSize
);
1072 SdPeimFreeMem (Trb
->Slot
->Private
->Pool
, Trb
, sizeof (SD_TRB
));
1078 Check if the env is ready for execute specified TRB.
1080 @param[in] Bar The mmio base address of the slot to be accessed.
1081 @param[in] Trb The pointer to the SD_TRB instance.
1083 @retval EFI_SUCCESS The env is ready for TRB execution.
1084 @retval EFI_NOT_READY The env is not ready for TRB execution.
1085 @retval Others Some erros happen.
1095 SD_COMMAND_PACKET
*Packet
;
1096 UINT32 PresentState
;
1098 Packet
= Trb
->Packet
;
1100 if ((Packet
->SdCmdBlk
->CommandType
== SdCommandTypeAdtc
) ||
1101 (Packet
->SdCmdBlk
->ResponseType
== SdResponseTypeR1b
) ||
1102 (Packet
->SdCmdBlk
->ResponseType
== SdResponseTypeR5b
)) {
1104 // Wait Command Inhibit (CMD) and Command Inhibit (DAT) in
1105 // the Present State register to be 0
1107 PresentState
= BIT0
| BIT1
;
1108 if (Packet
->SdCmdBlk
->CommandIndex
== SD_SEND_TUNING_BLOCK
) {
1109 PresentState
= BIT0
;
1113 // Wait Command Inhibit (CMD) in the Present State register
1116 PresentState
= BIT0
;
1119 Status
= SdPeimHcCheckMmioSet (
1120 Bar
+ SD_HC_PRESENT_STATE
,
1121 sizeof (PresentState
),
1130 Wait for the env to be ready for execute specified TRB.
1132 @param[in] Bar The mmio base address of the slot to be accessed.
1133 @param[in] Trb The pointer to the SD_TRB instance.
1135 @retval EFI_SUCCESS The env is ready for TRB execution.
1136 @retval EFI_TIMEOUT The env is not ready for TRB execution in time.
1137 @retval Others Some erros happen.
1147 SD_COMMAND_PACKET
*Packet
;
1149 BOOLEAN InfiniteWait
;
1152 // Wait Command Complete Interrupt Status bit in Normal Interrupt Status Register
1154 Packet
= Trb
->Packet
;
1155 Timeout
= Packet
->Timeout
;
1157 InfiniteWait
= TRUE
;
1159 InfiniteWait
= FALSE
;
1162 while (InfiniteWait
|| (Timeout
> 0)) {
1164 // Check Trb execution result by reading Normal Interrupt Status register.
1166 Status
= SdPeimCheckTrbEnv (Bar
, Trb
);
1167 if (Status
!= EFI_NOT_READY
) {
1171 // Stall for 1 microsecond.
1173 MicroSecondDelay (1);
1182 Execute the specified TRB.
1184 @param[in] Bar The mmio base address of the slot to be accessed.
1185 @param[in] Trb The pointer to the SD_TRB instance.
1187 @retval EFI_SUCCESS The TRB is sent to host controller successfully.
1188 @retval Others Some erros happen when sending this request to the host controller.
1198 SD_COMMAND_PACKET
*Packet
;
1209 Packet
= Trb
->Packet
;
1211 // Clear all bits in Error Interrupt Status Register
1214 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_ERR_INT_STS
, FALSE
, sizeof (IntStatus
), &IntStatus
);
1215 if (EFI_ERROR (Status
)) {
1219 // Clear all bits in Normal Interrupt Status Register
1222 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_NOR_INT_STS
, FALSE
, sizeof (IntStatus
), &IntStatus
);
1223 if (EFI_ERROR (Status
)) {
1227 // Set Host Control 1 register DMA Select field
1229 if (Trb
->Mode
== SdAdmaMode
) {
1231 Status
= SdPeimHcOrMmio (Bar
+ SD_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
1232 if (EFI_ERROR (Status
)) {
1237 SdPeimHcLedOnOff (Bar
, TRUE
);
1239 if (Trb
->Mode
== SdSdmaMode
) {
1240 if ((UINT64
)(UINTN
)Trb
->Data
>= 0x100000000ul
) {
1241 return EFI_INVALID_PARAMETER
;
1244 SdmaAddr
= (UINT32
)(UINTN
)Trb
->Data
;
1245 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_SDMA_ADDR
, FALSE
, sizeof (SdmaAddr
), &SdmaAddr
);
1246 if (EFI_ERROR (Status
)) {
1249 } else if (Trb
->Mode
== SdAdmaMode
) {
1250 AdmaAddr
= (UINT64
)(UINTN
)Trb
->AdmaDesc
;
1251 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_ADMA_SYS_ADDR
, FALSE
, sizeof (AdmaAddr
), &AdmaAddr
);
1252 if (EFI_ERROR (Status
)) {
1257 BlkSize
= Trb
->BlockSize
;
1258 if (Trb
->Mode
== SdSdmaMode
) {
1260 // Set SDMA boundary to be 512K bytes.
1265 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_BLK_SIZE
, FALSE
, sizeof (BlkSize
), &BlkSize
);
1266 if (EFI_ERROR (Status
)) {
1270 BlkCount
= (UINT16
)(Trb
->DataLen
/ Trb
->BlockSize
);
1271 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_BLK_COUNT
, FALSE
, sizeof (BlkCount
), &BlkCount
);
1272 if (EFI_ERROR (Status
)) {
1276 Argument
= Packet
->SdCmdBlk
->CommandArgument
;
1277 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_ARG1
, FALSE
, sizeof (Argument
), &Argument
);
1278 if (EFI_ERROR (Status
)) {
1283 if (Trb
->Mode
!= SdNoData
) {
1284 if (Trb
->Mode
!= SdPioMode
) {
1290 if (BlkCount
!= 0) {
1291 TransMode
|= BIT5
| BIT1
;
1298 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_TRANS_MOD
, FALSE
, sizeof (TransMode
), &TransMode
);
1299 if (EFI_ERROR (Status
)) {
1303 Cmd
= (UINT16
)LShiftU64(Packet
->SdCmdBlk
->CommandIndex
, 8);
1304 if (Packet
->SdCmdBlk
->CommandType
== SdCommandTypeAdtc
) {
1308 // Convert ResponseType to value
1310 if (Packet
->SdCmdBlk
->CommandType
!= SdCommandTypeBc
) {
1311 switch (Packet
->SdCmdBlk
->ResponseType
) {
1312 case SdResponseTypeR1
:
1313 case SdResponseTypeR5
:
1314 case SdResponseTypeR6
:
1315 case SdResponseTypeR7
:
1316 Cmd
|= (BIT1
| BIT3
| BIT4
);
1318 case SdResponseTypeR2
:
1319 Cmd
|= (BIT0
| BIT3
);
1321 case SdResponseTypeR3
:
1322 case SdResponseTypeR4
:
1325 case SdResponseTypeR1b
:
1326 case SdResponseTypeR5b
:
1327 Cmd
|= (BIT0
| BIT1
| BIT3
| BIT4
);
1337 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_COMMAND
, FALSE
, sizeof (Cmd
), &Cmd
);
1342 Check the TRB execution result.
1344 @param[in] Bar The mmio base address of the slot to be accessed.
1345 @param[in] Trb The pointer to the SD_TRB instance.
1347 @retval EFI_SUCCESS The TRB is executed successfully.
1348 @retval EFI_NOT_READY The TRB is not completed for execution.
1349 @retval Others Some erros happen when executing this request.
1353 SdPeimCheckTrbResult (
1359 SD_COMMAND_PACKET
*Packet
;
1367 Packet
= Trb
->Packet
;
1369 // Check Trb execution result by reading Normal Interrupt Status register.
1371 Status
= SdPeimHcRwMmio (
1372 Bar
+ SD_HC_NOR_INT_STS
,
1377 if (EFI_ERROR (Status
)) {
1381 // Check Transfer Complete bit is set or not.
1383 if ((IntStatus
& BIT1
) == BIT1
) {
1384 if ((IntStatus
& BIT15
) == BIT15
) {
1386 // Read Error Interrupt Status register to check if the error is
1387 // Data Timeout Error.
1388 // If yes, treat it as success as Transfer Complete has higher
1389 // priority than Data Timeout Error.
1391 Status
= SdPeimHcRwMmio (
1392 Bar
+ SD_HC_ERR_INT_STS
,
1397 if (!EFI_ERROR (Status
)) {
1398 if ((IntStatus
& BIT4
) == BIT4
) {
1399 Status
= EFI_SUCCESS
;
1401 Status
= EFI_DEVICE_ERROR
;
1409 // Check if there is a error happened during cmd execution.
1410 // If yes, then do error recovery procedure to follow SD Host Controller
1411 // Simplified Spec 3.0 section 3.10.1.
1413 if ((IntStatus
& BIT15
) == BIT15
) {
1414 Status
= SdPeimHcRwMmio (
1415 Bar
+ SD_HC_ERR_INT_STS
,
1420 if (EFI_ERROR (Status
)) {
1424 if ((IntStatus
& 0x0F) != 0) {
1427 if ((IntStatus
& 0xF0) != 0) {
1431 Status
= SdPeimHcRwMmio (
1437 if (EFI_ERROR (Status
)) {
1440 Status
= SdPeimHcWaitMmioSet (
1447 if (EFI_ERROR (Status
)) {
1451 Status
= EFI_DEVICE_ERROR
;
1455 // Check if DMA interrupt is signalled for the SDMA transfer.
1457 if ((Trb
->Mode
== SdSdmaMode
) && ((IntStatus
& BIT3
) == BIT3
)) {
1459 // Clear DMA interrupt bit.
1462 Status
= SdPeimHcRwMmio (
1463 Bar
+ SD_HC_NOR_INT_STS
,
1468 if (EFI_ERROR (Status
)) {
1472 // Update SDMA Address register.
1474 SdmaAddr
= SD_SDMA_ROUND_UP ((UINT32
)(UINTN
)Trb
->Data
, SD_SDMA_BOUNDARY
);
1475 Status
= SdPeimHcRwMmio (
1476 Bar
+ SD_HC_SDMA_ADDR
,
1481 if (EFI_ERROR (Status
)) {
1484 Trb
->Data
= (VOID
*)(UINTN
)SdmaAddr
;
1487 if ((Packet
->SdCmdBlk
->CommandType
!= SdCommandTypeAdtc
) &&
1488 (Packet
->SdCmdBlk
->ResponseType
!= SdResponseTypeR1b
) &&
1489 (Packet
->SdCmdBlk
->ResponseType
!= SdResponseTypeR5b
)) {
1490 if ((IntStatus
& BIT0
) == BIT0
) {
1491 Status
= EFI_SUCCESS
;
1496 if (Packet
->SdCmdBlk
->CommandIndex
== SD_SEND_TUNING_BLOCK
) {
1497 Status
= EFI_SUCCESS
;
1501 Status
= EFI_NOT_READY
;
1504 // Get response data when the cmd is executed successfully.
1506 if (!EFI_ERROR (Status
)) {
1507 if (Packet
->SdCmdBlk
->CommandType
!= SdCommandTypeBc
) {
1508 for (Index
= 0; Index
< 4; Index
++) {
1509 Status
= SdPeimHcRwMmio (
1510 Bar
+ SD_HC_RESPONSE
+ Index
* 4,
1515 if (EFI_ERROR (Status
)) {
1516 SdPeimHcLedOnOff (Bar
, FALSE
);
1520 CopyMem (Packet
->SdStatusBlk
, Response
, sizeof (Response
));
1524 if (Status
!= EFI_NOT_READY
) {
1525 SdPeimHcLedOnOff (Bar
, FALSE
);
1532 Wait for the TRB execution result.
1534 @param[in] Bar The mmio base address of the slot to be accessed.
1535 @param[in] Trb The pointer to the SD_TRB instance.
1537 @retval EFI_SUCCESS The TRB is executed successfully.
1538 @retval Others Some erros happen when executing this request.
1542 SdPeimWaitTrbResult (
1548 SD_COMMAND_PACKET
*Packet
;
1550 BOOLEAN InfiniteWait
;
1552 Packet
= Trb
->Packet
;
1554 // Wait Command Complete Interrupt Status bit in Normal Interrupt Status Register
1556 Timeout
= Packet
->Timeout
;
1558 InfiniteWait
= TRUE
;
1560 InfiniteWait
= FALSE
;
1563 while (InfiniteWait
|| (Timeout
> 0)) {
1565 // Check Trb execution result by reading Normal Interrupt Status register.
1567 Status
= SdPeimCheckTrbResult (Bar
, Trb
);
1568 if (Status
!= EFI_NOT_READY
) {
1572 // Stall for 1 microsecond.
1574 MicroSecondDelay (1);
1583 Sends SD command to an SD card that is attached to the SD controller.
1585 If Packet is successfully sent to the SD card, then EFI_SUCCESS is returned.
1587 If a device error occurs while sending the Packet, then EFI_DEVICE_ERROR is returned.
1589 If Slot is not in a valid range for the SD controller, then EFI_INVALID_PARAMETER
1592 If Packet defines a data command but both InDataBuffer and OutDataBuffer are NULL,
1593 EFI_INVALID_PARAMETER is returned.
1595 @param[in] Slot The slot number of the Sd card to send the command to.
1596 @param[in,out] Packet A pointer to the SD command data structure.
1598 @retval EFI_SUCCESS The SD Command Packet was sent by the host.
1599 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send the SD
1601 @retval EFI_INVALID_PARAMETER Packet, Slot, or the contents of the Packet is invalid.
1602 @retval EFI_INVALID_PARAMETER Packet defines a data command but both InDataBuffer and
1603 OutDataBuffer are NULL.
1604 @retval EFI_NO_MEDIA SD Device not present in the Slot.
1605 @retval EFI_UNSUPPORTED The command described by the SD Command Packet is not
1606 supported by the host controller.
1607 @retval EFI_BAD_BUFFER_SIZE The InTransferLength or OutTransferLength exceeds the
1608 limit supported by SD card ( i.e. if the number of bytes
1609 exceed the Last LBA).
1615 IN SD_PEIM_HC_SLOT
*Slot
,
1616 IN OUT SD_COMMAND_PACKET
*Packet
1622 if (Packet
== NULL
) {
1623 return EFI_INVALID_PARAMETER
;
1626 if ((Packet
->SdCmdBlk
== NULL
) || (Packet
->SdStatusBlk
== NULL
)) {
1627 return EFI_INVALID_PARAMETER
;
1630 if ((Packet
->OutDataBuffer
== NULL
) && (Packet
->OutTransferLength
!= 0)) {
1631 return EFI_INVALID_PARAMETER
;
1634 if ((Packet
->InDataBuffer
== NULL
) && (Packet
->InTransferLength
!= 0)) {
1635 return EFI_INVALID_PARAMETER
;
1638 Trb
= SdPeimCreateTrb (Slot
, Packet
);
1640 return EFI_OUT_OF_RESOURCES
;
1643 Status
= SdPeimWaitTrbEnv (Slot
->SdHcBase
, Trb
);
1644 if (EFI_ERROR (Status
)) {
1648 Status
= SdPeimExecTrb (Slot
->SdHcBase
, Trb
);
1649 if (EFI_ERROR (Status
)) {
1653 Status
= SdPeimWaitTrbResult (Slot
->SdHcBase
, Trb
);
1654 if (EFI_ERROR (Status
)) {
1659 SdPeimFreeTrb (Trb
);
1665 Send command GO_IDLE_STATE to the device to make it go to Idle State.
1667 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
1669 @param[in] Slot The slot number of the SD card to send the command to.
1671 @retval EFI_SUCCESS The SD device is reset correctly.
1672 @retval Others The device reset fails.
1677 IN SD_PEIM_HC_SLOT
*Slot
1680 SD_COMMAND_BLOCK SdCmdBlk
;
1681 SD_STATUS_BLOCK SdStatusBlk
;
1682 SD_COMMAND_PACKET Packet
;
1685 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
1686 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
1687 ZeroMem (&Packet
, sizeof (Packet
));
1689 Packet
.SdCmdBlk
= &SdCmdBlk
;
1690 Packet
.SdStatusBlk
= &SdStatusBlk
;
1691 Packet
.Timeout
= SD_TIMEOUT
;
1693 SdCmdBlk
.CommandIndex
= SD_GO_IDLE_STATE
;
1694 SdCmdBlk
.CommandType
= SdCommandTypeBc
;
1695 SdCmdBlk
.ResponseType
= 0;
1696 SdCmdBlk
.CommandArgument
= 0;
1698 Status
= SdPeimExecCmd (Slot
, &Packet
);
1704 Send command SEND_IF_COND to the device to inquiry the SD Memory Card interface
1707 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
1709 @param[in] Slot The slot number of the SD card to send the command to.
1710 @param[in] SupplyVoltage The supplied voltage by the host.
1711 @param[in] CheckPattern The check pattern to be sent to the device.
1713 @retval EFI_SUCCESS The operation is done correctly.
1714 @retval Others The operation fails.
1718 SdPeimVoltageCheck (
1719 IN SD_PEIM_HC_SLOT
*Slot
,
1720 IN UINT8 SupplyVoltage
,
1721 IN UINT8 CheckPattern
1724 SD_COMMAND_BLOCK SdCmdBlk
;
1725 SD_STATUS_BLOCK SdStatusBlk
;
1726 SD_COMMAND_PACKET Packet
;
1729 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
1730 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
1731 ZeroMem (&Packet
, sizeof (Packet
));
1733 Packet
.SdCmdBlk
= &SdCmdBlk
;
1734 Packet
.SdStatusBlk
= &SdStatusBlk
;
1735 Packet
.Timeout
= SD_TIMEOUT
;
1737 SdCmdBlk
.CommandIndex
= SD_SEND_IF_COND
;
1738 SdCmdBlk
.CommandType
= SdCommandTypeBcr
;
1739 SdCmdBlk
.ResponseType
= SdResponseTypeR7
;
1740 SdCmdBlk
.CommandArgument
= (SupplyVoltage
<< 8) | CheckPattern
;
1742 Status
= SdPeimExecCmd (Slot
, &Packet
);
1743 if (!EFI_ERROR (Status
)) {
1744 if (SdStatusBlk
.Resp0
!= SdCmdBlk
.CommandArgument
) {
1745 return EFI_DEVICE_ERROR
;
1753 Send command SDIO_SEND_OP_COND to the device to see whether it is SDIO device.
1755 Refer to SDIO Simplified Spec 3 Section 3.2 for details.
1757 @param[in] Slot The slot number of the SD card to send the command to.
1758 @param[in] VoltageWindow The supply voltage window.
1759 @param[in] S18r The boolean to show if it should switch to 1.8v.
1761 @retval EFI_SUCCESS The operation is done correctly.
1762 @retval Others The operation fails.
1767 IN SD_PEIM_HC_SLOT
*Slot
,
1768 IN UINT32 VoltageWindow
,
1772 SD_COMMAND_BLOCK SdCmdBlk
;
1773 SD_STATUS_BLOCK SdStatusBlk
;
1774 SD_COMMAND_PACKET Packet
;
1778 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
1779 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
1780 ZeroMem (&Packet
, sizeof (Packet
));
1782 Packet
.SdCmdBlk
= &SdCmdBlk
;
1783 Packet
.SdStatusBlk
= &SdStatusBlk
;
1784 Packet
.Timeout
= SD_TIMEOUT
;
1786 SdCmdBlk
.CommandIndex
= SDIO_SEND_OP_COND
;
1787 SdCmdBlk
.CommandType
= SdCommandTypeBcr
;
1788 SdCmdBlk
.ResponseType
= SdResponseTypeR4
;
1790 Switch
= S18r
? BIT24
: 0;
1792 SdCmdBlk
.CommandArgument
= (VoltageWindow
& 0xFFFFFF) | Switch
;
1794 Status
= SdPeimExecCmd (Slot
, &Packet
);
1800 Send command SD_SEND_OP_COND to the device to see whether it is SDIO device.
1802 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
1804 @param[in] Slot The slot number of the SD card to send the command to.
1805 @param[in] Rca The relative device address of addressed device.
1806 @param[in] VoltageWindow The supply voltage window.
1807 @param[in] S18r The boolean to show if it should switch to 1.8v.
1808 @param[in] Xpc The boolean to show if it should provide 0.36w power control.
1809 @param[in] Hcs The boolean to show if it support host capacity info.
1810 @param[out] Ocr The buffer to store returned OCR register value.
1813 @retval EFI_SUCCESS The operation is done correctly.
1814 @retval Others The operation fails.
1819 IN SD_PEIM_HC_SLOT
*Slot
,
1821 IN UINT32 VoltageWindow
,
1828 SD_COMMAND_BLOCK SdCmdBlk
;
1829 SD_STATUS_BLOCK SdStatusBlk
;
1830 SD_COMMAND_PACKET Packet
;
1834 UINT32 HostCapacity
;
1836 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
1837 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
1838 ZeroMem (&Packet
, sizeof (Packet
));
1840 Packet
.SdCmdBlk
= &SdCmdBlk
;
1841 Packet
.SdStatusBlk
= &SdStatusBlk
;
1842 Packet
.Timeout
= SD_TIMEOUT
;
1844 SdCmdBlk
.CommandIndex
= SD_APP_CMD
;
1845 SdCmdBlk
.CommandType
= SdCommandTypeAc
;
1846 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
1847 SdCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
1849 Status
= SdPeimExecCmd (Slot
, &Packet
);
1850 if (EFI_ERROR (Status
)) {
1854 SdCmdBlk
.CommandIndex
= SD_SEND_OP_COND
;
1855 SdCmdBlk
.CommandType
= SdCommandTypeBcr
;
1856 SdCmdBlk
.ResponseType
= SdResponseTypeR3
;
1858 Switch
= S18r
? BIT24
: 0;
1859 MaxPower
= Xpc
? BIT28
: 0;
1860 HostCapacity
= Hcs
? BIT30
: 0;
1861 SdCmdBlk
.CommandArgument
= (VoltageWindow
& 0xFFFFFF) | Switch
| MaxPower
| HostCapacity
;
1863 Status
= SdPeimExecCmd (Slot
, &Packet
);
1864 if (!EFI_ERROR (Status
)) {
1866 // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12.
1868 *Ocr
= SdStatusBlk
.Resp0
;
1875 Broadcast command ALL_SEND_CID to the bus to ask all the SD devices to send the
1876 data of their CID registers.
1878 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
1880 @param[in] Slot The slot number of the SD card to send the command to.
1882 @retval EFI_SUCCESS The operation is done correctly.
1883 @retval Others The operation fails.
1888 IN SD_PEIM_HC_SLOT
*Slot
1891 SD_COMMAND_BLOCK SdCmdBlk
;
1892 SD_STATUS_BLOCK SdStatusBlk
;
1893 SD_COMMAND_PACKET Packet
;
1896 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
1897 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
1898 ZeroMem (&Packet
, sizeof (Packet
));
1900 Packet
.SdCmdBlk
= &SdCmdBlk
;
1901 Packet
.SdStatusBlk
= &SdStatusBlk
;
1902 Packet
.Timeout
= SD_TIMEOUT
;
1904 SdCmdBlk
.CommandIndex
= SD_ALL_SEND_CID
;
1905 SdCmdBlk
.CommandType
= SdCommandTypeBcr
;
1906 SdCmdBlk
.ResponseType
= SdResponseTypeR2
;
1907 SdCmdBlk
.CommandArgument
= 0;
1909 Status
= SdPeimExecCmd (Slot
, &Packet
);
1915 Send command SET_RELATIVE_ADDR to the SD device to assign a Relative device
1918 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
1920 @param[in] Slot The slot number of the SD card to send the command to.
1921 @param[out] Rca The relative device address to be assigned.
1923 @retval EFI_SUCCESS The operation is done correctly.
1924 @retval Others The operation fails.
1929 IN SD_PEIM_HC_SLOT
*Slot
,
1933 SD_COMMAND_BLOCK SdCmdBlk
;
1934 SD_STATUS_BLOCK SdStatusBlk
;
1935 SD_COMMAND_PACKET Packet
;
1938 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
1939 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
1940 ZeroMem (&Packet
, sizeof (Packet
));
1942 Packet
.SdCmdBlk
= &SdCmdBlk
;
1943 Packet
.SdStatusBlk
= &SdStatusBlk
;
1944 Packet
.Timeout
= SD_TIMEOUT
;
1946 SdCmdBlk
.CommandIndex
= SD_SET_RELATIVE_ADDR
;
1947 SdCmdBlk
.CommandType
= SdCommandTypeBcr
;
1948 SdCmdBlk
.ResponseType
= SdResponseTypeR6
;
1950 Status
= SdPeimExecCmd (Slot
, &Packet
);
1951 if (!EFI_ERROR (Status
)) {
1952 *Rca
= (UINT16
)(SdStatusBlk
.Resp0
>> 16);
1959 Send command SEND_CSD to the SD device to get the data of the CSD register.
1961 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
1963 @param[in] Slot The slot number of the SD card to send the command to.
1964 @param[in] Rca The relative device address of selected device.
1965 @param[out] Csd The buffer to store the content of the CSD register.
1966 Note the caller should ignore the lowest byte of this
1967 buffer as the content of this byte is meaningless even
1968 if the operation succeeds.
1970 @retval EFI_SUCCESS The operation is done correctly.
1971 @retval Others The operation fails.
1976 IN SD_PEIM_HC_SLOT
*Slot
,
1981 SD_COMMAND_BLOCK SdCmdBlk
;
1982 SD_STATUS_BLOCK SdStatusBlk
;
1983 SD_COMMAND_PACKET Packet
;
1986 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
1987 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
1988 ZeroMem (&Packet
, sizeof (Packet
));
1990 Packet
.SdCmdBlk
= &SdCmdBlk
;
1991 Packet
.SdStatusBlk
= &SdStatusBlk
;
1992 Packet
.Timeout
= SD_TIMEOUT
;
1994 SdCmdBlk
.CommandIndex
= SD_SEND_CSD
;
1995 SdCmdBlk
.CommandType
= SdCommandTypeAc
;
1996 SdCmdBlk
.ResponseType
= SdResponseTypeR2
;
1997 SdCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
1999 Status
= SdPeimExecCmd (Slot
, &Packet
);
2000 if (!EFI_ERROR (Status
)) {
2002 // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12.
2004 CopyMem (((UINT8
*)Csd
) + 1, &SdStatusBlk
.Resp0
, sizeof (SD_CSD
) - 1);
2011 Send command SELECT_DESELECT_CARD to the SD device to select/deselect it.
2013 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
2015 @param[in] Slot The slot number of the SD card to send the command to.
2016 @param[in] Rca The relative device address of selected device.
2018 @retval EFI_SUCCESS The operation is done correctly.
2019 @retval Others The operation fails.
2024 IN SD_PEIM_HC_SLOT
*Slot
,
2028 SD_COMMAND_BLOCK SdCmdBlk
;
2029 SD_STATUS_BLOCK SdStatusBlk
;
2030 SD_COMMAND_PACKET Packet
;
2033 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
2034 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
2035 ZeroMem (&Packet
, sizeof (Packet
));
2037 Packet
.SdCmdBlk
= &SdCmdBlk
;
2038 Packet
.SdStatusBlk
= &SdStatusBlk
;
2039 Packet
.Timeout
= SD_TIMEOUT
;
2041 SdCmdBlk
.CommandIndex
= SD_SELECT_DESELECT_CARD
;
2042 SdCmdBlk
.CommandType
= SdCommandTypeAc
;
2043 SdCmdBlk
.ResponseType
= SdResponseTypeR1b
;
2044 SdCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
2046 Status
= SdPeimExecCmd (Slot
, &Packet
);
2052 Send command VOLTAGE_SWITCH to the SD device to switch the voltage of the device.
2054 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
2056 @param[in] Slot The slot number of the SD card to send the command to.
2058 @retval EFI_SUCCESS The operation is done correctly.
2059 @retval Others The operation fails.
2063 SdPeimVoltageSwitch (
2064 IN SD_PEIM_HC_SLOT
*Slot
2067 SD_COMMAND_BLOCK SdCmdBlk
;
2068 SD_STATUS_BLOCK SdStatusBlk
;
2069 SD_COMMAND_PACKET Packet
;
2072 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
2073 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
2074 ZeroMem (&Packet
, sizeof (Packet
));
2076 Packet
.SdCmdBlk
= &SdCmdBlk
;
2077 Packet
.SdStatusBlk
= &SdStatusBlk
;
2078 Packet
.Timeout
= SD_TIMEOUT
;
2080 SdCmdBlk
.CommandIndex
= SD_VOLTAGE_SWITCH
;
2081 SdCmdBlk
.CommandType
= SdCommandTypeAc
;
2082 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2083 SdCmdBlk
.CommandArgument
= 0;
2085 Status
= SdPeimExecCmd (Slot
, &Packet
);
2091 Send command SET_BUS_WIDTH to the SD device to set the bus width.
2093 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
2095 @param[in] Slot The slot number of the SD card to send the command to.
2096 @param[in] Rca The relative device address of addressed device.
2097 @param[in] BusWidth The bus width to be set, it could be 1 or 4.
2099 @retval EFI_SUCCESS The operation is done correctly.
2100 @retval Others The operation fails.
2105 IN SD_PEIM_HC_SLOT
*Slot
,
2110 SD_COMMAND_BLOCK SdCmdBlk
;
2111 SD_STATUS_BLOCK SdStatusBlk
;
2112 SD_COMMAND_PACKET Packet
;
2116 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
2117 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
2118 ZeroMem (&Packet
, sizeof (Packet
));
2120 Packet
.SdCmdBlk
= &SdCmdBlk
;
2121 Packet
.SdStatusBlk
= &SdStatusBlk
;
2122 Packet
.Timeout
= SD_TIMEOUT
;
2124 SdCmdBlk
.CommandIndex
= SD_APP_CMD
;
2125 SdCmdBlk
.CommandType
= SdCommandTypeAc
;
2126 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2127 SdCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
2129 Status
= SdPeimExecCmd (Slot
, &Packet
);
2130 if (EFI_ERROR (Status
)) {
2134 SdCmdBlk
.CommandIndex
= SD_SET_BUS_WIDTH
;
2135 SdCmdBlk
.CommandType
= SdCommandTypeAc
;
2136 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2138 if (BusWidth
== 1) {
2140 } else if (BusWidth
== 4) {
2143 return EFI_INVALID_PARAMETER
;
2145 SdCmdBlk
.CommandArgument
= Value
& 0x3;
2147 Status
= SdPeimExecCmd (Slot
, &Packet
);
2153 Send command SWITCH_FUNC to the SD device to check switchable function or switch card function.
2155 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
2157 @param[in] Slot The slot number of the SD card to send the command to.
2158 @param[in] AccessMode The value for access mode group.
2159 @param[in] CommandSystem The value for command set group.
2160 @param[in] DriveStrength The value for drive length group.
2161 @param[in] PowerLimit The value for power limit group.
2162 @param[in] Mode Switch or check function.
2164 @retval EFI_SUCCESS The operation is done correctly.
2165 @retval Others The operation fails.
2170 IN SD_PEIM_HC_SLOT
*Slot
,
2171 IN UINT8 AccessMode
,
2172 IN UINT8 CommandSystem
,
2173 IN UINT8 DriveStrength
,
2174 IN UINT8 PowerLimit
,
2178 SD_COMMAND_BLOCK SdCmdBlk
;
2179 SD_STATUS_BLOCK SdStatusBlk
;
2180 SD_COMMAND_PACKET Packet
;
2185 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
2186 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
2187 ZeroMem (&Packet
, sizeof (Packet
));
2189 Packet
.SdCmdBlk
= &SdCmdBlk
;
2190 Packet
.SdStatusBlk
= &SdStatusBlk
;
2191 Packet
.Timeout
= SD_TIMEOUT
;
2193 SdCmdBlk
.CommandIndex
= SD_SWITCH_FUNC
;
2194 SdCmdBlk
.CommandType
= SdCommandTypeAdtc
;
2195 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2197 ModeValue
= Mode
? BIT31
: 0;
2198 SdCmdBlk
.CommandArgument
= (AccessMode
& 0xF) | ((PowerLimit
& 0xF) << 4) | \
2199 ((DriveStrength
& 0xF) << 8) | ((DriveStrength
& 0xF) << 12) | \
2201 Packet
.InDataBuffer
= Data
;
2202 Packet
.InTransferLength
= sizeof (Data
);
2204 Status
= SdPeimExecCmd (Slot
, &Packet
);
2210 Send command SEND_STATUS to the addressed SD device to get its status register.
2212 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
2214 @param[in] Slot The slot number of the SD card to send the command to.
2215 @param[in] Rca The relative device address of addressed device.
2216 @param[out] DevStatus The returned device status.
2218 @retval EFI_SUCCESS The operation is done correctly.
2219 @retval Others The operation fails.
2224 IN SD_PEIM_HC_SLOT
*Slot
,
2226 OUT UINT32
*DevStatus
2229 SD_COMMAND_BLOCK SdCmdBlk
;
2230 SD_STATUS_BLOCK SdStatusBlk
;
2231 SD_COMMAND_PACKET Packet
;
2234 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
2235 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
2236 ZeroMem (&Packet
, sizeof (Packet
));
2238 Packet
.SdCmdBlk
= &SdCmdBlk
;
2239 Packet
.SdStatusBlk
= &SdStatusBlk
;
2240 Packet
.Timeout
= SD_TIMEOUT
;
2242 SdCmdBlk
.CommandIndex
= SD_SEND_STATUS
;
2243 SdCmdBlk
.CommandType
= SdCommandTypeAc
;
2244 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2245 SdCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
2247 Status
= SdPeimExecCmd (Slot
, &Packet
);
2248 if (!EFI_ERROR (Status
)) {
2249 *DevStatus
= SdStatusBlk
.Resp0
;
2256 Send command READ_SINGLE_BLOCK/WRITE_SINGLE_BLOCK to the addressed SD device
2257 to read/write the specified number of blocks.
2259 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
2261 @param[in] Slot The slot number of the SD card to send the command to.
2262 @param[in] Lba The logical block address of starting access.
2263 @param[in] BlockSize The block size of specified SD device partition.
2264 @param[in] Buffer The pointer to the transfer buffer.
2265 @param[in] BufferSize The size of transfer buffer.
2266 @param[in] IsRead Boolean to show the operation direction.
2268 @retval EFI_SUCCESS The operation is done correctly.
2269 @retval Others The operation fails.
2273 SdPeimRwSingleBlock (
2274 IN SD_PEIM_HC_SLOT
*Slot
,
2276 IN UINT32 BlockSize
,
2278 IN UINTN BufferSize
,
2282 SD_COMMAND_BLOCK SdCmdBlk
;
2283 SD_STATUS_BLOCK SdStatusBlk
;
2284 SD_COMMAND_PACKET Packet
;
2287 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
2288 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
2289 ZeroMem (&Packet
, sizeof (Packet
));
2291 Packet
.SdCmdBlk
= &SdCmdBlk
;
2292 Packet
.SdStatusBlk
= &SdStatusBlk
;
2294 // Calculate timeout value through the below formula.
2295 // Timeout = (transfer size) / (2MB/s).
2296 // Taking 2MB/s as divisor is because it's the lowest
2297 // transfer speed of class 2.
2299 Packet
.Timeout
= (BufferSize
/ (2 * 1024 * 1024) + 1) * 1000 * 1000;;
2302 Packet
.InDataBuffer
= Buffer
;
2303 Packet
.InTransferLength
= (UINT32
)BufferSize
;
2305 SdCmdBlk
.CommandIndex
= SD_READ_SINGLE_BLOCK
;
2306 SdCmdBlk
.CommandType
= SdCommandTypeAdtc
;
2307 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2309 Packet
.OutDataBuffer
= Buffer
;
2310 Packet
.OutTransferLength
= (UINT32
)BufferSize
;
2312 SdCmdBlk
.CommandIndex
= SD_WRITE_SINGLE_BLOCK
;
2313 SdCmdBlk
.CommandType
= SdCommandTypeAdtc
;
2314 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2317 if (Slot
->SectorAddressing
) {
2318 SdCmdBlk
.CommandArgument
= (UINT32
)Lba
;
2320 SdCmdBlk
.CommandArgument
= (UINT32
)MultU64x32 (Lba
, BlockSize
);
2323 Status
= SdPeimExecCmd (Slot
, &Packet
);
2329 Send command READ_MULTIPLE_BLOCK/WRITE_MULTIPLE_BLOCK to the addressed SD device
2330 to read/write the specified number of blocks.
2332 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
2334 @param[in] Slot The slot number of the SD card to send the command to.
2335 @param[in] Lba The logical block address of starting access.
2336 @param[in] BlockSize The block size of specified SD device partition.
2337 @param[in] Buffer The pointer to the transfer buffer.
2338 @param[in] BufferSize The size of transfer buffer.
2339 @param[in] IsRead Boolean to show the operation direction.
2341 @retval EFI_SUCCESS The operation is done correctly.
2342 @retval Others The operation fails.
2346 SdPeimRwMultiBlocks (
2347 IN SD_PEIM_HC_SLOT
*Slot
,
2349 IN UINT32 BlockSize
,
2351 IN UINTN BufferSize
,
2355 SD_COMMAND_BLOCK SdCmdBlk
;
2356 SD_STATUS_BLOCK SdStatusBlk
;
2357 SD_COMMAND_PACKET Packet
;
2360 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
2361 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
2362 ZeroMem (&Packet
, sizeof (Packet
));
2364 Packet
.SdCmdBlk
= &SdCmdBlk
;
2365 Packet
.SdStatusBlk
= &SdStatusBlk
;
2367 // Calculate timeout value through the below formula.
2368 // Timeout = (transfer size) / (2MB/s).
2369 // Taking 2MB/s as divisor is because it's the lowest
2370 // transfer speed of class 2.
2372 Packet
.Timeout
= (BufferSize
/ (2 * 1024 * 1024) + 1) * 1000 * 1000;;
2375 Packet
.InDataBuffer
= Buffer
;
2376 Packet
.InTransferLength
= (UINT32
)BufferSize
;
2378 SdCmdBlk
.CommandIndex
= SD_READ_MULTIPLE_BLOCK
;
2379 SdCmdBlk
.CommandType
= SdCommandTypeAdtc
;
2380 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2382 Packet
.OutDataBuffer
= Buffer
;
2383 Packet
.OutTransferLength
= (UINT32
)BufferSize
;
2385 SdCmdBlk
.CommandIndex
= SD_WRITE_MULTIPLE_BLOCK
;
2386 SdCmdBlk
.CommandType
= SdCommandTypeAdtc
;
2387 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2390 if (Slot
->SectorAddressing
) {
2391 SdCmdBlk
.CommandArgument
= (UINT32
)Lba
;
2393 SdCmdBlk
.CommandArgument
= (UINT32
)MultU64x32 (Lba
, BlockSize
);
2396 Status
= SdPeimExecCmd (Slot
, &Packet
);
2402 Send command SEND_TUNING_BLOCK to the SD device for SDR104/SDR50 optimal sampling point
2405 It may be sent up to 40 times until the host finishes the tuning procedure.
2407 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
2409 @param[in] Slot The slot number of the SD card to send the command to.
2411 @retval EFI_SUCCESS The operation is done correctly.
2412 @retval Others The operation fails.
2416 SdPeimSendTuningBlk (
2417 IN SD_PEIM_HC_SLOT
*Slot
2420 SD_COMMAND_BLOCK SdCmdBlk
;
2421 SD_STATUS_BLOCK SdStatusBlk
;
2422 SD_COMMAND_PACKET Packet
;
2424 UINT8 TuningBlock
[64];
2426 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
2427 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
2428 ZeroMem (&Packet
, sizeof (Packet
));
2430 Packet
.SdCmdBlk
= &SdCmdBlk
;
2431 Packet
.SdStatusBlk
= &SdStatusBlk
;
2432 Packet
.Timeout
= SD_TIMEOUT
;
2434 SdCmdBlk
.CommandIndex
= SD_SEND_TUNING_BLOCK
;
2435 SdCmdBlk
.CommandType
= SdCommandTypeAdtc
;
2436 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2437 SdCmdBlk
.CommandArgument
= 0;
2439 Packet
.InDataBuffer
= TuningBlock
;
2440 Packet
.InTransferLength
= sizeof (TuningBlock
);
2442 Status
= SdPeimExecCmd (Slot
, &Packet
);
2448 Tunning the sampling point of SDR104 or SDR50 bus speed mode.
2450 Command SD_SEND_TUNING_BLOCK may be sent up to 40 times until the host finishes the
2453 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and SD Host Controller
2454 Simplified Spec 3.0 Figure 2-29 for details.
2456 @param[in] Slot The slot number of the SD card to send the command to.
2458 @retval EFI_SUCCESS The operation is done correctly.
2459 @retval Others The operation fails.
2464 IN SD_PEIM_HC_SLOT
*Slot
2472 // Notify the host that the sampling clock tuning procedure starts.
2475 Status
= SdPeimHcOrMmio (Slot
->SdHcBase
+ SD_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2476 if (EFI_ERROR (Status
)) {
2480 // Ask the device to send a sequence of tuning blocks till the tuning procedure is done.
2484 Status
= SdPeimSendTuningBlk (Slot
);
2485 if (EFI_ERROR (Status
)) {
2489 Status
= SdPeimHcRwMmio (Slot
->SdHcBase
+ SD_HC_HOST_CTRL2
, TRUE
, sizeof (HostCtrl2
), &HostCtrl2
);
2490 if (EFI_ERROR (Status
)) {
2494 if ((HostCtrl2
& (BIT6
| BIT7
)) == BIT7
) {
2497 } while (++Retry
< 40);
2500 Status
= EFI_TIMEOUT
;
2506 Switch the bus width to specified width.
2508 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and
2509 SD Host Controller Simplified Spec 3.0 section Figure 3-7 for details.
2511 @param[in] Slot The slot number of the SD card to send the command to.
2512 @param[in] Rca The relative device address to be assigned.
2513 @param[in] BusWidth The bus width to be set, it could be 4 or 8.
2515 @retval EFI_SUCCESS The operation is done correctly.
2516 @retval Others The operation fails.
2520 SdPeimSwitchBusWidth (
2521 IN SD_PEIM_HC_SLOT
*Slot
,
2529 Status
= SdPeimSetBusWidth (Slot
, Rca
, BusWidth
);
2530 if (EFI_ERROR (Status
)) {
2534 Status
= SdPeimSendStatus (Slot
, Rca
, &DevStatus
);
2535 if (EFI_ERROR (Status
)) {
2539 // Check the switch operation is really successful or not.
2541 if ((DevStatus
>> 16) != 0) {
2542 return EFI_DEVICE_ERROR
;
2545 Status
= SdPeimHcSetBusWidth (Slot
->SdHcBase
, BusWidth
);
2551 Switch the high speed timing according to request.
2553 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and
2554 SD Host Controller Simplified Spec 3.0 section Figure 2-29 for details.
2556 @param[in] Slot The slot number of the SD card to send the command to.
2557 @param[in] Rca The relative device address to be assigned.
2558 @param[in] S18a The boolean to show if it's a UHS-I SD card.
2560 @retval EFI_SUCCESS The operation is done correctly.
2561 @retval Others The operation fails.
2566 IN SD_PEIM_HC_SLOT
*Slot
,
2572 SD_HC_SLOT_CAP Capability
;
2579 Status
= SdPeimGetCsd (Slot
, Rca
, &Slot
->Csd
);
2580 if (EFI_ERROR (Status
)) {
2581 DEBUG ((EFI_D_ERROR
, "SdPeimSetBusMode: SdPeimGetCsd fails with %r\n", Status
));
2585 Status
= SdPeimHcGetCapability (Slot
->SdHcBase
, &Capability
);
2586 if (EFI_ERROR (Status
)) {
2590 Status
= SdPeimSelect (Slot
, Rca
);
2591 if (EFI_ERROR (Status
)) {
2592 DEBUG ((EFI_D_ERROR
, "SdPeimSetBusMode: SdPeimSelect fails with %r\n", Status
));
2597 Status
= SdPeimSwitchBusWidth (Slot
, Rca
, BusWidth
);
2598 if (EFI_ERROR (Status
)) {
2599 DEBUG ((EFI_D_ERROR
, "SdPeimSetBusMode: SdPeimSwitchBusWidth fails with %r\n", Status
));
2604 // Calculate supported bus speed/bus width/clock frequency.
2607 if (S18a
&& (Capability
.Sdr104
!= 0)) {
2610 } else if (S18a
&& (Capability
.Sdr50
!= 0)) {
2613 } else if (S18a
&& (Capability
.Ddr50
!= 0)) {
2621 DEBUG ((EFI_D_INFO
, "AccessMode %d ClockFreq %d BusWidth %d\n", AccessMode
, ClockFreq
, BusWidth
));
2623 Status
= SdPeimSwitch (Slot
, AccessMode
, 0, 0, 0, TRUE
);
2624 if (EFI_ERROR (Status
)) {
2625 DEBUG ((EFI_D_ERROR
, "SdPeimSetBusMode: SdPeimSwitch fails with %r\n", Status
));
2630 // Set to Hight Speed timing
2632 if (AccessMode
== 1) {
2634 Status
= SdPeimHcOrMmio (Slot
->SdHcBase
+ SD_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
2635 if (EFI_ERROR (Status
)) {
2640 HostCtrl2
= (UINT8
)~0x7;
2641 Status
= SdPeimHcAndMmio (Slot
->SdHcBase
+ SD_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2642 if (EFI_ERROR (Status
)) {
2645 HostCtrl2
= AccessMode
;
2646 Status
= SdPeimHcOrMmio (Slot
->SdHcBase
+ SD_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2647 if (EFI_ERROR (Status
)) {
2651 Status
= SdPeimHcClockSupply (Slot
->SdHcBase
, ClockFreq
* 1000);
2652 if (EFI_ERROR (Status
)) {
2653 DEBUG ((EFI_D_ERROR
, "SdPeimSetBusMode: SdPeimHcClockSupply %r\n", Status
));
2657 if ((AccessMode
== 3) || ((AccessMode
== 2) && (Capability
.TuningSDR50
!= 0))) {
2658 Status
= SdPeimTuningClock (Slot
);
2659 if (EFI_ERROR (Status
)) {
2660 DEBUG ((EFI_D_ERROR
, "SdPeimSetBusMode: SdPeimTuningClock fails with %r\n", Status
));
2665 DEBUG ((EFI_D_INFO
, "SdPeimSetBusMode: SdPeimSetBusMode %r\n", Status
));
2671 Execute SD device identification procedure.
2673 Refer to SD Physical Layer Simplified Spec 4.1 Section 3.6 for details.
2675 @param[in] Slot The slot number of the SD card to send the command to.
2677 @retval EFI_SUCCESS There is a SD card.
2678 @retval Others There is not a SD card.
2682 SdPeimIdentification (
2683 IN SD_PEIM_HC_SLOT
*Slot
2693 UINT16 ControllerVer
;
2695 UINT32 PresentState
;
2697 SD_HC_SLOT_CAP Capability
;
2700 // 1. Send Cmd0 to the device
2702 Status
= SdPeimReset (Slot
);
2703 if (EFI_ERROR (Status
)) {
2704 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: Executing Cmd0 fails with %r\n", Status
));
2708 // 2. Send Cmd8 to the device
2710 Status
= SdPeimVoltageCheck (Slot
, 0x1, 0xFF);
2711 if (EFI_ERROR (Status
)) {
2712 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: Executing Cmd8 fails with %r\n", Status
));
2716 // 3. Send SDIO Cmd5 to the device to the SDIO device OCR register.
2718 Status
= SdioSendOpCond (Slot
, 0, FALSE
);
2719 if (!EFI_ERROR (Status
)) {
2720 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: Found SDIO device, ignore it as we don't support\n"));
2721 return EFI_DEVICE_ERROR
;
2724 // 4. Send Acmd41 with voltage window 0 to the device
2726 Status
= SdPeimSendOpCond (Slot
, 0, 0, FALSE
, FALSE
, FALSE
, &Ocr
);
2727 if (EFI_ERROR (Status
)) {
2728 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: Executing SdPeimSendOpCond fails with %r\n", Status
));
2729 return EFI_DEVICE_ERROR
;
2732 Status
= SdPeimHcGetCapability (Slot
->SdHcBase
, &Capability
);
2733 if (EFI_ERROR (Status
)) {
2737 Status
= SdPeimHcRwMmio (Slot
->SdHcBase
+ SD_HC_MAX_CURRENT_CAP
, TRUE
, sizeof (Current
), &Current
);
2738 if (EFI_ERROR (Status
)) {
2742 if (Capability
.Voltage33
!= 0) {
2746 MaxCurrent
= ((UINT32
)Current
& 0xFF) * 4;
2747 } else if (Capability
.Voltage30
!= 0) {
2751 MaxCurrent
= (((UINT32
)Current
>> 8) & 0xFF) * 4;
2752 } else if (Capability
.Voltage18
!= 0) {
2756 MaxCurrent
= (((UINT32
)Current
>> 16) & 0xFF) * 4;
2759 return EFI_DEVICE_ERROR
;
2762 if (MaxCurrent
>= 150) {
2768 Status
= SdPeimHcRwMmio (Slot
->SdHcBase
+ SD_HC_CTRL_VER
, TRUE
, sizeof (ControllerVer
), &ControllerVer
);
2769 if (EFI_ERROR (Status
)) {
2773 if ((ControllerVer
& 0xFF) == 2) {
2775 } else if (((ControllerVer
& 0xFF) == 0) || ((ControllerVer
& 0xFF) == 1)) {
2779 return EFI_UNSUPPORTED
;
2782 // 5. Repeatly send Acmd41 with supply voltage window to the device.
2783 // Note here we only support the cards complied with SD physical
2784 // layer simplified spec version 2.0 and version 3.0 and above.
2787 Status
= SdPeimSendOpCond (Slot
, 0, Ocr
, S18r
, Xpc
, TRUE
, &Ocr
);
2788 if (EFI_ERROR (Status
)) {
2789 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: SdPeimSendOpCond fails with %r Ocr %x, S18r %x, Xpc %x\n", Status
, Ocr
, S18r
, Xpc
));
2790 return EFI_DEVICE_ERROR
;
2792 } while ((Ocr
& BIT31
) == 0);
2795 // 6. If the S18a bit is set and the Host Controller supports 1.8V signaling
2796 // (One of support bits is set to 1: SDR50, SDR104 or DDR50 in the
2797 // Capabilities register), switch its voltage to 1.8V.
2799 if ((Capability
.Sdr50
!= 0 ||
2800 Capability
.Sdr104
!= 0 ||
2801 Capability
.Ddr50
!= 0) &&
2802 ((Ocr
& BIT24
) != 0)) {
2803 Status
= SdPeimVoltageSwitch (Slot
);
2804 if (EFI_ERROR (Status
)) {
2805 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: Executing SdPeimVoltageSwitch fails with %r\n", Status
));
2806 Status
= EFI_DEVICE_ERROR
;
2809 Status
= SdPeimHcStopClock (Slot
->SdHcBase
);
2810 if (EFI_ERROR (Status
)) {
2811 Status
= EFI_DEVICE_ERROR
;
2815 SdPeimHcRwMmio (Slot
->SdHcBase
+ SD_HC_PRESENT_STATE
, TRUE
, sizeof (PresentState
), &PresentState
);
2816 if (((PresentState
>> 20) & 0xF) != 0) {
2817 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: SwitchVoltage fails with PresentState = 0x%x\n", PresentState
));
2818 Status
= EFI_DEVICE_ERROR
;
2822 SdPeimHcOrMmio (Slot
->SdHcBase
+ SD_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2824 MicroSecondDelay (5000);
2826 SdPeimHcRwMmio (Slot
->SdHcBase
+ SD_HC_HOST_CTRL2
, TRUE
, sizeof (HostCtrl2
), &HostCtrl2
);
2827 if ((HostCtrl2
& BIT3
) == 0) {
2828 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: SwitchVoltage fails with HostCtrl2 = 0x%x\n", HostCtrl2
));
2829 Status
= EFI_DEVICE_ERROR
;
2833 SdPeimHcInitClockFreq (Slot
->SdHcBase
);
2835 MicroSecondDelay (1000);
2837 SdPeimHcRwMmio (Slot
->SdHcBase
+ SD_HC_PRESENT_STATE
, TRUE
, sizeof (PresentState
), &PresentState
);
2838 if (((PresentState
>> 20) & 0xF) != 0xF) {
2839 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: SwitchVoltage fails with PresentState = 0x%x, It should be 0xF\n", PresentState
));
2840 Status
= EFI_DEVICE_ERROR
;
2844 DEBUG ((EFI_D_INFO
, "SdPeimIdentification: Switch to 1.8v signal voltage success\n"));
2847 Status
= SdPeimAllSendCid (Slot
);
2848 if (EFI_ERROR (Status
)) {
2849 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: Executing SdPeimAllSendCid fails with %r\n", Status
));
2853 Status
= SdPeimSetRca (Slot
, &Rca
);
2854 if (EFI_ERROR (Status
)) {
2855 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: Executing SdPeimSetRca fails with %r\n", Status
));
2859 // Enter Data Tranfer Mode.
2861 DEBUG ((EFI_D_INFO
, "Found a SD device at slot [%d]\n", Slot
));
2863 Status
= SdPeimSetBusMode (Slot
, Rca
, ((Ocr
& BIT24
) != 0));
2869 // Set SD Bus Power = 0
2871 PowerCtrl
= (UINT8
)~BIT0
;
2872 Status
= SdPeimHcAndMmio (Slot
->SdHcBase
+ SD_HC_POWER_CTRL
, sizeof (PowerCtrl
), &PowerCtrl
);
2873 return EFI_DEVICE_ERROR
;