blob: 060857559390873ed6c75eebdd03800d278924de [file] [log] [blame]
Frank Vibrans2b4c8312011-02-14 18:30:54 +00001/* $NoKeywords:$ */
2/**
3 * @file
4 *
5 * mftds.c
6 *
7 * Northbridge table drive support file for DR
8 *
9 * @xrefitem bom "File Content Label" "Release Content"
10 * @e project: AGESA
11 * @e sub-project: (Mem/Feat/TABLE)
12 * @e \$Revision: 35136 $ @e \$Date: 2010-07-16 11:29:48 +0800 (Fri, 16 Jul 2010) $
13 *
14 **/
15/*
16 *****************************************************************************
17 *
18 * Copyright (c) 2011, Advanced Micro Devices, Inc.
19 * All rights reserved.
Edward O'Callaghan1542a6f2014-07-06 19:24:06 +100020 *
Frank Vibrans2b4c8312011-02-14 18:30:54 +000021 * 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.
Edward O'Callaghan1542a6f2014-07-06 19:24:06 +100028 * * Neither the name of Advanced Micro Devices, Inc. nor the names of
29 * its contributors may be used to endorse or promote products derived
Frank Vibrans2b4c8312011-02-14 18:30:54 +000030 * from this software without specific prior written permission.
Edward O'Callaghan1542a6f2014-07-06 19:24:06 +100031 *
Frank Vibrans2b4c8312011-02-14 18:30:54 +000032 * 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.
Edward O'Callaghan1542a6f2014-07-06 19:24:06 +100042 *
Frank Vibrans2b4c8312011-02-14 18:30:54 +000043 * ***************************************************************************
44 *
45 */
46
47
48
49#include "AGESA.h"
50#include "amdlib.h"
51#include "mm.h"
52#include "mn.h"
53#include "mt.h"
54#include "mftds.h"
55#include "Ids.h"
56#include "OptionMemory.h"
57#include "Filecode.h"
58CODE_GROUP (G2_PEI)
59RDATA_GROUP (G2_PEI)
60
61#define FILECODE PROC_MEM_FEAT_TABLE_MFTDS_FILECODE
62/*----------------------------------------------------------------------------
63 * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS)
64 *
65 *----------------------------------------------------------------------------
66 */
67
68/*-----------------------------------------------------------------------------
69 * DEFINITIONS AND MACROS
70 *
71 *-----------------------------------------------------------------------------
72 */
73#define MAX_BYTELANES_PER_CHANNEL (8 + 1) ///< Max Bytelanes per channel
74
75/*----------------------------------------------------------------------------
76 * TYPEDEFS, STRUCTURES, ENUMS
77 *
78 *----------------------------------------------------------------------------
79 */
80
81/*----------------------------------------------------------------------------
82 * FUNCTIONS PROTOTYPE
83 *
84 *----------------------------------------------------------------------------
85 */
86
87VOID
88SetTableValues (
89 IN OUT MEM_NB_BLOCK *NBPtr,
90 IN MEM_TABLE_ALIAS MTPtr
91 );
92
93VOID
94SetTableValuesLoop (
95 IN OUT MEM_NB_BLOCK *NBPtr,
96 IN MEM_TABLE_ALIAS *MTPtr,
97 IN UINT8 time
98 );
99
100/*-----------------------------------------------------------------------------
101 *
102 * This function initializes bit field translation table
103 *
104 * @param[in,out] *NBPtr - Pointer to the MEM_TABLE_ALIAS structure
105 * @param[in] time - Indicate the timing for the register which is written.
106 *
107 * @return None
108 * ----------------------------------------------------------------------------
109 */
110VOID
111MemFInitTableDrive (
112 IN OUT MEM_NB_BLOCK *NBPtr,
113 IN UINT8 time
114 )
115{
116 MEM_TABLE_ALIAS *MTPtr;
117 MEM_TABLE_ALIAS *IdsMTPtr;
118
119 ASSERT (NBPtr != NULL);
120 IdsMTPtr = NULL;
121
122 MTPtr = (MEM_TABLE_ALIAS *) NBPtr->RefPtr->TableBasedAlterations;
123
124 IDS_SKIP_HOOK (IDS_GET_DRAM_TABLE, &IdsMTPtr, &(NBPtr->MemPtr->StdHeader)) {
125 IDS_OPTION_HOOK (IDS_INIT_DRAM_TABLE, NBPtr, &(NBPtr->MemPtr->StdHeader));
126 IDS_OPTION_HOOK (IDS_GET_DRAM_TABLE, &IdsMTPtr, &(NBPtr->MemPtr->StdHeader));
127 }
128
129 SetTableValuesLoop (NBPtr, MTPtr, time);
130 SetTableValuesLoop (NBPtr, IdsMTPtr, time);
131}
132
133/*-----------------------------------------------------------------------------
134 *
135 * This function initializes bit field translation table
136 *
137 * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
138 * @param[in,out] *MTPtr - Pointer to the MEM_TABLE_ALIAS structure
139 * @param[in] time - Indicate the timing for the register which is written.
140 *
141 * @return None
142 * ----------------------------------------------------------------------------
143 */
144VOID
145SetTableValuesLoop (
146 IN OUT MEM_NB_BLOCK *NBPtr,
147 IN MEM_TABLE_ALIAS *MTPtr,
148 IN UINT8 time
149 )
150{
151 UINT8 i;
152 UINT8 CurDct;
153
154 if (MTPtr != NULL) {
155 CurDct = NBPtr->Dct;
156 for (i = 0; MTPtr[i].time != MTEnd; i++) {
157 if ((MTPtr[i].attr != MTAuto) && (MTPtr[i].time == time)) {
158 SetTableValues (NBPtr, MTPtr[i]);
159 }
160 }
161 NBPtr->SwitchDCT (NBPtr, CurDct);
162 }
163}
164
165/*-----------------------------------------------------------------------------
166 *
167 * Engine for setting Table Value.
168 *
169 * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
170 * @param[in] MTPtr - Pointer to the MEM_TABLE_ALIAS structure
171 *
172 * @return None
173 * ----------------------------------------------------------------------------
174 */
175VOID
176SetTableValues (
177 IN OUT MEM_NB_BLOCK *NBPtr,
178 IN MEM_TABLE_ALIAS MTPtr
179 )
180{
181 UINT8 AccessType;
182 UINT16 ByteLane;
183 UINT8 Dct;
184 UINT8 i;
185 UINT8 j;
186 UINT32 TempVal[36];
187 UINT8 *DqsSavePtr;
188 UINT8 DqsOffset;
189 BOOLEAN SaveDqs;
190
191 AccessType = 0;
192 DqsSavePtr = NULL;
193 SaveDqs = TRUE;
194
195 ASSERT (MTPtr.time <= MTValidTimePointLimit);
196 ASSERT (MTPtr.attr <= MTAdd);
197 ASSERT (MTPtr.node <= MTNodes);
198 ASSERT (MTPtr.dct <= MTDcts);
199 ASSERT (MTPtr.dimm <= MTDIMMs);
200 ASSERT (MTPtr.data.s.bytelane <= MTBLs);
201
202 for (Dct = 0; Dct < NBPtr->DctCount; Dct++) {
203 if ((MTPtr.dct == MTDcts) || (MTPtr.dct == Dct)) {
204 NBPtr->SwitchDCT (NBPtr, Dct);
205 switch (MTPtr.bfindex) {
206 case BFRcvEnDly:
207 AccessType = AccessRcvEnDly;
208 DqsSavePtr = NULL;
209 break;
210 case BFWrDatDly:
211 AccessType = AccessWrDatDly;
212 DqsSavePtr = NBPtr->ChannelPtr->WrDatDlys;
213 break;
214 case BFRdDqsDly:
215 AccessType = AccessRdDqsDly;
216 DqsSavePtr = NBPtr->ChannelPtr->RdDqsDlys;
217 break;
218 case BFWrDqsDly:
219 AccessType = AccessWrDqsDly;
220 DqsSavePtr = NBPtr->ChannelPtr->WrDqsDlys;
221 break;
222 case BFPhRecDly:
223 AccessType = AccessPhRecDly;
224 SaveDqs = FALSE;
225 break;
226 default:
227 AccessType = 0xFF;
228 break;
229 }
230 if (AccessType == 0xFF) {
231 if (MTPtr.attr == MTOverride) {
232 NBPtr->SetBitField (NBPtr, MTPtr.bfindex, MTPtr.data.s.value);
233 }
234 if (MTPtr.attr == MTSubtract) {
235 NBPtr->SetBitField (NBPtr, MTPtr.bfindex, NBPtr->GetBitField (NBPtr, MTPtr.bfindex) - MTPtr.data.s.value);
236 }
237 if (MTPtr.attr == MTAdd) {
238 NBPtr->SetBitField (NBPtr, MTPtr.bfindex, NBPtr->GetBitField (NBPtr, MTPtr.bfindex) + MTPtr.data.s.value);
239 }
240 } else {
241 // Store the DQS data first
242 for (i = 0; i < MAX_DIMMS_PER_CHANNEL; i++) {
243 for (j = 0; j < MAX_BYTELANES_PER_CHANNEL; j++) {
244 TempVal[i * MAX_BYTELANES_PER_CHANNEL + j] = NBPtr->GetTrainDly (NBPtr, AccessType, DIMM_BYTE_ACCESS (i, j));
245 }
246 }
247 //
248 // Single Value with Bytleane mask option
249 // Indicated by the vtype flag
250 //
251 if (MTPtr.vtype == VT_MSK_VALUE) {
252 // set the value which defined in Memory table.
253 ByteLane = MTPtr.data.s.bytelane;
254 for (i = 0; i < MAX_DIMMS_PER_CHANNEL; i++) {
255 if ((MTPtr.dimm == MTDIMMs) || (MTPtr.dimm == i)) {
256 for (j = 0; j < MAX_BYTELANES_PER_CHANNEL; j++) {
257 DqsOffset = (i * MAX_BYTELANES_PER_CHANNEL + j);
258 if ((ByteLane & (UINT16)1) != 0) {
259 if (MTPtr.attr == MTOverride) {
260 TempVal[DqsOffset] = (UINT16)MTPtr.data.s.value;
261 }
262 if (MTPtr.attr == MTSubtract) {
263 TempVal[DqsOffset] -= (UINT16)MTPtr.data.s.value;
264 }
265 if (MTPtr.attr == MTAdd) {
266 TempVal[DqsOffset] += (UINT16)MTPtr.data.s.value;
267 }
268 NBPtr->SetTrainDly (NBPtr, AccessType, DIMM_BYTE_ACCESS (i, j), (UINT16)TempVal[DqsOffset]);
269 if (SaveDqs) {
270 if (DqsSavePtr == NULL) {
271 NBPtr->ChannelPtr->RcvEnDlys[DqsOffset] = (UINT16)TempVal[DqsOffset];
272 } else {
273 DqsSavePtr[DqsOffset] = (UINT8)TempVal[DqsOffset];
274 }
275 }
276 }
277 ByteLane = ByteLane >> (UINT16)1;
278 }
279 }
280 }
281 } else {
282 // Multiple values specified in a byte array
283 for (i = 0; i < MAX_DIMMS_PER_CHANNEL; i++) {
284 if ((MTPtr.dimm == MTDIMMs) || (MTPtr.dimm == i)) {
285 for (j = 0; j < MAX_BYTELANES_PER_CHANNEL; j++) {
286 DqsOffset = (i * MAX_BYTELANES_PER_CHANNEL + j);
287 if (MTPtr.attr == MTOverride) {
288 TempVal[DqsOffset] = MTPtr.data.bytelanevalue[j];
289 }
290 if (MTPtr.attr == MTSubtract) {
291 TempVal[DqsOffset] -= MTPtr.data.bytelanevalue[j];
292 }
293 if (MTPtr.attr == MTAdd) {
294 TempVal[DqsOffset] += MTPtr.data.bytelanevalue[j];
295 }
296 NBPtr->SetTrainDly (NBPtr, AccessType, DIMM_BYTE_ACCESS (i, j), (UINT16)TempVal[DqsOffset]);
297 if (SaveDqs) {
298 if (DqsSavePtr == NULL) {
299 NBPtr->ChannelPtr->RcvEnDlys[DqsOffset] = (UINT16)TempVal[DqsOffset];
300 } else {
301 DqsSavePtr[DqsOffset] = (UINT8)TempVal[DqsOffset];
302 }
303 }
304 }
305 }
306 }
307 }
308 // set the DQS value to left DIMMs.
309 i = MTPtr.dimm;
310 while ((i != MTDIMMs) && ((++i) < MAX_DIMMS_PER_CHANNEL)) {
311 for (j = 0; j < MAX_BYTELANES_PER_CHANNEL; j++) {
312 NBPtr->SetTrainDly (NBPtr, AccessType, DIMM_BYTE_ACCESS (i, j), (UINT16)TempVal[i * MAX_BYTELANES_PER_CHANNEL + j]);
313 }
314 }
315 }
316 }
317 }
318}
319
320
321
322
323
324