\r
It would expose EFI_SD_MMC_PASS_THRU_PROTOCOL for upper layer use.\r
\r
- Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.\r
+ Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved.\r
Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
if (ControllerVer >= SD_MMC_HC_CTRL_VER_400) {\r
HostCtrl2 = SD_MMC_HC_V4_EN;\r
//\r
- // Check if V4 64bit support is available\r
+ // Check if controller version V4.0\r
//\r
- if (Capability.SysBus64V4 != 0) {\r
- HostCtrl2 |= SD_MMC_HC_64_ADDR_EN;\r
- DEBUG ((DEBUG_INFO, "Enabled V4 64 bit system bus support\n"));\r
+ if (ControllerVer == SD_MMC_HC_CTRL_VER_400) {\r
+ //\r
+ // Check if 64bit support is available\r
+ //\r
+ if (Capability.SysBus64V3 != 0) {\r
+ HostCtrl2 |= SD_MMC_HC_64_ADDR_EN;\r
+ DEBUG ((DEBUG_INFO, "Enabled V4 64 bit system bus support\n"));\r
+ }\r
}\r
//\r
// Check if controller version V4.10 or higher\r
//\r
- if (ControllerVer >= SD_MMC_HC_CTRL_VER_410) {\r
+ else if (ControllerVer >= SD_MMC_HC_CTRL_VER_410) {\r
+ //\r
+ // Check if 64bit support is available\r
+ //\r
+ if (Capability.SysBus64V4 != 0) {\r
+ HostCtrl2 |= SD_MMC_HC_64_ADDR_EN;\r
+ DEBUG ((DEBUG_INFO, "Enabled V4 64 bit system bus support\n"));\r
+ }\r
HostCtrl2 |= SD_MMC_HC_26_DATA_LEN_ADMA_EN;\r
DEBUG ((DEBUG_INFO, "Enabled V4 26 bit data length ADMA support\n"));\r
}\r
EFI_PCI_IO_PROTOCOL *PciIo;\r
EFI_STATUS Status;\r
UINTN Bytes;\r
- BOOLEAN AddressingMode64;\r
- BOOLEAN DataLength26;\r
UINT32 AdmaMaxDataPerLine;\r
UINT32 DescSize;\r
VOID *AdmaDesc;\r
\r
- AddressingMode64 = FALSE;\r
- DataLength26 = FALSE;\r
AdmaMaxDataPerLine = ADMA_MAX_DATA_PER_LINE_16B;\r
DescSize = sizeof (SD_MMC_HC_ADMA_32_DESC_LINE);\r
AdmaDesc = NULL;\r
DataLen = Trb->DataLen;\r
PciIo = Trb->Private->PciIo;\r
\r
- //\r
- // Detect whether 64bit addressing is supported.\r
- //\r
- if (ControllerVer >= SD_MMC_HC_CTRL_VER_400) {\r
- Status = SdMmcHcCheckMmioSet(PciIo, Trb->Slot, SD_MMC_HC_HOST_CTRL2, sizeof(UINT16),\r
- SD_MMC_HC_V4_EN|SD_MMC_HC_64_ADDR_EN, SD_MMC_HC_V4_EN|SD_MMC_HC_64_ADDR_EN);\r
- if (!EFI_ERROR (Status)) {\r
- AddressingMode64 = TRUE;\r
- DescSize = sizeof (SD_MMC_HC_ADMA_64_DESC_LINE);\r
- }\r
- }\r
//\r
// Check for valid ranges in 32bit ADMA Descriptor Table\r
//\r
- if (!AddressingMode64 &&\r
+ if ((Trb->Mode == SdMmcAdma32bMode) &&\r
((Data >= 0x100000000ul) || ((Data + DataLen) > 0x100000000ul))) {\r
return EFI_INVALID_PARAMETER;\r
}\r
//\r
// Check address field alignment\r
//\r
- if (AddressingMode64) {\r
+ if (Trb->Mode != SdMmcAdma32bMode) {\r
//\r
// Address field shall be set on 64-bit boundary (Lower 3-bit is always set to 0)\r
//\r
DEBUG ((DEBUG_INFO, "The buffer [0x%x] to construct ADMA desc is not aligned to 4 bytes boundary!\n", Data));\r
}\r
}\r
+\r
//\r
- // Detect whether 26bit data length is supported.\r
+ // Configure 64b ADMA.\r
//\r
- Status = SdMmcHcCheckMmioSet(PciIo, Trb->Slot, SD_MMC_HC_HOST_CTRL2, sizeof(UINT16),\r
- SD_MMC_HC_26_DATA_LEN_ADMA_EN, SD_MMC_HC_26_DATA_LEN_ADMA_EN);\r
- if (!EFI_ERROR (Status)) {\r
- DataLength26 = TRUE;\r
+ if (Trb->Mode == SdMmcAdma64bV3Mode) {\r
+ DescSize = sizeof (SD_MMC_HC_ADMA_64_V3_DESC_LINE);\r
+ }else if (Trb->Mode == SdMmcAdma64bV4Mode) {\r
+ DescSize = sizeof (SD_MMC_HC_ADMA_64_V4_DESC_LINE);\r
+ }\r
+ //\r
+ // Configure 26b data length.\r
+ //\r
+ if (Trb->AdmaLengthMode == SdMmcAdmaLen26b) {\r
AdmaMaxDataPerLine = ADMA_MAX_DATA_PER_LINE_26B;\r
}\r
\r
return EFI_OUT_OF_RESOURCES;\r
}\r
\r
- if ((!AddressingMode64) &&\r
+ if ((Trb->Mode == SdMmcAdma32bMode) &&\r
(UINT64)(UINTN)Trb->AdmaDescPhy > 0x100000000ul) {\r
//\r
// The ADMA doesn't support 64bit addressing.\r
\r
Remaining = DataLen;\r
Address = Data;\r
- if (!AddressingMode64) {\r
+ if (Trb->Mode == SdMmcAdma32bMode) {\r
Trb->Adma32Desc = AdmaDesc;\r
- Trb->Adma64Desc = NULL;\r
+ } else if (Trb->Mode == SdMmcAdma64bV3Mode) {\r
+ Trb->Adma64V3Desc = AdmaDesc;\r
} else {\r
- Trb->Adma64Desc = AdmaDesc;\r
- Trb->Adma32Desc = NULL;\r
+ Trb->Adma64V4Desc = AdmaDesc;\r
}\r
+\r
for (Index = 0; Index < Entries; Index++) {\r
- if (!AddressingMode64) {\r
+ if (Trb->Mode == SdMmcAdma32bMode) {\r
if (Remaining <= AdmaMaxDataPerLine) {\r
Trb->Adma32Desc[Index].Valid = 1;\r
Trb->Adma32Desc[Index].Act = 2;\r
- if (DataLength26) {\r
+ if (Trb->AdmaLengthMode == SdMmcAdmaLen26b) {\r
Trb->Adma32Desc[Index].UpperLength = (UINT16)RShiftU64 (Remaining, 16);\r
}\r
Trb->Adma32Desc[Index].LowerLength = (UINT16)(Remaining & MAX_UINT16);\r
} else {\r
Trb->Adma32Desc[Index].Valid = 1;\r
Trb->Adma32Desc[Index].Act = 2;\r
- if (DataLength26) {\r
+ if (Trb->AdmaLengthMode == SdMmcAdmaLen26b) {\r
Trb->Adma32Desc[Index].UpperLength = 0;\r
}\r
Trb->Adma32Desc[Index].LowerLength = 0;\r
Trb->Adma32Desc[Index].Address = (UINT32)Address;\r
}\r
+ } else if (Trb->Mode == SdMmcAdma64bV3Mode) {\r
+ if (Remaining <= AdmaMaxDataPerLine) {\r
+ Trb->Adma64V3Desc[Index].Valid = 1;\r
+ Trb->Adma64V3Desc[Index].Act = 2;\r
+ if (Trb->AdmaLengthMode == SdMmcAdmaLen26b) {\r
+ Trb->Adma64V3Desc[Index].UpperLength = (UINT16)RShiftU64 (Remaining, 16);\r
+ }\r
+ Trb->Adma64V3Desc[Index].LowerLength = (UINT16)(Remaining & MAX_UINT16);\r
+ Trb->Adma64V3Desc[Index].LowerAddress = (UINT32)Address;\r
+ Trb->Adma64V3Desc[Index].UpperAddress = (UINT32)RShiftU64 (Address, 32);\r
+ break;\r
+ } else {\r
+ Trb->Adma64V3Desc[Index].Valid = 1;\r
+ Trb->Adma64V3Desc[Index].Act = 2;\r
+ if (Trb->AdmaLengthMode == SdMmcAdmaLen26b) {\r
+ Trb->Adma64V3Desc[Index].UpperLength = 0;\r
+ }\r
+ Trb->Adma64V3Desc[Index].LowerLength = 0;\r
+ Trb->Adma64V3Desc[Index].LowerAddress = (UINT32)Address;\r
+ Trb->Adma64V3Desc[Index].UpperAddress = (UINT32)RShiftU64 (Address, 32);\r
+ }\r
} else {\r
if (Remaining <= AdmaMaxDataPerLine) {\r
- Trb->Adma64Desc[Index].Valid = 1;\r
- Trb->Adma64Desc[Index].Act = 2;\r
- if (DataLength26) {\r
- Trb->Adma64Desc[Index].UpperLength = (UINT16)RShiftU64 (Remaining, 16);\r
+ Trb->Adma64V4Desc[Index].Valid = 1;\r
+ Trb->Adma64V4Desc[Index].Act = 2;\r
+ if (Trb->AdmaLengthMode == SdMmcAdmaLen26b) {\r
+ Trb->Adma64V4Desc[Index].UpperLength = (UINT16)RShiftU64 (Remaining, 16);\r
}\r
- Trb->Adma64Desc[Index].LowerLength = (UINT16)(Remaining & MAX_UINT16);\r
- Trb->Adma64Desc[Index].LowerAddress = (UINT32)Address;\r
- Trb->Adma64Desc[Index].UpperAddress = (UINT32)RShiftU64 (Address, 32);\r
+ Trb->Adma64V4Desc[Index].LowerLength = (UINT16)(Remaining & MAX_UINT16);\r
+ Trb->Adma64V4Desc[Index].LowerAddress = (UINT32)Address;\r
+ Trb->Adma64V4Desc[Index].UpperAddress = (UINT32)RShiftU64 (Address, 32);\r
break;\r
} else {\r
- Trb->Adma64Desc[Index].Valid = 1;\r
- Trb->Adma64Desc[Index].Act = 2;\r
- if (DataLength26) {\r
- Trb->Adma64Desc[Index].UpperLength = 0;\r
+ Trb->Adma64V4Desc[Index].Valid = 1;\r
+ Trb->Adma64V4Desc[Index].Act = 2;\r
+ if (Trb->AdmaLengthMode == SdMmcAdmaLen26b) {\r
+ Trb->Adma64V4Desc[Index].UpperLength = 0;\r
}\r
- Trb->Adma64Desc[Index].LowerLength = 0;\r
- Trb->Adma64Desc[Index].LowerAddress = (UINT32)Address;\r
- Trb->Adma64Desc[Index].UpperAddress = (UINT32)RShiftU64 (Address, 32);\r
+ Trb->Adma64V4Desc[Index].LowerLength = 0;\r
+ Trb->Adma64V4Desc[Index].LowerAddress = (UINT32)Address;\r
+ Trb->Adma64V4Desc[Index].UpperAddress = (UINT32)RShiftU64 (Address, 32);\r
}\r
}\r
\r
//\r
// Set the last descriptor line as end of descriptor table\r
//\r
- AddressingMode64 ? (Trb->Adma64Desc[Index].End = 1) : (Trb->Adma32Desc[Index].End = 1);\r
+ if (Trb->Mode == SdMmcAdma32bMode) {\r
+ Trb->Adma32Desc[Index].End = 1;\r
+ } else if (Trb->Mode == SdMmcAdma64bV3Mode) {\r
+ Trb->Adma64V3Desc[Index].End = 1;\r
+ } else {\r
+ Trb->Adma64V4Desc[Index].End = 1;\r
+ }\r
return EFI_SUCCESS;\r
}\r
\r
if (Trb->DataLen == 0) {\r
Trb->Mode = SdMmcNoData;\r
} else if (Private->Capability[Slot].Adma2 != 0) {\r
- Trb->Mode = SdMmcAdmaMode;\r
+ Trb->Mode = SdMmcAdma32bMode;\r
+ Trb->AdmaLengthMode = SdMmcAdmaLen16b;\r
+ if ((Private->ControllerVersion[Slot] == SD_MMC_HC_CTRL_VER_300) &&\r
+ (Private->Capability[Slot].SysBus64V3 == 1)) {\r
+ Trb->Mode = SdMmcAdma64bV3Mode;\r
+ } else if (((Private->ControllerVersion[Slot] == SD_MMC_HC_CTRL_VER_400) &&\r
+ (Private->Capability[Slot].SysBus64V3 == 1)) ||\r
+ ((Private->ControllerVersion[Slot] >= SD_MMC_HC_CTRL_VER_410) &&\r
+ (Private->Capability[Slot].SysBus64V4 == 1))) {\r
+ Trb->Mode = SdMmcAdma64bV4Mode;\r
+ }\r
+ if (Private->ControllerVersion[Slot] >= SD_MMC_HC_CTRL_VER_410) {\r
+ Trb->AdmaLengthMode = SdMmcAdmaLen26b;\r
+ }\r
Status = BuildAdmaDescTable (Trb, Private->ControllerVersion[Slot]);\r
if (EFI_ERROR (Status)) {\r
PciIo->Unmap (PciIo, Trb->DataMap);\r
Trb->Adma32Desc\r
);\r
}\r
- if (Trb->Adma64Desc != NULL) {\r
+ if (Trb->Adma64V3Desc != NULL) {\r
+ PciIo->FreeBuffer (\r
+ PciIo,\r
+ Trb->AdmaPages,\r
+ Trb->Adma64V3Desc\r
+ );\r
+ }\r
+ if (Trb->Adma64V4Desc != NULL) {\r
PciIo->FreeBuffer (\r
PciIo,\r
Trb->AdmaPages,\r
- Trb->Adma64Desc\r
+ Trb->Adma64V4Desc\r
);\r
}\r
if (Trb->DataMap != NULL) {\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
+\r
+ if (Private->ControllerVersion[Trb->Slot] >= SD_MMC_HC_CTRL_VER_400) {\r
+ Status = SdMmcHcCheckMmioSet(PciIo, Trb->Slot, SD_MMC_HC_HOST_CTRL2, sizeof(UINT16),\r
+ SD_MMC_HC_64_ADDR_EN, SD_MMC_HC_64_ADDR_EN);\r
+ if (!EFI_ERROR (Status)) {\r
+ AddressingMode64 = TRUE;\r
+ }\r
+ }\r
+\r
//\r
// Set Host Control 1 register DMA Select field\r
//\r
- if (Trb->Mode == SdMmcAdmaMode) {\r
+ if ((Trb->Mode == SdMmcAdma32bMode) ||\r
+ (Trb->Mode == SdMmcAdma64bV4Mode)) {\r
HostCtrl1 = BIT4;\r
Status = SdMmcHcOrMmio (PciIo, Trb->Slot, SD_MMC_HC_HOST_CTRL1, sizeof (HostCtrl1), &HostCtrl1);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
+ } else if (Trb->Mode == SdMmcAdma64bV3Mode) {\r
+ HostCtrl1 = BIT4|BIT3;\r
+ Status = SdMmcHcOrMmio (PciIo, Trb->Slot, SD_MMC_HC_HOST_CTRL1, sizeof (HostCtrl1), &HostCtrl1);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
}\r
\r
SdMmcHcLedOnOff (PciIo, Trb->Slot, TRUE);\r
\r
- if (Private->ControllerVersion[Trb->Slot] >= SD_MMC_HC_CTRL_VER_400) {\r
- Status = SdMmcHcCheckMmioSet(PciIo, Trb->Slot, SD_MMC_HC_HOST_CTRL2, sizeof(UINT16),\r
- SD_MMC_HC_V4_EN|SD_MMC_HC_64_ADDR_EN, SD_MMC_HC_V4_EN|SD_MMC_HC_64_ADDR_EN);\r
- if (!EFI_ERROR (Status)) {\r
- AddressingMode64 = TRUE;\r
- }\r
- }\r
-\r
if (Trb->Mode == SdMmcSdmaMode) {\r
if ((!AddressingMode64) &&\r
((UINT64)(UINTN)Trb->DataPhy >= 0x100000000ul)) {\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
- } else if (Trb->Mode == SdMmcAdmaMode) {\r
+ } else if ((Trb->Mode == SdMmcAdma32bMode) ||\r
+ (Trb->Mode == SdMmcAdma64bV3Mode) ||\r
+ (Trb->Mode == SdMmcAdma64bV4Mode)) {\r
AdmaAddr = (UINT64)(UINTN)Trb->AdmaDescPhy;\r
Status = SdMmcHcRwMmio (PciIo, Trb->Slot, SD_MMC_HC_ADMA_SYS_ADDR, FALSE, sizeof (AdmaAddr), &AdmaAddr);\r
if (EFI_ERROR (Status)) {\r