[coreboot-gerrit] New patch to review for coreboot: [WIP] nb/intel/x4x: Implement resume from suspend

Arthur Heymans (arthur@aheymans.xyz) gerrit at coreboot.org
Fri Dec 30 22:02:46 CET 2016


Arthur Heymans (arthur at aheymans.xyz) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/17998

-gerrit

commit 6774d05bda91d9b2bff55ad643a6fcf8b2e14095
Author: Arthur Heymans <arthur at aheymans.xyz>
Date:   Fri Dec 30 21:07:18 2016 +0100

    [WIP] nb/intel/x4x: Implement resume from suspend
    
    does not work
    
    Change-Id: Ib54bc5c7b0fed6d975ffc31f037b5179d9e5600b
    Signed-off-by: Arthur Heymans <arthur at aheymans.xyz>
---
 src/mainboard/gigabyte/ga-g41m-es2l/romstage.c |  7 ++-
 src/northbridge/intel/x4x/pcie.c               | 15 ++++-
 src/northbridge/intel/x4x/raminit_ddr2.c       | 76 +++++++++++++++++++++++++-
 src/northbridge/intel/x4x/x4x.h                |  5 +-
 4 files changed, 97 insertions(+), 6 deletions(-)

diff --git a/src/mainboard/gigabyte/ga-g41m-es2l/romstage.c b/src/mainboard/gigabyte/ga-g41m-es2l/romstage.c
index 2503db9..4005295 100644
--- a/src/mainboard/gigabyte/ga-g41m-es2l/romstage.c
+++ b/src/mainboard/gigabyte/ga-g41m-es2l/romstage.c
@@ -136,6 +136,7 @@ void mainboard_romstage_entry(unsigned long bist)
 {
 	//                          ch0      ch1
 	const u8 spd_addrmap[4] = { 0x50, 0, 0x52, 0 };
+	u8 s3resume = 0;
 
 	/* Disable watchdog timer */
 	RCBA32(0x3410) = RCBA32(0x3410) | 0x20;
@@ -155,13 +156,15 @@ void mainboard_romstage_entry(unsigned long bist)
 
 	x4x_early_init();
 
+	s3resume = southbridge_detect_s3_resume();
+
 	printk(BIOS_DEBUG, "Initializing memory\n");
-	sdram_initialize(0, spd_addrmap);
+	sdram_initialize(s3resume ? 2 : 0, spd_addrmap);
 	quick_ram_check();
 	cbmem_initialize_empty();
 	printk(BIOS_DEBUG, "Memory initialized\n");
 
-	x4x_late_init();
+	x4x_late_init(s3resume);
 
 	printk(BIOS_DEBUG, "x4x late init complete\n");
 
diff --git a/src/northbridge/intel/x4x/pcie.c b/src/northbridge/intel/x4x/pcie.c
index f03869e..648f10d 100644
--- a/src/northbridge/intel/x4x/pcie.c
+++ b/src/northbridge/intel/x4x/pcie.c
@@ -18,10 +18,11 @@
 #include <stddef.h>
 #include <string.h>
 #include <arch/io.h>
+#include <cbmem.h>
 #include <device/pci_def.h>
 #include <device/pnp_def.h>
 #include <console/console.h>
-
+#include <romstage_handoff.h>
 #include "iomap.h"
 #include "x4x.h"
 
@@ -184,8 +185,18 @@ static void init_dmi(void)
 	reg16 = DMIBAR16(0x88);
 }
 
-void x4x_late_init(void)
+static void x4x_prepare_resume(int s3resume)
+{
+	int cbmem_was_initted;
+
+	cbmem_was_initted = !cbmem_recovery(s3resume);
+
+	romstage_handoff_init(cbmem_was_initted && s3resume);
+}
+
+void x4x_late_init(int s3resume)
 {
 	init_egress();
 	init_dmi();
+	x4x_prepare_resume(s3resume);
 }
diff --git a/src/northbridge/intel/x4x/raminit_ddr2.c b/src/northbridge/intel/x4x/raminit_ddr2.c
index b3ee34a..546d482 100644
--- a/src/northbridge/intel/x4x/raminit_ddr2.c
+++ b/src/northbridge/intel/x4x/raminit_ddr2.c
@@ -20,6 +20,8 @@
 #include <console/console.h>
 #include <commonlib/helpers.h>
 #include <delay.h>
+#include <pc80/mc146818rtc.h>
+#include <southbridge/intel/i82801ix/i82801ix.h>
 #include "iomap.h"
 #include "x4x.h"
 
@@ -1486,6 +1488,78 @@ static void rcven_ddr2(struct sysinfo *s)
 	printk(BIOS_DEBUG, "End rcven\n");
 }
 
+static void sdram_save_receive_enable(void)
+{
+	int i = 0, j;
+	u32 reg32;
+	u16 reg16;
+	u8 values[32];
+	u8 lane, ch;
+
+	FOR_EACH_CHANNEL(ch) {
+		for (lane = 0; lane < 8; lane++) {
+			values[i++] = MCHBAR8(0x400*ch + 0x560 + (lane*4));
+		}
+		reg32 = MCHBAR32(0x400*ch + 0x248);
+		for (j = 0; j < 4; j++)
+			values[i++] = (reg32 >> (j * 8)) & 0xff;
+		reg16 = MCHBAR16(0x400*ch + 0x5fa);
+		for (j = 0; j < 2; j++)
+			values[i++] = (reg16 >> (j * 8)) & 0xff;
+		reg16 = MCHBAR16(0x400*ch + 0x58c);
+		for (j = 0; j < 2; j++)
+			values[i++] = (reg16 >> (j * 8)) & 0xff;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(values); i++)
+		cmos_write(values[i], 128 + i);
+}
+
+static void sdram_recover_receive_enable(void)
+{
+	u8 i , j;
+	u32 reg32 = 0;
+	u16 reg16 = 0;
+	u8 values[32];
+	u8 ch, lane;
+
+	for (i = 0; i < 4; i++)
+		values[i] = cmos_read(128 + i);
+
+	i = 0;
+	FOR_EACH_CHANNEL(ch) {
+		for (lane = 0; lane < 8; lane++) {
+			MCHBAR8(0x400*ch + 0x560 + (lane*4)) = values[i++];
+		}
+		for (j = 0; j < 4; j++)
+			reg32 |= (values[i++] << (j * 8));
+		MCHBAR32(0x400*ch + 0x248) = reg32;
+		reg32 = 0;
+		for (j = 0; j < 2; j++)
+			reg16 |= (values[i++] << (j * 8));
+		MCHBAR16(0x400*ch + 0x5fa) = reg16;
+		reg16 = 0;
+		for (j = 0; j < 2; j++)
+			reg16 |= (values[i++] << (j * 8));
+		MCHBAR16(0x400*ch + 0x58c) = reg16;
+		reg16 = 0;
+	}
+}
+
+static void sdram_program_receive_enable(struct sysinfo *s)
+{
+	/* enable upper CMOS */
+	RCBA32(0x3400) = (1 << 2);
+
+	/* Program Receive Enable Timings */
+	if (s->boot_path == BOOT_PATH_RESUME) {
+		sdram_recover_receive_enable();
+	} else {
+		rcven_ddr2(s);
+		sdram_save_receive_enable();
+	}
+}
+
 static void dradrb_ddr2(struct sysinfo *s)
 {
 	u8 map, i, ch, r, rankpop0, rankpop1;
@@ -1989,7 +2063,7 @@ void raminit_ddr2(struct sysinfo *s)
 	}
 
 	// Receive enable
-	rcven_ddr2(s);
+	sdram_program_receive_enable(s);
 	printk(BIOS_DEBUG, "Done rcven\n");
 
 	// Finish rcven
diff --git a/src/northbridge/intel/x4x/x4x.h b/src/northbridge/intel/x4x/x4x.h
index 7ca634f..ce4463e 100644
--- a/src/northbridge/intel/x4x/x4x.h
+++ b/src/northbridge/intel/x4x/x4x.h
@@ -290,6 +290,9 @@ struct sysinfo {
 	struct dimminfo	dimms[4];
 	u8		spd_map[4];
 };
+#define BOOT_PATH_NORMAL	0
+#define BOOT_PATH_RESET		1
+#define BOOT_PATH_RESUME	2
 
 enum ddr2_signals {
 	CLKSET0 = 0,
@@ -319,7 +322,7 @@ enum ddr2_signals {
 
 #ifndef __BOOTBLOCK__
 void x4x_early_init(void);
-void x4x_late_init(void);
+void x4x_late_init(int s3resume);
 u32 decode_igd_memory_size(u32 gms);
 u32 decode_igd_gtt_size(u32 gsm);
 u8 decode_pciebar(u32 *const base, u32 *const len);



More information about the coreboot-gerrit mailing list