soc/intel/common/irq: Internally cache PCI IRQ results
The results of the PCI IRQ assignments are used in several places, so it makes for a nicer API to cache the results and provide simpler functions for the SoCs to call. BUG=b:130217151, b:171580862, b:176858827 Change-Id: Id79eae3f2360cd64f66e7f53e1d78a23cfe5e9df Signed-off-by: Tim Wawrzynczak <twawrzynczak@chromium.org> Reviewed-on: https://review.coreboot.org/c/coreboot/+/55825 Reviewed-by: Furquan Shaikh <furquan@google.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
81bcce9c8d
commit
e9ee919fac
|
@ -41,11 +41,24 @@ struct pci_irq_entry {
|
||||||
struct pci_irq_entry *next;
|
struct pci_irq_entry *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct pci_irq_entry *assign_pci_irqs(const struct slot_irq_constraints *constraints,
|
/*
|
||||||
size_t num_slots);
|
* This functions applies rules from FSP, BWG and SoC to come up with a set of
|
||||||
|
* PCI slot/function --> IRQ pin/IRQ number entries.
|
||||||
|
*
|
||||||
|
* The results of this calculation are cached within this module for usage
|
||||||
|
* by the other API functions.
|
||||||
|
*/
|
||||||
|
bool assign_pci_irqs(const struct slot_irq_constraints *constraints, size_t num_slots);
|
||||||
|
|
||||||
void generate_pin_irq_map(const struct pci_irq_entry *entries);
|
/* Generate an ACPI PCI IRQ routing table (_PRT) in the \_SB.PCI0 scope, using
|
||||||
|
the cached results. */
|
||||||
|
bool generate_pin_irq_map(void);
|
||||||
|
|
||||||
void irq_program_non_pch(const struct pci_irq_entry *entries);
|
/* Typically the FSP can accept a list of the mappings provided above, and
|
||||||
|
program them, but for PCH devices only. This function provides the same
|
||||||
|
function for non-PCH devices. */
|
||||||
|
bool irq_program_non_pch(void);
|
||||||
|
|
||||||
|
const struct pci_irq_entry *get_cached_pci_irqs(void);
|
||||||
|
|
||||||
#endif /* SOC_INTEL_COMMON_IRQ_H */
|
#endif /* SOC_INTEL_COMMON_IRQ_H */
|
||||||
|
|
|
@ -325,17 +325,16 @@ static bool assign_slot(struct pci_irq_entry **head,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct pci_irq_entry *assign_pci_irqs(const struct slot_irq_constraints *constraints,
|
static struct pci_irq_entry *cached_entries;
|
||||||
size_t num_slots)
|
|
||||||
{
|
|
||||||
struct pci_irq_entry *entries = NULL;
|
|
||||||
|
|
||||||
|
bool assign_pci_irqs(const struct slot_irq_constraints *constraints, size_t num_slots)
|
||||||
|
{
|
||||||
for (size_t i = 0; i < num_slots; i++) {
|
for (size_t i = 0; i < num_slots; i++) {
|
||||||
if (!assign_slot(&entries, &constraints[i]))
|
if (!assign_slot(&cached_entries, &constraints[i]))
|
||||||
return NULL;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct pci_irq_entry *entry = entries;
|
const struct pci_irq_entry *entry = cached_entries;
|
||||||
while (entry) {
|
while (entry) {
|
||||||
printk(BIOS_INFO, "PCI %2X.%X, %s, using IRQ #%d\n",
|
printk(BIOS_INFO, "PCI %2X.%X, %s, using IRQ #%d\n",
|
||||||
PCI_SLOT(entry->devfn), PCI_FUNC(entry->devfn),
|
PCI_SLOT(entry->devfn), PCI_FUNC(entry->devfn),
|
||||||
|
@ -344,7 +343,12 @@ const struct pci_irq_entry *assign_pci_irqs(const struct slot_irq_constraints *c
|
||||||
entry = entry->next;
|
entry = entry->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
return entries;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct pci_irq_entry *get_cached_pci_irqs(void)
|
||||||
|
{
|
||||||
|
return cached_entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum pirq irq_to_pirq(unsigned int irq)
|
static enum pirq irq_to_pirq(unsigned int irq)
|
||||||
|
@ -360,7 +364,7 @@ static enum pirq irq_to_pirq(unsigned int irq)
|
||||||
return PIRQ_INVALID;
|
return PIRQ_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
void generate_pin_irq_map(const struct pci_irq_entry *entries)
|
bool generate_pin_irq_map(void)
|
||||||
{
|
{
|
||||||
struct slot_pin_irq_map *pin_irq_map;
|
struct slot_pin_irq_map *pin_irq_map;
|
||||||
const uint8_t *legacy_pirq_routing;
|
const uint8_t *legacy_pirq_routing;
|
||||||
|
@ -369,6 +373,9 @@ void generate_pin_irq_map(const struct pci_irq_entry *entries)
|
||||||
size_t pirq_routes;
|
size_t pirq_routes;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
|
if (!cached_entries)
|
||||||
|
return false;
|
||||||
|
|
||||||
pin_irq_map = calloc(MAX_SLOTS, sizeof(struct slot_pin_irq_map) * PCI_INT_MAX);
|
pin_irq_map = calloc(MAX_SLOTS, sizeof(struct slot_pin_irq_map) * PCI_INT_MAX);
|
||||||
|
|
||||||
pirq_map.type = PIRQ_GSI;
|
pirq_map.type = PIRQ_GSI;
|
||||||
|
@ -376,7 +383,7 @@ void generate_pin_irq_map(const struct pci_irq_entry *entries)
|
||||||
for (i = 0; i < PIRQ_COUNT && i < pirq_routes; i++)
|
for (i = 0; i < PIRQ_COUNT && i < pirq_routes; i++)
|
||||||
pirq_map.gsi[i] = legacy_pirq_routing[i];
|
pirq_map.gsi[i] = legacy_pirq_routing[i];
|
||||||
|
|
||||||
const struct pci_irq_entry *entry = entries;
|
const struct pci_irq_entry *entry = cached_entries;
|
||||||
while (entry) {
|
while (entry) {
|
||||||
const unsigned int slot = PCI_SLOT(entry->devfn);
|
const unsigned int slot = PCI_SLOT(entry->devfn);
|
||||||
|
|
||||||
|
@ -395,21 +402,30 @@ void generate_pin_irq_map(const struct pci_irq_entry *entries)
|
||||||
|
|
||||||
intel_write_pci0_PRT(pin_irq_map, map_count, &pirq_map);
|
intel_write_pci0_PRT(pin_irq_map, map_count, &pirq_map);
|
||||||
free(pin_irq_map);
|
free(pin_irq_map);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void irq_program_non_pch(const struct pci_irq_entry *entries)
|
bool irq_program_non_pch(void)
|
||||||
{
|
{
|
||||||
while (entries) {
|
const struct pci_irq_entry *entry = cached_entries;
|
||||||
if (PCI_SLOT(entries->devfn) >= MIN_PCH_SLOT) {
|
|
||||||
entries = entries->next;
|
if (!entry)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
while (entry) {
|
||||||
|
if (PCI_SLOT(entry->devfn) >= MIN_PCH_SLOT) {
|
||||||
|
entry = entry->next;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entries->irq)
|
if (entry->irq)
|
||||||
pci_s_write_config8(PCI_DEV(0, PCI_SLOT(entries->devfn),
|
pci_s_write_config8(PCI_DEV(0, PCI_SLOT(entry->devfn),
|
||||||
PCI_FUNC(entries->devfn)),
|
PCI_FUNC(entry->devfn)),
|
||||||
PCI_INTERRUPT_LINE, entries->irq);
|
PCI_INTERRUPT_LINE, entry->irq);
|
||||||
|
|
||||||
entries = entries->next;
|
entry = entry->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue