EricR Lai has uploaded this change for review.

View Change

mb/google/drallion: memory spd data debug

Add debug function for printing SPD data. This can be enable
by unmark the SPD_DEBUG flag.

BUG=b:139397313
BRANCH=N/A
TEST=Tested the same code on Hatch and checked cbmem log.

Signed-off-by: Eric Lai <ericr_lai@compal.corp-partner.google.com>
Change-Id: Ie8e448f6f53db4ea0fd2ffdc58699064716c1d57
---
M src/mainboard/google/drallion/romstage.c
1 file changed, 114 insertions(+), 1 deletion(-)

git pull ssh://review.coreboot.org:29418/coreboot refs/changes/57/35157/1
diff --git a/src/mainboard/google/drallion/romstage.c b/src/mainboard/google/drallion/romstage.c
index 20eee7f..12cc3b3 100644
--- a/src/mainboard/google/drallion/romstage.c
+++ b/src/mainboard/google/drallion/romstage.c
@@ -17,6 +17,117 @@
#include <soc/cnl_memcfg_init.h>
#include <soc/romstage.h>

+//#define SPD_DEBUG
+#ifdef SPD_DEBUG
+#include <variant/gpio.h>
+#include <console/console.h>
+#include <cbfs.h>
+
+/* Offset to identify DRAM type. */
+#define SPD_DRAM_TYPE_OFF 2
+#define SPD_DRAM_DDR4 0x0c
+
+/* Length of SPD data. */
+#define SPD_LEN_DDR4 512
+
+/* 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_DDR4 12
+#define SPD_BUSW_OFF_DDR4 13
+#define SPD_PART_OFF_DDR4 329
+
+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 = {
+ .str = "DDR4",
+ .type_code = SPD_DRAM_DDR4,
+ .len = SPD_LEN_DDR4,
+ .org_off = SPD_ORG_OFF_DDR4,
+ .busw_off = SPD_BUSW_OFF_DDR4,
+ .part_off = SPD_PART_OFF_DDR4,
+};
+
+static void mainboard_print_spd_info(const uint8_t *spd)
+{
+ const int spd_banks[10] = { 4, 8, -1, -1, 8, 16, -1, -1, 16, 32 };
+ const int spd_capmb[10] = { 1, 2, 4, 8, 16, 32, 64, 128, 48, 96 };
+ const int spd_rows[8] = { 12, 13, 14, 15, 16, 17, 18, -1 };
+ const int spd_cols[8] = { 9, 10, 11, 12, -1, -1, -1, -1 };
+ const int spd_ranks[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
+ 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;
+
+ /* Module type */
+ 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[info->part_off], SPD_PART_LEN);
+ spd_name[SPD_PART_LEN] = 0;
+ printk(BIOS_INFO, "SPD: module part is %s\n", spd_name);
+
+ printk(BIOS_INFO,
+ "SPD: banks %d, ranks %d, rows %d, columns %d, density %d Mb\n",
+ banks, ranks, rows, cols, capmb);
+ printk(BIOS_INFO, "SPD: device width %d bits, bus width %d bits\n",
+ devw, busw);
+
+ if (capmb > 0 && busw > 0 && devw > 0 && ranks > 0) {
+ /* SIZE = DENSITY / 8 * BUS_WIDTH / SDRAM_WIDTH * RANKS */
+ printk(BIOS_INFO, "SPD: module size is %u MB (per channel)\n",
+ capmb / 8 * busw / devw * ranks);
+ }
+}
+
+static void mainboard_debug_spd_data(void)
+{
+ char *spd_file;
+ size_t spd_file_len;
+ int spd_index;
+ const size_t spd_len = spd_info.len;
+ const char *spd_bin = "spd.bin";
+
+ spd_index = variant_memory_sku();
+
+ printk(BIOS_INFO, "SPD: index %d\n", spd_index);
+
+ /* Load SPD data from CBFS */
+ spd_file = cbfs_boot_map_with_leak(spd_bin, CBFS_TYPE_SPD,
+ &spd_file_len);
+ if (!spd_file)
+ die("SPD data not found.");
+
+ /* make sure we have at least one SPD in the file. */
+ 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))
+ die("Invalid SPD index.");
+
+ spd_index *= spd_len;
+ mainboard_print_spd_info((uint8_t *)(spd_file + spd_index));
+}
+#endif
+
static const struct cnl_mb_cfg memcfg = {
/* Access memory info through SMBUS. */
.spd[0] = {
@@ -58,6 +169,8 @@
void mainboard_memory_init_params(FSPM_UPD *memupd)
{
wilco_ec_romstage_init();
-
+#ifdef SPD_DEBUG
+ mainboard_debug_spd_data();
+#endif
cannonlake_memcfg_init(&memupd->FspmConfig, &memcfg);
}

To view, visit change 35157. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: Ie8e448f6f53db4ea0fd2ffdc58699064716c1d57
Gerrit-Change-Number: 35157
Gerrit-PatchSet: 1
Gerrit-Owner: EricR Lai <ericr_lai@compal.corp-partner.google.com>
Gerrit-MessageType: newchange