]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EmbeddedPkg/Drivers/DwEmmcDxe/DwEmmcDxe.c
EmbeddedPkg/DwEmmc: Adjust FIFO threshold
[mirror_edk2.git] / EmbeddedPkg / Drivers / DwEmmcDxe / DwEmmcDxe.c
index bb26b69fd16b89ff89aea72af95191ebb59224e5..0437e30f940f00ea60a86b12308a5f93a13000c9 100644 (file)
@@ -415,6 +415,47 @@ DwEmmcReceiveResponse (
   return EFI_SUCCESS;\r
 }\r
 \r
+VOID\r
+DwEmmcAdjustFifoThreshold (\r
+  VOID\r
+  )\r
+{\r
+  /* DMA multiple transaction size map to reg value as array index */\r
+  CONST UINT32 BurstSize[] = {1, 4, 8, 16, 32, 64, 128, 256};\r
+  UINT32 BlkDepthInFifo, FifoThreshold, FifoWidth, FifoDepth;\r
+  UINT32 BlkSize = DWEMMC_BLOCK_SIZE, Idx = 0, RxWatermark = 1, TxWatermark, TxWatermarkInvers;\r
+\r
+  /* Skip FIFO adjustment if we do not have platform FIFO depth info */\r
+  FifoDepth = PcdGet32 (PcdDwEmmcDxeFifoDepth);\r
+  if (!FifoDepth) {\r
+    return;\r
+  }\r
+\r
+  TxWatermark = FifoDepth / 2;\r
+  TxWatermarkInvers = FifoDepth - TxWatermark;\r
+\r
+  FifoWidth = DWEMMC_GET_HDATA_WIDTH (MmioRead32 (DWEMMC_HCON));\r
+  if (!FifoWidth) {\r
+    FifoWidth = 2;\r
+  } else if (FifoWidth == 2) {\r
+    FifoWidth = 8;\r
+  } else {\r
+    FifoWidth = 4;\r
+  }\r
+\r
+  BlkDepthInFifo = BlkSize / FifoWidth;\r
+\r
+  Idx = ARRAY_SIZE (BurstSize) - 1;\r
+  while (Idx && ((BlkDepthInFifo % BurstSize[Idx]) || (TxWatermarkInvers % BurstSize[Idx]))) {\r
+    Idx--;\r
+  }\r
+\r
+  RxWatermark = BurstSize[Idx] - 1;\r
+  FifoThreshold = DWEMMC_DMA_BURST_SIZE (Idx) | DWEMMC_FIFO_TWMARK (TxWatermark)\r
+           | DWEMMC_FIFO_RWMARK (RxWatermark);\r
+  MmioWrite32 (DWEMMC_FIFOTH, FifoThreshold);\r
+}\r
+\r
 EFI_STATUS\r
 PrepareDmaData (\r
   IN DWEMMC_IDMAC_DESCRIPTOR*    IdmacDesc,\r
@@ -633,6 +674,7 @@ DwEmmcDxeInitialize (
 \r
   Handle = NULL;\r
 \r
+  DwEmmcAdjustFifoThreshold ();\r
   gpIdmacDesc = (DWEMMC_IDMAC_DESCRIPTOR *)AllocatePages (DWEMMC_MAX_DESC_PAGES);\r
   if (gpIdmacDesc == NULL) {\r
     return EFI_BUFFER_TOO_SMALL;\r