mb/google/brya/var/orisa: Update Type C DisplayPort HPD Configuration
[coreboot2.git] / src / soc / intel / skylake / acpi.c
blob3a60adad50159e7f58fe693fe1f3d6ac27645d7b
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <acpi/acpi_gnvs.h>
4 #include <acpi/acpi_pm.h>
5 #include <acpi/acpi.h>
6 #include <acpi/acpigen.h>
7 #include <arch/ioapic.h>
8 #include <arch/smp/mpspec.h>
9 #include <console/console.h>
10 #include <cpu/cpu.h>
11 #include <intelblocks/acpi_wake_source.h>
12 #include <intelblocks/acpi.h>
13 #include <intelblocks/cpulib.h>
14 #include <intelblocks/pmclib.h>
15 #include <soc/cpu.h>
16 #include <soc/msr.h>
17 #include <soc/pm.h>
18 #include <soc/ramstage.h>
19 #include <soc/systemagent.h>
20 #include <static.h>
21 #include <string.h>
22 #include <types.h>
24 #include "chip.h"
27 * List of supported C-states in this processor.
29 enum {
30 C_STATE_C0, /* 0 */
31 C_STATE_C1, /* 1 */
32 C_STATE_C1E, /* 2 */
33 C_STATE_C3, /* 3 */
34 C_STATE_C6_SHORT_LAT, /* 4 */
35 C_STATE_C6_LONG_LAT, /* 5 */
36 C_STATE_C7_SHORT_LAT, /* 6 */
37 C_STATE_C7_LONG_LAT, /* 7 */
38 C_STATE_C7S_SHORT_LAT, /* 8 */
39 C_STATE_C7S_LONG_LAT, /* 9 */
40 C_STATE_C8, /* 10 */
41 C_STATE_C9, /* 11 */
42 C_STATE_C10, /* 12 */
43 NUM_C_STATES
45 #define MWAIT_RES(state, sub_state) \
46 { \
47 .addrl = (((state) << 4) | (sub_state)), \
48 .space_id = ACPI_ADDRESS_SPACE_FIXED, \
49 .bit_width = ACPI_FFIXEDHW_VENDOR_INTEL, \
50 .bit_offset = ACPI_FFIXEDHW_CLASS_MWAIT, \
51 .access_size = ACPI_FFIXEDHW_FLAG_HW_COORD, \
54 static acpi_cstate_t cstate_map[NUM_C_STATES] = {
55 [C_STATE_C0] = { },
56 [C_STATE_C1] = {
57 .latency = 0,
58 .power = C1_POWER,
59 .resource = MWAIT_RES(0, 0),
61 [C_STATE_C1E] = {
62 .latency = 0,
63 .power = C1_POWER,
64 .resource = MWAIT_RES(0, 1),
66 [C_STATE_C3] = {
67 .latency = C_STATE_LATENCY_FROM_LAT_REG(0),
68 .power = C3_POWER,
69 .resource = MWAIT_RES(1, 0),
71 [C_STATE_C6_SHORT_LAT] = {
72 .latency = C_STATE_LATENCY_FROM_LAT_REG(1),
73 .power = C6_POWER,
74 .resource = MWAIT_RES(2, 0),
76 [C_STATE_C6_LONG_LAT] = {
77 .latency = C_STATE_LATENCY_FROM_LAT_REG(2),
78 .power = C6_POWER,
79 .resource = MWAIT_RES(2, 1),
81 [C_STATE_C7_SHORT_LAT] = {
82 .latency = C_STATE_LATENCY_FROM_LAT_REG(1),
83 .power = C7_POWER,
84 .resource = MWAIT_RES(3, 0),
86 [C_STATE_C7_LONG_LAT] = {
87 .latency = C_STATE_LATENCY_FROM_LAT_REG(2),
88 .power = C7_POWER,
89 .resource = MWAIT_RES(3, 1),
91 [C_STATE_C7S_SHORT_LAT] = {
92 .latency = C_STATE_LATENCY_FROM_LAT_REG(1),
93 .power = C7_POWER,
94 .resource = MWAIT_RES(3, 2),
96 [C_STATE_C7S_LONG_LAT] = {
97 .latency = C_STATE_LATENCY_FROM_LAT_REG(2),
98 .power = C7_POWER,
99 .resource = MWAIT_RES(3, 3),
101 [C_STATE_C8] = {
102 .latency = C_STATE_LATENCY_FROM_LAT_REG(3),
103 .power = C8_POWER,
104 .resource = MWAIT_RES(4, 0),
106 [C_STATE_C9] = {
107 .latency = C_STATE_LATENCY_FROM_LAT_REG(4),
108 .power = C9_POWER,
109 .resource = MWAIT_RES(5, 0),
111 [C_STATE_C10] = {
112 .latency = C_STATE_LATENCY_FROM_LAT_REG(5),
113 .power = C10_POWER,
114 .resource = MWAIT_RES(6, 0),
118 static int cstate_set_s0ix[] = {
119 C_STATE_C1E,
120 C_STATE_C7S_LONG_LAT,
121 C_STATE_C10
124 static int cstate_set_non_s0ix[] = {
125 C_STATE_C1E,
126 C_STATE_C3,
127 C_STATE_C7S_LONG_LAT,
130 const acpi_cstate_t *soc_get_cstate_map(size_t *entries)
132 static acpi_cstate_t map[MAX(ARRAY_SIZE(cstate_set_s0ix),
133 ARRAY_SIZE(cstate_set_non_s0ix))];
134 int *set;
135 int i;
137 config_t *config = config_of_soc();
139 int is_s0ix_enable = config->s0ix_enable;
141 if (is_s0ix_enable) {
142 *entries = ARRAY_SIZE(cstate_set_s0ix);
143 set = cstate_set_s0ix;
144 } else {
145 *entries = ARRAY_SIZE(cstate_set_non_s0ix);
146 set = cstate_set_non_s0ix;
149 for (i = 0; i < *entries; i++) {
150 memcpy(&map[i], &cstate_map[set[i]], sizeof(acpi_cstate_t));
151 map[i].ctype = i + 1;
153 return map;
156 void soc_power_states_generation(int core_id, int cores_per_package)
158 config_t *config = config_of_soc();
160 /* Generate P-state tables */
161 if (config->eist_enable)
162 generate_p_state_entries(core_id, cores_per_package);
165 uint32_t soc_read_sci_irq_select(void)
167 return read32p(soc_read_pmc_base() + IRQ_REG);
170 void soc_fill_gnvs(struct global_nvs *gnvs)
172 const struct soc_intel_skylake_config *config = config_of_soc();
174 /* Enable DPTF based on mainboard configuration */
175 gnvs->dpte = config->dptf_enable;
177 /* Set USB2/USB3 wake enable bitmaps. */
178 gnvs->u2we = config->usb2_wake_enable_bitmap;
179 gnvs->u3we = config->usb3_wake_enable_bitmap;
182 static unsigned long soc_fill_dmar(unsigned long current)
184 const u32 gfx_vtbar = MCHBAR32(GFXVTBAR) & ~0xfff;
185 const bool gfxvten = MCHBAR32(GFXVTBAR) & 1;
187 /* iGFX has to be enabled, GFXVTBAR set and in 32-bit space. */
188 const bool emit_igd =
189 is_devfn_enabled(SA_DEVFN_IGD) &&
190 gfx_vtbar && gfxvten &&
191 !MCHBAR32(GFXVTBAR + 4);
193 /* First, add DRHD entries */
194 if (emit_igd) {
195 const unsigned long tmp = current;
197 current += acpi_create_dmar_drhd_4k(current, 0, 0, gfx_vtbar);
198 current += acpi_create_dmar_ds_pci(current, 0, 2, 0);
200 acpi_dmar_drhd_fixup(tmp, current);
203 const u32 vtvc0bar = MCHBAR32(VTVC0BAR) & ~0xfff;
204 const bool vtvc0en = MCHBAR32(VTVC0BAR) & 1;
206 /* General VTBAR has to be set and in 32-bit space. */
207 if (vtvc0bar && vtvc0en && !MCHBAR32(VTVC0BAR + 4)) {
208 const unsigned long tmp = current;
210 current += acpi_create_dmar_drhd_4k(current, DRHD_INCLUDE_PCI_ALL, 0, vtvc0bar);
212 current += acpi_create_dmar_ds_ioapic_from_hw(current, IO_APIC_ADDR, V_P2SB_IBDF_BUS,
213 V_P2SB_IBDF_DEV, V_P2SB_IBDF_FUN);
215 current += acpi_create_dmar_ds_msi_hpet(current, 0, V_P2SB_HBDF_BUS,
216 V_P2SB_HBDF_DEV, V_P2SB_HBDF_FUN);
218 acpi_dmar_drhd_fixup(tmp, current);
221 /* Then, add RMRR entries after all DRHD entries */
222 if (emit_igd) {
223 const unsigned long tmp = current;
225 current += acpi_create_dmar_rmrr(current, 0,
226 sa_get_gsm_base(), sa_get_tolud_base() - 1);
227 current += acpi_create_dmar_ds_pci(current, 0, 2, 0);
228 acpi_dmar_rmrr_fixup(tmp, current);
231 return current;
234 unsigned long sa_write_acpi_tables(const struct device *const dev,
235 unsigned long current,
236 struct acpi_rsdp *const rsdp)
238 acpi_dmar_t *const dmar = (acpi_dmar_t *)current;
240 /* Create DMAR table only if we have VT-d capability. */
241 if (!soc_vtd_enabled())
242 return current;
244 printk(BIOS_DEBUG, "ACPI: * DMAR\n");
245 acpi_create_dmar(dmar, DMAR_INTR_REMAP, soc_fill_dmar);
246 current += dmar->header.length;
247 current = acpi_align_current(current);
248 acpi_add_table(rsdp, dmar);
250 return current;
253 int soc_madt_sci_irq_polarity(int sci)
255 if (sci >= 20)
256 return MP_IRQ_POLARITY_LOW;
257 else
258 return MP_IRQ_POLARITY_HIGH;
261 void acpi_fill_soc_wake(uint32_t *pm1_en, uint32_t *gpe0_en,
262 const struct chipset_power_state *ps)
264 const struct soc_intel_skylake_config *config = config_of_soc();
266 if (ps->prev_sleep_state == ACPI_S3 && deep_s3_enabled()) {
267 if (config->deep_sx_config & DSX_EN_LAN_WAKE_PIN)
268 gpe0_en[GPE_STD] |= LAN_WAK_EN;
269 if (config->deep_sx_config & DSX_EN_WAKE_PIN)
270 *pm1_en |= PCIEXPWAK_STS;