Arthur Heymans | f1b1412 | 2023-07-14 20:44:55 +0200 | [diff] [blame] | 1 | /* 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" |
| 10 | |
| 11 | static void nbio_config(void) |
| 12 | { |
| 13 | NBIOCLASS_DATA_BLOCK *nbio_data = SilFindStructure(SilId_NbioClass, 0); |
| 14 | NBIOCLASS_INPUT_BLK *input = &nbio_data->NbioInputBlk; |
| 15 | input->CfgHdAudioEnable = false; |
| 16 | input->EsmEnableAllRootPorts = false; |
| 17 | input->EsmTargetSpeed = 16; |
| 18 | input->CfgRxMarginPersistenceMode = 1; |
| 19 | input->CfgDxioFrequencyVetting = false; |
| 20 | input->CfgSkipPspMessage = 1; |
| 21 | input->CfgEarlyTrainTwoPcieLinks = false; |
| 22 | input->EarlyBmcLinkTraining = true; |
| 23 | input->EdpcEnable = 0; |
| 24 | input->PcieAerReportMechanism = 2; |
| 25 | input->SevSnpSupport = false; |
| 26 | } |
| 27 | |
| 28 | static void mpio_global_config(MPIOCLASS_INPUT_BLK *mpio_data) |
| 29 | { |
| 30 | mpio_data->CfgDxioClockGating = 1; |
| 31 | mpio_data->PcieDxioTimingControlEnable = 0; |
| 32 | mpio_data->PCIELinkReceiverDetectionPolling = 0; |
| 33 | mpio_data->PCIELinkResetToTrainingTime = 0; |
| 34 | mpio_data->PCIELinkL0Polling = 0; |
| 35 | mpio_data->PCIeExactMatchEnable = 0; |
| 36 | mpio_data->DxioPhyValid = 1; |
| 37 | mpio_data->DxioPhyProgramming = 1; |
| 38 | mpio_data->CfgSkipPspMessage = 1; |
| 39 | mpio_data->DxioSaveRestoreModes = 0xff; |
| 40 | mpio_data->AmdAllowCompliance = 0; |
| 41 | mpio_data->AmdAllowCompliance = 0xff; |
| 42 | mpio_data->SrisEnableMode = 0xff; |
| 43 | mpio_data->SrisSkipInterval = 0; |
| 44 | mpio_data->SrisSkpIntervalSel = 1; |
| 45 | mpio_data->SrisCfgType = 0; |
| 46 | mpio_data->SrisAutoDetectMode = 0xff; |
| 47 | mpio_data->SrisAutodetectFactor = 0; |
| 48 | mpio_data->SrisLowerSkpOsGenSup = 0; |
| 49 | mpio_data->SrisLowerSkpOsRcvSup = 0; |
| 50 | mpio_data->AmdCxlOnAllPorts = 1; |
| 51 | mpio_data->CxlCorrectableErrorLogging = 1; |
| 52 | mpio_data->CxlUnCorrectableErrorLogging = 1; |
| 53 | // This is also available in Nbio. How to handle duplicate entries? |
| 54 | mpio_data->CfgAEREnable = 1; |
| 55 | mpio_data->CfgMcCapEnable = 0; |
| 56 | mpio_data->CfgRcvErrEnable = 0; |
| 57 | mpio_data->EarlyBmcLinkTraining = 1; |
| 58 | mpio_data->SurpriseDownFeature = 1; |
| 59 | mpio_data->LcMultAutoSpdChgOnLastRateEnable = 0; |
| 60 | mpio_data->AmdRxMarginEnabled = 1; |
| 61 | mpio_data->CfgPcieCVTestWA = 1; |
| 62 | mpio_data->CfgPcieAriSupport = 1; |
| 63 | mpio_data->CfgNbioCTOtoSC = 0; |
| 64 | mpio_data->CfgNbioCTOIgnoreError = 1; |
| 65 | mpio_data->CfgNbioSsid = 0; |
| 66 | mpio_data->CfgIommuSsid = 0; |
| 67 | mpio_data->CfgPspccpSsid = 0; |
| 68 | mpio_data->CfgNtbccpSsid = 0; |
| 69 | mpio_data->CfgNbifF0Ssid = 0; |
| 70 | mpio_data->CfgNtbSsid = 0; |
| 71 | mpio_data->AmdPcieSubsystemDeviceID = 0x1453; |
| 72 | mpio_data->AmdPcieSubsystemVendorID = 0x1022; |
| 73 | mpio_data->GppAtomicOps = 1; |
| 74 | mpio_data->GfxAtomicOps = 1; |
| 75 | mpio_data->AmdNbioReportEdbErrors = 0; |
| 76 | mpio_data->OpnSpare = 0; |
| 77 | mpio_data->AmdPreSilCtrl0 = 0; |
| 78 | mpio_data->MPIOAncDataSupport = 1; |
| 79 | mpio_data->AfterResetDelay = 0; |
| 80 | mpio_data->CfgEarlyLink = 0; |
| 81 | mpio_data->AmdCfgExposeUnusedPciePorts = 1; // Show all ports |
| 82 | mpio_data->CfgForcePcieGenSpeed = 0; |
| 83 | mpio_data->CfgSataPhyTuning = 0; |
| 84 | mpio_data->PcieLinkComplianceModeAllPorts = 0; |
| 85 | mpio_data->AmdMCTPEnable = 0; |
| 86 | mpio_data->SbrBrokenLaneAvoidanceSup = 1; |
| 87 | mpio_data->AutoFullMarginSup = 1; |
| 88 | // A getter and setter, both are needed for this PCD. |
| 89 | mpio_data->AmdPciePresetMask8GtAllPort = 0xffffffff; |
| 90 | // A getter and setter, both are needed for this PCD. |
| 91 | mpio_data->AmdPciePresetMask16GtAllPort = 0xffffffff; |
| 92 | // A getter and setter, both are needed for this PCD. |
| 93 | mpio_data->AmdPciePresetMask32GtAllPort = 0xffffffff; |
| 94 | mpio_data->PcieLinkAspmAllPort = 0xff; |
| 95 | |
| 96 | mpio_data->SyncHeaderByPass = 1; |
| 97 | mpio_data->CxlTempGen5AdvertAltPtcl = 0; |
| 98 | |
| 99 | /* TODO handle this differently on multisocket */ |
| 100 | mpio_data->PcieTopologyData.PlatformData[0].Flags = DESCRIPTOR_TERMINATE_LIST; |
| 101 | mpio_data->PcieTopologyData.PlatformData[0].PciePortList = mpio_data->PcieTopologyData.PortList; |
| 102 | |
| 103 | } |
| 104 | |
| 105 | static void setup_bmc_lanes(uint8_t lane, uint8_t socket) |
| 106 | { |
| 107 | DFX_RCMGR_INPUT_BLK *rc_mgr_input_block = SilFindStructure(SilId_RcManager, 0); |
| 108 | rc_mgr_input_block->BmcSocket = socket; |
| 109 | rc_mgr_input_block->EarlyBmcLinkLaneNum = lane; |
| 110 | |
| 111 | NBIOCLASS_DATA_BLOCK *nbio_data = SilFindStructure(SilId_NbioClass, 0); |
| 112 | NBIOCLASS_INPUT_BLK *nbio_input = &nbio_data->NbioInputBlk; |
| 113 | nbio_input->EarlyBmcLinkSocket = socket; |
| 114 | nbio_input->EarlyBmcLinkLaneNum = lane; |
| 115 | nbio_input->EarlyBmcLinkDie = 0; |
| 116 | |
| 117 | MPIOCLASS_INPUT_BLK *mpio_data = SilFindStructure(SilId_MpioClass, 0); |
| 118 | mpio_data->EarlyBmcLinkSocket = socket; |
| 119 | mpio_data->EarlyBmcLinkLaneNum = lane; |
| 120 | mpio_data->EarlyBmcLinkDie = 0; |
| 121 | } |
| 122 | |
| 123 | static void per_device_config(MPIOCLASS_INPUT_BLK *mpio_data, struct device *dev, |
| 124 | struct vendorcode_amd_opensil_genoa_poc_mpio_config *const config) |
| 125 | { |
| 126 | static uint32_t slot_num; |
| 127 | const uint32_t domain = dev->bus->dev->path.domain.domain; |
| 128 | const uint32_t devfn = dev->path.pci.devfn; |
| 129 | printk(BIOS_DEBUG, "Setting MPIO port for domain 0x%x, PCI %d:%d\n", |
| 130 | domain, PCI_SLOT(devfn), PCI_FUNC(devfn)); |
| 131 | |
| 132 | if (config->bmc) { |
| 133 | setup_bmc_lanes(config->start_lane, 0); // TODO support multiple sockets |
| 134 | return; |
| 135 | } |
| 136 | |
| 137 | static int mpio_port = 0; |
| 138 | MPIO_PORT_DESCRIPTOR port = { .Flags = DESCRIPTOR_TERMINATE_LIST }; |
| 139 | if (config->type == PCIE) { |
| 140 | const MPIO_ENGINE_DATA engine_data = |
| 141 | MPIO_ENGINE_DATA_INITIALIZER(MpioPcieEngine, |
| 142 | config->start_lane, config->end_lane, |
| 143 | config->hotplug == HotplugDisabled ? 0 : 1, |
| 144 | config->gpio_group); |
| 145 | port.EngineData = engine_data; |
| 146 | const MPIO_PORT_DATA port_data = |
| 147 | MPIO_PORT_DATA_INITIALIZER_PCIE(MpioPortEnabled, |
| 148 | PCI_SLOT(devfn), |
| 149 | PCI_FUNC(devfn), |
| 150 | config->hotplug, |
| 151 | config->speed, |
| 152 | 0, // No backup PCIe speed |
| 153 | config->aspm, |
| 154 | config->aspm_l1_1, |
| 155 | config->aspm_l1_2, |
| 156 | config->clock_pm); |
| 157 | port.Port = port_data; |
| 158 | } else if (config->type == SATA) { |
| 159 | const MPIO_ENGINE_DATA engine_data = |
| 160 | MPIO_ENGINE_DATA_INITIALIZER(MpioSATAEngine, |
| 161 | config->start_lane, config->end_lane, |
| 162 | 0, // meaningless field |
| 163 | config->gpio_group); |
| 164 | port.EngineData = engine_data; |
| 165 | const MPIO_PORT_DATA port_data = { .PortPresent = 1 }; |
| 166 | port.Port = port_data; |
| 167 | |
| 168 | } |
| 169 | port.Port.AlwaysExpose = 1; |
| 170 | port.Port.SlotNum = ++slot_num; |
| 171 | mpio_data->PcieTopologyData.PortList[mpio_port] = port; |
| 172 | /* Update TERMINATE list */ |
| 173 | if (mpio_port > 0) |
| 174 | mpio_data->PcieTopologyData.PortList[mpio_port - 1].Flags = 0; |
| 175 | mpio_port++; |
| 176 | } |
| 177 | |
Felix Held | 204703d | 2024-01-22 16:06:33 +0100 | [diff] [blame] | 178 | static void configure_mpio(void *const config) |
Arthur Heymans | f1b1412 | 2023-07-14 20:44:55 +0200 | [diff] [blame] | 179 | { |
| 180 | MPIOCLASS_INPUT_BLK *mpio_data = SilFindStructure(SilId_MpioClass, 0); |
| 181 | mpio_global_config(mpio_data); |
| 182 | nbio_config(); |
| 183 | |
| 184 | /* Find all devices with this chip */ |
| 185 | for (struct device *dev = &dev_root; dev; dev = dev->next) |
Felix Held | 204703d | 2024-01-22 16:06:33 +0100 | [diff] [blame] | 186 | if (dev->chip_ops->init == configure_mpio) |
Arthur Heymans | f1b1412 | 2023-07-14 20:44:55 +0200 | [diff] [blame] | 187 | per_device_config(mpio_data, dev->bus->dev, dev->chip_info); |
| 188 | } |
| 189 | |
| 190 | struct chip_operations vendorcode_amd_opensil_genoa_poc_mpio_ops = { |
| 191 | CHIP_NAME("AMD GENOA MPIO") |
Felix Held | 204703d | 2024-01-22 16:06:33 +0100 | [diff] [blame] | 192 | .init = configure_mpio, |
Arthur Heymans | f1b1412 | 2023-07-14 20:44:55 +0200 | [diff] [blame] | 193 | }; |