Arthur Heymans (arthur@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@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@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);