]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg/SdMmcPciHcDxe: Check SD's supported bus mode before switch
authorFeng Tian <feng.tian@intel.com>
Tue, 3 May 2016 01:57:55 +0000 (09:57 +0800)
committerFeng Tian <feng.tian@intel.com>
Fri, 6 May 2016 08:10:01 +0000 (16:10 +0800)
Before switch to a bus mode, we need check if the SD device supports
this bus mode.

Cc: Wu, Hao A <hao.a.wu@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Feng Tian <feng.tian@intel.com>
MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdDevice.c
MdeModulePkg/Bus/Sd/SdBlockIoPei/SdHci.c
MdeModulePkg/Bus/Sd/SdBlockIoPei/SdHci.h

index b4e2c5843053ae1ab7c9a435f2ccbfc995675519..8193f4eb2f44c89bcb6dd7759a4005ef1e50a712 100644 (file)
@@ -591,6 +591,7 @@ SdCardSetBusWidth (
   @param[in]  DriveStrength The value for drive length group.\r
   @param[in]  PowerLimit    The value for power limit group.\r
   @param[in]  Mode          Switch or check function.\r
+  @param[out] SwitchResp    The return switch function status.\r
 \r
   @retval EFI_SUCCESS       The operation is done correctly.\r
   @retval Others            The operation fails.\r
@@ -598,13 +599,14 @@ SdCardSetBusWidth (
 **/\r
 EFI_STATUS\r
 SdCardSwitch (\r
-  IN EFI_SD_MMC_PASS_THRU_PROTOCOL      *PassThru,\r
-  IN UINT8                              Slot,\r
-  IN UINT8                              AccessMode,\r
-  IN UINT8                              CommandSystem,\r
-  IN UINT8                              DriveStrength,\r
-  IN UINT8                              PowerLimit,\r
-  IN BOOLEAN                            Mode\r
+  IN     EFI_SD_MMC_PASS_THRU_PROTOCOL  *PassThru,\r
+  IN     UINT8                          Slot,\r
+  IN     UINT8                          AccessMode,\r
+  IN     UINT8                          CommandSystem,\r
+  IN     UINT8                          DriveStrength,\r
+  IN     UINT8                          PowerLimit,\r
+  IN     BOOLEAN                        Mode,\r
+     OUT UINT8                          *SwitchResp\r
   )\r
 {\r
   EFI_SD_MMC_COMMAND_BLOCK              SdMmcCmdBlk;\r
@@ -612,7 +614,6 @@ SdCardSwitch (
   EFI_SD_MMC_PASS_THRU_COMMAND_PACKET   Packet;\r
   EFI_STATUS                            Status;\r
   UINT32                                ModeValue;\r
-  UINT8                                 Data[64];\r
 \r
   ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));\r
   ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));\r
@@ -631,8 +632,8 @@ SdCardSwitch (
                                 ((DriveStrength & 0xF) << 8) | ((DriveStrength & 0xF) << 12) | \\r
                                 ModeValue;\r
 \r
-  Packet.InDataBuffer     = Data;\r
-  Packet.InTransferLength = sizeof (Data);\r
+  Packet.InDataBuffer     = SwitchResp;\r
+  Packet.InTransferLength = 64;\r
 \r
   Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);\r
 \r
@@ -891,6 +892,7 @@ SdCardSetBusMode (
   UINT8                        AccessMode;\r
   UINT8                        HostCtrl1;\r
   UINT8                        HostCtrl2;\r
+  UINT8                        SwitchResp[64];\r
   SD_MMC_HC_PRIVATE_DATA       *Private;\r
 \r
   Private = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru);\r
@@ -908,32 +910,46 @@ SdCardSetBusMode (
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
-\r
   //\r
-  // Calculate supported bus speed/bus width/clock frequency.\r
+  // Get the supported bus speed from SWITCH cmd return data group #1.\r
+  //\r
+  Status = SdCardSwitch (PassThru, Slot, 0xF, 0xF, 0xF, 0xF, FALSE, SwitchResp);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  //\r
+  // Calculate supported bus speed/bus width/clock frequency by host and device capability.\r
   //\r
   ClockFreq = 0;\r
-  if (S18A && (Capability->Sdr104 != 0)) {\r
+  if (S18A && (Capability->Sdr104 != 0) && ((SwitchResp[13] & BIT3) != 0)) {\r
     ClockFreq = 208;\r
     AccessMode = 3;\r
-  } else if (S18A && (Capability->Sdr50 != 0)) {\r
+  } else if (S18A && (Capability->Sdr50 != 0) && ((SwitchResp[13] & BIT2) != 0)) {\r
     ClockFreq = 100;\r
     AccessMode = 2;\r
-  } else if (S18A && (Capability->Ddr50 != 0)) {\r
+  } else if (S18A && (Capability->Ddr50 != 0) && ((SwitchResp[13] & BIT4) != 0)) {\r
     ClockFreq = 50;\r
     AccessMode = 4;\r
-  } else {\r
+  } else if ((SwitchResp[13] & BIT1) != 0) {\r
     ClockFreq = 50;\r
     AccessMode = 1;\r
+  } else {\r
+    ClockFreq = 25;\r
+    AccessMode = 0;\r
   }\r
 \r
-  DEBUG ((EFI_D_INFO, "SdCardSetBusMode: AccessMode %d ClockFreq %d BusWidth %d\n", AccessMode, ClockFreq, BusWidth));\r
-\r
-  Status = SdCardSwitch (PassThru, Slot, AccessMode, 0, 0, 0, TRUE);\r
+  Status = SdCardSwitch (PassThru, Slot, AccessMode, 0xF, 0xF, 0xF, TRUE, SwitchResp);\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
 \r
+  if ((SwitchResp[16] & 0xF) != AccessMode) {\r
+    DEBUG ((EFI_D_ERROR, "SdCardSetBusMode: Switch to AccessMode %d ClockFreq %d BusWidth %d fails! The Switch response is 0x%1x\n", AccessMode, ClockFreq, BusWidth, SwitchResp[16] & 0xF));\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  DEBUG ((EFI_D_INFO, "SdCardSetBusMode: Switch to AccessMode %d ClockFreq %d BusWidth %d\n", AccessMode, ClockFreq, BusWidth));\r
+\r
   //\r
   // Set to Hight Speed timing\r
   //\r
index bb6df8fd9f3b5f0805ba6198734c3a757d69f7de..c251fbecb334978390f086dac31f4f47a8f86d0a 100644 (file)
@@ -2192,6 +2192,7 @@ SdPeimSetBusWidth (
   @param[in]  DriveStrength The value for drive length group.\r
   @param[in]  PowerLimit    The value for power limit group.\r
   @param[in]  Mode          Switch or check function.\r
+  @param[out] SwitchResp    The return switch function status.\r
 \r
   @retval EFI_SUCCESS       The operation is done correctly.\r
   @retval Others            The operation fails.\r
@@ -2199,12 +2200,13 @@ SdPeimSetBusWidth (
 **/\r
 EFI_STATUS\r
 SdPeimSwitch (\r
-  IN SD_PEIM_HC_SLOT        *Slot,\r
-  IN UINT8                  AccessMode,\r
-  IN UINT8                  CommandSystem,\r
-  IN UINT8                  DriveStrength,\r
-  IN UINT8                  PowerLimit,\r
-  IN BOOLEAN                Mode\r
+  IN     SD_PEIM_HC_SLOT              *Slot,\r
+  IN     UINT8                        AccessMode,\r
+  IN     UINT8                        CommandSystem,\r
+  IN     UINT8                        DriveStrength,\r
+  IN     UINT8                        PowerLimit,\r
+  IN     BOOLEAN                      Mode,\r
+     OUT UINT8                        *SwitchResp\r
   )\r
 {\r
   SD_COMMAND_BLOCK                    SdCmdBlk;\r
@@ -2212,7 +2214,6 @@ SdPeimSwitch (
   SD_COMMAND_PACKET                   Packet;\r
   EFI_STATUS                          Status;\r
   UINT32                              ModeValue;\r
-  UINT8                               Data[64];\r
 \r
   ZeroMem (&SdCmdBlk, sizeof (SdCmdBlk));\r
   ZeroMem (&SdStatusBlk, sizeof (SdStatusBlk));\r
@@ -2230,8 +2231,8 @@ SdPeimSwitch (
   SdCmdBlk.CommandArgument = (AccessMode & 0xF) | ((PowerLimit & 0xF) << 4) | \\r
                              ((DriveStrength & 0xF) << 8) | ((DriveStrength & 0xF) << 12) | \\r
                              ModeValue;\r
-  Packet.InDataBuffer     = Data;\r
-  Packet.InTransferLength = sizeof (Data);\r
+  Packet.InDataBuffer     = SwitchResp;\r
+  Packet.InTransferLength = 64;\r
 \r
   Status = SdPeimExecCmd (Slot, &Packet);\r
 \r
@@ -2617,6 +2618,7 @@ SdPeimSetBusMode (
   UINT8                        AccessMode;\r
   UINT8                        HostCtrl1;\r
   UINT8                        HostCtrl2;\r
+  UINT8                        SwitchResp[64];\r
 \r
   Status = SdPeimGetCsd (Slot, Rca, &Slot->Csd);\r
   if (EFI_ERROR (Status)) {\r
@@ -2643,31 +2645,45 @@ SdPeimSetBusMode (
   }\r
 \r
   //\r
-  // Calculate supported bus speed/bus width/clock frequency.\r
+  // Get the supported bus speed from SWITCH cmd return data group #1.\r
+  //\r
+  Status = SdPeimSwitch (Slot, 0xF, 0xF, 0xF, 0xF, FALSE, SwitchResp);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  //\r
+  // Calculate supported bus speed/bus width/clock frequency by host and device capability.\r
   //\r
   ClockFreq = 0;\r
-  if (S18a && (Capability.Sdr104 != 0)) {\r
+  if (S18a && (Capability.Sdr104 != 0) && ((SwitchResp[13] & BIT3) != 0)) {\r
     ClockFreq = 208;\r
     AccessMode = 3;\r
-  } else if (S18a && (Capability.Sdr50 != 0)) {\r
+  } else if (S18a && (Capability.Sdr50 != 0) && ((SwitchResp[13] & BIT2) != 0)) {\r
     ClockFreq = 100;\r
     AccessMode = 2;\r
-  } else if (S18a && (Capability.Ddr50 != 0)) {\r
+  } else if (S18a && (Capability.Ddr50 != 0) && ((SwitchResp[13] & BIT4) != 0)) {\r
     ClockFreq = 50;\r
     AccessMode = 4;\r
-  } else {\r
+  } else if ((SwitchResp[13] & BIT1) != 0) {\r
     ClockFreq = 50;\r
     AccessMode = 1;\r
+  } else {\r
+    ClockFreq = 25;\r
+    AccessMode = 0;\r
   }\r
 \r
-  DEBUG ((EFI_D_INFO, "AccessMode %d ClockFreq %d BusWidth %d\n", AccessMode, ClockFreq, BusWidth));\r
+  DEBUG ((EFI_D_INFO, "SdPeimSetBusMode: AccessMode %d ClockFreq %d BusWidth %d\n", AccessMode, ClockFreq, BusWidth));\r
 \r
-  Status = SdPeimSwitch (Slot, AccessMode, 0, 0, 0, TRUE);\r
+  Status = SdPeimSwitch (Slot, AccessMode, 0xF, 0xF, 0xF, TRUE, SwitchResp);\r
   if (EFI_ERROR (Status)) {\r
     DEBUG ((EFI_D_ERROR, "SdPeimSetBusMode: SdPeimSwitch fails with %r\n", Status));\r
     return Status;\r
   }\r
 \r
+  if ((SwitchResp[16] & 0xF) != AccessMode) {\r
+    DEBUG ((EFI_D_ERROR, "SdPeimSetBusMode: SdPeimSwitch to AccessMode %d ClockFreq %d BusWidth %d fails! The Switch response is 0x%1x\n", AccessMode, ClockFreq, BusWidth, SwitchResp[16] & 0xF));\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
   //\r
   // Set to Hight Speed timing\r
   //\r
index 2f443045b7e0e51a8b3eed2e03a0796db9df139f..b7c0dbc9f32587b87e709b0c64b9d42b498c03c2 100644 (file)
@@ -254,6 +254,7 @@ SdPeimHcInitHost (
   @param[in]  DriveStrength The value for drive length group.\r
   @param[in]  PowerLimit    The value for power limit group.\r
   @param[in]  Mode          Switch or check function.\r
+  @param[out] SwitchResp    The return switch function status.\r
 \r
   @retval EFI_SUCCESS       The operation is done correctly.\r
   @retval Others            The operation fails.\r
@@ -261,12 +262,13 @@ SdPeimHcInitHost (
 **/\r
 EFI_STATUS\r
 SdPeimSwitch (\r
-  IN SD_PEIM_HC_SLOT        *Slot,\r
-  IN UINT8                  AccessMode,\r
-  IN UINT8                  CommandSystem,\r
-  IN UINT8                  DriveStrength,\r
-  IN UINT8                  PowerLimit,\r
-  IN BOOLEAN                Mode\r
+  IN     SD_PEIM_HC_SLOT              *Slot,\r
+  IN     UINT8                        AccessMode,\r
+  IN     UINT8                        CommandSystem,\r
+  IN     UINT8                        DriveStrength,\r
+  IN     UINT8                        PowerLimit,\r
+  IN     BOOLEAN                      Mode,\r
+     OUT UINT8                        *SwitchResp\r
   );\r
 \r
 /**\r