Skip to content

Commit 2dd6d0e

Browse files
wkarnyrafaeljw
authored andcommitted
cpufreq: amd-pstate: Add guided autonomous mode
From ACPI spec below 3 modes for CPPC can be defined: 1. Non autonomous: OS scaling governor specifies operating frequency/ performance level through `Desired Performance` register and platform follows that. 2. Guided autonomous: OS scaling governor specifies min and max frequencies/ performance levels through `Minimum Performance` and `Maximum Performance` register, and platform can autonomously select an operating frequency in this range. 3. Fully autonomous: OS only hints (via EPP) to platform for the required energy performance preference for the workload and platform autonomously scales the frequency. Currently (1) is supported by amd_pstate as passive mode, and (3) is implemented by EPP support. This change is to support (2). In guided autonomous mode the min_perf is based on the input from the scaling governor. For example, in case of schedutil this value depends on the current utilization. And max_perf is set to max capacity. To activate guided auto mode ``amd_pstate=guided`` command line parameter has to be passed in the kernel. Acked-by: Huang Rui <ray.huang@amd.com> Reviewed-by: Mario Limonciello <mario.limonciello@amd.com> Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name> Signed-off-by: Wyes Karny <wyes.karny@amd.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
1 parent 3e6e078 commit 2dd6d0e

3 files changed

Lines changed: 40 additions & 11 deletions

File tree

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -344,18 +344,23 @@
344344
Do not enable amd_pstate as the default
345345
scaling driver for the supported processors
346346
passive
347-
Use amd_pstate as a scaling driver, driver requests a
348-
desired performance on this abstract scale and the power
349-
management firmware translates the requests into actual
350-
hardware states (core frequency, data fabric and memory
351-
clocks etc.)
347+
Use amd_pstate with passive mode as a scaling driver.
348+
In this mode autonomous selection is disabled.
349+
Driver requests a desired performance level and platform
350+
tries to match the same performance level if it is
351+
satisfied by guaranteed performance level.
352352
active
353353
Use amd_pstate_epp driver instance as the scaling driver,
354354
driver provides a hint to the hardware if software wants
355355
to bias toward performance (0x0) or energy efficiency (0xff)
356356
to the CPPC firmware. then CPPC power algorithm will
357357
calculate the runtime workload and adjust the realtime cores
358358
frequency.
359+
guided
360+
Activate guided autonomous mode. Driver requests minimum and
361+
maximum performance level and the platform autonomously
362+
selects a performance level in this range and appropriate
363+
to the current workload.
359364

360365
amijoy.map= [HW,JOY] Amiga joystick support
361366
Map of devices attached to JOY0DAT and JOY1DAT

drivers/cpufreq/amd-pstate.c

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,22 @@ static int cppc_init_perf(struct amd_cpudata *cpudata)
308308
cppc_perf.lowest_nonlinear_perf);
309309
WRITE_ONCE(cpudata->lowest_perf, cppc_perf.lowest_perf);
310310

311-
return 0;
311+
if (cppc_state == AMD_PSTATE_ACTIVE)
312+
return 0;
313+
314+
ret = cppc_get_auto_sel_caps(cpudata->cpu, &cppc_perf);
315+
if (ret) {
316+
pr_warn("failed to get auto_sel, ret: %d\n", ret);
317+
return 0;
318+
}
319+
320+
ret = cppc_set_auto_sel(cpudata->cpu,
321+
(cppc_state == AMD_PSTATE_PASSIVE) ? 0 : 1);
322+
323+
if (ret)
324+
pr_warn("failed to set auto_sel, ret: %d\n", ret);
325+
326+
return ret;
312327
}
313328

314329
DEFINE_STATIC_CALL(amd_pstate_init_perf, pstate_init_perf);
@@ -385,12 +400,18 @@ static inline bool amd_pstate_sample(struct amd_cpudata *cpudata)
385400
}
386401

387402
static void amd_pstate_update(struct amd_cpudata *cpudata, u32 min_perf,
388-
u32 des_perf, u32 max_perf, bool fast_switch)
403+
u32 des_perf, u32 max_perf, bool fast_switch, int gov_flags)
389404
{
390405
u64 prev = READ_ONCE(cpudata->cppc_req_cached);
391406
u64 value = prev;
392407

393408
des_perf = clamp_t(unsigned long, des_perf, min_perf, max_perf);
409+
410+
if ((cppc_state == AMD_PSTATE_GUIDED) && (gov_flags & CPUFREQ_GOV_DYNAMIC_SWITCHING)) {
411+
min_perf = des_perf;
412+
des_perf = 0;
413+
}
414+
394415
value &= ~AMD_CPPC_MIN_PERF(~0L);
395416
value |= AMD_CPPC_MIN_PERF(min_perf);
396417

@@ -445,7 +466,7 @@ static int amd_pstate_target(struct cpufreq_policy *policy,
445466

446467
cpufreq_freq_transition_begin(policy, &freqs);
447468
amd_pstate_update(cpudata, min_perf, des_perf,
448-
max_perf, false);
469+
max_perf, false, policy->governor->flags);
449470
cpufreq_freq_transition_end(policy, &freqs, false);
450471

451472
return 0;
@@ -479,7 +500,8 @@ static void amd_pstate_adjust_perf(unsigned int cpu,
479500
if (max_perf < min_perf)
480501
max_perf = min_perf;
481502

482-
amd_pstate_update(cpudata, min_perf, des_perf, max_perf, true);
503+
amd_pstate_update(cpudata, min_perf, des_perf, max_perf, true,
504+
policy->governor->flags);
483505
cpufreq_cpu_put(policy);
484506
}
485507

@@ -1279,7 +1301,7 @@ static int __init amd_pstate_init(void)
12791301
/* capability check */
12801302
if (boot_cpu_has(X86_FEATURE_CPPC)) {
12811303
pr_debug("AMD CPPC MSR based functionality is supported\n");
1282-
if (cppc_state == AMD_PSTATE_PASSIVE)
1304+
if (cppc_state != AMD_PSTATE_ACTIVE)
12831305
current_pstate_driver->adjust_perf = amd_pstate_adjust_perf;
12841306
} else {
12851307
pr_debug("AMD CPPC shared memory based functionality is supported\n");
@@ -1341,7 +1363,7 @@ static int __init amd_pstate_param(char *str)
13411363
if (cppc_state == AMD_PSTATE_ACTIVE)
13421364
current_pstate_driver = &amd_pstate_epp_driver;
13431365

1344-
if (cppc_state == AMD_PSTATE_PASSIVE)
1366+
if (cppc_state == AMD_PSTATE_PASSIVE || cppc_state == AMD_PSTATE_GUIDED)
13451367
current_pstate_driver = &amd_pstate_driver;
13461368

13471369
return 0;

include/linux/amd-pstate.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,13 +97,15 @@ enum amd_pstate_mode {
9797
AMD_PSTATE_DISABLE = 0,
9898
AMD_PSTATE_PASSIVE,
9999
AMD_PSTATE_ACTIVE,
100+
AMD_PSTATE_GUIDED,
100101
AMD_PSTATE_MAX,
101102
};
102103

103104
static const char * const amd_pstate_mode_string[] = {
104105
[AMD_PSTATE_DISABLE] = "disable",
105106
[AMD_PSTATE_PASSIVE] = "passive",
106107
[AMD_PSTATE_ACTIVE] = "active",
108+
[AMD_PSTATE_GUIDED] = "guided",
107109
NULL,
108110
};
109111
#endif /* _LINUX_AMD_PSTATE_H */

0 commit comments

Comments
 (0)