|
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 | } |
@@ -2709,7 +2713,7 @@ static int intel_pstate_init_cpu(unsigned int cpunum) |
2709 | 2713 | } |
2710 | 2714 |
|
2711 | 2715 | cpu->epp_powersave = -EINVAL; |
2712 | | - cpu->epp_policy = 0; |
| 2716 | + cpu->epp_policy = CPUFREQ_POLICY_UNKNOWN; |
2713 | 2717 |
|
2714 | 2718 | intel_pstate_get_cpu_pstates(cpu); |
2715 | 2719 |
|
@@ -3665,8 +3669,12 @@ 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 | | - X86_MATCH_VFM(INTEL_ARROWLAKE, HYBRID_SCALING_FACTOR_MTL), |
3670 | 3678 | X86_MATCH_VFM(INTEL_LUNARLAKE_M, HYBRID_SCALING_FACTOR_LNL), |
3671 | 3679 | {} |
3672 | 3680 | }; |
|
0 commit comments