Commit b27580b05e6f5253228debc60b8ff4a786ff573a

Authored by Dirk Brandewie
Committed by Rafael J. Wysocki
1 parent c034871712

intel_pstate: Fix BYT frequency reporting

BYT has a different conversion from P state to frequency than the core
processors.  This causes the min/max and current frequency to be
misreported on some BYT SKUs. Tested on BYT N2820, Ivybridge and
Haswell processors.

Link: https://bugzilla.yoctoproject.org/show_bug.cgi?id=6663
Cc: All applicable <stable@vger.kernel.org>
Signed-off-by: Dirk Brandewie <dirk.j.brandewie@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

Showing 1 changed file with 36 additions and 6 deletions Side-by-side Diff

drivers/cpufreq/intel_pstate.c
... ... @@ -64,6 +64,7 @@
64 64 int current_pstate;
65 65 int min_pstate;
66 66 int max_pstate;
  67 + int scaling;
67 68 int turbo_pstate;
68 69 };
69 70  
... ... @@ -113,6 +114,7 @@
113 114 int (*get_max)(void);
114 115 int (*get_min)(void);
115 116 int (*get_turbo)(void);
  117 + int (*get_scaling)(void);
116 118 void (*set)(struct cpudata*, int pstate);
117 119 void (*get_vid)(struct cpudata *);
118 120 };
... ... @@ -433,6 +435,22 @@
433 435 wrmsrl(MSR_IA32_PERF_CTL, val);
434 436 }
435 437  
  438 +#define BYT_BCLK_FREQS 5
  439 +static int byt_freq_table[BYT_BCLK_FREQS] = { 833, 1000, 1333, 1167, 800};
  440 +
  441 +static int byt_get_scaling(void)
  442 +{
  443 + u64 value;
  444 + int i;
  445 +
  446 + rdmsrl(MSR_FSB_FREQ, value);
  447 + i = value & 0x3;
  448 +
  449 + BUG_ON(i > BYT_BCLK_FREQS);
  450 +
  451 + return byt_freq_table[i] * 100;
  452 +}
  453 +
436 454 static void byt_get_vid(struct cpudata *cpudata)
437 455 {
438 456 u64 value;
... ... @@ -478,6 +496,11 @@
478 496 return ret;
479 497 }
480 498  
  499 +static inline int core_get_scaling(void)
  500 +{
  501 + return 100000;
  502 +}
  503 +
481 504 static void core_set_pstate(struct cpudata *cpudata, int pstate)
482 505 {
483 506 u64 val;
... ... @@ -502,6 +525,7 @@
502 525 .get_max = core_get_max_pstate,
503 526 .get_min = core_get_min_pstate,
504 527 .get_turbo = core_get_turbo_pstate,
  528 + .get_scaling = core_get_scaling,
505 529 .set = core_set_pstate,
506 530 },
507 531 };
... ... @@ -520,6 +544,7 @@
520 544 .get_min = byt_get_min_pstate,
521 545 .get_turbo = byt_get_turbo_pstate,
522 546 .set = byt_set_pstate,
  547 + .get_scaling = byt_get_scaling,
523 548 .get_vid = byt_get_vid,
524 549 },
525 550 };
... ... @@ -554,7 +579,7 @@
554 579 if (pstate == cpu->pstate.current_pstate)
555 580 return;
556 581  
557   - trace_cpu_frequency(pstate * 100000, cpu->cpu);
  582 + trace_cpu_frequency(pstate * cpu->pstate.scaling, cpu->cpu);
558 583  
559 584 cpu->pstate.current_pstate = pstate;
560 585  
... ... @@ -566,6 +591,7 @@
566 591 cpu->pstate.min_pstate = pstate_funcs.get_min();
567 592 cpu->pstate.max_pstate = pstate_funcs.get_max();
568 593 cpu->pstate.turbo_pstate = pstate_funcs.get_turbo();
  594 + cpu->pstate.scaling = pstate_funcs.get_scaling();
569 595  
570 596 if (pstate_funcs.get_vid)
571 597 pstate_funcs.get_vid(cpu);
... ... @@ -581,7 +607,9 @@
581 607 core_pct = div64_u64(core_pct, int_tofp(sample->mperf));
582 608  
583 609 sample->freq = fp_toint(
584   - mul_fp(int_tofp(cpu->pstate.max_pstate * 1000), core_pct));
  610 + mul_fp(int_tofp(
  611 + cpu->pstate.max_pstate * cpu->pstate.scaling / 100),
  612 + core_pct));
585 613  
586 614 sample->core_pct_busy = (int32_t)core_pct;
587 615 }
588 616  
... ... @@ -803,12 +831,13 @@
803 831 else
804 832 policy->policy = CPUFREQ_POLICY_POWERSAVE;
805 833  
806   - policy->min = cpu->pstate.min_pstate * 100000;
807   - policy->max = cpu->pstate.turbo_pstate * 100000;
  834 + policy->min = cpu->pstate.min_pstate * cpu->pstate.scaling;
  835 + policy->max = cpu->pstate.turbo_pstate * cpu->pstate.scaling;
808 836  
809 837 /* cpuinfo and default policy values */
810   - policy->cpuinfo.min_freq = cpu->pstate.min_pstate * 100000;
811   - policy->cpuinfo.max_freq = cpu->pstate.turbo_pstate * 100000;
  838 + policy->cpuinfo.min_freq = cpu->pstate.min_pstate * cpu->pstate.scaling;
  839 + policy->cpuinfo.max_freq =
  840 + cpu->pstate.turbo_pstate * cpu->pstate.scaling;
812 841 policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
813 842 cpumask_set_cpu(policy->cpu, policy->cpus);
814 843  
... ... @@ -866,6 +895,7 @@
866 895 pstate_funcs.get_max = funcs->get_max;
867 896 pstate_funcs.get_min = funcs->get_min;
868 897 pstate_funcs.get_turbo = funcs->get_turbo;
  898 + pstate_funcs.get_scaling = funcs->get_scaling;
869 899 pstate_funcs.set = funcs->set;
870 900 pstate_funcs.get_vid = funcs->get_vid;
871 901 }