summaryrefslogtreecommitdiffstats
path: root/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0013-nb-amd-mct_ddr3-Update-drive-strength-configuration.patch
blob: d9b70ca01d3ac7876b8b9e37f218a33958a36549 (plain)
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
From cebd4b26e543f7284ee6fa48531315bc6d40523d Mon Sep 17 00:00:00 2001
From: Timothy Pearson <tpearson@raptorengineeringinc.com>
Date: Tue, 24 Nov 2015 14:11:50 -0600
Subject: [PATCH 13/45] nb/amd/mct_ddr3: Update drive strength configuration

The existing drive strength calibration code did not strictly
follow the BKDG-defined setup process.  Bring the calibration
code in line with the BKDG recommendations.

Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
---
 src/northbridge/amd/amdmct/mct_ddr3/mct_d.c | 49 +++++++++++++++++++----------
 1 file changed, 32 insertions(+), 17 deletions(-)

diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c
index beb71f9..9724008 100644
--- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c
+++ b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c
@@ -6828,7 +6828,7 @@ static void InitPhyCompensation(struct MCTStatStruc *pMCTstat,
 		/* Program TxPreP/TxPreN for data lanes (Stage 1) */
 		for (index = 0; index < 0x9; index++) {
 			dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0006 | (index << 8));
-			dword &= ~(0xfff);
+			dword &= ~(0xffff);
 			dword |= tx_pre;
 			Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0006 | (index << 8), dword);
 		}
@@ -6841,13 +6841,13 @@ static void InitPhyCompensation(struct MCTStatStruc *pMCTstat,
 		/* Program TxPreP/TxPreN for data lanes (Stage 2) */
 		for (index = 0; index < 0x9; index++) {
 			dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f000a | (index << 8));
-			dword &= ~(0xfff);
+			dword &= ~(0xffff);
 			dword |= tx_pre;
 			Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f000a | (index << 8), dword);
 		}
 		for (index = 0; index < 0x9; index++) {
 			dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0002 | (index << 8));
-			dword &= ~(0xfff);
+			dword &= ~(0xffff);
 			dword |= (0x8000 | tx_pre);
 			Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0002 | (index << 8), dword);
 		}
@@ -6859,15 +6859,15 @@ static void InitPhyCompensation(struct MCTStatStruc *pMCTstat,
 
 		/* Program TxPreP/TxPreN for command/address lines (Stage 1) */
 		dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8006);
-		dword &= ~(0xfff);
+		dword &= ~(0xffff);
 		dword |= tx_pre;
 		Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8006, dword);
 		dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f800a);
-		dword &= ~(0xfff);
+		dword &= ~(0xffff);
 		dword |= tx_pre;
 		Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f800a, dword);
 		dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8002);
-		dword &= ~(0xfff);
+		dword &= ~(0xffff);
 		dword |= (0x8000 | tx_pre);
 		Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8002, dword);
 
@@ -6878,31 +6878,31 @@ static void InitPhyCompensation(struct MCTStatStruc *pMCTstat,
 
 		/* Program TxPreP/TxPreN for command/address lines (Stage 2) */
 		dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8106);
-		dword &= ~(0xfff);
+		dword &= ~(0xffff);
 		dword |= tx_pre;
 		Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8106, dword);
 		dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f810a);
-		dword &= ~(0xfff);
+		dword &= ~(0xffff);
 		dword |= tx_pre;
 		Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f810a, dword);
 		dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc006);
-		dword &= ~(0xfff);
+		dword &= ~(0xffff);
 		dword |= tx_pre;
 		Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc006, dword);
 		dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc00a);
-		dword &= ~(0xfff);
+		dword &= ~(0xffff);
 		dword |= tx_pre;
 		Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc00a, dword);
 		dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc00e);
-		dword &= ~(0xfff);
+		dword &= ~(0xffff);
 		dword |= tx_pre;
 		Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc00e, dword);
 		dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc012);
-		dword &= ~(0xfff);
+		dword &= ~(0xffff);
 		dword |= tx_pre;
 		Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc012, dword);
 		dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8102);
-		dword &= ~(0xfff);
+		dword &= ~(0xffff);
 		dword |= (0x8000 | tx_pre);
 		Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8102, dword);
 
@@ -6913,7 +6913,7 @@ static void InitPhyCompensation(struct MCTStatStruc *pMCTstat,
 
 		/* Program TxPreP/TxPreN for command/address lines (Stage 3) */
 		dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc002);
-		dword &= ~(0xfff);
+		dword &= ~(0xffff);
 		dword |= (0x8000 | tx_pre);
 		Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc002, dword);
 
@@ -6924,17 +6924,32 @@ static void InitPhyCompensation(struct MCTStatStruc *pMCTstat,
 
 		/* Program TxPreP/TxPreN for clock lines */
 		dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f2002);
-		dword &= ~(0xfff);
+		dword &= ~(0xffff);
 		dword |= (0x8000 | tx_pre);
 		Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f2002, dword);
 		dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f2102);
-		dword &= ~(0xfff);
+		dword &= ~(0xffff);
 		dword |= (0x8000 | tx_pre);
 		Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f2102, dword);
 		dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f2202);
-		dword &= ~(0xfff);
+		dword &= ~(0xffff);
 		dword |= (0x8000 | tx_pre);
 		Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f2202, dword);
+
+		/* Be extra safe and wait for the predriver calibration to be applied
+		 * to the hardware.  The BKDG does not require this, but it does take
+		 * some time for the data to propagate, so it's probably a good idea.
+		 */
+		uint8_t predriver_cal_pending = 1;
+		printk(BIOS_DEBUG, "Waiting for predriver calibration to be applied...");
+		while (predriver_cal_pending) {
+			predriver_cal_pending = 0;
+			for (index = 0; index < 0x9; index++) {
+				if (Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0002 | (index << 8)) & 0x8000)
+					predriver_cal_pending = 1;
+			}
+		}
+		printk(BIOS_DEBUG, "done!\n");
 	} else {
 		dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x00);
 		dword = 0;
-- 
2.1.4