diff options
-rw-r--r-- | drivers/cpufreq/intel_pstate.c | 58 |
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 | ||
68 | struct vid_data { | ||
69 | int32_t min; | ||
70 | int32_t max; | ||
71 | int32_t ratio; | ||
72 | }; | ||
73 | |||
67 | struct _pid { | 74 | struct _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 | ||
112 | struct cpu_defaults { | 121 | struct 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 | ||
370 | static 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 | |||
392 | static 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 | |||
361 | static int core_get_min_pstate(void) | 406 | static 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 | ||
387 | static void core_set_pstate(int pstate) | 432 | static 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 | ||
468 | static inline void intel_pstate_pstate_increase(struct cpudata *cpu, int steps) | 514 | static 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) |