From 3f36348dd7abc67048407f181065f1a99b3d0dab Mon Sep 17 00:00:00 2001 From: Duncan Laurie Date: Wed, 14 May 2014 16:09:16 -0700 Subject: [PATCH] samus: Add some code to print basic info from SPD The handling of LPDDR is a bit messy in Intel platforms. There is no traditional SPD so instead one is created by hand from the provided datasheets. These have varying (and sometimes unexpected) geometry and it can be important during bringup to know what configuration is being passed to the memory training code. This could in theory be put in a more generic location, but for now this is the only board with LPDDR3 where I have found it valuable. BUG=chrome-os-partner:28234 TEST=Build and boot on samus, look for SPD details on the console. CQ-DEPEND=CL:199920 CQ-DEPEND=CL:199921 CQ-DEPEND=CL:199922 CQ-DEPEND=CL:199943 CQ-DEPEND=CL:*163751 Change-Id: Ibce0187ceb77d37552ffa1b4a5935061d7019259 Signed-off-by: Duncan Laurie Reviewed-on: https://chromium-review.googlesource.com/199923 --- src/mainboard/google/samus/spd.c | 52 ++++++++++++++++++++++++++++++++ src/mainboard/google/samus/spd.h | 10 ++++++ 2 files changed, 62 insertions(+) diff --git a/src/mainboard/google/samus/spd.c b/src/mainboard/google/samus/spd.c index 61363f3a16..4371da9bd8 100644 --- a/src/mainboard/google/samus/spd.c +++ b/src/mainboard/google/samus/spd.c @@ -27,6 +27,56 @@ #include "gpio.h" #include "spd.h" +static void mainboard_print_spd_info(uint8_t spd[]) +{ + 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 }; + const int spd_rows[8] = { 12, 13, 14, 15, 16, -1, -1, -1 }; + const int spd_cols[8] = { 9, 10, 11, 12, -1, -1, -1, -1 }; + const int spd_ranks[8] = { 1, 2, 3, 4, -1, -1, -1, -1 }; + 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 }; + + 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]; + + /* Module type */ + printk(BIOS_INFO, "SPD: module type is "); + switch (spd[SPD_DRAM_TYPE]) { + case SPD_DRAM_DDR3: + printk(BIOS_INFO, "DDR3\n"); + break; + case SPD_DRAM_LPDDR3: + printk(BIOS_INFO, "LPDDR3\n"); + break; + default: + printk(BIOS_INFO, "Unknown (%02x)\n", spd[SPD_DRAM_TYPE]); + break; + } + + /* Module Part Number */ + memcpy(spd_name, &spd[SPD_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); + } +} + /* Copy SPD data for on-board memory */ void mainboard_fill_spd_data(struct pei_data *pei_data) { @@ -66,4 +116,6 @@ void mainboard_fill_spd_data(struct pei_data *pei_data) ((char*)CBFS_SUBHEADER(spd_file)) + spd_index, SPD_LEN); memcpy(pei_data->spd_data[1][0], ((char*)CBFS_SUBHEADER(spd_file)) + spd_index, SPD_LEN); + + mainboard_print_spd_info(pei_data->spd_data[0][0]); } diff --git a/src/mainboard/google/samus/spd.h b/src/mainboard/google/samus/spd.h index 0597ac382e..98180fa72c 100644 --- a/src/mainboard/google/samus/spd.h +++ b/src/mainboard/google/samus/spd.h @@ -22,6 +22,16 @@ #define SPD_LEN 256 +#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 + /* Samus board memory configuration GPIOs */ #define SPD_GPIO_BIT0 67 #define SPD_GPIO_BIT1 68