diff options
Diffstat (limited to 'src/soc/amd/common/block')
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; } |