blob: 448e56cc7ae30d034b8fccb5aeaa40fea14b1548 [file] [log] [blame]
Angel Ponsf5627e82020-04-05 15:46:52 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Lijian Zhao903c9762018-08-20 14:06:13 -07002#include <assert.h>
3#include <console/console.h>
4#include <fsp/util.h>
5#include <soc/cnl_memcfg_init.h>
6#include <spd_bin.h>
7#include <string.h>
8
9static void meminit_memcfg(FSP_M_CONFIG *mem_cfg,
Philip Chen0d4200f2019-04-29 10:18:24 -070010 const struct cnl_mb_cfg *board_cfg)
Lijian Zhao903c9762018-08-20 14:06:13 -070011{
12 /*
13 * DqByteMapChx expects 12 bytes of data, but the last 6 bytes
14 * are unused, so client passes in the relevant values and
15 * we null out the rest of the data.
16 */
17 memset(&mem_cfg->DqByteMapCh0, 0, sizeof(mem_cfg->DqByteMapCh0));
18 memcpy(&mem_cfg->DqByteMapCh0, &board_cfg->dq_map[DDR_CH0],
Philip Chen0d4200f2019-04-29 10:18:24 -070019 sizeof(board_cfg->dq_map[DDR_CH0]));
Lijian Zhao903c9762018-08-20 14:06:13 -070020
21 memset(&mem_cfg->DqByteMapCh1, 0, sizeof(mem_cfg->DqByteMapCh1));
22 memcpy(&mem_cfg->DqByteMapCh1, &board_cfg->dq_map[DDR_CH1],
Philip Chen0d4200f2019-04-29 10:18:24 -070023 sizeof(board_cfg->dq_map[DDR_CH1]));
Lijian Zhao903c9762018-08-20 14:06:13 -070024
25 memcpy(&mem_cfg->DqsMapCpu2DramCh0, &board_cfg->dqs_map[DDR_CH0],
Philip Chen0d4200f2019-04-29 10:18:24 -070026 sizeof(board_cfg->dqs_map[DDR_CH0]));
Lijian Zhao903c9762018-08-20 14:06:13 -070027 memcpy(&mem_cfg->DqsMapCpu2DramCh1, &board_cfg->dqs_map[DDR_CH1],
Philip Chen0d4200f2019-04-29 10:18:24 -070028 sizeof(board_cfg->dqs_map[DDR_CH1]));
Lijian Zhao903c9762018-08-20 14:06:13 -070029
30 memcpy(&mem_cfg->RcompResistor, &board_cfg->rcomp_resistor,
Philip Chen0d4200f2019-04-29 10:18:24 -070031 sizeof(mem_cfg->RcompResistor));
Lijian Zhao903c9762018-08-20 14:06:13 -070032
33 /* Early cannonlake requires rcomp targets to be 0 */
34 memcpy(&mem_cfg->RcompTarget, &board_cfg->rcomp_targets,
Philip Chen0d4200f2019-04-29 10:18:24 -070035 sizeof(mem_cfg->RcompTarget));
Lijian Zhao903c9762018-08-20 14:06:13 -070036}
37
38/*
39 * Initialize default memory settings using spd data contained in a buffer.
40 */
Philip Chen0d4200f2019-04-29 10:18:24 -070041static void meminit_spd_data(FSP_M_CONFIG *mem_cfg, uint8_t mem_slot,
42 size_t spd_data_len, uintptr_t spd_data_ptr)
Lijian Zhao903c9762018-08-20 14:06:13 -070043{
Philip Chen0d4200f2019-04-29 10:18:24 -070044 static size_t last_set_spd_data_len = 0;
45
46 assert(spd_data_ptr != 0 && spd_data_len != 0);
47
48 if (last_set_spd_data_len != 0 &&
49 last_set_spd_data_len != spd_data_len)
50 die("spd data length disparity among slots");
51
52 mem_cfg->MemorySpdDataLen = spd_data_len;
53 last_set_spd_data_len = spd_data_len;
54
55 switch (mem_slot) {
56 case 0:
57 mem_cfg->MemorySpdPtr00 = spd_data_ptr;
58 break;
59 case 1:
60 mem_cfg->MemorySpdPtr01 = spd_data_ptr;
61 break;
62 case 2:
63 mem_cfg->MemorySpdPtr10 = spd_data_ptr;
64 break;
65 case 3:
66 mem_cfg->MemorySpdPtr11 = spd_data_ptr;
67 break;
68 default:
69 die("nonexistent memory slot");
70 }
Eric Laid5c89122019-09-03 16:08:19 +080071 printk(BIOS_INFO, "memory slot: %d configuration done.\n", mem_slot);
Lijian Zhao903c9762018-08-20 14:06:13 -070072}
73
74/*
75 * Initialize default memory settings using the spd file specified by
76 * spd_index. The spd_index is an index into the SPD_SOURCES array defined
77 * in spd/Makefile.inc.
78 */
79static void meminit_cbfs_spd_index(FSP_M_CONFIG *mem_cfg,
Philip Chen0d4200f2019-04-29 10:18:24 -070080 int spd_index, uint8_t mem_slot)
Lijian Zhao903c9762018-08-20 14:06:13 -070081{
Furquan Shaikhb2709ae2019-05-30 17:24:12 -070082 static size_t spd_data_len;
83 static uintptr_t spd_data_ptr;
84 static int last_spd_index;
Lijian Zhao903c9762018-08-20 14:06:13 -070085
Philip Chen0d4200f2019-04-29 10:18:24 -070086 assert(mem_slot < NUM_DIMM_SLOT);
Furquan Shaikhb2709ae2019-05-30 17:24:12 -070087
88 if ((spd_data_ptr == 0) || (last_spd_index != spd_index)) {
Furquan Shaikhb2709ae2019-05-30 17:24:12 -070089 printk(BIOS_DEBUG, "SPD INDEX = %d\n", spd_index);
90
Julius Wernera9b44f42021-02-05 17:27:45 -080091 spd_data_ptr = spd_cbfs_map(spd_index);
92 if (!spd_data_ptr)
Furquan Shaikhb2709ae2019-05-30 17:24:12 -070093 die("spd.bin not found or incorrect index\n");
94
Julius Wernera9b44f42021-02-05 17:27:45 -080095 spd_data_len = CONFIG_DIMM_SPD_SIZE;
Furquan Shaikhb2709ae2019-05-30 17:24:12 -070096
97 /* Memory leak is ok since we have memory mapped boot media */
98 assert(CONFIG(BOOT_DEVICE_MEMORY_MAPPED));
99
Furquan Shaikhb2709ae2019-05-30 17:24:12 -0700100 last_spd_index = spd_index;
Eric Laid5c89122019-09-03 16:08:19 +0800101 print_spd_info((unsigned char *)spd_data_ptr);
Furquan Shaikhb2709ae2019-05-30 17:24:12 -0700102 }
103
Philip Chen0d4200f2019-04-29 10:18:24 -0700104 meminit_spd_data(mem_cfg, mem_slot, spd_data_len, spd_data_ptr);
Lijian Zhao903c9762018-08-20 14:06:13 -0700105}
106
107/* Initialize onboard memory configurations for CannonLake */
108void cannonlake_memcfg_init(FSP_M_CONFIG *mem_cfg,
Philip Chen0d4200f2019-04-29 10:18:24 -0700109 const struct cnl_mb_cfg *cnl_cfg)
Lijian Zhao903c9762018-08-20 14:06:13 -0700110{
Philip Chen0d4200f2019-04-29 10:18:24 -0700111 const struct spd_info *spdi;
112
Lijian Zhao903c9762018-08-20 14:06:13 -0700113 /* Early Command Training Enabled */
114 mem_cfg->ECT = cnl_cfg->ect;
115 mem_cfg->DqPinsInterleaved = cnl_cfg->dq_pins_interleaved;
116 mem_cfg->CaVrefConfig = cnl_cfg->vref_ca_config;
117
Philip Chen0d4200f2019-04-29 10:18:24 -0700118 for (int i = 0; i < NUM_DIMM_SLOT; i++) {
119 spdi = &(cnl_cfg->spd[i]);
120 switch (spdi->read_type) {
121 case NOT_EXISTING:
122 break;
123 case READ_SMBUS:
124 mem_cfg->SpdAddressTable[i] =
125 spdi->spd_spec.spd_smbus_address;
126 break;
127 case READ_SPD_CBFS:
128 meminit_cbfs_spd_index(mem_cfg,
129 spdi->spd_spec.spd_index, i);
130 break;
131 case READ_SPD_MEMPTR:
132 meminit_spd_data(mem_cfg, i,
133 spdi->spd_spec.spd_data_ptr_info.spd_data_len,
134 spdi->spd_spec.spd_data_ptr_info.spd_data_ptr);
135 break;
136 default:
137 die("no valid way to read mem info");
Lijian Zhao903c9762018-08-20 14:06:13 -0700138 }
139 }
Felix Singerb32599e2021-12-12 13:08:26 +0100140
141 meminit_memcfg(mem_cfg, cnl_cfg);
Lijian Zhao903c9762018-08-20 14:06:13 -0700142}