[coreboot-gerrit] Change in coreboot[master]: nb/intel/x4x: Add the option for stacked channel map settings

Arthur Heymans (Code Review) gerrit at coreboot.org
Sat May 26 15:09:42 CEST 2018


Arthur Heymans has uploaded this change for review. ( https://review.coreboot.org/26563


Change subject: nb/intel/x4x: Add the option for stacked channel map settings
......................................................................

nb/intel/x4x: Add the option for stacked channel map settings

There seems to be a hardware bug where the combination of non-stacked
channel settings, both channels populated and 533MHz dram speed cause
the display to be unusable.

The code to actually select stacked mode based on hardware
configuration will be add in a followup patch.

This patch does the following:
* Add option to the sysinfo struct for stacked mode
* Fix programming channel 1 DRB which needs special care for the last
  populated rank in stacked mode

TESTED on Intel dg41wv (with stacked mode hardcoded and dram at 533MHz)

Change-Id: I95965bfea129b37f64163159fefa1c8f16331b62
Signed-off-by: Arthur Heymans <arthur at aheymans.xyz>
---
M src/northbridge/intel/x4x/raminit_ddr23.c
M src/northbridge/intel/x4x/x4x.h
2 files changed, 37 insertions(+), 13 deletions(-)



  git pull ssh://review.coreboot.org:29418/coreboot refs/changes/63/26563/1

diff --git a/src/northbridge/intel/x4x/raminit_ddr23.c b/src/northbridge/intel/x4x/raminit_ddr23.c
index 4dbee32..6bf356f 100644
--- a/src/northbridge/intel/x4x/raminit_ddr23.c
+++ b/src/northbridge/intel/x4x/raminit_ddr23.c
@@ -1320,10 +1320,8 @@
 	MCHBAR16(C1DRB0) = 0x0002;
 	MCHBAR16(C1DRB1) = 0x0004;
 	MCHBAR16(C1DRB2) = 0x0006;
-	/*
-	 * For some reason the boundary needs to be 0x10 instead of 0x8 here.
-	 * Vendor does this too...
-	 */
+	/* In stacked mode the last present rank on ch1 needs to have its
+	 * size doubled in c1drbx */
 	MCHBAR16(C1DRB3) = 0x0010;
 	MCHBAR8(0x111) = MCHBAR8(0x111) | STACKED_MEM;
 	MCHBAR32(0x104) = 0;
@@ -1550,7 +1548,7 @@
 
 static void set_dradrb(struct sysinfo *s)
 {
-	u8 map, i, ch, r, rankpop0, rankpop1;
+	u8 map, i, ch, r, rankpop0, rankpop1, lastrank_ch1;
 	u32 c0dra = 0;
 	u32 c1dra = 0;
 	u32 c0drb = 0;
@@ -1632,6 +1630,7 @@
 		MCHBAR8(0x660) = MCHBAR8(0x660) | 1;
 
 	// DRB
+	lastrank_ch1 = 0;
 	FOR_EACH_RANK(ch, r) {
 		if (ch == 0) {
 			if (RANK_IS_POPULATED(s->dimms, ch, r)) {
@@ -1641,6 +1640,7 @@
 			MCHBAR16(0x200 + 2*r) = c0drb;
 		} else {
 			if (RANK_IS_POPULATED(s->dimms, ch, r)) {
+				lastrank_ch1 = r;
 				dra1 = (c1dra >> (8*r)) & 0x7f;
 				c1drb = (u16)(c1drb + drbtab[dra1]);
 			}
@@ -1650,6 +1650,14 @@
 
 	s->channel_capacity[0] = c0drb << 6;
 	s->channel_capacity[1] = c1drb << 6;
+
+	/* In stacked mode the last present rank on ch1 needs to have its
+	 * size doubled in c1drbx */
+	if (s->stacked_mode) {
+		for (r = lastrank_ch1; r < 4; r++)
+			MCHBAR16(0x600 + 2*r) = 2 * c1drb;
+	}
+
 	totalmemorymb = s->channel_capacity[0] + s->channel_capacity[1];
 	printk(BIOS_DEBUG, "Total memory: %d + %d = %dMiB\n",
 		s->channel_capacity[0], s->channel_capacity[1], totalmemorymb);
@@ -1659,8 +1667,12 @@
 	size_ch1 = s->channel_capacity[1];
 	size_me = ME_UMA_SIZEMB;
 
-	MCHBAR8(0x111) = MCHBAR8(0x111) & ~0x2;
-	MCHBAR8(0x111) = MCHBAR8(0x111) | (1 << 4);
+	if (s->stacked_mode) {
+		MCHBAR8(0x111) = MCHBAR8(0x111) | STACKED_MEM;
+	} else {
+		MCHBAR8(0x111) = MCHBAR8(0x111) & ~STACKED_MEM;
+		MCHBAR8(0x111) = MCHBAR8(0x111) | (1 << 4);
+	}
 
 	if (size_me == 0) {
 		dual_channel_size = MIN(size_ch0, size_ch1) * 2;
@@ -1677,6 +1689,9 @@
 		}
 		dual_channel_size = MIN(size_ch0 - size_me, size_ch1) * 2;
 	}
+
+	if (s->stacked_mode)
+		dual_channel_size = 0;
 	MCHBAR16(0x104) = dual_channel_size;
 	single_channel_size = size_ch0 + size_ch1 - dual_channel_size;
 	MCHBAR16(0x102) = single_channel_size;
@@ -1693,11 +1708,13 @@
 		map |= 0x18;
 	/* Enable flex mode, we hardcode this everywhere */
 	if (size_me == 0) {
-		map |= 0x04;
-		if (size_ch0 <= size_ch1)
-			map |= 0x01;
+		if (!(s->stacked_mode && size_ch0 != 0 && size_ch1 != 0)) {
+			map |= 0x04;
+			if (size_ch0 <= size_ch1)
+				map |= 0x01;
+		}
 	} else {
-		if (size_ch0 - size_me < size_ch1)
+		if (s->stacked_mode == 0 && size_ch0 - size_me < size_ch1)
 			map |= 0x04;
 	}
 
@@ -1712,13 +1729,17 @@
 	 * channel size on ch0.
 	 */
 	if (size_me == 0) {
-		if (size_ch0 > size_ch1)
+		if (s->stacked_mode && size_ch1 != 0)
+			single_channel_offset = 0;
+		else if (size_ch0 > size_ch1)
 			single_channel_offset = dual_channel_size / 2
 				+ single_channel_size;
 		else
 			single_channel_offset = dual_channel_size / 2;
 	} else {
-		if ((size_ch0 > size_ch1) && ((map & 0x7) == 4))
+		if (s->stacked_mode && size_ch1 != 0)
+			single_channel_offset = 0;
+		else if ((size_ch0 > size_ch1) && ((map & 0x7) == 4))
 			single_channel_offset = dual_channel_size / 2
 				+ single_channel_size;
 		else
diff --git a/src/northbridge/intel/x4x/x4x.h b/src/northbridge/intel/x4x/x4x.h
index 95f618d..ffbed2e 100644
--- a/src/northbridge/intel/x4x/x4x.h
+++ b/src/northbridge/intel/x4x/x4x.h
@@ -340,6 +340,9 @@
 	struct dll_setting dqs_settings[TOTAL_CHANNELS][TOTAL_BYTELANES];
 	struct dll_setting dq_settings[TOTAL_CHANNELS][TOTAL_BYTELANES];
 	u8		nmode;
+	/* at 533MHz memfreq the gfx device only works if channels
+	 * are put in stacked mode */
+	u8		stacked_mode;
 };
 #define BOOT_PATH_NORMAL	0
 #define BOOT_PATH_WARM_RESET	1

-- 
To view, visit https://review.coreboot.org/26563
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I95965bfea129b37f64163159fefa1c8f16331b62
Gerrit-Change-Number: 26563
Gerrit-PatchSet: 1
Gerrit-Owner: Arthur Heymans <arthur at aheymans.xyz>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.coreboot.org/pipermail/coreboot-gerrit/attachments/20180526/ff32f187/attachment.html>


More information about the coreboot-gerrit mailing list