<p>Matt DeVillier has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/21197">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">google/cyan: update SPD functions<br><br>Update cyan's SPD-related functions to more closely mirror<br>those of other Braswell boards, in order to simplify the upcoming<br>baseboard/variant setup for Braswell ChromeOS boards.<br><br>TEST: boot google/cyan, observe SPD correctly identified in<br>cbmem log, RAM-related data correct in SMBIOS tables.<br><br>Change-Id: Iafe99ec0795764f645e0a91f5b321be5b4c6fd88<br>Signed-off-by: Matt DeVillier <matt.devillier@gmail.com><br>---<br>M src/mainboard/google/cyan/spd/spd.c<br>A src/mainboard/google/cyan/spd/spd.h<br>2 files changed, 86 insertions(+), 36 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/97/21197/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/src/mainboard/google/cyan/spd/spd.c b/src/mainboard/google/cyan/spd/spd.c<br>index cbe8ceb..cd263e5 100644<br>--- a/src/mainboard/google/cyan/spd/spd.c<br>+++ b/src/mainboard/google/cyan/spd/spd.c<br>@@ -25,8 +25,7 @@<br> #include <soc/gpio.h><br> #include <soc/romstage.h><br> #include <string.h><br>-<br>-#define SPD_SIZE 256<br>+#include "spd.h"<br> <br> /*<br>  * 0b0000 - 4GiB total - 2 x 2GiB Samsung K4B4G1646Q-HYK0 1600MHz<br>@@ -46,10 +45,10 @@<br>    int ram_id = 0;<br> <br>    gpio_t spd_gpios[] = {<br>-               GP_SW_80,       /* SATA_GP3,RAMID0 */<br>-                GP_SW_67,       /* I2C3_SCL,RAMID1 */<br>+                GP_SW_80,       /* SATA_GP3, RAMID0 */<br>+               GP_SW_67,       /* I2C3_SCL, RAMID1 */<br>                GP_SE_02,       /* MF_PLT_CLK1, RAMID2 */<br>-            GP_SW_64,       /* I2C3_SDA RAMID3 */<br>+                GP_SW_64,       /* I2C3_SDA, RAMID3 */<br>        };<br> <br>         ram_id = gpio_base2_value(spd_gpios, ARRAY_SIZE(spd_gpios));<br>@@ -90,7 +89,7 @@<br>       }<br> <br>  /* Return the serial product data for the RAM */<br>-     return &spd_file_content[SPD_SIZE * ram_id];<br>+     return &spd_file_content[SPD_LEN * ram_id];<br> }<br> <br> /* Copy SPD data for on-board memory */<br>@@ -107,7 +106,7 @@<br>         if (!spd_file)<br>                die("SPD data not found.");<br> <br>-     if (spd_file_len < SPD_SIZE)<br>+      if (spd_file_len < SPD_LEN)<br>                die("Missing SPD data.");<br> <br>        /*<br>@@ -115,11 +114,11 @@<br>      * DIMMs so use the same SPD data for each DIMM.<br>       */<br>   spd_content = get_spd_pointer(spd_file,<br>-                                    spd_file_len / SPD_SIZE,<br>+                                     spd_file_len / SPD_LEN,<br>                                       &dual_channel);<br>     if (IS_ENABLED(CONFIG_DISPLAY_SPD_DATA) && spd_content != NULL) {<br>             printk(BIOS_DEBUG, "SPD Data:\n");<br>-         hexdump(spd_content, SPD_SIZE);<br>+              hexdump(spd_content, SPD_LEN);<br>                printk(BIOS_DEBUG, "\n");<br>   }<br> <br>@@ -144,48 +143,69 @@<br>   }<br> }<br> <br>-static void set_dimm_info(uint32_t chips, uint8_t *spd, struct dimm_info *dimm)<br>+static void set_dimm_info(uint8_t *spd, struct dimm_info *dimm)<br> {<br>+     const int spd_capmb[8] = {  1,  2,  4,  8, 16, 32, 64,  0 };<br>+ const int spd_ranks[8] = {  1,  2,  3,  4, -1, -1, -1, -1 };<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>  uint16_t clock_frequency;<br>-    uint32_t log2_chips;<br>+<br>+      int capmb = spd_capmb[spd[SPD_DENSITY_BANKS] & 7] * 256;<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>+<br>+     void *hob_list_ptr;<br>+  EFI_HOB_GUID_TYPE *hob_ptr;<br>+  FSP_SMBIOS_MEMORY_INFO *memory_info_hob;<br>+     const EFI_GUID memory_info_hob_guid = FSP_SMBIOS_MEMORY_INFO_GUID;<br>+<br>+        /* Locate the memory info HOB, presence validated by raminit */<br>+      hob_list_ptr = fsp_get_hob_list();<br>+   hob_ptr = get_next_guid_hob(&memory_info_hob_guid, hob_list_ptr);<br>+        if (hob_ptr != NULL) {<br>+               memory_info_hob = (FSP_SMBIOS_MEMORY_INFO *)(hob_ptr + 1);<br>+           dimm->ddr_frequency = memory_info_hob->MemoryFrequencyInMHz;<br>+   } else {<br>+             printk(BIOS_ERR, "Can't get memory info hob pointer\n");<br>+               dimm->ddr_frequency = 0;<br>+  }<br> <br>  /* Parse the SPD data to determine the DIMM information */<br>-   dimm->ddr_type = MEMORY_TYPE_DDR3;<br>-        dimm->dimm_size = (chips << (spd[4] & 0xf)) << (28 - 3 - 20);  /* MiB */<br>+  dimm->ddr_type = MEMORY_DEVICE_LPDDR3;<br>+    dimm->dimm_size = capmb / 8 * busw / devw * ranks;  /* MiB */<br>      clock_frequency = 1000 * spd[11] / (spd[10] * spd[12]); /* MHz */<br>     dimm->ddr_frequency = 2 * clock_frequency;   /* Double Data Rate */<br>        dimm->mod_type = spd[3] & 0xf;<br>         memcpy((char *)&dimm->module_part_number[0], &spd[0x80],<br>           sizeof(dimm->module_part_number) - 1);<br>     dimm->mod_id = *(uint16_t *)&spd[0x94];<br>-       switch (chips) {<br>-     case 1:<br>-              log2_chips = 0;<br>-              break;<br> <br>-    case 2:<br>-              log2_chips = 1;<br>-              break;<br>-<br>-    case 4:<br>-              log2_chips = 2;<br>-              break;<br>-<br>-    case 8:<br>-              log2_chips = 3;<br>-              break;<br>-<br>+    switch (busw) {<br>       default:<br>-             log2_chips = 0;<br>+      case 8:<br>+              dimm->bus_width = MEMORY_BUS_WIDTH_8;<br>+             break;<br>+<br>+    case 16:<br>+             dimm->bus_width = MEMORY_BUS_WIDTH_16;<br>+            break;<br>+<br>+    case 32:<br>+             dimm->bus_width = MEMORY_BUS_WIDTH_32;<br>+            break;<br>+<br>+    case 64:<br>+             dimm->bus_width = MEMORY_BUS_WIDTH_64;<br>+            break;<br>        }<br>-    dimm->bus_width = (uint8_t)(log2_chips + (spd[7] & 7) + 2 - 3);<br> }<br> <br> void mainboard_save_dimm_info(struct romstage_params *params)<br> {<br>     struct dimm_info *dimm;<br>       struct memory_info *mem_info;<br>-        uint32_t chips;<br> <br>    /*<br>     * Allocate CBMEM area for DIMM information used to populate SMBIOS<br>@@ -198,16 +218,15 @@<br>    memset(mem_info, 0, sizeof(*mem_info));<br> <br>    /* Describe the first channel memory */<br>-      chips = 4;<br>    dimm = &mem_info->dimm[0];<br>-    set_dimm_info(chips, params->pei_data->spd_data_ch0, dimm);<br>+    set_dimm_info(params->pei_data->spd_data_ch0, dimm);<br>    mem_info->dimm_cnt = 1;<br> <br>         /* Describe the second channel memory */<br>      if (params->pei_data->spd_ch1_config == 1) {<br>            dimm = &mem_info->dimm[1];<br>-            set_dimm_info(chips, params->pei_data->spd_data_ch1, dimm);<br>+            set_dimm_info(params->pei_data->spd_data_ch1, dimm);<br>            dimm->channel_num = 1;<br>             mem_info->dimm_cnt = 2;<br>    }<br>-}<br>+}<br>\ No newline at end of file<br>diff --git a/src/mainboard/google/cyan/spd/spd.h b/src/mainboard/google/cyan/spd/spd.h<br>new file mode 100644<br>index 0000000..ec044d6<br>--- /dev/null<br>+++ b/src/mainboard/google/cyan/spd/spd.h<br>@@ -0,0 +1,31 @@<br>+/*<br>+ * This file is part of the coreboot project.<br>+ *<br>+ * Copyright (C) 2014 Google Inc.<br>+ * Copyright (C) 2015 Intel Corporation.<br>+ *<br>+ * This program is free software; you can redistribute it and/or modify<br>+ * it under the terms of the GNU General Public License as published by<br>+ * the Free Software Foundation; version 2 of the License.<br>+ *<br>+ * This program is distributed in the hope that it will be useful,<br>+ * but WITHOUT ANY WARRANTY; without even the implied warranty of<br>+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the<br>+ * GNU General Public License for more details.<br>+ */<br>+<br>+#ifndef _MAINBOARD_SPD_H_<br>+#define _MAINBOARD_SPD_H_<br>+<br>+#define SPD_LEN                        256<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>+<br>+#endif /* _MAINBOARD_SPD_H_ */<br></pre><p>To view, visit <a href="https://review.coreboot.org/21197">change 21197</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/21197"/><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: Iafe99ec0795764f645e0a91f5b321be5b4c6fd88 </div>
<div style="display:none"> Gerrit-Change-Number: 21197 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Matt DeVillier <matt.devillier@gmail.com> </div>