soc/intel/pantherlake: Remove soc_info.[hc] interface
[coreboot2.git] / src / southbridge / intel / common / rcba_pirq.c
blob956fe633daf69f2deba8920a8abe5549f2ffc1a6
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <acpi/acpi_device.h>
4 #include <console/console.h>
5 #include <device/device.h>
6 #include <device/pci.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <southbridge/intel/common/acpi_pirq_gen.h>
10 #include <southbridge/intel/common/rcba_pirq.h>
11 #include <southbridge/intel/common/rcba.h>
13 #define MAX_SLOT 31
14 #define MIN_SLOT 19
16 static const u32 pirq_dir_route_reg[MAX_SLOT - MIN_SLOT + 1] = {
17 D19IR, D20IR, D21IR, D22IR, D23IR, 0, D25IR,
18 D26IR, D27IR, D28IR, D29IR, D30IR, D31IR,
21 static enum pirq map_pirq(const struct device *dev, const enum pci_pin pci_pin)
23 u8 slot = PCI_SLOT(dev->path.pci.devfn);
24 u8 shift = 4 * (pci_pin - PCI_INT_A);
25 u8 pirq;
26 u16 reg;
28 if (pci_pin < PCI_INT_A || pci_pin > PCI_INT_D) {
29 printk(BIOS_ERR, "ACPI_PIRQ_GEN: Slot %d PCI pin %d out of bounds\n",
30 slot, pci_pin);
31 return PIRQ_INVALID;
34 /* Slot 24 should not exist and has no D24IR but better be safe here */
35 if (slot < MIN_SLOT || slot > MAX_SLOT || slot == 24) {
36 /* non-PCH devices use 1:1 mapping. */
37 return (enum pirq)pci_pin;
40 reg = pirq_dir_route_reg[slot - MIN_SLOT];
42 pirq = (RCBA16(reg) >> shift) & 0x7;
44 return (enum pirq)(pirq + PIRQ_A);
47 void intel_acpi_gen_def_acpi_pirq(const struct device *lpc)
49 struct slot_pin_irq_map *pin_irq_map;
50 const char *lpcb_path = acpi_device_path(lpc);
51 struct pic_pirq_map pirq_map = {0};
52 unsigned int map_count = 0;
53 int i;
55 if (!lpcb_path) {
56 printk(BIOS_ERR, "ACPI_PIRQ_GEN: Missing LPCB ACPI path\n");
57 return;
60 printk(BIOS_DEBUG, "Generating ACPI PIRQ entries\n");
62 pin_irq_map = calloc(MAX_SLOTS * PCI_INT_MAX, sizeof(struct slot_pin_irq_map));
63 pirq_map.type = PIRQ_SOURCE_PATH;
64 for (i = 0; i < PIRQ_COUNT; i++)
65 snprintf(pirq_map.source_path[i], sizeof(pirq_map.source_path[i]),
66 "%s.LNK%c", lpcb_path, 'A' + i);
68 for (struct device *dev = pcidev_on_root(0, 0); dev; dev = dev->sibling) {
69 const u8 pci_dev = PCI_SLOT(dev->path.pci.devfn);
70 const u8 int_pin = pci_read_config8(dev, PCI_INTERRUPT_PIN);
72 if (int_pin < PCI_INT_A || int_pin > PCI_INT_D)
73 continue;
75 if (is_slot_pin_assigned(pin_irq_map, map_count, pci_dev, int_pin))
76 continue;
78 enum pirq pirq = map_pirq(dev, int_pin);
79 if (pirq == PIRQ_INVALID)
80 continue;
82 pin_irq_map[map_count].slot = pci_dev;
83 pin_irq_map[map_count].pin = (enum pci_pin)int_pin;
84 pin_irq_map[map_count].pic_pirq = pirq;
85 /* PIRQs are mapped to GSIs starting at 16 */
86 pin_irq_map[map_count].apic_gsi = 16 + pirq_idx(pirq);
87 printk(BIOS_SPEW, "ACPI_PIRQ_GEN: %s: pin=%d pirq=%zd\n",
88 dev_path(dev), int_pin - PCI_INT_A,
89 pirq_idx(pin_irq_map[map_count].pic_pirq));
90 map_count++;
93 intel_write_pci0_PRT(pin_irq_map, map_count, &pirq_map);
95 free(pin_irq_map);