AGESA_STATUS STATIC PcieMapPortsPciAddresses ( IN PCIe_SILICON_CONFIG *Silicon, IN PCIe_PLATFORM_CONFIG *Pcie ) { AGESA_STATUS Status; AGESA_STATUS AgesaStatus; PCIe_WRAPPER_CONFIG *WrapperList; PCIe_ENGINE_CONFIG *EngineList; AgesaStatus = AGESA_SUCCESS; WrapperList = PcieConfigGetChildWrapper (Silicon); while (WrapperList != NULL) { EngineList = PcieConfigGetChildEngine (WrapperList); while (EngineList != NULL) { if (PcieLibIsPcieEngine (EngineList) && PcieLibIsEngineAllocated (EngineList)) { Status = PcieFmMapPortPciAddress (EngineList); AGESA_STATUS_UPDATE (Status, AgesaStatus); if (Status == AGESA_SUCCESS) { EngineList->Type.Port.Address.AddressValue = MAKE_SBDFO ( 0, Silicon->Address.Address.Bus, EngineList->Type.Port.PortData.DeviceNumber, EngineList->Type.Port.PortData.FunctionNumber, 0 ); } else { EngineList->Type.Port.PortData.PortPresent = OFF; IDS_HDT_CONSOLE (PCIE_MISC, " ERROR! Fail to allocate PCI address for PCIe port\n" ); //Report error PutEventLog ( AGESA_ERROR, GNB_EVENT_INVALID_PCIE_PORT_CONFIGURATION, EngineList->Type.Port.PortData.DeviceNumber, 0, 0, 0, GnbLibGetHeader (Pcie) ); } } EngineList = PcieLibGetNextDescriptor (EngineList); } WrapperList = PcieLibGetNextDescriptor (WrapperList); } return AgesaStatus; }
/** * Initialize engine data * * * * @param[in] ComplexDescriptor Pointer to user defined complex descriptor * @param[in,out] Wrapper Pointer to wrapper config descriptor * @param[in] Pcie Pointer to global PCIe configuration */ VOID PcieMapInitializeEngineData ( IN PCIe_COMPLEX_DESCRIPTOR *ComplexDescriptor, IN OUT PCIe_WRAPPER_CONFIG *Wrapper, IN PCIe_PLATFORM_CONFIG *Pcie ) { PCIe_ENGINE_CONFIG *EngineList; PCIe_ENGINE_DESCRIPTOR *EngineDescriptor; EngineList = PcieConfigGetChildEngine (Wrapper); while (EngineList != NULL) { if (PcieLibIsEngineAllocated (EngineList)) { if (EngineList->Scratch != 0xFF) { EngineDescriptor = PcieInputParserGetEngineDescriptor (ComplexDescriptor, EngineList->Scratch); LibAmdMemCopy (&EngineList->EngineData, &EngineDescriptor->EngineData, sizeof (EngineDescriptor->EngineData), GnbLibGetHeader (Pcie)); if (PcieLibIsDdiEngine (EngineList)) { LibAmdMemCopy (&EngineList->Type.Ddi, &((PCIe_DDI_DESCRIPTOR*) EngineDescriptor)->Ddi, sizeof (PCIe_DDI_DATA), GnbLibGetHeader (Pcie)); EngineList->Type.Ddi.DisplayPriorityIndex = (UINT8) EngineList->Scratch; } else if (PcieLibIsPcieEngine (EngineList)) { LibAmdMemCopy (&EngineList->Type.Port, &((PCIe_PORT_DESCRIPTOR*) EngineDescriptor)->Port, sizeof (PCIe_PORT_DATA), GnbLibGetHeader (Pcie)); } } } EngineList = PcieLibGetNextDescriptor (EngineList); } }
BOOLEAN PcieTopologyIsGen3SupportedV5 ( IN PCIe_WRAPPER_CONFIG *Wrapper ) { UINT8 LaneNibbleArray [4]; UINT32 LaneBitmap; UINT8 Nibble; UINT8 NibbleBitmap; PCIe_ENGINE_CONFIG *Engine; LibAmdMemFill (&LaneNibbleArray[0], 0x00, sizeof (LaneNibbleArray), PcieConfigGetStdHeader (Wrapper)); Engine = PcieConfigGetChildEngine (Wrapper); while (Engine != NULL) { LaneBitmap = PcieUtilGetEngineLaneBitMap (LANE_TYPE_PCIE_PHY_NATIVE, 0, Engine); for (Nibble = 0; Nibble < 4; Nibble++) { NibbleBitmap = (0xF << (Nibble * 4)); if ((LaneBitmap & NibbleBitmap) != 0) { if (++LaneNibbleArray [Nibble] > 1) { return FALSE; } } } Engine = PcieLibGetNextDescriptor (Engine); } return TRUE; }
AGESA_STATUS STATIC PcieLnConfigureGppEnginesLaneAllocation ( IN PCIe_WRAPPER_CONFIG *Wrapper, IN UINT8 ConfigurationId ) { PCIe_ENGINE_CONFIG *EnginesList; UINTN CoreLaneIndex; UINTN PortIdIndex; if (ConfigurationId > ((sizeof (GppLaneConfigurationTable) / (NUMBER_OF_GPP_PORTS * 2)) - 1)) { return AGESA_ERROR; } EnginesList = PcieConfigGetChildEngine (Wrapper); CoreLaneIndex = 0; PortIdIndex = 0; while (EnginesList != NULL) { PcieConfigResetDescriptorFlags (EnginesList, DESCRIPTOR_ALLOCATED); EnginesList->Type.Port.PortId = GppPortIdConfigurationTable [ConfigurationId][PortIdIndex++]; EnginesList->Type.Port.StartCoreLane = GppLaneConfigurationTable [ConfigurationId][CoreLaneIndex++]; EnginesList->Type.Port.EndCoreLane = GppLaneConfigurationTable [ConfigurationId][CoreLaneIndex++]; EnginesList = PcieLibGetNextDescriptor (EnginesList); } return AGESA_SUCCESS; }
UINT32 PcieUtilGetWrapperLaneBitMap ( IN UINT32 IncludeLaneType, IN UINT32 ExcludeLaneType, IN PCIe_WRAPPER_CONFIG *Wrapper ) { PCIe_ENGINE_CONFIG *EngineList; UINT32 LaneBitmap; EngineList = PcieConfigGetChildEngine (Wrapper); LaneBitmap = 0; if ((IncludeLaneType | ExcludeLaneType) != 0) { if ((IncludeLaneType & LANE_TYPE_ALL) == LANE_TYPE_ALL) { LaneBitmap = (1 << (Wrapper->NumberOfLanes)) - 1; if (ExcludeLaneType != 0) { LaneBitmap &= (~PcieUtilGetWrapperLaneBitMap (ExcludeLaneType, 0, Wrapper)); } } else { while (EngineList != NULL) { LaneBitmap |= PcieUtilGetEngineLaneBitMap (IncludeLaneType, ExcludeLaneType, EngineList); EngineList = PcieLibGetNextDescriptor (EngineList); } if ((IncludeLaneType & LANE_TYPE_PCIE_PHY_NATIVE_MASTER_PLL) != 0) { LaneBitmap |= PcieUtilGetMasterPllLaneBitMap (Wrapper); } if ((ExcludeLaneType & LANE_TYPE_PCIE_PHY_NATIVE_MASTER_PLL) != 0) { LaneBitmap &= (~PcieUtilGetMasterPllLaneBitMap (Wrapper)); } } } return LaneBitmap; }
/** * Configure engine list to support lane allocation according to configuration ID. * * * * @param[in] Wrapper Pointer to wrapper config descriptor * @param[in] PcieLaneConfig Lane configuration descriptor * @param[in] ConfigurationId Configuration ID * @retval AGESA_SUCCESS Configuration successfully applied * @retval AGESA_ERROR Requested configuration not supported */ AGESA_STATUS PcieConfigurePcieEnginesLaneAllocationML ( IN PCIe_WRAPPER_CONFIG *Wrapper, IN PCIe_LANE_ALLOC_DESCRIPTOR *PcieLaneConfig, IN UINT8 ConfigurationId ) { UINT8 CoreLaneIndex; PCIe_ENGINE_CONFIG *EnginesList; if (ConfigurationId >= PcieLaneConfig->NumberOfConfigurations) { return AGESA_ERROR; } EnginesList = PcieConfigGetChildEngine (Wrapper); CoreLaneIndex = ConfigurationId * PcieLaneConfig->NumberOfEngines * 2; while (EnginesList != NULL) { if (PcieLibIsPcieEngine (EnginesList)) { PcieConfigResetDescriptorFlags (EnginesList, DESCRIPTOR_ALLOCATED); EnginesList->Type.Port.StartCoreLane = PcieLaneConfig->ConfigTable[CoreLaneIndex++]; EnginesList->Type.Port.EndCoreLane = PcieLaneConfig->ConfigTable[CoreLaneIndex++]; } EnginesList = PcieLibGetNextDescriptor (EnginesList); } return AGESA_SUCCESS; }
/** * Helper function to dump wrapper configuration * * * @param[in] WrapperList Wrapper Configuration */ VOID PcieConfigWrapperDebugDump ( IN PCIe_WRAPPER_CONFIG *WrapperList ) { PCIe_ENGINE_CONFIG *EngineList; IDS_HDT_CONSOLE (PCIE_MISC, " <---------Wrapper - %s Config -------->\n", PcieFmDebugGetWrapperNameString (WrapperList) ); IDS_HDT_CONSOLE (PCIE_MISC, " Start PHY lane - %02d\n", WrapperList->StartPhyLane); IDS_HDT_CONSOLE (PCIE_MISC, " End PHY lane - %02d\n", WrapperList->EndPhyLane); IDS_HDT_CONSOLE (PCIE_MISC, " Descriptor Flags - 0x%08x\n", WrapperList->Header.DescriptorFlags); IDS_HDT_CONSOLE (PCIE_MISC, " PowerOffUnusedLanes - %x\n PowerOffUnusedPlls - %x\n ClkGating - %x\n" " LclkGating - %x\n TxclkGatingPllPowerDown - %x\n PllOffInL1 - %x\n", WrapperList->Features.PowerOffUnusedLanes, WrapperList->Features.PowerOffUnusedPlls, WrapperList->Features.ClkGating, WrapperList->Features.LclkGating, WrapperList->Features.TxclkGatingPllPowerDown, WrapperList->Features.PllOffInL1 ); IDS_HDT_CONSOLE (PCIE_MISC, " <---------Wrapper - %s Config End----->\n", PcieFmDebugGetWrapperNameString (WrapperList) ); EngineList = PcieConfigGetChildEngine (WrapperList); while (EngineList != NULL) { if (PcieLibIsEngineAllocated (EngineList)) { PcieConfigEngineDebugDump (EngineList); } EngineList = PcieLibGetNextDescriptor (EngineList); } }
/** * Enable lane reversal * * * @param[in] Wrapper Pointer to wrapper config descriptor * @param[in] Pcie Pointer to global PCIe configuration */ VOID PcieTopologySetLinkReversal ( IN PCIe_WRAPPER_CONFIG *Wrapper, IN PCIe_PLATFORM_CONFIG *Pcie ) { PCIe_ENGINE_CONFIG *EngineList; IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologySetLinkReversal Enter\n"); EngineList = PcieConfigGetChildEngine (Wrapper); while (EngineList != NULL) { if (PcieLibIsEngineAllocated (EngineList)) { if (PcieLibIsPcieEngine (EngineList)) { if (EngineList->EngineData.StartLane > EngineList->EngineData.EndLane) { PciePortRegisterWriteField ( EngineList, DxF0xE4_xC1_ADDRESS, DxF0xE4_xC1_StrapReverseLanes_OFFSET, DxF0xE4_xC1_StrapReverseLanes_WIDTH, 0x1, FALSE, Pcie ); } } } EngineList = PcieLibGetNextDescriptor (EngineList); } IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologySetLinkReversal Exit\n"); }
VOID PcieSiliconHidePorts ( IN PCIe_SILICON_CONFIG *Silicon, IN PCIe_PLATFORM_CONFIG *Pcie ) { D0F0x64_x0C_STRUCT D0F0x64_x0C; PCIe_WRAPPER_CONFIG *WrapperList; D0F0x64_x0C.Value = 0; IDS_HDT_CONSOLE (GNB_TRACE, "PcieSiliconHidePorts Enter\n"); D0F0x64_x0C.Value = BIT2 | BIT3 | BIT4 | BIT5 | BIT6 | BIT7; WrapperList = PcieConfigGetChildWrapper (Silicon); while (WrapperList != NULL) { PCIe_ENGINE_CONFIG *EngineList; EngineList = PcieConfigGetChildEngine (WrapperList); while (EngineList != NULL) { if (PcieConfigIsPcieEngine (EngineList)) { if (PcieConfigIsActivePcieEngine (EngineList) && !PcieConfigIsSbPcieEngine (EngineList)) { D0F0x64_x0C.Value &= ~(1 << EngineList->Type.Port.Address.Address.Device); } } EngineList = PcieLibGetNextDescriptor (EngineList); } WrapperList = PcieLibGetNextDescriptor (WrapperList); } GnbLibPciIndirectRMW ( Silicon->Address.AddressValue | D0F0x60_ADDRESS, D0F0x64_x0C_ADDRESS | IOC_WRITE_ENABLE, AccessS3SaveWidth32, (UINT32)~(BIT2 | BIT3 | BIT4 | BIT5 | BIT6 | BIT7), D0F0x64_x0C.Value, GnbLibGetHeader (Pcie) ); GnbLibPciIndirectRMW ( Silicon->Address.AddressValue | D0F0x60_ADDRESS, D0F0x64_x00_ADDRESS | IOC_WRITE_ENABLE, AccessS3SaveWidth32, (UINT32)~BIT6, 0x0, GnbLibGetHeader (Pcie) ); IDS_HDT_CONSOLE (GNB_TRACE, "Write D0F0x64_x0C.Value = %x\n", D0F0x64_x0C.Value); IDS_HDT_CONSOLE (GNB_TRACE, "PcieSiliconHidePorts Exit\n"); }
UINT32 PcieLanesToPowerDownPllInL1 ( IN UINT8 PllPowerUpLatency, IN PCIe_WRAPPER_CONFIG *Wrapper, IN PCIe_PLATFORM_CONFIG *Pcie ) { UINT8 LaneGroupExitLatency [4]; UINT32 LaneBitmapForPllOffInL1; PCIe_ENGINE_CONFIG *EngineList; UINTN Index; IDS_HDT_CONSOLE (GNB_TRACE, "PcieLanesToPowerDownPllInL1 Enter\n"); LaneBitmapForPllOffInL1 = 0; if (PcieUtilGetWrapperLaneBitMap (LANE_TYPE_PCIE_PHY_NATIVE_ALLOC_ACTIVE | LANE_TYPE_PCIE_PHY_NATIVE_HOTPLUG, 0, Wrapper) != 0) { if (Wrapper->Features.PllOffInL1 != 0) { LibAmdMemFill (&LaneGroupExitLatency[0], 0xFF, sizeof (LaneGroupExitLatency), GnbLibGetHeader (Pcie)); EngineList = PcieConfigGetChildEngine (Wrapper); while (EngineList != NULL) { PCIe_ASPM_LATENCY_INFO LinkLatencyInfo; UINT32 ActiveLanesBitmap; UINT32 HotplugLanesBitmap; if (EngineList->EngineData.EngineType == PciePortEngine) { LinkLatencyInfo.MaxL1ExitLatency = 0; LinkLatencyInfo.MaxL0sExitLatency = 0; ActiveLanesBitmap = PcieUtilGetEngineLaneBitMap (LANE_TYPE_PCIE_PHY_NATIVE_ALLOC_ACTIVE, 0, EngineList); HotplugLanesBitmap = PcieUtilGetEngineLaneBitMap (LANE_TYPE_PCIE_PHY_NATIVE_HOTPLUG, 0, EngineList); if (ActiveLanesBitmap != 0 && HotplugLanesBitmap == 0 && !PcieConfigIsSbPcieEngine (EngineList)) { PcieAspmGetMaxExitLatency (EngineList->Type.Port.Address, &LinkLatencyInfo, GnbLibGetHeader (Pcie)); } if (HotplugLanesBitmap != 0 || PcieConfigIsSbPcieEngine (EngineList)) { LinkLatencyInfo.MaxL1ExitLatency = 0xff; } IDS_HDT_CONSOLE (GNB_TRACE, " Engine %d Active Lanes 0x%x, Hotplug Lanes 0x%x\n", EngineList->Type.Port.NativeDevNumber, ActiveLanesBitmap, HotplugLanesBitmap); for (Index = 0; Index < 4; Index++) { if ((ActiveLanesBitmap & (0xF << (Index * 4))) != 0) { if (LaneGroupExitLatency [Index] > LinkLatencyInfo.MaxL1ExitLatency) { IDS_HDT_CONSOLE (GNB_TRACE, " Index %d Latency %d\n", Index, LinkLatencyInfo.MaxL1ExitLatency); LaneGroupExitLatency [Index] = LinkLatencyInfo.MaxL1ExitLatency; } } } } EngineList = PcieLibGetNextDescriptor (EngineList); } LaneBitmapForPllOffInL1 = 0; for (Index = 0; Index < 4; Index++) { IDS_HDT_CONSOLE (GNB_TRACE, " Index %d Final Latency %d\n", Index, LaneGroupExitLatency[Index]); if (LaneGroupExitLatency[Index] > PllPowerUpLatency) { LaneBitmapForPllOffInL1 |= (0xF << (Index * 4)); } } } } IDS_HDT_CONSOLE (GNB_TRACE, " Lane bitmap %04x\n", LaneBitmapForPllOffInL1); IDS_HDT_CONSOLE (GNB_TRACE, "PcieLanesToPowerDownPllInL1 Exit\n"); return LaneBitmapForPllOffInL1; }
/** * Control port visibility in PCI config space * * * @param[in] Control Make port Hide/Unhide ports * @param[in] Pcie Pointer to global PCIe configuration */ VOID PciePortsVisibilityControl ( IN PCIE_PORT_VISIBILITY Control, IN PCIe_PLATFORM_CONFIG *Pcie ) { PCIe_COMPLEX_CONFIG *ComplexList; ComplexList = &Pcie->ComplexList[0]; while (ComplexList != NULL) { PCIe_SILICON_CONFIG *SiliconList; SiliconList = PcieConfigGetChildSilicon (ComplexList); while (SiliconList != NULL) { PcieFmPortVisabilityControl (Control, SiliconList, Pcie); SiliconList = PcieLibGetNextDescriptor (SiliconList); } ComplexList = PcieLibGetNextDescriptor (ComplexList); } }
VOID PcieSiliconHidePorts ( IN PCIe_SILICON_CONFIG *Silicon, IN PCIe_PLATFORM_CONFIG *Pcie ) { D0F0x64_x0C_STRUCT D0F0x64_x0C; PCIe_WRAPPER_CONFIG *WrapperList; D0F0x64_x0C.Value = 0; WrapperList = PcieSiliconGetWrapperList (Silicon); while (WrapperList != NULL) { PCIe_ENGINE_CONFIG *EngineList; EngineList = PcieWrapperGetEngineList (WrapperList); while (EngineList != NULL) { if (EngineList->EngineData.EngineType == PciePortEngine) { if (!PcieConfigCheckPortStatus (EngineList, INIT_STATUS_PCIE_TRAINING_SUCCESS) && ((EngineList->Type.Port.PortData.LinkHotplug == HotplugDisabled) || (EngineList->Type.Port.PortData.LinkHotplug == HotplugInboard)) && !EngineList->Type.Port.IsSB) { D0F0x64_x0C.Value |= 1 << EngineList->Type.Port.NativeDevNumber; } } EngineList = PcieLibGetNextDescriptor (EngineList); } WrapperList = PcieLibGetNextDescriptor (WrapperList); } GnbLibPciIndirectRMW ( Silicon->Address.AddressValue | D0F0x60_ADDRESS, D0F0x64_x0C_ADDRESS | IOC_WRITE_ENABLE, AccessS3SaveWidth32, ~(UINT32)(BIT2 | BIT3 | BIT4 | BIT5 | BIT6 | BIT7), D0F0x64_x0C.Value, GnbLibGetHeader (Pcie) ); GnbLibPciIndirectRMW ( Silicon->Address.AddressValue | D0F0x60_ADDRESS, D0F0x64_x00_ADDRESS | IOC_WRITE_ENABLE, AccessS3SaveWidth32, ~(UINT32)BIT6, 0x0, GnbLibGetHeader (Pcie) ); }
/** * Get number of complexes in platform topology configuration * * * * @param[in] ComplexList First complex configuration in complex configuration array * @retval Number of Complexes * */ UINTN PcieInputParserGetNumberOfComplexes ( IN PCIe_COMPLEX_DESCRIPTOR *ComplexList ) { UINTN Result; Result = 0; while (ComplexList != NULL) { Result++; ComplexList = PcieLibGetNextDescriptor (ComplexList); } return Result; }
/** * Get number of PCIe engines in given complex * * * * @param[in] Complex Complex configuration * @retval Number of Engines */ UINTN PcieInputParserGetLengthOfPcieEnginesList ( IN PCIe_COMPLEX_DESCRIPTOR *Complex ) { UINTN Result; PCIe_PORT_DESCRIPTOR *PciePortList; Result = 0; PciePortList = Complex->PciePortList; while (PciePortList != NULL) { Result++; PciePortList = PcieLibGetNextDescriptor (PciePortList); } return Result; }
/** * Get number of DDI engines in given complex * * * * @param[in] Complex Complex configuration * @retval Number of Engines */ UINTN PcieInputParserGetLengthOfDdiEnginesList ( IN PCIe_COMPLEX_DESCRIPTOR *Complex ) { UINTN Result; PCIe_DDI_DESCRIPTOR *DdiLinkList; Result = 0; DdiLinkList = Complex->DdiLinkList; while (DdiLinkList != NULL) { Result++; DdiLinkList = PcieLibGetNextDescriptor (DdiLinkList); } return Result; }
/** * Locate SB engine on wrapper * * * * @param[in] Wrapper Pointer to wrapper config descriptor * @retval SB engine pointer or NULL */ PCIe_ENGINE_CONFIG * PcieConfigLocateSbEngine ( IN PCIe_WRAPPER_CONFIG *Wrapper ) { PCIe_ENGINE_CONFIG *EngineList; EngineList = PcieConfigGetChildEngine (Wrapper); while (EngineList != NULL) { if (PcieConfigIsSbPcieEngine (EngineList)) { return EngineList; } EngineList = PcieLibGetNextDescriptor (EngineList); } return NULL; }
AGESA_STATUS PcieMapTopologyOnComplex ( IN PCIe_COMPLEX_DESCRIPTOR *ComplexDescriptor, IN PCIe_COMPLEX_CONFIG *Complex, IN PCIe_PLATFORM_CONFIG *Pcie ) { PCIe_SILICON_CONFIG *Silicon; PCIe_WRAPPER_CONFIG *Wrapper; AGESA_STATUS AgesaStatus; AGESA_STATUS Status; AgesaStatus = AGESA_SUCCESS; IDS_HDT_CONSOLE (GNB_TRACE, "PcieMapTopologyOnComplex Enter\n"); Silicon = PcieConfigGetChildSilicon (Complex); while (Silicon != NULL) { Wrapper = PcieConfigGetChildWrapper (Silicon); while (Wrapper != NULL) { Status = PcieMapTopologyOnWrapper (ComplexDescriptor, Wrapper, Pcie); AGESA_STATUS_UPDATE (Status, AgesaStatus); if (Status == AGESA_ERROR) { PcieConfigDisableAllEngines (PciePortEngine | PcieDdiEngine, Wrapper); IDS_HDT_CONSOLE (PCIE_MISC, " ERROR! Fail to map topology on %s Wrapper\n", PcieFmDebugGetWrapperNameString (Wrapper) ); ASSERT (FALSE); } Wrapper = PcieLibGetNextDescriptor (Wrapper); } Status = PcieMapPortsPciAddresses (Silicon, Pcie); AGESA_STATUS_UPDATE (Status, AgesaStatus); Silicon = PcieLibGetNextDescriptor (Silicon); } IDS_HDT_CONSOLE (GNB_TRACE, "PcieMapTopologyOnComplex Exit [%x]\n", AgesaStatus); return AgesaStatus; }
/** * Disable all engines on wrapper * * * * @param[in] EngineTypeMask Engine type bitmap. * @param[in] Wrapper Pointer to wrapper config descriptor */ VOID PcieConfigDisableAllEngines ( IN UINTN EngineTypeMask, IN PCIe_WRAPPER_CONFIG *Wrapper ) { PCIe_ENGINE_CONFIG *EngineList; EngineList = PcieConfigGetChildEngine (Wrapper); while (EngineList != NULL) { if ((EngineList->EngineData.EngineType & EngineTypeMask) != 0) { PcieConfigDisableEngine (EngineList); } EngineList = PcieLibGetNextDescriptor (EngineList); } }
/** * Get port configuration signature for given wrapper and core * * Support for unify register access through index/data pair on GNB * * @param[in] Wrapper Pointer to wrapper config descriptor * @param[in] CoreId Core ID * @retval Configuration Signature */ UINT64 PcieConfigGetConfigurationSignature ( IN PCIe_WRAPPER_CONFIG *Wrapper, IN UINT8 CoreId ) { UINT64 ConfigurationSignature; PCIe_ENGINE_CONFIG *EngineList; ConfigurationSignature = 0; EngineList = PcieConfigGetChildEngine (Wrapper); while (EngineList != NULL) { if (PcieConfigIsPcieEngine (EngineList) && EngineList->Type.Port.CoreId == CoreId) { ConfigurationSignature = (ConfigurationSignature << 8) | PcieConfigGetNumberOfCoreLane (EngineList); } EngineList = PcieLibGetNextDescriptor (EngineList); } return ConfigurationSignature; }
VOID STATIC GnbIommuMidInitCheckGfxPciePorts ( IN PCIe_PLATFORM_CONFIG *Pcie ) { PCIe_WRAPPER_CONFIG *WrapperList; BOOLEAN GfxPciePortUsed; D0F2xF4_x57_STRUCT D0F2xF4_x57; IDS_HDT_CONSOLE (GNB_TRACE, "GnbIommuMidInitCheckGfxPciePorts Enter\n"); GfxPciePortUsed = FALSE; WrapperList = PcieConfigGetChildWrapper (Pcie); ASSERT (WrapperList != NULL); if (WrapperList->WrapId == GFX_WRAP_ID) { PCIe_ENGINE_CONFIG *EngineList; EngineList = PcieConfigGetChildEngine (WrapperList); while (EngineList != NULL) { if (PcieConfigIsPcieEngine (EngineList)) { IDS_HDT_CONSOLE (GNB_TRACE, "Checking Gfx ports device number %x\n", EngineList->Type.Port.NativeDevNumber); if (PcieConfigCheckPortStatus (EngineList, INIT_STATUS_PCIE_TRAINING_SUCCESS) || ((EngineList->Type.Port.PortData.LinkHotplug != HotplugDisabled) && (EngineList->Type.Port.PortData.LinkHotplug != HotplugInboard))) { // GFX PCIe ports beeing used GfxPciePortUsed = TRUE; IDS_HDT_CONSOLE (GNB_TRACE, "GFX PCIe ports beeing used\n"); break; } } EngineList = PcieLibGetNextDescriptor (EngineList); } } if (!GfxPciePortUsed) { //D0F2xF4_x57.Field.L1ImuPcieGfxDis needs to be set GnbRegisterReadTN (D0F2xF4_x57_TYPE, D0F2xF4_x57_ADDRESS, &D0F2xF4_x57.Value, 0, GnbLibGetHeader (Pcie)); D0F2xF4_x57.Field.L1ImuPcieGfxDis = 1; GnbRegisterWriteTN (D0F2xF4_x57_TYPE, D0F2xF4_x57_ADDRESS, &D0F2xF4_x57.Value, GNB_REG_ACC_FLAG_S3SAVE, GnbLibGetHeader (Pcie)); } IDS_HDT_CONSOLE (GNB_TRACE, "GnbIommuMidInitCheckGfxPciePorts Exit\n"); }
AGESA_STATUS STATIC PcieLnConfigureDdiEnginesLaneAllocation ( IN PCIe_WRAPPER_CONFIG *Wrapper, IN UINT8 ConfigurationId ) { PCIe_ENGINE_CONFIG *EnginesList; UINTN LaneIndex; EnginesList = PcieConfigGetChildEngine (Wrapper); if (ConfigurationId > ((sizeof (DdiLaneConfigurationTable) / (NUMBER_OF_DDIS * 2)) - 1)) { return AGESA_ERROR; } LaneIndex = 0; while (EnginesList != NULL) { PcieConfigResetDescriptorFlags (EnginesList, DESCRIPTOR_ALLOCATED); EnginesList->EngineData.StartLane = DdiLaneConfigurationTable [ConfigurationId][LaneIndex++] + Wrapper->StartPhyLane; EnginesList->EngineData.EndLane = DdiLaneConfigurationTable [ConfigurationId][LaneIndex++] + Wrapper->StartPhyLane; EnginesList = PcieLibGetNextDescriptor (EnginesList); } return AGESA_SUCCESS; }
/** * Configure engine list to support lane allocation according to configuration ID. * * * * @param[in] Wrapper Pointer to wrapper config descriptor * @param[in] DdiLaneConfig Lane configuration descriptor * @param[in] ConfigurationId Configuration ID * @retval AGESA_SUCCESS Configuration successfully applied * @retval AGESA_ERROR Requested configuration not supported */ AGESA_STATUS PcieConfigureDdiEnginesLaneAllocationML ( IN PCIe_WRAPPER_CONFIG *Wrapper, IN PCIe_LANE_ALLOC_DESCRIPTOR *DdiLaneConfig, IN UINT8 ConfigurationId ) { UINTN LaneIndex; PCIe_ENGINE_CONFIG *EnginesList; if (ConfigurationId >= DdiLaneConfig->NumberOfConfigurations) { return AGESA_ERROR; } LaneIndex = ConfigurationId * DdiLaneConfig->NumberOfEngines * 2; EnginesList = PcieConfigGetChildEngine (Wrapper); while (EnginesList != NULL) { if (PcieLibIsDdiEngine (EnginesList)) { PcieConfigResetDescriptorFlags (EnginesList, DESCRIPTOR_ALLOCATED); EnginesList->EngineData.StartLane = DdiLaneConfig->ConfigTable[LaneIndex++] + Wrapper->StartPhyLane; EnginesList->EngineData.EndLane = DdiLaneConfig->ConfigTable[LaneIndex++] + Wrapper->StartPhyLane; } EnginesList = PcieLibGetNextDescriptor (EnginesList); } return AGESA_SUCCESS; }
VOID PcieTopologyApplyLaneMux ( IN PCIe_WRAPPER_CONFIG *Wrapper, IN PCIe_PLATFORM_CONFIG *Pcie ) { PCIe_ENGINE_CONFIG *EngineList; UINT8 CurrentPhyLane; UINT8 CurrentCoreLane; UINT8 CoreLaneIndex; UINT8 PhyLaneIndex; UINT8 NumberOfPhyLane; UINT8 TxLaneMuxSelectorArray [sizeof (LaneMuxSelectorTable)]; UINT8 RxLaneMuxSelectorArray [sizeof (LaneMuxSelectorTable)]; UINT8 Index; UINT32 TxMaxSelectorValue; UINT32 RxMaxSelectorValue; IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologyApplyLaneMux Enter\n"); if (PcieLibIsPcieWrapper (Wrapper)) { EngineList = PcieConfigGetChildEngine (Wrapper); LibAmdMemCopy ( &TxLaneMuxSelectorArray[0], &LaneMuxSelectorTable[0], sizeof (LaneMuxSelectorTable), GnbLibGetHeader (Pcie) ); LibAmdMemCopy ( &RxLaneMuxSelectorArray[0], &LaneMuxSelectorTable[0], sizeof (LaneMuxSelectorTable), GnbLibGetHeader (Pcie) ); while (EngineList != NULL) { if (PcieLibIsPcieEngine (EngineList) && PcieLibIsEngineAllocated (EngineList)) { CurrentPhyLane = (UINT8) PcieLibGetLoPhyLane (EngineList) - Wrapper->StartPhyLane; NumberOfPhyLane = (UINT8) PcieConfigGetNumberOfPhyLane (EngineList); CurrentCoreLane = (UINT8) EngineList->Type.Port.StartCoreLane; if (PcieUtilIsLinkReversed (FALSE, EngineList, Pcie)) { CurrentCoreLane = CurrentCoreLane + PcieConfigGetNumberOfCoreLane (EngineList) - NumberOfPhyLane; } for (Index = 0; Index < NumberOfPhyLane; Index = Index + 2 ) { CoreLaneIndex = (CurrentCoreLane + Index) / 2; PhyLaneIndex = (CurrentPhyLane + Index) / 2; if (RxLaneMuxSelectorArray [CoreLaneIndex] != PhyLaneIndex) { RxLaneMuxSelectorArray [PcieTopologyLocateMuxIndex (RxLaneMuxSelectorArray, PhyLaneIndex)] = RxLaneMuxSelectorArray [CoreLaneIndex]; RxLaneMuxSelectorArray [CoreLaneIndex] = PhyLaneIndex; } if (TxLaneMuxSelectorArray [PhyLaneIndex] != CoreLaneIndex) { TxLaneMuxSelectorArray [PcieTopologyLocateMuxIndex (TxLaneMuxSelectorArray, CoreLaneIndex)] = TxLaneMuxSelectorArray [PhyLaneIndex]; TxLaneMuxSelectorArray [PhyLaneIndex] = CoreLaneIndex; } } } EngineList = PcieLibGetNextDescriptor (EngineList); } RxMaxSelectorValue = 0; TxMaxSelectorValue = 0; for (Index = 0; Index < sizeof (LaneMuxSelectorTable); Index++) { RxMaxSelectorValue |= (RxLaneMuxSelectorArray[Index] << (Index * 4)); TxMaxSelectorValue |= (TxLaneMuxSelectorArray[Index] << (Index * 4)); } PcieRegisterWrite ( Wrapper, WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8021_ADDRESS), TxMaxSelectorValue, FALSE, Pcie ); PcieRegisterWrite ( Wrapper, WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8022_ADDRESS), RxMaxSelectorValue, FALSE, Pcie ); } IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologyApplyLaneMux Exit\n"); }
VOID PcieTopologySelectMasterPll ( IN PCIe_WRAPPER_CONFIG *Wrapper, IN PCIe_PLATFORM_CONFIG *Pcie ) { PCIe_ENGINE_CONFIG *EngineList; UINT16 MasterPhyLane; UINT16 MasterHotplugPhyLane; D0F0xE4_WRAP_8013_STRUCT D0F0xE4_WRAP_8013; EngineList = PcieWrapperGetEngineList (Wrapper); MasterPhyLane = 0xffff; MasterHotplugPhyLane = 0xffff; IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologySelectMasterPll Enter\n"); while (EngineList != NULL) { if (PcieLibIsEngineAllocated (EngineList)) { if (EngineList->EngineData.EngineType == PciePortEngine) { MasterPhyLane = EngineList->EngineData.StartLane; if (EngineList->Type.Port.PortData.LinkHotplug != HotplugDisabled) { MasterHotplugPhyLane = MasterPhyLane; } } } EngineList = PcieLibGetNextDescriptor (EngineList); } if (MasterPhyLane == 0xffff) { MasterPhyLane = MasterHotplugPhyLane; if (MasterPhyLane == 0xffff) { MasterPhyLane = Wrapper->StartPhyLane; } } D0F0xE4_WRAP_8013.Value = PcieRegisterRead ( Wrapper, WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8013_ADDRESS), Pcie ); MasterPhyLane = MasterPhyLane - Wrapper->StartPhyLane; if ( MasterPhyLane <= 3 ) { D0F0xE4_WRAP_8013.Field.MasterPciePllA = 0x1; D0F0xE4_WRAP_8013.Field.MasterPciePllB = 0x0; D0F0xE4_WRAP_8013.Field.MasterPciePllC = 0x0; D0F0xE4_WRAP_8013.Field.MasterPciePllD = 0x0; } else if (MasterPhyLane <= 7) { D0F0xE4_WRAP_8013.Field.MasterPciePllA = 0x0; D0F0xE4_WRAP_8013.Field.MasterPciePllB = 0x1; D0F0xE4_WRAP_8013.Field.MasterPciePllC = 0x0; D0F0xE4_WRAP_8013.Field.MasterPciePllD = 0x0; } else if (MasterPhyLane <= 11) { D0F0xE4_WRAP_8013.Field.MasterPciePllA = 0x0; D0F0xE4_WRAP_8013.Field.MasterPciePllB = 0x0; D0F0xE4_WRAP_8013.Field.MasterPciePllC = 0x1; D0F0xE4_WRAP_8013.Field.MasterPciePllD = 0x0; } else { D0F0xE4_WRAP_8013.Field.MasterPciePllA = 0x0; D0F0xE4_WRAP_8013.Field.MasterPciePllB = 0x0; D0F0xE4_WRAP_8013.Field.MasterPciePllC = 0x0; D0F0xE4_WRAP_8013.Field.MasterPciePllD = 0x1; } PcieRegisterWrite ( Wrapper, WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8013_ADDRESS), D0F0xE4_WRAP_8013.Value, FALSE, Pcie ); IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologySelectMasterPll Enter\n"); }
/** * Configure engine list to support lane allocation according to configuration ID. * * PCIE port * * * 1 Check if lane from user port descriptor (PCIe_PORT_DESCRIPTOR) belongs to wrapper (PCIe_WRAPPER_CONFIG) * 2 Check if link width from user descriptor less or equal to link width of engine (PCIe_ENGINE_CONFIG) * 3 Check if link width is correct. Correct link width for PCIe port x1, x2, x4, x8, x16, correct link width for DDI x4, x8 * 4 Check if user port device number (PCIe_PORT_DESCRIPTOR) match engine port device number (PCIe_ENGINE_CONFIG) * 5 Check if lane can be muxed * * * DDI Link * * 1 Check if lane from user port descriptor (PCIe_DDI_DESCRIPTOR) belongs to wrapper (PCIe_WRAPPER_CONFIG) * 2 Check lane from (PCIe_DDI_DESCRIPTOR) match exactly phy lane (PCIe_ENGINE_CONFIG) * * * * @param[in] ComplexDescriptor Pointer to used define complex descriptor * @param[in,out] Wrapper Pointer to wrapper config descriptor * @param[in] Pcie Pointer to global PCIe configuration * @retval AGESA_SUCCESS Topology successfully mapped * @retval AGESA_ERROR Topology can not be mapped */ AGESA_STATUS PcieMapTopologyOnWrapper ( IN PCIe_COMPLEX_DESCRIPTOR *ComplexDescriptor, IN OUT PCIe_WRAPPER_CONFIG *Wrapper, IN PCIe_PLATFORM_CONFIG *Pcie ) { AGESA_STATUS AgesaStatus; AGESA_STATUS Status; PCIe_ENGINE_CONFIG *EngineList; UINT32 WrapperPhyLaneBitMap; IDS_HDT_CONSOLE (GNB_TRACE, "PcieMapTopologyOnWrapper Enter\n"); AgesaStatus = AGESA_SUCCESS; if (PcieLibIsPcieWrapper (Wrapper)) { Status = PcieEnginesToWrapper (PciePortEngine, ComplexDescriptor, Wrapper); AGESA_STATUS_UPDATE (Status, AgesaStatus); if (Status == AGESA_ERROR) { // If we can not map topology on wrapper we can not enable any engines. PutEventLog ( AGESA_ERROR, GNB_EVENT_INVALID_PCIE_TOPOLOGY_CONFIGURATION, Wrapper->WrapId, Wrapper->StartPhyLane, Wrapper->EndPhyLane, 0, GnbLibGetHeader (Pcie) ); PcieConfigDisableAllEngines (PciePortEngine, Wrapper); } } if (PcieLibIsDdiWrapper (Wrapper)) { Status = PcieEnginesToWrapper (PcieDdiEngine, ComplexDescriptor, Wrapper); AGESA_STATUS_UPDATE (Status, AgesaStatus); if (Status == AGESA_ERROR) { // If we can not map topology on wrapper we can not enable any engines. PutEventLog ( AGESA_ERROR, GNB_EVENT_INVALID_DDI_TOPOLOGY_CONFIGURATION, Wrapper->WrapId, Wrapper->StartPhyLane, Wrapper->EndPhyLane, 0, GnbLibGetHeader (Pcie) ); PcieConfigDisableAllEngines (PcieDdiEngine, Wrapper); } } // Copy engine data PcieMapInitializeEngineData (ComplexDescriptor, Wrapper, Pcie); EngineList = PcieConfigGetChildEngine (Wrapper); // Verify if we oversubscribe lanes and PHY link width WrapperPhyLaneBitMap = 0; while (EngineList != NULL) { UINT32 EnginePhyLaneBitMap; if (PcieLibIsEngineAllocated (EngineList)) { EnginePhyLaneBitMap = PcieConfigGetEnginePhyLaneBitMap (EngineList); if ((WrapperPhyLaneBitMap & EnginePhyLaneBitMap) != 0) { IDS_HDT_CONSOLE (PCIE_MISC, " ERROR! Lanes double subscribe lanes [Engine Lanes %d..%d]\n", EngineList->EngineData.StartLane, EngineList->EngineData.EndLane ); PutEventLog ( AGESA_ERROR, GNB_EVENT_INVALID_LANES_CONFIGURATION, EngineList->EngineData.StartLane, EngineList->EngineData.EndLane, 0, 0, GnbLibGetHeader (Pcie) ); PcieConfigDisableEngine (EngineList); Status = AGESA_ERROR; AGESA_STATUS_UPDATE (Status, AgesaStatus); } else { WrapperPhyLaneBitMap |= EnginePhyLaneBitMap; } } EngineList = PcieLibGetNextDescriptor (EngineList); } IDS_HDT_CONSOLE (GNB_TRACE, "PcieMapTopologyOnWrapper Exit [%d]\n", AgesaStatus); return AgesaStatus; }
VOID PcieTopologySelectMasterPll ( IN PCIe_WRAPPER_CONFIG *Wrapper, OUT BOOLEAN *ConfigChanged, IN PCIe_PLATFORM_CONFIG *Pcie ) { PCIe_ENGINE_CONFIG *EngineList; UINT16 MasterLane; UINT16 MasterHotplugLane; D0F0xE4_WRAP_8013_STRUCT D0F0xE4_WRAP_8013; D0F0xE4_WRAP_8013_STRUCT D0F0xE4_WRAP_8013_BASE; IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologySelectMasterPll Enter\n"); MasterLane = 0xFFFF; MasterHotplugLane = 0xFFFF; EngineList = PcieConfigGetChildEngine (Wrapper); while (EngineList != NULL) { if (PcieConfigIsEngineAllocated (EngineList) && EngineList->Type.Port.PortData.PortPresent != PortDisabled && PcieConfigIsPcieEngine (EngineList)) { if (EngineList->Type.Port.PortData.LinkHotplug != HotplugDisabled) { MasterHotplugLane = PcieConfigGetPcieEngineMasterLane (EngineList); } else { MasterLane = PcieConfigGetPcieEngineMasterLane (EngineList); if (PcieConfigIsSbPcieEngine (EngineList)) { break; } } } EngineList = PcieLibGetNextDescriptor (EngineList); } if (MasterLane == 0xffff) { if (MasterHotplugLane != 0xffff) { MasterLane = MasterHotplugLane; } else { MasterLane = 0x0; } } D0F0xE4_WRAP_8013.Value = PcieRegisterRead ( Wrapper, WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8013_ADDRESS), Pcie ); D0F0xE4_WRAP_8013_BASE.Value = D0F0xE4_WRAP_8013.Value; if ( MasterLane <= 3 ) { D0F0xE4_WRAP_8013.Field.MasterPciePllA = 0x1; D0F0xE4_WRAP_8013.Field.MasterPciePllB = 0x0; D0F0xE4_WRAP_8013.Field.MasterPciePllC = 0x0; D0F0xE4_WRAP_8013.Field.MasterPciePllD = 0x0; Wrapper->MasterPll = 0xA; } else if (MasterLane <= 7) { D0F0xE4_WRAP_8013.Field.MasterPciePllA = 0x0; D0F0xE4_WRAP_8013.Field.MasterPciePllB = 0x1; D0F0xE4_WRAP_8013.Field.MasterPciePllC = 0x0; D0F0xE4_WRAP_8013.Field.MasterPciePllD = 0x0; Wrapper->MasterPll = 0xB; } else if (MasterLane <= 11) { D0F0xE4_WRAP_8013.Field.MasterPciePllA = 0x0; D0F0xE4_WRAP_8013.Field.MasterPciePllB = 0x0; D0F0xE4_WRAP_8013.Field.MasterPciePllC = 0x1; D0F0xE4_WRAP_8013.Field.MasterPciePllD = 0x0; Wrapper->MasterPll = 0xC; } else { D0F0xE4_WRAP_8013.Field.MasterPciePllA = 0x0; D0F0xE4_WRAP_8013.Field.MasterPciePllB = 0x0; D0F0xE4_WRAP_8013.Field.MasterPciePllC = 0x0; D0F0xE4_WRAP_8013.Field.MasterPciePllD = 0x1; Wrapper->MasterPll = 0xD; } if (ConfigChanged != NULL) { *ConfigChanged = (D0F0xE4_WRAP_8013.Value == D0F0xE4_WRAP_8013_BASE.Value) ? FALSE : TRUE; } PcieRegisterWrite ( Wrapper, WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8013_ADDRESS), D0F0xE4_WRAP_8013.Value, FALSE, Pcie ); IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologySelectMasterPll Exit\n"); }
VOID STATIC PcieTopologyApplyLaneMuxCZ ( IN PCIe_WRAPPER_CONFIG *Wrapper, IN PCIe_PLATFORM_CONFIG *Pcie ) { PCIe_ENGINE_CONFIG *EngineList; UINT32 Index; UINT8 RxLaneMuxSelectorArray [sizeof (LaneMuxSelectorArrayCZ)]; UINT8 TxLaneMuxSelectorArray [sizeof (LaneMuxSelectorArrayCZ)]; IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologyApplyLaneMuxCZ Enter\n"); if (PcieLibIsPcieWrapper (Wrapper)) { LibAmdMemCopy ( &TxLaneMuxSelectorArray[0], &LaneMuxSelectorArrayCZ[0], sizeof (LaneMuxSelectorArrayCZ), GnbLibGetHeader (Pcie) ); LibAmdMemCopy ( &RxLaneMuxSelectorArray[0], &LaneMuxSelectorArrayCZ[0], sizeof (LaneMuxSelectorArrayCZ), GnbLibGetHeader (Pcie) ); EngineList = PcieConfigGetChildEngine (Wrapper); while (EngineList != NULL) { if (PcieLibIsPcieEngine (EngineList) && PcieLibIsEngineAllocated (EngineList)) { UINT32 CoreLaneBitmap; UINT32 PifLaneBitmap; UINT8 CurrentCoreLane; UINT8 CurrentPifLane; CoreLaneBitmap = PcieUtilGetEngineLaneBitMap (LANE_TYPE_PCIE_CORE_ALLOC, 0, EngineList); PifLaneBitmap = PcieUtilGetEngineLaneBitMap (LANE_TYPE_PCIE_PHY_NATIVE, 0, EngineList); IDS_HDT_CONSOLE (GNB_TRACE, "CoreLaneBitmap - %x, CurrentPifLane - %x\n", CoreLaneBitmap, PifLaneBitmap); while (CoreLaneBitmap != 0) { CurrentCoreLane = LibAmdBitScanForward (CoreLaneBitmap); CurrentPifLane = LibAmdBitScanForward (PifLaneBitmap); if (TxLaneMuxSelectorArray[CurrentPifLane] != CurrentCoreLane) { TxLaneMuxSelectorArray[PcieTopologyLocateMuxIndexCZ (TxLaneMuxSelectorArray, CurrentCoreLane)] = TxLaneMuxSelectorArray[CurrentPifLane]; TxLaneMuxSelectorArray[CurrentPifLane] = CurrentCoreLane; } if (RxLaneMuxSelectorArray[CurrentCoreLane] != CurrentPifLane) { RxLaneMuxSelectorArray[PcieTopologyLocateMuxIndexCZ (RxLaneMuxSelectorArray, CurrentPifLane)] = RxLaneMuxSelectorArray[CurrentCoreLane]; RxLaneMuxSelectorArray[CurrentCoreLane] = CurrentPifLane; } CoreLaneBitmap &= (~ (1 << CurrentCoreLane)); PifLaneBitmap &= (~ (1 << CurrentPifLane)); } } EngineList = PcieLibGetNextDescriptor (EngineList); } for (Index = 0; Index < 2; ++Index) { PcieRegisterWrite ( Wrapper, CORE_SPACE (Wrapper->StartPcieCoreId, D0F0xE4_CORE_0121_ADDRESS + Index), ((UINT32 *) TxLaneMuxSelectorArray) [Index], FALSE, Pcie ); PcieRegisterWrite ( Wrapper, CORE_SPACE (Wrapper->StartPcieCoreId, D0F0xE4_CORE_0125_ADDRESS + Index), ((UINT32 *) RxLaneMuxSelectorArray) [Index], FALSE, Pcie ); } } IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologyApplyLaneMuxCZ Exit\n"); }
/** * Configure engine list to support lane allocation according to configuration ID. * * * * @param[in] EngineType Engine type * @param[in] ComplexDescriptor Pointer to used define complex descriptor * @param[in] Wrapper Pointer to wrapper config descriptor * @retval AGESA_SUCCESS Topology successfully mapped * @retval AGESA_ERROR Topology can not be mapped */ STATIC AGESA_STATUS PcieEnginesToWrapper ( IN PCIE_ENGINE_TYPE EngineType, IN PCIe_COMPLEX_DESCRIPTOR *ComplexDescriptor, IN PCIe_WRAPPER_CONFIG *Wrapper ) { AGESA_STATUS Status; PCIe_ENGINE_CONFIG *EngineList; PCIe_ENGINE_DESCRIPTOR *EngineDescriptor; UINT8 ConfigurationId; UINT8 Allocations; UINTN Index; UINTN NumberOfDescriptors; ConfigurationId = 0; Allocations = 0; IDS_HDT_CONSOLE (GNB_TRACE, "PcieEnginesToWrapper Enter\n"); NumberOfDescriptors = PcieInputParserGetNumberOfEngines (ComplexDescriptor); do { Status = PcieFmConfigureEnginesLaneAllocation (Wrapper, EngineType, ConfigurationId++); if (Status == AGESA_SUCCESS) { Allocations = 0; for (Index = 0; Index < NumberOfDescriptors; Index++) { EngineDescriptor = PcieInputParserGetEngineDescriptor (ComplexDescriptor, Index); if (EngineDescriptor->EngineData.EngineType == EngineType) { // Step 1, belongs to wrapper check. if (PcieCheckDescriptorMapsToWrapper (EngineDescriptor, Wrapper)) { ++Allocations; EngineList = PcieConfigGetChildEngine (Wrapper); while (EngineList != NULL) { if (!PcieLibIsEngineAllocated (EngineList)) { // Step 2.user descriptor less or equal to link width of engine if (PcieCheckLanesMatch (EngineDescriptor, EngineList)) { // Step 3, Check if link width is correct.x1, x2, x4, x8, x16. if (!PcieIsDescriptorLinkWidthValid (EngineDescriptor)) { PcieConfigDisableEngine (EngineList); return AGESA_ERROR; } if (EngineDescriptor->EngineData.EngineType == PciePortEngine) { // Step 4, Family specifc, port device number match engine device if (PcieCheckPortPciDeviceMapping ((PCIe_PORT_DESCRIPTOR*) EngineDescriptor, EngineList)) { //Step 5, Family specifc, lanes can be muxed. if (PcieFmCheckPortPcieLaneCanBeMuxed ((PCIe_PORT_DESCRIPTOR*) EngineDescriptor, EngineList)) { PcieAllocateEngine ((UINT8) Index, EngineList); --Allocations; break; } } } else { PcieAllocateEngine ((UINT8) Index, EngineList); --Allocations; break; } } } //end if PcieLibIsEngineAllocated EngineList = PcieLibGetNextDescriptor (EngineList); } } //end if PcieCheckDescriptorMapsToWrapper } // end if EngineType } //end for } } while (Status == AGESA_SUCCESS && Allocations != 0); IDS_HDT_CONSOLE (GNB_TRACE, "PcieEnginesToWrapper Exit [%x]\n", Status); return Status; }
/** * Helper function to dump configuration to debug out * * * @param[in] Pcie Pointer to global PCIe configuration */ VOID PcieConfigDebugDump ( IN PCIe_PLATFORM_CONFIG *Pcie ) { PCIe_SILICON_CONFIG *SiliconList; PCIe_WRAPPER_CONFIG *WrapperList; PCIe_COMPLEX_CONFIG *ComplexList; ComplexList = (PCIe_COMPLEX_CONFIG *) PcieConfigGetChild (DESCRIPTOR_COMPLEX, &Pcie->Header); IDS_HDT_CONSOLE (PCIE_MISC, "<-------------- PCIe Config Start------------>\n"); IDS_HDT_CONSOLE (PCIE_MISC, " PSPP Policy - %s\n", (Pcie->PsppPolicy == PsppPowerSaving) ? "Power Saving" : (Pcie->PsppPolicy == PsppBalanceHigh) ? "Balance-High" : ( (Pcie->PsppPolicy == PsppBalanceLow) ? "Balance-Low" : ( (Pcie->PsppPolicy == PsppPerformance) ? "Performance" : ( (Pcie->PsppPolicy == PsppDisabled) ? "Disabled" : "Unknown"))) ); IDS_HDT_CONSOLE (PCIE_MISC, " GFX Workaround - %s\n", (Pcie->GfxCardWorkaround == 0) ? "Disabled" : "Enabled" ); IDS_HDT_CONSOLE (PCIE_MISC, " LinkL0Pooling - %dus\n", Pcie->LinkL0Pooling ); IDS_HDT_CONSOLE (PCIE_MISC, " LinkGpioResetAssertionTime - %dus\n", Pcie->LinkGpioResetAssertionTime ); IDS_HDT_CONSOLE (PCIE_MISC, " LinkReceiverDetectionPooling - %dus\n", Pcie->LinkReceiverDetectionPooling ); IDS_HDT_CONSOLE (PCIE_MISC, " Training Algorythm - %s\n", (Pcie->TrainingAlgorithm == PcieTrainingStandard) ? "PcieTrainingStandard" : ( (Pcie->TrainingAlgorithm == PcieTrainingDistributed) ? "PcieTrainingDistributed" : "Unknown") ); while (ComplexList != NULL) { IDS_HDT_CONSOLE (PCIE_MISC, " <---------- Complex Config Start ---------->\n"); IDS_HDT_CONSOLE (PCIE_MISC, " Descriptor Flags - 0x%08x\n", ComplexList->Header.DescriptorFlags); IDS_HDT_CONSOLE (PCIE_MISC, " Socket ID - %d\n", ComplexList->SocketId); SiliconList = PcieConfigGetChildSilicon (ComplexList); while (SiliconList != NULL) { IDS_HDT_CONSOLE (PCIE_MISC, " <---------- Silicon Config Start -------->\n"); IDS_HDT_CONSOLE (PCIE_MISC, " Descriptor Flags - 0x%08x\n", SiliconList->Header.DescriptorFlags); IDS_HDT_CONSOLE (PCIE_MISC, " Silicon ID - %d\n", SiliconList->SiliconId); IDS_HDT_CONSOLE (PCIE_MISC, " Node ID - %d\n", SiliconList->NodeId); IDS_HDT_CONSOLE (PCIE_MISC, " Host PCI Address - %d:%d:%d\n", SiliconList->Address.Address.Bus, SiliconList->Address.Address.Device, SiliconList->Address.Address.Function ); WrapperList = PcieConfigGetChildWrapper (SiliconList); while (WrapperList != NULL) { PcieConfigWrapperDebugDump (WrapperList); WrapperList = PcieLibGetNextDescriptor (WrapperList); } IDS_HDT_CONSOLE (PCIE_MISC, " <---------- Silicon Config End ---------->\n"); SiliconList = PcieLibGetNextDescriptor (SiliconList); } IDS_HDT_CONSOLE (PCIE_MISC, " <---------- Complex Config End ------------>\n"); ComplexList = PcieLibGetNextDescriptor (ComplexList); } IDS_HDT_CONSOLE (PCIE_MISC, "<-------------- PCIe Config End-------------->\n"); }