AGESA F15: AMD family15 AGESA code
[coreboot.git] / src / vendorcode / amd / agesa / f15 / Proc / CPU / Family / 0x10 / F10PmNbCofVidInit.c
1 /* $NoKeywords:$ */
2 /**
3  * @file
4  *
5  * AMD Family_10 NB COF VID Initialization
6  *
7  * Performs the "BIOS Northbridge COF and VID Configuration" 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 "cpuF10PowerMgmt.h"
55 #include "cpuApicUtilities.h"
56 #include "OptionMultiSocket.h"
57 #include "cpuServices.h"
58 #include "GeneralServices.h"
59 #include "cpuFamilyTranslation.h"
60 #include "cpuF10Utilities.h"
61 #include "F10PmNbCofVidInit.h"
62 #include "Filecode.h"
63 CODE_GROUP (G1_PEICC)
64 RDATA_GROUP (G2_PEI)
65
66 #define FILECODE PROC_CPU_FAMILY_0X10_F10PMNBCOFVIDINIT_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
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 /// Structure used for performing the steps outlined in
78 /// the NB COFVID configuration sequence
79 typedef struct {
80   UINT8   NewNbVid;           ///< Destination NB VID code
81   BOOLEAN NbVidUpdateAll;     ///< Status of NbVidUpdateAll
82 } NB_COF_VID_INIT_WARM;
83
84 /*----------------------------------------------------------------------------------------
85  *           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
86  *----------------------------------------------------------------------------------------
87  */
88 VOID
89 STATIC
90 PmNbCofVidInitP0P1Core (
91   IN       VOID *NewNbVid,
92   IN       AMD_CONFIG_PARAMS *StdHeader
93   );
94
95 VOID
96 STATIC
97 PmNbCofVidInitWarmCore (
98   IN       VOID *FunctionData,
99   IN       AMD_CONFIG_PARAMS *StdHeader
100   );
101
102 /*----------------------------------------------------------------------------------------
103  *                          E X P O R T E D    F U N C T I O N S
104  *----------------------------------------------------------------------------------------
105  */
106 extern OPTION_MULTISOCKET_CONFIGURATION OptionMultiSocketConfiguration;
107
108 /*---------------------------------------------------------------------------------------*/
109 /**
110  * Family 10h core 0 entry point for performing the "Northbridge COF and
111  * VID Configuration" algorithm.
112  *
113  * The steps are as follows:
114  *    1. Determine if the algorithm is necessary by checking if all NB FIDs
115  *       match in the coherent fabric.  If so, check to see if NbCofVidUpdate
116  *       is zero for all CPUs.  If that is also true, no further steps are
117  *       necessary.  If not + cold reset, proceed to step 2.  If not + warm
118  *       reset, proceed to step 8.
119  *    2. Determine NewNbVid & NewNbFid.
120  *    3. Copy Startup Pstate settings to P0/P1 MSRs on all local cores.
121  *    4. Copy NewNbVid to P0 NbVid on all local cores.
122  *    5. Transition to P1 on all local cores.
123  *    6. Transition to P0 on local core 0 only.
124  *    7. Copy NewNbFid to F3xD4[NbFid], set NbFidEn, and issue a warm reset.
125  *    8. Update all enabled Pstate MSRs' NbVids according to NbVidUpdateAll
126  *       on all local cores.
127  *    9. Transition to Startup Pstate on all local cores.
128  *
129  * @param[in]  FamilySpecificServices  The current Family Specific Services.
130  * @param[in]  CpuEarlyParamsPtr       Service related parameters (unused).
131  * @param[in]  StdHeader               Config handle for library and services.
132  *
133  */
134 VOID
135 F10PmNbCofVidInit (
136   IN       CPU_SPECIFIC_SERVICES *FamilySpecificServices,
137   IN       AMD_CPU_EARLY_PARAMS  *CpuEarlyParamsPtr,
138   IN       AMD_CONFIG_PARAMS     *StdHeader
139   )
140 {
141   BOOLEAN   PerformNbCofVidCfg;
142   BOOLEAN   NotUsed;
143   BOOLEAN   SystemNbCofsMatch;
144   UINT8     NewNbFid;
145   UINT8     NewNbVid;
146   UINT32    Core;
147   UINT32    SystemNbCof;
148   UINT32    AndMask;
149   UINT32    OrMask;
150   UINT32    Ignored;
151   UINT32    NewNbVoltage;
152   UINT32    FrequencyDivisor;
153   WARM_RESET_REQUEST Request;
154   AP_TASK   TaskPtr;
155   PCI_ADDR  PciAddress;
156   NB_COF_VID_INIT_WARM FunctionData;
157
158   PerformNbCofVidCfg = TRUE;
159   OptionMultiSocketConfiguration.GetSystemNbPstateSettings ((UINT32) 0, &CpuEarlyParamsPtr->PlatformConfig, &SystemNbCof, &FrequencyDivisor, &SystemNbCofsMatch, &NotUsed, StdHeader);
160   if (SystemNbCofsMatch) {
161     if (!OptionMultiSocketConfiguration.GetSystemNbCofVidUpdate (StdHeader)) {
162       PerformNbCofVidCfg = FALSE;
163     }
164   }
165   if (PerformNbCofVidCfg) {
166     OptionMultiSocketConfiguration.GetCurrPciAddr (&PciAddress, StdHeader);
167
168     GetCurrentCore (&Core, StdHeader);
169     ASSERT (Core == 0);
170
171     // get NewNbVid
172     FamilySpecificServices->GetNbPstateInfo (FamilySpecificServices,
173                                              &CpuEarlyParamsPtr->PlatformConfig,
174                                              &PciAddress,
175                                              (UINT32) 0,
176                                              &Ignored,
177                                              &Ignored,
178                                              &NewNbVoltage,
179                                              StdHeader);
180     ASSERT (((1550000 - NewNbVoltage) % 12500) == 0);
181     NewNbVid = (UINT8) ((1550000 - NewNbVoltage) / 12500);
182     ASSERT (NewNbVid < 0x80);
183
184     if (!(IsWarmReset (StdHeader))) {
185
186       // determine NewNbFid
187       NewNbFid = (UINT8) ((SystemNbCof / 200) - 4);
188
189       TaskPtr.FuncAddress.PfApTaskI = PmNbCofVidInitP0P1Core;
190       TaskPtr.DataTransfer.DataSizeInDwords = 1;
191       TaskPtr.DataTransfer.DataPtr = &NewNbVid;
192       TaskPtr.DataTransfer.DataTransferFlags = 0;
193       TaskPtr.ExeFlags = 0;
194       ApUtilRunCodeOnAllLocalCoresAtEarly (&TaskPtr, StdHeader, CpuEarlyParamsPtr);
195
196       // Transition core 0 to P0 and wait for change to complete
197       FamilySpecificServices->TransitionPstate (FamilySpecificServices, (UINT8) 0, (BOOLEAN) TRUE, StdHeader);
198
199       PciAddress.Address.Register = CPTC0_REG;
200       AndMask = 0xFFFFFFFF;
201       ((CLK_PWR_TIMING_CTRL_REGISTER *) &AndMask)->NbFid = 0;
202       OrMask = 0x00000000;
203       ((CLK_PWR_TIMING_CTRL_REGISTER *) &OrMask)->NbFid = NewNbFid;
204       ((CLK_PWR_TIMING_CTRL_REGISTER *) &OrMask)->NbFidEn = 1;
205       OptionMultiSocketConfiguration.ModifyCurrSocketPci (&PciAddress, AndMask, OrMask, StdHeader);
206
207       // warm reset request
208       GetWarmResetFlag (StdHeader, &Request);
209       Request.RequestBit = TRUE;
210       Request.StateBits = Request.PostStage - 1;
211       SetWarmResetFlag (StdHeader, &Request);
212     } else {
213       // warm reset path
214
215       FunctionData.NewNbVid = NewNbVid;
216       FamilySpecificServices->IsNbCofInitNeeded (FamilySpecificServices, &PciAddress, &FunctionData.NbVidUpdateAll, StdHeader);
217
218       TaskPtr.FuncAddress.PfApTaskI = PmNbCofVidInitWarmCore;
219       TaskPtr.DataTransfer.DataSizeInDwords = SIZE_IN_DWORDS (NB_COF_VID_INIT_WARM);
220       TaskPtr.DataTransfer.DataPtr = &FunctionData;
221       TaskPtr.DataTransfer.DataTransferFlags = 0;
222       TaskPtr.ExeFlags = WAIT_FOR_CORE;
223       ApUtilRunCodeOnAllLocalCoresAtEarly (&TaskPtr, StdHeader, CpuEarlyParamsPtr);
224     }
225   } // skip whole algorithm
226 }
227
228
229 /*---------------------------------------------------------------------------------------*/
230 /**
231  * Cold reset support routine for F10PmNbCofVidInit.
232  *
233  * This function implements steps 3, 4, & 5 on each core.
234  *
235  * @param[in]  NewNbVid           NewNbVid determined by core 0 in step 2.
236  * @param[in]  StdHeader          Config handle for library and services.
237  *
238  */
239 VOID
240 STATIC
241 PmNbCofVidInitP0P1Core (
242   IN       VOID *NewNbVid,
243   IN       AMD_CONFIG_PARAMS *StdHeader
244   )
245 {
246   UINT8  NumBoostStates;
247   UINT32 MsrAddress;
248   UINT64 LocalMsrRegister;
249   CPU_SPECIFIC_SERVICES *FamilySpecificServices;
250
251   NumBoostStates = F10GetNumberOfBoostedPstatesOnCore (StdHeader);
252   GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader);
253   LibAmdMsrRead (MSR_COFVID_STS, &LocalMsrRegister, StdHeader);
254   MsrAddress = (UINT32) ((((COFVID_STS_MSR *) &LocalMsrRegister)->StartupPstate) + PS_REG_BASE);
255   LibAmdMsrRead (MsrAddress, &LocalMsrRegister, StdHeader);
256   LibAmdMsrWrite ((UINT32) (PS_REG_BASE + 1 + NumBoostStates), &LocalMsrRegister, StdHeader);
257   ((PSTATE_MSR *) &LocalMsrRegister)->NbVid = *(UINT8 *) NewNbVid;
258   LibAmdMsrWrite (PS_REG_BASE + NumBoostStates, &LocalMsrRegister, StdHeader);
259   FamilySpecificServices->TransitionPstate (FamilySpecificServices, (UINT8) 1, (BOOLEAN) FALSE, StdHeader);
260 }
261
262
263 /*---------------------------------------------------------------------------------------*/
264 /**
265  * Warm reset support routine for F10PmNbCofVidInit.
266  *
267  * This function implements steps 8 & 9 on each core.
268  *
269  * @param[in]  FunctionData       Contains NewNbVid determined by core 0 in step
270  *                                2, and NbVidUpdateAll.
271  * @param[in]  StdHeader          Config handle for library and services.
272  *
273  */
274 VOID
275 STATIC
276 PmNbCofVidInitWarmCore (
277   IN       VOID *FunctionData,
278   IN       AMD_CONFIG_PARAMS *StdHeader
279   )
280 {
281   UINT32 MsrAddress;
282   UINT64 LocalMsrRegister;
283   CPU_SPECIFIC_SERVICES *FamilySpecificServices;
284
285   GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader);
286   for (MsrAddress = PS_REG_BASE; MsrAddress <= PS_MAX_REG; MsrAddress++) {
287     LibAmdMsrRead (MsrAddress, &LocalMsrRegister, StdHeader);
288     if (((PSTATE_MSR *) &LocalMsrRegister)->IddValue != 0) {
289       if ((((PSTATE_MSR *) &LocalMsrRegister)->NbDid == 0) || ((NB_COF_VID_INIT_WARM *) FunctionData)->NbVidUpdateAll) {
290         ((PSTATE_MSR *) &LocalMsrRegister)->NbVid = ((NB_COF_VID_INIT_WARM *) FunctionData)->NewNbVid;
291         LibAmdMsrWrite (MsrAddress, &LocalMsrRegister, StdHeader);
292       }
293     }
294   }
295 }
296