summaryrefslogtreecommitdiff
path: root/src/soc/amd/morgana/root_complex.c
diff options
context:
space:
mode:
authorMartin Roth <martin.roth@amd.corp-partner.google.com>2022-10-06 15:57:21 -0600
committerMartin Roth <martin.roth@amd.corp-partner.google.com>2022-10-10 21:48:30 +0000
commit1a3de8e5bcc5c83934fa2a690e125b843e8b01ab (patch)
tree0df3332114bde60848c018a9b5de245a9568ba4a /src/soc/amd/morgana/root_complex.c
parent134908381f2b25063558f2ce1414fa70243c9c55 (diff)
soc/amd/morgana: Add initial commit for new SoC
This is an initial framework for the Morgana SoC. TODOs have been added to the files for both customization and commonization. Signed-off-by: Martin Roth <martin.roth@amd.corp-partner.google.com> Change-Id: If92e129db10d41595e1dc18a7c1dfe99d57790cc Reviewed-on: https://review.coreboot.org/c/coreboot/+/68195 Reviewed-by: Fred Reitberger <reitbergerfred@gmail.com> Reviewed-by: Marshall Dawson <marshalldawson3rd@gmail.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'src/soc/amd/morgana/root_complex.c')
-rw-r--r--src/soc/amd/morgana/root_complex.c252
1 files changed, 252 insertions, 0 deletions
diff --git a/src/soc/amd/morgana/root_complex.c b/src/soc/amd/morgana/root_complex.c
new file mode 100644
index 0000000000..5dd5d79579
--- /dev/null
+++ b/src/soc/amd/morgana/root_complex.c
@@ -0,0 +1,252 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+/* TODO: Update for Morgana */
+
+#include <acpi/acpigen.h>
+#include <amdblocks/acpi.h>
+#include <amdblocks/alib.h>
+#include <amdblocks/ioapic.h>
+#include <amdblocks/memmap.h>
+#include <arch/ioapic.h>
+#include <cbmem.h>
+#include <console/console.h>
+#include <cpu/amd/msr.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <fsp/util.h>
+#include <soc/iomap.h>
+#include <stdint.h>
+#include "chip.h"
+
+#define DPTC_TOTAL_UPDATE_PARAMS 7
+
+struct dptc_input {
+ uint16_t size;
+ struct alib_dptc_param params[DPTC_TOTAL_UPDATE_PARAMS];
+} __packed;
+
+#define DPTC_INPUTS(_thermctllmit, _sustained, _fast, _slow, \
+ _vrmCurrentLimit, _vrmMaxCurrentLimit, _vrmSocCurrentLimit) \
+ { \
+ .size = sizeof(struct dptc_input), \
+ .params = { \
+ { \
+ .id = ALIB_DPTC_THERMAL_CONTROL_LIMIT_ID, \
+ .value = _thermctllmit, \
+ }, \
+ { \
+ .id = ALIB_DPTC_SUSTAINED_POWER_LIMIT_ID, \
+ .value = _sustained, \
+ }, \
+ { \
+ .id = ALIB_DPTC_FAST_PPT_LIMIT_ID, \
+ .value = _fast, \
+ }, \
+ { \
+ .id = ALIB_DPTC_SLOW_PPT_LIMIT_ID, \
+ .value = _slow, \
+ }, \
+ { \
+ .id = ALIB_DPTC_VRM_CURRENT_LIMIT_ID, \
+ .value = _vrmCurrentLimit, \
+ }, \
+ { \
+ .id = ALIB_DPTC_VRM_MAXIMUM_CURRENT_LIMIT, \
+ .value = _vrmMaxCurrentLimit, \
+ }, \
+ { \
+ .id = ALIB_DPTC_VRM_SOC_CURRENT_LIMIT_ID, \
+ .value = _vrmSocCurrentLimit, \
+ }, \
+ }, \
+ }
+
+/*
+ *
+ * +--------------------------------+
+ * | |
+ * | |
+ * | |
+ * | |
+ * | |
+ * | |
+ * | |
+ * reserved_dram_end +--------------------------------+
+ * | |
+ * | verstage (if reqd) |
+ * | (VERSTAGE_SIZE) |
+ * +--------------------------------+ VERSTAGE_ADDR
+ * | |
+ * | FSP-M |
+ * | (FSP_M_SIZE) |
+ * +--------------------------------+ FSP_M_ADDR
+ * | romstage |
+ * | (ROMSTAGE_SIZE) |
+ * +--------------------------------+ ROMSTAGE_ADDR = BOOTBLOCK_END
+ * | | X86_RESET_VECTOR = BOOTBLOCK_END - 0x10
+ * | bootblock |
+ * | (C_ENV_BOOTBLOCK_SIZE) |
+ * +--------------------------------+ BOOTBLOCK_ADDR = BOOTBLOCK_END - C_ENV_BOOTBLOCK_SIZE
+ * | Unused hole |
+ * | (30KiB) |
+ * +--------------------------------+
+ * | FMAP cache (FMAP_SIZE) |
+ * +--------------------------------+ PSP_SHAREDMEM_BASE + PSP_SHAREDMEM_SIZE + PRERAM_CBMEM_CONSOLE_SIZE + 0x200
+ * | Early Timestamp region (512B) |
+ * +--------------------------------+ PSP_SHAREDMEM_BASE + PSP_SHAREDMEM_SIZE + PRERAM_CBMEM_CONSOLE_SIZE
+ * | Preram CBMEM console |
+ * | (PRERAM_CBMEM_CONSOLE_SIZE) |
+ * +--------------------------------+ PSP_SHAREDMEM_BASE + PSP_SHAREDMEM_SIZE
+ * | PSP shared (vboot workbuf) |
+ * | (PSP_SHAREDMEM_SIZE) |
+ * +--------------------------------+ PSP_SHAREDMEM_BASE
+ * | APOB (120KiB) |
+ * +--------------------------------+ PSP_APOB_DRAM_ADDRESS
+ * | Early BSP stack |
+ * | (EARLYRAM_BSP_STACK_SIZE) |
+ * reserved_dram_start +--------------------------------+ EARLY_RESERVED_DRAM_BASE
+ * | DRAM |
+ * +--------------------------------+ 0x100000
+ * | Option ROM |
+ * +--------------------------------+ 0xc0000
+ * | Legacy VGA |
+ * +--------------------------------+ 0xa0000
+ * | DRAM |
+ * +--------------------------------+ 0x0
+ */
+static void read_resources(struct device *dev)
+{
+ uint32_t mem_usable = (uintptr_t)cbmem_top();
+ unsigned int idx = 0;
+ const struct hob_header *hob = fsp_get_hob_list();
+ const struct hob_resource *res;
+ struct resource *gnb_apic;
+
+ uintptr_t early_reserved_dram_start, early_reserved_dram_end;
+ const struct memmap_early_dram *e = memmap_get_early_dram_usage();
+
+ early_reserved_dram_start = e->base;
+ early_reserved_dram_end = e->base + e->size;
+
+ /* The root complex has no PCI BARs implemented, so there's no need to call
+ pci_dev_read_resources for it */
+
+ /* 0x0 - 0x9ffff */
+ ram_resource_kb(dev, idx++, 0, 0xa0000 / KiB);
+
+ /* 0xa0000 - 0xbffff: legacy VGA */
+ mmio_resource_kb(dev, idx++, 0xa0000 / KiB, 0x20000 / KiB);
+
+ /* 0xc0000 - 0xfffff: Option ROM */
+ reserved_ram_resource_kb(dev, idx++, 0xc0000 / KiB, 0x40000 / KiB);
+
+ /* 1MiB - bottom of DRAM reserved for early coreboot usage */
+ ram_resource_kb(dev, idx++, (1 * MiB) / KiB,
+ (early_reserved_dram_start - (1 * MiB)) / KiB);
+
+ /* DRAM reserved for early coreboot usage */
+ reserved_ram_resource_kb(dev, idx++, early_reserved_dram_start / KiB,
+ (early_reserved_dram_end - early_reserved_dram_start) / KiB);
+
+ /*
+ * top of DRAM consumed early - low top usable RAM
+ * cbmem_top() accounts for low UMA and TSEG if they are used.
+ */
+ ram_resource_kb(dev, idx++, early_reserved_dram_end / KiB,
+ (mem_usable - early_reserved_dram_end) / KiB);
+
+ mmconf_resource(dev, idx++);
+
+ if (!hob) {
+ printk(BIOS_ERR, "Error: %s incomplete because no HOB list was found\n",
+ __func__);
+ return;
+ }
+
+ for (; hob->type != HOB_TYPE_END_OF_HOB_LIST; hob = fsp_next_hob(hob)) {
+
+ if (hob->type != HOB_TYPE_RESOURCE_DESCRIPTOR)
+ continue;
+
+ res = fsp_hob_header_to_resource(hob);
+
+ if (res->type == EFI_RESOURCE_SYSTEM_MEMORY && res->addr < mem_usable)
+ continue; /* 0 through low usable was set above */
+ if (res->type == EFI_RESOURCE_MEMORY_MAPPED_IO)
+ continue; /* Done separately */
+
+ if (res->type == EFI_RESOURCE_SYSTEM_MEMORY)
+ ram_resource_kb(dev, idx++, res->addr / KiB, res->length / KiB);
+ else if (res->type == EFI_RESOURCE_MEMORY_RESERVED)
+ reserved_ram_resource_kb(dev, idx++, res->addr / KiB, res->length / KiB);
+ else
+ printk(BIOS_ERR, "Error: failed to set resources for type %d\n",
+ res->type);
+ }
+
+ /* GNB IOAPIC resource */
+ gnb_apic = new_resource(dev, idx++);
+ gnb_apic->base = GNB_IO_APIC_ADDR;
+ gnb_apic->size = 0x00001000;
+ gnb_apic->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+}
+
+static void root_complex_init(struct device *dev)
+{
+ setup_ioapic((u8 *)GNB_IO_APIC_ADDR, GNB_IOAPIC_ID);
+}
+
+static void acipgen_dptci(void)
+{
+ const struct soc_amd_morgana_config *config = config_of_soc();
+
+ /* Normal mode DPTC values. */
+ struct dptc_input default_input = DPTC_INPUTS(config->thermctl_limit_degreeC,
+ config->sustained_power_limit_mW,
+ config->fast_ppt_limit_mW,
+ config->slow_ppt_limit_mW,
+ config->vrm_current_limit_mA,
+ config->vrm_maximum_current_limit_mA,
+ config->vrm_soc_current_limit_mA);
+ acpigen_write_alib_dptc_default((uint8_t *)&default_input, sizeof(default_input));
+
+ /* Low/No Battery */
+ struct dptc_input no_battery_input = DPTC_INPUTS(
+ config->thermctl_limit_degreeC,
+ config->sustained_power_limit_mW,
+ config->fast_ppt_limit_mW,
+ config->slow_ppt_limit_mW,
+ config->vrm_current_limit_throttle_mA,
+ config->vrm_maximum_current_limit_throttle_mA,
+ config->vrm_soc_current_limit_throttle_mA);
+ acpigen_write_alib_dptc_no_battery((uint8_t *)&no_battery_input,
+ sizeof(no_battery_input));
+}
+
+static void root_complex_fill_ssdt(const struct device *device)
+{
+ acpi_fill_root_complex_tom(device);
+ if (CONFIG(SOC_AMD_COMMON_BLOCK_ACPI_DPTC))
+ acipgen_dptci();
+}
+
+static const char *gnb_acpi_name(const struct device *dev)
+{
+ return "GNB";
+}
+
+static struct device_operations root_complex_operations = {
+ .read_resources = read_resources,
+ .set_resources = noop_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = root_complex_init,
+ .acpi_name = gnb_acpi_name,
+ .acpi_fill_ssdt = root_complex_fill_ssdt,
+};
+
+static const struct pci_driver family17_root_complex __pci_driver = {
+ .ops = &root_complex_operations,
+ .vendor = PCI_VID_AMD,
+ .device = PCI_DID_AMD_17H_MODEL_A0AF_NB, /* TODO: Update for Morgana */
+};