* [PATCH v2] cpufreq: acpi-cpufreq: Add better support for amd zen
@ 2026-05-14 17:37 yoy95104
0 siblings, 0 replies; only message in thread
From: yoy95104 @ 2026-05-14 17:37 UTC (permalink / raw)
To: rafael, viresh.kumar; +Cc: linux-pm, yoy95104
Found some bugs in the original implementation and repeated code
Signed-off-by: yahia ahmed <yahia.a.abdrabou@gmail.com>
---
drivers/cpufreq/acpi-cpufreq.c | 80 ++++++++++++++++++++++------------
1 file changed, 51 insertions(+), 29 deletions(-)
diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c
index a488a2e2f914..29daca4ffdc6 100644
--- a/drivers/cpufreq/acpi-cpufreq.c
+++ b/drivers/cpufreq/acpi-cpufreq.c
@@ -65,7 +65,6 @@ struct acpi_cpufreq_data {
void (*cpu_freq_write)(struct acpi_pct_register *reg, u32 val);
u32 (*cpu_freq_read)(struct acpi_pct_register *reg);
int is_amd_zen;
- int on_ac;
};
/* acpi_perf_data is a pointer to percpu data. */
@@ -773,7 +772,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
return blacklisted;
#endif
- data = kzalloc_obj(*data);
+ data = kcalloc(1, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
@@ -781,42 +780,65 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
result = -ENOMEM;
goto err_free;
}
-
perf = per_cpu_ptr(acpi_perf_data, cpu);
- data->acpi_perf_cpu = cpu;
- policy->driver_data = data;
+ result = acpi_processor_register_performance(perf, cpu);
+
+ if (result)
+ goto err_free_mask;
if (c->x86_vendor == X86_VENDOR_AMD && c->x86 >= 0x17 && c->x86_model >= 0x30) {
data->is_amd_zen = 1;
- policy->cur = get_current_freq(cpu);
- policy->shared_type = CPUFREQ_SHARED_TYPE_NONE;
- unsigned int max_boost = get_max_freq(cpu);
- u8 virtual_pstates = 16;
- unsigned int max_freq = get_max_freq(policy->cpu);
- unsigned int min_freq = perf->states[perf->state_count - 1].core_frequency * 1000;
- unsigned int step = (max_freq - min_freq) / (virtual_pstates - 1);
- freq_table = kcalloc(virtual_pstates + 1, sizeof(*freq_table), GFP_KERNEL);
- for (int i = 0; i < virtual_pstates; i++) {
- freq_table[i].driver_data = i;
- freq_table[i].frequency = max_freq - (i * step);
- }
- freq_table[virtual_pstates].frequency = CPUFREQ_TABLE_END;
- policy->freq_table = freq_table;
- if (max_boost) {
- policy->cpuinfo.max_freq = max_boost;
- policy->max = max_boost;
+
+ if (perf->state_count > 0 && perf->states) {
+ policy->cur = get_current_freq(cpu);
+ policy->shared_type = CPUFREQ_SHARED_TYPE_NONE;
+ unsigned int max_boost = get_max_freq(cpu);
+ u8 virtual_pstates = 16;
+ unsigned int max_freq = get_max_freq(policy->cpu);
+ unsigned int min_freq = perf->states[perf->state_count - 1].core_frequency * 1000;
+ unsigned int step = (max_freq - min_freq) / (virtual_pstates - 1);
+ freq_table = kcalloc(virtual_pstates + 1, sizeof(*freq_table), GFP_KERNEL);
+ for (int i = 0; i < virtual_pstates; i++) {
+ freq_table[i].driver_data = i;
+ freq_table[i].frequency = max_freq - (i * step);
+ }
+ freq_table[virtual_pstates].frequency = CPUFREQ_TABLE_END;
+ policy->freq_table = freq_table;
+ if (max_boost) {
+ policy->cpuinfo.max_freq = max_boost;
+ policy->max = max_boost;
+ } else {
+ policy->cpuinfo.max_freq = perf->states[0].core_frequency * 1000;
+ }
+ return 0;
} else {
- policy->cpuinfo.max_freq = perf->states[0].core_frequency * 1000;
+ pr_warn("ACPI Table didnt provide any P-States");
+ unsigned int max_freq = get_max_freq(cpu);
+
+ if (max_freq == 0)
+ max_freq = 2000000;
+ u8 virtual_pstates = 16;
+ unsigned int step = 25000;
+ freq_table = kcalloc(virtual_pstates + 1, sizeof(*freq_table), GFP_KERNEL);
+ if (!freq_table) {
+ result = -ENOMEM;
+ goto err_unreg;
+ }
+ for (int i = 0; i < virtual_pstates; i++) {
+ freq_table[i].driver_data = i;
+ freq_table[i].frequency = max_freq - (i * step);
+ }
+ freq_table[virtual_pstates].frequency = CPUFREQ_TABLE_END;
+ policy->freq_table = freq_table;
+ policy->cpuinfo.max_freq = max_freq;
+ policy->max = max_freq;
+ policy->cur = get_current_freq(cpu);
+ return 0;
}
} else {
policy->shared_type = CPUFREQ_SHARED_TYPE_HW;
}
if (cpu_has(c, X86_FEATURE_CONSTANT_TSC))
acpi_cpufreq_driver.flags |= CPUFREQ_CONST_LOOPS;
-
- result = acpi_processor_register_performance(perf, cpu);
- if (result)
- goto err_free_mask;
-
/*
* Will let policy->cpus know about dependency only when software
* coordination is required.
@@ -893,7 +915,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
goto err_unreg;
}
- freq_table = kzalloc_objs(*freq_table, perf->state_count + 1);
+ freq_table = kcalloc(17, sizeof(*freq_table), GFP_KERNEL);
if (!freq_table) {
result = -ENOMEM;
goto err_unreg;
--
2.54.0
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-05-14 17:37 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-14 17:37 [PATCH v2] cpufreq: acpi-cpufreq: Add better support for amd zen yoy95104
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox