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]; }
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); } }
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); } }
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; } } }
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; } } }
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; }
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]; } }
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; }