1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <arch/ioapic.h>
4 #include <console/console.h>
5 #include <device/pci.h>
6 #include <device/pci_def.h>
7 #include <device/pci_ops.h>
8 #include <intelblocks/itss.h>
9 #include <intelblocks/lpc_lib.h>
10 #include <intelblocks/pcr.h>
11 #include <soc/iomap.h>
14 #include <soc/pcr_ids.h>
17 static void soc_pch_pirq_init(void)
19 for (uint32_t reg
= PCR_ITSS_PIRQA_ROUT
; reg
<= PCR_ITSS_PIRQH_ROUT
; reg
++)
20 printk(BIOS_SPEW
, "PIRQ Routing Control %c at 0x%04x: 0x%02x\n",
21 reg
- PCR_ITSS_PIRQA_ROUT
+ 'A', reg
, pcr_read8(PID_ITSS
, reg
));
23 for (uint32_t reg
= 0; reg
< 32; reg
++)
24 printk(BIOS_SPEW
, "PCI Interrupt Route %d at 0x%04x: 0x%02x\n", reg
,
25 PCI_ITSS_PIR(reg
), pcr_read16(PID_ITSS
, PCI_ITSS_PIR(reg
)));
27 /* The PIRQA-H registers are programmable thus legacy PIC mode is supported. */
29 const uint8_t *pch_interrupt_routing
= lpc_get_pic_pirq_routing(&num
);
30 itss_irq_init(pch_interrupt_routing
);
32 for (struct device
*dev
= all_devices
; dev
; dev
= dev
->next
) {
33 if (!is_enabled_pci(dev
))
36 enum pirq pirq
= itss_soc_get_dev_pirq(dev
);
37 if (pirq
== PIRQ_INVALID
)
40 uint8_t pirq_value
= pcr_read8(PID_ITSS
, PCR_ITSS_PIRQA_ROUT
+ pirq_idx(pirq
));
41 if (pirq_value
& 0x80)
42 pci_write_config8(dev
, PCI_INTERRUPT_LINE
, PCH_IRQ16
+ pirq_idx(pirq
));
44 pci_write_config8(dev
, PCI_INTERRUPT_LINE
, pirq_value
& 0x0f);
46 printk(BIOS_DEBUG
, "%s is using %s, line 0x%2x\n", dev_path(dev
),
47 pin_to_str(pci_read_config8(dev
, PCI_INTERRUPT_PIN
)),
48 pci_read_config8(dev
, PCI_INTERRUPT_LINE
));
52 void lpc_soc_init(struct device
*dev
)
54 lpc_set_serirq_mode(CONFIG(SERIRQ_CONTINUOUS_MODE
) ? SERIRQ_CONTINUOUS
: SERIRQ_QUIET
);
56 ioapic_set_max_vectors(IO_APIC_ADDR
, PCH_REDIR_ETR
);
58 setup_ioapic(IO_APIC_ADDR
, PCH_IOAPIC_ID
);
59 ioapic_set_boot_config(IO_APIC_ADDR
, true);
64 void pch_lpc_soc_fill_io_resources(struct device
*dev
)
68 res
= new_resource(dev
, PCI_BASE_ADDRESS_4
); /**< Use the register offset in PMC. */
69 res
->base
= ACPI_BASE_ADDRESS
;
70 res
->size
= 0x80; /**< 128 bytes I/O config space */
71 res
->flags
= IORESOURCE_IO
| IORESOURCE_ASSIGNED
| IORESOURCE_FIXED
;
72 printk(BIOS_DEBUG
, "Adding ACPI IO config space BAR at base 0x%08llx, size 0x%08llx\n",
73 res
->base
, res
->size
);