blob: 4794a998f97058a9e94b0cd2deb007a2838dd430 [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
Furquan Shaikh76cedd22020-05-02 10:24:23 -07003#include <acpi/acpi.h>
Kyösti Mälkki0c1dd9c2020-06-17 23:37:49 +03004#include <acpi/acpi_gnvs.h>
Kyösti Mälkki27872372021-01-21 16:05:26 +02005#include <acpi/acpi_pm.h>
Furquan Shaikh76cedd22020-05-02 10:24:23 -07006#include <acpi/acpigen.h>
robbie zhangb45dde02015-10-01 17:21:33 -07007#include <arch/cpu.h>
Duncan Lauriedb54a672015-09-04 14:19:35 -07008#include <arch/ioapic.h>
Lee Leahyb0005132015-05-12 18:19:47 -07009#include <arch/smp/mpspec.h>
Lee Leahyb0005132015-05-12 18:19:47 -070010#include <console/console.h>
Matt Delco9084c3c2018-07-27 14:17:29 -070011#include <cpu/intel/common/common.h>
Michael Niewöhnerf6611a22020-08-03 16:53:41 +020012#include <intelblocks/acpi.h>
Kyösti Mälkkica71e132021-01-15 05:06:35 +020013#include <intelblocks/acpi_wake_source.h>
Barnali Sarkar0a203d12017-05-04 18:02:17 +053014#include <intelblocks/cpulib.h>
Michael Niewöhnerf6611a22020-08-03 16:53:41 +020015#include <intelblocks/pmclib.h>
Pratik Prajapati418535e2017-10-11 16:12:21 -070016#include <intelblocks/sgx.h>
Lee Leahyb0005132015-05-12 18:19:47 -070017#include <soc/cpu.h>
Lee Leahyb0005132015-05-12 18:19:47 -070018#include <soc/msr.h>
Lee Leahyb0005132015-05-12 18:19:47 -070019#include <soc/pm.h>
Naresh G Solankia2d40622016-08-30 20:47:13 +053020#include <soc/ramstage.h>
Nico Huberc37b0e32017-09-18 20:03:46 +020021#include <soc/systemagent.h>
robbie zhangb45dde02015-10-01 17:21:33 -070022#include <string.h>
23#include <types.h>
Lee Leahyb0005132015-05-12 18:19:47 -070024
Elyes HAOUASc3385072019-03-21 15:38:06 +010025#include "chip.h"
26
Lee Leahyb0005132015-05-12 18:19:47 -070027/*
Martin Roth26f97f92021-10-01 14:53:22 -060028 * List of supported C-states in this processor.
Lee Leahyb0005132015-05-12 18:19:47 -070029 */
30enum {
Lee Leahy1d14b3e2015-05-12 18:23:27 -070031 C_STATE_C0, /* 0 */
32 C_STATE_C1, /* 1 */
33 C_STATE_C1E, /* 2 */
34 C_STATE_C3, /* 3 */
35 C_STATE_C6_SHORT_LAT, /* 4 */
36 C_STATE_C6_LONG_LAT, /* 5 */
37 C_STATE_C7_SHORT_LAT, /* 6 */
38 C_STATE_C7_LONG_LAT, /* 7 */
39 C_STATE_C7S_SHORT_LAT, /* 8 */
40 C_STATE_C7S_LONG_LAT, /* 9 */
41 C_STATE_C8, /* 10 */
42 C_STATE_C9, /* 11 */
43 C_STATE_C10, /* 12 */
Lee Leahyb0005132015-05-12 18:19:47 -070044 NUM_C_STATES
45};
Lee Leahy1d14b3e2015-05-12 18:23:27 -070046#define MWAIT_RES(state, sub_state) \
47 { \
48 .addrl = (((state) << 4) | (sub_state)), \
49 .space_id = ACPI_ADDRESS_SPACE_FIXED, \
50 .bit_width = ACPI_FFIXEDHW_VENDOR_INTEL, \
51 .bit_offset = ACPI_FFIXEDHW_CLASS_MWAIT, \
52 .access_size = ACPI_FFIXEDHW_FLAG_HW_COORD, \
Lee Leahyb0005132015-05-12 18:19:47 -070053 }
54
55static acpi_cstate_t cstate_map[NUM_C_STATES] = {
56 [C_STATE_C0] = { },
57 [C_STATE_C1] = {
58 .latency = 0,
robbie zhangc16b1fd2015-09-11 14:25:15 -070059 .power = C1_POWER,
Lee Leahy1d14b3e2015-05-12 18:23:27 -070060 .resource = MWAIT_RES(0, 0),
Lee Leahyb0005132015-05-12 18:19:47 -070061 },
62 [C_STATE_C1E] = {
63 .latency = 0,
robbie zhangc16b1fd2015-09-11 14:25:15 -070064 .power = C1_POWER,
Lee Leahy1d14b3e2015-05-12 18:23:27 -070065 .resource = MWAIT_RES(0, 1),
Lee Leahyb0005132015-05-12 18:19:47 -070066 },
67 [C_STATE_C3] = {
68 .latency = C_STATE_LATENCY_FROM_LAT_REG(0),
robbie zhangc16b1fd2015-09-11 14:25:15 -070069 .power = C3_POWER,
Lee Leahyb0005132015-05-12 18:19:47 -070070 .resource = MWAIT_RES(1, 0),
71 },
72 [C_STATE_C6_SHORT_LAT] = {
73 .latency = C_STATE_LATENCY_FROM_LAT_REG(1),
robbie zhangc16b1fd2015-09-11 14:25:15 -070074 .power = C6_POWER,
Lee Leahyb0005132015-05-12 18:19:47 -070075 .resource = MWAIT_RES(2, 0),
76 },
77 [C_STATE_C6_LONG_LAT] = {
78 .latency = C_STATE_LATENCY_FROM_LAT_REG(2),
robbie zhangc16b1fd2015-09-11 14:25:15 -070079 .power = C6_POWER,
Lee Leahyb0005132015-05-12 18:19:47 -070080 .resource = MWAIT_RES(2, 1),
81 },
82 [C_STATE_C7_SHORT_LAT] = {
83 .latency = C_STATE_LATENCY_FROM_LAT_REG(1),
robbie zhangc16b1fd2015-09-11 14:25:15 -070084 .power = C7_POWER,
Lee Leahyb0005132015-05-12 18:19:47 -070085 .resource = MWAIT_RES(3, 0),
86 },
87 [C_STATE_C7_LONG_LAT] = {
88 .latency = C_STATE_LATENCY_FROM_LAT_REG(2),
robbie zhangc16b1fd2015-09-11 14:25:15 -070089 .power = C7_POWER,
Lee Leahyb0005132015-05-12 18:19:47 -070090 .resource = MWAIT_RES(3, 1),
91 },
92 [C_STATE_C7S_SHORT_LAT] = {
93 .latency = C_STATE_LATENCY_FROM_LAT_REG(1),
robbie zhangc16b1fd2015-09-11 14:25:15 -070094 .power = C7_POWER,
Lee Leahyb0005132015-05-12 18:19:47 -070095 .resource = MWAIT_RES(3, 2),
96 },
97 [C_STATE_C7S_LONG_LAT] = {
98 .latency = C_STATE_LATENCY_FROM_LAT_REG(2),
robbie zhangc16b1fd2015-09-11 14:25:15 -070099 .power = C7_POWER,
Lee Leahyb0005132015-05-12 18:19:47 -0700100 .resource = MWAIT_RES(3, 3),
101 },
102 [C_STATE_C8] = {
103 .latency = C_STATE_LATENCY_FROM_LAT_REG(3),
robbie zhangc16b1fd2015-09-11 14:25:15 -0700104 .power = C8_POWER,
Lee Leahyb0005132015-05-12 18:19:47 -0700105 .resource = MWAIT_RES(4, 0),
106 },
107 [C_STATE_C9] = {
108 .latency = C_STATE_LATENCY_FROM_LAT_REG(4),
robbie zhangc16b1fd2015-09-11 14:25:15 -0700109 .power = C9_POWER,
Lee Leahyb0005132015-05-12 18:19:47 -0700110 .resource = MWAIT_RES(5, 0),
111 },
112 [C_STATE_C10] = {
113 .latency = C_STATE_LATENCY_FROM_LAT_REG(5),
robbie zhangc16b1fd2015-09-11 14:25:15 -0700114 .power = C10_POWER,
Lee Leahyb0005132015-05-12 18:19:47 -0700115 .resource = MWAIT_RES(6, 0),
116 },
117};
118
Lee Leahy1d14b3e2015-05-12 18:23:27 -0700119static int cstate_set_s0ix[] = {
Lee Leahyb0005132015-05-12 18:19:47 -0700120 C_STATE_C1E,
121 C_STATE_C7S_LONG_LAT,
122 C_STATE_C10
123};
124
Lee Leahy1d14b3e2015-05-12 18:23:27 -0700125static int cstate_set_non_s0ix[] = {
Lee Leahyb0005132015-05-12 18:19:47 -0700126 C_STATE_C1E,
127 C_STATE_C3,
Lee Leahy1d14b3e2015-05-12 18:23:27 -0700128 C_STATE_C7S_LONG_LAT,
Lee Leahyb0005132015-05-12 18:19:47 -0700129};
130
Patrick Georgid2398192021-10-19 20:59:35 +0200131const acpi_cstate_t *soc_get_cstate_map(size_t *entries)
Lee Leahyb0005132015-05-12 18:19:47 -0700132{
Michael Niewöhnerf6611a22020-08-03 16:53:41 +0200133 static acpi_cstate_t map[MAX(ARRAY_SIZE(cstate_set_s0ix),
134 ARRAY_SIZE(cstate_set_non_s0ix))];
135 int *set;
136 int i;
Lee Leahyb0005132015-05-12 18:19:47 -0700137
Michael Niewöhnerf6611a22020-08-03 16:53:41 +0200138 config_t *config = config_of_soc();
Lee Leahyb0005132015-05-12 18:19:47 -0700139
Michael Niewöhnerf6611a22020-08-03 16:53:41 +0200140 int is_s0ix_enable = config->s0ix_enable;
Lee Leahyb0005132015-05-12 18:19:47 -0700141
Michael Niewöhnerf6611a22020-08-03 16:53:41 +0200142 if (is_s0ix_enable) {
143 *entries = ARRAY_SIZE(cstate_set_s0ix);
144 set = cstate_set_s0ix;
145 } else {
146 *entries = ARRAY_SIZE(cstate_set_non_s0ix);
147 set = cstate_set_non_s0ix;
148 }
149
150 for (i = 0; i < *entries; i++) {
151 memcpy(&map[i], &cstate_map[set[i]], sizeof(acpi_cstate_t));
152 map[i].ctype = i + 1;
153 }
154 return map;
155}
156
157void soc_power_states_generation(int core_id, int cores_per_package)
158{
159 config_t *config = config_of_soc();
160
161 /* Generate P-state tables */
162 if (config->eist_enable)
163 generate_p_state_entries(core_id, cores_per_package);
164}
165
166uint32_t soc_read_sci_irq_select(void)
167{
168 return read32p(soc_read_pmc_base() + IRQ_REG);
Lee Leahyb0005132015-05-12 18:19:47 -0700169}
170
Kyösti Mälkkic2b0a4f2020-06-28 22:39:59 +0300171void soc_fill_gnvs(struct global_nvs *gnvs)
Lee Leahyb0005132015-05-12 18:19:47 -0700172{
Kyösti Mälkkid5f645c2019-09-28 00:20:27 +0300173 const struct soc_intel_skylake_config *config = config_of_soc();
Duncan Laurie7fce30c2015-09-04 13:53:14 -0700174
Duncan Laurie7fce30c2015-09-04 13:53:14 -0700175 /* Enable DPTF based on mainboard configuration */
176 gnvs->dpte = config->dptf_enable;
Duncan Laurie3d3b76b2016-02-25 08:45:43 -0800177
Furquan Shaikh3bfe3402016-10-18 14:25:25 -0700178 /* Set USB2/USB3 wake enable bitmaps. */
179 gnvs->u2we = config->usb2_wake_enable_bitmap;
180 gnvs->u3we = config->usb3_wake_enable_bitmap;
Pratik Prajapati418535e2017-10-11 16:12:21 -0700181
Michael Niewöhner7736bfc2019-10-22 23:05:06 +0200182 if (CONFIG(SOC_INTEL_COMMON_BLOCK_SGX_ENABLE))
Pratik Prajapati418535e2017-10-11 16:12:21 -0700183 sgx_fill_gnvs(gnvs);
Subrata Banikb6df6b02020-01-03 15:29:02 +0530184
185 /* Fill in Above 4GB MMIO resource */
186 sa_fill_gnvs(gnvs);
Lee Leahyb0005132015-05-12 18:19:47 -0700187}
188
Michael Niewöhnerf6611a22020-08-03 16:53:41 +0200189static unsigned long soc_fill_dmar(unsigned long current)
Nico Huberc37b0e32017-09-18 20:03:46 +0200190{
Nico Huberc37b0e32017-09-18 20:03:46 +0200191 const u32 gfx_vtbar = MCHBAR32(GFXVTBAR) & ~0xfff;
192 const bool gfxvten = MCHBAR32(GFXVTBAR) & 1;
193
194 /* iGFX has to be enabled, GFXVTBAR set and in 32-bit space. */
Angel Pons96a80132020-08-03 12:29:41 +0200195 const bool emit_igd =
Angel Pons7ff3f312021-06-23 12:13:57 +0200196 is_devfn_enabled(SA_DEVFN_IGD) &&
Angel Pons96a80132020-08-03 12:29:41 +0200197 gfx_vtbar && gfxvten &&
198 !MCHBAR32(GFXVTBAR + 4);
199
200 /* First, add DRHD entries */
201 if (emit_igd) {
202 const unsigned long tmp = current;
Nico Huberc37b0e32017-09-18 20:03:46 +0200203
204 current += acpi_create_dmar_drhd(current, 0, 0, gfx_vtbar);
Matt DeVillier7866d492018-03-29 14:59:57 +0200205 current += acpi_create_dmar_ds_pci(current, 0, 2, 0);
Nico Huberc37b0e32017-09-18 20:03:46 +0200206
207 acpi_dmar_drhd_fixup(tmp, current);
208 }
209
Nico Huberc37b0e32017-09-18 20:03:46 +0200210 const u32 vtvc0bar = MCHBAR32(VTVC0BAR) & ~0xfff;
211 const bool vtvc0en = MCHBAR32(VTVC0BAR) & 1;
212
213 /* General VTBAR has to be set and in 32-bit space. */
Angel Ponsef879a82019-08-30 19:42:23 +0200214 if (vtvc0bar && vtvc0en && !MCHBAR32(VTVC0BAR + 4)) {
Nico Huberc37b0e32017-09-18 20:03:46 +0200215 const unsigned long tmp = current;
216
Angel Ponsef879a82019-08-30 19:42:23 +0200217 current += acpi_create_dmar_drhd(current, DRHD_INCLUDE_PCI_ALL, 0, vtvc0bar);
Nico Huberc37b0e32017-09-18 20:03:46 +0200218
Angel Ponsef879a82019-08-30 19:42:23 +0200219 current += acpi_create_dmar_ds_ioapic(current, 2, V_P2SB_IBDF_BUS,
220 V_P2SB_IBDF_DEV, V_P2SB_IBDF_FUN);
Nico Huberc37b0e32017-09-18 20:03:46 +0200221
Angel Ponsef879a82019-08-30 19:42:23 +0200222 current += acpi_create_dmar_ds_msi_hpet(current, 0, V_P2SB_HBDF_BUS,
223 V_P2SB_HBDF_DEV, V_P2SB_HBDF_FUN);
Nico Huberc37b0e32017-09-18 20:03:46 +0200224
225 acpi_dmar_drhd_fixup(tmp, current);
226 }
227
Angel Pons96a80132020-08-03 12:29:41 +0200228 /* Then, add RMRR entries after all DRHD entries */
229 if (emit_igd) {
230 const unsigned long tmp = current;
231
232 current += acpi_create_dmar_rmrr(current, 0,
233 sa_get_gsm_base(), sa_get_tolud_base() - 1);
234 current += acpi_create_dmar_ds_pci(current, 0, 2, 0);
235 acpi_dmar_rmrr_fixup(tmp, current);
236 }
237
Nico Huberc37b0e32017-09-18 20:03:46 +0200238 return current;
239}
240
Michael Niewöhnerf6611a22020-08-03 16:53:41 +0200241unsigned long sa_write_acpi_tables(const struct device *const dev,
242 unsigned long current,
243 struct acpi_rsdp *const rsdp)
Nico Huberc37b0e32017-09-18 20:03:46 +0200244{
Nico Huberc37b0e32017-09-18 20:03:46 +0200245 acpi_dmar_t *const dmar = (acpi_dmar_t *)current;
246
247 /* Create DMAR table only if we have VT-d capability. */
Sean Rhodes66c80622021-07-13 07:23:22 +0100248 if (!soc_vtd_enabled())
Nico Huberc37b0e32017-09-18 20:03:46 +0200249 return current;
250
251 printk(BIOS_DEBUG, "ACPI: * DMAR\n");
Michael Niewöhnerf6611a22020-08-03 16:53:41 +0200252 acpi_create_dmar(dmar, DMAR_INTR_REMAP, soc_fill_dmar);
Nico Huberc37b0e32017-09-18 20:03:46 +0200253 current += dmar->header.length;
254 current = acpi_align_current(current);
255 acpi_add_table(rsdp, dmar);
256
257 return current;
258}
259
Michael Niewöhnerf6611a22020-08-03 16:53:41 +0200260int soc_madt_sci_irq_polarity(int sci)
Angel Ponse4844ce2021-04-17 12:49:08 +0200261{
Lee Leahyb0005132015-05-12 18:19:47 -0700262 if (sci >= 20)
Michael Niewöhnerf6611a22020-08-03 16:53:41 +0200263 return MP_IRQ_POLARITY_LOW;
Lee Leahyb0005132015-05-12 18:19:47 -0700264 else
Michael Niewöhnerf6611a22020-08-03 16:53:41 +0200265 return MP_IRQ_POLARITY_HIGH;
Lee Leahyb0005132015-05-12 18:19:47 -0700266}
Lee Leahy1d14b3e2015-05-12 18:23:27 -0700267
Michael Niewöhnerf6611a22020-08-03 16:53:41 +0200268void acpi_fill_soc_wake(uint32_t *pm1_en, uint32_t *gpe0_en,
269 const struct chipset_power_state *ps)
Duncan Lauriea1c8b34d2015-09-08 16:12:44 -0700270{
Kyösti Mälkkid5f645c2019-09-28 00:20:27 +0300271 const struct soc_intel_skylake_config *config = config_of_soc();
Duncan Lauriea1c8b34d2015-09-08 16:12:44 -0700272
Michael Niewöhnerf6611a22020-08-03 16:53:41 +0200273 if (ps->prev_sleep_state == ACPI_S3 && deep_s3_enabled()) {
Duncan Laurie95f90202016-10-25 20:07:22 -0700274 if (config->deep_sx_config & DSX_EN_LAN_WAKE_PIN)
Michael Niewöhnerf6611a22020-08-03 16:53:41 +0200275 gpe0_en[GPE_STD] |= LAN_WAK_EN;
Duncan Laurie95f90202016-10-25 20:07:22 -0700276 if (config->deep_sx_config & DSX_EN_WAKE_PIN)
Michael Niewöhnerf6611a22020-08-03 16:53:41 +0200277 *pm1_en |= PCIEXPWAK_STS;
Duncan Laurie95f90202016-10-25 20:07:22 -0700278 }
Duncan Lauriea1c8b34d2015-09-08 16:12:44 -0700279}