AGESA F15: AMD family15 AGESA code
[coreboot.git] / src / vendorcode / amd / agesa / f15 / Proc / CPU / Family / 0x10 / RevD / F10RevDL3Features.c
1 /* $NoKeywords:$ */
2 /**
3  * @file
4  *
5  * AMD Family_10 RevD L3 dependent feature support functions.
6  *
7  * Provides the functions necessary to initialize L3 dependent feature.
8  *
9  * @xrefitem bom "File Content Label" "Release Content"
10  * @e project:      AGESA
11  * @e sub-project:  CPU/F10
12  * @e \$Revision: 60552 $   @e \$Date: 2011-10-17 18:50:55 -0600 (Mon, 17 Oct 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 /*
48  *----------------------------------------------------------------------------
49  *                                MODULES USED
50  *
51  *----------------------------------------------------------------------------
52  */
53
54 #include "AGESA.h"
55 #include "amdlib.h"
56 #include "Ids.h"
57 #include "CommonReturns.h"
58 #include "cpuRegisters.h"
59 #include "cpuF10PowerMgmt.h"
60 #include "cpuLateInit.h"
61 #include "cpuServices.h"
62 #include "GeneralServices.h"
63 #include "cpuFamilyTranslation.h"
64 #include "cpuL3Features.h"
65 #include "F10PackageType.h"
66 #include "Filecode.h"
67 CODE_GROUP (G1_PEICC)
68 RDATA_GROUP (G2_PEI)
69
70 #define FILECODE PROC_CPU_FAMILY_0X10_REVD_F10REVDL3FEATURES_FILECODE
71 /*----------------------------------------------------------------------------
72  *                          DEFINITIONS AND MACROS
73  *
74  *----------------------------------------------------------------------------
75  */
76
77 /*----------------------------------------------------------------------------
78  *                           TYPEDEFS AND STRUCTURES
79  *
80  *----------------------------------------------------------------------------
81  */
82
83 /**
84  * The family 10h background scrubber context structure.
85  *
86  * These fields need to be saved, modified, then restored
87  * per die as part of HT Assist initialization.
88  */
89 typedef struct {
90   UINT32  DramScrub:5;               ///< DRAM scrub rate
91   UINT32  :3;                        ///< Reserved
92   UINT32  L3Scrub:5;                 ///< L3 scrub rate
93   UINT32  :3;                        ///< Reserved
94   UINT32  Redirect:1;                ///< DRAM scrubber redirect enable
95   UINT32  :15;                       ///< Reserved
96 } F10_SCRUB_CONTEXT;
97
98
99 /*----------------------------------------------------------------------------
100  *                        PROTOTYPES OF LOCAL FUNCTIONS
101  *
102  *----------------------------------------------------------------------------
103  */
104
105 BOOLEAN
106 F10IsNonOptimalConfig (
107   IN       L3_FEATURE_FAMILY_SERVICES *L3FeatureServices,
108   IN       UINT32 Socket,
109   IN       AMD_CONFIG_PARAMS *StdHeader
110   );
111
112 /*----------------------------------------------------------------------------
113  *                            EXPORTED FUNCTIONS
114  *
115  *----------------------------------------------------------------------------
116  */
117 /*---------------------------------------------------------------------------------------*/
118 /**
119  *  Check to see if the input CPU supports L3 dependent features.
120  *
121  * @param[in]    L3FeatureServices   L3 Feature family services.
122  * @param[in]    Socket              Processor socket to check.
123  * @param[in]    StdHeader           Config Handle for library, services.
124  * @param[in]    PlatformConfig      Contains the runtime modifiable feature input data.
125  *
126  * @retval       TRUE                L3 dependent features are supported.
127  * @retval       FALSE               L3 dependent features are not supported.
128  *
129  */
130 BOOLEAN
131 STATIC
132 F10IsL3FeatureSupported (
133   IN       L3_FEATURE_FAMILY_SERVICES *L3FeatureServices,
134   IN       UINT32 Socket,
135   IN       AMD_CONFIG_PARAMS *StdHeader,
136   IN       PLATFORM_CONFIGURATION *PlatformConfig
137   )
138 {
139   UINT32       Module;
140   UINT32       LocalPciRegister;
141   BOOLEAN      IsSupported;
142   PCI_ADDR     PciAddress;
143   AGESA_STATUS IgnoredStatus;
144
145   IsSupported = FALSE;
146
147   if (PlatformConfig->PlatformProfile.UseHtAssist) {
148   for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) {
149     if (GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredStatus)) {
150       PciAddress.Address.Function = FUNC_3;
151       PciAddress.Address.Register = NB_CAPS_REG;
152       LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
153       if (((NB_CAPS_REGISTER *) &LocalPciRegister)->L3Capable == 1) {
154         IsSupported = TRUE;
155       }
156       break;
157     }
158   }
159   }
160   return IsSupported;
161 }
162
163 /*---------------------------------------------------------------------------------------*/
164 /**
165  *  Check to see if the input CPU supports HT Assist.
166  *
167  * @param[in]    L3FeatureServices   L3 Feature family services.
168  * @param[in]    PlatformConfig      Contains the runtime modifiable feature input data.
169  * @param[in]    StdHeader           Config Handle for library, services.
170  *
171  * @retval       TRUE                HT Assist is supported.
172  * @retval       FALSE               HT Assist cannot be enabled.
173  *
174  */
175 BOOLEAN
176 STATIC
177 F10IsHtAssistSupported (
178   IN       L3_FEATURE_FAMILY_SERVICES *L3FeatureServices,
179   IN       PLATFORM_CONFIGURATION *PlatformConfig,
180   IN       AMD_CONFIG_PARAMS *StdHeader
181   )
182 {
183   BOOLEAN          IsSupported;
184   UINT32           CpuCount;
185   AP_MAILBOXES     ApMailboxes;
186
187   IsSupported = FALSE;
188
189   if (PlatformConfig->PlatformProfile.UseHtAssist) {
190     CpuCount = GetNumberOfProcessors (StdHeader);
191     ASSERT (CpuCount != 0);
192
193     if (CpuCount == 1) {
194       GetApMailbox (&ApMailboxes.ApMailInfo.Info, StdHeader);
195       if (ApMailboxes.ApMailInfo.Fields.ModuleType != 0) {
196         IsSupported = TRUE;
197       }
198     } else if (CpuCount > 1) {
199       IsSupported = TRUE;
200     }
201   }
202   return IsSupported;
203 }
204
205
206 /*---------------------------------------------------------------------------------------*/
207 /**
208  *  Enable the Probe filter feature.
209  *
210  * @param[in]    L3FeatureServices   L3 Feature family services.
211  * @param[in]    Socket              Processor socket to check.
212  * @param[in]    StdHeader           Config Handle for library, services.
213  *
214  */
215 VOID
216 STATIC
217 F10HtAssistInit (
218   IN       L3_FEATURE_FAMILY_SERVICES  *L3FeatureServices,
219   IN       UINT32  Socket,
220   IN       AMD_CONFIG_PARAMS      *StdHeader
221   )
222 {
223   UINT32                     Module;
224   UINT32                     LocalPciRegister;
225   PCI_ADDR                   PciAddress;
226   AGESA_STATUS               IgnoredStatus;
227
228   for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) {
229     if (GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredStatus)) {
230       PciAddress.Address.Function = FUNC_3;
231       PciAddress.Address.Register = L3_CACHE_PARAM_REG;
232       LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
233       ((L3_CACHE_PARAM_REGISTER *) &LocalPciRegister)->L3TagInit = 1;
234       LibAmdPciWrite (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
235       do {
236         LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
237       } while (((L3_CACHE_PARAM_REGISTER *) &LocalPciRegister)->L3TagInit != 0);
238
239       PciAddress.Address.Register = PROBE_FILTER_CTRL_REG;
240       LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
241       ((PROBE_FILTER_CTRL_REGISTER *) &LocalPciRegister)->PFMode = 0;
242       LibAmdPciWrite (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
243
244       F10RevDProbeFilterCritical (PciAddress, LocalPciRegister);
245
246       do {
247         LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
248       } while (((PROBE_FILTER_CTRL_REGISTER *) &LocalPciRegister)->PFInitDone != 1);
249       IDS_OPTION_HOOK (IDS_HT_ASSIST, &PciAddress, StdHeader);
250     }
251   }
252 }
253
254
255 /*---------------------------------------------------------------------------------------*/
256 /**
257  *  Save the current settings of the scrubbers, and disabled them.
258  *
259  * @param[in]    L3FeatureServices   L3 Feature family services.
260  * @param[in]    Socket              Processor socket to check.
261  * @param[in]    ScrubSettings       Location to store current L3 scrubber settings.
262  * @param[in]    StdHeader           Config Handle for library, services.
263  *
264  */
265 VOID
266 STATIC
267 F10GetL3ScrubCtrl (
268   IN       L3_FEATURE_FAMILY_SERVICES *L3FeatureServices,
269   IN       UINT32 Socket,
270   IN       UINT32 ScrubSettings[L3_SCRUBBER_CONTEXT_ARRAY_SIZE],
271   IN       AMD_CONFIG_PARAMS *StdHeader
272   )
273 {
274   UINT32       Module;
275   UINT32       ScrubCtrl;
276   UINT32       ScrubAddr;
277   PCI_ADDR     PciAddress;
278   AGESA_STATUS IgnoredStatus;
279
280   for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) {
281     if (GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredStatus)) {
282
283       ASSERT (Module < L3_SCRUBBER_CONTEXT_ARRAY_SIZE);
284
285       PciAddress.Address.Function = FUNC_3;
286       PciAddress.Address.Register = DRAM_SCRUB_ADDR_LOW_REG;
287       LibAmdPciRead (AccessWidth32, PciAddress, &ScrubAddr, StdHeader);
288
289       PciAddress.Address.Register = SCRUB_RATE_CTRL_REG;
290       LibAmdPciRead (AccessWidth32, PciAddress, &ScrubCtrl, StdHeader);
291
292       ((F10_SCRUB_CONTEXT *) &ScrubSettings[Module])->DramScrub =
293         ((SCRUB_RATE_CTRL_REGISTER *) &ScrubCtrl)->DramScrub;
294       ((F10_SCRUB_CONTEXT *) &ScrubSettings[Module])->L3Scrub =
295         ((SCRUB_RATE_CTRL_REGISTER *) &ScrubCtrl)->L3Scrub;
296       ((F10_SCRUB_CONTEXT *) &ScrubSettings[Module])->Redirect =
297         ((DRAM_SCRUB_ADDR_LOW_REGISTER *) &ScrubAddr)->ScrubReDirEn;
298
299       ((SCRUB_RATE_CTRL_REGISTER *) &ScrubCtrl)->DramScrub = 0;
300       ((SCRUB_RATE_CTRL_REGISTER *) &ScrubCtrl)->L3Scrub = 0;
301       ((DRAM_SCRUB_ADDR_LOW_REGISTER *) &ScrubAddr)->ScrubReDirEn = 0;
302       LibAmdPciWrite (AccessWidth32, PciAddress, &ScrubCtrl, StdHeader);
303       PciAddress.Address.Register = DRAM_SCRUB_ADDR_LOW_REG;
304       LibAmdPciWrite (AccessWidth32, PciAddress, &ScrubAddr, StdHeader);
305     }
306   }
307 }
308
309
310 /*---------------------------------------------------------------------------------------*/
311 /**
312  *  Restore the initial settings for the scrubbers.
313  *
314  * @param[in]    L3FeatureServices   L3 Feature family services.
315  * @param[in]    Socket              Processor socket to check.
316  * @param[in]    ScrubSettings       Location to store current L3 scrubber settings.
317  * @param[in]    StdHeader           Config Handle for library, services.
318  *
319  */
320 VOID
321 STATIC
322 F10SetL3ScrubCtrl (
323   IN       L3_FEATURE_FAMILY_SERVICES *L3FeatureServices,
324   IN       UINT32 Socket,
325   IN       UINT32 ScrubSettings[L3_SCRUBBER_CONTEXT_ARRAY_SIZE],
326   IN       AMD_CONFIG_PARAMS *StdHeader
327   )
328 {
329   UINT32       Module;
330   UINT32       LocalPciRegister;
331   PCI_ADDR     PciAddress;
332   AGESA_STATUS IgnoredStatus;
333
334   for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) {
335     if (GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredStatus)) {
336
337       ASSERT (Module < L3_SCRUBBER_CONTEXT_ARRAY_SIZE);
338
339       PciAddress.Address.Function = FUNC_3;
340       PciAddress.Address.Register = SCRUB_RATE_CTRL_REG;
341       LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
342       ((SCRUB_RATE_CTRL_REGISTER *) &LocalPciRegister)->DramScrub =
343         ((F10_SCRUB_CONTEXT *) &ScrubSettings[Module])->DramScrub;
344       ((SCRUB_RATE_CTRL_REGISTER *) &LocalPciRegister)->L3Scrub =
345         ((F10_SCRUB_CONTEXT *) &ScrubSettings[Module])->L3Scrub;
346       LibAmdPciWrite (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
347
348       PciAddress.Address.Register = DRAM_SCRUB_ADDR_LOW_REG;
349       LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
350       ((DRAM_SCRUB_ADDR_LOW_REGISTER *) &LocalPciRegister)->ScrubReDirEn =
351         ((F10_SCRUB_CONTEXT *) &ScrubSettings[Module])->Redirect;
352       LibAmdPciWrite (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
353     }
354   }
355 }
356
357
358 /*---------------------------------------------------------------------------------------*/
359 /**
360  *  Set MSR bits required for L3 dependent features on each core.
361  *
362  * @param[in]    L3FeatureServices   L3 feature family services.
363  * @param[in]    HtAssistEnabled     Indicates whether Ht Assist is enabled.
364  * @param[in]    StdHeader           Config Handle for library, services.
365  *
366  */
367 VOID
368 STATIC
369 F10HookDisableCache (
370   IN       L3_FEATURE_FAMILY_SERVICES *L3FeatureServices,
371   IN       BOOLEAN HtAssistEnabled,
372   IN       AMD_CONFIG_PARAMS *StdHeader
373   )
374 {
375   UINT64  LocalMsrRegister;
376
377   LibAmdMsrRead (MSR_BU_CFG2, &LocalMsrRegister, StdHeader);
378   LocalMsrRegister |= BIT42;
379   LibAmdMsrWrite (MSR_BU_CFG2, &LocalMsrRegister, StdHeader);
380 }
381
382
383 /*---------------------------------------------------------------------------------------*/
384 /**
385  *  Hook before L3 features initialization sequence.
386  *
387  * @param[in]    L3FeatureServices   L3 Feature family services.
388  * @param[in]    Socket              Processor socket to check.
389  * @param[in]    StdHeader           Config Handle for library, services.
390  *
391  */
392 VOID
393 STATIC
394 F10HookBeforeInit (
395   IN       L3_FEATURE_FAMILY_SERVICES *L3FeatureServices,
396   IN       UINT32 Socket,
397   IN       AMD_CONFIG_PARAMS *StdHeader
398   )
399 {
400   UINT32          Module;
401   UINT32          LocalPciRegister;
402   UINT32          PfCtrlRegister;
403   PCI_ADDR        PciAddress;
404   CPU_LOGICAL_ID  LogicalId;
405   AGESA_STATUS    IgnoredStatus;
406   UINT32          PackageType;
407
408   GetLogicalIdOfSocket (Socket, &LogicalId, StdHeader);
409   PackageType = LibAmdGetPackageType (StdHeader);
410
411   LocalPciRegister = 0;
412   ((PROBE_FILTER_CTRL_REGISTER *) &LocalPciRegister)->PFWayNum = 2;
413   ((PROBE_FILTER_CTRL_REGISTER *) &LocalPciRegister)->PFSubCacheEn = 15;
414   ((PROBE_FILTER_CTRL_REGISTER *) &LocalPciRegister)->PFLoIndexHashEn = 1;
415   for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) {
416     if (GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredStatus)) {
417       PciAddress.Address.Function = FUNC_3;
418       PciAddress.Address.Register = PROBE_FILTER_CTRL_REG;
419       LibAmdPciRead (AccessWidth32, PciAddress, &PfCtrlRegister, StdHeader);
420       ((PROBE_FILTER_CTRL_REGISTER *) &LocalPciRegister)->PFPreferredSORepl =
421         ((PROBE_FILTER_CTRL_REGISTER *) &PfCtrlRegister)->PFPreferredSORepl;
422       LibAmdPciWrite (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
423
424       // Assumption: all socket use the same CPU package.
425       if (((LogicalId.Revision & AMD_F10_D0) != 0) && (PackageType == PACKAGE_TYPE_C32)) {
426         // Apply erratum #384
427         // Set F2x11C[13:12] = 11b
428         PciAddress.Address.Function = FUNC_2;
429         PciAddress.Address.Register = 0x11C;
430         LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
431         LocalPciRegister |= 0x3000;
432         LibAmdPciWrite (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
433       }
434     }
435   }
436 }
437
438
439 /*---------------------------------------------------------------------------------------*/
440 /**
441  *  Check to see if the input CPU is running in the optimal configuration.
442  *
443  * @param[in]    L3FeatureServices   L3 Feature family services.
444  * @param[in]    Socket              Processor socket to check.
445  * @param[in]    StdHeader           Config Handle for library, services.
446  *
447  * @retval       TRUE               HT Assist is running sub-optimally.
448  * @retval       FALSE              HT Assist is running optimally.
449  *
450  */
451 BOOLEAN
452 F10IsNonOptimalConfig (
453   IN       L3_FEATURE_FAMILY_SERVICES *L3FeatureServices,
454   IN       UINT32 Socket,
455   IN       AMD_CONFIG_PARAMS *StdHeader
456   )
457 {
458   BOOLEAN      IsNonOptimal;
459   BOOLEAN      IsMemoryPresent;
460   UINT32       Module;
461   UINT32       LocalPciRegister;
462   PCI_ADDR     PciAddress;
463   AGESA_STATUS IgnoredStatus;
464
465   IsNonOptimal = FALSE;
466   for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) {
467     if (GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredStatus)) {
468       IsMemoryPresent = FALSE;
469       PciAddress.Address.Function = FUNC_2;
470       PciAddress.Address.Register = DRAM_CFG_HI_REG0;
471
472       LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
473       if (((DRAM_CFG_HI_REGISTER *) &LocalPciRegister)->MemClkFreqVal == 1) {
474         IsMemoryPresent = TRUE;
475         if (((DRAM_CFG_HI_REGISTER *) &LocalPciRegister)->MemClkFreq < 4) {
476           IsNonOptimal = TRUE;
477           break;
478         }
479       }
480
481       PciAddress.Address.Register = DRAM_CFG_HI_REG1;
482
483       LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
484       if (((DRAM_CFG_HI_REGISTER *) &LocalPciRegister)->MemClkFreqVal == 1) {
485         IsMemoryPresent = TRUE;
486         if (((DRAM_CFG_HI_REGISTER *) &LocalPciRegister)->MemClkFreq < 4) {
487           IsNonOptimal = TRUE;
488           break;
489         }
490       }
491       if (!IsMemoryPresent) {
492         IsNonOptimal = TRUE;
493         break;
494       }
495     }
496   }
497   return IsNonOptimal;
498 }
499
500
501 CONST L3_FEATURE_FAMILY_SERVICES ROMDATA F10L3Features =
502 {
503   0,
504   F10IsL3FeatureSupported,
505   F10GetL3ScrubCtrl,
506   F10SetL3ScrubCtrl,
507   F10HookBeforeInit,
508   (PF_L3_FEATURE_AFTER_INIT) CommonVoid,
509   F10HookDisableCache,
510   (PF_L3_FEATURE_ENABLE_CACHE) CommonVoid,
511   F10IsHtAssistSupported,
512   F10HtAssistInit,
513   F10IsNonOptimalConfig,
514   (PF_ATM_MODE_IS_SUPPORTED) CommonReturnFalse,
515   (PF_ATM_MODE_INIT) CommonVoid
516 };