public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH] patch1_add_support_bh720_emmc_chip
@ 2019-01-28  7:35 Mike Li (WH)
  2019-01-29  2:31 ` Wu, Hao A
  0 siblings, 1 reply; 2+ messages in thread
From: Mike Li (WH) @ 2019-01-28  7:35 UTC (permalink / raw)
  To: edk2-devel@lists.01.org

---
 .../Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c        | 253 ++++++++++++------
 .../Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.h     |  47 +---
 2 files changed, 178 insertions(+), 122 deletions(-)

diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c
index 4ef849fd09..ac79a2f791 100644
--- a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c
+++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c
@@ -527,17 +527,35 @@ EmmcTuningClkForHs200 (
   if (EFI_ERROR (Status)) {
     return Status;
   }
+
+  if(BhtHostPciSupport(PciIo)){
+		//set data transfer with 4bit
+ 		Status = SdMmcHcSetBusWidth (PciIo, Slot, 4);
+		//enable hardware tuning
+		HostCtrl2 = (~0x10);
+		Status = SdMmcHcAndMmio (PciIo, Slot, 0x110,sizeof (HostCtrl2), &HostCtrl2);
+
+	  Status = EmmcSendTuningBlk (PassThru, Slot, 4);
+	  if (EFI_ERROR (Status)) {
+		DEBUG ((DEBUG_ERROR, "EmmcTuningClkForHs200: Send tuning block fails with %r\n", Status));
+		return Status;
+	  }
+
+  }
   //
   // Ask the device to send a sequence of tuning blocks till the tuning procedure is done.
   //
   Retry = 0;
   do {
-    Status = EmmcSendTuningBlk (PassThru, Slot, BusWidth);
-    if (EFI_ERROR (Status)) {
-      DEBUG ((DEBUG_ERROR, "EmmcTuningClkForHs200: Send tuning block fails with %r\n", Status));
-      return Status;
-    }
-
+  	if(!BhtHostPciSupport(PciIo)){
+	    Status = EmmcSendTuningBlk (PassThru, Slot, BusWidth);
+	    if (EFI_ERROR (Status)) {
+	      DEBUG ((DEBUG_ERROR, "EmmcTuningClkForHs200: Send tuning block fails with %r\n", Status));
+	      return Status;
+	    }
+  	} else {
+  		gBS->Stall(5000);
+  	}
     Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, TRUE, sizeof (HostCtrl2), &HostCtrl2);
     if (EFI_ERROR (Status)) {
       return Status;
@@ -548,6 +566,10 @@ EmmcTuningClkForHs200 (
     }
 
     if ((HostCtrl2 & (BIT6 | BIT7)) == BIT7) {
+	  if(BhtHostPciSupport(PciIo)){
+	  	//set data transfer with default
+	  	Status = SdMmcHcSetBusWidth (PciIo, Slot, BusWidth);
+	  	}
       return EFI_SUCCESS;
     }
   } while (++Retry < 40);
@@ -652,7 +674,6 @@ EmmcSwitchBusWidth (
   @param[in] Slot           The slot number of the SD card to send the command to.
   @param[in] Rca            The relative device address to be assigned.
   @param[in] HsTiming       The value to be written to HS_TIMING field of EXT_CSD register.
-  @param[in] Timing         The bus mode timing indicator.
   @param[in] ClockFreq      The max clock frequency to be set, the unit is MHz.
 
   @retval EFI_SUCCESS       The operation is done correctly.
@@ -666,7 +687,6 @@ EmmcSwitchClockFreq (
   IN UINT8                              Slot,
   IN UINT16                             Rca,
   IN UINT8                              HsTiming,
-  IN SD_MMC_BUS_MODE                    Timing,
   IN UINT32                             ClockFreq
   )
 {
@@ -708,28 +728,7 @@ EmmcSwitchClockFreq (
   //
   // Convert the clock freq unit from MHz to KHz.
   //
-  Status = SdMmcHcClockSupply (PciIo, Slot, ClockFreq * 1000, Private->BaseClkFreq[Slot], Private->ControllerVersion[Slot]);
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-
-  if (mOverride != NULL && mOverride->NotifyPhase != NULL) {
-    Status = mOverride->NotifyPhase (
-                          Private->ControllerHandle,
-                          Slot,
-                          EdkiiSdMmcSwitchClockFreqPost,
-                          &Timing
-                          );
-    if (EFI_ERROR (Status)) {
-      DEBUG ((
-        DEBUG_ERROR,
-        "%a: SD/MMC switch clock freq post notifier callback failed - %r\n",
-        __FUNCTION__,
-        Status
-        ));
-      return Status;
-    }
-  }
+  Status = SdMmcHcClockSupply (PciIo, Slot, ClockFreq * 1000, Private->Capability[Slot]);
 
   return Status;
 }
@@ -764,13 +763,10 @@ EmmcSwitchToHighSpeed (
   IN UINT8                              BusWidth
   )
 {
-  EFI_STATUS              Status;
-  UINT8                   HsTiming;
-  UINT8                   HostCtrl1;
-  SD_MMC_BUS_MODE         Timing;
-  SD_MMC_HC_PRIVATE_DATA  *Private;
-
-  Private = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru);
+  EFI_STATUS          Status;
+  UINT8               HsTiming;
+  UINT8               HostCtrl1;
+  UINT8               HostCtrl2;
 
   Status = EmmcSwitchBusWidth (PciIo, PassThru, Slot, Rca, IsDdr, BusWidth);
   if (EFI_ERROR (Status)) {
@@ -785,21 +781,31 @@ EmmcSwitchToHighSpeed (
     return Status;
   }
 
+  //
+  // Clean UHS Mode Select field of Host Control 2 reigster before update
+  //
+  HostCtrl2 = (UINT8)~0x7;
+  Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  //
+  // Set UHS Mode Select field of Host Control 2 reigster to SDR12/25/50
+  //
   if (IsDdr) {
-    Timing = SdMmcMmcHsDdr;
+    HostCtrl2 = BIT2;
   } else if (ClockFreq == 52) {
-    Timing = SdMmcMmcHsSdr;
+    HostCtrl2 = BIT0;
   } else {
-    Timing = SdMmcMmcLegacy;
+    HostCtrl2 = 0;
   }
-
-  Status = SdMmcHcUhsSignaling (Private->ControllerHandle, PciIo, Slot, Timing);
+  Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
   if (EFI_ERROR (Status)) {
     return Status;
   }
 
   HsTiming = 1;
-  Status = EmmcSwitchClockFreq (PciIo, PassThru, Slot, Rca, HsTiming, Timing, ClockFreq);
+  Status = EmmcSwitchClockFreq (PciIo, PassThru, Slot, Rca, HsTiming, ClockFreq);
 
   return Status;
 }
@@ -831,13 +837,10 @@ EmmcSwitchToHS200 (
   IN UINT8                              BusWidth
   )
 {
-  EFI_STATUS               Status;
-  UINT8                    HsTiming;
-  UINT16                   ClockCtrl;
-  SD_MMC_BUS_MODE          Timing;
-  SD_MMC_HC_PRIVATE_DATA  *Private;
-
-  Private = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru);
+  EFI_STATUS          Status;
+  UINT8               HsTiming;
+  UINT8               HostCtrl2;
+  UINT16              ClockCtrl;
 
   if ((BusWidth != 4) && (BusWidth != 8)) {
     return EFI_INVALID_PARAMETER;
@@ -857,29 +860,60 @@ EmmcSwitchToHS200 (
   if (EFI_ERROR (Status)) {
     return Status;
   }
-
-  Timing = SdMmcMmcHs200;
-
-  Status = SdMmcHcUhsSignaling (Private->ControllerHandle, PciIo, Slot, Timing);
+  //
+  // Clean UHS Mode Select field of Host Control 2 reigster before update
+  //
+  HostCtrl2 = (UINT8)~0x7;
+  Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  //
+  // Set UHS Mode Select field of Host Control 2 reigster to SDR104
+  //
+  HostCtrl2 = BIT0 | BIT1;
+  Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
   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 (BhtHostPciSupport(PciIo)) {
+  	    Status = SdMmcHcWaitMmioSet (
+               PciIo,
+               Slot,
+               0x1cc,
+               sizeof (ClockCtrl),
+               BIT14,
+               BIT14,
+               SD_MMC_HC_GENERIC_TIMEOUT
              );
+  }
+  else { 
+    Status = SdMmcHcWaitMmioSet (
+               PciIo,
+               Slot,
+               SD_MMC_HC_CLOCK_CTRL,
+               sizeof (ClockCtrl),
+               BIT1,
+               BIT1,
+               SD_MMC_HC_GENERIC_TIMEOUT
+             );
+  }
   if (EFI_ERROR (Status)) {
     return Status;
   }
+
+  if (BhtHostPciSupport(PciIo)){    
+    //Wait 2nd Card Detect debounce Finished by wait twice of debounce max time
+    UINT32 value32;
+    while (1) {
+	  Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_PRESENT_STATE, TRUE, sizeof(value32), &value32);
+  	  if (((value32 >> 18) & 0x01) == ((value32 >> 16) & 0x01))
+	    break;
+    }
+  }
   //
   // Set SD Clock Enable in the Clock Control register to 1
   //
@@ -887,12 +921,33 @@ EmmcSwitchToHS200 (
   Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_CLOCK_CTRL, sizeof (ClockCtrl), &ClockCtrl);
 
   HsTiming = 2;
-  Status = EmmcSwitchClockFreq (PciIo, PassThru, Slot, Rca, HsTiming, Timing, ClockFreq);
+  Status = EmmcSwitchClockFreq (PciIo, PassThru, Slot, Rca, HsTiming, ClockFreq);
   if (EFI_ERROR (Status)) {
     return Status;
   }
 
-  Status = EmmcTuningClkForHs200 (PciIo, PassThru, Slot, BusWidth);
+  if (BhtHostPciSupport(PciIo)){
+    Status = SdMmcHcWaitMmioSet (
+	 		   PciIo,
+			   Slot,
+               0x1cc,
+			   sizeof (ClockCtrl),
+			   BIT11,
+			   BIT11,
+			   SD_MMC_CLOCK_STABLE_TIMEOUT
+			   );
+    if (EFI_ERROR(Status)) {
+	  DbgMsg(L"Wait Clock Stable timeout, ClockFreq=%d\n", ClockFreq);
+	  return Status;
+      }	  
+  }
+  
+  if (EFI_ERROR(Status)) {
+	DbgMsg(L"Emmc tuning failed\n");	
+	return Status;
+  } 
+  
+
 
   return Status;
 }
@@ -922,12 +977,9 @@ EmmcSwitchToHS400 (
   IN UINT32                             ClockFreq
   )
 {
-  EFI_STATUS                 Status;
-  UINT8                      HsTiming;
-  SD_MMC_BUS_MODE            Timing;
-  SD_MMC_HC_PRIVATE_DATA     *Private;
-
-  Private = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru);
+  EFI_STATUS          Status;
+  UINT8               HsTiming;
+  UINT8               HostCtrl2;
 
   Status = EmmcSwitchToHS200 (PciIo, PassThru, Slot, Rca, ClockFreq, 8);
   if (EFI_ERROR (Status)) {
@@ -937,7 +989,7 @@ EmmcSwitchToHS400 (
   // Set to Hight Speed timing and set the clock frequency to a value less than 52MHz.
   //
   HsTiming = 1;
-  Status = EmmcSwitchClockFreq (PciIo, PassThru, Slot, Rca, HsTiming, SdMmcMmcHsSdr, 52);
+  Status = EmmcSwitchClockFreq (PciIo, PassThru, Slot, Rca, HsTiming, 52);
   if (EFI_ERROR (Status)) {
     return Status;
   }
@@ -948,16 +1000,25 @@ EmmcSwitchToHS400 (
   if (EFI_ERROR (Status)) {
     return Status;
   }
-
-  Timing = SdMmcMmcHs400;
-
-  Status = SdMmcHcUhsSignaling (Private->ControllerHandle, PciIo, Slot, Timing);
+  //
+  // Clean UHS Mode Select field of Host Control 2 reigster before update
+  //
+  HostCtrl2 = (UINT8)~0x7;
+  Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  //
+  // Set UHS Mode Select field of Host Control 2 reigster to HS400
+  //
+  HostCtrl2 = BIT0 | BIT2;
+  Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
   if (EFI_ERROR (Status)) {
     return Status;
   }
 
   HsTiming = 3;
-  Status = EmmcSwitchClockFreq (PciIo, PassThru, Slot, Rca, HsTiming, Timing, ClockFreq);
+  Status = EmmcSwitchClockFreq (PciIo, PassThru, Slot, Rca, HsTiming, ClockFreq);
 
   return Status;
 }
@@ -1008,7 +1069,7 @@ EmmcSetBusMode (
     return Status;
   }
 
-  ASSERT (Private->BaseClkFreq[Slot] != 0);
+  ASSERT (Private->Capability[Slot].BaseClkFreq != 0);
   //
   // Check if the Host Controller support 8bits bus width.
   //
@@ -1080,6 +1141,42 @@ EmmcSetBusMode (
     // Execute HS200 timing switch procedure
     //
     Status = EmmcSwitchToHS200 (PciIo, PassThru, Slot, Rca, ClockFreq, BusWidth);
+	if (EFI_ERROR(Status)) {
+      if (BhtHostPciSupport(PciIo)) {
+	  	  UINT32 val32;
+		  DbgMsg(L"switch to HS200 200MHZ failed, freq decrease to 100MHz\n");
+		  ClockFreq = 100;
+
+		  SdMmcHcRwMmio (PciIo, Slot, 0x3C, TRUE, sizeof(val32), &val32);
+		  val32 &= ~BIT22;
+	      SdMmcHcRwMmio (PciIo, Slot, 0x3C, FALSE, sizeof(val32), &val32);
+		  val32 = (BIT26 | BIT25);
+	      SdMmcHcOrMmio (PciIo, Slot, 0x2C, sizeof(val32), &val32);
+		  
+		  Status = EmmcSwitchToHS200 (PciIo, PassThru, Slot, Rca, ClockFreq, BusWidth);
+		  if (EFI_ERROR(Status)) {
+		  	if (((ExtCsd.DeviceType & BIT1)  != 0) && (Private->Capability[Slot].HighSpeed != 0)) {
+	 		  DbgMsg(L"switch to HS200 100MHZ failed, mode decrease to HS 50MHz\n");
+
+		      HsTiming  = 1;
+              IsDdr     = FALSE;
+              ClockFreq = 52;
+			  Status = EmmcSwitchToHighSpeed (PciIo, PassThru, Slot, Rca, ClockFreq, IsDdr, BusWidth);
+		  	}
+			else if (((ExtCsd.DeviceType & BIT0)  != 0) && (Private->Capability[Slot].HighSpeed != 0)) {
+  			  DbgMsg(L"switch to HS200 100MHZ failed, mode decrease to HS 25MHz\n");
+
+			  HsTiming  = 1;
+              IsDdr     = FALSE;
+              ClockFreq = 26;
+			  Status = EmmcSwitchToHighSpeed (PciIo, PassThru, Slot, Rca, ClockFreq, IsDdr, BusWidth);
+			}			
+			else {
+	 		  DbgMsg(L"switch to HS200 100MHZ failed, but emmc chip didn't support hs mode\n");
+			}
+		  }
+		}
+    }
   } else {
     //
     // Execute High Speed timing switch procedure
diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.h b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.h
index 1bb701a503..0d14b53105 100644
--- a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.h
+++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.h
@@ -36,7 +36,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Protocol/DriverBinding.h>
 #include <Protocol/ComponentName.h>
 #include <Protocol/ComponentName2.h>
-#include <Protocol/SdMmcOverride.h>
 #include <Protocol/SdMmcPassThru.h>
 
 #include "SdMmcPciHci.h"
@@ -45,8 +44,6 @@ extern EFI_COMPONENT_NAME_PROTOCOL  gSdMmcPciHcComponentName;
 extern EFI_COMPONENT_NAME2_PROTOCOL gSdMmcPciHcComponentName2;
 extern EFI_DRIVER_BINDING_PROTOCOL  gSdMmcPciHcDriverBinding;
 
-extern EDKII_SD_MMC_OVERRIDE        *mOverride;
-
 #define SD_MMC_HC_PRIVATE_SIGNATURE  SIGNATURE_32 ('s', 'd', 't', 'f')
 
 #define SD_MMC_HC_PRIVATE_FROM_THIS(a) \
@@ -56,6 +53,7 @@ extern EDKII_SD_MMC_OVERRIDE        *mOverride;
 // Generic time out value, 1 microsecond as unit.
 //
 #define SD_MMC_HC_GENERIC_TIMEOUT     1 * 1000 * 1000
+#define SD_MMC_CLOCK_STABLE_TIMEOUT   3 * 1000
 
 //
 // SD/MMC async transfer timer interval, set by experience.
@@ -117,13 +115,8 @@ typedef struct {
   SD_MMC_HC_SLOT                      Slot[SD_MMC_HC_MAX_SLOT];
   SD_MMC_HC_SLOT_CAP                  Capability[SD_MMC_HC_MAX_SLOT];
   UINT64                              MaxCurrent[SD_MMC_HC_MAX_SLOT];
-  UINT16                              ControllerVersion[SD_MMC_HC_MAX_SLOT];
 
-  //
-  // Some controllers may require to override base clock frequency
-  // value stored in Capabilities Register 1.
-  //
-  UINT32                              BaseClkFreq[SD_MMC_HC_MAX_SLOT];
+  UINT32                              ControllerVersion;
 } SD_MMC_HC_PRIVATE_DATA;
 
 #define SD_MMC_HC_TRB_SIG             SIGNATURE_32 ('T', 'R', 'B', 'T')
@@ -150,8 +143,7 @@ typedef struct {
   BOOLEAN                             Started;
   UINT64                              Timeout;
 
-  SD_MMC_HC_ADMA_32_DESC_LINE         *Adma32Desc;
-  SD_MMC_HC_ADMA_64_DESC_LINE         *Adma64Desc;
+  SD_MMC_HC_ADMA_DESC_LINE            *AdmaDesc;
   EFI_PHYSICAL_ADDRESS                AdmaDescPhy;
   VOID                                *AdmaMap;
   UINT32                              AdmaPages;
@@ -792,37 +784,4 @@ SdCardIdentification (
   IN UINT8                              Slot
   );
 
-/**
-  Software reset the specified SD/MMC host controller.
-
-  @param[in] Private        A pointer to the SD_MMC_HC_PRIVATE_DATA instance.
-  @param[in] Slot           The slot number of the SD card to send the command to.
-
-  @retval EFI_SUCCESS       The software reset executes successfully.
-  @retval Others            The software reset fails.
-
-**/
-EFI_STATUS
-SdMmcHcReset (
-  IN SD_MMC_HC_PRIVATE_DATA *Private,
-  IN UINT8                  Slot
-  );
-
-/**
-  Initial SD/MMC host controller with lowest clock frequency, max power and max timeout value
-  at initialization.
-
-  @param[in] Private        A pointer to the SD_MMC_HC_PRIVATE_DATA instance.
-  @param[in] Slot           The slot number of the SD card to send the command to.
-
-  @retval EFI_SUCCESS       The host controller is initialized successfully.
-  @retval Others            The host controller isn't initialized successfully.
-
-**/
-EFI_STATUS
-SdMmcHcInitHost (
-  IN SD_MMC_HC_PRIVATE_DATA *Private,
-  IN UINT8                  Slot
-  );
-
 #endif
-- 
2.19.1.windows.1



^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] patch1_add_support_bh720_emmc_chip
  2019-01-28  7:35 [PATCH] patch1_add_support_bh720_emmc_chip Mike Li (WH)
@ 2019-01-29  2:31 ` Wu, Hao A
  0 siblings, 0 replies; 2+ messages in thread
From: Wu, Hao A @ 2019-01-29  2:31 UTC (permalink / raw)
  To: Mike Li (WH), edk2-devel@lists.01.org

> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of Mike
> Li (WH)
> Sent: Monday, January 28, 2019 3:36 PM
> To: edk2-devel@lists.01.org
> Subject: [edk2] [PATCH] patch1_add_support_bh720_emmc_chip

Hi,

Thanks for the contribution. I saw you sent out a total of 3 patches for
the SdMmcPciHcDxe driver, and they seem to be related.

Could you please help to do the below things that will help for reviewing
your patches:

* Rebase your changes to the latest mater branch of the edk2;
* Generate a patch series rather than separate patch files if you think
  they are related;
* Help to provide detailed information on the purpose of the patches or
  the issue you met in the log message of each commit.

You may get some help by referring:
https://github.com/tianocore/tianocore.github.io/wiki/EDK-II-Development-Process

Thanks in advance.

Best Regards,
Hao Wu

> 
> ---
>  .../Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c        | 253 ++++++++++++------
>  .../Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.h     |  47 +---
>  2 files changed, 178 insertions(+), 122 deletions(-)
> 
> diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c
> b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c
> index 4ef849fd09..ac79a2f791 100644
> --- a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c
> +++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c
> @@ -527,17 +527,35 @@ EmmcTuningClkForHs200 (
>    if (EFI_ERROR (Status)) {
>      return Status;
>    }
> +
> +  if(BhtHostPciSupport(PciIo)){
> +		//set data transfer with 4bit
> + 		Status = SdMmcHcSetBusWidth (PciIo, Slot, 4);
> +		//enable hardware tuning
> +		HostCtrl2 = (~0x10);
> +		Status = SdMmcHcAndMmio (PciIo, Slot, 0x110,sizeof
> (HostCtrl2), &HostCtrl2);
> +
> +	  Status = EmmcSendTuningBlk (PassThru, Slot, 4);
> +	  if (EFI_ERROR (Status)) {
> +		DEBUG ((DEBUG_ERROR, "EmmcTuningClkForHs200: Send
> tuning block fails with %r\n", Status));
> +		return Status;
> +	  }
> +
> +  }
>    //
>    // Ask the device to send a sequence of tuning blocks till the tuning procedure
> is done.
>    //
>    Retry = 0;
>    do {
> -    Status = EmmcSendTuningBlk (PassThru, Slot, BusWidth);
> -    if (EFI_ERROR (Status)) {
> -      DEBUG ((DEBUG_ERROR, "EmmcTuningClkForHs200: Send tuning block
> fails with %r\n", Status));
> -      return Status;
> -    }
> -
> +  	if(!BhtHostPciSupport(PciIo)){
> +	    Status = EmmcSendTuningBlk (PassThru, Slot, BusWidth);
> +	    if (EFI_ERROR (Status)) {
> +	      DEBUG ((DEBUG_ERROR, "EmmcTuningClkForHs200: Send tuning
> block fails with %r\n", Status));
> +	      return Status;
> +	    }
> +  	} else {
> +  		gBS->Stall(5000);
> +  	}
>      Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, TRUE,
> sizeof (HostCtrl2), &HostCtrl2);
>      if (EFI_ERROR (Status)) {
>        return Status;
> @@ -548,6 +566,10 @@ EmmcTuningClkForHs200 (
>      }
> 
>      if ((HostCtrl2 & (BIT6 | BIT7)) == BIT7) {
> +	  if(BhtHostPciSupport(PciIo)){
> +	  	//set data transfer with default
> +	  	Status = SdMmcHcSetBusWidth (PciIo, Slot, BusWidth);
> +	  	}
>        return EFI_SUCCESS;
>      }
>    } while (++Retry < 40);
> @@ -652,7 +674,6 @@ EmmcSwitchBusWidth (
>    @param[in] Slot           The slot number of the SD card to send the command
> to.
>    @param[in] Rca            The relative device address to be assigned.
>    @param[in] HsTiming       The value to be written to HS_TIMING field of
> EXT_CSD register.
> -  @param[in] Timing         The bus mode timing indicator.
>    @param[in] ClockFreq      The max clock frequency to be set, the unit is MHz.
> 
>    @retval EFI_SUCCESS       The operation is done correctly.
> @@ -666,7 +687,6 @@ EmmcSwitchClockFreq (
>    IN UINT8                              Slot,
>    IN UINT16                             Rca,
>    IN UINT8                              HsTiming,
> -  IN SD_MMC_BUS_MODE                    Timing,
>    IN UINT32                             ClockFreq
>    )
>  {
> @@ -708,28 +728,7 @@ EmmcSwitchClockFreq (
>    //
>    // Convert the clock freq unit from MHz to KHz.
>    //
> -  Status = SdMmcHcClockSupply (PciIo, Slot, ClockFreq * 1000, Private-
> >BaseClkFreq[Slot], Private->ControllerVersion[Slot]);
> -  if (EFI_ERROR (Status)) {
> -    return Status;
> -  }
> -
> -  if (mOverride != NULL && mOverride->NotifyPhase != NULL) {
> -    Status = mOverride->NotifyPhase (
> -                          Private->ControllerHandle,
> -                          Slot,
> -                          EdkiiSdMmcSwitchClockFreqPost,
> -                          &Timing
> -                          );
> -    if (EFI_ERROR (Status)) {
> -      DEBUG ((
> -        DEBUG_ERROR,
> -        "%a: SD/MMC switch clock freq post notifier callback failed - %r\n",
> -        __FUNCTION__,
> -        Status
> -        ));
> -      return Status;
> -    }
> -  }
> +  Status = SdMmcHcClockSupply (PciIo, Slot, ClockFreq * 1000, Private-
> >Capability[Slot]);
> 
>    return Status;
>  }
> @@ -764,13 +763,10 @@ EmmcSwitchToHighSpeed (
>    IN UINT8                              BusWidth
>    )
>  {
> -  EFI_STATUS              Status;
> -  UINT8                   HsTiming;
> -  UINT8                   HostCtrl1;
> -  SD_MMC_BUS_MODE         Timing;
> -  SD_MMC_HC_PRIVATE_DATA  *Private;
> -
> -  Private = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru);
> +  EFI_STATUS          Status;
> +  UINT8               HsTiming;
> +  UINT8               HostCtrl1;
> +  UINT8               HostCtrl2;
> 
>    Status = EmmcSwitchBusWidth (PciIo, PassThru, Slot, Rca, IsDdr, BusWidth);
>    if (EFI_ERROR (Status)) {
> @@ -785,21 +781,31 @@ EmmcSwitchToHighSpeed (
>      return Status;
>    }
> 
> +  //
> +  // Clean UHS Mode Select field of Host Control 2 reigster before update
> +  //
> +  HostCtrl2 = (UINT8)~0x7;
> +  Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof
> (HostCtrl2), &HostCtrl2);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +  //
> +  // Set UHS Mode Select field of Host Control 2 reigster to SDR12/25/50
> +  //
>    if (IsDdr) {
> -    Timing = SdMmcMmcHsDdr;
> +    HostCtrl2 = BIT2;
>    } else if (ClockFreq == 52) {
> -    Timing = SdMmcMmcHsSdr;
> +    HostCtrl2 = BIT0;
>    } else {
> -    Timing = SdMmcMmcLegacy;
> +    HostCtrl2 = 0;
>    }
> -
> -  Status = SdMmcHcUhsSignaling (Private->ControllerHandle, PciIo, Slot,
> Timing);
> +  Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof
> (HostCtrl2), &HostCtrl2);
>    if (EFI_ERROR (Status)) {
>      return Status;
>    }
> 
>    HsTiming = 1;
> -  Status = EmmcSwitchClockFreq (PciIo, PassThru, Slot, Rca, HsTiming, Timing,
> ClockFreq);
> +  Status = EmmcSwitchClockFreq (PciIo, PassThru, Slot, Rca, HsTiming,
> ClockFreq);
> 
>    return Status;
>  }
> @@ -831,13 +837,10 @@ EmmcSwitchToHS200 (
>    IN UINT8                              BusWidth
>    )
>  {
> -  EFI_STATUS               Status;
> -  UINT8                    HsTiming;
> -  UINT16                   ClockCtrl;
> -  SD_MMC_BUS_MODE          Timing;
> -  SD_MMC_HC_PRIVATE_DATA  *Private;
> -
> -  Private = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru);
> +  EFI_STATUS          Status;
> +  UINT8               HsTiming;
> +  UINT8               HostCtrl2;
> +  UINT16              ClockCtrl;
> 
>    if ((BusWidth != 4) && (BusWidth != 8)) {
>      return EFI_INVALID_PARAMETER;
> @@ -857,29 +860,60 @@ EmmcSwitchToHS200 (
>    if (EFI_ERROR (Status)) {
>      return Status;
>    }
> -
> -  Timing = SdMmcMmcHs200;
> -
> -  Status = SdMmcHcUhsSignaling (Private->ControllerHandle, PciIo, Slot,
> Timing);
> +  //
> +  // Clean UHS Mode Select field of Host Control 2 reigster before update
> +  //
> +  HostCtrl2 = (UINT8)~0x7;
> +  Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof
> (HostCtrl2), &HostCtrl2);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +  //
> +  // Set UHS Mode Select field of Host Control 2 reigster to SDR104
> +  //
> +  HostCtrl2 = BIT0 | BIT1;
> +  Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof
> (HostCtrl2), &HostCtrl2);
>    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 (BhtHostPciSupport(PciIo)) {
> +  	    Status = SdMmcHcWaitMmioSet (
> +               PciIo,
> +               Slot,
> +               0x1cc,
> +               sizeof (ClockCtrl),
> +               BIT14,
> +               BIT14,
> +               SD_MMC_HC_GENERIC_TIMEOUT
>               );
> +  }
> +  else {
> +    Status = SdMmcHcWaitMmioSet (
> +               PciIo,
> +               Slot,
> +               SD_MMC_HC_CLOCK_CTRL,
> +               sizeof (ClockCtrl),
> +               BIT1,
> +               BIT1,
> +               SD_MMC_HC_GENERIC_TIMEOUT
> +             );
> +  }
>    if (EFI_ERROR (Status)) {
>      return Status;
>    }
> +
> +  if (BhtHostPciSupport(PciIo)){
> +    //Wait 2nd Card Detect debounce Finished by wait twice of debounce max
> time
> +    UINT32 value32;
> +    while (1) {
> +	  Status = SdMmcHcRwMmio (PciIo, Slot,
> SD_MMC_HC_PRESENT_STATE, TRUE, sizeof(value32), &value32);
> +  	  if (((value32 >> 18) & 0x01) == ((value32 >> 16) & 0x01))
> +	    break;
> +    }
> +  }
>    //
>    // Set SD Clock Enable in the Clock Control register to 1
>    //
> @@ -887,12 +921,33 @@ EmmcSwitchToHS200 (
>    Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_CLOCK_CTRL, sizeof
> (ClockCtrl), &ClockCtrl);
> 
>    HsTiming = 2;
> -  Status = EmmcSwitchClockFreq (PciIo, PassThru, Slot, Rca, HsTiming, Timing,
> ClockFreq);
> +  Status = EmmcSwitchClockFreq (PciIo, PassThru, Slot, Rca, HsTiming,
> ClockFreq);
>    if (EFI_ERROR (Status)) {
>      return Status;
>    }
> 
> -  Status = EmmcTuningClkForHs200 (PciIo, PassThru, Slot, BusWidth);
> +  if (BhtHostPciSupport(PciIo)){
> +    Status = SdMmcHcWaitMmioSet (
> +	 		   PciIo,
> +			   Slot,
> +               0x1cc,
> +			   sizeof (ClockCtrl),
> +			   BIT11,
> +			   BIT11,
> +			   SD_MMC_CLOCK_STABLE_TIMEOUT
> +			   );
> +    if (EFI_ERROR(Status)) {
> +	  DbgMsg(L"Wait Clock Stable timeout, ClockFreq=%d\n", ClockFreq);
> +	  return Status;
> +      }
> +  }
> +
> +  if (EFI_ERROR(Status)) {
> +	DbgMsg(L"Emmc tuning failed\n");
> +	return Status;
> +  }
> +
> +
> 
>    return Status;
>  }
> @@ -922,12 +977,9 @@ EmmcSwitchToHS400 (
>    IN UINT32                             ClockFreq
>    )
>  {
> -  EFI_STATUS                 Status;
> -  UINT8                      HsTiming;
> -  SD_MMC_BUS_MODE            Timing;
> -  SD_MMC_HC_PRIVATE_DATA     *Private;
> -
> -  Private = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru);
> +  EFI_STATUS          Status;
> +  UINT8               HsTiming;
> +  UINT8               HostCtrl2;
> 
>    Status = EmmcSwitchToHS200 (PciIo, PassThru, Slot, Rca, ClockFreq, 8);
>    if (EFI_ERROR (Status)) {
> @@ -937,7 +989,7 @@ EmmcSwitchToHS400 (
>    // Set to Hight Speed timing and set the clock frequency to a value less than
> 52MHz.
>    //
>    HsTiming = 1;
> -  Status = EmmcSwitchClockFreq (PciIo, PassThru, Slot, Rca, HsTiming,
> SdMmcMmcHsSdr, 52);
> +  Status = EmmcSwitchClockFreq (PciIo, PassThru, Slot, Rca, HsTiming, 52);
>    if (EFI_ERROR (Status)) {
>      return Status;
>    }
> @@ -948,16 +1000,25 @@ EmmcSwitchToHS400 (
>    if (EFI_ERROR (Status)) {
>      return Status;
>    }
> -
> -  Timing = SdMmcMmcHs400;
> -
> -  Status = SdMmcHcUhsSignaling (Private->ControllerHandle, PciIo, Slot,
> Timing);
> +  //
> +  // Clean UHS Mode Select field of Host Control 2 reigster before update
> +  //
> +  HostCtrl2 = (UINT8)~0x7;
> +  Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof
> (HostCtrl2), &HostCtrl2);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +  //
> +  // Set UHS Mode Select field of Host Control 2 reigster to HS400
> +  //
> +  HostCtrl2 = BIT0 | BIT2;
> +  Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof
> (HostCtrl2), &HostCtrl2);
>    if (EFI_ERROR (Status)) {
>      return Status;
>    }
> 
>    HsTiming = 3;
> -  Status = EmmcSwitchClockFreq (PciIo, PassThru, Slot, Rca, HsTiming, Timing,
> ClockFreq);
> +  Status = EmmcSwitchClockFreq (PciIo, PassThru, Slot, Rca, HsTiming,
> ClockFreq);
> 
>    return Status;
>  }
> @@ -1008,7 +1069,7 @@ EmmcSetBusMode (
>      return Status;
>    }
> 
> -  ASSERT (Private->BaseClkFreq[Slot] != 0);
> +  ASSERT (Private->Capability[Slot].BaseClkFreq != 0);
>    //
>    // Check if the Host Controller support 8bits bus width.
>    //
> @@ -1080,6 +1141,42 @@ EmmcSetBusMode (
>      // Execute HS200 timing switch procedure
>      //
>      Status = EmmcSwitchToHS200 (PciIo, PassThru, Slot, Rca, ClockFreq,
> BusWidth);
> +	if (EFI_ERROR(Status)) {
> +      if (BhtHostPciSupport(PciIo)) {
> +	  	  UINT32 val32;
> +		  DbgMsg(L"switch to HS200 200MHZ failed, freq decrease to
> 100MHz\n");
> +		  ClockFreq = 100;
> +
> +		  SdMmcHcRwMmio (PciIo, Slot, 0x3C, TRUE, sizeof(val32),
> &val32);
> +		  val32 &= ~BIT22;
> +	      SdMmcHcRwMmio (PciIo, Slot, 0x3C, FALSE, sizeof(val32), &val32);
> +		  val32 = (BIT26 | BIT25);
> +	      SdMmcHcOrMmio (PciIo, Slot, 0x2C, sizeof(val32), &val32);
> +
> +		  Status = EmmcSwitchToHS200 (PciIo, PassThru, Slot, Rca,
> ClockFreq, BusWidth);
> +		  if (EFI_ERROR(Status)) {
> +		  	if (((ExtCsd.DeviceType & BIT1)  != 0) && (Private-
> >Capability[Slot].HighSpeed != 0)) {
> +	 		  DbgMsg(L"switch to HS200 100MHZ failed, mode
> decrease to HS 50MHz\n");
> +
> +		      HsTiming  = 1;
> +              IsDdr     = FALSE;
> +              ClockFreq = 52;
> +			  Status = EmmcSwitchToHighSpeed (PciIo, PassThru,
> Slot, Rca, ClockFreq, IsDdr, BusWidth);
> +		  	}
> +			else if (((ExtCsd.DeviceType & BIT0)  != 0) && (Private-
> >Capability[Slot].HighSpeed != 0)) {
> +  			  DbgMsg(L"switch to HS200 100MHZ failed, mode
> decrease to HS 25MHz\n");
> +
> +			  HsTiming  = 1;
> +              IsDdr     = FALSE;
> +              ClockFreq = 26;
> +			  Status = EmmcSwitchToHighSpeed (PciIo, PassThru,
> Slot, Rca, ClockFreq, IsDdr, BusWidth);
> +			}
> +			else {
> +	 		  DbgMsg(L"switch to HS200 100MHZ failed, but emmc
> chip didn't support hs mode\n");
> +			}
> +		  }
> +		}
> +    }
>    } else {
>      //
>      // Execute High Speed timing switch procedure
> diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.h
> b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.h
> index 1bb701a503..0d14b53105 100644
> --- a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.h
> +++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.h
> @@ -36,7 +36,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY
> KIND, EITHER EXPRESS OR IMPLIED.
>  #include <Protocol/DriverBinding.h>
>  #include <Protocol/ComponentName.h>
>  #include <Protocol/ComponentName2.h>
> -#include <Protocol/SdMmcOverride.h>
>  #include <Protocol/SdMmcPassThru.h>
> 
>  #include "SdMmcPciHci.h"
> @@ -45,8 +44,6 @@ extern EFI_COMPONENT_NAME_PROTOCOL
> gSdMmcPciHcComponentName;
>  extern EFI_COMPONENT_NAME2_PROTOCOL
> gSdMmcPciHcComponentName2;
>  extern EFI_DRIVER_BINDING_PROTOCOL  gSdMmcPciHcDriverBinding;
> 
> -extern EDKII_SD_MMC_OVERRIDE        *mOverride;
> -
>  #define SD_MMC_HC_PRIVATE_SIGNATURE  SIGNATURE_32 ('s', 'd', 't', 'f')
> 
>  #define SD_MMC_HC_PRIVATE_FROM_THIS(a) \
> @@ -56,6 +53,7 @@ extern EDKII_SD_MMC_OVERRIDE        *mOverride;
>  // Generic time out value, 1 microsecond as unit.
>  //
>  #define SD_MMC_HC_GENERIC_TIMEOUT     1 * 1000 * 1000
> +#define SD_MMC_CLOCK_STABLE_TIMEOUT   3 * 1000
> 
>  //
>  // SD/MMC async transfer timer interval, set by experience.
> @@ -117,13 +115,8 @@ typedef struct {
>    SD_MMC_HC_SLOT                      Slot[SD_MMC_HC_MAX_SLOT];
>    SD_MMC_HC_SLOT_CAP                  Capability[SD_MMC_HC_MAX_SLOT];
>    UINT64                              MaxCurrent[SD_MMC_HC_MAX_SLOT];
> -  UINT16                              ControllerVersion[SD_MMC_HC_MAX_SLOT];
> 
> -  //
> -  // Some controllers may require to override base clock frequency
> -  // value stored in Capabilities Register 1.
> -  //
> -  UINT32                              BaseClkFreq[SD_MMC_HC_MAX_SLOT];
> +  UINT32                              ControllerVersion;
>  } SD_MMC_HC_PRIVATE_DATA;
> 
>  #define SD_MMC_HC_TRB_SIG             SIGNATURE_32 ('T', 'R', 'B', 'T')
> @@ -150,8 +143,7 @@ typedef struct {
>    BOOLEAN                             Started;
>    UINT64                              Timeout;
> 
> -  SD_MMC_HC_ADMA_32_DESC_LINE         *Adma32Desc;
> -  SD_MMC_HC_ADMA_64_DESC_LINE         *Adma64Desc;
> +  SD_MMC_HC_ADMA_DESC_LINE            *AdmaDesc;
>    EFI_PHYSICAL_ADDRESS                AdmaDescPhy;
>    VOID                                *AdmaMap;
>    UINT32                              AdmaPages;
> @@ -792,37 +784,4 @@ SdCardIdentification (
>    IN UINT8                              Slot
>    );
> 
> -/**
> -  Software reset the specified SD/MMC host controller.
> -
> -  @param[in] Private        A pointer to the SD_MMC_HC_PRIVATE_DATA
> instance.
> -  @param[in] Slot           The slot number of the SD card to send the command
> to.
> -
> -  @retval EFI_SUCCESS       The software reset executes successfully.
> -  @retval Others            The software reset fails.
> -
> -**/
> -EFI_STATUS
> -SdMmcHcReset (
> -  IN SD_MMC_HC_PRIVATE_DATA *Private,
> -  IN UINT8                  Slot
> -  );
> -
> -/**
> -  Initial SD/MMC host controller with lowest clock frequency, max power and
> max timeout value
> -  at initialization.
> -
> -  @param[in] Private        A pointer to the SD_MMC_HC_PRIVATE_DATA
> instance.
> -  @param[in] Slot           The slot number of the SD card to send the command
> to.
> -
> -  @retval EFI_SUCCESS       The host controller is initialized successfully.
> -  @retval Others            The host controller isn't initialized successfully.
> -
> -**/
> -EFI_STATUS
> -SdMmcHcInitHost (
> -  IN SD_MMC_HC_PRIVATE_DATA *Private,
> -  IN UINT8                  Slot
> -  );
> -
>  #endif
> --
> 2.19.1.windows.1
> 
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2019-01-29  2:31 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-01-28  7:35 [PATCH] patch1_add_support_bh720_emmc_chip Mike Li (WH)
2019-01-29  2:31 ` Wu, Hao A

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox