blob: 0c95f7a86f98d35a9f412788ab96cd365bd01e34 [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>
Felix Held81c81e32023-07-18 20:37:36 +020012#include <amdblocks/root_complex.h>
Felix Held3c44c622022-01-10 20:57:29 +010013#include <arch/ioapic.h>
Felix Helda4ced632023-06-05 21:22:15 +020014#include <arch/vga.h>
Felix Held3c44c622022-01-10 20:57:29 +010015#include <cbmem.h>
16#include <console/console.h>
Felix Held3c44c622022-01-10 20:57:29 +010017#include <device/device.h>
18#include <device/pci.h>
Tim Van Pattenf5ae1dd2023-03-31 17:31:10 -060019#include <fsp/amd_misc_data.h>
Felix Held3c44c622022-01-10 20:57:29 +010020#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 Held3c44c622022-01-10 20:57:29 +0100151
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 */
Arthur Heymansb2de1a32023-07-05 12:15:51 +0200164 ram_range(dev, idx++, 0, 0xa0000);
Felix Held3c44c622022-01-10 20:57:29 +0100165
166 /* 0xa0000 - 0xbffff: legacy VGA */
Arthur Heymansb2de1a32023-07-05 12:15:51 +0200167 mmio_range(dev, idx++, VGA_MMIO_BASE, VGA_MMIO_SIZE);
Felix Held3c44c622022-01-10 20:57:29 +0100168
169 /* 0xc0000 - 0xfffff: Option ROM */
Arthur Heymansb2de1a32023-07-05 12:15:51 +0200170 reserved_ram_from_to(dev, idx++, 0xc0000, 1 * MiB);
Felix Held3c44c622022-01-10 20:57:29 +0100171
172 /* 1MiB - bottom of DRAM reserved for early coreboot usage */
Arthur Heymansb2de1a32023-07-05 12:15:51 +0200173 ram_from_to(dev, idx++, 1 * MiB, early_reserved_dram_start);
Felix Held3c44c622022-01-10 20:57:29 +0100174
175 /* DRAM reserved for early coreboot usage */
Arthur Heymansb2de1a32023-07-05 12:15:51 +0200176 reserved_ram_from_to(dev, idx++, early_reserved_dram_start, early_reserved_dram_end);
Felix Held3c44c622022-01-10 20:57:29 +0100177
178 /*
179 * top of DRAM consumed early - low top usable RAM
180 * cbmem_top() accounts for low UMA and TSEG if they are used.
181 */
Arthur Heymansb2de1a32023-07-05 12:15:51 +0200182 ram_from_to(dev, idx++, early_reserved_dram_end, mem_usable);
Felix Held3c44c622022-01-10 20:57:29 +0100183
Felix Held56b037b2022-03-02 22:57:01 +0100184 mmconf_resource(dev, idx++);
Felix Held3c44c622022-01-10 20:57:29 +0100185
Felix Held12a44822023-06-02 15:30:50 +0200186 /* Reserve fixed IOMMU MMIO region */
187 mmio_range(dev, idx++, IOMMU_RESERVED_MMIO_BASE, IOMMU_RESERVED_MMIO_SIZE);
188
Felix Held6b248a22023-07-26 16:42:46 +0200189 read_fsp_resources(dev, &idx);
Felix Held3c44c622022-01-10 20:57:29 +0100190}
191
192static void root_complex_init(struct device *dev)
193{
Kyösti Mälkki2e65e9c2021-06-16 11:00:40 +0300194 register_new_ioapic((u8 *)GNB_IO_APIC_ADDR);
Felix Held3c44c622022-01-10 20:57:29 +0100195}
196
197static void acipgen_dptci(void)
198{
Jon Murphy4f732422022-08-05 15:43:44 -0600199 const struct soc_amd_mendocino_config *config = config_of_soc();
Felix Held3c44c622022-01-10 20:57:29 +0100200
Tim Van Patten53ba14d2022-09-13 15:42:01 -0600201 /* Normal mode DPTC values. */
EricKY Cheng33e0df12022-10-21 19:35:30 +0800202 struct dptc_input default_input = DPTC_INPUTS(
203 config->thermctl_limit_degreeC,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800204 config->slow_ppt_time_constant_s,
Tim Van Patten92443582022-08-23 16:06:33 -0600205 config->fast_ppt_limit_mW,
Tim Van Patten11ca9952022-09-15 17:08:29 -0600206 config->slow_ppt_limit_mW,
207 config->vrm_current_limit_mA,
208 config->vrm_maximum_current_limit_mA,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800209 config->vrm_soc_current_limit_mA,
210 config->stt_min_limit,
211 config->stt_m1,
212 config->stt_m2,
213 config->stt_c_apu,
Chris Wangeede5a22023-02-20 09:43:38 +0800214 config->stt_alpha_apu,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800215 config->stt_skin_temp_apu);
Tim Van Patten92443582022-08-23 16:06:33 -0600216 acpigen_write_alib_dptc_default((uint8_t *)&default_input, sizeof(default_input));
Tim Van Patten1075fef2022-05-20 11:06:03 -0600217
218 /* Low/No Battery */
219 struct dptc_input no_battery_input = DPTC_INPUTS(
220 config->thermctl_limit_degreeC,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800221 config->slow_ppt_time_constant_s,
Tim Van Patten1075fef2022-05-20 11:06:03 -0600222 config->fast_ppt_limit_mW,
223 config->slow_ppt_limit_mW,
224 config->vrm_current_limit_throttle_mA,
225 config->vrm_maximum_current_limit_throttle_mA,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800226 config->vrm_soc_current_limit_throttle_mA,
227 config->stt_min_limit,
228 config->stt_m1,
229 config->stt_m2,
230 config->stt_c_apu,
Chris Wangeede5a22023-02-20 09:43:38 +0800231 config->stt_alpha_apu,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800232 config->stt_skin_temp_apu);
Tim Van Patten1075fef2022-05-20 11:06:03 -0600233 acpigen_write_alib_dptc_no_battery((uint8_t *)&no_battery_input,
234 sizeof(no_battery_input));
EricKY Cheng33e0df12022-10-21 19:35:30 +0800235
Chris.Wang9ac09842022-12-13 14:31:38 +0800236#if (CONFIG(FEATURE_TABLET_MODE_DPTC))
237 struct dptc_input tablet_input = DPTC_INPUTS(
238 config->thermctl_limit_degreeC,
Chris.Wang9ac09842022-12-13 14:31:38 +0800239 config->slow_ppt_time_constant_s,
240 config->fast_ppt_limit_mW,
241 config->slow_ppt_limit_mW,
242 config->vrm_current_limit_mA,
243 config->vrm_maximum_current_limit_mA,
244 config->vrm_soc_current_limit_mA,
245 config->stt_min_limit,
Chris Wang28095072023-02-23 16:25:52 +0800246 config->stt_m1_tablet,
247 config->stt_m2_tablet,
248 config->stt_c_apu_tablet,
249 config->stt_alpha_apu_tablet,
Chris.Wang9ac09842022-12-13 14:31:38 +0800250 config->stt_skin_temp_apu);
251 acpigen_write_alib_dptc_tablet((uint8_t *)&tablet_input, sizeof(tablet_input));
252#endif
253
EricKY Cheng33e0df12022-10-21 19:35:30 +0800254#if (CONFIG(FEATURE_DYNAMIC_DPTC))
255 /* Profile B */
256 struct dptc_input thermal_B_input = DPTC_INPUTS(
257 config->thermctl_limit_degreeC,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800258 config->slow_ppt_time_constant_s_B,
259 config->fast_ppt_limit_mW_B,
260 config->slow_ppt_limit_mW_B,
261 config->vrm_current_limit_throttle_mA,
262 config->vrm_maximum_current_limit_mA,
263 config->vrm_soc_current_limit_mA,
264 config->stt_min_limit_B,
265 config->stt_m1_B,
266 config->stt_m2_B,
267 config->stt_c_apu_B,
Chris Wangeede5a22023-02-20 09:43:38 +0800268 config->stt_alpha_apu,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800269 config->stt_skin_temp_apu_B);
270 acpigen_write_alib_dptc_thermal_B((uint8_t *)&thermal_B_input,
271 sizeof(thermal_B_input));
272
273 /* Profile C */
274 struct dptc_input thermal_C_input = DPTC_INPUTS(
275 config->thermctl_limit_degreeC,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800276 config->slow_ppt_time_constant_s_C,
277 config->fast_ppt_limit_mW_C,
278 config->slow_ppt_limit_mW_C,
279 config->vrm_current_limit_mA,
280 config->vrm_maximum_current_limit_mA,
281 config->vrm_soc_current_limit_mA,
282 config->stt_min_limit_C,
283 config->stt_m1_C,
284 config->stt_m2_C,
285 config->stt_c_apu_C,
Chris Wangeede5a22023-02-20 09:43:38 +0800286 config->stt_alpha_apu,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800287 config->stt_skin_temp_apu_C);
288 acpigen_write_alib_dptc_thermal_C((uint8_t *)&thermal_C_input,
289 sizeof(thermal_C_input));
290
291 /* Profile D */
292 struct dptc_input thermal_D_input = DPTC_INPUTS(
293 config->thermctl_limit_degreeC,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800294 config->slow_ppt_time_constant_s_D,
295 config->fast_ppt_limit_mW_D,
296 config->slow_ppt_limit_mW_D,
297 config->vrm_current_limit_mA,
298 config->vrm_maximum_current_limit_mA,
299 config->vrm_soc_current_limit_mA,
300 config->stt_min_limit_D,
301 config->stt_m1_D,
302 config->stt_m2_D,
303 config->stt_c_apu_D,
Chris Wangeede5a22023-02-20 09:43:38 +0800304 config->stt_alpha_apu,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800305 config->stt_skin_temp_apu_D);
306 acpigen_write_alib_dptc_thermal_D((uint8_t *)&thermal_D_input,
307 sizeof(thermal_D_input));
308
309 /* Profile E */
310 struct dptc_input thermal_E_input = DPTC_INPUTS(
311 config->thermctl_limit_degreeC,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800312 config->slow_ppt_time_constant_s_E,
313 config->fast_ppt_limit_mW_E,
314 config->slow_ppt_limit_mW_E,
315 config->vrm_current_limit_mA,
316 config->vrm_maximum_current_limit_mA,
317 config->vrm_soc_current_limit_mA,
318 config->stt_min_limit_E,
319 config->stt_m1_E,
320 config->stt_m2_E,
321 config->stt_c_apu_E,
Chris Wangeede5a22023-02-20 09:43:38 +0800322 config->stt_alpha_apu,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800323 config->stt_skin_temp_apu_E);
324 acpigen_write_alib_dptc_thermal_E((uint8_t *)&thermal_E_input,
325 sizeof(thermal_E_input));
326
327 /* Profile F */
328 struct dptc_input thermal_F_input = DPTC_INPUTS(
329 config->thermctl_limit_degreeC,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800330 config->slow_ppt_time_constant_s_F,
331 config->fast_ppt_limit_mW_F,
332 config->slow_ppt_limit_mW_F,
333 config->vrm_current_limit_mA,
334 config->vrm_maximum_current_limit_mA,
335 config->vrm_soc_current_limit_mA,
336 config->stt_min_limit_F,
337 config->stt_m1_F,
338 config->stt_m2_F,
339 config->stt_c_apu_F,
Chris Wangeede5a22023-02-20 09:43:38 +0800340 config->stt_alpha_apu,
EricKY Cheng33e0df12022-10-21 19:35:30 +0800341 config->stt_skin_temp_apu_F);
342 acpigen_write_alib_dptc_thermal_F((uint8_t *)&thermal_F_input,
343 sizeof(thermal_F_input));
344#endif
Felix Held3c44c622022-01-10 20:57:29 +0100345}
346
347static void root_complex_fill_ssdt(const struct device *device)
348{
Tim Van Pattenf5ae1dd2023-03-31 17:31:10 -0600349 uint32_t tdp = 0;
350
Tim Van Pattenf5ae1dd2023-03-31 17:31:10 -0600351 if (get_amd_smu_reported_tdp(&tdp) != CB_SUCCESS) {
352 /* Unknown TDP, so return rather than setting invalid values. */
353 return;
354 }
355 /* TODO(b/249359574): Add support for 6W DPTC values. */
356 if (tdp != TDP_15W)
357 return;
358
Tim Van Patten53ba14d2022-09-13 15:42:01 -0600359 if (CONFIG(SOC_AMD_COMMON_BLOCK_ACPI_DPTC))
360 acipgen_dptci();
Felix Held3c44c622022-01-10 20:57:29 +0100361}
362
363static const char *gnb_acpi_name(const struct device *dev)
364{
365 return "GNB";
366}
367
Arthur Heymans6a5d7702022-10-05 14:41:51 +0200368struct device_operations mendocino_root_complex_operations = {
Felix Held3c44c622022-01-10 20:57:29 +0100369 .read_resources = read_resources,
370 .set_resources = noop_set_resources,
371 .enable_resources = pci_dev_enable_resources,
372 .init = root_complex_init,
373 .acpi_name = gnb_acpi_name,
374 .acpi_fill_ssdt = root_complex_fill_ssdt,
375};
Felix Held81c81e32023-07-18 20:37:36 +0200376
377uint32_t get_iohc_misc_smn_base(struct device *domain)
378{
Felix Held69ffebf2023-07-24 21:31:44 +0200379 return SMN_IOHC_MISC_BASE_13B1;
Felix Held81c81e32023-07-18 20:37:36 +0200380}
381
382static const struct non_pci_mmio_reg non_pci_mmio[] = {
383 { 0x2d8, 0xfffffff00000ull, 1 * MiB, NON_PCI_RES_IDX_AUTO },
384 { 0x2e0, 0xfffffff00000ull, 1 * MiB, NON_PCI_RES_IDX_AUTO },
385 { 0x2e8, 0xfffffff00000ull, 1 * MiB, NON_PCI_RES_IDX_AUTO },
386 /* The hardware has a 256 byte alignment requirement for the IOAPIC MMIO base, but we
387 tell the FSP to configure a 4k-aligned base address and this is reported as 4 KiB
388 resource. */
389 { 0x2f0, 0xffffffffff00ull, 4 * KiB, IOMMU_IOAPIC_IDX },
390 { 0x2f8, 0xfffffff00000ull, 1 * MiB, NON_PCI_RES_IDX_AUTO },
391 { 0x300, 0xfffffff00000ull, 1 * MiB, NON_PCI_RES_IDX_AUTO },
392 { 0x308, 0xfffffffff000ull, 4 * KiB, NON_PCI_RES_IDX_AUTO },
393 { 0x318, 0xfffffff80000ull, 512 * KiB, NON_PCI_RES_IDX_AUTO },
394};
395
396const struct non_pci_mmio_reg *get_iohc_non_pci_mmio_regs(size_t *count)
397{
398 *count = ARRAY_SIZE(non_pci_mmio);
399 return non_pci_mmio;
400}