blob: 5e1e11a431e03b48a8dd584adb94d5acbd2c6727 [file] [log] [blame]
Felix Held3c44c622022-01-10 20:57:29 +01001/* SPDX-License-Identifier: GPL-2.0-only */
2
3/* TODO: Check if this is still correct */
4
5#include <acpi/acpigen.h>
6#include <amdblocks/acpi.h>
7#include <amdblocks/alib.h>
Arthur Heymansce179722023-06-07 15:27:18 +02008#include <amdblocks/data_fabric.h>
Felix Held3c44c622022-01-10 20:57:29 +01009#include <amdblocks/ioapic.h>
Felix Held12a44822023-06-02 15:30:50 +020010#include <amdblocks/iomap.h>
Felix Held3c44c622022-01-10 20:57:29 +010011#include <amdblocks/memmap.h>
12#include <arch/ioapic.h>
Felix Helda4ced632023-06-05 21:22:15 +020013#include <arch/vga.h>
Felix Held3c44c622022-01-10 20:57:29 +010014#include <cbmem.h>
15#include <console/console.h>
Felix Held3c44c622022-01-10 20:57:29 +010016#include <device/device.h>
17#include <device/pci.h>
Tim Van Pattenf5ae1dd2023-03-31 17:31:10 -060018#include <fsp/amd_misc_data.h>
Felix Held3c44c622022-01-10 20:57:29 +010019#include <fsp/util.h>
20#include <soc/iomap.h>
21#include <stdint.h>
22#include "chip.h"
23
Tim Van Pattenf5ae1dd2023-03-31 17:31:10 -060024#define TDP_15W 15
Chris Wang50aa3d92023-02-20 10:27:50 +080025#define DPTC_TOTAL_UPDATE_PARAMS 13
Felix Held3c44c622022-01-10 20:57:29 +010026
27struct dptc_input {
28 uint16_t size;
29 struct alib_dptc_param params[DPTC_TOTAL_UPDATE_PARAMS];
30} __packed;
31
EricKY Cheng33e0df12022-10-21 19:35:30 +080032
Chris Wang50aa3d92023-02-20 10:27:50 +080033#define DPTC_INPUTS(_thermctllmit, _spptTimeConst, _fast, _slow, \
34 _vrmCurrentLimit, _vrmMaxCurrentLimit, _vrmSocCurrentLimit, \
Chris Wangeede5a22023-02-20 09:43:38 +080035 _sttMinLimit, _sttM1, _sttM2, _sttCApu, _sttAlphaApu, _sttSkinTempLimitApu) \
Felix Held3c44c622022-01-10 20:57:29 +010036 { \
37 .size = sizeof(struct dptc_input), \
38 .params = { \
39 { \
40 .id = ALIB_DPTC_THERMAL_CONTROL_LIMIT_ID, \
41 .value = _thermctllmit, \
42 }, \
43 { \
EricKY Cheng33e0df12022-10-21 19:35:30 +080044 .id = ALIB_DPTC_SLOW_PPT_TIME_CONSTANT_ID, \
45 .value = _spptTimeConst, \
46 }, \
47 { \
Felix Held3c44c622022-01-10 20:57:29 +010048 .id = ALIB_DPTC_FAST_PPT_LIMIT_ID, \
49 .value = _fast, \
50 }, \
51 { \
52 .id = ALIB_DPTC_SLOW_PPT_LIMIT_ID, \
53 .value = _slow, \
54 }, \
Tim Van Patten11ca9952022-09-15 17:08:29 -060055 { \
56 .id = ALIB_DPTC_VRM_CURRENT_LIMIT_ID, \
57 .value = _vrmCurrentLimit, \
58 }, \
59 { \
60 .id = ALIB_DPTC_VRM_MAXIMUM_CURRENT_LIMIT, \
61 .value = _vrmMaxCurrentLimit, \
62 }, \
63 { \
64 .id = ALIB_DPTC_VRM_SOC_CURRENT_LIMIT_ID, \
65 .value = _vrmSocCurrentLimit, \
66 }, \
EricKY Cheng33e0df12022-10-21 19:35:30 +080067 { \
68 .id = ALIB_DPTC_STT_MIN_LIMIT_ID, \
69 .value = _sttMinLimit, \
70 }, \
71 { \
72 .id = ALIB_DPTC_STT_M1_ID, \
73 .value = _sttM1, \
74 }, \
75 { \
76 .id = ALIB_DPTC_STT_M2_ID, \
77 .value = _sttM2, \
78 }, \
79 { \
80 .id = ALIB_DPTC_STT_C_APU_ID, \
81 .value = _sttCApu, \
82 }, \
83 { \
Chris Wangeede5a22023-02-20 09:43:38 +080084 .id = ALIB_DPTC_STT_ALPHA_APU, \
85 .value = _sttAlphaApu, \
86 }, \
87 { \
EricKY Cheng33e0df12022-10-21 19:35:30 +080088 .id = ALIB_DPTC_STT_SKIN_TEMPERATURE_LIMIT_APU_ID, \
89 .value = _sttSkinTempLimitApu, \
90 }, \
Felix Held3c44c622022-01-10 20:57:29 +010091 }, \
92 }
93
94/*
95 *
96 * +--------------------------------+
97 * | |
98 * | |
99 * | |
100 * | |
101 * | |
102 * | |
103 * | |
104 * reserved_dram_end +--------------------------------+
105 * | |
106 * | verstage (if reqd) |
107 * | (VERSTAGE_SIZE) |
108 * +--------------------------------+ VERSTAGE_ADDR
109 * | |
110 * | FSP-M |
111 * | (FSP_M_SIZE) |
112 * +--------------------------------+ FSP_M_ADDR
113 * | romstage |
114 * | (ROMSTAGE_SIZE) |
115 * +--------------------------------+ ROMSTAGE_ADDR = BOOTBLOCK_END
116 * | | X86_RESET_VECTOR = BOOTBLOCK_END - 0x10
117 * | bootblock |
118 * | (C_ENV_BOOTBLOCK_SIZE) |
119 * +--------------------------------+ BOOTBLOCK_ADDR = BOOTBLOCK_END - C_ENV_BOOTBLOCK_SIZE
120 * | Unused hole |
Fred Reitbergerfdb07582022-07-15 08:05:56 -0400121 * | (30KiB) |
Felix Held3c44c622022-01-10 20:57:29 +0100122 * +--------------------------------+
123 * | FMAP cache (FMAP_SIZE) |
124 * +--------------------------------+ PSP_SHAREDMEM_BASE + PSP_SHAREDMEM_SIZE + PRERAM_CBMEM_CONSOLE_SIZE + 0x200
125 * | Early Timestamp region (512B) |
126 * +--------------------------------+ PSP_SHAREDMEM_BASE + PSP_SHAREDMEM_SIZE + PRERAM_CBMEM_CONSOLE_SIZE
127 * | Preram CBMEM console |
128 * | (PRERAM_CBMEM_CONSOLE_SIZE) |
129 * +--------------------------------+ PSP_SHAREDMEM_BASE + PSP_SHAREDMEM_SIZE
130 * | PSP shared (vboot workbuf) |
131 * | (PSP_SHAREDMEM_SIZE) |
132 * +--------------------------------+ PSP_SHAREDMEM_BASE
Fred Reitbergerfdb07582022-07-15 08:05:56 -0400133 * | APOB (120KiB) |
Felix Held3c44c622022-01-10 20:57:29 +0100134 * +--------------------------------+ PSP_APOB_DRAM_ADDRESS
135 * | Early BSP stack |
136 * | (EARLYRAM_BSP_STACK_SIZE) |
137 * reserved_dram_start +--------------------------------+ EARLY_RESERVED_DRAM_BASE
138 * | DRAM |
139 * +--------------------------------+ 0x100000
140 * | Option ROM |
141 * +--------------------------------+ 0xc0000
142 * | Legacy VGA |
143 * +--------------------------------+ 0xa0000
144 * | DRAM |
145 * +--------------------------------+ 0x0
146 */
147static void read_resources(struct device *dev)
148{
149 uint32_t mem_usable = (uintptr_t)cbmem_top();
150 unsigned int idx = 0;
Felix Held2e814362022-11-10 22:44:18 +0100151 const struct hob_header *hob_iterator;
Felix Held3c44c622022-01-10 20:57:29 +0100152 const struct hob_resource *res;
Felix Held3c44c622022-01-10 20:57:29 +0100153
154 uintptr_t early_reserved_dram_start, early_reserved_dram_end;
155 const struct memmap_early_dram *e = memmap_get_early_dram_usage();
156
157 early_reserved_dram_start = e->base;
158 early_reserved_dram_end = e->base + e->size;
159
Felix Heldaf17f0b2022-03-02 23:36:55 +0100160 /* The root complex has no PCI BARs implemented, so there's no need to call
161 pci_dev_read_resources for it */
162
Felix Heldd0959dc2023-05-10 15:07:47 +0200163 fixed_io_range_reserved(dev, idx++, PCI_IO_CONFIG_INDEX, PCI_IO_CONFIG_PORT_COUNT);
164
Felix Held3c44c622022-01-10 20:57:29 +0100165 /* 0x0 - 0x9ffff */
Kyösti Mälkki27d62992022-05-24 20:25:58 +0300166 ram_resource_kb(dev, idx++, 0, 0xa0000 / KiB);
Felix Held3c44c622022-01-10 20:57:29 +0100167
168 /* 0xa0000 - 0xbffff: legacy VGA */
Felix Helda4ced632023-06-05 21:22:15 +0200169 mmio_resource_kb(dev, idx++, VGA_MMIO_BASE / KiB, VGA_MMIO_SIZE / KiB);
Felix Held3c44c622022-01-10 20:57:29 +0100170
171 /* 0xc0000 - 0xfffff: Option ROM */
Kyösti Mälkki27d62992022-05-24 20:25:58 +0300172 reserved_ram_resource_kb(dev, idx++, 0xc0000 / KiB, 0x40000 / KiB);
Felix Held3c44c622022-01-10 20:57:29 +0100173
174 /* 1MiB - bottom of DRAM reserved for early coreboot usage */
Kyösti Mälkki27d62992022-05-24 20:25:58 +0300175 ram_resource_kb(dev, idx++, (1 * MiB) / KiB,
Felix Held3c44c622022-01-10 20:57:29 +0100176 (early_reserved_dram_start - (1 * MiB)) / KiB);
177
178 /* DRAM reserved for early coreboot usage */
Kyösti Mälkki27d62992022-05-24 20:25:58 +0300179 reserved_ram_resource_kb(dev, idx++, early_reserved_dram_start / KiB,
Felix Held3c44c622022-01-10 20:57:29 +0100180 (early_reserved_dram_end - early_reserved_dram_start) / KiB);
181
182 /*
183 * top of DRAM consumed early - low top usable RAM
184 * cbmem_top() accounts for low UMA and TSEG if they are used.
185 */
Kyösti Mälkki27d62992022-05-24 20:25:58 +0300186 ram_resource_kb(dev, idx++, early_reserved_dram_end / KiB,
Felix Held3c44c622022-01-10 20:57:29 +0100187 (mem_usable - early_reserved_dram_end) / KiB);
188
Felix Held56b037b2022-03-02 22:57:01 +0100189 mmconf_resource(dev, idx++);
Felix Held3c44c622022-01-10 20:57:29 +0100190
Felix Helddafc6192022-11-10 18:19:36 +0100191 /* GNB IOAPIC resource */
Arthur Heymans61daf9b2023-06-15 09:59:58 +0200192 mmio_range(dev, IOMMU_IOAPIC_IDX, GNB_IO_APIC_ADDR, 0x1000);
Felix Helddafc6192022-11-10 18:19:36 +0100193
Felix Held12a44822023-06-02 15:30:50 +0200194 /* Reserve fixed IOMMU MMIO region */
195 mmio_range(dev, idx++, IOMMU_RESERVED_MMIO_BASE, IOMMU_RESERVED_MMIO_SIZE);
196
Felix Held2e814362022-11-10 22:44:18 +0100197 if (fsp_hob_iterator_init(&hob_iterator) != CB_SUCCESS) {
Elyes Haouasaba1c942022-11-09 15:05:23 +0100198 printk(BIOS_ERR, "%s incomplete because no HOB list was found\n",
Felix Held3c44c622022-01-10 20:57:29 +0100199 __func__);
200 return;
201 }
202
Felix Held2e814362022-11-10 22:44:18 +0100203 while (fsp_hob_iterator_get_next_resource(&hob_iterator, &res) == CB_SUCCESS) {
Felix Held3c44c622022-01-10 20:57:29 +0100204 if (res->type == EFI_RESOURCE_SYSTEM_MEMORY && res->addr < mem_usable)
205 continue; /* 0 through low usable was set above */
206 if (res->type == EFI_RESOURCE_MEMORY_MAPPED_IO)
207 continue; /* Done separately */
208
209 if (res->type == EFI_RESOURCE_SYSTEM_MEMORY)
Kyösti Mälkki27d62992022-05-24 20:25:58 +0300210 ram_resource_kb(dev, idx++, res->addr / KiB, res->length / KiB);
Felix Held3c44c622022-01-10 20:57:29 +0100211 else if (res->type == EFI_RESOURCE_MEMORY_RESERVED)
Kyösti Mälkki27d62992022-05-24 20:25:58 +0300212 reserved_ram_resource_kb(dev, idx++, res->addr / KiB, res->length / KiB);
Felix Held3c44c622022-01-10 20:57:29 +0100213 else
Elyes Haouasaba1c942022-11-09 15:05:23 +0100214 printk(BIOS_ERR, "Failed to set resources for type %d\n",
Felix Held3c44c622022-01-10 20:57:29 +0100215 res->type);
216 }
Felix Held3c44c622022-01-10 20:57:29 +0100217}
218
219static void root_complex_init(struct device *dev)
220{
Kyösti Mälkki2e65e9c2021-06-16 11:00:40 +0300221 register_new_ioapic((u8 *)GNB_IO_APIC_ADDR);
Felix Held3c44c622022-01-10 20:57:29 +0100222}
223
224static void acipgen_dptci(void)
225{
Jon Murphy4f732422022-08-05 15:43:44 -0600226 const struct soc_amd_mendocino_config *config = config_of_soc();
Felix Held3c44c622022-01-10 20:57:29 +0100227
Tim Van Patten53ba14d2022-09-13 15:42:01 -0600228 /* Normal mode DPTC values. */
EricKY Cheng33e0df12022-10-21 19:35:30 +0800229 struct dptc_input default_input = DPTC_INPUTS(
230 config->thermctl_limit_degreeC,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800231 config->slow_ppt_time_constant_s,
Tim Van Patten92443582022-08-23 16:06:33 -0600232 config->fast_ppt_limit_mW,
Tim Van Patten11ca9952022-09-15 17:08:29 -0600233 config->slow_ppt_limit_mW,
234 config->vrm_current_limit_mA,
235 config->vrm_maximum_current_limit_mA,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800236 config->vrm_soc_current_limit_mA,
237 config->stt_min_limit,
238 config->stt_m1,
239 config->stt_m2,
240 config->stt_c_apu,
Chris Wangeede5a22023-02-20 09:43:38 +0800241 config->stt_alpha_apu,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800242 config->stt_skin_temp_apu);
Tim Van Patten92443582022-08-23 16:06:33 -0600243 acpigen_write_alib_dptc_default((uint8_t *)&default_input, sizeof(default_input));
Tim Van Patten1075fef2022-05-20 11:06:03 -0600244
245 /* Low/No Battery */
246 struct dptc_input no_battery_input = DPTC_INPUTS(
247 config->thermctl_limit_degreeC,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800248 config->slow_ppt_time_constant_s,
Tim Van Patten1075fef2022-05-20 11:06:03 -0600249 config->fast_ppt_limit_mW,
250 config->slow_ppt_limit_mW,
251 config->vrm_current_limit_throttle_mA,
252 config->vrm_maximum_current_limit_throttle_mA,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800253 config->vrm_soc_current_limit_throttle_mA,
254 config->stt_min_limit,
255 config->stt_m1,
256 config->stt_m2,
257 config->stt_c_apu,
Chris Wangeede5a22023-02-20 09:43:38 +0800258 config->stt_alpha_apu,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800259 config->stt_skin_temp_apu);
Tim Van Patten1075fef2022-05-20 11:06:03 -0600260 acpigen_write_alib_dptc_no_battery((uint8_t *)&no_battery_input,
261 sizeof(no_battery_input));
EricKY Cheng33e0df12022-10-21 19:35:30 +0800262
Chris.Wang9ac09842022-12-13 14:31:38 +0800263#if (CONFIG(FEATURE_TABLET_MODE_DPTC))
264 struct dptc_input tablet_input = DPTC_INPUTS(
265 config->thermctl_limit_degreeC,
Chris.Wang9ac09842022-12-13 14:31:38 +0800266 config->slow_ppt_time_constant_s,
267 config->fast_ppt_limit_mW,
268 config->slow_ppt_limit_mW,
269 config->vrm_current_limit_mA,
270 config->vrm_maximum_current_limit_mA,
271 config->vrm_soc_current_limit_mA,
272 config->stt_min_limit,
Chris Wang28095072023-02-23 16:25:52 +0800273 config->stt_m1_tablet,
274 config->stt_m2_tablet,
275 config->stt_c_apu_tablet,
276 config->stt_alpha_apu_tablet,
Chris.Wang9ac09842022-12-13 14:31:38 +0800277 config->stt_skin_temp_apu);
278 acpigen_write_alib_dptc_tablet((uint8_t *)&tablet_input, sizeof(tablet_input));
279#endif
280
EricKY Cheng33e0df12022-10-21 19:35:30 +0800281#if (CONFIG(FEATURE_DYNAMIC_DPTC))
282 /* Profile B */
283 struct dptc_input thermal_B_input = DPTC_INPUTS(
284 config->thermctl_limit_degreeC,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800285 config->slow_ppt_time_constant_s_B,
286 config->fast_ppt_limit_mW_B,
287 config->slow_ppt_limit_mW_B,
288 config->vrm_current_limit_throttle_mA,
289 config->vrm_maximum_current_limit_mA,
290 config->vrm_soc_current_limit_mA,
291 config->stt_min_limit_B,
292 config->stt_m1_B,
293 config->stt_m2_B,
294 config->stt_c_apu_B,
Chris Wangeede5a22023-02-20 09:43:38 +0800295 config->stt_alpha_apu,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800296 config->stt_skin_temp_apu_B);
297 acpigen_write_alib_dptc_thermal_B((uint8_t *)&thermal_B_input,
298 sizeof(thermal_B_input));
299
300 /* Profile C */
301 struct dptc_input thermal_C_input = DPTC_INPUTS(
302 config->thermctl_limit_degreeC,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800303 config->slow_ppt_time_constant_s_C,
304 config->fast_ppt_limit_mW_C,
305 config->slow_ppt_limit_mW_C,
306 config->vrm_current_limit_mA,
307 config->vrm_maximum_current_limit_mA,
308 config->vrm_soc_current_limit_mA,
309 config->stt_min_limit_C,
310 config->stt_m1_C,
311 config->stt_m2_C,
312 config->stt_c_apu_C,
Chris Wangeede5a22023-02-20 09:43:38 +0800313 config->stt_alpha_apu,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800314 config->stt_skin_temp_apu_C);
315 acpigen_write_alib_dptc_thermal_C((uint8_t *)&thermal_C_input,
316 sizeof(thermal_C_input));
317
318 /* Profile D */
319 struct dptc_input thermal_D_input = DPTC_INPUTS(
320 config->thermctl_limit_degreeC,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800321 config->slow_ppt_time_constant_s_D,
322 config->fast_ppt_limit_mW_D,
323 config->slow_ppt_limit_mW_D,
324 config->vrm_current_limit_mA,
325 config->vrm_maximum_current_limit_mA,
326 config->vrm_soc_current_limit_mA,
327 config->stt_min_limit_D,
328 config->stt_m1_D,
329 config->stt_m2_D,
330 config->stt_c_apu_D,
Chris Wangeede5a22023-02-20 09:43:38 +0800331 config->stt_alpha_apu,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800332 config->stt_skin_temp_apu_D);
333 acpigen_write_alib_dptc_thermal_D((uint8_t *)&thermal_D_input,
334 sizeof(thermal_D_input));
335
336 /* Profile E */
337 struct dptc_input thermal_E_input = DPTC_INPUTS(
338 config->thermctl_limit_degreeC,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800339 config->slow_ppt_time_constant_s_E,
340 config->fast_ppt_limit_mW_E,
341 config->slow_ppt_limit_mW_E,
342 config->vrm_current_limit_mA,
343 config->vrm_maximum_current_limit_mA,
344 config->vrm_soc_current_limit_mA,
345 config->stt_min_limit_E,
346 config->stt_m1_E,
347 config->stt_m2_E,
348 config->stt_c_apu_E,
Chris Wangeede5a22023-02-20 09:43:38 +0800349 config->stt_alpha_apu,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800350 config->stt_skin_temp_apu_E);
351 acpigen_write_alib_dptc_thermal_E((uint8_t *)&thermal_E_input,
352 sizeof(thermal_E_input));
353
354 /* Profile F */
355 struct dptc_input thermal_F_input = DPTC_INPUTS(
356 config->thermctl_limit_degreeC,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800357 config->slow_ppt_time_constant_s_F,
358 config->fast_ppt_limit_mW_F,
359 config->slow_ppt_limit_mW_F,
360 config->vrm_current_limit_mA,
361 config->vrm_maximum_current_limit_mA,
362 config->vrm_soc_current_limit_mA,
363 config->stt_min_limit_F,
364 config->stt_m1_F,
365 config->stt_m2_F,
366 config->stt_c_apu_F,
Chris Wangeede5a22023-02-20 09:43:38 +0800367 config->stt_alpha_apu,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800368 config->stt_skin_temp_apu_F);
369 acpigen_write_alib_dptc_thermal_F((uint8_t *)&thermal_F_input,
370 sizeof(thermal_F_input));
371#endif
Felix Held3c44c622022-01-10 20:57:29 +0100372}
373
374static void root_complex_fill_ssdt(const struct device *device)
375{
Tim Van Pattenf5ae1dd2023-03-31 17:31:10 -0600376 uint32_t tdp = 0;
377
Tim Van Pattenf5ae1dd2023-03-31 17:31:10 -0600378 if (get_amd_smu_reported_tdp(&tdp) != CB_SUCCESS) {
379 /* Unknown TDP, so return rather than setting invalid values. */
380 return;
381 }
382 /* TODO(b/249359574): Add support for 6W DPTC values. */
383 if (tdp != TDP_15W)
384 return;
385
Tim Van Patten53ba14d2022-09-13 15:42:01 -0600386 if (CONFIG(SOC_AMD_COMMON_BLOCK_ACPI_DPTC))
387 acipgen_dptci();
Felix Held3c44c622022-01-10 20:57:29 +0100388}
389
390static const char *gnb_acpi_name(const struct device *dev)
391{
392 return "GNB";
393}
394
Arthur Heymans6a5d7702022-10-05 14:41:51 +0200395struct device_operations mendocino_root_complex_operations = {
Felix Held3c44c622022-01-10 20:57:29 +0100396 .read_resources = read_resources,
397 .set_resources = noop_set_resources,
398 .enable_resources = pci_dev_enable_resources,
399 .init = root_complex_init,
400 .acpi_name = gnb_acpi_name,
401 .acpi_fill_ssdt = root_complex_fill_ssdt,
402};