Пример #1
0
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];
}
Пример #2
0
STATIC VOID
GfxIntInfoTableInitSclkTable (
  IN       PP_FUSE_ARRAY                    *PpFuseArray,
  IN       ATOM_INTEGRATED_SYSTEM_INFO_V1_7 *IntegratedInfoTable,
  IN       GFX_PLATFORM_CONFIG              *Gfx
  )
{
  UINTN                       Index;
  UINTN                       AvailSclkIndex;
  ATOM_AVAILABLE_SCLK_LIST    *AvailSclkList;
  BOOLEAN                     Sorting;
  AvailSclkList = &IntegratedInfoTable->sAvail_SCLK[0];

  AvailSclkIndex = 0;
  for (Index = 0; Index < MAX_NUM_OF_FUSED_DPM_STATES; Index++) {
    if (PpFuseArray->SclkDpmDid[Index] != 0) {
      AvailSclkList[AvailSclkIndex].ulSupportedSCLK = GfxFmCalculateClock (PpFuseArray->SclkDpmDid[Index], GnbLibGetHeader (Gfx));
      AvailSclkList[AvailSclkIndex].usVoltageIndex = PpFuseArray->SclkDpmVid[Index];
      AvailSclkList[AvailSclkIndex].usVoltageID = PpFuseArray->SclkVid[PpFuseArray->SclkDpmVid[Index]];
      AvailSclkIndex++;
    }
  }
  //Sort by VoltageIndex & ulSupportedSCLK
  if (AvailSclkIndex > 1) {
    do {
      Sorting = FALSE;
      for (Index = 0; Index < (AvailSclkIndex - 1); Index++) {
        ATOM_AVAILABLE_SCLK_LIST  Temp;
        BOOLEAN                   Exchange;
        Exchange = FALSE;
        if (AvailSclkList[Index].usVoltageIndex > AvailSclkList[Index + 1].usVoltageIndex) {
          Exchange = TRUE;
        }
        if ((AvailSclkList[Index].usVoltageIndex == AvailSclkList[Index + 1].usVoltageIndex) &&
            (AvailSclkList[Index].ulSupportedSCLK > AvailSclkList[Index + 1].ulSupportedSCLK)) {
          Exchange = TRUE;
        }
        if (Exchange) {
          Sorting = TRUE;
          LibAmdMemCopy (&Temp, &AvailSclkList[Index], sizeof (ATOM_AVAILABLE_SCLK_LIST), GnbLibGetHeader (Gfx));
          LibAmdMemCopy (&AvailSclkList[Index], &AvailSclkList[Index + 1], sizeof (ATOM_AVAILABLE_SCLK_LIST), GnbLibGetHeader (Gfx));
          LibAmdMemCopy (&AvailSclkList[Index + 1], &Temp, sizeof (ATOM_AVAILABLE_SCLK_LIST), GnbLibGetHeader (Gfx));
        }
      }
    } while (Sorting);
  }
}
Пример #3
0
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);
  }
}
Пример #4
0
VOID
GfxIntInfoTableInitDispclkTableV3 (
  IN       PP_FUSE_ARRAY_V2                 *PpFuseArray,
  IN       ATOM_INTEGRATED_SYSTEM_INFO_V1_8 *IntegratedInfoTable,
  IN       GFX_PLATFORM_CONFIG              *Gfx
  )
{
  UINTN   Index;
  for (Index = 0; Index < 4; Index++) {
    if (PpFuseArray->DispClkDid[Index] != 0) {
      IntegratedInfoTable->sDISPCLK_Voltage[Index].ulMaximumSupportedCLK = GfxFmCalculateClock (
                                                                             PpFuseArray->DispClkDid[Index],
                                                                             GnbLibGetHeader (Gfx)
                                                                             );
      IntegratedInfoTable->sDISPCLK_Voltage[Index].ulVoltageIndex = (ULONG) Index;
    }
  }
}
Пример #5
0
STATIC VOID
GfxIntegratedInfoTable289_fun (
  IN       PP_F1_ARRAY_V2                 *PpF1Array,
  IN       ATOM_INTEGRATED_SYSTEM_INFO_V1_8 *IntegratedInfoTable,
  IN       GFX_PLATFORM_CONFIG              *Gfx
  )
{
  UINTN   Index;
  for (Index = 0; Index < 4; Index++) {
    if (PpF1Array->excel841_fld6[Index] != 0) {
      IntegratedInfoTable->ATOM_INTEGRATED_SYSTEM_INFO_V1_8_fld4[Index].ulMaximumSupportedCLK = GfxFmCalculateClock (
                                                                             PpF1Array->excel841_fld6[Index],
                                                                             GnbLibGetHeader (Gfx)
                                                                             );
      IntegratedInfoTable->ATOM_INTEGRATED_SYSTEM_INFO_V1_8_fld4[Index].ulVoltageIndex = (ULONG) Index;
    }
  }
}
Пример #6
0
STATIC AGESA_STATUS
GfxCalculateRestoreResetTimeTN (
  IN       ATOM_INTEGRATED_SYSTEM_INFO_V1_7 *IntegratedInfoTable,
  IN       GFX_PLATFORM_CONFIG              *Gfx,
  IN       PP_FUSE_ARRAY                    *PpFuseArray
  )
{
  UINT8      MaxDid;
  ULONG      FreqSclk;
  UINTN      Index;
  UINT32     TSclk;
  UINT32     TRefClk;
  UINT32     TNclkHalf;
  UINT32     PgfsmDelayReg0;
  UINT32     PgfsmDelayReg1;
  UINT32     ResetTime;
  UINT32     IsoTime;
  UINT32     MemSd;
  UINT32     MotherPso;
  UINT32     DaughterPso;
  UINT32     THandshake;
  UINT32     TGmcSync;
  UINT32     TPuCmd;
  UINT32     TPgfsmCmdSerialization;
  UINT32     TReset;
  UINT32     TMoPso;
  UINT32     TDaPso;
  UINT32     TMemSd;
  UINT32     TIso;
  UINT32     TRegRestore;
  UINT32     TPgfsmCleanUp;
  UINT32     TGmcPu;
  UINT32     TGmcPd;

  IDS_HDT_CONSOLE (GNB_TRACE, "GfxCalculateRestoreResetTimeTN Enter\n");
  // Find FreqSclk = MIN of frequencies SclkDpmDid (0 to 4) and SclkThermDid
  // First find the highest Did
  MaxDid = PpFuseArray->SclkThermDid;
  for (Index = 0; Index < 4; Index++) {
    // Compare with SclkDpmDid[x] - These are stored in:
    // IntegratedInfoTable-> sDISPCLK_Voltage[Index].ulMaximumSupportedCLK
    MaxDid = MAX (MaxDid, PpFuseArray->SclkDpmDid[Index]);
  }
  IDS_HDT_CONSOLE (GNB_TRACE, "MaxDid = %d\n", MaxDid);
  FreqSclk = GfxFmCalculateClock (MaxDid, GnbLibGetHeader (Gfx));
  // FreqSclk is in 10KHz units - need calculations in nS
  // For accuracy, do calculations in .01nS, then convert at the end
  TSclk = (100 * (1000000000 / 10000)) / FreqSclk;
  // FreqRefClk frequency of reference clock
  // Caclculate period in .01 nS
  TRefClk = (100 * 1000) / GFX_REFCLK;
  // FreqNclkHalf = half of Minimum NCLK value
  // Calculate period in .01 nS
  TNclkHalf = (100 * 1000) / (GFX_NCLK_MIN / 2);

  // Read delay time values from PGFSM registers
  GfxPgfsmRegisterReadTN (2 , &PgfsmDelayReg0, GnbLibGetHeader (Gfx));
  GfxPgfsmRegisterReadTN (3 , &PgfsmDelayReg1, GnbLibGetHeader (Gfx));
  ResetTime = (PgfsmDelayReg0 & 0x000000FF ) >> 0 ;
  IsoTime = (PgfsmDelayReg0 & 0x0000FF00 ) >> 8 ;
  MemSd = (PgfsmDelayReg0 & 0x00FF0000 ) >> 16 ;
  MotherPso = (PgfsmDelayReg1 & 0x00000FFF ) >> 0 ;
  DaughterPso = (PgfsmDelayReg1 & 0x00FFF000 ) >> 12 ;
  IDS_HDT_CONSOLE (GNB_TRACE, "ResetTime = %d\n", ResetTime);
  IDS_HDT_CONSOLE (GNB_TRACE, "IsoTime = %d\n", IsoTime);
  IDS_HDT_CONSOLE (GNB_TRACE, "MemSd = %d\n", MemSd);
  IDS_HDT_CONSOLE (GNB_TRACE, "MotherPso = %d\n", MotherPso);
  IDS_HDT_CONSOLE (GNB_TRACE, "DaughterPso = %d\n", DaughterPso);

  // Calculate various timing values required for the final calculation
  // THandshake = 10*1/FreqNclkHalf
  THandshake = 10 * TNclkHalf;
  // TGmcSync = 2.5*(1/FreqRefclk+1/FreqSclk)
  TGmcSync = (25 * (TRefClk + TSclk)) / 10;
  // TPuCmd =9*1/FreqSclk
  TPuCmd = 9 * TSclk;
  // TPgfsmCmdSerialization = 82*1/FreqSclk
  TPgfsmCmdSerialization = 82 * TSclk;
  // TReset = (RESET_TIME+3)*1/FreqRefclk+3*1/FreqSclk+TGmcSync
  TReset = ((ResetTime + 3) * TRefClk) + (3 * TSclk) + TGmcSync;
  // TMoPso = (MOTHER_PSO+3)*1/FreqRefclk+3*1/FreqSclk+TgmcSync
  TMoPso = ((MotherPso + 3) * TRefClk) + (3 * TSclk) + TGmcSync;
  // TDaPso = (DAUGHTER_PSO+3)*1/FreqRefclk+3*1/FreqSclk+TgmcSync
  TDaPso = ((DaughterPso + 3) * TRefClk) + (3 * TSclk) + TGmcSync;
  // TMemSD = (MEM_SD+3)*1/FreqRefclk+3*1/FreqSclk+TgmcSync
  TMemSd = ((MemSd + 3) * TRefClk) + (3 * TSclk) + TGmcSync;
  // TIso = (ISO_TIME+3)*1/FreqRefclk+3*1/FreqSclk+TgmcSync
  TIso = ((IsoTime + 3) * TRefClk) + (3 * TSclk) + TGmcSync;
  // TRegRestore = 508*1/FreqSclk
  TRegRestore = 508 * TSclk;
  // TPgfsmCleanUp = 3*1/FreqSclk
  TPgfsmCleanUp = 3 * TSclk;
  // TGmcPu = TPUCmd + TPgfsmCmdSerialization + TReset + TMoPso + TDaPso + TMemSD + TIso + TRegRestore
  TGmcPu = TPuCmd + TPgfsmCmdSerialization + TReset + TMoPso + TDaPso + TMemSd + TIso + TRegRestore;
  // TGmcPd = THandshake + TPgfsmCmdSerialization + Tiso + TmemSD + TMoPso + TDaPso + TpgfsmCleanUp + 3*TReset
  TGmcPd = THandshake + TPgfsmCmdSerialization + TIso + TMemSd + TMoPso + TDaPso + TPgfsmCleanUp + (3 * TReset);
  // ulGMCRestoreResetTime = TGmcPu + TGmcPd
  // All calculated times are in .01nS for accuracy.  We can now correct that.
  // By adding 99 and dividing by 100, value is rounded up to next 1 nS
  IntegratedInfoTable->ulGMCRestoreResetTime = (TGmcPd + TGmcPu + 99) / 100;
  IDS_HDT_CONSOLE (GNB_TRACE, "ulGMCRestoreResetTime = %d\n", IntegratedInfoTable->ulGMCRestoreResetTime);
  IDS_HDT_CONSOLE (GNB_TRACE, "GfxCalculateRestoreResetTimeTN Exit\n");
  return AGESA_SUCCESS;
}
Пример #7
0
VOID
GfxIntegratedInfoInitSclkTable (
  IN       PP_FUSE_ARRAY                    *PpFuseArray,
  IN       ATOM_INTEGRATED_SYSTEM_INFO_V6   *IntegratedInfoTable,
  IN       GFX_PLATFORM_CONFIG              *Gfx
  )
{
  UINTN                       Index;
  UINTN                       TargetIndex;
  UINTN                       ValidSclkStateMask;
  UINT8                       TempDID;
  UINT8                       SclkVidArray[4];
  UINTN                       AvailSclkIndex;
  ATOM_AVAILABLE_SCLK_LIST    *AvailSclkList;
  BOOLEAN                     Sorting;
  AvailSclkList = &IntegratedInfoTable->sAvail_SCLK[0];
  GnbLibPciRead (
    MAKE_SBDFO ( 0, 0, 0x18, 3, D18F3x15C_ADDRESS),
    AccessWidth32,
    &SclkVidArray[0],
    GnbLibGetHeader (Gfx)
    );
  AvailSclkIndex = 0;
  for (Index = 0; Index < MAX_NUM_OF_FUSED_DPM_STATES; Index++) {
    if (PpFuseArray->SclkDpmDid[Index] != 0) {
      AvailSclkList[AvailSclkIndex].ulSupportedSCLK = GfxLibCalculateClk (PpFuseArray->SclkDpmDid[Index], IntegratedInfoTable->ulDentistVCOFreq);
      AvailSclkList[AvailSclkIndex].usVoltageIndex = PpFuseArray->SclkDpmVid[Index];
      AvailSclkList[AvailSclkIndex].usVoltageID = SclkVidArray [PpFuseArray->SclkDpmVid[Index]];
      AvailSclkIndex++;
    }
  }
  //Sort by VoltageIndex & ulSupportedSCLK
  do {
    Sorting = FALSE;
    for (Index = 0; Index < (AvailSclkIndex - 1); Index++) {
      ATOM_AVAILABLE_SCLK_LIST  Temp;
      BOOLEAN                   Exchange;
      Exchange = FALSE;
      if (AvailSclkList[Index].usVoltageIndex > AvailSclkList[Index + 1].usVoltageIndex) {
        Exchange = TRUE;
      }
      if ((AvailSclkList[Index].usVoltageIndex == AvailSclkList[Index + 1].usVoltageIndex) &&
          (AvailSclkList[Index].ulSupportedSCLK > AvailSclkList[Index + 1].ulSupportedSCLK)) {
        Exchange = TRUE;
      }
      if (Exchange) {
        Sorting = TRUE;
        LibAmdMemCopy (&Temp, &AvailSclkList[Index], sizeof (ATOM_AVAILABLE_SCLK_LIST), GnbLibGetHeader (Gfx));
        LibAmdMemCopy (&AvailSclkList[Index], &AvailSclkList[Index + 1], sizeof (ATOM_AVAILABLE_SCLK_LIST), GnbLibGetHeader (Gfx));
        LibAmdMemCopy (&AvailSclkList[Index + 1], &Temp, sizeof (ATOM_AVAILABLE_SCLK_LIST), GnbLibGetHeader (Gfx));
      }
    }
  } while (Sorting);

  if (PpFuseArray->GpuBoostCap == 1) {
    IntegratedInfoTable->SclkDpmThrottleMargin = PpFuseArray->SclkDpmThrottleMargin;
    IntegratedInfoTable->SclkDpmTdpLimitPG = PpFuseArray->SclkDpmTdpLimitPG;
    IntegratedInfoTable->EnableBoost = PpFuseArray->GpuBoostCap;
    IntegratedInfoTable->SclkDpmBoostMargin = PpFuseArray->SclkDpmBoostMargin;
    IntegratedInfoTable->SclkDpmTdpLimitBoost = (PpFuseArray->SclkDpmTdpLimit)[5];
    IntegratedInfoTable->ulBoostEngineCLock = GfxFmCalculateClock ((PpFuseArray->SclkDpmDid)[5], GnbLibGetHeader (Gfx));
    IntegratedInfoTable->ulBoostVid_2bit = (PpFuseArray->SclkDpmVid)[5];

    ValidSclkStateMask = 0;
    TargetIndex = 0;
    for (Index = 0; Index < 6; Index++) {
      ValidSclkStateMask |= (PpFuseArray->SclkDpmValid)[Index];
    }
    TempDID = 0x7F;
    for (Index = 0; Index < 6; Index++) {
      if ((ValidSclkStateMask & ((UINTN)1 << Index)) != 0) {
        if ((PpFuseArray->SclkDpmDid)[Index] <= TempDID) {
          TempDID = (PpFuseArray->SclkDpmDid)[Index];
          TargetIndex = Index;
        }
      }
    }
    IntegratedInfoTable->GnbTdpLimit = (PpFuseArray->SclkDpmTdpLimit)[TargetIndex];
  }

}
Пример #8
0
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;
}