]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg/SdMmcPciHcDxe: Add UhsSignaling to SdMmcOverride protocol
authorTomasz Michalec <tm@semihalf.com>
Fri, 9 Nov 2018 23:01:25 +0000 (07:01 +0800)
committerHao Wu <hao.a.wu@intel.com>
Tue, 20 Nov 2018 05:46:57 +0000 (13:46 +0800)
Some SD Host Controllers use different values in Host Control 2 Register
to select UHS Mode. This patch adds a new UhsSignaling type routine to
the NotifyPhase of the SdMmcOverride protocol.

UHS signaling configuration is moved to a common, default routine
(SdMmcHcUhsSignaling). After it is executed, the protocol producer
can override the values if needed.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Marcin Wojtas <mw@semihalf.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Hao Wu <hao.a.wu@intel.com>
MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c
MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdDevice.c
MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c
MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.h
MdeModulePkg/Include/Protocol/SdMmcOverride.h

index c5fd214307ff5658bd80b17115c32fe67167372d..db4e8a118709b4a4fc19bb8823e9ad089c2cc35e 100755 (executable)
@@ -740,10 +740,13 @@ EmmcSwitchToHighSpeed (
   IN UINT8                              BusWidth\r
   )\r
 {\r
-  EFI_STATUS          Status;\r
-  UINT8               HsTiming;\r
-  UINT8               HostCtrl1;\r
-  UINT8               HostCtrl2;\r
+  EFI_STATUS              Status;\r
+  UINT8                   HsTiming;\r
+  UINT8                   HostCtrl1;\r
+  SD_MMC_BUS_MODE         Timing;\r
+  SD_MMC_HC_PRIVATE_DATA  *Private;\r
+\r
+  Private = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru);\r
 \r
   Status = EmmcSwitchBusWidth (PciIo, PassThru, Slot, Rca, IsDdr, BusWidth);\r
   if (EFI_ERROR (Status)) {\r
@@ -758,25 +761,15 @@ EmmcSwitchToHighSpeed (
     return Status;\r
   }\r
 \r
-  //\r
-  // Clean UHS Mode Select field of Host Control 2 reigster before update\r
-  //\r
-  HostCtrl2 = (UINT8)~0x7;\r
-  Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-  //\r
-  // Set UHS Mode Select field of Host Control 2 reigster to SDR12/25/50\r
-  //\r
   if (IsDdr) {\r
-    HostCtrl2 = BIT2;\r
+    Timing = SdMmcMmcHsDdr;\r
   } else if (ClockFreq == 52) {\r
-    HostCtrl2 = BIT0;\r
+    Timing = SdMmcMmcHsSdr;\r
   } else {\r
-    HostCtrl2 = 0;\r
+    Timing = SdMmcMmcLegacy;\r
   }\r
-  Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);\r
+\r
+  Status = SdMmcHcUhsSignaling (Private->ControllerHandle, PciIo, Slot, Timing);\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
@@ -814,10 +807,13 @@ EmmcSwitchToHS200 (
   IN UINT8                              BusWidth\r
   )\r
 {\r
-  EFI_STATUS          Status;\r
-  UINT8               HsTiming;\r
-  UINT8               HostCtrl2;\r
-  UINT16              ClockCtrl;\r
+  EFI_STATUS               Status;\r
+  UINT8                    HsTiming;\r
+  UINT16                   ClockCtrl;\r
+  SD_MMC_BUS_MODE          Timing;\r
+  SD_MMC_HC_PRIVATE_DATA  *Private;\r
+\r
+  Private = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru);\r
 \r
   if ((BusWidth != 4) && (BusWidth != 8)) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -837,22 +833,14 @@ EmmcSwitchToHS200 (
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
-  //\r
-  // Clean UHS Mode Select field of Host Control 2 reigster before update\r
-  //\r
-  HostCtrl2 = (UINT8)~0x7;\r
-  Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-  //\r
-  // Set UHS Mode Select field of Host Control 2 reigster to SDR104\r
-  //\r
-  HostCtrl2 = BIT0 | BIT1;\r
-  Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);\r
+\r
+  Timing = SdMmcMmcHs200;\r
+\r
+  Status = SdMmcHcUhsSignaling (Private->ControllerHandle, PciIo, Slot, Timing);\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
+\r
   //\r
   // Wait Internal Clock Stable in the Clock Control register to be 1 before set SD Clock Enable bit\r
   //\r
@@ -910,9 +898,12 @@ EmmcSwitchToHS400 (
   IN UINT32                             ClockFreq\r
   )\r
 {\r
-  EFI_STATUS          Status;\r
-  UINT8               HsTiming;\r
-  UINT8               HostCtrl2;\r
+  EFI_STATUS                 Status;\r
+  UINT8                      HsTiming;\r
+  SD_MMC_BUS_MODE            Timing;\r
+  SD_MMC_HC_PRIVATE_DATA     *Private;\r
+\r
+  Private = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru);\r
 \r
   Status = EmmcSwitchToHS200 (PciIo, PassThru, Slot, Rca, ClockFreq, 8);\r
   if (EFI_ERROR (Status)) {\r
@@ -933,19 +924,10 @@ EmmcSwitchToHS400 (
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
-  //\r
-  // Clean UHS Mode Select field of Host Control 2 reigster before update\r
-  //\r
-  HostCtrl2 = (UINT8)~0x7;\r
-  Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-  //\r
-  // Set UHS Mode Select field of Host Control 2 reigster to HS400\r
-  //\r
-  HostCtrl2 = BIT0 | BIT2;\r
-  Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);\r
+\r
+  Timing = SdMmcMmcHs400;\r
+\r
+  Status = SdMmcHcUhsSignaling (Private->ControllerHandle, PciIo, Slot, Timing);\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
index 6ee9ed7f14e22ee4d3e8ff62d7a8ac337f959f32..55b3564e9a77785cac64c4fc1f1fba0c7d40af68 100644 (file)
@@ -784,8 +784,8 @@ SdCardSetBusMode (
   UINT8                        BusWidth;\r
   UINT8                        AccessMode;\r
   UINT8                        HostCtrl1;\r
-  UINT8                        HostCtrl2;\r
   UINT8                        SwitchResp[64];\r
+  SD_MMC_BUS_MODE              Timing;\r
   SD_MMC_HC_PRIVATE_DATA       *Private;\r
 \r
   Private = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru);\r
@@ -817,18 +817,23 @@ SdCardSetBusMode (
   if (S18A && (Capability->Sdr104 != 0) && ((SwitchResp[13] & BIT3) != 0)) {\r
     ClockFreq = 208;\r
     AccessMode = 3;\r
+    Timing = SdMmcUhsSdr104;\r
   } else if (S18A && (Capability->Sdr50 != 0) && ((SwitchResp[13] & BIT2) != 0)) {\r
     ClockFreq = 100;\r
     AccessMode = 2;\r
+    Timing = SdMmcUhsSdr50;\r
   } else if (S18A && (Capability->Ddr50 != 0) && ((SwitchResp[13] & BIT4) != 0)) {\r
     ClockFreq = 50;\r
     AccessMode = 4;\r
+    Timing = SdMmcUhsDdr50;\r
   } else if ((SwitchResp[13] & BIT1) != 0) {\r
     ClockFreq = 50;\r
     AccessMode = 1;\r
+    Timing = SdMmcUhsSdr25;\r
   } else {\r
     ClockFreq = 25;\r
     AccessMode = 0;\r
+    Timing = SdMmcUhsSdr12;\r
   }\r
 \r
   Status = SdCardSwitch (PassThru, Slot, AccessMode, 0xF, 0xF, 0xF, TRUE, SwitchResp);\r
@@ -854,13 +859,7 @@ SdCardSetBusMode (
     }\r
   }\r
 \r
-  HostCtrl2 = (UINT8)~0x7;\r
-  Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-  HostCtrl2 = AccessMode;\r
-  Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);\r
+  Status = SdMmcHcUhsSignaling (Private->ControllerHandle, PciIo, Slot, Timing);\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
index 923c55bbbe877832185b8329083cbdba643e0c8f..c3eec8bcd4910bab83731a8e029ac9f97807a888 100644 (file)
@@ -1137,6 +1137,95 @@ SdMmcHcInitHost (
   return Status;\r
 }\r
 \r
+/**\r
+  Set SD Host Controler control 2 registry according to selected speed.\r
+\r
+  @param[in] ControllerHandle The handle of the controller.\r
+  @param[in] PciIo            The PCI IO protocol instance.\r
+  @param[in] Slot             The slot number of the SD card to send the command to.\r
+  @param[in] Timing           The timing to select.\r
+\r
+  @retval EFI_SUCCESS         The timing is set successfully.\r
+  @retval Others              The timing isn't set successfully.\r
+**/\r
+EFI_STATUS\r
+SdMmcHcUhsSignaling (\r
+  IN EFI_HANDLE             ControllerHandle,\r
+  IN EFI_PCI_IO_PROTOCOL    *PciIo,\r
+  IN UINT8                  Slot,\r
+  IN SD_MMC_BUS_MODE        Timing\r
+  )\r
+{\r
+  EFI_STATUS                 Status;\r
+  UINT8                      HostCtrl2;\r
+\r
+  HostCtrl2 = (UINT8)~SD_MMC_HC_CTRL_UHS_MASK;\r
+  Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  switch (Timing) {\r
+    case SdMmcUhsSdr12:\r
+      HostCtrl2 = SD_MMC_HC_CTRL_UHS_SDR12;\r
+      break;\r
+    case SdMmcUhsSdr25:\r
+      HostCtrl2 = SD_MMC_HC_CTRL_UHS_SDR25;\r
+      break;\r
+    case SdMmcUhsSdr50:\r
+      HostCtrl2 = SD_MMC_HC_CTRL_UHS_SDR50;\r
+      break;\r
+    case SdMmcUhsSdr104:\r
+      HostCtrl2 = SD_MMC_HC_CTRL_UHS_SDR104;\r
+      break;\r
+    case SdMmcUhsDdr50:\r
+      HostCtrl2 = SD_MMC_HC_CTRL_UHS_DDR50;\r
+      break;\r
+    case SdMmcMmcLegacy:\r
+      HostCtrl2 = SD_MMC_HC_CTRL_MMC_LEGACY;\r
+      break;\r
+    case SdMmcMmcHsSdr:\r
+      HostCtrl2 = SD_MMC_HC_CTRL_MMC_HS_SDR;\r
+      break;\r
+    case SdMmcMmcHsDdr:\r
+      HostCtrl2 = SD_MMC_HC_CTRL_MMC_HS_DDR;\r
+      break;\r
+    case SdMmcMmcHs200:\r
+      HostCtrl2 = SD_MMC_HC_CTRL_MMC_HS200;\r
+      break;\r
+    case SdMmcMmcHs400:\r
+      HostCtrl2 = SD_MMC_HC_CTRL_MMC_HS400;\r
+      break;\r
+    default:\r
+     HostCtrl2 = 0;\r
+     break;\r
+  }\r
+  Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  if (mOverride != NULL && mOverride->NotifyPhase != NULL) {\r
+    Status = mOverride->NotifyPhase (\r
+                          ControllerHandle,\r
+                          Slot,\r
+                          EdkiiSdMmcUhsSignaling,\r
+                          &Timing\r
+                          );\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((\r
+        DEBUG_ERROR,\r
+        "%a: SD/MMC uhs signaling notifier callback failed - %r\n",\r
+        __FUNCTION__,\r
+        Status\r
+        ));\r
+      return Status;\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
 /**\r
   Turn on/off LED.\r
 \r
index 7e3f588e0a229952054aff1595971093ed3c34e1..b47b0df7a7dd76c9cc572546a14e72d2b7f72f55 100644 (file)
@@ -62,6 +62,21 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #define SD_MMC_HC_SLOT_INT_STS        0xFC\r
 #define SD_MMC_HC_CTRL_VER            0xFE\r
 \r
+//\r
+// SD Host Controller bits to HOST_CTRL2 register\r
+//\r
+#define SD_MMC_HC_CTRL_UHS_MASK       0x0007\r
+#define SD_MMC_HC_CTRL_UHS_SDR12      0x0000\r
+#define SD_MMC_HC_CTRL_UHS_SDR25      0x0001\r
+#define SD_MMC_HC_CTRL_UHS_SDR50      0x0002\r
+#define SD_MMC_HC_CTRL_UHS_SDR104     0x0003\r
+#define SD_MMC_HC_CTRL_UHS_DDR50      0x0004\r
+#define SD_MMC_HC_CTRL_MMC_LEGACY     0x0000\r
+#define SD_MMC_HC_CTRL_MMC_HS_SDR     0x0001\r
+#define SD_MMC_HC_CTRL_MMC_HS_DDR     0x0004\r
+#define SD_MMC_HC_CTRL_MMC_HS200      0x0003\r
+#define SD_MMC_HC_CTRL_MMC_HS400      0x0005\r
+\r
 //\r
 // The transfer modes supported by SD Host Controller\r
 // Simplified Spec 3.0 Table 1-2\r
@@ -518,4 +533,23 @@ SdMmcHcInitTimeoutCtrl (
   IN UINT8                  Slot\r
   );\r
 \r
+/**\r
+  Set SD Host Controller control 2 registry according to selected speed.\r
+\r
+  @param[in] ControllerHandle The handle of the controller.\r
+  @param[in] PciIo            The PCI IO protocol instance.\r
+  @param[in] Slot             The slot number of the SD card to send the command to.\r
+  @param[in] Timing           The timing to select.\r
+\r
+  @retval EFI_SUCCESS         The timing is set successfully.\r
+  @retval Others              The timing isn't set successfully.\r
+**/\r
+EFI_STATUS\r
+SdMmcHcUhsSignaling (\r
+  IN EFI_HANDLE             ControllerHandle,\r
+  IN EFI_PCI_IO_PROTOCOL    *PciIo,\r
+  IN UINT8                  Slot,\r
+  IN SD_MMC_BUS_MODE        Timing\r
+  );\r
+\r
 #endif\r
index 8a7669e3108f36797b0f0db9b5f23e6afd355682..f948befba5b1989a283d864d8807c886b21d74a3 100644 (file)
 \r
 typedef struct _EDKII_SD_MMC_OVERRIDE EDKII_SD_MMC_OVERRIDE;\r
 \r
+//\r
+// Bus timing modes\r
+//\r
+typedef enum {\r
+  SdMmcUhsSdr12,\r
+  SdMmcUhsSdr25,\r
+  SdMmcUhsSdr50,\r
+  SdMmcUhsSdr104,\r
+  SdMmcUhsDdr50,\r
+  SdMmcMmcLegacy,\r
+  SdMmcMmcHsSdr,\r
+  SdMmcMmcHsDdr,\r
+  SdMmcMmcHs200,\r
+  SdMmcMmcHs400,\r
+} SD_MMC_BUS_MODE;\r
+\r
 typedef enum {\r
   EdkiiSdMmcResetPre,\r
   EdkiiSdMmcResetPost,\r
   EdkiiSdMmcInitHostPre,\r
   EdkiiSdMmcInitHostPost,\r
+  EdkiiSdMmcUhsSignaling,\r
 } EDKII_SD_MMC_PHASE_TYPE;\r
 \r
 /**\r