Merge tag 'driver-core-6.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git...
[sfrench/cifs-2.6.git] / drivers / base / arch_topology.c
index 9ccb7daee78eb5a316fddfc3f7a42b7c7198be33..018ac202de345e9a97bc7198385c1d95d460eb28 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/init.h>
 #include <linux/rcupdate.h>
 #include <linux/sched.h>
+#include <linux/units.h>
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/thermal_pressure.h>
@@ -26,7 +27,8 @@
 static DEFINE_PER_CPU(struct scale_freq_data __rcu *, sft_data);
 static struct cpumask scale_freq_counters_mask;
 static bool scale_freq_invariant;
-static DEFINE_PER_CPU(u32, freq_factor) = 1;
+DEFINE_PER_CPU(unsigned long, capacity_freq_ref) = 1;
+EXPORT_PER_CPU_SYMBOL_GPL(capacity_freq_ref);
 
 static bool supports_scale_freq_counters(const struct cpumask *cpus)
 {
@@ -170,9 +172,9 @@ DEFINE_PER_CPU(unsigned long, thermal_pressure);
  * operating on stale data when hot-plug is used for some CPUs. The
  * @capped_freq reflects the currently allowed max CPUs frequency due to
  * thermal capping. It might be also a boost frequency value, which is bigger
- * than the internal 'freq_factor' max frequency. In such case the pressure
- * value should simply be removed, since this is an indication that there is
- * no thermal throttling. The @capped_freq must be provided in kHz.
+ * than the internal 'capacity_freq_ref' max frequency. In such case the
+ * pressure value should simply be removed, since this is an indication that
+ * there is no thermal throttling. The @capped_freq must be provided in kHz.
  */
 void topology_update_thermal_pressure(const struct cpumask *cpus,
                                      unsigned long capped_freq)
@@ -183,10 +185,7 @@ void topology_update_thermal_pressure(const struct cpumask *cpus,
 
        cpu = cpumask_first(cpus);
        max_capacity = arch_scale_cpu_capacity(cpu);
-       max_freq = per_cpu(freq_factor, cpu);
-
-       /* Convert to MHz scale which is used in 'freq_factor' */
-       capped_freq /= 1000;
+       max_freq = arch_scale_freq_ref(cpu);
 
        /*
         * Handle properly the boost frequencies, which should simply clean
@@ -293,13 +292,13 @@ void topology_normalize_cpu_scale(void)
 
        capacity_scale = 1;
        for_each_possible_cpu(cpu) {
-               capacity = raw_capacity[cpu] * per_cpu(freq_factor, cpu);
+               capacity = raw_capacity[cpu] * per_cpu(capacity_freq_ref, cpu);
                capacity_scale = max(capacity, capacity_scale);
        }
 
        pr_debug("cpu_capacity: capacity_scale=%llu\n", capacity_scale);
        for_each_possible_cpu(cpu) {
-               capacity = raw_capacity[cpu] * per_cpu(freq_factor, cpu);
+               capacity = raw_capacity[cpu] * per_cpu(capacity_freq_ref, cpu);
                capacity = div64_u64(capacity << SCHED_CAPACITY_SHIFT,
                        capacity_scale);
                topology_set_cpu_scale(cpu, capacity);
@@ -335,15 +334,15 @@ bool __init topology_parse_cpu_capacity(struct device_node *cpu_node, int cpu)
                        cpu_node, raw_capacity[cpu]);
 
                /*
-                * Update freq_factor for calculating early boot cpu capacities.
+                * Update capacity_freq_ref for calculating early boot CPU capacities.
                 * For non-clk CPU DVFS mechanism, there's no way to get the
                 * frequency value now, assuming they are running at the same
-                * frequency (by keeping the initial freq_factor value).
+                * frequency (by keeping the initial capacity_freq_ref value).
                 */
                cpu_clk = of_clk_get(cpu_node, 0);
                if (!PTR_ERR_OR_ZERO(cpu_clk)) {
-                       per_cpu(freq_factor, cpu) =
-                               clk_get_rate(cpu_clk) / 1000;
+                       per_cpu(capacity_freq_ref, cpu) =
+                               clk_get_rate(cpu_clk) / HZ_PER_KHZ;
                        clk_put(cpu_clk);
                }
        } else {
@@ -359,11 +358,16 @@ bool __init topology_parse_cpu_capacity(struct device_node *cpu_node, int cpu)
        return !ret;
 }
 
+void __weak freq_inv_set_max_ratio(int cpu, u64 max_rate)
+{
+}
+
 #ifdef CONFIG_ACPI_CPPC_LIB
 #include <acpi/cppc_acpi.h>
 
 void topology_init_cpu_capacity_cppc(void)
 {
+       u64 capacity, capacity_scale = 0;
        struct cppc_perf_caps perf_caps;
        int cpu;
 
@@ -380,6 +384,10 @@ void topology_init_cpu_capacity_cppc(void)
                    (perf_caps.highest_perf >= perf_caps.nominal_perf) &&
                    (perf_caps.highest_perf >= perf_caps.lowest_perf)) {
                        raw_capacity[cpu] = perf_caps.highest_perf;
+                       capacity_scale = max_t(u64, capacity_scale, raw_capacity[cpu]);
+
+                       per_cpu(capacity_freq_ref, cpu) = cppc_perf_to_khz(&perf_caps, raw_capacity[cpu]);
+
                        pr_debug("cpu_capacity: CPU%d cpu_capacity=%u (raw).\n",
                                 cpu, raw_capacity[cpu]);
                        continue;
@@ -390,7 +398,18 @@ void topology_init_cpu_capacity_cppc(void)
                goto exit;
        }
 
-       topology_normalize_cpu_scale();
+       for_each_possible_cpu(cpu) {
+               freq_inv_set_max_ratio(cpu,
+                                      per_cpu(capacity_freq_ref, cpu) * HZ_PER_KHZ);
+
+               capacity = raw_capacity[cpu];
+               capacity = div64_u64(capacity << SCHED_CAPACITY_SHIFT,
+                                    capacity_scale);
+               topology_set_cpu_scale(cpu, capacity);
+               pr_debug("cpu_capacity: CPU%d cpu_capacity=%lu\n",
+                       cpu, topology_get_cpu_scale(cpu));
+       }
+
        schedule_work(&update_topology_flags_work);
        pr_debug("cpu_capacity: cpu_capacity initialization done\n");
 
@@ -424,8 +443,11 @@ init_cpu_capacity_callback(struct notifier_block *nb,
 
        cpumask_andnot(cpus_to_visit, cpus_to_visit, policy->related_cpus);
 
-       for_each_cpu(cpu, policy->related_cpus)
-               per_cpu(freq_factor, cpu) = policy->cpuinfo.max_freq / 1000;
+       for_each_cpu(cpu, policy->related_cpus) {
+               per_cpu(capacity_freq_ref, cpu) = policy->cpuinfo.max_freq;
+               freq_inv_set_max_ratio(cpu,
+                                      per_cpu(capacity_freq_ref, cpu) * HZ_PER_KHZ);
+       }
 
        if (cpumask_empty(cpus_to_visit)) {
                topology_normalize_cpu_scale();