示例#1
0
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;
}
示例#2
0
/**
 * Create IVRS entry
 *
 *
 * @param[in]  Type            Block type
 * @param[in]  Ivhd            IVHD header pointer
 * @param[in]  StdHeader       Standard configuration header
 *
 */
VOID
GnbCreateIvhdHeaderTN (
  IN       IVRS_BLOCK_TYPE            Type,
     OUT   IVRS_IVHD_ENTRY            *Ivhd,
  IN       AMD_CONFIG_PARAMS          *StdHeader
  )
{
  UINT32    Value;
  Ivhd->Type = (UINT8) Type;
  Ivhd->Flags = IVHD_FLAG_COHERENT | IVHD_FLAG_IOTLBSUP | IVHD_FLAG_ISOC | IVHD_FLAG_RESPASSPW | IVHD_FLAG_PASSPW | IVHD_FLAG_PPRSUB | IVHD_FLAG_PREFSUP;
  Ivhd->Length = sizeof (IVRS_IVHD_ENTRY);
  Ivhd->DeviceId = 0x2;
  Ivhd->CapabilityOffset = GnbLibFindPciCapability (MAKE_SBDFO (0, 0, 0, 2, 0), IOMMU_CAP_ID, StdHeader);
  Ivhd->PciSegment = 0;
  GnbLibPciRead (MAKE_SBDFO (0, 0, 0, 2, Ivhd->CapabilityOffset + 0x4), AccessWidth32, &Ivhd->BaseAddress, StdHeader);
  GnbLibPciRead (MAKE_SBDFO (0, 0, 0, 2, Ivhd->CapabilityOffset + 0x8), AccessWidth32, (UINT8 *) &Ivhd->BaseAddress + 4, StdHeader);
  Ivhd->BaseAddress = Ivhd->BaseAddress & 0xfffffffffffffffe;
  ASSERT (Ivhd->BaseAddress != 0x0);
  GnbLibPciRead (MAKE_SBDFO (0, 0, 0, 2, Ivhd->CapabilityOffset + 0x10), AccessWidth32, &Value, StdHeader);
  Ivhd->IommuInfo = (UINT16) (Value & 0x1f) | (0x13 << IVHD_INFO_UNITID_OFFSET);
  Ivhd->IommuEfr = (0 << IVHD_EFR_XTSUP_OFFSET) | (0 << IVHD_EFR_NXSUP_OFFSET) | (1 << IVHD_EFR_GTSUP_OFFSET) |
                   (0 << IVHD_EFR_GLXSUP_OFFSET) | (1 << IVHD_EFR_IASUP_OFFSET) | (0 << IVHD_EFR_GASUP_OFFSET) |
                   (0 << IVHD_EFR_HESUP_OFFSET) | (0x8 << IVHD_EFR_PASMAX_OFFSET) | (0 << IVHD_EFR_MSINUMPPR_OFFSET) |
                   (4 << IVHD_EFR_PNCOUNTERS_OFFSET) | (2 << IVHD_EFR_PNBANKS_OFFSET);
}
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
                                         );
}
示例#4
0
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;
}
示例#5
0
/**
 * Read CPU (DCT) indirect registers
 *
 *
 *
 * @param[in]  Address         PCI address of DCT register
 * @param[in]  IndirectAddress Offset of DCT register
 * @param[out] Value           Pointer to value
 * @param[in]  Config          Pointer to standard header
 */
VOID
GnbLibCpuPciIndirectRead (
    IN       UINT32        Address,
    IN       UINT32        IndirectAddress,
    OUT   UINT32        *Value,
    IN       VOID          *Config
)
{
    UINT32  OffsetRegisterValue;
    GnbLibPciWrite (Address, AccessWidth32, &IndirectAddress, Config);
    do {
        GnbLibPciRead (Address , AccessWidth32, &OffsetRegisterValue, Config);
    } while ((OffsetRegisterValue & BIT31) == 0);
    GnbLibPciRead (Address + 4, AccessWidth32, Value, Config);
}
示例#6
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");
}
示例#7
0
 /*----------------------------------------------------------------------------------------*/
BOOLEAN
IsPcieCommClk (
  IN       PCI_ADDR                 Device,
  IN       AMD_CONFIG_PARAMS        *StdHeader
  )
{

  UINT8   PcieCapPtr;
  UINT32  Value;

  PcieCapPtr = GnbLibFindPciCapability (Device.AddressValue, PCIE_CAP_ID, StdHeader);
  if (PcieCapPtr == 0) {
    return FALSE;
  }
  GnbLibPciRead (
    Device.AddressValue | (PcieCapPtr + PCIE_LINK_CTRL_REGISTER),
    AccessWidth32,
    &Value,
    StdHeader
    );
  if ((Value & BIT28) != 0) {
    return TRUE;
  }


  return FALSE;
}
示例#8
0
文件: GfxLib.c 项目: AdriDlu/coreboot
/**
 * Get max non 0 VID index
 *
 *
 * @param[in] StdHeader       Standard configuration header
 * @retval                    NBVDD VID index
 */
UINT8
GfxLibMaxVidIndex (
  IN      AMD_CONFIG_PARAMS     *StdHeader
  )
{
  UINT8           MaxVid;
  UINT8           MaxVidIndex;
  UINT8           SclkVidArray[4];
  UINTN           Index;

  GnbLibPciRead (
    MAKE_SBDFO ( 0, 0, 0x18, 3, D18F3x15C_ADDRESS),
    AccessWidth32,
    &SclkVidArray[0],
    StdHeader
    );
  MaxVidIndex = 0;
  MaxVid = 0xff;
  for (Index = 0; Index < 4; Index++) {
    if (SclkVidArray[Index] != 0 && SclkVidArray[Index] < MaxVid) {
      MaxVid = SclkVidArray[Index];
      MaxVidIndex = (UINT8) Index;
    }
  }
  return MaxVidIndex;
}
示例#9
0
AGESA_STATUS
GnbCreateIvrsEntryTN (
  IN       GNB_HANDLE                 *GnbHandle,
  IN       IVRS_BLOCK_TYPE            Type,
  IN       VOID                       *Ivrs,
  IN       AMD_CONFIG_PARAMS          *StdHeader
  )
{
  IVRS_IVHD_ENTRY                   *Ivhd;
  UINT8                             IommuCapabilityOffset;
  UINT32                            Value;

  IDS_HDT_CONSOLE (GNB_TRACE, "GnbFmCreateIvrsEntry Entry\n");
  if (Type == IvrsIvhdBlock || Type == IvrsIvhdrBlock) {
    // Update IVINFO
    IommuCapabilityOffset = GnbLibFindPciCapability (MAKE_SBDFO (0, 0, 0, 2, 0), IOMMU_CAP_ID, StdHeader);
    GnbLibPciRead (MAKE_SBDFO (0, 0, 0, 2, IommuCapabilityOffset + 0x10), AccessWidth32, &Value, StdHeader);
    ((IOMMU_IVRS_HEADER *) Ivrs)->IvInfo = Value & (IVINFO_HTATSRESV_MASK | IVINFO_VASIZE_MASK | IVINFO_GASIZE_MASK | IVINFO_PASIZE_MASK);

    // Address of IVHD entry
    Ivhd = (IVRS_IVHD_ENTRY*) ((UINT8 *)Ivrs + ((IOMMU_IVRS_HEADER *) Ivrs)->TableLength);
    GnbCreateIvhdHeaderTN (Type, Ivhd, StdHeader);
    if (Type == IvrsIvhdBlock) {
      GnbCreateIvhdTN (Ivhd, StdHeader);
    } else {
      GnbCreateIvhdrTN (Ivhd, StdHeader);
    }
    ((IOMMU_IVRS_HEADER *) Ivrs)->TableLength = ((IOMMU_IVRS_HEADER *) Ivrs)->TableLength + Ivhd->Length;
  }
  IDS_HDT_CONSOLE (GNB_TRACE, "GnbFmCreateIvrsEntry Exit\n");
  return AGESA_SUCCESS;
}
示例#10
0
 /*----------------------------------------------------------------------------------------*/
STATIC BOOLEAN
PcieClkPmCheckDeviceCapability (
  IN       PCI_ADDR                 Device,
  IN       AMD_CONFIG_PARAMS        *StdHeader
  )
{

  UINT8   MaxFunc;
  UINT8   CurrentFunc;
  UINT8   PcieCapPtr;
  UINT32  Value;

  MaxFunc = GnbLibPciIsMultiFunctionDevice (Device.AddressValue, StdHeader) ? 7 : 0;

  for (CurrentFunc = 0; CurrentFunc <= MaxFunc; CurrentFunc++) {
    Device.Address.Function = CurrentFunc;
    if (GnbLibPciIsDevicePresent (Device.AddressValue, StdHeader)) {
      PcieCapPtr = GnbLibFindPciCapability (Device.AddressValue, PCIE_CAP_ID, StdHeader);
      if (PcieCapPtr == 0) {
        return FALSE;
      }
      GnbLibPciRead (
        Device.AddressValue | (PcieCapPtr + PCIE_LINK_CAP_REGISTER),
        AccessWidth32,
        &Value,
        StdHeader
        );
      if ((Value & BIT18) == 0) {
        return FALSE;
      }
    }
  }
  return TRUE;
}
示例#11
0
/**
 * Check if link fail because device does not support Gen X
 *
 *
 * @param[in]  CurrentEngine       Pointer to engine config descriptor
 * @param[in]  Pcie                Pointer to global PCIe configuration
 *
 */
VOID
STATIC
PcieTrainingCheckVcoNegotiation (
  IN      PCIe_ENGINE_CONFIG    *CurrentEngine,
  IN      PCIe_PLATFORM_CONFIG  *Pcie
  )
{
  UINT32          TimeStamp;
  DxFxx128_STRUCT DxFxx128;
  TimeStamp = PcieTimerGetTimeStamp (Pcie);
  GnbLibPciRead (CurrentEngine->Type.Port.Address.AddressValue | DxFxx128_ADDRESS, AccessWidth32, &DxFxx128, GnbLibGetHeader (Pcie));
  if (DxFxx128.Field.VcNegotiationPending == 0) {
    UINT16  NumberOfPhyLane;
    NumberOfPhyLane = PcieConfigGetNumberOfPhyLane (CurrentEngine);
    if (Pcie->GfxCardWorkaround == GfxWorkaroundEnable && NumberOfPhyLane >= 8) {
      // Limit exposure of workaround to x8 and x16 port.
      PcieTrainingSetPortStateV2 (CurrentEngine, LinkStateGfxWorkaround, TRUE, Pcie);
    } else {
      PcieTrainingSetPortStateV2 (CurrentEngine, LinkStateTrainingSuccess, FALSE, Pcie);
    }
    return;
  }
  if (TIMESTAMPS_DELTA (TimeStamp, CurrentEngine->Type.Port.TimeStamp) >= 1000 * 1000) {
    PcieTrainingSetPortStateV2 (CurrentEngine, LinkStateRetrain, FALSE, Pcie);
  }
}
示例#12
0
 /*----------------------------------------------------------------------------------------*/
VOID
PcieRetrain (
  IN       PCI_ADDR             Function,
  IN       AMD_CONFIG_PARAMS    *StdHeader
  )
{
  UINT8       PcieCapPtr;
  UINT32      Value;

  PcieCapPtr = GnbLibFindPciCapability (Function.AddressValue, PCIE_CAP_ID, StdHeader);
  Value = BIT27;

  if (PcieCapPtr != 0) {
    GnbLibPciRMW (
      Function.AddressValue | (PcieCapPtr + PCIE_LINK_CTRL_REGISTER),
      AccessS3SaveWidth32,
      ~(UINT32) (BIT5),
      BIT5,
      StdHeader
      );
    IDS_HDT_CONSOLE (GNB_TRACE, "      PcieRetrain link on Device = %d:%d:%d\n", Function.Address.Bus, Function.Address.Device, Function.Address.Function);
    do {
      GnbLibPciRead (
        Function.AddressValue | (PcieCapPtr + PCIE_LINK_CTRL_REGISTER),
        AccessS3SaveWidth32,
        &Value,
        StdHeader);
    } while ((Value & BIT27) != 0);
  }
}
示例#13
0
/**
 * Create IVHD entry
 *
 *
 * @param[in]  Ivhd            IVHD header pointer
 * @param[in]  StdHeader       Standard configuration header
 *
 */
VOID
SbCreateIvhdEntries (
     OUT   IVRS_IVHD_ENTRY            *Ivhd,
  IN       AMD_CONFIG_PARAMS          *StdHeader
  )
{
  PCI_ADDR  Start;
  PCI_ADDR  End;
  PCI_ADDR  PciAddress;
  UINT32    Value;
  IDS_HDT_CONSOLE (GNB_TRACE, "SbCreateIvhdEntries Entry\n");
  PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0x14, 4, 0);
// P2P alias entry
  GnbLibPciRead (PciAddress.AddressValue | 0x18, AccessWidth32, &Value, StdHeader);
  Start.AddressValue = MAKE_SBDFO (0, (Value >> 8) & 0xff, 0, 0, 0);
  End.AddressValue = MAKE_SBDFO (0, (Value >> 16) & 0xff, 0x1f, 0x7, 0);
  GnbIvhdAddDeviceAliasRangeEntry (Start, End, PciAddress, 0, Ivhd, StdHeader);
  PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0x14, 0, 0);
// HPET
  GnbIvhdAddSpecialDeviceEntry (IvhdSpecialDeviceHpet, PciAddress, 0, 0, Ivhd, StdHeader);
// APIC
  GnbIvhdAddSpecialDeviceEntry (
    IvhdSpecialDeviceIoapic,
    PciAddress,
    GnbLiGetIoapicId (SbGetSbIoApicBaseAddress (StdHeader), StdHeader),
    0xD7,
    Ivhd,
    StdHeader
    );
  IDS_HDT_CONSOLE (GNB_TRACE, "SbCreateIvhdEntries Exit\n");
}
示例#14
0
AGESA_STATUS
GfxEnableGmmAccessV5 (
  IN OUT   GFX_PLATFORM_CONFIG   *Gfx
  )
{
  UINT32      Value;
  GNB_HANDLE  *GnbHandle;

  GnbHandle = GnbGetHandle (GnbLibGetHeader (Gfx));
  ASSERT (GnbHandle != NULL);
  // GmmBase should be 0 before enable.
  ASSERT (GnbHandle->GmmBase == 0);

  if (!GnbLibPciIsDevicePresent (Gfx->GfxPciAddress.AddressValue, GnbLibGetHeader (Gfx))) {
    IDS_ERROR_TRAP;
    return AGESA_ERROR;
  }

  // Check if base address for GMM allocated by reading D1F0x24 Graphics Memory Mapped Base Address
  Gfx->GmmBase = 0;
  GnbLibPciRead (Gfx->GfxPciAddress.AddressValue | 0x24, AccessWidth32, &Value, GnbLibGetHeader (Gfx));
  Gfx->GmmBase |= (Value & 0xfffffff0);
  if (Gfx->GmmBase == 0) {
    IDS_ERROR_TRAP;
    return AGESA_ERROR;
  }

  // Check if base address for FB allocated
  GnbLibPciRead (Gfx->GfxPciAddress.AddressValue | 0x10, AccessWidth32, &Value, GnbLibGetHeader (Gfx));
  if ((Value & 0xfffffff0) == 0) {
    IDS_ERROR_TRAP;
    return AGESA_ERROR;
  }
  //Push CPU MMIO pci config to S3 script
  GnbLibS3SaveConfigSpace (MAKE_SBDFO (0, 0, 0x18, 1, 0), 0xBC, 0x80, AccessS3SaveWidth32, GnbLibGetHeader (Gfx));
  // Turn on memory decoding on GFX to enable access to GMM register space
  GnbLibPciRMW (Gfx->GfxPciAddress.AddressValue | 0x4, AccessWidth32, 0xffffffff, BIT1 | BIT2, GnbLibGetHeader (Gfx));
  //Push iGPU pci config to S3 script
  GnbLibS3SaveConfigSpace (Gfx->GfxPciAddress.AddressValue, 0x24, 0x10, AccessS3SaveWidth32, GnbLibGetHeader (Gfx));
  GnbLibS3SaveConfigSpace (Gfx->GfxPciAddress.AddressValue, 0x04, 0x04, AccessS3SaveWidth16, GnbLibGetHeader (Gfx));
  GnbHandle->GmmBase = Gfx->GmmBase;
  return AGESA_SUCCESS;
}
示例#15
0
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;
}
示例#16
0
AGESA_STATUS
GfxEnableGmmAccess (
  IN OUT   GFX_PLATFORM_CONFIG   *Gfx
  )
{
  UINT32      Value;

  if (!GnbLibPciIsDevicePresent (Gfx->GfxPciAddress.AddressValue, GnbLibGetHeader (Gfx))) {
    IDS_ERROR_TRAP;
    return AGESA_ERROR;
  }

  // Check if base address for GMM allocated
  GnbLibPciRead (Gfx->GfxPciAddress.AddressValue | 0x18, AccessWidth32, &Gfx->GmmBase, GnbLibGetHeader (Gfx));
  if (Gfx->GmmBase == 0) {
    IDS_ERROR_TRAP;
    return AGESA_ERROR;
  }
  // Check if base address for FB allocated
  GnbLibPciRead (Gfx->GfxPciAddress.AddressValue | 0x10, AccessWidth32, &Value, GnbLibGetHeader (Gfx));
  if ((Value & 0xfffffff0) == 0) {
    IDS_ERROR_TRAP;
    return AGESA_ERROR;
  }
  //Push CPU MMIO pci config to S3 script
  GnbLibS3SaveConfigSpace (MAKE_SBDFO (0, 0, 0x18, 1, 0), 0xBC, 0x80, AccessS3SaveWidth32, GnbLibGetHeader (Gfx));
  // Turn on memory decoding on APC to enable access to GMM register space
  if (Gfx->GfxControllerMode == GfxControllerLegacyBridgeMode) {
    GnbLibPciRMW (MAKE_SBDFO (0, 0, 1, 0, 0x4), AccessWidth32, 0xffffffff, BIT1 | BIT2, GnbLibGetHeader (Gfx));
    //Push APC pci config to S3 script
    GnbLibS3SaveConfigSpace (MAKE_SBDFO (0, 0, 1, 0, 0), 0x2C, 0x18, AccessS3SaveWidth32, GnbLibGetHeader (Gfx));
    GnbLibS3SaveConfigSpace (MAKE_SBDFO (0, 0, 1, 0, 0), 0x4, 0x4, AccessS3SaveWidth16, GnbLibGetHeader (Gfx));
  }
  // Turn on memory decoding on GFX to enable access to GMM register space
  GnbLibPciRMW (Gfx->GfxPciAddress.AddressValue | 0x4, AccessWidth32, 0xffffffff, BIT1 | BIT2, GnbLibGetHeader (Gfx));
  //Push iGPU pci config to S3 script
  GnbLibS3SaveConfigSpace (Gfx->GfxPciAddress.AddressValue, 0x24, 0x10, AccessS3SaveWidth32, GnbLibGetHeader (Gfx));
  GnbLibS3SaveConfigSpace (Gfx->GfxPciAddress.AddressValue, 0x04, 0x04, AccessS3SaveWidth16, GnbLibGetHeader (Gfx));
  return AGESA_SUCCESS;
}
示例#17
0
/**
 * Check a PCIE device to see if it supports phantom functions
 *
 * @param[in] Device      Device pci address
 * @param[in] StdHeader   Standard configuration header
 * @return    TRUE        Current device supports phantom functions
 */
STATIC BOOLEAN
GnbCheckPhantomFuncSupport (
  IN       PCI_ADDR                 Device,
  IN       AMD_CONFIG_PARAMS        *StdHeader
  )
{
  UINT8   PcieCapPtr;
  UINT32  Value;
  Value = 0;

  PcieCapPtr = GnbLibFindPciCapability (Device.AddressValue, PCIE_CAP_ID, StdHeader);
  if (PcieCapPtr != 0) {
    GnbLibPciRead (Device.AddressValue | (PcieCapPtr + 4), AccessWidth32, &Value, StdHeader);
  }
  return ((Value & (BIT3 | BIT4)) != 0) ? TRUE : FALSE;
}
/**
 * Get disable DLL shutdown in self-refresh mode.
 *
 *
 * @param[in] Channel    DCT controller index
 * @param[in] StdHeader  Standard configuration header
 * @retval    DisDllShutdownSR
 */
UINT32
GfxLibGetDisDllShutdownSR (
  IN       UINT8       Channel,
  IN       AMD_CONFIG_PARAMS      *StdHeader
  )
{
  D18F2x90_STRUCT D18F2x090;

  GnbLibPciRead (
    MAKE_SBDFO ( 0, 0, 0x18, 2, (Channel == 0) ? D18F2x90_ADDRESS : D18F2x190_ADDRESS),
    AccessWidth32,
    &D18F2x090.Value,
    StdHeader
    );

  return  D18F2x090.Field.DisDllShutdownSR;
}
VOID
GfxFillHtcData (
  IN OUT   ATOM_INTEGRATED_SYSTEM_INFO_V6   *IntegratedInfoTable,
  IN       GFX_PLATFORM_CONFIG              *Gfx
  )
{
  D18F3x64_STRUCT  D18F3x64;

  GnbLibPciRead (
    MAKE_SBDFO ( 0, 0, 0x18, 3, D18F3x64_ADDRESS),
    AccessWidth32,
    &D18F3x64.Value,
    GnbLibGetHeader (Gfx)
    );
  IntegratedInfoTable->ucHtcTmpLmt = (UCHAR) (D18F3x64.Field.HtcTmpLmt / 2 + 52);
  IntegratedInfoTable->ucHtcHystLmt = (UCHAR) (D18F3x64.Field.HtcHystLmt / 2);
}
示例#20
0
/**
 * 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");
}
示例#21
0
AGESA_STATUS
PcieFmAlibBuildAcpiTable (
  IN       VOID                          *AlibSsdtPtr,
  IN       AMD_CONFIG_PARAMS             *StdHeader
  )
{
  AGESA_STATUS          AgesaStatus;
  D18F4x15C_STRUCT      D18F4x15C;
  PP_FUSE_ARRAY         *PpFuseArray;
  UINT32                AmlObjName;
  VOID                  *AmlObjPtr;

  IDS_HDT_CONSOLE (GNB_TRACE, "PcieFmAlibBuildAcpiTable Enter\n");
  AgesaStatus = AGESA_SUCCESS;
  // Set voltage configuration
  PpFuseArray = GnbLocateHeapBuffer (AMD_PP_FUSE_TABLE_HANDLE, StdHeader);
  ASSERT (PpFuseArray != NULL);
  if (PpFuseArray != NULL) {
    GnbLibPciRead (
      MAKE_SBDFO (0, 0, 0x18, 0x4, D18F4x15C_ADDRESS),
      AccessWidth32,
      &D18F4x15C.Value,
      StdHeader
      );
    if (D18F4x15C.Field.BoostSrc != 0 || PpFuseArray->GpuBoostCap != 0) {
//      AmlObjName = 'B0DA';
      AmlObjName = Int32FromChar ('A', 'D', '0', 'B');
      AmlObjPtr = GnbLibFind (AlibSsdtPtr, ((ACPI_TABLE_HEADER*) &AlibSsdt[0])->TableLength, (UINT8*) &AmlObjName, sizeof (AmlObjName));
      ASSERT (AmlObjPtr != NULL);
      if (AmlObjPtr != NULL) {
        *(UINT8*)((UINT8*) AmlObjPtr + 5) = 1;
      } else {
        AgesaStatus = AGESA_FATAL;
      }
    }
  } else {
    AgesaStatus = AGESA_FATAL;
  }
  
  IDS_HDT_CONSOLE (GNB_TRACE, "PcieFmAlibBuildAcpiTable Exit[0x%x]\n", AgesaStatus);
  return AgesaStatus;
}
示例#22
0
PCIE_ASPM_TYPE
excel950_fun1 (
  IN       PCI_ADDR                 Device,
  IN       AMD_CONFIG_PARAMS        *StdHeader
  )
{
  UINT8   PcieCapPtr;
  UINT32  Value;
  PcieCapPtr = GnbLibFindPciCapability (Device.AddressValue, PCIE_CAP_ID, StdHeader);
  if (PcieCapPtr == 0) {
    return 0;
  }
  GnbLibPciRead (
    Device.AddressValue | (PcieCapPtr + PCIE_LINK_CAP_REGISTER),
    AccessWidth32,
    &Value,
    StdHeader
    );
  return (Value >> 10) & 3;
}
示例#23
0
文件: GfxLib.c 项目: AdriDlu/coreboot
UINT32
GfxLibGetMainPllFreq (
  IN       AMD_CONFIG_PARAMS      *StdHeader
  )
{
  UINT32            MainPllFreq;
  D18F3xD4_STRUCT   D18F3xD4;
  GnbLibPciRead (
    MAKE_SBDFO ( 0, 0, 0x18, 3, D18F3xD4_ADDRESS),
    AccessWidth32,
    &D18F3xD4.Value,
    StdHeader
    );
  if (D18F3xD4.Field.MainPllOpFreqIdEn == 1) {
    MainPllFreq = 100 * (D18F3xD4.Field.MainPllOpFreqId + 0x10);
  } else {
    MainPllFreq = 1600;
  }
  return  MainPllFreq;
}
/**
 * Get Gen1 voltage Index
 *
 *
 *
 *
 * @param[in]  StdHeader           Standard configuration header
 */
UINT8
PcieSiliconGetGen1VoltageIndex (
  IN      AMD_CONFIG_PARAMS     *StdHeader
  )
{
  UINT8   Index;
  UINT8   Gen1VidIndex;
  UINT8   SclkVidArray[4];
  GnbLibPciRead (
    MAKE_SBDFO ( 0, 0, 0x18, 3, 0x15c ),
    AccessWidth32,
    &SclkVidArray[0],
    StdHeader
    );
  Gen1VidIndex = 0;
  for (Index = 0; Index < 4; Index++) {
    if (SclkVidArray[Index] > SclkVidArray[Gen1VidIndex]) {
      Gen1VidIndex = Index;
    }
  }
  return Gen1VidIndex;
}
示例#25
0
AGESA_STATUS
GfxInitSview (
  IN      AMD_CONFIG_PARAMS               *StdHeader
  )
{
  AGESA_STATUS          Status;
  AGESA_STATUS          AgesaStatus;
  GFX_PLATFORM_CONFIG   *Gfx;
  UINT32                OriginalCmdReg;
  IDS_HDT_CONSOLE (GNB_TRACE, "GfxInitSview Enter\n");
  AgesaStatus = AGESA_SUCCESS;
  Status =  GfxLocateConfigData (StdHeader, &Gfx);
  AGESA_STATUS_UPDATE (Status, AgesaStatus);
  if (Status == AGESA_SUCCESS) {
    if (GfxLibIsControllerPresent (StdHeader)) {
      if (!GfxFmIsVbiosPosted (Gfx)) {
        GFX_VBIOS_IMAGE_INFO  VbiosImageInfo;
        LibAmdMemCopy (&VbiosImageInfo.StdHeader, StdHeader, sizeof (AMD_CONFIG_PARAMS), StdHeader);
        VbiosImageInfo.ImagePtr = NULL;
        VbiosImageInfo.GfxPciAddress = Gfx->GfxPciAddress;
        VbiosImageInfo.Flags = GFX_VBIOS_IMAGE_FLAG_SPECIAL_POST;
        GnbLibPciRead (Gfx->GfxPciAddress.AddressValue | 0x4, AccessS3SaveWidth8, &OriginalCmdReg, StdHeader);
        GnbLibPciRMW (Gfx->GfxPciAddress.AddressValue | 0x4, AccessS3SaveWidth8, 0xff, BIT1 | BIT2 | BIT0, StdHeader);
        Status = AgesaGetVbiosImage (0, &VbiosImageInfo);
        if (Status == AGESA_SUCCESS && VbiosImageInfo.ImagePtr != NULL) {
          GfxLibCopyMemToFb (VbiosImageInfo.ImagePtr, 0, (*((UINT8*) VbiosImageInfo.ImagePtr + 2)) << 9, Gfx);
        } else {
          GfxFmDisableController (StdHeader);
          AgesaStatus = AGESA_ERROR;
        }
        GnbLibPciRMW (Gfx->GfxPciAddress.AddressValue | 0x4, AccessS3SaveWidth8, 0x00, OriginalCmdReg, StdHeader);
      }
    }
  }
  IDS_HDT_CONSOLE (GNB_TRACE, "GfxInitSview Exit [0x%x]\n", AgesaStatus);
  return  AgesaStatus;
}
示例#26
0
/**
 * Create IVHD entry
 *
 *
 * @param[in]  Ivhd            IVHD header pointer
 * @param[in]  StdHeader       Standard configuration header
 *
 */
VOID
SbCreateIvhdEntries (
     OUT   IVRS_IVHD_ENTRY            *Ivhd,
  IN       AMD_CONFIG_PARAMS          *StdHeader
  )
{
  PCI_ADDR  Start;
  PCI_ADDR  End;
  PCI_ADDR  PciAddress;
  UINT32    Value;
  AMD_LATE_PARAMS        *LateParamsPtr;
  IDS_HDT_CONSOLE (GNB_TRACE, "SbCreateIvhdEntries Entry\n");
  LateParamsPtr = (AMD_LATE_PARAMS *) StdHeader;
  PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0x14, 4, 0);
// P2P alias entry
  GnbLibPciRead (PciAddress.AddressValue | 0x18, AccessWidth32, &Value, StdHeader);
  Start.AddressValue = MAKE_SBDFO (0, (Value >> 8) & 0xff, 0, 0, 0);
  End.AddressValue = MAKE_SBDFO (0, (Value >> 16) & 0xff, 0x1f, 0x7, 0);
  GnbIvhdAddDeviceAliasRangeEntry (Start, End, PciAddress, 0, Ivhd, StdHeader);
  PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0x14, 0, 0);
// HPET
  GnbIvhdAddSpecialDeviceEntry (IvhdSpecialDeviceHpet, PciAddress, 0, 0, Ivhd, StdHeader);

// APIC
  if (LateParamsPtr->GnbLateConfiguration.FchIoapicId != 0xff) {
    GnbIvhdAddSpecialDeviceEntry (
      IvhdSpecialDeviceIoapic,
      PciAddress,
      LateParamsPtr->GnbLateConfiguration.FchIoapicId,
      0xD7,
      Ivhd,
      StdHeader
      );
  }
  IDS_HDT_CONSOLE (GNB_TRACE, "SbCreateIvhdEntries Exit\n");
}
示例#27
0
VOID
STATIC
PcieMidPortInitCallbackKV (
  IN       PCIe_ENGINE_CONFIG    *Engine,
  IN OUT   VOID                  *Buffer,
  IN       PCIe_PLATFORM_CONFIG  *Pcie
  )
{
  DxFxx68_STRUCT          DxFxx68;
  D0F0xE4_PIF_0012_STRUCT D0F0xE4_PIF_0012;
  PCIe_SUBLINK_INFO       *SublinkInfo;
  PCIe_WRAPPER_INFO       *WrapperInfo;
  PCIe_WRAPPER_CONFIG     *Wrapper;
  CPU_LOGICAL_ID          LogicalId;
  UINT8                   Count;
  UINT8                   Nibble;

  PciePortProgramRegisterTable (PortInitMidTableKV.Table, PortInitMidTableKV.Length, Engine, TRUE, Pcie);
  if (PcieConfigCheckPortStatus (Engine, INIT_STATUS_PCIE_TRAINING_SUCCESS) || Engine->Type.Port.PortData.LinkHotplug != HotplugDisabled) {
    PcieEnableSlotPowerLimitV5 (Engine, Pcie);
    if (GnbFmCheckIommuPresent ((GNB_HANDLE*) PcieConfigGetParentSilicon (Engine), GnbLibGetHeader (Pcie))) {
      PcieInitPortForIommuV4 (Engine, Pcie);
    }
    // After GFX link is trained up and before ASPM is enabled, AGESA needs to check link width,
    // if it equals to x16, then apply the following change to GFX port:
    // Per port register 0xA1 - PCIE LC TRAINING CONTROL, bit16 - LC_EXTEND_WAIT_FOR_SKP = 1
    GnbLibPciRead (
      Engine->Type.Port.Address.AddressValue | DxFxx68_ADDRESS,
      AccessWidth32,
      &DxFxx68,
      GnbLibGetHeader (Pcie)
      );
    if (DxFxx68.Field.NegotiatedLinkWidth == 16) {
      PciePortRegisterRMW (
        Engine,
        DxFxxE4_xA1_ADDRESS,
        DxFxxE4_xA1_LcExtendWaitForSkp_MASK,
        (1 << DxFxxE4_xA1_LcExtendWaitForSkp_OFFSET),
        TRUE,
        Pcie
        );
    }
  }

  Wrapper = PcieConfigGetParentWrapper (Engine);
  SublinkInfo = &(((PCIe_INFO_BUFFER *)Buffer)->SublinkInfo[MIN (Engine->EngineData.StartLane, Engine->EngineData.EndLane) / 4]);
  WrapperInfo = &(((PCIe_INFO_BUFFER *)Buffer)->WrapperInfo[Wrapper->WrapId]);
  GetLogicalIdOfCurrentCore (&LogicalId, (AMD_CONFIG_PARAMS *)Pcie->StdHeader);
  // Check if this CPU is KV A0
  // UBTS468566
  if ((LogicalId.Revision & AMD_F15_KV_A0) != 0) {

    Count = SublinkInfo->GppPortCount;
    IDS_HDT_CONSOLE (GNB_TRACE, "x1x2 PortCount = %02x\n", Count);

    if (Count == 2) {
      // If number of GPP ports under the same sublink is 2, Delay L1 Exit (prolong minimum time spent in L1)
      PciePortRegisterRMW (
        Engine,
        DxFxxE4_xA0_ADDRESS,
        DxFxxE4_xA0_LcDelayCount_MASK |
        DxFxxE4_xA0_LcDelayL1Exit_MASK,
        (0 << DxFxxE4_xA0_LcDelayCount_OFFSET) |
        (1 << DxFxxE4_xA0_LcDelayL1Exit_OFFSET),
        TRUE,
        Pcie
        );
    } else if (Count > 2) {
      // If number of GPP ports > 2
      if (SublinkInfo->MaxGenCapability > Gen1) {
        // If at least 1 GPP is Gen2 capable, Disable PLL Power down feature
        Wrapper = PcieConfigGetParentWrapper (Engine);
        Nibble = (UINT8) ((MIN (Engine->EngineData.StartLane, Engine->EngineData.EndLane) % 8) / 4);
        // Only PSD and PPD can have x1/x2 links, so we assume that PIF number is always 0
        D0F0xE4_PIF_0012.Value = PcieRegisterRead (
                                   Wrapper,
                                   PIF_SPACE (Wrapper->WrapId, 0, D0F0xE4_PIF_0012_ADDRESS + Nibble),
                                   Pcie
                                   );

        D0F0xE4_PIF_0012.Field.PllPowerStateInOff = PifPowerStateL0;
        D0F0xE4_PIF_0012.Field.PllPowerStateInTxs2 = PifPowerStateL0;

        PcieRegisterWrite (
          Wrapper,
          PIF_SPACE (Wrapper->WrapId, 0, D0F0xE4_PIF_0012_ADDRESS + Nibble),
          D0F0xE4_PIF_0012.Value,
          TRUE,
          Pcie
          );
      } else {
        // All ports are only Gen1
        PciePortRegisterRMW (
          Engine,
          DxFxxE4_xC0_ADDRESS,
          DxFxxE4_xC0_StrapMedyTSxCount_MASK,
          0x2 << DxFxxE4_xC0_StrapMedyTSxCount_OFFSET,
          TRUE,
          Pcie
          );
      }
    }
  }
  PcieRegisterRMW (
    Wrapper,
    WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_0802_ADDRESS + (0x100 * Engine->Type.Port.PortId)),
    D0F0xE4_WRAP_0802_StrapBifL1ExitLatency_MASK,
    (WrapperInfo->L1ExitLatencyValue << D0F0xE4_WRAP_0802_StrapBifL1ExitLatency_OFFSET),
    TRUE,
    Pcie
    );
  if (WrapperInfo->DisableL1OnWrapper == TRUE) {
    Engine->Type.Port.PortData.LinkAspm &= ~(AspmL1);
  }
  PcieEnableAspm (Engine,  Pcie);
}
示例#28
0
/**
 * 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)
   );
}
示例#29
0
AGESA_STATUS
PcieAlibBuildAcpiTable (
  IN       AMD_CONFIG_PARAMS    *StdHeader,
     OUT   VOID                 **AlibSsdtPtr
  )
{
  AGESA_STATUS            Status;
  UINT32                  AmlObjName;
  PCIe_PLATFORM_CONFIG    *Pcie;
  PP_FUSE_ARRAY           *PpFuseArray;
  VOID                    *AlibSsdtBuffer;
  VOID                    *AmlObjPtr;
  UINT8                   SclkVidArray[4];
  UINT8                   BootUpVid;
  UINT8                   BootUpVidIndex;
  UINT8                   Gen1VidIndex;
  UINTN                   Index;
  UINTN                   AlibSsdtlength;
  Status = AGESA_SUCCESS;
  AlibSsdtlength = ((ACPI_TABLE_HEADER*) &AlibSsdt[0])->TableLength;
  if (*AlibSsdtPtr == NULL) {
    AlibSsdtBuffer = GnbAllocateHeapBuffer (
                       AMD_ACPI_ALIB_BUFFER_HANDLE,
                       AlibSsdtlength,
                       StdHeader
                       );
    ASSERT (AlibSsdtBuffer != NULL);
    if (AlibSsdtBuffer == NULL) {
      return  AGESA_ERROR;
    }
    *AlibSsdtPtr = AlibSsdtBuffer;
  } else {
    AlibSsdtBuffer = *AlibSsdtPtr;
  }
  // Copy template to buffer
  LibAmdMemCopy (AlibSsdtBuffer, &AlibSsdt[0], AlibSsdtlength, StdHeader);
  // Set PCI MMIO configuration
//  AmlObjName = '10DA';
  AmlObjName = Int32FromChar ('A', 'D', '0', '1');
  AmlObjPtr = GnbLibFind (AlibSsdtBuffer, AlibSsdtlength, (UINT8*) &AmlObjName, sizeof (AmlObjName));
  if (AmlObjPtr != NULL) {
    UINT64  MsrReg;
    LibAmdMsrRead (MSR_MMIO_Cfg_Base, &MsrReg, StdHeader);
    if ((MsrReg & BIT0) != 0 && (MsrReg & 0xFFFFFFFF00000000) == 0) {
      *(UINT32*)((UINT8*)AmlObjPtr + 5) = (UINT32)(MsrReg & 0xFFFFF00000);
    } else {
      Status = AGESA_ERROR;
    }
  } else {
    Status = AGESA_ERROR;
  }
  // Set voltage configuration
  PpFuseArray = GnbLocateHeapBuffer (AMD_PP_FUSE_TABLE_HANDLE, StdHeader);
  if (PpFuseArray != NULL) {
//    AmlObjName = '30DA';
    AmlObjName = Int32FromChar ('A', 'D', '0', '3');
    AmlObjPtr = GnbLibFind (AlibSsdtBuffer, AlibSsdtlength, (UINT8*) &AmlObjName, sizeof (AmlObjName));
    ASSERT (AmlObjPtr != NULL);
    if (AmlObjPtr != NULL) {
      *(UINT8*)((UINT8*)AmlObjPtr + 5) = PpFuseArray->PcieGen2Vid;
    } else {
      Status = AGESA_ERROR;
    }
  } else {
    Status = AGESA_ERROR;
  }
  GnbLibPciRead (
    MAKE_SBDFO ( 0, 0, 0x18, 3, D18F3x15C_ADDRESS),
    AccessWidth32,
    &SclkVidArray[0],
    StdHeader
    );
  Gen1VidIndex = 0;
  BootUpVidIndex = 0;
  BootUpVid = 0xff;
  for (Index = 0; Index < 4; Index++) {
    if (SclkVidArray[Index] > SclkVidArray[Gen1VidIndex]) {
      Gen1VidIndex = (UINT8) Index;
    }
    if (SclkVidArray[Index] != 0 && SclkVidArray[Index] < BootUpVid) {
      BootUpVid = SclkVidArray[Index];
      BootUpVidIndex = (UINT8) Index;
    }
  }
//  AmlObjName = '40DA';
  AmlObjName = Int32FromChar ('A', 'D', '0', '4');
  AmlObjPtr = GnbLibFind (AlibSsdtBuffer, AlibSsdtlength, (UINT8*) &AmlObjName, sizeof (AmlObjName));
  ASSERT (AmlObjPtr != NULL);
  if (AmlObjPtr != NULL) {
    *(UINT8*)((UINT8*)AmlObjPtr + 5) = Gen1VidIndex;
  } else {
    Status = AGESA_ERROR;
  }
//  AmlObjName = '50DA';
  AmlObjName = Int32FromChar ('A', 'D', '0', '5');
  AmlObjPtr = GnbLibFind (AlibSsdtBuffer, AlibSsdtlength, (UINT8*) &AmlObjName, sizeof (AmlObjName));
  ASSERT (AmlObjPtr != NULL);
  if (AmlObjPtr != NULL) {
    *(UINT8*)((UINT8*)AmlObjPtr + 5) = BootUpVidIndex;
  } else {
    Status = AGESA_ERROR;
  }
  // Set PCIe configuration
  if (PcieLocateConfigurationData (StdHeader, &Pcie) == AGESA_SUCCESS) {
//    AmlObjName = '20DA';
    AmlObjName = Int32FromChar ('A', 'D', '0', '2');
    AmlObjPtr = GnbLibFind (AlibSsdtBuffer, AlibSsdtlength, (UINT8*) &AmlObjName, sizeof (AmlObjName));
    ASSERT (AmlObjPtr != NULL);
    if (AmlObjPtr != NULL) {
      *(UINT8*)((UINT8*)AmlObjPtr + 5) = Pcie->PsppPolicy;
    } else {
      Status = AGESA_ERROR;
    }
//    AmlObjName = '60DA';
    AmlObjName = Int32FromChar ('A', 'D', '0', '6');
    AmlObjPtr = GnbLibFind (AlibSsdtBuffer, AlibSsdtlength, (UINT8*) &AmlObjName, sizeof (AmlObjName));
    ASSERT (AmlObjPtr != NULL);
    if (AmlObjPtr != NULL) {
      PcieConfigRunProcForAllEngines (
        DESCRIPTOR_ALLOCATED | DESCRIPTOR_PCIE_ENGINE,
        PcieAlibSetPortMaxSpeedCallback,
        (UINT8*)((UINT8*)AmlObjPtr + 7),
        Pcie
        );
    } else {
      Status = AGESA_ERROR;
    }
//    AmlObjName = '80DA';
    AmlObjName = Int32FromChar ('A', 'D', '0', '8');
    AmlObjPtr = GnbLibFind (AlibSsdtBuffer, AlibSsdtlength, (UINT8*) &AmlObjName, sizeof (AmlObjName));
    ASSERT (AmlObjPtr != NULL);
    if (AmlObjPtr != NULL) {
      PcieConfigRunProcForAllEngines (
        DESCRIPTOR_ALLOCATED | DESCRIPTOR_PCIE_ENGINE,
        PcieAlibSetPortOverrideSpeedCallback,
        (UINT8*)((UINT8*)AmlObjPtr + 7),
        Pcie
        );
    } else {
      Status = AGESA_ERROR;
    }
//    AmlObjName = '70DA';
    AmlObjName = Int32FromChar ('A', 'D', '0', '7');
    AmlObjPtr = GnbLibFind (AlibSsdtBuffer, AlibSsdtlength, (UINT8*) &AmlObjName, sizeof (AmlObjName));
    ASSERT (AmlObjPtr != NULL);
    if (AmlObjPtr != NULL) {
      PcieConfigRunProcForAllEngines (
        DESCRIPTOR_ALLOCATED | DESCRIPTOR_PCIE_ENGINE,
        PcieAlibSetPortInfoCallback,
        (UINT8*)((UINT8*)AmlObjPtr + 4),
        Pcie
        );
    } else {
      Status = AGESA_ERROR;
    }
  } else {
    ASSERT (FALSE);
    Status = AGESA_ERROR;
  }
  if (Status == AGESA_SUCCESS) {
    Status = PcieFmAlibBuildAcpiTable (AlibSsdtBuffer, StdHeader);
  }
  if (Status != AGESA_SUCCESS) {
    //Shrink table length to size of the header
    ((ACPI_TABLE_HEADER*) AlibSsdtBuffer)->TableLength = sizeof (ACPI_TABLE_HEADER);
  }
  ChecksumAcpiTable ((ACPI_TABLE_HEADER*) AlibSsdtBuffer, StdHeader);
  return Status;
}
示例#30
0
/**
 * Family specific fuse table patch
 * Is's correct behavior if we would have 4 states, it would be
 *   PP_FUSE_ARRAY->LclkDpmDid[0] - Goes to State 5
 *   PP_FUSE_ARRAY->LclkDpmDid[1] - Goes to State 6
 *   PP_FUSE_ARRAY->LclkDpmDid[2] - Goes to State 7
 * If we would have 4 states it would be
 *   PP_FUSE_ARRAY->LclkDpmDid[0] - Goes to State 4
 *   PP_FUSE_ARRAY->LclkDpmDid[1] - Goes to State 5
 *   PP_FUSE_ARRAY->LclkDpmDid[2] - Goes to State 6
 *   PP_FUSE_ARRAY->LclkDpmDid[3] - Goes to State 7
 *
 * @param[in] PpFuseArray             Pointer to PP_FUSE_ARRAY
 * @param[in] StdHeader               Pointer to AMD_CONFIG_PARAMS
 */
VOID
NbFmFuseAdjustFuseTablePatch (
  IN OUT   PP_FUSE_ARRAY       *PpFuseArray,
  IN       AMD_CONFIG_PARAMS   *StdHeader
  )
{
  UINT8         LclkDpmMode;
  UINT8         SwSatateIndex;
  UINT8         MaxSclkIndex;
  UINT8         DpmStateIndex;
  UINT8         CurrentSclkDpmDid;
  CPU_LOGICAL_ID  LogicalId;
  D18F3x15C_STRUCT      D18F3x15C;

  LclkDpmMode = GnbBuildOptions.LclkDpmEn ? LclkDpmRcActivity : LclkDpmDisabled;
  GetLogicalIdOfCurrentCore (&LogicalId, StdHeader);
  if ((LogicalId.Revision & (AMD_F12_LN_A0 | AMD_F12_LN_A1)) != 0) {
    LclkDpmMode = LclkDpmDisabled;
  }
  IDS_OPTION_HOOK (IDS_GNB_LCLK_DPM_EN, &LclkDpmMode, StdHeader);

  // Read Sclk VID
  GnbLibPciRead (
    MAKE_SBDFO ( 0, 0, 0x18, 3, D18F3x15C_ADDRESS),
    AccessWidth32,
    &D18F3x15C.Value,
    StdHeader
    );
  PpFuseArray->SclkVid[0] = (UINT8) (D18F3x15C.Field.SclkVidLevel0);
  PpFuseArray->SclkVid[1] = (UINT8) (D18F3x15C.Field.SclkVidLevel1);
  PpFuseArray->SclkVid[2] = (UINT8) (D18F3x15C.Field.SclkVidLevel2);
  PpFuseArray->SclkVid[3] = (UINT8) (D18F3x15C.Field.SclkVidLevel3);

  //For all CPU rev  LclkDpmValid[3] = 0
  PpFuseArray->LclkDpmValid[3] = 0;
  PpFuseArray->LclkDpmVid[3] = 0;
  PpFuseArray->LclkDpmDid[3] = 0;

  // For LCLKDPM set LclkDpmVid[0] = 0, no matter if LCLK DMP enable or disable.
  PpFuseArray->LclkDpmVid[0] = 0;

  if (LclkDpmMode != LclkDpmRcActivity) {
    //If LCLK DPM disable (LclkDpmMode != LclkDpmRcActivity)
    // -  LclkDpmDid[1,2] = LclkDpmDid [0],  LclkDpmVid[1,2] = LclkDpmVid[0]
    // -  Execute LCLK DPM init

    PpFuseArray->LclkDpmVid[1] = PpFuseArray->LclkDpmVid[0];
    PpFuseArray->LclkDpmVid[2] = PpFuseArray->LclkDpmVid[0];
    PpFuseArray->LclkDpmDid[1] = PpFuseArray->LclkDpmDid[0];
    PpFuseArray->LclkDpmDid[2] = PpFuseArray->LclkDpmDid[0];
    IDS_HDT_CONSOLE (NB_MISC, "  F12 LCLK DPM Mode Disable -- use DPM0 fusing\n");

  } else {
    // If LCLK DPM enabled
    // - use fused values for LclkDpmDid[0,1,2] and appropriate voltage
    // - Execute LCLK DPM init
    PpFuseArray->LclkDpmVid[2] = PpFuseArray->PcieGen2Vid;
    if (GfxLibIsControllerPresent (StdHeader)) {
      //VID index = VID index associated with highest SCLK DPM state in the Powerplay state where Label_Performance=1 // This would ignore the UVD case (where Label_Performance would be 0).
      for (SwSatateIndex = 0 ; SwSatateIndex < PP_FUSE_MAX_NUM_SW_STATE; SwSatateIndex++) {
        if (PpFuseArray->PolicyLabel[SwSatateIndex] == POLICY_LABEL_PERFORMANCE) {
          break;
        }
      }
      MaxSclkIndex = 0;
      CurrentSclkDpmDid = 0xff;
      ASSERT (PpFuseArray->SclkDpmValid[SwSatateIndex] != 0);
      for (DpmStateIndex = 0; DpmStateIndex < PP_FUSE_MAX_NUM_DPM_STATE; DpmStateIndex++) {
        if ((PpFuseArray->SclkDpmValid[SwSatateIndex] & (1 << DpmStateIndex)) != 0) {
          if (PpFuseArray->SclkDpmDid[DpmStateIndex] < CurrentSclkDpmDid) {
            CurrentSclkDpmDid = PpFuseArray->SclkDpmDid[DpmStateIndex];
            MaxSclkIndex = DpmStateIndex;
          }
        }
      }
      PpFuseArray->LclkDpmVid[1] = PpFuseArray->SclkDpmVid[MaxSclkIndex];
    } else {
      PpFuseArray->LclkDpmVid[1] = PpFuseArray->LclkDpmVid[0];
      PpFuseArray->LclkDpmDid[1] = PpFuseArray->LclkDpmDid[0];
    }
    // - use fused values for LclkDpmDid[0,1,2] and appropriate voltage
    //Keep using actual fusing
    IDS_HDT_CONSOLE (NB_MISC, "  LCLK DPM use actual fusing.\n");
  }

  //Patch SclkThermDid to 200Mhz if not fused
  if (PpFuseArray->SclkThermDid == 0) {
    PpFuseArray->SclkThermDid = GfxLibCalculateDid (200 * 100, GfxLibGetMainPllFreq (StdHeader) * 100);
  }
}