Furquan Shaikh has uploaded this change for review. ( https://review.coreboot.org/22745
Change subject: mb/google/poppy: Add support for DDR4 memory ......................................................................
mb/google/poppy: Add support for DDR4 memory
This change updates memory SPD handling code in baseboard poppy to allow variants to define either LPDDR3 or DDR4 memory types. In addition to that, it also updates the function to print SPD info considering offsets that might be different across the two memory types.
BUG=b:70188937
Change-Id: Iefad01719c62264fb0d7e987904e77647d6026c2 Signed-off-by: Furquan Shaikh furquan@chromium.org --- M src/mainboard/google/poppy/romstage.c M src/mainboard/google/poppy/variants/baseboard/include/baseboard/variants.h M src/mainboard/google/poppy/variants/baseboard/memory.c M src/mainboard/google/poppy/variants/nautilus/memory.c 4 files changed, 82 insertions(+), 41 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/45/22745/1
diff --git a/src/mainboard/google/poppy/romstage.c b/src/mainboard/google/poppy/romstage.c index 2a6cd90..6bb4076 100644 --- a/src/mainboard/google/poppy/romstage.c +++ b/src/mainboard/google/poppy/romstage.c @@ -22,20 +22,52 @@
#include <fsp/soc_binding.h>
-#define SPD_LEN 256 +/* Offset to identify DRAM type. */ +#define SPD_DRAM_TYPE_OFF 2 +#define SPD_DRAM_LPDDR3 0xf1 +#define SPD_DRAM_DDR4 0x0c
-#define SPD_DRAM_TYPE 2 -#define SPD_DRAM_DDR3 0x0b -#define SPD_DRAM_LPDDR3 0xf1 -#define SPD_DENSITY_BANKS 4 -#define SPD_ADDRESSING 5 -#define SPD_ORGANIZATION 7 -#define SPD_BUS_DEV_WIDTH 8 -#define SPD_PART_OFF 128 -#define SPD_PART_LEN 18 -#define SPD_MANU_OFF 148 +/* Length of SPD data. */ +#define SPD_LEN_LPDDR3 256 +#define SPD_LEN_DDR4 512
-static void mainboard_print_spd_info(uint8_t spd[]) +/* Fields that are common across different memory types. */ +#define SPD_DENSITY_BANKS_OFF 4 +#define SPD_ADDRESSING_OFF 5 +#define SPD_PART_LEN 18 + +/* Fields that are different depending upon memory type. */ +#define SPD_ORG_OFF_LPDDR3 7 +#define SPD_BUSW_OFF_LPDDR3 8 +#define SPD_PART_OFF_LPDDR3 128 + +#define SPD_ORG_OFF_DDR4 12 +#define SPD_BUSW_OFF_DDR4 13 +#define SPD_PART_OFF_DDR4 329 + +#define SPD_INFO(_type) \ + [MEMORY_##_type] = { \ + .str = #_type, \ + .type_code = SPD_DRAM_##_type, \ + .len = SPD_LEN_##_type, \ + .org_off = SPD_ORG_OFF_##_type, \ + .busw_off = SPD_BUSW_OFF_##_type, \ + .part_off = SPD_PART_OFF_##_type, \ + } + +static const struct dram_info { + const char *str; + uint16_t type_code; + uint16_t len; + uint16_t org_off; + uint16_t busw_off; + uint16_t part_off; +} spd_info[MEMORY_COUNT] = { + SPD_INFO(LPDDR3), + SPD_INFO(DDR4), +}; + +static void mainboard_print_spd_info(const uint8_t *spd, enum memory_type type) { const int spd_banks[8] = { 8, 16, 32, 64, -1, -1, -1, -1 }; const int spd_capmb[8] = { 1, 2, 4, 8, 16, 32, 64, 0 }; @@ -45,28 +77,23 @@ const int spd_devw[8] = { 4, 8, 16, 32, -1, -1, -1, -1 }; const int spd_busw[8] = { 8, 16, 32, 64, -1, -1, -1, -1 }; char spd_name[SPD_PART_LEN+1] = { 0 }; + const struct dram_info *info = &spd_info[type];
- int banks = spd_banks[(spd[SPD_DENSITY_BANKS] >> 4) & 7]; - int capmb = spd_capmb[spd[SPD_DENSITY_BANKS] & 7] * 256; - int rows = spd_rows[(spd[SPD_ADDRESSING] >> 3) & 7]; - int cols = spd_cols[spd[SPD_ADDRESSING] & 7]; - int ranks = spd_ranks[(spd[SPD_ORGANIZATION] >> 3) & 7]; - int devw = spd_devw[spd[SPD_ORGANIZATION] & 7]; - int busw = spd_busw[spd[SPD_BUS_DEV_WIDTH] & 7]; + assert (info->type_code == spd[SPD_DRAM_TYPE_OFF]);
/* Module type */ - printk(BIOS_INFO, "SPD: module type is "); - switch (spd[SPD_DRAM_TYPE]) { - case SPD_DRAM_LPDDR3: - printk(BIOS_INFO, "LPDDR3\n"); - break; - default: - printk(BIOS_INFO, "Unknown (%02x)\n", spd[SPD_DRAM_TYPE]); - return; - } + printk(BIOS_INFO, "SPD: module type is %s\n", info->str); + + int banks = spd_banks[(spd[SPD_DENSITY_BANKS_OFF] >> 4) & 7]; + int capmb = spd_capmb[spd[SPD_DENSITY_BANKS_OFF] & 7] * 256; + int rows = spd_rows[(spd[SPD_ADDRESSING_OFF] >> 3) & 7]; + int cols = spd_cols[spd[SPD_ADDRESSING_OFF] & 7]; + int ranks = spd_ranks[(spd[info->org_off] >> 3) & 7]; + int devw = spd_devw[spd[info->org_off] & 7]; + int busw = spd_busw[spd[info->busw_off] & 7];
/* Module Part Number */ - memcpy(spd_name, &spd[SPD_PART_OFF], SPD_PART_LEN); + memcpy(spd_name, &spd[info->part_off], SPD_PART_LEN); spd_name[SPD_PART_LEN] = 0; printk(BIOS_INFO, "SPD: module part is %s\n", spd_name);
@@ -83,11 +110,12 @@ } }
-static uintptr_t mainboard_get_spd_data(void) +static uintptr_t mainboard_get_spd_data(enum memory_type type) { char *spd_file; size_t spd_file_len; int spd_index; + const size_t spd_len = spd_info[type].len;
spd_index = variant_memory_sku(); assert(spd_index >= 0); @@ -100,17 +128,15 @@ die("SPD data not found.");
/* make sure we have at least one SPD in the file. */ - if (spd_file_len < SPD_LEN) + if (spd_file_len < spd_len) die("Missing SPD data.");
/* Make sure we did not overrun the buffer */ - if (spd_file_len < ((spd_index + 1) * SPD_LEN)) { - printk(BIOS_ERR, "SPD index override to 1 - old hardware?\n"); - spd_index = 1; - } + if (spd_file_len < ((spd_index + 1) * spd_len)) + die("Invalid SPD index.");
- spd_index *= SPD_LEN; - mainboard_print_spd_info((uint8_t *)(spd_file + spd_index)); + spd_index *= spd_len; + mainboard_print_spd_info((uint8_t *)(spd_file + spd_index), type);
return (uintptr_t)(spd_file + spd_index); } @@ -122,13 +148,19 @@
variant_memory_params(&p);
- memcpy(&mem_cfg->DqByteMapCh0, p.dq_map, p.dq_map_size); - memcpy(&mem_cfg->DqsMapCpu2DramCh0, p.dqs_map, p.dqs_map_size); + assert(p.type < MEMORY_COUNT); + + if (p.dq_map && p.dq_map_size) + memcpy(&mem_cfg->DqByteMapCh0, p.dq_map, p.dq_map_size); + + if (p.dqs_map && p.dqs_map_size) + memcpy(&mem_cfg->DqsMapCpu2DramCh0, p.dqs_map, p.dqs_map_size); + memcpy(&mem_cfg->RcompResistor, p.rcomp_resistor, p.rcomp_resistor_size); memcpy(&mem_cfg->RcompTarget, p.rcomp_target, p.rcomp_target_size);
- mem_cfg->MemorySpdPtr00 = mainboard_get_spd_data(); + mem_cfg->MemorySpdPtr00 = mainboard_get_spd_data(p.type); mem_cfg->MemorySpdPtr10 = mem_cfg->MemorySpdPtr00; - mem_cfg->MemorySpdDataLen = SPD_LEN; + mem_cfg->MemorySpdDataLen = spd_info[p.type].len; } diff --git a/src/mainboard/google/poppy/variants/baseboard/include/baseboard/variants.h b/src/mainboard/google/poppy/variants/baseboard/include/baseboard/variants.h index 62389af..c88b99a 100644 --- a/src/mainboard/google/poppy/variants/baseboard/include/baseboard/variants.h +++ b/src/mainboard/google/poppy/variants/baseboard/include/baseboard/variants.h @@ -29,7 +29,14 @@
const struct cros_gpio *variant_cros_gpios(size_t *num);
+enum memory_type { + MEMORY_LPDDR3, + MEMORY_DDR4, + MEMORY_COUNT, +}; + struct memory_params { + enum memory_type type; const void *dq_map; size_t dq_map_size; const void *dqs_map; diff --git a/src/mainboard/google/poppy/variants/baseboard/memory.c b/src/mainboard/google/poppy/variants/baseboard/memory.c index d3f1286..8134f1a 100644 --- a/src/mainboard/google/poppy/variants/baseboard/memory.c +++ b/src/mainboard/google/poppy/variants/baseboard/memory.c @@ -39,6 +39,7 @@
void __attribute__((weak)) variant_memory_params(struct memory_params *p) { + p->type = MEMORY_LPDDR3; p->dq_map = dq_map; p->dq_map_size = sizeof(dq_map); p->dqs_map = dqs_map; diff --git a/src/mainboard/google/poppy/variants/nautilus/memory.c b/src/mainboard/google/poppy/variants/nautilus/memory.c index 508c299..dc845bc 100644 --- a/src/mainboard/google/poppy/variants/nautilus/memory.c +++ b/src/mainboard/google/poppy/variants/nautilus/memory.c @@ -37,6 +37,7 @@
void variant_memory_params(struct memory_params *p) { + p->type = MEMORY_LPDDR3; p->dq_map = dq_map; p->dq_map_size = sizeof(dq_map); p->dqs_map = dqs_map;