blob: 68abba7eb8d653c9a71b969a83d87e43c1511d29 [file] [log] [blame]
Sridahr Siricillacd1cd8d2021-11-11 01:29:40 +05301/* SPDX-License-Identifier: GPL-2.0-or-later */
Sridhar Siricillaf8ac3dd2023-03-30 11:25:36 +05302#include <acpi/acpi.h>
Sridahr Siricillacd1cd8d2021-11-11 01:29:40 +05303#include <acpi/acpigen.h>
Sridhar Siricillaf8ac3dd2023-03-30 11:25:36 +05304#include <bootstate.h>
5#include <commonlib/sort.h>
Sridahr Siricillacd1cd8d2021-11-11 01:29:40 +05306#include <cpu/x86/lapic.h>
7#include <cpu/x86/mp.h>
Sridhar Siricillaf8ac3dd2023-03-30 11:25:36 +05308#include <cpu/cpu.h>
9#include <device/path.h>
10#include <intelblocks/acpi.h>
11#include <soc/cpu.h>
Elyes Haouasbdd03c22024-05-27 11:20:07 +020012#include <stdio.h>
Sridhar Siricillaf8ac3dd2023-03-30 11:25:36 +053013#include <types.h>
Sridahr Siricillacd1cd8d2021-11-11 01:29:40 +053014
Sridhar Siricilla11736122021-11-15 17:12:49 +053015#define CPPC_NOM_FREQ_IDX 22
16#define CPPC_NOM_PERF_IDX 3
17
Sridhar Siricilla51c75ac2022-01-29 14:26:22 +053018enum cpu_perf_eff_type {
Sridhar Siricilla4c3014f2023-01-03 11:29:08 +053019 CPU_TYPE_EFF,
20 CPU_TYPE_PERF,
Sridhar Siricilla51c75ac2022-01-29 14:26:22 +053021};
22
Sridhar Siricillaf8ac3dd2023-03-30 11:25:36 +053023struct cpu_apic_info_type {
24 /*
25 * Ordered APIC IDs based on core type.
26 * Array begins with Performance Cores' APIC IDs,
27 * then followed by Efficeint Cores's APIC IDs.
28 */
29 int32_t apic_ids[CONFIG_MAX_CPUS];
Sridahr Siricillacd1cd8d2021-11-11 01:29:40 +053030
Sridhar Siricillaf8ac3dd2023-03-30 11:25:36 +053031 /* Total CPU count */
Sridhar Siricilla02b39ef2023-04-09 17:40:43 +053032 uint16_t total_cpu_cnt;
Sridhar Siricillaf8ac3dd2023-03-30 11:25:36 +053033
34 /*
35 * Total Performance core count. This will be used
36 * to identify the start of Efficient Cores's
37 * APIC ID list
38 */
Sridhar Siricilla02b39ef2023-04-09 17:40:43 +053039 uint16_t perf_cpu_cnt;
Sridhar Siricillaf8ac3dd2023-03-30 11:25:36 +053040};
41
42static struct cpu_apic_info_type cpu_apic_info;
43
44/*
45 * The function orders APIC IDs such that orders first Performance cores and then
46 * Efficient cores' APIC IDs in ascending order. Also calculates total number of
47 * Performance cores and all cores count in the system and populates the information
48 * in the cpu_apic_info sturct.
49 */
50static void acpi_set_hybrid_cpu_apicid_order(void *unused)
Sridahr Siricillacd1cd8d2021-11-11 01:29:40 +053051{
Sridhar Siricillaf8ac3dd2023-03-30 11:25:36 +053052 size_t perf_core_cnt = 0, eff_core_cnt = 0;
53 int32_t eff_apic_ids[CONFIG_MAX_CPUS] = {0};
54 extern struct cpu_info cpu_infos[];
55 uint32_t i, j = 0;
56
57 for (i = 0; i < ARRAY_SIZE(cpu_apic_info.apic_ids); i++) {
Jeremy Compostellaba7a9ee2023-09-01 16:17:51 -070058 if (!cpu_infos[i].cpu)
59 continue;
Sridhar Siricillaf8ac3dd2023-03-30 11:25:36 +053060 if (cpu_infos[i].cpu->path.apic.core_type == CPU_TYPE_PERF)
61 cpu_apic_info.apic_ids[perf_core_cnt++] =
62 cpu_infos[i].cpu->path.apic.apic_id;
63 else
64 eff_apic_ids[eff_core_cnt++] =
65 cpu_infos[i].cpu->path.apic.apic_id;
66 }
67
68 if (perf_core_cnt > 1)
69 bubblesort(cpu_apic_info.apic_ids, perf_core_cnt, NUM_ASCENDING);
70
71 for (i = perf_core_cnt; j < eff_core_cnt; i++, j++)
72 cpu_apic_info.apic_ids[i] = eff_apic_ids[j];
73
74 if (eff_core_cnt > 1)
75 bubblesort(&cpu_apic_info.apic_ids[perf_core_cnt], eff_core_cnt, NUM_ASCENDING);
76
77 /* Populate total core count */
78 cpu_apic_info.total_cpu_cnt = perf_core_cnt + eff_core_cnt;
79
80 cpu_apic_info.perf_cpu_cnt = perf_core_cnt;
Sridahr Siricillacd1cd8d2021-11-11 01:29:40 +053081}
82
Sridhar Siricilla7301cfa2023-01-19 18:50:09 +053083static unsigned long acpi_create_madt_lapics_hybrid(unsigned long current)
84{
85 size_t index;
86
Kyösti Mälkki2e9f0d32023-04-07 23:05:46 +030087 for (index = 0; index < cpu_apic_info.total_cpu_cnt; index++)
88 current = acpi_create_madt_one_lapic(current, index,
89 cpu_apic_info.apic_ids[index]);
Sridhar Siricilla7301cfa2023-01-19 18:50:09 +053090
91 return current;
92}
93
94unsigned long acpi_create_madt_lapics_with_nmis_hybrid(unsigned long current)
95{
Sridhar Siricilla7301cfa2023-01-19 18:50:09 +053096 current = acpi_create_madt_lapics_hybrid(current);
Kyösti Mälkki9ac1fb72023-04-07 22:39:53 +030097 current = acpi_create_madt_lapic_nmis(current);
Sridhar Siricilla7301cfa2023-01-19 18:50:09 +053098 return current;
99}
100
Sridhar Siricilla1b04e812023-03-30 09:51:28 +0530101static enum cpu_perf_eff_type get_core_type(void)
102{
103 return (get_soc_cpu_type() == CPUID_CORE_TYPE_INTEL_CORE) ?
104 CPU_TYPE_PERF : CPU_TYPE_EFF;
105}
106
107void set_dev_core_type(void)
108{
109 struct cpu_info *info = cpu_info();
110 info->cpu->path.apic.core_type = get_core_type();
111}
112
Sridhar Siricilla4c3014f2023-01-03 11:29:08 +0530113static void acpi_get_cpu_nomi_perf(u16 *eff_core_nom_perf, u16 *perf_core_nom_perf)
Sridhar Siricilla11736122021-11-15 17:12:49 +0530114{
Sridhar Siricilla11736122021-11-15 17:12:49 +0530115 u8 max_non_turbo_ratio = cpu_get_max_non_turbo_ratio();
116
Sridhar Siricillad9c82692023-01-05 17:08:17 +0530117 _Static_assert(CONFIG_SOC_INTEL_PERFORMANCE_CORE_SCALE_FACTOR != 0,
118 "CONFIG_SOC_INTEL_PERFORMANCE_CORE_SCALE_FACTOR must not be zero");
Sridhar Siricilla11736122021-11-15 17:12:49 +0530119
Sridhar Siricillad9c82692023-01-05 17:08:17 +0530120 _Static_assert(CONFIG_SOC_INTEL_EFFICIENT_CORE_SCALE_FACTOR != 0,
121 "CONFIG_SOC_INTEL_EFFICIENT_CORE_SCALE_FACTOR must not be zero");
Sridhar Siricilla11736122021-11-15 17:12:49 +0530122
Sridhar Siricillad9c82692023-01-05 17:08:17 +0530123 *perf_core_nom_perf = (u16)((max_non_turbo_ratio *
124 CONFIG_SOC_INTEL_PERFORMANCE_CORE_SCALE_FACTOR) / 100);
125
126 *eff_core_nom_perf = (u16)((max_non_turbo_ratio *
127 CONFIG_SOC_INTEL_EFFICIENT_CORE_SCALE_FACTOR) / 100);
Sridhar Siricilla11736122021-11-15 17:12:49 +0530128}
129
130static u16 acpi_get_cpu_nominal_freq(void)
131{
132 return cpu_get_max_non_turbo_ratio() * cpu_get_bus_frequency();
133}
134
135/* Updates Nominal Frequency and Nominal Performance */
136static void acpigen_cppc_update_nominal_freq_perf(const char *pkg_path, s32 core_id)
137{
Sridhar Siricilla4c3014f2023-01-03 11:29:08 +0530138 u16 eff_core_nom_perf, perf_core_nom_perf;
Sridhar Siricilla11736122021-11-15 17:12:49 +0530139
140 if (!soc_is_nominal_freq_supported())
141 return;
142
Sridhar Siricilla4c3014f2023-01-03 11:29:08 +0530143 acpi_get_cpu_nomi_perf(&eff_core_nom_perf, &perf_core_nom_perf);
Sridhar Siricilla11736122021-11-15 17:12:49 +0530144
Sridhar Siricillaf8ac3dd2023-03-30 11:25:36 +0530145 if (core_id < cpu_apic_info.perf_cpu_cnt)
Sridhar Siricilla4c3014f2023-01-03 11:29:08 +0530146 acpigen_set_package_element_int(pkg_path, CPPC_NOM_PERF_IDX, perf_core_nom_perf);
Sridhar Siricilla11736122021-11-15 17:12:49 +0530147 else
148 acpigen_set_package_element_int(pkg_path, CPPC_NOM_PERF_IDX,
Sridhar Siricilla4c3014f2023-01-03 11:29:08 +0530149 eff_core_nom_perf);
Sridhar Siricilla11736122021-11-15 17:12:49 +0530150
151 /* Update CPU's nominal frequency */
152 acpigen_set_package_element_int(pkg_path, CPPC_NOM_FREQ_IDX,
153 acpi_get_cpu_nominal_freq());
154}
155
156void acpigen_write_CPPC_hybrid_method(s32 core_id)
157{
158 char pkg_path[16];
159
160 if (core_id == 0)
161 snprintf(pkg_path, sizeof(pkg_path), CPPC_PACKAGE_NAME, 0);
162 else
163 snprintf(pkg_path, sizeof(pkg_path),
Felix Heldf0a8b042023-05-12 15:55:06 +0200164 "\\_SB." CONFIG_ACPI_CPU_STRING "." CPPC_PACKAGE_NAME, 0);
Sridhar Siricilla11736122021-11-15 17:12:49 +0530165
166 acpigen_write_method("_CPC", 0);
167
168 /* Update nominal performance and nominal frequency */
169 acpigen_cppc_update_nominal_freq_perf(pkg_path, core_id);
170 acpigen_emit_byte(RETURN_OP);
171 acpigen_emit_namestring(pkg_path);
172 acpigen_pop_len();
173}
174
Sridhar Siricillaf8ac3dd2023-03-30 11:25:36 +0530175BOOT_STATE_INIT_ENTRY(BS_DEV_INIT_CHIPS, BS_ON_EXIT, acpi_set_hybrid_cpu_apicid_order, NULL);