AGESA_STATUS STATIC PcieOnConfigureGppEnginesLaneAllocation ( 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 = PcieWrapperGetEngineList (Wrapper); CoreLaneIndex = 0; PortIdIndex = 0; do { if (PortIdIndex > 0) EnginesList++; EnginesList->Flags &= ~DESCRIPTOR_ALLOCATED; EnginesList->Type.Port.PortId = GppPortIdConfigurationTable [ConfigurationId][PortIdIndex++]; EnginesList->Type.Port.StartCoreLane = GppLaneConfigurationTable [ConfigurationId][CoreLaneIndex++]; EnginesList->Type.Port.EndCoreLane = GppLaneConfigurationTable [ConfigurationId][CoreLaneIndex++]; } while (IS_LAST_DESCRIPTOR (EnginesList)); return AGESA_SUCCESS; }
/** * 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 = PcieWrapperGetEngineList (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"); }
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 (Wrapper->Features.PllOffInL1 != 0) { LibAmdMemFill (&LaneGroupExitLatency[0], 0xFF, sizeof (LaneGroupExitLatency), GnbLibGetHeader (Pcie)); EngineList = PcieWrapperGetEngineList (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_ACTIVE, 0, EngineList, Pcie); HotplugLanesBitmap = PcieUtilGetEngineLaneBitMap (LANE_TYPE_PCIE_HOTPLUG, 0, EngineList, Pcie); if (ActiveLanesBitmap != 0 && HotplugLanesBitmap == 0 && !EngineList->Type.Port.IsSB) { PcieAspmGetMaxExitLatency (EngineList->Type.Port.Address, &LinkLatencyInfo, GnbLibGetHeader (Pcie)); } if (HotplugLanesBitmap != 0 || EngineList->Type.Port.IsSB) { 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; }
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) ); }
AGESA_STATUS STATIC PcieOnConfigureDdiEnginesLaneAllocation ( IN PCIe_WRAPPER_CONFIG *Wrapper, IN UINT8 ConfigurationId ) { PCIe_ENGINE_CONFIG *EnginesList; UINTN LaneIndex; EnginesList = PcieWrapperGetEngineList (Wrapper); if (ConfigurationId > ((sizeof (DdiLaneConfigurationTable) / (NUMBER_OF_DDIS * 2)) - 1)) { return AGESA_ERROR; } LaneIndex = 0; do { if (LaneIndex > 0) EnginesList++; EnginesList->Flags &= ~DESCRIPTOR_ALLOCATED; EnginesList->EngineData.StartLane = DdiLaneConfigurationTable [ConfigurationId][LaneIndex++] + Wrapper->StartPhyLane; EnginesList->EngineData.EndLane = DdiLaneConfigurationTable [ConfigurationId][LaneIndex++] + Wrapper->StartPhyLane; } while (IS_LAST_DESCRIPTOR (EnginesList)); return AGESA_SUCCESS; }
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"); }
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 = PcieWrapperGetEngineList (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"); }