summaryrefslogtreecommitdiff
path: root/src/mainboard/google/hatch/romstage_spd_cbfs.c
diff options
context:
space:
mode:
authorEdward O'Callaghan <quasisec@chromium.org>2019-10-23 00:28:39 +1100
committerPatrick Georgi <pgeorgi@google.com>2019-11-06 10:15:10 +0000
commitb4741616ea3dc1f0b281376f9c5e0ffe75a1b15b (patch)
tree74f462a669397f8456d118f5b3535da5a479ca0e /src/mainboard/google/hatch/romstage_spd_cbfs.c
parentfb2a9d5ed86d9d5e5d7a8b20e71df0deba3bc5c0 (diff)
downloadcoreboot-b4741616ea3dc1f0b281376f9c5e0ffe75a1b15b.tar.xz
mainboard/google: Rework Hatch so that SPD in CBFS is optional
All Hatch variants so far embed static SPD data encoded within the firmware image. However we wish the flexibility for romstage implementations that allow for reading the SPD data dynamically over SMBus. BRANCH=none BUG=b:143134702 TEST=./util/abuild/abuild -p none -t google/hatch -x -a Change-Id: Ie1637d08cdd85bc8d7c3b6f2d6f386d0e0c6589b Signed-off-by: Edward O'Callaghan <quasisec@chromium.org> Reviewed-on: https://review.coreboot.org/c/coreboot/+/36250 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Furquan Shaikh <furquan@google.com> Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Diffstat (limited to 'src/mainboard/google/hatch/romstage_spd_cbfs.c')
-rw-r--r--src/mainboard/google/hatch/romstage_spd_cbfs.c97
1 files changed, 97 insertions, 0 deletions
diff --git a/src/mainboard/google/hatch/romstage_spd_cbfs.c b/src/mainboard/google/hatch/romstage_spd_cbfs.c
new file mode 100644
index 0000000000..a94fab5df9
--- /dev/null
+++ b/src/mainboard/google/hatch/romstage_spd_cbfs.c
@@ -0,0 +1,97 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2018 Google LLC
+ *
+ * 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 <console/console.h>
+#include <ec/google/chromeec/ec.h>
+#include <gpio.h>
+#include <memory_info.h>
+#include <soc/cnl_memcfg_init.h>
+#include <soc/romstage.h>
+#include <string.h>
+#include <variant/gpio.h>
+
+/*
+ * GPIO_MEM_CH_SEL is set to 1 for single channel skus
+ * and 0 for dual channel skus.
+ */
+#define GPIO_MEM_CH_SEL GPP_F2
+
+int __weak variant_memory_sku(void)
+{
+ const 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));
+}
+
+void mainboard_memory_init_params(FSPM_UPD *memupd)
+{
+ struct cnl_mb_cfg memcfg;
+ int mem_sku;
+ int is_single_ch_mem;
+
+ variant_memory_params(&memcfg);
+ mem_sku = variant_memory_sku();
+ /*
+ * GPP_F2 is the MEM_CH_SEL gpio, which is set to 1 for single
+ * channel skus and 0 for dual channel skus.
+ */
+ is_single_ch_mem = gpio_get(GPIO_MEM_CH_SEL);
+
+ /*
+ * spd[0]-spd[3] map to CH0D0, CH0D1, CH1D0, CH1D1 respectively.
+ * Dual-DIMM memory is not used in hatch family, so we only
+ * fill in spd_info for CH0D0 and CH1D0 here.
+ */
+ memcfg.spd[0].read_type = READ_SPD_CBFS;
+ memcfg.spd[0].spd_spec.spd_index = mem_sku;
+ if (!is_single_ch_mem) {
+ memcfg.spd[2].read_type = READ_SPD_CBFS;
+ memcfg.spd[2].spd_spec.spd_index = mem_sku;
+ }
+
+ cannonlake_memcfg_init(&memupd->FspmConfig, &memcfg);
+}
+
+void mainboard_get_dram_part_num(const char **part_num, size_t *len)
+{
+ static char part_num_store[DIMM_INFO_PART_NUMBER_SIZE];
+ static enum {
+ PART_NUM_NOT_READ,
+ PART_NUM_AVAILABLE,
+ PART_NUM_NOT_IN_CBI,
+ } part_num_state = PART_NUM_NOT_READ;
+
+ if (part_num_state == PART_NUM_NOT_READ) {
+ if (google_chromeec_cbi_get_dram_part_num(&part_num_store[0],
+ sizeof(part_num_store)) < 0) {
+ printk(BIOS_ERR, "No DRAM part number in CBI!\n");
+ part_num_state = PART_NUM_NOT_IN_CBI;
+ } else {
+ part_num_state = PART_NUM_AVAILABLE;
+ }
+ }
+
+ if (part_num_state == PART_NUM_NOT_IN_CBI)
+ return;
+
+ *part_num = &part_num_store[0];
+ *len = strlen(part_num_store) + 1;
+}