Skip to content

Commit

Permalink
soc/amd/genoa: Add opensil MPIO chip files
Browse files Browse the repository at this point in the history
Add the openSIL MPIO chip driver that allows specifying the MPIO lane
configuration in the mainboard's devicetree instead of having this
configuration in a separate port descriptor C file.

Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
Change-Id: I1d408a7eff22423612bc5eb9bfebaf0d86642829
Reviewed-on: https://review.coreboot.org/c/coreboot/+/76520
Reviewed-by: Matt DeVillier <matt.devillier@amd.corp-partner.google.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
  • Loading branch information
ArthurHeymans authored and felixheld committed Dec 12, 2023
1 parent 62389ab commit f1b1412
Show file tree
Hide file tree
Showing 4 changed files with 265 additions and 0 deletions.
2 changes: 2 additions & 0 deletions 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

Expand Down
5 changes: 5 additions & 0 deletions 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
193 changes: 193 additions & 0 deletions 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,
};
65 changes: 65 additions & 0 deletions 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;
};

0 comments on commit f1b1412

Please sign in to comment.