[Linaro-uefi,2/2] Drivers/Mmc/DwEmmc: Adjust FIFO threshold

Message ID 1498791777-16122-2-git-send-email-jun.nie@linaro.org
State New
Headers show
Series
  • [Linaro-uefi,1/2] Drivers/Mmc/DwEmmc: limit max clock for platform
Related show

Commit Message

Jun Nie June 30, 2017, 3:02 a.m.
Adjust FIFO threshold according to FIFO depth. Skip
the adjustment if we do not have FIFO depth info.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jun Nie <jun.nie@linaro.org>
---
 Drivers/Mmc/DwEmmcDxe/DwEmmc.h      |  6 +++++
 Drivers/Mmc/DwEmmcDxe/DwEmmcDxe.c   | 54 +++++++++++++++++++++++++++++++++++++
 Drivers/Mmc/DwEmmcDxe/DwEmmcDxe.dec |  1 +
 Drivers/Mmc/DwEmmcDxe/DwEmmcDxe.inf |  1 +
 4 files changed, 62 insertions(+)

Comments

Jun Nie July 3, 2017, 4:04 a.m. | #1
2017-06-30 11:02 GMT+08:00 Jun Nie <jun.nie@linaro.org>:
> Adjust FIFO threshold according to FIFO depth. Skip
> the adjustment if we do not have FIFO depth info.

Just find that DwEmmc is already merged to mainline. I already post
patches to edk2 mainline in another thread list and please ignore this
thread.
Jun

>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Jun Nie <jun.nie@linaro.org>
> ---
>  Drivers/Mmc/DwEmmcDxe/DwEmmc.h      |  6 +++++
>  Drivers/Mmc/DwEmmcDxe/DwEmmcDxe.c   | 54 +++++++++++++++++++++++++++++++++++++
>  Drivers/Mmc/DwEmmcDxe/DwEmmcDxe.dec |  1 +
>  Drivers/Mmc/DwEmmcDxe/DwEmmcDxe.inf |  1 +
>  4 files changed, 62 insertions(+)
>
> diff --git a/Drivers/Mmc/DwEmmcDxe/DwEmmc.h b/Drivers/Mmc/DwEmmcDxe/DwEmmc.h
> index 055f1e0..2b41539 100644
> --- a/Drivers/Mmc/DwEmmcDxe/DwEmmc.h
> +++ b/Drivers/Mmc/DwEmmcDxe/DwEmmc.h
> @@ -38,7 +38,10 @@
>  #define DWEMMC_RINTSTS          ((UINT32)PcdGet32 (PcdDwEmmcDxeBaseAddress) + 0x044)
>  #define DWEMMC_STATUS           ((UINT32)PcdGet32 (PcdDwEmmcDxeBaseAddress) + 0x048)
>  #define DWEMMC_FIFOTH           ((UINT32)PcdGet32 (PcdDwEmmcDxeBaseAddress) + 0x04c)
> +#define DWEMMC_TCBCNT           ((UINT32)PcdGet32 (PcdDwEmmcDxeBaseAddress) + 0x05c)
> +#define DWEMMC_TBBCNT           ((UINT32)PcdGet32 (PcdDwEmmcDxeBaseAddress) + 0x060)
>  #define DWEMMC_DEBNCE           ((UINT32)PcdGet32 (PcdDwEmmcDxeBaseAddress) + 0x064)
> +#define DWEMMC_HCON             ((UINT32)PcdGet32 (PcdDwEmmcDxeBaseAddress) + 0x070)
>  #define DWEMMC_UHSREG           ((UINT32)PcdGet32 (PcdDwEmmcDxeBaseAddress) + 0x074)
>  #define DWEMMC_BMOD             ((UINT32)PcdGet32 (PcdDwEmmcDxeBaseAddress) + 0x080)
>  #define DWEMMC_DBADDR           ((UINT32)PcdGet32 (PcdDwEmmcDxeBaseAddress) + 0x088)
> @@ -47,6 +50,7 @@
>  #define DWEMMC_DSCADDR          ((UINT32)PcdGet32 (PcdDwEmmcDxeBaseAddress) + 0x094)
>  #define DWEMMC_BUFADDR          ((UINT32)PcdGet32 (PcdDwEmmcDxeBaseAddress) + 0x098)
>  #define DWEMMC_CARDTHRCTL       ((UINT32)PcdGet32 (PcdDwEmmcDxeBaseAddress) + 0X100)
> +#define DWEMMC_DATA             ((UINT32)PcdGet32 (PcdDwEmmcDxeBaseAddress) + 0X200)
>
>  #define CMD_UPDATE_CLK                          0x80202000
>  #define CMD_START_BIT                           (1 << 31)
> @@ -124,4 +128,6 @@
>  #define DWEMMC_CARD_RD_THR(x)                   ((x & 0xfff) << 16)
>  #define DWEMMC_CARD_RD_THR_EN                   (1 << 0)
>
> +#define DWEMMC_GET_HDATA_WIDTH(x)               (((x)>>7) & 0x7)
> +
>  #endif  // __DWEMMC_H__
> diff --git a/Drivers/Mmc/DwEmmcDxe/DwEmmcDxe.c b/Drivers/Mmc/DwEmmcDxe/DwEmmcDxe.c
> index c67dd0d..8299c13 100644
> --- a/Drivers/Mmc/DwEmmcDxe/DwEmmcDxe.c
> +++ b/Drivers/Mmc/DwEmmcDxe/DwEmmcDxe.c
> @@ -415,6 +415,59 @@ DwEmmcReceiveResponse (
>    return EFI_SUCCESS;
>  }
>
> +VOID DwEmmcAdjustFifoth(
> +  VOID
> +  )
> +{
> +  const UINT32 Mszs[] = {1, 4, 8, 16, 32, 64, 128, 256};
> +  UINT32 BlkSizeDepth, Fifoth, FifoWidth, FifoDepth;
> +  UINT32 BlkSize = 512, Msize = 0, RxWmark = 1, TxWmark, TxWmarkInvers;
> +  UINT32 Idx = ARRAY_SIZE(Mszs) - 1;
> +
> +  /* Skip FIFO adjustment if we do not have platform FIFO depth info */
> +  FifoDepth = PcdGet32 (PcdDwEmmcDxeFifoDepth);
> +  if (!FifoDepth)
> +    return;
> +
> +  TxWmark = FifoDepth / 2;
> +  TxWmarkInvers = FifoDepth - TxWmark;
> +
> +  FifoWidth = DWEMMC_GET_HDATA_WIDTH(MmioRead32 (DWEMMC_HCON));
> +  if (!FifoWidth) {
> +    FifoWidth = 2;
> +  } else if (FifoWidth == 2) {
> +    FifoWidth = 8;
> +  } else {
> +    FifoWidth = 4;
> +  }
> +
> +  BlkSizeDepth = BlkSize / FifoWidth;
> +
> +  /*
> +   * MSIZE is '1',
> +   * if BlkSize is not a multiple of the FIFO width
> +   */
> +  if (BlkSize % FifoWidth) {
> +    goto done;
> +  }
> +
> +  do {
> +    if (!((BlkSizeDepth % Mszs[Idx]) || (TxWmarkInvers % Mszs[Idx]))) {
> +      Msize = Idx;
> +      RxWmark = Mszs[Idx] - 1;
> +      break;
> +    }
> +  } while (--Idx > 0);
> +  /*
> +   * If Idx is '0', it won't be tried
> +   * Thus, initial values are uesed
> +   */
> +  done:
> +    Fifoth = DWEMMC_DMA_BURST_SIZE(Msize) | DWEMMC_FIFO_TWMARK(TxWmark)
> +             | DWEMMC_FIFO_RWMARK(RxWmark);
> +    MmioWrite32 (DWEMMC_FIFOTH, Fifoth);
> +  }
> +
>  EFI_STATUS
>  PrepareDmaData (
>    IN DWEMMC_IDMAC_DESCRIPTOR*    IdmacDesc,
> @@ -632,6 +685,7 @@ DwEmmcDxeInitialize (
>
>    Handle = NULL;
>
> +  DwEmmcAdjustFifoth();
>    gpIdmacDesc = (DWEMMC_IDMAC_DESCRIPTOR *)AllocatePages (DWEMMC_MAX_DESC_PAGES);
>    if (gpIdmacDesc == NULL) {
>      return EFI_BUFFER_TOO_SMALL;
> diff --git a/Drivers/Mmc/DwEmmcDxe/DwEmmcDxe.dec b/Drivers/Mmc/DwEmmcDxe/DwEmmcDxe.dec
> index 7b84a9a..503899c 100644
> --- a/Drivers/Mmc/DwEmmcDxe/DwEmmcDxe.dec
> +++ b/Drivers/Mmc/DwEmmcDxe/DwEmmcDxe.dec
> @@ -41,3 +41,4 @@
>    gDwEmmcDxeTokenSpaceGuid.PcdDwEmmcDxeBaseAddress|0x0|UINT32|0x00000001
>    gDwEmmcDxeTokenSpaceGuid.PcdDwEmmcDxeClockFrequencyInHz|0x0|UINT32|0x00000002
>    gDwEmmcDxeTokenSpaceGuid.PcdDwEmmcDxeMaxClockFrequencyInHz|0x0|UINT32|52000000
> +  gDwEmmcDxeTokenSpaceGuid.PcdDwEmmcDxeFifoDepth|0x0|UINT32|0
> diff --git a/Drivers/Mmc/DwEmmcDxe/DwEmmcDxe.inf b/Drivers/Mmc/DwEmmcDxe/DwEmmcDxe.inf
> index 99176f1..7872c52 100644
> --- a/Drivers/Mmc/DwEmmcDxe/DwEmmcDxe.inf
> +++ b/Drivers/Mmc/DwEmmcDxe/DwEmmcDxe.inf
> @@ -50,6 +50,7 @@
>    gDwEmmcDxeTokenSpaceGuid.PcdDwEmmcDxeBaseAddress
>    gDwEmmcDxeTokenSpaceGuid.PcdDwEmmcDxeClockFrequencyInHz
>    gDwEmmcDxeTokenSpaceGuid.PcdDwEmmcDxeMaxClockFrequencyInHz
> +  gDwEmmcDxeTokenSpaceGuid.PcdDwEmmcDxeFifoDepth
>
>  [Depex]
>    TRUE
> --
> 1.9.1
>

Patch

diff --git a/Drivers/Mmc/DwEmmcDxe/DwEmmc.h b/Drivers/Mmc/DwEmmcDxe/DwEmmc.h
index 055f1e0..2b41539 100644
--- a/Drivers/Mmc/DwEmmcDxe/DwEmmc.h
+++ b/Drivers/Mmc/DwEmmcDxe/DwEmmc.h
@@ -38,7 +38,10 @@ 
 #define DWEMMC_RINTSTS          ((UINT32)PcdGet32 (PcdDwEmmcDxeBaseAddress) + 0x044)
 #define DWEMMC_STATUS           ((UINT32)PcdGet32 (PcdDwEmmcDxeBaseAddress) + 0x048)
 #define DWEMMC_FIFOTH           ((UINT32)PcdGet32 (PcdDwEmmcDxeBaseAddress) + 0x04c)
+#define DWEMMC_TCBCNT           ((UINT32)PcdGet32 (PcdDwEmmcDxeBaseAddress) + 0x05c)
+#define DWEMMC_TBBCNT           ((UINT32)PcdGet32 (PcdDwEmmcDxeBaseAddress) + 0x060)
 #define DWEMMC_DEBNCE           ((UINT32)PcdGet32 (PcdDwEmmcDxeBaseAddress) + 0x064)
+#define DWEMMC_HCON             ((UINT32)PcdGet32 (PcdDwEmmcDxeBaseAddress) + 0x070)
 #define DWEMMC_UHSREG           ((UINT32)PcdGet32 (PcdDwEmmcDxeBaseAddress) + 0x074)
 #define DWEMMC_BMOD             ((UINT32)PcdGet32 (PcdDwEmmcDxeBaseAddress) + 0x080)
 #define DWEMMC_DBADDR           ((UINT32)PcdGet32 (PcdDwEmmcDxeBaseAddress) + 0x088)
@@ -47,6 +50,7 @@ 
 #define DWEMMC_DSCADDR          ((UINT32)PcdGet32 (PcdDwEmmcDxeBaseAddress) + 0x094)
 #define DWEMMC_BUFADDR          ((UINT32)PcdGet32 (PcdDwEmmcDxeBaseAddress) + 0x098)
 #define DWEMMC_CARDTHRCTL       ((UINT32)PcdGet32 (PcdDwEmmcDxeBaseAddress) + 0X100)
+#define DWEMMC_DATA             ((UINT32)PcdGet32 (PcdDwEmmcDxeBaseAddress) + 0X200)
 
 #define CMD_UPDATE_CLK                          0x80202000
 #define CMD_START_BIT                           (1 << 31)
@@ -124,4 +128,6 @@ 
 #define DWEMMC_CARD_RD_THR(x)                   ((x & 0xfff) << 16)
 #define DWEMMC_CARD_RD_THR_EN                   (1 << 0)
 
+#define DWEMMC_GET_HDATA_WIDTH(x)               (((x)>>7) & 0x7)
+
 #endif  // __DWEMMC_H__
diff --git a/Drivers/Mmc/DwEmmcDxe/DwEmmcDxe.c b/Drivers/Mmc/DwEmmcDxe/DwEmmcDxe.c
index c67dd0d..8299c13 100644
--- a/Drivers/Mmc/DwEmmcDxe/DwEmmcDxe.c
+++ b/Drivers/Mmc/DwEmmcDxe/DwEmmcDxe.c
@@ -415,6 +415,59 @@  DwEmmcReceiveResponse (
   return EFI_SUCCESS;
 }
 
+VOID DwEmmcAdjustFifoth(
+  VOID
+  )
+{
+  const UINT32 Mszs[] = {1, 4, 8, 16, 32, 64, 128, 256};
+  UINT32 BlkSizeDepth, Fifoth, FifoWidth, FifoDepth;
+  UINT32 BlkSize = 512, Msize = 0, RxWmark = 1, TxWmark, TxWmarkInvers;
+  UINT32 Idx = ARRAY_SIZE(Mszs) - 1;
+
+  /* Skip FIFO adjustment if we do not have platform FIFO depth info */
+  FifoDepth = PcdGet32 (PcdDwEmmcDxeFifoDepth);
+  if (!FifoDepth)
+    return;
+
+  TxWmark = FifoDepth / 2;
+  TxWmarkInvers = FifoDepth - TxWmark;
+
+  FifoWidth = DWEMMC_GET_HDATA_WIDTH(MmioRead32 (DWEMMC_HCON));
+  if (!FifoWidth) {
+    FifoWidth = 2;
+  } else if (FifoWidth == 2) {
+    FifoWidth = 8;
+  } else {
+    FifoWidth = 4;
+  }
+
+  BlkSizeDepth = BlkSize / FifoWidth;
+
+  /*
+   * MSIZE is '1',
+   * if BlkSize is not a multiple of the FIFO width
+   */
+  if (BlkSize % FifoWidth) {
+    goto done;
+  }
+
+  do {
+    if (!((BlkSizeDepth % Mszs[Idx]) || (TxWmarkInvers % Mszs[Idx]))) {
+      Msize = Idx;
+      RxWmark = Mszs[Idx] - 1;
+      break;
+    }
+  } while (--Idx > 0);
+  /*
+   * If Idx is '0', it won't be tried
+   * Thus, initial values are uesed
+   */
+  done:
+    Fifoth = DWEMMC_DMA_BURST_SIZE(Msize) | DWEMMC_FIFO_TWMARK(TxWmark)
+             | DWEMMC_FIFO_RWMARK(RxWmark);
+    MmioWrite32 (DWEMMC_FIFOTH, Fifoth);
+  }
+
 EFI_STATUS
 PrepareDmaData (
   IN DWEMMC_IDMAC_DESCRIPTOR*    IdmacDesc,
@@ -632,6 +685,7 @@  DwEmmcDxeInitialize (
 
   Handle = NULL;
 
+  DwEmmcAdjustFifoth();
   gpIdmacDesc = (DWEMMC_IDMAC_DESCRIPTOR *)AllocatePages (DWEMMC_MAX_DESC_PAGES);
   if (gpIdmacDesc == NULL) {
     return EFI_BUFFER_TOO_SMALL;
diff --git a/Drivers/Mmc/DwEmmcDxe/DwEmmcDxe.dec b/Drivers/Mmc/DwEmmcDxe/DwEmmcDxe.dec
index 7b84a9a..503899c 100644
--- a/Drivers/Mmc/DwEmmcDxe/DwEmmcDxe.dec
+++ b/Drivers/Mmc/DwEmmcDxe/DwEmmcDxe.dec
@@ -41,3 +41,4 @@ 
   gDwEmmcDxeTokenSpaceGuid.PcdDwEmmcDxeBaseAddress|0x0|UINT32|0x00000001
   gDwEmmcDxeTokenSpaceGuid.PcdDwEmmcDxeClockFrequencyInHz|0x0|UINT32|0x00000002
   gDwEmmcDxeTokenSpaceGuid.PcdDwEmmcDxeMaxClockFrequencyInHz|0x0|UINT32|52000000
+  gDwEmmcDxeTokenSpaceGuid.PcdDwEmmcDxeFifoDepth|0x0|UINT32|0
diff --git a/Drivers/Mmc/DwEmmcDxe/DwEmmcDxe.inf b/Drivers/Mmc/DwEmmcDxe/DwEmmcDxe.inf
index 99176f1..7872c52 100644
--- a/Drivers/Mmc/DwEmmcDxe/DwEmmcDxe.inf
+++ b/Drivers/Mmc/DwEmmcDxe/DwEmmcDxe.inf
@@ -50,6 +50,7 @@ 
   gDwEmmcDxeTokenSpaceGuid.PcdDwEmmcDxeBaseAddress
   gDwEmmcDxeTokenSpaceGuid.PcdDwEmmcDxeClockFrequencyInHz
   gDwEmmcDxeTokenSpaceGuid.PcdDwEmmcDxeMaxClockFrequencyInHz
+  gDwEmmcDxeTokenSpaceGuid.PcdDwEmmcDxeFifoDepth
 
 [Depex]
   TRUE