|
28 | 28 | #include <linux/pm_qos.h>
|
29 | 29 | #include <linux/bitfield.h>
|
30 | 30 | #include <trace/events/power.h>
|
| 31 | +#include <linux/units.h> |
31 | 32 |
|
32 | 33 | #include <asm/cpu.h>
|
33 | 34 | #include <asm/div64.h>
|
@@ -302,11 +303,11 @@ static bool hwp_is_hybrid;
|
302 | 303 |
|
303 | 304 | static struct cpufreq_driver *intel_pstate_driver __read_mostly;
|
304 | 305 |
|
305 |
| -#define HYBRID_SCALING_FACTOR 78741 |
| 306 | +#define HYBRID_SCALING_FACTOR_ADL 78741 |
306 | 307 | #define HYBRID_SCALING_FACTOR_MTL 80000
|
307 | 308 | #define HYBRID_SCALING_FACTOR_LNL 86957
|
308 | 309 |
|
309 |
| -static int hybrid_scaling_factor = HYBRID_SCALING_FACTOR; |
| 310 | +static int hybrid_scaling_factor; |
310 | 311 |
|
311 | 312 | static inline int core_get_scaling(void)
|
312 | 313 | {
|
@@ -414,18 +415,15 @@ static int intel_pstate_get_cppc_guaranteed(int cpu)
|
414 | 415 | static int intel_pstate_cppc_get_scaling(int cpu)
|
415 | 416 | {
|
416 | 417 | struct cppc_perf_caps cppc_perf;
|
417 |
| - int ret; |
418 |
| - |
419 |
| - ret = cppc_get_perf_caps(cpu, &cppc_perf); |
420 | 418 |
|
421 | 419 | /*
|
422 |
| - * If the nominal frequency and the nominal performance are not |
423 |
| - * zero and the ratio between them is not 100, return the hybrid |
424 |
| - * scaling factor. |
| 420 | + * Compute the perf-to-frequency scaling factor for the given CPU if |
| 421 | + * possible, unless it would be 0. |
425 | 422 | */
|
426 |
| - if (!ret && cppc_perf.nominal_perf && cppc_perf.nominal_freq && |
427 |
| - cppc_perf.nominal_perf * 100 != cppc_perf.nominal_freq) |
428 |
| - return hybrid_scaling_factor; |
| 423 | + if (!cppc_get_perf_caps(cpu, &cppc_perf) && |
| 424 | + cppc_perf.nominal_perf && cppc_perf.nominal_freq) |
| 425 | + return div_u64(cppc_perf.nominal_freq * KHZ_PER_MHZ, |
| 426 | + cppc_perf.nominal_perf); |
429 | 427 |
|
430 | 428 | return core_get_scaling();
|
431 | 429 | }
|
@@ -2211,24 +2209,30 @@ static void hybrid_get_type(void *data)
|
2211 | 2209 |
|
2212 | 2210 | static int hwp_get_cpu_scaling(int cpu)
|
2213 | 2211 | {
|
2214 |
| - u8 cpu_type = 0; |
| 2212 | + if (hybrid_scaling_factor) { |
| 2213 | + u8 cpu_type = 0; |
2215 | 2214 |
|
2216 |
| - smp_call_function_single(cpu, hybrid_get_type, &cpu_type, 1); |
2217 |
| - /* P-cores have a smaller perf level-to-freqency scaling factor. */ |
2218 |
| - if (cpu_type == 0x40) |
2219 |
| - return hybrid_scaling_factor; |
| 2215 | + smp_call_function_single(cpu, hybrid_get_type, &cpu_type, 1); |
2220 | 2216 |
|
2221 |
| - /* Use default core scaling for E-cores */ |
2222 |
| - if (cpu_type == 0x20) |
| 2217 | + /* |
| 2218 | + * Return the hybrid scaling factor for P-cores and use the |
| 2219 | + * default core scaling for E-cores. |
| 2220 | + */ |
| 2221 | + if (cpu_type == 0x40) |
| 2222 | + return hybrid_scaling_factor; |
| 2223 | + |
| 2224 | + if (cpu_type == 0x20) |
| 2225 | + return core_get_scaling(); |
| 2226 | + } |
| 2227 | + |
| 2228 | + /* Use core scaling on non-hybrid systems. */ |
| 2229 | + if (!cpu_feature_enabled(X86_FEATURE_HYBRID_CPU)) |
2223 | 2230 | return core_get_scaling();
|
2224 | 2231 |
|
2225 | 2232 | /*
|
2226 |
| - * If reached here, this system is either non-hybrid (like Tiger |
2227 |
| - * Lake) or hybrid-capable (like Alder Lake or Raptor Lake) with |
2228 |
| - * no E cores (in which case CPUID for hybrid support is 0). |
2229 |
| - * |
2230 |
| - * The CPPC nominal_frequency field is 0 for non-hybrid systems, |
2231 |
| - * so the default core scaling will be used for them. |
| 2233 | + * The system is hybrid, but the hybrid scaling factor is not known or |
| 2234 | + * the CPU type is not one of the above, so use CPPC to compute the |
| 2235 | + * scaling factor for this CPU. |
2232 | 2236 | */
|
2233 | 2237 | return intel_pstate_cppc_get_scaling(cpu);
|
2234 | 2238 | }
|
@@ -3665,6 +3669,11 @@ static const struct x86_cpu_id intel_epp_default[] = {
|
3665 | 3669 | };
|
3666 | 3670 |
|
3667 | 3671 | static const struct x86_cpu_id intel_hybrid_scaling_factor[] = {
|
| 3672 | + X86_MATCH_VFM(INTEL_ALDERLAKE, HYBRID_SCALING_FACTOR_ADL), |
| 3673 | + X86_MATCH_VFM(INTEL_ALDERLAKE_L, HYBRID_SCALING_FACTOR_ADL), |
| 3674 | + X86_MATCH_VFM(INTEL_RAPTORLAKE, HYBRID_SCALING_FACTOR_ADL), |
| 3675 | + X86_MATCH_VFM(INTEL_RAPTORLAKE_P, HYBRID_SCALING_FACTOR_ADL), |
| 3676 | + X86_MATCH_VFM(INTEL_RAPTORLAKE_S, HYBRID_SCALING_FACTOR_ADL), |
3668 | 3677 | X86_MATCH_VFM(INTEL_METEORLAKE_L, HYBRID_SCALING_FACTOR_MTL),
|
3669 | 3678 | X86_MATCH_VFM(INTEL_ARROWLAKE, HYBRID_SCALING_FACTOR_MTL),
|
3670 | 3679 | X86_MATCH_VFM(INTEL_LUNARLAKE_M, HYBRID_SCALING_FACTOR_LNL),
|
|
0 commit comments