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; }
VOID STATIC PciePostS3PortInitCallbackML ( IN PCIe_ENGINE_CONFIG *Engine, IN OUT VOID *Buffer, IN PCIe_PLATFORM_CONFIG *Pcie ) { PCIE_LINK_SPEED_CAP LinkSpeedCapability; PCIE_LINK_TRAINING_STATE State; ASSERT (Engine->EngineData.EngineType == PciePortEngine); LinkSpeedCapability = PcieFmGetLinkSpeedCap (PCIE_PORT_GEN_CAP_BOOT, Engine); PcieSetLinkSpeedCapV4 (LinkSpeedCapability, Engine, Pcie); if (Engine->Type.Port.PortData.MiscControls.LinkSafeMode == PcieGen1) { PcieLinkSafeMode (Engine, Pcie); } if (!PcieConfigIsSbPcieEngine (Engine)) { // // General Port // State = LinkStateDeviceNotPresent; if (Engine->Type.Port.PortData.LinkHotplug == HotplugDisabled || Engine->Type.Port.PortData.LinkHotplug == HotplugInboard) { // // Non hotplug device: we only check status from previous boot // if (PcieConfigCheckPortStatus (Engine, INIT_STATUS_PCIE_TRAINING_SUCCESS)) { State = LinkStateResetExit; } } else { UINT32 PcieScratch; // // Get endpoint staus from scratch // PcieScratch = PciePortRegisterRead (Engine, DxFxxE4_x01_ADDRESS, Pcie); // // Hotplug device: we check ep status if reported // if ((PcieScratch & 0x1) == 0) { State = LinkStateResetExit; } } // // For compliance we always leave link in enabled state // if (Engine->Type.Port.PortData.MiscControls.LinkComplianceMode) { State = LinkStateResetExit; } PcieConfigUpdatePortStatus (Engine, 0, INIT_STATUS_PCIE_TRAINING_SUCCESS); } else { // // SB port // State = LinkStateTrainingSuccess; } PcieTrainingSetPortStateV2 (Engine, State, FALSE, Pcie); }
VOID STATIC PcieSiliconEnablePortsV5 ( IN PCIe_SILICON_CONFIG *Silicon, IN PCIe_PLATFORM_CONFIG *Pcie ) { PCIe_ENGINE_CONFIG *EngineList; EngineList = PcieConfigGetChildEngine (Silicon); while (EngineList != NULL) { if (PcieConfigIsPcieEngine (EngineList)) { if (!PcieConfigIsSbPcieEngine (EngineList) && (PcieConfigCheckPortStatus (EngineList, INIT_STATUS_PCIE_TRAINING_SUCCESS) || ((EngineList->Type.Port.PortData.LinkHotplug != HotplugDisabled) && (EngineList->Type.Port.PortData.LinkHotplug != HotplugInboard)))) { GnbLibPciIndirectRMW ( Silicon->Address.AddressValue | D0F0xC8_ADDRESS, D0F0xCC_x01_ADDRESS | ((EngineList->Type.Port.PortData.DeviceNumber << 3 | EngineList->Type.Port.PortData.FunctionNumber) << D0F0xC8_NB_DEV_IND_SEL_OFFSET), AccessS3SaveWidth32, (UINT32)~(D0F0xCC_x01_BridgeDis_MASK | D0F0xCC_x01_CfgDis_MASK | D0F0xCC_x01_CsrEnable_MASK | D0F0xCC_x01_SetPowEn_MASK), ((1 << D0F0xCC_x01_CsrEnable_OFFSET) | (1 << D0F0xCC_x01_SetPowEn_OFFSET)), GnbLibGetHeader (Pcie) ); } } EngineList = (PCIe_ENGINE_CONFIG *) PcieConfigGetNextTopologyDescriptor (EngineList, DESCRIPTOR_TERMINATE_GNB); } }
/** * Get max link speed capability supported by this port * * * * @param[in] Flags See Flags PCIE_PORT_GEN_CAP_BOOT / PCIE_PORT_GEN_CAP_MAX * @param[in] Engine Pointer to engine config descriptor * @retval PcieGen1/PcieGen2 Max supported link gen capability */ PCIE_LINK_SPEED_CAP PcieGetLinkSpeedCapML ( IN UINT32 Flags, IN PCIe_ENGINE_CONFIG *Engine ) { PCIE_LINK_SPEED_CAP LinkSpeedCapability; PCIe_WRAPPER_CONFIG *Wrapper; PCIe_PLATFORM_CONFIG *Pcie; Wrapper = PcieConfigGetParentWrapper (Engine); Pcie = PcieConfigGetPlatform (Wrapper); LinkSpeedCapability = PcieGen2; if (Engine->Type.Port.PortData.LinkSpeedCapability == PcieGenMaxSupported) { Engine->Type.Port.PortData.LinkSpeedCapability = (UINT8) LinkSpeedCapability; } if (Pcie->PsppPolicy == PsppPowerSaving) { LinkSpeedCapability = PcieGen1; } if (Engine->Type.Port.PortData.LinkSpeedCapability < LinkSpeedCapability) { LinkSpeedCapability = Engine->Type.Port.PortData.LinkSpeedCapability; } if ((Flags & PCIE_PORT_GEN_CAP_BOOT) != 0) { if (( Pcie->PsppPolicy == PsppBalanceLow || Engine->Type.Port.PortData.MiscControls.LinkSafeMode == PcieGen1) && !PcieConfigIsSbPcieEngine (Engine)) { LinkSpeedCapability = PcieGen1; } } return LinkSpeedCapability; }
/** * Disable engine * * * * @param[in] Engine Pointer to engine config descriptor */ VOID PcieConfigDisableEngine ( IN PCIe_ENGINE_CONFIG *Engine ) { if (PcieConfigIsSbPcieEngine (Engine)) { return; } PcieConfigResetDescriptorFlags (Engine, DESCRIPTOR_ALLOCATED); }
VOID PcieEnableAspm ( IN PCIe_ENGINE_CONFIG *Engine, IN PCIe_PLATFORM_CONFIG *Pcie ) { if (Engine->Type.Port.PortData.LinkAspm != AspmDisabled) { if (PcieConfigIsSbPcieEngine (Engine)) { SbPcieLinkAspmControl (Engine, Pcie); } } }
VOID STATIC PcieAlibUpdatePciePortDataCallback ( IN PCIe_ENGINE_CONFIG *Engine, IN OUT VOID *Buffer, IN PCIe_PLATFORM_CONFIG *Pcie ) { _ALIB_PORT_DATA *PortData; PortData = &((ALIB_DATA *) Buffer)->PortData[Engine->Type.Port.PcieBridgeId].PortData; if (PcieConfigIsEngineAllocated (Engine) && (Engine->Type.Port.PortData.LinkHotplug != HotplugDisabled || PcieConfigCheckPortStatus (Engine, INIT_STATUS_PCIE_TRAINING_SUCCESS))) { // // Various speed capability // PortData->PciePortMaxSpeed = (UINT8) PcieFmGetLinkSpeedCap (PCIE_PORT_GEN_CAP_MAX, Engine); PortData->PciePortCurSpeed = (UINT8) PcieFmGetLinkSpeedCap (PCIE_PORT_GEN_CAP_BOOT, Engine); PortData->PciePortDcSpeed = PcieGen1; PortData->PciePortAcSpeed = PortData->PciePortMaxSpeed; if (Pcie->PsppPolicy == PsppBalanceLow) { PortData->PciePortAcSpeed = PcieGen1; } if (PcieConfigIsSbPcieEngine (Engine)) { PortData->PcieSbPort = 0x1; PortData->PciePortAcSpeed = PortData->PciePortMaxSpeed; } if (Engine->Type.Port.PortData.MiscControls.LinkSafeMode != 0) { PortData->PcieLinkSafeMode = 0x1; PortData->PcieLocalOverrideSpeed = Engine->Type.Port.PortData.MiscControls.LinkSafeMode; } // // various port capability // PortData->StartPhyLane = (UINT8) Engine->EngineData.StartLane; PortData->EndPhyLane = (UINT8) Engine->EngineData.EndLane; PortData->StartCoreLane = (UINT8) Engine->Type.Port.StartCoreLane; PortData->EndCoreLane = (UINT8) Engine->Type.Port.EndCoreLane; PortData->PortId = Engine->Type.Port.PortId; PortData->LinkHotplug = Engine->Type.Port.PortData.LinkHotplug; PortData->PciDev = (UINT8) Engine->Type.Port.Address.Address.Device; PortData->PciFun = (UINT8) Engine->Type.Port.Address.Address.Function; } else { PortData->PciePortMaxSpeed = PcieGen1; PortData->PciePortCurSpeed = PcieGen1; PortData->PciePortDcSpeed = PcieGen1; PortData->PciePortAcSpeed = PcieGen1; PortData->PcieLocalOverrideSpeed = PcieGen1; } }
/** * 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; }
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"); }
VOID STATIC PcieClkPmPortInitCallback ( IN PCIe_ENGINE_CONFIG *Engine, IN OUT VOID *Buffer, IN PCIe_PLATFORM_CONFIG *Pcie ) { if (Engine->Type.Port.PortData.MiscControls.ClkPmSupport == 0x1 && !PcieConfigIsSbPcieEngine (Engine) && PcieConfigCheckPortStatus (Engine, INIT_STATUS_PCIE_TRAINING_SUCCESS)) { PcieClkPmPortInitConfigure ( Engine->Type.Port.Address, GnbLibGetHeader (Pcie) ); } }
VOID STATIC PcieAspmPortInitCallback ( IN PCIe_ENGINE_CONFIG *Engine, IN OUT VOID *Buffer, IN PCIe_PLATFORM_CONFIG *Pcie ) { if (Engine->Type.Port.PortData.LinkAspm != AspmDisabled && !PcieConfigIsSbPcieEngine (Engine) && PcieConfigCheckPortStatus (Engine, INIT_STATUS_PCIE_TRAINING_SUCCESS)) { excel950_fun2 ( Engine->Type.Port.Address, Engine->Type.Port.PortData.LinkAspm, GnbLibGetHeader (Pcie) ); } }
VOID STATIC PcieCommClkCfgPortInitCallback ( IN PCIe_ENGINE_CONFIG *Engine, IN OUT VOID *Buffer, IN PCIe_PLATFORM_CONFIG *Pcie ) { PCI_ADDR DownstreamPort; PCIE_COMM_CLK_DATA PcieCommClkData; PcieCommClkData.ScanData.StdHeader = GnbLibGetHeader (Pcie); PcieCommClkData.ScanData.GnbScanCallback = PcieCommClkCfgCallback; DownstreamPort = Engine->Type.Port.Address; if (!PcieConfigIsSbPcieEngine (Engine) && PcieConfigCheckPortStatus (Engine, INIT_STATUS_PCIE_TRAINING_SUCCESS)) { GnbLibPciScan (DownstreamPort, DownstreamPort, &PcieCommClkData.ScanData); } }
/** * Set state for all engines connected to same reset ID * * * * @param[in] Engine Pointer to engine config descriptor * @param[in, out] Buffer Pointer to Reset Id * @param[in] Pcie Pointer to global PCIe configuration * */ VOID PcieSetResetStateOnEnginesV2 ( IN PCIe_ENGINE_CONFIG *Engine, IN OUT VOID *Buffer, IN PCIe_PLATFORM_CONFIG *Pcie ) { UINT8 ResetId; ResetId = *(UINT8 *)Buffer; if (Engine->Type.Port.PortData.ResetId == ResetId && !PcieConfigIsSbPcieEngine (Engine)) { PcieTrainingSetPortStateV2 (Engine, LinkStateResetDuration, TRUE, Pcie); GnbLibPciRMW ( Engine->Type.Port.Address.AddressValue | DxFxx68_ADDRESS, AccessWidth32, (UINT32) ~DxFxx68_LinkDis_MASK, 1 << DxFxx68_LinkDis_OFFSET, GnbLibGetHeader (Pcie) ); } }
VOID STATIC PcieEarlyPortInitCallbackTN ( IN PCIe_ENGINE_CONFIG *Engine, IN OUT VOID *Buffer, IN PCIe_PLATFORM_CONFIG *Pcie ) { IDS_HDT_CONSOLE (GNB_TRACE, "PcieEarlyPortInitCallbackTN Enter\n"); ASSERT (Engine->EngineData.EngineType == PciePortEngine); PciePortProgramRegisterTable (PortInitEarlyTableTN.Table, PortInitEarlyTableTN.Length, Engine, FALSE, Pcie); PcieSetLinkSpeedCapV4 (PcieGen1, Engine, Pcie); PcieSetLinkWidthCap (Engine, Pcie); PcieCompletionTimeout (Engine, Pcie); PcieLinkSetSlotCap (Engine, Pcie); PcieLinkInitHotplug (Engine, Pcie); if (Engine->Type.Port.PortData.PortPresent == PortDisabled || (Engine->Type.Port.PortData.EndpointStatus == EndpointNotPresent && Engine->Type.Port.PortData.LinkHotplug != HotplugEnhanced && Engine->Type.Port.PortData.LinkHotplug != HotplugServer)) { ASSERT (!PcieConfigIsSbPcieEngine (Engine)); // // Pass endpoint status in scratch // PciePortRegisterRMW ( Engine, DxF0xE4_x01_ADDRESS, 0x1, 0x1, FALSE, Pcie ); PcieTrainingSetPortStateV1 (Engine, LinkStateDeviceNotPresent, FALSE, Pcie); } if (Engine->Type.Port.PortData.MiscControls.LinkComplianceMode == 0x1) { PcieTrainingSetPortStateV1 (Engine, LinkStateTrainingCompleted, FALSE, Pcie); } IDS_HDT_CONSOLE (GNB_TRACE, "PcieEarlyPortInitCallbackTN Exit\n"); }
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"); }
/** * Set current link speed * * * @param[in] LinkSpeedCapability Link Speed Capability * @param[in] Engine Pointer to engine configuration descriptor * @param[in] Pcie Pointer to global PCIe configuration * */ VOID PcieSetLinkSpeedCapV4 ( IN PCIE_LINK_SPEED_CAP LinkSpeedCapability, IN PCIe_ENGINE_CONFIG *Engine, IN PCIe_PLATFORM_CONFIG *Pcie ) { DxF0xE4_xA4_STRUCT DxF0xE4_xA4; DxF0xE4_xC0_STRUCT DxF0xE4_xC0; DxF0x88_STRUCT DxF0x88; GnbLibPciRead ( Engine->Type.Port.Address.AddressValue | DxF0x88_ADDRESS, AccessWidth32, &DxF0x88.Value, GnbLibGetHeader (Pcie) ); DxF0xE4_xA4.Value = PciePortRegisterRead ( Engine, DxF0xE4_xA4_ADDRESS, Pcie ); DxF0xE4_xC0.Value = PciePortRegisterRead ( Engine, DxF0xE4_xC0_ADDRESS, Pcie ); switch (LinkSpeedCapability) { case PcieGen3: DxF0xE4_xA4.Field.LcGen2EnStrap = 0x1; DxF0xE4_xA4.Field.LcGen3EnStrap = 0x1; DxF0xE4_xA4.Field.LcMultUpstreamAutoSpdChngEn = 0x1; DxF0x88.Field.TargetLinkSpeed = 0x3; DxF0x88.Field.HwAutonomousSpeedDisable = 0x0; PciePortRegisterRMW ( Engine, DxF0xE4_xA2_ADDRESS, DxF0xE4_xA2_LcDynLanesPwrState_MASK, (2 << DxF0xE4_xA2_LcDynLanesPwrState_OFFSET), FALSE, Pcie ); break; case PcieGen2: DxF0xE4_xA4.Field.LcGen2EnStrap = 0x1; DxF0xE4_xA4.Field.LcMultUpstreamAutoSpdChngEn = 0x1; DxF0x88.Field.TargetLinkSpeed = 0x2; DxF0x88.Field.HwAutonomousSpeedDisable = 0x0; break; case PcieGen1: DxF0xE4_xA4.Field.LcGen2EnStrap = 0x0; DxF0xE4_xA4.Field.LcMultUpstreamAutoSpdChngEn = 0x0; DxF0x88.Field.TargetLinkSpeed = 0x1; DxF0x88.Field.HwAutonomousSpeedDisable = 0x1; PcieRegisterWriteField ( PcieConfigGetParentWrapper (Engine), WRAP_SPACE (PcieConfigGetParentWrapper (Engine)->WrapId, D0F0xE4_WRAP_0803_ADDRESS + 0x100 * Engine->Type.Port.PortId), D0F0xE4_WRAP_0803_StrapBifDeemphasisSel_OFFSET, D0F0xE4_WRAP_0803_StrapBifDeemphasisSel_WIDTH, 0, FALSE, Pcie ); break; default: ASSERT (FALSE); break; } if ((Pcie->PsppPolicy == PsppDisabled) || (PcieConfigIsSbPcieEngine (Engine))) { DxF0xE4_xC0.Field.StrapAutoRcSpeedNegotiationDis = 0x0; } else { DxF0xE4_xC0.Field.StrapAutoRcSpeedNegotiationDis = 0x1; } PciePortRegisterWrite ( Engine, DxF0xE4_xA4_ADDRESS, DxF0xE4_xA4.Value, FALSE, Pcie ); PciePortRegisterWrite ( Engine, DxF0xE4_xC0_ADDRESS, DxF0xE4_xC0.Value, FALSE, Pcie ); GnbLibPciWrite ( Engine->Type.Port.Address.AddressValue | DxF0x88_ADDRESS, AccessWidth32, &DxF0x88.Value, GnbLibGetHeader (Pcie) ); }
VOID PcieEnableSlotPowerLimitV5 ( IN PCIe_ENGINE_CONFIG *Engine, IN PCIe_PLATFORM_CONFIG *Pcie ) { PCIe_SILICON_CONFIG *Silicon; if (PcieLibIsEngineAllocated (Engine) && Engine->Type.Port.PortData.PortPresent != PortDisabled && !PcieConfigIsSbPcieEngine (Engine)) { IDS_HDT_CONSOLE (PCIE_MISC, " Enable Slot Power Limit for Port % d\n", Engine->Type.Port.Address.Address.Device); Silicon = PcieConfigGetParentSilicon (Engine); GnbLibPciIndirectRMW ( Silicon->Address.AddressValue | D0F0xC8_ADDRESS, D0F0xCC_x01_ADDRESS | ((Engine->Type.Port.PortData.DeviceNumber << 3 | Engine->Type.Port.PortData.FunctionNumber) << D0F0xC8_NB_DEV_IND_SEL_OFFSET), AccessS3SaveWidth32, 0xffffffff, 1 << D0F0xCC_x01_SetPowEn_OFFSET, GnbLibGetHeader (Pcie) ); } }
VOID STATIC PcieEarlyPortInitCallbackCZ ( IN PCIe_ENGINE_CONFIG *Engine, IN OUT VOID *Buffer, IN PCIe_PLATFORM_CONFIG *Pcie ) { IDS_HDT_CONSOLE (GNB_TRACE, "PcieEarlyPortInitCallbackCZ Enter\n"); ASSERT (Engine->EngineData.EngineType == PciePortEngine); PciePortProgramRegisterTable (PortInitEarlyTableCZ.Table, PortInitEarlyTableCZ.Length, Engine, FALSE, Pcie); IDS_OPTION_HOOK (IDS_GNB_EQUAL_PRESET, Engine, (AMD_CONFIG_PARAMS *)Pcie->StdHeader); PcieSetLinkSpeedCapV4 (PcieGen1, Engine, Pcie); PcieSetLinkWidthCap (Engine, Pcie); PcieCompletionTimeout (Engine, Pcie); PcieLinkSetSlotCap (Engine, Pcie); PcieLinkInitHotplugCZ (Engine, Pcie); //Move EXTENDED_FMT_SUPPORTED stting from Mid to here. PciePortRegisterRMW ( Engine, DxFxxE4_xC1_ADDRESS, DxFxxE4_xC1_StrapE2EPrefixEn_MASK | DxFxxE4_xC1_StrapExtendedFmtSupported_MASK, (1 << DxFxxE4_xC1_StrapE2EPrefixEn_OFFSET) | (1 << DxFxxE4_xC1_StrapExtendedFmtSupported_OFFSET), FALSE, Pcie ); if (Engine->Type.Port.PortData.PortPresent == PortDisabled || (Engine->Type.Port.PortData.EndpointStatus == EndpointNotPresent && Engine->Type.Port.PortData.LinkHotplug != HotplugEnhanced && Engine->Type.Port.PortData.LinkHotplug != HotplugServer)) { ASSERT (!PcieConfigIsSbPcieEngine (Engine)); // // Pass endpoint status in scratch // PciePortRegisterRMW ( Engine, DxFxxE4_x01_ADDRESS, 0x1, 0x1, FALSE, Pcie ); PcieTrainingSetPortStateV2 (Engine, LinkStateDeviceNotPresent, FALSE, Pcie); } if (PcieConfigIsSbPcieEngine (Engine)) { PcieTrainingSetPortStateV2 (Engine, LinkStateTrainingSuccess, FALSE, Pcie); PcieRegisterWriteField ( PcieConfigGetParentWrapper (Engine), CORE_SPACE (Engine->Type.Port.CoreId, D0F0xE4_CORE_001C_ADDRESS), D0F0xE4_CORE_001C_TX_ATOMIC_OPS_DISABLE_OFFSET, D0F0xE4_CORE_001C_TX_ATOMIC_OPS_DISABLE_WIDTH, 0x1, TRUE, Pcie ); } if (Engine->Type.Port.PortData.MiscControls.LinkComplianceMode == 0x1) { PcieTrainingSetPortStateV2 (Engine, LinkStateTrainingCompleted, FALSE, Pcie); } IDS_OPTION_HOOK (IDS_GNB_GEN1_LOOPBACK, Engine, (AMD_CONFIG_PARAMS *)Pcie->StdHeader); IDS_HDT_CONSOLE (GNB_TRACE, "PcieEarlyPortInitCallbackCZ Exit\n"); }
VOID STATIC GnbIommuMidInitOnPortCallback ( IN PCIe_ENGINE_CONFIG *Engine, IN OUT VOID *Buffer, IN PCIe_PLATFORM_CONFIG *Pcie ) { GNB_TOPOLOGY_INFO TopologyInfo; D0F2xFC_x07_L1_STRUCT D0F2xFC_x07_L1; D0F2xFC_x0D_L1_STRUCT D0F2xFC_x0D_L1; UINT8 L1cfgSel; TopologyInfo.PhantomFunction = FALSE; TopologyInfo.PcieToPciexBridge = FALSE; if (Engine->Type.Port.PortData.LinkHotplug != HotplugDisabled) { TopologyInfo.PhantomFunction = TRUE; TopologyInfo.PcieToPciexBridge = TRUE; } else { if (PcieConfigIsSbPcieEngine (Engine)) { PCI_ADDR StartSbPcieDev; PCI_ADDR EndSbPcieDev; StartSbPcieDev.AddressValue = MAKE_SBDFO (0, 0, 0x15, 0, 0); EndSbPcieDev.AddressValue = MAKE_SBDFO (0, 0, 0x15, 7, 0); GnbGetTopologyInfoV4 (StartSbPcieDev, EndSbPcieDev, &TopologyInfo, GnbLibGetHeader (Pcie)); } else { GnbGetTopologyInfoV4 (Engine->Type.Port.Address, Engine->Type.Port.Address, &TopologyInfo, GnbLibGetHeader (Pcie)); } } L1cfgSel = (Engine->Type.Port.CoreId == 1) ? 1 : 0; if (TopologyInfo.PhantomFunction) { GnbRegisterReadTN ( D0F2xFC_x07_L1_TYPE, D0F2xFC_x07_L1_ADDRESS (L1cfgSel), &D0F2xFC_x07_L1.Value, 0, GnbLibGetHeader (Pcie) ); D0F2xFC_x07_L1.Value |= BIT0; GnbRegisterWriteTN ( D0F2xFC_x07_L1_TYPE, D0F2xFC_x07_L1_ADDRESS (L1cfgSel), &D0F2xFC_x07_L1.Value, GNB_REG_ACC_FLAG_S3SAVE, GnbLibGetHeader (Pcie) ); } if (TopologyInfo.PcieToPciexBridge) { GnbRegisterReadTN ( D0F2xFC_x0D_L1_TYPE, D0F2xFC_x0D_L1_ADDRESS (L1cfgSel), &D0F2xFC_x0D_L1.Value, 0, GnbLibGetHeader (Pcie) ); D0F2xFC_x0D_L1.Field.VOQPortBits = 0x7; GnbRegisterWriteTN ( D0F2xFC_x0D_L1_TYPE, D0F2xFC_x0D_L1_ADDRESS (L1cfgSel), &D0F2xFC_x0D_L1.Value, GNB_REG_ACC_FLAG_S3SAVE, GnbLibGetHeader (Pcie) ); } }
BOOLEAN PcieCheckPortPciDeviceMappingTN ( IN PCIe_PORT_DESCRIPTOR *PortDescriptor, IN PCIe_ENGINE_CONFIG *Engine ) { BOOLEAN Result; if (PortDescriptor->Port.DeviceNumber >= 2 && PortDescriptor->Port.DeviceNumber <= 7 && PortDescriptor->Port.FunctionNumber == 0 && !PcieConfigIsSbPcieEngine (Engine)) { Result = TRUE; } else { Result = FALSE; } return Result; }
AGESA_STATUS PcieMapPortPciAddressTN ( IN PCIe_ENGINE_CONFIG *Engine ) { AGESA_STATUS Status; TN_COMPLEX_CONFIG *ComplexConfig; PCIe_PLATFORM_CONFIG *Pcie; UINT8 PortDevMap[6]; UINT8 FreeDevMap[6]; UINT8 PortIndex; UINT8 EnginePortIndex; UINT8 FreeIndex; D0F0x64_x20_STRUCT D0F0x64_x20; D0F0x64_x21_STRUCT D0F0x64_x21; Status = AGESA_SUCCESS; IDS_HDT_CONSOLE (GNB_TRACE, "PcieMapPortPciAddressTN Enter\n"); if (Engine->Type.Port.PortData.DeviceNumber == 0 && Engine->Type.Port.PortData.FunctionNumber == 0) { Engine->Type.Port.PortData.DeviceNumber = Engine->Type.Port.NativeDevNumber; Engine->Type.Port.PortData.FunctionNumber = Engine->Type.Port.NativeFunNumber; } if (!PcieConfigIsSbPcieEngine (Engine)) { ComplexConfig = (TN_COMPLEX_CONFIG *) PcieConfigGetParent (DESCRIPTOR_SILICON, &Engine->Header); Pcie = (PCIe_PLATFORM_CONFIG *) PcieConfigGetParent (DESCRIPTOR_PLATFORM, &Engine->Header); LibAmdMemFill (&FreeDevMap[0], 0x0, sizeof (FreeDevMap), GnbLibGetHeader (Pcie)); LibAmdMemCopy (&PortDevMap[0], &ComplexConfig->FmSilicon.PortDevMap, sizeof (PortDevMap), GnbLibGetHeader (Pcie)); for (PortIndex = 0; PortIndex < sizeof (PortDevMap); PortIndex++) { if (PortDevMap[PortIndex] != 0) { FreeDevMap[PortDevMap[PortIndex] - 2] = 1; } } EnginePortIndex = Engine->Type.Port.PortData.DeviceNumber - 2; if (FreeDevMap[EnginePortIndex] == 0) { // Dev number not yet allocated ComplexConfig->FmSilicon.PortDevMap[Engine->Type.Port.NativeDevNumber - 2] = Engine->Type.Port.PortData.DeviceNumber; FreeDevMap[EnginePortIndex] = 1; PortDevMap[Engine->Type.Port.NativeDevNumber - 2] = Engine->Type.Port.PortData.DeviceNumber; for (PortIndex = 0; PortIndex < sizeof (PortDevMap); PortIndex++) { if (PortDevMap[PortIndex] == 0) { for (FreeIndex = 0; FreeIndex < sizeof (FreeDevMap); FreeIndex++) { if (FreeDevMap[FreeIndex] == 0) { FreeDevMap[FreeIndex] = 1; break; } } PortDevMap[PortIndex] = FreeIndex + 2; } } GnbRegisterReadTN (D0F0x64_x20_TYPE, D0F0x64_x20_ADDRESS, &D0F0x64_x20, 0, GnbLibGetHeader (Pcie)); D0F0x64_x20.Field.ProgDevMapEn = 0; GnbRegisterWriteTN (D0F0x64_x20_TYPE, D0F0x64_x20_ADDRESS, &D0F0x64_x20, 0, GnbLibGetHeader (Pcie)); GnbRegisterReadTN (D0F0x64_x21_TYPE, D0F0x64_x21_ADDRESS, &D0F0x64_x21, 0, GnbLibGetHeader (Pcie)); D0F0x64_x21.Field.GfxPortADevmap = PortDevMap[2 - 2]; D0F0x64_x21.Field.GfxPortBDevmap = PortDevMap[3 - 2]; D0F0x64_x20.Field.GppPortBDevmap = PortDevMap[4 - 2]; D0F0x64_x20.Field.GppPortCDevmap = PortDevMap[5 - 2]; D0F0x64_x20.Field.GppPortDDevmap = PortDevMap[6 - 2]; D0F0x64_x20.Field.GppPortEDevmap = PortDevMap[7 - 2]; D0F0x64_x20.Field.ProgDevMapEn = 0x1; GnbRegisterWriteTN (D0F0x64_x20_TYPE, D0F0x64_x20_ADDRESS, &D0F0x64_x20, 0, GnbLibGetHeader (Pcie)); GnbRegisterWriteTN (D0F0x64_x21_TYPE, D0F0x64_x21_ADDRESS, &D0F0x64_x21, 0, GnbLibGetHeader (Pcie)); D0F0x64_x20.Field.ProgDevMapEn = 1; GnbRegisterWriteTN (D0F0x64_x20_TYPE, D0F0x64_x20_ADDRESS, &D0F0x64_x20, 0, GnbLibGetHeader (Pcie)); } else { IDS_HDT_CONSOLE (GNB_TRACE, " Fail device %d to port %d\n", Engine->Type.Port.PortData.DeviceNumber, Engine->Type.Port.NativeDevNumber); Status = AGESA_ERROR; } } IDS_HDT_CONSOLE (GNB_TRACE, "PcieMapPortPciAddressTN Exit [0x%x]\n", Status); return Status; }
UINT32 PcieUtilGetEngineLaneBitMap ( IN UINT32 IncludeLaneType, IN UINT32 ExcludeLaneType, IN PCIe_ENGINE_CONFIG *Engine ) { UINT32 LaneBitmap; LaneBitmap = 0; if (IncludeLaneType & LANE_TYPE_PCIE_LANES) { if (IncludeLaneType & LANE_TYPE_PCIE_CORE_CONFIG) { LaneBitmap |= PcieUtilGetPcieEngineLaneBitMap (LaneTypeCore, LanePropertyConfig, Engine); } if (IncludeLaneType & LANE_TYPE_PCIE_CORE_ALLOC) { LaneBitmap |= PcieUtilGetPcieEngineLaneBitMap (LaneTypeCore, LanePropertyAllocated, Engine); } if (IncludeLaneType & (LANE_TYPE_PCIE_CORE_ACTIVE | LANE_TYPE_PCIE_CORE_ALLOC_ACTIVE)) { if (Engine->Type.Port.PortData.LinkHotplug == HotplugEnhanced || PcieConfigCheckPortStatus (Engine, INIT_STATUS_PCIE_PORT_IN_COMPLIANCE)) { LaneBitmap |= PcieUtilGetPcieEngineLaneBitMap (LaneTypeCore, LanePropertyAllocated, Engine); } else if (PcieConfigCheckPortStatus (Engine, INIT_STATUS_PCIE_TRAINING_SUCCESS)) { if (IncludeLaneType & LANE_TYPE_PCIE_CORE_ALLOC_ACTIVE) { LaneBitmap |= PcieUtilGetPcieEngineLaneBitMap (LaneTypeCore, LanePropertyAllocated, Engine); } else { LaneBitmap |= PcieUtilGetPcieEngineLaneBitMap (LaneTypeCore, LanePropertyActive, Engine); } } } if ((IncludeLaneType & LANE_TYPE_PCIE_SB_CORE_CONFIG) && PcieConfigIsSbPcieEngine (Engine)) { LaneBitmap |= PcieUtilGetPcieEngineLaneBitMap (LaneTypeCore, LanePropertyConfig, Engine); } if ((IncludeLaneType & LANE_TYPE_PCIE_CORE_HOTPLUG) && (Engine->Type.Port.PortData.LinkHotplug != HotplugDisabled)) { LaneBitmap |= PcieUtilGetPcieEngineLaneBitMap (LaneTypeCore, LanePropertyAllocated, Engine); } if (IncludeLaneType & LANE_TYPE_PCIE_PHY) { LaneBitmap |= PcieUtilGetPcieEngineLaneBitMap (LaneTypePhy, LanePropertyAllocated, Engine); } if (IncludeLaneType & LANE_TYPE_PCIE_PHY_NATIVE) { LaneBitmap |= PcieUtilGetPcieEngineLaneBitMap (LaneTypeNativePhy, LanePropertyAllocated, Engine); } if (IncludeLaneType & (LANE_TYPE_PCIE_PHY_NATIVE_ACTIVE | LANE_TYPE_PCIE_PHY_NATIVE_ALLOC_ACTIVE)) { if (Engine->Type.Port.PortData.LinkHotplug == HotplugEnhanced || PcieConfigCheckPortStatus (Engine, INIT_STATUS_PCIE_PORT_IN_COMPLIANCE)) { LaneBitmap |= PcieUtilGetPcieEngineLaneBitMap (LaneTypeNativePhy, LanePropertyAllocated, Engine); } else if (PcieConfigCheckPortStatus (Engine, INIT_STATUS_PCIE_TRAINING_SUCCESS)) { if (IncludeLaneType & LANE_TYPE_PCIE_PHY_NATIVE_ALLOC_ACTIVE) { LaneBitmap |= PcieUtilGetPcieEngineLaneBitMap (LaneTypeNativePhy, LanePropertyAllocated, Engine); } else { LaneBitmap |= PcieUtilGetPcieEngineLaneBitMap (LaneTypeNativePhy, LanePropertyActive, Engine); } } } if ((IncludeLaneType & LANE_TYPE_PCIE_PHY_NATIVE_HOTPLUG) && (Engine->Type.Port.PortData.LinkHotplug != HotplugDisabled)) { LaneBitmap |= PcieUtilGetPcieEngineLaneBitMap (LaneTypeNativePhy, LanePropertyAllocated, Engine); } } if (IncludeLaneType & LANE_TYPE_DDI_LANES) { if (IncludeLaneType & LANE_TYPE_DDI_PHY) { LaneBitmap |= PcieUtilGetDdiEngineLaneBitMap (LaneTypePhy, LanePropertyAllocated, Engine); } if (IncludeLaneType & LANE_TYPE_DDI_PHY_NATIVE) { LaneBitmap |= PcieUtilGetDdiEngineLaneBitMap (LaneTypeNativePhy, LanePropertyAllocated, Engine); } if (IncludeLaneType & LANE_TYPE_DDI_PHY_NATIVE_ACTIVE) { LaneBitmap |= PcieUtilGetDdiEngineLaneBitMap (LaneTypeNativePhy, LanePropertyActive, Engine); } } if (ExcludeLaneType != 0) { LaneBitmap &= (~PcieUtilGetEngineLaneBitMap (ExcludeLaneType, 0, Engine)); } return LaneBitmap; }
VOID STATIC PciePostPortInitCallbackML ( IN PCIe_ENGINE_CONFIG *Engine, IN OUT VOID *Buffer, IN PCIe_PLATFORM_CONFIG *Pcie ) { PCIE_LINK_SPEED_CAP LinkSpeedCapability; ASSERT (Engine->EngineData.EngineType == PciePortEngine); if (Engine->Type.Port.PortData.MiscControls.LinkSafeMode == PcieGen1) { PcieLinkSafeMode (Engine, Pcie); } LinkSpeedCapability = PcieFmGetLinkSpeedCap (PCIE_PORT_GEN_CAP_BOOT, Engine); PcieSetLinkSpeedCapV4 (LinkSpeedCapability, Engine, Pcie); if (PcieConfigCheckPortStatus (Engine, INIT_STATUS_PCIE_TRAINING_SUCCESS) && (LinkSpeedCapability > PcieGen1) && !PcieConfigIsSbPcieEngine (Engine)) { PcieTrainingSetPortStateV2 (Engine, LinkStateRetrain, FALSE, Pcie); PcieConfigUpdatePortStatus (Engine, 0, INIT_STATUS_PCIE_TRAINING_SUCCESS); } if (Engine->Type.Port.PortData.MiscControls.LinkComplianceMode == 0x1) { PcieForceCompliance (Engine, Pcie); PcieTrainingSetPortStateV2 (Engine, LinkStateResetExit, FALSE, Pcie); } }
VOID PcieEnableSlotPowerLimit ( IN PCIe_ENGINE_CONFIG *Engine, IN PCIe_PLATFORM_CONFIG *Pcie ) { ASSERT (Engine->EngineData.EngineType == PciePortEngine); if (PcieLibIsEngineAllocated (Engine) && Engine->Type.Port.PortData.PortPresent != PortDisabled && !PcieConfigIsSbPcieEngine (Engine)) { IDS_HDT_CONSOLE (PCIE_MISC, " Enable Slot Power Limit for Port % d\n", Engine->Type.Port.Address.Address.Device); GnbLibPciIndirectRMW ( MAKE_SBDFO (0, 0, 0, 0, D0F0x60_ADDRESS), (D0F0x64_x51_ADDRESS + (Engine->Type.Port.Address.Address.Device - 2) * 2) | IOC_WRITE_ENABLE, AccessS3SaveWidth32, 0xffffffff, 1 << D0F0x64_x51_SetPowEn_OFFSET, GnbLibGetHeader (Pcie) ); } }