summaryrefslogtreecommitdiff
path: root/src/soc/intel/common/block/memory
diff options
context:
space:
mode:
authorAngel Pons <th3fanbus@gmail.com>2022-01-05 19:29:15 +0100
committerFelix Held <felix-coreboot@felixheld.de>2022-01-07 16:06:26 +0000
commitef5f7ee696097174f9d1f01e9b04ea8f1354cfe0 (patch)
treedb174d508c4ece7b6401d9433f96441bc62c9517 /src/soc/intel/common/block/memory
parentc921da3f0e369f2075ce0ccac03430e6568dc1fe (diff)
soc/intel/common/blk/memory: Make mixed topo work
When using a mixed memory topology with DDR4, it's not possible to boot when no DIMMs are installed, even though memory-down is available. This happens because the DIMM SPD length defaults to 256 when no DIMM SPD is available. Relax the length check when no DIMMs are present to overcome this problem. Tested on system76/lemp10. Unit boots with and without DIMM installed. Change-Id: I1cabf64fade1c06a44b6c3892659d54febc7a79a Signed-off-by: Angel Pons <th3fanbus@gmail.com> Tested-by: Tim Crawford <tcrawford@system76.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/60800 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org> Reviewed-by: Tim Crawford <tcrawford@system76.com>
Diffstat (limited to 'src/soc/intel/common/block/memory')
-rw-r--r--src/soc/intel/common/block/memory/meminit.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/src/soc/intel/common/block/memory/meminit.c b/src/soc/intel/common/block/memory/meminit.c
index 50c8b40df2..78dc2d443a 100644
--- a/src/soc/intel/common/block/memory/meminit.c
+++ b/src/soc/intel/common/block/memory/meminit.c
@@ -6,6 +6,7 @@
#include <commonlib/region.h>
#include <spd_bin.h>
#include <string.h>
+#include <types.h>
_Static_assert(CONFIG_MRC_CHANNEL_WIDTH > 0, "MRC channel width must be >0!");
_Static_assert(CONFIG_DATA_BUS_WIDTH > 0, "Data bus width must be >0!");
@@ -93,7 +94,7 @@ static void read_spd_md(const struct soc_mem_cfg *soc_mem_cfg, const struct mem_
#define CH_DIMM_OFFSET(ch, dimm) ((ch) * CONFIG_DIMMS_PER_CHANNEL + (dimm))
-static void read_spd_dimm(const struct soc_mem_cfg *soc_mem_cfg, const struct mem_spd *info,
+static bool read_spd_dimm(const struct soc_mem_cfg *soc_mem_cfg, const struct mem_spd *info,
bool half_populated, struct mem_channel_data *channel_data,
size_t *spd_len)
{
@@ -109,7 +110,7 @@ static void read_spd_dimm(const struct soc_mem_cfg *soc_mem_cfg, const struct me
uint32_t pop_mask = 0;
if (!(info->topo & MEM_TOPO_DIMM_MODULE))
- return;
+ return false;
for (ch = 0; ch < num_phys_ch; ch++) {
for (dimm = 0; dimm < CONFIG_DIMMS_PER_CHANNEL; dimm++) {
@@ -137,6 +138,8 @@ static void read_spd_dimm(const struct soc_mem_cfg *soc_mem_cfg, const struct me
}
channel_data->ch_population_flags |= populated_mask_to_flag(pop_mask, num_phys_ch);
+
+ return pop_mask != 0;
}
void mem_populate_channel_data(const struct soc_mem_cfg *soc_mem_cfg,
@@ -145,11 +148,12 @@ void mem_populate_channel_data(const struct soc_mem_cfg *soc_mem_cfg,
struct mem_channel_data *data)
{
size_t spd_md_len = 0, spd_dimm_len = 0;
+ bool have_dimms;
memset(data, 0, sizeof(*data));
read_spd_md(soc_mem_cfg, spd_info, half_populated, data, &spd_md_len);
- read_spd_dimm(soc_mem_cfg, spd_info, half_populated, data, &spd_dimm_len);
+ have_dimms = read_spd_dimm(soc_mem_cfg, spd_info, half_populated, data, &spd_dimm_len);
if (data->ch_population_flags == NO_CHANNEL_POPULATED)
die("No channels are populated. Incorrect memory configuration!\n");
@@ -161,11 +165,12 @@ void mem_populate_channel_data(const struct soc_mem_cfg *soc_mem_cfg,
} else {
/*
* SPD lengths must match for CBFS and EEPROM SPD for mixed
- * topology.
+ * topology. Skip this check when no DIMMs are installed.
*/
- if (spd_md_len != spd_dimm_len)
+ if (have_dimms && spd_md_len != spd_dimm_len)
die("Length of SPD does not match for mixed topology!\n");
+ /* Use memory-down SPD length in case there are no DIMMs installed */
data->spd_len = spd_md_len;
}
}