mb/starlabs/{lite_adl,byte_adl}: Don't select MAINBOARD_HAS_TPM2
[coreboot2.git] / src / soc / intel / cannonlake / fsp_params.c
blobe1eede206639ce14cf29b67b99f5c8e5a605c6b0
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <bootsplash.h>
4 #include <console/console.h>
5 #include <device/device.h>
6 #include <device/pci.h>
7 #include <fsp/api.h>
8 #include <fsp/util.h>
9 #include <option.h>
10 #include <intelblocks/irq.h>
11 #include <intelblocks/lpss.h>
12 #include <intelblocks/power_limit.h>
13 #include <intelblocks/pmclib.h>
14 #include <intelblocks/xdci.h>
15 #include <intelpch/lockdown.h>
16 #include <soc/intel/common/vbt.h>
17 #include <soc/pci_devs.h>
18 #include <soc/ramstage.h>
19 #include <string.h>
20 #include <types.h>
22 #include "chip.h"
24 static const pci_devfn_t serial_io_dev[] = {
25 PCH_DEVFN_I2C0,
26 PCH_DEVFN_I2C1,
27 PCH_DEVFN_I2C2,
28 PCH_DEVFN_I2C3,
29 PCH_DEVFN_I2C4,
30 PCH_DEVFN_I2C5,
31 PCH_DEVFN_GSPI0,
32 PCH_DEVFN_GSPI1,
33 PCH_DEVFN_GSPI2,
34 PCH_DEVFN_UART0,
35 PCH_DEVFN_UART1,
36 PCH_DEVFN_UART2
39 static const struct slot_irq_constraints irq_constraints[] = {
41 .slot = SA_DEV_SLOT_PEG,
42 .fns = {
43 FIXED_INT_PIRQ(SA_DEVFN_PEG0, PCI_INT_A, PIRQ_A),
44 FIXED_INT_PIRQ(SA_DEVFN_PEG1, PCI_INT_B, PIRQ_B),
45 FIXED_INT_PIRQ(SA_DEVFN_PEG2, PCI_INT_C, PIRQ_C),
47 * It looks like FSP does not apply this mapping properly to
48 * the PEG functions. The PINx to PIRQx mapping needs to be there
49 * in ACPI however in case PIN D is used.
51 FIXED_INT_PIRQ(PCI_DEVFN(SA_DEV_SLOT_PEG, 3), PCI_INT_D, PIRQ_D),
55 .slot = SA_DEV_SLOT_IGD,
56 .fns = {
57 ANY_PIRQ(SA_DEVFN_IGD),
61 .slot = SA_DEV_SLOT_TS,
62 .fns = {
63 ANY_PIRQ(SA_DEVFN_TS),
67 .slot = SA_DEV_SLOT_IPU,
68 .fns = {
69 ANY_PIRQ(SA_DEVFN_IPU),
73 .slot = SA_DEV_SLOT_GNA,
74 .fns = {
75 ANY_PIRQ(SA_DEVFN_GNA),
79 .slot = PCH_DEV_SLOT_THERMAL,
80 .fns = {
81 ANY_PIRQ(PCH_DEVFN_THERMAL),
82 #if !CONFIG(SOC_INTEL_CANNONLAKE_PCH_H)
83 ANY_PIRQ(PCH_DEVFN_UFS),
84 #endif
85 DIRECT_IRQ(PCH_DEVFN_GSPI2),
89 .slot = PCH_DEV_SLOT_ISH,
90 .fns = {
91 DIRECT_IRQ(PCH_DEVFN_ISH),
95 .slot = PCH_DEV_SLOT_XHCI,
96 .fns = {
97 ANY_PIRQ(PCH_DEVFN_XHCI),
98 ANY_PIRQ(PCH_DEVFN_USBOTG),
99 ANY_PIRQ(PCH_DEVFN_CNViWIFI),
100 ANY_PIRQ(PCH_DEVFN_SDCARD),
104 .slot = PCH_DEV_SLOT_SIO1,
105 .fns = {
106 DIRECT_IRQ(PCH_DEVFN_I2C0),
107 DIRECT_IRQ(PCH_DEVFN_I2C1),
108 DIRECT_IRQ(PCH_DEVFN_I2C2),
109 DIRECT_IRQ(PCH_DEVFN_I2C3),
113 .slot = PCH_DEV_SLOT_CSE,
114 .fns = {
115 ANY_PIRQ(PCH_DEVFN_CSE),
116 ANY_PIRQ(PCH_DEVFN_CSE_2),
117 ANY_PIRQ(PCH_DEVFN_CSE_IDER),
118 ANY_PIRQ(PCH_DEVFN_CSE_KT),
119 ANY_PIRQ(PCH_DEVFN_CSE_3),
120 ANY_PIRQ(PCH_DEVFN_CSE_4),
124 .slot = PCH_DEV_SLOT_SATA,
125 .fns = {
126 ANY_PIRQ(PCH_DEVFN_SATA),
130 .slot = PCH_DEV_SLOT_SIO2,
131 .fns = {
132 #if !CONFIG(SOC_INTEL_CANNONLAKE_PCH_H)
133 DIRECT_IRQ(PCH_DEVFN_I2C4),
134 DIRECT_IRQ(PCH_DEVFN_I2C5),
135 #endif
136 DIRECT_IRQ(PCH_DEVFN_UART2),
139 #if !CONFIG(SOC_INTEL_CANNONLAKE_PCH_H)
141 .slot = PCH_DEV_SLOT_STORAGE,
142 .fns = {
143 ANY_PIRQ(PCH_DEVFN_EMMC),
146 #endif
147 #if CONFIG(SOC_INTEL_CANNONLAKE_PCH_H)
149 .slot = PCH_DEV_SLOT_PCIE_2,
150 .fns = {
151 FIXED_INT_PIRQ(PCH_DEVFN_PCIE17, PCI_INT_A, PIRQ_A),
152 FIXED_INT_PIRQ(PCH_DEVFN_PCIE18, PCI_INT_B, PIRQ_B),
153 FIXED_INT_PIRQ(PCH_DEVFN_PCIE19, PCI_INT_C, PIRQ_C),
154 FIXED_INT_PIRQ(PCH_DEVFN_PCIE20, PCI_INT_D, PIRQ_D),
155 FIXED_INT_PIRQ(PCH_DEVFN_PCIE21, PCI_INT_A, PIRQ_A),
156 FIXED_INT_PIRQ(PCH_DEVFN_PCIE22, PCI_INT_B, PIRQ_B),
157 FIXED_INT_PIRQ(PCH_DEVFN_PCIE23, PCI_INT_C, PIRQ_C),
158 FIXED_INT_PIRQ(PCH_DEVFN_PCIE24, PCI_INT_D, PIRQ_D),
161 #endif
163 .slot = PCH_DEV_SLOT_PCIE,
164 .fns = {
165 FIXED_INT_PIRQ(PCH_DEVFN_PCIE1, PCI_INT_A, PIRQ_A),
166 FIXED_INT_PIRQ(PCH_DEVFN_PCIE2, PCI_INT_B, PIRQ_B),
167 FIXED_INT_PIRQ(PCH_DEVFN_PCIE3, PCI_INT_C, PIRQ_C),
168 FIXED_INT_PIRQ(PCH_DEVFN_PCIE4, PCI_INT_D, PIRQ_D),
169 FIXED_INT_PIRQ(PCH_DEVFN_PCIE5, PCI_INT_A, PIRQ_A),
170 FIXED_INT_PIRQ(PCH_DEVFN_PCIE6, PCI_INT_B, PIRQ_B),
171 FIXED_INT_PIRQ(PCH_DEVFN_PCIE7, PCI_INT_C, PIRQ_C),
172 FIXED_INT_PIRQ(PCH_DEVFN_PCIE8, PCI_INT_D, PIRQ_D),
176 .slot = PCH_DEV_SLOT_PCIE_1,
177 .fns = {
178 FIXED_INT_PIRQ(PCH_DEVFN_PCIE9, PCI_INT_A, PIRQ_A),
179 FIXED_INT_PIRQ(PCH_DEVFN_PCIE10, PCI_INT_B, PIRQ_B),
180 FIXED_INT_PIRQ(PCH_DEVFN_PCIE11, PCI_INT_C, PIRQ_C),
181 FIXED_INT_PIRQ(PCH_DEVFN_PCIE12, PCI_INT_D, PIRQ_D),
182 FIXED_INT_PIRQ(PCH_DEVFN_PCIE13, PCI_INT_A, PIRQ_A),
183 FIXED_INT_PIRQ(PCH_DEVFN_PCIE14, PCI_INT_B, PIRQ_B),
184 FIXED_INT_PIRQ(PCH_DEVFN_PCIE15, PCI_INT_C, PIRQ_C),
185 FIXED_INT_PIRQ(PCH_DEVFN_PCIE16, PCI_INT_D, PIRQ_D),
189 .slot = PCH_DEV_SLOT_SIO3,
190 .fns = {
191 DIRECT_IRQ(PCH_DEVFN_UART0),
192 DIRECT_IRQ(PCH_DEVFN_UART1),
193 DIRECT_IRQ(PCH_DEVFN_GSPI0),
194 DIRECT_IRQ(PCH_DEVFN_GSPI1),
198 .slot = PCH_DEV_SLOT_LPC,
199 .fns = {
200 ANY_PIRQ(PCH_DEVFN_HDA),
201 ANY_PIRQ(PCH_DEVFN_SMBUS),
202 ANY_PIRQ(PCH_DEVFN_GBE),
203 FIXED_INT_ANY_PIRQ(PCH_DEVFN_TRACEHUB, PCI_INT_A)
209 * Given an enum for PCH_SERIAL_IO_MODE, 1 needs to be subtracted to get the FSP
210 * UPD expected value for Serial IO since valid enum index starts from 1.
212 #define PCH_SERIAL_IO_INDEX(x) ((x) - 1)
214 static uint8_t get_param_value(const config_t *config, uint32_t dev_offset)
216 if (!is_devfn_enabled(serial_io_dev[dev_offset]))
217 return PCH_SERIAL_IO_INDEX(PchSerialIoDisabled);
219 if ((config->SerialIoDevMode[dev_offset] >= PchSerialIoMax) ||
220 (config->SerialIoDevMode[dev_offset] == PchSerialIoNotInitialized))
221 return PCH_SERIAL_IO_INDEX(PchSerialIoPci);
224 * Correct Enum index starts from 1, so subtract 1 while returning value
226 return PCH_SERIAL_IO_INDEX(config->SerialIoDevMode[dev_offset]);
229 static void parse_devicetree(const config_t *config, FSP_S_CONFIG *params)
231 #if CONFIG(SOC_INTEL_COMETLAKE)
232 uint32_t dev_offset = 0;
233 uint32_t i = 0;
235 for (i = 0; i < CONFIG_SOC_INTEL_I2C_DEV_MAX; i++, dev_offset++) {
236 params->SerialIoI2cMode[i] =
237 get_param_value(config, dev_offset);
240 for (i = 0; i < CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX; i++,
241 dev_offset++) {
242 params->SerialIoSpiMode[i] =
243 get_param_value(config, dev_offset);
246 for (i = 0; i < SOC_INTEL_CML_UART_DEV_MAX; i++, dev_offset++) {
247 params->SerialIoUartMode[i] =
248 get_param_value(config, dev_offset);
250 #else
251 for (int i = 0; i < ARRAY_SIZE(serial_io_dev); i++)
252 params->SerialIoDevMode[i] = get_param_value(config, i);
253 #endif
256 /* Ignore LTR value for GBE devices */
257 static void ignore_gbe_ltr(void)
259 uint8_t reg8;
260 uint8_t *pmcbase = pmc_mmio_regs();
262 reg8 = read8(pmcbase + LTR_IGN);
263 reg8 |= IGN_GBE;
264 write8(pmcbase + LTR_IGN, reg8);
267 static void configure_gspi_cs(int idx, const config_t *config,
268 uint8_t *polarity, uint8_t *enable,
269 uint8_t *defaultcs)
271 struct spi_cfg cfg;
273 /* If speed_mhz is set, infer that the port should be configured */
274 if (config->common_soc_config.gspi[idx].speed_mhz != 0) {
275 if (gspi_get_soc_spi_cfg(idx, &cfg) == 0) {
276 if (cfg.cs_polarity == SPI_POLARITY_LOW)
277 *polarity = 0;
278 else
279 *polarity = 1;
281 if (defaultcs != NULL)
282 *defaultcs = 0;
283 if (enable != NULL)
284 *enable = 1;
289 static const SI_PCH_DEVICE_INTERRUPT_CONFIG *pci_irq_to_fsp(size_t *out_count)
291 const struct pci_irq_entry *entry = get_cached_pci_irqs();
292 SI_PCH_DEVICE_INTERRUPT_CONFIG *config;
293 size_t pch_total = 0;
294 size_t cfg_count = 0;
296 if (!entry)
297 return NULL;
299 /* Count PCH devices */
300 while (entry) {
301 if (is_pch_slot(entry->devfn))
302 ++pch_total;
303 entry = entry->next;
306 /* Convert PCH device entries to FSP format */
307 config = calloc(pch_total, sizeof(*config));
308 entry = get_cached_pci_irqs();
309 while (entry) {
310 if (!is_pch_slot(entry->devfn)) {
311 entry = entry->next;
312 continue;
315 config[cfg_count].Device = PCI_SLOT(entry->devfn);
316 config[cfg_count].Function = PCI_FUNC(entry->devfn);
317 config[cfg_count].IntX = (SI_PCH_INT_PIN)entry->pin;
318 config[cfg_count].Irq = entry->irq;
319 ++cfg_count;
321 entry = entry->next;
324 *out_count = cfg_count;
326 return config;
329 /* UPD parameters to be initialized before SiliconInit */
330 void platform_fsp_silicon_init_params_cb(FSPS_UPD *supd)
332 int i;
333 FSP_S_CONFIG *params = &supd->FspsConfig;
334 FSP_S_TEST_CONFIG *tconfig = &supd->FspsTestConfig;
335 struct device *dev;
337 config_t *config = config_of_soc();
339 /* Parse device tree and enable/disable devices */
340 parse_devicetree(config, params);
342 /* Load VBT before devicetree-specific config. */
343 params->GraphicsConfigPtr = (uintptr_t)vbt_get();
345 mainboard_silicon_init_params(supd);
347 const struct soc_power_limits_config *soc_config;
348 soc_config = &config->power_limits_config;
349 /* Set PsysPmax if it is available from DT */
350 if (soc_config->psys_pmax) {
351 printk(BIOS_DEBUG, "psys_pmax = %dW\n", soc_config->psys_pmax);
352 /* PsysPmax is in unit of 1/8 Watt */
353 tconfig->PsysPmax = soc_config->psys_pmax * 8;
356 /* Unlock upper 8 bytes of RTC RAM */
357 params->PchLockDownRtcMemoryLock = 0;
359 /* SATA */
360 params->SataEnable = is_devfn_enabled(PCH_DEVFN_SATA);
361 if (params->SataEnable) {
362 params->SataMode = config->SataMode;
363 params->SataPwrOptEnable = config->satapwroptimize;
364 params->SataSalpSupport = config->SataSalpSupport;
365 memcpy(params->SataPortsEnable, config->SataPortsEnable,
366 sizeof(params->SataPortsEnable));
367 memcpy(params->SataPortsDevSlp, config->SataPortsDevSlp,
368 sizeof(params->SataPortsDevSlp));
369 memcpy(params->SataPortsHotPlug, config->SataPortsHotPlug,
370 sizeof(params->SataPortsHotPlug));
371 #if CONFIG(SOC_INTEL_COMETLAKE)
372 memcpy(params->SataPortsDevSlpResetConfig,
373 config->SataPortsDevSlpResetConfig,
374 sizeof(params->SataPortsDevSlpResetConfig));
375 #endif
377 params->SlpS0WithGbeSupport = 0;
378 params->PchPmSlpS0VmRuntimeControl = config->PchPmSlpS0VmRuntimeControl;
379 params->PchPmSlpS0Vm070VSupport = config->PchPmSlpS0Vm070VSupport;
380 params->PchPmSlpS0Vm075VSupport = config->PchPmSlpS0Vm075VSupport;
382 /* Lan */
383 params->PchLanEnable = is_devfn_enabled(PCH_DEVFN_GBE);
384 if (params->PchLanEnable) {
385 if (config->s0ix_enable) {
387 * The VmControl UPDs need to be set as per board
388 * design to allow voltage margining in S0ix to lower
389 * power consumption.
390 * But if GbE is enabled, voltage magining cannot be
391 * enabled, so the Vm control UPDs need to be set to 0.
393 params->SlpS0WithGbeSupport = 1;
394 params->PchPmSlpS0VmRuntimeControl = 0;
395 params->PchPmSlpS0Vm070VSupport = 0;
396 params->PchPmSlpS0Vm075VSupport = 0;
397 ignore_gbe_ltr();
401 /* Audio */
402 params->PchHdaDspEnable = config->PchHdaDspEnable;
403 params->PchHdaIDispCodecDisconnect = config->PchHdaIDispCodecDisconnect;
404 params->PchHdaAudioLinkHda = config->PchHdaAudioLinkHda;
405 params->PchHdaAudioLinkDmic0 = config->PchHdaAudioLinkDmic0;
406 params->PchHdaAudioLinkDmic1 = config->PchHdaAudioLinkDmic1;
407 params->PchHdaAudioLinkSsp0 = config->PchHdaAudioLinkSsp0;
408 params->PchHdaAudioLinkSsp1 = config->PchHdaAudioLinkSsp1;
409 params->PchHdaAudioLinkSsp2 = config->PchHdaAudioLinkSsp2;
410 params->PchHdaAudioLinkSndw1 = config->PchHdaAudioLinkSndw1;
411 params->PchHdaAudioLinkSndw2 = config->PchHdaAudioLinkSndw2;
412 params->PchHdaAudioLinkSndw3 = config->PchHdaAudioLinkSndw3;
413 params->PchHdaAudioLinkSndw4 = config->PchHdaAudioLinkSndw4;
415 /* eDP device */
416 params->DdiPortEdp = config->DdiPortEdp;
418 /* HPD of DDI ports */
419 params->DdiPortBHpd = config->DdiPortBHpd;
420 params->DdiPortCHpd = config->DdiPortCHpd;
421 params->DdiPortDHpd = config->DdiPortDHpd;
422 params->DdiPortFHpd = config->DdiPortFHpd;
424 /* DDC of DDI ports */
425 params->DdiPortBDdc = config->DdiPortBDdc;
426 params->DdiPortCDdc = config->DdiPortCDdc;
427 params->DdiPortDDdc = config->DdiPortDDdc;
428 params->DdiPortFDdc = config->DdiPortFDdc;
430 /* WOL */
431 params->PchPmPcieWakeFromDeepSx = config->LanWakeFromDeepSx;
432 params->PchPmWolEnableOverride = config->WolEnableOverride;
434 /* S0ix */
435 params->PchPmSlpS0Enable = config->s0ix_enable;
437 /* disable Legacy PME */
438 memset(params->PcieRpPmSci, 0, sizeof(params->PcieRpPmSci));
440 /* Legacy 8254 timer support */
441 bool use_8254 = get_uint_option("legacy_8254_timer", CONFIG(USE_LEGACY_8254_TIMER));
442 params->Enable8254ClockGating = !use_8254;
443 params->Enable8254ClockGatingOnS3 = !use_8254;
446 * Legacy PM ACPI Timer (and TCO Timer)
447 * This *must* be 1 in any case to keep FSP from
448 * 1) enabling PM ACPI Timer emulation in uCode.
449 * 2) disabling the PM ACPI Timer.
450 * We handle both by ourself!
452 params->EnableTcoTimer = 1;
454 /* USB */
455 for (i = 0; i < ARRAY_SIZE(config->usb2_ports); i++) {
456 params->PortUsb20Enable[i] = config->usb2_ports[i].enable;
457 params->Usb2AfePetxiset[i] = config->usb2_ports[i].pre_emp_bias;
458 params->Usb2AfeTxiset[i] = config->usb2_ports[i].tx_bias;
459 params->Usb2AfePredeemp[i] =
460 config->usb2_ports[i].tx_emp_enable;
461 params->Usb2AfePehalfbit[i] = config->usb2_ports[i].pre_emp_bit;
463 if (config->usb2_ports[i].enable)
464 params->Usb2OverCurrentPin[i] = config->usb2_ports[i].ocpin;
465 else
466 params->Usb2OverCurrentPin[i] = 0xff;
469 if (config->PchUsb2PhySusPgDisable)
470 params->PchUsb2PhySusPgEnable = 0;
472 for (i = 0; i < ARRAY_SIZE(config->usb3_ports); i++) {
473 params->PortUsb30Enable[i] = config->usb3_ports[i].enable;
474 if (config->usb3_ports[i].enable) {
475 params->Usb3OverCurrentPin[i] = config->usb3_ports[i].ocpin;
476 } else {
477 params->Usb3OverCurrentPin[i] = 0xff;
479 if (config->usb3_ports[i].tx_de_emp) {
480 params->Usb3HsioTxDeEmphEnable[i] = 1;
481 params->Usb3HsioTxDeEmph[i] =
482 config->usb3_ports[i].tx_de_emp;
484 if (config->usb3_ports[i].tx_downscale_amp) {
485 params->Usb3HsioTxDownscaleAmpEnable[i] = 1;
486 params->Usb3HsioTxDownscaleAmp[i] =
487 config->usb3_ports[i].tx_downscale_amp;
489 #if CONFIG(SOC_INTEL_COMETLAKE)
490 if (config->usb3_ports[i].gen2_tx_rate0_uniq_tran_enable) {
491 params->Usb3HsioTxRate0UniqTranEnable[i] = 1;
492 params->Usb3HsioTxRate0UniqTran[i] =
493 config->usb3_ports[i].gen2_tx_rate0_uniq_tran;
495 if (config->usb3_ports[i].gen2_tx_rate1_uniq_tran_enable) {
496 params->Usb3HsioTxRate1UniqTranEnable[i] = 1;
497 params->Usb3HsioTxRate1UniqTran[i] =
498 config->usb3_ports[i].gen2_tx_rate1_uniq_tran;
500 if (config->usb3_ports[i].gen2_tx_rate2_uniq_tran_enable) {
501 params->Usb3HsioTxRate2UniqTranEnable[i] = 1;
502 params->Usb3HsioTxRate2UniqTran[i] =
503 config->usb3_ports[i].gen2_tx_rate2_uniq_tran;
505 if (config->usb3_ports[i].gen2_tx_rate3_uniq_tran_enable) {
506 params->Usb3HsioTxRate3UniqTranEnable[i] = 1;
507 params->Usb3HsioTxRate3UniqTran[i] =
508 config->usb3_ports[i].gen2_tx_rate3_uniq_tran;
510 #endif
511 if (config->usb3_ports[i].gen2_rx_tuning_enable) {
512 params->PchUsbHsioRxTuningEnable[i] =
513 config->usb3_ports[i].gen2_rx_tuning_enable;
514 params->PchUsbHsioRxTuningParameters[i] =
515 config->usb3_ports[i].gen2_rx_tuning_params;
516 params->PchUsbHsioFilterSel[i] =
517 config->usb3_ports[i].gen2_rx_filter_sel;
521 params->XdciEnable = xdci_can_enable(PCH_DEVFN_USBOTG);
523 /* Set Debug serial port */
524 params->SerialIoDebugUartNumber = CONFIG_UART_FOR_CONSOLE;
525 #if !CONFIG(SOC_INTEL_COMETLAKE)
526 params->SerialIoEnableDebugUartAfterPost = CONFIG(INTEL_LPSS_UART_FOR_CONSOLE);
527 #endif
529 /* Enable CNVi Wifi if enabled in device tree */
530 #if CONFIG(SOC_INTEL_COMETLAKE)
531 params->CnviMode = is_devfn_enabled(PCH_DEVFN_CNViWIFI);
532 #else
533 params->PchCnviMode = is_devfn_enabled(PCH_DEVFN_CNViWIFI);
534 #endif
535 /* PCI Express */
536 for (i = 0; i < ARRAY_SIZE(config->PcieClkSrcUsage); i++) {
537 if (config->PcieClkSrcUsage[i] == 0)
538 config->PcieClkSrcUsage[i] = PCIE_CLK_NOTUSED;
539 else if (config->PcieClkSrcUsage[i] == PCIE_CLK_RP0)
540 config->PcieClkSrcUsage[i] = 0;
542 memcpy(params->PcieClkSrcUsage, config->PcieClkSrcUsage,
543 sizeof(config->PcieClkSrcUsage));
544 memcpy(params->PcieClkSrcClkReq, config->PcieClkSrcClkReq,
545 sizeof(config->PcieClkSrcClkReq));
547 memcpy(params->PcieRpAdvancedErrorReporting,
548 config->PcieRpAdvancedErrorReporting,
549 sizeof(config->PcieRpAdvancedErrorReporting));
551 memcpy(params->PcieRpLtrEnable, config->PcieRpLtrEnable,
552 sizeof(config->PcieRpLtrEnable));
553 memcpy(params->PcieRpSlotImplemented, config->PcieRpSlotImplemented,
554 sizeof(config->PcieRpSlotImplemented));
555 memcpy(params->PcieRpHotPlug, config->PcieRpHotPlug,
556 sizeof(config->PcieRpHotPlug));
558 for (i = 0; i < CONFIG_MAX_ROOT_PORTS; i++) {
559 params->PcieRpMaxPayload[i] = config->PcieRpMaxPayload[i];
560 if (config->PcieRpAspm[i])
561 params->PcieRpAspm[i] = config->PcieRpAspm[i] - 1;
564 /* eMMC and SD */
565 params->ScsEmmcEnabled = is_devfn_enabled(PCH_DEVFN_EMMC);
566 if (params->ScsEmmcEnabled) {
567 params->ScsEmmcHs400Enabled = config->ScsEmmcHs400Enabled;
568 params->PchScsEmmcHs400DllDataValid = config->EmmcHs400DllNeed;
569 if (config->EmmcHs400DllNeed == 1) {
570 params->PchScsEmmcHs400RxStrobeDll1 =
571 config->EmmcHs400RxStrobeDll1;
572 params->PchScsEmmcHs400TxDataDll =
573 config->EmmcHs400TxDataDll;
577 params->ScsSdCardEnabled = is_devfn_enabled(PCH_DEVFN_SDCARD);
578 if (params->ScsSdCardEnabled) {
579 params->SdCardPowerEnableActiveHigh = CONFIG(MB_HAS_ACTIVE_HIGH_SD_PWR_ENABLE);
580 #if CONFIG(SOC_INTEL_COMETLAKE)
581 params->ScsSdCardWpPinEnabled = config->ScsSdCardWpPinEnabled;
582 #endif
585 params->ScsUfsEnabled = is_devfn_enabled(PCH_DEVFN_UFS);
587 params->Heci3Enabled = is_devfn_enabled(PCH_DEVFN_CSE_3);
589 * coreboot will handle disabling of HECI1 device if `DISABLE_HECI1_AT_PRE_BOOT`
590 * config is selected hence, don't let FSP to disable the HECI1 device and set
591 * the `Heci1Disabled` UPD to `0`.
593 params->Heci1Disabled = 0;
594 params->Device4Enable = config->Device4Enable;
596 /* Teton Glacier hybrid storage support */
597 params->TetonGlacierMode = config->TetonGlacierMode;
599 /* VrConfig Settings for 5 domains
600 * 0 = System Agent, 1 = IA Core, 2 = Ring,
601 * 3 = GT unsliced, 4 = GT sliced */
602 for (i = 0; i < ARRAY_SIZE(config->domain_vr_config); i++)
603 fill_vr_domain_config(params, i, &config->domain_vr_config[i]);
605 /* Acoustic Noise Mitigation */
606 params->AcousticNoiseMitigation = config->AcousticNoiseMitigation;
607 params->SlowSlewRateForIa = config->SlowSlewRateForIa;
608 params->SlowSlewRateForGt = config->SlowSlewRateForGt;
609 params->SlowSlewRateForSa = config->SlowSlewRateForSa;
610 params->SlowSlewRateForFivr = config->SlowSlewRateForFivr;
611 params->FastPkgCRampDisableIa = config->FastPkgCRampDisableIa;
612 params->FastPkgCRampDisableGt = config->FastPkgCRampDisableGt;
613 params->FastPkgCRampDisableSa = config->FastPkgCRampDisableSa;
614 params->FastPkgCRampDisableFivr = config->FastPkgCRampDisableFivr;
616 /* Apply minimum assertion width settings if non-zero */
617 if (config->PchPmSlpS3MinAssert)
618 params->PchPmSlpS3MinAssert = config->PchPmSlpS3MinAssert;
619 if (config->PchPmSlpS4MinAssert)
620 params->PchPmSlpS4MinAssert = config->PchPmSlpS4MinAssert;
621 if (config->PchPmSlpSusMinAssert)
622 params->PchPmSlpSusMinAssert = config->PchPmSlpSusMinAssert;
623 if (config->PchPmSlpAMinAssert)
624 params->PchPmSlpAMinAssert = config->PchPmSlpAMinAssert;
626 #if CONFIG(SOC_INTEL_COMETLAKE)
627 if (config->PchPmPwrCycDur)
628 params->PchPmPwrCycDur = get_pm_pwr_cyc_dur(config->PchPmSlpS4MinAssert,
629 config->PchPmSlpS3MinAssert, config->PchPmSlpAMinAssert,
630 config->PchPmPwrCycDur);
631 #endif
633 /* Set TccActivationOffset */
634 tconfig->TccActivationOffset = config->tcc_offset;
635 tconfig->TccOffsetClamp = config->tcc_offset > 0;
637 /* Unlock all GPIO pads */
638 tconfig->PchUnlockGpioPads = config->PchUnlockGpioPads;
640 /* Set correct Sirq mode based on config */
641 params->PchSirqEnable = config->serirq_mode != SERIRQ_OFF;
642 params->PchSirqMode = config->serirq_mode == SERIRQ_CONTINUOUS;
645 * GSPI Chip Select parameters
646 * The GSPI driver assumes that CS0 is the used chip-select line,
647 * therefore only CS0 is configured below.
649 #if CONFIG(SOC_INTEL_COMETLAKE)
650 configure_gspi_cs(0, config, &params->SerialIoSpi0CsPolarity[0],
651 &params->SerialIoSpi0CsEnable[0],
652 &params->SerialIoSpiDefaultCsOutput[0]);
653 configure_gspi_cs(1, config, &params->SerialIoSpi1CsPolarity[0],
654 &params->SerialIoSpi1CsEnable[0],
655 &params->SerialIoSpiDefaultCsOutput[1]);
656 configure_gspi_cs(2, config, &params->SerialIoSpi2CsPolarity[0],
657 &params->SerialIoSpi2CsEnable[0],
658 &params->SerialIoSpiDefaultCsOutput[2]);
659 #else
660 for (i = 0; i < CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX; i++)
661 configure_gspi_cs(i, config,
662 &params->SerialIoSpiCsPolarity[0], NULL, NULL);
663 #endif
665 /* Chipset Lockdown */
666 const bool lockdown_by_fsp = get_lockdown_config() == CHIPSET_LOCKDOWN_FSP;
667 tconfig->PchLockDownGlobalSmi = lockdown_by_fsp;
668 tconfig->PchLockDownBiosInterface = lockdown_by_fsp;
669 params->PchLockDownBiosLock = lockdown_by_fsp;
670 params->PchLockDownRtcMemoryLock = lockdown_by_fsp;
671 tconfig->SkipPamLock = !lockdown_by_fsp;
672 #if CONFIG(SOC_INTEL_COMETLAKE)
674 * Making this config "0" means FSP won't set the FLOCKDN bit
675 * of SPIBAR + 0x04 (i.e., Bit 15 of BIOS_HSFSTS_CTL).
676 * So, it becomes coreboot's responsibility to set this bit
677 * before end of POST for security concerns.
679 params->SpiFlashCfgLockDown = lockdown_by_fsp;
680 #endif
682 #if !CONFIG(SOC_INTEL_COMETLAKE)
683 params->VrPowerDeliveryDesign = config->VrPowerDeliveryDesign;
684 #endif
686 params->PeiGraphicsPeimInit = CONFIG(RUN_FSP_GOP) && is_devfn_enabled(SA_DEVFN_IGD);
688 params->PavpEnable = CONFIG(PAVP);
691 * Prevent FSP from programming write-once subsystem IDs by providing
692 * a custom SSID table. Must have at least one entry for the FSP to
693 * use the table.
695 struct svid_ssid_init_entry {
696 union {
697 struct {
698 uint64_t reg:12; /* Register offset */
699 uint64_t function:3;
700 uint64_t device:5;
701 uint64_t bus:8;
702 uint64_t :4;
703 uint64_t segment:16;
704 uint64_t :16;
706 uint64_t segbusdevfuncregister;
708 struct {
709 uint16_t svid;
710 uint16_t ssid;
712 uint32_t reserved;
716 * The xHCI and HDA devices have RW/L rather than RW/O registers for
717 * subsystem IDs and so must be written before FspSiliconInit locks
718 * them with their default values.
720 const pci_devfn_t devfn_table[] = { PCH_DEVFN_XHCI, PCH_DEVFN_HDA };
721 static struct svid_ssid_init_entry ssid_table[ARRAY_SIZE(devfn_table)];
723 for (i = 0; i < ARRAY_SIZE(devfn_table); i++) {
724 ssid_table[i].reg = PCI_SUBSYSTEM_VENDOR_ID;
725 ssid_table[i].device = PCI_SLOT(devfn_table[i]);
726 ssid_table[i].function = PCI_FUNC(devfn_table[i]);
727 dev = pcidev_path_on_root(devfn_table[i]);
728 if (dev) {
729 ssid_table[i].svid = dev->subsystem_vendor;
730 ssid_table[i].ssid = dev->subsystem_device;
734 params->SiSsidTablePtr = (uintptr_t)ssid_table;
735 params->SiNumberOfSsidTableEntry = ARRAY_SIZE(ssid_table);
737 /* Assign PCI IRQs */
738 if (!assign_pci_irqs(irq_constraints, ARRAY_SIZE(irq_constraints)))
739 die("ERROR: Unable to assign PCI IRQs, and no ACPI _PRT table is defined\n");
741 size_t pch_count = 0;
742 const SI_PCH_DEVICE_INTERRUPT_CONFIG *upd_irqs = pci_irq_to_fsp(&pch_count);
743 params->DevIntConfigPtr = (UINT32)((uintptr_t)upd_irqs);
744 params->NumOfDevIntConfig = pch_count;
745 printk(BIOS_INFO, "IRQ: Using dynamically assigned PCI IO-APIC IRQs\n");
748 /* Mainboard GPIO Configuration */
749 __weak void mainboard_silicon_init_params(FSPS_UPD *supd)
751 printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__);
754 /* Handle FSP logo params */
755 void soc_load_logo(FSPS_UPD *supd)
757 size_t logo_size;
758 supd->FspsConfig.LogoPtr = (uintptr_t)bmp_load_logo(&logo_size);
759 supd->FspsConfig.LogoSize = (uint32_t)logo_size;