coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
romstage.c
Go to the documentation of this file.
1 /* 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>
8 #include <string.h>
9 #include <types.h>
10 
11 static unsigned int get_memory_config_straps(void)
12 {
13  /*
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).
17  *
18  * The mapping is defined in the schematics as follows (ID3 is always
19  * 0 and can be ignored):
20  *
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
31  *
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.
35  */
36 
37  gpio_t memid_gpios[] = {GPP_E22, GPP_E23, GPP_H6};
38  return (u8)gpio_base2_value(memid_gpios, ARRAY_SIZE(memid_gpios));
39 }
40 
41 static bool is_dual_channel(const unsigned int memid)
42 {
43  return memid != 3 && memid != 5 && memid != 7;
44 }
45 
46 static void fill_spd_data(struct cnl_mb_cfg *mem_cfg)
47 {
48  const unsigned int memid = get_memory_config_straps();
49  printk(BIOS_DEBUG, "Memory config straps: 0x%.2x\n", memid);
50  /*
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
53  * .spd[2] as well.
54  */
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;
60  }
61 }
62 
63 void mainboard_memory_init_params(FSPM_UPD *memupd)
64 {
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,
69  .vref_ca_config = 2,
70  .ect = 0,
71  };
72 
73  const uint8_t vtd = get_uint_option("vtd", 1);
74  memupd->FspmTestConfig.VtdDisable = !vtd;
75 
76  const uint8_t ht =
77  get_uint_option("hyper_threading", memupd->FspmConfig.HyperThreading);
78  memupd->FspmConfig.HyperThreading = ht;
79 
81  cannonlake_memcfg_init(&memupd->FspmConfig, &memcfg);
82 }
#define GPP_H6
#define GPP_E23
#define GPP_E22
#define ARRAY_SIZE(a)
Definition: helpers.h:12
void cannonlake_memcfg_init(FSP_M_CONFIG *mem_cfg, const struct cnl_mb_cfg *cnl_cfg)
@ READ_SPD_CBFS
#define printk(level,...)
Definition: stdlib.h:16
uint32_t gpio_base2_value(const gpio_t gpio[], int num_gpio)
Definition: gpio.c:30
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
void mainboard_memory_init_params(FSPM_UPD *mupd)
Definition: romstage.c:22
static const struct cnl_mb_cfg memcfg
Definition: romstage.c:6
static bool is_dual_channel(const unsigned int memid)
Definition: romstage.c:41
static void fill_spd_data(struct cnl_mb_cfg *mem_cfg)
Definition: romstage.c:46
static unsigned int get_memory_config_straps(void)
Definition: romstage.c:11
unsigned int get_uint_option(const char *name, const unsigned int fallback)
Definition: option.c:116
uint8_t u8
Definition: stdint.h:45
unsigned char uint8_t
Definition: stdint.h:8
struct spd_info spd[NUM_DIMM_SLOT]
uint16_t rcomp_resistor[3]
union spd_info::spd_data_by spd_spec
enum mem_info_read_type read_type