This changes is by adding 50ms delay during voltage swithcing from 3.3V to 1.8V, plus adding a while loop for 3.3V checking and retrying.
Signed-off-by: Aiman Rosli <muhammad.aiman.ro...@intel.com> --- MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdDevice.c | 273 ++++++++++-------- 1 file changed, 146 insertions(+), 127 deletions(-) diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdDevice.c b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdDevice.c index 662f9f483c..e91251d457 100644 --- a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdDevice.c +++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdDevice.c @@ -1213,167 +1213,186 @@ SdCardIdentification ( UINT32 PresentState; UINT8 HostCtrl2; UINTN Retry; + BOOLEAN Force3p3v; + + Force3p3v = FALSE; PciIo = Private->PciIo; PassThru = &Private->PassThru; - // - // 1. Send Cmd0 to the device - // - Status = SdCardReset (PassThru, Slot); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_INFO, "SdCardIdentification: Executing Cmd0 fails with %r\n", Status)); - return Status; - } - - // - // 2. Send Cmd8 to the device - // - Status = SdCardVoltageCheck (PassThru, Slot, 0x1, 0xFF); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_INFO, "SdCardIdentification: Executing Cmd8 fails with %r\n", Status)); - return Status; - } - - // - // 3. Send SDIO Cmd5 to the device to the SDIO device OCR register. - // - Status = SdioSendOpCond (PassThru, Slot, 0, FALSE); - if (!EFI_ERROR (Status)) { - DEBUG ((DEBUG_INFO, "SdCardIdentification: Found SDIO device, ignore it as we don't support\n")); - return EFI_DEVICE_ERROR; - } - // - // 4. Send Acmd41 with voltage window 0 to the device - // - Status = SdCardSendOpCond (PassThru, Slot, 0, 0, FALSE, FALSE, FALSE, &Ocr); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_INFO, "SdCardIdentification: Executing SdCardSendOpCond fails with %r\n", Status)); - return EFI_DEVICE_ERROR; - } - - if (Private->Capability[Slot].Voltage33 != 0) { + do { // - // Support 3.3V + // 1. Send Cmd0 to the device // - MaxCurrent = ((UINT32)Private->MaxCurrent[Slot] & 0xFF) * 4; - } else if (Private->Capability[Slot].Voltage30 != 0) { + Status = SdCardReset (PassThru, Slot); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "SdCardIdentification: Executing Cmd0 fails with %r\n", Status)); + return Status; + } + // - // Support 3.0V + // 2. Send Cmd8 to the device // - MaxCurrent = (((UINT32)Private->MaxCurrent[Slot] >> 8) & 0xFF) * 4; - } else if (Private->Capability[Slot].Voltage18 != 0) { + Status = SdCardVoltageCheck (PassThru, Slot, 0x1, 0xFF); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "SdCardIdentification: Executing Cmd8 fails with %r\n", Status)); + return Status; + } + // - // Support 1.8V + // 3. Send SDIO Cmd5 to the device to the SDIO device OCR register. // - MaxCurrent = (((UINT32)Private->MaxCurrent[Slot] >> 16) & 0xFF) * 4; - } else { - ASSERT (FALSE); - return EFI_DEVICE_ERROR; - } - - if (MaxCurrent >= 150) { - Xpc = TRUE; - } else { - Xpc = FALSE; - } - - Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_CTRL_VER, TRUE, sizeof (ControllerVer), &ControllerVer); - if (EFI_ERROR (Status)) { - return Status; - } - - if (((ControllerVer & 0xFF) >= SD_MMC_HC_CTRL_VER_300) && - ((ControllerVer & 0xFF) <= SD_MMC_HC_CTRL_VER_420)) - { - S18r = TRUE; - } else if (((ControllerVer & 0xFF) == SD_MMC_HC_CTRL_VER_100) || ((ControllerVer & 0xFF) == SD_MMC_HC_CTRL_VER_200)) { - S18r = FALSE; - } else { - ASSERT (FALSE); - return EFI_UNSUPPORTED; - } + Status = SdioSendOpCond (PassThru, Slot, 0, FALSE); + if (!EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "SdCardIdentification: Found SDIO device, ignore it as we don't support\n")); + return EFI_DEVICE_ERROR; + } - // - // 5. Repeatly send Acmd41 with supply voltage window to the device. - // Note here we only support the cards complied with SD physical - // layer simplified spec version 2.0 and version 3.0 and above. - // - Ocr = 0; - Retry = 0; - do { - Status = SdCardSendOpCond (PassThru, Slot, 0, Ocr, S18r, Xpc, TRUE, &Ocr); + // + // 4. Send Acmd41 with voltage window 0 to the device + // + Status = SdCardSendOpCond (PassThru, Slot, 0, 0, FALSE, FALSE, FALSE, &Ocr); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "SdCardIdentification: SdCardSendOpCond fails with %r Ocr %x, S18r %x, Xpc %x\n", Status, Ocr, S18r, Xpc)); + DEBUG ((DEBUG_INFO, "SdCardIdentification: Executing SdCardSendOpCond fails with %r\n", Status)); return EFI_DEVICE_ERROR; } - if (Retry++ == 100) { - DEBUG ((DEBUG_ERROR, "SdCardIdentification: SdCardSendOpCond fails too many times\n")); + if (Private->Capability[Slot].Voltage33 != 0) { + // + // Support 3.3V + // + MaxCurrent = ((UINT32)Private->MaxCurrent[Slot] & 0xFF) * 4; + } else if (Private->Capability[Slot].Voltage30 != 0) { + // + // Support 3.0V + // + MaxCurrent = (((UINT32)Private->MaxCurrent[Slot] >> 8) & 0xFF) * 4; + } else if (Private->Capability[Slot].Voltage18 != 0) { + // + // Support 1.8V + // + MaxCurrent = (((UINT32)Private->MaxCurrent[Slot] >> 16) & 0xFF) * 4; + } else { + ASSERT (FALSE); return EFI_DEVICE_ERROR; } - gBS->Stall (10 * 1000); - } while ((Ocr & BIT31) == 0); + if (MaxCurrent >= 150) { + Xpc = TRUE; + } else { + Xpc = FALSE; + } - // - // 6. If the S18A bit is set and the Host Controller supports 1.8V signaling - // (One of support bits is set to 1: SDR50, SDR104 or DDR50 in the - // Capabilities register), switch its voltage to 1.8V. - // - if (((Private->Capability[Slot].Sdr50 != 0) || - (Private->Capability[Slot].Sdr104 != 0) || - (Private->Capability[Slot].Ddr50 != 0)) && - ((Ocr & BIT24) != 0)) - { - Status = SdCardVoltageSwitch (PassThru, Slot); + Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_CTRL_VER, TRUE, sizeof (ControllerVer), &ControllerVer); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "SdCardIdentification: Executing SdCardVoltageSwitch fails with %r\n", Status)); - Status = EFI_DEVICE_ERROR; - goto Error; + return Status; + } + + if (((ControllerVer & 0xFF) >= SD_MMC_HC_CTRL_VER_300) && + ((ControllerVer & 0xFF) <= SD_MMC_HC_CTRL_VER_420)) + { + S18r = TRUE; + } else if (((ControllerVer & 0xFF) == SD_MMC_HC_CTRL_VER_100) || ((ControllerVer & 0xFF) == SD_MMC_HC_CTRL_VER_200)) { + S18r = FALSE; } else { - Status = SdMmcHcStopClock (PciIo, Slot); + ASSERT (FALSE); + return EFI_UNSUPPORTED; + } + + // + // 1.8V had failed in the previous run, forcing a retry with 3.3V instead + // + if (Force3p3v == TRUE) { + S18r = FALSE; + Force3p3v = FALSE; + } + + // + // 5. Repeatly send Acmd41 with supply voltage window to the device. + // Note here we only support the cards complied with SD physical + // layer simplified spec version 2.0 and version 3.0 and above. + // + Ocr = 0; + Retry = 0; + do { + Status = SdCardSendOpCond (PassThru, Slot, 0, Ocr, S18r, Xpc, TRUE, &Ocr); if (EFI_ERROR (Status)) { - Status = EFI_DEVICE_ERROR; - goto Error; + DEBUG ((DEBUG_ERROR, "SdCardIdentification: SdCardSendOpCond fails with %r Ocr %x, S18r %x, Xpc %x\n", Status, Ocr, S18r, Xpc)); + return EFI_DEVICE_ERROR; } - SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_PRESENT_STATE, TRUE, sizeof (PresentState), &PresentState); - if (((PresentState >> 20) & 0xF) != 0) { - DEBUG ((DEBUG_ERROR, "SdCardIdentification: SwitchVoltage fails with PresentState = 0x%x\n", PresentState)); - Status = EFI_DEVICE_ERROR; - goto Error; + if (Retry++ == 100) { + DEBUG ((DEBUG_ERROR, "SdCardIdentification: SdCardSendOpCond fails too many times\n")); + return EFI_DEVICE_ERROR; } - HostCtrl2 = BIT3; - SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2); - - gBS->Stall (5000); + gBS->Stall (10 * 1000); + } while ((Ocr & BIT31) == 0); - SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, TRUE, sizeof (HostCtrl2), &HostCtrl2); - if ((HostCtrl2 & BIT3) == 0) { - DEBUG ((DEBUG_ERROR, "SdCardIdentification: SwitchVoltage fails with HostCtrl2 = 0x%x\n", HostCtrl2)); + // + // 6. If the S18A bit is set and the Host Controller supports 1.8V signaling + // (One of support bits is set to 1: SDR50, SDR104 or DDR50 in the + // Capabilities register), switch its voltage to 1.8V. + // + if (((Private->Capability[Slot].Sdr50 != 0) || + (Private->Capability[Slot].Sdr104 != 0) || + (Private->Capability[Slot].Ddr50 != 0)) && + ((Ocr & BIT24) != 0)) + { + Status = SdCardVoltageSwitch (PassThru, Slot); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "SdCardIdentification: Executing SdCardVoltageSwitch fails with %r\n", Status)); Status = EFI_DEVICE_ERROR; goto Error; - } + } else { + Status = SdMmcHcStopClock (PciIo, Slot); + if (EFI_ERROR (Status)) { + Status = EFI_DEVICE_ERROR; + goto Error; + } - Status = SdMmcHcStartSdClock (PciIo, Slot); - if (EFI_ERROR (Status)) { - goto Error; - } + SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_PRESENT_STATE, TRUE, sizeof (PresentState), &PresentState); + if (((PresentState >> 20) & 0xF) != 0) { + DEBUG ((DEBUG_ERROR, "SdCardIdentification: SwitchVoltage fails with PresentState = 0x%x\n", PresentState)); + Status = EFI_DEVICE_ERROR; + goto Error; + } - gBS->Stall (1000); + HostCtrl2 = BIT3; + SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2); - SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_PRESENT_STATE, TRUE, sizeof (PresentState), &PresentState); - if (((PresentState >> 20) & 0xF) != 0xF) { - DEBUG ((DEBUG_ERROR, "SdCardIdentification: SwitchVoltage fails with PresentState = 0x%x, It should be 0xF\n", PresentState)); - Status = EFI_DEVICE_ERROR; - goto Error; + gBS->Stall (5000); + + SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, TRUE, sizeof (HostCtrl2), &HostCtrl2); + if ((HostCtrl2 & BIT3) == 0) { + DEBUG ((DEBUG_ERROR, "SdCardIdentification: SwitchVoltage fails with HostCtrl2 = 0x%x\n", HostCtrl2)); + Status = EFI_DEVICE_ERROR; + goto Error; + } + + Status = SdMmcHcStartSdClock (PciIo, Slot); + if (EFI_ERROR (Status)) { + goto Error; + } + + // Workaround to add a delay of 100ms in order for clock to stabilize before turning on the SD card again. + gBS->Stall (50000); + + gBS->Stall (1000); + + SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_PRESENT_STATE, TRUE, sizeof (PresentState), &PresentState); + if (((PresentState >> 20) & 0xF) != 0xF) { + DEBUG ((DEBUG_ERROR, "SdCardIdentification: SwitchVoltage fails with PresentState = 0x%x, It should be 0xF\n", PresentState)); + Status = SdMmcHcReset (Private, Slot); + Status = SdMmcHcInitHost (Private, Slot); + Force3p3v = TRUE; + DEBUG ((DEBUG_ERROR, "SdCardIdentification: Switching to 1.8V had failed in the previous run, forcing a retry with 3.3V instead\n")); + } } - } - DEBUG ((DEBUG_INFO, "SdCardIdentification: Switch to 1.8v signal voltage success\n")); - } + DEBUG ((DEBUG_INFO, "SdCardIdentification: Switch to 1.8v signal voltage success\n")); + } + } while (Force3p3v); Status = SdCardAllSendCid (PassThru, Slot); if (EFI_ERROR (Status)) { -- 2.34.1.windows.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#85723): https://edk2.groups.io/g/devel/message/85723 Mute This Topic: https://groups.io/mt/88477724/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-