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 <drivers/usb/acpi/chip.h>
11 #include <intelblocks/irq.h>
12 #include <intelblocks/lpss.h>
13 #include <intelblocks/power_limit.h>
14 #include <intelblocks/pmclib.h>
15 #include <intelblocks/xdci.h>
16 #include <intelpch/lockdown.h>
17 #include <soc/intel/common/vbt.h>
18 #include <soc/pci_devs.h>
19 #include <soc/ramstage.h>
26 static const pci_devfn_t serial_io_dev
[] = {
41 static const struct slot_irq_constraints irq_constraints
[] = {
43 .slot
= SA_DEV_SLOT_PEG
,
45 FIXED_INT_PIRQ(SA_DEVFN_PEG0
, PCI_INT_A
, PIRQ_A
),
46 FIXED_INT_PIRQ(SA_DEVFN_PEG1
, PCI_INT_B
, PIRQ_B
),
47 FIXED_INT_PIRQ(SA_DEVFN_PEG2
, PCI_INT_C
, PIRQ_C
),
49 * It looks like FSP does not apply this mapping properly to
50 * the PEG functions. The PINx to PIRQx mapping needs to be there
51 * in ACPI however in case PIN D is used.
53 FIXED_INT_PIRQ(PCI_DEVFN(SA_DEV_SLOT_PEG
, 3), PCI_INT_D
, PIRQ_D
),
57 .slot
= SA_DEV_SLOT_IGD
,
59 ANY_PIRQ(SA_DEVFN_IGD
),
63 .slot
= SA_DEV_SLOT_TS
,
65 ANY_PIRQ(SA_DEVFN_TS
),
69 .slot
= SA_DEV_SLOT_IPU
,
71 ANY_PIRQ(SA_DEVFN_IPU
),
75 .slot
= SA_DEV_SLOT_GNA
,
77 ANY_PIRQ(SA_DEVFN_GNA
),
81 .slot
= PCH_DEV_SLOT_THERMAL
,
83 ANY_PIRQ(PCH_DEVFN_THERMAL
),
84 #if !CONFIG(SOC_INTEL_CANNONLAKE_PCH_H)
85 ANY_PIRQ(PCH_DEVFN_UFS
),
87 DIRECT_IRQ(PCH_DEVFN_GSPI2
),
91 .slot
= PCH_DEV_SLOT_ISH
,
93 DIRECT_IRQ(PCH_DEVFN_ISH
),
97 .slot
= PCH_DEV_SLOT_XHCI
,
99 ANY_PIRQ(PCH_DEVFN_XHCI
),
100 ANY_PIRQ(PCH_DEVFN_USBOTG
),
101 ANY_PIRQ(PCH_DEVFN_CNViWIFI
),
102 ANY_PIRQ(PCH_DEVFN_SDCARD
),
106 .slot
= PCH_DEV_SLOT_SIO1
,
108 DIRECT_IRQ(PCH_DEVFN_I2C0
),
109 DIRECT_IRQ(PCH_DEVFN_I2C1
),
110 DIRECT_IRQ(PCH_DEVFN_I2C2
),
111 DIRECT_IRQ(PCH_DEVFN_I2C3
),
115 .slot
= PCH_DEV_SLOT_CSE
,
117 ANY_PIRQ(PCH_DEVFN_CSE
),
118 ANY_PIRQ(PCH_DEVFN_CSE_2
),
119 ANY_PIRQ(PCH_DEVFN_CSE_IDER
),
120 ANY_PIRQ(PCH_DEVFN_CSE_KT
),
121 ANY_PIRQ(PCH_DEVFN_CSE_3
),
122 ANY_PIRQ(PCH_DEVFN_CSE_4
),
126 .slot
= PCH_DEV_SLOT_SATA
,
128 ANY_PIRQ(PCH_DEVFN_SATA
),
132 .slot
= PCH_DEV_SLOT_SIO2
,
134 #if !CONFIG(SOC_INTEL_CANNONLAKE_PCH_H)
135 DIRECT_IRQ(PCH_DEVFN_I2C4
),
136 DIRECT_IRQ(PCH_DEVFN_I2C5
),
138 DIRECT_IRQ(PCH_DEVFN_UART2
),
141 #if !CONFIG(SOC_INTEL_CANNONLAKE_PCH_H)
143 .slot
= PCH_DEV_SLOT_STORAGE
,
145 ANY_PIRQ(PCH_DEVFN_EMMC
),
149 #if CONFIG(SOC_INTEL_CANNONLAKE_PCH_H)
151 .slot
= PCH_DEV_SLOT_PCIE_2
,
153 FIXED_INT_PIRQ(PCH_DEVFN_PCIE17
, PCI_INT_A
, PIRQ_A
),
154 FIXED_INT_PIRQ(PCH_DEVFN_PCIE18
, PCI_INT_B
, PIRQ_B
),
155 FIXED_INT_PIRQ(PCH_DEVFN_PCIE19
, PCI_INT_C
, PIRQ_C
),
156 FIXED_INT_PIRQ(PCH_DEVFN_PCIE20
, PCI_INT_D
, PIRQ_D
),
157 FIXED_INT_PIRQ(PCH_DEVFN_PCIE21
, PCI_INT_A
, PIRQ_A
),
158 FIXED_INT_PIRQ(PCH_DEVFN_PCIE22
, PCI_INT_B
, PIRQ_B
),
159 FIXED_INT_PIRQ(PCH_DEVFN_PCIE23
, PCI_INT_C
, PIRQ_C
),
160 FIXED_INT_PIRQ(PCH_DEVFN_PCIE24
, PCI_INT_D
, PIRQ_D
),
165 .slot
= PCH_DEV_SLOT_PCIE
,
167 FIXED_INT_PIRQ(PCH_DEVFN_PCIE1
, PCI_INT_A
, PIRQ_A
),
168 FIXED_INT_PIRQ(PCH_DEVFN_PCIE2
, PCI_INT_B
, PIRQ_B
),
169 FIXED_INT_PIRQ(PCH_DEVFN_PCIE3
, PCI_INT_C
, PIRQ_C
),
170 FIXED_INT_PIRQ(PCH_DEVFN_PCIE4
, PCI_INT_D
, PIRQ_D
),
171 FIXED_INT_PIRQ(PCH_DEVFN_PCIE5
, PCI_INT_A
, PIRQ_A
),
172 FIXED_INT_PIRQ(PCH_DEVFN_PCIE6
, PCI_INT_B
, PIRQ_B
),
173 FIXED_INT_PIRQ(PCH_DEVFN_PCIE7
, PCI_INT_C
, PIRQ_C
),
174 FIXED_INT_PIRQ(PCH_DEVFN_PCIE8
, PCI_INT_D
, PIRQ_D
),
178 .slot
= PCH_DEV_SLOT_PCIE_1
,
180 FIXED_INT_PIRQ(PCH_DEVFN_PCIE9
, PCI_INT_A
, PIRQ_A
),
181 FIXED_INT_PIRQ(PCH_DEVFN_PCIE10
, PCI_INT_B
, PIRQ_B
),
182 FIXED_INT_PIRQ(PCH_DEVFN_PCIE11
, PCI_INT_C
, PIRQ_C
),
183 FIXED_INT_PIRQ(PCH_DEVFN_PCIE12
, PCI_INT_D
, PIRQ_D
),
184 FIXED_INT_PIRQ(PCH_DEVFN_PCIE13
, PCI_INT_A
, PIRQ_A
),
185 FIXED_INT_PIRQ(PCH_DEVFN_PCIE14
, PCI_INT_B
, PIRQ_B
),
186 FIXED_INT_PIRQ(PCH_DEVFN_PCIE15
, PCI_INT_C
, PIRQ_C
),
187 FIXED_INT_PIRQ(PCH_DEVFN_PCIE16
, PCI_INT_D
, PIRQ_D
),
191 .slot
= PCH_DEV_SLOT_SIO3
,
193 DIRECT_IRQ(PCH_DEVFN_UART0
),
194 DIRECT_IRQ(PCH_DEVFN_UART1
),
195 DIRECT_IRQ(PCH_DEVFN_GSPI0
),
196 DIRECT_IRQ(PCH_DEVFN_GSPI1
),
200 .slot
= PCH_DEV_SLOT_LPC
,
202 ANY_PIRQ(PCH_DEVFN_HDA
),
203 ANY_PIRQ(PCH_DEVFN_SMBUS
),
204 ANY_PIRQ(PCH_DEVFN_GBE
),
205 FIXED_INT_ANY_PIRQ(PCH_DEVFN_TRACEHUB
, PCI_INT_A
)
211 * Given an enum for PCH_SERIAL_IO_MODE, 1 needs to be subtracted to get the FSP
212 * UPD expected value for Serial IO since valid enum index starts from 1.
214 #define PCH_SERIAL_IO_INDEX(x) ((x) - 1)
216 static uint8_t get_param_value(const config_t
*config
, uint32_t dev_offset
)
218 if (!is_devfn_enabled(serial_io_dev
[dev_offset
]))
219 return PCH_SERIAL_IO_INDEX(PchSerialIoDisabled
);
221 if ((config
->SerialIoDevMode
[dev_offset
] >= PchSerialIoMax
) ||
222 (config
->SerialIoDevMode
[dev_offset
] == PchSerialIoNotInitialized
))
223 return PCH_SERIAL_IO_INDEX(PchSerialIoPci
);
226 * Correct Enum index starts from 1, so subtract 1 while returning value
228 return PCH_SERIAL_IO_INDEX(config
->SerialIoDevMode
[dev_offset
]);
231 static void parse_devicetree(const config_t
*config
, FSP_S_CONFIG
*s_cfg
)
233 #if CONFIG(SOC_INTEL_COMETLAKE)
234 uint32_t dev_offset
= 0;
237 for (i
= 0; i
< CONFIG_SOC_INTEL_I2C_DEV_MAX
; i
++, dev_offset
++) {
238 s_cfg
->SerialIoI2cMode
[i
] =
239 get_param_value(config
, dev_offset
);
242 for (i
= 0; i
< CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX
; i
++,
244 s_cfg
->SerialIoSpiMode
[i
] =
245 get_param_value(config
, dev_offset
);
248 for (i
= 0; i
< SOC_INTEL_CML_UART_DEV_MAX
; i
++, dev_offset
++) {
249 s_cfg
->SerialIoUartMode
[i
] =
250 get_param_value(config
, dev_offset
);
253 for (int i
= 0; i
< ARRAY_SIZE(serial_io_dev
); i
++)
254 s_cfg
->SerialIoDevMode
[i
] = get_param_value(config
, i
);
258 /* Ignore LTR value for GBE devices */
259 static void ignore_gbe_ltr(void)
262 uint8_t *pmcbase
= pmc_mmio_regs();
264 reg8
= read8(pmcbase
+ LTR_IGN
);
266 write8(pmcbase
+ LTR_IGN
, reg8
);
269 static void configure_gspi_cs(int idx
, const config_t
*config
,
270 uint8_t *polarity
, uint8_t *enable
,
275 /* If speed_mhz is set, infer that the port should be configured */
276 if (config
->common_soc_config
.gspi
[idx
].speed_mhz
!= 0) {
277 if (gspi_get_soc_spi_cfg(idx
, &cfg
) == 0) {
278 if (cfg
.cs_polarity
== SPI_POLARITY_LOW
)
283 if (defaultcs
!= NULL
)
291 static const SI_PCH_DEVICE_INTERRUPT_CONFIG
*pci_irq_to_fsp(size_t *out_count
)
293 const struct pci_irq_entry
*entry
= get_cached_pci_irqs();
294 SI_PCH_DEVICE_INTERRUPT_CONFIG
*config
;
295 size_t pch_total
= 0;
296 size_t cfg_count
= 0;
301 /* Count PCH devices */
303 if (is_pch_slot(entry
->devfn
))
308 /* Convert PCH device entries to FSP format */
309 config
= calloc(pch_total
, sizeof(*config
));
310 entry
= get_cached_pci_irqs();
312 if (!is_pch_slot(entry
->devfn
)) {
317 config
[cfg_count
].Device
= PCI_SLOT(entry
->devfn
);
318 config
[cfg_count
].Function
= PCI_FUNC(entry
->devfn
);
319 config
[cfg_count
].IntX
= (SI_PCH_INT_PIN
)entry
->pin
;
320 config
[cfg_count
].Irq
= entry
->irq
;
326 *out_count
= cfg_count
;
331 /* UPD parameters to be initialized before SiliconInit */
332 void platform_fsp_silicon_init_params_cb(FSPS_UPD
*supd
)
335 FSP_S_CONFIG
*s_cfg
= &supd
->FspsConfig
;
336 FSP_S_TEST_CONFIG
*tconfig
= &supd
->FspsTestConfig
;
339 config_t
*config
= config_of_soc();
341 /* Parse device tree and enable/disable devices */
342 parse_devicetree(config
, s_cfg
);
344 /* Load VBT before devicetree-specific config. */
345 s_cfg
->GraphicsConfigPtr
= (uintptr_t)vbt_get();
347 mainboard_silicon_init_params(supd
);
349 const struct soc_power_limits_config
*soc_config
;
350 soc_config
= &config
->power_limits_config
;
351 /* Set PsysPmax if it is available from DT */
352 if (soc_config
->psys_pmax
) {
353 printk(BIOS_DEBUG
, "psys_pmax = %dW\n", soc_config
->psys_pmax
);
354 /* PsysPmax is in unit of 1/8 Watt */
355 tconfig
->PsysPmax
= soc_config
->psys_pmax
* 8;
358 /* Unlock upper 8 bytes of RTC RAM */
359 s_cfg
->PchLockDownRtcMemoryLock
= 0;
362 s_cfg
->SataEnable
= is_devfn_enabled(PCH_DEVFN_SATA
);
363 if (s_cfg
->SataEnable
) {
364 s_cfg
->SataMode
= config
->SataMode
;
365 s_cfg
->SataPwrOptEnable
= config
->satapwroptimize
;
366 s_cfg
->SataSalpSupport
= config
->SataSalpSupport
;
367 memcpy(s_cfg
->SataPortsEnable
, config
->SataPortsEnable
,
368 sizeof(s_cfg
->SataPortsEnable
));
369 memcpy(s_cfg
->SataPortsDevSlp
, config
->SataPortsDevSlp
,
370 sizeof(s_cfg
->SataPortsDevSlp
));
371 memcpy(s_cfg
->SataPortsHotPlug
, config
->SataPortsHotPlug
,
372 sizeof(s_cfg
->SataPortsHotPlug
));
373 #if CONFIG(SOC_INTEL_COMETLAKE)
374 memcpy(s_cfg
->SataPortsDevSlpResetConfig
,
375 config
->SataPortsDevSlpResetConfig
,
376 sizeof(s_cfg
->SataPortsDevSlpResetConfig
));
379 s_cfg
->SlpS0WithGbeSupport
= 0;
380 s_cfg
->PchPmSlpS0VmRuntimeControl
= config
->PchPmSlpS0VmRuntimeControl
;
381 s_cfg
->PchPmSlpS0Vm070VSupport
= config
->PchPmSlpS0Vm070VSupport
;
382 s_cfg
->PchPmSlpS0Vm075VSupport
= config
->PchPmSlpS0Vm075VSupport
;
385 s_cfg
->PchLanEnable
= is_devfn_enabled(PCH_DEVFN_GBE
);
386 if (s_cfg
->PchLanEnable
) {
387 if (config
->s0ix_enable
) {
389 * The VmControl UPDs need to be set as per board
390 * design to allow voltage margining in S0ix to lower
392 * But if GbE is enabled, voltage magining cannot be
393 * enabled, so the Vm control UPDs need to be set to 0.
395 s_cfg
->SlpS0WithGbeSupport
= 1;
396 s_cfg
->PchPmSlpS0VmRuntimeControl
= 0;
397 s_cfg
->PchPmSlpS0Vm070VSupport
= 0;
398 s_cfg
->PchPmSlpS0Vm075VSupport
= 0;
404 s_cfg
->PchHdaDspEnable
= config
->PchHdaDspEnable
;
405 s_cfg
->PchHdaIDispCodecDisconnect
= config
->PchHdaIDispCodecDisconnect
;
406 s_cfg
->PchHdaAudioLinkHda
= config
->PchHdaAudioLinkHda
;
407 s_cfg
->PchHdaAudioLinkDmic0
= config
->PchHdaAudioLinkDmic0
;
408 s_cfg
->PchHdaAudioLinkDmic1
= config
->PchHdaAudioLinkDmic1
;
409 s_cfg
->PchHdaAudioLinkSsp0
= config
->PchHdaAudioLinkSsp0
;
410 s_cfg
->PchHdaAudioLinkSsp1
= config
->PchHdaAudioLinkSsp1
;
411 s_cfg
->PchHdaAudioLinkSsp2
= config
->PchHdaAudioLinkSsp2
;
412 s_cfg
->PchHdaAudioLinkSndw1
= config
->PchHdaAudioLinkSndw1
;
413 s_cfg
->PchHdaAudioLinkSndw2
= config
->PchHdaAudioLinkSndw2
;
414 s_cfg
->PchHdaAudioLinkSndw3
= config
->PchHdaAudioLinkSndw3
;
415 s_cfg
->PchHdaAudioLinkSndw4
= config
->PchHdaAudioLinkSndw4
;
418 s_cfg
->DdiPortEdp
= config
->DdiPortEdp
;
420 /* HPD of DDI ports */
421 s_cfg
->DdiPortBHpd
= config
->DdiPortBHpd
;
422 s_cfg
->DdiPortCHpd
= config
->DdiPortCHpd
;
423 s_cfg
->DdiPortDHpd
= config
->DdiPortDHpd
;
424 s_cfg
->DdiPortFHpd
= config
->DdiPortFHpd
;
426 /* DDC of DDI ports */
427 s_cfg
->DdiPortBDdc
= config
->DdiPortBDdc
;
428 s_cfg
->DdiPortCDdc
= config
->DdiPortCDdc
;
429 s_cfg
->DdiPortDDdc
= config
->DdiPortDDdc
;
430 s_cfg
->DdiPortFDdc
= config
->DdiPortFDdc
;
433 s_cfg
->PchPmPcieWakeFromDeepSx
= config
->LanWakeFromDeepSx
;
434 s_cfg
->PchPmWolEnableOverride
= config
->WolEnableOverride
;
437 s_cfg
->PchPmSlpS0Enable
= config
->s0ix_enable
;
439 /* disable Legacy PME */
440 memset(s_cfg
->PcieRpPmSci
, 0, sizeof(s_cfg
->PcieRpPmSci
));
442 /* Legacy 8254 timer support */
443 bool use_8254
= get_uint_option("legacy_8254_timer", CONFIG(USE_LEGACY_8254_TIMER
));
444 s_cfg
->Enable8254ClockGating
= !use_8254
;
445 s_cfg
->Enable8254ClockGatingOnS3
= !use_8254
;
448 * Legacy PM ACPI Timer (and TCO Timer)
449 * This *must* be 1 in any case to keep FSP from
450 * 1) enabling PM ACPI Timer emulation in uCode.
451 * 2) disabling the PM ACPI Timer.
452 * We handle both by ourself!
454 s_cfg
->EnableTcoTimer
= 1;
457 for (i
= 0; i
< ARRAY_SIZE(config
->usb2_ports
); i
++) {
458 s_cfg
->PortUsb20Enable
[i
] = config
->usb2_ports
[i
].enable
;
459 s_cfg
->Usb2AfePetxiset
[i
] = config
->usb2_ports
[i
].pre_emp_bias
;
460 s_cfg
->Usb2AfeTxiset
[i
] = config
->usb2_ports
[i
].tx_bias
;
461 s_cfg
->Usb2AfePredeemp
[i
] =
462 config
->usb2_ports
[i
].tx_emp_enable
;
463 s_cfg
->Usb2AfePehalfbit
[i
] = config
->usb2_ports
[i
].pre_emp_bit
;
465 if (config
->usb2_ports
[i
].enable
)
466 s_cfg
->Usb2OverCurrentPin
[i
] = config
->usb2_ports
[i
].ocpin
;
468 s_cfg
->Usb2OverCurrentPin
[i
] = 0xff;
471 if (config
->PchUsb2PhySusPgDisable
)
472 s_cfg
->PchUsb2PhySusPgEnable
= 0;
474 for (i
= 0; i
< ARRAY_SIZE(config
->usb3_ports
); i
++) {
475 s_cfg
->PortUsb30Enable
[i
] = config
->usb3_ports
[i
].enable
;
476 if (config
->usb3_ports
[i
].enable
) {
477 s_cfg
->Usb3OverCurrentPin
[i
] = config
->usb3_ports
[i
].ocpin
;
479 s_cfg
->Usb3OverCurrentPin
[i
] = 0xff;
481 if (config
->usb3_ports
[i
].tx_de_emp
) {
482 s_cfg
->Usb3HsioTxDeEmphEnable
[i
] = 1;
483 s_cfg
->Usb3HsioTxDeEmph
[i
] =
484 config
->usb3_ports
[i
].tx_de_emp
;
486 if (config
->usb3_ports
[i
].tx_downscale_amp
) {
487 s_cfg
->Usb3HsioTxDownscaleAmpEnable
[i
] = 1;
488 s_cfg
->Usb3HsioTxDownscaleAmp
[i
] =
489 config
->usb3_ports
[i
].tx_downscale_amp
;
491 #if CONFIG(SOC_INTEL_COMETLAKE)
492 if (config
->usb3_ports
[i
].gen2_tx_rate0_uniq_tran_enable
) {
493 s_cfg
->Usb3HsioTxRate0UniqTranEnable
[i
] = 1;
494 s_cfg
->Usb3HsioTxRate0UniqTran
[i
] =
495 config
->usb3_ports
[i
].gen2_tx_rate0_uniq_tran
;
497 if (config
->usb3_ports
[i
].gen2_tx_rate1_uniq_tran_enable
) {
498 s_cfg
->Usb3HsioTxRate1UniqTranEnable
[i
] = 1;
499 s_cfg
->Usb3HsioTxRate1UniqTran
[i
] =
500 config
->usb3_ports
[i
].gen2_tx_rate1_uniq_tran
;
502 if (config
->usb3_ports
[i
].gen2_tx_rate2_uniq_tran_enable
) {
503 s_cfg
->Usb3HsioTxRate2UniqTranEnable
[i
] = 1;
504 s_cfg
->Usb3HsioTxRate2UniqTran
[i
] =
505 config
->usb3_ports
[i
].gen2_tx_rate2_uniq_tran
;
507 if (config
->usb3_ports
[i
].gen2_tx_rate3_uniq_tran_enable
) {
508 s_cfg
->Usb3HsioTxRate3UniqTranEnable
[i
] = 1;
509 s_cfg
->Usb3HsioTxRate3UniqTran
[i
] =
510 config
->usb3_ports
[i
].gen2_tx_rate3_uniq_tran
;
513 if (config
->usb3_ports
[i
].gen2_rx_tuning_enable
) {
514 s_cfg
->PchUsbHsioRxTuningEnable
[i
] =
515 config
->usb3_ports
[i
].gen2_rx_tuning_enable
;
516 s_cfg
->PchUsbHsioRxTuningParameters
[i
] =
517 config
->usb3_ports
[i
].gen2_rx_tuning_params
;
518 s_cfg
->PchUsbHsioFilterSel
[i
] =
519 config
->usb3_ports
[i
].gen2_rx_filter_sel
;
523 s_cfg
->XdciEnable
= xdci_can_enable(PCH_DEVFN_USBOTG
);
525 /* Set Debug serial port */
526 s_cfg
->SerialIoDebugUartNumber
= CONFIG_UART_FOR_CONSOLE
;
527 #if !CONFIG(SOC_INTEL_COMETLAKE)
528 s_cfg
->SerialIoEnableDebugUartAfterPost
= CONFIG(INTEL_LPSS_UART_FOR_CONSOLE
);
531 /* Enable CNVi Wifi if enabled in device tree */
532 #if CONFIG(SOC_INTEL_COMETLAKE)
533 struct device
*port
= NULL
;
534 struct drivers_usb_acpi_config
*usb_cfg
= NULL
;
535 bool usb_audio_offload
= false;
537 /* Search through the devicetree for matching USB devices */
538 while ((port
= dev_find_path(port
, DEVICE_PATH_USB
)) != NULL
) {
539 /* Skip ports that are not enabled or not of USB type */
540 if (!port
->enabled
|| port
->path
.type
!= DEVICE_PATH_USB
)
543 usb_cfg
= port
->chip_info
;
544 if (usb_cfg
&& usb_cfg
->cnvi_bt_audio_offload
) {
545 usb_audio_offload
= true;
551 s_cfg
->CnviMode
= is_devfn_enabled(PCH_DEVFN_CNViWIFI
);
552 s_cfg
->CnviBtCore
= config
->CnviBtCore
;
553 s_cfg
->CnviBtAudioOffload
= config
->CnviBtAudioOffload
;
555 if (!s_cfg
->CnviBtCore
&& s_cfg
->CnviBtAudioOffload
) {
556 printk(BIOS_ERR
, "BT offload is enabled without CNVi BT being enabled\n");
557 s_cfg
->CnviBtAudioOffload
= 0;
559 if (!s_cfg
->CnviMode
&& s_cfg
->CnviBtCore
) {
560 printk(BIOS_ERR
, "CNVi BT is enabled without CNVi being enabled\n");
561 s_cfg
->CnviBtCore
= 0;
562 s_cfg
->CnviBtAudioOffload
= 0;
564 if (s_cfg
->CnviBtAudioOffload
&& !usb_audio_offload
) {
565 printk(BIOS_WARNING
, "CNVi BT Audio offload enabled but not in USB driver.\n");
567 if (!s_cfg
->CnviBtAudioOffload
&& usb_cfg
&& usb_audio_offload
) {
568 printk(BIOS_ERR
, "USB BT Audio offload enabled but CNVi BT offload disabled\n");
569 usb_cfg
->cnvi_bt_audio_offload
= 0;
572 s_cfg
->PchCnviMode
= is_devfn_enabled(PCH_DEVFN_CNViWIFI
);
575 for (i
= 0; i
< ARRAY_SIZE(config
->PcieClkSrcUsage
); i
++) {
576 if (config
->PcieClkSrcUsage
[i
] == 0)
577 config
->PcieClkSrcUsage
[i
] = PCIE_CLK_NOTUSED
;
578 else if (config
->PcieClkSrcUsage
[i
] == PCIE_CLK_RP0
)
579 config
->PcieClkSrcUsage
[i
] = 0;
581 memcpy(s_cfg
->PcieClkSrcUsage
, config
->PcieClkSrcUsage
,
582 sizeof(config
->PcieClkSrcUsage
));
583 memcpy(s_cfg
->PcieClkSrcClkReq
, config
->PcieClkSrcClkReq
,
584 sizeof(config
->PcieClkSrcClkReq
));
586 memcpy(s_cfg
->PcieRpAdvancedErrorReporting
,
587 config
->PcieRpAdvancedErrorReporting
,
588 sizeof(config
->PcieRpAdvancedErrorReporting
));
590 memcpy(s_cfg
->PcieRpLtrEnable
, config
->PcieRpLtrEnable
,
591 sizeof(config
->PcieRpLtrEnable
));
592 memcpy(s_cfg
->PcieRpSlotImplemented
, config
->PcieRpSlotImplemented
,
593 sizeof(config
->PcieRpSlotImplemented
));
594 memcpy(s_cfg
->PcieRpHotPlug
, config
->PcieRpHotPlug
,
595 sizeof(config
->PcieRpHotPlug
));
597 for (i
= 0; i
< CONFIG_MAX_ROOT_PORTS
; i
++) {
598 s_cfg
->PcieRpMaxPayload
[i
] = config
->PcieRpMaxPayload
[i
];
599 if (config
->PcieRpAspm
[i
])
600 s_cfg
->PcieRpAspm
[i
] = config
->PcieRpAspm
[i
] - 1;
604 s_cfg
->ScsEmmcEnabled
= is_devfn_enabled(PCH_DEVFN_EMMC
);
605 if (s_cfg
->ScsEmmcEnabled
) {
606 s_cfg
->ScsEmmcHs400Enabled
= config
->ScsEmmcHs400Enabled
;
607 s_cfg
->PchScsEmmcHs400DllDataValid
= config
->EmmcHs400DllNeed
;
608 if (config
->EmmcHs400DllNeed
== 1) {
609 s_cfg
->PchScsEmmcHs400RxStrobeDll1
=
610 config
->EmmcHs400RxStrobeDll1
;
611 s_cfg
->PchScsEmmcHs400TxDataDll
=
612 config
->EmmcHs400TxDataDll
;
616 s_cfg
->ScsSdCardEnabled
= is_devfn_enabled(PCH_DEVFN_SDCARD
);
617 if (s_cfg
->ScsSdCardEnabled
) {
618 s_cfg
->SdCardPowerEnableActiveHigh
= CONFIG(MB_HAS_ACTIVE_HIGH_SD_PWR_ENABLE
);
619 #if CONFIG(SOC_INTEL_COMETLAKE)
620 s_cfg
->ScsSdCardWpPinEnabled
= config
->ScsSdCardWpPinEnabled
;
624 s_cfg
->ScsUfsEnabled
= is_devfn_enabled(PCH_DEVFN_UFS
);
626 s_cfg
->Heci3Enabled
= is_devfn_enabled(PCH_DEVFN_CSE_3
);
628 * coreboot will handle disabling of HECI1 device if `DISABLE_HECI1_AT_PRE_BOOT`
629 * config is selected hence, don't let FSP to disable the HECI1 device and set
630 * the `Heci1Disabled` UPD to `0`.
632 s_cfg
->Heci1Disabled
= 0;
633 s_cfg
->Device4Enable
= config
->Device4Enable
;
635 /* Teton Glacier hybrid storage support */
636 s_cfg
->TetonGlacierMode
= config
->TetonGlacierMode
;
638 /* VrConfig Settings for 5 domains
639 * 0 = System Agent, 1 = IA Core, 2 = Ring,
640 * 3 = GT unsliced, 4 = GT sliced */
641 for (i
= 0; i
< ARRAY_SIZE(config
->domain_vr_config
); i
++)
642 fill_vr_domain_config(s_cfg
, i
, &config
->domain_vr_config
[i
]);
644 /* Acoustic Noise Mitigation */
645 s_cfg
->AcousticNoiseMitigation
= config
->AcousticNoiseMitigation
;
646 s_cfg
->SlowSlewRateForIa
= config
->SlowSlewRateForIa
;
647 s_cfg
->SlowSlewRateForGt
= config
->SlowSlewRateForGt
;
648 s_cfg
->SlowSlewRateForSa
= config
->SlowSlewRateForSa
;
649 s_cfg
->SlowSlewRateForFivr
= config
->SlowSlewRateForFivr
;
650 s_cfg
->FastPkgCRampDisableIa
= config
->FastPkgCRampDisableIa
;
651 s_cfg
->FastPkgCRampDisableGt
= config
->FastPkgCRampDisableGt
;
652 s_cfg
->FastPkgCRampDisableSa
= config
->FastPkgCRampDisableSa
;
653 s_cfg
->FastPkgCRampDisableFivr
= config
->FastPkgCRampDisableFivr
;
655 /* Apply minimum assertion width settings if non-zero */
656 if (config
->PchPmSlpS3MinAssert
)
657 s_cfg
->PchPmSlpS3MinAssert
= config
->PchPmSlpS3MinAssert
;
658 if (config
->PchPmSlpS4MinAssert
)
659 s_cfg
->PchPmSlpS4MinAssert
= config
->PchPmSlpS4MinAssert
;
660 if (config
->PchPmSlpSusMinAssert
)
661 s_cfg
->PchPmSlpSusMinAssert
= config
->PchPmSlpSusMinAssert
;
662 if (config
->PchPmSlpAMinAssert
)
663 s_cfg
->PchPmSlpAMinAssert
= config
->PchPmSlpAMinAssert
;
665 #if CONFIG(SOC_INTEL_COMETLAKE)
666 if (config
->PchPmPwrCycDur
)
667 s_cfg
->PchPmPwrCycDur
= get_pm_pwr_cyc_dur(config
->PchPmSlpS4MinAssert
,
668 config
->PchPmSlpS3MinAssert
, config
->PchPmSlpAMinAssert
,
669 config
->PchPmPwrCycDur
);
672 /* Set TccActivationOffset */
673 tconfig
->TccActivationOffset
= config
->tcc_offset
;
674 tconfig
->TccOffsetClamp
= config
->tcc_offset
> 0;
676 /* Unlock all GPIO pads */
677 tconfig
->PchUnlockGpioPads
= config
->PchUnlockGpioPads
;
679 /* Set correct Sirq mode based on config */
680 s_cfg
->PchSirqEnable
= config
->serirq_mode
!= SERIRQ_OFF
;
681 s_cfg
->PchSirqMode
= config
->serirq_mode
== SERIRQ_CONTINUOUS
;
684 * GSPI Chip Select parameters
685 * The GSPI driver assumes that CS0 is the used chip-select line,
686 * therefore only CS0 is configured below.
688 #if CONFIG(SOC_INTEL_COMETLAKE)
689 configure_gspi_cs(0, config
, &s_cfg
->SerialIoSpi0CsPolarity
[0],
690 &s_cfg
->SerialIoSpi0CsEnable
[0],
691 &s_cfg
->SerialIoSpiDefaultCsOutput
[0]);
692 configure_gspi_cs(1, config
, &s_cfg
->SerialIoSpi1CsPolarity
[0],
693 &s_cfg
->SerialIoSpi1CsEnable
[0],
694 &s_cfg
->SerialIoSpiDefaultCsOutput
[1]);
695 configure_gspi_cs(2, config
, &s_cfg
->SerialIoSpi2CsPolarity
[0],
696 &s_cfg
->SerialIoSpi2CsEnable
[0],
697 &s_cfg
->SerialIoSpiDefaultCsOutput
[2]);
699 for (i
= 0; i
< CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX
; i
++)
700 configure_gspi_cs(i
, config
,
701 &s_cfg
->SerialIoSpiCsPolarity
[0], NULL
, NULL
);
704 /* Chipset Lockdown */
705 const bool lockdown_by_fsp
= get_lockdown_config() == CHIPSET_LOCKDOWN_FSP
;
706 tconfig
->PchLockDownGlobalSmi
= lockdown_by_fsp
;
707 tconfig
->PchLockDownBiosInterface
= lockdown_by_fsp
;
708 s_cfg
->PchLockDownBiosLock
= lockdown_by_fsp
;
709 s_cfg
->PchLockDownRtcMemoryLock
= lockdown_by_fsp
;
710 tconfig
->SkipPamLock
= !lockdown_by_fsp
;
711 #if CONFIG(SOC_INTEL_COMETLAKE)
713 * Making this config "0" means FSP won't set the FLOCKDN bit
714 * of SPIBAR + 0x04 (i.e., Bit 15 of BIOS_HSFSTS_CTL).
715 * So, it becomes coreboot's responsibility to set this bit
716 * before end of POST for security concerns.
718 s_cfg
->SpiFlashCfgLockDown
= lockdown_by_fsp
;
721 #if !CONFIG(SOC_INTEL_COMETLAKE)
722 s_cfg
->VrPowerDeliveryDesign
= config
->VrPowerDeliveryDesign
;
725 s_cfg
->PeiGraphicsPeimInit
= CONFIG(RUN_FSP_GOP
) && is_devfn_enabled(SA_DEVFN_IGD
);
727 s_cfg
->PavpEnable
= CONFIG(PAVP
);
730 * Prevent FSP from programming write-once subsystem IDs by providing
731 * a custom SSID table. Must have at least one entry for the FSP to
734 struct svid_ssid_init_entry
{
737 uint64_t reg
:12; /* Register offset */
745 uint64_t segbusdevfuncregister
;
755 * The xHCI and HDA devices have RW/L rather than RW/O registers for
756 * subsystem IDs and so must be written before FspSiliconInit locks
757 * them with their default values.
759 const pci_devfn_t devfn_table
[] = { PCH_DEVFN_XHCI
, PCH_DEVFN_HDA
};
760 static struct svid_ssid_init_entry ssid_table
[ARRAY_SIZE(devfn_table
)];
762 for (i
= 0; i
< ARRAY_SIZE(devfn_table
); i
++) {
763 ssid_table
[i
].reg
= PCI_SUBSYSTEM_VENDOR_ID
;
764 ssid_table
[i
].device
= PCI_SLOT(devfn_table
[i
]);
765 ssid_table
[i
].function
= PCI_FUNC(devfn_table
[i
]);
766 dev
= pcidev_path_on_root(devfn_table
[i
]);
768 ssid_table
[i
].svid
= dev
->subsystem_vendor
;
769 ssid_table
[i
].ssid
= dev
->subsystem_device
;
773 s_cfg
->SiSsidTablePtr
= (uintptr_t)ssid_table
;
774 s_cfg
->SiNumberOfSsidTableEntry
= ARRAY_SIZE(ssid_table
);
776 /* Assign PCI IRQs */
777 if (!assign_pci_irqs(irq_constraints
, ARRAY_SIZE(irq_constraints
)))
778 die("ERROR: Unable to assign PCI IRQs, and no ACPI _PRT table is defined\n");
780 size_t pch_count
= 0;
781 const SI_PCH_DEVICE_INTERRUPT_CONFIG
*upd_irqs
= pci_irq_to_fsp(&pch_count
);
782 s_cfg
->DevIntConfigPtr
= (UINT32
)((uintptr_t)upd_irqs
);
783 s_cfg
->NumOfDevIntConfig
= pch_count
;
784 printk(BIOS_INFO
, "IRQ: Using dynamically assigned PCI IO-APIC IRQs\n");
787 /* Mainboard GPIO Configuration */
788 __weak
void mainboard_silicon_init_params(FSPS_UPD
*supd
)
790 printk(BIOS_DEBUG
, "WEAK: %s/%s called\n", __FILE__
, __func__
);
793 /* Handle FSP logo params */
794 void soc_load_logo(FSPS_UPD
*supd
)
797 supd
->FspsConfig
.LogoPtr
= (uintptr_t)bmp_load_logo(&logo_size
);
798 supd
->FspsConfig
.LogoSize
= (uint32_t)logo_size
;