diff options
author | Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> | 2015-10-14 19:12:01 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2015-10-14 19:53:18 -0400 |
commit | 37afb00032424d684a48d649fcfb8b5e4f17c409 (patch) | |
tree | 27e39c9822569de2b6a18e5cc38c2074ce34d69e /drivers/cpufreq | |
parent | 3bcc6fa971c06151d6bf90cb0dc80807f71b93f6 (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.x86 | 1 | ||||
-rw-r--r-- | drivers/cpufreq/intel_pstate.c | 171 |
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 @@ | |||
5 | config X86_INTEL_PSTATE | 5 | config 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 | ||
118 | static struct cpudata **all_cpu_data; | 125 | static struct cpudata **all_cpu_data; |
@@ -143,6 +150,7 @@ struct cpu_defaults { | |||
143 | static struct pstate_adjust_policy pid_params; | 150 | static struct pstate_adjust_policy pid_params; |
144 | static struct pstate_funcs pstate_funcs; | 151 | static struct pstate_funcs pstate_funcs; |
145 | static int hwp_active; | 152 | static int hwp_active; |
153 | static int no_acpi_perf; | ||
146 | 154 | ||
147 | struct perf_limits { | 155 | struct 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 | */ | ||
193 | static int convert_to_native_pstate_format(struct cpudata *cpu, int index) | ||
194 | { | ||
195 | return cpu->acpi_perf_data.states[index].control >> 8; | ||
196 | } | ||
197 | |||
198 | static 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 | |||
304 | static 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 | ||
317 | static int intel_pstate_init_perf_limits(struct cpufreq_policy *policy) | ||
318 | { | ||
319 | return 0; | ||
320 | } | ||
321 | |||
322 | static int intel_pstate_exit_perf_limits(struct cpufreq_policy *policy) | ||
323 | { | ||
324 | return 0; | ||
325 | } | ||
326 | #endif | ||
327 | |||
173 | static inline void pid_reset(struct _pid *pid, int setpoint, int busy, | 328 | static 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 | ||
1285 | static int intel_pstate_cpu_exit(struct cpufreq_policy *policy) | ||
1286 | { | ||
1287 | return intel_pstate_exit_perf_limits(policy); | ||
1288 | } | ||
1289 | |||
1124 | static struct cpufreq_driver intel_pstate_driver = { | 1290 | static 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 | ||
1173 | static bool intel_pstate_no_acpi_pss(void) | 1339 | static 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 | } |
1365 | early_param("intel_pstate", intel_pstate_setup); | 1534 | early_param("intel_pstate", intel_pstate_setup); |