]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c
MdeModulePkg/SdMmcPciHcDxe: allow HC capabilities to be overridden
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / SdMmcPciHcDxe / SdMmcPciHci.c
index b4ff2af01961ebc4724bc54b170f2092363e30a2..9672b5b9bf18184055f6fc7f53bf3a8c68619d6d 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
@@ -419,7 +419,7 @@ SdMmcHcWaitMmioSet (
 /**\r
   Software reset the specified SD/MMC host controller and enable all interrupts.\r
 \r
-  @param[in] PciIo          The PCI IO protocol instance.\r
+  @param[in] Private        A pointer to the SD_MMC_HC_PRIVATE_DATA instance.\r
   @param[in] Slot           The slot number of the SD card to send the command to.\r
 \r
   @retval EFI_SUCCESS       The software reset executes successfully.\r
@@ -428,18 +428,37 @@ SdMmcHcWaitMmioSet (
 **/\r
 EFI_STATUS\r
 SdMmcHcReset (\r
-  IN EFI_PCI_IO_PROTOCOL    *PciIo,\r
+  IN SD_MMC_HC_PRIVATE_DATA *Private,\r
   IN UINT8                  Slot\r
   )\r
 {\r
   EFI_STATUS                Status;\r
   UINT8                     SwReset;\r
+  EFI_PCI_IO_PROTOCOL       *PciIo;\r
+\r
+  //\r
+  // Notify the SD/MMC override protocol that we are about to reset\r
+  // the SD/MMC host controller.\r
+  //\r
+  if (mOverride != NULL && mOverride->NotifyPhase != NULL) {\r
+    Status = mOverride->NotifyPhase (\r
+                          Private->ControllerHandle,\r
+                          Slot,\r
+                          EdkiiSdMmcResetPre);\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((DEBUG_WARN,\r
+        "%a: SD/MMC pre reset notifier callback failed - %r\n",\r
+        __FUNCTION__, Status));\r
+      return Status;\r
+    }\r
+  }\r
 \r
+  PciIo   = Private->PciIo;\r
   SwReset = 0xFF;\r
   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,13 +472,35 @@ 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
   //\r
   // Enable all interrupt after reset all.\r
   //\r
   Status = SdMmcHcEnableInterrupt (PciIo, Slot);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_INFO, "SdMmcHcReset: SdMmcHcEnableInterrupt done with %r\n",\r
+      Status));\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Notify the SD/MMC override protocol that we have just reset\r
+  // the SD/MMC host controller.\r
+  //\r
+  if (mOverride != NULL && mOverride->NotifyPhase != NULL) {\r
+    Status = mOverride->NotifyPhase (\r
+                          Private->ControllerHandle,\r
+                          Slot,\r
+                          EdkiiSdMmcResetPost);\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((DEBUG_WARN,\r
+        "%a: SD/MMC post reset notifier callback failed - %r\n",\r
+        __FUNCTION__, Status));\r
+    }\r
+  }\r
 \r
   return Status;\r
 }\r
@@ -732,7 +773,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
@@ -754,7 +795,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
@@ -772,7 +813,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
@@ -1021,9 +1062,8 @@ SdMmcHcInitTimeoutCtrl (
   Initial SD/MMC host controller with lowest clock frequency, max power and max timeout value\r
   at initialization.\r
 \r
-  @param[in] PciIo          The PCI IO protocol instance.\r
+  @param[in] Private        A pointer to the SD_MMC_HC_PRIVATE_DATA instance.\r
   @param[in] Slot           The slot number of the SD card to send the command to.\r
-  @param[in] Capability     The capability of the slot.\r
 \r
   @retval EFI_SUCCESS       The host controller is initialized successfully.\r
   @retval Others            The host controller isn't initialized successfully.\r
@@ -1031,12 +1071,33 @@ SdMmcHcInitTimeoutCtrl (
 **/\r
 EFI_STATUS\r
 SdMmcHcInitHost (\r
-  IN EFI_PCI_IO_PROTOCOL    *PciIo,\r
-  IN UINT8                  Slot,\r
-  IN SD_MMC_HC_SLOT_CAP     Capability\r
+  IN SD_MMC_HC_PRIVATE_DATA *Private,\r
+  IN UINT8                  Slot\r
   )\r
 {\r
-  EFI_STATUS       Status;\r
+  EFI_STATUS                Status;\r
+  EFI_PCI_IO_PROTOCOL       *PciIo;\r
+  SD_MMC_HC_SLOT_CAP        Capability;\r
+\r
+  //\r
+  // Notify the SD/MMC override protocol that we are about to initialize\r
+  // the SD/MMC host controller.\r
+  //\r
+  if (mOverride != NULL && mOverride->NotifyPhase != NULL) {\r
+    Status = mOverride->NotifyPhase (\r
+                          Private->ControllerHandle,\r
+                          Slot,\r
+                          EdkiiSdMmcInitHostPre);\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((DEBUG_WARN,\r
+        "%a: SD/MMC pre init notifier callback failed - %r\n",\r
+        __FUNCTION__, Status));\r
+      return Status;\r
+    }\r
+  }\r
+\r
+  PciIo = Private->PciIo;\r
+  Capability = Private->Capability[Slot];\r
 \r
   Status = SdMmcHcInitClockFreq (PciIo, Slot, Capability);\r
   if (EFI_ERROR (Status)) {\r
@@ -1049,6 +1110,25 @@ SdMmcHcInitHost (
   }\r
 \r
   Status = SdMmcHcInitTimeoutCtrl (PciIo, Slot);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Notify the SD/MMC override protocol that we are have just initialized\r
+  // the SD/MMC host controller.\r
+  //\r
+  if (mOverride != NULL && mOverride->NotifyPhase != NULL) {\r
+    Status = mOverride->NotifyPhase (\r
+                          Private->ControllerHandle,\r
+                          Slot,\r
+                          EdkiiSdMmcInitHostPost);\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((DEBUG_WARN,\r
+        "%a: SD/MMC post init notifier callback failed - %r\n",\r
+        __FUNCTION__, Status));\r
+    }\r
+  }\r
   return Status;\r
 }\r
 \r
@@ -1125,7 +1205,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
@@ -1265,7 +1345,7 @@ SdMmcCreateTrb (
     goto Error;\r
   }\r
 \r
-  if (Trb->DataLen < Trb->BlockSize) {\r
+  if ((Trb->DataLen != 0) && (Trb->DataLen < Trb->BlockSize)) {\r
     Trb->BlockSize = (UINT16)Trb->DataLen;\r
   }\r
 \r