diff options
Diffstat (limited to 'src/vendorcode')
-rw-r--r-- | src/vendorcode/amd/opensil/genoa_poc/Makefile.inc | 2 | ||||
-rw-r--r-- | src/vendorcode/amd/opensil/genoa_poc/mpio/Makefile.inc | 5 | ||||
-rw-r--r-- | src/vendorcode/amd/opensil/genoa_poc/mpio/chip.c | 193 | ||||
-rw-r--r-- | src/vendorcode/amd/opensil/genoa_poc/mpio/chip.h | 65 |
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; +}; |