soc/mediatek/mt8196: Initialize MCUPM
[coreboot2.git] / src / soc / intel / alderlake / fsp_params.c
blobcbfd223d6a83eaad42763b69c08d2c910288c2b1
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 <drivers/usb/acpi/chip.h>
15 #include <fsp/api.h>
16 #include <fsp/fsp_debug_event.h>
17 #include <fsp/fsp_gop_blt.h>
18 #include <fsp/ppi/mp_service_ppi.h>
19 #include <fsp/util.h>
20 #include <gpio.h>
21 #include <intelblocks/aspm.h>
22 #include <intelblocks/irq.h>
23 #include <intelblocks/lpss.h>
24 #include <intelblocks/mp_init.h>
25 #include <intelblocks/pmclib.h>
26 #include <intelblocks/xdci.h>
27 #include <intelpch/lockdown.h>
28 #include <intelblocks/systemagent.h>
29 #include <intelblocks/tcss.h>
30 #include <option.h>
31 #include <soc/cpu.h>
32 #include <soc/intel/common/vbt.h>
33 #include <soc/pci_devs.h>
34 #include <soc/pcie.h>
35 #include <soc/ramstage.h>
36 #include <soc/soc_chip.h>
37 #include <static.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <types.h>
42 /* THC assignment definition */
43 #define THC_NONE 0
44 #define THC_0 1
45 #define THC_1 2
47 /* SATA DEVSLP idle timeout default values */
48 #define DEF_DMVAL 15
49 #define DEF_DITOVAL 625
51 /* VccIn Aux Imon IccMax values in mA */
52 #define MILLIAMPS_TO_AMPS 1000
53 #define ICC_MAX_TDP_45W 34250
54 #define ICC_MAX_TDP_15W_28W 32000
55 #define ICC_MAX_ID_ADL_M_MA 12000
56 #define ICC_MAX_ID_ADL_N_MA 27000
57 #define ICC_MAX_ADL_S 33000
58 #define ICC_MAX_RPL_S 36000
61 * ME End of Post configuration
62 * 0 - Disable EOP.
63 * 1 - Send in PEI (Applicable for FSP in API mode)
64 * 2 - Send in DXE (Not applicable for FSP in API mode)
66 enum fsp_end_of_post {
67 EOP_DISABLE = 0,
68 EOP_PEI = 1,
69 EOP_DXE = 2,
72 static const struct slot_irq_constraints irq_constraints[] = {
74 .slot = SA_DEV_SLOT_CPU_1,
75 .fns = {
76 FIXED_INT_PIRQ(SA_DEVFN_CPU_PCIE1_0, PCI_INT_A, PIRQ_A),
80 .slot = SA_DEV_SLOT_IGD,
81 .fns = {
82 /* INTERRUPT_PIN is RO/0x01 */
83 FIXED_INT_ANY_PIRQ(SA_DEVFN_IGD, PCI_INT_A),
87 .slot = SA_DEV_SLOT_DPTF,
88 .fns = {
89 ANY_PIRQ(SA_DEVFN_DPTF),
93 .slot = SA_DEV_SLOT_IPU,
94 .fns = {
95 /* INTERRUPT_PIN is RO/0x01, and INTERRUPT_LINE is RW,
96 but S0ix fails when not set to 16 (b/193434192) */
97 FIXED_INT_PIRQ(SA_DEVFN_IPU, PCI_INT_A, PIRQ_A),
101 .slot = SA_DEV_SLOT_CPU_6,
102 .fns = {
103 FIXED_INT_PIRQ(SA_DEVFN_CPU_PCIE6_0, PCI_INT_D, PIRQ_A),
104 FIXED_INT_PIRQ(SA_DEVFN_CPU_PCIE6_2, PCI_INT_B, PIRQ_C),
108 .slot = SA_DEV_SLOT_TBT,
109 .fns = {
110 ANY_PIRQ(SA_DEVFN_TBT0),
111 ANY_PIRQ(SA_DEVFN_TBT1),
112 ANY_PIRQ(SA_DEVFN_TBT2),
113 ANY_PIRQ(SA_DEVFN_TBT3),
117 .slot = SA_DEV_SLOT_GNA,
118 .fns = {
119 /* INTERRUPT_PIN is RO/0x01 */
120 FIXED_INT_ANY_PIRQ(SA_DEVFN_GNA, PCI_INT_A),
124 .slot = SA_DEV_SLOT_TCSS,
125 .fns = {
126 ANY_PIRQ(SA_DEVFN_TCSS_XHCI),
127 ANY_PIRQ(SA_DEVFN_TCSS_XDCI),
131 .slot = PCH_DEV_SLOT_SIO0,
132 .fns = {
133 DIRECT_IRQ(PCH_DEVFN_I2C6),
134 DIRECT_IRQ(PCH_DEVFN_I2C7),
135 ANY_PIRQ(PCH_DEVFN_THC0),
136 ANY_PIRQ(PCH_DEVFN_THC1),
140 .slot = PCH_DEV_SLOT_SIO6,
141 .fns = {
142 DIRECT_IRQ(PCH_DEVFN_UART3),
143 DIRECT_IRQ(PCH_DEVFN_UART4),
144 DIRECT_IRQ(PCH_DEVFN_UART5),
145 DIRECT_IRQ(PCH_DEVFN_UART6),
149 .slot = PCH_DEV_SLOT_ISH,
150 .fns = {
151 DIRECT_IRQ(PCH_DEVFN_ISH),
152 DIRECT_IRQ(PCH_DEVFN_GSPI2),
153 ANY_PIRQ(PCH_DEVFN_UFS),
157 .slot = PCH_DEV_SLOT_SIO2,
158 .fns = {
159 DIRECT_IRQ(PCH_DEVFN_GSPI3),
160 DIRECT_IRQ(PCH_DEVFN_GSPI4),
161 DIRECT_IRQ(PCH_DEVFN_GSPI5),
162 DIRECT_IRQ(PCH_DEVFN_GSPI6),
166 .slot = PCH_DEV_SLOT_XHCI,
167 .fns = {
168 ANY_PIRQ(PCH_DEVFN_XHCI),
169 DIRECT_IRQ(PCH_DEVFN_USBOTG),
170 ANY_PIRQ(PCH_DEVFN_CNVI_WIFI),
174 .slot = PCH_DEV_SLOT_SIO3,
175 .fns = {
176 DIRECT_IRQ(PCH_DEVFN_I2C0),
177 DIRECT_IRQ(PCH_DEVFN_I2C1),
178 DIRECT_IRQ(PCH_DEVFN_I2C2),
179 DIRECT_IRQ(PCH_DEVFN_I2C3),
183 .slot = PCH_DEV_SLOT_CSE,
184 .fns = {
185 ANY_PIRQ(PCH_DEVFN_CSE),
186 ANY_PIRQ(PCH_DEVFN_CSE_2),
187 ANY_PIRQ(PCH_DEVFN_CSE_IDER),
188 ANY_PIRQ(PCH_DEVFN_CSE_KT),
189 ANY_PIRQ(PCH_DEVFN_CSE_3),
190 ANY_PIRQ(PCH_DEVFN_CSE_4),
194 .slot = PCH_DEV_SLOT_SATA,
195 .fns = {
196 ANY_PIRQ(PCH_DEVFN_SATA),
200 .slot = PCH_DEV_SLOT_SIO4,
201 .fns = {
202 DIRECT_IRQ(PCH_DEVFN_I2C4),
203 DIRECT_IRQ(PCH_DEVFN_I2C5),
204 DIRECT_IRQ(PCH_DEVFN_UART2),
207 #if CONFIG(SOC_INTEL_ALDERLAKE_PCH_N)
209 .slot = PCH_DEV_SLOT_EMMC,
210 .fns = {
211 ANY_PIRQ(PCH_DEVFN_EMMC),
214 #endif
216 .slot = PCH_DEV_SLOT_PCIE,
217 .fns = {
218 FIXED_INT_PIRQ(PCH_DEVFN_PCIE1, PCI_INT_A, PIRQ_A),
219 FIXED_INT_PIRQ(PCH_DEVFN_PCIE2, PCI_INT_B, PIRQ_B),
220 FIXED_INT_PIRQ(PCH_DEVFN_PCIE3, PCI_INT_C, PIRQ_C),
221 FIXED_INT_PIRQ(PCH_DEVFN_PCIE4, PCI_INT_D, PIRQ_D),
222 FIXED_INT_PIRQ(PCH_DEVFN_PCIE5, PCI_INT_A, PIRQ_A),
223 FIXED_INT_PIRQ(PCH_DEVFN_PCIE6, PCI_INT_B, PIRQ_B),
224 FIXED_INT_PIRQ(PCH_DEVFN_PCIE7, PCI_INT_C, PIRQ_C),
225 FIXED_INT_PIRQ(PCH_DEVFN_PCIE8, PCI_INT_D, PIRQ_D),
229 .slot = PCH_DEV_SLOT_PCIE_1,
230 .fns = {
231 FIXED_INT_PIRQ(PCH_DEVFN_PCIE9, PCI_INT_A, PIRQ_A),
232 FIXED_INT_PIRQ(PCH_DEVFN_PCIE10, PCI_INT_B, PIRQ_B),
233 FIXED_INT_PIRQ(PCH_DEVFN_PCIE11, PCI_INT_C, PIRQ_C),
234 FIXED_INT_PIRQ(PCH_DEVFN_PCIE12, PCI_INT_D, PIRQ_D),
238 .slot = PCH_DEV_SLOT_SIO5,
239 .fns = {
240 /* UART0 shares an interrupt line with TSN0, so must use
241 a PIRQ */
242 FIXED_INT_ANY_PIRQ(PCH_DEVFN_UART0, PCI_INT_A),
243 /* UART1 shares an interrupt line with TSN1, so must use
244 a PIRQ */
245 FIXED_INT_ANY_PIRQ(PCH_DEVFN_UART1, PCI_INT_B),
246 DIRECT_IRQ(PCH_DEVFN_GSPI0),
247 DIRECT_IRQ(PCH_DEVFN_GSPI1),
251 .slot = PCH_DEV_SLOT_ESPI,
252 .fns = {
253 ANY_PIRQ(PCH_DEVFN_HDA),
254 ANY_PIRQ(PCH_DEVFN_SMBUS),
255 ANY_PIRQ(PCH_DEVFN_GBE),
256 /* INTERRUPT_PIN is RO/0x01 */
257 FIXED_INT_ANY_PIRQ(PCH_DEVFN_TRACEHUB, PCI_INT_A),
262 static const struct slot_irq_constraints irq_constraints_pch_s[] = {
264 .slot = SA_DEV_SLOT_CPU_1,
265 .fns = {
266 FIXED_INT_PIRQ(SA_DEVFN_CPU_PCIE1_0, PCI_INT_A, PIRQ_A),
267 FIXED_INT_PIRQ(SA_DEVFN_CPU_PCIE1_1, PCI_INT_B, PIRQ_B),
271 .slot = SA_DEV_SLOT_IGD,
272 .fns = {
273 /* INTERRUPT_PIN is RO/0x01 */
274 FIXED_INT_ANY_PIRQ(SA_DEVFN_IGD, PCI_INT_A),
278 .slot = SA_DEV_SLOT_DPTF,
279 .fns = {
280 ANY_PIRQ(SA_DEVFN_DPTF),
284 .slot = SA_DEV_SLOT_CPU_6,
285 .fns = {
286 FIXED_INT_PIRQ(SA_DEVFN_CPU_PCIE6_0, PCI_INT_D, PIRQ_A),
290 .slot = SA_DEV_SLOT_GNA,
291 .fns = {
292 /* INTERRUPT_PIN is RO/0x01 */
293 FIXED_INT_ANY_PIRQ(SA_DEVFN_GNA, PCI_INT_A),
297 .slot = PCH_DEV_SLOT_SIO6,
298 .fns = {
299 DIRECT_IRQ(PCH_DEVFN_UART3),
303 .slot = PCH_DEV_SLOT_ISH,
304 .fns = {
305 DIRECT_IRQ(PCH_DEVFN_ISH),
306 DIRECT_IRQ(PCH_DEVFN_GSPI2),
310 .slot = PCH_DEV_SLOT_SIO2,
311 .fns = {
312 DIRECT_IRQ(PCH_DEVFN_GSPI3),
316 .slot = PCH_DEV_SLOT_XHCI,
317 .fns = {
318 ANY_PIRQ(PCH_DEVFN_XHCI),
319 DIRECT_IRQ(PCH_DEVFN_USBOTG),
320 ANY_PIRQ(PCH_DEVFN_CNVI_WIFI),
324 .slot = PCH_DEV_SLOT_SIO3,
325 .fns = {
326 DIRECT_IRQ(PCH_DEVFN_I2C0),
327 DIRECT_IRQ(PCH_DEVFN_I2C1),
328 DIRECT_IRQ(PCH_DEVFN_I2C2),
329 DIRECT_IRQ(PCH_DEVFN_I2C3),
333 .slot = PCH_DEV_SLOT_CSE,
334 .fns = {
335 ANY_PIRQ(PCH_DEVFN_CSE),
336 ANY_PIRQ(PCH_DEVFN_CSE_2),
337 ANY_PIRQ(PCH_DEVFN_CSE_IDER),
338 ANY_PIRQ(PCH_DEVFN_CSE_KT),
339 ANY_PIRQ(PCH_DEVFN_CSE_3),
340 ANY_PIRQ(PCH_DEVFN_CSE_4),
344 .slot = PCH_DEV_SLOT_SATA,
345 .fns = {
346 ANY_PIRQ(PCH_DEVFN_SATA),
350 .slot = PCH_DEV_SLOT_SIO4,
351 .fns = {
352 DIRECT_IRQ(PCH_DEVFN_I2C4),
353 DIRECT_IRQ(PCH_DEVFN_I2C5),
354 DIRECT_IRQ(PCH_DEVFN_UART2),
358 .slot = PCH_DEV_SLOT_PCIE,
359 .fns = {
360 FIXED_INT_PIRQ(PCH_DEVFN_PCIE1, PCI_INT_A, PIRQ_A),
361 FIXED_INT_PIRQ(PCH_DEVFN_PCIE2, PCI_INT_B, PIRQ_B),
362 FIXED_INT_PIRQ(PCH_DEVFN_PCIE3, PCI_INT_C, PIRQ_C),
363 FIXED_INT_PIRQ(PCH_DEVFN_PCIE4, PCI_INT_D, PIRQ_D),
364 FIXED_INT_PIRQ(PCH_DEVFN_PCIE5, PCI_INT_A, PIRQ_A),
365 FIXED_INT_PIRQ(PCH_DEVFN_PCIE6, PCI_INT_B, PIRQ_B),
366 FIXED_INT_PIRQ(PCH_DEVFN_PCIE7, PCI_INT_C, PIRQ_C),
367 FIXED_INT_PIRQ(PCH_DEVFN_PCIE8, PCI_INT_D, PIRQ_D),
371 .slot = PCH_DEV_SLOT_PCIE_1,
372 .fns = {
373 FIXED_INT_PIRQ(PCH_DEVFN_PCIE9, PCI_INT_A, PIRQ_A),
374 FIXED_INT_PIRQ(PCH_DEVFN_PCIE10, PCI_INT_B, PIRQ_B),
375 FIXED_INT_PIRQ(PCH_DEVFN_PCIE11, PCI_INT_C, PIRQ_C),
376 FIXED_INT_PIRQ(PCH_DEVFN_PCIE12, PCI_INT_D, PIRQ_D),
377 FIXED_INT_PIRQ(PCH_DEVFN_PCIE13, PCI_INT_A, PIRQ_A),
378 FIXED_INT_PIRQ(PCH_DEVFN_PCIE14, PCI_INT_B, PIRQ_B),
379 FIXED_INT_PIRQ(PCH_DEVFN_PCIE15, PCI_INT_C, PIRQ_C),
380 FIXED_INT_PIRQ(PCH_DEVFN_PCIE16, PCI_INT_D, PIRQ_D),
384 .slot = PCH_DEV_SLOT_PCIE_2,
385 .fns = {
386 FIXED_INT_PIRQ(PCH_DEVFN_PCIE17, PCI_INT_A, PIRQ_A),
387 FIXED_INT_PIRQ(PCH_DEVFN_PCIE18, PCI_INT_B, PIRQ_B),
388 FIXED_INT_PIRQ(PCH_DEVFN_PCIE19, PCI_INT_C, PIRQ_C),
389 FIXED_INT_PIRQ(PCH_DEVFN_PCIE20, PCI_INT_D, PIRQ_D),
390 FIXED_INT_PIRQ(PCH_DEVFN_PCIE21, PCI_INT_A, PIRQ_A),
391 FIXED_INT_PIRQ(PCH_DEVFN_PCIE22, PCI_INT_B, PIRQ_B),
392 FIXED_INT_PIRQ(PCH_DEVFN_PCIE23, PCI_INT_C, PIRQ_C),
393 FIXED_INT_PIRQ(PCH_DEVFN_PCIE24, PCI_INT_D, PIRQ_D),
397 .slot = PCH_DEV_SLOT_PCIE_3,
398 .fns = {
399 FIXED_INT_PIRQ(PCH_DEVFN_PCIE25, PCI_INT_A, PIRQ_A),
400 FIXED_INT_PIRQ(PCH_DEVFN_PCIE26, PCI_INT_B, PIRQ_B),
401 FIXED_INT_PIRQ(PCH_DEVFN_PCIE27, PCI_INT_C, PIRQ_C),
402 FIXED_INT_PIRQ(PCH_DEVFN_PCIE28, PCI_INT_D, PIRQ_D),
406 .slot = PCH_DEV_SLOT_SIO5,
407 .fns = {
408 /* UART0 shares an interrupt line with TSN0, so must use
409 a PIRQ */
410 FIXED_INT_ANY_PIRQ(PCH_DEVFN_UART0, PCI_INT_A),
411 /* UART1 shares an interrupt line with TSN1, so must use
412 a PIRQ */
413 FIXED_INT_ANY_PIRQ(PCH_DEVFN_UART1, PCI_INT_B),
414 DIRECT_IRQ(PCH_DEVFN_GSPI0),
415 DIRECT_IRQ(PCH_DEVFN_GSPI1),
419 .slot = PCH_DEV_SLOT_ESPI,
420 .fns = {
421 ANY_PIRQ(PCH_DEVFN_HDA),
422 ANY_PIRQ(PCH_DEVFN_SMBUS),
423 ANY_PIRQ(PCH_DEVFN_GBE),
424 /* INTERRUPT_PIN is RO/0x01 */
425 FIXED_INT_ANY_PIRQ(PCH_DEVFN_TRACEHUB, PCI_INT_A),
430 static const SI_PCH_DEVICE_INTERRUPT_CONFIG *pci_irq_to_fsp(size_t *out_count)
432 const struct pci_irq_entry *entry = get_cached_pci_irqs();
433 SI_PCH_DEVICE_INTERRUPT_CONFIG *config;
434 size_t pch_total = 0;
435 size_t cfg_count = 0;
437 if (!entry)
438 return NULL;
440 /* Count PCH devices */
441 while (entry) {
442 if (is_pch_slot(entry->devfn))
443 ++pch_total;
444 entry = entry->next;
447 /* Convert PCH device entries to FSP format */
448 config = calloc(pch_total, sizeof(*config));
449 entry = get_cached_pci_irqs();
450 while (entry) {
451 if (!is_pch_slot(entry->devfn)) {
452 entry = entry->next;
453 continue;
456 config[cfg_count].Device = PCI_SLOT(entry->devfn);
457 config[cfg_count].Function = PCI_FUNC(entry->devfn);
458 config[cfg_count].IntX = (SI_PCH_INT_PIN)entry->pin;
459 config[cfg_count].Irq = entry->irq;
460 ++cfg_count;
462 entry = entry->next;
465 *out_count = cfg_count;
467 return config;
470 /* This function returns the VccIn Aux Imon IccMax values for ADL and RPL
471 SKU's */
472 static uint16_t get_vccin_aux_imon_iccmax(const struct soc_intel_alderlake_config *config)
474 struct device *dev = pcidev_path_on_root(SA_DEVFN_ROOT);
475 uint16_t mch_id = dev ? pci_read_config16(dev, PCI_DEVICE_ID) : 0xffff;
476 uint8_t tdp;
478 switch (mch_id) {
479 case PCI_DID_INTEL_ADL_P_ID_1:
480 case PCI_DID_INTEL_ADL_P_ID_3:
481 case PCI_DID_INTEL_ADL_P_ID_4:
482 case PCI_DID_INTEL_ADL_P_ID_5:
483 case PCI_DID_INTEL_ADL_P_ID_6:
484 case PCI_DID_INTEL_ADL_P_ID_7:
485 case PCI_DID_INTEL_ADL_P_ID_8:
486 case PCI_DID_INTEL_ADL_P_ID_9:
487 case PCI_DID_INTEL_ADL_P_ID_10:
488 case PCI_DID_INTEL_RPL_P_ID_1:
489 case PCI_DID_INTEL_RPL_P_ID_2:
490 case PCI_DID_INTEL_RPL_P_ID_3:
491 case PCI_DID_INTEL_RPL_P_ID_4:
492 case PCI_DID_INTEL_RPL_P_ID_5:
493 case PCI_DID_INTEL_RPL_P_ID_6:
494 case PCI_DID_INTEL_RPL_P_ID_7:
495 case PCI_DID_INTEL_RPL_P_ID_8:
496 tdp = get_cpu_tdp();
497 if (tdp == TDP_45W)
498 return ICC_MAX_TDP_45W;
499 return ICC_MAX_TDP_15W_28W;
500 case PCI_DID_INTEL_ADL_M_ID_1:
501 case PCI_DID_INTEL_ADL_M_ID_2:
502 return ICC_MAX_ID_ADL_M_MA;
503 case PCI_DID_INTEL_ADL_N_ID_1:
504 case PCI_DID_INTEL_ADL_N_ID_2:
505 case PCI_DID_INTEL_ADL_N_ID_3:
506 case PCI_DID_INTEL_ADL_N_ID_4:
507 case PCI_DID_INTEL_ADL_N_ID_5:
508 case PCI_DID_INTEL_ADL_N_ID_6:
509 case PCI_DID_INTEL_ADL_N_ID_7:
510 case PCI_DID_INTEL_ADL_N_ID_8:
511 case PCI_DID_INTEL_ADL_N_ID_9:
512 return config->vccin_aux_imon_iccmax
513 ? config->vccin_aux_imon_iccmax : ICC_MAX_ID_ADL_N_MA;
514 case PCI_DID_INTEL_ADL_S_ID_1:
515 case PCI_DID_INTEL_ADL_S_ID_3:
516 case PCI_DID_INTEL_ADL_S_ID_8:
517 case PCI_DID_INTEL_ADL_S_ID_10:
518 case PCI_DID_INTEL_ADL_S_ID_11:
519 case PCI_DID_INTEL_ADL_S_ID_12:
520 case PCI_DID_INTEL_RPL_HX_ID_1:
521 case PCI_DID_INTEL_RPL_HX_ID_2:
522 case PCI_DID_INTEL_RPL_HX_ID_3:
523 case PCI_DID_INTEL_RPL_HX_ID_4:
524 case PCI_DID_INTEL_RPL_HX_ID_5:
525 case PCI_DID_INTEL_RPL_HX_ID_6:
526 case PCI_DID_INTEL_RPL_HX_ID_7:
527 case PCI_DID_INTEL_RPL_HX_ID_8:
528 return ICC_MAX_ADL_S;
529 case PCI_DID_INTEL_RPL_S_ID_1:
530 case PCI_DID_INTEL_RPL_S_ID_2:
531 case PCI_DID_INTEL_RPL_S_ID_3:
532 case PCI_DID_INTEL_RPL_S_ID_4:
533 case PCI_DID_INTEL_RPL_S_ID_5:
534 return ICC_MAX_RPL_S;
535 default:
536 printk(BIOS_ERR, "Unknown MCH ID: 0x%4x, skipping VccInAuxImonIccMax config\n",
537 mch_id);
538 return 0;
542 __weak void mainboard_update_soc_chip_config(struct soc_intel_alderlake_config *config)
544 /* Override settings per board. */
547 static void fill_fsps_lpss_params(FSP_S_CONFIG *s_cfg,
548 const struct soc_intel_alderlake_config *config)
550 for (int i = 0; i < CONFIG_SOC_INTEL_I2C_DEV_MAX; i++)
551 s_cfg->SerialIoI2cMode[i] = config->serial_io_i2c_mode[i];
553 for (int i = 0; i < CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX; i++) {
554 s_cfg->SerialIoSpiMode[i] = config->serial_io_gspi_mode[i];
555 s_cfg->SerialIoSpiCsMode[i] = config->serial_io_gspi_cs_mode[i];
556 s_cfg->SerialIoSpiCsState[i] = config->serial_io_gspi_cs_state[i];
559 for (int i = 0; i < CONFIG_SOC_INTEL_UART_DEV_MAX; i++)
560 s_cfg->SerialIoUartMode[i] = config->serial_io_uart_mode[i];
563 static void fill_fsps_microcode_params(FSP_S_CONFIG *s_cfg,
564 const struct soc_intel_alderlake_config *config)
566 const struct microcode *microcode_file;
567 size_t microcode_len;
569 /* Locate microcode and pass to FSP-S for 2nd microcode loading */
570 microcode_file = intel_microcode_find();
572 if (microcode_file != NULL) {
573 microcode_len = get_microcode_size(microcode_file);
574 if (microcode_len != 0) {
575 /* Update CPU Microcode patch base address/size */
576 s_cfg->MicrocodeRegionBase = (uint32_t)(uintptr_t)microcode_file;
577 s_cfg->MicrocodeRegionSize = (uint32_t)microcode_len;
582 static void fill_fsps_cpu_params(FSP_S_CONFIG *s_cfg,
583 const struct soc_intel_alderlake_config *config)
586 * FIXME: FSP assumes ownership of the APs (Application Processors)
587 * upon passing `NULL` pointer to the CpuMpPpi FSP-S UPD.
588 * Hence, pass a valid pointer to the CpuMpPpi UPD unconditionally.
589 * This would avoid APs from getting hijacked by FSP while coreboot
590 * decides to set SkipMpInit UPD.
592 s_cfg->CpuMpPpi = (uintptr_t)mp_fill_ppi_services_data();
594 if (CONFIG(USE_FSP_FEATURE_PROGRAM_ON_APS))
596 * Fill `2nd microcode loading FSP UPD` if FSP is running CPU feature
597 * programming.
599 fill_fsps_microcode_params(s_cfg, config);
600 else
601 s_cfg->SkipMpInit = !CONFIG(USE_INTEL_FSP_MP_INIT);
604 static void fill_fsps_igd_params(FSP_S_CONFIG *s_cfg,
605 const struct soc_intel_alderlake_config *config)
607 /* Load VBT before devicetree-specific config. */
608 s_cfg->GraphicsConfigPtr = (uintptr_t)vbt_get();
610 /* Check if IGD is present and fill Graphics init param accordingly */
611 s_cfg->PeiGraphicsPeimInit = CONFIG(RUN_FSP_GOP) && is_devfn_enabled(SA_DEVFN_IGD);
612 s_cfg->LidStatus = CONFIG(VBOOT_LID_SWITCH) ? get_lid_switch() : CONFIG(RUN_FSP_GOP);
613 s_cfg->PavpEnable = CONFIG(PAVP);
616 WEAK_DEV_PTR(tcss_usb3_port1);
617 WEAK_DEV_PTR(tcss_usb3_port2);
618 WEAK_DEV_PTR(tcss_usb3_port3);
619 WEAK_DEV_PTR(tcss_usb3_port4);
621 static void fill_fsps_tcss_params(FSP_S_CONFIG *s_cfg,
622 const struct soc_intel_alderlake_config *config)
624 const struct device *tcss_port_arr[] = {
625 DEV_PTR(tcss_usb3_port1),
626 DEV_PTR(tcss_usb3_port2),
627 DEV_PTR(tcss_usb3_port3),
628 DEV_PTR(tcss_usb3_port4),
631 s_cfg->TcssAuxOri = config->tcss_aux_ori;
633 /* Explicitly clear this field to avoid using defaults */
634 memset(s_cfg->IomTypeCPortPadCfg, 0, sizeof(s_cfg->IomTypeCPortPadCfg));
637 * Set FSPS UPD ITbtConnectTopologyTimeoutInMs with value 0. FSP will
638 * evaluate this UPD value and skip sending command. There will be no
639 * delay for command completion.
641 s_cfg->ITbtConnectTopologyTimeoutInMs = 0;
643 /* D3Hot and D3Cold for TCSS */
644 s_cfg->D3HotEnable = !config->tcss_d3_hot_disable;
645 s_cfg->D3ColdEnable = CONFIG(D3COLD_SUPPORT);
647 s_cfg->UsbTcPortEn = 0;
648 for (int i = 0; i < MAX_TYPE_C_PORTS; i++) {
649 if (is_dev_enabled(tcss_port_arr[i]))
650 s_cfg->UsbTcPortEn |= BIT(i);
653 s_cfg->Usb4CmMode = CONFIG(SOFTWARE_CONNECTION_MANAGER);
656 static void fill_fsps_chipset_lockdown_params(FSP_S_CONFIG *s_cfg,
657 const struct soc_intel_alderlake_config *config)
659 /* Chipset Lockdown */
660 const bool lockdown_by_fsp = get_lockdown_config() == CHIPSET_LOCKDOWN_FSP;
661 s_cfg->PchLockDownGlobalSmi = lockdown_by_fsp;
662 s_cfg->PchLockDownBiosInterface = lockdown_by_fsp;
663 s_cfg->PchUnlockGpioPads = lockdown_by_fsp;
664 s_cfg->RtcMemoryLock = lockdown_by_fsp;
665 s_cfg->SkipPamLock = !lockdown_by_fsp;
667 /* coreboot will send EOP before loading payload */
668 s_cfg->EndOfPostMessage = EOP_DISABLE;
671 static void fill_fsps_xhci_params(FSP_S_CONFIG *s_cfg,
672 const struct soc_intel_alderlake_config *config)
674 int i;
675 /* USB */
676 for (i = 0; i < ARRAY_SIZE(config->usb2_ports); i++) {
677 s_cfg->PortUsb20Enable[i] = config->usb2_ports[i].enable;
678 s_cfg->Usb2PhyPetxiset[i] = config->usb2_ports[i].pre_emp_bias;
679 s_cfg->Usb2PhyTxiset[i] = config->usb2_ports[i].tx_bias;
680 s_cfg->Usb2PhyPredeemp[i] = config->usb2_ports[i].tx_emp_enable;
681 s_cfg->Usb2PhyPehalfbit[i] = config->usb2_ports[i].pre_emp_bit;
683 if (config->usb2_ports[i].enable)
684 s_cfg->Usb2OverCurrentPin[i] = config->usb2_ports[i].ocpin;
685 else
686 s_cfg->Usb2OverCurrentPin[i] = OC_SKIP;
688 if (config->usb2_ports[i].type_c)
689 s_cfg->PortResetMessageEnable[i] = 1;
692 for (i = 0; i < ARRAY_SIZE(config->usb3_ports); i++) {
693 s_cfg->PortUsb30Enable[i] = config->usb3_ports[i].enable;
694 if (config->usb3_ports[i].enable)
695 s_cfg->Usb3OverCurrentPin[i] = config->usb3_ports[i].ocpin;
696 else
697 s_cfg->Usb3OverCurrentPin[i] = OC_SKIP;
699 if (config->usb3_ports[i].tx_de_emp) {
700 s_cfg->Usb3HsioTxDeEmphEnable[i] = 1;
701 s_cfg->Usb3HsioTxDeEmph[i] = config->usb3_ports[i].tx_de_emp;
703 if (config->usb3_ports[i].tx_downscale_amp) {
704 s_cfg->Usb3HsioTxDownscaleAmpEnable[i] = 1;
705 s_cfg->Usb3HsioTxDownscaleAmp[i] =
706 config->usb3_ports[i].tx_downscale_amp;
710 for (i = 0; i < ARRAY_SIZE(config->tcss_ports); i++) {
711 if (config->tcss_ports[i].enable)
712 s_cfg->CpuUsb3OverCurrentPin[i] = config->tcss_ports[i].ocpin;
715 s_cfg->PmcUsb2PhySusPgEnable = !config->usb2_phy_sus_pg_disable;
718 static void fill_fsps_xdci_params(FSP_S_CONFIG *s_cfg,
719 const struct soc_intel_alderlake_config *config)
721 s_cfg->XdciEnable = xdci_can_enable(PCH_DEVFN_USBOTG);
724 static void fill_fsps_uart_params(FSP_S_CONFIG *s_cfg,
725 const struct soc_intel_alderlake_config *config)
727 if (CONFIG(FSP_USES_CB_DEBUG_EVENT_HANDLER) && CONFIG(CONSOLE_SERIAL) &&
728 CONFIG(FSP_ENABLE_SERIAL_DEBUG))
729 s_cfg->FspEventHandler = (UINT32)((FSP_EVENT_HANDLER *)
730 fsp_debug_event_handler);
731 /* PCH UART selection for FSP Debug */
732 s_cfg->SerialIoDebugUartNumber = CONFIG_UART_FOR_CONSOLE;
733 ASSERT(ARRAY_SIZE(s_cfg->SerialIoUartAutoFlow) > CONFIG_UART_FOR_CONSOLE);
734 s_cfg->SerialIoUartAutoFlow[CONFIG_UART_FOR_CONSOLE] = 0;
737 static void fill_fsps_sata_params(FSP_S_CONFIG *s_cfg,
738 const struct soc_intel_alderlake_config *config)
740 /* SATA */
741 s_cfg->SataEnable = is_devfn_enabled(PCH_DEVFN_SATA);
742 if (s_cfg->SataEnable) {
743 s_cfg->SataMode = config->sata_mode;
744 s_cfg->SataSalpSupport = config->sata_salp_support;
745 memcpy(s_cfg->SataPortsEnable, config->sata_ports_enable,
746 sizeof(s_cfg->SataPortsEnable));
747 memcpy(s_cfg->SataPortsDevSlp, config->sata_ports_dev_slp,
748 sizeof(s_cfg->SataPortsDevSlp));
752 * Power Optimizer for SATA.
753 * SataPwrOptimizeDisable is default to 0.
754 * Boards not needing the optimizers explicitly disables them by setting
755 * these disable variables to 1 in devicetree overrides.
757 s_cfg->SataPwrOptEnable = !(config->sata_pwr_optimize_disable);
758 /* Test mode for SATA margining */
759 s_cfg->SataTestMode = CONFIG(ENABLE_SATA_TEST_MODE);
761 * Enable DEVSLP Idle Timeout settings DmVal and DitoVal.
762 * SataPortsDmVal is the DITO multiplier. Default is 15.
763 * SataPortsDitoVal is the DEVSLP Idle Timeout (DITO), Default is 625ms.
764 * The default values can be changed from devicetree.
766 for (size_t i = 0; i < ARRAY_SIZE(config->sata_ports_enable_dito_config); i++) {
767 if (config->sata_ports_enable_dito_config[i]) {
768 s_cfg->SataPortsDmVal[i] = config->sata_ports_dm_val[i];
769 s_cfg->SataPortsDitoVal[i] = config->sata_ports_dito_val[i];
774 static void fill_fsps_thermal_params(FSP_S_CONFIG *s_cfg,
775 const struct soc_intel_alderlake_config *config)
777 /* Enable TCPU for processor thermal control */
778 s_cfg->Device4Enable = is_devfn_enabled(SA_DEVFN_DPTF);
780 /* Set TccActivationOffset */
781 s_cfg->TccActivationOffset = config->tcc_offset;
784 static void fill_fsps_gna_params(FSP_S_CONFIG *s_cfg,
785 const struct soc_intel_alderlake_config *config)
787 s_cfg->GnaEnable = is_devfn_enabled(SA_DEVFN_GNA);
790 static void fill_fsps_lan_params(FSP_S_CONFIG *s_cfg,
791 const struct soc_intel_alderlake_config *config)
793 /* LAN */
794 s_cfg->PchLanEnable = is_devfn_enabled(PCH_DEVFN_GBE);
797 static void fill_fsps_cnvi_params(FSP_S_CONFIG *s_cfg,
798 const struct soc_intel_alderlake_config *config)
800 struct device *port = NULL;
801 struct drivers_usb_acpi_config *usb_cfg = NULL;
802 bool usb_audio_offload = false;
804 /* Search through the devicetree for matching USB devices */
805 while ((port = dev_find_path(port, DEVICE_PATH_USB)) != NULL) {
806 /* Skip ports that are not enabled or not of USB type */
807 if (!port->enabled || port->path.type != DEVICE_PATH_USB)
808 continue;
810 usb_cfg = port->chip_info;
811 if (usb_cfg && usb_cfg->cnvi_bt_audio_offload) {
812 usb_audio_offload = true;
813 break;
817 /* CNVi */
818 s_cfg->CnviWifiCore = is_devfn_enabled(PCH_DEVFN_CNVI_WIFI);
819 s_cfg->CnviMode = is_devfn_enabled(PCH_DEVFN_CNVI_WIFI);
820 s_cfg->CnviBtCore = config->cnvi_bt_core;
821 s_cfg->CnviBtAudioOffload = config->cnvi_bt_audio_offload;
823 if (!s_cfg->CnviBtCore && s_cfg->CnviBtAudioOffload) {
824 printk(BIOS_ERR, "BT offload is enabled without CNVi BT being enabled\n");
825 s_cfg->CnviBtAudioOffload = 0;
827 if (!s_cfg->CnviMode && s_cfg->CnviBtCore) {
828 printk(BIOS_ERR, "CNVi BT is enabled without CNVi being enabled\n");
829 s_cfg->CnviBtCore = 0;
830 s_cfg->CnviBtAudioOffload = 0;
832 if (s_cfg->CnviBtAudioOffload && !usb_audio_offload) {
833 printk(BIOS_WARNING, "CNVi BT Audio offload enabled but not in USB driver.\n");
835 if (!s_cfg->CnviBtAudioOffload && usb_cfg && usb_audio_offload) {
836 printk(BIOS_ERR, "USB BT Audio offload enabled but CNVi BT offload disabled\n");
837 usb_cfg->cnvi_bt_audio_offload = 0;
841 static void fill_fsps_vmd_params(FSP_S_CONFIG *s_cfg,
842 const struct soc_intel_alderlake_config *config)
844 /* VMD */
845 s_cfg->VmdEnable = is_devfn_enabled(SA_DEVFN_VMD);
848 static void fill_fsps_thc_params(FSP_S_CONFIG *s_cfg,
849 const struct soc_intel_alderlake_config *config)
851 /* THC */
852 s_cfg->ThcPort0Assignment = is_devfn_enabled(PCH_DEVFN_THC0) ? THC_0 : THC_NONE;
853 s_cfg->ThcPort1Assignment = is_devfn_enabled(PCH_DEVFN_THC1) ? THC_1 : THC_NONE;
856 static void fill_fsps_tbt_params(FSP_S_CONFIG *s_cfg,
857 const struct soc_intel_alderlake_config *config)
859 /* USB4/TBT */
860 for (int i = 0; i < ARRAY_SIZE(s_cfg->ITbtPcieRootPortEn); i++)
861 s_cfg->ITbtPcieRootPortEn[i] = is_devfn_enabled(SA_DEVFN_TBT(i));
864 static void fill_fsps_8254_params(FSP_S_CONFIG *s_cfg,
865 const struct soc_intel_alderlake_config *config)
867 /* Legacy 8254 timer support */
868 bool use_8254 = get_uint_option("legacy_8254_timer", CONFIG(USE_LEGACY_8254_TIMER));
869 s_cfg->Enable8254ClockGating = !use_8254;
870 s_cfg->Enable8254ClockGatingOnS3 = !use_8254;
873 static void fill_fsps_pm_timer_params(FSP_S_CONFIG *s_cfg,
874 const struct soc_intel_alderlake_config *config)
877 * Legacy PM ACPI Timer (and TCO Timer)
878 * This *must* be 1 in any case to keep FSP from
879 * 1) enabling PM ACPI Timer emulation in uCode.
880 * 2) disabling the PM ACPI Timer.
881 * We handle both by ourself!
883 s_cfg->EnableTcoTimer = 1;
886 static void fill_fsps_storage_params(FSP_S_CONFIG *s_cfg,
887 const struct soc_intel_alderlake_config *config)
889 #if CONFIG(SOC_INTEL_ALDERLAKE_PCH_N)
890 /* eMMC Configuration */
891 s_cfg->ScsEmmcEnabled = is_devfn_enabled(PCH_DEVFN_EMMC);
892 if (s_cfg->ScsEmmcEnabled)
893 s_cfg->ScsEmmcHs400Enabled = config->emmc_enable_hs400_mode;
894 #endif
896 /* UFS Configuration */
897 s_cfg->UfsEnable[0] = 0; /* UFS Controller 0 is fuse disabled */
898 s_cfg->UfsEnable[1] = is_devfn_enabled(PCH_DEVFN_UFS);
900 /* Enable Hybrid storage auto detection */
901 s_cfg->HybridStorageMode = config->hybrid_storage_mode;
904 static void fill_fsps_pcie_params(FSP_S_CONFIG *s_cfg,
905 const struct soc_intel_alderlake_config *config)
907 uint32_t enable_mask = pcie_rp_enable_mask(get_pch_pcie_rp_table());
908 for (int i = 0; i < CONFIG_MAX_PCH_ROOT_PORTS; i++) {
909 if (!(enable_mask & BIT(i)))
910 continue;
911 const struct pcie_rp_config *rp_cfg = &config->pch_pcie_rp[i];
912 s_cfg->PcieRpLtrEnable[i] = !!(rp_cfg->flags & PCIE_RP_LTR);
913 s_cfg->PcieRpAdvancedErrorReporting[i] = !!(rp_cfg->flags & PCIE_RP_AER);
914 s_cfg->PcieRpHotPlug[i] = !!(rp_cfg->flags & PCIE_RP_HOTPLUG)
915 || CONFIG(SOC_INTEL_COMPLIANCE_TEST_MODE);
916 s_cfg->PcieRpClkReqDetect[i] = !!(rp_cfg->flags & PCIE_RP_CLK_REQ_DETECT);
917 /* PcieRpSlotImplemented default to 1 (slot implemented) in FSP; 0: built-in */
918 if (!!(rp_cfg->flags & PCIE_RP_BUILT_IN))
919 s_cfg->PcieRpSlotImplemented[i] = 0;
920 s_cfg->PcieRpDetectTimeoutMs[i] = rp_cfg->pcie_rp_detect_timeout_ms;
921 configure_pch_rp_power_management(s_cfg, rp_cfg, i);
923 s_cfg->PcieComplianceTestMode = CONFIG(SOC_INTEL_COMPLIANCE_TEST_MODE);
925 #if CONFIG(FSP_TYPE_IOT) && !CONFIG(SOC_INTEL_ALDERLAKE_PCH_N)
927 * Intel requires that all enabled PCH PCIe ports have a CLK_REQ signal connected.
928 * The CLK_REQ is used to wake the silicon when link entered L1 link-state. L1
929 * link-state is also entered on PCI-PM D3, even with ASPM L1 disabled.
930 * When no CLK_REQ signal is used, for example when it's using a free running
931 * clock the Root port silicon will never wake from L1 link state.
932 * This will trigger a MCE.
934 * Starting with FSP MR4 the UPD 'PchPcieClockGating' allows to work around
935 * this issue by disabling ClockGating. Disabling ClockGating should be avoided
936 * as the silicon draws more power when it is idle.
938 for (int i = 0; i < CONFIG_MAX_PCH_ROOT_PORTS; i++) {
939 bool clk_req_missing = false;
940 if (!(enable_mask & BIT(i)))
941 continue;
942 const struct pcie_rp_config *rp_cfg = &config->pch_pcie_rp[i];
943 if (CONFIG(SOC_INTEL_COMPLIANCE_TEST_MODE)) {
944 clk_req_missing = true;
945 } else if (!rp_cfg->flags && rp_cfg->clk_src == 0 && rp_cfg->clk_req == 0) {
946 clk_req_missing = true;
947 } else if (rp_cfg->flags & PCIE_RP_CLK_REQ_UNUSED) {
948 clk_req_missing = true;
950 if (clk_req_missing) {
951 printk(BIOS_INFO, "PCH PCIe port %d has no CLK_REQ\n", i + 1);
952 printk(BIOS_INFO, "Disabling PCH PCIE ClockGating+PowerGating.\n");
953 s_cfg->PchPcieClockGating = false;
954 s_cfg->PchPciePowerGating = false;
955 break;
958 #endif
961 static void fill_fsps_cpu_pcie_params(FSP_S_CONFIG *s_cfg,
962 const struct soc_intel_alderlake_config *config)
964 if (!CONFIG_MAX_CPU_ROOT_PORTS)
965 return;
967 const uint32_t enable_mask = pcie_rp_enable_mask(get_cpu_pcie_rp_table());
968 for (int i = 0; i < CONFIG_MAX_CPU_ROOT_PORTS; i++) {
969 if (!(enable_mask & BIT(i)))
970 continue;
972 const struct pcie_rp_config *rp_cfg = &config->cpu_pcie_rp[i];
973 s_cfg->CpuPcieRpLtrEnable[i] = !!(rp_cfg->flags & PCIE_RP_LTR);
974 s_cfg->CpuPcieRpAdvancedErrorReporting[i] = !!(rp_cfg->flags & PCIE_RP_AER);
975 s_cfg->CpuPcieRpHotPlug[i] = !!(rp_cfg->flags & PCIE_RP_HOTPLUG)
976 || CONFIG(SOC_INTEL_COMPLIANCE_TEST_MODE);
977 s_cfg->CpuPcieRpDetectTimeoutMs[i] = rp_cfg->pcie_rp_detect_timeout_ms;
978 s_cfg->PtmEnabled[i] = 0;
980 if (!!(rp_cfg->flags & PCIE_RP_BUILT_IN))
981 s_cfg->CpuPcieRpSlotImplemented[i] = 0;
982 configure_cpu_rp_power_management(s_cfg, rp_cfg, i);
984 s_cfg->CpuPcieComplianceTestMode = CONFIG(SOC_INTEL_COMPLIANCE_TEST_MODE);
987 static void fill_fsps_misc_power_params(FSP_S_CONFIG *s_cfg,
988 const struct soc_intel_alderlake_config *config)
990 u32 cpu_id = cpu_get_cpuid();
991 /* Skip setting D0I3 bit for all HECI devices */
992 s_cfg->DisableD0I3SettingForHeci = 1;
994 * Power Optimizer for DMI
995 * DmiPwrOptimizeDisable is default to 0.
996 * Boards not needing the optimizers explicitly disables them by setting
997 * these disable variables to 1 in devicetree overrides.
999 s_cfg->PchPwrOptEnable = !(config->dmi_power_optimize_disable);
1000 s_cfg->PmSupport = 1;
1001 s_cfg->Hwp = 1;
1002 s_cfg->Cx = 1;
1003 s_cfg->PsOnEnable = 1;
1004 s_cfg->PkgCStateLimit = LIMIT_AUTO;
1006 /* Disable Energy Efficient Turbo mode */
1007 s_cfg->EnergyEfficientTurbo = 0;
1009 /* VccIn Aux Imon IccMax. Values are in 1/4 Amp increments and range is 0-512. */
1010 s_cfg->VccInAuxImonIccImax =
1011 get_vccin_aux_imon_iccmax(config) * 4 / MILLIAMPS_TO_AMPS;
1013 /* VrConfig Settings for IA and GT domains */
1014 for (size_t i = 0; i < ARRAY_SIZE(config->domain_vr_config); i++)
1015 fill_vr_domain_config(s_cfg, i, &config->domain_vr_config[i]);
1017 s_cfg->PmcLpmS0ixSubStateEnableMask = get_supported_lpm_mask();
1019 /* Apply minimum assertion width settings */
1020 if (config->pch_slp_s3_min_assertion_width == SLP_S3_ASSERTION_DEFAULT)
1021 s_cfg->PchPmSlpS3MinAssert = SLP_S3_ASSERTION_50_MS;
1022 else
1023 s_cfg->PchPmSlpS3MinAssert = config->pch_slp_s3_min_assertion_width;
1025 if (config->pch_slp_s4_min_assertion_width == SLP_S4_ASSERTION_DEFAULT)
1026 s_cfg->PchPmSlpS4MinAssert = SLP_S4_ASSERTION_1S;
1027 else
1028 s_cfg->PchPmSlpS4MinAssert = config->pch_slp_s4_min_assertion_width;
1030 if (config->pch_slp_sus_min_assertion_width == SLP_SUS_ASSERTION_DEFAULT)
1031 s_cfg->PchPmSlpSusMinAssert = SLP_SUS_ASSERTION_4_S;
1032 else
1033 s_cfg->PchPmSlpSusMinAssert = config->pch_slp_sus_min_assertion_width;
1035 if (config->pch_slp_a_min_assertion_width == SLP_A_ASSERTION_DEFAULT)
1036 s_cfg->PchPmSlpAMinAssert = SLP_A_ASSERTION_2_S;
1037 else
1038 s_cfg->PchPmSlpAMinAssert = config->pch_slp_a_min_assertion_width;
1040 unsigned int power_cycle_duration = config->pch_reset_power_cycle_duration;
1041 if (power_cycle_duration == POWER_CYCLE_DURATION_DEFAULT)
1042 power_cycle_duration = POWER_CYCLE_DURATION_4S;
1044 s_cfg->PchPmPwrCycDur = get_pm_pwr_cyc_dur(s_cfg->PchPmSlpS4MinAssert,
1045 s_cfg->PchPmSlpS3MinAssert,
1046 s_cfg->PchPmSlpAMinAssert,
1047 power_cycle_duration);
1049 /* Set PsysPmax if it is available from DT */
1050 if (config->platform_pmax) {
1051 printk(BIOS_DEBUG, "PsysPmax = %dW\n", config->platform_pmax);
1052 /* PsysPmax is in unit of 1/8 Watt */
1053 s_cfg->PsysPmax = config->platform_pmax * 8;
1056 s_cfg->C1StateAutoDemotion = !config->disable_c1_state_auto_demotion;
1058 s_cfg->VrPowerDeliveryDesign = config->vr_power_delivery_design;
1060 /* C state demotion must be disabled for Raptorlake J0 and Q0 SKUs */
1061 assert(!(config->s0ix_enable && ((cpu_id == CPUID_RAPTORLAKE_J0) ||
1062 (cpu_id == CPUID_RAPTORLAKE_Q0)) &&
1063 !config->disable_package_c_state_demotion));
1065 s_cfg->PkgCStateDemotion = !config->disable_package_c_state_demotion;
1067 if (cpu_id == CPUID_RAPTORLAKE_J0 || cpu_id == CPUID_RAPTORLAKE_Q0)
1068 s_cfg->C1e = config->enable_c1e;
1069 else
1070 s_cfg->C1e = 1;
1071 #if CONFIG(SOC_INTEL_RAPTORLAKE) && !CONFIG(FSP_USE_REPO)
1072 s_cfg->EnableHwpScalabilityTracking = config->enable_hwp_scalability_tracking;
1073 #endif
1076 static void fill_fsps_irq_params(FSP_S_CONFIG *s_cfg,
1077 const struct soc_intel_alderlake_config *config)
1079 const struct slot_irq_constraints *constraints;
1080 size_t num_slots;
1082 if (CONFIG(SOC_INTEL_ALDERLAKE_PCH_S)) {
1083 constraints = irq_constraints_pch_s;
1084 num_slots = ARRAY_SIZE(irq_constraints_pch_s);
1085 } else {
1086 constraints = irq_constraints;
1087 num_slots = ARRAY_SIZE(irq_constraints);
1090 if (!assign_pci_irqs(constraints, num_slots))
1091 die("ERROR: Unable to assign PCI IRQs, and no _PRT table available\n");
1093 size_t pch_count = 0;
1094 const SI_PCH_DEVICE_INTERRUPT_CONFIG *upd_irqs = pci_irq_to_fsp(&pch_count);
1096 s_cfg->DevIntConfigPtr = (UINT32)((uintptr_t)upd_irqs);
1097 s_cfg->NumOfDevIntConfig = pch_count;
1098 printk(BIOS_INFO, "IRQ: Using dynamically assigned PCI IO-APIC IRQs\n");
1101 static void fill_fsps_fivr_params(FSP_S_CONFIG *s_cfg,
1102 const struct soc_intel_alderlake_config *config)
1104 #if CONFIG(SOC_INTEL_ALDERLAKE_PCH_N)
1105 /* Enable the FIVR VCCST ICCMax Control for ADL-N.
1106 * TODO:Right now the UPD is update in partial headers for only ADL-N and when its
1107 * updated for ADL-P then we will remove the config since this needs to be enabled for
1108 * all the Alderlake platforms.
1110 s_cfg->PchFivrVccstIccMaxControl = 1;
1111 #endif
1113 /* PCH FIVR settings override */
1114 if (!config->ext_fivr_settings.configure_ext_fivr)
1115 return;
1117 s_cfg->PchFivrExtV1p05RailEnabledStates =
1118 config->ext_fivr_settings.v1p05_enable_bitmap;
1120 s_cfg->PchFivrExtV1p05RailSupportedVoltageStates =
1121 config->ext_fivr_settings.v1p05_supported_voltage_bitmap;
1123 s_cfg->PchFivrExtVnnRailEnabledStates =
1124 config->ext_fivr_settings.vnn_enable_bitmap;
1126 s_cfg->PchFivrExtVnnRailSupportedVoltageStates =
1127 config->ext_fivr_settings.vnn_supported_voltage_bitmap;
1129 s_cfg->PchFivrExtVnnRailSxEnabledStates =
1130 config->ext_fivr_settings.vnn_sx_enable_bitmap;
1132 /* Convert the voltages to increments of 2.5mv */
1133 s_cfg->PchFivrExtV1p05RailVoltage =
1134 (config->ext_fivr_settings.v1p05_voltage_mv * 10) / 25;
1136 s_cfg->PchFivrExtVnnRailVoltage =
1137 (config->ext_fivr_settings.vnn_voltage_mv * 10) / 25;
1139 s_cfg->PchFivrExtVnnRailSxVoltage =
1140 (config->ext_fivr_settings.vnn_sx_voltage_mv * 10 / 25);
1142 s_cfg->PchFivrExtV1p05RailIccMaximum =
1143 config->ext_fivr_settings.v1p05_icc_max_ma;
1145 s_cfg->PchFivrExtVnnRailIccMaximum =
1146 config->ext_fivr_settings.vnn_icc_max_ma;
1149 static void fill_fsps_fivr_rfi_params(FSP_S_CONFIG *s_cfg,
1150 const struct soc_intel_alderlake_config *config)
1152 /* transform from Hz to 100 KHz */
1153 s_cfg->FivrRfiFrequency = config->fivr_rfi_frequency / (100 * KHz);
1154 s_cfg->FivrSpreadSpectrum = config->fivr_spread_spectrum;
1157 static void fill_fsps_acoustic_params(FSP_S_CONFIG *s_cfg,
1158 const struct soc_intel_alderlake_config *config)
1160 s_cfg->AcousticNoiseMitigation = config->acoustic_noise_mitigation;
1162 if (s_cfg->AcousticNoiseMitigation) {
1163 s_cfg->PreWake = config->PreWake;
1164 for (int i = 0; i < NUM_VR_DOMAINS; i++) {
1165 s_cfg->FastPkgCRampDisable[i] = config->fast_pkg_c_ramp_disable[i];
1166 s_cfg->SlowSlewRate[i] = config->slow_slew_rate[i];
1171 static void fill_fsps_pci_ssid_params(FSP_S_CONFIG *s_cfg,
1172 const struct soc_intel_alderlake_config *config)
1174 struct device *dev;
1175 int i;
1177 * Prevent FSP from programming write-once subsystem IDs by providing
1178 * a custom SSID table. Must have at least one entry for the FSP to
1179 * use the table.
1181 struct svid_ssid_init_entry {
1182 union {
1183 struct {
1184 uint64_t reg:12; /* Register offset */
1185 uint64_t function:3;
1186 uint64_t device:5;
1187 uint64_t bus:8;
1188 uint64_t :4;
1189 uint64_t segment:16;
1190 uint64_t :16;
1192 uint64_t segbusdevfuncregister;
1194 struct {
1195 uint16_t svid;
1196 uint16_t ssid;
1198 uint32_t reserved;
1202 * The xHCI and HDA devices have RW/L rather than RW/O registers for
1203 * subsystem IDs and so must be written before FspSiliconInit locks
1204 * them with their default values.
1206 const pci_devfn_t devfn_table[] = { PCH_DEVFN_XHCI, PCH_DEVFN_HDA };
1207 static struct svid_ssid_init_entry ssid_table[ARRAY_SIZE(devfn_table)];
1209 for (i = 0; i < ARRAY_SIZE(devfn_table); i++) {
1210 ssid_table[i].reg = PCI_SUBSYSTEM_VENDOR_ID;
1211 ssid_table[i].device = PCI_SLOT(devfn_table[i]);
1212 ssid_table[i].function = PCI_FUNC(devfn_table[i]);
1213 dev = pcidev_path_on_root(devfn_table[i]);
1214 if (dev) {
1215 ssid_table[i].svid = dev->subsystem_vendor;
1216 ssid_table[i].ssid = dev->subsystem_device;
1220 s_cfg->SiSsidTablePtr = (uintptr_t)ssid_table;
1221 s_cfg->SiNumberOfSsidTableEntry = ARRAY_SIZE(ssid_table);
1224 * Replace the default SVID:SSID value with the values specified in
1225 * the devicetree for the root device.
1227 dev = pcidev_path_on_root(SA_DEVFN_ROOT);
1228 s_cfg->SiCustomizedSvid = dev->subsystem_vendor;
1229 s_cfg->SiCustomizedSsid = dev->subsystem_device;
1231 /* Ensure FSP will program the registers */
1232 s_cfg->SiSkipSsidProgramming = 0;
1235 static void soc_silicon_init_params(FSP_S_CONFIG *s_cfg,
1236 struct soc_intel_alderlake_config *config)
1238 /* Override settings per board if required. */
1239 mainboard_update_soc_chip_config(config);
1241 void (*const fill_fsps_params[])(FSP_S_CONFIG *s_cfg,
1242 const struct soc_intel_alderlake_config *config) = {
1243 fill_fsps_lpss_params,
1244 fill_fsps_cpu_params,
1245 fill_fsps_igd_params,
1246 fill_fsps_tcss_params,
1247 fill_fsps_chipset_lockdown_params,
1248 fill_fsps_xhci_params,
1249 fill_fsps_xdci_params,
1250 fill_fsps_uart_params,
1251 fill_fsps_sata_params,
1252 fill_fsps_thermal_params,
1253 fill_fsps_gna_params,
1254 fill_fsps_lan_params,
1255 fill_fsps_cnvi_params,
1256 fill_fsps_vmd_params,
1257 fill_fsps_thc_params,
1258 fill_fsps_tbt_params,
1259 fill_fsps_8254_params,
1260 fill_fsps_pm_timer_params,
1261 fill_fsps_storage_params,
1262 fill_fsps_pcie_params,
1263 fill_fsps_cpu_pcie_params,
1264 fill_fsps_misc_power_params,
1265 fill_fsps_irq_params,
1266 fill_fsps_fivr_params,
1267 fill_fsps_fivr_rfi_params,
1268 fill_fsps_acoustic_params,
1269 fill_fsps_pci_ssid_params,
1272 for (size_t i = 0; i < ARRAY_SIZE(fill_fsps_params); i++)
1273 fill_fsps_params[i](s_cfg, config);
1277 * The Alder Lake PEIM graphics driver executed as part of the FSP does not wait
1278 * for the panel power cycle to complete before it initializes communication
1279 * with the display. It can result in AUX channel communication time out and
1280 * PEIM graphics driver failing to bring up graphics.
1282 * If we have performed some graphics operations in romstage, it is possible
1283 * that a panel power cycle is still in progress. To prevent any issue with the
1284 * PEIM graphics driver it is preferable to ensure that panel power cycle is
1285 * complete.
1287 * BUG:b:264526798
1289 static void wait_for_panel_power_cycle_done(const struct soc_intel_alderlake_config *config)
1291 const struct i915_gpu_panel_config *panel_cfg;
1292 uint32_t bar0;
1293 void *mmio;
1295 if (!CONFIG(RUN_FSP_GOP))
1296 return;
1298 bar0 = pci_s_read_config32(SA_DEV_IGD, PCI_BASE_ADDRESS_0);
1299 mmio = (void *)(bar0 & ~PCI_BASE_ADDRESS_MEM_ATTR_MASK);
1300 if (!mmio)
1301 return;
1303 panel_cfg = &config->panel_cfg;
1304 for (size_t i = 0;; i++) {
1305 uint32_t status = read32(mmio + PCH_PP_STATUS);
1306 if (!(status & PANEL_POWER_CYCLE_ACTIVE))
1307 break;
1308 if (i == panel_cfg->cycle_delay_ms) {
1309 printk(BIOS_ERR, "Panel power cycle is still active.\n");
1310 break;
1312 mdelay(1);
1316 /* UPD parameters to be initialized before SiliconInit */
1317 void platform_fsp_silicon_init_params_cb(FSPS_UPD *supd)
1319 struct soc_intel_alderlake_config *config;
1320 FSP_S_CONFIG *s_cfg = &supd->FspsConfig;
1322 config = config_of_soc();
1323 soc_silicon_init_params(s_cfg, config);
1324 mainboard_silicon_init_params(s_cfg);
1326 wait_for_panel_power_cycle_done(config);
1330 * Callbacks for SoC/Mainboard specific overrides for FspMultiPhaseSiInit
1331 * This platform supports below MultiPhaseSIInit Phase(s):
1332 * Phase | FSP return point | Purpose
1333 * ------- + ------------------------------------------------ + -------------------------------
1334 * 1 | After TCSS initialization completed | for TCSS specific init
1335 * 2 | Before BIOS Reset CPL is set by FSP-S | for CPU specific init
1337 void platform_fsp_silicon_multi_phase_init_cb(uint32_t phase_index)
1339 switch (phase_index) {
1340 case 1:
1341 /* TCSS specific initialization here */
1342 printk(BIOS_DEBUG, "FSP MultiPhaseSiInit %s/%s called\n",
1343 __FILE__, __func__);
1345 if (CONFIG(SOC_INTEL_COMMON_BLOCK_TCSS)) {
1346 const config_t *config = config_of_soc();
1347 tcss_configure(config->typec_aux_bias_pads);
1349 break;
1350 case 2:
1351 /* CPU specific initialization here */
1352 printk(BIOS_DEBUG, "FSP MultiPhaseSiInit %s/%s called\n",
1353 __FILE__, __func__);
1354 before_post_cpus_init();
1355 /* Enable BIOS Reset CPL */
1356 enable_bios_reset_cpl();
1357 break;
1358 default:
1359 break;
1363 /* Mainboard GPIO Configuration */
1364 __weak void mainboard_silicon_init_params(FSP_S_CONFIG *s_cfg)
1366 printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__);
1369 /* Handle FSP logo params */
1370 void soc_load_logo(FSPS_UPD *supd)
1372 fsp_convert_bmp_to_gop_blt(&supd->FspsConfig.LogoPtr,
1373 &supd->FspsConfig.LogoSize,
1374 &supd->FspsConfig.BltBufferAddress,
1375 &supd->FspsConfig.BltBufferSize,
1376 &supd->FspsConfig.LogoPixelHeight,
1377 &supd->FspsConfig.LogoPixelWidth);