From 7d48d20a3dbea79f3b33b562c84bdf8decc4b368 Mon Sep 17 00:00:00 2001 From: "Albecki, Mateusz" Date: Fri, 28 Feb 2020 01:25:24 +0800 Subject: [PATCH] MdeModulePkg/SdMmcPciHcDxe: Refactor data transfer completion This patch refactors the way in which the driver will check the data transfer completion. Data transfer related functionalities have been moved to separate function. Cc: Hao A Wu Cc: Marcin Wojtas Cc: Zhichao Gao Cc: Liming Gao Signed-off-by: Mateusz Albecki Tested-by: Hao A Wu Reviewed-by: Hao A Wu --- .../Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c | 181 +++++++++++------- 1 file changed, 112 insertions(+), 69 deletions(-) diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c index 1fa6823cbb..fa8ab72757 100644 --- a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c +++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c @@ -2447,6 +2447,112 @@ SdMmcCheckCommandComplete ( return EFI_NOT_READY; } +/** + Update the SDMA address on the SDMA buffer boundary interrupt. + + @param[in] Private A pointer to the SD_MMC_HC_PRIVATE_DATA instance. + @param[in] Trb The pointer to the SD_MMC_HC_TRB instance. + + @retval EFI_SUCCESS Updated SDMA buffer address. + @retval Others Failed to update SDMA buffer address. +**/ +EFI_STATUS +SdMmcUpdateSdmaAddress ( + IN SD_MMC_HC_PRIVATE_DATA *Private, + IN SD_MMC_HC_TRB *Trb + ) +{ + UINT64 SdmaAddr; + EFI_STATUS Status; + + SdmaAddr = SD_MMC_SDMA_ROUND_UP ((UINTN)Trb->DataPhy, SD_MMC_SDMA_BOUNDARY); + + if (Private->ControllerVersion[Trb->Slot] >= 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, + FALSE, + sizeof (UINT32), + &SdmaAddr + ); + } + + if (EFI_ERROR (Status)) { + return Status; + } + + Trb->DataPhy = (UINT64)(UINTN)SdmaAddr; + return EFI_SUCCESS; +} + +/** + Checks if the data transfer completed and performs any actions + neccessary to continue the data transfer such as SDMA system + address fixup or PIO data transfer. + + @param[in] Private A pointer to the SD_MMC_HC_PRIVATE_DATA instance. + @param[in] Trb The pointer to the SD_MMC_HC_TRB instance. + @param[in] IntStatus Snapshot of the normal interrupt status register. + + @retval EFI_SUCCESS Data transfer completed successfully. + @retval EFI_NOT_READY Data transfer completion still pending. + @retval Others Data transfer failed to complete. +**/ +EFI_STATUS +SdMmcCheckDataTransfer ( + IN SD_MMC_HC_PRIVATE_DATA *Private, + IN SD_MMC_HC_TRB *Trb, + IN UINT16 IntStatus + ) +{ + UINT16 Data16; + EFI_STATUS Status; + + if ((IntStatus & BIT1) != 0) { + Data16 = BIT1; + Status = SdMmcHcRwMmio ( + Private->PciIo, + Trb->Slot, + SD_MMC_HC_NOR_INT_STS, + FALSE, + sizeof (Data16), + &Data16 + ); + return Status; + } + + if ((Trb->Mode == SdMmcSdmaMode) && ((IntStatus & BIT3) != 0)) { + Data16 = BIT3; + Status = SdMmcHcRwMmio ( + Private->PciIo, + Trb->Slot, + SD_MMC_HC_NOR_INT_STS, + FALSE, + sizeof (Data16), + &Data16 + ); + if (EFI_ERROR (Status)) { + return Status; + } + Status = SdMmcUpdateSdmaAddress (Private, Trb); + if (EFI_ERROR (Status)) { + return Status; + } + } + + return EFI_NOT_READY; +} + /** Check the TRB execution result. @@ -2467,7 +2573,6 @@ SdMmcCheckTrbResult ( EFI_STATUS Status; EFI_SD_MMC_PASS_THRU_COMMAND_PACKET *Packet; UINT16 IntStatus; - UINT64 SdmaAddr; UINT32 PioLength; Packet = Trb->Packet; @@ -2530,80 +2635,18 @@ SdMmcCheckTrbResult ( Status = SdMmcCheckCommandComplete (Private, Trb, IntStatus); if (EFI_ERROR (Status)) { goto Done; - } else { - // - // If the command doesn't require data transfer skip the transfer - // complete checking. - // - if ((Packet->SdMmcCmdBlk->CommandType != SdMmcCommandTypeAdtc) && - (Packet->SdMmcCmdBlk->ResponseType != SdMmcResponseTypeR1b) && - (Packet->SdMmcCmdBlk->ResponseType != SdMmcResponseTypeR5b)) { - goto Done; - } } } - // - // Check Transfer Complete bit is set or not. - // - if ((IntStatus & BIT1) == BIT1) { - goto Done; - } - - // - // Check if DMA interrupt is signalled for the SDMA transfer. - // - if ((Trb->Mode == SdMmcSdmaMode) && ((IntStatus & BIT3) == BIT3)) { - // - // Clear DMA interrupt bit. - // - IntStatus = BIT3; - Status = SdMmcHcRwMmio ( - Private->PciIo, - Trb->Slot, - SD_MMC_HC_NOR_INT_STS, - FALSE, - sizeof (IntStatus), - &IntStatus - ); - if (EFI_ERROR (Status)) { - goto Done; - } - // - // Update SDMA Address register. - // - SdmaAddr = SD_MMC_SDMA_ROUND_UP ((UINTN)Trb->DataPhy, SD_MMC_SDMA_BOUNDARY); - - if (Private->ControllerVersion[Trb->Slot] >= 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, - FALSE, - sizeof (UINT32), - &SdmaAddr - ); - } - - if (EFI_ERROR (Status)) { - goto Done; - } - Trb->DataPhy = (UINT64)(UINTN)SdmaAddr; + if (Packet->SdMmcCmdBlk->CommandType == SdMmcCommandTypeAdtc || + Packet->SdMmcCmdBlk->ResponseType == SdMmcResponseTypeR1b || + Packet->SdMmcCmdBlk->ResponseType == SdMmcResponseTypeR5b) { + Status = SdMmcCheckDataTransfer (Private, Trb, IntStatus); + } else { + Status = EFI_SUCCESS; } - - Status = EFI_NOT_READY; Done: - if (Status != EFI_NOT_READY) { SdMmcHcLedOnOff (Private->PciIo, Trb->Slot, FALSE); if (EFI_ERROR (Status)) { -- 2.39.2