1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <console/console.h>
6 #include <soc/cnl_memcfg_init.h>
7 #include <soc/romstage.h>
11 static unsigned int get_memory_config_straps(void)
14 * The hardware supports a number of different memory configurations
15 * which are selected using four ID bits ID3 (GPP_H7), ID2 (GPP_H6),
16 * ID1 (GPP_E23) and ID0 (GPP_E22).
18 * The mapping is defined in the schematics as follows (ID3 is always
19 * 0 and can be ignored):
21 * ID2 ID1 ID0 Memory type
22 * -----------------------------------------------
23 * 0 0 0 Hynix 16G dual channel
24 * 0 0 1 Micron 16G dual channel
25 * 0 1 0 Hynix 8G dual channel
26 * 0 1 1 Hynix 4G single channel
27 * 1 0 0 Micron 8G dual channel
28 * 1 0 1 Micron 4G single channel
29 * 1 1 0 Samsung 8G dual channel
30 * 1 1 1 Samsung 4G single channel
32 * We return the value of these bits so that the index into the SPD
33 * table can be .spd[] values can be configured correctly in the
34 * memory configuration structure.
37 gpio_t memid_gpios
[] = {GPP_E22
, GPP_E23
, GPP_H6
};
38 return (u8
)gpio_base2_value(memid_gpios
, ARRAY_SIZE(memid_gpios
));
41 static bool is_dual_channel(const unsigned int memid
)
43 return memid
!= 3 && memid
!= 5 && memid
!= 7;
46 static void fill_spd_data(struct cnl_mb_cfg
*mem_cfg
)
48 const unsigned int memid
= get_memory_config_straps();
49 printk(BIOS_DEBUG
, "Memory config straps: 0x%.2x\n", memid
);
51 * If we are using single channel ID = 3, 5 or 7 then we only
52 * populate .spd[0].If we are dual channel then we also populate
55 mem_cfg
->spd
[0].read_type
= READ_SPD_CBFS
;
56 mem_cfg
->spd
[0].spd_spec
.spd_index
= memid
;
57 if (is_dual_channel(memid
)) {
58 mem_cfg
->spd
[2].read_type
= READ_SPD_CBFS
;
59 mem_cfg
->spd
[2].spd_spec
.spd_index
= memid
;
63 void mainboard_memory_init_params(FSPM_UPD
*memupd
)
65 struct cnl_mb_cfg memcfg
= {
66 .rcomp_resistor
= {121, 81, 100},
67 .rcomp_targets
= {100, 40, 20, 20, 26},
68 .dq_pins_interleaved
= 0,
73 const uint8_t vtd
= get_uint_option("vtd", 1);
74 memupd
->FspmTestConfig
.VtdDisable
= !vtd
;
76 fill_spd_data(&memcfg
);
77 cannonlake_memcfg_init(&memupd
->FspmConfig
, &memcfg
);