Files
nix-config/packages/edk2/patches/platforms/0007-Platform-RPi5-Add-SDHCI-support.patch
2026-01-07 21:28:20 -06:00

767 lines
23 KiB
Diff

From 8f06d1faaae5fcd2773ddf7e003f252f601406c4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mario=20B=C4=83l=C4=83nic=C4=83?=
<mariobalanica02@gmail.com>
Date: Fri, 29 Dec 2023 05:40:21 +0200
Subject: [PATCH 07/16] Platform/RPi5: Add SDHCI support
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Also configure SDIO Wi-Fi for later.
Depends on the SdMmcPciHcDxe patch in EDK2 for external 1.8v signaling
switch.
Signed-off-by: Mario Bălănică <mariobalanica02@gmail.com>
---
.../RPi5/Drivers/RpiPlatformDxe/Peripherals.c | 104 ++++++++
.../RPi5/Drivers/RpiPlatformDxe/Peripherals.h | 18 ++
.../Drivers/RpiPlatformDxe/RpiPlatformDxe.c | 23 ++
.../Drivers/RpiPlatformDxe/RpiPlatformDxe.inf | 40 ++++
Platform/RaspberryPi/RPi5/RPi5.dsc | 13 +-
Platform/RaspberryPi/RPi5/RPi5.fdf | 10 +-
.../Include/IndustryStandard/Bcm2712.h | 7 +
Silicon/Broadcom/BroadcomPkg.dec | 22 ++
.../Drivers/BrcmStbSdhciDxe/BrcmStbSdhciDxe.c | 224 ++++++++++++++++++
.../Drivers/BrcmStbSdhciDxe/BrcmStbSdhciDxe.h | 62 +++++
.../BrcmStbSdhciDxe/BrcmStbSdhciDxe.inf | 39 +++
.../Include/Protocol/BrcmStbSdhciDevice.h | 47 ++++
12 files changed, 606 insertions(+), 3 deletions(-)
create mode 100644 Platform/RaspberryPi/RPi5/Drivers/RpiPlatformDxe/Peripherals.c
create mode 100644 Platform/RaspberryPi/RPi5/Drivers/RpiPlatformDxe/Peripherals.h
create mode 100644 Platform/RaspberryPi/RPi5/Drivers/RpiPlatformDxe/RpiPlatformDxe.c
create mode 100644 Platform/RaspberryPi/RPi5/Drivers/RpiPlatformDxe/RpiPlatformDxe.inf
create mode 100644 Silicon/Broadcom/BroadcomPkg.dec
create mode 100644 Silicon/Broadcom/Drivers/BrcmStbSdhciDxe/BrcmStbSdhciDxe.c
create mode 100644 Silicon/Broadcom/Drivers/BrcmStbSdhciDxe/BrcmStbSdhciDxe.h
create mode 100644 Silicon/Broadcom/Drivers/BrcmStbSdhciDxe/BrcmStbSdhciDxe.inf
create mode 100644 Silicon/Broadcom/Include/Protocol/BrcmStbSdhciDevice.h
diff --git a/Platform/RaspberryPi/RPi5/Drivers/RpiPlatformDxe/Peripherals.c b/Platform/RaspberryPi/RPi5/Drivers/RpiPlatformDxe/Peripherals.c
new file mode 100644
index 00000000..7cb08635
--- /dev/null
+++ b/Platform/RaspberryPi/RPi5/Drivers/RpiPlatformDxe/Peripherals.c
@@ -0,0 +1,104 @@
+/** @file
+ *
+ * Copyright (c) 2023, Mario Bălănică <mariobalanica02@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause-Patent
+ *
+ **/
+
+#include <Uefi.h>
+#include <IndustryStandard/Bcm2712.h>
+#include <IndustryStandard/Bcm2712Pinctrl.h>
+#include <Library/Bcm2712GpioLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/BrcmStbSdhciDevice.h>
+
+#include "Peripherals.h"
+
+STATIC
+EFI_STATUS
+EFIAPI
+SdControllerSetSignalingVoltage (
+ IN BRCMSTB_SDHCI_DEVICE_PROTOCOL *This,
+ IN SD_MMC_SIGNALING_VOLTAGE Voltage
+ )
+{
+ // sd_io_1v8_reg
+ GpioWrite (BCM2712_GIO_AON, 3, Voltage == SdMmcSignalingVoltage18);
+
+ return EFI_SUCCESS;
+}
+
+STATIC BRCMSTB_SDHCI_DEVICE_PROTOCOL mSdController = {
+ .HostAddress = BCM2712_BRCMSTB_SDIO1_HOST_BASE,
+ .CfgAddress = BCM2712_BRCMSTB_SDIO1_CFG_BASE,
+ .DmaType = NonDiscoverableDeviceDmaTypeNonCoherent,
+ .IsSlotRemovable = TRUE,
+ .SetSignalingVoltage = SdControllerSetSignalingVoltage
+};
+
+STATIC
+EFI_STATUS
+EFIAPI
+RegisterSdControllers (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle = NULL;
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Handle,
+ &gBrcmStbSdhciDeviceProtocolGuid,
+ &mSdController,
+ NULL);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+InitGpioPinctrls (
+ VOID
+ )
+{
+ // SD card detect
+ GpioSetFunction (BCM2712_GIO_AON, 5, GIO_AON_PIN5_ALT_SD_CARD_G);
+ GpioSetPull (BCM2712_GIO_AON, 5, BCM2712_GPIO_PIN_PULL_UP);
+
+ // Route SDIO to Wi-Fi
+ GpioSetFunction (BCM2712_GIO, 30, GIO_PIN30_ALT_SD2);
+ GpioSetPull (BCM2712_GIO, 30, BCM2712_GPIO_PIN_PULL_NONE);
+ GpioSetFunction (BCM2712_GIO, 31, GIO_PIN31_ALT_SD2);
+ GpioSetPull (BCM2712_GIO, 31, BCM2712_GPIO_PIN_PULL_UP);
+ GpioSetFunction (BCM2712_GIO, 32, GIO_PIN32_ALT_SD2);
+ GpioSetPull (BCM2712_GIO, 32, BCM2712_GPIO_PIN_PULL_UP);
+ GpioSetFunction (BCM2712_GIO, 33, GIO_PIN33_ALT_SD2);
+ GpioSetPull (BCM2712_GIO, 33, BCM2712_GPIO_PIN_PULL_UP);
+ GpioSetFunction (BCM2712_GIO, 34, GIO_PIN34_ALT_SD2);
+ GpioSetPull (BCM2712_GIO, 34, BCM2712_GPIO_PIN_PULL_UP);
+ GpioSetFunction (BCM2712_GIO, 35, GIO_PIN35_ALT_SD2);
+ GpioSetPull (BCM2712_GIO, 35, BCM2712_GPIO_PIN_PULL_UP);
+
+ // wl_on_reg
+ GpioWrite (BCM2712_GIO, 28, TRUE);
+ GpioSetDirection (BCM2712_GIO, 28, BCM2712_GPIO_PIN_OUTPUT);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+SetupPeripherals (
+ VOID
+ )
+{
+ InitGpioPinctrls ();
+
+ RegisterSdControllers ();
+
+ return EFI_SUCCESS;
+}
diff --git a/Platform/RaspberryPi/RPi5/Drivers/RpiPlatformDxe/Peripherals.h b/Platform/RaspberryPi/RPi5/Drivers/RpiPlatformDxe/Peripherals.h
new file mode 100644
index 00000000..ef74a44d
--- /dev/null
+++ b/Platform/RaspberryPi/RPi5/Drivers/RpiPlatformDxe/Peripherals.h
@@ -0,0 +1,18 @@
+/** @file
+ *
+ * Copyright (c) 2023, Mario Bălănică <mariobalanica02@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause-Patent
+ *
+ **/
+
+#ifndef __RPI_PLATFORM_PERIPHERALS_H__
+#define __RPI_PLATFORM_PERIPHERALS_H__
+
+EFI_STATUS
+EFIAPI
+SetupPeripherals (
+ VOID
+ );
+
+#endif // __RPI_PLATFORM_PERIPHERALS_H__
diff --git a/Platform/RaspberryPi/RPi5/Drivers/RpiPlatformDxe/RpiPlatformDxe.c b/Platform/RaspberryPi/RPi5/Drivers/RpiPlatformDxe/RpiPlatformDxe.c
new file mode 100644
index 00000000..5d993266
--- /dev/null
+++ b/Platform/RaspberryPi/RPi5/Drivers/RpiPlatformDxe/RpiPlatformDxe.c
@@ -0,0 +1,23 @@
+/** @file
+ *
+ * Copyright (c) 2023, Mario Bălănică <mariobalanica02@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause-Patent
+ *
+ **/
+
+#include <Uefi.h>
+
+#include "Peripherals.h"
+
+EFI_STATUS
+EFIAPI
+RpiPlatformDxeEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ SetupPeripherals ();
+
+ return EFI_SUCCESS;
+}
diff --git a/Platform/RaspberryPi/RPi5/Drivers/RpiPlatformDxe/RpiPlatformDxe.inf b/Platform/RaspberryPi/RPi5/Drivers/RpiPlatformDxe/RpiPlatformDxe.inf
new file mode 100644
index 00000000..7292ca30
--- /dev/null
+++ b/Platform/RaspberryPi/RPi5/Drivers/RpiPlatformDxe/RpiPlatformDxe.inf
@@ -0,0 +1,40 @@
+#/** @file
+#
+# Copyright (c) 2023, Mario Bălănică <mariobalanica02@gmail.com>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x0001001A
+ BASE_NAME = RpiPlatformDxe
+ FILE_GUID = f6490266-0e7f-492e-8e15-ac69c1b7708a
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = RpiPlatformDxeEntryPoint
+
+[Sources]
+ RpiPlatformDxe.c
+ Peripherals.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ Platform/RaspberryPi/RaspberryPi.dec
+ Silicon/Broadcom/BroadcomPkg.dec
+ Silicon/Broadcom/Bcm27xx/Bcm27xx.dec
+
+[LibraryClasses]
+ DebugLib
+ UefiLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ Bcm2712GpioLib
+
+[Protocols]
+ gBrcmStbSdhciDeviceProtocolGuid ## PRODUCES
+
+[Depex]
+ TRUE
diff --git a/Platform/RaspberryPi/RPi5/RPi5.dsc b/Platform/RaspberryPi/RPi5/RPi5.dsc
index 6850203e..0a97e317 100644
--- a/Platform/RaspberryPi/RPi5/RPi5.dsc
+++ b/Platform/RaspberryPi/RPi5/RPi5.dsc
@@ -180,7 +180,6 @@
VariableFlashInfoLib|MdeModulePkg/Library/BaseVariableFlashInfoLib/BaseVariableFlashInfoLib.inf
VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf
VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf
- GpioLib|Silicon/Broadcom/Bcm283x/Library/GpioLib/GpioLib.inf
FdtPlatformLib|Platform/RaspberryPi/Library/FdtPlatformLib/FdtPlatformLib.inf
BoardInfoLib|Platform/RaspberryPi/Library/BoardInfoLib/BoardInfoLib.inf
@@ -188,6 +187,8 @@
NonDiscoverableDeviceRegistrationLib|MdeModulePkg/Library/NonDiscoverableDeviceRegistrationLib/NonDiscoverableDeviceRegistrationLib.inf
+ Bcm2712GpioLib|Silicon/Broadcom/Bcm27xx/Library/Bcm2712GpioLib/Bcm2712GpioLib.inf
+
[LibraryClasses.common.SEC]
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
@@ -561,8 +562,8 @@
ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
Platform/RaspberryPi/Drivers/RpiFirmwareDxe/RpiFirmwareDxe.inf
+ Platform/RaspberryPi/RPi5/Drivers/RpiPlatformDxe/RpiPlatformDxe.inf
# Platform/RaspberryPi/Drivers/FdtDxe/FdtDxe.inf
- # Platform/RaspberryPi/Drivers/ConfigDxe/ConfigDxe.inf
ArmPkg/Drivers/TimerDxe/TimerDxe.inf
MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
MdeModulePkg/Universal/EbcDxe/EbcDxe.inf
@@ -625,6 +626,14 @@
MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
+ #
+ # SD/eMMC Support
+ #
+ MdeModulePkg/Bus/Sd/SdDxe/SdDxe.inf
+ MdeModulePkg/Bus/Sd/EmmcDxe/EmmcDxe.inf
+ MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.inf
+ Silicon/Broadcom/Drivers/BrcmStbSdhciDxe/BrcmStbSdhciDxe.inf
+
#
# Networking stack
#
diff --git a/Platform/RaspberryPi/RPi5/RPi5.fdf b/Platform/RaspberryPi/RPi5/RPi5.fdf
index 8cd67254..ba19551b 100644
--- a/Platform/RaspberryPi/RPi5/RPi5.fdf
+++ b/Platform/RaspberryPi/RPi5/RPi5.fdf
@@ -214,8 +214,8 @@ READ_LOCK_STATUS = TRUE
INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
INF Platform/RaspberryPi/Drivers/RpiFirmwareDxe/RpiFirmwareDxe.inf
+ INF Platform/RaspberryPi/RPi5/Drivers/RpiPlatformDxe/RpiPlatformDxe.inf
# INF Platform/RaspberryPi/Drivers/FdtDxe/FdtDxe.inf
- # INF Platform/RaspberryPi/Drivers/ConfigDxe/ConfigDxe.inf
INF ArmPkg/Drivers/TimerDxe/TimerDxe.inf
INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
INF MdeModulePkg/Universal/EbcDxe/EbcDxe.inf
@@ -308,6 +308,14 @@ READ_LOCK_STATUS = TRUE
INF MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
INF MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
+ #
+ # SD/eMMC Support
+ #
+ INF MdeModulePkg/Bus/Sd/SdDxe/SdDxe.inf
+ INF MdeModulePkg/Bus/Sd/EmmcDxe/EmmcDxe.inf
+ INF MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.inf
+ INF Silicon/Broadcom/Drivers/BrcmStbSdhciDxe/BrcmStbSdhciDxe.inf
+
#
# Pi logo (splash screen)
#
diff --git a/Silicon/Broadcom/Bcm27xx/Include/IndustryStandard/Bcm2712.h b/Silicon/Broadcom/Bcm27xx/Include/IndustryStandard/Bcm2712.h
index a0d3e850..c5365141 100644
--- a/Silicon/Broadcom/Bcm27xx/Include/IndustryStandard/Bcm2712.h
+++ b/Silicon/Broadcom/Bcm27xx/Include/IndustryStandard/Bcm2712.h
@@ -19,4 +19,11 @@
#define BCM2712_PINCTRL_AON_BASE 0x107d510700
#define BCM2712_PINCTRL_AON_LENGTH 0x20
+#define BCM2712_BRCMSTB_SDIO1_HOST_BASE 0x1000fff000
+#define BCM2712_BRCMSTB_SDIO1_CFG_BASE 0x1000fff400
+#define BCM2712_BRCMSTB_SDIO2_HOST_BASE 0x1001100000
+#define BCM2712_BRCMSTB_SDIO2_CFG_BASE 0x1001100400
+#define BCM2712_BRCMSTB_SDIO_HOST_LENGTH 0x260
+#define BCM2712_BRCMSTB_SDIO_CFG_LENGTH 0x200
+
#endif // __BCM2712_H__
diff --git a/Silicon/Broadcom/BroadcomPkg.dec b/Silicon/Broadcom/BroadcomPkg.dec
new file mode 100644
index 00000000..31f876ae
--- /dev/null
+++ b/Silicon/Broadcom/BroadcomPkg.dec
@@ -0,0 +1,22 @@
+#/** @file
+#
+# Copyright (c) 2023, Mario Bălănică <mariobalanica02@gmail.com>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+ DEC_SPECIFICATION = 0x0001001A
+ PACKAGE_NAME = BroadcomPkg
+ PACKAGE_GUID = b25a0fef-f089-420f-98f2-adb9b9a34b18
+ PACKAGE_VERSION = 1.0
+
+[Includes]
+ Include
+
+[Guids]
+ gBroadcomTokenSpaceGuid = { 0xe49c8829, 0xfd87, 0x40cd, { 0x99, 0xf4, 0x61, 0x08, 0x15, 0x92, 0x76, 0x4e } }
+
+[Protocols]
+ gBrcmStbSdhciDeviceProtocolGuid = { 0xd6c196f9, 0x9c8c, 0x448f, { 0xbd, 0x21, 0xd9, 0x76, 0xa8, 0x3a, 0x82, 0x7f } }
diff --git a/Silicon/Broadcom/Drivers/BrcmStbSdhciDxe/BrcmStbSdhciDxe.c b/Silicon/Broadcom/Drivers/BrcmStbSdhciDxe/BrcmStbSdhciDxe.c
new file mode 100644
index 00000000..80e30a2d
--- /dev/null
+++ b/Silicon/Broadcom/Drivers/BrcmStbSdhciDxe/BrcmStbSdhciDxe.c
@@ -0,0 +1,224 @@
+/** @file
+ *
+ * Copyright (c) 2023, Mario Bălănică <mariobalanica02@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause-Patent
+ *
+ **/
+
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/NonDiscoverableDeviceRegistrationLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <Protocol/BrcmStbSdhciDevice.h>
+#include <Protocol/NonDiscoverableDevice.h>
+#include <Protocol/SdMmcOverride.h>
+
+#include "BrcmStbSdhciDxe.h"
+
+STATIC
+EFI_STATUS
+EFIAPI
+SdMmcCapability (
+ IN EFI_HANDLE ControllerHandle,
+ IN UINT8 Slot,
+ IN OUT VOID *SdMmcHcSlotCapability,
+ IN OUT UINT32 *BaseClkFreq
+ )
+{
+ SD_MMC_HC_SLOT_CAP *Capability;
+
+ if (Slot != 0) {
+ return EFI_UNSUPPORTED;
+ }
+ if (SdMmcHcSlotCapability == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Capability = SdMmcHcSlotCapability;
+
+ // Hardware retuning is not supported.
+ Capability->RetuningMod = 0;
+
+ return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+SdMmcNotifyPhase (
+ IN EFI_HANDLE ControllerHandle,
+ IN UINT8 Slot,
+ IN EDKII_SD_MMC_PHASE_TYPE PhaseType,
+ IN OUT VOID *PhaseData
+ )
+{
+ EFI_STATUS Status;
+ BRCMSTB_SDHCI_DEVICE_PROTOCOL *Device;
+
+ if (Slot != 0) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = gBS->HandleProtocol (
+ ControllerHandle,
+ &gBrcmStbSdhciDeviceProtocolGuid,
+ (VOID **)&Device);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Failed to get protocol. Status=%r\n",
+ __func__, Status));
+ return EFI_UNSUPPORTED;
+ }
+
+ switch (PhaseType) {
+ case EdkiiSdMmcSetSignalingVoltage:
+ if (PhaseData == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (Device->SetSignalingVoltage != NULL) {
+ return Device->SetSignalingVoltage (Device, *(SD_MMC_SIGNALING_VOLTAGE *)PhaseData);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return EFI_SUCCESS;
+}
+
+STATIC EDKII_SD_MMC_OVERRIDE mSdMmcOverride = {
+ EDKII_SD_MMC_OVERRIDE_PROTOCOL_VERSION,
+ SdMmcCapability,
+ SdMmcNotifyPhase,
+};
+
+STATIC
+EFI_STATUS
+EFIAPI
+StartDevice (
+ IN BRCMSTB_SDHCI_DEVICE_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Set the PHY DLL as clock source to support higher speed modes
+ // reliably.
+ //
+ MmioAndThenOr32 (This->CfgAddress + SDIO_CFG_MAX_50MHZ_MODE,
+ ~SDIO_CFG_MAX_50MHZ_MODE_ENABLE,
+ SDIO_CFG_MAX_50MHZ_MODE_STRAP_OVERRIDE);
+
+ if (This->IsSlotRemovable) {
+ MmioAndThenOr32 (This->CfgAddress + SDIO_CFG_SD_PIN_SEL,
+ ~SDIO_CFG_SD_PIN_SEL_MASK,
+ SDIO_CFG_SD_PIN_SEL_CARD);
+ } else {
+ MmioAndThenOr32 (This->CfgAddress + SDIO_CFG_CTRL,
+ ~SDIO_CFG_CTRL_SDCD_N_TEST_LEV,
+ SDIO_CFG_CTRL_SDCD_N_TEST_EN);
+ }
+
+ Status = RegisterNonDiscoverableMmioDevice (
+ NonDiscoverableDeviceTypeSdhci,
+ This->DmaType,
+ NULL,
+ &ControllerHandle,
+ 1,
+ This->HostAddress, SDIO_HOST_SIZE);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR,
+ "%a: Failed to register Broadcom STB SDHCI controller at 0x%lx. Status=%r\n",
+ __func__, This->HostAddress, Status));
+ return Status;
+ }
+
+ return Status;
+}
+
+STATIC VOID *mProtocolInstallEventRegistration;
+
+STATIC
+VOID
+EFIAPI
+NotifyProtocolInstall (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+ UINTN BufferSize;
+ BRCMSTB_SDHCI_DEVICE_PROTOCOL *Device;
+
+ while (TRUE) {
+ BufferSize = sizeof (EFI_HANDLE);
+ Status = gBS->LocateHandle (
+ ByRegisterNotify,
+ NULL,
+ mProtocolInstallEventRegistration,
+ &BufferSize,
+ &Handle);
+ if (EFI_ERROR (Status)) {
+ if (Status != EFI_NOT_FOUND) {
+ DEBUG ((DEBUG_ERROR, "%a: Failed to locate protocol. Status=%r\n",
+ __func__, Status));
+ }
+ break;
+ }
+
+ Status = gBS->HandleProtocol (
+ Handle,
+ &gBrcmStbSdhciDeviceProtocolGuid,
+ (VOID **)&Device);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Failed to get protocol. Status=%r\n",
+ __func__, Status));
+ break;
+ }
+
+ Status = StartDevice (Device, Handle);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Failed to start device. Status=%r\n",
+ __func__, Status));
+ break;
+ }
+ }
+}
+
+EFI_STATUS
+EFIAPI
+BrcmStbSdhciDxeInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+ EFI_EVENT ProtocolInstallEvent;
+
+ ProtocolInstallEvent = EfiCreateProtocolNotifyEvent (
+ &gBrcmStbSdhciDeviceProtocolGuid,
+ TPL_CALLBACK,
+ NotifyProtocolInstall,
+ NULL,
+ &mProtocolInstallEventRegistration);
+ if (ProtocolInstallEvent == NULL) {
+ ASSERT (FALSE);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Handle = NULL;
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Handle,
+ &gEdkiiSdMmcOverrideProtocolGuid,
+ &mSdMmcOverride,
+ NULL);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
diff --git a/Silicon/Broadcom/Drivers/BrcmStbSdhciDxe/BrcmStbSdhciDxe.h b/Silicon/Broadcom/Drivers/BrcmStbSdhciDxe/BrcmStbSdhciDxe.h
new file mode 100644
index 00000000..7ea854c1
--- /dev/null
+++ b/Silicon/Broadcom/Drivers/BrcmStbSdhciDxe/BrcmStbSdhciDxe.h
@@ -0,0 +1,62 @@
+/** @file
+ *
+ * Copyright (c) 2023, Mario Bălănică <mariobalanica02@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause-Patent
+ *
+ **/
+
+#ifndef __BRCMSTB_SDHCI_DXE_H__
+#define __BRCMSTB_SDHCI_DXE_H__
+
+#define SDIO_HOST_SIZE 0x260
+
+#define SDIO_CFG_CTRL 0x0
+#define SDIO_CFG_CTRL_SDCD_N_TEST_EN BIT31
+#define SDIO_CFG_CTRL_SDCD_N_TEST_LEV BIT30
+
+#define SDIO_CFG_SD_PIN_SEL 0x44
+#define SDIO_CFG_SD_PIN_SEL_MASK (BIT1 | BIT0)
+#define SDIO_CFG_SD_PIN_SEL_CARD BIT1
+
+#define SDIO_CFG_MAX_50MHZ_MODE 0x1ac
+#define SDIO_CFG_MAX_50MHZ_MODE_STRAP_OVERRIDE BIT31
+#define SDIO_CFG_MAX_50MHZ_MODE_ENABLE BIT0
+
+typedef struct {
+ UINT32 TimeoutFreq : 6; // bit 0:5
+ UINT32 Reserved : 1; // bit 6
+ UINT32 TimeoutUnit : 1; // bit 7
+ UINT32 BaseClkFreq : 8; // bit 8:15
+ UINT32 MaxBlkLen : 2; // bit 16:17
+ UINT32 BusWidth8 : 1; // bit 18
+ UINT32 Adma2 : 1; // bit 19
+ UINT32 Reserved2 : 1; // bit 20
+ UINT32 HighSpeed : 1; // bit 21
+ UINT32 Sdma : 1; // bit 22
+ UINT32 SuspRes : 1; // bit 23
+ UINT32 Voltage33 : 1; // bit 24
+ UINT32 Voltage30 : 1; // bit 25
+ UINT32 Voltage18 : 1; // bit 26
+ UINT32 SysBus64V4 : 1; // bit 27
+ UINT32 SysBus64V3 : 1; // bit 28
+ UINT32 AsyncInt : 1; // bit 29
+ UINT32 SlotType : 2; // bit 30:31
+ UINT32 Sdr50 : 1; // bit 32
+ UINT32 Sdr104 : 1; // bit 33
+ UINT32 Ddr50 : 1; // bit 34
+ UINT32 Reserved3 : 1; // bit 35
+ UINT32 DriverTypeA : 1; // bit 36
+ UINT32 DriverTypeC : 1; // bit 37
+ UINT32 DriverTypeD : 1; // bit 38
+ UINT32 DriverType4 : 1; // bit 39
+ UINT32 TimerCount : 4; // bit 40:43
+ UINT32 Reserved4 : 1; // bit 44
+ UINT32 TuningSDR50 : 1; // bit 45
+ UINT32 RetuningMod : 2; // bit 46:47
+ UINT32 ClkMultiplier : 8; // bit 48:55
+ UINT32 Reserved5 : 7; // bit 56:62
+ UINT32 Hs400 : 1; // bit 63
+} SD_MMC_HC_SLOT_CAP;
+
+#endif // __BRCMSTB_SDHCI_DXE_H__
diff --git a/Silicon/Broadcom/Drivers/BrcmStbSdhciDxe/BrcmStbSdhciDxe.inf b/Silicon/Broadcom/Drivers/BrcmStbSdhciDxe/BrcmStbSdhciDxe.inf
new file mode 100644
index 00000000..9c513a3f
--- /dev/null
+++ b/Silicon/Broadcom/Drivers/BrcmStbSdhciDxe/BrcmStbSdhciDxe.inf
@@ -0,0 +1,39 @@
+#/** @file
+#
+# Copyright (c) 2023, Mario Bălănică <mariobalanica02@gmail.com>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x0001001A
+ BASE_NAME = BrcmStbSdhciDxe
+ FILE_GUID = d72a2469-f274-48e1-9bcb-3a28a2a09234
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = BrcmStbSdhciDxeInitialize
+
+[Sources]
+ BrcmStbSdhciDxe.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ Silicon/Broadcom/BroadcomPkg.dec
+
+[LibraryClasses]
+ DebugLib
+ IoLib
+ NonDiscoverableDeviceRegistrationLib
+ UefiLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+
+[Protocols]
+ gEdkiiNonDiscoverableDeviceProtocolGuid ## PRODUCES
+ gEdkiiSdMmcOverrideProtocolGuid ## PRODUCES
+ gBrcmStbSdhciDeviceProtocolGuid ## CONSUMES
+
+[Depex]
+ TRUE
diff --git a/Silicon/Broadcom/Include/Protocol/BrcmStbSdhciDevice.h b/Silicon/Broadcom/Include/Protocol/BrcmStbSdhciDevice.h
new file mode 100644
index 00000000..7837862c
--- /dev/null
+++ b/Silicon/Broadcom/Include/Protocol/BrcmStbSdhciDevice.h
@@ -0,0 +1,47 @@
+/** @file
+ *
+ * Copyright (c) 2023, Mario Bălănică <mariobalanica02@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause-Patent
+ *
+ **/
+
+#ifndef __BRCMSTB_SDHCI_DEVICE_H__
+#define __BRCMSTB_SDHCI_DEVICE_H__
+
+#include <Uefi/UefiBaseType.h>
+#include <Protocol/NonDiscoverableDevice.h>
+#include <Protocol/SdMmcOverride.h>
+
+#define BRCMSTB_SDHCI_DEVICE_PROTOCOL_GUID \
+ { 0xd6c196f9, 0x9c8c, 0x448f, { 0xbd, 0x21, 0xd9, 0x76, 0xa8, 0x3a, 0x82, 0x7f } }
+
+typedef struct _BRCMSTB_SDHCI_DEVICE_PROTOCOL BRCMSTB_SDHCI_DEVICE_PROTOCOL;
+
+typedef
+EFI_STATUS
+(EFIAPI *BRCMSTB_SDHCI_SET_SIGNALING_VOLTAGE) (
+ IN BRCMSTB_SDHCI_DEVICE_PROTOCOL *This,
+ IN SD_MMC_SIGNALING_VOLTAGE Voltage
+ );
+
+struct _BRCMSTB_SDHCI_DEVICE_PROTOCOL {
+ //
+ // Controller platform info
+ //
+ EFI_PHYSICAL_ADDRESS HostAddress;
+ EFI_PHYSICAL_ADDRESS CfgAddress;
+ NON_DISCOVERABLE_DEVICE_DMA_TYPE DmaType;
+
+ BOOLEAN IsSlotRemovable;
+
+ //
+ // Optional callback for setting the signaling voltage via
+ // an external regulator.
+ //
+ BRCMSTB_SDHCI_SET_SIGNALING_VOLTAGE SetSignalingVoltage;
+};
+
+extern EFI_GUID gBrcmStbSdhciDeviceProtocolGuid;
+
+#endif // __BRCMSTB_SDHCI_DEVICE_H__
--
2.51.2