| /* $NoKeywords:$ */ |
| /** |
| * @file |
| * |
| * AMD Family_16 Kabini PSI Initialization |
| * |
| * Enables Power Status Indicator (PSI) feature |
| * |
| * @xrefitem bom "File Content Label" "Release Content" |
| * @e project: AGESA |
| * @e sub-project: CPU/Family/0x16/KB |
| * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ |
| * |
| */ |
| /* |
| ****************************************************************************** |
| * |
| * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are met: |
| * * Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * * Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * * Neither the name of Advanced Micro Devices, Inc. nor the names of |
| * its contributors may be used to endorse or promote products derived |
| * from this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY |
| * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| ****************************************************************************** |
| */ |
| |
| /*---------------------------------------------------------------------------------------- |
| * M O D U L E S U S E D |
| *---------------------------------------------------------------------------------------- |
| */ |
| #include "AGESA.h" |
| #include "amdlib.h" |
| #include "cpuRegisters.h" |
| #include "cpuF16PowerMgmt.h" |
| #include "F16KbPowerMgmt.h" |
| #include "cpuFeatures.h" |
| #include "cpuServices.h" |
| #include "GeneralServices.h" |
| #include "cpuFamilyTranslation.h" |
| #include "CommonReturns.h" |
| #include "cpuPsi.h" |
| #include "Filecode.h" |
| CODE_GROUP (G2_PEI) |
| RDATA_GROUP (G2_PEI) |
| |
| #define FILECODE PROC_CPU_FAMILY_0X16_KB_F16KBPSI_FILECODE |
| |
| /*---------------------------------------------------------------------------------------- |
| * D E F I N I T I O N S A N D M A C R O S |
| *---------------------------------------------------------------------------------------- |
| */ |
| |
| /*---------------------------------------------------------------------------------------- |
| * T Y P E D E F S A N D S T R U C T U R E S |
| *---------------------------------------------------------------------------------------- |
| */ |
| |
| /*---------------------------------------------------------------------------------------- |
| * P R O T O T Y P E S O F L O C A L F U N C T I O N S |
| *---------------------------------------------------------------------------------------- |
| */ |
| |
| VOID |
| STATIC |
| F16KbPmVrmLowPowerModeEnable ( |
| IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, |
| IN PLATFORM_CONFIGURATION *PlatformConfig, |
| IN PCI_ADDR PciAddress, |
| IN AMD_CONFIG_PARAMS *StdHeader |
| ); |
| |
| /*---------------------------------------------------------------------------------------- |
| * E X P O R T E D F U N C T I O N S |
| *---------------------------------------------------------------------------------------- |
| */ |
| |
| /*---------------------------------------------------------------------------------------*/ |
| /** |
| * Entry point for enabling Power Status Indicator |
| * |
| * This function must be run after all P-State routines have been executed |
| * |
| * @param[in] PsiServices The current CPU's family services. |
| * @param[in] EntryPoint Timepoint designator. |
| * @param[in] PlatformConfig Contains the runtime modifiable feature input data. |
| * @param[in] StdHeader Config handle for library and services. |
| * |
| * @retval AGESA_SUCCESS Always succeeds. |
| * |
| */ |
| AGESA_STATUS |
| STATIC |
| F16KbInitializePsi ( |
| IN PSI_FAMILY_SERVICES *PsiServices, |
| IN UINT64 EntryPoint, |
| IN PLATFORM_CONFIGURATION *PlatformConfig, |
| IN AMD_CONFIG_PARAMS *StdHeader |
| ) |
| { |
| PCI_ADDR PciAddress; |
| CPU_SPECIFIC_SERVICES *FamilySpecificServices; |
| |
| if ((EntryPoint & (CPU_FEAT_AFTER_POST_MTRR_SYNC | CPU_FEAT_AFTER_RESUME_MTRR_SYNC)) != 0) { |
| GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader); |
| PciAddress.AddressValue = MAKE_SBDFO (0, 0, 24, 0, 0); |
| // Configure PsiVid |
| F16KbPmVrmLowPowerModeEnable (FamilySpecificServices, PlatformConfig, PciAddress, StdHeader); |
| } |
| |
| return AGESA_SUCCESS; |
| } |
| |
| |
| /*---------------------------------------------------------------------------------------*/ |
| /** |
| * 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 |
| F16KbPmVrmLowPowerModeEnable ( |
| 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, " F16KbPmVrmLowPowerModeEnable\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.HwPstateMaxVal; |
| 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) GetF16KbNbVid (&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; |
| } |
| } |
| } |
| } |
| |
| |
| CONST PSI_FAMILY_SERVICES ROMDATA F16KbPsiSupport = |
| { |
| 0, |
| (PF_PSI_IS_SUPPORTED) CommonReturnTrue, |
| F16KbInitializePsi |
| }; |