SCAN_STATUS GfxScanPcieDevice ( IN PCI_ADDR Device, IN OUT GNB_PCI_SCAN_DATA *ScanData ) { UINT8 ClassCode; UINT32 VendorId; IDS_HDT_CONSOLE (GFX_MISC, " Evaluate device [%d:%d:%d]\n", Device.Address.Bus, Device.Address.Device, Device.Address.Function ); if (GnbLibPciIsBridgeDevice (Device.AddressValue, ScanData->StdHeader)) { UINT32 SaveBusConfiguration; UINT32 Value; if (Device.Address.Bus == 0) { ((GFX_SCAN_DATA *) ScanData)->BaseBridge = Device; } GnbLibPciRead (Device.AddressValue | 0x18, AccessWidth32, &SaveBusConfiguration, ScanData->StdHeader); Value = (((0xFF << 8) | ((GFX_SCAN_DATA *) ScanData)->BusNumber) << 8) | Device.Address.Bus; GnbLibPciWrite (Device.AddressValue | 0x18, AccessWidth32, &Value, ScanData->StdHeader); ((GFX_SCAN_DATA *) ScanData)->BusNumber++; GnbLibPciScanSecondaryBus (Device, ScanData); ((GFX_SCAN_DATA *) ScanData)->BusNumber--; GnbLibPciWrite (Device.AddressValue | 0x18, AccessWidth32, &SaveBusConfiguration, ScanData->StdHeader); return 0; } GnbLibPciRead (Device.AddressValue | 0x0b, AccessWidth8, &ClassCode, ScanData->StdHeader); if (ClassCode == 3) { IDS_HDT_CONSOLE (GFX_MISC, " Found GFX Card\n" ); GnbLibPciRead (Device.AddressValue | 0x00, AccessWidth32, &VendorId, ScanData->StdHeader); if (!GnbLibPciIsPcieDevice (Device.AddressValue, ScanData->StdHeader)) { IDS_HDT_CONSOLE (GFX_MISC, " GFX Card is PCI device\n" ); ((GFX_SCAN_DATA *) ScanData)->GfxCardInfo->PciGfxCardBitmap |= (1 << ((GFX_SCAN_DATA *) ScanData)->BaseBridge.Address.Device); return 0; } if ((UINT16) VendorId == 0x1002) { IDS_HDT_CONSOLE (GFX_MISC, " GFX Card is AMD PCIe device\n" ); ((GFX_SCAN_DATA *) ScanData)->GfxCardInfo->AmdPcieGfxCardBitmap |= (1 << ((GFX_SCAN_DATA *) ScanData)->BaseBridge.Address.Device); } ((GFX_SCAN_DATA *) ScanData)->GfxCardInfo->PcieGfxCardBitmap |= (1 << ((GFX_SCAN_DATA *) ScanData)->BaseBridge.Address.Device); } return 0; }
/** * Write CPU (DCT) indirect registers * * * * @param[in] Address PCI address of DCT register * @param[in] IndirectAddress Offset of DCT register * @param[in] Value Pointer to value * @param[in] Config Pointer to standard header */ VOID GnbLibCpuPciIndirectWrite ( IN UINT32 Address, IN UINT32 IndirectAddress, IN UINT32 *Value, IN VOID *Config ) { UINT32 OffsetRegisterValue; OffsetRegisterValue = IndirectAddress | BIT30; GnbLibPciWrite (Address + 4, AccessWidth32, Value, Config); GnbLibPciWrite (Address, AccessWidth32, &IndirectAddress, Config); do { GnbLibPciRead (Address , AccessWidth32, &OffsetRegisterValue, Config); } while ((OffsetRegisterValue & BIT31) == 0); }
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"); }
/** * Request boot up voltage * * * * @param[in] LinkCap Global GEN capability * @param[in] Pcie Pointer to PCIe configuration data area */ VOID PcieFmSetBootUpVoltage ( IN PCIE_LINK_SPEED_CAP LinkCap, IN PCIe_PLATFORM_CONFIG *Pcie ) { FCRxFE00_70A2_STRUCT FCRxFE00_70A2; D18F3x15C_STRUCT D18F3x15C; UINT8 TargetVidIndex; UINT32 Temp; IDS_HDT_CONSOLE (GNB_TRACE, "PcieFmSetBootUpVoltage Enter\n"); ASSERT (LinkCap <= PcieGen2); GnbLibPciRead ( MAKE_SBDFO ( 0, 0, 0x18, 3, D18F3x15C_ADDRESS), AccessWidth32, &D18F3x15C.Value, GnbLibGetHeader (Pcie) ); Temp = D18F3x15C.Value; if (LinkCap > PcieGen1) { FCRxFE00_70A2.Value = NbSmuReadEfuse (FCRxFE00_70A2_ADDRESS, GnbLibGetHeader (Pcie)); TargetVidIndex = (UINT8) FCRxFE00_70A2.Field.PcieGen2Vid; } else { TargetVidIndex = PcieSiliconGetGen1VoltageIndex (GnbLibGetHeader (Pcie)); } IDS_HDT_CONSOLE (PCIE_MISC, " Set Voltage for Gen %d, Vid Index %d\n", LinkCap, TargetVidIndex); if (TargetVidIndex == 3) { D18F3x15C.Field.SclkVidLevel2 = D18F3x15C.Field.SclkVidLevel3; GnbLibPciWrite ( MAKE_SBDFO ( 0, 0, 0x18, 3, D18F3x15C_ADDRESS), AccessWidth32, &D18F3x15C.Value, GnbLibGetHeader (Pcie) ); PcieSiliconRequestVoltage (2, GnbLibGetHeader (Pcie)); } GnbLibPciWrite ( MAKE_SBDFO ( 0, 0, 0x18, 3, D18F3x15C_ADDRESS), AccessWidth32, &Temp, GnbLibGetHeader (Pcie) ); PcieSiliconRequestVoltage (TargetVidIndex, GnbLibGetHeader (Pcie)); IDS_HDT_CONSOLE (GNB_TRACE, "PcieFmSetBootUpVoltage Exit\n"); }
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; }
/** * Set current link speed * * * @param[in] LinkSpeedCapability Link Speed Capability * @param[in] Engine Pointer to engine configuration descriptor * @param[in] Pcie Pointer to global PCIe configuration * */ VOID PcieSetLinkSpeedCapV4 ( IN PCIE_LINK_SPEED_CAP LinkSpeedCapability, IN PCIe_ENGINE_CONFIG *Engine, IN PCIe_PLATFORM_CONFIG *Pcie ) { DxF0xE4_xA4_STRUCT DxF0xE4_xA4; DxF0xE4_xC0_STRUCT DxF0xE4_xC0; DxF0x88_STRUCT DxF0x88; GnbLibPciRead ( Engine->Type.Port.Address.AddressValue | DxF0x88_ADDRESS, AccessWidth32, &DxF0x88.Value, GnbLibGetHeader (Pcie) ); DxF0xE4_xA4.Value = PciePortRegisterRead ( Engine, DxF0xE4_xA4_ADDRESS, Pcie ); DxF0xE4_xC0.Value = PciePortRegisterRead ( Engine, DxF0xE4_xC0_ADDRESS, Pcie ); switch (LinkSpeedCapability) { case PcieGen3: DxF0xE4_xA4.Field.LcGen2EnStrap = 0x1; DxF0xE4_xA4.Field.LcGen3EnStrap = 0x1; DxF0xE4_xA4.Field.LcMultUpstreamAutoSpdChngEn = 0x1; DxF0x88.Field.TargetLinkSpeed = 0x3; DxF0x88.Field.HwAutonomousSpeedDisable = 0x0; PciePortRegisterRMW ( Engine, DxF0xE4_xA2_ADDRESS, DxF0xE4_xA2_LcDynLanesPwrState_MASK, (2 << DxF0xE4_xA2_LcDynLanesPwrState_OFFSET), FALSE, Pcie ); break; case PcieGen2: DxF0xE4_xA4.Field.LcGen2EnStrap = 0x1; DxF0xE4_xA4.Field.LcMultUpstreamAutoSpdChngEn = 0x1; DxF0x88.Field.TargetLinkSpeed = 0x2; DxF0x88.Field.HwAutonomousSpeedDisable = 0x0; break; case PcieGen1: DxF0xE4_xA4.Field.LcGen2EnStrap = 0x0; DxF0xE4_xA4.Field.LcMultUpstreamAutoSpdChngEn = 0x0; DxF0x88.Field.TargetLinkSpeed = 0x1; DxF0x88.Field.HwAutonomousSpeedDisable = 0x1; PcieRegisterWriteField ( PcieConfigGetParentWrapper (Engine), WRAP_SPACE (PcieConfigGetParentWrapper (Engine)->WrapId, D0F0xE4_WRAP_0803_ADDRESS + 0x100 * Engine->Type.Port.PortId), D0F0xE4_WRAP_0803_StrapBifDeemphasisSel_OFFSET, D0F0xE4_WRAP_0803_StrapBifDeemphasisSel_WIDTH, 0, FALSE, Pcie ); break; default: ASSERT (FALSE); break; } if ((Pcie->PsppPolicy == PsppDisabled) || (PcieConfigIsSbPcieEngine (Engine))) { DxF0xE4_xC0.Field.StrapAutoRcSpeedNegotiationDis = 0x0; } else { DxF0xE4_xC0.Field.StrapAutoRcSpeedNegotiationDis = 0x1; } PciePortRegisterWrite ( Engine, DxF0xE4_xA4_ADDRESS, DxF0xE4_xA4.Value, FALSE, Pcie ); PciePortRegisterWrite ( Engine, DxF0xE4_xC0_ADDRESS, DxF0xE4_xC0.Value, FALSE, Pcie ); GnbLibPciWrite ( Engine->Type.Port.Address.AddressValue | DxF0x88_ADDRESS, AccessWidth32, &DxF0x88.Value, GnbLibGetHeader (Pcie) ); }