aboutsummaryrefslogtreecommitdiff
path: root/SOURCES/0001-amd-pstate.patch
diff options
context:
space:
mode:
Diffstat (limited to 'SOURCES/0001-amd-pstate.patch')
-rw-r--r--SOURCES/0001-amd-pstate.patch304
1 files changed, 67 insertions, 237 deletions
diff --git a/SOURCES/0001-amd-pstate.patch b/SOURCES/0001-amd-pstate.patch
index 74fc021..8e7b5cb 100644
--- a/SOURCES/0001-amd-pstate.patch
+++ b/SOURCES/0001-amd-pstate.patch
@@ -1,151 +1,66 @@
-From f3018861226770c17b47bcda4d4fd4291ad00ae6 Mon Sep 17 00:00:00 2001
+From 14416a42f37d3455e6de7d249df9a76b40a456bf Mon Sep 17 00:00:00 2001
From: Peter Jung <admin@ptr1337.dev>
-Date: Sun, 16 Jun 2024 15:33:06 +0200
+Date: Fri, 21 Jun 2024 15:31:56 +0200
Subject: [PATCH 02/10] amd-pstate
Signed-off-by: Peter Jung <admin@ptr1337.dev>
---
- drivers/cpufreq/amd-pstate.c | 265 +++++++++++++++++++++--------------
- include/linux/amd-pstate.h | 20 ++-
- 2 files changed, 177 insertions(+), 108 deletions(-)
+ drivers/cpufreq/amd-pstate.c | 115 +++++++++++++++++++----------------
+ drivers/cpufreq/amd-pstate.h | 14 +++--
+ 2 files changed, 70 insertions(+), 59 deletions(-)
diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
-index e263db0385ab..cde3b91b4422 100644
+index 6c989d859b39..c08463f8dcac 100644
--- a/drivers/cpufreq/amd-pstate.c
+++ b/drivers/cpufreq/amd-pstate.c
-@@ -68,6 +68,7 @@ static struct cpufreq_driver amd_pstate_epp_driver;
- static int cppc_state = AMD_PSTATE_UNDEFINED;
- static bool cppc_enabled;
- static bool amd_pstate_prefcore = true;
-+static struct quirk_entry *quirks;
-
- /*
- * AMD Energy Preference Performance (EPP)
-@@ -112,6 +113,41 @@ static unsigned int epp_values[] = {
-
- typedef int (*cppc_mode_transition_fn)(int);
+@@ -85,15 +85,6 @@ struct quirk_entry {
+ u32 lowest_freq;
+ };
-+static struct quirk_entry quirk_amd_7k62 = {
-+ .nominal_freq = 2600,
-+ .lowest_freq = 550,
-+};
-+
-+static int __init dmi_matched_7k62_bios_bug(const struct dmi_system_id *dmi)
-+{
-+ /**
-+ * match the broken bios for family 17h processor support CPPC V2
-+ * broken BIOS lack of nominal_freq and lowest_freq capabilities
-+ * definition in ACPI tables
-+ */
-+ if (boot_cpu_has(X86_FEATURE_ZEN2)) {
-+ quirks = dmi->driver_data;
-+ pr_info("Overriding nominal and lowest frequencies for %s\n", dmi->ident);
-+ return 1;
-+ }
-+
-+ return 0;
-+}
-+
-+static const struct dmi_system_id amd_pstate_quirks_table[] __initconst = {
-+ {
-+ .callback = dmi_matched_7k62_bios_bug,
-+ .ident = "AMD EPYC 7K62",
-+ .matches = {
-+ DMI_MATCH(DMI_BIOS_VERSION, "5.14"),
-+ DMI_MATCH(DMI_BIOS_RELEASE, "12/12/2019"),
-+ },
-+ .driver_data = &quirk_amd_7k62,
-+ },
-+ {}
-+};
-+MODULE_DEVICE_TABLE(dmi, amd_pstate_quirks_table);
-+
- static inline int get_mode_idx_from_str(const char *str, size_t size)
- {
- int i;
-@@ -620,78 +656,6 @@ static void amd_pstate_adjust_perf(unsigned int cpu,
+-/*
+- * TODO: We need more time to fine tune processors with shared memory solution
+- * with community together.
+- *
+- * There are some performance drops on the CPU benchmarks which reports from
+- * Suse. We are co-working with them to fine tune the shared memory solution. So
+- * we disable it by default to go acpi-cpufreq on these processors and add a
+- * module parameter to be able to enable it manually for debugging.
+- */
+ static struct cpufreq_driver *current_pstate_driver;
+ static struct cpufreq_driver amd_pstate_driver;
+ static struct cpufreq_driver amd_pstate_epp_driver;
+@@ -688,26 +679,6 @@ static void amd_pstate_adjust_perf(unsigned int cpu,
cpufreq_cpu_put(policy);
}
-static int amd_get_min_freq(struct amd_cpudata *cpudata)
-{
-- struct cppc_perf_caps cppc_perf;
--
-- int ret = cppc_get_perf_caps(cpudata->cpu, &cppc_perf);
-- if (ret)
-- return ret;
--
-- /* Switch to khz */
-- return cppc_perf.lowest_freq * 1000;
+- return READ_ONCE(cpudata->min_freq);
-}
-
-static int amd_get_max_freq(struct amd_cpudata *cpudata)
-{
-- struct cppc_perf_caps cppc_perf;
-- u32 max_perf, max_freq, nominal_freq, nominal_perf;
-- u64 boost_ratio;
--
-- int ret = cppc_get_perf_caps(cpudata->cpu, &cppc_perf);
-- if (ret)
-- return ret;
--
-- nominal_freq = cppc_perf.nominal_freq;
-- nominal_perf = READ_ONCE(cpudata->nominal_perf);
-- max_perf = READ_ONCE(cpudata->highest_perf);
--
-- boost_ratio = div_u64(max_perf << SCHED_CAPACITY_SHIFT,
-- nominal_perf);
--
-- max_freq = nominal_freq * boost_ratio >> SCHED_CAPACITY_SHIFT;
--
-- /* Switch to khz */
-- return max_freq * 1000;
+- return READ_ONCE(cpudata->max_freq);
-}
-
-static int amd_get_nominal_freq(struct amd_cpudata *cpudata)
-{
-- struct cppc_perf_caps cppc_perf;
--
-- int ret = cppc_get_perf_caps(cpudata->cpu, &cppc_perf);
-- if (ret)
-- return ret;
--
-- /* Switch to khz */
-- return cppc_perf.nominal_freq * 1000;
+- return READ_ONCE(cpudata->nominal_freq);
-}
-
-static int amd_get_lowest_nonlinear_freq(struct amd_cpudata *cpudata)
-{
-- struct cppc_perf_caps cppc_perf;
-- u32 lowest_nonlinear_freq, lowest_nonlinear_perf,
-- nominal_freq, nominal_perf;
-- u64 lowest_nonlinear_ratio;
--
-- int ret = cppc_get_perf_caps(cpudata->cpu, &cppc_perf);
-- if (ret)
-- return ret;
--
-- nominal_freq = cppc_perf.nominal_freq;
-- nominal_perf = READ_ONCE(cpudata->nominal_perf);
--
-- lowest_nonlinear_perf = cppc_perf.lowest_nonlinear_perf;
--
-- lowest_nonlinear_ratio = div_u64(lowest_nonlinear_perf << SCHED_CAPACITY_SHIFT,
-- nominal_perf);
--
-- lowest_nonlinear_freq = nominal_freq * lowest_nonlinear_ratio >> SCHED_CAPACITY_SHIFT;
--
-- /* Switch to khz */
-- return lowest_nonlinear_freq * 1000;
+- return READ_ONCE(cpudata->lowest_nonlinear_freq);
-}
-
static int amd_pstate_set_boost(struct cpufreq_policy *policy, int state)
{
struct amd_cpudata *cpudata = policy->driver_data;
-@@ -844,9 +808,93 @@ static void amd_pstate_update_limits(unsigned int cpu)
+@@ -860,7 +831,37 @@ static void amd_pstate_update_limits(unsigned int cpu)
mutex_unlock(&amd_pstate_driver_lock);
}
+-/**
+/*
+ * Get pstate transition delay time from ACPI tables that firmware set
+ * instead of using hardcode value directly.
@@ -177,59 +92,19 @@ index e263db0385ab..cde3b91b4422 100644
+}
+
+/*
-+ * amd_pstate_init_freq: Initialize the max_freq, min_freq,
-+ * nominal_freq and lowest_nonlinear_freq for
-+ * the @cpudata object.
-+ *
-+ * Requires: highest_perf, lowest_perf, nominal_perf and
-+ * lowest_nonlinear_perf members of @cpudata to be
-+ * initialized.
-+ *
-+ * Returns 0 on success, non-zero value on failure.
-+ */
-+static int amd_pstate_init_freq(struct amd_cpudata *cpudata)
-+{
-+ int ret;
-+ u32 min_freq;
-+ u32 highest_perf, max_freq;
-+ u32 nominal_perf, nominal_freq;
-+ u32 lowest_nonlinear_perf, lowest_nonlinear_freq;
-+ u32 boost_ratio, lowest_nonlinear_ratio;
-+ struct cppc_perf_caps cppc_perf;
-+
-+ ret = cppc_get_perf_caps(cpudata->cpu, &cppc_perf);
-+ if (ret)
-+ return ret;
-+
-+ if (quirks && quirks->lowest_freq)
-+ min_freq = quirks->lowest_freq * 1000;
-+ else
-+ min_freq = cppc_perf.lowest_freq * 1000;
-+
-+ if (quirks && quirks->nominal_freq)
-+ nominal_freq = quirks->nominal_freq ;
-+ else
-+ nominal_freq = cppc_perf.nominal_freq;
-+
-+ nominal_perf = READ_ONCE(cpudata->nominal_perf);
-+
-+ highest_perf = READ_ONCE(cpudata->highest_perf);
-+ boost_ratio = div_u64(highest_perf << SCHED_CAPACITY_SHIFT, nominal_perf);
-+ max_freq = (nominal_freq * boost_ratio >> SCHED_CAPACITY_SHIFT) * 1000;
-+
-+ lowest_nonlinear_perf = READ_ONCE(cpudata->lowest_nonlinear_perf);
-+ lowest_nonlinear_ratio = div_u64(lowest_nonlinear_perf << SCHED_CAPACITY_SHIFT,
-+ nominal_perf);
-+ lowest_nonlinear_freq = (nominal_freq * lowest_nonlinear_ratio >> SCHED_CAPACITY_SHIFT) * 1000;
-+
-+ WRITE_ONCE(cpudata->min_freq, min_freq);
-+ WRITE_ONCE(cpudata->lowest_nonlinear_freq, lowest_nonlinear_freq);
-+ WRITE_ONCE(cpudata->nominal_freq, nominal_freq);
-+ WRITE_ONCE(cpudata->max_freq, max_freq);
-+
-+ return 0;
-+}
-+
+ * amd_pstate_init_freq: Initialize the max_freq, min_freq,
+ * nominal_freq and lowest_nonlinear_freq for
+ * the @cpudata object.
+@@ -881,7 +882,6 @@ static int amd_pstate_init_freq(struct amd_cpudata *cpudata)
+ u32 boost_ratio, lowest_nonlinear_ratio;
+ struct cppc_perf_caps cppc_perf;
+
+-
+ ret = cppc_get_perf_caps(cpudata->cpu, &cppc_perf);
+ if (ret)
+ return ret;
+@@ -917,7 +917,7 @@ static int amd_pstate_init_freq(struct amd_cpudata *cpudata)
+
static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
{
- int min_freq, max_freq, nominal_freq, lowest_nonlinear_freq, ret;
@@ -237,7 +112,7 @@ index e263db0385ab..cde3b91b4422 100644
struct device *dev;
struct amd_cpudata *cpudata;
-@@ -871,20 +919,25 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
+@@ -946,20 +946,21 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
if (ret)
goto free_cpudata1;
@@ -245,17 +120,13 @@ index e263db0385ab..cde3b91b4422 100644
- max_freq = amd_get_max_freq(cpudata);
- nominal_freq = amd_get_nominal_freq(cpudata);
- lowest_nonlinear_freq = amd_get_lowest_nonlinear_freq(cpudata);
-+ ret = amd_pstate_init_freq(cpudata);
-+ if (ret)
-+ goto free_cpudata1;
++ min_freq = READ_ONCE(cpudata->min_freq);
++ max_freq = READ_ONCE(cpudata->max_freq);
++ nominal_freq = READ_ONCE(cpudata->nominal_freq);
- if (min_freq < 0 || max_freq < 0 || min_freq > max_freq) {
- dev_err(dev, "min_freq(%d) or max_freq(%d) value is incorrect\n",
- min_freq, max_freq);
-+ min_freq = READ_ONCE(cpudata->min_freq);
-+ max_freq = READ_ONCE(cpudata->max_freq);
-+ nominal_freq = READ_ONCE(cpudata->nominal_freq);
-+
+ if (min_freq <= 0 || max_freq <= 0 ||
+ nominal_freq <= 0 || min_freq > max_freq) {
+ dev_err(dev,
@@ -272,21 +143,7 @@ index e263db0385ab..cde3b91b4422 100644
policy->min = min_freq;
policy->max = max_freq;
-@@ -912,13 +965,8 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
- goto free_cpudata2;
- }
-
-- /* Initial processor data capability frequencies */
-- cpudata->max_freq = max_freq;
-- cpudata->min_freq = min_freq;
- cpudata->max_limit_freq = max_freq;
- cpudata->min_limit_freq = min_freq;
-- cpudata->nominal_freq = nominal_freq;
-- cpudata->lowest_nonlinear_freq = lowest_nonlinear_freq;
-
- policy->driver_data = cpudata;
-
-@@ -982,7 +1030,7 @@ static ssize_t show_amd_pstate_max_freq(struct cpufreq_policy *policy,
+@@ -1052,7 +1053,7 @@ static ssize_t show_amd_pstate_max_freq(struct cpufreq_policy *policy,
int max_freq;
struct amd_cpudata *cpudata = policy->driver_data;
@@ -295,7 +152,7 @@ index e263db0385ab..cde3b91b4422 100644
if (max_freq < 0)
return max_freq;
-@@ -995,7 +1043,7 @@ static ssize_t show_amd_pstate_lowest_nonlinear_freq(struct cpufreq_policy *poli
+@@ -1065,7 +1066,7 @@ static ssize_t show_amd_pstate_lowest_nonlinear_freq(struct cpufreq_policy *poli
int freq;
struct amd_cpudata *cpudata = policy->driver_data;
@@ -304,7 +161,7 @@ index e263db0385ab..cde3b91b4422 100644
if (freq < 0)
return freq;
-@@ -1306,7 +1354,7 @@ static bool amd_pstate_acpi_pm_profile_undefined(void)
+@@ -1376,7 +1377,7 @@ static bool amd_pstate_acpi_pm_profile_undefined(void)
static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
{
@@ -313,7 +170,7 @@ index e263db0385ab..cde3b91b4422 100644
struct amd_cpudata *cpudata;
struct device *dev;
u64 value;
-@@ -1333,13 +1381,18 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
+@@ -1407,13 +1408,14 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
if (ret)
goto free_cpudata1;
@@ -324,10 +181,6 @@ index e263db0385ab..cde3b91b4422 100644
- if (min_freq < 0 || max_freq < 0 || min_freq > max_freq) {
- dev_err(dev, "min_freq(%d) or max_freq(%d) value is incorrect\n",
- min_freq, max_freq);
-+ ret = amd_pstate_init_freq(cpudata);
-+ if (ret)
-+ goto free_cpudata1;
-+
+ min_freq = READ_ONCE(cpudata->min_freq);
+ max_freq = READ_ONCE(cpudata->max_freq);
+ nominal_freq = READ_ONCE(cpudata->nominal_freq);
@@ -339,20 +192,7 @@ index e263db0385ab..cde3b91b4422 100644
ret = -EINVAL;
goto free_cpudata1;
}
-@@ -1349,12 +1402,6 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
- /* It will be updated by governor */
- policy->cur = policy->cpuinfo.min_freq;
-
-- /* Initial processor data capability frequencies */
-- cpudata->max_freq = max_freq;
-- cpudata->min_freq = min_freq;
-- cpudata->nominal_freq = nominal_freq;
-- cpudata->lowest_nonlinear_freq = lowest_nonlinear_freq;
--
- policy->driver_data = cpudata;
-
- cpudata->epp_cached = amd_pstate_get_epp(cpudata, 0);
-@@ -1394,6 +1441,13 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
+@@ -1462,6 +1464,13 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
static int amd_pstate_epp_cpu_exit(struct cpufreq_policy *policy)
{
@@ -366,23 +206,24 @@ index e263db0385ab..cde3b91b4422 100644
pr_debug("CPU %d exiting\n", policy->cpu);
return 0;
}
-@@ -1672,6 +1726,11 @@ static int __init amd_pstate_init(void)
- if (cpufreq_get_current_driver())
- return -EEXIST;
-
-+ quirks = NULL;
-+
-+ /* check if this machine need CPPC quirks */
-+ dmi_check_system(amd_pstate_quirks_table);
-+
- switch (cppc_state) {
- case AMD_PSTATE_UNDEFINED:
+@@ -1750,11 +1759,9 @@ static int __init amd_pstate_init(void)
/* Disable on the following configs by default:
-diff --git a/include/linux/amd-pstate.h b/include/linux/amd-pstate.h
-index d21838835abd..d58fc022ec46 100644
---- a/include/linux/amd-pstate.h
-+++ b/include/linux/amd-pstate.h
-@@ -49,13 +49,17 @@ struct amd_aperf_mperf {
+ * 1. Undefined platforms
+ * 2. Server platforms
+- * 3. Shared memory designs
+ */
+ if (amd_pstate_acpi_pm_profile_undefined() ||
+- amd_pstate_acpi_pm_profile_server() ||
+- !boot_cpu_has(X86_FEATURE_CPPC)) {
++ amd_pstate_acpi_pm_profile_server()) {
+ pr_info("driver load is disabled, boot with specific mode to enable this\n");
+ return -ENODEV;
+ }
+diff --git a/drivers/cpufreq/amd-pstate.h b/drivers/cpufreq/amd-pstate.h
+index bc341f35908d..e6a28e7f4dbf 100644
+--- a/drivers/cpufreq/amd-pstate.h
++++ b/drivers/cpufreq/amd-pstate.h
+@@ -42,13 +42,17 @@ struct amd_aperf_mperf {
* @lowest_perf: the absolute lowest performance level of the processor
* @prefcore_ranking: the preferred core ranking, the higher value indicates a higher
* priority.
@@ -405,17 +246,6 @@ index d21838835abd..d58fc022ec46 100644
* @boost_supported: check whether the Processor or SBIOS supports boost mode
* @hw_prefcore: check whether HW supports preferred core featue.
* Only when hw_prefcore and early prefcore param are true,
-@@ -124,4 +128,10 @@ static const char * const amd_pstate_mode_string[] = {
- [AMD_PSTATE_GUIDED] = "guided",
- NULL,
- };
-+
-+struct quirk_entry {
-+ u32 nominal_freq;
-+ u32 lowest_freq;
-+};
-+
- #endif /* _LINUX_AMD_PSTATE_H */
--
2.45.2