mb/google/nissa/var/telith: Disable stylus function
[coreboot2.git] / src / soc / intel / braswell / acpi.c
blobff8774c6351fe6815edcb9c734b9a06089002c4a
1 /* SPDX-License-Identifier: GPL-2.0-only */
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 <device/mmio.h>
9 #include <console/console.h>
10 #include <cpu/intel/turbo.h>
11 #include <cpu/x86/msr.h>
12 #include <cpu/x86/smm.h>
13 #include <device/pci.h>
14 #include <drivers/intel/gma/opregion.h>
15 #include <soc/acpi.h>
16 #include <soc/device_nvs.h>
17 #include <soc/gfx.h>
18 #include <soc/iomap.h>
19 #include <soc/irq.h>
20 #include <soc/msr.h>
21 #include <soc/nvs.h>
22 #include <soc/pattrs.h>
23 #include <soc/pci_devs.h>
24 #include <soc/pm.h>
25 #include <string.h>
26 #include <types.h>
27 #include <wrdd.h>
29 #include "chip.h"
31 #define MWAIT_RES(state, sub_state) \
32 { \
33 .addrl = (((state) << 4) | (sub_state)), \
34 .space_id = ACPI_ADDRESS_SPACE_FIXED, \
35 .bit_width = ACPI_FFIXEDHW_VENDOR_INTEL, \
36 .bit_offset = ACPI_FFIXEDHW_CLASS_MWAIT, \
37 .access_size = ACPI_FFIXEDHW_FLAG_HW_COORD, \
40 /* C-state map without S0ix */
41 static const acpi_cstate_t cstate_map[] = {
43 /* C1 */
44 .ctype = 1, /* ACPI C1 */
45 .latency = 1,
46 .power = 1000,
47 .resource = MWAIT_RES(0, 0),
50 /* C6NS with no L2 shrink */
51 /* NOTE: this substate is above CPUID limit */
52 .ctype = 2, /* ACPI C2 */
53 .latency = 500,
54 .power = 10,
55 .resource = MWAIT_RES(5, 1),
58 /* C6FS with full L2 shrink */
59 .ctype = 3, /* ACPI C3 */
60 .latency = 1500, /* 1.5ms worst case */
61 .power = 1,
62 .resource = MWAIT_RES(5, 2),
66 size_t size_of_dnvs(void)
68 return sizeof(struct device_nvs);
71 void soc_fill_gnvs(struct global_nvs *gnvs)
73 gnvs->dpte = is_devfn_enabled(PCI_DEVFN(PUNIT_DEV, 0));
75 /* Fill in the Wi-Fi Region ID */
76 if (CONFIG(HAVE_REGULATORY_DOMAIN))
77 gnvs->cid1 = wifi_regulatory_domain();
78 else
79 gnvs->cid1 = WRDD_DEFAULT_REGULATORY_DOMAIN;
82 static u8 soc_madt_sci_irq_polarity(u8 sci_irq)
84 if (sci_irq >= 20)
85 return MP_IRQ_POLARITY_LOW;
86 else
87 return MP_IRQ_POLARITY_HIGH;
90 #define ACPI_SCI_IRQ 9
92 void ioapic_get_sci_pin(u8 *gsi, u8 *irq, u8 *flags)
94 u32 *actl = (u32 *)(ILB_BASE_ADDRESS + ACTL);
95 int sci_irq = ACPI_SCI_IRQ;
96 int scis;
98 /* Determine how SCI is routed. */
99 scis = read32(actl) & SCIS_MASK;
100 switch (scis) {
101 case SCIS_IRQ9:
102 case SCIS_IRQ10:
103 case SCIS_IRQ11:
104 sci_irq = scis - SCIS_IRQ9 + 9;
105 break;
106 case SCIS_IRQ20:
107 case SCIS_IRQ21:
108 case SCIS_IRQ22:
109 case SCIS_IRQ23:
110 sci_irq = scis - SCIS_IRQ20 + 20;
111 break;
112 default:
113 printk(BIOS_DEBUG, "Invalid SCI route! Defaulting to IRQ%d.\n", sci_irq);
114 break;
117 *gsi = sci_irq;
118 *irq = (sci_irq < 16) ? sci_irq : ACPI_SCI_IRQ;
119 *flags = MP_IRQ_TRIGGER_LEVEL | soc_madt_sci_irq_polarity(sci_irq);
121 printk(BIOS_DEBUG, "SCI is IRQ %d, GSI %d\n", *irq, *gsi);
124 static acpi_tstate_t soc_tss_table[] = {
125 { 100, 1000, 0, 0x00, 0 },
126 { 88, 875, 0, 0x1e, 0 },
127 { 75, 750, 0, 0x1c, 0 },
128 { 63, 625, 0, 0x1a, 0 },
129 { 50, 500, 0, 0x18, 0 },
130 { 38, 375, 0, 0x16, 0 },
131 { 25, 250, 0, 0x14, 0 },
132 { 13, 125, 0, 0x12, 0 },
135 static void generate_t_state_entries(int core, int cores_per_package)
137 /* Indicate SW_ALL coordination for T-states */
138 acpigen_write_TSD_package(core, cores_per_package, SW_ALL);
140 /* Indicate FFixedHW so OS will use MSR */
141 acpigen_write_empty_PTC();
143 /* Set NVS controlled T-state limit */
144 acpigen_write_TPC("\\TLVL");
146 /* Write TSS table for MSR access */
147 acpigen_write_TSS_package(ARRAY_SIZE(soc_tss_table), soc_tss_table);
150 static int calculate_power(int tdp, int p1_ratio, int ratio)
152 u32 m, power;
155 * M = ((1.1 - ((p1_ratio - ratio) * 0.00625)) / 1.1) ^ 2
158 m = (110000 - ((p1_ratio - ratio) * 625)) / 11;
159 m = (m * m) / 1000;
162 * Power = (ratio / p1_ratio) * m * TDP
164 power = ((ratio * 100000 / p1_ratio) / 100);
165 power *= (m / 100) * (tdp / 1000);
166 power /= 1000;
168 return (int)power;
171 static void generate_p_state_entries(int core)
173 int ratio_min, ratio_max, ratio_turbo, ratio_step, ratio_range_2;
174 int coord_type, power_max, power_unit, num_entries;
175 int ratio, power, clock, clock_max;
176 int vid, vid_turbo, vid_min, vid_max, vid_range_2;
177 u32 control_status;
178 const struct pattrs *pattrs = pattrs_get();
179 msr_t msr;
181 /* Inputs from CPU attributes */
182 ratio_max = pattrs->iacore_ratios[IACORE_MAX];
183 ratio_min = pattrs->iacore_ratios[IACORE_LFM];
184 vid_max = pattrs->iacore_vids[IACORE_MAX];
185 vid_min = pattrs->iacore_vids[IACORE_LFM];
187 /* Set P-states coordination type based on MSR disable bit */
188 coord_type = (pattrs->num_cpus > 2) ? SW_ALL : HW_ALL;
190 /* Max Non-Turbo Frequency */
191 clock_max = (ratio_max * pattrs->bclk_khz) / 1000;
193 /* Calculate CPU TDP in mW */
194 msr = rdmsr(MSR_PKG_POWER_SKU_UNIT);
195 power_unit = 1 << (msr.lo & 0xf);
196 msr = rdmsr(MSR_PKG_POWER_LIMIT);
197 power_max = ((msr.lo & 0x7fff) / power_unit) * 1000;
199 /* Write _PCT indicating use of FFixedHW */
200 acpigen_write_empty_PCT();
202 /* Write _PPC with NVS specified limit on supported P-state */
203 acpigen_write_PPC_NVS();
205 /* Write PSD indicating configured coordination type */
206 acpigen_write_PSD_package(core, 1, coord_type);
208 /* Add P-state entries in _PSS table */
209 acpigen_write_name("_PSS");
211 /* Determine ratio points */
212 ratio_step = 1;
213 num_entries = (ratio_max - ratio_min) / ratio_step;
214 while (num_entries > 15) { /* ACPI max is 15 ratios */
215 ratio_step <<= 1;
216 num_entries >>= 1;
219 /* P[T] is Turbo state if enabled */
220 if (get_turbo_state() == TURBO_ENABLED) {
221 /* _PSS package count including Turbo */
222 acpigen_write_package(num_entries + 2);
224 ratio_turbo = pattrs->iacore_ratios[IACORE_TURBO];
225 vid_turbo = pattrs->iacore_vids[IACORE_TURBO];
226 control_status = (ratio_turbo << 8) | vid_turbo;
228 /* Add entry for Turbo ratio */
229 acpigen_write_PSS_package(
230 clock_max + 1, /* MHz */
231 power_max, /* mW */
232 10, /* lat1 */
233 10, /* lat2 */
234 control_status, /* control */
235 control_status); /* status */
236 } else {
237 /* _PSS package count without Turbo */
238 acpigen_write_package(num_entries + 1);
239 ratio_turbo = ratio_max;
240 vid_turbo = vid_max;
243 /* First regular entry is max non-turbo ratio */
244 control_status = (ratio_max << 8) | vid_max;
245 acpigen_write_PSS_package(
246 clock_max, /* MHz */
247 power_max, /* mW */
248 10, /* lat1 */
249 10, /* lat2 */
250 control_status, /* control */
251 control_status); /* status */
253 /* Set up ratio and vid ranges for VID calculation */
254 ratio_range_2 = (ratio_turbo - ratio_min) * 2;
255 vid_range_2 = (vid_turbo - vid_min) * 2;
257 /* Generate the remaining entries */
258 for (ratio = ratio_min + ((num_entries - 1) * ratio_step);
259 ratio >= ratio_min; ratio -= ratio_step) {
260 /* Calculate VID for this ratio */
261 vid = ((ratio - ratio_min) * vid_range_2) / ratio_range_2 + vid_min;
263 /* Round up if remainder */
264 if (((ratio - ratio_min) * vid_range_2) % ratio_range_2)
265 vid++;
267 /* Calculate power at this ratio */
268 power = calculate_power(power_max, ratio_max, ratio);
269 clock = (ratio * pattrs->bclk_khz) / 1000;
270 control_status = (ratio << 8) | (vid & 0xff);
272 acpigen_write_PSS_package(
273 clock, /* MHz */
274 power, /* mW */
275 10, /* lat1 */
276 10, /* lat2 */
277 control_status, /* control */
278 control_status); /* status */
281 /* Fix package length */
282 acpigen_pop_len();
285 static void generate_cpu_entry(int core, int cores_per_package)
287 /* Generate Scope(\_SB) { Device(CPUx */
288 acpigen_write_processor_device(core);
290 /* Generate P-state tables */
291 generate_p_state_entries(core);
293 /* Generate C-state tables */
294 acpigen_write_CST_package(cstate_map, ARRAY_SIZE(cstate_map));
296 /* Generate T-state tables */
297 generate_t_state_entries(core, cores_per_package);
299 acpigen_write_processor_device_end();
302 void generate_cpu_entries(const struct device *device)
304 int core;
305 const struct pattrs *pattrs = pattrs_get();
307 for (core = 0; core < pattrs->num_cpus; core++)
308 generate_cpu_entry(core, pattrs->num_cpus);
310 /* PPKG is usually used for thermal management
311 of the first and only package. */
312 acpigen_write_processor_package("PPKG", 0, pattrs->num_cpus);
314 /* Add a method to notify processor nodes */
315 acpigen_write_processor_cnot(pattrs->num_cpus);
318 unsigned long southcluster_write_acpi_tables(const struct device *device, unsigned long current,
319 struct acpi_rsdp *rsdp)
321 acpi_header_t *ssdt2;
323 if (!CONFIG(DISABLE_HPET)) {
324 current = acpi_write_hpet(device, current, rsdp);
325 current = acpi_align_current(current);
328 ssdt2 = (acpi_header_t *)current;
329 memset(ssdt2, 0, sizeof(acpi_header_t));
330 acpi_create_serialio_ssdt(ssdt2);
331 if (ssdt2->length) {
332 current += ssdt2->length;
333 acpi_add_table(rsdp, ssdt2);
334 printk(BIOS_DEBUG, "ACPI: * SSDT2 @ %p Length %x\n", ssdt2, ssdt2->length);
335 current = acpi_align_current(current);
337 } else {
338 ssdt2 = NULL;
339 printk(BIOS_DEBUG, "ACPI: * SSDT2 not generated.\n");
342 printk(BIOS_DEBUG, "current = %lx\n", current);
344 return current;
347 __weak void acpi_create_serialio_ssdt(acpi_header_t *ssdt)