blob: 9ee8d6a59ba81e8c60859a4eb93a6bd70b3200ac [file] [log] [blame]
Patrick Georgiac959032020-05-05 22:49:26 +02001/* SPDX-License-Identifier: GPL-2.0-or-later */
Jonathan Zhang8f895492020-01-16 11:16:45 -08002
3#include <assert.h>
Marc Jones63e2a842020-12-02 11:33:02 -07004#include <intelblocks/acpi.h>
Patrick Rudolph40e07482024-02-23 09:23:41 +01005#include <soc/chip_common.h>
Jonathan Zhang8f895492020-01-16 11:16:45 -08006#include <soc/pci_devs.h>
Marc Jones18960ce2020-11-02 12:41:12 -07007#include <soc/util.h>
Arthur Heymans8a3e2b82022-12-02 12:42:27 +01008#include <stdint.h>
Maximilian Bruneb3e336c2023-09-16 19:49:39 +02009#include <stdlib.h>
Marc Jones9f555742020-09-24 16:35:56 -060010
Marc Jones31ed8852021-01-15 13:29:14 -070011#include "chip.h"
12
13/*
14 * List of supported C-states in this processor.
15 */
16enum {
17 C_STATE_C1, /* 0 */
18 C_STATE_C3, /* 1 */
19 C_STATE_C6, /* 2 */
20 C_STATE_C7, /* 3 */
21 NUM_C_STATES
22};
23
24static const acpi_cstate_t cstate_map[NUM_C_STATES] = {
25 [C_STATE_C1] = {
26 /* C1 */
27 .latency = 1,
28 .power = 0x3e8,
29 .resource = MWAIT_RES(0, 0),
30 },
31 [C_STATE_C3] = {
32 /* C3 */
33 .latency = 15,
34 .power = 0x1f4,
35 .resource = MWAIT_RES(1, 0),
36 },
37 [C_STATE_C6] = {
38 /* C6 */
39 .latency = 41,
40 .power = 0x15e,
41 .resource = MWAIT_RES(2, 0),
42 },
43 [C_STATE_C7] = {
44 /* C7 */
45 .latency = 41,
46 .power = 0x0c8,
47 .resource = MWAIT_RES(3, 0),
48 }
49};
50
51/* Max states supported */
52static int cstate_set_all[] = {
53 C_STATE_C1,
54 C_STATE_C3,
55 C_STATE_C6,
56 C_STATE_C7
57};
58
59static int cstate_set_c1_c6[] = {
60 C_STATE_C1,
61 C_STATE_C6,
62};
63
Angel Ponse9f10ff2021-10-17 13:28:23 +020064const acpi_cstate_t *soc_get_cstate_map(size_t *entries)
Marc Jones9f555742020-09-24 16:35:56 -060065{
Marc Jones31ed8852021-01-15 13:29:14 -070066 static acpi_cstate_t map[ARRAY_SIZE(cstate_set_all)];
67 int *cstate_set;
68 int i;
69
70 const config_t *config = config_of_soc();
71
72 const enum acpi_cstate_mode states = config->cstate_states;
73
74 switch (states) {
75 case CSTATES_C1C6:
76 *entries = ARRAY_SIZE(cstate_set_c1_c6);
77 cstate_set = cstate_set_c1_c6;
78 break;
79 case CSTATES_ALL:
80 default:
81 *entries = ARRAY_SIZE(cstate_set_all);
82 cstate_set = cstate_set_all;
83 break;
84 }
85
86 for (i = 0; i < *entries; i++) {
87 map[i] = cstate_map[cstate_set[i]];
88 map[i].ctype = i + 1;
89 }
90 return map;
Marc Jones9f555742020-09-24 16:35:56 -060091}
92
Shuo Liu37a2fb52024-04-02 22:10:20 +080093#if CONFIG(XEON_SP_HAVE_IIO_IOAPIC)
Arthur Heymans8a3e2b82022-12-02 12:42:27 +010094static uintptr_t xeonsp_ioapic_bases[CONFIG(XEON_SP_HAVE_IIO_IOAPIC) * 8 + 1];
Arthur Heymansc7eebac2020-11-06 12:25:28 +010095
Arthur Heymans8a3e2b82022-12-02 12:42:27 +010096size_t soc_get_ioapic_info(const uintptr_t *ioapic_bases[])
Marc Jones9f555742020-09-24 16:35:56 -060097{
Arthur Heymans8a3e2b82022-12-02 12:42:27 +010098 int index = 0;
Arthur Heymans7598b4b2020-11-06 12:33:35 +010099 const IIO_UDS *hob = get_iio_uds();
Marc Jones9f555742020-09-24 16:35:56 -0600100
Arthur Heymans8a3e2b82022-12-02 12:42:27 +0100101 *ioapic_bases = xeonsp_ioapic_bases;
Christian Walter106def92022-06-29 18:23:51 +0200102
Patrick Rudolphabc27442024-03-12 14:48:16 +0100103 for (int socket = 0; socket < CONFIG_MAX_SOCKET; socket++) {
Patrick Rudolphac028572023-07-14 17:44:33 +0200104 if (!soc_cpu_is_enabled(socket))
105 continue;
Arthur Heymans7598b4b2020-11-06 12:33:35 +0100106 for (int stack = 0; stack < MAX_IIO_STACK; ++stack) {
107 const STACK_RES *ri =
108 &hob->PlatformData.IIO_resource[socket].StackRes[stack];
Arthur Heymans8a3e2b82022-12-02 12:42:27 +0100109 uint32_t ioapic_base = ri->IoApicBase;
Arthur Heymans470f1d32023-08-31 18:19:09 +0200110 if (ioapic_base == 0 || ioapic_base == 0xFFFFFFFF)
111 continue;
Arthur Heymans8a3e2b82022-12-02 12:42:27 +0100112 assert(index < ARRAY_SIZE(xeonsp_ioapic_bases));
113 xeonsp_ioapic_bases[index++] = ioapic_base;
114 if (!CONFIG(XEON_SP_HAVE_IIO_IOAPIC))
115 return index;
Arthur Heymans7598b4b2020-11-06 12:33:35 +0100116 /*
117 * Stack 0 has non-PCH IOAPIC and PCH IOAPIC.
Arthur Heymans77038b12020-11-06 12:59:46 +0100118 * The IIO IOAPIC is placed at 0x1000 from the reported base.
Arthur Heymans7598b4b2020-11-06 12:33:35 +0100119 */
Arthur Heymans8a3e2b82022-12-02 12:42:27 +0100120 if (socket == 0 && stack == 0) {
121 ioapic_base += 0x1000;
122 assert(index < ARRAY_SIZE(xeonsp_ioapic_bases));
123 xeonsp_ioapic_bases[index++] = ioapic_base;
124 }
Jonathan Zhang8f895492020-01-16 11:16:45 -0800125 }
126 }
Marc Jones9f555742020-09-24 16:35:56 -0600127
Arthur Heymans8a3e2b82022-12-02 12:42:27 +0100128 return index;
Marc Jones9f555742020-09-24 16:35:56 -0600129}
Shuo Liu37a2fb52024-04-02 22:10:20 +0800130#endif
Patrick Rudolph40e07482024-02-23 09:23:41 +0100131
132void iio_domain_set_acpi_name(struct device *dev, const char *prefix)
133{
134 const union xeon_domain_path dn = {
135 .domain_path = dev->path.domain.domain
136 };
137
138 assert(dn.socket < CONFIG_MAX_SOCKET);
139 assert(dn.stack < 16);
140 assert(prefix != NULL && strlen(prefix) == 2);
141
142 if (dn.socket >= CONFIG_MAX_SOCKET || dn.stack >= 16 ||
143 !prefix || strlen(prefix) != 2)
144 return;
145
146 char *name = xmalloc(ACPI_NAME_BUFFER_SIZE);
147 snprintf(name, ACPI_NAME_BUFFER_SIZE, "%s%1X%1X", prefix, dn.socket, dn.stack);
148 dev->name = name;
149}
150
151const char *soc_acpi_name(const struct device *dev)
152{
153 if (dev->path.type == DEVICE_PATH_DOMAIN)
154 return dev->name;
155
156 /* FIXME: Add SoC specific device names here */
157
158 return NULL;
159}