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.patch734
1 files changed, 0 insertions, 734 deletions
diff --git a/SOURCES/0001-amd-pstate.patch b/SOURCES/0001-amd-pstate.patch
deleted file mode 100644
index c865d00..0000000
--- a/SOURCES/0001-amd-pstate.patch
+++ /dev/null
@@ -1,734 +0,0 @@
-From 06c02d91fcfeb0fde264f03f0e364161b11a678d Mon Sep 17 00:00:00 2001
-From: Peter Jung <admin@ptr1337.dev>
-Date: Sat, 3 Aug 2024 09:32:45 +0200
-Subject: [PATCH 01/12] amd-pstate
-
-Signed-off-by: Peter Jung <admin@ptr1337.dev>
----
- Documentation/admin-guide/pm/amd-pstate.rst | 18 +-
- arch/x86/include/asm/cpufeatures.h | 1 +
- arch/x86/include/asm/msr-index.h | 2 +
- arch/x86/kernel/cpu/scattered.c | 1 +
- drivers/cpufreq/Kconfig.x86 | 1 +
- drivers/cpufreq/acpi-cpufreq.c | 3 +-
- drivers/cpufreq/amd-pstate.c | 307 ++++++++++++++------
- drivers/cpufreq/amd-pstate.h | 2 +
- drivers/cpufreq/cpufreq.c | 11 +-
- 9 files changed, 251 insertions(+), 95 deletions(-)
-
-diff --git a/Documentation/admin-guide/pm/amd-pstate.rst b/Documentation/admin-guide/pm/amd-pstate.rst
-index 1e0d101b020a..d0324d44f548 100644
---- a/Documentation/admin-guide/pm/amd-pstate.rst
-+++ b/Documentation/admin-guide/pm/amd-pstate.rst
-@@ -281,6 +281,22 @@ integer values defined between 0 to 255 when EPP feature is enabled by platform
- firmware, if EPP feature is disabled, driver will ignore the written value
- This attribute is read-write.
-
-+``boost``
-+The `boost` sysfs attribute provides control over the CPU core
-+performance boost, allowing users to manage the maximum frequency limitation
-+of the CPU. This attribute can be used to enable or disable the boost feature
-+on individual CPUs.
-+
-+When the boost feature is enabled, the CPU can dynamically increase its frequency
-+beyond the base frequency, providing enhanced performance for demanding workloads.
-+On the other hand, disabling the boost feature restricts the CPU to operate at the
-+base frequency, which may be desirable in certain scenarios to prioritize power
-+efficiency or manage temperature.
-+
-+To manipulate the `boost` attribute, users can write a value of `0` to disable the
-+boost or `1` to enable it, for the respective CPU using the sysfs path
-+`/sys/devices/system/cpu/cpuX/cpufreq/boost`, where `X` represents the CPU number.
-+
- Other performance and frequency values can be read back from
- ``/sys/devices/system/cpu/cpuX/acpi_cppc/``, see :ref:`cppc_sysfs`.
-
-@@ -406,7 +422,7 @@ control its functionality at the system level. They are located in the
- ``/sys/devices/system/cpu/amd_pstate/`` directory and affect all CPUs.
-
- ``status``
-- Operation mode of the driver: "active", "passive" or "disable".
-+ Operation mode of the driver: "active", "passive", "guided" or "disable".
-
- "active"
- The driver is functional and in the ``active mode``
-diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
-index 3c7434329661..6c128d463a14 100644
---- a/arch/x86/include/asm/cpufeatures.h
-+++ b/arch/x86/include/asm/cpufeatures.h
-@@ -470,6 +470,7 @@
- #define X86_FEATURE_BHI_CTRL (21*32+ 2) /* "" BHI_DIS_S HW control available */
- #define X86_FEATURE_CLEAR_BHB_HW (21*32+ 3) /* "" BHI_DIS_S HW control enabled */
- #define X86_FEATURE_CLEAR_BHB_LOOP_ON_VMEXIT (21*32+ 4) /* "" Clear branch history at vmexit using SW loop */
-+#define X86_FEATURE_FAST_CPPC (21*32 + 5) /* "" AMD Fast CPPC */
-
- /*
- * BUG word(s)
-diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
-index e022e6eb766c..384739d592af 100644
---- a/arch/x86/include/asm/msr-index.h
-+++ b/arch/x86/include/asm/msr-index.h
-@@ -781,6 +781,8 @@
- #define MSR_K7_HWCR_IRPERF_EN BIT_ULL(MSR_K7_HWCR_IRPERF_EN_BIT)
- #define MSR_K7_FID_VID_CTL 0xc0010041
- #define MSR_K7_FID_VID_STATUS 0xc0010042
-+#define MSR_K7_HWCR_CPB_DIS_BIT 25
-+#define MSR_K7_HWCR_CPB_DIS BIT_ULL(MSR_K7_HWCR_CPB_DIS_BIT)
-
- /* K6 MSRs */
- #define MSR_K6_WHCR 0xc0000082
-diff --git a/arch/x86/kernel/cpu/scattered.c b/arch/x86/kernel/cpu/scattered.c
-index af5aa2c754c2..c84c30188fdf 100644
---- a/arch/x86/kernel/cpu/scattered.c
-+++ b/arch/x86/kernel/cpu/scattered.c
-@@ -45,6 +45,7 @@ static const struct cpuid_bit cpuid_bits[] = {
- { X86_FEATURE_HW_PSTATE, CPUID_EDX, 7, 0x80000007, 0 },
- { X86_FEATURE_CPB, CPUID_EDX, 9, 0x80000007, 0 },
- { X86_FEATURE_PROC_FEEDBACK, CPUID_EDX, 11, 0x80000007, 0 },
-+ { X86_FEATURE_FAST_CPPC, CPUID_EDX, 15, 0x80000007, 0 },
- { X86_FEATURE_MBA, CPUID_EBX, 6, 0x80000008, 0 },
- { X86_FEATURE_SMBA, CPUID_EBX, 2, 0x80000020, 0 },
- { X86_FEATURE_BMEC, CPUID_EBX, 3, 0x80000020, 0 },
-diff --git a/drivers/cpufreq/Kconfig.x86 b/drivers/cpufreq/Kconfig.x86
-index 438c9e75a04d..97c2d4f15d76 100644
---- a/drivers/cpufreq/Kconfig.x86
-+++ b/drivers/cpufreq/Kconfig.x86
-@@ -71,6 +71,7 @@ config X86_AMD_PSTATE_DEFAULT_MODE
- config X86_AMD_PSTATE_UT
- tristate "selftest for AMD Processor P-State driver"
- depends on X86 && ACPI_PROCESSOR
-+ depends on X86_AMD_PSTATE
- default n
- help
- This kernel module is used for testing. It's safe to say M here.
-diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c
-index 4ac3a35dcd98..f4f8587c4ea0 100644
---- a/drivers/cpufreq/acpi-cpufreq.c
-+++ b/drivers/cpufreq/acpi-cpufreq.c
-@@ -50,8 +50,6 @@ enum {
- #define AMD_MSR_RANGE (0x7)
- #define HYGON_MSR_RANGE (0x7)
-
--#define MSR_K7_HWCR_CPB_DIS (1ULL << 25)
--
- struct acpi_cpufreq_data {
- unsigned int resume;
- unsigned int cpu_feature;
-@@ -139,6 +137,7 @@ static int set_boost(struct cpufreq_policy *policy, int val)
- (void *)(long)val, 1);
- pr_debug("CPU %*pbl: Core Boosting %s.\n",
- cpumask_pr_args(policy->cpus), str_enabled_disabled(val));
-+ policy->boost_enabled = val;
-
- return 0;
- }
-diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
-index a092b13ffbc2..804fab4ebb26 100644
---- a/drivers/cpufreq/amd-pstate.c
-+++ b/drivers/cpufreq/amd-pstate.c
-@@ -51,6 +51,7 @@
-
- #define AMD_PSTATE_TRANSITION_LATENCY 20000
- #define AMD_PSTATE_TRANSITION_DELAY 1000
-+#define AMD_PSTATE_FAST_CPPC_TRANSITION_DELAY 600
- #define CPPC_HIGHEST_PERF_PERFORMANCE 196
- #define CPPC_HIGHEST_PERF_DEFAULT 166
-
-@@ -85,15 +86,6 @@ struct quirk_entry {
- u32 lowest_freq;
- };
-
--/*
-- * 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;
-@@ -157,7 +149,7 @@ static int __init dmi_matched_7k62_bios_bug(const struct dmi_system_id *dmi)
- * broken BIOS lack of nominal_freq and lowest_freq capabilities
- * definition in ACPI tables
- */
-- if (boot_cpu_has(X86_FEATURE_ZEN2)) {
-+ if (cpu_feature_enabled(X86_FEATURE_ZEN2)) {
- quirks = dmi->driver_data;
- pr_info("Overriding nominal and lowest frequencies for %s\n", dmi->ident);
- return 1;
-@@ -199,7 +191,7 @@ static s16 amd_pstate_get_epp(struct amd_cpudata *cpudata, u64 cppc_req_cached)
- u64 epp;
- int ret;
-
-- if (boot_cpu_has(X86_FEATURE_CPPC)) {
-+ if (cpu_feature_enabled(X86_FEATURE_CPPC)) {
- if (!cppc_req_cached) {
- epp = rdmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ,
- &cppc_req_cached);
-@@ -272,7 +264,7 @@ static int amd_pstate_set_epp(struct amd_cpudata *cpudata, u32 epp)
- int ret;
- struct cppc_perf_ctrls perf_ctrls;
-
-- if (boot_cpu_has(X86_FEATURE_CPPC)) {
-+ if (cpu_feature_enabled(X86_FEATURE_CPPC)) {
- u64 value = READ_ONCE(cpudata->cppc_req_cached);
-
- value &= ~GENMASK_ULL(31, 24);
-@@ -524,7 +514,10 @@ static inline bool amd_pstate_sample(struct amd_cpudata *cpudata)
- static void amd_pstate_update(struct amd_cpudata *cpudata, u32 min_perf,
- u32 des_perf, u32 max_perf, bool fast_switch, int gov_flags)
- {
-+ unsigned long max_freq;
-+ struct cpufreq_policy *policy = cpufreq_cpu_get(cpudata->cpu);
- u64 prev = READ_ONCE(cpudata->cppc_req_cached);
-+ u32 nominal_perf = READ_ONCE(cpudata->nominal_perf);
- u64 value = prev;
-
- min_perf = clamp_t(unsigned long, min_perf, cpudata->min_limit_perf,
-@@ -533,6 +526,9 @@ static void amd_pstate_update(struct amd_cpudata *cpudata, u32 min_perf,
- cpudata->max_limit_perf);
- des_perf = clamp_t(unsigned long, des_perf, min_perf, max_perf);
-
-+ max_freq = READ_ONCE(cpudata->max_limit_freq);
-+ policy->cur = div_u64(des_perf * max_freq, max_perf);
-+
- if ((cppc_state == AMD_PSTATE_GUIDED) && (gov_flags & CPUFREQ_GOV_DYNAMIC_SWITCHING)) {
- min_perf = des_perf;
- des_perf = 0;
-@@ -544,6 +540,10 @@ static void amd_pstate_update(struct amd_cpudata *cpudata, u32 min_perf,
- value &= ~AMD_CPPC_DES_PERF(~0L);
- value |= AMD_CPPC_DES_PERF(des_perf);
-
-+ /* limit the max perf when core performance boost feature is disabled */
-+ if (!cpudata->boost_supported)
-+ max_perf = min_t(unsigned long, nominal_perf, max_perf);
-+
- value &= ~AMD_CPPC_MAX_PERF(~0L);
- value |= AMD_CPPC_MAX_PERF(max_perf);
-
-@@ -654,10 +654,9 @@ static void amd_pstate_adjust_perf(unsigned int cpu,
- unsigned long capacity)
- {
- unsigned long max_perf, min_perf, des_perf,
-- cap_perf, lowest_nonlinear_perf, max_freq;
-+ cap_perf, lowest_nonlinear_perf;
- struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
- struct amd_cpudata *cpudata = policy->driver_data;
-- unsigned int target_freq;
-
- if (policy->min != cpudata->min_limit_freq || policy->max != cpudata->max_limit_freq)
- amd_pstate_update_min_max_limit(policy);
-@@ -665,7 +664,6 @@ static void amd_pstate_adjust_perf(unsigned int cpu,
-
- cap_perf = READ_ONCE(cpudata->highest_perf);
- lowest_nonlinear_perf = READ_ONCE(cpudata->lowest_nonlinear_perf);
-- max_freq = READ_ONCE(cpudata->max_freq);
-
- des_perf = cap_perf;
- if (target_perf < capacity)
-@@ -683,51 +681,111 @@ static void amd_pstate_adjust_perf(unsigned int cpu,
- max_perf = min_perf;
-
- des_perf = clamp_t(unsigned long, des_perf, min_perf, max_perf);
-- target_freq = div_u64(des_perf * max_freq, max_perf);
-- policy->cur = target_freq;
-
- amd_pstate_update(cpudata, min_perf, des_perf, max_perf, true,
- policy->governor->flags);
- cpufreq_cpu_put(policy);
- }
-
--static int amd_pstate_set_boost(struct cpufreq_policy *policy, int state)
-+static int amd_pstate_cpu_boost_update(struct cpufreq_policy *policy, bool on)
- {
- struct amd_cpudata *cpudata = policy->driver_data;
-+ struct cppc_perf_ctrls perf_ctrls;
-+ u32 highest_perf, nominal_perf, nominal_freq, max_freq;
- int ret;
-
-- if (!cpudata->boost_supported) {
-- pr_err("Boost mode is not supported by this processor or SBIOS\n");
-- return -EINVAL;
-+ highest_perf = READ_ONCE(cpudata->highest_perf);
-+ nominal_perf = READ_ONCE(cpudata->nominal_perf);
-+ nominal_freq = READ_ONCE(cpudata->nominal_freq);
-+ max_freq = READ_ONCE(cpudata->max_freq);
-+
-+ if (boot_cpu_has(X86_FEATURE_CPPC)) {
-+ u64 value = READ_ONCE(cpudata->cppc_req_cached);
-+
-+ value &= ~GENMASK_ULL(7, 0);
-+ value |= on ? highest_perf : nominal_perf;
-+ WRITE_ONCE(cpudata->cppc_req_cached, value);
-+
-+ wrmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, value);
-+ } else {
-+ perf_ctrls.max_perf = on ? highest_perf : nominal_perf;
-+ ret = cppc_set_perf(cpudata->cpu, &perf_ctrls);
-+ if (ret) {
-+ cpufreq_cpu_release(policy);
-+ pr_debug("Failed to set max perf on CPU:%d. ret:%d\n",
-+ cpudata->cpu, ret);
-+ return ret;
-+ }
- }
-
-- if (state)
-- policy->cpuinfo.max_freq = cpudata->max_freq;
-- else
-- policy->cpuinfo.max_freq = cpudata->nominal_freq * 1000;
-+ if (on)
-+ policy->cpuinfo.max_freq = max_freq;
-+ else if (policy->cpuinfo.max_freq > nominal_freq * 1000)
-+ policy->cpuinfo.max_freq = nominal_freq * 1000;
-
- policy->max = policy->cpuinfo.max_freq;
-
-- ret = freq_qos_update_request(&cpudata->req[1],
-- policy->cpuinfo.max_freq);
-- if (ret < 0)
-- return ret;
-+ if (cppc_state == AMD_PSTATE_PASSIVE) {
-+ ret = freq_qos_update_request(&cpudata->req[1], policy->cpuinfo.max_freq);
-+ if (ret < 0)
-+ pr_debug("Failed to update freq constraint: CPU%d\n", cpudata->cpu);
-+ }
-
-- return 0;
-+ return ret < 0 ? ret : 0;
- }
-
--static void amd_pstate_boost_init(struct amd_cpudata *cpudata)
-+static int amd_pstate_set_boost(struct cpufreq_policy *policy, int state)
- {
-- u32 highest_perf, nominal_perf;
-+ struct amd_cpudata *cpudata = policy->driver_data;
-+ int ret;
-
-- highest_perf = READ_ONCE(cpudata->highest_perf);
-- nominal_perf = READ_ONCE(cpudata->nominal_perf);
-+ if (!cpudata->boost_supported) {
-+ pr_err("Boost mode is not supported by this processor or SBIOS\n");
-+ return -EOPNOTSUPP;
-+ }
-+ mutex_lock(&amd_pstate_driver_lock);
-+ ret = amd_pstate_cpu_boost_update(policy, state);
-+ WRITE_ONCE(cpudata->boost_state, !ret ? state : false);
-+ policy->boost_enabled = !ret ? state : false;
-+ refresh_frequency_limits(policy);
-+ mutex_unlock(&amd_pstate_driver_lock);
-
-- if (highest_perf <= nominal_perf)
-- return;
-+ return ret;
-+}
-
-- cpudata->boost_supported = true;
-+static int amd_pstate_init_boost_support(struct amd_cpudata *cpudata)
-+{
-+ u64 boost_val;
-+ int ret = -1;
-+
-+ /*
-+ * If platform has no CPB support or disable it, initialize current driver
-+ * boost_enabled state to be false, it is not an error for cpufreq core to handle.
-+ */
-+ if (!cpu_feature_enabled(X86_FEATURE_CPB)) {
-+ pr_debug_once("Boost CPB capabilities not present in the processor\n");
-+ ret = 0;
-+ goto exit_err;
-+ }
-+
-+ /* at least one CPU supports CPB, even if others fail later on to set up */
- current_pstate_driver->boost_enabled = true;
-+
-+ ret = rdmsrl_on_cpu(cpudata->cpu, MSR_K7_HWCR, &boost_val);
-+ if (ret) {
-+ pr_err_once("failed to read initial CPU boost state!\n");
-+ ret = -EIO;
-+ goto exit_err;
-+ }
-+
-+ if (!(boost_val & MSR_K7_HWCR_CPB_DIS))
-+ cpudata->boost_supported = true;
-+
-+ return 0;
-+
-+exit_err:
-+ cpudata->boost_supported = false;
-+ return ret;
- }
-
- static void amd_perf_ctl_reset(unsigned int cpu)
-@@ -756,7 +814,7 @@ static int amd_pstate_get_highest_perf(int cpu, u32 *highest_perf)
- {
- int ret;
-
-- if (boot_cpu_has(X86_FEATURE_CPPC)) {
-+ if (cpu_feature_enabled(X86_FEATURE_CPPC)) {
- u64 cap1;
-
- ret = rdmsrl_safe_on_cpu(cpu, MSR_AMD_CPPC_CAP1, &cap1);
-@@ -852,8 +910,12 @@ 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;
-+ if (transition_delay_ns == CPUFREQ_ETERNAL) {
-+ if (cpu_feature_enabled(X86_FEATURE_FAST_CPPC))
-+ return AMD_PSTATE_FAST_CPPC_TRANSITION_DELAY;
-+ else
-+ return AMD_PSTATE_TRANSITION_DELAY;
-+ }
-
- return transition_delay_ns / NSEC_PER_USEC;
- }
-@@ -924,12 +986,30 @@ static int amd_pstate_init_freq(struct amd_cpudata *cpudata)
- WRITE_ONCE(cpudata->nominal_freq, nominal_freq);
- WRITE_ONCE(cpudata->max_freq, max_freq);
-
-+ /**
-+ * Below values need to be initialized correctly, otherwise driver will fail to load
-+ * max_freq is calculated according to (nominal_freq * highest_perf)/nominal_perf
-+ * lowest_nonlinear_freq is a value between [min_freq, nominal_freq]
-+ * Check _CPC in ACPI table objects if any values are incorrect
-+ */
-+ if (min_freq <= 0 || max_freq <= 0 || nominal_freq <= 0 || min_freq > max_freq) {
-+ pr_err("min_freq(%d) or max_freq(%d) or nominal_freq(%d) value is incorrect\n",
-+ min_freq, max_freq, nominal_freq * 1000);
-+ return -EINVAL;
-+ }
-+
-+ if (lowest_nonlinear_freq <= min_freq || lowest_nonlinear_freq > nominal_freq * 1000) {
-+ pr_err("lowest_nonlinear_freq(%d) value is out of range [min_freq(%d), nominal_freq(%d)]\n",
-+ lowest_nonlinear_freq, min_freq, nominal_freq * 1000);
-+ return -EINVAL;
-+ }
-+
- return 0;
- }
-
- static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
- {
-- int min_freq, max_freq, nominal_freq, ret;
-+ int min_freq, max_freq, ret;
- struct device *dev;
- struct amd_cpudata *cpudata;
-
-@@ -958,18 +1038,12 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
- if (ret)
- goto free_cpudata1;
-
-+ ret = amd_pstate_init_boost_support(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 ||
-- nominal_freq <= 0 || min_freq > max_freq) {
-- dev_err(dev,
-- "min_freq(%d) or max_freq(%d) or nominal_freq (%d) value is incorrect, check _CPC in ACPI tables\n",
-- min_freq, max_freq, nominal_freq);
-- ret = -EINVAL;
-- goto free_cpudata1;
-- }
-
- policy->cpuinfo.transition_latency = amd_pstate_get_transition_latency(policy->cpu);
- policy->transition_delay_us = amd_pstate_get_transition_delay_us(policy->cpu);
-@@ -980,10 +1054,12 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
- policy->cpuinfo.min_freq = min_freq;
- policy->cpuinfo.max_freq = max_freq;
-
-+ policy->boost_enabled = READ_ONCE(cpudata->boost_supported);
-+
- /* It will be updated by governor */
- policy->cur = policy->cpuinfo.min_freq;
-
-- if (boot_cpu_has(X86_FEATURE_CPPC))
-+ if (cpu_feature_enabled(X86_FEATURE_CPPC))
- policy->fast_switch_possible = true;
-
- ret = freq_qos_add_request(&policy->constraints, &cpudata->req[0],
-@@ -1005,7 +1081,6 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
-
- policy->driver_data = cpudata;
-
-- amd_pstate_boost_init(cpudata);
- if (!current_pstate_driver->adjust_perf)
- current_pstate_driver->adjust_perf = amd_pstate_adjust_perf;
-
-@@ -1216,7 +1291,7 @@ static int amd_pstate_change_mode_without_dvr_change(int mode)
-
- cppc_state = mode;
-
-- if (boot_cpu_has(X86_FEATURE_CPPC) || cppc_state == AMD_PSTATE_ACTIVE)
-+ if (cpu_feature_enabled(X86_FEATURE_CPPC) || cppc_state == AMD_PSTATE_ACTIVE)
- return 0;
-
- for_each_present_cpu(cpu) {
-@@ -1389,7 +1464,7 @@ static bool amd_pstate_acpi_pm_profile_undefined(void)
-
- static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
- {
-- int min_freq, max_freq, nominal_freq, ret;
-+ int min_freq, max_freq, ret;
- struct amd_cpudata *cpudata;
- struct device *dev;
- u64 value;
-@@ -1420,17 +1495,12 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
- if (ret)
- goto free_cpudata1;
-
-+ ret = amd_pstate_init_boost_support(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 ||
-- nominal_freq <= 0 || min_freq > max_freq) {
-- dev_err(dev,
-- "min_freq(%d) or max_freq(%d) or nominal_freq(%d) value is incorrect, check _CPC in ACPI tables\n",
-- min_freq, max_freq, nominal_freq);
-- ret = -EINVAL;
-- goto free_cpudata1;
-- }
-
- policy->cpuinfo.min_freq = min_freq;
- policy->cpuinfo.max_freq = max_freq;
-@@ -1439,11 +1509,13 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
-
- policy->driver_data = cpudata;
-
- cpudata->epp_cached = cpudata->epp_default = amd_pstate_get_epp(cpudata, 0);
-
- policy->min = policy->cpuinfo.min_freq;
- policy->max = policy->cpuinfo.max_freq;
-
-+ policy->boost_enabled = READ_ONCE(cpudata->boost_supported);
-+
- /*
- * Set the policy to provide a valid fallback value in case
- * the default cpufreq governor is neither powersave nor performance.
-@@ -1454,7 +1526,7 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
- else
- policy->policy = CPUFREQ_POLICY_POWERSAVE;
-
-- if (boot_cpu_has(X86_FEATURE_CPPC)) {
-+ if (cpu_feature_enabled(X86_FEATURE_CPPC)) {
- ret = rdmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, &value);
- if (ret)
- return ret;
-@@ -1465,7 +1537,6 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
- return ret;
- WRITE_ONCE(cpudata->cppc_cap1_cached, value);
- }
-- amd_pstate_boost_init(cpudata);
-
- return 0;
-
-@@ -1544,7 +1615,7 @@ static void amd_pstate_epp_update_limit(struct cpufreq_policy *policy)
- epp = 0;
-
- /* Set initial EPP value */
-- if (boot_cpu_has(X86_FEATURE_CPPC)) {
-+ if (cpu_feature_enabled(X86_FEATURE_CPPC)) {
- value &= ~GENMASK_ULL(31, 24);
- value |= (u64)epp << 24;
- }
-@@ -1567,6 +1638,12 @@ static int amd_pstate_epp_set_policy(struct cpufreq_policy *policy)
-
- amd_pstate_epp_update_limit(policy);
-
-+ /*
-+ * policy->cur is never updated with the amd_pstate_epp driver, but it
-+ * is used as a stale frequency value. So, keep it within limits.
-+ */
-+ policy->cur = policy->min;
-+
- return 0;
- }
-
-@@ -1583,7 +1660,7 @@ static void amd_pstate_epp_reenable(struct amd_cpudata *cpudata)
- value = READ_ONCE(cpudata->cppc_req_cached);
- max_perf = READ_ONCE(cpudata->highest_perf);
-
-- if (boot_cpu_has(X86_FEATURE_CPPC)) {
-+ if (cpu_feature_enabled(X86_FEATURE_CPPC)) {
- wrmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, value);
- } else {
- perf_ctrls.max_perf = max_perf;
-@@ -1617,7 +1694,7 @@ static void amd_pstate_epp_offline(struct cpufreq_policy *policy)
- value = READ_ONCE(cpudata->cppc_req_cached);
-
- mutex_lock(&amd_pstate_limits_lock);
-- if (boot_cpu_has(X86_FEATURE_CPPC)) {
-+ if (cpu_feature_enabled(X86_FEATURE_CPPC)) {
- cpudata->epp_policy = CPUFREQ_POLICY_UNKNOWN;
-
- /* Set max perf same as min perf */
-@@ -1721,6 +1798,7 @@ static struct cpufreq_driver amd_pstate_epp_driver = {
- .suspend = amd_pstate_epp_suspend,
- .resume = amd_pstate_epp_resume,
- .update_limits = amd_pstate_update_limits,
-+ .set_boost = amd_pstate_set_boost,
- .name = "amd-pstate-epp",
- .attr = amd_pstate_epp_attr,
- };
-@@ -1744,6 +1822,46 @@ static int __init amd_pstate_set_driver(int mode_idx)
- return -EINVAL;
- }
-
-+/**
-+ * CPPC function is not supported for family ID 17H with model_ID ranging from 0x10 to 0x2F.
-+ * show the debug message that helps to check if the CPU has CPPC support for loading issue.
-+ */
-+static bool amd_cppc_supported(void)
-+{
-+ struct cpuinfo_x86 *c = &cpu_data(0);
-+ bool warn = false;
-+
-+ if ((boot_cpu_data.x86 == 0x17) && (boot_cpu_data.x86_model < 0x30)) {
-+ pr_debug_once("CPPC feature is not supported by the processor\n");
-+ return false;
-+ }
-+
-+ /*
-+ * If the CPPC feature is disabled in the BIOS for processors that support MSR-based CPPC,
-+ * the AMD Pstate driver may not function correctly.
-+ * Check the CPPC flag and display a warning message if the platform supports CPPC.
-+ * Note: below checking code will not abort the driver registeration process because of
-+ * the code is added for debugging purposes.
-+ */
-+ if (!cpu_feature_enabled(X86_FEATURE_CPPC)) {
-+ if (cpu_feature_enabled(X86_FEATURE_ZEN1) || cpu_feature_enabled(X86_FEATURE_ZEN2)) {
-+ if (c->x86_model > 0x60 && c->x86_model < 0xaf)
-+ warn = true;
-+ } else if (cpu_feature_enabled(X86_FEATURE_ZEN3) || cpu_feature_enabled(X86_FEATURE_ZEN4)) {
-+ if ((c->x86_model > 0x10 && c->x86_model < 0x1F) ||
-+ (c->x86_model > 0x40 && c->x86_model < 0xaf))
-+ warn = true;
-+ } else if (cpu_feature_enabled(X86_FEATURE_ZEN5)) {
-+ warn = true;
-+ }
-+ }
-+
-+ if (warn)
-+ pr_warn_once("The CPPC feature is supported but currently disabled by the BIOS.\n"
-+ "Please enable it if your BIOS has the CPPC option.\n");
-+ return true;
-+}
-+
- static int __init amd_pstate_init(void)
- {
- struct device *dev_root;
-@@ -1752,6 +1870,11 @@ static int __init amd_pstate_init(void)
- if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
- return -ENODEV;
-
-+ /* show debug message only if CPPC is not supported */
-+ if (!amd_cppc_supported())
-+ return -EOPNOTSUPP;
-+
-+ /* show warning message when BIOS broken or ACPI disabled */
- if (!acpi_cpc_valid()) {
- pr_warn_once("the _CPC object is not present in SBIOS or ACPI disabled\n");
- return -ENODEV;
-@@ -1774,11 +1899,9 @@ static int __init amd_pstate_init(void)
- /* Disable on the following configs by default:
- * 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;
- }
-@@ -1802,7 +1925,7 @@ static int __init amd_pstate_init(void)
- }
-
- /* capability check */
-- if (boot_cpu_has(X86_FEATURE_CPPC)) {
-+ if (cpu_feature_enabled(X86_FEATURE_CPPC)) {
- pr_debug("AMD CPPC MSR based functionality is supported\n");
- if (cppc_state != AMD_PSTATE_ACTIVE)
- current_pstate_driver->adjust_perf = amd_pstate_adjust_perf;
-@@ -1821,8 +1944,10 @@ static int __init amd_pstate_init(void)
- }
-
- ret = cpufreq_register_driver(current_pstate_driver);
-- if (ret)
-+ if (ret) {
- pr_err("failed to register with return %d\n", ret);
-+ goto disable_driver;
-+ }
-
- dev_root = bus_get_dev_root(&cpu_subsys);
- if (dev_root) {
-@@ -1830,6 +1963,8 @@ static int __init amd_pstate_init(void)
-
- global_attr_free:
- cpufreq_unregister_driver(current_pstate_driver);
-+disable_driver:
-+ amd_pstate_enable(false);
- return ret;
- }
- device_initcall(amd_pstate_init);
-diff --git a/drivers/cpufreq/amd-pstate.h b/drivers/cpufreq/amd-pstate.h
-index e6a28e7f4dbf..cc8bb2bc325a 100644
---- a/drivers/cpufreq/amd-pstate.h
-+++ b/drivers/cpufreq/amd-pstate.h
-@@ -99,7 +99,8 @@ struct amd_cpudata {
- u32 policy;
- u64 cppc_cap1_cached;
- bool suspended;
- s16 epp_default;
-+ bool boost_state;
- };
-
- #endif /* _LINUX_AMD_PSTATE_H */
-diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
-index 9e5060b27864..270ea04fb616 100644
---- a/drivers/cpufreq/cpufreq.c
-+++ b/drivers/cpufreq/cpufreq.c
-@@ -614,10 +614,9 @@ static ssize_t show_boost(struct kobject *kobj,
- static ssize_t store_boost(struct kobject *kobj, struct kobj_attribute *attr,
- const char *buf, size_t count)
- {
-- int ret, enable;
-+ bool enable;
-
-- ret = sscanf(buf, "%d", &enable);
-- if (ret != 1 || enable < 0 || enable > 1)
-+ if (kstrtobool(buf, &enable))
- return -EINVAL;
-
- if (cpufreq_boost_trigger_state(enable)) {
-@@ -641,10 +640,10 @@ static ssize_t show_local_boost(struct cpufreq_policy *policy, char *buf)
- static ssize_t store_local_boost(struct cpufreq_policy *policy,
- const char *buf, size_t count)
- {
-- int ret, enable;
-+ int ret;
-+ bool enable;
-
-- ret = kstrtoint(buf, 10, &enable);
-- if (ret || enable < 0 || enable > 1)
-+ if (kstrtobool(buf, &enable))
- return -EINVAL;
-
- if (!cpufreq_driver->boost_enabled)
---
-2.46.0.rc1
-