blob: de9db88bad9b18ababff87533ba2ae490295f2d3 [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>
Jonathan Zhang8f895492020-01-16 11:16:45 -08005#include <soc/pci_devs.h>
Marc Jones18960ce2020-11-02 12:41:12 -07006#include <soc/util.h>
Marc Jones9f555742020-09-24 16:35:56 -06007
Marc Jones31ed8852021-01-15 13:29:14 -07008#include "chip.h"
9
10/*
11 * List of supported C-states in this processor.
12 */
13enum {
14 C_STATE_C1, /* 0 */
15 C_STATE_C3, /* 1 */
16 C_STATE_C6, /* 2 */
17 C_STATE_C7, /* 3 */
18 NUM_C_STATES
19};
20
21static const acpi_cstate_t cstate_map[NUM_C_STATES] = {
22 [C_STATE_C1] = {
23 /* C1 */
24 .latency = 1,
25 .power = 0x3e8,
26 .resource = MWAIT_RES(0, 0),
27 },
28 [C_STATE_C3] = {
29 /* C3 */
30 .latency = 15,
31 .power = 0x1f4,
32 .resource = MWAIT_RES(1, 0),
33 },
34 [C_STATE_C6] = {
35 /* C6 */
36 .latency = 41,
37 .power = 0x15e,
38 .resource = MWAIT_RES(2, 0),
39 },
40 [C_STATE_C7] = {
41 /* C7 */
42 .latency = 41,
43 .power = 0x0c8,
44 .resource = MWAIT_RES(3, 0),
45 }
46};
47
48/* Max states supported */
49static int cstate_set_all[] = {
50 C_STATE_C1,
51 C_STATE_C3,
52 C_STATE_C6,
53 C_STATE_C7
54};
55
56static int cstate_set_c1_c6[] = {
57 C_STATE_C1,
58 C_STATE_C6,
59};
60
Angel Ponse9f10ff2021-10-17 13:28:23 +020061const acpi_cstate_t *soc_get_cstate_map(size_t *entries)
Marc Jones9f555742020-09-24 16:35:56 -060062{
Marc Jones31ed8852021-01-15 13:29:14 -070063 static acpi_cstate_t map[ARRAY_SIZE(cstate_set_all)];
64 int *cstate_set;
65 int i;
66
67 const config_t *config = config_of_soc();
68
69 const enum acpi_cstate_mode states = config->cstate_states;
70
71 switch (states) {
72 case CSTATES_C1C6:
73 *entries = ARRAY_SIZE(cstate_set_c1_c6);
74 cstate_set = cstate_set_c1_c6;
75 break;
76 case CSTATES_ALL:
77 default:
78 *entries = ARRAY_SIZE(cstate_set_all);
79 cstate_set = cstate_set_all;
80 break;
81 }
82
83 for (i = 0; i < *entries; i++) {
84 map[i] = cstate_map[cstate_set[i]];
85 map[i].ctype = i + 1;
86 }
87 return map;
Marc Jones9f555742020-09-24 16:35:56 -060088}
89
Marc Jones63e2a842020-12-02 11:33:02 -070090static void print_madt_ioapic(int socket, int stack,
Arthur Heymans7598b4b2020-11-06 12:33:35 +010091 int ioapic_id, uint32_t ioapic_base, int gsi_base)
Arthur Heymansc7eebac2020-11-06 12:25:28 +010092{
Arthur Heymans7598b4b2020-11-06 12:33:35 +010093 printk(BIOS_DEBUG, "Adding MADT IOAPIC for socket: %d, stack: %d, ioapic_id: 0x%x, "
Arthur Heymansc7eebac2020-11-06 12:25:28 +010094 "ioapic_base: 0x%x, gsi_base: 0x%x\n",
Arthur Heymans7598b4b2020-11-06 12:33:35 +010095 socket, stack, ioapic_id, ioapic_base, gsi_base);
Marc Jones63e2a842020-12-02 11:33:02 -070096 return;
Arthur Heymansc7eebac2020-11-06 12:25:28 +010097}
98
Marc Jones63e2a842020-12-02 11:33:02 -070099const struct madt_ioapic_info *soc_get_ioapic_info(size_t *entries)
Marc Jones9f555742020-09-24 16:35:56 -0600100{
Marc Jonesd49c8cf2020-10-19 20:16:41 -0600101 int cur_index;
Arthur Heymans7598b4b2020-11-06 12:33:35 +0100102 const IIO_UDS *hob = get_iio_uds();
Marc Jones9f555742020-09-24 16:35:56 -0600103
Marc Jonesd49c8cf2020-10-19 20:16:41 -0600104 /* With XEON-SP FSP, PCH IOAPIC is allocated with first 120 GSIs. */
Marc Jones444fda42020-10-19 21:12:27 -0600105#if (CONFIG(SOC_INTEL_COOPERLAKE_SP))
106 const int gsi_bases[] = { 0, 0x78, 0x80, 0x88, 0x90, 0x98, 0xA0, 0xA8, 0xB0 };
Marc Jones444fda42020-10-19 21:12:27 -0600107#endif
Marc Jones9f555742020-09-24 16:35:56 -0600108
Marc Jones444fda42020-10-19 21:12:27 -0600109#if (CONFIG(SOC_INTEL_SKYLAKE_SP))
110 const int gsi_bases[] = { 0, 0x18, 0x20, 0x28, 0x30, 0x48, 0x50, 0x58, 0x60 };
Marc Jones444fda42020-10-19 21:12:27 -0600111#endif
Marc Jones63e2a842020-12-02 11:33:02 -0700112
113 static struct madt_ioapic_info madt_tbl[ARRAY_SIZE(gsi_bases)];
Marc Jones9f555742020-09-24 16:35:56 -0600114
Marc Jonesd49c8cf2020-10-19 20:16:41 -0600115 cur_index = 0;
Marc Jones63e2a842020-12-02 11:33:02 -0700116 madt_tbl[cur_index].id = PCH_IOAPIC_ID;
117 madt_tbl[cur_index].addr = hob->PlatformData.IIO_resource[0].StackRes[0].IoApicBase;
118 madt_tbl[cur_index].gsi_base = gsi_bases[cur_index];
119 print_madt_ioapic(0, 0, madt_tbl[cur_index].id,
120 madt_tbl[cur_index].addr, madt_tbl[cur_index].gsi_base);
121 ++cur_index;
Jonathan Zhang8f895492020-01-16 11:16:45 -0800122
Arthur Heymans7598b4b2020-11-06 12:33:35 +0100123 for (int socket = 0; socket < hob->PlatformData.numofIIO; ++socket) {
124 for (int stack = 0; stack < MAX_IIO_STACK; ++stack) {
125 const STACK_RES *ri =
126 &hob->PlatformData.IIO_resource[socket].StackRes[stack];
127 if (!is_iio_stack_res(ri))
128 continue;
Marc Jonesd49c8cf2020-10-19 20:16:41 -0600129 assert(cur_index < ARRAY_SIZE(gsi_bases));
Marc Jones63e2a842020-12-02 11:33:02 -0700130 madt_tbl[cur_index].id = soc_get_iio_ioapicid(socket, stack);
131 madt_tbl[cur_index].gsi_base = gsi_bases[cur_index];
132 madt_tbl[cur_index].addr = ri->IoApicBase;
Arthur Heymans7598b4b2020-11-06 12:33:35 +0100133
134 /*
135 * Stack 0 has non-PCH IOAPIC and PCH IOAPIC.
Arthur Heymans77038b12020-11-06 12:59:46 +0100136 * The IIO IOAPIC is placed at 0x1000 from the reported base.
Arthur Heymans7598b4b2020-11-06 12:33:35 +0100137 */
Arthur Heymans77038b12020-11-06 12:59:46 +0100138 if (stack == 0 && socket == 0)
Marc Jones63e2a842020-12-02 11:33:02 -0700139 madt_tbl[cur_index].addr += 0x1000;
Arthur Heymans77038b12020-11-06 12:59:46 +0100140
Marc Jones63e2a842020-12-02 11:33:02 -0700141 print_madt_ioapic(socket, stack, madt_tbl[cur_index].id,
142 madt_tbl[cur_index].addr,
143 madt_tbl[cur_index].gsi_base);
Arthur Heymans77038b12020-11-06 12:59:46 +0100144 ++cur_index;
Jonathan Zhang8f895492020-01-16 11:16:45 -0800145 }
146 }
Marc Jones9f555742020-09-24 16:35:56 -0600147
Marc Jones63e2a842020-12-02 11:33:02 -0700148 *entries = cur_index;
149 return madt_tbl;
Marc Jones9f555742020-09-24 16:35:56 -0600150}