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"); }
AGESA_STATUS PcieEdpPortPowerCheckCZ ( IN AMD_CONFIG_PARAMS *StdHeader ) { GMMx1206C_STRUCT GMMx1206C; BOOLEAN EdpPresent; AGESA_STATUS Status; AGESA_STATUS AgesaStatus; PCIe_PLATFORM_CONFIG *Pcie; AgesaStatus = AGESA_SUCCESS; IDS_HDT_CONSOLE (GNB_TRACE, "PcieEdpPortPowerCheckCZ Enter\n"); Status = PcieLocateConfigurationData (StdHeader, &Pcie); AGESA_STATUS_UPDATE (Status, AgesaStatus); if (Status == AGESA_SUCCESS) { EdpPresent = FALSE; PcieConfigRunProcForAllEngines ( DESCRIPTOR_ALLOCATED | DESCRIPTOR_DDI_ENGINE | DESCRIPTOR_VIRTUAL, DdiEdpPortDetectCallbackCZ, (VOID *)&EdpPresent, Pcie ); if (EdpPresent == FALSE) { // Power off GnbRegisterReadCZ (GnbGetHandle (GnbLibGetHeader (Pcie)), GMMx1206C_TYPE, GMMx1206C_ADDRESS, &GMMx1206C.Value, 0, GnbLibGetHeader (Pcie)); GMMx1206C.Field.LVTMA_PWRSEQ_EN = 0; GMMx1206C.Field.LVTMA_PWRSEQ_TARGET_STATE = 0; GMMx1206C.Field.LVTMA_BLON_OVRD = 0; GnbRegisterWriteCZ (GnbGetHandle (GnbLibGetHeader (Pcie)), GMMx1206C_TYPE, GMMx1206C_ADDRESS, &GMMx1206C.Value, GNB_REG_ACC_FLAG_S3SAVE, GnbLibGetHeader (Pcie)); } } IDS_HDT_CONSOLE (GNB_TRACE, "PcieMidBeforeGfxInitCZ Exit [0x%x]\n", AgesaStatus); return AgesaStatus; }
/** * Power Up/Down iGPU * * * * @param[in,out] Gfx Pointer to GFX configuration * @param[in,out] PowerControl Control power Up/Down iGPU, 0, power down iGPU, 1, power on iGPU * @retval AGESA_STATUS */ AGESA_STATUS GfxRequestGPUPowerV3 ( IN OUT GFX_PLATFORM_CONFIG *Gfx, IN UINT8 PowerControl ) { GNB_HANDLE *GnbHandle; DEV_OBJECT DevObject; GnbHandle = GnbGetHandle (GnbLibGetHeader (Gfx)); DevObject.DevPciAddress.AddressValue = MAKE_SBDFO (0, 0, 0, 0, 0); DevObject.GnbHandle = GnbHandle; DevObject.StdHeader = GnbLibGetHeader (Gfx); if (PowerControl == 0) { GnbSmuServiceRequestV7 ( &DevObject, SMC_MSG_POWERDOWNGPU, 0, GNB_REG_ACC_FLAG_S3SAVE ); } else { GnbSmuServiceRequestV7 ( &DevObject, SMC_MSG_POWERUPGPU, 0, GNB_REG_ACC_FLAG_S3SAVE ); } return AGESA_SUCCESS; }
VOID GfxFillNbPStateVid ( IN OUT ATOM_INTEGRATED_SYSTEM_INFO_V6 *IntegratedInfoTable, IN GFX_PLATFORM_CONFIG *Gfx ) { D18F3xDC_STRUCT D18F3xDC; D18F6x90_STRUCT D18F6x90; GnbLibPciRead ( MAKE_SBDFO ( 0, 0, 0x18, 3, D18F3xDC_ADDRESS), AccessWidth32, &D18F3xDC.Value, GnbLibGetHeader (Gfx) ); IntegratedInfoTable->usNBP0Voltage = (USHORT) D18F3xDC.Field.NbPs0Vid; GnbLibPciRead ( MAKE_SBDFO ( 0, 0, 0x18, 6, D18F6x90_ADDRESS), AccessWidth32, &D18F6x90.Value, GnbLibGetHeader (Gfx) ); IntegratedInfoTable->usNBP1Voltage = (USHORT) D18F6x90.Field.NbPs1Vid; IntegratedInfoTable->ulMinimumNClk = GfxLibCalculateClk ( (UINT8) (((D18F6x90.Field.NbPs1NclkDiv != 0) && (D18F6x90.Field.NbPs1NclkDiv < D18F3xDC.Field.NbPs0NclkDiv)) ? D18F6x90.Field.NbPs1NclkDiv : D18F3xDC.Field.NbPs0NclkDiv), IntegratedInfoTable->ulDentistVCOFreq ); }
AGESA_STATUS GfxInitSsid ( IN GFX_PLATFORM_CONFIG *Gfx ) { AGESA_STATUS Status; UINT32 TempData; PCI_ADDR IgpuAddress; PCI_ADDR HdaudioAddress; Status = AGESA_SUCCESS; TempData = 0; IgpuAddress = Gfx->GfxPciAddress; HdaudioAddress = Gfx->GfxPciAddress; HdaudioAddress.Address.Function = 1; // Set SSID for internal GPU if (UserOptions.CfgGnbIGPUSSID != 0) { GnbLibPciRMW ((IgpuAddress.AddressValue | 0x4C), AccessS3SaveWidth32, 0, UserOptions.CfgGnbIGPUSSID, GnbLibGetHeader (Gfx)); } else { GnbLibPciRead (IgpuAddress.AddressValue, AccessS3SaveWidth32, &TempData, GnbLibGetHeader (Gfx)); GnbLibPciRMW ((IgpuAddress.AddressValue | 0x4C), AccessS3SaveWidth32, 0, TempData, GnbLibGetHeader (Gfx)); } // Set SSID for internal HD Audio if (UserOptions.CfgGnbHDAudioSSID != 0) { GnbLibPciRMW ((HdaudioAddress.AddressValue | 0x4C), AccessS3SaveWidth32, 0, UserOptions.CfgGnbHDAudioSSID, GnbLibGetHeader (Gfx)); } else { GnbLibPciRead (HdaudioAddress.AddressValue, AccessS3SaveWidth32, &TempData, GnbLibGetHeader (Gfx)); GnbLibPciRMW ((HdaudioAddress.AddressValue | 0x4C), AccessS3SaveWidth32, 0, TempData, GnbLibGetHeader (Gfx)); } return Status; }
VOID PcieAcsCapabilityPortEnableV4 ( IN PCIe_ENGINE_CONFIG *Engine, IN PCIe_PLATFORM_CONFIG *Pcie ) { DxF0x2A4_STRUCT DxF0x2A4; IDS_HDT_CONSOLE (GNB_TRACE, "PcieAcsCapabilityPortEnableV4 Enter\n"); //Step 3, Check each individual ACS sub-capability in each port configure space, if the individual capability is implemented, then go to step 4 to enable it GnbLibPciRead ( Engine->Type.Port.Address.AddressValue | DxF0x2A4_ADDRESS, AccessWidth32, &DxF0x2A4.Value, GnbLibGetHeader (Pcie) ); DxF0x2A4.Field.Bitfield_16_16 = DxF0x2A4.Field.Bitfield_0_0; DxF0x2A4.Field.Bitfield_17_17 = DxF0x2A4.Field.Bitfield_1_1; //Step 4, Enable each individual ACS sub-items in each port configure space GnbLibPciWrite ( Engine->Type.Port.Address.AddressValue | DxF0x2A4_ADDRESS, AccessS3SaveWidth32, &DxF0x2A4.Value, GnbLibGetHeader (Pcie) ); IDS_HDT_CONSOLE (GNB_TRACE, "PcieAcsCapabilityPortEnableV4 Exit\n"); }
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; }
/** * 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"); } }
STATIC AGESA_STATUS GfxSetBootUpVoltageTN ( IN GFX_PLATFORM_CONFIG *Gfx ) { IDS_HDT_CONSOLE (GNB_TRACE, "GfxSetBootUpVoltageTN Enter\n"); GfxRequestVoltageTN (GnbLocateHighestVidCode (GnbLibGetHeader (Gfx)), GnbLibGetHeader (Gfx)); return AGESA_SUCCESS; }
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; } } }
/** * Callback to Enable IOAPIC on GNB * * * * @param[in] Descriptor Silicon descriptor * @param[in] Buffer Pointer to buffer * @param[in] Pcie Pointer to global PCIe configuration * @retval AGESA_STATUS */ AGESA_STATUS IoapicEnableCallbackV5 ( IN PCIe_DESCRIPTOR_HEADER *Descriptor, IN OUT VOID *Buffer, IN PCIe_PLATFORM_CONFIG *Pcie ) { PCI_ADDR GnbPciAddress; D0F0xFC_x00_STRUCT D0F0xFC_x00; UINT32 *AddressPtr; UINT32 AddressLow; UINT32 AddressHigh; D0F0xFC_x00.Value = 0x0; D0F0xFC_x00.Field.IoapicEnable = 1; // Set the extended ID enable (default) D0F0xFC_x00.Field.IoapicIdExtEn = 1; // Enable SB feature for every APIC. ACPI OS may disable this once the OS boots D0F0xFC_x00.Field.IoapicSbFeatureEn = 1; AddressPtr = (UINT32*) Buffer; AddressLow = AddressPtr[0] & 0xFFFFFF00; AddressHigh = AddressPtr[1]; // Get the PCI address of the GNB GnbPciAddress = GnbGetHostPciAddress (GnbGetHandle (GnbLibGetHeader (Pcie))); // If the BLDCFG base address is null, assume that the base address of the APIC has already been programmed // If base address is defined in BLDCFG, program it here if ((AddressLow != NULL) || (AddressHigh != NULL)) { GnbLibPciIndirectWrite ( GnbPciAddress.AddressValue | D0F0xF8_ADDRESS, D0F0xFC_x01_ADDRESS, AccessS3SaveWidth32, &AddressLow, GnbLibGetHeader (Pcie) ); GnbLibPciIndirectWrite ( GnbPciAddress.AddressValue | D0F0xF8_ADDRESS, D0F0xFC_x02_ADDRESS, AccessS3SaveWidth32, &AddressHigh, GnbLibGetHeader (Pcie) ); IDS_HDT_CONSOLE (GNB_TRACE, "GNB IOAPIC base address is at high %x, low %x\n", AddressHigh, AddressLow); // Enable the IOAPIC. GnbLibPciIndirectWrite ( GnbPciAddress.AddressValue | D0F0xF8_ADDRESS, D0F0xFC_x00_ADDRESS, AccessS3SaveWidth32, &D0F0xFC_x00.Value, GnbLibGetHeader (Pcie) ); } return AGESA_SUCCESS; }
UINT32 PcieSiliconRegisterRead ( IN PCIe_SILICON_CONFIG *Silicon, IN UINT32 Address, IN PCIe_PLATFORM_CONFIG *Pcie ) { UINT32 Value; GnbLibPciWrite (Silicon->Address.AddressValue | 0xE0, AccessWidth32, &Address, GnbLibGetHeader (Pcie)); GnbLibPciRead (Silicon->Address.AddressValue | 0xE4, AccessWidth32, &Value, GnbLibGetHeader (Pcie)); return Value; }
/** * 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"); } }
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 PcieCompletionTimeout ( IN PCIe_ENGINE_CONFIG *Engine, IN PCIe_PLATFORM_CONFIG *Pcie ) { GnbLibPciRMW ( Engine->Type.Port.Address.AddressValue | DxF0x80_ADDRESS, AccessWidth32, 0xffffffff, 0x6 << DxF0x80_CplTimeoutValue_OFFSET, GnbLibGetHeader (Pcie) ); if (Engine->Type.Port.PortData.LinkHotplug != HotplugDisabled) { PciePortRegisterWriteField ( Engine, DxF0xE4_x20_ADDRESS, DxF0xE4_x20_TxFlushTlpDis_OFFSET, DxF0xE4_x20_TxFlushTlpDis_WIDTH, 0x0, TRUE, Pcie ); } }
VOID PcieUtilGetLinkHwStateHistory ( IN PCIe_ENGINE_CONFIG *Engine, OUT UINT8 *History, IN UINT8 Length, IN PCIe_PLATFORM_CONFIG *Pcie ) { UINT8 ReadLength; UINT32 LocalHistory [6]; UINT16 Index; ASSERT (Length <= 16); ASSERT (Length > 0); if (Length > 6*4) { Length = 6*4; } ReadLength = (Length + 3) / 4; for (Index = 0; Index < ReadLength; Index++) { LocalHistory[Index] = PciePortRegisterRead ( Engine, DxF0xE4_xA5_ADDRESS + Index, Pcie ); } LibAmdMemCopy (History, LocalHistory, Length, GnbLibGetHeader (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); } }
VOID STATIC PcieSiliconControlPortsV5 ( IN PCIE_PORT_VISIBILITY Control, IN PCIe_SILICON_CONFIG *Silicon, IN PCIe_PLATFORM_CONFIG *Pcie ) { PCIe_ENGINE_CONFIG *EngineList; UINT32 Value; Value = (Control == HidePorts) ? ((1 << D0F0xCC_x01_BridgeDis_OFFSET) | (1 << D0F0xCC_x01_CfgDis_OFFSET)) : 0; Value |= (1 << D0F0xCC_x01_CsrEnable_OFFSET) | (1 << D0F0xCC_x01_SetPowEn_OFFSET); EngineList = PcieConfigGetChildEngine (Silicon); while (EngineList != NULL) { if (PcieConfigIsPcieEngine (EngineList)) { GnbLibPciIndirectRMW ( Silicon->Address.AddressValue | D0F0xC8_ADDRESS, D0F0xCC_x01_ADDRESS | ((EngineList->Type.Port.NativeDevNumber << 3 | EngineList->Type.Port.NativeFunNumber) << D0F0xC8_NB_DEV_IND_SEL_OFFSET), AccessS3SaveWidth32, (UINT32)~(D0F0xCC_x01_BridgeDis_MASK | D0F0xCC_x01_CfgDis_MASK | D0F0xCC_x01_CsrEnable_MASK | D0F0xCC_x01_SetPowEn_MASK), Value, GnbLibGetHeader (Pcie) ); } EngineList = (PCIe_ENGINE_CONFIG *) PcieConfigGetNextTopologyDescriptor (EngineList, DESCRIPTOR_TERMINATE_GNB); } }
/** * 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; }
/** * Enumerate audio endpoint in all display connectors. * * * * @param[in] Gfx Gfx configuration info * @param[in, out] AudioEPCount Total Audio endpoint number * @retval AGESA_STATUS */ AGESA_STATUS GfxIntAudioEPEnumV5 ( IN GFX_PLATFORM_CONFIG *Gfx, IN OUT UINT8 *AudioEPCount ) { UINT8 NumAudioEp; AGESA_STATUS Status; PCIe_PLATFORM_CONFIG *Pcie; IDS_HDT_CONSOLE (GNB_TRACE, "GfxIntAudioEPEnumV5 Enter\n"); NumAudioEp = 0; Status = PcieLocateConfigurationData (GnbLibGetHeader (Gfx), &Pcie); if ((Status == AGESA_SUCCESS) && (Gfx->GnbHdAudio != 0)) { PcieConfigRunProcForAllEngines ( DESCRIPTOR_ALLOCATED | DESCRIPTOR_DDI_ENGINE | DESCRIPTOR_VIRTUAL, GfxIntAudioEpEnumCallback, &NumAudioEp, Pcie ); if (Gfx->GnbRemoteDisplaySupport) { NumAudioEp++; } } *AudioEPCount = NumAudioEp; IDS_HDT_CONSOLE (GNB_TRACE, "GfxIntAudioEPEnumV5 Exit\n"); return Status; }
VOID PcieForceCompliance ( IN PCIe_ENGINE_CONFIG *Engine, IN PCIe_PLATFORM_CONFIG *Pcie ) { if (Engine->Type.Port.PortData.LinkSpeedCapability >= PcieGen2) { GnbLibPciRMW ( Engine->Type.Port.Address.AddressValue | DxF0x88_ADDRESS, AccessWidth32, 0xffffffff, 0x1 << DxF0x88_EnterCompliance_OFFSET, GnbLibGetHeader (Pcie) ); } else if (Engine->Type.Port.PortData.LinkSpeedCapability == PcieGen1) { PciePortRegisterWriteField ( Engine, DxF0xE4_xC0_ADDRESS, DxF0xE4_xC0_StrapForceCompliance_OFFSET, DxF0xE4_xC0_StrapForceCompliance_WIDTH, 0x1, FALSE, Pcie ); } }
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; } }
/** * Check if for GFX workaround condition * * * @param[in] CurrentEngine Pointer to engine config descriptor * @param[in] Pcie Pointer to global PCIe configuration * */ VOID STATIC PcieTrainingGfxWorkaround ( IN PCIe_ENGINE_CONFIG *CurrentEngine, IN PCIe_PLATFORM_CONFIG *Pcie ) { UINT32 TimeStamp; GFX_WORKAROUND_STATUS GfxWorkaroundStatus; TimeStamp = PcieTimerGetTimeStamp (Pcie); GfxWorkaroundStatus = PcieGfxCardWorkaroundV2 (CurrentEngine->Type.Port.Address, GnbLibGetHeader (Pcie)); switch (GfxWorkaroundStatus) { case GFX_WORKAROUND_DEVICE_NOT_READY: if (TIMESTAMPS_DELTA (TimeStamp, CurrentEngine->Type.Port.TimeStamp) >= (3 * 1000000)) { PcieTrainingSetPortStateV2 (CurrentEngine, LinkStateTrainingFail, TRUE, Pcie); } break; case GFX_WORKAROUND_SUCCESS: PcieTrainingSetPortStateV2 (CurrentEngine, LinkStateTrainingSuccess, FALSE, Pcie); break; case GFX_WORKAROUND_RESET_DEVICE: if (CurrentEngine->Type.Port.GfxWrkRetryCount < 5) { CurrentEngine->Type.Port.GfxWrkRetryCount++; PcieTrainingSetPortStateV2 (CurrentEngine, LinkStateResetAssert, TRUE, Pcie); } else { PcieTrainingSetPortStateV2 (CurrentEngine, LinkStateTrainingFail, TRUE, Pcie); } break; default: ASSERT (FALSE); } }
/** * Check if link fail because device does not support Gen2 * * * @param[in] CurrentEngine Pointer to engine config descriptor * @param[in] Pcie Pointer to global PCIe configuration * */ VOID PcieTrainingGen2FailV2 ( IN PCIe_ENGINE_CONFIG *CurrentEngine, IN PCIe_PLATFORM_CONFIG *Pcie ) { UINT8 LinkTrainingState; if (CurrentEngine->Type.Port.PortData.MiscControls.LinkSafeMode != PcieGen1) { PcieConfigUpdatePortStatus (CurrentEngine, INIT_STATUS_PCIE_PORT_GEN2_RECOVERY, 0); CurrentEngine->Type.Port.PortData.MiscControls.LinkSafeMode = PcieGen1; PcieLinkSafeMode (CurrentEngine, Pcie); LinkTrainingState = LinkStateResetAssert; PutEventLog ( AGESA_WARNING, GNB_EVENT_BROKEN_LANE_RECOVERY, CurrentEngine->Type.Port.Address.AddressValue, 0, 0, 0, GnbLibGetHeader (Pcie) ); } else { LinkTrainingState = LinkStateTrainingFail; } PcieTrainingSetPortStateV2 (CurrentEngine, LinkTrainingState, FALSE, Pcie); }
STATIC VOID GfxIntInfoTableInitDispclkTable ( IN PP_FUSE_ARRAY *PpFuseArray, IN ATOM_INTEGRATED_SYSTEM_INFO_V1_7 *IntegratedInfoTable, IN GFX_PLATFORM_CONFIG *Gfx ) { UINTN Index; for (Index = 0; Index < 4; Index++) { if (PpFuseArray->DisplclkDid[Index] != 0) { IntegratedInfoTable->sDISPCLK_Voltage[Index].ulMaximumSupportedCLK = GfxFmCalculateClock ( PpFuseArray->DisplclkDid[Index], GnbLibGetHeader (Gfx) ); IntegratedInfoTable->sDISPCLK_Voltage[Index].ulVoltageIndex = (ULONG) Index; } } IntegratedInfoTable->ucDPMState0VclkFid = PpFuseArray->VclkDid[0]; IntegratedInfoTable->ucDPMState1VclkFid = PpFuseArray->VclkDid[1]; IntegratedInfoTable->ucDPMState2VclkFid = PpFuseArray->VclkDid[2]; IntegratedInfoTable->ucDPMState3VclkFid = PpFuseArray->VclkDid[3]; IntegratedInfoTable->ucDPMState0DclkFid = PpFuseArray->DclkDid[0]; IntegratedInfoTable->ucDPMState1DclkFid = PpFuseArray->DclkDid[1]; IntegratedInfoTable->ucDPMState2DclkFid = PpFuseArray->DclkDid[2]; IntegratedInfoTable->ucDPMState3DclkFid = PpFuseArray->DclkDid[3]; }
VOID PcieTrainingBrokenLineV2 ( IN PCIe_ENGINE_CONFIG *CurrentEngine, IN PCIe_PLATFORM_CONFIG *Pcie ) { UINT8 CurrentLinkWidth; UINT8 LinkTrainingState; CurrentLinkWidth = PcieUtilGetLinkWidth (CurrentEngine, Pcie); if (CurrentLinkWidth < PcieConfigGetNumberOfPhyLane (CurrentEngine) && CurrentLinkWidth > 0) { CurrentEngine->InitStatus |= INIT_STATUS_PCIE_PORT_BROKEN_LANE_RECOVERY; PcieTopologyReduceLinkWidthV5 (CurrentLinkWidth, CurrentEngine, Pcie); LinkTrainingState = LinkStateResetAssert; PutEventLog ( AGESA_WARNING, GNB_EVENT_BROKEN_LANE_RECOVERY, CurrentEngine->Type.Port.Address.AddressValue, 0, 0, 0, GnbLibGetHeader (Pcie) ); } else { LinkTrainingState = LinkStateGen2Fail; } PcieTrainingSetPortStateV2 (CurrentEngine, LinkTrainingState, FALSE, Pcie); }
VOID STATIC IoapicInitCallbackV5 ( IN PCIe_ENGINE_CONFIG *Engine, IN OUT VOID *Buffer, IN PCIe_PLATFORM_CONFIG *Pcie ) { PCI_ADDR GnbPciAddress; D0F0xFC_x10_STRUCT D0F0xFC_x10; GnbPciAddress = GnbGetHostPciAddress ((GNB_HANDLE *) PcieConfigGetParent (DESCRIPTOR_SILICON, &Engine->Header)); D0F0xFC_x10.Value = 0x0; // Bounds check values - make sure the value is small enough to fit the field size ASSERT (Engine->Type.Port.PortData.ApicDeviceInfo.GroupMap < (1 << D0F0xFC_x10_BrExtIntrGrp_WIDTH)); ASSERT (Engine->Type.Port.PortData.ApicDeviceInfo.Swizzle < (1 << D0F0xFC_x10_BrExtIntrSwz_WIDTH)); ASSERT (Engine->Type.Port.PortData.ApicDeviceInfo.BridgeInt < (1 << D0F0xFC_x10_BrIntIntrMap_WIDTH)); // Get the configuration from the PCIe_PORT_DATA APIC_DEVICE_INFO struct D0F0xFC_x10.Field.BrExtIntrGrp = Engine->Type.Port.PortData.ApicDeviceInfo.GroupMap; D0F0xFC_x10.Field.BrExtIntrSwz = Engine->Type.Port.PortData.ApicDeviceInfo.Swizzle; D0F0xFC_x10.Field.BrIntIntrMap = Engine->Type.Port.PortData.ApicDeviceInfo.BridgeInt; // Write the register GnbLibPciIndirectWrite ( GnbPciAddress.AddressValue | D0F0xF8_ADDRESS, D0F0xFC_x10_ADDRESS + Engine->Type.Port.LogicalBridgeId, AccessS3SaveWidth32, &D0F0xFC_x10.Value, GnbLibGetHeader (Pcie) ); }
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"); }
STATIC VOID GfxIntegratedInfoTable318_fun ( IN PP_F1_ARRAY_V2 *PpF1Array, IN ATOM_INTEGRATED_SYSTEM_INFO_V1_8 *IntegratedInfoTable, IN GFX_PLATFORM_CONFIG *Gfx ) { UINT8 Index; UINTN v1; GnbGfx275_STRUCT *pv2; BOOLEAN Sorting; pv2 = &IntegratedInfoTable->ATOM_INTEGRATED_SYSTEM_INFO_V1_8[0]; v1 = 0; for (Index = 0; Index < 5; Index++) { if (PpF1Array->PP_FUSE_ARRAY_V2_fld33[Index] != 0) { pv2[v1].GnbGfx275_STRUCT_fld0 = GfxFmCalculateClock (PpF1Array->PP_FUSE_ARRAY_V2_fld33[Index], GnbLibGetHeader (Gfx)); pv2[v1].GnbGfx275_STRUCT_fld1 = Index; pv2[v1].GnbGfx275_STRUCT_fld2 = PpF1Array->PP_FUSE_ARRAY_V2_fld32[Index]; v1++; } } if (v1 > 1) { do { Sorting = FALSE; for (Index = 0; Index < (v1 - 1); Index++) { GnbGfx275_STRUCT Temp; BOOLEAN Exchange; Exchange = FALSE; if (pv2[Index].GnbGfx275_STRUCT_fld1 > pv2[Index + 1].GnbGfx275_STRUCT_fld1) { Exchange = TRUE; } if ((pv2[Index].GnbGfx275_STRUCT_fld1 == pv2[Index + 1].GnbGfx275_STRUCT_fld1) && (pv2[Index].GnbGfx275_STRUCT_fld0 > pv2[Index + 1].GnbGfx275_STRUCT_fld0)) { Exchange = TRUE; } if (Exchange) { Sorting = TRUE; LibAmdMemCopy (&Temp, &pv2[Index], sizeof (GnbGfx275_STRUCT), GnbLibGetHeader (Gfx)); LibAmdMemCopy (&pv2[Index], &pv2[Index + 1], sizeof (GnbGfx275_STRUCT), GnbLibGetHeader (Gfx)); LibAmdMemCopy (&pv2[Index + 1], &Temp, sizeof (GnbGfx275_STRUCT), GnbLibGetHeader (Gfx)); } } } while (Sorting); } }
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; }