Drivers/DwMmcHcDxe: use fifo

Since fail to use DMA on HiKey960 platform, use FIFO instead.

Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
diff --git a/Drivers/SdMmc/DwMmcHcDxe/DwMmcHcDxe.h b/Drivers/SdMmc/DwMmcHcDxe/DwMmcHcDxe.h
index 4e175b9..4fe040e 100644
--- a/Drivers/SdMmc/DwMmcHcDxe/DwMmcHcDxe.h
+++ b/Drivers/SdMmc/DwMmcHcDxe/DwMmcHcDxe.h
@@ -139,6 +139,7 @@
   VOID                                *DmaMap;

 

   BOOLEAN                             UseFifo;

+  BOOLEAN                             UseBE;                  // Big-endian

 

   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 9ca044b..cf34e30 100644
--- a/Drivers/SdMmc/DwMmcHcDxe/DwMmcHci.c
+++ b/Drivers/SdMmc/DwMmcHcDxe/DwMmcHci.c
@@ -1214,17 +1214,23 @@
   UINT32                    Intsts;

   UINT32                    Sts;

   UINT32                    FifoCount;

+  UINT32                    Index;     // count with bytes

+  UINT32                    Ascending;

+  UINT32                    Descending;

 

   PciIo   = Trb->Private->PciIo;

   Received = 0;

-  Count = (Trb->DataLen + 3) / 4;

-  while (1) {

+  Count = 0;

+  Index = 0;

+  Ascending = 0;

+  Descending = ((Trb->DataLen + 3) & ~3) - 4;

+  do {

     Status = DwMmcHcRwMmio (PciIo, Trb->Slot, DW_MMC_RINTSTS, TRUE, sizeof (Intsts), &Intsts);

     if (EFI_ERROR (Status)) {

       DEBUG ((DEBUG_ERROR, "ReadFifo: failed to read RINTSTS, Status:%r\n", Status));

       return Status;

     }

-    if (Intsts & DW_MMC_INT_DTO) {

+    if (Trb->DataLen && ((Intsts & DW_MMC_INT_RXDR) || (Intsts & DW_MMC_INT_DTO))) {

       Status = DwMmcHcRwMmio (PciIo, Trb->Slot, DW_MMC_STATUS, TRUE, sizeof (Sts), &Sts);

       if (EFI_ERROR (Status)) {

         DEBUG ((DEBUG_ERROR, "ReadFifo: failed to read STATUS, Status:%r\n", Status));

@@ -1232,28 +1238,30 @@
       }

       // Convert to bytes

       FifoCount = GET_STS_FIFO_COUNT (Sts) << 2;

-      Count = (MIN (FifoCount, Trb->DataLen) + 3) / 4;

-      Received = 0;

-      // Read FIFO

-      while (Count && (Received < Count)) {

+      if ((FifoCount == 0) && (Received < Trb->DataLen)) {

+        continue;

+      }

+      Index = 0;

+      Count = (MIN (FifoCount, Trb->DataLen) + 3) & ~3;

+      while (Index < Count) {

         Status = DwMmcHcRwMmio (PciIo, Trb->Slot, DW_MMC_FIFO_START, TRUE, sizeof (Data), &Data);

         if (EFI_ERROR (Status)) {

           DEBUG ((DEBUG_ERROR, "ReadFifo: failed to read FIFO, Status:%r\n", Status));

           return Status;

         }

-        *(UINT32 *)((UINTN)Trb->Data + ((Count - Received - 1) << 2)) = SwapBytes32 (Data);

-        Received++;

-      }

-    }

-    if (Intsts & DW_MMC_INT_CMD_DONE) {

-      if ((Intsts == DW_MMC_INT_CMD_DONE) && Count) {

-        // CMD_DONE interrupt comes earlier before other interrupts. Just wait for a while.

-        continue;

-      } else {

-        break;

-      }

-    }

-  }

+        if (Trb->UseBE) {

+          *(UINT32 *)((UINTN)Trb->Data + Descending) = SwapBytes32 (Data);

+          Descending = Descending - 4;

+        } else {

+          *(UINT32 *)((UINTN)Trb->Data + Ascending) = Data;

+          Ascending += 4;

+        }

+        Index += 4;

+        Received += 4;

+      } // while

+    } // if

+  } while (((Intsts & DW_MMC_INT_CMD_DONE) == 0) || (Received < Trb->DataLen));

+  // Clear RINTSTS

   Intsts = ~0;

   Status = DwMmcHcRwMmio (PciIo, Trb->Slot, DW_MMC_RINTSTS, FALSE, sizeof (Intsts), &Intsts);

   if (EFI_ERROR (Status)) {

@@ -1334,9 +1342,13 @@
     }

 

     PciIo = Private->PciIo;

+#if 0

     if ((Private->Slot[Trb->Slot].CardType == SdCardType) &&

         (Trb->DataLen != 0) &&

         (Trb->DataLen <= DWMMC_FIFO_THRESHOLD)) {

+#else

+    if (Private->Slot[Trb->Slot].CardType == SdCardType) {

+#endif

       Trb->UseFifo = TRUE;

     } else {

       Trb->UseFifo = FALSE;

@@ -1689,6 +1701,9 @@
     case SD_STOP_TRANSMISSION:

       Cmd |= BIT_CMD_STOP_ABORT_CMD;

       break;

+    case SD_SEND_SCR:

+      Trb->UseBE = TRUE;

+      break;

     }

     if (Packet->InTransferLength) {

       Cmd |= BIT_CMD_WAIT_PRVDATA_COMPLETE | BIT_CMD_DATA_EXPECTED | BIT_CMD_READ;

@@ -1725,7 +1740,11 @@
     if (EFI_ERROR (Status)) {

       return Status;

     }

-    BlkSize = Packet->InTransferLength;

+    if (Packet->InTransferLength > DW_MMC_BLOCK_SIZE) {

+      BlkSize = DW_MMC_BLOCK_SIZE;

+    } else {

+      BlkSize = Packet->InTransferLength;

+    }

     Status = DwMmcHcRwMmio (PciIo, Trb->Slot, DW_MMC_BLKSIZ, FALSE, sizeof (BlkSize), &BlkSize);

     if (EFI_ERROR (Status)) {

       DEBUG ((DEBUG_ERROR, "DwMmcHcReset: set block size fails: %r\n", Status));

@@ -1761,6 +1780,9 @@
   } else {

     Timeout = 10000;

     do {

+      if (--Timeout == 0) {

+        break;

+      }

       Status = DwMmcHcRwMmio (PciIo, Trb->Slot, DW_MMC_RINTSTS, TRUE, sizeof (IntStatus), &IntStatus);

       if (EFI_ERROR (Status)) {

         return Status;

@@ -1768,13 +1790,12 @@
       if (IntStatus & ErrMask) {

         return EFI_DEVICE_ERROR;

       }

-      if (IntStatus & DW_MMC_INT_DTO) {  // Transfer Done

-        break;

+      if (Trb->DataLen && ((IntStatus & DW_MMC_INT_DTO) == 0)) {  // Transfer Done

+        MicroSecondDelay (10);

+        continue;

+      } else {

+        MicroSecondDelay (10);

       }

-      if (--Timeout == 0) {

-        break;

-      }

-      MicroSecondDelay (10);

     } while (!(IntStatus & DW_MMC_INT_CMD_DONE));

     if (Packet->InTransferLength) {

       do {