summaryrefslogtreecommitdiffstats
path: root/resources/libreboot/patch/kgpe-d16/0103-northbridge-amd-amdfam10-Add-Family-15h-cache-partit.patch
blob: 15836d480cbf263310f0a5f68917c9eb315d4e1f (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
From 1f667d55b99e81e636572d9f3ac9498ef782536c Mon Sep 17 00:00:00 2001
From: Timothy Pearson <tpearson@raptorengineeringinc.com>
Date: Sat, 8 Aug 2015 20:29:27 -0500
Subject: [PATCH 103/139] northbridge/amd/amdfam10: Add Family 15h cache
 partitioning support

Change-Id: Ie4e28dd886aaa1c586b0919c5fe87ef1696f47e9
Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
---
 src/northbridge/amd/amdfam10/northbridge.c | 94 ++++++++++++++++++++++++++++++
 1 file changed, 94 insertions(+)

diff --git a/src/northbridge/amd/amdfam10/northbridge.c b/src/northbridge/amd/amdfam10/northbridge.c
index 9f132c7..8ad5200 100644
--- a/src/northbridge/amd/amdfam10/northbridge.c
+++ b/src/northbridge/amd/amdfam10/northbridge.c
@@ -1809,9 +1809,103 @@ static void detect_and_enable_probe_filter(device_t dev)
 	}
 }
 
+static void detect_and_enable_cache_partitioning(device_t dev)
+{
+	uint8_t i;
+	uint32_t dword;
+
+	if (is_fam15h()) {
+		printk(BIOS_DEBUG, "Enabling L3 cache partitioning\n");
+
+		uint32_t f5x80;
+		uint8_t cu_enabled;
+		uint8_t compute_unit_count = 0;
+
+		uint32_t f3xe8;
+		uint8_t dual_node = 0;
+
+		for (i = 0; i < sysconf.nodes; i++) {
+			device_t f3x_dev = dev_find_slot(0, PCI_DEVFN(0x18 + i, 3));
+			device_t f4x_dev = dev_find_slot(0, PCI_DEVFN(0x18 + i, 4));
+			device_t f5x_dev = dev_find_slot(0, PCI_DEVFN(0x18 + i, 5));
+
+			f3xe8 = pci_read_config32(f3x_dev, 0xe8);
+
+			/* Check for dual node capability */
+			if (f3xe8 & 0x20000000)
+				dual_node = 1;
+
+			/* Determine the number of active compute units on this node */
+			f5x80 = pci_read_config32(f5x_dev, 0x80);
+			cu_enabled = f5x80 & 0xf;
+			if (cu_enabled == 0x1)
+				compute_unit_count = 1;
+			if (cu_enabled == 0x3)
+				compute_unit_count = 2;
+			if (cu_enabled == 0x7)
+				compute_unit_count = 3;
+			if (cu_enabled == 0xf)
+				compute_unit_count = 4;
+
+			/* Disable BAN mode */
+			dword = pci_read_config32(f3x_dev, 0x1b8);
+			dword &= ~(0x7 << 19);	/* L3BanMode = 0x0 */
+			pci_write_config32(f3x_dev, 0x1b8, dword);
+
+			/* Set up cache mapping */
+			dword = pci_read_config32(f4x_dev, 0x1d4);
+			if (compute_unit_count == 1) {
+				dword |= 0xf;		/* ComputeUnit0SubCacheEn = 0xf */
+			}
+			if (compute_unit_count == 2) {
+				dword &= ~(0xf << 4);	/* ComputeUnit1SubCacheEn = 0xc */
+				dword |= (0xc << 4);
+				dword &= ~0xf;		/* ComputeUnit0SubCacheEn = 0x3 */
+				dword |= 0x3;
+			}
+			if (compute_unit_count == 3) {
+				dword &= ~(0xf << 8);	/* ComputeUnit2SubCacheEn = 0x8 */
+				dword |= (0x8 << 8);
+				dword &= ~(0xf << 4);	/* ComputeUnit1SubCacheEn = 0x4 */
+				dword |= (0x4 << 4);
+				dword &= ~0xf;		/* ComputeUnit0SubCacheEn = 0x3 */
+				dword |= 0x3;
+			}
+			if (compute_unit_count == 4) {
+				dword &= ~(0xf << 12);	/* ComputeUnit3SubCacheEn = 0x8 */
+				dword |= (0x8 << 12);
+				dword &= ~(0xf << 8);	/* ComputeUnit2SubCacheEn = 0x4 */
+				dword |= (0x4 << 8);
+				dword &= ~(0xf << 4);	/* ComputeUnit1SubCacheEn = 0x2 */
+				dword |= (0x2 << 4);
+				dword &= ~0xf;		/* ComputeUnit0SubCacheEn = 0x1 */
+				dword |= 0x1;
+			}
+			pci_write_config32(f4x_dev, 0x1d4, dword);
+
+			/* Enable cache partitioning */
+			pci_write_config32(f4x_dev, 0x1d4, dword);
+			if (compute_unit_count == 1) {
+				dword &= ~(0xf << 26);	/* MaskUpdateForComputeUnit = 0x1 */
+				dword |= (0x1 << 26);
+			} else if (compute_unit_count == 2) {
+				dword &= ~(0xf << 26);	/* MaskUpdateForComputeUnit = 0x3 */
+				dword |= (0x3 << 26);
+			} else if (compute_unit_count == 3) {
+				dword &= ~(0xf << 26);	/* MaskUpdateForComputeUnit = 0x7 */
+				dword |= (0x7 << 26);
+			} else if (compute_unit_count == 4) {
+				dword |= (0xf << 26);	/* MaskUpdateForComputeUnit = 0xf */
+			}
+			pci_write_config32(f4x_dev, 0x1d4, dword);
+		}
+	}
+}
+
 static void cpu_bus_init(device_t dev)
 {
 	detect_and_enable_probe_filter(dev);
+	detect_and_enable_cache_partitioning(dev);
 	initialize_cpus(dev->link_list);
 #if CONFIG_AMD_SB_CIMX
 	sb_After_Pci_Init();
-- 
1.9.1