soc/amd/picasso: Migrate to struct pci_routing_info

This allows us to use the common get_pci_routing_info and
pci_calculate_irq. The IRQ field in the struct was also filled in from
the PPR.

BUG=b:184766519
TEST=Boot ezkinil and verify SSDT table is identical.

Signed-off-by: Raul E Rangel <rrangel@chromium.org>
Change-Id: I16d90d8c89bfcf48878c0741154290ebc52a4120
Reviewed-on: https://review.coreboot.org/c/coreboot/+/53923
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Raul E Rangel
2021-05-07 11:19:42 -06:00
committed by Felix Held
parent 6ddace437c
commit a8405a4c4a

View File

@@ -12,30 +12,24 @@
#include <soc/pci_devs.h> #include <soc/pci_devs.h>
#include <stdio.h> #include <stdio.h>
/** /* See AMD PPR 55570 - IOAPIC Initialization for the table that AGESA sets up */
* Each PCI bridge has its INTx lines routed to one of the 8 GNB IOAPIC PCI const struct pci_routing_info pci_routing_table[] = {
* groups. Each group has 4 interrupts. The INTx lines can be swizzled before {PCIE_GPP_0_DEVFN, 0, PCI_SWIZZLE_ABCD, 0x10},
* being routed to the IOAPIC. If the IOAPIC redirection entry is masked, the {PCIE_GPP_1_DEVFN, 1, PCI_SWIZZLE_ABCD, 0x11},
* interrupt is reduced modulo 8 onto INT[A-H] and forwarded to the FCH IOAPIC. {PCIE_GPP_2_DEVFN, 2, PCI_SWIZZLE_ABCD, 0x12},
**/ {PCIE_GPP_3_DEVFN, 3, PCI_SWIZZLE_ABCD, 0x13},
struct pci_routing { {PCIE_GPP_4_DEVFN, 4, PCI_SWIZZLE_ABCD, 0x10},
unsigned int devfn; {PCIE_GPP_5_DEVFN, 5, PCI_SWIZZLE_ABCD, 0x11},
unsigned int group; {PCIE_GPP_6_DEVFN, 6, PCI_SWIZZLE_ABCD, 0x12},
uint8_t pin[4]; {PCIE_GPP_A_DEVFN, 7, PCI_SWIZZLE_ABCD, 0x13},
{PCIE_GPP_B_DEVFN, 7, PCI_SWIZZLE_CDAB, 0x0C},
}; };
/* See AMD PPR 55570 - IOAPIC Initialization for the table that AGESA sets up */ const struct pci_routing_info *get_pci_routing_table(size_t *entries)
static const struct pci_routing pci_routing_table[] = { {
{PCIE_GPP_0_DEVFN, 0, {PIRQ_A, PIRQ_B, PIRQ_C, PIRQ_D} }, *entries = ARRAY_SIZE(pci_routing_table);
{PCIE_GPP_1_DEVFN, 1, {PIRQ_A, PIRQ_B, PIRQ_C, PIRQ_D} }, return pci_routing_table;
{PCIE_GPP_2_DEVFN, 2, {PIRQ_A, PIRQ_B, PIRQ_C, PIRQ_D} }, }
{PCIE_GPP_3_DEVFN, 3, {PIRQ_A, PIRQ_B, PIRQ_C, PIRQ_D} },
{PCIE_GPP_4_DEVFN, 4, {PIRQ_A, PIRQ_B, PIRQ_C, PIRQ_D} },
{PCIE_GPP_5_DEVFN, 5, {PIRQ_A, PIRQ_B, PIRQ_C, PIRQ_D} },
{PCIE_GPP_6_DEVFN, 6, {PIRQ_A, PIRQ_B, PIRQ_C, PIRQ_D} },
{PCIE_GPP_A_DEVFN, 7, {PIRQ_A, PIRQ_B, PIRQ_C, PIRQ_D} },
{PCIE_GPP_B_DEVFN, 7, {PIRQ_C, PIRQ_D, PIRQ_A, PIRQ_B} },
};
/* /*
* This data structure is populated from the raw data above. It is used * This data structure is populated from the raw data above. It is used
@@ -44,28 +38,9 @@ static const struct pci_routing pci_routing_table[] = {
*/ */
static struct pirq_struct pirq_data[ARRAY_SIZE(pci_routing_table)]; static struct pirq_struct pirq_data[ARRAY_SIZE(pci_routing_table)];
static const struct pci_routing *get_pci_routing(unsigned int devfn)
{
for (size_t i = 0; i < ARRAY_SIZE(pci_routing_table); ++i) {
if (devfn == pci_routing_table[i].devfn)
return &pci_routing_table[i];
}
return NULL;
}
static unsigned int calculate_irq(const struct pci_routing *pci_routing, unsigned int i)
{
unsigned int irq_index;
irq_index = pci_routing->group * 4;
irq_index += pci_routing->pin[i];
return irq_index;
}
void populate_pirq_data(void) void populate_pirq_data(void)
{ {
const struct pci_routing *pci_routing; const struct pci_routing_info *pci_routing;
struct pirq_struct *pirq; struct pirq_struct *pirq;
unsigned int irq_index; unsigned int irq_index;
@@ -75,7 +50,7 @@ void populate_pirq_data(void)
pirq->devfn = pci_routing->devfn; pirq->devfn = pci_routing->devfn;
for (size_t j = 0; j < 4; ++j) { for (size_t j = 0; j < 4; ++j) {
irq_index = calculate_irq(pci_routing, j); irq_index = pci_calculate_irq(pci_routing, j);
pirq->PIN[j] = irq_index % 8; pirq->PIN[j] = irq_index % 8;
} }
@@ -119,7 +94,7 @@ static void acpigen_write_PRT(const struct device *dev)
char link_template[] = "\\_SB.INTX"; char link_template[] = "\\_SB.INTX";
unsigned int irq_index; unsigned int irq_index;
const struct pci_routing *pci_routing = get_pci_routing(dev->path.pci.devfn); const struct pci_routing_info *pci_routing = get_pci_routing_info(dev->path.pci.devfn);
if (!pci_routing) { if (!pci_routing) {
printk(BIOS_ERR, "PCI routing table not found for %s\n", dev_path(dev)); printk(BIOS_ERR, "PCI routing table not found for %s\n", dev_path(dev));
return; return;
@@ -136,7 +111,7 @@ static void acpigen_write_PRT(const struct device *dev)
acpigen_write_package(4); /* Package - APIC Routing */ acpigen_write_package(4); /* Package - APIC Routing */
for (unsigned int i = 0; i < 4; ++i) { for (unsigned int i = 0; i < 4; ++i) {
irq_index = calculate_irq(pci_routing, i); irq_index = pci_calculate_irq(pci_routing, i);
acpigen_write_package(4); acpigen_write_package(4);
/* There is only one device attached to the bridge */ /* There is only one device attached to the bridge */
@@ -157,7 +132,7 @@ static void acpigen_write_PRT(const struct device *dev)
acpigen_write_package(4); /* Package - PIC Routing */ acpigen_write_package(4); /* Package - PIC Routing */
for (unsigned int i = 0; i < 4; ++i) { for (unsigned int i = 0; i < 4; ++i) {
irq_index = calculate_irq(pci_routing, i); irq_index = pci_calculate_irq(pci_routing, i);
link_template[8] = 'A' + (irq_index % 8); link_template[8] = 'A' + (irq_index % 8);