summaryrefslogtreecommitdiff
path: root/resources/coreboot/haswell/patches/0015-haswell-NRI-Program-memory-map.patch
diff options
context:
space:
mode:
Diffstat (limited to 'resources/coreboot/haswell/patches/0015-haswell-NRI-Program-memory-map.patch')
-rw-r--r--resources/coreboot/haswell/patches/0015-haswell-NRI-Program-memory-map.patch263
1 files changed, 0 insertions, 263 deletions
diff --git a/resources/coreboot/haswell/patches/0015-haswell-NRI-Program-memory-map.patch b/resources/coreboot/haswell/patches/0015-haswell-NRI-Program-memory-map.patch
deleted file mode 100644
index ad8527b2..00000000
--- a/resources/coreboot/haswell/patches/0015-haswell-NRI-Program-memory-map.patch
+++ /dev/null
@@ -1,263 +0,0 @@
-From 89ff35083af68d1b24c1633886202ecc153af67d Mon Sep 17 00:00:00 2001
-From: Angel Pons <th3fanbus@gmail.com>
-Date: Sat, 7 May 2022 21:24:50 +0200
-Subject: [PATCH 15/26] haswell NRI: Program memory map
-
-This is very similar to Sandy/Ivy Bridge, except that there's several
-registers to program in GDXCBAR. One of these GDXCBAR registers has a
-lock bit that must be set in order for the memory controller to allow
-normal access to DRAM. And it took me four months to realize this one
-bit was the only reason why native raminit did not work.
-
-Change-Id: I3af73a018a7ba948701a542e661e7fefd57591fe
-Signed-off-by: Angel Pons <th3fanbus@gmail.com>
----
- .../intel/haswell/native_raminit/Makefile.inc | 1 +
- .../intel/haswell/native_raminit/memory_map.c | 183 ++++++++++++++++++
- .../haswell/native_raminit/raminit_main.c | 1 +
- .../haswell/native_raminit/raminit_native.h | 1 +
- .../intel/haswell/registers/host_bridge.h | 2 +
- 5 files changed, 188 insertions(+)
- create mode 100644 src/northbridge/intel/haswell/native_raminit/memory_map.c
-
-diff --git a/src/northbridge/intel/haswell/native_raminit/Makefile.inc b/src/northbridge/intel/haswell/native_raminit/Makefile.inc
-index fc55277a65..37d527e972 100644
---- a/src/northbridge/intel/haswell/native_raminit/Makefile.inc
-+++ b/src/northbridge/intel/haswell/native_raminit/Makefile.inc
-@@ -4,6 +4,7 @@ romstage-y += configure_mc.c
- romstage-y += lookup_timings.c
- romstage-y += init_mpll.c
- romstage-y += io_comp_control.c
-+romstage-y += memory_map.c
- romstage-y += raminit_main.c
- romstage-y += raminit_native.c
- romstage-y += spd_bitmunching.c
-diff --git a/src/northbridge/intel/haswell/native_raminit/memory_map.c b/src/northbridge/intel/haswell/native_raminit/memory_map.c
-new file mode 100644
-index 0000000000..e3aded2b37
---- /dev/null
-+++ b/src/northbridge/intel/haswell/native_raminit/memory_map.c
-@@ -0,0 +1,183 @@
-+/* SPDX-License-Identifier: GPL-2.0-or-later */
-+
-+#include <device/pci_ops.h>
-+#include <northbridge/intel/haswell/haswell.h>
-+#include <southbridge/intel/lynxpoint/me.h>
-+#include <types.h>
-+
-+#include "raminit_native.h"
-+
-+/* GDXCBAR */
-+#define MPCOHTRK_GDXC_MOT_ADDRESS_LO 0x10
-+#define MPCOHTRK_GDXC_MOT_ADDRESS_HI 0x14
-+#define MPCOHTRK_GDXC_MOT_REGION 0x18
-+
-+#define MPCOHTRK_GDXC_OCLA_ADDRESS_LO 0x20
-+#define MPCOHTRK_GDXC_OCLA_ADDRESS_HI 0x24
-+#define MPCOHTRK_GDXC_OCLA_REGION 0x28
-+
-+/* This lock bit made me lose what little sanity I had left. - Angel Pons */
-+#define MPCOHTRK_GDXC_OCLA_ADDRESS_HI_LOCK BIT(2)
-+
-+static inline uint32_t gdxcbar_read32(const uintptr_t offset)
-+{
-+ return read32p((mchbar_read32(GDXCBAR) & ~1) + offset);
-+}
-+
-+static inline void gdxcbar_write32(const uintptr_t offset, const uint32_t value)
-+{
-+ write32p((mchbar_read32(GDXCBAR) & ~1) + offset, value);
-+}
-+
-+static inline void gdxcbar_clrsetbits32(const uintptr_t offset, uint32_t clear, uint32_t set)
-+{
-+ const uintptr_t address = (mchbar_read32(GDXCBAR) & ~1) + offset;
-+ clrsetbits32((void *)address, clear, set);
-+}
-+
-+#define gdxcbar_setbits32(offset, set) gdxcbar_clrsetbits32(offset, 0, set)
-+#define gdxcbar_clrbits32(offset, clear) gdxcbar_clrsetbits32(offset, clear, 0)
-+
-+/* All values stored in here (except the bool) are specified in MiB */
-+struct memory_map_data {
-+ uint32_t dpr_size;
-+ uint32_t tseg_size;
-+ uint32_t gtt_size;
-+ uint32_t gms_size;
-+ uint32_t me_stolen_size;
-+ uint32_t mmio_size;
-+ uint32_t touud;
-+ uint32_t remaplimit;
-+ uint32_t remapbase;
-+ uint32_t tom;
-+ uint32_t tom_minus_me;
-+ uint32_t tolud;
-+ uint32_t bdsm_base;
-+ uint32_t gtt_base;
-+ uint32_t tseg_base;
-+ bool reclaim_possible;
-+};
-+
-+static void compute_memory_map(struct memory_map_data *map)
-+{
-+ map->tom_minus_me = map->tom - map->me_stolen_size;
-+
-+ /*
-+ * MMIO size will actually be slightly smaller than computed,
-+ * but matches what MRC does and is more MTRR-friendly given
-+ * that TSEG is treated as WB, but SMRR makes TSEG UC anyway.
-+ */
-+ const uint32_t mmio_size = MIN(map->tom_minus_me, 4096) / 2;
-+ map->gtt_base = ALIGN_DOWN(mmio_size, map->tseg_size);
-+ map->tseg_base = map->gtt_base - map->tseg_size;
-+ map->bdsm_base = map->gtt_base + map->gtt_size;
-+ map->tolud = map->bdsm_base + map->gms_size;
-+ map->reclaim_possible = map->tom_minus_me > map->tolud;
-+
-+ if (map->reclaim_possible) {
-+ map->remapbase = MAX(4096, map->tom_minus_me);
-+ map->touud = MIN(4096, map->tom_minus_me) + map->remapbase - map->tolud;
-+ map->remaplimit = map->touud - 1;
-+ } else {
-+ map->remapbase = 0;
-+ map->remaplimit = 0;
-+ map->touud = map->tom_minus_me;
-+ }
-+}
-+
-+static void display_memory_map(const struct memory_map_data *map)
-+{
-+ if (!CONFIG(DEBUG_RAM_SETUP))
-+ return;
-+
-+ printk(BIOS_DEBUG, "============ MEMORY MAP ============\n");
-+ printk(BIOS_DEBUG, "\n");
-+ printk(BIOS_DEBUG, "dpr_size = %u MiB\n", map->dpr_size);
-+ printk(BIOS_DEBUG, "tseg_size = %u MiB\n", map->tseg_size);
-+ printk(BIOS_DEBUG, "gtt_size = %u MiB\n", map->gtt_size);
-+ printk(BIOS_DEBUG, "gms_size = %u MiB\n", map->gms_size);
-+ printk(BIOS_DEBUG, "me_stolen_size = %u MiB\n", map->me_stolen_size);
-+ printk(BIOS_DEBUG, "\n");
-+ printk(BIOS_DEBUG, "touud = %u MiB\n", map->touud);
-+ printk(BIOS_DEBUG, "remaplimit = %u MiB\n", map->remaplimit);
-+ printk(BIOS_DEBUG, "remapbase = %u MiB\n", map->remapbase);
-+ printk(BIOS_DEBUG, "tom = %u MiB\n", map->tom);
-+ printk(BIOS_DEBUG, "tom_minus_me = %u MiB\n", map->tom_minus_me);
-+ printk(BIOS_DEBUG, "tolud = %u MiB\n", map->tolud);
-+ printk(BIOS_DEBUG, "bdsm_base = %u MiB\n", map->bdsm_base);
-+ printk(BIOS_DEBUG, "gtt_base = %u MiB\n", map->gtt_base);
-+ printk(BIOS_DEBUG, "tseg_base = %u MiB\n", map->tseg_base);
-+ printk(BIOS_DEBUG, "\n");
-+ printk(BIOS_DEBUG, "reclaim_possible = %s\n", map->reclaim_possible ? "Yes" : "No");
-+}
-+
-+static void map_write_reg64(const uint16_t reg, const uint64_t size)
-+{
-+ const uint64_t value = size << 20;
-+ pci_write_config32(HOST_BRIDGE, reg + 4, value >> 32);
-+ pci_write_config32(HOST_BRIDGE, reg + 0, value >> 0);
-+}
-+
-+static void map_write_reg32(const uint16_t reg, const uint32_t size)
-+{
-+ const uint32_t value = size << 20;
-+ pci_write_config32(HOST_BRIDGE, reg, value);
-+}
-+
-+static void program_memory_map(const struct memory_map_data *map)
-+{
-+ map_write_reg64(TOUUD, map->touud);
-+ map_write_reg64(TOM, map->tom);
-+ if (map->reclaim_possible) {
-+ map_write_reg64(REMAPBASE, map->remapbase);
-+ map_write_reg64(REMAPLIMIT, map->remaplimit);
-+ }
-+ if (map->me_stolen_size) {
-+ map_write_reg64(MESEG_LIMIT, 0x80000 - map->me_stolen_size);
-+ map_write_reg64(MESEG_BASE, map->tom_minus_me);
-+ pci_or_config32(HOST_BRIDGE, MESEG_LIMIT, ME_STLEN_EN);
-+ }
-+ map_write_reg32(TOLUD, map->tolud);
-+ map_write_reg32(BDSM, map->bdsm_base);
-+ map_write_reg32(BGSM, map->gtt_base);
-+ map_write_reg32(TSEG, map->tseg_base);
-+
-+ const uint32_t dpr_reg = map->tseg_base << 20 | map->dpr_size << 4;
-+ pci_write_config32(HOST_BRIDGE, DPR, dpr_reg);
-+
-+ const uint16_t gfx_stolen_size = GGC_IGD_MEM_IN_32MB_UNITS(map->gms_size / 32);
-+ const uint16_t ggc = map->gtt_size << 8 | gfx_stolen_size;
-+ pci_write_config16(HOST_BRIDGE, GGC, ggc);
-+
-+ /** TODO: Do not hardcode these? GDXC has weird alignment requirements, though. **/
-+ gdxcbar_write32(MPCOHTRK_GDXC_MOT_ADDRESS_LO, 0);
-+ gdxcbar_write32(MPCOHTRK_GDXC_MOT_ADDRESS_HI, 0);
-+ gdxcbar_write32(MPCOHTRK_GDXC_MOT_REGION, 0);
-+
-+ gdxcbar_write32(MPCOHTRK_GDXC_OCLA_ADDRESS_LO, 0);
-+ gdxcbar_write32(MPCOHTRK_GDXC_OCLA_ADDRESS_HI, 0);
-+ gdxcbar_write32(MPCOHTRK_GDXC_OCLA_REGION, 0);
-+
-+ gdxcbar_setbits32(MPCOHTRK_GDXC_OCLA_ADDRESS_HI, MPCOHTRK_GDXC_OCLA_ADDRESS_HI_LOCK);
-+}
-+
-+enum raminit_status configure_memory_map(struct sysinfo *ctrl)
-+{
-+ struct memory_map_data memory_map = {
-+ .tom = ctrl->channel_size_mb[0] + ctrl->channel_size_mb[1],
-+ .dpr_size = CONFIG_INTEL_TXT_DPR_SIZE,
-+ .tseg_size = CONFIG_SMM_TSEG_SIZE >> 20,
-+ .me_stolen_size = intel_early_me_uma_size(),
-+ };
-+ /** FIXME: MRC hardcodes iGPU parameters, but we should not **/
-+ const bool igpu_on = pci_read_config32(HOST_BRIDGE, DEVEN) & DEVEN_D2EN;
-+ if (CONFIG(ONBOARD_VGA_IS_PRIMARY) || igpu_on) {
-+ memory_map.gtt_size = 2;
-+ memory_map.gms_size = 64;
-+ pci_or_config32(HOST_BRIDGE, DEVEN, DEVEN_D2EN);
-+ }
-+ compute_memory_map(&memory_map);
-+ display_memory_map(&memory_map);
-+ program_memory_map(&memory_map);
-+ return 0;
-+}
-diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_main.c b/src/northbridge/intel/haswell/native_raminit/raminit_main.c
-index 3a773cfa19..136a8ba989 100644
---- a/src/northbridge/intel/haswell/native_raminit/raminit_main.c
-+++ b/src/northbridge/intel/haswell/native_raminit/raminit_main.c
-@@ -24,6 +24,7 @@ static const struct task_entry cold_boot[] = {
- { initialise_mpll, true, "INITMPLL", },
- { convert_timings, true, "CONVTIM", },
- { configure_mc, true, "CONFMC", },
-+ { configure_memory_map, true, "MEMMAP", },
- };
-
- /* Return a generic stepping value to make stepping checks simpler */
-diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_native.h b/src/northbridge/intel/haswell/native_raminit/raminit_native.h
-index cd1f2eb2a5..4763b25e8d 100644
---- a/src/northbridge/intel/haswell/native_raminit/raminit_native.h
-+++ b/src/northbridge/intel/haswell/native_raminit/raminit_native.h
-@@ -202,6 +202,7 @@ enum raminit_status collect_spd_info(struct sysinfo *ctrl);
- enum raminit_status initialise_mpll(struct sysinfo *ctrl);
- enum raminit_status convert_timings(struct sysinfo *ctrl);
- enum raminit_status configure_mc(struct sysinfo *ctrl);
-+enum raminit_status configure_memory_map(struct sysinfo *ctrl);
-
- void configure_timings(struct sysinfo *ctrl);
- void configure_refresh(struct sysinfo *ctrl);
-diff --git a/src/northbridge/intel/haswell/registers/host_bridge.h b/src/northbridge/intel/haswell/registers/host_bridge.h
-index 1ee0ab2890..0228cf6bb9 100644
---- a/src/northbridge/intel/haswell/registers/host_bridge.h
-+++ b/src/northbridge/intel/haswell/registers/host_bridge.h
-@@ -34,6 +34,8 @@
-
- #define MESEG_BASE 0x70 /* Management Engine Base */
- #define MESEG_LIMIT 0x78 /* Management Engine Limit */
-+#define MELCK (1 << 10) /* ME Range Lock */
-+#define ME_STLEN_EN (1 << 11) /* ME Stolen Memory Enable */
-
- #define PAM0 0x80
- #define PAM1 0x81
---
-2.39.2
-