3 Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>
4 SPDX-License-Identifier: BSD-2-Clause-Patent
8 #include "SdBlockIoPei.h"
11 Read/Write specified SD host controller mmio register.
13 @param[in] Address The address of the mmio register to be read/written.
14 @param[in] Read A boolean to indicate it's read or write operation.
15 @param[in] Count The width of the mmio register in bytes.
16 Must be 1, 2 , 4 or 8 bytes.
17 @param[in, out] Data For read operations, the destination buffer to store
18 the results. For write operations, the source buffer
19 to write data from. The caller is responsible for
20 having ownership of the data buffer and ensuring its
21 size not less than Count bytes.
23 @retval EFI_INVALID_PARAMETER The Address or the Data or the Count is not valid.
24 @retval EFI_SUCCESS The read/write operation succeeds.
25 @retval Others The read/write operation fails.
37 if ((Address
== 0) || (Data
== NULL
)) {
38 return EFI_INVALID_PARAMETER
;
41 if ((Count
!= 1) && (Count
!= 2) && (Count
!= 4) && (Count
!= 8)) {
42 return EFI_INVALID_PARAMETER
;
48 *(UINT8
*)Data
= MmioRead8 (Address
);
50 MmioWrite8 (Address
, *(UINT8
*)Data
);
55 *(UINT16
*)Data
= MmioRead16 (Address
);
57 MmioWrite16 (Address
, *(UINT16
*)Data
);
62 *(UINT32
*)Data
= MmioRead32 (Address
);
64 MmioWrite32 (Address
, *(UINT32
*)Data
);
69 *(UINT64
*)Data
= MmioRead64 (Address
);
71 MmioWrite64 (Address
, *(UINT64
*)Data
);
76 return EFI_INVALID_PARAMETER
;
83 Do OR operation with the value of the specified SD host controller mmio register.
85 @param[in] Address The address of the mmio register to be read/written.
86 @param[in] Count The width of the mmio register in bytes.
87 Must be 1, 2 , 4 or 8 bytes.
88 @param[in] OrData The pointer to the data used to do OR operation.
89 The caller is responsible for having ownership of
90 the data buffer and ensuring its size not less than
93 @retval EFI_INVALID_PARAMETER The Address or the OrData or the Count is not valid.
94 @retval EFI_SUCCESS The OR operation succeeds.
95 @retval Others The OR operation fails.
110 Status
= SdPeimHcRwMmio (Address
, TRUE
, Count
, &Data
);
111 if (EFI_ERROR (Status
)) {
116 Or
= *(UINT8
*) OrData
;
117 } else if (Count
== 2) {
118 Or
= *(UINT16
*) OrData
;
119 } else if (Count
== 4) {
120 Or
= *(UINT32
*) OrData
;
121 } else if (Count
== 8) {
122 Or
= *(UINT64
*) OrData
;
124 return EFI_INVALID_PARAMETER
;
128 Status
= SdPeimHcRwMmio (Address
, FALSE
, Count
, &Data
);
134 Do AND operation with the value of the specified SD host controller mmio register.
136 @param[in] Address The address of the mmio register to be read/written.
137 @param[in] Count The width of the mmio register in bytes.
138 Must be 1, 2 , 4 or 8 bytes.
139 @param[in] AndData The pointer to the data used to do AND operation.
140 The caller is responsible for having ownership of
141 the data buffer and ensuring its size not less than
144 @retval EFI_INVALID_PARAMETER The Address or the AndData or the Count is not valid.
145 @retval EFI_SUCCESS The AND operation succeeds.
146 @retval Others The AND operation fails.
161 Status
= SdPeimHcRwMmio (Address
, TRUE
, Count
, &Data
);
162 if (EFI_ERROR (Status
)) {
167 And
= *(UINT8
*) AndData
;
168 } else if (Count
== 2) {
169 And
= *(UINT16
*) AndData
;
170 } else if (Count
== 4) {
171 And
= *(UINT32
*) AndData
;
172 } else if (Count
== 8) {
173 And
= *(UINT64
*) AndData
;
175 return EFI_INVALID_PARAMETER
;
179 Status
= SdPeimHcRwMmio (Address
, FALSE
, Count
, &Data
);
185 Wait for the value of the specified MMIO register set to the test value.
187 @param[in] Address The address of the mmio register to be checked.
188 @param[in] Count The width of the mmio register in bytes.
189 Must be 1, 2, 4 or 8 bytes.
190 @param[in] MaskValue The mask value of memory.
191 @param[in] TestValue The test value of memory.
193 @retval EFI_NOT_READY The MMIO register hasn't set to the expected value.
194 @retval EFI_SUCCESS The MMIO register has expected value.
195 @retval Others The MMIO operation fails.
200 SdPeimHcCheckMmioSet (
211 // Access PCI MMIO space to see if the value is the tested one.
214 Status
= SdPeimHcRwMmio (Address
, TRUE
, Count
, &Value
);
215 if (EFI_ERROR (Status
)) {
221 if (Value
== TestValue
) {
225 return EFI_NOT_READY
;
229 Wait for the value of the specified MMIO register set to the test value.
231 @param[in] Address The address of the mmio register to wait.
232 @param[in] Count The width of the mmio register in bytes.
233 Must be 1, 2, 4 or 8 bytes.
234 @param[in] MaskValue The mask value of memory.
235 @param[in] TestValue The test value of memory.
236 @param[in] Timeout The time out value for wait memory set, uses 1
237 microsecond as a unit.
239 @retval EFI_TIMEOUT The MMIO register hasn't expected value in timeout
241 @retval EFI_SUCCESS The MMIO register has expected value.
242 @retval Others The MMIO operation fails.
247 SdPeimHcWaitMmioSet (
256 BOOLEAN InfiniteWait
;
261 InfiniteWait
= FALSE
;
264 while (InfiniteWait
|| (Timeout
> 0)) {
265 Status
= SdPeimHcCheckMmioSet (
271 if (Status
!= EFI_NOT_READY
) {
276 // Stall for 1 microsecond.
278 MicroSecondDelay (1);
287 Software reset the specified SD host controller and enable all interrupts.
289 @param[in] Bar The mmio base address of the slot to be accessed.
291 @retval EFI_SUCCESS The software reset executes successfully.
292 @retval Others The software reset fails.
304 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_SW_RST
, FALSE
, sizeof (SwReset
), &SwReset
);
306 if (EFI_ERROR (Status
)) {
307 DEBUG ((EFI_D_ERROR
, "SdPeimHcReset: write full 1 fails: %r\n", Status
));
311 Status
= SdPeimHcWaitMmioSet (
318 if (EFI_ERROR (Status
)) {
319 DEBUG ((EFI_D_INFO
, "SdPeimHcReset: reset done with %r\n", Status
));
323 // Enable all interrupt after reset all.
325 Status
= SdPeimHcEnableInterrupt (Bar
);
331 Set all interrupt status bits in Normal and Error Interrupt Status Enable
334 @param[in] Bar The mmio base address of the slot to be accessed.
336 @retval EFI_SUCCESS The operation executes successfully.
337 @retval Others The operation fails.
341 SdPeimHcEnableInterrupt (
349 // Enable all bits in Error Interrupt Status Enable Register
352 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_ERR_INT_STS_EN
, FALSE
, sizeof (IntStatus
), &IntStatus
);
353 if (EFI_ERROR (Status
)) {
357 // Enable all bits in Normal Interrupt Status Enable Register
360 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_NOR_INT_STS_EN
, FALSE
, sizeof (IntStatus
), &IntStatus
);
366 Get the capability data from the specified slot.
368 @param[in] Bar The mmio base address of the slot to be accessed.
369 @param[out] Capability The buffer to store the capability data.
371 @retval EFI_SUCCESS The operation executes successfully.
372 @retval Others The operation fails.
376 SdPeimHcGetCapability (
378 OUT SD_HC_SLOT_CAP
*Capability
384 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_CAP
, TRUE
, sizeof (Cap
), &Cap
);
385 if (EFI_ERROR (Status
)) {
389 CopyMem (Capability
, &Cap
, sizeof (Cap
));
395 Detect whether there is a SD card attached at the specified SD host controller
398 Refer to SD Host Controller Simplified spec 3.0 Section 3.1 for details.
400 @param[in] Bar The mmio base address of the slot to be accessed.
402 @retval EFI_SUCCESS There is a SD card attached.
403 @retval EFI_NO_MEDIA There is not a SD card attached.
404 @retval Others The detection fails.
417 // Check Normal Interrupt Status Register
419 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_NOR_INT_STS
, TRUE
, sizeof (Data
), &Data
);
420 if (EFI_ERROR (Status
)) {
424 if ((Data
& (BIT6
| BIT7
)) != 0) {
426 // Clear BIT6 and BIT7 by writing 1 to these two bits if set.
429 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_NOR_INT_STS
, FALSE
, sizeof (Data
), &Data
);
430 if (EFI_ERROR (Status
)) {
436 // Check Present State Register to see if there is a card presented.
438 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_PRESENT_STATE
, TRUE
, sizeof (PresentState
), &PresentState
);
439 if (EFI_ERROR (Status
)) {
443 if ((PresentState
& BIT16
) != 0) {
453 Refer to SD Host Controller Simplified spec 3.0 Section 3.2.2 for details.
455 @param[in] Bar The mmio base address of the slot to be accessed.
457 @retval EFI_SUCCESS Succeed to stop SD clock.
458 @retval Others Fail to stop SD clock.
471 // Ensure no SD transactions are occurring on the SD Bus by
472 // waiting for Command Inhibit (DAT) and Command Inhibit (CMD)
473 // in the Present State register to be 0.
475 Status
= SdPeimHcWaitMmioSet (
476 Bar
+ SD_HC_PRESENT_STATE
,
477 sizeof (PresentState
),
482 if (EFI_ERROR (Status
)) {
487 // Set SD Clock Enable in the Clock Control register to 0
489 ClockCtrl
= (UINT16
)~BIT2
;
490 Status
= SdPeimHcAndMmio (Bar
+ SD_HC_CLOCK_CTRL
, sizeof (ClockCtrl
), &ClockCtrl
);
496 SD card clock supply.
498 Refer to SD Host Controller Simplified spec 3.0 Section 3.2.1 for details.
500 @param[in] Bar The mmio base address of the slot to be accessed.
501 @param[in] ClockFreq The max clock frequency to be set. The unit is KHz.
503 @retval EFI_SUCCESS The clock is supplied successfully.
504 @retval Others The clock isn't supplied successfully.
508 SdPeimHcClockSupply (
514 SD_HC_SLOT_CAP Capability
;
519 UINT16 ControllerVer
;
523 // Calculate a divisor for SD clock frequency
525 Status
= SdPeimHcGetCapability (Bar
, &Capability
);
526 if (EFI_ERROR (Status
)) {
529 ASSERT (Capability
.BaseClkFreq
!= 0);
531 BaseClkFreq
= Capability
.BaseClkFreq
;
533 if (ClockFreq
== 0) {
534 return EFI_INVALID_PARAMETER
;
537 if (ClockFreq
> (BaseClkFreq
* 1000)) {
538 ClockFreq
= BaseClkFreq
* 1000;
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
;
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
;
995 EDKII_IOMMU_OPERATION MapOp
;
999 // Calculate a divisor for SD clock frequency
1001 Status
= SdPeimHcGetCapability (Slot
->SdHcBase
, &Capability
);
1002 if (EFI_ERROR (Status
)) {
1006 Trb
= AllocateZeroPool (sizeof (SD_TRB
));
1012 Trb
->BlockSize
= 0x200;
1013 Trb
->Packet
= Packet
;
1014 Trb
->Timeout
= Packet
->Timeout
;
1016 if ((Packet
->InTransferLength
!= 0) && (Packet
->InDataBuffer
!= NULL
)) {
1017 Trb
->Data
= Packet
->InDataBuffer
;
1018 Trb
->DataLen
= Packet
->InTransferLength
;
1020 } else if ((Packet
->OutTransferLength
!= 0) && (Packet
->OutDataBuffer
!= NULL
)) {
1021 Trb
->Data
= Packet
->OutDataBuffer
;
1022 Trb
->DataLen
= Packet
->OutTransferLength
;
1024 } else if ((Packet
->InTransferLength
== 0) && (Packet
->OutTransferLength
== 0)) {
1031 if ((Trb
->DataLen
!= 0) && (Trb
->DataLen
< Trb
->BlockSize
)) {
1032 Trb
->BlockSize
= (UINT16
)Trb
->DataLen
;
1035 if (Packet
->SdCmdBlk
->CommandIndex
== SD_SEND_TUNING_BLOCK
) {
1036 Trb
->Mode
= SdPioMode
;
1039 MapOp
= EdkiiIoMmuOperationBusMasterWrite
;
1041 MapOp
= EdkiiIoMmuOperationBusMasterRead
;
1044 if (Trb
->DataLen
!= 0) {
1045 MapLength
= Trb
->DataLen
;
1046 Status
= IoMmuMap (MapOp
, Trb
->Data
, &MapLength
, &Trb
->DataPhy
, &Trb
->DataMap
);
1048 if (EFI_ERROR (Status
) || (MapLength
!= Trb
->DataLen
)) {
1049 DEBUG ((DEBUG_ERROR
, "SdPeimCreateTrb: Fail to map data buffer.\n"));
1054 if (Trb
->DataLen
== 0) {
1055 Trb
->Mode
= SdNoData
;
1056 } else if (Capability
.Adma2
!= 0) {
1057 Trb
->Mode
= SdAdmaMode
;
1058 Status
= BuildAdmaDescTable (Trb
);
1059 if (EFI_ERROR (Status
)) {
1062 } else if (Capability
.Sdma
!= 0) {
1063 Trb
->Mode
= SdSdmaMode
;
1065 Trb
->Mode
= SdPioMode
;
1071 SdPeimFreeTrb (Trb
);
1076 Free the resource used by the TRB.
1078 @param[in] Trb The pointer to the SD_TRB instance.
1086 if ((Trb
!= NULL
) && (Trb
->DataMap
!= NULL
)) {
1087 IoMmuUnmap (Trb
->DataMap
);
1090 if ((Trb
!= NULL
) && (Trb
->AdmaDesc
!= NULL
)) {
1091 SdPeimFreeMem (Trb
->Slot
->Private
->Pool
, Trb
->AdmaDesc
, Trb
->AdmaDescSize
);
1101 Check if the env is ready for execute specified TRB.
1103 @param[in] Bar The mmio base address of the slot to be accessed.
1104 @param[in] Trb The pointer to the SD_TRB instance.
1106 @retval EFI_SUCCESS The env is ready for TRB execution.
1107 @retval EFI_NOT_READY The env is not ready for TRB execution.
1108 @retval Others Some erros happen.
1118 SD_COMMAND_PACKET
*Packet
;
1119 UINT32 PresentState
;
1121 Packet
= Trb
->Packet
;
1123 if ((Packet
->SdCmdBlk
->CommandType
== SdCommandTypeAdtc
) ||
1124 (Packet
->SdCmdBlk
->ResponseType
== SdResponseTypeR1b
) ||
1125 (Packet
->SdCmdBlk
->ResponseType
== SdResponseTypeR5b
)) {
1127 // Wait Command Inhibit (CMD) and Command Inhibit (DAT) in
1128 // the Present State register to be 0
1130 PresentState
= BIT0
| BIT1
;
1133 // Wait Command Inhibit (CMD) in the Present State register
1136 PresentState
= BIT0
;
1139 Status
= SdPeimHcCheckMmioSet (
1140 Bar
+ SD_HC_PRESENT_STATE
,
1141 sizeof (PresentState
),
1150 Wait for the env to be ready for execute specified TRB.
1152 @param[in] Bar The mmio base address of the slot to be accessed.
1153 @param[in] Trb The pointer to the SD_TRB instance.
1155 @retval EFI_SUCCESS The env is ready for TRB execution.
1156 @retval EFI_TIMEOUT The env is not ready for TRB execution in time.
1157 @retval Others Some erros happen.
1167 SD_COMMAND_PACKET
*Packet
;
1169 BOOLEAN InfiniteWait
;
1172 // Wait Command Complete Interrupt Status bit in Normal Interrupt Status Register
1174 Packet
= Trb
->Packet
;
1175 Timeout
= Packet
->Timeout
;
1177 InfiniteWait
= TRUE
;
1179 InfiniteWait
= FALSE
;
1182 while (InfiniteWait
|| (Timeout
> 0)) {
1184 // Check Trb execution result by reading Normal Interrupt Status register.
1186 Status
= SdPeimCheckTrbEnv (Bar
, Trb
);
1187 if (Status
!= EFI_NOT_READY
) {
1191 // Stall for 1 microsecond.
1193 MicroSecondDelay (1);
1202 Execute the specified TRB.
1204 @param[in] Bar The mmio base address of the slot to be accessed.
1205 @param[in] Trb The pointer to the SD_TRB instance.
1207 @retval EFI_SUCCESS The TRB is sent to host controller successfully.
1208 @retval Others Some erros happen when sending this request to the host controller.
1218 SD_COMMAND_PACKET
*Packet
;
1229 Packet
= Trb
->Packet
;
1231 // Clear all bits in Error Interrupt Status Register
1234 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_ERR_INT_STS
, FALSE
, sizeof (IntStatus
), &IntStatus
);
1235 if (EFI_ERROR (Status
)) {
1239 // Clear all bits in Normal Interrupt Status Register
1242 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_NOR_INT_STS
, FALSE
, sizeof (IntStatus
), &IntStatus
);
1243 if (EFI_ERROR (Status
)) {
1247 // Set Host Control 1 register DMA Select field
1249 if (Trb
->Mode
== SdAdmaMode
) {
1251 Status
= SdPeimHcOrMmio (Bar
+ SD_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
1252 if (EFI_ERROR (Status
)) {
1257 SdPeimHcLedOnOff (Bar
, TRUE
);
1259 if (Trb
->Mode
== SdSdmaMode
) {
1260 if ((UINT64
)(UINTN
)Trb
->DataPhy
>= 0x100000000ul
) {
1261 return EFI_INVALID_PARAMETER
;
1264 SdmaAddr
= (UINT32
)(UINTN
)Trb
->DataPhy
;
1265 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_SDMA_ADDR
, FALSE
, sizeof (SdmaAddr
), &SdmaAddr
);
1266 if (EFI_ERROR (Status
)) {
1269 } else if (Trb
->Mode
== SdAdmaMode
) {
1270 AdmaAddr
= (UINT64
)(UINTN
)Trb
->AdmaDesc
;
1271 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_ADMA_SYS_ADDR
, FALSE
, sizeof (AdmaAddr
), &AdmaAddr
);
1272 if (EFI_ERROR (Status
)) {
1277 BlkSize
= Trb
->BlockSize
;
1278 if (Trb
->Mode
== SdSdmaMode
) {
1280 // Set SDMA boundary to be 512K bytes.
1285 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_BLK_SIZE
, FALSE
, sizeof (BlkSize
), &BlkSize
);
1286 if (EFI_ERROR (Status
)) {
1291 if (Trb
->Mode
!= SdNoData
) {
1293 // Calculate Block Count.
1295 BlkCount
= (UINT16
)(Trb
->DataLen
/ Trb
->BlockSize
);
1297 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_BLK_COUNT
, FALSE
, sizeof (BlkCount
), &BlkCount
);
1298 if (EFI_ERROR (Status
)) {
1302 Argument
= Packet
->SdCmdBlk
->CommandArgument
;
1303 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_ARG1
, FALSE
, sizeof (Argument
), &Argument
);
1304 if (EFI_ERROR (Status
)) {
1309 if (Trb
->Mode
!= SdNoData
) {
1310 if (Trb
->Mode
!= SdPioMode
) {
1317 TransMode
|= BIT5
| BIT1
;
1320 // SD memory card needs to use AUTO CMD12 feature.
1327 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_TRANS_MOD
, FALSE
, sizeof (TransMode
), &TransMode
);
1328 if (EFI_ERROR (Status
)) {
1332 Cmd
= (UINT16
)LShiftU64(Packet
->SdCmdBlk
->CommandIndex
, 8);
1333 if (Packet
->SdCmdBlk
->CommandType
== SdCommandTypeAdtc
) {
1337 // Convert ResponseType to value
1339 if (Packet
->SdCmdBlk
->CommandType
!= SdCommandTypeBc
) {
1340 switch (Packet
->SdCmdBlk
->ResponseType
) {
1341 case SdResponseTypeR1
:
1342 case SdResponseTypeR5
:
1343 case SdResponseTypeR6
:
1344 case SdResponseTypeR7
:
1345 Cmd
|= (BIT1
| BIT3
| BIT4
);
1347 case SdResponseTypeR2
:
1348 Cmd
|= (BIT0
| BIT3
);
1350 case SdResponseTypeR3
:
1351 case SdResponseTypeR4
:
1354 case SdResponseTypeR1b
:
1355 case SdResponseTypeR5b
:
1356 Cmd
|= (BIT0
| BIT1
| BIT3
| BIT4
);
1366 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_COMMAND
, FALSE
, sizeof (Cmd
), &Cmd
);
1371 Check the TRB execution result.
1373 @param[in] Bar The mmio base address of the slot to be accessed.
1374 @param[in] Trb The pointer to the SD_TRB instance.
1376 @retval EFI_SUCCESS The TRB is executed successfully.
1377 @retval EFI_NOT_READY The TRB is not completed for execution.
1378 @retval Others Some erros happen when executing this request.
1382 SdPeimCheckTrbResult (
1388 SD_COMMAND_PACKET
*Packet
;
1397 Packet
= Trb
->Packet
;
1399 // Check Trb execution result by reading Normal Interrupt Status register.
1401 Status
= SdPeimHcRwMmio (
1402 Bar
+ SD_HC_NOR_INT_STS
,
1407 if (EFI_ERROR (Status
)) {
1411 // Check Transfer Complete bit is set or not.
1413 if ((IntStatus
& BIT1
) == BIT1
) {
1414 if ((IntStatus
& BIT15
) == BIT15
) {
1416 // Read Error Interrupt Status register to check if the error is
1417 // Data Timeout Error.
1418 // If yes, treat it as success as Transfer Complete has higher
1419 // priority than Data Timeout Error.
1421 Status
= SdPeimHcRwMmio (
1422 Bar
+ SD_HC_ERR_INT_STS
,
1427 if (!EFI_ERROR (Status
)) {
1428 if ((IntStatus
& BIT4
) == BIT4
) {
1429 Status
= EFI_SUCCESS
;
1431 Status
= EFI_DEVICE_ERROR
;
1439 // Check if there is a error happened during cmd execution.
1440 // If yes, then do error recovery procedure to follow SD Host Controller
1441 // Simplified Spec 3.0 section 3.10.1.
1443 if ((IntStatus
& BIT15
) == BIT15
) {
1444 Status
= SdPeimHcRwMmio (
1445 Bar
+ SD_HC_ERR_INT_STS
,
1450 if (EFI_ERROR (Status
)) {
1454 if ((IntStatus
& 0x0F) != 0) {
1457 if ((IntStatus
& 0xF0) != 0) {
1461 Status
= SdPeimHcRwMmio (
1467 if (EFI_ERROR (Status
)) {
1470 Status
= SdPeimHcWaitMmioSet (
1477 if (EFI_ERROR (Status
)) {
1481 Status
= EFI_DEVICE_ERROR
;
1485 // Check if DMA interrupt is signalled for the SDMA transfer.
1487 if ((Trb
->Mode
== SdSdmaMode
) && ((IntStatus
& BIT3
) == BIT3
)) {
1489 // Clear DMA interrupt bit.
1492 Status
= SdPeimHcRwMmio (
1493 Bar
+ SD_HC_NOR_INT_STS
,
1498 if (EFI_ERROR (Status
)) {
1502 // Update SDMA Address register.
1504 SdmaAddr
= SD_SDMA_ROUND_UP ((UINT32
)(UINTN
)Trb
->DataPhy
, SD_SDMA_BOUNDARY
);
1505 Status
= SdPeimHcRwMmio (
1506 Bar
+ SD_HC_SDMA_ADDR
,
1511 if (EFI_ERROR (Status
)) {
1514 Trb
->DataPhy
= (UINT32
)(UINTN
)SdmaAddr
;
1517 if ((Packet
->SdCmdBlk
->CommandType
!= SdCommandTypeAdtc
) &&
1518 (Packet
->SdCmdBlk
->ResponseType
!= SdResponseTypeR1b
) &&
1519 (Packet
->SdCmdBlk
->ResponseType
!= SdResponseTypeR5b
)) {
1520 if ((IntStatus
& BIT0
) == BIT0
) {
1521 Status
= EFI_SUCCESS
;
1526 if (Packet
->SdCmdBlk
->CommandIndex
== SD_SEND_TUNING_BLOCK
) {
1528 // When performing tuning procedure (Execute Tuning is set to 1) through PIO mode,
1529 // wait Buffer Read Ready bit of Normal Interrupt Status Register to be 1.
1530 // Refer to SD Host Controller Simplified Specification 3.0 figure 2-29 for details.
1532 if ((IntStatus
& BIT5
) == BIT5
) {
1534 // Clear Buffer Read Ready interrupt at first.
1537 SdPeimHcRwMmio (Bar
+ SD_HC_NOR_INT_STS
, FALSE
, sizeof (IntStatus
), &IntStatus
);
1539 // Read data out from Buffer Port register
1541 for (PioLength
= 0; PioLength
< Trb
->DataLen
; PioLength
+= 4) {
1542 SdPeimHcRwMmio (Bar
+ SD_HC_BUF_DAT_PORT
, TRUE
, 4, (UINT8
*)Trb
->Data
+ PioLength
);
1544 Status
= EFI_SUCCESS
;
1549 Status
= EFI_NOT_READY
;
1552 // Get response data when the cmd is executed successfully.
1554 if (!EFI_ERROR (Status
)) {
1555 if (Packet
->SdCmdBlk
->CommandType
!= SdCommandTypeBc
) {
1556 for (Index
= 0; Index
< 4; Index
++) {
1557 Status
= SdPeimHcRwMmio (
1558 Bar
+ SD_HC_RESPONSE
+ Index
* 4,
1563 if (EFI_ERROR (Status
)) {
1564 SdPeimHcLedOnOff (Bar
, FALSE
);
1568 CopyMem (Packet
->SdStatusBlk
, Response
, sizeof (Response
));
1572 if (Status
!= EFI_NOT_READY
) {
1573 SdPeimHcLedOnOff (Bar
, FALSE
);
1580 Wait for the TRB execution result.
1582 @param[in] Bar The mmio base address of the slot to be accessed.
1583 @param[in] Trb The pointer to the SD_TRB instance.
1585 @retval EFI_SUCCESS The TRB is executed successfully.
1586 @retval Others Some erros happen when executing this request.
1590 SdPeimWaitTrbResult (
1596 SD_COMMAND_PACKET
*Packet
;
1598 BOOLEAN InfiniteWait
;
1600 Packet
= Trb
->Packet
;
1602 // Wait Command Complete Interrupt Status bit in Normal Interrupt Status Register
1604 Timeout
= Packet
->Timeout
;
1606 InfiniteWait
= TRUE
;
1608 InfiniteWait
= FALSE
;
1611 while (InfiniteWait
|| (Timeout
> 0)) {
1613 // Check Trb execution result by reading Normal Interrupt Status register.
1615 Status
= SdPeimCheckTrbResult (Bar
, Trb
);
1616 if (Status
!= EFI_NOT_READY
) {
1620 // Stall for 1 microsecond.
1622 MicroSecondDelay (1);
1631 Sends SD command to an SD card that is attached to the SD controller.
1633 If Packet is successfully sent to the SD card, then EFI_SUCCESS is returned.
1635 If a device error occurs while sending the Packet, then EFI_DEVICE_ERROR is returned.
1637 If Slot is not in a valid range for the SD controller, then EFI_INVALID_PARAMETER
1640 If Packet defines a data command but both InDataBuffer and OutDataBuffer are NULL,
1641 EFI_INVALID_PARAMETER is returned.
1643 @param[in] Slot The slot number of the Sd card to send the command to.
1644 @param[in,out] Packet A pointer to the SD command data structure.
1646 @retval EFI_SUCCESS The SD Command Packet was sent by the host.
1647 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send the SD
1649 @retval EFI_INVALID_PARAMETER Packet, Slot, or the contents of the Packet is invalid.
1650 @retval EFI_INVALID_PARAMETER Packet defines a data command but both InDataBuffer and
1651 OutDataBuffer are NULL.
1652 @retval EFI_NO_MEDIA SD Device not present in the Slot.
1653 @retval EFI_UNSUPPORTED The command described by the SD Command Packet is not
1654 supported by the host controller.
1655 @retval EFI_BAD_BUFFER_SIZE The InTransferLength or OutTransferLength exceeds the
1656 limit supported by SD card ( i.e. if the number of bytes
1657 exceed the Last LBA).
1663 IN SD_PEIM_HC_SLOT
*Slot
,
1664 IN OUT SD_COMMAND_PACKET
*Packet
1670 if (Packet
== NULL
) {
1671 return EFI_INVALID_PARAMETER
;
1674 if ((Packet
->SdCmdBlk
== NULL
) || (Packet
->SdStatusBlk
== NULL
)) {
1675 return EFI_INVALID_PARAMETER
;
1678 if ((Packet
->OutDataBuffer
== NULL
) && (Packet
->OutTransferLength
!= 0)) {
1679 return EFI_INVALID_PARAMETER
;
1682 if ((Packet
->InDataBuffer
== NULL
) && (Packet
->InTransferLength
!= 0)) {
1683 return EFI_INVALID_PARAMETER
;
1686 Trb
= SdPeimCreateTrb (Slot
, Packet
);
1688 return EFI_OUT_OF_RESOURCES
;
1691 Status
= SdPeimWaitTrbEnv (Slot
->SdHcBase
, Trb
);
1692 if (EFI_ERROR (Status
)) {
1696 Status
= SdPeimExecTrb (Slot
->SdHcBase
, Trb
);
1697 if (EFI_ERROR (Status
)) {
1701 Status
= SdPeimWaitTrbResult (Slot
->SdHcBase
, Trb
);
1702 if (EFI_ERROR (Status
)) {
1707 SdPeimFreeTrb (Trb
);
1713 Send command GO_IDLE_STATE to the device to make it go to Idle State.
1715 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
1717 @param[in] Slot The slot number of the SD card to send the command to.
1719 @retval EFI_SUCCESS The SD device is reset correctly.
1720 @retval Others The device reset fails.
1725 IN SD_PEIM_HC_SLOT
*Slot
1728 SD_COMMAND_BLOCK SdCmdBlk
;
1729 SD_STATUS_BLOCK SdStatusBlk
;
1730 SD_COMMAND_PACKET Packet
;
1733 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
1734 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
1735 ZeroMem (&Packet
, sizeof (Packet
));
1737 Packet
.SdCmdBlk
= &SdCmdBlk
;
1738 Packet
.SdStatusBlk
= &SdStatusBlk
;
1739 Packet
.Timeout
= SD_TIMEOUT
;
1741 SdCmdBlk
.CommandIndex
= SD_GO_IDLE_STATE
;
1742 SdCmdBlk
.CommandType
= SdCommandTypeBc
;
1743 SdCmdBlk
.ResponseType
= 0;
1744 SdCmdBlk
.CommandArgument
= 0;
1746 Status
= SdPeimExecCmd (Slot
, &Packet
);
1752 Send command SEND_IF_COND to the device to inquiry the SD Memory Card interface
1755 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
1757 @param[in] Slot The slot number of the SD card to send the command to.
1758 @param[in] SupplyVoltage The supplied voltage by the host.
1759 @param[in] CheckPattern The check pattern to be sent to the device.
1761 @retval EFI_SUCCESS The operation is done correctly.
1762 @retval Others The operation fails.
1766 SdPeimVoltageCheck (
1767 IN SD_PEIM_HC_SLOT
*Slot
,
1768 IN UINT8 SupplyVoltage
,
1769 IN UINT8 CheckPattern
1772 SD_COMMAND_BLOCK SdCmdBlk
;
1773 SD_STATUS_BLOCK SdStatusBlk
;
1774 SD_COMMAND_PACKET Packet
;
1777 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
1778 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
1779 ZeroMem (&Packet
, sizeof (Packet
));
1781 Packet
.SdCmdBlk
= &SdCmdBlk
;
1782 Packet
.SdStatusBlk
= &SdStatusBlk
;
1783 Packet
.Timeout
= SD_TIMEOUT
;
1785 SdCmdBlk
.CommandIndex
= SD_SEND_IF_COND
;
1786 SdCmdBlk
.CommandType
= SdCommandTypeBcr
;
1787 SdCmdBlk
.ResponseType
= SdResponseTypeR7
;
1788 SdCmdBlk
.CommandArgument
= (SupplyVoltage
<< 8) | CheckPattern
;
1790 Status
= SdPeimExecCmd (Slot
, &Packet
);
1791 if (!EFI_ERROR (Status
)) {
1792 if (SdStatusBlk
.Resp0
!= SdCmdBlk
.CommandArgument
) {
1793 return EFI_DEVICE_ERROR
;
1801 Send command SDIO_SEND_OP_COND to the device to see whether it is SDIO device.
1803 Refer to SDIO Simplified Spec 3 Section 3.2 for details.
1805 @param[in] Slot The slot number of the SD card to send the command to.
1806 @param[in] VoltageWindow The supply voltage window.
1807 @param[in] S18r The boolean to show if it should switch to 1.8v.
1809 @retval EFI_SUCCESS The operation is done correctly.
1810 @retval Others The operation fails.
1815 IN SD_PEIM_HC_SLOT
*Slot
,
1816 IN UINT32 VoltageWindow
,
1820 SD_COMMAND_BLOCK SdCmdBlk
;
1821 SD_STATUS_BLOCK SdStatusBlk
;
1822 SD_COMMAND_PACKET Packet
;
1826 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
1827 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
1828 ZeroMem (&Packet
, sizeof (Packet
));
1830 Packet
.SdCmdBlk
= &SdCmdBlk
;
1831 Packet
.SdStatusBlk
= &SdStatusBlk
;
1832 Packet
.Timeout
= SD_TIMEOUT
;
1834 SdCmdBlk
.CommandIndex
= SDIO_SEND_OP_COND
;
1835 SdCmdBlk
.CommandType
= SdCommandTypeBcr
;
1836 SdCmdBlk
.ResponseType
= SdResponseTypeR4
;
1838 Switch
= S18r
? BIT24
: 0;
1840 SdCmdBlk
.CommandArgument
= (VoltageWindow
& 0xFFFFFF) | Switch
;
1842 Status
= SdPeimExecCmd (Slot
, &Packet
);
1848 Send command SD_SEND_OP_COND to the device to see whether it is SDIO device.
1850 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
1852 @param[in] Slot The slot number of the SD card to send the command to.
1853 @param[in] Rca The relative device address of addressed device.
1854 @param[in] VoltageWindow The supply voltage window.
1855 @param[in] S18r The boolean to show if it should switch to 1.8v.
1856 @param[in] Xpc The boolean to show if it should provide 0.36w power control.
1857 @param[in] Hcs The boolean to show if it support host capacity info.
1858 @param[out] Ocr The buffer to store returned OCR register value.
1861 @retval EFI_SUCCESS The operation is done correctly.
1862 @retval Others The operation fails.
1867 IN SD_PEIM_HC_SLOT
*Slot
,
1869 IN UINT32 VoltageWindow
,
1876 SD_COMMAND_BLOCK SdCmdBlk
;
1877 SD_STATUS_BLOCK SdStatusBlk
;
1878 SD_COMMAND_PACKET Packet
;
1882 UINT32 HostCapacity
;
1884 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
1885 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
1886 ZeroMem (&Packet
, sizeof (Packet
));
1888 Packet
.SdCmdBlk
= &SdCmdBlk
;
1889 Packet
.SdStatusBlk
= &SdStatusBlk
;
1890 Packet
.Timeout
= SD_TIMEOUT
;
1892 SdCmdBlk
.CommandIndex
= SD_APP_CMD
;
1893 SdCmdBlk
.CommandType
= SdCommandTypeAc
;
1894 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
1895 SdCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
1897 Status
= SdPeimExecCmd (Slot
, &Packet
);
1898 if (EFI_ERROR (Status
)) {
1902 SdCmdBlk
.CommandIndex
= SD_SEND_OP_COND
;
1903 SdCmdBlk
.CommandType
= SdCommandTypeBcr
;
1904 SdCmdBlk
.ResponseType
= SdResponseTypeR3
;
1906 Switch
= S18r
? BIT24
: 0;
1907 MaxPower
= Xpc
? BIT28
: 0;
1908 HostCapacity
= Hcs
? BIT30
: 0;
1909 SdCmdBlk
.CommandArgument
= (VoltageWindow
& 0xFFFFFF) | Switch
| MaxPower
| HostCapacity
;
1911 Status
= SdPeimExecCmd (Slot
, &Packet
);
1912 if (!EFI_ERROR (Status
)) {
1914 // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12.
1916 *Ocr
= SdStatusBlk
.Resp0
;
1923 Broadcast command ALL_SEND_CID to the bus to ask all the SD devices to send the
1924 data of their CID registers.
1926 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
1928 @param[in] Slot The slot number of the SD card to send the command to.
1930 @retval EFI_SUCCESS The operation is done correctly.
1931 @retval Others The operation fails.
1936 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_ALL_SEND_CID
;
1953 SdCmdBlk
.CommandType
= SdCommandTypeBcr
;
1954 SdCmdBlk
.ResponseType
= SdResponseTypeR2
;
1955 SdCmdBlk
.CommandArgument
= 0;
1957 Status
= SdPeimExecCmd (Slot
, &Packet
);
1963 Send command SET_RELATIVE_ADDR to the SD device to assign a Relative device
1966 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
1968 @param[in] Slot The slot number of the SD card to send the command to.
1969 @param[out] Rca The relative device address to be assigned.
1971 @retval EFI_SUCCESS The operation is done correctly.
1972 @retval Others The operation fails.
1977 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_SET_RELATIVE_ADDR
;
1995 SdCmdBlk
.CommandType
= SdCommandTypeBcr
;
1996 SdCmdBlk
.ResponseType
= SdResponseTypeR6
;
1998 Status
= SdPeimExecCmd (Slot
, &Packet
);
1999 if (!EFI_ERROR (Status
)) {
2000 *Rca
= (UINT16
)(SdStatusBlk
.Resp0
>> 16);
2007 Send command SEND_CSD to the SD device to get the data of the CSD register.
2009 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
2011 @param[in] Slot The slot number of the SD card to send the command to.
2012 @param[in] Rca The relative device address of selected device.
2013 @param[out] Csd The buffer to store the content of the CSD register.
2014 Note the caller should ignore the lowest byte of this
2015 buffer as the content of this byte is meaningless even
2016 if the operation succeeds.
2018 @retval EFI_SUCCESS The operation is done correctly.
2019 @retval Others The operation fails.
2024 IN SD_PEIM_HC_SLOT
*Slot
,
2029 SD_COMMAND_BLOCK SdCmdBlk
;
2030 SD_STATUS_BLOCK SdStatusBlk
;
2031 SD_COMMAND_PACKET Packet
;
2034 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
2035 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
2036 ZeroMem (&Packet
, sizeof (Packet
));
2038 Packet
.SdCmdBlk
= &SdCmdBlk
;
2039 Packet
.SdStatusBlk
= &SdStatusBlk
;
2040 Packet
.Timeout
= SD_TIMEOUT
;
2042 SdCmdBlk
.CommandIndex
= SD_SEND_CSD
;
2043 SdCmdBlk
.CommandType
= SdCommandTypeAc
;
2044 SdCmdBlk
.ResponseType
= SdResponseTypeR2
;
2045 SdCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
2047 Status
= SdPeimExecCmd (Slot
, &Packet
);
2048 if (!EFI_ERROR (Status
)) {
2050 // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12.
2052 CopyMem (((UINT8
*)Csd
) + 1, &SdStatusBlk
.Resp0
, sizeof (SD_CSD
) - 1);
2059 Send command SELECT_DESELECT_CARD to the SD device to select/deselect it.
2061 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
2063 @param[in] Slot The slot number of the SD card to send the command to.
2064 @param[in] Rca The relative device address of selected device.
2066 @retval EFI_SUCCESS The operation is done correctly.
2067 @retval Others The operation fails.
2072 IN SD_PEIM_HC_SLOT
*Slot
,
2076 SD_COMMAND_BLOCK SdCmdBlk
;
2077 SD_STATUS_BLOCK SdStatusBlk
;
2078 SD_COMMAND_PACKET Packet
;
2081 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
2082 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
2083 ZeroMem (&Packet
, sizeof (Packet
));
2085 Packet
.SdCmdBlk
= &SdCmdBlk
;
2086 Packet
.SdStatusBlk
= &SdStatusBlk
;
2087 Packet
.Timeout
= SD_TIMEOUT
;
2089 SdCmdBlk
.CommandIndex
= SD_SELECT_DESELECT_CARD
;
2090 SdCmdBlk
.CommandType
= SdCommandTypeAc
;
2091 SdCmdBlk
.ResponseType
= SdResponseTypeR1b
;
2092 SdCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
2094 Status
= SdPeimExecCmd (Slot
, &Packet
);
2100 Send command VOLTAGE_SWITCH to the SD device to switch the voltage of the device.
2102 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
2104 @param[in] Slot The slot number of the SD card to send the command to.
2106 @retval EFI_SUCCESS The operation is done correctly.
2107 @retval Others The operation fails.
2111 SdPeimVoltageSwitch (
2112 IN SD_PEIM_HC_SLOT
*Slot
2115 SD_COMMAND_BLOCK SdCmdBlk
;
2116 SD_STATUS_BLOCK SdStatusBlk
;
2117 SD_COMMAND_PACKET Packet
;
2120 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
2121 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
2122 ZeroMem (&Packet
, sizeof (Packet
));
2124 Packet
.SdCmdBlk
= &SdCmdBlk
;
2125 Packet
.SdStatusBlk
= &SdStatusBlk
;
2126 Packet
.Timeout
= SD_TIMEOUT
;
2128 SdCmdBlk
.CommandIndex
= SD_VOLTAGE_SWITCH
;
2129 SdCmdBlk
.CommandType
= SdCommandTypeAc
;
2130 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2131 SdCmdBlk
.CommandArgument
= 0;
2133 Status
= SdPeimExecCmd (Slot
, &Packet
);
2139 Send command SET_BUS_WIDTH to the SD device to set the bus width.
2141 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
2143 @param[in] Slot The slot number of the SD card to send the command to.
2144 @param[in] Rca The relative device address of addressed device.
2145 @param[in] BusWidth The bus width to be set, it could be 1 or 4.
2147 @retval EFI_SUCCESS The operation is done correctly.
2148 @retval Others The operation fails.
2153 IN SD_PEIM_HC_SLOT
*Slot
,
2158 SD_COMMAND_BLOCK SdCmdBlk
;
2159 SD_STATUS_BLOCK SdStatusBlk
;
2160 SD_COMMAND_PACKET Packet
;
2164 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
2165 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
2166 ZeroMem (&Packet
, sizeof (Packet
));
2168 Packet
.SdCmdBlk
= &SdCmdBlk
;
2169 Packet
.SdStatusBlk
= &SdStatusBlk
;
2170 Packet
.Timeout
= SD_TIMEOUT
;
2172 SdCmdBlk
.CommandIndex
= SD_APP_CMD
;
2173 SdCmdBlk
.CommandType
= SdCommandTypeAc
;
2174 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2175 SdCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
2177 Status
= SdPeimExecCmd (Slot
, &Packet
);
2178 if (EFI_ERROR (Status
)) {
2182 SdCmdBlk
.CommandIndex
= SD_SET_BUS_WIDTH
;
2183 SdCmdBlk
.CommandType
= SdCommandTypeAc
;
2184 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2186 if (BusWidth
== 1) {
2188 } else if (BusWidth
== 4) {
2191 return EFI_INVALID_PARAMETER
;
2193 SdCmdBlk
.CommandArgument
= Value
& 0x3;
2195 Status
= SdPeimExecCmd (Slot
, &Packet
);
2201 Send command SWITCH_FUNC to the SD device to check switchable function or switch card function.
2203 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
2205 @param[in] Slot The slot number of the SD card to send the command to.
2206 @param[in] AccessMode The value for access mode group.
2207 @param[in] CommandSystem The value for command set group.
2208 @param[in] DriveStrength The value for drive length group.
2209 @param[in] PowerLimit The value for power limit group.
2210 @param[in] Mode Switch or check function.
2211 @param[out] SwitchResp The return switch function status.
2213 @retval EFI_SUCCESS The operation is done correctly.
2214 @retval Others The operation fails.
2219 IN SD_PEIM_HC_SLOT
*Slot
,
2220 IN UINT8 AccessMode
,
2221 IN UINT8 CommandSystem
,
2222 IN UINT8 DriveStrength
,
2223 IN UINT8 PowerLimit
,
2225 OUT UINT8
*SwitchResp
2228 SD_COMMAND_BLOCK SdCmdBlk
;
2229 SD_STATUS_BLOCK SdStatusBlk
;
2230 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_SWITCH_FUNC
;
2243 SdCmdBlk
.CommandType
= SdCommandTypeAdtc
;
2244 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2246 ModeValue
= Mode
? BIT31
: 0;
2247 SdCmdBlk
.CommandArgument
= (AccessMode
& 0xF) | ((PowerLimit
& 0xF) << 4) | \
2248 ((DriveStrength
& 0xF) << 8) | ((DriveStrength
& 0xF) << 12) | \
2250 Packet
.InDataBuffer
= SwitchResp
;
2251 Packet
.InTransferLength
= 64;
2253 Status
= SdPeimExecCmd (Slot
, &Packet
);
2259 Send command SEND_STATUS to the addressed SD device to get its status register.
2261 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
2263 @param[in] Slot The slot number of the SD card to send the command to.
2264 @param[in] Rca The relative device address of addressed device.
2265 @param[out] DevStatus The returned device status.
2267 @retval EFI_SUCCESS The operation is done correctly.
2268 @retval Others The operation fails.
2273 IN SD_PEIM_HC_SLOT
*Slot
,
2275 OUT UINT32
*DevStatus
2278 SD_COMMAND_BLOCK SdCmdBlk
;
2279 SD_STATUS_BLOCK SdStatusBlk
;
2280 SD_COMMAND_PACKET Packet
;
2283 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
2284 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
2285 ZeroMem (&Packet
, sizeof (Packet
));
2287 Packet
.SdCmdBlk
= &SdCmdBlk
;
2288 Packet
.SdStatusBlk
= &SdStatusBlk
;
2289 Packet
.Timeout
= SD_TIMEOUT
;
2291 SdCmdBlk
.CommandIndex
= SD_SEND_STATUS
;
2292 SdCmdBlk
.CommandType
= SdCommandTypeAc
;
2293 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2294 SdCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
2296 Status
= SdPeimExecCmd (Slot
, &Packet
);
2297 if (!EFI_ERROR (Status
)) {
2298 *DevStatus
= SdStatusBlk
.Resp0
;
2305 Send command READ_SINGLE_BLOCK/WRITE_SINGLE_BLOCK to the addressed SD device
2306 to read/write the specified number of blocks.
2308 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
2310 @param[in] Slot The slot number of the SD card to send the command to.
2311 @param[in] Lba The logical block address of starting access.
2312 @param[in] BlockSize The block size of specified SD device partition.
2313 @param[in] Buffer The pointer to the transfer buffer.
2314 @param[in] BufferSize The size of transfer buffer.
2315 @param[in] IsRead Boolean to show the operation direction.
2317 @retval EFI_SUCCESS The operation is done correctly.
2318 @retval Others The operation fails.
2322 SdPeimRwSingleBlock (
2323 IN SD_PEIM_HC_SLOT
*Slot
,
2325 IN UINT32 BlockSize
,
2327 IN UINTN BufferSize
,
2331 SD_COMMAND_BLOCK SdCmdBlk
;
2332 SD_STATUS_BLOCK SdStatusBlk
;
2333 SD_COMMAND_PACKET Packet
;
2336 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
2337 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
2338 ZeroMem (&Packet
, sizeof (Packet
));
2340 Packet
.SdCmdBlk
= &SdCmdBlk
;
2341 Packet
.SdStatusBlk
= &SdStatusBlk
;
2343 // Calculate timeout value through the below formula.
2344 // Timeout = (transfer size) / (2MB/s).
2345 // Taking 2MB/s as divisor is because it's the lowest
2346 // transfer speed of class 2.
2348 Packet
.Timeout
= (BufferSize
/ (2 * 1024 * 1024) + 1) * 1000 * 1000;;
2351 Packet
.InDataBuffer
= Buffer
;
2352 Packet
.InTransferLength
= (UINT32
)BufferSize
;
2354 SdCmdBlk
.CommandIndex
= SD_READ_SINGLE_BLOCK
;
2355 SdCmdBlk
.CommandType
= SdCommandTypeAdtc
;
2356 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2358 Packet
.OutDataBuffer
= Buffer
;
2359 Packet
.OutTransferLength
= (UINT32
)BufferSize
;
2361 SdCmdBlk
.CommandIndex
= SD_WRITE_SINGLE_BLOCK
;
2362 SdCmdBlk
.CommandType
= SdCommandTypeAdtc
;
2363 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2366 if (Slot
->SectorAddressing
) {
2367 SdCmdBlk
.CommandArgument
= (UINT32
)Lba
;
2369 SdCmdBlk
.CommandArgument
= (UINT32
)MultU64x32 (Lba
, BlockSize
);
2372 Status
= SdPeimExecCmd (Slot
, &Packet
);
2378 Send command READ_MULTIPLE_BLOCK/WRITE_MULTIPLE_BLOCK to the addressed SD device
2379 to read/write the specified number of blocks.
2381 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
2383 @param[in] Slot The slot number of the SD card to send the command to.
2384 @param[in] Lba The logical block address of starting access.
2385 @param[in] BlockSize The block size of specified SD device partition.
2386 @param[in] Buffer The pointer to the transfer buffer.
2387 @param[in] BufferSize The size of transfer buffer.
2388 @param[in] IsRead Boolean to show the operation direction.
2390 @retval EFI_SUCCESS The operation is done correctly.
2391 @retval Others The operation fails.
2395 SdPeimRwMultiBlocks (
2396 IN SD_PEIM_HC_SLOT
*Slot
,
2398 IN UINT32 BlockSize
,
2400 IN UINTN BufferSize
,
2404 SD_COMMAND_BLOCK SdCmdBlk
;
2405 SD_STATUS_BLOCK SdStatusBlk
;
2406 SD_COMMAND_PACKET Packet
;
2409 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
2410 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
2411 ZeroMem (&Packet
, sizeof (Packet
));
2413 Packet
.SdCmdBlk
= &SdCmdBlk
;
2414 Packet
.SdStatusBlk
= &SdStatusBlk
;
2416 // Calculate timeout value through the below formula.
2417 // Timeout = (transfer size) / (2MB/s).
2418 // Taking 2MB/s as divisor is because it's the lowest
2419 // transfer speed of class 2.
2421 Packet
.Timeout
= (BufferSize
/ (2 * 1024 * 1024) + 1) * 1000 * 1000;;
2424 Packet
.InDataBuffer
= Buffer
;
2425 Packet
.InTransferLength
= (UINT32
)BufferSize
;
2427 SdCmdBlk
.CommandIndex
= SD_READ_MULTIPLE_BLOCK
;
2428 SdCmdBlk
.CommandType
= SdCommandTypeAdtc
;
2429 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2431 Packet
.OutDataBuffer
= Buffer
;
2432 Packet
.OutTransferLength
= (UINT32
)BufferSize
;
2434 SdCmdBlk
.CommandIndex
= SD_WRITE_MULTIPLE_BLOCK
;
2435 SdCmdBlk
.CommandType
= SdCommandTypeAdtc
;
2436 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2439 if (Slot
->SectorAddressing
) {
2440 SdCmdBlk
.CommandArgument
= (UINT32
)Lba
;
2442 SdCmdBlk
.CommandArgument
= (UINT32
)MultU64x32 (Lba
, BlockSize
);
2445 Status
= SdPeimExecCmd (Slot
, &Packet
);
2451 Send command SEND_TUNING_BLOCK to the SD device for SDR104/SDR50 optimal sampling point
2454 It may be sent up to 40 times until the host finishes the tuning procedure.
2456 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
2458 @param[in] Slot The slot number of the SD card to send the command to.
2460 @retval EFI_SUCCESS The operation is done correctly.
2461 @retval Others The operation fails.
2465 SdPeimSendTuningBlk (
2466 IN SD_PEIM_HC_SLOT
*Slot
2469 SD_COMMAND_BLOCK SdCmdBlk
;
2470 SD_STATUS_BLOCK SdStatusBlk
;
2471 SD_COMMAND_PACKET Packet
;
2473 UINT8 TuningBlock
[64];
2475 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
2476 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
2477 ZeroMem (&Packet
, sizeof (Packet
));
2479 Packet
.SdCmdBlk
= &SdCmdBlk
;
2480 Packet
.SdStatusBlk
= &SdStatusBlk
;
2481 Packet
.Timeout
= SD_TIMEOUT
;
2483 SdCmdBlk
.CommandIndex
= SD_SEND_TUNING_BLOCK
;
2484 SdCmdBlk
.CommandType
= SdCommandTypeAdtc
;
2485 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2486 SdCmdBlk
.CommandArgument
= 0;
2488 Packet
.InDataBuffer
= TuningBlock
;
2489 Packet
.InTransferLength
= sizeof (TuningBlock
);
2491 Status
= SdPeimExecCmd (Slot
, &Packet
);
2497 Tuning the sampling point of SDR104 or SDR50 bus speed mode.
2499 Command SD_SEND_TUNING_BLOCK may be sent up to 40 times until the host finishes the
2502 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and SD Host Controller
2503 Simplified Spec 3.0 Figure 2-29 for details.
2505 @param[in] Slot The slot number of the SD card to send the command to.
2507 @retval EFI_SUCCESS The operation is done correctly.
2508 @retval Others The operation fails.
2513 IN SD_PEIM_HC_SLOT
*Slot
2521 // Notify the host that the sampling clock tuning procedure starts.
2524 Status
= SdPeimHcOrMmio (Slot
->SdHcBase
+ SD_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2525 if (EFI_ERROR (Status
)) {
2529 // Ask the device to send a sequence of tuning blocks till the tuning procedure is done.
2533 Status
= SdPeimSendTuningBlk (Slot
);
2534 if (EFI_ERROR (Status
)) {
2538 Status
= SdPeimHcRwMmio (Slot
->SdHcBase
+ SD_HC_HOST_CTRL2
, TRUE
, sizeof (HostCtrl2
), &HostCtrl2
);
2539 if (EFI_ERROR (Status
)) {
2543 if ((HostCtrl2
& (BIT6
| BIT7
)) == 0) {
2547 if ((HostCtrl2
& (BIT6
| BIT7
)) == BIT7
) {
2550 } while (++Retry
< 40);
2552 DEBUG ((EFI_D_ERROR
, "SdPeimTuningClock: Send tuning block fails at %d times with HostCtrl2 %02x\n", Retry
, HostCtrl2
));
2554 // Abort the tuning procedure and reset the tuning circuit.
2556 HostCtrl2
= (UINT8
)~(BIT6
| BIT7
);
2557 Status
= SdPeimHcAndMmio (Slot
->SdHcBase
+ SD_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2558 if (EFI_ERROR (Status
)) {
2561 return EFI_DEVICE_ERROR
;
2565 Switch the bus width to specified width.
2567 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and
2568 SD Host Controller Simplified Spec 3.0 section Figure 3-7 for details.
2570 @param[in] Slot The slot number of the SD card to send the command to.
2571 @param[in] Rca The relative device address to be assigned.
2572 @param[in] BusWidth The bus width to be set, it could be 4 or 8.
2574 @retval EFI_SUCCESS The operation is done correctly.
2575 @retval Others The operation fails.
2579 SdPeimSwitchBusWidth (
2580 IN SD_PEIM_HC_SLOT
*Slot
,
2588 Status
= SdPeimSetBusWidth (Slot
, Rca
, BusWidth
);
2589 if (EFI_ERROR (Status
)) {
2593 Status
= SdPeimSendStatus (Slot
, Rca
, &DevStatus
);
2594 if (EFI_ERROR (Status
)) {
2598 // Check the switch operation is really successful or not.
2600 if ((DevStatus
>> 16) != 0) {
2601 return EFI_DEVICE_ERROR
;
2604 Status
= SdPeimHcSetBusWidth (Slot
->SdHcBase
, BusWidth
);
2610 Switch the high speed timing according to request.
2612 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and
2613 SD Host Controller Simplified Spec 3.0 section Figure 2-29 for details.
2615 @param[in] Slot The slot number of the SD card to send the command to.
2616 @param[in] Rca The relative device address to be assigned.
2617 @param[in] S18a The boolean to show if it's a UHS-I SD card.
2619 @retval EFI_SUCCESS The operation is done correctly.
2620 @retval Others The operation fails.
2625 IN SD_PEIM_HC_SLOT
*Slot
,
2631 SD_HC_SLOT_CAP Capability
;
2637 UINT8 SwitchResp
[64];
2639 Status
= SdPeimGetCsd (Slot
, Rca
, &Slot
->Csd
);
2640 if (EFI_ERROR (Status
)) {
2641 DEBUG ((EFI_D_ERROR
, "SdPeimSetBusMode: SdPeimGetCsd fails with %r\n", Status
));
2645 Status
= SdPeimHcGetCapability (Slot
->SdHcBase
, &Capability
);
2646 if (EFI_ERROR (Status
)) {
2650 Status
= SdPeimSelect (Slot
, Rca
);
2651 if (EFI_ERROR (Status
)) {
2652 DEBUG ((EFI_D_ERROR
, "SdPeimSetBusMode: SdPeimSelect fails with %r\n", Status
));
2657 Status
= SdPeimSwitchBusWidth (Slot
, Rca
, BusWidth
);
2658 if (EFI_ERROR (Status
)) {
2659 DEBUG ((EFI_D_ERROR
, "SdPeimSetBusMode: SdPeimSwitchBusWidth fails with %r\n", Status
));
2664 // Get the supported bus speed from SWITCH cmd return data group #1.
2666 ZeroMem (SwitchResp
, sizeof (SwitchResp
));
2667 Status
= SdPeimSwitch (Slot
, 0xF, 0xF, 0xF, 0xF, FALSE
, SwitchResp
);
2668 if (EFI_ERROR (Status
)) {
2672 // Calculate supported bus speed/bus width/clock frequency by host and device capability.
2675 if (S18a
&& (Capability
.Sdr104
!= 0) && ((SwitchResp
[13] & BIT3
) != 0)) {
2678 } else if (S18a
&& (Capability
.Sdr50
!= 0) && ((SwitchResp
[13] & BIT2
) != 0)) {
2681 } else if (S18a
&& (Capability
.Ddr50
!= 0) && ((SwitchResp
[13] & BIT4
) != 0)) {
2684 } else if ((SwitchResp
[13] & BIT1
) != 0) {
2692 DEBUG ((EFI_D_INFO
, "SdPeimSetBusMode: AccessMode %d ClockFreq %d BusWidth %d\n", AccessMode
, ClockFreq
, BusWidth
));
2694 Status
= SdPeimSwitch (Slot
, AccessMode
, 0xF, 0xF, 0xF, TRUE
, SwitchResp
);
2695 if (EFI_ERROR (Status
)) {
2696 DEBUG ((EFI_D_ERROR
, "SdPeimSetBusMode: SdPeimSwitch fails with %r\n", Status
));
2700 if ((SwitchResp
[16] & 0xF) != AccessMode
) {
2701 DEBUG ((EFI_D_ERROR
, "SdPeimSetBusMode: SdPeimSwitch to AccessMode %d ClockFreq %d BusWidth %d fails! The Switch response is 0x%1x\n", AccessMode
, ClockFreq
, BusWidth
, SwitchResp
[16] & 0xF));
2702 return EFI_DEVICE_ERROR
;
2705 // Set to High Speed timing
2707 if (AccessMode
== 1) {
2709 Status
= SdPeimHcOrMmio (Slot
->SdHcBase
+ SD_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
2710 if (EFI_ERROR (Status
)) {
2715 HostCtrl2
= (UINT8
)~0x7;
2716 Status
= SdPeimHcAndMmio (Slot
->SdHcBase
+ SD_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2717 if (EFI_ERROR (Status
)) {
2720 HostCtrl2
= AccessMode
;
2721 Status
= SdPeimHcOrMmio (Slot
->SdHcBase
+ SD_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2722 if (EFI_ERROR (Status
)) {
2726 Status
= SdPeimHcClockSupply (Slot
->SdHcBase
, ClockFreq
* 1000);
2727 if (EFI_ERROR (Status
)) {
2728 DEBUG ((EFI_D_ERROR
, "SdPeimSetBusMode: SdPeimHcClockSupply %r\n", Status
));
2732 if ((AccessMode
== 3) || ((AccessMode
== 2) && (Capability
.TuningSDR50
!= 0))) {
2733 Status
= SdPeimTuningClock (Slot
);
2734 if (EFI_ERROR (Status
)) {
2735 DEBUG ((EFI_D_ERROR
, "SdPeimSetBusMode: SdPeimTuningClock fails with %r\n", Status
));
2740 DEBUG ((EFI_D_INFO
, "SdPeimSetBusMode: SdPeimSetBusMode %r\n", Status
));
2746 Execute SD device identification procedure.
2748 Refer to SD Physical Layer Simplified Spec 4.1 Section 3.6 for details.
2750 @param[in] Slot The slot number of the SD card to send the command to.
2752 @retval EFI_SUCCESS There is a SD card.
2753 @retval Others There is not a SD card.
2757 SdPeimIdentification (
2758 IN SD_PEIM_HC_SLOT
*Slot
2768 UINT16 ControllerVer
;
2770 UINT32 PresentState
;
2772 SD_HC_SLOT_CAP Capability
;
2775 // 1. Send Cmd0 to the device
2777 Status
= SdPeimReset (Slot
);
2778 if (EFI_ERROR (Status
)) {
2779 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: Executing Cmd0 fails with %r\n", Status
));
2783 // 2. Send Cmd8 to the device
2785 Status
= SdPeimVoltageCheck (Slot
, 0x1, 0xFF);
2786 if (EFI_ERROR (Status
)) {
2787 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: Executing Cmd8 fails with %r\n", Status
));
2791 // 3. Send SDIO Cmd5 to the device to the SDIO device OCR register.
2793 Status
= SdioSendOpCond (Slot
, 0, FALSE
);
2794 if (!EFI_ERROR (Status
)) {
2795 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: Found SDIO device, ignore it as we don't support\n"));
2796 return EFI_DEVICE_ERROR
;
2799 // 4. Send Acmd41 with voltage window 0 to the device
2801 Status
= SdPeimSendOpCond (Slot
, 0, 0, FALSE
, FALSE
, FALSE
, &Ocr
);
2802 if (EFI_ERROR (Status
)) {
2803 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: Executing SdPeimSendOpCond fails with %r\n", Status
));
2804 return EFI_DEVICE_ERROR
;
2807 Status
= SdPeimHcGetCapability (Slot
->SdHcBase
, &Capability
);
2808 if (EFI_ERROR (Status
)) {
2812 Status
= SdPeimHcRwMmio (Slot
->SdHcBase
+ SD_HC_MAX_CURRENT_CAP
, TRUE
, sizeof (Current
), &Current
);
2813 if (EFI_ERROR (Status
)) {
2817 if (Capability
.Voltage33
!= 0) {
2821 MaxCurrent
= ((UINT32
)Current
& 0xFF) * 4;
2822 } else if (Capability
.Voltage30
!= 0) {
2826 MaxCurrent
= (((UINT32
)Current
>> 8) & 0xFF) * 4;
2827 } else if (Capability
.Voltage18
!= 0) {
2831 MaxCurrent
= (((UINT32
)Current
>> 16) & 0xFF) * 4;
2834 return EFI_DEVICE_ERROR
;
2837 if (MaxCurrent
>= 150) {
2843 Status
= SdPeimHcRwMmio (Slot
->SdHcBase
+ SD_HC_CTRL_VER
, TRUE
, sizeof (ControllerVer
), &ControllerVer
);
2844 if (EFI_ERROR (Status
)) {
2848 if ((ControllerVer
& 0xFF) == 2) {
2850 } else if (((ControllerVer
& 0xFF) == 0) || ((ControllerVer
& 0xFF) == 1)) {
2854 return EFI_UNSUPPORTED
;
2857 // 5. Repeatly send Acmd41 with supply voltage window to the device.
2858 // Note here we only support the cards complied with SD physical
2859 // layer simplified spec version 2.0 and version 3.0 and above.
2864 Status
= SdPeimSendOpCond (Slot
, 0, Ocr
, S18r
, Xpc
, TRUE
, &Ocr
);
2865 if (EFI_ERROR (Status
)) {
2866 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: SdPeimSendOpCond fails with %r Ocr %x, S18r %x, Xpc %x\n", Status
, Ocr
, S18r
, Xpc
));
2867 return EFI_DEVICE_ERROR
;
2870 if (Retry
++ == 100) {
2871 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: SdPeimSendOpCond fails too many times\n"));
2872 return EFI_DEVICE_ERROR
;
2874 MicroSecondDelay (10 * 1000);
2875 } while ((Ocr
& BIT31
) == 0);
2878 // 6. If the S18a bit is set and the Host Controller supports 1.8V signaling
2879 // (One of support bits is set to 1: SDR50, SDR104 or DDR50 in the
2880 // Capabilities register), switch its voltage to 1.8V.
2882 if ((Capability
.Sdr50
!= 0 ||
2883 Capability
.Sdr104
!= 0 ||
2884 Capability
.Ddr50
!= 0) &&
2885 ((Ocr
& BIT24
) != 0)) {
2886 Status
= SdPeimVoltageSwitch (Slot
);
2887 if (EFI_ERROR (Status
)) {
2888 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: Executing SdPeimVoltageSwitch fails with %r\n", Status
));
2889 Status
= EFI_DEVICE_ERROR
;
2892 Status
= SdPeimHcStopClock (Slot
->SdHcBase
);
2893 if (EFI_ERROR (Status
)) {
2894 Status
= EFI_DEVICE_ERROR
;
2898 SdPeimHcRwMmio (Slot
->SdHcBase
+ SD_HC_PRESENT_STATE
, TRUE
, sizeof (PresentState
), &PresentState
);
2899 if (((PresentState
>> 20) & 0xF) != 0) {
2900 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: SwitchVoltage fails with PresentState = 0x%x\n", PresentState
));
2901 Status
= EFI_DEVICE_ERROR
;
2905 SdPeimHcOrMmio (Slot
->SdHcBase
+ SD_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2907 MicroSecondDelay (5000);
2909 SdPeimHcRwMmio (Slot
->SdHcBase
+ SD_HC_HOST_CTRL2
, TRUE
, sizeof (HostCtrl2
), &HostCtrl2
);
2910 if ((HostCtrl2
& BIT3
) == 0) {
2911 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: SwitchVoltage fails with HostCtrl2 = 0x%x\n", HostCtrl2
));
2912 Status
= EFI_DEVICE_ERROR
;
2916 SdPeimHcInitClockFreq (Slot
->SdHcBase
);
2918 MicroSecondDelay (1000);
2920 SdPeimHcRwMmio (Slot
->SdHcBase
+ SD_HC_PRESENT_STATE
, TRUE
, sizeof (PresentState
), &PresentState
);
2921 if (((PresentState
>> 20) & 0xF) != 0xF) {
2922 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: SwitchVoltage fails with PresentState = 0x%x, It should be 0xF\n", PresentState
));
2923 Status
= EFI_DEVICE_ERROR
;
2927 DEBUG ((EFI_D_INFO
, "SdPeimIdentification: Switch to 1.8v signal voltage success\n"));
2930 Status
= SdPeimAllSendCid (Slot
);
2931 if (EFI_ERROR (Status
)) {
2932 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: Executing SdPeimAllSendCid fails with %r\n", Status
));
2936 Status
= SdPeimSetRca (Slot
, &Rca
);
2937 if (EFI_ERROR (Status
)) {
2938 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: Executing SdPeimSetRca fails with %r\n", Status
));
2942 // Enter Data Tranfer Mode.
2944 DEBUG ((EFI_D_INFO
, "Found a SD device at slot [%d]\n", Slot
));
2946 Status
= SdPeimSetBusMode (Slot
, Rca
, ((Ocr
& BIT24
) != 0));
2952 // Set SD Bus Power = 0
2954 PowerCtrl
= (UINT8
)~BIT0
;
2955 Status
= SdPeimHcAndMmio (Slot
->SdHcBase
+ SD_HC_POWER_CTRL
, sizeof (PowerCtrl
), &PowerCtrl
);
2956 return EFI_DEVICE_ERROR
;