[coreboot-gerrit] New patch to review for coreboot: a820cb3 gm45: Decrease MTRR usage

Vladimir Serbinenko (phcoder@gmail.com) gerrit at coreboot.org
Sat Aug 16 14:09:24 CEST 2014


Vladimir Serbinenko (phcoder at gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/6687

-gerrit

commit a820cb3f315ad429fca9bd548c3e44b142f300d5
Author: Vladimir Serbinenko <phcoder at gmail.com>
Date:   Sat Aug 16 10:59:02 2014 +0200

    gm45: Decrease MTRR usage
    
    Change-Id: I4c790b0eaf2af94286e6691281fcad3d14659a99
    Signed-off-by: Vladimir Serbinenko <phcoder at gmail.com>
---
 src/mainboard/lenovo/x200/romstage.c     |  5 ++--
 src/mainboard/roda/rk9/romstage.c        |  5 ++--
 src/northbridge/intel/gm45/gm45.h        |  6 ++++-
 src/northbridge/intel/gm45/igd.c         | 43 +++++++++++++++++++-------------
 src/northbridge/intel/gm45/northbridge.c | 10 +++++---
 src/northbridge/intel/gm45/raminit.c     | 35 +++++++++++++++++++++++---
 6 files changed, 75 insertions(+), 29 deletions(-)

diff --git a/src/mainboard/lenovo/x200/romstage.c b/src/mainboard/lenovo/x200/romstage.c
index 816fde4..dcb4e16 100644
--- a/src/mainboard/lenovo/x200/romstage.c
+++ b/src/mainboard/lenovo/x200/romstage.c
@@ -126,13 +126,14 @@ void main(unsigned long bist)
 
 	/* RAM initialization */
 	enter_raminit_or_reset();
+	memset(&sysinfo, 0, sizeof(sysinfo));
 	sysinfo.spd_map[0] = 0x50;
 	sysinfo.spd_map[2] = 0x51;
+	sysinfo.enable_igd = 1;
+	sysinfo.enable_peg = 0;
 	get_gmch_info(&sysinfo);
 	raminit(&sysinfo, s3resume);
 
-	raminit_thermal(&sysinfo);
-	init_igd(&sysinfo, 0, 1); /* Enable IGD, disable PEG. */
 	const u32 deven = pci_read_config32(MCH_DEV, D0F0_DEVEN);
 	/* Disable D4F0 (unknown signal controller). */
 	pci_write_config32(MCH_DEV, D0F0_DEVEN, deven & ~0x4000);
diff --git a/src/mainboard/roda/rk9/romstage.c b/src/mainboard/roda/rk9/romstage.c
index 405d75e..c8b75e0 100644
--- a/src/mainboard/roda/rk9/romstage.c
+++ b/src/mainboard/roda/rk9/romstage.c
@@ -171,15 +171,16 @@ void main(unsigned long bist)
 
 	/* RAM initialization */
 	enter_raminit_or_reset();
+	memset(&sysinfo, 0, sizeof(sysinfo));
 	get_gmch_info(&sysinfo);
 	sysinfo.spd_map[0] = 0x50;
 	sysinfo.spd_map[1] = 0;
 	sysinfo.spd_map[2] = 0x52;
 	sysinfo.spd_map[3] = 0;
+	sysinfo.enable_igd = 1;
+	sysinfo.enable_peg = 0;
 	raminit(&sysinfo, s3resume);
 
-	raminit_thermal(&sysinfo);
-	init_igd(&sysinfo, 0, 1); /* Enable IGD, disable PEG. */
 	init_pm(&sysinfo, 1);
 
 	i82801ix_dmi_setup();
diff --git a/src/northbridge/intel/gm45/gm45.h b/src/northbridge/intel/gm45/gm45.h
index db64d86..d93b6e4 100644
--- a/src/northbridge/intel/gm45/gm45.h
+++ b/src/northbridge/intel/gm45/gm45.h
@@ -139,6 +139,9 @@ typedef struct {
 	fsb_clock_t	max_fsb;
 	int		max_fsb_mhz;
 	int		max_render_mhz;
+	int		enable_igd;
+	int		enable_peg;
+	u16		ggc;
 
 	int		spd_type;
 	timings_t	selected_timings;
@@ -407,8 +410,9 @@ void enter_raminit_or_reset(void);
 void get_gmch_info(sysinfo_t *);
 void raminit(sysinfo_t *, int s3resume);
 void raminit_thermal(const sysinfo_t *);
-void init_igd(const sysinfo_t *, int no_igd, int no_peg);
+void init_igd(const sysinfo_t *const);
 void init_pm(const sysinfo_t *, int do_freq_scaling_cfg);
+void igd_compute_ggc(sysinfo_t *const sysinfo);
 
 int raminit_read_vco_index(void);
 u32 raminit_get_rank_addr(unsigned int channel, unsigned int rank);
diff --git a/src/northbridge/intel/gm45/igd.c b/src/northbridge/intel/gm45/igd.c
index 786919f..b7847c0 100644
--- a/src/northbridge/intel/gm45/igd.c
+++ b/src/northbridge/intel/gm45/igd.c
@@ -41,7 +41,6 @@ static void enable_igd(const sysinfo_t *const sysinfo, const int no_peg)
 
 	u16 reg16;
 	u32 reg32;
-	u8 gfxsize;
 
 	printk(BIOS_DEBUG, "Enabling IGD.\n");
 
@@ -61,20 +60,9 @@ static void enable_igd(const sysinfo_t *const sysinfo, const int no_peg)
 	reg16 |= display_clock_from_f0_and_vco[f0_12][vco];
 	pci_write_config16(igd_dev, 0xcc, reg16);
 
-	/* Graphics Stolen Memory: 2MB GTT (0x0300) when VT-d disabled,
-	                           2MB GTT + 2MB shadow GTT (0x0b00) else. */
-	const u32 capid = pci_read_config32(mch_dev, D0F0_CAPID0 + 4);
 	reg16 = pci_read_config16(mch_dev, D0F0_GGC);
-
-	if (get_option(&gfxsize, "gfx_uma_size") != CB_SUCCESS) {
-		/* 0 for 32MB */
-		gfxsize = 0;
-	}
-
 	reg16 &= 0xf00f;
-	reg16 |= 0x0300 | ((gfxsize + 5) << 4);
-	if (!(capid & (1 << (48 - 32))))
-		reg16 |= 0x0800;
+	reg16 |= sysinfo->ggc;
 	pci_write_config16(mch_dev, D0F0_GGC, reg16);
 
 	if ((sysinfo->gfx_type != GMCH_GL40) &&
@@ -146,14 +134,35 @@ static void disable_igd(const sysinfo_t *const sysinfo)
 	}
 }
 
-void init_igd(const sysinfo_t *const sysinfo,
-	      const int no_igd, const int no_peg)
+void init_igd(const sysinfo_t *const sysinfo)
 {
 	const device_t mch_dev	= PCI_DEV(0, 0, 0);
 
 	const u8 capid = pci_read_config8(mch_dev, D0F0_CAPID0 + 4);
-	if (no_igd || (capid & (1 << (33 - 32))))
+	if (!sysinfo->enable_igd || (capid & (1 << (33 - 32))))
 		disable_igd(sysinfo);
 	else
-		enable_igd(sysinfo, no_peg);
+		enable_igd(sysinfo, !sysinfo->enable_peg);
+}
+
+void igd_compute_ggc(sysinfo_t *const sysinfo)
+{
+	const device_t mch_dev	= PCI_DEV(0, 0, 0);
+
+	const u32 capid = pci_read_config32(mch_dev, D0F0_CAPID0 + 4);
+	if (!sysinfo->enable_igd || (capid & (1 << (33 - 32))))
+		sysinfo->ggc = 0x0002;
+	else {
+		u8 gfxsize;
+
+		/* Graphics Stolen Memory: 2MB GTT (0x0300) when VT-d disabled,
+		   2MB GTT + 2MB shadow GTT (0x0b00) else. */
+		if (get_option(&gfxsize, "gfx_uma_size") != CB_SUCCESS) {
+			/* 0 for 32MB */
+			gfxsize = 0;
+		}
+		sysinfo->ggc = 0x0300 | ((gfxsize + 5) << 4);
+		if (!(capid & (1 << (48 - 32))))
+			sysinfo->ggc |= 0x0800;
+	}
 }
diff --git a/src/northbridge/intel/gm45/northbridge.c b/src/northbridge/intel/gm45/northbridge.c
index 11ca6f4..42561e4 100644
--- a/src/northbridge/intel/gm45/northbridge.c
+++ b/src/northbridge/intel/gm45/northbridge.c
@@ -78,7 +78,7 @@ static int decode_pcie_bar(u32 *const base, u32 *const len)
 static void mch_domain_read_resources(device_t dev)
 {
 	u64 tom, touud;
-	u32 tomk, tolud, uma_sizek = 0;
+	u32 tomk, tolud, uma_sizek = 0, usable_tomk;
 	u32 pcie_config_base, pcie_config_size;
 
 	/* Total Memory 2GB example:
@@ -137,12 +137,16 @@ static void mch_domain_read_resources(device_t dev)
 		uma_sizek = gms_sizek + gsm_sizek;
 	}
 
-	printk(BIOS_INFO, "Available memory below 4GB: %uM\n", tomk >> 10);
+	usable_tomk = ALIGN_DOWN(tomk, 64 << 10);
+	if (tomk - usable_tomk > (16 << 10))
+		usable_tomk = tomk;
+
+	printk(BIOS_INFO, "Available memory below 4GB: %uM\n", usable_tomk >> 10);
 
 	/* Report the memory regions */
 	ram_resource(dev, 3, 0, legacy_hole_base_k);
 	ram_resource(dev, 4, legacy_hole_base_k + legacy_hole_size_k,
-	     (tomk - (legacy_hole_base_k + legacy_hole_size_k)));
+		     (usable_tomk - (legacy_hole_base_k + legacy_hole_size_k)));
 
 	/*
 	 * If >= 4GB installed then memory from TOLUD to 4GB
diff --git a/src/northbridge/intel/gm45/raminit.c b/src/northbridge/intel/gm45/raminit.c
index 2d92651..60b05bd 100644
--- a/src/northbridge/intel/gm45/raminit.c
+++ b/src/northbridge/intel/gm45/raminit.c
@@ -1163,7 +1163,7 @@ static void vc1_program_timings(const fsb_clock_t fsb)
 }
 
 /* @prejedec if not zero, set rank size to 128MB and page size to 4KB. */
-static void program_memory_map(const dimminfo_t *const dimms, const channel_mode_t mode, const int prejedec)
+static void program_memory_map(const dimminfo_t *const dimms, const channel_mode_t mode, const int prejedec, u16 ggc)
 {
 	int ch, r;
 
@@ -1210,7 +1210,29 @@ static void program_memory_map(const dimminfo_t *const dimms, const channel_mode
 	}
 
 	/* Calculate memory mapping, all values in MB. */
-	const unsigned int MMIOstart = 0x0c00; /* 3GB, makes MTRR configuration small. */
+
+	u32 uma_sizem = 0;
+	if (!prejedec) {
+		if (!(ggc & 2)) {
+			printk(BIOS_DEBUG, "IGD decoded, subtracting ");
+
+			/* Graphics memory */
+			const u32 gms_sizek = decode_igd_memory_size((ggc >> 4) & 0xf);
+			printk(BIOS_DEBUG, "%uM UMA", gms_sizek >> 10);
+
+			/* GTT Graphics Stolen Memory Size (GGMS) */
+			const u32 gsm_sizek = decode_igd_gtt_size((ggc >> 8) & 0xf);
+			printk(BIOS_DEBUG, " and %uM GTT\n", gsm_sizek >> 10);
+
+			uma_sizem = (gms_sizek + gsm_sizek) >> 10;
+			/* Further reduce MTRR usage if it costs use less than
+			   16 MiB.  */
+			if (ALIGN_UP(uma_sizem, 64) - uma_sizem <= 16)
+				uma_sizem = ALIGN_UP(uma_sizem, 64);
+		}
+	}
+
+	const unsigned int MMIOstart = 0x0c00 + uma_sizem; /* 3GB, makes MTRR configuration small. */
 	const int me_active = pci_read_config8(PCI_DEV(0, 3, 0), PCI_CLASS_REVISION) != 0xff;
 	const unsigned int ME_SIZE = prejedec || !me_active ? 0 : 32;
 	const unsigned int usedMEsize = (total_mb[0] != total_mb[1]) ? ME_SIZE : 2 * ME_SIZE;
@@ -1278,7 +1300,7 @@ static void prejedec_memory_map(const dimminfo_t *const dimms, channel_mode_t mo
 	if (CHANNEL_MODE_DUAL_INTERLEAVED == mode)
 		mode = CHANNEL_MODE_DUAL_ASYNC;
 
-	program_memory_map(dimms, mode, 1);
+	program_memory_map(dimms, mode, 1, 0);
 	MCHBAR32(DCC_MCHBAR) |= DCC_NO_CHANXOR;
 }
 
@@ -1773,8 +1795,10 @@ void raminit(sysinfo_t *const sysinfo, const int s3resume)
 		raminit_write_training(timings->mem_clock, dimms, s3resume);
 	}
 
+	igd_compute_ggc(sysinfo);
+
 	/* Program final memory map (with real values). */
-	program_memory_map(dimms, timings->channel_mode, 0);
+	program_memory_map(dimms, timings->channel_mode, 0, sysinfo->ggc);
 
 	/* Some last optimizations. */
 	dram_optimizations(timings, dimms);
@@ -1782,4 +1806,7 @@ void raminit(sysinfo_t *const sysinfo, const int s3resume)
 	/* Mark raminit beeing finished. :-) */
 	u8 tmp8 = pci_read_config8(PCI_DEV(0, 0x1f, 0), 0xa2) & ~(1 << 7);
 	pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xa2, tmp8);
+
+	raminit_thermal(sysinfo);
+	init_igd(sysinfo);
 }



More information about the coreboot-gerrit mailing list