Power management fixes for 6.4-rc4
Fix 3 issues related to the ->fast_switch callback in the AMD P-state cpufreq driver (Gautham R. Shenoy and Wyes Karny). -----BEGIN PGP SIGNATURE----- iQJGBAABCAAwFiEE4fcc61cGeeHD/fCwgsRv/nhiVHEFAmRw2+cSHHJqd0Byand5 c29ja2kubmV0AAoJEILEb/54YlRxW68P/2W9mcDxlepkfN9KEUgZ6ianmoRdHqSU KpL8uB4Snavd0QQYnRUbNPeDht5cAMZT1cEzmcdkGAzGz2SpD/44LH0T8zFO24aM SAdlo6j72VWiRmR5POvEZbKPRczCWFPlpqKkQyh227Msb5tGayo7fRa1VpRqo/AH YwYWaW5Ur5XfU0c8E5K+P3Rj2dz+RsFzZ4chb5yd14ae2Qr8f6EnOVte0ja0bFUF uPneqJ27U4MoDW1s/bkud32lJTeGLi8BwgIIyP6L7a8m5QdWxv+pTZMsa/NW7a+v 3+3GrXoLZp6xeBGdt0z6/04BwpcRUh6ZpVlloGeYoSMpnQpGleqeJaVepWZCAKDm K0Gc7nLTLQUMO877oOz17cDLdDgXbIDmngw9ubEW0N7g5yOGzSCTfQyYYItN0dky mnTMXU5TM2LktH3V1y34HTTZTZU5TDZkLzoFNAgHqmlFhEqEdaN6l5AJJ6rPt9IM ZwJNpLz3R4rQ+XwGofebQGSlwpQVAzUrigiHJ2VJAbFxWqw4iohYkgD+1e8B/VzG e5DygskN1FFTJ7oMXlPSDWqulCRghOillqtUWocdHJAbnkglkLpexxqUAsoNahDt qA553sM5/lp29uNlpuz6AbqHscjOto94aC3uK3kxNUGsDy6CRcbn5VVIN5ceDVk+ SnzKHfnh65vv =6XJv -----END PGP SIGNATURE----- Merge tag 'pm-6.4-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm Pull power management fixes from Rafael Wysocki: "Fix three issues related to the ->fast_switch callback in the AMD P-state cpufreq driver (Gautham R. Shenoy and Wyes Karny)" * tag 'pm-6.4-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: cpufreq: amd-pstate: Update policy->cur in amd_pstate_adjust_perf() cpufreq: amd-pstate: Remove fast_switch_possible flag from active driver cpufreq: amd-pstate: Add ->fast_switch() callback
This commit is contained in:
commit
c551afcdc3
|
@ -444,9 +444,8 @@ static int amd_pstate_verify(struct cpufreq_policy_data *policy)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int amd_pstate_target(struct cpufreq_policy *policy,
|
||||
unsigned int target_freq,
|
||||
unsigned int relation)
|
||||
static int amd_pstate_update_freq(struct cpufreq_policy *policy,
|
||||
unsigned int target_freq, bool fast_switch)
|
||||
{
|
||||
struct cpufreq_freqs freqs;
|
||||
struct amd_cpudata *cpudata = policy->driver_data;
|
||||
|
@ -465,26 +464,51 @@ static int amd_pstate_target(struct cpufreq_policy *policy,
|
|||
des_perf = DIV_ROUND_CLOSEST(target_freq * cap_perf,
|
||||
cpudata->max_freq);
|
||||
|
||||
WARN_ON(fast_switch && !policy->fast_switch_enabled);
|
||||
/*
|
||||
* If fast_switch is desired, then there aren't any registered
|
||||
* transition notifiers. See comment for
|
||||
* cpufreq_enable_fast_switch().
|
||||
*/
|
||||
if (!fast_switch)
|
||||
cpufreq_freq_transition_begin(policy, &freqs);
|
||||
|
||||
amd_pstate_update(cpudata, min_perf, des_perf,
|
||||
max_perf, false, policy->governor->flags);
|
||||
max_perf, fast_switch, policy->governor->flags);
|
||||
|
||||
if (!fast_switch)
|
||||
cpufreq_freq_transition_end(policy, &freqs, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int amd_pstate_target(struct cpufreq_policy *policy,
|
||||
unsigned int target_freq,
|
||||
unsigned int relation)
|
||||
{
|
||||
return amd_pstate_update_freq(policy, target_freq, false);
|
||||
}
|
||||
|
||||
static unsigned int amd_pstate_fast_switch(struct cpufreq_policy *policy,
|
||||
unsigned int target_freq)
|
||||
{
|
||||
return amd_pstate_update_freq(policy, target_freq, true);
|
||||
}
|
||||
|
||||
static void amd_pstate_adjust_perf(unsigned int cpu,
|
||||
unsigned long _min_perf,
|
||||
unsigned long target_perf,
|
||||
unsigned long capacity)
|
||||
{
|
||||
unsigned long max_perf, min_perf, des_perf,
|
||||
cap_perf, lowest_nonlinear_perf;
|
||||
cap_perf, lowest_nonlinear_perf, max_freq;
|
||||
struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
|
||||
struct amd_cpudata *cpudata = policy->driver_data;
|
||||
unsigned int target_freq;
|
||||
|
||||
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)
|
||||
|
@ -501,6 +525,10 @@ static void amd_pstate_adjust_perf(unsigned int cpu,
|
|||
if (max_perf < min_perf)
|
||||
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);
|
||||
|
@ -715,6 +743,7 @@ static int amd_pstate_cpu_exit(struct cpufreq_policy *policy)
|
|||
|
||||
freq_qos_remove_request(&cpudata->req[1]);
|
||||
freq_qos_remove_request(&cpudata->req[0]);
|
||||
policy->fast_switch_possible = false;
|
||||
kfree(cpudata);
|
||||
|
||||
return 0;
|
||||
|
@ -1079,7 +1108,6 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
|
|||
policy->policy = CPUFREQ_POLICY_POWERSAVE;
|
||||
|
||||
if (boot_cpu_has(X86_FEATURE_CPPC)) {
|
||||
policy->fast_switch_possible = true;
|
||||
ret = rdmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, &value);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -1102,7 +1130,6 @@ free_cpudata1:
|
|||
static int amd_pstate_epp_cpu_exit(struct cpufreq_policy *policy)
|
||||
{
|
||||
pr_debug("CPU %d exiting\n", policy->cpu);
|
||||
policy->fast_switch_possible = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1309,6 +1336,7 @@ static struct cpufreq_driver amd_pstate_driver = {
|
|||
.flags = CPUFREQ_CONST_LOOPS | CPUFREQ_NEED_UPDATE_LIMITS,
|
||||
.verify = amd_pstate_verify,
|
||||
.target = amd_pstate_target,
|
||||
.fast_switch = amd_pstate_fast_switch,
|
||||
.init = amd_pstate_cpu_init,
|
||||
.exit = amd_pstate_cpu_exit,
|
||||
.suspend = amd_pstate_cpu_suspend,
|
||||
|
|
Loading…
Reference in New Issue