summaryrefslogtreecommitdiff
path: root/src/vendorcode
diff options
context:
space:
mode:
Diffstat (limited to 'src/vendorcode')
-rw-r--r--src/vendorcode/amd/opensil/genoa_poc/Makefile.inc2
-rw-r--r--src/vendorcode/amd/opensil/genoa_poc/mpio/Makefile.inc5
-rw-r--r--src/vendorcode/amd/opensil/genoa_poc/mpio/chip.c193
-rw-r--r--src/vendorcode/amd/opensil/genoa_poc/mpio/chip.h65
4 files changed, 265 insertions, 0 deletions
diff --git a/src/vendorcode/amd/opensil/genoa_poc/Makefile.inc b/src/vendorcode/amd/opensil/genoa_poc/Makefile.inc
index 6bfd95e264..cccb006686 100644
--- a/src/vendorcode/amd/opensil/genoa_poc/Makefile.inc
+++ b/src/vendorcode/amd/opensil/genoa_poc/Makefile.inc
@@ -1,5 +1,7 @@
## SPDX-License-Identifier: GPL-2.0-only
+subdirs-y += mpio
+
CPPFLAGS_ramstage += -I$(opensil_dir)/Include -I$(opensil_dir)/xUSL -I$(opensil_dir)/xUSL/Include -I$(opensil_dir)/xUSL/FCH -I$(opensil_dir)/xUSL/FCH/Common -I$(opensil_dir)/xSIM -I$(opensil_dir)/xPRF
CPPFLAGS_romstage += -I$(opensil_dir)/Include -I$(opensil_dir)/xUSL -I$(opensil_dir)/xUSL/Include -I$(opensil_dir)/xSIM -I$(opensil_dir)/xPRF
diff --git a/src/vendorcode/amd/opensil/genoa_poc/mpio/Makefile.inc b/src/vendorcode/amd/opensil/genoa_poc/mpio/Makefile.inc
new file mode 100644
index 0000000000..f3ae3ef614
--- /dev/null
+++ b/src/vendorcode/amd/opensil/genoa_poc/mpio/Makefile.inc
@@ -0,0 +1,5 @@
+## SPDX-License-Identifier: GPL-2.0-only
+
+ramstage-y += chip.c
+
+$(obj)/ramstage/vendorcode/amd/opensil/genoa_poc/mpio/chip.o: CFLAGS_ramstage += -D_MSC_EXTENSIONS=0 -DHAS_STRING_H=1 -Wno-unknown-pragmas
diff --git a/src/vendorcode/amd/opensil/genoa_poc/mpio/chip.c b/src/vendorcode/amd/opensil/genoa_poc/mpio/chip.c
new file mode 100644
index 0000000000..c2682933f8
--- /dev/null
+++ b/src/vendorcode/amd/opensil/genoa_poc/mpio/chip.c
@@ -0,0 +1,193 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <RcMgr/DfX/RcManager4-api.h>
+#include <NBIO/NbioClass-api.h>
+#include <Mpio/MpioClass-api.h>
+#include <Mpio/Common/MpioStructs.h>
+#include <device/device.h>
+#include <device/pci_def.h>
+#include "chip.h"
+
+static void nbio_config(void)
+{
+ NBIOCLASS_DATA_BLOCK *nbio_data = SilFindStructure(SilId_NbioClass, 0);
+ NBIOCLASS_INPUT_BLK *input = &nbio_data->NbioInputBlk;
+ input->CfgHdAudioEnable = false;
+ input->EsmEnableAllRootPorts = false;
+ input->EsmTargetSpeed = 16;
+ input->CfgRxMarginPersistenceMode = 1;
+ input->CfgDxioFrequencyVetting = false;
+ input->CfgSkipPspMessage = 1;
+ input->CfgEarlyTrainTwoPcieLinks = false;
+ input->EarlyBmcLinkTraining = true;
+ input->EdpcEnable = 0;
+ input->PcieAerReportMechanism = 2;
+ input->SevSnpSupport = false;
+}
+
+static void mpio_global_config(MPIOCLASS_INPUT_BLK *mpio_data)
+{
+ mpio_data->CfgDxioClockGating = 1;
+ mpio_data->PcieDxioTimingControlEnable = 0;
+ mpio_data->PCIELinkReceiverDetectionPolling = 0;
+ mpio_data->PCIELinkResetToTrainingTime = 0;
+ mpio_data->PCIELinkL0Polling = 0;
+ mpio_data->PCIeExactMatchEnable = 0;
+ mpio_data->DxioPhyValid = 1;
+ mpio_data->DxioPhyProgramming = 1;
+ mpio_data->CfgSkipPspMessage = 1;
+ mpio_data->DxioSaveRestoreModes = 0xff;
+ mpio_data->AmdAllowCompliance = 0;
+ mpio_data->AmdAllowCompliance = 0xff;
+ mpio_data->SrisEnableMode = 0xff;
+ mpio_data->SrisSkipInterval = 0;
+ mpio_data->SrisSkpIntervalSel = 1;
+ mpio_data->SrisCfgType = 0;
+ mpio_data->SrisAutoDetectMode = 0xff;
+ mpio_data->SrisAutodetectFactor = 0;
+ mpio_data->SrisLowerSkpOsGenSup = 0;
+ mpio_data->SrisLowerSkpOsRcvSup = 0;
+ mpio_data->AmdCxlOnAllPorts = 1;
+ mpio_data->CxlCorrectableErrorLogging = 1;
+ mpio_data->CxlUnCorrectableErrorLogging = 1;
+ // This is also available in Nbio. How to handle duplicate entries?
+ mpio_data->CfgAEREnable = 1;
+ mpio_data->CfgMcCapEnable = 0;
+ mpio_data->CfgRcvErrEnable = 0;
+ mpio_data->EarlyBmcLinkTraining = 1;
+ mpio_data->SurpriseDownFeature = 1;
+ mpio_data->LcMultAutoSpdChgOnLastRateEnable = 0;
+ mpio_data->AmdRxMarginEnabled = 1;
+ mpio_data->CfgPcieCVTestWA = 1;
+ mpio_data->CfgPcieAriSupport = 1;
+ mpio_data->CfgNbioCTOtoSC = 0;
+ mpio_data->CfgNbioCTOIgnoreError = 1;
+ mpio_data->CfgNbioSsid = 0;
+ mpio_data->CfgIommuSsid = 0;
+ mpio_data->CfgPspccpSsid = 0;
+ mpio_data->CfgNtbccpSsid = 0;
+ mpio_data->CfgNbifF0Ssid = 0;
+ mpio_data->CfgNtbSsid = 0;
+ mpio_data->AmdPcieSubsystemDeviceID = 0x1453;
+ mpio_data->AmdPcieSubsystemVendorID = 0x1022;
+ mpio_data->GppAtomicOps = 1;
+ mpio_data->GfxAtomicOps = 1;
+ mpio_data->AmdNbioReportEdbErrors = 0;
+ mpio_data->OpnSpare = 0;
+ mpio_data->AmdPreSilCtrl0 = 0;
+ mpio_data->MPIOAncDataSupport = 1;
+ mpio_data->AfterResetDelay = 0;
+ mpio_data->CfgEarlyLink = 0;
+ mpio_data->AmdCfgExposeUnusedPciePorts = 1; // Show all ports
+ mpio_data->CfgForcePcieGenSpeed = 0;
+ mpio_data->CfgSataPhyTuning = 0;
+ mpio_data->PcieLinkComplianceModeAllPorts = 0;
+ mpio_data->AmdMCTPEnable = 0;
+ mpio_data->SbrBrokenLaneAvoidanceSup = 1;
+ mpio_data->AutoFullMarginSup = 1;
+ // A getter and setter, both are needed for this PCD.
+ mpio_data->AmdPciePresetMask8GtAllPort = 0xffffffff;
+ // A getter and setter, both are needed for this PCD.
+ mpio_data->AmdPciePresetMask16GtAllPort = 0xffffffff;
+ // A getter and setter, both are needed for this PCD.
+ mpio_data->AmdPciePresetMask32GtAllPort = 0xffffffff;
+ mpio_data->PcieLinkAspmAllPort = 0xff;
+
+ mpio_data->SyncHeaderByPass = 1;
+ mpio_data->CxlTempGen5AdvertAltPtcl = 0;
+
+ /* TODO handle this differently on multisocket */
+ mpio_data->PcieTopologyData.PlatformData[0].Flags = DESCRIPTOR_TERMINATE_LIST;
+ mpio_data->PcieTopologyData.PlatformData[0].PciePortList = mpio_data->PcieTopologyData.PortList;
+
+}
+
+static void setup_bmc_lanes(uint8_t lane, uint8_t socket)
+{
+ DFX_RCMGR_INPUT_BLK *rc_mgr_input_block = SilFindStructure(SilId_RcManager, 0);
+ rc_mgr_input_block->BmcSocket = socket;
+ rc_mgr_input_block->EarlyBmcLinkLaneNum = lane;
+
+ NBIOCLASS_DATA_BLOCK *nbio_data = SilFindStructure(SilId_NbioClass, 0);
+ NBIOCLASS_INPUT_BLK *nbio_input = &nbio_data->NbioInputBlk;
+ nbio_input->EarlyBmcLinkSocket = socket;
+ nbio_input->EarlyBmcLinkLaneNum = lane;
+ nbio_input->EarlyBmcLinkDie = 0;
+
+ MPIOCLASS_INPUT_BLK *mpio_data = SilFindStructure(SilId_MpioClass, 0);
+ mpio_data->EarlyBmcLinkSocket = socket;
+ mpio_data->EarlyBmcLinkLaneNum = lane;
+ mpio_data->EarlyBmcLinkDie = 0;
+}
+
+static void per_device_config(MPIOCLASS_INPUT_BLK *mpio_data, struct device *dev,
+ struct vendorcode_amd_opensil_genoa_poc_mpio_config *const config)
+{
+ static uint32_t slot_num;
+ const uint32_t domain = dev->bus->dev->path.domain.domain;
+ const uint32_t devfn = dev->path.pci.devfn;
+ printk(BIOS_DEBUG, "Setting MPIO port for domain 0x%x, PCI %d:%d\n",
+ domain, PCI_SLOT(devfn), PCI_FUNC(devfn));
+
+ if (config->bmc) {
+ setup_bmc_lanes(config->start_lane, 0); // TODO support multiple sockets
+ return;
+ }
+
+ static int mpio_port = 0;
+ MPIO_PORT_DESCRIPTOR port = { .Flags = DESCRIPTOR_TERMINATE_LIST };
+ if (config->type == PCIE) {
+ const MPIO_ENGINE_DATA engine_data =
+ MPIO_ENGINE_DATA_INITIALIZER(MpioPcieEngine,
+ config->start_lane, config->end_lane,
+ config->hotplug == HotplugDisabled ? 0 : 1,
+ config->gpio_group);
+ port.EngineData = engine_data;
+ const MPIO_PORT_DATA port_data =
+ MPIO_PORT_DATA_INITIALIZER_PCIE(MpioPortEnabled,
+ PCI_SLOT(devfn),
+ PCI_FUNC(devfn),
+ config->hotplug,
+ config->speed,
+ 0, // No backup PCIe speed
+ config->aspm,
+ config->aspm_l1_1,
+ config->aspm_l1_2,
+ config->clock_pm);
+ port.Port = port_data;
+ } else if (config->type == SATA) {
+ const MPIO_ENGINE_DATA engine_data =
+ MPIO_ENGINE_DATA_INITIALIZER(MpioSATAEngine,
+ config->start_lane, config->end_lane,
+ 0, // meaningless field
+ config->gpio_group);
+ port.EngineData = engine_data;
+ const MPIO_PORT_DATA port_data = { .PortPresent = 1 };
+ port.Port = port_data;
+
+ }
+ port.Port.AlwaysExpose = 1;
+ port.Port.SlotNum = ++slot_num;
+ mpio_data->PcieTopologyData.PortList[mpio_port] = port;
+ /* Update TERMINATE list */
+ if (mpio_port > 0)
+ mpio_data->PcieTopologyData.PortList[mpio_port - 1].Flags = 0;
+ mpio_port++;
+}
+
+static void mpio_config(void *const config)
+{
+ MPIOCLASS_INPUT_BLK *mpio_data = SilFindStructure(SilId_MpioClass, 0);
+ mpio_global_config(mpio_data);
+ nbio_config();
+
+ /* Find all devices with this chip */
+ for (struct device *dev = &dev_root; dev; dev = dev->next)
+ if (dev->chip_ops->init == mpio_config)
+ per_device_config(mpio_data, dev->bus->dev, dev->chip_info);
+}
+
+struct chip_operations vendorcode_amd_opensil_genoa_poc_mpio_ops = {
+ CHIP_NAME("AMD GENOA MPIO")
+ .init = mpio_config,
+};
diff --git a/src/vendorcode/amd/opensil/genoa_poc/mpio/chip.h b/src/vendorcode/amd/opensil/genoa_poc/mpio/chip.h
new file mode 100644
index 0000000000..2ef3e8b233
--- /dev/null
+++ b/src/vendorcode/amd/opensil/genoa_poc/mpio/chip.h
@@ -0,0 +1,65 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <stdint.h>
+
+/*
+ * GENOA MPIO mapping
+ * P0 -> [0-15]
+ * G0 -> [16-31]
+ * P1 -> [32-47]
+ * G1 -> [48-63]
+ * P2 -> [64-79]
+ * G2 -> [80-95]
+ * P3 -> [96-111]
+ * G3 -> [112-127]
+ * P4 -> [128-131]
+ * P5 -> [132-136]
+ */
+
+enum mpio_type {
+ PCIE,
+ SATA,
+};
+
+/* Sync with PCIE_HOTPLUG_TYPE */
+enum mpio_hotplug {
+ HotplugDisabled, ///< Hotplug disable
+ Basic, ///< Basic Hotplug
+ ServerExpress, ///< Server Hotplug Express Module
+ Enhanced, ///< Enhanced
+ Inboard, ///< Inboard
+ ServerEntSSD, ///< Server Hotplug Enterprise SSD
+ UBM, ///< UBM Backplane
+ OCP, ///< OCP NIC 3.0
+};
+
+enum pcie_link_speed {
+ MaxSupported,
+ Gen1,
+ Gen2,
+ Gen3,
+ Gen4,
+ Gen5,
+};
+
+/* Sync with PCIE_ASPM_TYPE */
+enum pcie_asmp {
+ aspm_disabled,
+ L0s,
+ L1,
+ L0sL1,
+};
+
+struct vendorcode_amd_opensil_genoa_poc_mpio_config {
+ enum mpio_type type;
+ uint8_t start_lane;
+ uint8_t end_lane;
+ uint8_t gpio_group;
+ enum mpio_hotplug hotplug;
+ enum pcie_link_speed speed;
+ enum pcie_asmp aspm;
+ uint8_t aspm_l1_1 : 1;
+ uint8_t aspm_l1_2 : 1;
+ uint8_t clock_pm : 1;
+ uint8_t bmc : 1;
+};