aboutsummaryrefslogtreecommitdiff
path: root/src/soc/intel/elkhartlake/meminit.c
diff options
context:
space:
mode:
authorTan, Lean Sheng <lean.sheng.tan@intel.com>2020-08-25 20:40:17 -0700
committerPatrick Georgi <pgeorgi@google.com>2020-09-08 05:29:37 +0000
commit05dfe3177dc728995e93ef6f9d1aa549bcbaa032 (patch)
tree5817d8dde3c1fa73e97ed401de848efdc9a6a32d /src/soc/intel/elkhartlake/meminit.c
parent320f2c1f06c355366ed105c037b254c5bfda56f3 (diff)
soc/intel/elkhartlake: Do initial SoC commit till ramstage
Clone entirely from Jasperlake List of changes on top off initial jasperlake clone 1. Replace "Jasperlake" with "Elkhartlake" 2. Replace "jsl" with "ehl" 3. Replace "jsp" with "mcc" 4. Rename structure based on Jasperlake with Elkhartlake 5. Clean up upd override in fsp_params.c will be added later 6. Sort #include files alphabetically as per comment 7. Remove doc details from espi.c until it is ready 8. Remove pch_isclk & camera clocks related codes 9. Add new #define NMI_STS_CNT & NMI_EN as per comment Signed-off-by: Tan, Lean Sheng <lean.sheng.tan@intel.com> Change-Id: I372b0bb5912e013445ed8df7c58d0a9ee9a7cf35 Reviewed-on: https://review.coreboot.org/c/coreboot/+/44802 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Werner Zeh <werner.zeh@siemens.com>
Diffstat (limited to 'src/soc/intel/elkhartlake/meminit.c')
-rw-r--r--src/soc/intel/elkhartlake/meminit.c114
1 files changed, 114 insertions, 0 deletions
diff --git a/src/soc/intel/elkhartlake/meminit.c b/src/soc/intel/elkhartlake/meminit.c
new file mode 100644
index 0000000000..cd777ba3a0
--- /dev/null
+++ b/src/soc/intel/elkhartlake/meminit.c
@@ -0,0 +1,114 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <assert.h>
+#include <console/console.h>
+#include <fsp/util.h>
+#include <soc/meminit.h>
+#include <spd_bin.h>
+#include <string.h>
+
+static void spd_read_from_cbfs(const struct spd_info *spd_info, uintptr_t *spd_data_ptr,
+ size_t *spd_data_len)
+{
+ struct region_device spd_rdev;
+ size_t spd_index = spd_info->spd_spec.spd_index;
+
+ printk(BIOS_DEBUG, "SPD INDEX = %lu\n", spd_index);
+ if (get_spd_cbfs_rdev(&spd_rdev, spd_index) < 0)
+ die("spd.bin not found or incorrect index\n");
+
+ *spd_data_len = region_device_sz(&spd_rdev);
+
+ /* Memory leak is ok since we have memory mapped boot media */
+ assert(CONFIG(BOOT_DEVICE_MEMORY_MAPPED));
+
+ *spd_data_ptr = (uintptr_t)rdev_mmap_full(&spd_rdev);
+}
+
+static void get_spd_data(const struct spd_info *spd_info, uintptr_t *spd_data_ptr,
+ size_t *spd_data_len)
+{
+ if (spd_info->read_type == READ_SPD_MEMPTR) {
+ *spd_data_ptr = spd_info->spd_spec.spd_data_ptr_info.spd_data_ptr;
+ *spd_data_len = spd_info->spd_spec.spd_data_ptr_info.spd_data_len;
+ return;
+ }
+
+ if (spd_info->read_type == READ_SPD_CBFS) {
+ spd_read_from_cbfs(spd_info, spd_data_ptr, spd_data_len);
+ return;
+ }
+
+ die("no valid way to read SPD info");
+}
+
+static void meminit_dq_dqs_map(FSP_M_CONFIG *mem_cfg, const struct mb_cfg *board_cfg,
+ bool half_populated)
+{
+ memcpy(&mem_cfg->RcompResistor, &board_cfg->rcomp_resistor,
+ sizeof(mem_cfg->RcompResistor));
+
+ memcpy(&mem_cfg->RcompTarget, &board_cfg->rcomp_targets,
+ sizeof(mem_cfg->RcompTarget));
+
+ memcpy(&mem_cfg->DqByteMapCh0, &board_cfg->dq_map[DDR_CH0],
+ sizeof(board_cfg->dq_map[DDR_CH0]));
+
+ memcpy(&mem_cfg->DqsMapCpu2DramCh0, &board_cfg->dqs_map[DDR_CH0],
+ sizeof(board_cfg->dqs_map[DDR_CH0]));
+
+ if (half_populated)
+ return;
+
+ memcpy(&mem_cfg->DqByteMapCh1, &board_cfg->dq_map[DDR_CH1],
+ sizeof(board_cfg->dq_map[DDR_CH1]));
+
+ memcpy(&mem_cfg->DqsMapCpu2DramCh1, &board_cfg->dqs_map[DDR_CH1],
+ sizeof(board_cfg->dqs_map[DDR_CH1]));
+}
+
+static void meminit_channels(FSP_M_CONFIG *mem_cfg, const struct mb_cfg *board_cfg,
+ uintptr_t spd_data_ptr, bool half_populated)
+{
+ /* Channel 0 */
+ mem_cfg->MemorySpdPtr00 = spd_data_ptr;
+ mem_cfg->MemorySpdPtr01 = 0;
+
+ if (half_populated) {
+ printk(BIOS_INFO, "%s: DRAM half-populated\n", __func__);
+ spd_data_ptr = 0;
+ }
+
+ /* Channel 1 */
+ mem_cfg->MemorySpdPtr10 = spd_data_ptr;
+ mem_cfg->MemorySpdPtr11 = 0;
+
+ meminit_dq_dqs_map(mem_cfg, board_cfg, half_populated);
+}
+
+/* Initialize onboard memory configurations for lpddr4x */
+void memcfg_init(FSP_M_CONFIG *mem_cfg, const struct mb_cfg *board_cfg,
+ const struct spd_info *spd_info, bool half_populated)
+{
+
+ if (spd_info->read_type == READ_SMBUS) {
+ for (int i = 0; i < NUM_DIMM_SLOT; i++)
+ mem_cfg->SpdAddressTable[i] = spd_info->spd_spec.spd_smbus_address[i];
+
+ meminit_dq_dqs_map(mem_cfg, board_cfg, half_populated);
+ } else {
+ uintptr_t spd_data_ptr = 0;
+ size_t spd_data_len = 0;
+ memset(&mem_cfg->SpdAddressTable, 0, sizeof(mem_cfg->SpdAddressTable));
+ get_spd_data(spd_info, &spd_data_ptr, &spd_data_len);
+ print_spd_info((unsigned char *)spd_data_ptr);
+
+ mem_cfg->MemorySpdDataLen = spd_data_len;
+ meminit_channels(mem_cfg, board_cfg, spd_data_ptr, half_populated);
+ }
+
+ /* Early Command Training Enabled */
+ mem_cfg->ECT = board_cfg->ect;
+
+ mem_cfg->UserBd = board_cfg->UserBd;
+}