mb/starlabs/{lite_adl,byte_adl}: Don't select MAINBOARD_HAS_TPM2
[coreboot2.git] / src / soc / intel / alderlake / fsp_params.c
blob8c4c29122d29e6872415747c9dcbaf4fd2f27e02
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <assert.h>
4 #include <bootmode.h>
5 #include <bootsplash.h>
6 #include <console/console.h>
7 #include <cpu/intel/microcode.h>
8 #include <delay.h>
9 #include <device/device.h>
10 #include <device/pci.h>
11 #include <device/pci_ids.h>
12 #include <device/pci_ops.h>
13 #include <drivers/intel/gma/i915_reg.h>
14 #include <fsp/api.h>
15 #include <fsp/fsp_debug_event.h>
16 #include <fsp/fsp_gop_blt.h>
17 #include <fsp/ppi/mp_service_ppi.h>
18 #include <fsp/util.h>
19 #include <gpio.h>
20 #include <intelblocks/irq.h>
21 #include <intelblocks/lpss.h>
22 #include <intelblocks/mp_init.h>
23 #include <intelblocks/pmclib.h>
24 #include <intelblocks/xdci.h>
25 #include <intelpch/lockdown.h>
26 #include <intelblocks/systemagent.h>
27 #include <intelblocks/tcss.h>
28 #include <option.h>
29 #include <soc/cpu.h>
30 #include <soc/intel/common/vbt.h>
31 #include <soc/pci_devs.h>
32 #include <soc/pcie.h>
33 #include <soc/ramstage.h>
34 #include <soc/soc_chip.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <types.h>
39 /* THC assignment definition */
40 #define THC_NONE 0
41 #define THC_0 1
42 #define THC_1 2
44 /* SATA DEVSLP idle timeout default values */
45 #define DEF_DMVAL 15
46 #define DEF_DITOVAL 625
48 /* VccIn Aux Imon IccMax values in mA */
49 #define MILLIAMPS_TO_AMPS 1000
50 #define ICC_MAX_TDP_45W 34250
51 #define ICC_MAX_TDP_15W_28W 32000
52 #define ICC_MAX_ID_ADL_M_MA 12000
53 #define ICC_MAX_ID_ADL_N_MA 27000
54 #define ICC_MAX_ADL_S 33000
55 #define ICC_MAX_RPL_S 36000
58 * ME End of Post configuration
59 * 0 - Disable EOP.
60 * 1 - Send in PEI (Applicable for FSP in API mode)
61 * 2 - Send in DXE (Not applicable for FSP in API mode)
63 enum fsp_end_of_post {
64 EOP_DISABLE = 0,
65 EOP_PEI = 1,
66 EOP_DXE = 2,
69 static const struct slot_irq_constraints irq_constraints[] = {
71 .slot = SA_DEV_SLOT_CPU_1,
72 .fns = {
73 FIXED_INT_PIRQ(SA_DEVFN_CPU_PCIE1_0, PCI_INT_A, PIRQ_A),
77 .slot = SA_DEV_SLOT_IGD,
78 .fns = {
79 /* INTERRUPT_PIN is RO/0x01 */
80 FIXED_INT_ANY_PIRQ(SA_DEVFN_IGD, PCI_INT_A),
84 .slot = SA_DEV_SLOT_DPTF,
85 .fns = {
86 ANY_PIRQ(SA_DEVFN_DPTF),
90 .slot = SA_DEV_SLOT_IPU,
91 .fns = {
92 /* INTERRUPT_PIN is RO/0x01, and INTERRUPT_LINE is RW,
93 but S0ix fails when not set to 16 (b/193434192) */
94 FIXED_INT_PIRQ(SA_DEVFN_IPU, PCI_INT_A, PIRQ_A),
98 .slot = SA_DEV_SLOT_CPU_6,
99 .fns = {
100 FIXED_INT_PIRQ(SA_DEVFN_CPU_PCIE6_0, PCI_INT_A, PIRQ_A),
101 FIXED_INT_PIRQ(SA_DEVFN_CPU_PCIE6_2, PCI_INT_C, PIRQ_C),
105 .slot = SA_DEV_SLOT_TBT,
106 .fns = {
107 ANY_PIRQ(SA_DEVFN_TBT0),
108 ANY_PIRQ(SA_DEVFN_TBT1),
109 ANY_PIRQ(SA_DEVFN_TBT2),
110 ANY_PIRQ(SA_DEVFN_TBT3),
114 .slot = SA_DEV_SLOT_GNA,
115 .fns = {
116 /* INTERRUPT_PIN is RO/0x01 */
117 FIXED_INT_ANY_PIRQ(SA_DEVFN_GNA, PCI_INT_A),
121 .slot = SA_DEV_SLOT_TCSS,
122 .fns = {
123 ANY_PIRQ(SA_DEVFN_TCSS_XHCI),
124 ANY_PIRQ(SA_DEVFN_TCSS_XDCI),
128 .slot = PCH_DEV_SLOT_SIO0,
129 .fns = {
130 DIRECT_IRQ(PCH_DEVFN_I2C6),
131 DIRECT_IRQ(PCH_DEVFN_I2C7),
132 ANY_PIRQ(PCH_DEVFN_THC0),
133 ANY_PIRQ(PCH_DEVFN_THC1),
137 .slot = PCH_DEV_SLOT_SIO6,
138 .fns = {
139 DIRECT_IRQ(PCH_DEVFN_UART3),
140 DIRECT_IRQ(PCH_DEVFN_UART4),
141 DIRECT_IRQ(PCH_DEVFN_UART5),
142 DIRECT_IRQ(PCH_DEVFN_UART6),
146 .slot = PCH_DEV_SLOT_ISH,
147 .fns = {
148 DIRECT_IRQ(PCH_DEVFN_ISH),
149 DIRECT_IRQ(PCH_DEVFN_GSPI2),
150 ANY_PIRQ(PCH_DEVFN_UFS),
154 .slot = PCH_DEV_SLOT_SIO2,
155 .fns = {
156 DIRECT_IRQ(PCH_DEVFN_GSPI3),
157 DIRECT_IRQ(PCH_DEVFN_GSPI4),
158 DIRECT_IRQ(PCH_DEVFN_GSPI5),
159 DIRECT_IRQ(PCH_DEVFN_GSPI6),
163 .slot = PCH_DEV_SLOT_XHCI,
164 .fns = {
165 ANY_PIRQ(PCH_DEVFN_XHCI),
166 DIRECT_IRQ(PCH_DEVFN_USBOTG),
167 ANY_PIRQ(PCH_DEVFN_CNVI_WIFI),
171 .slot = PCH_DEV_SLOT_SIO3,
172 .fns = {
173 DIRECT_IRQ(PCH_DEVFN_I2C0),
174 DIRECT_IRQ(PCH_DEVFN_I2C1),
175 DIRECT_IRQ(PCH_DEVFN_I2C2),
176 DIRECT_IRQ(PCH_DEVFN_I2C3),
180 .slot = PCH_DEV_SLOT_CSE,
181 .fns = {
182 ANY_PIRQ(PCH_DEVFN_CSE),
183 ANY_PIRQ(PCH_DEVFN_CSE_2),
184 ANY_PIRQ(PCH_DEVFN_CSE_IDER),
185 ANY_PIRQ(PCH_DEVFN_CSE_KT),
186 ANY_PIRQ(PCH_DEVFN_CSE_3),
187 ANY_PIRQ(PCH_DEVFN_CSE_4),
191 .slot = PCH_DEV_SLOT_SATA,
192 .fns = {
193 ANY_PIRQ(PCH_DEVFN_SATA),
197 .slot = PCH_DEV_SLOT_SIO4,
198 .fns = {
199 DIRECT_IRQ(PCH_DEVFN_I2C4),
200 DIRECT_IRQ(PCH_DEVFN_I2C5),
201 DIRECT_IRQ(PCH_DEVFN_UART2),
204 #if CONFIG(SOC_INTEL_ALDERLAKE_PCH_N)
206 .slot = PCH_DEV_SLOT_EMMC,
207 .fns = {
208 ANY_PIRQ(PCH_DEVFN_EMMC),
211 #endif
213 .slot = PCH_DEV_SLOT_PCIE,
214 .fns = {
215 FIXED_INT_PIRQ(PCH_DEVFN_PCIE1, PCI_INT_A, PIRQ_A),
216 FIXED_INT_PIRQ(PCH_DEVFN_PCIE2, PCI_INT_B, PIRQ_B),
217 FIXED_INT_PIRQ(PCH_DEVFN_PCIE3, PCI_INT_C, PIRQ_C),
218 FIXED_INT_PIRQ(PCH_DEVFN_PCIE4, PCI_INT_D, PIRQ_D),
219 FIXED_INT_PIRQ(PCH_DEVFN_PCIE5, PCI_INT_A, PIRQ_A),
220 FIXED_INT_PIRQ(PCH_DEVFN_PCIE6, PCI_INT_B, PIRQ_B),
221 FIXED_INT_PIRQ(PCH_DEVFN_PCIE7, PCI_INT_C, PIRQ_C),
222 FIXED_INT_PIRQ(PCH_DEVFN_PCIE8, PCI_INT_D, PIRQ_D),
226 .slot = PCH_DEV_SLOT_PCIE_1,
227 .fns = {
228 FIXED_INT_PIRQ(PCH_DEVFN_PCIE9, PCI_INT_A, PIRQ_A),
229 FIXED_INT_PIRQ(PCH_DEVFN_PCIE10, PCI_INT_B, PIRQ_B),
230 FIXED_INT_PIRQ(PCH_DEVFN_PCIE11, PCI_INT_C, PIRQ_C),
231 FIXED_INT_PIRQ(PCH_DEVFN_PCIE12, PCI_INT_D, PIRQ_D),
235 .slot = PCH_DEV_SLOT_SIO5,
236 .fns = {
237 /* UART0 shares an interrupt line with TSN0, so must use
238 a PIRQ */
239 FIXED_INT_ANY_PIRQ(PCH_DEVFN_UART0, PCI_INT_A),
240 /* UART1 shares an interrupt line with TSN1, so must use
241 a PIRQ */
242 FIXED_INT_ANY_PIRQ(PCH_DEVFN_UART1, PCI_INT_B),
243 DIRECT_IRQ(PCH_DEVFN_GSPI0),
244 DIRECT_IRQ(PCH_DEVFN_GSPI1),
248 .slot = PCH_DEV_SLOT_ESPI,
249 .fns = {
250 ANY_PIRQ(PCH_DEVFN_HDA),
251 ANY_PIRQ(PCH_DEVFN_SMBUS),
252 ANY_PIRQ(PCH_DEVFN_GBE),
253 /* INTERRUPT_PIN is RO/0x01 */
254 FIXED_INT_ANY_PIRQ(PCH_DEVFN_TRACEHUB, PCI_INT_A),
259 static const struct slot_irq_constraints irq_constraints_pch_s[] = {
261 .slot = SA_DEV_SLOT_CPU_1,
262 .fns = {
263 FIXED_INT_PIRQ(SA_DEVFN_CPU_PCIE1_0, PCI_INT_A, PIRQ_A),
264 FIXED_INT_PIRQ(SA_DEVFN_CPU_PCIE1_1, PCI_INT_B, PIRQ_B),
268 .slot = SA_DEV_SLOT_IGD,
269 .fns = {
270 /* INTERRUPT_PIN is RO/0x01 */
271 FIXED_INT_ANY_PIRQ(SA_DEVFN_IGD, PCI_INT_A),
275 .slot = SA_DEV_SLOT_DPTF,
276 .fns = {
277 ANY_PIRQ(SA_DEVFN_DPTF),
281 .slot = SA_DEV_SLOT_CPU_6,
282 .fns = {
283 FIXED_INT_PIRQ(SA_DEVFN_CPU_PCIE6_0, PCI_INT_D, PIRQ_A),
287 .slot = SA_DEV_SLOT_GNA,
288 .fns = {
289 /* INTERRUPT_PIN is RO/0x01 */
290 FIXED_INT_ANY_PIRQ(SA_DEVFN_GNA, PCI_INT_A),
294 .slot = PCH_DEV_SLOT_SIO6,
295 .fns = {
296 DIRECT_IRQ(PCH_DEVFN_UART3),
300 .slot = PCH_DEV_SLOT_ISH,
301 .fns = {
302 DIRECT_IRQ(PCH_DEVFN_ISH),
303 DIRECT_IRQ(PCH_DEVFN_GSPI2),
307 .slot = PCH_DEV_SLOT_SIO2,
308 .fns = {
309 DIRECT_IRQ(PCH_DEVFN_GSPI3),
313 .slot = PCH_DEV_SLOT_XHCI,
314 .fns = {
315 ANY_PIRQ(PCH_DEVFN_XHCI),
316 DIRECT_IRQ(PCH_DEVFN_USBOTG),
317 ANY_PIRQ(PCH_DEVFN_CNVI_WIFI),
321 .slot = PCH_DEV_SLOT_SIO3,
322 .fns = {
323 DIRECT_IRQ(PCH_DEVFN_I2C0),
324 DIRECT_IRQ(PCH_DEVFN_I2C1),
325 DIRECT_IRQ(PCH_DEVFN_I2C2),
326 DIRECT_IRQ(PCH_DEVFN_I2C3),
330 .slot = PCH_DEV_SLOT_CSE,
331 .fns = {
332 ANY_PIRQ(PCH_DEVFN_CSE),
333 ANY_PIRQ(PCH_DEVFN_CSE_2),
334 ANY_PIRQ(PCH_DEVFN_CSE_IDER),
335 ANY_PIRQ(PCH_DEVFN_CSE_KT),
336 ANY_PIRQ(PCH_DEVFN_CSE_3),
337 ANY_PIRQ(PCH_DEVFN_CSE_4),
341 .slot = PCH_DEV_SLOT_SATA,
342 .fns = {
343 ANY_PIRQ(PCH_DEVFN_SATA),
347 .slot = PCH_DEV_SLOT_SIO4,
348 .fns = {
349 DIRECT_IRQ(PCH_DEVFN_I2C4),
350 DIRECT_IRQ(PCH_DEVFN_I2C5),
351 DIRECT_IRQ(PCH_DEVFN_UART2),
355 .slot = PCH_DEV_SLOT_PCIE,
356 .fns = {
357 FIXED_INT_PIRQ(PCH_DEVFN_PCIE1, PCI_INT_A, PIRQ_A),
358 FIXED_INT_PIRQ(PCH_DEVFN_PCIE2, PCI_INT_B, PIRQ_B),
359 FIXED_INT_PIRQ(PCH_DEVFN_PCIE3, PCI_INT_C, PIRQ_C),
360 FIXED_INT_PIRQ(PCH_DEVFN_PCIE4, PCI_INT_D, PIRQ_D),
361 FIXED_INT_PIRQ(PCH_DEVFN_PCIE5, PCI_INT_A, PIRQ_A),
362 FIXED_INT_PIRQ(PCH_DEVFN_PCIE6, PCI_INT_B, PIRQ_B),
363 FIXED_INT_PIRQ(PCH_DEVFN_PCIE7, PCI_INT_C, PIRQ_C),
364 FIXED_INT_PIRQ(PCH_DEVFN_PCIE8, PCI_INT_D, PIRQ_D),
368 .slot = PCH_DEV_SLOT_PCIE_1,
369 .fns = {
370 FIXED_INT_PIRQ(PCH_DEVFN_PCIE9, PCI_INT_A, PIRQ_A),
371 FIXED_INT_PIRQ(PCH_DEVFN_PCIE10, PCI_INT_B, PIRQ_B),
372 FIXED_INT_PIRQ(PCH_DEVFN_PCIE11, PCI_INT_C, PIRQ_C),
373 FIXED_INT_PIRQ(PCH_DEVFN_PCIE12, PCI_INT_D, PIRQ_D),
374 FIXED_INT_PIRQ(PCH_DEVFN_PCIE13, PCI_INT_A, PIRQ_A),
375 FIXED_INT_PIRQ(PCH_DEVFN_PCIE14, PCI_INT_B, PIRQ_B),
376 FIXED_INT_PIRQ(PCH_DEVFN_PCIE15, PCI_INT_C, PIRQ_C),
377 FIXED_INT_PIRQ(PCH_DEVFN_PCIE16, PCI_INT_D, PIRQ_D),
381 .slot = PCH_DEV_SLOT_PCIE_2,
382 .fns = {
383 FIXED_INT_PIRQ(PCH_DEVFN_PCIE17, PCI_INT_A, PIRQ_A),
384 FIXED_INT_PIRQ(PCH_DEVFN_PCIE18, PCI_INT_B, PIRQ_B),
385 FIXED_INT_PIRQ(PCH_DEVFN_PCIE19, PCI_INT_C, PIRQ_C),
386 FIXED_INT_PIRQ(PCH_DEVFN_PCIE20, PCI_INT_D, PIRQ_D),
387 FIXED_INT_PIRQ(PCH_DEVFN_PCIE21, PCI_INT_A, PIRQ_A),
388 FIXED_INT_PIRQ(PCH_DEVFN_PCIE22, PCI_INT_B, PIRQ_B),
389 FIXED_INT_PIRQ(PCH_DEVFN_PCIE23, PCI_INT_C, PIRQ_C),
390 FIXED_INT_PIRQ(PCH_DEVFN_PCIE24, PCI_INT_D, PIRQ_D),
394 .slot = PCH_DEV_SLOT_PCIE_3,
395 .fns = {
396 FIXED_INT_PIRQ(PCH_DEVFN_PCIE25, PCI_INT_A, PIRQ_A),
397 FIXED_INT_PIRQ(PCH_DEVFN_PCIE26, PCI_INT_B, PIRQ_B),
398 FIXED_INT_PIRQ(PCH_DEVFN_PCIE27, PCI_INT_C, PIRQ_C),
399 FIXED_INT_PIRQ(PCH_DEVFN_PCIE28, PCI_INT_D, PIRQ_D),
403 .slot = PCH_DEV_SLOT_SIO5,
404 .fns = {
405 /* UART0 shares an interrupt line with TSN0, so must use
406 a PIRQ */
407 FIXED_INT_ANY_PIRQ(PCH_DEVFN_UART0, PCI_INT_A),
408 /* UART1 shares an interrupt line with TSN1, so must use
409 a PIRQ */
410 FIXED_INT_ANY_PIRQ(PCH_DEVFN_UART1, PCI_INT_B),
411 DIRECT_IRQ(PCH_DEVFN_GSPI0),
412 DIRECT_IRQ(PCH_DEVFN_GSPI1),
416 .slot = PCH_DEV_SLOT_ESPI,
417 .fns = {
418 ANY_PIRQ(PCH_DEVFN_HDA),
419 ANY_PIRQ(PCH_DEVFN_SMBUS),
420 ANY_PIRQ(PCH_DEVFN_GBE),
421 /* INTERRUPT_PIN is RO/0x01 */
422 FIXED_INT_ANY_PIRQ(PCH_DEVFN_TRACEHUB, PCI_INT_A),
427 static const SI_PCH_DEVICE_INTERRUPT_CONFIG *pci_irq_to_fsp(size_t *out_count)
429 const struct pci_irq_entry *entry = get_cached_pci_irqs();
430 SI_PCH_DEVICE_INTERRUPT_CONFIG *config;
431 size_t pch_total = 0;
432 size_t cfg_count = 0;
434 if (!entry)
435 return NULL;
437 /* Count PCH devices */
438 while (entry) {
439 if (is_pch_slot(entry->devfn))
440 ++pch_total;
441 entry = entry->next;
444 /* Convert PCH device entries to FSP format */
445 config = calloc(pch_total, sizeof(*config));
446 entry = get_cached_pci_irqs();
447 while (entry) {
448 if (!is_pch_slot(entry->devfn)) {
449 entry = entry->next;
450 continue;
453 config[cfg_count].Device = PCI_SLOT(entry->devfn);
454 config[cfg_count].Function = PCI_FUNC(entry->devfn);
455 config[cfg_count].IntX = (SI_PCH_INT_PIN)entry->pin;
456 config[cfg_count].Irq = entry->irq;
457 ++cfg_count;
459 entry = entry->next;
462 *out_count = cfg_count;
464 return config;
468 * The PCIe RP ASPM and PCIe L1 Substate UPDs follow the PCI Express Base
469 * Specification 1.1. The UPDs and their default values are consistent
470 * from Skylake through Meteor Lake. However, the default for CPU ports
471 * differs from PCH ports. Use auto and maximum unless overwritten
472 * to make the behaviour consistent.
474 * +-------------------+--------------------------+-----------+-----------+
475 * | Setting | Option | PCH Ports | CPU Ports |
476 * |-------------------|--------------------------|-----------|-----------|
477 * | PcieRpEnableCpm | Disabled | [Default] | [Default] |
478 * | | Enabled | | |
479 * |-------------------|--------------------------|-----------|-----------|
480 * | PcieRpAspm | PchPcieAspmDisabled | | |
481 * | | PchPcieAspmL0s | | |
482 * | | PchPcieAspmL1 | | |
483 * | | PchPcieAspmL0sL1 | | [Default] |
484 * | | PchPcieAspmAutoConfig | [Default] | |
485 * | | PchPcieAspmMax | | |
486 * |-------------------|--------------------------|-----------|-----------|
487 * | PcieRpL1Substates | Disabled | | |
488 * | | PchPcieL1SubstatesL1_1 | | |
489 * | | PchPcieL1SubstatesL1_1_2 | | [Default] |
490 * | | PchPcieL1SubstatesMax | [Default] | |
491 * +-------------------+--------------------------+-----------+-----------+
494 static unsigned int adl_aspm_control_to_upd(enum ASPM_control aspm_control)
496 /* Disable without Kconfig selected */
497 if (!CONFIG(PCIEXP_ASPM))
498 return UPD_INDEX(ASPM_DISABLE);
500 /* Use auto unless overwritten */
501 if (!aspm_control)
502 return UPD_INDEX(ASPM_AUTO);
504 return UPD_INDEX(aspm_control);
507 static unsigned int adl_l1ss_control_to_upd(enum L1_substates_control l1_substates_control)
509 /* Disable without Kconfig selected */
510 if (!CONFIG(PCIEXP_ASPM))
511 return UPD_INDEX(L1_SS_DISABLED);
513 /* Don't enable UPD if Kconfig not set */
514 if (!CONFIG(PCIEXP_L1_SUB_STATE))
515 return UPD_INDEX(L1_SS_DISABLED);
517 /* L1 Substate should be disabled in compliance mode */
518 if (CONFIG(SOC_INTEL_COMPLIANCE_TEST_MODE))
519 return UPD_INDEX(L1_SS_DISABLED);
521 /* Use maximum unless overwritten */
522 if (!l1_substates_control)
523 return UPD_INDEX(L1_SS_L1_2);
525 return UPD_INDEX(l1_substates_control);
528 static void configure_pch_rp_power_management(FSP_S_CONFIG *s_cfg,
529 const struct pcie_rp_config *rp_cfg,
530 unsigned int index)
532 s_cfg->PcieRpEnableCpm[index] = CONFIG(PCIEXP_CLK_PM);
533 s_cfg->PcieRpAspm[index] = adl_aspm_control_to_upd(rp_cfg->pcie_rp_aspm);
534 s_cfg->PcieRpL1Substates[index] = adl_l1ss_control_to_upd(rp_cfg->PcieRpL1Substates);
538 * Starting with Alder Lake, UPDs for Clock Power Management were
539 * introduced for the CPU root ports.
541 * CpuPcieClockGating:
542 * Disabled
543 * Enabled [Default]
545 * CpuPciePowerGating
546 * Disabled
547 * Enabled [Default]
550 static void configure_cpu_rp_power_management(FSP_S_CONFIG *s_cfg,
551 const struct pcie_rp_config *rp_cfg,
552 unsigned int index)
554 s_cfg->CpuPcieRpEnableCpm[index] = CONFIG(PCIEXP_CLK_PM);
555 s_cfg->CpuPcieClockGating[index] = CONFIG(PCIEXP_CLK_PM);
556 s_cfg->CpuPciePowerGating[index] = CONFIG(PCIEXP_CLK_PM);
557 s_cfg->CpuPcieRpAspm[index] = adl_aspm_control_to_upd(rp_cfg->pcie_rp_aspm);
558 s_cfg->CpuPcieRpL1Substates[index] = adl_l1ss_control_to_upd(rp_cfg->PcieRpL1Substates);
561 /* This function returns the VccIn Aux Imon IccMax values for ADL and RPL
562 SKU's */
563 static uint16_t get_vccin_aux_imon_iccmax(const struct soc_intel_alderlake_config *config)
565 struct device *dev = pcidev_path_on_root(SA_DEVFN_ROOT);
566 uint16_t mch_id = dev ? pci_read_config16(dev, PCI_DEVICE_ID) : 0xffff;
567 uint8_t tdp;
569 switch (mch_id) {
570 case PCI_DID_INTEL_ADL_P_ID_1:
571 case PCI_DID_INTEL_ADL_P_ID_3:
572 case PCI_DID_INTEL_ADL_P_ID_4:
573 case PCI_DID_INTEL_ADL_P_ID_5:
574 case PCI_DID_INTEL_ADL_P_ID_6:
575 case PCI_DID_INTEL_ADL_P_ID_7:
576 case PCI_DID_INTEL_ADL_P_ID_8:
577 case PCI_DID_INTEL_ADL_P_ID_9:
578 case PCI_DID_INTEL_ADL_P_ID_10:
579 case PCI_DID_INTEL_RPL_P_ID_1:
580 case PCI_DID_INTEL_RPL_P_ID_2:
581 case PCI_DID_INTEL_RPL_P_ID_3:
582 case PCI_DID_INTEL_RPL_P_ID_4:
583 case PCI_DID_INTEL_RPL_P_ID_5:
584 case PCI_DID_INTEL_RPL_P_ID_6:
585 case PCI_DID_INTEL_RPL_P_ID_7:
586 case PCI_DID_INTEL_RPL_P_ID_8:
587 tdp = get_cpu_tdp();
588 if (tdp == TDP_45W)
589 return ICC_MAX_TDP_45W;
590 return ICC_MAX_TDP_15W_28W;
591 case PCI_DID_INTEL_ADL_M_ID_1:
592 case PCI_DID_INTEL_ADL_M_ID_2:
593 return ICC_MAX_ID_ADL_M_MA;
594 case PCI_DID_INTEL_ADL_N_ID_1:
595 case PCI_DID_INTEL_ADL_N_ID_2:
596 case PCI_DID_INTEL_ADL_N_ID_3:
597 case PCI_DID_INTEL_ADL_N_ID_4:
598 case PCI_DID_INTEL_ADL_N_ID_5:
599 case PCI_DID_INTEL_ADL_N_ID_6:
600 case PCI_DID_INTEL_ADL_N_ID_7:
601 case PCI_DID_INTEL_ADL_N_ID_8:
602 case PCI_DID_INTEL_ADL_N_ID_9:
603 return config->vccin_aux_imon_iccmax
604 ? config->vccin_aux_imon_iccmax : ICC_MAX_ID_ADL_N_MA;
605 case PCI_DID_INTEL_ADL_S_ID_1:
606 case PCI_DID_INTEL_ADL_S_ID_3:
607 case PCI_DID_INTEL_ADL_S_ID_8:
608 case PCI_DID_INTEL_ADL_S_ID_10:
609 case PCI_DID_INTEL_ADL_S_ID_11:
610 case PCI_DID_INTEL_ADL_S_ID_12:
611 case PCI_DID_INTEL_RPL_HX_ID_1:
612 case PCI_DID_INTEL_RPL_HX_ID_2:
613 case PCI_DID_INTEL_RPL_HX_ID_3:
614 case PCI_DID_INTEL_RPL_HX_ID_4:
615 case PCI_DID_INTEL_RPL_HX_ID_5:
616 case PCI_DID_INTEL_RPL_HX_ID_6:
617 case PCI_DID_INTEL_RPL_HX_ID_7:
618 case PCI_DID_INTEL_RPL_HX_ID_8:
619 return ICC_MAX_ADL_S;
620 case PCI_DID_INTEL_RPL_S_ID_1:
621 case PCI_DID_INTEL_RPL_S_ID_2:
622 case PCI_DID_INTEL_RPL_S_ID_3:
623 case PCI_DID_INTEL_RPL_S_ID_4:
624 case PCI_DID_INTEL_RPL_S_ID_5:
625 return ICC_MAX_RPL_S;
626 default:
627 printk(BIOS_ERR, "Unknown MCH ID: 0x%4x, skipping VccInAuxImonIccMax config\n",
628 mch_id);
629 return 0;
633 __weak void mainboard_update_soc_chip_config(struct soc_intel_alderlake_config *config)
635 /* Override settings per board. */
638 static void fill_fsps_lpss_params(FSP_S_CONFIG *s_cfg,
639 const struct soc_intel_alderlake_config *config)
641 for (int i = 0; i < CONFIG_SOC_INTEL_I2C_DEV_MAX; i++)
642 s_cfg->SerialIoI2cMode[i] = config->serial_io_i2c_mode[i];
644 for (int i = 0; i < CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX; i++) {
645 s_cfg->SerialIoSpiMode[i] = config->serial_io_gspi_mode[i];
646 s_cfg->SerialIoSpiCsMode[i] = config->serial_io_gspi_cs_mode[i];
647 s_cfg->SerialIoSpiCsState[i] = config->serial_io_gspi_cs_state[i];
650 for (int i = 0; i < CONFIG_SOC_INTEL_UART_DEV_MAX; i++)
651 s_cfg->SerialIoUartMode[i] = config->serial_io_uart_mode[i];
654 static void fill_fsps_microcode_params(FSP_S_CONFIG *s_cfg,
655 const struct soc_intel_alderlake_config *config)
657 const struct microcode *microcode_file;
658 size_t microcode_len;
660 /* Locate microcode and pass to FSP-S for 2nd microcode loading */
661 microcode_file = intel_microcode_find();
663 if (microcode_file != NULL) {
664 microcode_len = get_microcode_size(microcode_file);
665 if (microcode_len != 0) {
666 /* Update CPU Microcode patch base address/size */
667 s_cfg->MicrocodeRegionBase = (uint32_t)(uintptr_t)microcode_file;
668 s_cfg->MicrocodeRegionSize = (uint32_t)microcode_len;
673 static void fill_fsps_cpu_params(FSP_S_CONFIG *s_cfg,
674 const struct soc_intel_alderlake_config *config)
677 * FIXME: FSP assumes ownership of the APs (Application Processors)
678 * upon passing `NULL` pointer to the CpuMpPpi FSP-S UPD.
679 * Hence, pass a valid pointer to the CpuMpPpi UPD unconditionally.
680 * This would avoid APs from getting hijacked by FSP while coreboot
681 * decides to set SkipMpInit UPD.
683 s_cfg->CpuMpPpi = (uintptr_t)mp_fill_ppi_services_data();
685 if (CONFIG(USE_FSP_FEATURE_PROGRAM_ON_APS))
687 * Fill `2nd microcode loading FSP UPD` if FSP is running CPU feature
688 * programming.
690 fill_fsps_microcode_params(s_cfg, config);
691 else
692 s_cfg->SkipMpInit = !CONFIG(USE_INTEL_FSP_MP_INIT);
695 static void fill_fsps_igd_params(FSP_S_CONFIG *s_cfg,
696 const struct soc_intel_alderlake_config *config)
698 /* Load VBT before devicetree-specific config. */
699 s_cfg->GraphicsConfigPtr = (uintptr_t)vbt_get();
701 /* Check if IGD is present and fill Graphics init param accordingly */
702 s_cfg->PeiGraphicsPeimInit = CONFIG(RUN_FSP_GOP) && is_devfn_enabled(SA_DEVFN_IGD);
703 s_cfg->LidStatus = CONFIG(VBOOT_LID_SWITCH) ? get_lid_switch() : CONFIG(RUN_FSP_GOP);
704 s_cfg->PavpEnable = CONFIG(PAVP);
707 WEAK_DEV_PTR(tcss_usb3_port1);
708 WEAK_DEV_PTR(tcss_usb3_port2);
709 WEAK_DEV_PTR(tcss_usb3_port3);
710 WEAK_DEV_PTR(tcss_usb3_port4);
712 static void fill_fsps_tcss_params(FSP_S_CONFIG *s_cfg,
713 const struct soc_intel_alderlake_config *config)
715 const struct device *tcss_port_arr[] = {
716 DEV_PTR(tcss_usb3_port1),
717 DEV_PTR(tcss_usb3_port2),
718 DEV_PTR(tcss_usb3_port3),
719 DEV_PTR(tcss_usb3_port4),
722 s_cfg->TcssAuxOri = config->tcss_aux_ori;
724 /* Explicitly clear this field to avoid using defaults */
725 memset(s_cfg->IomTypeCPortPadCfg, 0, sizeof(s_cfg->IomTypeCPortPadCfg));
728 * Set FSPS UPD ITbtConnectTopologyTimeoutInMs with value 0. FSP will
729 * evaluate this UPD value and skip sending command. There will be no
730 * delay for command completion.
732 s_cfg->ITbtConnectTopologyTimeoutInMs = 0;
734 /* D3Hot and D3Cold for TCSS */
735 s_cfg->D3HotEnable = !config->tcss_d3_hot_disable;
736 s_cfg->D3ColdEnable = CONFIG(D3COLD_SUPPORT);
738 s_cfg->UsbTcPortEn = 0;
739 for (int i = 0; i < MAX_TYPE_C_PORTS; i++) {
740 if (is_dev_enabled(tcss_port_arr[i]))
741 s_cfg->UsbTcPortEn |= BIT(i);
744 s_cfg->Usb4CmMode = CONFIG(SOFTWARE_CONNECTION_MANAGER);
747 static void fill_fsps_chipset_lockdown_params(FSP_S_CONFIG *s_cfg,
748 const struct soc_intel_alderlake_config *config)
750 /* Chipset Lockdown */
751 const bool lockdown_by_fsp = get_lockdown_config() == CHIPSET_LOCKDOWN_FSP;
752 s_cfg->PchLockDownGlobalSmi = lockdown_by_fsp;
753 s_cfg->PchLockDownBiosInterface = lockdown_by_fsp;
754 s_cfg->PchUnlockGpioPads = lockdown_by_fsp;
755 s_cfg->RtcMemoryLock = lockdown_by_fsp;
756 s_cfg->SkipPamLock = !lockdown_by_fsp;
758 /* coreboot will send EOP before loading payload */
759 s_cfg->EndOfPostMessage = EOP_DISABLE;
762 static void fill_fsps_xhci_params(FSP_S_CONFIG *s_cfg,
763 const struct soc_intel_alderlake_config *config)
765 int i;
766 /* USB */
767 for (i = 0; i < ARRAY_SIZE(config->usb2_ports); i++) {
768 s_cfg->PortUsb20Enable[i] = config->usb2_ports[i].enable;
769 s_cfg->Usb2PhyPetxiset[i] = config->usb2_ports[i].pre_emp_bias;
770 s_cfg->Usb2PhyTxiset[i] = config->usb2_ports[i].tx_bias;
771 s_cfg->Usb2PhyPredeemp[i] = config->usb2_ports[i].tx_emp_enable;
772 s_cfg->Usb2PhyPehalfbit[i] = config->usb2_ports[i].pre_emp_bit;
774 if (config->usb2_ports[i].enable)
775 s_cfg->Usb2OverCurrentPin[i] = config->usb2_ports[i].ocpin;
776 else
777 s_cfg->Usb2OverCurrentPin[i] = OC_SKIP;
779 if (config->usb2_ports[i].type_c)
780 s_cfg->PortResetMessageEnable[i] = 1;
783 for (i = 0; i < ARRAY_SIZE(config->usb3_ports); i++) {
784 s_cfg->PortUsb30Enable[i] = config->usb3_ports[i].enable;
785 if (config->usb3_ports[i].enable)
786 s_cfg->Usb3OverCurrentPin[i] = config->usb3_ports[i].ocpin;
787 else
788 s_cfg->Usb3OverCurrentPin[i] = OC_SKIP;
790 if (config->usb3_ports[i].tx_de_emp) {
791 s_cfg->Usb3HsioTxDeEmphEnable[i] = 1;
792 s_cfg->Usb3HsioTxDeEmph[i] = config->usb3_ports[i].tx_de_emp;
794 if (config->usb3_ports[i].tx_downscale_amp) {
795 s_cfg->Usb3HsioTxDownscaleAmpEnable[i] = 1;
796 s_cfg->Usb3HsioTxDownscaleAmp[i] =
797 config->usb3_ports[i].tx_downscale_amp;
801 for (i = 0; i < ARRAY_SIZE(config->tcss_ports); i++) {
802 if (config->tcss_ports[i].enable)
803 s_cfg->CpuUsb3OverCurrentPin[i] = config->tcss_ports[i].ocpin;
806 s_cfg->PmcUsb2PhySusPgEnable = !config->usb2_phy_sus_pg_disable;
809 static void fill_fsps_xdci_params(FSP_S_CONFIG *s_cfg,
810 const struct soc_intel_alderlake_config *config)
812 s_cfg->XdciEnable = xdci_can_enable(PCH_DEVFN_USBOTG);
815 static void fill_fsps_uart_params(FSP_S_CONFIG *s_cfg,
816 const struct soc_intel_alderlake_config *config)
818 if (CONFIG(FSP_USES_CB_DEBUG_EVENT_HANDLER) && CONFIG(CONSOLE_SERIAL) &&
819 CONFIG(FSP_ENABLE_SERIAL_DEBUG))
820 s_cfg->FspEventHandler = (UINT32)((FSP_EVENT_HANDLER *)
821 fsp_debug_event_handler);
822 /* PCH UART selection for FSP Debug */
823 s_cfg->SerialIoDebugUartNumber = CONFIG_UART_FOR_CONSOLE;
824 ASSERT(ARRAY_SIZE(s_cfg->SerialIoUartAutoFlow) > CONFIG_UART_FOR_CONSOLE);
825 s_cfg->SerialIoUartAutoFlow[CONFIG_UART_FOR_CONSOLE] = 0;
828 static void fill_fsps_sata_params(FSP_S_CONFIG *s_cfg,
829 const struct soc_intel_alderlake_config *config)
831 /* SATA */
832 s_cfg->SataEnable = is_devfn_enabled(PCH_DEVFN_SATA);
833 if (s_cfg->SataEnable) {
834 s_cfg->SataMode = config->sata_mode;
835 s_cfg->SataSalpSupport = config->sata_salp_support;
836 memcpy(s_cfg->SataPortsEnable, config->sata_ports_enable,
837 sizeof(s_cfg->SataPortsEnable));
838 memcpy(s_cfg->SataPortsDevSlp, config->sata_ports_dev_slp,
839 sizeof(s_cfg->SataPortsDevSlp));
843 * Power Optimizer for SATA.
844 * SataPwrOptimizeDisable is default to 0.
845 * Boards not needing the optimizers explicitly disables them by setting
846 * these disable variables to 1 in devicetree overrides.
848 s_cfg->SataPwrOptEnable = !(config->sata_pwr_optimize_disable);
849 /* Test mode for SATA margining */
850 s_cfg->SataTestMode = CONFIG(ENABLE_SATA_TEST_MODE);
852 * Enable DEVSLP Idle Timeout settings DmVal and DitoVal.
853 * SataPortsDmVal is the DITO multiplier. Default is 15.
854 * SataPortsDitoVal is the DEVSLP Idle Timeout (DITO), Default is 625ms.
855 * The default values can be changed from devicetree.
857 for (size_t i = 0; i < ARRAY_SIZE(config->sata_ports_enable_dito_config); i++) {
858 if (config->sata_ports_enable_dito_config[i]) {
859 s_cfg->SataPortsDmVal[i] = config->sata_ports_dm_val[i];
860 s_cfg->SataPortsDitoVal[i] = config->sata_ports_dito_val[i];
865 static void fill_fsps_thermal_params(FSP_S_CONFIG *s_cfg,
866 const struct soc_intel_alderlake_config *config)
868 /* Enable TCPU for processor thermal control */
869 s_cfg->Device4Enable = is_devfn_enabled(SA_DEVFN_DPTF);
871 /* Set TccActivationOffset */
872 s_cfg->TccActivationOffset = config->tcc_offset;
875 static void fill_fsps_gna_params(FSP_S_CONFIG *s_cfg,
876 const struct soc_intel_alderlake_config *config)
878 s_cfg->GnaEnable = is_devfn_enabled(SA_DEVFN_GNA);
881 static void fill_fsps_lan_params(FSP_S_CONFIG *s_cfg,
882 const struct soc_intel_alderlake_config *config)
884 /* LAN */
885 s_cfg->PchLanEnable = is_devfn_enabled(PCH_DEVFN_GBE);
888 static void fill_fsps_cnvi_params(FSP_S_CONFIG *s_cfg,
889 const struct soc_intel_alderlake_config *config)
891 /* CNVi */
892 s_cfg->CnviWifiCore = is_devfn_enabled(PCH_DEVFN_CNVI_WIFI);
893 s_cfg->CnviMode = is_devfn_enabled(PCH_DEVFN_CNVI_WIFI);
894 s_cfg->CnviBtCore = config->cnvi_bt_core;
895 s_cfg->CnviBtAudioOffload = config->cnvi_bt_audio_offload;
896 /* Assert if CNVi BT is enabled without CNVi being enabled. */
897 assert(s_cfg->CnviMode || !s_cfg->CnviBtCore);
898 /* Assert if CNVi BT offload is enabled without CNVi BT being enabled. */
899 assert(s_cfg->CnviBtCore || !s_cfg->CnviBtAudioOffload);
902 static void fill_fsps_vmd_params(FSP_S_CONFIG *s_cfg,
903 const struct soc_intel_alderlake_config *config)
905 /* VMD */
906 s_cfg->VmdEnable = is_devfn_enabled(SA_DEVFN_VMD);
909 static void fill_fsps_thc_params(FSP_S_CONFIG *s_cfg,
910 const struct soc_intel_alderlake_config *config)
912 /* THC */
913 s_cfg->ThcPort0Assignment = is_devfn_enabled(PCH_DEVFN_THC0) ? THC_0 : THC_NONE;
914 s_cfg->ThcPort1Assignment = is_devfn_enabled(PCH_DEVFN_THC1) ? THC_1 : THC_NONE;
917 static void fill_fsps_tbt_params(FSP_S_CONFIG *s_cfg,
918 const struct soc_intel_alderlake_config *config)
920 /* USB4/TBT */
921 for (int i = 0; i < ARRAY_SIZE(s_cfg->ITbtPcieRootPortEn); i++)
922 s_cfg->ITbtPcieRootPortEn[i] = is_devfn_enabled(SA_DEVFN_TBT(i));
925 static void fill_fsps_8254_params(FSP_S_CONFIG *s_cfg,
926 const struct soc_intel_alderlake_config *config)
928 /* Legacy 8254 timer support */
929 bool use_8254 = get_uint_option("legacy_8254_timer", CONFIG(USE_LEGACY_8254_TIMER));
930 s_cfg->Enable8254ClockGating = !use_8254;
931 s_cfg->Enable8254ClockGatingOnS3 = !use_8254;
934 static void fill_fsps_pm_timer_params(FSP_S_CONFIG *s_cfg,
935 const struct soc_intel_alderlake_config *config)
938 * Legacy PM ACPI Timer (and TCO Timer)
939 * This *must* be 1 in any case to keep FSP from
940 * 1) enabling PM ACPI Timer emulation in uCode.
941 * 2) disabling the PM ACPI Timer.
942 * We handle both by ourself!
944 s_cfg->EnableTcoTimer = 1;
947 static void fill_fsps_storage_params(FSP_S_CONFIG *s_cfg,
948 const struct soc_intel_alderlake_config *config)
950 #if CONFIG(SOC_INTEL_ALDERLAKE_PCH_N)
951 /* eMMC Configuration */
952 s_cfg->ScsEmmcEnabled = is_devfn_enabled(PCH_DEVFN_EMMC);
953 if (s_cfg->ScsEmmcEnabled)
954 s_cfg->ScsEmmcHs400Enabled = config->emmc_enable_hs400_mode;
955 #endif
957 /* UFS Configuration */
958 s_cfg->UfsEnable[0] = 0; /* UFS Controller 0 is fuse disabled */
959 s_cfg->UfsEnable[1] = is_devfn_enabled(PCH_DEVFN_UFS);
961 /* Enable Hybrid storage auto detection */
962 s_cfg->HybridStorageMode = config->hybrid_storage_mode;
965 static void fill_fsps_pcie_params(FSP_S_CONFIG *s_cfg,
966 const struct soc_intel_alderlake_config *config)
968 uint32_t enable_mask = pcie_rp_enable_mask(get_pch_pcie_rp_table());
969 for (int i = 0; i < CONFIG_MAX_PCH_ROOT_PORTS; i++) {
970 if (!(enable_mask & BIT(i)))
971 continue;
972 const struct pcie_rp_config *rp_cfg = &config->pch_pcie_rp[i];
973 s_cfg->PcieRpLtrEnable[i] = !!(rp_cfg->flags & PCIE_RP_LTR);
974 s_cfg->PcieRpAdvancedErrorReporting[i] = !!(rp_cfg->flags & PCIE_RP_AER);
975 s_cfg->PcieRpHotPlug[i] = !!(rp_cfg->flags & PCIE_RP_HOTPLUG)
976 || CONFIG(SOC_INTEL_COMPLIANCE_TEST_MODE);
977 s_cfg->PcieRpClkReqDetect[i] = !!(rp_cfg->flags & PCIE_RP_CLK_REQ_DETECT);
978 /* PcieRpSlotImplemented default to 1 (slot implemented) in FSP; 0: built-in */
979 if (!!(rp_cfg->flags & PCIE_RP_BUILT_IN))
980 s_cfg->PcieRpSlotImplemented[i] = 0;
981 s_cfg->PcieRpDetectTimeoutMs[i] = rp_cfg->pcie_rp_detect_timeout_ms;
982 configure_pch_rp_power_management(s_cfg, rp_cfg, i);
984 s_cfg->PcieComplianceTestMode = CONFIG(SOC_INTEL_COMPLIANCE_TEST_MODE);
986 #if CONFIG(FSP_TYPE_IOT) && !CONFIG(SOC_INTEL_ALDERLAKE_PCH_N)
988 * Intel requires that all enabled PCH PCIe ports have a CLK_REQ signal connected.
989 * The CLK_REQ is used to wake the silicon when link entered L1 link-state. L1
990 * link-state is also entered on PCI-PM D3, even with ASPM L1 disabled.
991 * When no CLK_REQ signal is used, for example when it's using a free running
992 * clock the Root port silicon will never wake from L1 link state.
993 * This will trigger a MCE.
995 * Starting with FSP MR4 the UPD 'PchPcieClockGating' allows to work around
996 * this issue by disabling ClockGating. Disabling ClockGating should be avoided
997 * as the silicon draws more power when it is idle.
999 for (int i = 0; i < CONFIG_MAX_PCH_ROOT_PORTS; i++) {
1000 bool clk_req_missing = false;
1001 if (!(enable_mask & BIT(i)))
1002 continue;
1003 const struct pcie_rp_config *rp_cfg = &config->pch_pcie_rp[i];
1004 if (CONFIG(SOC_INTEL_COMPLIANCE_TEST_MODE)) {
1005 clk_req_missing = true;
1006 } else if (!rp_cfg->flags && rp_cfg->clk_src == 0 && rp_cfg->clk_req == 0) {
1007 clk_req_missing = true;
1008 } else if (rp_cfg->flags & PCIE_RP_CLK_REQ_UNUSED) {
1009 clk_req_missing = true;
1011 if (clk_req_missing) {
1012 printk(BIOS_INFO, "PCH PCIe port %d has no CLK_REQ\n", i + 1);
1013 printk(BIOS_INFO, "Disabling PCH PCIE ClockGating+PowerGating.\n");
1014 s_cfg->PchPcieClockGating = false;
1015 s_cfg->PchPciePowerGating = false;
1016 break;
1019 #endif
1022 static void fill_fsps_cpu_pcie_params(FSP_S_CONFIG *s_cfg,
1023 const struct soc_intel_alderlake_config *config)
1025 if (!CONFIG_MAX_CPU_ROOT_PORTS)
1026 return;
1028 const uint32_t enable_mask = pcie_rp_enable_mask(get_cpu_pcie_rp_table());
1029 for (int i = 0; i < CONFIG_MAX_CPU_ROOT_PORTS; i++) {
1030 if (!(enable_mask & BIT(i)))
1031 continue;
1033 const struct pcie_rp_config *rp_cfg = &config->cpu_pcie_rp[i];
1034 s_cfg->CpuPcieRpLtrEnable[i] = !!(rp_cfg->flags & PCIE_RP_LTR);
1035 s_cfg->CpuPcieRpAdvancedErrorReporting[i] = !!(rp_cfg->flags & PCIE_RP_AER);
1036 s_cfg->CpuPcieRpHotPlug[i] = !!(rp_cfg->flags & PCIE_RP_HOTPLUG)
1037 || CONFIG(SOC_INTEL_COMPLIANCE_TEST_MODE);
1038 s_cfg->CpuPcieRpDetectTimeoutMs[i] = rp_cfg->pcie_rp_detect_timeout_ms;
1039 s_cfg->PtmEnabled[i] = 0;
1041 if (!!(rp_cfg->flags & PCIE_RP_BUILT_IN))
1042 s_cfg->CpuPcieRpSlotImplemented[i] = 0;
1043 configure_cpu_rp_power_management(s_cfg, rp_cfg, i);
1045 s_cfg->CpuPcieComplianceTestMode = CONFIG(SOC_INTEL_COMPLIANCE_TEST_MODE);
1048 static void fill_fsps_misc_power_params(FSP_S_CONFIG *s_cfg,
1049 const struct soc_intel_alderlake_config *config)
1051 u32 cpu_id = cpu_get_cpuid();
1052 /* Skip setting D0I3 bit for all HECI devices */
1053 s_cfg->DisableD0I3SettingForHeci = 1;
1055 * Power Optimizer for DMI
1056 * DmiPwrOptimizeDisable is default to 0.
1057 * Boards not needing the optimizers explicitly disables them by setting
1058 * these disable variables to 1 in devicetree overrides.
1060 s_cfg->PchPwrOptEnable = !(config->dmi_power_optimize_disable);
1061 s_cfg->PmSupport = 1;
1062 s_cfg->Hwp = 1;
1063 s_cfg->Cx = 1;
1064 s_cfg->PsOnEnable = 1;
1065 s_cfg->PkgCStateLimit = LIMIT_AUTO;
1067 /* Disable Energy Efficient Turbo mode */
1068 s_cfg->EnergyEfficientTurbo = 0;
1070 /* VccIn Aux Imon IccMax. Values are in 1/4 Amp increments and range is 0-512. */
1071 s_cfg->VccInAuxImonIccImax =
1072 get_vccin_aux_imon_iccmax(config) * 4 / MILLIAMPS_TO_AMPS;
1074 /* VrConfig Settings for IA and GT domains */
1075 for (size_t i = 0; i < ARRAY_SIZE(config->domain_vr_config); i++)
1076 fill_vr_domain_config(s_cfg, i, &config->domain_vr_config[i]);
1078 s_cfg->PmcLpmS0ixSubStateEnableMask = get_supported_lpm_mask();
1080 /* Apply minimum assertion width settings */
1081 if (config->pch_slp_s3_min_assertion_width == SLP_S3_ASSERTION_DEFAULT)
1082 s_cfg->PchPmSlpS3MinAssert = SLP_S3_ASSERTION_50_MS;
1083 else
1084 s_cfg->PchPmSlpS3MinAssert = config->pch_slp_s3_min_assertion_width;
1086 if (config->pch_slp_s4_min_assertion_width == SLP_S4_ASSERTION_DEFAULT)
1087 s_cfg->PchPmSlpS4MinAssert = SLP_S4_ASSERTION_1S;
1088 else
1089 s_cfg->PchPmSlpS4MinAssert = config->pch_slp_s4_min_assertion_width;
1091 if (config->pch_slp_sus_min_assertion_width == SLP_SUS_ASSERTION_DEFAULT)
1092 s_cfg->PchPmSlpSusMinAssert = SLP_SUS_ASSERTION_4_S;
1093 else
1094 s_cfg->PchPmSlpSusMinAssert = config->pch_slp_sus_min_assertion_width;
1096 if (config->pch_slp_a_min_assertion_width == SLP_A_ASSERTION_DEFAULT)
1097 s_cfg->PchPmSlpAMinAssert = SLP_A_ASSERTION_2_S;
1098 else
1099 s_cfg->PchPmSlpAMinAssert = config->pch_slp_a_min_assertion_width;
1101 unsigned int power_cycle_duration = config->pch_reset_power_cycle_duration;
1102 if (power_cycle_duration == POWER_CYCLE_DURATION_DEFAULT)
1103 power_cycle_duration = POWER_CYCLE_DURATION_4S;
1105 s_cfg->PchPmPwrCycDur = get_pm_pwr_cyc_dur(s_cfg->PchPmSlpS4MinAssert,
1106 s_cfg->PchPmSlpS3MinAssert,
1107 s_cfg->PchPmSlpAMinAssert,
1108 power_cycle_duration);
1110 /* Set PsysPmax if it is available from DT */
1111 if (config->platform_pmax) {
1112 printk(BIOS_DEBUG, "PsysPmax = %dW\n", config->platform_pmax);
1113 /* PsysPmax is in unit of 1/8 Watt */
1114 s_cfg->PsysPmax = config->platform_pmax * 8;
1117 s_cfg->C1StateAutoDemotion = !config->disable_c1_state_auto_demotion;
1119 s_cfg->VrPowerDeliveryDesign = config->vr_power_delivery_design;
1121 /* C state demotion must be disabled for Raptorlake J0 and Q0 SKUs */
1122 assert(!(config->s0ix_enable && ((cpu_id == CPUID_RAPTORLAKE_J0) ||
1123 (cpu_id == CPUID_RAPTORLAKE_Q0)) &&
1124 !config->disable_package_c_state_demotion));
1126 s_cfg->PkgCStateDemotion = !config->disable_package_c_state_demotion;
1128 if (cpu_id == CPUID_RAPTORLAKE_J0 || cpu_id == CPUID_RAPTORLAKE_Q0)
1129 s_cfg->C1e = config->enable_c1e;
1130 else
1131 s_cfg->C1e = 1;
1132 #if CONFIG(SOC_INTEL_RAPTORLAKE) && !CONFIG(FSP_USE_REPO)
1133 s_cfg->EnableHwpScalabilityTracking = config->enable_hwp_scalability_tracking;
1134 #endif
1137 static void fill_fsps_irq_params(FSP_S_CONFIG *s_cfg,
1138 const struct soc_intel_alderlake_config *config)
1140 const struct slot_irq_constraints *constraints;
1141 size_t num_slots;
1143 if (CONFIG(SOC_INTEL_ALDERLAKE_PCH_S)) {
1144 constraints = irq_constraints_pch_s;
1145 num_slots = ARRAY_SIZE(irq_constraints_pch_s);
1146 } else {
1147 constraints = irq_constraints;
1148 num_slots = ARRAY_SIZE(irq_constraints);
1151 if (!assign_pci_irqs(constraints, num_slots))
1152 die("ERROR: Unable to assign PCI IRQs, and no _PRT table available\n");
1154 size_t pch_count = 0;
1155 const SI_PCH_DEVICE_INTERRUPT_CONFIG *upd_irqs = pci_irq_to_fsp(&pch_count);
1157 s_cfg->DevIntConfigPtr = (UINT32)((uintptr_t)upd_irqs);
1158 s_cfg->NumOfDevIntConfig = pch_count;
1159 printk(BIOS_INFO, "IRQ: Using dynamically assigned PCI IO-APIC IRQs\n");
1162 static void fill_fsps_fivr_params(FSP_S_CONFIG *s_cfg,
1163 const struct soc_intel_alderlake_config *config)
1165 /* PCH FIVR settings override */
1166 if (!config->ext_fivr_settings.configure_ext_fivr)
1167 return;
1169 s_cfg->PchFivrExtV1p05RailEnabledStates =
1170 config->ext_fivr_settings.v1p05_enable_bitmap;
1172 s_cfg->PchFivrExtV1p05RailSupportedVoltageStates =
1173 config->ext_fivr_settings.v1p05_supported_voltage_bitmap;
1175 s_cfg->PchFivrExtVnnRailEnabledStates =
1176 config->ext_fivr_settings.vnn_enable_bitmap;
1178 s_cfg->PchFivrExtVnnRailSupportedVoltageStates =
1179 config->ext_fivr_settings.vnn_supported_voltage_bitmap;
1181 s_cfg->PchFivrExtVnnRailSxEnabledStates =
1182 config->ext_fivr_settings.vnn_sx_enable_bitmap;
1184 /* Convert the voltages to increments of 2.5mv */
1185 s_cfg->PchFivrExtV1p05RailVoltage =
1186 (config->ext_fivr_settings.v1p05_voltage_mv * 10) / 25;
1188 s_cfg->PchFivrExtVnnRailVoltage =
1189 (config->ext_fivr_settings.vnn_voltage_mv * 10) / 25;
1191 s_cfg->PchFivrExtVnnRailSxVoltage =
1192 (config->ext_fivr_settings.vnn_sx_voltage_mv * 10 / 25);
1194 s_cfg->PchFivrExtV1p05RailIccMaximum =
1195 config->ext_fivr_settings.v1p05_icc_max_ma;
1197 s_cfg->PchFivrExtVnnRailIccMaximum =
1198 config->ext_fivr_settings.vnn_icc_max_ma;
1200 #if CONFIG(SOC_INTEL_ALDERLAKE_PCH_N)
1201 /* Enable the FIVR VCCST ICCMax Control for ADL-N.
1202 * TODO:Right now the UPD is update in partial headers for only ADL-N and when its
1203 * updated for ADL-P then we will remove the config since this needs to be enabled for
1204 * all the Alderlake platforms.
1206 s_cfg->PchFivrVccstIccMaxControl = 1;
1207 #endif
1210 static void fill_fsps_fivr_rfi_params(FSP_S_CONFIG *s_cfg,
1211 const struct soc_intel_alderlake_config *config)
1213 /* transform from Hz to 100 KHz */
1214 s_cfg->FivrRfiFrequency = config->fivr_rfi_frequency / (100 * KHz);
1215 s_cfg->FivrSpreadSpectrum = config->fivr_spread_spectrum;
1218 static void fill_fsps_acoustic_params(FSP_S_CONFIG *s_cfg,
1219 const struct soc_intel_alderlake_config *config)
1221 s_cfg->AcousticNoiseMitigation = config->acoustic_noise_mitigation;
1223 if (s_cfg->AcousticNoiseMitigation) {
1224 s_cfg->PreWake = config->PreWake;
1225 for (int i = 0; i < NUM_VR_DOMAINS; i++) {
1226 s_cfg->FastPkgCRampDisable[i] = config->fast_pkg_c_ramp_disable[i];
1227 s_cfg->SlowSlewRate[i] = config->slow_slew_rate[i];
1232 static void fill_fsps_pci_ssid_params(FSP_S_CONFIG *s_cfg,
1233 const struct soc_intel_alderlake_config *config)
1235 struct device *dev;
1236 int i;
1238 * Prevent FSP from programming write-once subsystem IDs by providing
1239 * a custom SSID table. Must have at least one entry for the FSP to
1240 * use the table.
1242 struct svid_ssid_init_entry {
1243 union {
1244 struct {
1245 uint64_t reg:12; /* Register offset */
1246 uint64_t function:3;
1247 uint64_t device:5;
1248 uint64_t bus:8;
1249 uint64_t :4;
1250 uint64_t segment:16;
1251 uint64_t :16;
1253 uint64_t segbusdevfuncregister;
1255 struct {
1256 uint16_t svid;
1257 uint16_t ssid;
1259 uint32_t reserved;
1263 * The xHCI and HDA devices have RW/L rather than RW/O registers for
1264 * subsystem IDs and so must be written before FspSiliconInit locks
1265 * them with their default values.
1267 const pci_devfn_t devfn_table[] = { PCH_DEVFN_XHCI, PCH_DEVFN_HDA };
1268 static struct svid_ssid_init_entry ssid_table[ARRAY_SIZE(devfn_table)];
1270 for (i = 0; i < ARRAY_SIZE(devfn_table); i++) {
1271 ssid_table[i].reg = PCI_SUBSYSTEM_VENDOR_ID;
1272 ssid_table[i].device = PCI_SLOT(devfn_table[i]);
1273 ssid_table[i].function = PCI_FUNC(devfn_table[i]);
1274 dev = pcidev_path_on_root(devfn_table[i]);
1275 if (dev) {
1276 ssid_table[i].svid = dev->subsystem_vendor;
1277 ssid_table[i].ssid = dev->subsystem_device;
1281 s_cfg->SiSsidTablePtr = (uintptr_t)ssid_table;
1282 s_cfg->SiNumberOfSsidTableEntry = ARRAY_SIZE(ssid_table);
1285 * Replace the default SVID:SSID value with the values specified in
1286 * the devicetree for the root device.
1288 dev = pcidev_path_on_root(SA_DEVFN_ROOT);
1289 s_cfg->SiCustomizedSvid = dev->subsystem_vendor;
1290 s_cfg->SiCustomizedSsid = dev->subsystem_device;
1292 /* Ensure FSP will program the registers */
1293 s_cfg->SiSkipSsidProgramming = 0;
1296 static void soc_silicon_init_params(FSP_S_CONFIG *s_cfg,
1297 struct soc_intel_alderlake_config *config)
1299 /* Override settings per board if required. */
1300 mainboard_update_soc_chip_config(config);
1302 void (*const fill_fsps_params[])(FSP_S_CONFIG *s_cfg,
1303 const struct soc_intel_alderlake_config *config) = {
1304 fill_fsps_lpss_params,
1305 fill_fsps_cpu_params,
1306 fill_fsps_igd_params,
1307 fill_fsps_tcss_params,
1308 fill_fsps_chipset_lockdown_params,
1309 fill_fsps_xhci_params,
1310 fill_fsps_xdci_params,
1311 fill_fsps_uart_params,
1312 fill_fsps_sata_params,
1313 fill_fsps_thermal_params,
1314 fill_fsps_gna_params,
1315 fill_fsps_lan_params,
1316 fill_fsps_cnvi_params,
1317 fill_fsps_vmd_params,
1318 fill_fsps_thc_params,
1319 fill_fsps_tbt_params,
1320 fill_fsps_8254_params,
1321 fill_fsps_pm_timer_params,
1322 fill_fsps_storage_params,
1323 fill_fsps_pcie_params,
1324 fill_fsps_cpu_pcie_params,
1325 fill_fsps_misc_power_params,
1326 fill_fsps_irq_params,
1327 fill_fsps_fivr_params,
1328 fill_fsps_fivr_rfi_params,
1329 fill_fsps_acoustic_params,
1330 fill_fsps_pci_ssid_params,
1333 for (size_t i = 0; i < ARRAY_SIZE(fill_fsps_params); i++)
1334 fill_fsps_params[i](s_cfg, config);
1338 * The Alder Lake PEIM graphics driver executed as part of the FSP does not wait
1339 * for the panel power cycle to complete before it initializes communication
1340 * with the display. It can result in AUX channel communication time out and
1341 * PEIM graphics driver failing to bring up graphics.
1343 * If we have performed some graphics operations in romstage, it is possible
1344 * that a panel power cycle is still in progress. To prevent any issue with the
1345 * PEIM graphics driver it is preferable to ensure that panel power cycle is
1346 * complete.
1348 * BUG:b:264526798
1350 static void wait_for_panel_power_cycle_done(const struct soc_intel_alderlake_config *config)
1352 const struct i915_gpu_panel_config *panel_cfg;
1353 uint32_t bar0;
1354 void *mmio;
1356 if (!CONFIG(RUN_FSP_GOP))
1357 return;
1359 bar0 = pci_s_read_config32(SA_DEV_IGD, PCI_BASE_ADDRESS_0);
1360 mmio = (void *)(bar0 & ~PCI_BASE_ADDRESS_MEM_ATTR_MASK);
1361 if (!mmio)
1362 return;
1364 panel_cfg = &config->panel_cfg;
1365 for (size_t i = 0;; i++) {
1366 uint32_t status = read32(mmio + PCH_PP_STATUS);
1367 if (!(status & PANEL_POWER_CYCLE_ACTIVE))
1368 break;
1369 if (i == panel_cfg->cycle_delay_ms) {
1370 printk(BIOS_ERR, "Panel power cycle is still active.\n");
1371 break;
1373 mdelay(1);
1377 /* UPD parameters to be initialized before SiliconInit */
1378 void platform_fsp_silicon_init_params_cb(FSPS_UPD *supd)
1380 struct soc_intel_alderlake_config *config;
1381 FSP_S_CONFIG *s_cfg = &supd->FspsConfig;
1383 config = config_of_soc();
1384 soc_silicon_init_params(s_cfg, config);
1385 mainboard_silicon_init_params(s_cfg);
1387 wait_for_panel_power_cycle_done(config);
1391 * Callbacks for SoC/Mainboard specific overrides for FspMultiPhaseSiInit
1392 * This platform supports below MultiPhaseSIInit Phase(s):
1393 * Phase | FSP return point | Purpose
1394 * ------- + ------------------------------------------------ + -------------------------------
1395 * 1 | After TCSS initialization completed | for TCSS specific init
1396 * 2 | Before BIOS Reset CPL is set by FSP-S | for CPU specific init
1398 void platform_fsp_silicon_multi_phase_init_cb(uint32_t phase_index)
1400 switch (phase_index) {
1401 case 1:
1402 /* TCSS specific initialization here */
1403 printk(BIOS_DEBUG, "FSP MultiPhaseSiInit %s/%s called\n",
1404 __FILE__, __func__);
1406 if (CONFIG(SOC_INTEL_COMMON_BLOCK_TCSS)) {
1407 const config_t *config = config_of_soc();
1408 tcss_configure(config->typec_aux_bias_pads);
1410 break;
1411 case 2:
1412 /* CPU specific initialization here */
1413 printk(BIOS_DEBUG, "FSP MultiPhaseSiInit %s/%s called\n",
1414 __FILE__, __func__);
1415 before_post_cpus_init();
1416 /* Enable BIOS Reset CPL */
1417 enable_bios_reset_cpl();
1418 break;
1419 default:
1420 break;
1424 /* Mainboard GPIO Configuration */
1425 __weak void mainboard_silicon_init_params(FSP_S_CONFIG *s_cfg)
1427 printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__);
1430 /* Handle FSP logo params */
1431 void soc_load_logo(FSPS_UPD *supd)
1433 fsp_convert_bmp_to_gop_blt(&supd->FspsConfig.LogoPtr,
1434 &supd->FspsConfig.LogoSize,
1435 &supd->FspsConfig.BltBufferAddress,
1436 &supd->FspsConfig.BltBufferSize,
1437 &supd->FspsConfig.LogoPixelHeight,
1438 &supd->FspsConfig.LogoPixelWidth);