AGESA F15: AMD family15 AGESA code
[coreboot.git] / src / vendorcode / amd / agesa / f15 / Proc / Mem / Main / OR / mmflowor.c
1 /* $NoKeywords:$ */
2 /**
3  * @file
4  *
5  * mmflowor.c
6  *
7  * Main Memory initialization sequence for OR
8  *
9  * @xrefitem bom "File Content Label" "Release Content"
10  * @e project: AGESA
11  * @e sub-project: (Mem/Main/OR)
12  * @e \$Revision: 54925 $ @e \$Date: 2011-06-14 09:05:43 -0600 (Tue, 14 Jun 2011) $
13  *
14  **/
15 /*****************************************************************************
16 *
17 * Copyright (C) 2012 Advanced Micro Devices, Inc.
18 * All rights reserved.
19 *
20 * Redistribution and use in source and binary forms, with or without
21 * modification, are permitted provided that the following conditions are met:
22 *     * Redistributions of source code must retain the above copyright
23 *       notice, this list of conditions and the following disclaimer.
24 *     * Redistributions in binary form must reproduce the above copyright
25 *       notice, this list of conditions and the following disclaimer in the
26 *       documentation and/or other materials provided with the distribution.
27 *     * Neither the name of Advanced Micro Devices, Inc. nor the names of
28 *       its contributors may be used to endorse or promote products derived
29 *       from this software without specific prior written permission.
30 *
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
32 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
33 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
34 * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
35 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
36 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
38 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
40 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 *
42 * ***************************************************************************
43 *
44 */
45
46 /*
47  *----------------------------------------------------------------------------
48  *                                MODULES USED
49  *
50  *----------------------------------------------------------------------------
51  */
52
53
54
55 #include "AGESA.h"
56 #include "Ids.h"
57 #include "OptionMemory.h"
58 #include "mm.h"
59 #include "mn.h"
60 #include "mnor.h"
61 #include "mt.h"
62 #include "mmLvDdr3.h"
63 #include "cpuFamilyTranslation.h"
64 #include "Filecode.h"
65 #include "GeneralServices.h"
66 CODE_GROUP (G3_DXE)
67 RDATA_GROUP (G3_DXE)
68
69 #define FILECODE PROC_MEM_MAIN_OR_MMFLOWOR_FILECODE
70 /* features */
71 #include "mftds.h"
72
73 extern MEM_FEAT_BLOCK_MAIN MemFeatMain;
74
75 /*----------------------------------------------------------------------------
76  *                          DEFINITIONS AND MACROS
77  *
78  *----------------------------------------------------------------------------
79  */
80
81 /*----------------------------------------------------------------------------
82  *                           TYPEDEFS AND STRUCTURES
83  *
84  *----------------------------------------------------------------------------
85  */
86
87 /*----------------------------------------------------------------------------
88  *                        PROTOTYPES OF LOCAL FUNCTIONS
89  *
90  *----------------------------------------------------------------------------
91  */
92
93 AGESA_STATUS
94 MemMFlowOr (
95   IN OUT   MEM_MAIN_DATA_BLOCK *MemMainPtr
96   );
97
98 /*----------------------------------------------------------------------------
99  *                            EXPORTED FUNCTIONS
100  *
101  *----------------------------------------------------------------------------
102  */
103 /* -----------------------------------------------------------------------------*/
104 /**
105  *
106  *
107  *      This function defines the memory initialization flow for
108  *      systems that only support OR processors.
109  *
110  *     @param[in,out]   *MemMainPtr   - Pointer to the MEM_MAIN_DATA_BLOCK
111  *
112  *     @return          AGESA_STATUS
113  *                          - AGESA_ALERT
114  *                          - AGESA_FATAL
115  *                          - AGESA_SUCCESS
116  *                          - AGESA_WARNING
117  */
118 AGESA_STATUS
119 MemMFlowOr (
120   IN OUT   MEM_MAIN_DATA_BLOCK *MemMainPtr
121   )
122 {
123   UINT8   Node;
124   UINT8   NodeCnt;
125   MEM_NB_BLOCK  *NBPtr;
126   MEM_TECH_BLOCK *TechPtr;
127   MEM_DATA_STRUCT *MemPtr;
128   ID_INFO CallOutIdInfo;
129
130   NBPtr = MemMainPtr->NBPtr;
131   TechPtr = MemMainPtr->TechPtr;
132   NodeCnt = MemMainPtr->DieCount;
133   MemPtr = MemMainPtr->MemPtr;
134
135   GetLogicalIdOfSocket (MemPtr->DiesPerSystem[BSP_DIE].SocketId, &(MemPtr->DiesPerSystem[BSP_DIE].LogicalCpuid), &(MemPtr->StdHeader));
136   if (!MemNIsIdSupportedOr (NBPtr, &(MemPtr->DiesPerSystem[BSP_DIE].LogicalCpuid))) {
137     MemPtr->IsFlowControlSupported = FALSE;
138     return AGESA_FATAL;
139   } else {
140     MemPtr->IsFlowControlSupported = TRUE;
141   }
142
143   for (Node = 0; Node < NodeCnt; Node++) {
144     MemFInitTableDrive (&NBPtr[Node], MTBeforeInitializeMCT);
145   }
146
147   //----------------------------------------------------------------
148   // Initialize MCT
149   //----------------------------------------------------------------
150   AGESA_TESTPOINT (TpProcMemInitializeMCT, &(MemMainPtr->MemPtr->StdHeader));
151   for (Node = 0; Node < NodeCnt; Node++) {
152     if (!NBPtr[Node].InitializeMCT (&NBPtr[Node])) {
153       return AGESA_FATAL;
154     }
155   }
156
157   //----------------------------------------------------------------
158   // Low voltage DDR3
159   //----------------------------------------------------------------
160   // Levelize DDR3 voltage based on socket, as each socket has its own voltage for dimms.
161   AGESA_TESTPOINT (TpProcMemLvDdr3, &(MemMainPtr->MemPtr->StdHeader));
162   if (!MemFeatMain.LvDDR3 (MemMainPtr)) {
163     return AGESA_FATAL;
164   }
165
166   //----------------------------------------------------------------
167   // Initialize DRAM and DCTs
168   //----------------------------------------------------------------
169   AGESA_TESTPOINT (TpProcMemInitMCT, &(MemMainPtr->MemPtr->StdHeader));
170   for (Node = 0; Node < NodeCnt; Node++) {
171     // Initialize Memory Controller and Dram
172     IDS_HDT_CONSOLE (MEM_STATUS, "Node %d\n", Node);
173     if (!NBPtr[Node].InitMCT (&NBPtr[Node])) {
174       return AGESA_FATAL; //fatalexit
175     }
176
177     MemFInitTableDrive (NBPtr, MTBeforeDInit);
178   }
179
180   //------------------------------------------------
181   // Finalize target frequency
182   //------------------------------------------------
183   if (!MemMLvDdr3PerformanceEnhFinalize (MemMainPtr)) {
184     return AGESA_FATAL;
185   }
186
187   //------------------------------------------------
188   // Callout before Dram Init
189   //------------------------------------------------
190   AGESA_TESTPOINT (TpProcMemBeforeAgesaHookBeforeDramInit, &(MemMainPtr->MemPtr->StdHeader));
191   for (Node = 0; Node < NodeCnt; Node ++) {
192     CallOutIdInfo.IdField.SocketId = NBPtr[Node].MCTPtr->SocketId;
193     CallOutIdInfo.IdField.ModuleId = NBPtr[Node].MCTPtr->DieId;
194     IDS_HDT_CONSOLE (MEM_FLOW, "\nCalling out to Platform BIOS on Socket %d Module %d...\n", CallOutIdInfo.IdField.SocketId, CallOutIdInfo.IdField.ModuleId);
195     AgesaHookBeforeDramInit ((UINTN) CallOutIdInfo.IdInformation, MemMainPtr->MemPtr);
196     IDS_HDT_CONSOLE (MEM_FLOW, "\nVDDIO = 1.%dV\n", (NBPtr[Node].RefPtr->DDR3Voltage == VOLT1_5) ? 5 :
197                                         (NBPtr[Node].RefPtr->DDR3Voltage == VOLT1_35) ? 35 :
198                                         (NBPtr[Node].RefPtr->DDR3Voltage == VOLT1_25) ? 25 : 999);
199   }
200   AGESA_TESTPOINT (TpProcMemAfterAgesaHookBeforeDramInit, &(NBPtr->MemPtr->StdHeader));
201
202   //-------------------------------------------------
203   // Do dram init and create memory map
204   //-------------------------------------------------
205   for (Node = 0; Node < NodeCnt; Node++) {
206     IDS_OPTION_HOOK (IDS_BEFORE_DRAM_INIT, &NBPtr[Node], &(MemMainPtr->MemPtr->StdHeader));
207     NBPtr[Node].StartupDCT (&NBPtr[Node]);
208
209     // Create memory map
210     AGESA_TESTPOINT (TpProcMemSystemMemoryMapping, &(MemMainPtr->MemPtr->StdHeader));
211     if (!NBPtr[Node].HtMemMapInit (&NBPtr[Node])) {
212       return AGESA_FATAL;
213     }
214   }
215
216   //----------------------------------------------------
217   // If there is no dimm on the system, do fatal exit
218   //----------------------------------------------------
219   if (NBPtr[BSP_DIE].RefPtr->SysLimit == 0) {
220     PutEventLog (AGESA_FATAL, MEM_ERROR_NO_DIMM_FOUND_ON_SYSTEM, 0, 0, 0, 0, &(MemMainPtr->MemPtr->StdHeader));
221     return AGESA_FATAL;
222   }
223
224   //----------------------------------------------------------------
225   // Synchronize DCTs
226   //----------------------------------------------------------------
227   AGESA_TESTPOINT (TpProcMemSynchronizeDcts, &(MemMainPtr->MemPtr->StdHeader));
228   for (Node = 0; Node < NodeCnt; Node++) {
229     if (!NBPtr[Node].SyncDctsReady (&NBPtr[Node])) {
230       return AGESA_FATAL;
231     }
232   }
233
234   //----------------------------------------------------------------
235   // CpuMemTyping
236   //----------------------------------------------------------------
237   AGESA_TESTPOINT (TpProcMemMtrrConfiguration, &(MemMainPtr->MemPtr->StdHeader));
238   if (!NBPtr[BSP_DIE].CpuMemTyping (&NBPtr[BSP_DIE])) {
239     return AGESA_FATAL;
240   }
241
242   //----------------------------------------------------------------
243   // Before Training Table values
244   //----------------------------------------------------------------
245   for (Node = 0; Node < NodeCnt; Node++) {
246     MemFInitTableDrive (&NBPtr[Node], MTBeforeTrn);
247   }
248
249   //----------------------------------------------------------------
250   // Memory Context Restore
251   //----------------------------------------------------------------
252   if (!MemFeatMain.MemRestore (MemMainPtr)) {
253     // Do DQS training only if memory context restore fails
254
255     //----------------------------------------------------------------
256     // Training
257     //----------------------------------------------------------------
258     MemMainPtr->mmSharedPtr->DimmExcludeFlag = TRAINING;
259     AGESA_TESTPOINT (TpProcMemDramTraining, &(MemMainPtr->MemPtr->StdHeader));
260     IDS_SKIP_HOOK (IDS_BEFORE_DQS_TRAINING, MemMainPtr, &(MemMainPtr->MemPtr->StdHeader)) {
261       if (!MemFeatMain.Training (MemMainPtr)) {
262         return AGESA_FATAL;
263       }
264     }
265     IDS_HDT_CONSOLE (MEM_FLOW, "\nEnd DQS training\n\n");
266   }
267
268   //----------------------------------------------------------------
269   // Disable chipselects that fail training
270   //----------------------------------------------------------------
271   MemMainPtr->mmSharedPtr->DimmExcludeFlag = END_TRAINING;
272   MemFeatMain.ExcludeDIMM (MemMainPtr);
273   MemMainPtr->mmSharedPtr->DimmExcludeFlag = NORMAL;
274
275   //----------------------------------------------------------------
276   // OtherTiming
277   //----------------------------------------------------------------
278   AGESA_TESTPOINT (TpProcMemOtherTiming, &(MemMainPtr->MemPtr->StdHeader));
279   for (Node = 0; Node < NodeCnt; Node++) {
280     if (!NBPtr[Node].OtherTiming (&NBPtr[Node])) {
281       return AGESA_FATAL;
282     }
283   }
284   IDS_HDT_CONSOLE (MEM_FLOW, "\nEnd Non-SPD Timings.\n");
285
286   //----------------------------------------------------------------
287   // After Training Table values
288   //----------------------------------------------------------------
289   for (Node = 0; Node < NodeCnt; Node++) {
290     MemFInitTableDrive (&NBPtr[Node], MTAfterTrn);
291   }
292
293   //----------------------------------------------------------------
294   // Online Spare
295   //----------------------------------------------------------------
296   if (!MemFeatMain.OnlineSpare (MemMainPtr)) {
297     return AGESA_FATAL;
298   }
299
300   //----------------------------------------------------------------
301   // Interleave banks
302   //----------------------------------------------------------------
303   for (Node = 0; Node < NodeCnt; Node++) {
304     if (NBPtr[Node].FeatPtr->InterleaveBanks (&NBPtr[Node])) {
305       if (NBPtr[Node].MCTPtr->ErrCode == AGESA_FATAL) {
306         return AGESA_FATAL;
307       }
308     }
309   }
310
311   //----------------------------------------------------------------
312   // Interleave Nodes
313   //----------------------------------------------------------------
314   if (!MemFeatMain.InterleaveNodes (MemMainPtr)) {
315     return AGESA_FATAL;
316   }
317
318   //----------------------------------------------------------------
319   // Interleave channels
320   //----------------------------------------------------------------
321   for (Node = 0; Node < NodeCnt; Node++) {
322     if (NBPtr[Node].FeatPtr->InterleaveChannels (&NBPtr[Node])) {
323       if (NBPtr[Node].MCTPtr->ErrCode == AGESA_FATAL) {
324         return AGESA_FATAL;
325       }
326     }
327   }
328
329   //----------------------------------------------------------------
330   // After Programming Interleave registers
331   //----------------------------------------------------------------
332   for (Node = 0; Node < NodeCnt; Node++) {
333     MemFInitTableDrive (&NBPtr[Node], MTAfterInterleave);
334   }
335
336   // ECC
337   //----------------------------------------------------------------
338   if (!MemFeatMain.InitEcc (MemMainPtr)) {
339     return AGESA_FATAL;
340   }
341
342   //----------------------------------------------------------------
343   // Memory Clear
344   //----------------------------------------------------------------
345   AGESA_TESTPOINT (TpProcMemMemClr, &(MemMainPtr->MemPtr->StdHeader));
346   if (!MemFeatMain.MemClr (MemMainPtr)) {
347     return AGESA_FATAL;
348   }
349
350   //----------------------------------------------------------------
351   // C6 Storage Allocation
352   //----------------------------------------------------------------
353   for (Node = 0; Node < NodeCnt; Node++) {
354     NBPtr[Node].AllocateC6Storage (&NBPtr[Node]);
355   }
356
357   //----------------------------------------------------------------
358   // UMA Allocation & UMAMemTyping
359   //----------------------------------------------------------------
360   AGESA_TESTPOINT (TpProcMemUMAMemTyping, &(MemMainPtr->MemPtr->StdHeader));
361   if (!MemFeatMain.UmaAllocation (MemMainPtr)) {
362     return AGESA_FATAL;
363   }
364
365   //----------------------------------------------------------------
366   // Interleave region
367   //----------------------------------------------------------------
368   NBPtr[BSP_DIE].FeatPtr->InterleaveRegion (&NBPtr[BSP_DIE]);
369
370   //----------------------------------------------------------------
371   // OnDimm Thermal
372   //----------------------------------------------------------------
373   for (Node = 0; Node < NodeCnt; Node++) {
374     if (NBPtr[Node].FeatPtr->OnDimmThermal (&NBPtr[Node])) {
375       if (NBPtr[Node].MCTPtr->ErrCode == AGESA_FATAL) {
376         return AGESA_FATAL;
377       }
378     }
379   }
380
381   //----------------------------------------------------------------
382   // Finalize MCT
383   //----------------------------------------------------------------
384   for (Node = 0; Node < NodeCnt; Node++) {
385     if (!NBPtr[Node].FinalizeMCT (&NBPtr[Node])) {
386       return AGESA_FATAL;
387     }
388   }
389
390   //----------------------------------------------------------------
391   // After Finalize MCT
392   //----------------------------------------------------------------
393   for (Node = 0; Node < NodeCnt; Node++) {
394     MemFInitTableDrive (&NBPtr[Node], MTAfterFinalizeMCT);
395   }
396
397   //----------------------------------------------------------------
398   // Memory Context Save
399   //----------------------------------------------------------------
400   MemFeatMain.MemSave (MemMainPtr);
401
402   //----------------------------------------------------------------
403   // Memory DMI support
404   //----------------------------------------------------------------
405   if (!MemFeatMain.MemDmi (MemMainPtr)) {
406     return AGESA_CRITICAL;
407   }
408
409   //----------------------------------------------------------------
410   // Switch back to DCT 0 before sending control back
411   //----------------------------------------------------------------
412   for (Node = 0; Node < NodeCnt; Node ++) {
413     NBPtr[Node].SwitchDCT (&NBPtr[Node], 0);
414   }
415
416   return AGESA_SUCCESS;
417 }
418
419 /*----------------------------------------------------------------------------
420  *                              LOCAL FUNCTIONS
421  *
422  *----------------------------------------------------------------------------
423  */