blob: 46fc0ca7ecb5e9117ceae0b601d21aeab9a81178 [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 Helddafc6192022-11-10 18:19:36 +0100144 /* GNB IOAPIC resource */
Arthur Heymans61daf9b2023-06-15 09:59:58 +0200145 mmio_range(dev, IOMMU_IOAPIC_IDX, GNB_IO_APIC_ADDR, 0x1000);
Felix Helddafc6192022-11-10 18:19:36 +0100146
Felix Held12a44822023-06-02 15:30:50 +0200147 /* Reserve fixed IOMMU MMIO region */
148 mmio_range(dev, idx++, IOMMU_RESERVED_MMIO_BASE, IOMMU_RESERVED_MMIO_SIZE);
149
Felix Held2e814362022-11-10 22:44:18 +0100150 if (fsp_hob_iterator_init(&hob_iterator) != CB_SUCCESS) {
151 printk(BIOS_ERR, "%s incomplete because no HOB list was found\n", __func__);
Marshall Dawsoneb724872019-07-16 15:46:35 -0600152 return;
153 }
154
Felix Held2e814362022-11-10 22:44:18 +0100155 while (fsp_hob_iterator_get_next_resource(&hob_iterator, &res) == CB_SUCCESS) {
Marshall Dawsoneb724872019-07-16 15:46:35 -0600156 if (res->type == EFI_RESOURCE_SYSTEM_MEMORY && res->addr < mem_usable)
157 continue; /* 0 through low usable was set above */
158 if (res->type == EFI_RESOURCE_MEMORY_MAPPED_IO)
159 continue; /* Done separately */
160
161 if (res->type == EFI_RESOURCE_SYSTEM_MEMORY)
Arthur Heymansb2de1a32023-07-05 12:15:51 +0200162 ram_range(dev, idx++, res->addr, res->length);
Marshall Dawsoneb724872019-07-16 15:46:35 -0600163 else if (res->type == EFI_RESOURCE_MEMORY_RESERVED)
Arthur Heymansb2de1a32023-07-05 12:15:51 +0200164 reserved_ram_range(dev, idx++, res->addr, res->length);
Marshall Dawsoneb724872019-07-16 15:46:35 -0600165 else
Julius Wernere9665952022-01-21 17:06:20 -0800166 printk(BIOS_ERR, "failed to set resources for type %d\n",
Marshall Dawsoneb724872019-07-16 15:46:35 -0600167 res->type);
168 }
169}
170
Felix Heldf9608cd2020-12-03 16:57:02 +0100171static void root_complex_init(struct device *dev)
172{
Kyösti Mälkki2e65e9c2021-06-16 11:00:40 +0300173 register_new_ioapic((u8 *)GNB_IO_APIC_ADDR);
Felix Heldf9608cd2020-12-03 16:57:02 +0100174}
175
Chris Wang4735b1c2020-07-13 23:29:29 +0800176static void acipgen_dptci(void)
177{
Felix Held507fc032020-12-05 01:55:27 +0100178 const struct soc_amd_picasso_config *config = config_of_soc();
Chris Wang4735b1c2020-07-13 23:29:29 +0800179
Tim Van Patten54ce4aa2022-09-13 14:37:32 -0600180 /* Normal mode DPTC values. */
Zheng Bao795d73c2020-10-27 15:36:55 +0800181 struct dptc_input default_input = DPTC_INPUTS(config->thermctl_limit_degreeC,
182 config->sustained_power_limit_mW,
183 config->fast_ppt_limit_mW,
184 config->slow_ppt_limit_mW);
Tim Van Patten92443582022-08-23 16:06:33 -0600185 acpigen_write_alib_dptc_default((uint8_t *)&default_input, sizeof(default_input));
186
187 /* Tablet Mode */
Chris Wang4735b1c2020-07-13 23:29:29 +0800188 struct dptc_input tablet_mode_input = DPTC_INPUTS(
Zheng Bao795d73c2020-10-27 15:36:55 +0800189 config->thermctl_limit_tablet_mode_degreeC,
190 config->sustained_power_limit_tablet_mode_mW,
191 config->fast_ppt_limit_tablet_mode_mW,
192 config->slow_ppt_limit_tablet_mode_mW);
Tim Van Patten92443582022-08-23 16:06:33 -0600193 acpigen_write_alib_dptc_tablet((uint8_t *)&tablet_mode_input,
194 sizeof(tablet_mode_input));
Chris Wang4735b1c2020-07-13 23:29:29 +0800195}
196
Marshall Dawsoneb724872019-07-16 15:46:35 -0600197static void root_complex_fill_ssdt(const struct device *device)
198{
Tim Van Patten54ce4aa2022-09-13 14:37:32 -0600199 if (CONFIG(SOC_AMD_COMMON_BLOCK_ACPI_DPTC))
200 acipgen_dptci();
Marshall Dawsoneb724872019-07-16 15:46:35 -0600201}
202
Felix Heldff092d42021-02-17 00:04:59 +0100203static const char *gnb_acpi_name(const struct device *dev)
204{
205 return "GNB";
206}
207
Arthur Heymans826955d2022-09-20 17:26:30 +0200208struct device_operations picasso_root_complex_operations = {
Marshall Dawsoneb724872019-07-16 15:46:35 -0600209 .read_resources = read_resources,
Felix Held9541d172021-01-05 00:56:10 +0100210 .set_resources = noop_set_resources,
Marshall Dawsoneb724872019-07-16 15:46:35 -0600211 .enable_resources = pci_dev_enable_resources,
Felix Heldf9608cd2020-12-03 16:57:02 +0100212 .init = root_complex_init,
Felix Heldff092d42021-02-17 00:04:59 +0100213 .acpi_name = gnb_acpi_name,
Marshall Dawsoneb724872019-07-16 15:46:35 -0600214 .acpi_fill_ssdt = root_complex_fill_ssdt,
215};
Felix Held43662b52023-07-18 20:36:34 +0200216
217uint32_t get_iohc_misc_smn_base(struct device *domain)
218{
219 return 0x13b10000;
220}
221
222static const struct non_pci_mmio_reg non_pci_mmio[] = {
223 { 0x2e0, 0xfffffff00000ull, 1 * MiB, NON_PCI_RES_IDX_AUTO },
224 { 0x2e8, 0xfffffff00000ull, 1 * MiB, NON_PCI_RES_IDX_AUTO },
225 /* The hardware has a 256 byte alignment requirement for the IOAPIC MMIO base, but we
226 tell the FSP to configure a 4k-aligned base address and this is reported as 4 KiB
227 resource. */
228 { 0x2f0, 0xffffffffff00ull, 4 * KiB, IOMMU_IOAPIC_IDX },
229 { 0x2f8, 0xfffffff00000ull, 1 * MiB, NON_PCI_RES_IDX_AUTO },
230 { 0x300, 0xfffffff00000ull, 1 * MiB, NON_PCI_RES_IDX_AUTO },
231 { 0x308, 0xfffffffff000ull, 4 * KiB, NON_PCI_RES_IDX_AUTO },
232 { 0x318, 0xfffffff80000ull, 512 * KiB, NON_PCI_RES_IDX_AUTO },
233};
234
235const struct non_pci_mmio_reg *get_iohc_non_pci_mmio_regs(size_t *count)
236{
237 *count = ARRAY_SIZE(non_pci_mmio);
238 return non_pci_mmio;
239}