ArmPlatformPkg/PL180MciDxe: update for identifying SD
authorHaojian Zhuang <haojian.zhuang@linaro.org>
Wed, 23 Nov 2016 13:36:23 +0000 (21:36 +0800)
committerArd Biesheuvel <ard.biesheuvel@linaro.org>
Thu, 24 Nov 2016 16:29:03 +0000 (16:29 +0000)
When CMD6 & ACMD51 are added into identifying SD process, PL180
should also support CMD6 & ACMD51. Otherwise, it will hang when
system tries to read expected data.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Tested-by: Ryan Harkin <ryan.harkin@linaro.org>
ArmPlatformPkg/Drivers/PL180MciDxe/PL180Mci.c

index 5526aaca92b3653d1929854f7606c7f26de5d233..f8e4cc087cfd501cfcf0836a24c8dd31baefeae0 100644 (file)
@@ -63,11 +63,6 @@ MciIsReadOnly (
   return (MmioRead32 (FixedPcdGet32 (PcdPL180SysMciRegAddress)) & SYS_MCI_WPROT);\r
 }\r
 \r
-#if 0\r
-//Note: This function has been commented out because it is not used yet.\r
-//      This function could be used to remove the hardcoded BlockLen used\r
-//      in MciPrepareDataPath\r
-\r
 // Convert block size to 2^n\r
 STATIC\r
 UINT32\r
@@ -87,7 +82,6 @@ GetPow2BlockLen (
 \r
   return Pow2BlockLen;\r
 }\r
-#endif\r
 \r
 VOID\r
 MciPrepareDataPath (\r
@@ -126,6 +120,23 @@ MciSendCommand (
     MciPrepareDataPath (MCI_DATACTL_CARD_TO_CONT);\r
   } else if ((MmcCmd == MMC_CMD24) || (MmcCmd == MMC_CMD20)) {\r
     MciPrepareDataPath (MCI_DATACTL_CONT_TO_CARD);\r
+  } else if (MmcCmd == MMC_CMD6) {\r
+    MmioWrite32 (MCI_DATA_TIMER_REG, 0xFFFFFFF);\r
+    MmioWrite32 (MCI_DATA_LENGTH_REG, 64);\r
+#ifndef USE_STREAM\r
+    MmioWrite32 (MCI_DATA_CTL_REG, MCI_DATACTL_ENABLE | MCI_DATACTL_CARD_TO_CONT | GetPow2BlockLen (64));\r
+#else\r
+    MmioWrite32 (MCI_DATA_CTL_REG, MCI_DATACTL_ENABLE | MCI_DATACTL_CARD_TO_CONT | MCI_DATACTL_STREAM_TRANS);\r
+#endif\r
+  } else if (MmcCmd == MMC_ACMD51) {\r
+    MmioWrite32 (MCI_DATA_TIMER_REG, 0xFFFFFFF);\r
+    /* SCR register is 8 bytes long. */\r
+    MmioWrite32 (MCI_DATA_LENGTH_REG, 8);\r
+#ifndef USE_STREAM\r
+    MmioWrite32 (MCI_DATA_CTL_REG, MCI_DATACTL_ENABLE | MCI_DATACTL_CARD_TO_CONT | GetPow2BlockLen (8));\r
+#else\r
+    MmioWrite32 (MCI_DATA_CTL_REG, MCI_DATACTL_ENABLE | MCI_DATACTL_CARD_TO_CONT | MCI_DATACTL_STREAM_TRANS);\r
+#endif\r
   }\r
 \r
   // Create Command for PL180\r
@@ -223,7 +234,11 @@ MciReadBlockData (
 \r
   // Read data from the RX FIFO\r
   Loop   = 0;\r
-  Finish = MMCI0_BLOCKLEN / 4;\r
+  if (Length < MMCI0_BLOCKLEN) {\r
+    Finish = Length / 4;\r
+  } else {\r
+    Finish = MMCI0_BLOCKLEN / 4;\r
+  }\r
 \r
   // Raise the TPL at the highest level to disable Interrupts.\r
   Tpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r