Attention is currently required from: Jason Glenesk, Marshall Dawson, Felix Held. Raul Rangel has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/53922 )
Change subject: soc/amd/common/block/pci: Introduce struct pci_routing_info ......................................................................
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 --- M src/soc/amd/common/block/include/amdblocks/amd_pci_util.h M src/soc/amd/common/block/pci/Makefile.inc A src/soc/amd/common/block/pci/pci_routing_info.c 3 files changed, 85 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/22/53922/1
diff --git a/src/soc/amd/common/block/include/amdblocks/amd_pci_util.h b/src/soc/amd/common/block/include/amdblocks/amd_pci_util.h index 081741a..bc8eefb 100644 --- a/src/soc/amd/common/block/include/amdblocks/amd_pci_util.h +++ b/src/soc/amd/common/block/include/amdblocks/amd_pci_util.h @@ -31,7 +31,34 @@ 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, + 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; +}; + /* 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 */ diff --git a/src/soc/amd/common/block/pci/Makefile.inc b/src/soc/amd/common/block/pci/Makefile.inc index 78453d4..5df641b 100644 --- a/src/soc/amd/common/block/pci/Makefile.inc +++ b/src/soc/amd/common/block/pci/Makefile.inc @@ -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)
diff --git a/src/soc/amd/common/block/pci/pci_routing_info.c b/src/soc/amd/common/block/pci/pci_routing_info.c new file mode 100644 index 0000000..e0a6964 --- /dev/null +++ b/src/soc/amd/common/block/pci/pci_routing_info.c @@ -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; +}