[coreboot-gerrit] Patch set updated for coreboot: fad0273 X201: Make S3 work.
Vladimir Serbinenko (phcoder@gmail.com)
gerrit at coreboot.org
Thu Jan 9 04:38:05 CET 2014
Vladimir Serbinenko (phcoder at gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/4632
-gerrit
commit fad0273563d9985d4082ba7ed3ecf01dd13ed972
Author: Vladimir Serbinenko <phcoder at gmail.com>
Date: Thu Jan 9 03:34:38 2014 +0100
X201: Make S3 work.
Change-Id: I319e57af52ff01083bfbffbcd883ac5f453320a1
Signed-off-by: Vladimir Serbinenko <phcoder at gmail.com>
---
src/mainboard/lenovo/x201/Kconfig | 2 +-
src/mainboard/lenovo/x201/romstage.c | 12 +-
src/northbridge/intel/nehalem/early_init.c | 6 +
src/northbridge/intel/nehalem/raminit.c | 177 ++++++++++++++---------------
4 files changed, 94 insertions(+), 103 deletions(-)
diff --git a/src/mainboard/lenovo/x201/Kconfig b/src/mainboard/lenovo/x201/Kconfig
index dbc80c5..aeb0954 100644
--- a/src/mainboard/lenovo/x201/Kconfig
+++ b/src/mainboard/lenovo/x201/Kconfig
@@ -43,7 +43,7 @@ config IRQ_SLOT_COUNT
int
default 18
-config CONFIG_DRAM_GATE_GPIO
+config DRAM_GATE_GPIO
int
default 10
diff --git a/src/mainboard/lenovo/x201/romstage.c b/src/mainboard/lenovo/x201/romstage.c
index 8022d7b..fbf240e 100644
--- a/src/mainboard/lenovo/x201/romstage.c
+++ b/src/mainboard/lenovo/x201/romstage.c
@@ -239,25 +239,19 @@ void main(unsigned long bist)
if (bist == 0)
enable_lapic();
- /* Force PCIRST# */
- pci_write_config16(PCI_DEV(0, 0x1e, 0), BCTRL, SBR);
- pci_write_config16(PCI_DEV(0, 0, 0), BCTRL, SBR);
- udelay(200 * 1000);
- pci_write_config16(PCI_DEV(0, 0x1e, 0), BCTRL, 0);
- pci_write_config16(PCI_DEV(0, 0, 0), BCTRL, 0);
+ nehalem_early_initialization(NEHALEM_MOBILE);
+
+ pch_enable_lpc();
/* Enable USB Power. We need to do it early for usbdebug to work. */
ec_set_bit(0x3b, 4);
- pch_enable_lpc();
-
/* Enable GPIOs */
pci_write_config32(PCH_LPC_DEV, GPIO_BASE, DEFAULT_GPIOBASE | 1);
pci_write_config8(PCH_LPC_DEV, GPIO_CNTL, 0x10);
setup_pch_gpios(&x201_gpio_map);
- nehalem_early_initialization(NEHALEM_MOBILE);
/* This should probably go away. Until now it is required
* and mainboard specific
diff --git a/src/northbridge/intel/nehalem/early_init.c b/src/northbridge/intel/nehalem/early_init.c
index 81bac87..ee8c17a 100644
--- a/src/northbridge/intel/nehalem/early_init.c
+++ b/src/northbridge/intel/nehalem/early_init.c
@@ -166,4 +166,10 @@ void nehalem_early_initialization(int chipset_type)
pci_write_config32(PCI_DEV(0, 0x16, 0), 0x10, DEFAULT_HECIBAR);
pci_write_config32(PCI_DEV(0, 0x16, 0), PCI_COMMAND,
PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
+
+ /* Magic for S3 resume. Must be done early. */
+ if (((inl(DEFAULT_PMBASE + PM1_CNT) >> 10) & 7) == SLP_TYP_S3) {
+ MCHBAR32 (0x1e8) = (MCHBAR32(0x1e8) & ~1) | 6;
+ MCHBAR32 (0x1e8) = (MCHBAR32(0x1e8) & ~3) | 4;
+ }
}
diff --git a/src/northbridge/intel/nehalem/raminit.c b/src/northbridge/intel/nehalem/raminit.c
index 19af3bb..e210427 100644
--- a/src/northbridge/intel/nehalem/raminit.c
+++ b/src/northbridge/intel/nehalem/raminit.c
@@ -102,6 +102,10 @@ struct ram_training {
u16 timing_offset[2][2][2][9];
u16 timing2_offset[2][2][2][9];
u16 timing2_bounds[2][2][2][9][2];
+ u8 reg274265[2][3]; /* [CHANNEL][REGISTER] */
+ u8 reg2ca9_bit0;
+ u32 reg_6dc;
+ u32 reg_6e8;
};
#if !REAL
@@ -259,15 +263,14 @@ struct raminfo {
struct ram_training training;
u32 last_500_command[2];
- u8 reg2ca9_bit0;
- u8 reg274265[2][3]; /* [CHANNEL][REGISTER] */
- u32 delay46_ps[2];
- u32 delay54_ps[2];
u8 revision_flag_1;
u8 some_delay_1_cycle_floor;
u8 some_delay_2_halfcycles_ceil;
u8 some_delay_3_ps_rounded;
+ u32 delay46_ps[2];
+ u32 delay54_ps[2];
+
const struct ram_training *cached_training;
};
@@ -1680,6 +1683,9 @@ static void dump_timings(struct raminfo *info)
#endif
}
+/* Read timings and other registers that need to be restored verbatim and
+ put them to CBFS.
+ */
static void save_timings(struct raminfo *info)
{
#if CONFIG_EARLY_CBMEM_INIT
@@ -1698,6 +1704,20 @@ static void save_timings(struct raminfo *info)
train.reg_178 = read_1d0(0x178, 7);
train.reg_10b = read_1d0(0x10b, 6);
+ for (channel = 0; channel < NUM_CHANNELS; channel++) {
+ u32 reg32;
+ reg32 = read_mchbar32 ((channel << 10) + 0x274);
+ train.reg274265[channel][0] = reg32 >> 16;
+ train.reg274265[channel][1] = reg32 & 0xffff;
+ train.reg274265[channel][2] = read_mchbar16 ((channel << 10) + 0x265) >> 8;
+ }
+ train.reg2ca9_bit0 = read_mchbar8(0x2ca9) & 1;
+ train.reg_6dc = read_mchbar32 (0x6dc);
+ train.reg_6e8 = read_mchbar32 (0x6e8);
+
+ printk (BIOS_ERR, "[6dc] = %x\n", train.reg_6dc);
+ printk (BIOS_ERR, "[6e8] = %x\n", train.reg_6e8);
+
/* Save the MRC S3 restore data to cbmem */
cbmem_initialize();
mrcdata = cbmem_add
@@ -1814,7 +1834,7 @@ recv_heci_packet(struct raminfo *info, struct mei_header *head, u32 * packet,
do {
csr.raw = read32(DEFAULT_HECIBAR | 0xc);
#if !REAL
- if (i++ > 346)
+ if (i++ > 330)
return -1;
#endif
}
@@ -1990,8 +2010,6 @@ static int have_match_ranks(struct raminfo *info, int channel, int ranks)
return 1;
}
-#define WTF1 1
-
static void read_4090(struct raminfo *info)
{
int i, channel, slot, rank, lane;
@@ -3493,6 +3511,13 @@ set_6d_reg(struct raminfo *info, u16 reg, u16 freq1, u16 freq2,
0, 1, &ratios2);
compute_frequence_ratios(info, freq1, freq2, num_cycles_3, num_cycles_4,
0, 1, &ratios1);
+ printk (BIOS_ERR, "[%x] <= %x\n", reg,
+ ratios1.freq4_to_max_remainder | (ratios2.
+ freq4_to_max_remainder
+ << 8)
+ | (ratios1.divisor_f4_to_fmax << 16) | (ratios2.
+ divisor_f4_to_fmax
+ << 20));
write_mchbar32(reg,
ratios1.freq4_to_max_remainder | (ratios2.
freq4_to_max_remainder
@@ -3555,7 +3580,7 @@ set_2dx8_reg(struct raminfo *info, u16 reg, u8 mode, u16 freq1, u16 freq2,
}
}
-static void set_2dxx_series(struct raminfo *info)
+static void set_2dxx_series(struct raminfo *info, int s3resume)
{
set_2dx8_reg(info, 0x2d00, 0, 0x78, frequency_11(info) / 2, 1359, 1005,
0, 1);
@@ -3583,14 +3608,24 @@ static void set_2dxx_series(struct raminfo *info)
set_2dx8_reg(info, 0x6d8, 2, info->fsb_frequency,
frequency_11(info) / 2, 4000, 4000, 0, 0);
- set_6d_reg(info, 0x6dc, 2 * info->fsb_frequency, frequency_11(info), 0,
- info->delay46_ps[0], 0, info->delay54_ps[0]);
+ if (s3resume) {
+ printk (BIOS_ERR, "[6dc] <= %x\n", info->cached_training->reg_6dc);
+ write_mchbar32(0x6dc, info->cached_training->reg_6dc);
+ } else
+ set_6d_reg(info, 0x6dc, 2 * info->fsb_frequency, frequency_11(info), 0,
+ info->delay46_ps[0], 0,
+ info->delay54_ps[0]);
set_2dx8_reg(info, 0x6e0, 1, 2 * info->fsb_frequency,
frequency_11(info), 2500, 0, 0, 0);
set_2dx8_reg(info, 0x6e4, 1, 2 * info->fsb_frequency,
frequency_11(info) / 2, 3500, 0, 0, 0);
- set_6d_reg(info, 0x6e8, 2 * info->fsb_frequency, frequency_11(info), 0,
- info->delay46_ps[1], 0, info->delay54_ps[1]);
+ if (s3resume) {
+ printk (BIOS_ERR, "[6e8] <= %x\n", info->cached_training->reg_6e8);
+ write_mchbar32(0x6e8, info->cached_training->reg_6e8);
+ } else
+ set_6d_reg(info, 0x6e8, 2 * info->fsb_frequency, frequency_11(info), 0,
+ info->delay46_ps[1], 0,
+ info->delay54_ps[1]);
set_2d5x_reg(info, 0x2d58, 0x78, 0x78, 864, 1195, 762, 786, 0);
set_2d5x_reg(info, 0x2d60, 0x195, info->fsb_frequency, 1352, 725, 455,
470, 0);
@@ -3641,7 +3676,7 @@ static void set_274265(struct raminfo *info)
int channel;
delay_a_ps = 4 * halfcycle_ps(info) + 6 * fsbcycle_ps(info);
- info->reg2ca9_bit0 = 0;
+ info->training.reg2ca9_bit0 = 0;
for (channel = 0; channel < NUM_CHANNELS; channel++) {
cycletime_ps =
900000 / lcm(2 * info->fsb_frequency, frequency_11(info));
@@ -3692,7 +3727,7 @@ static void set_274265(struct raminfo *info)
if (info->delay46_ps[channel] < 2500) {
info->delay46_ps[channel] = 2500;
- info->reg2ca9_bit0 = 1;
+ info->training.reg2ca9_bit0 = 1;
}
delay_b_ps = halfcycle_ps(info) + delay_c_ps;
if (delay_b_ps <= delay_a_ps)
@@ -3705,25 +3740,24 @@ static void set_274265(struct raminfo *info)
2 * halfcycle_ps(info) * delay_e_cycles;
if (info->delay54_ps[channel] < 2500)
info->delay54_ps[channel] = 2500;
- info->reg274265[channel][0] = delay_e_cycles;
+ info->training.reg274265[channel][0] = delay_e_cycles;
if (delay_d_ps + 7 * halfcycle_ps(info) <=
24 * halfcycle_ps(info))
- info->reg274265[channel][1] = 0;
+ info->training.reg274265[channel][1] = 0;
else
- info->reg274265[channel][1] =
+ info->training.reg274265[channel][1] =
div_roundup(delay_d_ps + 7 * halfcycle_ps(info),
4 * halfcycle_ps(info)) - 6;
write_mchbar32((channel << 10) + 0x274,
- info->reg274265[channel][1] | (info->
- reg274265[channel]
- [0] << 16));
- info->reg274265[channel][2] =
+ info->training.reg274265[channel][1]
+ | (info->training.reg274265[channel][0] << 16));
+ info->training.reg274265[channel][2] =
div_roundup(delay_c_ps + 3 * fsbcycle_ps(info),
4 * halfcycle_ps(info)) + 1;
write_mchbar16((channel << 10) + 0x265,
- info->reg274265[channel][2] << 8);
+ info->training.reg274265[channel][2] << 8);
}
- if (info->reg2ca9_bit0)
+ if (info->training.reg2ca9_bit0)
write_mchbar8(0x2ca9, read_mchbar8(0x2ca9) | 1);
else
write_mchbar8(0x2ca9, read_mchbar8(0x2ca9) & ~1);
@@ -3735,12 +3769,12 @@ static void restore_274265(struct raminfo *info)
for (channel = 0; channel < NUM_CHANNELS; channel++) {
write_mchbar32((channel << 10) + 0x274,
- (info->reg274265[channel][0] << 16) | info->
- reg274265[channel][1]);
+ (info->cached_training->reg274265[channel][0] << 16)
+ | info->cached_training->reg274265[channel][1]);
write_mchbar16((channel << 10) + 0x265,
- info->reg274265[channel][2] << 8);
+ info->cached_training->reg274265[channel][2] << 8);
}
- if (info->reg2ca9_bit0)
+ if (info->cached_training->reg2ca9_bit0)
write_mchbar8(0x2ca9, read_mchbar8(0x2ca9) | 1);
else
write_mchbar8(0x2ca9, read_mchbar8(0x2ca9) & ~1);
@@ -3763,6 +3797,7 @@ static void dmi_setup(void)
}
#endif
+#if REAL
static void
set_fsb_frequency (void)
{
@@ -3774,29 +3809,15 @@ set_fsb_frequency (void)
smbus_block_write(0x69, 0, 5, block);
}
+#endif
-#if REAL
void raminit(const int s3resume)
-#else
-void raminit(int s3resume)
-#endif
{
unsigned channel, slot, lane, rank;
int i;
struct raminfo info;
#if !REAL
- pre_raminit1();
-#endif
-
- if (s3resume) {
- read_mchbar32(0x1e8);
- write_mchbar32(0x1e8, 0x6);
- read_mchbar32(0x1e8);
- write_mchbar32(0x1e8, 0x4);
- }
-
-#if !REAL
pre_raminit_2();
#endif
u8 x2ca8;
@@ -3822,7 +3843,7 @@ void raminit(int s3resume)
#endif
#if !REAL
- pre_raminit_4a();
+ pre_raminit_4a(x2ca8);
#endif
dmi_setup();
@@ -4160,50 +4181,29 @@ void raminit(int s3resume)
udelay(1000);
+ info.cached_training = get_cached_training();
+
if (x2ca8 == 0) {
- if (s3resume) {
-#if REAL && 0
- info.reg2ca9_bit0 = 0;
- info.reg274265[0][0] = 5;
- info.reg274265[0][1] = 5;
- info.reg274265[0][2] = 0xe;
- info.reg274265[1][0] = 5;
- info.reg274265[1][1] = 5;
- info.reg274265[1][2] = 0xe;
- info.delay46_ps[0] = 0xa86;
- info.delay46_ps[1] = 0xa86;
- info.delay54_ps[0] = 0xdc6;
- info.delay54_ps[1] = 0xdc6;
-#else
- info.reg2ca9_bit0 = 0;
- info.reg274265[0][0] = 3;
- info.reg274265[0][1] = 5;
- info.reg274265[0][2] = 0xd;
- info.reg274265[1][0] = 4;
- info.reg274265[1][1] = 5;
- info.reg274265[1][2] = 0xd;
- info.delay46_ps[0] = 0x110a;
- info.delay46_ps[1] = 0xb58;
- info.delay54_ps[0] = 0x144a;
- info.delay54_ps[1] = 0xe98;
-#endif
+ int j;
+ if (s3resume && info.cached_training) {
restore_274265(&info);
- } else
+ printk(BIOS_DEBUG, "reg2ca9_bit0 = %x\n",
+ info.cached_training->reg2ca9_bit0);
+ for (i = 0; i < 2; i++)
+ for (j = 0; j < 3; j++)
+ printk(BIOS_DEBUG, "reg274265[%d][%d] = %x\n",
+ i, j, info.cached_training->reg274265[i][j]);
+ } else {
set_274265(&info);
- int j;
- printk(BIOS_DEBUG, "reg2ca9_bit0 = %x\n", info.reg2ca9_bit0);
- for (i = 0; i < 2; i++)
- for (j = 0; j < 3; j++)
- printk(BIOS_DEBUG, "reg274265[%d][%d] = %x\n",
- i, j, info.reg274265[i][j]);
- for (i = 0; i < 2; i++)
- printk(BIOS_DEBUG, "delay46_ps[%d] = %x\n", i,
- info.delay46_ps[i]);
- for (i = 0; i < 2; i++)
- printk(BIOS_DEBUG, "delay54_ps[%d] = %x\n", i,
- info.delay54_ps[i]);
-
- set_2dxx_series(&info);
+ printk(BIOS_DEBUG, "reg2ca9_bit0 = %x\n",
+ info.training.reg2ca9_bit0);
+ for (i = 0; i < 2; i++)
+ for (j = 0; j < 3; j++)
+ printk(BIOS_DEBUG, "reg274265[%d][%d] = %x\n",
+ i, j, info.training.reg274265[i][j]);
+ }
+
+ set_2dxx_series(&info, s3resume);
if (!(deven & 8)) {
read_mchbar32(0x2cb0);
@@ -4519,8 +4519,6 @@ void raminit(int s3resume)
udelay(1000);
- info.cached_training = get_cached_training();
-
if (s3resume) {
if (info.cached_training == NULL) {
u32 reg32;
@@ -5010,10 +5008,3 @@ unsigned long get_top_of_ram(void)
}
#endif
-#if !REAL
-int main(void)
-{
- raminit(0);
- return 0;
-}
-#endif
More information about the coreboot-gerrit
mailing list