aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/cpufreq/intel_pstate.c58
1 files changed, 54 insertions, 4 deletions
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index 5f1cbae36961..c84b280238a4 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -35,6 +35,7 @@
35#define SAMPLE_COUNT 3 35#define SAMPLE_COUNT 3
36 36
37#define BYT_RATIOS 0x66a 37#define BYT_RATIOS 0x66a
38#define BYT_VIDS 0x66b
38 39
39#define FRAC_BITS 8 40#define FRAC_BITS 8
40#define int_tofp(X) ((int64_t)(X) << FRAC_BITS) 41#define int_tofp(X) ((int64_t)(X) << FRAC_BITS)
@@ -64,6 +65,12 @@ struct pstate_data {
64 int turbo_pstate; 65 int turbo_pstate;
65}; 66};
66 67
68struct vid_data {
69 int32_t min;
70 int32_t max;
71 int32_t ratio;
72};
73
67struct _pid { 74struct _pid {
68 int setpoint; 75 int setpoint;
69 int32_t integral; 76 int32_t integral;
@@ -82,6 +89,7 @@ struct cpudata {
82 struct timer_list timer; 89 struct timer_list timer;
83 90
84 struct pstate_data pstate; 91 struct pstate_data pstate;
92 struct vid_data vid;
85 struct _pid pid; 93 struct _pid pid;
86 94
87 int min_pstate_count; 95 int min_pstate_count;
@@ -106,7 +114,8 @@ struct pstate_funcs {
106 int (*get_max)(void); 114 int (*get_max)(void);
107 int (*get_min)(void); 115 int (*get_min)(void);
108 int (*get_turbo)(void); 116 int (*get_turbo)(void);
109 void (*set)(int pstate); 117 void (*set)(struct cpudata*, int pstate);
118 void (*get_vid)(struct cpudata *);
110}; 119};
111 120
112struct cpu_defaults { 121struct cpu_defaults {
@@ -358,6 +367,42 @@ static int byt_get_max_pstate(void)
358 return (value >> 16) & 0xFF; 367 return (value >> 16) & 0xFF;
359} 368}
360 369
370static void byt_set_pstate(struct cpudata *cpudata, int pstate)
371{
372 u64 val;
373 int32_t vid_fp;
374 u32 vid;
375
376 val = pstate << 8;
377 if (limits.no_turbo)
378 val |= (u64)1 << 32;
379
380 vid_fp = cpudata->vid.min + mul_fp(
381 int_tofp(pstate - cpudata->pstate.min_pstate),
382 cpudata->vid.ratio);
383
384 vid_fp = clamp_t(int32_t, vid_fp, cpudata->vid.min, cpudata->vid.max);
385 vid = fp_toint(vid_fp);
386
387 val |= vid;
388
389 wrmsrl(MSR_IA32_PERF_CTL, val);
390}
391
392static void byt_get_vid(struct cpudata *cpudata)
393{
394 u64 value;
395
396 rdmsrl(BYT_VIDS, value);
397 cpudata->vid.min = int_tofp((value >> 8) & 0x7f);
398 cpudata->vid.max = int_tofp((value >> 16) & 0x7f);
399 cpudata->vid.ratio = div_fp(
400 cpudata->vid.max - cpudata->vid.min,
401 int_tofp(cpudata->pstate.max_pstate -
402 cpudata->pstate.min_pstate));
403}
404
405
361static int core_get_min_pstate(void) 406static int core_get_min_pstate(void)
362{ 407{
363 u64 value; 408 u64 value;
@@ -384,7 +429,7 @@ static int core_get_turbo_pstate(void)
384 return ret; 429 return ret;
385} 430}
386 431
387static void core_set_pstate(int pstate) 432static void core_set_pstate(struct cpudata *cpudata, int pstate)
388{ 433{
389 u64 val; 434 u64 val;
390 435
@@ -425,7 +470,8 @@ static struct cpu_defaults byt_params = {
425 .get_max = byt_get_max_pstate, 470 .get_max = byt_get_max_pstate,
426 .get_min = byt_get_min_pstate, 471 .get_min = byt_get_min_pstate,
427 .get_turbo = byt_get_max_pstate, 472 .get_turbo = byt_get_max_pstate,
428 .set = core_set_pstate, 473 .set = byt_set_pstate,
474 .get_vid = byt_get_vid,
429 }, 475 },
430}; 476};
431 477
@@ -462,7 +508,7 @@ static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate)
462 508
463 cpu->pstate.current_pstate = pstate; 509 cpu->pstate.current_pstate = pstate;
464 510
465 pstate_funcs.set(pstate); 511 pstate_funcs.set(cpu, pstate);
466} 512}
467 513
468static inline void intel_pstate_pstate_increase(struct cpudata *cpu, int steps) 514static inline void intel_pstate_pstate_increase(struct cpudata *cpu, int steps)
@@ -488,6 +534,9 @@ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
488 cpu->pstate.max_pstate = pstate_funcs.get_max(); 534 cpu->pstate.max_pstate = pstate_funcs.get_max();
489 cpu->pstate.turbo_pstate = pstate_funcs.get_turbo(); 535 cpu->pstate.turbo_pstate = pstate_funcs.get_turbo();
490 536
537 if (pstate_funcs.get_vid)
538 pstate_funcs.get_vid(cpu);
539
491 /* 540 /*
492 * goto max pstate so we don't slow up boot if we are built-in if we are 541 * goto max pstate so we don't slow up boot if we are built-in if we are
493 * a module we will take care of it during normal operation 542 * a module we will take care of it during normal operation
@@ -776,6 +825,7 @@ static void copy_cpu_funcs(struct pstate_funcs *funcs)
776 pstate_funcs.get_min = funcs->get_min; 825 pstate_funcs.get_min = funcs->get_min;
777 pstate_funcs.get_turbo = funcs->get_turbo; 826 pstate_funcs.get_turbo = funcs->get_turbo;
778 pstate_funcs.set = funcs->set; 827 pstate_funcs.set = funcs->set;
828 pstate_funcs.get_vid = funcs->get_vid;
779} 829}
780 830
781#if IS_ENABLED(CONFIG_ACPI) 831#if IS_ENABLED(CONFIG_ACPI)