@@ -268,6 +268,7 @@ static struct cpudata **all_cpu_data;
268
268
* @get_min: Callback to get minimum P state
269
269
* @get_turbo: Callback to get turbo P state
270
270
* @get_scaling: Callback to get frequency scaling factor
271
+ * @get_cpu_scaling: Get frequency scaling factor for a given cpu
271
272
* @get_aperf_mperf_shift: Callback to get the APERF vs MPERF frequency difference
272
273
* @get_val: Callback to convert P state to actual MSR write value
273
274
* @get_vid: Callback to get VID data for Atom platforms
@@ -281,6 +282,7 @@ struct pstate_funcs {
281
282
int (* get_min )(void );
282
283
int (* get_turbo )(void );
283
284
int (* get_scaling )(void );
285
+ int (* get_cpu_scaling )(int cpu );
284
286
int (* get_aperf_mperf_shift )(void );
285
287
u64 (* get_val )(struct cpudata * , int pstate );
286
288
void (* get_vid )(struct cpudata * );
@@ -384,6 +386,15 @@ static int intel_pstate_get_cppc_guaranteed(int cpu)
384
386
return cppc_perf .nominal_perf ;
385
387
}
386
388
389
+ static u32 intel_pstate_cppc_nominal (int cpu )
390
+ {
391
+ u64 nominal_perf ;
392
+
393
+ if (cppc_get_nominal_perf (cpu , & nominal_perf ))
394
+ return 0 ;
395
+
396
+ return nominal_perf ;
397
+ }
387
398
#else /* CONFIG_ACPI_CPPC_LIB */
388
399
static inline void intel_pstate_set_itmt_prio (int cpu )
389
400
{
@@ -470,20 +481,6 @@ static void intel_pstate_exit_perf_limits(struct cpufreq_policy *policy)
470
481
471
482
acpi_processor_unregister_performance (policy -> cpu );
472
483
}
473
-
474
- static bool intel_pstate_cppc_perf_valid (u32 perf , struct cppc_perf_caps * caps )
475
- {
476
- return perf && perf <= caps -> highest_perf && perf >= caps -> lowest_perf ;
477
- }
478
-
479
- static bool intel_pstate_cppc_perf_caps (struct cpudata * cpu ,
480
- struct cppc_perf_caps * caps )
481
- {
482
- if (cppc_get_perf_caps (cpu -> cpu , caps ))
483
- return false;
484
-
485
- return caps -> highest_perf && caps -> lowest_perf <= caps -> highest_perf ;
486
- }
487
484
#else /* CONFIG_ACPI */
488
485
static inline void intel_pstate_init_acpi_perf_limits (struct cpufreq_policy * policy )
489
486
{
@@ -506,131 +503,55 @@ static inline int intel_pstate_get_cppc_guaranteed(int cpu)
506
503
}
507
504
#endif /* CONFIG_ACPI_CPPC_LIB */
508
505
509
- static void intel_pstate_hybrid_hwp_perf_ctl_parity (struct cpudata * cpu )
510
- {
511
- pr_debug ("CPU%d: Using PERF_CTL scaling for HWP\n" , cpu -> cpu );
512
-
513
- cpu -> pstate .scaling = cpu -> pstate .perf_ctl_scaling ;
514
- }
515
-
516
506
/**
517
- * intel_pstate_hybrid_hwp_calibrate - Calibrate HWP performance levels.
507
+ * intel_pstate_hybrid_hwp_adjust - Calibrate HWP performance levels.
518
508
* @cpu: Target CPU.
519
509
*
520
510
* On hybrid processors, HWP may expose more performance levels than there are
521
511
* P-states accessible through the PERF_CTL interface. If that happens, the
522
512
* scaling factor between HWP performance levels and CPU frequency will be less
523
513
* than the scaling factor between P-state values and CPU frequency.
524
514
*
525
- * In that case, the scaling factor between HWP performance levels and CPU
526
- * frequency needs to be determined which can be done with the help of the
527
- * observation that certain HWP performance levels should correspond to certain
528
- * P-states, like for example the HWP highest performance should correspond
529
- * to the maximum turbo P-state of the CPU.
515
+ * In that case, adjust the CPU parameters used in computations accordingly.
530
516
*/
531
- static void intel_pstate_hybrid_hwp_calibrate (struct cpudata * cpu )
517
+ static void intel_pstate_hybrid_hwp_adjust (struct cpudata * cpu )
532
518
{
533
519
int perf_ctl_max_phys = cpu -> pstate .max_pstate_physical ;
534
520
int perf_ctl_scaling = cpu -> pstate .perf_ctl_scaling ;
535
521
int perf_ctl_turbo = pstate_funcs .get_turbo ();
536
522
int turbo_freq = perf_ctl_turbo * perf_ctl_scaling ;
537
- int perf_ctl_max = pstate_funcs .get_max ();
538
- int max_freq = perf_ctl_max * perf_ctl_scaling ;
539
- int scaling = INT_MAX ;
540
- int freq ;
523
+ int scaling = cpu -> pstate .scaling ;
541
524
542
525
pr_debug ("CPU%d: perf_ctl_max_phys = %d\n" , cpu -> cpu , perf_ctl_max_phys );
543
- pr_debug ("CPU%d: perf_ctl_max = %d\n" , cpu -> cpu , perf_ctl_max );
526
+ pr_debug ("CPU%d: perf_ctl_max = %d\n" , cpu -> cpu , pstate_funcs . get_max () );
544
527
pr_debug ("CPU%d: perf_ctl_turbo = %d\n" , cpu -> cpu , perf_ctl_turbo );
545
528
pr_debug ("CPU%d: perf_ctl_scaling = %d\n" , cpu -> cpu , perf_ctl_scaling );
546
-
547
529
pr_debug ("CPU%d: HWP_CAP guaranteed = %d\n" , cpu -> cpu , cpu -> pstate .max_pstate );
548
530
pr_debug ("CPU%d: HWP_CAP highest = %d\n" , cpu -> cpu , cpu -> pstate .turbo_pstate );
549
-
550
- #ifdef CONFIG_ACPI
551
- if (IS_ENABLED (CONFIG_ACPI_CPPC_LIB )) {
552
- struct cppc_perf_caps caps ;
553
-
554
- if (intel_pstate_cppc_perf_caps (cpu , & caps )) {
555
- if (intel_pstate_cppc_perf_valid (caps .nominal_perf , & caps )) {
556
- pr_debug ("CPU%d: Using CPPC nominal\n" , cpu -> cpu );
557
-
558
- /*
559
- * If the CPPC nominal performance is valid, it
560
- * can be assumed to correspond to cpu_khz.
561
- */
562
- if (caps .nominal_perf == perf_ctl_max_phys ) {
563
- intel_pstate_hybrid_hwp_perf_ctl_parity (cpu );
564
- return ;
565
- }
566
- scaling = DIV_ROUND_UP (cpu_khz , caps .nominal_perf );
567
- } else if (intel_pstate_cppc_perf_valid (caps .guaranteed_perf , & caps )) {
568
- pr_debug ("CPU%d: Using CPPC guaranteed\n" , cpu -> cpu );
569
-
570
- /*
571
- * If the CPPC guaranteed performance is valid,
572
- * it can be assumed to correspond to max_freq.
573
- */
574
- if (caps .guaranteed_perf == perf_ctl_max ) {
575
- intel_pstate_hybrid_hwp_perf_ctl_parity (cpu );
576
- return ;
577
- }
578
- scaling = DIV_ROUND_UP (max_freq , caps .guaranteed_perf );
579
- }
580
- }
581
- }
582
- #endif
583
- /*
584
- * If using the CPPC data to compute the HWP-to-frequency scaling factor
585
- * doesn't work, use the HWP_CAP gauranteed perf for this purpose with
586
- * the assumption that it corresponds to max_freq.
587
- */
588
- if (scaling > perf_ctl_scaling ) {
589
- pr_debug ("CPU%d: Using HWP_CAP guaranteed\n" , cpu -> cpu );
590
-
591
- if (cpu -> pstate .max_pstate == perf_ctl_max ) {
592
- intel_pstate_hybrid_hwp_perf_ctl_parity (cpu );
593
- return ;
594
- }
595
- scaling = DIV_ROUND_UP (max_freq , cpu -> pstate .max_pstate );
596
- if (scaling > perf_ctl_scaling ) {
597
- /*
598
- * This should not happen, because it would mean that
599
- * the number of HWP perf levels was less than the
600
- * number of P-states, so use the PERF_CTL scaling in
601
- * that case.
602
- */
603
- pr_debug ("CPU%d: scaling (%d) out of range\n" , cpu -> cpu ,
604
- scaling );
605
-
606
- intel_pstate_hybrid_hwp_perf_ctl_parity (cpu );
607
- return ;
608
- }
609
- }
531
+ pr_debug ("CPU%d: HWP-to-frequency scaling factor: %d\n" , cpu -> cpu , scaling );
610
532
611
533
/*
612
- * If the product of the HWP performance scaling factor obtained above
613
- * and the HWP_CAP highest performance is greater than the maximum turbo
614
- * frequency corresponding to the pstate_funcs.get_turbo() return value,
615
- * the scaling factor is too high, so recompute it so that the HWP_CAP
616
- * highest performance corresponds to the maximum turbo frequency.
534
+ * If the product of the HWP performance scaling factor and the HWP_CAP
535
+ * highest performance is greater than the maximum turbo frequency
536
+ * corresponding to the pstate_funcs.get_turbo() return value, the
537
+ * scaling factor is too high, so recompute it to make the HWP_CAP
538
+ * highest performance correspond to the maximum turbo frequency.
617
539
*/
618
540
if (turbo_freq < cpu -> pstate .turbo_pstate * scaling ) {
619
- pr_debug ("CPU%d: scaling too high (%d)\n" , cpu -> cpu , scaling );
620
-
621
541
cpu -> pstate .turbo_freq = turbo_freq ;
622
542
scaling = DIV_ROUND_UP (turbo_freq , cpu -> pstate .turbo_pstate );
623
- }
543
+ cpu -> pstate . scaling = scaling ;
624
544
625
- cpu -> pstate . scaling = scaling ;
626
-
627
- pr_debug ( "CPU%d: HWP-to-frequency scaling factor: %d\n" , cpu -> cpu , scaling );
545
+ pr_debug ( "CPU%d: refined HWP-to-frequency scaling factor: %d\n" ,
546
+ cpu -> cpu , scaling );
547
+ }
628
548
629
549
cpu -> pstate .max_freq = rounddown (cpu -> pstate .max_pstate * scaling ,
630
550
perf_ctl_scaling );
631
551
632
- freq = perf_ctl_max_phys * perf_ctl_scaling ;
633
- cpu -> pstate .max_pstate_physical = DIV_ROUND_UP (freq , scaling );
552
+ cpu -> pstate .max_pstate_physical =
553
+ DIV_ROUND_UP (perf_ctl_max_phys * perf_ctl_scaling ,
554
+ scaling );
634
555
635
556
cpu -> pstate .min_freq = cpu -> pstate .min_pstate * perf_ctl_scaling ;
636
557
/*
@@ -1861,6 +1782,38 @@ static int knl_get_turbo_pstate(void)
1861
1782
return ret ;
1862
1783
}
1863
1784
1785
+ #ifdef CONFIG_ACPI_CPPC_LIB
1786
+ static u32 hybrid_ref_perf ;
1787
+
1788
+ static int hybrid_get_cpu_scaling (int cpu )
1789
+ {
1790
+ return DIV_ROUND_UP (core_get_scaling () * hybrid_ref_perf ,
1791
+ intel_pstate_cppc_nominal (cpu ));
1792
+ }
1793
+
1794
+ static void intel_pstate_cppc_set_cpu_scaling (void )
1795
+ {
1796
+ u32 min_nominal_perf = U32_MAX ;
1797
+ int cpu ;
1798
+
1799
+ for_each_present_cpu (cpu ) {
1800
+ u32 nominal_perf = intel_pstate_cppc_nominal (cpu );
1801
+
1802
+ if (nominal_perf && nominal_perf < min_nominal_perf )
1803
+ min_nominal_perf = nominal_perf ;
1804
+ }
1805
+
1806
+ if (min_nominal_perf < U32_MAX ) {
1807
+ hybrid_ref_perf = min_nominal_perf ;
1808
+ pstate_funcs .get_cpu_scaling = hybrid_get_cpu_scaling ;
1809
+ }
1810
+ }
1811
+ #else
1812
+ static inline void intel_pstate_cppc_set_cpu_scaling (void )
1813
+ {
1814
+ }
1815
+ #endif /* CONFIG_ACPI_CPPC_LIB */
1816
+
1864
1817
static void intel_pstate_set_pstate (struct cpudata * cpu , int pstate )
1865
1818
{
1866
1819
trace_cpu_frequency (pstate * cpu -> pstate .scaling , cpu -> cpu );
@@ -1889,10 +1842,8 @@ static void intel_pstate_max_within_limits(struct cpudata *cpu)
1889
1842
1890
1843
static void intel_pstate_get_cpu_pstates (struct cpudata * cpu )
1891
1844
{
1892
- bool hybrid_cpu = boot_cpu_has (X86_FEATURE_HYBRID_CPU );
1893
1845
int perf_ctl_max_phys = pstate_funcs .get_max_physical ();
1894
- int perf_ctl_scaling = hybrid_cpu ? cpu_khz / perf_ctl_max_phys :
1895
- pstate_funcs .get_scaling ();
1846
+ int perf_ctl_scaling = pstate_funcs .get_scaling ();
1896
1847
1897
1848
cpu -> pstate .min_pstate = pstate_funcs .get_min ();
1898
1849
cpu -> pstate .max_pstate_physical = perf_ctl_max_phys ;
@@ -1901,10 +1852,13 @@ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
1901
1852
if (hwp_active && !hwp_mode_bdw ) {
1902
1853
__intel_pstate_get_hwp_cap (cpu );
1903
1854
1904
- if (hybrid_cpu )
1905
- intel_pstate_hybrid_hwp_calibrate (cpu );
1906
- else
1855
+ if (pstate_funcs .get_cpu_scaling ) {
1856
+ cpu -> pstate .scaling = pstate_funcs .get_cpu_scaling (cpu -> cpu );
1857
+ if (cpu -> pstate .scaling != perf_ctl_scaling )
1858
+ intel_pstate_hybrid_hwp_adjust (cpu );
1859
+ } else {
1907
1860
cpu -> pstate .scaling = perf_ctl_scaling ;
1861
+ }
1908
1862
} else {
1909
1863
cpu -> pstate .scaling = perf_ctl_scaling ;
1910
1864
cpu -> pstate .max_pstate = pstate_funcs .get_max ();
@@ -3276,6 +3230,9 @@ static int __init intel_pstate_init(void)
3276
3230
if (!default_driver )
3277
3231
default_driver = & intel_pstate ;
3278
3232
3233
+ if (boot_cpu_has (X86_FEATURE_HYBRID_CPU ))
3234
+ intel_pstate_cppc_set_cpu_scaling ();
3235
+
3279
3236
goto hwp_cpu_matched ;
3280
3237
}
3281
3238
} else {
0 commit comments