From: "Wu, Hao A" <hao.a.wu@intel.com>
To: Ashish Singhal <ashishsingha@nvidia.com>,
"edk2-devel@lists.01.org" <edk2-devel@lists.01.org>
Subject: Re: [PATCH v6 2/2] MdeModulePkg/SdMmcPciHcDxe: Add SDMMC HC v4 and above Support.
Date: Fri, 30 Nov 2018 08:03:15 +0000 [thread overview]
Message-ID: <B80AF82E9BFB8E4FBD8C89DA810C6A093C85E992@SHSMSX104.ccr.corp.intel.com> (raw)
In-Reply-To: <7213b761dc6c09d587e63823c5241a54aa1b0e6f.1543515597.git.ashishsingha@nvidia.com>
Hello,
Please refer to the inline comments below:
> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
> Ashish Singhal
> Sent: Friday, November 30, 2018 3:15 AM
> To: edk2-devel@lists.01.org
> 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 <ashishsingha@nvidia.com>
> ---
> 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
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
next prev parent reply other threads:[~2018-11-30 8:03 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-11-29 18:25 [PATCH v5 1/2] MdeModulePkg/SdMmcPciHcDxe: Declare V4 64 bit address capability Ashish Singhal
2018-11-29 18:25 ` [PATCH v5 2/2] MdeModulePkg/SdMmcPciHcDxe: Add SDMMC HC v4 and above Support Ashish Singhal
2018-11-30 8:03 ` Wu, Hao A [this message]
2018-12-18 21:28 ` [PATCH v6 " Ashish Singhal
2018-11-30 8:00 ` [PATCH v6 1/2] MdeModulePkg/SdMmcPciHcDxe: Declare V4 64 bit address capability Wu, Hao A
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=B80AF82E9BFB8E4FBD8C89DA810C6A093C85E992@SHSMSX104.ccr.corp.intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox