aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq/intel_pstate.c
diff options
context:
space:
mode:
authorDirk Brandewie <dirk.j.brandewie@intel.com>2013-10-21 12:20:34 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-10-25 17:46:10 -0400
commit016c815084d5b89f7c1a24b1a3a0b796512a91bc (patch)
tree7ef6c7979e3011eebd1355ebc8561fdacad84170 /drivers/cpufreq/intel_pstate.c
parent9c0ebcf78fde0ffa348a95a544c6d3f2dac5af65 (diff)
intel_pstate: Refactor driver to support CPUs with different MSR layouts
Non-core processors have a different MSR layout to commumicate P state information. Refactor the driver to use CPU dependent accessors to P state information. Signed-off-by: Dirk Brandewie <dirk.j.brandewie@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/cpufreq/intel_pstate.c')
-rw-r--r--drivers/cpufreq/intel_pstate.c144
1 files changed, 98 insertions, 46 deletions
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index d57648989c0b..6b37c9ff1d64 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -78,7 +78,6 @@ struct cpudata {
78 78
79 struct timer_list timer; 79 struct timer_list timer;
80 80
81 struct pstate_adjust_policy *pstate_policy;
82 struct pstate_data pstate; 81 struct pstate_data pstate;
83 struct _pid pid; 82 struct _pid pid;
84 83
@@ -100,15 +99,21 @@ struct pstate_adjust_policy {
100 int i_gain_pct; 99 int i_gain_pct;
101}; 100};
102 101
103static struct pstate_adjust_policy default_policy = { 102struct pstate_funcs {
104 .sample_rate_ms = 10, 103 int (*get_max)(void);
105 .deadband = 0, 104 int (*get_min)(void);
106 .setpoint = 97, 105 int (*get_turbo)(void);
107 .p_gain_pct = 20, 106 void (*set)(int pstate);
108 .d_gain_pct = 0,
109 .i_gain_pct = 0,
110}; 107};
111 108
109struct cpu_defaults {
110 struct pstate_adjust_policy pid_policy;
111 struct pstate_funcs funcs;
112};
113
114static struct pstate_adjust_policy pid_params;
115static struct pstate_funcs pstate_funcs;
116
112struct perf_limits { 117struct perf_limits {
113 int no_turbo; 118 int no_turbo;
114 int max_perf_pct; 119 int max_perf_pct;
@@ -186,14 +191,14 @@ static signed int pid_calc(struct _pid *pid, int busy)
186 191
187static inline void intel_pstate_busy_pid_reset(struct cpudata *cpu) 192static inline void intel_pstate_busy_pid_reset(struct cpudata *cpu)
188{ 193{
189 pid_p_gain_set(&cpu->pid, cpu->pstate_policy->p_gain_pct); 194 pid_p_gain_set(&cpu->pid, pid_params.p_gain_pct);
190 pid_d_gain_set(&cpu->pid, cpu->pstate_policy->d_gain_pct); 195 pid_d_gain_set(&cpu->pid, pid_params.d_gain_pct);
191 pid_i_gain_set(&cpu->pid, cpu->pstate_policy->i_gain_pct); 196 pid_i_gain_set(&cpu->pid, pid_params.i_gain_pct);
192 197
193 pid_reset(&cpu->pid, 198 pid_reset(&cpu->pid,
194 cpu->pstate_policy->setpoint, 199 pid_params.setpoint,
195 100, 200 100,
196 cpu->pstate_policy->deadband, 201 pid_params.deadband,
197 0); 202 0);
198} 203}
199 204
@@ -227,12 +232,12 @@ struct pid_param {
227}; 232};
228 233
229static struct pid_param pid_files[] = { 234static struct pid_param pid_files[] = {
230 {"sample_rate_ms", &default_policy.sample_rate_ms}, 235 {"sample_rate_ms", &pid_params.sample_rate_ms},
231 {"d_gain_pct", &default_policy.d_gain_pct}, 236 {"d_gain_pct", &pid_params.d_gain_pct},
232 {"i_gain_pct", &default_policy.i_gain_pct}, 237 {"i_gain_pct", &pid_params.i_gain_pct},
233 {"deadband", &default_policy.deadband}, 238 {"deadband", &pid_params.deadband},
234 {"setpoint", &default_policy.setpoint}, 239 {"setpoint", &pid_params.setpoint},
235 {"p_gain_pct", &default_policy.p_gain_pct}, 240 {"p_gain_pct", &pid_params.p_gain_pct},
236 {NULL, NULL} 241 {NULL, NULL}
237}; 242};
238 243
@@ -337,33 +342,60 @@ static void intel_pstate_sysfs_expose_params(void)
337} 342}
338 343
339/************************** sysfs end ************************/ 344/************************** sysfs end ************************/
340 345static int core_get_min_pstate(void)
341static int intel_pstate_min_pstate(void)
342{ 346{
343 u64 value; 347 u64 value;
344 rdmsrl(MSR_PLATFORM_INFO, value); 348 rdmsrl(MSR_PLATFORM_INFO, value);
345 return (value >> 40) & 0xFF; 349 return (value >> 40) & 0xFF;
346} 350}
347 351
348static int intel_pstate_max_pstate(void) 352static int core_get_max_pstate(void)
349{ 353{
350 u64 value; 354 u64 value;
351 rdmsrl(MSR_PLATFORM_INFO, value); 355 rdmsrl(MSR_PLATFORM_INFO, value);
352 return (value >> 8) & 0xFF; 356 return (value >> 8) & 0xFF;
353} 357}
354 358
355static int intel_pstate_turbo_pstate(void) 359static int core_get_turbo_pstate(void)
356{ 360{
357 u64 value; 361 u64 value;
358 int nont, ret; 362 int nont, ret;
359 rdmsrl(MSR_NHM_TURBO_RATIO_LIMIT, value); 363 rdmsrl(MSR_NHM_TURBO_RATIO_LIMIT, value);
360 nont = intel_pstate_max_pstate(); 364 nont = core_get_max_pstate();
361 ret = ((value) & 255); 365 ret = ((value) & 255);
362 if (ret <= nont) 366 if (ret <= nont)
363 ret = nont; 367 ret = nont;
364 return ret; 368 return ret;
365} 369}
366 370
371static void core_set_pstate(int pstate)
372{
373 u64 val;
374
375 val = pstate << 8;
376 if (limits.no_turbo)
377 val |= (u64)1 << 32;
378
379 wrmsrl(MSR_IA32_PERF_CTL, val);
380}
381
382static struct cpu_defaults core_params = {
383 .pid_policy = {
384 .sample_rate_ms = 10,
385 .deadband = 0,
386 .setpoint = 97,
387 .p_gain_pct = 20,
388 .d_gain_pct = 0,
389 .i_gain_pct = 0,
390 },
391 .funcs = {
392 .get_max = core_get_max_pstate,
393 .get_min = core_get_min_pstate,
394 .get_turbo = core_get_turbo_pstate,
395 .set = core_set_pstate,
396 },
397};
398
367static void intel_pstate_get_min_max(struct cpudata *cpu, int *min, int *max) 399static void intel_pstate_get_min_max(struct cpudata *cpu, int *min, int *max)
368{ 400{
369 int max_perf = cpu->pstate.turbo_pstate; 401 int max_perf = cpu->pstate.turbo_pstate;
@@ -383,7 +415,6 @@ static void intel_pstate_get_min_max(struct cpudata *cpu, int *min, int *max)
383static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate) 415static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate)
384{ 416{
385 int max_perf, min_perf; 417 int max_perf, min_perf;
386 u64 val;
387 418
388 intel_pstate_get_min_max(cpu, &min_perf, &max_perf); 419 intel_pstate_get_min_max(cpu, &min_perf, &max_perf);
389 420
@@ -395,11 +426,8 @@ static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate)
395 trace_cpu_frequency(pstate * 100000, cpu->cpu); 426 trace_cpu_frequency(pstate * 100000, cpu->cpu);
396 427
397 cpu->pstate.current_pstate = pstate; 428 cpu->pstate.current_pstate = pstate;
398 val = pstate << 8;
399 if (limits.no_turbo)
400 val |= (u64)1 << 32;
401 429
402 wrmsrl(MSR_IA32_PERF_CTL, val); 430 pstate_funcs.set(pstate);
403} 431}
404 432
405static inline void intel_pstate_pstate_increase(struct cpudata *cpu, int steps) 433static inline void intel_pstate_pstate_increase(struct cpudata *cpu, int steps)
@@ -421,9 +449,9 @@ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
421{ 449{
422 sprintf(cpu->name, "Intel 2nd generation core"); 450 sprintf(cpu->name, "Intel 2nd generation core");
423 451
424 cpu->pstate.min_pstate = intel_pstate_min_pstate(); 452 cpu->pstate.min_pstate = pstate_funcs.get_min();
425 cpu->pstate.max_pstate = intel_pstate_max_pstate(); 453 cpu->pstate.max_pstate = pstate_funcs.get_max();
426 cpu->pstate.turbo_pstate = intel_pstate_turbo_pstate(); 454 cpu->pstate.turbo_pstate = pstate_funcs.get_turbo();
427 455
428 /* 456 /*
429 * goto max pstate so we don't slow up boot if we are built-in if we are 457 * goto max pstate so we don't slow up boot if we are built-in if we are
@@ -464,7 +492,7 @@ static inline void intel_pstate_set_sample_time(struct cpudata *cpu)
464{ 492{
465 int sample_time, delay; 493 int sample_time, delay;
466 494
467 sample_time = cpu->pstate_policy->sample_rate_ms; 495 sample_time = pid_params.sample_rate_ms;
468 delay = msecs_to_jiffies(sample_time); 496 delay = msecs_to_jiffies(sample_time);
469 mod_timer_pinned(&cpu->timer, jiffies + delay); 497 mod_timer_pinned(&cpu->timer, jiffies + delay);
470} 498}
@@ -523,14 +551,14 @@ static void intel_pstate_timer_func(unsigned long __data)
523 { X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long)&policy } 551 { X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long)&policy }
524 552
525static const struct x86_cpu_id intel_pstate_cpu_ids[] = { 553static const struct x86_cpu_id intel_pstate_cpu_ids[] = {
526 ICPU(0x2a, default_policy), 554 ICPU(0x2a, core_params),
527 ICPU(0x2d, default_policy), 555 ICPU(0x2d, core_params),
528 ICPU(0x3a, default_policy), 556 ICPU(0x3a, core_params),
529 ICPU(0x3c, default_policy), 557 ICPU(0x3c, core_params),
530 ICPU(0x3e, default_policy), 558 ICPU(0x3e, core_params),
531 ICPU(0x3f, default_policy), 559 ICPU(0x3f, core_params),
532 ICPU(0x45, default_policy), 560 ICPU(0x45, core_params),
533 ICPU(0x46, default_policy), 561 ICPU(0x46, core_params),
534 {} 562 {}
535}; 563};
536MODULE_DEVICE_TABLE(x86cpu, intel_pstate_cpu_ids); 564MODULE_DEVICE_TABLE(x86cpu, intel_pstate_cpu_ids);
@@ -554,8 +582,7 @@ static int intel_pstate_init_cpu(unsigned int cpunum)
554 intel_pstate_get_cpu_pstates(cpu); 582 intel_pstate_get_cpu_pstates(cpu);
555 583
556 cpu->cpu = cpunum; 584 cpu->cpu = cpunum;
557 cpu->pstate_policy = 585
558 (struct pstate_adjust_policy *)id->driver_data;
559 init_timer_deferrable(&cpu->timer); 586 init_timer_deferrable(&cpu->timer);
560 cpu->timer.function = intel_pstate_timer_func; 587 cpu->timer.function = intel_pstate_timer_func;
561 cpu->timer.data = 588 cpu->timer.data =
@@ -683,9 +710,9 @@ static int intel_pstate_msrs_not_valid(void)
683 rdmsrl(MSR_IA32_APERF, aperf); 710 rdmsrl(MSR_IA32_APERF, aperf);
684 rdmsrl(MSR_IA32_MPERF, mperf); 711 rdmsrl(MSR_IA32_MPERF, mperf);
685 712
686 if (!intel_pstate_min_pstate() || 713 if (!pstate_funcs.get_max() ||
687 !intel_pstate_max_pstate() || 714 !pstate_funcs.get_min() ||
688 !intel_pstate_turbo_pstate()) 715 !pstate_funcs.get_turbo())
689 return -ENODEV; 716 return -ENODEV;
690 717
691 rdmsrl(MSR_IA32_APERF, tmp); 718 rdmsrl(MSR_IA32_APERF, tmp);
@@ -698,10 +725,30 @@ static int intel_pstate_msrs_not_valid(void)
698 725
699 return 0; 726 return 0;
700} 727}
728
729void copy_pid_params(struct pstate_adjust_policy *policy)
730{
731 pid_params.sample_rate_ms = policy->sample_rate_ms;
732 pid_params.p_gain_pct = policy->p_gain_pct;
733 pid_params.i_gain_pct = policy->i_gain_pct;
734 pid_params.d_gain_pct = policy->d_gain_pct;
735 pid_params.deadband = policy->deadband;
736 pid_params.setpoint = policy->setpoint;
737}
738
739void copy_cpu_funcs(struct pstate_funcs *funcs)
740{
741 pstate_funcs.get_max = funcs->get_max;
742 pstate_funcs.get_min = funcs->get_min;
743 pstate_funcs.get_turbo = funcs->get_turbo;
744 pstate_funcs.set = funcs->set;
745}
746
701static int __init intel_pstate_init(void) 747static int __init intel_pstate_init(void)
702{ 748{
703 int cpu, rc = 0; 749 int cpu, rc = 0;
704 const struct x86_cpu_id *id; 750 const struct x86_cpu_id *id;
751 struct cpu_defaults *cpu_info;
705 752
706 if (no_load) 753 if (no_load)
707 return -ENODEV; 754 return -ENODEV;
@@ -710,6 +757,11 @@ static int __init intel_pstate_init(void)
710 if (!id) 757 if (!id)
711 return -ENODEV; 758 return -ENODEV;
712 759
760 cpu_info = (struct cpu_defaults *)id->driver_data;
761
762 copy_pid_params(&cpu_info->pid_policy);
763 copy_cpu_funcs(&cpu_info->funcs);
764
713 if (intel_pstate_msrs_not_valid()) 765 if (intel_pstate_msrs_not_valid())
714 return -ENODEV; 766 return -ENODEV;
715 767