/** * Execute/clean up reconfiguration * * * @param[in] Wrapper Pointer to wrapper config descriptor * @param[in] Pcie Pointer to global PCIe configuration */ VOID PcieTopologyExecuteReconfigV4 ( IN PCIe_WRAPPER_CONFIG *Wrapper, IN PCIe_PLATFORM_CONFIG *Pcie ) { D0F0xE4_WRAP_8062_STRUCT D0F0xE4_WRAP_8062; PCIe_SILICON_CONFIG *Silicon; if (PcieLibIsPcieWrapper (Wrapper)) { IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologyExecuteReconfigV4 Enter\n"); PcieTopologyInitSrbmReset (FALSE, Wrapper, Pcie); D0F0xE4_WRAP_8062.Value = PcieRegisterRead ( Wrapper, WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8062_ADDRESS), Pcie ); D0F0xE4_WRAP_8062.Field.ReconfigureEn = 0x1; PcieRegisterWrite ( Wrapper, WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8062_ADDRESS), D0F0xE4_WRAP_8062.Value, FALSE, Pcie ); Silicon = PcieConfigGetParentSilicon (Wrapper); GnbLibPciIndirectRMW ( Silicon->Address.AddressValue | D0F0xB8_ADDRESS, D0F0xBC_x1F630_ADDRESS, AccessWidth32, (UINT32) ~D0F0xBC_x1F630_RECONF_WRAPPER_MASK, Wrapper->WrapId << D0F0xBC_x1F630_RECONF_WRAPPER_OFFSET, GnbLibGetHeader (Pcie) ); GnbSmuServiceRequestV4 ( Silicon->Address, SMC_MSG_RECONFIGURE, 0, GnbLibGetHeader (Pcie) ); D0F0xE4_WRAP_8062.Field.ConfigXferMode = 0x1; D0F0xE4_WRAP_8062.Field.ReconfigureEn = 0x0; PcieRegisterWrite ( Wrapper, WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8062_ADDRESS), D0F0xE4_WRAP_8062.Value, FALSE, Pcie ); PcieTopologyInitSrbmReset (TRUE, Wrapper, Pcie); IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologyExecuteReconfigV4 Exit\n"); } }
/** * Read PCIe register value. * * Support for unify register access through index/data pair on GNB * * @param[in] Wrapper Pointer to Wrapper descriptor * @param[in] Address Register address * @param[in] Pcie Pointer to global PCIe configuration * @retval Register Value */ UINT32 PcieRegisterRead ( IN PCIe_WRAPPER_CONFIG *Wrapper, IN UINT32 Address, IN PCIe_PLATFORM_CONFIG *Pcie ) { return PcieSiliconRegisterRead (PcieConfigGetParentSilicon (Wrapper), Address, Pcie); }
/** * RX offset cancellation enablement * * * * @param[in] Wrapper Pointer to Wrapper configuration data area * @param[in] Pcie Pointer to PCIe configuration data area */ VOID PcieOffsetCancelCalibration ( IN PCIe_WRAPPER_CONFIG *Wrapper, IN PCIe_PLATFORM_CONFIG *Pcie ) { UINT32 LaneBitmap; D0F0xBC_x1F39C_STRUCT D0F0xBC_x1F39C; LaneBitmap = PcieUtilGetWrapperLaneBitMap (LANE_TYPE_PHY_NATIVE_ALL, LANE_TYPE_PCIE_SB_CORE_CONFIG, Wrapper); if ((Wrapper->WrapId != GFX_WRAP_ID) && (Wrapper->WrapId != GPP_WRAP_ID)) { return; } if (LaneBitmap != 0) { D0F0xBC_x1F39C.Value = 0; D0F0xBC_x1F39C.Field.Tx = 1; D0F0xBC_x1F39C.Field.Rx = 1; D0F0xBC_x1F39C.Field.UpperLaneID = LibAmdBitScanReverse (LaneBitmap) + Wrapper->StartPhyLane; D0F0xBC_x1F39C.Field.LowerLaneID = LibAmdBitScanForward (LaneBitmap) + Wrapper->StartPhyLane; GnbRegisterWriteTN (D0F0xBC_x1F39C_TYPE, D0F0xBC_x1F39C_ADDRESS, &D0F0xBC_x1F39C.Value, GNB_REG_ACC_FLAG_S3SAVE, GnbLibGetHeader (Pcie)); GnbSmuServiceRequestV4 ( PcieConfigGetParentSilicon (Wrapper)->Address, SMC_MSG_PHY_LN_OFF, GNB_REG_ACC_FLAG_S3SAVE, GnbLibGetHeader (Pcie) ); GnbSmuServiceRequestV4 ( PcieConfigGetParentSilicon (Wrapper)->Address, SMC_MSG_PHY_LN_ON, GNB_REG_ACC_FLAG_S3SAVE, GnbLibGetHeader (Pcie) ); } PcieTopologyLaneControl ( EnableLanes, PcieUtilGetWrapperLaneBitMap (LANE_TYPE_ALL, 0, Wrapper), Wrapper, Pcie ); }
/** * Execute/clean up reconfiguration * * * @param[in] Wrapper Pointer to wrapper config descriptor * @param[in] Pcie Pointer to global PCIe configuration */ VOID PcieTopologyExecuteReconfigV5 ( IN PCIe_WRAPPER_CONFIG *Wrapper, IN PCIe_PLATFORM_CONFIG *Pcie ) { D0F0xE4_WRAP_8062_STRUCT D0F0xE4_WRAP_8062; PCIe_SILICON_CONFIG *Silicon; DEV_OBJECT DevObject; if (PcieLibIsPcieWrapper (Wrapper)) { IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologyExecuteReconfigV5 Enter\n"); D0F0xE4_WRAP_8062.Value = PcieRegisterRead ( Wrapper, WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8062_ADDRESS), Pcie ); D0F0xE4_WRAP_8062.Field.ReconfigureEn = 0x1; D0F0xE4_WRAP_8062.Field.ResetPeriod = 0x0; PcieRegisterWrite ( Wrapper, WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8062_ADDRESS), D0F0xE4_WRAP_8062.Value, FALSE, Pcie ); Silicon = PcieConfigGetParentSilicon (Wrapper); DevObject.StdHeader = GnbLibGetHeader (Pcie); DevObject.GnbHandle = GnbGetHandle (GnbLibGetHeader (Pcie)); DevObject.DevPciAddress.AddressValue = Silicon->Address.AddressValue; GnbSmuServiceRequestV7 ( &DevObject, SMC_MSG_RECONFIGURE, Wrapper->WrapId, 0 ); D0F0xE4_WRAP_8062.Field.ConfigXferMode = 0x1; D0F0xE4_WRAP_8062.Field.ReconfigureEn = 0x0; PcieRegisterWrite ( Wrapper, WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8062_ADDRESS), D0F0xE4_WRAP_8062.Value, FALSE, Pcie ); IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologyExecuteReconfigV5 Exit\n"); } }
/** * Write PCIe register value. * * Support for unify register access through index/data pair on GNB * * @param[in] Wrapper Pointer to wrapper descriptor * @param[in] Address Register address * @param[in] Value New register value * @param[in] S3Save Save register for S3 (True/False) * @param[in] Pcie Pointer to global PCIe configuration */ VOID PcieRegisterWrite ( IN PCIe_WRAPPER_CONFIG *Wrapper, IN UINT32 Address, IN UINT32 Value, IN BOOLEAN S3Save, IN PCIe_PLATFORM_CONFIG *Pcie ) { PcieSiliconRegisterWrite ( PcieConfigGetParentSilicon (Wrapper), Address, Value, S3Save, Pcie ); }
AGESA_STATUS PcieMapPortPciAddressML ( IN PCIe_ENGINE_CONFIG *Engine ) { AGESA_STATUS Status; ML_COMPLEX_CONFIG *ComplexConfig; PCIe_COMPLEX_CONFIG *Complex; PCIe_PLATFORM_CONFIG *Pcie; UINT8 DevFunc; UINT8 Index; Status = AGESA_SUCCESS; IDS_HDT_CONSOLE (GNB_TRACE, "PcieMapPortPciAddressML Enter\n"); Complex = (PCIe_COMPLEX_CONFIG *) PcieConfigGetParent (DESCRIPTOR_COMPLEX, &Engine->Header); Pcie = (PCIe_PLATFORM_CONFIG *) PcieConfigGetParent (DESCRIPTOR_PLATFORM, &Complex->Header); 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; } ComplexConfig = (ML_COMPLEX_CONFIG *) PcieConfigGetParentSilicon (Engine); IDS_OPTION_HOOK (IDS_GNB_PCIE_PORT_REMAP, &Engine->Type.Port, GnbLibGetHeader (Pcie)); DevFunc = (Engine->Type.Port.PortData.DeviceNumber << 3) | Engine->Type.Port.PortData.FunctionNumber; for (Index = 0; Index < sizeof (ComplexConfig->FmSilicon.PortDevMap); ++Index) { if (ComplexConfig->FmSilicon.PortDevMap[Index] == DevFunc) { Status = AGESA_ERROR; break; } } if (Status == AGESA_SUCCESS) { ComplexConfig->FmSilicon.PortDevMap[Engine->Type.Port.PcieBridgeId] = DevFunc; } for (Index = 0; Index < sizeof (DefaultPortDevMapML); ++Index) { if (DevFunc == DefaultPortDevMapML[Index]) { Engine->Type.Port.LogicalBridgeId = Index; // Get the configuration from the table or from "auto settings" if (Engine->Type.Port.PortData.ApicDeviceInfo.GroupMap == 0x00) { // If Group is 0, use "Auto" settings Engine->Type.Port.PortData.ApicDeviceInfo = DefaultIoapicConfigML[Index]; } break; } } IDS_HDT_CONSOLE (GNB_TRACE, "PcieMapPortPciAddressML Exit [0x%x]\n", Status); return Status; }
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 PcieMidPortInitCallbackKV ( IN PCIe_ENGINE_CONFIG *Engine, IN OUT VOID *Buffer, IN PCIe_PLATFORM_CONFIG *Pcie ) { DxFxx68_STRUCT DxFxx68; D0F0xE4_PIF_0012_STRUCT D0F0xE4_PIF_0012; PCIe_SUBLINK_INFO *SublinkInfo; PCIe_WRAPPER_INFO *WrapperInfo; PCIe_WRAPPER_CONFIG *Wrapper; CPU_LOGICAL_ID LogicalId; UINT8 Count; UINT8 Nibble; PciePortProgramRegisterTable (PortInitMidTableKV.Table, PortInitMidTableKV.Length, Engine, TRUE, Pcie); if (PcieConfigCheckPortStatus (Engine, INIT_STATUS_PCIE_TRAINING_SUCCESS) || Engine->Type.Port.PortData.LinkHotplug != HotplugDisabled) { PcieEnableSlotPowerLimitV5 (Engine, Pcie); if (GnbFmCheckIommuPresent ((GNB_HANDLE*) PcieConfigGetParentSilicon (Engine), GnbLibGetHeader (Pcie))) { PcieInitPortForIommuV4 (Engine, Pcie); } // After GFX link is trained up and before ASPM is enabled, AGESA needs to check link width, // if it equals to x16, then apply the following change to GFX port: // Per port register 0xA1 - PCIE LC TRAINING CONTROL, bit16 - LC_EXTEND_WAIT_FOR_SKP = 1 GnbLibPciRead ( Engine->Type.Port.Address.AddressValue | DxFxx68_ADDRESS, AccessWidth32, &DxFxx68, GnbLibGetHeader (Pcie) ); if (DxFxx68.Field.NegotiatedLinkWidth == 16) { PciePortRegisterRMW ( Engine, DxFxxE4_xA1_ADDRESS, DxFxxE4_xA1_LcExtendWaitForSkp_MASK, (1 << DxFxxE4_xA1_LcExtendWaitForSkp_OFFSET), TRUE, Pcie ); } } Wrapper = PcieConfigGetParentWrapper (Engine); SublinkInfo = &(((PCIe_INFO_BUFFER *)Buffer)->SublinkInfo[MIN (Engine->EngineData.StartLane, Engine->EngineData.EndLane) / 4]); WrapperInfo = &(((PCIe_INFO_BUFFER *)Buffer)->WrapperInfo[Wrapper->WrapId]); GetLogicalIdOfCurrentCore (&LogicalId, (AMD_CONFIG_PARAMS *)Pcie->StdHeader); // Check if this CPU is KV A0 // UBTS468566 if ((LogicalId.Revision & AMD_F15_KV_A0) != 0) { Count = SublinkInfo->GppPortCount; IDS_HDT_CONSOLE (GNB_TRACE, "x1x2 PortCount = %02x\n", Count); if (Count == 2) { // If number of GPP ports under the same sublink is 2, Delay L1 Exit (prolong minimum time spent in L1) PciePortRegisterRMW ( Engine, DxFxxE4_xA0_ADDRESS, DxFxxE4_xA0_LcDelayCount_MASK | DxFxxE4_xA0_LcDelayL1Exit_MASK, (0 << DxFxxE4_xA0_LcDelayCount_OFFSET) | (1 << DxFxxE4_xA0_LcDelayL1Exit_OFFSET), TRUE, Pcie ); } else if (Count > 2) { // If number of GPP ports > 2 if (SublinkInfo->MaxGenCapability > Gen1) { // If at least 1 GPP is Gen2 capable, Disable PLL Power down feature Wrapper = PcieConfigGetParentWrapper (Engine); Nibble = (UINT8) ((MIN (Engine->EngineData.StartLane, Engine->EngineData.EndLane) % 8) / 4); // Only PSD and PPD can have x1/x2 links, so we assume that PIF number is always 0 D0F0xE4_PIF_0012.Value = PcieRegisterRead ( Wrapper, PIF_SPACE (Wrapper->WrapId, 0, D0F0xE4_PIF_0012_ADDRESS + Nibble), Pcie ); D0F0xE4_PIF_0012.Field.PllPowerStateInOff = PifPowerStateL0; D0F0xE4_PIF_0012.Field.PllPowerStateInTxs2 = PifPowerStateL0; PcieRegisterWrite ( Wrapper, PIF_SPACE (Wrapper->WrapId, 0, D0F0xE4_PIF_0012_ADDRESS + Nibble), D0F0xE4_PIF_0012.Value, TRUE, Pcie ); } else { // All ports are only Gen1 PciePortRegisterRMW ( Engine, DxFxxE4_xC0_ADDRESS, DxFxxE4_xC0_StrapMedyTSxCount_MASK, 0x2 << DxFxxE4_xC0_StrapMedyTSxCount_OFFSET, TRUE, Pcie ); } } } PcieRegisterRMW ( Wrapper, WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_0802_ADDRESS + (0x100 * Engine->Type.Port.PortId)), D0F0xE4_WRAP_0802_StrapBifL1ExitLatency_MASK, (WrapperInfo->L1ExitLatencyValue << D0F0xE4_WRAP_0802_StrapBifL1ExitLatency_OFFSET), TRUE, Pcie ); if (WrapperInfo->DisableL1OnWrapper == TRUE) { Engine->Type.Port.PortData.LinkAspm &= ~(AspmL1); } PcieEnableAspm (Engine, Pcie); }
/** * Execute/clean up reconfiguration * * * @param[in] Wrapper Pointer to wrapper config descriptor * @param[in] Pcie Pointer to global PCIe configuration */ VOID STATIC PcieTopologyExecuteReconfigCZ ( IN PCIe_WRAPPER_CONFIG *Wrapper, IN PCIe_PLATFORM_CONFIG *Pcie ) { D0F0xE4_CORE_0101_STRUCT D0F0xE4_CORE_0101; PCIe_SILICON_CONFIG *Silicon; DEV_OBJECT DevObject; UINT32 SmuArg[6]; if (PcieLibIsPcieWrapper (Wrapper)) { IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologyExecuteReconfigCZ Enter\n"); D0F0xE4_CORE_0101.Value = PcieRegisterRead ( Wrapper, CORE_SPACE (Wrapper->StartPcieCoreId, D0F0xE4_CORE_0101_ADDRESS), Pcie ); D0F0xE4_CORE_0101.Field.RECONFIGURE_EN = 0x1; D0F0xE4_CORE_0101.Field.RESET_PERIOD = 0x2; PcieRegisterWrite ( Wrapper, CORE_SPACE (Wrapper->StartPcieCoreId, D0F0xE4_CORE_0101_ADDRESS), D0F0xE4_CORE_0101.Value, FALSE, Pcie ); Silicon = PcieConfigGetParentSilicon (Wrapper); DevObject.StdHeader = GnbLibGetHeader (Pcie); DevObject.GnbHandle = GnbGetHandle (GnbLibGetHeader (Pcie)); DevObject.DevPciAddress.AddressValue = Silicon->Address.AddressValue; LibAmdMemFill (SmuArg, 0x00, sizeof (SmuArg), GnbLibGetHeader (Pcie)); SmuArg [0] = Wrapper->WrapId; GnbSmuServiceRequestV8 ( &DevObject, SMC_MSG_RECONFIGURE_SB, SmuArg, 0 ); D0F0xE4_CORE_0101.Value = PcieRegisterRead ( Wrapper, CORE_SPACE (Wrapper->StartPcieCoreId, D0F0xE4_CORE_0101_ADDRESS), Pcie ); D0F0xE4_CORE_0101.Field.RECONFIGURE_EN = 0x0; PcieRegisterWrite ( Wrapper, CORE_SPACE (Wrapper->StartPcieCoreId, D0F0xE4_CORE_0101_ADDRESS), D0F0xE4_CORE_0101.Value, FALSE, Pcie ); IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologyExecuteReconfigCZ Exit\n"); } }