blob: 11f111f69f31a26a68a1126e3c030abd0426b3c9 [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>
8#include <amdblocks/ioapic.h>
9#include <amdblocks/memmap.h>
10#include <arch/ioapic.h>
11#include <cbmem.h>
12#include <console/console.h>
Felix Held3c44c622022-01-10 20:57:29 +010013#include <device/device.h>
14#include <device/pci.h>
Tim Van Pattenf5ae1dd2023-03-31 17:31:10 -060015#include <fsp/amd_misc_data.h>
Felix Held3c44c622022-01-10 20:57:29 +010016#include <fsp/util.h>
17#include <soc/iomap.h>
18#include <stdint.h>
19#include "chip.h"
20
Tim Van Pattenf5ae1dd2023-03-31 17:31:10 -060021#define TDP_15W 15
Chris Wang50aa3d92023-02-20 10:27:50 +080022#define DPTC_TOTAL_UPDATE_PARAMS 13
Felix Held3c44c622022-01-10 20:57:29 +010023
24struct dptc_input {
25 uint16_t size;
26 struct alib_dptc_param params[DPTC_TOTAL_UPDATE_PARAMS];
27} __packed;
28
EricKY Cheng33e0df12022-10-21 19:35:30 +080029
Chris Wang50aa3d92023-02-20 10:27:50 +080030#define DPTC_INPUTS(_thermctllmit, _spptTimeConst, _fast, _slow, \
31 _vrmCurrentLimit, _vrmMaxCurrentLimit, _vrmSocCurrentLimit, \
Chris Wangeede5a22023-02-20 09:43:38 +080032 _sttMinLimit, _sttM1, _sttM2, _sttCApu, _sttAlphaApu, _sttSkinTempLimitApu) \
Felix Held3c44c622022-01-10 20:57:29 +010033 { \
34 .size = sizeof(struct dptc_input), \
35 .params = { \
36 { \
37 .id = ALIB_DPTC_THERMAL_CONTROL_LIMIT_ID, \
38 .value = _thermctllmit, \
39 }, \
40 { \
EricKY Cheng33e0df12022-10-21 19:35:30 +080041 .id = ALIB_DPTC_SLOW_PPT_TIME_CONSTANT_ID, \
42 .value = _spptTimeConst, \
43 }, \
44 { \
Felix Held3c44c622022-01-10 20:57:29 +010045 .id = ALIB_DPTC_FAST_PPT_LIMIT_ID, \
46 .value = _fast, \
47 }, \
48 { \
49 .id = ALIB_DPTC_SLOW_PPT_LIMIT_ID, \
50 .value = _slow, \
51 }, \
Tim Van Patten11ca9952022-09-15 17:08:29 -060052 { \
53 .id = ALIB_DPTC_VRM_CURRENT_LIMIT_ID, \
54 .value = _vrmCurrentLimit, \
55 }, \
56 { \
57 .id = ALIB_DPTC_VRM_MAXIMUM_CURRENT_LIMIT, \
58 .value = _vrmMaxCurrentLimit, \
59 }, \
60 { \
61 .id = ALIB_DPTC_VRM_SOC_CURRENT_LIMIT_ID, \
62 .value = _vrmSocCurrentLimit, \
63 }, \
EricKY Cheng33e0df12022-10-21 19:35:30 +080064 { \
65 .id = ALIB_DPTC_STT_MIN_LIMIT_ID, \
66 .value = _sttMinLimit, \
67 }, \
68 { \
69 .id = ALIB_DPTC_STT_M1_ID, \
70 .value = _sttM1, \
71 }, \
72 { \
73 .id = ALIB_DPTC_STT_M2_ID, \
74 .value = _sttM2, \
75 }, \
76 { \
77 .id = ALIB_DPTC_STT_C_APU_ID, \
78 .value = _sttCApu, \
79 }, \
80 { \
Chris Wangeede5a22023-02-20 09:43:38 +080081 .id = ALIB_DPTC_STT_ALPHA_APU, \
82 .value = _sttAlphaApu, \
83 }, \
84 { \
EricKY Cheng33e0df12022-10-21 19:35:30 +080085 .id = ALIB_DPTC_STT_SKIN_TEMPERATURE_LIMIT_APU_ID, \
86 .value = _sttSkinTempLimitApu, \
87 }, \
Felix Held3c44c622022-01-10 20:57:29 +010088 }, \
89 }
90
91/*
92 *
93 * +--------------------------------+
94 * | |
95 * | |
96 * | |
97 * | |
98 * | |
99 * | |
100 * | |
101 * reserved_dram_end +--------------------------------+
102 * | |
103 * | verstage (if reqd) |
104 * | (VERSTAGE_SIZE) |
105 * +--------------------------------+ VERSTAGE_ADDR
106 * | |
107 * | FSP-M |
108 * | (FSP_M_SIZE) |
109 * +--------------------------------+ FSP_M_ADDR
110 * | romstage |
111 * | (ROMSTAGE_SIZE) |
112 * +--------------------------------+ ROMSTAGE_ADDR = BOOTBLOCK_END
113 * | | X86_RESET_VECTOR = BOOTBLOCK_END - 0x10
114 * | bootblock |
115 * | (C_ENV_BOOTBLOCK_SIZE) |
116 * +--------------------------------+ BOOTBLOCK_ADDR = BOOTBLOCK_END - C_ENV_BOOTBLOCK_SIZE
117 * | Unused hole |
Fred Reitbergerfdb07582022-07-15 08:05:56 -0400118 * | (30KiB) |
Felix Held3c44c622022-01-10 20:57:29 +0100119 * +--------------------------------+
120 * | FMAP cache (FMAP_SIZE) |
121 * +--------------------------------+ PSP_SHAREDMEM_BASE + PSP_SHAREDMEM_SIZE + PRERAM_CBMEM_CONSOLE_SIZE + 0x200
122 * | Early Timestamp region (512B) |
123 * +--------------------------------+ PSP_SHAREDMEM_BASE + PSP_SHAREDMEM_SIZE + PRERAM_CBMEM_CONSOLE_SIZE
124 * | Preram CBMEM console |
125 * | (PRERAM_CBMEM_CONSOLE_SIZE) |
126 * +--------------------------------+ PSP_SHAREDMEM_BASE + PSP_SHAREDMEM_SIZE
127 * | PSP shared (vboot workbuf) |
128 * | (PSP_SHAREDMEM_SIZE) |
129 * +--------------------------------+ PSP_SHAREDMEM_BASE
Fred Reitbergerfdb07582022-07-15 08:05:56 -0400130 * | APOB (120KiB) |
Felix Held3c44c622022-01-10 20:57:29 +0100131 * +--------------------------------+ PSP_APOB_DRAM_ADDRESS
132 * | Early BSP stack |
133 * | (EARLYRAM_BSP_STACK_SIZE) |
134 * reserved_dram_start +--------------------------------+ EARLY_RESERVED_DRAM_BASE
135 * | DRAM |
136 * +--------------------------------+ 0x100000
137 * | Option ROM |
138 * +--------------------------------+ 0xc0000
139 * | Legacy VGA |
140 * +--------------------------------+ 0xa0000
141 * | DRAM |
142 * +--------------------------------+ 0x0
143 */
144static void read_resources(struct device *dev)
145{
146 uint32_t mem_usable = (uintptr_t)cbmem_top();
147 unsigned int idx = 0;
Felix Held2e814362022-11-10 22:44:18 +0100148 const struct hob_header *hob_iterator;
Felix Held3c44c622022-01-10 20:57:29 +0100149 const struct hob_resource *res;
150 struct resource *gnb_apic;
151
152 uintptr_t early_reserved_dram_start, early_reserved_dram_end;
153 const struct memmap_early_dram *e = memmap_get_early_dram_usage();
154
155 early_reserved_dram_start = e->base;
156 early_reserved_dram_end = e->base + e->size;
157
Felix Heldaf17f0b2022-03-02 23:36:55 +0100158 /* The root complex has no PCI BARs implemented, so there's no need to call
159 pci_dev_read_resources for it */
160
Felix Heldd0959dc2023-05-10 15:07:47 +0200161 fixed_io_range_reserved(dev, idx++, PCI_IO_CONFIG_INDEX, PCI_IO_CONFIG_PORT_COUNT);
162
Felix Held3c44c622022-01-10 20:57:29 +0100163 /* 0x0 - 0x9ffff */
Kyösti Mälkki27d62992022-05-24 20:25:58 +0300164 ram_resource_kb(dev, idx++, 0, 0xa0000 / KiB);
Felix Held3c44c622022-01-10 20:57:29 +0100165
166 /* 0xa0000 - 0xbffff: legacy VGA */
Kyösti Mälkki27d62992022-05-24 20:25:58 +0300167 mmio_resource_kb(dev, idx++, 0xa0000 / KiB, 0x20000 / KiB);
Felix Held3c44c622022-01-10 20:57:29 +0100168
169 /* 0xc0000 - 0xfffff: Option ROM */
Kyösti Mälkki27d62992022-05-24 20:25:58 +0300170 reserved_ram_resource_kb(dev, idx++, 0xc0000 / KiB, 0x40000 / KiB);
Felix Held3c44c622022-01-10 20:57:29 +0100171
172 /* 1MiB - bottom of DRAM reserved for early coreboot usage */
Kyösti Mälkki27d62992022-05-24 20:25:58 +0300173 ram_resource_kb(dev, idx++, (1 * MiB) / KiB,
Felix Held3c44c622022-01-10 20:57:29 +0100174 (early_reserved_dram_start - (1 * MiB)) / KiB);
175
176 /* DRAM reserved for early coreboot usage */
Kyösti Mälkki27d62992022-05-24 20:25:58 +0300177 reserved_ram_resource_kb(dev, idx++, early_reserved_dram_start / KiB,
Felix Held3c44c622022-01-10 20:57:29 +0100178 (early_reserved_dram_end - early_reserved_dram_start) / KiB);
179
180 /*
181 * top of DRAM consumed early - low top usable RAM
182 * cbmem_top() accounts for low UMA and TSEG if they are used.
183 */
Kyösti Mälkki27d62992022-05-24 20:25:58 +0300184 ram_resource_kb(dev, idx++, early_reserved_dram_end / KiB,
Felix Held3c44c622022-01-10 20:57:29 +0100185 (mem_usable - early_reserved_dram_end) / KiB);
186
Felix Held56b037b2022-03-02 22:57:01 +0100187 mmconf_resource(dev, idx++);
Felix Held3c44c622022-01-10 20:57:29 +0100188
Felix Helddafc6192022-11-10 18:19:36 +0100189 /* GNB IOAPIC resource */
190 gnb_apic = new_resource(dev, idx++);
191 gnb_apic->base = GNB_IO_APIC_ADDR;
192 gnb_apic->size = 0x00001000;
193 gnb_apic->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
194
Felix Held2e814362022-11-10 22:44:18 +0100195 if (fsp_hob_iterator_init(&hob_iterator) != CB_SUCCESS) {
Elyes Haouasaba1c942022-11-09 15:05:23 +0100196 printk(BIOS_ERR, "%s incomplete because no HOB list was found\n",
Felix Held3c44c622022-01-10 20:57:29 +0100197 __func__);
198 return;
199 }
200
Felix Held2e814362022-11-10 22:44:18 +0100201 while (fsp_hob_iterator_get_next_resource(&hob_iterator, &res) == CB_SUCCESS) {
Felix Held3c44c622022-01-10 20:57:29 +0100202 if (res->type == EFI_RESOURCE_SYSTEM_MEMORY && res->addr < mem_usable)
203 continue; /* 0 through low usable was set above */
204 if (res->type == EFI_RESOURCE_MEMORY_MAPPED_IO)
205 continue; /* Done separately */
206
207 if (res->type == EFI_RESOURCE_SYSTEM_MEMORY)
Kyösti Mälkki27d62992022-05-24 20:25:58 +0300208 ram_resource_kb(dev, idx++, res->addr / KiB, res->length / KiB);
Felix Held3c44c622022-01-10 20:57:29 +0100209 else if (res->type == EFI_RESOURCE_MEMORY_RESERVED)
Kyösti Mälkki27d62992022-05-24 20:25:58 +0300210 reserved_ram_resource_kb(dev, idx++, res->addr / KiB, res->length / KiB);
Felix Held3c44c622022-01-10 20:57:29 +0100211 else
Elyes Haouasaba1c942022-11-09 15:05:23 +0100212 printk(BIOS_ERR, "Failed to set resources for type %d\n",
Felix Held3c44c622022-01-10 20:57:29 +0100213 res->type);
214 }
Felix Held3c44c622022-01-10 20:57:29 +0100215}
216
217static void root_complex_init(struct device *dev)
218{
Kyösti Mälkki2e65e9c2021-06-16 11:00:40 +0300219 register_new_ioapic((u8 *)GNB_IO_APIC_ADDR);
Felix Held3c44c622022-01-10 20:57:29 +0100220}
221
222static void acipgen_dptci(void)
223{
Jon Murphy4f732422022-08-05 15:43:44 -0600224 const struct soc_amd_mendocino_config *config = config_of_soc();
Felix Held3c44c622022-01-10 20:57:29 +0100225
Tim Van Patten53ba14d2022-09-13 15:42:01 -0600226 /* Normal mode DPTC values. */
EricKY Cheng33e0df12022-10-21 19:35:30 +0800227 struct dptc_input default_input = DPTC_INPUTS(
228 config->thermctl_limit_degreeC,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800229 config->slow_ppt_time_constant_s,
Tim Van Patten92443582022-08-23 16:06:33 -0600230 config->fast_ppt_limit_mW,
Tim Van Patten11ca9952022-09-15 17:08:29 -0600231 config->slow_ppt_limit_mW,
232 config->vrm_current_limit_mA,
233 config->vrm_maximum_current_limit_mA,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800234 config->vrm_soc_current_limit_mA,
235 config->stt_min_limit,
236 config->stt_m1,
237 config->stt_m2,
238 config->stt_c_apu,
Chris Wangeede5a22023-02-20 09:43:38 +0800239 config->stt_alpha_apu,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800240 config->stt_skin_temp_apu);
Tim Van Patten92443582022-08-23 16:06:33 -0600241 acpigen_write_alib_dptc_default((uint8_t *)&default_input, sizeof(default_input));
Tim Van Patten1075fef2022-05-20 11:06:03 -0600242
243 /* Low/No Battery */
244 struct dptc_input no_battery_input = DPTC_INPUTS(
245 config->thermctl_limit_degreeC,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800246 config->slow_ppt_time_constant_s,
Tim Van Patten1075fef2022-05-20 11:06:03 -0600247 config->fast_ppt_limit_mW,
248 config->slow_ppt_limit_mW,
249 config->vrm_current_limit_throttle_mA,
250 config->vrm_maximum_current_limit_throttle_mA,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800251 config->vrm_soc_current_limit_throttle_mA,
252 config->stt_min_limit,
253 config->stt_m1,
254 config->stt_m2,
255 config->stt_c_apu,
Chris Wangeede5a22023-02-20 09:43:38 +0800256 config->stt_alpha_apu,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800257 config->stt_skin_temp_apu);
Tim Van Patten1075fef2022-05-20 11:06:03 -0600258 acpigen_write_alib_dptc_no_battery((uint8_t *)&no_battery_input,
259 sizeof(no_battery_input));
EricKY Cheng33e0df12022-10-21 19:35:30 +0800260
Chris.Wang9ac09842022-12-13 14:31:38 +0800261#if (CONFIG(FEATURE_TABLET_MODE_DPTC))
262 struct dptc_input tablet_input = DPTC_INPUTS(
263 config->thermctl_limit_degreeC,
Chris.Wang9ac09842022-12-13 14:31:38 +0800264 config->slow_ppt_time_constant_s,
265 config->fast_ppt_limit_mW,
266 config->slow_ppt_limit_mW,
267 config->vrm_current_limit_mA,
268 config->vrm_maximum_current_limit_mA,
269 config->vrm_soc_current_limit_mA,
270 config->stt_min_limit,
Chris Wang28095072023-02-23 16:25:52 +0800271 config->stt_m1_tablet,
272 config->stt_m2_tablet,
273 config->stt_c_apu_tablet,
274 config->stt_alpha_apu_tablet,
Chris.Wang9ac09842022-12-13 14:31:38 +0800275 config->stt_skin_temp_apu);
276 acpigen_write_alib_dptc_tablet((uint8_t *)&tablet_input, sizeof(tablet_input));
277#endif
278
EricKY Cheng33e0df12022-10-21 19:35:30 +0800279#if (CONFIG(FEATURE_DYNAMIC_DPTC))
280 /* Profile B */
281 struct dptc_input thermal_B_input = DPTC_INPUTS(
282 config->thermctl_limit_degreeC,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800283 config->slow_ppt_time_constant_s_B,
284 config->fast_ppt_limit_mW_B,
285 config->slow_ppt_limit_mW_B,
286 config->vrm_current_limit_throttle_mA,
287 config->vrm_maximum_current_limit_mA,
288 config->vrm_soc_current_limit_mA,
289 config->stt_min_limit_B,
290 config->stt_m1_B,
291 config->stt_m2_B,
292 config->stt_c_apu_B,
Chris Wangeede5a22023-02-20 09:43:38 +0800293 config->stt_alpha_apu,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800294 config->stt_skin_temp_apu_B);
295 acpigen_write_alib_dptc_thermal_B((uint8_t *)&thermal_B_input,
296 sizeof(thermal_B_input));
297
298 /* Profile C */
299 struct dptc_input thermal_C_input = DPTC_INPUTS(
300 config->thermctl_limit_degreeC,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800301 config->slow_ppt_time_constant_s_C,
302 config->fast_ppt_limit_mW_C,
303 config->slow_ppt_limit_mW_C,
304 config->vrm_current_limit_mA,
305 config->vrm_maximum_current_limit_mA,
306 config->vrm_soc_current_limit_mA,
307 config->stt_min_limit_C,
308 config->stt_m1_C,
309 config->stt_m2_C,
310 config->stt_c_apu_C,
Chris Wangeede5a22023-02-20 09:43:38 +0800311 config->stt_alpha_apu,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800312 config->stt_skin_temp_apu_C);
313 acpigen_write_alib_dptc_thermal_C((uint8_t *)&thermal_C_input,
314 sizeof(thermal_C_input));
315
316 /* Profile D */
317 struct dptc_input thermal_D_input = DPTC_INPUTS(
318 config->thermctl_limit_degreeC,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800319 config->slow_ppt_time_constant_s_D,
320 config->fast_ppt_limit_mW_D,
321 config->slow_ppt_limit_mW_D,
322 config->vrm_current_limit_mA,
323 config->vrm_maximum_current_limit_mA,
324 config->vrm_soc_current_limit_mA,
325 config->stt_min_limit_D,
326 config->stt_m1_D,
327 config->stt_m2_D,
328 config->stt_c_apu_D,
Chris Wangeede5a22023-02-20 09:43:38 +0800329 config->stt_alpha_apu,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800330 config->stt_skin_temp_apu_D);
331 acpigen_write_alib_dptc_thermal_D((uint8_t *)&thermal_D_input,
332 sizeof(thermal_D_input));
333
334 /* Profile E */
335 struct dptc_input thermal_E_input = DPTC_INPUTS(
336 config->thermctl_limit_degreeC,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800337 config->slow_ppt_time_constant_s_E,
338 config->fast_ppt_limit_mW_E,
339 config->slow_ppt_limit_mW_E,
340 config->vrm_current_limit_mA,
341 config->vrm_maximum_current_limit_mA,
342 config->vrm_soc_current_limit_mA,
343 config->stt_min_limit_E,
344 config->stt_m1_E,
345 config->stt_m2_E,
346 config->stt_c_apu_E,
Chris Wangeede5a22023-02-20 09:43:38 +0800347 config->stt_alpha_apu,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800348 config->stt_skin_temp_apu_E);
349 acpigen_write_alib_dptc_thermal_E((uint8_t *)&thermal_E_input,
350 sizeof(thermal_E_input));
351
352 /* Profile F */
353 struct dptc_input thermal_F_input = DPTC_INPUTS(
354 config->thermctl_limit_degreeC,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800355 config->slow_ppt_time_constant_s_F,
356 config->fast_ppt_limit_mW_F,
357 config->slow_ppt_limit_mW_F,
358 config->vrm_current_limit_mA,
359 config->vrm_maximum_current_limit_mA,
360 config->vrm_soc_current_limit_mA,
361 config->stt_min_limit_F,
362 config->stt_m1_F,
363 config->stt_m2_F,
364 config->stt_c_apu_F,
Chris Wangeede5a22023-02-20 09:43:38 +0800365 config->stt_alpha_apu,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800366 config->stt_skin_temp_apu_F);
367 acpigen_write_alib_dptc_thermal_F((uint8_t *)&thermal_F_input,
368 sizeof(thermal_F_input));
369#endif
Felix Held3c44c622022-01-10 20:57:29 +0100370}
371
372static void root_complex_fill_ssdt(const struct device *device)
373{
Tim Van Pattenf5ae1dd2023-03-31 17:31:10 -0600374 uint32_t tdp = 0;
375
Felix Held3c44c622022-01-10 20:57:29 +0100376 acpi_fill_root_complex_tom(device);
Tim Van Pattenf5ae1dd2023-03-31 17:31:10 -0600377
378 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};