• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <acpi/acpi.h>
4 #include <acpi/acpi_gnvs.h>
5 #include <acpi/acpigen.h>
6 #include <arch/ioapic.h>
7 #include <arch/smp/mpspec.h>
8 #include <console/console.h>
9 #include <device/mmio.h>
10 #include <device/pci_ops.h>
11 #include <intelblocks/cpulib.h>
12 #include <intelblocks/pmclib.h>
13 #include <intelblocks/acpi.h>
14 #include <intelblocks/p2sb.h>
15 #include <soc/cpu.h>
16 #include <soc/iomap.h>
17 #include <soc/nvs.h>
18 #include <soc/pci_devs.h>
19 #include <soc/pm.h>
20 #include <soc/systemagent.h>
21 
22 #include "chip.h"
23 
24 /*
25  * List of supported C-states in this processor.
26  */
27 enum {
28 	C_STATE_C0,		/* 0 */
29 	C_STATE_C1,		/* 1 */
30 	C_STATE_C1E,		/* 2 */
31 	C_STATE_C6_SHORT_LAT,	/* 3 */
32 	C_STATE_C6_LONG_LAT,	/* 4 */
33 	C_STATE_C7_SHORT_LAT,	/* 5 */
34 	C_STATE_C7_LONG_LAT,	/* 6 */
35 	C_STATE_C7S_SHORT_LAT,	/* 7 */
36 	C_STATE_C7S_LONG_LAT,	/* 8 */
37 	C_STATE_C8,		/* 9 */
38 	C_STATE_C9,		/* 10 */
39 	C_STATE_C10,		/* 11 */
40 	NUM_C_STATES
41 };
42 
43 static const acpi_cstate_t cstate_map[NUM_C_STATES] = {
44 	[C_STATE_C0] = {},
45 	[C_STATE_C1] = {
46 		.latency = 0,
47 		.power = C1_POWER,
48 		.resource = MWAIT_RES(0, 0),
49 	},
50 	[C_STATE_C1E] = {
51 		.latency = 0,
52 		.power = C1_POWER,
53 		.resource = MWAIT_RES(0, 1),
54 	},
55 	[C_STATE_C6_SHORT_LAT] = {
56 		.latency = C_STATE_LATENCY_FROM_LAT_REG(1),
57 		.power = C6_POWER,
58 		.resource = MWAIT_RES(2, 0),
59 	},
60 	[C_STATE_C6_LONG_LAT] = {
61 		.latency = C_STATE_LATENCY_FROM_LAT_REG(2),
62 		.power = C6_POWER,
63 		.resource = MWAIT_RES(2, 1),
64 	},
65 	[C_STATE_C7_SHORT_LAT] = {
66 		.latency = C_STATE_LATENCY_FROM_LAT_REG(1),
67 		.power = C7_POWER,
68 		.resource = MWAIT_RES(3, 0),
69 	},
70 	[C_STATE_C7_LONG_LAT] = {
71 		.latency = C_STATE_LATENCY_FROM_LAT_REG(2),
72 		.power = C7_POWER,
73 		.resource = MWAIT_RES(3, 1),
74 	},
75 	[C_STATE_C7S_SHORT_LAT] = {
76 		.latency = C_STATE_LATENCY_FROM_LAT_REG(1),
77 		.power = C7_POWER,
78 		.resource = MWAIT_RES(3, 2),
79 	},
80 	[C_STATE_C7S_LONG_LAT] = {
81 		.latency = C_STATE_LATENCY_FROM_LAT_REG(2),
82 		.power = C7_POWER,
83 		.resource = MWAIT_RES(3, 3),
84 	},
85 	[C_STATE_C8] = {
86 		.latency = C_STATE_LATENCY_FROM_LAT_REG(3),
87 		.power = C8_POWER,
88 		.resource = MWAIT_RES(4, 0),
89 	},
90 	[C_STATE_C9] = {
91 		.latency = C_STATE_LATENCY_FROM_LAT_REG(4),
92 		.power = C9_POWER,
93 		.resource = MWAIT_RES(5, 0),
94 	},
95 	[C_STATE_C10] = {
96 		.latency = C_STATE_LATENCY_FROM_LAT_REG(5),
97 		.power = C10_POWER,
98 		.resource = MWAIT_RES(6, 0),
99 	},
100 };
101 
102 static int cstate_set_non_s0ix[] = {
103 	C_STATE_C1E,
104 	C_STATE_C6_LONG_LAT,
105 	C_STATE_C7S_LONG_LAT
106 };
107 
108 static int cstate_set_s0ix[] = {
109 	C_STATE_C1E,
110 	C_STATE_C7S_LONG_LAT,
111 	C_STATE_C10
112 };
113 
soc_get_cstate_map(size_t * entries)114 const acpi_cstate_t *soc_get_cstate_map(size_t *entries)
115 {
116 	static acpi_cstate_t map[MAX(ARRAY_SIZE(cstate_set_s0ix),
117 				ARRAY_SIZE(cstate_set_non_s0ix))];
118 	int *set;
119 	int i;
120 
121 	config_t *config = config_of_soc();
122 
123 	int is_s0ix_enable = config->s0ix_enable;
124 
125 	if (is_s0ix_enable) {
126 		*entries = ARRAY_SIZE(cstate_set_s0ix);
127 		set = cstate_set_s0ix;
128 	} else {
129 		*entries = ARRAY_SIZE(cstate_set_non_s0ix);
130 		set = cstate_set_non_s0ix;
131 	}
132 
133 	for (i = 0; i < *entries; i++) {
134 		map[i] = cstate_map[set[i]];
135 		map[i].ctype = i + 1;
136 	}
137 	return map;
138 }
139 
soc_power_states_generation(int core_id,int cores_per_package)140 void soc_power_states_generation(int core_id, int cores_per_package)
141 {
142 	config_t *config = config_of_soc();
143 
144 	/* Generate P-state tables */
145 	if (config->eist_enable)
146 		generate_p_state_entries(core_id, cores_per_package);
147 }
148 
soc_fill_fadt(acpi_fadt_t * fadt)149 void soc_fill_fadt(acpi_fadt_t *fadt)
150 {
151 	const uint16_t pmbase = ACPI_BASE_ADDRESS;
152 	const struct soc_intel_cannonlake_config *config;
153 	config = config_of_soc();
154 
155 	fadt->pm_tmr_blk = pmbase + PM1_TMR;
156 	fadt->pm_tmr_len = 4;
157 
158 	fill_fadt_extended_pm_io(fadt);
159 
160 	if (config->s0ix_enable)
161 		fadt->flags |= ACPI_FADT_LOW_PWR_IDLE_S0;
162 }
163 
164 static struct min_sleep_state min_pci_sleep_states[] = {
165 	{ SA_DEVFN_ROOT,	ACPI_DEVICE_SLEEP_D3 },
166 	{ SA_DEVFN_PEG0,	ACPI_DEVICE_SLEEP_D3 },
167 	{ SA_DEVFN_PEG1,	ACPI_DEVICE_SLEEP_D3 },
168 	{ SA_DEVFN_PEG2,	ACPI_DEVICE_SLEEP_D3 },
169 	{ SA_DEVFN_IGD,		ACPI_DEVICE_SLEEP_D3 },
170 	{ SA_DEVFN_TS,		ACPI_DEVICE_SLEEP_D3 },
171 	{ SA_DEVFN_IPU,		ACPI_DEVICE_SLEEP_D3 },
172 	{ SA_DEVFN_GNA,		ACPI_DEVICE_SLEEP_D3 },
173 	{ PCH_DEVFN_UFS,	ACPI_DEVICE_SLEEP_D3 },
174 	{ PCH_DEVFN_GSPI2,	ACPI_DEVICE_SLEEP_D3 },
175 	{ PCH_DEVFN_ISH,	ACPI_DEVICE_SLEEP_D3 },
176 	{ PCH_DEVFN_XHCI,	ACPI_DEVICE_SLEEP_D3 },
177 	{ PCH_DEVFN_USBOTG,	ACPI_DEVICE_SLEEP_D3 },
178 	{ PCH_DEVFN_CNViWIFI,	ACPI_DEVICE_SLEEP_D3 },
179 	{ PCH_DEVFN_SDCARD,	ACPI_DEVICE_SLEEP_D3 },
180 	{ PCH_DEVFN_I2C0,	ACPI_DEVICE_SLEEP_D3 },
181 	{ PCH_DEVFN_I2C1,	ACPI_DEVICE_SLEEP_D3 },
182 	{ PCH_DEVFN_I2C2,	ACPI_DEVICE_SLEEP_D3 },
183 	{ PCH_DEVFN_I2C3,	ACPI_DEVICE_SLEEP_D3 },
184 	{ PCH_DEVFN_CSE,	ACPI_DEVICE_SLEEP_D0 },
185 	{ PCH_DEVFN_SATA,	ACPI_DEVICE_SLEEP_D3 },
186 	{ PCH_DEVFN_I2C4,	ACPI_DEVICE_SLEEP_D3 },
187 	{ PCH_DEVFN_I2C5,	ACPI_DEVICE_SLEEP_D3 },
188 	{ PCH_DEVFN_UART2,	ACPI_DEVICE_SLEEP_D3 },
189 	{ PCH_DEVFN_EMMC,	ACPI_DEVICE_SLEEP_D3 },
190 	{ PCH_DEVFN_PCIE1,	ACPI_DEVICE_SLEEP_D0 },
191 	{ PCH_DEVFN_PCIE2,	ACPI_DEVICE_SLEEP_D0 },
192 	{ PCH_DEVFN_PCIE3,	ACPI_DEVICE_SLEEP_D0 },
193 	{ PCH_DEVFN_PCIE4,	ACPI_DEVICE_SLEEP_D0 },
194 	{ PCH_DEVFN_PCIE5,	ACPI_DEVICE_SLEEP_D0 },
195 	{ PCH_DEVFN_PCIE6,	ACPI_DEVICE_SLEEP_D0 },
196 	{ PCH_DEVFN_PCIE7,	ACPI_DEVICE_SLEEP_D0 },
197 	{ PCH_DEVFN_PCIE8,	ACPI_DEVICE_SLEEP_D0 },
198 	{ PCH_DEVFN_PCIE9,	ACPI_DEVICE_SLEEP_D0 },
199 	{ PCH_DEVFN_PCIE10,	ACPI_DEVICE_SLEEP_D0 },
200 	{ PCH_DEVFN_PCIE11,	ACPI_DEVICE_SLEEP_D0 },
201 	{ PCH_DEVFN_PCIE12,	ACPI_DEVICE_SLEEP_D0 },
202 	{ PCH_DEVFN_PCIE13,	ACPI_DEVICE_SLEEP_D0 },
203 	{ PCH_DEVFN_PCIE14,	ACPI_DEVICE_SLEEP_D0 },
204 	{ PCH_DEVFN_PCIE15,	ACPI_DEVICE_SLEEP_D0 },
205 	{ PCH_DEVFN_PCIE16,	ACPI_DEVICE_SLEEP_D0 },
206 	{ PCH_DEVFN_PCIE17,	ACPI_DEVICE_SLEEP_D0 },
207 	{ PCH_DEVFN_PCIE18,	ACPI_DEVICE_SLEEP_D0 },
208 	{ PCH_DEVFN_PCIE19,	ACPI_DEVICE_SLEEP_D0 },
209 	{ PCH_DEVFN_PCIE20,	ACPI_DEVICE_SLEEP_D0 },
210 	{ PCH_DEVFN_PCIE21,	ACPI_DEVICE_SLEEP_D0 },
211 	{ PCH_DEVFN_PCIE22,	ACPI_DEVICE_SLEEP_D0 },
212 	{ PCH_DEVFN_PCIE23,	ACPI_DEVICE_SLEEP_D0 },
213 	{ PCH_DEVFN_PCIE24,	ACPI_DEVICE_SLEEP_D0 },
214 	{ PCH_DEVFN_UART0,	ACPI_DEVICE_SLEEP_D3 },
215 	{ PCH_DEVFN_UART1,	ACPI_DEVICE_SLEEP_D3 },
216 	{ PCH_DEVFN_GSPI0,	ACPI_DEVICE_SLEEP_D3 },
217 	{ PCH_DEVFN_GSPI1,	ACPI_DEVICE_SLEEP_D3 },
218 	{ PCH_DEVFN_LPC,	ACPI_DEVICE_SLEEP_D0 },
219 	{ PCH_DEVFN_P2SB,	ACPI_DEVICE_SLEEP_D0 },
220 	{ PCH_DEVFN_HDA,	ACPI_DEVICE_SLEEP_D0 },
221 	{ PCH_DEVFN_SMBUS,	ACPI_DEVICE_SLEEP_D0 },
222 	{ PCH_DEVFN_SPI,	ACPI_DEVICE_SLEEP_D3 },
223 	{ PCH_DEVFN_GBE,	ACPI_DEVICE_SLEEP_D3 },
224 	{ PCH_DEVFN_TRACEHUB,	ACPI_DEVICE_SLEEP_D3 },
225 };
226 
soc_get_min_sleep_state_array(size_t * size)227 struct min_sleep_state *soc_get_min_sleep_state_array(size_t *size)
228 {
229 	*size = ARRAY_SIZE(min_pci_sleep_states);
230 	return min_pci_sleep_states;
231 }
232 
soc_read_sci_irq_select(void)233 uint32_t soc_read_sci_irq_select(void)
234 {
235 	return read32p(soc_read_pmc_base() + IRQ_REG);
236 }
237 
soc_fill_gnvs(struct global_nvs * gnvs)238 void soc_fill_gnvs(struct global_nvs *gnvs)
239 {
240 	const struct soc_intel_cannonlake_config *config;
241 	config = config_of_soc();
242 
243 	/* Enable DPTF based on mainboard configuration */
244 	gnvs->dpte = config->dptf_enable;
245 
246 	/* Set USB2/USB3 wake enable bitmaps. */
247 	gnvs->u2we = config->usb2_wake_enable_bitmap;
248 	gnvs->u3we = config->usb3_wake_enable_bitmap;
249 }
250 
soc_madt_sci_irq_polarity(int sci)251 int soc_madt_sci_irq_polarity(int sci)
252 {
253 	return MP_IRQ_POLARITY_HIGH;
254 }
255 
soc_fill_dmar(unsigned long current)256 static unsigned long soc_fill_dmar(unsigned long current)
257 {
258 	uint64_t gfxvtbar = MCHBAR64(GFXVTBAR) & VTBAR_MASK;
259 	bool gfxvten = MCHBAR32(GFXVTBAR) & VTBAR_ENABLED;
260 	const bool emit_igd = is_devfn_enabled(SA_DEVFN_IGD) && gfxvtbar && gfxvten;
261 	if (emit_igd) {
262 		unsigned long tmp = current;
263 
264 		current += acpi_create_dmar_drhd_4k(current, 0, 0, gfxvtbar);
265 		current += acpi_create_dmar_ds_pci(current, 0, 2, 0);
266 
267 		acpi_dmar_drhd_fixup(tmp, current);
268 	}
269 
270 	uint64_t ipuvtbar = MCHBAR64(IPUVTBAR) & VTBAR_MASK;
271 	bool ipuvten = MCHBAR32(IPUVTBAR) & VTBAR_ENABLED;
272 
273 	if (is_devfn_enabled(SA_DEVFN_IPU) && ipuvtbar && ipuvten) {
274 		unsigned long tmp = current;
275 
276 		current += acpi_create_dmar_drhd_4k(current, 0, 0, ipuvtbar);
277 		current += acpi_create_dmar_ds_pci(current, 0, 5, 0);
278 
279 		acpi_dmar_drhd_fixup(tmp, current);
280 	}
281 
282 	uint64_t vtvc0bar = MCHBAR64(VTVC0BAR) & VTBAR_MASK;
283 	bool vtvc0en = MCHBAR32(VTVC0BAR) & VTBAR_ENABLED;
284 
285 	if (vtvc0bar && vtvc0en) {
286 		const unsigned long tmp = current;
287 
288 		current += acpi_create_dmar_drhd_4k(current,
289 				DRHD_INCLUDE_PCI_ALL, 0, vtvc0bar);
290 		current += acpi_create_dmar_ds_ioapic_from_hw(current,
291 				IO_APIC_ADDR, V_P2SB_CFG_IBDF_BUS, V_P2SB_CFG_IBDF_DEV,
292 				V_P2SB_CFG_IBDF_FUNC);
293 		current += acpi_create_dmar_ds_msi_hpet(current,
294 				0, V_P2SB_CFG_HBDF_BUS, V_P2SB_CFG_HBDF_DEV,
295 				V_P2SB_CFG_HBDF_FUNC);
296 
297 		acpi_dmar_drhd_fixup(tmp, current);
298 	}
299 
300 	/* Add RMRR entry after all DRHD entries */
301 	if (emit_igd) {
302 		const unsigned long tmp = current;
303 
304 		current += acpi_create_dmar_rmrr(current, 0,
305 			sa_get_gsm_base(), sa_get_tolud_base() - 1);
306 		current += acpi_create_dmar_ds_pci(current, 0, 2, 0);
307 		acpi_dmar_rmrr_fixup(tmp, current);
308 	}
309 
310 	return current;
311 }
312 
sa_write_acpi_tables(const struct device * dev,unsigned long current,struct acpi_rsdp * rsdp)313 unsigned long sa_write_acpi_tables(const struct device *dev, unsigned long current,
314 				   struct acpi_rsdp *rsdp)
315 {
316 	acpi_dmar_t *const dmar = (acpi_dmar_t *)current;
317 
318 	/* Create DMAR table only if we have VT-d capability
319 	 * and FSP does not override its feature.
320 	 */
321 	if ((pci_read_config32(dev, CAPID0_A) & VTD_DISABLE) ||
322 	    !(MCHBAR32(VTVC0BAR) & VTBAR_ENABLED))
323 		return current;
324 
325 	printk(BIOS_DEBUG, "ACPI:    * DMAR\n");
326 	acpi_create_dmar(dmar, DMAR_INTR_REMAP, soc_fill_dmar);
327 
328 	current += dmar->header.length;
329 	current = acpi_align_current(current);
330 	acpi_add_table(rsdp, dmar);
331 
332 	return current;
333 }
334