/** * Set X & Y value * * * @param[in] X X value * @param[in] Y Y value * @param[in] AddrOffset Offset of address * @param[in] StdHeader Standard configuration header */ VOID GnbBapmSetYAndX ( IN INT32 X, IN INT32 Y, IN UINT32 AddrOffset, IN AMD_CONFIG_PARAMS *StdHeader ) { GnbRegisterWriteTN ( D0F0xBC_x1F480_TYPE, D0F0xBC_x1F480_ADDRESS + AddrOffset, &X, 0, StdHeader ); IDS_HDT_CONSOLE (GNB_TRACE, "X: 0x%08x\n", X); GnbRegisterWriteTN ( D0F0xBC_x1F480_TYPE, D0F0xBC_x1F480_ADDRESS + AddrOffset + 4, &Y, 0, StdHeader ); IDS_HDT_CONSOLE (GNB_TRACE, "Y: 0x%08x\n", Y); }
VOID STATIC GnbCgttOverrideTN ( IN UINT32 Property, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 CGINDx0_Value; UINT32 CGINDx1_Value; GFX_PLATFORM_CONFIG *Gfx; AGESA_STATUS Status; D0F0x64_x23_STRUCT D0F0x64_x23; IDS_HDT_CONSOLE (GNB_TRACE, "GnbCgttOverrideTN Enter\n"); CGINDx0_Value = 0xFFFFFFFF; //When orb clock gating is enabled in the BIOS clear CG_ORB_cgtt_lclk_override - bit 13 CGINDx1_Value = 0xFFFFFFFF; if ((Property & TABLE_PROPERTY_ORB_CLK_GATING) == TABLE_PROPERTY_ORB_CLK_GATING) { CGINDx1_Value &= 0xFFFFDFFF; } //When ioc clock gating is enabled in the BIOS clear CG_IOC_cgtt_lclk_override - bit 15 if ((Property & TABLE_PROPERTY_IOC_LCLK_CLOCK_GATING) == TABLE_PROPERTY_IOC_LCLK_CLOCK_GATING) { CGINDx1_Value &= 0xFFFF7FFF; if ((Property & TABLE_PROPERTY_IOMMU_DISABLED) != TABLE_PROPERTY_IOMMU_DISABLED) { //only IOMMU enabled and IOC clock gating enable GnbRegisterReadTN (D0F0x64_x23_TYPE, D0F0x64_x23_ADDRESS, &D0F0x64_x23.Value, 0, StdHeader); D0F0x64_x23.Field.SoftOverrideClk0 = 1; D0F0x64_x23.Field.SoftOverrideClk1 = 1; D0F0x64_x23.Field.SoftOverrideClk3 = 1; D0F0x64_x23.Field.SoftOverrideClk4 = 1; GnbRegisterWriteTN (D0F0x64_x23_TYPE, D0F0x64_x23_ADDRESS, &D0F0x64_x23.Value, GNB_REG_ACC_FLAG_S3SAVE, StdHeader); } } //When smu sclk clock gating is enabled in the BIOS clear CG_IOC_cgtt_lclk_override - bit 18 if ((Property & TABLE_PROPERTY_SMU_SCLK_CLOCK_GATING) == TABLE_PROPERTY_SMU_SCLK_CLOCK_GATING) { CGINDx1_Value &= 0xFFFBFFFF; } Status = GfxLocateConfigData (StdHeader, &Gfx); if (Status != AGESA_FATAL) { if (Gfx->GmcClockGating) { //In addition to above registers it is necessary to reset override bits for VMC, MCB, and MCD blocks // CGINDx0, clear bit 27, bit 28 CGINDx0_Value &= 0xE7FFFFFF; GnbRegisterWriteTN (TYPE_CGIND, 0x0, &CGINDx0_Value, GNB_REG_ACC_FLAG_S3SAVE, StdHeader); // CGINDx1, clear bit 11 CGINDx1_Value &= 0xFFFFF7FF; } } if (CGINDx1_Value != 0xFFFFFFFF) { GnbRegisterWriteTN (TYPE_CGIND, 0x1, &CGINDx1_Value, GNB_REG_ACC_FLAG_S3SAVE, StdHeader); } IDS_HDT_CONSOLE (GNB_TRACE, "GnbCgttOverrideTN Exit\n"); }
VOID STATIC DdiEarlyPortInitCallbackTN ( IN PCIe_ENGINE_CONFIG *Engine, IN OUT VOID *Buffer, IN PCIe_PLATFORM_CONFIG *Pcie ) { GMMx6464_STRUCT GMMx6464; IDS_HDT_CONSOLE (GNB_TRACE, "DdiEarlyPortInitCallbackTN Enter\n"); if ((Engine->Type.Ddi.DdiData.ConnectorType == ConnectorTypeEDP) || (Engine->Type.Ddi.DdiData.ConnectorType == ConnectorTypeDpToLvds) || (Engine->Type.Ddi.DdiData.ConnectorType == ConnectorTypeEDPToLvds) || (Engine->Type.Ddi.DdiData.ConnectorType == ConnectorTypeEDPToLvdsSwInit)) { IDS_HDT_CONSOLE (GNB_TRACE, "Found eDP/LVDS Connector\n"); GnbRegisterReadTN (GMMx6464_TYPE, GMMx6464_ADDRESS, &GMMx6464.Value, 0, GnbLibGetHeader (Pcie)); GMMx6464.Field.LVTMA_PWRSEQ_EN = 1; GMMx6464.Field.LVTMA_PWRSEQ_TARGET_STATE = 1; GMMx6464.Field.LVTMA_BLON_OVRD = 1; GnbRegisterWriteTN (GMMx6464_TYPE, GMMx6464_ADDRESS, &GMMx6464.Value, 0, GnbLibGetHeader (Pcie)); } IDS_HDT_CONSOLE (GNB_TRACE, "DdiEarlyPortInitCallbackTN Exit\n"); }
STATIC VOID GfxPgfsmRegisterReadTN ( IN UINT32 RegisterAddress, OUT UINT32 *Value, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 RegisterWriteValue; UINT32 RegisterReadValue; RegisterWriteValue = (RegisterAddress << D0F0xBC_xE0300000_RegAddr_OFFSET) + (1 << D0F0xBC_xE0300000_ReadOp_OFFSET) + (0 << D0F0xBC_xE0300000_FsmAddr_OFFSET); IDS_HDT_CONSOLE (GNB_TRACE, "Read PGFSM Register %d\n", RegisterAddress); GnbRegisterWriteTN ( D0F0xBC_xE0300000_TYPE, D0F0xBC_xE0300000_ADDRESS, &RegisterWriteValue, 0, StdHeader); do { GnbRegisterReadTN ( D0F0xBC_xE0300008_TYPE, D0F0xBC_xE0300008_ADDRESS, &RegisterReadValue, 0, StdHeader); } while ((RegisterReadValue & D0F0xBC_xE0300008_ReadValid_MASK) == 0); *Value = RegisterReadValue & D0F0xBC_xE0300008_ReadValue_MASK; }
/** * Enumerate all display connectors with audio capability and configure number of ports * * * * @param[in] Gfx Gfx configuration info */ AGESA_STATUS GfxIntegratedEnumerateAudioConnectors ( IN GFX_PLATFORM_CONFIG *Gfx ) { UINT8 AudioCount; AGESA_STATUS Status; GMMx5F50_STRUCT GMMx5F50; PCIe_PLATFORM_CONFIG *Pcie; IDS_HDT_CONSOLE (GNB_TRACE, "GfxIntegratedEnumerateAudioConnectors Enter\n"); Status = PcieLocateConfigurationData (GnbLibGetHeader (Gfx), &Pcie); if ((Status == AGESA_SUCCESS) && (Gfx->GnbHdAudio != 0)) { AudioCount = 0; PcieConfigRunProcForAllEngines ( DESCRIPTOR_ALLOCATED | DESCRIPTOR_VIRTUAL | DESCRIPTOR_DDI_ENGINE, GfxIntegratedAudioEnumCallback, &AudioCount, Pcie ); if (AudioCount > 4) { AudioCount = 4; } GMMx5F50.Value = 0x00; GMMx5F50.Field.PortConnectivity = (7 - AudioCount); GMMx5F50.Field.PortConnectivityOverrideEnable = 1; GnbRegisterWriteTN (GMMx5F50_TYPE, GMMx5F50_ADDRESS, &GMMx5F50.Value, GNB_REG_ACC_FLAG_S3SAVE, GnbLibGetHeader (Gfx)); } IDS_HDT_CONSOLE (GNB_TRACE, "GfxIntegratedEnumerateAudioConnectors Exit\n"); return Status; }
AGESA_STATUS GfxRequestVoltageTN ( IN UINT8 Vid, IN AMD_CONFIG_PARAMS *StdHeader ) { GMMx770_STRUCT GMMx770; GMMx774_STRUCT GMMx774; IDS_HDT_CONSOLE (GNB_TRACE, "GfxRequestVoltageTN Enter\n"); GnbRegisterReadTN (GMMx770_TYPE, GMMx770_ADDRESS, &GMMx770, 0, StdHeader); GMMx770.Field.VoltageChangeEn = 1; GnbRegisterWriteTN (GMMx770_TYPE, GMMx770_ADDRESS, &GMMx770, GNB_REG_ACC_FLAG_S3SAVE, StdHeader); GMMx770.Field.VoltageLevel = Vid; GMMx770.Field.VoltageChangeReq = ~GMMx770.Field.VoltageChangeReq; GnbRegisterWriteTN (GMMx770_TYPE, GMMx770_ADDRESS, &GMMx770, GNB_REG_ACC_FLAG_S3SAVE, StdHeader); do { GnbRegisterReadTN (GMMx774_TYPE, GMMx774_ADDRESS, &GMMx774, 0, StdHeader); } while (GMMx774.Field.VoltageChangeAck != GMMx770.Field.VoltageChangeReq); IDS_HDT_CONSOLE (GNB_TRACE, "GfxRequestVoltageTN Exit\n"); return AGESA_SUCCESS; }
/** * 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 ); }
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"); }
UINT8 GfxRequestSclkTN ( IN UINT8 Did, IN AMD_CONFIG_PARAMS *StdHeader ) { GMMx600_STRUCT GMMx600; GMMx604_STRUCT GMMx604; UINT8 OriginalDid; do { GnbRegisterReadTN (GMMx604_TYPE, GMMx604_ADDRESS, &GMMx604, 0, StdHeader); } while (GMMx604.Field.SclkStatus == 0); GnbRegisterReadTN (GMMx600_TYPE, GMMx600_ADDRESS, &GMMx600, 0, StdHeader); OriginalDid = (UINT8) GMMx600.Field.IndClkDiv; GMMx600.Field.IndClkDiv = Did; GnbRegisterWriteTN (GMMx600_TYPE, GMMx600_ADDRESS, &GMMx600, 0, StdHeader); do { GnbRegisterReadTN (GMMx604_TYPE, GMMx604_ADDRESS, &GMMx604, 0, StdHeader); } while (GMMx604.Field.SclkStatus == 0); return OriginalDid; }
/** * Family 15h Trinity core 0 entry point for performing the necessary Nb P-state VID adjustment * after a cold reset has occurred. * * @param[in] FamilySpecificServices The current Family Specific Services. * @param[in] CpuEarlyParamsPtr Service parameters * @param[in] StdHeader Config handle for library and services. * */ VOID F15TnNbPstateVidAdjustAfterReset ( IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, IN AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr, IN AMD_CONFIG_PARAMS *StdHeader ) { PCI_ADDR PciAddress; BOOLEAN NeitherHiNorLo; NB_PSTATE_REGISTER NbPsReg; UINT32 NbPsVid; UINT32 i; NB_PSTATE_CTRL_REGISTER NbPsCtrl; NB_PSTATE_CTRL_REGISTER NbPsCtrlSave; NB_PSTATE_STS_REGISTER NbPsSts; CLK_PWR_TIMING_CTRL_5_REGISTER ClkPwrTimgCtrl5; D0F0xBC_x1F400_STRUCT D0F0xBC_x1F400; // Check if D18F5x188[NbOffsetTrim] has been programmed to 01b (-25mV) PciAddress.AddressValue = CPTC5_PCI_ADDR; LibAmdPciRead (AccessWidth32, PciAddress, &ClkPwrTimgCtrl5, StdHeader); if (ClkPwrTimgCtrl5.NbOffsetTrim == 1) { return; } // Add 25mV (-4 VID steps) to all VddNb VIDs. PciAddress.AddressValue = NB_PSTATE_0_PCI_ADDR; for (i = 0; i < NM_NB_PS_REG; i++) { PciAddress.Address.Register = NB_PSTATE_0 + (i * 4); LibAmdPciRead (AccessWidth32, PciAddress, &NbPsReg, StdHeader); if (NbPsReg.NbPstateEn == 1) { NbPsVid = GetF15TnNbVid (&NbPsReg); NbPsVid -= 4; SetF15TnNbVid (&NbPsReg, &NbPsVid); LibAmdPciWrite (AccessWidth32, PciAddress, &NbPsReg, StdHeader); } } // Check if D18F5x174[CurNbPstate] equals NbPstateHi or NbPstateLo PciAddress.Address.Register = NB_PSTATE_STATUS; LibAmdPciRead (AccessWidth32, PciAddress, &NbPsSts, StdHeader); PciAddress.Address.Register = NB_PSTATE_CTRL; LibAmdPciRead (AccessWidth32, PciAddress, &NbPsCtrl, StdHeader); // Save NB P-state control setting NbPsCtrlSave = NbPsCtrl; // Force a NB P-state Transition. NeitherHiNorLo = FALSE; if (NbPsSts.CurNbPstate == NbPsCtrl.NbPstateHi) { TransitionToNbLow (PciAddress, StdHeader); } else if (NbPsSts.CurNbPstate == NbPsCtrl.NbPstateLo) { TransitionToNbHigh (PciAddress, StdHeader); } else { NeitherHiNorLo = TRUE; } // Set OffsetTrim to -25mV: // D18F5x188[NbOffsetTrim]=01b (-25mV) // D0F0xBC_x1F400[SviLoadLineOffsetVddNB]=01b (-25mV) PciAddress.Address.Register = CPTC5_REG; LibAmdPciRead (AccessWidth32, PciAddress, &ClkPwrTimgCtrl5, StdHeader); ClkPwrTimgCtrl5.NbOffsetTrim = 1; LibAmdPciWrite (AccessWidth32, PciAddress, &ClkPwrTimgCtrl5, StdHeader); GnbRegisterReadTN (D0F0xBC_x1F400_TYPE, D0F0xBC_x1F400_ADDRESS, &D0F0xBC_x1F400, 0, StdHeader); D0F0xBC_x1F400.Field.SviLoadLineOffsetVddNB = 1; GnbRegisterWriteTN (D0F0xBC_x1F400_TYPE, D0F0xBC_x1F400_ADDRESS, &D0F0xBC_x1F400, 0, StdHeader); // Unforce NB P-state back to CurNbPstate value upon entry. if (NeitherHiNorLo || (NbPsSts.CurNbPstate == NbPsCtrl.NbPstateHi)) { TransitionToNbHigh (PciAddress, StdHeader); } else { // if (NbPsSts.CurNbPstate == NbPsCtrl.NbPstateLo) TransitionToNbLow (PciAddress, StdHeader); } // Restore NB P-state control setting PciAddress.Address.Register = NB_PSTATE_CTRL; NbPsCtrl = NbPsCtrlSave; LibAmdPciWrite (AccessWidth32, PciAddress, &NbPsCtrl, StdHeader); }
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; }
STATIC AGESA_STATUS GnbLclkDpmInitTN ( IN AMD_CONFIG_PARAMS *StdHeader ) { AGESA_STATUS Status; PCIe_PLATFORM_CONFIG *Pcie; PP_FUSE_ARRAY *PpFuseArray; PCI_ADDR GnbPciAddress; UINT32 Index; UINT8 LclkDpmMode; D0F0xBC_x1F200_STRUCT D0F0xBC_x1F200[NUM_DPM_STATES]; D0F0xBC_x1F208_STRUCT D0F0xBC_x1F208[NUM_DPM_STATES]; D0F0xBC_x1F210_STRUCT D0F0xBC_x1F210[NUM_DPM_STATES]; D0F0xBC_x1F300_STRUCT D0F0xBC_x1F300; ex1003_STRUCT ex1003 [NUM_DPM_STATES]; DOUBLE PcieCacLut; ex1072_STRUCT ex1072 ; D0F0xBC_x1FE00_STRUCT D0F0xBC_x1FE00; D0F0xBC_x1F30C_STRUCT D0F0xBC_x1F30C; D18F3x64_STRUCT D18F3x64; IDS_HDT_CONSOLE (GNB_TRACE, "GnbLclkDpmInitTN Enter\n"); Status = AGESA_SUCCESS; LclkDpmMode = GnbBuildOptions.LclkDpmEn ? LclkDpmRcActivity : LclkDpmDisabled; IDS_OPTION_HOOK (IDS_GNB_LCLK_DPM_EN, &LclkDpmMode, StdHeader); if (LclkDpmMode == LclkDpmRcActivity) { PpFuseArray = GnbLocateHeapBuffer (AMD_PP_FUSE_TABLE_HANDLE, StdHeader); if (PpFuseArray != NULL) { Status = PcieLocateConfigurationData (StdHeader, &Pcie); if (Status == AGESA_SUCCESS) { GnbPciAddress.AddressValue = MAKE_SBDFO (0, 0, 0, 0, 0); //Clear DPM_EN bit in LCLK_DPM_CNTL register //Call BIOS service SMC_MSG_CONFIG_LCLK_DPM to disable LCLK DPM GnbRegisterReadTN (D0F0xBC_x1F300_TYPE, D0F0xBC_x1F300_ADDRESS, &D0F0xBC_x1F300.Value, 0, StdHeader); D0F0xBC_x1F300.Field.LclkDpmEn = 0x0; GnbRegisterWriteTN (D0F0xBC_x1F300_TYPE, D0F0xBC_x1F300_ADDRESS, &D0F0xBC_x1F300.Value, GNB_REG_ACC_FLAG_S3SAVE, StdHeader); GnbSmuServiceRequestV4 ( GnbPciAddress, SMC_MSG_CONFIG_LCLK_DPM, GNB_REG_ACC_FLAG_S3SAVE, StdHeader ); //Initialize LCLK states LibAmdMemFill (D0F0xBC_x1F200, 0x00, sizeof (D0F0xBC_x1F200), StdHeader); LibAmdMemFill (D0F0xBC_x1F208, 0x00, sizeof (D0F0xBC_x1F208), StdHeader); LibAmdMemFill (ex1003, 0x00, sizeof (D0F0xBC_x1F208), StdHeader); D0F0xBC_x1F200[0].Field.LclkDivider = PpFuseArray->LclkDpmDid[0]; D0F0xBC_x1F200[0].Field.VID = PpFuseArray->SclkVid[PpFuseArray->LclkDpmVid[0]]; D0F0xBC_x1F200[0].Field.LowVoltageReqThreshold = 0xa; D0F0xBC_x1F210[0].Field.ActivityThreshold = 0xf; D0F0xBC_x1F200[5].Field.LclkDivider = PpFuseArray->LclkDpmDid[1]; D0F0xBC_x1F200[5].Field.VID = PpFuseArray->SclkVid[PpFuseArray->LclkDpmVid[1]]; D0F0xBC_x1F200[5].Field.LowVoltageReqThreshold = 0xa; D0F0xBC_x1F210[5].Field.ActivityThreshold = 0x32; D0F0xBC_x1F200[5].Field.StateValid = 0x1; D0F0xBC_x1F200[6].Field.LclkDivider = PpFuseArray->LclkDpmDid[2]; D0F0xBC_x1F200[6].Field.VID = PpFuseArray->SclkVid[PpFuseArray->LclkDpmVid[2]]; D0F0xBC_x1F200[6].Field.LowVoltageReqThreshold = 0xa; D0F0xBC_x1F210[6].Field.ActivityThreshold = 0x32; D0F0xBC_x1F200[6].Field.StateValid = 0x1; GnbRegisterReadTN (TYPE_D0F0xBC , 0x1f920 , &ex1072.Value, 0, StdHeader); PcieCacLut = 0.0000057028 * (1 << ex1072.Field.ex1072_0 ); IDS_HDT_CONSOLE (GNB_TRACE, "LCLK DPM1 10khz %x (%d)\n", GfxFmCalculateClock (PpFuseArray->LclkDpmDid[1], StdHeader), GfxFmCalculateClock (PpFuseArray->LclkDpmDid[1], StdHeader)); D0F0xBC_x1FE00.Field.Data = (UINT32) GnbFpLibDoubleToInt32 (PcieCacLut * GfxFmCalculateClock (PpFuseArray->LclkDpmDid[1], StdHeader)); GnbRegisterWriteTN (D0F0xBC_x1FE00_TYPE, D0F0xBC_x1FE00_ADDRESS, &D0F0xBC_x1FE00.Value, GNB_REG_ACC_FLAG_S3SAVE, StdHeader); PcieCacLut = 0.00000540239329 * (1 << ex1072.Field.ex1072_0 ); ex1003[6].Field.ex1003_0 = (UINT32) GnbFpLibDoubleToInt32 (PcieCacLut * GfxFmCalculateClock (PpFuseArray->LclkDpmDid[2], StdHeader)); IDS_HDT_CONSOLE (GNB_TRACE, "LCLK DPM2 10khz %x (%d)\n", GfxFmCalculateClock (PpFuseArray->LclkDpmDid[2], StdHeader), GfxFmCalculateClock (PpFuseArray->LclkDpmDid[2], StdHeader)); for (Index = 0; Index < NUM_DPM_STATES; ++Index) { GnbRegisterWriteTN ( D0F0xBC_x1F200_TYPE, D0F0xBC_x1F200_ADDRESS + Index * 0x20, &D0F0xBC_x1F200[Index].Value, GNB_REG_ACC_FLAG_S3SAVE, StdHeader ); GnbRegisterWriteTN ( D0F0xBC_x1F208_TYPE, D0F0xBC_x1F208_ADDRESS + Index * 0x20, &D0F0xBC_x1F208[Index].Value, GNB_REG_ACC_FLAG_S3SAVE, StdHeader ); GnbRegisterWriteTN ( D0F0xBC_x1F210_TYPE, D0F0xBC_x1F210_ADDRESS + Index * 0x20, &D0F0xBC_x1F210[Index].Value, GNB_REG_ACC_FLAG_S3SAVE, StdHeader ); GnbRegisterWriteTN ( TYPE_D0F0xBC , 0x1f940 + Index * 4, &ex1003[Index].Value, GNB_REG_ACC_FLAG_S3SAVE, StdHeader ); } //Enable LCLK DPM Voltage Scaling GnbRegisterReadTN (D0F0xBC_x1F300_TYPE, D0F0xBC_x1F300_ADDRESS, &D0F0xBC_x1F300.Value, 0, StdHeader); D0F0xBC_x1F300.Field.VoltageChgEn = 0x1; D0F0xBC_x1F300.Field.LclkDpmEn = 0x1; D0F0xBC_x1F300.Field.LclkDpmBootState = 0x5; GnbRegisterWriteTN (D0F0xBC_x1F300_TYPE, D0F0xBC_x1F300_ADDRESS, &D0F0xBC_x1F300.Value, GNB_REG_ACC_FLAG_S3SAVE, StdHeader); //Programming Lclk Thermal Throttling Threshold GnbRegisterReadTN (D18F3x64_TYPE, D18F3x64_ADDRESS, &D18F3x64.Value, 0, StdHeader); GnbRegisterReadTN (D0F0xBC_x1F30C_TYPE, D0F0xBC_x1F30C_ADDRESS, &D0F0xBC_x1F30C.Value, 0, StdHeader); D0F0xBC_x1F30C.Field.LowThreshold = (UINT16) (((D18F3x64.Field.HtcTmpLmt / 2 + 52) - 1 + 49) * 8); D0F0xBC_x1F30C.Field.HighThreshold = (UINT16) (((D18F3x64.Field.HtcTmpLmt / 2 + 52) + 49) * 8); GnbRegisterWriteTN (D0F0xBC_x1F30C_TYPE, D0F0xBC_x1F30C_ADDRESS, &D0F0xBC_x1F30C.Value, GNB_REG_ACC_FLAG_S3SAVE, StdHeader); GnbSmuServiceRequestV4 ( GnbPciAddress, SMC_MSG_CONFIG_LCLK_DPM, GNB_REG_ACC_FLAG_S3SAVE, StdHeader ); } } else { Status = AGESA_ERROR; } } IDS_HDT_CONSOLE (GNB_TRACE, "GnbLclkDpmInitTN Exit [0x%x]\n", Status); return Status; }
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) ); } }
AGESA_STATUS GnbEnvInterfaceTN ( IN AMD_CONFIG_PARAMS *StdHeader ) { AGESA_STATUS Status; AMD_ENV_PARAMS *EnvParamsPtr; UINT32 Property; GNB_HANDLE *GnbHandle; D18F5x170_STRUCT D18F5x170; D0F0xBC_x1F8DC_STRUCT D0F0xBC_x1F8DC; PP_FUSE_ARRAY *PpFuseArray; IDS_HDT_CONSOLE (GNB_TRACE, "GnbEnvInterfaceTN Enter\n"); Property = TABLE_PROPERTY_DEFAULT; EnvParamsPtr = (AMD_ENV_PARAMS *) StdHeader; GnbHandle = GnbGetHandle (StdHeader); ASSERT (GnbHandle != NULL); GnbLoadFuseTableTN (StdHeader); Status = GnbSetTom (GnbGetHostPciAddress (GnbHandle), StdHeader); GnbOrbDynamicWake (GnbGetHostPciAddress (GnbHandle), StdHeader); GnbClumpUnitIdV4 (GnbHandle, StdHeader); GnbLpcDmaDeadlockPreventionV4 (GnbHandle, StdHeader); Property |= GnbBuildOptionsTN.CfgLoadlineEnable ? TABLE_PROPERTY_LOADLINE_ENABLE : 0; if (!EnvParamsPtr->GnbEnvConfiguration.IommuSupport) { Property |= TABLE_PROPERTY_IOMMU_DISABLED; } else { // Force disable iommu if non-FM2 // PACKAGE_TYPE_FP2 1 // PACKAGE_TYPE_FS1r2 2 // PACKAGE_TYPE_FM2 4 if (LibAmdGetPackageType (StdHeader) != PACKAGE_TYPE_FM2) { EnvParamsPtr->GnbEnvConfiguration.IommuSupport = FALSE; Property |= TABLE_PROPERTY_IOMMU_DISABLED; } else { Property |= GnbBuildOptionsTN.GnbCommonOptions.CfgIommuL1ClockGatingEnable ? TABLE_PROPERTY_IOMMU_L1_CLOCK_GATING : 0; Property |= GnbBuildOptionsTN.GnbCommonOptions.CfgIommuL2ClockGatingEnable ? TABLE_PROPERTY_IOMMU_L2_CLOCK_GATING : 0; } } if (GnbBuildOptionsTN.CfgNbdpmEnable) { GnbRegisterReadTN ( TYPE_D18F5, D18F5x170_ADDRESS, &D18F5x170.Value, 0, StdHeader ); // Check if NbPstate enable if ((D18F5x170.Field.SwNbPstateLoDis != 1) && (D18F5x170.Field.NbPstateMaxVal != 0)) { Property |= TABLE_PROPERTY_NBDPM; PpFuseArray = GnbLocateHeapBuffer (AMD_PP_FUSE_TABLE_HANDLE, StdHeader); if (PpFuseArray != NULL) { // NBDPM is requesting SclkVid0 from the register. // Write them back if SclkVid has been changed in PpFuseArray. GnbRegisterReadTN (D0F0xBC_x1F8DC_TYPE, D0F0xBC_x1F8DC_ADDRESS, &D0F0xBC_x1F8DC.Value, 0, StdHeader); if ((D0F0xBC_x1F8DC.Field.SClkVid0 != PpFuseArray->SclkVid[0]) || (D0F0xBC_x1F8DC.Field.SClkVid1 != PpFuseArray->SclkVid[1]) || (D0F0xBC_x1F8DC.Field.SClkVid2 != PpFuseArray->SclkVid[2]) || (D0F0xBC_x1F8DC.Field.SClkVid3 != PpFuseArray->SclkVid[3])) { D0F0xBC_x1F8DC.Field.SClkVid0 = PpFuseArray->SclkVid[0]; D0F0xBC_x1F8DC.Field.SClkVid1 = PpFuseArray->SclkVid[1]; D0F0xBC_x1F8DC.Field.SClkVid2 = PpFuseArray->SclkVid[2]; D0F0xBC_x1F8DC.Field.SClkVid3 = PpFuseArray->SclkVid[3]; GnbRegisterWriteTN (D0F0xBC_x1F8DC_TYPE, D0F0xBC_x1F8DC_ADDRESS, &D0F0xBC_x1F8DC.Value, GNB_REG_ACC_FLAG_S3SAVE, StdHeader); } } } } IDS_OPTION_HOOK (IDS_GNB_PROPERTY, &Property, StdHeader); Status = GnbProcessTable ( GnbHandle, GnbEnvInitTableTN, Property, GNB_TABLE_FLAGS_FORCE_S3_SAVE, StdHeader ); IDS_HDT_CONSOLE (GNB_TRACE, "GnbEnvInterfaceTN Exit [0x%x]\n", Status); return Status; }