AGESA F15: AMD family15 AGESA code
[coreboot.git] / src / vendorcode / amd / agesa / f15 / Proc / CPU / Family / 0x10 / F10PmDualPlaneOnlySupport.c
1 /* $NoKeywords:$ */
2 /**
3  * @file
4  *
5  * AMD Family_10 Dual-plane Only Support
6  *
7  * Performs the "BIOS Configuration for Dual-plane Only Support" as
8  * described in the BKDG.
9  *
10  * @xrefitem bom "File Content Label" "Release Content"
11  * @e project:      AGESA
12  * @e sub-project:  CPU/F10
13  * @e \$Revision: 56279 $   @e \$Date: 2011-07-11 13:11:28 -0600 (Mon, 11 Jul 2011) $
14  *
15  */
16 /*
17  ******************************************************************************
18  *
19  * Copyright (C) 2012 Advanced Micro Devices, Inc.
20  * All rights reserved.
21  *
22  * Redistribution and use in source and binary forms, with or without
23  * modification, are permitted provided that the following conditions are met:
24  *     * Redistributions of source code must retain the above copyright
25  *       notice, this list of conditions and the following disclaimer.
26  *     * Redistributions in binary form must reproduce the above copyright
27  *       notice, this list of conditions and the following disclaimer in the
28  *       documentation and/or other materials provided with the distribution.
29  *     * Neither the name of Advanced Micro Devices, Inc. nor the names of
30  *       its contributors may be used to endorse or promote products derived
31  *       from this software without specific prior written permission.
32  *
33  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
34  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
35  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
36  * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
37  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
38  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
39  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
40  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
41  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
42  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43  *
44  ******************************************************************************
45  */
46
47 /*----------------------------------------------------------------------------------------
48  *                             M O D U L E S    U S E D
49  *----------------------------------------------------------------------------------------
50  */
51 #include "AGESA.h"
52 #include "amdlib.h"
53 #include "cpuRegisters.h"
54 #include "cpuApicUtilities.h"
55 #include "cpuServices.h"
56 #include "GeneralServices.h"
57 #include "cpuFamilyTranslation.h"
58 #include "cpuF10PowerMgmt.h"
59 #include "F10PmDualPlaneOnlySupport.h"
60 #include "F10PackageType.h"
61 #include "OptionMultiSocket.h"
62 #include "Filecode.h"
63 CODE_GROUP (G1_PEICC)
64 RDATA_GROUP (G2_PEI)
65
66 #define FILECODE PROC_CPU_FAMILY_0X10_F10PMDUALPLANEONLYSUPPORT_FILECODE
67
68 /*----------------------------------------------------------------------------------------
69  *                   D E F I N I T I O N S    A N D    M A C R O S
70  *----------------------------------------------------------------------------------------
71  */
72 extern OPTION_MULTISOCKET_CONFIGURATION OptionMultiSocketConfiguration;
73 /*----------------------------------------------------------------------------------------
74  *                  T Y P E D E F S     A N D     S T R U C T U R E S
75  *----------------------------------------------------------------------------------------
76  */
77
78 /*----------------------------------------------------------------------------------------
79  *           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
80  *----------------------------------------------------------------------------------------
81  */
82 UINT32
83 STATIC
84 SetPstateMSR (
85   IN       VOID  *CPB,
86   IN       AMD_CONFIG_PARAMS *StdHeader
87   );
88
89 /*----------------------------------------------------------------------------------------
90  *                          E X P O R T E D    F U N C T I O N S
91  *----------------------------------------------------------------------------------------
92  */
93
94 /*---------------------------------------------------------------------------------------*/
95 /**
96  * Family 10h core 0 entry point for performing the "Dual-plane Only Support" algorithm.
97  *
98  * The algorithm is as follows:
99  *    // Determine whether algorithm applies to this processor
100  *    if (CPUID Fn8000_0001_EBX[PkgType] == 0001b && (revision C or E) {
101  *        // Determine whether processor is supported in this infrastructure
102  *        if (((F3x1FC[DualPlaneOnly] == 1) && (this is a dual-plane platform))
103  *            || ((F3x1FC[AM3r2Only] == 1) && (this is an AM3r2 platform))) {
104  *            // Fixup the P-state MSRs
105  *            for (each core in the system) {
106  *            if (CPUID Fn8000_0007[CPB]) {
107  *                Copy MSRC001_0065 as MinPstate;
108  *                Copy MSRC001_0068 to MSRC001_0065;
109  *                Copy MinPstate to MSRC001_0068;
110  *            } else {
111  *                Copy MSRC001_0068 to MSRC001_0064;
112  *                Program MSRC001_0068 = 0;
113  *            } // endif
114  *            for (each MSR in MSRC001_00[68:64]) {
115  *                if (value in MSRC001_00[68:64][IddValue] != 0) {
116  *                    Set PstateEn in current MSR to 1;
117  *                } // endif
118  *            } // endfor
119  *        } // endfor
120  *        Set F3xDC[PstateMaxVal] = lowest-performance enabled P-state;
121  *        Set F3xA8[PopDownPstate] = lowest-performance enabled P-state;
122  *        Set F3x64[HtcPstateLimit] = lowest-performance enabled P-state;
123  *        } // endif
124  *    } // endif
125  *
126  * @param[in]  FamilySpecificServices  The current Family Specific Services.
127  * @param[in]  CpuEarlyParamsPtr       Service related parameters (unused).
128  * @param[in]  StdHeader               Config handle for library and services.
129  *
130  */
131 VOID
132 F10PmDualPlaneOnlySupport (
133   IN       CPU_SPECIFIC_SERVICES *FamilySpecificServices,
134   IN       AMD_CPU_EARLY_PARAMS  *CpuEarlyParamsPtr,
135   IN       AMD_CONFIG_PARAMS     *StdHeader
136   )
137 {
138   AP_TASK                 TaskPtr;
139   UINT32                  CPB;
140   UINT32                  Core;
141   UINT32                  Pvimode;
142   UINT32                  LowestPsEn;
143   UINT32                  LocalPciRegister;
144   UINT32                  ActiveCores;
145   UINT32                  ProcessorPackageType;
146   PCI_ADDR                PciAddress;
147   CPUID_DATA              CpuidData;
148   CPU_LOGICAL_ID          LogicalId;
149
150   OptionMultiSocketConfiguration.GetCurrPciAddr (&PciAddress, StdHeader);
151
152   // get the package type
153   ProcessorPackageType = LibAmdGetPackageType (StdHeader);
154   GetLogicalIdOfCurrentCore (&LogicalId, StdHeader);
155   if (((LogicalId.Revision & (AMD_F10_Cx | AMD_F10_Ex)) != 0) && ((ProcessorPackageType & PACKAGE_TYPE_AM2R2_AM3) != 0)) {
156     PciAddress.AddressValue = PRCT_INFO_PCI_ADDR;
157     LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
158     PciAddress.AddressValue = PW_CTL_MISC_PCI_ADDR;
159     LibAmdPciRead (AccessWidth32, PciAddress, &Pvimode, StdHeader);
160     if ((((LocalPciRegister & 0x80000000) != 0) && (((POWER_CTRL_MISC_REGISTER *) &Pvimode)->PviMode == 0))
161       || ((LocalPciRegister & 0x04000000) != 0)) {
162       CPB = 0;
163       LibAmdCpuidRead (AMD_CPUID_APM, &CpuidData, StdHeader);
164       if (((CpuidData.EDX_Reg & 0x00000200) >> 9) == 1) {
165         CPB = 1;
166       }
167
168       TaskPtr.FuncAddress.PfApTaskIO = SetPstateMSR;
169       TaskPtr.ExeFlags = TASK_HAS_OUTPUT | WAIT_FOR_CORE;
170       TaskPtr.DataTransfer.DataTransferFlags = 0;
171       TaskPtr.DataTransfer.DataSizeInDwords = 1;
172       TaskPtr.DataTransfer.DataPtr = &CPB;
173
174       GetActiveCoresInCurrentSocket (&ActiveCores, StdHeader);
175       for (Core = 1; Core < (UINT8) ActiveCores; ++Core) {
176         ApUtilRunCodeOnSocketCore ((UINT8)0, (UINT8)Core, &TaskPtr, StdHeader);
177       }
178       LowestPsEn = ApUtilTaskOnExecutingCore (&TaskPtr, StdHeader, (VOID *) CpuEarlyParamsPtr);
179
180       PciAddress.AddressValue = CPTC2_PCI_ADDR;
181       LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
182       ((CLK_PWR_TIMING_CTRL2_REGISTER *) &LocalPciRegister)->PstateMaxVal = LowestPsEn;
183       LibAmdPciWrite (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
184
185       PciAddress.AddressValue = POPUP_PSTATE_PCI_ADDR;
186       LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
187       ((POPUP_PSTATE_REGISTER *) &LocalPciRegister)->PopDownPstate = LowestPsEn;
188       LibAmdPciWrite (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
189
190       PciAddress.AddressValue = HTC_PCI_ADDR;
191       LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
192       ((HTC_REGISTER *) &LocalPciRegister)->HtcPstateLimit = LowestPsEn;
193       LibAmdPciWrite (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
194     }
195   }
196 }
197 /*---------------------------------------------------------------------------------------*/
198 /**
199  * Set P-State MSR.
200  *
201  * This function set the P-state MSRs per each core in the system.
202  *
203  * @param[in]  CPB               Contains the value of Asymmetric Boost register
204  * @param[in]  StdHeader         Config handle for library and services
205  *
206  * @return         Return the lowest-performance enabled P-state
207  */
208 UINT32
209 STATIC
210 SetPstateMSR (
211   IN       VOID  *CPB,
212   IN       AMD_CONFIG_PARAMS *StdHeader
213   )
214 {
215   UINT32 dtemp;
216   UINT32 LowestPsEn;
217   UINT64 MsrValue;
218   UINT64 MinMsrValue;
219
220   if (*(UINT32*) CPB != 0) {
221     LibAmdMsrRead (MSR_PSTATE_1, &MinMsrValue, StdHeader);
222     LibAmdMsrRead (MSR_PSTATE_4, &MsrValue, StdHeader);
223     LibAmdMsrWrite (MSR_PSTATE_1, &MsrValue, StdHeader);
224     LibAmdMsrWrite (MSR_PSTATE_4, &MinMsrValue, StdHeader);
225   } else {
226     LibAmdMsrRead (MSR_PSTATE_4, &MsrValue, StdHeader);
227     LibAmdMsrWrite (MSR_PSTATE_0, &MsrValue, StdHeader);
228     MsrValue = 0;
229     LibAmdMsrWrite (MSR_PSTATE_4, &MsrValue, StdHeader);
230   }
231
232   LowestPsEn = 0;
233   for (dtemp = MSR_PSTATE_0; dtemp <= MSR_PSTATE_4; dtemp++) {
234     LibAmdMsrRead (dtemp, &MsrValue, StdHeader);
235     if (((PSTATE_MSR *) &MsrValue)->IddValue != 0) {
236       MsrValue = MsrValue | BIT63;
237       LibAmdMsrWrite (dtemp, &MsrValue, StdHeader);
238       LowestPsEn =  dtemp - MSR_PSTATE_0;
239     }
240   }
241   return (LowestPsEn);
242 }
243