diff options
author | Timothy Pearson <tpearson@raptorengineeringinc.com> | 2015-06-08 19:35:06 -0500 |
---|---|---|
committer | Ronald G. Minnich <rminnich@gmail.com> | 2015-11-11 18:45:14 +0100 |
commit | 83abd81c8acb3a53dfc125e248d9e5fd58f3e0f7 (patch) | |
tree | ca0652a1421652f4eb8b4af358f66e2fc256e1db /src/northbridge/amd/amdfam10/northbridge.c | |
parent | dd4390b6e055ef862084a5fc45b756d6fe09151d (diff) |
cpu/amd: Add CC6 support
This patch adds CC6 power save support to the AMD Family 15h
support code. As CC6 is a complex power saving state that
relies heavily on CPU, northbridge, and southbridge cooperation,
this patch alters significant amounts of code throughout the
tree simultaneously.
Allowing the CPU to enter CC6 allows the second level of turbo
boost to be reached, and also provides significant power savings
when the system is idle due to the complete core shutdown.
Change-Id: I44ce157cda97fb85f3e8f3d7262d4712b5410670
Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
Reviewed-on: http://review.coreboot.org/11979
Tested-by: build bot (Jenkins)
Tested-by: Raptor Engineering Automated Test Stand <noreply@raptorengineeringinc.com>
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
Diffstat (limited to 'src/northbridge/amd/amdfam10/northbridge.c')
-rw-r--r-- | src/northbridge/amd/amdfam10/northbridge.c | 58 |
1 files changed, 27 insertions, 31 deletions
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); } } } |