Hello, Please refer to the inline comments below:
> -----Original Message----- > From: edk2-devel [mailto:[email protected]] On Behalf Of > Ashish Singhal > Sent: Friday, November 30, 2018 3:15 AM > To: [email protected] > Cc: Ashish Singhal > Subject: [edk2] [PATCH v6 2/2] MdeModulePkg/SdMmcPciHcDxe: Add > SDMMC HC v4 and above Support. > > Add SDMA, ADMA2 and 26b data length support. > > If V4 64 bit address mode is enabled in compatibility register, > program controller to enable V4 host mode and use appropriate > SDMA registers supporting 64 bit addresses. > > If V4 64 bit address mode is enabled in compatibility register, > program controller to enable V4 host mode and use appropriate > ADMA descriptors supporting 64 bit addresses. > > If host controller version is above V4.0, enable ADMA2 with 26b data > length support for better performance. HC 2 register is configured to > use 26 bit data lengths and ADMA2 descriptors are configured appropriately. > > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1359 > > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Ashish Singhal <[email protected]> > --- > MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.h | 4 +- > MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c | 328 > ++++++++++++++++++--- > MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.h | 48 ++- > 3 files changed, 322 insertions(+), 58 deletions(-) > > diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.h > b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.h > index 8c1a589..3af7c95 100644 > --- a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.h > +++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.h > @@ -2,6 +2,7 @@ > > Provides some data structure definitions used by the SD/MMC host > controller driver. > > +Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. > Copyright (c) 2015, Intel Corporation. All rights reserved.<BR> > This program and the accompanying materials > are licensed and made available under the terms and conditions of the BSD > License > @@ -150,7 +151,8 @@ typedef struct { > BOOLEAN Started; > UINT64 Timeout; > > - SD_MMC_HC_ADMA_DESC_LINE *AdmaDesc; > + SD_MMC_HC_ADMA_32_DESC_LINE *Adma32Desc; > + SD_MMC_HC_ADMA_64_DESC_LINE *Adma64Desc; > EFI_PHYSICAL_ADDRESS AdmaDescPhy; > VOID *AdmaMap; > UINT32 AdmaPages; > diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c > b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c > index 598b6a3..debc3be 100644 > --- a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c > +++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c > @@ -4,6 +4,7 @@ > > It would expose EFI_SD_MMC_PASS_THRU_PROTOCOL for upper layer use. > > + Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. > Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR> > This program and the accompanying materials > are licensed and made available under the terms and conditions of the > BSD License > @@ -418,6 +419,36 @@ SdMmcHcWaitMmioSet ( > } > > /** > + Get the controller version information from the specified slot. > + > + @param[in] PciIo The PCI IO protocol instance. > + @param[in] Slot The slot number of the SD card to send the > command to. > + @param[out] Version The buffer to store the version information. > + > + @retval EFI_SUCCESS The operation executes successfully. > + @retval Others The operation fails. > + > +**/ > +EFI_STATUS > +SdMmcHcGetControllerVersion ( > + IN EFI_PCI_IO_PROTOCOL *PciIo, > + IN UINT8 Slot, > + OUT UINT16 *Version > + ) > +{ > + EFI_STATUS Status; > + > + Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_CTRL_VER, TRUE, > sizeof (UINT16), Version); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + *Version &= 0xFF; > + > + return EFI_SUCCESS; > +} > + > +/** > Software reset the specified SD/MMC host controller and enable all > interrupts. > > @param[in] Private A pointer to the SD_MMC_HC_PRIVATE_DATA > instance. > @@ -776,18 +807,19 @@ SdMmcHcClockSupply ( > > DEBUG ((DEBUG_INFO, "BaseClkFreq %dMHz Divisor %d > ClockFreq %dKhz\n", BaseClkFreq, Divisor, ClockFreq)); > > - Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_CTRL_VER, TRUE, > sizeof (ControllerVer), &ControllerVer); > + Status = SdMmcHcGetControllerVersion (PciIo, Slot, &ControllerVer); > if (EFI_ERROR (Status)) { > return Status; > } > // > // Set SDCLK Frequency Select and Internal Clock Enable fields in Clock > Control register. > // > - if (((ControllerVer & 0xFF) >= SD_MMC_HC_CTRL_VER_300) && > - ((ControllerVer & 0xFF) <= SD_MMC_HC_CTRL_VER_420)) { > + if ((ControllerVer >= SD_MMC_HC_CTRL_VER_300) && > + (ControllerVer <= SD_MMC_HC_CTRL_VER_420)) { > ASSERT (Divisor <= 0x3FF); > ClockCtrl = ((Divisor & 0xFF) << 8) | ((Divisor & 0x300) >> 2); > - } else if (((ControllerVer & 0xFF) == 0) || ((ControllerVer & 0xFF) == 1)) > { > + } else if ((ControllerVer == SD_MMC_HC_CTRL_VER_100) || > + (ControllerVer == SD_MMC_HC_CTRL_VER_200)) { > // > // Only the most significant bit can be used as divisor. > // > @@ -935,6 +967,60 @@ SdMmcHcSetBusWidth ( > } > > /** > + Configure V4 controller enhancements at initialization. > + > + @param[in] PciIo The PCI IO protocol instance. > + @param[in] Slot The slot number of the SD card to send the > command to. > + @param[in] Capability The capability of the slot. > + > + @retval EFI_SUCCESS The clock is supplied successfully. > + > +**/ > +EFI_STATUS > +SdMmcHcInitV4Enhancements ( > + IN EFI_PCI_IO_PROTOCOL *PciIo, > + IN UINT8 Slot, > + IN SD_MMC_HC_SLOT_CAP Capability > + ) > +{ > + EFI_STATUS Status; > + UINT16 ControllerVer; > + UINT16 HostCtrl2; > + > + // > + // Check if controller version V4 or higher > + // > + Status = SdMmcHcGetControllerVersion (PciIo, Slot, &ControllerVer); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + if (ControllerVer >= SD_MMC_HC_CTRL_VER_400) { > + HostCtrl2 = SD_MMC_HC_V4_EN; > + // > + // Check if V4 64bit support is available > + // > + if (Capability.SysBus64V4 != 0) { > + HostCtrl2 |= SD_MMC_HC_64_ADDR_EN; > + DEBUG ((DEBUG_INFO, "Enabled V4 64 bit system bus support\n")); > + } > + // > + // Check if controller version V4.10 or higher > + // > + if (ControllerVer >= SD_MMC_HC_CTRL_VER_410) { > + HostCtrl2 |= SD_MMC_HC_26_DATA_LEN_ADMA_EN; > + DEBUG ((DEBUG_INFO, "Enabled V4 26 bit data length ADMA > support\n")); > + } > + Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof > (HostCtrl2), &HostCtrl2); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + } > + > + return EFI_SUCCESS; > +} > + > +/** > Supply SD/MMC card with lowest clock frequency at initialization. > > @param[in] PciIo The PCI IO protocol instance. > @@ -1105,6 +1191,11 @@ SdMmcHcInitHost ( > PciIo = Private->PciIo; > Capability = Private->Capability[Slot]; > > + Status = SdMmcHcInitV4Enhancements (PciIo, Slot, Capability); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > Status = SdMmcHcInitClockFreq (PciIo, Slot, Private->BaseClkFreq[Slot]); > if (EFI_ERROR (Status)) { > return Status; > @@ -1263,7 +1354,7 @@ SdMmcHcLedOnOff ( > /** > Build ADMA descriptor table for transfer. > > - Refer to SD Host Controller Simplified spec 3.0 Section 1.13 for details. > + Refer to SD Host Controller Simplified spec 4.2 Section 1.13 for details. > > @param[in] Trb The pointer to the SD_MMC_HC_TRB instance. > > @@ -1281,49 +1372,98 @@ BuildAdmaDescTable ( > UINT64 Entries; > UINT32 Index; > UINT64 Remaining; > - UINT32 Address; > + UINT64 Address; > UINTN TableSize; > EFI_PCI_IO_PROTOCOL *PciIo; > EFI_STATUS Status; > UINTN Bytes; > + UINT16 ControllerVer; > + BOOLEAN AddressingMode64; > + BOOLEAN DataLength26; > + UINT32 AdmaMaxDataPerLine; > + UINT32 DescSize; > + VOID *AdmaDesc; > + > + AddressingMode64 = FALSE; > + DataLength26 = FALSE; > + AdmaMaxDataPerLine = ADMA_MAX_DATA_PER_LINE_16B; > + DescSize = sizeof (SD_MMC_HC_ADMA_32_DESC_LINE); > + AdmaDesc = NULL; > > Data = Trb->DataPhy; > DataLen = Trb->DataLen; > PciIo = Trb->Private->PciIo; > + > + // > + // Detect whether 64bit addressing is supported. > + // > + Status = SdMmcHcGetControllerVersion (PciIo, Trb->Slot, &ControllerVer); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + if (ControllerVer >= SD_MMC_HC_CTRL_VER_400) { > + Status = SdMmcHcCheckMmioSet(PciIo, Trb->Slot, > SD_MMC_HC_HOST_CTRL2, 0x2, > + SD_MMC_HC_V4_EN|SD_MMC_HC_64_ADDR_EN, > SD_MMC_HC_V4_EN|SD_MMC_HC_64_ADDR_EN); > + if (!EFI_ERROR (Status)) { > + AddressingMode64 = TRUE; > + DescSize = sizeof (SD_MMC_HC_ADMA_64_DESC_LINE); > + } > + } > // > - // Only support 32bit ADMA Descriptor Table > + // Check for valid ranges in 32bit ADMA Descriptor Table > // > - if ((Data >= 0x100000000ul) || ((Data + DataLen) > 0x100000000ul)) { > + if (!AddressingMode64 && > + ((Data >= 0x100000000ul) || ((Data + DataLen) > 0x100000000ul))) { > return EFI_INVALID_PARAMETER; > } > // > - // Address field shall be set on 32-bit boundary (Lower 2-bit is always set > to 0) > - // for 32-bit address descriptor table. > + // Check address field alignment > + // > + if (AddressingMode64) { > + // > + // Address field shall be set on 32-bit boundary (Lower 2-bit is always > set > to 0) Please update the comments here. The boundary is 64-bit with lower 3-bit cleared. > + // > + if ((Data & (BIT0 | BIT1 | BIT2)) != 0) { > + DEBUG ((DEBUG_INFO, "The buffer [0x%x] to construct ADMA desc is not > aligned to 8 bytes boundary!\n", Data)); > + } > + } else { > + // > + // Address field shall be set on 32-bit boundary (Lower 2-bit is always > set > to 0) > + // > + if ((Data & (BIT0 | BIT1)) != 0) { > + DEBUG ((DEBUG_INFO, "The buffer [0x%x] to construct ADMA desc is not > aligned to 4 bytes boundary!\n", Data)); > + } > + } > + // > + // Detect whether 26bit data length is supported. > // > - if ((Data & (BIT0 | BIT1)) != 0) { > - DEBUG ((DEBUG_INFO, "The buffer [0x%x] to construct ADMA desc is not > aligned to 4 bytes boundary!\n", Data)); > + Status = SdMmcHcCheckMmioSet(PciIo, Trb->Slot, > SD_MMC_HC_HOST_CTRL2, 0x2, > + SD_MMC_HC_26_DATA_LEN_ADMA_EN, > SD_MMC_HC_26_DATA_LEN_ADMA_EN); > + if (!EFI_ERROR (Status)) { > + DataLength26 = TRUE; > + AdmaMaxDataPerLine = ADMA_MAX_DATA_PER_LINE_26B; > } > > - Entries = DivU64x32 ((DataLen + ADMA_MAX_DATA_PER_LINE - 1), > ADMA_MAX_DATA_PER_LINE); > - TableSize = (UINTN)MultU64x32 (Entries, sizeof > (SD_MMC_HC_ADMA_DESC_LINE)); > + Entries = DivU64x32 ((DataLen + AdmaMaxDataPerLine - 1), > AdmaMaxDataPerLine); > + TableSize = (UINTN)MultU64x32 (Entries, DescSize); > Trb->AdmaPages = (UINT32)EFI_SIZE_TO_PAGES (TableSize); > Status = PciIo->AllocateBuffer ( > PciIo, > AllocateAnyPages, > EfiBootServicesData, > EFI_SIZE_TO_PAGES (TableSize), > - (VOID **)&Trb->AdmaDesc, > + (VOID **)&AdmaDesc, > 0 > ); > if (EFI_ERROR (Status)) { > return EFI_OUT_OF_RESOURCES; > } > - ZeroMem (Trb->AdmaDesc, TableSize); > + ZeroMem (AdmaDesc, TableSize); > Bytes = TableSize; > Status = PciIo->Map ( > PciIo, > EfiPciIoOperationBusMasterCommonBuffer, > - Trb->AdmaDesc, > + AdmaDesc, > &Bytes, > &Trb->AdmaDescPhy, > &Trb->AdmaMap > @@ -1336,12 +1476,13 @@ BuildAdmaDescTable ( > PciIo->FreeBuffer ( > PciIo, > EFI_SIZE_TO_PAGES (TableSize), > - Trb->AdmaDesc > + AdmaDesc > ); > return EFI_OUT_OF_RESOURCES; > } > > - if ((UINT64)(UINTN)Trb->AdmaDescPhy > 0x100000000ul) { > + if ((!AddressingMode64) && > + (UINT64)(UINTN)Trb->AdmaDescPhy > 0x100000000ul) { > // > // The ADMA doesn't support 64bit addressing. > // > @@ -1352,35 +1493,71 @@ BuildAdmaDescTable ( > PciIo->FreeBuffer ( > PciIo, > EFI_SIZE_TO_PAGES (TableSize), > - Trb->AdmaDesc > + AdmaDesc > ); > return EFI_DEVICE_ERROR; > } > > Remaining = DataLen; > - Address = (UINT32)Data; > + Address = Data; > + if (!AddressingMode64) { > + Trb->Adma32Desc = AdmaDesc; > + Trb->Adma64Desc = NULL; > + } else { > + Trb->Adma64Desc = AdmaDesc; > + Trb->Adma32Desc = NULL; > + } > for (Index = 0; Index < Entries; Index++) { > - if (Remaining <= ADMA_MAX_DATA_PER_LINE) { > - Trb->AdmaDesc[Index].Valid = 1; > - Trb->AdmaDesc[Index].Act = 2; > - Trb->AdmaDesc[Index].Length = (UINT16)Remaining; > - Trb->AdmaDesc[Index].Address = Address; > - break; > + if (!AddressingMode64) { > + if (Remaining < AdmaMaxDataPerLine) { For the file access issue on SD/eMMC devices, found that it is related with the above change. Please update it to: if (Remaining <= AdmaMaxDataPerLine) { Otherwise, when the length of the last chunk of transfer equals to 'AdmaMaxDataPerLine', the proposed change will not break out of the 'for' loop. This will lead to a value underflow of the variable 'Remaining', which will further cause the file access failure. > + Trb->Adma32Desc[Index].Valid = 1; > + Trb->Adma32Desc[Index].Act = 2; > + if (DataLength26 == TRUE) { Please update the above line to: if (DataLength26) { There are some similar cases below, please help to update them as well. > + Trb->Adma32Desc[Index].UpperLength = (UINT32)(Remaining >> 16); > + } > + Trb->Adma32Desc[Index].LowerLength = (UINT32)(Remaining & > MAX_UINT16); The above 2 statements seem not consistent with their counterparts under the 'else' part. Please help to refine one of them, thanks. > + Trb->Adma32Desc[Index].Address = (UINT32)Address; > + break; > + } else { > + Trb->Adma32Desc[Index].Valid = 1; > + Trb->Adma32Desc[Index].Act = 2; > + if (DataLength26 == TRUE) { > + Trb->Adma32Desc[Index].UpperLength = 0; > + } > + Trb->Adma32Desc[Index].LowerLength = 0; > + Trb->Adma32Desc[Index].Address = (UINT32)Address; > + } > } else { > - Trb->AdmaDesc[Index].Valid = 1; > - Trb->AdmaDesc[Index].Act = 2; > - Trb->AdmaDesc[Index].Length = 0; > - Trb->AdmaDesc[Index].Address = Address; > + if (Remaining < AdmaMaxDataPerLine) { Same issue with the previous one. Could you please help to verify on SD controllers with version greater than 4.0, with the case that the data length of a TRB is a multiple of 64M bytes? Thanks in advance. Best Regards, Hao Wu > + Trb->Adma64Desc[Index].Valid = 1; > + Trb->Adma64Desc[Index].Act = 2; > + if (DataLength26 == TRUE) { > + Trb->Adma64Desc[Index].UpperLength = (UINT16)(Remaining >> 16); > + } > + Trb->Adma64Desc[Index].LowerLength = (UINT16)(Remaining & > MAX_UINT16); > + Trb->Adma64Desc[Index].LowerAddress = (UINT32)Address; > + Trb->Adma64Desc[Index].UpperAddress = (UINT32)(Address >> 32); > + break; > + } else { > + Trb->Adma64Desc[Index].Valid = 1; > + Trb->Adma64Desc[Index].Act = 2; > + if (DataLength26 == TRUE) { > + Trb->Adma64Desc[Index].UpperLength = 0; > + } > + Trb->Adma64Desc[Index].LowerLength = 0; > + Trb->Adma64Desc[Index].LowerAddress = (UINT32)Address; > + Trb->Adma64Desc[Index].UpperAddress = (UINT32)(Address >> 32); > + } > } > > - Remaining -= ADMA_MAX_DATA_PER_LINE; > - Address += ADMA_MAX_DATA_PER_LINE; > + Remaining -= AdmaMaxDataPerLine; > + Address += AdmaMaxDataPerLine; > } > > // > // Set the last descriptor line as end of descriptor table > // > - Trb->AdmaDesc[Index].End = 1; > + AddressingMode64 ? (Trb->Adma64Desc[Index].End = 1) : (Trb- > >Adma32Desc[Index].End = 1); > return EFI_SUCCESS; > } > > @@ -1524,11 +1701,18 @@ SdMmcFreeTrb ( > Trb->AdmaMap > ); > } > - if (Trb->AdmaDesc != NULL) { > + if (Trb->Adma32Desc != NULL) { > PciIo->FreeBuffer ( > PciIo, > Trb->AdmaPages, > - Trb->AdmaDesc > + Trb->Adma32Desc > + ); > + } > + if (Trb->Adma64Desc != NULL) { > + PciIo->FreeBuffer ( > + PciIo, > + Trb->AdmaPages, > + Trb->Adma64Desc > ); > } > if (Trb->DataMap != NULL) { > @@ -1668,12 +1852,16 @@ SdMmcExecTrb ( > UINT16 Cmd; > UINT16 IntStatus; > UINT32 Argument; > - UINT16 BlkCount; > + UINT32 BlkCount; > UINT16 BlkSize; > UINT16 TransMode; > UINT8 HostCtrl1; > - UINT32 SdmaAddr; > + UINT64 SdmaAddr; > UINT64 AdmaAddr; > + UINT16 ControllerVer; > + BOOLEAN AddressingMode64; > + > + AddressingMode64 = FALSE; > > Packet = Trb->Packet; > PciIo = Trb->Private->PciIo; > @@ -1706,13 +1894,32 @@ SdMmcExecTrb ( > > SdMmcHcLedOnOff (PciIo, Trb->Slot, TRUE); > > + Status = SdMmcHcGetControllerVersion (PciIo, Trb->Slot, &ControllerVer); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + if (ControllerVer >= SD_MMC_HC_CTRL_VER_400) { > + Status = SdMmcHcCheckMmioSet(PciIo, Trb->Slot, > SD_MMC_HC_HOST_CTRL2, 0x2, > + SD_MMC_HC_V4_EN|SD_MMC_HC_64_ADDR_EN, > SD_MMC_HC_V4_EN|SD_MMC_HC_64_ADDR_EN); > + if (!EFI_ERROR (Status)) { > + AddressingMode64 = TRUE; > + } > + } > + > if (Trb->Mode == SdMmcSdmaMode) { > - if ((UINT64)(UINTN)Trb->DataPhy >= 0x100000000ul) { > + if ((!AddressingMode64) && > + ((UINT64)(UINTN)Trb->DataPhy >= 0x100000000ul)) { > return EFI_INVALID_PARAMETER; > } > > - SdmaAddr = (UINT32)(UINTN)Trb->DataPhy; > - Status = SdMmcHcRwMmio (PciIo, Trb->Slot, SD_MMC_HC_SDMA_ADDR, > FALSE, sizeof (SdmaAddr), &SdmaAddr); > + SdmaAddr = (UINT64)(UINTN)Trb->DataPhy; > + > + if (ControllerVer >= SD_MMC_HC_CTRL_VER_400) { > + Status = SdMmcHcRwMmio (PciIo, Trb->Slot, > SD_MMC_HC_ADMA_SYS_ADDR, FALSE, sizeof (UINT64), &SdmaAddr); > + } else { > + Status = SdMmcHcRwMmio (PciIo, Trb->Slot, SD_MMC_HC_SDMA_ADDR, > FALSE, sizeof (UINT32), &SdmaAddr); > + } > + > if (EFI_ERROR (Status)) { > return Status; > } > @@ -1742,9 +1949,13 @@ SdMmcExecTrb ( > // > // Calcuate Block Count. > // > - BlkCount = (UINT16)(Trb->DataLen / Trb->BlockSize); > + BlkCount = (Trb->DataLen / Trb->BlockSize); > + } > + if (ControllerVer >= SD_MMC_HC_CTRL_VER_410) { > + Status = SdMmcHcRwMmio (PciIo, Trb->Slot, SD_MMC_HC_SDMA_ADDR, > FALSE, sizeof (UINT32), &BlkCount); > + } else { > + Status = SdMmcHcRwMmio (PciIo, Trb->Slot, SD_MMC_HC_BLK_COUNT, > FALSE, sizeof (UINT16), &BlkCount); > } > - Status = SdMmcHcRwMmio (PciIo, Trb->Slot, SD_MMC_HC_BLK_COUNT, > FALSE, sizeof (BlkCount), &BlkCount); > if (EFI_ERROR (Status)) { > return Status; > } > @@ -1840,10 +2051,11 @@ SdMmcCheckTrbResult ( > EFI_SD_MMC_PASS_THRU_COMMAND_PACKET *Packet; > UINT16 IntStatus; > UINT32 Response[4]; > - UINT32 SdmaAddr; > + UINT64 SdmaAddr; > UINT8 Index; > UINT8 SwReset; > UINT32 PioLength; > + UINT16 ControllerVer; > > SwReset = 0; > Packet = Trb->Packet; > @@ -1964,8 +2176,28 @@ SdMmcCheckTrbResult ( > // > // Update SDMA Address register. > // > - SdmaAddr = SD_MMC_SDMA_ROUND_UP ((UINT32)(UINTN)Trb->DataPhy, > SD_MMC_SDMA_BOUNDARY); > - Status = SdMmcHcRwMmio ( > + SdmaAddr = SD_MMC_SDMA_ROUND_UP ((UINTN)Trb->DataPhy, > SD_MMC_SDMA_BOUNDARY); > + > + Status = SdMmcHcGetControllerVersion ( > + Private->PciIo, > + Trb->Slot, > + &ControllerVer > + ); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + if (ControllerVer >= SD_MMC_HC_CTRL_VER_400) { > + Status = SdMmcHcRwMmio ( > + Private->PciIo, > + Trb->Slot, > + SD_MMC_HC_ADMA_SYS_ADDR, > + FALSE, > + sizeof (UINT64), > + &SdmaAddr > + ); > + } else { > + Status = SdMmcHcRwMmio ( > Private->PciIo, > Trb->Slot, > SD_MMC_HC_SDMA_ADDR, > @@ -1973,10 +2205,12 @@ SdMmcCheckTrbResult ( > sizeof (UINT32), > &SdmaAddr > ); > + } > + > if (EFI_ERROR (Status)) { > goto Done; > } > - Trb->DataPhy = (UINT32)(UINTN)SdmaAddr; > + Trb->DataPhy = (UINT64)(UINTN)SdmaAddr; > } > > if ((Packet->SdMmcCmdBlk->CommandType != SdMmcCommandTypeAdtc) > && > diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.h > b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.h > index ad9ce64..230687b 100644 > --- a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.h > +++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.h > @@ -2,6 +2,7 @@ > > Provides some data structure definitions used by the SD/MMC host > controller driver. > > +Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. > Copyright (c) 2015, Intel Corporation. All rights reserved.<BR> > This program and the accompanying materials > are licensed and made available under the terms and conditions of the BSD > License > @@ -91,18 +92,38 @@ typedef enum { > // > // The maximum data length of each descriptor line > // > -#define ADMA_MAX_DATA_PER_LINE 0x10000 > +#define ADMA_MAX_DATA_PER_LINE_16B SIZE_64KB > +#define ADMA_MAX_DATA_PER_LINE_26B SIZE_64MB > > +// > +// ADMA descriptor for 32b addressing. > +// > typedef struct { > UINT32 Valid:1; > UINT32 End:1; > UINT32 Int:1; > UINT32 Reserved:1; > UINT32 Act:2; > - UINT32 Reserved1:10; > - UINT32 Length:16; > + UINT32 UpperLength:10; > + UINT32 LowerLength:16; > UINT32 Address; > -} SD_MMC_HC_ADMA_DESC_LINE; > +} SD_MMC_HC_ADMA_32_DESC_LINE; > + > +// > +// ADMA descriptor for 64b addressing. > +// > +typedef struct { > + UINT32 Valid:1; > + UINT32 End:1; > + UINT32 Int:1; > + UINT32 Reserved:1; > + UINT32 Act:2; > + UINT32 UpperLength:10; > + UINT32 LowerLength:16; > + UINT32 LowerAddress; > + UINT32 UpperAddress; > + UINT32 Reserved1; > +} SD_MMC_HC_ADMA_64_DESC_LINE; > > #define SD_MMC_SDMA_BOUNDARY 512 * 1024 > #define SD_MMC_SDMA_ROUND_UP(x, n) (((x) + n) & ~(n - 1)) > @@ -153,12 +174,19 @@ typedef struct { > // > // SD Host controller version > // > -#define SD_MMC_HC_CTRL_VER_100 0x00 > -#define SD_MMC_HC_CTRL_VER_200 0x01 > -#define SD_MMC_HC_CTRL_VER_300 0x02 > -#define SD_MMC_HC_CTRL_VER_400 0x03 > -#define SD_MMC_HC_CTRL_VER_410 0x04 > -#define SD_MMC_HC_CTRL_VER_420 0x05 > +#define SD_MMC_HC_CTRL_VER_100 0x00 > +#define SD_MMC_HC_CTRL_VER_200 0x01 > +#define SD_MMC_HC_CTRL_VER_300 0x02 > +#define SD_MMC_HC_CTRL_VER_400 0x03 > +#define SD_MMC_HC_CTRL_VER_410 0x04 > +#define SD_MMC_HC_CTRL_VER_420 0x05 > + > +// > +// SD Host controller V4 enhancements > +// > +#define SD_MMC_HC_V4_EN BIT12 > +#define SD_MMC_HC_64_ADDR_EN BIT13 > +#define SD_MMC_HC_26_DATA_LEN_ADMA_EN BIT10 > > /** > Dump the content of SD/MMC host controller's Capability Register. > -- > 2.7.4 > > _______________________________________________ > edk2-devel mailing list > [email protected] > https://lists.01.org/mailman/listinfo/edk2-devel _______________________________________________ edk2-devel mailing list [email protected] https://lists.01.org/mailman/listinfo/edk2-devel

