@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
**/\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
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
((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
do {\r
Status = SdCardSendTuningBlk (PassThru, Slot);\r
if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "SdCardSendTuningBlk: Send tuning block fails with %r\n", Status));\r
+ DEBUG ((DEBUG_ERROR, "SdCardSendTuningBlk: Send tuning block fails with %r\n", Status));\r
return Status;\r
}\r
\r
return Status;\r
}\r
\r
- if ((HostCtrl2 & (BIT6 | BIT7)) == BIT7) {\r
+ if ((HostCtrl2 & (BIT6 | BIT7)) == 0) {\r
break;\r
}\r
+ if ((HostCtrl2 & (BIT6 | BIT7)) == BIT7) {\r
+ return EFI_SUCCESS;\r
+ }\r
} while (++Retry < 40);\r
\r
- if (Retry == 40) {\r
- Status = EFI_TIMEOUT;\r
- DEBUG ((EFI_D_ERROR, "SdCardTuningClock: Send tuning block exceeds 40 times\n"));\r
+ DEBUG ((DEBUG_ERROR, "SdCardTuningClock: Send tuning block fails at %d times with HostCtrl2 %02x\n", Retry, HostCtrl2));\r
+ //\r
+ // Abort the tuning procedure and reset the tuning circuit.\r
+ //\r
+ HostCtrl2 = (UINT8)~(BIT6 | BIT7);\r
+ Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
}\r
-\r
- return Status;\r
+ return EFI_DEVICE_ERROR;\r
}\r
\r
/**\r
\r
Status = SdCardSetBusWidth (PassThru, Slot, Rca, BusWidth);\r
if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "SdCardSwitchBusWidth: Switch to bus width %d fails with %r\n", BusWidth, Status));\r
+ DEBUG ((DEBUG_ERROR, "SdCardSwitchBusWidth: Switch to bus width %d fails with %r\n", BusWidth, Status));\r
return Status;\r
}\r
\r
Status = SdCardSendStatus (PassThru, Slot, Rca, &DevStatus);\r
if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "SdCardSwitchBusWidth: Send status fails with %r\n", Status));\r
+ DEBUG ((DEBUG_ERROR, "SdCardSwitchBusWidth: Send status fails with %r\n", Status));\r
return Status;\r
}\r
//\r
// Check the switch operation is really successful or not.\r
//\r
if ((DevStatus >> 16) != 0) {\r
- DEBUG ((EFI_D_ERROR, "SdCardSwitchBusWidth: The switch operation fails as DevStatus is 0x%08x\n", DevStatus));\r
+ DEBUG ((DEBUG_ERROR, "SdCardSwitchBusWidth: The switch operation fails as DevStatus is 0x%08x\n", DevStatus));\r
return EFI_DEVICE_ERROR;\r
}\r
\r
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
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 ((DEBUG_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 ((DEBUG_INFO, "SdCardSetBusMode: Switch to AccessMode %d ClockFreq %d BusWidth %d\n", AccessMode, ClockFreq, BusWidth));\r
+\r
//\r
// Set to Hight Speed timing\r
//\r
UINT8 PowerCtrl;\r
UINT32 PresentState;\r
UINT8 HostCtrl2;\r
+ UINTN Retry;\r
\r
PciIo = Private->PciIo;\r
PassThru = &Private->PassThru;\r
//\r
Status = SdCardReset (PassThru, Slot);\r
if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_INFO, "SdCardIdentification: Executing Cmd0 fails with %r\n", Status));\r
+ DEBUG ((DEBUG_INFO, "SdCardIdentification: Executing Cmd0 fails with %r\n", Status));\r
return Status;\r
}\r
//\r
//\r
Status = SdCardVoltageCheck (PassThru, Slot, 0x1, 0xFF);\r
if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_INFO, "SdCardIdentification: Executing Cmd8 fails with %r\n", Status));\r
+ DEBUG ((DEBUG_INFO, "SdCardIdentification: Executing Cmd8 fails with %r\n", Status));\r
return Status;\r
}\r
//\r
//\r
Status = SdioSendOpCond (PassThru, Slot, 0, FALSE);\r
if (!EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_INFO, "SdCardIdentification: Found SDIO device, ignore it as we don't support\n"));\r
+ DEBUG ((DEBUG_INFO, "SdCardIdentification: Found SDIO device, ignore it as we don't support\n"));\r
return EFI_DEVICE_ERROR;\r
}\r
//\r
//\r
Status = SdCardSendOpCond (PassThru, Slot, 0, 0, FALSE, FALSE, FALSE, &Ocr);\r
if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_INFO, "SdCardIdentification: Executing SdCardSendOpCond fails with %r\n", Status));\r
+ DEBUG ((DEBUG_INFO, "SdCardIdentification: Executing SdCardSendOpCond fails with %r\n", Status));\r
return EFI_DEVICE_ERROR;\r
}\r
\r
// Note here we only support the cards complied with SD physical\r
// layer simplified spec version 2.0 and version 3.0 and above.\r
//\r
+ Ocr = 0;\r
+ Retry = 0;\r
do {\r
Status = SdCardSendOpCond (PassThru, Slot, 0, Ocr, S18r, Xpc, TRUE, &Ocr);\r
if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "SdCardIdentification: SdCardSendOpCond fails with %r Ocr %x, S18r %x, Xpc %x\n", Status, Ocr, S18r, Xpc));\r
+ DEBUG ((DEBUG_ERROR, "SdCardIdentification: SdCardSendOpCond fails with %r Ocr %x, S18r %x, Xpc %x\n", Status, Ocr, S18r, Xpc));\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ if (Retry++ == 100) {\r
+ DEBUG ((DEBUG_ERROR, "SdCardIdentification: SdCardSendOpCond fails too many times\n"));\r
return EFI_DEVICE_ERROR;\r
}\r
+ gBS->Stall(10 * 1000);\r
} while ((Ocr & BIT31) == 0);\r
\r
//\r
((Ocr & BIT24) != 0)) {\r
Status = SdCardVoltageSwitch (PassThru, Slot);\r
if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "SdCardIdentification: Executing SdCardVoltageSwitch fails with %r\n", Status));\r
+ DEBUG ((DEBUG_ERROR, "SdCardIdentification: Executing SdCardVoltageSwitch fails with %r\n", Status));\r
Status = EFI_DEVICE_ERROR;\r
goto Error;\r
} else {\r
\r
SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_PRESENT_STATE, TRUE, sizeof (PresentState), &PresentState);\r
if (((PresentState >> 20) & 0xF) != 0) {\r
- DEBUG ((EFI_D_ERROR, "SdCardIdentification: SwitchVoltage fails with PresentState = 0x%x\n", PresentState));\r
+ DEBUG ((DEBUG_ERROR, "SdCardIdentification: SwitchVoltage fails with PresentState = 0x%x\n", PresentState));\r
Status = EFI_DEVICE_ERROR;\r
goto Error;\r
}\r
\r
SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, TRUE, sizeof (HostCtrl2), &HostCtrl2);\r
if ((HostCtrl2 & BIT3) == 0) {\r
- DEBUG ((EFI_D_ERROR, "SdCardIdentification: SwitchVoltage fails with HostCtrl2 = 0x%x\n", HostCtrl2));\r
+ DEBUG ((DEBUG_ERROR, "SdCardIdentification: SwitchVoltage fails with HostCtrl2 = 0x%x\n", HostCtrl2));\r
Status = EFI_DEVICE_ERROR;\r
goto Error;\r
}\r
\r
SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_PRESENT_STATE, TRUE, sizeof (PresentState), &PresentState);\r
if (((PresentState >> 20) & 0xF) != 0xF) {\r
- DEBUG ((EFI_D_ERROR, "SdCardIdentification: SwitchVoltage fails with PresentState = 0x%x, It should be 0xF\n", PresentState));\r
+ DEBUG ((DEBUG_ERROR, "SdCardIdentification: SwitchVoltage fails with PresentState = 0x%x, It should be 0xF\n", PresentState));\r
Status = EFI_DEVICE_ERROR;\r
goto Error;\r
}\r
}\r
- DEBUG ((EFI_D_INFO, "SdCardIdentification: Switch to 1.8v signal voltage success\n"));\r
+ DEBUG ((DEBUG_INFO, "SdCardIdentification: Switch to 1.8v signal voltage success\n"));\r
}\r
\r
Status = SdCardAllSendCid (PassThru, Slot);\r
if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "SdCardIdentification: Executing SdCardAllSendCid fails with %r\n", Status));\r
+ DEBUG ((DEBUG_ERROR, "SdCardIdentification: Executing SdCardAllSendCid fails with %r\n", Status));\r
return Status;\r
}\r
\r
Status = SdCardSetRca (PassThru, Slot, &Rca);\r
if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "SdCardIdentification: Executing SdCardSetRca fails with %r\n", Status));\r
+ DEBUG ((DEBUG_ERROR, "SdCardIdentification: Executing SdCardSetRca fails with %r\n", Status));\r
return Status;\r
}\r
//\r
// Enter Data Tranfer Mode.\r
//\r
- DEBUG ((EFI_D_INFO, "SdCardIdentification: Found a SD device at slot [%d]\n", Slot));\r
+ DEBUG ((DEBUG_INFO, "SdCardIdentification: Found a SD device at slot [%d]\n", Slot));\r
Private->Slot[Slot].CardType = SdCardType;\r
\r
Status = SdCardSetBusMode (PciIo, PassThru, Slot, Rca, ((Ocr & BIT24) != 0));\r