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;