History

cpufreq: CPPC: Enable fast_switch

The communication mean of the _CPC desired performance can be PCC, System Memory, System IO, or Functional Fixed Hardware. commit b7898fda5bc7 ("cpufreq: Support for fast frequency switching") fast_switching is 'for switching CPU frequencies from interrupt context'. Writes to SystemMemory and SystemIo are fast and suitable this. This is not the case for PCC and might not be the case for FFH. Enable fast_switching for the cppc_cpufreq driver in above cases. Add cppc_allow_fast_switch() to check the desired performance register address space and set fast_switching accordingly.

Pierre Gondois committed 4 years ago

Commit 3cc30dd1 parent 6380b7b3 files · +47 −0Browse files

Unified · Split

3 files
  1. drivers/acpi/cppc_acpi.c +18 −0
  2. drivers/cpufreq/cppc_cpufreq.c +24 −0
  3. include/acpi/cppc_acpi.h +5 −0
drivers/acpi/cppc_acpi.c+18−0
@@ -434,6 +434,24 @@ bool acpi_cpc_valid(void) · 433 unmodified lines
434}434}
435EXPORT_SYMBOL_GPL(acpi_cpc_valid);435EXPORT_SYMBOL_GPL(acpi_cpc_valid);
436 436
437bool cppc_allow_fast_switch(void)
438{
439 struct cpc_register_resource *desired_reg;
440 struct cpc_desc *cpc_ptr;
441 int cpu;
442
443 for_each_possible_cpu(cpu) {
444 cpc_ptr = per_cpu(cpc_desc_ptr, cpu);
445 desired_reg = &cpc_ptr->cpc_regs[DESIRED_PERF];
446 if (!CPC_IN_SYSTEM_MEMORY(desired_reg) &&
447 !CPC_IN_SYSTEM_IO(desired_reg))
448 return false;
449 }
450
451 return true;
452}
453EXPORT_SYMBOL_GPL(cppc_allow_fast_switch);
454
437/**455/**
438 * acpi_get_psd_map - Map the CPUs in the freq domain of a given cpu456 * acpi_get_psd_map - Map the CPUs in the freq domain of a given cpu
439 * @cpu: Find all CPUs that share a domain with cpu.457 * @cpu: Find all CPUs that share a domain with cpu.
drivers/cpufreq/cppc_cpufreq.c+24−0
@@ -389,6 +389,27 @@ static int cppc_cpufreq_set_target(struct cpufreq_policy *policy, · 388 unmodified lines
389 return ret;389 return ret;
390}390}
391 391
392static unsigned int cppc_cpufreq_fast_switch(struct cpufreq_policy *policy,
393 unsigned int target_freq)
394{
395 struct cppc_cpudata *cpu_data = policy->driver_data;
396 unsigned int cpu = policy->cpu;
397 u32 desired_perf;
398 int ret;
399
400 desired_perf = cppc_cpufreq_khz_to_perf(cpu_data, target_freq);
401 cpu_data->perf_ctrls.desired_perf = desired_perf;
402 ret = cppc_set_perf(cpu, &cpu_data->perf_ctrls);
403
404 if (ret) {
405 pr_debug("Failed to set target on CPU:%d. ret:%d\n",
406 cpu, ret);
407 return 0;
408 }
409
410 return target_freq;
411}
412
392static int cppc_verify_policy(struct cpufreq_policy_data *policy)413static int cppc_verify_policy(struct cpufreq_policy_data *policy)
393{414{
394 cpufreq_verify_within_cpu_limits(policy);415 cpufreq_verify_within_cpu_limits(policy);
@@ -721,6 +742,8 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy) · 326 unmodified lines
721 goto out;742 goto out;
722 }743 }
723 744
745 policy->fast_switch_possible = cppc_allow_fast_switch();
746
724 /*747 /*
725 * If 'highest_perf' is greater than 'nominal_perf', we assume CPU Boost748 * If 'highest_perf' is greater than 'nominal_perf', we assume CPU Boost
726 * is supported.749 * is supported.
@@ -866,6 +889,7 @@ static struct cpufreq_driver cppc_cpufreq_driver = { · 139 unmodified lines
866 .verify = cppc_verify_policy,889 .verify = cppc_verify_policy,
867 .target = cppc_cpufreq_set_target,890 .target = cppc_cpufreq_set_target,
868 .get = cppc_cpufreq_get_rate,891 .get = cppc_cpufreq_get_rate,
892 .fast_switch = cppc_cpufreq_fast_switch,
869 .init = cppc_cpufreq_cpu_init,893 .init = cppc_cpufreq_cpu_init,
870 .exit = cppc_cpufreq_cpu_exit,894 .exit = cppc_cpufreq_cpu_exit,
871 .set_boost = cppc_cpufreq_set_boost,895 .set_boost = cppc_cpufreq_set_boost,
include/acpi/cppc_acpi.h+5−0
@@ -141,6 +141,7 @@ extern int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls); · 140 unmodified lines
141extern int cppc_set_enable(int cpu, bool enable);141extern int cppc_set_enable(int cpu, bool enable);
142extern int cppc_get_perf_caps(int cpu, struct cppc_perf_caps *caps);142extern int cppc_get_perf_caps(int cpu, struct cppc_perf_caps *caps);
143extern bool acpi_cpc_valid(void);143extern bool acpi_cpc_valid(void);
144extern bool cppc_allow_fast_switch(void);
144extern int acpi_get_psd_map(unsigned int cpu, struct cppc_cpudata *cpu_data);145extern int acpi_get_psd_map(unsigned int cpu, struct cppc_cpudata *cpu_data);
145extern unsigned int cppc_get_transition_latency(int cpu);146extern unsigned int cppc_get_transition_latency(int cpu);
146extern bool cpc_ffh_supported(void);147extern bool cpc_ffh_supported(void);
@@ -175,6 +176,10 @@ static inline bool acpi_cpc_valid(void) · 28 unmodified lines
175{176{
176 return false;177 return false;
177}178}
179static inline bool cppc_allow_fast_switch(void)
180{
181 return false;
182}
178static inline unsigned int cppc_get_transition_latency(int cpu)183static inline unsigned int cppc_get_transition_latency(int cpu)
179{184{
180 return CPUFREQ_ETERNAL;185 return CPUFREQ_ETERNAL;