STATIC VOID GfxFillNbPstateMemclkFreqTN ( IN OUT ATOM_INTEGRATED_SYSTEM_INFO_V1_7 *IntegratedInfoTable, IN GFX_PLATFORM_CONFIG *Gfx ) { D18F2x94_dct0_STRUCT D18F2x94; D18F2x2E0_dct0_STRUCT D18F2x2E0; D18F5x160_STRUCT NbPstate; UINT8 i; UINT8 Channel; ULONG memps0_freq; ULONG memps1_freq; if ((Gfx->UmaInfo.UmaAttributes & UMA_ATTRIBUTE_ON_DCT0) != 0) { Channel = 0; } else { Channel = 1; } GnbRegisterReadTN ( ((Channel == 0) ? D18F2x94_dct0_TYPE : D18F2x94_dct1_TYPE), ((Channel == 0) ? D18F2x94_dct0_ADDRESS : D18F2x94_dct1_ADDRESS), &D18F2x94.Value, 0, GnbLibGetHeader (Gfx) ); GnbRegisterReadTN ( ((Channel == 0) ? D18F2x2E0_dct0_TYPE : D18F2x2E0_dct1_TYPE), ((Channel == 0) ? D18F2x2E0_dct0_ADDRESS : D18F2x2E0_dct1_ADDRESS), &D18F2x2E0.Value, 0, GnbLibGetHeader (Gfx) ); memps0_freq = 100 * GfxLibExtractDramFrequency ((UINT8) D18F2x94.Field.MemClkFreq, GnbLibGetHeader (Gfx)); memps1_freq = 100 * GfxLibExtractDramFrequency ((UINT8) D18F2x2E0.Field.M1MemClkFreq, GnbLibGetHeader (Gfx)); for (i = 0; i < 4; i++) { NbPstate.Value = 0; GnbRegisterReadTN ( TYPE_D18F5, (D18F5x160_ADDRESS + (i * 4)), &NbPstate.Value, 0, GnbLibGetHeader (Gfx) ); if (NbPstate.Field.NbPstateEn == 1) { IntegratedInfoTable->ulNbpStateMemclkFreq[i] = (NbPstate.Field.MemPstate == 0) ? memps0_freq : memps1_freq; } } }
STATIC VOID GfxFillNbPStateVidTN ( IN OUT ATOM_INTEGRATED_SYSTEM_INFO_V1_7 *IntegratedInfoTable, IN GFX_PLATFORM_CONFIG *Gfx ) { //TN Register Mapping for D18F5x1[6C:60] D18F5x160_STRUCT NbPstate[4]; D0F0xBC_x1F428_STRUCT D0F0xBC_x1F428; UINT8 MinNclkIndex; UINT8 i; MinNclkIndex = 0; IntegratedInfoTable->ucNBDPMEnable = 0; GnbRegisterReadTN ( D0F0xBC_x1F428_TYPE, D0F0xBC_x1F428_ADDRESS, &D0F0xBC_x1F428.Value, 0, GnbLibGetHeader (Gfx) ); // Check if NbPstate enbale if (D0F0xBC_x1F428.Field.EnableNbDpm == 1) { //1: enable 0: not enable IntegratedInfoTable->ucNBDPMEnable = 1; } for (i = 0; i < 4; i++) { GnbRegisterReadTN ( TYPE_D18F5, (D18F5x160_ADDRESS + (i * 4)), &NbPstate[i].Value, 0, GnbLibGetHeader (Gfx) ); if (NbPstate[i].Field.NbPstateEn == 1) { MinNclkIndex = i; } IntegratedInfoTable->ulNbpStateNClkFreq[i] = GfxLibGetNclkTN ((UINT8) NbPstate[i].Field.NbFid, (UINT8) NbPstate[i].Field.NbDid); } IntegratedInfoTable->usNBP0Voltage = (USHORT) ((NbPstate[0].Field.NbVid_7_ << 7) | NbPstate[0].Field.NbVid_6_0_); IntegratedInfoTable->usNBP1Voltage = (USHORT) ((NbPstate[1].Field.NbVid_7_ << 7) | NbPstate[1].Field.NbVid_6_0_); IntegratedInfoTable->usNBP2Voltage = (USHORT) ((NbPstate[2].Field.NbVid_7_ << 7) | NbPstate[2].Field.NbVid_6_0_); IntegratedInfoTable->usNBP3Voltage = (USHORT) ((NbPstate[3].Field.NbVid_7_ << 7) | NbPstate[3].Field.NbVid_6_0_); IntegratedInfoTable->ulMinimumNClk = GfxLibGetNclkTN ((UINT8) NbPstate[MinNclkIndex].Field.NbFid, (UINT8) NbPstate[MinNclkIndex].Field.NbDid); }
VOID GfxIntInfoTableInitTDPConfigTN ( IN ATOM_INTEGRATED_SYSTEM_INFO_V1_7 *IntegratedInfoTable, IN GFX_PLATFORM_CONFIG *Gfx ) { D0F0xBC_x1F758_STRUCT D0F0xBC_x1F758; // Read cTDP_CONFIG register GnbRegisterReadTN ( D0F0xBC_x1F758_TYPE, D0F0xBC_x1F758_ADDRESS, &D0F0xBC_x1F758.Value, 0, GnbLibGetHeader (Gfx) ); // Values in register are watts Q8.8 encoded // Need to convert to mW*10 // mW*10 = watts * 100 / 256 IntegratedInfoTable->asTdpConfig.TDP_config.uCTDP_Value = D0F0xBC_x1F758.Field.TargetTdp * 100 / 256; IntegratedInfoTable->asTdpConfig.TDP_config.uTDP_Value = D0F0xBC_x1F758.Field.SocketTdp * 100 / 256; if (D0F0xBC_x1F758.Field.TargetTdp > D0F0xBC_x1F758.Field.SocketTdp) { IntegratedInfoTable->asTdpConfig.TDP_config.uCTDP_Enable = 2; } else if (D0F0xBC_x1F758.Field.TargetTdp < D0F0xBC_x1F758.Field.SocketTdp) { IntegratedInfoTable->asTdpConfig.TDP_config.uCTDP_Enable = 1; } else { IntegratedInfoTable->asTdpConfig.TDP_config.uCTDP_Enable = 0; } }
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; }
AGESA_STATUS PcieFP2CriteriaTN ( IN PCIe_PLATFORM_CONFIG *Pcie ) { AGESA_STATUS Status; D18F3x1FC_STRUCT D18F3x1FC; IDS_HDT_CONSOLE (GNB_TRACE, "PcieFP2CriteriaTN Enter\n"); // PACKAGE_TYPE_FP2 1 // PACKAGE_TYPE_FS1r2 2 // PACKAGE_TYPE_FM2 4 if (LibAmdGetPackageType (GnbLibGetHeader (Pcie)) != PACKAGE_TYPE_FP2) { return AGESA_SUCCESS; } GnbRegisterReadTN (D18F3x1FC_TYPE, D18F3x1FC_ADDRESS, &D18F3x1FC.Value, 0, GnbLibGetHeader (Pcie)); // FP2 processor link supports Gen2 mode if (D18F3x1FC.Field.Fp2PcieGen2Sup == 1) { return AGESA_SUCCESS; } // FP2 force gen1 Pcie->PsppPolicy = PsppPowerSaving; // FP2 only use x8 on the same PHY Status = PcieConfigRunProcForAllWrappers (DESCRIPTOR_ALL_WRAPPERS, PcieFP2x8CheckCallbackTN, NULL, Pcie); IDS_HDT_CONSOLE (GNB_TRACE, "PcieFP2CriteriaTN Exit\n"); return Status; }
/** * Get max SCLK * * * @param[in] StdHeader Standard configuration header * @retval Max SCLK in Mhz */ UINT32 GfxLibGetMaxSclk ( IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 MaxSclkClk; D0F0xBC_xFF000000_STRUCT D0F0xBC_xFF000000; D0F0xBC_xE0003048_STRUCT D0F0xBC_xE0003048; GnbRegisterReadTN (TYPE_D0F0xBC, D0F0xBC_xFF000000_ADDRESS, &D0F0xBC_xFF000000.Value, 0, StdHeader); GnbRegisterReadTN (TYPE_D0F0xBC, D0F0xBC_xE0003048_ADDRESS, &D0F0xBC_xE0003048.Value, 0, StdHeader); //sclk_max_freq = 100 * (GCLK_PLL_FUSES.MainPllOptFreqIdStartup + 16) / // (((SCLK_MIN_DIV.INT<<12 + SCLK_MIN_DIV.FRAC)>>12) MaxSclkClk = 100 * (D0F0xBC_xFF000000.Field.MainPllOpFreqIdStartup + 16); MaxSclkClk /= ((D0F0xBC_xE0003048.Field.Intv << 12) + D0F0xBC_xE0003048.Field.Fracv) >> 12; return MaxSclkClk; }
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"); }
/** * Get system PLL COF * * * * @param[in] StdHeader Standard configuration header * @retval System PLL COF */ UINT32 GfxLibGetSytemPllCofTN ( IN AMD_CONFIG_PARAMS *StdHeader ) { D0F0xBC_xFF000000_STRUCT D0F0xBC_xFF000000; GnbRegisterReadTN (D0F0xBC_xFF000000_TYPE, D0F0xBC_xFF000000_ADDRESS, &D0F0xBC_xFF000000.Value, 0, StdHeader); return 100 * (D0F0xBC_xFF000000.Field.MainPllOpFreqIdStartup + 0x10); }
BOOLEAN GfxFmIsVbiosPosted ( IN GFX_PLATFORM_CONFIG *Gfx ) { UINT32 Value; GnbRegisterReadTN (GMMx670_TYPE, GMMx670_ADDRESS, &Value, 0, GnbLibGetHeader (Gfx)); return ((Value & BIT16) == 0) ? TRUE : FALSE; }
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; }
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; }
/** * Get TN disable DLL shutdown in self-refresh mode. * * * @param[in] Channel DCT controller index * @param[in] StdHeader Standard configuration header * @retval DisDllShutdownSR */ STATIC UINT32 GfxLibGetDisDllShutdownSRTN ( IN UINT8 Channel, IN AMD_CONFIG_PARAMS *StdHeader ) { D18F2x90_dct0_STRUCT D18F2x90; GnbRegisterReadTN ( ((Channel == 0) ? D18F2x90_dct0_TYPE : D18F2x90_dct1_TYPE), ((Channel == 0) ? D18F2x90_dct0_ADDRESS : D18F2x90_dct1_ADDRESS), &D18F2x90.Value, 0, StdHeader ); IDS_HDT_CONSOLE (GNB_TRACE, "DisDllShutdownSR : %x\n", D18F2x90.Field.DisDllShutdownSR); return D18F2x90.Field.DisDllShutdownSR; }
/** * Get TN CSR phy self refresh power down mode. * * * @param[in] Channel DCT controller index * @param[in] StdHeader Standard configuration header * @retval CsrPhySrPllPdMode */ STATIC UINT32 GfxLibGetMemPhyPllPdModeTN ( IN UINT8 Channel, IN AMD_CONFIG_PARAMS *StdHeader ) { D18F2xA8_dct0_STRUCT D18F2xA8; GnbRegisterReadTN ( ((Channel == 0) ? D18F2xA8_dct0_TYPE : D18F2xA8_dct1_TYPE), ((Channel == 0) ? D18F2xA8_dct0_ADDRESS : D18F2xA8_dct1_ADDRESS), &D18F2xA8.Value, 0, StdHeader ); IDS_HDT_CONSOLE (GNB_TRACE, "MemPhyPllPdMode : %x\n", D18F2xA8.Field.MemPhyPllPdMode); return D18F2xA8.Field.MemPhyPllPdMode; }
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"); }
STATIC VOID GfxFillHtcDataTN ( IN OUT ATOM_INTEGRATED_SYSTEM_INFO_V1_7 *IntegratedInfoTable, IN GFX_PLATFORM_CONFIG *Gfx ) { D18F3x64_STRUCT D18F3x64; GnbRegisterReadTN ( D18F3x64_TYPE, D18F3x64_ADDRESS, &D18F3x64.Value, 0, GnbLibGetHeader (Gfx) ); if (D18F3x64.Field.HtcEn == 1) { IntegratedInfoTable->ucHtcTmpLmt = (UCHAR) (D18F3x64.Field.HtcTmpLmt / 2 + 52); IntegratedInfoTable->ucHtcHystLmt = (UCHAR) (D18F3x64.Field.HtcHystLmt / 2); } else { IntegratedInfoTable->ucHtcTmpLmt = 0; IntegratedInfoTable->ucHtcHystLmt = 0; } }
/** * Set Dll Cap based on fuses * * * * @param[in] Wrapper Pointer to Wrapper configuration data area * @param[in] Pcie Pointer to PCIe configuration data area */ VOID PcieSetDllCapTN ( IN PCIe_WRAPPER_CONFIG *Wrapper, IN PCIe_PLATFORM_CONFIG *Pcie ) { D18F3x1FC_STRUCT D18F3x1FC; D0F0xE4_PHY_500F_STRUCT D0F0xE4_PHY_500F; D0F0xE4_PHY_4010_STRUCT D0F0xE4_PHY_4010; D0F0xE4_PHY_4011_STRUCT D0F0xE4_PHY_4011; UINT32 Gen1Index; UINT32 Gen2Index; CPU_LOGICAL_ID LogicalId; GNB_HANDLE *GnbHandle; IDS_HDT_CONSOLE (GNB_TRACE, "PcieSetDllCapTN Enter\n"); D0F0xE4_PHY_500F.Value = 0; GnbHandle = GnbGetHandle (GnbLibGetHeader (Pcie)); ASSERT (GnbHandle != NULL); GetLogicalIdOfSocket (GnbGetSocketId (GnbHandle), &LogicalId, GnbLibGetHeader (Pcie)); //Read SWDllCapTableEn GnbRegisterReadTN (D18F3x1FC_TYPE, D18F3x1FC_ADDRESS, &D18F3x1FC, 0, GnbLibGetHeader (Pcie)); IDS_HDT_CONSOLE (GNB_TRACE, "Read D18F3x1FC value %x\n", D18F3x1FC.Value); if ((D18F3x1FC.Field.SWDllCapTableEn != 0) || ((LogicalId.Revision & AMD_F15_TN_A0) != AMD_F15_TN_A0 )) { IDS_HDT_CONSOLE (GNB_TRACE, "Executing DLL configuration\n"); // Read D0F0xE4_x0[2:1]2[1:0]_[5:4][7:6,3:0][9,1]0 Phy Receiver Functional Fuse Control (FuseFuncDllProcessCompCtl[1:0]) IDS_HDT_CONSOLE (GNB_TRACE, "Reading 0x4010 from PHY_SPACE %x\n", PHY_SPACE (Wrapper->WrapId, 0, D0F0xE4_PHY_4010_ADDRESS)); D0F0xE4_PHY_4010.Value = PcieRegisterRead (Wrapper, PHY_SPACE (Wrapper->WrapId, 0, D0F0xE4_PHY_4010_ADDRESS), Pcie); IDS_HDT_CONSOLE (GNB_TRACE, "Read 4010 value = %x\n", D0F0xE4_PHY_4010.Value); // Read D0F0xE4_x0[2:1]2[1:0]_[5:4][7:6,3:0][9,1]1 Phy Receiver Process Fuse Control (FuseProcDllProcessComp[2:0]) IDS_HDT_CONSOLE (GNB_TRACE, "Reading 0x4011 from PHY_SPACE %x\n", PHY_SPACE (Wrapper->WrapId, 0, D0F0xE4_PHY_4011_ADDRESS)); D0F0xE4_PHY_4011.Value = PcieRegisterRead (Wrapper, PHY_SPACE (Wrapper->WrapId, 0, D0F0xE4_PHY_4011_ADDRESS), Pcie); IDS_HDT_CONSOLE (GNB_TRACE, "Read 4011 value = %x\n", D0F0xE4_PHY_4011.Value); // If FuseProcDllProcessCompCtl[1:0] == 2'b11 Then Gen1Index[3:0] = FuseProcDllProcessComp[2:0], 0 // Else... // If FuseProcDllProcessComp[2:0] == 3'b000 Then Gen1Index[3:0] =4'b1101 //Typical // If FuseProcDllProcessComp[2:0] == 3'b001 Then Gen1Index[3:0] =4'b1111 //Fast // If FuseProcDllProcessComp[2:0] == 3'b010 Then Gen1Index[3:0] =4'b1010 //Slow IDS_HDT_CONSOLE (GNB_TRACE, "FuseFuncDllProcessCompCtl %x\n", D0F0xE4_PHY_4010.Field.FuseFuncDllProcessCompCtl); if (D0F0xE4_PHY_4010.Field.FuseFuncDllProcessCompCtl == 3) { IDS_HDT_CONSOLE (GNB_TRACE, "Setting Gen1Index from FuseFuncDllProcessComp %x\n", D0F0xE4_PHY_4011.Field.FuseProcDllProcessComp); Gen1Index = D0F0xE4_PHY_4011.Field.FuseProcDllProcessComp << 1; } else { IDS_HDT_CONSOLE (GNB_TRACE, "Setting Gen1Index from switch case..."); switch (D0F0xE4_PHY_4011.Field.FuseProcDllProcessComp) { case 0: IDS_HDT_CONSOLE (GNB_TRACE, "case 0 - using 0xd\n"); Gen1Index = 0xd; break; case 1: IDS_HDT_CONSOLE (GNB_TRACE, "case 1 - using 0xf\n"); Gen1Index = 0xf; break; case 2: IDS_HDT_CONSOLE (GNB_TRACE, "case 2 - using 0xa\n"); Gen1Index = 0xa; break; default: IDS_HDT_CONSOLE (GNB_TRACE, "default - using 0xd\n"); Gen1Index = 0xd; //Use typical for default case break; } } D0F0xE4_PHY_500F.Field.DllProcessFreqCtlIndex1 = Gen1Index; IDS_HDT_CONSOLE (GNB_TRACE, "Set Gen1Index to %x\n", Gen1Index); // Bits 3:0 = Gen1Index[3:0] // Bits 10:7 = DllProcessFreqCtlIndex2Rate50[3:0] if (D18F3x1FC.Field.SWDllCapTableEn != 0) { IDS_HDT_CONSOLE (GNB_TRACE, "Gen2Index - using DllProcFreqCtlIndex2Rate50 = %x\n", D18F3x1FC.Field.DllProcFreqCtlIndex2Rate50); Gen2Index = D18F3x1FC.Field.DllProcFreqCtlIndex2Rate50; } else { Gen2Index = 0x03; // Hard coded default } D0F0xE4_PHY_500F.Field.DllProcessFreqCtlIndex2 = Gen2Index; IDS_HDT_CONSOLE (GNB_TRACE, "Set Gen2Index to %x\n", Gen2Index); PcieRegisterWrite ( Wrapper, PHY_SPACE (Wrapper->WrapId, 0, D0F0xE4_PHY_500F_ADDRESS), D0F0xE4_PHY_500F.Value, FALSE, Pcie ); // Set DllProcessFreqCtlOverride on second write D0F0xE4_PHY_500F.Field.DllProcessFreqCtlOverride = 1; PcieRegisterWrite ( Wrapper, PHY_SPACE (Wrapper->WrapId, 0, D0F0xE4_PHY_500F_ADDRESS), D0F0xE4_PHY_500F.Value, FALSE, Pcie ); if (Wrapper->WrapId == 1) { // For Wrapper 1, configure PHY0 and PHY1 D0F0xE4_PHY_500F.Field.DllProcessFreqCtlOverride = 0; PcieRegisterWrite ( Wrapper, PHY_SPACE (Wrapper->WrapId, 1, D0F0xE4_PHY_500F_ADDRESS), D0F0xE4_PHY_500F.Value, FALSE, Pcie ); // Set DllProcessFreqCtlOverride on second write D0F0xE4_PHY_500F.Field.DllProcessFreqCtlOverride = 1; PcieRegisterWrite ( Wrapper, PHY_SPACE (Wrapper->WrapId, 1, D0F0xE4_PHY_500F_ADDRESS), D0F0xE4_PHY_500F.Value, FALSE, Pcie ); } } IDS_HDT_CONSOLE (GNB_TRACE, "PcieSetDllCapTN Exit\n"); }
/** * 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); }
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 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; }
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; }