aboutsummaryrefslogtreecommitdiff
path: root/SOURCES
diff options
context:
space:
mode:
Diffstat (limited to 'SOURCES')
-rw-r--r--SOURCES/0001-amd-pstate.patch471
1 files changed, 467 insertions, 4 deletions
diff --git a/SOURCES/0001-amd-pstate.patch b/SOURCES/0001-amd-pstate.patch
index d7fd4b3..da6f35d 100644
--- a/SOURCES/0001-amd-pstate.patch
+++ b/SOURCES/0001-amd-pstate.patch
@@ -1,9 +1,10 @@
-From 1449b07b2bd2af451bba8ba17f7b01cf30b6471f Mon Sep 17 00:00:00 2001
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peter Jung <admin@ptr1337.dev>
Date: Fri, 23 Feb 2024 17:11:08 +0100
-Subject: [PATCH 1/7] amd-pstate
+Subject: [PATCH] amd-pstate
Signed-off-by: Peter Jung <admin@ptr1337.dev>
+Signed-off-by: Jan200101 <sentrycraft123@gmail.com>
---
.../admin-guide/kernel-parameters.txt | 5 +
Documentation/admin-guide/pm/amd-pstate.rst | 59 +++++-
@@ -573,6 +574,468 @@ index 1c5ca92a0555..5d62beea2712 100644
#endif
#ifdef CONFIG_CPU_FREQ_STAT
---
-2.43.2
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Perry Yuan <perry.yuan@amd.com>
+Date: Wed, 31 Jan 2024 16:50:15 +0800
+Subject: [PATCH] AMD Pstate Fixes And Enhancements
+
+The patch series adds some fixes and enhancements to the AMD pstate driver.
+It enables CPPC v2 for certain processors in the family 17H, as requested
+by TR40 processor users who expect improved performance and lower system
+temperature.
+
+Additionally, it fixes the initialization of nominal_freq for each cpudata
+and changes latency and delay values to be read from platform firmware firstly
+for more accurate timing.
+
+A new quirk is also added for legacy processors that lack CPPC capabilities,
+which caused the pstate driver to fail loading.
+
+I would greatly appreciate any feedbacks.
+
+Thank you!
+
+Perry Yuan (6):
+ ACPI: CPPC: enable AMD CPPC V2 support for family 17h processors
+ cpufreq:amd-pstate: fix the nominal freq value set
+ cpufreq:amd-pstate: initialize nominal_freq of each cpudata
+ cpufreq:amd-pstate: get pstate transition delay and latency value from
+ ACPI tables
+ cppc_acpi: print error message if CPPC is unsupported
+ cpufreq:amd-pstate: add quirk for the pstate CPPC capabilities missing
+
+ arch/x86/kernel/acpi/cppc.c | 2 +-
+ drivers/acpi/cppc_acpi.c | 6 +-
+ drivers/cpufreq/amd-pstate.c | 112 ++++++++++++++++++++++++++++-------
+ include/linux/amd-pstate.h | 6 ++
+ 4 files changed, 102 insertions(+), 24 deletions(-)
+
+--
+2.34.1
+
+Signed-off-by: Jan200101 <sentrycraft123@gmail.com>
+
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Perry Yuan <perry.yuan@amd.com>
+Date: Wed, 31 Jan 2024 16:50:16 +0800
+Subject: [PATCH] ACPI: CPPC: enable AMD CPPC V2 support for family 17h
+ processors
+
+As there are some AMD processors which only support CPPC V2 firmware and
+BIOS implementation, the amd_pstate driver will be failed to load when
+system booting with below kernel warning message:
+
+[ 0.477523] amd_pstate: the _CPC object is not present in SBIOS or ACPI disabled
+
+To make the amd_pstate driver can be loaded on those TR40 processors, it
+needs to match x86_model from 0x30 to 0x7F for family 17H.
+With the change, the system can load amd_pstate driver as expected.
+
+Reported-by: Gino Badouri <badouri.g@gmail.com>
+Issue: https://bugzilla.kernel.org/show_bug.cgi?id=218171
+Fixes: fbd74d1689 ("ACPI: CPPC: Fix enabling CPPC on AMD systems with shared memory")
+Signed-off-by: Perry Yuan <perry.yuan@amd.com>
+Signed-off-by: Jan200101 <sentrycraft123@gmail.com>
+---
+ arch/x86/kernel/acpi/cppc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/x86/kernel/acpi/cppc.c b/arch/x86/kernel/acpi/cppc.c
+index 8d8752b44f11..ff8f25faca3d 100644
+--- a/arch/x86/kernel/acpi/cppc.c
++++ b/arch/x86/kernel/acpi/cppc.c
+@@ -20,7 +20,7 @@ bool cpc_supported_by_cpu(void)
+ (boot_cpu_data.x86_model >= 0x20 && boot_cpu_data.x86_model <= 0x2f)))
+ return true;
+ else if (boot_cpu_data.x86 == 0x17 &&
+- boot_cpu_data.x86_model >= 0x70 && boot_cpu_data.x86_model <= 0x7f)
++ boot_cpu_data.x86_model >= 0x30 && boot_cpu_data.x86_model <= 0x7f)
+ return true;
+ return boot_cpu_has(X86_FEATURE_CPPC);
+ }
+
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Perry Yuan <perry.yuan@amd.com>
+Date: Wed, 31 Jan 2024 16:50:17 +0800
+Subject: [PATCH] cpufreq:amd-pstate: fix the nominal freq value set
+
+Address an untested error where the nominal_freq was returned in KHz
+instead of the correct MHz units, this oversight led to a wrong
+nominal_freq set and resued, it will cause the max frequency of core to
+be initialized with a wrong frequency value.
+
+Cc: stable@vger.kernel.org
+Fixes: ec437d71db7 ("cpufreq: amd-pstate: Introduce a new AMD P-State driver to support future processors")
+Signed-off-by: Perry Yuan <perry.yuan@amd.com>
+Signed-off-by: Jan200101 <sentrycraft123@gmail.com>
+---
+ drivers/cpufreq/amd-pstate.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
+index 54df68773620..d2591ef3b4f6 100644
+--- a/drivers/cpufreq/amd-pstate.c
++++ b/drivers/cpufreq/amd-pstate.c
+@@ -638,8 +638,7 @@ static int amd_get_nominal_freq(struct amd_cpudata *cpudata)
+ if (ret)
+ return ret;
+
+- /* Switch to khz */
+- return cppc_perf.nominal_freq * 1000;
++ return cppc_perf.nominal_freq;
+ }
+
+ static int amd_get_lowest_nonlinear_freq(struct amd_cpudata *cpudata)
+
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Perry Yuan <perry.yuan@amd.com>
+Date: Wed, 31 Jan 2024 16:50:18 +0800
+Subject: [PATCH] cpufreq:amd-pstate: initialize nominal_freq of each cpudata
+
+Optimizes the process of retrieving the nominal frequency by utilizing
+'cpudata->nominal_freq' instead of repeatedly accessing the cppc_acpi interface.
+
+To enhance efficiency and reduce the CPU load, shifted to using
+'cpudata->nominal_freq'. It allows for the nominal frequency to be accessed
+directly from the cached data in 'cpudata' of each CPU.
+It will also slightly reduce the frequency change latency while using pstate
+driver passive mode.
+
+Signed-off-by: Perry Yuan <perry.yuan@amd.com>
+Signed-off-by: Jan200101 <sentrycraft123@gmail.com>
+---
+ drivers/cpufreq/amd-pstate.c | 26 ++++++++++++++------------
+ 1 file changed, 14 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
+index d2591ef3b4f6..fa4908b37793 100644
+--- a/drivers/cpufreq/amd-pstate.c
++++ b/drivers/cpufreq/amd-pstate.c
+@@ -617,7 +617,7 @@ static int amd_get_max_freq(struct amd_cpudata *cpudata)
+ if (ret)
+ return ret;
+
+- nominal_freq = cppc_perf.nominal_freq;
++ nominal_freq = READ_ONCE(cpudata->nominal_freq);
+ nominal_perf = READ_ONCE(cpudata->nominal_perf);
+ max_perf = READ_ONCE(cpudata->highest_perf);
+
+@@ -652,7 +652,7 @@ static int amd_get_lowest_nonlinear_freq(struct amd_cpudata *cpudata)
+ if (ret)
+ return ret;
+
+- nominal_freq = cppc_perf.nominal_freq;
++ nominal_freq = READ_ONCE(cpudata->nominal_freq);
+ nominal_perf = READ_ONCE(cpudata->nominal_perf);
+
+ lowest_nonlinear_perf = cppc_perf.lowest_nonlinear_perf;
+@@ -846,13 +846,15 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
+ goto free_cpudata1;
+
+ min_freq = amd_get_min_freq(cpudata);
+- max_freq = amd_get_max_freq(cpudata);
+ nominal_freq = amd_get_nominal_freq(cpudata);
++ cpudata->nominal_freq = nominal_freq;
++ max_freq = amd_get_max_freq(cpudata);
+ lowest_nonlinear_freq = amd_get_lowest_nonlinear_freq(cpudata);
+
+- 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);
++ if (min_freq < 0 || max_freq < 0 || min_freq > max_freq || nominal_freq == 0) {
++ dev_err(dev, "min_freq(%d) or max_freq(%d) or nominal_freq(%d) \
++ value is incorrect\n", \
++ min_freq, max_freq, nominal_freq);
+ ret = -EINVAL;
+ goto free_cpudata1;
+ }
+@@ -891,7 +893,6 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
+ 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;
+@@ -1308,12 +1309,14 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
+ goto free_cpudata1;
+
+ min_freq = amd_get_min_freq(cpudata);
+- max_freq = amd_get_max_freq(cpudata);
+ nominal_freq = amd_get_nominal_freq(cpudata);
++ cpudata->nominal_freq = nominal_freq;
++ max_freq = amd_get_max_freq(cpudata);
+ lowest_nonlinear_freq = amd_get_lowest_nonlinear_freq(cpudata);
+- 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);
++ if (min_freq < 0 || max_freq < 0 || min_freq > max_freq || nominal_freq == 0) {
++ dev_err(dev, "min_freq(%d) or max_freq(%d) or nominal_freq(%d) \
++ value is incorrect\n", \
++ min_freq, max_freq, nominal_freq);
+ ret = -EINVAL;
+ goto free_cpudata1;
+ }
+@@ -1326,7 +1329,6 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
+ /* 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;
+
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Perry Yuan <perry.yuan@amd.com>
+Date: Wed, 31 Jan 2024 16:50:19 +0800
+Subject: [PATCH] cpufreq:amd-pstate: get pstate transition delay and latency
+ value from ACPI tables
+
+make pstate driver initially retrieve the P-state transition delay and latency
+values from the BIOS ACPI tables which has more reasonable delay and latency
+values according to the platform design and requirements.
+
+Previously there values were hardcoded at specific value which may
+have conflicted with platform and it might not reflect the most accurate or
+optimized setting for the processor.
+
+[054h 0084 8] Preserve Mask : FFFFFFFF00000000
+[05Ch 0092 8] Write Mask : 0000000000000001
+[064h 0100 4] Command Latency : 00000FA0
+[068h 0104 4] Maximum Access Rate : 0000EA60
+[06Ch 0108 2] Minimum Turnaround Time : 0000
+
+Signed-off-by: Perry Yuan <perry.yuan@amd.com>
+Signed-off-by: Jan200101 <sentrycraft123@gmail.com>
+---
+ drivers/cpufreq/amd-pstate.c | 34 ++++++++++++++++++++++++++++++++--
+ 1 file changed, 32 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
+index fa4908b37793..484e89c9cd86 100644
+--- a/drivers/cpufreq/amd-pstate.c
++++ b/drivers/cpufreq/amd-pstate.c
+@@ -818,6 +818,36 @@ 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.
++ */
++static u32 amd_pstate_get_transition_delay_us(unsigned int cpu)
++{
++ u32 transition_delay_ns;
++
++ transition_delay_ns= cppc_get_transition_latency(cpu);
++ if (transition_delay_ns == CPUFREQ_ETERNAL)
++ return AMD_PSTATE_TRANSITION_DELAY;
++
++ return transition_delay_ns / NSEC_PER_USEC;
++}
++
++/**
++ * Get pstate transition latency value from ACPI tables that firmware set
++ * instead of using hardcode value directly.
++ */
++static u32 amd_pstate_get_transition_latency(unsigned int cpu)
++{
++ u32 transition_latency;
++
++ transition_latency = cppc_get_transition_latency(cpu);
++ if (transition_latency == CPUFREQ_ETERNAL)
++ return AMD_PSTATE_TRANSITION_LATENCY;
++
++ return transition_latency;
++}
++
+ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
+ {
+ int min_freq, max_freq, nominal_freq, lowest_nonlinear_freq, ret;
+@@ -859,8 +889,8 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
+ goto free_cpudata1;
+ }
+
+- policy->cpuinfo.transition_latency = AMD_PSTATE_TRANSITION_LATENCY;
+- policy->transition_delay_us = AMD_PSTATE_TRANSITION_DELAY;
++ policy->cpuinfo.transition_latency = amd_pstate_get_transition_latency(policy->cpu);
++ policy->transition_delay_us = amd_pstate_get_transition_delay_us(policy->cpu);
+
+ policy->min = min_freq;
+ policy->max = max_freq;
+
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Perry Yuan <perry.yuan@amd.com>
+Date: Wed, 31 Jan 2024 16:50:20 +0800
+Subject: [PATCH] cppc_acpi: print error message if CPPC is unsupported
+
+to be more clear what is wrong with CPPC when pstate driver failed to
+load which has dependency on the CPPC capabilities.
+
+Add one more debug message to notify user if CPPC is not supported by
+the CPU, then it will be easy to find out what need to fix for pstate
+driver loading issue.
+
+[ 0.477523] amd_pstate: the _CPC object is not present in SBIOS or ACPI disabled
+
+Above message is not clear enough to verify whether CPPC is not supported.
+
+Signed-off-by: Perry Yuan <perry.yuan@amd.com>
+Signed-off-by: Jan200101 <sentrycraft123@gmail.com>
+---
+ drivers/acpi/cppc_acpi.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
+index ad388a0e8484..6e89fc97c82f 100644
+--- a/drivers/acpi/cppc_acpi.c
++++ b/drivers/acpi/cppc_acpi.c
+@@ -676,8 +676,10 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
+
+ if (!osc_sb_cppc2_support_acked) {
+ pr_debug("CPPC v2 _OSC not acked\n");
+- if (!cpc_supported_by_cpu())
+- return -ENODEV;
++ if (!cpc_supported_by_cpu()) {
++ pr_debug("CPPC is not supported\n");
++ return -ENODEV;
++ }
+ }
+
+ /* Parse the ACPI _CPC table for this CPU. */
+
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Perry Yuan <perry.yuan@amd.com>
+Date: Wed, 31 Jan 2024 16:50:21 +0800
+Subject: [PATCH] cpufreq:amd-pstate: add quirk for the pstate CPPC
+ capabilities missing
+
+Add quirk table to get CPPC capabilities issue fixed by providing
+correct perf or frequency values while driver loading.
+
+If CPPC capabilities are not defined in the ACPI tables or wrongly
+defined by platform firmware, it needs to use quick to get those
+issues fixed with correct workaround values to make pstate driver
+can be loaded even though there are CPPC capabilities errors.
+
+Signed-off-by: Perry Yuan <perry.yuan@amd.com>
+Signed-off-by: Jan200101 <sentrycraft123@gmail.com>
+---
+ drivers/cpufreq/amd-pstate.c | 51 +++++++++++++++++++++++++++++++-----
+ include/linux/amd-pstate.h | 6 +++++
+ 2 files changed, 51 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
+index 484e89c9cd86..01ae446c08e6 100644
+--- a/drivers/cpufreq/amd-pstate.c
++++ b/drivers/cpufreq/amd-pstate.c
+@@ -66,6 +66,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)
+@@ -110,6 +111,32 @@ static unsigned int epp_values[] = {
+
+ typedef int (*cppc_mode_transition_fn)(int);
+
++static struct quirk_entry quirk_amd_7k62 = {
++ .nominal_freq = 2600,
++ .lowest_freq = 550,
++};
++
++static int __init dmi_matched(const struct dmi_system_id *dmi)
++{
++ quirks = dmi->driver_data;
++
++ return 1;
++}
++
++static const struct dmi_system_id amd_pstate_quirks_table[] __initconst = {
++ {
++ .callback = dmi_matched,
++ .ident = "AMD EPYC 7K62",
++ .matches = {
++ DMI_MATCH(DMI_PRODUCT_VERSION, "C1"),
++ DMI_MATCH(DMI_PRODUCT_SERIAL, "FX19911000028"),
++ },
++ .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;
+@@ -598,13 +625,19 @@ static void amd_pstate_adjust_perf(unsigned int cpu,
+ static int amd_get_min_freq(struct amd_cpudata *cpudata)
+ {
+ struct cppc_perf_caps cppc_perf;
++ u32 lowest_freq;
+
+ int ret = cppc_get_perf_caps(cpudata->cpu, &cppc_perf);
+ if (ret)
+ return ret;
+
++ if (quirks && quirks->lowest_freq)
++ lowest_freq = quirks->lowest_freq;
++ else
++ lowest_freq = cppc_perf.lowest_freq;
++
+ /* Switch to khz */
+- return cppc_perf.lowest_freq * 1000;
++ return lowest_freq * 1000;
+ }
+
+ static int amd_get_max_freq(struct amd_cpudata *cpudata)
+@@ -632,13 +665,14 @@ static int amd_get_max_freq(struct amd_cpudata *cpudata)
+
+ static int amd_get_nominal_freq(struct amd_cpudata *cpudata)
+ {
+- struct cppc_perf_caps cppc_perf;
++ u32 nominal_freq;
+
+- int ret = cppc_get_perf_caps(cpudata->cpu, &cppc_perf);
+- if (ret)
+- return ret;
++ if (quirks && quirks->nominal_freq)
++ nominal_freq = quirks->nominal_freq;
++ else
++ nominal_freq = READ_ONCE(cpudata->nominal_freq);
+
+- return cppc_perf.nominal_freq;
++ return nominal_freq;
+ }
+
+ static int amd_get_lowest_nonlinear_freq(struct amd_cpudata *cpudata)
+@@ -1672,6 +1706,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:
+ /* Disable on the following configs by default:
+diff --git a/include/linux/amd-pstate.h b/include/linux/amd-pstate.h
+index d21838835abd..7b2cbb892fd9 100644
+--- a/include/linux/amd-pstate.h
++++ b/include/linux/amd-pstate.h
+@@ -124,4 +124,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 */