From: "Mario Bălănică" <mariobalanica02@gmail.com>
To: devel@edk2.groups.io
Cc: gaoliming@byosoft.com.cn, ray.ni@intel.com
Subject: [edk2-devel] [PATCH 1/1] MdeModulePkg/SdMmcPciHcDxe: Support override for SD 1.8v signaling switch
Date: Thu, 4 Jan 2024 04:43:47 +0200 [thread overview]
Message-ID: <20240104024347.1502-1-mariobalanica02@gmail.com> (raw)
Some platforms (e.g. Raspberry Pi) have SDHCI implementations where the
internal signaling voltage control isn't wired up and therefore needs to
be set externally, in a non-standard way.
Power cycling the card to get it out of 1.8V is also kind of necessary,
but for now it can be done in the Reset/InitHost phase override.
Signed-off-by: Mario Bălănică <mariobalanica02@gmail.com>
---
MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdDevice.c | 32 ++++----
MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c | 77 ++++++++++++++++++++
MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.h | 20 +++++
MdeModulePkg/Include/Protocol/SdMmcOverride.h | 10 ++-
4 files changed, 124 insertions(+), 15 deletions(-)
diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdDevice.c b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdDevice.c
index 8bf452e9d01e..acb98c4a6a38 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 2e7497a89db1..26cada645bb3 100644
--- a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c
+++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c
@@ -1171,6 +1171,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 91155770e098..e3df7ed9a557 100644
--- a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.h
+++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.h
@@ -60,6 +60,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
//
// 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
@@ -553,6 +554,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 4fd12b9ad4c0..d611bb04d8d4 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.39.1.windows.1
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#113127): https://edk2.groups.io/g/devel/message/113127
Mute This Topic: https://groups.io/mt/103516142/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
next reply other threads:[~2024-01-04 2:44 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-01-04 2:43 Mario Bălănică [this message]
2024-03-15 21:18 ` [edk2-devel] [PATCH 1/1] MdeModulePkg/SdMmcPciHcDxe: Support override for SD 1.8v signaling switch Mario Bălănică
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240104024347.1502-1-mariobalanica02@gmail.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox