Files
nix-config/packages/edk2/patches/0001-SD-fixup.patch
2026-01-07 21:28:20 -06:00

258 lines
8.8 KiB
Diff

From cea64af8854a7785e6ac3ecdcc47f46779940b21 Mon Sep 17 00:00:00 2001
From: mattp <svidasultaresurge@gmail.com>
Date: Fri, 18 Jul 2025 08:23:43 -0400
Subject: [PATCH] SD fixup
---
MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdDevice.c | 32 ++++----
.../Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c | 77 +++++++++++++++++++
.../Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.h | 28 ++++++-
MdeModulePkg/Include/Protocol/SdMmcOverride.h | 10 ++-
4 files changed, 128 insertions(+), 19 deletions(-)
diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdDevice.c b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdDevice.c
index 8bf452e9d0..acb98c4a6a 100644
--- a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdDevice.c
+++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdDevice.c
@@ -1215,6 +1215,7 @@ SdCardIdentification (
EFI_STATUS Status;
EFI_PCI_IO_PROTOCOL *PciIo;
EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru;
+ EFI_HANDLE ControllerHandle;
UINT32 Ocr;
UINT16 Rca;
BOOLEAN Xpc;
@@ -1223,7 +1224,6 @@ SdCardIdentification (
UINT16 ControllerVer;
UINT8 PowerCtrl;
UINT32 PresentState;
- UINT8 HostCtrl2;
UINTN Retry;
BOOLEAN ForceVoltage33;
BOOLEAN SdVersion1;
@@ -1231,10 +1231,22 @@ SdCardIdentification (
ForceVoltage33 = FALSE;
SdVersion1 = FALSE;
- PciIo = Private->PciIo;
- PassThru = &Private->PassThru;
+ PciIo = Private->PciIo;
+ PassThru = &Private->PassThru;
+ ControllerHandle = Private->ControllerHandle;
Voltage33Retry:
+ //
+ // Start at 3.3V.
+ // Note that if we got here from a failed 1.8V switching attempt,
+ // the card should've been power cycled to reset its own voltage level.
+ //
+ Status = SdMmcHcSetSignalingVoltage (ControllerHandle, PciIo, Slot, SdMmcSignalingVoltage33);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "SdCardIdentification: Couldn't set 3.3V signaling: %r\n", Status));
+ return Status;
+ }
+
//
// 1. Send Cmd0 to the device
//
@@ -1371,16 +1383,10 @@ Voltage33Retry:
goto Error;
}
- HostCtrl2 = BIT3;
- SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
-
- 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 = SdMmcHcSetSignalingVoltage (ControllerHandle, PciIo, Slot, SdMmcSignalingVoltage18);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "SdCardIdentification: Couldn't set 1.8V signaling: %r\n", Status));
+ return Status;
}
Status = SdMmcHcStartSdClock (PciIo, Slot);
diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c
index 9e8a7f4e43..2e334c67e2 100644
--- a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c
+++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c
@@ -1175,6 +1175,83 @@ SdMmcHcInitPowerVoltage (
return Status;
}
+/**
+ Set the voltage regulator for I/O signaling.
+
+ @param[in] PciIo The PCI IO protocol instance.
+ @param[in] Slot The slot number of the SD card to send the command to.
+ @param[in] Voltage The signaling voltage.
+
+ @retval EFI_SUCCESS The voltage is supplied successfully.
+ @retval Others The voltage isn't supplied successfully.
+
+**/
+EFI_STATUS
+SdMmcHcSetSignalingVoltage (
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_PCI_IO_PROTOCOL *PciIo,
+ IN UINT8 Slot,
+ IN SD_MMC_SIGNALING_VOLTAGE Voltage
+ )
+{
+ EFI_STATUS Status;
+ UINT8 HostCtrl2;
+
+ //
+ // Set the internal regulator first.
+ //
+ switch (Voltage) {
+ case SdMmcSignalingVoltage33:
+ HostCtrl2 = ~SD_MMC_HC_CTRL_1V8_SIGNAL;
+ SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
+ break;
+ case SdMmcSignalingVoltage18:
+ HostCtrl2 = SD_MMC_HC_CTRL_1V8_SIGNAL;
+ SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
+ break;
+ default:
+ ASSERT (FALSE);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Some controllers rely on an external regulator.
+ //
+ if ((mOverride != NULL) && (mOverride->NotifyPhase != NULL)) {
+ Status = mOverride->NotifyPhase (
+ ControllerHandle,
+ Slot,
+ EdkiiSdMmcSetSignalingVoltage,
+ &Voltage
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a: SD/MMC set signaling voltage notifier callback failed - %r\n",
+ __func__,
+ Status
+ ));
+ return Status;
+ }
+ }
+
+ gBS->Stall (5000);
+
+ Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, TRUE, sizeof (HostCtrl2), &HostCtrl2);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ HostCtrl2 &= SD_MMC_HC_CTRL_1V8_SIGNAL;
+ if (((Voltage == SdMmcSignalingVoltage33) && (HostCtrl2 != 0)) ||
+ ((Voltage == SdMmcSignalingVoltage18) && (HostCtrl2 == 0)))
+ {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
/**
Initialize the Timeout Control register with most conservative value at initialization.
diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.h b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.h
index e436a7d11a..e771ba7bad 100644
--- a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.h
+++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.h
@@ -2,10 +2,10 @@
Provides some data structure definitions used by the SD/MMC host controller driver.
- Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved.
- Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
- Copyright (C) 2023, Apple Inc. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
+Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved.
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+Copyright (C) 2023, Apple Inc. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
@par Specification Reference:
- SD Host Controller Simplified Specification, Version 4.20, July 25, 2018
@@ -63,6 +63,7 @@
//
// SD Host Controller bits to HOST_CTRL2 register
//
+#define SD_MMC_HC_CTRL_1V8_SIGNAL 0x0008
#define SD_MMC_HC_CTRL_UHS_MASK 0x0007
#define SD_MMC_HC_CTRL_UHS_SDR12 0x0000
#define SD_MMC_HC_CTRL_UHS_SDR25 0x0001
@@ -559,6 +560,25 @@ SdMmcHcInitPowerVoltage (
IN SD_MMC_HC_SLOT_CAP Capability
);
+/**
+ Set the voltage regulator for I/O signaling.
+
+ @param[in] PciIo The PCI IO protocol instance.
+ @param[in] Slot The slot number of the SD card to send the command to.
+ @param[in] Voltage The signaling voltage.
+
+ @retval EFI_SUCCESS The voltage is supplied successfully.
+ @retval Others The voltage isn't supplied successfully.
+
+**/
+EFI_STATUS
+SdMmcHcSetSignalingVoltage (
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_PCI_IO_PROTOCOL *PciIo,
+ IN UINT8 Slot,
+ IN SD_MMC_SIGNALING_VOLTAGE Voltage
+ );
+
/**
Initialize the Timeout Control register with most conservative value at initialization.
diff --git a/MdeModulePkg/Include/Protocol/SdMmcOverride.h b/MdeModulePkg/Include/Protocol/SdMmcOverride.h
index 4fd12b9ad4..d611bb04d8 100644
--- a/MdeModulePkg/Include/Protocol/SdMmcOverride.h
+++ b/MdeModulePkg/Include/Protocol/SdMmcOverride.h
@@ -16,7 +16,7 @@
#define EDKII_SD_MMC_OVERRIDE_PROTOCOL_GUID \
{ 0xeaf9e3c1, 0xc9cd, 0x46db, { 0xa5, 0xe5, 0x5a, 0x12, 0x4c, 0x83, 0x23, 0x23 } }
-#define EDKII_SD_MMC_OVERRIDE_PROTOCOL_VERSION 0x3
+#define EDKII_SD_MMC_OVERRIDE_PROTOCOL_VERSION 0x4
typedef struct _EDKII_SD_MMC_OVERRIDE EDKII_SD_MMC_OVERRIDE;
@@ -83,6 +83,11 @@ typedef enum {
SdMmcMmcHs400,
} SD_MMC_BUS_MODE;
+typedef enum {
+ SdMmcSignalingVoltage33,
+ SdMmcSignalingVoltage18
+} SD_MMC_SIGNALING_VOLTAGE;
+
typedef enum {
EdkiiSdMmcResetPre,
EdkiiSdMmcResetPost,
@@ -90,7 +95,8 @@ typedef enum {
EdkiiSdMmcInitHostPost,
EdkiiSdMmcUhsSignaling,
EdkiiSdMmcSwitchClockFreqPost,
- EdkiiSdMmcGetOperatingParam
+ EdkiiSdMmcGetOperatingParam,
+ EdkiiSdMmcSetSignalingVoltage
} EDKII_SD_MMC_PHASE_TYPE;
/**
--
2.51.2