blob: 4799528fcc3d9cb76825c1de2dd33c4acfaca421 [file] [log] [blame]
/* 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, unsigned int pin);
#endif