[coreboot-gerrit] Patch set updated for coreboot: nb/intel/x4x: Implement resume from S3 suspend
Arthur Heymans (arthur@aheymans.xyz)
gerrit at coreboot.org
Sat Dec 31 11:18:37 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 b80fdf42b8a926137e8e278c1ca506067fdd0d81
Author: Arthur Heymans <arthur at aheymans.xyz>
Date: Fri Dec 30 21:07:18 2016 +0100
nb/intel/x4x: Implement resume from S3 suspend
It stores the results of receive enable in 256 bits in the unused
upper 1024 bits sized region of nvram.
Change-Id: Ib54bc5c7b0fed6d975ffc31f037b5179d9e5600b
Signed-off-by: Arthur Heymans <arthur at aheymans.xyz>
---
src/mainboard/gigabyte/ga-g41m-es2l/Kconfig | 1 +
src/mainboard/gigabyte/ga-g41m-es2l/cmos.layout | 1 +
src/mainboard/gigabyte/ga-g41m-es2l/romstage.c | 8 +-
src/northbridge/intel/x4x/pcie.c | 15 +++-
src/northbridge/intel/x4x/raminit_ddr2.c | 99 ++++++++++++++++++++++---
src/northbridge/intel/x4x/x4x.h | 5 +-
6 files changed, 112 insertions(+), 17 deletions(-)
diff --git a/src/mainboard/gigabyte/ga-g41m-es2l/Kconfig b/src/mainboard/gigabyte/ga-g41m-es2l/Kconfig
index 3d2a892..ae57e5b 100644
--- a/src/mainboard/gigabyte/ga-g41m-es2l/Kconfig
+++ b/src/mainboard/gigabyte/ga-g41m-es2l/Kconfig
@@ -33,6 +33,7 @@ config BOARD_SPECIFIC_OPTIONS
select REALTEK_8168_RESET
select HAVE_OPTION_TABLE
select HAVE_CMOS_DEFAULT
+ select HAVE_ACPI_RESUME
config MMCONF_BASE_ADDRESS
hex
diff --git a/src/mainboard/gigabyte/ga-g41m-es2l/cmos.layout b/src/mainboard/gigabyte/ga-g41m-es2l/cmos.layout
index 3138479..cee6fe9 100644
--- a/src/mainboard/gigabyte/ga-g41m-es2l/cmos.layout
+++ b/src/mainboard/gigabyte/ga-g41m-es2l/cmos.layout
@@ -68,6 +68,7 @@ entries
# coreboot config options: check sums
984 16 h 0 check_sum
+1024 256 h 0 recv_enable_results
# -----------------------------------------------------------------
enumerations
diff --git a/src/mainboard/gigabyte/ga-g41m-es2l/romstage.c b/src/mainboard/gigabyte/ga-g41m-es2l/romstage.c
index 2503db9..dd2fab6 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,14 @@ 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 de62517..e30efea 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"
@@ -1502,6 +1504,79 @@ 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 < ARRAY_SIZE(values); 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;
@@ -2005,7 +2080,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
@@ -2020,16 +2095,18 @@ void raminit_ddr2(struct sysinfo *s)
MCHBAR8(0x5dc) = MCHBAR8(0x5dc) | 0x80;
// Dummy writes / reads
- volatile u32 data;
- FOR_EACH_POPULATED_RANK(s->dimms, ch, r) {
- for (bank = 0; bank < 4; bank++) {
- reg32 = (ch << 29) | (r*0x8000000) | (bank << 12);
- write32((u32 *)reg32, 0xffffffff);
- data = read32((u32 *)reg32);
- printk(BIOS_DEBUG, "Wrote ones, Read: [0x%08x]=0x%08x\n", reg32, data);
- write32((u32 *)reg32, 0x00000000);
- data = read32((u32 *)reg32);
- printk(BIOS_DEBUG, "Wrote zeros, Read: [0x%08x]=0x%08x\n", reg32, data);
+ if (s->boot_path != BOOT_PATH_RESUME) {
+ volatile u32 data;
+ FOR_EACH_POPULATED_RANK(s->dimms, ch, r) {
+ for (bank = 0; bank < 4; bank++) {
+ reg32 = (ch << 29) | (r*0x8000000) | (bank << 12);
+ write32((u32 *)reg32, 0xffffffff);
+ data = read32((u32 *)reg32);
+ printk(BIOS_DEBUG, "Wrote ones, Read: [0x%08x]=0x%08x\n", reg32, data);
+ write32((u32 *)reg32, 0x00000000);
+ data = read32((u32 *)reg32);
+ printk(BIOS_DEBUG, "Wrote zeros, Read: [0x%08x]=0x%08x\n", reg32, data);
+ }
}
}
printk(BIOS_DEBUG, "Done dummy reads\n");
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