diff options
author | Huang Rui <ray.huang@amd.com> | 2021-12-24 09:05:04 +0800 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2021-12-30 18:51:39 +0100 |
commit | 41271016dfa4a08487bf2862f817edc9070489d1 (patch) | |
tree | a97b66f02cfde89eab55217f779d706a380507ca /drivers/cpufreq/amd-pstate.c | |
parent | 60e10f896dbf6d78f912e4972081bd4119131376 (diff) | |
download | linux-41271016dfa4a08487bf2862f817edc9070489d1.tar.bz2 |
cpufreq: amd-pstate: Add boost mode support for AMD P-State
If the sbios supports the boost mode of AMD P-State, let's switch to
boost enabled by default.
Signed-off-by: Huang Rui <ray.huang@amd.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/cpufreq/amd-pstate.c')
-rw-r--r-- | drivers/cpufreq/amd-pstate.c | 69 |
1 files changed, 66 insertions, 3 deletions
diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c index 63efd5de98a2..9e23efc7b9eb 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -87,6 +87,7 @@ static struct cpufreq_driver amd_pstate_driver; struct amd_cpudata { int cpu; + struct freq_qos_request req[2]; u64 cppc_req_cached; u32 highest_perf; @@ -98,6 +99,8 @@ struct amd_cpudata { u32 min_freq; u32 nominal_freq; u32 lowest_nonlinear_freq; + + bool boost_supported; }; static inline int pstate_enable(bool enable) @@ -374,6 +377,45 @@ static int amd_get_lowest_nonlinear_freq(struct amd_cpudata *cpudata) return lowest_nonlinear_freq * 1000; } +static int amd_pstate_set_boost(struct cpufreq_policy *policy, int state) +{ + struct amd_cpudata *cpudata = policy->driver_data; + int ret; + + if (!cpudata->boost_supported) { + pr_err("Boost mode is not supported by this processor or SBIOS\n"); + return -EINVAL; + } + + if (state) + policy->cpuinfo.max_freq = cpudata->max_freq; + else + policy->cpuinfo.max_freq = cpudata->nominal_freq; + + policy->max = policy->cpuinfo.max_freq; + + ret = freq_qos_update_request(&cpudata->req[1], + policy->cpuinfo.max_freq); + if (ret < 0) + return ret; + + return 0; +} + +static void amd_pstate_boost_init(struct amd_cpudata *cpudata) +{ + u32 highest_perf, nominal_perf; + + highest_perf = READ_ONCE(cpudata->highest_perf); + nominal_perf = READ_ONCE(cpudata->nominal_perf); + + if (highest_perf <= nominal_perf) + return; + + cpudata->boost_supported = true; + amd_pstate_driver.boost_enabled = true; +} + static int amd_pstate_cpu_init(struct cpufreq_policy *policy) { int min_freq, max_freq, nominal_freq, lowest_nonlinear_freq, ret; @@ -392,7 +434,7 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy) ret = amd_pstate_init_perf(cpudata); if (ret) - goto free_cpudata; + goto free_cpudata1; min_freq = amd_get_min_freq(cpudata); max_freq = amd_get_max_freq(cpudata); @@ -403,7 +445,7 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy) dev_err(dev, "min_freq(%d) or max_freq(%d) value is incorrect\n", min_freq, max_freq); ret = -EINVAL; - goto free_cpudata; + goto free_cpudata1; } policy->cpuinfo.transition_latency = AMD_PSTATE_TRANSITION_LATENCY; @@ -421,6 +463,20 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy) if (boot_cpu_has(X86_FEATURE_CPPC)) policy->fast_switch_possible = true; + ret = freq_qos_add_request(&policy->constraints, &cpudata->req[0], + FREQ_QOS_MIN, policy->cpuinfo.min_freq); + if (ret < 0) { + dev_err(dev, "Failed to add min-freq constraint (%d)\n", ret); + goto free_cpudata1; + } + + ret = freq_qos_add_request(&policy->constraints, &cpudata->req[1], + FREQ_QOS_MAX, policy->cpuinfo.max_freq); + if (ret < 0) { + dev_err(dev, "Failed to add max-freq constraint (%d)\n", ret); + goto free_cpudata2; + } + /* Initial processor data capability frequencies */ cpudata->max_freq = max_freq; cpudata->min_freq = min_freq; @@ -429,9 +485,13 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy) policy->driver_data = cpudata; + amd_pstate_boost_init(cpudata); + return 0; -free_cpudata: +free_cpudata2: + freq_qos_remove_request(&cpudata->req[0]); +free_cpudata1: kfree(cpudata); return ret; } @@ -442,6 +502,8 @@ static int amd_pstate_cpu_exit(struct cpufreq_policy *policy) cpudata = policy->driver_data; + freq_qos_remove_request(&cpudata->req[1]); + freq_qos_remove_request(&cpudata->req[0]); kfree(cpudata); return 0; @@ -453,6 +515,7 @@ static struct cpufreq_driver amd_pstate_driver = { .target = amd_pstate_target, .init = amd_pstate_cpu_init, .exit = amd_pstate_cpu_exit, + .set_boost = amd_pstate_set_boost, .name = "amd-pstate", }; |