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