blob: e3855bd794ae71b4e29294ae38d92d78e12e4519 [file] [log] [blame]
amanda_hwangb3b47e12018-03-08 11:04:40 +08001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright 2018 Google Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
Shelley Chen467cce42018-03-07 14:22:28 -080016#include <arch/cpu.h>
17#include <assert.h>
18#include <baseboard/variants.h>
Furquan Shaikhf5b7e802018-05-07 14:42:27 -070019#include <cbfs.h>
amanda_hwangb3b47e12018-03-08 11:04:40 +080020#include <chip.h>
Furquan Shaikhf5b7e802018-05-07 14:42:27 -070021#include <commonlib/cbfs_serialized.h>
Elyes HAOUAS20eaef02019-03-29 17:45:28 +010022#include <console/console.h>
amanda_hwangb3b47e12018-03-08 11:04:40 +080023#include <device/device.h>
Furquan Shaikhc6141b92018-05-10 21:58:39 -070024#include <drivers/intel/gma/opregion.h>
amanda_hwangb3b47e12018-03-08 11:04:40 +080025#include <ec/google/chromeec/ec.h>
Furquan Shaikhe3011452018-05-23 21:27:33 -070026#include <intelblocks/mp_init.h>
Shelley Chen467cce42018-03-07 14:22:28 -080027#include <smbios.h>
28#include <soc/ramstage.h>
29#include <string.h>
amanda_hwang04ccd5f2018-03-16 13:43:52 +080030#include <variant/sku.h>
amanda_hwangb3b47e12018-03-08 11:04:40 +080031
Furquan Shaikhe3011452018-05-23 21:27:33 -070032#define PL2_I7_SKU 44
33#define PL2_DEFAULT 29
John Su2257a352018-10-25 19:21:15 +080034#define PL2_KBL_U 25
35
36/* PL2 ID define*/
37#define PL2_ID_DEFAULT 0
38#define PL2_ID_SONA_SYNDRA 1
Ren Kuoa355b162018-12-12 14:39:36 +080039#define PL2_ID_BARD_EKKO 2
John Su2257a352018-10-25 19:21:15 +080040
41static const struct pl2_config {
42 uint32_t cpuid_y0_pl2;
43 uint32_t cpuid_non_y0_pl2;
44} pl2_config_table[] = {
45 [PL2_ID_DEFAULT] = { PL2_I7_SKU, PL2_DEFAULT },
46 [PL2_ID_SONA_SYNDRA] = { PL2_DEFAULT, PL2_KBL_U },
Ren Kuoa355b162018-12-12 14:39:36 +080047 [PL2_ID_BARD_EKKO] = { PL2_DEFAULT, PL2_KBL_U },
John Su2257a352018-10-25 19:21:15 +080048};
Furquan Shaikhe3011452018-05-23 21:27:33 -070049
Gaggery Tsai70627772018-07-26 00:14:09 -070050/* Variant for AKALI */
51#define AKALI_SA_AC_LOADLINE 1100
52#define AKALI_SA_DC_LOADLINE 1028
53#define AKALI_IA_AC_LOADLINE 272
54#define AKALI_IA_DC_LOADLINE 247
55#define AKALI_GT_AC_LOADLINE 314
56#define AKALI_GT_DC_LOADLINE 321
57
58/* We only have Akali and Nami default settings so far */
59enum project_sku {
60 PRJ_AKALI = 1,
61};
62
63static const struct {
64 enum project_sku sku;
65 int ac_loadline[NUM_VR_DOMAINS];
66 int dc_loadline[NUM_VR_DOMAINS];
67} sku_overwrite_mapping[] = {
68 {
69 .sku = PRJ_AKALI,
70 .ac_loadline = {
71 AKALI_SA_AC_LOADLINE,
72 AKALI_IA_AC_LOADLINE,
73 AKALI_GT_AC_LOADLINE,
74 AKALI_GT_AC_LOADLINE
75 },
76 .dc_loadline = {
77 AKALI_SA_DC_LOADLINE,
78 AKALI_IA_DC_LOADLINE,
79 AKALI_GT_DC_LOADLINE,
80 AKALI_GT_DC_LOADLINE
81 }
82 },
83};
84
John Su2257a352018-10-25 19:21:15 +080085static uint32_t get_pl2(int pl2_id)
Furquan Shaikhe3011452018-05-23 21:27:33 -070086{
John Su2257a352018-10-25 19:21:15 +080087 assert(pl2_id < ARRAY_SIZE(pl2_config_table));
Furquan Shaikhe3011452018-05-23 21:27:33 -070088 if (cpuid_eax(1) == CPUID_KABYLAKE_Y0)
John Su2257a352018-10-25 19:21:15 +080089 return pl2_config_table[pl2_id].cpuid_y0_pl2;
Furquan Shaikhe3011452018-05-23 21:27:33 -070090
John Su2257a352018-10-25 19:21:15 +080091 return pl2_config_table[pl2_id].cpuid_non_y0_pl2;
Furquan Shaikhe3011452018-05-23 21:27:33 -070092}
93
Zhuohao Leef7b59552018-03-17 05:00:49 +080094uint32_t variant_board_sku(void)
amanda_hwangb3b47e12018-03-08 11:04:40 +080095{
Zhuohao Leef7b59552018-03-17 05:00:49 +080096 static uint32_t sku_id = SKU_UNKNOWN;
amanda_hwangb3b47e12018-03-08 11:04:40 +080097 uint32_t id;
Zhuohao Leef7b59552018-03-17 05:00:49 +080098
99 if (sku_id != SKU_UNKNOWN)
amanda_hwangb3b47e12018-03-08 11:04:40 +0800100 return sku_id;
101 if (google_chromeec_cbi_get_sku_id(&id))
102 return SKU_UNKNOWN;
103 sku_id = id;
Zhuohao Leef7b59552018-03-17 05:00:49 +0800104
amanda_hwangb3b47e12018-03-08 11:04:40 +0800105 return sku_id;
106}
107
Nico Huberebd8a4f2017-11-01 09:49:16 +0100108const char *smbios_system_sku(void)
Shelley Chen467cce42018-03-07 14:22:28 -0800109{
Zhuohao Leef7b59552018-03-17 05:00:49 +0800110 static char sku_str[14]; /* sku{0..4294967295} */
Shelley Chen467cce42018-03-07 14:22:28 -0800111
Zhuohao Leef7b59552018-03-17 05:00:49 +0800112 snprintf(sku_str, sizeof(sku_str), "sku%u", variant_board_sku());
Shelley Chen467cce42018-03-07 14:22:28 -0800113
114 return sku_str;
115}
Furquan Shaikhf5b7e802018-05-07 14:42:27 -0700116
117#define OEM_UNKNOWN 0xff
118
119/*
120 * Read OEM ID from EC using cbi commands.
121 * Return value:
122 * Success = OEM ID read from EC
123 * Failure = OEM_UNKNOWN (0xff)
124 */
125static uint8_t read_oem_id(void)
126{
127 static uint8_t oem_id = OEM_UNKNOWN;
128 uint32_t id;
129
130 if (oem_id != OEM_UNKNOWN)
131 return oem_id;
132
133 if (google_chromeec_cbi_get_oem_id(&id))
134 return OEM_UNKNOWN;
135
136 if (id > OEM_UNKNOWN) {
137 printk(BIOS_ERR, "%s: OEM ID too big %u!\n", __func__, id);
138 return OEM_UNKNOWN;
139 }
140
141 oem_id = id;
142 printk(BIOS_DEBUG, "%s: OEM ID=%d\n", __func__, oem_id);
143
144 return oem_id;
145}
146
147/* "oem.bin" in cbfs contains array of records using the following structure. */
148struct oem_mapping {
149 uint8_t oem_id;
150 char oem_name[10];
151} __packed;
152
153/* Local buffer to read "oem.bin" */
154static char oem_bin_data[200];
155
156const char *smbios_mainboard_manufacturer(void)
157{
158 uint8_t oem_id = read_oem_id();
159 const struct oem_mapping *oem_entry = (void *)&oem_bin_data;
160 size_t oem_data_size;
161 size_t curr = 0;
162 static const char *manuf;
163
164 if (manuf)
165 return manuf;
166
167 /* If OEM ID cannot be determined, return default manuf string. */
168 if (oem_id == OEM_UNKNOWN)
169 return CONFIG_MAINBOARD_SMBIOS_MANUFACTURER;
170
171 oem_data_size = cbfs_boot_load_file("oem.bin", oem_bin_data,
172 sizeof(oem_bin_data),
173 CBFS_TYPE_RAW);
174
175 while ((curr < oem_data_size) &&
176 ((oem_data_size - curr) >= sizeof(*oem_entry))) {
177 if (oem_id == oem_entry->oem_id) {
178 manuf = oem_entry->oem_name;
179 break;
180 }
181 curr += sizeof(*oem_entry);
182 oem_entry++;
183 }
184
185 if (manuf == NULL)
186 manuf = CONFIG_MAINBOARD_SMBIOS_MANUFACTURER;
187
188 return manuf;
189}
Furquan Shaikhc6141b92018-05-10 21:58:39 -0700190
191const char *mainboard_vbt_filename(void)
192{
193 uint32_t sku_id = variant_board_sku();
194
195 switch (sku_id) {
Ivy Jianfaafbfb2018-05-14 09:38:20 +0800196 case SKU_0_PANTHEON:
197 case SKU_1_PANTHEON:
Ivy Jian457253c2018-07-11 14:15:29 +0800198 case SKU_2_PANTHEON:
John Suc2209e42019-03-05 10:41:46 +0800199 case SKU_3_PANTHEON:
200 case SKU_4_PANTHEON:
Ivy Jianfaafbfb2018-05-14 09:38:20 +0800201 return "vbt-pantheon.bin";
Ivy Jian8bd5c5f2018-06-01 15:43:56 +0800202 case SKU_0_VAYNE:
203 case SKU_1_VAYNE:
204 case SKU_2_VAYNE:
205 return "vbt-vayne.bin";
T.H. Lin770b0342018-07-17 16:09:04 +0800206 case SKU_0_AKALI:
207 case SKU_1_AKALI:
208 case SKU_0_AKALI360:
209 case SKU_1_AKALI360:
210 return "vbt-akali.bin";
Ren Kuo337afb02018-12-22 15:04:56 +0800211 case SKU_0_BARD:
212 case SKU_1_BARD:
213 case SKU_2_BARD:
214 case SKU_3_BARD:
Ren Kuodeab64d2019-07-19 11:10:10 +0800215 case SKU_4_BARD:
216 case SKU_5_BARD:
Ren Kuo02240b72019-08-27 16:17:24 +0800217 case SKU_6_BARD:
218 case SKU_7_BARD:
Ren Kuo337afb02018-12-22 15:04:56 +0800219 return "vbt-bard.bin";
Furquan Shaikhc6141b92018-05-10 21:58:39 -0700220 default:
221 return "vbt.bin";
Furquan Shaikhc6141b92018-05-10 21:58:39 -0700222 }
223}
Gaggery Tsai70627772018-07-26 00:14:09 -0700224
225static int find_sku_mapping(const uint8_t oem_id)
226{
227 /* Check if this OEM ID has a mapping table entry. */
228 for (int i = 0; i < ARRAY_SIZE(sku_overwrite_mapping); i++)
229 if (oem_id == sku_overwrite_mapping[i].sku)
230 return i;
231
232 return -1;
233}
234
235/* Override dev tree settings per board */
236void variant_devtree_update(void)
237{
238 uint32_t sku_id = variant_board_sku();
239 uint32_t i;
240 int oem_index;
John Su2257a352018-10-25 19:21:15 +0800241 uint8_t pl2_id = PL2_ID_DEFAULT;
Ivy Jianb80d1322019-05-27 11:19:44 +0800242 struct device *spi_fpmcu = PCH_DEV_GSPI1;
Gaggery Tsai70627772018-07-26 00:14:09 -0700243
Kyösti Mälkkid5f645c2019-09-28 00:20:27 +0300244 config_t *cfg = config_of_soc();
Kyösti Mälkki28dc7dc2019-07-12 13:10:19 +0300245
Gaggery Tsai70627772018-07-26 00:14:09 -0700246 switch (sku_id) {
Gaggery Tsai70627772018-07-26 00:14:09 -0700247 case SKU_0_SONA:
248 case SKU_1_SONA:
Amanda Huangf7b57d02018-10-11 11:39:37 +0800249 case SKU_0_SYNDRA:
250 case SKU_1_SYNDRA:
251 case SKU_2_SYNDRA:
252 case SKU_3_SYNDRA:
Amanda Huang3080fe02018-12-17 13:25:03 +0800253 case SKU_4_SYNDRA:
254 case SKU_5_SYNDRA:
255 case SKU_6_SYNDRA:
256 case SKU_7_SYNDRA:
John Su2257a352018-10-25 19:21:15 +0800257 pl2_id = PL2_ID_SONA_SYNDRA;
Jacob Garber38b74452019-05-31 14:43:19 -0600258 /* fallthrough */
John Su2257a352018-10-25 19:21:15 +0800259 case SKU_0_VAYNE:
260 case SKU_1_VAYNE:
261 case SKU_2_VAYNE:
262 case SKU_0_PANTHEON:
263 case SKU_1_PANTHEON:
264 case SKU_2_PANTHEON:
Frank Wud0cc3bc2018-12-24 11:25:36 +0800265 case SKU_3_PANTHEON:
266 case SKU_4_PANTHEON:
Gaggery Tsai70627772018-07-26 00:14:09 -0700267 cfg->usb2_ports[5].enable = 0;
Ivy Jianb80d1322019-05-27 11:19:44 +0800268 spi_fpmcu->enabled = 0;
Gaggery Tsai70627772018-07-26 00:14:09 -0700269 break;
Ren Kuoa355b162018-12-12 14:39:36 +0800270 case SKU_0_BARD:
271 case SKU_1_BARD:
272 case SKU_2_BARD:
273 case SKU_3_BARD:
Ren Kuodeab64d2019-07-19 11:10:10 +0800274 case SKU_4_BARD:
275 case SKU_5_BARD:
Ren Kuo02240b72019-08-27 16:17:24 +0800276 case SKU_6_BARD:
277 case SKU_7_BARD:
Ren Kuoa355b162018-12-12 14:39:36 +0800278 case SKU_0_EKKO:
279 case SKU_1_EKKO:
280 case SKU_2_EKKO:
281 case SKU_3_EKKO:
Ren Kuo02240b72019-08-27 16:17:24 +0800282 case SKU_4_EKKO:
283 case SKU_5_EKKO:
284 case SKU_6_EKKO:
285 case SKU_7_EKKO:
Ren Kuoa355b162018-12-12 14:39:36 +0800286 pl2_id = PL2_ID_BARD_EKKO;
Ren Kuo03f654c2019-01-18 17:12:33 +0800287 cfg->usb2_ports[5].enable = 0;
288 cfg->usb2_ports[7].enable = 0;
289 cfg->usb2_ports[8].enable = 0;
290 cfg->usb2_ports[9].enable = 0;
Ren Kuoa355b162018-12-12 14:39:36 +0800291 break;
Gaggery Tsai70627772018-07-26 00:14:09 -0700292 default:
293 break;
294 }
295
John Su2257a352018-10-25 19:21:15 +0800296 /* Update PL2 based on SKU. */
297 cfg->tdp_pl2_override = get_pl2(pl2_id);
298
Gaggery Tsai70627772018-07-26 00:14:09 -0700299 /* Overwrite settings for different projects based on OEM ID*/
300 oem_index = find_sku_mapping(read_oem_id());
301
302 /* Return if the OEM ID is not supported or no changes are required */
303 if (oem_index < 0)
304 return;
305
306 for (i = 0; i < ARRAY_SIZE(cfg->domain_vr_config); i++) {
307 cfg->domain_vr_config[i].ac_loadline =
308 sku_overwrite_mapping[oem_index].ac_loadline[i];
309 cfg->domain_vr_config[i].dc_loadline =
310 sku_overwrite_mapping[oem_index].dc_loadline[i];
311 }
312}