AGESA F15: AMD family15 AGESA code
[coreboot.git] / src / vendorcode / amd / agesa / f15 / Proc / CPU / cpuPowerMgmtSingleSocket.c
1 /* $NoKeywords:$ */
2 /**
3  * @file
4  *
5  * AMD CPU Power Management Single Socket Functions.
6  *
7  * Contains code for doing power management for single socket CPU
8  *
9  * @xrefitem bom "File Content Label" "Release Content"
10  * @e project:      AGESA
11  * @e sub-project:  CPU
12  * @e \$Revision: 56322 $   @e \$Date: 2011-07-11 16:51:42 -0600 (Mon, 11 Jul 2011) $
13  *
14  */
15 /*
16  ******************************************************************************
17  *
18  * Copyright (C) 2012 Advanced Micro Devices, Inc.
19  * All rights reserved.
20  *
21  * Redistribution and use in source and binary forms, with or without
22  * modification, are permitted provided that the following conditions are met:
23  *     * Redistributions of source code must retain the above copyright
24  *       notice, this list of conditions and the following disclaimer.
25  *     * Redistributions in binary form must reproduce the above copyright
26  *       notice, this list of conditions and the following disclaimer in the
27  *       documentation and/or other materials provided with the distribution.
28  *     * Neither the name of Advanced Micro Devices, Inc. nor the names of
29  *       its contributors may be used to endorse or promote products derived
30  *       from this software without specific prior written permission.
31  *
32  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
33  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
34  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
35  * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
36  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
37  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
38  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
39  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
40  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
41  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42  *
43  ******************************************************************************
44  */
45
46 /*----------------------------------------------------------------------------------------
47  *                             M O D U L E S    U S E D
48  *----------------------------------------------------------------------------------------
49  */
50
51 #include "AGESA.h"
52 #include "amdlib.h"
53 #include "GeneralServices.h"
54 #include "cpuRegisters.h"
55 #include "cpuApicUtilities.h"
56 #include "cpuFamilyTranslation.h"
57 #include "cpuPowerMgmtSystemTables.h"
58 #include "cpuPowerMgmtSingleSocket.h"
59 #include "Filecode.h"
60 CODE_GROUP (G1_PEICC)
61 RDATA_GROUP (G2_PEI)
62
63 #define FILECODE PROC_CPU_CPUPOWERMGMTSINGLESOCKET_FILECODE
64 /*----------------------------------------------------------------------------------------
65  *                   D E F I N I T I O N S    A N D    M A C R O S
66  *----------------------------------------------------------------------------------------
67  */
68
69 /*----------------------------------------------------------------------------------------
70  *                  T Y P E D E F S     A N D     S T R U C T U R E S
71  *----------------------------------------------------------------------------------------
72  */
73
74 /*----------------------------------------------------------------------------------------
75  *           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
76  *----------------------------------------------------------------------------------------
77  */
78
79 /*----------------------------------------------------------------------------------------
80  *                          E X P O R T E D    F U N C T I O N S
81  *----------------------------------------------------------------------------------------
82  */
83
84 /*---------------------------------------------------------------------------------------*/
85 /**
86  * Single socket BSC call to start all system core 0s to perform a standard AP_TASK.
87  *
88  * This function will simply invoke the task on the executing core.  This must be
89  * run by the system BSC only.
90  *
91  * @param[in]  TaskPtr           Function descriptor
92  * @param[in]  StdHeader         Config handle for library and services
93  * @param[in]  ConfigParams      AMD entry point's CPU parameter structure
94  *
95  */
96 VOID
97 RunCodeOnAllSystemCore0sSingle (
98   IN       AP_TASK *TaskPtr,
99   IN       AMD_CONFIG_PARAMS *StdHeader,
100   IN       VOID *ConfigParams
101   )
102 {
103   ApUtilTaskOnExecutingCore (TaskPtr, StdHeader, ConfigParams);
104 }
105
106
107 /*---------------------------------------------------------------------------------------*/
108 /**
109  * Single socket BSC call to determine the maximum number of steps that any single
110  * processor needs to execute.
111  *
112  * This function simply returns the number of steps that the BSC needs.
113  *
114  * @param[out] NumSystemSteps    Maximum number of system steps required
115  * @param[in]  StdHeader         Config handle for library and services
116  *
117  */
118 VOID
119 GetNumberOfSystemPmStepsPtrSingle (
120      OUT   UINT8 *NumSystemSteps,
121   IN       AMD_CONFIG_PARAMS   *StdHeader
122   )
123 {
124   SYS_PM_TBL_STEP *Ignored;
125   CPU_SPECIFIC_SERVICES *FamilySpecificServices;
126
127   GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader);
128   FamilySpecificServices->GetSysPmTableStruct (FamilySpecificServices, (CONST VOID **) &Ignored, NumSystemSteps, StdHeader);
129 }
130
131
132 /*---------------------------------------------------------------------------------------*/
133 /**
134  * Single socket call to determine the frequency that the northbridges must run.
135  *
136  * This function simply returns the executing core's NB frequency, and that all
137  * NB frequencies are equivalent.
138  *
139  * @param[in]  NbPstate                    NB P-state number to check (0 = fastest)
140  * @param[in]  PlatformConfig              Platform profile/build option config structure.
141  * @param[out] SystemNbCofNumerator        NB frequency numerator for the system in MHz
142  * @param[out] SystemNbCofDenominator      NB frequency denominator for the system
143  * @param[out] SystemNbCofsMatch           Whether or not all NB frequencies are equivalent
144  * @param[out] NbPstateIsEnabledOnAllCPUs  Whether or not NbPstate is valid on all CPUs
145  * @param[in]  StdHeader                   Config handle for library and services
146  *
147  * @retval     TRUE                        At least one processor has NbPstate enabled.
148  * @retval     FALSE                       NbPstate is disabled on all CPUs
149  *
150  */
151 BOOLEAN
152 GetSystemNbCofSingle (
153   IN       UINT32 NbPstate,
154   IN       PLATFORM_CONFIGURATION *PlatformConfig,
155      OUT   UINT32 *SystemNbCofNumerator,
156      OUT   UINT32 *SystemNbCofDenominator,
157      OUT   BOOLEAN *SystemNbCofsMatch,
158      OUT   BOOLEAN *NbPstateIsEnabledOnAllCPUs,
159   IN       AMD_CONFIG_PARAMS *StdHeader
160   )
161 {
162   UINT32 Ignored;
163   PCI_ADDR PciAddress;
164   CPU_SPECIFIC_SERVICES *FamilySpecificServices;
165
166   PciAddress.AddressValue = MAKE_SBDFO (0, 0, 24, 0, 0);
167   *SystemNbCofsMatch = TRUE;
168   GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader);
169   *NbPstateIsEnabledOnAllCPUs = FamilySpecificServices->GetNbPstateInfo (FamilySpecificServices,
170                                                                          PlatformConfig,
171                                                                          &PciAddress,
172                                                                          NbPstate,
173                                                                          SystemNbCofNumerator,
174                                                                          SystemNbCofDenominator,
175                                                                          &Ignored,
176                                                                          StdHeader);
177   return *NbPstateIsEnabledOnAllCPUs;
178 }
179
180
181 /*---------------------------------------------------------------------------------------*/
182 /**
183  * Single socket call to determine if the BIOS is responsible for updating the
184  * northbridge operating frequency and voltage.
185  *
186  * This function simply returns whether or not the executing core needs NB COF
187  * VID programming.
188  *
189  * @param[in]  StdHeader              Config handle for library and services
190  *
191  * @retval     TRUE    BIOS needs to set up NB frequency and voltage
192  * @retval     FALSE   BIOS does not need to set up NB frequency and voltage
193  *
194  */
195 BOOLEAN
196 GetSystemNbCofVidUpdateSingle (
197   IN       AMD_CONFIG_PARAMS *StdHeader
198   )
199 {
200   BOOLEAN   Ignored;
201   PCI_ADDR PciAddress;
202   CPU_SPECIFIC_SERVICES *FamilySpecificServices;
203
204   PciAddress.AddressValue = MAKE_SBDFO (0, 0, 24, 0, 0);
205   GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader);
206   return (FamilySpecificServices->IsNbCofInitNeeded (FamilySpecificServices, &PciAddress, &Ignored, StdHeader));
207 }
208
209
210 /*---------------------------------------------------------------------------------------*/
211 /**
212  * Single socket call to determine the most severe AGESA_STATUS return value after
213  * processing the power management initialization tables.
214  *
215  * This function searches the event log for the most severe error and returns
216  * the status code.  This function must be called by the BSC only.
217  *
218  * @param[in]  StdHeader         Config handle for library and services
219  *
220  * @return     The most severe error code from power management init
221  *
222  */
223 AGESA_STATUS
224 GetEarlyPmErrorsSingle (
225   IN       AMD_CONFIG_PARAMS *StdHeader
226   )
227 {
228   UINT16       i;
229   AGESA_EVENT  EventLogEntry;
230   AGESA_STATUS ReturnCode;
231
232   ASSERT (IsBsp (StdHeader, &ReturnCode));
233
234   ReturnCode = AGESA_SUCCESS;
235   for (i = 0; PeekEventLog (&EventLogEntry, i, StdHeader); i++) {
236     if ((EventLogEntry.EventInfo & CPU_EVENT_PM_EVENT_MASK) == CPU_EVENT_PM_EVENT_CLASS) {
237       if (EventLogEntry.EventClass > ReturnCode) {
238         ReturnCode = EventLogEntry.EventClass;
239       }
240     }
241   }
242
243   return (ReturnCode);
244 }
245
246 /**
247  * Single socket call to loop through all Nb Pstates, comparing the NB frequencies
248  * to determine the slowest in the system. This routine also returns the NB P0 frequency.
249  *
250  * @param[in]  PlatformConfig      Platform profile/build option config structure.
251  * @param[out] MinSysNbFreq        NB frequency numerator for the system in MHz
252  * @param[out] MinP0NbFreq         NB frequency numerator for P0 in MHz
253  * @param[in]  StdHeader           Config handle for library and services
254  */
255 VOID
256 GetMinNbCofSingle (
257   IN       PLATFORM_CONFIGURATION *PlatformConfig,
258      OUT   UINT32                 *MinSysNbFreq,
259      OUT   UINT32                 *MinP0NbFreq,
260   IN       AMD_CONFIG_PARAMS      *StdHeader
261   )
262 {
263   PCI_ADDR              PciAddress;
264   CPU_SPECIFIC_SERVICES *FamilySpecificServices;
265
266   PciAddress.AddressValue = MAKE_SBDFO (0, 0, 24, 0, 0);
267   GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader);
268   FamilySpecificServices->GetMinMaxNbFrequency (FamilySpecificServices,
269                                              PlatformConfig,
270                                              &PciAddress,
271                                              MinSysNbFreq,
272                                              MinP0NbFreq,
273                                              StdHeader);
274 }
275
276 /*---------------------------------------------------------------------------------------*/
277 /**
278  * Get PCI Config Space Address for the current running core.
279  *
280  * @param[out]   PciAddress   The Processor's PCI Config Space address (Function 0, Register 0)
281  * @param[in]    StdHeader    Header for library and services.
282  *
283  * @retval       TRUE         The core is present, PCI Address valid
284  * @retval       FALSE        The core is not present, PCI Address not valid.
285  */
286 BOOLEAN
287 GetCurrPciAddrSingle (
288      OUT   PCI_ADDR               *PciAddress,
289   IN       AMD_CONFIG_PARAMS      *StdHeader
290   )
291 {
292   PciAddress->AddressValue = MAKE_SBDFO (0, 0, 24, 0, 0);
293
294   return TRUE;
295 }
296
297 /*---------------------------------------------------------------------------------------*/
298 /**
299  *  Writes to all nodes on the executing core's socket.
300  *
301  *  @param[in]     PciAddress    The Function and Register to update
302  *  @param[in]     Mask          The bitwise AND mask to apply to the current register value
303  *  @param[in]     Data          The bitwise OR mask to apply to the current register value
304  *  @param[in]     StdHeader     Header for library and services.
305  *
306  */
307 VOID
308 ModifyCurrSocketPciSingle (
309   IN       PCI_ADDR               *PciAddress,
310   IN       UINT32                 Mask,
311   IN       UINT32                 Data,
312   IN       AMD_CONFIG_PARAMS      *StdHeader
313   )
314 {
315   UINT32 LocalPciRegister;
316   PCI_ADDR Reg;
317
318   Reg.AddressValue     = MAKE_SBDFO (0, 0, 24, 0, 0);
319   Reg.Address.Function = PciAddress->Address.Function;
320   Reg.Address.Register = PciAddress->Address.Register;
321   LibAmdPciRead (AccessWidth32, Reg, &LocalPciRegister, StdHeader);
322   LocalPciRegister &= Mask;
323   LocalPciRegister |= Data;
324   LibAmdPciWrite (AccessWidth32, Reg, &LocalPciRegister, StdHeader);
325 }