From 56ae8a0b0faf1ca009e977dbd05cd9f0ea3fc2eb Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Sat, 16 Aug 2014 10:59:02 +0200 Subject: [PATCH] gm45: Decrease MTRR usage Change-Id: I4c790b0eaf2af94286e6691281fcad3d14659a99 Signed-off-by: Vladimir Serbinenko Reviewed-on: http://review.coreboot.org/6687 Tested-by: build bot (Jenkins) Reviewed-by: Edward O'Callaghan --- 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 816fde4222..dcb4e16415 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 405d75e848..c8b75e0ed0 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 db64d867f2..d93b6e4a4e 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 786919f08b..b7847c05fc 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 11ca6f49d8..42561e4d5d 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 2d92651b4b..60b05bdcb3 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); }