aboutsummaryrefslogtreecommitdiff
path: root/resources/libreboot/patch/kgpe-d16/0083-northbridge-amd-amdmct-mct_ddr3-Fix-RDIMM-errors-due.patch
blob: 6bf6885f5acf8534157af4faa6fcc595d0f39e42 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
From 34c8a0f868d298f787713a2dd3ba6852c794ae86 Mon Sep 17 00:00:00 2001
From: Timothy Pearson <tpearson@raptorengineeringinc.com>
Date: Sat, 25 Jul 2015 01:23:17 -0500
Subject: [PATCH 083/139] northbridge/amd/amdmct/mct_ddr3: Fix RDIMM errors due
 to undefined number of slots

Change-Id: I488511d6262ffa8207c442d133314aed0f75acfb
Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
---
 src/northbridge/amd/amdmct/mct/mct_d.h         |  2 ++
 src/northbridge/amd/amdmct/mct_ddr3/mct_d.c    | 24 ++++--------------------
 src/northbridge/amd/amdmct/mct_ddr3/mct_d.h    |  2 ++
 src/northbridge/amd/amdmct/mct_ddr3/mctproc.c  |  6 +-----
 src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c   | 12 ++----------
 src/northbridge/amd/amdmct/mct_ddr3/mctsrc.c   |  6 +-----
 src/northbridge/amd/amdmct/mct_ddr3/mctwl.c    |  2 --
 src/northbridge/amd/amdmct/mct_ddr3/mhwlc_d.c  | 20 ++++++--------------
 src/northbridge/amd/amdmct/mct_ddr3/modtrdim.c | 11 ++++++-----
 src/northbridge/amd/amdmct/mct_ddr3/mwlc_d.h   |  4 ----
 src/northbridge/amd/amdmct/wrappers/mcti_d.c   |  7 +++++++
 11 files changed, 31 insertions(+), 65 deletions(-)

diff --git a/src/northbridge/amd/amdmct/mct/mct_d.h b/src/northbridge/amd/amdmct/mct/mct_d.h
index 7569300..296f3f0 100644
--- a/src/northbridge/amd/amdmct/mct/mct_d.h
+++ b/src/northbridge/amd/amdmct/mct/mct_d.h
@@ -691,6 +691,8 @@ struct DCTStatStruc {		/* A per Node structure*/
 					xx0b = disable
 					yy1b = enable with DctSelIntLvAddr set to yyb */
 
+#define NV_MAX_DIMMS_PER_CH	64	/* Maximum number of DIMMs per channel */
+
 /*===============================================================================
 	CBMEM storage
 ===============================================================================*/
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c
index 1758bd6..b616c2d 100644
--- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c
+++ b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c
@@ -803,11 +803,7 @@ static uint32_t fam15h_phy_predriver_clk_calibration_code(struct DCTStatStruc *p
 
 static uint32_t fam15h_output_driver_compensation_code(struct DCTStatStruc *pDCTstat, uint8_t dct)
 {
-	/* FIXME
-	 * Mainboards need to be able to specify the maximum number of DIMMs installable per channel
-	 * For now assume a maximum of 2 DIMMs per channel can be installed
-	 */
-	uint8_t MaxDimmsInstallable = 2;
+	uint8_t MaxDimmsInstallable = mctGet_NVbits(NV_MAX_DIMMS_PER_CH);
 
 	uint8_t package_type;
 	uint32_t calibration_code = 0;
@@ -983,11 +979,7 @@ static uint32_t fam15h_output_driver_compensation_code(struct DCTStatStruc *pDCT
 
 static uint32_t fam15h_address_timing_compensation_code(struct DCTStatStruc *pDCTstat, uint8_t dct)
 {
-	/* FIXME
-	 * Mainboards need to be able to specify the maximum number of DIMMs installable per channel
-	 * For now assume a maximum of 2 DIMMs per channel can be installed
-	 */
-	uint8_t MaxDimmsInstallable = 2;
+	uint8_t MaxDimmsInstallable = mctGet_NVbits(NV_MAX_DIMMS_PER_CH);
 
 	uint8_t package_type;
 	uint32_t calibration_code = 0;
@@ -1165,11 +1157,7 @@ static uint32_t fam15h_address_timing_compensation_code(struct DCTStatStruc *pDC
 
 static uint8_t fam15h_slow_access_mode(struct DCTStatStruc *pDCTstat, uint8_t dct)
 {
-	/* FIXME
-	 * Mainboards need to be able to specify the maximum number of DIMMs installable per channel
-	 * For now assume a maximum of 2 DIMMs per channel can be installed
-	 */
-	uint8_t MaxDimmsInstallable = 2;
+	uint8_t MaxDimmsInstallable = mctGet_NVbits(NV_MAX_DIMMS_PER_CH);
 
 	uint8_t package_type;
 	uint32_t slow_access = 0;
@@ -5868,11 +5856,7 @@ static void mct_ProgramODT_D(struct MCTStatStruc *pMCTstat,
 
 	printk(BIOS_DEBUG, "%s: Start\n", __func__);
 
-	/* FIXME
-	 * Mainboards need to be able to specify the maximum number of DIMMs installable per channel
-	 * For now assume a maximum of 2 DIMMs per channel can be installed
-	 */
-	uint8_t MaxDimmsInstallable = 2;
+	uint8_t MaxDimmsInstallable = mctGet_NVbits(NV_MAX_DIMMS_PER_CH);
 
 	if (is_fam15h()) {
 		/* Obtain number of DIMMs on channel */
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h
index 7bc392b..6b5d8c1 100644
--- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h
+++ b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h
@@ -957,6 +957,8 @@ struct amd_s3_persistent_data {
 					xx0b = disable
 					yy1b = enable with DctSelIntLvAddr set to yyb */
 
+#define NV_MAX_DIMMS_PER_CH	64	/* Maximum number of DIMMs per channel */
+
 /*===============================================================================
         CBMEM storage
 ===============================================================================*/
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctproc.c b/src/northbridge/amd/amdmct/mct_ddr3/mctproc.c
index 32b447f..738304e 100644
--- a/src/northbridge/amd/amdmct/mct_ddr3/mctproc.c
+++ b/src/northbridge/amd/amdmct/mct_ddr3/mctproc.c
@@ -23,11 +23,7 @@ u32 mct_SetDramConfigMisc2(struct DCTStatStruc *pDCTstat, u8 dct, u32 misc2)
 {
 	u32 val;
 
-	/* FIXME
-	 * Mainboards need to be able to specify the maximum number of DIMMs installable per channel
-	 * For now assume a maximum of 2 DIMMs per channel can be installed
-	 */
-	uint8_t MaxDimmsInstallable = 2;
+	uint8_t MaxDimmsInstallable = mctGet_NVbits(NV_MAX_DIMMS_PER_CH);
 
 	if (pDCTstat->LogicalCPUID & AMD_FAM15_ALL) {
 		uint8_t cs_mux_45;
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c b/src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c
index dfbd2d9..6a2c2a7 100644
--- a/src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c
+++ b/src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c
@@ -51,11 +51,7 @@ static uint8_t fam15_rttwr(struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t d
 	else
 		frequency_index = Get_NB32_DCT(pDCTstat->dev_dct, dct, 0x94) & 0x7;
 
-	/* FIXME
-	 * Mainboards need to be able to specify the maximum number of DIMMs installable per channel
-	 * For now assume a maximum of 2 DIMMs per channel can be installed
-	 */
-	uint8_t MaxDimmsInstallable = 2;
+	uint8_t MaxDimmsInstallable = mctGet_NVbits(NV_MAX_DIMMS_PER_CH);
 
 	if (is_fam15h()) {
 		if (pDCTstat->Status & (1 << SB_LoadReduced)) {
@@ -184,11 +180,7 @@ static uint8_t fam15_rttnom(struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t
 	else
 		frequency_index = Get_NB32_DCT(pDCTstat->dev_dct, dct, 0x94) & 0x7;
 
-	/* FIXME
-	 * Mainboards need to be able to specify the maximum number of DIMMs installable per channel
-	 * For now assume a maximum of 2 DIMMs per channel can be installed
-	 */
-	uint8_t MaxDimmsInstallable = 2;
+	uint8_t MaxDimmsInstallable = mctGet_NVbits(NV_MAX_DIMMS_PER_CH);
 
 	if (is_fam15h()) {
 		if (pDCTstat->Status & (1 << SB_LoadReduced)) {
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctsrc.c b/src/northbridge/amd/amdmct/mct_ddr3/mctsrc.c
index 57641a1..9313673 100644
--- a/src/northbridge/amd/amdmct/mct_ddr3/mctsrc.c
+++ b/src/northbridge/amd/amdmct/mct_ddr3/mctsrc.c
@@ -105,11 +105,7 @@ static uint16_t fam15_receiver_enable_training_seed(struct DCTStatStruc *pDCTsta
 	uint32_t dword;
 	uint16_t seed = 0;
 
-	/* FIXME
-	 * Mainboards need to be able to specify the maximum number of DIMMs installable per channel
-	 * For now assume a maximum of 2 DIMMs per channel can be installed
-	 */
-	uint8_t MaxDimmsInstallable = 2;
+	uint8_t MaxDimmsInstallable = mctGet_NVbits(NV_MAX_DIMMS_PER_CH);
 
 	uint8_t channel = dct;
 	if (package_type == PT_GR) {
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctwl.c b/src/northbridge/amd/amdmct/mct_ddr3/mctwl.c
index 0ff4484..6b63ba0 100644
--- a/src/northbridge/amd/amdmct/mct_ddr3/mctwl.c
+++ b/src/northbridge/amd/amdmct/mct_ddr3/mctwl.c
@@ -31,8 +31,6 @@ void PrepareC_MCT(struct MCTStatStruc *pMCTstat,
 					struct DCTStatStruc *pDCTstat)
 {
 	pDCTstat->C_MCTPtr->AgesaDelay = AgesaDelay;
-	pDCTstat->C_MCTPtr->PlatMaxTotalDimms = mctGet_NVbits(NV_MAX_DIMMS);
-	pDCTstat->C_MCTPtr->PlatMaxDimmsDct = pDCTstat->C_MCTPtr->PlatMaxTotalDimms >> 1;
 }
 
 void PrepareC_DCT(struct MCTStatStruc *pMCTstat,
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mhwlc_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mhwlc_d.c
index bd37ba7..47ad152 100644
--- a/src/northbridge/amd/amdmct/mct_ddr3/mhwlc_d.c
+++ b/src/northbridge/amd/amdmct/mct_ddr3/mhwlc_d.c
@@ -419,11 +419,7 @@ static uint16_t unbuffered_dimm_nominal_termination_emrs(uint8_t number_of_dimms
 {
 	uint16_t term;
 
-	/* FIXME
-	 * Mainboards need to be able to specify the maximum number of DIMMs installable per channel
-	 * For now assume a maximum of 2 DIMMs per channel can be installed
-	 */
-	uint8_t MaxDimmsInstallable = 2;
+	uint8_t MaxDimmsInstallable = mctGet_NVbits(NV_MAX_DIMMS_PER_CH);
 
 	if (number_of_dimms == 1) {
 		if (MaxDimmsInstallable < 3) {
@@ -452,11 +448,7 @@ static uint16_t unbuffered_dimm_dynamic_termination_emrs(uint8_t number_of_dimms
 {
 	uint16_t term;
 
-	/* FIXME
-	 * Mainboards need to be able to specify the maximum number of DIMMs installable per channel
-	 * For now assume a maximum of 2 DIMMs per channel can be installed
-	 */
-	uint8_t MaxDimmsInstallable = 2;
+	uint8_t MaxDimmsInstallable = mctGet_NVbits(NV_MAX_DIMMS_PER_CH);
 
 	if (number_of_dimms == 1) {
 		if (MaxDimmsInstallable < 3) {
@@ -574,7 +566,7 @@ void prepareDimms(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat,
 					if (number_of_dimms > 1) {
 						if (rank == 0) {
 							/* Get Rtt_WR for the current DIMM and rank */
-							uint16_t dynamic_term = unbuffered_dimm_dynamic_termination_emrs(pDCTData->MaxDimmsInstalled, MemClkFreq, pDCTData->DimmRanks[currDimm]);
+							uint16_t dynamic_term = unbuffered_dimm_dynamic_termination_emrs(pDCTData->MaxDimmsInstalled, MemClkFreq, pDCTData->DimmRanks[dimm]);
 
 							/* Convert dynamic termination code to corresponding nominal termination code */
 							if (dynamic_term == 0x200)
@@ -584,13 +576,13 @@ void prepareDimms(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat,
 							else
 								tempW1 = 0x0;
 						} else {
-							tempW1 = unbuffered_dimm_nominal_termination_emrs(pDCTData->MaxDimmsInstalled, MemClkFreq, pDCTData->DimmRanks[currDimm], rank);
+							tempW1 = unbuffered_dimm_nominal_termination_emrs(pDCTData->MaxDimmsInstalled, MemClkFreq, pDCTData->DimmRanks[dimm], rank);
 						}
 					} else {
-						tempW1 = unbuffered_dimm_nominal_termination_emrs(pDCTData->MaxDimmsInstalled, MemClkFreq, pDCTData->DimmRanks[currDimm], rank);
+						tempW1 = unbuffered_dimm_nominal_termination_emrs(pDCTData->MaxDimmsInstalled, MemClkFreq, pDCTData->DimmRanks[dimm], rank);
 					}
 				} else {
-					tempW1 = unbuffered_dimm_nominal_termination_emrs(pDCTData->MaxDimmsInstalled, MemClkFreq, pDCTData->DimmRanks[currDimm], rank);
+					tempW1 = unbuffered_dimm_nominal_termination_emrs(pDCTData->MaxDimmsInstalled, MemClkFreq, pDCTData->DimmRanks[dimm], rank);
 				}
 			}
 		}
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/modtrdim.c b/src/northbridge/amd/amdmct/mct_ddr3/modtrdim.c
index c92143c..bb4c3c0 100644
--- a/src/northbridge/amd/amdmct/mct_ddr3/modtrdim.c
+++ b/src/northbridge/amd/amdmct/mct_ddr3/modtrdim.c
@@ -2,6 +2,7 @@
  * This file is part of the coreboot project.
  *
  * Copyright (C) 2010 Advanced Micro Devices, Inc.
+ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -57,7 +58,7 @@ static u32 RttNomTargetRegDimm (sMCTStruct *pMCTData, sDCTStruct *pDCTData, u8 d
 	u32 tempW1;
 	tempW1 = 0;
 	if (wl) {
-		switch (pMCTData->PlatMaxDimmsDct) {
+		switch (mctGet_NVbits(NV_MAX_DIMMS_PER_CH)) {
 		case 2:
 			/* 2 dimms per channel */
 			if (pDCTData->MaxDimmsInstalled == 1) {
@@ -111,7 +112,7 @@ static u32 RttNomTargetRegDimm (sMCTStruct *pMCTData, sDCTStruct *pDCTData, u8 d
 			ASSERT (FALSE);
 		}
 	} else {
-		switch (pMCTData->PlatMaxDimmsDct) {
+		switch (mctGet_NVbits(NV_MAX_DIMMS_PER_CH)) {
 		case 2:
 			/* 2 dimms per channel */
 			if ((pDCTData->DimmRanks[dimm] == 4) && (rank == 1)) {
@@ -167,7 +168,7 @@ static u32 RttNomTargetRegDimm (sMCTStruct *pMCTData, sDCTStruct *pDCTData, u8 d
  */
 static u32 RttNomNonTargetRegDimm (sMCTStruct *pMCTData, sDCTStruct *pDCTData, u8 dimm, BOOL wl, u8 MemClkFreq, u8 rank)
 {
-	if ((wl) && (pMCTData->PlatMaxDimmsDct == 2) && (pDCTData->DimmRanks[dimm] == 2) && (rank == 1)) {
+	if ((wl) && (mctGet_NVbits(NV_MAX_DIMMS_PER_CH) == 2) && (pDCTData->DimmRanks[dimm] == 2) && (rank == 1)) {
 		return 0x00;	/* for non-target dimm during WL, the second rank of a DR dimm need to have Rtt_Nom = OFF */
 	} else {
 		return RttNomTargetRegDimm (pMCTData, pDCTData, dimm, FALSE, MemClkFreq, rank);	/* otherwise, the same as target dimm in normal mode. */
@@ -197,7 +198,7 @@ static u32 RttWrRegDimm (sMCTStruct *pMCTData, sDCTStruct *pDCTData, u8 dimm, BO
 	if (wl) {
 		tempW1 = 0x00;	/* Rtt_WR = OFF */
 	} else {
-		switch (pMCTData->PlatMaxDimmsDct) {
+		switch (mctGet_NVbits(NV_MAX_DIMMS_PER_CH)) {
 		case 2:
 			if (pDCTData->MaxDimmsInstalled == 1) {
 				if (pDCTData->DimmRanks[dimm] != 4) {
@@ -262,7 +263,7 @@ static u8 WrLvOdtRegDimm (sMCTStruct *pMCTData, sDCTStruct *pDCTData, u8 dimm)
 		}
 		i += 2;
 	}
-	if (pMCTData->PlatMaxDimmsDct == 2) {
+	if (mctGet_NVbits(NV_MAX_DIMMS_PER_CH) == 2) {
 		if ((pDCTData->DimmRanks[dimm] == 4) && (pDCTData->MaxDimmsInstalled != 1)) {
 			if (dimm >= 2) {
 				WrLvOdt1 = (u8)bitTestReset (WrLvOdt1, (dimm - 2));
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mwlc_d.h b/src/northbridge/amd/amdmct/mct_ddr3/mwlc_d.h
index 162340e..12e7c4a 100644
--- a/src/northbridge/amd/amdmct/mct_ddr3/mwlc_d.h
+++ b/src/northbridge/amd/amdmct/mct_ddr3/mwlc_d.h
@@ -109,10 +109,6 @@
 
 typedef struct _sMCTStruct
 {
-	u8 PlatMaxTotalDimms;			/* IBV defined total number of DIMMs */
-						/* on a particular node */
-	u8 PlatMaxDimmsDct;			/* IBV defined maximum number of */
-						/* DIMMs on a DCT */
 	void (*AgesaDelay)(u32 delayval);	/* IBV defined Delay Function */
 } sMCTStruct;
 
diff --git a/src/northbridge/amd/amdmct/wrappers/mcti_d.c b/src/northbridge/amd/amdmct/wrappers/mcti_d.c
index ce2329d..28d298f 100644
--- a/src/northbridge/amd/amdmct/wrappers/mcti_d.c
+++ b/src/northbridge/amd/amdmct/wrappers/mcti_d.c
@@ -74,6 +74,13 @@ static u16 mctGet_NVbits(u8 index)
 		val = MAX_DIMMS_SUPPORTED;
 		//val = 8;
 		break;
+	case NV_MAX_DIMMS_PER_CH:
+		/* FIXME
+		 * Mainboards need to be able to specify the maximum number of DIMMs installable per channel
+		 * For now assume a maximum of 2 DIMMs per channel can be installed
+		 */
+		val = 2;
+		break;
 	case NV_MAX_MEMCLK:
 		/* Maximum platform supported memclk */
 		val =  MEM_MAX_LOAD_FREQ;
-- 
1.9.1