Patrick Georgi | ac95903 | 2020-05-05 22:49:26 +0200 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ |
Jonathan Zhang | 8f89549 | 2020-01-16 11:16:45 -0800 | [diff] [blame] | 2 | |
| 3 | #include <assert.h> |
Marc Jones | 63e2a84 | 2020-12-02 11:33:02 -0700 | [diff] [blame] | 4 | #include <intelblocks/acpi.h> |
Jonathan Zhang | 8f89549 | 2020-01-16 11:16:45 -0800 | [diff] [blame] | 5 | #include <soc/pci_devs.h> |
Marc Jones | 18960ce | 2020-11-02 12:41:12 -0700 | [diff] [blame] | 6 | #include <soc/util.h> |
Marc Jones | 9f55574 | 2020-09-24 16:35:56 -0600 | [diff] [blame] | 7 | |
Marc Jones | 31ed885 | 2021-01-15 13:29:14 -0700 | [diff] [blame] | 8 | #include "chip.h" |
| 9 | |
| 10 | /* |
| 11 | * List of supported C-states in this processor. |
| 12 | */ |
| 13 | enum { |
| 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 | |
| 21 | static 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 */ |
| 49 | static int cstate_set_all[] = { |
| 50 | C_STATE_C1, |
| 51 | C_STATE_C3, |
| 52 | C_STATE_C6, |
| 53 | C_STATE_C7 |
| 54 | }; |
| 55 | |
| 56 | static int cstate_set_c1_c6[] = { |
| 57 | C_STATE_C1, |
| 58 | C_STATE_C6, |
| 59 | }; |
| 60 | |
Angel Pons | e9f10ff | 2021-10-17 13:28:23 +0200 | [diff] [blame] | 61 | const acpi_cstate_t *soc_get_cstate_map(size_t *entries) |
Marc Jones | 9f55574 | 2020-09-24 16:35:56 -0600 | [diff] [blame] | 62 | { |
Marc Jones | 31ed885 | 2021-01-15 13:29:14 -0700 | [diff] [blame] | 63 | 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 Jones | 9f55574 | 2020-09-24 16:35:56 -0600 | [diff] [blame] | 88 | } |
| 89 | |
Marc Jones | 63e2a84 | 2020-12-02 11:33:02 -0700 | [diff] [blame] | 90 | static void print_madt_ioapic(int socket, int stack, |
Arthur Heymans | 7598b4b | 2020-11-06 12:33:35 +0100 | [diff] [blame] | 91 | int ioapic_id, uint32_t ioapic_base, int gsi_base) |
Arthur Heymans | c7eebac | 2020-11-06 12:25:28 +0100 | [diff] [blame] | 92 | { |
Arthur Heymans | 7598b4b | 2020-11-06 12:33:35 +0100 | [diff] [blame] | 93 | printk(BIOS_DEBUG, "Adding MADT IOAPIC for socket: %d, stack: %d, ioapic_id: 0x%x, " |
Arthur Heymans | c7eebac | 2020-11-06 12:25:28 +0100 | [diff] [blame] | 94 | "ioapic_base: 0x%x, gsi_base: 0x%x\n", |
Arthur Heymans | 7598b4b | 2020-11-06 12:33:35 +0100 | [diff] [blame] | 95 | socket, stack, ioapic_id, ioapic_base, gsi_base); |
Marc Jones | 63e2a84 | 2020-12-02 11:33:02 -0700 | [diff] [blame] | 96 | return; |
Arthur Heymans | c7eebac | 2020-11-06 12:25:28 +0100 | [diff] [blame] | 97 | } |
| 98 | |
Marc Jones | 63e2a84 | 2020-12-02 11:33:02 -0700 | [diff] [blame] | 99 | const struct madt_ioapic_info *soc_get_ioapic_info(size_t *entries) |
Marc Jones | 9f55574 | 2020-09-24 16:35:56 -0600 | [diff] [blame] | 100 | { |
Marc Jones | d49c8cf | 2020-10-19 20:16:41 -0600 | [diff] [blame] | 101 | int cur_index; |
Arthur Heymans | 7598b4b | 2020-11-06 12:33:35 +0100 | [diff] [blame] | 102 | const IIO_UDS *hob = get_iio_uds(); |
Marc Jones | 9f55574 | 2020-09-24 16:35:56 -0600 | [diff] [blame] | 103 | |
Marc Jones | d49c8cf | 2020-10-19 20:16:41 -0600 | [diff] [blame] | 104 | /* With XEON-SP FSP, PCH IOAPIC is allocated with first 120 GSIs. */ |
Marc Jones | 444fda4 | 2020-10-19 21:12:27 -0600 | [diff] [blame] | 105 | #if (CONFIG(SOC_INTEL_COOPERLAKE_SP)) |
| 106 | const int gsi_bases[] = { 0, 0x78, 0x80, 0x88, 0x90, 0x98, 0xA0, 0xA8, 0xB0 }; |
Marc Jones | 444fda4 | 2020-10-19 21:12:27 -0600 | [diff] [blame] | 107 | #endif |
Marc Jones | 9f55574 | 2020-09-24 16:35:56 -0600 | [diff] [blame] | 108 | |
Marc Jones | 444fda4 | 2020-10-19 21:12:27 -0600 | [diff] [blame] | 109 | #if (CONFIG(SOC_INTEL_SKYLAKE_SP)) |
| 110 | const int gsi_bases[] = { 0, 0x18, 0x20, 0x28, 0x30, 0x48, 0x50, 0x58, 0x60 }; |
Marc Jones | 444fda4 | 2020-10-19 21:12:27 -0600 | [diff] [blame] | 111 | #endif |
Marc Jones | 63e2a84 | 2020-12-02 11:33:02 -0700 | [diff] [blame] | 112 | |
| 113 | static struct madt_ioapic_info madt_tbl[ARRAY_SIZE(gsi_bases)]; |
Marc Jones | 9f55574 | 2020-09-24 16:35:56 -0600 | [diff] [blame] | 114 | |
Marc Jones | d49c8cf | 2020-10-19 20:16:41 -0600 | [diff] [blame] | 115 | cur_index = 0; |
Marc Jones | 63e2a84 | 2020-12-02 11:33:02 -0700 | [diff] [blame] | 116 | 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 Zhang | 8f89549 | 2020-01-16 11:16:45 -0800 | [diff] [blame] | 122 | |
Arthur Heymans | 7598b4b | 2020-11-06 12:33:35 +0100 | [diff] [blame] | 123 | 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 Jones | d49c8cf | 2020-10-19 20:16:41 -0600 | [diff] [blame] | 129 | assert(cur_index < ARRAY_SIZE(gsi_bases)); |
Marc Jones | 63e2a84 | 2020-12-02 11:33:02 -0700 | [diff] [blame] | 130 | 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 Heymans | 7598b4b | 2020-11-06 12:33:35 +0100 | [diff] [blame] | 133 | |
| 134 | /* |
| 135 | * Stack 0 has non-PCH IOAPIC and PCH IOAPIC. |
Arthur Heymans | 77038b1 | 2020-11-06 12:59:46 +0100 | [diff] [blame] | 136 | * The IIO IOAPIC is placed at 0x1000 from the reported base. |
Arthur Heymans | 7598b4b | 2020-11-06 12:33:35 +0100 | [diff] [blame] | 137 | */ |
Arthur Heymans | 77038b1 | 2020-11-06 12:59:46 +0100 | [diff] [blame] | 138 | if (stack == 0 && socket == 0) |
Marc Jones | 63e2a84 | 2020-12-02 11:33:02 -0700 | [diff] [blame] | 139 | madt_tbl[cur_index].addr += 0x1000; |
Arthur Heymans | 77038b1 | 2020-11-06 12:59:46 +0100 | [diff] [blame] | 140 | |
Marc Jones | 63e2a84 | 2020-12-02 11:33:02 -0700 | [diff] [blame] | 141 | print_madt_ioapic(socket, stack, madt_tbl[cur_index].id, |
| 142 | madt_tbl[cur_index].addr, |
| 143 | madt_tbl[cur_index].gsi_base); |
Arthur Heymans | 77038b1 | 2020-11-06 12:59:46 +0100 | [diff] [blame] | 144 | ++cur_index; |
Jonathan Zhang | 8f89549 | 2020-01-16 11:16:45 -0800 | [diff] [blame] | 145 | } |
| 146 | } |
Marc Jones | 9f55574 | 2020-09-24 16:35:56 -0600 | [diff] [blame] | 147 | |
Marc Jones | 63e2a84 | 2020-12-02 11:33:02 -0700 | [diff] [blame] | 148 | *entries = cur_index; |
| 149 | return madt_tbl; |
Marc Jones | 9f55574 | 2020-09-24 16:35:56 -0600 | [diff] [blame] | 150 | } |