coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
mainboard.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <arch/cpu.h>
4 #include <assert.h>
5 #include <baseboard/variants.h>
6 #include <cbfs.h>
7 #include <chip.h>
8 #include <console/console.h>
9 #include <cpu/intel/cpu_ids.h>
10 #include <device/device.h>
12 #include <ec/google/chromeec/ec.h>
14 #include <smbios.h>
15 #include <soc/ramstage.h>
16 #include <string.h>
17 #include <variant/sku.h>
18 
19 #define PL2_I7_SKU 44
20 #define PL2_DEFAULT 29
21 #define PL2_KBL_U 25
22 
23 /* PL2 ID define*/
24 #define PL2_ID_DEFAULT 0
25 #define PL2_ID_SONA_SYNDRA 1
26 #define PL2_ID_BARD_EKKO 2
27 
28 static const struct pl2_config {
31 } pl2_config_table[] = {
35 };
36 
37 /* Variant for AKALI */
38 #define AKALI_SA_AC_LOADLINE 1100
39 #define AKALI_SA_DC_LOADLINE 1028
40 #define AKALI_IA_AC_LOADLINE 272
41 #define AKALI_IA_DC_LOADLINE 247
42 #define AKALI_GT_AC_LOADLINE 314
43 #define AKALI_GT_DC_LOADLINE 321
44 
45 /* We only have Akali and Nami default settings so far */
47  PRJ_AKALI = 1,
48 };
49 
50 static const struct {
51  enum project_sku sku;
55  {
56  .sku = PRJ_AKALI,
57  .ac_loadline = {
62  },
63  .dc_loadline = {
68  }
69  },
70 };
71 
72 static uint32_t get_pl2(int pl2_id)
73 {
75  if (cpuid_eax(1) == CPUID_KABYLAKE_Y0)
76  return pl2_config_table[pl2_id].cpuid_y0_pl2;
77 
78  return pl2_config_table[pl2_id].cpuid_non_y0_pl2;
79 }
80 
82 {
83  static uint32_t sku_id = SKU_UNKNOWN;
84  uint32_t id;
85 
86  if (sku_id != SKU_UNKNOWN)
87  return sku_id;
89  return SKU_UNKNOWN;
90  sku_id = id;
91 
92  return sku_id;
93 }
94 
95 const char *smbios_system_sku(void)
96 {
97  static char sku_str[14]; /* sku{0..4294967295} */
98 
99  snprintf(sku_str, sizeof(sku_str), "sku%u", variant_board_sku());
100 
101  return sku_str;
102 }
103 
104 #define OEM_UNKNOWN 0xff
105 
106 /*
107  * Read OEM ID from EC using cbi commands.
108  * Return value:
109  * Success = OEM ID read from EC
110  * Failure = OEM_UNKNOWN (0xff)
111  */
112 static uint8_t read_oem_id(void)
113 {
114  static uint8_t oem_id = OEM_UNKNOWN;
115  uint32_t id;
116 
117  if (oem_id != OEM_UNKNOWN)
118  return oem_id;
119 
121  return OEM_UNKNOWN;
122 
123  if (id > OEM_UNKNOWN) {
124  printk(BIOS_ERR, "%s: OEM ID too big %u!\n", __func__, id);
125  return OEM_UNKNOWN;
126  }
127 
128  oem_id = id;
129  printk(BIOS_DEBUG, "%s: OEM ID=%d\n", __func__, oem_id);
130 
131  return oem_id;
132 }
133 
134 /* "oem.bin" in cbfs contains array of records using the following structure. */
135 struct oem_mapping {
137  char oem_name[10];
139 
140 /* Local buffer to read "oem.bin" */
141 static char oem_bin_data[200];
142 
144 {
145  uint8_t oem_id = read_oem_id();
146  const struct oem_mapping *oem_entry = (void *)&oem_bin_data;
147  size_t oem_data_size;
148  size_t curr = 0;
149  static const char *manuf;
150 
151  if (manuf)
152  return manuf;
153 
154  /* If OEM ID cannot be determined, return default manuf string. */
155  if (oem_id == OEM_UNKNOWN)
156  return CONFIG_MAINBOARD_SMBIOS_MANUFACTURER;
157 
158  oem_data_size = cbfs_load("oem.bin", oem_bin_data,
159  sizeof(oem_bin_data));
160 
161  while ((curr < oem_data_size) &&
162  ((oem_data_size - curr) >= sizeof(*oem_entry))) {
163  if (oem_id == oem_entry->oem_id) {
164  manuf = oem_entry->oem_name;
165  break;
166  }
167  curr += sizeof(*oem_entry);
168  oem_entry++;
169  }
170 
171  if (manuf == NULL)
172  manuf = CONFIG_MAINBOARD_SMBIOS_MANUFACTURER;
173 
174  return manuf;
175 }
176 
177 const char *mainboard_vbt_filename(void)
178 {
180 
181  switch (sku_id) {
182  case SKU_0_PANTHEON:
183  case SKU_1_PANTHEON:
184  case SKU_2_PANTHEON:
185  case SKU_3_PANTHEON:
186  case SKU_4_PANTHEON:
187  return "vbt-pantheon.bin";
188  case SKU_0_VAYNE:
189  case SKU_1_VAYNE:
190  case SKU_2_VAYNE:
191  return "vbt-vayne.bin";
192  case SKU_0_AKALI:
193  case SKU_1_AKALI:
194  case SKU_0_AKALI360:
195  case SKU_1_AKALI360:
196  return "vbt-akali.bin";
197  case SKU_0_BARD:
198  case SKU_1_BARD:
199  case SKU_2_BARD:
200  case SKU_3_BARD:
201  case SKU_4_BARD:
202  case SKU_5_BARD:
203  case SKU_6_BARD:
204  case SKU_7_BARD:
205  return "vbt-bard.bin";
206  default:
207  return "vbt.bin";
208  }
209 }
210 
211 static int find_sku_mapping(const uint8_t oem_id)
212 {
213  /* Check if this OEM ID has a mapping table entry. */
214  for (int i = 0; i < ARRAY_SIZE(sku_overwrite_mapping); i++)
215  if (oem_id == sku_overwrite_mapping[i].sku)
216  return i;
217 
218  return -1;
219 }
220 
221 /* Override dev tree settings per board */
223 {
225  uint32_t i;
226  int oem_index;
227  uint8_t pl2_id = PL2_ID_DEFAULT;
228  struct device *spi_fpmcu = PCH_DEV_GSPI1;
229 
230  config_t *cfg = config_of_soc();
231 
232  switch (sku_id) {
233  case SKU_0_SONA:
234  case SKU_1_SONA:
235  case SKU_0_SYNDRA:
236  case SKU_1_SYNDRA:
237  case SKU_2_SYNDRA:
238  case SKU_3_SYNDRA:
239  case SKU_4_SYNDRA:
240  case SKU_5_SYNDRA:
241  case SKU_6_SYNDRA:
242  case SKU_7_SYNDRA:
243  pl2_id = PL2_ID_SONA_SYNDRA;
245  case SKU_0_VAYNE:
246  case SKU_1_VAYNE:
247  case SKU_2_VAYNE:
248  case SKU_0_PANTHEON:
249  case SKU_1_PANTHEON:
250  case SKU_2_PANTHEON:
251  case SKU_3_PANTHEON:
252  case SKU_4_PANTHEON:
253  cfg->usb2_ports[5].enable = 0;
254  spi_fpmcu->enabled = 0;
255  break;
256  case SKU_0_BARD:
257  case SKU_1_BARD:
258  case SKU_2_BARD:
259  case SKU_3_BARD:
260  case SKU_4_BARD:
261  case SKU_5_BARD:
262  case SKU_6_BARD:
263  case SKU_7_BARD:
264  case SKU_0_EKKO:
265  case SKU_1_EKKO:
266  case SKU_2_EKKO:
267  case SKU_3_EKKO:
268  case SKU_4_EKKO:
269  case SKU_5_EKKO:
270  case SKU_6_EKKO:
271  case SKU_7_EKKO:
272  pl2_id = PL2_ID_BARD_EKKO;
273  cfg->usb2_ports[5].enable = 0;
274  cfg->usb2_ports[7].enable = 0;
275  cfg->usb2_ports[8].enable = 0;
276  cfg->usb2_ports[9].enable = 0;
277  break;
278  default:
279  break;
280  }
281 
282  struct soc_power_limits_config *soc_conf;
283  soc_conf = &cfg->power_limits_config;
284 
285  /* Update PL2 based on SKU. */
286  soc_conf->tdp_pl2_override = get_pl2(pl2_id);
287 
288  /* Overwrite settings for different projects based on OEM ID*/
289  oem_index = find_sku_mapping(read_oem_id());
290 
291  /* Return if the OEM ID is not supported or no changes are required */
292  if (oem_index < 0)
293  return;
294 
295  for (i = 0; i < ARRAY_SIZE(cfg->domain_vr_config); i++) {
296  cfg->domain_vr_config[i].ac_loadline =
297  sku_overwrite_mapping[oem_index].ac_loadline[i];
298  cfg->domain_vr_config[i].dc_loadline =
299  sku_overwrite_mapping[oem_index].dc_loadline[i];
300  }
301 }
@ NUM_VR_DOMAINS
Definition: vr_config.h:43
static unsigned int cpuid_eax(unsigned int op)
Definition: cpu.h:79
#define assert(statement)
Definition: assert.h:74
#define ARRAY_SIZE(a)
Definition: helpers.h:12
static size_t cbfs_load(const char *name, void *buf, size_t size)
Definition: cbfs.h:282
#define printk(level,...)
Definition: stdlib.h:16
#define __fallthrough
Definition: compiler.h:39
#define CPUID_KABYLAKE_Y0
Definition: cpu_ids.h:20
int google_chromeec_cbi_get_oem_id(uint32_t *id)
Get data from Cros Board Info.
Definition: ec.c:865
int google_chromeec_cbi_get_sku_id(uint32_t *id)
Definition: ec.c:839
void __weak variant_devtree_update(void)
Definition: mainboard.c:86
const char * smbios_system_sku(void)
Definition: mainboard.c:174
uint8_t __weak variant_board_sku(void)
Definition: mainboard.c:172
const char * smbios_mainboard_manufacturer(void)
Definition: mainboard.c:32
uint32_t sku_id(void)
Definition: mainboard.c:11
#define PL2_ID_BARD_EKKO
Definition: mainboard.c:26
enum project_sku sku
Definition: mainboard.c:51
static char oem_bin_data[200]
Definition: mainboard.c:141
#define PL2_ID_DEFAULT
Definition: mainboard.c:24
#define PL2_DEFAULT
Definition: mainboard.c:20
#define OEM_UNKNOWN
Definition: mainboard.c:104
int ac_loadline[NUM_VR_DOMAINS]
Definition: mainboard.c:52
#define PL2_I7_SKU
Definition: mainboard.c:19
#define AKALI_SA_DC_LOADLINE
Definition: mainboard.c:39
project_sku
Definition: mainboard.c:46
@ PRJ_AKALI
Definition: mainboard.c:47
static uint32_t get_pl2(int pl2_id)
Definition: mainboard.c:72
struct oem_mapping __packed
static const struct pl2_config pl2_config_table[]
#define PL2_KBL_U
Definition: mainboard.c:21
int dc_loadline[NUM_VR_DOMAINS]
Definition: mainboard.c:53
static const struct @295 sku_overwrite_mapping[]
const char * mainboard_vbt_filename(void)
Definition: mainboard.c:177
static uint8_t read_oem_id(void)
Definition: mainboard.c:112
#define AKALI_GT_AC_LOADLINE
Definition: mainboard.c:42
#define PL2_ID_SONA_SYNDRA
Definition: mainboard.c:25
#define AKALI_IA_DC_LOADLINE
Definition: mainboard.c:41
static int find_sku_mapping(const uint8_t oem_id)
Definition: mainboard.c:211
#define AKALI_SA_AC_LOADLINE
Definition: mainboard.c:38
#define AKALI_IA_AC_LOADLINE
Definition: mainboard.c:40
#define AKALI_GT_DC_LOADLINE
Definition: mainboard.c:43
@ SKU_UNKNOWN
Definition: mainboard.c:12
#define config_of_soc()
Definition: device.h:394
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
Definition: loglevel.h:72
#define SKU_6_BARD
Definition: sku.h:44
#define SKU_0_AKALI
Definition: sku.h:18
#define SKU_0_VAYNE
Definition: sku.h:8
#define SKU_6_SYNDRA
Definition: sku.h:28
#define SKU_7_EKKO
Definition: sku.h:37
#define SKU_1_VAYNE
Definition: sku.h:9
#define SKU_7_BARD
Definition: sku.h:45
#define SKU_0_BARD
Definition: sku.h:38
#define SKU_2_VAYNE
Definition: sku.h:10
#define SKU_3_BARD
Definition: sku.h:41
#define SKU_4_BARD
Definition: sku.h:42
#define SKU_1_SYNDRA
Definition: sku.h:23
#define SKU_4_EKKO
Definition: sku.h:34
#define SKU_2_BARD
Definition: sku.h:40
#define SKU_3_PANTHEON
Definition: sku.h:14
#define SKU_0_SYNDRA
Definition: sku.h:22
#define SKU_7_SYNDRA
Definition: sku.h:29
#define SKU_0_PANTHEON
Definition: sku.h:11
#define SKU_5_SYNDRA
Definition: sku.h:27
#define SKU_1_PANTHEON
Definition: sku.h:12
#define SKU_0_AKALI360
Definition: sku.h:20
#define SKU_0_SONA
Definition: sku.h:16
#define SKU_4_SYNDRA
Definition: sku.h:26
#define SKU_1_EKKO
Definition: sku.h:31
#define SKU_1_AKALI
Definition: sku.h:19
#define SKU_0_EKKO
Definition: sku.h:30
#define SKU_1_AKALI360
Definition: sku.h:21
#define SKU_5_BARD
Definition: sku.h:43
#define SKU_5_EKKO
Definition: sku.h:35
#define SKU_4_PANTHEON
Definition: sku.h:15
#define SKU_2_PANTHEON
Definition: sku.h:13
#define SKU_1_SONA
Definition: sku.h:17
#define SKU_6_EKKO
Definition: sku.h:36
#define SKU_1_BARD
Definition: sku.h:39
#define SKU_3_SYNDRA
Definition: sku.h:25
#define SKU_2_EKKO
Definition: sku.h:32
#define SKU_2_SYNDRA
Definition: sku.h:24
#define SKU_3_EKKO
Definition: sku.h:33
#define PCH_DEV_GSPI1
Definition: pci_devs.h:211
#define NULL
Definition: stddef.h:19
unsigned int uint32_t
Definition: stdint.h:14
unsigned char uint8_t
Definition: stdint.h:8
Definition: device.h:107
unsigned int enabled
Definition: device.h:122
char oem_name[10]
Definition: mainboard.c:137
uint8_t oem_id
Definition: mainboard.c:136
uint32_t cpuid_y0_pl2
Definition: mainboard.c:29
uint32_t cpuid_non_y0_pl2
Definition: mainboard.c:30
int snprintf(char *buf, size_t size, const char *fmt,...)
Note: This file is only for POSIX compatibility, and is meant to be chain-included via string....
Definition: vsprintf.c:35