* [edk2-platform][PATCH 1/1] MdeModulePkg: SdMmcPciHcDxe: Support for Bayhub SD/eMMC host
@ 2023-02-24 12:39 Chevron Li
2023-02-28 2:55 ` Wu, Hao A
0 siblings, 1 reply; 2+ messages in thread
From: Chevron Li @ 2023-02-24 12:39 UTC (permalink / raw)
To: devel
Cc: hao.a.wu, ray.ni, jian.j.wang, gaoliming, shaper.liu, chevron.li,
xiaoguang.yu, shirley.her
From: "Chevron Li (WH)" <chevron.li@bayhubtech.com>
1.Implement override function for EdkiiSdMmcInitHostPre case to
configure bayhub host.
2.Implement override function for EdkiiSdMmcInitHostPost case to
configure bayhub host.
Cc: Hao A Wu <hao.a.wu@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Signed-off-by: Chevron Li <chevron.li@bayhubtech.com>
---
.../Bus/Pci/SdMmcPciHcDxe/BayhubHost.c | 676 ++++++++++++++++++
.../Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.c | 3 +
.../Bus/Pci/SdMmcPciHcDxe/BayhubHost.h | 95 +++
.../Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.inf | 2 +
4 files changed, 776 insertions(+)
create mode 100644 MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/BayhubHost.c
create mode 100644 MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/BayhubHost.h
diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/BayhubHost.c b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/BayhubHost.c
new file mode 100644
index 0000000000..470838e37e
--- /dev/null
+++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/BayhubHost.c
@@ -0,0 +1,676 @@
+/** @file
+ This driver is used to manage SD/MMC PCI host controllers override function
+ for BayHub SD/eMMC host controller.
+
+ Copyright (c) 2018 - 2019, BayHub Tech inc. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "BayhubHost.h"
+#include "SdMmcPciHcDxe.h"
+#include <Protocol/PciIo.h>
+
+/* Driver global variables*/
+UINT16 BhtDeviceId = 0;
+
+EDKII_SD_MMC_OVERRIDE BhtOverride = {
+ EDKII_SD_MMC_OVERRIDE_PROTOCOL_VERSION,
+ BhtHostOverrideCapability,
+ BhtHostOverrideNotifyPhase
+};
+
+/**
+ Judgement function for Host type
+
+ @param[in] PciIo The PCI IO protocol instance.
+
+ @retval UNSUPPORT The host isn't Bayhub host.
+ @retval EMMC_HOST The host is Bayhub eMMC host.
+ @retval SD_HOST The host is Bayhub SD host.
+
+**/
+UINT8
+BhtHostPciSupportType (
+ IN EFI_PCI_IO_PROTOCOL *PciIo
+ )
+{
+ PCI_TYPE00 Pci;
+ UINT8 HostType;
+
+ PciIo->Pci.Read (
+ PciIo,
+ EfiPciIoWidthUint32,
+ 0,
+ sizeof (PCI_TYPE00) / sizeof (UINT32),
+ &Pci
+ );
+ DEBUG ((DEBUG_INFO, "Check device %04x:%04x\n", Pci.Hdr.VendorId, Pci.Hdr.DeviceId));
+
+ // Judgement bayhub device or not
+ if (Pci.Hdr.VendorId != 0x1217) {
+ HostType = UNSUPPORT;
+ goto end;
+ }
+
+ BhtDeviceId = Pci.Hdr.DeviceId;
+
+ // Bayhub host only 0x8620 is eMMC host
+ switch (Pci.Hdr.DeviceId) {
+ case PCI_DEV_ID_SB0:
+ HostType = EMMC_HOST;
+ break;
+ case PCI_DEV_ID_SB1:
+ default:
+ HostType = SD_HOST;
+ break;
+ }
+
+end:
+ return HostType;
+}
+
+/**
+ Read specified SD/MMC host controller mmio register
+
+ @param[in] PciIo The PCI IO protocol instance.
+ @param[in] Offset The Offset within the selected BAR to start the
+ memory operation.
+
+ @retval Value The value of specified SD/MMC host controller mmio register.
+
+**/
+UINT32
+BhtMmRead32 (
+ IN EFI_PCI_IO_PROTOCOL *PciIo,
+ IN UINT32 Offset
+ )
+{
+ UINT32 Value;
+
+ PciIo->Mem.Read (PciIo, EfiPciIoWidthUint32, 1, Offset, 1, &Value);
+ return Value;
+}
+
+/**
+ Write specified SD/MMC host controller mmio register
+
+ @param[in] PciIo The PCI IO protocol instance.
+ @param[in] Offset The Offset within the selected BAR to start the
+ memory operation.
+ @param[in] Value The value to write.
+
+**/
+VOID
+BhtMmWrite32 (
+ IN EFI_PCI_IO_PROTOCOL *PciIo,
+ IN UINT32 Offset,
+ IN UINT32 Value
+ )
+{
+ PciIo->Mem.Write (PciIo, EfiPciIoWidthUint32, 1, Offset, 1, &Value);
+}
+
+/**
+ Read specified SD/MMC host controller PCIe configure register
+
+ @param[in] PciIo The PCI IO protocol instance.
+ @param[in] Offset The Offset within the selected BAR to start the
+ memory operation.
+
+ @retval Value The value of specified SD/MMC host controller PCIe configure register.
+
+**/
+UINT32
+BhtPciRead32 (
+ IN EFI_PCI_IO_PROTOCOL *PciIo,
+ IN UINT32 Offset
+ )
+{
+ UINT32 Index;
+ UINT32 TmpBuff[2];
+
+ if ((BhtDeviceId == PCI_DEV_ID_SDS0) ||
+ (BhtDeviceId == PCI_DEV_ID_SDS1) ||
+ (BhtDeviceId == PCI_DEV_ID_FJ2) ||
+ (BhtDeviceId == PCI_DEV_ID_SB0) ||
+ (BhtDeviceId == PCI_DEV_ID_SB1))
+ {
+ // For Sandstorm, HW implement a mapping method by memory space reg to access PCI reg.
+ // Enable mapping
+
+ // Check function conflict
+ if ((BhtDeviceId == PCI_DEV_ID_SDS0) ||
+ (BhtDeviceId == PCI_DEV_ID_FJ2) ||
+ (BhtDeviceId == PCI_DEV_ID_SB0) ||
+ (BhtDeviceId == PCI_DEV_ID_SB1))
+ {
+ Index = 0;
+ BhtMmWrite32 (PciIo, BHT_PCR_MAP_EN, 0x40000000);
+ while ((BhtMmRead32 (PciIo, BHT_PCR_MAP_EN) & 0x40000000) == 0) {
+ if (Index == 5) {
+ goto RD_DIS_MAPPING;
+ }
+
+ gBS->Stall (1000);
+ Index++;
+ BhtMmWrite32 (PciIo, BHT_PCR_MAP_EN, 0x40000000);
+ }
+ } else if (BhtDeviceId == PCI_DEV_ID_SDS1) {
+ Index = 0;
+ BhtMmWrite32 (PciIo, BHT_PCR_MAP_EN, 0x20000000);
+ while ((BhtMmRead32 (PciIo, BHT_PCR_MAP_EN) & 0x20000000) == 0) {
+ if (Index == 5) {
+ goto RD_DIS_MAPPING;
+ }
+
+ gBS->Stall (1000);
+ Index++;
+ BhtMmWrite32 (PciIo, BHT_PCR_MAP_EN, 0x20000000);
+ }
+ }
+
+ // Check last operation is complete
+ Index = 0;
+ while (BhtMmRead32 (PciIo, BHT_PCR_MAP_CTL) & 0xc0000000) {
+ if (Index == 5) {
+ goto RD_DIS_MAPPING;
+ }
+
+ gBS->Stall (1000);
+ Index++;
+ }
+
+ // Set register address
+ TmpBuff[0] = 0x40000000;
+ TmpBuff[0] |= Offset;
+ BhtMmWrite32 (PciIo, BHT_PCR_MAP_CTL, TmpBuff[0]);
+
+ // Check read is complete
+ Index = 0;
+ while (BhtMmRead32 (PciIo, BHT_PCR_MAP_CTL) & 0x40000000) {
+ if (Index == 5) {
+ goto RD_DIS_MAPPING;
+ }
+
+ gBS->Stall (1000);
+ Index++;
+ }
+
+ // Get PCIR value
+ TmpBuff[1] = BhtMmRead32 (PciIo, BHT_PCR_MAP_VAL);
+
+RD_DIS_MAPPING:
+ // Disable mapping
+ BhtMmWrite32 (PciIo, BHT_PCR_MAP_EN, 0x80000000);
+ return TmpBuff[1];
+ } else {
+ return BhtMmRead32 (PciIo, Offset);
+ }
+}
+
+/**
+ Write specified SD/MMC host controller PCIe configure register
+
+ @param[in] PciIo The PCI IO protocol instance.
+ @param[in] Offset The Offset within the selected BAR to start the
+ memory operation.
+ @param[in] Value The value to write.
+
+**/
+VOID
+BhtPciWrite32 (
+ IN EFI_PCI_IO_PROTOCOL *PciIo,
+ IN UINT32 Offset,
+ IN UINT32 Value
+ )
+{
+ UINT32 TmpBuff;
+ UINT32 Index;
+
+ if ((BhtDeviceId == PCI_DEV_ID_SDS0) ||
+ (BhtDeviceId == PCI_DEV_ID_SDS1) ||
+ (BhtDeviceId == PCI_DEV_ID_FJ2) ||
+ (BhtDeviceId == PCI_DEV_ID_SB0) ||
+ (BhtDeviceId == PCI_DEV_ID_SB1))
+ {
+ // Enable mapping
+ // Check function conflict
+ if ((BhtDeviceId == PCI_DEV_ID_SDS0) ||
+ (BhtDeviceId == PCI_DEV_ID_FJ2) ||
+ (BhtDeviceId == PCI_DEV_ID_SB0) ||
+ (BhtDeviceId == PCI_DEV_ID_SB1))
+ {
+ Index = 0;
+ BhtMmWrite32 (PciIo, BHT_PCR_MAP_EN, 0x40000000);
+ while ((BhtMmRead32 (PciIo, BHT_PCR_MAP_EN) & 0x40000000) == 0) {
+ if (Index == 5) {
+ goto WR_DIS_MAPPING;
+ }
+
+ gBS->Stall (1000);
+ Index++;
+ BhtMmWrite32 (PciIo, BHT_PCR_MAP_EN, 0x40000000);
+ }
+ } else if (BhtDeviceId == PCI_DEV_ID_SDS1) {
+ Index = 0;
+ BhtMmWrite32 (PciIo, BHT_PCR_MAP_EN, 0x20000000);
+
+ while ((BhtMmRead32 (PciIo, BHT_PCR_MAP_EN) & 0x20000000) == 0) {
+ if (Index == 5) {
+ goto WR_DIS_MAPPING;
+ }
+
+ gBS->Stall (1000);
+ Index++;
+ BhtMmWrite32 (PciIo, BHT_PCR_MAP_EN, 0x20000000);
+ }
+ }
+
+ // Enable MEM access
+ BhtMmWrite32 (PciIo, BHT_PCR_MAP_VAL, 0x80000000);
+ BhtMmWrite32 (PciIo, BHT_PCR_MAP_CTL, 0x800000D0);
+
+ // Check last operation is complete
+ Index = 0;
+ while (BhtMmRead32 (PciIo, BHT_PCR_MAP_CTL) & 0xc0000000) {
+ if (Index == 5) {
+ goto WR_DIS_MAPPING;
+ }
+
+ gBS->Stall (1000);
+ Index++;
+ }
+
+ // Set write value
+ BhtMmWrite32 (PciIo, BHT_PCR_MAP_VAL, Value);
+ // Set register address
+ TmpBuff = 0x80000000;
+ TmpBuff |= Offset;
+ BhtMmWrite32 (PciIo, BHT_PCR_MAP_CTL, TmpBuff);
+
+ // Check write is complete
+ Index = 0;
+ while (BhtMmRead32 (PciIo, BHT_PCR_MAP_CTL) & 0x80000000) {
+ if (Index == 5) {
+ goto WR_DIS_MAPPING;
+ }
+
+ gBS->Stall (1000);
+ Index++;
+ }
+
+WR_DIS_MAPPING:
+ // Disable MEM access
+ BhtMmWrite32 (PciIo, BHT_PCR_MAP_VAL, 0x80000001);
+ BhtMmWrite32 (PciIo, BHT_PCR_MAP_CTL, 0x800000D0);
+
+ // Check last operation is complete
+ Index = 0;
+ while (BhtMmRead32 (PciIo, BHT_PCR_MAP_CTL) & 0xc0000000) {
+ if (Index == 5) {
+ break;
+ }
+
+ gBS->Stall (1000);
+ Index++;
+ }
+
+ // Disable function conflict
+ // Disable mapping
+ BhtMmWrite32 (PciIo, BHT_PCR_MAP_EN, 0x80000000);
+ } else {
+ BhtMmWrite32 (PciIo, Offset, Value);
+ }
+}
+
+/**
+ Do OR operation with the value of the specified SD/MMC host controller PCIe configure register
+
+ @param[in] PciIo The PCI IO protocol instance.
+ @param[in] Offset The Offset within the selected BAR to start the
+ memory operation.
+ @param[in] Value The value to do OR operation.
+
+**/
+VOID
+BhtPciOr32 (
+ IN EFI_PCI_IO_PROTOCOL *PciIo,
+ IN UINT32 Offset,
+ IN UINT32 Value
+ )
+{
+ UINT32 OldValue;
+
+ OldValue = BhtPciRead32 (PciIo, Offset);
+ BhtPciWrite32 (PciIo, Offset, Value | OldValue);
+}
+
+/**
+ Do AND operation with the value of the specified SD/MMC host controller PCIe configure register
+
+ @param[in] PciIo The PCI IO protocol instance.
+ @param[in] Offset The Offset within the selected BAR to start the
+ memory operation.
+ @param[in] Value The value to do AND operation.
+
+**/
+VOID
+PciBhtAnd32 (
+ IN EFI_PCI_IO_PROTOCOL *PciIo,
+ IN UINT32 Offset,
+ IN UINT32 Value
+ )
+{
+ UINT32 OldValue;
+
+ OldValue = BhtPciRead32 (PciIo, Offset);
+ BhtPciWrite32 (PciIo, Offset, Value & OldValue);
+}
+
+/**
+ Dump the content of SD/MMC host controller's key Registers.
+
+ @param[in] PciIo The PCI IO protocol instance.
+
+**/
+VOID
+BhtDbgDump (
+ IN EFI_PCI_IO_PROTOCOL *PciIo
+ )
+{
+ if (BhtHostPciSupportType (PciIo) != UNSUPPORT) {
+ DEBUG ((DEBUG_INFO, "HOST_CLK_DRIVE_STRENGTH: 0x%x\n", HOST_CLK_DRIVE_STRENGTH));
+ DEBUG ((DEBUG_INFO, "HOST_DAT_DRIVE_STRENGTH: 0x%x\n", HOST_DAT_DRIVE_STRENGTH));
+ DEBUG ((DEBUG_INFO, "Host register 0x24: 0x%08X\n", BhtMmRead32 (PciIo, SD_MMC_HC_PRESENT_STATE)));
+ DEBUG ((DEBUG_INFO, "Host register 0x28: 0x%08X\n", BhtMmRead32 (PciIo, SD_MMC_HC_HOST_CTRL1)));
+ DEBUG ((DEBUG_INFO, "Host register 0x2C: 0x%08X\n", BhtMmRead32 (PciIo, SD_MMC_HC_CLOCK_CTRL)));
+ DEBUG ((DEBUG_INFO, "Host register 0x30: 0x%08X\n", BhtMmRead32 (PciIo, SD_MMC_HC_NOR_INT_STS)));
+ DEBUG ((DEBUG_INFO, "Host register 0x3C: 0x%08X\n", BhtMmRead32 (PciIo, SD_MMC_HC_AUTO_CMD_ERR_STS)));
+ DEBUG ((DEBUG_INFO, "Host register 0x110: 0x%08X\n", BhtMmRead32 (PciIo, 0x110)));
+ DEBUG ((DEBUG_INFO, "Host register 0x114: 0x%08X\n", BhtMmRead32 (PciIo, 0x114)));
+ DEBUG ((DEBUG_INFO, "Host register 0x1A8: 0x%08X\n", BhtMmRead32 (PciIo, 0x1A8)));
+ DEBUG ((DEBUG_INFO, "Host register 0x1AC: 0x%08X\n", BhtMmRead32 (PciIo, 0x1AC)));
+ DEBUG ((DEBUG_INFO, "Host register 0x1B0: 0x%08X\n", BhtMmRead32 (PciIo, 0x1B0)));
+ DEBUG ((DEBUG_INFO, "Host register 0x1CC: 0x%08X\n", BhtMmRead32 (PciIo, 0x1CC)));
+
+ DEBUG ((DEBUG_INFO, "PCR 0x300: 0x%08X\n", BhtPciRead32 (PciIo, 0x300)));
+ DEBUG ((DEBUG_INFO, "PCR 0x304: 0x%08X\n", BhtPciRead32 (PciIo, 0x304)));
+ DEBUG ((DEBUG_INFO, "PCR 0x328: 0x%08X\n", BhtPciRead32 (PciIo, 0x328)));
+ DEBUG ((DEBUG_INFO, "PCR 0x3E4: 0x%08X\n", BhtPciRead32 (PciIo, 0x3e4)));
+ }
+}
+
+/**
+ Configure Bayhub Host before initial SD/MMC host controller
+
+ @param[in] PciIo The PCI IO protocol instance.
+ @param[in] Slot The slot number of the SD card to send the command to.
+
+ @retval EFI_SUCCESS The host controller is initialized successfully.
+ @retval Others The host controller isn't initialized successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+BhtHostInit (
+ IN EFI_PCI_IO_PROTOCOL *PciIo,
+ IN UINT8 Slot
+ )
+{
+ UINT16 EmmcVar;
+ UINT32 Value32;
+ EFI_STATUS Status;
+
+ if (BhtHostPciSupportType (PciIo) == EMMC_HOST) {
+ /* FET on */
+ BhtPciOr32 (PciIo, 0xEC, 0x3);
+ /* Led on */
+ BhtPciOr32 (PciIo, 0xD4, BIT6);
+ /* Set 1.8v emmc signaling flag */
+ BhtPciOr32 (PciIo, 0x308, BIT4);
+ }
+
+ /* Set 200MBaseClock */
+ Value32 = BhtPciRead32 (PciIo, 0x304);
+ Value32 &= 0x0000FFFF;
+ Value32 |= 0x25100000;
+
+ /* Host driver strength setting*/
+ EmmcVar = HOST_CLK_DRIVE_STRENGTH;
+ Value32 &= 0xFFFFFF8F;
+ Value32 |= ((EmmcVar & 0x7) << 4);
+ EmmcVar = HOST_DAT_DRIVE_STRENGTH;
+ Value32 &= 0xFFFFFFF1;
+ Value32 |= ((EmmcVar & 0x7) << 1);
+
+ // PCR 0x3E4[22] = 1'b1(Divide the clock to 1/4)
+ BhtPciWrite32 (PciIo, 0x304, Value32);
+ BhtPciOr32 (PciIo, 0x3E4, BIT22);
+
+ // enable internal clk
+ Value32 = BIT0;
+ Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_CLOCK_CTRL, sizeof (Value32), &Value32);
+
+ // reset pll start
+ Status = SdMmcHcRwMmio (PciIo, Slot, 0x1CC, TRUE, sizeof (Value32), &Value32);
+ Value32 |= BIT12;
+ Status = SdMmcHcRwMmio (PciIo, Slot, 0x1CC, FALSE, sizeof (Value32), &Value32);
+ gBS->Stall (1);
+
+ // reset pll end
+ Status = SdMmcHcRwMmio (PciIo, Slot, 0x1CC, TRUE, sizeof (Value32), &Value32);
+ Value32 &= ~BIT12;
+ Value32 |= BIT18;
+ Status = SdMmcHcRwMmio (PciIo, Slot, 0x1CC, FALSE, sizeof (Value32), &Value32);
+
+ // wait BaseClk stable 0x1CC bit14
+ Status = SdMmcHcRwMmio (PciIo, Slot, 0x1CC, TRUE, sizeof (Value32), &Value32);
+ while (!(Value32 & BIT14)) {
+ gBS->Stall (100);
+ Status = SdMmcHcRwMmio (PciIo, Slot, 0x1CC, TRUE, sizeof (Value32), &Value32);
+ DEBUG ((DEBUG_INFO, "1CC=0x%08x\n", Value32));
+ }
+
+ if (Value32 & BIT18) {
+ // Wait 2nd Card Detect debounce Finished by wait twice of debounce max time
+ while (1) {
+ Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_PRESENT_STATE, TRUE, sizeof (Value32), &Value32);
+ if (((Value32 >> 16) & 0x01) == ((Value32 >> 18) & 0x01)) {
+ break;
+ }
+ }
+
+ // force pll active end
+ Status = SdMmcHcRwMmio (PciIo, Slot, 0x1CC, TRUE, sizeof (Value32), &Value32);
+ Value32 &= ~BIT18;
+ Status = SdMmcHcRwMmio (PciIo, Slot, 0x1CC, FALSE, sizeof (Value32), &Value32);
+ }
+
+ return Status;
+}
+
+/**
+ Do Bayhub Host Voltage after initial SD/MMC host controller
+
+ @param[in] PciIo The PCI IO protocol instance.
+ @param[in] Slot The slot number of the SD card to send the command to.
+
+ @retval EFI_SUCCESS The host controller is initialized successfully.
+ @retval Others The host controller isn't initialized successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+BhtHostVoltageSet (
+ IN EFI_PCI_IO_PROTOCOL *PciIo,
+ IN UINT8 Slot
+ )
+{
+ EFI_STATUS Status;
+ UINT8 HostCtrl2;
+ UINT16 ControllerVer;
+ SD_MMC_HC_PRIVATE_DATA Private;
+
+ if (BhtHostPciSupportType (PciIo) == EMMC_HOST) {
+ // 1.8V signaling enable
+ HostCtrl2 = BIT3;
+ Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
+ gBS->Stall (5000);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ } else {
+ /* when disable 1.8v setting for SD card, driver need to delay 10ms
+ waiting for card voltage stable. */
+ gBS->Stall (10000);
+ }
+
+ Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_CTRL_VER, TRUE, sizeof (ControllerVer), &ControllerVer);
+
+ ControllerVer &= 0x0f;
+
+ Private.PciIo = PciIo;
+ Private.BaseClkFreq[Slot] = 200;
+ Private.ControllerVersion[Slot] = ControllerVer;
+
+ Status = SdMmcHcClockSupply (&Private, Slot, 0, TRUE, 400);
+
+ return Status;
+}
+
+/**
+ Override function for SDHCI controller operations
+
+ @param[in] ControllerHandle The EFI_HANDLE of the controller.
+ @param[in] Slot The 0 based slot index.
+ @param[in] PhaseType The type of operation and whether the
+ hook is invoked right before (pre) or
+ right after (post)
+ @param[in,out] PhaseData The pointer to a phase-specific data.
+
+ @retval EFI_SUCCESS The override function completed successfully.
+ @retval EFI_NOT_FOUND The specified controller or slot does not exist.
+ @retval EFI_INVALID_PARAMETER PhaseType is invalid
+
+**/
+EFI_STATUS
+EFIAPI
+BhtHostOverrideNotifyPhase (
+ IN EFI_HANDLE ControllerHandle,
+ IN UINT8 Slot,
+ IN EDKII_SD_MMC_PHASE_TYPE PhaseType,
+ IN OUT VOID *PhaseData
+ )
+{
+ EFI_STATUS Status;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+
+ Status = gBS->HandleProtocol (
+ ControllerHandle,
+ &gEfiPciIoProtocolGuid,
+ (VOID **)&PciIo
+ );
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "open gEfiPciIoProtocolGuid failed at BhtHostOverrideNotifyPhase, Status = 0x%llx\n", Status));
+ return Status;
+ }
+
+ if (BhtHostPciSupportType (PciIo) == UNSUPPORT) {
+ return EFI_SUCCESS;
+ }
+
+ switch (PhaseType) {
+ case EdkiiSdMmcInitHostPre:
+ DEBUG ((DEBUG_INFO, "EdkiiSdMmcInitHostPre\n"));
+ Status = BhtHostInit (PciIo, Slot);
+ break;
+ case EdkiiSdMmcInitHostPost:
+ DEBUG ((DEBUG_INFO, "EdkiiSdMmcInitHostPost\n"));
+ Status = BhtHostVoltageSet (PciIo, Slot);
+ break;
+ case EdkiiSdMmcResetPre:
+ DEBUG ((DEBUG_INFO, "EdkiiSdMmcResetPre\n"));
+ Status = EFI_SUCCESS;
+ break;
+ case EdkiiSdMmcResetPost:
+ DEBUG ((DEBUG_INFO, "EdkiiSdMmcResetPost\n"));
+ Status = EFI_SUCCESS;
+ break;
+ case EdkiiSdMmcUhsSignaling:
+ DEBUG ((DEBUG_INFO, "EdkiiSdMmcUhsSignaling\n"));
+ Status = EFI_SUCCESS;
+ break;
+ case EdkiiSdMmcSwitchClockFreqPost:
+ DEBUG ((DEBUG_INFO, "EdkiiSdMmcSwitchClockFreqPost\n"));
+ BhtDbgDump (PciIo);
+ Status = EFI_SUCCESS;
+ break;
+ case EdkiiSdMmcGetOperatingParam:
+ DEBUG ((DEBUG_INFO, "EdkiiSdMmcGetOperatingParam\n"));
+ Status = EFI_SUCCESS;
+ break;
+ default:
+ DEBUG ((DEBUG_INFO, "Overridenotify\n"));
+ Status = EFI_SUCCESS;
+ break;
+ }
+
+ return Status;
+}
+
+/**
+ Override function for SDHCI capability bits
+
+ @param[in] ControllerHandle The EFI_HANDLE of the controller.
+ @param[in] Slot The 0 based slot index.
+ @param[in,out] SdMmcHcSlotCapability The SDHCI capability structure.
+ @param[in,out] BaseClkFreq The base clock frequency value that
+ optionally can be updated.
+
+ @retval EFI_SUCCESS The override function completed successfully.
+ @retval EFI_NOT_FOUND The specified controller or slot does not exist.
+ @retval EFI_INVALID_PARAMETER SdMmcHcSlotCapability is NULL
+
+**/
+EFI_STATUS
+EFIAPI
+BhtHostOverrideCapability (
+ IN EFI_HANDLE ControllerHandle,
+ IN UINT8 Slot,
+ IN OUT VOID *SdMmcHcSlotCapability,
+ IN OUT UINT32 *BaseClkFreq
+ )
+{
+ EFI_STATUS Status;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ SD_MMC_HC_SLOT_CAP *Cap;
+
+ Status = gBS->HandleProtocol (
+ ControllerHandle,
+ &gEfiPciIoProtocolGuid,
+ (VOID **)&PciIo
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (BhtHostPciSupportType (PciIo) == UNSUPPORT) {
+ return EFI_SUCCESS;
+ }
+
+ Cap = SdMmcHcSlotCapability;
+
+ Cap->HighSpeed = 1;
+ Cap->Sdr104 = 0;
+ Cap->Ddr50 = 0;
+ Cap->Sdr50 = 0;
+ Cap->Hs400 = 0;
+ Cap->BusWidth8 = 1;
+ Cap->BaseClkFreq = 200;
+ Cap->SysBus64V3 = 0;
+ *BaseClkFreq = Cap->BaseClkFreq;
+
+ return EFI_SUCCESS;
+}
diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.c b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.c
index ab2becdd19..c333f12618 100644
--- a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.c
+++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.c
@@ -13,6 +13,7 @@
**/
#include "SdMmcPciHcDxe.h"
+#include "BayhubHost.h"
EDKII_SD_MMC_OVERRIDE *mOverride;
@@ -136,6 +137,8 @@ InitializeSdMmcPciHcDxe (
);
ASSERT_EFI_ERROR (Status);
+ mOverride = &BhtOverride;
+
return Status;
}
diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/BayhubHost.h b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/BayhubHost.h
new file mode 100644
index 0000000000..fc069e6342
--- /dev/null
+++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/BayhubHost.h
@@ -0,0 +1,95 @@
+/** @file
+This driver is used to manage SD/MMC PCI host controllers override function
+for BayHub BH720 eMMC host controller.
+
+Copyright (c) 2018 - 2019, BayHub Tech inc. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef BAYHUB_HOST_H_
+#define BAYHUB_HOST_H_
+
+#include <Uefi.h>
+#include <Protocol/SdMmcOverride.h>
+#include <Protocol/PciIo.h>
+#include <Library/UefiLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Guid/DebugMask.h>
+
+// O2/BHT add BAR1 for PCIR mapping registers
+// These registers is defined by O2/BHT, but we may follow name definition rule.
+#define BHT_PCR_MAP_VAL 0x200 /* PCI CFG Space Register Mapping Value Register */
+#define BHT_PCR_MAP_CTL 0x204 /* PCI CFG Space Register Mapping Control Register */
+#define BHT_PCR_MAP_EN 0x208 /* PCI CFG Space Register Mapping Enable Register */
+#define BHT_GPIOCTL 0x210 /* GPIO control register*/
+
+#define HOST_CLK_DRIVE_STRENGTH 2
+#define HOST_DAT_DRIVE_STRENGTH 2
+#define HS200_ALLPASS_PHASE 0
+#define HS100_ALLPASS_PHASE 6
+
+#define UNSUPPORT 0
+#define SD_HOST 1
+#define EMMC_HOST 2
+
+#define PCI_DEV_ID_RJ 0x8320
+#define PCI_DEV_ID_SDS0 0x8420
+#define PCI_DEV_ID_SDS1 0x8421
+#define PCI_DEV_ID_FJ2 0x8520
+#define PCI_DEV_ID_SB0 0x8620
+#define PCI_DEV_ID_SB1 0x8621
+#define PCI_DEV_ID_SE2 0x8720
+
+/**
+ Override function for SDHCI capability bits
+
+ @param[in] ControllerHandle The EFI_HANDLE of the controller.
+ @param[in] Slot The 0 based slot index.
+ @param[in,out] SdMmcHcSlotCapability The SDHCI capability structure.
+ @param[in,out] BaseClkFreq The base clock frequency value that
+ optionally can be updated.
+
+ @retval EFI_SUCCESS The override function completed successfully.
+ @retval EFI_NOT_FOUND The specified controller or slot does not exist.
+ @retval EFI_INVALID_PARAMETER SdMmcHcSlotCapability is NULL
+
+**/
+EFI_STATUS
+EFIAPI
+BhtHostOverrideCapability (
+ IN EFI_HANDLE ControllerHandle,
+ IN UINT8 Slot,
+ IN OUT VOID *SdMmcHcSlotCapability,
+ IN OUT UINT32 *BaseClkFreq
+ );
+
+/**
+ Override function for SDHCI controller operations
+
+ @param[in] ControllerHandle The EFI_HANDLE of the controller.
+ @param[in] Slot The 0 based slot index.
+ @param[in] PhaseType The type of operation and whether the
+ hook is invoked right before (pre) or
+ right after (post)
+ @param[in,out] PhaseData The pointer to a phase-specific data.
+
+ @retval EFI_SUCCESS The override function completed successfully.
+ @retval EFI_NOT_FOUND The specified controller or slot does not exist.
+ @retval EFI_INVALID_PARAMETER PhaseType is invalid
+
+**/
+EFI_STATUS
+EFIAPI
+BhtHostOverrideNotifyPhase (
+ IN EFI_HANDLE ControllerHandle,
+ IN UINT8 Slot,
+ IN EDKII_SD_MMC_PHASE_TYPE PhaseType,
+ IN OUT VOID *PhaseData
+ );
+
+extern EDKII_SD_MMC_OVERRIDE BhtOverride;
+
+#endif
diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.inf b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.inf
index e502443ddd..adb8f20984 100644
--- a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.inf
+++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.inf
@@ -41,6 +41,8 @@
SdMmcPciHci.h
SdMmcPciHci.c
ComponentName.c
+ BayhubHost.c
+ BayhubHost.h
[Packages]
MdePkg/MdePkg.dec
base-commit: 9d669016d968b0f3e17ce7df16ae51d85b0adfcf
--
2.18.0.windows.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [edk2-platform][PATCH 1/1] MdeModulePkg: SdMmcPciHcDxe: Support for Bayhub SD/eMMC host
2023-02-24 12:39 [edk2-platform][PATCH 1/1] MdeModulePkg: SdMmcPciHcDxe: Support for Bayhub SD/eMMC host Chevron Li
@ 2023-02-28 2:55 ` Wu, Hao A
0 siblings, 0 replies; 2+ messages in thread
From: Wu, Hao A @ 2023-02-28 2:55 UTC (permalink / raw)
To: Chevron Li, devel@edk2.groups.io
Cc: Ni, Ray, Wang, Jian J, Gao, Liming, shaper.liu@bayhubtech.com,
chevron.li@bayhubtech.com, xiaoguang.yu@bayhubtech.com,
shirley.her@bayhubtech.com
Thanks for the patch.
The proposed method is not the intended way for the EDKII_SD_MMC_OVERRIDE protocol to work.
The content in BayhubHost.c should be placed a platform level driver.
This platform level driver should produce the EDKII_SD_MMC_OVERRIDE protocol.
Then SdMmcPciHcDxe will consume the protocol to perform the platform specific actions.
Best Regards,
Hao Wu
> -----Original Message-----
> From: Chevron Li <chevron_li@126.com>
> Sent: Friday, February 24, 2023 8:40 PM
> To: devel@edk2.groups.io
> Cc: Wu, Hao A <hao.a.wu@intel.com>; Ni, Ray <ray.ni@intel.com>; Wang,
> Jian J <jian.j.wang@intel.com>; Gao, Liming <gaoliming@byosoft.com.cn>;
> shaper.liu@bayhubtech.com; chevron.li@bayhubtech.com;
> xiaoguang.yu@bayhubtech.com; shirley.her@bayhubtech.com
> Subject: [edk2-platform][PATCH 1/1] MdeModulePkg: SdMmcPciHcDxe:
> Support for Bayhub SD/eMMC host
>
> From: "Chevron Li (WH)" <chevron.li@bayhubtech.com>
>
> 1.Implement override function for EdkiiSdMmcInitHostPre case to
> configure bayhub host.
> 2.Implement override function for EdkiiSdMmcInitHostPost case to
> configure bayhub host.
>
> Cc: Hao A Wu <hao.a.wu@intel.com>
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Jian J Wang <jian.j.wang@intel.com>
> Cc: Liming Gao <gaoliming@byosoft.com.cn>
> Signed-off-by: Chevron Li <chevron.li@bayhubtech.com>
> ---
> .../Bus/Pci/SdMmcPciHcDxe/BayhubHost.c | 676 ++++++++++++++++++
> .../Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.c | 3 +
> .../Bus/Pci/SdMmcPciHcDxe/BayhubHost.h | 95 +++
> .../Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.inf | 2 +
> 4 files changed, 776 insertions(+)
> create mode 100644
> MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/BayhubHost.c
> create mode 100644
> MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/BayhubHost.h
>
> diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/BayhubHost.c
> b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/BayhubHost.c
> new file mode 100644
> index 0000000000..470838e37e
> --- /dev/null
> +++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/BayhubHost.c
> @@ -0,0 +1,676 @@
> +/** @file
> + This driver is used to manage SD/MMC PCI host controllers override
> function
> + for BayHub SD/eMMC host controller.
> +
> + Copyright (c) 2018 - 2019, BayHub Tech inc. All rights reserved.
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "BayhubHost.h"
> +#include "SdMmcPciHcDxe.h"
> +#include <Protocol/PciIo.h>
> +
> +/* Driver global variables*/
> +UINT16 BhtDeviceId = 0;
> +
> +EDKII_SD_MMC_OVERRIDE BhtOverride = {
> + EDKII_SD_MMC_OVERRIDE_PROTOCOL_VERSION,
> + BhtHostOverrideCapability,
> + BhtHostOverrideNotifyPhase
> +};
> +
> +/**
> + Judgement function for Host type
> +
> + @param[in] PciIo The PCI IO protocol instance.
> +
> + @retval UNSUPPORT The host isn't Bayhub host.
> + @retval EMMC_HOST The host is Bayhub eMMC host.
> + @retval SD_HOST The host is Bayhub SD host.
> +
> +**/
> +UINT8
> +BhtHostPciSupportType (
> + IN EFI_PCI_IO_PROTOCOL *PciIo
> + )
> +{
> + PCI_TYPE00 Pci;
> + UINT8 HostType;
> +
> + PciIo->Pci.Read (
> + PciIo,
> + EfiPciIoWidthUint32,
> + 0,
> + sizeof (PCI_TYPE00) / sizeof (UINT32),
> + &Pci
> + );
> + DEBUG ((DEBUG_INFO, "Check device %04x:%04x\n", Pci.Hdr.VendorId,
> Pci.Hdr.DeviceId));
> +
> + // Judgement bayhub device or not
> + if (Pci.Hdr.VendorId != 0x1217) {
> + HostType = UNSUPPORT;
> + goto end;
> + }
> +
> + BhtDeviceId = Pci.Hdr.DeviceId;
> +
> + // Bayhub host only 0x8620 is eMMC host
> + switch (Pci.Hdr.DeviceId) {
> + case PCI_DEV_ID_SB0:
> + HostType = EMMC_HOST;
> + break;
> + case PCI_DEV_ID_SB1:
> + default:
> + HostType = SD_HOST;
> + break;
> + }
> +
> +end:
> + return HostType;
> +}
> +
> +/**
> + Read specified SD/MMC host controller mmio register
> +
> + @param[in] PciIo The PCI IO protocol instance.
> + @param[in] Offset The Offset within the selected BAR to start the
> + memory operation.
> +
> + @retval Value The value of specified SD/MMC host controller
> mmio register.
> +
> +**/
> +UINT32
> +BhtMmRead32 (
> + IN EFI_PCI_IO_PROTOCOL *PciIo,
> + IN UINT32 Offset
> + )
> +{
> + UINT32 Value;
> +
> + PciIo->Mem.Read (PciIo, EfiPciIoWidthUint32, 1, Offset, 1, &Value);
> + return Value;
> +}
> +
> +/**
> + Write specified SD/MMC host controller mmio register
> +
> + @param[in] PciIo The PCI IO protocol instance.
> + @param[in] Offset The Offset within the selected BAR to start the
> + memory operation.
> + @param[in] Value The value to write.
> +
> +**/
> +VOID
> +BhtMmWrite32 (
> + IN EFI_PCI_IO_PROTOCOL *PciIo,
> + IN UINT32 Offset,
> + IN UINT32 Value
> + )
> +{
> + PciIo->Mem.Write (PciIo, EfiPciIoWidthUint32, 1, Offset, 1, &Value);
> +}
> +
> +/**
> + Read specified SD/MMC host controller PCIe configure register
> +
> + @param[in] PciIo The PCI IO protocol instance.
> + @param[in] Offset The Offset within the selected BAR to start the
> + memory operation.
> +
> + @retval Value The value of specified SD/MMC host controller
> PCIe configure register.
> +
> +**/
> +UINT32
> +BhtPciRead32 (
> + IN EFI_PCI_IO_PROTOCOL *PciIo,
> + IN UINT32 Offset
> + )
> +{
> + UINT32 Index;
> + UINT32 TmpBuff[2];
> +
> + if ((BhtDeviceId == PCI_DEV_ID_SDS0) ||
> + (BhtDeviceId == PCI_DEV_ID_SDS1) ||
> + (BhtDeviceId == PCI_DEV_ID_FJ2) ||
> + (BhtDeviceId == PCI_DEV_ID_SB0) ||
> + (BhtDeviceId == PCI_DEV_ID_SB1))
> + {
> + // For Sandstorm, HW implement a mapping method by memory space
> reg to access PCI reg.
> + // Enable mapping
> +
> + // Check function conflict
> + if ((BhtDeviceId == PCI_DEV_ID_SDS0) ||
> + (BhtDeviceId == PCI_DEV_ID_FJ2) ||
> + (BhtDeviceId == PCI_DEV_ID_SB0) ||
> + (BhtDeviceId == PCI_DEV_ID_SB1))
> + {
> + Index = 0;
> + BhtMmWrite32 (PciIo, BHT_PCR_MAP_EN, 0x40000000);
> + while ((BhtMmRead32 (PciIo, BHT_PCR_MAP_EN) & 0x40000000) == 0) {
> + if (Index == 5) {
> + goto RD_DIS_MAPPING;
> + }
> +
> + gBS->Stall (1000);
> + Index++;
> + BhtMmWrite32 (PciIo, BHT_PCR_MAP_EN, 0x40000000);
> + }
> + } else if (BhtDeviceId == PCI_DEV_ID_SDS1) {
> + Index = 0;
> + BhtMmWrite32 (PciIo, BHT_PCR_MAP_EN, 0x20000000);
> + while ((BhtMmRead32 (PciIo, BHT_PCR_MAP_EN) & 0x20000000) == 0) {
> + if (Index == 5) {
> + goto RD_DIS_MAPPING;
> + }
> +
> + gBS->Stall (1000);
> + Index++;
> + BhtMmWrite32 (PciIo, BHT_PCR_MAP_EN, 0x20000000);
> + }
> + }
> +
> + // Check last operation is complete
> + Index = 0;
> + while (BhtMmRead32 (PciIo, BHT_PCR_MAP_CTL) & 0xc0000000) {
> + if (Index == 5) {
> + goto RD_DIS_MAPPING;
> + }
> +
> + gBS->Stall (1000);
> + Index++;
> + }
> +
> + // Set register address
> + TmpBuff[0] = 0x40000000;
> + TmpBuff[0] |= Offset;
> + BhtMmWrite32 (PciIo, BHT_PCR_MAP_CTL, TmpBuff[0]);
> +
> + // Check read is complete
> + Index = 0;
> + while (BhtMmRead32 (PciIo, BHT_PCR_MAP_CTL) & 0x40000000) {
> + if (Index == 5) {
> + goto RD_DIS_MAPPING;
> + }
> +
> + gBS->Stall (1000);
> + Index++;
> + }
> +
> + // Get PCIR value
> + TmpBuff[1] = BhtMmRead32 (PciIo, BHT_PCR_MAP_VAL);
> +
> +RD_DIS_MAPPING:
> + // Disable mapping
> + BhtMmWrite32 (PciIo, BHT_PCR_MAP_EN, 0x80000000);
> + return TmpBuff[1];
> + } else {
> + return BhtMmRead32 (PciIo, Offset);
> + }
> +}
> +
> +/**
> + Write specified SD/MMC host controller PCIe configure register
> +
> + @param[in] PciIo The PCI IO protocol instance.
> + @param[in] Offset The Offset within the selected BAR to start the
> + memory operation.
> + @param[in] Value The value to write.
> +
> +**/
> +VOID
> +BhtPciWrite32 (
> + IN EFI_PCI_IO_PROTOCOL *PciIo,
> + IN UINT32 Offset,
> + IN UINT32 Value
> + )
> +{
> + UINT32 TmpBuff;
> + UINT32 Index;
> +
> + if ((BhtDeviceId == PCI_DEV_ID_SDS0) ||
> + (BhtDeviceId == PCI_DEV_ID_SDS1) ||
> + (BhtDeviceId == PCI_DEV_ID_FJ2) ||
> + (BhtDeviceId == PCI_DEV_ID_SB0) ||
> + (BhtDeviceId == PCI_DEV_ID_SB1))
> + {
> + // Enable mapping
> + // Check function conflict
> + if ((BhtDeviceId == PCI_DEV_ID_SDS0) ||
> + (BhtDeviceId == PCI_DEV_ID_FJ2) ||
> + (BhtDeviceId == PCI_DEV_ID_SB0) ||
> + (BhtDeviceId == PCI_DEV_ID_SB1))
> + {
> + Index = 0;
> + BhtMmWrite32 (PciIo, BHT_PCR_MAP_EN, 0x40000000);
> + while ((BhtMmRead32 (PciIo, BHT_PCR_MAP_EN) & 0x40000000) == 0) {
> + if (Index == 5) {
> + goto WR_DIS_MAPPING;
> + }
> +
> + gBS->Stall (1000);
> + Index++;
> + BhtMmWrite32 (PciIo, BHT_PCR_MAP_EN, 0x40000000);
> + }
> + } else if (BhtDeviceId == PCI_DEV_ID_SDS1) {
> + Index = 0;
> + BhtMmWrite32 (PciIo, BHT_PCR_MAP_EN, 0x20000000);
> +
> + while ((BhtMmRead32 (PciIo, BHT_PCR_MAP_EN) & 0x20000000) == 0) {
> + if (Index == 5) {
> + goto WR_DIS_MAPPING;
> + }
> +
> + gBS->Stall (1000);
> + Index++;
> + BhtMmWrite32 (PciIo, BHT_PCR_MAP_EN, 0x20000000);
> + }
> + }
> +
> + // Enable MEM access
> + BhtMmWrite32 (PciIo, BHT_PCR_MAP_VAL, 0x80000000);
> + BhtMmWrite32 (PciIo, BHT_PCR_MAP_CTL, 0x800000D0);
> +
> + // Check last operation is complete
> + Index = 0;
> + while (BhtMmRead32 (PciIo, BHT_PCR_MAP_CTL) & 0xc0000000) {
> + if (Index == 5) {
> + goto WR_DIS_MAPPING;
> + }
> +
> + gBS->Stall (1000);
> + Index++;
> + }
> +
> + // Set write value
> + BhtMmWrite32 (PciIo, BHT_PCR_MAP_VAL, Value);
> + // Set register address
> + TmpBuff = 0x80000000;
> + TmpBuff |= Offset;
> + BhtMmWrite32 (PciIo, BHT_PCR_MAP_CTL, TmpBuff);
> +
> + // Check write is complete
> + Index = 0;
> + while (BhtMmRead32 (PciIo, BHT_PCR_MAP_CTL) & 0x80000000) {
> + if (Index == 5) {
> + goto WR_DIS_MAPPING;
> + }
> +
> + gBS->Stall (1000);
> + Index++;
> + }
> +
> +WR_DIS_MAPPING:
> + // Disable MEM access
> + BhtMmWrite32 (PciIo, BHT_PCR_MAP_VAL, 0x80000001);
> + BhtMmWrite32 (PciIo, BHT_PCR_MAP_CTL, 0x800000D0);
> +
> + // Check last operation is complete
> + Index = 0;
> + while (BhtMmRead32 (PciIo, BHT_PCR_MAP_CTL) & 0xc0000000) {
> + if (Index == 5) {
> + break;
> + }
> +
> + gBS->Stall (1000);
> + Index++;
> + }
> +
> + // Disable function conflict
> + // Disable mapping
> + BhtMmWrite32 (PciIo, BHT_PCR_MAP_EN, 0x80000000);
> + } else {
> + BhtMmWrite32 (PciIo, Offset, Value);
> + }
> +}
> +
> +/**
> + Do OR operation with the value of the specified SD/MMC host controller
> PCIe configure register
> +
> + @param[in] PciIo The PCI IO protocol instance.
> + @param[in] Offset The Offset within the selected BAR to start the
> + memory operation.
> + @param[in] Value The value to do OR operation.
> +
> +**/
> +VOID
> +BhtPciOr32 (
> + IN EFI_PCI_IO_PROTOCOL *PciIo,
> + IN UINT32 Offset,
> + IN UINT32 Value
> + )
> +{
> + UINT32 OldValue;
> +
> + OldValue = BhtPciRead32 (PciIo, Offset);
> + BhtPciWrite32 (PciIo, Offset, Value | OldValue);
> +}
> +
> +/**
> + Do AND operation with the value of the specified SD/MMC host controller
> PCIe configure register
> +
> + @param[in] PciIo The PCI IO protocol instance.
> + @param[in] Offset The Offset within the selected BAR to start the
> + memory operation.
> + @param[in] Value The value to do AND operation.
> +
> +**/
> +VOID
> +PciBhtAnd32 (
> + IN EFI_PCI_IO_PROTOCOL *PciIo,
> + IN UINT32 Offset,
> + IN UINT32 Value
> + )
> +{
> + UINT32 OldValue;
> +
> + OldValue = BhtPciRead32 (PciIo, Offset);
> + BhtPciWrite32 (PciIo, Offset, Value & OldValue);
> +}
> +
> +/**
> + Dump the content of SD/MMC host controller's key Registers.
> +
> + @param[in] PciIo The PCI IO protocol instance.
> +
> +**/
> +VOID
> +BhtDbgDump (
> + IN EFI_PCI_IO_PROTOCOL *PciIo
> + )
> +{
> + if (BhtHostPciSupportType (PciIo) != UNSUPPORT) {
> + DEBUG ((DEBUG_INFO, "HOST_CLK_DRIVE_STRENGTH: 0x%x\n",
> HOST_CLK_DRIVE_STRENGTH));
> + DEBUG ((DEBUG_INFO, "HOST_DAT_DRIVE_STRENGTH: 0x%x\n",
> HOST_DAT_DRIVE_STRENGTH));
> + DEBUG ((DEBUG_INFO, "Host register 0x24: 0x%08X\n", BhtMmRead32
> (PciIo, SD_MMC_HC_PRESENT_STATE)));
> + DEBUG ((DEBUG_INFO, "Host register 0x28: 0x%08X\n", BhtMmRead32
> (PciIo, SD_MMC_HC_HOST_CTRL1)));
> + DEBUG ((DEBUG_INFO, "Host register 0x2C: 0x%08X\n", BhtMmRead32
> (PciIo, SD_MMC_HC_CLOCK_CTRL)));
> + DEBUG ((DEBUG_INFO, "Host register 0x30: 0x%08X\n", BhtMmRead32
> (PciIo, SD_MMC_HC_NOR_INT_STS)));
> + DEBUG ((DEBUG_INFO, "Host register 0x3C: 0x%08X\n", BhtMmRead32
> (PciIo, SD_MMC_HC_AUTO_CMD_ERR_STS)));
> + DEBUG ((DEBUG_INFO, "Host register 0x110: 0x%08X\n", BhtMmRead32
> (PciIo, 0x110)));
> + DEBUG ((DEBUG_INFO, "Host register 0x114: 0x%08X\n", BhtMmRead32
> (PciIo, 0x114)));
> + DEBUG ((DEBUG_INFO, "Host register 0x1A8: 0x%08X\n", BhtMmRead32
> (PciIo, 0x1A8)));
> + DEBUG ((DEBUG_INFO, "Host register 0x1AC: 0x%08X\n", BhtMmRead32
> (PciIo, 0x1AC)));
> + DEBUG ((DEBUG_INFO, "Host register 0x1B0: 0x%08X\n", BhtMmRead32
> (PciIo, 0x1B0)));
> + DEBUG ((DEBUG_INFO, "Host register 0x1CC: 0x%08X\n", BhtMmRead32
> (PciIo, 0x1CC)));
> +
> + DEBUG ((DEBUG_INFO, "PCR 0x300: 0x%08X\n", BhtPciRead32 (PciIo,
> 0x300)));
> + DEBUG ((DEBUG_INFO, "PCR 0x304: 0x%08X\n", BhtPciRead32 (PciIo,
> 0x304)));
> + DEBUG ((DEBUG_INFO, "PCR 0x328: 0x%08X\n", BhtPciRead32 (PciIo,
> 0x328)));
> + DEBUG ((DEBUG_INFO, "PCR 0x3E4: 0x%08X\n", BhtPciRead32 (PciIo,
> 0x3e4)));
> + }
> +}
> +
> +/**
> + Configure Bayhub Host before initial SD/MMC host controller
> +
> + @param[in] PciIo The PCI IO protocol instance.
> + @param[in] Slot The slot number of the SD card to send the
> command to.
> +
> + @retval EFI_SUCCESS The host controller is initialized successfully.
> + @retval Others The host controller isn't initialized successfully.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BhtHostInit (
> + IN EFI_PCI_IO_PROTOCOL *PciIo,
> + IN UINT8 Slot
> + )
> +{
> + UINT16 EmmcVar;
> + UINT32 Value32;
> + EFI_STATUS Status;
> +
> + if (BhtHostPciSupportType (PciIo) == EMMC_HOST) {
> + /* FET on */
> + BhtPciOr32 (PciIo, 0xEC, 0x3);
> + /* Led on */
> + BhtPciOr32 (PciIo, 0xD4, BIT6);
> + /* Set 1.8v emmc signaling flag */
> + BhtPciOr32 (PciIo, 0x308, BIT4);
> + }
> +
> + /* Set 200MBaseClock */
> + Value32 = BhtPciRead32 (PciIo, 0x304);
> + Value32 &= 0x0000FFFF;
> + Value32 |= 0x25100000;
> +
> + /* Host driver strength setting*/
> + EmmcVar = HOST_CLK_DRIVE_STRENGTH;
> + Value32 &= 0xFFFFFF8F;
> + Value32 |= ((EmmcVar & 0x7) << 4);
> + EmmcVar = HOST_DAT_DRIVE_STRENGTH;
> + Value32 &= 0xFFFFFFF1;
> + Value32 |= ((EmmcVar & 0x7) << 1);
> +
> + // PCR 0x3E4[22] = 1'b1(Divide the clock to 1/4)
> + BhtPciWrite32 (PciIo, 0x304, Value32);
> + BhtPciOr32 (PciIo, 0x3E4, BIT22);
> +
> + // enable internal clk
> + Value32 = BIT0;
> + Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_CLOCK_CTRL, sizeof
> (Value32), &Value32);
> +
> + // reset pll start
> + Status = SdMmcHcRwMmio (PciIo, Slot, 0x1CC, TRUE, sizeof (Value32),
> &Value32);
> + Value32 |= BIT12;
> + Status = SdMmcHcRwMmio (PciIo, Slot, 0x1CC, FALSE, sizeof (Value32),
> &Value32);
> + gBS->Stall (1);
> +
> + // reset pll end
> + Status = SdMmcHcRwMmio (PciIo, Slot, 0x1CC, TRUE, sizeof (Value32),
> &Value32);
> + Value32 &= ~BIT12;
> + Value32 |= BIT18;
> + Status = SdMmcHcRwMmio (PciIo, Slot, 0x1CC, FALSE, sizeof (Value32),
> &Value32);
> +
> + // wait BaseClk stable 0x1CC bit14
> + Status = SdMmcHcRwMmio (PciIo, Slot, 0x1CC, TRUE, sizeof (Value32),
> &Value32);
> + while (!(Value32 & BIT14)) {
> + gBS->Stall (100);
> + Status = SdMmcHcRwMmio (PciIo, Slot, 0x1CC, TRUE, sizeof (Value32),
> &Value32);
> + DEBUG ((DEBUG_INFO, "1CC=0x%08x\n", Value32));
> + }
> +
> + if (Value32 & BIT18) {
> + // Wait 2nd Card Detect debounce Finished by wait twice of debounce
> max time
> + while (1) {
> + Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_PRESENT_STATE,
> TRUE, sizeof (Value32), &Value32);
> + if (((Value32 >> 16) & 0x01) == ((Value32 >> 18) & 0x01)) {
> + break;
> + }
> + }
> +
> + // force pll active end
> + Status = SdMmcHcRwMmio (PciIo, Slot, 0x1CC, TRUE, sizeof (Value32),
> &Value32);
> + Value32 &= ~BIT18;
> + Status = SdMmcHcRwMmio (PciIo, Slot, 0x1CC, FALSE, sizeof (Value32),
> &Value32);
> + }
> +
> + return Status;
> +}
> +
> +/**
> + Do Bayhub Host Voltage after initial SD/MMC host controller
> +
> + @param[in] PciIo The PCI IO protocol instance.
> + @param[in] Slot The slot number of the SD card to send the
> command to.
> +
> + @retval EFI_SUCCESS The host controller is initialized successfully.
> + @retval Others The host controller isn't initialized successfully.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BhtHostVoltageSet (
> + IN EFI_PCI_IO_PROTOCOL *PciIo,
> + IN UINT8 Slot
> + )
> +{
> + EFI_STATUS Status;
> + UINT8 HostCtrl2;
> + UINT16 ControllerVer;
> + SD_MMC_HC_PRIVATE_DATA Private;
> +
> + if (BhtHostPciSupportType (PciIo) == EMMC_HOST) {
> + // 1.8V signaling enable
> + HostCtrl2 = BIT3;
> + Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2,
> sizeof (HostCtrl2), &HostCtrl2);
> + gBS->Stall (5000);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> + } else {
> + /* when disable 1.8v setting for SD card, driver need to delay 10ms
> + waiting for card voltage stable. */
> + gBS->Stall (10000);
> + }
> +
> + Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_CTRL_VER, TRUE,
> sizeof (ControllerVer), &ControllerVer);
> +
> + ControllerVer &= 0x0f;
> +
> + Private.PciIo = PciIo;
> + Private.BaseClkFreq[Slot] = 200;
> + Private.ControllerVersion[Slot] = ControllerVer;
> +
> + Status = SdMmcHcClockSupply (&Private, Slot, 0, TRUE, 400);
> +
> + return Status;
> +}
> +
> +/**
> + Override function for SDHCI controller operations
> +
> + @param[in] ControllerHandle The EFI_HANDLE of the controller.
> + @param[in] Slot The 0 based slot index.
> + @param[in] PhaseType The type of operation and whether the
> + hook is invoked right before (pre) or
> + right after (post)
> + @param[in,out] PhaseData The pointer to a phase-specific data.
> +
> + @retval EFI_SUCCESS The override function completed successfully.
> + @retval EFI_NOT_FOUND The specified controller or slot does not
> exist.
> + @retval EFI_INVALID_PARAMETER PhaseType is invalid
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BhtHostOverrideNotifyPhase (
> + IN EFI_HANDLE ControllerHandle,
> + IN UINT8 Slot,
> + IN EDKII_SD_MMC_PHASE_TYPE PhaseType,
> + IN OUT VOID *PhaseData
> + )
> +{
> + EFI_STATUS Status;
> + EFI_PCI_IO_PROTOCOL *PciIo;
> +
> + Status = gBS->HandleProtocol (
> + ControllerHandle,
> + &gEfiPciIoProtocolGuid,
> + (VOID **)&PciIo
> + );
> +
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "open gEfiPciIoProtocolGuid failed at
> BhtHostOverrideNotifyPhase, Status = 0x%llx\n", Status));
> + return Status;
> + }
> +
> + if (BhtHostPciSupportType (PciIo) == UNSUPPORT) {
> + return EFI_SUCCESS;
> + }
> +
> + switch (PhaseType) {
> + case EdkiiSdMmcInitHostPre:
> + DEBUG ((DEBUG_INFO, "EdkiiSdMmcInitHostPre\n"));
> + Status = BhtHostInit (PciIo, Slot);
> + break;
> + case EdkiiSdMmcInitHostPost:
> + DEBUG ((DEBUG_INFO, "EdkiiSdMmcInitHostPost\n"));
> + Status = BhtHostVoltageSet (PciIo, Slot);
> + break;
> + case EdkiiSdMmcResetPre:
> + DEBUG ((DEBUG_INFO, "EdkiiSdMmcResetPre\n"));
> + Status = EFI_SUCCESS;
> + break;
> + case EdkiiSdMmcResetPost:
> + DEBUG ((DEBUG_INFO, "EdkiiSdMmcResetPost\n"));
> + Status = EFI_SUCCESS;
> + break;
> + case EdkiiSdMmcUhsSignaling:
> + DEBUG ((DEBUG_INFO, "EdkiiSdMmcUhsSignaling\n"));
> + Status = EFI_SUCCESS;
> + break;
> + case EdkiiSdMmcSwitchClockFreqPost:
> + DEBUG ((DEBUG_INFO, "EdkiiSdMmcSwitchClockFreqPost\n"));
> + BhtDbgDump (PciIo);
> + Status = EFI_SUCCESS;
> + break;
> + case EdkiiSdMmcGetOperatingParam:
> + DEBUG ((DEBUG_INFO, "EdkiiSdMmcGetOperatingParam\n"));
> + Status = EFI_SUCCESS;
> + break;
> + default:
> + DEBUG ((DEBUG_INFO, "Overridenotify\n"));
> + Status = EFI_SUCCESS;
> + break;
> + }
> +
> + return Status;
> +}
> +
> +/**
> + Override function for SDHCI capability bits
> +
> + @param[in] ControllerHandle The EFI_HANDLE of the controller.
> + @param[in] Slot The 0 based slot index.
> + @param[in,out] SdMmcHcSlotCapability The SDHCI capability structure.
> + @param[in,out] BaseClkFreq The base clock frequency value that
> + optionally can be updated.
> +
> + @retval EFI_SUCCESS The override function completed successfully.
> + @retval EFI_NOT_FOUND The specified controller or slot does not
> exist.
> + @retval EFI_INVALID_PARAMETER SdMmcHcSlotCapability is NULL
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BhtHostOverrideCapability (
> + IN EFI_HANDLE ControllerHandle,
> + IN UINT8 Slot,
> + IN OUT VOID *SdMmcHcSlotCapability,
> + IN OUT UINT32 *BaseClkFreq
> + )
> +{
> + EFI_STATUS Status;
> + EFI_PCI_IO_PROTOCOL *PciIo;
> + SD_MMC_HC_SLOT_CAP *Cap;
> +
> + Status = gBS->HandleProtocol (
> + ControllerHandle,
> + &gEfiPciIoProtocolGuid,
> + (VOID **)&PciIo
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + if (BhtHostPciSupportType (PciIo) == UNSUPPORT) {
> + return EFI_SUCCESS;
> + }
> +
> + Cap = SdMmcHcSlotCapability;
> +
> + Cap->HighSpeed = 1;
> + Cap->Sdr104 = 0;
> + Cap->Ddr50 = 0;
> + Cap->Sdr50 = 0;
> + Cap->Hs400 = 0;
> + Cap->BusWidth8 = 1;
> + Cap->BaseClkFreq = 200;
> + Cap->SysBus64V3 = 0;
> + *BaseClkFreq = Cap->BaseClkFreq;
> +
> + return EFI_SUCCESS;
> +}
> diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.c
> b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.c
> index ab2becdd19..c333f12618 100644
> --- a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.c
> +++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.c
> @@ -13,6 +13,7 @@
> **/
>
> #include "SdMmcPciHcDxe.h"
> +#include "BayhubHost.h"
>
> EDKII_SD_MMC_OVERRIDE *mOverride;
>
> @@ -136,6 +137,8 @@ InitializeSdMmcPciHcDxe (
> );
> ASSERT_EFI_ERROR (Status);
>
> + mOverride = &BhtOverride;
> +
> return Status;
> }
>
> diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/BayhubHost.h
> b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/BayhubHost.h
> new file mode 100644
> index 0000000000..fc069e6342
> --- /dev/null
> +++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/BayhubHost.h
> @@ -0,0 +1,95 @@
> +/** @file
> +This driver is used to manage SD/MMC PCI host controllers override
> function
> +for BayHub BH720 eMMC host controller.
> +
> +Copyright (c) 2018 - 2019, BayHub Tech inc. All rights reserved.
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef BAYHUB_HOST_H_
> +#define BAYHUB_HOST_H_
> +
> +#include <Uefi.h>
> +#include <Protocol/SdMmcOverride.h>
> +#include <Protocol/PciIo.h>
> +#include <Library/UefiLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Guid/DebugMask.h>
> +
> +// O2/BHT add BAR1 for PCIR mapping registers
> +// These registers is defined by O2/BHT, but we may follow name definition
> rule.
> +#define BHT_PCR_MAP_VAL 0x200 /* PCI CFG Space Register Mapping
> Value Register */
> +#define BHT_PCR_MAP_CTL 0x204 /* PCI CFG Space Register Mapping
> Control Register */
> +#define BHT_PCR_MAP_EN 0x208 /* PCI CFG Space Register Mapping
> Enable Register */
> +#define BHT_GPIOCTL 0x210 /* GPIO control register*/
> +
> +#define HOST_CLK_DRIVE_STRENGTH 2
> +#define HOST_DAT_DRIVE_STRENGTH 2
> +#define HS200_ALLPASS_PHASE 0
> +#define HS100_ALLPASS_PHASE 6
> +
> +#define UNSUPPORT 0
> +#define SD_HOST 1
> +#define EMMC_HOST 2
> +
> +#define PCI_DEV_ID_RJ 0x8320
> +#define PCI_DEV_ID_SDS0 0x8420
> +#define PCI_DEV_ID_SDS1 0x8421
> +#define PCI_DEV_ID_FJ2 0x8520
> +#define PCI_DEV_ID_SB0 0x8620
> +#define PCI_DEV_ID_SB1 0x8621
> +#define PCI_DEV_ID_SE2 0x8720
> +
> +/**
> + Override function for SDHCI capability bits
> +
> + @param[in] ControllerHandle The EFI_HANDLE of the controller.
> + @param[in] Slot The 0 based slot index.
> + @param[in,out] SdMmcHcSlotCapability The SDHCI capability structure.
> + @param[in,out] BaseClkFreq The base clock frequency value that
> + optionally can be updated.
> +
> + @retval EFI_SUCCESS The override function completed successfully.
> + @retval EFI_NOT_FOUND The specified controller or slot does not
> exist.
> + @retval EFI_INVALID_PARAMETER SdMmcHcSlotCapability is NULL
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BhtHostOverrideCapability (
> + IN EFI_HANDLE ControllerHandle,
> + IN UINT8 Slot,
> + IN OUT VOID *SdMmcHcSlotCapability,
> + IN OUT UINT32 *BaseClkFreq
> + );
> +
> +/**
> + Override function for SDHCI controller operations
> +
> + @param[in] ControllerHandle The EFI_HANDLE of the controller.
> + @param[in] Slot The 0 based slot index.
> + @param[in] PhaseType The type of operation and whether the
> + hook is invoked right before (pre) or
> + right after (post)
> + @param[in,out] PhaseData The pointer to a phase-specific data.
> +
> + @retval EFI_SUCCESS The override function completed successfully.
> + @retval EFI_NOT_FOUND The specified controller or slot does not
> exist.
> + @retval EFI_INVALID_PARAMETER PhaseType is invalid
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BhtHostOverrideNotifyPhase (
> + IN EFI_HANDLE ControllerHandle,
> + IN UINT8 Slot,
> + IN EDKII_SD_MMC_PHASE_TYPE PhaseType,
> + IN OUT VOID *PhaseData
> + );
> +
> +extern EDKII_SD_MMC_OVERRIDE BhtOverride;
> +
> +#endif
> diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.inf
> b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.inf
> index e502443ddd..adb8f20984 100644
> --- a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.inf
> +++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.inf
> @@ -41,6 +41,8 @@
> SdMmcPciHci.h
> SdMmcPciHci.c
> ComponentName.c
> + BayhubHost.c
> + BayhubHost.h
>
> [Packages]
> MdePkg/MdePkg.dec
>
> base-commit: 9d669016d968b0f3e17ce7df16ae51d85b0adfcf
> --
> 2.18.0.windows.1
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2023-02-28 2:55 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-02-24 12:39 [edk2-platform][PATCH 1/1] MdeModulePkg: SdMmcPciHcDxe: Support for Bayhub SD/eMMC host Chevron Li
2023-02-28 2:55 ` Wu, Hao A
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox