aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq
diff options
context:
space:
mode:
authorSrinivas Pandruvada <srinivas.pandruvada@linux.intel.com>2015-10-14 19:12:01 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2015-10-14 19:53:18 -0400
commit37afb00032424d684a48d649fcfb8b5e4f17c409 (patch)
tree27e39c9822569de2b6a18e5cc38c2074ce34d69e /drivers/cpufreq
parent3bcc6fa971c06151d6bf90cb0dc80807f71b93f6 (diff)
cpufreq: intel_pstate: Use ACPI perf configuration
Use ACPI _PSS to limit the Intel P State turbo, max and min ratios. This driver uses acpi processor perf lib calls to register performance. The following logic is used to adjust Intel P state driver limits: - If there is no turbo entry in _PSS, then disable Intel P state turbo and limit to non turbo max - If the non turbo max ratio is more than _PSS max non turbo value, then set the max non turbo ratio to _PSS non turbo max - If the min ratio is less than _PSS min then change the min ratio matching _PSS min - Scale the _PSS turbo frequency to max turbo frequency based on control value. This feature can be disabled by using kernel parameters: intel_pstate=no_acpi Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> Acked-by: Kristen Carlson Accardi <kristen@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/cpufreq')
-rw-r--r--drivers/cpufreq/Kconfig.x861
-rw-r--r--drivers/cpufreq/intel_pstate.c171
2 files changed, 171 insertions, 1 deletions
diff --git a/drivers/cpufreq/Kconfig.x86 b/drivers/cpufreq/Kconfig.x86
index c59bdcb83217..adbd1de1cea5 100644
--- a/drivers/cpufreq/Kconfig.x86
+++ b/drivers/cpufreq/Kconfig.x86
@@ -5,6 +5,7 @@
5config X86_INTEL_PSTATE 5config X86_INTEL_PSTATE
6 bool "Intel P state control" 6 bool "Intel P state control"
7 depends on X86 7 depends on X86
8 select ACPI_PROCESSOR if ACPI
8 help 9 help
9 This driver provides a P state for Intel core processors. 10 This driver provides a P state for Intel core processors.
10 The driver implements an internal governor and will become 11 The driver implements an internal governor and will become
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index 1369afdc1e19..041cb4107991 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -34,6 +34,10 @@
34#include <asm/cpu_device_id.h> 34#include <asm/cpu_device_id.h>
35#include <asm/cpufeature.h> 35#include <asm/cpufeature.h>
36 36
37#if IS_ENABLED(CONFIG_ACPI)
38#include <acpi/processor.h>
39#endif
40
37#define BYT_RATIOS 0x66a 41#define BYT_RATIOS 0x66a
38#define BYT_VIDS 0x66b 42#define BYT_VIDS 0x66b
39#define BYT_TURBO_RATIOS 0x66c 43#define BYT_TURBO_RATIOS 0x66c
@@ -113,6 +117,9 @@ struct cpudata {
113 u64 prev_mperf; 117 u64 prev_mperf;
114 u64 prev_tsc; 118 u64 prev_tsc;
115 struct sample sample; 119 struct sample sample;
120#if IS_ENABLED(CONFIG_ACPI)
121 struct acpi_processor_performance acpi_perf_data;
122#endif
116}; 123};
117 124
118static struct cpudata **all_cpu_data; 125static struct cpudata **all_cpu_data;
@@ -143,6 +150,7 @@ struct cpu_defaults {
143static struct pstate_adjust_policy pid_params; 150static struct pstate_adjust_policy pid_params;
144static struct pstate_funcs pstate_funcs; 151static struct pstate_funcs pstate_funcs;
145static int hwp_active; 152static int hwp_active;
153static int no_acpi_perf;
146 154
147struct perf_limits { 155struct perf_limits {
148 int no_turbo; 156 int no_turbo;
@@ -170,6 +178,153 @@ static struct perf_limits limits = {
170 .min_sysfs_pct = 0, 178 .min_sysfs_pct = 0,
171}; 179};
172 180
181#if IS_ENABLED(CONFIG_ACPI)
182/*
183 * The max target pstate ratio is a 8 bit value in both PLATFORM_INFO MSR and
184 * in TURBO_RATIO_LIMIT MSR, which pstate driver stores in max_pstate and
185 * max_turbo_pstate fields. The PERF_CTL MSR contains 16 bit value for P state
186 * ratio, out of it only high 8 bits are used. For example 0x1700 is setting
187 * target ratio 0x17. The _PSS control value stores in a format which can be
188 * directly written to PERF_CTL MSR. But in intel_pstate driver this shift
189 * occurs during write to PERF_CTL (E.g. for cores core_set_pstate()).
190 * This function converts the _PSS control value to intel pstate driver format
191 * for comparison and assignment.
192 */
193static int convert_to_native_pstate_format(struct cpudata *cpu, int index)
194{
195 return cpu->acpi_perf_data.states[index].control >> 8;
196}
197
198static int intel_pstate_init_perf_limits(struct cpufreq_policy *policy)
199{
200 struct cpudata *cpu;
201 int ret;
202 bool turbo_absent = false;
203 int max_pstate_index;
204 int min_pss_ctl, max_pss_ctl, turbo_pss_ctl;
205 int i;
206
207 cpu = all_cpu_data[policy->cpu];
208
209 pr_debug("intel_pstate: default limits 0x%x 0x%x 0x%x\n",
210 cpu->pstate.min_pstate, cpu->pstate.max_pstate,
211 cpu->pstate.turbo_pstate);
212
213 if (!cpu->acpi_perf_data.shared_cpu_map &&
214 zalloc_cpumask_var_node(&cpu->acpi_perf_data.shared_cpu_map,
215 GFP_KERNEL, cpu_to_node(policy->cpu))) {
216 return -ENOMEM;
217 }
218
219 ret = acpi_processor_register_performance(&cpu->acpi_perf_data,
220 policy->cpu);
221 if (ret)
222 return ret;
223
224 /*
225 * Check if the control value in _PSS is for PERF_CTL MSR, which should
226 * guarantee that the states returned by it map to the states in our
227 * list directly.
228 */
229 if (cpu->acpi_perf_data.control_register.space_id !=
230 ACPI_ADR_SPACE_FIXED_HARDWARE)
231 return -EIO;
232
233 pr_debug("intel_pstate: CPU%u - ACPI _PSS perf data\n", policy->cpu);
234 for (i = 0; i < cpu->acpi_perf_data.state_count; i++)
235 pr_debug(" %cP%d: %u MHz, %u mW, 0x%x\n",
236 (i == cpu->acpi_perf_data.state ? '*' : ' '), i,
237 (u32) cpu->acpi_perf_data.states[i].core_frequency,
238 (u32) cpu->acpi_perf_data.states[i].power,
239 (u32) cpu->acpi_perf_data.states[i].control);
240
241 /*
242 * If there is only one entry _PSS, simply ignore _PSS and continue as
243 * usual without taking _PSS into account
244 */
245 if (cpu->acpi_perf_data.state_count < 2)
246 return 0;
247
248 turbo_pss_ctl = convert_to_native_pstate_format(cpu, 0);
249 min_pss_ctl = convert_to_native_pstate_format(cpu,
250 cpu->acpi_perf_data.state_count - 1);
251 /* Check if there is a turbo freq in _PSS */
252 if (turbo_pss_ctl <= cpu->pstate.max_pstate &&
253 turbo_pss_ctl > cpu->pstate.min_pstate) {
254 pr_debug("intel_pstate: no turbo range exists in _PSS\n");
255 limits.no_turbo = limits.turbo_disabled = 1;
256 cpu->pstate.turbo_pstate = cpu->pstate.max_pstate;
257 turbo_absent = true;
258 }
259
260 /* Check if the max non turbo p state < Intel P state max */
261 max_pstate_index = turbo_absent ? 0 : 1;
262 max_pss_ctl = convert_to_native_pstate_format(cpu, max_pstate_index);
263 if (max_pss_ctl < cpu->pstate.max_pstate &&
264 max_pss_ctl > cpu->pstate.min_pstate)
265 cpu->pstate.max_pstate = max_pss_ctl;
266
267 /* check If min perf > Intel P State min */
268 if (min_pss_ctl > cpu->pstate.min_pstate &&
269 min_pss_ctl < cpu->pstate.max_pstate) {
270 cpu->pstate.min_pstate = min_pss_ctl;
271 policy->cpuinfo.min_freq = min_pss_ctl * cpu->pstate.scaling;
272 }
273
274 if (turbo_absent)
275 policy->cpuinfo.max_freq = cpu->pstate.max_pstate *
276 cpu->pstate.scaling;
277 else {
278 policy->cpuinfo.max_freq = cpu->pstate.turbo_pstate *
279 cpu->pstate.scaling;
280 /*
281 * The _PSS table doesn't contain whole turbo frequency range.
282 * This just contains +1 MHZ above the max non turbo frequency,
283 * with control value corresponding to max turbo ratio. But
284 * when cpufreq set policy is called, it will call with this
285 * max frequency, which will cause a reduced performance as
286 * this driver uses real max turbo frequency as the max
287 * frequeny. So correct this frequency in _PSS table to
288 * correct max turbo frequency based on the turbo ratio.
289 * Also need to convert to MHz as _PSS freq is in MHz.
290 */
291 cpu->acpi_perf_data.states[0].core_frequency =
292 turbo_pss_ctl * 100;
293 }
294
295 pr_debug("intel_pstate: Updated limits using _PSS 0x%x 0x%x 0x%x\n",
296 cpu->pstate.min_pstate, cpu->pstate.max_pstate,
297 cpu->pstate.turbo_pstate);
298 pr_debug("intel_pstate: policy max_freq=%d Khz min_freq = %d KHz\n",
299 policy->cpuinfo.max_freq, policy->cpuinfo.min_freq);
300
301 return 0;
302}
303
304static int intel_pstate_exit_perf_limits(struct cpufreq_policy *policy)
305{
306 struct cpudata *cpu;
307
308 if (!no_acpi_perf)
309 return 0;
310
311 cpu = all_cpu_data[policy->cpu];
312 acpi_processor_unregister_performance(policy->cpu);
313 return 0;
314}
315
316#else
317static int intel_pstate_init_perf_limits(struct cpufreq_policy *policy)
318{
319 return 0;
320}
321
322static int intel_pstate_exit_perf_limits(struct cpufreq_policy *policy)
323{
324 return 0;
325}
326#endif
327
173static inline void pid_reset(struct _pid *pid, int setpoint, int busy, 328static inline void pid_reset(struct _pid *pid, int setpoint, int busy,
174 int deadband, int integral) { 329 int deadband, int integral) {
175 pid->setpoint = setpoint; 330 pid->setpoint = setpoint;
@@ -1115,18 +1270,30 @@ static int intel_pstate_cpu_init(struct cpufreq_policy *policy)
1115 policy->cpuinfo.min_freq = cpu->pstate.min_pstate * cpu->pstate.scaling; 1270 policy->cpuinfo.min_freq = cpu->pstate.min_pstate * cpu->pstate.scaling;
1116 policy->cpuinfo.max_freq = 1271 policy->cpuinfo.max_freq =
1117 cpu->pstate.turbo_pstate * cpu->pstate.scaling; 1272 cpu->pstate.turbo_pstate * cpu->pstate.scaling;
1273 if (!no_acpi_perf)
1274 intel_pstate_init_perf_limits(policy);
1275 /*
1276 * If there is no acpi perf data or error, we ignore and use Intel P
1277 * state calculated limits, So this is not fatal error.
1278 */
1118 policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; 1279 policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
1119 cpumask_set_cpu(policy->cpu, policy->cpus); 1280 cpumask_set_cpu(policy->cpu, policy->cpus);
1120 1281
1121 return 0; 1282 return 0;
1122} 1283}
1123 1284
1285static int intel_pstate_cpu_exit(struct cpufreq_policy *policy)
1286{
1287 return intel_pstate_exit_perf_limits(policy);
1288}
1289
1124static struct cpufreq_driver intel_pstate_driver = { 1290static struct cpufreq_driver intel_pstate_driver = {
1125 .flags = CPUFREQ_CONST_LOOPS, 1291 .flags = CPUFREQ_CONST_LOOPS,
1126 .verify = intel_pstate_verify_policy, 1292 .verify = intel_pstate_verify_policy,
1127 .setpolicy = intel_pstate_set_policy, 1293 .setpolicy = intel_pstate_set_policy,
1128 .get = intel_pstate_get, 1294 .get = intel_pstate_get,
1129 .init = intel_pstate_cpu_init, 1295 .init = intel_pstate_cpu_init,
1296 .exit = intel_pstate_cpu_exit,
1130 .stop_cpu = intel_pstate_stop_cpu, 1297 .stop_cpu = intel_pstate_stop_cpu,
1131 .name = "intel_pstate", 1298 .name = "intel_pstate",
1132}; 1299};
@@ -1168,7 +1335,6 @@ static void copy_cpu_funcs(struct pstate_funcs *funcs)
1168} 1335}
1169 1336
1170#if IS_ENABLED(CONFIG_ACPI) 1337#if IS_ENABLED(CONFIG_ACPI)
1171#include <acpi/processor.h>
1172 1338
1173static bool intel_pstate_no_acpi_pss(void) 1339static bool intel_pstate_no_acpi_pss(void)
1174{ 1340{
@@ -1360,6 +1526,9 @@ static int __init intel_pstate_setup(char *str)
1360 force_load = 1; 1526 force_load = 1;
1361 if (!strcmp(str, "hwp_only")) 1527 if (!strcmp(str, "hwp_only"))
1362 hwp_only = 1; 1528 hwp_only = 1;
1529 if (!strcmp(str, "no_acpi"))
1530 no_acpi_perf = 1;
1531
1363 return 0; 1532 return 0;
1364} 1533}
1365early_param("intel_pstate", intel_pstate_setup); 1534early_param("intel_pstate", intel_pstate_setup);