aboutsummaryrefslogtreecommitdiff
path: root/src/northbridge/amd/amdfam10/link_control.c
diff options
context:
space:
mode:
authorTimothy Pearson <tpearson@raptorengineeringinc.com>2015-06-08 19:35:06 -0500
committerRonald G. Minnich <rminnich@gmail.com>2015-11-11 18:45:14 +0100
commit83abd81c8acb3a53dfc125e248d9e5fd58f3e0f7 (patch)
treeca0652a1421652f4eb8b4af358f66e2fc256e1db /src/northbridge/amd/amdfam10/link_control.c
parentdd4390b6e055ef862084a5fc45b756d6fe09151d (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/link_control.c')
-rw-r--r--src/northbridge/amd/amdfam10/link_control.c81
1 files changed, 80 insertions, 1 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
+};