[coreboot-gerrit] New patch to review for coreboot: nb/intel/sandybridge/raminit: add comments

Patrick Rudolph (siro@das-labor.org) gerrit at coreboot.org
Fri Oct 16 13:25:37 CEST 2015


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

-gerrit

commit c9debd94c34fda68d1042696a9dad5cedf2dbee5
Author: Patrick Rudolph <siro at das-labor.org>
Date:   Fri Oct 9 13:33:25 2015 +0200

    nb/intel/sandybridge/raminit: add comments
    
    Add lot's of comments for better documentation.
    
    Change-Id: Ia203cb649857f979bb6c1c2d405b74f2ccc8f99d
    Signed-off-by: Patrick Rudolph <siro at das-labor.org>
---
 src/northbridge/intel/sandybridge/raminit.c | 205 ++++++++++++++++++++++++++--
 1 file changed, 190 insertions(+), 15 deletions(-)

diff --git a/src/northbridge/intel/sandybridge/raminit.c b/src/northbridge/intel/sandybridge/raminit.c
index 76f62a6..23b34f5 100644
--- a/src/northbridge/intel/sandybridge/raminit.c
+++ b/src/northbridge/intel/sandybridge/raminit.c
@@ -45,6 +45,38 @@
 /* FIXME: no ECC support.  */
 /* FIXME: no support for 3-channel chipsets.  */
 
+/*
+ * Register description:
+ * Intel provides a command queue of depth four.
+ * Every command is configured by using multiple registers.
+ * On executing the command queue you have to provide the depth used.
+ *
+ * Known registers:
+ * Channel X = [0, 1]
+ * Command queue index Y = [0, 1, 2, 3]
+ *
+ * DEFAULT_MCHBAR + 0x4220 + 0x400 * X + 4 * Y: command io register
+ *  Controls the DRAM command signals
+ *  Bit 0: !RAS
+ *  Bit 1: !CAS
+ *  Bit 2: !WE
+ *
+ * DEFAULT_MCHBAR + 0x4200 + 0x400 * X + 4 * Y: addr bankslot io register
+ *  Controls the address, bank address and slotrank signals
+ *  Bit 0-15 : Address
+ *  Bit 20-22: Bank Address
+ *  Bit 24-25: slotrank
+ *
+ * DEFAULT_MCHBAR + 0x4230 + 0x400 * X + 4 * Y: idle register
+ *  Controls the idle time after issuing this DRAM command
+ *  Bit 16-32: number of clock-cylces to idle
+ *
+ * DEFAULT_MCHBAR + 0x4284 + 0x400 * channel: execute command queue
+ *  Starts to execute all queued commands
+ *  Bit 0    : start DRAM command execution
+ *  Bit 16-20: (number of queued commands - 1) * 4
+ */
+
 #define BASEFREQ 133
 #define tDLLK 512
 
@@ -1119,6 +1151,7 @@ static void write_reset(ramctr_timing * ctrl)
 	/* choose a populated rank.  */
 	slotrank = (ctrl->rankmap[channel] & 1) ? 0 : 2;
 
+	/* DRAM command ZQCS */
 	write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x0f003);
 	write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel, 0x80c01);
 
@@ -1229,18 +1262,21 @@ static void write_mrreg(ramctr_timing * ctrl, int channel, int slotrank,
 
 	printram("MRd: %x <= %x\n", reg, val);
 
+	/* DRAM command MRS */
 	write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x0f000);
 	write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel, 0x41001);
 	write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
 		(slotrank << 24) | (reg << 20) | val | 0x60000);
 	write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
 
+	/* DRAM command MRS */
 	write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f000);
 	write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel, 0x41001);
 	write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
 		(slotrank << 24) | (reg << 20) | val | 0x60000);
 	write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
 
+	/* DRAM command MRS */
 	write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x0f000);
 	write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
 		0x1001 | (ctrl->tMOD << 16));
@@ -1254,6 +1290,8 @@ static u32 make_mr0(ramctr_timing * ctrl, u8 rank)
 {
 	u16 mr0reg, mch_cas, mch_wr;
 	static const u8 mch_wr_t[12] = { 1, 2, 3, 4, 0, 5, 0, 6, 0, 7, 0, 0 };
+
+	/* DLL Reset - self clearing - set after CLK frequency has been changed */
 	mr0reg = 0x100;
 
 	// Convert CAS to MCH register friendly
@@ -1270,7 +1308,8 @@ static u32 make_mr0(ramctr_timing * ctrl, u8 rank)
 	mr0reg = (mr0reg & ~0x4) | (mch_cas & 0x1);
 	mr0reg = (mr0reg & ~0x70) | ((mch_cas & 0xe) << 3);
 	mr0reg = (mr0reg & ~0xe00) | (mch_wr << 9);
-	// Fast (desktop) 0x1 or slow (mobile) 0x0
+
+	// Precharge PD - Fast (desktop) 0x1 or slow (mobile) 0x0 - mostly power-saving feature
 	mr0reg = (mr0reg & ~0x1000) | (!ctrl->mobile << 12);
 	return mr0reg;
 }
@@ -1385,14 +1424,18 @@ static void dram_mrscommands(ramctr_timing * ctrl)
 		printram("done\n");
 	}
 
+	/* DRAM command NOP */
 	write32(DEFAULT_MCHBAR + 0x4e20, 0x7);
 	write32(DEFAULT_MCHBAR + 0x4e30, 0xf1001);
 	write32(DEFAULT_MCHBAR + 0x4e00, 0x60002);
 	write32(DEFAULT_MCHBAR + 0x4e10, 0);
+
+	/* DRAM command ZQCL */
 	write32(DEFAULT_MCHBAR + 0x4e24, 0x1f003);
 	write32(DEFAULT_MCHBAR + 0x4e34, 0x1901001);
 	write32(DEFAULT_MCHBAR + 0x4e04, 0x60400);
 	write32(DEFAULT_MCHBAR + 0x4e14, 0x288);
+
 	write32(DEFAULT_MCHBAR + 0x4e84, 0x40004);
 
 	// Drain
@@ -1417,6 +1460,7 @@ static void dram_mrscommands(ramctr_timing * ctrl)
 		// Drain
 		wait_428c(channel);
 
+		/* DRAM command ZQCS */
 		write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x0f003);
 		write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel, 0x659001);
 		write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
@@ -1593,6 +1637,10 @@ static void test_timA(ramctr_timing * ctrl, int channel, int slotrank)
 {
 	wait_428c(channel);
 
+	/* DRAM command MRS
+	 * write MR3 MPR enable
+	 * in this mode only RD and RDA are allowed
+	 * all reads return a predefined pattern */
 	write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f000);
 	write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
 		(0xc01 | (ctrl->tMOD << 16)));
@@ -1600,11 +1648,13 @@ static void test_timA(ramctr_timing * ctrl, int channel, int slotrank)
 		(slotrank << 24) | 0x360004);
 	write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
 
+	/* DRAM command RD */
 	write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f105);
 	write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel, 0x4040c01);
 	write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel, (slotrank << 24));
 	write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
 
+	/* DRAM command RD */
 	write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x1f105);
 	write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
 		0x100f | ((ctrl->CAS + 36) << 16));
@@ -1612,6 +1662,8 @@ static void test_timA(ramctr_timing * ctrl, int channel, int slotrank)
 		(slotrank << 24) | 0x60000);
 	write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
 
+	/* DRAM command MRS
+	 * write MR3 MPR disable */
 	write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel, 0x1f000);
 	write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
 		(0xc01 | (ctrl->tMOD << 16)));
@@ -1843,6 +1895,23 @@ static void post_timA_change(ramctr_timing * ctrl, int channel, int slotrank,
 	printram("4028 += %d;\n", shift_402x);
 }
 
+/* Compensate the skew between DQS and DQs.
+ * To ease PCB design a small skew between Data Strobe signals and
+ * Data Signals is allow.
+ * The controller has to measure and compensate this skew for every byte-lane.
+ * By delaying either all DQs signals or DQS signal, a full phase
+ * shift can be introduced.
+ * It is assumed that one byte-lane's DQs signals have the same routing delay.
+ *
+ * To measure the actual skew, the DRAM is placed in "read leveling" mode.
+ * In read leveling mode the DRAM-chip outputs an alternating periodic pattern.
+ * The memory controller iterates over all possible values to do a full phase shift
+ * and issues read commands.
+ * With DQS and DQs in phase the data read is expected to alternate on every byte:
+ * 0xFF 0x00 0xFF ...
+ * 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)
 {
 	int channel, slotrank, lane;
@@ -1854,6 +1923,8 @@ static void read_training(ramctr_timing * ctrl)
 		struct timA_minmax mnmx;
 
 		 wait_428c(channel);
+
+		 /* DRAM command PREA */
 		 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f002);
 		 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
 			 0xc01 | (ctrl->tRP << 16));
@@ -1929,12 +2000,11 @@ static void read_training(ramctr_timing * ctrl)
 
 		write32(DEFAULT_MCHBAR + 0x3400, 0);
 
+		/* toggle IO reset bit */
 		r32 = read32(DEFAULT_MCHBAR + 0x5030);
 		write32(DEFAULT_MCHBAR + 0x5030, r32 | 0x20);
 		udelay(1);
-
 		write32(DEFAULT_MCHBAR + 0x5030, r32 & ~0x20);
-
 		udelay(1);
 	}
 
@@ -1958,6 +2028,7 @@ static void test_timC(ramctr_timing * ctrl, int channel, int slotrank)
 
 	wait_428c(channel);
 
+	/* DRAM command ACT */
 	write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f006);
 	write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
 		(max((ctrl->tFAW >> 2) + 1, ctrl->tRRD) << 10)
@@ -1968,17 +2039,20 @@ static void test_timC(ramctr_timing * ctrl, int channel, int slotrank)
 
 	write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x244);
 
+	/* DRAM command NOP */
 	write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f207);
 	write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel, 0x8041001);
 	write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
 		(slotrank << 24) | 8);
 	write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0x3e0);
 
+	/* DRAM command WR */
 	write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x1f201);
 	write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel, 0x80411f4);
 	write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel, (slotrank << 24));
 	write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0x242);
 
+	/* DRAM command NOP */
 	write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel, 0x1f207);
 	write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
 		0x8000c01 | ((ctrl->CWL + ctrl->tWTR + 5) << 16));
@@ -1990,6 +2064,7 @@ static void test_timC(ramctr_timing * ctrl, int channel, int slotrank)
 
 	wait_428c(channel);
 
+	/* DRAM command PREA */
 	write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f002);
 	write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
 		0xc01 | (ctrl->tRP << 16));
@@ -1997,6 +2072,7 @@ static void test_timC(ramctr_timing * ctrl, int channel, int slotrank)
 		(slotrank << 24) | 0x60400);
 	write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x240);
 
+	/* DRAM command ACT */
 	write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f006);
 	write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
 		(max(ctrl->tRRD, (ctrl->tFAW >> 2) + 1) << 10)
@@ -2007,12 +2083,14 @@ static void test_timC(ramctr_timing * ctrl, int channel, int slotrank)
 
 	write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0x244);
 
+	/* DRAM command RD */
 	write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x1f105);
 	write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
 		0x40011f4 | (max(ctrl->tRTP, 8) << 16));
 	write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel, (slotrank << 24));
 	write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0x242);
 
+	/* DRAM command PREA */
 	write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel, 0x1f002);
 	write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
 		0xc01 | (ctrl->tRP << 16));
@@ -2031,6 +2109,7 @@ static void discover_timC(ramctr_timing * ctrl, int channel, int slotrank)
 
 	wait_428c(channel);
 
+	/* DRAM command PREA */
 	write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f002);
 	write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
 		0xc01 | (ctrl->tRP << 16));
@@ -2121,6 +2200,10 @@ static void precharge(ramctr_timing * ctrl)
 		FOR_ALL_POPULATED_RANKS {
 			wait_428c(channel);
 
+			/* DRAM command MRS
+			 * write MR3 MPR enable
+			 * in this mode only RD and RDA are allowed
+			 * all reads return a predefined pattern */
 			write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel,
 				0x1f000);
 			write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
@@ -2129,6 +2212,7 @@ static void precharge(ramctr_timing * ctrl)
 				(slotrank << 24) | 0x360004);
 			write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
 
+			/* DRAM command RD */
 			write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel,
 				0x1f105);
 			write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
@@ -2137,6 +2221,7 @@ static void precharge(ramctr_timing * ctrl)
 				(slotrank << 24) | 0);
 			write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
 
+			/* DRAM command RD */
 			write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel,
 				0x1f105);
 			write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
@@ -2145,6 +2230,8 @@ static void precharge(ramctr_timing * ctrl)
 				(slotrank << 24) | 0x60000);
 			write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
 
+			/* DRAM command MRS
+			 * write MR3 MPR disable */
 			write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel,
 				0x1f000);
 			write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
@@ -2169,7 +2256,10 @@ static void precharge(ramctr_timing * ctrl)
 
 		FOR_ALL_POPULATED_RANKS {
 			wait_428c(channel);
-
+			/* DRAM command MRS
+			 * write MR3 MPR enable
+			 * in this mode only RD and RDA are allowed
+			 * all reads return a predefined pattern */
 			write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel,
 				0x1f000);
 			write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
@@ -2178,6 +2268,7 @@ static void precharge(ramctr_timing * ctrl)
 				(slotrank << 24) | 0x360004);
 			write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
 
+			/* DRAM command RD */
 			write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel,
 				0x1f105);
 			write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
@@ -2186,6 +2277,7 @@ static void precharge(ramctr_timing * ctrl)
 				(slotrank << 24) | 0);
 			write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
 
+			/* DRAM command RD */
 			write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel,
 				0x1f105);
 			write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
@@ -2194,6 +2286,8 @@ static void precharge(ramctr_timing * ctrl)
 				(slotrank << 24) | 0x60000);
 			write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
 
+			/* DRAM command MRS
+			 * write MR3 MPR disable */
 			write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel,
 				0x1f000);
 			write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
@@ -2212,10 +2306,12 @@ static void precharge(ramctr_timing * ctrl)
 
 static void test_timB(ramctr_timing * ctrl, int channel, int slotrank)
 {
+	/* enable DQs on this slotrank */
 	write_mrreg(ctrl, channel, slotrank, 1,
 		    0x80 | make_mr1(ctrl, slotrank));
 
 	wait_428c(channel);
+	/* DRAM command NOP */
 	write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f207);
 	write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
 		0x8000c01 | ((ctrl->CWL + ctrl->tWLO) << 16));
@@ -2223,6 +2319,7 @@ static void test_timB(ramctr_timing * ctrl, int channel, int slotrank)
 		8 | (slotrank << 24));
 	write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
 
+	/* DRAM command NOP */
 	write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f107);
 	write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
 		0x4000c01 | ((ctrl->CAS + 38) << 16));
@@ -2233,6 +2330,7 @@ static void test_timB(ramctr_timing * ctrl, int channel, int slotrank)
 	write32(DEFAULT_MCHBAR + 0x400 * channel + 0x4284, 0x40001);
 	wait_428c(channel);
 
+	/* disable DQs on this slotrank */
 	write_mrreg(ctrl, channel, slotrank, 1,
 		    0x1080 | make_mr1(ctrl, slotrank));
 }
@@ -2310,6 +2408,7 @@ static void adjust_high_timB(ramctr_timing * ctrl)
 
 		wait_428c(channel);
 
+		/* DRAM command ACT */
 		write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f006);
 		write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
 			0xc01 | (ctrl->tRCD << 16));
@@ -2317,18 +2416,21 @@ static void adjust_high_timB(ramctr_timing * ctrl)
 			(slotrank << 24) | 0x60000);
 		write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
 
+		/* DRAM command NOP */
 		write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f207);
 		write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel, 0x8040c01);
 		write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
 			(slotrank << 24) | 0x8);
 		write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0x3e0);
 
+		/* DRAM command WR */
 		write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x1f201);
 		write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel, 0x8041003);
 		write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
 			(slotrank << 24));
 		write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0x3e2);
 
+		/* DRAM command NOP */
 		write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel, 0x1f207);
 		write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
 			0x8000c01 | ((ctrl->CWL + ctrl->tWTR + 5) << 16));
@@ -2340,6 +2442,7 @@ static void adjust_high_timB(ramctr_timing * ctrl)
 
 		wait_428c(channel);
 
+		/* DRAM command PREA */
 		write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f002);
 		write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
 			0xc01 | ((ctrl->tRP) << 16));
@@ -2347,6 +2450,7 @@ static void adjust_high_timB(ramctr_timing * ctrl)
 			(slotrank << 24) | 0x60400);
 		write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x240);
 
+		/* DRAM command ACT */
 		write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f006);
 		write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
 			0xc01 | ((ctrl->tRCD) << 16));
@@ -2354,6 +2458,7 @@ static void adjust_high_timB(ramctr_timing * ctrl)
 			(slotrank << 24) | 0x60000);
 		write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
 
+		/* DRAM command RD */
 		write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x3f105);
 		write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
 			0x4000c01 |
@@ -2396,6 +2501,7 @@ static void write_op(ramctr_timing * ctrl, int channel)
 	/* choose an existing rank.  */
 	slotrank = !(ctrl->rankmap[channel] & 1) ? 2 : 0;
 
+	/* DRAM command ACT */
 	write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x0f003);
 	write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel, 0x41001);
 
@@ -2408,6 +2514,19 @@ static void write_op(ramctr_timing * ctrl, int channel)
 	wait_428c(channel);
 }
 
+/* Compensate the skew between CMD/ADDR/CLK and DQ/DQS lanes.
+ * DDR3 adopted the fly-by topology. The data and strobes signals reach
+ * the chips at different times with respect to command, address and
+ * clock signals.
+ * By delaying either all DQ/DQs or all CMD/ADDR/CLK signals, a full phase
+ * shift can be introduced.
+ * It is assumed that the CLK/ADDR/CMD signals have the same routing delay.
+ *
+ * To find the required phase shift the DRAM is placed in "write leveling" mode.
+ * In this mode the DRAM-chip samples the CLK on every DQS edge and feeds back the
+ * sampled value on the data lanes (DQs).
+ * The memory controller iterates over all possible values and
+ */
 static void write_training(ramctr_timing * ctrl)
 {
 	int channel, slotrank, lane;
@@ -2424,11 +2543,16 @@ static void write_training(ramctr_timing * ctrl)
 			read32(DEFAULT_MCHBAR + 0x4020 +
 			       0x400 * channel) | 0x200000);
 	}
+
+	/* refresh disable */
 	write32(DEFAULT_MCHBAR + 0x5030, read32(DEFAULT_MCHBAR + 0x5030) & ~8);
 	FOR_ALL_POPULATED_CHANNELS {
 		write_op(ctrl, channel);
 	}
 
+	/* enable write leveling on all ranks
+	 * disable all DQ outputs
+	 * only NOP is allowed in this mode */
 	FOR_ALL_CHANNELS
 	    FOR_ALL_POPULATED_RANKS
 		write_mrreg(ctrl, channel, slotrank, 1,
@@ -2436,17 +2560,18 @@ static void write_training(ramctr_timing * ctrl)
 
 	write32(DEFAULT_MCHBAR + 0x3400, 0x108052);
 
+	/* toggle IO reset bit */
 	r32 = read32(DEFAULT_MCHBAR + 0x5030);
 	write32(DEFAULT_MCHBAR + 0x5030, r32 | 0x20);
 	udelay(1);
-
 	write32(DEFAULT_MCHBAR + 0x5030, r32 & ~0x20);
-
 	udelay(1);
 
+	/* set any valid value for timB, it gets corrected later */
 	FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS
 		discover_timB(ctrl, channel, slotrank);
 
+	/* disable write leveling on all ranks */
 	FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS
 		write_mrreg(ctrl, channel,
 			    slotrank, 1, make_mr1(ctrl, slotrank));
@@ -2456,6 +2581,7 @@ static void write_training(ramctr_timing * ctrl)
 	FOR_ALL_POPULATED_CHANNELS
 		wait_428c(channel);
 
+	/* refresh enable */
 	write32(DEFAULT_MCHBAR + 0x5030, read32(DEFAULT_MCHBAR + 0x5030) | 8);
 
 	FOR_ALL_POPULATED_CHANNELS {
@@ -2465,6 +2591,7 @@ static void write_training(ramctr_timing * ctrl)
 		read32(DEFAULT_MCHBAR + 0x428c + 0x400 * channel);
 		wait_428c(channel);
 
+		/* DRAM command ZQCS */
 		write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x0f003);
 		write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel, 0x659001);
 		write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel, 0x60000);
@@ -2474,12 +2601,11 @@ static void write_training(ramctr_timing * ctrl)
 		wait_428c(channel);
 	}
 
+	/* toggle IO reset bit */
 	r32 = read32(DEFAULT_MCHBAR + 0x5030);
 	write32(DEFAULT_MCHBAR + 0x5030, r32 | 0x20);
 	udelay(1);
-
 	write32(DEFAULT_MCHBAR + 0x5030, r32 & ~0x20);
-
 	udelay(1);
 
 	printram("CPE\n");
@@ -2503,6 +2629,7 @@ static void write_training(ramctr_timing * ctrl)
 	FOR_ALL_POPULATED_CHANNELS
 		program_timings(ctrl, channel);
 
+	/* measure and adjust timB timings */
 	adjust_high_timB(ctrl);
 
 	FOR_ALL_POPULATED_CHANNELS
@@ -2536,7 +2663,7 @@ static int test_320c(ramctr_timing * ctrl, int channel, int slotrank)
 		write32(DEFAULT_MCHBAR + 0x4288 + 0x400 * channel, 0x1f);
 
 		wait_428c(channel);
-
+		/* DRAM command ACT */
 		write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f006);
 		write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
 			((max(ctrl->tRRD, (ctrl->tFAW >> 2) + 1)) << 10)
@@ -2546,7 +2673,7 @@ static int test_320c(ramctr_timing * ctrl, int channel, int slotrank)
 			(slotrank << 24) | ctr | 0x60000);
 
 		write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x244);
-
+		/* DRAM command WR */
 		write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f201);
 		write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
 			0x8001020 | ((ctrl->CWL + ctrl->tWTR + 8) << 16));
@@ -2555,6 +2682,7 @@ static int test_320c(ramctr_timing * ctrl, int channel, int slotrank)
 		write32(DEFAULT_MCHBAR + 0x4244 + 0x400 * channel, 0x389abcd);
 		write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0x20e42);
 
+		/* DRAM command RD */
 		write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x1f105);
 		write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
 			0x4001020 | (max(ctrl->tRTP, 8) << 16));
@@ -2563,6 +2691,7 @@ static int test_320c(ramctr_timing * ctrl, int channel, int slotrank)
 		write32(DEFAULT_MCHBAR + 0x4248 + 0x400 * channel, 0x389abcd);
 		write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0x20e42);
 
+		/* DRAM command PRE */
 		write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel, 0x1f002);
 		write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel, 0xf1001);
 		write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
@@ -2633,6 +2762,7 @@ static void reprogram_320c(ramctr_timing * ctrl)
 		/* choose an existing rank.  */
 		slotrank = !(ctrl->rankmap[channel] & 1) ? 2 : 0;
 
+		/* DRAM command ZQCS */
 		write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x0f003);
 		write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel, 0x41001);
 
@@ -2647,6 +2777,8 @@ static void reprogram_320c(ramctr_timing * ctrl)
 			read32(DEFAULT_MCHBAR + 0x4020 +
 			       0x400 * channel) | 0x200000);
 	}
+
+	/* refresh disable */
 	write32(DEFAULT_MCHBAR + 0x5030, read32(DEFAULT_MCHBAR + 0x5030) & ~8);
 	FOR_ALL_POPULATED_CHANNELS {
 		wait_428c(channel);
@@ -2654,6 +2786,7 @@ static void reprogram_320c(ramctr_timing * ctrl)
 		/* choose an existing rank.  */
 		slotrank = !(ctrl->rankmap[channel] & 1) ? 2 : 0;
 
+		/* DRAM command ZQCS */
 		write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x0f003);
 		write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel, 0x41001);
 
@@ -2671,12 +2804,11 @@ static void reprogram_320c(ramctr_timing * ctrl)
 	/* mrs commands. */
 	dram_mrscommands(ctrl);
 
+	/* toggle IO reset bit */
 	r32 = read32(DEFAULT_MCHBAR + 0x5030);
 	write32(DEFAULT_MCHBAR + 0x5030, r32 | 0x20);
 	udelay(1);
-
 	write32(DEFAULT_MCHBAR + 0x5030, r32 & ~0x20);
-
 	udelay(1);
 }
 
@@ -2754,6 +2886,9 @@ static int try_cmd_stretch(ramctr_timing * ctrl, int cmd_stretch)
 	return 1;
 }
 
+/* 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)
 {
 	int channel;
@@ -2799,7 +2934,10 @@ static void discover_edges_real(ramctr_timing * ctrl, int channel, int slotrank,
 		}
 
 		wait_428c(channel);
-
+		/* DRAM command MRS
+		 * write MR3 MPR enable
+		 * in this mode only RD and RDA are allowed
+		 * all reads return a predefined pattern */
 		write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f000);
 		write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
 			(0xc01 | (ctrl->tMOD << 16)));
@@ -2807,12 +2945,14 @@ static void discover_edges_real(ramctr_timing * ctrl, int channel, int slotrank,
 			(slotrank << 24) | 0x360004);
 		write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
 
+		/* DRAM command RD */
 		write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f105);
 		write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel, 0x40411f4);
 		write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
 			(slotrank << 24));
 		write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
 
+		/* DRAM command RD */
 		write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x1f105);
 		write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
 			0x1001 | ((ctrl->CAS + 8) << 16));
@@ -2820,6 +2960,8 @@ static void discover_edges_real(ramctr_timing * ctrl, int channel, int slotrank,
 			(slotrank << 24) | 0x60000);
 		write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
 
+		/* DRAM command MRS
+		 * MR3 disable MPR */
 		write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel, 0x1f000);
 		write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
 			(0xc01 | (ctrl->tMOD << 16)));
@@ -2857,12 +2999,11 @@ static void discover_edges(ramctr_timing * ctrl)
 
 	write32(DEFAULT_MCHBAR + 0x3400, 0);
 
+	/* toggle IO reset bit */
 	r32 = read32(DEFAULT_MCHBAR + 0x5030);
 	write32(DEFAULT_MCHBAR + 0x5030, r32 | 0x20);
 	udelay(1);
-
 	write32(DEFAULT_MCHBAR + 0x5030, r32 & ~0x20);
-
 	udelay(1);
 
 	FOR_ALL_POPULATED_CHANNELS FOR_ALL_LANES {
@@ -2890,6 +3031,11 @@ static void discover_edges(ramctr_timing * ctrl)
 		FOR_ALL_POPULATED_RANKS {
 			wait_428c(channel);
 
+			/* DRAM command MRS
+			 * MR3 enable MPR
+			 * write MR3 MPR enable
+			 * in this mode only RD and RDA are allowed
+			 * all reads return a predefined pattern */
 			write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel,
 				0x1f000);
 			write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
@@ -2898,6 +3044,7 @@ static void discover_edges(ramctr_timing * ctrl)
 				(slotrank << 24) | 0x360004);
 			write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
 
+			/* DRAM command RD */
 			write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel,
 				0x1f105);
 			write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
@@ -2906,6 +3053,7 @@ static void discover_edges(ramctr_timing * ctrl)
 				(slotrank << 24) | 0);
 			write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
 
+			/* DRAM command RD */
 			write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel,
 				0x1f105);
 			write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
@@ -2914,6 +3062,8 @@ static void discover_edges(ramctr_timing * ctrl)
 				(slotrank << 24) | 0x60000);
 			write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
 
+			/* DRAM command MRS
+			 * MR3 disable MPR */
 			write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel,
 				0x1f000);
 			write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
@@ -2927,6 +3077,8 @@ static void discover_edges(ramctr_timing * ctrl)
 			wait_428c(channel);
 		}
 
+		/* XXX: check any measured value ? */
+
 		FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
 			ctrl->timings[channel][slotrank].lanes[lane].falling =
 			    48;
@@ -2939,6 +3091,11 @@ static void discover_edges(ramctr_timing * ctrl)
 		FOR_ALL_POPULATED_RANKS {
 			wait_428c(channel);
 
+			/* DRAM command MRS
+			 * MR3 enable MPR
+			 * write MR3 MPR enable
+			 * in this mode only RD and RDA are allowed
+			 * all reads return a predefined pattern */
 			write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel,
 				0x1f000);
 			write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
@@ -2947,6 +3104,7 @@ static void discover_edges(ramctr_timing * ctrl)
 				(slotrank << 24) | 0x360004);
 			write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
 
+			/* DRAM command RD */
 			write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel,
 				0x1f105);
 			write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
@@ -2955,6 +3113,7 @@ static void discover_edges(ramctr_timing * ctrl)
 				(slotrank << 24) | 0);
 			write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
 
+			/* DRAM command RD */
 			write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel,
 				0x1f105);
 			write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
@@ -2963,6 +3122,8 @@ static void discover_edges(ramctr_timing * ctrl)
 				(slotrank << 24) | 0x60000);
 			write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
 
+			/* DRAM command MRS
+			 * MR3 disable MPR */
 			write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel,
 				0x1f000);
 			write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
@@ -2976,6 +3137,8 @@ static void discover_edges(ramctr_timing * ctrl)
 			wait_428c(channel);
 		}
 
+		/* XXX: check any measured value ? */
+
 		FOR_ALL_LANES {
 			write32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel +
 				lane * 4,
@@ -3065,6 +3228,7 @@ static void discover_edges_write_real(ramctr_timing * ctrl, int channel,
 				}
 				wait_428c(channel);
 
+				/* DRAM command ACT */
 				write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel,
 					0x1f006);
 				write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
@@ -3076,6 +3240,7 @@ static void discover_edges_write_real(ramctr_timing * ctrl, int channel,
 				write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel,
 					0x240);
 
+				/* DRAM command WR */
 				write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel,
 					0x1f201);
 				write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
@@ -3086,6 +3251,7 @@ static void discover_edges_write_real(ramctr_timing * ctrl, int channel,
 				write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel,
 					0x242);
 
+				/* DRAM command RD */
 				write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel,
 					0x1f105);
 				write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
@@ -3095,6 +3261,7 @@ static void discover_edges_write_real(ramctr_timing * ctrl, int channel,
 				write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel,
 					0x242);
 
+				/* DRAM command PRE */
 				write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel,
 					0x1f002);
 				write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
@@ -3183,6 +3350,7 @@ static void discover_edges_write(ramctr_timing * ctrl)
 static void test_timC_write(ramctr_timing *ctrl, int channel, int slotrank)
 {
 	wait_428c(channel);
+	/* DRAM command ACT */
 	write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f006);
 	write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
 		(max((ctrl->tFAW >> 2) + 1, ctrl->tRRD)
@@ -3191,6 +3359,7 @@ static void test_timC_write(ramctr_timing *ctrl, int channel, int slotrank)
 		(slotrank << 24) | 0x60000);
 	write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x244);
 
+	/* DRAM command WR */
 	write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f201);
 	write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
 		0x80011e0 |
@@ -3200,6 +3369,7 @@ static void test_timC_write(ramctr_timing *ctrl, int channel, int slotrank)
 	write32(DEFAULT_MCHBAR + 0x4214 +
 		0x400 * channel, 0x242);
 
+	/* DRAM command RD */
 	write32(DEFAULT_MCHBAR + 0x4228 +
 		0x400 * channel, 0x1f105);
 	write32(DEFAULT_MCHBAR + 0x4238 +
@@ -3210,6 +3380,7 @@ static void test_timC_write(ramctr_timing *ctrl, int channel, int slotrank)
 	write32(DEFAULT_MCHBAR + 0x4218 +
 		0x400 * channel, 0x242);
 
+	/* DRAM command PRE */
 	write32(DEFAULT_MCHBAR + 0x422c +
 		0x400 * channel, 0x1f002);
 	write32(DEFAULT_MCHBAR + 0x423c +
@@ -3371,21 +3542,25 @@ static void channel_test(ramctr_timing * ctrl)
 			write32(DEFAULT_MCHBAR + (0x4d40 + 4 * lane), 0);
 		}
 		wait_428c(channel);
+		/* DRAM command ACT */
 		write32(DEFAULT_MCHBAR + 0x4220 + (channel << 10), 0x0001f006);
 		write32(DEFAULT_MCHBAR + 0x4230 + (channel << 10), 0x0028a004);
 		write32(DEFAULT_MCHBAR + 0x4200 + (channel << 10),
 			0x00060000 | (slotrank << 24));
 		write32(DEFAULT_MCHBAR + 0x4210 + (channel << 10), 0x00000244);
+		/* DRAM command WR */
 		write32(DEFAULT_MCHBAR + 0x4224 + (channel << 10), 0x0001f201);
 		write32(DEFAULT_MCHBAR + 0x4234 + (channel << 10), 0x08281064);
 		write32(DEFAULT_MCHBAR + 0x4204 + (channel << 10),
 			0x00000000 | (slotrank << 24));
 		write32(DEFAULT_MCHBAR + 0x4214 + (channel << 10), 0x00000242);
+		/* DRAM command RD */
 		write32(DEFAULT_MCHBAR + 0x4228 + (channel << 10), 0x0001f105);
 		write32(DEFAULT_MCHBAR + 0x4238 + (channel << 10), 0x04281064);
 		write32(DEFAULT_MCHBAR + 0x4208 + (channel << 10),
 			0x00000000 | (slotrank << 24));
 		write32(DEFAULT_MCHBAR + 0x4218 + (channel << 10), 0x00000242);
+		/* DRAM command PRE */
 		write32(DEFAULT_MCHBAR + 0x422c + (channel << 10), 0x0001f002);
 		write32(DEFAULT_MCHBAR + 0x423c + (channel << 10), 0x00280c01);
 		write32(DEFAULT_MCHBAR + 0x420c + (channel << 10),



More information about the coreboot-gerrit mailing list