blob: e279693511ba83efc90ed8091f9873995a450559 [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>
amanda_hwangb3b47e12018-03-08 11:04:40 +080022#include <device/device.h>
Furquan Shaikhc6141b92018-05-10 21:58:39 -070023#include <drivers/intel/gma/opregion.h>
amanda_hwangb3b47e12018-03-08 11:04:40 +080024#include <ec/google/chromeec/ec.h>
Furquan Shaikhe3011452018-05-23 21:27:33 -070025#include <intelblocks/mp_init.h>
Shelley Chen467cce42018-03-07 14:22:28 -080026#include <smbios.h>
27#include <soc/ramstage.h>
28#include <string.h>
amanda_hwang04ccd5f2018-03-16 13:43:52 +080029#include <variant/sku.h>
amanda_hwangb3b47e12018-03-08 11:04:40 +080030
Furquan Shaikhe3011452018-05-23 21:27:33 -070031#define PL2_I7_SKU 44
32#define PL2_DEFAULT 29
John Su2257a352018-10-25 19:21:15 +080033#define PL2_KBL_U 25
34
35/* PL2 ID define*/
36#define PL2_ID_DEFAULT 0
37#define PL2_ID_SONA_SYNDRA 1
Ren Kuoa355b162018-12-12 14:39:36 +080038#define PL2_ID_BARD_EKKO 2
John Su2257a352018-10-25 19:21:15 +080039
40static const struct pl2_config {
41 uint32_t cpuid_y0_pl2;
42 uint32_t cpuid_non_y0_pl2;
43} pl2_config_table[] = {
44 [PL2_ID_DEFAULT] = { PL2_I7_SKU, PL2_DEFAULT },
45 [PL2_ID_SONA_SYNDRA] = { PL2_DEFAULT, PL2_KBL_U },
Ren Kuoa355b162018-12-12 14:39:36 +080046 [PL2_ID_BARD_EKKO] = { PL2_DEFAULT, PL2_KBL_U },
John Su2257a352018-10-25 19:21:15 +080047};
Furquan Shaikhe3011452018-05-23 21:27:33 -070048
Gaggery Tsai70627772018-07-26 00:14:09 -070049/* Variant for AKALI */
50#define AKALI_SA_AC_LOADLINE 1100
51#define AKALI_SA_DC_LOADLINE 1028
52#define AKALI_IA_AC_LOADLINE 272
53#define AKALI_IA_DC_LOADLINE 247
54#define AKALI_GT_AC_LOADLINE 314
55#define AKALI_GT_DC_LOADLINE 321
56
57/* We only have Akali and Nami default settings so far */
58enum project_sku {
59 PRJ_AKALI = 1,
60};
61
62static const struct {
63 enum project_sku sku;
64 int ac_loadline[NUM_VR_DOMAINS];
65 int dc_loadline[NUM_VR_DOMAINS];
66} sku_overwrite_mapping[] = {
67 {
68 .sku = PRJ_AKALI,
69 .ac_loadline = {
70 AKALI_SA_AC_LOADLINE,
71 AKALI_IA_AC_LOADLINE,
72 AKALI_GT_AC_LOADLINE,
73 AKALI_GT_AC_LOADLINE
74 },
75 .dc_loadline = {
76 AKALI_SA_DC_LOADLINE,
77 AKALI_IA_DC_LOADLINE,
78 AKALI_GT_DC_LOADLINE,
79 AKALI_GT_DC_LOADLINE
80 }
81 },
82};
83
John Su2257a352018-10-25 19:21:15 +080084static uint32_t get_pl2(int pl2_id)
Furquan Shaikhe3011452018-05-23 21:27:33 -070085{
John Su2257a352018-10-25 19:21:15 +080086 assert(pl2_id < ARRAY_SIZE(pl2_config_table));
Furquan Shaikhe3011452018-05-23 21:27:33 -070087 if (cpuid_eax(1) == CPUID_KABYLAKE_Y0)
John Su2257a352018-10-25 19:21:15 +080088 return pl2_config_table[pl2_id].cpuid_y0_pl2;
Furquan Shaikhe3011452018-05-23 21:27:33 -070089
John Su2257a352018-10-25 19:21:15 +080090 return pl2_config_table[pl2_id].cpuid_non_y0_pl2;
Furquan Shaikhe3011452018-05-23 21:27:33 -070091}
92
Zhuohao Leef7b59552018-03-17 05:00:49 +080093uint32_t variant_board_sku(void)
amanda_hwangb3b47e12018-03-08 11:04:40 +080094{
Zhuohao Leef7b59552018-03-17 05:00:49 +080095 static uint32_t sku_id = SKU_UNKNOWN;
amanda_hwangb3b47e12018-03-08 11:04:40 +080096 uint32_t id;
Zhuohao Leef7b59552018-03-17 05:00:49 +080097
98 if (sku_id != SKU_UNKNOWN)
amanda_hwangb3b47e12018-03-08 11:04:40 +080099 return sku_id;
100 if (google_chromeec_cbi_get_sku_id(&id))
101 return SKU_UNKNOWN;
102 sku_id = id;
Zhuohao Leef7b59552018-03-17 05:00:49 +0800103
amanda_hwangb3b47e12018-03-08 11:04:40 +0800104 return sku_id;
105}
106
Shelley Chen467cce42018-03-07 14:22:28 -0800107const char *smbios_mainboard_sku(void)
108{
Zhuohao Leef7b59552018-03-17 05:00:49 +0800109 static char sku_str[14]; /* sku{0..4294967295} */
Shelley Chen467cce42018-03-07 14:22:28 -0800110
Zhuohao Leef7b59552018-03-17 05:00:49 +0800111 snprintf(sku_str, sizeof(sku_str), "sku%u", variant_board_sku());
Shelley Chen467cce42018-03-07 14:22:28 -0800112
113 return sku_str;
114}
Furquan Shaikhf5b7e802018-05-07 14:42:27 -0700115
116#define OEM_UNKNOWN 0xff
117
118/*
119 * Read OEM ID from EC using cbi commands.
120 * Return value:
121 * Success = OEM ID read from EC
122 * Failure = OEM_UNKNOWN (0xff)
123 */
124static uint8_t read_oem_id(void)
125{
126 static uint8_t oem_id = OEM_UNKNOWN;
127 uint32_t id;
128
129 if (oem_id != OEM_UNKNOWN)
130 return oem_id;
131
132 if (google_chromeec_cbi_get_oem_id(&id))
133 return OEM_UNKNOWN;
134
135 if (id > OEM_UNKNOWN) {
136 printk(BIOS_ERR, "%s: OEM ID too big %u!\n", __func__, id);
137 return OEM_UNKNOWN;
138 }
139
140 oem_id = id;
141 printk(BIOS_DEBUG, "%s: OEM ID=%d\n", __func__, oem_id);
142
143 return oem_id;
144}
145
146/* "oem.bin" in cbfs contains array of records using the following structure. */
147struct oem_mapping {
148 uint8_t oem_id;
149 char oem_name[10];
150} __packed;
151
152/* Local buffer to read "oem.bin" */
153static char oem_bin_data[200];
154
155const char *smbios_mainboard_manufacturer(void)
156{
157 uint8_t oem_id = read_oem_id();
158 const struct oem_mapping *oem_entry = (void *)&oem_bin_data;
159 size_t oem_data_size;
160 size_t curr = 0;
161 static const char *manuf;
162
163 if (manuf)
164 return manuf;
165
166 /* If OEM ID cannot be determined, return default manuf string. */
167 if (oem_id == OEM_UNKNOWN)
168 return CONFIG_MAINBOARD_SMBIOS_MANUFACTURER;
169
170 oem_data_size = cbfs_boot_load_file("oem.bin", oem_bin_data,
171 sizeof(oem_bin_data),
172 CBFS_TYPE_RAW);
173
174 while ((curr < oem_data_size) &&
175 ((oem_data_size - curr) >= sizeof(*oem_entry))) {
176 if (oem_id == oem_entry->oem_id) {
177 manuf = oem_entry->oem_name;
178 break;
179 }
180 curr += sizeof(*oem_entry);
181 oem_entry++;
182 }
183
184 if (manuf == NULL)
185 manuf = CONFIG_MAINBOARD_SMBIOS_MANUFACTURER;
186
187 return manuf;
188}
Furquan Shaikhc6141b92018-05-10 21:58:39 -0700189
190const char *mainboard_vbt_filename(void)
191{
192 uint32_t sku_id = variant_board_sku();
193
194 switch (sku_id) {
Ivy Jianfaafbfb2018-05-14 09:38:20 +0800195 case SKU_0_PANTHEON:
196 case SKU_1_PANTHEON:
Ivy Jian457253c2018-07-11 14:15:29 +0800197 case SKU_2_PANTHEON:
John Suc2209e42019-03-05 10:41:46 +0800198 case SKU_3_PANTHEON:
199 case SKU_4_PANTHEON:
Ivy Jianfaafbfb2018-05-14 09:38:20 +0800200 return "vbt-pantheon.bin";
Ivy Jian8bd5c5f2018-06-01 15:43:56 +0800201 case SKU_0_VAYNE:
202 case SKU_1_VAYNE:
203 case SKU_2_VAYNE:
204 return "vbt-vayne.bin";
T.H. Lin770b0342018-07-17 16:09:04 +0800205 case SKU_0_AKALI:
206 case SKU_1_AKALI:
207 case SKU_0_AKALI360:
208 case SKU_1_AKALI360:
209 return "vbt-akali.bin";
Ren Kuo337afb02018-12-22 15:04:56 +0800210 case SKU_0_BARD:
211 case SKU_1_BARD:
212 case SKU_2_BARD:
213 case SKU_3_BARD:
214 return "vbt-bard.bin";
Furquan Shaikhc6141b92018-05-10 21:58:39 -0700215 default:
216 return "vbt.bin";
217 break;
218 }
219}
Gaggery Tsai70627772018-07-26 00:14:09 -0700220
221static int find_sku_mapping(const uint8_t oem_id)
222{
223 /* Check if this OEM ID has a mapping table entry. */
224 for (int i = 0; i < ARRAY_SIZE(sku_overwrite_mapping); i++)
225 if (oem_id == sku_overwrite_mapping[i].sku)
226 return i;
227
228 return -1;
229}
230
231/* Override dev tree settings per board */
232void variant_devtree_update(void)
233{
234 uint32_t sku_id = variant_board_sku();
235 uint32_t i;
236 int oem_index;
237 struct device *root = SA_DEV_ROOT;
238 config_t *cfg = root->chip_info;
John Su2257a352018-10-25 19:21:15 +0800239 uint8_t pl2_id = PL2_ID_DEFAULT;
Gaggery Tsai70627772018-07-26 00:14:09 -0700240
241 switch (sku_id) {
Gaggery Tsai70627772018-07-26 00:14:09 -0700242 case SKU_0_SONA:
243 case SKU_1_SONA:
Amanda Huangf7b57d02018-10-11 11:39:37 +0800244 case SKU_0_SYNDRA:
245 case SKU_1_SYNDRA:
246 case SKU_2_SYNDRA:
247 case SKU_3_SYNDRA:
Amanda Huang3080fe02018-12-17 13:25:03 +0800248 case SKU_4_SYNDRA:
249 case SKU_5_SYNDRA:
250 case SKU_6_SYNDRA:
251 case SKU_7_SYNDRA:
John Su2257a352018-10-25 19:21:15 +0800252 pl2_id = PL2_ID_SONA_SYNDRA;
253 case SKU_0_VAYNE:
254 case SKU_1_VAYNE:
255 case SKU_2_VAYNE:
256 case SKU_0_PANTHEON:
257 case SKU_1_PANTHEON:
258 case SKU_2_PANTHEON:
Frank Wud0cc3bc2018-12-24 11:25:36 +0800259 case SKU_3_PANTHEON:
260 case SKU_4_PANTHEON:
Gaggery Tsai70627772018-07-26 00:14:09 -0700261 cfg->usb2_ports[5].enable = 0;
262 break;
Ren Kuoa355b162018-12-12 14:39:36 +0800263 case SKU_0_BARD:
264 case SKU_1_BARD:
265 case SKU_2_BARD:
266 case SKU_3_BARD:
267 case SKU_0_EKKO:
268 case SKU_1_EKKO:
269 case SKU_2_EKKO:
270 case SKU_3_EKKO:
271 pl2_id = PL2_ID_BARD_EKKO;
Ren Kuo03f654c2019-01-18 17:12:33 +0800272 cfg->usb2_ports[5].enable = 0;
273 cfg->usb2_ports[7].enable = 0;
274 cfg->usb2_ports[8].enable = 0;
275 cfg->usb2_ports[9].enable = 0;
Ren Kuoa355b162018-12-12 14:39:36 +0800276 break;
Gaggery Tsai70627772018-07-26 00:14:09 -0700277 default:
278 break;
279 }
280
John Su2257a352018-10-25 19:21:15 +0800281 /* Update PL2 based on SKU. */
282 cfg->tdp_pl2_override = get_pl2(pl2_id);
283
Gaggery Tsai70627772018-07-26 00:14:09 -0700284 /* Overwrite settings for different projects based on OEM ID*/
285 oem_index = find_sku_mapping(read_oem_id());
286
287 /* Return if the OEM ID is not supported or no changes are required */
288 if (oem_index < 0)
289 return;
290
291 for (i = 0; i < ARRAY_SIZE(cfg->domain_vr_config); i++) {
292 cfg->domain_vr_config[i].ac_loadline =
293 sku_overwrite_mapping[oem_index].ac_loadline[i];
294 cfg->domain_vr_config[i].dc_loadline =
295 sku_overwrite_mapping[oem_index].dc_loadline[i];
296 }
297}