3 Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php.
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14 #include "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
;
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
;
1001 EDKII_IOMMU_OPERATION MapOp
;
1005 // Calculate a divisor for SD clock frequency
1007 Status
= SdPeimHcGetCapability (Slot
->SdHcBase
, &Capability
);
1008 if (EFI_ERROR (Status
)) {
1012 Trb
= AllocateZeroPool (sizeof (SD_TRB
));
1018 Trb
->BlockSize
= 0x200;
1019 Trb
->Packet
= Packet
;
1020 Trb
->Timeout
= Packet
->Timeout
;
1022 if ((Packet
->InTransferLength
!= 0) && (Packet
->InDataBuffer
!= NULL
)) {
1023 Trb
->Data
= Packet
->InDataBuffer
;
1024 Trb
->DataLen
= Packet
->InTransferLength
;
1026 } else if ((Packet
->OutTransferLength
!= 0) && (Packet
->OutDataBuffer
!= NULL
)) {
1027 Trb
->Data
= Packet
->OutDataBuffer
;
1028 Trb
->DataLen
= Packet
->OutTransferLength
;
1030 } else if ((Packet
->InTransferLength
== 0) && (Packet
->OutTransferLength
== 0)) {
1037 if ((Trb
->DataLen
!= 0) && (Trb
->DataLen
< Trb
->BlockSize
)) {
1038 Trb
->BlockSize
= (UINT16
)Trb
->DataLen
;
1041 if (Packet
->SdCmdBlk
->CommandIndex
== SD_SEND_TUNING_BLOCK
) {
1042 Trb
->Mode
= SdPioMode
;
1045 MapOp
= EdkiiIoMmuOperationBusMasterWrite
;
1047 MapOp
= EdkiiIoMmuOperationBusMasterRead
;
1050 if (Trb
->DataLen
!= 0) {
1051 MapLength
= Trb
->DataLen
;
1052 Status
= IoMmuMap (MapOp
, Trb
->Data
, &MapLength
, &Trb
->DataPhy
, &Trb
->DataMap
);
1054 if (EFI_ERROR (Status
) || (MapLength
!= Trb
->DataLen
)) {
1055 DEBUG ((DEBUG_ERROR
, "SdPeimCreateTrb: Fail to map data buffer.\n"));
1060 if (Trb
->DataLen
== 0) {
1061 Trb
->Mode
= SdNoData
;
1062 } else if (Capability
.Adma2
!= 0) {
1063 Trb
->Mode
= SdAdmaMode
;
1064 Status
= BuildAdmaDescTable (Trb
);
1065 if (EFI_ERROR (Status
)) {
1068 } else if (Capability
.Sdma
!= 0) {
1069 Trb
->Mode
= SdSdmaMode
;
1071 Trb
->Mode
= SdPioMode
;
1077 SdPeimFreeTrb (Trb
);
1082 Free the resource used by the TRB.
1084 @param[in] Trb The pointer to the SD_TRB instance.
1092 if ((Trb
!= NULL
) && (Trb
->DataMap
!= NULL
)) {
1093 IoMmuUnmap (Trb
->DataMap
);
1096 if ((Trb
!= NULL
) && (Trb
->AdmaDesc
!= NULL
)) {
1097 SdPeimFreeMem (Trb
->Slot
->Private
->Pool
, Trb
->AdmaDesc
, Trb
->AdmaDescSize
);
1107 Check if the env is ready for execute specified TRB.
1109 @param[in] Bar The mmio base address of the slot to be accessed.
1110 @param[in] Trb The pointer to the SD_TRB instance.
1112 @retval EFI_SUCCESS The env is ready for TRB execution.
1113 @retval EFI_NOT_READY The env is not ready for TRB execution.
1114 @retval Others Some erros happen.
1124 SD_COMMAND_PACKET
*Packet
;
1125 UINT32 PresentState
;
1127 Packet
= Trb
->Packet
;
1129 if ((Packet
->SdCmdBlk
->CommandType
== SdCommandTypeAdtc
) ||
1130 (Packet
->SdCmdBlk
->ResponseType
== SdResponseTypeR1b
) ||
1131 (Packet
->SdCmdBlk
->ResponseType
== SdResponseTypeR5b
)) {
1133 // Wait Command Inhibit (CMD) and Command Inhibit (DAT) in
1134 // the Present State register to be 0
1136 PresentState
= BIT0
| BIT1
;
1139 // Wait Command Inhibit (CMD) in the Present State register
1142 PresentState
= BIT0
;
1145 Status
= SdPeimHcCheckMmioSet (
1146 Bar
+ SD_HC_PRESENT_STATE
,
1147 sizeof (PresentState
),
1156 Wait for the env to be ready for execute specified TRB.
1158 @param[in] Bar The mmio base address of the slot to be accessed.
1159 @param[in] Trb The pointer to the SD_TRB instance.
1161 @retval EFI_SUCCESS The env is ready for TRB execution.
1162 @retval EFI_TIMEOUT The env is not ready for TRB execution in time.
1163 @retval Others Some erros happen.
1173 SD_COMMAND_PACKET
*Packet
;
1175 BOOLEAN InfiniteWait
;
1178 // Wait Command Complete Interrupt Status bit in Normal Interrupt Status Register
1180 Packet
= Trb
->Packet
;
1181 Timeout
= Packet
->Timeout
;
1183 InfiniteWait
= TRUE
;
1185 InfiniteWait
= FALSE
;
1188 while (InfiniteWait
|| (Timeout
> 0)) {
1190 // Check Trb execution result by reading Normal Interrupt Status register.
1192 Status
= SdPeimCheckTrbEnv (Bar
, Trb
);
1193 if (Status
!= EFI_NOT_READY
) {
1197 // Stall for 1 microsecond.
1199 MicroSecondDelay (1);
1208 Execute the specified TRB.
1210 @param[in] Bar The mmio base address of the slot to be accessed.
1211 @param[in] Trb The pointer to the SD_TRB instance.
1213 @retval EFI_SUCCESS The TRB is sent to host controller successfully.
1214 @retval Others Some erros happen when sending this request to the host controller.
1224 SD_COMMAND_PACKET
*Packet
;
1235 Packet
= Trb
->Packet
;
1237 // Clear all bits in Error Interrupt Status Register
1240 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_ERR_INT_STS
, FALSE
, sizeof (IntStatus
), &IntStatus
);
1241 if (EFI_ERROR (Status
)) {
1245 // Clear all bits in Normal Interrupt Status Register
1248 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_NOR_INT_STS
, FALSE
, sizeof (IntStatus
), &IntStatus
);
1249 if (EFI_ERROR (Status
)) {
1253 // Set Host Control 1 register DMA Select field
1255 if (Trb
->Mode
== SdAdmaMode
) {
1257 Status
= SdPeimHcOrMmio (Bar
+ SD_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
1258 if (EFI_ERROR (Status
)) {
1263 SdPeimHcLedOnOff (Bar
, TRUE
);
1265 if (Trb
->Mode
== SdSdmaMode
) {
1266 if ((UINT64
)(UINTN
)Trb
->DataPhy
>= 0x100000000ul
) {
1267 return EFI_INVALID_PARAMETER
;
1270 SdmaAddr
= (UINT32
)(UINTN
)Trb
->DataPhy
;
1271 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_SDMA_ADDR
, FALSE
, sizeof (SdmaAddr
), &SdmaAddr
);
1272 if (EFI_ERROR (Status
)) {
1275 } else if (Trb
->Mode
== SdAdmaMode
) {
1276 AdmaAddr
= (UINT64
)(UINTN
)Trb
->AdmaDesc
;
1277 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_ADMA_SYS_ADDR
, FALSE
, sizeof (AdmaAddr
), &AdmaAddr
);
1278 if (EFI_ERROR (Status
)) {
1283 BlkSize
= Trb
->BlockSize
;
1284 if (Trb
->Mode
== SdSdmaMode
) {
1286 // Set SDMA boundary to be 512K bytes.
1291 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_BLK_SIZE
, FALSE
, sizeof (BlkSize
), &BlkSize
);
1292 if (EFI_ERROR (Status
)) {
1297 if (Trb
->Mode
!= SdNoData
) {
1299 // Calcuate Block Count.
1301 BlkCount
= (UINT16
)(Trb
->DataLen
/ Trb
->BlockSize
);
1303 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_BLK_COUNT
, FALSE
, sizeof (BlkCount
), &BlkCount
);
1304 if (EFI_ERROR (Status
)) {
1308 Argument
= Packet
->SdCmdBlk
->CommandArgument
;
1309 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_ARG1
, FALSE
, sizeof (Argument
), &Argument
);
1310 if (EFI_ERROR (Status
)) {
1315 if (Trb
->Mode
!= SdNoData
) {
1316 if (Trb
->Mode
!= SdPioMode
) {
1323 TransMode
|= BIT5
| BIT1
;
1326 // SD memory card needs to use AUTO CMD12 feature.
1333 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_TRANS_MOD
, FALSE
, sizeof (TransMode
), &TransMode
);
1334 if (EFI_ERROR (Status
)) {
1338 Cmd
= (UINT16
)LShiftU64(Packet
->SdCmdBlk
->CommandIndex
, 8);
1339 if (Packet
->SdCmdBlk
->CommandType
== SdCommandTypeAdtc
) {
1343 // Convert ResponseType to value
1345 if (Packet
->SdCmdBlk
->CommandType
!= SdCommandTypeBc
) {
1346 switch (Packet
->SdCmdBlk
->ResponseType
) {
1347 case SdResponseTypeR1
:
1348 case SdResponseTypeR5
:
1349 case SdResponseTypeR6
:
1350 case SdResponseTypeR7
:
1351 Cmd
|= (BIT1
| BIT3
| BIT4
);
1353 case SdResponseTypeR2
:
1354 Cmd
|= (BIT0
| BIT3
);
1356 case SdResponseTypeR3
:
1357 case SdResponseTypeR4
:
1360 case SdResponseTypeR1b
:
1361 case SdResponseTypeR5b
:
1362 Cmd
|= (BIT0
| BIT1
| BIT3
| BIT4
);
1372 Status
= SdPeimHcRwMmio (Bar
+ SD_HC_COMMAND
, FALSE
, sizeof (Cmd
), &Cmd
);
1377 Check the TRB execution result.
1379 @param[in] Bar The mmio base address of the slot to be accessed.
1380 @param[in] Trb The pointer to the SD_TRB instance.
1382 @retval EFI_SUCCESS The TRB is executed successfully.
1383 @retval EFI_NOT_READY The TRB is not completed for execution.
1384 @retval Others Some erros happen when executing this request.
1388 SdPeimCheckTrbResult (
1394 SD_COMMAND_PACKET
*Packet
;
1403 Packet
= Trb
->Packet
;
1405 // Check Trb execution result by reading Normal Interrupt Status register.
1407 Status
= SdPeimHcRwMmio (
1408 Bar
+ SD_HC_NOR_INT_STS
,
1413 if (EFI_ERROR (Status
)) {
1417 // Check Transfer Complete bit is set or not.
1419 if ((IntStatus
& BIT1
) == BIT1
) {
1420 if ((IntStatus
& BIT15
) == BIT15
) {
1422 // Read Error Interrupt Status register to check if the error is
1423 // Data Timeout Error.
1424 // If yes, treat it as success as Transfer Complete has higher
1425 // priority than Data Timeout Error.
1427 Status
= SdPeimHcRwMmio (
1428 Bar
+ SD_HC_ERR_INT_STS
,
1433 if (!EFI_ERROR (Status
)) {
1434 if ((IntStatus
& BIT4
) == BIT4
) {
1435 Status
= EFI_SUCCESS
;
1437 Status
= EFI_DEVICE_ERROR
;
1445 // Check if there is a error happened during cmd execution.
1446 // If yes, then do error recovery procedure to follow SD Host Controller
1447 // Simplified Spec 3.0 section 3.10.1.
1449 if ((IntStatus
& BIT15
) == BIT15
) {
1450 Status
= SdPeimHcRwMmio (
1451 Bar
+ SD_HC_ERR_INT_STS
,
1456 if (EFI_ERROR (Status
)) {
1460 if ((IntStatus
& 0x0F) != 0) {
1463 if ((IntStatus
& 0xF0) != 0) {
1467 Status
= SdPeimHcRwMmio (
1473 if (EFI_ERROR (Status
)) {
1476 Status
= SdPeimHcWaitMmioSet (
1483 if (EFI_ERROR (Status
)) {
1487 Status
= EFI_DEVICE_ERROR
;
1491 // Check if DMA interrupt is signalled for the SDMA transfer.
1493 if ((Trb
->Mode
== SdSdmaMode
) && ((IntStatus
& BIT3
) == BIT3
)) {
1495 // Clear DMA interrupt bit.
1498 Status
= SdPeimHcRwMmio (
1499 Bar
+ SD_HC_NOR_INT_STS
,
1504 if (EFI_ERROR (Status
)) {
1508 // Update SDMA Address register.
1510 SdmaAddr
= SD_SDMA_ROUND_UP ((UINT32
)(UINTN
)Trb
->DataPhy
, SD_SDMA_BOUNDARY
);
1511 Status
= SdPeimHcRwMmio (
1512 Bar
+ SD_HC_SDMA_ADDR
,
1517 if (EFI_ERROR (Status
)) {
1520 Trb
->DataPhy
= (UINT32
)(UINTN
)SdmaAddr
;
1523 if ((Packet
->SdCmdBlk
->CommandType
!= SdCommandTypeAdtc
) &&
1524 (Packet
->SdCmdBlk
->ResponseType
!= SdResponseTypeR1b
) &&
1525 (Packet
->SdCmdBlk
->ResponseType
!= SdResponseTypeR5b
)) {
1526 if ((IntStatus
& BIT0
) == BIT0
) {
1527 Status
= EFI_SUCCESS
;
1532 if (Packet
->SdCmdBlk
->CommandIndex
== SD_SEND_TUNING_BLOCK
) {
1534 // When performing tuning procedure (Execute Tuning is set to 1) through PIO mode,
1535 // wait Buffer Read Ready bit of Normal Interrupt Status Register to be 1.
1536 // Refer to SD Host Controller Simplified Specification 3.0 figure 2-29 for details.
1538 if ((IntStatus
& BIT5
) == BIT5
) {
1540 // Clear Buffer Read Ready interrupt at first.
1543 SdPeimHcRwMmio (Bar
+ SD_HC_NOR_INT_STS
, FALSE
, sizeof (IntStatus
), &IntStatus
);
1545 // Read data out from Buffer Port register
1547 for (PioLength
= 0; PioLength
< Trb
->DataLen
; PioLength
+= 4) {
1548 SdPeimHcRwMmio (Bar
+ SD_HC_BUF_DAT_PORT
, TRUE
, 4, (UINT8
*)Trb
->Data
+ PioLength
);
1550 Status
= EFI_SUCCESS
;
1555 Status
= EFI_NOT_READY
;
1558 // Get response data when the cmd is executed successfully.
1560 if (!EFI_ERROR (Status
)) {
1561 if (Packet
->SdCmdBlk
->CommandType
!= SdCommandTypeBc
) {
1562 for (Index
= 0; Index
< 4; Index
++) {
1563 Status
= SdPeimHcRwMmio (
1564 Bar
+ SD_HC_RESPONSE
+ Index
* 4,
1569 if (EFI_ERROR (Status
)) {
1570 SdPeimHcLedOnOff (Bar
, FALSE
);
1574 CopyMem (Packet
->SdStatusBlk
, Response
, sizeof (Response
));
1578 if (Status
!= EFI_NOT_READY
) {
1579 SdPeimHcLedOnOff (Bar
, FALSE
);
1586 Wait for the TRB execution result.
1588 @param[in] Bar The mmio base address of the slot to be accessed.
1589 @param[in] Trb The pointer to the SD_TRB instance.
1591 @retval EFI_SUCCESS The TRB is executed successfully.
1592 @retval Others Some erros happen when executing this request.
1596 SdPeimWaitTrbResult (
1602 SD_COMMAND_PACKET
*Packet
;
1604 BOOLEAN InfiniteWait
;
1606 Packet
= Trb
->Packet
;
1608 // Wait Command Complete Interrupt Status bit in Normal Interrupt Status Register
1610 Timeout
= Packet
->Timeout
;
1612 InfiniteWait
= TRUE
;
1614 InfiniteWait
= FALSE
;
1617 while (InfiniteWait
|| (Timeout
> 0)) {
1619 // Check Trb execution result by reading Normal Interrupt Status register.
1621 Status
= SdPeimCheckTrbResult (Bar
, Trb
);
1622 if (Status
!= EFI_NOT_READY
) {
1626 // Stall for 1 microsecond.
1628 MicroSecondDelay (1);
1637 Sends SD command to an SD card that is attached to the SD controller.
1639 If Packet is successfully sent to the SD card, then EFI_SUCCESS is returned.
1641 If a device error occurs while sending the Packet, then EFI_DEVICE_ERROR is returned.
1643 If Slot is not in a valid range for the SD controller, then EFI_INVALID_PARAMETER
1646 If Packet defines a data command but both InDataBuffer and OutDataBuffer are NULL,
1647 EFI_INVALID_PARAMETER is returned.
1649 @param[in] Slot The slot number of the Sd card to send the command to.
1650 @param[in,out] Packet A pointer to the SD command data structure.
1652 @retval EFI_SUCCESS The SD Command Packet was sent by the host.
1653 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send the SD
1655 @retval EFI_INVALID_PARAMETER Packet, Slot, or the contents of the Packet is invalid.
1656 @retval EFI_INVALID_PARAMETER Packet defines a data command but both InDataBuffer and
1657 OutDataBuffer are NULL.
1658 @retval EFI_NO_MEDIA SD Device not present in the Slot.
1659 @retval EFI_UNSUPPORTED The command described by the SD Command Packet is not
1660 supported by the host controller.
1661 @retval EFI_BAD_BUFFER_SIZE The InTransferLength or OutTransferLength exceeds the
1662 limit supported by SD card ( i.e. if the number of bytes
1663 exceed the Last LBA).
1669 IN SD_PEIM_HC_SLOT
*Slot
,
1670 IN OUT SD_COMMAND_PACKET
*Packet
1676 if (Packet
== NULL
) {
1677 return EFI_INVALID_PARAMETER
;
1680 if ((Packet
->SdCmdBlk
== NULL
) || (Packet
->SdStatusBlk
== NULL
)) {
1681 return EFI_INVALID_PARAMETER
;
1684 if ((Packet
->OutDataBuffer
== NULL
) && (Packet
->OutTransferLength
!= 0)) {
1685 return EFI_INVALID_PARAMETER
;
1688 if ((Packet
->InDataBuffer
== NULL
) && (Packet
->InTransferLength
!= 0)) {
1689 return EFI_INVALID_PARAMETER
;
1692 Trb
= SdPeimCreateTrb (Slot
, Packet
);
1694 return EFI_OUT_OF_RESOURCES
;
1697 Status
= SdPeimWaitTrbEnv (Slot
->SdHcBase
, Trb
);
1698 if (EFI_ERROR (Status
)) {
1702 Status
= SdPeimExecTrb (Slot
->SdHcBase
, Trb
);
1703 if (EFI_ERROR (Status
)) {
1707 Status
= SdPeimWaitTrbResult (Slot
->SdHcBase
, Trb
);
1708 if (EFI_ERROR (Status
)) {
1713 SdPeimFreeTrb (Trb
);
1719 Send command GO_IDLE_STATE to the device to make it go to Idle State.
1721 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
1723 @param[in] Slot The slot number of the SD card to send the command to.
1725 @retval EFI_SUCCESS The SD device is reset correctly.
1726 @retval Others The device reset fails.
1731 IN SD_PEIM_HC_SLOT
*Slot
1734 SD_COMMAND_BLOCK SdCmdBlk
;
1735 SD_STATUS_BLOCK SdStatusBlk
;
1736 SD_COMMAND_PACKET Packet
;
1739 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
1740 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
1741 ZeroMem (&Packet
, sizeof (Packet
));
1743 Packet
.SdCmdBlk
= &SdCmdBlk
;
1744 Packet
.SdStatusBlk
= &SdStatusBlk
;
1745 Packet
.Timeout
= SD_TIMEOUT
;
1747 SdCmdBlk
.CommandIndex
= SD_GO_IDLE_STATE
;
1748 SdCmdBlk
.CommandType
= SdCommandTypeBc
;
1749 SdCmdBlk
.ResponseType
= 0;
1750 SdCmdBlk
.CommandArgument
= 0;
1752 Status
= SdPeimExecCmd (Slot
, &Packet
);
1758 Send command SEND_IF_COND to the device to inquiry the SD Memory Card interface
1761 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
1763 @param[in] Slot The slot number of the SD card to send the command to.
1764 @param[in] SupplyVoltage The supplied voltage by the host.
1765 @param[in] CheckPattern The check pattern to be sent to the device.
1767 @retval EFI_SUCCESS The operation is done correctly.
1768 @retval Others The operation fails.
1772 SdPeimVoltageCheck (
1773 IN SD_PEIM_HC_SLOT
*Slot
,
1774 IN UINT8 SupplyVoltage
,
1775 IN UINT8 CheckPattern
1778 SD_COMMAND_BLOCK SdCmdBlk
;
1779 SD_STATUS_BLOCK SdStatusBlk
;
1780 SD_COMMAND_PACKET Packet
;
1783 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
1784 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
1785 ZeroMem (&Packet
, sizeof (Packet
));
1787 Packet
.SdCmdBlk
= &SdCmdBlk
;
1788 Packet
.SdStatusBlk
= &SdStatusBlk
;
1789 Packet
.Timeout
= SD_TIMEOUT
;
1791 SdCmdBlk
.CommandIndex
= SD_SEND_IF_COND
;
1792 SdCmdBlk
.CommandType
= SdCommandTypeBcr
;
1793 SdCmdBlk
.ResponseType
= SdResponseTypeR7
;
1794 SdCmdBlk
.CommandArgument
= (SupplyVoltage
<< 8) | CheckPattern
;
1796 Status
= SdPeimExecCmd (Slot
, &Packet
);
1797 if (!EFI_ERROR (Status
)) {
1798 if (SdStatusBlk
.Resp0
!= SdCmdBlk
.CommandArgument
) {
1799 return EFI_DEVICE_ERROR
;
1807 Send command SDIO_SEND_OP_COND to the device to see whether it is SDIO device.
1809 Refer to SDIO Simplified Spec 3 Section 3.2 for details.
1811 @param[in] Slot The slot number of the SD card to send the command to.
1812 @param[in] VoltageWindow The supply voltage window.
1813 @param[in] S18r The boolean to show if it should switch to 1.8v.
1815 @retval EFI_SUCCESS The operation is done correctly.
1816 @retval Others The operation fails.
1821 IN SD_PEIM_HC_SLOT
*Slot
,
1822 IN UINT32 VoltageWindow
,
1826 SD_COMMAND_BLOCK SdCmdBlk
;
1827 SD_STATUS_BLOCK SdStatusBlk
;
1828 SD_COMMAND_PACKET Packet
;
1832 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
1833 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
1834 ZeroMem (&Packet
, sizeof (Packet
));
1836 Packet
.SdCmdBlk
= &SdCmdBlk
;
1837 Packet
.SdStatusBlk
= &SdStatusBlk
;
1838 Packet
.Timeout
= SD_TIMEOUT
;
1840 SdCmdBlk
.CommandIndex
= SDIO_SEND_OP_COND
;
1841 SdCmdBlk
.CommandType
= SdCommandTypeBcr
;
1842 SdCmdBlk
.ResponseType
= SdResponseTypeR4
;
1844 Switch
= S18r
? BIT24
: 0;
1846 SdCmdBlk
.CommandArgument
= (VoltageWindow
& 0xFFFFFF) | Switch
;
1848 Status
= SdPeimExecCmd (Slot
, &Packet
);
1854 Send command SD_SEND_OP_COND to the device to see whether it is SDIO device.
1856 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
1858 @param[in] Slot The slot number of the SD card to send the command to.
1859 @param[in] Rca The relative device address of addressed device.
1860 @param[in] VoltageWindow The supply voltage window.
1861 @param[in] S18r The boolean to show if it should switch to 1.8v.
1862 @param[in] Xpc The boolean to show if it should provide 0.36w power control.
1863 @param[in] Hcs The boolean to show if it support host capacity info.
1864 @param[out] Ocr The buffer to store returned OCR register value.
1867 @retval EFI_SUCCESS The operation is done correctly.
1868 @retval Others The operation fails.
1873 IN SD_PEIM_HC_SLOT
*Slot
,
1875 IN UINT32 VoltageWindow
,
1882 SD_COMMAND_BLOCK SdCmdBlk
;
1883 SD_STATUS_BLOCK SdStatusBlk
;
1884 SD_COMMAND_PACKET Packet
;
1888 UINT32 HostCapacity
;
1890 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
1891 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
1892 ZeroMem (&Packet
, sizeof (Packet
));
1894 Packet
.SdCmdBlk
= &SdCmdBlk
;
1895 Packet
.SdStatusBlk
= &SdStatusBlk
;
1896 Packet
.Timeout
= SD_TIMEOUT
;
1898 SdCmdBlk
.CommandIndex
= SD_APP_CMD
;
1899 SdCmdBlk
.CommandType
= SdCommandTypeAc
;
1900 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
1901 SdCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
1903 Status
= SdPeimExecCmd (Slot
, &Packet
);
1904 if (EFI_ERROR (Status
)) {
1908 SdCmdBlk
.CommandIndex
= SD_SEND_OP_COND
;
1909 SdCmdBlk
.CommandType
= SdCommandTypeBcr
;
1910 SdCmdBlk
.ResponseType
= SdResponseTypeR3
;
1912 Switch
= S18r
? BIT24
: 0;
1913 MaxPower
= Xpc
? BIT28
: 0;
1914 HostCapacity
= Hcs
? BIT30
: 0;
1915 SdCmdBlk
.CommandArgument
= (VoltageWindow
& 0xFFFFFF) | Switch
| MaxPower
| HostCapacity
;
1917 Status
= SdPeimExecCmd (Slot
, &Packet
);
1918 if (!EFI_ERROR (Status
)) {
1920 // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12.
1922 *Ocr
= SdStatusBlk
.Resp0
;
1929 Broadcast command ALL_SEND_CID to the bus to ask all the SD devices to send the
1930 data of their CID registers.
1932 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
1934 @param[in] Slot The slot number of the SD card to send the command to.
1936 @retval EFI_SUCCESS The operation is done correctly.
1937 @retval Others The operation fails.
1942 IN SD_PEIM_HC_SLOT
*Slot
1945 SD_COMMAND_BLOCK SdCmdBlk
;
1946 SD_STATUS_BLOCK SdStatusBlk
;
1947 SD_COMMAND_PACKET Packet
;
1950 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
1951 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
1952 ZeroMem (&Packet
, sizeof (Packet
));
1954 Packet
.SdCmdBlk
= &SdCmdBlk
;
1955 Packet
.SdStatusBlk
= &SdStatusBlk
;
1956 Packet
.Timeout
= SD_TIMEOUT
;
1958 SdCmdBlk
.CommandIndex
= SD_ALL_SEND_CID
;
1959 SdCmdBlk
.CommandType
= SdCommandTypeBcr
;
1960 SdCmdBlk
.ResponseType
= SdResponseTypeR2
;
1961 SdCmdBlk
.CommandArgument
= 0;
1963 Status
= SdPeimExecCmd (Slot
, &Packet
);
1969 Send command SET_RELATIVE_ADDR to the SD device to assign a Relative device
1972 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
1974 @param[in] Slot The slot number of the SD card to send the command to.
1975 @param[out] Rca The relative device address to be assigned.
1977 @retval EFI_SUCCESS The operation is done correctly.
1978 @retval Others The operation fails.
1983 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_SET_RELATIVE_ADDR
;
2001 SdCmdBlk
.CommandType
= SdCommandTypeBcr
;
2002 SdCmdBlk
.ResponseType
= SdResponseTypeR6
;
2004 Status
= SdPeimExecCmd (Slot
, &Packet
);
2005 if (!EFI_ERROR (Status
)) {
2006 *Rca
= (UINT16
)(SdStatusBlk
.Resp0
>> 16);
2013 Send command SEND_CSD to the SD device to get the data of the CSD register.
2015 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
2017 @param[in] Slot The slot number of the SD card to send the command to.
2018 @param[in] Rca The relative device address of selected device.
2019 @param[out] Csd The buffer to store the content of the CSD register.
2020 Note the caller should ignore the lowest byte of this
2021 buffer as the content of this byte is meaningless even
2022 if the operation succeeds.
2024 @retval EFI_SUCCESS The operation is done correctly.
2025 @retval Others The operation fails.
2030 IN SD_PEIM_HC_SLOT
*Slot
,
2035 SD_COMMAND_BLOCK SdCmdBlk
;
2036 SD_STATUS_BLOCK SdStatusBlk
;
2037 SD_COMMAND_PACKET Packet
;
2040 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
2041 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
2042 ZeroMem (&Packet
, sizeof (Packet
));
2044 Packet
.SdCmdBlk
= &SdCmdBlk
;
2045 Packet
.SdStatusBlk
= &SdStatusBlk
;
2046 Packet
.Timeout
= SD_TIMEOUT
;
2048 SdCmdBlk
.CommandIndex
= SD_SEND_CSD
;
2049 SdCmdBlk
.CommandType
= SdCommandTypeAc
;
2050 SdCmdBlk
.ResponseType
= SdResponseTypeR2
;
2051 SdCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
2053 Status
= SdPeimExecCmd (Slot
, &Packet
);
2054 if (!EFI_ERROR (Status
)) {
2056 // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12.
2058 CopyMem (((UINT8
*)Csd
) + 1, &SdStatusBlk
.Resp0
, sizeof (SD_CSD
) - 1);
2065 Send command SELECT_DESELECT_CARD to the SD device to select/deselect it.
2067 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
2069 @param[in] Slot The slot number of the SD card to send the command to.
2070 @param[in] Rca The relative device address of selected device.
2072 @retval EFI_SUCCESS The operation is done correctly.
2073 @retval Others The operation fails.
2078 IN SD_PEIM_HC_SLOT
*Slot
,
2082 SD_COMMAND_BLOCK SdCmdBlk
;
2083 SD_STATUS_BLOCK SdStatusBlk
;
2084 SD_COMMAND_PACKET Packet
;
2087 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
2088 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
2089 ZeroMem (&Packet
, sizeof (Packet
));
2091 Packet
.SdCmdBlk
= &SdCmdBlk
;
2092 Packet
.SdStatusBlk
= &SdStatusBlk
;
2093 Packet
.Timeout
= SD_TIMEOUT
;
2095 SdCmdBlk
.CommandIndex
= SD_SELECT_DESELECT_CARD
;
2096 SdCmdBlk
.CommandType
= SdCommandTypeAc
;
2097 SdCmdBlk
.ResponseType
= SdResponseTypeR1b
;
2098 SdCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
2100 Status
= SdPeimExecCmd (Slot
, &Packet
);
2106 Send command VOLTAGE_SWITCH to the SD device to switch the voltage of the device.
2108 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
2110 @param[in] Slot The slot number of the SD card to send the command to.
2112 @retval EFI_SUCCESS The operation is done correctly.
2113 @retval Others The operation fails.
2117 SdPeimVoltageSwitch (
2118 IN SD_PEIM_HC_SLOT
*Slot
2121 SD_COMMAND_BLOCK SdCmdBlk
;
2122 SD_STATUS_BLOCK SdStatusBlk
;
2123 SD_COMMAND_PACKET Packet
;
2126 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
2127 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
2128 ZeroMem (&Packet
, sizeof (Packet
));
2130 Packet
.SdCmdBlk
= &SdCmdBlk
;
2131 Packet
.SdStatusBlk
= &SdStatusBlk
;
2132 Packet
.Timeout
= SD_TIMEOUT
;
2134 SdCmdBlk
.CommandIndex
= SD_VOLTAGE_SWITCH
;
2135 SdCmdBlk
.CommandType
= SdCommandTypeAc
;
2136 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2137 SdCmdBlk
.CommandArgument
= 0;
2139 Status
= SdPeimExecCmd (Slot
, &Packet
);
2145 Send command SET_BUS_WIDTH to the SD device to set the bus width.
2147 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
2149 @param[in] Slot The slot number of the SD card to send the command to.
2150 @param[in] Rca The relative device address of addressed device.
2151 @param[in] BusWidth The bus width to be set, it could be 1 or 4.
2153 @retval EFI_SUCCESS The operation is done correctly.
2154 @retval Others The operation fails.
2159 IN SD_PEIM_HC_SLOT
*Slot
,
2164 SD_COMMAND_BLOCK SdCmdBlk
;
2165 SD_STATUS_BLOCK SdStatusBlk
;
2166 SD_COMMAND_PACKET Packet
;
2170 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
2171 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
2172 ZeroMem (&Packet
, sizeof (Packet
));
2174 Packet
.SdCmdBlk
= &SdCmdBlk
;
2175 Packet
.SdStatusBlk
= &SdStatusBlk
;
2176 Packet
.Timeout
= SD_TIMEOUT
;
2178 SdCmdBlk
.CommandIndex
= SD_APP_CMD
;
2179 SdCmdBlk
.CommandType
= SdCommandTypeAc
;
2180 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2181 SdCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
2183 Status
= SdPeimExecCmd (Slot
, &Packet
);
2184 if (EFI_ERROR (Status
)) {
2188 SdCmdBlk
.CommandIndex
= SD_SET_BUS_WIDTH
;
2189 SdCmdBlk
.CommandType
= SdCommandTypeAc
;
2190 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2192 if (BusWidth
== 1) {
2194 } else if (BusWidth
== 4) {
2197 return EFI_INVALID_PARAMETER
;
2199 SdCmdBlk
.CommandArgument
= Value
& 0x3;
2201 Status
= SdPeimExecCmd (Slot
, &Packet
);
2207 Send command SWITCH_FUNC to the SD device to check switchable function or switch card function.
2209 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
2211 @param[in] Slot The slot number of the SD card to send the command to.
2212 @param[in] AccessMode The value for access mode group.
2213 @param[in] CommandSystem The value for command set group.
2214 @param[in] DriveStrength The value for drive length group.
2215 @param[in] PowerLimit The value for power limit group.
2216 @param[in] Mode Switch or check function.
2217 @param[out] SwitchResp The return switch function status.
2219 @retval EFI_SUCCESS The operation is done correctly.
2220 @retval Others The operation fails.
2225 IN SD_PEIM_HC_SLOT
*Slot
,
2226 IN UINT8 AccessMode
,
2227 IN UINT8 CommandSystem
,
2228 IN UINT8 DriveStrength
,
2229 IN UINT8 PowerLimit
,
2231 OUT UINT8
*SwitchResp
2234 SD_COMMAND_BLOCK SdCmdBlk
;
2235 SD_STATUS_BLOCK SdStatusBlk
;
2236 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_SWITCH_FUNC
;
2249 SdCmdBlk
.CommandType
= SdCommandTypeAdtc
;
2250 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2252 ModeValue
= Mode
? BIT31
: 0;
2253 SdCmdBlk
.CommandArgument
= (AccessMode
& 0xF) | ((PowerLimit
& 0xF) << 4) | \
2254 ((DriveStrength
& 0xF) << 8) | ((DriveStrength
& 0xF) << 12) | \
2256 Packet
.InDataBuffer
= SwitchResp
;
2257 Packet
.InTransferLength
= 64;
2259 Status
= SdPeimExecCmd (Slot
, &Packet
);
2265 Send command SEND_STATUS to the addressed SD device to get its status register.
2267 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
2269 @param[in] Slot The slot number of the SD card to send the command to.
2270 @param[in] Rca The relative device address of addressed device.
2271 @param[out] DevStatus The returned device status.
2273 @retval EFI_SUCCESS The operation is done correctly.
2274 @retval Others The operation fails.
2279 IN SD_PEIM_HC_SLOT
*Slot
,
2281 OUT UINT32
*DevStatus
2284 SD_COMMAND_BLOCK SdCmdBlk
;
2285 SD_STATUS_BLOCK SdStatusBlk
;
2286 SD_COMMAND_PACKET Packet
;
2289 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
2290 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
2291 ZeroMem (&Packet
, sizeof (Packet
));
2293 Packet
.SdCmdBlk
= &SdCmdBlk
;
2294 Packet
.SdStatusBlk
= &SdStatusBlk
;
2295 Packet
.Timeout
= SD_TIMEOUT
;
2297 SdCmdBlk
.CommandIndex
= SD_SEND_STATUS
;
2298 SdCmdBlk
.CommandType
= SdCommandTypeAc
;
2299 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2300 SdCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
2302 Status
= SdPeimExecCmd (Slot
, &Packet
);
2303 if (!EFI_ERROR (Status
)) {
2304 *DevStatus
= SdStatusBlk
.Resp0
;
2311 Send command READ_SINGLE_BLOCK/WRITE_SINGLE_BLOCK to the addressed SD device
2312 to read/write the specified number of blocks.
2314 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
2316 @param[in] Slot The slot number of the SD card to send the command to.
2317 @param[in] Lba The logical block address of starting access.
2318 @param[in] BlockSize The block size of specified SD device partition.
2319 @param[in] Buffer The pointer to the transfer buffer.
2320 @param[in] BufferSize The size of transfer buffer.
2321 @param[in] IsRead Boolean to show the operation direction.
2323 @retval EFI_SUCCESS The operation is done correctly.
2324 @retval Others The operation fails.
2328 SdPeimRwSingleBlock (
2329 IN SD_PEIM_HC_SLOT
*Slot
,
2331 IN UINT32 BlockSize
,
2333 IN UINTN BufferSize
,
2337 SD_COMMAND_BLOCK SdCmdBlk
;
2338 SD_STATUS_BLOCK SdStatusBlk
;
2339 SD_COMMAND_PACKET Packet
;
2342 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
2343 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
2344 ZeroMem (&Packet
, sizeof (Packet
));
2346 Packet
.SdCmdBlk
= &SdCmdBlk
;
2347 Packet
.SdStatusBlk
= &SdStatusBlk
;
2349 // Calculate timeout value through the below formula.
2350 // Timeout = (transfer size) / (2MB/s).
2351 // Taking 2MB/s as divisor is because it's the lowest
2352 // transfer speed of class 2.
2354 Packet
.Timeout
= (BufferSize
/ (2 * 1024 * 1024) + 1) * 1000 * 1000;;
2357 Packet
.InDataBuffer
= Buffer
;
2358 Packet
.InTransferLength
= (UINT32
)BufferSize
;
2360 SdCmdBlk
.CommandIndex
= SD_READ_SINGLE_BLOCK
;
2361 SdCmdBlk
.CommandType
= SdCommandTypeAdtc
;
2362 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2364 Packet
.OutDataBuffer
= Buffer
;
2365 Packet
.OutTransferLength
= (UINT32
)BufferSize
;
2367 SdCmdBlk
.CommandIndex
= SD_WRITE_SINGLE_BLOCK
;
2368 SdCmdBlk
.CommandType
= SdCommandTypeAdtc
;
2369 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2372 if (Slot
->SectorAddressing
) {
2373 SdCmdBlk
.CommandArgument
= (UINT32
)Lba
;
2375 SdCmdBlk
.CommandArgument
= (UINT32
)MultU64x32 (Lba
, BlockSize
);
2378 Status
= SdPeimExecCmd (Slot
, &Packet
);
2384 Send command READ_MULTIPLE_BLOCK/WRITE_MULTIPLE_BLOCK to the addressed SD device
2385 to read/write the specified number of blocks.
2387 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
2389 @param[in] Slot The slot number of the SD card to send the command to.
2390 @param[in] Lba The logical block address of starting access.
2391 @param[in] BlockSize The block size of specified SD device partition.
2392 @param[in] Buffer The pointer to the transfer buffer.
2393 @param[in] BufferSize The size of transfer buffer.
2394 @param[in] IsRead Boolean to show the operation direction.
2396 @retval EFI_SUCCESS The operation is done correctly.
2397 @retval Others The operation fails.
2401 SdPeimRwMultiBlocks (
2402 IN SD_PEIM_HC_SLOT
*Slot
,
2404 IN UINT32 BlockSize
,
2406 IN UINTN BufferSize
,
2410 SD_COMMAND_BLOCK SdCmdBlk
;
2411 SD_STATUS_BLOCK SdStatusBlk
;
2412 SD_COMMAND_PACKET Packet
;
2415 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
2416 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
2417 ZeroMem (&Packet
, sizeof (Packet
));
2419 Packet
.SdCmdBlk
= &SdCmdBlk
;
2420 Packet
.SdStatusBlk
= &SdStatusBlk
;
2422 // Calculate timeout value through the below formula.
2423 // Timeout = (transfer size) / (2MB/s).
2424 // Taking 2MB/s as divisor is because it's the lowest
2425 // transfer speed of class 2.
2427 Packet
.Timeout
= (BufferSize
/ (2 * 1024 * 1024) + 1) * 1000 * 1000;;
2430 Packet
.InDataBuffer
= Buffer
;
2431 Packet
.InTransferLength
= (UINT32
)BufferSize
;
2433 SdCmdBlk
.CommandIndex
= SD_READ_MULTIPLE_BLOCK
;
2434 SdCmdBlk
.CommandType
= SdCommandTypeAdtc
;
2435 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2437 Packet
.OutDataBuffer
= Buffer
;
2438 Packet
.OutTransferLength
= (UINT32
)BufferSize
;
2440 SdCmdBlk
.CommandIndex
= SD_WRITE_MULTIPLE_BLOCK
;
2441 SdCmdBlk
.CommandType
= SdCommandTypeAdtc
;
2442 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2445 if (Slot
->SectorAddressing
) {
2446 SdCmdBlk
.CommandArgument
= (UINT32
)Lba
;
2448 SdCmdBlk
.CommandArgument
= (UINT32
)MultU64x32 (Lba
, BlockSize
);
2451 Status
= SdPeimExecCmd (Slot
, &Packet
);
2457 Send command SEND_TUNING_BLOCK to the SD device for SDR104/SDR50 optimal sampling point
2460 It may be sent up to 40 times until the host finishes the tuning procedure.
2462 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
2464 @param[in] Slot The slot number of the SD card to send the command to.
2466 @retval EFI_SUCCESS The operation is done correctly.
2467 @retval Others The operation fails.
2471 SdPeimSendTuningBlk (
2472 IN SD_PEIM_HC_SLOT
*Slot
2475 SD_COMMAND_BLOCK SdCmdBlk
;
2476 SD_STATUS_BLOCK SdStatusBlk
;
2477 SD_COMMAND_PACKET Packet
;
2479 UINT8 TuningBlock
[64];
2481 ZeroMem (&SdCmdBlk
, sizeof (SdCmdBlk
));
2482 ZeroMem (&SdStatusBlk
, sizeof (SdStatusBlk
));
2483 ZeroMem (&Packet
, sizeof (Packet
));
2485 Packet
.SdCmdBlk
= &SdCmdBlk
;
2486 Packet
.SdStatusBlk
= &SdStatusBlk
;
2487 Packet
.Timeout
= SD_TIMEOUT
;
2489 SdCmdBlk
.CommandIndex
= SD_SEND_TUNING_BLOCK
;
2490 SdCmdBlk
.CommandType
= SdCommandTypeAdtc
;
2491 SdCmdBlk
.ResponseType
= SdResponseTypeR1
;
2492 SdCmdBlk
.CommandArgument
= 0;
2494 Packet
.InDataBuffer
= TuningBlock
;
2495 Packet
.InTransferLength
= sizeof (TuningBlock
);
2497 Status
= SdPeimExecCmd (Slot
, &Packet
);
2503 Tunning the sampling point of SDR104 or SDR50 bus speed mode.
2505 Command SD_SEND_TUNING_BLOCK may be sent up to 40 times until the host finishes the
2508 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and SD Host Controller
2509 Simplified Spec 3.0 Figure 2-29 for details.
2511 @param[in] Slot The slot number of the SD card to send the command to.
2513 @retval EFI_SUCCESS The operation is done correctly.
2514 @retval Others The operation fails.
2519 IN SD_PEIM_HC_SLOT
*Slot
2527 // Notify the host that the sampling clock tuning procedure starts.
2530 Status
= SdPeimHcOrMmio (Slot
->SdHcBase
+ SD_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2531 if (EFI_ERROR (Status
)) {
2535 // Ask the device to send a sequence of tuning blocks till the tuning procedure is done.
2539 Status
= SdPeimSendTuningBlk (Slot
);
2540 if (EFI_ERROR (Status
)) {
2544 Status
= SdPeimHcRwMmio (Slot
->SdHcBase
+ SD_HC_HOST_CTRL2
, TRUE
, sizeof (HostCtrl2
), &HostCtrl2
);
2545 if (EFI_ERROR (Status
)) {
2549 if ((HostCtrl2
& (BIT6
| BIT7
)) == 0) {
2553 if ((HostCtrl2
& (BIT6
| BIT7
)) == BIT7
) {
2556 } while (++Retry
< 40);
2558 DEBUG ((EFI_D_ERROR
, "SdPeimTuningClock: Send tuning block fails at %d times with HostCtrl2 %02x\n", Retry
, HostCtrl2
));
2560 // Abort the tuning procedure and reset the tuning circuit.
2562 HostCtrl2
= (UINT8
)~(BIT6
| BIT7
);
2563 Status
= SdPeimHcAndMmio (Slot
->SdHcBase
+ SD_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2564 if (EFI_ERROR (Status
)) {
2567 return EFI_DEVICE_ERROR
;
2571 Switch the bus width to specified width.
2573 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and
2574 SD Host Controller Simplified Spec 3.0 section Figure 3-7 for details.
2576 @param[in] Slot The slot number of the SD card to send the command to.
2577 @param[in] Rca The relative device address to be assigned.
2578 @param[in] BusWidth The bus width to be set, it could be 4 or 8.
2580 @retval EFI_SUCCESS The operation is done correctly.
2581 @retval Others The operation fails.
2585 SdPeimSwitchBusWidth (
2586 IN SD_PEIM_HC_SLOT
*Slot
,
2594 Status
= SdPeimSetBusWidth (Slot
, Rca
, BusWidth
);
2595 if (EFI_ERROR (Status
)) {
2599 Status
= SdPeimSendStatus (Slot
, Rca
, &DevStatus
);
2600 if (EFI_ERROR (Status
)) {
2604 // Check the switch operation is really successful or not.
2606 if ((DevStatus
>> 16) != 0) {
2607 return EFI_DEVICE_ERROR
;
2610 Status
= SdPeimHcSetBusWidth (Slot
->SdHcBase
, BusWidth
);
2616 Switch the high speed timing according to request.
2618 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and
2619 SD Host Controller Simplified Spec 3.0 section Figure 2-29 for details.
2621 @param[in] Slot The slot number of the SD card to send the command to.
2622 @param[in] Rca The relative device address to be assigned.
2623 @param[in] S18a The boolean to show if it's a UHS-I SD card.
2625 @retval EFI_SUCCESS The operation is done correctly.
2626 @retval Others The operation fails.
2631 IN SD_PEIM_HC_SLOT
*Slot
,
2637 SD_HC_SLOT_CAP Capability
;
2643 UINT8 SwitchResp
[64];
2645 Status
= SdPeimGetCsd (Slot
, Rca
, &Slot
->Csd
);
2646 if (EFI_ERROR (Status
)) {
2647 DEBUG ((EFI_D_ERROR
, "SdPeimSetBusMode: SdPeimGetCsd fails with %r\n", Status
));
2651 Status
= SdPeimHcGetCapability (Slot
->SdHcBase
, &Capability
);
2652 if (EFI_ERROR (Status
)) {
2656 Status
= SdPeimSelect (Slot
, Rca
);
2657 if (EFI_ERROR (Status
)) {
2658 DEBUG ((EFI_D_ERROR
, "SdPeimSetBusMode: SdPeimSelect fails with %r\n", Status
));
2663 Status
= SdPeimSwitchBusWidth (Slot
, Rca
, BusWidth
);
2664 if (EFI_ERROR (Status
)) {
2665 DEBUG ((EFI_D_ERROR
, "SdPeimSetBusMode: SdPeimSwitchBusWidth fails with %r\n", Status
));
2670 // Get the supported bus speed from SWITCH cmd return data group #1.
2672 ZeroMem (SwitchResp
, sizeof (SwitchResp
));
2673 Status
= SdPeimSwitch (Slot
, 0xF, 0xF, 0xF, 0xF, FALSE
, SwitchResp
);
2674 if (EFI_ERROR (Status
)) {
2678 // Calculate supported bus speed/bus width/clock frequency by host and device capability.
2681 if (S18a
&& (Capability
.Sdr104
!= 0) && ((SwitchResp
[13] & BIT3
) != 0)) {
2684 } else if (S18a
&& (Capability
.Sdr50
!= 0) && ((SwitchResp
[13] & BIT2
) != 0)) {
2687 } else if (S18a
&& (Capability
.Ddr50
!= 0) && ((SwitchResp
[13] & BIT4
) != 0)) {
2690 } else if ((SwitchResp
[13] & BIT1
) != 0) {
2698 DEBUG ((EFI_D_INFO
, "SdPeimSetBusMode: AccessMode %d ClockFreq %d BusWidth %d\n", AccessMode
, ClockFreq
, BusWidth
));
2700 Status
= SdPeimSwitch (Slot
, AccessMode
, 0xF, 0xF, 0xF, TRUE
, SwitchResp
);
2701 if (EFI_ERROR (Status
)) {
2702 DEBUG ((EFI_D_ERROR
, "SdPeimSetBusMode: SdPeimSwitch fails with %r\n", Status
));
2706 if ((SwitchResp
[16] & 0xF) != AccessMode
) {
2707 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));
2708 return EFI_DEVICE_ERROR
;
2711 // Set to Hight Speed timing
2713 if (AccessMode
== 1) {
2715 Status
= SdPeimHcOrMmio (Slot
->SdHcBase
+ SD_HC_HOST_CTRL1
, sizeof (HostCtrl1
), &HostCtrl1
);
2716 if (EFI_ERROR (Status
)) {
2721 HostCtrl2
= (UINT8
)~0x7;
2722 Status
= SdPeimHcAndMmio (Slot
->SdHcBase
+ SD_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2723 if (EFI_ERROR (Status
)) {
2726 HostCtrl2
= AccessMode
;
2727 Status
= SdPeimHcOrMmio (Slot
->SdHcBase
+ SD_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2728 if (EFI_ERROR (Status
)) {
2732 Status
= SdPeimHcClockSupply (Slot
->SdHcBase
, ClockFreq
* 1000);
2733 if (EFI_ERROR (Status
)) {
2734 DEBUG ((EFI_D_ERROR
, "SdPeimSetBusMode: SdPeimHcClockSupply %r\n", Status
));
2738 if ((AccessMode
== 3) || ((AccessMode
== 2) && (Capability
.TuningSDR50
!= 0))) {
2739 Status
= SdPeimTuningClock (Slot
);
2740 if (EFI_ERROR (Status
)) {
2741 DEBUG ((EFI_D_ERROR
, "SdPeimSetBusMode: SdPeimTuningClock fails with %r\n", Status
));
2746 DEBUG ((EFI_D_INFO
, "SdPeimSetBusMode: SdPeimSetBusMode %r\n", Status
));
2752 Execute SD device identification procedure.
2754 Refer to SD Physical Layer Simplified Spec 4.1 Section 3.6 for details.
2756 @param[in] Slot The slot number of the SD card to send the command to.
2758 @retval EFI_SUCCESS There is a SD card.
2759 @retval Others There is not a SD card.
2763 SdPeimIdentification (
2764 IN SD_PEIM_HC_SLOT
*Slot
2774 UINT16 ControllerVer
;
2776 UINT32 PresentState
;
2778 SD_HC_SLOT_CAP Capability
;
2781 // 1. Send Cmd0 to the device
2783 Status
= SdPeimReset (Slot
);
2784 if (EFI_ERROR (Status
)) {
2785 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: Executing Cmd0 fails with %r\n", Status
));
2789 // 2. Send Cmd8 to the device
2791 Status
= SdPeimVoltageCheck (Slot
, 0x1, 0xFF);
2792 if (EFI_ERROR (Status
)) {
2793 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: Executing Cmd8 fails with %r\n", Status
));
2797 // 3. Send SDIO Cmd5 to the device to the SDIO device OCR register.
2799 Status
= SdioSendOpCond (Slot
, 0, FALSE
);
2800 if (!EFI_ERROR (Status
)) {
2801 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: Found SDIO device, ignore it as we don't support\n"));
2802 return EFI_DEVICE_ERROR
;
2805 // 4. Send Acmd41 with voltage window 0 to the device
2807 Status
= SdPeimSendOpCond (Slot
, 0, 0, FALSE
, FALSE
, FALSE
, &Ocr
);
2808 if (EFI_ERROR (Status
)) {
2809 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: Executing SdPeimSendOpCond fails with %r\n", Status
));
2810 return EFI_DEVICE_ERROR
;
2813 Status
= SdPeimHcGetCapability (Slot
->SdHcBase
, &Capability
);
2814 if (EFI_ERROR (Status
)) {
2818 Status
= SdPeimHcRwMmio (Slot
->SdHcBase
+ SD_HC_MAX_CURRENT_CAP
, TRUE
, sizeof (Current
), &Current
);
2819 if (EFI_ERROR (Status
)) {
2823 if (Capability
.Voltage33
!= 0) {
2827 MaxCurrent
= ((UINT32
)Current
& 0xFF) * 4;
2828 } else if (Capability
.Voltage30
!= 0) {
2832 MaxCurrent
= (((UINT32
)Current
>> 8) & 0xFF) * 4;
2833 } else if (Capability
.Voltage18
!= 0) {
2837 MaxCurrent
= (((UINT32
)Current
>> 16) & 0xFF) * 4;
2840 return EFI_DEVICE_ERROR
;
2843 if (MaxCurrent
>= 150) {
2849 Status
= SdPeimHcRwMmio (Slot
->SdHcBase
+ SD_HC_CTRL_VER
, TRUE
, sizeof (ControllerVer
), &ControllerVer
);
2850 if (EFI_ERROR (Status
)) {
2854 if ((ControllerVer
& 0xFF) == 2) {
2856 } else if (((ControllerVer
& 0xFF) == 0) || ((ControllerVer
& 0xFF) == 1)) {
2860 return EFI_UNSUPPORTED
;
2863 // 5. Repeatly send Acmd41 with supply voltage window to the device.
2864 // Note here we only support the cards complied with SD physical
2865 // layer simplified spec version 2.0 and version 3.0 and above.
2870 Status
= SdPeimSendOpCond (Slot
, 0, Ocr
, S18r
, Xpc
, TRUE
, &Ocr
);
2871 if (EFI_ERROR (Status
)) {
2872 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: SdPeimSendOpCond fails with %r Ocr %x, S18r %x, Xpc %x\n", Status
, Ocr
, S18r
, Xpc
));
2873 return EFI_DEVICE_ERROR
;
2876 if (Retry
++ == 100) {
2877 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: SdPeimSendOpCond fails too many times\n"));
2878 return EFI_DEVICE_ERROR
;
2880 MicroSecondDelay (10 * 1000);
2881 } while ((Ocr
& BIT31
) == 0);
2884 // 6. If the S18a bit is set and the Host Controller supports 1.8V signaling
2885 // (One of support bits is set to 1: SDR50, SDR104 or DDR50 in the
2886 // Capabilities register), switch its voltage to 1.8V.
2888 if ((Capability
.Sdr50
!= 0 ||
2889 Capability
.Sdr104
!= 0 ||
2890 Capability
.Ddr50
!= 0) &&
2891 ((Ocr
& BIT24
) != 0)) {
2892 Status
= SdPeimVoltageSwitch (Slot
);
2893 if (EFI_ERROR (Status
)) {
2894 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: Executing SdPeimVoltageSwitch fails with %r\n", Status
));
2895 Status
= EFI_DEVICE_ERROR
;
2898 Status
= SdPeimHcStopClock (Slot
->SdHcBase
);
2899 if (EFI_ERROR (Status
)) {
2900 Status
= EFI_DEVICE_ERROR
;
2904 SdPeimHcRwMmio (Slot
->SdHcBase
+ SD_HC_PRESENT_STATE
, TRUE
, sizeof (PresentState
), &PresentState
);
2905 if (((PresentState
>> 20) & 0xF) != 0) {
2906 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: SwitchVoltage fails with PresentState = 0x%x\n", PresentState
));
2907 Status
= EFI_DEVICE_ERROR
;
2911 SdPeimHcOrMmio (Slot
->SdHcBase
+ SD_HC_HOST_CTRL2
, sizeof (HostCtrl2
), &HostCtrl2
);
2913 MicroSecondDelay (5000);
2915 SdPeimHcRwMmio (Slot
->SdHcBase
+ SD_HC_HOST_CTRL2
, TRUE
, sizeof (HostCtrl2
), &HostCtrl2
);
2916 if ((HostCtrl2
& BIT3
) == 0) {
2917 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: SwitchVoltage fails with HostCtrl2 = 0x%x\n", HostCtrl2
));
2918 Status
= EFI_DEVICE_ERROR
;
2922 SdPeimHcInitClockFreq (Slot
->SdHcBase
);
2924 MicroSecondDelay (1000);
2926 SdPeimHcRwMmio (Slot
->SdHcBase
+ SD_HC_PRESENT_STATE
, TRUE
, sizeof (PresentState
), &PresentState
);
2927 if (((PresentState
>> 20) & 0xF) != 0xF) {
2928 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: SwitchVoltage fails with PresentState = 0x%x, It should be 0xF\n", PresentState
));
2929 Status
= EFI_DEVICE_ERROR
;
2933 DEBUG ((EFI_D_INFO
, "SdPeimIdentification: Switch to 1.8v signal voltage success\n"));
2936 Status
= SdPeimAllSendCid (Slot
);
2937 if (EFI_ERROR (Status
)) {
2938 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: Executing SdPeimAllSendCid fails with %r\n", Status
));
2942 Status
= SdPeimSetRca (Slot
, &Rca
);
2943 if (EFI_ERROR (Status
)) {
2944 DEBUG ((EFI_D_ERROR
, "SdPeimIdentification: Executing SdPeimSetRca fails with %r\n", Status
));
2948 // Enter Data Tranfer Mode.
2950 DEBUG ((EFI_D_INFO
, "Found a SD device at slot [%d]\n", Slot
));
2952 Status
= SdPeimSetBusMode (Slot
, Rca
, ((Ocr
& BIT24
) != 0));
2958 // Set SD Bus Power = 0
2960 PowerCtrl
= (UINT8
)~BIT0
;
2961 Status
= SdPeimHcAndMmio (Slot
->SdHcBase
+ SD_HC_POWER_CTRL
, sizeof (PowerCtrl
), &PowerCtrl
);
2962 return EFI_DEVICE_ERROR
;