[edk2-devel] [PATCH 1/1] MdeModulePkg/SdMmcPciHcDxe: Fix bus timing switch sequence

Albecki, Mateusz mateusz.albecki at intel.com
Mon Sep 23 08:37:01 UTC 2019


SD specification recommends switching card bus timing before
switching bus timing in controller. Emmc driver used to do
this switch other way around. This commit adds controller
timing switch in EmmcSwitchBusTiming function to enforce this
order and removes all controller timing programing from
EmmcSwitchToXXX functions.

Signed-off-by: Mateusz Albecki <mateusz.albecki at intel.com>
Cc: Hao A Wu <hao.a.wu at intel.com>
Cc: Marcin Wojtas <mw at semihalf.com>
---
 MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c | 79 +++++++------------------
 1 file changed, 20 insertions(+), 59 deletions(-)

diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c
index 3f4a8e5413..06ee1208be 100644
--- a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c
+++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c
@@ -671,6 +671,7 @@ EmmcSwitchBusTiming (
   UINT8                     CmdSet;
   UINT32                    DevStatus;
   SD_MMC_HC_PRIVATE_DATA    *Private;
+  UINT8                     HostCtrl1;
 
   Private = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru);
   //
@@ -704,6 +705,25 @@ EmmcSwitchBusTiming (
     return Status;
   }
 
+  if (BusTiming == SdMmcMmcHsSdr || BusTiming == SdMmcMmcHsDdr) {
+    HostCtrl1 = BIT2;
+    Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL1, sizeof (HostCtrl1), &HostCtrl1);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  } else {
+    HostCtrl1 = (UINT8)~BIT2;
+    Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL1, sizeof (HostCtrl1), &HostCtrl1);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  }
+
+  Status = SdMmcHcUhsSignaling (Private->ControllerHandle, PciIo, Slot, BusTiming);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
   //
   // Convert the clock freq unit from MHz to KHz.
   //
@@ -772,7 +792,6 @@ EmmcSwitchToHighSpeed (
   )
 {
   EFI_STATUS              Status;
-  UINT8                   HostCtrl1;
   SD_MMC_HC_PRIVATE_DATA  *Private;
   BOOLEAN                 IsDdr;
 
@@ -794,20 +813,6 @@ EmmcSwitchToHighSpeed (
     return Status;
   }
 
-  //
-  // Set to High Speed timing
-  //
-  HostCtrl1 = BIT2;
-  Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL1, sizeof (HostCtrl1), &HostCtrl1);
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-
-  Status = SdMmcHcUhsSignaling (Private->ControllerHandle, PciIo, Slot, BusMode->BusTiming);
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-
   return EmmcSwitchBusTiming (PciIo, PassThru, Slot, Rca, BusMode->DriverStrength, BusMode->BusTiming, BusMode->ClockFreq);
 }
 
@@ -837,7 +842,6 @@ EmmcSwitchToHS200 (
   )
 {
   EFI_STATUS               Status;
-  UINT16                   ClockCtrl;
   SD_MMC_HC_PRIVATE_DATA  *Private;
 
   Private = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru);
@@ -851,39 +855,6 @@ EmmcSwitchToHS200 (
   if (EFI_ERROR (Status)) {
     return Status;
   }
-  //
-  // Stop bus clock at first
-  //
-  Status = SdMmcHcStopClock (PciIo, Slot);
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-
-  Status = SdMmcHcUhsSignaling (Private->ControllerHandle, PciIo, Slot, BusMode->BusTiming);
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-
-  //
-  // Wait Internal Clock Stable in the Clock Control register to be 1 before set SD Clock Enable bit
-  //
-  Status = SdMmcHcWaitMmioSet (
-             PciIo,
-             Slot,
-             SD_MMC_HC_CLOCK_CTRL,
-             sizeof (ClockCtrl),
-             BIT1,
-             BIT1,
-             SD_MMC_HC_GENERIC_TIMEOUT
-             );
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-  //
-  // Set SD Clock Enable in the Clock Control register to 1
-  //
-  ClockCtrl = BIT2;
-  Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_CLOCK_CTRL, sizeof (ClockCtrl), &ClockCtrl);
 
   Status = EmmcSwitchBusTiming (PciIo, PassThru, Slot, Rca, BusMode->DriverStrength, BusMode->BusTiming, BusMode->ClockFreq);
   if (EFI_ERROR (Status)) {
@@ -945,11 +916,6 @@ EmmcSwitchToHS400 (
   // Set to High Speed timing and set the clock frequency to a value less than or equal to 52MHz.
   // This step is necessary to be able to switch Bus into 8 bit DDR mode which is unsupported in HS200.
   //
-  Status = SdMmcHcUhsSignaling (Private->ControllerHandle, PciIo, Slot, SdMmcMmcHsSdr);
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-
   HsFreq = BusMode->ClockFreq < 52 ? BusMode->ClockFreq : 52;
   Status = EmmcSwitchBusTiming (PciIo, PassThru, Slot, Rca, BusMode->DriverStrength, SdMmcMmcHsSdr, HsFreq);
   if (EFI_ERROR (Status)) {
@@ -961,11 +927,6 @@ EmmcSwitchToHS400 (
     return Status;
   }
 
-  Status = SdMmcHcUhsSignaling (Private->ControllerHandle, PciIo, Slot, BusMode->BusTiming);
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-
   return EmmcSwitchBusTiming (PciIo, PassThru, Slot, Rca, BusMode->DriverStrength, BusMode->BusTiming, BusMode->ClockFreq);
 }
 
-- 
2.14.1.windows.1

--------------------------------------------------------------------

Intel Technology Poland sp. z o.o.
ul. Slowackiego 173 | 80-298 Gdansk | Sad Rejonowy Gdansk Polnoc | VII Wydzial Gospodarczy Krajowego Rejestru Sadowego - KRS 101882 | NIP 957-07-52-316 | Kapital zakladowy 200.000 PLN.

Ta wiadomosc wraz z zalacznikami jest przeznaczona dla okreslonego adresata i moze zawierac informacje poufne. W razie przypadkowego otrzymania tej wiadomosci, prosimy o powiadomienie nadawcy oraz trwale jej usuniecie; jakiekolwiek
przegladanie lub rozpowszechnianie jest zabronione.
This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). If you are not the intended recipient, please contact the sender and delete all copies; any review or distribution by
others is strictly prohibited.


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.

View/Reply Online (#47832): https://edk2.groups.io/g/devel/message/47832
Mute This Topic: https://groups.io/mt/34262004/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub  [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-




More information about the edk2-devel-archive mailing list