mirror of https://github.com/OpenIPC/firmware.git
119 lines
3.0 KiB
Diff
119 lines
3.0 KiB
Diff
diff -drupN a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c
|
|
--- a/arch/arm64/kernel/topology.c 2018-08-06 17:23:04.000000000 +0300
|
|
+++ b/arch/arm64/kernel/topology.c 2022-06-12 05:28:14.000000000 +0300
|
|
@@ -19,10 +19,24 @@
|
|
#include <linux/nodemask.h>
|
|
#include <linux/of.h>
|
|
#include <linux/sched.h>
|
|
+#include <linux/sched.h>
|
|
+#include <linux/sched_energy.h>
|
|
|
|
#include <asm/cputype.h>
|
|
#include <asm/topology.h>
|
|
|
|
+static DEFINE_PER_CPU(unsigned long, cpu_scale) = SCHED_CAPACITY_SCALE;
|
|
+
|
|
+unsigned long scale_cpu_capacity(struct sched_domain *sd, int cpu)
|
|
+{
|
|
+ return per_cpu(cpu_scale, cpu);
|
|
+}
|
|
+
|
|
+static void set_capacity_scale(unsigned int cpu, unsigned long capacity)
|
|
+{
|
|
+ per_cpu(cpu_scale, cpu) = capacity;
|
|
+}
|
|
+
|
|
static int __init get_cpu_for_node(struct device_node *node)
|
|
{
|
|
struct device_node *cpu_node;
|
|
@@ -206,11 +220,72 @@ out:
|
|
struct cpu_topology cpu_topology[NR_CPUS];
|
|
EXPORT_SYMBOL_GPL(cpu_topology);
|
|
|
|
+/* sd energy functions */
|
|
+static inline
|
|
+const struct sched_group_energy * const cpu_cluster_energy(int cpu)
|
|
+{
|
|
+ struct sched_group_energy *sge = sge_array[cpu][SD_LEVEL1];
|
|
+
|
|
+ if (!sge) {
|
|
+ pr_warn("Invalid sched_group_energy for Cluster%d\n", cpu);
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ return sge;
|
|
+}
|
|
+
|
|
+static inline
|
|
+const struct sched_group_energy * const cpu_core_energy(int cpu)
|
|
+{
|
|
+ struct sched_group_energy *sge = sge_array[cpu][SD_LEVEL0];
|
|
+
|
|
+ if (!sge) {
|
|
+ pr_warn("Invalid sched_group_energy for CPU%d\n", cpu);
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ return sge;
|
|
+}
|
|
+
|
|
const struct cpumask *cpu_coregroup_mask(int cpu)
|
|
{
|
|
return &cpu_topology[cpu].core_sibling;
|
|
}
|
|
|
|
+static int cpu_cpu_flags(void)
|
|
+{
|
|
+ return SD_ASYM_CPUCAPACITY;
|
|
+}
|
|
+
|
|
+static inline int cpu_corepower_flags(void)
|
|
+{
|
|
+ return SD_SHARE_PKG_RESOURCES | SD_SHARE_POWERDOMAIN | \
|
|
+ SD_SHARE_CAP_STATES;
|
|
+}
|
|
+
|
|
+static struct sched_domain_topology_level arm64_topology[] = {
|
|
+#ifdef CONFIG_SCHED_MC
|
|
+ { cpu_coregroup_mask, cpu_corepower_flags, cpu_core_energy, SD_INIT_NAME(MC) },
|
|
+#endif
|
|
+ { cpu_cpu_mask, cpu_cpu_flags, cpu_cluster_energy, SD_INIT_NAME(DIE) },
|
|
+ { NULL, },
|
|
+};
|
|
+
|
|
+static void update_cpu_capacity(unsigned int cpu)
|
|
+{
|
|
+ unsigned long capacity = SCHED_CAPACITY_SCALE;
|
|
+
|
|
+ if (cpu_core_energy(cpu)) {
|
|
+ int max_cap_idx = cpu_core_energy(cpu)->nr_cap_states - 1;
|
|
+ capacity = cpu_core_energy(cpu)->cap_states[max_cap_idx].cap;
|
|
+ }
|
|
+
|
|
+ set_capacity_scale(cpu, capacity);
|
|
+
|
|
+ pr_info("CPU%d: update cpu_capacity %lu\n",
|
|
+ cpu, arch_scale_cpu_capacity(NULL, cpu));
|
|
+}
|
|
+
|
|
static void update_siblings_masks(unsigned int cpuid)
|
|
{
|
|
struct cpu_topology *cpu_topo, *cpuid_topo = &cpu_topology[cpuid];
|
|
@@ -272,6 +347,7 @@ void store_cpu_topology(unsigned int cpu
|
|
|
|
topology_populated:
|
|
update_siblings_masks(cpuid);
|
|
+ update_cpu_capacity(cpuid);
|
|
}
|
|
|
|
static void __init reset_cpu_topology(void)
|
|
@@ -302,4 +378,8 @@ void __init init_cpu_topology(void)
|
|
*/
|
|
if (of_have_populated_dt() && parse_dt_topology())
|
|
reset_cpu_topology();
|
|
+ else
|
|
+ set_sched_topology(arm64_topology);
|
|
+
|
|
+ init_sched_energy_costs();
|
|
}
|