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;
80 return EFI_INVALID_PARAMETER;
115 if (EFI_ERROR (Status)) {
120 Or = *(UINT8 *)OrData;
121 }
else if (Count == 2) {
122 Or = *(UINT16 *)OrData;
123 }
else if (Count == 4) {
124 Or = *(UINT32 *)OrData;
125 }
else if (Count == 8) {
126 Or = *(UINT64 *)OrData;
128 return EFI_INVALID_PARAMETER;
166 if (EFI_ERROR (Status)) {
171 And = *(UINT8 *)AndData;
172 }
else if (Count == 2) {
173 And = *(UINT16 *)AndData;
174 }
else if (Count == 4) {
175 And = *(UINT32 *)AndData;
176 }
else if (Count == 8) {
177 And = *(UINT64 *)AndData;
179 return EFI_INVALID_PARAMETER;
219 if (EFI_ERROR (Status)) {
225 if (Value == TestValue) {
229 return EFI_NOT_READY;
260 BOOLEAN InfiniteWait;
265 InfiniteWait =
FALSE;
268 while (InfiniteWait || (Timeout > 0)) {
275 if (Status != EFI_NOT_READY) {
310 if (EFI_ERROR (Status)) {
311 DEBUG ((DEBUG_ERROR,
"EmmcPeimHcReset: write full 1 fails: %r\n", Status));
316 Bar + EMMC_HC_SW_RST,
322 if (EFI_ERROR (Status)) {
323 DEBUG ((DEBUG_INFO,
"EmmcPeimHcReset: reset done with %r\n", Status));
358 if (EFI_ERROR (Status)) {
391 if (EFI_ERROR (Status)) {
395 CopyMem (Capability, &Cap,
sizeof (Cap));
426 if (EFI_ERROR (Status)) {
430 if ((Data & (BIT6 | BIT7)) != 0) {
436 if (EFI_ERROR (Status)) {
444 Status =
EmmcPeimHcRwMmio (Bar + EMMC_HC_PRESENT_STATE,
TRUE,
sizeof (PresentState), &PresentState);
445 if (EFI_ERROR (Status)) {
449 if ((PresentState & BIT16) != 0) {
482 Bar + EMMC_HC_PRESENT_STATE,
483 sizeof (PresentState),
488 if (EFI_ERROR (Status)) {
495 ClockCtrl = (UINT16) ~BIT2;
496 Status =
EmmcPeimHcAndMmio (Bar + EMMC_HC_CLOCK_CTRL,
sizeof (ClockCtrl), &ClockCtrl);
525 UINT16 ControllerVer;
532 if (EFI_ERROR (Status)) {
536 ASSERT (Capability.BaseClkFreq != 0);
538 BaseClkFreq = Capability.BaseClkFreq;
540 if (ClockFreq == 0) {
541 return EFI_INVALID_PARAMETER;
544 if (ClockFreq > (BaseClkFreq * 1000)) {
545 ClockFreq = BaseClkFreq * 1000;
552 SettingFreq = BaseClkFreq * 1000;
553 while (ClockFreq < SettingFreq) {
556 SettingFreq = (BaseClkFreq * 1000) / (2 * Divisor);
557 Remainder = (BaseClkFreq * 1000) % (2 * Divisor);
558 if ((ClockFreq == SettingFreq) && (Remainder == 0)) {
562 if ((ClockFreq == SettingFreq) && (Remainder != 0)) {
567 DEBUG ((DEBUG_INFO,
"BaseClkFreq %dMHz Divisor %d ClockFreq %dKhz\n", BaseClkFreq, Divisor, ClockFreq));
569 Status =
EmmcPeimHcRwMmio (Bar + EMMC_HC_CTRL_VER,
TRUE,
sizeof (ControllerVer), &ControllerVer);
570 if (EFI_ERROR (Status)) {
577 if ((ControllerVer & 0xFF) == 2) {
578 ASSERT (Divisor <= 0x3FF);
579 ClockCtrl = ((Divisor & 0xFF) << 8) | ((Divisor & 0x300) >> 2);
580 }
else if (((ControllerVer & 0xFF) == 0) || ((ControllerVer & 0xFF) == 1)) {
584 if (((Divisor - 1) & Divisor) != 0) {
588 ASSERT (Divisor <= 0x80);
589 ClockCtrl = (Divisor & 0xFF) << 8;
591 DEBUG ((DEBUG_ERROR,
"Unknown SD Host Controller Spec version [0x%x]!!!\n", ControllerVer));
592 return EFI_UNSUPPORTED;
599 if (EFI_ERROR (Status)) {
608 if (EFI_ERROR (Status)) {
609 DEBUG ((DEBUG_ERROR,
"Set SDCLK Frequency Select and Internal Clock Enable fields fails\n"));
617 Bar + EMMC_HC_CLOCK_CTRL,
623 if (EFI_ERROR (Status)) {
631 Status =
EmmcPeimHcOrMmio (Bar + EMMC_HC_CLOCK_CTRL,
sizeof (ClockCtrl), &ClockCtrl);
659 PowerCtrl &= (UINT8) ~BIT0;
661 if (EFI_ERROR (Status)) {
696 HostCtrl1 = (UINT8) ~(BIT5 | BIT1);
697 Status =
EmmcPeimHcAndMmio (Bar + EMMC_HC_HOST_CTRL1,
sizeof (HostCtrl1), &HostCtrl1);
698 }
else if (BusWidth == 4) {
700 if (EFI_ERROR (Status)) {
705 HostCtrl1 &= (UINT8) ~BIT5;
707 }
else if (BusWidth == 8) {
709 if (EFI_ERROR (Status)) {
713 HostCtrl1 &= (UINT8) ~BIT1;
718 return EFI_INVALID_PARAMETER;
746 if (EFI_ERROR (Status)) {
750 if (Capability.BaseClkFreq == 0) {
754 return EFI_UNSUPPORTED;
790 if (EFI_ERROR (Status)) {
797 if (Capability.Voltage33 != 0) {
802 }
else if (Capability.Voltage30 != 0) {
807 }
else if (Capability.Voltage18 != 0) {
813 Status =
EmmcPeimHcOrMmio (Bar + EMMC_HC_HOST_CTRL2,
sizeof (HostCtrl2), &HostCtrl2);
814 if (EFI_ERROR (Status)) {
821 return EFI_DEVICE_ERROR;
875 if (EFI_ERROR (Status)) {
880 if (EFI_ERROR (Status)) {
909 Status =
EmmcPeimHcOrMmio (Bar + EMMC_HC_HOST_CTRL1,
sizeof (HostCtrl1), &HostCtrl1);
911 HostCtrl1 = (UINT8) ~BIT0;
912 Status =
EmmcPeimHcAndMmio (Bar + EMMC_HC_HOST_CTRL1,
sizeof (HostCtrl1), &HostCtrl1);
942 DataLen = Trb->DataLen;
946 if ((Data >= 0x100000000ul) || ((Data + DataLen) > 0x100000000ul)) {
947 return EFI_INVALID_PARAMETER;
954 if ((Data & (BIT0 | BIT1)) != 0) {
955 DEBUG ((DEBUG_INFO,
"The buffer [0x%x] to construct ADMA desc is not aligned to 4 bytes boundary!\n", Data));
958 Entries =
DivU64x32 ((DataLen + ADMA_MAX_DATA_PER_LINE - 1), ADMA_MAX_DATA_PER_LINE);
962 if (Trb->AdmaDesc ==
NULL) {
963 return EFI_OUT_OF_RESOURCES;
967 Address = (UINT32)Data;
968 for (Index = 0; Index < Entries; Index++) {
969 if (Remaining <= ADMA_MAX_DATA_PER_LINE) {
970 Trb->AdmaDesc[Index].Valid = 1;
971 Trb->AdmaDesc[Index].Act = 2;
972 Trb->AdmaDesc[Index].Length = (UINT16)Remaining;
973 Trb->AdmaDesc[Index].Address = Address;
976 Trb->AdmaDesc[Index].Valid = 1;
977 Trb->AdmaDesc[Index].Act = 2;
978 Trb->AdmaDesc[Index].Length = 0;
979 Trb->AdmaDesc[Index].Address = Address;
982 Remaining -= ADMA_MAX_DATA_PER_LINE;
983 Address += ADMA_MAX_DATA_PER_LINE;
989 Trb->AdmaDesc[Index].End = 1;
1018 if (EFI_ERROR (Status)) {
1028 Trb->BlockSize = 0x200;
1029 Trb->Packet = Packet;
1030 Trb->Timeout = Packet->Timeout;
1032 if ((Packet->InTransferLength != 0) && (Packet->InDataBuffer !=
NULL)) {
1033 Trb->Data = Packet->InDataBuffer;
1034 Trb->DataLen = Packet->InTransferLength;
1036 }
else if ((Packet->OutTransferLength != 0) && (Packet->OutDataBuffer !=
NULL)) {
1037 Trb->Data = Packet->OutDataBuffer;
1038 Trb->DataLen = Packet->OutTransferLength;
1040 }
else if ((Packet->InTransferLength == 0) && (Packet->OutTransferLength == 0)) {
1047 if ((Trb->DataLen != 0) && (Trb->DataLen < Trb->BlockSize)) {
1048 Trb->BlockSize = (UINT16)Trb->DataLen;
1051 if (Packet->EmmcCmdBlk->CommandIndex == EMMC_SEND_TUNING_BLOCK) {
1052 Trb->Mode = EmmcPioMode;
1060 if (Trb->DataLen != 0) {
1061 MapLength = Trb->DataLen;
1062 Status =
IoMmuMap (MapOp, Trb->Data, &MapLength, &Trb->DataPhy, &Trb->DataMap);
1064 if (EFI_ERROR (Status) || (MapLength != Trb->DataLen)) {
1065 DEBUG ((DEBUG_ERROR,
"EmmcPeimCreateTrb: Fail to map data buffer.\n"));
1070 if (Trb->DataLen == 0) {
1071 Trb->Mode = EmmcNoData;
1072 }
else if (Capability.Adma2 != 0) {
1073 Trb->Mode = EmmcAdmaMode;
1075 if (EFI_ERROR (Status)) {
1078 }
else if (Capability.Sdma != 0) {
1079 Trb->Mode = EmmcSdmaMode;
1081 Trb->Mode = EmmcPioMode;
1103 if ((Trb !=
NULL) && (Trb->DataMap !=
NULL)) {
1107 if ((Trb !=
NULL) && (Trb->AdmaDesc !=
NULL)) {
1108 EmmcPeimFreeMem (Trb->Slot->Private->Pool, Trb->AdmaDesc, Trb->AdmaDescSize);
1137 UINT32 PresentState;
1139 Packet = Trb->Packet;
1141 if ((Packet->EmmcCmdBlk->CommandType == EmmcCommandTypeAdtc) ||
1142 (Packet->EmmcCmdBlk->ResponseType == EmmcResponceTypeR1b) ||
1143 (Packet->EmmcCmdBlk->ResponseType == EmmcResponceTypeR5b))
1149 PresentState = BIT0 | BIT1;
1155 PresentState = BIT0;
1159 Bar + EMMC_HC_PRESENT_STATE,
1160 sizeof (PresentState),
1188 BOOLEAN InfiniteWait;
1193 Packet = Trb->Packet;
1194 Timeout = Packet->Timeout;
1196 InfiniteWait =
TRUE;
1198 InfiniteWait =
FALSE;
1201 while (InfiniteWait || (Timeout > 0)) {
1206 if (Status != EFI_NOT_READY) {
1249 Packet = Trb->Packet;
1255 if (EFI_ERROR (Status)) {
1264 if (EFI_ERROR (Status)) {
1271 if (Trb->Mode == EmmcAdmaMode) {
1273 Status =
EmmcPeimHcOrMmio (Bar + EMMC_HC_HOST_CTRL1,
sizeof (HostCtrl1), &HostCtrl1);
1274 if (EFI_ERROR (Status)) {
1281 if (Trb->Mode == EmmcSdmaMode) {
1282 if ((UINT64)(
UINTN)Trb->DataPhy >= 0x100000000ul) {
1283 return EFI_INVALID_PARAMETER;
1286 SdmaAddr = (UINT32)(
UINTN)Trb->DataPhy;
1288 if (EFI_ERROR (Status)) {
1291 }
else if (Trb->Mode == EmmcAdmaMode) {
1292 AdmaAddr = (UINT64)(
UINTN)Trb->AdmaDesc;
1294 if (EFI_ERROR (Status)) {
1299 BlkSize = Trb->BlockSize;
1300 if (Trb->Mode == EmmcSdmaMode) {
1308 if (EFI_ERROR (Status)) {
1313 if (Trb->Mode != EmmcNoData) {
1317 BlkCount = (UINT16)(Trb->DataLen / Trb->BlockSize);
1321 if (EFI_ERROR (Status)) {
1325 Argument = Packet->EmmcCmdBlk->CommandArgument;
1327 if (EFI_ERROR (Status)) {
1332 if (Trb->Mode != EmmcNoData) {
1333 if (Trb->Mode != EmmcPioMode) {
1342 TransMode |= BIT5 | BIT1;
1347 if (EFI_ERROR (Status)) {
1351 Cmd = (UINT16)
LShiftU64 (Packet->EmmcCmdBlk->CommandIndex, 8);
1352 if (Packet->EmmcCmdBlk->CommandType == EmmcCommandTypeAdtc) {
1359 if (Packet->EmmcCmdBlk->CommandType != EmmcCommandTypeBc) {
1360 switch (Packet->EmmcCmdBlk->ResponseType) {
1361 case EmmcResponceTypeR1:
1362 case EmmcResponceTypeR5:
1363 case EmmcResponceTypeR6:
1364 case EmmcResponceTypeR7:
1365 Cmd |= (BIT1 | BIT3 | BIT4);
1367 case EmmcResponceTypeR2:
1368 Cmd |= (BIT0 | BIT3);
1370 case EmmcResponceTypeR3:
1371 case EmmcResponceTypeR4:
1374 case EmmcResponceTypeR1b:
1375 case EmmcResponceTypeR5b:
1376 Cmd |= (BIT0 | BIT1 | BIT3 | BIT4);
1418 Packet = Trb->Packet;
1423 Bar + EMMC_HC_NOR_INT_STS,
1428 if (EFI_ERROR (Status)) {
1435 if ((IntStatus & BIT1) == BIT1) {
1436 if ((IntStatus & BIT15) == BIT15) {
1444 Bar + EMMC_HC_ERR_INT_STS,
1449 if (!EFI_ERROR (Status)) {
1450 if ((IntStatus & BIT4) == BIT4) {
1453 Status = EFI_DEVICE_ERROR;
1466 if ((IntStatus & BIT15) == BIT15) {
1468 Bar + EMMC_HC_ERR_INT_STS,
1473 if (EFI_ERROR (Status)) {
1477 if ((IntStatus & 0x0F) != 0) {
1481 if ((IntStatus & 0xF0) != 0) {
1486 Bar + EMMC_HC_SW_RST,
1491 if (EFI_ERROR (Status)) {
1496 Bar + EMMC_HC_SW_RST,
1502 if (EFI_ERROR (Status)) {
1506 Status = EFI_DEVICE_ERROR;
1513 if ((Trb->Mode == EmmcSdmaMode) && ((IntStatus & BIT3) == BIT3)) {
1519 Bar + EMMC_HC_NOR_INT_STS,
1524 if (EFI_ERROR (Status)) {
1531 SdmaAddr = EMMC_SDMA_ROUND_UP ((UINT32)(
UINTN)Trb->DataPhy, EMMC_SDMA_BOUNDARY);
1533 Bar + EMMC_HC_SDMA_ADDR,
1538 if (EFI_ERROR (Status)) {
1542 Trb->DataPhy = (UINT32)(
UINTN)SdmaAddr;
1545 if ((Packet->EmmcCmdBlk->CommandType != EmmcCommandTypeAdtc) &&
1546 (Packet->EmmcCmdBlk->ResponseType != EmmcResponceTypeR1b) &&
1547 (Packet->EmmcCmdBlk->ResponseType != EmmcResponceTypeR5b))
1549 if ((IntStatus & BIT0) == BIT0) {
1555 if (Packet->EmmcCmdBlk->CommandIndex == EMMC_SEND_TUNING_BLOCK) {
1561 if ((IntStatus & BIT5) == BIT5) {
1570 for (PioLength = 0; PioLength < Trb->DataLen; PioLength += 4) {
1579 Status = EFI_NOT_READY;
1584 if (!EFI_ERROR (Status)) {
1585 if (Packet->EmmcCmdBlk->CommandType != EmmcCommandTypeBc) {
1586 for (Index = 0; Index < 4; Index++) {
1588 Bar + EMMC_HC_RESPONSE + Index * 4,
1593 if (EFI_ERROR (Status)) {
1599 CopyMem (Packet->EmmcStatusBlk, Response, sizeof (Response));
1603 if (Status != EFI_NOT_READY) {
1629 BOOLEAN InfiniteWait;
1631 Packet = Trb->Packet;
1635 Timeout = Packet->Timeout;
1637 InfiniteWait =
TRUE;
1639 InfiniteWait =
FALSE;
1642 while (InfiniteWait || (Timeout > 0)) {
1647 if (Status != EFI_NOT_READY) {
1702 if (Packet ==
NULL) {
1703 return EFI_INVALID_PARAMETER;
1706 if ((Packet->EmmcCmdBlk ==
NULL) || (Packet->EmmcStatusBlk ==
NULL)) {
1707 return EFI_INVALID_PARAMETER;
1710 if ((Packet->OutDataBuffer ==
NULL) && (Packet->OutTransferLength != 0)) {
1711 return EFI_INVALID_PARAMETER;
1714 if ((Packet->InDataBuffer ==
NULL) && (Packet->InTransferLength != 0)) {
1715 return EFI_INVALID_PARAMETER;
1720 return EFI_OUT_OF_RESOURCES;
1724 if (EFI_ERROR (Status)) {
1729 if (EFI_ERROR (Status)) {
1734 if (EFI_ERROR (Status)) {
1766 ZeroMem (&EmmcCmdBlk,
sizeof (EmmcCmdBlk));
1767 ZeroMem (&EmmcStatusBlk,
sizeof (EmmcStatusBlk));
1768 ZeroMem (&Packet,
sizeof (Packet));
1770 Packet.EmmcCmdBlk = &EmmcCmdBlk;
1771 Packet.EmmcStatusBlk = &EmmcStatusBlk;
1772 Packet.Timeout = EMMC_TIMEOUT;
1774 EmmcCmdBlk.CommandIndex = EMMC_GO_IDLE_STATE;
1775 EmmcCmdBlk.CommandType = EmmcCommandTypeBc;
1776 EmmcCmdBlk.ResponseType = 0;
1777 EmmcCmdBlk.CommandArgument = 0;
1800 IN OUT UINT32 *Argument
1808 ZeroMem (&EmmcCmdBlk,
sizeof (EmmcCmdBlk));
1809 ZeroMem (&EmmcStatusBlk,
sizeof (EmmcStatusBlk));
1810 ZeroMem (&Packet,
sizeof (Packet));
1812 Packet.EmmcCmdBlk = &EmmcCmdBlk;
1813 Packet.EmmcStatusBlk = &EmmcStatusBlk;
1814 Packet.Timeout = EMMC_TIMEOUT;
1816 EmmcCmdBlk.CommandIndex = EMMC_SEND_OP_COND;
1817 EmmcCmdBlk.CommandType = EmmcCommandTypeBcr;
1818 EmmcCmdBlk.ResponseType = EmmcResponceTypeR3;
1819 EmmcCmdBlk.CommandArgument = *Argument;
1822 if (!EFI_ERROR (Status)) {
1826 *Argument = EmmcStatusBlk.Resp0;
1854 ZeroMem (&EmmcCmdBlk,
sizeof (EmmcCmdBlk));
1855 ZeroMem (&EmmcStatusBlk,
sizeof (EmmcStatusBlk));
1856 ZeroMem (&Packet,
sizeof (Packet));
1858 Packet.EmmcCmdBlk = &EmmcCmdBlk;
1859 Packet.EmmcStatusBlk = &EmmcStatusBlk;
1860 Packet.Timeout = EMMC_TIMEOUT;
1862 EmmcCmdBlk.CommandIndex = EMMC_ALL_SEND_CID;
1863 EmmcCmdBlk.CommandType = EmmcCommandTypeBcr;
1864 EmmcCmdBlk.ResponseType = EmmcResponceTypeR2;
1865 EmmcCmdBlk.CommandArgument = 0;
1896 ZeroMem (&EmmcCmdBlk,
sizeof (EmmcCmdBlk));
1897 ZeroMem (&EmmcStatusBlk,
sizeof (EmmcStatusBlk));
1898 ZeroMem (&Packet,
sizeof (Packet));
1900 Packet.EmmcCmdBlk = &EmmcCmdBlk;
1901 Packet.EmmcStatusBlk = &EmmcStatusBlk;
1902 Packet.Timeout = EMMC_TIMEOUT;
1904 EmmcCmdBlk.CommandIndex = EMMC_SET_RELATIVE_ADDR;
1905 EmmcCmdBlk.CommandType = EmmcCommandTypeAc;
1906 EmmcCmdBlk.ResponseType = EmmcResponceTypeR1;
1907 EmmcCmdBlk.CommandArgument = Rca << 16;
1942 ZeroMem (&EmmcCmdBlk,
sizeof (EmmcCmdBlk));
1943 ZeroMem (&EmmcStatusBlk,
sizeof (EmmcStatusBlk));
1944 ZeroMem (&Packet,
sizeof (Packet));
1946 Packet.EmmcCmdBlk = &EmmcCmdBlk;
1947 Packet.EmmcStatusBlk = &EmmcStatusBlk;
1948 Packet.Timeout = EMMC_TIMEOUT;
1950 EmmcCmdBlk.CommandIndex = EMMC_SEND_CSD;
1951 EmmcCmdBlk.CommandType = EmmcCommandTypeAc;
1952 EmmcCmdBlk.ResponseType = EmmcResponceTypeR2;
1953 EmmcCmdBlk.CommandArgument = Rca << 16;
1956 if (!EFI_ERROR (Status)) {
1960 CopyMem (((UINT8 *)Csd) + 1, &EmmcStatusBlk.Resp0, sizeof (
EMMC_CSD) - 1);
1989 ZeroMem (&EmmcCmdBlk,
sizeof (EmmcCmdBlk));
1990 ZeroMem (&EmmcStatusBlk,
sizeof (EmmcStatusBlk));
1991 ZeroMem (&Packet,
sizeof (Packet));
1993 Packet.EmmcCmdBlk = &EmmcCmdBlk;
1994 Packet.EmmcStatusBlk = &EmmcStatusBlk;
1995 Packet.Timeout = EMMC_TIMEOUT;
1997 EmmcCmdBlk.CommandIndex = EMMC_SELECT_DESELECT_CARD;
1998 EmmcCmdBlk.CommandType = EmmcCommandTypeAc;
1999 EmmcCmdBlk.ResponseType = EmmcResponceTypeR1;
2000 EmmcCmdBlk.CommandArgument = Rca << 16;
2030 ZeroMem (&EmmcCmdBlk,
sizeof (EmmcCmdBlk));
2031 ZeroMem (&EmmcStatusBlk,
sizeof (EmmcStatusBlk));
2032 ZeroMem (&Packet,
sizeof (Packet));
2034 Packet.EmmcCmdBlk = &EmmcCmdBlk;
2035 Packet.EmmcStatusBlk = &EmmcStatusBlk;
2036 Packet.Timeout = EMMC_TIMEOUT;
2038 EmmcCmdBlk.CommandIndex = EMMC_SEND_EXT_CSD;
2039 EmmcCmdBlk.CommandType = EmmcCommandTypeAdtc;
2040 EmmcCmdBlk.ResponseType = EmmcResponceTypeR1;
2041 EmmcCmdBlk.CommandArgument = 0x00000000;
2043 Packet.InDataBuffer = ExtCsd;
2080 ZeroMem (&EmmcCmdBlk,
sizeof (EmmcCmdBlk));
2081 ZeroMem (&EmmcStatusBlk,
sizeof (EmmcStatusBlk));
2082 ZeroMem (&Packet,
sizeof (Packet));
2084 Packet.EmmcCmdBlk = &EmmcCmdBlk;
2085 Packet.EmmcStatusBlk = &EmmcStatusBlk;
2086 Packet.Timeout = EMMC_TIMEOUT;
2088 EmmcCmdBlk.CommandIndex = EMMC_SWITCH;
2089 EmmcCmdBlk.CommandType = EmmcCommandTypeAc;
2090 EmmcCmdBlk.ResponseType = EmmcResponceTypeR1b;
2091 EmmcCmdBlk.CommandArgument = (Access << 24) | (Index << 16) | (Value << 8) | CmdSet;
2115 OUT UINT32 *DevStatus
2123 ZeroMem (&EmmcCmdBlk,
sizeof (EmmcCmdBlk));
2124 ZeroMem (&EmmcStatusBlk,
sizeof (EmmcStatusBlk));
2125 ZeroMem (&Packet,
sizeof (Packet));
2127 Packet.EmmcCmdBlk = &EmmcCmdBlk;
2128 Packet.EmmcStatusBlk = &EmmcStatusBlk;
2129 Packet.Timeout = EMMC_TIMEOUT;
2131 EmmcCmdBlk.CommandIndex = EMMC_SEND_STATUS;
2132 EmmcCmdBlk.CommandType = EmmcCommandTypeAc;
2133 EmmcCmdBlk.ResponseType = EmmcResponceTypeR1;
2134 EmmcCmdBlk.CommandArgument = Rca << 16;
2137 if (!EFI_ERROR (Status)) {
2138 *DevStatus = EmmcStatusBlk.Resp0;
2160 IN UINT16 BlockCount
2168 ZeroMem (&EmmcCmdBlk,
sizeof (EmmcCmdBlk));
2169 ZeroMem (&EmmcStatusBlk,
sizeof (EmmcStatusBlk));
2170 ZeroMem (&Packet,
sizeof (Packet));
2172 Packet.EmmcCmdBlk = &EmmcCmdBlk;
2173 Packet.EmmcStatusBlk = &EmmcStatusBlk;
2174 Packet.Timeout = EMMC_TIMEOUT;
2176 EmmcCmdBlk.CommandIndex = EMMC_SET_BLOCK_COUNT;
2177 EmmcCmdBlk.CommandType = EmmcCommandTypeAc;
2178 EmmcCmdBlk.ResponseType = EmmcResponceTypeR1;
2179 EmmcCmdBlk.CommandArgument = BlockCount;
2207 IN UINT32 BlockSize,
2218 ZeroMem (&EmmcCmdBlk,
sizeof (EmmcCmdBlk));
2219 ZeroMem (&EmmcStatusBlk,
sizeof (EmmcStatusBlk));
2220 ZeroMem (&Packet,
sizeof (Packet));
2222 Packet.EmmcCmdBlk = &EmmcCmdBlk;
2223 Packet.EmmcStatusBlk = &EmmcStatusBlk;
2231 Packet.Timeout = (BufferSize / (2 * 1024 * 1024) + 1) * 1000 * 1000;
2234 Packet.InDataBuffer = Buffer;
2235 Packet.InTransferLength = (UINT32)BufferSize;
2237 EmmcCmdBlk.CommandIndex = EMMC_READ_MULTIPLE_BLOCK;
2238 EmmcCmdBlk.CommandType = EmmcCommandTypeAdtc;
2239 EmmcCmdBlk.ResponseType = EmmcResponceTypeR1;
2241 Packet.OutDataBuffer = Buffer;
2242 Packet.OutTransferLength = (UINT32)BufferSize;
2244 EmmcCmdBlk.CommandIndex = EMMC_WRITE_MULTIPLE_BLOCK;
2245 EmmcCmdBlk.CommandType = EmmcCommandTypeAdtc;
2246 EmmcCmdBlk.ResponseType = EmmcResponceTypeR1;
2249 if (Slot->SectorAddressing) {
2250 EmmcCmdBlk.CommandArgument = (UINT32)Lba;
2252 EmmcCmdBlk.CommandArgument = (UINT32)
MultU64x32 (Lba, BlockSize);
2285 UINT8 TuningBlock[128];
2287 ZeroMem (&EmmcCmdBlk,
sizeof (EmmcCmdBlk));
2288 ZeroMem (&EmmcStatusBlk,
sizeof (EmmcStatusBlk));
2289 ZeroMem (&Packet,
sizeof (Packet));
2291 Packet.EmmcCmdBlk = &EmmcCmdBlk;
2292 Packet.EmmcStatusBlk = &EmmcStatusBlk;
2293 Packet.Timeout = EMMC_TIMEOUT;
2295 EmmcCmdBlk.CommandIndex = EMMC_SEND_TUNING_BLOCK;
2296 EmmcCmdBlk.CommandType = EmmcCommandTypeAdtc;
2297 EmmcCmdBlk.ResponseType = EmmcResponceTypeR1;
2298 EmmcCmdBlk.CommandArgument = 0;
2300 Packet.InDataBuffer = TuningBlock;
2301 if (BusWidth == 8) {
2302 Packet.InTransferLength =
sizeof (TuningBlock);
2304 Packet.InTransferLength = 64;
2342 Status =
EmmcPeimHcOrMmio (Slot->EmmcHcBase + EMMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
2343 if (EFI_ERROR (Status)) {
2353 if (EFI_ERROR (Status)) {
2357 Status =
EmmcPeimHcRwMmio (Slot->EmmcHcBase + EMMC_HC_HOST_CTRL2,
TRUE, sizeof (HostCtrl2), &HostCtrl2);
2358 if (EFI_ERROR (Status)) {
2362 if ((HostCtrl2 & (BIT6 | BIT7)) == 0) {
2366 if ((HostCtrl2 & (BIT6 | BIT7)) == BIT7) {
2369 }
while (++Retry < 40);
2371 DEBUG ((DEBUG_ERROR,
"EmmcPeimTuningClkForHs200: Send tuning block fails at %d times with HostCtrl2 %02x\n", Retry, HostCtrl2));
2375 HostCtrl2 = (UINT8) ~(BIT6 | BIT7);
2376 Status =
EmmcPeimHcAndMmio (Slot->EmmcHcBase + EMMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
2377 if (EFI_ERROR (Status)) {
2381 return EFI_DEVICE_ERROR;
2420 if (BusWidth == 4) {
2422 }
else if (BusWidth == 8) {
2425 return EFI_INVALID_PARAMETER;
2434 if (EFI_ERROR (Status)) {
2439 if (EFI_ERROR (Status)) {
2446 if ((DevStatus & BIT7) != 0) {
2447 return EFI_DEVICE_ERROR;
2494 if (EFI_ERROR (Status)) {
2499 if (EFI_ERROR (Status)) {
2506 if ((DevStatus & BIT7) != 0) {
2507 return EFI_DEVICE_ERROR;
2539 IN UINT32 ClockFreq,
2550 if (EFI_ERROR (Status)) {
2558 Status =
EmmcPeimHcOrMmio (Slot->EmmcHcBase + EMMC_HC_HOST_CTRL1, sizeof (HostCtrl1), &HostCtrl1);
2559 if (EFI_ERROR (Status)) {
2563 HostCtrl2 = (UINT8) ~0x7;
2564 Status =
EmmcPeimHcAndMmio (Slot->EmmcHcBase + EMMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
2565 if (EFI_ERROR (Status)) {
2571 }
else if (ClockFreq == 52) {
2577 Status =
EmmcPeimHcOrMmio (Slot->EmmcHcBase + EMMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
2578 if (EFI_ERROR (Status)) {
2607 IN UINT32 ClockFreq,
2616 if ((BusWidth != 4) && (BusWidth != 8)) {
2617 return EFI_INVALID_PARAMETER;
2621 if (EFI_ERROR (Status)) {
2632 if (EFI_ERROR (Status)) {
2636 HostCtrl2 = (UINT8) ~0x7;
2637 Status =
EmmcPeimHcAndMmio (Slot->EmmcHcBase + EMMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
2638 if (EFI_ERROR (Status)) {
2642 HostCtrl2 = BIT0 | BIT1;
2643 Status =
EmmcPeimHcOrMmio (Slot->EmmcHcBase + EMMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
2644 if (EFI_ERROR (Status)) {
2652 Slot->EmmcHcBase + EMMC_HC_CLOCK_CTRL,
2658 if (EFI_ERROR (Status)) {
2666 Status =
EmmcPeimHcOrMmio (Slot->EmmcHcBase + EMMC_HC_CLOCK_CTRL, sizeof (ClockCtrl), &ClockCtrl);
2670 if (EFI_ERROR (Status)) {
2705 if (EFI_ERROR (Status)) {
2714 if (EFI_ERROR (Status)) {
2722 if (EFI_ERROR (Status)) {
2729 HostCtrl2 = (UINT8) ~0x7;
2730 Status =
EmmcPeimHcAndMmio (Slot->EmmcHcBase + EMMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
2731 if (EFI_ERROR (Status)) {
2735 HostCtrl2 = BIT0 | BIT2;
2736 Status =
EmmcPeimHcOrMmio (Slot->EmmcHcBase + EMMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
2737 if (EFI_ERROR (Status)) {
2774 if (EFI_ERROR (Status)) {
2775 DEBUG ((DEBUG_ERROR,
"EmmcPeimSetBusMode: EmmcPeimGetCsd fails with %r\n", Status));
2779 if ((Slot->Csd.CSizeLow | Slot->Csd.CSizeHigh << 2) == 0xFFF) {
2780 Slot->SectorAddressing =
TRUE;
2782 Slot->SectorAddressing =
FALSE;
2786 if (EFI_ERROR (Status)) {
2787 DEBUG ((DEBUG_ERROR,
"EmmcPeimSetBusMode: EmmcPeimSelect fails with %r\n", Status));
2792 if (EFI_ERROR (Status)) {
2793 DEBUG ((DEBUG_ERROR,
"EmmcPeimSetBusMode: EmmcPeimHcGetCapability fails with %r\n", Status));
2797 ASSERT (Capability.BaseClkFreq != 0);
2801 if (Capability.BusWidth8 != 0) {
2811 if (EFI_ERROR (Status)) {
2812 DEBUG ((DEBUG_ERROR,
"EmmcPeimSetBusMode: EmmcPeimGetExtCsd fails with %r\n", Status));
2822 if (((Slot->ExtCsd.DeviceType & (BIT4 | BIT5)) != 0) && (Capability.Sdr104 != 0)) {
2826 }
else if (((Slot->ExtCsd.DeviceType & (BIT2 | BIT3)) != 0) && (Capability.Ddr50 != 0)) {
2830 }
else if (((Slot->ExtCsd.DeviceType & BIT1) != 0) && (Capability.HighSpeed != 0)) {
2834 }
else if (((Slot->ExtCsd.DeviceType & BIT0) != 0) && (Capability.HighSpeed != 0)) {
2843 if (((Slot->ExtCsd.DeviceType & (BIT6 | BIT7)) != 0) && (Capability.Hs400 != 0)) {
2847 ASSERT (BusWidth == 8);
2853 if ((ClockFreq == 0) || (HsTiming == 0)) {
2860 DEBUG ((DEBUG_INFO,
"HsTiming %d ClockFreq %d BusWidth %d Ddr %a\n", HsTiming, ClockFreq, BusWidth, IsDdr ?
"TRUE" :
"FALSE"));
2862 if (HsTiming == 3) {
2867 }
else if (HsTiming == 2) {
2904 if (EFI_ERROR (Status)) {
2905 DEBUG ((DEBUG_ERROR,
"EmmcPeimIdentification: EmmcPeimReset fails with %r\n", Status));
2913 if (EFI_ERROR (Status)) {
2914 DEBUG ((DEBUG_ERROR,
"EmmcPeimIdentification: EmmcPeimGetOcr fails with %r\n", Status));
2918 if (Retry++ == 100) {
2919 DEBUG ((DEBUG_ERROR,
"EmmcPeimIdentification: EmmcPeimGetOcr fails too many times\n"));
2920 return EFI_DEVICE_ERROR;
2924 }
while ((Ocr & BIT31) == 0);
2927 if (EFI_ERROR (Status)) {
2928 DEBUG ((DEBUG_ERROR,
"EmmcPeimIdentification: EmmcPeimGetAllCid fails with %r\n", Status));
2938 if (EFI_ERROR (Status)) {
2939 DEBUG ((DEBUG_ERROR,
"EmmcPeimIdentification: EmmcPeimSetRca fails with %r\n", Status));
2946 DEBUG ((DEBUG_INFO,
"Found a EMMC device at slot [%d], RCA [%d]\n", Slot, Rca));
EFI_STATUS IoMmuUnmap(IN VOID *Mapping)
EFI_STATUS IoMmuMap(IN EDKII_IOMMU_OPERATION Operation, IN VOID *HostAddress, IN OUT UINTN *NumberOfBytes, OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, OUT VOID **Mapping)
UINTN EFIAPI MicroSecondDelay(IN UINTN MicroSeconds)
UINT64 EFIAPI DivU64x32(IN UINT64 Dividend, IN UINT32 Divisor)
UINT64 EFIAPI MultU64x32(IN UINT64 Multiplicand, IN UINT32 Multiplier)
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
INTN EFIAPI HighBitSet32(IN UINT32 Operand)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID EmmcPeimFreeMem(IN EMMC_PEIM_MEM_POOL *Pool, IN VOID *Mem, IN UINTN Size)
VOID * EmmcPeimAllocateMem(IN EMMC_PEIM_MEM_POOL *Pool, IN UINTN Size)
EFI_STATUS EmmcPeimHcEnableInterrupt(IN UINTN Bar)
EFI_STATUS EmmcPeimHcSetBusWidth(IN UINTN Bar, IN UINT16 BusWidth)
VOID EmmcPeimFreeTrb(IN EMMC_TRB *Trb)
EFI_STATUS EmmcPeimSendTuningBlk(IN EMMC_PEIM_HC_SLOT *Slot, IN UINT8 BusWidth)
EFI_STATUS EmmcPeimSelect(IN EMMC_PEIM_HC_SLOT *Slot, IN UINT32 Rca)
EFI_STATUS EmmcPeimHcInitHost(IN UINTN Bar)
EFI_STATUS EmmcPeimHcClockSupply(IN UINTN Bar, IN UINT64 ClockFreq)
EFI_STATUS EmmcPeimGetAllCid(IN EMMC_PEIM_HC_SLOT *Slot)
EFI_STATUS EmmcPeimGetExtCsd(IN EMMC_PEIM_HC_SLOT *Slot, OUT EMMC_EXT_CSD *ExtCsd)
EMMC_TRB * EmmcPeimCreateTrb(IN EMMC_PEIM_HC_SLOT *Slot, IN EMMC_COMMAND_PACKET *Packet)
EFI_STATUS EmmcPeimSetBlkCount(IN EMMC_PEIM_HC_SLOT *Slot, IN UINT16 BlockCount)
EFI_STATUS EmmcPeimExecTrb(IN UINTN Bar, IN EMMC_TRB *Trb)
EFI_STATUS EmmcPeimHcInitTimeoutCtrl(IN UINTN Bar)
EFI_STATUS EFIAPI EmmcPeimExecCmd(IN EMMC_PEIM_HC_SLOT *Slot, IN OUT EMMC_COMMAND_PACKET *Packet)
EFI_STATUS EFIAPI EmmcPeimHcOrMmio(IN UINTN Address, IN UINT8 Count, IN VOID *OrData)
EFI_STATUS BuildAdmaDescTable(IN EMMC_TRB *Trb)
EFI_STATUS EmmcPeimHcGetCapability(IN UINTN Bar, OUT EMMC_HC_SLOT_CAP *Capability)
EFI_STATUS EmmcPeimGetOcr(IN EMMC_PEIM_HC_SLOT *Slot, IN OUT UINT32 *Argument)
EFI_STATUS EmmcPeimSwitchClockFreq(IN EMMC_PEIM_HC_SLOT *Slot, IN UINT32 Rca, IN UINT8 HsTiming, IN UINT32 ClockFreq)
EFI_STATUS EFIAPI EmmcPeimHcRwMmio(IN UINTN Address, IN BOOLEAN Read, IN UINT8 Count, IN OUT VOID *Data)
EFI_STATUS EmmcPeimSwitchBusWidth(IN EMMC_PEIM_HC_SLOT *Slot, IN UINT32 Rca, IN BOOLEAN IsDdr, IN UINT8 BusWidth)
EFI_STATUS EmmcPeimTuningClkForHs200(IN EMMC_PEIM_HC_SLOT *Slot, IN UINT8 BusWidth)
EFI_STATUS EmmcPeimCheckTrbResult(IN UINTN Bar, IN EMMC_TRB *Trb)
EFI_STATUS EmmcPeimSendStatus(IN EMMC_PEIM_HC_SLOT *Slot, IN UINT32 Rca, OUT UINT32 *DevStatus)
EFI_STATUS EmmcPeimHcInitClockFreq(IN UINTN Bar)
EFI_STATUS EmmcPeimSwitch(IN EMMC_PEIM_HC_SLOT *Slot, IN UINT8 Access, IN UINT8 Index, IN UINT8 Value, IN UINT8 CmdSet)
EFI_STATUS EmmcPeimSwitchToHS200(IN EMMC_PEIM_HC_SLOT *Slot, IN UINT32 Rca, IN UINT32 ClockFreq, IN UINT8 BusWidth)
EFI_STATUS EmmcPeimCheckTrbEnv(IN UINTN Bar, IN EMMC_TRB *Trb)
EFI_STATUS EmmcPeimWaitTrbResult(IN UINTN Bar, IN EMMC_TRB *Trb)
EFI_STATUS EmmcPeimReset(IN EMMC_PEIM_HC_SLOT *Slot)
EFI_STATUS EmmcPeimHcReset(IN UINTN Bar)
EFI_STATUS EFIAPI EmmcPeimHcCheckMmioSet(IN UINTN Address, IN UINT8 Count, IN UINT64 MaskValue, IN UINT64 TestValue)
EFI_STATUS EmmcPeimSetRca(IN EMMC_PEIM_HC_SLOT *Slot, IN UINT32 Rca)
EFI_STATUS EmmcPeimHcCardDetect(IN UINTN Bar)
EFI_STATUS EmmcPeimWaitTrbEnv(IN UINTN Bar, IN EMMC_TRB *Trb)
EFI_STATUS EmmcPeimSwitchToHighSpeed(IN EMMC_PEIM_HC_SLOT *Slot, IN UINT32 Rca, IN UINT32 ClockFreq, IN BOOLEAN IsDdr, IN UINT8 BusWidth)
EFI_STATUS EmmcPeimRwMultiBlocks(IN EMMC_PEIM_HC_SLOT *Slot, IN EFI_LBA Lba, IN UINT32 BlockSize, IN VOID *Buffer, IN UINTN BufferSize, IN BOOLEAN IsRead)
EFI_STATUS EFIAPI EmmcPeimHcAndMmio(IN UINTN Address, IN UINT8 Count, IN VOID *AndData)
EFI_STATUS EmmcPeimHcStopClock(IN UINTN Bar)
EFI_STATUS EmmcPeimSetBusMode(IN EMMC_PEIM_HC_SLOT *Slot, IN UINT32 Rca)
EFI_STATUS EmmcPeimGetCsd(IN EMMC_PEIM_HC_SLOT *Slot, IN UINT32 Rca, OUT EMMC_CSD *Csd)
EFI_STATUS EmmcPeimHcLedOnOff(IN UINTN Bar, IN BOOLEAN On)
EFI_STATUS EmmcPeimIdentification(IN EMMC_PEIM_HC_SLOT *Slot)
EFI_STATUS EmmcPeimHcInitPowerVoltage(IN UINTN Bar)
EFI_STATUS EFIAPI EmmcPeimHcWaitMmioSet(IN UINTN Address, IN UINT8 Count, IN UINT64 MaskValue, IN UINT64 TestValue, IN UINT64 Timeout)
EFI_STATUS EmmcPeimHcPowerControl(IN UINTN Bar, IN UINT8 PowerCtrl)
EFI_STATUS EmmcPeimSwitchToHS400(IN EMMC_PEIM_HC_SLOT *Slot, IN UINT32 Rca, IN UINT32 ClockFreq)
UINT64 EFIAPI MmioWrite64(IN UINTN Address, IN UINT64 Value)
UINT64 EFIAPI MmioRead64(IN UINTN Address)
UINT16 EFIAPI MmioRead16(IN UINTN Address)
UINT8 EFIAPI MmioRead8(IN UINTN Address)
UINT8 EFIAPI MmioWrite8(IN UINTN Address, IN UINT8 Value)
UINT32 EFIAPI MmioRead32(IN UINTN Address)
UINT16 EFIAPI MmioWrite16(IN UINTN Address, IN UINT16 Value)
UINT32 EFIAPI MmioWrite32(IN UINTN Address, IN UINT32 Value)
#define OFFSET_OF(TYPE, Field)
#define DEBUG(Expression)
@ EdkiiIoMmuOperationBusMasterWrite
@ EdkiiIoMmuOperationBusMasterRead
UINT64 EFI_PHYSICAL_ADDRESS