| /* SPDX-License-Identifier: GPL-2.0-only */ |
| |
| #ifndef INTEL_COMMON_ACPI_PIRQ_GEN_H |
| #define INTEL_COMMON_ACPI_PIRQ_GEN_H |
| |
| #include <assert.h> |
| #include <device/device.h> |
| |
| #define MAX_SLOTS 32 |
| |
| enum pci_pin { |
| PCI_INT_NONE = 0, |
| PCI_INT_A, |
| PCI_INT_B, |
| PCI_INT_C, |
| PCI_INT_D, |
| PCI_INT_MAX = PCI_INT_D, |
| }; |
| |
| enum pirq { |
| PIRQ_INVALID, |
| PIRQ_A, |
| PIRQ_B, |
| PIRQ_C, |
| PIRQ_D, |
| PIRQ_E, |
| PIRQ_F, |
| PIRQ_G, |
| PIRQ_H, |
| PIRQ_COUNT = PIRQ_H, |
| }; |
| |
| static inline size_t pirq_idx(enum pirq pirq) |
| { |
| assert(pirq > PIRQ_INVALID && pirq <= PIRQ_H); |
| return (size_t)(pirq - PIRQ_A); |
| } |
| |
| /* |
| * This struct represents an assignment of slot/pin -> IRQ. Some chipsets may |
| * want to provide both PIC-mode and APIC-mode IRQs (e.g. selected using PICM |
| * set by the OS), therefore a field for each of a PIRQ for PIC-mode and a |
| * GSI for APIC-mode are provided. |
| * |
| * For APIC mode, only GSIs are supported (`acpi_gsi`). |
| * |
| * For PIC mode, if the pirq_map_type is PIRQ_GSI, then `pic_pirq` is used as an |
| * index into `struct pic_pirq_map.gsi`, or for SOURCE_PATH, `pic_pirq` indexes |
| * into `struct pic_pirq_map.source_path` to pick the path to the LNKx device. |
| * |
| * The reasoning for this structure is related to older vs. newer Intel |
| * platforms; older platforms supported routing of PCI IRQs to a PIRQ |
| * only. Newer platforms support routing IRQs to either a PIRQ or (for some PCI |
| * devices) a non-PIRQ GSI. |
| */ |
| struct slot_pin_irq_map { |
| unsigned int slot; |
| enum pci_pin pin; |
| /* PIRQ # for PIC mode */ |
| unsigned int pic_pirq; |
| /* GSI # for APIC mode */ |
| unsigned int apic_gsi; |
| }; |
| |
| enum pirq_map_type { |
| PIRQ_GSI, |
| PIRQ_SOURCE_PATH, |
| }; |
| |
| /* |
| * A PIRQ can be either be statically assigned a GSI or OSPM can use the Methods |
| * on the ACPI device (source_path) to assign IRQs at runtime. |
| */ |
| struct pic_pirq_map { |
| enum pirq_map_type type; |
| union { |
| unsigned int gsi[PIRQ_COUNT]; |
| char source_path[PIRQ_COUNT][DEVICE_PATH_MAX]; |
| }; |
| }; |
| |
| /* |
| * Generate an ACPI _PRT table by providing PIRQ and/or GSI information for each |
| * slot/pin combination, and optionally providing paths to LNKx devices that can |
| * provide IRQs in PIC mode. |
| */ |
| void intel_write_pci0_PRT(const struct slot_pin_irq_map *pin_irq_map, |
| unsigned int map_count, |
| const struct pic_pirq_map *pirq_map); |
| |
| bool is_slot_pin_assigned(const struct slot_pin_irq_map *pin_irq_map, |
| unsigned int map_count, unsigned int slot, |
| enum pci_pin pin); |
| |
| #endif |