Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 826aa25e authored by Dietmar Eggemann's avatar Dietmar Eggemann Committed by Chris Redpath
Browse files

ANDROID: arm: Support for extracting EAS energy costs from DT



This patch implements support in the arm architecture for extracting
energy cost data from DT and matches the support added for arm64
in "ANDROID: arm64: Support for extracting EAS energy costs from DT"

The data should conform to the DT bindings for energy cost data needed
by EAS (energy aware scheduling).

Test output on TC2:

150     187     172     275     215     334     258     407     301     447     344     549     387     761     430     1024
0       0       0
8
3
150     187     172     275     215     334     258     407     301     447     344     549     387     761     430     1024
0       0       0
8
3
150     187     172     275     215     334     258     407     301     447     344     549     387     761     430     1024
0       0       0
8
3
150     2967    172     2792    215     2810    258     2815    301     2919    344     2847    387     3917    430     4905
25      25      10
8
3
426     7920    512     8165    597     8172    682     8195    768     8265    853     8446    938     11426   1024    15200
70      70      25
8
3

Change-Id: I1f6a70917ec5f4615a57cdbb7a34f1d783901c77
Signed-off-by: default avatarDietmar Eggemann <dietmar.eggemann@arm.com>
Signed-off-by: default avatarChris Redpath <chris.redpath@arm.com>
parent 04b61628
Loading
Loading
Loading
Loading
+61 −6
Original line number Diff line number Diff line
@@ -25,11 +25,49 @@
#include <linux/sched/topology.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/sched_energy.h>

#include <asm/cpu.h>
#include <asm/cputype.h>
#include <asm/topology.h>

/* sd energy functions */
static inline
const struct sched_group_energy * const cpu_core_energy(int cpu)
{
	struct sched_group_energy *sge = sge_array[cpu][SD_LEVEL0];
	unsigned long capacity;
	int max_cap_idx;

	if (!sge) {
		pr_warn("Invalid sched_group_energy for CPU%d\n", cpu);
		return NULL;
	}

	max_cap_idx = sge->nr_cap_states - 1;
	capacity = sge->cap_states[max_cap_idx].cap;

	printk_deferred("cpu=%d set cpu scale %lu from energy model\n",
			cpu, capacity);

	topology_set_cpu_scale(cpu, capacity);

	return sge;
}

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;
}

/*
 * cpu capacity scale management
 */
@@ -169,10 +207,26 @@ static void __init parse_dt_topology(void)
 */
static void update_cpu_capacity(unsigned int cpu)
{
	const struct sched_group_energy *sge;
	unsigned long capacity;

	sge = cpu_core_energy(cpu);

	if (sge) {
		int max_cap_idx;

		max_cap_idx = sge->nr_cap_states - 1;
		capacity = sge->cap_states[max_cap_idx].cap;

		printk_deferred("cpu=%d set cpu scale %lu from energy model\n",
				cpu, capacity);
	} else {
		if (!cpu_capacity(cpu) || cap_from_dt)
			return;
		capacity = cpu_capacity(cpu) / middle_capacity;
	}

	topology_set_cpu_scale(cpu, cpu_capacity(cpu) / middle_capacity);
	topology_set_cpu_scale(cpu, capacity);

	pr_info("CPU%u: update cpu_capacity %lu\n",
		cpu, topology_get_cpu_scale(NULL, cpu));
@@ -306,10 +360,9 @@ static int cpu_flags(void)

static struct sched_domain_topology_level arm_topology[] = {
#ifdef CONFIG_SCHED_MC
	{ cpu_corepower_mask, cpu_corepower_flags, SD_INIT_NAME(GMC) },
	{ cpu_coregroup_mask, core_flags, SD_INIT_NAME(MC) },
	{ cpu_coregroup_mask, core_flags, cpu_core_energy, SD_INIT_NAME(MC) },
#endif
	{ cpu_cpu_mask, cpu_flags, SD_INIT_NAME(DIE) },
	{ cpu_cpu_mask, cpu_flags, cpu_cluster_energy, SD_INIT_NAME(DIE) },
	{ NULL, },
};

@@ -337,4 +390,6 @@ void __init init_cpu_topology(void)

	/* Set scheduler topology descriptor */
	set_sched_topology(arm_topology);

	init_sched_energy_costs();
}