[coreboot-gerrit] Change in coreboot[master]: nb/intel/x4x: DDR3 JEDEC init

Arthur Heymans (Code Review) gerrit at coreboot.org
Wed May 24 22:10:37 CEST 2017


Arthur Heymans has uploaded a new change for review. ( https://review.coreboot.org/19877 )

Change subject: nb/intel/x4x: DDR3 JEDEC init
......................................................................

nb/intel/x4x: DDR3 JEDEC init

Change-Id: I3b5eeb0aff6764292bbcbed7274274f615066c14
Signed-off-by: Arthur Heymans <arthur at aheymans.xyz>
---
M src/northbridge/intel/x4x/raminit_ddr23.c
M src/northbridge/intel/x4x/spd_ddr3_decode.c
M src/northbridge/intel/x4x/x4x.h
3 files changed, 78 insertions(+), 9 deletions(-)


  git pull ssh://review.coreboot.org:29418/coreboot refs/changes/77/19877/1

diff --git a/src/northbridge/intel/x4x/raminit_ddr23.c b/src/northbridge/intel/x4x/raminit_ddr23.c
index 0d09c05..a289788 100644
--- a/src/northbridge/intel/x4x/raminit_ddr23.c
+++ b/src/northbridge/intel/x4x/raminit_ddr23.c
@@ -1269,14 +1269,31 @@
 	}
 }
 
-static void send_jedec_cmd(u8 r, u8 ch, u8 cmd, u16 val)
+void send_jedec_cmd(const struct sysinfo *s, u8 r, u8 ch, u8 cmd, u32 val)
 {
 	u32 addr = (ch << 29) | (r*0x08000000);
 	volatile u32 rubbish;
+	u8 data8 = cmd;
+	u32 data32;
 
-	MCHBAR8(0x271) = (MCHBAR8(0x271) & ~0x3e) | cmd;
-	MCHBAR8(0x671) = (MCHBAR8(0x671) & ~0x3e) | cmd;
-	rubbish = read32((void *)((val<<3) | addr));
+	if (s->spd_type == DDR3 && (r & 1) && s->dimms[r].mirrorred) {
+		data8 &= ~(1 << 4);
+		data8 |= ((1 << 4) & (cmd >> 1));
+		data8 &= ~(1 << 5);
+		data8 |= ((1 << 5) & (cmd << 1));
+	}
+
+	MCHBAR8(0x271) = (MCHBAR8(0x271) & ~0x3e) | data8;
+	MCHBAR8(0x671) = (MCHBAR8(0x671) & ~0x3e) | data8;
+	data32 = val;
+	if (s->spd_type == DDR3 && (r & 1) && s->dimms[r].mirrorred) {
+		data32 &= ~(0x1f8);
+		data32 |= (val & 0xb0) << 1;
+		data32 |= (val & 0x160) >> 1;
+	}
+	data32 <<= 3;
+
+	rubbish = read32((void *)((data32 | addr)));
 	udelay(10);
 	MCHBAR8(0x271) = (MCHBAR8(0x271) & ~0x3e) | NORMALOP_CMD;
 	MCHBAR8(0x671) = (MCHBAR8(0x671) & ~0x3e) | NORMALOP_CMD;
@@ -1341,7 +1358,7 @@
 			default:
 				break;
 			}
-			send_jedec_cmd(r + ch*4, ch, jedec[i][0], v);
+			send_jedec_cmd(s, r + ch*4, ch, jedec[i][0], v);
 			udelay(1);
 			//printk(BIOS_DEBUG, "Jedec step %d\n", i);
 		}
@@ -1349,6 +1366,51 @@
 	printk(BIOS_DEBUG, "MRS done\n");
 }
 
+static void jedec_ddr3(struct sysinfo *s)
+{
+	int ch, r, dimmconfig, cmd, ddr3_freq;
+
+	u8 ddr3_emrs2_config[16][4] = { /* [config][Rank] */
+		{0, 0, 0, 0},	/* NC_NC */
+		{0, 0, 0, 0},	/* x8ss_NC */
+		{0, 0, 0, 0},	/* x8ds_NC */
+		{0, 0, 0, 0},	/* x16ss_NC */
+		{0, 0, 0, 0},	/* NC_x8ss */
+		{2, 0, 2, 0},	/* x8ss_x8ss */
+		{2, 2, 2, 0},	/* x8ds_x8ss */
+		{2, 0, 2, 0},	/* x16ss_x8ss */
+		{0, 0, 0, 0},	/* NC_x8ss */
+		{2, 0, 2, 2},	/* x8ss_x8ds */
+		{2, 2, 2, 2},	/* x8ds_x8ds */
+		{2, 0, 2, 2},	/* x16ss_x8ds */
+		{0, 0, 0, 0},	/* NC_x16ss */
+		{2, 0, 2, 0},	/* x8ss_x16ss */
+		{2, 2, 2, 0},	/* x8ds_x16ss */
+		{2, 0, 2, 0},	/* x16ss_x16ss */
+	};
+
+	printk(BIOS_DEBUG, "MRS...\n");
+
+	ddr3_freq = s->selected_timings.mem_clk - MEM_CLOCK_800MHz;
+	FOR_EACH_POPULATED_RANK(s->dimms, ch, r) {
+		printk(BIOS_DEBUG, "CH%d: Found Rank %d\n", ch, r);
+		send_jedec_cmd(s, r + ch * 4, ch, NOP_CMD, 0);
+		udelay(200);
+		dimmconfig = s->dimm_config[ch];
+		cmd = ddr3_freq << 3; /* actually twl - 5 which is same */
+		cmd |= ddr3_emrs2_config[dimmconfig][r] << 9;
+		send_jedec_cmd(s, r + ch * 4, ch, EMRS2_CMD, cmd);
+		send_jedec_cmd(s, r + ch * 4, ch, EMRS3_CMD, 0);
+		cmd = ddr3_emrs1_config[dimmconfig][r] << 2;
+		cmd |= (1 << 1);
+		send_jedec_cmd(s, r + ch * 4, ch, EMRS1_CMD, cmd);
+		send_jedec_cmd(s, r + ch *  4, ch, MRS_CMD, (1 << 3) | (1 << 8)
+			| (1 << 12) | ((s->selected_timings.CAS - 4) << 4)
+			| ((s->selected_timings.tWR - 4) << 9));
+		send_jedec_cmd(s, r + ch * 4, ch, ZQCAL_CMD, (1 << 10));
+	}
+	printk(BIOS_DEBUG, "MRS done\n");
+}
 static u8 sampledqs(u16 mchloc, u32 addr, u8 hilow, u8 repeat)
 {
 	u8 dqsmatch = 1;
@@ -2163,9 +2225,12 @@
 	MCHBAR16(0x212) = (MCHBAR16(0x212) & ~0xf00) | 0xf00;
 	printk(BIOS_DEBUG, "Done pre-jedec\n");
 
-	// JEDEC reset
-	if (s->boot_path != BOOT_PATH_RESUME)
-		jedec_ddr2(s);
+	if (s->boot_path != BOOT_PATH_RESUME) {
+		if (s->spd_type == DDR2)
+			jedec_ddr2(s);
+		else
+			jedec_ddr3(s);
+	}
 
 	printk(BIOS_DEBUG, "Done jedec steps\n");
 
diff --git a/src/northbridge/intel/x4x/spd_ddr3_decode.c b/src/northbridge/intel/x4x/spd_ddr3_decode.c
index fd69fd4..eab0548 100644
--- a/src/northbridge/intel/x4x/spd_ddr3_decode.c
+++ b/src/northbridge/intel/x4x/spd_ddr3_decode.c
@@ -152,6 +152,8 @@
 	s->dimms[dimm_idx].rows = decoded_dimm.row_bits;
 	s->dimms[dimm_idx].cols = decoded_dimm.col_bits;
 
+	s->dimms[dimm_idx].mirrorred = decoded_dimm.flags.pins_mirrored;
+
 	saved_timings->min_tRAS =
 		MAX(saved_timings->min_tRAS, decoded_dimm.tRAS);
 	saved_timings->min_tRP =
diff --git a/src/northbridge/intel/x4x/x4x.h b/src/northbridge/intel/x4x/x4x.h
index 9ef07b3..c2eea38 100644
--- a/src/northbridge/intel/x4x/x4x.h
+++ b/src/northbridge/intel/x4x/x4x.h
@@ -276,6 +276,7 @@
 	unsigned int	ranks;
 	unsigned int	rows;
 	unsigned int	cols;
+	u8		mirrorred;
 };
 
 /* The setup is up to two DIMMs per channel */
@@ -355,6 +356,7 @@
 			struct abs_timings *saved_timings);
 int ddr3_save_dimminfo(u8 dimm_idx, u8 *raw_spd,
 		struct abs_timings *saved_timings, struct sysinfo *s);
+void send_jedec_cmd(const struct sysinfo *s, u8 r, u8 ch, u8 cmd, u32 val);
 void dqsset(u8 ch, u8 lane, const struct dll_setting *setting);
 void dqset(u8 ch, u8 lane, const struct dll_setting *setting);
 
@@ -364,7 +366,7 @@
 extern const struct dll_setting ddr3_dll_setting_800[2][23];
 extern const struct dll_setting ddr3_dll_setting_1066[2][23];
 extern const struct dll_setting ddr3_dll_setting_1333[2][23];
-
+extern const u8 ddr3_emrs1_config[16][4];
 
 struct acpi_rsdp;
 #ifndef __SIMPLE_DEVICE__

-- 
To view, visit https://review.coreboot.org/19877
To unsubscribe, visit https://review.coreboot.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I3b5eeb0aff6764292bbcbed7274274f615066c14
Gerrit-PatchSet: 1
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Owner: Arthur Heymans <arthur at aheymans.xyz>



More information about the coreboot-gerrit mailing list