summaryrefslogtreecommitdiff
path: root/src/soc/amd/common/block
diff options
context:
space:
mode:
Diffstat (limited to 'src/soc/amd/common/block')
-rw-r--r--src/soc/amd/common/block/data_fabric/Kconfig16
-rw-r--r--src/soc/amd/common/block/data_fabric/domain.c12
-rw-r--r--src/soc/amd/common/block/data_fabric/pci_segment_multi.c8
-rw-r--r--src/soc/amd/common/block/data_fabric/pci_segment_single.c9
4 files changed, 37 insertions, 8 deletions
diff --git a/src/soc/amd/common/block/data_fabric/Kconfig b/src/soc/amd/common/block/data_fabric/Kconfig
index ba771c6dce..699c8888e5 100644
--- a/src/soc/amd/common/block/data_fabric/Kconfig
+++ b/src/soc/amd/common/block/data_fabric/Kconfig
@@ -14,6 +14,22 @@ config SOC_AMD_COMMON_BLOCK_DATA_FABRIC_DOMAIN
fabric registers so that it knows in which regions it can properly
allocate the non-fixed MMIO devices.
+config SOC_AMD_COMMON_BLOCK_DATA_FABRIC_DOMAIN_MULTI_PCI_ROOT
+ bool
+ depends on SOC_AMD_COMMON_BLOCK_DATA_FABRIC_DOMAIN
+ help
+ On AMD SoCs with more than one PCI root, make sure to only report the
+ PCI bus number, IO, and MMIO resources that get decoded to a specific
+ PCI root in the corresponding coreboot domain. This will make sure
+ that the allocation the resoucre allocator calculates will be decoded
+ correctly to the PCI roots. In order for coreboot to know the correct
+ mapping, the coreboot domain numbers must be set to the corresponding
+ data fabric destination ID. On AMD systems with only one PCI root,
+ this isn't needed and even though selecting this option works when
+ the coreboot domain numbers are set up correctly, some link-time
+ optimizations won't be possible, so it's preferable to only select
+ this option on SoCs with multiple PCI roots.
+
config SOC_AMD_COMMON_BLOCK_DATA_FABRIC_MULTI_PCI_SEGMENT
bool
depends on SOC_AMD_COMMON_BLOCK_DATA_FABRIC_DOMAIN
diff --git a/src/soc/amd/common/block/data_fabric/domain.c b/src/soc/amd/common/block/data_fabric/domain.c
index d693879ce6..39243514cc 100644
--- a/src/soc/amd/common/block/data_fabric/domain.c
+++ b/src/soc/amd/common/block/data_fabric/domain.c
@@ -113,8 +113,10 @@ static void add_data_fabric_mmio_regions(struct device *domain, unsigned int *id
if (ctrl.np)
continue;
- /* TODO: Systems with more than one PCI root need to check to which PCI root
- the MMIO range gets decoded to. */
+ /* Only look at MMIO regions that are decoded to the right PCI root */
+ if (CONFIG(SOC_AMD_COMMON_BLOCK_DATA_FABRIC_DOMAIN_MULTI_PCI_ROOT) &&
+ ctrl.dst_fabric_id != domain->path.domain.domain)
+ continue;
data_fabric_get_mmio_base_size(i, &mmio_base, &mmio_limit);
@@ -168,8 +170,10 @@ static void add_data_fabric_io_regions(struct device *domain, unsigned int *idx)
limit_reg.raw = data_fabric_broadcast_read32(DF_IO_LIMIT(i));
- /* TODO: Systems with more than one PCI root need to check to which PCI root
- the IO range gets decoded to. */
+ /* Only look at IO regions that are decoded to the right PCI root */
+ if (CONFIG(SOC_AMD_COMMON_BLOCK_DATA_FABRIC_DOMAIN_MULTI_PCI_ROOT) &&
+ limit_reg.dst_fabric_id != domain->path.domain.domain)
+ continue;
io_base = base_reg.io_base << DF_IO_ADDR_SHIFT;
io_limit = ((limit_reg.io_limit + 1) << DF_IO_ADDR_SHIFT) - 1;
diff --git a/src/soc/amd/common/block/data_fabric/pci_segment_multi.c b/src/soc/amd/common/block/data_fabric/pci_segment_multi.c
index 67822216cd..a474ed94bf 100644
--- a/src/soc/amd/common/block/data_fabric/pci_segment_multi.c
+++ b/src/soc/amd/common/block/data_fabric/pci_segment_multi.c
@@ -15,8 +15,10 @@ enum cb_err data_fabric_get_pci_bus_numbers(struct device *domain, uint8_t *firs
pci_bus_base.raw = data_fabric_broadcast_read32(DF_PCI_CFG_BASE(i));
pci_bus_limit.raw = data_fabric_broadcast_read32(DF_PCI_CFG_LIMIT(i));
- /* TODO: Systems with more than one PCI root need to check to which PCI root
- the PCI bus number range gets decoded to. */
+ if (CONFIG(SOC_AMD_COMMON_BLOCK_DATA_FABRIC_DOMAIN_MULTI_PCI_ROOT) &&
+ pci_bus_limit.dst_fabric_id != domain->path.domain.domain)
+ continue;
+
if (pci_bus_base.we && pci_bus_base.re) {
/* TODO: Implement support for multiple PCI segments in coreboot */
if (pci_bus_base.segment_num) {
@@ -31,5 +33,7 @@ enum cb_err data_fabric_get_pci_bus_numbers(struct device *domain, uint8_t *firs
}
}
+ printk(BIOS_ERR, "No valid DF PCI CFG register pair found for domain %x.\n",
+ domain->path.domain.domain);
return CB_ERR;
}
diff --git a/src/soc/amd/common/block/data_fabric/pci_segment_single.c b/src/soc/amd/common/block/data_fabric/pci_segment_single.c
index 5f2152b668..d4e1580805 100644
--- a/src/soc/amd/common/block/data_fabric/pci_segment_single.c
+++ b/src/soc/amd/common/block/data_fabric/pci_segment_single.c
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <amdblocks/data_fabric.h>
+#include <console/console.h>
#include <device/device.h>
#include <types.h>
@@ -12,8 +13,10 @@ enum cb_err data_fabric_get_pci_bus_numbers(struct device *domain, uint8_t *firs
for (unsigned int i = 0; i < DF_PCI_CFG_MAP_COUNT; i++) {
pci_bus_map.raw = data_fabric_broadcast_read32(DF_PCI_CFG_MAP(i));
- /* TODO: Systems with more than one PCI root need to check to which PCI root
- the PCI bus number range gets decoded to. */
+ if (CONFIG(SOC_AMD_COMMON_BLOCK_DATA_FABRIC_DOMAIN_MULTI_PCI_ROOT) &&
+ pci_bus_map.dst_fabric_id != domain->path.domain.domain)
+ continue;
+
if (pci_bus_map.we && pci_bus_map.re) {
*first_bus = pci_bus_map.bus_num_base;
*last_bus = pci_bus_map.bus_num_limit;
@@ -21,5 +24,7 @@ enum cb_err data_fabric_get_pci_bus_numbers(struct device *domain, uint8_t *firs
}
}
+ printk(BIOS_ERR, "No valid DF PCI CFG register found for domain %x.\n",
+ domain->path.domain.domain);
return CB_ERR;
}