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