]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c
MdeModulePkg/Xhci: Remove TRB when canceling Async Int Transfer
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / SdMmcPciHcDxe / SdMmcPciHci.c
index baa12f44eeacea52453f5c01ea687f665ad72d2d..aa75aa8d243480f6142015b8a7c17e342f982ed8 100644 (file)
@@ -4,7 +4,7 @@
 \r
   It would expose EFI_SD_MMC_PASS_THRU_PROTOCOL for upper layer use.\r
 \r
-  Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>\r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
   which accompanies this distribution.  The full text of the license may be found at\r
@@ -33,46 +33,46 @@ DumpCapabilityReg (
   //\r
   // Dump Capability Data\r
   //\r
-  DEBUG ((EFI_D_INFO, " == Slot [%d] Capability is 0x%x ==\n", Slot, Capability));\r
-  DEBUG ((EFI_D_INFO, "   Timeout Clk Freq  %d%a\n", Capability->TimeoutFreq, (Capability->TimeoutUnit) ? "MHz" : "KHz"));\r
-  DEBUG ((EFI_D_INFO, "   Base Clk Freq     %dMHz\n", Capability->BaseClkFreq));\r
-  DEBUG ((EFI_D_INFO, "   Max Blk Len       %dbytes\n", 512 * (1 << Capability->MaxBlkLen)));\r
-  DEBUG ((EFI_D_INFO, "   8-bit Support     %a\n", Capability->BusWidth8 ? "TRUE" : "FALSE"));\r
-  DEBUG ((EFI_D_INFO, "   ADMA2 Support     %a\n", Capability->Adma2 ? "TRUE" : "FALSE"));\r
-  DEBUG ((EFI_D_INFO, "   HighSpeed Support %a\n", Capability->HighSpeed ? "TRUE" : "FALSE"));\r
-  DEBUG ((EFI_D_INFO, "   SDMA Support      %a\n", Capability->Sdma ? "TRUE" : "FALSE"));\r
-  DEBUG ((EFI_D_INFO, "   Suspend/Resume    %a\n", Capability->SuspRes ? "TRUE" : "FALSE"));\r
-  DEBUG ((EFI_D_INFO, "   Voltage 3.3       %a\n", Capability->Voltage33 ? "TRUE" : "FALSE"));\r
-  DEBUG ((EFI_D_INFO, "   Voltage 3.0       %a\n", Capability->Voltage30 ? "TRUE" : "FALSE"));\r
-  DEBUG ((EFI_D_INFO, "   Voltage 1.8       %a\n", Capability->Voltage18 ? "TRUE" : "FALSE"));\r
-  DEBUG ((EFI_D_INFO, "   64-bit Sys Bus    %a\n", Capability->SysBus64 ? "TRUE" : "FALSE"));\r
-  DEBUG ((EFI_D_INFO, "   Async Interrupt   %a\n", Capability->AsyncInt ? "TRUE" : "FALSE"));\r
-  DEBUG ((EFI_D_INFO, "   SlotType          "));\r
+  DEBUG ((DEBUG_INFO, " == Slot [%d] Capability is 0x%x ==\n", Slot, Capability));\r
+  DEBUG ((DEBUG_INFO, "   Timeout Clk Freq  %d%a\n", Capability->TimeoutFreq, (Capability->TimeoutUnit) ? "MHz" : "KHz"));\r
+  DEBUG ((DEBUG_INFO, "   Base Clk Freq     %dMHz\n", Capability->BaseClkFreq));\r
+  DEBUG ((DEBUG_INFO, "   Max Blk Len       %dbytes\n", 512 * (1 << Capability->MaxBlkLen)));\r
+  DEBUG ((DEBUG_INFO, "   8-bit Support     %a\n", Capability->BusWidth8 ? "TRUE" : "FALSE"));\r
+  DEBUG ((DEBUG_INFO, "   ADMA2 Support     %a\n", Capability->Adma2 ? "TRUE" : "FALSE"));\r
+  DEBUG ((DEBUG_INFO, "   HighSpeed Support %a\n", Capability->HighSpeed ? "TRUE" : "FALSE"));\r
+  DEBUG ((DEBUG_INFO, "   SDMA Support      %a\n", Capability->Sdma ? "TRUE" : "FALSE"));\r
+  DEBUG ((DEBUG_INFO, "   Suspend/Resume    %a\n", Capability->SuspRes ? "TRUE" : "FALSE"));\r
+  DEBUG ((DEBUG_INFO, "   Voltage 3.3       %a\n", Capability->Voltage33 ? "TRUE" : "FALSE"));\r
+  DEBUG ((DEBUG_INFO, "   Voltage 3.0       %a\n", Capability->Voltage30 ? "TRUE" : "FALSE"));\r
+  DEBUG ((DEBUG_INFO, "   Voltage 1.8       %a\n", Capability->Voltage18 ? "TRUE" : "FALSE"));\r
+  DEBUG ((DEBUG_INFO, "   64-bit Sys Bus    %a\n", Capability->SysBus64 ? "TRUE" : "FALSE"));\r
+  DEBUG ((DEBUG_INFO, "   Async Interrupt   %a\n", Capability->AsyncInt ? "TRUE" : "FALSE"));\r
+  DEBUG ((DEBUG_INFO, "   SlotType          "));\r
   if (Capability->SlotType == 0x00) {\r
-    DEBUG ((EFI_D_INFO, "%a\n", "Removable Slot"));\r
+    DEBUG ((DEBUG_INFO, "%a\n", "Removable Slot"));\r
   } else if (Capability->SlotType == 0x01) {\r
-    DEBUG ((EFI_D_INFO, "%a\n", "Embedded Slot"));\r
+    DEBUG ((DEBUG_INFO, "%a\n", "Embedded Slot"));\r
   } else if (Capability->SlotType == 0x02) {\r
-    DEBUG ((EFI_D_INFO, "%a\n", "Shared Bus Slot"));\r
+    DEBUG ((DEBUG_INFO, "%a\n", "Shared Bus Slot"));\r
   } else {\r
-    DEBUG ((EFI_D_INFO, "%a\n", "Reserved"));\r
-  }\r
-  DEBUG ((EFI_D_INFO, "   SDR50  Support    %a\n", Capability->Sdr50 ? "TRUE" : "FALSE"));\r
-  DEBUG ((EFI_D_INFO, "   SDR104 Support    %a\n", Capability->Sdr104 ? "TRUE" : "FALSE"));\r
-  DEBUG ((EFI_D_INFO, "   DDR50  Support    %a\n", Capability->Ddr50 ? "TRUE" : "FALSE"));\r
-  DEBUG ((EFI_D_INFO, "   Driver Type A     %a\n", Capability->DriverTypeA ? "TRUE" : "FALSE"));\r
-  DEBUG ((EFI_D_INFO, "   Driver Type C     %a\n", Capability->DriverTypeC ? "TRUE" : "FALSE"));\r
-  DEBUG ((EFI_D_INFO, "   Driver Type D     %a\n", Capability->DriverTypeD ? "TRUE" : "FALSE"));\r
-  DEBUG ((EFI_D_INFO, "   Driver Type 4     %a\n", Capability->DriverType4 ? "TRUE" : "FALSE"));\r
+    DEBUG ((DEBUG_INFO, "%a\n", "Reserved"));\r
+  }\r
+  DEBUG ((DEBUG_INFO, "   SDR50  Support    %a\n", Capability->Sdr50 ? "TRUE" : "FALSE"));\r
+  DEBUG ((DEBUG_INFO, "   SDR104 Support    %a\n", Capability->Sdr104 ? "TRUE" : "FALSE"));\r
+  DEBUG ((DEBUG_INFO, "   DDR50  Support    %a\n", Capability->Ddr50 ? "TRUE" : "FALSE"));\r
+  DEBUG ((DEBUG_INFO, "   Driver Type A     %a\n", Capability->DriverTypeA ? "TRUE" : "FALSE"));\r
+  DEBUG ((DEBUG_INFO, "   Driver Type C     %a\n", Capability->DriverTypeC ? "TRUE" : "FALSE"));\r
+  DEBUG ((DEBUG_INFO, "   Driver Type D     %a\n", Capability->DriverTypeD ? "TRUE" : "FALSE"));\r
+  DEBUG ((DEBUG_INFO, "   Driver Type 4     %a\n", Capability->DriverType4 ? "TRUE" : "FALSE"));\r
   if (Capability->TimerCount == 0) {\r
-    DEBUG ((EFI_D_INFO, "   Retuning TimerCnt Disabled\n", 2 * (Capability->TimerCount - 1)));\r
+    DEBUG ((DEBUG_INFO, "   Retuning TimerCnt Disabled\n", 2 * (Capability->TimerCount - 1)));\r
   } else {\r
-    DEBUG ((EFI_D_INFO, "   Retuning TimerCnt %dseconds\n", 2 * (Capability->TimerCount - 1)));\r
+    DEBUG ((DEBUG_INFO, "   Retuning TimerCnt %dseconds\n", 2 * (Capability->TimerCount - 1)));\r
   }\r
-  DEBUG ((EFI_D_INFO, "   SDR50 Tuning      %a\n", Capability->TuningSDR50 ? "TRUE" : "FALSE"));\r
-  DEBUG ((EFI_D_INFO, "   Retuning Mode     Mode %d\n", Capability->RetuningMod + 1));\r
-  DEBUG ((EFI_D_INFO, "   Clock Multiplier  M = %d\n", Capability->ClkMultiplier + 1));\r
-  DEBUG ((EFI_D_INFO, "   HS 400            %a\n", Capability->Hs400 ? "TRUE" : "FALSE"));\r
+  DEBUG ((DEBUG_INFO, "   SDR50 Tuning      %a\n", Capability->TuningSDR50 ? "TRUE" : "FALSE"));\r
+  DEBUG ((DEBUG_INFO, "   Retuning Mode     Mode %d\n", Capability->RetuningMod + 1));\r
+  DEBUG ((DEBUG_INFO, "   Clock Multiplier  M = %d\n", Capability->ClkMultiplier + 1));\r
+  DEBUG ((DEBUG_INFO, "   HS 400            %a\n", Capability->Hs400 ? "TRUE" : "FALSE"));\r
   return;\r
 }\r
 \r
@@ -439,7 +439,7 @@ SdMmcHcReset (
   Status  = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_SW_RST, FALSE, sizeof (SwReset), &SwReset);\r
 \r
   if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "SdMmcHcReset: write full 1 fails: %r\n", Status));\r
+    DEBUG ((DEBUG_ERROR, "SdMmcHcReset: write full 1 fails: %r\n", Status));\r
     return Status;\r
   }\r
 \r
@@ -453,7 +453,7 @@ SdMmcHcReset (
              SD_MMC_HC_GENERIC_TIMEOUT\r
              );\r
   if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_INFO, "SdMmcHcReset: reset done with %r\n", Status));\r
+    DEBUG ((DEBUG_INFO, "SdMmcHcReset: reset done with %r\n", Status));\r
     return Status;\r
   }\r
   //\r
@@ -706,9 +706,14 @@ SdMmcHcClockSupply (
   ASSERT (Capability.BaseClkFreq != 0);\r
 \r
   BaseClkFreq = Capability.BaseClkFreq;\r
-  if ((ClockFreq > (BaseClkFreq * 1000)) || (ClockFreq == 0)) {\r
+  if (ClockFreq == 0) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
+\r
+  if (ClockFreq > (BaseClkFreq * 1000)) {\r
+    ClockFreq = BaseClkFreq * 1000;\r
+  }\r
+\r
   //\r
   // Calculate the divisor of base frequency.\r
   //\r
@@ -727,7 +732,7 @@ SdMmcHcClockSupply (
     }\r
   }\r
 \r
-  DEBUG ((EFI_D_INFO, "BaseClkFreq %dMHz Divisor %d ClockFreq %dKhz\n", BaseClkFreq, Divisor, ClockFreq));\r
+  DEBUG ((DEBUG_INFO, "BaseClkFreq %dMHz Divisor %d ClockFreq %dKhz\n", BaseClkFreq, Divisor, ClockFreq));\r
 \r
   Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_CTRL_VER, TRUE, sizeof (ControllerVer), &ControllerVer);\r
   if (EFI_ERROR (Status)) {\r
@@ -749,7 +754,7 @@ SdMmcHcClockSupply (
     ASSERT (Divisor <= 0x80);\r
     ClockCtrl = (Divisor & 0xFF) << 8;\r
   } else {\r
-    DEBUG ((EFI_D_ERROR, "Unknown SD Host Controller Spec version [0x%x]!!!\n", ControllerVer));\r
+    DEBUG ((DEBUG_ERROR, "Unknown SD Host Controller Spec version [0x%x]!!!\n", ControllerVer));\r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
@@ -767,7 +772,7 @@ SdMmcHcClockSupply (
   ClockCtrl |= BIT0;\r
   Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_CLOCK_CTRL, FALSE, sizeof (ClockCtrl), &ClockCtrl);\r
   if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "Set SDCLK Frequency Select and Internal Clock Enable fields fails\n"));\r
+    DEBUG ((DEBUG_ERROR, "Set SDCLK Frequency Select and Internal Clock Enable fields fails\n"));\r
     return Status;\r
   }\r
 \r
@@ -1120,7 +1125,7 @@ BuildAdmaDescTable (
   // for 32-bit address descriptor table.\r
   //\r
   if ((Data & (BIT0 | BIT1)) != 0) {\r
-    DEBUG ((EFI_D_INFO, "The buffer [0x%x] to construct ADMA desc is not aligned to 4 bytes boundary!\n", Data));\r
+    DEBUG ((DEBUG_INFO, "The buffer [0x%x] to construct ADMA desc is not aligned to 4 bytes boundary!\n", Data));\r
   }\r
 \r
   Entries   = DivU64x32 ((DataLen + ADMA_MAX_DATA_PER_LINE - 1), ADMA_MAX_DATA_PER_LINE);\r
@@ -1260,52 +1265,57 @@ SdMmcCreateTrb (
     goto Error;\r
   }\r
 \r
-  if (Trb->Read) {\r
-    Flag = EfiPciIoOperationBusMasterWrite;\r
+  if ((Trb->DataLen != 0) && (Trb->DataLen < Trb->BlockSize)) {\r
+    Trb->BlockSize = (UINT16)Trb->DataLen;\r
+  }\r
+\r
+  if (((Private->Slot[Trb->Slot].CardType == EmmcCardType) &&\r
+       (Packet->SdMmcCmdBlk->CommandIndex == EMMC_SEND_TUNING_BLOCK)) ||\r
+      ((Private->Slot[Trb->Slot].CardType == SdCardType) &&\r
+       (Packet->SdMmcCmdBlk->CommandIndex == SD_SEND_TUNING_BLOCK))) {\r
+    Trb->Mode = SdMmcPioMode;\r
   } else {\r
-    Flag = EfiPciIoOperationBusMasterRead;\r
-  }\r
-\r
-  PciIo = Private->PciIo;\r
-  if (Trb->DataLen != 0) {\r
-    MapLength = Trb->DataLen;\r
-    Status = PciIo->Map (\r
-                      PciIo,\r
-                      Flag,\r
-                      Trb->Data,\r
-                      &MapLength,\r
-                      &Trb->DataPhy,\r
-                      &Trb->DataMap\r
-                      );\r
-    if (EFI_ERROR (Status) || (Trb->DataLen != MapLength)) {\r
-      Status = EFI_BAD_BUFFER_SIZE;\r
-      goto Error;\r
+    if (Trb->Read) {\r
+      Flag = EfiPciIoOperationBusMasterWrite;\r
+    } else {\r
+      Flag = EfiPciIoOperationBusMasterRead;\r
     }\r
-  }\r
 \r
-  if ((Trb->DataLen % Trb->BlockSize) != 0) {\r
-    if (Trb->DataLen < Trb->BlockSize) {\r
-      Trb->BlockSize = (UINT16)Trb->DataLen;\r
+    PciIo = Private->PciIo;\r
+    if (Trb->DataLen != 0) {\r
+      MapLength = Trb->DataLen;\r
+      Status = PciIo->Map (\r
+                        PciIo,\r
+                        Flag,\r
+                        Trb->Data,\r
+                        &MapLength,\r
+                        &Trb->DataPhy,\r
+                        &Trb->DataMap\r
+                        );\r
+      if (EFI_ERROR (Status) || (Trb->DataLen != MapLength)) {\r
+        Status = EFI_BAD_BUFFER_SIZE;\r
+        goto Error;\r
+      }\r
     }\r
-  }\r
 \r
-  if (Trb->DataLen == 0) {\r
-    Trb->Mode = SdMmcNoData;\r
-  } else if (Private->Capability[Slot].Adma2 != 0) {\r
-    Trb->Mode = SdMmcAdmaMode;\r
-    Status = BuildAdmaDescTable (Trb);\r
-    if (EFI_ERROR (Status)) {\r
-      PciIo->Unmap (PciIo, Trb->DataMap);\r
-      goto Error;\r
+    if (Trb->DataLen == 0) {\r
+      Trb->Mode = SdMmcNoData;\r
+    } else if (Private->Capability[Slot].Adma2 != 0) {\r
+      Trb->Mode = SdMmcAdmaMode;\r
+      Status = BuildAdmaDescTable (Trb);\r
+      if (EFI_ERROR (Status)) {\r
+        PciIo->Unmap (PciIo, Trb->DataMap);\r
+        goto Error;\r
+      }\r
+    } else if (Private->Capability[Slot].Sdma != 0) {\r
+      Trb->Mode = SdMmcSdmaMode;\r
+    } else {\r
+      Trb->Mode = SdMmcPioMode;\r
     }\r
-  } else if (Private->Capability[Slot].Sdma != 0) {\r
-    Trb->Mode = SdMmcSdmaMode;\r
-  } else {\r
-    Trb->Mode = SdMmcPioMode;\r
   }\r
 \r
   if (Event != NULL) {\r
-    OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
+    OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
     InsertTailList (&Private->Queue, &Trb->TrbList);\r
     gBS->RestoreTPL (OldTpl);\r
   }\r
@@ -1387,15 +1397,6 @@ SdMmcCheckTrbEnv (
     // the Present State register to be 0\r
     //\r
     PresentState = BIT0 | BIT1;\r
-    //\r
-    // For Send Tuning Block cmd, just wait for Command Inhibit (CMD) to be 0\r
-    //\r
-    if (((Private->Slot[Trb->Slot].CardType == EmmcCardType) &&\r
-         (Packet->SdMmcCmdBlk->CommandIndex == EMMC_SEND_TUNING_BLOCK)) ||\r
-        ((Private->Slot[Trb->Slot].CardType == SdCardType) &&\r
-         (Packet->SdMmcCmdBlk->CommandIndex == SD_SEND_TUNING_BLOCK))) {\r
-      PresentState = BIT0;\r
-    }\r
   } else {\r
     //\r
     // Wait Command Inhibit (CMD) in the Present State register\r
@@ -1560,7 +1561,13 @@ SdMmcExecTrb (
     return Status;\r
   }\r
 \r
-  BlkCount = (UINT16)(Trb->DataLen / Trb->BlockSize);\r
+  BlkCount = 0;\r
+  if (Trb->Mode != SdMmcNoData) {\r
+    //\r
+    // Calcuate Block Count.\r
+    //\r
+    BlkCount = (UINT16)(Trb->DataLen / Trb->BlockSize);\r
+  }\r
   Status   = SdMmcHcRwMmio (PciIo, Trb->Slot, SD_MMC_HC_BLK_COUNT, FALSE, sizeof (BlkCount), &BlkCount);\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
@@ -1580,7 +1587,7 @@ SdMmcExecTrb (
     if (Trb->Read) {\r
       TransMode |= BIT4;\r
     }\r
-    if (BlkCount != 0) {\r
+    if (BlkCount > 1) {\r
       TransMode |= BIT5 | BIT1;\r
     }\r
     //\r
@@ -1660,6 +1667,7 @@ SdMmcCheckTrbResult (
   UINT32                              SdmaAddr;\r
   UINT8                               Index;\r
   UINT8                               SwReset;\r
+  UINT32                              PioLength;\r
 \r
   SwReset = 0;\r
   Packet  = Trb->Packet;\r
@@ -1809,12 +1817,25 @@ SdMmcCheckTrbResult (
       ((Private->Slot[Trb->Slot].CardType == SdCardType) &&\r
        (Packet->SdMmcCmdBlk->CommandIndex == SD_SEND_TUNING_BLOCK))) {\r
     //\r
-    // While performing tuning procedure (Execute Tuning is set to 1),\r
-    // Transfer Completeis not set to 1\r
-    // Refer to SD Host Controller Simplified Specification 3.0 table 2-23 for details.\r
+    // When performing tuning procedure (Execute Tuning is set to 1) through PIO mode,\r
+    // wait Buffer Read Ready bit of Normal Interrupt Status Register to be 1.\r
+    // Refer to SD Host Controller Simplified Specification 3.0 figure 2-29 for details.\r
     //\r
-    Status = EFI_SUCCESS;\r
-    goto Done;\r
+    if ((IntStatus & BIT5) == BIT5) {\r
+      //\r
+      // Clear Buffer Read Ready interrupt at first.\r
+      //\r
+      IntStatus = BIT5;\r
+      SdMmcHcRwMmio (Private->PciIo, Trb->Slot, SD_MMC_HC_NOR_INT_STS, FALSE, sizeof (IntStatus), &IntStatus);\r
+      //\r
+      // Read data out from Buffer Port register\r
+      //\r
+      for (PioLength = 0; PioLength < Trb->DataLen; PioLength += 4) {\r
+        SdMmcHcRwMmio (Private->PciIo, Trb->Slot, SD_MMC_HC_BUF_DAT_PORT, TRUE, 4, (UINT8*)Trb->Data + PioLength);\r
+      }\r
+      Status = EFI_SUCCESS;\r
+      goto Done;\r
+    }\r
   }\r
 \r
   Status = EFI_NOT_READY;\r