aboutsummaryrefslogtreecommitdiff
path: root/resources/libreboot/patch/kgpe-d16/0044-northbridge-amd-amdfam10-Enable-CC6-DRAM-save-area-s.patch
diff options
context:
space:
mode:
authorFrancis Rowe <info@gluglug.org.uk>2015-10-19 00:12:53 +0100
committerFrancis Rowe <info@gluglug.org.uk>2015-10-19 02:32:36 +0100
commit0622df6194dbb1b2120743c0fd1cc5e72c380128 (patch)
tree4c858b8c5667fe001a9907ae0578b4ec28a8f513 /resources/libreboot/patch/kgpe-d16/0044-northbridge-amd-amdfam10-Enable-CC6-DRAM-save-area-s.patch
parent5999dba5f71f1c05040a551d2420ab8c7f3a9da4 (diff)
downloadlibrebootfr-0622df6194dbb1b2120743c0fd1cc5e72c380128.tar.gz
librebootfr-0622df6194dbb1b2120743c0fd1cc5e72c380128.zip
KGPE-D16: update patch set (also update coreboot and vboot)
Also contains other fixes from coreboot, like: * 551cff0 Derive lvds_dual_channel from EDID timings. ^ makes single/dual channel LVDS selection on GM45 automatic * 26fc544 lenovo/t60: Enable native intel gfx init. ^ was being maintained in libreboot, now upstreamed so not needed Framebuffer mode was disabled for the KGPE-D16, because only text-mode works at the moment.
Diffstat (limited to 'resources/libreboot/patch/kgpe-d16/0044-northbridge-amd-amdfam10-Enable-CC6-DRAM-save-area-s.patch')
-rw-r--r--resources/libreboot/patch/kgpe-d16/0044-northbridge-amd-amdfam10-Enable-CC6-DRAM-save-area-s.patch261
1 files changed, 261 insertions, 0 deletions
diff --git a/resources/libreboot/patch/kgpe-d16/0044-northbridge-amd-amdfam10-Enable-CC6-DRAM-save-area-s.patch b/resources/libreboot/patch/kgpe-d16/0044-northbridge-amd-amdfam10-Enable-CC6-DRAM-save-area-s.patch
new file mode 100644
index 00000000..9ed1c3d4
--- /dev/null
+++ b/resources/libreboot/patch/kgpe-d16/0044-northbridge-amd-amdfam10-Enable-CC6-DRAM-save-area-s.patch
@@ -0,0 +1,261 @@
+From a8478c829628eb43b1222ad981600ff742d271e8 Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Fri, 5 Jun 2015 21:13:30 -0500
+Subject: [PATCH 044/139] northbridge/amd/amdfam10: Enable CC6 DRAM save area
+ setup
+
+Change-Id: Ibeb35da3395dc77a21a2f92f0e1d0845be53d175
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/northbridge/amd/amdfam10/northbridge.c | 70 +++++++++++++++
+ src/northbridge/amd/amdmct/mct_ddr3/mct_d.c | 132 ++++++++++++++++++++++++++++
+ 2 files changed, 202 insertions(+)
+
+diff --git a/src/northbridge/amd/amdfam10/northbridge.c b/src/northbridge/amd/amdfam10/northbridge.c
+index baf77d6..51eac77 100644
+--- a/src/northbridge/amd/amdfam10/northbridge.c
++++ b/src/northbridge/amd/amdfam10/northbridge.c
+@@ -706,6 +706,8 @@ struct chip_operations northbridge_amd_amdfam10_ops = {
+ static void amdfam10_domain_read_resources(device_t dev)
+ {
+ unsigned reg;
++ uint8_t nvram;
++ uint8_t enable_cc6;
+
+ /* Find the already assigned resource pairs */
+ get_fx_devs();
+@@ -749,6 +751,74 @@ static void amdfam10_domain_read_resources(device_t dev)
+ /* Reserve lower DRAM region to force PCI MMIO region to correct location above 0xefffffff */
+ ram_resource(dev, 7, 0, rdmsr(TOP_MEM).lo >> 10);
+ #endif
++
++ if (is_fam15h()) {
++ enable_cc6 = 0;
++ if (get_option(&nvram, "cpu_cc6_state") == CB_SUCCESS)
++ enable_cc6 = !!nvram;
++
++ if (enable_cc6) {
++ uint8_t node;
++ uint8_t interleaved;
++ int8_t range;
++ int8_t max_range;
++ uint8_t max_node;
++ uint64_t max_range_limit;
++ uint32_t dword;
++ uint32_t dword2;
++ uint64_t qword;
++ uint8_t num_nodes;
++
++ /* Find highest DRAM range (DramLimitAddr) */
++ 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++;
++ }
++
++ /* Calculate CC6 sotrage 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);
++ }
++ }
+ }
+
+ static u32 my_find_pci_tolm(struct bus *bus, u32 tolm)
+diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c
+index 20e66f2..2798506 100644
+--- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c
++++ b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c
+@@ -1188,6 +1188,100 @@ static void compare_nvram_spd_hashes(struct MCTStatStruc *pMCTstat,
+ }
+ #endif
+
++static void set_up_cc6_storage_fam15(struct MCTStatStruc *pMCTstat,
++ struct DCTStatStruc *pDCTstat, uint8_t num_nodes)
++{
++ uint8_t interleaved;
++ uint8_t destination_node;
++ int8_t range;
++ int8_t max_range;
++ uint8_t max_node;
++ uint64_t max_range_limit;
++ uint32_t dword;
++ uint32_t dword2;
++ uint64_t qword;
++
++ interleaved = 0;
++ if (pMCTstat->GStatus & (1 << GSB_NodeIntlv))
++ interleaved = 1;
++
++ /* Find highest DRAM range (DramLimitAddr) */
++ max_node = 0;
++ max_range = -1;
++ max_range_limit = 0;
++ for (range = 0; range < 8; range++) {
++ dword = Get_NB32(pDCTstat->dev_map, 0x40 + (range * 0x8));
++ if (!(dword & 0x3))
++ continue;
++
++ 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 |= (((uint64_t)dword2) & 0xff) << 40;
++
++ if (qword > max_range_limit) {
++ max_range = range;
++ max_range_limit = qword;
++ max_node = dword & 0x7;
++ }
++ }
++
++ 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);
++ }
++ }
++
++ /* Determine save state destination node */
++ if (interleaved)
++ destination_node = Get_NB32(pDCTstat->dev_host, 0x60) & 0x7;
++ else
++ destination_node = max_node;
++
++ /* Set save state destination node */
++ dword = Get_NB32(pDCTstat->dev_link, 0x128);
++ dword &= ~(0x3f << 12); /* CoreSaveStateDestNode = destination_node */
++ dword |= (destination_node & 0x3f) << 12;
++ Set_NB32(pDCTstat->dev_link, 0x128, dword);
++}
++
++static void lock_dram_config(struct MCTStatStruc *pMCTstat,
++ struct DCTStatStruc *pDCTstat)
++{
++ uint32_t dword;
++
++ dword = Get_NB32(pDCTstat->dev_dct, 0x118);
++ dword |= 0x1 << 19; /* LockDramCfg = 1 */
++ Set_NB32(pDCTstat->dev_dct, 0x118, dword);
++}
++
++static void set_cc6_save_enable(struct MCTStatStruc *pMCTstat,
++ struct DCTStatStruc *pDCTstat, uint8_t enable)
++{
++ uint32_t dword;
++
++ dword = Get_NB32(pDCTstat->dev_dct, 0x118);
++ dword &= ~(0x1 << 18); /* CC6SaveEn = enable */
++ dword |= (enable & 0x1) << 18;
++ Set_NB32(pDCTstat->dev_dct, 0x118, dword);
++}
++
+ static void mctAutoInitMCT_D(struct MCTStatStruc *pMCTstat,
+ struct DCTStatStruc *pDCTstatA)
+ {
+@@ -1237,6 +1331,7 @@ static void mctAutoInitMCT_D(struct MCTStatStruc *pMCTstat,
+ u8 Node, NodesWmem;
+ u32 node_sys_base;
+ uint8_t nvram;
++ uint8_t enable_cc6;
+ uint8_t allow_config_restore;
+
+ uint8_t s3resume = acpi_is_wakeup_s3();
+@@ -1406,6 +1501,43 @@ restartinit:
+ mct_ForceNBPState0_Dis_Fam15(pMCTstat, pDCTstat);
+ }
+
++ if (is_fam15h()) {
++ enable_cc6 = 0;
++ if (get_option(&nvram, "cpu_cc6_state") == CB_SUCCESS)
++ enable_cc6 = !!nvram;
++
++ if (enable_cc6) {
++ uint8_t num_nodes;
++
++ num_nodes = 0;
++ for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
++ struct DCTStatStruc *pDCTstat;
++ pDCTstat = pDCTstatA + Node;
++
++ if (pDCTstat->NodePresent)
++ num_nodes++;
++ }
++
++ for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
++ struct DCTStatStruc *pDCTstat;
++ pDCTstat = pDCTstatA + Node;
++
++ if (pDCTstat->NodePresent)
++ set_up_cc6_storage_fam15(pMCTstat, pDCTstat, num_nodes);
++ }
++
++ for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
++ struct DCTStatStruc *pDCTstat;
++ pDCTstat = pDCTstatA + Node;
++
++ if (pDCTstat->NodePresent) {
++ lock_dram_config(pMCTstat, pDCTstat);
++ set_cc6_save_enable(pMCTstat, pDCTstat, 1);
++ }
++ }
++ }
++ }
++
+ mct_FinalMCT_D(pMCTstat, pDCTstatA);
+ printk(BIOS_DEBUG, "mctAutoInitMCT_D Done: Global Status: %x\n", pMCTstat->GStatus);
+ }
+--
+1.9.1
+