diff options
Diffstat (limited to 'drivers/cpufreq/intel_pstate.c')
| -rw-r--r-- | drivers/cpufreq/intel_pstate.c | 34 |
1 files changed, 16 insertions, 18 deletions
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 099967302bf2..eab8ccfe6beb 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 | ||
| @@ -545,12 +554,7 @@ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu) | |||
| 545 | 554 | ||
| 546 | if (pstate_funcs.get_vid) | 555 | if (pstate_funcs.get_vid) |
| 547 | pstate_funcs.get_vid(cpu); | 556 | pstate_funcs.get_vid(cpu); |
| 548 | 557 | intel_pstate_set_pstate(cpu, cpu->pstate.min_pstate); | |
| 549 | /* | ||
| 550 | * goto max pstate so we don't slow up boot if we are built-in if we are | ||
| 551 | * a module we will take care of it during normal operation | ||
| 552 | */ | ||
| 553 | intel_pstate_set_pstate(cpu, cpu->pstate.max_pstate); | ||
| 554 | } | 558 | } |
| 555 | 559 | ||
| 556 | static inline void intel_pstate_calc_busy(struct cpudata *cpu, | 560 | static inline void intel_pstate_calc_busy(struct cpudata *cpu, |
| @@ -695,11 +699,6 @@ static int intel_pstate_init_cpu(unsigned int cpunum) | |||
| 695 | cpu = all_cpu_data[cpunum]; | 699 | cpu = all_cpu_data[cpunum]; |
| 696 | 700 | ||
| 697 | intel_pstate_get_cpu_pstates(cpu); | 701 | intel_pstate_get_cpu_pstates(cpu); |
| 698 | if (!cpu->pstate.current_pstate) { | ||
| 699 | all_cpu_data[cpunum] = NULL; | ||
| 700 | kfree(cpu); | ||
| 701 | return -ENODATA; | ||
| 702 | } | ||
| 703 | 702 | ||
| 704 | cpu->cpu = cpunum; | 703 | cpu->cpu = cpunum; |
| 705 | 704 | ||
| @@ -710,7 +709,6 @@ static int intel_pstate_init_cpu(unsigned int cpunum) | |||
| 710 | cpu->timer.expires = jiffies + HZ/100; | 709 | cpu->timer.expires = jiffies + HZ/100; |
| 711 | intel_pstate_busy_pid_reset(cpu); | 710 | intel_pstate_busy_pid_reset(cpu); |
| 712 | intel_pstate_sample(cpu); | 711 | intel_pstate_sample(cpu); |
| 713 | intel_pstate_set_pstate(cpu, cpu->pstate.max_pstate); | ||
| 714 | 712 | ||
| 715 | add_timer_on(&cpu->timer, cpunum); | 713 | add_timer_on(&cpu->timer, cpunum); |
| 716 | 714 | ||
