Drivers/DwMmcHcDxe: change UseDma to UseFifo property
When DataLen equals to 0, avoid to call ReadFifo() to check
status.
And optimize the SD initialization.
Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
diff --git a/Drivers/SdMmc/DwMmcHcDxe/DwMmcHcDxe.h b/Drivers/SdMmc/DwMmcHcDxe/DwMmcHcDxe.h
index df68c67..4e175b9 100644
--- a/Drivers/SdMmc/DwMmcHcDxe/DwMmcHcDxe.h
+++ b/Drivers/SdMmc/DwMmcHcDxe/DwMmcHcDxe.h
@@ -137,7 +137,8 @@
EFI_PHYSICAL_ADDRESS DmaDescPhy;
UINT32 DmaDescPages;
VOID *DmaMap;
- BOOLEAN UseDma;
+
+ BOOLEAN UseFifo;
DW_MMC_HC_PRIVATE_DATA *Private;
} DW_MMC_HC_TRB;
diff --git a/Drivers/SdMmc/DwMmcHcDxe/DwMmcHci.c b/Drivers/SdMmc/DwMmcHcDxe/DwMmcHci.c
index 69ffd73..47e7415 100644
--- a/Drivers/SdMmc/DwMmcHcDxe/DwMmcHci.c
+++ b/Drivers/SdMmc/DwMmcHcDxe/DwMmcHci.c
@@ -1334,36 +1334,39 @@
}
PciIo = Private->PciIo;
- if (((Private->Slot[Trb->Slot].CardType == EmmcCardType) && (Trb->DataLen != 0)) ||
- ((Private->Slot[Trb->Slot].CardType == SdCardType) && (Trb->DataLen >= DWMMC_FIFO_THRESHOLD))) {
- MapLength = Trb->DataLen;
- Trb->UseDma = TRUE;
- Status = PciIo->Map (
- PciIo,
- Flag,
- Trb->Data,
- &MapLength,
- &Trb->DataPhy,
- &Trb->DataMap
- );
- if (EFI_ERROR (Status) || (Trb->DataLen != MapLength)) {
- Status = EFI_BAD_BUFFER_SIZE;
- goto Error;
- }
-
- Status = BuildDmaDescTable (Trb);
- if (EFI_ERROR (Status)) {
- PciIo->Unmap (PciIo, Trb->DataMap);
- goto Error;
- }
- Status = DwMmcHcStartDma (Private, Trb);
- if (EFI_ERROR (Status)) {
- PciIo->Unmap (PciIo, Trb->DataMap);
- goto Error;
- }
+ if ((Private->Slot[Trb->Slot].CardType == SdCardType) &&
+ (Trb->DataLen != 0) &&
+ (Trb->DataLen <= DWMMC_FIFO_THRESHOLD)) {
+ Trb->UseFifo = TRUE;
} else {
- Trb->UseDma = FALSE;
- } // Dma
+ Trb->UseFifo = FALSE;
+ if (Trb->DataLen) {
+ MapLength = Trb->DataLen;
+ Status = PciIo->Map (
+ PciIo,
+ Flag,
+ Trb->Data,
+ &MapLength,
+ &Trb->DataPhy,
+ &Trb->DataMap
+ );
+ if (EFI_ERROR (Status) || (Trb->DataLen != MapLength)) {
+ Status = EFI_BAD_BUFFER_SIZE;
+ goto Error;
+ }
+
+ Status = BuildDmaDescTable (Trb);
+ if (EFI_ERROR (Status)) {
+ PciIo->Unmap (PciIo, Trb->DataMap);
+ goto Error;
+ }
+ Status = DwMmcHcStartDma (Private, Trb);
+ if (EFI_ERROR (Status)) {
+ PciIo->Unmap (PciIo, Trb->DataMap);
+ goto Error;
+ }
+ }
+ }
} // TuningBlock
if (Event != NULL) {
@@ -1718,7 +1721,7 @@
}
Cmd |= BIT_CMD_USE_HOLD_REG | BIT_CMD_START;
- if (Trb->UseDma == FALSE) {
+ if (Trb->UseFifo == TRUE) {
BytCnt = Packet->InTransferLength;
Status = DwMmcHcRwMmio (PciIo, Trb->Slot, DW_MMC_BYTCNT, FALSE, sizeof (BytCnt), &BytCnt);
if (EFI_ERROR (Status)) {
@@ -1752,7 +1755,7 @@
if (Packet->InTransferLength || Packet->OutTransferLength) {
ErrMask |= DW_MMC_INT_DCRC;
}
- if (Trb->UseDma == FALSE) {
+ if (Trb->UseFifo == TRUE) {
Status = ReadFifo (Trb);
if (EFI_ERROR (Status)) {
return Status;
@@ -1798,7 +1801,7 @@
return Status;
}
} // Packet->InTransferLength
- } // UseDma
+ } // UseFifo
switch (Packet->SdMmcCmdBlk->ResponseType) {
case SdMmcResponseTypeR1:
case SdMmcResponseTypeR1b:
@@ -1899,7 +1902,7 @@
UINT32 Idsts;
Packet = Trb->Packet;
- if (Trb->UseDma == FALSE) {
+ if (Trb->UseFifo == TRUE) {
return EFI_SUCCESS;
}
if (Packet->InTransferLength) {
diff --git a/Drivers/SdMmc/DwMmcHcDxe/DwMmcHci.h b/Drivers/SdMmc/DwMmcHcDxe/DwMmcHci.h
index 9f0380c..228b20f 100644
--- a/Drivers/SdMmc/DwMmcHcDxe/DwMmcHci.h
+++ b/Drivers/SdMmc/DwMmcHcDxe/DwMmcHci.h
@@ -185,6 +185,8 @@
#define DWMMC_DMA_BUF_SIZE (512 * 8)
#define DWMMC_FIFO_THRESHOLD 16
+#define DWMMC_INIT_CLOCK_FREQ 400 // KHz
+
//
// The transfer modes supported by SD Host Controller
// Simplified Spec 3.0 Table 1-2
diff --git a/Drivers/SdMmc/DwMmcHcDxe/SdDevice.c b/Drivers/SdMmc/DwMmcHcDxe/SdDevice.c
index 02b4d9d..8bff945 100644
--- a/Drivers/SdMmc/DwMmcHcDxe/SdDevice.c
+++ b/Drivers/SdMmc/DwMmcHcDxe/SdDevice.c
@@ -800,6 +800,7 @@
@param[in] Slot The slot number of the SD card to send the command to.
@param[in] Rca The relative device address to be assigned.
@param[in] S18A The boolean to show if it's a UHS-I SD card.
+ @param[in] BusWidths The bus width of the SD card.
@retval EFI_SUCCESS The operation is done correctly.
@retval Others The operation fails.
@@ -811,7 +812,8 @@
IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
IN UINT8 Slot,
IN UINT16 Rca,
- IN BOOLEAN S18A
+ IN BOOLEAN S18A,
+ IN UINT32 BusWidths
)
{
EFI_STATUS Status;
@@ -820,11 +822,36 @@
UINT8 AccessMode;
UINT8 SwitchResp[64];
DW_MMC_HC_PRIVATE_DATA *Private;
+ BOOLEAN IsDdr;
Private = DW_MMC_HC_PRIVATE_FROM_THIS (PassThru);
Capability = &Private->Capability[Slot];
+ if ((Capability->BusWidth == 1) || (Capability->BusWidth == 4)) {
+ BusWidths &= Capability[Slot].BusWidth;
+ } else {
+ DEBUG ((DEBUG_ERROR, "SdCardSetBusMode: BusWidths (%d) in capability are wrong\n", Capability->BusWidth));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (BusWidths == 0) {
+ DEBUG ((DEBUG_ERROR, "SdCardSetBusMode: Get wrong BusWidths:%d\n", BusWidths));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Private->Capability[Slot].Ddr50) {
+ IsDdr = TRUE;
+ } else {
+ IsDdr = FALSE;
+ }
+
+ Status = SdCardSwitchBusWidth (PciIo, PassThru, Slot, Rca, IsDdr, BusWidths);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "SdCardSetBusMode: Executing SdCardSwitchBusWidth fails with %r\n", Status));
+ return Status;
+ }
+
//
// Get the supported bus speed from SWITCH cmd return data group #1.
//
@@ -901,8 +928,6 @@
UINT64 MaxCurrent;
SD_SCR Scr;
SD_CSD Csd;
- UINT32 BusWidths;
- BOOLEAN IsDdr;
PciIo = Private->PciIo;
PassThru = &Private->PassThru;
@@ -1001,45 +1026,40 @@
return Status;
}
+ Status = SdCardSwitchBusWidth (PciIo, PassThru, Slot, Rca, FALSE, 1);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "SdCardIdentification: Executing SdCardSwitchBusWidth fails with %r\n", Status));
+ return Status;
+ }
+
+ Status = DwMmcHcClockSupply (PciIo, Slot, DWMMC_INIT_CLOCK_FREQ, Private->Capability[Slot]);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "SdCardIdentification: Failing to set clock frequency %d, Status:%r\n", DWMMC_INIT_CLOCK_FREQ, Status));
+ return Status;
+ }
+
Status = SdCardGetScr (PassThru, Slot, Rca, &Scr);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "SdCardIdentification: Executing SdCardGetScr fails with %r\n", Status));
return Status;
}
- if ((Private->Capability[Slot].BusWidth == 1) || (Private->Capability[Slot].BusWidth == 4)) {
- BusWidths = Private->Capability[Slot].BusWidth & Scr.SdBusWidths;
- } else {
- return EFI_INVALID_PARAMETER;
- }
-
- if (Private->Capability[Slot].Ddr50) {
- IsDdr = TRUE;
- } else {
- IsDdr = FALSE;
- }
-
- Status = SdCardSwitchBusWidth (PciIo, PassThru, Slot, Rca, IsDdr, BusWidths);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "SdCardIdentification: Executing SdCardSwitchBusWidth fails with %r\n", Status));
- return Status;
- }
-
- Status = SdCardGetCsd (PassThru, Slot, Rca, &Csd);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "SdCardIdentification: Executing SdCardGetCsd fails with %r\n", Status));
- return Status;
- }
//
// Enter Data Tranfer Mode.
//
DEBUG ((DEBUG_INFO, "SdCardIdentification: Found a SD device at slot [%d]\n", Slot));
Private->Slot[Slot].CardType = SdCardType;
- Status = SdCardSetBusMode (PciIo, PassThru, Slot, Rca, S18r);
+ Status = SdCardSetBusMode (PciIo, PassThru, Slot, Rca, S18r, Scr.SdBusWidths);
if (EFI_ERROR (Status)) {
return Status;
}
+
+ Status = SdCardGetCsd (PassThru, Slot, Rca, &Csd);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "SdCardIdentification: Executing SdCardGetCsd fails with %r\n", Status));
+ return Status;
+ }
Private->Slot[Slot].Initialized = TRUE;
return Status;