diff options
| author | Dirk Brandewie <dirk.j.brandewie@intel.com> | 2014-05-08 15:57:23 -0400 |
|---|---|---|
| committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2014-05-11 19:58:58 -0400 |
| commit | 21855ff5bcbdd075e1c99772827a84912ab083dd (patch) | |
| tree | 94d57fd13861e229f1478c50cc47b6d3fd27a8dc | |
| parent | d6d211db37e75de2ddc3a4f979038c40df7cc79c (diff) | |
intel_pstate: Set turbo VID for BayTrail
A documentation update exposed that there is a separate set of VID
values that must be used in the turbo/boost P state range. Add
enumerating and setting the correct VID for P states in the turbo
range.
Cc: v3.13+ <stable@vger.kernel.org> # v3.13+
Signed-off-by: Dirk Brandewie <dirk.j.brandewie@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
| -rw-r--r-- | drivers/cpufreq/intel_pstate.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 099967302bf2..39c4f8520848 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c | |||
| @@ -37,6 +37,7 @@ | |||
| 37 | #define BYT_RATIOS 0x66a | 37 | #define BYT_RATIOS 0x66a |
| 38 | #define BYT_VIDS 0x66b | 38 | #define BYT_VIDS 0x66b |
| 39 | #define BYT_TURBO_RATIOS 0x66c | 39 | #define BYT_TURBO_RATIOS 0x66c |
| 40 | #define BYT_TURBO_VIDS 0x66d | ||
| 40 | 41 | ||
| 41 | 42 | ||
| 42 | #define FRAC_BITS 6 | 43 | #define FRAC_BITS 6 |
| @@ -70,8 +71,9 @@ struct pstate_data { | |||
| 70 | }; | 71 | }; |
| 71 | 72 | ||
| 72 | struct vid_data { | 73 | struct vid_data { |
| 73 | int32_t min; | 74 | int min; |
| 74 | int32_t max; | 75 | int max; |
| 76 | int turbo; | ||
| 75 | int32_t ratio; | 77 | int32_t ratio; |
| 76 | }; | 78 | }; |
| 77 | 79 | ||
| @@ -359,14 +361,14 @@ static int byt_get_min_pstate(void) | |||
| 359 | { | 361 | { |
| 360 | u64 value; | 362 | u64 value; |
| 361 | rdmsrl(BYT_RATIOS, value); | 363 | rdmsrl(BYT_RATIOS, value); |
| 362 | return (value >> 8) & 0xFF; | 364 | return (value >> 8) & 0x3F; |
| 363 | } | 365 | } |
| 364 | 366 | ||
| 365 | static int byt_get_max_pstate(void) | 367 | static int byt_get_max_pstate(void) |
| 366 | { | 368 | { |
| 367 | u64 value; | 369 | u64 value; |
| 368 | rdmsrl(BYT_RATIOS, value); | 370 | rdmsrl(BYT_RATIOS, value); |
| 369 | return (value >> 16) & 0xFF; | 371 | return (value >> 16) & 0x3F; |
| 370 | } | 372 | } |
| 371 | 373 | ||
| 372 | static int byt_get_turbo_pstate(void) | 374 | static int byt_get_turbo_pstate(void) |
| @@ -393,6 +395,9 @@ static void byt_set_pstate(struct cpudata *cpudata, int pstate) | |||
| 393 | vid_fp = clamp_t(int32_t, vid_fp, cpudata->vid.min, cpudata->vid.max); | 395 | vid_fp = clamp_t(int32_t, vid_fp, cpudata->vid.min, cpudata->vid.max); |
| 394 | vid = fp_toint(vid_fp); | 396 | vid = fp_toint(vid_fp); |
| 395 | 397 | ||
| 398 | if (pstate > cpudata->pstate.max_pstate) | ||
| 399 | vid = cpudata->vid.turbo; | ||
| 400 | |||
| 396 | val |= vid; | 401 | val |= vid; |
| 397 | 402 | ||
| 398 | wrmsrl(MSR_IA32_PERF_CTL, val); | 403 | wrmsrl(MSR_IA32_PERF_CTL, val); |
| @@ -402,13 +407,17 @@ static void byt_get_vid(struct cpudata *cpudata) | |||
| 402 | { | 407 | { |
| 403 | u64 value; | 408 | u64 value; |
| 404 | 409 | ||
| 410 | |||
| 405 | rdmsrl(BYT_VIDS, value); | 411 | rdmsrl(BYT_VIDS, value); |
| 406 | cpudata->vid.min = int_tofp((value >> 8) & 0x7f); | 412 | cpudata->vid.min = int_tofp((value >> 8) & 0x3f); |
| 407 | cpudata->vid.max = int_tofp((value >> 16) & 0x7f); | 413 | cpudata->vid.max = int_tofp((value >> 16) & 0x3f); |
| 408 | cpudata->vid.ratio = div_fp( | 414 | cpudata->vid.ratio = div_fp( |
| 409 | cpudata->vid.max - cpudata->vid.min, | 415 | cpudata->vid.max - cpudata->vid.min, |
| 410 | int_tofp(cpudata->pstate.max_pstate - | 416 | int_tofp(cpudata->pstate.max_pstate - |
| 411 | cpudata->pstate.min_pstate)); | 417 | cpudata->pstate.min_pstate)); |
| 418 | |||
| 419 | rdmsrl(BYT_TURBO_VIDS, value); | ||
| 420 | cpudata->vid.turbo = value & 0x7f; | ||
| 412 | } | 421 | } |
| 413 | 422 | ||
| 414 | 423 | ||
