[coreboot-gerrit] Patch set updated for coreboot: 45df124 X201: Make S3 work.

Vladimir Serbinenko (phcoder@gmail.com) gerrit at coreboot.org
Thu Jan 9 04:04:38 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 45df1246fc5384cb95036cb6d1bb7d0c25325895
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/romstage.c       |  12 +-
 src/northbridge/intel/nehalem/early_init.c |   6 +
 src/northbridge/intel/nehalem/raminit.c    | 177 ++++++++++++++---------------
 3 files changed, 93 insertions(+), 102 deletions(-)

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