blob: 6a56071a3b74f672a0bd71cf573f1069ac5f195d [file] [log] [blame]
Angel Pons3bd1e3d2020-04-05 15:47:17 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Lee Leahyb0005132015-05-12 18:19:47 -07002
Kyösti Mälkki0c1dd9c2020-06-17 23:37:49 +03003#include <acpi/acpi_gnvs.h>
Kyösti Mälkki27872372021-01-21 16:05:26 +02004#include <acpi/acpi_pm.h>
Elyes Haouasdef74aa2022-10-31 13:44:40 +01005#include <acpi/acpi.h>
Furquan Shaikh76cedd22020-05-02 10:24:23 -07006#include <acpi/acpigen.h>
Duncan Lauriedb54a672015-09-04 14:19:35 -07007#include <arch/ioapic.h>
Lee Leahyb0005132015-05-12 18:19:47 -07008#include <arch/smp/mpspec.h>
Lee Leahyb0005132015-05-12 18:19:47 -07009#include <console/console.h>
Elyes Haouasdef74aa2022-10-31 13:44:40 +010010#include <cpu/cpu.h>
Kyösti Mälkkica71e132021-01-15 05:06:35 +020011#include <intelblocks/acpi_wake_source.h>
Elyes Haouasdef74aa2022-10-31 13:44:40 +010012#include <intelblocks/acpi.h>
Barnali Sarkar0a203d12017-05-04 18:02:17 +053013#include <intelblocks/cpulib.h>
Michael Niewöhnerf6611a22020-08-03 16:53:41 +020014#include <intelblocks/pmclib.h>
Lee Leahyb0005132015-05-12 18:19:47 -070015#include <soc/cpu.h>
Lee Leahyb0005132015-05-12 18:19:47 -070016#include <soc/msr.h>
Lee Leahyb0005132015-05-12 18:19:47 -070017#include <soc/pm.h>
Naresh G Solankia2d40622016-08-30 20:47:13 +053018#include <soc/ramstage.h>
Nico Huberc37b0e32017-09-18 20:03:46 +020019#include <soc/systemagent.h>
robbie zhangb45dde02015-10-01 17:21:33 -070020#include <string.h>
21#include <types.h>
Lee Leahyb0005132015-05-12 18:19:47 -070022
Elyes HAOUASc3385072019-03-21 15:38:06 +010023#include "chip.h"
24
Lee Leahyb0005132015-05-12 18:19:47 -070025/*
Martin Roth26f97f92021-10-01 14:53:22 -060026 * List of supported C-states in this processor.
Lee Leahyb0005132015-05-12 18:19:47 -070027 */
28enum {
Lee Leahy1d14b3e2015-05-12 18:23:27 -070029 C_STATE_C0, /* 0 */
30 C_STATE_C1, /* 1 */
31 C_STATE_C1E, /* 2 */
32 C_STATE_C3, /* 3 */
33 C_STATE_C6_SHORT_LAT, /* 4 */
34 C_STATE_C6_LONG_LAT, /* 5 */
35 C_STATE_C7_SHORT_LAT, /* 6 */
36 C_STATE_C7_LONG_LAT, /* 7 */
37 C_STATE_C7S_SHORT_LAT, /* 8 */
38 C_STATE_C7S_LONG_LAT, /* 9 */
39 C_STATE_C8, /* 10 */
40 C_STATE_C9, /* 11 */
41 C_STATE_C10, /* 12 */
Lee Leahyb0005132015-05-12 18:19:47 -070042 NUM_C_STATES
43};
Lee Leahy1d14b3e2015-05-12 18:23:27 -070044#define MWAIT_RES(state, sub_state) \
45 { \
46 .addrl = (((state) << 4) | (sub_state)), \
47 .space_id = ACPI_ADDRESS_SPACE_FIXED, \
48 .bit_width = ACPI_FFIXEDHW_VENDOR_INTEL, \
49 .bit_offset = ACPI_FFIXEDHW_CLASS_MWAIT, \
50 .access_size = ACPI_FFIXEDHW_FLAG_HW_COORD, \
Lee Leahyb0005132015-05-12 18:19:47 -070051 }
52
53static acpi_cstate_t cstate_map[NUM_C_STATES] = {
54 [C_STATE_C0] = { },
55 [C_STATE_C1] = {
56 .latency = 0,
robbie zhangc16b1fd2015-09-11 14:25:15 -070057 .power = C1_POWER,
Lee Leahy1d14b3e2015-05-12 18:23:27 -070058 .resource = MWAIT_RES(0, 0),
Lee Leahyb0005132015-05-12 18:19:47 -070059 },
60 [C_STATE_C1E] = {
61 .latency = 0,
robbie zhangc16b1fd2015-09-11 14:25:15 -070062 .power = C1_POWER,
Lee Leahy1d14b3e2015-05-12 18:23:27 -070063 .resource = MWAIT_RES(0, 1),
Lee Leahyb0005132015-05-12 18:19:47 -070064 },
65 [C_STATE_C3] = {
66 .latency = C_STATE_LATENCY_FROM_LAT_REG(0),
robbie zhangc16b1fd2015-09-11 14:25:15 -070067 .power = C3_POWER,
Lee Leahyb0005132015-05-12 18:19:47 -070068 .resource = MWAIT_RES(1, 0),
69 },
70 [C_STATE_C6_SHORT_LAT] = {
71 .latency = C_STATE_LATENCY_FROM_LAT_REG(1),
robbie zhangc16b1fd2015-09-11 14:25:15 -070072 .power = C6_POWER,
Lee Leahyb0005132015-05-12 18:19:47 -070073 .resource = MWAIT_RES(2, 0),
74 },
75 [C_STATE_C6_LONG_LAT] = {
76 .latency = C_STATE_LATENCY_FROM_LAT_REG(2),
robbie zhangc16b1fd2015-09-11 14:25:15 -070077 .power = C6_POWER,
Lee Leahyb0005132015-05-12 18:19:47 -070078 .resource = MWAIT_RES(2, 1),
79 },
80 [C_STATE_C7_SHORT_LAT] = {
81 .latency = C_STATE_LATENCY_FROM_LAT_REG(1),
robbie zhangc16b1fd2015-09-11 14:25:15 -070082 .power = C7_POWER,
Lee Leahyb0005132015-05-12 18:19:47 -070083 .resource = MWAIT_RES(3, 0),
84 },
85 [C_STATE_C7_LONG_LAT] = {
86 .latency = C_STATE_LATENCY_FROM_LAT_REG(2),
robbie zhangc16b1fd2015-09-11 14:25:15 -070087 .power = C7_POWER,
Lee Leahyb0005132015-05-12 18:19:47 -070088 .resource = MWAIT_RES(3, 1),
89 },
90 [C_STATE_C7S_SHORT_LAT] = {
91 .latency = C_STATE_LATENCY_FROM_LAT_REG(1),
robbie zhangc16b1fd2015-09-11 14:25:15 -070092 .power = C7_POWER,
Lee Leahyb0005132015-05-12 18:19:47 -070093 .resource = MWAIT_RES(3, 2),
94 },
95 [C_STATE_C7S_LONG_LAT] = {
96 .latency = C_STATE_LATENCY_FROM_LAT_REG(2),
robbie zhangc16b1fd2015-09-11 14:25:15 -070097 .power = C7_POWER,
Lee Leahyb0005132015-05-12 18:19:47 -070098 .resource = MWAIT_RES(3, 3),
99 },
100 [C_STATE_C8] = {
101 .latency = C_STATE_LATENCY_FROM_LAT_REG(3),
robbie zhangc16b1fd2015-09-11 14:25:15 -0700102 .power = C8_POWER,
Lee Leahyb0005132015-05-12 18:19:47 -0700103 .resource = MWAIT_RES(4, 0),
104 },
105 [C_STATE_C9] = {
106 .latency = C_STATE_LATENCY_FROM_LAT_REG(4),
robbie zhangc16b1fd2015-09-11 14:25:15 -0700107 .power = C9_POWER,
Lee Leahyb0005132015-05-12 18:19:47 -0700108 .resource = MWAIT_RES(5, 0),
109 },
110 [C_STATE_C10] = {
111 .latency = C_STATE_LATENCY_FROM_LAT_REG(5),
robbie zhangc16b1fd2015-09-11 14:25:15 -0700112 .power = C10_POWER,
Lee Leahyb0005132015-05-12 18:19:47 -0700113 .resource = MWAIT_RES(6, 0),
114 },
115};
116
Lee Leahy1d14b3e2015-05-12 18:23:27 -0700117static int cstate_set_s0ix[] = {
Lee Leahyb0005132015-05-12 18:19:47 -0700118 C_STATE_C1E,
119 C_STATE_C7S_LONG_LAT,
120 C_STATE_C10
121};
122
Lee Leahy1d14b3e2015-05-12 18:23:27 -0700123static int cstate_set_non_s0ix[] = {
Lee Leahyb0005132015-05-12 18:19:47 -0700124 C_STATE_C1E,
125 C_STATE_C3,
Lee Leahy1d14b3e2015-05-12 18:23:27 -0700126 C_STATE_C7S_LONG_LAT,
Lee Leahyb0005132015-05-12 18:19:47 -0700127};
128
Patrick Georgid2398192021-10-19 20:59:35 +0200129const acpi_cstate_t *soc_get_cstate_map(size_t *entries)
Lee Leahyb0005132015-05-12 18:19:47 -0700130{
Michael Niewöhnerf6611a22020-08-03 16:53:41 +0200131 static acpi_cstate_t map[MAX(ARRAY_SIZE(cstate_set_s0ix),
132 ARRAY_SIZE(cstate_set_non_s0ix))];
133 int *set;
134 int i;
Lee Leahyb0005132015-05-12 18:19:47 -0700135
Michael Niewöhnerf6611a22020-08-03 16:53:41 +0200136 config_t *config = config_of_soc();
Lee Leahyb0005132015-05-12 18:19:47 -0700137
Michael Niewöhnerf6611a22020-08-03 16:53:41 +0200138 int is_s0ix_enable = config->s0ix_enable;
Lee Leahyb0005132015-05-12 18:19:47 -0700139
Michael Niewöhnerf6611a22020-08-03 16:53:41 +0200140 if (is_s0ix_enable) {
141 *entries = ARRAY_SIZE(cstate_set_s0ix);
142 set = cstate_set_s0ix;
143 } else {
144 *entries = ARRAY_SIZE(cstate_set_non_s0ix);
145 set = cstate_set_non_s0ix;
146 }
147
148 for (i = 0; i < *entries; i++) {
149 memcpy(&map[i], &cstate_map[set[i]], sizeof(acpi_cstate_t));
150 map[i].ctype = i + 1;
151 }
152 return map;
153}
154
155void soc_power_states_generation(int core_id, int cores_per_package)
156{
157 config_t *config = config_of_soc();
158
159 /* Generate P-state tables */
160 if (config->eist_enable)
161 generate_p_state_entries(core_id, cores_per_package);
162}
163
164uint32_t soc_read_sci_irq_select(void)
165{
166 return read32p(soc_read_pmc_base() + IRQ_REG);
Lee Leahyb0005132015-05-12 18:19:47 -0700167}
168
Kyösti Mälkkic2b0a4f2020-06-28 22:39:59 +0300169void soc_fill_gnvs(struct global_nvs *gnvs)
Lee Leahyb0005132015-05-12 18:19:47 -0700170{
Kyösti Mälkkid5f645c2019-09-28 00:20:27 +0300171 const struct soc_intel_skylake_config *config = config_of_soc();
Duncan Laurie7fce30c2015-09-04 13:53:14 -0700172
Duncan Laurie7fce30c2015-09-04 13:53:14 -0700173 /* Enable DPTF based on mainboard configuration */
174 gnvs->dpte = config->dptf_enable;
Duncan Laurie3d3b76b2016-02-25 08:45:43 -0800175
Furquan Shaikh3bfe3402016-10-18 14:25:25 -0700176 /* Set USB2/USB3 wake enable bitmaps. */
177 gnvs->u2we = config->usb2_wake_enable_bitmap;
178 gnvs->u3we = config->usb3_wake_enable_bitmap;
Lee Leahyb0005132015-05-12 18:19:47 -0700179}
180
Michael Niewöhnerf6611a22020-08-03 16:53:41 +0200181static unsigned long soc_fill_dmar(unsigned long current)
Nico Huberc37b0e32017-09-18 20:03:46 +0200182{
Nico Huberc37b0e32017-09-18 20:03:46 +0200183 const u32 gfx_vtbar = MCHBAR32(GFXVTBAR) & ~0xfff;
184 const bool gfxvten = MCHBAR32(GFXVTBAR) & 1;
185
186 /* iGFX has to be enabled, GFXVTBAR set and in 32-bit space. */
Angel Pons96a80132020-08-03 12:29:41 +0200187 const bool emit_igd =
Angel Pons7ff3f312021-06-23 12:13:57 +0200188 is_devfn_enabled(SA_DEVFN_IGD) &&
Angel Pons96a80132020-08-03 12:29:41 +0200189 gfx_vtbar && gfxvten &&
190 !MCHBAR32(GFXVTBAR + 4);
191
192 /* First, add DRHD entries */
193 if (emit_igd) {
194 const unsigned long tmp = current;
Nico Huberc37b0e32017-09-18 20:03:46 +0200195
196 current += acpi_create_dmar_drhd(current, 0, 0, gfx_vtbar);
Matt DeVillier7866d492018-03-29 14:59:57 +0200197 current += acpi_create_dmar_ds_pci(current, 0, 2, 0);
Nico Huberc37b0e32017-09-18 20:03:46 +0200198
199 acpi_dmar_drhd_fixup(tmp, current);
200 }
201
Nico Huberc37b0e32017-09-18 20:03:46 +0200202 const u32 vtvc0bar = MCHBAR32(VTVC0BAR) & ~0xfff;
203 const bool vtvc0en = MCHBAR32(VTVC0BAR) & 1;
204
205 /* General VTBAR has to be set and in 32-bit space. */
Angel Ponsef879a82019-08-30 19:42:23 +0200206 if (vtvc0bar && vtvc0en && !MCHBAR32(VTVC0BAR + 4)) {
Nico Huberc37b0e32017-09-18 20:03:46 +0200207 const unsigned long tmp = current;
208
Angel Ponsef879a82019-08-30 19:42:23 +0200209 current += acpi_create_dmar_drhd(current, DRHD_INCLUDE_PCI_ALL, 0, vtvc0bar);
Nico Huberc37b0e32017-09-18 20:03:46 +0200210
Arthur Heymansd90154c2022-12-02 13:27:35 +0100211 current += acpi_create_dmar_ds_ioapic_from_hw(current, IO_APIC_ADDR, V_P2SB_IBDF_BUS,
Angel Ponsef879a82019-08-30 19:42:23 +0200212 V_P2SB_IBDF_DEV, V_P2SB_IBDF_FUN);
Nico Huberc37b0e32017-09-18 20:03:46 +0200213
Angel Ponsef879a82019-08-30 19:42:23 +0200214 current += acpi_create_dmar_ds_msi_hpet(current, 0, V_P2SB_HBDF_BUS,
215 V_P2SB_HBDF_DEV, V_P2SB_HBDF_FUN);
Nico Huberc37b0e32017-09-18 20:03:46 +0200216
217 acpi_dmar_drhd_fixup(tmp, current);
218 }
219
Angel Pons96a80132020-08-03 12:29:41 +0200220 /* Then, add RMRR entries after all DRHD entries */
221 if (emit_igd) {
222 const unsigned long tmp = current;
223
224 current += acpi_create_dmar_rmrr(current, 0,
225 sa_get_gsm_base(), sa_get_tolud_base() - 1);
226 current += acpi_create_dmar_ds_pci(current, 0, 2, 0);
227 acpi_dmar_rmrr_fixup(tmp, current);
228 }
229
Nico Huberc37b0e32017-09-18 20:03:46 +0200230 return current;
231}
232
Michael Niewöhnerf6611a22020-08-03 16:53:41 +0200233unsigned long sa_write_acpi_tables(const struct device *const dev,
234 unsigned long current,
235 struct acpi_rsdp *const rsdp)
Nico Huberc37b0e32017-09-18 20:03:46 +0200236{
Nico Huberc37b0e32017-09-18 20:03:46 +0200237 acpi_dmar_t *const dmar = (acpi_dmar_t *)current;
238
239 /* Create DMAR table only if we have VT-d capability. */
Sean Rhodes66c80622021-07-13 07:23:22 +0100240 if (!soc_vtd_enabled())
Nico Huberc37b0e32017-09-18 20:03:46 +0200241 return current;
242
243 printk(BIOS_DEBUG, "ACPI: * DMAR\n");
Michael Niewöhnerf6611a22020-08-03 16:53:41 +0200244 acpi_create_dmar(dmar, DMAR_INTR_REMAP, soc_fill_dmar);
Nico Huberc37b0e32017-09-18 20:03:46 +0200245 current += dmar->header.length;
246 current = acpi_align_current(current);
247 acpi_add_table(rsdp, dmar);
248
249 return current;
250}
251
Michael Niewöhnerf6611a22020-08-03 16:53:41 +0200252int soc_madt_sci_irq_polarity(int sci)
Angel Ponse4844ce2021-04-17 12:49:08 +0200253{
Lee Leahyb0005132015-05-12 18:19:47 -0700254 if (sci >= 20)
Michael Niewöhnerf6611a22020-08-03 16:53:41 +0200255 return MP_IRQ_POLARITY_LOW;
Lee Leahyb0005132015-05-12 18:19:47 -0700256 else
Michael Niewöhnerf6611a22020-08-03 16:53:41 +0200257 return MP_IRQ_POLARITY_HIGH;
Lee Leahyb0005132015-05-12 18:19:47 -0700258}
Lee Leahy1d14b3e2015-05-12 18:23:27 -0700259
Michael Niewöhnerf6611a22020-08-03 16:53:41 +0200260void acpi_fill_soc_wake(uint32_t *pm1_en, uint32_t *gpe0_en,
261 const struct chipset_power_state *ps)
Duncan Lauriea1c8b34d2015-09-08 16:12:44 -0700262{
Kyösti Mälkkid5f645c2019-09-28 00:20:27 +0300263 const struct soc_intel_skylake_config *config = config_of_soc();
Duncan Lauriea1c8b34d2015-09-08 16:12:44 -0700264
Michael Niewöhnerf6611a22020-08-03 16:53:41 +0200265 if (ps->prev_sleep_state == ACPI_S3 && deep_s3_enabled()) {
Duncan Laurie95f90202016-10-25 20:07:22 -0700266 if (config->deep_sx_config & DSX_EN_LAN_WAKE_PIN)
Michael Niewöhnerf6611a22020-08-03 16:53:41 +0200267 gpe0_en[GPE_STD] |= LAN_WAK_EN;
Duncan Laurie95f90202016-10-25 20:07:22 -0700268 if (config->deep_sx_config & DSX_EN_WAKE_PIN)
Michael Niewöhnerf6611a22020-08-03 16:53:41 +0200269 *pm1_en |= PCIEXPWAK_STS;
Duncan Laurie95f90202016-10-25 20:07:22 -0700270 }
Duncan Lauriea1c8b34d2015-09-08 16:12:44 -0700271}