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