]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Sd/SdBlockIoPei/SdHci.c
MdeModulePkg/SdMmcPciHcDxe: Using PIO rather than DMA for clock tuning
[mirror_edk2.git] / MdeModulePkg / Bus / Sd / SdBlockIoPei / SdHci.c
index 48e4ae68caa7d9bf2d0e29d45149ecac874a3cd3..3f327f8b393552f0cdb1545a784de22c71306d79 100644 (file)
@@ -1032,26 +1032,27 @@ SdPeimCreateTrb (
     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 = SdNoData;\r
-  } else if (Capability.Adma2 != 0) {\r
-    Trb->Mode = SdAdmaMode;\r
-    Status = BuildAdmaDescTable (Trb);\r
-    if (EFI_ERROR (Status)) {\r
-      goto Error;\r
-    }\r
-  } else if (Capability.Sdma != 0) {\r
-    Trb->Mode = SdSdmaMode;\r
-  } else {\r
+  if (Packet->SdCmdBlk->CommandIndex == SD_SEND_TUNING_BLOCK) {\r
     Trb->Mode = SdPioMode;\r
+  } else {\r
+    if (Trb->DataLen == 0) {\r
+      Trb->Mode = SdNoData;\r
+    } else if (Capability.Adma2 != 0) {\r
+      Trb->Mode = SdAdmaMode;\r
+      Status = BuildAdmaDescTable (Trb);\r
+      if (EFI_ERROR (Status)) {\r
+        goto Error;\r
+      }\r
+    } else if (Capability.Sdma != 0) {\r
+      Trb->Mode = SdSdmaMode;\r
+    } else {\r
+      Trb->Mode = SdPioMode;\r
+    }\r
   }\r
-\r
   return Trb;\r
 \r
 Error:\r
@@ -1111,9 +1112,6 @@ SdPeimCheckTrbEnv (
     // the Present State register to be 0\r
     //\r
     PresentState = BIT0 | BIT1;\r
-    if (Packet->SdCmdBlk->CommandIndex == SD_SEND_TUNING_BLOCK) {\r
-      PresentState = BIT0;\r
-    }\r
   } else {\r
     //\r
     // Wait Command Inhibit (CMD) in the Present State register\r
@@ -1273,7 +1271,13 @@ SdPeimExecTrb (
     return Status;\r
   }\r
 \r
-  BlkCount = (UINT16)(Trb->DataLen / Trb->BlockSize);\r
+  BlkCount = 0;\r
+  if (Trb->Mode != SdNoData) {\r
+    //\r
+    // Calcuate Block Count.\r
+    //\r
+    BlkCount = (UINT16)(Trb->DataLen / Trb->BlockSize);\r
+  }\r
   Status   = SdPeimHcRwMmio (Bar + SD_HC_BLK_COUNT, FALSE, sizeof (BlkCount), &BlkCount);\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
@@ -1293,9 +1297,12 @@ SdPeimExecTrb (
     if (Trb->Read) {\r
       TransMode |= BIT4;\r
     }\r
-    if (BlkCount != 0) {\r
+    if (BlkCount > 1) {\r
       TransMode |= BIT5 | BIT1;\r
     }\r
+    //\r
+    // SD memory card needs to use AUTO CMD12 feature.\r
+    //\r
     if (BlkCount > 1) {\r
       TransMode |= BIT2;\r
     }\r
@@ -1368,6 +1375,7 @@ SdPeimCheckTrbResult (
   UINT32                              SdmaAddr;\r
   UINT8                               Index;\r
   UINT8                               SwReset;\r
+  UINT32                              PioLength;\r
 \r
   SwReset = 0;\r
   Packet  = Trb->Packet;\r
@@ -1500,8 +1508,26 @@ SdPeimCheckTrbResult (
   }\r
 \r
   if (Packet->SdCmdBlk->CommandIndex == SD_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
+      SdPeimHcRwMmio (Bar + SD_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
+        SdPeimHcRwMmio (Bar + SD_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