Skip to content

Commit 0fcfc9e

Browse files
spandruvadarafaeljw
authored andcommitted
cpufreq: intel_pstate: Fix scaling for hybrid-capable systems with disabled E-cores
Some system BIOS configuration may provide option to disable E-cores. As part of this change, CPUID feature for hybrid (Leaf 7 sub leaf 0, EDX[15] = 0) may not be set. But HWP performance limits will still be using a scaling factor like any other hybrid enabled system. The current check for applying scaling factor will fail when hybrid CPUID feature is not set and the only way to make sure that scaling should be applied by checking CPPC nominal frequency and nominal performance. First, or systems predating Alder Lake, the CPPC nominal frequency and nominal performance are 0, which can be used to distinguish those systems from hybrid systems with disabled E-cores. Second, if the CPPC nominal frequency and nominal performance are defined, which indicates the need to use a special scaling factor, and the nominal performance value multiplied by 100 is not equal to the nominal frequency one, use hybrid scaling factor. This can be done for all HWP systems without additional CPU model check. Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> [ rjw: Subject and changelog edits, removal of unneeded parens, comment edits ] Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
1 parent 0b76cc3 commit 0fcfc9e

1 file changed

Lines changed: 48 additions & 10 deletions

File tree

drivers/cpufreq/intel_pstate.c

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,13 @@ static bool hwp_forced __read_mostly;
302302

303303
static struct cpufreq_driver *intel_pstate_driver __read_mostly;
304304

305+
#define HYBRID_SCALING_FACTOR 78741
306+
307+
static inline int core_get_scaling(void)
308+
{
309+
return 100000;
310+
}
311+
305312
#ifdef CONFIG_ACPI
306313
static bool acpi_ppc;
307314
#endif
@@ -400,6 +407,26 @@ static int intel_pstate_get_cppc_guaranteed(int cpu)
400407

401408
return cppc_perf.nominal_perf;
402409
}
410+
411+
static int intel_pstate_cppc_get_scaling(int cpu)
412+
{
413+
struct cppc_perf_caps cppc_perf;
414+
int ret;
415+
416+
ret = cppc_get_perf_caps(cpu, &cppc_perf);
417+
418+
/*
419+
* If the nominal frequency and the nominal performance are not
420+
* zero and the ratio between them is not 100, return the hybrid
421+
* scaling factor.
422+
*/
423+
if (!ret && cppc_perf.nominal_perf && cppc_perf.nominal_freq &&
424+
cppc_perf.nominal_perf * 100 != cppc_perf.nominal_freq)
425+
return HYBRID_SCALING_FACTOR;
426+
427+
return core_get_scaling();
428+
}
429+
403430
#else /* CONFIG_ACPI_CPPC_LIB */
404431
static inline void intel_pstate_set_itmt_prio(int cpu)
405432
{
@@ -492,6 +519,11 @@ static inline int intel_pstate_get_cppc_guaranteed(int cpu)
492519
{
493520
return -ENOTSUPP;
494521
}
522+
523+
static int intel_pstate_cppc_get_scaling(int cpu)
524+
{
525+
return core_get_scaling();
526+
}
495527
#endif /* CONFIG_ACPI_CPPC_LIB */
496528

497529
/**
@@ -1897,11 +1929,6 @@ static int core_get_turbo_pstate(int cpu)
18971929
return ret;
18981930
}
18991931

1900-
static inline int core_get_scaling(void)
1901-
{
1902-
return 100000;
1903-
}
1904-
19051932
static u64 core_get_val(struct cpudata *cpudata, int pstate)
19061933
{
19071934
u64 val;
@@ -1938,16 +1965,28 @@ static void hybrid_get_type(void *data)
19381965
*cpu_type = get_this_hybrid_cpu_type();
19391966
}
19401967

1941-
static int hybrid_get_cpu_scaling(int cpu)
1968+
static int hwp_get_cpu_scaling(int cpu)
19421969
{
19431970
u8 cpu_type = 0;
19441971

19451972
smp_call_function_single(cpu, hybrid_get_type, &cpu_type, 1);
19461973
/* P-cores have a smaller perf level-to-freqency scaling factor. */
19471974
if (cpu_type == 0x40)
1948-
return 78741;
1975+
return HYBRID_SCALING_FACTOR;
19491976

1950-
return core_get_scaling();
1977+
/* Use default core scaling for E-cores */
1978+
if (cpu_type == 0x20)
1979+
return core_get_scaling();
1980+
1981+
/*
1982+
* If reached here, this system is either non-hybrid (like Tiger
1983+
* Lake) or hybrid-capable (like Alder Lake or Raptor Lake) with
1984+
* no E cores (in which case CPUID for hybrid support is 0).
1985+
*
1986+
* The CPPC nominal_frequency field is 0 for non-hybrid systems,
1987+
* so the default core scaling will be used for them.
1988+
*/
1989+
return intel_pstate_cppc_get_scaling(cpu);
19511990
}
19521991

19531992
static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate)
@@ -3395,8 +3434,7 @@ static int __init intel_pstate_init(void)
33953434
if (!default_driver)
33963435
default_driver = &intel_pstate;
33973436

3398-
if (boot_cpu_has(X86_FEATURE_HYBRID_CPU))
3399-
pstate_funcs.get_cpu_scaling = hybrid_get_cpu_scaling;
3437+
pstate_funcs.get_cpu_scaling = hwp_get_cpu_scaling;
34003438

34013439
goto hwp_cpu_matched;
34023440
}

0 commit comments

Comments
 (0)