blob: fc2b65d16540c4cf6f628b38d2c125bb3a03e880 [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>
Lee Leahyb0005132015-05-12 18:19:47 -070016#include <soc/cpu.h>
Lee Leahyb0005132015-05-12 18:19:47 -070017#include <soc/msr.h>
Lee Leahyb0005132015-05-12 18:19:47 -070018#include <soc/pm.h>
Naresh G Solankia2d40622016-08-30 20:47:13 +053019#include <soc/ramstage.h>
Nico Huberc37b0e32017-09-18 20:03:46 +020020#include <soc/systemagent.h>
robbie zhangb45dde02015-10-01 17:21:33 -070021#include <string.h>
22#include <types.h>
Lee Leahyb0005132015-05-12 18:19:47 -070023
Elyes HAOUASc3385072019-03-21 15:38:06 +010024#include "chip.h"
25
Lee Leahyb0005132015-05-12 18:19:47 -070026/*
Martin Roth26f97f92021-10-01 14:53:22 -060027 * List of supported C-states in this processor.
Lee Leahyb0005132015-05-12 18:19:47 -070028 */
29enum {
Lee Leahy1d14b3e2015-05-12 18:23:27 -070030 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 */
Lee Leahyb0005132015-05-12 18:19:47 -070043 NUM_C_STATES
44};
Lee Leahy1d14b3e2015-05-12 18:23:27 -070045#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, \
Lee Leahyb0005132015-05-12 18:19:47 -070052 }
53
54static acpi_cstate_t cstate_map[NUM_C_STATES] = {
55 [C_STATE_C0] = { },
56 [C_STATE_C1] = {
57 .latency = 0,
robbie zhangc16b1fd2015-09-11 14:25:15 -070058 .power = C1_POWER,
Lee Leahy1d14b3e2015-05-12 18:23:27 -070059 .resource = MWAIT_RES(0, 0),
Lee Leahyb0005132015-05-12 18:19:47 -070060 },
61 [C_STATE_C1E] = {
62 .latency = 0,
robbie zhangc16b1fd2015-09-11 14:25:15 -070063 .power = C1_POWER,
Lee Leahy1d14b3e2015-05-12 18:23:27 -070064 .resource = MWAIT_RES(0, 1),
Lee Leahyb0005132015-05-12 18:19:47 -070065 },
66 [C_STATE_C3] = {
67 .latency = C_STATE_LATENCY_FROM_LAT_REG(0),
robbie zhangc16b1fd2015-09-11 14:25:15 -070068 .power = C3_POWER,
Lee Leahyb0005132015-05-12 18:19:47 -070069 .resource = MWAIT_RES(1, 0),
70 },
71 [C_STATE_C6_SHORT_LAT] = {
72 .latency = C_STATE_LATENCY_FROM_LAT_REG(1),
robbie zhangc16b1fd2015-09-11 14:25:15 -070073 .power = C6_POWER,
Lee Leahyb0005132015-05-12 18:19:47 -070074 .resource = MWAIT_RES(2, 0),
75 },
76 [C_STATE_C6_LONG_LAT] = {
77 .latency = C_STATE_LATENCY_FROM_LAT_REG(2),
robbie zhangc16b1fd2015-09-11 14:25:15 -070078 .power = C6_POWER,
Lee Leahyb0005132015-05-12 18:19:47 -070079 .resource = MWAIT_RES(2, 1),
80 },
81 [C_STATE_C7_SHORT_LAT] = {
82 .latency = C_STATE_LATENCY_FROM_LAT_REG(1),
robbie zhangc16b1fd2015-09-11 14:25:15 -070083 .power = C7_POWER,
Lee Leahyb0005132015-05-12 18:19:47 -070084 .resource = MWAIT_RES(3, 0),
85 },
86 [C_STATE_C7_LONG_LAT] = {
87 .latency = C_STATE_LATENCY_FROM_LAT_REG(2),
robbie zhangc16b1fd2015-09-11 14:25:15 -070088 .power = C7_POWER,
Lee Leahyb0005132015-05-12 18:19:47 -070089 .resource = MWAIT_RES(3, 1),
90 },
91 [C_STATE_C7S_SHORT_LAT] = {
92 .latency = C_STATE_LATENCY_FROM_LAT_REG(1),
robbie zhangc16b1fd2015-09-11 14:25:15 -070093 .power = C7_POWER,
Lee Leahyb0005132015-05-12 18:19:47 -070094 .resource = MWAIT_RES(3, 2),
95 },
96 [C_STATE_C7S_LONG_LAT] = {
97 .latency = C_STATE_LATENCY_FROM_LAT_REG(2),
robbie zhangc16b1fd2015-09-11 14:25:15 -070098 .power = C7_POWER,
Lee Leahyb0005132015-05-12 18:19:47 -070099 .resource = MWAIT_RES(3, 3),
100 },
101 [C_STATE_C8] = {
102 .latency = C_STATE_LATENCY_FROM_LAT_REG(3),
robbie zhangc16b1fd2015-09-11 14:25:15 -0700103 .power = C8_POWER,
Lee Leahyb0005132015-05-12 18:19:47 -0700104 .resource = MWAIT_RES(4, 0),
105 },
106 [C_STATE_C9] = {
107 .latency = C_STATE_LATENCY_FROM_LAT_REG(4),
robbie zhangc16b1fd2015-09-11 14:25:15 -0700108 .power = C9_POWER,
Lee Leahyb0005132015-05-12 18:19:47 -0700109 .resource = MWAIT_RES(5, 0),
110 },
111 [C_STATE_C10] = {
112 .latency = C_STATE_LATENCY_FROM_LAT_REG(5),
robbie zhangc16b1fd2015-09-11 14:25:15 -0700113 .power = C10_POWER,
Lee Leahyb0005132015-05-12 18:19:47 -0700114 .resource = MWAIT_RES(6, 0),
115 },
116};
117
Lee Leahy1d14b3e2015-05-12 18:23:27 -0700118static int cstate_set_s0ix[] = {
Lee Leahyb0005132015-05-12 18:19:47 -0700119 C_STATE_C1E,
120 C_STATE_C7S_LONG_LAT,
121 C_STATE_C10
122};
123
Lee Leahy1d14b3e2015-05-12 18:23:27 -0700124static int cstate_set_non_s0ix[] = {
Lee Leahyb0005132015-05-12 18:19:47 -0700125 C_STATE_C1E,
126 C_STATE_C3,
Lee Leahy1d14b3e2015-05-12 18:23:27 -0700127 C_STATE_C7S_LONG_LAT,
Lee Leahyb0005132015-05-12 18:19:47 -0700128};
129
Patrick Georgid2398192021-10-19 20:59:35 +0200130const acpi_cstate_t *soc_get_cstate_map(size_t *entries)
Lee Leahyb0005132015-05-12 18:19:47 -0700131{
Michael Niewöhnerf6611a22020-08-03 16:53:41 +0200132 static acpi_cstate_t map[MAX(ARRAY_SIZE(cstate_set_s0ix),
133 ARRAY_SIZE(cstate_set_non_s0ix))];
134 int *set;
135 int i;
Lee Leahyb0005132015-05-12 18:19:47 -0700136
Michael Niewöhnerf6611a22020-08-03 16:53:41 +0200137 config_t *config = config_of_soc();
Lee Leahyb0005132015-05-12 18:19:47 -0700138
Michael Niewöhnerf6611a22020-08-03 16:53:41 +0200139 int is_s0ix_enable = config->s0ix_enable;
Lee Leahyb0005132015-05-12 18:19:47 -0700140
Michael Niewöhnerf6611a22020-08-03 16:53:41 +0200141 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;
147 }
148
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;
152 }
153 return map;
154}
155
156void soc_power_states_generation(int core_id, int cores_per_package)
157{
158 config_t *config = config_of_soc();
159
160 /* Generate P-state tables */
161 if (config->eist_enable)
162 generate_p_state_entries(core_id, cores_per_package);
163}
164
165uint32_t soc_read_sci_irq_select(void)
166{
167 return read32p(soc_read_pmc_base() + IRQ_REG);
Lee Leahyb0005132015-05-12 18:19:47 -0700168}
169
Kyösti Mälkkic2b0a4f2020-06-28 22:39:59 +0300170void soc_fill_gnvs(struct global_nvs *gnvs)
Lee Leahyb0005132015-05-12 18:19:47 -0700171{
Kyösti Mälkkid5f645c2019-09-28 00:20:27 +0300172 const struct soc_intel_skylake_config *config = config_of_soc();
Duncan Laurie7fce30c2015-09-04 13:53:14 -0700173
Duncan Laurie7fce30c2015-09-04 13:53:14 -0700174 /* Enable DPTF based on mainboard configuration */
175 gnvs->dpte = config->dptf_enable;
Duncan Laurie3d3b76b2016-02-25 08:45:43 -0800176
Furquan Shaikh3bfe3402016-10-18 14:25:25 -0700177 /* Set USB2/USB3 wake enable bitmaps. */
178 gnvs->u2we = config->usb2_wake_enable_bitmap;
179 gnvs->u3we = config->usb3_wake_enable_bitmap;
Pratik Prajapati418535e2017-10-11 16:12:21 -0700180
Subrata Banikb6df6b02020-01-03 15:29:02 +0530181 /* Fill in Above 4GB MMIO resource */
182 sa_fill_gnvs(gnvs);
Lee Leahyb0005132015-05-12 18:19:47 -0700183}
184
Michael Niewöhnerf6611a22020-08-03 16:53:41 +0200185static unsigned long soc_fill_dmar(unsigned long current)
Nico Huberc37b0e32017-09-18 20:03:46 +0200186{
Nico Huberc37b0e32017-09-18 20:03:46 +0200187 const u32 gfx_vtbar = MCHBAR32(GFXVTBAR) & ~0xfff;
188 const bool gfxvten = MCHBAR32(GFXVTBAR) & 1;
189
190 /* iGFX has to be enabled, GFXVTBAR set and in 32-bit space. */
Angel Pons96a80132020-08-03 12:29:41 +0200191 const bool emit_igd =
Angel Pons7ff3f312021-06-23 12:13:57 +0200192 is_devfn_enabled(SA_DEVFN_IGD) &&
Angel Pons96a80132020-08-03 12:29:41 +0200193 gfx_vtbar && gfxvten &&
194 !MCHBAR32(GFXVTBAR + 4);
195
196 /* First, add DRHD entries */
197 if (emit_igd) {
198 const unsigned long tmp = current;
Nico Huberc37b0e32017-09-18 20:03:46 +0200199
200 current += acpi_create_dmar_drhd(current, 0, 0, gfx_vtbar);
Matt DeVillier7866d492018-03-29 14:59:57 +0200201 current += acpi_create_dmar_ds_pci(current, 0, 2, 0);
Nico Huberc37b0e32017-09-18 20:03:46 +0200202
203 acpi_dmar_drhd_fixup(tmp, current);
204 }
205
Nico Huberc37b0e32017-09-18 20:03:46 +0200206 const u32 vtvc0bar = MCHBAR32(VTVC0BAR) & ~0xfff;
207 const bool vtvc0en = MCHBAR32(VTVC0BAR) & 1;
208
209 /* General VTBAR has to be set and in 32-bit space. */
Angel Ponsef879a82019-08-30 19:42:23 +0200210 if (vtvc0bar && vtvc0en && !MCHBAR32(VTVC0BAR + 4)) {
Nico Huberc37b0e32017-09-18 20:03:46 +0200211 const unsigned long tmp = current;
212
Angel Ponsef879a82019-08-30 19:42:23 +0200213 current += acpi_create_dmar_drhd(current, DRHD_INCLUDE_PCI_ALL, 0, vtvc0bar);
Nico Huberc37b0e32017-09-18 20:03:46 +0200214
Angel Ponsef879a82019-08-30 19:42:23 +0200215 current += acpi_create_dmar_ds_ioapic(current, 2, V_P2SB_IBDF_BUS,
216 V_P2SB_IBDF_DEV, V_P2SB_IBDF_FUN);
Nico Huberc37b0e32017-09-18 20:03:46 +0200217
Angel Ponsef879a82019-08-30 19:42:23 +0200218 current += acpi_create_dmar_ds_msi_hpet(current, 0, V_P2SB_HBDF_BUS,
219 V_P2SB_HBDF_DEV, V_P2SB_HBDF_FUN);
Nico Huberc37b0e32017-09-18 20:03:46 +0200220
221 acpi_dmar_drhd_fixup(tmp, current);
222 }
223
Angel Pons96a80132020-08-03 12:29:41 +0200224 /* Then, add RMRR entries after all DRHD entries */
225 if (emit_igd) {
226 const unsigned long tmp = current;
227
228 current += acpi_create_dmar_rmrr(current, 0,
229 sa_get_gsm_base(), sa_get_tolud_base() - 1);
230 current += acpi_create_dmar_ds_pci(current, 0, 2, 0);
231 acpi_dmar_rmrr_fixup(tmp, current);
232 }
233
Nico Huberc37b0e32017-09-18 20:03:46 +0200234 return current;
235}
236
Michael Niewöhnerf6611a22020-08-03 16:53:41 +0200237unsigned long sa_write_acpi_tables(const struct device *const dev,
238 unsigned long current,
239 struct acpi_rsdp *const rsdp)
Nico Huberc37b0e32017-09-18 20:03:46 +0200240{
Nico Huberc37b0e32017-09-18 20:03:46 +0200241 acpi_dmar_t *const dmar = (acpi_dmar_t *)current;
242
243 /* Create DMAR table only if we have VT-d capability. */
Sean Rhodes66c80622021-07-13 07:23:22 +0100244 if (!soc_vtd_enabled())
Nico Huberc37b0e32017-09-18 20:03:46 +0200245 return current;
246
247 printk(BIOS_DEBUG, "ACPI: * DMAR\n");
Michael Niewöhnerf6611a22020-08-03 16:53:41 +0200248 acpi_create_dmar(dmar, DMAR_INTR_REMAP, soc_fill_dmar);
Nico Huberc37b0e32017-09-18 20:03:46 +0200249 current += dmar->header.length;
250 current = acpi_align_current(current);
251 acpi_add_table(rsdp, dmar);
252
253 return current;
254}
255
Michael Niewöhnerf6611a22020-08-03 16:53:41 +0200256int soc_madt_sci_irq_polarity(int sci)
Angel Ponse4844ce2021-04-17 12:49:08 +0200257{
Lee Leahyb0005132015-05-12 18:19:47 -0700258 if (sci >= 20)
Michael Niewöhnerf6611a22020-08-03 16:53:41 +0200259 return MP_IRQ_POLARITY_LOW;
Lee Leahyb0005132015-05-12 18:19:47 -0700260 else
Michael Niewöhnerf6611a22020-08-03 16:53:41 +0200261 return MP_IRQ_POLARITY_HIGH;
Lee Leahyb0005132015-05-12 18:19:47 -0700262}
Lee Leahy1d14b3e2015-05-12 18:23:27 -0700263
Michael Niewöhnerf6611a22020-08-03 16:53:41 +0200264void acpi_fill_soc_wake(uint32_t *pm1_en, uint32_t *gpe0_en,
265 const struct chipset_power_state *ps)
Duncan Lauriea1c8b34d2015-09-08 16:12:44 -0700266{
Kyösti Mälkkid5f645c2019-09-28 00:20:27 +0300267 const struct soc_intel_skylake_config *config = config_of_soc();
Duncan Lauriea1c8b34d2015-09-08 16:12:44 -0700268
Michael Niewöhnerf6611a22020-08-03 16:53:41 +0200269 if (ps->prev_sleep_state == ACPI_S3 && deep_s3_enabled()) {
Duncan Laurie95f90202016-10-25 20:07:22 -0700270 if (config->deep_sx_config & DSX_EN_LAN_WAKE_PIN)
Michael Niewöhnerf6611a22020-08-03 16:53:41 +0200271 gpe0_en[GPE_STD] |= LAN_WAK_EN;
Duncan Laurie95f90202016-10-25 20:07:22 -0700272 if (config->deep_sx_config & DSX_EN_WAKE_PIN)
Michael Niewöhnerf6611a22020-08-03 16:53:41 +0200273 *pm1_en |= PCIEXPWAK_STS;
Duncan Laurie95f90202016-10-25 20:07:22 -0700274 }
Duncan Lauriea1c8b34d2015-09-08 16:12:44 -0700275}