diff options
Diffstat (limited to 'src/northbridge/amd/amdfam10')
-rw-r--r-- | src/northbridge/amd/amdfam10/link_control.c | 81 | ||||
-rw-r--r-- | src/northbridge/amd/amdfam10/northbridge.c | 58 |
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); } } } |