blob: 6d811ce47dfd84a8935c88d433f3b960f04ddb2d [file] [log] [blame]
Arthur Heymansf1b14122023-07-14 20:44:55 +02001/* SPDX-License-Identifier: GPL-2.0-only */
2
3#include <RcMgr/DfX/RcManager4-api.h>
4#include <NBIO/NbioClass-api.h>
5#include <Mpio/MpioClass-api.h>
6#include <Mpio/Common/MpioStructs.h>
7#include <device/device.h>
8#include <device/pci_def.h>
9#include "chip.h"
Felix Helde5197e12024-01-22 18:17:57 +010010#include "../opensil.h"
11
12struct chip_operations vendorcode_amd_opensil_genoa_poc_mpio_ops = {
Nicholas Sudsgaardbfb11be2024-01-30 09:53:46 +090013 .name = "AMD GENOA MPIO",
Felix Helde5197e12024-01-22 18:17:57 +010014};
Arthur Heymansf1b14122023-07-14 20:44:55 +020015
16static void nbio_config(void)
17{
18 NBIOCLASS_DATA_BLOCK *nbio_data = SilFindStructure(SilId_NbioClass, 0);
19 NBIOCLASS_INPUT_BLK *input = &nbio_data->NbioInputBlk;
20 input->CfgHdAudioEnable = false;
21 input->EsmEnableAllRootPorts = false;
22 input->EsmTargetSpeed = 16;
23 input->CfgRxMarginPersistenceMode = 1;
24 input->CfgDxioFrequencyVetting = false;
25 input->CfgSkipPspMessage = 1;
26 input->CfgEarlyTrainTwoPcieLinks = false;
27 input->EarlyBmcLinkTraining = true;
28 input->EdpcEnable = 0;
29 input->PcieAerReportMechanism = 2;
30 input->SevSnpSupport = false;
31}
32
33static void mpio_global_config(MPIOCLASS_INPUT_BLK *mpio_data)
34{
35 mpio_data->CfgDxioClockGating = 1;
36 mpio_data->PcieDxioTimingControlEnable = 0;
37 mpio_data->PCIELinkReceiverDetectionPolling = 0;
38 mpio_data->PCIELinkResetToTrainingTime = 0;
39 mpio_data->PCIELinkL0Polling = 0;
40 mpio_data->PCIeExactMatchEnable = 0;
41 mpio_data->DxioPhyValid = 1;
42 mpio_data->DxioPhyProgramming = 1;
43 mpio_data->CfgSkipPspMessage = 1;
44 mpio_data->DxioSaveRestoreModes = 0xff;
45 mpio_data->AmdAllowCompliance = 0;
46 mpio_data->AmdAllowCompliance = 0xff;
47 mpio_data->SrisEnableMode = 0xff;
48 mpio_data->SrisSkipInterval = 0;
49 mpio_data->SrisSkpIntervalSel = 1;
50 mpio_data->SrisCfgType = 0;
51 mpio_data->SrisAutoDetectMode = 0xff;
52 mpio_data->SrisAutodetectFactor = 0;
53 mpio_data->SrisLowerSkpOsGenSup = 0;
54 mpio_data->SrisLowerSkpOsRcvSup = 0;
55 mpio_data->AmdCxlOnAllPorts = 1;
56 mpio_data->CxlCorrectableErrorLogging = 1;
57 mpio_data->CxlUnCorrectableErrorLogging = 1;
58 // This is also available in Nbio. How to handle duplicate entries?
59 mpio_data->CfgAEREnable = 1;
60 mpio_data->CfgMcCapEnable = 0;
61 mpio_data->CfgRcvErrEnable = 0;
62 mpio_data->EarlyBmcLinkTraining = 1;
63 mpio_data->SurpriseDownFeature = 1;
64 mpio_data->LcMultAutoSpdChgOnLastRateEnable = 0;
65 mpio_data->AmdRxMarginEnabled = 1;
66 mpio_data->CfgPcieCVTestWA = 1;
67 mpio_data->CfgPcieAriSupport = 1;
68 mpio_data->CfgNbioCTOtoSC = 0;
69 mpio_data->CfgNbioCTOIgnoreError = 1;
70 mpio_data->CfgNbioSsid = 0;
71 mpio_data->CfgIommuSsid = 0;
72 mpio_data->CfgPspccpSsid = 0;
73 mpio_data->CfgNtbccpSsid = 0;
74 mpio_data->CfgNbifF0Ssid = 0;
75 mpio_data->CfgNtbSsid = 0;
76 mpio_data->AmdPcieSubsystemDeviceID = 0x1453;
77 mpio_data->AmdPcieSubsystemVendorID = 0x1022;
78 mpio_data->GppAtomicOps = 1;
79 mpio_data->GfxAtomicOps = 1;
80 mpio_data->AmdNbioReportEdbErrors = 0;
81 mpio_data->OpnSpare = 0;
82 mpio_data->AmdPreSilCtrl0 = 0;
83 mpio_data->MPIOAncDataSupport = 1;
84 mpio_data->AfterResetDelay = 0;
85 mpio_data->CfgEarlyLink = 0;
86 mpio_data->AmdCfgExposeUnusedPciePorts = 1; // Show all ports
87 mpio_data->CfgForcePcieGenSpeed = 0;
88 mpio_data->CfgSataPhyTuning = 0;
89 mpio_data->PcieLinkComplianceModeAllPorts = 0;
90 mpio_data->AmdMCTPEnable = 0;
91 mpio_data->SbrBrokenLaneAvoidanceSup = 1;
92 mpio_data->AutoFullMarginSup = 1;
93 // A getter and setter, both are needed for this PCD.
94 mpio_data->AmdPciePresetMask8GtAllPort = 0xffffffff;
95 // A getter and setter, both are needed for this PCD.
96 mpio_data->AmdPciePresetMask16GtAllPort = 0xffffffff;
97 // A getter and setter, both are needed for this PCD.
98 mpio_data->AmdPciePresetMask32GtAllPort = 0xffffffff;
99 mpio_data->PcieLinkAspmAllPort = 0xff;
100
101 mpio_data->SyncHeaderByPass = 1;
102 mpio_data->CxlTempGen5AdvertAltPtcl = 0;
103
104 /* TODO handle this differently on multisocket */
105 mpio_data->PcieTopologyData.PlatformData[0].Flags = DESCRIPTOR_TERMINATE_LIST;
106 mpio_data->PcieTopologyData.PlatformData[0].PciePortList = mpio_data->PcieTopologyData.PortList;
107
108}
109
110static void setup_bmc_lanes(uint8_t lane, uint8_t socket)
111{
112 DFX_RCMGR_INPUT_BLK *rc_mgr_input_block = SilFindStructure(SilId_RcManager, 0);
113 rc_mgr_input_block->BmcSocket = socket;
114 rc_mgr_input_block->EarlyBmcLinkLaneNum = lane;
115
116 NBIOCLASS_DATA_BLOCK *nbio_data = SilFindStructure(SilId_NbioClass, 0);
117 NBIOCLASS_INPUT_BLK *nbio_input = &nbio_data->NbioInputBlk;
118 nbio_input->EarlyBmcLinkSocket = socket;
119 nbio_input->EarlyBmcLinkLaneNum = lane;
120 nbio_input->EarlyBmcLinkDie = 0;
121
122 MPIOCLASS_INPUT_BLK *mpio_data = SilFindStructure(SilId_MpioClass, 0);
123 mpio_data->EarlyBmcLinkSocket = socket;
124 mpio_data->EarlyBmcLinkLaneNum = lane;
125 mpio_data->EarlyBmcLinkDie = 0;
126}
127
128static void per_device_config(MPIOCLASS_INPUT_BLK *mpio_data, struct device *dev,
129 struct vendorcode_amd_opensil_genoa_poc_mpio_config *const config)
130{
131 static uint32_t slot_num;
Arthur Heymans7fcd4d52023-08-24 15:12:19 +0200132 const uint32_t domain = dev->upstream->dev->path.domain.domain;
Arthur Heymansf1b14122023-07-14 20:44:55 +0200133 const uint32_t devfn = dev->path.pci.devfn;
134 printk(BIOS_DEBUG, "Setting MPIO port for domain 0x%x, PCI %d:%d\n",
135 domain, PCI_SLOT(devfn), PCI_FUNC(devfn));
136
Felix Held929ef5f2024-03-15 19:19:46 +0100137 if (config->type == IFTYPE_UNUSED) {
138 if (is_dev_enabled(dev)) {
139 printk(BIOS_WARNING, "Unused MPIO engine, disabling PCI device.\n");
140 dev->enabled = false;
141 }
142 return;
143 }
144
Arthur Heymansf1b14122023-07-14 20:44:55 +0200145 if (config->bmc) {
146 setup_bmc_lanes(config->start_lane, 0); // TODO support multiple sockets
147 return;
148 }
149
150 static int mpio_port = 0;
151 MPIO_PORT_DESCRIPTOR port = { .Flags = DESCRIPTOR_TERMINATE_LIST };
Felix Heldc12ef5d2024-03-11 22:31:43 +0100152 if (config->type == IFTYPE_PCIE) {
Arthur Heymansf1b14122023-07-14 20:44:55 +0200153 const MPIO_ENGINE_DATA engine_data =
154 MPIO_ENGINE_DATA_INITIALIZER(MpioPcieEngine,
155 config->start_lane, config->end_lane,
156 config->hotplug == HotplugDisabled ? 0 : 1,
157 config->gpio_group);
158 port.EngineData = engine_data;
159 const MPIO_PORT_DATA port_data =
160 MPIO_PORT_DATA_INITIALIZER_PCIE(MpioPortEnabled,
161 PCI_SLOT(devfn),
162 PCI_FUNC(devfn),
163 config->hotplug,
164 config->speed,
165 0, // No backup PCIe speed
166 config->aspm,
167 config->aspm_l1_1,
168 config->aspm_l1_2,
169 config->clock_pm);
170 port.Port = port_data;
Felix Heldc12ef5d2024-03-11 22:31:43 +0100171 } else if (config->type == IFTYPE_SATA) {
Arthur Heymansf1b14122023-07-14 20:44:55 +0200172 const MPIO_ENGINE_DATA engine_data =
173 MPIO_ENGINE_DATA_INITIALIZER(MpioSATAEngine,
174 config->start_lane, config->end_lane,
175 0, // meaningless field
176 config->gpio_group);
177 port.EngineData = engine_data;
178 const MPIO_PORT_DATA port_data = { .PortPresent = 1 };
179 port.Port = port_data;
180
181 }
182 port.Port.AlwaysExpose = 1;
183 port.Port.SlotNum = ++slot_num;
184 mpio_data->PcieTopologyData.PortList[mpio_port] = port;
185 /* Update TERMINATE list */
186 if (mpio_port > 0)
187 mpio_data->PcieTopologyData.PortList[mpio_port - 1].Flags = 0;
188 mpio_port++;
189}
190
Felix Helde5197e12024-01-22 18:17:57 +0100191void configure_mpio(void)
Arthur Heymansf1b14122023-07-14 20:44:55 +0200192{
193 MPIOCLASS_INPUT_BLK *mpio_data = SilFindStructure(SilId_MpioClass, 0);
194 mpio_global_config(mpio_data);
195 nbio_config();
196
Felix Heldc4e5e912024-01-22 18:42:35 +0100197 /* Find all devices with this chip that are directly below the chip */
Arthur Heymansf1b14122023-07-14 20:44:55 +0200198 for (struct device *dev = &dev_root; dev; dev = dev->next)
Felix Heldc4e5e912024-01-22 18:42:35 +0100199 if (dev->chip_ops == &vendorcode_amd_opensil_genoa_poc_mpio_ops &&
Arthur Heymans7fcd4d52023-08-24 15:12:19 +0200200 dev->chip_info != dev->upstream->dev->chip_info)
Felix Held4b187552024-03-18 21:08:25 +0100201 per_device_config(mpio_data, dev, dev->chip_info);
Arthur Heymansf1b14122023-07-14 20:44:55 +0200202}