diff options
author | Furquan Shaikh <furquan@chromium.org> | 2017-04-14 22:11:13 -0700 |
---|---|---|
committer | Furquan Shaikh <furquan@google.com> | 2017-04-19 19:18:32 +0200 |
commit | cbed0c26d0949489e7430013fd01c8f9ea1e3a88 (patch) | |
tree | 526de3c862432ef4641c906afac918ca6cb498e4 | |
parent | 374d1ff8aacba5fc872b76bed6daf97da55e997a (diff) |
mainboard/google/poppy: Provide memory configuration variant API
Add support for memory configuration by providing weak implementation
from the baseboard. All SPD files are present under spd/
directory. SPD_SOURCES must be provided by the variants to ensure that
required SPD hex files are included in the SPD binary.
BUG=b:37375693
Change-Id: Ic9bcc03d5a35bebd14061680f264ac072b3c0634
Signed-off-by: Furquan Shaikh <furquan@chromium.org>
Reviewed-on: https://review.coreboot.org/19325
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
-rw-r--r-- | src/mainboard/google/poppy/Makefile.inc | 4 | ||||
-rw-r--r-- | src/mainboard/google/poppy/romstage.c | 127 | ||||
-rw-r--r-- | src/mainboard/google/poppy/spd/Makefile.inc | 31 | ||||
-rw-r--r-- | src/mainboard/google/poppy/spd/spd.c | 116 | ||||
-rw-r--r-- | src/mainboard/google/poppy/spd/spd.h | 35 | ||||
-rw-r--r-- | src/mainboard/google/poppy/variants/baseboard/Makefile.inc | 1 | ||||
-rw-r--r-- | src/mainboard/google/poppy/variants/baseboard/include/baseboard/variants.h | 14 | ||||
-rw-r--r-- | src/mainboard/google/poppy/variants/baseboard/memory.c | 62 | ||||
-rw-r--r-- | src/mainboard/google/poppy/variants/poppy/Makefile.inc | 8 |
9 files changed, 197 insertions, 201 deletions
diff --git a/src/mainboard/google/poppy/Makefile.inc b/src/mainboard/google/poppy/Makefile.inc index b151b0c140..c837acdd5e 100644 --- a/src/mainboard/google/poppy/Makefile.inc +++ b/src/mainboard/google/poppy/Makefile.inc @@ -13,8 +13,6 @@ ## GNU General Public License for more details. ## -subdirs-y += spd - bootblock-y += bootblock.c bootblock-$(CONFIG_CHROMEOS) += chromeos.c @@ -36,3 +34,5 @@ CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/variants/baseboard/include subdirs-y += variants/$(VARIANT_DIR) CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/variants/$(VARIANT_DIR)/include + +subdirs-y += spd diff --git a/src/mainboard/google/poppy/romstage.c b/src/mainboard/google/poppy/romstage.c index 790e5ae833..2a6cd90ea7 100644 --- a/src/mainboard/google/poppy/romstage.c +++ b/src/mainboard/google/poppy/romstage.c @@ -13,37 +13,120 @@ * GNU General Public License for more details. */ +#include <assert.h> +#include <baseboard/variants.h> +#include <cbfs.h> +#include <console/console.h> #include <soc/romstage.h> #include <string.h> #include <fsp/soc_binding.h> -#include "spd/spd.h" +#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 +#define SPD_MANU_OFF 148 + +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_LPDDR3: + printk(BIOS_INFO, "LPDDR3\n"); + break; + default: + printk(BIOS_INFO, "Unknown (%02x)\n", spd[SPD_DRAM_TYPE]); + return; + } + + /* 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); + } +} + +static uintptr_t mainboard_get_spd_data(void) +{ + char *spd_file; + size_t spd_file_len; + int spd_index; + + spd_index = variant_memory_sku(); + assert(spd_index >= 0); + 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)) { + printk(BIOS_ERR, "SPD index override to 1 - old hardware?\n"); + spd_index = 1; + } + + spd_index *= SPD_LEN; + mainboard_print_spd_info((uint8_t *)(spd_file + spd_index)); + + return (uintptr_t)(spd_file + spd_index); +} void mainboard_memory_init_params(FSPM_UPD *mupd) { FSP_M_CONFIG *mem_cfg = &mupd->FspmConfig; - /* DQ byte map */ - const u8 dq_map[2][12] = { - { 0x0F, 0xF0, 0x00, 0xF0, 0x0F, 0xF0, - 0x0F, 0x00, 0xFF, 0x00, 0xFF, 0x00 }, - { 0xCC, 0x33, 0x00, 0x33, 0xCC, 0x33, - 0xCC, 0x00, 0xFF, 0x00, 0xFF, 0x00 } - }; - /* DQS CPU<>DRAM map */ - const u8 dqs_map[2][8] = { - { 2, 3, 1, 0, 4, 7, 6, 5 }, - { 5, 6, 0, 3, 4, 7, 2, 1 }, - }; - /* Rcomp resistor */ - const u16 rcomp_resistor[] = { 200, 81, 162 }; - /* Rcomp target */ - const u16 rcomp_target[] = { 100, 40, 40, 23, 40 }; - - memcpy(&mem_cfg->DqByteMapCh0, dq_map, sizeof(dq_map)); - memcpy(&mem_cfg->DqsMapCpu2DramCh0, dqs_map, sizeof(dqs_map)); - memcpy(&mem_cfg->RcompResistor, rcomp_resistor, sizeof(rcomp_resistor)); - memcpy(&mem_cfg->RcompTarget, rcomp_target, sizeof(rcomp_target)); + struct memory_params p; + + variant_memory_params(&p); + + memcpy(&mem_cfg->DqByteMapCh0, p.dq_map, p.dq_map_size); + memcpy(&mem_cfg->DqsMapCpu2DramCh0, p.dqs_map, p.dqs_map_size); + memcpy(&mem_cfg->RcompResistor, p.rcomp_resistor, + p.rcomp_resistor_size); + memcpy(&mem_cfg->RcompTarget, p.rcomp_target, p.rcomp_target_size); mem_cfg->MemorySpdPtr00 = mainboard_get_spd_data(); mem_cfg->MemorySpdPtr10 = mem_cfg->MemorySpdPtr00; diff --git a/src/mainboard/google/poppy/spd/Makefile.inc b/src/mainboard/google/poppy/spd/Makefile.inc index 2a3c0c0803..30e632ded0 100644 --- a/src/mainboard/google/poppy/spd/Makefile.inc +++ b/src/mainboard/google/poppy/spd/Makefile.inc @@ -1,32 +1,11 @@ -## -## This file is part of the coreboot project. -## -## Copyright (C) 2016 Google Inc. -## Copyright (C) 2016 Intel Corporation -## -## This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; version 2 of the License. -## -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. -## - -romstage-y += spd.c SPD_BIN = $(obj)/spd.bin -SPD_SOURCES = empty # 0b0000 -SPD_SOURCES += empty # 0b0001 -SPD_SOURCES += empty # 0b0010 -SPD_SOURCES += micron_dimm_MT52L512M64D4PQ-107 # 0b0011 -SPD_SOURCES += hynix_dimm_H9CCNNNCPTALBR-NUD # 0b0100 -SPD_SOURCES += micron_dimm_MT52L1G64D8QC-107 # 0b0101 -SPD_SOURCES += hynix_dimm_H9CCNNNFAGMLLR-NUD # 0b0110 - -SPD_DEPS := $(foreach f, $(SPD_SOURCES), src/mainboard/$(MAINBOARDDIR)/spd/$(f).spd.hex) +ifeq ($(SPD_SOURCES),) + SPD_DEPS := $(error SPD_SOURCES is not set. Variant must provide this) +else + SPD_DEPS := $(foreach f, $(SPD_SOURCES), src/mainboard/$(MAINBOARDDIR)/spd/$(f).spd.hex) +endif # Include spd ROM data $(SPD_BIN): $(SPD_DEPS) diff --git a/src/mainboard/google/poppy/spd/spd.c b/src/mainboard/google/poppy/spd/spd.c deleted file mode 100644 index fa0012a908..0000000000 --- a/src/mainboard/google/poppy/spd/spd.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2016 Google Inc. - * Copyright (C) 2016 Intel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include <arch/byteorder.h> -#include <cbfs.h> -#include <console/console.h> -#include <gpio.h> -#include <soc/gpio.h> -#include <soc/pei_data.h> -#include <soc/romstage.h> -#include <string.h> - -#include <variant/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); - } -} - -uintptr_t mainboard_get_spd_data(void) -{ - char *spd_file; - size_t spd_file_len; - int spd_index; - - gpio_t spd_gpios[] = { - GPIO_MEM_CONFIG_0, - GPIO_MEM_CONFIG_1, - GPIO_MEM_CONFIG_2, - GPIO_MEM_CONFIG_3, - }; - - spd_index = gpio_base2_value(spd_gpios, ARRAY_SIZE(spd_gpios)); - 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)) { - printk(BIOS_ERR, "SPD index override to 1 - old hardware?\n"); - spd_index = 1; - } - - spd_index *= SPD_LEN; - mainboard_print_spd_info((uint8_t *)(spd_file + spd_index)); - - return (uintptr_t)(spd_file + spd_index); -} diff --git a/src/mainboard/google/poppy/spd/spd.h b/src/mainboard/google/poppy/spd/spd.h deleted file mode 100644 index 4195a0cf1b..0000000000 --- a/src/mainboard/google/poppy/spd/spd.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2016 Google Inc. - * Copyright (C) 2016 Intel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef MAINBOARD_SPD_H -#define MAINBOARD_SPD_H - -#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 -#define SPD_MANU_OFF 148 - -uintptr_t mainboard_get_spd_data(void); - -#endif diff --git a/src/mainboard/google/poppy/variants/baseboard/Makefile.inc b/src/mainboard/google/poppy/variants/baseboard/Makefile.inc index 37a60a41a5..160b0f84bc 100644 --- a/src/mainboard/google/poppy/variants/baseboard/Makefile.inc +++ b/src/mainboard/google/poppy/variants/baseboard/Makefile.inc @@ -1,6 +1,7 @@ bootblock-y += gpio.c romstage-y += boardid.c +romstage-y += memory.c ramstage-y += boardid.c ramstage-y += gpio.c diff --git a/src/mainboard/google/poppy/variants/baseboard/include/baseboard/variants.h b/src/mainboard/google/poppy/variants/baseboard/include/baseboard/variants.h index 0b7cf3519b..bf73585c2d 100644 --- a/src/mainboard/google/poppy/variants/baseboard/include/baseboard/variants.h +++ b/src/mainboard/google/poppy/variants/baseboard/include/baseboard/variants.h @@ -32,4 +32,18 @@ const struct pad_config *variant_early_gpio_table(size_t *num); const struct cros_gpio *variant_cros_gpios(size_t *num); +struct memory_params { + const void *dq_map; + size_t dq_map_size; + const void *dqs_map; + size_t dqs_map_size; + const void *rcomp_resistor; + size_t rcomp_resistor_size; + const void *rcomp_target; + size_t rcomp_target_size; +}; + +void variant_memory_params(struct memory_params *p); +int variant_memory_sku(void); + #endif /* __BASEBOARD_VARIANTS_H__ */ diff --git a/src/mainboard/google/poppy/variants/baseboard/memory.c b/src/mainboard/google/poppy/variants/baseboard/memory.c new file mode 100644 index 0000000000..d3f1286716 --- /dev/null +++ b/src/mainboard/google/poppy/variants/baseboard/memory.c @@ -0,0 +1,62 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2017 Google Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <baseboard/variants.h> +#include <gpio.h> +#include <variant/gpio.h> + +/* DQ byte map */ +static const u8 dq_map[][12] = { + { 0x0F, 0xF0, 0x00, 0xF0, 0x0F, 0xF0, + 0x0F, 0x00, 0xFF, 0x00, 0xFF, 0x00 }, + { 0xCC, 0x33, 0x00, 0x33, 0xCC, 0x33, + 0xCC, 0x00, 0xFF, 0x00, 0xFF, 0x00 } +}; + +/* DQS CPU<>DRAM map */ +static const u8 dqs_map[][8] = { + { 2, 3, 1, 0, 4, 7, 6, 5 }, + { 5, 6, 0, 3, 4, 7, 2, 1 }, +}; + +/* Rcomp resistor */ +static const u16 rcomp_resistor[] = { 200, 81, 162 }; + +/* Rcomp target */ +static const u16 rcomp_target[] = { 100, 40, 40, 23, 40 }; + +void __attribute__((weak)) variant_memory_params(struct memory_params *p) +{ + p->dq_map = dq_map; + p->dq_map_size = sizeof(dq_map); + p->dqs_map = dqs_map; + p->dqs_map_size = sizeof(dqs_map); + p->rcomp_resistor = rcomp_resistor; + p->rcomp_resistor_size = sizeof(rcomp_resistor); + p->rcomp_target = rcomp_target; + p->rcomp_target_size = sizeof(rcomp_target); +} + +int __attribute__((weak)) variant_memory_sku(void) +{ + gpio_t spd_gpios[] = { + GPIO_MEM_CONFIG_0, + GPIO_MEM_CONFIG_1, + GPIO_MEM_CONFIG_2, + GPIO_MEM_CONFIG_3, + }; + + return gpio_base2_value(spd_gpios, ARRAY_SIZE(spd_gpios)); +} diff --git a/src/mainboard/google/poppy/variants/poppy/Makefile.inc b/src/mainboard/google/poppy/variants/poppy/Makefile.inc new file mode 100644 index 0000000000..41e40f7ee7 --- /dev/null +++ b/src/mainboard/google/poppy/variants/poppy/Makefile.inc @@ -0,0 +1,8 @@ + +SPD_SOURCES = empty # 0b0000 +SPD_SOURCES += empty # 0b0001 +SPD_SOURCES += empty # 0b0010 +SPD_SOURCES += micron_dimm_MT52L512M64D4PQ-107 # 0b0011 +SPD_SOURCES += hynix_dimm_H9CCNNNCPTALBR-NUD # 0b0100 +SPD_SOURCES += micron_dimm_MT52L1G64D8QC-107 # 0b0101 +SPD_SOURCES += hynix_dimm_H9CCNNNFAGMLLR-NUD # 0b0110 |