aboutsummaryrefslogtreecommitdiff
path: root/src/northbridge/amd/amdfam10
diff options
context:
space:
mode:
Diffstat (limited to 'src/northbridge/amd/amdfam10')
-rw-r--r--src/northbridge/amd/amdfam10/link_control.c81
-rw-r--r--src/northbridge/amd/amdfam10/northbridge.c58
2 files changed, 107 insertions, 32 deletions
diff --git a/src/northbridge/amd/amdfam10/link_control.c b/src/northbridge/amd/amdfam10/link_control.c
index 1091ef4f2e..7fa9f12b05 100644
--- a/src/northbridge/amd/amdfam10/link_control.c
+++ b/src/northbridge/amd/amdfam10/link_control.c
@@ -49,15 +49,94 @@ static inline uint8_t is_fam15h(void)
static void nb_control_init(struct device *dev)
{
+ uint8_t enable_c_states;
+ uint8_t enable_cc6;
uint32_t dword;
printk(BIOS_DEBUG, "NB: Function 4 Link Control.. ");
+ /* Configure L3 Power Control */
+ dword = pci_read_config32(dev, 0x1c4);
+ dword |= (0x1 << 8); /* L3PwrSavEn = 1 */
+ pci_write_config32(dev, 0x1c4, dword);
+
if (is_fam15h()) {
+ /* Configure L3 Control 2 */
+ dword = pci_read_config32(dev, 0x1cc);
+ dword &= ~(0x7 << 6); /* ImplRdProjDelayThresh = 0x2 */
+ dword |= (0x2 << 6);
+ pci_write_config32(dev, 0x1cc, dword);
+
+ /* Configure TDP Accumulator Divisor Control */
+ dword = pci_read_config32(dev, 0x104);
+ dword &= ~(0xfff << 2); /* TdpAccDivRate = 0xc8 */
+ dword |= (0xc8 << 2);
+ dword &= ~0x3; /* TdpAccDivVal = 0x1 */
+ dword |= 0x1;
+ pci_write_config32(dev, 0x104, dword);
+
+ /* Configure Sample and Residency Timers */
+ dword = pci_read_config32(dev, 0x110);
+ dword &= ~0xfff; /* CSampleTimer = 0x1 */
+ dword |= 0x1;
+ pci_write_config32(dev, 0x110, dword);
+
+ /* Configure APM TDP Control */
+ dword = pci_read_config32(dev, 0x16c);
+ dword |= (0x1 << 4); /* ApmTdpLimitIntEn = 1 */
+ pci_write_config32(dev, 0x16c, dword);
+
/* Enable APM */
dword = pci_read_config32(dev, 0x15c);
dword |= (0x1 << 7); /* ApmMasterEn = 1 */
pci_write_config32(dev, 0x15c, dword);
+
+ enable_c_states = 0;
+ enable_cc6 = 0;
+#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
+ uint8_t nvram;
+
+ if (get_option(&nvram, "cpu_c_states") == CB_SUCCESS)
+ enable_c_states = !!nvram;
+
+ if (get_option(&nvram, "cpu_cc6_state") == CB_SUCCESS)
+ enable_cc6 = !!nvram;
+#endif
+
+ if (enable_c_states) {
+ /* Configure C-state Control 1 */
+ dword = pci_read_config32(dev, 0x118);
+ dword |= (0x1 << 24); /* PwrGateEnCstAct1 = 1 */
+ dword &= ~(0x7 << 21); /* ClkDivisorCstAct1 = 0x0 */
+ dword &= ~(0x3 << 18); /* CacheFlushTmrSelCstAct1 = 0x1 */
+ dword |= (0x1 << 18);
+ dword |= (0x1 << 17); /* CacheFlushEnCstAct1 = 1 */
+ dword |= (0x1 << 16); /* CpuPrbEnCstAct1 = 1 */
+ dword &= ~(0x1 << 8); /* PwrGateEnCstAct0 = 0 */
+ dword &= ~(0x7 << 5); /* ClkDivisorCstAct0 = 0x0 */
+ dword &= ~(0x3 << 2); /* CacheFlushTmrSelCstAct0 = 0x2 */
+ dword |= (0x2 << 2);
+ dword |= (0x1 << 1); /* CacheFlushEnCstAct0 = 1 */
+ dword |= 0x1; /* CpuPrbEnCstAct0 = 1 */
+ pci_write_config32(dev, 0x118, dword);
+
+ /* Configure C-state Control 2 */
+ dword = pci_read_config32(dev, 0x11c);
+ dword &= ~(0x1 << 8); /* PwrGateEnCstAct2 = 0 */
+ dword &= ~(0x7 << 5); /* ClkDivisorCstAct2 = 0x0 */
+ dword &= ~(0x3 << 2); /* CacheFlushTmrSelCstAct0 = 0x0 */
+ dword &= ~(0x1 << 1); /* CacheFlushEnCstAct0 = 0 */
+ dword &= ~(0x1); /* CpuPrbEnCstAct0 = 0 */
+ pci_write_config32(dev, 0x11c, dword);
+
+ /* Configure C-state Policy Control 1 */
+ dword = pci_read_config32(dev, 0x128);
+ dword &= ~(0x7f << 5); /* CacheFlushTmr = 0x28 */
+ dword |= (0x28 << 5);
+ dword &= ~0x1; /* CoreCstateMode = !enable_cc6 */
+ dword |= ((enable_cc6)?0:1);
+ pci_write_config32(dev, 0x128, dword);
+ }
}
printk(BIOS_DEBUG, "done.\n");
@@ -83,4 +162,4 @@ static const struct pci_driver mcf4_driver_fam15 __pci_driver = {
.ops = &mcf4_ops,
.vendor = PCI_VENDOR_ID_AMD,
.device = 0x1604,
-}; \ No newline at end of file
+};
diff --git a/src/northbridge/amd/amdfam10/northbridge.c b/src/northbridge/amd/amdfam10/northbridge.c
index 116789ce11..0c1971bbc4 100644
--- a/src/northbridge/amd/amdfam10/northbridge.c
+++ b/src/northbridge/amd/amdfam10/northbridge.c
@@ -766,53 +766,49 @@ static void amdfam10_domain_read_resources(device_t dev)
uint8_t num_nodes;
/* Find highest DRAM range (DramLimitAddr) */
+ num_nodes = 0;
max_node = 0;
max_range = -1;
interleaved = 0;
max_range_limit = 0;
- for (range = 0; range < 8; range++) {
- dword = f1_read_config32(0x40 + (range * 0x8));
- if (!(dword & 0x3))
- continue;
-
- if ((dword >> 8) & 0x7)
- interleaved = 1;
-
- dword = f1_read_config32(0x44 + (range * 0x8));
- dword2 = f1_read_config32(0x144 + (range * 0x8));
- qword = ((((uint64_t)dword) >> 16) & 0xffff) << 24;
- qword |= (((uint64_t)dword2) & 0xff) << 40;
-
- if (qword > max_range_limit) {
- max_range = range;
- max_range_limit = qword;
- max_node = dword & 0x7;
- }
- }
-
- num_nodes = 0;
device_t node_dev;
for (node = 0; node < FX_DEVS; node++) {
node_dev = get_node_pci(node, 0);
/* Test for node presence */
- if ((node_dev) && (pci_read_config32(node_dev, PCI_VENDOR_ID) != 0xffffffff))
- num_nodes++;
+ if ((!node_dev) || (pci_read_config32(node_dev, PCI_VENDOR_ID) == 0xffffffff))
+ continue;
+
+ num_nodes++;
+ for (range = 0; range < 8; range++) {
+ dword = pci_read_config32(get_node_pci(node, 1), 0x40 + (range * 0x8));
+ if (!(dword & 0x3))
+ continue;
+
+ if ((dword >> 8) & 0x7)
+ interleaved = 1;
+
+ dword = pci_read_config32(get_node_pci(node, 1), 0x44 + (range * 0x8));
+ dword2 = pci_read_config32(get_node_pci(node, 1), 0x144 + (range * 0x8));
+ qword = 0xffffff;
+ qword |= ((((uint64_t)dword) >> 16) & 0xffff) << 24;
+ qword |= (((uint64_t)dword2) & 0xff) << 40;
+
+ if (qword > max_range_limit) {
+ max_range = range;
+ max_range_limit = qword;
+ max_node = dword & 0x7;
+ }
+ }
}
- /* Calculate CC6 sotrage area size */
+ /* Calculate CC6 storage area size */
if (interleaved)
qword = (0x1000000 * num_nodes);
else
qword = 0x1000000;
/* Reserve the CC6 save segment */
- reserved_ram_resource(dev, 8, max_range_limit >> 10, qword >> 10);
-
- /* Set up the C-state base address */
- msr_t c_state_addr_msr;
- c_state_addr_msr = rdmsr(0xc0010073);
- c_state_addr_msr.lo = 0xe0e0; /* CstateAddr = 0xe0e0 */
- wrmsr(0xc0010073, c_state_addr_msr);
+ reserved_ram_resource(dev, 8, (max_range_limit + 1) >> 10, qword >> 10);
}
}
}