northbridge/intel/i945: CHECK_SLFRCS_ON_RESUME Kconfig option

Originally brought up by Sven Schnelle in March 2011
http://patchwork.coreboot.org/patch/2801/
http://www.coreboot.org/pipermail/coreboot/2011-March/064277.html

On some mainboards it may be neccessary to reset early during resume
from S3 if the SLFRCS register indicates that a memory channel is not
guaranteed to be in self-refresh.

On other mainboards, such as Lenovo X60 and T60, the check always
creates false positives, effectively making it impossible to resume.

The SLFRCS register is documented on page 197 of

Mobile Intel® 945 Express Chipset Family Datasheet
Document Number: 309219-006

which is publically available, and the register indicates if a memory
channel is guaranteed to be in self-refresh mode (if bit = 1), or that
a memory channel *may or may not be* in self-refresh mode (if bit = 0).

The register can thus only be used to positively learn that memory is
in self-refresh. It is not known for sure that memory is *not* in
self-refresh. The register is reset by the PWROK signal, which *should*
go low during S3, and go high again when resuming, so it is unsurprising
that SLFRCS has already been cleared when we read the register.

Sven's measurements of the CKE signal on a ThinkPad shows that memory
remains in self-refresh indefinitely, until coreboot re-initializes the
memory controller, even when SLFRCS bits were = 0.

Boards which require a warm reset when SLFRCS bits are cleared must now
explicitly enable the check in the mainboard Kconfig file.

This commit selects the new option in all existing i945 mainboards.
A follow-up commit will remove the option for ThinkPads.

Change-Id: I02320675efb8fde05c371ef243ba5093a4da6d11
Signed-off-by: Peter Stuge <peter@stuge.se>
Reviewed-on: http://review.coreboot.org/590
Tested-by: build bot (Jenkins)
Reviewed-by: Sven Schnelle <svens@stackframe.org>
This commit is contained in:
Peter Stuge 2012-01-27 22:17:09 +01:00 committed by Sven Schnelle
parent 247c727693
commit 751508ab01
9 changed files with 18 additions and 2 deletions

View File

@ -23,6 +23,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy
select ARCH_X86 select ARCH_X86
select CPU_INTEL_SOCKET_MFCPGA478 select CPU_INTEL_SOCKET_MFCPGA478
select NORTHBRIDGE_INTEL_I945GM select NORTHBRIDGE_INTEL_I945GM
select CHECK_SLFRCS_ON_RESUME
select SOUTHBRIDGE_INTEL_I82801GX select SOUTHBRIDGE_INTEL_I82801GX
select SOUTHBRIDGE_TI_PCIXX12 select SOUTHBRIDGE_TI_PCIXX12
select SUPERIO_SMSC_FDC37N972 select SUPERIO_SMSC_FDC37N972

View File

@ -5,6 +5,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy
select ARCH_X86 select ARCH_X86
select CPU_INTEL_SOCKET_MFCPGA478 select CPU_INTEL_SOCKET_MFCPGA478
select NORTHBRIDGE_INTEL_I945GM select NORTHBRIDGE_INTEL_I945GM
select CHECK_SLFRCS_ON_RESUME
select SOUTHBRIDGE_INTEL_I82801GX select SOUTHBRIDGE_INTEL_I82801GX
select SUPERIO_WINBOND_W83627EHG select SUPERIO_WINBOND_W83627EHG
select BOARD_HAS_FADT select BOARD_HAS_FADT

View File

@ -23,6 +23,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy
select ARCH_X86 select ARCH_X86
select CPU_INTEL_SOCKET_441 select CPU_INTEL_SOCKET_441
select NORTHBRIDGE_INTEL_I945GC select NORTHBRIDGE_INTEL_I945GC
select CHECK_SLFRCS_ON_RESUME
select SOUTHBRIDGE_INTEL_I82801GX select SOUTHBRIDGE_INTEL_I82801GX
select SUPERIO_SMSC_LPC47M15X select SUPERIO_SMSC_LPC47M15X
select BOARD_HAS_FADT select BOARD_HAS_FADT

View File

@ -5,6 +5,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy
select ARCH_X86 select ARCH_X86
select CPU_INTEL_SOCKET_MFCPGA478 select CPU_INTEL_SOCKET_MFCPGA478
select NORTHBRIDGE_INTEL_I945GM select NORTHBRIDGE_INTEL_I945GM
select CHECK_SLFRCS_ON_RESUME
select SOUTHBRIDGE_INTEL_I82801GX select SOUTHBRIDGE_INTEL_I82801GX
select SUPERIO_WINBOND_W83627THG select SUPERIO_WINBOND_W83627THG
select BOARD_HAS_FADT select BOARD_HAS_FADT

View File

@ -5,6 +5,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy
select ARCH_X86 select ARCH_X86
select CPU_INTEL_SOCKET_MFCPGA478 select CPU_INTEL_SOCKET_MFCPGA478
select NORTHBRIDGE_INTEL_I945GM select NORTHBRIDGE_INTEL_I945GM
select CHECK_SLFRCS_ON_RESUME
select SOUTHBRIDGE_INTEL_I82801GX select SOUTHBRIDGE_INTEL_I82801GX
select SUPERIO_NSC_PC87382 select SUPERIO_NSC_PC87382
select SUPERIO_NSC_PC87384 select SUPERIO_NSC_PC87384

View File

@ -5,6 +5,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy
select ARCH_X86 select ARCH_X86
select CPU_INTEL_SOCKET_MFCPGA478 select CPU_INTEL_SOCKET_MFCPGA478
select NORTHBRIDGE_INTEL_I945GM select NORTHBRIDGE_INTEL_I945GM
select CHECK_SLFRCS_ON_RESUME
select SOUTHBRIDGE_INTEL_I82801GX select SOUTHBRIDGE_INTEL_I82801GX
select SOUTHBRIDGE_RICOH_RL5C476 select SOUTHBRIDGE_RICOH_RL5C476
select SUPERIO_NSC_PC87382 select SUPERIO_NSC_PC87382

View File

@ -5,6 +5,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy
select ARCH_X86 select ARCH_X86
select CPU_INTEL_SOCKET_MFCPGA478 select CPU_INTEL_SOCKET_MFCPGA478
select NORTHBRIDGE_INTEL_I945GM select NORTHBRIDGE_INTEL_I945GM
select CHECK_SLFRCS_ON_RESUME
select SOUTHBRIDGE_INTEL_I82801GX select SOUTHBRIDGE_INTEL_I82801GX
select SOUTHBRIDGE_TI_PCI7420 select SOUTHBRIDGE_TI_PCI7420
select SUPERIO_SMSC_LPC47N227 select SUPERIO_SMSC_LPC47N227

View File

@ -53,4 +53,13 @@ config MAXIMUM_SUPPORTED_FREQUENCY
the board supports, despite what the chipset should be the board supports, despite what the chipset should be
capable of. capable of.
config CHECK_SLFRCS_ON_RESUME
def_bool n
help
On some boards it may be neccessary to hard reset early
during resume from S3 if the SLFRCS register indicates that
a memory channel is not guaranteed to be in self-refresh.
On other boards the check always creates a false positive,
effectively making it impossible to resume.
endif endif

View File

@ -294,8 +294,8 @@ static void sdram_detect_errors(struct sys_info *sysinfo)
reg8 |= (1<<7); reg8 |= (1<<7);
pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xa2, reg8); pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xa2, reg8);
/* clear self refresh if not wake-up from suspend */ /* clear self refresh status if check is disabled or not a resume */
if (sysinfo->boot_path != 2) { if (!CONFIG_CHECK_SLFRCS_ON_RESUME || sysinfo->boot_path != 2) {
MCHBAR8(0xf14) |= 3; MCHBAR8(0xf14) |= 3;
} else { } else {
/* Validate self refresh config */ /* Validate self refresh config */