soc/amd/common/block/pci: Introduce struct pci_routing_info

This struct is similar to `struct pci_routing` defined in
picasso/pcie_gpp.c. It additionally contains the irq used for the bridge
and is structured in a way that the FSP can provide via HOB.

The next set of CLs will migrate the pci routing functions used by
picasso into common and enable pci routing table generation for cezanne.

BUG=b:184766519
TEST=Build guybrush

Signed-off-by: Raul E Rangel <rrangel@chromium.org>
Change-Id: I1a8d988d125f407f0aa7bc1722d432446aa9aff8
Reviewed-on: https://review.coreboot.org/c/coreboot/+/53922
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
This commit is contained in:
Raul E Rangel 2021-05-07 10:47:34 -06:00 committed by Felix Held
parent 9b330fafeb
commit 6ddace437c
3 changed files with 85 additions and 0 deletions

View File

@ -31,7 +31,34 @@ void write_pci_cfg_irqs(void);
void write_pci_int_table(void);
const struct irq_idx_name *sb_get_apic_reg_association(size_t *size);
enum pci_routing_swizzle {
PCI_SWIZZLE_ABCD = 0,
PCI_SWIZZLE_BCDA,
PCI_SWIZZLE_CDAB,
PCI_SWIZZLE_DABC,
};
/**
* Each PCI bridge has its INTx lines routed to one of the GNB IO-APIC PCI
* groups. Each group has 4 interrupts. The INTx lines can be swizzled before
* being routed to the IO-APIC. If the IO-APIC redirection entry is masked, the
* interrupt is reduced modulo 8 onto INT[A-H] and forwarded to the FCH IO-APIC.
**/
struct pci_routing_info {
uint8_t devfn;
uint8_t group;
uint8_t swizzle;
uint8_t irq;
} __packed;
/* Implemented by the SoC */
void populate_pirq_data(void);
/* Implemented by the SoC */
const struct pci_routing_info *get_pci_routing_table(size_t *entries);
const struct pci_routing_info *get_pci_routing_info(unsigned int devfn);
unsigned int pci_calculate_irq(const struct pci_routing_info *routing_info, unsigned int pin);
#endif /* AMD_BLOCK_PCI_UTIL_H */

View File

@ -1,4 +1,5 @@
ramstage-$(CONFIG_SOC_AMD_COMMON_BLOCK_PCI) += amd_pci_util.c
ramstage-$(CONFIG_SOC_AMD_COMMON_BLOCK_PCI) += pci_routing_info.c
ifeq ($(CONFIG_SOC_AMD_COMMON_BLOCK_PCI_MMCONF),y)

View File

@ -0,0 +1,57 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <amdblocks/amd_pci_util.h>
#include <console/console.h>
#include <device/pci_def.h>
#include <types.h>
enum pcie_swizzle_pin {
PIN_A,
PIN_B,
PIN_C,
PIN_D,
};
static const uint8_t pcie_swizzle_table[][4] = {
{PIN_A, PIN_B, PIN_C, PIN_D},
{PIN_B, PIN_C, PIN_D, PIN_A},
{PIN_C, PIN_D, PIN_A, PIN_B},
{PIN_D, PIN_A, PIN_B, PIN_C},
};
const struct pci_routing_info *get_pci_routing_info(unsigned int devfn)
{
const struct pci_routing_info *routing_info;
size_t entries = 0;
routing_info = get_pci_routing_table(&entries);
if (!routing_info || !entries)
return NULL;
for (size_t i = 0; i < entries; ++i, ++routing_info)
if (routing_info->devfn == devfn)
return routing_info;
printk(BIOS_ERR, "Failed to find PCIe routing info for dev: %#x, fn: %#x\n",
PCI_SLOT(devfn), PCI_FUNC(devfn));
return NULL;
}
unsigned int pci_calculate_irq(const struct pci_routing_info *routing_info,
unsigned int pin)
{
unsigned int irq;
if (routing_info->swizzle >= ARRAY_SIZE(pcie_swizzle_table))
die("%s: swizzle %u out of bounds\n", __func__, routing_info->swizzle);
if (pin >= ARRAY_SIZE(pcie_swizzle_table[routing_info->swizzle]))
die("%s: pin %u out of bounds\n", __func__, pin);
irq = routing_info->group * 4;
irq += pcie_swizzle_table[routing_info->swizzle][pin];
return irq;
}