AGESA F15: AMD family15 AGESA code
[coreboot.git] / src / vendorcode / amd / agesa / f15 / Proc / CPU / cpuPowerMgmt.c
1 /* $NoKeywords:$ */
2 /**
3  * @file
4  *
5  * AMD CPU Power Management functions.
6  *
7  * Contains code for doing early power management
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 "cpuRegisters.h"
54 #include "cpuFamilyTranslation.h"
55 #include "OptionMultiSocket.h"
56 #include "cpuApicUtilities.h"
57 #include "cpuEarlyInit.h"
58 #include "cpuPowerMgmtSystemTables.h"
59 #include "cpuServices.h"
60 #include "Filecode.h"
61 CODE_GROUP (G1_PEICC)
62 RDATA_GROUP (G2_PEI)
63
64 #define FILECODE PROC_CPU_CPUPOWERMGMT_FILECODE
65 /*----------------------------------------------------------------------------------------
66  *                   D E F I N I T I O N S    A N D    M A C R O S
67  *----------------------------------------------------------------------------------------
68  */
69
70 /*----------------------------------------------------------------------------------------
71  *                  T Y P E D E F S     A N D     S T R U C T U R E S
72  *----------------------------------------------------------------------------------------
73  */
74
75 /*----------------------------------------------------------------------------------------
76  *           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
77  *----------------------------------------------------------------------------------------
78  */
79 VOID
80 STATIC
81 PerformThisPmStep (
82   IN       VOID *Step,
83   IN       AMD_CONFIG_PARAMS    *StdHeader,
84   IN       AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr
85   );
86
87 VOID
88 STATIC
89 GoToMemInitPstateCore0 (
90   IN       AMD_CONFIG_PARAMS *StdHeader,
91   IN       AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr
92   );
93
94 VOID
95 STATIC
96 GoToMemInitPstateCore (
97   IN       AMD_CONFIG_PARAMS *StdHeader,
98   IN       AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr
99   );
100
101 /*----------------------------------------------------------------------------------------
102  *                          E X P O R T E D    F U N C T I O N S
103  *----------------------------------------------------------------------------------------
104  */
105 extern OPTION_MULTISOCKET_CONFIGURATION OptionMultiSocketConfiguration;
106
107 /*---------------------------------------------------------------------------------------*/
108 /**
109  * Perform the "BIOS Requirements for P-State Initialization and Transitions."
110  *
111  * This is the generic arbiter code to be executed by the BSC.  The system power
112  * management init tables will be traversed.  This must be run by the system BSC
113  * only.
114  *
115  * @param[in]  CpuEarlyParams    Required input parameters for early CPU initialization
116  * @param[in]  StdHeader         Config handle for library and services
117  *
118  * @return     Most severe AGESA_STATUS level that any system processor encountered
119  *
120  */
121 AGESA_STATUS
122 PmInitializationAtEarly (
123   IN       AMD_CPU_EARLY_PARAMS *CpuEarlyParams,
124   IN       AMD_CONFIG_PARAMS    *StdHeader
125   )
126 {
127   UINT8              i;
128   UINT8              NumberOfSystemWideSteps;
129   AP_TASK            TaskPtr;
130   AGESA_STATUS       ReturnCode;
131   WARM_RESET_REQUEST Request;
132
133   // Determine the number of steps to perform
134   OptionMultiSocketConfiguration.GetNumberOfSystemPmSteps (&NumberOfSystemWideSteps, StdHeader);
135
136   // Traverse the PM init table
137   TaskPtr.FuncAddress.PfApTaskIC = PerformThisPmStep;
138   TaskPtr.DataTransfer.DataSizeInDwords = 1;
139   TaskPtr.DataTransfer.DataPtr = &i;
140   TaskPtr.DataTransfer.DataTransferFlags = 0;
141   TaskPtr.ExeFlags = PASS_EARLY_PARAMS;
142   for (i = 0; i < NumberOfSystemWideSteps; ++i) {
143     IDS_HDT_CONSOLE (CPU_TRACE, "  Perform PM init step %d\n", i);
144     OptionMultiSocketConfiguration.BscRunCodeOnAllSystemCore0s (&TaskPtr, StdHeader, CpuEarlyParams);
145   }
146
147   // GoToMemInitPstateCore0 only if there is no pending warm reset.
148   GetWarmResetFlag (StdHeader, &Request);
149   if (Request.RequestBit == FALSE) {
150     TaskPtr.FuncAddress.PfApTaskC = GoToMemInitPstateCore0;
151     TaskPtr.DataTransfer.DataSizeInDwords = 0;
152     TaskPtr.ExeFlags = PASS_EARLY_PARAMS;
153     IDS_HDT_CONSOLE (CPU_TRACE, "  Transition all cores to POST P-state\n");
154     OptionMultiSocketConfiguration.BscRunCodeOnAllSystemCore0s (&TaskPtr, StdHeader, CpuEarlyParams);
155   }
156
157   // Retrieve/Process any errors
158   ReturnCode = OptionMultiSocketConfiguration.BscRetrievePmEarlyInitErrors (StdHeader);
159
160   return (ReturnCode);
161 }
162
163
164 /*---------------------------------------------------------------------------------------*/
165 /**
166  * Performs the next step in the executing core 0's family specific power
167  * management table.
168  *
169  * This function determines if the input step is valid, and invokes the power
170  * management step if appropriate.  This must be run by processor core 0s only.
171  *
172  * @param[in]  Step              Zero based step number
173  * @param[in]  StdHeader         Config handle for library and services
174  * @param[in]  CpuEarlyParamsPtr Required input parameters for early CPU initialization
175  *
176  */
177 VOID
178 STATIC
179 PerformThisPmStep (
180   IN       VOID *Step,
181   IN       AMD_CONFIG_PARAMS    *StdHeader,
182   IN       AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr
183   )
184 {
185   UINT8  MyNumberOfSteps;
186   SYS_PM_TBL_STEP *FamilyTablePtr;
187   CPU_SPECIFIC_SERVICES *FamilySpecificServices;
188
189   GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader);
190   FamilySpecificServices->GetSysPmTableStruct (FamilySpecificServices, (CONST VOID **) &FamilyTablePtr, &MyNumberOfSteps, StdHeader);
191
192   if (*(UINT8 *)Step < MyNumberOfSteps) {
193     if (FamilyTablePtr[*(UINT8 *)Step].FuncPtr != NULL) {
194       if (!(BOOLEAN) (FamilyTablePtr[*(UINT8 *)Step].ExeFlags & PM_EXEFLAGS_WARM_ONLY) ||
195           IsWarmReset (StdHeader)) {
196         FamilyTablePtr[*(UINT8 *)Step].FuncPtr (FamilySpecificServices, CpuEarlyParamsPtr, StdHeader);
197       }
198     }
199   }
200 }
201
202
203 /*---------------------------------------------------------------------------------------*/
204 /**
205  * Transitions the executing processor to the desired P-state.
206  *
207  * This function implements the AMD_CPU_EARLY_PARAMS.MemInitPState parameter, and is
208  * run by all processor core 0s.
209  *
210  * @param[in]  StdHeader         Config handle for library and services
211  * @param[in]  CpuEarlyParamsPtr Required input parameters for early CPU initialization
212  *
213  */
214 VOID
215 STATIC
216 GoToMemInitPstateCore0 (
217   IN       AMD_CONFIG_PARAMS *StdHeader,
218   IN       AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr
219   )
220 {
221   AP_TASK      TaskPtr;
222
223   TaskPtr.FuncAddress.PfApTaskC = GoToMemInitPstateCore;
224   TaskPtr.DataTransfer.DataSizeInDwords = 0;
225   TaskPtr.ExeFlags = WAIT_FOR_CORE | PASS_EARLY_PARAMS;
226   ApUtilRunCodeOnAllLocalCoresAtEarly (&TaskPtr, StdHeader, CpuEarlyParamsPtr);
227 }
228
229
230 /*---------------------------------------------------------------------------------------*/
231 /**
232  * Transitions the executing core to the desired P-state.
233  *
234  * This function implements the AMD_CPU_EARLY_PARAMS.MemInitPState parameter, and is
235  * run by all system cores.
236  *
237  * @param[in]  StdHeader         Config handle for library and services
238  * @param[in]  CpuEarlyParamsPtr Required input parameters for early CPU initialization
239  *
240  */
241 VOID
242 STATIC
243 GoToMemInitPstateCore (
244   IN       AMD_CONFIG_PARAMS    *StdHeader,
245   IN       AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr
246   )
247 {
248   CPU_SPECIFIC_SERVICES *FamilySpecificServices;
249
250   GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader);
251   FamilySpecificServices->TransitionPstate (FamilySpecificServices, CpuEarlyParamsPtr->MemInitPState, (BOOLEAN) FALSE, StdHeader);
252 }