AGESA F15: AMD family15 AGESA code
[coreboot.git] / src / vendorcode / amd / agesa / f15 / Proc / Mem / NB / mntrain3.c
1 /* $NoKeywords:$ */
2 /**
3  * @file
4  *
5  * mntrain3.c
6  *
7  * Common Northbridge function for training flow for DDR3
8  *
9  * @xrefitem bom "File Content Label" "Release Content"
10  * @e project: AGESA
11  * @e sub-project: (Mem/NB)
12  * @e \$Revision: 59563 $ @e \$Date: 2011-09-26 12:06:49 -0600 (Mon, 26 Sep 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 "amdlib.h"
57 #include "Ids.h"
58 #include "OptionMemory.h"
59 #include "mm.h"
60 #include "mn.h"
61 #include "mt.h"
62 #include "Filecode.h"
63 CODE_GROUP (G1_PEICC)
64 RDATA_GROUP (G2_PEI)
65
66 #define FILECODE PROC_MEM_NB_MNTRAIN3_FILECODE
67 /* features */
68 #include "mftds.h"
69 /*----------------------------------------------------------------------------
70  *                          DEFINITIONS AND MACROS
71  *
72  *----------------------------------------------------------------------------
73  */
74
75 /*----------------------------------------------------------------------------
76  *                           TYPEDEFS AND STRUCTURES
77  *
78  *----------------------------------------------------------------------------
79  */
80
81 /*----------------------------------------------------------------------------
82  *                        PROTOTYPES OF LOCAL FUNCTIONS
83  *
84  *----------------------------------------------------------------------------
85  */
86
87 BOOLEAN
88 STATIC
89 MemNHwWlPart2Nb (
90   IN OUT   MEM_TECH_BLOCK *TechPtr
91   );
92 /*----------------------------------------------------------------------------
93  *                            EXPORTED FUNCTIONS
94  *
95  *----------------------------------------------------------------------------
96  */
97 extern MEM_FEAT_TRAIN_SEQ memTrainSequenceDDR3[];
98 /* -----------------------------------------------------------------------------*/
99 /**
100  *
101  *   This function initiates DQS training
102  *
103  *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
104  *
105  */
106
107 BOOLEAN
108 MemNDQSTiming3Nb (
109   IN OUT   MEM_NB_BLOCK *NBPtr
110   )
111 {
112   MEM_TECH_BLOCK *TechPtr;
113   UINT8 i;
114   BOOLEAN Retval;
115   TechPtr = NBPtr->TechPtr;
116   Retval = TRUE;
117   if (TechPtr->NBPtr->MCTPtr->NodeMemSize) {
118     //Execute Technology specific training features
119     i = 0;
120     while (memTrainSequenceDDR3[i].TrainingSequenceEnabled != 0) {
121       if (memTrainSequenceDDR3[i].TrainingSequenceEnabled (NBPtr)) {
122         NBPtr->TrainingSequenceIndex = i;
123         Retval = memTrainSequenceDDR3[i].TrainingSequence (NBPtr);
124         break;
125       }
126       i++;
127     }
128   }
129   return Retval;
130 }
131 /* -----------------------------------------------------------------------------*/
132 /**
133  *
134  *   This function initiates DQS training for Server NB
135  *
136  *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
137  *
138  */
139
140 BOOLEAN
141 memNSequenceDDR3Nb (
142   IN OUT   MEM_NB_BLOCK *NBPtr
143   )
144 {
145   MEM_TECH_BLOCK *TechPtr;
146   UINT8 i;
147   TechPtr = NBPtr->TechPtr;
148   i = NBPtr->TrainingSequenceIndex;
149   if (TechPtr->NBPtr->MCTPtr->NodeMemSize != 0) {
150     AGESA_TESTPOINT (TpProcMemBeforeAgesaHookBeforeDQSTraining, &NBPtr->MemPtr->StdHeader);
151     IDS_HDT_CONSOLE (MEM_FLOW, "\nCalling out to Platform BIOS...\n");
152     if (AgesaHookBeforeDQSTraining (NBPtr->MCTPtr->SocketId, TechPtr->NBPtr->MemPtr) == AGESA_SUCCESS) {
153       // Right now we do not have anything to do if the callout is implemented
154     }
155     AGESA_TESTPOINT (TpProcMemAfterAgesaHookBeforeDQSTraining, &NBPtr->MemPtr->StdHeader);
156     //Execute Technology specific training features
157     if (memTrainSequenceDDR3[i].MemTechFeatBlock->EnterHardwareTraining (TechPtr)) {
158       TechPtr->TechnologySpecificHook[LrdimmBuf2DramTrain] (TechPtr, NULL);
159       if (memTrainSequenceDDR3[i].MemTechFeatBlock->SwWLTraining (TechPtr)) {
160         MemFInitTableDrive (NBPtr, MTAfterSwWLTrn);
161         if (memTrainSequenceDDR3[i].MemTechFeatBlock->HwBasedWLTrainingPart1 (TechPtr)) {
162           MemFInitTableDrive (NBPtr, MTAfterHwWLTrnP1);
163           if (memTrainSequenceDDR3[i].MemTechFeatBlock->HwBasedDQSReceiverEnableTrainingPart1 (TechPtr)) {
164             MemFInitTableDrive (NBPtr, MTAfterHwRxEnTrnP1);
165             // If target speed is higher than start-up speed, do frequency change and second pass of WL
166             do {
167               if (MemNHwWlPart2Nb (TechPtr)) {
168                 if (memTrainSequenceDDR3[i].MemTechFeatBlock->TrainExitHwTrn (TechPtr)) {
169                   IDS_OPTION_HOOK (IDS_PHY_DLL_STANDBY_CTRL, NBPtr, &(NBPtr->MemPtr->StdHeader));
170                   if (memTrainSequenceDDR3[i].MemTechFeatBlock->NonOptimizedSWDQSRecEnTrainingPart1 (TechPtr)) {
171                     if (memTrainSequenceDDR3[i].MemTechFeatBlock->OptimizedSwDqsRecEnTrainingPart1 (TechPtr)) {
172                       MemFInitTableDrive (NBPtr, MTAfterSwRxEnTrn);
173                       if (memTrainSequenceDDR3[i].MemTechFeatBlock->NonOptimizedSRdWrPosTraining (TechPtr)) {
174                         if (memTrainSequenceDDR3[i].MemTechFeatBlock->OptimizedSRdWrPosTraining (TechPtr)) {
175                           MemFInitTableDrive (NBPtr, MTAfterDqsRwPosTrn);
176                           if (!NBPtr->FamilySpecificHook[MemPstateStageChange] (NBPtr, NULL)) {
177                             continue;
178                           }
179                           if (NBPtr->Execute1dMaxRdLatTraining) {
180                             do {
181                               if (memTrainSequenceDDR3[i].MemTechFeatBlock->MaxRdLatencyTraining (TechPtr)) {
182                                 MemFInitTableDrive (NBPtr, MTAfterMaxRdLatTrn);
183                               }
184                             } while (NBPtr->ChangeNbFrequency (NBPtr));
185                                                   } else {
186                             // If not running MRL training, set everything back for training
187                                                         memTrainSequenceDDR3[i].MemTechFeatBlock->TrainExitHwTrn (TechPtr);
188                           }
189                         }
190                       }
191                     }
192                   }
193                 }
194               }
195             } while (NBPtr->MemPstateStage == MEMORY_PSTATE_2ND_STAGE);
196           }
197         }
198       }
199     }
200     MemTMarkTrainFail (TechPtr);
201   }
202   return TRUE;
203 }
204 /* -----------------------------------------------------------------------------*/
205 /**
206  *
207  *   This function executes HW WL at multiple speeds
208  *
209  *     @param[in,out]   *TechPtr   - Pointer to the MEM_TECH_BLOCK
210  *     @return       TRUE - No errors occurred
211  *                   FALSE - errors occurred
212  */
213
214 BOOLEAN
215 STATIC
216 MemNHwWlPart2Nb (
217   IN OUT   MEM_TECH_BLOCK *TechPtr
218   )
219 {
220   BOOLEAN retVal;
221   UINT8 i;
222   retVal = TRUE;
223   i = TechPtr->NBPtr->TrainingSequenceIndex;
224   while ((TechPtr->NBPtr->DCTPtr->Timings.TargetSpeed > TechPtr->NBPtr->DCTPtr->Timings.Speed) && (TechPtr->NBPtr->MemPstateStage != MEMORY_PSTATE_1ST_STAGE)) {
225     TechPtr->PrevSpeed = TechPtr->NBPtr->DCTPtr->Timings.Speed;
226     if (TechPtr->NBPtr->RampUpFrequency (TechPtr->NBPtr)) {
227       TechPtr->TechnologySpecificHook[LrdimmBuf2DramTrain] (TechPtr, NULL);
228       if (!memTrainSequenceDDR3[i].MemTechFeatBlock->HwBasedWLTrainingPart2 (TechPtr)) {
229         retVal = FALSE;
230         break;
231       }
232       MemFInitTableDrive (TechPtr->NBPtr, MTAfterHwWLTrnP2);
233       if (!memTrainSequenceDDR3[i].MemTechFeatBlock->HwBasedDQSReceiverEnableTrainingPart2 (TechPtr)) {
234         retVal = FALSE;
235         break;
236       }
237       MemFInitTableDrive (TechPtr->NBPtr, MTAfterHwRxEnTrnP2);
238     } else {
239       retVal = FALSE;
240       break;
241     }
242   }
243   return retVal;
244 }