[coreboot-gerrit] Patch set updated for coreboot: nb/intel/sandybridge/raminit: prepare raminit for fallback

Patrick Rudolph (siro@das-labor.org) gerrit at coreboot.org
Sat Mar 26 15:51:59 CET 2016


Patrick Rudolph (siro at das-labor.org) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/14170

-gerrit

commit 02d2ecf2e1a1bb8aeab6af039d673ca1f05d7e7c
Author: Patrick Rudolph <siro at das-labor.org>
Date:   Fri Mar 25 18:19:47 2016 +0100

    nb/intel/sandybridge/raminit: prepare raminit for fallback
    
    Return errors to top level ram init function.
    Required by the folowing series to implement a fallback.
    
    No functionality is changed.
    On error case the system still halts in every test.
    
    Change-Id: I6278c4a1d7b4a96be8988a60671fc3d72cd6cb3d
    Signed-off-by: Patrick Rudolph <siro at das-labor.org>
---
 src/northbridge/intel/sandybridge/raminit.c | 201 ++++++++++++++++++++--------
 1 file changed, 148 insertions(+), 53 deletions(-)

diff --git a/src/northbridge/intel/sandybridge/raminit.c b/src/northbridge/intel/sandybridge/raminit.c
index dbec9fb..cf096a2 100644
--- a/src/northbridge/intel/sandybridge/raminit.c
+++ b/src/northbridge/intel/sandybridge/raminit.c
@@ -199,6 +199,8 @@ typedef struct ramctr_timing_st {
 #define MAX_TIMB 511
 #define MAX_TIMA 127
 
+#define MAKE_ERR ((channel<<16)|(slotrank<<8)|1)
+
 static void program_timings(ramctr_timing * ctrl, int channel);
 
 static const char *ecc_decoder[] = {
@@ -1877,7 +1879,7 @@ static void discover_timA_fine(ramctr_timing * ctrl, int channel, int slotrank,
 	}
 }
 
-static void discover_402x(ramctr_timing * ctrl, int channel, int slotrank,
+static int discover_402x(ramctr_timing *ctrl, int channel, int slotrank,
 			  int *upperA)
 {
 	int works[NUM_LANES];
@@ -1895,18 +1897,26 @@ static void discover_402x(ramctr_timing * ctrl, int channel, int slotrank,
 				all_works = 0;
 		}
 		if (all_works)
-			return;
+			return 0;
 		if (!some_works) {
-			if (ctrl->timings[channel][slotrank].val_4024 < 2)
-				die("402x discovery failed");
+			if (ctrl->timings[channel][slotrank].val_4024 < 2) {
+				printk(BIOS_EMERG, "402x discovery failed (1): %d, %d\n",
+				       channel, slotrank);
+				halt();
+				return MAKE_ERR;
+			}
 			ctrl->timings[channel][slotrank].val_4024 -= 2;
 			printram("4024 -= 2;\n");
 			continue;
 		}
 		ctrl->timings[channel][slotrank].val_4028 += 2;
 		printram("4028 += 2;\n");
-		if (ctrl->timings[channel][slotrank].val_4028 >= 0x10)
-			die("402x discovery failed");
+		if (ctrl->timings[channel][slotrank].val_4028 >= 0x10) {
+			printk(BIOS_EMERG, "402x discovery failed (2): %d, %d\n",
+			       channel, slotrank);
+			halt();
+			return MAKE_ERR;
+		}
 		FOR_ALL_LANES if (works[lane]) {
 			ctrl->timings[channel][slotrank].lanes[lane].timA +=
 			    128;
@@ -1915,6 +1925,7 @@ static void discover_402x(ramctr_timing * ctrl, int channel, int slotrank,
 			       slotrank, lane);
 		}
 	}
+	return 0;
 }
 
 struct timA_minmax {
@@ -1983,9 +1994,10 @@ static void post_timA_change(ramctr_timing * ctrl, int channel, int slotrank,
  * Once the controller has detected this pattern a bit in the result register is
  * set for the current phase shift.
  */
-static void read_training(ramctr_timing * ctrl)
+static int read_training(ramctr_timing * ctrl)
 {
 	int channel, slotrank, lane;
+	int err;
 
 	FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
 		int all_high, some_high;
@@ -2041,7 +2053,9 @@ static void read_training(ramctr_timing * ctrl)
 
 		pre_timA_change(ctrl, channel, slotrank, &mnmx);
 
-		discover_402x(ctrl, channel, slotrank, upperA);
+		err = discover_402x(ctrl, channel, slotrank, upperA);
+		if (err)
+			return err;
 
 		post_timA_change(ctrl, channel, slotrank, &mnmx);
 		pre_timA_change(ctrl, channel, slotrank, &mnmx);
@@ -2081,6 +2095,7 @@ static void read_training(ramctr_timing * ctrl)
 		write32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel
 			+ 4 * lane, 0);
 	}
+	return 0;
 }
 
 static void test_timC(ramctr_timing * ctrl, int channel, int slotrank)
@@ -2167,7 +2182,7 @@ static void test_timC(ramctr_timing * ctrl, int channel, int slotrank)
 	wait_428c(channel);
 }
 
-static void discover_timC(ramctr_timing * ctrl, int channel, int slotrank)
+static int discover_timC(ramctr_timing *ctrl, int channel, int slotrank)
 {
 	int timC;
 	int statistics[NUM_LANES][MAX_TIMC + 1];
@@ -2204,11 +2219,16 @@ static void discover_timC(ramctr_timing * ctrl, int channel, int slotrank)
 		struct run rn =
 		    get_longest_zero_run(statistics[lane], MAX_TIMC + 1);
 		ctrl->timings[channel][slotrank].lanes[lane].timC = rn.middle;
-		if (rn.all)
-			die("timC discovery failed");
+		if (rn.all) {
+			printk(BIOS_EMERG, "timC discovery failed: %d, %d, %d\n",
+			       channel, slotrank, lane);
+			halt();
+			return MAKE_ERR;
+		}
 		printram("Cval: %d, %d, %d: %x\n", channel, slotrank,
 		       lane, ctrl->timings[channel][slotrank].lanes[lane].timC);
 	}
+	return 0;
 }
 
 static int get_precedening_channels(ramctr_timing * ctrl, int target_channel)
@@ -2402,7 +2422,7 @@ static void test_timB(ramctr_timing * ctrl, int channel, int slotrank)
 		    0x1080 | make_mr1(ctrl, slotrank, channel));
 }
 
-static void discover_timB(ramctr_timing * ctrl, int channel, int slotrank)
+static int discover_timB(ramctr_timing *ctrl, int channel, int slotrank)
 {
 	int timB;
 	int statistics[NUM_LANES][128];
@@ -2445,11 +2465,16 @@ static void discover_timB(ramctr_timing * ctrl, int channel, int slotrank)
 		else if ((rn.start & 0x3F) == 0x3F)
 			rn.start += 1;
 		ctrl->timings[channel][slotrank].lanes[lane].timB = rn.start;
-		if (rn.all)
-			die("timB discovery failed");
+		if (rn.all) {
+			printk(BIOS_EMERG, "timB discovery failed: %d, %d, %d\n",
+			       channel, slotrank, lane);
+			halt();
+			return MAKE_ERR;
+		}
 		printram("Bval: %d, %d, %d: %x\n", channel, slotrank,
 		       lane, ctrl->timings[channel][slotrank].lanes[lane].timB);
 	}
+	return 0;
 }
 
 static int get_timB_high_adjust(u64 val)
@@ -2606,9 +2631,10 @@ static void write_op(ramctr_timing * ctrl, int channel)
  * In this mode the DRAM-chip samples the CLK on every DQS edge and feeds back the
  * sampled value on the data lanes (DQs).
  */
-static void write_training(ramctr_timing * ctrl)
+static int write_training(ramctr_timing * ctrl)
 {
 	int channel, slotrank, lane;
+	int err;
 
 	FOR_ALL_POPULATED_CHANNELS
 	    write32(DEFAULT_MCHBAR + 0x4008 + 0x400 * channel,
@@ -2641,8 +2667,11 @@ static void write_training(ramctr_timing * ctrl)
 	toggle_io_reset();
 
 	/* set any valid value for timB, it gets corrected later */
-	FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS
-		discover_timB(ctrl, channel, slotrank);
+	FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
+		err = discover_timB(ctrl, channel, slotrank);
+		if (err)
+			return err;
+	}
 
 	/* disable write leveling on all ranks */
 	FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS
@@ -2691,8 +2720,11 @@ static void write_training(ramctr_timing * ctrl)
 		write32(DEFAULT_MCHBAR + 0x4288 + (channel << 10), 0);
 	}
 
-	FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS
-		discover_timC(ctrl, channel, slotrank);
+	FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
+		err = discover_timC(ctrl, channel, slotrank);
+		if (err)
+			return err;
+	}
 
 	FOR_ALL_POPULATED_CHANNELS
 		program_timings(ctrl, channel);
@@ -2708,6 +2740,7 @@ static void write_training(ramctr_timing * ctrl)
 		write32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel + 4 * lane,
 			0);
 	}
+	return 0;
 }
 
 static int test_320c(ramctr_timing * ctrl, int channel, int slotrank)
@@ -2876,7 +2909,7 @@ static void reprogram_320c(ramctr_timing * ctrl)
 
 #define MIN_C320C_LEN 13
 
-static int try_cmd_stretch(ramctr_timing * ctrl, int cmd_stretch)
+static int try_cmd_stretch(ramctr_timing *ctrl, int cmd_stretch)
 {
 	struct ram_rank_timings saved_timings[NUM_CHANNELS][NUM_SLOTRANKS];
 	int channel, slotrank;
@@ -2941,19 +2974,20 @@ static int try_cmd_stretch(ramctr_timing * ctrl, int cmd_stretch)
 				FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
 					ctrl->timings[channel][slotrank] = saved_timings[channel][slotrank];
 				}
-				return 0;
+				return MAKE_ERR;
 			}
 		}
 	}
-	return 1;
+	return 0;
 }
 
 /* Adjust CMD phase shift and try multiple command rates.
  * A command rate of 2T doubles the time needed for address and
  * command decode. */
-static void command_training(ramctr_timing * ctrl)
+static int command_training(ramctr_timing *ctrl)
 {
 	int channel;
+	int err;
 
 	FOR_ALL_POPULATED_CHANNELS {
 		fill_pattern5(ctrl, channel, 0);
@@ -2961,17 +2995,25 @@ static void command_training(ramctr_timing * ctrl)
 	}
 
 	/* try command rate 1T and 2T */
-	if (!try_cmd_stretch(ctrl, 0) && !try_cmd_stretch(ctrl, 2))
-		die("c320c discovery failed");
+	err = try_cmd_stretch(ctrl, 0);
+	if (err) {
+		err = try_cmd_stretch(ctrl, 2);
+		if (err) {
+			printk(BIOS_EMERG, "c320c discovery failed\n");
+			halt();
+			return err;
+		}
+	}
 
 	FOR_ALL_POPULATED_CHANNELS {
 		program_timings(ctrl, channel);
 	}
 
 	reprogram_320c(ctrl);
+	return 0;
 }
 
-static void discover_edges_real(ramctr_timing * ctrl, int channel, int slotrank,
+static int discover_edges_real(ramctr_timing *ctrl, int channel, int slotrank,
 				int *edges)
 {
 	int edge;
@@ -3044,18 +3086,24 @@ static void discover_edges_real(ramctr_timing * ctrl, int channel, int slotrank,
 		struct run rn =
 		    get_longest_zero_run(statistics[lane], MAX_EDGE_TIMING + 1);
 		edges[lane] = rn.middle;
-		if (rn.all)
-			die("edge discovery failed");
+		if (rn.all) {
+			printk(BIOS_EMERG, "edge discovery failed: %d, %d, %d\n",
+			       channel, slotrank, lane);
+			halt();
+			return MAKE_ERR;
+		}
 		printram("eval %d, %d, %d: %02x\n", channel, slotrank,
 		       lane, edges[lane]);
 	}
+	return 0;
 }
 
-static void discover_edges(ramctr_timing * ctrl)
+static int discover_edges(ramctr_timing *ctrl)
 {
 	int falling_edges[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES];
 	int rising_edges[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES];
 	int channel, slotrank, lane;
+	int err;
 
 	write32(DEFAULT_MCHBAR + 0x3400, 0);
 
@@ -3210,16 +3258,20 @@ static void discover_edges(ramctr_timing * ctrl)
 	printram("discover falling edges:\n[%x] = %x\n", 0x4eb0, 0x300);
 
 	FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
-		discover_edges_real(ctrl, channel, slotrank,
+		err = discover_edges_real(ctrl, channel, slotrank,
 				    falling_edges[channel][slotrank]);
+		if (err)
+			return err;
 	}
 
 	write32(DEFAULT_MCHBAR + 0x4eb0, 0x200);
 	printram("discover rising edges:\n[%x] = %x\n", 0x4eb0, 0x200);
 
 	FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
-		discover_edges_real(ctrl, channel, slotrank,
+		err = discover_edges_real(ctrl, channel, slotrank,
 				    rising_edges[channel][slotrank]);
+		if (err)
+			return err;
 	}
 
 	write32(DEFAULT_MCHBAR + 0x4eb0, 0);
@@ -3239,9 +3291,10 @@ static void discover_edges(ramctr_timing * ctrl)
 		write32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel + 4 * lane,
 			0);
 	}
+	return 0;
 }
 
-static void discover_edges_write_real(ramctr_timing * ctrl, int channel,
+static int discover_edges_write_real(ramctr_timing *ctrl, int channel,
 				      int slotrank, int *edges)
 {
 	int edge;
@@ -3353,38 +3406,47 @@ static void discover_edges_write_real(ramctr_timing * ctrl, int channel,
 				upper[lane] =
 					min(rn.end - ctrl->edge_offset[i], upper[lane]);
 				edges[lane] = (lower[lane] + upper[lane]) / 2;
-				if (rn.all || (lower[lane] > upper[lane]))
-					die("edge write discovery failed");
-
+				if (rn.all || (lower[lane] > upper[lane])) {
+					printk(BIOS_EMERG, "edge write discovery failed: %d, %d, %d\n",
+					       channel, slotrank, lane);
+					halt();
+					return MAKE_ERR;
+				}
 			}
 		}
 	}
 
 	write32(DEFAULT_MCHBAR + 0x3000, 0);
 	printram("CPA\n");
+	return 0;
 }
 
-static void discover_edges_write(ramctr_timing * ctrl)
+static int discover_edges_write(ramctr_timing *ctrl)
 {
 	int falling_edges[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES];
 	int rising_edges[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES];
 	int channel, slotrank, lane;
+	int err;
 
 	/* FIXME: under some conditions (older chipsets?) vendor BIOS sets both edges to the same value.  */
 	write32(DEFAULT_MCHBAR + 0x4eb0, 0x300);
 	printram("discover falling edges write:\n[%x] = %x\n", 0x4eb0, 0x300);
 
 	FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
-		discover_edges_write_real(ctrl, channel, slotrank,
+		err = discover_edges_write_real(ctrl, channel, slotrank,
 					  falling_edges[channel][slotrank]);
+		if (err)
+			return err;
 	}
 
 	write32(DEFAULT_MCHBAR + 0x4eb0, 0x200);
 	printram("discover rising edges write:\n[%x] = %x\n", 0x4eb0, 0x200);
 
 	FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
-		discover_edges_write_real(ctrl, channel, slotrank,
+		err = discover_edges_write_real(ctrl, channel, slotrank,
 					  rising_edges[channel][slotrank]);
+		if (err)
+			return err;
 	}
 
 	write32(DEFAULT_MCHBAR + 0x4eb0, 0);
@@ -3403,6 +3465,7 @@ static void discover_edges_write(ramctr_timing * ctrl)
 		write32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel + 4 * lane,
 			0);
 	}
+	return 0;
 }
 
 static void test_timC_write(ramctr_timing *ctrl, int channel, int slotrank)
@@ -3455,7 +3518,7 @@ static void test_timC_write(ramctr_timing *ctrl, int channel, int slotrank)
 	wait_428c(channel);
 }
 
-static void discover_timC_write(ramctr_timing * ctrl)
+static int discover_timC_write(ramctr_timing *ctrl)
 {
 	const u8 rege3c_b24[3] = { 0, 0xf, 0x2f };
 	int i, pat;
@@ -3509,8 +3572,12 @@ static void discover_timC_write(ramctr_timing * ctrl)
 
 						rn = get_longest_zero_run(statistics,
 									  MAX_TIMC + 1);
-						if (rn.all)
-							die("timC write discovery failed");
+						if (rn.all) {
+							printk(BIOS_EMERG, "timC write discovery failed: %d, %d, %d\n",
+							       channel, slotrank, lane);
+							halt();
+							return MAKE_ERR;
+						}
 						printram("timC: %d, %d, %d: 0x%02x-0x%02x-0x%02x, 0x%02x-0x%02x\n",
 							 channel, slotrank, i, rn.start,
 							 rn.middle, rn.end,
@@ -3551,6 +3618,7 @@ static void discover_timC_write(ramctr_timing * ctrl)
 	FOR_ALL_POPULATED_CHANNELS {
 		program_timings(ctrl, channel);
 	}
+	return 0;
 }
 
 static void normalize_training(ramctr_timing * ctrl)
@@ -3585,13 +3653,18 @@ static void write_controller_mr(ramctr_timing * ctrl)
 	}
 }
 
-static void channel_test(ramctr_timing * ctrl)
+static int channel_test(ramctr_timing *ctrl)
 {
 	int channel, slotrank, lane;
 
+	slotrank = 0;
 	FOR_ALL_POPULATED_CHANNELS
-		if (read32(DEFAULT_MCHBAR + 0x42a0 + (channel << 10)) & 0xa000)
-			die("Mini channel test failed (1)\n");
+		if (read32(DEFAULT_MCHBAR + 0x42a0 + (channel << 10)) & 0xa000) {
+			printk(BIOS_EMERG, "Mini channel test failed (1): %d\n",
+			       channel);
+			halt();
+			return MAKE_ERR;
+		}
 	FOR_ALL_POPULATED_CHANNELS {
 		fill_pattern0(ctrl, channel, 0x12345678, 0x98765432);
 
@@ -3633,9 +3706,14 @@ static void channel_test(ramctr_timing * ctrl)
 		write32(DEFAULT_MCHBAR + 0x4284 + (channel << 10), 0x000c0001);
 		wait_428c(channel);
 		FOR_ALL_LANES
-			if (read32(DEFAULT_MCHBAR + 0x4340 + (channel << 10) + 4 * lane))
-				die("Mini channel test failed (2)\n");
+			if (read32(DEFAULT_MCHBAR + 0x4340 + (channel << 10) + 4 * lane)) {
+				printk(BIOS_EMERG, "Mini channel test failed (2): %d, %d, %d\n",
+				       channel, slotrank, lane);
+				halt();
+				return MAKE_ERR;
+			}
 	}
+	return 0;
 }
 
 static void set_scrambling_seed(ramctr_timing * ctrl)
@@ -3949,6 +4027,8 @@ static void restore_timings(ramctr_timing * ctrl)
 static int try_init_dram_ddr3(ramctr_timing *ctrl, int s3resume,
 		int me_uma_size)
 {
+	int err;
+
 	if (!s3resume) {
 		/* Find fastest common supported parameters */
 		dram_find_common_params(ctrl);
@@ -4016,22 +4096,35 @@ static int try_init_dram_ddr3(ramctr_timing *ctrl, int s3resume,
 		/* Prepare for memory training */
 		prepare_training(ctrl);
 
-		read_training(ctrl);
-		write_training(ctrl);
+		err = read_training(ctrl);
+		if (err)
+			return err;
+
+		err = write_training(ctrl);
+		if (err)
+			return err;
 
 		printram("CP5a\n");
 
-		discover_edges(ctrl);
+		err = discover_edges(ctrl);
+		if (err)
+			return err;
 
 		printram("CP5b\n");
 
-		command_training(ctrl);
+		err = command_training(ctrl);
+		if (err)
+			return err;
 
 		printram("CP5c\n");
 
-		discover_edges_write(ctrl);
+		err = discover_edges_write(ctrl);
+		if (err)
+			return err;
 
-		discover_timC_write(ctrl);
+		err = discover_timC_write(ctrl);
+		if (err)
+			return err;
 
 		normalize_training(ctrl);
 	}
@@ -4041,7 +4134,9 @@ static int try_init_dram_ddr3(ramctr_timing *ctrl, int s3resume,
 	write_controller_mr(ctrl);
 
 	if (!s3resume) {
-		channel_test(ctrl);
+		err = channel_test(ctrl);
+		if (err)
+			return err;
 	}
 
 	return 0;



More information about the coreboot-gerrit mailing list