summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/soc/amd/common/block/data_fabric/Kconfig9
-rw-r--r--src/soc/amd/common/block/data_fabric/Makefile.inc6
-rw-r--r--src/soc/amd/common/block/data_fabric/domain.c11
-rw-r--r--src/soc/amd/common/block/data_fabric/extended_mmio.c22
-rw-r--r--src/soc/amd/common/block/data_fabric/mmio.c16
-rw-r--r--src/soc/amd/common/block/include/amdblocks/data_fabric.h6
6 files changed, 59 insertions, 11 deletions
diff --git a/src/soc/amd/common/block/data_fabric/Kconfig b/src/soc/amd/common/block/data_fabric/Kconfig
index ba771c6dce..add2374b18 100644
--- a/src/soc/amd/common/block/data_fabric/Kconfig
+++ b/src/soc/amd/common/block/data_fabric/Kconfig
@@ -24,3 +24,12 @@ config SOC_AMD_COMMON_BLOCK_DATA_FABRIC_MULTI_PCI_SEGMENT
the PCI bus number which includes the segment number must select this
option; SoCs that use one data fabric register for the PCI bus number
which doesn't include a segment number field mustn't select this.
+
+config SOC_AMD_COMMON_BLOCK_DATA_FABRIC_EXTENDED_MMIO
+ bool
+ depends on SOC_AMD_COMMON_BLOCK_DATA_FABRIC_DOMAIN
+ help
+ Some AMD SoCs support more than 48 bit MMIO addresses. In order to
+ have enough bits for this, the MMIO address extension register is
+ introduced. SoCs that have this register must select this option in
+ order for the MMIO regions to be reported correctly.
diff --git a/src/soc/amd/common/block/data_fabric/Makefile.inc b/src/soc/amd/common/block/data_fabric/Makefile.inc
index bf0a21fddb..55a4d3f311 100644
--- a/src/soc/amd/common/block/data_fabric/Makefile.inc
+++ b/src/soc/amd/common/block/data_fabric/Makefile.inc
@@ -8,3 +8,9 @@ ramstage-$(CONFIG_SOC_AMD_COMMON_BLOCK_DATA_FABRIC_DOMAIN) += pci_segment_multi.
else
ramstage-$(CONFIG_SOC_AMD_COMMON_BLOCK_DATA_FABRIC_DOMAIN) += pci_segment_single.c
endif
+
+ifeq ($(CONFIG_SOC_AMD_COMMON_BLOCK_DATA_FABRIC_EXTENDED_MMIO),y)
+ramstage-$(CONFIG_SOC_AMD_COMMON_BLOCK_DATA_FABRIC_DOMAIN) += extended_mmio.c
+else
+ramstage-$(CONFIG_SOC_AMD_COMMON_BLOCK_DATA_FABRIC_DOMAIN) += mmio.c
+endif
diff --git a/src/soc/amd/common/block/data_fabric/domain.c b/src/soc/amd/common/block/data_fabric/domain.c
index 680d8d8c49..ca685b2fde 100644
--- a/src/soc/amd/common/block/data_fabric/domain.c
+++ b/src/soc/amd/common/block/data_fabric/domain.c
@@ -36,17 +36,6 @@ void amd_pci_domain_scan_bus(struct device *domain)
pci_domain_scan_bus(domain);
}
-/* Read the registers and return normalized values */
-static void data_fabric_get_mmio_base_size(unsigned int reg,
- resource_t *mmio_base, resource_t *mmio_limit)
-{
- const uint32_t base_reg = data_fabric_broadcast_read32(DF_MMIO_BASE(reg));
- const uint32_t limit_reg = data_fabric_broadcast_read32(DF_MMIO_LIMIT(reg));
- /* The raw register values are bits 47..16 of the actual address */
- *mmio_base = (resource_t)base_reg << DF_MMIO_SHIFT;
- *mmio_limit = (((resource_t)limit_reg + 1) << DF_MMIO_SHIFT) - 1;
-}
-
static void print_df_mmio_outside_of_cpu_mmio_error(unsigned int reg)
{
printk(BIOS_WARNING, "DF MMIO register %u outside of CPU MMIO region.\n", reg);
diff --git a/src/soc/amd/common/block/data_fabric/extended_mmio.c b/src/soc/amd/common/block/data_fabric/extended_mmio.c
new file mode 100644
index 0000000000..d0c3d9f051
--- /dev/null
+++ b/src/soc/amd/common/block/data_fabric/extended_mmio.c
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <amdblocks/data_fabric.h>
+#include <device/device.h>
+#include <types.h>
+
+/* Read the registers and return normalized values */
+void data_fabric_get_mmio_base_size(unsigned int reg, resource_t *mmio_base,
+ resource_t *mmio_limit)
+{
+ const uint32_t base_reg = data_fabric_broadcast_read32(DF_MMIO_BASE(reg));
+ const uint32_t limit_reg = data_fabric_broadcast_read32(DF_MMIO_LIMIT(reg));
+ const union df_mmio_addr_ext ext_reg.raw =
+ data_fabric_broadcast_read32(DF_MMIO_ADDR_EXT(reg));
+ /* The raw register values in the base and limit registers are bits 47..16 of the
+ actual address. The MMIO address extension register contains the extended MMIO base
+ and limit bits starting with bit 48 of the actual address. */
+ *mmio_base = (resource_t)ext_reg.base_ext << DF_MMIO_EXT_ADDR_SHIFT |
+ (resource_t)base_reg << DF_MMIO_SHIFT;
+ *mmio_limit = (resource_t)ext_reg.limit_ext << DF_MMIO_EXT_ADDR_SHIFT |
+ (((resource_t)limit_reg + 1) << DF_MMIO_SHIFT) - 1;
+}
diff --git a/src/soc/amd/common/block/data_fabric/mmio.c b/src/soc/amd/common/block/data_fabric/mmio.c
new file mode 100644
index 0000000000..f7f31037c7
--- /dev/null
+++ b/src/soc/amd/common/block/data_fabric/mmio.c
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <amdblocks/data_fabric.h>
+#include <device/device.h>
+#include <types.h>
+
+/* Read the registers and return normalized values */
+void data_fabric_get_mmio_base_size(unsigned int reg, resource_t *mmio_base,
+ resource_t *mmio_limit)
+{
+ const uint32_t base_reg = data_fabric_broadcast_read32(DF_MMIO_BASE(reg));
+ const uint32_t limit_reg = data_fabric_broadcast_read32(DF_MMIO_LIMIT(reg));
+ /* The raw register values are bits 47..16 of the actual address */
+ *mmio_base = (resource_t)base_reg << DF_MMIO_SHIFT;
+ *mmio_limit = (((resource_t)limit_reg + 1) << DF_MMIO_SHIFT) - 1;
+}
diff --git a/src/soc/amd/common/block/include/amdblocks/data_fabric.h b/src/soc/amd/common/block/include/amdblocks/data_fabric.h
index 341bad6415..6fdd3f9a27 100644
--- a/src/soc/amd/common/block/include/amdblocks/data_fabric.h
+++ b/src/soc/amd/common/block/include/amdblocks/data_fabric.h
@@ -22,6 +22,9 @@
#define DF_MMIO_BASE(reg) (DF_MMIO_BASE0 + DF_MMIO_REG_OFFSET(reg))
#define DF_MMIO_LIMIT(reg) (DF_MMIO_LIMIT0 + DF_MMIO_REG_OFFSET(reg))
#define DF_MMIO_CONTROL(reg) (DF_MMIO_CTRL0 + DF_MMIO_REG_OFFSET(reg))
+#if CONFIG(SOC_AMD_COMMON_BLOCK_DATA_FABRIC_EXTENDED_MMIO)
+#define DF_MMIO_ADDR_EXT(reg) (DF_MMIO_ADDR_EXT0 + DF_MMIO_REG_OFFSET(reg))
+#endif
/* Last 12GB of the usable address space are reserved */
#define DF_RESERVED_TOP_12GB_MMIO_SIZE (12ULL * GiB)
@@ -51,6 +54,9 @@ void data_fabric_set_mmio_np(void);
enum cb_err data_fabric_get_pci_bus_numbers(struct device *domain, uint8_t *first_bus,
uint8_t *last_bus);
+void data_fabric_get_mmio_base_size(unsigned int reg, resource_t *mmio_base,
+ resource_t *mmio_limit);
+
/* Inform the resource allocator about the usable IO and MMIO regions and PCI bus numbers */
void amd_pci_domain_read_resources(struct device *domain);
void amd_pci_domain_scan_bus(struct device *domain);