blob: 9e9e8860342a9e093f0d5cbc6764e2c3e8ec4397 [file] [log] [blame]
/* 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"
#include "../opensil.h"
struct chip_operations vendorcode_amd_opensil_genoa_poc_mpio_ops = {
.name = "AMD GENOA MPIO",
};
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++;
}
void configure_mpio(void)
{
MPIOCLASS_INPUT_BLK *mpio_data = SilFindStructure(SilId_MpioClass, 0);
mpio_global_config(mpio_data);
nbio_config();
/* Find all devices with this chip that are directly below the chip */
for (struct device *dev = &dev_root; dev; dev = dev->next)
if (dev->chip_ops == &vendorcode_amd_opensil_genoa_poc_mpio_ops &&
dev->chip_info != dev->bus->dev->chip_info)
per_device_config(mpio_data, dev->bus->dev, dev->chip_info);
}