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
;
539 if (ClockFreq
== 0) {
540 return EFI_INVALID_PARAMETER
;
543 if (ClockFreq
> (BaseClkFreq
* 1000)) {
544 ClockFreq
= BaseClkFreq
* 1000;
548 // Calculate the divisor of base frequency.
551 SettingFreq
= BaseClkFreq
* 1000;
552 while (ClockFreq
< SettingFreq
) {
555 SettingFreq
= (BaseClkFreq
* 1000) / (2 * Divisor
);
556 Remainder
= (BaseClkFreq
* 1000) % (2 * Divisor
);
557 if ((ClockFreq
== SettingFreq
) && (Remainder
== 0)) {
560 if ((ClockFreq
== SettingFreq
) && (Remainder
!= 0)) {
565 DEBUG ((EFI_D_INFO
, "BaseClkFreq %dMHz Divisor %d ClockFreq %dKhz\n", BaseClkFreq
, Divisor
, ClockFreq
));
567 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_CTRL_VER
, TRUE
, sizeof (ControllerVer
), &ControllerVer
);
568 if (EFI_ERROR (Status
)) {
572 // Set SDCLK Frequency Select and Internal Clock Enable fields in Clock Control register.
574 if ((ControllerVer
& 0xFF) == 2) {
575 ASSERT (Divisor
<= 0x3FF);
576 ClockCtrl
= ((Divisor
& 0xFF) << 8) | ((Divisor
& 0x300) >> 2);
577 } else if (((ControllerVer
& 0xFF) == 0) || ((ControllerVer
& 0xFF) == 1)) {
579 // Only the most significant bit can be used as divisor.
581 if (((Divisor
- 1) & Divisor
) != 0) {
582 Divisor
= 1 << (HighBitSet32 (Divisor
) + 1);
584 ASSERT (Divisor
<= 0x80);
585 ClockCtrl
= (Divisor
& 0xFF) << 8;
587 DEBUG ((EFI_D_ERROR
, "Unknown SD Host Controller Spec version [0x%x]!!!\n", ControllerVer
));
588 return EFI_UNSUPPORTED
;
592 // Stop bus clock at first
594 Status
= SdPeimHcStopClock (Bar
);
595 if (EFI_ERROR (Status
)) {
600 // Supply clock frequency with specified divisor
603 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_CLOCK_CTRL
, FALSE
, sizeof (ClockCtrl
), &ClockCtrl
);
604 if (EFI_ERROR (Status
)) {
605 DEBUG ((EFI_D_ERROR
, "Set SDCLK Frequency Select and Internal Clock Enable fields fails\n"));
610 // Wait Internal Clock Stable in the Clock Control register to be 1
612 Status
= SdPeimHcWaitMmioSet (
613 Bar
+ SD_HC_CLOCK_CTRL
,
619 if (EFI_ERROR (Status
)) {
624 // Set SD Clock Enable in the Clock Control register to 1
627 Status
= SdPeimHcOrMmio (Bar
+ SD_HC_CLOCK_CTRL
, sizeof (ClockCtrl
), &ClockCtrl
);
633 SD bus power control.
635 Refer to SD Host Controller Simplified spec 3.0 Section 3.3 for details.
637 @param[in] Bar The mmio base address of the slot to be accessed.
638 @param[in] PowerCtrl The value setting to the power control register.
640 @retval TRUE There is a SD card attached.
641 @retval FALSE There is no a SD card attached.
645 SdPeimHcPowerControl (
655 PowerCtrl
&= (UINT8
)~BIT0
;
656 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_POWER_CTRL
, FALSE
, sizeof (PowerCtrl
), &PowerCtrl
);
657 if (EFI_ERROR (Status
)) {
662 // Set SD Bus Voltage Select and SD Bus Power fields in Power Control Register
665 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_POWER_CTRL
, FALSE
, sizeof (PowerCtrl
), &PowerCtrl
);
671 Set the SD bus width.
673 Refer to SD Host Controller Simplified spec 3.0 Section 3.4 for details.
675 @param[in] Bar The mmio base address of the slot to be accessed.
676 @param[in] BusWidth The bus width used by the SD device, it must be 1, 4 or 8.
678 @retval EFI_SUCCESS The bus width is set successfully.
679 @retval Others The bus width isn't set successfully.
683 SdPeimHcSetBusWidth (
692 HostCtrl1
= (UINT8
)~(BIT5
| BIT1
);
693 Status
= SdPeimHcAndMmio (Bar
+ SD_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
694 } else if (BusWidth
== 4) {
695 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_HOST_CTRL1
, TRUE
, sizeof (HostCtrl1
), &HostCtrl1
);
696 if (EFI_ERROR (Status
)) {
700 HostCtrl1
&= (UINT8
)~BIT5
;
701 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_HOST_CTRL1
, FALSE
, sizeof (HostCtrl1
), &HostCtrl1
);
702 } else if (BusWidth
== 8) {
703 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_HOST_CTRL1
, TRUE
, sizeof (HostCtrl1
), &HostCtrl1
);
704 if (EFI_ERROR (Status
)) {
707 HostCtrl1
&= (UINT8
)~BIT1
;
709 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_HOST_CTRL1
, FALSE
, sizeof (HostCtrl1
), &HostCtrl1
);
712 return EFI_INVALID_PARAMETER
;
719 Supply SD card with lowest clock frequency at initialization.
721 @param[in] Bar The mmio base address of the slot to be accessed.
723 @retval EFI_SUCCESS The clock is supplied successfully.
724 @retval Others The clock isn't supplied successfully.
728 SdPeimHcInitClockFreq (
733 SD_HC_SLOT_CAP Capability
;
737 // Calculate a divisor for SD clock frequency
739 Status
= SdPeimHcGetCapability (Bar
, &Capability
);
740 if (EFI_ERROR (Status
)) {
744 if (Capability
.BaseClkFreq
== 0) {
746 // Don't support get Base Clock Frequency information via another method
748 return EFI_UNSUPPORTED
;
751 // Supply 400KHz clock frequency at initialization phase.
754 Status
= SdPeimHcClockSupply (Bar
, InitFreq
);
759 Supply SD card with maximum voltage at initialization.
761 Refer to SD Host Controller Simplified spec 3.0 Section 3.3 for details.
763 @param[in] Bar The mmio base address of the slot to be accessed.
765 @retval EFI_SUCCESS The voltage is supplied successfully.
766 @retval Others The voltage isn't supplied successfully.
770 SdPeimHcInitPowerVoltage (
775 SD_HC_SLOT_CAP Capability
;
780 // Get the support voltage of the Host Controller
782 Status
= SdPeimHcGetCapability (Bar
, &Capability
);
783 if (EFI_ERROR (Status
)) {
787 // Calculate supported maximum voltage according to SD Bus Voltage Select
789 if (Capability
.Voltage33
!= 0) {
794 } else if (Capability
.Voltage30
!= 0) {
799 } else if (Capability
.Voltage18
!= 0) {
805 Status
= SdPeimHcOrMmio (Bar
+ SD_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
806 if (EFI_ERROR (Status
)) {
809 MicroSecondDelay (5000);
812 return EFI_DEVICE_ERROR
;
816 // Set SD Bus Voltage Select and SD Bus Power fields in Power Control Register
818 Status
= SdPeimHcPowerControl (Bar
, MaxVoltage
);
824 Initialize the Timeout Control register with most conservative value at initialization.
826 Refer to SD Host Controller Simplified spec 3.0 Section 2.2.15 for details.
828 @param[in] Bar The mmio base address of the slot to be accessed.
830 @retval EFI_SUCCESS The timeout control register is configured successfully.
831 @retval Others The timeout control register isn't configured successfully.
835 SdPeimHcInitTimeoutCtrl (
843 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_TIMEOUT_CTRL
, FALSE
, sizeof (Timeout
), &Timeout
);
849 Initial SD host controller with lowest clock frequency, max power and max timeout value
852 @param[in] Bar The mmio base address of the slot to be accessed.
854 @retval EFI_SUCCESS The host controller is initialized successfully.
855 @retval Others The host controller isn't initialized successfully.
865 Status
= SdPeimHcInitClockFreq (Bar
);
866 if (EFI_ERROR (Status
)) {
870 Status
= SdPeimHcInitPowerVoltage (Bar
);
871 if (EFI_ERROR (Status
)) {
875 Status
= SdPeimHcInitTimeoutCtrl (Bar
);
882 @param[in] Bar The mmio base address of the slot to be accessed.
883 @param[in] On The boolean to turn on/off LED.
885 @retval EFI_SUCCESS The LED is turned on/off successfully.
886 @retval Others The LED isn't turned on/off successfully.
900 Status
= SdPeimHcOrMmio (Bar
+ SD_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
902 HostCtrl1
= (UINT8
)~BIT0
;
903 Status
= SdPeimHcAndMmio (Bar
+ SD_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
910 Build ADMA descriptor table for transfer.
912 Refer to SD Host Controller Simplified spec 3.0 Section 1.13 for details.
914 @param[in] Trb The pointer to the SD_TRB instance.
916 @retval EFI_SUCCESS The ADMA descriptor table is created successfully.
917 @retval Others The ADMA descriptor table isn't created successfully.
925 EFI_PHYSICAL_ADDRESS Data
;
932 Data
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)Trb
->Data
;
933 DataLen
= Trb
->DataLen
;
935 // Only support 32bit ADMA Descriptor Table
937 if ((Data
>= 0x100000000ul
) || ((Data
+ DataLen
) > 0x100000000ul
)) {
938 return EFI_INVALID_PARAMETER
;
941 // Address field shall be set on 32-bit boundary (Lower 2-bit is always set to 0)
942 // for 32-bit address descriptor table.
944 if ((Data
& (BIT0
| BIT1
)) != 0) {
945 DEBUG ((EFI_D_INFO
, "The buffer [0x%x] to construct ADMA desc is not aligned to 4 bytes boundary!\n", Data
));
948 Entries
= DivU64x32 ((DataLen
+ ADMA_MAX_DATA_PER_LINE
- 1), ADMA_MAX_DATA_PER_LINE
);
950 Trb
->AdmaDescSize
= (UINTN
)MultU64x32 (Entries
, sizeof (SD_HC_ADMA_DESC_LINE
));
951 Trb
->AdmaDesc
= SdPeimAllocateMem (Trb
->Slot
->Private
->Pool
, Trb
->AdmaDescSize
);
952 if (Trb
->AdmaDesc
== NULL
) {
953 return EFI_OUT_OF_RESOURCES
;
957 Address
= (UINT32
)Data
;
958 for (Index
= 0; Index
< Entries
; Index
++) {
959 if (Remaining
<= ADMA_MAX_DATA_PER_LINE
) {
960 Trb
->AdmaDesc
[Index
].Valid
= 1;
961 Trb
->AdmaDesc
[Index
].Act
= 2;
962 Trb
->AdmaDesc
[Index
].Length
= (UINT16
)Remaining
;
963 Trb
->AdmaDesc
[Index
].Address
= Address
;
966 Trb
->AdmaDesc
[Index
].Valid
= 1;
967 Trb
->AdmaDesc
[Index
].Act
= 2;
968 Trb
->AdmaDesc
[Index
].Length
= 0;
969 Trb
->AdmaDesc
[Index
].Address
= Address
;
972 Remaining
-= ADMA_MAX_DATA_PER_LINE
;
973 Address
+= ADMA_MAX_DATA_PER_LINE
;
977 // Set the last descriptor line as end of descriptor table
979 Trb
->AdmaDesc
[Index
].End
= 1;
984 Create a new TRB for the SD cmd request.
986 @param[in] Slot The slot number of the SD card to send the command to.
987 @param[in] Packet A pointer to the SD command data structure.
989 @return Created Trb or NULL.
994 IN SD_PEIM_HC_SLOT
*Slot
,
995 IN SD_COMMAND_PACKET
*Packet
1000 SD_HC_SLOT_CAP Capability
;
1003 // Calculate a divisor for SD clock frequency
1005 Status
= SdPeimHcGetCapability (Slot
->SdHcBase
, &Capability
);
1006 if (EFI_ERROR (Status
)) {
1010 Trb
= SdPeimAllocateMem (Slot
->Private
->Pool
, sizeof (SD_TRB
));
1016 Trb
->BlockSize
= 0x200;
1017 Trb
->Packet
= Packet
;
1018 Trb
->Timeout
= Packet
->Timeout
;
1020 if ((Packet
->InTransferLength
!= 0) && (Packet
->InDataBuffer
!= NULL
)) {
1021 Trb
->Data
= Packet
->InDataBuffer
;
1022 Trb
->DataLen
= Packet
->InTransferLength
;
1024 } else if ((Packet
->OutTransferLength
!= 0) && (Packet
->OutDataBuffer
!= NULL
)) {
1025 Trb
->Data
= Packet
->OutDataBuffer
;
1026 Trb
->DataLen
= Packet
->OutTransferLength
;
1028 } else if ((Packet
->InTransferLength
== 0) && (Packet
->OutTransferLength
== 0)) {
1035 if ((Trb
->DataLen
% Trb
->BlockSize
) != 0) {
1036 if (Trb
->DataLen
< Trb
->BlockSize
) {
1037 Trb
->BlockSize
= (UINT16
)Trb
->DataLen
;
1041 if (Trb
->DataLen
== 0) {
1042 Trb
->Mode
= SdNoData
;
1043 } else if (Capability
.Adma2
!= 0) {
1044 Trb
->Mode
= SdAdmaMode
;
1045 Status
= BuildAdmaDescTable (Trb
);
1046 if (EFI_ERROR (Status
)) {
1049 } else if (Capability
.Sdma
!= 0) {
1050 Trb
->Mode
= SdSdmaMode
;
1052 Trb
->Mode
= SdPioMode
;
1058 SdPeimFreeTrb (Trb
);
1063 Free the resource used by the TRB.
1065 @param[in] Trb The pointer to the SD_TRB instance.
1073 if ((Trb
!= NULL
) && (Trb
->AdmaDesc
!= NULL
)) {
1074 SdPeimFreeMem (Trb
->Slot
->Private
->Pool
, Trb
->AdmaDesc
, Trb
->AdmaDescSize
);
1078 SdPeimFreeMem (Trb
->Slot
->Private
->Pool
, Trb
, sizeof (SD_TRB
));
1084 Check if the env is ready for execute specified TRB.
1086 @param[in] Bar The mmio base address of the slot to be accessed.
1087 @param[in] Trb The pointer to the SD_TRB instance.
1089 @retval EFI_SUCCESS The env is ready for TRB execution.
1090 @retval EFI_NOT_READY The env is not ready for TRB execution.
1091 @retval Others Some erros happen.
1101 SD_COMMAND_PACKET
*Packet
;
1102 UINT32 PresentState
;
1104 Packet
= Trb
->Packet
;
1106 if ((Packet
->SdCmdBlk
->CommandType
== SdCommandTypeAdtc
) ||
1107 (Packet
->SdCmdBlk
->ResponseType
== SdResponseTypeR1b
) ||
1108 (Packet
->SdCmdBlk
->ResponseType
== SdResponseTypeR5b
)) {
1110 // Wait Command Inhibit (CMD) and Command Inhibit (DAT) in
1111 // the Present State register to be 0
1113 PresentState
= BIT0
| BIT1
;
1114 if (Packet
->SdCmdBlk
->CommandIndex
== SD_SEND_TUNING_BLOCK
) {
1115 PresentState
= BIT0
;
1119 // Wait Command Inhibit (CMD) in the Present State register
1122 PresentState
= BIT0
;
1125 Status
= SdPeimHcCheckMmioSet (
1126 Bar
+ SD_HC_PRESENT_STATE
,
1127 sizeof (PresentState
),
1136 Wait for the env to be ready for execute specified TRB.
1138 @param[in] Bar The mmio base address of the slot to be accessed.
1139 @param[in] Trb The pointer to the SD_TRB instance.
1141 @retval EFI_SUCCESS The env is ready for TRB execution.
1142 @retval EFI_TIMEOUT The env is not ready for TRB execution in time.
1143 @retval Others Some erros happen.
1153 SD_COMMAND_PACKET
*Packet
;
1155 BOOLEAN InfiniteWait
;
1158 // Wait Command Complete Interrupt Status bit in Normal Interrupt Status Register
1160 Packet
= Trb
->Packet
;
1161 Timeout
= Packet
->Timeout
;
1163 InfiniteWait
= TRUE
;
1165 InfiniteWait
= FALSE
;
1168 while (InfiniteWait
|| (Timeout
> 0)) {
1170 // Check Trb execution result by reading Normal Interrupt Status register.
1172 Status
= SdPeimCheckTrbEnv (Bar
, Trb
);
1173 if (Status
!= EFI_NOT_READY
) {
1177 // Stall for 1 microsecond.
1179 MicroSecondDelay (1);
1188 Execute the specified TRB.
1190 @param[in] Bar The mmio base address of the slot to be accessed.
1191 @param[in] Trb The pointer to the SD_TRB instance.
1193 @retval EFI_SUCCESS The TRB is sent to host controller successfully.
1194 @retval Others Some erros happen when sending this request to the host controller.
1204 SD_COMMAND_PACKET
*Packet
;
1215 Packet
= Trb
->Packet
;
1217 // Clear all bits in Error Interrupt Status Register
1220 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_ERR_INT_STS
, FALSE
, sizeof (IntStatus
), &IntStatus
);
1221 if (EFI_ERROR (Status
)) {
1225 // Clear all bits in Normal Interrupt Status Register
1228 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_NOR_INT_STS
, FALSE
, sizeof (IntStatus
), &IntStatus
);
1229 if (EFI_ERROR (Status
)) {
1233 // Set Host Control 1 register DMA Select field
1235 if (Trb
->Mode
== SdAdmaMode
) {
1237 Status
= SdPeimHcOrMmio (Bar
+ SD_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
1238 if (EFI_ERROR (Status
)) {
1243 SdPeimHcLedOnOff (Bar
, TRUE
);
1245 if (Trb
->Mode
== SdSdmaMode
) {
1246 if ((UINT64
)(UINTN
)Trb
->Data
>= 0x100000000ul
) {
1247 return EFI_INVALID_PARAMETER
;
1250 SdmaAddr
= (UINT32
)(UINTN
)Trb
->Data
;
1251 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_SDMA_ADDR
, FALSE
, sizeof (SdmaAddr
), &SdmaAddr
);
1252 if (EFI_ERROR (Status
)) {
1255 } else if (Trb
->Mode
== SdAdmaMode
) {
1256 AdmaAddr
= (UINT64
)(UINTN
)Trb
->AdmaDesc
;
1257 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_ADMA_SYS_ADDR
, FALSE
, sizeof (AdmaAddr
), &AdmaAddr
);
1258 if (EFI_ERROR (Status
)) {
1263 BlkSize
= Trb
->BlockSize
;
1264 if (Trb
->Mode
== SdSdmaMode
) {
1266 // Set SDMA boundary to be 512K bytes.
1271 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_BLK_SIZE
, FALSE
, sizeof (BlkSize
), &BlkSize
);
1272 if (EFI_ERROR (Status
)) {
1276 BlkCount
= (UINT16
)(Trb
->DataLen
/ Trb
->BlockSize
);
1277 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_BLK_COUNT
, FALSE
, sizeof (BlkCount
), &BlkCount
);
1278 if (EFI_ERROR (Status
)) {
1282 Argument
= Packet
->SdCmdBlk
->CommandArgument
;
1283 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_ARG1
, FALSE
, sizeof (Argument
), &Argument
);
1284 if (EFI_ERROR (Status
)) {
1289 if (Trb
->Mode
!= SdNoData
) {
1290 if (Trb
->Mode
!= SdPioMode
) {
1296 if (BlkCount
!= 0) {
1297 TransMode
|= BIT5
| BIT1
;
1304 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_TRANS_MOD
, FALSE
, sizeof (TransMode
), &TransMode
);
1305 if (EFI_ERROR (Status
)) {
1309 Cmd
= (UINT16
)LShiftU64(Packet
->SdCmdBlk
->CommandIndex
, 8);
1310 if (Packet
->SdCmdBlk
->CommandType
== SdCommandTypeAdtc
) {
1314 // Convert ResponseType to value
1316 if (Packet
->SdCmdBlk
->CommandType
!= SdCommandTypeBc
) {
1317 switch (Packet
->SdCmdBlk
->ResponseType
) {
1318 case SdResponseTypeR1
:
1319 case SdResponseTypeR5
:
1320 case SdResponseTypeR6
:
1321 case SdResponseTypeR7
:
1322 Cmd
|= (BIT1
| BIT3
| BIT4
);
1324 case SdResponseTypeR2
:
1325 Cmd
|= (BIT0
| BIT3
);
1327 case SdResponseTypeR3
:
1328 case SdResponseTypeR4
:
1331 case SdResponseTypeR1b
:
1332 case SdResponseTypeR5b
:
1333 Cmd
|= (BIT0
| BIT1
| BIT3
| BIT4
);
1343 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_COMMAND
, FALSE
, sizeof (Cmd
), &Cmd
);
1348 Check the TRB execution result.
1350 @param[in] Bar The mmio base address of the slot to be accessed.
1351 @param[in] Trb The pointer to the SD_TRB instance.
1353 @retval EFI_SUCCESS The TRB is executed successfully.
1354 @retval EFI_NOT_READY The TRB is not completed for execution.
1355 @retval Others Some erros happen when executing this request.
1359 SdPeimCheckTrbResult (
1365 SD_COMMAND_PACKET
*Packet
;
1373 Packet
= Trb
->Packet
;
1375 // Check Trb execution result by reading Normal Interrupt Status register.
1377 Status
= SdPeimHcRwMmio (
1378 Bar
+ SD_HC_NOR_INT_STS
,
1383 if (EFI_ERROR (Status
)) {
1387 // Check Transfer Complete bit is set or not.
1389 if ((IntStatus
& BIT1
) == BIT1
) {
1390 if ((IntStatus
& BIT15
) == BIT15
) {
1392 // Read Error Interrupt Status register to check if the error is
1393 // Data Timeout Error.
1394 // If yes, treat it as success as Transfer Complete has higher
1395 // priority than Data Timeout Error.
1397 Status
= SdPeimHcRwMmio (
1398 Bar
+ SD_HC_ERR_INT_STS
,
1403 if (!EFI_ERROR (Status
)) {
1404 if ((IntStatus
& BIT4
) == BIT4
) {
1405 Status
= EFI_SUCCESS
;
1407 Status
= EFI_DEVICE_ERROR
;
1415 // Check if there is a error happened during cmd execution.
1416 // If yes, then do error recovery procedure to follow SD Host Controller
1417 // Simplified Spec 3.0 section 3.10.1.
1419 if ((IntStatus
& BIT15
) == BIT15
) {
1420 Status
= SdPeimHcRwMmio (
1421 Bar
+ SD_HC_ERR_INT_STS
,
1426 if (EFI_ERROR (Status
)) {
1430 if ((IntStatus
& 0x0F) != 0) {
1433 if ((IntStatus
& 0xF0) != 0) {
1437 Status
= SdPeimHcRwMmio (
1443 if (EFI_ERROR (Status
)) {
1446 Status
= SdPeimHcWaitMmioSet (
1453 if (EFI_ERROR (Status
)) {
1457 Status
= EFI_DEVICE_ERROR
;
1461 // Check if DMA interrupt is signalled for the SDMA transfer.
1463 if ((Trb
->Mode
== SdSdmaMode
) && ((IntStatus
& BIT3
) == BIT3
)) {
1465 // Clear DMA interrupt bit.
1468 Status
= SdPeimHcRwMmio (
1469 Bar
+ SD_HC_NOR_INT_STS
,
1474 if (EFI_ERROR (Status
)) {
1478 // Update SDMA Address register.
1480 SdmaAddr
= SD_SDMA_ROUND_UP ((UINT32
)(UINTN
)Trb
->Data
, SD_SDMA_BOUNDARY
);
1481 Status
= SdPeimHcRwMmio (
1482 Bar
+ SD_HC_SDMA_ADDR
,
1487 if (EFI_ERROR (Status
)) {
1490 Trb
->Data
= (VOID
*)(UINTN
)SdmaAddr
;
1493 if ((Packet
->SdCmdBlk
->CommandType
!= SdCommandTypeAdtc
) &&
1494 (Packet
->SdCmdBlk
->ResponseType
!= SdResponseTypeR1b
) &&
1495 (Packet
->SdCmdBlk
->ResponseType
!= SdResponseTypeR5b
)) {
1496 if ((IntStatus
& BIT0
) == BIT0
) {
1497 Status
= EFI_SUCCESS
;
1502 if (Packet
->SdCmdBlk
->CommandIndex
== SD_SEND_TUNING_BLOCK
) {
1503 Status
= EFI_SUCCESS
;
1507 Status
= EFI_NOT_READY
;
1510 // Get response data when the cmd is executed successfully.
1512 if (!EFI_ERROR (Status
)) {
1513 if (Packet
->SdCmdBlk
->CommandType
!= SdCommandTypeBc
) {
1514 for (Index
= 0; Index
< 4; Index
++) {
1515 Status
= SdPeimHcRwMmio (
1516 Bar
+ SD_HC_RESPONSE
+ Index
* 4,
1521 if (EFI_ERROR (Status
)) {
1522 SdPeimHcLedOnOff (Bar
, FALSE
);
1526 CopyMem (Packet
->SdStatusBlk
, Response
, sizeof (Response
));
1530 if (Status
!= EFI_NOT_READY
) {
1531 SdPeimHcLedOnOff (Bar
, FALSE
);
1538 Wait for the TRB execution result.
1540 @param[in] Bar The mmio base address of the slot to be accessed.
1541 @param[in] Trb The pointer to the SD_TRB instance.
1543 @retval EFI_SUCCESS The TRB is executed successfully.
1544 @retval Others Some erros happen when executing this request.
1548 SdPeimWaitTrbResult (
1554 SD_COMMAND_PACKET
*Packet
;
1556 BOOLEAN InfiniteWait
;
1558 Packet
= Trb
->Packet
;
1560 // Wait Command Complete Interrupt Status bit in Normal Interrupt Status Register
1562 Timeout
= Packet
->Timeout
;
1564 InfiniteWait
= TRUE
;
1566 InfiniteWait
= FALSE
;
1569 while (InfiniteWait
|| (Timeout
> 0)) {
1571 // Check Trb execution result by reading Normal Interrupt Status register.
1573 Status
= SdPeimCheckTrbResult (Bar
, Trb
);
1574 if (Status
!= EFI_NOT_READY
) {
1578 // Stall for 1 microsecond.
1580 MicroSecondDelay (1);
1589 Sends SD command to an SD card that is attached to the SD controller.
1591 If Packet is successfully sent to the SD card, then EFI_SUCCESS is returned.
1593 If a device error occurs while sending the Packet, then EFI_DEVICE_ERROR is returned.
1595 If Slot is not in a valid range for the SD controller, then EFI_INVALID_PARAMETER
1598 If Packet defines a data command but both InDataBuffer and OutDataBuffer are NULL,
1599 EFI_INVALID_PARAMETER is returned.
1601 @param[in] Slot The slot number of the Sd card to send the command to.
1602 @param[in,out] Packet A pointer to the SD command data structure.
1604 @retval EFI_SUCCESS The SD Command Packet was sent by the host.
1605 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send the SD
1607 @retval EFI_INVALID_PARAMETER Packet, Slot, or the contents of the Packet is invalid.
1608 @retval EFI_INVALID_PARAMETER Packet defines a data command but both InDataBuffer and
1609 OutDataBuffer are NULL.
1610 @retval EFI_NO_MEDIA SD Device not present in the Slot.
1611 @retval EFI_UNSUPPORTED The command described by the SD Command Packet is not
1612 supported by the host controller.
1613 @retval EFI_BAD_BUFFER_SIZE The InTransferLength or OutTransferLength exceeds the
1614 limit supported by SD card ( i.e. if the number of bytes
1615 exceed the Last LBA).
1621 IN SD_PEIM_HC_SLOT
*Slot
,
1622 IN OUT SD_COMMAND_PACKET
*Packet
1628 if (Packet
== NULL
) {
1629 return EFI_INVALID_PARAMETER
;
1632 if ((Packet
->SdCmdBlk
== NULL
) || (Packet
->SdStatusBlk
== NULL
)) {
1633 return EFI_INVALID_PARAMETER
;
1636 if ((Packet
->OutDataBuffer
== NULL
) && (Packet
->OutTransferLength
!= 0)) {
1637 return EFI_INVALID_PARAMETER
;
1640 if ((Packet
->InDataBuffer
== NULL
) && (Packet
->InTransferLength
!= 0)) {
1641 return EFI_INVALID_PARAMETER
;
1644 Trb
= SdPeimCreateTrb (Slot
, Packet
);
1646 return EFI_OUT_OF_RESOURCES
;
1649 Status
= SdPeimWaitTrbEnv (Slot
->SdHcBase
, Trb
);
1650 if (EFI_ERROR (Status
)) {
1654 Status
= SdPeimExecTrb (Slot
->SdHcBase
, Trb
);
1655 if (EFI_ERROR (Status
)) {
1659 Status
= SdPeimWaitTrbResult (Slot
->SdHcBase
, Trb
);
1660 if (EFI_ERROR (Status
)) {
1665 SdPeimFreeTrb (Trb
);
1671 Send command GO_IDLE_STATE to the device to make it go to Idle State.
1673 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
1675 @param[in] Slot The slot number of the SD card to send the command to.
1677 @retval EFI_SUCCESS The SD device is reset correctly.
1678 @retval Others The device reset fails.
1683 IN SD_PEIM_HC_SLOT
*Slot
1686 SD_COMMAND_BLOCK SdCmdBlk
;
1687 SD_STATUS_BLOCK SdStatusBlk
;
1688 SD_COMMAND_PACKET Packet
;
1691 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
1692 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
1693 ZeroMem (&Packet
, sizeof (Packet
));
1695 Packet
.SdCmdBlk
= &SdCmdBlk
;
1696 Packet
.SdStatusBlk
= &SdStatusBlk
;
1697 Packet
.Timeout
= SD_TIMEOUT
;
1699 SdCmdBlk
.CommandIndex
= SD_GO_IDLE_STATE
;
1700 SdCmdBlk
.CommandType
= SdCommandTypeBc
;
1701 SdCmdBlk
.ResponseType
= 0;
1702 SdCmdBlk
.CommandArgument
= 0;
1704 Status
= SdPeimExecCmd (Slot
, &Packet
);
1710 Send command SEND_IF_COND to the device to inquiry the SD Memory Card interface
1713 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
1715 @param[in] Slot The slot number of the SD card to send the command to.
1716 @param[in] SupplyVoltage The supplied voltage by the host.
1717 @param[in] CheckPattern The check pattern to be sent to the device.
1719 @retval EFI_SUCCESS The operation is done correctly.
1720 @retval Others The operation fails.
1724 SdPeimVoltageCheck (
1725 IN SD_PEIM_HC_SLOT
*Slot
,
1726 IN UINT8 SupplyVoltage
,
1727 IN UINT8 CheckPattern
1730 SD_COMMAND_BLOCK SdCmdBlk
;
1731 SD_STATUS_BLOCK SdStatusBlk
;
1732 SD_COMMAND_PACKET Packet
;
1735 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
1736 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
1737 ZeroMem (&Packet
, sizeof (Packet
));
1739 Packet
.SdCmdBlk
= &SdCmdBlk
;
1740 Packet
.SdStatusBlk
= &SdStatusBlk
;
1741 Packet
.Timeout
= SD_TIMEOUT
;
1743 SdCmdBlk
.CommandIndex
= SD_SEND_IF_COND
;
1744 SdCmdBlk
.CommandType
= SdCommandTypeBcr
;
1745 SdCmdBlk
.ResponseType
= SdResponseTypeR7
;
1746 SdCmdBlk
.CommandArgument
= (SupplyVoltage
<< 8) | CheckPattern
;
1748 Status
= SdPeimExecCmd (Slot
, &Packet
);
1749 if (!EFI_ERROR (Status
)) {
1750 if (SdStatusBlk
.Resp0
!= SdCmdBlk
.CommandArgument
) {
1751 return EFI_DEVICE_ERROR
;
1759 Send command SDIO_SEND_OP_COND to the device to see whether it is SDIO device.
1761 Refer to SDIO Simplified Spec 3 Section 3.2 for details.
1763 @param[in] Slot The slot number of the SD card to send the command to.
1764 @param[in] VoltageWindow The supply voltage window.
1765 @param[in] S18r The boolean to show if it should switch to 1.8v.
1767 @retval EFI_SUCCESS The operation is done correctly.
1768 @retval Others The operation fails.
1773 IN SD_PEIM_HC_SLOT
*Slot
,
1774 IN UINT32 VoltageWindow
,
1778 SD_COMMAND_BLOCK SdCmdBlk
;
1779 SD_STATUS_BLOCK SdStatusBlk
;
1780 SD_COMMAND_PACKET Packet
;
1784 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
1785 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
1786 ZeroMem (&Packet
, sizeof (Packet
));
1788 Packet
.SdCmdBlk
= &SdCmdBlk
;
1789 Packet
.SdStatusBlk
= &SdStatusBlk
;
1790 Packet
.Timeout
= SD_TIMEOUT
;
1792 SdCmdBlk
.CommandIndex
= SDIO_SEND_OP_COND
;
1793 SdCmdBlk
.CommandType
= SdCommandTypeBcr
;
1794 SdCmdBlk
.ResponseType
= SdResponseTypeR4
;
1796 Switch
= S18r
? BIT24
: 0;
1798 SdCmdBlk
.CommandArgument
= (VoltageWindow
& 0xFFFFFF) | Switch
;
1800 Status
= SdPeimExecCmd (Slot
, &Packet
);
1806 Send command SD_SEND_OP_COND to the device to see whether it is SDIO device.
1808 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
1810 @param[in] Slot The slot number of the SD card to send the command to.
1811 @param[in] Rca The relative device address of addressed device.
1812 @param[in] VoltageWindow The supply voltage window.
1813 @param[in] S18r The boolean to show if it should switch to 1.8v.
1814 @param[in] Xpc The boolean to show if it should provide 0.36w power control.
1815 @param[in] Hcs The boolean to show if it support host capacity info.
1816 @param[out] Ocr The buffer to store returned OCR register value.
1819 @retval EFI_SUCCESS The operation is done correctly.
1820 @retval Others The operation fails.
1825 IN SD_PEIM_HC_SLOT
*Slot
,
1827 IN UINT32 VoltageWindow
,
1834 SD_COMMAND_BLOCK SdCmdBlk
;
1835 SD_STATUS_BLOCK SdStatusBlk
;
1836 SD_COMMAND_PACKET Packet
;
1840 UINT32 HostCapacity
;
1842 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
1843 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
1844 ZeroMem (&Packet
, sizeof (Packet
));
1846 Packet
.SdCmdBlk
= &SdCmdBlk
;
1847 Packet
.SdStatusBlk
= &SdStatusBlk
;
1848 Packet
.Timeout
= SD_TIMEOUT
;
1850 SdCmdBlk
.CommandIndex
= SD_APP_CMD
;
1851 SdCmdBlk
.CommandType
= SdCommandTypeAc
;
1852 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
1853 SdCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
1855 Status
= SdPeimExecCmd (Slot
, &Packet
);
1856 if (EFI_ERROR (Status
)) {
1860 SdCmdBlk
.CommandIndex
= SD_SEND_OP_COND
;
1861 SdCmdBlk
.CommandType
= SdCommandTypeBcr
;
1862 SdCmdBlk
.ResponseType
= SdResponseTypeR3
;
1864 Switch
= S18r
? BIT24
: 0;
1865 MaxPower
= Xpc
? BIT28
: 0;
1866 HostCapacity
= Hcs
? BIT30
: 0;
1867 SdCmdBlk
.CommandArgument
= (VoltageWindow
& 0xFFFFFF) | Switch
| MaxPower
| HostCapacity
;
1869 Status
= SdPeimExecCmd (Slot
, &Packet
);
1870 if (!EFI_ERROR (Status
)) {
1872 // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12.
1874 *Ocr
= SdStatusBlk
.Resp0
;
1881 Broadcast command ALL_SEND_CID to the bus to ask all the SD devices to send the
1882 data of their CID registers.
1884 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
1886 @param[in] Slot The slot number of the SD card to send the command to.
1888 @retval EFI_SUCCESS The operation is done correctly.
1889 @retval Others The operation fails.
1894 IN SD_PEIM_HC_SLOT
*Slot
1897 SD_COMMAND_BLOCK SdCmdBlk
;
1898 SD_STATUS_BLOCK SdStatusBlk
;
1899 SD_COMMAND_PACKET Packet
;
1902 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
1903 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
1904 ZeroMem (&Packet
, sizeof (Packet
));
1906 Packet
.SdCmdBlk
= &SdCmdBlk
;
1907 Packet
.SdStatusBlk
= &SdStatusBlk
;
1908 Packet
.Timeout
= SD_TIMEOUT
;
1910 SdCmdBlk
.CommandIndex
= SD_ALL_SEND_CID
;
1911 SdCmdBlk
.CommandType
= SdCommandTypeBcr
;
1912 SdCmdBlk
.ResponseType
= SdResponseTypeR2
;
1913 SdCmdBlk
.CommandArgument
= 0;
1915 Status
= SdPeimExecCmd (Slot
, &Packet
);
1921 Send command SET_RELATIVE_ADDR to the SD device to assign a Relative device
1924 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
1926 @param[in] Slot The slot number of the SD card to send the command to.
1927 @param[out] Rca The relative device address to be assigned.
1929 @retval EFI_SUCCESS The operation is done correctly.
1930 @retval Others The operation fails.
1935 IN SD_PEIM_HC_SLOT
*Slot
,
1939 SD_COMMAND_BLOCK SdCmdBlk
;
1940 SD_STATUS_BLOCK SdStatusBlk
;
1941 SD_COMMAND_PACKET Packet
;
1944 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
1945 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
1946 ZeroMem (&Packet
, sizeof (Packet
));
1948 Packet
.SdCmdBlk
= &SdCmdBlk
;
1949 Packet
.SdStatusBlk
= &SdStatusBlk
;
1950 Packet
.Timeout
= SD_TIMEOUT
;
1952 SdCmdBlk
.CommandIndex
= SD_SET_RELATIVE_ADDR
;
1953 SdCmdBlk
.CommandType
= SdCommandTypeBcr
;
1954 SdCmdBlk
.ResponseType
= SdResponseTypeR6
;
1956 Status
= SdPeimExecCmd (Slot
, &Packet
);
1957 if (!EFI_ERROR (Status
)) {
1958 *Rca
= (UINT16
)(SdStatusBlk
.Resp0
>> 16);
1965 Send command SEND_CSD to the SD device to get the data of the CSD register.
1967 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
1969 @param[in] Slot The slot number of the SD card to send the command to.
1970 @param[in] Rca The relative device address of selected device.
1971 @param[out] Csd The buffer to store the content of the CSD register.
1972 Note the caller should ignore the lowest byte of this
1973 buffer as the content of this byte is meaningless even
1974 if the operation succeeds.
1976 @retval EFI_SUCCESS The operation is done correctly.
1977 @retval Others The operation fails.
1982 IN SD_PEIM_HC_SLOT
*Slot
,
1987 SD_COMMAND_BLOCK SdCmdBlk
;
1988 SD_STATUS_BLOCK SdStatusBlk
;
1989 SD_COMMAND_PACKET Packet
;
1992 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
1993 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
1994 ZeroMem (&Packet
, sizeof (Packet
));
1996 Packet
.SdCmdBlk
= &SdCmdBlk
;
1997 Packet
.SdStatusBlk
= &SdStatusBlk
;
1998 Packet
.Timeout
= SD_TIMEOUT
;
2000 SdCmdBlk
.CommandIndex
= SD_SEND_CSD
;
2001 SdCmdBlk
.CommandType
= SdCommandTypeAc
;
2002 SdCmdBlk
.ResponseType
= SdResponseTypeR2
;
2003 SdCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
2005 Status
= SdPeimExecCmd (Slot
, &Packet
);
2006 if (!EFI_ERROR (Status
)) {
2008 // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12.
2010 CopyMem (((UINT8
*)Csd
) + 1, &SdStatusBlk
.Resp0
, sizeof (SD_CSD
) - 1);
2017 Send command SELECT_DESELECT_CARD to the SD device to select/deselect it.
2019 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
2021 @param[in] Slot The slot number of the SD card to send the command to.
2022 @param[in] Rca The relative device address of selected device.
2024 @retval EFI_SUCCESS The operation is done correctly.
2025 @retval Others The operation fails.
2030 IN SD_PEIM_HC_SLOT
*Slot
,
2034 SD_COMMAND_BLOCK SdCmdBlk
;
2035 SD_STATUS_BLOCK SdStatusBlk
;
2036 SD_COMMAND_PACKET Packet
;
2039 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
2040 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
2041 ZeroMem (&Packet
, sizeof (Packet
));
2043 Packet
.SdCmdBlk
= &SdCmdBlk
;
2044 Packet
.SdStatusBlk
= &SdStatusBlk
;
2045 Packet
.Timeout
= SD_TIMEOUT
;
2047 SdCmdBlk
.CommandIndex
= SD_SELECT_DESELECT_CARD
;
2048 SdCmdBlk
.CommandType
= SdCommandTypeAc
;
2049 SdCmdBlk
.ResponseType
= SdResponseTypeR1b
;
2050 SdCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
2052 Status
= SdPeimExecCmd (Slot
, &Packet
);
2058 Send command VOLTAGE_SWITCH to the SD device to switch the voltage of the device.
2060 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
2062 @param[in] Slot The slot number of the SD card to send the command to.
2064 @retval EFI_SUCCESS The operation is done correctly.
2065 @retval Others The operation fails.
2069 SdPeimVoltageSwitch (
2070 IN SD_PEIM_HC_SLOT
*Slot
2073 SD_COMMAND_BLOCK SdCmdBlk
;
2074 SD_STATUS_BLOCK SdStatusBlk
;
2075 SD_COMMAND_PACKET Packet
;
2078 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
2079 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
2080 ZeroMem (&Packet
, sizeof (Packet
));
2082 Packet
.SdCmdBlk
= &SdCmdBlk
;
2083 Packet
.SdStatusBlk
= &SdStatusBlk
;
2084 Packet
.Timeout
= SD_TIMEOUT
;
2086 SdCmdBlk
.CommandIndex
= SD_VOLTAGE_SWITCH
;
2087 SdCmdBlk
.CommandType
= SdCommandTypeAc
;
2088 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2089 SdCmdBlk
.CommandArgument
= 0;
2091 Status
= SdPeimExecCmd (Slot
, &Packet
);
2097 Send command SET_BUS_WIDTH to the SD device to set the bus width.
2099 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
2101 @param[in] Slot The slot number of the SD card to send the command to.
2102 @param[in] Rca The relative device address of addressed device.
2103 @param[in] BusWidth The bus width to be set, it could be 1 or 4.
2105 @retval EFI_SUCCESS The operation is done correctly.
2106 @retval Others The operation fails.
2111 IN SD_PEIM_HC_SLOT
*Slot
,
2116 SD_COMMAND_BLOCK SdCmdBlk
;
2117 SD_STATUS_BLOCK SdStatusBlk
;
2118 SD_COMMAND_PACKET Packet
;
2122 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
2123 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
2124 ZeroMem (&Packet
, sizeof (Packet
));
2126 Packet
.SdCmdBlk
= &SdCmdBlk
;
2127 Packet
.SdStatusBlk
= &SdStatusBlk
;
2128 Packet
.Timeout
= SD_TIMEOUT
;
2130 SdCmdBlk
.CommandIndex
= SD_APP_CMD
;
2131 SdCmdBlk
.CommandType
= SdCommandTypeAc
;
2132 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2133 SdCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
2135 Status
= SdPeimExecCmd (Slot
, &Packet
);
2136 if (EFI_ERROR (Status
)) {
2140 SdCmdBlk
.CommandIndex
= SD_SET_BUS_WIDTH
;
2141 SdCmdBlk
.CommandType
= SdCommandTypeAc
;
2142 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2144 if (BusWidth
== 1) {
2146 } else if (BusWidth
== 4) {
2149 return EFI_INVALID_PARAMETER
;
2151 SdCmdBlk
.CommandArgument
= Value
& 0x3;
2153 Status
= SdPeimExecCmd (Slot
, &Packet
);
2159 Send command SWITCH_FUNC to the SD device to check switchable function or switch card function.
2161 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
2163 @param[in] Slot The slot number of the SD card to send the command to.
2164 @param[in] AccessMode The value for access mode group.
2165 @param[in] CommandSystem The value for command set group.
2166 @param[in] DriveStrength The value for drive length group.
2167 @param[in] PowerLimit The value for power limit group.
2168 @param[in] Mode Switch or check function.
2170 @retval EFI_SUCCESS The operation is done correctly.
2171 @retval Others The operation fails.
2176 IN SD_PEIM_HC_SLOT
*Slot
,
2177 IN UINT8 AccessMode
,
2178 IN UINT8 CommandSystem
,
2179 IN UINT8 DriveStrength
,
2180 IN UINT8 PowerLimit
,
2184 SD_COMMAND_BLOCK SdCmdBlk
;
2185 SD_STATUS_BLOCK SdStatusBlk
;
2186 SD_COMMAND_PACKET Packet
;
2191 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
2192 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
2193 ZeroMem (&Packet
, sizeof (Packet
));
2195 Packet
.SdCmdBlk
= &SdCmdBlk
;
2196 Packet
.SdStatusBlk
= &SdStatusBlk
;
2197 Packet
.Timeout
= SD_TIMEOUT
;
2199 SdCmdBlk
.CommandIndex
= SD_SWITCH_FUNC
;
2200 SdCmdBlk
.CommandType
= SdCommandTypeAdtc
;
2201 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2203 ModeValue
= Mode
? BIT31
: 0;
2204 SdCmdBlk
.CommandArgument
= (AccessMode
& 0xF) | ((PowerLimit
& 0xF) << 4) | \
2205 ((DriveStrength
& 0xF) << 8) | ((DriveStrength
& 0xF) << 12) | \
2207 Packet
.InDataBuffer
= Data
;
2208 Packet
.InTransferLength
= sizeof (Data
);
2210 Status
= SdPeimExecCmd (Slot
, &Packet
);
2216 Send command SEND_STATUS to the addressed SD device to get its status register.
2218 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
2220 @param[in] Slot The slot number of the SD card to send the command to.
2221 @param[in] Rca The relative device address of addressed device.
2222 @param[out] DevStatus The returned device status.
2224 @retval EFI_SUCCESS The operation is done correctly.
2225 @retval Others The operation fails.
2230 IN SD_PEIM_HC_SLOT
*Slot
,
2232 OUT UINT32
*DevStatus
2235 SD_COMMAND_BLOCK SdCmdBlk
;
2236 SD_STATUS_BLOCK SdStatusBlk
;
2237 SD_COMMAND_PACKET Packet
;
2240 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
2241 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
2242 ZeroMem (&Packet
, sizeof (Packet
));
2244 Packet
.SdCmdBlk
= &SdCmdBlk
;
2245 Packet
.SdStatusBlk
= &SdStatusBlk
;
2246 Packet
.Timeout
= SD_TIMEOUT
;
2248 SdCmdBlk
.CommandIndex
= SD_SEND_STATUS
;
2249 SdCmdBlk
.CommandType
= SdCommandTypeAc
;
2250 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2251 SdCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
2253 Status
= SdPeimExecCmd (Slot
, &Packet
);
2254 if (!EFI_ERROR (Status
)) {
2255 *DevStatus
= SdStatusBlk
.Resp0
;
2262 Send command READ_SINGLE_BLOCK/WRITE_SINGLE_BLOCK to the addressed SD device
2263 to read/write the specified number of blocks.
2265 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
2267 @param[in] Slot The slot number of the SD card to send the command to.
2268 @param[in] Lba The logical block address of starting access.
2269 @param[in] BlockSize The block size of specified SD device partition.
2270 @param[in] Buffer The pointer to the transfer buffer.
2271 @param[in] BufferSize The size of transfer buffer.
2272 @param[in] IsRead Boolean to show the operation direction.
2274 @retval EFI_SUCCESS The operation is done correctly.
2275 @retval Others The operation fails.
2279 SdPeimRwSingleBlock (
2280 IN SD_PEIM_HC_SLOT
*Slot
,
2282 IN UINT32 BlockSize
,
2284 IN UINTN BufferSize
,
2288 SD_COMMAND_BLOCK SdCmdBlk
;
2289 SD_STATUS_BLOCK SdStatusBlk
;
2290 SD_COMMAND_PACKET Packet
;
2293 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
2294 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
2295 ZeroMem (&Packet
, sizeof (Packet
));
2297 Packet
.SdCmdBlk
= &SdCmdBlk
;
2298 Packet
.SdStatusBlk
= &SdStatusBlk
;
2300 // Calculate timeout value through the below formula.
2301 // Timeout = (transfer size) / (2MB/s).
2302 // Taking 2MB/s as divisor is because it's the lowest
2303 // transfer speed of class 2.
2305 Packet
.Timeout
= (BufferSize
/ (2 * 1024 * 1024) + 1) * 1000 * 1000;;
2308 Packet
.InDataBuffer
= Buffer
;
2309 Packet
.InTransferLength
= (UINT32
)BufferSize
;
2311 SdCmdBlk
.CommandIndex
= SD_READ_SINGLE_BLOCK
;
2312 SdCmdBlk
.CommandType
= SdCommandTypeAdtc
;
2313 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2315 Packet
.OutDataBuffer
= Buffer
;
2316 Packet
.OutTransferLength
= (UINT32
)BufferSize
;
2318 SdCmdBlk
.CommandIndex
= SD_WRITE_SINGLE_BLOCK
;
2319 SdCmdBlk
.CommandType
= SdCommandTypeAdtc
;
2320 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2323 if (Slot
->SectorAddressing
) {
2324 SdCmdBlk
.CommandArgument
= (UINT32
)Lba
;
2326 SdCmdBlk
.CommandArgument
= (UINT32
)MultU64x32 (Lba
, BlockSize
);
2329 Status
= SdPeimExecCmd (Slot
, &Packet
);
2335 Send command READ_MULTIPLE_BLOCK/WRITE_MULTIPLE_BLOCK to the addressed SD device
2336 to read/write the specified number of blocks.
2338 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
2340 @param[in] Slot The slot number of the SD card to send the command to.
2341 @param[in] Lba The logical block address of starting access.
2342 @param[in] BlockSize The block size of specified SD device partition.
2343 @param[in] Buffer The pointer to the transfer buffer.
2344 @param[in] BufferSize The size of transfer buffer.
2345 @param[in] IsRead Boolean to show the operation direction.
2347 @retval EFI_SUCCESS The operation is done correctly.
2348 @retval Others The operation fails.
2352 SdPeimRwMultiBlocks (
2353 IN SD_PEIM_HC_SLOT
*Slot
,
2355 IN UINT32 BlockSize
,
2357 IN UINTN BufferSize
,
2361 SD_COMMAND_BLOCK SdCmdBlk
;
2362 SD_STATUS_BLOCK SdStatusBlk
;
2363 SD_COMMAND_PACKET Packet
;
2366 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
2367 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
2368 ZeroMem (&Packet
, sizeof (Packet
));
2370 Packet
.SdCmdBlk
= &SdCmdBlk
;
2371 Packet
.SdStatusBlk
= &SdStatusBlk
;
2373 // Calculate timeout value through the below formula.
2374 // Timeout = (transfer size) / (2MB/s).
2375 // Taking 2MB/s as divisor is because it's the lowest
2376 // transfer speed of class 2.
2378 Packet
.Timeout
= (BufferSize
/ (2 * 1024 * 1024) + 1) * 1000 * 1000;;
2381 Packet
.InDataBuffer
= Buffer
;
2382 Packet
.InTransferLength
= (UINT32
)BufferSize
;
2384 SdCmdBlk
.CommandIndex
= SD_READ_MULTIPLE_BLOCK
;
2385 SdCmdBlk
.CommandType
= SdCommandTypeAdtc
;
2386 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2388 Packet
.OutDataBuffer
= Buffer
;
2389 Packet
.OutTransferLength
= (UINT32
)BufferSize
;
2391 SdCmdBlk
.CommandIndex
= SD_WRITE_MULTIPLE_BLOCK
;
2392 SdCmdBlk
.CommandType
= SdCommandTypeAdtc
;
2393 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2396 if (Slot
->SectorAddressing
) {
2397 SdCmdBlk
.CommandArgument
= (UINT32
)Lba
;
2399 SdCmdBlk
.CommandArgument
= (UINT32
)MultU64x32 (Lba
, BlockSize
);
2402 Status
= SdPeimExecCmd (Slot
, &Packet
);
2408 Send command SEND_TUNING_BLOCK to the SD device for SDR104/SDR50 optimal sampling point
2411 It may be sent up to 40 times until the host finishes the tuning procedure.
2413 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
2415 @param[in] Slot The slot number of the SD card to send the command to.
2417 @retval EFI_SUCCESS The operation is done correctly.
2418 @retval Others The operation fails.
2422 SdPeimSendTuningBlk (
2423 IN SD_PEIM_HC_SLOT
*Slot
2426 SD_COMMAND_BLOCK SdCmdBlk
;
2427 SD_STATUS_BLOCK SdStatusBlk
;
2428 SD_COMMAND_PACKET Packet
;
2430 UINT8 TuningBlock
[64];
2432 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
2433 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
2434 ZeroMem (&Packet
, sizeof (Packet
));
2436 Packet
.SdCmdBlk
= &SdCmdBlk
;
2437 Packet
.SdStatusBlk
= &SdStatusBlk
;
2438 Packet
.Timeout
= SD_TIMEOUT
;
2440 SdCmdBlk
.CommandIndex
= SD_SEND_TUNING_BLOCK
;
2441 SdCmdBlk
.CommandType
= SdCommandTypeAdtc
;
2442 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2443 SdCmdBlk
.CommandArgument
= 0;
2445 Packet
.InDataBuffer
= TuningBlock
;
2446 Packet
.InTransferLength
= sizeof (TuningBlock
);
2448 Status
= SdPeimExecCmd (Slot
, &Packet
);
2454 Tunning the sampling point of SDR104 or SDR50 bus speed mode.
2456 Command SD_SEND_TUNING_BLOCK may be sent up to 40 times until the host finishes the
2459 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and SD Host Controller
2460 Simplified Spec 3.0 Figure 2-29 for details.
2462 @param[in] Slot The slot number of the SD card to send the command to.
2464 @retval EFI_SUCCESS The operation is done correctly.
2465 @retval Others The operation fails.
2470 IN SD_PEIM_HC_SLOT
*Slot
2478 // Notify the host that the sampling clock tuning procedure starts.
2481 Status
= SdPeimHcOrMmio (Slot
->SdHcBase
+ SD_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2482 if (EFI_ERROR (Status
)) {
2486 // Ask the device to send a sequence of tuning blocks till the tuning procedure is done.
2490 Status
= SdPeimSendTuningBlk (Slot
);
2491 if (EFI_ERROR (Status
)) {
2495 Status
= SdPeimHcRwMmio (Slot
->SdHcBase
+ SD_HC_HOST_CTRL2
, TRUE
, sizeof (HostCtrl2
), &HostCtrl2
);
2496 if (EFI_ERROR (Status
)) {
2500 if ((HostCtrl2
& (BIT6
| BIT7
)) == BIT7
) {
2503 } while (++Retry
< 40);
2506 Status
= EFI_TIMEOUT
;
2512 Switch the bus width to specified width.
2514 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and
2515 SD Host Controller Simplified Spec 3.0 section Figure 3-7 for details.
2517 @param[in] Slot The slot number of the SD card to send the command to.
2518 @param[in] Rca The relative device address to be assigned.
2519 @param[in] BusWidth The bus width to be set, it could be 4 or 8.
2521 @retval EFI_SUCCESS The operation is done correctly.
2522 @retval Others The operation fails.
2526 SdPeimSwitchBusWidth (
2527 IN SD_PEIM_HC_SLOT
*Slot
,
2535 Status
= SdPeimSetBusWidth (Slot
, Rca
, BusWidth
);
2536 if (EFI_ERROR (Status
)) {
2540 Status
= SdPeimSendStatus (Slot
, Rca
, &DevStatus
);
2541 if (EFI_ERROR (Status
)) {
2545 // Check the switch operation is really successful or not.
2547 if ((DevStatus
>> 16) != 0) {
2548 return EFI_DEVICE_ERROR
;
2551 Status
= SdPeimHcSetBusWidth (Slot
->SdHcBase
, BusWidth
);
2557 Switch the high speed timing according to request.
2559 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and
2560 SD Host Controller Simplified Spec 3.0 section Figure 2-29 for details.
2562 @param[in] Slot The slot number of the SD card to send the command to.
2563 @param[in] Rca The relative device address to be assigned.
2564 @param[in] S18a The boolean to show if it's a UHS-I SD card.
2566 @retval EFI_SUCCESS The operation is done correctly.
2567 @retval Others The operation fails.
2572 IN SD_PEIM_HC_SLOT
*Slot
,
2578 SD_HC_SLOT_CAP Capability
;
2585 Status
= SdPeimGetCsd (Slot
, Rca
, &Slot
->Csd
);
2586 if (EFI_ERROR (Status
)) {
2587 DEBUG ((EFI_D_ERROR
, "SdPeimSetBusMode: SdPeimGetCsd fails with %r\n", Status
));
2591 Status
= SdPeimHcGetCapability (Slot
->SdHcBase
, &Capability
);
2592 if (EFI_ERROR (Status
)) {
2596 Status
= SdPeimSelect (Slot
, Rca
);
2597 if (EFI_ERROR (Status
)) {
2598 DEBUG ((EFI_D_ERROR
, "SdPeimSetBusMode: SdPeimSelect fails with %r\n", Status
));
2603 Status
= SdPeimSwitchBusWidth (Slot
, Rca
, BusWidth
);
2604 if (EFI_ERROR (Status
)) {
2605 DEBUG ((EFI_D_ERROR
, "SdPeimSetBusMode: SdPeimSwitchBusWidth fails with %r\n", Status
));
2610 // Calculate supported bus speed/bus width/clock frequency.
2613 if (S18a
&& (Capability
.Sdr104
!= 0)) {
2616 } else if (S18a
&& (Capability
.Sdr50
!= 0)) {
2619 } else if (S18a
&& (Capability
.Ddr50
!= 0)) {
2627 DEBUG ((EFI_D_INFO
, "AccessMode %d ClockFreq %d BusWidth %d\n", AccessMode
, ClockFreq
, BusWidth
));
2629 Status
= SdPeimSwitch (Slot
, AccessMode
, 0, 0, 0, TRUE
);
2630 if (EFI_ERROR (Status
)) {
2631 DEBUG ((EFI_D_ERROR
, "SdPeimSetBusMode: SdPeimSwitch fails with %r\n", Status
));
2636 // Set to Hight Speed timing
2638 if (AccessMode
== 1) {
2640 Status
= SdPeimHcOrMmio (Slot
->SdHcBase
+ SD_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
2641 if (EFI_ERROR (Status
)) {
2646 HostCtrl2
= (UINT8
)~0x7;
2647 Status
= SdPeimHcAndMmio (Slot
->SdHcBase
+ SD_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2648 if (EFI_ERROR (Status
)) {
2651 HostCtrl2
= AccessMode
;
2652 Status
= SdPeimHcOrMmio (Slot
->SdHcBase
+ SD_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2653 if (EFI_ERROR (Status
)) {
2657 Status
= SdPeimHcClockSupply (Slot
->SdHcBase
, ClockFreq
* 1000);
2658 if (EFI_ERROR (Status
)) {
2659 DEBUG ((EFI_D_ERROR
, "SdPeimSetBusMode: SdPeimHcClockSupply %r\n", Status
));
2663 if ((AccessMode
== 3) || ((AccessMode
== 2) && (Capability
.TuningSDR50
!= 0))) {
2664 Status
= SdPeimTuningClock (Slot
);
2665 if (EFI_ERROR (Status
)) {
2666 DEBUG ((EFI_D_ERROR
, "SdPeimSetBusMode: SdPeimTuningClock fails with %r\n", Status
));
2671 DEBUG ((EFI_D_INFO
, "SdPeimSetBusMode: SdPeimSetBusMode %r\n", Status
));
2677 Execute SD device identification procedure.
2679 Refer to SD Physical Layer Simplified Spec 4.1 Section 3.6 for details.
2681 @param[in] Slot The slot number of the SD card to send the command to.
2683 @retval EFI_SUCCESS There is a SD card.
2684 @retval Others There is not a SD card.
2688 SdPeimIdentification (
2689 IN SD_PEIM_HC_SLOT
*Slot
2699 UINT16 ControllerVer
;
2701 UINT32 PresentState
;
2703 SD_HC_SLOT_CAP Capability
;
2706 // 1. Send Cmd0 to the device
2708 Status
= SdPeimReset (Slot
);
2709 if (EFI_ERROR (Status
)) {
2710 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: Executing Cmd0 fails with %r\n", Status
));
2714 // 2. Send Cmd8 to the device
2716 Status
= SdPeimVoltageCheck (Slot
, 0x1, 0xFF);
2717 if (EFI_ERROR (Status
)) {
2718 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: Executing Cmd8 fails with %r\n", Status
));
2722 // 3. Send SDIO Cmd5 to the device to the SDIO device OCR register.
2724 Status
= SdioSendOpCond (Slot
, 0, FALSE
);
2725 if (!EFI_ERROR (Status
)) {
2726 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: Found SDIO device, ignore it as we don't support\n"));
2727 return EFI_DEVICE_ERROR
;
2730 // 4. Send Acmd41 with voltage window 0 to the device
2732 Status
= SdPeimSendOpCond (Slot
, 0, 0, FALSE
, FALSE
, FALSE
, &Ocr
);
2733 if (EFI_ERROR (Status
)) {
2734 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: Executing SdPeimSendOpCond fails with %r\n", Status
));
2735 return EFI_DEVICE_ERROR
;
2738 Status
= SdPeimHcGetCapability (Slot
->SdHcBase
, &Capability
);
2739 if (EFI_ERROR (Status
)) {
2743 Status
= SdPeimHcRwMmio (Slot
->SdHcBase
+ SD_HC_MAX_CURRENT_CAP
, TRUE
, sizeof (Current
), &Current
);
2744 if (EFI_ERROR (Status
)) {
2748 if (Capability
.Voltage33
!= 0) {
2752 MaxCurrent
= ((UINT32
)Current
& 0xFF) * 4;
2753 } else if (Capability
.Voltage30
!= 0) {
2757 MaxCurrent
= (((UINT32
)Current
>> 8) & 0xFF) * 4;
2758 } else if (Capability
.Voltage18
!= 0) {
2762 MaxCurrent
= (((UINT32
)Current
>> 16) & 0xFF) * 4;
2765 return EFI_DEVICE_ERROR
;
2768 if (MaxCurrent
>= 150) {
2774 Status
= SdPeimHcRwMmio (Slot
->SdHcBase
+ SD_HC_CTRL_VER
, TRUE
, sizeof (ControllerVer
), &ControllerVer
);
2775 if (EFI_ERROR (Status
)) {
2779 if ((ControllerVer
& 0xFF) == 2) {
2781 } else if (((ControllerVer
& 0xFF) == 0) || ((ControllerVer
& 0xFF) == 1)) {
2785 return EFI_UNSUPPORTED
;
2788 // 5. Repeatly send Acmd41 with supply voltage window to the device.
2789 // Note here we only support the cards complied with SD physical
2790 // layer simplified spec version 2.0 and version 3.0 and above.
2793 Status
= SdPeimSendOpCond (Slot
, 0, Ocr
, S18r
, Xpc
, TRUE
, &Ocr
);
2794 if (EFI_ERROR (Status
)) {
2795 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: SdPeimSendOpCond fails with %r Ocr %x, S18r %x, Xpc %x\n", Status
, Ocr
, S18r
, Xpc
));
2796 return EFI_DEVICE_ERROR
;
2798 } while ((Ocr
& BIT31
) == 0);
2801 // 6. If the S18a bit is set and the Host Controller supports 1.8V signaling
2802 // (One of support bits is set to 1: SDR50, SDR104 or DDR50 in the
2803 // Capabilities register), switch its voltage to 1.8V.
2805 if ((Capability
.Sdr50
!= 0 ||
2806 Capability
.Sdr104
!= 0 ||
2807 Capability
.Ddr50
!= 0) &&
2808 ((Ocr
& BIT24
) != 0)) {
2809 Status
= SdPeimVoltageSwitch (Slot
);
2810 if (EFI_ERROR (Status
)) {
2811 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: Executing SdPeimVoltageSwitch fails with %r\n", Status
));
2812 Status
= EFI_DEVICE_ERROR
;
2815 Status
= SdPeimHcStopClock (Slot
->SdHcBase
);
2816 if (EFI_ERROR (Status
)) {
2817 Status
= EFI_DEVICE_ERROR
;
2821 SdPeimHcRwMmio (Slot
->SdHcBase
+ SD_HC_PRESENT_STATE
, TRUE
, sizeof (PresentState
), &PresentState
);
2822 if (((PresentState
>> 20) & 0xF) != 0) {
2823 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: SwitchVoltage fails with PresentState = 0x%x\n", PresentState
));
2824 Status
= EFI_DEVICE_ERROR
;
2828 SdPeimHcOrMmio (Slot
->SdHcBase
+ SD_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2830 MicroSecondDelay (5000);
2832 SdPeimHcRwMmio (Slot
->SdHcBase
+ SD_HC_HOST_CTRL2
, TRUE
, sizeof (HostCtrl2
), &HostCtrl2
);
2833 if ((HostCtrl2
& BIT3
) == 0) {
2834 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: SwitchVoltage fails with HostCtrl2 = 0x%x\n", HostCtrl2
));
2835 Status
= EFI_DEVICE_ERROR
;
2839 SdPeimHcInitClockFreq (Slot
->SdHcBase
);
2841 MicroSecondDelay (1000);
2843 SdPeimHcRwMmio (Slot
->SdHcBase
+ SD_HC_PRESENT_STATE
, TRUE
, sizeof (PresentState
), &PresentState
);
2844 if (((PresentState
>> 20) & 0xF) != 0xF) {
2845 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: SwitchVoltage fails with PresentState = 0x%x, It should be 0xF\n", PresentState
));
2846 Status
= EFI_DEVICE_ERROR
;
2850 DEBUG ((EFI_D_INFO
, "SdPeimIdentification: Switch to 1.8v signal voltage success\n"));
2853 Status
= SdPeimAllSendCid (Slot
);
2854 if (EFI_ERROR (Status
)) {
2855 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: Executing SdPeimAllSendCid fails with %r\n", Status
));
2859 Status
= SdPeimSetRca (Slot
, &Rca
);
2860 if (EFI_ERROR (Status
)) {
2861 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: Executing SdPeimSetRca fails with %r\n", Status
));
2865 // Enter Data Tranfer Mode.
2867 DEBUG ((EFI_D_INFO
, "Found a SD device at slot [%d]\n", Slot
));
2869 Status
= SdPeimSetBusMode (Slot
, Rca
, ((Ocr
& BIT24
) != 0));
2875 // Set SD Bus Power = 0
2877 PowerCtrl
= (UINT8
)~BIT0
;
2878 Status
= SdPeimHcAndMmio (Slot
->SdHcBase
+ SD_HC_POWER_CTRL
, sizeof (PowerCtrl
), &PowerCtrl
);
2879 return EFI_DEVICE_ERROR
;