aboutsummaryrefslogtreecommitdiff
path: root/src/northbridge/amd/amdmct/mct_ddr3
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/amdmct/mct_ddr3
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/amdmct/mct_ddr3')
-rw-r--r--src/northbridge/amd/amdmct/mct_ddr3/mct_d.c57
-rw-r--r--src/northbridge/amd/amdmct/mct_ddr3/mctecc_d.c8
2 files changed, 42 insertions, 23 deletions
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c
index 27fa7ae018..1d48070084 100644
--- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c
+++ b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c
@@ -1203,6 +1203,7 @@ static void set_up_cc6_storage_fam15(struct MCTStatStruc *pMCTstat,
int8_t max_range;
uint8_t max_node;
uint64_t max_range_limit;
+ uint8_t byte;
uint32_t dword;
uint32_t dword2;
uint64_t qword;
@@ -1222,7 +1223,8 @@ static void set_up_cc6_storage_fam15(struct MCTStatStruc *pMCTstat,
dword = Get_NB32(pDCTstat->dev_map, 0x44 + (range * 0x8));
dword2 = Get_NB32(pDCTstat->dev_map, 0x144 + (range * 0x8));
- qword = ((((uint64_t)dword) >> 16) & 0xffff) << 24;
+ qword = 0xffffff;
+ qword |= ((((uint64_t)dword) >> 16) & 0xffff) << 24;
qword |= (((uint64_t)dword2) & 0xff) << 40;
if (qword > max_range_limit) {
@@ -1232,26 +1234,35 @@ static void set_up_cc6_storage_fam15(struct MCTStatStruc *pMCTstat,
}
}
- if (pDCTstat->Node_ID == max_node) {
- if (max_range >= 0) {
- if (interleaved)
- /* Move upper limit down by 16M * the number of nodes */
- max_range_limit -= (0x1000000 * num_nodes);
- else
- /* Move upper limit down by 16M */
- max_range_limit -= 0x1000000;
-
- /* Store modified range */
- dword = Get_NB32(pDCTstat->dev_map, 0x44 + (range * 0x8));
- dword &= ~(0xffff << 16); /* DramLimit[39:24] = max_range_limit[39:24] */
- dword |= (max_range_limit >> 24) & 0xffff;
- Set_NB32(pDCTstat->dev_map, 0x44 + (range * 0x8), dword);
-
- dword = Get_NB32(pDCTstat->dev_map, 0x144 + (range * 0x8));
- dword &= ~(0xffff << 16); /* DramLimit[47:40] = max_range_limit[47:40] */
- dword |= (max_range_limit >> 40) & 0xff;
- Set_NB32(pDCTstat->dev_map, 0x144 + (range * 0x8), dword);
- }
+ if (max_range >= 0) {
+ if (interleaved)
+ /* Move upper limit down by 16M * the number of nodes */
+ max_range_limit -= (0x1000000 * num_nodes);
+ else
+ /* Move upper limit down by 16M */
+ max_range_limit -= 0x1000000;
+
+ /* Disable the range */
+ dword = Get_NB32(pDCTstat->dev_map, 0x40 + (max_range * 0x8));
+ byte = dword & 0x3;
+ dword &= ~(0x3);
+ Set_NB32(pDCTstat->dev_map, 0x40 + (max_range * 0x8), dword);
+
+ /* Store modified range */
+ dword = Get_NB32(pDCTstat->dev_map, 0x44 + (max_range * 0x8));
+ dword &= ~(0xffff << 16); /* DramLimit[39:24] = max_range_limit[39:24] */
+ dword |= ((max_range_limit >> 24) & 0xffff) << 16;
+ Set_NB32(pDCTstat->dev_map, 0x44 + (max_range * 0x8), dword);
+
+ dword = Get_NB32(pDCTstat->dev_map, 0x144 + (max_range * 0x8));
+ dword &= ~0xff; /* DramLimit[47:40] = max_range_limit[47:40] */
+ dword |= (max_range_limit >> 40) & 0xff;
+ Set_NB32(pDCTstat->dev_map, 0x144 + (max_range * 0x8), dword);
+
+ /* Reenable the range */
+ dword = Get_NB32(pDCTstat->dev_map, 0x40 + (max_range * 0x8));
+ dword |= byte;
+ Set_NB32(pDCTstat->dev_map, 0x40 + (max_range * 0x8), dword);
}
/* Determine save state destination node */
@@ -1538,8 +1549,8 @@ restartinit:
pDCTstat = pDCTstatA + Node;
if (pDCTstat->NodePresent) {
- lock_dram_config(pMCTstat, pDCTstat);
set_cc6_save_enable(pMCTstat, pDCTstat, 1);
+ lock_dram_config(pMCTstat, pDCTstat);
}
}
}
@@ -5118,7 +5129,7 @@ static void mct_HTMemMapExt(struct MCTStatStruc *pMCTstat,
/* get base/limit from Node0 */
reg = 0x40 + (Node << 3); /* Node0/Dram Base 0 */
val = Get_NB32(dev, reg);
- Drambase = val >> ( 16 + 3);
+ Drambase = val >> (16 + 3);
reg = 0x44 + (Node << 3); /* Node0/Dram Base 0 */
val = Get_NB32(dev, reg);
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctecc_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mctecc_d.c
index 0a51b1a228..6ab33a3b1e 100644
--- a/src/northbridge/amd/amdmct/mct_ddr3/mctecc_d.c
+++ b/src/northbridge/amd/amdmct/mct_ddr3/mctecc_d.c
@@ -155,6 +155,14 @@ u8 ECCInit_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA)
if (MemClrECC) {
MCTMemClrSync_D(pMCTstat, pDCTstatA);
}
+
+ if (pDCTstat->LogicalCPUID & (AMD_DR_GT_D0 | AMD_FAM15_ALL)) {
+ /* Set up message triggered C1E */
+ val = pci_read_config32(pDCTstat->dev_nbmisc, 0xd4);
+ val &= ~(0x1 << 15); /* StutterScrubEn = DRAM scrub enabled */
+ val |= (mctGet_NVbits(NV_DramBKScrub)?1:0) << 15;
+ pci_write_config32(pDCTstat->dev_nbmisc, 0xd4, val);
+ }
} /* if Node present */
}