summaryrefslogtreecommitdiffstats
path: root/resources/libreboot/patch/coreboot/33fb4cf0ffb01be8bcb6b488872c87eb50e7d77f/grub/kgpe-d16/0026-mainboard-asus-kgpe-d16-Set-DDR3-memory-voltage-base.patch
blob: 9d6ebc8f1b1bd9c695edf4f435856a4e30c13ce3 (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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
From 7b1479a41c0fd5741f03fff5ce6ed3676f41b4dc Mon Sep 17 00:00:00 2001
From: Timothy Pearson <tpearson@raptorengineeringinc.com>
Date: Sun, 10 May 2015 04:37:56 -0500
Subject: [PATCH 026/143] mainboard/asus/kgpe-d16: Set DDR3 memory voltage
 based on SPD data

Change-Id: I21777283ce0fd3c607951204a63ff67dc656c8cc
Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
---
 src/mainboard/asus/kgpe-d16/Kconfig      |    1 +
 src/mainboard/asus/kgpe-d16/cmos.default |    1 +
 src/mainboard/asus/kgpe-d16/cmos.layout  |    5 ++
 src/mainboard/asus/kgpe-d16/romstage.c   |   76 ++++++++++++++++++++++++++++--
 4 files changed, 78 insertions(+), 5 deletions(-)

diff --git a/src/mainboard/asus/kgpe-d16/Kconfig b/src/mainboard/asus/kgpe-d16/Kconfig
index f9556fc..9471692 100644
--- a/src/mainboard/asus/kgpe-d16/Kconfig
+++ b/src/mainboard/asus/kgpe-d16/Kconfig
@@ -6,6 +6,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy
 	select DIMM_DDR3
 	select DIMM_REGISTERED
 	# select QRANK_DIMM_SUPPORT
+	select DIMM_VOLTAGE_SET_SUPPORT
 	select NORTHBRIDGE_AMD_AMDFAM10
 	select SOUTHBRIDGE_AMD_SR5650
 	select SOUTHBRIDGE_AMD_SB700
diff --git a/src/mainboard/asus/kgpe-d16/cmos.default b/src/mainboard/asus/kgpe-d16/cmos.default
index e920297..39a4778 100644
--- a/src/mainboard/asus/kgpe-d16/cmos.default
+++ b/src/mainboard/asus/kgpe-d16/cmos.default
@@ -6,6 +6,7 @@ iommu = Disable
 nmi = Disable
 hypertransport_speed_limit = Auto
 max_mem_clock = DDR3-1600
+minimum_memory_voltage = 1.5V
 ECC_memory = Enable
 ECC_redirection = Disable
 ecc_scrub_rate = 1.28us
diff --git a/src/mainboard/asus/kgpe-d16/cmos.layout b/src/mainboard/asus/kgpe-d16/cmos.layout
index b9266dc..110e0bb 100644
--- a/src/mainboard/asus/kgpe-d16/cmos.layout
+++ b/src/mainboard/asus/kgpe-d16/cmos.layout
@@ -41,6 +41,7 @@ entries
 456          1       e       1        ECC_memory
 457          1       e       1        ECC_redirection
 458          4       e       11       hypertransport_speed_limit
+462          2       e       12       minimum_memory_voltage
 477          1       e       1        ieee1394
 728        256       h       0        user_data
 984         16       h       0        check_sum
@@ -129,6 +130,10 @@ enumerations
 11    13    400MHz
 11    14    300MHz
 11    15    200MHz
+12    0     1.5V
+12    1     1.35V
+12    2     1.25V
+12    3     1.15V
 
 checksums
 
diff --git a/src/mainboard/asus/kgpe-d16/romstage.c b/src/mainboard/asus/kgpe-d16/romstage.c
index 3431bab..18e7c16 100644
--- a/src/mainboard/asus/kgpe-d16/romstage.c
+++ b/src/mainboard/asus/kgpe-d16/romstage.c
@@ -135,7 +135,7 @@ static void activate_spd_rom(const struct mem_controller *ctrl) {
  */
 static void set_ddr3_voltage(uint8_t node, uint8_t index) {
 	uint8_t byte;
-	uint8_t value;
+	uint8_t value = 0;
 
 	if (index == 0)
 		value = 0x0;
@@ -161,6 +161,74 @@ static void set_ddr3_voltage(uint8_t node, uint8_t index) {
 	byte = pci_read_config8(PCI_DEV(0, 0x14, 3), 0xd0);
 	byte &= 0x0f;
 	pci_write_config8(PCI_DEV(0, 0x14, 3), 0xd0, byte);
+
+	printk(BIOS_DEBUG, "Node %02d DIMM voltage set to index %02x\n", node, index);
+}
+
+void DIMMSetVoltages(struct MCTStatStruc *pMCTstat,
+				struct DCTStatStruc *pDCTstatA) {
+	/* This mainboard allows the DIMM voltage to be set per-socket.
+	 * Therefore, for each socket, iterate over all DIMMs to find the
+	 * lowest supported voltage common to all DIMMs on that socket.
+	 */
+	uint8_t nvram;
+	uint8_t dimm;
+	uint8_t node;
+	uint8_t socket;
+	uint8_t allowed_voltages = 0xf;	/* The mainboard VRMs allow 1.15V, 1.25V, 1.35V, and 1.5V */
+	uint32_t set_voltage = 0;
+
+	if (get_option(&nvram, "minimum_memory_voltage") == CB_SUCCESS) {
+		if (nvram == 2)
+			allowed_voltages = 0x7;	/* Allow 1.25V, 1.35V, and 1.5V */
+		if (nvram == 1)
+			allowed_voltages = 0x3;	/* Allow 1.35V and 1.5V */
+		if (nvram == 0)
+			allowed_voltages = 0x1;	/* Allow 1.5V only */
+	}
+
+	for (node = 0; node < MAX_NODES_SUPPORTED; node++) {
+		socket = node / 2;
+		struct DCTStatStruc *pDCTstat;
+		pDCTstat = pDCTstatA + node;
+		if (pDCTstat->NodePresent) {
+			for (dimm = 0; dimm < MAX_DIMMS_SUPPORTED; dimm++) {
+				if (pDCTstat->DIMMValid & (1 << dimm)) {
+					allowed_voltages &= pDCTstat->DimmSupportedVoltages[dimm];
+				}
+			}
+		}
+
+		if (pDCTstat->NodePresent && (node & 0x1)) {
+			/* Set voltages */
+			if (allowed_voltages & 0x8) {
+				set_voltage = 1150;
+				set_ddr3_voltage(socket, 3);
+			} else if (allowed_voltages & 0x4) {
+				set_voltage = 1250;
+				set_ddr3_voltage(socket, 2);
+			} else if (allowed_voltages & 0x2) {
+				set_voltage = 1350;
+				set_ddr3_voltage(socket, 1);
+			} else {
+				set_voltage = 1500;
+				set_ddr3_voltage(socket, 0);
+			}
+
+			/* Save final DIMM voltages for SMBIOS use */
+			if (pDCTstat->NodePresent) {
+				for (dimm = 0; dimm < MAX_DIMMS_SUPPORTED; dimm++) {
+					pDCTstat->DimmConfiguredVoltage[dimm] = set_voltage;
+				}
+			}
+			pDCTstat = pDCTstatA + (node - 1);
+			if (pDCTstat->NodePresent) {
+				for (dimm = 0; dimm < MAX_DIMMS_SUPPORTED; dimm++) {
+					pDCTstat->DimmConfiguredVoltage[dimm] = set_voltage;
+				}
+			}
+		}
+	}
 }
 
 static void set_peripheral_control_lines(void) {
@@ -355,10 +423,8 @@ void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
 		die("After soft_reset_x - shouldn't see this message!!!\n");
 	}
 
-	/* Set DDR memory voltage
-	 * FIXME
-	 * This should be set based on the output of the DIMM SPDs
-	 * For now it is locked to 1.5V
+	/* Set default DDR memory voltage
+	 * This will be overridden later during RAM initialization
 	 */
 	set_lpc_sticky_ctl(1);	/* Retain LPC/IMC GPIO configuration during S3 sleep */
 	if (!s3resume) {	/* Avoid supply voltage glitches while the DIMMs are retaining data */
-- 
1.7.9.5