]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcHci.c
MdeModulePkg/SdMmcPciHcDxe: Using PIO rather than DMA for clock tuning
[mirror_edk2.git] / MdeModulePkg / Bus / Sd / EmmcBlockIoPei / EmmcHci.c
index 569a86a6e14af2652d183ab76157db5973acb7a2..3ffc4779d948f0a111798f4121e670381b2dfeb0 100644 (file)
@@ -1032,26 +1032,27 @@ EmmcPeimCreateTrb (
     goto Error;\r
   }\r
 \r
-  if ((Trb->DataLen % Trb->BlockSize) != 0) {\r
-    if (Trb->DataLen < Trb->BlockSize) {\r
-      Trb->BlockSize = (UINT16)Trb->DataLen;\r
-    }\r
+  if (Trb->DataLen < Trb->BlockSize) {\r
+    Trb->BlockSize = (UINT16)Trb->DataLen;\r
   }\r
 \r
-  if (Trb->DataLen == 0) {\r
-    Trb->Mode = EmmcNoData;\r
-  } else if (Capability.Adma2 != 0) {\r
-    Trb->Mode = EmmcAdmaMode;\r
-    Status = BuildAdmaDescTable (Trb);\r
-    if (EFI_ERROR (Status)) {\r
-      goto Error;\r
-    }\r
-  } else if (Capability.Sdma != 0) {\r
-    Trb->Mode = EmmcSdmaMode;\r
-  } else {\r
+  if (Packet->EmmcCmdBlk->CommandIndex == EMMC_SEND_TUNING_BLOCK) {\r
     Trb->Mode = EmmcPioMode;\r
+  } else {\r
+    if (Trb->DataLen == 0) {\r
+      Trb->Mode = EmmcNoData;\r
+    } else if (Capability.Adma2 != 0) {\r
+      Trb->Mode = EmmcAdmaMode;\r
+      Status = BuildAdmaDescTable (Trb);\r
+      if (EFI_ERROR (Status)) {\r
+        goto Error;\r
+      }\r
+    } else if (Capability.Sdma != 0) {\r
+      Trb->Mode = EmmcSdmaMode;\r
+    } else {\r
+      Trb->Mode = EmmcPioMode;\r
+    }\r
   }\r
-\r
   return Trb;\r
 \r
 Error:\r
@@ -1111,9 +1112,6 @@ EmmcPeimCheckTrbEnv (
     // the Present State register to be 0\r
     //\r
     PresentState = BIT0 | BIT1;\r
-    if (Packet->EmmcCmdBlk->CommandIndex == EMMC_SEND_TUNING_BLOCK) {\r
-      PresentState = BIT0;\r
-    }\r
   } else {\r
     //\r
     // Wait Command Inhibit (CMD) in the Present State register\r
@@ -1273,7 +1271,14 @@ EmmcPeimExecTrb (
     return Status;\r
   }\r
 \r
-  BlkCount = (UINT16)(Trb->DataLen / Trb->BlockSize);\r
+  BlkCount = 0;\r
+  if (Trb->Mode != EmmcNoData) {\r
+    //\r
+    // Calcuate Block Count.\r
+    //\r
+    BlkCount = (UINT16)(Trb->DataLen / Trb->BlockSize);\r
+  }\r
+\r
   Status   = EmmcPeimHcRwMmio (Bar + EMMC_HC_BLK_COUNT, FALSE, sizeof (BlkCount), &BlkCount);\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
@@ -1293,7 +1298,7 @@ EmmcPeimExecTrb (
     if (Trb->Read) {\r
       TransMode |= BIT4;\r
     }\r
-    if (BlkCount != 0) {\r
+    if (BlkCount > 1) {\r
       TransMode |= BIT5 | BIT1;\r
     }\r
   }\r
@@ -1365,6 +1370,7 @@ EmmcPeimCheckTrbResult (
   UINT32                              SdmaAddr;\r
   UINT8                               Index;\r
   UINT8                               SwReset;\r
+  UINT32                              PioLength;\r
 \r
   SwReset = 0;\r
   Packet  = Trb->Packet;\r
@@ -1497,8 +1503,26 @@ EmmcPeimCheckTrbResult (
   }\r
 \r
   if (Packet->EmmcCmdBlk->CommandIndex == EMMC_SEND_TUNING_BLOCK) {\r
-    Status = EFI_SUCCESS;\r
-    goto Done;\r
+    //\r
+    // When performing tuning procedure (Execute Tuning is set to 1) through PIO mode,\r
+    // wait Buffer Read Ready bit of Normal Interrupt Status Register to be 1.\r
+    // Refer to SD Host Controller Simplified Specification 3.0 figure 2-29 for details.\r
+    //\r
+    if ((IntStatus & BIT5) == BIT5) {\r
+      //\r
+      // Clear Buffer Read Ready interrupt at first.\r
+      //\r
+      IntStatus = BIT5;\r
+      EmmcPeimHcRwMmio (Bar + EMMC_HC_NOR_INT_STS, FALSE, sizeof (IntStatus), &IntStatus);\r
+      //\r
+      // Read data out from Buffer Port register\r
+      //\r
+      for (PioLength = 0; PioLength < Trb->DataLen; PioLength += 4) {\r
+        EmmcPeimHcRwMmio (Bar + EMMC_HC_BUF_DAT_PORT, TRUE, 4, (UINT8*)Trb->Data + PioLength);\r
+      }\r
+      Status = EFI_SUCCESS;\r
+      goto Done;\r
+    }\r
   }\r
 \r
   Status = EFI_NOT_READY;\r