blob: 7ae1df0481fc2a24ad616bd55b38b86741f672a8 [file] [log] [blame]
Marshall Dawsoneb724872019-07-16 15:46:35 -06001/* SPDX-License-Identifier: GPL-2.0-only */
2
3#include <acpi/acpigen.h>
Raul E Rangel58a8ad12021-02-18 16:36:08 -07004#include <amdblocks/acpi.h>
Felix Held95f1bb82021-05-07 18:46:36 +02005#include <amdblocks/alib.h>
Arthur Heymansce179722023-06-07 15:27:18 +02006#include <amdblocks/data_fabric.h>
Raul E Rangel899be1b2021-02-05 15:50:20 -07007#include <amdblocks/memmap.h>
Felix Held604ffa62021-02-12 00:43:20 +01008#include <amdblocks/ioapic.h>
Felix Held12a44822023-06-02 15:30:50 +02009#include <amdblocks/iomap.h>
Felix Held43662b52023-07-18 20:36:34 +020010#include <amdblocks/root_complex.h>
Felix Heldf9608cd2020-12-03 16:57:02 +010011#include <arch/ioapic.h>
Felix Helda4ced632023-06-05 21:22:15 +020012#include <arch/vga.h>
John Zhaof6f1f732020-06-26 10:00:02 -070013#include <assert.h>
Marshall Dawsoneb724872019-07-16 15:46:35 -060014#include <cbmem.h>
15#include <console/console.h>
Marshall Dawsoneb724872019-07-16 15:46:35 -060016#include <device/device.h>
17#include <device/pci.h>
Marshall Dawsoneb724872019-07-16 15:46:35 -060018#include <fsp/util.h>
19#include <stdint.h>
Marshall Dawson39c64b02020-09-04 12:07:27 -060020#include <soc/iomap.h>
Chris Wang4735b1c2020-07-13 23:29:29 +080021#include "chip.h"
Marshall Dawsoneb724872019-07-16 15:46:35 -060022
Felix Heldef511572021-05-07 19:02:45 +020023#define DPTC_TOTAL_UPDATE_PARAMS 4
24
Chris Wang4735b1c2020-07-13 23:29:29 +080025struct dptc_input {
26 uint16_t size;
Felix Heldf0610172021-05-07 19:21:08 +020027 struct alib_dptc_param params[DPTC_TOTAL_UPDATE_PARAMS];
Chris Wang4735b1c2020-07-13 23:29:29 +080028} __packed;
29
Kevin Chiucdd9f5c2020-09-18 17:30:30 +080030#define DPTC_INPUTS(_thermctllmit, _sustained, _fast, _slow) \
Felix Held3acafa22021-05-07 19:17:51 +020031 { \
32 .size = sizeof(struct dptc_input), \
33 .params = { \
34 { \
35 .id = ALIB_DPTC_THERMAL_CONTROL_LIMIT_ID, \
36 .value = _thermctllmit, \
Chris Wang4735b1c2020-07-13 23:29:29 +080037 }, \
Felix Held3acafa22021-05-07 19:17:51 +020038 { \
39 .id = ALIB_DPTC_SUSTAINED_POWER_LIMIT_ID, \
40 .value = _sustained, \
41 }, \
42 { \
43 .id = ALIB_DPTC_FAST_PPT_LIMIT_ID, \
44 .value = _fast, \
45 }, \
46 { \
47 .id = ALIB_DPTC_SLOW_PPT_LIMIT_ID, \
48 .value = _slow, \
49 }, \
50 }, \
51 }
Furquan Shaikhbc456502020-06-10 16:37:23 -070052/*
53 *
54 * +--------------------------------+
55 * | |
56 * | |
57 * | |
58 * | |
59 * | |
60 * | |
61 * | |
62 * reserved_dram_end +--------------------------------+
63 * | |
64 * | verstage (if reqd) |
65 * | (VERSTAGE_SIZE) |
66 * +--------------------------------+ VERSTAGE_ADDR
67 * | |
68 * | FSP-M |
69 * | (FSP_M_SIZE) |
70 * +--------------------------------+ FSP_M_ADDR
Furquan Shaikhbc456502020-06-10 16:37:23 -070071 * | romstage |
72 * | (ROMSTAGE_SIZE) |
Kyösti Mälkkib3621f82020-12-04 19:51:17 +020073 * +--------------------------------+ ROMSTAGE_ADDR = BOOTBLOCK_END
74 * | | X86_RESET_VECTOR = BOOTBLOCK_END - 0x10
Furquan Shaikhbc456502020-06-10 16:37:23 -070075 * | bootblock |
76 * | (C_ENV_BOOTBLOCK_SIZE) |
Kyösti Mälkkib3621f82020-12-04 19:51:17 +020077 * +--------------------------------+ BOOTBLOCK_ADDR = BOOTBLOCK_END - C_ENV_BOOTBLOCK_SIZE
Furquan Shaikhbc456502020-06-10 16:37:23 -070078 * | Unused hole |
79 * | (86KiB) |
80 * +--------------------------------+
81 * | FMAP cache (FMAP_SIZE) |
82 * +--------------------------------+ PSP_SHAREDMEM_BASE + PSP_SHAREDMEM_SIZE + PRERAM_CBMEM_CONSOLE_SIZE + 0x200
83 * | Early Timestamp region (512B) |
84 * +--------------------------------+ PSP_SHAREDMEM_BASE + PSP_SHAREDMEM_SIZE + PRERAM_CBMEM_CONSOLE_SIZE
85 * | Preram CBMEM console |
86 * | (PRERAM_CBMEM_CONSOLE_SIZE) |
87 * +--------------------------------+ PSP_SHAREDMEM_BASE + PSP_SHAREDMEM_SIZE
88 * | PSP shared (vboot workbuf) |
89 * | (PSP_SHAREDMEM_SIZE) |
90 * +--------------------------------+ PSP_SHAREDMEM_BASE
91 * | APOB (64KiB) |
92 * +--------------------------------+ PSP_APOB_DRAM_ADDRESS
93 * | Early BSP stack |
94 * | (EARLYRAM_BSP_STACK_SIZE) |
95 * reserved_dram_start +--------------------------------+ EARLY_RESERVED_DRAM_BASE
96 * | DRAM |
97 * +--------------------------------+ 0x100000
98 * | Option ROM |
99 * +--------------------------------+ 0xc0000
100 * | Legacy VGA |
101 * +--------------------------------+ 0xa0000
102 * | DRAM |
103 * +--------------------------------+ 0x0
104 */
Marshall Dawsoneb724872019-07-16 15:46:35 -0600105static void read_resources(struct device *dev)
106{
107 uint32_t mem_usable = (uintptr_t)cbmem_top();
108 unsigned int idx = 0;
Felix Held2e814362022-11-10 22:44:18 +0100109 const struct hob_header *hob_iterator;
Marshall Dawsoneb724872019-07-16 15:46:35 -0600110 const struct hob_resource *res;
111
Furquan Shaikhbc456502020-06-10 16:37:23 -0700112 uintptr_t early_reserved_dram_start, early_reserved_dram_end;
113 const struct memmap_early_dram *e = memmap_get_early_dram_usage();
114
115 early_reserved_dram_start = e->base;
116 early_reserved_dram_end = e->base + e->size;
117
Felix Heldaf17f0b2022-03-02 23:36:55 +0100118 /* The root complex has no PCI BARs implemented, so there's no need to call
119 pci_dev_read_resources for it */
120
Felix Heldd0959dc2023-05-10 15:07:47 +0200121 fixed_io_range_reserved(dev, idx++, PCI_IO_CONFIG_INDEX, PCI_IO_CONFIG_PORT_COUNT);
122
Marshall Dawsoneb724872019-07-16 15:46:35 -0600123 /* 0x0 - 0x9ffff */
Arthur Heymansb2de1a32023-07-05 12:15:51 +0200124 ram_range(dev, idx++, 0, 0xa0000);
Marshall Dawsoneb724872019-07-16 15:46:35 -0600125
126 /* 0xa0000 - 0xbffff: legacy VGA */
Arthur Heymansb2de1a32023-07-05 12:15:51 +0200127 mmio_range(dev, idx++, VGA_MMIO_BASE, VGA_MMIO_SIZE);
Marshall Dawsoneb724872019-07-16 15:46:35 -0600128
129 /* 0xc0000 - 0xfffff: Option ROM */
Arthur Heymansb2de1a32023-07-05 12:15:51 +0200130 reserved_ram_from_to(dev, idx++, 0xc0000, 1 * MiB);
Marshall Dawsoneb724872019-07-16 15:46:35 -0600131
Furquan Shaikhbc456502020-06-10 16:37:23 -0700132 /* 1MB - bottom of DRAM reserved for early coreboot usage */
Arthur Heymansb2de1a32023-07-05 12:15:51 +0200133 ram_from_to(dev, idx++, 1 * MiB, early_reserved_dram_start);
Furquan Shaikhbc456502020-06-10 16:37:23 -0700134
135 /* DRAM reserved for early coreboot usage */
Arthur Heymansb2de1a32023-07-05 12:15:51 +0200136 reserved_ram_from_to(dev, idx++, early_reserved_dram_start, early_reserved_dram_end);
Furquan Shaikhbc456502020-06-10 16:37:23 -0700137
138 /* top of DRAM consumed early - low top usable RAM
139 * cbmem_top() accounts for low UMA and TSEG if they are used. */
Arthur Heymansb2de1a32023-07-05 12:15:51 +0200140 ram_from_to(dev, idx++, early_reserved_dram_end, mem_usable);
Marshall Dawsoneb724872019-07-16 15:46:35 -0600141
Felix Held56b037b2022-03-02 22:57:01 +0100142 mmconf_resource(dev, idx++);
Marshall Dawsoneb724872019-07-16 15:46:35 -0600143
Felix Held12a44822023-06-02 15:30:50 +0200144 /* Reserve fixed IOMMU MMIO region */
145 mmio_range(dev, idx++, IOMMU_RESERVED_MMIO_BASE, IOMMU_RESERVED_MMIO_SIZE);
146
Felix Held2e814362022-11-10 22:44:18 +0100147 if (fsp_hob_iterator_init(&hob_iterator) != CB_SUCCESS) {
148 printk(BIOS_ERR, "%s incomplete because no HOB list was found\n", __func__);
Marshall Dawsoneb724872019-07-16 15:46:35 -0600149 return;
150 }
151
Felix Held2e814362022-11-10 22:44:18 +0100152 while (fsp_hob_iterator_get_next_resource(&hob_iterator, &res) == CB_SUCCESS) {
Marshall Dawsoneb724872019-07-16 15:46:35 -0600153 if (res->type == EFI_RESOURCE_SYSTEM_MEMORY && res->addr < mem_usable)
154 continue; /* 0 through low usable was set above */
155 if (res->type == EFI_RESOURCE_MEMORY_MAPPED_IO)
156 continue; /* Done separately */
157
158 if (res->type == EFI_RESOURCE_SYSTEM_MEMORY)
Arthur Heymansb2de1a32023-07-05 12:15:51 +0200159 ram_range(dev, idx++, res->addr, res->length);
Marshall Dawsoneb724872019-07-16 15:46:35 -0600160 else if (res->type == EFI_RESOURCE_MEMORY_RESERVED)
Arthur Heymansb2de1a32023-07-05 12:15:51 +0200161 reserved_ram_range(dev, idx++, res->addr, res->length);
Marshall Dawsoneb724872019-07-16 15:46:35 -0600162 else
Julius Wernere9665952022-01-21 17:06:20 -0800163 printk(BIOS_ERR, "failed to set resources for type %d\n",
Marshall Dawsoneb724872019-07-16 15:46:35 -0600164 res->type);
165 }
166}
167
Felix Heldf9608cd2020-12-03 16:57:02 +0100168static void root_complex_init(struct device *dev)
169{
Kyösti Mälkki2e65e9c2021-06-16 11:00:40 +0300170 register_new_ioapic((u8 *)GNB_IO_APIC_ADDR);
Felix Heldf9608cd2020-12-03 16:57:02 +0100171}
172
Chris Wang4735b1c2020-07-13 23:29:29 +0800173static void acipgen_dptci(void)
174{
Felix Held507fc032020-12-05 01:55:27 +0100175 const struct soc_amd_picasso_config *config = config_of_soc();
Chris Wang4735b1c2020-07-13 23:29:29 +0800176
Tim Van Patten54ce4aa2022-09-13 14:37:32 -0600177 /* Normal mode DPTC values. */
Zheng Bao795d73c2020-10-27 15:36:55 +0800178 struct dptc_input default_input = DPTC_INPUTS(config->thermctl_limit_degreeC,
179 config->sustained_power_limit_mW,
180 config->fast_ppt_limit_mW,
181 config->slow_ppt_limit_mW);
Tim Van Patten92443582022-08-23 16:06:33 -0600182 acpigen_write_alib_dptc_default((uint8_t *)&default_input, sizeof(default_input));
183
184 /* Tablet Mode */
Chris Wang4735b1c2020-07-13 23:29:29 +0800185 struct dptc_input tablet_mode_input = DPTC_INPUTS(
Zheng Bao795d73c2020-10-27 15:36:55 +0800186 config->thermctl_limit_tablet_mode_degreeC,
187 config->sustained_power_limit_tablet_mode_mW,
188 config->fast_ppt_limit_tablet_mode_mW,
189 config->slow_ppt_limit_tablet_mode_mW);
Tim Van Patten92443582022-08-23 16:06:33 -0600190 acpigen_write_alib_dptc_tablet((uint8_t *)&tablet_mode_input,
191 sizeof(tablet_mode_input));
Chris Wang4735b1c2020-07-13 23:29:29 +0800192}
193
Marshall Dawsoneb724872019-07-16 15:46:35 -0600194static void root_complex_fill_ssdt(const struct device *device)
195{
Tim Van Patten54ce4aa2022-09-13 14:37:32 -0600196 if (CONFIG(SOC_AMD_COMMON_BLOCK_ACPI_DPTC))
197 acipgen_dptci();
Marshall Dawsoneb724872019-07-16 15:46:35 -0600198}
199
Felix Heldff092d42021-02-17 00:04:59 +0100200static const char *gnb_acpi_name(const struct device *dev)
201{
202 return "GNB";
203}
204
Arthur Heymans826955d2022-09-20 17:26:30 +0200205struct device_operations picasso_root_complex_operations = {
Marshall Dawsoneb724872019-07-16 15:46:35 -0600206 .read_resources = read_resources,
Felix Held9541d172021-01-05 00:56:10 +0100207 .set_resources = noop_set_resources,
Marshall Dawsoneb724872019-07-16 15:46:35 -0600208 .enable_resources = pci_dev_enable_resources,
Felix Heldf9608cd2020-12-03 16:57:02 +0100209 .init = root_complex_init,
Felix Heldff092d42021-02-17 00:04:59 +0100210 .acpi_name = gnb_acpi_name,
Marshall Dawsoneb724872019-07-16 15:46:35 -0600211 .acpi_fill_ssdt = root_complex_fill_ssdt,
212};
Felix Held43662b52023-07-18 20:36:34 +0200213
214uint32_t get_iohc_misc_smn_base(struct device *domain)
215{
Felix Held69ffebf2023-07-24 21:31:44 +0200216 return SMN_IOHC_MISC_BASE_13B1;
Felix Held43662b52023-07-18 20:36:34 +0200217}
218
219static const struct non_pci_mmio_reg non_pci_mmio[] = {
220 { 0x2e0, 0xfffffff00000ull, 1 * MiB, NON_PCI_RES_IDX_AUTO },
221 { 0x2e8, 0xfffffff00000ull, 1 * MiB, NON_PCI_RES_IDX_AUTO },
222 /* The hardware has a 256 byte alignment requirement for the IOAPIC MMIO base, but we
223 tell the FSP to configure a 4k-aligned base address and this is reported as 4 KiB
224 resource. */
225 { 0x2f0, 0xffffffffff00ull, 4 * KiB, IOMMU_IOAPIC_IDX },
226 { 0x2f8, 0xfffffff00000ull, 1 * MiB, NON_PCI_RES_IDX_AUTO },
227 { 0x300, 0xfffffff00000ull, 1 * MiB, NON_PCI_RES_IDX_AUTO },
228 { 0x308, 0xfffffffff000ull, 4 * KiB, NON_PCI_RES_IDX_AUTO },
229 { 0x318, 0xfffffff80000ull, 512 * KiB, NON_PCI_RES_IDX_AUTO },
230};
231
232const struct non_pci_mmio_reg *get_iohc_non_pci_mmio_regs(size_t *count)
233{
234 *count = ARRAY_SIZE(non_pci_mmio);
235 return non_pci_mmio;
236}