/** * Family 15h Trinity core 0 entry point for performing the necessary Nb P-state VID adjustment * after a cold reset has occurred. * * @param[in] FamilySpecificServices The current Family Specific Services. * @param[in] CpuEarlyParamsPtr Service parameters * @param[in] StdHeader Config handle for library and services. * */ VOID F15TnNbPstateVidAdjustAfterReset ( IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, IN AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr, IN AMD_CONFIG_PARAMS *StdHeader ) { PCI_ADDR PciAddress; BOOLEAN NeitherHiNorLo; NB_PSTATE_REGISTER NbPsReg; UINT32 NbPsVid; UINT32 i; NB_PSTATE_CTRL_REGISTER NbPsCtrl; NB_PSTATE_CTRL_REGISTER NbPsCtrlSave; NB_PSTATE_STS_REGISTER NbPsSts; CLK_PWR_TIMING_CTRL_5_REGISTER ClkPwrTimgCtrl5; D0F0xBC_x1F400_STRUCT D0F0xBC_x1F400; // Check if D18F5x188[NbOffsetTrim] has been programmed to 01b (-25mV) PciAddress.AddressValue = CPTC5_PCI_ADDR; LibAmdPciRead (AccessWidth32, PciAddress, &ClkPwrTimgCtrl5, StdHeader); if (ClkPwrTimgCtrl5.NbOffsetTrim == 1) { return; } // Add 25mV (-4 VID steps) to all VddNb VIDs. PciAddress.AddressValue = NB_PSTATE_0_PCI_ADDR; for (i = 0; i < NM_NB_PS_REG; i++) { PciAddress.Address.Register = NB_PSTATE_0 + (i * 4); LibAmdPciRead (AccessWidth32, PciAddress, &NbPsReg, StdHeader); if (NbPsReg.NbPstateEn == 1) { NbPsVid = GetF15TnNbVid (&NbPsReg); NbPsVid -= 4; SetF15TnNbVid (&NbPsReg, &NbPsVid); LibAmdPciWrite (AccessWidth32, PciAddress, &NbPsReg, StdHeader); } } // Check if D18F5x174[CurNbPstate] equals NbPstateHi or NbPstateLo PciAddress.Address.Register = NB_PSTATE_STATUS; LibAmdPciRead (AccessWidth32, PciAddress, &NbPsSts, StdHeader); PciAddress.Address.Register = NB_PSTATE_CTRL; LibAmdPciRead (AccessWidth32, PciAddress, &NbPsCtrl, StdHeader); // Save NB P-state control setting NbPsCtrlSave = NbPsCtrl; // Force a NB P-state Transition. NeitherHiNorLo = FALSE; if (NbPsSts.CurNbPstate == NbPsCtrl.NbPstateHi) { TransitionToNbLow (PciAddress, StdHeader); } else if (NbPsSts.CurNbPstate == NbPsCtrl.NbPstateLo) { TransitionToNbHigh (PciAddress, StdHeader); } else { NeitherHiNorLo = TRUE; } // Set OffsetTrim to -25mV: // D18F5x188[NbOffsetTrim]=01b (-25mV) // D0F0xBC_x1F400[SviLoadLineOffsetVddNB]=01b (-25mV) PciAddress.Address.Register = CPTC5_REG; LibAmdPciRead (AccessWidth32, PciAddress, &ClkPwrTimgCtrl5, StdHeader); ClkPwrTimgCtrl5.NbOffsetTrim = 1; LibAmdPciWrite (AccessWidth32, PciAddress, &ClkPwrTimgCtrl5, StdHeader); GnbRegisterReadTN (D0F0xBC_x1F400_TYPE, D0F0xBC_x1F400_ADDRESS, &D0F0xBC_x1F400, 0, StdHeader); D0F0xBC_x1F400.Field.SviLoadLineOffsetVddNB = 1; GnbRegisterWriteTN (D0F0xBC_x1F400_TYPE, D0F0xBC_x1F400_ADDRESS, &D0F0xBC_x1F400, 0, StdHeader); // Unforce NB P-state back to CurNbPstate value upon entry. if (NeitherHiNorLo || (NbPsSts.CurNbPstate == NbPsCtrl.NbPstateHi)) { TransitionToNbHigh (PciAddress, StdHeader); } else { // if (NbPsSts.CurNbPstate == NbPsCtrl.NbPstateLo) TransitionToNbLow (PciAddress, StdHeader); } // Restore NB P-state control setting PciAddress.Address.Register = NB_PSTATE_CTRL; NbPsCtrl = NbPsCtrlSave; LibAmdPciWrite (AccessWidth32, PciAddress, &NbPsCtrl, StdHeader); }
/** * Sets up PSI_L operation. * * This function implements the LowPowerThreshold parameter. * * @param[in] FamilySpecificServices The current Family Specific Services. * @param[in] PlatformConfig Contains the runtime modifiable feature input data. * @param[in] PciAddress Segment, bus, device number of the node to transition. * @param[in] StdHeader Config handle for library and services. * */ VOID STATIC F15TnPmVrmLowPowerModeEnable ( IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, IN PLATFORM_CONFIGURATION *PlatformConfig, IN PCI_ADDR PciAddress, IN AMD_CONFIG_PARAMS *StdHeader ) { PSTATE_MSR PstateMsr; CLK_PWR_TIMING_CTRL2_REGISTER ClkPwrTimingCtrl2; POWER_CTRL_MISC_REGISTER PwrCtrlMisc; UINT32 CoreVrmLowPowerThreshold; UINT32 Pstate; UINT32 HwPstateMaxVal; UINT32 PstateCurrent; UINT32 NextPstateCurrent; UINT32 PreviousVid; UINT32 CurrentVid; NB_PSTATE_REGISTER NbPstateReg; NB_PSTATE_CTRL_REGISTER NbPsCtrl; MISC_VOLTAGE_REGISTER MiscVoltageReg; UINT32 NbVrmLowPowerThreshold; UINT32 NbPstate; UINT32 NbPstateMaxVal; UINT32 NbPstateCurrent; UINT32 NextNbPstateCurrent; UINT32 PreviousNbVid; UINT32 CurrentNbVid; IDS_HDT_CONSOLE (CPU_TRACE, " F15TnPmVrmLowPowerModeEnable\n"); if (PlatformConfig->VrmProperties[CoreVrm].LowPowerThreshold != 0) { // Set up PSI0_L for VDD CoreVrmLowPowerThreshold = PlatformConfig->VrmProperties[CoreVrm].LowPowerThreshold; IDS_HDT_CONSOLE (CPU_TRACE, " Core VRM - LowPowerThreshold: %d\n", CoreVrmLowPowerThreshold); PreviousVid = 0xFF; CurrentVid = 0xFF; PciAddress.AddressValue = CPTC2_PCI_ADDR; LibAmdPciRead (AccessWidth32, PciAddress, &ClkPwrTimingCtrl2, StdHeader); HwPstateMaxVal = ClkPwrTimingCtrl2.PstateMaxVal; ASSERT (HwPstateMaxVal < NM_PS_REG); IDS_HDT_CONSOLE (CPU_TRACE, " HwPstateMaxVal %d\n", HwPstateMaxVal); // Check P-state from P0 to HwPstateMaxVal for (Pstate = 0; Pstate <= HwPstateMaxVal; Pstate++) { FamilySpecificServices->GetProcIddMax (FamilySpecificServices, (UINT8) Pstate, &PstateCurrent, StdHeader); LibAmdMsrRead ((UINT32) (Pstate + PS_REG_BASE), (UINT64 *) &PstateMsr, StdHeader); CurrentVid = (UINT32) PstateMsr.CpuVid; if (Pstate == HwPstateMaxVal) { NextPstateCurrent = 0; } else { // Check P-state from P1 to HwPstateMaxVal FamilySpecificServices->GetProcIddMax (FamilySpecificServices, (UINT8) (Pstate + 1), &NextPstateCurrent, StdHeader); } if ((PstateCurrent <= CoreVrmLowPowerThreshold) && (NextPstateCurrent <= CoreVrmLowPowerThreshold) && (CurrentVid != PreviousVid)) { // Program PsiVid and PsiVidEn if PSI state is found and stop searching. PciAddress.AddressValue = PW_CTL_MISC_PCI_ADDR; LibAmdPciRead (AccessWidth32, PciAddress, &PwrCtrlMisc, StdHeader); PwrCtrlMisc.PsiVid = CurrentVid; PwrCtrlMisc.PsiVidEn = 1; LibAmdPciWrite (AccessWidth32, PciAddress, &PwrCtrlMisc, StdHeader); IDS_HDT_CONSOLE (CPU_TRACE, " PsiVid is enabled at P-state %d. PsiVid: %d\n", Pstate, CurrentVid); break; } else { PstateCurrent = NextPstateCurrent; PreviousVid = CurrentVid; } } } if (PlatformConfig->VrmProperties[NbVrm].LowPowerThreshold != 0) { // Set up NBPSI0_L for VDDNB NbVrmLowPowerThreshold = PlatformConfig->VrmProperties[NbVrm].LowPowerThreshold; IDS_HDT_CONSOLE (CPU_TRACE, " NB VRM - LowPowerThreshold: %d\n", NbVrmLowPowerThreshold); PreviousNbVid = 0xFF; CurrentNbVid = 0xFF; PciAddress.AddressValue = NB_PSTATE_CTRL_PCI_ADDR; LibAmdPciRead (AccessWidth32, PciAddress, &NbPsCtrl, StdHeader); NbPstateMaxVal = NbPsCtrl.NbPstateMaxVal; ASSERT (NbPstateMaxVal < NM_NB_PS_REG); IDS_HDT_CONSOLE (CPU_TRACE, " NbPstateMaxVal %d\n", NbPstateMaxVal); for (NbPstate = 0; NbPstate <= NbPstateMaxVal; NbPstate++) { // Check only valid NB P-state if (FamilySpecificServices->GetNbIddMax (FamilySpecificServices, (UINT8) NbPstate, &NbPstateCurrent, StdHeader) != TRUE) { continue; } PciAddress.Address.Register = (NB_PSTATE_0 + (sizeof (NB_PSTATE_REGISTER) * NbPstate)); LibAmdPciRead (AccessWidth32, PciAddress, &NbPstateReg, StdHeader); CurrentNbVid = (UINT32) GetF15TnNbVid (&NbPstateReg); if (NbPstate == NbPstateMaxVal) { NextNbPstateCurrent = 0; } else { // Check only valid NB P-state if (FamilySpecificServices->GetNbIddMax (FamilySpecificServices, (UINT8) (NbPstate + 1), &NextNbPstateCurrent, StdHeader) != TRUE) { continue; } } if ((NbPstateCurrent <= NbVrmLowPowerThreshold) && (NextNbPstateCurrent <= NbVrmLowPowerThreshold) && (CurrentNbVid != PreviousNbVid)) { // Program NbPsi0Vid and NbPsi0VidEn if PSI state is found and stop searching. PciAddress.AddressValue = MISC_VOLTAGES_PCI_ADDR; LibAmdPciRead (AccessWidth32, PciAddress, &MiscVoltageReg, StdHeader); MiscVoltageReg.NbPsi0Vid = CurrentNbVid; MiscVoltageReg.NbPsi0VidEn = 1; LibAmdPciWrite (AccessWidth32, PciAddress, &MiscVoltageReg, StdHeader); IDS_HDT_CONSOLE (CPU_TRACE, " NbPsi0Vid is enabled at NB P-state %d. NbPsi0Vid: %d\n", NbPstate, CurrentNbVid); break; } else { PreviousNbVid = CurrentNbVid; } } } }