2024-12-10 00:17:37 +03:00
|
|
|
From ba9f0c8ca71a1c44e35dd8d3221abda0bd4e465a Mon Sep 17 00:00:00 2001
|
2024-10-29 05:12:06 +03:00
|
|
|
From: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
2024-12-10 00:17:37 +03:00
|
|
|
Date: Thu, 17 Oct 2024 05:39:30 +0000
|
2024-10-29 05:12:06 +03:00
|
|
|
Subject: cpufreq/amd-pstate: Set the initial min_freq to lowest_nonlinear_freq
|
|
|
|
|
|
|
|
According to the AMD architectural programmer's manual volume 2 [1], in
|
|
|
|
section "17.6.4.1 CPPC_CAPABILITY_1" lowest_nonlinear_perf is described
|
|
|
|
as "Reports the most energy efficient performance level (in terms of
|
|
|
|
performance per watt). Above this threshold, lower performance levels
|
|
|
|
generally result in increased energy efficiency. Reducing performance
|
|
|
|
below this threshold does not result in total energy savings for a given
|
|
|
|
computation, although it reduces instantaneous power consumption". So
|
|
|
|
lowest_nonlinear_perf is the most power efficient performance level, and
|
|
|
|
going below that would lead to a worse performance/watt.
|
|
|
|
|
|
|
|
Also, setting the minimum frequency to lowest_nonlinear_freq (instead of
|
|
|
|
lowest_freq) allows the CPU to idle at a higher frequency which leads
|
|
|
|
to more time being spent in a deeper idle state (as trivial idle tasks
|
|
|
|
are completed sooner). This has shown a power benefit in some systems,
|
|
|
|
in other systems, power consumption has increased but so has the
|
|
|
|
throughput/watt.
|
|
|
|
|
2024-12-10 00:17:37 +03:00
|
|
|
Modify the initial policy_data->min set by cpufreq-core to
|
|
|
|
lowest_nonlinear_freq, in the ->verify() callback. Also set the
|
|
|
|
cpudata->req[0] to FREQ_QOS_MIN_DEFAULT_VALUE (i.e. 0), so that it also
|
|
|
|
gets overriden by the check in verify function.
|
2024-10-29 05:12:06 +03:00
|
|
|
|
|
|
|
Link: https://www.amd.com/content/dam/amd/en/documents/processor-tech-docs/programmer-references/24593.pdf [1]
|
|
|
|
|
|
|
|
Signed-off-by: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
|
|
Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
|
|
|
|
---
|
2024-12-10 00:17:37 +03:00
|
|
|
drivers/cpufreq/amd-pstate.c | 21 ++++++++++++++++++++-
|
|
|
|
1 file changed, 20 insertions(+), 1 deletion(-)
|
2024-10-29 05:12:06 +03:00
|
|
|
|
|
|
|
--- a/drivers/cpufreq/amd-pstate.c
|
|
|
|
+++ b/drivers/cpufreq/amd-pstate.c
|
2024-12-10 00:17:37 +03:00
|
|
|
@@ -559,8 +559,27 @@ cpufreq_policy_put:
|
2024-10-29 05:12:06 +03:00
|
|
|
|
2024-12-10 00:17:37 +03:00
|
|
|
static int amd_pstate_verify(struct cpufreq_policy_data *policy_data)
|
|
|
|
{
|
|
|
|
+ /*
|
|
|
|
+ * Initialize lower frequency limit (i.e.policy->min) with
|
|
|
|
+ * lowest_nonlinear_frequency which is the most energy efficient
|
|
|
|
+ * frequency. Override the initial value set by cpufreq core and
|
|
|
|
+ * amd-pstate qos_requests.
|
|
|
|
+ */
|
|
|
|
+ if (policy_data->min == FREQ_QOS_MIN_DEFAULT_VALUE) {
|
|
|
|
+ struct cpufreq_policy *policy = cpufreq_cpu_get(policy_data->cpu);
|
|
|
|
+ struct amd_cpudata *cpudata;
|
|
|
|
+
|
|
|
|
+ if (!policy)
|
|
|
|
+ return -EINVAL;
|
2024-10-29 05:12:06 +03:00
|
|
|
+
|
2024-12-10 00:17:37 +03:00
|
|
|
+ cpudata = policy->driver_data;
|
|
|
|
+ policy_data->min = cpudata->lowest_nonlinear_freq;
|
|
|
|
+ cpufreq_cpu_put(policy);
|
|
|
|
+ }
|
2024-10-29 05:12:06 +03:00
|
|
|
+
|
2024-12-10 00:17:37 +03:00
|
|
|
cpufreq_verify_within_cpu_limits(policy_data);
|
|
|
|
pr_debug("policy_max =%d, policy_min=%d\n", policy_data->max, policy_data->min);
|
|
|
|
+
|
|
|
|
return 0;
|
|
|
|
}
|
2024-10-29 05:12:06 +03:00
|
|
|
|
2024-12-10 00:17:37 +03:00
|
|
|
@@ -1009,7 +1028,7 @@ static int amd_pstate_cpu_init(struct cp
|
|
|
|
policy->fast_switch_possible = true;
|
2024-10-29 05:12:06 +03:00
|
|
|
|
2024-12-10 00:17:37 +03:00
|
|
|
ret = freq_qos_add_request(&policy->constraints, &cpudata->req[0],
|
|
|
|
- FREQ_QOS_MIN, policy->cpuinfo.min_freq);
|
|
|
|
+ FREQ_QOS_MIN, FREQ_QOS_MIN_DEFAULT_VALUE);
|
|
|
|
if (ret < 0) {
|
|
|
|
dev_err(dev, "Failed to add min-freq constraint (%d)\n", ret);
|
|
|
|
goto free_cpudata1;
|