soc/mediatek/mt8196: Initialize SSPM
[coreboot.git] / src / soc / intel / cannonlake / cnl_memcfg_init.c
blobdb488ee626f2f4577168d007f618151b53ce00a6
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 #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>
9 static void meminit_memcfg(FSP_M_CONFIG *mem_cfg,
10 const struct cnl_mb_cfg *board_cfg)
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.
17 memset(&mem_cfg->DqByteMapCh0, 0, sizeof(mem_cfg->DqByteMapCh0));
18 memcpy(&mem_cfg->DqByteMapCh0, &board_cfg->dq_map[DDR_CH0],
19 sizeof(board_cfg->dq_map[DDR_CH0]));
21 memset(&mem_cfg->DqByteMapCh1, 0, sizeof(mem_cfg->DqByteMapCh1));
22 memcpy(&mem_cfg->DqByteMapCh1, &board_cfg->dq_map[DDR_CH1],
23 sizeof(board_cfg->dq_map[DDR_CH1]));
25 memcpy(&mem_cfg->DqsMapCpu2DramCh0, &board_cfg->dqs_map[DDR_CH0],
26 sizeof(board_cfg->dqs_map[DDR_CH0]));
27 memcpy(&mem_cfg->DqsMapCpu2DramCh1, &board_cfg->dqs_map[DDR_CH1],
28 sizeof(board_cfg->dqs_map[DDR_CH1]));
30 memcpy(&mem_cfg->RcompResistor, &board_cfg->rcomp_resistor,
31 sizeof(mem_cfg->RcompResistor));
33 /* Early cannonlake requires rcomp targets to be 0 */
34 memcpy(&mem_cfg->RcompTarget, &board_cfg->rcomp_targets,
35 sizeof(mem_cfg->RcompTarget));
39 * Initialize default memory settings using spd data contained in a buffer.
41 static void meminit_spd_data(FSP_M_CONFIG *mem_cfg, uint8_t mem_slot,
42 size_t spd_data_len, uintptr_t spd_data_ptr)
44 static size_t last_set_spd_data_len = 0;
46 assert(spd_data_ptr != 0 && spd_data_len != 0);
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");
52 mem_cfg->MemorySpdDataLen = spd_data_len;
53 last_set_spd_data_len = spd_data_len;
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");
71 printk(BIOS_INFO, "memory slot: %d configuration done.\n", mem_slot);
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.mk.
79 static void meminit_cbfs_spd_index(FSP_M_CONFIG *mem_cfg,
80 int spd_index, uint8_t mem_slot)
82 static size_t spd_data_len;
83 static uintptr_t spd_data_ptr;
84 static int last_spd_index;
86 assert(mem_slot < NUM_DIMM_SLOT);
88 if ((spd_data_ptr == 0) || (last_spd_index != spd_index)) {
89 printk(BIOS_DEBUG, "SPD INDEX = %d\n", spd_index);
91 spd_data_ptr = spd_cbfs_map(spd_index);
92 if (!spd_data_ptr)
93 die("spd.bin not found or incorrect index\n");
95 spd_data_len = CONFIG_DIMM_SPD_SIZE;
97 /* Memory leak is ok since we have memory mapped boot media */
98 assert(CONFIG(BOOT_DEVICE_MEMORY_MAPPED));
100 last_spd_index = spd_index;
101 print_spd_info((unsigned char *)spd_data_ptr);
104 meminit_spd_data(mem_cfg, mem_slot, spd_data_len, spd_data_ptr);
107 /* Initialize onboard memory configurations for CannonLake */
108 void cannonlake_memcfg_init(FSP_M_CONFIG *mem_cfg,
109 const struct cnl_mb_cfg *cnl_cfg)
111 const struct spd_info *spdi;
113 /* 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;
118 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");
141 meminit_memcfg(mem_cfg, cnl_cfg);