[coreboot-gerrit] Change in coreboot[master]: mb/google/poppy: Add support for DDR4 memory

Furquan Shaikh (Code Review) gerrit at coreboot.org
Wed Dec 6 01:03:03 CET 2017


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 at 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;

-- 
To view, visit https://review.coreboot.org/22745
To unsubscribe, visit https://review.coreboot.org/settings

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: Iefad01719c62264fb0d7e987904e77647d6026c2
Gerrit-Change-Number: 22745
Gerrit-PatchSet: 1
Gerrit-Owner: Furquan Shaikh <furquan at google.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.coreboot.org/pipermail/coreboot-gerrit/attachments/20171206/ee10b0b9/attachment-0001.html>


More information about the coreboot-gerrit mailing list